@principal-ai/subsystems-react 0.38.0 → 0.40.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/components/maintain-events/MaintainEventLog.d.ts +35 -0
- package/dist/components/maintain-events/MaintainEventLog.d.ts.map +1 -0
- package/dist/components/maintain-events/MaintainEventLog.js +66 -0
- package/dist/components/maintain-events/MaintainEventLog.js.map +1 -0
- package/dist/components/maintain-events/MaintainLivePanel.d.ts +15 -0
- package/dist/components/maintain-events/MaintainLivePanel.d.ts.map +1 -0
- package/dist/components/maintain-events/MaintainLivePanel.js +49 -0
- package/dist/components/maintain-events/MaintainLivePanel.js.map +1 -0
- package/dist/components/maintain-events/index.d.ts +8 -0
- package/dist/components/maintain-events/index.d.ts.map +1 -0
- package/dist/components/maintain-events/index.js +6 -0
- package/dist/components/maintain-events/index.js.map +1 -0
- package/dist/graphify/consolidated.d.ts +8 -0
- package/dist/graphify/consolidated.d.ts.map +1 -1
- package/dist/graphify/construct.d.ts +18 -0
- package/dist/graphify/construct.d.ts.map +1 -1
- package/dist/graphify/construct.js +23 -0
- package/dist/graphify/construct.js.map +1 -1
- package/dist/graphify/index.d.ts +2 -2
- package/dist/graphify/index.d.ts.map +1 -1
- package/dist/graphify/index.js +1 -1
- package/dist/graphify/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/subsystem/IssueList.d.ts +49 -3
- package/dist/subsystem/IssueList.d.ts.map +1 -1
- package/dist/subsystem/IssueList.js +180 -79
- package/dist/subsystem/IssueList.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts +15 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +464 -14
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/formatDeclaration.js +19 -5
- package/dist/subsystem/formatDeclaration.js.map +1 -1
- package/dist/subsystem/model.d.ts +38 -0
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +124 -67
- package/dist/subsystem/nodes.js.map +1 -1
- package/dist/subsystem/symbolRefs.d.ts.map +1 -1
- package/dist/subsystem/symbolRefs.js +2 -0
- package/dist/subsystem/symbolRefs.js.map +1 -1
- package/package.json +3 -3
- package/src/components/maintain-events/MaintainEventLog.tsx +152 -0
- package/src/components/maintain-events/MaintainLivePanel.tsx +99 -0
- package/src/components/maintain-events/index.ts +10 -0
- package/src/graphify/consolidated.ts +8 -0
- package/src/graphify/construct.test.ts +61 -1
- package/src/graphify/construct.ts +33 -0
- package/src/graphify/index.ts +6 -1
- package/src/index.ts +9 -0
- package/src/stories/MaintainEvents/MaintainEventLog.stories.tsx +66 -0
- package/src/stories/MaintainEvents/MaintainLivePanel.stories.tsx +77 -0
- package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +625 -0
- package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +7 -1
- package/src/stories/Subsystem/ComponentGraph/NodeAnatomy.stories.tsx +40 -73
- package/src/stories/Subsystem/ComponentGraph/StoreValueType.stories.tsx +261 -0
- package/src/stories/Subsystem/StoreValueTypeDeclaration.stories.tsx +182 -0
- package/src/stories/data/maintain-live-events.json +554 -0
- package/src/subsystem/IssueList.focus.test.tsx +113 -0
- package/src/subsystem/IssueList.icon.test.tsx +95 -0
- package/src/subsystem/IssueList.tsx +267 -111
- package/src/subsystem/SubsystemComponentGraph.tsx +541 -13
- package/src/subsystem/formatDeclaration.test.ts +64 -0
- package/src/subsystem/formatDeclaration.ts +20 -5
- package/src/subsystem/model.ts +46 -0
- package/src/subsystem/nodes.group.test.tsx +52 -0
- package/src/subsystem/nodes.tsx +102 -2
- package/src/subsystem/symbolRefs.ts +2 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
import { useMemo, useState } from 'react';
|
|
2
|
+
import '@xyflow/react/dist/style.css';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
5
|
+
import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
|
|
6
|
+
import type { SubsystemComponent, SubsystemWalkthrough } from '../../../subsystem/model';
|
|
7
|
+
import {
|
|
8
|
+
issueCategory,
|
|
9
|
+
type SubsystemIssue,
|
|
10
|
+
type SubsystemIssueCategory,
|
|
11
|
+
} from '../../../subsystem/IssueList';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* IssueOverlay — the proposed per-node diagnostics layer (severity ring +
|
|
15
|
+
* earliest-rung corner chip, see NodeAnatomy/IssueOverlayProposal) driven by a
|
|
16
|
+
* *real* subsystem graph rather than isolated nodes.
|
|
17
|
+
*
|
|
18
|
+
* The graph is the Maintain-run model stored at
|
|
19
|
+
* ~/.principal/subsystem-models/sg-1789951509967-ppkvezdy0.json
|
|
20
|
+
* ("Maintain run — fire-and-forget RPC, wait for the finish event"): the
|
|
21
|
+
* renderer picker → host RPC → background runner → maintain orchestrator →
|
|
22
|
+
* opencode V2 session, plus the liveness-probe handshake. Its components and
|
|
23
|
+
* three walkthroughs are reproduced verbatim below; the topology is carried by
|
|
24
|
+
* the walkthroughs (`relations: []`), exactly as stored.
|
|
25
|
+
*
|
|
26
|
+
* What this story exercises: the graph's diagnostics surface over the real
|
|
27
|
+
* model — the title-row status chip, the grouped issue list, the per-node
|
|
28
|
+
* overlay (dotted border + earliest-rung chip, wired via `data.issue`), and
|
|
29
|
+
* layer-expand dimming. Clicking a card focuses its construct; collapsing it
|
|
30
|
+
* unfocuses.
|
|
31
|
+
*/
|
|
32
|
+
const meta = {
|
|
33
|
+
title: 'Subsystem/ComponentGraph/IssueOverlay',
|
|
34
|
+
parameters: { layout: 'fullscreen' },
|
|
35
|
+
decorators: [
|
|
36
|
+
(Story) => (
|
|
37
|
+
<ThemeProvider theme={defaultEditorTheme}>
|
|
38
|
+
<Story />
|
|
39
|
+
</ThemeProvider>
|
|
40
|
+
),
|
|
41
|
+
],
|
|
42
|
+
} satisfies Meta;
|
|
43
|
+
|
|
44
|
+
export default meta;
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
46
|
+
|
|
47
|
+
const PURL = 'pkg:github/principal-ai/subsystem-modeling';
|
|
48
|
+
const HOST = 'subsystems-studio/host';
|
|
49
|
+
const RENDERER = 'subsystems-studio/renderer';
|
|
50
|
+
/** The host barrel whose members disagree about their process (see `events-tab`). */
|
|
51
|
+
const BUN_INDEX = 'packages/subsystems-studio/src/bun/index.ts';
|
|
52
|
+
|
|
53
|
+
/** The Maintain-run model's components, as captured in the stored model. */
|
|
54
|
+
const MAINTAIN_COMPONENTS: SubsystemComponent[] = [
|
|
55
|
+
{
|
|
56
|
+
alias: 'maintain-picker',
|
|
57
|
+
name: 'MaintainModelPickerModal',
|
|
58
|
+
construct: 'function',
|
|
59
|
+
role: 'entry',
|
|
60
|
+
process: RENDERER,
|
|
61
|
+
file: 'packages/subsystems-studio/src/mainview/components/MaintainModelPickerModal.tsx',
|
|
62
|
+
purl: PURL,
|
|
63
|
+
symbol: 'MaintainModelPickerModal',
|
|
64
|
+
purpose: 'Picks the tier + model, then fires the maintain RPC and closes.',
|
|
65
|
+
framework: 'react',
|
|
66
|
+
stereotype: 'component',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
alias: 'maintain-rpc-handler',
|
|
70
|
+
name: 'maintainSubsystemModel RPC',
|
|
71
|
+
construct: 'function',
|
|
72
|
+
role: 'entry',
|
|
73
|
+
process: HOST,
|
|
74
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
75
|
+
module: BUN_INDEX,
|
|
76
|
+
purl: PURL,
|
|
77
|
+
purpose: 'Fire-and-forget RPC: returns started:true and hands off to the background runner.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
alias: 'maintain-background-runner',
|
|
81
|
+
name: 'maintainSubsystemModelInBackground',
|
|
82
|
+
construct: 'function',
|
|
83
|
+
process: HOST,
|
|
84
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
85
|
+
module: BUN_INDEX,
|
|
86
|
+
purl: PURL,
|
|
87
|
+
symbol: 'maintainSubsystemModelInBackground',
|
|
88
|
+
purpose: 'Guards duplicate runs, broadcasts running/done/error, and resolves the background maintain result.',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
alias: 'maintain-orchestrator',
|
|
92
|
+
name: 'maintainSubsystemModel',
|
|
93
|
+
construct: 'function',
|
|
94
|
+
process: HOST,
|
|
95
|
+
file: 'packages/subsystems-studio/src/bun/maintain-model.ts',
|
|
96
|
+
purl: PURL,
|
|
97
|
+
symbol: 'maintainSubsystemModel',
|
|
98
|
+
purpose: 'Installs agents, audits, routes by verdict, builds the brief, and resolves the maintainer model.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
alias: 'maintain-agent-launcher',
|
|
102
|
+
name: 'runMaintainAgent',
|
|
103
|
+
construct: 'function',
|
|
104
|
+
process: HOST,
|
|
105
|
+
file: 'packages/subsystems-studio/src/bun/maintain-model.ts',
|
|
106
|
+
purl: PURL,
|
|
107
|
+
symbol: 'runMaintainAgent',
|
|
108
|
+
purpose: 'Wraps an opencode V2 session run with the agent, task, and model.',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
alias: 'session-runner',
|
|
112
|
+
name: 'runOpencodeV2AgentSession',
|
|
113
|
+
construct: 'function',
|
|
114
|
+
process: HOST,
|
|
115
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
116
|
+
purl: PURL,
|
|
117
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
118
|
+
purpose: 'Creates + prompts an opencode session, then blocks until a terminal event arrives on the SSE feed.',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
alias: 'service-ensurer',
|
|
122
|
+
name: 'ensureServiceRunning',
|
|
123
|
+
construct: 'function',
|
|
124
|
+
process: HOST,
|
|
125
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
126
|
+
purl: PURL,
|
|
127
|
+
symbol: 'ensureServiceRunning',
|
|
128
|
+
purpose: 'Starts the opencode2 service when the daemon is not healthy.',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
alias: 'sse-feed-reader',
|
|
132
|
+
name: 'readSse',
|
|
133
|
+
construct: 'function',
|
|
134
|
+
process: HOST,
|
|
135
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
136
|
+
purl: PURL,
|
|
137
|
+
symbol: 'readSse',
|
|
138
|
+
purpose: 'Streams /api/event once and routes raw events into the wait loop.',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
alias: 'terminal-matcher',
|
|
142
|
+
name: 'isTerminalEvent',
|
|
143
|
+
construct: 'function',
|
|
144
|
+
process: HOST,
|
|
145
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
146
|
+
purl: PURL,
|
|
147
|
+
symbol: 'isTerminalEvent',
|
|
148
|
+
purpose: 'True when an event ends the session (execution finished/succeeded/failed or session idle).',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
alias: 'live-feed-store',
|
|
152
|
+
name: 'OpencodeLiveFeedState store',
|
|
153
|
+
construct: 'store',
|
|
154
|
+
process: HOST,
|
|
155
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
156
|
+
purl: PURL,
|
|
157
|
+
symbol: 'subscribeOpencodeLiveFeeds',
|
|
158
|
+
purpose: 'Retains per-session live status (starting/running/done/error) pushed to the renderer.',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
alias: 'maintain-probe-registry',
|
|
162
|
+
name: 'MaintainerProbeRegistry',
|
|
163
|
+
construct: 'store',
|
|
164
|
+
process: HOST,
|
|
165
|
+
file: 'packages/subsystems-studio/src/bun/maintainer-probe.ts',
|
|
166
|
+
purl: PURL,
|
|
167
|
+
symbol: 'getMaintainerProbeRegistry',
|
|
168
|
+
purpose: "Records when a maintain run's liveness probe lands.",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
alias: 'probe-route',
|
|
172
|
+
name: 'POST /api/maintainer/probe',
|
|
173
|
+
construct: 'function',
|
|
174
|
+
role: 'entry',
|
|
175
|
+
process: HOST,
|
|
176
|
+
file: 'packages/subsystems-studio/src/bun/http-server.ts',
|
|
177
|
+
purl: PURL,
|
|
178
|
+
purpose: "Liveness endpoint the agent's first tool call curls; proves the model can run tools headless.",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
alias: 'events-tab',
|
|
182
|
+
name: 'openMaintainEventsTab',
|
|
183
|
+
construct: 'function',
|
|
184
|
+
// Declared in the host barrel, but the only thing it does is drive the
|
|
185
|
+
// renderer — so it claims the renderer process. That disagreement with its
|
|
186
|
+
// two barrel siblings is exactly the `boundary_process_nest_disagree`
|
|
187
|
+
// finding below, and it is why the barrel gets a frame that refuses to
|
|
188
|
+
// nest under either process.
|
|
189
|
+
process: RENDERER,
|
|
190
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
191
|
+
module: BUN_INDEX,
|
|
192
|
+
purl: PURL,
|
|
193
|
+
symbol: 'openMaintainEventsTab',
|
|
194
|
+
purpose: "Opens the renderer tab that renders a session's live feed.",
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
alias: 'opencode-v2-server',
|
|
198
|
+
name: 'OpenCode V2 service',
|
|
199
|
+
construct: 'external',
|
|
200
|
+
role: 'service',
|
|
201
|
+
file: '',
|
|
202
|
+
purl: 'external:opencode2-service',
|
|
203
|
+
purpose: 'The opencode2 daemon owning /api/session and /api/event; executes the agent session.',
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
/** The model's three runtime walkthroughs, verbatim (these carry the topology). */
|
|
208
|
+
const MAINTAIN_WALKTHROUGHS: SubsystemWalkthrough[] = [
|
|
209
|
+
{
|
|
210
|
+
id: 'wt-start-maintain',
|
|
211
|
+
title: 'Start a maintenance run',
|
|
212
|
+
steps: [
|
|
213
|
+
{
|
|
214
|
+
from: 'maintain-picker',
|
|
215
|
+
to: 'maintain-rpc-handler',
|
|
216
|
+
mechanism: 'calls',
|
|
217
|
+
file: 'packages/subsystems-studio/src/mainview/components/MaintainModelPickerModal.tsx',
|
|
218
|
+
line: 116,
|
|
219
|
+
symbol: 'MaintainModelPickerModal',
|
|
220
|
+
purl: `${PURL}#packages/subsystems-studio/src/mainview/components/MaintainModelPickerModal.tsx`,
|
|
221
|
+
annotation: 'Fire the maintainSubsystemModel RPC with the selected model.',
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
from: 'maintain-rpc-handler',
|
|
225
|
+
to: 'maintain-background-runner',
|
|
226
|
+
mechanism: 'calls',
|
|
227
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
228
|
+
line: 2522,
|
|
229
|
+
symbol: 'maintainSubsystemModelInBackground',
|
|
230
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/index.ts`,
|
|
231
|
+
annotation: 'RPC returns started:true immediately and hands off to the guarded runner.',
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
from: 'maintain-background-runner',
|
|
235
|
+
to: 'maintain-orchestrator',
|
|
236
|
+
mechanism: 'calls',
|
|
237
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
238
|
+
line: 3160,
|
|
239
|
+
symbol: 'maintainSubsystemModelInBackground',
|
|
240
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/index.ts`,
|
|
241
|
+
annotation: 'Run the full install → audit → route-by-verdict → brief pipeline.',
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
from: 'maintain-orchestrator',
|
|
245
|
+
to: 'maintain-agent-launcher',
|
|
246
|
+
mechanism: 'calls',
|
|
247
|
+
file: 'packages/subsystems-studio/src/bun/maintain-model.ts',
|
|
248
|
+
line: 854,
|
|
249
|
+
symbol: 'runMaintainAgent',
|
|
250
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/maintain-model.ts`,
|
|
251
|
+
annotation: 'Resolve the model then launch the agent run, retrying once on the credentialed fallback if unusable.',
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
from: 'maintain-agent-launcher',
|
|
255
|
+
to: 'session-runner',
|
|
256
|
+
mechanism: 'calls',
|
|
257
|
+
file: 'packages/subsystems-studio/src/bun/maintain-model.ts',
|
|
258
|
+
line: 742,
|
|
259
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
260
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/maintain-model.ts`,
|
|
261
|
+
annotation: 'Hand the brief, agent, and directory to the V2 session runner.',
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
from: 'maintain-background-runner',
|
|
265
|
+
to: 'events-tab',
|
|
266
|
+
mechanism: 'calls',
|
|
267
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
268
|
+
line: 3164,
|
|
269
|
+
symbol: 'maintainSubsystemModelInBackground',
|
|
270
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/index.ts`,
|
|
271
|
+
annotation: 'Open the live feed tab the instant the session id exists.',
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
id: 'wt-wait-finish-event',
|
|
277
|
+
title: 'Wait for the finish event',
|
|
278
|
+
steps: [
|
|
279
|
+
{
|
|
280
|
+
from: 'session-runner',
|
|
281
|
+
to: 'sse-feed-reader',
|
|
282
|
+
mechanism: 'calls',
|
|
283
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
284
|
+
line: 355,
|
|
285
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
286
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
287
|
+
annotation: 'Open the /api/event subscription before creating the session.',
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
from: 'sse-feed-reader',
|
|
291
|
+
to: 'opencode-v2-server',
|
|
292
|
+
mechanism: 'watches',
|
|
293
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
294
|
+
line: 222,
|
|
295
|
+
symbol: 'readSse',
|
|
296
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
297
|
+
annotation: "Stream the single SSE feed that carries every session's events.",
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
from: 'session-runner',
|
|
301
|
+
to: 'service-ensurer',
|
|
302
|
+
mechanism: 'calls',
|
|
303
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
304
|
+
line: 326,
|
|
305
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
306
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
307
|
+
annotation: 'Ensure the opencode2 daemon is healthy, starting the service if it is not.',
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
from: 'session-runner',
|
|
311
|
+
to: 'opencode-v2-server',
|
|
312
|
+
mechanism: 'calls',
|
|
313
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
314
|
+
line: 384,
|
|
315
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
316
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
317
|
+
annotation: 'POST /api/session creates the session with a 15s HTTP timeout.',
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
from: 'session-runner',
|
|
321
|
+
to: 'opencode-v2-server',
|
|
322
|
+
mechanism: 'calls',
|
|
323
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
324
|
+
line: 428,
|
|
325
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
326
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
327
|
+
annotation: 'POST /api/session/{id}/prompt feeds the maintain brief with a 15s HTTP timeout.',
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
from: 'sse-feed-reader',
|
|
331
|
+
to: 'terminal-matcher',
|
|
332
|
+
mechanism: 'calls',
|
|
333
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
334
|
+
line: 365,
|
|
335
|
+
symbol: 'readSse',
|
|
336
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
337
|
+
annotation: 'Flag sawTerminal when the event is an execution finish or session idle.',
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
from: 'terminal-matcher',
|
|
341
|
+
to: 'session-runner',
|
|
342
|
+
mechanism: 'feeds',
|
|
343
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
344
|
+
line: 469,
|
|
345
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
346
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
347
|
+
annotation: 'Wait loop polls every 400ms until sawTerminal or the 15-minute deadline.',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
from: 'session-runner',
|
|
351
|
+
to: 'maintain-probe-registry',
|
|
352
|
+
mechanism: 'reads',
|
|
353
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
354
|
+
line: 484,
|
|
355
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
356
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
357
|
+
annotation: "Confirm the model's first tool call landed the liveness probe; abort as unusable on timeout.",
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
from: 'session-runner',
|
|
361
|
+
to: 'live-feed-store',
|
|
362
|
+
mechanism: 'writes',
|
|
363
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
364
|
+
line: 529,
|
|
365
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
366
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
367
|
+
annotation: 'Stamp the feed done (or error) when the wait loop exits.',
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
from: 'maintain-background-runner',
|
|
371
|
+
to: 'maintain-picker',
|
|
372
|
+
mechanism: 'feeds',
|
|
373
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
374
|
+
line: 3187,
|
|
375
|
+
symbol: 'maintainSubsystemModelInBackground',
|
|
376
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/index.ts`,
|
|
377
|
+
annotation: 'Broadcast done/error so the Maintain row flips off Running.',
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
id: 'wt-probe-handshake',
|
|
383
|
+
title: 'Liveness probe handshake',
|
|
384
|
+
steps: [
|
|
385
|
+
{
|
|
386
|
+
from: 'opencode-v2-server',
|
|
387
|
+
to: 'probe-route',
|
|
388
|
+
mechanism: 'calls',
|
|
389
|
+
file: 'packages/subsystems-studio/src/bun/http-server.ts',
|
|
390
|
+
line: 314,
|
|
391
|
+
symbol: 'handleSubsystemModelRequest',
|
|
392
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/http-server.ts`,
|
|
393
|
+
annotation: "The agent's step-0 tool call curls POST /api/maintainer/probe with the run token.",
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
from: 'probe-route',
|
|
397
|
+
to: 'maintain-probe-registry',
|
|
398
|
+
mechanism: 'writes',
|
|
399
|
+
file: 'packages/subsystems-studio/src/bun/http-server.ts',
|
|
400
|
+
line: 318,
|
|
401
|
+
symbol: 'getMaintainerProbeRegistry',
|
|
402
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/http-server.ts`,
|
|
403
|
+
annotation: 'mark(runId) records when the probe landed.',
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
from: 'session-runner',
|
|
407
|
+
to: 'maintain-probe-registry',
|
|
408
|
+
mechanism: 'reads',
|
|
409
|
+
file: 'packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
410
|
+
line: 484,
|
|
411
|
+
symbol: 'runOpencodeV2AgentSession',
|
|
412
|
+
purl: `${PURL}#packages/subsystems-studio/src/bun/opencode-v2-live.ts`,
|
|
413
|
+
annotation: 'Each loop tick checks whether the token landed before the probe deadline.',
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
},
|
|
417
|
+
];
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Illustrative audit findings, mapped onto the real component aliases in the
|
|
421
|
+
* Maintain-run model. The stored model's verification block is clean
|
|
422
|
+
* (13/13 anchored, 0 missing), so these are the *shape* of findings the
|
|
423
|
+
* diagnostics layer would receive — one per rung of the verification ladder
|
|
424
|
+
* (file → symbol → declaration → type → signature) plus the topology / walkthrough
|
|
425
|
+
* layers — to exercise the proposal end to end.
|
|
426
|
+
*/
|
|
427
|
+
const MAINTAIN_ISSUES: SubsystemIssue[] = [
|
|
428
|
+
{
|
|
429
|
+
id: 'mr-file',
|
|
430
|
+
severity: 'error',
|
|
431
|
+
kind: 'missing_file',
|
|
432
|
+
message:
|
|
433
|
+
'File packages/subsystems-studio/src/bun/maintainer-probe.ts is not present on disk at the captured commit.',
|
|
434
|
+
target: { kind: 'component', id: 'maintain-probe-registry', label: 'MaintainerProbeRegistry' },
|
|
435
|
+
fix: { label: 'Re-anchor to the current file' },
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'mr-symbol',
|
|
439
|
+
severity: 'error',
|
|
440
|
+
kind: 'symbol_ambiguous',
|
|
441
|
+
message: 'Multiple graphify nodes match runOpencodeV2AgentSession (2 candidates).',
|
|
442
|
+
target: { kind: 'component', id: 'session-runner', label: 'runOpencodeV2AgentSession' },
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
id: 'mr-decl',
|
|
446
|
+
severity: 'error',
|
|
447
|
+
kind: 'stale_declaration',
|
|
448
|
+
message: 'Declaration moved since capture — recorded start line 2522, now 2588.',
|
|
449
|
+
target: {
|
|
450
|
+
kind: 'component',
|
|
451
|
+
id: 'maintain-background-runner',
|
|
452
|
+
label: 'maintainSubsystemModelInBackground',
|
|
453
|
+
},
|
|
454
|
+
fix: { label: 'Re-pin declaration' },
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
id: 'mr-type',
|
|
458
|
+
severity: 'error',
|
|
459
|
+
kind: 'signature_mismatch',
|
|
460
|
+
message: 'Claimed (agent, task, model) => Session; graphify has (opts: RunOptions) => void.',
|
|
461
|
+
target: { kind: 'component', id: 'maintain-agent-launcher', label: 'runMaintainAgent' },
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
id: 'mr-sig',
|
|
465
|
+
severity: 'info',
|
|
466
|
+
kind: 'signature_unconfirmed',
|
|
467
|
+
message: 'Named parameter types are not present in the graphify cache.',
|
|
468
|
+
target: { kind: 'component', id: 'maintain-orchestrator', label: 'maintainSubsystemModel' },
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
id: 'mr-symbol-unmatched',
|
|
472
|
+
severity: 'info',
|
|
473
|
+
kind: 'symbol_unmatched',
|
|
474
|
+
message:
|
|
475
|
+
'No graphify node matches symbol readSse in packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
476
|
+
target: { kind: 'component', id: 'sse-feed-reader', label: 'readSse' },
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
id: 'mr-construct',
|
|
480
|
+
severity: 'info',
|
|
481
|
+
kind: 'construct_unconfirmed',
|
|
482
|
+
message: 'Graphify anchored the node but left the construct unclassified (store vs interface).',
|
|
483
|
+
target: { kind: 'component', id: 'live-feed-store', label: 'OpencodeLiveFeedState store' },
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
id: 'mr-endpoint',
|
|
487
|
+
severity: 'error',
|
|
488
|
+
kind: 'topology_broken_endpoint',
|
|
489
|
+
message: 'Relationship endpoint "maintain-background-runner" does not resolve to a component.',
|
|
490
|
+
target: {
|
|
491
|
+
kind: 'relation',
|
|
492
|
+
id: 'maintain-rpc-handler→maintain-background-runner',
|
|
493
|
+
label: 'maintainSubsystemModel RPC → maintainSubsystemModelInBackground',
|
|
494
|
+
detail: 'calls',
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
id: 'mr-hang',
|
|
499
|
+
severity: 'error',
|
|
500
|
+
kind: 'topology_broken_endpoint',
|
|
501
|
+
message: 'Run reaches the 15-minute deadline without an endpoint on the finish event.',
|
|
502
|
+
target: {
|
|
503
|
+
kind: 'relation',
|
|
504
|
+
id: 'session-runner→opencode-v2-server',
|
|
505
|
+
label: 'runOpencodeV2AgentSession → OpenCode V2 service',
|
|
506
|
+
detail: 'calls',
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
id: 'mr-boundary',
|
|
511
|
+
severity: 'info',
|
|
512
|
+
kind: 'boundary_process_nest_disagree',
|
|
513
|
+
message:
|
|
514
|
+
'module "packages/subsystems-studio/src/bun/index.ts" members claim different processes: "subsystems-studio/host", "subsystems-studio/renderer"',
|
|
515
|
+
target: {
|
|
516
|
+
kind: 'module',
|
|
517
|
+
id: BUN_INDEX,
|
|
518
|
+
label: 'packages/subsystems-studio/src/bun/index.ts',
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
id: 'mr-wt',
|
|
523
|
+
severity: 'info',
|
|
524
|
+
kind: 'walkthrough',
|
|
525
|
+
message:
|
|
526
|
+
'Step 7 (terminal-matcher → session-runner) references a line that moved (was :469).',
|
|
527
|
+
target: {
|
|
528
|
+
kind: 'step',
|
|
529
|
+
id: 'wt-wait-finish-event',
|
|
530
|
+
label: 'Wait for the finish event',
|
|
531
|
+
detail: 'step 7',
|
|
532
|
+
stepIndex: 6,
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
id: 'mr-repo',
|
|
537
|
+
severity: 'info',
|
|
538
|
+
kind: 'repo_unresolved',
|
|
539
|
+
message:
|
|
540
|
+
'Repo external:opencode2-service is not available locally — start the daemon to verify its endpoints.',
|
|
541
|
+
target: { kind: 'repo', id: 'external:opencode2-service', label: 'external:opencode2-service' },
|
|
542
|
+
},
|
|
543
|
+
];
|
|
544
|
+
|
|
545
|
+
function MaintainRunGraph({
|
|
546
|
+
issues,
|
|
547
|
+
status,
|
|
548
|
+
showIssues,
|
|
549
|
+
focusCategory,
|
|
550
|
+
}: {
|
|
551
|
+
issues: SubsystemIssue[];
|
|
552
|
+
status: 'ok' | 'issues' | 'gaps';
|
|
553
|
+
showIssues?: boolean;
|
|
554
|
+
focusCategory?: SubsystemIssueCategory;
|
|
555
|
+
}) {
|
|
556
|
+
const [lastEvent, setLastEvent] = useState<string | null>(null);
|
|
557
|
+
const errorCount = useMemo(
|
|
558
|
+
() => issues.filter((i) => i.severity === 'error').length,
|
|
559
|
+
[issues],
|
|
560
|
+
);
|
|
561
|
+
const gapCount = useMemo(
|
|
562
|
+
() => issues.filter((i) => i.severity === 'info').length,
|
|
563
|
+
[issues],
|
|
564
|
+
);
|
|
565
|
+
const issueCount = status === 'issues' ? errorCount : status === 'gaps' ? gapCount : 0;
|
|
566
|
+
return (
|
|
567
|
+
<div style={{ display: 'flex', flexDirection: 'column', width: '100%', height: '100vh' }}>
|
|
568
|
+
<div
|
|
569
|
+
style={{
|
|
570
|
+
padding: '6px 12px',
|
|
571
|
+
fontFamily: 'ui-monospace, monospace',
|
|
572
|
+
fontSize: 11,
|
|
573
|
+
opacity: 0.7,
|
|
574
|
+
borderBottom: '1px solid #333',
|
|
575
|
+
}}
|
|
576
|
+
>
|
|
577
|
+
proposed diagnostics layer · over the real Maintain-run graph ·{' '}
|
|
578
|
+
{lastEvent ?? 'click an issue to focus its target'}
|
|
579
|
+
</div>
|
|
580
|
+
<div style={{ flex: 1, minHeight: 0 }}>
|
|
581
|
+
<SubsystemComponentGraph
|
|
582
|
+
components={MAINTAIN_COMPONENTS}
|
|
583
|
+
relations={[]}
|
|
584
|
+
walkthroughs={MAINTAIN_WALKTHROUGHS}
|
|
585
|
+
title="Maintain run"
|
|
586
|
+
description="Fire-and-forget RPC, wait for the finish event — picker → RPC → background runner → orchestrator → opencode V2 session, plus the liveness-probe handshake."
|
|
587
|
+
diagnostic={{ status, issueCount, onToggle: () => {} }}
|
|
588
|
+
issues={issues}
|
|
589
|
+
showIssues={showIssues}
|
|
590
|
+
focusIssueCategory={focusCategory}
|
|
591
|
+
onSelectIssue={(issue) =>
|
|
592
|
+
setLastEvent(
|
|
593
|
+
`focused ${issue.target?.label ?? issue.id} · ${issueCategory(issue)}`,
|
|
594
|
+
)
|
|
595
|
+
}
|
|
596
|
+
onApplyIssueFix={(issue) => setLastEvent(`applied fix · ${issue.id}`)}
|
|
597
|
+
onHoverIssue={(issue) =>
|
|
598
|
+
setLastEvent(issue ? `hover ${issue.target?.label ?? issue.id}` : null)
|
|
599
|
+
}
|
|
600
|
+
/>
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** The model as stored — clean (13/13 anchored). Contrast for the overlay. */
|
|
607
|
+
export const MaintainRunClean: Story = {
|
|
608
|
+
render: () => <MaintainRunGraph issues={[]} status="ok" />,
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
/** The real graph in diagnostics mode, fed the illustrative findings above. */
|
|
612
|
+
export const MaintainRunIssues: Story = {
|
|
613
|
+
render: () => <MaintainRunGraph issues={MAINTAIN_ISSUES} status="issues" showIssues />,
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
/** Diagnostics seeded from issue presence; land the list on the construct layer. */
|
|
617
|
+
export const MaintainRunConstructLayer: Story = {
|
|
618
|
+
render: () => (
|
|
619
|
+
<MaintainRunGraph
|
|
620
|
+
issues={MAINTAIN_ISSUES}
|
|
621
|
+
status="issues"
|
|
622
|
+
focusCategory="construct"
|
|
623
|
+
/>
|
|
624
|
+
),
|
|
625
|
+
};
|
|
@@ -66,7 +66,13 @@ const ISSUES: SubsystemIssue[] = [
|
|
|
66
66
|
severity: 'info',
|
|
67
67
|
kind: 'walkthrough',
|
|
68
68
|
message: 'Step 2 references a line that moved (was :42).',
|
|
69
|
-
target: {
|
|
69
|
+
target: {
|
|
70
|
+
kind: 'step',
|
|
71
|
+
id: 'flow-1',
|
|
72
|
+
label: 'Checkout',
|
|
73
|
+
detail: 'step 2',
|
|
74
|
+
stepIndex: 1,
|
|
75
|
+
},
|
|
70
76
|
},
|
|
71
77
|
{
|
|
72
78
|
id: 'i7',
|