@overdeck/contracts 0.51.0 → 0.60.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.
package/dist/index.cjs CHANGED
@@ -26,6 +26,143 @@ let effect_unstable_rpc_Rpc = require("effect/unstable/rpc/Rpc");
26
26
  effect_unstable_rpc_Rpc = __toESM(effect_unstable_rpc_Rpc, 1);
27
27
  let effect_unstable_rpc_RpcGroup = require("effect/unstable/rpc/RpcGroup");
28
28
  effect_unstable_rpc_RpcGroup = __toESM(effect_unstable_rpc_RpcGroup, 1);
29
+ //#region src/backend-pane.ts
30
+ const BackendPane = effect.Schema.Struct({
31
+ /** Stable pane identity: the backend-native pane handle. */
32
+ id: effect.Schema.String,
33
+ /** Issue the pane belongs to; absent for operator conversations. */
34
+ issue: effect.Schema.optional(effect.Schema.String),
35
+ role: effect.Schema.Literals([
36
+ "work",
37
+ "worker",
38
+ "review",
39
+ "test",
40
+ "uat",
41
+ "strike",
42
+ "plan"
43
+ ]),
44
+ harness: effect.Schema.String,
45
+ model: effect.Schema.String,
46
+ state: effect.Schema.Literals([
47
+ "idle",
48
+ "working",
49
+ "blocked",
50
+ "done",
51
+ "exited",
52
+ "unknown"
53
+ ]),
54
+ /** Epoch millis the pane entered `state`; drives the `stuck` attention. */
55
+ stateSince: effect.Schema.optional(effect.Schema.Number),
56
+ /** Handle the terminal WebSocket attaches to. */
57
+ terminalId: effect.Schema.optional(effect.Schema.String),
58
+ /** Working directory of the pane (the issue workspace path). */
59
+ workspace: effect.Schema.optional(effect.Schema.String)
60
+ });
61
+ //#endregion
62
+ //#region src/derived-issue-state.ts
63
+ /**
64
+ * The nine pipeline states of the FR-6 table. They are mutually exclusive and
65
+ * resolved in this precedence (highest first), because the underlying facts
66
+ * overlap:
67
+ *
68
+ * closed > merged > ready > changes-requested > in-review > working >
69
+ * parked > planned > backlog
70
+ */
71
+ const IssueState = effect.Schema.Literals([
72
+ "backlog",
73
+ "parked",
74
+ "planned",
75
+ "working",
76
+ "in-review",
77
+ "changes-requested",
78
+ "ready",
79
+ "merged",
80
+ "closed"
81
+ ]);
82
+ /** Something the operator has to look at. Orthogonal to `IssueState`. */
83
+ const IssueAttention = effect.Schema.Literals([
84
+ "needs-you",
85
+ "stuck",
86
+ "api-error"
87
+ ]);
88
+ /** Latest review decision on the PR, as the forge reports it. */
89
+ const PrReviewState = effect.Schema.Literals([
90
+ "approved",
91
+ "changes-requested",
92
+ "review-requested",
93
+ "commented",
94
+ "none"
95
+ ]);
96
+ /** Aggregate check-run conclusion for the PR head. */
97
+ const PrChecksState = effect.Schema.Literals([
98
+ "green",
99
+ "red",
100
+ "pending"
101
+ ]);
102
+ /** The pull request (or merge request) backing an issue. */
103
+ const DerivedPrState = effect.Schema.Struct({
104
+ url: effect.Schema.String,
105
+ number: effect.Schema.Number,
106
+ reviewState: PrReviewState,
107
+ checks: PrChecksState,
108
+ /** Forge mergeability. `null` when the forge has not computed it yet. */
109
+ mergeable: effect.Schema.NullOr(effect.Schema.Boolean)
110
+ });
111
+ /** The issue's feature branch as git reports it. */
112
+ const DerivedBranchState = effect.Schema.Struct({
113
+ name: effect.Schema.String,
114
+ aheadOfMain: effect.Schema.Number,
115
+ pushed: effect.Schema.Boolean
116
+ });
117
+ /** Everything the dashboard needs to render an issue's pipeline position. */
118
+ const DerivedIssueState = effect.Schema.Struct({
119
+ issueId: effect.Schema.String,
120
+ state: IssueState,
121
+ attention: effect.Schema.optional(IssueAttention),
122
+ pr: effect.Schema.optional(DerivedPrState),
123
+ branch: effect.Schema.optional(DerivedBranchState),
124
+ /**
125
+ * No tracker answered for this issue, so `closed` — the top of the
126
+ * precedence — could not be ruled in or out. Present only in that case; an
127
+ * unresolved tracker read is never reported as an open issue.
128
+ */
129
+ trackerUnknown: effect.Schema.optional(effect.Schema.Literal(true))
130
+ });
131
+ const ISSUE_STATES = [
132
+ "backlog",
133
+ "parked",
134
+ "planned",
135
+ "working",
136
+ "in-review",
137
+ "changes-requested",
138
+ "ready",
139
+ "merged",
140
+ "closed"
141
+ ];
142
+ /** Highest precedence first — the order `deriveIssueState` resolves in. */
143
+ const ISSUE_STATE_PRECEDENCE = [
144
+ "closed",
145
+ "merged",
146
+ "ready",
147
+ "changes-requested",
148
+ "in-review",
149
+ "working",
150
+ "parked",
151
+ "planned",
152
+ "backlog"
153
+ ];
154
+ const ISSUE_ATTENTIONS = [
155
+ "needs-you",
156
+ "stuck",
157
+ "api-error"
158
+ ];
159
+ function isIssueState(value) {
160
+ return typeof value === "string" && ISSUE_STATES.includes(value);
161
+ }
162
+ function isIssueAttention(value) {
163
+ return typeof value === "string" && ISSUE_ATTENTIONS.includes(value);
164
+ }
165
+ //#endregion
29
166
  //#region src/types.ts
30
167
  const IssueId = effect.Schema.String;
31
168
  const MEMBERSHIP_UNAVAILABLE_REASONS = [
@@ -66,52 +203,6 @@ const AgentResolution = effect.Schema.Literals([
66
203
  "abandoned",
67
204
  "api_error"
68
205
  ]);
69
- const ReviewStatusValue = effect.Schema.Literals([
70
- "pending",
71
- "reviewing",
72
- "passed",
73
- "failed",
74
- "blocked",
75
- "skipped"
76
- ]);
77
- const TestStatusValue = effect.Schema.Literals([
78
- "pending",
79
- "testing",
80
- "passed",
81
- "failed",
82
- "skipped",
83
- "dispatch_failed"
84
- ]);
85
- const UatStatusValue = effect.Schema.Literals([
86
- "pending",
87
- "testing",
88
- "passed",
89
- "failed"
90
- ]);
91
- const MergeStatusValue = effect.Schema.Literals([
92
- "pending",
93
- "queued",
94
- "merging",
95
- "verifying",
96
- "merged",
97
- "failed"
98
- ]);
99
- const ReleaseStatusValue = effect.Schema.Literals([
100
- "pending",
101
- "releasing",
102
- "passed",
103
- "failed",
104
- "partial",
105
- "rolled_back",
106
- "skipped"
107
- ]);
108
- const VerificationStatusValue = effect.Schema.Literals([
109
- "pending",
110
- "running",
111
- "passed",
112
- "failed",
113
- "skipped"
114
- ]);
115
206
  const KNOWN_HARNESSES = new Set([
116
207
  "claude-code",
117
208
  "ohmypi",
@@ -301,87 +392,6 @@ const AgentSnapshot = effect.Schema.Struct({
301
392
  runtimeSnapshotSequence: effect.Schema.optional(SequenceNumber)
302
393
  });
303
394
  /** PAN-3151: A recorded cycle in the review convergence tracking series */
304
- const ReviewCycleEntry = effect.Schema.Struct({
305
- cycle: effect.Schema.Number,
306
- runId: effect.Schema.String,
307
- atCommit: effect.Schema.optional(effect.Schema.String),
308
- blockingCount: effect.Schema.Number,
309
- recordedAt: effect.Schema.String
310
- });
311
- const ReviewStatusSnapshot = effect.Schema.Struct({
312
- issueId: IssueId,
313
- reviewStatus: effect.Schema.optional(ReviewStatusValue),
314
- testStatus: effect.Schema.optional(TestStatusValue),
315
- uatStatus: effect.Schema.optional(UatStatusValue),
316
- uatNotes: effect.Schema.optional(effect.Schema.String),
317
- mergeStatus: effect.Schema.optional(MergeStatusValue),
318
- releaseStatus: effect.Schema.optional(ReleaseStatusValue),
319
- releaseNotes: effect.Schema.optional(effect.Schema.String),
320
- verificationStatus: effect.Schema.optional(VerificationStatusValue),
321
- verificationNotes: effect.Schema.optional(effect.Schema.String),
322
- verificationCycleCount: effect.Schema.optional(effect.Schema.Number),
323
- readyForMerge: effect.Schema.optional(effect.Schema.Boolean),
324
- updatedAt: effect.Schema.optional(effect.Schema.String),
325
- prUrl: effect.Schema.optional(effect.Schema.String),
326
- /** Persistent stuck flag — set by divergence guard, cleared by /unstick */
327
- stuck: effect.Schema.optional(effect.Schema.Boolean),
328
- stuckReason: effect.Schema.optional(effect.Schema.String),
329
- stuckAt: effect.Schema.optional(effect.Schema.String),
330
- stuckDetails: effect.Schema.optional(effect.Schema.String),
331
- /** PAN-3151: review cycle history for convergence detection */
332
- reviewCycleHistory: effect.Schema.optional(effect.Schema.Array(ReviewCycleEntry)),
333
- /** Commit SHA at which review passed; deacon uses this to detect new pushes after review */
334
- reviewedAtCommit: effect.Schema.optional(effect.Schema.String),
335
- /** Commit SHA at which the pre-review verification gate last passed */
336
- lastVerifiedCommit: effect.Schema.optional(effect.Schema.String),
337
- /** Current merge pipeline step (granular visibility for the merge step tracker) */
338
- mergeStep: effect.Schema.optional(effect.Schema.String),
339
- /** PAN-699: timestamp when review agents were dispatched */
340
- reviewSpawnedAt: effect.Schema.optional(effect.Schema.String),
341
- /** PAN-699: number of test-agent dispatch retries */
342
- testRetryCount: effect.Schema.optional(effect.Schema.Number),
343
- /** PAN-794: parallel-review re-dispatch retry counter (current recovery cycle) */
344
- reviewRetryCount: effect.Schema.optional(effect.Schema.Number),
345
- /** PAN-796: review auto-requeue count (circuit breaker threshold) */
346
- autoRequeueCount: effect.Schema.optional(effect.Schema.Number),
347
- /** PAN-794: ISO timestamp marking the start of the current recovery cycle */
348
- recoveryStartedAt: effect.Schema.optional(effect.Schema.String),
349
- /** Human-requested patrol opt-out — when true, Deacon ignores this issue. */
350
- deaconIgnored: effect.Schema.optional(effect.Schema.Boolean),
351
- deaconIgnoredAt: effect.Schema.optional(effect.Schema.String),
352
- deaconIgnoredReason: effect.Schema.optional(effect.Schema.String),
353
- /** PAN-1691: per-issue auto-merge routing key. undefined = project default, true = auto-merge (fast lane), false = hold for UAT. */
354
- autoMerge: effect.Schema.optional(effect.Schema.Boolean),
355
- /** Active review orchestrator tmux session name (e.g. agent-pan-540-review). */
356
- reviewCoordinatorSessionName: effect.Schema.optional(effect.Schema.String),
357
- /** Active review sub-role tmux session names (e.g. agent-pan-540-review-correctness). Discovered at emission time. */
358
- reviewSessionNames: effect.Schema.optional(effect.Schema.Array(effect.Schema.String)),
359
- /** Per-role review completion status (keyed by role: 'correctness' | 'security' | ...) */
360
- reviewSubStatuses: effect.Schema.optional(effect.Schema.Record(effect.Schema.String, effect.Schema.Literals(["running", "done"]))),
361
- /** PAN-905: queue position in the merge queue */
362
- queuePosition: effect.Schema.optional(effect.Schema.Number),
363
- /** PAN-905: currently active specialist (e.g. 'merge-agent') */
364
- activeSpecialist: effect.Schema.optional(effect.Schema.String),
365
- /** PAN-905: number of merge retries attempted */
366
- mergeRetryCount: effect.Schema.optional(effect.Schema.Number),
367
- /** PAN-905: free-form notes about the merge attempt */
368
- mergeNotes: effect.Schema.optional(effect.Schema.String),
369
- /** Merge blocker reasons surfaced to operators. */
370
- blockerReasons: effect.Schema.optional(effect.Schema.Array(effect.Schema.Struct({
371
- type: effect.Schema.Literals([
372
- "failing_checks",
373
- "merge_conflict",
374
- "unresolved_conversations",
375
- "changes_requested",
376
- "draft_pr",
377
- "not_mergeable",
378
- "unmerged_sibling_repo"
379
- ]),
380
- summary: effect.Schema.String,
381
- details: effect.Schema.optional(effect.Schema.String),
382
- detectedAt: effect.Schema.String
383
- })))
384
- });
385
395
  const TurnDiffFileChange = effect.Schema.Struct({
386
396
  path: effect.Schema.String,
387
397
  kind: effect.Schema.optional(effect.Schema.String),
@@ -507,7 +517,10 @@ const DashboardSnapshot = effect.Schema.Struct({
507
517
  sequence: SequenceNumber,
508
518
  agents: effect.Schema.Array(AgentSnapshot),
509
519
  specialists: effect.Schema.Array(effect.Schema.Unknown),
510
- reviewStatuses: effect.Schema.Array(ReviewStatusSnapshot),
520
+ /** PAN-3917 FR-6: the derived pipeline state of every known issue. */
521
+ derivedIssueStates: effect.Schema.Array(DerivedIssueState),
522
+ /** PAN-3917 FR-12: every live agent pane the terminal backend reports. */
523
+ backendPanes: effect.Schema.Array(BackendPane),
511
524
  issues: effect.Schema.Array(effect.Schema.Unknown),
512
525
  recentActivity: effect.Schema.optional(effect.Schema.Array(effect.Schema.Unknown)),
513
526
  resources: effect.Schema.optional(effect.Schema.Unknown),
@@ -522,13 +535,6 @@ const DashboardSnapshot = effect.Schema.Struct({
522
535
  restartGate: effect.Schema.optional(RestartGateSnapshot),
523
536
  timestamp: effect.Schema.String
524
537
  });
525
- const WorkspaceDetail = effect.Schema.Struct({
526
- workspace: effect.Schema.Unknown,
527
- reviewStatus: effect.Schema.Unknown,
528
- planning: effect.Schema.Unknown,
529
- costs: effect.Schema.Unknown,
530
- agentOutput: effect.Schema.Array(effect.Schema.String)
531
- });
532
538
  const ResourceStats = effect.Schema.Struct({ containers: effect.Schema.Array(effect.Schema.Struct({
533
539
  name: effect.Schema.String,
534
540
  cpu: effect.Schema.optional(effect.Schema.String),
@@ -613,14 +619,6 @@ const SessionNode = effect.Schema.Struct({
613
619
  "tmux",
614
620
  "supervisor"
615
621
  ])),
616
- paused: effect.Schema.optional(effect.Schema.Boolean),
617
- pausedReason: effect.Schema.optional(effect.Schema.String),
618
- pausedAt: effect.Schema.optional(effect.Schema.String),
619
- troubled: effect.Schema.optional(effect.Schema.Boolean),
620
- troubledAt: effect.Schema.optional(effect.Schema.String),
621
- troubledReason: effect.Schema.optional(effect.Schema.String),
622
- consecutiveFailures: effect.Schema.optional(effect.Schema.Number),
623
- queuedMailCount: effect.Schema.optional(effect.Schema.Number),
624
622
  modelOrigin: effect.Schema.optional(ModelOrigin)
625
623
  });
626
624
  const FeatureNode = effect.Schema.Struct({
@@ -1760,16 +1758,32 @@ const PlanItemsUnblockedEvent = effect.Schema.Struct({
1760
1758
  items: effect.Schema.Array(effect.Schema.String)
1761
1759
  })
1762
1760
  });
1763
- /** Replaces socket.io `pipeline:status` */
1764
- const PipelineStatusChangedEvent = effect.Schema.Struct({
1765
- type: effect.Schema.Literal("pipeline.status_changed"),
1761
+ /**
1762
+ * PAN-3917 FR-6 — an issue's derived pipeline state changed.
1763
+ *
1764
+ * Emitted with `emitOnly`: derived state is recomputed from the tracker, the
1765
+ * forge and the terminal backend on every boot, so persisting it would be
1766
+ * storing a status Overdeck can derive.
1767
+ */
1768
+ const IssueStateChangedEvent = effect.Schema.Struct({
1769
+ type: effect.Schema.Literal("issue_state.changed"),
1766
1770
  sequence: SequenceNumber,
1767
1771
  timestamp: effect.Schema.String,
1768
- payload: effect.Schema.Struct({
1769
- issueId: IssueId,
1770
- workspaceId: effect.Schema.optional(effect.Schema.String),
1771
- status: ReviewStatusSnapshot
1772
- })
1772
+ payload: effect.Schema.Struct({ issueState: DerivedIssueState })
1773
+ });
1774
+ /** PAN-3917 FR-12 — a live agent pane appeared or changed. `emitOnly`. */
1775
+ const BackendPaneChangedEvent = effect.Schema.Struct({
1776
+ type: effect.Schema.Literal("backend_pane.changed"),
1777
+ sequence: SequenceNumber,
1778
+ timestamp: effect.Schema.String,
1779
+ payload: effect.Schema.Struct({ pane: BackendPane })
1780
+ });
1781
+ /** PAN-3917 FR-12 — a pane left the backend inventory. `emitOnly`. */
1782
+ const BackendPaneRemovedEvent = effect.Schema.Struct({
1783
+ type: effect.Schema.Literal("backend_pane.removed"),
1784
+ sequence: SequenceNumber,
1785
+ timestamp: effect.Schema.String,
1786
+ payload: effect.Schema.Struct({ paneId: effect.Schema.String })
1773
1787
  });
1774
1788
  /** Replaces socket.io `merge:ready` */
1775
1789
  const MergeReadyEvent = effect.Schema.Struct({
@@ -1781,17 +1795,6 @@ const MergeReadyEvent = effect.Schema.Struct({
1781
1795
  workspaceId: effect.Schema.optional(effect.Schema.String)
1782
1796
  })
1783
1797
  });
1784
- /** New — review status changed */
1785
- const ReviewStatusChangedEvent = effect.Schema.Struct({
1786
- type: effect.Schema.Literal("review.status_changed"),
1787
- sequence: SequenceNumber,
1788
- timestamp: effect.Schema.String,
1789
- payload: effect.Schema.Struct({
1790
- issueId: IssueId,
1791
- workspaceId: effect.Schema.optional(effect.Schema.String),
1792
- status: ReviewStatusSnapshot
1793
- })
1794
- });
1795
1798
  /** New — review specialist dispatched */
1796
1799
  const PipelineReviewStartedEvent = effect.Schema.Struct({
1797
1800
  type: effect.Schema.Literal("pipeline.review-started"),
@@ -2630,9 +2633,10 @@ const DomainEvent = effect.Schema.Union([
2630
2633
  PlanItemStatusChangedEvent,
2631
2634
  PlanSubitemStatusChangedEvent,
2632
2635
  PlanItemsUnblockedEvent,
2633
- PipelineStatusChangedEvent,
2636
+ IssueStateChangedEvent,
2637
+ BackendPaneChangedEvent,
2638
+ BackendPaneRemovedEvent,
2634
2639
  MergeReadyEvent,
2635
- ReviewStatusChangedEvent,
2636
2640
  PipelineReviewStartedEvent,
2637
2641
  PipelineReviewCompletedEvent,
2638
2642
  PipelineTestStartedEvent,
@@ -2862,248 +2866,66 @@ const OpenInEditorInput = effect.Schema.Struct({
2862
2866
  editor: EditorIdSchema
2863
2867
  });
2864
2868
  //#endregion
2865
- //#region src/flywheel.ts
2866
- const FlywheelRunId = effect.Schema.String.check(effect.Schema.isPattern(/^RUN-\d+$/));
2867
- const FlywheelHttpUrl = effect.Schema.String.check(effect.Schema.isPattern(/^https?:\/\/\S+$/i));
2868
- const FlywheelHarness = effect.Schema.Literals([
2869
- "claude-code",
2870
- "pi",
2871
- "ohmypi",
2872
- "codex",
2873
- "acp",
2874
- "kimi-code",
2875
- "opencode",
2876
- "muse"
2877
- ]);
2878
- const FlywheelEffort = effect.Schema.Literals([
2879
- "low",
2880
- "medium",
2881
- "high",
2882
- "xhigh",
2883
- "max"
2884
- ]);
2885
- const FlywheelOrchestrator = effect.Schema.Struct({
2886
- harness: FlywheelHarness,
2887
- model: effect.Schema.String,
2888
- effort: FlywheelEffort,
2889
- ctxPercent: effect.Schema.Number
2869
+ //#region src/rpc.ts
2870
+ const WS_METHODS = {
2871
+ scanConversations: "pan.scanConversations",
2872
+ searchConversations: "pan.searchConversations",
2873
+ listDiscoveredSessions: "pan.listDiscoveredSessions",
2874
+ listSessionsFeed: "pan.listSessionsFeed",
2875
+ getSessionsFeedFacets: "pan.getSessionsFeedFacets",
2876
+ getDiscoveredSession: "pan.getDiscoveredSession",
2877
+ enrichSessions: "pan.enrichSessions",
2878
+ embedSessions: "pan.embedSessions",
2879
+ getConversationCost: "pan.getConversationCost",
2880
+ getConversationCostByWorkspace: "pan.getConversationCostByWorkspace",
2881
+ getConversationStats: "pan.getConversationStats",
2882
+ subscribeDomainEvents: "pan.subscribeDomainEvents",
2883
+ subscribeIssueEvents: "pan.subscribeIssueEvents",
2884
+ subscribeTerminal: "pan.subscribeTerminal",
2885
+ subscribeAgentOutput: "pan.subscribeAgentOutput",
2886
+ subscribeConversationMessages: "pan.subscribeConversationMessages",
2887
+ subscribeProjectSessionTree: "pan.subscribeProjectSessionTree",
2888
+ getSnapshot: "pan.getSnapshot",
2889
+ replayEvents: "pan.replayEvents",
2890
+ readWorkspaceFile: "pan.readWorkspaceFile",
2891
+ readFileAtPath: "pan.readFileAtPath",
2892
+ writeFileAtPath: "pan.writeFileAtPath",
2893
+ resolveFilePathExists: "pan.resolveFilePathExists",
2894
+ terminalOpen: "pan.terminalOpen",
2895
+ terminalWrite: "pan.terminalWrite",
2896
+ terminalResize: "pan.terminalResize",
2897
+ terminalClose: "pan.terminalClose",
2898
+ startPlanning: "pan.startPlanning",
2899
+ startAgent: "pan.startAgent",
2900
+ deepWipe: "pan.deepWipe",
2901
+ sendTerminalInput: "pan.sendTerminalInput",
2902
+ resizeTerminal: "pan.resizeTerminal",
2903
+ shellOpenInEditor: "pan.shellOpenInEditor",
2904
+ getAvailableEditors: "pan.getAvailableEditors"
2905
+ };
2906
+ var PanRpcError = class extends effect.Schema.TaggedErrorClass()("PanRpcError", {
2907
+ message: effect.Schema.String,
2908
+ code: effect.Schema.optional(effect.Schema.String)
2909
+ }) {};
2910
+ const TerminalOutput = effect.Schema.Struct({
2911
+ sessionName: effect.Schema.String,
2912
+ data: effect.Schema.String
2890
2913
  });
2891
- const FlywheelScope = effect.Schema.Literals(["pan-only", "all-tracked-projects"]);
2892
- const FlywheelHeadline = effect.Schema.Struct({
2893
- bugsFixed: effect.Schema.Number,
2894
- swarmItemsMerged: effect.Schema.Number,
2895
- swarmItemsTotal: effect.Schema.Number,
2896
- prsMerged: effect.Schema.Number,
2897
- awaitingUat: effect.Schema.Number
2914
+ const AgentOutput = effect.Schema.Struct({
2915
+ agentId: effect.Schema.String,
2916
+ line: effect.Schema.String
2898
2917
  });
2899
- /**
2900
- * Pipeline verbs — display state only. They no longer gate the merge queue.
2901
- *
2902
- * History worth keeping (PAN-1736 / PAN-1759): the merge queue used to be
2903
- * derived by filtering these verbs, treating only "shipping" or "merging" as
2904
- * "at the merge gate". Any other verb on an issue that was ready_for_merge in
2905
- * the review DB silently dropped it from the queue and from UAT batch
2906
- * assembly — RUN-18 shipped an empty queue with five ready issues exactly that
2907
- * way — and the queue existed only while a run was emitting a pipeline at all.
2908
- *
2909
- * PAN-1696 removed that coupling. The ready set is now sourced from the
2910
- * review-status records per project (`listEligibleCandidatesByProject` +
2911
- * `computeMergeQueueFromCandidates` in src/lib/flywheel-merge-order.ts), which
2912
- * needs no flywheel run and cannot be affected by which verb an orchestrator
2913
- * chose to report. Adding a verb here therefore has no merge-queue consequence;
2914
- * it only changes what the dashboard displays.
2915
- */
2916
- const FlywheelPipelineVerb = effect.Schema.Literals([
2917
- "planning",
2918
- "working",
2919
- "reviewing",
2920
- "testing",
2921
- "shipping",
2922
- "merging",
2923
- "blocked",
2924
- "parked"
2925
- ]);
2926
- const FlywheelPipelineStatus = effect.Schema.Literals([
2927
- "queued",
2928
- "running",
2929
- "blocked",
2930
- "passed",
2931
- "failed",
2932
- "merged",
2933
- "parked"
2934
- ]);
2935
- const FlywheelPipelineItem = effect.Schema.Struct({
2936
- issueId: effect.Schema.String,
2937
- title: effect.Schema.String,
2938
- verb: FlywheelPipelineVerb,
2939
- status: FlywheelPipelineStatus,
2940
- progressPercent: effect.Schema.optional(effect.Schema.Number),
2941
- agentId: effect.Schema.optional(effect.Schema.String),
2942
- pr: effect.Schema.optional(effect.Schema.Number),
2943
- mergeOrder: effect.Schema.optional(effect.Schema.Number),
2944
- conflictsWith: effect.Schema.optional(effect.Schema.Array(effect.Schema.String))
2945
- });
2946
- const FlywheelSubstrateBugStatus = effect.Schema.Literals([
2947
- "filed",
2948
- "fixed",
2949
- "workaround"
2950
- ]);
2951
- const FlywheelSubstrateBug = effect.Schema.Struct({
2952
- issueId: effect.Schema.String,
2953
- title: effect.Schema.String,
2954
- status: FlywheelSubstrateBugStatus,
2955
- commitSha: effect.Schema.optional(effect.Schema.String),
2956
- url: effect.Schema.optional(FlywheelHttpUrl)
2957
- });
2958
- const FlywheelAgentStatus = effect.Schema.Literals([
2959
- "starting",
2960
- "running",
2961
- "waiting",
2962
- "idle",
2963
- "stopped",
2964
- "error"
2965
- ]);
2966
- const FlywheelAgent = effect.Schema.Struct({
2967
- id: effect.Schema.String,
2968
- label: effect.Schema.String,
2969
- status: FlywheelAgentStatus,
2970
- issueId: effect.Schema.optional(effect.Schema.String),
2971
- role: effect.Schema.optional(effect.Schema.String),
2972
- model: effect.Schema.optional(effect.Schema.String),
2973
- ctxPercent: effect.Schema.optional(effect.Schema.Number),
2974
- currentAction: effect.Schema.optional(effect.Schema.String)
2975
- });
2976
- const FlywheelParkedItem = effect.Schema.Struct({
2977
- issueId: effect.Schema.String,
2978
- title: effect.Schema.String,
2979
- reason: effect.Schema.String,
2980
- parkedAt: effect.Schema.optional(effect.Schema.String)
2981
- });
2982
- const FlywheelSuggestionAction = effect.Schema.Literals([
2983
- "start",
2984
- "resume",
2985
- "plan",
2986
- "review",
2987
- "merge",
2988
- "unblock",
2989
- "park",
2990
- "investigate",
2991
- "wait"
2992
- ]);
2993
- const FlywheelSuggestionPriority = effect.Schema.Literals([
2994
- "urgent",
2995
- "high",
2996
- "medium",
2997
- "low"
2998
- ]);
2999
- const FlywheelSuggestion = effect.Schema.Struct({
3000
- action: FlywheelSuggestionAction,
3001
- issueId: effect.Schema.optional(effect.Schema.String),
3002
- rationale: effect.Schema.String,
3003
- priority: FlywheelSuggestionPriority,
3004
- filedBy: effect.Schema.optional(effect.Schema.Literals(["agent", "operator"])),
3005
- weight: effect.Schema.optional(effect.Schema.Number),
3006
- weightReason: effect.Schema.optional(effect.Schema.String)
3007
- });
3008
- const FlywheelSystemStatus = effect.Schema.Struct({
3009
- mainHead: effect.Schema.String,
3010
- ramUsedMb: effect.Schema.Number,
3011
- ramTotalMb: effect.Schema.Number,
3012
- swapUsedMb: effect.Schema.Number,
3013
- swapTotalMb: effect.Schema.Number,
3014
- agentsActive: effect.Schema.Number,
3015
- agentsCap: effect.Schema.Number
3016
- });
3017
- const FlywheelOrders = effect.Schema.Struct({
3018
- bookId: effect.Schema.String,
3019
- bookName: effect.Schema.String,
3020
- landed: effect.Schema.Number,
3021
- total: effect.Schema.Number,
3022
- laneAInFlight: effect.Schema.Array(effect.Schema.String),
3023
- laneBInFlight: effect.Schema.optional(effect.Schema.String),
3024
- drained: effect.Schema.Boolean
3025
- });
3026
- const FlywheelStatus = effect.Schema.Struct({
3027
- runId: FlywheelRunId,
3028
- startedAt: effect.Schema.String,
3029
- elapsedMs: effect.Schema.Number,
3030
- orchestrator: FlywheelOrchestrator,
3031
- headline: FlywheelHeadline,
3032
- activePipeline: effect.Schema.Array(FlywheelPipelineItem),
3033
- substrateBugs: effect.Schema.Array(FlywheelSubstrateBug),
3034
- agents: effect.Schema.Array(FlywheelAgent),
3035
- parked: effect.Schema.Array(FlywheelParkedItem),
3036
- suggestions: effect.Schema.Array(FlywheelSuggestion).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed([]))),
3037
- system: FlywheelSystemStatus,
3038
- openQuestions: effect.Schema.Array(effect.Schema.String),
3039
- orders: effect.Schema.optional(FlywheelOrders),
3040
- scope: effect.Schema.optional(FlywheelScope),
3041
- ticks: effect.Schema.Number,
3042
- lastTickAt: effect.Schema.String
3043
- });
3044
- //#endregion
3045
- //#region src/rpc.ts
3046
- const WS_METHODS = {
3047
- scanConversations: "pan.scanConversations",
3048
- searchConversations: "pan.searchConversations",
3049
- listDiscoveredSessions: "pan.listDiscoveredSessions",
3050
- listSessionsFeed: "pan.listSessionsFeed",
3051
- getSessionsFeedFacets: "pan.getSessionsFeedFacets",
3052
- getDiscoveredSession: "pan.getDiscoveredSession",
3053
- enrichSessions: "pan.enrichSessions",
3054
- embedSessions: "pan.embedSessions",
3055
- getConversationCost: "pan.getConversationCost",
3056
- getConversationCostByWorkspace: "pan.getConversationCostByWorkspace",
3057
- getConversationStats: "pan.getConversationStats",
3058
- subscribeDomainEvents: "pan.subscribeDomainEvents",
3059
- subscribeIssueEvents: "pan.subscribeIssueEvents",
3060
- subscribeTerminal: "pan.subscribeTerminal",
3061
- subscribeAgentOutput: "pan.subscribeAgentOutput",
3062
- subscribeConversationMessages: "pan.subscribeConversationMessages",
3063
- subscribeProjectSessionTree: "pan.subscribeProjectSessionTree",
3064
- subscribeFlywheelStatus: "pan.subscribeFlywheelStatus",
3065
- getSnapshot: "pan.getSnapshot",
3066
- replayEvents: "pan.replayEvents",
3067
- getWorkspaceDetail: "pan.getWorkspaceDetail",
3068
- readWorkspaceFile: "pan.readWorkspaceFile",
3069
- readFileAtPath: "pan.readFileAtPath",
3070
- writeFileAtPath: "pan.writeFileAtPath",
3071
- resolveFilePathExists: "pan.resolveFilePathExists",
3072
- terminalOpen: "pan.terminalOpen",
3073
- terminalWrite: "pan.terminalWrite",
3074
- terminalResize: "pan.terminalResize",
3075
- terminalClose: "pan.terminalClose",
3076
- startPlanning: "pan.startPlanning",
3077
- startAgent: "pan.startAgent",
3078
- deepWipe: "pan.deepWipe",
3079
- sendTerminalInput: "pan.sendTerminalInput",
3080
- resizeTerminal: "pan.resizeTerminal",
3081
- shellOpenInEditor: "pan.shellOpenInEditor",
3082
- getAvailableEditors: "pan.getAvailableEditors"
3083
- };
3084
- var PanRpcError = class extends effect.Schema.TaggedErrorClass()("PanRpcError", {
3085
- message: effect.Schema.String,
3086
- code: effect.Schema.optional(effect.Schema.String)
3087
- }) {};
3088
- const TerminalOutput = effect.Schema.Struct({
3089
- sessionName: effect.Schema.String,
3090
- data: effect.Schema.String
3091
- });
3092
- const AgentOutput = effect.Schema.Struct({
3093
- agentId: effect.Schema.String,
3094
- line: effect.Schema.String
3095
- });
3096
- const ProposedPlan = effect.Schema.Struct({
3097
- id: effect.Schema.String,
3098
- plan: effect.Schema.String,
3099
- planFilePath: effect.Schema.optional(effect.Schema.String),
3100
- status: effect.Schema.Literals([
3101
- "pending",
3102
- "approved",
3103
- "rejected"
3104
- ]),
3105
- createdAt: effect.Schema.String,
3106
- resolvedAt: effect.Schema.optional(effect.Schema.String)
2918
+ const ProposedPlan = effect.Schema.Struct({
2919
+ id: effect.Schema.String,
2920
+ plan: effect.Schema.String,
2921
+ planFilePath: effect.Schema.optional(effect.Schema.String),
2922
+ status: effect.Schema.Literals([
2923
+ "pending",
2924
+ "approved",
2925
+ "rejected"
2926
+ ]),
2927
+ createdAt: effect.Schema.String,
2928
+ resolvedAt: effect.Schema.optional(effect.Schema.String)
3107
2929
  });
3108
2930
  const CompactBoundary = effect.Schema.Struct({
3109
2931
  id: effect.Schema.String,
@@ -3305,12 +3127,6 @@ const TerminalCloseRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.terminalClose,
3305
3127
  payload: effect.Schema.Struct({ sessionName: effect.Schema.String }),
3306
3128
  error: PanRpcError
3307
3129
  });
3308
- /** 10. Get batched workspace detail (unary) — replaces 5 separate HTTP calls */
3309
- const GetWorkspaceDetailRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.getWorkspaceDetail, {
3310
- payload: effect.Schema.Struct({ issueId: IssueId }),
3311
- success: WorkspaceDetail,
3312
- error: PanRpcError
3313
- });
3314
3130
  const ReadWorkspaceFileInput = effect.Schema.Struct({
3315
3131
  issueId: IssueId,
3316
3132
  relativePath: effect.Schema.String,
@@ -3457,13 +3273,6 @@ const SubscribeProjectSessionTreeRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.s
3457
3273
  error: PanRpcError,
3458
3274
  stream: true
3459
3275
  });
3460
- /** 18. Subscribe to latest Flywheel status snapshots (stream) */
3461
- const SubscribeFlywheelStatusRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.subscribeFlywheelStatus, {
3462
- payload: effect.Schema.Struct({}),
3463
- success: effect.Schema.NullOr(FlywheelStatus),
3464
- error: PanRpcError,
3465
- stream: true
3466
- });
3467
3276
  /** 19. Open a workspace in an editor (PAN-966) */
3468
3277
  const ShellOpenInEditorRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.shellOpenInEditor, {
3469
3278
  payload: OpenInEditorInput,
@@ -3641,7 +3450,7 @@ const GetConversationStatsRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.getConve
3641
3450
  error: PanRpcError
3642
3451
  });
3643
3452
  /** All Overdeck WebSocket RPC methods */
3644
- const PanRpcGroup = effect_unstable_rpc_RpcGroup.make(SubscribeDomainEventsRpc, SubscribeIssueEventsRpc, SubscribeTerminalRpc, SubscribeAgentOutputRpc, GetSnapshotRpc, ReplayEventsRpc, GetWorkspaceDetailRpc, ReadWorkspaceFileRpc, ReadFileAtPathRpc, WriteFileAtPathRpc, ResolveFilePathExistsRpc, TerminalOpenRpc, TerminalWriteRpc, TerminalResizeRpc, TerminalCloseRpc, StartPlanningRpc, StartAgentRpc, DeepWipeRpc, SendTerminalInputRpc, ResizeTerminalRpc, SubscribeConversationMessagesRpc, SubscribeProjectSessionTreeRpc, SubscribeFlywheelStatusRpc, ShellOpenInEditorRpc, GetAvailableEditorsRpc, ScanConversationsRpc, SearchConversationsRpc, ListDiscoveredSessionsRpc, ListSessionsFeedRpc, GetSessionsFeedFacetsRpc, GetDiscoveredSessionRpc, EnrichSessionsRpc, EmbedSessionsRpc, GetConversationCostRpc, GetConversationCostByWorkspaceRpc, GetConversationStatsRpc);
3453
+ const PanRpcGroup = effect_unstable_rpc_RpcGroup.make(SubscribeDomainEventsRpc, SubscribeIssueEventsRpc, SubscribeTerminalRpc, SubscribeAgentOutputRpc, GetSnapshotRpc, ReplayEventsRpc, ReadWorkspaceFileRpc, ReadFileAtPathRpc, WriteFileAtPathRpc, ResolveFilePathExistsRpc, TerminalOpenRpc, TerminalWriteRpc, TerminalResizeRpc, TerminalCloseRpc, StartPlanningRpc, StartAgentRpc, DeepWipeRpc, SendTerminalInputRpc, ResizeTerminalRpc, SubscribeConversationMessagesRpc, SubscribeProjectSessionTreeRpc, ShellOpenInEditorRpc, GetAvailableEditorsRpc, ScanConversationsRpc, SearchConversationsRpc, ListDiscoveredSessionsRpc, ListSessionsFeedRpc, GetSessionsFeedFacetsRpc, GetDiscoveredSessionRpc, EnrichSessionsRpc, EmbedSessionsRpc, GetConversationCostRpc, GetConversationCostByWorkspaceRpc, GetConversationStatsRpc);
3645
3454
  //#endregion
3646
3455
  //#region src/issue-delta.ts
3647
3456
  function createIssueDelta(previous, next) {
@@ -3666,7 +3475,8 @@ const INITIAL_READ_MODEL_STATE = {
3666
3475
  sequence: 0,
3667
3476
  agentsById: {},
3668
3477
  agentRuntimeById: {},
3669
- reviewStatusByIssueId: {},
3478
+ derivedIssueStateByIssueId: {},
3479
+ backendPanesById: {},
3670
3480
  resources: null,
3671
3481
  agentOutputById: {},
3672
3482
  issuesRaw: [],
@@ -3783,8 +3593,10 @@ function bumpRuntimeSnapshotSequence(agentsById, agentId, sequence) {
3783
3593
  function syncSnapshot(state, snapshot) {
3784
3594
  const agentsById = {};
3785
3595
  for (const agent of snapshot.agents) agentsById[agent.id] = agent;
3786
- const reviewStatusByIssueId = {};
3787
- for (const rs of snapshot.reviewStatuses) reviewStatusByIssueId[rs.issueId] = rs;
3596
+ const derivedIssueStateByIssueId = {};
3597
+ for (const derived of snapshot.derivedIssueStates ?? []) derivedIssueStateByIssueId[derived.issueId] = derived;
3598
+ const backendPanesById = {};
3599
+ for (const pane of snapshot.backendPanes ?? []) backendPanesById[pane.id] = pane;
3788
3600
  const channelPermissionRequestsById = {};
3789
3601
  const channelPermissionRequestIdsByAgentId = {};
3790
3602
  for (const request of snapshot.channelPermissionRequests ?? []) {
@@ -3800,7 +3612,8 @@ function syncSnapshot(state, snapshot) {
3800
3612
  ...state,
3801
3613
  sequence: snapshot.sequence,
3802
3614
  agentsById,
3803
- reviewStatusByIssueId,
3615
+ derivedIssueStateByIssueId,
3616
+ backendPanesById,
3804
3617
  agentRuntimeById: snapshot.agentRuntimeById ?? state.agentRuntimeById,
3805
3618
  channelPermissionRequestsById,
3806
3619
  channelPermissionRequestIdsByAgentId,
@@ -3890,7 +3703,16 @@ function applyEvent(state, event) {
3890
3703
  };
3891
3704
  }
3892
3705
  case "agent.stopped": {
3893
- const { [event.payload.agentId]: _removed, ...rest } = state.agentsById;
3706
+ const stoppedAgent = state.agentsById[event.payload.agentId];
3707
+ const nextAgentsById = stoppedAgent ? {
3708
+ ...state.agentsById,
3709
+ [event.payload.agentId]: {
3710
+ ...stoppedAgent,
3711
+ status: "stopped",
3712
+ hasLiveTmuxSession: false,
3713
+ lastActivity: event.timestamp
3714
+ }
3715
+ } : state.agentsById;
3894
3716
  const runtimeById = state.agentRuntimeById ?? {};
3895
3717
  const prevRuntime = runtimeById[event.payload.agentId];
3896
3718
  const nextRuntimeById = prevRuntime ? {
@@ -3919,7 +3741,7 @@ function applyEvent(state, event) {
3919
3741
  return {
3920
3742
  ...state,
3921
3743
  sequence: Math.max(state.sequence, event.sequence),
3922
- agentsById: rest,
3744
+ agentsById: nextAgentsById,
3923
3745
  agentRuntimeById: nextRuntimeById,
3924
3746
  channelPermissionRequestsById: nextPermissionRequestsById,
3925
3747
  channelPermissionRequestIdsByAgentId: restPendingIds,
@@ -4064,85 +3886,35 @@ function applyEvent(state, event) {
4064
3886
  }
4065
3887
  };
4066
3888
  }
4067
- case "pipeline.status_changed":
4068
- case "review.status_changed": return {
3889
+ case "issue_state.changed": return {
4069
3890
  ...state,
4070
3891
  sequence: Math.max(state.sequence, event.sequence),
4071
- reviewStatusByIssueId: {
4072
- ...state.reviewStatusByIssueId,
4073
- [event.payload.issueId]: event.payload.status
3892
+ derivedIssueStateByIssueId: {
3893
+ ...state.derivedIssueStateByIssueId,
3894
+ [event.payload.issueState.issueId]: event.payload.issueState
4074
3895
  }
4075
3896
  };
4076
- case "review.reviewer_started": {
4077
- const { issueId, role, sessionName } = event.payload;
4078
- const existing = state.reviewStatusByIssueId[issueId];
4079
- const prevSubs = existing?.reviewSubStatuses ?? {};
4080
- const prevNames = existing?.reviewSessionNames ?? [];
4081
- const nextNames = prevNames.includes(sessionName) ? prevNames : [...prevNames, sessionName];
4082
- const nextStatus = {
4083
- ...existing ?? { issueId },
4084
- reviewSubStatuses: {
4085
- ...prevSubs,
4086
- [role]: "running"
4087
- },
4088
- reviewSessionNames: nextNames
4089
- };
4090
- return {
4091
- ...state,
4092
- sequence: Math.max(state.sequence, event.sequence),
4093
- reviewStatusByIssueId: {
4094
- ...state.reviewStatusByIssueId,
4095
- [issueId]: nextStatus
4096
- }
4097
- };
4098
- }
4099
- case "review.reviewer_completed": {
4100
- const { issueId, role } = event.payload;
4101
- const existing = state.reviewStatusByIssueId[issueId];
4102
- if (!existing) return {
4103
- ...state,
4104
- sequence: Math.max(state.sequence, event.sequence)
4105
- };
4106
- const prevSubs = existing.reviewSubStatuses ?? {};
4107
- const nextStatus = {
4108
- ...existing,
4109
- reviewSubStatuses: {
4110
- ...prevSubs,
4111
- [role]: "done"
4112
- }
4113
- };
4114
- return {
4115
- ...state,
4116
- sequence: Math.max(state.sequence, event.sequence),
4117
- reviewStatusByIssueId: {
4118
- ...state.reviewStatusByIssueId,
4119
- [issueId]: nextStatus
4120
- }
4121
- };
4122
- }
4123
- case "review.specialist.timed_out": return {
3897
+ case "backend_pane.changed": return {
4124
3898
  ...state,
4125
- sequence: Math.max(state.sequence, event.sequence)
3899
+ sequence: Math.max(state.sequence, event.sequence),
3900
+ backendPanesById: {
3901
+ ...state.backendPanesById,
3902
+ [event.payload.pane.id]: event.payload.pane
3903
+ }
4126
3904
  };
4127
- case "review.coordinator_started": {
4128
- const { issueId, sessionName } = event.payload;
4129
- const nextStatus = {
4130
- ...state.reviewStatusByIssueId[issueId] ?? { issueId },
4131
- reviewCoordinatorSessionName: sessionName
4132
- };
3905
+ case "backend_pane.removed": {
3906
+ const { [event.payload.paneId]: _removed, ...rest } = state.backendPanesById;
4133
3907
  return {
4134
3908
  ...state,
4135
3909
  sequence: Math.max(state.sequence, event.sequence),
4136
- reviewStatusByIssueId: {
4137
- ...state.reviewStatusByIssueId,
4138
- [issueId]: nextStatus
4139
- }
3910
+ backendPanesById: rest
4140
3911
  };
4141
3912
  }
4142
- case "review.coordinator.died": return {
4143
- ...state,
4144
- sequence: Math.max(state.sequence, event.sequence)
4145
- };
3913
+ case "review.reviewer_started":
3914
+ case "review.reviewer_completed":
3915
+ case "review.specialist.timed_out":
3916
+ case "review.coordinator_started":
3917
+ case "review.coordinator.died":
4146
3918
  case "pipeline.review-started":
4147
3919
  case "pipeline.review-completed":
4148
3920
  case "pipeline.test-started":
@@ -5127,49 +4899,229 @@ function deriveProjectCi(record) {
5127
4899
  };
5128
4900
  }
5129
4901
  //#endregion
5130
- //#region src/flywheel-stats.ts
5131
- const FlywheelStatsCriterionStatus = effect.Schema.Literals([
5132
- "green",
5133
- "yellow",
5134
- "red",
5135
- "insufficient_data"
4902
+ //#region src/flywheel.ts
4903
+ const FlywheelRunId = effect.Schema.String.check(effect.Schema.isPattern(/^RUN-\d+$/));
4904
+ const FlywheelHttpUrl = effect.Schema.String.check(effect.Schema.isPattern(/^https?:\/\/\S+$/i));
4905
+ const FlywheelHarness = effect.Schema.Literals([
4906
+ "claude-code",
4907
+ "pi",
4908
+ "ohmypi",
4909
+ "codex",
4910
+ "acp",
4911
+ "kimi-code",
4912
+ "opencode",
4913
+ "muse"
5136
4914
  ]);
5137
- const FlywheelStatsTrend = effect.Schema.Literals([
5138
- "up",
5139
- "down",
5140
- "flat"
4915
+ const FlywheelEffort = effect.Schema.Literals([
4916
+ "low",
4917
+ "medium",
4918
+ "high",
4919
+ "xhigh",
4920
+ "max"
5141
4921
  ]);
5142
- const FlywheelStatsCriterionValueObject = effect.Schema.Record(effect.Schema.String, effect.Schema.Json);
5143
- const FlywheelStatsCriterionValue = effect.Schema.Union([effect.Schema.Number, FlywheelStatsCriterionValueObject]);
5144
- const FlywheelStatsCriterion = effect.Schema.Struct({
5145
- label: effect.Schema.String,
5146
- value: FlywheelStatsCriterionValue,
5147
- target: FlywheelStatsCriterionValue,
5148
- status: FlywheelStatsCriterionStatus,
5149
- trend: effect.Schema.optional(FlywheelStatsTrend),
5150
- sampleSize: effect.Schema.Number,
5151
- dataSufficient: effect.Schema.Boolean
5152
- });
5153
- const FlywheelStatsCriteria = effect.Schema.Struct({
5154
- c1_bugRate: FlywheelStatsCriterion,
5155
- c2_p0Bugs: FlywheelStatsCriterion,
5156
- c3_passRate: FlywheelStatsCriterion,
5157
- c4_mttr: FlywheelStatsCriterion,
5158
- c5_intervention: FlywheelStatsCriterion,
5159
- c6_timeConsistency: FlywheelStatsCriterion,
5160
- c7_flake: FlywheelStatsCriterion
4922
+ const FlywheelOrchestrator = effect.Schema.Struct({
4923
+ harness: FlywheelHarness,
4924
+ model: effect.Schema.String,
4925
+ effort: FlywheelEffort,
4926
+ ctxPercent: effect.Schema.Number
5161
4927
  });
5162
- const FlywheelStats = effect.Schema.Struct({
5163
- window: effect.Schema.String,
5164
- generatedAt: effect.Schema.String,
5165
- criteria: FlywheelStatsCriteria
4928
+ const FlywheelScope = effect.Schema.Literals(["pan-only", "all-tracked-projects"]);
4929
+ const FlywheelHeadline = effect.Schema.Struct({
4930
+ bugsFixed: effect.Schema.Number,
4931
+ swarmItemsMerged: effect.Schema.Number,
4932
+ swarmItemsTotal: effect.Schema.Number,
4933
+ prsMerged: effect.Schema.Number,
4934
+ awaitingUat: effect.Schema.Number
5166
4935
  });
5167
- const decodeFlywheelStats = effect.Schema.decodeUnknownSync(FlywheelStats);
5168
- const encodeFlywheelStats = effect.Schema.encodeSync(FlywheelStats);
5169
- //#endregion
5170
- //#region src/orders.ts
5171
- const OrderBookLane = effect.Schema.Literals(["A", "B"]);
5172
- const OrderBookStatus = effect.Schema.Literals([
4936
+ /**
4937
+ * Pipeline verbs — display state only. They no longer gate the merge queue.
4938
+ *
4939
+ * History worth keeping (PAN-1736 / PAN-1759): the merge queue used to be
4940
+ * derived by filtering these verbs, treating only "shipping" or "merging" as
4941
+ * "at the merge gate". Any other verb on an issue that was ready_for_merge in
4942
+ * the review DB silently dropped it from the queue and from UAT batch
4943
+ * assembly — RUN-18 shipped an empty queue with five ready issues exactly that
4944
+ * way — and the queue existed only while a run was emitting a pipeline at all.
4945
+ *
4946
+ * PAN-1696 removed that coupling. The ready set is now sourced from the
4947
+ * review-status records per project (`listEligibleCandidatesByProject` +
4948
+ * `computeMergeQueueFromCandidates` in src/lib/flywheel-merge-order.ts), which
4949
+ * needs no flywheel run and cannot be affected by which verb an orchestrator
4950
+ * chose to report. Adding a verb here therefore has no merge-queue consequence;
4951
+ * it only changes what the dashboard displays.
4952
+ */
4953
+ const FlywheelPipelineVerb = effect.Schema.Literals([
4954
+ "planning",
4955
+ "working",
4956
+ "reviewing",
4957
+ "testing",
4958
+ "shipping",
4959
+ "merging",
4960
+ "blocked",
4961
+ "parked"
4962
+ ]);
4963
+ const FlywheelPipelineStatus = effect.Schema.Literals([
4964
+ "queued",
4965
+ "running",
4966
+ "blocked",
4967
+ "passed",
4968
+ "failed",
4969
+ "merged",
4970
+ "parked"
4971
+ ]);
4972
+ const FlywheelPipelineItem = effect.Schema.Struct({
4973
+ issueId: effect.Schema.String,
4974
+ title: effect.Schema.String,
4975
+ verb: FlywheelPipelineVerb,
4976
+ status: FlywheelPipelineStatus,
4977
+ progressPercent: effect.Schema.optional(effect.Schema.Number),
4978
+ agentId: effect.Schema.optional(effect.Schema.String),
4979
+ pr: effect.Schema.optional(effect.Schema.Number),
4980
+ mergeOrder: effect.Schema.optional(effect.Schema.Number),
4981
+ conflictsWith: effect.Schema.optional(effect.Schema.Array(effect.Schema.String))
4982
+ });
4983
+ const FlywheelSubstrateBugStatus = effect.Schema.Literals([
4984
+ "filed",
4985
+ "fixed",
4986
+ "workaround"
4987
+ ]);
4988
+ const FlywheelSubstrateBug = effect.Schema.Struct({
4989
+ issueId: effect.Schema.String,
4990
+ title: effect.Schema.String,
4991
+ status: FlywheelSubstrateBugStatus,
4992
+ commitSha: effect.Schema.optional(effect.Schema.String),
4993
+ url: effect.Schema.optional(FlywheelHttpUrl)
4994
+ });
4995
+ const FlywheelAgentStatus = effect.Schema.Literals([
4996
+ "starting",
4997
+ "running",
4998
+ "waiting",
4999
+ "idle",
5000
+ "stopped",
5001
+ "error"
5002
+ ]);
5003
+ const FlywheelAgent = effect.Schema.Struct({
5004
+ id: effect.Schema.String,
5005
+ label: effect.Schema.String,
5006
+ status: FlywheelAgentStatus,
5007
+ issueId: effect.Schema.optional(effect.Schema.String),
5008
+ role: effect.Schema.optional(effect.Schema.String),
5009
+ model: effect.Schema.optional(effect.Schema.String),
5010
+ ctxPercent: effect.Schema.optional(effect.Schema.Number),
5011
+ currentAction: effect.Schema.optional(effect.Schema.String)
5012
+ });
5013
+ const FlywheelParkedItem = effect.Schema.Struct({
5014
+ issueId: effect.Schema.String,
5015
+ title: effect.Schema.String,
5016
+ reason: effect.Schema.String,
5017
+ parkedAt: effect.Schema.optional(effect.Schema.String)
5018
+ });
5019
+ const FlywheelSuggestionAction = effect.Schema.Literals([
5020
+ "start",
5021
+ "resume",
5022
+ "plan",
5023
+ "review",
5024
+ "merge",
5025
+ "unblock",
5026
+ "park",
5027
+ "investigate",
5028
+ "wait"
5029
+ ]);
5030
+ const FlywheelSuggestionPriority = effect.Schema.Literals([
5031
+ "urgent",
5032
+ "high",
5033
+ "medium",
5034
+ "low"
5035
+ ]);
5036
+ const FlywheelSuggestion = effect.Schema.Struct({
5037
+ action: FlywheelSuggestionAction,
5038
+ issueId: effect.Schema.optional(effect.Schema.String),
5039
+ rationale: effect.Schema.String,
5040
+ priority: FlywheelSuggestionPriority,
5041
+ filedBy: effect.Schema.optional(effect.Schema.Literals(["agent", "operator"])),
5042
+ weight: effect.Schema.optional(effect.Schema.Number),
5043
+ weightReason: effect.Schema.optional(effect.Schema.String)
5044
+ });
5045
+ const FlywheelSystemStatus = effect.Schema.Struct({
5046
+ mainHead: effect.Schema.String,
5047
+ ramUsedMb: effect.Schema.Number,
5048
+ ramTotalMb: effect.Schema.Number,
5049
+ swapUsedMb: effect.Schema.Number,
5050
+ swapTotalMb: effect.Schema.Number,
5051
+ agentsActive: effect.Schema.Number,
5052
+ agentsCap: effect.Schema.Number
5053
+ });
5054
+ const FlywheelOrders = effect.Schema.Struct({
5055
+ bookId: effect.Schema.String,
5056
+ bookName: effect.Schema.String,
5057
+ landed: effect.Schema.Number,
5058
+ total: effect.Schema.Number,
5059
+ laneAInFlight: effect.Schema.Array(effect.Schema.String),
5060
+ laneBInFlight: effect.Schema.optional(effect.Schema.String),
5061
+ drained: effect.Schema.Boolean
5062
+ });
5063
+ const FlywheelStatus = effect.Schema.Struct({
5064
+ runId: FlywheelRunId,
5065
+ startedAt: effect.Schema.String,
5066
+ elapsedMs: effect.Schema.Number,
5067
+ orchestrator: FlywheelOrchestrator,
5068
+ headline: FlywheelHeadline,
5069
+ activePipeline: effect.Schema.Array(FlywheelPipelineItem),
5070
+ substrateBugs: effect.Schema.Array(FlywheelSubstrateBug),
5071
+ agents: effect.Schema.Array(FlywheelAgent),
5072
+ parked: effect.Schema.Array(FlywheelParkedItem),
5073
+ suggestions: effect.Schema.Array(FlywheelSuggestion).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed([]))),
5074
+ system: FlywheelSystemStatus,
5075
+ openQuestions: effect.Schema.Array(effect.Schema.String),
5076
+ orders: effect.Schema.optional(FlywheelOrders),
5077
+ scope: effect.Schema.optional(FlywheelScope),
5078
+ ticks: effect.Schema.Number,
5079
+ lastTickAt: effect.Schema.String
5080
+ });
5081
+ //#endregion
5082
+ //#region src/flywheel-stats.ts
5083
+ const FlywheelStatsCriterionStatus = effect.Schema.Literals([
5084
+ "green",
5085
+ "yellow",
5086
+ "red",
5087
+ "insufficient_data"
5088
+ ]);
5089
+ const FlywheelStatsTrend = effect.Schema.Literals([
5090
+ "up",
5091
+ "down",
5092
+ "flat"
5093
+ ]);
5094
+ const FlywheelStatsCriterionValueObject = effect.Schema.Record(effect.Schema.String, effect.Schema.Json);
5095
+ const FlywheelStatsCriterionValue = effect.Schema.Union([effect.Schema.Number, FlywheelStatsCriterionValueObject]);
5096
+ const FlywheelStatsCriterion = effect.Schema.Struct({
5097
+ label: effect.Schema.String,
5098
+ value: FlywheelStatsCriterionValue,
5099
+ target: FlywheelStatsCriterionValue,
5100
+ status: FlywheelStatsCriterionStatus,
5101
+ trend: effect.Schema.optional(FlywheelStatsTrend),
5102
+ sampleSize: effect.Schema.Number,
5103
+ dataSufficient: effect.Schema.Boolean
5104
+ });
5105
+ const FlywheelStatsCriteria = effect.Schema.Struct({
5106
+ c1_bugRate: FlywheelStatsCriterion,
5107
+ c2_p0Bugs: FlywheelStatsCriterion,
5108
+ c3_passRate: FlywheelStatsCriterion,
5109
+ c4_mttr: FlywheelStatsCriterion,
5110
+ c5_intervention: FlywheelStatsCriterion,
5111
+ c6_timeConsistency: FlywheelStatsCriterion,
5112
+ c7_flake: FlywheelStatsCriterion
5113
+ });
5114
+ const FlywheelStats = effect.Schema.Struct({
5115
+ window: effect.Schema.String,
5116
+ generatedAt: effect.Schema.String,
5117
+ criteria: FlywheelStatsCriteria
5118
+ });
5119
+ const decodeFlywheelStats = effect.Schema.decodeUnknownSync(FlywheelStats);
5120
+ const encodeFlywheelStats = effect.Schema.encodeSync(FlywheelStats);
5121
+ //#endregion
5122
+ //#region src/orders.ts
5123
+ const OrderBookLane = effect.Schema.Literals(["A", "B"]);
5124
+ const OrderBookStatus = effect.Schema.Literals([
5173
5125
  "draft",
5174
5126
  "ready",
5175
5127
  "running",
@@ -5518,6 +5470,18 @@ const FeatureRegistryEntry = effect.Schema.Struct({
5518
5470
  });
5519
5471
  //#endregion
5520
5472
  //#region src/harness-behavior.ts
5473
+ const AGENT_SESSION_PREFIXES = [
5474
+ "agent-",
5475
+ "planning-",
5476
+ "specialist-",
5477
+ "strike-",
5478
+ "inspect-"
5479
+ ];
5480
+ const AGENT_SESSION_SINGLETONS = new Set(["flywheel-orchestrator", "conv-flywheel-orchestrator"]);
5481
+ /** Canonical synthetic agent-session identity shared by dashboard client/server. */
5482
+ function isAgentSessionName(name) {
5483
+ return AGENT_SESSION_SINGLETONS.has(name) || AGENT_SESSION_PREFIXES.some((prefix) => name.startsWith(prefix));
5484
+ }
5521
5485
  const CLAUDE_CODE_BEHAVIOR = {
5522
5486
  displayName: "Claude Code",
5523
5487
  nativeCommands: [
@@ -6276,12 +6240,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6276
6240
  "required": false,
6277
6241
  "valueHint": null
6278
6242
  },
6279
- {
6280
- "flags": "--shadow-only",
6281
- "description": "Show only shadowed issues",
6282
- "required": false,
6283
- "valueHint": null
6284
- },
6285
6243
  {
6286
6244
  "flags": "--triage",
6287
6245
  "description": "Show triage queue",
@@ -6296,19 +6254,13 @@ const COMPOSER_COMMAND_MANIFEST = [
6296
6254
  "id": "pan-show",
6297
6255
  "path": ["show"],
6298
6256
  "display": "/pan show",
6299
- "description": "Unified lens: shadow state, CV, context, health for one issue",
6257
+ "description": "Unified lens: derived issue state, CV, context, health for one issue",
6300
6258
  "args": [{
6301
6259
  "name": "id",
6302
6260
  "required": true,
6303
6261
  "variadic": false
6304
6262
  }],
6305
6263
  "options": [
6306
- {
6307
- "flags": "--shadow",
6308
- "description": "Shadow state details only",
6309
- "required": false,
6310
- "valueHint": null
6311
- },
6312
6264
  {
6313
6265
  "flags": "--cv",
6314
6266
  "description": "Agent work history only",
@@ -6360,32 +6312,12 @@ const COMPOSER_COMMAND_MANIFEST = [
6360
6312
  "id": "pan-review",
6361
6313
  "path": ["review"],
6362
6314
  "display": "/pan review",
6363
- "description": "Review-loop management: pending items, request re-review, reset cycles",
6315
+ "description": "Review-loop management: request re-review, abort reviewers, restart a round",
6364
6316
  "args": [],
6365
6317
  "options": [],
6366
6318
  "aliases": [],
6367
6319
  "category": "Review"
6368
6320
  },
6369
- {
6370
- "id": "pan-review-pending",
6371
- "path": ["review", "pending"],
6372
- "display": "/pan review pending",
6373
- "description": "List completed work awaiting review",
6374
- "args": [],
6375
- "options": [{
6376
- "flags": "--ready",
6377
- "description": "List issues ready for merge (review+test green, not merged) regardless of origin",
6378
- "required": false,
6379
- "valueHint": null
6380
- }, {
6381
- "flags": "--blocked",
6382
- "description": "List issues blocked in review/test/merge from the SQLite review-status store",
6383
- "required": false,
6384
- "valueHint": null
6385
- }],
6386
- "aliases": [],
6387
- "category": "Review"
6388
- },
6389
6321
  {
6390
6322
  "id": "pan-review-request",
6391
6323
  "path": ["review", "request"],
@@ -6405,39 +6337,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6405
6337
  "aliases": [],
6406
6338
  "category": "Review"
6407
6339
  },
6408
- {
6409
- "id": "pan-review-reset",
6410
- "path": ["review", "reset"],
6411
- "display": "/pan review reset",
6412
- "description": "Reset review/test/merge cycles (human override)",
6413
- "args": [{
6414
- "name": "id",
6415
- "required": true,
6416
- "variadic": false
6417
- }],
6418
- "options": [{
6419
- "flags": "--session",
6420
- "description": "Also clear all saved Claude review-session pointers",
6421
- "required": false,
6422
- "valueHint": null
6423
- }],
6424
- "aliases": [],
6425
- "category": "Review"
6426
- },
6427
- {
6428
- "id": "pan-review-resync",
6429
- "path": ["review", "resync"],
6430
- "display": "/pan review resync",
6431
- "description": "Re-emit canonical review status (heal a lost pipeline event)",
6432
- "args": [{
6433
- "name": "id",
6434
- "required": true,
6435
- "variadic": false
6436
- }],
6437
- "options": [],
6438
- "aliases": [],
6439
- "category": "Review"
6440
- },
6441
6340
  {
6442
6341
  "id": "pan-review-abort",
6443
6342
  "path": ["review", "abort"],
@@ -6452,24 +6351,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6452
6351
  "aliases": [],
6453
6352
  "category": "Review"
6454
6353
  },
6455
- {
6456
- "id": "pan-review-mode",
6457
- "path": ["review", "mode"],
6458
- "display": "/pan review mode",
6459
- "description": "Set per-issue review mode (quick, full, or none)",
6460
- "args": [{
6461
- "name": "id",
6462
- "required": true,
6463
- "variadic": false
6464
- }, {
6465
- "name": "mode",
6466
- "required": true,
6467
- "variadic": false
6468
- }],
6469
- "options": [],
6470
- "aliases": [],
6471
- "category": "Review"
6472
- },
6473
6354
  {
6474
6355
  "id": "pan-review-restart",
6475
6356
  "path": ["review", "restart"],
@@ -6494,56 +6375,17 @@ const COMPOSER_COMMAND_MANIFEST = [
6494
6375
  "aliases": [],
6495
6376
  "category": "Review"
6496
6377
  },
6497
- {
6498
- "id": "pan-verify",
6499
- "path": ["verify"],
6500
- "display": "/pan verify",
6501
- "description": "Verification-gate overrides",
6502
- "args": [],
6503
- "options": [],
6504
- "aliases": [],
6505
- "category": "CLI"
6506
- },
6507
- {
6508
- "id": "pan-verify-waive-test-removal",
6509
- "path": ["verify", "waive-test-removal"],
6510
- "display": "/pan verify waive-test-removal",
6511
- "description": "Record an operator waiver letting a net test-call removal past the test-skip gate at the current head",
6512
- "args": [{
6513
- "name": "id",
6514
- "required": true,
6515
- "variadic": false
6516
- }],
6517
- "options": [{
6518
- "flags": "--reason <reason>",
6519
- "description": "Why the removed tests are not coming back",
6520
- "required": true,
6521
- "valueHint": "reason"
6522
- }],
6523
- "aliases": [],
6524
- "category": "CLI"
6525
- },
6526
6378
  {
6527
6379
  "id": "pan-staffing",
6528
6380
  "path": ["staffing"],
6529
6381
  "display": "/pan staffing",
6530
- "description": "Show or set per-issue work-model and swarm overrides",
6382
+ "description": "Show the work model and swarm policy in effect for an issue",
6531
6383
  "args": [{
6532
6384
  "name": "id",
6533
6385
  "required": true,
6534
6386
  "variadic": false
6535
6387
  }],
6536
- "options": [{
6537
- "flags": "--model <model>",
6538
- "description": "Set the work model, or default to clear the override",
6539
- "required": true,
6540
- "valueHint": "model"
6541
- }, {
6542
- "flags": "--swarm <mode>",
6543
- "description": "Set swarm mode (off, auto, always), or default to clear the override",
6544
- "required": true,
6545
- "valueHint": "mode"
6546
- }],
6388
+ "options": [],
6547
6389
  "aliases": [],
6548
6390
  "category": "Lifecycle"
6549
6391
  },
@@ -6561,7 +6403,7 @@ const COMPOSER_COMMAND_MANIFEST = [
6561
6403
  "id": "pan-backlog-write-sequence",
6562
6404
  "path": ["backlog", "write-sequence"],
6563
6405
  "display": "/pan backlog write-sequence",
6564
- "description": "Validate a SequenceDoc JSON file and write it to .pan/backlog/sequence.md (triggers auto-commit)",
6406
+ "description": "Validate a SequenceDoc JSON file, write it to .pan/backlog/sequence.md, and commit it",
6565
6407
  "args": [{
6566
6408
  "name": "file",
6567
6409
  "required": true,
@@ -6576,21 +6418,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6576
6418
  "aliases": [],
6577
6419
  "category": "Lifecycle"
6578
6420
  },
6579
- {
6580
- "id": "pan-backlog-forecast",
6581
- "path": ["backlog", "forecast"],
6582
- "display": "/pan backlog forecast",
6583
- "description": "Pickup forecast (waves / needs-planning / cohort / stats) from sequence.md + SQLite — no HTTP (sandbox-safe)",
6584
- "args": [],
6585
- "options": [{
6586
- "flags": "-n, --n <n>",
6587
- "description": "Wave size (default 5)",
6588
- "required": true,
6589
- "valueHint": "n"
6590
- }],
6591
- "aliases": [],
6592
- "category": "Lifecycle"
6593
- },
6594
6421
  {
6595
6422
  "id": "pan-plan",
6596
6423
  "path": ["plan"],
@@ -6802,25 +6629,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6802
6629
  "aliases": ["stop"],
6803
6630
  "category": "Lifecycle"
6804
6631
  },
6805
- {
6806
- "id": "pan-reset-to-planned",
6807
- "path": ["reset-to-planned"],
6808
- "display": "/pan reset-to-planned",
6809
- "description": "Return a finalized issue to post-planning without deleting its workspace, plan, commits, or branch",
6810
- "args": [{
6811
- "name": "id",
6812
- "required": true,
6813
- "variadic": false
6814
- }],
6815
- "options": [{
6816
- "flags": "--dry-run",
6817
- "description": "Show the exact reset without changing state",
6818
- "required": false,
6819
- "valueHint": null
6820
- }],
6821
- "aliases": [],
6822
- "category": "Lifecycle"
6823
- },
6824
6632
  {
6825
6633
  "id": "pan-reset-session",
6826
6634
  "path": ["reset-session"],
@@ -6868,34 +6676,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6868
6676
  "aliases": [],
6869
6677
  "category": "Lifecycle"
6870
6678
  },
6871
- {
6872
- "id": "pan-untroubled",
6873
- "path": ["untroubled"],
6874
- "display": "/pan untroubled",
6875
- "description": "Clear an agent troubled gate without spawning it",
6876
- "args": [{
6877
- "name": "id",
6878
- "required": true,
6879
- "variadic": false
6880
- }],
6881
- "options": [],
6882
- "aliases": [],
6883
- "category": "Lifecycle"
6884
- },
6885
- {
6886
- "id": "pan-unstick",
6887
- "path": ["unstick"],
6888
- "display": "/pan unstick",
6889
- "description": "Clear an issue stuck gate without resetting a merged lifecycle",
6890
- "args": [{
6891
- "name": "id",
6892
- "required": true,
6893
- "variadic": false
6894
- }],
6895
- "options": [],
6896
- "aliases": [],
6897
- "category": "CLI"
6898
- },
6899
6679
  {
6900
6680
  "id": "pan-fork",
6901
6681
  "path": ["fork"],
@@ -7139,13 +6919,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7139
6919
  },
7140
6920
  {
7141
6921
  "flags": "--strike",
7142
- "description": "Strike-agent shape: skip review-pipeline dispatch (used by `pan strike` agents that merged directly to main)",
7143
- "required": false,
7144
- "valueHint": null
7145
- },
7146
- {
7147
- "flags": "--json",
7148
- "description": "Output as JSON",
6922
+ "description": "Strike shape: verify the strike branch is contained in origin/main; no PR is opened",
7149
6923
  "required": false,
7150
6924
  "valueHint": null
7151
6925
  }
@@ -7153,20 +6927,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7153
6927
  "aliases": [],
7154
6928
  "category": "Lifecycle"
7155
6929
  },
7156
- {
7157
- "id": "pan-approve",
7158
- "path": ["approve"],
7159
- "display": "/pan approve",
7160
- "description": "[REMOVED] Use dashboard MERGE button instead",
7161
- "args": [{
7162
- "name": "id",
7163
- "required": true,
7164
- "variadic": false
7165
- }],
7166
- "options": [],
7167
- "aliases": [],
7168
- "category": "Lifecycle"
7169
- },
7170
6930
  {
7171
6931
  "id": "pan-reopen",
7172
6932
  "path": ["reopen"],
@@ -7348,25 +7108,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7348
7108
  "options": [
7349
7109
  {
7350
7110
  "flags": "--model <model>",
7351
- "description": "Work model to use and persist for later respawns (defaults to Cloister config)",
7352
- "required": true,
7353
- "valueHint": "model"
7354
- },
7355
- {
7356
- "flags": "--swarm <mode>",
7357
- "description": "Per-issue swarm policy: off | auto | always",
7358
- "required": true,
7359
- "valueHint": "mode"
7360
- },
7361
- {
7362
- "flags": "--review-mode <mode>",
7363
- "description": "Per-issue review mode: quick | full | none",
7364
- "required": true,
7365
- "valueHint": "mode"
7366
- },
7367
- {
7368
- "flags": "--review-model <model>",
7369
- "description": "Per-issue review model override",
7111
+ "description": "Work model for this session (defaults to Cloister config)",
7370
7112
  "required": true,
7371
7113
  "valueHint": "model"
7372
7114
  },
@@ -7394,18 +7136,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7394
7136
  "required": false,
7395
7137
  "valueHint": null
7396
7138
  },
7397
- {
7398
- "flags": "--shadow",
7399
- "description": "Enable shadow mode",
7400
- "required": false,
7401
- "valueHint": null
7402
- },
7403
- {
7404
- "flags": "--no-shadow",
7405
- "description": "Disable shadow mode",
7406
- "required": false,
7407
- "valueHint": null
7408
- },
7409
7139
  {
7410
7140
  "flags": "--remote",
7411
7141
  "description": "Use remote workspace (Fly.io)",
@@ -7461,8 +7191,8 @@ const COMPOSER_COMMAND_MANIFEST = [
7461
7191
  "valueHint": null
7462
7192
  },
7463
7193
  {
7464
- "flags": "--off-book",
7465
- "description": "Allow one work-agent dispatch outside the active order book and log the override",
7194
+ "flags": "--skip-freshness",
7195
+ "description": "Bypass the plan-freshness preflight and spawn even if the plan names files that no longer exist",
7466
7196
  "required": false,
7467
7197
  "valueHint": null
7468
7198
  }
@@ -7474,7 +7204,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7474
7204
  "id": "pan-strike",
7475
7205
  "path": ["strike"],
7476
7206
  "display": "/pan strike",
7477
- "description": "Spawn strike agent(s) — implement and push a strike branch for Deacon to land through the verified merge door. Bypasses plan/review/test/ship.",
7207
+ "description": "Spawn strike agent(s) — implement a fix on a strike branch and open a PR against main for the operator to merge. Bypasses plan/review/test/ship.",
7478
7208
  "args": [{
7479
7209
  "name": "ids",
7480
7210
  "required": true,
@@ -7509,20 +7239,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7509
7239
  "aliases": [],
7510
7240
  "category": "Lifecycle"
7511
7241
  },
7512
- {
7513
- "id": "pan-strike-ready",
7514
- "path": ["strike-ready"],
7515
- "display": "/pan strike-ready",
7516
- "description": "Persist readiness for a pushed strike branch so Deacon can land it",
7517
- "args": [{
7518
- "name": "id",
7519
- "required": true,
7520
- "variadic": false
7521
- }],
7522
- "options": [],
7523
- "aliases": [],
7524
- "category": "Lifecycle"
7525
- },
7526
7242
  {
7527
7243
  "id": "pan-knowledge",
7528
7244
  "path": ["knowledge"],
@@ -7789,7 +7505,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7789
7505
  "id": "pan-task",
7790
7506
  "path": ["task"],
7791
7507
  "display": "/pan task",
7792
- "description": "Read and update xBRIEF task state for one issue",
7508
+ "description": "Read and update xBRIEF item state for one issue",
7793
7509
  "args": [],
7794
7510
  "options": [],
7795
7511
  "aliases": [],
@@ -7851,32 +7567,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7851
7567
  "required": true,
7852
7568
  "variadic": false
7853
7569
  }],
7854
- "options": [
7855
- {
7856
- "flags": "--reason <text>",
7857
- "description": "Reason for the status change",
7858
- "required": true,
7859
- "valueHint": "text"
7860
- },
7861
- {
7862
- "flags": "--expected-sequence <n>",
7863
- "description": "Require the current task sequence",
7864
- "required": true,
7865
- "valueHint": "n"
7866
- },
7867
- {
7868
- "flags": "--force",
7869
- "description": "Override a non-terminal transition or claim owner; requires --reason",
7870
- "required": false,
7871
- "valueHint": null
7872
- },
7873
- {
7874
- "flags": "--json",
7875
- "description": "Print JSON",
7876
- "required": false,
7877
- "valueHint": null
7878
- }
7879
- ],
7570
+ "options": [{
7571
+ "flags": "--json",
7572
+ "description": "Print JSON",
7573
+ "required": false,
7574
+ "valueHint": null
7575
+ }],
7880
7576
  "aliases": [],
7881
7577
  "category": "Lifecycle"
7882
7578
  },
@@ -7884,7 +7580,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7884
7580
  "id": "pan-task-done",
7885
7581
  "path": ["task", "done"],
7886
7582
  "display": "/pan task done",
7887
- "description": "",
7583
+ "description": "Record an item as done. Requires a commit carrying \"Item: <item>\" on a pushed branch.",
7888
7584
  "args": [{
7889
7585
  "name": "issue",
7890
7586
  "required": true,
@@ -7894,32 +7590,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7894
7590
  "required": true,
7895
7591
  "variadic": false
7896
7592
  }],
7897
- "options": [
7898
- {
7899
- "flags": "--reason <text>",
7900
- "description": "Reason for the status change",
7901
- "required": true,
7902
- "valueHint": "text"
7903
- },
7904
- {
7905
- "flags": "--expected-sequence <n>",
7906
- "description": "Require the current task sequence",
7907
- "required": true,
7908
- "valueHint": "n"
7909
- },
7910
- {
7911
- "flags": "--force",
7912
- "description": "Override a non-terminal transition or claim owner; requires --reason",
7913
- "required": false,
7914
- "valueHint": null
7915
- },
7916
- {
7917
- "flags": "--json",
7918
- "description": "Print JSON",
7919
- "required": false,
7920
- "valueHint": null
7921
- }
7922
- ],
7593
+ "options": [{
7594
+ "flags": "--json",
7595
+ "description": "Print JSON",
7596
+ "required": false,
7597
+ "valueHint": null
7598
+ }],
7923
7599
  "aliases": [],
7924
7600
  "category": "Lifecycle"
7925
7601
  },
@@ -7937,75 +7613,35 @@ const COMPOSER_COMMAND_MANIFEST = [
7937
7613
  "required": true,
7938
7614
  "variadic": false
7939
7615
  }],
7940
- "options": [
7941
- {
7942
- "flags": "--reason <text>",
7943
- "description": "Reason for the status change",
7944
- "required": true,
7945
- "valueHint": "text"
7946
- },
7947
- {
7948
- "flags": "--expected-sequence <n>",
7949
- "description": "Require the current task sequence",
7950
- "required": true,
7951
- "valueHint": "n"
7952
- },
7953
- {
7954
- "flags": "--force",
7955
- "description": "Override a non-terminal transition or claim owner; requires --reason",
7956
- "required": false,
7957
- "valueHint": null
7958
- },
7959
- {
7960
- "flags": "--json",
7961
- "description": "Print JSON",
7962
- "required": false,
7963
- "valueHint": null
7964
- }
7965
- ],
7616
+ "options": [{
7617
+ "flags": "--json",
7618
+ "description": "Print JSON",
7619
+ "required": false,
7620
+ "valueHint": null
7621
+ }],
7966
7622
  "aliases": [],
7967
7623
  "category": "Lifecycle"
7968
7624
  },
7969
7625
  {
7970
- "id": "pan-task-unblock",
7971
- "path": ["task", "unblock"],
7972
- "display": "/pan task unblock",
7973
- "description": "",
7974
- "args": [{
7975
- "name": "issue",
7976
- "required": true,
7977
- "variadic": false
7978
- }, {
7979
- "name": "item",
7980
- "required": true,
7981
- "variadic": false
7982
- }],
7983
- "options": [
7984
- {
7985
- "flags": "--reason <text>",
7986
- "description": "Reason for the status change",
7987
- "required": true,
7988
- "valueHint": "text"
7989
- },
7990
- {
7991
- "flags": "--expected-sequence <n>",
7992
- "description": "Require the current task sequence",
7993
- "required": true,
7994
- "valueHint": "n"
7995
- },
7996
- {
7997
- "flags": "--force",
7998
- "description": "Override a non-terminal transition or claim owner; requires --reason",
7999
- "required": false,
8000
- "valueHint": null
8001
- },
8002
- {
8003
- "flags": "--json",
8004
- "description": "Print JSON",
8005
- "required": false,
8006
- "valueHint": null
8007
- }
8008
- ],
7626
+ "id": "pan-task-unblock",
7627
+ "path": ["task", "unblock"],
7628
+ "display": "/pan task unblock",
7629
+ "description": "",
7630
+ "args": [{
7631
+ "name": "issue",
7632
+ "required": true,
7633
+ "variadic": false
7634
+ }, {
7635
+ "name": "item",
7636
+ "required": true,
7637
+ "variadic": false
7638
+ }],
7639
+ "options": [{
7640
+ "flags": "--json",
7641
+ "description": "Print JSON",
7642
+ "required": false,
7643
+ "valueHint": null
7644
+ }],
8009
7645
  "aliases": [],
8010
7646
  "category": "Lifecycle"
8011
7647
  },
@@ -8023,32 +7659,12 @@ const COMPOSER_COMMAND_MANIFEST = [
8023
7659
  "required": true,
8024
7660
  "variadic": false
8025
7661
  }],
8026
- "options": [
8027
- {
8028
- "flags": "--reason <text>",
8029
- "description": "Reason for the status change",
8030
- "required": true,
8031
- "valueHint": "text"
8032
- },
8033
- {
8034
- "flags": "--expected-sequence <n>",
8035
- "description": "Require the current task sequence",
8036
- "required": true,
8037
- "valueHint": "n"
8038
- },
8039
- {
8040
- "flags": "--force",
8041
- "description": "Override a non-terminal transition or claim owner; requires --reason",
8042
- "required": false,
8043
- "valueHint": null
8044
- },
8045
- {
8046
- "flags": "--json",
8047
- "description": "Print JSON",
8048
- "required": false,
8049
- "valueHint": null
8050
- }
8051
- ],
7662
+ "options": [{
7663
+ "flags": "--json",
7664
+ "description": "Print JSON",
7665
+ "required": false,
7666
+ "valueHint": null
7667
+ }],
8052
7668
  "aliases": [],
8053
7669
  "category": "Lifecycle"
8054
7670
  },
@@ -8066,32 +7682,12 @@ const COMPOSER_COMMAND_MANIFEST = [
8066
7682
  "required": true,
8067
7683
  "variadic": false
8068
7684
  }],
8069
- "options": [
8070
- {
8071
- "flags": "--reason <text>",
8072
- "description": "Reason for the status change",
8073
- "required": true,
8074
- "valueHint": "text"
8075
- },
8076
- {
8077
- "flags": "--expected-sequence <n>",
8078
- "description": "Require the current task sequence",
8079
- "required": true,
8080
- "valueHint": "n"
8081
- },
8082
- {
8083
- "flags": "--force",
8084
- "description": "Override a non-terminal transition or claim owner; requires --reason",
8085
- "required": false,
8086
- "valueHint": null
8087
- },
8088
- {
8089
- "flags": "--json",
8090
- "description": "Print JSON",
8091
- "required": false,
8092
- "valueHint": null
8093
- }
8094
- ],
7685
+ "options": [{
7686
+ "flags": "--json",
7687
+ "description": "Print JSON",
7688
+ "required": false,
7689
+ "valueHint": null
7690
+ }],
8095
7691
  "aliases": [],
8096
7692
  "category": "Lifecycle"
8097
7693
  },
@@ -9038,7 +8634,7 @@ const COMPOSER_COMMAND_MANIFEST = [
9038
8634
  "id": "pan-rollout-status",
9039
8635
  "path": ["rollout", "status"],
9040
8636
  "display": "/pan rollout status",
9041
- "description": "Print the release set for an issue (releaseStatus + per-component status)",
8637
+ "description": "Print the release set for an issue (overall + per-component status)",
9042
8638
  "args": [{
9043
8639
  "name": "issueId",
9044
8640
  "required": true,
@@ -9912,7 +9508,7 @@ const COMPOSER_COMMAND_MANIFEST = [
9912
9508
  "id": "pan-parked",
9913
9509
  "path": ["parked"],
9914
9510
  "display": "/pan parked",
9915
- "description": "List every issue parked in a stall orbit (stuck flags, gates, failed merges, zombies), oldest first, with why + release condition",
9511
+ "description": "List every issue parked in a stall orbit (operator gates, zombie sessions, idle-running agents), oldest first, with why + release condition",
9916
9512
  "args": [],
9917
9513
  "options": [{
9918
9514
  "flags": "--json",
@@ -9923,35 +9519,6 @@ const COMPOSER_COMMAND_MANIFEST = [
9923
9519
  "aliases": [],
9924
9520
  "category": "CLI"
9925
9521
  },
9926
- {
9927
- "id": "pan-parked-ack",
9928
- "path": ["parked", "ack"],
9929
- "display": "/pan parked ack",
9930
- "description": "Batch-acknowledge parked rows (default orbit: needs-you), then print the flywheel hand-off",
9931
- "args": [],
9932
- "options": [
9933
- {
9934
- "flags": "--orbit <orbit>",
9935
- "description": "Parked orbit to acknowledge",
9936
- "required": true,
9937
- "valueHint": "orbit"
9938
- },
9939
- {
9940
- "flags": "--older-than <days>",
9941
- "description": "Only rows parked at least this many days",
9942
- "required": true,
9943
- "valueHint": "days"
9944
- },
9945
- {
9946
- "flags": "--dry-run",
9947
- "description": "List what would be acknowledged without writing",
9948
- "required": false,
9949
- "valueHint": null
9950
- }
9951
- ],
9952
- "aliases": [],
9953
- "category": "CLI"
9954
- },
9955
9522
  {
9956
9523
  "id": "pan-docs",
9957
9524
  "path": ["docs"],
@@ -10072,32 +9639,18 @@ const COMPOSER_COMMAND_MANIFEST = [
10072
9639
  "category": "Admin"
10073
9640
  },
10074
9641
  {
10075
- "id": "pan-admin-state",
10076
- "path": ["admin", "state"],
10077
- "display": "/pan admin state",
10078
- "description": "Permanent state administration",
10079
- "args": [],
10080
- "options": [],
10081
- "aliases": [],
10082
- "category": "Admin"
10083
- },
10084
- {
10085
- "id": "pan-admin-state-migrate",
10086
- "path": [
10087
- "admin",
10088
- "state",
10089
- "migrate"
10090
- ],
10091
- "display": "/pan admin state migrate",
10092
- "description": "Move permanent state to the orphan overdeck-state branch",
9642
+ "id": "pan-admin-seed-uat-fixtures",
9643
+ "path": ["admin", "seed-uat-fixtures"],
9644
+ "display": "/pan admin seed-uat-fixtures",
9645
+ "description": "Seed the obviously-fake FIX-1 issue fixture into a workspace container for UI UAT. Host mode: `pan admin seed-uat-fixtures <issue-id>` seeds and restarts that issue's workspace container from the host. `--local` runs the seed itself against the current OVERDECK_HOME — used by the host wrapper, or manually inside a container.",
10093
9646
  "args": [{
10094
- "name": "project",
10095
- "required": true,
9647
+ "name": "issue-id",
9648
+ "required": false,
10096
9649
  "variadic": false
10097
9650
  }],
10098
9651
  "options": [{
10099
- "flags": "--dry-run",
10100
- "description": "Print the exact migration plan without mutating anything",
9652
+ "flags": "--local",
9653
+ "description": "Seed the current (container-local) OVERDECK_HOME directly, without a host wrapper step",
10101
9654
  "required": false,
10102
9655
  "valueHint": null
10103
9656
  }],
@@ -10105,92 +9658,47 @@ const COMPOSER_COMMAND_MANIFEST = [
10105
9658
  "category": "Admin"
10106
9659
  },
10107
9660
  {
10108
- "id": "pan-admin-state-migrate-xbrief",
10109
- "path": [
10110
- "admin",
10111
- "state",
10112
- "migrate-xbrief"
10113
- ],
10114
- "display": "/pan admin state migrate-xbrief",
10115
- "description": "Rename state documents to .xbrief.json and migrate legacy envelopes",
9661
+ "id": "pan-admin-migrate-plan-home",
9662
+ "path": ["admin", "migrate-plan-home"],
9663
+ "display": "/pan admin migrate-plan-home",
9664
+ "description": "One-time bridge: copy open-issue planning artifacts and item progress from ~/.overdeck/state/<project>/ into <planHome>/.pan/ (PAN-3917 D8)",
10116
9665
  "args": [{
10117
- "name": "project",
9666
+ "name": "project-key",
10118
9667
  "required": true,
10119
9668
  "variadic": false
10120
9669
  }],
10121
- "options": [{
10122
- "flags": "--dry-run",
10123
- "description": "Print the exact xBRIEF migration plan without mutating anything",
10124
- "required": false,
10125
- "valueHint": null
10126
- }],
10127
- "aliases": [],
10128
- "category": "Admin"
10129
- },
10130
- {
10131
- "id": "pan-admin-state-backfill-agents",
10132
- "path": [
10133
- "admin",
10134
- "state",
10135
- "backfill-agents"
9670
+ "options": [
9671
+ {
9672
+ "flags": "--commit",
9673
+ "description": "Commit the copied artifacts in the plan home",
9674
+ "required": false,
9675
+ "valueHint": null
9676
+ },
9677
+ {
9678
+ "flags": "--dry-run",
9679
+ "description": "Preview what would be copied without writing anything",
9680
+ "required": false,
9681
+ "valueHint": null
9682
+ },
9683
+ {
9684
+ "flags": "--state-root <dir>",
9685
+ "description": "Override the state worktree root (tests / odd setups)",
9686
+ "required": true,
9687
+ "valueHint": "dir"
9688
+ },
9689
+ {
9690
+ "flags": "--plan-home <dir>",
9691
+ "description": "Override the plan home (tests / odd setups)",
9692
+ "required": true,
9693
+ "valueHint": "dir"
9694
+ },
9695
+ {
9696
+ "flags": "--open-issues <file>",
9697
+ "description": "Read open issue ids from a file instead of calling the tracker",
9698
+ "required": true,
9699
+ "valueHint": "file"
9700
+ }
10136
9701
  ],
10137
- "display": "/pan admin state backfill-agents",
10138
- "description": "Reconstruct durable agent runtime records from local and retained state",
10139
- "args": [{
10140
- "name": "project",
10141
- "required": false,
10142
- "variadic": false
10143
- }],
10144
- "options": [{
10145
- "flags": "--dry-run",
10146
- "description": "Report the records and sessions that would be written",
10147
- "required": false,
10148
- "valueHint": null
10149
- }],
10150
- "aliases": [],
10151
- "category": "Admin"
10152
- },
10153
- {
10154
- "id": "pan-admin-reconcile-labels",
10155
- "path": ["admin", "reconcile-labels"],
10156
- "display": "/pan admin reconcile-labels",
10157
- "description": "Reconcile pipeline labels from permanent issue truth",
10158
- "args": [],
10159
- "options": [{
10160
- "flags": "--dry-run",
10161
- "description": "Print changes without mutating labels",
10162
- "required": false,
10163
- "valueHint": null
10164
- }],
10165
- "aliases": [],
10166
- "category": "Admin"
10167
- },
10168
- {
10169
- "id": "pan-admin-migrate-legacy-agent-dirs",
10170
- "path": ["admin", "migrate-legacy-agent-dirs"],
10171
- "display": "/pan admin migrate-legacy-agent-dirs",
10172
- "description": "Copy pre-rebrand conv-* agent dirs into the configured Overdeck home without overwriting",
10173
- "args": [],
10174
- "options": [],
10175
- "aliases": [],
10176
- "category": "Admin"
10177
- },
10178
- {
10179
- "id": "pan-admin-seed-uat-fixtures",
10180
- "path": ["admin", "seed-uat-fixtures"],
10181
- "display": "/pan admin seed-uat-fixtures",
10182
- "description": "Seed the obviously-fake FIX-1 issue fixture into a workspace container for UI UAT. Host mode: `pan admin seed-uat-fixtures <issue-id>` seeds and restarts that issue's workspace container from the host. `--local` runs the seed itself against the current OVERDECK_HOME — used by the host wrapper, or manually inside a container.",
10183
- "args": [{
10184
- "name": "issue-id",
10185
- "required": false,
10186
- "variadic": false
10187
- }],
10188
- "options": [{
10189
- "flags": "--local",
10190
- "description": "Seed the current (container-local) OVERDECK_HOME directly, without a host wrapper step",
10191
- "required": false,
10192
- "valueHint": null
10193
- }],
10194
9702
  "aliases": [],
10195
9703
  "category": "Admin"
10196
9704
  },
@@ -10298,53 +9806,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10298
9806
  "aliases": [],
10299
9807
  "category": "Admin"
10300
9808
  },
10301
- {
10302
- "id": "pan-admin-cloister-brake",
10303
- "path": [
10304
- "admin",
10305
- "cloister",
10306
- "brake"
10307
- ],
10308
- "display": "/pan admin cloister brake",
10309
- "description": "Emergency brake - trim running work agents down to the concurrency cap (idle-first, resumable)",
10310
- "args": [],
10311
- "options": [{
10312
- "flags": "--json",
10313
- "description": "Output in JSON format",
10314
- "required": false,
10315
- "valueHint": null
10316
- }],
10317
- "aliases": [],
10318
- "category": "Admin"
10319
- },
10320
- {
10321
- "id": "pan-admin-cloister-freeze",
10322
- "path": [
10323
- "admin",
10324
- "cloister",
10325
- "freeze"
10326
- ],
10327
- "display": "/pan admin cloister freeze",
10328
- "description": "Globally pause the Deacon (patrols run but skip all actions); running agents unaffected",
10329
- "args": [],
10330
- "options": [],
10331
- "aliases": [],
10332
- "category": "Admin"
10333
- },
10334
- {
10335
- "id": "pan-admin-cloister-unfreeze",
10336
- "path": [
10337
- "admin",
10338
- "cloister",
10339
- "unfreeze"
10340
- ],
10341
- "display": "/pan admin cloister unfreeze",
10342
- "description": "Resume the Deacon from a global pause",
10343
- "args": [],
10344
- "options": [],
10345
- "aliases": [],
10346
- "category": "Admin"
10347
- },
10348
9809
  {
10349
9810
  "id": "pan-admin-specialists",
10350
9811
  "path": ["admin", "specialists"],
@@ -10433,7 +9894,7 @@ const COMPOSER_COMMAND_MANIFEST = [
10433
9894
  "done"
10434
9895
  ],
10435
9896
  "display": "/pan admin specialists done",
10436
- "description": "Signal specialist completion (deterministic status update)",
9897
+ "description": "Post a specialist verdict to the issue's pull/merge request (review, test, uat)",
10437
9898
  "args": [{
10438
9899
  "name": "type",
10439
9900
  "required": true,
@@ -10450,12 +9911,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10450
9911
  "required": true,
10451
9912
  "valueHint": "status"
10452
9913
  },
10453
- {
10454
- "flags": "--item <itemId>",
10455
- "description": "xBRIEF item ID (required for inspect verdicts)",
10456
- "required": true,
10457
- "valueHint": "itemId"
10458
- },
10459
9914
  {
10460
9915
  "flags": "--notes <notes>",
10461
9916
  "description": "Optional notes about the result",
@@ -10806,40 +10261,16 @@ const COMPOSER_COMMAND_MANIFEST = [
10806
10261
  "path": [
10807
10262
  "admin",
10808
10263
  "db",
10809
- "config"
10810
- ],
10811
- "display": "/pan admin db config",
10812
- "description": "Show database configuration for a project",
10813
- "args": [{
10814
- "name": "project",
10815
- "required": false,
10816
- "variadic": false
10817
- }],
10818
- "options": [],
10819
- "aliases": [],
10820
- "category": "Admin"
10821
- },
10822
- {
10823
- "id": "pan-admin-db-rebuild-agents",
10824
- "path": [
10825
- "admin",
10826
- "db",
10827
- "rebuild-agents"
10828
- ],
10829
- "display": "/pan admin db rebuild-agents",
10830
- "description": "Rebuild the SQLite agents table from state.json rollback sources (PAN-1908)",
10831
- "args": [],
10832
- "options": [{
10833
- "flags": "--dry-run",
10834
- "description": "Show what would be backfilled without writing",
10835
- "required": false,
10836
- "valueHint": null
10837
- }, {
10838
- "flags": "--verbose",
10839
- "description": "Log each processed agent",
10264
+ "config"
10265
+ ],
10266
+ "display": "/pan admin db config",
10267
+ "description": "Show database configuration for a project",
10268
+ "args": [{
10269
+ "name": "project",
10840
10270
  "required": false,
10841
- "valueHint": null
10271
+ "variadic": false
10842
10272
  }],
10273
+ "options": [],
10843
10274
  "aliases": [],
10844
10275
  "category": "Admin"
10845
10276
  },
@@ -10905,105 +10336,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10905
10336
  "aliases": [],
10906
10337
  "category": "Admin"
10907
10338
  },
10908
- {
10909
- "id": "pan-admin-db-backfill-records",
10910
- "path": [
10911
- "admin",
10912
- "db",
10913
- "backfill-records"
10914
- ],
10915
- "display": "/pan admin db backfill-records",
10916
- "description": "Backfill per-issue permanent records into the infra repo (PAN-1908)",
10917
- "args": [],
10918
- "options": [
10919
- {
10920
- "flags": "--issue-id <id>",
10921
- "description": "Backfill only this issue",
10922
- "required": true,
10923
- "valueHint": "id"
10924
- },
10925
- {
10926
- "flags": "--force",
10927
- "description": "Overwrite records even if unchanged",
10928
- "required": false,
10929
- "valueHint": null
10930
- },
10931
- {
10932
- "flags": "--verbose",
10933
- "description": "Log each processed issue",
10934
- "required": false,
10935
- "valueHint": null
10936
- }
10937
- ],
10938
- "aliases": [],
10939
- "category": "Admin"
10940
- },
10941
- {
10942
- "id": "pan-admin-db-restore-verdicts",
10943
- "path": [
10944
- "admin",
10945
- "db",
10946
- "restore-verdicts"
10947
- ],
10948
- "display": "/pan admin db restore-verdicts",
10949
- "description": "Rebuild review_status verdicts from per-issue records + live GitHub PR state (PAN-1922)",
10950
- "args": [],
10951
- "options": [
10952
- {
10953
- "flags": "--issue-id <id>",
10954
- "description": "Restore only this issue",
10955
- "required": true,
10956
- "valueHint": "id"
10957
- },
10958
- {
10959
- "flags": "--dry-run",
10960
- "description": "Show what would be restored without writing",
10961
- "required": false,
10962
- "valueHint": null
10963
- },
10964
- {
10965
- "flags": "--verbose",
10966
- "description": "Log each processed issue",
10967
- "required": false,
10968
- "valueHint": null
10969
- }
10970
- ],
10971
- "aliases": [],
10972
- "category": "Admin"
10973
- },
10974
- {
10975
- "id": "pan-admin-db-reconcile-merges",
10976
- "path": [
10977
- "admin",
10978
- "db",
10979
- "reconcile-merges"
10980
- ],
10981
- "display": "/pan admin db reconcile-merges",
10982
- "description": "Backfill fulfilled merge state from tracked PR and branch ancestry evidence (PAN-2311)",
10983
- "args": [],
10984
- "options": [
10985
- {
10986
- "flags": "--issue-id <id>",
10987
- "description": "Reconcile only this issue",
10988
- "required": true,
10989
- "valueHint": "id"
10990
- },
10991
- {
10992
- "flags": "--dry-run",
10993
- "description": "Show what would be reconciled without writing",
10994
- "required": false,
10995
- "valueHint": null
10996
- },
10997
- {
10998
- "flags": "--verbose",
10999
- "description": "Log each processed issue",
11000
- "required": false,
11001
- "valueHint": null
11002
- }
11003
- ],
11004
- "aliases": [],
11005
- "category": "Admin"
11006
- },
11007
10339
  {
11008
10340
  "id": "pan-admin-config",
11009
10341
  "path": ["admin", "config"],
@@ -11846,43 +11178,16 @@ const COMPOSER_COMMAND_MANIFEST = [
11846
11178
  "description": "Skip Qwen TTS daemon venv install (CUDA torch download is large)",
11847
11179
  "required": false,
11848
11180
  "valueHint": null
11849
- }
11850
- ],
11851
- "aliases": [],
11852
- "category": "Core"
11853
- },
11854
- {
11855
- "id": "pan-inspect",
11856
- "path": ["inspect"],
11857
- "display": "/pan inspect",
11858
- "description": "Request inspection of a completed xBRIEF item before proceeding to the next",
11859
- "args": [{
11860
- "name": "issueId",
11861
- "required": true,
11862
- "variadic": false
11863
- }],
11864
- "options": [
11865
- {
11866
- "flags": "--item <itemId>",
11867
- "description": "xBRIEF item ID to inspect",
11868
- "required": true,
11869
- "valueHint": "itemId"
11870
- },
11871
- {
11872
- "flags": "--workspace <path>",
11873
- "description": "Workspace path (auto-detected if not provided)",
11874
- "required": true,
11875
- "valueHint": "path"
11876
11181
  },
11877
11182
  {
11878
- "flags": "--deep",
11879
- "description": "Use the deep inspection sub-role",
11183
+ "flags": "--skip-herdr",
11184
+ "description": "Skip Herdr terminal backend install/verify (tmux-only hosts)",
11880
11185
  "required": false,
11881
11186
  "valueHint": null
11882
11187
  }
11883
11188
  ],
11884
11189
  "aliases": [],
11885
- "category": "Lifecycle"
11190
+ "category": "Core"
11886
11191
  },
11887
11192
  {
11888
11193
  "id": "pan-caveman-compress",
@@ -12038,111 +11343,86 @@ const COMPOSER_COMMAND_MANIFEST = [
12038
11343
  "category": "Lifecycle"
12039
11344
  },
12040
11345
  {
12041
- "id": "pan-flywheel",
12042
- "path": ["flywheel"],
12043
- "display": "/pan flywheel",
12044
- "description": "Flywheel orchestrator lifecycle and status helpers",
12045
- "args": [],
12046
- "options": [],
12047
- "aliases": [],
12048
- "category": "Flywheel"
12049
- },
12050
- {
12051
- "id": "pan-flywheel-merge-blockers",
12052
- "path": ["flywheel", "merge-blockers"],
12053
- "display": "/pan flywheel merge-blockers",
12054
- "description": "PRs that passed review but cannot merge (GitHub-native reasons) — reads SQLite directly, no HTTP (sandbox-safe)",
12055
- "args": [],
12056
- "options": [{
12057
- "flags": "--json",
12058
- "description": "Output JSON",
12059
- "required": false,
12060
- "valueHint": null
12061
- }],
12062
- "aliases": [],
12063
- "category": "Flywheel"
12064
- },
12065
- {
12066
- "id": "pan-flywheel-weights",
12067
- "path": ["flywheel", "weights"],
12068
- "display": "/pan flywheel weights",
12069
- "description": "Weighted substrate bugs by affected v1.0 criterion — reads SQLite directly, no HTTP (sandbox-safe)",
11346
+ "id": "pan-spawn",
11347
+ "path": ["spawn"],
11348
+ "display": "/pan spawn",
11349
+ "description": "Create a worker pane for one xBRIEF item in the issue workspace",
12070
11350
  "args": [],
12071
11351
  "options": [
12072
11352
  {
12073
11353
  "flags": "--issue <id>",
12074
- "description": "Filter to a single issue",
11354
+ "description": "Issue the worker belongs to",
12075
11355
  "required": true,
12076
11356
  "valueHint": "id"
12077
11357
  },
12078
11358
  {
12079
- "flags": "--window <dur>",
12080
- "description": "Stats window like 30d, 7d (default 30d)",
11359
+ "flags": "--item <item>",
11360
+ "description": "xBRIEF item the worker takes",
12081
11361
  "required": true,
12082
- "valueHint": "dur"
11362
+ "valueHint": "item"
12083
11363
  },
12084
11364
  {
12085
- "flags": "--json",
12086
- "description": "Output JSON",
12087
- "required": false,
12088
- "valueHint": null
11365
+ "flags": "--model <model>",
11366
+ "description": "Model the worker runs on",
11367
+ "required": true,
11368
+ "valueHint": "model"
11369
+ },
11370
+ {
11371
+ "flags": "--harness <harness>",
11372
+ "description": "Coding-agent harness (default: claude-code)",
11373
+ "required": true,
11374
+ "valueHint": "harness"
12089
11375
  }
12090
11376
  ],
12091
11377
  "aliases": [],
12092
- "category": "Flywheel"
11378
+ "category": "CLI"
12093
11379
  },
12094
11380
  {
12095
- "id": "pan-flywheel-start",
12096
- "path": ["flywheel", "start"],
12097
- "display": "/pan flywheel start",
12098
- "description": "Start the Flywheel orchestrator",
11381
+ "id": "pan-flywheel",
11382
+ "path": ["flywheel"],
11383
+ "display": "/pan flywheel",
11384
+ "description": "Start, stop, or check the flywheel conversation",
12099
11385
  "args": [],
12100
- "options": [{
12101
- "flags": "--brief <path>",
12102
- "description": "Path to the Flywheel brief",
12103
- "required": true,
12104
- "valueHint": "path"
12105
- }, {
12106
- "flags": "--orders <book-id>",
12107
- "description": "Bind the run to a validated order book",
12108
- "required": true,
12109
- "valueHint": "book-id"
12110
- }],
11386
+ "options": [],
12111
11387
  "aliases": [],
12112
11388
  "category": "Flywheel"
12113
11389
  },
12114
11390
  {
12115
- "id": "pan-flywheel-emit-status",
12116
- "path": ["flywheel", "emit-status"],
12117
- "display": "/pan flywheel emit-status",
12118
- "description": "Validate and publish a FlywheelStatus JSON snapshot to the local dashboard",
11391
+ "id": "pan-flywheel-start",
11392
+ "path": ["flywheel", "start"],
11393
+ "display": "/pan flywheel start",
11394
+ "description": "Launch a conversation running /pan-flywheel",
12119
11395
  "args": [],
12120
- "options": [{
12121
- "flags": "--file <path>",
12122
- "description": "Path to FlywheelStatus JSON, or - to read from stdin",
12123
- "required": true,
12124
- "valueHint": "path"
12125
- }],
11396
+ "options": [
11397
+ {
11398
+ "flags": "--model <model>",
11399
+ "description": "Model for the flywheel conversation",
11400
+ "required": true,
11401
+ "valueHint": "model"
11402
+ },
11403
+ {
11404
+ "flags": "--harness <harness>",
11405
+ "description": "Harness for the flywheel conversation",
11406
+ "required": true,
11407
+ "valueHint": "harness"
11408
+ },
11409
+ {
11410
+ "flags": "--cwd <path>",
11411
+ "description": "Working directory (default: cwd)",
11412
+ "required": true,
11413
+ "valueHint": "path"
11414
+ }
11415
+ ],
12126
11416
  "aliases": [],
12127
11417
  "category": "Flywheel"
12128
11418
  },
12129
11419
  {
12130
- "id": "pan-flywheel-config",
12131
- "path": ["flywheel", "config"],
12132
- "display": "/pan flywheel config",
12133
- "description": "Get or set Flywheel autonomy configuration",
11420
+ "id": "pan-flywheel-stop",
11421
+ "path": ["flywheel", "stop"],
11422
+ "display": "/pan flywheel stop",
11423
+ "description": "Stop the flywheel conversation",
12134
11424
  "args": [],
12135
- "options": [{
12136
- "flags": "--get [key]",
12137
- "description": "Print Flywheel config values",
12138
- "required": false,
12139
- "valueHint": "key"
12140
- }, {
12141
- "flags": "--set <key=value>",
12142
- "description": "Set a Flywheel config boolean",
12143
- "required": true,
12144
- "valueHint": "key=value"
12145
- }],
11425
+ "options": [],
12146
11426
  "aliases": [],
12147
11427
  "category": "Flywheel"
12148
11428
  },
@@ -12150,107 +11430,17 @@ const COMPOSER_COMMAND_MANIFEST = [
12150
11430
  "id": "pan-flywheel-status",
12151
11431
  "path": ["flywheel", "status"],
12152
11432
  "display": "/pan flywheel status",
12153
- "description": "Show the active Flywheel run status",
12154
- "args": [],
12155
- "options": [{
12156
- "flags": "--json",
12157
- "description": "Emit the raw FlywheelStatus JSON",
12158
- "required": false,
12159
- "valueHint": null
12160
- }],
12161
- "aliases": [],
12162
- "category": "Flywheel"
12163
- },
12164
- {
12165
- "id": "pan-flywheel-stats",
12166
- "path": ["flywheel", "stats"],
12167
- "display": "/pan flywheel stats",
12168
- "description": "Show Flywheel v1.0 readiness stats",
11433
+ "description": "Say whether the flywheel conversation is running",
12169
11434
  "args": [],
12170
11435
  "options": [{
12171
- "flags": "--window <duration>",
12172
- "description": "Stats window duration",
12173
- "required": true,
12174
- "valueHint": "duration"
12175
- }, {
12176
11436
  "flags": "--json",
12177
- "description": "Emit the raw FlywheelStats JSON",
12178
- "required": false,
12179
- "valueHint": null
12180
- }],
12181
- "aliases": [],
12182
- "category": "Flywheel"
12183
- },
12184
- {
12185
- "id": "pan-flywheel-pause",
12186
- "path": ["flywheel", "pause"],
12187
- "display": "/pan flywheel pause",
12188
- "description": "Pause the active Flywheel orchestrator run",
12189
- "args": [],
12190
- "options": [],
12191
- "aliases": [],
12192
- "category": "Flywheel"
12193
- },
12194
- {
12195
- "id": "pan-flywheel-resume",
12196
- "path": ["flywheel", "resume"],
12197
- "display": "/pan flywheel resume",
12198
- "description": "Resume the paused Flywheel orchestrator run",
12199
- "args": [],
12200
- "options": [],
12201
- "aliases": [],
12202
- "category": "Flywheel"
12203
- },
12204
- {
12205
- "id": "pan-flywheel-report",
12206
- "path": ["flywheel", "report"],
12207
- "display": "/pan flywheel report",
12208
- "description": "Finalize the active Flywheel run: write report.md, compact over-threshold FLYWHEEL-STATE.md history, commit State changes, and clear the active-run gate. Refuses to run while the orchestrator session is alive (pause or abort first).",
12209
- "args": [],
12210
- "options": [{
12211
- "flags": "--force",
12212
- "description": "Bypass the orchestrator-alive guard. Intended for the orchestrator role's own end-of-run call.",
12213
- "required": false,
12214
- "valueHint": null
12215
- }],
12216
- "aliases": [],
12217
- "category": "Flywheel"
12218
- },
12219
- {
12220
- "id": "pan-flywheel-complete",
12221
- "path": ["flywheel", "complete"],
12222
- "display": "/pan flywheel complete",
12223
- "description": "Complete a drained order-book run, write its report and retrospective, then continue mechanically",
12224
- "args": [],
12225
- "options": [{
12226
- "flags": "--force",
12227
- "description": "Complete even when the order book still has non-terminal items",
11437
+ "description": "Output as JSON",
12228
11438
  "required": false,
12229
11439
  "valueHint": null
12230
11440
  }],
12231
11441
  "aliases": [],
12232
11442
  "category": "Flywheel"
12233
11443
  },
12234
- {
12235
- "id": "pan-flywheel-stop",
12236
- "path": ["flywheel", "stop"],
12237
- "display": "/pan flywheel stop",
12238
- "description": "Stop the Flywheel orchestrator gracefully: kill any live session, write report.md, commit FLYWHEEL-STATE.md changes, and clear the active-run gate",
12239
- "args": [],
12240
- "options": [],
12241
- "aliases": [],
12242
- "category": "Flywheel"
12243
- },
12244
- {
12245
- "id": "pan-flywheel-abort",
12246
- "path": ["flywheel", "abort"],
12247
- "display": "/pan flywheel abort",
12248
- "description": "Discard the active Flywheel run without writing a report",
12249
- "args": [],
12250
- "options": [],
12251
- "aliases": [],
12252
- "category": "Flywheel"
12253
- },
12254
11444
  {
12255
11445
  "id": "pan-merge",
12256
11446
  "path": ["merge"],
@@ -13571,14 +12761,6 @@ const COMPOSER_COMMAND_VARIANTS = [
13571
12761
  "insert": "/pan plan --auto --auto-start ",
13572
12762
  "category": "Lifecycle"
13573
12763
  },
13574
- {
13575
- "id": "pan-review-reset-session",
13576
- "path": ["review", "reset"],
13577
- "display": "/pan review reset --session",
13578
- "description": "Reset review and clear saved Claude session",
13579
- "insert": "/pan review reset --session",
13580
- "category": "Review"
13581
- },
13582
12764
  {
13583
12765
  "id": "pan-fork-plain",
13584
12766
  "path": ["fork"],
@@ -13713,7 +12895,26 @@ const HOOK_INVENTORY = [
13713
12895
  const WIRED_HOOK_INVENTORY = HOOK_INVENTORY.filter((hook) => hook.wired);
13714
12896
  const WIRED_HOOK_NAMES = WIRED_HOOK_INVENTORY.map((hook) => hook.name);
13715
12897
  //#endregion
12898
+ //#region src/terminal-backend.ts
12899
+ const TERMINAL_BACKEND_NAMES = ["herdr", "tmux"];
12900
+ const AGENT_ROLES = [
12901
+ "work",
12902
+ "worker",
12903
+ "review",
12904
+ "test",
12905
+ "uat",
12906
+ "strike",
12907
+ "plan"
12908
+ ];
12909
+ function isTerminalBackendName(value) {
12910
+ return typeof value === "string" && TERMINAL_BACKEND_NAMES.includes(value);
12911
+ }
12912
+ function isAgentRole(value) {
12913
+ return typeof value === "string" && AGENT_ROLES.includes(value);
12914
+ }
12915
+ //#endregion
13716
12916
  exports.ACP_BEHAVIOR = ACP_BEHAVIOR;
12917
+ exports.AGENT_ROLES = AGENT_ROLES;
13717
12918
  exports.Activity = Activity;
13718
12919
  exports.ActivityDetailedEvent = ActivityDetailedEvent;
13719
12920
  exports.ActivityEntryEvent = ActivityEntryEvent;
@@ -13772,6 +12973,9 @@ exports.ArtifactUrls = ArtifactUrls;
13772
12973
  exports.ArtifactValidationCode = ArtifactValidationCode;
13773
12974
  exports.ArtifactValidationFinding = ArtifactValidationFinding;
13774
12975
  exports.ArtifactValidationResult = ArtifactValidationResult;
12976
+ exports.BackendPane = BackendPane;
12977
+ exports.BackendPaneChangedEvent = BackendPaneChangedEvent;
12978
+ exports.BackendPaneRemovedEvent = BackendPaneRemovedEvent;
13775
12979
  exports.BeadsFreshnessChangedEvent = BeadsFreshnessChangedEvent;
13776
12980
  exports.CHANNEL_REPLY_KIND_VALUES = CHANNEL_REPLY_KIND_VALUES;
13777
12981
  exports.CLAUDE_CODE_BEHAVIOR = CLAUDE_CODE_BEHAVIOR;
@@ -13823,6 +13027,9 @@ exports.DashboardLifecycleStartedEvent = DashboardLifecycleStartedEvent;
13823
13027
  exports.DashboardSnapshot = DashboardSnapshot;
13824
13028
  exports.DeepWipeRpc = DeepWipeRpc;
13825
13029
  exports.DeployStalenessSnapshot = DeployStalenessSnapshot;
13030
+ exports.DerivedBranchState = DerivedBranchState;
13031
+ exports.DerivedIssueState = DerivedIssueState;
13032
+ exports.DerivedPrState = DerivedPrState;
13826
13033
  exports.DiscoveredSessionSnapshot = DiscoveredSessionSnapshot;
13827
13034
  exports.DomainEvent = DomainEvent;
13828
13035
  exports.EDITORS = EDITORS;
@@ -13875,7 +13082,6 @@ exports.GetConversationStatsRpc = GetConversationStatsRpc;
13875
13082
  exports.GetDiscoveredSessionRpc = GetDiscoveredSessionRpc;
13876
13083
  exports.GetSessionsFeedFacetsRpc = GetSessionsFeedFacetsRpc;
13877
13084
  exports.GetSnapshotRpc = GetSnapshotRpc;
13878
- exports.GetWorkspaceDetailRpc = GetWorkspaceDetailRpc;
13879
13085
  exports.GlobalContextLayerRecord = GlobalContextLayerRecord;
13880
13086
  exports.GlobalContextLayerTarget = GlobalContextLayerTarget;
13881
13087
  exports.HOOK_INVENTORY = HOOK_INVENTORY;
@@ -13887,7 +13093,13 @@ exports.HygieneFinding = HygieneFinding;
13887
13093
  exports.HygienePullRequest = HygienePullRequest;
13888
13094
  exports.HygieneReport = HygieneReport;
13889
13095
  exports.INITIAL_READ_MODEL_STATE = INITIAL_READ_MODEL_STATE;
13096
+ exports.ISSUE_ATTENTIONS = ISSUE_ATTENTIONS;
13097
+ exports.ISSUE_STATES = ISSUE_STATES;
13098
+ exports.ISSUE_STATE_PRECEDENCE = ISSUE_STATE_PRECEDENCE;
13099
+ exports.IssueAttention = IssueAttention;
13890
13100
  exports.IssueId = IssueId;
13101
+ exports.IssueState = IssueState;
13102
+ exports.IssueStateChangedEvent = IssueStateChangedEvent;
13891
13103
  exports.IssueStatusChangedEvent = IssueStatusChangedEvent;
13892
13104
  exports.IssueTransitionedEvent = IssueTransitionedEvent;
13893
13105
  exports.IssuesDeltaEvent = IssuesDeltaEvent;
@@ -13921,7 +13133,6 @@ exports.MemoryStatusPhase = MemoryStatusPhase;
13921
13133
  exports.MemoryStatusUpdatedEvent = MemoryStatusUpdatedEvent;
13922
13134
  exports.MemoryTokenUsage = MemoryTokenUsage;
13923
13135
  exports.MergeReadyEvent = MergeReadyEvent;
13924
- exports.MergeStatusValue = MergeStatusValue;
13925
13136
  exports.ModelOrigin = ModelOrigin;
13926
13137
  exports.ModelOriginEntry = ModelOriginEntry;
13927
13138
  exports.OHMYPI_BEHAVIOR = OHMYPI_BEHAVIOR;
@@ -13942,7 +13153,6 @@ exports.PanRpcGroup = PanRpcGroup;
13942
13153
  exports.PendingTurn = PendingTurn;
13943
13154
  exports.PipelineReviewCompletedEvent = PipelineReviewCompletedEvent;
13944
13155
  exports.PipelineReviewStartedEvent = PipelineReviewStartedEvent;
13945
- exports.PipelineStatusChangedEvent = PipelineStatusChangedEvent;
13946
13156
  exports.PipelineTestCompletedEvent = PipelineTestCompletedEvent;
13947
13157
  exports.PipelineTestStartedEvent = PipelineTestStartedEvent;
13948
13158
  exports.PipelineVerificationFailedEvent = PipelineVerificationFailedEvent;
@@ -13953,6 +13163,8 @@ exports.PlanSubitemStatusChangedEvent = PlanSubitemStatusChangedEvent;
13953
13163
  exports.PlanningFailedEvent = PlanningFailedEvent;
13954
13164
  exports.PlanningStartedEvent = PlanningStartedEvent;
13955
13165
  exports.PlanningSyncEvent = PlanningSyncEvent;
13166
+ exports.PrChecksState = PrChecksState;
13167
+ exports.PrReviewState = PrReviewState;
13956
13168
  exports.ProjectCiHeadObservedEvent = ProjectCiHeadObservedEvent;
13957
13169
  exports.ProjectCiSnapshot = ProjectCiSnapshot;
13958
13170
  exports.ProjectCiSuite = ProjectCiSuite;
@@ -13969,7 +13181,6 @@ exports.ReadFileAtPathRpc = ReadFileAtPathRpc;
13969
13181
  exports.ReadWorkspaceFileInput = ReadWorkspaceFileInput;
13970
13182
  exports.ReadWorkspaceFileResult = ReadWorkspaceFileResult;
13971
13183
  exports.ReadWorkspaceFileRpc = ReadWorkspaceFileRpc;
13972
- exports.ReleaseStatusValue = ReleaseStatusValue;
13973
13184
  exports.ReplayEventsRpc = ReplayEventsRpc;
13974
13185
  exports.ResetMarker = ResetMarker;
13975
13186
  exports.ResetMarkerScope = ResetMarkerScope;
@@ -13987,13 +13198,9 @@ exports.RestartGateSnapshot = RestartGateSnapshot;
13987
13198
  exports.ReviewApprovedEvent = ReviewApprovedEvent;
13988
13199
  exports.ReviewCoordinatorDiedEvent = ReviewCoordinatorDiedEvent;
13989
13200
  exports.ReviewCoordinatorStartedEvent = ReviewCoordinatorStartedEvent;
13990
- exports.ReviewCycleEntry = ReviewCycleEntry;
13991
13201
  exports.ReviewReviewerCompletedEvent = ReviewReviewerCompletedEvent;
13992
13202
  exports.ReviewReviewerStartedEvent = ReviewReviewerStartedEvent;
13993
13203
  exports.ReviewSpecialistTimedOutEvent = ReviewSpecialistTimedOutEvent;
13994
- exports.ReviewStatusChangedEvent = ReviewStatusChangedEvent;
13995
- exports.ReviewStatusSnapshot = ReviewStatusSnapshot;
13996
- exports.ReviewStatusValue = ReviewStatusValue;
13997
13204
  exports.ReviewVerdictDispatchedEvent = ReviewVerdictDispatchedEvent;
13998
13205
  exports.ReviewVerdictRejectedEvent = ReviewVerdictRejectedEvent;
13999
13206
  exports.ReviewVerdictRestoreBlockedEvent = ReviewVerdictRestoreBlockedEvent;
@@ -14030,7 +13237,6 @@ exports.SubagentSummary = SubagentSummary;
14030
13237
  exports.SubscribeAgentOutputRpc = SubscribeAgentOutputRpc;
14031
13238
  exports.SubscribeConversationMessagesRpc = SubscribeConversationMessagesRpc;
14032
13239
  exports.SubscribeDomainEventsRpc = SubscribeDomainEventsRpc;
14033
- exports.SubscribeFlywheelStatusRpc = SubscribeFlywheelStatusRpc;
14034
13240
  exports.SubscribeIssueEventsRpc = SubscribeIssueEventsRpc;
14035
13241
  exports.SubscribeProjectSessionTreeRpc = SubscribeProjectSessionTreeRpc;
14036
13242
  exports.SubscribeTerminalRpc = SubscribeTerminalRpc;
@@ -14046,18 +13252,16 @@ exports.TELEMETRY_CLI_VERBS = TELEMETRY_CLI_VERBS;
14046
13252
  exports.TELEMETRY_EVENT_CATALOG = TELEMETRY_EVENT_CATALOG;
14047
13253
  exports.TELEMETRY_EVENT_NAMES = TELEMETRY_EVENT_NAMES;
14048
13254
  exports.TELEMETRY_PROPERTY_DOMAINS = TELEMETRY_PROPERTY_DOMAINS;
13255
+ exports.TERMINAL_BACKEND_NAMES = TERMINAL_BACKEND_NAMES;
14049
13256
  exports.TerminalCloseRpc = TerminalCloseRpc;
14050
13257
  exports.TerminalOpenRpc = TerminalOpenRpc;
14051
13258
  exports.TerminalOutput = TerminalOutput;
14052
13259
  exports.TerminalResizeRpc = TerminalResizeRpc;
14053
13260
  exports.TerminalWriteRpc = TerminalWriteRpc;
14054
13261
  exports.TestPassedEvent = TestPassedEvent;
14055
- exports.TestStatusValue = TestStatusValue;
14056
13262
  exports.ThinkingState = ThinkingState;
14057
13263
  exports.TurnDiffFileChange = TurnDiffFileChange;
14058
13264
  exports.TurnDiffSummary = TurnDiffSummary;
14059
- exports.UatStatusValue = UatStatusValue;
14060
- exports.VerificationStatusValue = VerificationStatusValue;
14061
13265
  exports.WIRED_HOOK_INVENTORY = WIRED_HOOK_INVENTORY;
14062
13266
  exports.WIRED_HOOK_NAMES = WIRED_HOOK_NAMES;
14063
13267
  exports.WS_METHODS = WS_METHODS;
@@ -14072,7 +13276,6 @@ exports.WorkspaceContextLayerTarget = WorkspaceContextLayerTarget;
14072
13276
  exports.WorkspaceCreatedEvent = WorkspaceCreatedEvent;
14073
13277
  exports.WorkspaceDeletedEvent = WorkspaceDeletedEvent;
14074
13278
  exports.WorkspaceDestroyedEvent = WorkspaceDestroyedEvent;
14075
- exports.WorkspaceDetail = WorkspaceDetail;
14076
13279
  exports.WorkspaceWipeStartedEvent = WorkspaceWipeStartedEvent;
14077
13280
  exports.WriteFileAtPathInput = WriteFileAtPathInput;
14078
13281
  exports.WriteFileAtPathResult = WriteFileAtPathResult;
@@ -14090,7 +13293,12 @@ exports.getHarnessBehavior = getHarnessBehavior;
14090
13293
  exports.getMaxMemoryObservationsPerIssue = getMaxMemoryObservationsPerIssue;
14091
13294
  exports.getMaxTurnDiffSummariesPerAgent = getMaxTurnDiffSummariesPerAgent;
14092
13295
  exports.getRuntimeBehavior = getRuntimeBehavior;
13296
+ exports.isAgentRole = isAgentRole;
13297
+ exports.isAgentSessionName = isAgentSessionName;
14093
13298
  exports.isChannelReplyKind = isChannelReplyKind;
13299
+ exports.isIssueAttention = isIssueAttention;
13300
+ exports.isIssueState = isIssueState;
13301
+ exports.isTerminalBackendName = isTerminalBackendName;
14094
13302
  exports.isTerminalTurnDiffSummaryStatus = isTerminalTurnDiffSummaryStatus;
14095
13303
  exports.normalizeChannelReplyPayload = normalizeChannelReplyPayload;
14096
13304
  exports.omitTurnDiffSummariesForAgent = omitTurnDiffSummariesForAgent;