@principal-ai/principal-view-react 0.16.55 → 0.16.57
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/graphify/consolidated.d.ts +16 -1
- package/dist/graphify/consolidated.d.ts.map +1 -1
- package/dist/graphify/index.d.ts +1 -1
- package/dist/graphify/index.d.ts.map +1 -1
- package/dist/graphify/index.js.map +1 -1
- package/dist/graphify/kind.d.ts +1 -1
- package/dist/graphify/kind.d.ts.map +1 -1
- package/dist/graphify/kind.js +7 -1
- package/dist/graphify/kind.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/pierre/constructColors.d.ts +24 -0
- package/dist/pierre/constructColors.d.ts.map +1 -0
- package/dist/pierre/constructColors.js +91 -0
- package/dist/pierre/constructColors.js.map +1 -0
- package/dist/pierre/index.d.ts +2 -0
- package/dist/pierre/index.d.ts.map +1 -1
- package/dist/pierre/index.js +1 -0
- package/dist/pierre/index.js.map +1 -1
- package/dist/pierre/pierreSyntaxTheme.d.ts +11 -0
- package/dist/pierre/pierreSyntaxTheme.d.ts.map +1 -0
- package/dist/pierre/pierreSyntaxTheme.js +20 -0
- package/dist/pierre/pierreSyntaxTheme.js.map +1 -0
- package/dist/pierre/syntaxTokens.d.ts +11 -0
- package/dist/pierre/syntaxTokens.d.ts.map +1 -0
- package/dist/pierre/syntaxTokens.js +51 -0
- package/dist/pierre/syntaxTokens.js.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +8 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js +116 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -0
- package/dist/subsystem/ComponentDeclaration.d.ts +2 -2
- package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -1
- package/dist/subsystem/ComponentDeclaration.js +47 -24
- package/dist/subsystem/ComponentDeclaration.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +23 -2
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/formatDeclaration.d.ts.map +1 -1
- package/dist/subsystem/formatDeclaration.js +49 -10
- package/dist/subsystem/formatDeclaration.js.map +1 -1
- package/dist/subsystem/model.d.ts +57 -12
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +54 -24
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts +4 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +70 -21
- package/dist/subsystem/nodes.js.map +1 -1
- package/dist/subsystem/tokenizeComponent.d.ts +4 -3
- package/dist/subsystem/tokenizeComponent.d.ts.map +1 -1
- package/dist/subsystem/tokenizeComponent.js +7 -12
- package/dist/subsystem/tokenizeComponent.js.map +1 -1
- package/dist/subsystem/tokenizeFormatted.d.ts +3 -6
- package/dist/subsystem/tokenizeFormatted.d.ts.map +1 -1
- package/dist/subsystem/tokenizeFormatted.js +4 -75
- package/dist/subsystem/tokenizeFormatted.js.map +1 -1
- package/package.json +3 -1
- package/src/graphify/consolidated.ts +18 -1
- package/src/graphify/index.ts +1 -0
- package/src/graphify/kind.ts +7 -1
- package/src/index.ts +5 -3
- package/src/pierre/constructColors.test.ts +52 -0
- package/src/pierre/constructColors.ts +112 -0
- package/src/pierre/index.ts +5 -0
- package/src/pierre/pierreSyntaxTheme.ts +23 -0
- package/src/pierre/syntaxTokens.test.ts +35 -0
- package/src/pierre/syntaxTokens.ts +60 -0
- package/src/stories/{BoundaryNodes.stories.tsx → Audit/BoundaryNodes.stories.tsx} +1 -1
- package/src/stories/{CanvasEdgeTypes.stories.tsx → Audit/CanvasEdgeTypes.stories.tsx} +1 -1
- package/src/stories/{CanvasNodeTypes.stories.tsx → Audit/CanvasNodeTypes.stories.tsx} +1 -1
- package/src/stories/{ColorPriority.stories.tsx → Audit/ColorPriority.stories.tsx} +1 -1
- package/src/stories/{DiamondBadges.stories.tsx → Audit/DiamondBadges.stories.tsx} +1 -1
- package/src/stories/{NodeDimensionsTesting.stories.tsx → Audit/NodeDimensionsTesting.stories.tsx} +2 -2
- package/src/stories/{NodeFieldsAudit.stories.tsx → Audit/NodeFieldsAudit.stories.tsx} +1 -1
- package/src/stories/{NodeFontSizeTesting.stories.tsx → Audit/NodeFontSizeTesting.stories.tsx} +2 -2
- package/src/stories/{NodeShapes.stories.tsx → Audit/NodeShapes.stories.tsx} +1 -1
- package/src/stories/{WideNodesTesting.stories.tsx → Audit/WideNodesTesting.stories.tsx} +2 -2
- package/src/stories/{dashboard → Components}/DashboardRenderer.stories.tsx +2 -2
- package/src/stories/{GraphRenderer.stories.tsx → Components/GraphRenderer.stories.tsx} +2 -2
- package/src/stories/{MultiCanvasRenderer.stories.tsx → Components/MultiCanvasRenderer.stories.tsx} +2 -2
- package/src/stories/{SequenceDiagram.stories.tsx → Components/SequenceDiagram.stories.tsx} +2 -2
- package/src/stories/{StateView.stories.tsx → Components/StateView.stories.tsx} +2 -2
- package/src/stories/{TraceViewer.stories.tsx → Components/TraceViewer.stories.tsx} +3 -3
- package/src/stories/{WorkflowSequenceDiagram.stories.tsx → Components/WorkflowSequenceDiagram.stories.tsx} +1 -1
- package/src/stories/{AnimationWorkshop.stories.tsx → Features/AnimationWorkshop.stories.tsx} +5 -5
- package/src/stories/{ChangeTypeVisual.stories.tsx → Features/ChangeTypeVisual.stories.tsx} +2 -2
- package/src/stories/{EventDrivenAnimations.stories.tsx → Features/EventDrivenAnimations.stories.tsx} +2 -2
- package/src/stories/{MultiConfig.stories.tsx → Features/MultiConfig.stories.tsx} +2 -2
- package/src/stories/{ElkEdgeRouting.stories.tsx → Layout/ElkEdgeRouting.stories.tsx} +2 -2
- package/src/stories/{GraphOrientation.stories.tsx → Layout/GraphOrientation.stories.tsx} +3 -3
- package/src/stories/{MultiDirectionalConnections.stories.tsx → Layout/MultiDirectionalConnections.stories.tsx} +2 -2
- package/src/stories/{NodeDefinitionComparison.stories.tsx → Nodes/NodeDefinitionComparison.stories.tsx} +2 -2
- package/src/stories/{NodeNameFallbacks.stories.tsx → Nodes/NodeNameFallbacks.stories.tsx} +2 -2
- package/src/stories/{NumericColors.stories.tsx → Nodes/NumericColors.stories.tsx} +2 -2
- package/src/stories/{EventNameDisplay.stories.tsx → OTEL/EventNameDisplay.stories.tsx} +2 -2
- package/src/stories/{EventNameFallback.stories.tsx → OTEL/EventNameFallback.stories.tsx} +2 -2
- package/src/stories/{OtelComponents.stories.tsx → OTEL/OtelComponents.stories.tsx} +3 -3
- package/src/stories/{OtelNodeTypesPrototype.stories.tsx → OTEL/OtelNodeTypesPrototype.stories.tsx} +2 -2
- package/src/stories/{RawEventCards.stories.tsx → OTEL/RawEventCards.stories.tsx} +3 -3
- package/src/stories/{SpanBadges.stories.tsx → OTEL/SpanBadges.stories.tsx} +1 -1
- package/src/stories/{ValidationEventsCanvas.stories.tsx → OTEL/ValidationEventsCanvas.stories.tsx} +3 -3
- package/src/stories/{BacklogMdCanvases.stories.tsx → RealWorld/BacklogMdCanvases.stories.tsx} +2 -2
- package/src/stories/{FileCitySequence.stories.tsx → RealWorld/FileCitySequence.stories.tsx} +4 -4
- package/src/stories/{RealCanvasFiles.stories.tsx → RealWorld/RealCanvasFiles.stories.tsx} +7 -7
- package/src/stories/{ComponentDeclarationAudit.stories.tsx → Subsystem/ComponentDeclarationAudit.stories.tsx} +19 -20
- package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +365 -0
- package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +137 -0
- package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +238 -0
- package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +315 -0
- package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +959 -0
- package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +646 -0
- package/src/stories/Subsystem/ComponentGraph/fixtures.ts +129 -0
- package/src/subsystem/ComponentDeclaration.tsx +64 -26
- package/src/subsystem/SubsystemComponentGraph.tsx +26 -6
- package/src/subsystem/formatDeclaration.ts +57 -11
- package/src/subsystem/model.test.ts +38 -6
- package/src/subsystem/model.ts +110 -31
- package/src/subsystem/nodes.tsx +103 -27
- package/src/subsystem/tokenizeComponent.ts +12 -12
- package/src/subsystem/tokenizeFormatted.ts +9 -82
- package/src/stories/SubsystemComponentGraph.stories.tsx +0 -1225
- /package/src/stories/{dashboard/sample-dashboards → data}/activity-feed-analytics.dashboard.json +0 -0
|
@@ -0,0 +1,646 @@
|
|
|
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, type EdgeProps } from '@xyflow/react';
|
|
5
|
+
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
6
|
+
import { SubsystemComponentNode, SubsystemEdge } from '../../../subsystem/nodes';
|
|
7
|
+
import { ComponentDeclaration } from '../../../subsystem/ComponentDeclaration';
|
|
8
|
+
import {
|
|
9
|
+
MECHANISM_COLOR,
|
|
10
|
+
type SubsystemComponent,
|
|
11
|
+
type SubsystemEdgeMechanism,
|
|
12
|
+
type SubsystemGraphNode,
|
|
13
|
+
type SubsystemGraphEdge,
|
|
14
|
+
} from '../../../subsystem/model';
|
|
15
|
+
import { constructColorsFromPierreTheme } from '../../../pierre/constructColors';
|
|
16
|
+
import { resolvePierreSyntaxThemeName } from '../../../pierre/pierreSyntaxTheme';
|
|
17
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
18
|
+
|
|
19
|
+
const meta = {
|
|
20
|
+
title: 'Subsystem/ComponentGraph/Spotlights',
|
|
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
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Targeted side-by-side spotlights: each construct's DATA next to its
|
|
39
|
+
// RENDERING — no full graph shell. Three spotlights: nodes, mechanisms
|
|
40
|
+
// (edges), and anatomy (declaration panels). The mapping these make visible:
|
|
41
|
+
// construct:→ node anatomy + color, role → topology glyph, detail → drill-down,
|
|
42
|
+
// mechanism → edge color/style.
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
/** Data snippet card — the raw object on the left of every row. */
|
|
46
|
+
function JsonCard({ label, value, width = 300 }: { label: string; value: unknown; width?: number }) {
|
|
47
|
+
return (
|
|
48
|
+
<div style={{ width, flex: '0 0 auto', display: 'flex', flexDirection: 'column' }}>
|
|
49
|
+
<div
|
|
50
|
+
style={{
|
|
51
|
+
fontFamily: 'monospace',
|
|
52
|
+
fontSize: 10,
|
|
53
|
+
textTransform: 'uppercase',
|
|
54
|
+
letterSpacing: 0.5,
|
|
55
|
+
color: '#9ca3af',
|
|
56
|
+
padding: '4px 8px',
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
{label}
|
|
60
|
+
</div>
|
|
61
|
+
<pre
|
|
62
|
+
style={{
|
|
63
|
+
margin: 0,
|
|
64
|
+
padding: 10,
|
|
65
|
+
fontFamily: 'monospace',
|
|
66
|
+
fontSize: 10.5,
|
|
67
|
+
lineHeight: 1.5,
|
|
68
|
+
color: '#d8dee9',
|
|
69
|
+
background: '#14171c',
|
|
70
|
+
borderRadius: 6,
|
|
71
|
+
overflow: 'auto',
|
|
72
|
+
maxHeight: 230,
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
{JSON.stringify(value, null, 2)}
|
|
76
|
+
</pre>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function Row({ children }: { children: React.ReactNode }) {
|
|
82
|
+
return (
|
|
83
|
+
<div
|
|
84
|
+
style={{
|
|
85
|
+
display: 'flex',
|
|
86
|
+
gap: 16,
|
|
87
|
+
alignItems: 'stretch',
|
|
88
|
+
background: '#1b1f27',
|
|
89
|
+
border: '1px solid #2c313a',
|
|
90
|
+
borderRadius: 8,
|
|
91
|
+
padding: 12,
|
|
92
|
+
marginBottom: 12,
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
{children}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function RenderPane({ label, width = 380, children }: { label: string; width?: number; children: React.ReactNode }) {
|
|
101
|
+
return (
|
|
102
|
+
<div style={{ flex: '1 1 auto', display: 'flex', flexDirection: 'column' }}>
|
|
103
|
+
<div
|
|
104
|
+
style={{
|
|
105
|
+
fontFamily: 'monospace',
|
|
106
|
+
fontSize: 10,
|
|
107
|
+
textTransform: 'uppercase',
|
|
108
|
+
letterSpacing: 0.5,
|
|
109
|
+
color: '#9ca3af',
|
|
110
|
+
padding: '4px 8px',
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
{label}
|
|
114
|
+
</div>
|
|
115
|
+
<div
|
|
116
|
+
style={{
|
|
117
|
+
flex: 1,
|
|
118
|
+
display: 'flex',
|
|
119
|
+
alignItems: 'center',
|
|
120
|
+
justifyContent: 'center',
|
|
121
|
+
background: '#10131a',
|
|
122
|
+
borderRadius: 6,
|
|
123
|
+
padding: 16,
|
|
124
|
+
overflow: 'auto',
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{children}
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Minimal NodeProps for rendering the real node component outside a pane. */
|
|
134
|
+
function nodeProps(c: SubsystemComponent): NodeProps<SubsystemGraphNode> {
|
|
135
|
+
return { data: { component: c }, selected: false, width: 230, height: 84 } as unknown as NodeProps<SubsystemGraphNode>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function edgeProps(mechanism: SubsystemEdgeMechanism, path: string): EdgeProps<SubsystemGraphEdge> {
|
|
139
|
+
return { data: { mechanism, elkPath: path }, markerEnd: `url(#mk-${mechanism})` } as unknown as EdgeProps<SubsystemGraphEdge>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Node spotlights — one row per construct/role combination that carries meaning.
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
const corePurl = 'pkg:github/principal-ai/principal-view-core-library';
|
|
146
|
+
|
|
147
|
+
const nodeSpotlights: Array<{ label: string; component: SubsystemComponent; note: string }> = [
|
|
148
|
+
{
|
|
149
|
+
label: 'construct: type_alias — a type alias',
|
|
150
|
+
note: 'the `type` keyword form: `type X = { … }` or a union — anything `=`-assigned',
|
|
151
|
+
component: {
|
|
152
|
+
id: 'alias-status',
|
|
153
|
+
name: 'AnalysisStatus',
|
|
154
|
+
construct: 'type_alias',
|
|
155
|
+
file: 'packages/trail-viewer/src/bun/analysis.ts',
|
|
156
|
+
purl: corePurl,
|
|
157
|
+
symbol: 'AnalysisStatus',
|
|
158
|
+
detail: {
|
|
159
|
+
kind: 'type',
|
|
160
|
+
properties: [
|
|
161
|
+
{ name: 'state', type: "'idle' | 'running' | 'done'" },
|
|
162
|
+
{ name: 'startedAt', type: 'number' },
|
|
163
|
+
],
|
|
164
|
+
usedBy: [],
|
|
165
|
+
implementors: [],
|
|
166
|
+
} satisfies GraphifyComponentDetail,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: 'role: entry on construct: type — contract as entry',
|
|
171
|
+
note: 'same role, different inherited anatomy — entries are topology, not shape',
|
|
172
|
+
component: {
|
|
173
|
+
id: 'ipc-entry',
|
|
174
|
+
name: 'TrailViewerMessages',
|
|
175
|
+
construct: 'interface',
|
|
176
|
+
file: 'packages/trail-viewer/src/shared/contract.ts',
|
|
177
|
+
purl: corePurl,
|
|
178
|
+
symbol: 'TrailViewerMessages',
|
|
179
|
+
role: 'entry',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
label: 'construct: enum — runtime values + a type',
|
|
184
|
+
note: 'the one type-family form that exists at runtime; members render in the drill-down',
|
|
185
|
+
component: {
|
|
186
|
+
id: 'enum-phase',
|
|
187
|
+
name: 'VerificationPhase',
|
|
188
|
+
construct: 'enum',
|
|
189
|
+
file: 'packages/trail-viewer/src/bun/verify.ts',
|
|
190
|
+
purl: corePurl,
|
|
191
|
+
symbol: 'VerificationPhase',
|
|
192
|
+
detail: {
|
|
193
|
+
kind: 'type',
|
|
194
|
+
properties: [{ name: 'idle' }, { name: 'checking' }, { name: 'done' }],
|
|
195
|
+
usedBy: [],
|
|
196
|
+
implementors: [],
|
|
197
|
+
} satisfies GraphifyComponentDetail,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
label: 'construct: function — plain accessor',
|
|
202
|
+
note: 'indigo; the default for anchored behavior',
|
|
203
|
+
component: {
|
|
204
|
+
id: 'create',
|
|
205
|
+
name: 'createSubsystemGraph',
|
|
206
|
+
construct: 'function',
|
|
207
|
+
file: 'packages/trail-viewer/src/bun/subsystem-graph-store.ts',
|
|
208
|
+
purl: corePurl,
|
|
209
|
+
symbol: 'createSubsystemGraph',
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
label: 'role: entry on construct: function — boundary element',
|
|
214
|
+
note: 'orange overrides construct:color; anatomy inherited from the function',
|
|
215
|
+
component: {
|
|
216
|
+
id: 'http-entry',
|
|
217
|
+
name: 'HTTP bridge :3045',
|
|
218
|
+
construct: 'function',
|
|
219
|
+
file: 'packages/trail-viewer/src/bun/http-server.ts',
|
|
220
|
+
purl: corePurl,
|
|
221
|
+
symbol: 'handleSubsystemGraphRequest',
|
|
222
|
+
role: 'entry',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
label: 'construct: class — declaration anatomy',
|
|
227
|
+
note: 'blue; drill-down renders the real class stub with its methods',
|
|
228
|
+
component: {
|
|
229
|
+
id: 'cache',
|
|
230
|
+
name: 'SessionCache',
|
|
231
|
+
construct: 'class',
|
|
232
|
+
file: 'src/session/SessionCache.ts',
|
|
233
|
+
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
234
|
+
symbol: 'SessionCache',
|
|
235
|
+
detail: {
|
|
236
|
+
kind: 'class',
|
|
237
|
+
methods: [{ nodeId: 'm1', name: 'put', parameters: [{ type: 'SessionRecord' }] }],
|
|
238
|
+
properties: [],
|
|
239
|
+
extends: [],
|
|
240
|
+
implements: [],
|
|
241
|
+
instantiations: [],
|
|
242
|
+
references: [],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
label: 'construct: method — a function bound to its class',
|
|
248
|
+
note: 'dotted symbol (SessionCache.put) is the identity; drill-down renders it inside a host-class stub',
|
|
249
|
+
component: {
|
|
250
|
+
id: 'method-put',
|
|
251
|
+
name: 'put',
|
|
252
|
+
construct: 'method',
|
|
253
|
+
file: 'src/session/SessionCache.ts',
|
|
254
|
+
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
255
|
+
symbol: 'SessionCache.put',
|
|
256
|
+
detail: {
|
|
257
|
+
kind: 'method',
|
|
258
|
+
hostClass: 'SessionCache',
|
|
259
|
+
parameters: [{ type: 'SessionRecord' }],
|
|
260
|
+
} satisfies GraphifyComponentDetail,
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
label: 'construct: store — state-block anatomy',
|
|
265
|
+
note: 'green = the store construct:color; drill-down renders declare const state, never a class stub',
|
|
266
|
+
component: {
|
|
267
|
+
id: 'store',
|
|
268
|
+
name: 'Graph Store',
|
|
269
|
+
construct: 'store',
|
|
270
|
+
file: 'packages/trail-viewer/src/bun/subsystem-graph-store.ts',
|
|
271
|
+
purl: corePurl,
|
|
272
|
+
purpose: 'retained state — anchored to a state location',
|
|
273
|
+
detail: { kind: 'store', properties: [{ name: 'ROOT', type: 'string' }, { name: 'INDEX_PATH', type: 'string' }] },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
label: 'construct: external — actor outside every boundary',
|
|
278
|
+
note: 'purple; no process → drawn outside all regions',
|
|
279
|
+
component: {
|
|
280
|
+
id: 'agents',
|
|
281
|
+
name: 'agent clients',
|
|
282
|
+
construct: 'external',
|
|
283
|
+
file: '',
|
|
284
|
+
purl: 'pkg:generic/local-agent-clients',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
label: 'role: service on construct: external — far-side boundary element',
|
|
289
|
+
note: 'colored by its construct (external); identity via purl, no source at all',
|
|
290
|
+
component: {
|
|
291
|
+
id: 'github',
|
|
292
|
+
name: 'api.github.com',
|
|
293
|
+
construct: 'external',
|
|
294
|
+
file: '',
|
|
295
|
+
purl: 'pkg:generic/api.github.com',
|
|
296
|
+
role: 'service',
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
function NodeSpotlightsDemo() {
|
|
303
|
+
const { mode } = useTheme();
|
|
304
|
+
const constructColors = constructColorsFromPierreTheme(resolvePierreSyntaxThemeName(mode));
|
|
305
|
+
const [activeIds, setActiveIds] = useState<Set<string>>(
|
|
306
|
+
() => new Set(nodeSpotlights.map((n) => n.component.id)),
|
|
307
|
+
);
|
|
308
|
+
const toggle = (id: string) =>
|
|
309
|
+
setActiveIds((prev) => {
|
|
310
|
+
const next = new Set(prev);
|
|
311
|
+
if (next.has(id)) {
|
|
312
|
+
next.delete(id);
|
|
313
|
+
} else {
|
|
314
|
+
next.add(id);
|
|
315
|
+
}
|
|
316
|
+
return next;
|
|
317
|
+
});
|
|
318
|
+
const visible = nodeSpotlights.filter((n) => activeIds.has(n.component.id));
|
|
319
|
+
|
|
320
|
+
return (
|
|
321
|
+
<div style={{ padding: 20, overflow: 'auto', height: '100vh', boxSizing: 'border-box', background: '#0f1216' }}>
|
|
322
|
+
<div style={{ fontFamily: 'monospace', fontSize: 13, color: '#d8dee9', marginBottom: 10 }}>
|
|
323
|
+
node spotlights — data (left) → rendered node (right). Hover a node for its role · construct:badge.
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
{/* Toggle bar — chips colored by each node's own construct color */}
|
|
327
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', marginBottom: 16 }}>
|
|
328
|
+
<span style={{ fontFamily: 'monospace', fontSize: 10, textTransform: 'uppercase', letterSpacing: 0.5, color: '#9ca3af' }}>
|
|
329
|
+
show:
|
|
330
|
+
</span>
|
|
331
|
+
{nodeSpotlights.map(({ component }) => {
|
|
332
|
+
const on = activeIds.has(component.id);
|
|
333
|
+
const color = constructColors[component.construct];
|
|
334
|
+
const chip = component.role != null ? `${component.construct} · ${component.role}` : component.construct;
|
|
335
|
+
return (
|
|
336
|
+
<button
|
|
337
|
+
key={component.id}
|
|
338
|
+
type="button"
|
|
339
|
+
onClick={() => toggle(component.id)}
|
|
340
|
+
style={{
|
|
341
|
+
fontFamily: 'monospace',
|
|
342
|
+
fontSize: 11,
|
|
343
|
+
cursor: 'pointer',
|
|
344
|
+
padding: '4px 12px',
|
|
345
|
+
borderRadius: 999,
|
|
346
|
+
border: `1px solid ${on ? color : '#2c313a'}`,
|
|
347
|
+
background: on ? `${color}26` : 'transparent',
|
|
348
|
+
color: on ? '#d8dee9' : '#6b7280',
|
|
349
|
+
}}
|
|
350
|
+
>
|
|
351
|
+
{on ? '● ' : '○ '}
|
|
352
|
+
{chip}
|
|
353
|
+
</button>
|
|
354
|
+
);
|
|
355
|
+
})}
|
|
356
|
+
<button
|
|
357
|
+
type="button"
|
|
358
|
+
onClick={() => setActiveIds(new Set(nodeSpotlights.map((n) => n.component.id)))}
|
|
359
|
+
style={{ fontFamily: 'monospace', fontSize: 11, cursor: 'pointer', padding: '4px 10px', borderRadius: 999, border: '1px solid #2c313a', background: 'transparent', color: '#9ca3af' }}
|
|
360
|
+
>
|
|
361
|
+
all
|
|
362
|
+
</button>
|
|
363
|
+
<button
|
|
364
|
+
type="button"
|
|
365
|
+
onClick={() => setActiveIds(new Set())}
|
|
366
|
+
style={{ fontFamily: 'monospace', fontSize: 11, cursor: 'pointer', padding: '4px 10px', borderRadius: 999, border: '1px solid #2c313a', background: 'transparent', color: '#9ca3af' }}
|
|
367
|
+
>
|
|
368
|
+
none
|
|
369
|
+
</button>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
{visible.length === 0 && (
|
|
373
|
+
<div style={{ fontFamily: 'monospace', fontSize: 12, color: '#6b7280' }}>
|
|
374
|
+
nothing selected — toggle constructs on above to compare them
|
|
375
|
+
</div>
|
|
376
|
+
)}
|
|
377
|
+
{visible.map(({ label, component, note }) => (
|
|
378
|
+
<div key={component.id}>
|
|
379
|
+
<div style={{ fontFamily: 'monospace', fontSize: 11, color: '#6b7280', margin: '10px 2px 6px' }}>
|
|
380
|
+
{label} — {note}
|
|
381
|
+
</div>
|
|
382
|
+
<Row>
|
|
383
|
+
<JsonCard label="the data — SubsystemComponent" value={component} />
|
|
384
|
+
<RenderPane label="the rendering — SubsystemComponentNode">
|
|
385
|
+
<SubsystemComponentNode {...nodeProps(component)} />
|
|
386
|
+
</RenderPane>
|
|
387
|
+
</Row>
|
|
388
|
+
</div>
|
|
389
|
+
))}
|
|
390
|
+
</div>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export const NodeSpotlights: Story = {
|
|
395
|
+
render: () => <NodeSpotlightsDemo />,
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
// Mechanism spotlights — the edge vocabulary with its real colors/styles.
|
|
400
|
+
// ---------------------------------------------------------------------------
|
|
401
|
+
const mechanismRows: Array<{ mechanism: SubsystemEdgeMechanism; from: string; to: string; note: string }> = [
|
|
402
|
+
{ mechanism: 'calls', from: 'http-entry', to: 'create', note: 'dependency — initiator → target' },
|
|
403
|
+
{ mechanism: 'writes', from: 'create', to: 'Graph Store', note: 'state access — deep green, target retains the value' },
|
|
404
|
+
{ mechanism: 'reads', from: 'get', to: 'Graph Store', note: 'state access — sky, arrow points initiator → state' },
|
|
405
|
+
{ mechanism: 'watches', from: 'watcher', to: 'Graph Store', note: 'dashed gray — observes, owns nothing' },
|
|
406
|
+
{ mechanism: 'produces', from: 'Graph Store', to: 'broadcast', note: 'flow — the store\u2019s change stream' },
|
|
407
|
+
{ mechanism: 'feeds', from: 'broadcast', to: 'rpc-subscribers', note: 'flow — payload consumed, not retained' },
|
|
408
|
+
{ mechanism: 'registers-into', from: 'change-listener', to: 'broadcast', note: 'dashed orange — control inverts' },
|
|
409
|
+
];
|
|
410
|
+
|
|
411
|
+
function MechanismSpotlightsDemo() {
|
|
412
|
+
return (
|
|
413
|
+
<div style={{ padding: 20, overflow: 'auto', height: '100vh', boxSizing: 'border-box', background: '#0f1216' }}>
|
|
414
|
+
<SpotlightsMarkerDefs />
|
|
415
|
+
<div style={{ fontFamily: 'monospace', fontSize: 13, color: '#d8dee9', marginBottom: 14 }}>
|
|
416
|
+
mechanism spotlights — the real SubsystemEdge renderer with a sample path per mechanism.
|
|
417
|
+
</div>
|
|
418
|
+
{mechanismRows.map(({ mechanism, from, to, note }) => (
|
|
419
|
+
<div key={mechanism}>
|
|
420
|
+
<div style={{ fontFamily: 'monospace', fontSize: 11, color: '#6b7280', margin: '10px 2px 6px' }}>{note}</div>
|
|
421
|
+
<Row>
|
|
422
|
+
<JsonCard
|
|
423
|
+
label="the data — SubsystemComponentEdge"
|
|
424
|
+
value={{ id: `e-${mechanism}`, from, to, mechanism }}
|
|
425
|
+
width={340}
|
|
426
|
+
/>
|
|
427
|
+
<RenderPane label={`the rendering — ${mechanism}`} width={300}>
|
|
428
|
+
<div style={{ width: 280 }}>
|
|
429
|
+
<svg width={280} height={40}>
|
|
430
|
+
<SubsystemEdge {...edgeProps(mechanism, 'M 12 20 C 90 20, 190 20, 268 20')} />
|
|
431
|
+
</svg>
|
|
432
|
+
<div style={{ fontFamily: 'monospace', fontSize: 10, color: '#9ca3af', textAlign: 'center' }}>
|
|
433
|
+
{from} ──{mechanism}──▶ {to}
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
</RenderPane>
|
|
437
|
+
</Row>
|
|
438
|
+
</div>
|
|
439
|
+
))}
|
|
440
|
+
</div>
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export const MechanismSpotlights: Story = {
|
|
445
|
+
render: () => <MechanismSpotlightsDemo />,
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// ---------------------------------------------------------------------------
|
|
449
|
+
// Anatomy spotlights — the drill-down panel per detail construct: what clicking a
|
|
450
|
+
// node opens. store renders state declarations; class/function render their
|
|
451
|
+
// real signatures.
|
|
452
|
+
// ---------------------------------------------------------------------------
|
|
453
|
+
const anatomyComponents: Array<{ label: string; component: SubsystemComponent; note: string }> = [
|
|
454
|
+
{
|
|
455
|
+
label: 'store detail → state block',
|
|
456
|
+
note: 'declare const lines — honest to module-level state; no class stub, no methods',
|
|
457
|
+
component: {
|
|
458
|
+
id: 'store',
|
|
459
|
+
name: 'Graph Store',
|
|
460
|
+
construct: 'store',
|
|
461
|
+
file: 'packages/trail-viewer/src/bun/subsystem-graph-store.ts',
|
|
462
|
+
purl: corePurl,
|
|
463
|
+
detail: {
|
|
464
|
+
kind: 'store',
|
|
465
|
+
properties: [
|
|
466
|
+
{ name: 'ROOT', type: 'string' },
|
|
467
|
+
{ name: 'INDEX_PATH', type: 'string' },
|
|
468
|
+
{ name: 'changeListener', type: 'SubsystemGraphChangeListener | null' },
|
|
469
|
+
{ name: 'dirWatcher', type: 'FSWatcher | null' },
|
|
470
|
+
],
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
label: 'class detail → class stub',
|
|
476
|
+
note: 'the verifiable access mechanism — methods with typed params + returns',
|
|
477
|
+
component: {
|
|
478
|
+
id: 'cache',
|
|
479
|
+
name: 'SessionCache',
|
|
480
|
+
construct: 'class',
|
|
481
|
+
file: 'src/session/SessionCache.ts',
|
|
482
|
+
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
483
|
+
symbol: 'SessionCache',
|
|
484
|
+
detail: {
|
|
485
|
+
kind: 'class',
|
|
486
|
+
methods: [
|
|
487
|
+
{ nodeId: 'cm1', name: 'put', parameters: [{ type: 'SessionRecord' }] },
|
|
488
|
+
{ nodeId: 'cm2', name: 'get', parameters: [{ type: 'string' }], returnType: 'SessionRecord | null' },
|
|
489
|
+
],
|
|
490
|
+
properties: [],
|
|
491
|
+
extends: [],
|
|
492
|
+
implements: [],
|
|
493
|
+
instantiations: [],
|
|
494
|
+
references: [],
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
label: 'function detail → signature',
|
|
500
|
+
note: 'params + return type, callers/callees intentionally not rendered (edges carry them)',
|
|
501
|
+
component: {
|
|
502
|
+
id: 'get',
|
|
503
|
+
name: 'getSubsystemGraph',
|
|
504
|
+
construct: 'function',
|
|
505
|
+
file: 'packages/trail-viewer/src/bun/subsystem-graph-store.ts',
|
|
506
|
+
purl: corePurl,
|
|
507
|
+
symbol: 'getSubsystemGraph',
|
|
508
|
+
detail: {
|
|
509
|
+
kind: 'function',
|
|
510
|
+
parameters: [{ name: 'graphId', type: 'string' }],
|
|
511
|
+
returnType: 'Promise<StoredSubsystemGraph | null>',
|
|
512
|
+
callers: [],
|
|
513
|
+
callees: [],
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
label: 'type detail → interface fields',
|
|
519
|
+
note: 'the IPC contract as an entry: anatomy inherited from the type',
|
|
520
|
+
component: {
|
|
521
|
+
id: 'ipc-entry',
|
|
522
|
+
name: 'TrailViewerMessages',
|
|
523
|
+
construct: 'interface',
|
|
524
|
+
file: 'packages/trail-viewer/src/shared/contract.ts',
|
|
525
|
+
purl: corePurl,
|
|
526
|
+
symbol: 'TrailViewerMessages',
|
|
527
|
+
role: 'entry',
|
|
528
|
+
detail: {
|
|
529
|
+
kind: 'type',
|
|
530
|
+
properties: [
|
|
531
|
+
{ name: 'subsystemGraphChanged', type: 'push' },
|
|
532
|
+
{ name: 'graphifyChanged', type: 'push' },
|
|
533
|
+
],
|
|
534
|
+
usedBy: [],
|
|
535
|
+
implementors: [],
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
label: 'method detail → method in host-class stub',
|
|
541
|
+
note: 'the class is context, the method is the node — same anatomy a standalone function gets, plus the owning class',
|
|
542
|
+
component: {
|
|
543
|
+
id: 'anatomy-method',
|
|
544
|
+
name: 'put',
|
|
545
|
+
construct: 'method',
|
|
546
|
+
file: 'src/session/SessionCache.ts',
|
|
547
|
+
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
548
|
+
symbol: 'SessionCache.put',
|
|
549
|
+
detail: {
|
|
550
|
+
kind: 'method',
|
|
551
|
+
hostClass: 'SessionCache',
|
|
552
|
+
parameters: [{ name: 'record', type: 'SessionRecord' }],
|
|
553
|
+
returnType: 'void',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
label: 'type_alias detail → braced alias',
|
|
559
|
+
note: 'the alias renders as `type X = { … }` — the honest keyword form',
|
|
560
|
+
component: {
|
|
561
|
+
id: 'anatomy-alias',
|
|
562
|
+
name: 'AnalysisStatus',
|
|
563
|
+
construct: 'type_alias',
|
|
564
|
+
file: 'packages/trail-viewer/src/bun/analysis.ts',
|
|
565
|
+
purl: corePurl,
|
|
566
|
+
symbol: 'AnalysisStatus',
|
|
567
|
+
detail: {
|
|
568
|
+
kind: 'type',
|
|
569
|
+
properties: [{ name: 'state', type: "'idle' | 'running'" }],
|
|
570
|
+
usedBy: [],
|
|
571
|
+
implementors: [],
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
label: 'enum detail → enum declaration',
|
|
577
|
+
note: 'members render inline — the runtime type',
|
|
578
|
+
component: {
|
|
579
|
+
id: 'anatomy-enum',
|
|
580
|
+
name: 'VerificationPhase',
|
|
581
|
+
construct: 'enum',
|
|
582
|
+
file: 'packages/trail-viewer/src/bun/verify.ts',
|
|
583
|
+
purl: corePurl,
|
|
584
|
+
symbol: 'VerificationPhase',
|
|
585
|
+
detail: {
|
|
586
|
+
kind: 'type',
|
|
587
|
+
properties: [{ name: 'idle' }, { name: 'checking' }, { name: 'done' }],
|
|
588
|
+
usedBy: [],
|
|
589
|
+
implementors: [],
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
];
|
|
594
|
+
|
|
595
|
+
function AnatomySpotlightsDemo() {
|
|
596
|
+
return (
|
|
597
|
+
<div style={{ padding: 20, overflow: 'auto', height: '100vh', boxSizing: 'border-box', background: '#0f1216' }}>
|
|
598
|
+
<div style={{ fontFamily: 'monospace', fontSize: 13, color: '#d8dee9', marginBottom: 14 }}>
|
|
599
|
+
anatomy spotlights — data (left) → the drill-down panel you get on click (right).
|
|
600
|
+
</div>
|
|
601
|
+
{anatomyComponents.map(({ label, component, note }) => (
|
|
602
|
+
<div key={component.id}>
|
|
603
|
+
<div style={{ fontFamily: 'monospace', fontSize: 11, color: '#6b7280', margin: '10px 2px 6px' }}>
|
|
604
|
+
{label} — {note}
|
|
605
|
+
</div>
|
|
606
|
+
<Row>
|
|
607
|
+
<JsonCard label="the data — component.detail" value={component.detail} width={320} />
|
|
608
|
+
<RenderPane label="the rendering — ComponentDeclaration">
|
|
609
|
+
<div style={{ width: 360 }}>
|
|
610
|
+
<ComponentDeclaration component={component} />
|
|
611
|
+
</div>
|
|
612
|
+
</RenderPane>
|
|
613
|
+
</Row>
|
|
614
|
+
</div>
|
|
615
|
+
))}
|
|
616
|
+
</div>
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
export const AnatomySpotlights: Story = {
|
|
621
|
+
render: () => <AnatomySpotlightsDemo />,
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// Shared SVG marker defs — the arrowheads the spotlit edges reference by url(#…).
|
|
625
|
+
function SpotlightsMarkerDefs() {
|
|
626
|
+
return (
|
|
627
|
+
<svg width={0} height={0} style={{ position: 'absolute' }}>
|
|
628
|
+
<defs>
|
|
629
|
+
{Object.entries(MECHANISM_COLOR).map(([mechanism, color]) => (
|
|
630
|
+
<marker
|
|
631
|
+
key={mechanism}
|
|
632
|
+
id={`mk-${mechanism}`}
|
|
633
|
+
viewBox="0 0 10 10"
|
|
634
|
+
refX="9"
|
|
635
|
+
refY="5"
|
|
636
|
+
markerWidth="6"
|
|
637
|
+
markerHeight="6"
|
|
638
|
+
orient="auto-start-reverse"
|
|
639
|
+
>
|
|
640
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill={color} />
|
|
641
|
+
</marker>
|
|
642
|
+
))}
|
|
643
|
+
</defs>
|
|
644
|
+
</svg>
|
|
645
|
+
);
|
|
646
|
+
}
|