@henryqw/pi-pr 6.2.2 → 6.2.3

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 CHANGED
@@ -61,9 +61,9 @@ Run `/pr` in a GitHub checkout. It reads fresh local and GitHub state, takes the
61
61
 
62
62
  Creation chooses the base from `branch.<branch>.gh-merge-base` or the validated `origin` default branch. It requires a commit ahead or ordinary pending work, including untracked files. It stays silent on the base branch itself. The head may be in a fork on the same GitHub host; other fork relationships block creation. A published ref without a PR, multiple candidate remotes or PRs, and unsafe push configuration also block it.
63
63
 
64
- Local work takes priority over other open-PR routes. Behind or diverged local HEAD blocks publication; a behind base alone never authorizes a rebase. Running CI prevents merging, not a safe earlier route. New or edited standalone comments and review bodies are assessed before merge or waiting; GitHub does not provide a resolution control for these, so they are triaged rather than marked resolved. A sweep makes scoped fixes without a second approval, but new feedback after publication waits for a later `/pr` cycle.
64
+ Local work normally takes priority over other open-PR routes, except when `/pr` finds verified, matching-branch recovery for a conflict rebase or feedback sweep; those workflows resume first. Behind or diverged local HEAD blocks publication; a behind base alone never authorizes a rebase. Running CI prevents merging, not a safe earlier route. New or edited standalone comments and review bodies are assessed before merge or waiting; GitHub does not provide a resolution control for these, so they are triaged rather than marked resolved. A sweep makes scoped fixes without a second approval, but new feedback after publication waits for a later `/pr` cycle.
65
65
 
66
- The footer shows one linked `PR #number` and a text status such as `N unresolved`, `CI failed`, `merge conflict`, or `merge-ready`. The widget shows a route hint without repeating the footer. Status text remains meaningful without color. When `/pr` begins, the widget shows `⠋ Checking pull request…` until route selection; errors use `✗`, warnings `!`, success `✓`, and neutral routes `●`.
66
+ For an identified PR, the footer shows a linked `PR #number` and a text status such as `N unresolved`, `CI failed`, `merge conflict`, or `merge-ready`. Blocked discovery and unavailable status show generic `PR` text without a number or link. The widget shows a route hint without repeating the footer. Status text remains meaningful without color. When `/pr` begins, the widget shows `⠋ Checking pull request…` until route selection; errors use `✗`, warnings `!`, success `✓`, and neutral routes `●`.
67
67
 
68
68
  ### Refresh and Herdr
69
69
 
@@ -35,42 +35,43 @@ export type PrTheme = {
35
35
  fg(color: PrStatusColor | "text", text: string): string;
36
36
  };
37
37
 
38
- export function discoveryIssueKey(issue: DiscoveryIssue): string {
39
- switch (issue.kind) {
40
- case "candidate-remotes-ambiguous":
41
- return `${issue.kind}:${[...issue.remotes].sort().join(",")}`;
42
- case "candidate-prs-ambiguous":
43
- return `${issue.kind}:${issue.urls.map((url) => url.href).sort().join(",")}`;
44
- case "candidate-oid-mismatch":
45
- return `${issue.kind}:${issue.remote}:${issue.urls.map((url) => url.href).sort().join(",")}`;
46
- case "published-without-pr":
47
- case "link-configuration":
48
- return `${issue.kind}:${issue.remote}`;
49
- case "detached-head":
50
- case "origin-invalid":
51
- case "target-invalid":
52
- return issue.kind;
53
- }
54
- }
55
-
56
- export function discoveryIssueMessage(issue: DiscoveryIssue): string {
38
+ export function discoveryIssueDetails(issue: DiscoveryIssue): { key: string; message: string } {
57
39
  switch (issue.kind) {
58
40
  case "detached-head":
59
- return "PR discovery is blocked because HEAD is detached";
60
- case "candidate-remotes-ambiguous":
61
- return `PR target is ambiguous across remotes: ${[...issue.remotes].sort().join(", ")}`;
62
- case "candidate-prs-ambiguous":
63
- return `PR target is ambiguous across pull requests: ${issue.urls.map((url) => url.href).sort().join(", ")}`;
41
+ return { key: issue.kind, message: "PR discovery is blocked because HEAD is detached" };
42
+ case "candidate-remotes-ambiguous": {
43
+ const remotes = [...issue.remotes].sort();
44
+ return {
45
+ key: `${issue.kind}:${remotes.join(",")}`,
46
+ message: `PR target is ambiguous across remotes: ${remotes.join(", ")}`,
47
+ };
48
+ }
49
+ case "candidate-prs-ambiguous": {
50
+ const urls = issue.urls.map((url) => url.href).sort();
51
+ return {
52
+ key: `${issue.kind}:${urls.join(",")}`,
53
+ message: `PR target is ambiguous across pull requests: ${urls.join(", ")}`,
54
+ };
55
+ }
64
56
  case "candidate-oid-mismatch":
65
- return `PR discovery is blocked because ${issue.remote} has a different pull request head`;
57
+ return {
58
+ key: `${issue.kind}:${issue.remote}:${issue.urls.map((url) => url.href).sort().join(",")}`,
59
+ message: `PR discovery is blocked because ${issue.remote} has a different pull request head`,
60
+ };
66
61
  case "published-without-pr":
67
- return `Branch is published on ${issue.remote}; configure it before creating a pull request`;
62
+ return {
63
+ key: `${issue.kind}:${issue.remote}`,
64
+ message: `Branch is published on ${issue.remote}; configure it before creating a pull request`,
65
+ };
68
66
  case "link-configuration":
69
- return `PR discovery cannot safely link remote ${issue.remote}; simplify the branch push configuration first`;
67
+ return {
68
+ key: `${issue.kind}:${issue.remote}`,
69
+ message: `PR discovery cannot safely link remote ${issue.remote}; simplify the branch push configuration first`,
70
+ };
70
71
  case "origin-invalid":
71
- return "PR creation is blocked because origin is not one validated GitHub destination";
72
+ return { key: issue.kind, message: "PR creation is blocked because origin is not one validated GitHub destination" };
72
73
  case "target-invalid":
73
- return "PR discovery is blocked by an invalid push target";
74
+ return { key: issue.kind, message: "PR discovery is blocked by an invalid push target" };
74
75
  }
75
76
  }
76
77
 
package/extensions/pr.ts CHANGED
@@ -30,8 +30,7 @@ import {
30
30
  } from "./pr-github.ts";
31
31
  import { isRecord, parseSingleOutputLine, runChecked } from "./pr-execution.ts";
32
32
  import {
33
- discoveryIssueKey,
34
- discoveryIssueMessage,
33
+ discoveryIssueDetails,
35
34
  formatPrFooter,
36
35
  formatPrWidget,
37
36
  projectPrDisplay,
@@ -627,9 +626,9 @@ export default function pullRequestExtension(
627
626
  ctx.ui.setStatus(UI_KEY, footer);
628
627
  reconcileWidget(ctx);
629
628
  if (discovery.kind === "blocked") {
630
- const key = discoveryIssueKey(discovery.issue);
629
+ const { key, message } = discoveryIssueDetails(discovery.issue);
631
630
  if (lastBlockedIssueKey !== key) {
632
- ctx.ui.notify(discoveryIssueMessage(discovery.issue), "warning");
631
+ ctx.ui.notify(message, "warning");
633
632
  lastBlockedIssueKey = key;
634
633
  }
635
634
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henryqw/pi-pr",
3
- "version": "6.2.2",
3
+ "version": "6.2.3",
4
4
  "description": "Run /pr to safely discover or link the current pull request, then create, update, address feedback, fix CI, or merge when ready.",
5
5
  "keywords": [
6
6
  "pi-package",