canary-test-cli 7.1.0 → 8.0.0

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.
Files changed (128) hide show
  1. package/agents/skills/README.md +327 -0
  2. package/agents/skills/canary:generate.md +49 -0
  3. package/agents/skills/canary:init.md +37 -0
  4. package/agents/skills/canary:migrate.md +66 -0
  5. package/agents/skills/claude-code/canary-add-framework/SKILL.md +248 -0
  6. package/agents/skills/claude-code/canary-batwoman/SKILL.md +119 -0
  7. package/agents/skills/claude-code/canary-blackhawk/SKILL.md +170 -0
  8. package/agents/skills/claude-code/canary-blackhawk/scripts/cli.mjs +188 -0
  9. package/agents/skills/claude-code/canary-blackhawk/scripts/rules.mjs +120 -0
  10. package/agents/skills/claude-code/canary-blackhawk/scripts/scanner.mjs +244 -0
  11. package/agents/skills/claude-code/canary-blackhawk/scripts/string-literals.mjs +116 -0
  12. package/agents/skills/claude-code/canary-cassandra/SKILL.md +187 -0
  13. package/agents/skills/claude-code/canary-cassandra/scripts/cli.mjs +270 -0
  14. package/agents/skills/claude-code/canary-cassandra/scripts/engine.mjs +95 -0
  15. package/agents/skills/claude-code/canary-ci-ready/SKILL.md +178 -0
  16. package/agents/skills/claude-code/canary-ci-ready/skill.yaml +14 -0
  17. package/agents/skills/claude-code/canary-company-knowledge/SKILL.md +196 -0
  18. package/agents/skills/claude-code/canary-critical-areas/SKILL.md +142 -0
  19. package/agents/skills/claude-code/canary-critical-areas/skill.yaml +16 -0
  20. package/agents/skills/claude-code/canary-edge-case-discovery/SKILL.md +160 -0
  21. package/agents/skills/claude-code/canary-edge-case-discovery/skill.yaml +16 -0
  22. package/agents/skills/claude-code/canary-fail-fast/SKILL.md +75 -0
  23. package/agents/skills/claude-code/canary-fail-fast/scripts/cli.mjs +118 -0
  24. package/agents/skills/claude-code/canary-fail-fast/scripts/digest.mjs +69 -0
  25. package/agents/skills/claude-code/canary-fail-fast/scripts/failures.mjs +60 -0
  26. package/agents/skills/claude-code/canary-fail-fast/scripts/fastfail_check.mjs +43 -0
  27. package/agents/skills/claude-code/canary-fail-fast/scripts/parse.mjs +149 -0
  28. package/agents/skills/claude-code/canary-failure-impact/SKILL.md +153 -0
  29. package/agents/skills/claude-code/canary-failure-impact/skill.yaml +15 -0
  30. package/agents/skills/claude-code/canary-fleet-health/SKILL.md +197 -0
  31. package/agents/skills/claude-code/canary-generate-test/SKILL.md +185 -0
  32. package/agents/skills/claude-code/canary-instrument/SKILL.md +157 -0
  33. package/agents/skills/claude-code/canary-instrument/scripts/cli.mjs +178 -0
  34. package/agents/skills/claude-code/canary-instrument/scripts/otel_bootstrap/instrument.mjs +96 -0
  35. package/agents/skills/claude-code/canary-instrument/scripts/otel_bootstrap/playwright-fixture.ts +44 -0
  36. package/agents/skills/claude-code/canary-instrument/scripts/run_types.mjs +81 -0
  37. package/agents/skills/claude-code/canary-instrument/scripts/span_reader.mjs +187 -0
  38. package/agents/skills/claude-code/canary-katana/SKILL.md +243 -0
  39. package/agents/skills/claude-code/canary-katana/scripts/alarm.mjs +296 -0
  40. package/agents/skills/claude-code/canary-katana/scripts/cli.mjs +247 -0
  41. package/agents/skills/claude-code/canary-katana/scripts/diffscan.mjs +0 -0
  42. package/agents/skills/claude-code/canary-katana/scripts/ledger.mjs +183 -0
  43. package/agents/skills/claude-code/canary-pr-guardian/SKILL.md +144 -0
  44. package/agents/skills/claude-code/canary-pr-guardian/skill.yaml +17 -0
  45. package/agents/skills/claude-code/canary-promote-test/SKILL.md +228 -0
  46. package/agents/skills/claude-code/canary-savant/SKILL.md +233 -0
  47. package/agents/skills/claude-code/canary-savant/scripts/cli.mjs +274 -0
  48. package/agents/skills/claude-code/canary-savant/scripts/restoration.mjs +274 -0
  49. package/agents/skills/claude-code/canary-savant/scripts/rules.mjs +168 -0
  50. package/agents/skills/claude-code/canary-savant/scripts/runner.mjs +572 -0
  51. package/agents/skills/claude-code/canary-savant/scripts/scanner.mjs +374 -0
  52. package/agents/skills/claude-code/canary-savant/scripts/string-literals.mjs +116 -0
  53. package/agents/skills/claude-code/canary-screech/SKILL.md +109 -0
  54. package/agents/skills/claude-code/canary-screech/scripts/blast.mjs +125 -0
  55. package/agents/skills/claude-code/canary-screech/scripts/cli.mjs +128 -0
  56. package/agents/skills/claude-code/canary-screech/scripts/cluster.mjs +97 -0
  57. package/agents/skills/claude-code/canary-screech/scripts/history.mjs +73 -0
  58. package/agents/skills/claude-code/canary-screech/scripts/redness.mjs +94 -0
  59. package/agents/skills/claude-code/canary-setup-harness/SKILL.md +263 -0
  60. package/agents/skills/claude-code/canary-shadow/SKILL.md +131 -0
  61. package/agents/skills/claude-code/canary-shadow/scripts/cases.example.json +32 -0
  62. package/agents/skills/claude-code/canary-shadow/scripts/cli.mjs +195 -0
  63. package/agents/skills/claude-code/canary-ship/SKILL.md +177 -0
  64. package/agents/skills/claude-code/canary-ship/skill.yaml +16 -0
  65. package/agents/skills/claude-code/canary-strix/SKILL.md +130 -0
  66. package/agents/skills/claude-code/canary-strix/scripts/cli.mjs +255 -0
  67. package/agents/skills/claude-code/canary-strix/scripts/scanner.mjs +252 -0
  68. package/agents/skills/claude-code/canary-strix/scripts/terms.mjs +132 -0
  69. package/agents/skills/claude-code/canary-test-pipeline/SKILL.md +159 -0
  70. package/agents/skills/claude-code/canary-test-pipeline/skill.yaml +19 -0
  71. package/agents/skills/claude-code/canary-test-reporter/SKILL.md +138 -0
  72. package/agents/skills/claude-code/canary-test-reporter/scripts/cli.mjs +98 -0
  73. package/agents/skills/claude-code/canary-test-reporter/scripts/json_report.mjs +58 -0
  74. package/agents/skills/claude-code/canary-test-reporter/scripts/parse.mjs +216 -0
  75. package/agents/skills/claude-code/canary-test-reporter/scripts/render.mjs +114 -0
  76. package/agents/skills/lib/parse-args.mjs +275 -0
  77. package/dist/engine/analysis/batwoman/audit.js +39 -0
  78. package/dist/engine/analysis/batwoman/closure.js +159 -0
  79. package/dist/engine/analysis/batwoman/gh-history.js +119 -0
  80. package/dist/engine/analysis/batwoman/probes.js +195 -0
  81. package/dist/engine/analysis/batwoman/registry.js +142 -0
  82. package/dist/engine/analysis/batwoman/render.js +194 -0
  83. package/dist/engine/analysis/batwoman/run-window.js +122 -0
  84. package/dist/engine/analysis/batwoman/text.js +84 -0
  85. package/dist/engine/analysis/batwoman/triggers.js +122 -0
  86. package/dist/engine/analysis/batwoman/verdict.js +64 -0
  87. package/dist/engine/analysis/cli.js +47 -14
  88. package/dist/engine/analysis/gh-flaky/gh-run-attempts.js +206 -0
  89. package/dist/engine/batwoman-cli.js +119 -0
  90. package/dist/engine/ci-ready-cli.js +71 -0
  91. package/dist/engine/cli-commands.js +49 -72
  92. package/dist/engine/cli.core.js +16 -0
  93. package/dist/engine/company-knowledge-cli.js +10 -2
  94. package/dist/engine/core/ci-ready.js +112 -0
  95. package/dist/engine/core/company-knowledge.js +8 -0
  96. package/dist/engine/core/migrator.js +147 -20
  97. package/dist/engine/core/permission-matrix.js +219 -0
  98. package/dist/engine/core/quality-scorer.js +27 -19
  99. package/dist/engine/core/scaling-curve.js +143 -0
  100. package/dist/engine/core/skill-dispatch.js +115 -0
  101. package/dist/engine/core/skill-examples.js +103 -3
  102. package/dist/engine/core/skill-registry.js +59 -4
  103. package/dist/engine/core/string-literals.js +3 -1
  104. package/dist/engine/core/test-files.js +77 -0
  105. package/dist/engine/core/vacuity-scanner.js +330 -15
  106. package/dist/engine/core/workflow-discovery.js +41 -23
  107. package/dist/engine/guardian/adjudication-github.js +136 -0
  108. package/dist/engine/guardian/adjudication.js +119 -340
  109. package/dist/engine/guardian/analysis-emit.js +7 -2
  110. package/dist/engine/guardian/cli.js +277 -249
  111. package/dist/engine/guardian/coverage.js +2 -1
  112. package/dist/engine/guardian/diff-coverage/coverage-delta.js +162 -0
  113. package/dist/engine/guardian/diff-coverage/formats/cobertura.js +45 -1
  114. package/dist/engine/guardian/diff-coverage/orchestrator.js +25 -21
  115. package/dist/engine/guardian/diff-coverage/paths.js +5 -9
  116. package/dist/engine/guardian/diff-coverage/report-tier.js +88 -12
  117. package/dist/engine/guardian/diff-extractor.js +31 -32
  118. package/dist/engine/guardian/pr-check.js +354 -223
  119. package/dist/engine/guardian/pr-comment.js +35 -58
  120. package/dist/engine/guardian/weak-test.js +236 -0
  121. package/dist/engine/mcp-server.js +67 -4
  122. package/dist/engine/permission-matrix-cli.js +51 -0
  123. package/dist/engine/scaling-curve-cli.js +147 -0
  124. package/dist/engine/skills-cli.js +171 -51
  125. package/dist/engine/workflow-cli.js +85 -65
  126. package/dist/reporters/testtracker.d.ts +1 -1
  127. package/dist/reporters/testtracker.js +1 -1
  128. package/package.json +3 -2
@@ -0,0 +1,327 @@
1
+ # Canary Agent Skills
2
+
3
+ Agent-invokable workflows for Canary, written in the harness-engineering
4
+ SKILL.md format. Each skill is a prescriptive, phase-broken procedure with
5
+ explicit When-to-Use / NOT-for clauses, success criteria, rationalizations to
6
+ reject, examples, and escalation paths.
7
+
8
+ Skills are _prescriptive_. They tell an agent what to do, when to stop, and what
9
+ to refuse. For _descriptive_ documentation (what a component is and how to drive
10
+ it), see [Guides](../../docs/guides/index.md).
11
+
12
+ ## Structure
13
+
14
+ ```text
15
+ agents/skills/
16
+ ├── claude-code/ # Claude Code skills (24)
17
+ │ ├── canary-add-framework/
18
+ │ ├── canary-batwoman/
19
+ │ ├── canary-blackhawk/
20
+ │ ├── canary-cassandra/
21
+ │ ├── canary-ci-ready/
22
+ │ ├── canary-company-knowledge/
23
+ │ ├── canary-critical-areas/
24
+ │ ├── canary-edge-case-discovery/
25
+ │ ├── canary-fail-fast/
26
+ │ ├── canary-failure-impact/
27
+ │ ├── canary-fleet-health/
28
+ │ ├── canary-generate-test/
29
+ │ ├── canary-instrument/
30
+ │ ├── canary-katana/
31
+ │ ├── canary-pr-guardian/
32
+ │ ├── canary-promote-test/
33
+ │ ├── canary-savant/
34
+ │ ├── canary-screech/
35
+ │ ├── canary-setup-harness/
36
+ │ ├── canary-shadow/
37
+ │ ├── canary-ship/
38
+ │ ├── canary-strix/
39
+ │ ├── canary-test-pipeline/
40
+ │ └── canary-test-reporter/
41
+ └── README.md # this file
42
+ ```
43
+
44
+ Skills are organized by host platform. As Canary adds support for additional
45
+ agent runtimes (Gemini CLI, Cursor, Codex), sibling directories mirror the same
46
+ skill set with platform-specific tool-list adjustments.
47
+
48
+ ## Available Skills
49
+
50
+ Grouped by what you're trying to do, not alphabetically — see
51
+ [README.md's Usage section](../../README.md#-usage) for the CLI and
52
+ slash-command entry points.
53
+
54
+ ### Generation & lifecycle
55
+
56
+ - [`canary-generate-test`](./claude-code/canary-generate-test/SKILL.md) —
57
+ Generate a framework-appropriate test from a natural-language requirement.
58
+ Routes through classify → recommend → generate, writes the test under
59
+ `tests/generated/`, and optionally executes it. Invoked by
60
+ `/canary-write-test`.
61
+ - [`canary-promote-test`](./claude-code/canary-promote-test/SKILL.md) — Move a
62
+ generated test from `tests/generated/` into the committed test suite. Reviews,
63
+ relocates, drops generation artifacts, and verifies the test runs in the
64
+ project's normal flow.
65
+
66
+ ### Discovery & prioritization
67
+
68
+ - [`canary-critical-areas`](./claude-code/canary-critical-areas/SKILL.md) —
69
+ Risk-rank codebase areas by git churn, downstream dependents,
70
+ business-critical signals, and existing coverage depth. Invoked by
71
+ `/canary-critical-areas`; also Phase 1 of `canary-test-pipeline`.
72
+ - [`canary-edge-case-discovery`](./claude-code/canary-edge-case-discovery/SKILL.md)
73
+ — Surface edge cases worth testing across six categories, for a feature
74
+ description, function signature, or existing test suite. Invoked by
75
+ `/canary-edge-cases`; also Phase 2 of `canary-test-pipeline`.
76
+ - [`canary-failure-impact`](./claude-code/canary-failure-impact/SKILL.md) —
77
+ Trace the downstream blast radius of a test, function, or code path failing
78
+ undetected; produces a severity label. Invoked by `/canary-failure-impact`;
79
+ also Phase 3 of `canary-test-pipeline`.
80
+
81
+ ### CI gate & reporting
82
+
83
+ - [`canary-ci-ready`](./claude-code/canary-ci-ready/SKILL.md) — Analyse a suite
84
+ for CI readiness across five checks (coverage depth, flakiness, assertion
85
+ quality, critical-path coverage, runtime). Invoked by `/canary-ci-ready`; also
86
+ the gate/convergence check of `canary-test-pipeline`.
87
+ - [`canary-fail-fast`](./claude-code/canary-fail-fast/SKILL.md) — Bundled
88
+ executable skill (`scripts/cli.mjs`). Audits a Playwright config for fail-fast
89
+ knobs and prints a loud, categorized CI failure digest with GitHub `::error`
90
+ annotations, failing the step so a real failure can't be missed.
91
+ - [`canary-test-reporter`](./claude-code/canary-test-reporter/SKILL.md) —
92
+ Bundled executable skill (`scripts/cli.py`). Turns Playwright JSON results
93
+ into a Markdown and/or JSON report with pass/fail/flaky/skipped counts.
94
+ Complements `canary-fail-fast` (which aborts early) by summarising the full
95
+ run at the end.
96
+ - [`canary-screech`](./claude-code/canary-screech/SKILL.md) — Bundled executable
97
+ skill (`scripts/cli.mjs`). Broken-main siren: reads the cross-run history
98
+ store, decides whether the default branch is red, and emits a one-page blast
99
+ (culprit commit range, failure cluster, owning area, quarantine-or-revert
100
+ recommendation, chat-ready block) as a markdown artifact plus a `::error`
101
+ annotation. The cross-run complement to the two above — neither of them can
102
+ tell that the branch itself went red.
103
+
104
+ ### Closure auditing
105
+
106
+ - [`canary-batwoman`](./claude-code/canary-batwoman/SKILL.md) — Reports whether
107
+ the files a closed issue's fix changed have actually **executed** since that
108
+ fix merged. GitHub closes an issue on a keyword match, which checks neither
109
+ that the fix works nor that it ever ran. Advisory, and the only skill here
110
+ that requires the network (`gh`): deterministic, network, no agent.
111
+
112
+ ### Test hygiene & reliability
113
+
114
+ - [`canary-savant`](./claude-code/canary-savant/SKILL.md) — Order-dependence &
115
+ isolation detector. A static pass flags shared-state smells that predict
116
+ order-dependent tests; an opt-in confirming pass shuffles the suite under a
117
+ pinned seed and (for pytest) bisects the prefix to name the polluter. The
118
+ first JS/Node skill (`requires: node>=20`).
119
+ - [`canary-katana`](./claude-code/canary-katana/SKILL.md) — Quarantines deleted
120
+ and newly-skipped tests into an append-only provenance ledger, alarming in
121
+ exactly one case: the deletion dropped the last coverage of a critical-area
122
+ symbol. Silent by default; degrades to recording-only when critical-area data
123
+ is absent.
124
+ - [`canary-blackhawk`](./claude-code/canary-blackhawk/SKILL.md) —
125
+ Temporal-dependency linter. Statically flags tests that lean on wall-clock
126
+ time, a real delay, or the local timezone — the ones that pass all day and
127
+ fail at midnight, across a DST boundary, or on Feb 29 — suppressing itself
128
+ when a frozen-clock idiom is already in use.
129
+
130
+ ### Orchestration
131
+
132
+ - [`canary-test-pipeline`](./claude-code/canary-test-pipeline/SKILL.md) —
133
+ Multi-phase orchestrator composing `canary-ci-ready`, `canary-critical-areas`,
134
+ `canary-edge-case-discovery`, `canary-failure-impact`, and test generation
135
+ into a sequential pipeline with a convergence loop, looping until CI-ready or
136
+ the user stops. Invoked by `/canary-test-pipeline`.
137
+
138
+ ### Integration & shipping
139
+
140
+ - [`canary-pr-guardian`](./claude-code/canary-pr-guardian/SKILL.md) — PR /
141
+ pre-commit test-guardian. Runs a deterministic Tier-0 diff-coverage pass and
142
+ posts fidelity-labeled findings (coverage-verified › graph-verified ›
143
+ heuristic) on a sticky PR comment, with optional at-desk authoring of missing
144
+ tests. Gate defaults to soft. Invoked by `/canary-pr-guardian`.
145
+ - [`canary-ship`](./claude-code/canary-ship/SKILL.md) — The ship gate for a
146
+ finished, locally-green change: parallel adversarial review of the diff,
147
+ resolve confirmed findings with regression tests, then commit, PR, and
148
+ squash-merge while watching CI to green. Bakes in this repo's conventions (no
149
+ co-author trailer, squash, prettier, exclude local IDE churn, roadmap update).
150
+ Not for the implementation itself.
151
+
152
+ ### Maintenance & instrumentation
153
+
154
+ - [`canary-add-framework`](./claude-code/canary-add-framework/SKILL.md) — Add a
155
+ new testing framework to Canary's registry end-to-end. Enforces the
156
+ classifier↔registry contract, authors the registry entry, validates the
157
+ execution command, and updates docs + state.
158
+ - [`canary-instrument`](./claude-code/canary-instrument/SKILL.md) — Bundled
159
+ executable skill (`scripts/cli.py`). Instruments a Playwright run with
160
+ OpenTelemetry and emits a `run.json` artifact correlating every test to the
161
+ outbound HTTP requests it made, with zero manual bookkeeping in test code.
162
+
163
+ ### Setup
164
+
165
+ - [`canary-setup-harness`](./claude-code/canary-setup-harness/SKILL.md) —
166
+ Configure the Harness Engineering guardrails in a new Canary project or fork.
167
+ Installs the harness CLI, initialises the config, wires up CI workflows, and
168
+ verifies all gates pass.
169
+
170
+ - [`canary-company-knowledge`](./claude-code/canary-company-knowledge/SKILL.md)
171
+ — Scaffold `.canary/company.json`, the org-specific pointer file
172
+ `canary-ci-ready` and `canary-failure-impact` assume already exists; prompts
173
+ for the fields that can't be inferred.
174
+
175
+ ### Analysis
176
+
177
+ - [`canary-fleet-health`](./claude-code/canary-fleet-health/SKILL.md) —
178
+ Fleet-wide flake/spike/regression health summary across suites from the
179
+ run-history store, condensed to one scannable chat-turn report.
180
+
181
+ - [`canary-cassandra`](./claude-code/canary-cassandra/SKILL.md) — Vacuous-test
182
+ detection: tests that pass without proving anything (an assertion identical to
183
+ the value it checks, a target never invoked, an absence observed on a
184
+ bystander). Deterministic and advisory; a zero denominator exits 3 rather than
185
+ reporting a pass.
186
+
187
+ ## SKILL.md Format
188
+
189
+ Every skill in this tree follows the same structure:
190
+
191
+ 1. **Tagline** — one sentence, what the skill does
192
+ 2. **When to Use** — bulleted use-cases plus explicit NOT-for clauses
193
+ 3. **Process** — broken into numbered phases with numbered steps
194
+ 4. **Canary Integration** — files, env vars, and project entry points the skill
195
+ touches
196
+ 5. **Success Criteria** — measurable end-state conditions
197
+ 6. **Rationalizations to Reject** — table of common shortcuts and why they fail
198
+ 7. **Examples** — concrete walk-throughs (happy path + at least one failure
199
+ path)
200
+ 8. **Escalation** — when to stop the skill and surface to the user
201
+
202
+ This shape comes directly from the harness-engineering skill convention. Skills
203
+ authored outside this format don't belong here — file them as guides or wiki
204
+ pages.
205
+
206
+ ## Usage
207
+
208
+ ### Claude Code
209
+
210
+ Invoke by referencing the skill name in conversation, or via one of the 13
211
+ registered slash commands (`commands/*.md`) that wrap a skill or agent — e.g.
212
+ `/canary-write-test`, `/canary-ci-ready`, `/canary-critical-areas`. See
213
+ [README.md's Usage section](../../README.md#-usage) for the full
214
+ command-to-skill mapping.
215
+
216
+ ```text
217
+ Use the canary-generate-test skill to write a load test for /v1/search.
218
+ ```
219
+
220
+ ### Programmatic
221
+
222
+ Most skills here are documentation, not executable artifacts — they describe
223
+ _how an agent should behave_, not a function to call. Several are bundled
224
+ executable skills with their own CLI entry point (`cli:` in frontmatter).
225
+ `canary-fail-fast`, `canary-katana`, `canary-screech`, and `canary-blackhawk`
226
+ ship a Node entry (`scripts/cli.mjs`); `canary-instrument` and
227
+ `canary-test-reporter` ship a Python entry (`scripts/cli.py`). Run those
228
+ directly, e.g.:
229
+
230
+ ```bash
231
+ node agents/skills/claude-code/canary-fail-fast/scripts/cli.mjs --help
232
+ ```
233
+
234
+ For the rest — generation, review, healing, and analysis — there is no
235
+ standalone `generate`/orchestrator command; that pipeline was removed in v3.0
236
+ and now runs through the Claude Code plugin (`/canary-write-test` and friends)
237
+ using your session's own LLM. The deterministic, no-LLM subset of that work
238
+ (`recommend`, `init`, `run`, `review-test`, `flake-check`, `heal-test`,
239
+ `migrate`, and more) is exposed on the `canary` CLI — run `canary --help`, or
240
+ see [README.md's Usage section](../../README.md#-usage) for the full,
241
+ use-case-organized command list.
242
+
243
+ ## Authoring New Skills
244
+
245
+ Before adding a skill, confirm:
246
+
247
+ - The workflow is **prescriptive** (a sequence an agent should follow), not
248
+ **descriptive** (an explanation of how something works). Descriptive content
249
+ goes in `docs/guides/`.
250
+ - The workflow is **agent-invokable** — there's a clear trigger phrase or
251
+ context that should make an agent reach for it.
252
+ - The workflow has **at least one rationalization worth rejecting** — if no
253
+ shortcut is tempting, the skill is probably too thin and should be a guide
254
+ instead.
255
+
256
+ Then mirror the SKILL.md format above. Use the existing skills in this catalog
257
+ as templates — match section ordering, table style, and example density.
258
+
259
+ ## The skill-CLI contract
260
+
261
+ A skill that declares `cli:` in its frontmatter ships an executable entry point,
262
+ and every one of them behaves the same way. That uniformity is enforced, not
263
+ merely encouraged: `test/skill-cli-conformance.test.ts` **discovers** every
264
+ SKILL.md declaring `cli:` and holds it to the contract below, so a new skill is
265
+ covered the moment it lands rather than when someone remembers to add a copy.
266
+
267
+ | Situation | stdout/stderr | Exit |
268
+ | ------------------------------------------------ | ---------------------------------------- | ------------------- |
269
+ | `--help` / `-h` | usage on **stdout** | 0 |
270
+ | unknown flag, missing/empty value, bad int | `<prog>: error: <message>` on **stderr** | 2 |
271
+ | runtime failure (missing file, unreadable input) | `<prog>: <message>` on stderr | 1 |
272
+ | advisory run, findings present | report | 0 unless `--strict` |
273
+ | zero items verified | the abstention line | 3 under `--strict` |
274
+
275
+ Do not hand-roll the parsing loop. Five skills did, and the same bug class came
276
+ back three consecutive rounds — the pattern was copy-paste, so each new skill
277
+ inherited whichever version its author copied, and two copies drifted into
278
+ passing against buggy code. Instead, declare a spec and export it:
279
+
280
+ ```js
281
+ import {
282
+ createParser,
283
+ formatUsageError,
284
+ EXIT_USAGE,
285
+ } from '../../../lib/parse-args.mjs';
286
+
287
+ export const CLI_SPEC = {
288
+ prog: 'canary-example',
289
+ booleans: { '--json': 'json', '--strict': 'strict' },
290
+ values: { '--repo': { key: 'repo' }, '--seed': { key: 'seed', type: 'int' } },
291
+ defaults: { repo: '.' },
292
+ required: [],
293
+ // Declaring positionals also enables `--` and a lone `-`; a CLI that takes
294
+ // no paths gets neither, since there is nothing for them to protect.
295
+ positionals: { key: 'paths', defaults: ['.'] },
296
+ };
297
+
298
+ const parseArgs = createParser(CLI_SPEC);
299
+ ```
300
+
301
+ `CLI_SPEC` is the bridge between discovery and per-skill flags: the conformance
302
+ suite reads it to generate that skill's cases. A CLI that hand-rolls its parser
303
+ again exports no spec and fails the suite.
304
+
305
+ [`lib/parse-args.mjs`](lib/parse-args.mjs) owns four invariants that are easy to
306
+ get wrong by hand:
307
+
308
+ 1. **null-prototype lookup** — on a plain object every inherited key resolves
309
+ truthy, so `--toString` was swallowed as a value flag instead of rejected.
310
+ 2. **empty-value rejection** — `--repo=` is typed by nobody, but
311
+ `--repo "$UNSET_VAR"` expands to `--repo ''` in any shell, and an accepted
312
+ empty path silently retargets writes at the process CWD.
313
+ 3. **arity checking** — a value flag never consumes the next flag as its value.
314
+ 4. **`--flag=value`** — both spellings, everywhere, not per-skill.
315
+
316
+ Deliberate divergences from argparse, shared by the whole family: flags must be
317
+ spelled in full (no prefix abbreviation), and `--bogus --help` exits 2 rather
318
+ than printing help.
319
+
320
+ ## Related
321
+
322
+ - [Guides](../../docs/guides/index.md) — descriptive component documentation
323
+ - [Architecture Deep-Dive][arch-deep-dive] — internals for skill authors who
324
+ need to know what they're orchestrating
325
+ - [Roadmap](../../docs/roadmap.md) — planned skills and capabilities
326
+
327
+ [arch-deep-dive]: ../../docs/wiki/Architecture-Deep-Dive.md
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: canary:generate
3
+ description:
4
+ Generate a framework-appropriate test for the active editor file using
5
+ Canary's analysis pipeline.
6
+ ---
7
+
8
+ # canary:generate
9
+
10
+ Invoke the `canary-test-generator` agent with the active editor file as the
11
+ analysis target.
12
+
13
+ ## Usage
14
+
15
+ ```text
16
+ /canary:generate [file_path]
17
+ ```
18
+
19
+ If `file_path` is omitted, use the currently open file in the editor.
20
+
21
+ ## Prompt template for the agent
22
+
23
+ Provide this context to `canary-test-generator`:
24
+
25
+ ```text
26
+ Target file: <file_path>
27
+
28
+ Analysis instructions:
29
+ 1. Call canary__analyze_file on the target file.
30
+ 2. Use the returned framework, imports, functions, and context_snippets
31
+ to write tests that:
32
+ - Cover every public function listed in `functions`
33
+ - Mirror the import style from `imports`
34
+ - Follow naming conventions inferred from `context_snippets`
35
+ - Use the assertion style standard for the detected framework
36
+ (e.g. `expect().toBe()` for Playwright/Vitest, `assert` for pytest)
37
+ 3. Write the test file adjacent to the source file, e.g.:
38
+ - src/auth/login.ts → tests/auth/login.spec.ts
39
+ - ts/src/core/classifier.ts → ts/src/core/classifier.test.ts
40
+ 4. Run the test file and fix failures (up to 3 attempts).
41
+ 5. Report the final test file path and pass/fail status.
42
+ ```
43
+
44
+ ## Success criteria
45
+
46
+ - The generated test file exists at the expected path.
47
+ - `canary__run_tests` returns `exit_code == 0` on the final attempt.
48
+ - If tests could not be made to pass after 3 attempts, the agent reports the
49
+ last failure output and the test file path.
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: canary:init
3
+ description: Scaffold a new test suite for a chosen framework using Canary's initializer agent.
4
+ ---
5
+
6
+ # canary:init
7
+
8
+ Invoke the `canary-initializer` agent to scaffold a test suite.
9
+
10
+ ## Usage
11
+
12
+ ```text
13
+ /canary:init [framework]
14
+ ```
15
+
16
+ - If `[framework]` is provided (e.g. `/canary:init playwright`), pass
17
+ it directly to `canary-initializer` — skip the framework-selection step.
18
+ - If omitted, `canary-initializer` will call `canary__list_frameworks`
19
+ and prompt the user to choose.
20
+
21
+ ## Prompt template for the agent
22
+
23
+ Provide this context to `canary-initializer`:
24
+
25
+ ```text
26
+ Framework: <framework or "unspecified">
27
+ Target directory: <current working directory>
28
+
29
+ If framework is "unspecified", call canary__list_frameworks and ask the
30
+ user to choose before calling canary__init_suite.
31
+ ```
32
+
33
+ ## Success criteria
34
+
35
+ - `canary__init_suite` returns without error.
36
+ - The response lists at least one created file or directory.
37
+ - The user is reminded to install framework dependencies if applicable.
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: canary:migrate
3
+ description:
4
+ Migrate a harness-scaffolded test suite to Canary's layout, optionally
5
+ deploying overlay skills.
6
+ ---
7
+
8
+ # canary:migrate
9
+
10
+ Invoke the `canary-migrator` agent against the current working directory.
11
+
12
+ ## Usage
13
+
14
+ ```text
15
+ /canary:migrate
16
+ /canary:migrate --overlay /path/to/company-overlay
17
+ ```
18
+
19
+ The agent always runs a dry-run first and requires explicit confirmation before
20
+ writing any files.
21
+
22
+ ## Options
23
+
24
+ | Flag | Description |
25
+ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | `--overlay <path>` | Path to an overlay repo whose `.canary/skills/` are deployed into the target. Skills are filtered by `deploy_to` frontmatter matching any detected project shape. |
27
+ | `--framework <name>` | Override auto-detected framework (playwright, vitest, pytest, k6). |
28
+
29
+ ## Skill deployment
30
+
31
+ When `--overlay` is provided, skills with `deploy_to` values matching any
32
+ detected project shape are copied into the target's `.canary/skills/`. Skills
33
+ already present are skipped. Dry-run shows what would be copied without writing
34
+ anything.
35
+
36
+ Example: an API test repo (`shape=api`) with `--overlay path/to/acme-overlay`
37
+ receives all skills tagged `deploy_to: [api]` or `deploy_to: [all]`.
38
+
39
+ A workspace repo resolves a **set** of shapes — one per package — and receives
40
+ the union. A monorepo with an e2e package and a unit package gets both
41
+ `deploy_to: [e2e_ui]` and `deploy_to: [frontend_unit]` skills; a skill matching
42
+ both is deployed once. See
43
+ [Tracked Overlays](../../docs/guides/tracked-overlays.md#shape-is-a-set-not-a-single-value).
44
+
45
+ ## Prompt template for the agent
46
+
47
+ Provide this context to `canary-migrator`:
48
+
49
+ ```text
50
+ Target directory: <current working directory>
51
+ Overlay (if applicable): <overlay path or "none">
52
+
53
+ 1. Run canary migrate --overlay <overlay> with apply=false and show the
54
+ dry-run plan, including which skills would be deployed.
55
+ 2. Ask the user to confirm before applying.
56
+ 3. On confirmation, run canary migrate --overlay <overlay> with apply=true.
57
+ 4. Report created files, deployed skills, skipped files, and manual follow-ups.
58
+ ```
59
+
60
+ ## Success criteria
61
+
62
+ - Dry-run completes without error.
63
+ - User explicitly confirmed before apply was called.
64
+ - Final response lists created files, deployed skills, and required manual
65
+ follow-ups.
66
+ - If no harness project is detected, the agent surfaces the error and stops.