@henryqw/pi-pr 6.0.6 → 6.0.8
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 +232 -112
- package/extensions/pr-github.ts +7 -6
- package/extensions/pr.ts +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# `@henryqw/pi-pr`
|
|
2
2
|
|
|
3
|
-
See the current
|
|
3
|
+
See the current-branch pull request in the Pi footer, then run `/pr` for its next safe step. It
|
|
4
|
+
shows CI, review, merge, and lifecycle status without repeated `gh` commands.
|
|
4
5
|
|
|
5
6
|
## Install
|
|
6
7
|
|
|
@@ -8,60 +9,92 @@ See the current branch pull request in the Pi footer. Use `/pr` to run its next
|
|
|
8
9
|
pi install npm:@henryqw/pi-pr
|
|
9
10
|
```
|
|
10
11
|
|
|
11
|
-
Requires an authenticated GitHub CLI session (`gh auth login`) and a checkout on GitHub.com or
|
|
12
|
-
|
|
13
|
-
## Feedback snapshots
|
|
14
|
-
|
|
15
|
-
`pr-feedback.mjs fetch --out FILE` prints a compact feedback index. The index
|
|
16
|
-
includes IDs, kinds, states, authors, locations, and parent IDs as needed. It
|
|
17
|
-
does not print comment or review bodies.
|
|
18
|
-
|
|
19
|
-
With `--out`, it atomically replaces `FILE` as a mode-0600 file. It does not
|
|
20
|
-
change the parent directory's permissions.
|
|
21
|
-
|
|
22
|
-
The saved snapshot still contains the complete feedback. `fetch --json` also
|
|
23
|
-
keeps the complete JSON output. Read one item with
|
|
24
|
-
`pr-feedback.mjs show --snapshot FILE --id ID`.
|
|
25
|
-
|
|
26
|
-
`show` prints one JSON record with its exact stored body and fields. A thread
|
|
27
|
-
record includes child IDs without child bodies. Treat that record as a container.
|
|
28
|
-
Inspect the `thread_comment` IDs directly. Do not call `show` on the parent only
|
|
29
|
-
to find children. Show the parent only when it has no child, or when you need
|
|
30
|
-
parent-level metadata. Issue independent `show` lookups in one tool-call round.
|
|
31
|
-
A nested comment includes only its parent thread's ID, state, and location.
|
|
32
|
-
Missing, unknown, duplicate, or ambiguous IDs fail. `show` does not run Git, call
|
|
33
|
-
GitHub, use the network, or write files.
|
|
12
|
+
Requires an authenticated GitHub CLI session (`gh auth login`) and a checkout on GitHub.com or
|
|
13
|
+
GitHub Enterprise. Run `gh auth status` to verify authentication.
|
|
34
14
|
|
|
35
15
|
## Works with
|
|
36
16
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
| Package | Relationship | Purpose |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| [`@henryqw/pi-footer`](https://pi.henry.wang/extensions/pi-footer) | Improves | Shows current-branch pull-request status in the footer. |
|
|
20
|
+
| [`@henryqw/pi-herdr`](https://pi.henry.wang/extensions/pi-herdr) | Improves | Adds the pull-request number to a Herdr workspace label after creation. |
|
|
21
|
+
| [`@henryqw/pi-process`](https://pi.henry.wang/packages/pi-process) | Required | Runs bounded child processes used by Git and GitHub workflows. |
|
|
42
22
|
|
|
43
23
|
## Use
|
|
44
24
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
25
|
+
In a GitHub checkout, run `/pr`. It reads fresh pull-request and local state, then runs one route or
|
|
26
|
+
explains why action is blocked. The pull-request hostname selects its GitHub API host, and the
|
|
27
|
+
extension works outside Herdr.
|
|
48
28
|
|
|
49
|
-
|
|
29
|
+
Commands are for people; tools and skills are for the agent. The extension exposes these interfaces:
|
|
50
30
|
|
|
51
31
|
| Surface | Type | Purpose |
|
|
52
32
|
| --- | --- | --- |
|
|
53
|
-
| `/pr [--base BRANCH] [creation instructions]` | command |
|
|
33
|
+
| `/pr [--base BRANCH] [creation instructions]` | command | Discover the current pull request and run its next safe route; base and instructions apply only to creation. |
|
|
54
34
|
| `/pr --feedback` | command | Explicitly start or resume the guarded feedback sweep. |
|
|
55
|
-
|
|
|
56
|
-
|
|
|
35
|
+
| `pi_pr_create` | tool | Agent-only guarded actions for pull-request creation. |
|
|
36
|
+
| `pi_pr_fix_ci` | tool | Agent-only guarded actions for repairing failed GitHub Actions. |
|
|
37
|
+
| `pi_pr_sweep` | tool | Agent-only guarded actions for reviewing and resolving feedback. |
|
|
38
|
+
| `pi_pr_update_branch` | tool | Agent-only guarded actions for updating a pull-request branch. |
|
|
39
|
+
| `pi-pr-comment-sweep` | skill | Agent workflow for triaging feedback and resolving addressed review threads. |
|
|
40
|
+
| `pi-pr-create` | skill | Agent workflow for safely creating and publishing a pull request. |
|
|
41
|
+
| `pi-pr-fix-ci` | skill | Agent workflow for diagnosing and publishing a scoped CI fix. |
|
|
42
|
+
| `pi-pr-update-branch` | skill | Agent workflow for merging the exact base revision into the pull-request branch. |
|
|
43
|
+
| `Footer` | ui | Show a linked `PR #number` and one plain-language status. |
|
|
44
|
+
| `Widget` | ui | Show one action hint or transient routing status. |
|
|
45
|
+
| Confirmation | ui | Ask before linking an inferred branch or squash-merging a pull request. |
|
|
46
|
+
| Notification | ui | Report blocked discovery, no-action status, refresh errors, and Herdr rename warnings. |
|
|
47
|
+
| `node skills/pi-pr-comment-sweep/scripts/pr-feedback.mjs` | command | Read-only feedback diagnostic CLI; supported commands and arguments are below. |
|
|
48
|
+
|
|
49
|
+
For creation, put an optional base branch first. For example, run `/pr --base release/2026 Keep the
|
|
50
|
+
title concise.` The base is a branch name, not a host or repository. Only creation accepts the base
|
|
51
|
+
and remaining guidance; other routes reject them instead of ignoring them. Run `/pr --feedback` to
|
|
52
|
+
explicitly start or resume a feedback sweep for actionable conversation comments that do not select
|
|
53
|
+
the sweep automatically. It cannot be combined with a base, other options, or instructions.
|
|
54
|
+
|
|
55
|
+
The footer shows the pull request and status. Actionable widgets omit duplicate identity and status.
|
|
56
|
+
Each uses one semantic status icon, a space, and a plain `Run /pr to …` route. `✗` marks errors, `!`
|
|
57
|
+
warnings, `✓` success, and `●` accent or neutral routes. In TUI, only the icon uses a theme color.
|
|
58
|
+
RPC and non-TUI output use the same plain text without ANSI.
|
|
59
|
+
|
|
60
|
+
The widget switches to `⠋ Checking pull request…` as soon as `/pr` starts discovery. The braille
|
|
61
|
+
spinner animates in TUI mode; RPC receives one plain static line. The footer stays unchanged. The
|
|
62
|
+
routing widget clears after route selection and before any prompt, notification, mutation, or
|
|
63
|
+
workflow dispatch.
|
|
64
|
+
|
|
65
|
+
### Feedback snapshots
|
|
66
|
+
|
|
67
|
+
Run the bundled read-only diagnostic CLI from the installed package directory:
|
|
57
68
|
|
|
58
|
-
|
|
69
|
+
```bash
|
|
70
|
+
node skills/pi-pr-comment-sweep/scripts/pr-feedback.mjs fetch [--pr PR] (--out FILE | --json)
|
|
71
|
+
node skills/pi-pr-comment-sweep/scripts/pr-feedback.mjs show --snapshot FILE --id ID
|
|
72
|
+
node skills/pi-pr-comment-sweep/scripts/pr-feedback.mjs checks [--pr PR] --expected-head SHA
|
|
73
|
+
node skills/pi-pr-comment-sweep/scripts/pr-feedback.mjs self-test
|
|
74
|
+
```
|
|
59
75
|
|
|
60
|
-
|
|
76
|
+
`fetch` prints a compact feedback index with IDs, kinds, states, authors, locations, and parent IDs
|
|
77
|
+
as needed; it does not print comment or review bodies. With `--out`, it atomically replaces `FILE`
|
|
78
|
+
as a mode-0600 file but does not change the parent directory's permissions. The saved snapshot still
|
|
79
|
+
contains the complete feedback, as does `fetch --json` output. Read one item with `show`.
|
|
80
|
+
|
|
81
|
+
`show` prints one JSON record with its exact stored body and fields. A thread record includes child
|
|
82
|
+
IDs without child bodies; treat it as a container and inspect each `thread_comment` ID directly. Do
|
|
83
|
+
not call `show` on the parent only to find children. Show the parent only when it has no child or
|
|
84
|
+
when parent-level metadata is needed. Issue independent `show` lookups in one tool-call round. A
|
|
85
|
+
nested comment includes only its parent thread's ID, state, and location. Missing, unknown,
|
|
86
|
+
duplicate, or ambiguous IDs fail. `show` does not run Git, call GitHub, use the network, or write
|
|
87
|
+
files.
|
|
88
|
+
|
|
89
|
+
`checks` verifies the current pull request and its checks against the supplied full head SHA.
|
|
90
|
+
`self-test` checks the bundled CLI's local behavior.
|
|
61
91
|
|
|
62
92
|
## Flow
|
|
63
93
|
|
|
64
|
-
Each footer entry is one linked `PR #number` plus one plain-language status: `N unresolved`,
|
|
94
|
+
Each footer entry is one linked `PR #number` plus one plain-language status: `N unresolved`,
|
|
95
|
+
`draft`, `open`, `approved`, `CI running`, `CI failed`, `changes requested`, `base update required`,
|
|
96
|
+
`merge conflict`, `merge-ready`, `merged`, or `closed`. Colors support the text; they do not carry
|
|
97
|
+
meaning alone.
|
|
65
98
|
|
|
66
99
|

|
|
67
100
|
|
|
@@ -80,47 +113,81 @@ Each footer entry is one linked `PR #number` plus one plain-language status: `N
|
|
|
80
113
|
| No-action state | Report the state without taking action. |
|
|
81
114
|
| Merge-ready pull request | Ask for final confirmation, recheck fresh state, and squash-merge if confirmed. |
|
|
82
115
|
|
|
83
|
-
`pi-pr-create` selects its base in this order: the leading `/pr --base BRANCH`, one
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
`pi-pr-create` selects its base in this order: the leading `/pr --base BRANCH`, one
|
|
117
|
+
`branch.<branch>.gh-merge-base` value, then the default branch of validated `origin`. It captures
|
|
118
|
+
the selected base OID and merge-base. Creation requires a commit ahead or ordinary pending work,
|
|
119
|
+
including untracked files. A Git operation in progress does not count as pending work. If the
|
|
120
|
+
current branch is the selected base, pi-pr stays silent because GitHub cannot create a pull request
|
|
121
|
+
from a ref to itself.
|
|
122
|
+
|
|
123
|
+
The base always comes from validated `origin`. The head may use that repository or a fork with the
|
|
124
|
+
same GitHub source. Base and head must use the same GitHub host. Other fork relationships stop
|
|
125
|
+
before mutation.
|
|
126
|
+
|
|
127
|
+
Creation merges the captured base commit before validation and push. It resolves clear conflicts and
|
|
128
|
+
stops when the base or conflict intent is ambiguous.
|
|
129
|
+
|
|
130
|
+
A configured target never changes branch upstream settings. Without a target, the helper pushes the
|
|
131
|
+
captured OID to the local branch ref on validated `origin` and fetches its tracking ref. It leaves
|
|
132
|
+
upstream unset. It creates or updates and validates the exact PR before setting and verifying
|
|
133
|
+
upstream. A failed setup rolls back only unchanged helper-owned settings. If configuration changed
|
|
134
|
+
concurrently, it stops without overwriting it. Retrying `publish` resumes setup without another push
|
|
135
|
+
or PR mutation.
|
|
136
|
+
|
|
137
|
+
Without a configured push target, discovery checks validated remotes for the same branch ref. One
|
|
138
|
+
exact open PR becomes an inferred target. `/pr` names the exact `remote/ref` and asks before linking
|
|
139
|
+
it. The extension revalidates the branch, PR, remote OID, and Git configuration before mutation. It
|
|
140
|
+
rolls back its upstream and remote-tracking changes if final verification fails.
|
|
141
|
+
|
|
142
|
+
Multiple candidate remotes, multiple matching PRs, OID mismatches, and unsafe Git push configuration
|
|
143
|
+
block routing. A published ref with no PR also blocks creation. If no candidate ref exists, creation
|
|
144
|
+
uses only a validated `origin` destination.
|
|
145
|
+
|
|
146
|
+
The creation workflow repeats destination, remote OID, PR, and configuration checks immediately
|
|
147
|
+
before pushing. It pushes to the saved validated URL, not a mutable remote name. Every push uses the
|
|
148
|
+
saved remote OID as an exact lease. Existing refs must also be ancestors of the captured local OID.
|
|
149
|
+
A missing ref uses an empty lease as a create-only compare-and-swap.
|
|
150
|
+
|
|
151
|
+
Each helper workflow receives a random run ID and its first action. The run stays bound to one
|
|
152
|
+
session, canonical worktree, route, and fresh authority. Helper calls from another run, session,
|
|
153
|
+
worktree, or route fail.
|
|
154
|
+
|
|
155
|
+
For comment sweeps, `/pr` checks the package recovery file without changing it. It selects `start`
|
|
156
|
+
when recovery is absent, and `resume` only when valid recovery matches the fresh route authority.
|
|
157
|
+
Invalid recovery stays unchanged and blocks dispatch with its path and reason.
|
|
158
|
+
|
|
159
|
+
`/pr --feedback` uses the same discovery, reservation, recovery, and guard checks. It can select the
|
|
160
|
+
sweep even when CI failure or merge readiness would otherwise select another route. Without the
|
|
161
|
+
flag, route priority stays unchanged. Direct skill or `pi_pr_*` tool calls cannot create route
|
|
162
|
+
authority; run `/pr` to reserve a fresh route.
|
|
163
|
+
|
|
164
|
+
Only one helper run can exist at a time. Most runs expire when the agent settles. A create or
|
|
165
|
+
branch-update conflict stays available for one user-guided continuation, then expires after that
|
|
166
|
+
continuation settles. Session replacement and shutdown forget the run without aborting or cleaning a
|
|
167
|
+
pending merge.
|
|
168
|
+
|
|
169
|
+
After a `/pr` create workflow settles, the extension waits for a refresh that finds a configured
|
|
170
|
+
current PR. Failed or empty discovery leaves one rename pending for a later refresh. A restored
|
|
171
|
+
configured PR completes the rename even when GitHub reports it as merged or closed. It then prefixes
|
|
172
|
+
the Herdr workspace label with `#<number> • `. It removes repeated leading `#<number> • ` prefixes
|
|
173
|
+
and legacy trailing ` · PR #<number>` suffixes before adding one current prefix. The remaining
|
|
174
|
+
workspace name must be non-empty. It renames only the workspace, requires `HERDR_ENV=1` and a
|
|
175
|
+
non-empty, trimmed `HERDR_WORKSPACE_ID`, and does nothing outside Herdr. Each Herdr command has a
|
|
176
|
+
10-second timeout. If Herdr lookup, JSON validation, or rename fails, the PR and normal UI refresh
|
|
177
|
+
remain available; the extension warns with `Herdr workspace rename failed: <error>`.
|
|
178
|
+
|
|
179
|
+
Current-branch discovery reads pull requests associated with the exact push repository ref. It does
|
|
180
|
+
not run a global branch search. It finds a fork-head PR whose base is an upstream repository. A
|
|
181
|
+
unique historical match uses the exact remote push-ref OID, not local HEAD.
|
|
182
|
+
|
|
183
|
+
A no-action state includes drafts, merged or closed pull requests, unsupported failed CI, pending
|
|
184
|
+
review, and blocked merge policy. Running CI blocks merge but not other mutating workflows. A dirty
|
|
185
|
+
tree or mismatched local HEAD also blocks a mutating workflow.
|
|
120
186
|
|
|
121
187
|
### Route priority
|
|
122
188
|
|
|
123
|
-
A missing pull request uses creation. For an existing pull request, the first matching condition
|
|
189
|
+
A missing pull request uses creation. For an existing pull request, the first matching condition
|
|
190
|
+
wins:
|
|
124
191
|
|
|
125
192
|
1. Merged, closed, or draft: no action.
|
|
126
193
|
2. Base update required or merge conflict. Run only with a clean tree and equal local and PR heads.
|
|
@@ -129,52 +196,105 @@ A missing pull request uses creation. For an existing pull request, the first ma
|
|
|
129
196
|
5. Waiting or local safety block: no action.
|
|
130
197
|
6. Merge-ready: allow clean local HEAD equal to or behind the PR head. Confirm, then merge directly.
|
|
131
198
|
|
|
132
|
-
Ordinary conversation comments do not trigger a route or block a merge. Changes requested and
|
|
199
|
+
Ordinary conversation comments do not trigger a route or block a merge. Changes requested and
|
|
200
|
+
unresolved review threads can select the package comment sweep. Use `/pr --feedback` when a
|
|
201
|
+
conversation comment needs action.
|
|
133
202
|
|
|
134
|
-
The comment sweep resolves its bundled helper and references from the installed package skill path.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
The sweep runs existing non-destructive checks on the clean committed `HEAD` before publishing. Finalization reruns them as a later state guard.
|
|
203
|
+
The comment sweep resolves its bundled helper and references from the installed package skill path.
|
|
204
|
+
It does not require an external `jq` executable. After publishing, `refresh` freezes the complete
|
|
205
|
+
latest feedback and returns only IDs and kinds. Use `show` to inspect every fresh item. A second
|
|
206
|
+
guarded `record` must cover that exact snapshot before resolution or finalization and keeps the
|
|
207
|
+
paths from the initial record. The sweep runs existing non-destructive checks on the clean committed
|
|
208
|
+
`HEAD` before publishing. Finalization reruns them as a later state guard.
|
|
141
209
|
|
|
142
210
|
### Refresh
|
|
143
211
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
212
|
+
PR discovery starts in the background at session start, so the Pi footer appears before PR status
|
|
213
|
+
is ready. On a session switch, the previous status and action hint clear immediately; new ones
|
|
214
|
+
appear after discovery. A directory outside a Git worktree stays silent. Other discovery failures
|
|
215
|
+
show `PR · status unavailable` and only a generic error.
|
|
216
|
+
|
|
217
|
+
The footer and widget refresh after local commits, PR creation, pushes, and each dispatched
|
|
218
|
+
workflow settles. During creation, intermediate refreshes wait until the workflow settles. They
|
|
219
|
+
also refresh after successful delegated tasks. There is no periodic presentation refresh, so
|
|
220
|
+
external changes may leave them stale indefinitely. `/pr` cancels any pending presentation lookup
|
|
221
|
+
and reads fresh state before routing or acting; it remains authoritative.
|
|
222
|
+
|
|
223
|
+
The create widget stays hidden on a clean branch with no commit ahead. It appears for a commit ahead
|
|
224
|
+
or ordinary pending work. It stays hidden during a Git operation and when the current branch is the
|
|
225
|
+
selected base. `/pr` replaces any hint with routing feedback while it selects a route. The feedback
|
|
226
|
+
clears before route interaction. A dispatched workflow keeps the widget hidden until the agent
|
|
227
|
+
settles. Direct and no-action routes refresh it after completion. A failed command restores the
|
|
228
|
+
prior hint and schedules a refresh, except when fresh lookup hits the GitHub API quota: it shows the
|
|
229
|
+
sanitized message `GitHub API rate limit exhausted; retry after GitHub resets it` and does not
|
|
230
|
+
immediately retry.
|
|
231
|
+
|
|
232
|
+
Presentation uses route priority, so draft appears before running CI. `/pr` reads fresh state before
|
|
233
|
+
routing or merging. The command is authoritative for actions.
|
|
234
|
+
|
|
235
|
+
## State and storage
|
|
236
|
+
|
|
237
|
+
The extension records one configured PR identity in the Pi session. It stores only the PR URL,
|
|
238
|
+
number, host, head identity, and configured target identity. It does not store lifecycle, CI,
|
|
239
|
+
review, merge readiness, or base state. Event-driven refreshes do not add duplicate entries, and no
|
|
240
|
+
repository cache file is created.
|
|
241
|
+
|
|
242
|
+
Normal discovery always runs first. If the configured remote ref was deleted, the footer and `/pr`
|
|
243
|
+
may reload the exact observed PR URL. The current host, repository, branch, remote, ref, and local
|
|
244
|
+
HEAD must still match the observation. Repository names use case-insensitive GitHub matching. The
|
|
245
|
+
GitHub response must match the observed URL, host, repository, head ref, head OID, and PR number.
|
|
246
|
+
GitHub supplies fresh mutable state. Invalid session data is ignored. A failed GitHub lookup stops
|
|
247
|
+
routing and cannot start PR creation.
|
|
248
|
+
|
|
249
|
+
Comment sweeps own one versioned recovery file per canonical worktree at
|
|
250
|
+
`<agent-dir>/config/pi-pr/sweep/<worktree-id>/state.json`. The file is private, bounded to 1 MiB,
|
|
251
|
+
and replaced atomically. It contains the frozen PR authority, original head and lease, complete
|
|
252
|
+
feedback, exact ledger, owned paths, and mutation attempts. A missing file allows a fresh `start`; a
|
|
253
|
+
valid file matching the fresh route authority allows `resume`. Resume rechecks the canonical
|
|
254
|
+
worktree, local changes, PR linkage, and remote head under its lock, and reconciles an attempted
|
|
255
|
+
push or thread resolution before issuing a new epoch and run ID. Calls from the old run then fail.
|
|
256
|
+
|
|
257
|
+
A completed post-publish `refresh` stores the new complete snapshot before any replacement ledger.
|
|
258
|
+
Recovery keeps that snapshot in `refresh-pending`, with its new generation and fingerprint; status
|
|
259
|
+
exposes only item IDs and kinds. Use `show` with the resumed guard to inspect every frozen item,
|
|
260
|
+
then `record` without `ownedPaths` to supply exact complete coverage for that snapshot. Resolution
|
|
261
|
+
and finalization stay blocked until this record succeeds. Malformed, oversized, obsolete,
|
|
262
|
+
wrong-worktree, or route-mismatched recovery is preserved and blocks dispatch. Never repair, move,
|
|
263
|
+
replace, or delete it automatically; report the state path and exact blocker. An unknown mutation is
|
|
264
|
+
never replayed. If reconciliation cannot prove its exact result, stop and report the state path and
|
|
265
|
+
blocker.
|
|
159
266
|
|
|
160
267
|
## Limits and recovery
|
|
161
268
|
|
|
162
|
-
- `/pr` accepts either standalone `--feedback` or creation syntax with leading `--base BRANCH` and
|
|
269
|
+
- `/pr` accepts either standalone `--feedback` or creation syntax with leading `--base BRANCH` and
|
|
270
|
+
optional guidance. It rejects unknown or conflicting options. It does not open a browser.
|
|
163
271
|
- It does not run `/done` or `/sweep`.
|
|
164
|
-
- Presentation refreshes do not auto-triage comments or start a workflow. The package comment sweep
|
|
272
|
+
- Presentation refreshes do not auto-triage comments or start a workflow. The package comment sweep
|
|
273
|
+
starts or resumes only when an explicit `/pr` selects it.
|
|
165
274
|
- It does not enable auto-merge or add a merge queue.
|
|
166
|
-
- It does not rebase the local branch, overwrite concurrent remote updates, delete branches, or
|
|
167
|
-
|
|
168
|
-
|
|
275
|
+
- It does not rebase the local branch, overwrite concurrent remote updates, delete branches, or
|
|
276
|
+
clean up worktrees. Creation uses exact leases plus ancestry checks; an empty lease is only an
|
|
277
|
+
atomic absence check.
|
|
278
|
+
- Creation, discovery, and comment-sweep pushes require one unambiguous push URL for the configured
|
|
279
|
+
destination.
|
|
280
|
+
- Presentation fetches use that exact push URL and exact advertised OID. They do not use shared
|
|
281
|
+
fetch state.
|
|
169
282
|
- A pull request that GitHub reports as behind requires a base update.
|
|
170
|
-
- Direct merges always use squash. GitHub rejects the mutation if repository policy does not allow
|
|
171
|
-
|
|
172
|
-
-
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
|
|
283
|
+
- Direct merges always use squash. GitHub rejects the mutation if repository policy does not allow
|
|
284
|
+
it.
|
|
285
|
+
- Before merge, `/pr` fetches the exact head OID from the validated push URL without shared fetch
|
|
286
|
+
state.
|
|
287
|
+
- A merge, rebase, cherry-pick, revert, or sequencer state blocks direct merge, even when `git
|
|
288
|
+
status` is empty.
|
|
289
|
+
- A branch update resolves the base repository ref directly. It stops if that ref moves before merge
|
|
290
|
+
or push.
|
|
291
|
+
- Before a comment-sweep push, it revalidates the configured destination, full PR identity, and
|
|
292
|
+
local HEAD. It pushes the captured OID.
|
|
293
|
+
- CI repair resolves workflow runs from check-suite IDs. It does not treat HTML details links as
|
|
294
|
+
identity.
|
|
176
295
|
- It streams a bounded failed-step log tail and runs one narrow local reproducer before editing.
|
|
177
|
-
- Before push, CI repair revalidates the saved destination, open PR, failure evidence, and repair
|
|
296
|
+
- Before push, CI repair revalidates the saved destination, open PR, failure evidence, and repair
|
|
297
|
+
HEAD.
|
|
178
298
|
- An already-published local HEAD needs no second push.
|
|
179
299
|
- Direct merge requires final confirmation and a fresh readiness check.
|
|
180
300
|
- After a successful merge, the create widget stays hidden until a new local commit.
|
package/extensions/pr-github.ts
CHANGED
|
@@ -1240,18 +1240,19 @@ async function readRemoteAuthority(
|
|
|
1240
1240
|
if (urls.length !== 1) fail(action, `multiple ${kind} URLs are configured`);
|
|
1241
1241
|
return parseRemoteUrl(urls[0], kind);
|
|
1242
1242
|
};
|
|
1243
|
-
const readRepository = async (remoteUrl: PushUrl, kind: "push" | "fetch"): Promise<
|
|
1244
|
-
const
|
|
1245
|
-
const result = await execute(pi, context, action, "gh", [
|
|
1243
|
+
const readRepository = async (remoteUrl: PushUrl, kind: "push" | "fetch"): Promise<string> => {
|
|
1244
|
+
const result = await execute(pi, context, `Read ${kind} repository`, "gh", [
|
|
1246
1245
|
"repo", "view", remoteUrl.locator, "--json", "nameWithOwner,url",
|
|
1247
1246
|
]);
|
|
1248
|
-
return
|
|
1247
|
+
return result.stdout;
|
|
1249
1248
|
};
|
|
1250
1249
|
|
|
1251
1250
|
const pushUrl = await readUrl("push");
|
|
1252
|
-
const
|
|
1251
|
+
const pushOutput = await readRepository(pushUrl, "push");
|
|
1252
|
+
const pushRepository = parseRemoteRepository(pushOutput, pushUrl, "push");
|
|
1253
1253
|
const fetchUrl = await readUrl("fetch");
|
|
1254
|
-
const
|
|
1254
|
+
const fetchOutput = fetchUrl.locator === pushUrl.locator ? pushOutput : await readRepository(fetchUrl, "fetch");
|
|
1255
|
+
const fetchRepository = parseRemoteRepository(fetchOutput, fetchUrl, "fetch");
|
|
1255
1256
|
if (
|
|
1256
1257
|
fetchRepository.host !== pushRepository.host ||
|
|
1257
1258
|
fetchRepository.normalizedName !== pushRepository.normalizedName
|
package/extensions/pr.ts
CHANGED
|
@@ -717,12 +717,14 @@ export default function pullRequestExtension(
|
|
|
717
717
|
}
|
|
718
718
|
});
|
|
719
719
|
|
|
720
|
-
pi.on("session_start",
|
|
720
|
+
pi.on("session_start", (_event, ctx) => {
|
|
721
721
|
stop();
|
|
722
722
|
observation = latestObservation(ctx);
|
|
723
723
|
if (!ctx.hasUI) return;
|
|
724
724
|
context = ctx;
|
|
725
|
-
|
|
725
|
+
ctx.ui.setStatus(UI_KEY, undefined);
|
|
726
|
+
ctx.ui.setWidget(UI_KEY, undefined);
|
|
727
|
+
refreshInBackground();
|
|
726
728
|
});
|
|
727
729
|
|
|
728
730
|
pi.on("session_shutdown", stop);
|
|
@@ -779,6 +781,7 @@ export default function pullRequestExtension(
|
|
|
779
781
|
description: "[--feedback | --base <branch> [instructions]] — Run the current branch pull request next step",
|
|
780
782
|
handler: async (args, ctx) => {
|
|
781
783
|
if (!ctx.hasUI || !context) return;
|
|
784
|
+
cancelRefresh();
|
|
782
785
|
const generation = sessionGeneration;
|
|
783
786
|
const invocation = ++commandGeneration;
|
|
784
787
|
activeInvocations.set(invocation, "routing");
|
package/package.json
CHANGED