@overdeck/contracts 0.51.0 → 0.61.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,145 @@ 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
+ /** Overdeck agent id: Herdr `agentId` token or live agent name; tmux session name (PAN-3920). */
34
+ agentId: effect.Schema.optional(effect.Schema.String),
35
+ /** Issue the pane belongs to; absent for operator conversations. */
36
+ issue: effect.Schema.optional(effect.Schema.String),
37
+ role: effect.Schema.Literals([
38
+ "work",
39
+ "worker",
40
+ "review",
41
+ "test",
42
+ "uat",
43
+ "strike",
44
+ "plan"
45
+ ]),
46
+ harness: effect.Schema.String,
47
+ model: effect.Schema.String,
48
+ state: effect.Schema.Literals([
49
+ "idle",
50
+ "working",
51
+ "blocked",
52
+ "done",
53
+ "exited",
54
+ "unknown"
55
+ ]),
56
+ /** Epoch millis the pane entered `state`; drives the `stuck` attention. */
57
+ stateSince: effect.Schema.optional(effect.Schema.Number),
58
+ /** Handle the terminal WebSocket attaches to. */
59
+ terminalId: effect.Schema.optional(effect.Schema.String),
60
+ /** Working directory of the pane (the issue workspace path). */
61
+ workspace: effect.Schema.optional(effect.Schema.String)
62
+ });
63
+ //#endregion
64
+ //#region src/derived-issue-state.ts
65
+ /**
66
+ * The nine pipeline states of the FR-6 table. They are mutually exclusive and
67
+ * resolved in this precedence (highest first), because the underlying facts
68
+ * overlap:
69
+ *
70
+ * closed > merged > ready > changes-requested > in-review > working >
71
+ * parked > planned > backlog
72
+ */
73
+ const IssueState = effect.Schema.Literals([
74
+ "backlog",
75
+ "parked",
76
+ "planned",
77
+ "working",
78
+ "in-review",
79
+ "changes-requested",
80
+ "ready",
81
+ "merged",
82
+ "closed"
83
+ ]);
84
+ /** Something the operator has to look at. Orthogonal to `IssueState`. */
85
+ const IssueAttention = effect.Schema.Literals([
86
+ "needs-you",
87
+ "stuck",
88
+ "api-error"
89
+ ]);
90
+ /** Latest review decision on the PR, as the forge reports it. */
91
+ const PrReviewState = effect.Schema.Literals([
92
+ "approved",
93
+ "changes-requested",
94
+ "review-requested",
95
+ "commented",
96
+ "none"
97
+ ]);
98
+ /** Aggregate check-run conclusion for the PR head. */
99
+ const PrChecksState = effect.Schema.Literals([
100
+ "green",
101
+ "red",
102
+ "pending"
103
+ ]);
104
+ /** The pull request (or merge request) backing an issue. */
105
+ const DerivedPrState = effect.Schema.Struct({
106
+ url: effect.Schema.String,
107
+ number: effect.Schema.Number,
108
+ reviewState: PrReviewState,
109
+ checks: PrChecksState,
110
+ /** Forge mergeability. `null` when the forge has not computed it yet. */
111
+ mergeable: effect.Schema.NullOr(effect.Schema.Boolean)
112
+ });
113
+ /** The issue's feature branch as git reports it. */
114
+ const DerivedBranchState = effect.Schema.Struct({
115
+ name: effect.Schema.String,
116
+ aheadOfMain: effect.Schema.Number,
117
+ pushed: effect.Schema.Boolean
118
+ });
119
+ /** Everything the dashboard needs to render an issue's pipeline position. */
120
+ const DerivedIssueState = effect.Schema.Struct({
121
+ issueId: effect.Schema.String,
122
+ state: IssueState,
123
+ attention: effect.Schema.optional(IssueAttention),
124
+ pr: effect.Schema.optional(DerivedPrState),
125
+ branch: effect.Schema.optional(DerivedBranchState),
126
+ /**
127
+ * No tracker answered for this issue, so `closed` — the top of the
128
+ * precedence — could not be ruled in or out. Present only in that case; an
129
+ * unresolved tracker read is never reported as an open issue.
130
+ */
131
+ trackerUnknown: effect.Schema.optional(effect.Schema.Literal(true))
132
+ });
133
+ const ISSUE_STATES = [
134
+ "backlog",
135
+ "parked",
136
+ "planned",
137
+ "working",
138
+ "in-review",
139
+ "changes-requested",
140
+ "ready",
141
+ "merged",
142
+ "closed"
143
+ ];
144
+ /** Highest precedence first — the order `deriveIssueState` resolves in. */
145
+ const ISSUE_STATE_PRECEDENCE = [
146
+ "closed",
147
+ "merged",
148
+ "ready",
149
+ "changes-requested",
150
+ "in-review",
151
+ "working",
152
+ "parked",
153
+ "planned",
154
+ "backlog"
155
+ ];
156
+ const ISSUE_ATTENTIONS = [
157
+ "needs-you",
158
+ "stuck",
159
+ "api-error"
160
+ ];
161
+ function isIssueState(value) {
162
+ return typeof value === "string" && ISSUE_STATES.includes(value);
163
+ }
164
+ function isIssueAttention(value) {
165
+ return typeof value === "string" && ISSUE_ATTENTIONS.includes(value);
166
+ }
167
+ //#endregion
29
168
  //#region src/types.ts
30
169
  const IssueId = effect.Schema.String;
31
170
  const MEMBERSHIP_UNAVAILABLE_REASONS = [
@@ -54,7 +193,8 @@ const Role = effect.Schema.Literals([
54
193
  "flywheel",
55
194
  "strike",
56
195
  "sequencer",
57
- "knowledge"
196
+ "knowledge",
197
+ "worker"
58
198
  ]);
59
199
  const AgentResolution = effect.Schema.Literals([
60
200
  "working",
@@ -66,52 +206,6 @@ const AgentResolution = effect.Schema.Literals([
66
206
  "abandoned",
67
207
  "api_error"
68
208
  ]);
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
209
  const KNOWN_HARNESSES = new Set([
116
210
  "claude-code",
117
211
  "ohmypi",
@@ -301,87 +395,6 @@ const AgentSnapshot = effect.Schema.Struct({
301
395
  runtimeSnapshotSequence: effect.Schema.optional(SequenceNumber)
302
396
  });
303
397
  /** 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
398
  const TurnDiffFileChange = effect.Schema.Struct({
386
399
  path: effect.Schema.String,
387
400
  kind: effect.Schema.optional(effect.Schema.String),
@@ -507,7 +520,10 @@ const DashboardSnapshot = effect.Schema.Struct({
507
520
  sequence: SequenceNumber,
508
521
  agents: effect.Schema.Array(AgentSnapshot),
509
522
  specialists: effect.Schema.Array(effect.Schema.Unknown),
510
- reviewStatuses: effect.Schema.Array(ReviewStatusSnapshot),
523
+ /** PAN-3917 FR-6: the derived pipeline state of every known issue. */
524
+ derivedIssueStates: effect.Schema.Array(DerivedIssueState),
525
+ /** PAN-3917 FR-12: every live agent pane the terminal backend reports. */
526
+ backendPanes: effect.Schema.Array(BackendPane),
511
527
  issues: effect.Schema.Array(effect.Schema.Unknown),
512
528
  recentActivity: effect.Schema.optional(effect.Schema.Array(effect.Schema.Unknown)),
513
529
  resources: effect.Schema.optional(effect.Schema.Unknown),
@@ -522,13 +538,6 @@ const DashboardSnapshot = effect.Schema.Struct({
522
538
  restartGate: effect.Schema.optional(RestartGateSnapshot),
523
539
  timestamp: effect.Schema.String
524
540
  });
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
541
  const ResourceStats = effect.Schema.Struct({ containers: effect.Schema.Array(effect.Schema.Struct({
533
542
  name: effect.Schema.String,
534
543
  cpu: effect.Schema.optional(effect.Schema.String),
@@ -613,14 +622,6 @@ const SessionNode = effect.Schema.Struct({
613
622
  "tmux",
614
623
  "supervisor"
615
624
  ])),
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
625
  modelOrigin: effect.Schema.optional(ModelOrigin)
625
626
  });
626
627
  const FeatureNode = effect.Schema.Struct({
@@ -1760,16 +1761,32 @@ const PlanItemsUnblockedEvent = effect.Schema.Struct({
1760
1761
  items: effect.Schema.Array(effect.Schema.String)
1761
1762
  })
1762
1763
  });
1763
- /** Replaces socket.io `pipeline:status` */
1764
- const PipelineStatusChangedEvent = effect.Schema.Struct({
1765
- type: effect.Schema.Literal("pipeline.status_changed"),
1764
+ /**
1765
+ * PAN-3917 FR-6 — an issue's derived pipeline state changed.
1766
+ *
1767
+ * Emitted with `emitOnly`: derived state is recomputed from the tracker, the
1768
+ * forge and the terminal backend on every boot, so persisting it would be
1769
+ * storing a status Overdeck can derive.
1770
+ */
1771
+ const IssueStateChangedEvent = effect.Schema.Struct({
1772
+ type: effect.Schema.Literal("issue_state.changed"),
1766
1773
  sequence: SequenceNumber,
1767
1774
  timestamp: effect.Schema.String,
1768
- payload: effect.Schema.Struct({
1769
- issueId: IssueId,
1770
- workspaceId: effect.Schema.optional(effect.Schema.String),
1771
- status: ReviewStatusSnapshot
1772
- })
1775
+ payload: effect.Schema.Struct({ issueState: DerivedIssueState })
1776
+ });
1777
+ /** PAN-3917 FR-12 — a live agent pane appeared or changed. `emitOnly`. */
1778
+ const BackendPaneChangedEvent = effect.Schema.Struct({
1779
+ type: effect.Schema.Literal("backend_pane.changed"),
1780
+ sequence: SequenceNumber,
1781
+ timestamp: effect.Schema.String,
1782
+ payload: effect.Schema.Struct({ pane: BackendPane })
1783
+ });
1784
+ /** PAN-3917 FR-12 — a pane left the backend inventory. `emitOnly`. */
1785
+ const BackendPaneRemovedEvent = effect.Schema.Struct({
1786
+ type: effect.Schema.Literal("backend_pane.removed"),
1787
+ sequence: SequenceNumber,
1788
+ timestamp: effect.Schema.String,
1789
+ payload: effect.Schema.Struct({ paneId: effect.Schema.String })
1773
1790
  });
1774
1791
  /** Replaces socket.io `merge:ready` */
1775
1792
  const MergeReadyEvent = effect.Schema.Struct({
@@ -1781,17 +1798,6 @@ const MergeReadyEvent = effect.Schema.Struct({
1781
1798
  workspaceId: effect.Schema.optional(effect.Schema.String)
1782
1799
  })
1783
1800
  });
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
1801
  /** New — review specialist dispatched */
1796
1802
  const PipelineReviewStartedEvent = effect.Schema.Struct({
1797
1803
  type: effect.Schema.Literal("pipeline.review-started"),
@@ -2630,9 +2636,10 @@ const DomainEvent = effect.Schema.Union([
2630
2636
  PlanItemStatusChangedEvent,
2631
2637
  PlanSubitemStatusChangedEvent,
2632
2638
  PlanItemsUnblockedEvent,
2633
- PipelineStatusChangedEvent,
2639
+ IssueStateChangedEvent,
2640
+ BackendPaneChangedEvent,
2641
+ BackendPaneRemovedEvent,
2634
2642
  MergeReadyEvent,
2635
- ReviewStatusChangedEvent,
2636
2643
  PipelineReviewStartedEvent,
2637
2644
  PipelineReviewCompletedEvent,
2638
2645
  PipelineTestStartedEvent,
@@ -2862,248 +2869,66 @@ const OpenInEditorInput = effect.Schema.Struct({
2862
2869
  editor: EditorIdSchema
2863
2870
  });
2864
2871
  //#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
2872
+ //#region src/rpc.ts
2873
+ const WS_METHODS = {
2874
+ scanConversations: "pan.scanConversations",
2875
+ searchConversations: "pan.searchConversations",
2876
+ listDiscoveredSessions: "pan.listDiscoveredSessions",
2877
+ listSessionsFeed: "pan.listSessionsFeed",
2878
+ getSessionsFeedFacets: "pan.getSessionsFeedFacets",
2879
+ getDiscoveredSession: "pan.getDiscoveredSession",
2880
+ enrichSessions: "pan.enrichSessions",
2881
+ embedSessions: "pan.embedSessions",
2882
+ getConversationCost: "pan.getConversationCost",
2883
+ getConversationCostByWorkspace: "pan.getConversationCostByWorkspace",
2884
+ getConversationStats: "pan.getConversationStats",
2885
+ subscribeDomainEvents: "pan.subscribeDomainEvents",
2886
+ subscribeIssueEvents: "pan.subscribeIssueEvents",
2887
+ subscribeTerminal: "pan.subscribeTerminal",
2888
+ subscribeAgentOutput: "pan.subscribeAgentOutput",
2889
+ subscribeConversationMessages: "pan.subscribeConversationMessages",
2890
+ subscribeProjectSessionTree: "pan.subscribeProjectSessionTree",
2891
+ getSnapshot: "pan.getSnapshot",
2892
+ replayEvents: "pan.replayEvents",
2893
+ readWorkspaceFile: "pan.readWorkspaceFile",
2894
+ readFileAtPath: "pan.readFileAtPath",
2895
+ writeFileAtPath: "pan.writeFileAtPath",
2896
+ resolveFilePathExists: "pan.resolveFilePathExists",
2897
+ terminalOpen: "pan.terminalOpen",
2898
+ terminalWrite: "pan.terminalWrite",
2899
+ terminalResize: "pan.terminalResize",
2900
+ terminalClose: "pan.terminalClose",
2901
+ startPlanning: "pan.startPlanning",
2902
+ startAgent: "pan.startAgent",
2903
+ deepWipe: "pan.deepWipe",
2904
+ sendTerminalInput: "pan.sendTerminalInput",
2905
+ resizeTerminal: "pan.resizeTerminal",
2906
+ shellOpenInEditor: "pan.shellOpenInEditor",
2907
+ getAvailableEditors: "pan.getAvailableEditors"
2908
+ };
2909
+ var PanRpcError = class extends effect.Schema.TaggedErrorClass()("PanRpcError", {
2910
+ message: effect.Schema.String,
2911
+ code: effect.Schema.optional(effect.Schema.String)
2912
+ }) {};
2913
+ const TerminalOutput = effect.Schema.Struct({
2914
+ sessionName: effect.Schema.String,
2915
+ data: effect.Schema.String
2890
2916
  });
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
2917
+ const AgentOutput = effect.Schema.Struct({
2918
+ agentId: effect.Schema.String,
2919
+ line: effect.Schema.String
2898
2920
  });
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)
2921
+ const ProposedPlan = effect.Schema.Struct({
2922
+ id: effect.Schema.String,
2923
+ plan: effect.Schema.String,
2924
+ planFilePath: effect.Schema.optional(effect.Schema.String),
2925
+ status: effect.Schema.Literals([
2926
+ "pending",
2927
+ "approved",
2928
+ "rejected"
2929
+ ]),
2930
+ createdAt: effect.Schema.String,
2931
+ resolvedAt: effect.Schema.optional(effect.Schema.String)
3107
2932
  });
3108
2933
  const CompactBoundary = effect.Schema.Struct({
3109
2934
  id: effect.Schema.String,
@@ -3305,12 +3130,6 @@ const TerminalCloseRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.terminalClose,
3305
3130
  payload: effect.Schema.Struct({ sessionName: effect.Schema.String }),
3306
3131
  error: PanRpcError
3307
3132
  });
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
3133
  const ReadWorkspaceFileInput = effect.Schema.Struct({
3315
3134
  issueId: IssueId,
3316
3135
  relativePath: effect.Schema.String,
@@ -3457,13 +3276,6 @@ const SubscribeProjectSessionTreeRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.s
3457
3276
  error: PanRpcError,
3458
3277
  stream: true
3459
3278
  });
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
3279
  /** 19. Open a workspace in an editor (PAN-966) */
3468
3280
  const ShellOpenInEditorRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.shellOpenInEditor, {
3469
3281
  payload: OpenInEditorInput,
@@ -3641,7 +3453,7 @@ const GetConversationStatsRpc = effect_unstable_rpc_Rpc.make(WS_METHODS.getConve
3641
3453
  error: PanRpcError
3642
3454
  });
3643
3455
  /** 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);
3456
+ 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
3457
  //#endregion
3646
3458
  //#region src/issue-delta.ts
3647
3459
  function createIssueDelta(previous, next) {
@@ -3666,7 +3478,8 @@ const INITIAL_READ_MODEL_STATE = {
3666
3478
  sequence: 0,
3667
3479
  agentsById: {},
3668
3480
  agentRuntimeById: {},
3669
- reviewStatusByIssueId: {},
3481
+ derivedIssueStateByIssueId: {},
3482
+ backendPanesById: {},
3670
3483
  resources: null,
3671
3484
  agentOutputById: {},
3672
3485
  issuesRaw: [],
@@ -3783,8 +3596,10 @@ function bumpRuntimeSnapshotSequence(agentsById, agentId, sequence) {
3783
3596
  function syncSnapshot(state, snapshot) {
3784
3597
  const agentsById = {};
3785
3598
  for (const agent of snapshot.agents) agentsById[agent.id] = agent;
3786
- const reviewStatusByIssueId = {};
3787
- for (const rs of snapshot.reviewStatuses) reviewStatusByIssueId[rs.issueId] = rs;
3599
+ const derivedIssueStateByIssueId = {};
3600
+ for (const derived of snapshot.derivedIssueStates ?? []) derivedIssueStateByIssueId[derived.issueId] = derived;
3601
+ const backendPanesById = {};
3602
+ for (const pane of snapshot.backendPanes ?? []) backendPanesById[pane.id] = pane;
3788
3603
  const channelPermissionRequestsById = {};
3789
3604
  const channelPermissionRequestIdsByAgentId = {};
3790
3605
  for (const request of snapshot.channelPermissionRequests ?? []) {
@@ -3800,7 +3615,8 @@ function syncSnapshot(state, snapshot) {
3800
3615
  ...state,
3801
3616
  sequence: snapshot.sequence,
3802
3617
  agentsById,
3803
- reviewStatusByIssueId,
3618
+ derivedIssueStateByIssueId,
3619
+ backendPanesById,
3804
3620
  agentRuntimeById: snapshot.agentRuntimeById ?? state.agentRuntimeById,
3805
3621
  channelPermissionRequestsById,
3806
3622
  channelPermissionRequestIdsByAgentId,
@@ -3890,7 +3706,16 @@ function applyEvent(state, event) {
3890
3706
  };
3891
3707
  }
3892
3708
  case "agent.stopped": {
3893
- const { [event.payload.agentId]: _removed, ...rest } = state.agentsById;
3709
+ const stoppedAgent = state.agentsById[event.payload.agentId];
3710
+ const nextAgentsById = stoppedAgent ? {
3711
+ ...state.agentsById,
3712
+ [event.payload.agentId]: {
3713
+ ...stoppedAgent,
3714
+ status: "stopped",
3715
+ hasLiveTmuxSession: false,
3716
+ lastActivity: event.timestamp
3717
+ }
3718
+ } : state.agentsById;
3894
3719
  const runtimeById = state.agentRuntimeById ?? {};
3895
3720
  const prevRuntime = runtimeById[event.payload.agentId];
3896
3721
  const nextRuntimeById = prevRuntime ? {
@@ -3919,7 +3744,7 @@ function applyEvent(state, event) {
3919
3744
  return {
3920
3745
  ...state,
3921
3746
  sequence: Math.max(state.sequence, event.sequence),
3922
- agentsById: rest,
3747
+ agentsById: nextAgentsById,
3923
3748
  agentRuntimeById: nextRuntimeById,
3924
3749
  channelPermissionRequestsById: nextPermissionRequestsById,
3925
3750
  channelPermissionRequestIdsByAgentId: restPendingIds,
@@ -4064,85 +3889,35 @@ function applyEvent(state, event) {
4064
3889
  }
4065
3890
  };
4066
3891
  }
4067
- case "pipeline.status_changed":
4068
- case "review.status_changed": return {
3892
+ case "issue_state.changed": return {
4069
3893
  ...state,
4070
3894
  sequence: Math.max(state.sequence, event.sequence),
4071
- reviewStatusByIssueId: {
4072
- ...state.reviewStatusByIssueId,
4073
- [event.payload.issueId]: event.payload.status
3895
+ derivedIssueStateByIssueId: {
3896
+ ...state.derivedIssueStateByIssueId,
3897
+ [event.payload.issueState.issueId]: event.payload.issueState
4074
3898
  }
4075
3899
  };
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 {
3900
+ case "backend_pane.changed": return {
4124
3901
  ...state,
4125
- sequence: Math.max(state.sequence, event.sequence)
3902
+ sequence: Math.max(state.sequence, event.sequence),
3903
+ backendPanesById: {
3904
+ ...state.backendPanesById,
3905
+ [event.payload.pane.id]: event.payload.pane
3906
+ }
4126
3907
  };
4127
- case "review.coordinator_started": {
4128
- const { issueId, sessionName } = event.payload;
4129
- const nextStatus = {
4130
- ...state.reviewStatusByIssueId[issueId] ?? { issueId },
4131
- reviewCoordinatorSessionName: sessionName
4132
- };
3908
+ case "backend_pane.removed": {
3909
+ const { [event.payload.paneId]: _removed, ...rest } = state.backendPanesById;
4133
3910
  return {
4134
3911
  ...state,
4135
3912
  sequence: Math.max(state.sequence, event.sequence),
4136
- reviewStatusByIssueId: {
4137
- ...state.reviewStatusByIssueId,
4138
- [issueId]: nextStatus
4139
- }
3913
+ backendPanesById: rest
4140
3914
  };
4141
3915
  }
4142
- case "review.coordinator.died": return {
4143
- ...state,
4144
- sequence: Math.max(state.sequence, event.sequence)
4145
- };
3916
+ case "review.reviewer_started":
3917
+ case "review.reviewer_completed":
3918
+ case "review.specialist.timed_out":
3919
+ case "review.coordinator_started":
3920
+ case "review.coordinator.died":
4146
3921
  case "pipeline.review-started":
4147
3922
  case "pipeline.review-completed":
4148
3923
  case "pipeline.test-started":
@@ -5127,64 +4902,352 @@ function deriveProjectCi(record) {
5127
4902
  };
5128
4903
  }
5129
4904
  //#endregion
5130
- //#region src/flywheel-stats.ts
5131
- const FlywheelStatsCriterionStatus = effect.Schema.Literals([
5132
- "green",
5133
- "yellow",
5134
- "red",
5135
- "insufficient_data"
4905
+ //#region src/flywheel.ts
4906
+ const FlywheelRunId = effect.Schema.String.check(effect.Schema.isPattern(/^RUN-\d+$/));
4907
+ const FlywheelHttpUrl = effect.Schema.String.check(effect.Schema.isPattern(/^https?:\/\/\S+$/i));
4908
+ const FlywheelHarness = effect.Schema.Literals([
4909
+ "claude-code",
4910
+ "pi",
4911
+ "ohmypi",
4912
+ "codex",
4913
+ "acp",
4914
+ "kimi-code",
4915
+ "opencode",
4916
+ "muse"
5136
4917
  ]);
5137
- const FlywheelStatsTrend = effect.Schema.Literals([
5138
- "up",
5139
- "down",
5140
- "flat"
4918
+ const FlywheelEffort = effect.Schema.Literals([
4919
+ "low",
4920
+ "medium",
4921
+ "high",
4922
+ "xhigh",
4923
+ "max"
5141
4924
  ]);
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
4925
+ const FlywheelOrchestrator = effect.Schema.Struct({
4926
+ harness: FlywheelHarness,
4927
+ model: effect.Schema.String,
4928
+ effort: FlywheelEffort,
4929
+ ctxPercent: effect.Schema.Number
5161
4930
  });
5162
- const FlywheelStats = effect.Schema.Struct({
5163
- window: effect.Schema.String,
5164
- generatedAt: effect.Schema.String,
5165
- criteria: FlywheelStatsCriteria
4931
+ const FlywheelScope = effect.Schema.Literals(["pan-only", "all-tracked-projects"]);
4932
+ const FlywheelHeadline = effect.Schema.Struct({
4933
+ bugsFixed: effect.Schema.Number,
4934
+ swarmItemsMerged: effect.Schema.Number,
4935
+ swarmItemsTotal: effect.Schema.Number,
4936
+ prsMerged: effect.Schema.Number,
4937
+ awaitingUat: effect.Schema.Number
5166
4938
  });
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([
5173
- "draft",
5174
- "ready",
5175
- "running",
5176
- "drained",
5177
- "complete"
5178
- ]);
5179
- const OrderBookPosture = effect.Schema.Literals(["open", "drain"]);
5180
- const OrderBookItem = effect.Schema.Struct({
5181
- issue: effect.Schema.String,
5182
- lane: OrderBookLane,
5183
- order: effect.Schema.Number,
5184
- prereqs: effect.Schema.Array(effect.Schema.String),
5185
- reVerify: effect.Schema.Boolean,
5186
- planAtPickup: effect.Schema.optional(effect.Schema.Boolean),
5187
- addedAt: effect.Schema.String,
4939
+ /**
4940
+ * Pipeline verbs — display state only. They no longer gate the merge queue.
4941
+ *
4942
+ * History worth keeping (PAN-1736 / PAN-1759): the merge queue used to be
4943
+ * derived by filtering these verbs, treating only "shipping" or "merging" as
4944
+ * "at the merge gate". Any other verb on an issue that was ready_for_merge in
4945
+ * the review DB silently dropped it from the queue and from UAT batch
4946
+ * assembly — RUN-18 shipped an empty queue with five ready issues exactly that
4947
+ * way — and the queue existed only while a run was emitting a pipeline at all.
4948
+ *
4949
+ * PAN-1696 removed that coupling. The ready set is now sourced from the
4950
+ * review-status records per project (`listEligibleCandidatesByProject` +
4951
+ * `computeMergeQueueFromCandidates` in src/lib/flywheel-merge-order.ts), which
4952
+ * needs no flywheel run and cannot be affected by which verb an orchestrator
4953
+ * chose to report. Adding a verb here therefore has no merge-queue consequence;
4954
+ * it only changes what the dashboard displays.
4955
+ */
4956
+ const FlywheelPipelineVerb = effect.Schema.Literals([
4957
+ "planning",
4958
+ "working",
4959
+ "reviewing",
4960
+ "testing",
4961
+ "shipping",
4962
+ "merging",
4963
+ "blocked",
4964
+ "parked"
4965
+ ]);
4966
+ const FlywheelPipelineStatus = effect.Schema.Literals([
4967
+ "queued",
4968
+ "running",
4969
+ "blocked",
4970
+ "passed",
4971
+ "failed",
4972
+ "merged",
4973
+ "parked"
4974
+ ]);
4975
+ const FlywheelPipelineItem = effect.Schema.Struct({
4976
+ issueId: effect.Schema.String,
4977
+ title: effect.Schema.String,
4978
+ verb: FlywheelPipelineVerb,
4979
+ status: FlywheelPipelineStatus,
4980
+ progressPercent: effect.Schema.optional(effect.Schema.Number),
4981
+ agentId: effect.Schema.optional(effect.Schema.String),
4982
+ pr: effect.Schema.optional(effect.Schema.Number),
4983
+ mergeOrder: effect.Schema.optional(effect.Schema.Number),
4984
+ conflictsWith: effect.Schema.optional(effect.Schema.Array(effect.Schema.String))
4985
+ });
4986
+ const FlywheelSubstrateBugStatus = effect.Schema.Literals([
4987
+ "filed",
4988
+ "fixed",
4989
+ "workaround"
4990
+ ]);
4991
+ const FlywheelSubstrateBug = effect.Schema.Struct({
4992
+ issueId: effect.Schema.String,
4993
+ title: effect.Schema.String,
4994
+ status: FlywheelSubstrateBugStatus,
4995
+ commitSha: effect.Schema.optional(effect.Schema.String),
4996
+ url: effect.Schema.optional(FlywheelHttpUrl)
4997
+ });
4998
+ const FlywheelAgentStatus = effect.Schema.Literals([
4999
+ "starting",
5000
+ "running",
5001
+ "waiting",
5002
+ "idle",
5003
+ "stopped",
5004
+ "error"
5005
+ ]);
5006
+ const FlywheelAgent = effect.Schema.Struct({
5007
+ id: effect.Schema.String,
5008
+ label: effect.Schema.String,
5009
+ status: FlywheelAgentStatus,
5010
+ issueId: effect.Schema.optional(effect.Schema.String),
5011
+ role: effect.Schema.optional(effect.Schema.String),
5012
+ model: effect.Schema.optional(effect.Schema.String),
5013
+ ctxPercent: effect.Schema.optional(effect.Schema.Number),
5014
+ currentAction: effect.Schema.optional(effect.Schema.String)
5015
+ });
5016
+ const FlywheelParkedItem = effect.Schema.Struct({
5017
+ issueId: effect.Schema.String,
5018
+ title: effect.Schema.String,
5019
+ reason: effect.Schema.String,
5020
+ parkedAt: effect.Schema.optional(effect.Schema.String)
5021
+ });
5022
+ const FlywheelSuggestionAction = effect.Schema.Literals([
5023
+ "start",
5024
+ "resume",
5025
+ "plan",
5026
+ "review",
5027
+ "merge",
5028
+ "unblock",
5029
+ "park",
5030
+ "investigate",
5031
+ "wait"
5032
+ ]);
5033
+ const FlywheelSuggestionPriority = effect.Schema.Literals([
5034
+ "urgent",
5035
+ "high",
5036
+ "medium",
5037
+ "low"
5038
+ ]);
5039
+ const FlywheelSuggestion = effect.Schema.Struct({
5040
+ action: FlywheelSuggestionAction,
5041
+ issueId: effect.Schema.optional(effect.Schema.String),
5042
+ rationale: effect.Schema.String,
5043
+ priority: FlywheelSuggestionPriority,
5044
+ filedBy: effect.Schema.optional(effect.Schema.Literals(["agent", "operator"])),
5045
+ weight: effect.Schema.optional(effect.Schema.Number),
5046
+ weightReason: effect.Schema.optional(effect.Schema.String)
5047
+ });
5048
+ const FlywheelSystemStatus = effect.Schema.Struct({
5049
+ mainHead: effect.Schema.String,
5050
+ ramUsedMb: effect.Schema.Number,
5051
+ ramTotalMb: effect.Schema.Number,
5052
+ swapUsedMb: effect.Schema.Number,
5053
+ swapTotalMb: effect.Schema.Number,
5054
+ agentsActive: effect.Schema.Number,
5055
+ agentsCap: effect.Schema.Number
5056
+ });
5057
+ const FlywheelOrders = effect.Schema.Struct({
5058
+ bookId: effect.Schema.String,
5059
+ bookName: effect.Schema.String,
5060
+ landed: effect.Schema.Number,
5061
+ total: effect.Schema.Number,
5062
+ laneAInFlight: effect.Schema.Array(effect.Schema.String),
5063
+ laneBInFlight: effect.Schema.optional(effect.Schema.String),
5064
+ drained: effect.Schema.Boolean
5065
+ });
5066
+ const FlywheelStatus = effect.Schema.Struct({
5067
+ runId: FlywheelRunId,
5068
+ startedAt: effect.Schema.String,
5069
+ elapsedMs: effect.Schema.Number,
5070
+ orchestrator: FlywheelOrchestrator,
5071
+ headline: FlywheelHeadline,
5072
+ activePipeline: effect.Schema.Array(FlywheelPipelineItem),
5073
+ substrateBugs: effect.Schema.Array(FlywheelSubstrateBug),
5074
+ agents: effect.Schema.Array(FlywheelAgent),
5075
+ parked: effect.Schema.Array(FlywheelParkedItem),
5076
+ suggestions: effect.Schema.Array(FlywheelSuggestion).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed([]))),
5077
+ system: FlywheelSystemStatus,
5078
+ openQuestions: effect.Schema.Array(effect.Schema.String),
5079
+ orders: effect.Schema.optional(FlywheelOrders),
5080
+ scope: effect.Schema.optional(FlywheelScope),
5081
+ ticks: effect.Schema.Number,
5082
+ lastTickAt: effect.Schema.String
5083
+ });
5084
+ //#endregion
5085
+ //#region src/flywheel-stats.ts
5086
+ const FlywheelStatsCriterionStatus = effect.Schema.Literals([
5087
+ "green",
5088
+ "yellow",
5089
+ "red",
5090
+ "insufficient_data"
5091
+ ]);
5092
+ const FlywheelStatsTrend = effect.Schema.Literals([
5093
+ "up",
5094
+ "down",
5095
+ "flat"
5096
+ ]);
5097
+ const FlywheelSubstrateSeverity = effect.Schema.Literals([
5098
+ "P0",
5099
+ "P1",
5100
+ "P2",
5101
+ "unknown"
5102
+ ]);
5103
+ const FlywheelStatsWindow = effect.Schema.Struct({
5104
+ days: effect.Schema.Number,
5105
+ since: effect.Schema.String,
5106
+ until: effect.Schema.String
5107
+ });
5108
+ /** c1: substrate bugs filed per merged PR in the window. */
5109
+ const FlywheelBugRateCriterion = effect.Schema.Struct({
5110
+ /** `null` when no PR merged in the window (the rate is undefined). */
5111
+ value: effect.Schema.NullOr(effect.Schema.Number),
5112
+ count: effect.Schema.Number,
5113
+ denominator: effect.Schema.Number,
5114
+ status: FlywheelStatsCriterionStatus,
5115
+ trend: FlywheelStatsTrend,
5116
+ dataSufficient: effect.Schema.Boolean
5117
+ });
5118
+ /** c2: P0 substrate bugs filed in the window. */
5119
+ const FlywheelP0Criterion = effect.Schema.Struct({
5120
+ value: effect.Schema.Number,
5121
+ status: FlywheelStatsCriterionStatus,
5122
+ trend: FlywheelStatsTrend,
5123
+ dataSufficient: effect.Schema.Boolean
5124
+ });
5125
+ const FlywheelSubstrateBugRow = effect.Schema.Struct({
5126
+ number: effect.Schema.Number,
5127
+ title: effect.Schema.String,
5128
+ createdAt: effect.Schema.String,
5129
+ closedAt: effect.Schema.NullOr(effect.Schema.String),
5130
+ severity: FlywheelSubstrateSeverity
5131
+ });
5132
+ const FlywheelStats = effect.Schema.Struct({
5133
+ window: FlywheelStatsWindow,
5134
+ generatedAt: effect.Schema.String,
5135
+ criteria: effect.Schema.Struct({
5136
+ c1_bugRate: FlywheelBugRateCriterion,
5137
+ c2_p0Bugs: FlywheelP0Criterion
5138
+ }),
5139
+ bugs: effect.Schema.Array(FlywheelSubstrateBugRow)
5140
+ });
5141
+ const decodeFlywheelStats = effect.Schema.decodeUnknownSync(FlywheelStats);
5142
+ const encodeFlywheelStats = effect.Schema.encodeSync(FlywheelStats);
5143
+ //#endregion
5144
+ //#region src/flywheel-derived.ts
5145
+ /** The loop's phases, as the skill reports them in its tick marker. */
5146
+ const TickMarkerPhase = effect.Schema.Literals([
5147
+ "orient",
5148
+ "pick",
5149
+ "launch",
5150
+ "watch",
5151
+ "park",
5152
+ "idle",
5153
+ "stopping"
5154
+ ]);
5155
+ /**
5156
+ * One parsed tick marker line:
5157
+ * `flywheel-tick: tick=<n> pick=<ID|none> phase=<phase> in-flight=<ID,…|none> needs-you=<text|none>`.
5158
+ */
5159
+ const TickMarker = effect.Schema.Struct({
5160
+ tick: effect.Schema.Number,
5161
+ pick: effect.Schema.NullOr(effect.Schema.String),
5162
+ phase: TickMarkerPhase,
5163
+ inFlight: effect.Schema.Array(effect.Schema.String),
5164
+ needsYou: effect.Schema.NullOr(effect.Schema.String)
5165
+ });
5166
+ /** `running` = row + live session; `paused` = row, no live session; `idle` = no row. */
5167
+ const FlywheelRunState = effect.Schema.Literals([
5168
+ "running",
5169
+ "paused",
5170
+ "idle"
5171
+ ]);
5172
+ /** Age of the last tick: ≤ 60 s live, ≤ 20 min breathing, older stalled. */
5173
+ const FlywheelFreshness = effect.Schema.Literals([
5174
+ "live",
5175
+ "breathing",
5176
+ "stalled"
5177
+ ]);
5178
+ const FlywheelConversationSummary = effect.Schema.Struct({
5179
+ name: effect.Schema.String,
5180
+ id: effect.Schema.Number,
5181
+ title: effect.Schema.NullOr(effect.Schema.String),
5182
+ model: effect.Schema.NullOr(effect.Schema.String),
5183
+ harness: effect.Schema.NullOr(effect.Schema.String),
5184
+ cwd: effect.Schema.String,
5185
+ sessionAlive: effect.Schema.Boolean
5186
+ });
5187
+ const FlywheelLastTick = effect.Schema.Struct({
5188
+ tick: effect.Schema.Number,
5189
+ pick: effect.Schema.NullOr(effect.Schema.String),
5190
+ phase: TickMarkerPhase,
5191
+ inFlight: effect.Schema.Array(effect.Schema.String),
5192
+ needsYou: effect.Schema.NullOr(effect.Schema.String),
5193
+ /** The assistant message's `createdAt`. */
5194
+ at: effect.Schema.String
5195
+ });
5196
+ const FlywheelPolicies = effect.Schema.Struct({
5197
+ auto_pickup_backlog: effect.Schema.Boolean,
5198
+ require_uat_before_merge: effect.Schema.Boolean,
5199
+ merge_train_enabled: effect.Schema.Boolean
5200
+ });
5201
+ const FlywheelJournalSummary = effect.Schema.Struct({
5202
+ at: effect.Schema.String,
5203
+ type: effect.Schema.String,
5204
+ source: effect.Schema.optional(effect.Schema.String)
5205
+ });
5206
+ const FlywheelInFlightRow = effect.Schema.Struct({
5207
+ issueId: effect.Schema.String,
5208
+ state: IssueState,
5209
+ attention: effect.Schema.optional(IssueAttention),
5210
+ pr: effect.Schema.optional(DerivedPrState),
5211
+ lastJournal: effect.Schema.NullOr(FlywheelJournalSummary)
5212
+ });
5213
+ const FlywheelOrderBookSummary = effect.Schema.Struct({
5214
+ id: effect.Schema.String,
5215
+ name: effect.Schema.String,
5216
+ status: effect.Schema.String,
5217
+ landed: effect.Schema.Number,
5218
+ total: effect.Schema.Number
5219
+ });
5220
+ const FlywheelDerivedStatus = effect.Schema.Struct({
5221
+ run: FlywheelRunState,
5222
+ conversation: effect.Schema.NullOr(FlywheelConversationSummary),
5223
+ lastTick: effect.Schema.NullOr(FlywheelLastTick),
5224
+ freshness: effect.Schema.NullOr(FlywheelFreshness),
5225
+ policies: FlywheelPolicies,
5226
+ inFlight: effect.Schema.Array(FlywheelInFlightRow),
5227
+ orderBook: effect.Schema.NullOr(FlywheelOrderBookSummary),
5228
+ projectRoot: effect.Schema.String,
5229
+ generatedAt: effect.Schema.String
5230
+ });
5231
+ const decodeFlywheelDerivedStatus = effect.Schema.decodeUnknownSync(FlywheelDerivedStatus);
5232
+ //#endregion
5233
+ //#region src/orders.ts
5234
+ const OrderBookLane = effect.Schema.Literals(["A", "B"]);
5235
+ const OrderBookStatus = effect.Schema.Literals([
5236
+ "draft",
5237
+ "ready",
5238
+ "running",
5239
+ "drained",
5240
+ "complete"
5241
+ ]);
5242
+ const OrderBookPosture = effect.Schema.Literals(["open", "drain"]);
5243
+ const OrderBookItem = effect.Schema.Struct({
5244
+ issue: effect.Schema.String,
5245
+ lane: OrderBookLane,
5246
+ order: effect.Schema.Number,
5247
+ prereqs: effect.Schema.Array(effect.Schema.String),
5248
+ reVerify: effect.Schema.Boolean,
5249
+ planAtPickup: effect.Schema.optional(effect.Schema.Boolean),
5250
+ addedAt: effect.Schema.String,
5188
5251
  addedBy: effect.Schema.String
5189
5252
  });
5190
5253
  const OrderBookSettings = effect.Schema.Struct({
@@ -5518,6 +5581,18 @@ const FeatureRegistryEntry = effect.Schema.Struct({
5518
5581
  });
5519
5582
  //#endregion
5520
5583
  //#region src/harness-behavior.ts
5584
+ const AGENT_SESSION_PREFIXES = [
5585
+ "agent-",
5586
+ "planning-",
5587
+ "specialist-",
5588
+ "strike-",
5589
+ "inspect-"
5590
+ ];
5591
+ const AGENT_SESSION_SINGLETONS = new Set(["flywheel-orchestrator", "conv-flywheel-orchestrator"]);
5592
+ /** Canonical synthetic agent-session identity shared by dashboard client/server. */
5593
+ function isAgentSessionName(name) {
5594
+ return AGENT_SESSION_SINGLETONS.has(name) || AGENT_SESSION_PREFIXES.some((prefix) => name.startsWith(prefix));
5595
+ }
5521
5596
  const CLAUDE_CODE_BEHAVIOR = {
5522
5597
  displayName: "Claude Code",
5523
5598
  nativeCommands: [
@@ -6276,12 +6351,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6276
6351
  "required": false,
6277
6352
  "valueHint": null
6278
6353
  },
6279
- {
6280
- "flags": "--shadow-only",
6281
- "description": "Show only shadowed issues",
6282
- "required": false,
6283
- "valueHint": null
6284
- },
6285
6354
  {
6286
6355
  "flags": "--triage",
6287
6356
  "description": "Show triage queue",
@@ -6296,19 +6365,13 @@ const COMPOSER_COMMAND_MANIFEST = [
6296
6365
  "id": "pan-show",
6297
6366
  "path": ["show"],
6298
6367
  "display": "/pan show",
6299
- "description": "Unified lens: shadow state, CV, context, health for one issue",
6368
+ "description": "Unified lens: derived issue state, CV, context, health for one issue",
6300
6369
  "args": [{
6301
6370
  "name": "id",
6302
6371
  "required": true,
6303
6372
  "variadic": false
6304
6373
  }],
6305
6374
  "options": [
6306
- {
6307
- "flags": "--shadow",
6308
- "description": "Shadow state details only",
6309
- "required": false,
6310
- "valueHint": null
6311
- },
6312
6375
  {
6313
6376
  "flags": "--cv",
6314
6377
  "description": "Agent work history only",
@@ -6360,32 +6423,12 @@ const COMPOSER_COMMAND_MANIFEST = [
6360
6423
  "id": "pan-review",
6361
6424
  "path": ["review"],
6362
6425
  "display": "/pan review",
6363
- "description": "Review-loop management: pending items, request re-review, reset cycles",
6426
+ "description": "Review-loop management: request re-review, abort reviewers, restart a round",
6364
6427
  "args": [],
6365
6428
  "options": [],
6366
6429
  "aliases": [],
6367
6430
  "category": "Review"
6368
6431
  },
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
6432
  {
6390
6433
  "id": "pan-review-request",
6391
6434
  "path": ["review", "request"],
@@ -6405,39 +6448,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6405
6448
  "aliases": [],
6406
6449
  "category": "Review"
6407
6450
  },
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
6451
  {
6442
6452
  "id": "pan-review-abort",
6443
6453
  "path": ["review", "abort"],
@@ -6452,24 +6462,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6452
6462
  "aliases": [],
6453
6463
  "category": "Review"
6454
6464
  },
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
6465
  {
6474
6466
  "id": "pan-review-restart",
6475
6467
  "path": ["review", "restart"],
@@ -6494,56 +6486,17 @@ const COMPOSER_COMMAND_MANIFEST = [
6494
6486
  "aliases": [],
6495
6487
  "category": "Review"
6496
6488
  },
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
6489
  {
6527
6490
  "id": "pan-staffing",
6528
6491
  "path": ["staffing"],
6529
6492
  "display": "/pan staffing",
6530
- "description": "Show or set per-issue work-model and swarm overrides",
6493
+ "description": "Show the work model and swarm policy in effect for an issue",
6531
6494
  "args": [{
6532
6495
  "name": "id",
6533
6496
  "required": true,
6534
6497
  "variadic": false
6535
6498
  }],
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
- }],
6499
+ "options": [],
6547
6500
  "aliases": [],
6548
6501
  "category": "Lifecycle"
6549
6502
  },
@@ -6561,7 +6514,7 @@ const COMPOSER_COMMAND_MANIFEST = [
6561
6514
  "id": "pan-backlog-write-sequence",
6562
6515
  "path": ["backlog", "write-sequence"],
6563
6516
  "display": "/pan backlog write-sequence",
6564
- "description": "Validate a SequenceDoc JSON file and write it to .pan/backlog/sequence.md (triggers auto-commit)",
6517
+ "description": "Validate a SequenceDoc JSON file, write it to .pan/backlog/sequence.md, and commit it",
6565
6518
  "args": [{
6566
6519
  "name": "file",
6567
6520
  "required": true,
@@ -6576,21 +6529,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6576
6529
  "aliases": [],
6577
6530
  "category": "Lifecycle"
6578
6531
  },
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
6532
  {
6595
6533
  "id": "pan-plan",
6596
6534
  "path": ["plan"],
@@ -6802,25 +6740,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6802
6740
  "aliases": ["stop"],
6803
6741
  "category": "Lifecycle"
6804
6742
  },
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
6743
  {
6825
6744
  "id": "pan-reset-session",
6826
6745
  "path": ["reset-session"],
@@ -6868,34 +6787,6 @@ const COMPOSER_COMMAND_MANIFEST = [
6868
6787
  "aliases": [],
6869
6788
  "category": "Lifecycle"
6870
6789
  },
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
6790
  {
6900
6791
  "id": "pan-fork",
6901
6792
  "path": ["fork"],
@@ -7139,13 +7030,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7139
7030
  },
7140
7031
  {
7141
7032
  "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",
7033
+ "description": "Strike shape: verify the strike branch is contained in origin/main; no PR is opened",
7149
7034
  "required": false,
7150
7035
  "valueHint": null
7151
7036
  }
@@ -7153,20 +7038,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7153
7038
  "aliases": [],
7154
7039
  "category": "Lifecycle"
7155
7040
  },
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
7041
  {
7171
7042
  "id": "pan-reopen",
7172
7043
  "path": ["reopen"],
@@ -7348,25 +7219,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7348
7219
  "options": [
7349
7220
  {
7350
7221
  "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",
7222
+ "description": "Work model for this session (defaults to Cloister config)",
7370
7223
  "required": true,
7371
7224
  "valueHint": "model"
7372
7225
  },
@@ -7394,18 +7247,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7394
7247
  "required": false,
7395
7248
  "valueHint": null
7396
7249
  },
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
7250
  {
7410
7251
  "flags": "--remote",
7411
7252
  "description": "Use remote workspace (Fly.io)",
@@ -7461,8 +7302,8 @@ const COMPOSER_COMMAND_MANIFEST = [
7461
7302
  "valueHint": null
7462
7303
  },
7463
7304
  {
7464
- "flags": "--off-book",
7465
- "description": "Allow one work-agent dispatch outside the active order book and log the override",
7305
+ "flags": "--skip-freshness",
7306
+ "description": "Bypass the plan-freshness preflight and spawn even if the plan names files that no longer exist",
7466
7307
  "required": false,
7467
7308
  "valueHint": null
7468
7309
  }
@@ -7474,7 +7315,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7474
7315
  "id": "pan-strike",
7475
7316
  "path": ["strike"],
7476
7317
  "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.",
7318
+ "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
7319
  "args": [{
7479
7320
  "name": "ids",
7480
7321
  "required": true,
@@ -7509,20 +7350,6 @@ const COMPOSER_COMMAND_MANIFEST = [
7509
7350
  "aliases": [],
7510
7351
  "category": "Lifecycle"
7511
7352
  },
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
7353
  {
7527
7354
  "id": "pan-knowledge",
7528
7355
  "path": ["knowledge"],
@@ -7789,7 +7616,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7789
7616
  "id": "pan-task",
7790
7617
  "path": ["task"],
7791
7618
  "display": "/pan task",
7792
- "description": "Read and update xBRIEF task state for one issue",
7619
+ "description": "Read and update xBRIEF item state for one issue",
7793
7620
  "args": [],
7794
7621
  "options": [],
7795
7622
  "aliases": [],
@@ -7851,32 +7678,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7851
7678
  "required": true,
7852
7679
  "variadic": false
7853
7680
  }],
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
- ],
7681
+ "options": [{
7682
+ "flags": "--json",
7683
+ "description": "Print JSON",
7684
+ "required": false,
7685
+ "valueHint": null
7686
+ }],
7880
7687
  "aliases": [],
7881
7688
  "category": "Lifecycle"
7882
7689
  },
@@ -7884,7 +7691,7 @@ const COMPOSER_COMMAND_MANIFEST = [
7884
7691
  "id": "pan-task-done",
7885
7692
  "path": ["task", "done"],
7886
7693
  "display": "/pan task done",
7887
- "description": "",
7694
+ "description": "Record an item as done. Requires a commit carrying \"Item: <item>\" on a pushed branch.",
7888
7695
  "args": [{
7889
7696
  "name": "issue",
7890
7697
  "required": true,
@@ -7894,32 +7701,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7894
7701
  "required": true,
7895
7702
  "variadic": false
7896
7703
  }],
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
- ],
7704
+ "options": [{
7705
+ "flags": "--json",
7706
+ "description": "Print JSON",
7707
+ "required": false,
7708
+ "valueHint": null
7709
+ }],
7923
7710
  "aliases": [],
7924
7711
  "category": "Lifecycle"
7925
7712
  },
@@ -7937,32 +7724,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7937
7724
  "required": true,
7938
7725
  "variadic": false
7939
7726
  }],
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
- ],
7727
+ "options": [{
7728
+ "flags": "--json",
7729
+ "description": "Print JSON",
7730
+ "required": false,
7731
+ "valueHint": null
7732
+ }],
7966
7733
  "aliases": [],
7967
7734
  "category": "Lifecycle"
7968
7735
  },
@@ -7980,32 +7747,12 @@ const COMPOSER_COMMAND_MANIFEST = [
7980
7747
  "required": true,
7981
7748
  "variadic": false
7982
7749
  }],
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
- ],
7750
+ "options": [{
7751
+ "flags": "--json",
7752
+ "description": "Print JSON",
7753
+ "required": false,
7754
+ "valueHint": null
7755
+ }],
8009
7756
  "aliases": [],
8010
7757
  "category": "Lifecycle"
8011
7758
  },
@@ -8023,32 +7770,12 @@ const COMPOSER_COMMAND_MANIFEST = [
8023
7770
  "required": true,
8024
7771
  "variadic": false
8025
7772
  }],
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
- ],
7773
+ "options": [{
7774
+ "flags": "--json",
7775
+ "description": "Print JSON",
7776
+ "required": false,
7777
+ "valueHint": null
7778
+ }],
8052
7779
  "aliases": [],
8053
7780
  "category": "Lifecycle"
8054
7781
  },
@@ -8066,32 +7793,12 @@ const COMPOSER_COMMAND_MANIFEST = [
8066
7793
  "required": true,
8067
7794
  "variadic": false
8068
7795
  }],
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
- ],
7796
+ "options": [{
7797
+ "flags": "--json",
7798
+ "description": "Print JSON",
7799
+ "required": false,
7800
+ "valueHint": null
7801
+ }],
8095
7802
  "aliases": [],
8096
7803
  "category": "Lifecycle"
8097
7804
  },
@@ -9038,7 +8745,7 @@ const COMPOSER_COMMAND_MANIFEST = [
9038
8745
  "id": "pan-rollout-status",
9039
8746
  "path": ["rollout", "status"],
9040
8747
  "display": "/pan rollout status",
9041
- "description": "Print the release set for an issue (releaseStatus + per-component status)",
8748
+ "description": "Print the release set for an issue (overall + per-component status)",
9042
8749
  "args": [{
9043
8750
  "name": "issueId",
9044
8751
  "required": true,
@@ -9912,7 +9619,7 @@ const COMPOSER_COMMAND_MANIFEST = [
9912
9619
  "id": "pan-parked",
9913
9620
  "path": ["parked"],
9914
9621
  "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",
9622
+ "description": "List every issue parked in a stall orbit (operator gates, zombie sessions, idle-running agents), oldest first, with why + release condition",
9916
9623
  "args": [],
9917
9624
  "options": [{
9918
9625
  "flags": "--json",
@@ -9923,35 +9630,6 @@ const COMPOSER_COMMAND_MANIFEST = [
9923
9630
  "aliases": [],
9924
9631
  "category": "CLI"
9925
9632
  },
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
9633
  {
9956
9634
  "id": "pan-docs",
9957
9635
  "path": ["docs"],
@@ -10071,110 +9749,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10071
9749
  "aliases": [],
10072
9750
  "category": "Admin"
10073
9751
  },
10074
- {
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",
10093
- "args": [{
10094
- "name": "project",
10095
- "required": true,
10096
- "variadic": false
10097
- }],
10098
- "options": [{
10099
- "flags": "--dry-run",
10100
- "description": "Print the exact migration plan without mutating anything",
10101
- "required": false,
10102
- "valueHint": null
10103
- }],
10104
- "aliases": [],
10105
- "category": "Admin"
10106
- },
10107
- {
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",
10116
- "args": [{
10117
- "name": "project",
10118
- "required": true,
10119
- "variadic": false
10120
- }],
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"
10136
- ],
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
9752
  {
10179
9753
  "id": "pan-admin-seed-uat-fixtures",
10180
9754
  "path": ["admin", "seed-uat-fixtures"],
@@ -10194,6 +9768,57 @@ const COMPOSER_COMMAND_MANIFEST = [
10194
9768
  "aliases": [],
10195
9769
  "category": "Admin"
10196
9770
  },
9771
+ {
9772
+ "id": "pan-admin-migrate-plan-home",
9773
+ "path": ["admin", "migrate-plan-home"],
9774
+ "display": "/pan admin migrate-plan-home",
9775
+ "description": "One-time bridge: copy open-issue planning artifacts and item progress from ~/.overdeck/state/<project>/ into <planHome>/.pan/ (PAN-3917 D8)",
9776
+ "args": [{
9777
+ "name": "project-key",
9778
+ "required": true,
9779
+ "variadic": false
9780
+ }],
9781
+ "options": [
9782
+ {
9783
+ "flags": "--commit",
9784
+ "description": "Commit the copied artifacts in the plan home",
9785
+ "required": false,
9786
+ "valueHint": null
9787
+ },
9788
+ {
9789
+ "flags": "--dry-run",
9790
+ "description": "Preview what would be copied without writing anything",
9791
+ "required": false,
9792
+ "valueHint": null
9793
+ },
9794
+ {
9795
+ "flags": "--repair-ignore",
9796
+ "description": "Only remove Overdeck's legacy .pan/ line from .gitignore and commit that file (no copy)",
9797
+ "required": false,
9798
+ "valueHint": null
9799
+ },
9800
+ {
9801
+ "flags": "--state-root <dir>",
9802
+ "description": "Override the state worktree root (tests / odd setups)",
9803
+ "required": true,
9804
+ "valueHint": "dir"
9805
+ },
9806
+ {
9807
+ "flags": "--plan-home <dir>",
9808
+ "description": "Override the plan home (tests / odd setups)",
9809
+ "required": true,
9810
+ "valueHint": "dir"
9811
+ },
9812
+ {
9813
+ "flags": "--open-issues <file>",
9814
+ "description": "Read open issue ids from a file instead of calling the tracker",
9815
+ "required": true,
9816
+ "valueHint": "file"
9817
+ }
9818
+ ],
9819
+ "aliases": [],
9820
+ "category": "Admin"
9821
+ },
10197
9822
  {
10198
9823
  "id": "pan-admin-agents",
10199
9824
  "path": ["admin", "agents"],
@@ -10298,53 +9923,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10298
9923
  "aliases": [],
10299
9924
  "category": "Admin"
10300
9925
  },
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
9926
  {
10349
9927
  "id": "pan-admin-specialists",
10350
9928
  "path": ["admin", "specialists"],
@@ -10433,7 +10011,7 @@ const COMPOSER_COMMAND_MANIFEST = [
10433
10011
  "done"
10434
10012
  ],
10435
10013
  "display": "/pan admin specialists done",
10436
- "description": "Signal specialist completion (deterministic status update)",
10014
+ "description": "Post a specialist verdict to the issue's pull/merge request (review, test, uat)",
10437
10015
  "args": [{
10438
10016
  "name": "type",
10439
10017
  "required": true,
@@ -10450,12 +10028,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10450
10028
  "required": true,
10451
10029
  "valueHint": "status"
10452
10030
  },
10453
- {
10454
- "flags": "--item <itemId>",
10455
- "description": "xBRIEF item ID (required for inspect verdicts)",
10456
- "required": true,
10457
- "valueHint": "itemId"
10458
- },
10459
10031
  {
10460
10032
  "flags": "--notes <notes>",
10461
10033
  "description": "Optional notes about the result",
@@ -10474,6 +10046,12 @@ const COMPOSER_COMMAND_MANIFEST = [
10474
10046
  "required": true,
10475
10047
  "valueHint": "notes"
10476
10048
  },
10049
+ {
10050
+ "flags": "--tested-sha <sha>",
10051
+ "description": "Test/UAT only: the commit the run exercised (git rev-parse HEAD before the gates)",
10052
+ "required": true,
10053
+ "valueHint": "sha"
10054
+ },
10477
10055
  {
10478
10056
  "flags": "--run-id <runId>",
10479
10057
  "description": "Review cycle ID used to deduplicate review feedback",
@@ -10819,30 +10397,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10819
10397
  "aliases": [],
10820
10398
  "category": "Admin"
10821
10399
  },
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",
10840
- "required": false,
10841
- "valueHint": null
10842
- }],
10843
- "aliases": [],
10844
- "category": "Admin"
10845
- },
10846
10400
  {
10847
10401
  "id": "pan-admin-db-rebuild-workspaces",
10848
10402
  "path": [
@@ -10905,105 +10459,6 @@ const COMPOSER_COMMAND_MANIFEST = [
10905
10459
  "aliases": [],
10906
10460
  "category": "Admin"
10907
10461
  },
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
10462
  {
11008
10463
  "id": "pan-admin-config",
11009
10464
  "path": ["admin", "config"],
@@ -11846,43 +11301,16 @@ const COMPOSER_COMMAND_MANIFEST = [
11846
11301
  "description": "Skip Qwen TTS daemon venv install (CUDA torch download is large)",
11847
11302
  "required": false,
11848
11303
  "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
11304
  },
11877
11305
  {
11878
- "flags": "--deep",
11879
- "description": "Use the deep inspection sub-role",
11306
+ "flags": "--skip-herdr",
11307
+ "description": "Skip Herdr terminal backend install/verify (tmux-only hosts)",
11880
11308
  "required": false,
11881
11309
  "valueHint": null
11882
11310
  }
11883
11311
  ],
11884
11312
  "aliases": [],
11885
- "category": "Lifecycle"
11313
+ "category": "Core"
11886
11314
  },
11887
11315
  {
11888
11316
  "id": "pan-caveman-compress",
@@ -12038,146 +11466,375 @@ const COMPOSER_COMMAND_MANIFEST = [
12038
11466
  "category": "Lifecycle"
12039
11467
  },
12040
11468
  {
12041
- "id": "pan-flywheel",
12042
- "path": ["flywheel"],
12043
- "display": "/pan flywheel",
12044
- "description": "Flywheel orchestrator lifecycle and status helpers",
11469
+ "id": "pan-spawn",
11470
+ "path": ["spawn"],
11471
+ "display": "/pan spawn",
11472
+ "description": "Create a worker pane for one xBRIEF item in the issue workspace",
11473
+ "args": [],
11474
+ "options": [
11475
+ {
11476
+ "flags": "--issue <id>",
11477
+ "description": "Issue the worker belongs to",
11478
+ "required": true,
11479
+ "valueHint": "id"
11480
+ },
11481
+ {
11482
+ "flags": "--item <item>",
11483
+ "description": "xBRIEF item the worker takes",
11484
+ "required": true,
11485
+ "valueHint": "item"
11486
+ },
11487
+ {
11488
+ "flags": "--model <model>",
11489
+ "description": "Model the worker runs on",
11490
+ "required": true,
11491
+ "valueHint": "model"
11492
+ },
11493
+ {
11494
+ "flags": "--harness <harness>",
11495
+ "description": "Coding-agent harness (default: claude-code)",
11496
+ "required": true,
11497
+ "valueHint": "harness"
11498
+ }
11499
+ ],
11500
+ "aliases": [],
11501
+ "category": "CLI"
11502
+ },
11503
+ {
11504
+ "id": "pan-worker",
11505
+ "path": ["worker"],
11506
+ "display": "/pan worker",
11507
+ "description": "Registered workers: spawn an issue-linked agent and get its report back; register external agents",
12045
11508
  "args": [],
12046
11509
  "options": [],
12047
11510
  "aliases": [],
12048
- "category": "Flywheel"
11511
+ "category": "CLI"
11512
+ },
11513
+ {
11514
+ "id": "pan-worker-run",
11515
+ "path": ["worker", "run"],
11516
+ "display": "/pan worker run",
11517
+ "description": "Start a worker for an issue and wait for its report (exit 0 done, 4 blocked/failed, 2 no report, 3 timeout, 1 error)",
11518
+ "args": [],
11519
+ "options": [
11520
+ {
11521
+ "flags": "--issue <id>",
11522
+ "description": "Issue the worker belongs to (required)",
11523
+ "required": true,
11524
+ "valueHint": "id"
11525
+ },
11526
+ {
11527
+ "flags": "--prompt <text>",
11528
+ "description": "The brief, inline",
11529
+ "required": true,
11530
+ "valueHint": "text"
11531
+ },
11532
+ {
11533
+ "flags": "--brief <file>",
11534
+ "description": "The brief, from a file",
11535
+ "required": true,
11536
+ "valueHint": "file"
11537
+ },
11538
+ {
11539
+ "flags": "--model <model>",
11540
+ "description": "Model override (default: roles.worker.model)",
11541
+ "required": true,
11542
+ "valueHint": "model"
11543
+ },
11544
+ {
11545
+ "flags": "--harness <harness>",
11546
+ "description": "Harness override (default: routed from the model)",
11547
+ "required": true,
11548
+ "valueHint": "harness"
11549
+ },
11550
+ {
11551
+ "flags": "--read-only",
11552
+ "description": "Run in the issue workspace with git writes blocked",
11553
+ "required": false,
11554
+ "valueHint": null
11555
+ },
11556
+ {
11557
+ "flags": "--cwd <path>",
11558
+ "description": "Working directory inside the issue workspace",
11559
+ "required": true,
11560
+ "valueHint": "path"
11561
+ },
11562
+ {
11563
+ "flags": "--parent <id>",
11564
+ "description": "Spawning agent or conversation (default: $OVERDECK_AGENT_ID, then $OVERDECK_CONVERSATION)",
11565
+ "required": true,
11566
+ "valueHint": "id"
11567
+ },
11568
+ {
11569
+ "flags": "--name <label>",
11570
+ "description": "Label shown in the Agents Directory",
11571
+ "required": true,
11572
+ "valueHint": "label"
11573
+ },
11574
+ {
11575
+ "flags": "--detach",
11576
+ "description": "Print the worker id and return without waiting",
11577
+ "required": false,
11578
+ "valueHint": null
11579
+ },
11580
+ {
11581
+ "flags": "--timeout <seconds>",
11582
+ "description": "Stop waiting after this many seconds (exit 3; the worker keeps running)",
11583
+ "required": true,
11584
+ "valueHint": "seconds"
11585
+ },
11586
+ {
11587
+ "flags": "--stop-after-report",
11588
+ "description": "Stop the worker after its first report",
11589
+ "required": false,
11590
+ "valueHint": null
11591
+ }
11592
+ ],
11593
+ "aliases": [],
11594
+ "category": "CLI"
11595
+ },
11596
+ {
11597
+ "id": "pan-worker-wait",
11598
+ "path": ["worker", "wait"],
11599
+ "display": "/pan worker wait",
11600
+ "description": "Wait for a worker's report (same exit codes as run); the status line names its seq",
11601
+ "args": [{
11602
+ "name": "worker-id",
11603
+ "required": true,
11604
+ "variadic": false
11605
+ }],
11606
+ "options": [{
11607
+ "flags": "--after <seq>",
11608
+ "description": "Return the next report after this seq (default: the newest report, whenever written)",
11609
+ "required": true,
11610
+ "valueHint": "seq"
11611
+ }, {
11612
+ "flags": "--timeout <seconds>",
11613
+ "description": "Stop waiting after this many seconds (exit 3)",
11614
+ "required": true,
11615
+ "valueHint": "seconds"
11616
+ }],
11617
+ "aliases": [],
11618
+ "category": "CLI"
12049
11619
  },
12050
11620
  {
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
11621
+ "id": "pan-worker-report",
11622
+ "path": ["worker", "report"],
11623
+ "display": "/pan worker report",
11624
+ "description": "Record a worker's report (run by the worker itself)",
11625
+ "args": [{
11626
+ "name": "worker-id",
11627
+ "required": true,
11628
+ "variadic": false
12061
11629
  }],
11630
+ "options": [
11631
+ {
11632
+ "flags": "--file <path>",
11633
+ "description": "Read the Markdown report from a file",
11634
+ "required": true,
11635
+ "valueHint": "path"
11636
+ },
11637
+ {
11638
+ "flags": "--stdin",
11639
+ "description": "Read the Markdown report from stdin",
11640
+ "required": false,
11641
+ "valueHint": null
11642
+ },
11643
+ {
11644
+ "flags": "--status <status>",
11645
+ "description": "done | blocked | failed (default: done)",
11646
+ "required": true,
11647
+ "valueHint": "status"
11648
+ }
11649
+ ],
12062
11650
  "aliases": [],
12063
- "category": "Flywheel"
11651
+ "category": "CLI"
12064
11652
  },
12065
11653
  {
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)",
11654
+ "id": "pan-worker-list",
11655
+ "path": ["worker", "list"],
11656
+ "display": "/pan worker list",
11657
+ "description": "List workers with their parent, live state and newest report",
12070
11658
  "args": [],
12071
11659
  "options": [
12072
11660
  {
12073
11661
  "flags": "--issue <id>",
12074
- "description": "Filter to a single issue",
11662
+ "description": "Only this issue's workers",
12075
11663
  "required": true,
12076
11664
  "valueHint": "id"
12077
11665
  },
12078
11666
  {
12079
- "flags": "--window <dur>",
12080
- "description": "Stats window like 30d, 7d (default 30d)",
11667
+ "flags": "--parent <id>",
11668
+ "description": "Only workers of this parent",
12081
11669
  "required": true,
12082
- "valueHint": "dur"
11670
+ "valueHint": "id"
12083
11671
  },
12084
11672
  {
12085
11673
  "flags": "--json",
12086
- "description": "Output JSON",
11674
+ "description": "Print JSON",
12087
11675
  "required": false,
12088
11676
  "valueHint": null
12089
11677
  }
12090
11678
  ],
12091
11679
  "aliases": [],
12092
- "category": "Flywheel"
11680
+ "category": "CLI"
12093
11681
  },
12094
11682
  {
12095
- "id": "pan-flywheel-start",
12096
- "path": ["flywheel", "start"],
12097
- "display": "/pan flywheel start",
12098
- "description": "Start the Flywheel orchestrator",
11683
+ "id": "pan-worker-register",
11684
+ "path": ["worker", "register"],
11685
+ "display": "/pan worker register",
11686
+ "description": "Record an agent another tool launched so the Agents Directory shows it (read-only; prints its id)",
12099
11687
  "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
- }],
11688
+ "options": [
11689
+ {
11690
+ "flags": "--source <name>",
11691
+ "description": "Who launched it ([a-z0-9-], not codex-plugin) (required)",
11692
+ "required": true,
11693
+ "valueHint": "name"
11694
+ },
11695
+ {
11696
+ "flags": "--external-id <id>",
11697
+ "description": "The launcher's id for it (required)",
11698
+ "required": true,
11699
+ "valueHint": "id"
11700
+ },
11701
+ {
11702
+ "flags": "--harness <harness>",
11703
+ "description": "codex, claude-code, … (required)",
11704
+ "required": true,
11705
+ "valueHint": "harness"
11706
+ },
11707
+ {
11708
+ "flags": "--model <model>",
11709
+ "description": "Model it runs",
11710
+ "required": true,
11711
+ "valueHint": "model"
11712
+ },
11713
+ {
11714
+ "flags": "--cwd <path>",
11715
+ "description": "Its working directory",
11716
+ "required": true,
11717
+ "valueHint": "path"
11718
+ },
11719
+ {
11720
+ "flags": "--issue <id>",
11721
+ "description": "Issue it works on",
11722
+ "required": true,
11723
+ "valueHint": "id"
11724
+ },
11725
+ {
11726
+ "flags": "--parent <id>",
11727
+ "description": "Spawning agent id, conversation tmux session, or claude-session:<uuid>",
11728
+ "required": true,
11729
+ "valueHint": "id"
11730
+ },
11731
+ {
11732
+ "flags": "--label <text>",
11733
+ "description": "Label shown in the Agents Directory",
11734
+ "required": true,
11735
+ "valueHint": "text"
11736
+ },
11737
+ {
11738
+ "flags": "--pid <n>",
11739
+ "description": "Its process id (liveness is read from it)",
11740
+ "required": true,
11741
+ "valueHint": "n"
11742
+ },
11743
+ {
11744
+ "flags": "--transcript <path>",
11745
+ "description": "Its transcript file",
11746
+ "required": true,
11747
+ "valueHint": "path"
11748
+ },
11749
+ {
11750
+ "flags": "--session-id <id>",
11751
+ "description": "Its session or thread id",
11752
+ "required": true,
11753
+ "valueHint": "id"
11754
+ },
11755
+ {
11756
+ "flags": "--json",
11757
+ "description": "Print { id, created }",
11758
+ "required": false,
11759
+ "valueHint": null
11760
+ }
11761
+ ],
12111
11762
  "aliases": [],
12112
- "category": "Flywheel"
11763
+ "category": "CLI"
12113
11764
  },
12114
11765
  {
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",
11766
+ "id": "pan-flywheel",
11767
+ "path": ["flywheel"],
11768
+ "display": "/pan flywheel",
11769
+ "description": "Start, stop, pause, resume, or inspect the flywheel conversation",
12119
11770
  "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
- }],
11771
+ "options": [],
12126
11772
  "aliases": [],
12127
11773
  "category": "Flywheel"
12128
11774
  },
12129
11775
  {
12130
- "id": "pan-flywheel-config",
12131
- "path": ["flywheel", "config"],
12132
- "display": "/pan flywheel config",
12133
- "description": "Get or set Flywheel autonomy configuration",
11776
+ "id": "pan-flywheel-start",
11777
+ "path": ["flywheel", "start"],
11778
+ "display": "/pan flywheel start",
11779
+ "description": "Launch a conversation running /pan-flywheel",
12134
11780
  "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
- }],
11781
+ "options": [
11782
+ {
11783
+ "flags": "--model <model>",
11784
+ "description": "Model for the flywheel conversation",
11785
+ "required": true,
11786
+ "valueHint": "model"
11787
+ },
11788
+ {
11789
+ "flags": "--harness <harness>",
11790
+ "description": "Harness for the flywheel conversation",
11791
+ "required": true,
11792
+ "valueHint": "harness"
11793
+ },
11794
+ {
11795
+ "flags": "--cwd <path>",
11796
+ "description": "Working directory (default: cwd)",
11797
+ "required": true,
11798
+ "valueHint": "path"
11799
+ },
11800
+ {
11801
+ "flags": "--orders <book-id>",
11802
+ "description": "Order book the flywheel works from",
11803
+ "required": true,
11804
+ "valueHint": "book-id"
11805
+ },
11806
+ {
11807
+ "flags": "--fresh",
11808
+ "description": "Replace a paused flywheel conversation instead of refusing",
11809
+ "required": false,
11810
+ "valueHint": null
11811
+ }
11812
+ ],
12146
11813
  "aliases": [],
12147
11814
  "category": "Flywheel"
12148
11815
  },
12149
11816
  {
12150
- "id": "pan-flywheel-status",
12151
- "path": ["flywheel", "status"],
12152
- "display": "/pan flywheel status",
12153
- "description": "Show the active Flywheel run status",
11817
+ "id": "pan-flywheel-stop",
11818
+ "path": ["flywheel", "stop"],
11819
+ "display": "/pan flywheel stop",
11820
+ "description": "Ask the loop to write its report, wait for it, then pause",
12154
11821
  "args": [],
12155
11822
  "options": [{
12156
- "flags": "--json",
12157
- "description": "Emit the raw FlywheelStatus JSON",
12158
- "required": false,
12159
- "valueHint": null
11823
+ "flags": "--timeout <ms>",
11824
+ "description": "How long to wait for the report (default 120000)",
11825
+ "required": true,
11826
+ "valueHint": "ms"
12160
11827
  }],
12161
11828
  "aliases": [],
12162
11829
  "category": "Flywheel"
12163
11830
  },
12164
11831
  {
12165
- "id": "pan-flywheel-stats",
12166
- "path": ["flywheel", "stats"],
12167
- "display": "/pan flywheel stats",
12168
- "description": "Show Flywheel v1.0 readiness stats",
11832
+ "id": "pan-flywheel-abort",
11833
+ "path": ["flywheel", "abort"],
11834
+ "display": "/pan flywheel abort",
11835
+ "description": "Stop the flywheel conversation without a report",
12169
11836
  "args": [],
12170
- "options": [{
12171
- "flags": "--window <duration>",
12172
- "description": "Stats window duration",
12173
- "required": true,
12174
- "valueHint": "duration"
12175
- }, {
12176
- "flags": "--json",
12177
- "description": "Emit the raw FlywheelStats JSON",
12178
- "required": false,
12179
- "valueHint": null
12180
- }],
11837
+ "options": [],
12181
11838
  "aliases": [],
12182
11839
  "category": "Flywheel"
12183
11840
  },
@@ -12185,7 +11842,7 @@ const COMPOSER_COMMAND_MANIFEST = [
12185
11842
  "id": "pan-flywheel-pause",
12186
11843
  "path": ["flywheel", "pause"],
12187
11844
  "display": "/pan flywheel pause",
12188
- "description": "Pause the active Flywheel orchestrator run",
11845
+ "description": "Stop the flywheel session, keeping its conversation and transcript",
12189
11846
  "args": [],
12190
11847
  "options": [],
12191
11848
  "aliases": [],
@@ -12195,7 +11852,7 @@ const COMPOSER_COMMAND_MANIFEST = [
12195
11852
  "id": "pan-flywheel-resume",
12196
11853
  "path": ["flywheel", "resume"],
12197
11854
  "display": "/pan flywheel resume",
12198
- "description": "Resume the paused Flywheel orchestrator run",
11855
+ "description": "Respawn a paused flywheel and re-send /pan-flywheel",
12199
11856
  "args": [],
12200
11857
  "options": [],
12201
11858
  "aliases": [],
@@ -12205,26 +11862,21 @@ const COMPOSER_COMMAND_MANIFEST = [
12205
11862
  "id": "pan-flywheel-report",
12206
11863
  "path": ["flywheel", "report"],
12207
11864
  "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).",
11865
+ "description": "Ask a running loop for its report, or print .pan/flywheel/report.md",
12209
11866
  "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
- }],
11867
+ "options": [],
12216
11868
  "aliases": [],
12217
11869
  "category": "Flywheel"
12218
11870
  },
12219
11871
  {
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",
11872
+ "id": "pan-flywheel-status",
11873
+ "path": ["flywheel", "status"],
11874
+ "display": "/pan flywheel status",
11875
+ "description": "Show the derived flywheel status: run, last tick, policies, in-flight issues, order book",
12224
11876
  "args": [],
12225
11877
  "options": [{
12226
- "flags": "--force",
12227
- "description": "Complete even when the order book still has non-terminal items",
11878
+ "flags": "--json",
11879
+ "description": "Output as JSON",
12228
11880
  "required": false,
12229
11881
  "valueHint": null
12230
11882
  }],
@@ -12232,22 +11884,22 @@ const COMPOSER_COMMAND_MANIFEST = [
12232
11884
  "category": "Flywheel"
12233
11885
  },
12234
11886
  {
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",
11887
+ "id": "pan-flywheel-stats",
11888
+ "path": ["flywheel", "stats"],
11889
+ "display": "/pan flywheel stats",
11890
+ "description": "Substrate-bug discovery rate and P0 count, computed from the tracker and forge",
12249
11891
  "args": [],
12250
- "options": [],
11892
+ "options": [{
11893
+ "flags": "--json",
11894
+ "description": "Output as JSON",
11895
+ "required": false,
11896
+ "valueHint": null
11897
+ }, {
11898
+ "flags": "--window <days>",
11899
+ "description": "Window in days (default 30)",
11900
+ "required": true,
11901
+ "valueHint": "days"
11902
+ }],
12251
11903
  "aliases": [],
12252
11904
  "category": "Flywheel"
12253
11905
  },
@@ -13571,14 +13223,6 @@ const COMPOSER_COMMAND_VARIANTS = [
13571
13223
  "insert": "/pan plan --auto --auto-start ",
13572
13224
  "category": "Lifecycle"
13573
13225
  },
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
13226
  {
13583
13227
  "id": "pan-fork-plain",
13584
13228
  "path": ["fork"],
@@ -13713,7 +13357,117 @@ const HOOK_INVENTORY = [
13713
13357
  const WIRED_HOOK_INVENTORY = HOOK_INVENTORY.filter((hook) => hook.wired);
13714
13358
  const WIRED_HOOK_NAMES = WIRED_HOOK_INVENTORY.map((hook) => hook.name);
13715
13359
  //#endregion
13360
+ //#region src/terminal-backend.ts
13361
+ const TERMINAL_BACKEND_NAMES = ["herdr", "tmux"];
13362
+ const AGENT_ROLES = [
13363
+ "work",
13364
+ "worker",
13365
+ "review",
13366
+ "test",
13367
+ "uat",
13368
+ "strike",
13369
+ "plan"
13370
+ ];
13371
+ function isTerminalBackendName(value) {
13372
+ return typeof value === "string" && TERMINAL_BACKEND_NAMES.includes(value);
13373
+ }
13374
+ function isAgentRole(value) {
13375
+ return typeof value === "string" && AGENT_ROLES.includes(value);
13376
+ }
13377
+ //#endregion
13378
+ //#region src/agent-directory.ts
13379
+ const DirectoryEntryKind = effect.Schema.Literals([
13380
+ "agent",
13381
+ "conversation",
13382
+ "subagent",
13383
+ "external"
13384
+ ]);
13385
+ const DirectoryEntryState = effect.Schema.Literals([
13386
+ "working",
13387
+ "idle",
13388
+ "blocked",
13389
+ "done",
13390
+ "stopped",
13391
+ "unknown"
13392
+ ]);
13393
+ const DirectoryEntrySource = effect.Schema.Literals([
13394
+ "overdeck",
13395
+ "pane",
13396
+ "conversation",
13397
+ "claude-subagent",
13398
+ "codex-subagent",
13399
+ "registered",
13400
+ "codex-plugin"
13401
+ ]);
13402
+ const DirectoryTranscriptRef = effect.Schema.Union([
13403
+ effect.Schema.Struct({
13404
+ route: effect.Schema.Literal("agent"),
13405
+ agentId: effect.Schema.String
13406
+ }),
13407
+ effect.Schema.Struct({
13408
+ route: effect.Schema.Literal("agent-subagent"),
13409
+ agentId: effect.Schema.String,
13410
+ subagentId: effect.Schema.String
13411
+ }),
13412
+ effect.Schema.Struct({
13413
+ route: effect.Schema.Literal("conversation"),
13414
+ conversationName: effect.Schema.String
13415
+ }),
13416
+ effect.Schema.Struct({
13417
+ route: effect.Schema.Literal("conversation-subagent"),
13418
+ conversationName: effect.Schema.String,
13419
+ subagentId: effect.Schema.String
13420
+ })
13421
+ ]);
13422
+ const DirectoryEntryLocation = effect.Schema.Literals(["local", "remote"]);
13423
+ const DirectoryEntry = effect.Schema.Struct({
13424
+ id: effect.Schema.String,
13425
+ kind: DirectoryEntryKind,
13426
+ label: effect.Schema.String,
13427
+ location: DirectoryEntryLocation,
13428
+ /** projects.yaml key; `unassigned` when none (D5). */
13429
+ projectKey: effect.Schema.String,
13430
+ /** Uppercase issue id, e.g. `PAN-3920`. */
13431
+ issueId: effect.Schema.NullOr(effect.Schema.String),
13432
+ /** The issue's title from the dashboard's tracker cache; null when unknown. */
13433
+ issueTitle: effect.Schema.NullOr(effect.Schema.String),
13434
+ parentId: effect.Schema.NullOr(effect.Schema.String),
13435
+ role: effect.Schema.NullOr(effect.Schema.String),
13436
+ /** `unknown` when not known. */
13437
+ harness: effect.Schema.String,
13438
+ /** `unknown` when not known. */
13439
+ model: effect.Schema.String,
13440
+ state: DirectoryEntryState,
13441
+ startedAt: effect.Schema.NullOr(effect.Schema.String),
13442
+ lastActivityAt: effect.Schema.NullOr(effect.Schema.String),
13443
+ costUsd: effect.Schema.NullOr(effect.Schema.Number),
13444
+ source: DirectoryEntrySource,
13445
+ transcript: effect.Schema.NullOr(DirectoryTranscriptRef)
13446
+ });
13447
+ const AgentDirectoryResponse = effect.Schema.Struct({
13448
+ generatedAt: effect.Schema.String,
13449
+ windowHours: effect.Schema.Number,
13450
+ entries: effect.Schema.Array(DirectoryEntry)
13451
+ });
13452
+ //#endregion
13453
+ //#region src/companion-terminal.ts
13454
+ /**
13455
+ * Which companion terminal a conversation gets, or `null` for "keep the
13456
+ * owner pane as TERMINAL". A Codex conversation still on the legacy
13457
+ * `codex.transport: tui` runs the native TUI in its owner pane; the server
13458
+ * adapter reports that as `unsupported` and points at the runtime pane.
13459
+ */
13460
+ function companionTerminalKindFor(conversation) {
13461
+ if (conversation.harness === "opencode") return "opencode-attach";
13462
+ if (conversation.harness === "codex") return "codex-resume-remote";
13463
+ return null;
13464
+ }
13465
+ /** Body keys each mutation accepts. Anything else is rejected as target injection. */
13466
+ const COMPANION_TERMINAL_OPEN_BODY_KEYS = [];
13467
+ const COMPANION_TERMINAL_CLOSE_BODY_KEYS = ["generation"];
13468
+ //#endregion
13716
13469
  exports.ACP_BEHAVIOR = ACP_BEHAVIOR;
13470
+ exports.AGENT_ROLES = AGENT_ROLES;
13717
13471
  exports.Activity = Activity;
13718
13472
  exports.ActivityDetailedEvent = ActivityDetailedEvent;
13719
13473
  exports.ActivityEntryEvent = ActivityEntryEvent;
@@ -13727,6 +13481,7 @@ exports.AgentCompletedEvent = AgentCompletedEvent;
13727
13481
  exports.AgentContextSaturationChangedEvent = AgentContextSaturationChangedEvent;
13728
13482
  exports.AgentCreatedEvent = AgentCreatedEvent;
13729
13483
  exports.AgentCurrentIssueSetEvent = AgentCurrentIssueSetEvent;
13484
+ exports.AgentDirectoryResponse = AgentDirectoryResponse;
13730
13485
  exports.AgentEnrichmentChangedEvent = AgentEnrichmentChangedEvent;
13731
13486
  exports.AgentHealthKind = AgentHealthKind;
13732
13487
  exports.AgentHealthSnapshot = AgentHealthSnapshot;
@@ -13772,10 +13527,15 @@ exports.ArtifactUrls = ArtifactUrls;
13772
13527
  exports.ArtifactValidationCode = ArtifactValidationCode;
13773
13528
  exports.ArtifactValidationFinding = ArtifactValidationFinding;
13774
13529
  exports.ArtifactValidationResult = ArtifactValidationResult;
13530
+ exports.BackendPane = BackendPane;
13531
+ exports.BackendPaneChangedEvent = BackendPaneChangedEvent;
13532
+ exports.BackendPaneRemovedEvent = BackendPaneRemovedEvent;
13775
13533
  exports.BeadsFreshnessChangedEvent = BeadsFreshnessChangedEvent;
13776
13534
  exports.CHANNEL_REPLY_KIND_VALUES = CHANNEL_REPLY_KIND_VALUES;
13777
13535
  exports.CLAUDE_CODE_BEHAVIOR = CLAUDE_CODE_BEHAVIOR;
13778
13536
  exports.CODEX_BEHAVIOR = CODEX_BEHAVIOR;
13537
+ exports.COMPANION_TERMINAL_CLOSE_BODY_KEYS = COMPANION_TERMINAL_CLOSE_BODY_KEYS;
13538
+ exports.COMPANION_TERMINAL_OPEN_BODY_KEYS = COMPANION_TERMINAL_OPEN_BODY_KEYS;
13779
13539
  exports.COMPOSER_COMMAND_INSERT_OVERRIDES = COMPOSER_COMMAND_INSERT_OVERRIDES;
13780
13540
  exports.COMPOSER_COMMAND_MANIFEST = COMPOSER_COMMAND_MANIFEST;
13781
13541
  exports.COMPOSER_COMMAND_VARIANTS = COMPOSER_COMMAND_VARIANTS;
@@ -13823,6 +13583,15 @@ exports.DashboardLifecycleStartedEvent = DashboardLifecycleStartedEvent;
13823
13583
  exports.DashboardSnapshot = DashboardSnapshot;
13824
13584
  exports.DeepWipeRpc = DeepWipeRpc;
13825
13585
  exports.DeployStalenessSnapshot = DeployStalenessSnapshot;
13586
+ exports.DerivedBranchState = DerivedBranchState;
13587
+ exports.DerivedIssueState = DerivedIssueState;
13588
+ exports.DerivedPrState = DerivedPrState;
13589
+ exports.DirectoryEntry = DirectoryEntry;
13590
+ exports.DirectoryEntryKind = DirectoryEntryKind;
13591
+ exports.DirectoryEntryLocation = DirectoryEntryLocation;
13592
+ exports.DirectoryEntrySource = DirectoryEntrySource;
13593
+ exports.DirectoryEntryState = DirectoryEntryState;
13594
+ exports.DirectoryTranscriptRef = DirectoryTranscriptRef;
13826
13595
  exports.DiscoveredSessionSnapshot = DiscoveredSessionSnapshot;
13827
13596
  exports.DomainEvent = DomainEvent;
13828
13597
  exports.EDITORS = EDITORS;
@@ -13842,28 +13611,38 @@ exports.FeatureRegistryEntry = FeatureRegistryEntry;
13842
13611
  exports.FeatureRegistryStatus = FeatureRegistryStatus;
13843
13612
  exports.FlywheelAgent = FlywheelAgent;
13844
13613
  exports.FlywheelAgentStatus = FlywheelAgentStatus;
13614
+ exports.FlywheelBugRateCriterion = FlywheelBugRateCriterion;
13615
+ exports.FlywheelConversationSummary = FlywheelConversationSummary;
13616
+ exports.FlywheelDerivedStatus = FlywheelDerivedStatus;
13845
13617
  exports.FlywheelEffort = FlywheelEffort;
13618
+ exports.FlywheelFreshness = FlywheelFreshness;
13846
13619
  exports.FlywheelHarness = FlywheelHarness;
13847
13620
  exports.FlywheelHeadline = FlywheelHeadline;
13848
13621
  exports.FlywheelHttpUrl = FlywheelHttpUrl;
13622
+ exports.FlywheelInFlightRow = FlywheelInFlightRow;
13623
+ exports.FlywheelJournalSummary = FlywheelJournalSummary;
13624
+ exports.FlywheelLastTick = FlywheelLastTick;
13849
13625
  exports.FlywheelOrchestrator = FlywheelOrchestrator;
13626
+ exports.FlywheelOrderBookSummary = FlywheelOrderBookSummary;
13850
13627
  exports.FlywheelOrders = FlywheelOrders;
13628
+ exports.FlywheelP0Criterion = FlywheelP0Criterion;
13851
13629
  exports.FlywheelParkedItem = FlywheelParkedItem;
13852
13630
  exports.FlywheelPipelineItem = FlywheelPipelineItem;
13853
13631
  exports.FlywheelPipelineStatus = FlywheelPipelineStatus;
13854
13632
  exports.FlywheelPipelineVerb = FlywheelPipelineVerb;
13633
+ exports.FlywheelPolicies = FlywheelPolicies;
13855
13634
  exports.FlywheelRunId = FlywheelRunId;
13635
+ exports.FlywheelRunState = FlywheelRunState;
13856
13636
  exports.FlywheelScope = FlywheelScope;
13857
13637
  exports.FlywheelStats = FlywheelStats;
13858
- exports.FlywheelStatsCriteria = FlywheelStatsCriteria;
13859
- exports.FlywheelStatsCriterion = FlywheelStatsCriterion;
13860
13638
  exports.FlywheelStatsCriterionStatus = FlywheelStatsCriterionStatus;
13861
- exports.FlywheelStatsCriterionValue = FlywheelStatsCriterionValue;
13862
- exports.FlywheelStatsCriterionValueObject = FlywheelStatsCriterionValueObject;
13863
13639
  exports.FlywheelStatsTrend = FlywheelStatsTrend;
13640
+ exports.FlywheelStatsWindow = FlywheelStatsWindow;
13864
13641
  exports.FlywheelStatus = FlywheelStatus;
13865
13642
  exports.FlywheelSubstrateBug = FlywheelSubstrateBug;
13643
+ exports.FlywheelSubstrateBugRow = FlywheelSubstrateBugRow;
13866
13644
  exports.FlywheelSubstrateBugStatus = FlywheelSubstrateBugStatus;
13645
+ exports.FlywheelSubstrateSeverity = FlywheelSubstrateSeverity;
13867
13646
  exports.FlywheelSuggestion = FlywheelSuggestion;
13868
13647
  exports.FlywheelSuggestionAction = FlywheelSuggestionAction;
13869
13648
  exports.FlywheelSuggestionPriority = FlywheelSuggestionPriority;
@@ -13875,7 +13654,6 @@ exports.GetConversationStatsRpc = GetConversationStatsRpc;
13875
13654
  exports.GetDiscoveredSessionRpc = GetDiscoveredSessionRpc;
13876
13655
  exports.GetSessionsFeedFacetsRpc = GetSessionsFeedFacetsRpc;
13877
13656
  exports.GetSnapshotRpc = GetSnapshotRpc;
13878
- exports.GetWorkspaceDetailRpc = GetWorkspaceDetailRpc;
13879
13657
  exports.GlobalContextLayerRecord = GlobalContextLayerRecord;
13880
13658
  exports.GlobalContextLayerTarget = GlobalContextLayerTarget;
13881
13659
  exports.HOOK_INVENTORY = HOOK_INVENTORY;
@@ -13887,7 +13665,13 @@ exports.HygieneFinding = HygieneFinding;
13887
13665
  exports.HygienePullRequest = HygienePullRequest;
13888
13666
  exports.HygieneReport = HygieneReport;
13889
13667
  exports.INITIAL_READ_MODEL_STATE = INITIAL_READ_MODEL_STATE;
13668
+ exports.ISSUE_ATTENTIONS = ISSUE_ATTENTIONS;
13669
+ exports.ISSUE_STATES = ISSUE_STATES;
13670
+ exports.ISSUE_STATE_PRECEDENCE = ISSUE_STATE_PRECEDENCE;
13671
+ exports.IssueAttention = IssueAttention;
13890
13672
  exports.IssueId = IssueId;
13673
+ exports.IssueState = IssueState;
13674
+ exports.IssueStateChangedEvent = IssueStateChangedEvent;
13891
13675
  exports.IssueStatusChangedEvent = IssueStatusChangedEvent;
13892
13676
  exports.IssueTransitionedEvent = IssueTransitionedEvent;
13893
13677
  exports.IssuesDeltaEvent = IssuesDeltaEvent;
@@ -13921,7 +13705,6 @@ exports.MemoryStatusPhase = MemoryStatusPhase;
13921
13705
  exports.MemoryStatusUpdatedEvent = MemoryStatusUpdatedEvent;
13922
13706
  exports.MemoryTokenUsage = MemoryTokenUsage;
13923
13707
  exports.MergeReadyEvent = MergeReadyEvent;
13924
- exports.MergeStatusValue = MergeStatusValue;
13925
13708
  exports.ModelOrigin = ModelOrigin;
13926
13709
  exports.ModelOriginEntry = ModelOriginEntry;
13927
13710
  exports.OHMYPI_BEHAVIOR = OHMYPI_BEHAVIOR;
@@ -13942,7 +13725,6 @@ exports.PanRpcGroup = PanRpcGroup;
13942
13725
  exports.PendingTurn = PendingTurn;
13943
13726
  exports.PipelineReviewCompletedEvent = PipelineReviewCompletedEvent;
13944
13727
  exports.PipelineReviewStartedEvent = PipelineReviewStartedEvent;
13945
- exports.PipelineStatusChangedEvent = PipelineStatusChangedEvent;
13946
13728
  exports.PipelineTestCompletedEvent = PipelineTestCompletedEvent;
13947
13729
  exports.PipelineTestStartedEvent = PipelineTestStartedEvent;
13948
13730
  exports.PipelineVerificationFailedEvent = PipelineVerificationFailedEvent;
@@ -13953,6 +13735,8 @@ exports.PlanSubitemStatusChangedEvent = PlanSubitemStatusChangedEvent;
13953
13735
  exports.PlanningFailedEvent = PlanningFailedEvent;
13954
13736
  exports.PlanningStartedEvent = PlanningStartedEvent;
13955
13737
  exports.PlanningSyncEvent = PlanningSyncEvent;
13738
+ exports.PrChecksState = PrChecksState;
13739
+ exports.PrReviewState = PrReviewState;
13956
13740
  exports.ProjectCiHeadObservedEvent = ProjectCiHeadObservedEvent;
13957
13741
  exports.ProjectCiSnapshot = ProjectCiSnapshot;
13958
13742
  exports.ProjectCiSuite = ProjectCiSuite;
@@ -13969,7 +13753,6 @@ exports.ReadFileAtPathRpc = ReadFileAtPathRpc;
13969
13753
  exports.ReadWorkspaceFileInput = ReadWorkspaceFileInput;
13970
13754
  exports.ReadWorkspaceFileResult = ReadWorkspaceFileResult;
13971
13755
  exports.ReadWorkspaceFileRpc = ReadWorkspaceFileRpc;
13972
- exports.ReleaseStatusValue = ReleaseStatusValue;
13973
13756
  exports.ReplayEventsRpc = ReplayEventsRpc;
13974
13757
  exports.ResetMarker = ResetMarker;
13975
13758
  exports.ResetMarkerScope = ResetMarkerScope;
@@ -13987,13 +13770,9 @@ exports.RestartGateSnapshot = RestartGateSnapshot;
13987
13770
  exports.ReviewApprovedEvent = ReviewApprovedEvent;
13988
13771
  exports.ReviewCoordinatorDiedEvent = ReviewCoordinatorDiedEvent;
13989
13772
  exports.ReviewCoordinatorStartedEvent = ReviewCoordinatorStartedEvent;
13990
- exports.ReviewCycleEntry = ReviewCycleEntry;
13991
13773
  exports.ReviewReviewerCompletedEvent = ReviewReviewerCompletedEvent;
13992
13774
  exports.ReviewReviewerStartedEvent = ReviewReviewerStartedEvent;
13993
13775
  exports.ReviewSpecialistTimedOutEvent = ReviewSpecialistTimedOutEvent;
13994
- exports.ReviewStatusChangedEvent = ReviewStatusChangedEvent;
13995
- exports.ReviewStatusSnapshot = ReviewStatusSnapshot;
13996
- exports.ReviewStatusValue = ReviewStatusValue;
13997
13776
  exports.ReviewVerdictDispatchedEvent = ReviewVerdictDispatchedEvent;
13998
13777
  exports.ReviewVerdictRejectedEvent = ReviewVerdictRejectedEvent;
13999
13778
  exports.ReviewVerdictRestoreBlockedEvent = ReviewVerdictRestoreBlockedEvent;
@@ -14030,7 +13809,6 @@ exports.SubagentSummary = SubagentSummary;
14030
13809
  exports.SubscribeAgentOutputRpc = SubscribeAgentOutputRpc;
14031
13810
  exports.SubscribeConversationMessagesRpc = SubscribeConversationMessagesRpc;
14032
13811
  exports.SubscribeDomainEventsRpc = SubscribeDomainEventsRpc;
14033
- exports.SubscribeFlywheelStatusRpc = SubscribeFlywheelStatusRpc;
14034
13812
  exports.SubscribeIssueEventsRpc = SubscribeIssueEventsRpc;
14035
13813
  exports.SubscribeProjectSessionTreeRpc = SubscribeProjectSessionTreeRpc;
14036
13814
  exports.SubscribeTerminalRpc = SubscribeTerminalRpc;
@@ -14046,18 +13824,18 @@ exports.TELEMETRY_CLI_VERBS = TELEMETRY_CLI_VERBS;
14046
13824
  exports.TELEMETRY_EVENT_CATALOG = TELEMETRY_EVENT_CATALOG;
14047
13825
  exports.TELEMETRY_EVENT_NAMES = TELEMETRY_EVENT_NAMES;
14048
13826
  exports.TELEMETRY_PROPERTY_DOMAINS = TELEMETRY_PROPERTY_DOMAINS;
13827
+ exports.TERMINAL_BACKEND_NAMES = TERMINAL_BACKEND_NAMES;
14049
13828
  exports.TerminalCloseRpc = TerminalCloseRpc;
14050
13829
  exports.TerminalOpenRpc = TerminalOpenRpc;
14051
13830
  exports.TerminalOutput = TerminalOutput;
14052
13831
  exports.TerminalResizeRpc = TerminalResizeRpc;
14053
13832
  exports.TerminalWriteRpc = TerminalWriteRpc;
14054
13833
  exports.TestPassedEvent = TestPassedEvent;
14055
- exports.TestStatusValue = TestStatusValue;
14056
13834
  exports.ThinkingState = ThinkingState;
13835
+ exports.TickMarker = TickMarker;
13836
+ exports.TickMarkerPhase = TickMarkerPhase;
14057
13837
  exports.TurnDiffFileChange = TurnDiffFileChange;
14058
13838
  exports.TurnDiffSummary = TurnDiffSummary;
14059
- exports.UatStatusValue = UatStatusValue;
14060
- exports.VerificationStatusValue = VerificationStatusValue;
14061
13839
  exports.WIRED_HOOK_INVENTORY = WIRED_HOOK_INVENTORY;
14062
13840
  exports.WIRED_HOOK_NAMES = WIRED_HOOK_NAMES;
14063
13841
  exports.WS_METHODS = WS_METHODS;
@@ -14072,7 +13850,6 @@ exports.WorkspaceContextLayerTarget = WorkspaceContextLayerTarget;
14072
13850
  exports.WorkspaceCreatedEvent = WorkspaceCreatedEvent;
14073
13851
  exports.WorkspaceDeletedEvent = WorkspaceDeletedEvent;
14074
13852
  exports.WorkspaceDestroyedEvent = WorkspaceDestroyedEvent;
14075
- exports.WorkspaceDetail = WorkspaceDetail;
14076
13853
  exports.WorkspaceWipeStartedEvent = WorkspaceWipeStartedEvent;
14077
13854
  exports.WriteFileAtPathInput = WriteFileAtPathInput;
14078
13855
  exports.WriteFileAtPathResult = WriteFileAtPathResult;
@@ -14080,8 +13857,10 @@ exports.WriteFileAtPathRpc = WriteFileAtPathRpc;
14080
13857
  exports.applyEvent = applyEvent;
14081
13858
  exports.applyEvents = applyEvents;
14082
13859
  exports.applyIssueDelta = applyIssueDelta;
13860
+ exports.companionTerminalKindFor = companionTerminalKindFor;
14083
13861
  exports.compareIssueIds = compareIssueIds;
14084
13862
  exports.createIssueDelta = createIssueDelta;
13863
+ exports.decodeFlywheelDerivedStatus = decodeFlywheelDerivedStatus;
14085
13864
  exports.decodeFlywheelStats = decodeFlywheelStats;
14086
13865
  exports.deriveProjectCi = deriveProjectCi;
14087
13866
  exports.encodeFlywheelStats = encodeFlywheelStats;
@@ -14090,7 +13869,12 @@ exports.getHarnessBehavior = getHarnessBehavior;
14090
13869
  exports.getMaxMemoryObservationsPerIssue = getMaxMemoryObservationsPerIssue;
14091
13870
  exports.getMaxTurnDiffSummariesPerAgent = getMaxTurnDiffSummariesPerAgent;
14092
13871
  exports.getRuntimeBehavior = getRuntimeBehavior;
13872
+ exports.isAgentRole = isAgentRole;
13873
+ exports.isAgentSessionName = isAgentSessionName;
14093
13874
  exports.isChannelReplyKind = isChannelReplyKind;
13875
+ exports.isIssueAttention = isIssueAttention;
13876
+ exports.isIssueState = isIssueState;
13877
+ exports.isTerminalBackendName = isTerminalBackendName;
14094
13878
  exports.isTerminalTurnDiffSummaryStatus = isTerminalTurnDiffSummaryStatus;
14095
13879
  exports.normalizeChannelReplyPayload = normalizeChannelReplyPayload;
14096
13880
  exports.omitTurnDiffSummariesForAgent = omitTurnDiffSummariesForAgent;