@erclx/aitk 3.24.0 → 3.25.1
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/create-snippet/REQUIREMENT.md +3 -3
- package/claude/skills/create-snippet/SKILL.md +3 -3
- package/claude/skills/migration-claude-md/REQUIREMENT.md +0 -1
- package/claude/skills/migration-context/REQUIREMENT.md +0 -1
- package/claude/skills/migration-superseded/REQUIREMENT.md +0 -1
- package/claude/skills/setup-init/REQUIREMENT.md +1 -1
- package/claude/skills/setup-init/SKILL.md +4 -9
- package/claude/skills/toolkit-cli/REQUIREMENT.md +1 -2
- package/claude/skills/toolkit-operator/REQUIREMENT.md +1 -1
- package/claude/skills/toolkit-operator/SKILL.md +1 -1
- package/docs/agents/commands.md +1 -1
- package/docs/agents/context-audit.md +1 -1
- package/docs/agents/install-and-sync.md +30 -45
- package/docs/agents/scripting.md +0 -6
- package/docs/agents/skills-reach.md +1 -1
- package/docs/ai-workflow.md +0 -1
- package/docs/target-projects.md +12 -14
- package/governance/rules/claude/575-hooks.md +17 -0
- package/governance/stacks/base.toml +5 -3
- package/package.json +1 -1
- package/scripts/core/install-check.sh +10 -12
- package/scripts/core/verify.sh +9 -7
- package/src/claude/cases/setup.ts +0 -5
- package/src/claude/skills-reach.ts +3 -3
- package/src/cli.ts +2 -3
- package/src/commands/context.ts +2 -2
- package/src/commands/init.ts +0 -3
- package/src/commands/snippets.ts +2 -157
- package/src/commands/sync.ts +2 -5
- package/src/context/citations.ts +41 -1
- package/src/init/flags.ts +3 -8
- package/src/init/plan.ts +1 -21
- package/src/init/steps.ts +1 -21
- package/src/sync/check.ts +6 -11
- package/src/sync/layout.ts +9 -6
- package/src/sync/reverse.ts +3 -5
- package/src/sync/stamp.ts +7 -7
- package/src/sync/target.ts +1 -3
- package/standards/skill.md +1 -1
- package/claude/skills/migration-standards/REQUIREMENT.md +0 -50
- package/claude/skills/migration-standards/SKILL.md +0 -99
- package/src/snippets/adapter.ts +0 -35
- package/src/snippets/install.ts +0 -172
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ git init
|
|
|
116
116
|
aitk init
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
`aitk init` installs base tooling configs, Claude seeds, and governance rules in one pass, and scaffolds a `.claude/wiki/` stub for your project's own reference pages. Governance defaults to the `base` stack, so a bare init lands the coding and doc-authoring rules in `.claude/rules/`. Each rule names the standard it answers to and reads it with `aitk standards <name>`, so no corpus is copied into your project. Pass `--stack <name>` for a framework stack, or `--skip governance` to leave rules out.
|
|
119
|
+
`aitk init` installs base tooling configs, Claude seeds, and governance rules in one pass, and scaffolds a `.claude/wiki/` stub for your project's own reference pages. Governance defaults to the `base` stack, so a bare init lands the coding and doc-authoring rules in `.claude/rules/`. Each rule names the standard it answers to and reads it with `aitk standards <name>`, so no corpus is copied into your project. Pass `--stack <name>` for a framework stack, or `--skip governance` to leave rules out. A snippet resolves the same way, reached at its `@` reference through the plugin's live `claude/snippets` symlink rather than a copy. Run `aitk tooling list --json` to see the catalog.
|
|
120
120
|
|
|
121
121
|
For the full journey from scaffold through adding a domain later to syncing upstream drift, see [target projects](docs/target-projects.md).
|
|
122
122
|
|
|
@@ -9,15 +9,15 @@ description: Why a snippet needs its shape read from the reference and its write
|
|
|
9
9
|
|
|
10
10
|
Without this skill, a snippet is drafted the way any other markdown file is drafted, so it arrives carrying frontmatter, headings, and a fill-in placeholder. None of the invocation channels strip those. Typing `>slug` in a chat inserts the scaffolding verbatim, and the file that was meant to be one instruction reads as a document.
|
|
11
11
|
|
|
12
|
-
The write surface is the second failure. The toolkit authors at `snippets/` and a target project
|
|
12
|
+
The write surface is the second failure. The toolkit authors at `snippets/` and a target project may still hold a stale `.claude/snippets/` copy from before that domain's install channel retired, so a session picks whichever folder it noticed first. A toolkit snippet written into the consumed copy fails the drift assertion that regenerates that folder. A snippet written there in a target project is correct and looks identical, which is why the surface has to be resolved from what the project has rather than guessed.
|
|
13
13
|
|
|
14
|
-
Inside the project surface, a third failure sits one level deeper. A project-authored snippet sharing a name with a toolkit one used to be indistinguishable from it,
|
|
14
|
+
Inside the project surface, a third failure sits one level deeper. A project-authored snippet sharing a name with a toolkit one used to be indistinguishable from it, back when `aitk snippets sync` walked that folder and could not tell which side owned the file. That verb retired with the domain's install channel, so nothing reads ownership by location there any more, but the `project/` subfolder still separates the two by eye, which is worth keeping even with no sync left to protect from.
|
|
15
15
|
|
|
16
16
|
## Must
|
|
17
17
|
|
|
18
18
|
- Read the bundled snippet reference before drafting, since the shape rules are what the invocation channels depend on
|
|
19
19
|
- Resolve the write surface from which snippet folder the project has, rather than from whichever one the session noticed first
|
|
20
|
-
- On the project surface, write under its `project/` subfolder
|
|
20
|
+
- On the project surface, write under its `project/` subfolder, keeping a project-authored file visually apart from a toolkit-installed one
|
|
21
21
|
- Confirm the slug and the full body with the user before writing
|
|
22
22
|
- Emit the written path in full, so the terminal can resolve it
|
|
23
23
|
- State what the resolved surface implies after writing, since a root file needs the consumed copy regenerated and a project-local one needs copying to the toolkit to ship
|
|
@@ -17,14 +17,14 @@ Creates one snippet file. Read these files in parallel:
|
|
|
17
17
|
|
|
18
18
|
## Steps
|
|
19
19
|
|
|
20
|
-
1. Resolve the write surface: `snippets/` at the root if present, which is the toolkit's own authoring source. Otherwise `.claude/snippets/`, a target project
|
|
20
|
+
1. Resolve the write surface: `snippets/` at the root if present, which is the toolkit's own authoring source. Otherwise `.claude/snippets/`, a stale copy a target project holds from before its install channel retired.
|
|
21
21
|
2. Draft the content from the user's description. The snippet reference governs structure, invocation, and authoring conventions.
|
|
22
22
|
3. Confirm the slug and full content with the user before writing
|
|
23
|
-
4. Write the file. On the root surface: `<surface>/<category>/<slug>.md`, or `<surface>/<slug>.md` when the snippet takes no category. On the `.claude/` surface: the same shape nested one level deeper under `project/`,
|
|
23
|
+
4. Write the file. On the root surface: `<surface>/<category>/<slug>.md`, or `<surface>/<slug>.md` when the snippet takes no category. On the `.claude/` surface: the same shape nested one level deeper under `project/`, a convention kept for its own sake now that nothing syncs that folder.
|
|
24
24
|
|
|
25
25
|
## After writing
|
|
26
26
|
|
|
27
27
|
Emit the full path on its own line.
|
|
28
28
|
|
|
29
29
|
- Root surface: this is the toolkit's authoring source. Remind the user to run `bun run check` to regenerate the consumed copy under `.claude/`.
|
|
30
|
-
- `.claude/` surface: the file is project-local, under `.claude/snippets/project/`.
|
|
30
|
+
- `.claude/` surface: the file is project-local, under `.claude/snippets/project/`. Remind the user to copy it to the toolkit repo, under `snippets/<category>/<name>.md`, if it should ship to every project.
|
|
@@ -36,6 +36,5 @@ The skill also writes into `.claude/context/`, a folder `migration-context` move
|
|
|
36
36
|
## Out of scope
|
|
37
37
|
|
|
38
38
|
- Relocating `docs/` files, which `migration-context` proposes into this same `.claude/context/` folder. Run that skill first when both apply, so Step 3 reads a folder its moves have already populated.
|
|
39
|
-
- Relocating root `standards/` and `snippets/`: `migration-standards`
|
|
40
39
|
- Scaffolding the rule files it proposes, which `create-rule` does with the numbering and frontmatter
|
|
41
40
|
- Regenerating `.claude/context/index.md`, which `aitk indexes regen` does once the user has applied the moves
|
|
@@ -33,5 +33,4 @@ A seed-derived `development.md` moved out of `docs/` comes back on the next seed
|
|
|
33
33
|
## Out of scope
|
|
34
34
|
|
|
35
35
|
- Classifying `CLAUDE.md` sections, which `migration-claude-md` proposes into this same `.claude/context/` folder. Run this skill first when both apply, so that skill's append-or-create check reads a folder the moves have already populated.
|
|
36
|
-
- Relocating root `standards/` and `snippets/`: `migration-standards`
|
|
37
36
|
- Regenerating `.claude/context/index.md`, which `aitk indexes regen` does once the user has applied the moves
|
|
@@ -38,7 +38,6 @@ The last is the two-speed release skew arriving as a confident wrong answer. `su
|
|
|
38
38
|
|
|
39
39
|
## Out of scope
|
|
40
40
|
|
|
41
|
-
- Relocating root `snippets/` into `.claude/`: `migration-standards`
|
|
42
41
|
- Classifying `CLAUDE.md` sections into the three-tier model: `migration-claude-md`
|
|
43
42
|
- Relocating `docs/` files by audience: `migration-context`
|
|
44
43
|
- Reconciling a seed file against its source section by section, which diffs two files rather than splitting one into a folder: `claude-seed-sync`
|
|
@@ -36,7 +36,7 @@ The other is the refusal that ends rather than routes. An existing project, an i
|
|
|
36
36
|
|
|
37
37
|
## Out of scope
|
|
38
38
|
|
|
39
|
-
- Installing governance rules alone: `setup-gov`. This skill installs governance beside tooling
|
|
39
|
+
- Installing governance rules alone: `setup-gov`. This skill installs governance beside tooling and the seeds.
|
|
40
40
|
- Bootstrapping the `index.md` system: `setup-indexes`. Neither `aitk init` nor this chain performs it.
|
|
41
41
|
- Provisioning Claude Code plugins: `setup-plugins`. Those install once per machine rather than into a project, so no project-scoped chain can carry them.
|
|
42
42
|
- Running the verification scripts, which `setup-verify` owns and this chain invokes as its last step
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-init
|
|
3
|
-
description: Detects a new project's type and runs `aitk init` with a resolved stack
|
|
3
|
+
description: Detects a new project's type and runs `aitk init` with a resolved stack in one shot. Use when bootstrapping a new project with the toolkit, or when asked to "init this project", "bootstrap the toolkit", "set up toolkit", or "one-shot install". Assumes the `aitk` CLI is on PATH. Do NOT use when only installing governance rules. Use `setup-gov` instead.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Init project
|
|
@@ -30,8 +30,6 @@ Run from the target project's current directory. Do not cd into the toolkit sour
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
aitk gov list --json 2>/dev/null
|
|
33
|
-
aitk snippets list --json 2>/dev/null
|
|
34
|
-
aitk standards list --json 2>/dev/null
|
|
35
33
|
aitk tooling list --json 2>/dev/null
|
|
36
34
|
```
|
|
37
35
|
|
|
@@ -49,8 +47,7 @@ Read these from the project root in parallel, skipping any that do not exist:
|
|
|
49
47
|
- **Stack:** pick the closest governance stack by matching detected runtime or framework against stack names in the catalog. If nothing matches, fall back to `base` and carry the fallback into the preview.
|
|
50
48
|
- **Tooling stack:** pick the closest tooling stack from `aitk tooling list --json` (e.g. `vite-react`, `astro`). Distinct from the governance stack. Fall back to `base` if no framework match, and carry that fallback into the preview too.
|
|
51
49
|
- **Extras:** identify technologies not already covered by the picked stack. For each, find a rule whose `description` or `paths` points at that technology and pass it via `--add`. Do not add a rule the stack already pulls in.
|
|
52
|
-
- **
|
|
53
|
-
- **Skip (`--skip`):** `standards` and `wiki` are core and install by default. Add `--skip standards` or `--skip wiki` only when the user explicitly wants them left out.
|
|
50
|
+
- **Skip (`--skip`):** `wiki` installs by default. Add `--skip wiki` only when the user explicitly wants it left out.
|
|
54
51
|
|
|
55
52
|
## Gap handling
|
|
56
53
|
|
|
@@ -59,7 +56,7 @@ If a detected technology has no matching rule or stack, do not guess. Surface th
|
|
|
59
56
|
1. Defer to `setup-gov`. Author a rule in the toolkit, then re-run this skill.
|
|
60
57
|
2. Proceed with the matched layer, listing the gap in the final report.
|
|
61
58
|
|
|
62
|
-
Rules
|
|
59
|
+
Rules and stacks are authored in the toolkit repo, never in the target project on the fly.
|
|
63
60
|
|
|
64
61
|
## Preview
|
|
65
62
|
|
|
@@ -69,7 +66,6 @@ Before executing, output:
|
|
|
69
66
|
- **Stack:** picked governance stack + resolved rule count. Mark it `fallback` when no detected runtime or framework matched a catalog name.
|
|
70
67
|
- **Tooling stack:** picked tooling stack. Mark it `fallback` on the same test, and name what `base` lands: configs, seeds, and gitignore entries in every case, plus the JavaScript development dependencies, scripts, and hook activation wherever a `package.json` exists to carry them. A project outside that ecosystem runs none of the second group and keeps the first.
|
|
71
68
|
- **Extras:** each `--add` rule with a one-line reason
|
|
72
|
-
- **Snippets:** resolved category
|
|
73
69
|
- **Skip:** any `--skip` entries with reason
|
|
74
70
|
- **Target:** resolved target path
|
|
75
71
|
- **Commands:** the full chain that will run
|
|
@@ -80,13 +76,12 @@ A resolved name and a fallback read alike once written, so mark the fallback her
|
|
|
80
76
|
|
|
81
77
|
Run the chain in order, starting immediately after the preview. Each step's permission dialog is the confirmation gate. Do not pause for additional confirmation. Run from the target project's current directory.
|
|
82
78
|
|
|
83
|
-
Step 1: `aitk init` installs base tooling, claude seeds, governance rules,
|
|
79
|
+
Step 1: `aitk init` installs base tooling, claude seeds, governance rules, and wiki.
|
|
84
80
|
|
|
85
81
|
```bash
|
|
86
82
|
AITK_NON_INTERACTIVE=1 aitk init \
|
|
87
83
|
--stack <stack> \
|
|
88
84
|
--add <rules> \
|
|
89
|
-
--snippets <category> \
|
|
90
85
|
<target>
|
|
91
86
|
```
|
|
92
87
|
|
|
@@ -15,7 +15,7 @@ The inverse failure is quieter. A session that assumes a sync will pick up a cha
|
|
|
15
15
|
|
|
16
16
|
Being reachable is a separate problem from being right. This is a pure reference whose moment happens inside another skill's run, so nothing brings it up unless a body names it. Three sibling requirement files named it and routed nothing, because Claude Code loads `SKILL.md` as the entry and never opens the sibling. A route lives in a body or it does not exist, and a fourth requirement mention would repeat the same defect.
|
|
17
17
|
|
|
18
|
-
The
|
|
18
|
+
The two bodies now carrying an inline pointer are `claude-seed-sync` and `toolkit-operator`, each at the point it runs or prints an overwriting command.
|
|
19
19
|
|
|
20
20
|
## Must
|
|
21
21
|
|
|
@@ -38,5 +38,4 @@ The three bodies now carrying an inline pointer are `claude-seed-sync`, `migrati
|
|
|
38
38
|
|
|
39
39
|
- Executing the sync, which the user runs or `toolkit-operator` routes
|
|
40
40
|
- Reconciling a customized seed section by section: `claude-seed-sync`
|
|
41
|
-
- Relocating a project's folders into the layout a newer version expects: `migration-standards`
|
|
42
41
|
- Deciding which stack, rule, or standard a project should install, which the setup skills resolve from live catalogs
|
|
@@ -27,7 +27,7 @@ The last failure is a section no route reaches. `## Route` maps an intent or a d
|
|
|
27
27
|
- Run the CLI non-interactively and report the command run, what changed, and the full path of anything written
|
|
28
28
|
- Read the overwrite contract from the body before any install or sync, and name each surface it lists as overwritten before running one
|
|
29
29
|
- Read the reverse walk beside the forward sections, so a folder the toolkit stopped shipping and a migration with a live case both reach the user
|
|
30
|
-
- Hand off a named migration to the skill the report names,
|
|
30
|
+
- Hand off a named migration to the skill the report names, and name an unmigrated domain's root and install path for the user to move themselves when no skill covers it
|
|
31
31
|
- Route a measurement intent to the audit offers from the route table itself, rather than leaving the section reachable only by reading past the table
|
|
32
32
|
- Rank a lifecycle row against the audit offers where the route table itself states it, so a session acting on the lifecycle row reads the ranking without opening the section being ranked
|
|
33
33
|
- Offer every audit whose surface the target carries, and offer none whose surface it lacks
|
|
@@ -42,7 +42,7 @@ Map the stated intent, or what `## Diagnose` found, to one lifecycle phase, then
|
|
|
42
42
|
|
|
43
43
|
The two can name different rows, and a reply answers both rather than picking one. Run or hand off what the finding names, then answer the intent in the same reply. A measurement intent therefore reaches the audit offers below even on a target whose diagnostic found scaffold work, which is the case a session leaving from the scaffold row would otherwise never read.
|
|
44
44
|
|
|
45
|
-
- A domain in `unmigrated`:
|
|
45
|
+
- A domain in `unmigrated`: name it, the root path, and the install path. No command moves it, so the user runs the relocation themselves
|
|
46
46
|
- An entry in `migrations`: hand off to the skill its `skill` field names, spelled as the report spells it. Both of them propose without writing, so the handoff is where this stops
|
|
47
47
|
- Anything in `superseded`: name which files and what replaced them, then hand off to `migration-superseded`. Both skills propose, so neither moves nor deletes the file
|
|
48
48
|
- A folder in `unclaimed`: name it and the attribution it carries. No command moves it and the content may be the project's own, so the decision is the user's
|
package/docs/agents/commands.md
CHANGED
|
@@ -71,7 +71,7 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
|
|
|
71
71
|
| Domain | Subcommands |
|
|
72
72
|
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
73
73
|
| `tooling` | `list`, `sync`, `ref`, `create`, `verify`, `inject`, `prune-gitignore` |
|
|
74
|
-
| `snippets` | `list`, `
|
|
74
|
+
| `snippets` | `list`, `create` |
|
|
75
75
|
| `standards` | `list`, `<name>` |
|
|
76
76
|
| `gov` | `list`, `install`, `sync`, `build`, `regen`, `test-order`, `superseded` |
|
|
77
77
|
| `claude` | `init`, `sync`, `routing`, `seeds list`, `skills list`, `skills audit`, `skills drift`, `skills reach`, `skills rank`, `setup [dest]` |
|
|
@@ -76,7 +76,7 @@ Three exclusions keep it from firing on prose about paths. Fenced blocks are ski
|
|
|
76
76
|
|
|
77
77
|
Two cases remain, and no syntax separates either from a real reference. One is a sentence naming a hypothetical entry to show the shape of a name. The other is a line instructing a target project about its own tree, which resolves against the target rather than against this repository and passes here only while the two layouts agree. Splitting a seeded domain into a folder ends that agreement and turns every such line red at once.
|
|
78
78
|
|
|
79
|
-
Append `<!-- audit-ignore-citations -->` to the source line in either case. The marker
|
|
79
|
+
Append `<!-- audit-ignore-citations: <path> -->` to the source line in either case, naming the exact path the sentence displays. The marker excuses only the paths it names, so a line carrying a real reference beside the displayed one keeps that reference checked. A bare `<!-- audit-ignore-citations -->` with no path excuses every citation the line carries instead, and the reference-form check reads either form the same way, since both ask whether a line points at a file and the marker is how a line says it displays a name instead.
|
|
80
80
|
|
|
81
81
|
The marker itself stays out of anything that installs. A seed, a plugin skill body, and a stack reference all reach a target, so a marker there lands as toolkit bookkeeping in someone else's tree. Reword those lines to drop the path instead, and where a stop message has to spell it, move that message into a fenced block, which this check already skips.
|
|
82
82
|
|
|
@@ -26,10 +26,8 @@ rules, skills, and docs may cite. `aitk standards rule` carries the reserved
|
|
|
26
26
|
number bands behind that placement, where `900-999` is the range a
|
|
27
27
|
project-authored rule takes and everything below it belongs to the toolkit.
|
|
28
28
|
|
|
29
|
-
`aitk
|
|
30
|
-
|
|
31
|
-
`aitk sync --check` does not. It skips every orphaned entry, so the destination
|
|
32
|
-
reaches the two domain sync verbs alone.
|
|
29
|
+
`aitk sync --check` does not report an orphaned entry. It skips every one, so
|
|
30
|
+
the destination reaches `aitk gov sync` alone, the one domain sync verb left.
|
|
33
31
|
|
|
34
32
|
When the target's install recorded a stack, `aitk gov sync` also reports a
|
|
35
33
|
rule that stack lists and `.claude/rules/` does not hold, as a `missing` entry
|
|
@@ -46,30 +44,27 @@ installs into no project, so the domain has nothing in a target to reconcile.
|
|
|
46
44
|
and then the corpus inside the package, and `aitk standards list --json` carries
|
|
47
45
|
the catalog.
|
|
48
46
|
|
|
49
|
-
`aitk snippets sync`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
It is not preset-aware, so a project that installed `essentials`
|
|
55
|
-
does not grow new snippets on a sync. Use `aitk snippets install` to add them.
|
|
47
|
+
There is no `aitk snippets sync` and no `aitk snippets install` either, on the
|
|
48
|
+
same ground: `claude/snippets` in the plugin cache symlinks live to the
|
|
49
|
+
toolkit's own `snippets/`, so a session reaches one at its `@` reference with
|
|
50
|
+
no copy to reconcile. `aitk snippets list --json` carries the catalog and
|
|
51
|
+
`aitk snippets create` is the one verb left that still writes a file.
|
|
56
52
|
|
|
57
53
|
## Install guards
|
|
58
54
|
|
|
59
|
-
`aitk gov install`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
and exits 1.
|
|
55
|
+
`aitk gov install` requires its first argument under
|
|
56
|
+
`AITK_NON_INTERACTIVE=1`. It used to fall back to an interactive picker that
|
|
57
|
+
resolved to its first option headlessly, so a call with no stack installed
|
|
58
|
+
whichever stack sorted first. It now reports the valid names on stderr and
|
|
59
|
+
exits 1.
|
|
65
60
|
|
|
66
61
|
Every documented agent path already passes the argument, including
|
|
67
62
|
`aitk init`. The confirm-then-apply prompt after it still resolves to `Yes`
|
|
68
|
-
headlessly, so a call that names its stack
|
|
63
|
+
headlessly, so a call that names its stack is unchanged.
|
|
69
64
|
|
|
70
|
-
`aitk gov install` also refuses the toolkit root as a target
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
`aitk gov install` also refuses the toolkit root as a target. It resolves the
|
|
66
|
+
target before anything else, so a path that does not exist fails rather than
|
|
67
|
+
being scaffolded.
|
|
73
68
|
|
|
74
69
|
## Standards resolution
|
|
75
70
|
|
|
@@ -227,14 +222,13 @@ refusal rather than a shape nobody stated.
|
|
|
227
222
|
to, with nothing at the path the current one reads. It carries `rootPath`,
|
|
228
223
|
`installPath`, and a file count. Without it a project holding `standards/` at its
|
|
229
224
|
root reports zero entries for that domain and reads as clean, which is the most
|
|
230
|
-
misleading state the report can produce.
|
|
225
|
+
misleading state the report can produce.
|
|
231
226
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
file and proposes relocating the lot.
|
|
227
|
+
The field currently names no domain. Standards and snippets are the two the
|
|
228
|
+
toolkit ever installed at a project root, and both closed their install channel,
|
|
229
|
+
so a project still holding a root `standards/` or `snippets/` folder is carrying
|
|
230
|
+
its own authoring surface rather than an unfinished install. Nothing proposes
|
|
231
|
+
moving either, and no command relocates the content. Move it yourself.
|
|
238
232
|
|
|
239
233
|
#### Rules the target never received
|
|
240
234
|
|
|
@@ -268,8 +262,8 @@ rule the chain lists reaches both surfaces the same way.
|
|
|
268
262
|
A target stamped before governance recorded a chain falls back to the older
|
|
269
263
|
band-inference read below. The measurement there anchors on governance's own
|
|
270
264
|
stamp rather than on the oldest anchor across domains, since rules are
|
|
271
|
-
domain-scoped and a shared anchor would let
|
|
272
|
-
rules are measured from. A target carrying no chain and no governance anchor
|
|
265
|
+
domain-scoped and a shared anchor would let another domain's sync move the
|
|
266
|
+
revision rules are measured from. A target carrying no chain and no governance anchor
|
|
273
267
|
reports nothing at all: it has no date to measure against, and diffing from the
|
|
274
268
|
start of history would read the whole catalog as new.
|
|
275
269
|
|
|
@@ -343,9 +337,8 @@ colliding on a retired name costs the walk no reads. The cost is that a file the
|
|
|
343
337
|
toolkit shipped and the target renamed goes unmatched, the same limit the
|
|
344
338
|
`unmigrated` count carries.
|
|
345
339
|
|
|
346
|
-
`migrations` names a proposal-only skill with a live case in this target
|
|
347
|
-
|
|
348
|
-
`CLAUDE.md` past 250 lines for `migration-claude-md`, and on a `docs/` folder
|
|
340
|
+
`migrations` names a proposal-only skill with a live case in this target. It
|
|
341
|
+
fires on a `CLAUDE.md` past 250 lines for `migration-claude-md`, and on a `docs/` folder
|
|
349
342
|
holding markdown with no populated `.claude/context/` for `migration-context`.
|
|
350
343
|
Each entry carries the skill name and the measurement behind it, so a consumer
|
|
351
344
|
can check the proposal before running it. Without the field both skills are
|
|
@@ -371,24 +364,16 @@ so this section reports and gates nothing.
|
|
|
371
364
|
|
|
372
365
|
## Bootstrap
|
|
373
366
|
|
|
374
|
-
`aitk init` installs up to
|
|
367
|
+
`aitk init` installs up to four core domains and reports each one independently. A
|
|
375
368
|
domain that fails does not abort the run, so the command finishes the rest and
|
|
376
369
|
exits 1 naming the failures. Passing any flag skips the confirmation prompt,
|
|
377
370
|
which is what makes it scriptable.
|
|
378
371
|
|
|
379
372
|
`--stack` defaults to `base`, and the default
|
|
380
373
|
does not read as a passed flag, so a bare `aitk init` installs governance and
|
|
381
|
-
still prompts. `--skip` takes `wiki
|
|
382
|
-
without aborting on any other value. There is no `--standards
|
|
383
|
-
writes
|
|
384
|
-
|
|
385
|
-
`--snippets` carries no default. A bare `aitk init` installs no snippets and
|
|
386
|
-
reports the domain as skipped, the same way an explicit `--skip snippets`
|
|
387
|
-
does, both naming `aitk snippets install essentials <target>` as the recovery
|
|
388
|
-
command. `--snippets none` is a distinct, deliberate way to reach the same
|
|
389
|
-
zero-file result while still running the step, which is what lets a scripted
|
|
390
|
-
caller assert "install nothing" without depending on an empty string, which
|
|
391
|
-
`aitk snippets install` refuses.
|
|
374
|
+
still prompts. `--skip` takes `wiki` and `governance`, and warns
|
|
375
|
+
without aborting on any other value. There is no `--standards` and no
|
|
376
|
+
`--snippets`, since no run writes either corpus into the target.
|
|
392
377
|
|
|
393
378
|
## Unguarded tooling primitives
|
|
394
379
|
|
package/docs/agents/scripting.md
CHANGED
|
@@ -106,12 +106,6 @@ aitk tooling inject base /path/to/project --configs --seeds
|
|
|
106
106
|
# Prints the number removed on stdout, diagnostics on stderr
|
|
107
107
|
aitk tooling prune-gitignore base /path/to/project
|
|
108
108
|
|
|
109
|
-
# Install a snippet preset
|
|
110
|
-
AITK_NON_INTERACTIVE=1 aitk snippets install essentials /path/to/project
|
|
111
|
-
|
|
112
|
-
# Update snippets already installed, leaving project-authored ones alone
|
|
113
|
-
AITK_NON_INTERACTIVE=1 aitk snippets sync /path/to/project
|
|
114
|
-
|
|
115
109
|
# Print one standard. Nothing installs the corpus, so this is how a target reads one
|
|
116
110
|
AITK_NON_INTERACTIVE=1 aitk standards slug >slug.md
|
|
117
111
|
|
|
@@ -34,7 +34,7 @@ A path the toolkit does not hold is dropped rather than reported. The measure as
|
|
|
34
34
|
|
|
35
35
|
## The ownership key
|
|
36
36
|
|
|
37
|
-
A cited path counts when it sits under an authoring root no install channel delivers. Standards install nowhere and are read through the plugin corpus,
|
|
37
|
+
A cited path counts when it sits under an authoring root no install channel delivers. Standards and snippets install nowhere and are read through the plugin corpus, governance rules install under `.claude/rules/`, and the rest is this repository's own source, catalogs, and contract pages.
|
|
38
38
|
|
|
39
39
|
`src/`, `scripts/`, and bare `docs/` are deliberately outside the list. A body naming one of those is describing the reader's own tree, so listing them reports a correct citation on every run and buries the finding under the pass.
|
|
40
40
|
|
package/docs/ai-workflow.md
CHANGED
|
@@ -262,7 +262,6 @@ This section is the corpus the coverage claim is measured against: every name `a
|
|
|
262
262
|
| `aitk:claude-seed-sync` | After a toolkit update, to reconcile installed seeds without losing customizations |
|
|
263
263
|
| `aitk:migration-claude-md` | When `CLAUDE.md` grew past what always-load context should carry |
|
|
264
264
|
| `aitk:migration-context` | When `docs/` holds agent-flavored files belonging in `.claude/context/` |
|
|
265
|
-
| `aitk:migration-standards` | When standards sit at the root while rules point into `.claude/` |
|
|
266
265
|
| `aitk:migration-superseded` | When a drift report names a `.claude/` file a folder has replaced |
|
|
267
266
|
| `aitk:toolkit-feedback` | When something in the toolkit is broken, missing, or off |
|
|
268
267
|
| `aitk:toolkit-triage` | In the toolkit repo, to work through the open feedback issues |
|
package/docs/target-projects.md
CHANGED
|
@@ -27,7 +27,7 @@ The `aitk` CLI is separate. Twenty skills invoke it in a command position, and a
|
|
|
27
27
|
bun install --global @erclx/aitk
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
The package ships the catalogs the CLI reads, not only `src/`, so `aitk init` resolves
|
|
30
|
+
The package ships the catalogs the CLI reads, not only `src/`, so `aitk init` resolves governance, tooling, and the seeds from wherever the package landed, and `aitk standards <name>` reads the corpus from there too.
|
|
31
31
|
|
|
32
32
|
Pointing Claude Code at a checkout stays the development path, where a local skill edit overrides the installed copy for that session.
|
|
33
33
|
|
|
@@ -46,12 +46,12 @@ The chain is:
|
|
|
46
46
|
|
|
47
47
|
- `aitk init` installs base tooling, Claude seeds, and governance rules into `.claude/rules/` in the same pass
|
|
48
48
|
- `aitk tooling sync <stack> --write` adds stack-specific deps, scripts, and gitignore entries
|
|
49
|
-
- The agent reads `aitk tooling reference <stack>` (plus parents) as its audit context, follows it to generate eslint, vitest, playwright configs and the stack's setup script, and extends `.claude/context/ci.md` and `.claude/context/development.md` per the reference's extend sections <!-- audit-ignore-citations -->
|
|
49
|
+
- The agent reads `aitk tooling reference <stack>` (plus parents) as its audit context, follows it to generate eslint, vitest, playwright configs and the stack's setup script, and extends `.claude/context/ci.md` and `.claude/context/development.md` per the reference's extend sections <!-- audit-ignore-citations: .claude/context/development.md -->
|
|
50
50
|
- `setup-verify` runs the installed `package.json` scripts (lint, typecheck, check, test, build) and reports pass or fail
|
|
51
51
|
|
|
52
52
|
The chain serves a fresh scaffold and names a destination for the three states it does not. An existing project goes to `aitk:toolkit-operator`, which reads what the project already carries before naming a per-domain command. An install wanting the Claude layer without the tooling chain runs `aitk claude init` for the seed docs and then `aitk:setup-indexes` for the index system. A language the toolkit ships no stack for is the one of the three the chain still runs for, on `base`, with the fallback marked in the preview so it can be declined there.
|
|
53
53
|
|
|
54
|
-
Keep the `## Scripts` table in `.claude/context/development.md` current as scripts are added. Base tooling seeds that entry with the commands it installs, and each stack reference extends the table. `project-commands` reads it to start the app or run a check on request, so a command missing from the table cannot be run that way. A project whose entry outgrew one file and split into `.claude/context/development/` keeps the table in `overview.md`, which is where the skill looks next. <!-- audit-ignore-citations -->
|
|
54
|
+
Keep the `## Scripts` table in `.claude/context/development.md` current as scripts are added. Base tooling seeds that entry with the commands it installs, and each stack reference extends the table. `project-commands` reads it to start the app or run a check on request, so a command missing from the table cannot be run that way. A project whose entry outgrew one file and split into `.claude/context/development/` keeps the table in `overview.md`, which is where the skill looks next. <!-- audit-ignore-citations: .claude/context/development.md -->
|
|
55
55
|
|
|
56
56
|
### From scaffold to first feature
|
|
57
57
|
|
|
@@ -88,12 +88,11 @@ Run `aitk tooling list --json` and `aitk gov list --json` to see the current cat
|
|
|
88
88
|
|
|
89
89
|
No standard is written into the project. Each governance rule's authority line names `aitk standards <name>`, which answers from the corpus inside the CLI's own package, and every toolkit skill names the copy in its own plugin root. `aitk markdown audit` needs no standard at all, its ban sets and checkpoints shipping with the package as data.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
No snippet is written into the project either. `claude/snippets` in the plugin cache symlinks to the toolkit's own `snippets/`, so a session reaches one at its `@` reference with no install step, the same live resolution `claude/standards` gives a rule's authority line.
|
|
92
92
|
|
|
93
|
-
`governance
|
|
93
|
+
`governance` and `wiki` are skippable:
|
|
94
94
|
|
|
95
95
|
- `--skip governance`: leave `.claude/rules/` empty, so no coding standard loads on a file match. The preview names any `--add` rules the skip drops, and the run prints the `aitk gov install <stack> <path>` command to add rules afterward, carrying those extras so one paste restores what the skip declined.
|
|
96
|
-
- `--skip snippets`: the explicit spelling for what a bare init already does, since `--snippets` carries no default. Both print the `aitk snippets install essentials <path>` command afterward.
|
|
97
96
|
- `--skip wiki`: skip the `.claude/wiki/` scaffold. A target that already carries a root `wiki/` keeps it, since the verb reports that folder rather than migrating it.
|
|
98
97
|
|
|
99
98
|
The plugin corpus carries runtime behavior rather than reference prose alone, because the pre-publish scan and the branch-slug transform each have a standard of their own, `publish.md` and `slug.md`, cited by the skills that run them.
|
|
@@ -105,9 +104,8 @@ When a new need appears after scaffold, install the one domain without re-runnin
|
|
|
105
104
|
- Governance rule for a newly adopted library: invoke `aitk:setup-gov`, or run `aitk gov install <stack> --add <rule> <path>`
|
|
106
105
|
- Project-specific rule the toolkit does not ship: invoke `aitk:create-rule`. It scaffolds a rule into `.claude/rules/` with a non-colliding number, and `aitk gov sync` leaves it untouched.
|
|
107
106
|
- Index.md system for a markdown-heavy folder that emerged: invoke `aitk:setup-indexes`
|
|
108
|
-
- A snippet preset or category: `aitk snippets install <preset|category|all> <path>`. The argument is required, since the picker refuses headlessly rather than choosing for the caller
|
|
109
107
|
|
|
110
|
-
Standards are not on that list, and there is nothing to add.
|
|
108
|
+
Standards and snippets are not on that list, and there is nothing to add for either. Neither installs into a project, by default or by flag, so a session reads a standard with `aitk standards <name>` and a snippet through its `@` reference off the live plugin symlink, both resolving against the toolkit rather than a project copy. A project holding a `.claude/standards/` or `.claude/snippets/` folder from an older toolkit is carrying a stale artifact nothing reads, and deleting it is safe.
|
|
111
109
|
|
|
112
110
|
Per-domain mechanics live in the corresponding `docs/<domain>.md`. The skill body in `claude/skills/<skill>/SKILL.md` covers detection and preview.
|
|
113
111
|
|
|
@@ -125,17 +123,17 @@ The report opens by naming the binary running it. The installed version reads ag
|
|
|
125
123
|
|
|
126
124
|
#### Then the causes
|
|
127
125
|
|
|
128
|
-
A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision and `aitk:claude-seed-sync` is the tool for it. A `stranded` file sits where an older toolkit installed it and the toolkit has since moved, which is
|
|
126
|
+
A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision and `aitk:claude-seed-sync` is the tool for it. A `stranded` file sits where an older toolkit installed it and the toolkit has since moved, which is a relocation the report names but no command runs.
|
|
129
127
|
|
|
130
|
-
That attribution comes from `.claude/aitk/config.json`, a stamp every install and sync writes. A target stamped before that path shipped is read from the retired `.claude/aitk.json` instead, reported rather than migrated.
|
|
128
|
+
That attribution comes from `.claude/aitk/config.json`, a stamp every install and sync writes. A target stamped before that path shipped is read from the retired `.claude/aitk.json` instead, reported rather than migrated. Governance records a hash per installed file, plus the stack `aitk gov install` was given, and tooling records the stack chain it resolved instead of any file hash, since its install runs no per-file walk to attribute.
|
|
131
129
|
|
|
132
|
-
Each domain holds its own toolkit commit, so syncing governance today does not move the revision
|
|
130
|
+
Each domain holds its own toolkit commit, so syncing governance today does not move the revision tooling measures against, and each domain reports the upstream commits touching its own source path. Running any sync stamps that domain, and the report names the ones still unstamped.
|
|
133
131
|
|
|
134
132
|
A project that has never synced under a toolkit new enough to write a stamp falls back to the toolkit's own git history. Installed content matching any version that history published proves the file untouched, so it reports `stale` naming the commit it came from, and content matching no published version stays `drifted`. That fallback needs the toolkit as a git checkout. Installed from the registry it ships source without history, and the report says attribution was unavailable rather than reading every file as a local edit.
|
|
135
133
|
|
|
136
|
-
Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and reconciled with `aitk:claude-seed-sync`, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.claude/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated
|
|
134
|
+
Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and reconciled with `aitk:claude-seed-sync`, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.claude/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself.
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
`unmigrated` currently names no domain, since standards and snippets are the two the toolkit ever installed at the project root and both closed their install channel. A target still holding a root `standards/` or `snippets/` folder from an older toolkit is carrying its own authoring surface now, not an unfinished install, and nothing proposes moving either.
|
|
139
137
|
|
|
140
138
|
#### Rules you never received
|
|
141
139
|
|
|
@@ -202,7 +200,7 @@ cd <your-project>
|
|
|
202
200
|
claude
|
|
203
201
|
```
|
|
204
202
|
|
|
205
|
-
In the session, invoke `aitk:setup-init`. The skill detects no framework and resolves tooling to `base
|
|
203
|
+
In the session, invoke `aitk:setup-init`. The skill detects no framework and resolves tooling to `base` and governance to `base`. The preview marks both stacks as fallbacks, since neither came from a match, then the chain runs `aitk init`.
|
|
206
204
|
|
|
207
205
|
Ongoing: run `aitk sync --check .` to see what has drifted, then invoke `aitk:claude-seed-sync` for seed drift or `aitk sync .` for a catch-all refresh.
|
|
208
206
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: State the hook stdin guard and the silencing rule for .claude/hooks scripts and their seeded copies
|
|
3
|
+
paths:
|
|
4
|
+
- '.claude/hooks/**/*.sh'
|
|
5
|
+
- 'tooling/claude/seeds/.claude/hooks/**/*.sh'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Hook standards
|
|
9
|
+
|
|
10
|
+
## Reading a payload
|
|
11
|
+
|
|
12
|
+
- Open a hook that reads a payload with a bounded `IFS= read -r -d '' -t 2 input`, exiting non-zero on an empty payload. An unbounded `cat` blocks forever against a hand run or an open socket, holding the session open with it. A test already checks this per file across both hook trees, but the rule stops the pattern being rediscovered rather than caught only after the fact.
|
|
13
|
+
|
|
14
|
+
## Silencing output
|
|
15
|
+
|
|
16
|
+
- Before silencing a hook's output, name the stage that catches the same failure. A hook that is the only enforcer of a rule makes its documented guarantee false when it discards that output.
|
|
17
|
+
- Where no other stage catches the failure, capture the output into a variable, exit 0 on success, and emit the error lines as `additionalContext`.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
extends = ""
|
|
2
|
-
#
|
|
3
|
-
# so adding one is a single edit rather than a file and a name here.
|
|
4
|
-
|
|
2
|
+
# All three folders whole. Every rule authored under them ships to a base
|
|
3
|
+
# consumer, so adding one is a single edit rather than a file and a name here.
|
|
4
|
+
# `snippets` carries the `@`-reference convention rule, which lost its only
|
|
5
|
+
# other delivery path when `aitk snippets install` retired.
|
|
6
|
+
rules = ["core", "claude", "snippets", "120-bash"]
|
package/package.json
CHANGED
|
@@ -67,7 +67,7 @@ mkdir -p "$TARGET_DIR"
|
|
|
67
67
|
log_info "Initialized git in $TARGET_DIR"
|
|
68
68
|
|
|
69
69
|
log_step "Run aitk init"
|
|
70
|
-
(cd "$TARGET_DIR" && AITK_NON_INTERACTIVE=1 bun run "$CLONE_DIR/src/cli.ts" init --stack base
|
|
70
|
+
(cd "$TARGET_DIR" && AITK_NON_INTERACTIVE=1 bun run "$CLONE_DIR/src/cli.ts" init --stack base 2>&1 | pipe_output) || log_error "aitk init failed"
|
|
71
71
|
log_info "aitk init completed"
|
|
72
72
|
|
|
73
73
|
log_step "Assert scaffold"
|
|
@@ -76,18 +76,16 @@ log_step "Assert scaffold"
|
|
|
76
76
|
# catches a failed domain, and the gate stays green while the target is
|
|
77
77
|
# missing everything that domain provides.
|
|
78
78
|
#
|
|
79
|
-
# Standards name no path because
|
|
80
|
-
# reads a standard through `aitk standards <name
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
# alongside it, since a target that declined snippets never receives it.
|
|
88
|
-
for path in "CLAUDE.md" ".claude/snippets/decision-help.md" ".claude/rules/snippets/505-at-references.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
|
|
79
|
+
# Standards and snippets name no path because neither corpus installs into a
|
|
80
|
+
# target. A scaffold reads a standard through `aitk standards <name>` and a
|
|
81
|
+
# snippet through the plugin's live `claude/snippets` symlink, both resolving
|
|
82
|
+
# against the toolkit rather than a copy this gate could assert on. The
|
|
83
|
+
# `@`-reference convention rule is the one snippets-domain file that still
|
|
84
|
+
# installs, since `base` carries `governance/rules/snippets/` as a
|
|
85
|
+
# folder-whole entry the same way it does `core` and `claude`.
|
|
86
|
+
for path in "CLAUDE.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
|
|
89
87
|
".prettierrc" ".editorconfig" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.sh" \
|
|
90
|
-
".claude/rules/core/000-constitution.md"; do
|
|
88
|
+
".claude/rules/core/000-constitution.md" ".claude/rules/snippets/505-at-references.md"; do
|
|
91
89
|
if [ ! -e "$TARGET_DIR/$path" ]; then
|
|
92
90
|
log_error "Missing after aitk init: $path"
|
|
93
91
|
fi
|
package/scripts/core/verify.sh
CHANGED
|
@@ -21,13 +21,15 @@ SANDBOX_UNDECLARED_CEILING=47
|
|
|
21
21
|
|
|
22
22
|
# Rules no stack reaches, space separated and sorted the way `aitk gov list`
|
|
23
23
|
# emits them. `260-shadcn` and `320-tanstack-query` are opt-in libraries a
|
|
24
|
-
# project may not want
|
|
25
|
-
# since a rule under `claude/` would reach every
|
|
26
|
-
# folder-whole entry
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
|
|
24
|
+
# project may not want. `505-at-references` used to sit here too, shipping
|
|
25
|
+
# with no stack on purpose since a rule under `claude/` would reach every
|
|
26
|
+
# base consumer through the folder-whole entry there. Its own install
|
|
27
|
+
# channel, `aitk snippets install`, retired with nothing left to deliver it,
|
|
28
|
+
# so `base` now carries `snippets` as a folder-whole entry of its own and the
|
|
29
|
+
# rule reaches every base consumer through that instead. Both are recorded
|
|
30
|
+
# here rather than in a config file: the list is what a reader compares a
|
|
31
|
+
# new arrival against, and a config file would absorb the arrival silently.
|
|
32
|
+
GOV_EXPECTED_UNREFERENCED="260-shadcn 320-tanstack-query"
|
|
31
33
|
|
|
32
34
|
# The retained counts the audit stage compares each run against. Spelled here
|
|
33
35
|
# rather than derived, because this script only ever names the file in a remedy
|