@erclx/aitk 3.17.0 → 3.18.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-pr-review/SKILL.md +7 -5
- package/governance/rules/core/005-behavior.md +27 -0
- package/governance/rules/core/015-output.md +20 -0
- package/governance/rules/core/025-indexes.md +9 -0
- package/governance/rules/core/035-tasks.md +13 -0
- package/governance/rules/core/045-memory.md +12 -0
- package/governance/rules/core/055-scratch.md +9 -0
- package/governance/rules/core/085-worktrees.md +17 -0
- package/package.json +1 -1
- package/tooling/claude/seeds/CLAUDE.md +0 -59
|
@@ -76,16 +76,18 @@ On exit zero, review `<prior-oid>..<headRefOid>` and nothing else. `git diff` an
|
|
|
76
76
|
A commit is its own ancestor, so an unchanged head passes that test too, with an empty range. When `<prior-oid>` equals `<headRefOid>`, decide whether this pass has anything to add before reading anything else, since the empty range itself cannot answer that:
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
gh pr view <number> --json reviews,comments --jq '([.reviews[] | select(.body // "" | split("\n")[0] | rtrimstr("\r") | . == "## Review" or . == "## Review closed")] | last | .submittedAt) as $prior | [.comments[] | select(.body // "" | split("\n")[0] | rtrimstr("\r") | . == "## Review response") | select(.createdAt > $prior)] | last | .url // empty | split("-") | last'
|
|
79
|
+
gh pr view <number> --json reviews,comments --jq '([.reviews[] | select(.body // "" | split("\n")[0] | rtrimstr("\r") | . == "## Review" or . == "## Review closed")] | last | .submittedAt) as $prior | [.comments[] | select(.body // "" | split("\n")[0] | rtrimstr("\r") | . == "## Review response" or . == "## Rebase" or . == "## Post-review findings") | select(.createdAt > $prior)] | last | .url // empty | split("-") | last'
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
Scope the
|
|
82
|
+
Scope the replies to those newer than the prior pass, never to every reply the thread carries. A pass answering the newest reply and a pass answering an older one derive the same third segment (Step 4), so an unscoped read hands a re-run after a close-out the name its own prior pass already wrote. That is the collision this case exists to prevent, reached without a rebase or an error.
|
|
83
83
|
|
|
84
84
|
Read the number off `.url`. The `id` field carries a GraphQL node id, which the thread never displays. Keep the `// empty` guard, since `split` aborts jq on the null an empty selection returns, and an aborted command reaches the session as an error rather than as the empty result the stop below reads.
|
|
85
85
|
|
|
86
|
-
An empty result means no
|
|
86
|
+
An empty result means no reply arrived since the prior pass, so the head is unchanged and this pass has nothing new to add. Stop here, before Step 3 or Step 4 run: `❌ The head is unchanged since the prior pass on <short-sha>. Nothing new to review.` This is the earliest point every path crosses, which is why the check sits here rather than inside Step 4's filename derivation. A path that decides there is nothing to add never reaches a step reached only when composing a body, so a stop written there is a stop a shortcut path can route around.
|
|
87
87
|
|
|
88
|
-
A non-empty result carries the comment id Step 4 needs for the third filename segment.
|
|
88
|
+
A non-empty result carries the comment id Step 4 needs for the third filename segment. A `## Review response` or a `## Rebase` reply answers a finding already argued or reports a stale branch resolved without one, so read it for what the worker changed or accepted, treat an accepted finding as closed rather than restating it, and skip the diff and file reads below. This is the entire read on a repeated head for either heading, since the empty range above has nothing in it to say whether a prior finding landed and neither reply needs anything more to answer that.
|
|
89
|
+
|
|
90
|
+
A `## Post-review findings` reply carries no argued finding behind it, since it asserts a new defect rather than answering one, and this pass is its first independent reader. Restating it as a finding without opening anything is repeating the worker's claim rather than checking it. Read the file the comment names at `<headRefOid>`, the same `git show <headRefOid>:<path>` read Step 3 already runs to confirm a ticked box, and confirm the defect before it becomes a finding of this pass's own.
|
|
89
91
|
|
|
90
92
|
Read each changed file in scope. Skip deleted files. Run reads in parallel.
|
|
91
93
|
|
|
@@ -123,7 +125,7 @@ Write the comment to `.claude/.tmp/pr-review/body-<number>-<short-sha>.md`. The
|
|
|
123
125
|
|
|
124
126
|
Derive both segments from Step 1. Never pick a suffix by hand, and never reuse a name the folder already holds.
|
|
125
127
|
|
|
126
|
-
When `<prior-oid>` from Step 2 equals `headRefOid`, the head repeats and the folder already holds `body-<number>-<short-sha>.md`. Add a third segment taking the id of the
|
|
128
|
+
When `<prior-oid>` from Step 2 equals `headRefOid`, the head repeats and the folder already holds `body-<number>-<short-sha>.md`. Add a third segment taking the id of the reply Step 2 resolved, giving `body-<number>-<short-sha>-r<comment-id>.md`. That satisfies both prohibitions above rather than carving an exception into either. Step 2 already stopped the pass when that resolution came back empty, so reaching this line means the comment id is in hand.
|
|
127
129
|
|
|
128
130
|
The comment is a rendered-for-human GitHub surface, so load the `write-human` skill for voice and follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for the banned words: cut editorializing, and keep every sentence load-bearing. Match this shape on a first pass:
|
|
129
131
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Handle judgment calls, scope discipline, and file-editing mechanics during a session
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Behavior standards
|
|
6
|
+
|
|
7
|
+
## Communication
|
|
8
|
+
|
|
9
|
+
- Flag concerns or alternatives when a proposed change has tradeoffs worth discussing
|
|
10
|
+
|
|
11
|
+
## Judgment calls
|
|
12
|
+
|
|
13
|
+
- When facing a judgment call with 2-3 reasonable options mid-flow, pick one and state the tradeoff in one sentence. Enumerate options only when the user's preference is the deciding factor.
|
|
14
|
+
- Put a call the user's preference decides through the structured question surface, such as `AskUserQuestion` in Claude Code, and fall back to a numbered list in one message where none exists. Rank the recommendation first and mark it, order the rest behind it, and give each option its cost, since an option with no stated cost is picked blind.
|
|
15
|
+
- Author the real choices only. A structured surface appends its own trailing escapes for a free-text answer and for reopening the question as conversation, so never write either as an option. On the numbered-list fallback, say that answering outside the list is fine.
|
|
16
|
+
- Answer from the artifact when one already put the question in writing with a suggestion, rather than re-asking it. A blank `- Answer:` slot in a plan accepts the `- Suggested:` line above it, per the plan standard, which your toolkit resolves by name.
|
|
17
|
+
|
|
18
|
+
## Scope discipline
|
|
19
|
+
|
|
20
|
+
- Match edit scope to the request. Ship minimal v1 and queue extensions as follow-ups.
|
|
21
|
+
- On simplification requests, edit only what the user named
|
|
22
|
+
- Do not add features the user did not ask for
|
|
23
|
+
- When rewriting a section, preserve existing code blocks, tables, and grouped examples unless the user asked to remove them
|
|
24
|
+
|
|
25
|
+
## Editing mechanics
|
|
26
|
+
|
|
27
|
+
- Edit an existing file with the file-editing tool, never a shell stream editor. An unescaped `&` in a `sed` replacement expands to the whole match, and `sed -i` exits zero when its pattern matches nothing, so both fail silently while reporting success. This governs edits you make, not stream editors written into a project's own scripts.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Report file paths correctly for the reading surface and group them when the response covers many
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Output standards
|
|
6
|
+
|
|
7
|
+
## Reporting paths
|
|
8
|
+
|
|
9
|
+
- After creating or modifying a file, include its path on its own line so the reader can open it. Do not paraphrase paths into prose ("the seeds folder", "your CLAUDE.md").
|
|
10
|
+
- Read `CLAUDE_CODE_ENTRYPOINT` once, at the first response that emits a path, and reuse it for the rest of the session. The surface cannot change mid-session, so a second read only confirms the first.
|
|
11
|
+
- When it reads `claude-desktop`, emit each path as a markdown link carrying the path as its text and an absolute `file://` URI as its target, resolving a relative path against the main project root to build that target. The desktop file tree hides dotted folders, so a bare path into one names a file the reader cannot reach.
|
|
12
|
+
- On every other value, including unset, emit the path bare. A terminal emulator makes it clickable through its own path detection, and link markup defeats that.
|
|
13
|
+
- Both forms govern a path emitted in a response. A path written into a markdown file follows the markdown standard instead, which your toolkit resolves by name, and which backticks a file reference and never repeats it as a link label.
|
|
14
|
+
- Use the path the user's editor can resolve. The editor is rooted at the main project root.
|
|
15
|
+
- In the main worktree: relative from `pwd` works because `pwd` equals the editor root.
|
|
16
|
+
- In a linked worktree (under `.claude/worktrees/<name>/`): use absolute paths. Relative paths from worktree `pwd` would not resolve against the editor's project root.
|
|
17
|
+
|
|
18
|
+
## Grouping multiple files
|
|
19
|
+
|
|
20
|
+
- When the response covers multiple files, group paths under headers: `**Created:**`, `**Modified:**`, `**Deleted:**`. Every path under them takes the form the entrypoint selected rather than the first alone. For single-file changes, the path on its own line is enough.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Check a folder's index before searching its contents
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Indexes standards
|
|
6
|
+
|
|
7
|
+
## Before searching
|
|
8
|
+
|
|
9
|
+
- Check a folder's `index.md` before grepping its source or reading its files, starting with `.claude/context/` for a domain and `.claude/wireframes/` for a UI surface. It orients faster than a blind search.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scope, size, and link a task file correctly
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Tasks standards
|
|
6
|
+
|
|
7
|
+
## Task files
|
|
8
|
+
|
|
9
|
+
- `.claude/tasks/` is gitignored local session scratch, one file per task. Edit freely. No staging or revert before commits.
|
|
10
|
+
- Only create a task for work that spans multiple sessions or has real dependencies. Handle small edits immediately without a task entry.
|
|
11
|
+
- Do not add tasks retroactively for work already completed. Completed work is visible in git.
|
|
12
|
+
- When a task needs execution detail beyond its own file, create a plan in `.claude/plans/` and link to it from the task's intro paragraph. When that task ships, move its plan file to `.claude/plans/archive/`. Never delete it.
|
|
13
|
+
- Write the plan in the same session as the task file. The session that executes the plan later inherits reasoning context it would otherwise have to re-derive.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Keep memory writes scoped to .claude/memory/ and out of context-owned domains
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Memory standards
|
|
6
|
+
|
|
7
|
+
## Writing memory
|
|
8
|
+
|
|
9
|
+
- Write all memory files to `.claude/memory/`, not `~/.claude/projects/`
|
|
10
|
+
- A fact about a domain goes to that domain's `.claude/context/` entry, not to memory. `claude-memory-capture` routes it there and `claude-docs` folds it in. Memory keeps only what no context entry owns.
|
|
11
|
+
- Never delete a memory entry. Retire one by moving it to `.claude/.tmp/memory-archive/`. A bulk retire runs through the shell, where no file edit fires a path-scoped rule, and the folder is gitignored with nothing to recover from.
|
|
12
|
+
- Follow the memory standard, which your toolkit resolves by name, for the filename and type prefix, the frontmatter, the body shape each type carries, and the lifecycle. Check every entry in the pen against that standard and fix what breaks it, since nothing keeps the folder conforming on its own.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Write temporary files to the scratch folder structure
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Scratch standards
|
|
6
|
+
|
|
7
|
+
## Temporary files
|
|
8
|
+
|
|
9
|
+
- Write temporary files to `.claude/.tmp/<slug>/<file>.md` in the project root, a nested `<slug>/` folder with a kebab-slug tied to the topic, not a flat `<slug>-<file>.md`. The scratch-guard hook enforces the location.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Route tracked-file writes and shared session scratch correctly from a linked worktree
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Worktrees standards
|
|
6
|
+
|
|
7
|
+
## Entering a worktree
|
|
8
|
+
|
|
9
|
+
- Implementation work runs in a linked worktree. From the main worktree, enter one with `/claude-worktree` before editing tracked files for a feature.
|
|
10
|
+
|
|
11
|
+
## Shared session scratch
|
|
12
|
+
|
|
13
|
+
- Shared session scratch (`.claude/plans/`, `.claude/review/`, `.claude/memory/`, `.claude/tasks/`) lives at the main worktree root, not inside a linked worktree. From a linked worktree, resolve these paths against the main root via `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. Fall back to `pwd` if not a git repo.
|
|
14
|
+
- From a linked worktree, every `Edit` or `Write` to a tracked file (source, docs) must use a path starting with `pwd`.
|
|
15
|
+
- From a linked worktree, `Edit` and `Write` are refused for every main-root path, session scratch included. The refusal names session isolation and points at the worktree copy, which is a second gitignored file no later session reads, so never take that redirect.
|
|
16
|
+
- `Read` resolves against the main root normally from a linked worktree. A main-root write reaches it only through `Bash`, as one plain command rather than a compound one, which is refused for complexity.
|
|
17
|
+
- Route a main-root write by what it does to the file. Creating a whole file goes out as one plain `Bash` command carrying a heredoc. Changing a line inside a file that already exists goes through a command that resolves the main root in-process, because the shell route for that case is the stream editor this file bans.
|
package/package.json
CHANGED
|
@@ -13,41 +13,10 @@
|
|
|
13
13
|
@.claude/context/index.md
|
|
14
14
|
@.claude/wireframes/index.md
|
|
15
15
|
|
|
16
|
-
## Behavior
|
|
17
|
-
|
|
18
|
-
- Flag concerns or alternatives when a proposed change has tradeoffs worth discussing
|
|
19
|
-
- When facing a judgment call with 2-3 reasonable options mid-flow, pick one and state the tradeoff in one sentence. Enumerate options only when the user's preference is the deciding factor.
|
|
20
|
-
- Put a call the user's preference decides through the structured question surface, such as `AskUserQuestion` in Claude Code, and fall back to a numbered list in one message where none exists. Rank the recommendation first and mark it, order the rest behind it, and give each option its cost, since an option with no stated cost is picked blind.
|
|
21
|
-
- Author the real choices only. A structured surface appends its own trailing escapes for a free-text answer and for reopening the question as conversation, so never write either as an option. On the numbered-list fallback, say that answering outside the list is fine.
|
|
22
|
-
- Answer from the artifact when one already put the question in writing with a suggestion, rather than re-asking it. A blank `- Answer:` slot in a plan accepts the `- Suggested:` line above it, per the plan standard, which your toolkit resolves by name.
|
|
23
|
-
- Match edit scope to the request. Ship minimal v1 and queue extensions as follow-ups.
|
|
24
|
-
- On simplification requests, edit only what the user named
|
|
25
|
-
- Do not add features the user did not ask for
|
|
26
|
-
- When rewriting a section, preserve existing code blocks, tables, and grouped examples unless the user asked to remove them
|
|
27
|
-
- When planning an edit to `CLAUDE.md`, show the proposed change as a fenced `diff` block in chat first, then wait for approval before calling `Edit`
|
|
28
|
-
- Keep a rule in `CLAUDE.md` when it applies every session regardless of what is being edited. Move one that fires only on a specific path being edited and ships silently when violated into `.claude/rules/`.
|
|
29
|
-
- Edit an existing file with the file-editing tool, never a shell stream editor. An unescaped `&` in a `sed` replacement expands to the whole match, and `sed -i` exits zero when its pattern matches nothing, so both fail silently while reporting success. This governs edits you make, not stream editors written into a project's own scripts.
|
|
30
|
-
|
|
31
|
-
## Indexes
|
|
32
|
-
|
|
33
|
-
- Check a folder's `index.md` before grepping its source or reading its files, starting with `.claude/context/` for a domain and `.claude/wireframes/` for a UI surface. It orients faster than a blind search.
|
|
34
|
-
|
|
35
16
|
## Commands
|
|
36
17
|
|
|
37
18
|
- Run `bun run check` before committing. Full script reference in the development entry under `.claude/context/`.
|
|
38
19
|
|
|
39
|
-
## Output
|
|
40
|
-
|
|
41
|
-
- After creating or modifying a file, include its path on its own line so the reader can open it. Do not paraphrase paths into prose ("the seeds folder", "your CLAUDE.md").
|
|
42
|
-
- Read `CLAUDE_CODE_ENTRYPOINT` once, at the first response that emits a path, and reuse it for the rest of the session. The surface cannot change mid-session, so a second read only confirms the first.
|
|
43
|
-
- When it reads `claude-desktop`, emit each path as a markdown link carrying the path as its text and an absolute `file://` URI as its target, resolving a relative path against the main project root to build that target. The desktop file tree hides dotted folders, so a bare path into one names a file the reader cannot reach.
|
|
44
|
-
- On every other value, including unset, emit the path bare. A terminal emulator makes it clickable through its own path detection, and link markup defeats that.
|
|
45
|
-
- Both forms govern a path emitted in a response. A path written into a markdown file follows the markdown standard instead, which your toolkit resolves by name, and which backticks a file reference and never repeats it as a link label.
|
|
46
|
-
- Use the path the user's editor can resolve. The editor is rooted at the main project root.
|
|
47
|
-
- In the main worktree: relative from `pwd` works because `pwd` equals the editor root.
|
|
48
|
-
- In a linked worktree (under `.claude/worktrees/<name>/`): use absolute paths. Relative paths from worktree `pwd` would not resolve against the editor's project root.
|
|
49
|
-
- When the response covers multiple files, group paths under headers: `**Created:**`, `**Modified:**`, `**Deleted:**`. Every path under them takes the form the entrypoint selected rather than the first alone. For single-file changes, the path on its own line is enough.
|
|
50
|
-
|
|
51
20
|
## Key paths
|
|
52
21
|
|
|
53
22
|
- `src/`: [description]
|
|
@@ -57,31 +26,3 @@
|
|
|
57
26
|
- `.claude/wiki/`: reference pages for tools, workflows, and concepts, indexed via `.claude/wiki/index.md`
|
|
58
27
|
- `.claude/rules/`: path-scoped coding standards loaded by Claude Code on file match
|
|
59
28
|
- `.claude/review/`: gitignored scratch for review and UI-test output, overwritten on each run
|
|
60
|
-
|
|
61
|
-
## Tasks
|
|
62
|
-
|
|
63
|
-
- `.claude/tasks/` is gitignored local session scratch, one file per task. Edit freely. No staging or revert before commits.
|
|
64
|
-
- Only create a task for work that spans multiple sessions or has real dependencies. Handle small edits immediately without a task entry.
|
|
65
|
-
- Do not add tasks retroactively for work already completed. Completed work is visible in git.
|
|
66
|
-
- When a task needs execution detail beyond its own file, create a plan in `.claude/plans/` and link to it from the task's intro paragraph. When that task ships, move its plan file to `.claude/plans/archive/`. Never delete it.
|
|
67
|
-
- Write the plan in the same session as the task file. The session that executes the plan later inherits reasoning context it would otherwise have to re-derive.
|
|
68
|
-
|
|
69
|
-
## Memory
|
|
70
|
-
|
|
71
|
-
- Write all memory files to `.claude/memory/`, not `~/.claude/projects/`
|
|
72
|
-
- A fact about a domain goes to that domain's `.claude/context/` entry, not to memory. `claude-memory-capture` routes it there and `claude-docs` folds it in. Memory keeps only what no context entry owns.
|
|
73
|
-
- Never delete a memory entry. Retire one by moving it to `.claude/.tmp/memory-archive/`. A bulk retire runs through the shell, where no file edit fires a path-scoped rule, and the folder is gitignored with nothing to recover from.
|
|
74
|
-
- Follow the memory standard, which your toolkit resolves by name, for the filename and type prefix, the frontmatter, the body shape each type carries, and the lifecycle. Check every entry in the pen against that standard and fix what breaks it, since nothing keeps the folder conforming on its own.
|
|
75
|
-
|
|
76
|
-
## Scratch
|
|
77
|
-
|
|
78
|
-
- Write temporary files to `.claude/.tmp/<slug>/<file>.md` in the project root, a nested `<slug>/` folder with a kebab-slug tied to the topic, not a flat `<slug>-<file>.md`. The scratch-guard hook enforces the location.
|
|
79
|
-
|
|
80
|
-
## Worktrees
|
|
81
|
-
|
|
82
|
-
- Implementation work runs in a linked worktree. From the main worktree, enter one with `/claude-worktree` before editing tracked files for a feature.
|
|
83
|
-
- Shared session scratch (`.claude/plans/`, `.claude/review/`, `.claude/memory/`, `.claude/tasks/`) lives at the main worktree root, not inside a linked worktree. From a linked worktree, resolve these paths against the main root via `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. Fall back to `pwd` if not a git repo.
|
|
84
|
-
- From a linked worktree, every `Edit` or `Write` to a tracked file (source, docs) must use a path starting with `pwd`.
|
|
85
|
-
- From a linked worktree, `Edit` and `Write` are refused for every main-root path, session scratch included. The refusal names session isolation and points at the worktree copy, which is a second gitignored file no later session reads, so never take that redirect.
|
|
86
|
-
- `Read` resolves against the main root normally from a linked worktree. A main-root write reaches it only through `Bash`, as one plain command rather than a compound one, which is refused for complexity.
|
|
87
|
-
- Route a main-root write by what it does to the file. Creating a whole file goes out as one plain `Bash` command carrying a heredoc. Changing a line inside a file that already exists goes through a command that resolves the main root in-process, because the shell route for that case is the stream editor this file bans.
|