@erclx/aitk 1.7.1 → 2.1.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 +2 -2
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-autoship/SKILL.md +2 -2
- package/claude/skills/claude-docs/SKILL.md +11 -0
- package/claude/skills/claude-groundwork/SKILL.md +1 -1
- package/claude/skills/claude-seed-sync/REQUIREMENT.md +2 -2
- package/claude/skills/claude-seed-sync/SKILL.md +15 -18
- package/claude/skills/create-standard/REQUIREMENT.md +7 -10
- package/claude/skills/create-standard/SKILL.md +10 -11
- package/claude/skills/git-pr/references/labels.md +7 -1
- package/claude/skills/migration-standards/REQUIREMENT.md +10 -7
- package/claude/skills/migration-standards/SKILL.md +24 -22
- package/claude/skills/migration-superseded/REQUIREMENT.md +2 -2
- package/claude/skills/migration-superseded/SKILL.md +7 -9
- package/claude/skills/setup-gov/REQUIREMENT.md +2 -2
- package/claude/skills/toolkit-cli/SKILL.md +13 -14
- package/docs/agents/commands.md +1 -1
- package/docs/agents/install-and-sync.md +27 -41
- package/docs/agents/scripting.md +2 -9
- package/docs/target-projects.md +14 -15
- package/package.json +1 -1
- package/scripts/core/install-check.sh +5 -1
- package/scripts/lib/sandbox-git.sh +56 -4
- package/scripts/manage-sandbox.sh +4 -7
- package/scripts/standards/list.sh +6 -4
- package/src/cli.ts +1 -1
- package/src/commands/gov.ts +1 -7
- package/src/commands/init.ts +1 -4
- package/src/commands/standards.ts +9 -141
- package/src/commands/sync.ts +1 -2
- package/src/gov/install.ts +0 -9
- package/src/init/flags.ts +3 -10
- package/src/init/plan.ts +8 -26
- package/src/init/steps.ts +0 -24
- package/src/standards/read.ts +16 -14
- package/src/sync/check.ts +4 -7
- package/src/sync/layout.ts +8 -10
- package/src/sync/stamp.ts +18 -15
- package/src/sync/target.ts +1 -8
- package/standards/skill.md +6 -6
- package/standards/standard.md +1 -1
- package/tooling/claude/seeds/.claude/ARCHITECTURE.md +1 -1
- package/tooling/claude/seeds/.claude/DESIGN.md +1 -1
- package/tooling/claude/seeds/.claude/REQUIREMENTS.md +1 -1
- package/tooling/claude/seeds/CLAUDE.md +2 -2
- package/src/standards/adapter.ts +0 -51
- package/src/standards/closure.ts +0 -200
- package/src/standards/index-refresh.ts +0 -44
- package/src/standards/install.ts +0 -52
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ Each domain has a canonical source in this repo and a thin install or sync CLI o
|
|
|
67
67
|
|
|
68
68
|
- [Claude Code plugin](.claude/context/claude-plugin/index.md): skills for planning, review, docs sync, and the git ship chain
|
|
69
69
|
- [Governance rules](.claude/context/governance/index.md): Claude rules and stacks, installable per project
|
|
70
|
-
- [Standards](.claude/context/standards/index.md): shared authoring conventions,
|
|
70
|
+
- [Standards](.claude/context/standards/index.md): shared authoring conventions, read by name rather than installed
|
|
71
71
|
- [Snippets](.claude/context/snippets.md): reusable prompts for Claude and Gemini chat
|
|
72
72
|
- [Tooling stacks](.claude/context/tooling.md): golden configs, seeds, and references per framework
|
|
73
73
|
- [Design system](.claude/context/design.md): `DESIGN.md` token shape, extract skill and its two paths, render command
|
|
@@ -116,7 +116,7 @@ git init
|
|
|
116
116
|
aitk init
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
`aitk init` installs base tooling configs, Claude seeds, governance rules,
|
|
119
|
+
`aitk init` installs base tooling configs, Claude seeds, governance rules, and snippets 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. 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
|
|
|
@@ -75,11 +75,11 @@ The two causes want different responses. A plan that has yet to produce its outp
|
|
|
75
75
|
|
|
76
76
|
The skip needs both tests to pass: every changed file matches `*.md` or `*.txt`, and no changed file sits under a behavior path. On a pass, skip review entirely and continue to Step 7. Otherwise invoke `aitk:claude-review`.
|
|
77
77
|
|
|
78
|
-
Behavior paths carry two spellings, the one a surface authors at and the one it
|
|
78
|
+
Behavior paths carry two spellings, the one a surface authors at and the one it reaches a session at, so the rule reads the same in a toolkit and in a project that consumed one:
|
|
79
79
|
|
|
80
80
|
- `claude/skills/` and `.claude/skills/`
|
|
81
81
|
- `governance/rules/` and `.claude/rules/`
|
|
82
|
-
- `standards/` and `.claude/standards
|
|
82
|
+
- `standards/` and `.claude/standards/`, which is the authoring root and this repository's generated mirror rather than an install destination, since the corpus installs into no project
|
|
83
83
|
- `snippets/` and `.claude/snippets/`
|
|
84
84
|
- `internal/` and `tooling/`, which hold the stack references and the seed documents a target is handed
|
|
85
85
|
- `CLAUDE.md` at the repository root, named as a file because a path prefix reaches nothing that sits in no folder
|
|
@@ -174,6 +174,17 @@ Reuse the diff from the baseline above, names and content both. For each existin
|
|
|
174
174
|
- For each relevant entry, rewrite only the sections affected by the diff. Same pattern as `docs-sync`. Do not touch unrelated sections.
|
|
175
175
|
- Write a reference to another entry as the path that entry sits at, rather than as its bare filename. `${CLAUDE_SKILL_DIR}/../../standards/context.md` states the form, and a bare name strands the reference once a domain splits into subfolders.
|
|
176
176
|
|
|
177
|
+
### When the diff removes a capability
|
|
178
|
+
|
|
179
|
+
The mapping above is scoped by file, and a removal invalidates claims that mapping cannot reach. Run this only when the diff deletes a command, a flag, a constant, or a folder. Ordinary feature work takes the narrow rule alone, since widening it on every ship churns prose nothing put in doubt.
|
|
180
|
+
|
|
181
|
+
Grep the tree for the name that went, rather than for the paths the diff carries. A capability removed by name is cited by that name, which reaches a file the diff never touched.
|
|
182
|
+
|
|
183
|
+
- An entry this run already rewrote is read whole before it is left. A refresh that updates the top and leaves a contradicting claim below reads worse than an untouched entry, because the current opening lends authority to the stale remainder. This is the one case that overrides "do not touch unrelated sections", and it overrides it only inside an entry the run edited anyway.
|
|
184
|
+
- A claim comparing two surfaces is checked even where its file is outside the diff. Such a claim holds only while both surfaces do, so moving one inverts it with nobody editing the file it sits in.
|
|
185
|
+
|
|
186
|
+
Report each hit as an ordinary rewrite.
|
|
187
|
+
|
|
177
188
|
Do not create new entries automatically. New entries are a deliberate decision: the user invokes `claude-docs --new-context <domain>` (future flag) or hand-creates the file following `${CLAUDE_SKILL_DIR}/../../standards/context.md`. Auto-creation risks padding `.claude/context/` with low-signal entries.
|
|
178
189
|
|
|
179
190
|
Write each updated entry immediately. Output one line per file:
|
|
@@ -35,7 +35,7 @@ A track may run an experiment to settle an open question without stopping to ask
|
|
|
35
35
|
- Writing a fixture this session reads or provisions itself: run it, under the fixtures path above. Provisioning is the usual blocker rather than spend, and it costs nothing.
|
|
36
36
|
- Spawning a billed headless session: run up to three, then ask before spawning more. The bound is a run count rather than a budget, because a headless run reports its total cost only after it finishes, so a dollar ceiling is reportable and not enforceable while a run count is checkable before spawning.
|
|
37
37
|
|
|
38
|
-
A fixture a headless run is pointed at goes outside the repository, under `mktemp -d`, and never under `.claude/.tmp/`. A session started anywhere beneath the project root loads that project's `CLAUDE.md
|
|
38
|
+
A fixture a headless run is pointed at goes outside the repository, under `mktemp -d`, and never under `.claude/.tmp/`. A session started anywhere beneath the project root loads that project's `CLAUDE.md` and `.claude/rules/` through the ancestor chain, so an in-repo fixture measures the repository instead of the arm. Record the fixture as contaminated and re-run it outside if this is discovered after the fact, because the result reads as evidence either way.
|
|
39
39
|
|
|
40
40
|
Record method, result, measured cost, and caveats in `08-spikes.md`. Put whatever the run produced that the record cites in `evidence/` beside it, so a reader checking a claim opens the artifact rather than taking the prose for it. Reach for a test harness the project already carries before building one, and copy how it isolates its fixture rather than only what it asserts.
|
|
41
41
|
|
|
@@ -7,7 +7,7 @@ description: Scope boundary for section-granular seed reconciliation against the
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a project that edited
|
|
10
|
+
Without this skill, a project that edited a seed has no way to take an upstream change without losing something. No `aitk` command touches a seed at all, so the only route is a hand copy that overwrites the file and takes the edits with it, unrecorded. Nothing can deliver one upstream section into a file the project has customized, which is the case a grown project is always in.
|
|
11
11
|
|
|
12
12
|
A whole-file diff does not close it either. It cannot separate a section the user rewrote on purpose from a section the toolkit moved on without them, so the choice reaches the user as accept everything or lose everything, and the safe answer is always to skip.
|
|
13
13
|
|
|
@@ -17,7 +17,7 @@ Two failures belong to the audit rather than to the diff. A decision taken in ch
|
|
|
17
17
|
|
|
18
18
|
## Must
|
|
19
19
|
|
|
20
|
-
- Read seed
|
|
20
|
+
- Read seed content from the CLI rather than holding a copy, so the audit and the install cannot disagree
|
|
21
21
|
- Diff per section, treating the preamble as a section of its own
|
|
22
22
|
- Separate a customized section from a stale one by reading the attribution the drift report records, not by how the section looks, and default the customized one to no action
|
|
23
23
|
- Fall back to appearance only when attribution is unavailable, and mark every verdict reached that way as unverified
|
|
@@ -14,27 +14,24 @@ Surfaces drift between the toolkit's current seed docs and what was installed in
|
|
|
14
14
|
|
|
15
15
|
## Step 1: read toolkit sources and the drift report
|
|
16
16
|
|
|
17
|
-
Run
|
|
17
|
+
Run both in parallel from the project root:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
aitk claude seeds list --json 2>/dev/null
|
|
21
|
-
aitk standards list --json 2>/dev/null
|
|
22
21
|
aitk sync --check . --json 2>/dev/null
|
|
23
22
|
```
|
|
24
23
|
|
|
25
|
-
Seeds emit an array of `{name, source, target, content}
|
|
24
|
+
Seeds emit an array of `{name, source, target, content}`, where `target` is the path relative to the project root where the file installs.
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
Seeds are the whole subject. No standard installs into a project, so there is no installed copy to audit and nothing to reconcile against the corpus. A standard a session needs is read with `aitk standards <name>`, which resolves against the copy inside the package.
|
|
28
27
|
|
|
29
28
|
### Narrow the set by attribution
|
|
30
29
|
|
|
31
|
-
The report is what separates a file the project edited from one the toolkit moved on without it. Read `seeds.entries` for seed paths
|
|
30
|
+
The report is what separates a file the project edited from one the toolkit moved on without it. Read `seeds.entries` for seed paths.
|
|
32
31
|
|
|
33
32
|
Keep every seed regardless of state. `CLAUDE.md` is the file a project edits most, and its `drifted` verdict is the case this skill exists for.
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Read the `toolkit-cli` skill before naming that command in the output. It states which surfaces a sync overwrites, merges, or writes once, and this skill hands the user a command against files its own attribution pass cleared as carrying no edits.
|
|
34
|
+
Read the `toolkit-cli` skill before naming a sync command in the output. It states which surfaces a sync overwrites, merges, or writes once.
|
|
38
35
|
|
|
39
36
|
Fall back to the appearance heuristic in step 3 when the report cannot attribute, which is `historyUnavailable` set on the relevant section or the command failing outright. Say so in the summary block, because a fallback audit reports guesses rather than facts.
|
|
40
37
|
|
|
@@ -53,7 +50,8 @@ Note on `settings.json`: the seed now ships only the PostToolUse hook block. If
|
|
|
53
50
|
For each seed file present in both sides, parse the body into a preamble (everything between H1 and the first H2) plus one part per `##` header, then compare part by part. Treat the preamble as a single unit with the same verdicts as a section. Use `(preamble)` as its label in the proposal.
|
|
54
51
|
|
|
55
52
|
- **Identical:** ignore.
|
|
56
|
-
- **Toolkit-only section** (present in source, absent in target): candidate to **Add**.
|
|
53
|
+
- **Toolkit-only section** (present in source, absent in target): candidate to **Add**. Number it whatever the file's own verdict is. The verdict rules below govern a section present in both, and a section the project never had cannot be the customization a `drifted` file is being credited with. A pass that reads the file-level verdict first proposes nothing on a target missing eleven sections, which is the shape this bullet exists to catch.
|
|
54
|
+
- A deliberate removal reads the same as one that never arrived, and no decline is carried between runs, so a section the user skips is proposed again on the next branch. Say so beside the item rather than letting a reader meet it a third time wondering. The way to settle it for good is to keep the heading and write the project's own content under it, which moves the section onto the drifted path below, where the customization rule protects it and stops numbering it.
|
|
57
55
|
- **Target-only section** (present in target, absent in source): preserve, never propose removal. These are user customizations.
|
|
58
56
|
- **Drifted section** (present in both, content differs): candidate to **Update**.
|
|
59
57
|
- Read the file's verdict from the report rather than judging it by eye. `drifted` means the content matches no version the toolkit ever published, so the project wrote it: call it **Customized**, default to skip, record in the scope table only, never numbered.
|
|
@@ -87,16 +85,15 @@ How to respond: fill in `Decision:` per item (`apply` or `skip`), then ping. Cha
|
|
|
87
85
|
|
|
88
86
|
## Scope
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
Mark target-only files (present in target, absent in source) as `local-only` and leave them untouched.
|
|
91
89
|
|
|
92
|
-
| Source
|
|
93
|
-
|
|
|
94
|
-
| seed
|
|
95
|
-
| seed
|
|
96
|
-
| seed
|
|
97
|
-
| seed
|
|
98
|
-
|
|
|
99
|
-
| standard | `<target>` | local-only | not in toolkit, preserved |
|
|
90
|
+
| Source | File | Status | Note |
|
|
91
|
+
| ------ | ---------- | ---------- | ---------------------------- |
|
|
92
|
+
| seed | `<target>` | diffed | <counts> |
|
|
93
|
+
| seed | `<target>` | in sync | |
|
|
94
|
+
| seed | `<target>` | skipped | non-text, compare manually |
|
|
95
|
+
| seed | `<target>` | customized | <section> skipped by default |
|
|
96
|
+
| seed | `<target>` | local-only | not in toolkit, preserved |
|
|
100
97
|
|
|
101
98
|
## 1. 📝 Update → `<target-path>` / <section>
|
|
102
99
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create-standard
|
|
3
|
-
description: Why a standard needs its shape read from the meta-standard and
|
|
3
|
+
description: Why a standard needs its shape read from the meta-standard before anything is drafted, and why the follow-up depends on who owns the folder it landed in
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Create standard requirement
|
|
@@ -9,30 +9,27 @@ description: Why a standard needs its shape read from the meta-standard and its
|
|
|
9
9
|
|
|
10
10
|
Without this skill, a standard is written from memory of what other standards look like. It arrives without the scope section that says what the file does not govern, so the next author cannot tell whether a rule belongs to it or to a sibling, and two standards end up claiming the same subject with no way to settle which one wins.
|
|
11
11
|
|
|
12
|
-
The
|
|
12
|
+
The consumed copy is the second failure. This repository mirrors `standards/` into `.claude/standards/` and asserts the two match, so a toolkit standard written into the mirror fails that assertion while looking like a correct file. One write surface removes the choice: `standards/` is what the resolver reads first and what every author writes to, in the toolkit and in a project alike.
|
|
13
13
|
|
|
14
|
-
A standard written
|
|
14
|
+
A standard written and left there is the third. The index entry and the context table are both generated or maintained downstream of the write, so a file that ships without them is catalogued nowhere and reached only by whoever already knew the path.
|
|
15
15
|
|
|
16
16
|
## Must
|
|
17
17
|
|
|
18
18
|
- Read the meta-standard before drafting, since the shape is what makes the file arguable against a sibling
|
|
19
|
-
-
|
|
19
|
+
- Write to `standards/`, creating it when absent, since it is the one root the resolver reads and the only surface either kind of author has
|
|
20
20
|
- Confirm the slug and the full body with the user before writing
|
|
21
21
|
- Emit the written path in full, so the terminal can resolve it
|
|
22
|
-
- State what the
|
|
22
|
+
- State what the write implies for whoever owns the folder, since a toolkit standard needs the consumed copy and the index regenerated and a project-local one needs copying to the toolkit to ship
|
|
23
23
|
|
|
24
24
|
## Must not
|
|
25
25
|
|
|
26
26
|
- Work the standard's shape or frontmatter from memory
|
|
27
27
|
- Write a snippet, which carries no frontmatter and answers to a different authoring contract
|
|
28
|
-
|
|
29
|
-
## Guards
|
|
30
|
-
|
|
31
|
-
- Neither standards folder exists: stop, since there is nowhere for the standard to live
|
|
28
|
+
- Write into `.claude/standards/`, which is this repository's generated mirror and reaches no resolver
|
|
32
29
|
|
|
33
30
|
## Out of scope
|
|
34
31
|
|
|
35
32
|
- Editing a standard that already exists
|
|
36
33
|
- A snippet, which `create-snippet` owns
|
|
37
34
|
- A path-scoped coding rule, which `create-rule` owns
|
|
38
|
-
-
|
|
35
|
+
- Reading a standard the toolkit ships, which `aitk standards <name>` owns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create-standard
|
|
3
|
-
description: Creates a new standard file in `standards
|
|
3
|
+
description: Creates a new standard file in `standards/`. Use when asked to create a standard, add a standard, or write a new authoring convention. Do NOT use to edit an existing standard.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Create standard
|
|
@@ -11,20 +11,19 @@ Creates one standard file. Read these files in parallel:
|
|
|
11
11
|
- The `write-human` skill: voice, rhythm, and sentence construction for all generated text
|
|
12
12
|
- `${CLAUDE_SKILL_DIR}/../../standards/standard.md`: the meta-standard for shape, frontmatter, and structure
|
|
13
13
|
|
|
14
|
-
## Guards
|
|
15
|
-
|
|
16
|
-
- If neither `standards/` nor `.claude/standards/` exists, stop: `❌ No standards/ or .claude/standards/ directory found.`
|
|
17
|
-
|
|
18
14
|
## Steps
|
|
19
15
|
|
|
20
|
-
1.
|
|
21
|
-
2.
|
|
22
|
-
3.
|
|
23
|
-
|
|
16
|
+
1. Draft the content from the user's description. The meta-standard governs frontmatter, headings, and structure.
|
|
17
|
+
2. Confirm the slug and full content with the user before writing
|
|
18
|
+
3. Write the file to `standards/<slug>.md`, creating the folder when it is absent
|
|
19
|
+
|
|
20
|
+
`standards/` is the one write surface. It is the toolkit's authoring source in this repository and a project's own folder anywhere else, and both are the root `aitk standards <name>` resolves against first. No corpus installs into a project, so there is no second surface to pick between and no guard on a folder the skill can create itself.
|
|
24
21
|
|
|
25
22
|
## After writing
|
|
26
23
|
|
|
27
24
|
Emit the full path on its own line.
|
|
28
25
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
26
|
+
- In the toolkit: this is the authoring source. Remind the user to run `bun run check` to regenerate the consumed copy under `.claude/`. That pass also regenerates the `standards/index.md` entry, and the user adds a row to the standards table in `.claude/context/standards/overview.md`.
|
|
27
|
+
- In a project: the file is project-local and no toolkit command touches it. Remind the user to copy it to the toolkit repo, under `standards/<slug>.md`, if it should ship to every project.
|
|
28
|
+
|
|
29
|
+
Separate the two by whether the folder already held toolkit-authored standards before this write, since a project authoring its own uses the same path.
|
|
@@ -27,7 +27,13 @@ web = ["apps/web/", "packages/ui/"]
|
|
|
27
27
|
|
|
28
28
|
A label takes more than one prefix when two folders read as one surface. Two labels may claim overlapping prefixes, and a path under both earns both.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Matching is prefix-anchored, so a row written for an authoring root reaches nothing under the copy a project consumes. A surface living only under a dotted folder carries its own prefix on the row that owns its subject, and a folder holding several subjects rather than one splits across the rows that own them.
|
|
31
|
+
|
|
32
|
+
The map is authored by hand and nothing detects a directory it fails to cover, so a surface added after the map was written labels nothing until someone adds a row. A map that has been censused against its own history says in its comment where that check is owned, so a reader meeting the gap is sent somewhere rather than left with the prediction.
|
|
33
|
+
|
|
34
|
+
## Paths a map declines to label
|
|
35
|
+
|
|
36
|
+
A path that moves only when a release or a generator rewrites it earns no row. Release automation applies its own label, and a domain label on a generated file gives a mechanical edit a subject it does not have. Neither is covered, so both are recorded in the map's comment with the reason, which is what separates a path nobody has gotten to from one somebody decided against.
|
|
31
37
|
|
|
32
38
|
## Matching
|
|
33
39
|
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: migration-standards
|
|
3
|
-
description: Why the root-to-.claude relocation ships as git mv commands the user runs,
|
|
3
|
+
description: Why the root-to-.claude snippets relocation ships as git mv commands the user runs, which inbound references are worth fixing, and why standards no longer travel with it
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Migration standards requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a project whose rules cite `.claude/
|
|
10
|
+
Without this skill, a project whose rules cite `.claude/snippets/` while the files sit at the root gets fixed by hand, and the hand fix loses what version control was holding. A plain `mv` breaks the rename chain, so every relocated snippet reads as a delete beside an unrelated add and its history stops at the move.
|
|
11
11
|
|
|
12
|
-
A fourth failure comes before those three, from deciding what is unmigrated by listing the folder. A root `
|
|
12
|
+
A fourth failure comes before those three, from deciding what is unmigrated by listing the folder. A root `snippets/` can hold the project's own prompts and nothing the toolkit ever installed, and a listing cannot tell the two apart, so the skill proposes moving project files under `.claude/` where a sync walks them. The drift report already answers this, counting only files whose basename the toolkit ships, and it is the same report `toolkit-operator` reads to route here.
|
|
13
|
+
|
|
14
|
+
Standards left this skill when the corpus stopped installing into a project. The report no longer names the domain, so a body still describing the move would propose relocating a folder the project authored, which is the exact failure the paragraph above records in the other direction.
|
|
13
15
|
|
|
14
16
|
Taking detection from a command opens a failure the listing never had. A CLI predating the field exits zero with a well-formed report that never mentions it, so a skill treating an absent key as an empty answer tells a project whose every domain sits at the root that it has nothing to relocate. That is the population this skill exists for, and a silent false negative there costs more than the unfiltered count reading the folder would have produced.
|
|
15
17
|
|
|
16
18
|
The re-sync the skill names has the same gap in the other direction. The relocation is what makes those commands land on a path that held nothing before, so the run hands over a command whose overwrite behavior it never states, and the reference holding that answer is named in the boundary below where no session reads it. Claude Code loads the skill entry alone.
|
|
17
19
|
|
|
18
|
-
Three failures follow from acting without looking first. A move onto an existing `.claude/
|
|
20
|
+
Three failures follow from acting without looking first. A move onto an existing `.claude/snippets/` copy overwrites the files already installed there, which is the case the relocation was supposed to be unnecessary for. A `git mv` on a dirty tree lands the relocation in the same commit as unrelated work, so neither can be reviewed or reverted alone. And a session that rewrites every inbound reference spends its effort on toolkit-owned rules and skills, which the next sync overwrites, while the author-owned lines that actually break go unmentioned.
|
|
19
21
|
|
|
20
22
|
## Must
|
|
21
23
|
|
|
22
|
-
- Take
|
|
24
|
+
- Take what to relocate from `aitk sync --check --json`, and report its filtered count rather than a folder listing
|
|
25
|
+
- Say in one line that a root `standards/` folder is left alone, since a user who came here expecting both domains reads silence as an oversight
|
|
23
26
|
- Keep the listing as the fallback for a target where `aitk` is absent, the command fails, or the report carries no `unmigrated` key, and say that its counts are unfiltered
|
|
24
|
-
- Detect an existing copy under `.claude/` and skip
|
|
27
|
+
- Detect an existing copy under `.claude/` and skip the move rather than merging into it
|
|
25
28
|
- Read the working tree state and require it clean before the moves, since the relocation has to be revertible on its own
|
|
26
29
|
- Propose `git mv` so history follows each file
|
|
27
30
|
- Report author-owned inbound references as TODO lines the user fixes, and leave the reference itself untouched
|
|
@@ -36,7 +39,7 @@ Three failures follow from acting without looking first. A move onto an existing
|
|
|
36
39
|
|
|
37
40
|
## Guards
|
|
38
41
|
|
|
39
|
-
-
|
|
42
|
+
- No root `snippets/` present stops, since there is nothing to relocate
|
|
40
43
|
- A directory that is not a git work tree stops, since `git mv` needs version control and a plain move is the failure the skill exists to prevent
|
|
41
44
|
|
|
42
45
|
## Out of scope
|
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: migration-standards
|
|
3
|
-
description: Proposes `git mv` commands to relocate a target project's root `
|
|
3
|
+
description: Proposes `git mv` commands to relocate a target project's root `snippets/` folder into `.claude/snippets/`, the install layout newer toolkit versions expect. Use when asked to "relocate snippets", "move snippets to .claude", "migrate snippets to .claude", or after a toolkit upgrade leaves a rule pointing at `.claude/snippets/` while the files sit at the root. Do NOT auto-execute moves or edit rule files. Proposal only.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Claude standards relocate
|
|
7
7
|
|
|
8
|
+
Snippets is the one domain this skill relocates. Standards used to travel beside it and the toolkit corpus now installs into no project at all, so a root `standards/` folder in a target holds work the project authored and nothing proposes moving it. `aitk standards <name>` reads a toolkit standard wherever a session needs one.
|
|
9
|
+
|
|
8
10
|
## Guards
|
|
9
11
|
|
|
10
|
-
- If
|
|
12
|
+
- If `snippets/` does not exist at `pwd`, stop: `❌ No root snippets/ to relocate.`
|
|
11
13
|
- If `pwd` is not a git work tree, stop: `❌ Not a git repository. git mv needs version control.`
|
|
12
14
|
|
|
13
15
|
## Step 1: read the report
|
|
14
16
|
|
|
15
17
|
Run `aitk sync --check . --json` from the project root. Its `unmigrated` array is the detection. Each entry carries `domain`, `rootPath`, `installPath`, and `files`, and a domain appears only when the root folder holds a file the toolkit ships and nothing sits at the install path. Report `files` as the count, since it excludes files the project wrote into the same folder.
|
|
16
18
|
|
|
17
|
-
Run these beside it, in parallel. The report answers
|
|
19
|
+
Run these beside it, in parallel. The report answers whether to move and neither of these is derivable from it:
|
|
18
20
|
|
|
19
|
-
- `ls .claude/
|
|
20
|
-
- `ls .claude/snippets/ 2>/dev/null`: the same, for the other domain
|
|
21
|
+
- `ls .claude/snippets/ 2>/dev/null`: separate a domain already relocated from one never installed, which the report cannot, since both are absent from `unmigrated`
|
|
21
22
|
- `git status --short 2>/dev/null`: confirm a clean tree before proposing moves
|
|
22
23
|
|
|
23
|
-
Keep the two listings as separate commands. `ls` labels its output with a `dir:` header only when more than one operand succeeds, so a combined call with one directory present prints that directory's filenames bare while the redirect swallows the other's failure, and the result reads as whichever directory was expected.
|
|
24
|
-
|
|
25
24
|
### When the report is unavailable
|
|
26
25
|
|
|
27
|
-
Fall back to `ls
|
|
26
|
+
Fall back to `ls snippets/` on any of three conditions. Say in the output that the count is unfiltered, because a root folder can hold project-authored files the report would have excluded and the fallback counts every one of them.
|
|
28
27
|
|
|
29
28
|
- `aitk` is not on `PATH`
|
|
30
29
|
- The command exits non-zero
|
|
@@ -38,19 +37,20 @@ Do not fall back on `historyUnavailable`. That field reports failed attribution
|
|
|
38
37
|
|
|
39
38
|
## Step 2: check conflicts
|
|
40
39
|
|
|
41
|
-
- If `.claude/
|
|
42
|
-
- If `.claude/snippets/` already holds `.md` files, mark snippets as "already relocated" and skip its move.
|
|
40
|
+
- If `.claude/snippets/` already holds `.md` files, mark snippets as "already relocated" and skip the move.
|
|
43
41
|
- If `git status` is not clean, add a TODO line telling the user to commit or stash first. `git mv` on a dirty tree mixes the move with unrelated changes.
|
|
44
|
-
- If
|
|
42
|
+
- If the root folder holds files and no domain names it in a report that carried the key, propose nothing. The content is the project's own, and moving it under `.claude/` puts project files where a sync walks. This reads a present key alone. A report with no `unmigrated` key never reaches here, since Step 1 sends it to the fallback.
|
|
43
|
+
- A root `standards/` folder is never a conflict and never a move. Say so in one line when one is present, since a user who came here expecting both domains reads silence as an oversight.
|
|
45
44
|
|
|
46
45
|
## Step 3: find author-owned inbound references
|
|
47
46
|
|
|
48
47
|
Toolkit-owned rules and skills are re-synced, so do not rewrite them. Surface only references the user authored:
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
```bash
|
|
50
|
+
git grep -n "snippets/" -- 'CLAUDE.md' '.claude/rules/**' 'docs/**' 2>/dev/null
|
|
51
|
+
```
|
|
52
52
|
|
|
53
|
-
Report each hit as a TODO line. Exclude paths already under `.claude/
|
|
53
|
+
Report each hit as a TODO line. Exclude paths already under `.claude/snippets/`.
|
|
54
54
|
|
|
55
55
|
## Step 4: output
|
|
56
56
|
|
|
@@ -59,38 +59,40 @@ Print one grouped proposal block. Omit empty groups.
|
|
|
59
59
|
```markdown
|
|
60
60
|
## Relocate
|
|
61
61
|
|
|
62
|
-
- standards/ → .claude/standards/ (<count> files)
|
|
63
62
|
- snippets/ → .claude/snippets/ (<count> files)
|
|
64
63
|
|
|
65
64
|
## Already relocated
|
|
66
65
|
|
|
67
|
-
- .claude/
|
|
66
|
+
- .claude/snippets/ exists. Skipping.
|
|
67
|
+
|
|
68
|
+
## Left alone
|
|
69
|
+
|
|
70
|
+
- standards/ is the project's own. No toolkit standard installs into a project.
|
|
68
71
|
|
|
69
72
|
## Suggested git mv commands
|
|
70
73
|
|
|
71
74
|
mkdir -p .claude
|
|
72
|
-
git mv standards .claude/standards
|
|
73
75
|
git mv snippets .claude/snippets
|
|
74
76
|
|
|
75
77
|
## Re-sync after moving
|
|
76
78
|
|
|
77
|
-
aitk
|
|
79
|
+
aitk snippets sync .
|
|
78
80
|
aitk gov sync .
|
|
79
81
|
|
|
80
82
|
## Inbound references to verify
|
|
81
83
|
|
|
82
|
-
- CLAUDE.md:42 references
|
|
84
|
+
- CLAUDE.md:42 references snippets/align.md
|
|
83
85
|
- docs/contributing.md:8 references snippets/claude/feature
|
|
84
86
|
|
|
85
87
|
## Reminder
|
|
86
88
|
|
|
87
|
-
Re-syncing reinstalls toolkit-owned rules and
|
|
89
|
+
Re-syncing reinstalls toolkit-owned rules and snippets at the new path. Author-owned references above need a manual one-line fix.
|
|
88
90
|
```
|
|
89
91
|
|
|
90
92
|
Two states produce no proposal at all, and each gets its own line rather than an empty block:
|
|
91
93
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
+
- The folder already lives under `.claude/`: `✅ snippets/ already lives under .claude/. Nothing to relocate.`
|
|
95
|
+
- The root folder exists and no domain names it in `unmigrated`: `✅ snippets/ holds no file the toolkit installed. Nothing to relocate.` The guard passed because the folder is there, so a session that printed nothing would leave the user reading silence as a failed run rather than as the answer.
|
|
94
96
|
|
|
95
97
|
Read the `toolkit-cli` skill before printing the re-sync block, and name in the reminder any surface it lists as overwritten. The user runs those commands against a tree the moves above relocated, and that relocation is what puts an overwrite onto files never installed at the new path.
|
|
96
98
|
|
|
@@ -19,7 +19,7 @@ The last is the two-speed release skew arriving as a confident wrong answer. `su
|
|
|
19
19
|
|
|
20
20
|
- Take detection from the report's `superseded` array alone, and stop when the key is absent rather than treating it as empty
|
|
21
21
|
- Resolve the governing standard by matching the replacement folder against the `appliesTo` the standards catalog declares, so a seed folder added later resolves without an edit to the body
|
|
22
|
-
- Read the destination shape
|
|
22
|
+
- Read the destination shape with `aitk standards <name>`, report the root it answered from, and propose nothing for a folder the catalog names no standard for
|
|
23
23
|
- Separate a folder no standard governs from one whose governing standard could not be read, since the catalog derives `appliesTo` from prose and answers an unparsed scope statement with an empty array
|
|
24
24
|
- Name the untrack command ahead of the ignore entry whenever a retired file is both tracked and ignored, and say when the check could not run
|
|
25
25
|
- Report what the destination standard leaves open, such as a phase label the retired file never recorded, rather than supplying a value for it
|
|
@@ -38,7 +38,7 @@ 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 `
|
|
41
|
+
- Relocating root `snippets/` into `.claude/`: `migration-standards`
|
|
42
42
|
- Classifying `CLAUDE.md` sections into the three-tier model: `migration-claude-md`
|
|
43
43
|
- Relocating `docs/` files by audience: `migration-context`
|
|
44
44
|
- Reconciling a seed file against its source section by section, which diffs two files rather than splitting one into a folder: `claude-seed-sync`
|
|
@@ -37,13 +37,13 @@ Run `aitk standards list --json` and match each entry's `replacedBy` against the
|
|
|
37
37
|
|
|
38
38
|
Compare on the folder rather than on the exact string. An `appliesTo` value matches when it equals `replacedBy` or begins with `replacedBy` followed by a slash. The report spells the folder `.claude/tasks` and the catalog spells it `.claude/tasks/`, and `memory` declares a filename pattern beneath its folder rather than the folder itself, so string equality matches nothing the catalog actually carries and sends every entry to a decline below.
|
|
39
39
|
|
|
40
|
-
###
|
|
40
|
+
### Read the standard through the verb
|
|
41
41
|
|
|
42
|
-
A match resolves to that standard's `name`.
|
|
42
|
+
A match resolves to that standard's `name`. Read it with `aitk standards <name>`, which writes the document to stdout and the root it answered from to stderr.
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
The verb is the one route. It resolves `standards/<name>.md` at the project root first, which is where a project that authors standards of its own keeps them, and falls back to the corpus inside the aitk package. No toolkit standard installs into a project, so there is no third path to test and no case where the shape is unreachable while the catalog names it.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Report the root the frame named beside the proposal. A shape read from the project's own `standards/` is the project's stated agreement, and one read from the package is the toolkit's default, which is a difference the user weighs rather than a reason to refuse.
|
|
47
47
|
|
|
48
48
|
### The states that end an entry
|
|
49
49
|
|
|
@@ -51,10 +51,8 @@ Four states end an entry with no proposal. Name whichever one fired rather than
|
|
|
51
51
|
|
|
52
52
|
- The catalog carries no `appliesTo` key: `⚠️ This aitk emits no appliesTo, so which standard governs <replacedBy> is unread.`
|
|
53
53
|
- No value covers `replacedBy` and some entry carries an empty `appliesTo`: an empty array is a scope statement that did not parse, so a no-match verdict is unread rather than negative. Name the standards that did not parse.
|
|
54
|
-
- No value covers `replacedBy` and every array is populated: `⚠️ The toolkit ships no standard for <replacedBy>. Nothing states the destination shape.`
|
|
55
|
-
- The standard resolved and
|
|
56
|
-
|
|
57
|
-
Do not read the toolkit's own copy through `${CLAUDE_SKILL_DIR}` when the target lacks the file. Sibling skills cite that fallback for a standard they follow themselves, and this one is different: the standard here is the project's agreement about the shape of its own folder. A proposal drawn from the plugin copy hands back a shape the project never adopted, against content only the user can place.
|
|
54
|
+
- No value covers `replacedBy` and every array is populated: `⚠️ The toolkit ships no standard for <replacedBy>. Nothing states the destination shape.` No command fixes it, so name none.
|
|
55
|
+
- The standard resolved in the catalog and `aitk standards <name>` exits non-zero: name the standard and the exit, since the catalog and the read disagree and only one of them can be right.
|
|
58
56
|
|
|
59
57
|
## Step 3: read the shape and map the file onto it
|
|
60
58
|
|
|
@@ -90,7 +88,7 @@ Print one block per superseded entry, then the shared reminder. Omit empty group
|
|
|
90
88
|
```markdown
|
|
91
89
|
## Split
|
|
92
90
|
|
|
93
|
-
`.claude/TASKS.md` → `.claude/tasks/`, shaped by
|
|
91
|
+
`.claude/TASKS.md` → `.claude/tasks/`, shaped by `aitk standards tasks`
|
|
94
92
|
|
|
95
93
|
## Proposed files
|
|
96
94
|
|
|
@@ -32,6 +32,6 @@ The last failure sits at a boundary rather than inside a run. `setup-init` turns
|
|
|
32
32
|
|
|
33
33
|
## Out of scope
|
|
34
34
|
|
|
35
|
-
- The rest of the onboarding chain. This skill installs governance and nothing else, and `setup-init` is the one-shot path that installs governance beside tooling,
|
|
36
|
-
- Scaffolding the rule file an unmatched technology needs. `create-rule` writes one into a target project, and a rule the toolkit should ship is authored under `governance/rules/` against
|
|
35
|
+
- The rest of the onboarding chain. This skill installs governance and nothing else, and `setup-init` is the one-shot path that installs governance beside tooling, snippets, and the seeds.
|
|
36
|
+
- Scaffolding the rule file an unmatched technology needs. `create-rule` writes one into a target project, and a rule the toolkit should ship is authored under `governance/rules/` against `aitk standards rule`.
|
|
37
37
|
- Updating rules a project already has, which `aitk gov sync` owns
|
|
@@ -9,18 +9,17 @@ What each `aitk` sync or install command does to existing files in a target proj
|
|
|
9
9
|
|
|
10
10
|
## Overwrite contract
|
|
11
11
|
|
|
12
|
-
| Surface | Command
|
|
13
|
-
| -------------------------------------------------------- |
|
|
14
|
-
| Golden configs, listed in full below | `aitk tooling sync`
|
|
15
|
-
| Dictionary seeds (`.cspell/*.txt`) | `aitk tooling sync`
|
|
16
|
-
| Other seeds (`cspell.json`, `.lintstagedrc`, state docs) | `aitk tooling sync`
|
|
17
|
-
| Standards | `aitk standards
|
|
18
|
-
|
|
|
19
|
-
| Seed docs
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
| Generated `index.md` | any sync or regen | Rewritten from target state. Hand edits are lost. |
|
|
12
|
+
| Surface | Command | Effect on existing files |
|
|
13
|
+
| -------------------------------------------------------- | ------------------- | ----------------------------------------------------------------- |
|
|
14
|
+
| Golden configs, listed in full below | `aitk tooling sync` | Overwritten once `--write` is passed. Local edits are lost. |
|
|
15
|
+
| Dictionary seeds (`.cspell/*.txt`) | `aitk tooling sync` | Merged and sorted. Existing terms preserved. |
|
|
16
|
+
| Other seeds (`cspell.json`, `.lintstagedrc`, state docs) | `aitk tooling sync` | Copy-once. Dropped on first install, untouched after. |
|
|
17
|
+
| Standards | none | Nothing installs. `aitk standards <name>` reads and never writes. |
|
|
18
|
+
| Seed docs and `CLAUDE.md` | `aitk claude init` | Skipped when present. Never overwritten. |
|
|
19
|
+
| Seed docs | `aitk claude sync` | Never touched. Only `.gitignore` is written. |
|
|
20
|
+
| References (`.claude/tooling/<stack>.md`) | `aitk tooling ref` | Overwritten. |
|
|
21
|
+
| `.gitignore`, deps, scripts | any sync | Additive. Existing entries preserved. Deps re-pin on major skew. |
|
|
22
|
+
| Generated `index.md` | any sync or regen | Rewritten from target state. Hand edits are lost. |
|
|
24
23
|
|
|
25
24
|
## What a tooling sync can overwrite
|
|
26
25
|
|
|
@@ -94,8 +93,8 @@ Run `aitk tooling sync <stack> <target> --check` for the list resolved against a
|
|
|
94
93
|
- Run `--check` first when the project carries local edits to any path above. The report names each file it would replace, which is the warning the user needs before the write.
|
|
95
94
|
- An interactive run still prompts. `--write` skips the prompt, and `--check` refuses to write even with a TTY.
|
|
96
95
|
- Seeds are user-owned. Dictionary `.txt` files merge and sort. Other seeds are copy-once, so re-seeding a structured file means deleting it and syncing again.
|
|
97
|
-
-
|
|
98
|
-
- For section-level customizations of a
|
|
96
|
+
- No command writes a standard into a project. A `.claude/standards/` folder from an older toolkit is inert, and deleting it costs nothing.
|
|
97
|
+
- For section-level customizations of a seed doc, use the `claude-seed-sync` skill, not `aitk ... sync`. It diffs per section and preserves edits.
|
|
99
98
|
|
|
100
99
|
## CLAUDE.md
|
|
101
100
|
|
package/docs/agents/commands.md
CHANGED
|
@@ -60,7 +60,7 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
|
|
|
60
60
|
| ----------- | ------------------------------------------------------------------------------------------- |
|
|
61
61
|
| `tooling` | `list`, `sync`, `ref`, `create`, `verify`, `inject`, `prune-gitignore` |
|
|
62
62
|
| `snippets` | `list`, `install`, `sync`, `create` |
|
|
63
|
-
| `standards` | `list`,
|
|
63
|
+
| `standards` | `list`, `<name>` |
|
|
64
64
|
| `gov` | `list`, `install`, `sync`, `build`, `regen`, `test-order` |
|
|
65
65
|
| `claude` | `init`, `sync`, `seeds list`, `skills list`, `skills audit`, `skills drift`, `setup [dest]` |
|
|
66
66
|
| `wiki` | `init` |
|