@principal-ai/subsystems-react 0.50.0 → 0.51.1
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.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts.map +1 -1
- package/dist/pierre/PierreTrailCodeView.js +44 -21
- package/dist/pierre/PierreTrailCodeView.js.map +1 -1
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts +493 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts.map +1 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js +329 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js.map +1 -0
- package/dist/subsystem/C4Graph.d.ts +2 -2
- package/dist/subsystem/C4Graph.d.ts.map +1 -1
- package/dist/subsystem/C4Graph.js +38 -73
- package/dist/subsystem/C4Graph.js.map +1 -1
- package/dist/subsystem/C4NodeCard.d.ts +119 -0
- package/dist/subsystem/C4NodeCard.d.ts.map +1 -0
- package/dist/subsystem/C4NodeCard.js +223 -0
- package/dist/subsystem/C4NodeCard.js.map +1 -0
- package/dist/subsystem/DiagnosticToggle.d.ts +8 -1
- package/dist/subsystem/DiagnosticToggle.d.ts.map +1 -1
- package/dist/subsystem/DiagnosticToggle.js +40 -6
- package/dist/subsystem/DiagnosticToggle.js.map +1 -1
- package/dist/subsystem/FileDrawer.d.ts.map +1 -1
- package/dist/subsystem/FileDrawer.js +20 -21
- package/dist/subsystem/FileDrawer.js.map +1 -1
- package/dist/subsystem/IssueList.js +1 -1
- package/dist/subsystem/IssueList.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +13 -4
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/c4.d.ts +272 -0
- package/dist/subsystem/c4.d.ts.map +1 -0
- package/dist/subsystem/c4.js +322 -0
- package/dist/subsystem/c4.js.map +1 -0
- package/dist/subsystem/c4Evidence.d.ts +143 -0
- package/dist/subsystem/c4Evidence.d.ts.map +1 -0
- package/dist/subsystem/c4Evidence.js +240 -0
- package/dist/subsystem/c4Evidence.js.map +1 -0
- package/dist/subsystem/model.d.ts +27 -7
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +15 -0
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +78 -7
- package/dist/subsystem/nodes.js.map +1 -1
- package/package.json +3 -2
- package/src/index.ts +37 -0
- package/src/pierre/PierreTrailCodeView.tsx +49 -21
- package/src/stories/Subsystem/C4Graph/C4NodeGallery.stories.tsx +413 -0
- package/src/stories/Subsystem/C4Graph/ProposedElements.stories.tsx +293 -0
- package/src/stories/Subsystem/C4Graph/c4ProposedElements.fixture.ts +366 -0
- package/src/stories/Subsystem/ComponentGraph/Deprecated.stories.tsx +358 -0
- package/src/stories/Subsystem/ComponentGraph/Diagnostics.stories.tsx +27 -2
- package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +1 -1
- package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +1 -1
- package/src/stories/Subsystem/ComponentGraph/{Flows.stories.tsx → Trails.stories.tsx} +4 -4
- package/src/subsystem/C4Graph.tsx +81 -107
- package/src/subsystem/C4NodeCard.test.ts +301 -0
- package/src/subsystem/C4NodeCard.tsx +301 -0
- package/src/subsystem/DiagnosticToggle.tsx +58 -4
- package/src/subsystem/FileDrawer.tsx +32 -34
- package/src/subsystem/IssueList.tsx +1 -1
- package/src/subsystem/SubsystemComponentGraph.tsx +13 -5
- package/src/subsystem/c4.test.ts +573 -0
- package/src/subsystem/c4.ts +558 -0
- package/src/subsystem/c4Evidence.test.ts +386 -0
- package/src/subsystem/c4Evidence.ts +329 -0
- package/src/subsystem/model.ts +36 -7
- package/src/subsystem/nodes.tsx +124 -5
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts +0 -3
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts.map +0 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js +0 -2
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +0 -1
- package/dist/subsystem/toC4.d.ts +0 -95
- package/dist/subsystem/toC4.d.ts.map +0 -1
- package/dist/subsystem/toC4.js +0 -192
- package/dist/subsystem/toC4.js.map +0 -1
- package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +0 -101
- package/src/stories/Subsystem/C4Graph/c4Fixture.ts +0 -6
- package/src/subsystem/toC4.test.ts +0 -114
- package/src/subsystem/toC4.ts +0 -273
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import '@xyflow/react/dist/style.css';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { ReactFlowProvider, type NodeProps } from '@xyflow/react';
|
|
5
|
+
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
6
|
+
import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
|
|
7
|
+
import { SubsystemComponentNode } from '../../../subsystem/nodes';
|
|
8
|
+
import type {
|
|
9
|
+
SubsystemComponent,
|
|
10
|
+
SubsystemGraphNode,
|
|
11
|
+
} from '../../../subsystem/model';
|
|
12
|
+
import { trailFromSteps } from './fixtures';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `deprecated` is the inverse of `proposed`: the claim was real, its source is
|
|
16
|
+
* gone upstream. Mirrors Proposed.stories.tsx so the two temporary states read
|
|
17
|
+
* as siblings — proposed = not built yet, deprecated = built once, removed since.
|
|
18
|
+
*/
|
|
19
|
+
const meta = {
|
|
20
|
+
title: 'Subsystem/ComponentGraph/Deprecated',
|
|
21
|
+
parameters: { layout: 'fullscreen' },
|
|
22
|
+
tags: ['autodocs'],
|
|
23
|
+
decorators: [
|
|
24
|
+
(Story) => (
|
|
25
|
+
<ThemeProvider theme={defaultEditorTheme}>
|
|
26
|
+
<ReactFlowProvider>
|
|
27
|
+
<Story />
|
|
28
|
+
</ReactFlowProvider>
|
|
29
|
+
</ThemeProvider>
|
|
30
|
+
),
|
|
31
|
+
],
|
|
32
|
+
} satisfies Meta;
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
type Story = StoryObj<typeof meta>;
|
|
36
|
+
|
|
37
|
+
const PURL = 'pkg:github/principal-ai/subsystem-modeling';
|
|
38
|
+
|
|
39
|
+
function nodeProps(c: SubsystemComponent): NodeProps<SubsystemGraphNode> {
|
|
40
|
+
return {
|
|
41
|
+
data: { component: c },
|
|
42
|
+
selected: false,
|
|
43
|
+
width: 230,
|
|
44
|
+
height: 84,
|
|
45
|
+
} as unknown as NodeProps<SubsystemGraphNode>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Side-by-side single-node spotlights — deprecated vs its live neighbours. */
|
|
49
|
+
function NodeSpotlight({
|
|
50
|
+
label,
|
|
51
|
+
component,
|
|
52
|
+
}: {
|
|
53
|
+
label: string;
|
|
54
|
+
component: SubsystemComponent;
|
|
55
|
+
}) {
|
|
56
|
+
return (
|
|
57
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, width: 260 }}>
|
|
58
|
+
<div
|
|
59
|
+
style={{
|
|
60
|
+
fontFamily: 'ui-monospace, monospace',
|
|
61
|
+
fontSize: 11,
|
|
62
|
+
color: '#888',
|
|
63
|
+
minHeight: 32,
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
{label}
|
|
67
|
+
</div>
|
|
68
|
+
<div style={{ position: 'relative', height: 110, width: 240 }}>
|
|
69
|
+
<SubsystemComponentNode {...nodeProps(component)} />
|
|
70
|
+
</div>
|
|
71
|
+
<pre
|
|
72
|
+
style={{
|
|
73
|
+
margin: 0,
|
|
74
|
+
fontSize: 10,
|
|
75
|
+
fontFamily: 'ui-monospace, monospace',
|
|
76
|
+
background: '#1a1a1a',
|
|
77
|
+
color: '#ccc',
|
|
78
|
+
padding: 8,
|
|
79
|
+
borderRadius: 4,
|
|
80
|
+
overflow: 'auto',
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
{JSON.stringify(
|
|
84
|
+
{
|
|
85
|
+
construct: component.construct,
|
|
86
|
+
deprecated: component.deprecated || undefined,
|
|
87
|
+
removedIn: component.removedIn,
|
|
88
|
+
role: component.role,
|
|
89
|
+
symbol: component.symbol || undefined,
|
|
90
|
+
file: component.file || undefined,
|
|
91
|
+
},
|
|
92
|
+
null,
|
|
93
|
+
2,
|
|
94
|
+
)}
|
|
95
|
+
</pre>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const spotlightRows: Array<{ label: string; component: SubsystemComponent }> = [
|
|
101
|
+
{
|
|
102
|
+
label: 'live function (baseline)',
|
|
103
|
+
component: {
|
|
104
|
+
alias: 'live-fn',
|
|
105
|
+
name: 'auditSubsystemModel',
|
|
106
|
+
construct: 'function',
|
|
107
|
+
file: 'src/bun/verify-subsystem-component.ts',
|
|
108
|
+
purl: PURL,
|
|
109
|
+
symbol: 'auditSubsystemModel',
|
|
110
|
+
purpose: 'Deterministic dry-run audit of a stored model',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
label: 'deprecated + removedIn — slate border, badge',
|
|
115
|
+
component: {
|
|
116
|
+
alias: 'dead-fn',
|
|
117
|
+
name: 'auditTopologyRelations',
|
|
118
|
+
construct: 'function',
|
|
119
|
+
file: 'src/bun/topology-audit.ts',
|
|
120
|
+
purl: PURL,
|
|
121
|
+
symbol: 'auditTopologyRelations',
|
|
122
|
+
purpose: 'Verifies authored relations[] endpoints',
|
|
123
|
+
deprecated: true,
|
|
124
|
+
removedIn: {
|
|
125
|
+
commit: 'e168afc',
|
|
126
|
+
reason: 'Remove topology relations; nest module boundaries by path',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
label: 'deprecated, no removedIn (bare marker)',
|
|
132
|
+
component: {
|
|
133
|
+
alias: 'dead-bare',
|
|
134
|
+
name: 'graphifyHasRelationBetween',
|
|
135
|
+
construct: 'function',
|
|
136
|
+
file: 'src/bun/topology-audit.ts',
|
|
137
|
+
purl: PURL,
|
|
138
|
+
symbol: 'graphifyHasRelationBetween',
|
|
139
|
+
purpose: 'Relation predicate over the graphify edge set',
|
|
140
|
+
deprecated: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
label: 'deprecated + role: entry (badge shows deprecated only)',
|
|
145
|
+
component: {
|
|
146
|
+
alias: 'dead-entry',
|
|
147
|
+
name: 'topologyRelationsAudit',
|
|
148
|
+
construct: 'function',
|
|
149
|
+
file: 'src/bun/topology-audit.ts',
|
|
150
|
+
purl: PURL,
|
|
151
|
+
symbol: 'topologyRelationsAudit',
|
|
152
|
+
purpose: 'Audit entry for relation endpoints',
|
|
153
|
+
deprecated: true,
|
|
154
|
+
role: 'entry',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
label: 'proposed (the sibling temporary state)',
|
|
159
|
+
component: {
|
|
160
|
+
alias: 'prop-fn',
|
|
161
|
+
name: 'OpenCodeV2Lifecycle',
|
|
162
|
+
construct: 'function',
|
|
163
|
+
file: '',
|
|
164
|
+
purl: PURL,
|
|
165
|
+
symbol: 'OpenCodeV2Lifecycle',
|
|
166
|
+
purpose: 'Proposed Studio host lifecycle',
|
|
167
|
+
proposed: true,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
/** Spotlights: slate deprecated badge + border vs live, proposed, and entry. */
|
|
173
|
+
export const Spotlights: Story = {
|
|
174
|
+
render: () => (
|
|
175
|
+
<div
|
|
176
|
+
style={{
|
|
177
|
+
padding: 24,
|
|
178
|
+
display: 'flex',
|
|
179
|
+
flexWrap: 'wrap',
|
|
180
|
+
gap: 28,
|
|
181
|
+
alignItems: 'flex-start',
|
|
182
|
+
minHeight: '100vh',
|
|
183
|
+
boxSizing: 'border-box',
|
|
184
|
+
}}
|
|
185
|
+
>
|
|
186
|
+
{spotlightRows.map((row) => (
|
|
187
|
+
<NodeSpotlight key={row.component.alias} {...row} />
|
|
188
|
+
))}
|
|
189
|
+
</div>
|
|
190
|
+
),
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Full graph: live audit calling a deleted topology audit, which called two
|
|
195
|
+
// more deleted helpers. Mirrors the real wedged model.
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
const deprecatedComponents: SubsystemComponent[] = [
|
|
198
|
+
{
|
|
199
|
+
alias: 'audit',
|
|
200
|
+
name: 'auditSubsystemModel',
|
|
201
|
+
construct: 'function',
|
|
202
|
+
file: 'src/bun/verify-subsystem-component.ts',
|
|
203
|
+
purl: PURL,
|
|
204
|
+
symbol: 'auditSubsystemModel',
|
|
205
|
+
purpose: 'Deterministic dry-run audit of a stored model',
|
|
206
|
+
role: 'entry',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
alias: 'topology',
|
|
210
|
+
name: 'auditTopologyRelations',
|
|
211
|
+
construct: 'function',
|
|
212
|
+
file: 'src/bun/topology-audit.ts',
|
|
213
|
+
purl: PURL,
|
|
214
|
+
symbol: 'auditTopologyRelations',
|
|
215
|
+
purpose: 'Orchestrates relations[] endpoint checks',
|
|
216
|
+
deprecated: true,
|
|
217
|
+
removedIn: {
|
|
218
|
+
commit: 'e168afc',
|
|
219
|
+
reason: 'Remove topology relations; nest module boundaries by path',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
alias: 'topo-relation',
|
|
224
|
+
name: 'graphifyHasRelationBetween',
|
|
225
|
+
construct: 'function',
|
|
226
|
+
file: 'src/bun/topology-audit.ts',
|
|
227
|
+
purl: PURL,
|
|
228
|
+
symbol: 'graphifyHasRelationBetween',
|
|
229
|
+
purpose: 'True when Graphify records a relation between two nodes',
|
|
230
|
+
deprecated: true,
|
|
231
|
+
removedIn: {
|
|
232
|
+
commit: 'e168afc',
|
|
233
|
+
reason: 'Remove topology relations; nest module boundaries by path',
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
alias: 'topo-hints',
|
|
238
|
+
name: 'graphifyHasRelationTowardHints',
|
|
239
|
+
construct: 'function',
|
|
240
|
+
file: 'src/bun/topology-audit.ts',
|
|
241
|
+
purl: PURL,
|
|
242
|
+
symbol: 'graphifyHasRelationTowardHints',
|
|
243
|
+
purpose: 'Relation hints directed at a component',
|
|
244
|
+
deprecated: true,
|
|
245
|
+
removedIn: { commit: 'e168afc' },
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
alias: 'boundary',
|
|
249
|
+
name: 'auditBoundaryFields',
|
|
250
|
+
construct: 'function',
|
|
251
|
+
file: 'src/bun/boundary-audit.ts',
|
|
252
|
+
purl: PURL,
|
|
253
|
+
symbol: 'auditBoundaryFields',
|
|
254
|
+
purpose: 'Package/module containment + process checks',
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
const deprecatedTrails = [
|
|
259
|
+
trailFromSteps('audit-steps', 'Audit (dry-run, graphify-backed)', [
|
|
260
|
+
['audit', 'topology', 'calls', 'src/bun/verify-subsystem-component.ts', 1],
|
|
261
|
+
['audit', 'boundary', 'calls', 'src/bun/verify-subsystem-component.ts', 1],
|
|
262
|
+
['topology', 'topo-relation', 'calls', 'src/bun/topology-audit.ts', 1],
|
|
263
|
+
['topology', 'topo-hints', 'calls', 'src/bun/topology-audit.ts', 1],
|
|
264
|
+
]),
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
function DeprecatedDemo() {
|
|
268
|
+
const [selected, setSelected] = useState<string | null>(null);
|
|
269
|
+
return (
|
|
270
|
+
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
271
|
+
<SubsystemComponentGraph
|
|
272
|
+
components={deprecatedComponents}
|
|
273
|
+
trails={deprecatedTrails}
|
|
274
|
+
onSelect={(id) => setSelected(id)}
|
|
275
|
+
/>
|
|
276
|
+
<div style={{ marginTop: 8, padding: '0 12px', fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
277
|
+
Click a slate `deprecated` badge to open the removal provenance
|
|
278
|
+
{selected ? ` · selected: ${selected}` : ''}
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Full graph: the deleted topology subtree still wired into a live audit. */
|
|
285
|
+
export const RemovedSubtree: Story = {
|
|
286
|
+
render: () => <DeprecatedDemo />,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* The popover states, isolated — every badge variant the popover can render.
|
|
291
|
+
* `Spotlights` shows the closed badge only; this is what the click opens.
|
|
292
|
+
*/
|
|
293
|
+
export function RemovalPopover() {
|
|
294
|
+
const deprecatedColor = '#6b7280';
|
|
295
|
+
const variants = [
|
|
296
|
+
{
|
|
297
|
+
label: 'with removedIn',
|
|
298
|
+
removal: {
|
|
299
|
+
commit: 'e168afc',
|
|
300
|
+
reason: 'Remove topology relations; nest module boundaries by path',
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
{ label: 'no removedIn (fallback copy)', removal: undefined },
|
|
304
|
+
] as const;
|
|
305
|
+
return (
|
|
306
|
+
<div style={{ display: 'flex', gap: 24, padding: 24, alignItems: 'flex-start' }}>
|
|
307
|
+
{variants.map((v) => (
|
|
308
|
+
<div key={v.label} style={{ width: 300 }}>
|
|
309
|
+
<div
|
|
310
|
+
style={{
|
|
311
|
+
fontFamily: 'ui-monospace, monospace',
|
|
312
|
+
fontSize: 11,
|
|
313
|
+
color: '#888',
|
|
314
|
+
marginBottom: 6,
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
317
|
+
{v.label}
|
|
318
|
+
</div>
|
|
319
|
+
<div
|
|
320
|
+
role="dialog"
|
|
321
|
+
aria-label="Removal provenance"
|
|
322
|
+
style={{
|
|
323
|
+
padding: '8px 10px',
|
|
324
|
+
borderRadius: 6,
|
|
325
|
+
background: '#1f1f1f',
|
|
326
|
+
border: `1px solid ${deprecatedColor}`,
|
|
327
|
+
boxShadow: '0 6px 20px rgba(0,0,0,0.35)',
|
|
328
|
+
fontFamily: 'system-ui, sans-serif',
|
|
329
|
+
fontSize: 13,
|
|
330
|
+
color: '#eee',
|
|
331
|
+
}}
|
|
332
|
+
>
|
|
333
|
+
<div style={{ fontWeight: 600, marginBottom: 4, color: deprecatedColor }}>
|
|
334
|
+
Deprecated
|
|
335
|
+
</div>
|
|
336
|
+
{v.removal ? (
|
|
337
|
+
<>
|
|
338
|
+
<div style={{ fontFamily: 'ui-monospace, monospace', marginBottom: 4 }}>
|
|
339
|
+
removed in {v.removal.commit}
|
|
340
|
+
</div>
|
|
341
|
+
{v.removal.reason && <div style={{ color: '#aaa' }}>{v.removal.reason}</div>}
|
|
342
|
+
</>
|
|
343
|
+
) : (
|
|
344
|
+
<div style={{ color: '#aaa' }}>
|
|
345
|
+
This claim's source was removed upstream.
|
|
346
|
+
</div>
|
|
347
|
+
)}
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
))}
|
|
351
|
+
</div>
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** The removal-provenance popover, both copy variants. */
|
|
356
|
+
export const Popover: Story = {
|
|
357
|
+
render: () => <RemovalPopover />,
|
|
358
|
+
};
|
|
@@ -46,24 +46,30 @@ const GRAPH_DESCRIPTION =
|
|
|
46
46
|
/** Every chip state side by side, for quick visual review. */
|
|
47
47
|
export const States: Story = {
|
|
48
48
|
render: () => {
|
|
49
|
-
const rows: Array<{ label: string; status: SubsystemDiagnosticStatus; issueCount?: number; stale?: boolean; busy?: boolean }> = [
|
|
49
|
+
const rows: Array<{ label: string; status: SubsystemDiagnosticStatus; issueCount?: number; fixableCount?: number; stale?: boolean; busy?: boolean }> = [
|
|
50
50
|
{ label: 'ok', status: 'ok' },
|
|
51
51
|
{ label: 'ok (stale)', status: 'ok', stale: true },
|
|
52
52
|
{ label: 'issues · 3', status: 'issues', issueCount: 3 },
|
|
53
53
|
{ label: 'gaps · 2', status: 'gaps', issueCount: 2 },
|
|
54
54
|
{ label: 'unknown (never checked)', status: 'unknown' },
|
|
55
55
|
{ label: 'issues (busy)', status: 'issues', issueCount: 3, busy: true },
|
|
56
|
+
{ label: 'issues · 7, 7 fixable', status: 'issues', issueCount: 7, fixableCount: 7 },
|
|
57
|
+
{ label: 'issues · 4, 2 fixable', status: 'issues', issueCount: 4, fixableCount: 2 },
|
|
58
|
+
{ label: 'issues · 2, fixable + stale', status: 'issues', issueCount: 2, fixableCount: 2, stale: true },
|
|
59
|
+
{ label: 'issues · 120, fixable capped', status: 'issues', issueCount: 120, fixableCount: 120 },
|
|
60
|
+
{ label: 'issues (busy) hides badge', status: 'issues', issueCount: 3, fixableCount: 3, busy: true },
|
|
56
61
|
];
|
|
57
62
|
return (
|
|
58
63
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 18, padding: 32 }}>
|
|
59
64
|
{rows.map((row) => (
|
|
60
65
|
<div key={row.label} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
|
61
|
-
<span style={{ width:
|
|
66
|
+
<span style={{ width: 220, fontFamily: 'monospace', fontSize: 12, opacity: 0.7 }}>
|
|
62
67
|
{row.label}
|
|
63
68
|
</span>
|
|
64
69
|
<SubsystemDiagnosticToggle
|
|
65
70
|
status={row.status}
|
|
66
71
|
issueCount={row.issueCount}
|
|
72
|
+
fixableCount={row.fixableCount}
|
|
67
73
|
stale={row.stale}
|
|
68
74
|
busy={row.busy}
|
|
69
75
|
onToggle={() => {}}
|
|
@@ -75,6 +81,25 @@ export const States: Story = {
|
|
|
75
81
|
},
|
|
76
82
|
};
|
|
77
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The real case that motivated the badge: seven re-pin findings, every one a
|
|
86
|
+
* one-click fix the construct-fixer defers to the human. The chip announces
|
|
87
|
+
* them so the deferral isn't silent.
|
|
88
|
+
*/
|
|
89
|
+
export const GraphFixableBadge: Story = {
|
|
90
|
+
render: () => (
|
|
91
|
+
<div style={{ width: '100%', height: '100vh' }}>
|
|
92
|
+
<SubsystemComponentGraph
|
|
93
|
+
components={graphComponents}
|
|
94
|
+
trails={graphEdges.trails}
|
|
95
|
+
title="Vestigial detail layer vs single-source declaration"
|
|
96
|
+
description={GRAPH_DESCRIPTION}
|
|
97
|
+
diagnostic={{ status: 'issues', issueCount: 7, fixableCount: 7, onToggle: () => {} }}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
|
|
78
103
|
/** The chip in its real home: the sidebar title row, beside the description toggle. */
|
|
79
104
|
export const GraphClean: Story = {
|
|
80
105
|
render: () => (
|
|
@@ -469,7 +469,7 @@ const MAINTAIN_ISSUES: SubsystemIssue[] = [
|
|
|
469
469
|
},
|
|
470
470
|
{
|
|
471
471
|
id: 'mr-symbol-unmatched',
|
|
472
|
-
severity: '
|
|
472
|
+
severity: 'error',
|
|
473
473
|
kind: 'symbol_unmatched',
|
|
474
474
|
message:
|
|
475
475
|
'No graphify node matches symbol readSse in packages/subsystems-studio/src/bun/opencode-v2-live.ts',
|
|
@@ -84,7 +84,7 @@ const ISSUES: SubsystemIssue[] = [
|
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
id: 'i18',
|
|
87
|
-
severity: '
|
|
87
|
+
severity: 'error',
|
|
88
88
|
kind: 'symbol_unmatched',
|
|
89
89
|
message: 'No Graphify node matches symbol persistSession in src/session/SessionStore.ts',
|
|
90
90
|
target: { kind: 'component', id: 'session-store', label: 'SessionStore' },
|
|
@@ -8,7 +8,7 @@ import { PierreTrailCodeView } from '../../../pierre';
|
|
|
8
8
|
import type { TrailViewerContext } from '../../../subsystem/SubsystemComponentGraph';
|
|
9
9
|
|
|
10
10
|
const meta = {
|
|
11
|
-
title: 'Subsystem/ComponentGraph/
|
|
11
|
+
title: 'Subsystem/ComponentGraph/Trails',
|
|
12
12
|
component: SubsystemComponentGraph,
|
|
13
13
|
parameters: {
|
|
14
14
|
layout: 'fullscreen',
|
|
@@ -164,7 +164,7 @@ const drawingTrails: SubsystemTrail[] = [
|
|
|
164
164
|
},
|
|
165
165
|
];
|
|
166
166
|
|
|
167
|
-
function
|
|
167
|
+
function TrailsDemo() {
|
|
168
168
|
const renderTrailViewer = useCallback(
|
|
169
169
|
({
|
|
170
170
|
trail,
|
|
@@ -219,8 +219,8 @@ function FlowsDemo() {
|
|
|
219
219
|
);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
export const
|
|
223
|
-
render: () => <
|
|
222
|
+
export const ThreeTrails: Story = {
|
|
223
|
+
render: () => <TrailsDemo />,
|
|
224
224
|
};
|
|
225
225
|
|
|
226
226
|
/**
|