@principal-ai/subsystems-react 0.42.0 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/stories/Subsystem/C4Graph/c4Fixture.js +1 -1
  6. package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +1 -1
  7. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +6 -9
  8. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -1
  9. package/dist/stories/Subsystem/ComponentGraph/fixtures.js +15 -50
  10. package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -1
  11. package/dist/subsystem/C4Graph.d.ts +2 -3
  12. package/dist/subsystem/C4Graph.d.ts.map +1 -1
  13. package/dist/subsystem/C4Graph.js +2 -3
  14. package/dist/subsystem/C4Graph.js.map +1 -1
  15. package/dist/subsystem/IssueList.d.ts +5 -5
  16. package/dist/subsystem/IssueList.d.ts.map +1 -1
  17. package/dist/subsystem/IssueList.js +9 -18
  18. package/dist/subsystem/IssueList.js.map +1 -1
  19. package/dist/subsystem/SubsystemComponentGraph.d.ts +16 -12
  20. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  21. package/dist/subsystem/SubsystemComponentGraph.js +99 -113
  22. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  23. package/dist/subsystem/SubsystemFileTree.d.ts +5 -5
  24. package/dist/subsystem/SubsystemFileTree.d.ts.map +1 -1
  25. package/dist/subsystem/SubsystemFileTree.js +13 -49
  26. package/dist/subsystem/SubsystemFileTree.js.map +1 -1
  27. package/dist/subsystem/model.d.ts +67 -53
  28. package/dist/subsystem/model.d.ts.map +1 -1
  29. package/dist/subsystem/model.js +305 -55
  30. package/dist/subsystem/model.js.map +1 -1
  31. package/dist/subsystem/nodes.d.ts.map +1 -1
  32. package/dist/subsystem/nodes.js +11 -4
  33. package/dist/subsystem/nodes.js.map +1 -1
  34. package/dist/subsystem/toC4.d.ts +4 -4
  35. package/dist/subsystem/toC4.d.ts.map +1 -1
  36. package/dist/subsystem/toC4.js +3 -7
  37. package/dist/subsystem/toC4.js.map +1 -1
  38. package/dist/utils/elkLayout.d.ts.map +1 -1
  39. package/dist/utils/elkLayout.js +7 -0
  40. package/dist/utils/elkLayout.js.map +1 -1
  41. package/package.json +3 -3
  42. package/src/index.ts +0 -4
  43. package/src/stories/Subsystem/AgentsPanel.stories.tsx +3 -5
  44. package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +1 -4
  45. package/src/stories/Subsystem/C4Graph/c4Fixture.ts +1 -1
  46. package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +2 -4
  47. package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +8 -8
  48. package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +19 -19
  49. package/src/stories/Subsystem/ComponentGraph/Constructs.stories.tsx +0 -1
  50. package/src/stories/Subsystem/ComponentGraph/CustomEntities.stories.tsx +3 -3
  51. package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +0 -2
  52. package/src/stories/Subsystem/ComponentGraph/Diagnostics.stories.tsx +2 -6
  53. package/src/stories/Subsystem/ComponentGraph/EdgeViews.stories.tsx +21 -21
  54. package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +0 -3
  55. package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +30 -32
  56. package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +4 -4
  57. package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +1 -26
  58. package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +3 -25
  59. package/src/stories/Subsystem/ComponentGraph/ModuleBadges.stories.tsx +7 -8
  60. package/src/stories/Subsystem/ComponentGraph/ModulePathNesting.stories.tsx +116 -0
  61. package/src/stories/Subsystem/ComponentGraph/Modules.stories.tsx +9 -11
  62. package/src/stories/Subsystem/ComponentGraph/Packages.stories.tsx +3 -6
  63. package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +3 -3
  64. package/src/stories/Subsystem/ComponentGraph/Proposed.stories.tsx +8 -6
  65. package/src/stories/Subsystem/ComponentGraph/ProposedWalkthroughs.stories.tsx +0 -1
  66. package/src/stories/Subsystem/ComponentGraph/Reorder.stories.tsx +0 -1
  67. package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +26 -28
  68. package/src/stories/Subsystem/ComponentGraph/WalkthroughAutoplay.stories.tsx +0 -1
  69. package/src/stories/Subsystem/ComponentGraph/WorkspacePackageFrames.stories.tsx +2 -3
  70. package/src/stories/Subsystem/ComponentGraph/fixtures.ts +18 -58
  71. package/src/stories/Subsystem/EgoGraph/EgoGraph.stories.tsx +0 -2
  72. package/src/subsystem/C4Graph.tsx +2 -3
  73. package/src/subsystem/IssueList.tsx +12 -22
  74. package/src/subsystem/SubsystemComponentGraph.tsx +117 -135
  75. package/src/subsystem/SubsystemFileTree.tsx +17 -50
  76. package/src/subsystem/model.test.ts +155 -24
  77. package/src/subsystem/model.ts +352 -108
  78. package/src/subsystem/nodes.tsx +13 -3
  79. package/src/subsystem/toC4.test.ts +5 -12
  80. package/src/subsystem/toC4.ts +5 -9
  81. package/src/utils/elkLayout.ts +10 -0
@@ -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, investigateOnlyRelations, investigateOnlyWalkthroughs } from './fixtures';
8
+ import { investigateOnlyComponents, 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
- relations={investigateOnlyRelations} walkthroughs={investigateOnlyWalkthroughs}
35
+ walkthroughs={investigateOnlyWalkthroughs}
36
36
  maxNodeWidth={140}
37
37
  />
38
38
  </div>
@@ -101,7 +101,6 @@ export const NamingConventions: Story = {
101
101
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
102
102
  <SubsystemComponentGraph
103
103
  components={namingConventionComponents}
104
- relations={[]}
105
104
  maxNodeWidth={180}
106
105
  />
107
106
  </div>
@@ -303,7 +302,6 @@ function KindVariationsDemo() {
303
302
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
304
303
  <SubsystemComponentGraph
305
304
  components={kindVariationComponents}
306
- relations={[]}
307
305
  onSelect={(id) => setSelected(id)}
308
306
  />
309
307
  <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, graphSpecFromEdges } from './fixtures';
7
+ import { components, graphSpecFromHops } from './fixtures';
8
8
 
9
9
  const meta = {
10
10
  title: 'Subsystem/ComponentGraph/Basics',
@@ -33,8 +33,8 @@ 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 = graphSpecFromEdges([
37
- ['src', 'dst', 'method'],
36
+ const twoNodeEdges = graphSpecFromHops([
37
+ ['src', 'dst', 'calls'],
38
38
  ]);
39
39
 
40
40
  function TwoNodeDemo({ showEdgeLabels = true }: { showEdgeLabels?: boolean }) {
@@ -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
- relations={twoNodeEdges.relations} walkthroughs={twoNodeEdges.walkthroughs}
47
+ walkthroughs={twoNodeEdges.walkthroughs}
48
48
  onSelect={(id) => setSelected(id)}
49
49
  onEdgeSelect={(e) => setSelectedEdge(e)}
50
50
  showEdgeLabels={showEdgeLabels}
@@ -99,14 +99,14 @@ function PlaygroundDemo({ leftCount, rightCount, showEdgeLabels }: { leftCount:
99
99
 
100
100
  for (let i = 0; i < leftCount; i++) {
101
101
  for (let j = 0; j < rightCount; j++) {
102
- edgeSpec.push([`l${i}`, `r${j}`, 'method']);
102
+ edgeSpec.push([`l${i}`, `r${j}`, 'calls']);
103
103
  }
104
104
  }
105
- const graph = graphSpecFromEdges(edgeSpec);
105
+ const graph = graphSpecFromHops(edgeSpec);
106
106
 
107
107
  return (
108
108
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
109
- <SubsystemComponentGraph components={comps} relations={graph.relations} walkthroughs={graph.walkthroughs} showEdgeLabels={showEdgeLabels} />
109
+ <SubsystemComponentGraph components={comps} 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={[]} relations={[]} />
134
+ <SubsystemComponentGraph components={[]} />
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, graphSpecFromEdges, readerDetail, investigateOnlyComponents, investigateOnlyRelations, investigateOnlyWalkthroughs } from './fixtures';
8
+ import { components, graphSpecFromHops, readerDetail, investigateOnlyComponents, investigateOnlyWalkthroughs } from './fixtures';
9
9
 
10
10
  const meta = {
11
11
  title: 'Subsystem/ComponentGraph/Captures',
@@ -37,15 +37,15 @@ const v2ReaderComponents = components([
37
37
  ['registry', 'supported-agents', 'function', 'supported-agents.ts', 'pkg:github/principal-ai/agent-monitoring', 'registry of supported agents (the shared seam)', 'registerAgent'],
38
38
  ]);
39
39
 
40
- const v2ReaderEdges = graphSpecFromEdges([
41
- ['transcript', 'reader', 'method'],
42
- ['paths', 'reader', 'method'],
40
+ const v2ReaderEdges = graphSpecFromHops([
41
+ ['transcript', 'reader', 'calls'],
42
+ ['paths', 'reader', 'uses'],
43
43
  ['capture', 'reader', 'calls'],
44
- ['reader', 'registry', 'registers-into', ['supported-agents.ts']],
44
+ ['reader', 'registry', 'registers-into'],
45
45
  // Consumer packages - cross-package edges leave the subgraph
46
- ['reader', 'principal-studio-host', 'method'],
47
- ['reader', 'core-sessions', 'method'],
48
- ['reader', 'cli-session', 'method'],
46
+ ['reader', 'principal-studio-host', 'calls'],
47
+ ['reader', 'core-sessions', 'uses'],
48
+ ['reader', 'cli-session', 'uses'],
49
49
  ]);
50
50
 
51
51
  function V2ReaderDemo() {
@@ -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
- relations={v2ReaderEdges.relations} walkthroughs={v2ReaderEdges.walkthroughs}
58
+ 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} relations={investigateOnlyRelations} walkthroughs={investigateOnlyWalkthroughs} />
83
+ <SubsystemComponentGraph components={investigateOnlyComponents} walkthroughs={investigateOnlyWalkthroughs} />
84
84
  </div>
85
85
  ),
86
86
  };
@@ -98,10 +98,10 @@ const minimalComponents = components([
98
98
  ['transcript', 'transcript', 'function', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
99
99
  ]);
100
100
 
101
- const sharedEdges = graphSpecFromEdges([
102
- ['transcript', 'record', 'method'],
103
- ['reader', 'normalize', 'method'],
104
- ['normalize', 'record', 'method'],
101
+ const sharedEdges = graphSpecFromHops([
102
+ ['transcript', 'record', 'uses'],
103
+ ['reader', 'normalize', 'calls'],
104
+ ['normalize', 'record', 'uses'],
105
105
  ]);
106
106
 
107
107
  /** The same subsystem after `resolveSubsystemToGraphify` populates `detail`. */
@@ -137,7 +137,7 @@ function MinimalVsResolvedDemo({ resolved }: { resolved: boolean }) {
137
137
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
138
138
  <SubsystemComponentGraph
139
139
  components={resolved ? resolvedComponents : minimalComponents}
140
- relations={sharedEdges.relations} walkthroughs={sharedEdges.walkthroughs}
140
+ walkthroughs={sharedEdges.walkthroughs}
141
141
  onSelect={(id) => setSelected(id)}
142
142
  />
143
143
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
@@ -191,10 +191,10 @@ const investigationComponents: SubsystemComponent[] = [
191
191
  },
192
192
  ];
193
193
 
194
- const investigationEdges = graphSpecFromEdges([
195
- ['adapter', 'contracts', 'method'],
194
+ const investigationEdges = graphSpecFromHops([
195
+ ['adapter', 'contracts', 'uses'],
196
196
  ['ingestion', 'adapter', 'uses'],
197
- ['ingestion', 'contracts', 'method'],
197
+ ['ingestion', 'contracts', 'uses'],
198
198
  ]);
199
199
 
200
200
  function InvestigationDemo() {
@@ -203,7 +203,7 @@ function InvestigationDemo() {
203
203
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
204
204
  <SubsystemComponentGraph
205
205
  components={investigationComponents}
206
- relations={investigationEdges.relations} walkthroughs={investigationEdges.walkthroughs}
206
+ walkthroughs={investigationEdges.walkthroughs}
207
207
  onSelect={(id) => setSelected(id)}
208
208
  />
209
209
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
@@ -260,7 +260,6 @@ function CatalogDemo({ hideSidebar = false }: { hideSidebar?: boolean }) {
260
260
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
261
261
  <SubsystemComponentGraph
262
262
  components={constructsOnly}
263
- relations={[]}
264
263
  title="Constructs at a glance"
265
264
  description="Layer 1 — constructs only. Click a file path or L# to open the declaration source."
266
265
  hideSidebar={hideSidebar}
@@ -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 { GraphifyCustomEntityDetail } from '../../../graphify';
8
- import { graphSpecFromEdges } from './fixtures';
8
+ import { graphSpecFromHops } from './fixtures';
9
9
 
10
10
  /** Authored attributes surfaced in the declaration panel. */
11
11
  function entityDetail(attributes: Array<[string, string]>): GraphifyCustomEntityDetail {
@@ -143,7 +143,7 @@ const components: SubsystemComponent[] = [
143
143
  },
144
144
  ];
145
145
 
146
- const entityGraph = graphSpecFromEdges([
146
+ const entityGraph = graphSpecFromHops([
147
147
  ['wr', 'store', 'feeds'],
148
148
  ['store', 'tech', 'feeds'],
149
149
  ['tech', 'sup', 'watches'],
@@ -178,7 +178,7 @@ export const NovaTechWorkRequests: Story = {
178
178
  title="Custom entities — NovaTech work-request chain"
179
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)."
180
180
  components={components}
181
- relations={entityGraph.relations} walkthroughs={entityGraph.walkthroughs}
181
+ walkthroughs={entityGraph.walkthroughs}
182
182
  />
183
183
  </div>
184
184
  ),
@@ -207,7 +207,6 @@ function DetailKindsDemo() {
207
207
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
208
208
  <SubsystemComponentGraph
209
209
  components={detailKindComponents}
210
- relations={[]}
211
210
  onSelect={(id) => setSelected(id)}
212
211
  />
213
212
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
@@ -303,7 +302,6 @@ 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
- relations={[]}
307
305
  renderFileViewer={renderFileViewer}
308
306
  />
309
307
  </div>
@@ -7,7 +7,7 @@ import {
7
7
  SubsystemDiagnosticToggle,
8
8
  type SubsystemDiagnosticStatus,
9
9
  } from '../../../subsystem/DiagnosticToggle';
10
- import { components, graphSpecFromEdges } from './fixtures';
10
+ import { components, graphSpecFromHops } from './fixtures';
11
11
 
12
12
  const meta = {
13
13
  title: 'Subsystem/ComponentGraph/Diagnostics',
@@ -34,7 +34,7 @@ const graphComponents = components([
34
34
  ['caller', 'Web client', 'external', '', 'external', undefined, undefined],
35
35
  ]);
36
36
 
37
- const graphEdges = graphSpecFromEdges([
37
+ const graphEdges = graphSpecFromHops([
38
38
  ['caller', 'entry', 'calls'],
39
39
  ['entry', 'store', 'writes'],
40
40
  ['entry', 'stripe', 'calls'],
@@ -81,7 +81,6 @@ export const GraphClean: Story = {
81
81
  <div style={{ width: '100%', height: '100vh' }}>
82
82
  <SubsystemComponentGraph
83
83
  components={graphComponents}
84
- relations={graphEdges.relations}
85
84
  walkthroughs={graphEdges.walkthroughs}
86
85
  title="Checkout"
87
86
  description={GRAPH_DESCRIPTION}
@@ -96,7 +95,6 @@ export const GraphWithIssues: Story = {
96
95
  <div style={{ width: '100%', height: '100vh' }}>
97
96
  <SubsystemComponentGraph
98
97
  components={graphComponents}
99
- relations={graphEdges.relations}
100
98
  walkthroughs={graphEdges.walkthroughs}
101
99
  title="Checkout"
102
100
  description={GRAPH_DESCRIPTION}
@@ -112,7 +110,6 @@ export const GraphStale: Story = {
112
110
  <div style={{ width: '100%', height: '100vh' }}>
113
111
  <SubsystemComponentGraph
114
112
  components={graphComponents}
115
- relations={graphEdges.relations}
116
113
  walkthroughs={graphEdges.walkthroughs}
117
114
  title="Checkout"
118
115
  description={GRAPH_DESCRIPTION}
@@ -128,7 +125,6 @@ export const GraphChipOnly: Story = {
128
125
  <div style={{ width: '100%', height: '100vh' }}>
129
126
  <SubsystemComponentGraph
130
127
  components={graphComponents}
131
- relations={graphEdges.relations}
132
128
  walkthroughs={graphEdges.walkthroughs}
133
129
  title="Checkout"
134
130
  diagnostic={{ status: 'gaps', issueCount: 2, onToggle: () => {} }}
@@ -3,8 +3,8 @@ import '@xyflow/react/dist/style.css';
3
3
  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
- import type { SubsystemEdgeView } from '../../../subsystem/model';
7
- import { components, relations, walkthroughFromHops } from './fixtures';
6
+ import type { SubsystemEdgeView, SubsystemGraphifyRelation } from '../../../subsystem/model';
7
+ import { components, walkthroughFromHops } from './fixtures';
8
8
 
9
9
  const meta = {
10
10
  title: 'Subsystem/ComponentGraph/EdgeViews',
@@ -26,11 +26,11 @@ export default meta;
26
26
  type Story = StoryObj<typeof meta>;
27
27
 
28
28
  // ---------------------------------------------------------------------------
29
- // A graph that carries BOTH vocabularies between overlapping node pairs:
30
- // svc --references--> reader (topology)
31
- // svc --calls--> reader (runtime hop)
32
- // store --references--> db (topology)
33
- // store --calls--> db (runtime hop)
29
+ // A graph that carries BOTH edge sources between overlapping node pairs:
30
+ // svc --references--> reader (graphify static edge)
31
+ // svc --calls--> reader (runtime hop)
32
+ // store --references--> db (graphify static edge)
33
+ // store --calls--> db (runtime hop)
34
34
  // so switching the label view visibly changes which labels appear.
35
35
  // ---------------------------------------------------------------------------
36
36
  const labelViewComponents = components([
@@ -42,12 +42,12 @@ const labelViewComponents = components([
42
42
  ['db', 'PostgresStore', 'external', 'src/db/PostgresStore.ts', 'pkg:github/principal-ai/agent-monitoring', 'external persistence driver', 'PostgresStore'],
43
43
  ]);
44
44
 
45
- const labelViewRelations = relations([
46
- ['svc', 'reader', 'method'],
47
- ['svc', 'event', 'method'],
48
- ['store', 'db', 'method'],
49
- ['reader', 'event', 'method'],
50
- ]);
45
+ const labelViewGraphify: SubsystemGraphifyRelation[] = [
46
+ { id: 'g-svc-reader', from: 'svc', to: 'reader', relation: 'references' },
47
+ { id: 'g-svc-event', from: 'svc', to: 'event', relation: 'references' },
48
+ { id: 'g-store-db', from: 'store', to: 'db', relation: 'references' },
49
+ { id: 'g-reader-event', from: 'reader', to: 'event', relation: 'references' },
50
+ ];
51
51
 
52
52
  const labelViewWalkthroughs = [
53
53
  walkthroughFromHops('tl-capture', 'Capture session', [
@@ -63,12 +63,12 @@ const labelViewWalkthroughs = [
63
63
  ];
64
64
 
65
65
  const VIEWS: { value: SubsystemEdgeView; label: string }[] = [
66
- { value: 'relations', label: 'Relations' },
66
+ { value: 'graphify', label: 'Graphify' },
67
67
  { value: 'walkthroughs', label: 'Walkthroughs' },
68
68
  ];
69
69
 
70
70
  function EdgeViewDemo() {
71
- const [view, setView] = useState<SubsystemEdgeView>('relations');
71
+ const [view, setView] = useState<SubsystemEdgeView>('graphify');
72
72
  const [showEdgeLabels, setShowEdgeLabels] = useState(true);
73
73
 
74
74
  return (
@@ -118,10 +118,10 @@ function EdgeViewDemo() {
118
118
  <div style={{ flex: 1, minHeight: 0 }}>
119
119
  <SubsystemComponentGraph
120
120
  components={labelViewComponents}
121
- relations={labelViewRelations}
121
+ graphifyRelations={labelViewGraphify}
122
122
  walkthroughs={labelViewWalkthroughs}
123
123
  title="edge views"
124
- description="The relation and walkthrough vocabularies are disjoint and never shown together. Toggle the view: **Relations** draws `svc --references--> reader`; **Walkthroughs** draws `svc --calls--> reader`. The model is the same either way."
124
+ description="The graphify and walkthrough edge sources are disjoint and never shown together. Toggle the view: **Graphify** draws `svc --references--> reader`; **Walkthroughs** draws `svc --calls--> reader`. The model is the same either way."
125
125
  showEdgeLabels={showEdgeLabels}
126
126
  edgeView={view}
127
127
  />
@@ -130,7 +130,7 @@ function EdgeViewDemo() {
130
130
  );
131
131
  }
132
132
 
133
- /** Interactive toggle between the `relations` and `walkthroughs` edge views. */
133
+ /** Interactive toggle between the `graphify` and `walkthroughs` edge views. */
134
134
  export const ToggleEdgeView: Story = {
135
135
  render: () => <EdgeViewDemo />,
136
136
  };
@@ -141,7 +141,7 @@ export const ViewControl: Story = {
141
141
  <div style={{ width: '100%', height: '100vh' }}>
142
142
  <SubsystemComponentGraph
143
143
  components={labelViewComponents}
144
- relations={labelViewRelations}
144
+ graphifyRelations={labelViewGraphify}
145
145
  walkthroughs={labelViewWalkthroughs}
146
146
  showEdgeLabels={args.showEdgeLabels}
147
147
  edgeView={args.edgeView}
@@ -150,10 +150,10 @@ export const ViewControl: Story = {
150
150
  ),
151
151
  args: {
152
152
  showEdgeLabels: true,
153
- edgeView: 'relations',
153
+ edgeView: 'graphify',
154
154
  },
155
155
  argTypes: {
156
156
  showEdgeLabels: { control: 'boolean' },
157
- edgeView: { control: 'inline-radio', options: ['relations', 'walkthroughs'] },
157
+ edgeView: { control: 'inline-radio', options: ['graphify', 'walkthroughs'] },
158
158
  },
159
159
  };
@@ -192,7 +192,6 @@ function FlowsDemo() {
192
192
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
193
193
  <SubsystemComponentGraph
194
194
  components={drawingComponents}
195
- relations={[]}
196
195
  walkthroughs={drawingWalkthroughs}
197
196
  title="drawing-files flow"
198
197
  description="Three walkthroughs over one graph — opening, saving, and deleting a drawing. The sidebar's **Walkthroughs** panel lists each step by **symbol**; clicking a step focuses that hop and scrolls the bottom CodeView to that snippet."
@@ -301,7 +300,6 @@ function ProposedMissingStepDemo() {
301
300
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
302
301
  <SubsystemComponentGraph
303
302
  components={proposedComponents}
304
- relations={[]}
305
303
  walkthroughs={proposedWalkthroughs}
306
304
  title="proposed seam with a missing file"
307
305
  description="Expand **Associate a finished run with its model** and click either step. The proposed hop has no file in the checkout, so its snippet shows an inline *Proposed — … isn't in the local checkout yet.* placeholder instead of failing the whole flow."
@@ -518,7 +516,6 @@ function ClickableConstructsDemo() {
518
516
  <div style={{ flex: 1, minHeight: 0 }}>
519
517
  <SubsystemComponentGraph
520
518
  components={clickableComponents}
521
- relations={[]}
522
519
  walkthroughs={clickableWalkthroughs}
523
520
  initialWalkthroughId="tl-load"
524
521
  title="clickable constructs"
@@ -2,7 +2,8 @@ import '@xyflow/react/dist/style.css';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
4
4
  import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
5
- import type { SubsystemComponent, SubsystemComponentEdge } from '../../../subsystem/model';
5
+ import type { SubsystemComponent } from '../../../subsystem/model';
6
+ import { walkthroughFromHops } from './fixtures';
6
7
 
7
8
  const meta = {
8
9
  title: 'Subsystem/ComponentGraph/FrameworkStereotype',
@@ -78,6 +79,19 @@ const reactUiComponents: SubsystemComponent[] = [
78
79
  process: 'principal-studio/renderer',
79
80
  layer: 2,
80
81
  },
82
+ {
83
+ alias: 'analysis-view',
84
+ name: 'AnalysisView',
85
+ construct: 'function',
86
+ file: 'packages/subsystems-studio/src/mainview/views/AnalysisView.tsx',
87
+ purl,
88
+ symbol: 'AnalysisView',
89
+ purpose: 'React component that consumes the graph document type',
90
+ framework: 'react',
91
+ stereotype: 'component',
92
+ process: 'principal-studio/renderer',
93
+ layer: 2,
94
+ },
81
95
  {
82
96
  alias: 'drawings-host',
83
97
  name: 'useDrawingsHost',
@@ -103,31 +117,13 @@ const reactUiComponents: SubsystemComponent[] = [
103
117
  },
104
118
  ];
105
119
 
106
- const reactUiEdges: SubsystemComponentEdge[] = [
107
- {
108
- id: 'http-to-create',
109
- from: 'http-entry',
110
- to: 'create-graph',
111
- mechanism: 'calls',
112
- },
113
- {
114
- id: 'sessions-uses-hook',
115
- from: 'sessions-view',
116
- to: 'drawings-host',
117
- mechanism: 'uses',
118
- },
119
- {
120
- id: 'analysis-uses-type',
121
- from: 'analysis-view',
122
- to: 'graph-doc-type',
123
- mechanism: 'references',
124
- },
125
- {
126
- id: 'sessions-to-analysis',
127
- from: 'sessions-view',
128
- to: 'analysis-view',
129
- mechanism: 'feeds',
130
- },
120
+ const reactUiWalkthroughs = [
121
+ walkthroughFromHops('react-ui-hops', 'React UI hops', [
122
+ ['http-entry', 'create-graph', 'calls', 'packages/subsystems-studio/src/bun/http-server.ts', 1],
123
+ ['sessions-view', 'drawings-host', 'uses', 'packages/subsystems-studio/src/mainview/views/AgentSessions.tsx', 1],
124
+ ['analysis-view', 'graph-doc-type', 'uses', 'packages/subsystems-studio/src/mainview/views/AnalysisView.tsx', 1],
125
+ ['sessions-view', 'analysis-view', 'feeds', 'packages/subsystems-studio/src/mainview/views/AgentSessions.tsx', 2],
126
+ ]),
131
127
  ];
132
128
 
133
129
  export const ReactComponentsAndHooks: Story = {
@@ -137,7 +133,7 @@ export const ReactComponentsAndHooks: Story = {
137
133
  title="Framework + stereotype"
138
134
  description="construct stays language-shaped (function / type_alias). framework + stereotype label React units as component / hook without inventing a react_component construct. Empty fields mean language-only."
139
135
  components={reactUiComponents}
140
- relations={reactUiEdges.relations} walkthroughs={reactUiEdges.walkthroughs}
136
+ walkthroughs={reactUiWalkthroughs}
141
137
  />
142
138
  </div>
143
139
  ),
@@ -196,10 +192,12 @@ const nestComponents: SubsystemComponent[] = [
196
192
  },
197
193
  ];
198
194
 
199
- const nestEdges: SubsystemComponentEdge[] = [
200
- { id: 'mw-to-guard', from: 'logging-mw', to: 'auth-guard', mechanism: 'uses' },
201
- { id: 'guard-to-ctrl', from: 'auth-guard', to: 'graphs-controller', mechanism: 'uses' },
202
- { id: 'ctrl-to-svc', from: 'graphs-controller', to: 'graphs-service', mechanism: 'calls' },
195
+ const nestWalkthroughs = [
196
+ walkthroughFromHops('nest-stack-hops', 'Nest controller stack hops', [
197
+ ['logging-mw', 'auth-guard', 'uses', 'src/logging/logging.middleware.ts', 1],
198
+ ['auth-guard', 'graphs-controller', 'uses', 'src/auth/auth.guard.ts', 1],
199
+ ['graphs-controller', 'graphs-service', 'calls', 'src/graphs/graphs.controller.ts', 1],
200
+ ]),
203
201
  ];
204
202
 
205
203
  export const NestControllerStack: Story = {
@@ -209,7 +207,7 @@ export const NestControllerStack: Story = {
209
207
  title="Nest framework stereotypes"
210
208
  description="Same optional fields work outside React: class/function constructs plus nestjs controller / guard / middleware / injectable stereotypes."
211
209
  components={nestComponents}
212
- relations={nestEdges.relations} walkthroughs={nestEdges.walkthroughs}
210
+ walkthroughs={nestWalkthroughs}
213
211
  />
214
212
  </div>
215
213
  ),
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  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
- import { components, graphSpecFromEdges, relations } from './fixtures';
6
+ import { components, graphSpecFromHops } from './fixtures';
7
7
 
8
8
  const meta = {
9
9
  title: 'Subsystem/ComponentGraph/GraphTitle',
@@ -30,7 +30,7 @@ const graphOnlyComponents = components([
30
30
  ['caller', 'Web client', 'external', '', 'external', undefined, undefined],
31
31
  ]);
32
32
 
33
- const graphOnlyEdges = graphSpecFromEdges([
33
+ const graphOnlyEdges = graphSpecFromHops([
34
34
  ['caller', 'entry', 'calls'],
35
35
  ['entry', 'store', 'writes'],
36
36
  ['entry', 'stripe', 'calls'],
@@ -41,7 +41,7 @@ function GraphOnly() {
41
41
  <div style={{ width: '100%', height: '100vh' }}>
42
42
  <SubsystemComponentGraph
43
43
  components={graphOnlyComponents}
44
- relations={graphOnlyEdges.relations} walkthroughs={graphOnlyEdges.walkthroughs}
44
+ walkthroughs={graphOnlyEdges.walkthroughs}
45
45
  graphTitle="Checkout"
46
46
  hideSidebar
47
47
  />
@@ -60,7 +60,7 @@ export const WithSidebar: Story = {
60
60
  <div style={{ width: '100%', height: '100vh' }}>
61
61
  <SubsystemComponentGraph
62
62
  components={graphOnlyComponents}
63
- relations={graphOnlyEdges.relations} walkthroughs={graphOnlyEdges.walkthroughs}
63
+ walkthroughs={graphOnlyEdges.walkthroughs}
64
64
  title="Checkout"
65
65
  description="A small e-commerce checkout subsystem: an HTTP entry point that writes to retained cart state and calls out to Stripe."
66
66
  graphTitle="Checkout"
@@ -21,7 +21,7 @@ import {
21
21
  * renderer picker → host RPC → background runner → maintain orchestrator →
22
22
  * opencode V2 session, plus the liveness-probe handshake. Its components and
23
23
  * three walkthroughs are reproduced verbatim below; the topology is carried by
24
- * the walkthroughs (`relations: []`), exactly as stored.
24
+ * the walkthroughs, exactly as stored.
25
25
  *
26
26
  * What this story exercises: the graph's diagnostics surface over the real
27
27
  * model — the title-row status chip, the grouped issue list, the per-node
@@ -482,30 +482,6 @@ const MAINTAIN_ISSUES: SubsystemIssue[] = [
482
482
  message: 'Graphify anchored the node but left the construct unclassified (store vs interface).',
483
483
  target: { kind: 'component', id: 'live-feed-store', label: 'OpencodeLiveFeedState store' },
484
484
  },
485
- {
486
- id: 'mr-endpoint',
487
- severity: 'error',
488
- kind: 'topology_broken_endpoint',
489
- message: 'Relationship endpoint "maintain-background-runner" does not resolve to a component.',
490
- target: {
491
- kind: 'relation',
492
- id: 'maintain-rpc-handler→maintain-background-runner',
493
- label: 'maintainSubsystemModel RPC → maintainSubsystemModelInBackground',
494
- detail: 'calls',
495
- },
496
- },
497
- {
498
- id: 'mr-hang',
499
- severity: 'error',
500
- kind: 'topology_broken_endpoint',
501
- message: 'Run reaches the 15-minute deadline without an endpoint on the finish event.',
502
- target: {
503
- kind: 'relation',
504
- id: 'session-runner→opencode-v2-server',
505
- label: 'runOpencodeV2AgentSession → OpenCode V2 service',
506
- detail: 'calls',
507
- },
508
- },
509
485
  {
510
486
  id: 'mr-boundary',
511
487
  severity: 'info',
@@ -580,7 +556,6 @@ function MaintainRunGraph({
580
556
  <div style={{ flex: 1, minHeight: 0 }}>
581
557
  <SubsystemComponentGraph
582
558
  components={MAINTAIN_COMPONENTS}
583
- relations={[]}
584
559
  walkthroughs={MAINTAIN_WALKTHROUGHS}
585
560
  title="Maintain run"
586
561
  description="Fire-and-forget RPC, wait for the finish event — picker → RPC → background runner → orchestrator → opencode V2 session, plus the liveness-probe handshake."