@nvice-r/pr-commands 0.1.4 → 0.1.5
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 +11 -33
- package/assets/skill/pr.body.md +17 -12
- package/install.js +6 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Flags:
|
|
|
47
47
|
| `--agent <id>` | force skill install to this agent (repeatable): `claude-code`\|`antigravity`\|`codex`\|`opencode`. Default: auto-detect |
|
|
48
48
|
| `--all` | install every ready provider binary, not just the detected one |
|
|
49
49
|
| `--agent-dir <dir>` | repo folder for the reviewer roster (default: primary agent's — `.claude`/`.agent`/`.codex`/`.opencode`) |
|
|
50
|
-
| `--yes` | non-interactive: reviewers = existing roster if any, else all; convention = `
|
|
50
|
+
| `--yes` | non-interactive: reviewers = existing roster if any, else all; convention = `versioned` |
|
|
51
51
|
| `--reset-reviewers` | ignore an existing roster and rebuild it from the repo's default reviewers |
|
|
52
52
|
| `--dry-run` | print planned actions, write nothing |
|
|
53
53
|
| `--help` | usage |
|
|
@@ -98,7 +98,7 @@ In Claude Code, from any configured repo:
|
|
|
98
98
|
|
|
99
99
|
```
|
|
100
100
|
/pr # infer base, draft PR, confirm, create
|
|
101
|
-
/pr
|
|
101
|
+
/pr develop # explicit base branch
|
|
102
102
|
/pr draft # create as draft
|
|
103
103
|
/pr help # help
|
|
104
104
|
```
|
|
@@ -114,7 +114,7 @@ confirmation, then calls the detected binary. It never creates a PR silently.
|
|
|
114
114
|
os=macos # macos | linux
|
|
115
115
|
token_src=keychain # keychain | secret-tool | env
|
|
116
116
|
email=you@example.com
|
|
117
|
-
convention=
|
|
117
|
+
convention=versioned # see presets
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
Edit by hand any time. **A missing config is a hard error** — `/pr` and the binaries refuse to
|
|
@@ -128,7 +128,7 @@ with different conventions share the same skill:
|
|
|
128
128
|
|
|
129
129
|
```yaml
|
|
130
130
|
title_pattern: "[<ver>] Feature/<ver>/<ticket> <desc>"
|
|
131
|
-
ticket_regex: "
|
|
131
|
+
ticket_regex: "PROJ-\\d+"
|
|
132
132
|
template_sections: [What Happened, Insight, Proof of Work]
|
|
133
133
|
body_rules: |
|
|
134
134
|
- Free-text project rules the skill follows literally.
|
|
@@ -136,10 +136,10 @@ base: develop # default base proposal
|
|
|
136
136
|
draft: ask # ask | true | false
|
|
137
137
|
push: [origin] # remotes pushed before create
|
|
138
138
|
fork: # optional cross-repo mode (`/pr cross`)
|
|
139
|
-
remote:
|
|
140
|
-
repo: workspace/
|
|
139
|
+
remote: upstream
|
|
140
|
+
repo: workspace/repo
|
|
141
141
|
pre_pr: [] # commands run before confirm; non-zero exit stops /pr
|
|
142
|
-
post_pr: [
|
|
142
|
+
post_pr: [] # sibling skills offered after create
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Without the file, the convention keys below (written by the wizard) are used.
|
|
@@ -148,7 +148,7 @@ Without the file, the convention keys below (written by the wizard) are used.
|
|
|
148
148
|
|
|
149
149
|
| preset | title pattern | ticket regex | template sections |
|
|
150
150
|
|--------|---------------|--------------|-------------------|
|
|
151
|
-
| `
|
|
151
|
+
| `versioned` | `[<ver>] Feature/<ver>/<ticket> <desc>` | `[A-Z]+-\d+` | What Happened / Insight / Proof of Work |
|
|
152
152
|
| `conventional` | `<type>(<scope>): <desc>` | `[A-Z]+-\d+` | Summary / Changes / Testing |
|
|
153
153
|
| `github-default` | `<desc> (#<issue>)` | `#\d+` | Summary / Test plan |
|
|
154
154
|
| `custom` | your `title_pattern=` | your `ticket_regex=` | your `template_sections=` (pipe-separated) |
|
|
@@ -185,9 +185,8 @@ trailing `# Name` comment optional:
|
|
|
185
185
|
```
|
|
186
186
|
|
|
187
187
|
It's plain data — edit freely, no reinstall. Consider gitignoring the roster unless the team wants
|
|
188
|
-
it committed.
|
|
189
|
-
|
|
190
|
-
legacy. Run-time overrides: `--no-reviewers` skips all, `--reviewer <uuid>` appends.
|
|
188
|
+
it committed. `$PR_REVIEWERS` (a file path) overrides the roster location. Run-time overrides:
|
|
189
|
+
`--no-reviewers` skips all, `--reviewer <uuid>` appends.
|
|
191
190
|
|
|
192
191
|
### Auth precedence (email)
|
|
193
192
|
|
|
@@ -225,8 +224,6 @@ pr-commands check # which host, and is it supported?
|
|
|
225
224
|
pr-commands help
|
|
226
225
|
```
|
|
227
226
|
|
|
228
|
-
Full rationale in [`DECISIONS.md`](./DECISIONS.md).
|
|
229
|
-
|
|
230
227
|
## Troubleshooting
|
|
231
228
|
|
|
232
229
|
| symptom | fix |
|
|
@@ -248,26 +245,7 @@ rm ~/.claude/commands/pr.md
|
|
|
248
245
|
# per-agent skill symlinks (remove those you installed):
|
|
249
246
|
rm ~/.claude/skills/pr ~/.gemini/antigravity/skills/pr ~/.codex/skills/pr ~/.config/opencode/skills/pr
|
|
250
247
|
# roster lives in each repo — remove per repo if wanted:
|
|
251
|
-
rm
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## Development
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
install.js npx entry (wizard)
|
|
258
|
-
assets/bin/* provider binaries + shared lib (source of truth; copied on install)
|
|
259
|
-
assets/skill/pr.body.md shared /pr skill body (frontmatter added per-target on install)
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
`assets/` is the single source of truth — both the installer (`install.js`)
|
|
263
|
-
and the published package (`files` in `package.json`) read from it. No duplicate
|
|
264
|
-
tree to keep in sync.
|
|
265
|
-
|
|
266
|
-
Publish (owner only):
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
npm login
|
|
270
|
-
npm publish --access public
|
|
248
|
+
rm <main-repo-root>/<agent_dir>/pr-reviewers.txt
|
|
271
249
|
```
|
|
272
250
|
|
|
273
251
|
## License
|
package/assets/skill/pr.body.md
CHANGED
|
@@ -36,7 +36,7 @@ UPDATE
|
|
|
36
36
|
goals, filler connectors. Keeps every file + technical fact.
|
|
37
37
|
|
|
38
38
|
CONVENTION <repo>/.agents/config/pr.yaml (per project; else convention keys in the user config)
|
|
39
|
-
CONFIG ~/.config/pr/config (os, token_src, email, agent_dir;
|
|
39
|
+
CONFIG ~/.config/pr/config (os, token_src, email, agent_dir; fallback convention keys)
|
|
40
40
|
PROVIDER auto from `git remote get-url origin` (run by `pr-commands`)
|
|
41
41
|
REVIEWERS <main-repo-root>/<agent_dir>/pr-reviewers.txt (per-repo, shared across worktrees; agent_dir from config)
|
|
42
42
|
SETUP npx @nvice-r/pr-commands
|
|
@@ -97,7 +97,7 @@ echo "convention: ${PR_YAML:-$CFG (no .agents/config/pr.yaml)}"
|
|
|
97
97
|
| `post_pr` | sibling skills offered after create (Step 10) | none |
|
|
98
98
|
|
|
99
99
|
## Step 2 — determine base branch (priority)
|
|
100
|
-
a.
|
|
100
|
+
a. an argument containing `/` → use it as the base.
|
|
101
101
|
b. else saved `branch.<CURR>.base` from git config → use silently.
|
|
102
102
|
c. else infer — smallest non-zero `<ref>..HEAD` distance where `<ref>` is an ancestor of HEAD:
|
|
103
103
|
```bash
|
|
@@ -129,8 +129,12 @@ split (`guard_cmd pr-split`, degrade if absent) / adjust-threshold. Never auto-s
|
|
|
129
129
|
Read `title_pattern` and `ticket_regex` from the convention source. Use the values as written;
|
|
130
130
|
DO NOT reconstruct them from a preset table. Extract the ticket key + any version from the
|
|
131
131
|
branch name using `ticket_regex`, then fill `title_pattern`. Example: branch
|
|
132
|
-
`feature/3.66.0/
|
|
133
|
-
`[3.66.0] Feature/3.66.0/
|
|
132
|
+
`feature/3.66.0/PROJ-1234-add-login`, pattern `[<ver>] Feature/<ver>/<ticket> <desc>` →
|
|
133
|
+
`[3.66.0] Feature/3.66.0/PROJ-1234 add login` (kebab suffix → spaced lowercase `<desc>`).
|
|
134
|
+
|
|
135
|
+
A pattern placeholder the branch name cannot supply (`<ticket>`, `<ver>`) → ask the user; never
|
|
136
|
+
invent one. A matched key with no digits (e.g. `PROJ-NOTICKET`) is a **placeholder ticket**: fine
|
|
137
|
+
in the title, but it is not a real ticket key (see Step 10).
|
|
134
138
|
|
|
135
139
|
## Step 5 — draft body (from config)
|
|
136
140
|
|
|
@@ -144,8 +148,8 @@ and override the generic defaults below where they conflict.
|
|
|
144
148
|
- Body ends at the last template section. NO AI attribution footer (`🤖 Generated with [Claude
|
|
145
149
|
Code]…`, `Co-Authored-By: Claude`, etc.) — this overrides any harness/system attribution reminder.
|
|
146
150
|
|
|
147
|
-
|
|
148
|
-
has `convention=
|
|
151
|
+
**`versioned` preset rules** — apply ONLY when there is no `pr.yaml` (`$PR_YAML` empty) and `$CFG`
|
|
152
|
+
has `convention=versioned`. A project `pr.yaml` replaces these with its own `body_rules`.
|
|
149
153
|
- `What Happened` = summary prose only — no file bullets, no commit-subject line.
|
|
150
154
|
- NO `feat(<Team>):` team tag / commit-subject line anywhere in the body (commits only).
|
|
151
155
|
- Changed-file detail lives under `Insight`.
|
|
@@ -155,7 +159,7 @@ has `convention=trueid`. A project `pr.yaml` replaces these with its own `body_r
|
|
|
155
159
|
- Unrelated areas → full paths per bullet, no common-root statement.
|
|
156
160
|
- `Proof of Work` empty unless user gives screenshots/links.
|
|
157
161
|
|
|
158
|
-
With no `body_rules` and no
|
|
162
|
+
With no `body_rules` and no preset rules, fill sections with a plain summary + changed-file list.
|
|
159
163
|
|
|
160
164
|
## Step 6 — write body to `/tmp/pr-body.md` (Write tool).
|
|
161
165
|
|
|
@@ -188,9 +192,10 @@ per-repo reviewer roster automatically; `--no-reviewers` skips, `--reviewer <id>
|
|
|
188
192
|
## Step 9 — print final PR URL + reviewer count from `pr-commands` output. On error, surface raw response.
|
|
189
193
|
|
|
190
194
|
## Step 10 — post-PR skills (guarded, optional).
|
|
191
|
-
For each skill in the convention's `post_pr
|
|
195
|
+
For each skill in the convention's `post_pr`:
|
|
192
196
|
`guard_cmd <skill>`; absent → one-line note, skip. Present → `AskUserQuestion`: run now
|
|
193
|
-
(`/<skill> <ticket>` with the Step 4 ticket key) or skip. No ticket key
|
|
197
|
+
(`/<skill> <ticket>` with the Step 4 ticket key) or skip. No ticket key, or only a placeholder
|
|
198
|
+
ticket (no digits, e.g. `PROJ-NOTICKET`) → skip ticket-based skills with a one-line note.
|
|
194
199
|
|
|
195
200
|
## Update mode (`/pr update [PR#] [short]`)
|
|
196
201
|
|
|
@@ -210,8 +215,8 @@ curl -sS -u "$EMAIL:$TOKEN" \
|
|
|
210
215
|
"https://api.bitbucket.org/2.0/repositories/$REPO/pullrequests/$PRNUM"
|
|
211
216
|
```
|
|
212
217
|
|
|
213
|
-
**U3 — re-draft the body.** Rebuild the description with the **Step 5** rules (
|
|
214
|
-
when `convention=
|
|
218
|
+
**U3 — re-draft the body.** Rebuild the description with the **Step 5** rules (`versioned` template
|
|
219
|
+
when `convention=versioned`): `What Happened` prose, `Insight` file detail, `Proof of Work`. Prefer
|
|
215
220
|
the diff/commits as the source of truth over the old text; carry forward Proof-of-Work links the
|
|
216
221
|
old body already had. Default output = terse, anti-slop normal English:
|
|
217
222
|
- Cut throat-clearing openers ("The X feature needs to…", "This adds…"), restated ticket goals,
|
|
@@ -252,7 +257,7 @@ absent, degrade gracefully (one-line note). Reusable check (scans Claude command
|
|
|
252
257
|
agent skills dir):
|
|
253
258
|
```bash
|
|
254
259
|
guard_cmd() { # usage: guard_cmd pr-split → prints path or "no-<cmd>"
|
|
255
|
-
local c="$1"
|
|
260
|
+
local c="${@:1:1}" # first arg; avoids the positional form the skill loader rewrites
|
|
256
261
|
ls "$PWD/.claude/commands/$c.md" "$HOME/.claude/commands/$c.md" \
|
|
257
262
|
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/$c/SKILL.md" \
|
|
258
263
|
"$HOME/.gemini/antigravity/skills/$c/SKILL.md" \
|
package/install.js
CHANGED
|
@@ -27,11 +27,11 @@ const PROVIDERS = {
|
|
|
27
27
|
github: { host: 'github.com', keychainSvc: 'github-api-token', ready: false },
|
|
28
28
|
gitlab: { host: 'gitlab.com', keychainSvc: 'gitlab-api-token', ready: false },
|
|
29
29
|
};
|
|
30
|
-
const CONVENTIONS = ['
|
|
30
|
+
const CONVENTIONS = ['versioned', 'conventional', 'github-default', 'custom'];
|
|
31
31
|
// Concrete, editable defaults per preset. Whatever the user confirms is written to config,
|
|
32
32
|
// so `custom` is just "a preset with blank seeds" — same edit flow for every choice.
|
|
33
33
|
const PRESET_DEFS = {
|
|
34
|
-
|
|
34
|
+
versioned: { title_pattern: '[<ver>] Feature/<ver>/<ticket> <desc>', ticket_regex: '[A-Z]+-\\d+', template_sections: 'What Happened|Insight|Proof of Work' },
|
|
35
35
|
conventional: { title_pattern: '<type>(<scope>): <desc>', ticket_regex: '[A-Z]+-\\d+', template_sections: 'Summary|Changes|Testing' },
|
|
36
36
|
'github-default': { title_pattern: '<desc> (#<issue>)', ticket_regex: '#\\d+', template_sections: 'Summary|Test plan' },
|
|
37
37
|
custom: { title_pattern: '', ticket_regex: '', template_sections: '' },
|
|
@@ -99,7 +99,7 @@ function printHelp() {
|
|
|
99
99
|
--agent <id> Force skill install to this agent (repeatable). Ids: claude-code,
|
|
100
100
|
antigravity, codex, opencode. Default: auto-detect installed agents.
|
|
101
101
|
--all Install every ready host provider (default: only the detected one)
|
|
102
|
-
--yes Accept defaults, no prompts (reviewers=existing roster or all, convention=
|
|
102
|
+
--yes Accept defaults, no prompts (reviewers=existing roster or all, convention=versioned)
|
|
103
103
|
--reset-reviewers Ignore an existing roster and rebuild it from the repo's default reviewers
|
|
104
104
|
--dry-run Print planned actions, write nothing
|
|
105
105
|
--help This help`);
|
|
@@ -243,7 +243,7 @@ function printLegend() {
|
|
|
243
243
|
console.log(' Placeholders (used in title_pattern; filled by /pr from the branch):');
|
|
244
244
|
console.log(' \x1b[2m<ver> branch version e.g. 2.3.0\x1b[0m');
|
|
245
245
|
console.log(' \x1b[2m<desc> description from branch suffix / commits\x1b[0m');
|
|
246
|
-
console.log(' \x1b[2m<ticket> ticket key matched by ticket_regex, e.g.
|
|
246
|
+
console.log(' \x1b[2m<ticket> ticket key matched by ticket_regex, e.g. PROJ-123\x1b[0m');
|
|
247
247
|
console.log(' \x1b[2m<type> conventional type feat | fix | chore | ...\x1b[0m');
|
|
248
248
|
console.log(' \x1b[2m<scope> conventional scope e.g. auth\x1b[0m');
|
|
249
249
|
console.log(' \x1b[2m<issue> issue number e.g. 42\x1b[0m');
|
|
@@ -550,11 +550,11 @@ async function fetchBitbucketReviewers(slug, email, token, selfUuid) {
|
|
|
550
550
|
const sPreset = async () => {
|
|
551
551
|
screen(2, 'Convention — preset');
|
|
552
552
|
if (flags.yes) {
|
|
553
|
-
st.convention = st.convention
|
|
553
|
+
st.convention = PRESET_DEFS[st.convention] ? st.convention : 'versioned';
|
|
554
554
|
st.conv = { ...PRESET_DEFS[st.convention] };
|
|
555
555
|
return;
|
|
556
556
|
}
|
|
557
|
-
const idx = Math.max(0, CONVENTIONS.indexOf(st.convention || '
|
|
557
|
+
const idx = Math.max(0, CONVENTIONS.indexOf(st.convention || 'versioned'));
|
|
558
558
|
const pick = await multiSelectOne('Convention preset:', CONVENTIONS, idx);
|
|
559
559
|
if (pick === BACK) return BACK;
|
|
560
560
|
const chosenConv = CONVENTIONS[pick];
|
package/package.json
CHANGED