@erclx/aitk 0.35.1 → 0.35.2

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aitk",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "0.35.1",
4
+ "version": "0.35.2",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -9,6 +9,8 @@ description: What pull request generation is for, the gaps it closes, and what i
9
9
 
10
10
  Without this skill, a pull request body is written from memory of the branch rather than from its diff, so it describes the intent and omits what the work turned into. Testing boxes get ticked from intent, which records what was meant to run instead of what ran, and a reviewer trusts the list. A second push either errors on create or opens a duplicate pull request, and banned characters survive into a body the hook never sees.
11
11
 
12
+ A lookup that resolves by head branch alone carries its own failure. A branch name reused after an earlier pull request merged resolves to the closed one, so the run rewrites a merged pull request's title and body and reports its URL as the one it opened. Both fields are recoverable only through the issue timeline and the edit history, and nothing reports that the write landed on the wrong object.
13
+
12
14
  ## Must
13
15
 
14
16
  - Refuse a branch name that does not conform, since the name lands on the pull request permanently and renaming it afterward breaks the link
@@ -17,12 +19,15 @@ Without this skill, a pull request body is written from memory of the branch rat
17
19
  - Leave a box unchecked only for a human-only case, naming which human and why on the same line
18
20
  - Scan the title and body for banned characters and internal phase labels as an explicit step, on top of reading the prose standard
19
21
  - Detect an open pull request and edit it in place, so a follow-up push keeps the body in sync instead of failing
22
+ - Scope that detection to an open pull request on the current head and the default base, so neither a reused branch name nor a second base resolves the wrong one
23
+ - Resolve the pull request once and reuse what that resolution returned, so the number recorded never depends on how a lookup ranks two pull requests sharing a head
20
24
 
21
25
  ## Must not
22
26
 
23
27
  - Tick a testing box from intent or from a past session. The box records a run.
24
28
  - Put a request for the reviewer in the Testing list, since a request is not a result
25
29
  - Create a second pull request when one is open
30
+ - Edit a pull request that is not open, or record its number on a task
26
31
  - Emit anything after the result line
27
32
 
28
33
  ## Guards
@@ -71,9 +71,19 @@ Leave a box unchecked only for the human-only cases the reference defines, and n
71
71
 
72
72
  Before running the final command, run the scan in `.claude/standards/publish.md` against the PR title and body, or `${CLAUDE_SKILL_DIR}/../../standards/publish.md` when the project does not have it. The title and body go straight to the remote with nothing checking them on the way, so this scan is the only gate. It covers the phase-label check as well as the characters, since both go to a reader who has no task board. It applies on top of the banned phrases in `${CLAUDE_SKILL_DIR}/references/pr.md`.
73
73
 
74
+ ### Resolving the pull request
75
+
76
+ The run resolves the pull request once, in the final command below, and every later step reads what that command printed. Nothing else looks the number up again.
77
+
78
+ `gh pr view` is the form this replaces. It resolves by head branch and ignores state, so a branch name reused after an earlier pull request merged returns the closed one. The detection then takes the edit path and rewrites a merged pull request's title and body, and the run reports that pull request's URL as the one it opened, so nothing surfaces the write landing on the wrong object. Scoping the lookup with `--state open` returns empty there and sends the run down the create path.
79
+
80
+ The lookup scopes to the base as well as the head. One head can carry open pull requests against two bases, and a lookup reading the first result would pick between them by list order. Resolving the base from the repository's default branch is what makes the detection and `gh pr create` agree on which pull request the run is about.
81
+
82
+ A detached HEAD gives `git branch --show-current` an empty result, which would read as no open pull request and create a second one. The branch-name guard above stops the run first, since an empty name does not match `<type>/<description>`.
83
+
74
84
  ### Final command
75
85
 
76
- Detect an existing PR and branch: edit it in place when one is open, create it otherwise. This keeps the body in sync on a follow-up push instead of erroring on `gh pr create`.
86
+ Detect an open pull request on the current head and branch: edit it in place when one exists, create it otherwise. This keeps the body in sync on a follow-up push instead of erroring on `gh pr create`.
77
87
 
78
88
  ```bash
79
89
  mkdir -p .claude/.tmp/pr
@@ -81,21 +91,21 @@ cat <<'BODY' > .claude/.tmp/pr/body.md
81
91
  <body content following pr.md template exactly>
82
92
  BODY
83
93
  git push -u origin HEAD || exit 1
84
- if gh pr view --json number >/dev/null 2>&1; then
85
- gh pr edit --title "<title>" --body-file .claude/.tmp/pr/body.md
94
+ base_branch=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name) || exit 1
95
+ pr_number=$(gh pr list --head "$(git branch --show-current)" --base "$base_branch" --state open --json number --jq '.[0].number // empty')
96
+ if [ -n "$pr_number" ]; then
97
+ pr_url=$(gh pr edit "$pr_number" --title "<title>" --body-file .claude/.tmp/pr/body.md) || exit 1
86
98
  else
87
- gh pr create --title "<title>" --body-file .claude/.tmp/pr/body.md
99
+ pr_url=$(gh pr create --title "<title>" --body-file .claude/.tmp/pr/body.md) || exit 1
100
+ pr_number=${pr_url##*/}
88
101
  fi
89
102
  rm -rf .claude/.tmp/pr
103
+ printf 'number=%s\nurl=%s\n' "$pr_number" "$pr_url"
90
104
  ```
91
105
 
92
106
  ### Record the number on the task
93
107
 
94
- Resolve the number the run created or edited, then write it onto the task the branch is closing:
95
-
96
- ```bash
97
- gh pr view --json number --jq .number
98
- ```
108
+ Write the `number` the final command printed onto the task the branch is closing. Do not resolve it again. A head branch that carried an earlier pull request now has two, and a second `gh pr view` would pick between them by a precedence rule nothing here states. Reading what created or edited the pull request needs no such rule.
99
109
 
100
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.
101
111
 
@@ -107,7 +117,7 @@ The number is what lets the merge close the task. Every merge on `main` is a squ
107
117
 
108
118
  ## After execution
109
119
 
110
- Respond with exactly one line:
120
+ Respond with exactly one line, using the `url` the final command printed:
111
121
 
112
122
  `✅ PR: <url>`
113
123
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/aitk",
3
3
  "type": "module",
4
- "version": "0.35.1",
4
+ "version": "0.35.2",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {