patchrelay 0.24.1 → 0.25.0

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.24.1",
4
- "commit": "9aedb538a702",
5
- "builtAt": "2026-03-26T16:38:55.273Z"
3
+ "version": "0.25.0",
4
+ "commit": "9c5a9d135320",
5
+ "builtAt": "2026-03-26T16:55:56.222Z"
6
6
  }
@@ -53,15 +53,22 @@ const STATE_LABELS = {
53
53
  failed: "failed",
54
54
  };
55
55
  // ─── Sub-components ──────────────────────────────────────────────
56
- function RunLine({ run, index }) {
56
+ function RunLine({ run, index, gutter }) {
57
57
  const label = RUN_LABELS[run.runType] ?? run.runType;
58
58
  const dur = run.endedAt
59
59
  ? formatDuration(run.startedAt, run.endedAt)
60
60
  : undefined;
61
61
  const isActive = run.status === "running";
62
- return (_jsxs(Box, { children: [_jsxs(Text, { color: runStatusColor(run.status), children: [runStatusSymbol(run.status), " "] }), _jsxs(Text, { dimColor: true, children: ["#", index + 1, " "] }), _jsxs(Text, { children: ["(", label, ")"] }), dur && _jsxs(Text, { dimColor: true, children: [" ", dur] }), isActive && _jsx(Text, { dimColor: true, children: " ..." })] }));
62
+ // Report stats
63
+ const stats = [];
64
+ if (run.messageCount !== undefined)
65
+ stats.push(`${run.messageCount} msgs`);
66
+ if (run.commandCount)
67
+ stats.push(`${run.commandCount} cmds`);
68
+ if (run.fileChangeCount)
69
+ stats.push(`${run.fileChangeCount} files`);
70
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: runStatusColor(run.status), children: [runStatusSymbol(run.status), " "] }), _jsxs(Text, { dimColor: true, children: ["#", index + 1, " "] }), _jsxs(Text, { children: ["(", label, ")"] }), dur && _jsxs(Text, { dimColor: true, children: [" ", dur] }), isActive && _jsx(Text, { dimColor: true, children: " ..." }), stats.length > 0 && _jsxs(Text, { dimColor: true, children: [" ", stats.join(", ")] })] }), run.lastMessage && (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: [gutter, " "] }), _jsx(Text, { dimColor: true, wrap: "truncate", children: run.lastMessage.slice(0, 120) })] }))] }));
63
71
  }
64
- const MAX_VISIBLE_RUNS = 5;
65
72
  function RunSummary({ runs }) {
66
73
  const completed = runs.filter((r) => r.status === "completed").length;
67
74
  const failed = runs.filter((r) => r.status === "failed").length;
@@ -81,7 +88,7 @@ function PlanSteps({ plan }) {
81
88
  function SideTripBlock({ trip, runOffset, isLast, }) {
82
89
  const stateLabel = STATE_LABELS[trip.state] ?? trip.state;
83
90
  const hasReturn = trip.returnedAt && trip.returnState !== trip.state;
84
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u250c " }), _jsx(Text, { color: "magenta", bold: true, children: stateLabel }), _jsxs(Text, { dimColor: true, children: [" ", formatTime(trip.enteredAt)] })] }), trip.reason && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2502 " }), _jsx(Text, { dimColor: true, children: trip.reason })] })), trip.runs.map((run, ri) => (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2502 " }), _jsx(RunLine, { run: run, index: runOffset + ri })] }, `st-run-${run.id}`))), hasReturn ? (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2514\u2192 " }), _jsx(Text, { children: STATE_LABELS[trip.returnState] ?? trip.returnState }), trip.returnedAt && _jsxs(Text, { dimColor: true, children: [" ", formatTime(trip.returnedAt)] })] })) : (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2514\u2500" }), _jsx(Text, { dimColor: true, children: " (active)" })] })), !isLast && (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: " \u2502" }) }))] }));
91
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u250c " }), _jsx(Text, { color: "magenta", bold: true, children: stateLabel }), _jsxs(Text, { dimColor: true, children: [" ", formatTime(trip.enteredAt)] })] }), trip.reason && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2502 " }), _jsx(Text, { dimColor: true, children: trip.reason })] })), trip.runs.map((run, ri) => (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2502 " }), _jsx(RunLine, { run: run, index: runOffset + ri, gutter: " \u2502 \u2502" })] }, `st-run-${run.id}`))), hasReturn ? (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2514\u2192 " }), _jsx(Text, { children: STATE_LABELS[trip.returnState] ?? trip.returnState }), trip.returnedAt && _jsxs(Text, { dimColor: true, children: [" ", formatTime(trip.returnedAt)] })] })) : (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: " \u2502 \u2514\u2500" }), _jsx(Text, { dimColor: true, children: " (active)" })] })), !isLast && (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: " \u2502" }) }))] }));
85
92
  }
86
93
  function MainPathNode({ node, isLast, runOffset, plan, activeRunId, }) {
87
94
  const stateLabel = STATE_LABELS[node.state] ?? node.state;
@@ -89,7 +96,7 @@ function MainPathNode({ node, isLast, runOffset, plan, activeRunId, }) {
89
96
  const stateColor = node.isCurrent ? "green" : "white";
90
97
  const hasActiveRun = node.runs.some((r) => r.id === activeRunId);
91
98
  const gutter = isLast && node.sideTrips.length === 0 ? " " : " \u2502 ";
92
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: stateColor, bold: node.isCurrent, children: [" ", marker, " "] }), _jsx(Text, { color: stateColor, bold: node.isCurrent, children: stateLabel }), _jsxs(Text, { dimColor: true, children: [" ", formatTime(node.enteredAt)] })] }), node.reason && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(Text, { dimColor: true, children: node.reason })] })), node.runs.length > MAX_VISIBLE_RUNS ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunSummary, { runs: node.runs })] }), node.runs.slice(0, 3).map((run, ri) => (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunLine, { run: run, index: runOffset + ri })] }, `run-${run.id}`))), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: [gutter, " ... ", node.runs.length - 4, " more"] }) }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunLine, { run: node.runs[node.runs.length - 1], index: runOffset + node.runs.length - 1 })] }, `run-${node.runs[node.runs.length - 1].id}`)] })) : (node.runs.map((run, ri) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunLine, { run: run, index: runOffset + ri })] }), run.id === activeRunId && plan && plan.length > 0 && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(PlanSteps, { plan: plan })] }))] }, `run-${run.id}`)))), node.sideTrips.length > 0 && (_jsx(Box, { flexDirection: "column", children: node.sideTrips.map((trip, ti) => {
99
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: stateColor, bold: node.isCurrent, children: [" ", marker, " "] }), _jsx(Text, { color: stateColor, bold: node.isCurrent, children: stateLabel }), _jsxs(Text, { dimColor: true, children: [" ", formatTime(node.enteredAt)] })] }), node.reason && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(Text, { dimColor: true, children: node.reason })] })), node.runs.length > 5 && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunSummary, { runs: node.runs })] })), node.runs.map((run, ri) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(RunLine, { run: run, index: runOffset + ri, gutter: gutter })] }), run.id === activeRunId && plan && plan.length > 0 && (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: gutter }), _jsx(PlanSteps, { plan: plan })] }))] }, `run-${run.id}`))), node.sideTrips.length > 0 && (_jsx(Box, { flexDirection: "column", children: node.sideTrips.map((trip, ti) => {
93
100
  // Count runs before this side-trip for numbering
94
101
  const priorSideTripRuns = node.sideTrips.slice(0, ti).reduce((acc, st) => acc + st.runs.length, 0);
95
102
  const tripRunOffset = runOffset + node.runs.length + priorSideTripRuns;
@@ -39,13 +39,23 @@ function extractTransitions(feedEvents) {
39
39
  }
40
40
  // ─── Run helpers ─────────────────────────────────────────────────
41
41
  function toRunInfo(run) {
42
- return {
42
+ const info = {
43
43
  id: run.id,
44
44
  runType: run.runType,
45
45
  status: run.status,
46
46
  startedAt: run.startedAt,
47
47
  endedAt: run.endedAt,
48
48
  };
49
+ if (run.report) {
50
+ info.messageCount = run.report.assistantMessages.length;
51
+ info.commandCount = run.report.commands.length;
52
+ info.fileChangeCount = run.report.fileChanges.length;
53
+ const lastMsg = run.report.assistantMessages[run.report.assistantMessages.length - 1];
54
+ if (lastMsg) {
55
+ info.lastMessage = lastMsg;
56
+ }
57
+ }
58
+ return info;
49
59
  }
50
60
  function runToState(run) {
51
61
  return RUN_TYPE_TO_STATE[run.runType] ?? run.runType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.24.1",
3
+ "version": "0.25.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {