Use when an AI tool gains support for a feature agentsmesh does not yet expose — or exposes wrongly — and you must raise or correct an existing target's capability for project and/or global scope (rules, additionalRules, commands, agents, skills, mcp, hooks, ignore, permissions). Also use to audit every target for capability gaps, or to act on an audit/feature-request someone else wrote. Start by verifying the claim against the tool's OWN primary docs — such findings are frequently fabricated...
Installs into .claude/skills of the current project.
Are you the author of Update Target Capabilities?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/samplexbro-update-target-capabilities)
---
name: update-target-capabilities
description: Use when an AI tool gains support for a feature agentsmesh does not yet expose — or exposes wrongly — and you must raise or correct an existing target's capability for project and/or global scope (rules, additionalRules, commands, agents, skills, mcp, hooks, ignore, permissions). Also use to audit every target for capability gaps, or to act on an audit/feature-request someone else wrote. Start by verifying the claim against the tool's OWN primary docs — such findings are frequently fabricated, stale, or wrong-scoped, so be ready to reject. Covers verification-first research, descriptor wiring, round-trip symmetry, global-only scopeExtras emission, settings-merge and plugin safety, format/path-change blast radius, strict TDD, two-stage review, and matrix/docs sync. Start with `pnpm capabilities:audit`; research only STALE/MISSING cells; the ledger memoizes verified formats so audits stay fast.
---
## Purpose
# Update Target Capabilities
Use this skill when an existing target already lives in `src/targets/<target>/` and the underlying tool has started supporting a canonical feature that agentsmesh declares as `none` (or under-declares as `partial`/`embedded`) — **or** declares as `native` but doesn't actually work (wrong path, wrong key, wrong shape, generate-only with no importer, or a file the tool never reads). The job is to raise or correct that capability — for the right scope(s), with the generate **and** import sides symmetric — and to prove it.
> **The meta-rule: verify the claim before you build it.** Most invocations of this skill act on a *claim* — an audit row, a feature-request, a changelog rumor, or a comment in our own code. In real use, a large fraction of those claims are wrong: the surface is fabricated (no such file exists), already-correct (the claim is stale), wrong-scoped (claimed "both scopes" but the tool only reads it globally), or GUI-only (no writable file → `partial`, not `native`). Treat every claim as a hypothesis and confirm it against the tool's **own** primary docs/source before writing a line. Rejecting a bad finding is a successful outcome — ship a guess and you ship a broken capability the matrix now advertises as real.
This is the skill `add-agent-target` defers to under "changing capability levels for an existing target." Use `add-agent-target` only for a brand-new target id; use `add-global-mode-target` only for first-time global wiring of a target that predates global support.
Read `./references/capability-update-checklist.md` before editing code. It holds the decision matrices, the format/path-change blast-radius list, and the full touchpoint/test/review list.
## When To Use
- A tool shipped a new feature surface (a config file, a settings key, a hooks format) that agentsmesh does not yet generate or import.
- You are auditing all targets for gaps ("which features do tools now support that we declare `none`?"), or working through an audit/feature-request someone else produced (verify each row — see the meta-rule).
- A capability is declared `partial`/`embedded` but the tool now has a dedicated file surface agentsmesh could own natively.
- A capability is declared `native` but is **broken**: wrong path/key/shape, a file the tool never reads, or generate-only with no importer. Fixing it so the tool actually loads it (or so it round-trips) is in scope and counts as a real capability gain even though the matrix level doesn't move.
## Do Not Use This Skill For
- Adding a brand-new target id — use `add-agent-target`.
- First-time global-mode architecture for a target — use `add-global-mode-target`.
- Pure refactors that do not change any capability level or fix any broken surface.
- Downgrades/removals (`native → none/partial`) — those are breaking changes that need a product decision, not this skill's expansion-first flow.
## Non-Negotiable Rules
### MUST
- **Verify the claim against the tool's own primary docs/source first — and reject what doesn't hold up.** A claim is real only when you can point at the tool's docs/source that say it reads this file/key in this shape at this scope. Reject (and write down why) when you find: a **fabricated** surface (no such file/key exists — e.g. a permissions path the tool never reads); an **already-correct** state (the claim is stale; the current code is right); a **wrong scope** (claimed "both" but the tool only reads it globally, or vice versa); or a **GUI/cloud-only** surface (no writable file → `partial`, not `native`). Do not trust the audit row, *our own code comments*, the README, or memory — they are exactly what produced the wrong claims. A rejection with evidence is a complete, valuable result.
- **Research the real, current format from primary sources** (only after the claim survives verification): the exact file path, the exact JSON/YAML/Markdown shape, and the exact top-level key (`mcpServers` vs `servers` vs `extensions` vs `context_servers` all differ). Separate the target product from the assistant runtime (a generated `codex-cli` target ≠ Codex desktop), and note when a project moved orgs/paths (e.g. Goose → AAIF).
- **Global-only settings-backed features emit via `globalSupport.scopeExtras`, not a plain `generateX`.** The permissions/settings feature loop invokes generators *without* a scope, and `resolveTargetFeatureGenerator` does not gate by level — so a plain `generatePermissions`/`generateX` for a feature that's `native` global but `none` project will **leak the file into project scope**. Emit it from `scopeExtras` (which receives the scope) and gate on `scope === 'global'`; the descriptor schema accepts `scopeExtras` as the implementation of a settings-backed global capability. (MCP/hooks generators *do* receive a `ctx` and can scope-gate via `ctx?.scope`.)
- **When two or more targets share a file format, extract one shared helper instead of duplicating per-target logic** (e.g. the wrapped command-hook serialize/import shared by codex-cli, factory-droid, and goose). Existing targets' tests then prove the extraction is behavior-preserving. Duplicated per-target format logic is the anti-pattern the architecture guide calls out.
- **Decide the level per scope, independently.** Project and global capabilities are separate fields and frequently differ (e.g. Goose MCP is global-only; Rovo Dev hooks/permissions are global-only). Use the level matrix in the checklist: `native` (dedicated file/key), `embedded` (folded into another file), `partial` (tool supports it but only via UI/managed settings agentsmesh cannot write), `none`.
- **Round-trip symmetry is the first-class requirement.** A `native` generate side MUST have a matching import side, or the capability is broken — this is the trap that slips through most often. After wiring a generator, wire the importer (descriptor `importer` block or custom `importFrom`) and assert canonical output in a test. The support matrix says "Native"; users read that as both directions.
- **`partial` requires a no-op generator stub plus a lint warning.** The descriptor schema requires a `generateX` returning `[]` even when the level is `partial`; add a `lint.<feature>` warning (reuse `createWarning`) pointing the user at the tool's UI/settings.
- **Settings-file merge discipline.** If a target emits *multiple* writes to one settings file in a pass (separate per-feature generators, or an array from one emitter), its `mergeGeneratedOutputContent` MUST use `pending?.content ?? existing` as the merge base, never just `existing` — otherwise earlier keys (e.g. `mcpServers`) are silently clobbered. If the target emits a *single combined* write (one `emitScopedSettings` output carrying every key), `_pending` is correctly unused — do not "fix" it.
- **Plugin safety.** The engine resolves every hook via `getBuiltinTargetDefinition(id) ?? getDescriptor(id)` — builtins and plugin descriptors share the path. If you change a descriptor hook *contract* (new field, new hook), update `tests/fixtures/plugins/rich-plugin` and add a registered-plugin-descriptor test, not only builtin coverage. If you merely *use* an existing hook, no fixture change is needed.
- **No target-name hardcoding in shared/core.** Extend shared infrastructure with data-driven, optional, default-preserving fields (e.g. `mcpServersKey?` on the mcpJson import mode), never `if (target === 'x')` branches.
- **Write failing tests first** for every new behavior: generator/emitter edge cases (`null`, empty, valid, each of allow/deny/ask), strict contract path arrays, and global-layout capability assertions.
- **Keep every file ≤ 200 lines.** Capability wiring grows `index.ts`; split into `capabilities.ts`, `importer-spec.ts`, `layout.ts`, `merge.ts`, `settings.ts` as the existing targets do. Check `wc -l` after wiring.
- **Reference rewriting.** If you add a new generated directory that contains cross-references (e.g. a commands dir), register it in `src/core/reference/import-maps/<target>.ts` both directions, and confirm the prose-vs-link classifier still holds.
- **Keep target data single-source.** Capabilities live only in the descriptor; the matrix builds dynamically. Run the matrix regen and sync README + `website/src/content/docs/reference/supported-tools.mdx` (the single per-target support page).
- **Run the lessons ritual.** Recall before each file edit / state-changing command; capture immediately after any failure or correction.
- **Run `post-feature-qa`** before claiming done.
### MUST NOT
- Do not implement a claim you could not confirm from the tool's own primary source — reject it with a one-line reason instead.
- Do not declare `native` and ship generate-only — that is a broken round-trip, not a feature.
- Do not infer the format from old fixtures, the README, our own code comments, or memory.
- Do not add a generator for a feature the tool only manages in its GUI — that is `partial`, with a lint warning.
- Do not use a plain `generateX` for a global-only feature — it leaks into project scope (use `scopeExtras`).
- Do not let `index.ts` cross 200 lines "temporarily."
- Do not update README without the website page, or vice versa.
- Do not hand-edit `package.json` version or the matrix tables; they are generated.
## Workflow (audit-driven)
Run `superpowers:subagent-driven-development` when touching more than one (target, feature).
1. **Audit (deterministic, ~0 tokens):** `pnpm capabilities:audit --json`. It joins descriptors × the capability ledger (`src/targets/catalog/capability-ledger.json`) and returns four buckets:
- **GAPS** — `descriptor < maxAchievable`: raise-opportunities. Do NOT leave these on the table (coverage bias: overstatement beats understatement).
- **STALE** — provenance is null (seeded but unverified) or older than the window, or the descriptor over-declares vs the ledger: re-verify.
- **MISSING** — a native/embedded cell with no ledger provenance: research and add an entry.
- **BROKEN** — surfaced by `pnpm test` (the conformance test): a native/embedded cell whose generated output fails its ledger fingerprint (wrong path / extension / top-level key / shape).
2. **Research ONLY STALE + MISSING** against the tool's OWN primary docs (the §0 verification rules below still apply — reject fabricated / GUI-only / wrong-scope claims). Update the ledger cell's `path`, `ext`, `format`, `fingerprint`, `source` (primary-doc URL), `verifiedAt` (today), `maxAchievable`, and `verdict: "confirmed"`. Never re-research a cell whose provenance is fresh. Directory/projection features (commands, agents, skills) and extensionless ignore files are intentionally unseeded — research those by hand and add cells (or leave `none`).
3. **Fix BROKEN** — correct the generator/importer until `pnpm test` conformance passes for that cell.
4. **Flip GAPS** — for each, follow `./references/capability-update-checklist.md` in full (TDD generator + importer, round-trip symmetry, blast-radius). The format is already in the ledger — do not re-research it. A flip to `native` still requires proven generate **and** import; the matrix never advertises an unproven native.
5. **Guard:** `pnpm capabilities:verify` (every native/embedded cell has provenance) + `pnpm matrix:verify` + the full stack.
The ledger is an oracle, not a source of truth: current levels always come from the descriptor (the matrix derives from there); the ledger records where the tool's docs say the file/shape is, so we validate — never generate — against it. Re-run `pnpm capabilities:seed` after adding or changing a native/embedded feature to refresh fingerprint skeletons.
## Fast Execution Playbook
Optimise for zero wasted tokens. Treat each phase as a gate: only enter the next if the previous signals real work.
**Phase 0 — Deterministic triage (~0 tokens).**
Run `pnpm capabilities:audit --json` then the full verification stack (`pnpm typecheck`, `pnpm lint`, `pnpm test`, `pnpm matrix:verify`, `pnpm capabilities:verify`), capturing the **real exit codes** — never pipe any of those commands through `tail`/`grep`; a non-zero exit masked by the pipeline is the single most common source of false-green audits. If the audit returns 0 gaps, 0 stale, 0 missing, 0 broken **and** all verification passes, **stop** — there is nothing to do.
**Phase 1 — One pipelined pass per target.**
Work only the targets that appear in the gaps/stale/missing/broken buckets or in the current diff. For each such target, execute research → primary-doc verification → ledger update → descriptor fix as **one uninterrupted unit of work**. Do not split into separate "research wave" then "fix wave" — that forces redundant diff re-reads and doubles context. Assignment rules:
- Shared cross-cutting test suites (layout-metadata, agents-folder-structure-research, skill-mirror, reference-rewrite matrix, e2e content contracts) each get **exactly one owner target** designated up front; other targets import from or assert against that owner's output rather than duplicating coverage.
- Verify majors (level raises) once with primary-doc evidence; verify criticals (round-trip symmetry claims, scopeExtras gating, multi-write merge base) twice — run the test and re-read the generator path to confirm the gate is actually reached.
- Ledger cell `path`, `ext`, `format`, and `fingerprint` values MUST be derived from the conformance fixture's actual generated output — not from docs. Docs determine `maxAchievable`, `verdict`, and `source` only.
**Phase 2 — Single-writer close.**
After all per-target fixes are in, merge ledger provenance in one pass, then run `catalog:generate` → `matrix:generate` sequentially. Follow with exactly **one** full-stack run: `pnpm test` to completion, then `pnpm test:e2e` — never concurrent with a build, never interleaved. If any command fails, diagnose before retrying; a second blind retry without root-cause analysis wastes more context than it saves.
## Required Verification
Before claiming completion, every command must pass:
- `pnpm typecheck`
- `pnpm lint`
- `pnpm build` — **before** any e2e/round-trip run. The e2e matrix spawns the built `dist/cli.js`; the in-process contract test does not. If the contract round-trip passes but the e2e fails with a missing/extra/relocated file, the dist is stale — rebuild, don't chase the importer.
- `pnpm test`
- `pnpm matrix:verify`
- `pnpm capabilities:verify`
Run narrower target-scoped tests while iterating, but do not skip the full stack at the end. (Note: a few test runs rewrite `tests/e2e/agents-last-run.md` as a side effect — `git checkout --` that file before committing so it doesn't ride along.)
## Completion Standard
The task is not done until all of the following are true:
- Either the claim was **confirmed** from the tool's own primary source and implemented, or it was **rejected** with a one-line evidence-backed reason — never implemented on faith.
- The new level is declared in the descriptor for each scope it applies to, and `pnpm matrix:verify` passes.
- Generate **and** import are both covered by tests for every level raised to `native`; round-trip preserves content where the format permits.
- Global-only features emit via `scopeExtras` (not a project-leaking `generateX`), gated to `scope === 'global'`, with project scope staying `none`.
- `partial` features have a no-op generator stub and a lint warning verified by tests.
- Multi-write settings files merge with a `pending?.content ?? existing` base; single-combined-write mergers are left untouched.
- Every output path/format change is reflected in all blast-radius sites (contract arrays, e2e exclusion sets, both `reference-targets` chains, `dirTreeExactly`, layout/matrix tests) — verified by a tree-wide grep for the old string.
- No file exceeds 200 lines; no target-name branch was added to shared/core.
- Plugin path holds (rich-plugin fixture updated only if a hook *contract* changed).
- README matrix and the website supported-tools page agree with the descriptor.
- A changeset exists at the right level — `minor` for a new capability (level raise), `patch` for a same-level fix that makes an existing `native` claim actually work. `post-feature-qa` has been applied and any gaps closed.
- The full verification stack passes.