@erclx/aitk 0.38.0 → 0.40.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/README.md +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-design-extract/SKILL.md +1 -1
- package/claude/skills/claude-feature/REQUIREMENT.md +2 -1
- package/claude/skills/claude-feature/SKILL.md +9 -1
- package/claude/skills/create-rule/REQUIREMENT.md +1 -1
- package/claude/skills/create-skill/REQUIREMENT.md +6 -2
- package/claude/skills/create-skill/SKILL.md +5 -2
- package/claude/skills/create-snippet/REQUIREMENT.md +36 -0
- package/claude/skills/create-snippet/SKILL.md +23 -5
- package/claude/skills/{create-standard → create-snippet}/references/snippets.md +1 -1
- package/claude/skills/create-standard/REQUIREMENT.md +38 -0
- package/claude/skills/create-standard/SKILL.md +8 -12
- package/claude/skills/migration-claude-md/REQUIREMENT.md +41 -0
- package/claude/skills/migration-standards/REQUIREMENT.md +38 -0
- package/claude/skills/project-commands/REQUIREMENT.md +42 -0
- package/claude/skills/session-resume/REQUIREMENT.md +38 -0
- package/claude/skills/setup-indexes/REQUIREMENT.md +42 -0
- package/claude/skills/setup-indexes/SKILL.md +1 -1
- package/claude/skills/setup-plugins/REQUIREMENT.md +42 -0
- package/claude/skills/setup-verify/REQUIREMENT.md +39 -0
- package/claude/skills/systematic-debugging/REQUIREMENT.md +41 -0
- package/claude/skills/toolkit-cli/REQUIREMENT.md +37 -0
- package/claude/skills/toolkit-feedback/REQUIREMENT.md +40 -0
- package/claude/skills/toolkit-operator/REQUIREMENT.md +39 -0
- package/claude/skills/toolkit-triage/REQUIREMENT.md +40 -0
- package/claude/skills/youtube-transcripts/REQUIREMENT.md +38 -0
- package/docs/agents/capture.md +31 -0
- package/docs/agents/commands.md +57 -0
- package/docs/agents/comments.md +32 -0
- package/docs/agents/context-audit-checks.md +40 -0
- package/docs/agents/context-audit.md +44 -0
- package/docs/agents/docs.md +17 -0
- package/docs/agents/index.md +23 -0
- package/docs/agents/indexes.md +29 -0
- package/docs/agents/install-and-sync.md +109 -0
- package/docs/agents/output-shape.md +45 -0
- package/docs/agents/overview.md +26 -0
- package/docs/agents/sandbox.md +65 -0
- package/docs/agents/scripting.md +115 -0
- package/docs/agents/tasks.md +33 -0
- package/docs/index.md +4 -1
- package/docs/target-projects.md +2 -2
- package/package.json +1 -1
- package/scripts/docs/list.sh +36 -17
- package/scripts/manage-sandbox.sh +4 -0
- package/src/commands/sandbox.ts +1 -1
- package/src/sandbox/census.ts +1 -1
- package/src/ui.ts +1 -1
- package/standards/bundled/snippets.md +1 -1
- package/standards/skill.md +4 -4
- package/claude/skills/claude-design-propose/SKILL.md +0 -15
- package/docs/agents.md +0 -535
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Install and sync
|
|
3
|
+
description: What each install and sync verb writes, refuses, or leaves alone, and how drift is attributed in a target project
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Install and sync
|
|
7
|
+
|
|
8
|
+
The behavior notes behind the verbs listed in `commands.md`. Each one records what the verb writes, what it refuses, and what it deliberately leaves alone.
|
|
9
|
+
|
|
10
|
+
## Domain sync
|
|
11
|
+
|
|
12
|
+
`aitk gov sync` updates only rules already present under `.claude/rules/` and
|
|
13
|
+
never adds new ones. A rule the toolkit does not ship is left alone, which is
|
|
14
|
+
how project-authored rules survive. It also removes a stale `.claude/GOV.md`
|
|
15
|
+
from the retired build. Use `aitk gov install` to add rules.
|
|
16
|
+
|
|
17
|
+
`aitk standards sync` matches by filename against `.claude/standards/` and
|
|
18
|
+
regenerates that folder's `index.md` on every completed run. It is the one sync
|
|
19
|
+
that refuses under `AITK_NON_INTERACTIVE=1` when drift exists, logging a warning
|
|
20
|
+
and exiting 0 without writing, because standards are seeds a project edits. Run
|
|
21
|
+
it interactively, or use the `claude-seed-sync` skill for a per-section audit
|
|
22
|
+
that preserves customizations.
|
|
23
|
+
|
|
24
|
+
`aitk snippets sync` behaves the same way against `.claude/snippets/`. It
|
|
25
|
+
matches by path relative to that directory, so a snippet the toolkit no longer
|
|
26
|
+
ships, or one authored directly in the target, is reported and skipped rather
|
|
27
|
+
than deleted. It is not preset-aware, so a project that installed `essentials`
|
|
28
|
+
does not grow new snippets on a sync. Use `aitk snippets install` to add them.
|
|
29
|
+
|
|
30
|
+
## Install guards
|
|
31
|
+
|
|
32
|
+
`aitk gov install` and `aitk snippets install` require their first argument
|
|
33
|
+
under `AITK_NON_INTERACTIVE=1`. Both used to fall back to an interactive picker
|
|
34
|
+
that resolved to its first option headlessly, so `aitk gov install` with no
|
|
35
|
+
stack installed whichever stack sorted first and `aitk snippets install` with no
|
|
36
|
+
category installed every category. Each now reports the valid names on stderr
|
|
37
|
+
and exits 1. Every documented agent path already passes the argument, including
|
|
38
|
+
`aitk init`. The confirm-then-apply prompt after it still resolves to `Yes`
|
|
39
|
+
headlessly, so a call that names its stack or category is unchanged.
|
|
40
|
+
|
|
41
|
+
`aitk gov install` also refuses the toolkit root as a target, matching
|
|
42
|
+
`aitk snippets install`. Both resolve the target before anything else, so a path
|
|
43
|
+
that does not exist fails rather than being scaffolded.
|
|
44
|
+
|
|
45
|
+
## Governance regen
|
|
46
|
+
|
|
47
|
+
`aitk gov regen` is the one governance verb that runs against the toolkit root,
|
|
48
|
+
because the `.claude/rules/` it writes there is produced output rather than an
|
|
49
|
+
operator's working copy. It reads the stack recorded in `internal/governance.toml`,
|
|
50
|
+
installs it alongside anything under `internal/rules/`, and clears the
|
|
51
|
+
destination first so a rule the record stopped naming disappears. It takes
|
|
52
|
+
`--root <path>` and defaults to the toolkit root, prints nothing on success, and
|
|
53
|
+
reports the reason on stderr with exit 1 when the record names a stack or rule
|
|
54
|
+
that does not resolve. `scripts/core/regen-claude-copies.sh` calls it, and the
|
|
55
|
+
Consumed copies stage of `bun run check` asserts the result is committed.
|
|
56
|
+
|
|
57
|
+
## Whole-project sync
|
|
58
|
+
|
|
59
|
+
`aitk sync` runs every installed domain sync, then offers to commit the result
|
|
60
|
+
and open a pull request. Under `AITK_NON_INTERACTIVE=1` it applies the domain
|
|
61
|
+
syncs and then refuses the git workflow, reporting the branch and commit it
|
|
62
|
+
would have created and exiting 0. Nothing is staged, committed, or pushed
|
|
63
|
+
headlessly. Run it interactively to reach the commit and pull request options.
|
|
64
|
+
It also refuses a target whose working tree is dirty, so commit or stash first.
|
|
65
|
+
|
|
66
|
+
## Drift reporting
|
|
67
|
+
|
|
68
|
+
`aitk sync --check` reports drift and writes nothing, so it needs no clean tree
|
|
69
|
+
and is safe to run at any time. Each file is classified as `stale` when it still
|
|
70
|
+
matches what the toolkit installed, `customized` when the project edited it,
|
|
71
|
+
`stranded` when it sits at a path the toolkit no longer installs to, `orphaned`
|
|
72
|
+
when the project authored it, or `drifted` when no stamp covers it. Use `--json`
|
|
73
|
+
for the machine-readable report and `--exit-code` to fail a CI job. Orphaned
|
|
74
|
+
files are excluded from that exit code, since a project-authored rule never
|
|
75
|
+
converges. Attribution reads `.claude/aitk.json`, which every install and sync
|
|
76
|
+
writes.
|
|
77
|
+
|
|
78
|
+
A target installed before stamping shipped has no such file, and the report
|
|
79
|
+
falls back to the toolkit's own git history. Installed content matching any
|
|
80
|
+
version that history ever published proves the file is untouched, so it reports
|
|
81
|
+
`stale` naming the commit it came from, and content matching no published
|
|
82
|
+
version stays `drifted`. A toolkit reached outside a git clone, which is what a
|
|
83
|
+
registry install is, cannot run that fallback and reports
|
|
84
|
+
`historyUnavailable` alongside the unattributed files.
|
|
85
|
+
|
|
86
|
+
Each domain carries its own toolkit anchor in that file, so syncing one domain
|
|
87
|
+
never advances the revision another measures from, and each reports the upstream
|
|
88
|
+
commits touching its own source path. The `covers` field names the domains a
|
|
89
|
+
target has actually stamped, so a domain that was never stamped is legible
|
|
90
|
+
rather than reading as a clean one.
|
|
91
|
+
|
|
92
|
+
## Bootstrap
|
|
93
|
+
|
|
94
|
+
`aitk init` installs up to six core domains and reports each one independently. A
|
|
95
|
+
domain that fails does not abort the run, so the command finishes the rest and
|
|
96
|
+
exits 1 naming the failures. Passing any flag skips the confirmation prompt,
|
|
97
|
+
which is what makes it scriptable. `--stack` defaults to `base`, and the default
|
|
98
|
+
does not read as a passed flag, so a bare `aitk init` installs governance and
|
|
99
|
+
still prompts. `--skip` takes `wiki`, `standards`, and `governance`, and warns
|
|
100
|
+
without aborting on any other value.
|
|
101
|
+
|
|
102
|
+
## Unguarded tooling primitives
|
|
103
|
+
|
|
104
|
+
`aitk tooling inject` and `aitk tooling prune-gitignore` are the unguarded
|
|
105
|
+
primitives beneath `sync`. They apply one stack with no scan and no prompt, and
|
|
106
|
+
they deliberately skip the check that rejects `claude`, which is how `aitk
|
|
107
|
+
claude` drives its own stack through them. Use `sync` unless you are scripting
|
|
108
|
+
provisioning. Both frame their own output, so pass `--nested` when calling from
|
|
109
|
+
inside an already-open frame.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Output shape
|
|
3
|
+
description: The two framed shapes every command renders into, and how JSON and --names modes keep stdout clean
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Output shape
|
|
7
|
+
|
|
8
|
+
Every CLI command renders into one of two framed shapes. Data goes to stdout. UI and logs go to stderr. Help output is the exception. It prints to stdout so it can be piped and grepped.
|
|
9
|
+
|
|
10
|
+
## Data shape (lists, runs, errors)
|
|
11
|
+
|
|
12
|
+
```plaintext
|
|
13
|
+
┌
|
|
14
|
+
│ aitk <domain>
|
|
15
|
+
│
|
|
16
|
+
├ Section
|
|
17
|
+
│ ✓ item
|
|
18
|
+
│ ✓ item
|
|
19
|
+
└
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Rules:
|
|
23
|
+
|
|
24
|
+
- `┌` opens the frame on stderr
|
|
25
|
+
- `│ aitk <domain>` is the command banner, one per invocation
|
|
26
|
+
- `├ Section` headers introduce groups of items. `log_step` produces the blank `│` spacer before each.
|
|
27
|
+
- `└` closes the frame on stderr, wired via `trap close_timeline EXIT`
|
|
28
|
+
- Errors render as `│ ✗ message` inside the same frame. Never emit a lone error line without a frame.
|
|
29
|
+
|
|
30
|
+
## Help shape
|
|
31
|
+
|
|
32
|
+
```plaintext
|
|
33
|
+
┌
|
|
34
|
+
├ Usage: aitk <domain> [command]
|
|
35
|
+
│
|
|
36
|
+
│ Commands:
|
|
37
|
+
│ ...
|
|
38
|
+
└
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Help skips the banner. The `Usage:` line sits directly on `├`. Help writes to stdout because `--help` is documentation, not runtime UI.
|
|
42
|
+
|
|
43
|
+
## JSON and `--names` modes
|
|
44
|
+
|
|
45
|
+
`--json` and `--names` keep stdout clean and machine-readable. The frame still renders on stderr (open, banner, close) so the stream discipline is consistent across modes. Consumers that only read stdout see pure data.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Overview
|
|
3
|
+
description: What this folder covers, the invocation rules every command inherits, and where domain behavior is documented instead
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Overview
|
|
7
|
+
|
|
8
|
+
CLI catalog and invocation rules for agents working in this repository.
|
|
9
|
+
|
|
10
|
+
This folder is an index of what an agent can run and how to run it cleanly from a script. It does not cover domain behavior. Read `CLAUDE.md` for project behaviors and load the matching `.claude/skills/aitk-*` skill when working inside a domain.
|
|
11
|
+
|
|
12
|
+
## Invocation rules
|
|
13
|
+
|
|
14
|
+
See `CLAUDE.md` design principles. They apply to every command in this folder.
|
|
15
|
+
|
|
16
|
+
## Where to start
|
|
17
|
+
|
|
18
|
+
- `output-shape.md`: the stream contract every command renders into, which is what a caller parsing stdout depends on
|
|
19
|
+
- `commands.md`: the full command catalog, project-level and per-domain
|
|
20
|
+
- `scripting.md`: the runtime catalogs that replace hardcoded names, plus headless invocation examples
|
|
21
|
+
|
|
22
|
+
## Related
|
|
23
|
+
|
|
24
|
+
- `CLAUDE.md`: project behaviors and design principles
|
|
25
|
+
- `.claude/skills/aitk-*`: domain-scoped guidance for editing work
|
|
26
|
+
- `docs/index.md`: full docs directory
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Sandbox
|
|
3
|
+
description: Scenario routing, the expectation scoring surface, and the coverage census over scenarios and skills
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sandbox
|
|
7
|
+
|
|
8
|
+
`aitk sandbox` provisions isolated project states, scores a provisioned one against a declared expectation, and reports which scenarios declare an expectation at all.
|
|
9
|
+
|
|
10
|
+
## Scenarios
|
|
11
|
+
|
|
12
|
+
Scenarios live under `scripts/sandbox/`, one folder per category. `scripts/sandbox/fixtures/` is the exception, holding file content that scenarios stage rather than scenarios of its own, so both pickers filter it out. `files` in `package.json` excludes that tree, so an installed `aitk` carries the command, reports it as toolkit-only on one line, and exits 1 rather than failing on the missing directory. Route non-interactively with `SANDBOX_SCENARIO`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
SANDBOX_SCENARIO=sync aitk sandbox infra:tooling
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Scenario categories: `infra:*` (domain flows), `git:*`, `scaffold:*`. `create` scenarios require interactive input and loop on empty input, so skip them in automated runs.
|
|
19
|
+
|
|
20
|
+
## Scenario expectations
|
|
21
|
+
|
|
22
|
+
`aitk sandbox check <category>:<command> [arm]` scores a provisioned sandbox against the arm's `expect.toml`, printing a verdict on stderr and, with `--json`, the same verdict as a record on stdout.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
aitk sandbox check claude:docs drift --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Flag | Effect |
|
|
29
|
+
| ------------------- | ---------------------------------------------------------- |
|
|
30
|
+
| `--envelope <file>` | Read `is_error`, `num_turns`, denials, and the reply text |
|
|
31
|
+
| `--writes <file>` | Newline-delimited paths the session wrote, for write scope |
|
|
32
|
+
| `--json` | Emit the verdict record on stdout |
|
|
33
|
+
| `--strict` | Exit 1 on `unchecked` instead of 0 |
|
|
34
|
+
|
|
35
|
+
The verdict `state` is `pass`, `fail`, or `unchecked`. An arm with no `expect.toml` is `unchecked` and exits 0, so the harness stays usable while expectations roll out. A declaration that exists but asserts nothing is a failure, since an expectation file that asserts nothing passes every run.
|
|
36
|
+
|
|
37
|
+
Omitting `--writes` or `--envelope` does not silently drop the assertion kinds that need them. Write scope, the turn ceiling, and the reply assertion report as unchecked and appear in the count, so the standalone command cannot claim more coverage than it had. A verdict never reports `pass` with zero assertions.
|
|
38
|
+
|
|
39
|
+
An envelope that parses but carries no `result` field skips the reply assertion the same way an absent file does. An envelope carrying an empty `result` fails it, since a run that returned no text is a finding rather than a gap in the input.
|
|
40
|
+
|
|
41
|
+
Exit 0 means `pass` or `unchecked`. Exit 1 means `fail`, or a caller error: a malformed target, or a sandbox that was never provisioned. A missing sandbox reports as an error rather than a failed verdict, because failing every path assertion would read as a skill that did nothing. `--strict` moves `unchecked` to exit 1 for a caller that has finished arming its scenarios.
|
|
42
|
+
|
|
43
|
+
## Scenario coverage
|
|
44
|
+
|
|
45
|
+
`aitk sandbox coverage` reports which scenarios declare expectations and which only provision a state. It reads the fixture tree, so it needs no provisioned sandbox and runs nothing. Where that tree does not ship it exits 1 and prints no percentage, since a denominator nobody looked at is not a coverage result. A tree that is present and holds no scenarios is a real zero and still reports one.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
aitk sandbox coverage --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Flag | Effect |
|
|
52
|
+
| ---------- | ----------------------------------------------------------- |
|
|
53
|
+
| `--json` | Emit the coverage record on stdout |
|
|
54
|
+
| `--strict` | Exit 1 while any scenario declares no expectation |
|
|
55
|
+
| `--skills` | Add a per-skill asserted, should-be-asserted, exempt census |
|
|
56
|
+
|
|
57
|
+
The record carries every scenario with the arms that declare, plus `totalScenarios`, `armedScenarios`, and `armedArms`. Scenarios and arms count separately, since several arms can share one scenario and dividing one by the other overstates the rollout.
|
|
58
|
+
|
|
59
|
+
### The skills census
|
|
60
|
+
|
|
61
|
+
`--skills` answers what the scenario count cannot, which is whether anything can fail a given skill. It adds `skills`, `totalSkills`, `asserted`, `shouldBeAsserted`, `exempt`, `staleExemptions`, and `supersededExemptions` to the record, and keeps the scenario view rather than replacing it. The two denominators disagree on purpose: an armed scenario under `infra/` or `tooling/` exercises a CLI domain and pairs with no skill at all.
|
|
62
|
+
|
|
63
|
+
A skill pairs to a scenario by filename, `<category>-<command>` first and bare `<command>` second, so `claude/setup-init.sh` reaches the `setup-init` skill. `should-be-asserted` is the default rather than a queue to drain, and which of those skills earns an arm is a project decision the census does not make. `exempt` means no arm should be written and holds only with a reason, declared in `scripts/sandbox/exempt.toml` and limited to a harness limit the checker cannot reach past or a skill that writes no artifact. An armed arm outranks an exemption. An exemption naming no shipped skill, or naming one an arm now asserts, exits 1 without `--strict`. Each armed arm reports as `<category>:<command>/<arm>`, so two same-named arms under different scenarios stay distinct.
|
|
64
|
+
|
|
65
|
+
`scripts/sandbox/run.sh` calls this after a headless run and merges the verdict into the envelope it prints. It also writes that merged record to `.claude/.tmp/sandbox-runs/<target>-<arm>-<timestamp>.json` with a `writes` array appended, and logs the path on stderr. Both fields are what a later re-score needs, since `--envelope` and `--writes` read files the run deletes on exit. Stdout carries the same bytes it did before the record existed.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Scripting
|
|
3
|
+
description: The runtime catalogs that replace hardcoded names, what each carries, and a headless invocation per domain
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scripting
|
|
7
|
+
|
|
8
|
+
What a skill or script reads to discover names at runtime, and how each domain is invoked with no TTY.
|
|
9
|
+
|
|
10
|
+
## Runtime catalogs
|
|
11
|
+
|
|
12
|
+
Use these to discover what's available instead of hardcoding names.
|
|
13
|
+
|
|
14
|
+
| Command | Returns |
|
|
15
|
+
| -------------------------------- | --------------------------------------------- |
|
|
16
|
+
| `aitk tooling list --json` | Stacks, extends chain, dep and script counts |
|
|
17
|
+
| `aitk snippets list --json` | Presets and categories with their slugs |
|
|
18
|
+
| `aitk standards list --json` | Standards docs and the paths each governs |
|
|
19
|
+
| `aitk gov list --json` | Governance stacks and rule sets |
|
|
20
|
+
| `aitk claude seeds list --json` | Seed doc sources with content |
|
|
21
|
+
| `aitk claude skills list --json` | Plugin skills, descriptions, requirement flag |
|
|
22
|
+
| `aitk docs list --json` | Consumer docs plus per-domain context |
|
|
23
|
+
|
|
24
|
+
### Catalog fields
|
|
25
|
+
|
|
26
|
+
Every catalog serializes through `JSON.stringify`, so a name carrying a quote
|
|
27
|
+
emits valid JSON. `aitk tooling list` and `aitk snippets list` previously built
|
|
28
|
+
their output with `printf` and no escaping.
|
|
29
|
+
|
|
30
|
+
`aitk standards list` carries `appliesTo` per standard, the paths that standard's
|
|
31
|
+
`## Scope` statement declares. It holds the backticked paths from the first
|
|
32
|
+
sentence of the statement, the single entry `*` for a standard governing an
|
|
33
|
+
attribute rather than a document type, and an empty array when the statement
|
|
34
|
+
declares nothing a parser can read. A consumer mapping a file to its governing
|
|
35
|
+
standards reads this rather than holding a table of its own, and reports an empty
|
|
36
|
+
array rather than skipping the standard behind it.
|
|
37
|
+
|
|
38
|
+
`aitk claude seeds list` reads the same plan `aitk claude init` applies, so the
|
|
39
|
+
listing and the install cannot disagree. It now reports
|
|
40
|
+
`.claude/context/index.md`, which `init` has always installed and the listing
|
|
41
|
+
never named, and it emits the project-level `CLAUDE.md` last rather than first.
|
|
42
|
+
|
|
43
|
+
### The skills catalog
|
|
44
|
+
|
|
45
|
+
`aitk claude skills list` reads `claude/skills/*/SKILL.md` and reports the folder
|
|
46
|
+
name with the frontmatter description, sorted by name. Internal skills under
|
|
47
|
+
`.claude/skills/` are excluded, since they never install into a target and a
|
|
48
|
+
count spanning both overstates what ships. A skill whose frontmatter is missing
|
|
49
|
+
or unparseable returns an empty description rather than failing the listing, so
|
|
50
|
+
one malformed file cannot hide the rest of the catalog. `--names` emits skill
|
|
51
|
+
names one per line.
|
|
52
|
+
|
|
53
|
+
Each entry also carries `requirement`, whether the folder holds a sibling
|
|
54
|
+
`REQUIREMENT.md`. Every skill is meant to carry one, so a `false` is a gap to
|
|
55
|
+
close rather than a recorded exemption, and the flag answers which skills are
|
|
56
|
+
missing theirs without a caller listing the directory itself. Nothing gates the
|
|
57
|
+
rule yet, which is why the flag is worth reading against the shipped corpus after
|
|
58
|
+
a merge.
|
|
59
|
+
|
|
60
|
+
## Non-interactive examples
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Create a new tooling stack
|
|
64
|
+
AITK_NON_INTERACTIVE=1 aitk tooling create astro
|
|
65
|
+
|
|
66
|
+
# Sync a stack into a target project
|
|
67
|
+
AITK_NON_INTERACTIVE=1 aitk tooling sync astro /path/to/project
|
|
68
|
+
|
|
69
|
+
# Install a governance stack (the stack argument is required headlessly)
|
|
70
|
+
AITK_NON_INTERACTIVE=1 aitk gov install astro --add 260-shadcn /path/to/project
|
|
71
|
+
|
|
72
|
+
# Update installed governance rules, dropping a retired .claude/GOV.md
|
|
73
|
+
AITK_NON_INTERACTIVE=1 aitk gov sync /path/to/project
|
|
74
|
+
|
|
75
|
+
# Concatenate installed rules into a paste payload
|
|
76
|
+
AITK_NON_INTERACTIVE=1 aitk gov build /path/to/project
|
|
77
|
+
|
|
78
|
+
# Sync a monorepo subtree, skipping the base layer the repo root already owns
|
|
79
|
+
AITK_NON_INTERACTIVE=1 aitk tooling sync vite-react /path/to/repo/frontend --skip base
|
|
80
|
+
|
|
81
|
+
# Verify a stack end-to-end in a throwaway scaffold
|
|
82
|
+
aitk tooling verify vite-react
|
|
83
|
+
|
|
84
|
+
# Apply one stack without scanning or prompting, for scripted provisioning
|
|
85
|
+
aitk tooling inject base /path/to/project
|
|
86
|
+
aitk tooling inject base /path/to/project --configs --seeds
|
|
87
|
+
|
|
88
|
+
# Drop managed gitignore entries a manifest no longer declares
|
|
89
|
+
# Prints the number removed on stdout, diagnostics on stderr
|
|
90
|
+
aitk tooling prune-gitignore base /path/to/project
|
|
91
|
+
|
|
92
|
+
# Install a snippet preset
|
|
93
|
+
AITK_NON_INTERACTIVE=1 aitk snippets install essentials /path/to/project
|
|
94
|
+
|
|
95
|
+
# Update snippets already installed, leaving project-authored ones alone
|
|
96
|
+
AITK_NON_INTERACTIVE=1 aitk snippets sync /path/to/project
|
|
97
|
+
|
|
98
|
+
# Report standards drift without applying it, which is what headless does here
|
|
99
|
+
AITK_NON_INTERACTIVE=1 aitk standards sync /path/to/project
|
|
100
|
+
|
|
101
|
+
# Copy every standard into a target, overwriting what is there
|
|
102
|
+
AITK_NON_INTERACTIVE=1 aitk standards install /path/to/project
|
|
103
|
+
|
|
104
|
+
# Bootstrap a project. Any flag suppresses the confirmation prompt
|
|
105
|
+
AITK_NON_INTERACTIVE=1 aitk init --stack astro --skip wiki /path/to/project
|
|
106
|
+
|
|
107
|
+
# Run every domain sync. The git workflow is refused headlessly, so nothing is pushed
|
|
108
|
+
AITK_NON_INTERACTIVE=1 aitk sync /path/to/project
|
|
109
|
+
|
|
110
|
+
# Scaffold .claude/wiki/ with a stub index. The target must already exist
|
|
111
|
+
AITK_NON_INTERACTIVE=1 aitk wiki init /path/to/project
|
|
112
|
+
|
|
113
|
+
# Run a sandbox scenario non-interactively
|
|
114
|
+
SANDBOX_SCENARIO=sync aitk sandbox infra:tooling
|
|
115
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tasks
|
|
3
|
+
description: Selecting a shipped task by stem or pull request, the refusal reasons, and why the board root defaults to the main worktree
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tasks
|
|
7
|
+
|
|
8
|
+
`aitk tasks archive` moves a shipped task from `.claude/tasks/` into `.claude/.tmp/task-archive/`, drops its row from `priority.md`, and regenerates the board index. The three run as one unit, so the attended and unattended callers cannot archive differently.
|
|
9
|
+
|
|
10
|
+
Name the task by its filename stem, or by the pull request it carries:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
aitk tasks archive v28.1-trigger-escalation
|
|
14
|
+
aitk tasks archive --pull-request 673 --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Option | Behavior |
|
|
18
|
+
| -------------------- | ------------------------------------------------------------ |
|
|
19
|
+
| `--pull-request <n>` | Select the task whose `Pull request:` line names this number |
|
|
20
|
+
| `--json` | Emit a machine-readable record on stdout |
|
|
21
|
+
| `--root <path>` | Board root, defaulting to the main worktree |
|
|
22
|
+
|
|
23
|
+
Exit codes: `0` archived, `1` refused. Every gate is a refusal rather than a warning, because `.husky/post-merge` calls this with nobody watching. The `reason` field carries which gate fired: `no-board`, `no-match`, `ambiguous`, `no-outcomes`, `open-outcomes`, or `plan-unswept`.
|
|
24
|
+
|
|
25
|
+
The board is shared scratch at the main worktree root, so `--root` defaults to the first entry of `git worktree list` rather than the working directory. A linked worktree archives against the same board every other session reads.
|
|
26
|
+
|
|
27
|
+
Skills branch on the reason rather than on the exit code:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
aitk tasks archive --pull-request 673 --json | jq -r 'if .ok then .task else .reason end'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For the board format, the `Pull request:` line, and the archive rules, see `.claude/standards/tasks.md`.
|
package/docs/index.md
CHANGED
|
@@ -9,7 +9,6 @@ One-line reference for each doc in this folder.
|
|
|
9
9
|
|
|
10
10
|
## Agent surface
|
|
11
11
|
|
|
12
|
-
- [Agents](agents.md): CLI catalog and invocation rules for agents
|
|
13
12
|
- [AI workflow](ai-workflow.md): Overarching AI workflow across domains
|
|
14
13
|
- [Target projects](target-projects.md): Scaffold, add domains later, and sync upstream drift in a toolkit-managed project
|
|
15
14
|
|
|
@@ -18,3 +17,7 @@ One-line reference for each doc in this folder.
|
|
|
18
17
|
- [Operating model](operating-model.md): Orchestrator and worker roles for building across parallel sessions
|
|
19
18
|
- [Visual design workflow](visual-design-workflow.md): Tiered guide for design and wireframe authoring with Claude Code
|
|
20
19
|
- [Zshrc aliases for Claude Code](zshrc-aliases.md): Shell aliases that shorten common Claude Code invocations
|
|
20
|
+
|
|
21
|
+
## Sub-catalogs
|
|
22
|
+
|
|
23
|
+
- [Agents](agents/index.md): CLI catalog and invocation rules for agents, split by command domain. Start with overview.
|
package/docs/target-projects.md
CHANGED
|
@@ -8,7 +8,7 @@ category: Agent surface
|
|
|
8
8
|
|
|
9
9
|
How a project outside this repo consumes the toolkit across its lifecycle. Three phases: scaffold once, add a domain later when a new need appears, and sync when the upstream toolkit moves.
|
|
10
10
|
|
|
11
|
-
This doc stays at the narrative layer. For command flags and JSON shapes, see [agents](agents.md). For per-domain mechanics, see each `.claude/context/<domain>.md`.
|
|
11
|
+
This doc stays at the narrative layer. For command flags and JSON shapes, see [agents](agents/index.md). For per-domain mechanics, see each `.claude/context/<domain>.md`.
|
|
12
12
|
|
|
13
13
|
## Getting the skills
|
|
14
14
|
|
|
@@ -179,7 +179,7 @@ Sync also refuses a target whose working tree is dirty, so commit or stash befor
|
|
|
179
179
|
|
|
180
180
|
## Related
|
|
181
181
|
|
|
182
|
-
- [agents](agents.md): CLI flags, exit codes, and JSON output shapes
|
|
182
|
+
- [agents](agents/index.md): CLI flags, exit codes, and JSON output shapes
|
|
183
183
|
- [AI workflow](ai-workflow.md): feature-development loop inside a toolkit-managed project
|
|
184
184
|
- [tooling](../.claude/context/tooling.md), [governance](../.claude/context/governance.md), [claude plugin](../.claude/context/claude-plugin/index.md), [indexes](../.claude/context/indexes.md), [snippets](../.claude/context/snippets.md), [standards](../.claude/context/standards.md): per-domain mechanics
|
|
185
185
|
- [sandbox](../.claude/context/sandbox/index.md): scenario catalog for verifying domain flows
|
package/package.json
CHANGED
package/scripts/docs/list.sh
CHANGED
|
@@ -38,6 +38,35 @@ is_internal_topic() {
|
|
|
38
38
|
esac
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
# Emits `name<TAB>description<TAB>category<TAB>target` per target-facing doc,
|
|
42
|
+
# sorted so a domain split into a folder lands in its alphabetical place rather
|
|
43
|
+
# than after every file. A folder declares its category on its own index, since
|
|
44
|
+
# the allowlist is what separates a target-facing doc from a workflow one and a
|
|
45
|
+
# split domain is not exempt from it.
|
|
46
|
+
collect_docs() {
|
|
47
|
+
local file name description category
|
|
48
|
+
{
|
|
49
|
+
while IFS= read -r file; do
|
|
50
|
+
name=$(basename "$file" .md)
|
|
51
|
+
[ "$name" = "index" ] && continue
|
|
52
|
+
category=$(read_frontmatter_field "$file" "category")
|
|
53
|
+
is_target_facing "$category" || continue
|
|
54
|
+
description=$(read_frontmatter_field "$file" "description")
|
|
55
|
+
printf '%s\t%s\t%s\t%s\n' "$name" "$description" "$category" "docs/$name.md"
|
|
56
|
+
done < <(find "$DOCS_DIR" -maxdepth 1 -type f -name "*.md")
|
|
57
|
+
|
|
58
|
+
# A split domain is named by its folder and described by its generated
|
|
59
|
+
# index, which carries subtitle where a sibling file carries description
|
|
60
|
+
while IFS= read -r file; do
|
|
61
|
+
name=$(basename "$(dirname "$file")")
|
|
62
|
+
category=$(read_frontmatter_field "$file" "category")
|
|
63
|
+
is_target_facing "$category" || continue
|
|
64
|
+
description=$(read_frontmatter_field "$file" "subtitle")
|
|
65
|
+
printf '%s\t%s\t%s\t%s\n' "$name" "$description" "$category" "docs/$name/index.md"
|
|
66
|
+
done < <(find "$DOCS_DIR" -mindepth 2 -maxdepth 2 -type f -name "index.md")
|
|
67
|
+
} | sort
|
|
68
|
+
}
|
|
69
|
+
|
|
41
70
|
# Emits `name<TAB>description<TAB>target` per context entry, sorted so a domain
|
|
42
71
|
# split into a folder lands in its alphabetical place rather than after every
|
|
43
72
|
# file. Matches listTopics in src/docs/read.ts, which sorts both together.
|
|
@@ -64,16 +93,11 @@ collect_context() {
|
|
|
64
93
|
}
|
|
65
94
|
|
|
66
95
|
list_text() {
|
|
67
|
-
local
|
|
96
|
+
local name description category target
|
|
68
97
|
log_step "Docs"
|
|
69
|
-
while IFS
|
|
70
|
-
name=$(basename "$file" .md)
|
|
71
|
-
[ "$name" = "index" ] && continue
|
|
72
|
-
category=$(read_frontmatter_field "$file" "category")
|
|
73
|
-
is_target_facing "$category" || continue
|
|
74
|
-
description=$(read_frontmatter_field "$file" "description")
|
|
98
|
+
while IFS=$'\t' read -r name description category target; do
|
|
75
99
|
log_info "$name : $description"
|
|
76
|
-
done < <(
|
|
100
|
+
done < <(collect_docs)
|
|
77
101
|
|
|
78
102
|
# Absent in a registry install, which ships docs/ without .claude/
|
|
79
103
|
if [ -d "$CONTEXT_DIR" ]; then
|
|
@@ -97,17 +121,12 @@ emit_json_entry() {
|
|
|
97
121
|
}
|
|
98
122
|
|
|
99
123
|
list_json() {
|
|
100
|
-
local
|
|
124
|
+
local name description category target
|
|
101
125
|
JSON_FIRST=1
|
|
102
126
|
printf '['
|
|
103
|
-
while IFS
|
|
104
|
-
name
|
|
105
|
-
|
|
106
|
-
category=$(read_frontmatter_field "$file" "category")
|
|
107
|
-
is_target_facing "$category" || continue
|
|
108
|
-
description=$(read_frontmatter_field "$file" "description")
|
|
109
|
-
emit_json_entry "$name" "$description" "$category" "docs/$(basename "$file")"
|
|
110
|
-
done < <(find "$DOCS_DIR" -maxdepth 1 -type f -name "*.md" | sort)
|
|
127
|
+
while IFS=$'\t' read -r name description category target; do
|
|
128
|
+
emit_json_entry "$name" "$description" "$category" "$target"
|
|
129
|
+
done < <(collect_docs)
|
|
111
130
|
|
|
112
131
|
if [ -d "$CONTEXT_DIR" ]; then
|
|
113
132
|
while IFS=$'\t' read -r name description target; do
|
|
@@ -296,6 +296,10 @@ inject_changed_skills() {
|
|
|
296
296
|
[ -z "$combined" ] && return
|
|
297
297
|
|
|
298
298
|
while IFS= read -r skill_path; do
|
|
299
|
+
# The diff against main lists a deleted skill alongside a changed one, and
|
|
300
|
+
# there is nothing left to inject for a name this branch removed.
|
|
301
|
+
[ -f "$PROJECT_ROOT/$skill_path" ] || continue
|
|
302
|
+
|
|
299
303
|
local skill_name
|
|
300
304
|
skill_name=$(basename "$(dirname "$skill_path")")
|
|
301
305
|
local target_dir="$SANDBOX/.claude/skills/$skill_name"
|
package/src/commands/sandbox.ts
CHANGED
|
@@ -389,7 +389,7 @@ function runCheck(
|
|
|
389
389
|
|
|
390
390
|
// The report always renders on stderr. `--json` adds the machine copy on
|
|
391
391
|
// stdout rather than replacing the frame, per the stream contract in
|
|
392
|
-
// `docs/agents.md`, so one invocation serves a human and a caller at once.
|
|
392
|
+
// `docs/agents/output-shape.md`, so one invocation serves a human and a caller at once.
|
|
393
393
|
reportVerdict(verdict)
|
|
394
394
|
if (options.json === true)
|
|
395
395
|
process.stdout.write(`${JSON.stringify(verdict)}\n`)
|
package/src/sandbox/census.ts
CHANGED
|
@@ -70,7 +70,7 @@ export function listSkills(root: string): string[] {
|
|
|
70
70
|
* Maps a scenario to the skill it drives, trying two spellings in order.
|
|
71
71
|
*
|
|
72
72
|
* `<category>-<command>` is the rule `.claude/context/sandbox/coverage.md` states, and it
|
|
73
|
-
* alone pairs 29 of
|
|
73
|
+
* alone pairs 29 of 54 skills. The bare `<command>` fallback is what reaches the
|
|
74
74
|
* rest: `claude/setup-init.sh` drives the `setup-init` skill, not a
|
|
75
75
|
* `claude-setup-init` that does not exist. Stating one spelling and shipping two
|
|
76
76
|
* is what let the audit report a paired skill as unpaired.
|
package/src/ui.ts
CHANGED
|
@@ -31,7 +31,7 @@ export function logRemove(message: string): void {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Renders the `✗` shape `docs/agents.md` specifies for a failure inside an
|
|
34
|
+
* Renders the `✗` shape `docs/agents/output-shape.md` specifies for a failure inside an
|
|
35
35
|
* open frame. It does not exit, so the caller closes the frame and returns an
|
|
36
36
|
* exit code rather than terminating mid-write.
|
|
37
37
|
*/
|
package/standards/skill.md
CHANGED
|
@@ -11,7 +11,7 @@ Skills give Claude Code domain-specific constraints and rules inline, so it can
|
|
|
11
11
|
|
|
12
12
|
## Scope
|
|
13
13
|
|
|
14
|
-
Governs a skill folder under `skills/` as one artifact: `SKILL.md`, its
|
|
14
|
+
Governs a skill folder under `skills/` as one artifact: `SKILL.md`, its sibling `REQUIREMENT.md`, and the bundled reference, script, and asset folders beside them.
|
|
15
15
|
|
|
16
16
|
Does not govern:
|
|
17
17
|
|
|
@@ -68,14 +68,14 @@ allowed-tools: <tools required>
|
|
|
68
68
|
|
|
69
69
|
## Structure
|
|
70
70
|
|
|
71
|
-
- Skill is a folder named in kebab-case containing `SKILL.md` (required), `REQUIREMENT.md` (
|
|
71
|
+
- Skill is a folder named in kebab-case containing `SKILL.md` (required), `REQUIREMENT.md` (required), `scripts/` (optional), `references/` (optional), `assets/` (optional)
|
|
72
72
|
- `SKILL.md` must start with YAML frontmatter between `---` delimiters
|
|
73
73
|
- No `README.md` inside the skill folder
|
|
74
74
|
- No spaces, capitals, or underscores in folder or skill name
|
|
75
75
|
|
|
76
76
|
## Requirement
|
|
77
77
|
|
|
78
|
-
`REQUIREMENT.md` states what a skill is for, so a proposed change can be argued against something. This standard governs shape across the corpus and the requirement governs scope for one skill. Claude Code loads `SKILL.md` as the entry and ignores the sibling, so the file costs a target session nothing.
|
|
78
|
+
`REQUIREMENT.md` states what a skill is for, so a proposed change can be argued against something and the corpus can be read to decide whether a skill should exist at all. This standard governs shape across the corpus and the requirement governs scope and behavior for one skill. Claude Code loads `SKILL.md` as the entry and ignores the sibling, so the file costs a target session nothing.
|
|
79
79
|
|
|
80
80
|
The file serves a second purpose beside the argument. A skill body is procedural by design, so what the skill is for sits spread across its steps rather than stated in one place. The requirement is the compressed statement a reader gets before opening the body, and that purpose holds whether or not the skill's scope is contested.
|
|
81
81
|
|
|
@@ -83,7 +83,7 @@ Read it before editing the skill. When a change closes no gap the requirement st
|
|
|
83
83
|
|
|
84
84
|
Write the gaps from what the skill is for, then compare the body against them. Deriving the requirement from the body is circular, because a requirement reverse-engineered from an overfitted skill records the overfitting as the requirement. That failure costs more under the orientation purpose than under the argument one, since a file summarizing the body misinforms whoever reads it in place of the body rather than merely failing to gate a change.
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
Every skill carries one. Coverage was selective while the file existed only to disambiguate a contested boundary, and a file present for some skills and absent for others cannot be scanned, because an absence reads as a gap rather than as a verdict. A skill whose scope nobody contests still owes the statement, since the reader deciding whether a skill should exist reads the corpus rather than one entry. A new skill is created with the sibling beside it rather than acquiring one in a later sweep.
|
|
87
87
|
|
|
88
88
|
### What a working requirement looks like
|
|
89
89
|
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: claude-design-propose
|
|
3
|
-
description: Retired. `claude-design-extract` absorbed this skill and now takes the greenfield path itself. Invoke `aitk:claude-design-extract` instead.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Design propose
|
|
8
|
-
|
|
9
|
-
Retired. `claude-design-extract` absorbed the greenfield path, picks it from what the project has, and its description carries every trigger this skill used to route on.
|
|
10
|
-
|
|
11
|
-
Invoke `aitk:claude-design-extract` instead. It reads `.claude/REQUIREMENTS.md` for the `## Personality` paragraph and `.claude/ARCHITECTURE.md` for platform signals when the project has no UI code, which is what this skill did.
|
|
12
|
-
|
|
13
|
-
This body exists so a project that installed the plugin before the merge keeps resolving the old name for one sync cycle. It ships in `0.18.0` and is removed in `0.19.0`.
|
|
14
|
-
|
|
15
|
-
`scripts/sandbox/claude/design-propose.sh` goes at the same time, but its fixture does not. That scenario is the only greenfield coverage the survivor has, so `0.19.0` folds it into `scripts/sandbox/claude/design-extract.sh` as a second arm rather than deleting it. Removing the file outright drops the greenfield path from the catalog.
|