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