@principal-ai/subsystems-react 0.20.6 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +1 -1
  2. package/dist/graphify/anchor.d.ts +17 -0
  3. package/dist/graphify/anchor.d.ts.map +1 -1
  4. package/dist/graphify/anchor.js +41 -0
  5. package/dist/graphify/anchor.js.map +1 -1
  6. package/dist/graphify/consolidated.d.ts +40 -1
  7. package/dist/graphify/consolidated.d.ts.map +1 -1
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/pierre/PierreWalkthroughCodeView.d.ts +22 -0
  13. package/dist/pierre/PierreWalkthroughCodeView.d.ts.map +1 -0
  14. package/dist/pierre/PierreWalkthroughCodeView.js +198 -0
  15. package/dist/pierre/PierreWalkthroughCodeView.js.map +1 -0
  16. package/dist/pierre/index.d.ts +2 -2
  17. package/dist/pierre/index.js +1 -1
  18. package/dist/pierre/pierreFileLang.d.ts +1 -1
  19. package/dist/pierre/pierreFileLang.js +1 -1
  20. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +14 -2
  21. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -1
  22. package/dist/stories/Subsystem/ComponentGraph/fixtures.js +86 -20
  23. package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -1
  24. package/dist/subsystem/FileDrawer.d.ts +2 -2
  25. package/dist/subsystem/FileDrawer.js +2 -2
  26. package/dist/subsystem/SubsystemComponentGraph.d.ts +25 -24
  27. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  28. package/dist/subsystem/SubsystemComponentGraph.js +204 -199
  29. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  30. package/dist/subsystem/formatDeclaration.d.ts +2 -1
  31. package/dist/subsystem/formatDeclaration.d.ts.map +1 -1
  32. package/dist/subsystem/formatDeclaration.js +57 -33
  33. package/dist/subsystem/formatDeclaration.js.map +1 -1
  34. package/dist/subsystem/model.d.ts +85 -35
  35. package/dist/subsystem/model.d.ts.map +1 -1
  36. package/dist/subsystem/model.js +85 -6
  37. package/dist/subsystem/model.js.map +1 -1
  38. package/dist/subsystem/nodes.d.ts.map +1 -1
  39. package/dist/subsystem/nodes.js +30 -13
  40. package/dist/subsystem/nodes.js.map +1 -1
  41. package/dist/subsystem/tokenizeComponent.js +2 -2
  42. package/dist/subsystem/tokenizeComponent.js.map +1 -1
  43. package/package.json +3 -3
  44. package/src/graphify/anchor.test.ts +31 -2
  45. package/src/graphify/anchor.ts +46 -0
  46. package/src/graphify/consolidated.ts +43 -1
  47. package/src/index.ts +13 -5
  48. package/src/pierre/{PierreThroughlineCodeView.tsx → PierreWalkthroughCodeView.tsx} +39 -47
  49. package/src/pierre/index.ts +2 -2
  50. package/src/pierre/pierreFileLang.ts +1 -1
  51. package/src/stories/Pierre/CodeView.stories.tsx +3 -3
  52. package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +14 -14
  53. package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +13 -15
  54. package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +8 -8
  55. package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +14 -14
  56. package/src/stories/Subsystem/ComponentGraph/CustomEntities.stories.tsx +11 -10
  57. package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +13 -14
  58. package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +31 -66
  59. package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +2 -2
  60. package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +4 -4
  61. package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +3 -3
  62. package/src/stories/Subsystem/ComponentGraph/Proposed.stories.tsx +1 -1
  63. package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +518 -33
  64. package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +13 -13
  65. package/src/stories/Subsystem/ComponentGraph/fixtures.ts +105 -21
  66. package/src/subsystem/FileDrawer.tsx +2 -2
  67. package/src/subsystem/SubsystemComponentGraph.tsx +268 -259
  68. package/src/subsystem/formatDeclaration.test.ts +76 -1
  69. package/src/subsystem/formatDeclaration.ts +57 -33
  70. package/src/subsystem/model.test.ts +27 -15
  71. package/src/subsystem/model.ts +175 -45
  72. package/src/subsystem/nodes.tsx +47 -13
  73. package/src/subsystem/tokenizeComponent.ts +2 -2
@@ -5,7 +5,7 @@ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme
5
5
  import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
6
6
  import type { SubsystemComponent, SubsystemComponentEdge } from '../../../subsystem/model';
7
7
  import type { GraphifyComponentDetail } from '../../../graphify';
8
- import { investigateOnlyComponents, investigateOnlyEdges } from './fixtures';
8
+ import { investigateOnlyComponents, investigateOnlyRelations, investigateOnlyWalkthroughs } from './fixtures';
9
9
 
10
10
  const meta = {
11
11
  title: 'Subsystem/ComponentGraph/Appearance',
@@ -32,7 +32,7 @@ export const NarrowMaxWidth: Story = {
32
32
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
33
33
  <SubsystemComponentGraph
34
34
  components={investigateOnlyComponents}
35
- edges={investigateOnlyEdges}
35
+ relations={investigateOnlyRelations} walkthroughs={investigateOnlyWalkthroughs}
36
36
  maxNodeWidth={140}
37
37
  />
38
38
  </div>
@@ -93,7 +93,6 @@ const namingConventionComponents: SubsystemComponent[] = [
93
93
  },
94
94
  ];
95
95
 
96
- const namingConventionEdges: SubsystemComponentEdge[] = [];
97
96
 
98
97
  /** Nodes with compact `maxNodeWidth` so the different conventions visibly wrap
99
98
  * at their word boundaries (camelCase, snake_case, PascalCase, acronyms). */
@@ -102,7 +101,7 @@ export const NamingConventions: Story = {
102
101
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
103
102
  <SubsystemComponentGraph
104
103
  components={namingConventionComponents}
105
- edges={namingConventionEdges}
104
+ relations={[]}
106
105
  maxNodeWidth={180}
107
106
  />
108
107
  </div>
@@ -137,7 +136,7 @@ const kindVariationComponents: SubsystemComponent[] = [
137
136
  purpose: 'members only — methods with typed params + returns, a typed field',
138
137
  symbol: 'Transcoder',
139
138
  layer: 1,
140
- detail: {
139
+ declaration: {
141
140
  kind: 'class',
142
141
  methods: [
143
142
  { nodeId: 'tm1', name: 'encode', parameters: [{ type: 'RawFrame' }], returnType: 'Uint8Array' },
@@ -160,7 +159,7 @@ const kindVariationComponents: SubsystemComponent[] = [
160
159
  purpose: 'relationships only — extends + implements, constructed-by comment; empty body elides the braces',
161
160
  symbol: 'HttpTransport',
162
161
  layer: 1,
163
- detail: {
162
+ declaration: {
164
163
  kind: 'class',
165
164
  methods: [],
166
165
  properties: [],
@@ -191,7 +190,7 @@ const kindVariationComponents: SubsystemComponent[] = [
191
190
  purpose: 'signature only — named + positional (type-only) params, array return; no callers/callees comments',
192
191
  symbol: 'normalizeSession',
193
192
  layer: 2,
194
- detail: {
193
+ declaration: {
195
194
  kind: 'function',
196
195
  parameters: [
197
196
  { name: 'session', type: 'SessionRecord' },
@@ -211,7 +210,7 @@ const kindVariationComponents: SubsystemComponent[] = [
211
210
  purpose: 'signature + call relationships — union-typed param, generic return, called-by / calls trailing comments',
212
211
  symbol: 'mergeSessions',
213
212
  layer: 2,
214
- detail: {
213
+ declaration: {
215
214
  kind: 'function',
216
215
  parameters: [
217
216
  { name: 'sessions', type: 'SessionRecord[]' },
@@ -243,7 +242,7 @@ const kindVariationComponents: SubsystemComponent[] = [
243
242
  purpose: 'fields only — typed interface body, nothing else',
244
243
  symbol: 'SessionRecord',
245
244
  layer: 3,
246
- detail: {
245
+ declaration: {
247
246
  kind: 'type',
248
247
  properties: [
249
248
  { name: 'id', type: 'string' },
@@ -262,7 +261,7 @@ const kindVariationComponents: SubsystemComponent[] = [
262
261
  purpose: 'full — fields + implemented-by (clicks through to HttpTransport) + used-by comments',
263
262
  symbol: 'Transport',
264
263
  layer: 3,
265
- detail: {
264
+ declaration: {
266
265
  kind: 'type',
267
266
  properties: [{ name: 'name', type: 'string' }],
268
267
  usedBy: [{ nodeId: 'u1', name: 'main', context: 'parameter_type' }],
@@ -290,7 +289,7 @@ const kindVariationComponents: SubsystemComponent[] = [
290
289
  purpose: 'exports only — export statement + defines comment',
291
290
  symbol: '',
292
291
  layer: 4,
293
- detail: {
292
+ declaration: {
294
293
  kind: 'module',
295
294
  exports: ['extractToolName', 'extractFilePath'],
296
295
  imports: [],
@@ -306,7 +305,7 @@ const kindVariationComponents: SubsystemComponent[] = [
306
305
  purpose: 'full — import statements + re-export statement + defines comment',
307
306
  symbol: '',
308
307
  layer: 4,
309
- detail: {
308
+ declaration: {
310
309
  kind: 'module',
311
310
  exports: ['SessionReader', 'SessionStore'],
312
311
  imports: [{ nodeId: 'i1', name: 'transcript', relation: 'imports_from' }],
@@ -334,14 +333,13 @@ const kindVariationComponents: SubsystemComponent[] = [
334
333
  purpose: 'labeled — the full purl as a quoted string literal',
335
334
  symbol: '',
336
335
  layer: 5,
337
- detail: {
336
+ declaration: {
338
337
  kind: 'external',
339
338
  label: 'pkg:npm/@principal-ai/subsystems-studio',
340
339
  } satisfies GraphifyComponentDetail,
341
340
  },
342
341
  ];
343
342
 
344
- const kindVariationEdges: SubsystemComponentEdge[] = [];
345
343
 
346
344
  function KindVariationsDemo() {
347
345
  const [selected, setSelected] = useState<string | null>(null);
@@ -349,7 +347,7 @@ function KindVariationsDemo() {
349
347
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
350
348
  <SubsystemComponentGraph
351
349
  components={kindVariationComponents}
352
- edges={kindVariationEdges}
350
+ relations={[]}
353
351
  onSelect={(id) => setSelected(id)}
354
352
  />
355
353
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
@@ -4,7 +4,7 @@ import type { Meta, StoryObj } from '@storybook/react';
4
4
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
5
5
  import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
6
6
  import type { SubsystemComponent, SubsystemComponentEdge } from '../../../subsystem/model';
7
- import { components, edges } from './fixtures';
7
+ import { components, graphSpecFromEdges } from './fixtures';
8
8
 
9
9
  const meta = {
10
10
  title: 'Subsystem/ComponentGraph/Basics',
@@ -33,7 +33,7 @@ const twoNodeComponents = components([
33
33
  ['dst', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes sessions into events'],
34
34
  ]);
35
35
 
36
- const twoNodeEdges = edges([
36
+ const twoNodeEdges = graphSpecFromEdges([
37
37
  ['src', 'dst', 'imports'],
38
38
  ]);
39
39
 
@@ -44,7 +44,7 @@ function TwoNodeDemo({ showEdgeLabels = true }: { showEdgeLabels?: boolean }) {
44
44
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
45
45
  <SubsystemComponentGraph
46
46
  components={twoNodeComponents}
47
- edges={twoNodeEdges}
47
+ relations={twoNodeEdges.relations} walkthroughs={twoNodeEdges.walkthroughs}
48
48
  onSelect={(id) => setSelected(id)}
49
49
  onEdgeSelect={(e) => setSelectedEdge(e)}
50
50
  showEdgeLabels={showEdgeLabels}
@@ -74,7 +74,7 @@ export const TwoNodeNoLabels: Story = {
74
74
  // ---------------------------------------------------------------------------
75
75
  function PlaygroundDemo({ leftCount, rightCount, showEdgeLabels }: { leftCount: number; rightCount: number; showEdgeLabels: boolean }) {
76
76
  const comps: SubsystemComponent[] = [];
77
- const edgeList: SubsystemComponentEdge[] = [];
77
+ const edgeSpec: Array<[string, string, SubsystemComponentEdge['mechanism']]> = [];
78
78
 
79
79
  for (let i = 0; i < leftCount; i++) {
80
80
  comps.push({
@@ -97,16 +97,16 @@ function PlaygroundDemo({ leftCount, rightCount, showEdgeLabels }: { leftCount:
97
97
  });
98
98
  }
99
99
 
100
- let ei = 0;
101
100
  for (let i = 0; i < leftCount; i++) {
102
101
  for (let j = 0; j < rightCount; j++) {
103
- edgeList.push({ id: `e${ei++}`, from: `l${i}`, to: `r${j}`, mechanism: 'imports' });
102
+ edgeSpec.push([`l${i}`, `r${j}`, 'imports']);
104
103
  }
105
104
  }
105
+ const graph = graphSpecFromEdges(edgeSpec);
106
106
 
107
107
  return (
108
108
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
109
- <SubsystemComponentGraph components={comps} edges={edgeList} showEdgeLabels={showEdgeLabels} />
109
+ <SubsystemComponentGraph components={comps} relations={graph.relations} walkthroughs={graph.walkthroughs} showEdgeLabels={showEdgeLabels} />
110
110
  </div>
111
111
  );
112
112
  }
@@ -131,7 +131,7 @@ export const Playground: Story = {
131
131
  export const Empty: Story = {
132
132
  render: () => (
133
133
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
134
- <SubsystemComponentGraph components={[]} edges={[]} />
134
+ <SubsystemComponentGraph components={[]} relations={[]} />
135
135
  </div>
136
136
  ),
137
137
  };
@@ -5,7 +5,7 @@ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme
5
5
  import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
6
6
  import type { SubsystemComponent, SubsystemComponentEdge } from '../../../subsystem/model';
7
7
  import type { GraphifyComponentDetail } from '../../../graphify';
8
- import { components, edges, readerDetail, investigateOnlyComponents, investigateOnlyEdges } from './fixtures';
8
+ import { components, graphSpecFromEdges, readerDetail, investigateOnlyComponents, investigateOnlyRelations, investigateOnlyWalkthroughs } from './fixtures';
9
9
 
10
10
  const meta = {
11
11
  title: 'Subsystem/ComponentGraph/Captures',
@@ -37,7 +37,7 @@ const v2ReaderComponents = components([
37
37
  ['registry', 'supported-agents', 'module', 'supported-agents.ts', 'pkg:github/principal-ai/agent-monitoring', 'registry of supported agents (the shared seam)', 'registerAgent'],
38
38
  ]);
39
39
 
40
- const v2ReaderEdges = edges([
40
+ const v2ReaderEdges = graphSpecFromEdges([
41
41
  ['transcript', 'reader', 'imports'],
42
42
  ['paths', 'reader', 'imports'],
43
43
  ['capture', 'reader', 'calls'],
@@ -55,7 +55,7 @@ function V2ReaderDemo() {
55
55
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
56
56
  <SubsystemComponentGraph
57
57
  components={v2ReaderComponents}
58
- edges={v2ReaderEdges}
58
+ relations={v2ReaderEdges.relations} walkthroughs={v2ReaderEdges.walkthroughs}
59
59
  onSelect={(id) => setSelected(id)}
60
60
  onEdgeSelect={(e) => setSelectedEdge(e)}
61
61
  />
@@ -80,7 +80,7 @@ export const V2ReaderSubsystem: Story = {
80
80
  export const InvestigateOnly: Story = {
81
81
  render: () => (
82
82
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
83
- <SubsystemComponentGraph components={investigateOnlyComponents} edges={investigateOnlyEdges} />
83
+ <SubsystemComponentGraph components={investigateOnlyComponents} relations={investigateOnlyRelations} walkthroughs={investigateOnlyWalkthroughs} />
84
84
  </div>
85
85
  ),
86
86
  };
@@ -98,7 +98,7 @@ const minimalComponents = components([
98
98
  ['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
99
99
  ]);
100
100
 
101
- const sharedEdges = edges([
101
+ const sharedEdges = graphSpecFromEdges([
102
102
  ['transcript', 'record', 'defines'],
103
103
  ['reader', 'normalize', 'method'],
104
104
  ['normalize', 'record', 'references'],
@@ -106,10 +106,10 @@ const sharedEdges = edges([
106
106
 
107
107
  /** The same subsystem after `resolveSubsystemToGraphify` populates `detail`. */
108
108
  const resolvedComponents: SubsystemComponent[] = [
109
- { ...minimalComponents[0], detail: readerDetail },
109
+ { ...minimalComponents[0], declaration: readerDetail },
110
110
  {
111
111
  ...minimalComponents[1],
112
- detail: {
112
+ declaration: {
113
113
  kind: 'function',
114
114
  parameters: [{ name: 'session', type: 'SessionRecord' }],
115
115
  returnType: 'SessionEvent[]',
@@ -119,7 +119,7 @@ const resolvedComponents: SubsystemComponent[] = [
119
119
  },
120
120
  {
121
121
  ...minimalComponents[2],
122
- detail: {
122
+ declaration: {
123
123
  kind: 'type',
124
124
  properties: [
125
125
  { name: 'id', type: 'string' },
@@ -131,7 +131,7 @@ const resolvedComponents: SubsystemComponent[] = [
131
131
  },
132
132
  {
133
133
  ...minimalComponents[3],
134
- detail: {
134
+ declaration: {
135
135
  kind: 'module',
136
136
  exports: ['CodexRolloutRecord', 'CodexSessionMeta'],
137
137
  imports: [{ nodeId: 'i1', name: 'paths', relation: 'imports_from' }],
@@ -146,12 +146,12 @@ function MinimalVsResolvedDemo({ resolved }: { resolved: boolean }) {
146
146
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
147
147
  <SubsystemComponentGraph
148
148
  components={resolved ? resolvedComponents : minimalComponents}
149
- edges={sharedEdges}
149
+ relations={sharedEdges.relations} walkthroughs={sharedEdges.walkthroughs}
150
150
  onSelect={(id) => setSelected(id)}
151
151
  />
152
152
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
153
153
  {resolved
154
- ? 'post-graphify: click a component to see the enriched GraphifyComponentDetail'
154
+ ? 'post-graphify: click a component to see the enriched declaration'
155
155
  : 'pre-graphify: LLM-authored symbols only — no detail yet'}
156
156
  </div>
157
157
  </div>
@@ -179,7 +179,7 @@ const investigationComponents: SubsystemComponent[] = [
179
179
  purl: 'pkg:github/t3code/t3code',
180
180
  purpose: 'adapts opencode session/threads + events to the t3 runtime',
181
181
  symbol: 'makeOpenCodeAdapter',
182
- detail: {
182
+ declaration: {
183
183
  kind: 'module',
184
184
  exports: ['makeOpenCodeAdapter', 'OpenCodeAdapterLiveOptions'],
185
185
  imports: [{ nodeId: 'i1', name: 'orchestration', relation: 'imports_from' }],
@@ -206,7 +206,7 @@ const investigationComponents: SubsystemComponent[] = [
206
206
  },
207
207
  ];
208
208
 
209
- const investigationEdges = edges([
209
+ const investigationEdges = graphSpecFromEdges([
210
210
  ['adapter', 'contracts', 'imports_from'],
211
211
  ['ingestion', 'adapter', 'uses'],
212
212
  ['ingestion', 'contracts', 'references'],
@@ -218,7 +218,7 @@ function InvestigationDemo() {
218
218
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
219
219
  <SubsystemComponentGraph
220
220
  components={investigationComponents}
221
- edges={investigationEdges}
221
+ relations={investigationEdges.relations} walkthroughs={investigationEdges.walkthroughs}
222
222
  onSelect={(id) => setSelected(id)}
223
223
  />
224
224
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
@@ -5,6 +5,7 @@ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme
5
5
  import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
6
6
  import type { SubsystemComponent, SubsystemComponentEdge } from '../../../subsystem/model';
7
7
  import type { GraphifyCustomEntityDetail } from '../../../graphify';
8
+ import { graphSpecFromEdges } from './fixtures';
8
9
 
9
10
  /** Authored attributes surfaced in the declaration panel. */
10
11
  function entityDetail(attributes: Array<[string, string]>): GraphifyCustomEntityDetail {
@@ -32,7 +33,7 @@ const components: SubsystemComponent[] = [
32
33
  purl: 'external',
33
34
  purpose: 'submits a facilities work request',
34
35
  role: 'entry',
35
- detail: entityDetail([
36
+ declaration: entityDetail([
36
37
  ['vertical', 'buildings'],
37
38
  ['escalationPath', 'FacilitiesTechnician → ShiftSupervisor'],
38
39
  ]),
@@ -47,7 +48,7 @@ const components: SubsystemComponent[] = [
47
48
  purpose: 'performs repairs, resolves L1 requests',
48
49
  process: 'novatech/core-ops',
49
50
  layer: 1,
50
- detail: entityDetail([
51
+ declaration: entityDetail([
51
52
  ['level', 'L1'],
52
53
  ['projects', 'HVAC, plumbing'],
53
54
  ]),
@@ -62,7 +63,7 @@ const components: SubsystemComponent[] = [
62
63
  purpose: 'assigns technicians, approves out-of-scope work',
63
64
  process: 'novatech/core-ops',
64
65
  layer: 2,
65
- detail: entityDetail([
66
+ declaration: entityDetail([
66
67
  ['level', 'L2'],
67
68
  ['approvalLimit', '$500'],
68
69
  ]),
@@ -77,7 +78,7 @@ const components: SubsystemComponent[] = [
77
78
  purpose: 'owns the queue, escalates campus-wide issues',
78
79
  process: 'novatech/core-ops',
79
80
  layer: 3,
80
- detail: entityDetail([
81
+ declaration: entityDetail([
81
82
  ['level', 'L3'],
82
83
  ['approvalLimit', '$5,000'],
83
84
  ]),
@@ -92,7 +93,7 @@ const components: SubsystemComponent[] = [
92
93
  purpose: 'funds large projects, signs off L4 requests',
93
94
  process: 'novatech/core-ops',
94
95
  layer: 4,
95
- detail: entityDetail([
96
+ declaration: entityDetail([
96
97
  ['level', 'L4'],
97
98
  ['approvalLimit', 'unlimited'],
98
99
  ]),
@@ -108,7 +109,7 @@ const components: SubsystemComponent[] = [
108
109
  purpose: 'proposes nudges from open-request patterns; never owns the queue',
109
110
  process: 'novatech/core-ops',
110
111
  layer: 2,
111
- detail: entityDetail([
112
+ declaration: entityDetail([
112
113
  ['slack', 'novatech/facilities-ops'],
113
114
  ['permission', 'propose-only'],
114
115
  ]),
@@ -124,7 +125,7 @@ const components: SubsystemComponent[] = [
124
125
  purpose: 'holds proposed nudges until a supervisor confirms them',
125
126
  process: 'novatech/core-ops',
126
127
  layer: 3,
127
- detail: entityDetail([
128
+ declaration: entityDetail([
128
129
  ['durable', 'postgres + outbox'],
129
130
  ['owner', 'CampusOpsManager'],
130
131
  ]),
@@ -142,7 +143,7 @@ const components: SubsystemComponent[] = [
142
143
  },
143
144
  ];
144
145
 
145
- const edges: SubsystemComponentEdge[] = [
146
+ const entityGraph = graphSpecFromEdges([
146
147
  ['wr', 'store', 'feeds'],
147
148
  ['store', 'tech', 'feeds'],
148
149
  ['tech', 'sup', 'watches'],
@@ -151,7 +152,7 @@ const edges: SubsystemComponentEdge[] = [
151
152
  ['agent', 'queue', 'feeds'],
152
153
  ['queue', 'mgr', 'feeds'],
153
154
  ['mgr', 'vp', 'watches'],
154
- ].map(([from, to, mechanism], i) => ({ id: `e${i}`, from, to, mechanism }));
155
+ ]);
155
156
 
156
157
  const meta = {
157
158
  title: 'Subsystem/ComponentGraph/CustomEntities',
@@ -177,7 +178,7 @@ export const NovaTechWorkRequests: Story = {
177
178
  title="Custom entities — NovaTech work-request chain"
178
179
  description="Persons, an agent, and a queue as `custom_entity` nodes (badge = entityKind). Actors keep the themed coral; the agent and queue wear authored `color` overrides. Click a node for its declaration — `entity 'Name' — kind` plus authored `attributes` (key: value)."
179
180
  components={components}
180
- edges={edges}
181
+ relations={entityGraph.relations} walkthroughs={entityGraph.walkthroughs}
181
182
  />
182
183
  </div>
183
184
  ),
@@ -31,7 +31,7 @@ export default meta;
31
31
  type Story = StoryObj<typeof meta>;
32
32
 
33
33
  // ---------------------------------------------------------------------------
34
- // One node per GraphifyComponentDetail kind — what each looks like + drills down
34
+ // One node per declaration kind — what each looks like + drills down
35
35
  // ---------------------------------------------------------------------------
36
36
  const detailKindComponents: SubsystemComponent[] = [
37
37
  {
@@ -42,7 +42,7 @@ const detailKindComponents: SubsystemComponent[] = [
42
42
  purl: 'pkg:github/principal-ai/agent-monitoring',
43
43
  purpose: 'class-like: owns outgoing method edges',
44
44
  symbol: '',
45
- detail: readerDetail,
45
+ declaration: readerDetail,
46
46
  },
47
47
  {
48
48
  id: 'detail-method',
@@ -52,7 +52,7 @@ const detailKindComponents: SubsystemComponent[] = [
52
52
  purl: 'pkg:github/principal-ai/agent-monitoring',
53
53
  purpose: 'a class method — the specific thing this session focused on',
54
54
  symbol: 'SessionReader.normalize',
55
- detail: {
55
+ declaration: {
56
56
  kind: 'function',
57
57
  parameters: [{ name: 'session', type: 'SessionRecord' }],
58
58
  returnType: 'SessionEvent[]',
@@ -68,7 +68,7 @@ const detailKindComponents: SubsystemComponent[] = [
68
68
  purl: 'pkg:github/principal-ai/agent-monitoring',
69
69
  purpose: 'function-like: label ends () with no method edges',
70
70
  symbol: 'normalizeSession',
71
- detail: {
71
+ declaration: {
72
72
  kind: 'function',
73
73
  parameters: [
74
74
  { name: 'session', type: 'SessionRecord' },
@@ -87,7 +87,7 @@ const detailKindComponents: SubsystemComponent[] = [
87
87
  purl: 'pkg:github/principal-ai/agent-monitoring',
88
88
  purpose: 'multi-param signature — named, positional (graphify captures types only), union types, generic return',
89
89
  symbol: 'mergeSessions',
90
- detail: {
90
+ declaration: {
91
91
  kind: 'function',
92
92
  parameters: [
93
93
  { name: 'sessions', type: 'SessionRecord[]' },
@@ -111,7 +111,7 @@ const detailKindComponents: SubsystemComponent[] = [
111
111
  purl: 'pkg:github/principal-ai/agent-monitoring',
112
112
  purpose: 'no parameters, no return type — the barest function signature',
113
113
  symbol: 'flush',
114
- detail: {
114
+ declaration: {
115
115
  kind: 'function',
116
116
  parameters: [],
117
117
  callers: [{ nodeId: 'c4', name: 'EventProcessor.dispose', source_location: 'L142' }],
@@ -126,7 +126,7 @@ const detailKindComponents: SubsystemComponent[] = [
126
126
  purl: 'pkg:github/principal-ai/agent-monitoring',
127
127
  purpose: 'class with fully-typed members — method params + returns, field types, extends + implements',
128
128
  symbol: 'EventProcessor',
129
- detail: {
129
+ declaration: {
130
130
  kind: 'class',
131
131
  methods: [
132
132
  { nodeId: 'rm1', name: 'process', parameters: [{ type: 'RawEvent' }, { type: 'ProcessingOptions' }], returnType: 'ProcessedEvent' },
@@ -156,7 +156,7 @@ const detailKindComponents: SubsystemComponent[] = [
156
156
  purl: 'pkg:github/principal-ai/agent-monitoring',
157
157
  purpose: 'type-like: revealed by incoming implements edges',
158
158
  symbol: 'SessionRecord',
159
- detail: {
159
+ declaration: {
160
160
  kind: 'type',
161
161
  properties: [
162
162
  { name: 'id', type: 'string' },
@@ -174,7 +174,7 @@ const detailKindComponents: SubsystemComponent[] = [
174
174
  purl: 'pkg:github/principal-ai/agent-monitoring',
175
175
  purpose: 'a type symbol that lives in the transcript module; the node is the symbol, the file is its location',
176
176
  symbol: 'CodexRolloutRecord',
177
- detail: {
177
+ declaration: {
178
178
  kind: 'type',
179
179
  properties: [
180
180
  { name: 'type', type: 'string' },
@@ -193,14 +193,13 @@ const detailKindComponents: SubsystemComponent[] = [
193
193
  purl: 'pkg:npm/@principal-ai/subsystems-studio',
194
194
  purpose: 'an npm package consumer — the whole package as a node',
195
195
  symbol: '',
196
- detail: {
196
+ declaration: {
197
197
  kind: 'external',
198
198
  label: 'pkg:npm/@principal-ai/subsystems-studio',
199
199
  } satisfies GraphifyComponentDetail,
200
200
  },
201
201
  ];
202
202
 
203
- const detailKindEdges: SubsystemComponentEdge[] = [];
204
203
 
205
204
  function DetailKindsDemo() {
206
205
  const [selected, setSelected] = useState<string | null>(null);
@@ -208,11 +207,11 @@ function DetailKindsDemo() {
208
207
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
209
208
  <SubsystemComponentGraph
210
209
  components={detailKindComponents}
211
- edges={detailKindEdges}
210
+ relations={[]}
212
211
  onSelect={(id) => setSelected(id)}
213
212
  />
214
213
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
215
- {selected ? `selected: ${selected}` : 'click a component to see its GraphifyComponentDetail'}
214
+ {selected ? `selected: ${selected}` : 'click a component to see its declaration'}
216
215
  </div>
217
216
  </div>
218
217
  );
@@ -303,7 +302,7 @@ function DeclarationLineOpenDemo() {
303
302
  title="Declaration line open (Storybook)"
304
303
  description="Uses bundled ?raw fixtures + PierreSnippetView from this package. Select ComponentDeclaration, toggle file, click the path or L251."
305
304
  components={declarationOpenComponents}
306
- edges={[]}
305
+ relations={[]}
307
306
  renderFileViewer={renderFileViewer}
308
307
  />
309
308
  </div>