@erclx/aitk 0.46.1 → 0.47.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-tasks/SKILL.md +1 -1
- package/claude/skills/create-snippet/references/snippets.md +12 -1
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/docs/ai-workflow.md +1 -1
- package/package.json +1 -1
- package/scripts/core/install-check.sh +5 -1
- package/snippets/align.md +12 -0
- package/snippets/snippets.toml +8 -2
- package/standards/bundled/snippets.md +12 -1
- package/standards/tasks.md +6 -3
- package/tooling/claude/manifest.toml +1 -1
- package/tooling/claude/reference.md +1 -1
- package/snippets/create-snippet.md +0 -7
|
@@ -36,7 +36,7 @@ Do not derive the label from a version file. `.claude/standards/versioning.md` p
|
|
|
36
36
|
|
|
37
37
|
Write `.claude/tasks/vXX.Y-<slug>.md` following the format in `.claude/standards/tasks.md`. Include a link line only when the file or folder it names exists. A link to a plan nobody has written yet is the broken pointer the archive rules exist to prevent.
|
|
38
38
|
|
|
39
|
-
Write `Plan
|
|
39
|
+
Write `Plan:`, `Groundwork:`, and `Intake:` as markdown links relative to `.claude/tasks/`, as in `Plan: [feature-<slug>](../plans/feature-<slug>.md)`. Leave `Issue:` a bare `#NNN`. A task written in the older bare-path form still parses, so it costs the board a clickable line rather than an archive, but it leaves the board in two shapes for every reader after.
|
|
40
40
|
|
|
41
41
|
Never write a `Pull request:` line here. `git-pr` adds it when a pull request opens, and a number guessed at create time points at someone else's work.
|
|
42
42
|
|
|
@@ -8,7 +8,7 @@ consumers: create-snippet
|
|
|
8
8
|
|
|
9
9
|
## Scope
|
|
10
10
|
|
|
11
|
-
Governs a snippet file: what one is for, how it is invoked, and the structure of its body.
|
|
11
|
+
Governs a snippet file: what one is for, whether a prompt qualifies as one, how it is invoked, and the structure of its body.
|
|
12
12
|
|
|
13
13
|
Does not govern:
|
|
14
14
|
|
|
@@ -19,6 +19,17 @@ Does not govern:
|
|
|
19
19
|
|
|
20
20
|
A snippet is a short, focused prompt stored as a plain markdown file. Invoke one to insert a prepared instruction into any AI chat without retyping it. Each snippet covers one purpose. If a prompt needs headers or multiple goals, use a system prompt instead.
|
|
21
21
|
|
|
22
|
+
## Admission
|
|
23
|
+
|
|
24
|
+
Two tests decide whether a prompt becomes a snippet, and both have to pass. Apply them when adding one and when auditing the catalog.
|
|
25
|
+
|
|
26
|
+
- Cadence: a prompt invoked many times across sessions qualifies. A one-shot audit, migration, or bootstrap prompt does not, and belongs in notes outside the catalog.
|
|
27
|
+
- Audience: a prompt the consuming project would invoke ships in `snippets/`. One only the authoring repository can run stays outside every installable folder, which is a rule for a repository that authors snippets for others rather than for one that only consumes them.
|
|
28
|
+
|
|
29
|
+
A subfolder under `snippets/` names where a prompt is invoked rather than what it is about. A prompt that reads or writes the project's own files goes in a folder, and one carrying its whole context in the message goes at the root.
|
|
30
|
+
|
|
31
|
+
Overlapping a skill that does the same job is not disqualifying on its own. A snippet fires when a person asks for it by name and a skill fires on a description match, so the two coexist when those paths differ and the outputs do. Record the reason where the project keeps its decisions, or drop the snippet.
|
|
32
|
+
|
|
22
33
|
## Invocation channels
|
|
23
34
|
|
|
24
35
|
- Chrome extension: type `>slug` in a supported chat UI (claude.ai, gemini.google.com) to insert the snippet text inline
|
|
@@ -109,7 +109,7 @@ Write the `number` the final command printed onto the task the branch is closing
|
|
|
109
109
|
|
|
110
110
|
Find the task by reading `.claude/tasks/` at the main worktree root, resolved with `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. The board is shared scratch, so a linked worktree writing to its own `pwd` creates a second board nothing reads.
|
|
111
111
|
|
|
112
|
-
Confirm the match against the task's `Plan:` line, which names the plan this branch implemented. A branch name does not derive a plan slug and a plan slug does not derive a branch, so neither one alone identifies the task. Add `Pull request: #NNN` under the existing `Plan:`, `Groundwork:`, or `Issue:` lines when the task carries no such line, and correct the number in place when it does.
|
|
112
|
+
Confirm the match against the task's `Plan:` line, which names the plan this branch implemented. A branch name does not derive a plan slug and a plan slug does not derive a branch, so neither one alone identifies the task. Add `Pull request: #NNN` under the existing `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` lines when the task carries no such line, and correct the number in place when it does.
|
|
113
113
|
|
|
114
114
|
Skip this silently in three cases: no `.claude/tasks/` folder, no task whose `Plan:` line matches, or more than one match. One task, one pull request, so a second match is a misfile that a guessed write would compound. A wrong match archives the wrong task unattended once the branch merges.
|
|
115
115
|
|
package/docs/ai-workflow.md
CHANGED
|
@@ -88,7 +88,7 @@ The sweep reads the whole board rather than the tasks the session touched. It is
|
|
|
88
88
|
|
|
89
89
|
`aitk tasks validate` checks what those rows claim against what the tree holds: every plan pointer resolves, every row and task file map one to one, no task sits in two groups, and no two rows marked ready touch the same file. That last check is the half a reader cannot run by eye, and it is what keeps two workers from being handed colliding work. It reports and never writes, because a row is the orchestrator's claim and a validator repairing one would assert the claim it exists to test. Nothing fires it automatically, since the board is gitignored per-machine scratch with no shared moment to hang a hook on, so the orchestrator's sweep calls it at the point the readiness claim is made.
|
|
90
90
|
|
|
91
|
-
`aitk:claude-tasks` owns the two operations that bracket a task's life. It creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and it moves a shipped task to `.claude/.tmp/task-archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, or an issue, since a task with no origin is either lost context or work nobody decided to do. Archiving a task leaves its plan alone, because `aitk:claude-docs` owns the plans sweep and already holds the last-live-citation rule. That makes the order load-bearing, so the archive verb refuses to run while the `Plan:` line still points into `.claude/plans/`. The sweep only reaches tasks still in the live folder, and archiving the task first would strand the plan there with nothing citing it.
|
|
91
|
+
`aitk:claude-tasks` owns the two operations that bracket a task's life. It creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and it moves a shipped task to `.claude/.tmp/task-archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do. Archiving a task leaves its plan alone, because `aitk:claude-docs` owns the plans sweep and already holds the last-live-citation rule. That makes the order load-bearing, so the archive verb refuses to run while the `Plan:` line still points into `.claude/plans/`. The sweep only reaches tasks still in the live folder, and archiving the task first would strand the plan there with nothing citing it.
|
|
92
92
|
|
|
93
93
|
Nothing chained that archive until the `post-merge` git hook landed. Every earlier step fires from `aitk:claude-autoship` or `aitk:git-ship`, both of which finish while the pull request is still open, so a task archived there would close for work that may be abandoned. The board is gitignored, which rules out reading it from anywhere but the machine that pulled. The hook names the board's archive candidates and stays silent otherwise, including on a project with no board.
|
|
94
94
|
|
package/package.json
CHANGED
|
@@ -75,7 +75,11 @@ log_step "Assert scaffold"
|
|
|
75
75
|
# no assertion can truncate silently: init still exits 0 because run_domain
|
|
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
|
+
# The snippets path has to name a slug the default preset still carries, since
|
|
80
|
+
# init resolves snippets through `essentials`. Editing that preset without
|
|
81
|
+
# editing this line fails the gate on a correct install.
|
|
82
|
+
for path in "CLAUDE.md" ".claude/snippets/decision-help.md" ".claude/standards/prose.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
|
|
79
83
|
".prettierrc" ".editorconfig" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.sh" \
|
|
80
84
|
".claude/rules/core/000-constitution.md"; do
|
|
81
85
|
if [ ! -e "$TARGET_DIR/$path" ]; then
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Check alignment before acting, not after. State three lines, then proceed.
|
|
2
|
+
|
|
3
|
+
- Outcome: what will be true when this is done
|
|
4
|
+
- Scope: what this deliberately does not touch
|
|
5
|
+
- Assumption: the one inference that would change the work if it is wrong
|
|
6
|
+
|
|
7
|
+
Act without waiting, unless being wrong about the assumption wastes the work rather than costing an edit.
|
|
8
|
+
|
|
9
|
+
- Three lines, not three paragraphs
|
|
10
|
+
- Name the inference you are least sure of, not the safest one
|
|
11
|
+
- Do not ask what the request already answers
|
|
12
|
+
- Silence is agreement
|
package/snippets/snippets.toml
CHANGED
|
@@ -8,7 +8,7 @@ consumers: create-snippet
|
|
|
8
8
|
|
|
9
9
|
## Scope
|
|
10
10
|
|
|
11
|
-
Governs a snippet file: what one is for, how it is invoked, and the structure of its body.
|
|
11
|
+
Governs a snippet file: what one is for, whether a prompt qualifies as one, how it is invoked, and the structure of its body.
|
|
12
12
|
|
|
13
13
|
Does not govern:
|
|
14
14
|
|
|
@@ -19,6 +19,17 @@ Does not govern:
|
|
|
19
19
|
|
|
20
20
|
A snippet is a short, focused prompt stored as a plain markdown file. Invoke one to insert a prepared instruction into any AI chat without retyping it. Each snippet covers one purpose. If a prompt needs headers or multiple goals, use a system prompt instead.
|
|
21
21
|
|
|
22
|
+
## Admission
|
|
23
|
+
|
|
24
|
+
Two tests decide whether a prompt becomes a snippet, and both have to pass. Apply them when adding one and when auditing the catalog.
|
|
25
|
+
|
|
26
|
+
- Cadence: a prompt invoked many times across sessions qualifies. A one-shot audit, migration, or bootstrap prompt does not, and belongs in notes outside the catalog.
|
|
27
|
+
- Audience: a prompt the consuming project would invoke ships in `snippets/`. One only the authoring repository can run stays outside every installable folder, which is a rule for a repository that authors snippets for others rather than for one that only consumes them.
|
|
28
|
+
|
|
29
|
+
A subfolder under `snippets/` names where a prompt is invoked rather than what it is about. A prompt that reads or writes the project's own files goes in a folder, and one carrying its whole context in the message goes at the root.
|
|
30
|
+
|
|
31
|
+
Overlapping a skill that does the same job is not disqualifying on its own. A snippet fires when a person asks for it by name and a skill fires on a description match, so the two coexist when those paths differ and the outputs do. Record the reason where the project keeps its decisions, or drop the snippet.
|
|
32
|
+
|
|
22
33
|
## Invocation channels
|
|
23
34
|
|
|
24
35
|
- Chrome extension: type `>slug` in a supported chat UI (claude.ai, gemini.google.com) to insert the snippet text inline
|
package/standards/tasks.md
CHANGED
|
@@ -125,6 +125,7 @@ description: One line on what this task achieves
|
|
|
125
125
|
|
|
126
126
|
Plan: [feature-<slug>](../plans/feature-<slug>.md)
|
|
127
127
|
Groundwork: [<slug>](../.tmp/groundwork/<slug>/)
|
|
128
|
+
Intake: [<slug>](../intake/<slug>/)
|
|
128
129
|
Issue: #NNN
|
|
129
130
|
Pull request: #NNN
|
|
130
131
|
|
|
@@ -144,11 +145,11 @@ Why this task exists and what it depends on.
|
|
|
144
145
|
|
|
145
146
|
## Origin
|
|
146
147
|
|
|
147
|
-
Every task names where it came from, through a `Plan:`, `Groundwork:`, or `Issue:` line under the title. Include each only when the file, folder, or issue it names exists.
|
|
148
|
+
Every task names where it came from, through a `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` line under the title. Include each only when the file, folder, or issue it names exists.
|
|
148
149
|
|
|
149
|
-
A task with no origin is either lost context or work nobody decided to do. The invariant runs both ways, and the second direction is the one that bites: a groundwork track or an open issue that no task points at is work already decided and on its way to being forgotten.
|
|
150
|
+
A task with no origin is either lost context or work nobody decided to do. The invariant runs both ways, and the second direction is the one that bites: a groundwork track or an open issue that no task points at is work already decided and on its way to being forgotten. An intake folder is exempt from that direction, since it dispositions many items at once and most of them close without ever becoming a task.
|
|
150
151
|
|
|
151
|
-
`Plan
|
|
152
|
+
`Plan:`, `Groundwork:`, and `Intake:` name their target as a markdown link whose text is the file or folder stem, so the line resolves on a ctrl-click the way `priority.md` rows already do. Write the path relative to `.claude/tasks/`, which makes it `../plans/`, `../.tmp/groundwork/`, and `../intake/`. A path written from the project root renders as a link and resolves to nothing in an editor rooted at the project. `Issue:` stays a bare `#NNN`, since an issue number is not a path and a full URL would write the remote into a gitignored file.
|
|
152
153
|
|
|
153
154
|
Phase-label format and where labels may appear are governed by `standards/versioning.md`.
|
|
154
155
|
|
|
@@ -156,6 +157,8 @@ Phase-label format and where labels may appear are governed by `standards/versio
|
|
|
156
157
|
|
|
157
158
|
`Groundwork:` points at `../.tmp/groundwork/<slug>/`, the folder `claude-groundwork` fills. It names the surface it points at the way `Plan:` does. Use this key alone. `Research record` and `Decision record` are earlier spellings of the same thing and both convert to it.
|
|
158
159
|
|
|
160
|
+
`Intake:` points at `../intake/<slug>/`, the folder an intake pass fills. Use it rather than `Groundwork:`, because a groundwork track measures one question in depth while an intake dispositions many across a tree, and one key covering both loses which kind of pass produced the task. The line names the folder rather than an item inside it. A task routinely promotes several items at once, so an anchored line would name one and drop the rest, and the item numbers belong in that task's `## Findings`.
|
|
161
|
+
|
|
159
162
|
`Pull request:` records which pull request carries the task's work, as a bare `#NNN` the way `Issue:` does. It is not an origin, so a task without one is well-formed. `git-pr` writes it when a pull request opens, which is the one step that always runs whether the chain drives it or a person does.
|
|
160
163
|
|
|
161
164
|
The line is what lets a merge close its own task. Every merge on `main` is a squash carrying the number in its subject, so the number survives where a branch name does not, and `aitk tasks archive --pull-request <n>` resolves the task from it. Without the line the board can only be swept blind, and a blind sweep cannot tell a shipped task from an abandoned one. One task, one pull request: two tasks naming the same number refuse to archive rather than both moving.
|
|
@@ -8,4 +8,4 @@ runtime = ""
|
|
|
8
8
|
scaffold = ""
|
|
9
9
|
|
|
10
10
|
[gitignore]
|
|
11
|
-
"# Claude" = [".claude/.tmp/", ".claude/memory/", ".claude/plans/", ".claude/review/", ".claude/worktrees/", ".claude/tasks/"]
|
|
11
|
+
"# Claude" = [".claude/.tmp/", ".claude/intake/", ".claude/memory/", ".claude/plans/", ".claude/review/", ".claude/worktrees/", ".claude/tasks/"]
|
|
@@ -49,7 +49,7 @@ A project installed before the diagram surface became a folder still holds `.cla
|
|
|
49
49
|
|
|
50
50
|
## Gitignore
|
|
51
51
|
|
|
52
|
-
- `# Claude`: `.claude/.tmp/`, `.claude/memory/`, `.claude/plans/`, `.claude/review/`, `.claude/worktrees/`, `.claude/tasks/`
|
|
52
|
+
- `# Claude`: `.claude/.tmp/`, `.claude/intake/`, `.claude/memory/`, `.claude/plans/`, `.claude/review/`, `.claude/worktrees/`, `.claude/tasks/`
|
|
53
53
|
|
|
54
54
|
## CLI
|
|
55
55
|
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Draft a new snippet following these conventions:
|
|
2
|
-
|
|
3
|
-
- Filename is the slug: kebab-case, no capitals, no underscores
|
|
4
|
-
- Plain markdown only, no YAML frontmatter, no headers or nested structure
|
|
5
|
-
- One focused purpose, self-contained with no external file references
|
|
6
|
-
|
|
7
|
-
Output the slug and the full file content.
|