You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ca0a698
Browse filesBrowse the repository at this point in the historyBrowse files
test(cli): derive the guard's inputs instead of restating them
Review feedback on the cross-reference guard, three findings, one root
cause each:
- The subcommand alternation was a hand-copied duplicate of the registry
in src/index.ts. A command added there and forgotten here would drop
out of the guard silently. Moved the names to src/commands/names.ts and
had index.ts check its record against them with `satisfies`, so the
drift is a type error.
- The citation checks anchored on a fixed `taskless|@taskless/cli`
spelling, which matches nothing a dev/self build renders — under those
targets every check found zero citations and passed without measuring
anything. The anchor now derives from `buildInvocation()`, and the
dangling-citation check fails when it finds no citation at all.
- openspec/specs/cli-agent claimed SKILL.md and tskl.md express the CLI
as `%(TASKLESS_CLI)s`. They do not, by design: they carry the canonical
`npx @taskless/cli` that `applyCliInvocation` rewrites. Reworded the
requirement to describe both mechanisms, and scoped the automated-check
sentence to recipe sources, which is all it covers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cyga14bww8rmazH2XrF8ms
Copy file name to clipboardExpand all lines: openspec/specs/cli-agent/spec.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -269,11 +269,14 @@ No embedded recipe SHALL contain the string `taskless help`. Recipes cross-refer
269
269
270
270
### Requirement: Recipes name the CLI by its full invocation
271
271
272
-
Every instruction in shipped agent-facing content that tells a reader to run the Taskless CLI SHALL express the CLI as `%(TASKLESS_CLI)s`, followed by the subcommand and its arguments. This applies to the recipe sources under `packages/cli/src/agent/`, to `skills/taskless/SKILL.md`, and to `commands/tskl/tskl.md`.
272
+
Every instruction in shipped agent-facing content that tells a reader to run the Taskless CLI SHALL name the CLI by the invocation the build resolves for the reader, followed by the subcommand and its arguments — never by a hand-written one. Two mechanisms deliver that, because the content travels by two different paths:
273
273
274
-
Content SHALL NOT name the CLI as a bare `taskless` binary, because it is not installed on `PATH` for the overwhelming majority of readers, and SHALL NOT hardcode a launcher-and-package string such as `npx @taskless/cli`, because that is the fact `%(TASKLESS_CLI)s` exists to hold in one place. Prose that mentions the product, a config filename, or a directory (`taskless.config`, `.taskless/`) is unaffected — the requirement is about executable instructions.
274
+
- Recipe sources under `packages/cli/src/agent/` SHALL express the CLI as `%(TASKLESS_CLI)s`, which the recipe renderer substitutes at render time.
275
+
-`skills/taskless/SKILL.md` and `commands/tskl/tskl.md` are not rendered through the recipe renderer, so they SHALL carry the canonical `npx @taskless/cli` string, which `applyCliInvocation` rewrites to the build target's invocation when the content is emitted.
275
276
276
-
An automated check SHALL fail when a bare `` `taskless <subcommand>` `` invocation appears in a recipe source, so the normalization cannot silently regress as recipes are edited.
277
+
Content SHALL NOT name the CLI as a bare `taskless` binary, because it is not installed on `PATH` for the overwhelming majority of readers. A recipe source SHALL NOT hardcode a launcher-and-package string such as `npx @taskless/cli` either, because that is the fact `%(TASKLESS_CLI)s` exists to hold in one place — the string is canonical only in the two files above, where it is the rewrite anchor rather than a hardcoding. Prose that mentions the product, a config filename, or a directory (`taskless.config`, `.taskless/`) is unaffected — the requirement is about executable instructions.
278
+
279
+
An automated check SHALL fail when a bare `` `taskless <subcommand>` `` invocation, or a hardcoded `npx @taskless/cli`, appears in a recipe source, so the normalization cannot silently regress as recipes are edited. The check SHALL read the subcommand names from the CLI's own registry rather than restating them, so a newly added subcommand is covered without a second edit. It does not extend to `skills/taskless/SKILL.md` or `commands/tskl/tskl.md`, whose rewrite anchor is the very string it flags and which quote invocations as example user utterances.
277
280
278
281
#### Scenario: A recipe instructs the reader to run a subcommand
279
282
@@ -294,3 +297,5 @@ An automated check SHALL fail when a bare `` `taskless <subcommand>` `` invocati
294
297
295
298
-**WHEN** the check that recipe cross-references cite only topics that resolve is run
296
299
-**THEN** it SHALL operate on rendered recipe text, where the invocation is a stable literal, rather than on source text where it is a placeholder
300
+
-**AND** it SHALL anchor on the invocation the running build actually renders, so the check does not pass vacuously under a `nightly`, `dev`, or `self` build whose rendered invocation names neither `taskless` nor `@taskless/cli`
301
+
-**AND** it SHALL fail when it finds no cross-reference at all, since an empty result is otherwise indistinguishable from every reference resolving
0 commit comments