patchrelay 0.35.15 → 0.35.16

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,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.35.15",
4
- "commit": "da544a1edbf6",
5
- "builtAt": "2026-04-08T09:10:23.366Z"
3
+ "version": "0.35.16",
4
+ "commit": "1915fecc2b8c",
5
+ "builtAt": "2026-04-08T09:31:00.146Z"
6
6
  }
@@ -186,10 +186,10 @@ export function App({ baseUrl, bearerToken, initialIssueKey }) {
186
186
  else if (input === "k" || key.upArrow) {
187
187
  dispatch({ type: "detail-scroll", delta: -1 });
188
188
  }
189
- else if (key.pageDown || (key.ctrl && input === "d")) {
189
+ else if (key.pageDown || (key.ctrl && input === "d") || (key.ctrl && key.downArrow)) {
190
190
  dispatch({ type: "detail-page", direction: "down" });
191
191
  }
192
- else if (key.pageUp || (key.ctrl && input === "u")) {
192
+ else if (key.pageUp || (key.ctrl && input === "u") || (key.ctrl && key.upArrow)) {
193
193
  dispatch({ type: "detail-page", direction: "up" });
194
194
  }
195
195
  else if (key.home) {
@@ -4,7 +4,7 @@ export function HelpBar({ view, follow, detailTab }) {
4
4
  let text;
5
5
  if (view === "detail") {
6
6
  const tabHint = detailTab === "history" ? "t: timeline" : "h: history";
7
- text = [tabHint, "j/k: scroll", "PgUp/PgDn: page", "[ ]: issue", "Home/End: jump", `f: live ${follow ? "on" : "off"}`, "p: prompt", "s: stop", "r: retry"]
7
+ text = [tabHint, "j/k: scroll", "Ctrl-U/Ctrl-D: page", "[ ]: issue", "Home/End: jump", `f: live ${follow ? "on" : "off"}`, "p: prompt", "s: stop", "r: retry"]
8
8
  .filter(Boolean)
9
9
  .join(" ");
10
10
  }
@@ -70,7 +70,7 @@ function buildHeaderLines(input, width) {
70
70
  const issue = input.issue;
71
71
  const session = sessionDisplay(issue);
72
72
  const stage = stageDisplay(issue);
73
- const facts = buildFacts(issue, input.issueContext);
73
+ const facts = buildFactSegments(issue, input.issueContext);
74
74
  const meta = buildMeta(input.tokenUsage, input.diffSummary, input.issueContext);
75
75
  const headerSegments = [
76
76
  { text: issue.issueKey ?? issue.projectId, bold: true },
@@ -81,7 +81,7 @@ function buildHeaderLines(input, width) {
81
81
  ];
82
82
  if (facts.length > 0) {
83
83
  headerSegments.push({ text: " ", dimColor: true });
84
- headerSegments.push({ text: facts.join(" · "), dimColor: true });
84
+ headerSegments.push(...joinFactSegments(facts));
85
85
  }
86
86
  if (input.activeRunStartedAt) {
87
87
  headerSegments.push({ text: " ", dimColor: true });
@@ -394,28 +394,38 @@ function renderSideTripLines(trip, runOffset, width) {
394
394
  }));
395
395
  return lines;
396
396
  }
397
- function buildFacts(issue, issueContext) {
397
+ function buildFactSegments(issue, issueContext) {
398
398
  const facts = [];
399
399
  const rereviewNeeded = isRereviewNeeded(issue);
400
400
  if (issue.prNumber !== undefined)
401
- facts.push(`PR #${issue.prNumber}`);
401
+ facts.push([{ text: `PR #${issue.prNumber}`, color: "cyan" }]);
402
402
  if (issue.prReviewState === "approved")
403
- facts.push("approved");
403
+ facts.push([{ text: "approved", color: "green" }]);
404
404
  else if (rereviewNeeded)
405
- facts.push("re-review needed");
405
+ facts.push([{ text: "re-review needed", color: "yellow" }]);
406
406
  else if (issue.prReviewState === "changes_requested")
407
- facts.push("changes requested");
407
+ facts.push([{ text: "changes requested", color: "yellow" }]);
408
408
  if (issue.waitingReason && issue.sessionState === "waiting_input")
409
- facts.push(issue.waitingReason);
409
+ facts.push([{ text: issue.waitingReason, color: "yellow" }]);
410
410
  const checks = prChecksFact({
411
411
  ...issue,
412
412
  latestFailureCheckName: issueContext?.latestFailureCheckName ?? issue.latestFailureCheckName,
413
413
  });
414
414
  if (checks) {
415
- facts.push(checks.text);
415
+ facts.push([{ text: checks.text, color: checks.color }]);
416
416
  }
417
417
  return facts;
418
418
  }
419
+ function joinFactSegments(facts) {
420
+ const segments = [];
421
+ for (const [index, fact] of facts.entries()) {
422
+ if (index > 0) {
423
+ segments.push({ text: " · ", dimColor: true });
424
+ }
425
+ segments.push(...fact);
426
+ }
427
+ return segments;
428
+ }
419
429
  function buildMeta(tokenUsage, diffSummary, issueContext) {
420
430
  const meta = [];
421
431
  if (tokenUsage)
@@ -127,7 +127,7 @@ function detailStateAfterLayout(state, viewportRows, contentRows) {
127
127
  detailContentRows: Math.max(0, contentRows),
128
128
  };
129
129
  const maxOffset = maxDetailScrollOffset(nextState.detailContentRows, nextState.detailViewportRows);
130
- const shouldFollow = state.follow || isDetailNearBottom(state.detailScrollOffset, state.detailContentRows, state.detailViewportRows);
130
+ const shouldFollow = state.follow;
131
131
  const nextOffset = shouldFollow ? maxOffset : Math.min(state.detailScrollOffset, maxOffset);
132
132
  return {
133
133
  detailViewportRows: nextState.detailViewportRows,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.35.15",
3
+ "version": "0.35.16",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {