@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
|
@@ -1,1225 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import '@xyflow/react/dist/style.css';
|
|
3
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
-
import { ThemeProvider, defaultTheme, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
5
|
-
import { SubsystemComponentGraph } from '../subsystem/SubsystemComponentGraph';
|
|
6
|
-
import { PierreFileView, PierreSnippetView } from '../pierre';
|
|
7
|
-
import type { SubsystemComponent, SubsystemComponentEdge } from '../subsystem/model';
|
|
8
|
-
import type { SubsystemOpenFileOptions } from '../subsystem/declarationRef';
|
|
9
|
-
import type { GraphifyComponentDetail } from '../graphify';
|
|
10
|
-
import componentDeclarationSource from '../subsystem/ComponentDeclaration.tsx?raw';
|
|
11
|
-
import resolveSource from '../graphify/resolve.ts?raw';
|
|
12
|
-
const meta = {
|
|
13
|
-
title: 'Subsystem/Component Graph',
|
|
14
|
-
component: SubsystemComponentGraph,
|
|
15
|
-
parameters: {
|
|
16
|
-
layout: 'fullscreen',
|
|
17
|
-
},
|
|
18
|
-
tags: ['autodocs'],
|
|
19
|
-
decorators: [
|
|
20
|
-
(Story) => (
|
|
21
|
-
<ThemeProvider theme={defaultEditorTheme}>
|
|
22
|
-
<Story />
|
|
23
|
-
</ThemeProvider>
|
|
24
|
-
),
|
|
25
|
-
],
|
|
26
|
-
} satisfies Meta<typeof SubsystemComponentGraph>;
|
|
27
|
-
|
|
28
|
-
export default meta;
|
|
29
|
-
type Story = StoryObj<typeof meta>;
|
|
30
|
-
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
// Build a subsystem graph from a compact spec - helpers
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
function components(
|
|
35
|
-
spec: Array<[id: string, name: string, kind: SubsystemComponent['kind'], file: string, purl: string, purpose?: string, symbol?: string, detail?: GraphifyComponentDetail]>,
|
|
36
|
-
): SubsystemComponent[] {
|
|
37
|
-
return spec.map(([id, name, kind, file, purl, purpose, symbol, detail]) => ({
|
|
38
|
-
id,
|
|
39
|
-
name,
|
|
40
|
-
kind,
|
|
41
|
-
file,
|
|
42
|
-
purl,
|
|
43
|
-
purpose,
|
|
44
|
-
symbol,
|
|
45
|
-
detail,
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function edges(
|
|
50
|
-
spec: Array<[from: string, to: string, mechanism: SubsystemComponentEdge['mechanism'], refs?: string[]]>,
|
|
51
|
-
): SubsystemComponentEdge[] {
|
|
52
|
-
return spec.map(([from, to, mechanism, refs], i) => ({
|
|
53
|
-
id: `e${i}`,
|
|
54
|
-
from,
|
|
55
|
-
to,
|
|
56
|
-
mechanism,
|
|
57
|
-
refs,
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// ---------------------------------------------------------------------------
|
|
62
|
-
// Minimal: two nodes, one edge — the simplest possible label layout test.
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
const twoNodeComponents = components([
|
|
65
|
-
['src', 'TranscriptParser', 'class', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records'],
|
|
66
|
-
['dst', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes sessions into events'],
|
|
67
|
-
]);
|
|
68
|
-
|
|
69
|
-
const twoNodeEdges = edges([
|
|
70
|
-
['src', 'dst', 'imports'],
|
|
71
|
-
]);
|
|
72
|
-
|
|
73
|
-
function TwoNodeDemo({ showEdgeLabels = true }: { showEdgeLabels?: boolean }) {
|
|
74
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
75
|
-
const [selectedEdge, setSelectedEdge] = useState<SubsystemComponentEdge | null>(null);
|
|
76
|
-
return (
|
|
77
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
78
|
-
<SubsystemComponentGraph
|
|
79
|
-
components={twoNodeComponents}
|
|
80
|
-
edges={twoNodeEdges}
|
|
81
|
-
onSelect={(id) => setSelected(id)}
|
|
82
|
-
onEdgeSelect={(e) => setSelectedEdge(e)}
|
|
83
|
-
showEdgeLabels={showEdgeLabels}
|
|
84
|
-
/>
|
|
85
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
86
|
-
{selectedEdge
|
|
87
|
-
? `edge: ${selectedEdge.from} --${selectedEdge.mechanism}--> ${selectedEdge.to}`
|
|
88
|
-
: selected
|
|
89
|
-
? `selected: ${selected}`
|
|
90
|
-
: 'click a component or edge to select it'}
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export const TwoNodeSingleEdge: Story = {
|
|
97
|
-
render: () => <TwoNodeDemo />,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export const TwoNodeNoLabels: Story = {
|
|
101
|
-
render: () => <TwoNodeDemo showEdgeLabels={false} />,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
// Playground: control the number of nodes in left and right layers.
|
|
106
|
-
// All left nodes connect to all right nodes (fan-in / fan-out).
|
|
107
|
-
// ---------------------------------------------------------------------------
|
|
108
|
-
function PlaygroundDemo({ leftCount, rightCount, showEdgeLabels }: { leftCount: number; rightCount: number; showEdgeLabels: boolean }) {
|
|
109
|
-
const comps: SubsystemComponent[] = [];
|
|
110
|
-
const edgeList: SubsystemComponentEdge[] = [];
|
|
111
|
-
|
|
112
|
-
for (let i = 0; i < leftCount; i++) {
|
|
113
|
-
comps.push({
|
|
114
|
-
id: `l${i}`,
|
|
115
|
-
name: `Left${i}`,
|
|
116
|
-
kind: 'class',
|
|
117
|
-
file: `left${i}.ts`,
|
|
118
|
-
purl: 'pkg:github/principal-ai/playground',
|
|
119
|
-
purpose: `left layer node ${i}`,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
for (let i = 0; i < rightCount; i++) {
|
|
123
|
-
comps.push({
|
|
124
|
-
id: `r${i}`,
|
|
125
|
-
name: `Right${i}`,
|
|
126
|
-
kind: 'class',
|
|
127
|
-
file: `right${i}.ts`,
|
|
128
|
-
purl: 'pkg:github/principal-ai/playground',
|
|
129
|
-
purpose: `right layer node ${i}`,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
let ei = 0;
|
|
134
|
-
for (let i = 0; i < leftCount; i++) {
|
|
135
|
-
for (let j = 0; j < rightCount; j++) {
|
|
136
|
-
edgeList.push({ id: `e${ei++}`, from: `l${i}`, to: `r${j}`, mechanism: 'imports' });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
142
|
-
<SubsystemComponentGraph components={comps} edges={edgeList} showEdgeLabels={showEdgeLabels} />
|
|
143
|
-
</div>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export const Playground: Story = {
|
|
148
|
-
render: (args) => <PlaygroundDemo {...args} />,
|
|
149
|
-
args: {
|
|
150
|
-
leftCount: 1,
|
|
151
|
-
rightCount: 1,
|
|
152
|
-
showEdgeLabels: true,
|
|
153
|
-
},
|
|
154
|
-
argTypes: {
|
|
155
|
-
leftCount: { control: { type: 'number', min: 0, max: 6, step: 1 } },
|
|
156
|
-
rightCount: { control: { type: 'number', min: 0, max: 6, step: 1 } },
|
|
157
|
-
showEdgeLabels: { control: 'boolean' },
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// ---------------------------------------------------------------------------
|
|
162
|
-
// Primary: opencode V2 event reader subsystem (agent-monitoring) + consumers
|
|
163
|
-
// ---------------------------------------------------------------------------
|
|
164
|
-
const readerDetail: GraphifyComponentDetail = {
|
|
165
|
-
kind: 'class',
|
|
166
|
-
methods: [
|
|
167
|
-
{ nodeId: 'm1', name: 'normalize', returnType: 'SessionEvent[]' },
|
|
168
|
-
{ nodeId: 'm2', name: 'readSession', parameters: [{ type: 'string' }], returnType: 'SessionRecord' },
|
|
169
|
-
{ nodeId: 'm3', name: 'toUniversalEvents', returnType: 'UniversalEvent[]' },
|
|
170
|
-
],
|
|
171
|
-
properties: [{ name: 'sessionId', type: 'string' }],
|
|
172
|
-
extends: [],
|
|
173
|
-
implements: ['SessionReaderLike'],
|
|
174
|
-
instantiations: [{ nodeId: 'caller1', name: 'capture-session' }],
|
|
175
|
-
references: [{ nodeId: 'ref1', name: 'supported-agents', context: 'type' }],
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const v2ReaderComponents = components([
|
|
179
|
-
['capture', 'capture script', 'function', 'scripts/capture-session.ts', 'pkg:github/principal-ai/agent-monitoring', 'captures a real session for fixtures'],
|
|
180
|
-
['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards'],
|
|
181
|
-
['paths', 'paths', 'module', 'paths.ts', 'pkg:github/principal-ai/agent-monitoring', 'extracts tool names + file paths'],
|
|
182
|
-
['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader.normalize', readerDetail],
|
|
183
|
-
['registry', 'supported-agents', 'module', 'supported-agents.ts', 'pkg:github/principal-ai/agent-monitoring', 'registry of supported agents (the shared seam)', 'registerAgent'],
|
|
184
|
-
]);
|
|
185
|
-
|
|
186
|
-
const v2ReaderEdges = edges([
|
|
187
|
-
['transcript', 'reader', 'imports'],
|
|
188
|
-
['paths', 'reader', 'imports'],
|
|
189
|
-
['capture', 'reader', 'calls'],
|
|
190
|
-
['reader', 'registry', 'registers-into', ['supported-agents.ts']],
|
|
191
|
-
// Consumer packages - cross-package edges leave the subgraph
|
|
192
|
-
['reader', 'trail-viewer-host', 'imports'],
|
|
193
|
-
['reader', 'core-sessions', 'imports'],
|
|
194
|
-
['reader', 'cli-session', 'imports'],
|
|
195
|
-
]);
|
|
196
|
-
|
|
197
|
-
function V2ReaderDemo() {
|
|
198
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
199
|
-
const [selectedEdge, setSelectedEdge] = useState<SubsystemComponentEdge | null>(null);
|
|
200
|
-
return (
|
|
201
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
202
|
-
<SubsystemComponentGraph
|
|
203
|
-
components={v2ReaderComponents}
|
|
204
|
-
edges={v2ReaderEdges}
|
|
205
|
-
onSelect={(id) => setSelected(id)}
|
|
206
|
-
onEdgeSelect={(e) => setSelectedEdge(e)}
|
|
207
|
-
/>
|
|
208
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
209
|
-
{selectedEdge
|
|
210
|
-
? `edge: ${selectedEdge.from} --${selectedEdge.mechanism}--> ${selectedEdge.to}${selectedEdge.refs?.length ? ` [refs: ${selectedEdge.refs.join(', ')}]` : ''}`
|
|
211
|
-
: selected
|
|
212
|
-
? `selected: ${selected}`
|
|
213
|
-
: 'click a component or edge to select it'}
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export const V2ReaderSubsystem: Story = {
|
|
220
|
-
render: () => <V2ReaderDemo />,
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
// ---------------------------------------------------------------------------
|
|
224
|
-
// Empty state
|
|
225
|
-
// ---------------------------------------------------------------------------
|
|
226
|
-
export const Empty: Story = {
|
|
227
|
-
render: () => (
|
|
228
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
229
|
-
<SubsystemComponentGraph components={[]} edges={[]} />
|
|
230
|
-
</div>
|
|
231
|
-
),
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
// ---------------------------------------------------------------------------
|
|
235
|
-
// Single package (no consumers) - the investigate-and-pin pattern.
|
|
236
|
-
// Conveys the idea via LAYERS: readers (input) → accumulator (processing).
|
|
237
|
-
// ---------------------------------------------------------------------------
|
|
238
|
-
const investigateOnlyComponents: SubsystemComponent[] = [
|
|
239
|
-
{
|
|
240
|
-
id: 'v1',
|
|
241
|
-
name: 'V1EventBridgeProcessor',
|
|
242
|
-
kind: 'class',
|
|
243
|
-
file: 'src/event-processing/V1EventBridge.ts',
|
|
244
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
245
|
-
purpose: 'normalizes V1 DB rows into universal events',
|
|
246
|
-
symbol: 'V1EventBridgeProcessor',
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
id: 'v2',
|
|
250
|
-
name: 'V2EventBridgeProcessor',
|
|
251
|
-
kind: 'class',
|
|
252
|
-
file: 'src/event-processing/V2EventBridge.ts',
|
|
253
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
254
|
-
purpose: 'normalizes V2 durable events into universal events',
|
|
255
|
-
symbol: 'V2EventBridgeProcessor',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
id: 'input',
|
|
259
|
-
name: 'RepoNormalizedUniversalAgentSessionEvent',
|
|
260
|
-
kind: 'type',
|
|
261
|
-
file: 'types/RepoNormalizedUniversalAgentSessionEvent.ts',
|
|
262
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
263
|
-
purpose: 'the subsystem\u2019s input type — a repo-normalized universal event the readers produce and the accumulator consumes',
|
|
264
|
-
symbol: 'RepoNormalizedUniversalAgentSessionEvent',
|
|
265
|
-
detail: {
|
|
266
|
-
kind: 'type',
|
|
267
|
-
properties: [
|
|
268
|
-
{ name: 'eventType', type: 'NormalizedEventType' },
|
|
269
|
-
{ name: 'sessionId', type: 'string' },
|
|
270
|
-
{ name: 'timestamp', type: 'number' },
|
|
271
|
-
],
|
|
272
|
-
usedBy: [{ nodeId: 'acc', name: 'accumulateToAgentSessionEvents', context: 'parameter_type' }],
|
|
273
|
-
implementors: [],
|
|
274
|
-
} satisfies GraphifyComponentDetail,
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
id: 'acc',
|
|
278
|
-
name: 'accumulateToAgentSessionEvents',
|
|
279
|
-
kind: 'function',
|
|
280
|
-
file: 'src/event-processing/accumulator.ts',
|
|
281
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
282
|
-
purpose: 'accumulates normalized events into agent session events',
|
|
283
|
-
symbol: 'accumulateToAgentSessionEvents',
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
id: 'out',
|
|
287
|
-
name: 'AgentSessionEvent',
|
|
288
|
-
kind: 'type',
|
|
289
|
-
file: 'src/event-processing/accumulator.ts',
|
|
290
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
291
|
-
purpose: 'the subsystem\u2019s output type — an accumulated agent-session event',
|
|
292
|
-
symbol: 'AgentSessionEvent',
|
|
293
|
-
detail: {
|
|
294
|
-
kind: 'type',
|
|
295
|
-
properties: [
|
|
296
|
-
{ name: 'sessionName', type: 'string' },
|
|
297
|
-
{ name: 'operation', type: 'AgentSessionEventOperation' },
|
|
298
|
-
{ name: 'description', type: 'string' },
|
|
299
|
-
],
|
|
300
|
-
usedBy: [{ nodeId: 'acc', name: 'accumulateToAgentSessionEvents', context: 'return_type' }],
|
|
301
|
-
implementors: [],
|
|
302
|
-
} satisfies GraphifyComponentDetail,
|
|
303
|
-
},
|
|
304
|
-
];
|
|
305
|
-
|
|
306
|
-
const investigateOnlyEdges = edges([
|
|
307
|
-
// Concept-level data flow — the LLM's semantic intent.
|
|
308
|
-
['v1', 'input', 'produces'],
|
|
309
|
-
['v2', 'input', 'produces'],
|
|
310
|
-
['input', 'acc', 'feeds'],
|
|
311
|
-
['acc', 'out', 'produces'],
|
|
312
|
-
]);
|
|
313
|
-
|
|
314
|
-
export const InvestigateOnly: Story = {
|
|
315
|
-
render: () => (
|
|
316
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
317
|
-
<SubsystemComponentGraph components={investigateOnlyComponents} edges={investigateOnlyEdges} />
|
|
318
|
-
</div>
|
|
319
|
-
),
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
/** Same pipeline with a narrower `maxNodeWidth` (140) — long names wrap. */
|
|
323
|
-
export const NarrowMaxWidth: Story = {
|
|
324
|
-
render: () => (
|
|
325
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
326
|
-
<SubsystemComponentGraph
|
|
327
|
-
components={investigateOnlyComponents}
|
|
328
|
-
edges={investigateOnlyEdges}
|
|
329
|
-
maxNodeWidth={140}
|
|
330
|
-
/>
|
|
331
|
-
</div>
|
|
332
|
-
),
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
// ---------------------------------------------------------------------------
|
|
336
|
-
// Naming-convention wrap check — one node per common symbol convention.
|
|
337
|
-
// ---------------------------------------------------------------------------
|
|
338
|
-
const namingConventionComponents: SubsystemComponent[] = [
|
|
339
|
-
{
|
|
340
|
-
id: 'camel',
|
|
341
|
-
name: 'accumulateToAgentSessionEvents',
|
|
342
|
-
kind: 'function',
|
|
343
|
-
file: 'src/event-processing/accumulator.ts',
|
|
344
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
345
|
-
symbol: 'accumulateToAgentSessionEvents',
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
id: 'snake',
|
|
349
|
-
name: 'repo_normalized_universal_event',
|
|
350
|
-
kind: 'type',
|
|
351
|
-
file: 'src/event-processing/repo_normalized.ts',
|
|
352
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
353
|
-
symbol: 'repo_normalized_universal_event',
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
id: 'pascal',
|
|
357
|
-
name: 'RepoNormalizedUniversalAgentSessionEvent',
|
|
358
|
-
kind: 'class',
|
|
359
|
-
file: 'src/event-processing/RepoNormalized.ts',
|
|
360
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
361
|
-
symbol: 'RepoNormalizedUniversalAgentSessionEvent',
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
id: 'acronym',
|
|
365
|
-
name: 'ProcessSSEStreamForEventToken',
|
|
366
|
-
kind: 'function',
|
|
367
|
-
file: 'src/event-processing/sse.ts',
|
|
368
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
369
|
-
symbol: 'ProcessSSEStreamForEventToken',
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
id: 'method',
|
|
373
|
-
name: 'normalize',
|
|
374
|
-
kind: 'function',
|
|
375
|
-
file: 'src/session/SessionReader.ts',
|
|
376
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
377
|
-
symbol: 'SessionReader.normalize',
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
id: 'pkg',
|
|
381
|
-
name: 'trail-viewer',
|
|
382
|
-
kind: 'external',
|
|
383
|
-
file: '',
|
|
384
|
-
purl: 'pkg:npm/@principal-ai/trail-viewer',
|
|
385
|
-
symbol: '',
|
|
386
|
-
},
|
|
387
|
-
];
|
|
388
|
-
|
|
389
|
-
const namingConventionEdges: SubsystemComponentEdge[] = [];
|
|
390
|
-
|
|
391
|
-
/** Nodes with compact `maxNodeWidth` so the different conventions visibly wrap
|
|
392
|
-
* at their word boundaries (camelCase, snake_case, PascalCase, acronyms). */
|
|
393
|
-
export const NamingConventions: Story = {
|
|
394
|
-
render: () => (
|
|
395
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
396
|
-
<SubsystemComponentGraph
|
|
397
|
-
components={namingConventionComponents}
|
|
398
|
-
edges={namingConventionEdges}
|
|
399
|
-
maxNodeWidth={180}
|
|
400
|
-
/>
|
|
401
|
-
</div>
|
|
402
|
-
),
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
// ---------------------------------------------------------------------------
|
|
406
|
-
// One node per GraphifyComponentDetail kind — what each looks like + drills down
|
|
407
|
-
// ---------------------------------------------------------------------------
|
|
408
|
-
const detailKindComponents: SubsystemComponent[] = [
|
|
409
|
-
{
|
|
410
|
-
id: 'detail-class',
|
|
411
|
-
name: 'SessionReader',
|
|
412
|
-
kind: 'class',
|
|
413
|
-
file: 'src/session/SessionReader.ts',
|
|
414
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
415
|
-
purpose: 'class-like: owns outgoing method edges',
|
|
416
|
-
symbol: '',
|
|
417
|
-
detail: readerDetail,
|
|
418
|
-
},
|
|
419
|
-
{
|
|
420
|
-
id: 'detail-method',
|
|
421
|
-
name: 'normalize',
|
|
422
|
-
kind: 'function',
|
|
423
|
-
file: 'src/session/SessionReader.ts',
|
|
424
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
425
|
-
purpose: 'a class method — the specific thing this session focused on',
|
|
426
|
-
symbol: 'SessionReader.normalize',
|
|
427
|
-
detail: {
|
|
428
|
-
kind: 'function',
|
|
429
|
-
parameters: [{ name: 'session', type: 'SessionRecord' }],
|
|
430
|
-
returnType: 'SessionEvent[]',
|
|
431
|
-
callers: [{ nodeId: 'c1', name: 'capture-session', source_location: 'L120' }],
|
|
432
|
-
callees: [{ nodeId: 'c2', name: 'toUniversalEvents', source_location: 'L64' }],
|
|
433
|
-
} satisfies GraphifyComponentDetail,
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
id: 'detail-fn',
|
|
437
|
-
name: 'normalizeSession',
|
|
438
|
-
kind: 'function',
|
|
439
|
-
file: 'src/event-processing/normalize.ts',
|
|
440
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
441
|
-
purpose: 'function-like: label ends () with no method edges',
|
|
442
|
-
symbol: 'normalizeSession',
|
|
443
|
-
detail: {
|
|
444
|
-
kind: 'function',
|
|
445
|
-
parameters: [
|
|
446
|
-
{ name: 'session', type: 'SessionRecord' },
|
|
447
|
-
{ name: 'limit', type: 'number' },
|
|
448
|
-
],
|
|
449
|
-
returnType: 'SessionEvent[]',
|
|
450
|
-
callers: [{ nodeId: 'c1', name: 'SessionReader.normalize', source_location: 'L120' }],
|
|
451
|
-
callees: [{ nodeId: 'c2', name: 'toUniversalEvents', source_location: 'L64' }],
|
|
452
|
-
} satisfies GraphifyComponentDetail,
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
id: 'detail-fn-rich',
|
|
456
|
-
name: 'mergeSessions',
|
|
457
|
-
kind: 'function',
|
|
458
|
-
file: 'src/session/merge.ts',
|
|
459
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
460
|
-
purpose: 'multi-param signature — named, positional (graphify captures types only), union types, generic return',
|
|
461
|
-
symbol: 'mergeSessions',
|
|
462
|
-
detail: {
|
|
463
|
-
kind: 'function',
|
|
464
|
-
parameters: [
|
|
465
|
-
{ name: 'sessions', type: 'SessionRecord[]' },
|
|
466
|
-
{ type: 'MergeOptions' },
|
|
467
|
-
{ name: 'strategy', type: `'append' | 'replace' | 'skip'` },
|
|
468
|
-
{ name: 'onConflict', type: '((a: SessionRecord, b: SessionRecord) => SessionRecord)' },
|
|
469
|
-
],
|
|
470
|
-
returnType: 'Promise<Map<string, SessionEvent[]>>',
|
|
471
|
-
callers: [
|
|
472
|
-
{ nodeId: 'c1', name: 'capture-session', source_location: 'L88' },
|
|
473
|
-
{ nodeId: 'c3', name: 'backfill', source_location: 'L210' },
|
|
474
|
-
],
|
|
475
|
-
callees: [{ nodeId: 'c2', name: 'toUniversalEvents', source_location: 'L64' }],
|
|
476
|
-
} satisfies GraphifyComponentDetail,
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
id: 'detail-fn-void',
|
|
480
|
-
name: 'flush',
|
|
481
|
-
kind: 'function',
|
|
482
|
-
file: 'src/event-processing/sink.ts',
|
|
483
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
484
|
-
purpose: 'no parameters, no return type — the barest function signature',
|
|
485
|
-
symbol: 'flush',
|
|
486
|
-
detail: {
|
|
487
|
-
kind: 'function',
|
|
488
|
-
parameters: [],
|
|
489
|
-
callers: [{ nodeId: 'c4', name: 'EventProcessor.dispose', source_location: 'L142' }],
|
|
490
|
-
callees: [],
|
|
491
|
-
} satisfies GraphifyComponentDetail,
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
id: 'detail-class-rich',
|
|
495
|
-
name: 'EventProcessor',
|
|
496
|
-
kind: 'class',
|
|
497
|
-
file: 'src/event-processing/EventProcessor.ts',
|
|
498
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
499
|
-
purpose: 'class with fully-typed members — method params + returns, field types, extends + implements',
|
|
500
|
-
symbol: 'EventProcessor',
|
|
501
|
-
detail: {
|
|
502
|
-
kind: 'class',
|
|
503
|
-
methods: [
|
|
504
|
-
{ nodeId: 'rm1', name: 'process', parameters: [{ type: 'RawEvent' }, { type: 'ProcessingOptions' }], returnType: 'ProcessedEvent' },
|
|
505
|
-
{ nodeId: 'rm2', name: 'batch', parameters: [{ type: 'RawEvent[]' }], returnType: 'Promise<ProcessedEvent[]>' },
|
|
506
|
-
{ nodeId: 'rm3', name: 'onError', parameters: [{ type: 'Error' }] },
|
|
507
|
-
{ nodeId: 'rm4', name: 'dispose' },
|
|
508
|
-
],
|
|
509
|
-
properties: [
|
|
510
|
-
{ name: 'queue', type: 'RawEvent[]' },
|
|
511
|
-
{ name: 'options', type: 'Required<ProcessingOptions>' },
|
|
512
|
-
{ name: 'retryLimit', type: 'number' },
|
|
513
|
-
],
|
|
514
|
-
extends: ['BaseProcessor'],
|
|
515
|
-
implements: ['Disposable', 'EventEmitterLike'],
|
|
516
|
-
instantiations: [
|
|
517
|
-
{ nodeId: 'x1', name: 'main' },
|
|
518
|
-
{ nodeId: 'x2', name: 'worker-pool' },
|
|
519
|
-
],
|
|
520
|
-
references: [{ nodeId: 'x3', name: 'pipeline', context: 'type' }],
|
|
521
|
-
} satisfies GraphifyComponentDetail,
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
id: 'detail-type',
|
|
525
|
-
name: 'SessionRecord',
|
|
526
|
-
kind: 'type',
|
|
527
|
-
file: 'src/session/transcript.ts',
|
|
528
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
529
|
-
purpose: 'type-like: revealed by incoming implements edges',
|
|
530
|
-
symbol: 'SessionRecord',
|
|
531
|
-
detail: {
|
|
532
|
-
kind: 'type',
|
|
533
|
-
properties: [
|
|
534
|
-
{ name: 'id', type: 'string' },
|
|
535
|
-
{ name: 'admittedSeq', type: 'number' },
|
|
536
|
-
],
|
|
537
|
-
usedBy: [{ nodeId: 'u1', name: 'normalizeSession', context: 'type' }],
|
|
538
|
-
implementors: ['SessionReaderLike'],
|
|
539
|
-
} satisfies GraphifyComponentDetail,
|
|
540
|
-
},
|
|
541
|
-
{
|
|
542
|
-
id: 'detail-module',
|
|
543
|
-
name: 'CodexRolloutRecord',
|
|
544
|
-
kind: 'type',
|
|
545
|
-
file: 'src/session/transcript.ts',
|
|
546
|
-
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
547
|
-
purpose: 'a type symbol that lives in the transcript module; the node is the symbol, the file is its location',
|
|
548
|
-
symbol: 'CodexRolloutRecord',
|
|
549
|
-
detail: {
|
|
550
|
-
kind: 'type',
|
|
551
|
-
properties: [
|
|
552
|
-
{ name: 'type', type: 'string' },
|
|
553
|
-
{ name: 'id', type: 'string' },
|
|
554
|
-
],
|
|
555
|
-
usedBy: [{ nodeId: 'u1', name: 'isCodexRolloutRecord', context: 'type' }],
|
|
556
|
-
implementors: [],
|
|
557
|
-
} satisfies GraphifyComponentDetail,
|
|
558
|
-
},
|
|
559
|
-
{
|
|
560
|
-
id: 'detail-external',
|
|
561
|
-
// name = the package's name after the namespace; namespace shown above.
|
|
562
|
-
name: 'trail-viewer',
|
|
563
|
-
kind: 'external',
|
|
564
|
-
file: '',
|
|
565
|
-
purl: 'pkg:npm/@principal-ai/trail-viewer',
|
|
566
|
-
purpose: 'an npm package consumer — the whole package as a node',
|
|
567
|
-
symbol: '',
|
|
568
|
-
detail: {
|
|
569
|
-
kind: 'external',
|
|
570
|
-
label: 'pkg:npm/@principal-ai/trail-viewer',
|
|
571
|
-
} satisfies GraphifyComponentDetail,
|
|
572
|
-
},
|
|
573
|
-
];
|
|
574
|
-
|
|
575
|
-
const detailKindEdges: SubsystemComponentEdge[] = [];
|
|
576
|
-
|
|
577
|
-
function DetailKindsDemo() {
|
|
578
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
579
|
-
return (
|
|
580
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
581
|
-
<SubsystemComponentGraph
|
|
582
|
-
components={detailKindComponents}
|
|
583
|
-
edges={detailKindEdges}
|
|
584
|
-
onSelect={(id) => setSelected(id)}
|
|
585
|
-
/>
|
|
586
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
587
|
-
{selected ? `selected: ${selected}` : 'click a component to see its GraphifyComponentDetail'}
|
|
588
|
-
</div>
|
|
589
|
-
</div>
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
export const DetailKinds: Story = {
|
|
594
|
-
render: () => <DetailKindsDemo />,
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
// ---------------------------------------------------------------------------
|
|
598
|
-
// Kind variations — one column per kind (class / function / type / module /
|
|
599
|
-
// external), rows going bare → detailed. Click a node to see its declaration
|
|
600
|
-
// panel; type names inside it are clickable when they match another node here.
|
|
601
|
-
// ---------------------------------------------------------------------------
|
|
602
|
-
const variationPurl = 'pkg:github/principal-ai/agent-monitoring';
|
|
603
|
-
|
|
604
|
-
const kindVariationComponents: SubsystemComponent[] = [
|
|
605
|
-
// --- class: bare → members only → relationships only
|
|
606
|
-
{
|
|
607
|
-
id: 'cls-bare',
|
|
608
|
-
name: 'SessionStore',
|
|
609
|
-
kind: 'class',
|
|
610
|
-
file: 'src/session/SessionStore.ts',
|
|
611
|
-
purl: variationPurl,
|
|
612
|
-
purpose: 'no drill-down — renders a plain `class SessionStore`',
|
|
613
|
-
symbol: 'SessionStore',
|
|
614
|
-
layer: 1,
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
id: 'cls-members',
|
|
618
|
-
name: 'Transcoder',
|
|
619
|
-
kind: 'class',
|
|
620
|
-
file: 'src/session/Transcoder.ts',
|
|
621
|
-
purl: variationPurl,
|
|
622
|
-
purpose: 'members only — methods with typed params + returns, a typed field',
|
|
623
|
-
symbol: 'Transcoder',
|
|
624
|
-
layer: 1,
|
|
625
|
-
detail: {
|
|
626
|
-
kind: 'class',
|
|
627
|
-
methods: [
|
|
628
|
-
{ nodeId: 'tm1', name: 'encode', parameters: [{ type: 'RawFrame' }], returnType: 'Uint8Array' },
|
|
629
|
-
{ nodeId: 'tm2', name: 'decode', parameters: [{ type: 'Uint8Array' }], returnType: 'RawFrame' },
|
|
630
|
-
{ nodeId: 'tm3', name: 'reset' },
|
|
631
|
-
],
|
|
632
|
-
properties: [{ name: 'bufferSize', type: 'number' }],
|
|
633
|
-
extends: [],
|
|
634
|
-
implements: [],
|
|
635
|
-
instantiations: [],
|
|
636
|
-
references: [],
|
|
637
|
-
} satisfies GraphifyComponentDetail,
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
id: 'cls-relations',
|
|
641
|
-
name: 'HttpTransport',
|
|
642
|
-
kind: 'class',
|
|
643
|
-
file: 'src/transport/HttpTransport.ts',
|
|
644
|
-
purl: variationPurl,
|
|
645
|
-
purpose: 'relationships only — extends + implements, constructed-by comment; empty body elides the braces',
|
|
646
|
-
symbol: 'HttpTransport',
|
|
647
|
-
layer: 1,
|
|
648
|
-
detail: {
|
|
649
|
-
kind: 'class',
|
|
650
|
-
methods: [],
|
|
651
|
-
properties: [],
|
|
652
|
-
extends: ['BaseTransport'],
|
|
653
|
-
implements: ['Transport'],
|
|
654
|
-
instantiations: [{ nodeId: 'x1', name: 'main' }],
|
|
655
|
-
references: [],
|
|
656
|
-
} satisfies GraphifyComponentDetail,
|
|
657
|
-
},
|
|
658
|
-
|
|
659
|
-
// --- function: bare → signature only → signature + call relationships
|
|
660
|
-
{
|
|
661
|
-
id: 'fn-bare',
|
|
662
|
-
name: 'bootstrap',
|
|
663
|
-
kind: 'function',
|
|
664
|
-
file: 'src/bootstrap.ts',
|
|
665
|
-
purl: variationPurl,
|
|
666
|
-
purpose: 'no drill-down — renders a plain `function bootstrap()`',
|
|
667
|
-
symbol: 'bootstrap',
|
|
668
|
-
layer: 2,
|
|
669
|
-
},
|
|
670
|
-
{
|
|
671
|
-
id: 'fn-signature',
|
|
672
|
-
name: 'normalizeSession',
|
|
673
|
-
kind: 'function',
|
|
674
|
-
file: 'src/event-processing/normalize.ts',
|
|
675
|
-
purl: variationPurl,
|
|
676
|
-
purpose: 'signature only — named + positional (type-only) params, array return; no callers/callees comments',
|
|
677
|
-
symbol: 'normalizeSession',
|
|
678
|
-
layer: 2,
|
|
679
|
-
detail: {
|
|
680
|
-
kind: 'function',
|
|
681
|
-
parameters: [
|
|
682
|
-
{ name: 'session', type: 'SessionRecord' },
|
|
683
|
-
{ type: 'NormalizeOptions' },
|
|
684
|
-
],
|
|
685
|
-
returnType: 'SessionEvent[]',
|
|
686
|
-
callers: [],
|
|
687
|
-
callees: [],
|
|
688
|
-
} satisfies GraphifyComponentDetail,
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
id: 'fn-calls',
|
|
692
|
-
name: 'mergeSessions',
|
|
693
|
-
kind: 'function',
|
|
694
|
-
file: 'src/session/merge.ts',
|
|
695
|
-
purl: variationPurl,
|
|
696
|
-
purpose: 'signature + call relationships — union-typed param, generic return, called-by / calls trailing comments',
|
|
697
|
-
symbol: 'mergeSessions',
|
|
698
|
-
layer: 2,
|
|
699
|
-
detail: {
|
|
700
|
-
kind: 'function',
|
|
701
|
-
parameters: [
|
|
702
|
-
{ name: 'sessions', type: 'SessionRecord[]' },
|
|
703
|
-
{ name: 'strategy', type: `'append' | 'replace'` },
|
|
704
|
-
],
|
|
705
|
-
returnType: 'Promise<SessionEvent[]>',
|
|
706
|
-
callers: [{ nodeId: 'c1', name: 'capture-session', source_location: 'L88' }],
|
|
707
|
-
callees: [{ nodeId: 'c2', name: 'toUniversalEvents', source_location: 'L64' }],
|
|
708
|
-
} satisfies GraphifyComponentDetail,
|
|
709
|
-
},
|
|
710
|
-
|
|
711
|
-
// --- type: bare → fields only → fields + implementors + used-by
|
|
712
|
-
{
|
|
713
|
-
id: 'ty-bare',
|
|
714
|
-
name: 'RawFrame',
|
|
715
|
-
kind: 'type',
|
|
716
|
-
file: 'src/session/RawFrame.ts',
|
|
717
|
-
purl: variationPurl,
|
|
718
|
-
purpose: 'no drill-down — renders a plain `interface RawFrame`',
|
|
719
|
-
symbol: 'RawFrame',
|
|
720
|
-
layer: 3,
|
|
721
|
-
},
|
|
722
|
-
{
|
|
723
|
-
id: 'ty-fields',
|
|
724
|
-
name: 'SessionRecord',
|
|
725
|
-
kind: 'type',
|
|
726
|
-
file: 'src/session/transcript.ts',
|
|
727
|
-
purl: variationPurl,
|
|
728
|
-
purpose: 'fields only — typed interface body, nothing else',
|
|
729
|
-
symbol: 'SessionRecord',
|
|
730
|
-
layer: 3,
|
|
731
|
-
detail: {
|
|
732
|
-
kind: 'type',
|
|
733
|
-
properties: [
|
|
734
|
-
{ name: 'id', type: 'string' },
|
|
735
|
-
{ name: 'admittedSeq', type: 'number' },
|
|
736
|
-
],
|
|
737
|
-
usedBy: [],
|
|
738
|
-
implementors: [],
|
|
739
|
-
} satisfies GraphifyComponentDetail,
|
|
740
|
-
},
|
|
741
|
-
{
|
|
742
|
-
id: 'ty-full',
|
|
743
|
-
name: 'Transport',
|
|
744
|
-
kind: 'type',
|
|
745
|
-
file: 'src/transport/Transport.ts',
|
|
746
|
-
purl: variationPurl,
|
|
747
|
-
purpose: 'full — fields + implemented-by (clicks through to HttpTransport) + used-by comments',
|
|
748
|
-
symbol: 'Transport',
|
|
749
|
-
layer: 3,
|
|
750
|
-
detail: {
|
|
751
|
-
kind: 'type',
|
|
752
|
-
properties: [{ name: 'name', type: 'string' }],
|
|
753
|
-
usedBy: [{ nodeId: 'u1', name: 'main', context: 'parameter_type' }],
|
|
754
|
-
implementors: ['HttpTransport'],
|
|
755
|
-
} satisfies GraphifyComponentDetail,
|
|
756
|
-
},
|
|
757
|
-
|
|
758
|
-
// --- module: bare → exports only → exports + imports
|
|
759
|
-
{
|
|
760
|
-
id: 'mod-bare',
|
|
761
|
-
name: 'transcript',
|
|
762
|
-
kind: 'module',
|
|
763
|
-
file: 'src/session/transcript.ts',
|
|
764
|
-
purl: variationPurl,
|
|
765
|
-
purpose: 'no drill-down — symbol-less module named from its file basename',
|
|
766
|
-
symbol: '',
|
|
767
|
-
layer: 4,
|
|
768
|
-
},
|
|
769
|
-
{
|
|
770
|
-
id: 'mod-exports',
|
|
771
|
-
name: 'paths',
|
|
772
|
-
kind: 'module',
|
|
773
|
-
file: 'src/session/paths.ts',
|
|
774
|
-
purl: variationPurl,
|
|
775
|
-
purpose: 'exports only — export statement + defines comment',
|
|
776
|
-
symbol: '',
|
|
777
|
-
layer: 4,
|
|
778
|
-
detail: {
|
|
779
|
-
kind: 'module',
|
|
780
|
-
exports: ['extractToolName', 'extractFilePath'],
|
|
781
|
-
imports: [],
|
|
782
|
-
symbols: ['extractToolName', 'extractFilePath'],
|
|
783
|
-
} satisfies GraphifyComponentDetail,
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
id: 'mod-full',
|
|
787
|
-
name: 'index',
|
|
788
|
-
kind: 'module',
|
|
789
|
-
file: 'src/index.ts',
|
|
790
|
-
purl: variationPurl,
|
|
791
|
-
purpose: 'full — import statements + re-export statement + defines comment',
|
|
792
|
-
symbol: '',
|
|
793
|
-
layer: 4,
|
|
794
|
-
detail: {
|
|
795
|
-
kind: 'module',
|
|
796
|
-
exports: ['SessionReader', 'SessionStore'],
|
|
797
|
-
imports: [{ nodeId: 'i1', name: 'transcript', relation: 'imports_from' }],
|
|
798
|
-
symbols: ['SessionReader', 'SessionStore'],
|
|
799
|
-
} satisfies GraphifyComponentDetail,
|
|
800
|
-
},
|
|
801
|
-
|
|
802
|
-
// --- external: bare → labeled
|
|
803
|
-
{
|
|
804
|
-
id: 'ext-bare',
|
|
805
|
-
name: 'left-pad',
|
|
806
|
-
kind: 'external',
|
|
807
|
-
file: '',
|
|
808
|
-
purl: 'pkg:npm/left-pad',
|
|
809
|
-
purpose: 'no drill-down — renders a plain `external left-pad`',
|
|
810
|
-
symbol: '',
|
|
811
|
-
layer: 5,
|
|
812
|
-
},
|
|
813
|
-
{
|
|
814
|
-
id: 'ext-label',
|
|
815
|
-
name: 'trail-viewer',
|
|
816
|
-
kind: 'external',
|
|
817
|
-
file: '',
|
|
818
|
-
purl: 'pkg:npm/@principal-ai/trail-viewer',
|
|
819
|
-
purpose: 'labeled — the full purl as a quoted string literal',
|
|
820
|
-
symbol: '',
|
|
821
|
-
layer: 5,
|
|
822
|
-
detail: {
|
|
823
|
-
kind: 'external',
|
|
824
|
-
label: 'pkg:npm/@principal-ai/trail-viewer',
|
|
825
|
-
} satisfies GraphifyComponentDetail,
|
|
826
|
-
},
|
|
827
|
-
];
|
|
828
|
-
|
|
829
|
-
const kindVariationEdges: SubsystemComponentEdge[] = [];
|
|
830
|
-
|
|
831
|
-
function KindVariationsDemo() {
|
|
832
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
833
|
-
return (
|
|
834
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
835
|
-
<SubsystemComponentGraph
|
|
836
|
-
components={kindVariationComponents}
|
|
837
|
-
edges={kindVariationEdges}
|
|
838
|
-
onSelect={(id) => setSelected(id)}
|
|
839
|
-
/>
|
|
840
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
841
|
-
columns: class · function · type · module · external — each goes bare → detailed
|
|
842
|
-
{selected ? ` · selected: ${selected}` : ''}
|
|
843
|
-
</div>
|
|
844
|
-
</div>
|
|
845
|
-
);
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
export const KindVariations: Story = {
|
|
849
|
-
render: () => <KindVariationsDemo />,
|
|
850
|
-
};
|
|
851
|
-
|
|
852
|
-
// ---------------------------------------------------------------------------
|
|
853
|
-
// Minimal (pre-graphify) vs Resolved (post-graphify) — the SAME subsystem,
|
|
854
|
-
// showing what the LLM emits (no detail) and what graphify enrichment adds.
|
|
855
|
-
// ---------------------------------------------------------------------------
|
|
856
|
-
|
|
857
|
-
/** The minimal LLM-authored substrate: symbols only, no `detail`. */
|
|
858
|
-
const minimalComponents = components([
|
|
859
|
-
['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader'],
|
|
860
|
-
['normalize', 'normalize', 'function', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'maps a session into universal events', 'SessionReader.normalize'],
|
|
861
|
-
['record', 'SessionRecord', 'type', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'the parsed codex session record', 'SessionRecord'],
|
|
862
|
-
['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
|
|
863
|
-
]);
|
|
864
|
-
|
|
865
|
-
const sharedEdges = edges([
|
|
866
|
-
['transcript', 'record', 'defines'],
|
|
867
|
-
['reader', 'normalize', 'method'],
|
|
868
|
-
['normalize', 'record', 'references'],
|
|
869
|
-
]);
|
|
870
|
-
|
|
871
|
-
/** The same subsystem after `resolveSubsystemToGraphify` populates `detail`. */
|
|
872
|
-
const resolvedComponents: SubsystemComponent[] = [
|
|
873
|
-
{ ...minimalComponents[0], detail: readerDetail },
|
|
874
|
-
{
|
|
875
|
-
...minimalComponents[1],
|
|
876
|
-
detail: {
|
|
877
|
-
kind: 'function',
|
|
878
|
-
parameters: [{ name: 'session', type: 'SessionRecord' }],
|
|
879
|
-
returnType: 'SessionEvent[]',
|
|
880
|
-
callers: [{ nodeId: 'c1', name: 'capture-session', source_location: 'L120' }],
|
|
881
|
-
callees: [{ nodeId: 'c2', name: 'toUniversalEvents', source_location: 'L64' }],
|
|
882
|
-
} satisfies GraphifyComponentDetail,
|
|
883
|
-
},
|
|
884
|
-
{
|
|
885
|
-
...minimalComponents[2],
|
|
886
|
-
detail: {
|
|
887
|
-
kind: 'type',
|
|
888
|
-
properties: [
|
|
889
|
-
{ name: 'id', type: 'string' },
|
|
890
|
-
{ name: 'type', type: 'string' },
|
|
891
|
-
],
|
|
892
|
-
usedBy: [{ nodeId: 'u1', name: 'normalize', context: 'type' }],
|
|
893
|
-
implementors: ['SessionReaderLike'],
|
|
894
|
-
} satisfies GraphifyComponentDetail,
|
|
895
|
-
},
|
|
896
|
-
{
|
|
897
|
-
...minimalComponents[3],
|
|
898
|
-
detail: {
|
|
899
|
-
kind: 'module',
|
|
900
|
-
exports: ['CodexRolloutRecord', 'CodexSessionMeta'],
|
|
901
|
-
imports: [{ nodeId: 'i1', name: 'paths', relation: 'imports_from' }],
|
|
902
|
-
symbols: ['CodexRolloutRecord', 'CodexSessionMeta'],
|
|
903
|
-
} satisfies GraphifyComponentDetail,
|
|
904
|
-
},
|
|
905
|
-
];
|
|
906
|
-
|
|
907
|
-
function MinimalVsResolvedDemo({ resolved }: { resolved: boolean }) {
|
|
908
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
909
|
-
return (
|
|
910
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
911
|
-
<SubsystemComponentGraph
|
|
912
|
-
components={resolved ? resolvedComponents : minimalComponents}
|
|
913
|
-
edges={sharedEdges}
|
|
914
|
-
onSelect={(id) => setSelected(id)}
|
|
915
|
-
/>
|
|
916
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
917
|
-
{resolved
|
|
918
|
-
? 'post-graphify: click a component to see the enriched GraphifyComponentDetail'
|
|
919
|
-
: 'pre-graphify: LLM-authored symbols only — no detail yet'}
|
|
920
|
-
</div>
|
|
921
|
-
</div>
|
|
922
|
-
);
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
export const MinimalPreGraphify: Story = {
|
|
926
|
-
render: () => <MinimalVsResolvedDemo resolved={false} />,
|
|
927
|
-
};
|
|
928
|
-
|
|
929
|
-
export const ResolvedPostGraphify: Story = {
|
|
930
|
-
render: () => <MinimalVsResolvedDemo resolved />,
|
|
931
|
-
};
|
|
932
|
-
|
|
933
|
-
// ---------------------------------------------------------------------------
|
|
934
|
-
// Investigation-derived subsystem — grok session 019fd2a9 (t3code)
|
|
935
|
-
// Read-only analysis of "provider / event threading". Components are occupied
|
|
936
|
-
// (analyzed, not edited) — no code touched, but a coherent concept was worked.
|
|
937
|
-
// ---------------------------------------------------------------------------
|
|
938
|
-
const investigationComponents: SubsystemComponent[] = [
|
|
939
|
-
{
|
|
940
|
-
id: 'adapter',
|
|
941
|
-
name: 'OpenCodeAdapter',
|
|
942
|
-
kind: 'module',
|
|
943
|
-
file: 'apps/server/src/provider/Layers/OpenCodeAdapter.ts',
|
|
944
|
-
purl: 'pkg:github/t3code/t3code',
|
|
945
|
-
purpose: 'adapts opencode session/threads + events to the t3 runtime',
|
|
946
|
-
symbol: 'makeOpenCodeAdapter',
|
|
947
|
-
capture: 'analyzed',
|
|
948
|
-
detail: {
|
|
949
|
-
kind: 'module',
|
|
950
|
-
exports: ['makeOpenCodeAdapter', 'OpenCodeAdapterLiveOptions'],
|
|
951
|
-
imports: [{ nodeId: 'i1', name: 'orchestration', relation: 'imports_from' }],
|
|
952
|
-
symbols: ['makeOpenCodeAdapter', 'isOpenCodeNotFound', 'OpenCodeSessionContext'],
|
|
953
|
-
} satisfies GraphifyComponentDetail,
|
|
954
|
-
},
|
|
955
|
-
{
|
|
956
|
-
id: 'ingestion',
|
|
957
|
-
name: 'ProviderRuntimeIngestion',
|
|
958
|
-
kind: 'module',
|
|
959
|
-
file: 'apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts',
|
|
960
|
-
purl: 'pkg:github/t3code/t3code',
|
|
961
|
-
purpose: 'ingests provider events into the runtime',
|
|
962
|
-
symbol: 'ProviderRuntimeIngestion',
|
|
963
|
-
capture: 'analyzed',
|
|
964
|
-
},
|
|
965
|
-
{
|
|
966
|
-
id: 'contracts',
|
|
967
|
-
name: 'orchestration',
|
|
968
|
-
kind: 'module',
|
|
969
|
-
file: 'packages/contracts/src/orchestration.ts',
|
|
970
|
-
purl: 'pkg:github/t3code/t3code',
|
|
971
|
-
purpose: 'contracts for orchestration/providers',
|
|
972
|
-
symbol: 'ORCHESTRATION_WS_METHODS',
|
|
973
|
-
capture: 'analyzed',
|
|
974
|
-
},
|
|
975
|
-
];
|
|
976
|
-
|
|
977
|
-
const investigationEdges = edges([
|
|
978
|
-
['adapter', 'contracts', 'imports_from'],
|
|
979
|
-
['ingestion', 'adapter', 'uses'],
|
|
980
|
-
['ingestion', 'contracts', 'references'],
|
|
981
|
-
]);
|
|
982
|
-
|
|
983
|
-
function InvestigationDemo() {
|
|
984
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
985
|
-
return (
|
|
986
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
987
|
-
<SubsystemComponentGraph
|
|
988
|
-
components={investigationComponents}
|
|
989
|
-
edges={investigationEdges}
|
|
990
|
-
onSelect={(id) => setSelected(id)}
|
|
991
|
-
/>
|
|
992
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
993
|
-
read-only investigation snapshot (grok 019fd2a9) — components analyzed, not edited
|
|
994
|
-
{selected ? ` · selected: ${selected}` : ''}
|
|
995
|
-
</div>
|
|
996
|
-
</div>
|
|
997
|
-
);
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
export const InvestigationDerived: Story = {
|
|
1001
|
-
render: () => <InvestigationDemo />,
|
|
1002
|
-
};
|
|
1003
|
-
|
|
1004
|
-
// ---------------------------------------------------------------------------
|
|
1005
|
-
// Mermaid diagram rendering pipeline (industry-themed-markdown)
|
|
1006
|
-
// ---------------------------------------------------------------------------
|
|
1007
|
-
const mermaidPurl = 'pkg:github/principal-ade/industry-themed-markdown';
|
|
1008
|
-
|
|
1009
|
-
const mermaidComponents: SubsystemComponent[] = [
|
|
1010
|
-
{
|
|
1011
|
-
id: 'input',
|
|
1012
|
-
name: 'MarkdownContent',
|
|
1013
|
-
kind: 'type',
|
|
1014
|
-
file: 'industryMarkdown/components/IndustryMarkdownSlide.tsx',
|
|
1015
|
-
purl: mermaidPurl,
|
|
1016
|
-
purpose: 'raw markdown string — the slide\u2019s input',
|
|
1017
|
-
symbol: 'MarkdownContent',
|
|
1018
|
-
},
|
|
1019
|
-
{
|
|
1020
|
-
id: 'slide',
|
|
1021
|
-
name: 'IndustryMarkdownSlide',
|
|
1022
|
-
kind: 'class',
|
|
1023
|
-
file: 'industryMarkdown/components/IndustryMarkdownSlide.tsx',
|
|
1024
|
-
purl: mermaidPurl,
|
|
1025
|
-
purpose: 'orchestrator — parses markdown into chunks, maps mermaid chunks to diagrams',
|
|
1026
|
-
symbol: 'IndustryMarkdownSlide',
|
|
1027
|
-
},
|
|
1028
|
-
{
|
|
1029
|
-
id: 'chunk',
|
|
1030
|
-
name: 'MermaidChunk',
|
|
1031
|
-
kind: 'type',
|
|
1032
|
-
file: 'industryMarkdown/types/customMarkdownChunks.ts',
|
|
1033
|
-
purl: mermaidPurl,
|
|
1034
|
-
purpose: 'parsed chunk — code string + id, the slide\u2019s output per mermaid block',
|
|
1035
|
-
symbol: 'MermaidChunk',
|
|
1036
|
-
},
|
|
1037
|
-
{
|
|
1038
|
-
id: 'lazy',
|
|
1039
|
-
name: 'IndustryLazyMermaidDiagram',
|
|
1040
|
-
kind: 'class',
|
|
1041
|
-
file: 'industryMarkdown/components/IndustryLazyMermaidDiagram.tsx',
|
|
1042
|
-
purl: mermaidPurl,
|
|
1043
|
-
purpose: 'IntersectionObserver lazy-loading wrapper \u2014 defers render until scrolled into view',
|
|
1044
|
-
symbol: 'IndustryLazyMermaidDiagram',
|
|
1045
|
-
},
|
|
1046
|
-
{
|
|
1047
|
-
id: 'diagram',
|
|
1048
|
-
name: 'IndustryMermaidDiagram',
|
|
1049
|
-
kind: 'class',
|
|
1050
|
-
file: 'industryMarkdown/components/IndustryMermaidDiagram.tsx',
|
|
1051
|
-
purl: mermaidPurl,
|
|
1052
|
-
purpose: 'core renderer \u2014 picks engine (beautiful-mermaid vs mermaid.js), renders themed SVG',
|
|
1053
|
-
symbol: 'IndustryMermaidDiagram',
|
|
1054
|
-
},
|
|
1055
|
-
{
|
|
1056
|
-
id: 'helpers',
|
|
1057
|
-
name: 'beautifulMermaid',
|
|
1058
|
-
kind: 'module',
|
|
1059
|
-
file: 'industryMarkdown/utils/beautifulMermaid.ts',
|
|
1060
|
-
purl: mermaidPurl,
|
|
1061
|
-
purpose: 'engine detection, theme\u2192options mapping, SVG post-processing',
|
|
1062
|
-
symbol: 'beautifulMermaid',
|
|
1063
|
-
},
|
|
1064
|
-
];
|
|
1065
|
-
|
|
1066
|
-
const mermaidEdges = edges([
|
|
1067
|
-
['input', 'slide', 'feeds'],
|
|
1068
|
-
['slide', 'chunk', 'produces'],
|
|
1069
|
-
['chunk', 'lazy', 'feeds'],
|
|
1070
|
-
['lazy', 'diagram', 'wraps'],
|
|
1071
|
-
['diagram', 'helpers', 'uses'],
|
|
1072
|
-
]);
|
|
1073
|
-
|
|
1074
|
-
function MermaidDemo() {
|
|
1075
|
-
const [selected, setSelected] = useState<string | null>(null);
|
|
1076
|
-
return (
|
|
1077
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
1078
|
-
<SubsystemComponentGraph
|
|
1079
|
-
components={mermaidComponents}
|
|
1080
|
-
edges={mermaidEdges}
|
|
1081
|
-
onSelect={(id) => setSelected(id)}
|
|
1082
|
-
/>
|
|
1083
|
-
<div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
|
|
1084
|
-
mermaid diagram rendering pipeline — lazy → render → zoom → modal
|
|
1085
|
-
{selected ? ` · selected: ${selected}` : ''}
|
|
1086
|
-
</div>
|
|
1087
|
-
</div>
|
|
1088
|
-
);
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
export const MermaidPipeline: Story = {
|
|
1092
|
-
render: () => <MermaidDemo />,
|
|
1093
|
-
};
|
|
1094
|
-
|
|
1095
|
-
// ---------------------------------------------------------------------------
|
|
1096
|
-
// Multi-repo: two repos → two sidebar trees, one per repo, each under its own
|
|
1097
|
-
// owner-avatar + repo-name header. Exercises buildRepoGroups grouping,
|
|
1098
|
-
// cross-repo edges (external stub targets), and per-tree selection.
|
|
1099
|
-
// ---------------------------------------------------------------------------
|
|
1100
|
-
const coreLibPurl = 'pkg:github/principal-ai/principal-view-core-library';
|
|
1101
|
-
const graphifyPurl = 'pkg:github/Graphify-Labs/graphify';
|
|
1102
|
-
|
|
1103
|
-
const multiRepoComponents = components([
|
|
1104
|
-
['resolver', 'resolve.ts', 'module', 'packages/react/src/graphify/resolve.ts', coreLibPurl, 'consumer-side resolution mirroring graphify rewire tiers', 'createGraphifyTypeResolver'],
|
|
1105
|
-
['reftypes', 'consolidated.ts', 'module', 'packages/react/src/graphify/consolidated.ts', coreLibPurl, 'drill-down payload types carrying ref.nodeId', 'GraphifyParamInfo'],
|
|
1106
|
-
['detail', 'ComponentDeclaration.tsx', 'module', 'packages/react/src/subsystem/ComponentDeclaration.tsx', coreLibPurl, 'declaration panel rendering the selected component as code, with clickable type tokens', 'ComponentDeclaration'],
|
|
1107
|
-
['engine', 'engine.py', 'module', 'graphify/extractors/engine.py', graphifyPurl, 'tree-sitter walk emitting references[parameter_type] edges + sourceless stubs', 'ensure_named_node'],
|
|
1108
|
-
['rewire', 'extract.py', 'module', 'graphify/extract.py', graphifyPurl, 'corpus pass folding unique-label stubs onto definitions', '_rewire_unique_stub_nodes'],
|
|
1109
|
-
]);
|
|
1110
|
-
|
|
1111
|
-
const multiRepoEdges = edges([
|
|
1112
|
-
['detail', 'reftypes', 'imports'],
|
|
1113
|
-
['resolver', 'reftypes', 'imports'],
|
|
1114
|
-
['resolver', 'engine', 'references'],
|
|
1115
|
-
['rewire', 'resolver', 'calls'],
|
|
1116
|
-
]);
|
|
1117
|
-
|
|
1118
|
-
function MultiRepoDemo() {
|
|
1119
|
-
return (
|
|
1120
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
1121
|
-
<SubsystemComponentGraph
|
|
1122
|
-
title="Type-ref resolution across repos"
|
|
1123
|
-
description="Two repos → two file trees. Each tree is scoped to its repo's files and headed by the owner avatar + repo name. Cross-repo edges land on external stubs."
|
|
1124
|
-
components={multiRepoComponents}
|
|
1125
|
-
edges={multiRepoEdges}
|
|
1126
|
-
/>
|
|
1127
|
-
</div>
|
|
1128
|
-
);
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
export const MultiRepoTrees: Story = {
|
|
1132
|
-
render: () => <MultiRepoDemo />,
|
|
1133
|
-
};
|
|
1134
|
-
|
|
1135
|
-
// ---------------------------------------------------------------------------
|
|
1136
|
-
// Declaration line open — Pierre snippet/file views + declarationRef.
|
|
1137
|
-
// Click the ComponentDeclaration node → toggle file → click path or L251.
|
|
1138
|
-
// ---------------------------------------------------------------------------
|
|
1139
|
-
const storyFileContents: Record<string, string> = {
|
|
1140
|
-
'packages/react/src/subsystem/ComponentDeclaration.tsx': componentDeclarationSource,
|
|
1141
|
-
'packages/react/src/graphify/resolve.ts': resolveSource,
|
|
1142
|
-
};
|
|
1143
|
-
|
|
1144
|
-
const declarationOpenComponents: SubsystemComponent[] = [
|
|
1145
|
-
{
|
|
1146
|
-
id: 'detail',
|
|
1147
|
-
name: 'ComponentDeclaration',
|
|
1148
|
-
kind: 'module',
|
|
1149
|
-
file: 'packages/react/src/subsystem/ComponentDeclaration.tsx',
|
|
1150
|
-
purl: 'pkg:github/principal-ai/principal-view-core-library',
|
|
1151
|
-
purpose: 'declaration panel — click file or L251 to open the drawer at the export line',
|
|
1152
|
-
symbol: 'ComponentDeclaration',
|
|
1153
|
-
declarationRef: {
|
|
1154
|
-
file: 'packages/react/src/subsystem/ComponentDeclaration.tsx',
|
|
1155
|
-
startLine: 251,
|
|
1156
|
-
lineHash: 'storybook-placeholder',
|
|
1157
|
-
capturedAt: new Date(0).toISOString(),
|
|
1158
|
-
},
|
|
1159
|
-
},
|
|
1160
|
-
{
|
|
1161
|
-
id: 'resolver',
|
|
1162
|
-
name: 'resolve.ts',
|
|
1163
|
-
kind: 'module',
|
|
1164
|
-
file: 'packages/react/src/graphify/resolve.ts',
|
|
1165
|
-
purl: 'pkg:github/principal-ai/principal-view-core-library',
|
|
1166
|
-
purpose: 'graphify type-ref resolver (second file for tree navigation)',
|
|
1167
|
-
symbol: 'resolveGraphifyTypeRef',
|
|
1168
|
-
declarationRef: {
|
|
1169
|
-
file: 'packages/react/src/graphify/resolve.ts',
|
|
1170
|
-
startLine: 1,
|
|
1171
|
-
lineHash: 'storybook-placeholder',
|
|
1172
|
-
capturedAt: new Date(0).toISOString(),
|
|
1173
|
-
},
|
|
1174
|
-
},
|
|
1175
|
-
];
|
|
1176
|
-
|
|
1177
|
-
function readStoryFile(path: string): Promise<string> {
|
|
1178
|
-
const content = storyFileContents[path];
|
|
1179
|
-
if (content == null) {
|
|
1180
|
-
return Promise.reject(new Error(`No story fixture for ${path}`));
|
|
1181
|
-
}
|
|
1182
|
-
return Promise.resolve(content);
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
function DeclarationLineOpenDemo() {
|
|
1186
|
-
const renderFileViewer = (file: string, opts?: SubsystemOpenFileOptions) => {
|
|
1187
|
-
const startLine = opts?.startLine;
|
|
1188
|
-
if (startLine != null) {
|
|
1189
|
-
return (
|
|
1190
|
-
<PierreSnippetView
|
|
1191
|
-
filePath={file}
|
|
1192
|
-
fileName={file.split('/').pop() ?? file}
|
|
1193
|
-
startLine={startLine}
|
|
1194
|
-
endLine={startLine}
|
|
1195
|
-
focusLine={startLine}
|
|
1196
|
-
contextLines={40}
|
|
1197
|
-
readFile={readStoryFile}
|
|
1198
|
-
/>
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
return (
|
|
1202
|
-
<PierreFileView
|
|
1203
|
-
filePath={file}
|
|
1204
|
-
fileName={file.split('/').pop() ?? file}
|
|
1205
|
-
readFile={readStoryFile}
|
|
1206
|
-
/>
|
|
1207
|
-
);
|
|
1208
|
-
};
|
|
1209
|
-
|
|
1210
|
-
return (
|
|
1211
|
-
<div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
1212
|
-
<SubsystemComponentGraph
|
|
1213
|
-
title="Declaration line open (Storybook)"
|
|
1214
|
-
description="Uses bundled ?raw fixtures + PierreSnippetView from this package. Select ComponentDeclaration, toggle file, click the path or L251."
|
|
1215
|
-
components={declarationOpenComponents}
|
|
1216
|
-
edges={[]}
|
|
1217
|
-
renderFileViewer={renderFileViewer}
|
|
1218
|
-
/>
|
|
1219
|
-
</div>
|
|
1220
|
-
);
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
export const DeclarationLineOpen: Story = {
|
|
1224
|
-
render: () => <DeclarationLineOpenDemo />,
|
|
1225
|
-
};
|