@open-agent-toolkit/cli 0.2.66 → 0.2.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +14 -1
- package/assets/docs/cli-utilities/project-log.md +63 -4
- package/assets/docs/contributing/code.md +8 -4
- package/assets/docs/contributing/skills.md +29 -17
- package/assets/docs/docs-tooling/commands.md +3 -1
- package/assets/docs/provider-sync/manifest-and-drift.md +2 -18
- package/assets/docs/workflows/projects/lifecycle.md +17 -0
- package/assets/docs/workflows/projects/picking-up-projects.md +18 -0
- package/assets/docs/workflows/skills/repo-improve.md +7 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/SKILL.md +19 -37
- package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +58 -15
- package/assets/skills/create-agnostic-skill/references/skill-template.md +17 -15
- package/assets/skills/oat-agent-instructions-apply/SKILL.md +1 -1
- package/assets/skills/oat-agent-instructions-apply/references/instruction-file-templates/glob-scoped-rule.md +1 -4
- package/assets/skills/oat-doctor/SKILL.md +1 -4
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-complete/SKILL.md +158 -30
- package/assets/skills/oat-project-complete/scripts/finalize-synced-archive.mjs +26 -7
- package/assets/skills/oat-project-complete/scripts/validate-durable-archive-receipt.mjs +183 -0
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-retro/SKILL.md +1 -1
- package/assets/skills/oat-project-retro/references/apply-procedure.md +11 -0
- package/assets/skills/oat-project-review-provide/SKILL.md +4 -4
- package/assets/skills/oat-project-summary/SKILL.md +24 -2
- package/assets/skills/oat-repo-improve/SKILL.md +9 -2
- package/assets/skills/oat-repo-improve/references/plan-template.md +4 -6
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +11 -9
- package/assets/skills/oat-wave-execute/SKILL.md +20 -6
- package/assets/skills/oat-wave-program/SKILL.md +9 -4
- package/dist/commands/config/index.d.ts +2 -1
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +133 -38
- package/dist/commands/docs/index-generate/index.d.ts.map +1 -1
- package/dist/commands/docs/index-generate/index.js +68 -12
- package/dist/commands/docs/init/index.d.ts +11 -0
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +19 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +10 -2
- package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
- package/dist/commands/instructions/instructions.utils.js +42 -9
- package/dist/commands/internal/validate-skill-version-bumps.d.ts.map +1 -1
- package/dist/commands/internal/validate-skill-version-bumps.js +5 -5
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +32 -18
- package/dist/commands/project/log/append.d.ts +48 -0
- package/dist/commands/project/log/append.d.ts.map +1 -1
- package/dist/commands/project/log/append.js +207 -30
- package/dist/commands/project/log/check.d.ts +87 -1
- package/dist/commands/project/log/check.d.ts.map +1 -1
- package/dist/commands/project/log/check.js +139 -5
- package/dist/commands/project/log/grammar.d.ts +165 -0
- package/dist/commands/project/log/grammar.d.ts.map +1 -1
- package/dist/commands/project/log/grammar.js +219 -1
- package/dist/commands/project/log/rollup.d.ts +16 -1
- package/dist/commands/project/log/rollup.d.ts.map +1 -1
- package/dist/commands/project/log/rollup.js +22 -2
- package/dist/commands/project/log/synthesize.d.ts +16 -0
- package/dist/commands/project/log/synthesize.d.ts.map +1 -1
- package/dist/commands/project/log/synthesize.js +85 -9
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +24 -2
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +6 -4
- package/dist/config/dispatch-matrix.d.ts.map +1 -1
- package/dist/config/dispatch-matrix.js +13 -5
- package/dist/config/oat-config.d.ts +15 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +61 -7
- package/dist/config/own-keys.d.ts +22 -0
- package/dist/config/own-keys.d.ts.map +1 -0
- package/dist/config/own-keys.js +32 -0
- package/dist/config/resolve.d.ts +11 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +35 -11
- package/dist/config/sync-config.d.ts.map +1 -1
- package/dist/config/sync-config.js +16 -0
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/drift/detector.js +52 -1
- package/dist/drift/skill-view-diagnostic.d.ts.map +1 -1
- package/dist/drift/skill-view-diagnostic.js +2 -23
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +22 -72
- package/dist/engine/managed-copy-hash.d.ts +69 -0
- package/dist/engine/managed-copy-hash.d.ts.map +1 -0
- package/dist/engine/managed-copy-hash.js +175 -0
- package/dist/fs/assets.d.ts +11 -0
- package/dist/fs/assets.d.ts.map +1 -1
- package/dist/fs/assets.js +1 -1
- package/dist/manifest/hash.d.ts +110 -0
- package/dist/manifest/hash.d.ts.map +1 -1
- package/dist/manifest/hash.js +111 -13
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +6 -1
- package/dist/providers/identity/dispatch-report.d.ts.map +1 -1
- package/dist/providers/identity/dispatch-report.js +4 -1
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +21 -0
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +305 -40
- package/package.json +2 -2
|
@@ -93,7 +93,7 @@ Common keys in `.oat/config.json`:
|
|
|
93
93
|
- `git.defaultBranch` — base branch fallback for PR workflows
|
|
94
94
|
- `documentation.root`, `documentation.tooling`, `documentation.config` — docs-surface ownership
|
|
95
95
|
- `documentation.excludes` — a JSON array of globs, relative to the docs directory, that `oat docs generate-index` leaves out of the generated index. `oat config set` takes the list as one comma-separated value (`"a/**,b.md"`) and stores it as an array; repeated `--exclude` flags extend it, and an empty value clears the key
|
|
96
|
-
- `documentation.instructionPointerExcludes` — a JSON array of repository-relative directories that `oat instructions sync` and `oat instructions validate` must not treat as pointer sites, additive to the documentation content root they already skip by default (see [Instruction Sync](../provider-sync/instruction-sync.md#documentation-trees)). `oat config set` takes the list as one comma-separated value (`"vendor/generated,apps/oat-docs/docs"`) and stores it as an array of repository-relative POSIX paths, trimmed and de-duplicated; an empty value clears the key, and `oat config unset documentation.instructionPointerExcludes` removes it. An entry that could never exclude anything — an absolute path, or one escaping the repository with `..` — is rejected with exit code `1` rather than stored. A structurally malformed value already on disk (a non-array, or an empty or non-string entry) is rejected with exit code `2` and a repair message, and `oat config set` can still replace it. Entries that are well formed but cannot exclude anything — among them absolute paths, paths escaping the repository, paths that match no directory (matching is case-sensitive), and the unexcludable `.oat/repo` carve-in root — never abort the command; they are reported as warnings and are not counted as protection. Warnings go to stderr in human mode and to the `exclusionWarnings` field under `--json`
|
|
96
|
+
- `documentation.instructionPointerExcludes` — a JSON array of repository-relative directories that `oat instructions sync` and `oat instructions validate` must not treat as pointer sites, additive to the documentation content root they already skip by default (see [Instruction Sync](../provider-sync/instruction-sync.md#documentation-trees)). `oat config set` takes the list as one comma-separated value (`"vendor/generated,apps/oat-docs/docs"`) and stores it as an array of repository-relative POSIX paths, trimmed and de-duplicated; an empty value clears the key, and `oat config unset documentation.instructionPointerExcludes` removes it. An entry that could never exclude anything — an absolute path, or one escaping the repository with `..` — is rejected with exit code `1` rather than stored. A structurally malformed value already on disk (a non-array, or an empty or non-string entry) is rejected with exit code `2` and a repair message, and `oat config set` can still replace it. Entries that are well formed but cannot exclude anything — among them absolute paths, paths escaping the repository, paths that match no directory (matching is case-sensitive, and the warning names the on-disk spelling when the path differs only in case), paths that resolve elsewhere through a symlink (the warning names the resolved target instead of blaming case-sensitivity), and the unexcludable `.oat/repo` carve-in root — never abort the command; they are reported as warnings and are not counted as protection. Warnings go to stderr in human mode and to the `exclusionWarnings` field under `--json`
|
|
97
97
|
- `documentation.requireForProjectCompletion` — whether docs sync is a completion gate
|
|
98
98
|
- `archive.s3Uri` — base S3 archive prefix
|
|
99
99
|
- `archive.s3SyncOnComplete` — upload archived projects to S3 during completion
|
|
@@ -274,6 +274,19 @@ packaged `assets/` directory next to the installed CLI. Setting a non-empty
|
|
|
274
274
|
unset the override, never to rebuild or reinstall the CLI; a packaged-bundle
|
|
275
275
|
failure keeps the rebuild/reinstall guidance. A directory that exists but
|
|
276
276
|
cannot be read reports the underlying error code.
|
|
277
|
+
- The published npm tarball is held to the same seven-directory shape. The
|
|
278
|
+
CLI's public-package contract names a concrete file under each of the seven
|
|
279
|
+
directories, and release validation requires each one in the build workspace
|
|
280
|
+
and again in the packed tarball. The tarball check is the stronger of the two,
|
|
281
|
+
because a path can exist in the workspace and still never reach the tarball —
|
|
282
|
+
an empty directory that `npm pack` drops, or a `files`/symlink exclusion. So a
|
|
283
|
+
published package cannot ship a bundle whose top-level shape would fail
|
|
284
|
+
`validateBundleStructure`. That is a narrower promise than the exit-2 list
|
|
285
|
+
above: release validation does not check bundle metadata beyond its presence,
|
|
286
|
+
so a malformed or version-mismatched `bundle-metadata.json` is not covered.
|
|
287
|
+
The regression evidence is the negative pack control in
|
|
288
|
+
`packages/cli/src/release/public-package-contract.test.ts`:
|
|
289
|
+
`fails release validation when a required bundle directory is empty in the tarball`.
|
|
277
290
|
- Produce a matching bundle with `bash packages/cli/scripts/bundle-assets.sh`
|
|
278
291
|
while `OAT_ASSETS_DIR` points at the target directory (the script already
|
|
279
292
|
honors the variable as its destination).
|
|
@@ -77,8 +77,10 @@ Two optional flags let an interrupted append be replayed safely:
|
|
|
77
77
|
|
|
78
78
|
- `--idempotency-key <key>` — skip the append when an existing entry body
|
|
79
79
|
already carries `key`, reporting `already-appended` instead of writing a
|
|
80
|
-
duplicate. The key must appear in `--body
|
|
81
|
-
recognizes the entry it already wrote
|
|
80
|
+
duplicate. The key must appear in `--body` as its own whitespace-delimited
|
|
81
|
+
word, since that is how a replay recognizes the entry it already wrote; a key
|
|
82
|
+
glued to varying text such as a timestamp never matches its earlier self.
|
|
83
|
+
Deduplication does not require `--commit`.
|
|
82
84
|
- `--commit` — stage and commit the log after appending, retrying a bounded
|
|
83
85
|
three attempts when the failure is a transient `.git/index.lock`.
|
|
84
86
|
|
|
@@ -101,6 +103,14 @@ instead.
|
|
|
101
103
|
|
|
102
104
|
Run `oat project log append --help` for the complete entry contract.
|
|
103
105
|
|
|
106
|
+
Bodies may use line feeds or CRLF line endings. A CRLF body is accepted and
|
|
107
|
+
stored normalized to line feeds, and the result then carries
|
|
108
|
+
`normalizedLineEndings: true`, so the bytes on disk are known to differ from the
|
|
109
|
+
bytes passed. A lone carriage return, U+2028, or U+2029 anywhere in a body — including
|
|
110
|
+
at its very start or end — is refused, because those are the terminators the
|
|
111
|
+
log's readers do not all agree about. Structural entries take one line and
|
|
112
|
+
accept no line terminator at all.
|
|
113
|
+
|
|
104
114
|
## Automatic workflow integration
|
|
105
115
|
|
|
106
116
|
When project logging is enabled, OAT lifecycle surfaces append structural
|
|
@@ -149,6 +159,25 @@ oat project log check --project .oat/projects/shared/example --json
|
|
|
149
159
|
entry counts by class, type, and scope; the last entry date; and invalid
|
|
150
160
|
hand-written headings. It reads only `project-log.md`.
|
|
151
161
|
|
|
162
|
+
It also reports whether the log carries a completion seal:
|
|
163
|
+
|
|
164
|
+
- `sealed`: `true` once the log holds a structural entry whose producer is
|
|
165
|
+
`oat-project-complete` and whose ref is `seal`. Both halves are required — a
|
|
166
|
+
`seal` ref from another producer is an ordinary entry.
|
|
167
|
+
- `seal`: `null` when unsealed, otherwise the first seal's `heading` and
|
|
168
|
+
`date`, whether it is `keyed`, and the `count` of seal entries. A `count`
|
|
169
|
+
above one is a log sealed twice before the seal append became idempotent.
|
|
170
|
+
|
|
171
|
+
`status` keeps its `ok` / `absent` / `synthesis_pending` values on a sealed log;
|
|
172
|
+
sealing is reported alongside the status, not as a status value. The one
|
|
173
|
+
additional status is `ambiguous`: a `##` heading, or a dated `###` entry
|
|
174
|
+
heading, starts a line after a lone carriage return, U+2028, or U+2029 rather
|
|
175
|
+
than a line feed, so the log's structure can be read two ways; or a seal is
|
|
176
|
+
physically present outside the parseable `## Entries` region. `check` then
|
|
177
|
+
exits 1 and reports an `ambiguity` reason instead of a clean verdict, every
|
|
178
|
+
writing command (`append`, `synthesize`, `rollup`) refuses the same file, and
|
|
179
|
+
the lifecycle skills stop rather than treat the log as empty.
|
|
180
|
+
|
|
152
181
|
Use `--require-synthesis` to exit with status 1 while synthesis is pending:
|
|
153
182
|
|
|
154
183
|
```bash
|
|
@@ -156,7 +185,8 @@ oat project log check --require-synthesis
|
|
|
156
185
|
```
|
|
157
186
|
|
|
158
187
|
Without that flag, normal `absent`, `ok`, and `synthesis_pending` results exit
|
|
159
|
-
successfully so lifecycle skills can decide whether to warn or enforce
|
|
188
|
+
successfully so lifecycle skills can decide whether to warn or enforce;
|
|
189
|
+
`ambiguous` always exits 1.
|
|
160
190
|
|
|
161
191
|
## Complete the synthesis
|
|
162
192
|
|
|
@@ -201,15 +231,44 @@ deduplicate by date and area. The command is idempotent.
|
|
|
201
231
|
|
|
202
232
|
The structured result contains:
|
|
203
233
|
|
|
204
|
-
- `status`: `ok` or `
|
|
234
|
+
- `status`: `ok`, `failed`, or `ambiguous`
|
|
205
235
|
- `summarySection`: `written` or `updated`
|
|
206
236
|
- `ledgerOutcome`: `appended`, `deduplicated`, `skipped_permitted`, or `failed`
|
|
207
237
|
- `entriesRolledUp`: number of log entries written to the summary section
|
|
208
238
|
|
|
239
|
+
An `ambiguous` result carries only `status` and an `ambiguity` reason, and exits
|
|
240
|
+
1: the log's structure has two readings, so no count would mean anything and
|
|
241
|
+
neither `summary.md` nor the ledger is written. The other fields are absent
|
|
242
|
+
rather than zeroed, because `entriesRolledUp: 0` for an unreadable log is
|
|
243
|
+
indistinguishable from the same result for an empty one.
|
|
244
|
+
|
|
209
245
|
`skipped_permitted` means the default repository reference layer is absent and
|
|
210
246
|
no ledger path was explicitly configured; `status` remains `ok`. An explicitly
|
|
211
247
|
configured ledger write failure returns `status: "failed"`. Completion must not
|
|
212
248
|
seal or archive a project with entries until roll-up reports `status: "ok"`.
|
|
213
249
|
|
|
250
|
+
## The completion seal
|
|
251
|
+
|
|
252
|
+
The seal is the last entry a project log may ever receive, and `append`
|
|
253
|
+
enforces that rather than leaving it to convention:
|
|
254
|
+
|
|
255
|
+
- Replaying the seal reports `already-appended` and leaves exactly one seal
|
|
256
|
+
entry. This holds for a seal carrying the completion skill's
|
|
257
|
+
`oat-seal:<project>` key and for an unkeyed seal written before that
|
|
258
|
+
convention, which is recognized by its heading instead.
|
|
259
|
+
- Every append carrying **new** content is refused with `status: "sealed"` and a
|
|
260
|
+
non-zero exit, naming the seal that closed the log.
|
|
261
|
+
- A replay that `--idempotency-key` recognizes as its own earlier entry is the
|
|
262
|
+
one exception: it reports `already-appended` and exits 0 even on a sealed log.
|
|
263
|
+
Nothing is appended — the entry it finds necessarily predates the seal — so
|
|
264
|
+
the seal stays the final entry. This is what keeps a gate
|
|
265
|
+
partial-finalization receipt replayable after the project is completed. The
|
|
266
|
+
key matches a whole word in an existing entry body, so an unrelated append
|
|
267
|
+
whose key happens to occur in some earlier entry is reported the same way
|
|
268
|
+
and likewise writes nothing.
|
|
269
|
+
|
|
270
|
+
A resumed completion therefore reads `sealed` from `check` and skips the
|
|
271
|
+
roll-up and the seal instead of duplicating them.
|
|
272
|
+
|
|
214
273
|
`rollup` requires an existing `summary.md`; summary authoring remains the
|
|
215
274
|
responsibility of the project summary workflow.
|
|
@@ -56,8 +56,8 @@ pnpm build:docs # builds docs site and its dependencies
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
`pnpm test` is composite: it runs the workspace vitest suites, then
|
|
59
|
-
`test:smoke` (`tools/smoke`), `test:skills` (`.agents/skills/*/tests`),
|
|
60
|
-
|
|
59
|
+
`test:smoke` (`tools/smoke`), `test:skills` (`.agents/skills/*/tests`), the
|
|
60
|
+
named-file `test:release` set, and last `test:scripts` (`scripts/worktree`). Steps 5 and 6 are the version-lockstep
|
|
61
61
|
gates; they are in the local list because they previously ran only in CI and
|
|
62
62
|
version-bump drift twice reached review with no local gate to surface it.
|
|
63
63
|
|
|
@@ -73,8 +73,12 @@ checkout with neither `origin/main` nor `main` skips the whole gate (CI uses
|
|
|
73
73
|
`fetch-depth: 0`). Test files under `packages/cli/src/` count as publishable
|
|
74
74
|
changes for this gate.
|
|
75
75
|
|
|
76
|
-
CI runs neither `pnpm lint` nor `pnpm format`
|
|
77
|
-
|
|
76
|
+
CI runs neither `pnpm lint` nor `pnpm format`. `pnpm check` now covers the
|
|
77
|
+
formatting of `.agents/skills/**`, `apps/oat-docs/docs`, and `tools/smoke`
|
|
78
|
+
through `format:root`, but `pnpm lint`'s root `oxlint` pass over `tools/smoke`
|
|
79
|
+
and `.agents/skills`, and `packages/control-plane`'s `format` (it defines no
|
|
80
|
+
`check` script), still run in no CI gate — run both whenever a change touches
|
|
81
|
+
those paths.
|
|
78
82
|
For narrower changes, use package-specific checks when possible, but do not
|
|
79
83
|
merge without passing the relevant workspace gates.
|
|
80
84
|
|
|
@@ -203,15 +203,19 @@ resolution. `resolveSkillVersion` in
|
|
|
203
203
|
`packages/cli/src/commands/shared/frontmatter.ts` owns that order, so the
|
|
204
204
|
runtime helper and the validators cannot disagree.
|
|
205
205
|
|
|
206
|
-
The top-level `version` field remains supported as a deprecated alias
|
|
207
|
-
|
|
208
|
-
`version
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
206
|
+
The top-level `version` field remains supported as a deprecated alias, and a
|
|
207
|
+
skill that declares it is now reported as an **error**. Every bundled skill
|
|
208
|
+
declares `metadata.version` and carries no top-level `version`, so
|
|
209
|
+
`pnpm oat:validate-skills` reports no alias findings on the bundled tree. The
|
|
210
|
+
alias is still read for third-party skills installed from packs, which may
|
|
211
|
+
carry it; it retires on the schedule recorded in
|
|
212
|
+
`DR-260908-bundled-skills-declare`. Step 1 of that schedule — promoting the
|
|
213
|
+
alias finding from a warning to an error — ships in the first release after
|
|
214
|
+
0.2.65 that changes the validator. Step 2 removes the resolver's top-level read
|
|
215
|
+
one release after that error has produced no findings on the bundled tree; it
|
|
216
|
+
is tracked by `BL-260908-remove-the-top-level-skill` and must account for the
|
|
217
|
+
canonical agent roles, which the bump gate now enforces while they still
|
|
218
|
+
declare the top-level field.
|
|
215
219
|
|
|
216
220
|
A skill that carries both fields with different values is a conflict. The
|
|
217
221
|
resolver reports the `metadata.version` value together with the conflict, and
|
|
@@ -220,7 +224,7 @@ than silently picking one, and canonical role resolution treats the identity as
|
|
|
220
224
|
invalid. The runtime version readers still return the `metadata.version` value,
|
|
221
225
|
so an installed-versus-bundled comparison keeps working while the conflict is
|
|
222
226
|
being fixed. Carrying both with the _same_ value resolves without a conflict and
|
|
223
|
-
without an alias
|
|
227
|
+
without an alias finding, because `metadata.version` wins. A bundled skill must
|
|
224
228
|
still carry `metadata.version` alone: the corpus sweep in
|
|
225
229
|
`packages/cli/src/validation/skills.test.ts` fails on any column-0 `version:`
|
|
226
230
|
line under `.agents/skills`, which is the only check that catches the
|
|
@@ -228,16 +232,24 @@ same-value case.
|
|
|
228
232
|
|
|
229
233
|
### The version is gated
|
|
230
234
|
|
|
231
|
-
Changing any canonical skill
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
Changing any bundled file of a canonical skill — anything under
|
|
236
|
+
`.agents/skills/<name>/` except `tests/`, because `tests/` is the one subtree
|
|
237
|
+
the bundle strips — requires bumping that skill's `metadata.version` in the
|
|
238
|
+
same PR, one bump per changed skill in the final PR diff, even if the skill was
|
|
239
|
+
edited multiple times on the branch. A change to a skill's `scripts/` or
|
|
240
|
+
`references/` therefore needs the bump just as an edit to `SKILL.md` does: both
|
|
241
|
+
ship to every `oat tools install` consumer. Changing a canonical agent role
|
|
242
|
+
under `.agents/agents/*.md` requires bumping that file's top-level `version:`;
|
|
243
|
+
agent roles deliberately keep the top-level field, so the gate accepts either
|
|
244
|
+
declaration shape and never demands `metadata.version` of them. The gate reads
|
|
245
|
+
the resolved version, so it enforces the bump whether the file declares
|
|
235
246
|
`metadata.version` or the top-level alias. The rule is enforced by
|
|
236
247
|
`pnpm run check:skill-bumps`, which runs locally (root `AGENTS.md` Definition
|
|
237
248
|
of Done) and in CI; a changed skill whose version matches `origin/main` fails
|
|
238
|
-
the gate. The
|
|
239
|
-
`check:skill-bumps` fails on any finding it receives
|
|
240
|
-
routed through it would fail every changed skill that still
|
|
249
|
+
the gate. The alias finding above is deliberately not part of that gate:
|
|
250
|
+
`check:skill-bumps` fails on any finding it receives regardless of severity, so
|
|
251
|
+
an alias finding routed through it would fail every changed skill that still
|
|
252
|
+
carried one.
|
|
241
253
|
|
|
242
254
|
## Practical Authoring Flow
|
|
243
255
|
|
|
@@ -132,11 +132,13 @@ Key behavior:
|
|
|
132
132
|
- treats explicitly supplied `--docs-dir` / `--output` paths as overrides resolved from the current directory
|
|
133
133
|
- fails with exit code `2` before generating or writing anything when an omitted path has no non-empty `documentation.root` to resolve against, or when the configured root is not a directory
|
|
134
134
|
- refuses unsafe output targets with exit code `1` before generation, for derived and explicit paths alike, comparing symlink-resolved paths: inside the docs directory it indexes, equal to `documentation.config`, or ending in `.yml` / `.yaml` in any case. A derived output whose existing file lacks the `AUTOGENERATED` header is refused too; naming that path with `--output` overwrites it explicitly. A refused target is an actionable flag error (`1`); unusable path configuration is a separate condition and exits `2`, so scripts can branch on the two
|
|
135
|
+
- refuses a symlink chain that exceeds its own 32-hop cap, naming the path you supplied or the CLI derived rather than an intermediate link, and addressing the flag that owns it: an unusable **output** chain names `--output` and exits `1`; an unusable **docs directory** chain names `--docs-dir` and, when the directory was derived from `documentation.root` rather than passed explicitly, also names the `oat config set documentation.root <path>` repair and exits `2` as unusable path configuration. That cap governs the dangling links the command walks itself; a chain the operating system refuses first surfaces as its own `ELOOP` error with exit `1`, which is what a too-deep chain reports on a platform whose own limit is 32 or lower
|
|
135
136
|
- writes configuration only for the Fumadocs manifest transition — recording the manifest it just wrote inside `documentation.root` in `documentation.index`, when `documentation.tooling` is `fumadocs` or the config declares neither `tooling` nor `config`. MkDocs configurations are never written, and `documentation.root` and `documentation.config` are never modified
|
|
136
137
|
- prepends an `AUTOGENERATED` warning comment to the output and rewrites the file on every run; do not hand-edit the generated `index.md`
|
|
137
138
|
- should be freshness-checked against authored `docs/**/index.md` `## Contents` maps before treating it as navigation evidence
|
|
138
139
|
- sorting: `index.md` first, then directories before files, then lexical
|
|
139
|
-
- reports the derived docs directory in human output and as `docsDir` / `docsDirSource` under `--json`
|
|
140
|
+
- reports the derived docs directory in human output and as `docsDir` / `docsDirSource` under `--json`, alongside `excludes` — the effective exclusion list, `documentation.excludes` merged with the `--exclude` flags exactly as it was handed to the generator
|
|
141
|
+
- says where to look when a manifest is empty rather than reporting a bare `0 entries`: which exclusion patterns were active, or that the docs directory held no indexable pages. The wording is observational — the command reports indexed entries, not pattern matches, so it names the exclusions without asserting they are the cause. An empty manifest is a report, not a failure — the file is still written, so a stale index is never left behind, and the command still exits `0`
|
|
140
142
|
- omits pages matching the exclusion list. Nothing is excluded by default; once listed, non-page Markdown such as `CLAUDE.md` or `AGENTS.md` stops reaching the manifest. Patterns come from `documentation.excludes` in `.oat/config.json` and from repeated `--exclude` flags, and the flags **extend** the configured list rather than replacing it. A directory left empty by exclusion emits no heading, and an empty list produces byte-identical output to no exclusions at all
|
|
141
143
|
|
|
142
144
|
Supported flags:
|
|
@@ -95,8 +95,8 @@ the manifest.
|
|
|
95
95
|
|
|
96
96
|
- `missing-additive` — active, supported, no manifest entry, nothing at the expected path: the only true projection gap
|
|
97
97
|
- `removed` — a manifest entry exists but the provider file is gone
|
|
98
|
-
- `modified` — a manifest entry exists and the view no longer agrees with what the last sync recorded, or its version has fallen behind canonical
|
|
99
|
-
- `in-sync` — a symlinked, collection-aliased, or natively read view _is_ the canonical file; a `copy` view matches the content recorded at its last sync
|
|
98
|
+
- `modified` — a manifest entry exists and the view no longer agrees with what the last sync recorded, or its version has fallen behind canonical
|
|
99
|
+
- `in-sync` — a symlinked, collection-aliased, or natively read view _is_ the canonical file; a `copy` view matches the content recorded at its last sync. A managed directory copy is compared with its OAT-managed banner and its `.oat-generated` sentinel excluded, so a freshly synced copy reads `in_sync` rather than drifted (owned by `skill-view-convergence.integration.test.ts`, "converges a copy-strategy skill directory")
|
|
100
100
|
- `untracked` — something exists at the expected path that no manifest entry tracks; stray detection skips provider entries whose name matches a canonical entry, so `oat status` does not report it as a stray and reports the untracked projection as `missing` instead
|
|
101
101
|
- `unverified` — the view's state is unknown: either a manifest entry arrived with no drift observation, or reading that one view failed and the row carries the redacted reason
|
|
102
102
|
- `inactive`, `unsupported`, `excluded` — no projection is expected in this scope, so none of them is reported as missing
|
|
@@ -173,22 +173,6 @@ declared values and says the comparison was skipped, so the ambiguity is
|
|
|
173
173
|
visible rather than silently resolved. When the resolver's answer happens to
|
|
174
174
|
agree with canonical, nothing is withheld and the detail says so instead.
|
|
175
175
|
|
|
176
|
-
### Known limitation: copy-strategy skill views
|
|
177
|
-
|
|
178
|
-
A `copy` skill view is reported `modified` immediately after a successful sync,
|
|
179
|
-
and stays that way. The engine writes an OAT-managed banner into the copied
|
|
180
|
-
`SKILL.md` and an `.oat-generated` sentinel beside it, and neither is accounted
|
|
181
|
-
for in the manifest hash, so `oat status` reports `drifted:modified` and every
|
|
182
|
-
later `oat sync --dry-run` plans another `update_copy`. Because no sync clears
|
|
183
|
-
that state, `oat tools info` prints no repair line when a `modified` copy's
|
|
184
|
-
version still matches canonical.
|
|
185
|
-
|
|
186
|
-
That suppression is a conservative heuristic rather than a proof: equal versions
|
|
187
|
-
do not establish equal bodies, so an edit to the canonical source or to the copy
|
|
188
|
-
that kept the version reaches the same branch, and a sync _would_ repair that
|
|
189
|
-
one. The class detail says so and names the concrete scope command to run if you
|
|
190
|
-
know either side was edited. Tracked as `BL-260908-make-copy-strategy-skill`.
|
|
191
|
-
|
|
192
176
|
## Stray adoption
|
|
193
177
|
|
|
194
178
|
`oat init` and `oat status` can offer adoption of unmanaged provider entries into canonical `.agents`.
|
|
@@ -113,6 +113,15 @@ and retro is not added to the lite closeout sequence.
|
|
|
113
113
|
On completion, OAT treats archive handling as an explicit closeout choice:
|
|
114
114
|
|
|
115
115
|
- When archiving is selected, the local archive is written to `.oat/projects/archived/<project>/`.
|
|
116
|
+
- Every completion that will actually archive — any durable (`shared` or
|
|
117
|
+
`synced`) project with archive selected — keeps the `activeProject` pointer
|
|
118
|
+
until the archive returns a validated receipt, and only then clears it.
|
|
119
|
+
`local` projects are never durable and never archive, so they clear the
|
|
120
|
+
pointer immediately, as does any completion that declines archive. An archive
|
|
121
|
+
failure therefore leaves the pointer intact and the completion directly
|
|
122
|
+
resumable. See
|
|
123
|
+
[Picking Up a Project](picking-up-projects.md#archive-contents) for the
|
|
124
|
+
post-archive resume and its manual recovery path.
|
|
116
125
|
- When archiving is disabled or declined, durable projects remain at their
|
|
117
126
|
active path. Synced completion still finalizes and pushes the project ref,
|
|
118
127
|
commits the discovery record as `complete`, retains the checkout and ref, and
|
|
@@ -183,6 +192,14 @@ each finding as a `deferred advisory` warning and continues, a project with no l
|
|
|
183
192
|
final completion summary, and a resumed completion whose log already
|
|
184
193
|
carries a seal runs report-only and appends nothing.
|
|
185
194
|
|
|
195
|
+
A resume detects that seal from `oat project log check`, which reports a
|
|
196
|
+
`sealed` field, rather than by re-reading the log. The invariant is enforced in
|
|
197
|
+
the CLI: replaying the seal reports `already-appended` and leaves exactly one
|
|
198
|
+
seal entry; a replay recognized by its own idempotency key reports
|
|
199
|
+
`already-appended` even on a sealed log (nothing is appended), and every
|
|
200
|
+
append carrying new content is refused with `status: "sealed"` and a non-zero
|
|
201
|
+
exit.
|
|
202
|
+
|
|
186
203
|
Repositories that never adopted PJM skip the sweep with a one-line note. A
|
|
187
204
|
missing planning surface degrades the sweep, never the closeout.
|
|
188
205
|
|
|
@@ -99,6 +99,24 @@ If closeout is interrupted after terminal archive identity exists, rerun
|
|
|
99
99
|
completion so it can resume from the completed ref and archive metadata. Do not
|
|
100
100
|
use `pull` or `open` to recreate an active record or checkout.
|
|
101
101
|
|
|
102
|
+
For a `shared` project, archive moves the project into
|
|
103
|
+
`.oat/projects/archived/<project>/` and removes the source directory, while
|
|
104
|
+
completion keeps the `activeProject` pointer until the receipt validates.
|
|
105
|
+
Rerunning completion after an interruption between the archive and that clear
|
|
106
|
+
recognizes exactly this state — the pointer names a source directory that no
|
|
107
|
+
longer exists and the archive carries `oat_lifecycle: complete` plus the
|
|
108
|
+
`Lifecycle complete; archived locally` phase marker — so it validates the
|
|
109
|
+
discovered archive and clears the pointer without archiving a second time or
|
|
110
|
+
sealing the project log again. An interruption before the archive leaves the
|
|
111
|
+
source directory in place, so completion simply reruns from the start and skips
|
|
112
|
+
the work it already finished.
|
|
113
|
+
|
|
114
|
+
If the archive cannot be discovered — the source directory is gone and either
|
|
115
|
+
no archived project or several match the name — completion stops and leaves the
|
|
116
|
+
pointer untouched. Recover manually: locate the archive directory under
|
|
117
|
+
`.oat/projects/archived/`, confirm `oat_lifecycle: complete` in its `state.md`,
|
|
118
|
+
then clear the pointer with `oat config set activeProject ""`.
|
|
119
|
+
|
|
102
120
|
## Related
|
|
103
121
|
|
|
104
122
|
- [Reviewing OAT PRs](reviewing-oat-prs.md)
|
|
@@ -72,9 +72,13 @@ Failure to publish a backlog item or issue does not invalidate a successfully wr
|
|
|
72
72
|
|
|
73
73
|
Full repository audits use bounded read-only reconnaissance while the root
|
|
74
74
|
agent retains classification, vetting, prioritization, cross-lane synthesis,
|
|
75
|
-
and plan writing.
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
and plan writing. Plan writes never move below the caller's model class — a
|
|
76
|
+
parallelized author runs on the caller's model and every plan is
|
|
77
|
+
caller-reviewed before publication or wave composition; the
|
|
78
|
+
`keeps external-plan writes on the caller's model class` case in
|
|
79
|
+
`skills-bundled-docs-contract.test.ts` is the backstop. Before launch, the
|
|
80
|
+
caller loads the durable task classes and model-selection principles from
|
|
81
|
+
`subagent-orchestration` plus exactly one active-provider selection reference.
|
|
78
82
|
|
|
79
83
|
The internal `oat-dispatch-subagents` skill then owns capability checks, live
|
|
80
84
|
catalog intersection, exact route selection, launch acceptance, recovery, and
|
|
@@ -6,7 +6,7 @@ disable-model-invocation: true
|
|
|
6
6
|
allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
|
|
7
7
|
user-invocable: true
|
|
8
8
|
metadata:
|
|
9
|
-
version: 1.
|
|
9
|
+
version: 1.5.0
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Create Skill
|
|
@@ -69,7 +69,7 @@ If not provided in arguments, ask for:
|
|
|
69
69
|
**The context window is a shared resource.** Skills share context with everything else the agent needs. Structure information in three levels:
|
|
70
70
|
|
|
71
71
|
1. **Metadata** (~100 words): Name + description in frontmatter, always loaded
|
|
72
|
-
2. **SKILL.md body** (
|
|
72
|
+
2. **SKILL.md body** (~5,000 tokens): Loads when skill triggers
|
|
73
73
|
3. **Bundled resources**: Files in `references/`, `scripts/`, `assets/` loaded as-needed
|
|
74
74
|
|
|
75
75
|
**Writing principles:**
|
|
@@ -172,11 +172,12 @@ Natural language request that triggers this skill
|
|
|
172
172
|
**Frontmatter notes:**
|
|
173
173
|
|
|
174
174
|
- `argument-hint`, `allowed-tools`, `user-invocable`, `context`, `hooks` are Claude Code specific
|
|
175
|
-
-
|
|
175
|
+
- `allowed-tools`: write the value as a **comma-separated** list. The spec's own example is space-delimited and OAT never parses the separator — `validateOatSkills` in `packages/cli/src/validation/skills.ts` only checks that the key is present, and `getToolDetail` in `packages/cli/src/commands/tools/info/index.ts` reads the raw scalar — so this is OAT's authoring convention rather than a runtime contract. Backstop: `it('declares allowed-tools as a comma-separated list in every canonical skill')` in `packages/cli/src/validation/skills.test.ts`
|
|
176
|
+
- The spec defines a fixed field set, and providers differ in which extension fields they read. An unread field is inert rather than guaranteed harmless, so check the dated compatibility section of `references/docs/skills-guide.md` for the per-provider picture before depending on one
|
|
176
177
|
- `name`: max 64 chars for cross-provider portability (Codex allows 100, but 64 is the spec limit)
|
|
177
178
|
- `metadata.version`: include valid semver and start new skills at `1.0.0`. The Agent Skills specification puts the version under `metadata`, and OAT resolves `metadata.version` first and the top-level `version` second — `resolveSkillVersion` in `packages/cli/src/commands/shared/frontmatter.ts` owns that order, backstopped by `packages/cli/src/commands/shared/frontmatter.test.ts`
|
|
178
|
-
- `version` (top-level): the deprecated alias, still read when `metadata.version` is absent.
|
|
179
|
-
- `description`: **single line, ≤ 500 chars
|
|
179
|
+
- `version` (top-level): the deprecated alias, still read when `metadata.version` is absent — but a skill whose only version is that alias no longer validates. `validateOatSkills` in `packages/cli/src/validation/skills.ts` reports it as `skill-version-alias` at `severity: 'error'`, so `pnpm oat:validate-skills` fails the skill outright; the pass runs over every skill directory, not just `oat-*`, so an agnostic skill is covered too. Backstop: `it('reports exactly once for a non-oat-* alias-only skill')` in `packages/cli/src/validation/skills.test.ts`. Setting both to different values is the separate `skill-version-conflict` error: OAT reports the conflict, skill validation fails on it, and canonical role identity rejects it. Declare `metadata.version` and leave the alias out
|
|
180
|
+
- `description`: **single line, ≤ 500 chars**. This is OAT's house rule, not a provider requirement: `validateOatSkills` in `packages/cli/src/validation/skills.ts` enforces it only for skills whose directory name starts with `oat-`. For every other skill it is an unenforced authoring convention this repository follows for portability. Backstops in `packages/cli/src/validation/skills.test.ts`: `it('reports description longer than 500 characters')` and `it('does not report a description longer than 500 characters for a non-oat-* skill')`. The spec allows 1024
|
|
180
181
|
- Bump `metadata.version` on future edits: patch for fixes/clarifications, minor for backward-compatible behavior additions, major for breaking workflow/interface changes
|
|
181
182
|
|
|
182
183
|
**Writing the `description` field:**
|
|
@@ -194,7 +195,7 @@ Examples:
|
|
|
194
195
|
- Bad: "Reviews code by checking spec compliance, then code quality, then creates PR"
|
|
195
196
|
- Good: "Use when reviewing code or checking PRs. Systematic quality and security analysis."
|
|
196
197
|
|
|
197
|
-
Present the plan and
|
|
198
|
+
Present the plan and ask once for approval, stating the approval scope: it covers the skill directory, its `SKILL.md`, and the supporting files this plan named, for the rest of this run. Re-ask only if the file set changes. If the user declines, stop before creating any file and report the plan instead.
|
|
198
199
|
|
|
199
200
|
### Step 4: Create Skill File
|
|
200
201
|
|
|
@@ -231,18 +232,21 @@ Skills can include supporting files in subdirectories:
|
|
|
231
232
|
|
|
232
233
|
### Step 5: Sync and Verify
|
|
233
234
|
|
|
234
|
-
|
|
235
|
+
If the repository uses OAT sync, refresh the provider views for this repository only:
|
|
235
236
|
|
|
236
237
|
```bash
|
|
237
|
-
oat sync
|
|
238
|
+
oat sync --scope project
|
|
238
239
|
```
|
|
239
240
|
|
|
241
|
+
A bare `oat sync` defaults to `--scope all`, which also rewrites the invoking user's home-scope provider
|
|
242
|
+
directories. `withScopeOption` in `packages/cli/src/commands/shared/scope-option.ts` owns that default, and `it('sync --help matches snapshot')` in `packages/cli/src/commands/help-snapshots.test.ts` is its backstop.
|
|
243
|
+
|
|
240
244
|
Verify:
|
|
241
245
|
|
|
242
246
|
- File created at `.agents/skills/{skill-name}/SKILL.md`
|
|
243
247
|
- Frontmatter syntax is valid
|
|
244
248
|
- Frontmatter includes valid semver `metadata.version:` (new skills start at `1.0.0`)
|
|
245
|
-
- Skill
|
|
249
|
+
- Skill resolves through the provider views after a scoped sync — check with `oat tools info {skill-name}` or the provider's own skill list
|
|
246
250
|
- Examples include both invocation styles
|
|
247
251
|
- If the skill name starts with `oat-`, run `pnpm oat:validate-skills` and fix any findings
|
|
248
252
|
|
|
@@ -268,7 +272,7 @@ Provide:
|
|
|
268
272
|
- **Context window is a public good**—keep skills lean, challenge every paragraph
|
|
269
273
|
- Description is the trigger—include "when to use" in frontmatter, not just body
|
|
270
274
|
- Bump `metadata.version` for edits: patch = fixes/clarifications, minor = backward-compatible additions, major = breaking changes
|
|
271
|
-
- Keep SKILL.md **under 500 lines / ~5,000 tokens**
|
|
275
|
+
- Keep SKILL.md **under 500 lines / ~5,000 tokens** — OAT's authoring budget, not a specification limit; see the dated provider-compatibility section of `references/docs/skills-guide.md` for what each provider documents
|
|
272
276
|
- Use clear, task-based headings
|
|
273
277
|
- Include working examples for both invocation styles
|
|
274
278
|
- Document all arguments with defaults
|
|
@@ -289,7 +293,7 @@ Skills that need user decisions (parameter choices, confirmations, disambiguatio
|
|
|
289
293
|
|
|
290
294
|
Do **not** hard-code a specific Codex question tool name in skill prose unless the runtime contract is guaranteed. Prefer capability-based wording ("structured user-input tooling when available") so the skill remains portable across Codex hosts.
|
|
291
295
|
|
|
292
|
-
**Claude Code enhancement:** Add `AskUserQuestion` to `allowed-tools` in frontmatter. Claude Code renders these as structured UI prompts with selectable options, headers, and multi-select support.
|
|
296
|
+
**Claude Code enhancement:** Add `AskUserQuestion` to `allowed-tools` in frontmatter. Claude Code renders these as structured UI prompts with selectable options, headers, and multi-select support. Providers that do not read `allowed-tools` handle the same instructions as conversational questions; treat the field as having no effect there rather than as universally supported, and check the dated compatibility matrix in `references/docs/skills-guide.md`.
|
|
293
297
|
|
|
294
298
|
**When to include interactive input:**
|
|
295
299
|
|
|
@@ -374,32 +378,11 @@ For multi-step skills, print brief progress updates so the user knows what's hap
|
|
|
374
378
|
|
|
375
379
|
### Frontmatter Reference
|
|
376
380
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
| Field | Spec | Claude Code | Cursor | Codex CLI | Gemini CLI |
|
|
380
|
-
| -------------------------- | --------------- | ----------- | ------ | ----------- | ---------- |
|
|
381
|
-
| `name` | ✅ required | ✅ | ✅ | ✅ required | ✅ |
|
|
382
|
-
| `description` | ✅ required | ✅ | ✅ | ✅ required | ✅ |
|
|
383
|
-
| `license` | ✅ optional | ❓ | ✅ | 💤 | ❓ |
|
|
384
|
-
| `compatibility` | ✅ optional | ❓ | ✅ | 💤 | ❓ |
|
|
385
|
-
| `metadata` | ✅ optional | ❓ | ✅ | 💤 | ❓ |
|
|
386
|
-
| `allowed-tools` | ⚠️ experimental | ✅ | ❓ | 💤 | ❓ |
|
|
387
|
-
| `disable-model-invocation` | ❌ | ✅ | ✅ | 💤 | ❓ |
|
|
388
|
-
| `user-invocable` | ❌ | ✅ | ❓ | 💤 | ❓ |
|
|
389
|
-
| `argument-hint` | ❌ | ✅ | ❓ | 💤 | ❓ |
|
|
390
|
-
| `context` / `agent` | ❌ | ✅ | ❌ | 💤 | ❓ |
|
|
391
|
-
| `hooks` | ❌ | ✅ | ❌ | 💤 | ❓ |
|
|
392
|
-
|
|
393
|
-
**Key takeaway:** `name` + `description` are the only truly portable interface. Codex ignores unknown keys (safe to include Claude fields), so layer tool-specific fields on top of a portable baseline. For the full matrix, see `references/docs/skills-guide.md` (bundled with this skill).
|
|
381
|
+
**Key takeaway:** `name` + `description` are the only truly portable interface. Layer tool-specific fields on top of that baseline, but treat an unread field as inert rather than guaranteed harmless — providers differ in which extension fields they read, and not every provider documents what it does with the rest. The single canonical, dated compatibility matrix lives in `references/docs/skills-guide.md` (bundled with this skill); consult it rather than a copy.
|
|
394
382
|
|
|
395
383
|
### Detail Level
|
|
396
384
|
|
|
397
|
-
|
|
398
|
-
| --------------------- | ------------ | ------------------------------ |
|
|
399
|
-
| Complex workflows | Detailed | docs-new, docs-review |
|
|
400
|
-
| Simple command-like | Concise | update-doc-refs, create-ticket |
|
|
401
|
-
| Reference/standards | Detailed | repo-documentation |
|
|
402
|
-
| Helper (auto-invoked) | Moderate | read-relevant-docs |
|
|
385
|
+
For the detail level each skill type warrants, see `references/skill-template.md`.
|
|
403
386
|
|
|
404
387
|
## Examples
|
|
405
388
|
|
|
@@ -428,7 +411,7 @@ I need a skill for running database migrations
|
|
|
428
411
|
- [Agent Skills Open Standard](https://agentskills.io) — the spec
|
|
429
412
|
- [Claude Code Skills](https://code.claude.com/docs/en/skills) — Claude-specific features
|
|
430
413
|
- [Cursor Skills](https://cursor.com/docs/context/skills) — Cursor-specific features
|
|
431
|
-
- [Codex CLI Skills](https://
|
|
414
|
+
- [Codex CLI Skills](https://learn.chatgpt.com/docs/build-skills) — Codex-specific features
|
|
432
415
|
- [Gemini CLI Skills](https://geminicli.com/docs/cli/skills/) — Gemini-specific features
|
|
433
416
|
- [npx skills CLI](https://github.com/vercel-labs/skills) — installing remote/community skills
|
|
434
417
|
- [Skills best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) — authoring guidance
|
|
@@ -439,7 +422,7 @@ I need a skill for running database migrations
|
|
|
439
422
|
|
|
440
423
|
**Skill not appearing in menu:**
|
|
441
424
|
|
|
442
|
-
- Run `oat sync` to regenerate provider views
|
|
425
|
+
- Run `oat sync --scope project` to regenerate this repository's provider views
|
|
443
426
|
- Verify YAML frontmatter syntax is valid
|
|
444
427
|
- Check that skill name matches directory name
|
|
445
428
|
- Ensure `user-invocable` is not set to `false` (Claude Code)
|
|
@@ -461,7 +444,6 @@ I need a skill for running database migrations
|
|
|
461
444
|
Successful skill creation:
|
|
462
445
|
|
|
463
446
|
- ✅ Skill created at `.agents/skills/{name}/SKILL.md`
|
|
464
|
-
- ✅ `oat sync` run successfully
|
|
465
447
|
- ✅ For `oat-*` skills, `pnpm oat:validate-skills` passes
|
|
466
448
|
- ✅ Frontmatter valid
|
|
467
449
|
- ✅ Workflow uses "Step" naming
|