Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Agent Facets

`facet` is a CLI package manager and toolkit for facets — modular skills, agents, commands, and tools that extend AI coding assistants.
`facet` is a CLI package manager and toolkit for facets — modular skills, agents, commands, and tools that extend AI coding assistants. Facets can also ship non-asset files — a `README.md`, a `LICENSE`, or skill companion files — that travel inside the archive; only skill companions materialize on disk. See the [docs](https://docs.agentfacets.io) for details.

The official registry for Agent Facets is [agentfacets.io](https://agentfacets.io) where you can publish and share facets.

Expand Down
88 changes: 88 additions & 0 deletions docs/changelog/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,94 @@ description: What's new in Agent Facets
rss: true
---

<Update label="2026-07-23" description="Facets ship non-asset files; archive 0.2, per-file lockfiles, first-class README, and the 0.1 adapter contract" tags={["CLI", "Breaking", "New Feature"]} rss={{
title: "Supplementary files, archive 0.2, and first-class README authoring",
description: "Facets can now declare and ship non-asset files: skill companion files (references, scripts, templates beside SKILL.md) that install and remove atomically with their skill, and top-level archive-only files like README.md and LICENSE that ship in the archive but never materialize on disk. Declare them with exact paths in the manifest's top-level files array or a skill descriptor's files array. Builds emit the new 0.2 archive format with a complete per-entry hash map; lockfiles move to 0.2 with a per-file integrity record for every materialized file; install reports and repairs drift per file. facet create now writes and declares an editable README.md by default (skip with --no-readme), and facet edit has a dedicated README panel. Consumers still accept legacy 0.1 archives and legacy alpha lockfiles during the compatibility window; the two versions are dispatched by exact match. Asset names are single-segment Agent Skills names -- slash-namespaced names are no longer valid in new manifests -- and skills and commands now share one namespace. The adapter contract advances from positional 0.0 to the tagged 0.1 request/result shape: rebuild and reinstall any adapter that still declares 0.0. Rollout is consumer-first: protocol, then registry, then adapters, then the CLI."
Comment on lines +8 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Delay the changelog entry until the CLI release ships

This publishes a July 23 “now” release announcement even though the same change leaves the held CLI release gate unfinished and adds no agent-facets changeset. Users of the released CLI will follow the documented --no-readme, archive 0.2, and adapter 0.1 migration paths before a CLI package exposing them exists. Keep this information in unreleased documentation, or add the <Update> with the final CLI release.

AGENTS.md reference: docs/changelog/AGENTS.md:L91-L109

Useful? React with 👍 / 👎.

}}>
## Facets can ship non-asset files

A facet is no longer just its assets. You can now declare **supplementary
files** that travel inside the `.facet` archive and are integrity-protected
like everything else:

- **Skill companions** — files beside a `SKILL.md` (references, scripts,
templates). They install and remove **atomically** with their skill, and
files you add to a skill directory yourself are preserved on removal.
- **Top-level archive-only files** — `README.md`, `LICENSE`, design notes.
They ship in the archive but are **never** written to disk at install.

Declare them with exact paths (no globs) in the manifest's top-level `files`
array or a skill descriptor's own `files` array:

```json
{
"skills": {
"code-review": {
"description": "Code review guidelines",
"files": ["references/style-guide.md"]
}
},
"files": ["README.md", "LICENSE"]
}
```

See [Supplementary files](/specification/manifest#supplementary-files).

## First-class README authoring

[`facet create`](/cli/authoring/create) now writes and declares an editable
`README.md` by default (skip it with `--no-readme`), and
[`facet edit`](/cli/authoring/edit) has a dedicated README panel for
creating, adopting, editing, or removing both `README.md` and the
extensionless `README`.

## **Breaking:** archive `0.2`, per-file lockfiles, and naming

- **Archive format `0.2`.** Every build now emits `facetVersion: 0.2` with a
complete per-entry hash map covering every file, asset or not. Consumers
still accept legacy `0.1` archives during the compatibility window; the two
are dispatched by **exact** version match, never numeric ordering. An
archive whose version your CLI doesn't support fails with upgrade guidance —
run [`facet self-update`](/cli/self-update).
- **Lockfile `0.2`.** `facets.lock` records a per-file `{ path, integrity }`
record for every materialized file inside each asset, and install
reconciles them before writing, reporting and repairing drift by exact
path. A verified legacy alpha lockfile migrates automatically on a normal
install. See [Lockfile](/specification/lockfile).
- **Asset names.** Skill, command, and agent names are now single-segment
[Agent Skills names](/specification/manifest#asset-names) — slash-namespaced
names like `viper-plans/planning` are no longer valid in new manifests (use
`viper-planning`). Skills and commands now share one namespace and can't
reuse a name.
- **Primary files carry no front matter.** Asset metadata lives in the
manifest; a `SKILL.md`, agent, or command file with YAML front matter is now
a build error. Supplementary files still ship verbatim.

## **Breaking:** adapter API `0.0` → `0.1`

The adapter contract advances from the positional single-file shape (`0.0`)
to the tagged multi-file request/result contract (`0.1`) that carries skill
companions. A `0.1` CLI treats a positional `0.0` adapter as unsupported and
fails closed before any write. Rebuild against a `0.1` SDK and reinstall:

```sh
facet adapter list # shows each adapter's declared API
facet adapter install my-adapter # reinstall the newest compatible release
```

The archive `facetVersion`, the lockfile version, and the adapter API are
three **independent** axes — a consumer classifies each separately. See
[Custom adapters](/guides/custom-adapters).

## Rollout

The change ships **consumer-first**: the protocol package publishes dual
`0.1`/`0.2` verification, then the registry adopts it, then the adapter SDK
and first-party adapters publish `0.1`, and finally the CLI release turns on
`0.2` production. Existing `0.0` CLIs keep selecting compatible `0.0` adapters
until you update.
</Update>

<Update label="2026-07-13" description="facet remove now prunes empty adapter directories" tags={["CLI", "Improvement"]} rss={{
title: "facet remove now prunes empty adapter directories",
description: "Removing a facet now cleans up empty parent directories left behind in each connected adapter. When facet remove (or facet rm) deletes the last asset inside a nested folder -- for example skills/<name>/SKILL.md under Claude Code or OpenCode -- the CLI walks up and removes empty parent directories up to (but not including) the adapter root. Uninstalls leave a tidy tree instead of hollow namespace folders. No flags to set; behavior is automatic."
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/authoring/build.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Validates and builds the facet in the specified directory (defaults to the curre

## What it does

`facet build` runs the validation-and-assembly pipeline defined in the [Build specification](/specification/build): parse and validate the manifest, resolve prompts from their conventional paths, validate content, validate adapter metadata, and assemble the deterministic two-layer archive.
`facet build` runs the validation-and-assembly pipeline defined in the [Build specification](/specification/build): parse and validate the manifest, resolve prompts from their conventional paths, resolve and validate declared [supplementary files](/specification/manifest#supplementary-files), validate content, validate adapter metadata, and assemble the deterministic two-layer archive. Validation happens **before** any `dist/` cleanup, so a build that fails leaves your previous output intact. Build output shows the emitted archive-format version, the complete entry listing (assets and supplementary files), and the integrity hash.

On success, the build writes `dist/<name>-<version>.facet` — the single distributable artifact, with the build manifest embedded inside it (see [Archive format](/specification/archive)). `dist/` is purged first, so it contains exactly one `.facet` after a successful build. For a scoped identity the name's `/` renders as a nested path: `@acme/cowsay` at `1.0.0` lands at `dist/@acme/cowsay-1.0.0.facet`.

Expand Down
15 changes: 11 additions & 4 deletions docs/cli/authoring/create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ facet create ./my-facet \
--version 0.1.0 \
--skill greet --agent helper --command run \
--json # headless scaffold, machine-readable result
facet create ./bare --name bare --skill greet --no-readme # skip the default README
```

## Flags
Expand All @@ -44,7 +45,11 @@ facet create ./my-facet \
</ResponseField>

<ResponseField name="--skill / --agent / --command" type="repeatable">
An asset to scaffold. Repeat per asset; at least one is required in headless mode. Asset names must be kebab-case.
An asset to scaffold. Repeat per asset; at least one is required in headless mode. Asset names are single-segment [Agent Skills names](/specification/manifest#asset-names); a skill and command can't share a name.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject cross-type duplicates in headless create

The documented shared namespace is enforced only by the interactive wizard. In headless mode, decideCreate validates each flag group independently and passes both arrays to writeScaffold, so facet create --name demo --skill review --command review succeeds but writes a manifest the current schema rejects; the user's immediately scaffolded project then cannot build. Add a cross-check before returning the headless options (or avoid promising this constraint for headless creation).

Useful? React with 👍 / 👎.

</ResponseField>

<ResponseField name="--no-readme" type="boolean">
Skip the default `README.md`. `facet create` writes and declares an editable `README.md` (seeded from the name and description) by default; pass `--no-readme` to scaffold without it.
Comment on lines +51 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make --no-readme trigger headless scaffolding

When users run facet create --no-readme without another content flag, this documentation promises that the README will be skipped, but decideCreate deliberately leaves readme out of HEADLESS_FLAGS and its test confirms that this invocation opens the default README-enabled wizard instead. Either include --no-readme in the headless trigger set or document that it only takes effect alongside headless content flags.

Useful? React with 👍 / 👎.

</ResponseField>

<ResponseField name="--force" type="boolean">
Expand Down Expand Up @@ -79,17 +84,19 @@ After scaffolding, validate with [`facet build --verify`](/cli/authoring/build),
3. **Version** -- defaults to `0.0.0`.
4. **Privacy** -- choose Public (the default) or Private.
5. **Assets** -- add skills, agents, and commands by name.
6. **Confirmation** -- review the summary -- and confirm.
6. **README** -- enabled by default. The wizard seeds `README.md` from the name and description; open the editor to customize it, or toggle it off. Edited content is preserved even if you change the name or description later.
7. **Confirmation** -- review the summary — which lists `README.md` when enabled — and confirm.

## Generated files

On confirmation, the wizard writes:

- `facet.json` -- the manifest with named asset descriptors
- `facet.json` -- the manifest with named asset descriptors (and `README.md` in top-level `files` when README is enabled)
- `README.md` -- editable README, written and declared by default (skip with `--no-readme`)
- `skills/<name>/SKILL.md` -- starter skill template (Agent Skills directory convention)
- `agents/<name>.md` -- starter agent template
- `commands/<name>.md` -- starter command template

Content files are markdown. Optional YAML front matter [survives the build untouched](/specification/build#steps); at install time the manifest's `name`, `description`, and any per-adapter extras are merged on top of whatever the author wrote.
Content files are markdown. A primary asset file (skill, agent, command) carries **no** YAML front matter — asset metadata lives in the manifest. `README.md` and other [supplementary files](/specification/manifest#supplementary-files) are written verbatim.

After creating the project, use `facet edit` to iterate on your facet, or `facet build` to validate and package it.
31 changes: 25 additions & 6 deletions docs/cli/authoring/edit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ The edit command has two phases:

If the edit command detects drift between the manifest and the files on disk, it enters a reconciliation phase first. Drift includes:

- **New files on disk** not tracked in the manifest -- choose "Add to manifest" or "Ignore for now"
- **Missing files** declared in the manifest but absent from disk -- choose "Scaffold template" or "Remove from manifest"
- **New assets on disk** not tracked in the manifest -- choose "Add to manifest" or "Ignore for now"
- **Undeclared files inside a declared skill directory** -- adopt them into that skill's [companion `files`](/specification/manifest#supplementary-files), or ignore
- **Common root files** like `LICENSE` -- adopt them into the top-level `files`, or ignore
- **Missing files** declared in the manifest but absent from disk -- choose "Scaffold template" or "Remove from manifest" (at the exact declared path, for both assets and supplementary files)

YAML front matter in content files is not flagged here -- it is permitted and [preserved verbatim through the build](/specification/build#steps), then merged with the manifest's `name`, `description`, and any per-adapter extras at install time.
`README.md` and the extensionless `README` are handled by their own [README panel](#readme-panel), not generic reconciliation, so they never appear twice. Ignored files stay on disk and undeclared.

All reconciliation items must be resolved before proceeding to editing.

Expand All @@ -43,19 +45,36 @@ After reconciliation (or immediately if no drift), the edit phase allows:

- **Identity editing** -- modify the facet name, description, and version
- **Privacy editing** -- inspect the facet's current visibility intent without opening `facet.json`, and switch between Public and Private.
- **Asset management** -- add, remove, or rename skills, agents, and commands
- **Asset management** -- add, remove, or rename skills, agents, and commands. Deleting a skill removes its declared companion files too, while any files you added to the skill directory yourself are preserved.
- **Description editing** -- press Enter on an asset to edit its name, or press ↓ during name editing to open the description in your terminal editor (`$VISUAL` / `$EDITOR` / `vi`)

A primary asset file carries no YAML front matter — asset metadata lives in the manifest, and edit writes confirmed content without front matter.

All changes are transactional -- nothing is written to disk until you review and confirm on the confirmation page. Exit at any point with Esc Esc to discard all changes.

### README panel

Both conventional README paths — `README.md` and the extensionless `README` — get a dedicated panel, managed independently. The actions offered depend on each path's current state:

| State | Actions |
| --- | --- |
| Present and declared | **Edit** the content, or **Remove** (deletes the file and its declaration) |
| Present but undeclared | **Adopt** (declare it, bytes untouched), or **Edit and adopt** |
| Declared but missing | **Scaffold** at that path, or **Remove declaration** |
| Absent and undeclared | **Create** (defaults to `README.md`) |

Adopt preserves the existing bytes unless you explicitly edit them. Every README operation is queued until Apply, like all other edits.

## Confirmation

Before applying, a summary shows the final state of your facet -- identity fields, the privacy intent, and all assets with their descriptions -- along with a reminder that a privacy change is embedded at build time (rebuild to apply it, and bump the version if it was already published). Choose "Apply" to write changes or "Go back" to continue editing.

On apply, the edit command:
The confirmation lists every queued file operation with its exact path. On apply, the edit command transactionally:
- Writes the updated `facet.json`
- Scaffolds template files for new assets
- Deletes files for removed assets
- Deletes files for removed assets (and a removed skill's declared companions)
- Writes or deletes README files per the [README panel](#readme-panel) choices
- Scaffolds or removes reconciled supplementary files

## See also

Expand Down
6 changes: 5 additions & 1 deletion docs/cli/authoring/modify.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,16 @@ facet modify agent helper --description "Reviews code"

### Rename an asset

Renames the manifest key and moves the asset's file (removing the now-empty skill directory, for skills).
Renames the manifest key and moves the asset's primary file (removing the now-empty skill directory, for skills).

```sh
facet modify command run --rename start
```

<Note>
`facet modify` operates on asset primaries. To adopt, move, or reconcile a skill's [companion files](/specification/manifest#supplementary-files) or top-level supplementary files, use [`facet edit`](/cli/authoring/edit).
</Note>
Comment on lines +87 to +89

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not direct companion moves to facet edit

For a skill that has declared companions, facet edit cannot move those files during a rename: its edit session treats the renamed skill as a new scaffold plus deletion of the old skill and its declared companions (use-edit-session.ts builds those operations), and reconciliation only offers add/ignore or scaffold/remove actions. Thus the newly documented instruction sends users to a flow that cannot preserve or relocate companion content; document a safe manual move sequence or implement companion-aware renaming before recommending this command.

Useful? React with 👍 / 👎.


### Remove an asset

Removes the manifest descriptor and deletes the asset's file.
Expand Down
25 changes: 19 additions & 6 deletions docs/docs/learn/skills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ title: Skills
description: Reusable knowledge and guidelines
---

A skill is a markdown file containing domain-specific instructions, guidelines, or best practices. Skills follow the [Agent Skills](https://agentskills.io/specification) specification. They are the passive knowledge layer of a facet -- text that shapes how an AI assistant approaches a domain without defining a persona or a user-invokable action.
A skill is a directory bundle — a `SKILL.md` primary plus any declared companion files — containing domain-specific instructions, guidelines, or best practices. Skills follow the [Agent Skills](https://agentskills.io/specification) specification. They are the passive knowledge layer of a facet -- text that shapes how an AI assistant approaches a domain without defining a persona or a user-invokable action.

Each skill lives at `skills/<name>/SKILL.md` and is declared in `facet.json` under the `skills` map. The normative rules — placement, descriptor shape, and the YAML front-matter contract — live at [Text assets](/specification/manifest#text-assets) in the manifest specification.
Each skill lives in its own directory at `skills/<name>/SKILL.md` and is declared in `facet.json` under the `skills` map. The normative rules — placement, descriptor shape, and the no-front-matter contract — live at [Text assets](/specification/manifest#text-assets) in the manifest specification.

## Example

A "code-review" skill (`skills/code-review/SKILL.md`):

```markdown expandable skills/code-review/SKILL.md
---
description: Code review guidelines for TypeScript projects
---

# Code Review

## Structure
Expand All @@ -40,6 +36,23 @@ description: Code review guidelines for TypeScript projects
- Do not comment obvious code.
```

## Companion files

A skill can ship more than its `SKILL.md`. Declare **companion files** — references, scripts, templates — in the skill descriptor's `files` array, as exact paths relative to the skill directory:

```json
{
"skills": {
"code-review": {
"description": "Code review guidelines",
"files": ["references/style-guide.md", "scripts/lint.ts"]
}
}
}
```

Companions ship inside the archive and install and remove **atomically** with their skill; files you add to a skill directory yourself are left untouched on removal. They ship as opaque bytes (binary and empty files are fine), the skill name is still a single segment (the `/` in a companion path is directory depth, not part of the name), and a companion can't be `SKILL.md` itself. See [Supplementary files](/specification/manifest#supplementary-files) for the full rules.

## When to use skills

Skills are **passive knowledge** -- they inform how the assistant thinks and works but do not define who it is or what the user can invoke. Use skills for:
Expand Down
Loading