@principal-ai/subsystems-react 0.20.5 → 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 (87) 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/graphify/construct.d.ts +23 -0
  9. package/dist/graphify/construct.d.ts.map +1 -0
  10. package/dist/graphify/construct.js +77 -0
  11. package/dist/graphify/construct.js.map +1 -0
  12. package/dist/graphify/index.d.ts +2 -2
  13. package/dist/graphify/index.d.ts.map +1 -1
  14. package/dist/graphify/index.js +1 -1
  15. package/dist/graphify/index.js.map +1 -1
  16. package/dist/index.d.ts +7 -7
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/pierre/PierreWalkthroughCodeView.d.ts +22 -0
  21. package/dist/pierre/PierreWalkthroughCodeView.d.ts.map +1 -0
  22. package/dist/pierre/PierreWalkthroughCodeView.js +198 -0
  23. package/dist/pierre/PierreWalkthroughCodeView.js.map +1 -0
  24. package/dist/pierre/index.d.ts +2 -2
  25. package/dist/pierre/index.js +1 -1
  26. package/dist/pierre/pierreFileLang.d.ts +1 -1
  27. package/dist/pierre/pierreFileLang.js +1 -1
  28. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +14 -2
  29. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -1
  30. package/dist/stories/Subsystem/ComponentGraph/fixtures.js +86 -20
  31. package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -1
  32. package/dist/subsystem/ComponentDeclaration.js +1 -1
  33. package/dist/subsystem/ComponentDeclaration.js.map +1 -1
  34. package/dist/subsystem/FileDrawer.d.ts +2 -2
  35. package/dist/subsystem/FileDrawer.js +2 -2
  36. package/dist/subsystem/SubsystemComponentGraph.d.ts +25 -24
  37. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  38. package/dist/subsystem/SubsystemComponentGraph.js +220 -194
  39. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  40. package/dist/subsystem/formatDeclaration.d.ts +2 -1
  41. package/dist/subsystem/formatDeclaration.d.ts.map +1 -1
  42. package/dist/subsystem/formatDeclaration.js +57 -33
  43. package/dist/subsystem/formatDeclaration.js.map +1 -1
  44. package/dist/subsystem/model.d.ts +109 -42
  45. package/dist/subsystem/model.d.ts.map +1 -1
  46. package/dist/subsystem/model.js +107 -5
  47. package/dist/subsystem/model.js.map +1 -1
  48. package/dist/subsystem/nodes.d.ts.map +1 -1
  49. package/dist/subsystem/nodes.js +43 -18
  50. package/dist/subsystem/nodes.js.map +1 -1
  51. package/dist/subsystem/tokenizeComponent.js +2 -2
  52. package/dist/subsystem/tokenizeComponent.js.map +1 -1
  53. package/package.json +3 -3
  54. package/src/graphify/anchor.test.ts +31 -2
  55. package/src/graphify/anchor.ts +46 -0
  56. package/src/graphify/consolidated.ts +43 -1
  57. package/src/graphify/{kind.test.ts → construct.test.ts} +20 -20
  58. package/src/graphify/{kind.ts → construct.ts} +17 -17
  59. package/src/graphify/index.ts +5 -2
  60. package/src/index.ts +20 -9
  61. package/src/pierre/{PierreThroughlineCodeView.tsx → PierreWalkthroughCodeView.tsx} +39 -47
  62. package/src/pierre/index.ts +2 -2
  63. package/src/pierre/pierreFileLang.ts +1 -1
  64. package/src/stories/Pierre/CodeView.stories.tsx +3 -3
  65. package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +14 -14
  66. package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +13 -15
  67. package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +8 -8
  68. package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +16 -20
  69. package/src/stories/Subsystem/ComponentGraph/CustomEntities.stories.tsx +11 -10
  70. package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +13 -14
  71. package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +31 -66
  72. package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +2 -2
  73. package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +4 -4
  74. package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +3 -3
  75. package/src/stories/Subsystem/ComponentGraph/Proposed.stories.tsx +254 -0
  76. package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +518 -33
  77. package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +13 -13
  78. package/src/stories/Subsystem/ComponentGraph/fixtures.ts +105 -21
  79. package/src/subsystem/ComponentDeclaration.tsx +1 -1
  80. package/src/subsystem/FileDrawer.tsx +2 -2
  81. package/src/subsystem/SubsystemComponentGraph.tsx +284 -254
  82. package/src/subsystem/formatDeclaration.test.ts +76 -1
  83. package/src/subsystem/formatDeclaration.ts +57 -33
  84. package/src/subsystem/model.test.ts +49 -15
  85. package/src/subsystem/model.ts +210 -51
  86. package/src/subsystem/nodes.tsx +63 -22
  87. 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 { 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>
@@ -168,8 +168,7 @@ export const ResolvedPostGraphify: Story = {
168
168
 
169
169
  // ---------------------------------------------------------------------------
170
170
  // Investigation-derived subsystem — grok session 019fd2a9 (t3code)
171
- // Read-only analysis of "provider / event threading". Components are occupied
172
- // (analyzed, not edited) — no code touched, but a coherent concept was worked.
171
+ // Read-only analysis of "provider / event threading".
173
172
  // ---------------------------------------------------------------------------
174
173
  const investigationComponents: SubsystemComponent[] = [
175
174
  {
@@ -180,8 +179,7 @@ const investigationComponents: SubsystemComponent[] = [
180
179
  purl: 'pkg:github/t3code/t3code',
181
180
  purpose: 'adapts opencode session/threads + events to the t3 runtime',
182
181
  symbol: 'makeOpenCodeAdapter',
183
- capture: 'analyzed',
184
- detail: {
182
+ declaration: {
185
183
  kind: 'module',
186
184
  exports: ['makeOpenCodeAdapter', 'OpenCodeAdapterLiveOptions'],
187
185
  imports: [{ nodeId: 'i1', name: 'orchestration', relation: 'imports_from' }],
@@ -196,7 +194,6 @@ const investigationComponents: SubsystemComponent[] = [
196
194
  purl: 'pkg:github/t3code/t3code',
197
195
  purpose: 'ingests provider events into the runtime',
198
196
  symbol: 'ProviderRuntimeIngestion',
199
- capture: 'analyzed',
200
197
  },
201
198
  {
202
199
  id: 'contracts',
@@ -206,11 +203,10 @@ const investigationComponents: SubsystemComponent[] = [
206
203
  purl: 'pkg:github/t3code/t3code',
207
204
  purpose: 'contracts for orchestration/providers',
208
205
  symbol: 'ORCHESTRATION_WS_METHODS',
209
- capture: 'analyzed',
210
206
  },
211
207
  ];
212
208
 
213
- const investigationEdges = edges([
209
+ const investigationEdges = graphSpecFromEdges([
214
210
  ['adapter', 'contracts', 'imports_from'],
215
211
  ['ingestion', 'adapter', 'uses'],
216
212
  ['ingestion', 'contracts', 'references'],
@@ -222,11 +218,11 @@ function InvestigationDemo() {
222
218
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
223
219
  <SubsystemComponentGraph
224
220
  components={investigationComponents}
225
- edges={investigationEdges}
221
+ relations={investigationEdges.relations} walkthroughs={investigationEdges.walkthroughs}
226
222
  onSelect={(id) => setSelected(id)}
227
223
  />
228
224
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
229
- read-only investigation snapshot (grok 019fd2a9) — components analyzed, not edited
225
+ read-only investigation snapshot (grok 019fd2a9)
230
226
  {selected ? ` · selected: ${selected}` : ''}
231
227
  </div>
232
228
  </div>
@@ -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>
@@ -3,13 +3,9 @@ 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 {
7
- SubsystemComponent,
8
- SubsystemComponentEdge,
9
- SubsystemThroughline,
10
- } from '../../../subsystem/model';
11
- import { PierreThroughlineCodeView } from '../../../pierre';
12
- import type { ThroughlineViewerContext } from '../../../subsystem/SubsystemComponentGraph';
6
+ import type { SubsystemComponent, SubsystemWalkthrough } from '../../../subsystem/model';
7
+ import { PierreWalkthroughCodeView } from '../../../pierre';
8
+ import type { WalkthroughViewerContext } from '../../../subsystem/SubsystemComponentGraph';
13
9
 
14
10
  const meta = {
15
11
  title: 'Subsystem/ComponentGraph/Flows',
@@ -30,16 +26,6 @@ const meta = {
30
26
  export default meta;
31
27
  type Story = StoryObj<typeof meta>;
32
28
 
33
- // ---------------------------------------------------------------------------
34
- // Mirror of the retrofitted electron-app drawing graph: the sidebar's Files
35
- // panel swaps to a Flows panel listing three throughlines (open / save /
36
- // delete). Clicking a flow row toggles its steps; clicking a step focuses
37
- // that step's edge, frames it on the canvas, and scrolls the bottom CodeView
38
- // to that step's snippet. Other opened flows stay dimmed; the rest of the
39
- // graph is hidden.
40
- // ---------------------------------------------------------------------------
41
-
42
- /** Build enough placeholder lines so step `line` values land inside the file. */
43
29
  function fakeSource(path: string, markedLines: number[]): string {
44
30
  const maxLine = Math.max(80, ...markedLines);
45
31
  const marks = new Set(markedLines);
@@ -58,19 +44,11 @@ function fakeSource(path: string, markedLines: number[]): string {
58
44
  }
59
45
 
60
46
  const storyFiles: Record<string, string> = {
61
- 'src/panels/DrawingsLeftPanel.tsx': fakeSource('src/panels/DrawingsLeftPanel.tsx', [
62
- 56, 85,
63
- ]),
64
- 'src/hooks/useDrawingsHost.ts': fakeSource('src/hooks/useDrawingsHost.ts', [
65
- 45, 64, 66,
66
- ]),
67
- 'src/workspace/WorkspaceShell.tsx': fakeSource('src/workspace/WorkspaceShell.tsx', [
68
- 369, 372,
69
- ]),
47
+ 'src/panels/DrawingsLeftPanel.tsx': fakeSource('src/panels/DrawingsLeftPanel.tsx', [56, 85]),
48
+ 'src/hooks/useDrawingsHost.ts': fakeSource('src/hooks/useDrawingsHost.ts', [45, 64, 66]),
49
+ 'src/workspace/WorkspaceShell.tsx': fakeSource('src/workspace/WorkspaceShell.tsx', [369, 372]),
70
50
  'src/storage/drawingsStorage.ts': fakeSource('src/storage/drawingsStorage.ts', [90]),
71
- 'src/components/DrawingTabContent.tsx': fakeSource('src/components/DrawingTabContent.tsx', [
72
- 83, 112, 121,
73
- ]),
51
+ 'src/components/DrawingTabContent.tsx': fakeSource('src/components/DrawingTabContent.tsx', [83, 112, 121]),
74
52
  };
75
53
 
76
54
  function readStoryFile(path: string): Promise<string> {
@@ -144,59 +122,46 @@ const drawingComponents: SubsystemComponent[] = [
144
122
  },
145
123
  ];
146
124
 
147
- const drawingEdges: SubsystemComponentEdge[] = [
148
- { id: 'e-scan', from: 'panel', to: 'storage', mechanism: 'calls' },
149
- { id: 'e-open-event', from: 'panel', to: 'host', mechanism: 'produces' },
150
- { id: 'e-refresh', from: 'host', to: 'panel', mechanism: 'produces' },
151
- { id: 'e-open', from: 'host', to: 'storage', mechanism: 'calls' },
152
- { id: 'e-read', from: 'storage', to: 'fs', mechanism: 'calls' },
153
- { id: 'e-delete', from: 'host', to: 'fs', mechanism: 'calls' },
154
- { id: 'e-show', from: 'host', to: 'shell', mechanism: 'produces' },
155
- { id: 'e-mount', from: 'shell', to: 'tab', mechanism: 'feeds' },
156
- { id: 'e-tab-io', from: 'tab', to: 'fs', mechanism: 'calls' },
157
- { id: 'e-saved-event', from: 'tab', to: 'host', mechanism: 'produces' },
158
- ];
159
-
160
- const drawingThroughlines: SubsystemThroughline[] = [
125
+ const drawingWalkthroughs: SubsystemWalkthrough[] = [
161
126
  {
162
127
  id: 'tl-open-drawing',
163
128
  title: 'Open drawing',
164
129
  steps: [
165
- { edgeId: 'e-scan', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan', annotation: 'Lists the drawings directory; each row feeds an open intent.' },
166
- { edgeId: 'e-open-event', file: 'src/panels/DrawingsLeftPanel.tsx', line: 85, symbol: 'DrawingsLeftPanel.openDrawing', annotation: 'Emits the open intent up to the host.' },
167
- { edgeId: 'e-open', file: 'src/hooks/useDrawingsHost.ts', line: 45, symbol: 'useDrawingsHost.openDrawing', annotation: 'Host resolves the path and delegates to storage.' },
168
- { edgeId: 'e-show', file: 'src/workspace/WorkspaceShell.tsx', line: 369, symbol: 'WorkspaceShell.openTab', annotation: 'Asks the shell to surface the drawing as a tab.' },
169
- { edgeId: 'e-mount', file: 'src/workspace/WorkspaceShell.tsx', line: 372, symbol: 'WorkspaceShell.mountTab' },
170
- { edgeId: 'e-read', file: 'src/storage/drawingsStorage.ts', line: 90, symbol: 'DrawingsStorage.read', annotation: 'Reads the file through the sandboxed fs service.' },
171
- { edgeId: 'e-tab-io', file: 'src/components/DrawingTabContent.tsx', line: 83, symbol: 'DrawingTabContent.load' },
130
+ { from: 'panel', to: 'storage', mechanism: 'calls', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan', annotation: 'Lists the drawings directory; each row feeds an open intent.' },
131
+ { from: 'panel', to: 'host', mechanism: 'produces', file: 'src/panels/DrawingsLeftPanel.tsx', line: 85, symbol: 'DrawingsLeftPanel.openDrawing', annotation: 'Emits the open intent up to the host.' },
132
+ { from: 'host', to: 'storage', mechanism: 'calls', file: 'src/hooks/useDrawingsHost.ts', line: 45, symbol: 'useDrawingsHost.openDrawing', annotation: 'Host resolves the path and delegates to storage.' },
133
+ { from: 'host', to: 'shell', mechanism: 'produces', file: 'src/workspace/WorkspaceShell.tsx', line: 369, symbol: 'WorkspaceShell.openTab', annotation: 'Asks the shell to surface the drawing as a tab.' },
134
+ { from: 'shell', to: 'tab', mechanism: 'feeds', file: 'src/workspace/WorkspaceShell.tsx', line: 372, symbol: 'WorkspaceShell.mountTab' },
135
+ { from: 'storage', to: 'fs', mechanism: 'calls', file: 'src/storage/drawingsStorage.ts', line: 90, symbol: 'DrawingsStorage.read', annotation: 'Reads the file through the sandboxed fs service.' },
136
+ { from: 'tab', to: 'fs', mechanism: 'calls', file: 'src/components/DrawingTabContent.tsx', line: 83, symbol: 'DrawingTabContent.load' },
172
137
  ],
173
138
  },
174
139
  {
175
140
  id: 'tl-save-drawing',
176
141
  title: 'Save drawing',
177
142
  steps: [
178
- { edgeId: 'e-tab-io', file: 'src/components/DrawingTabContent.tsx', line: 112, symbol: 'DrawingTabContent.save' },
179
- { edgeId: 'e-saved-event', file: 'src/components/DrawingTabContent.tsx', line: 121, symbol: 'DrawingTabContent.emitSaved' },
180
- { edgeId: 'e-refresh', file: 'src/hooks/useDrawingsHost.ts', line: 64, symbol: 'useDrawingsHost.onSaved' },
181
- { edgeId: 'e-scan', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan' },
143
+ { from: 'tab', to: 'fs', mechanism: 'calls', file: 'src/components/DrawingTabContent.tsx', line: 112, symbol: 'DrawingTabContent.save' },
144
+ { from: 'tab', to: 'host', mechanism: 'produces', file: 'src/components/DrawingTabContent.tsx', line: 121, symbol: 'DrawingTabContent.emitSaved' },
145
+ { from: 'host', to: 'panel', mechanism: 'produces', file: 'src/hooks/useDrawingsHost.ts', line: 64, symbol: 'useDrawingsHost.onSaved' },
146
+ { from: 'panel', to: 'storage', mechanism: 'calls', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan' },
182
147
  ],
183
148
  },
184
149
  {
185
150
  id: 'tl-delete-drawing',
186
151
  title: 'Delete drawing',
187
152
  steps: [
188
- { edgeId: 'e-delete', file: 'src/hooks/useDrawingsHost.ts', line: 64, symbol: 'useDrawingsHost.deleteDrawing' },
189
- { edgeId: 'e-refresh', file: 'src/hooks/useDrawingsHost.ts', line: 66, symbol: 'useDrawingsHost.refreshList' },
190
- { edgeId: 'e-scan', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan' },
153
+ { from: 'host', to: 'fs', mechanism: 'calls', file: 'src/hooks/useDrawingsHost.ts', line: 64, symbol: 'useDrawingsHost.deleteDrawing' },
154
+ { from: 'host', to: 'panel', mechanism: 'produces', file: 'src/hooks/useDrawingsHost.ts', line: 66, symbol: 'useDrawingsHost.refreshList' },
155
+ { from: 'panel', to: 'storage', mechanism: 'calls', file: 'src/panels/DrawingsLeftPanel.tsx', line: 56, symbol: 'DrawingsLeftPanel.scan' },
191
156
  ],
192
157
  },
193
158
  ];
194
159
 
195
160
  function FlowsDemo() {
196
- const renderThroughlineViewer = useCallback(
197
- ({ throughline, stepIndex }: ThroughlineViewerContext) => (
198
- <PierreThroughlineCodeView
199
- throughline={throughline}
161
+ const renderWalkthroughViewer = useCallback(
162
+ ({ walkthrough, stepIndex }: WalkthroughViewerContext) => (
163
+ <PierreWalkthroughCodeView
164
+ walkthrough={walkthrough}
200
165
  stepIndex={stepIndex}
201
166
  readFile={readStoryFile}
202
167
  contextLines={4}
@@ -209,11 +174,11 @@ function FlowsDemo() {
209
174
  <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
210
175
  <SubsystemComponentGraph
211
176
  components={drawingComponents}
212
- edges={drawingEdges}
213
- throughlines={drawingThroughlines}
177
+ relations={[]}
178
+ walkthroughs={drawingWalkthroughs}
214
179
  title="drawing-files flow"
215
- description="Three throughlines over one graph — opening, saving, and deleting a drawing. The sidebar's **Flows** panel lists each step by **symbol**; clicking a step focuses that edge and scrolls the bottom CodeView to that snippet."
216
- renderThroughlineViewer={renderThroughlineViewer}
180
+ 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."
181
+ renderWalkthroughViewer={renderWalkthroughViewer}
217
182
  renderFileViewer={(file, opts) => (
218
183
  <div
219
184
  style={{
@@ -236,4 +201,4 @@ function FlowsDemo() {
236
201
 
237
202
  export const ThreeFlows: Story = {
238
203
  render: () => <FlowsDemo />,
239
- };
204
+ };
@@ -137,7 +137,7 @@ export const ReactComponentsAndHooks: Story = {
137
137
  title="Framework + stereotype"
138
138
  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
139
  components={reactUiComponents}
140
- edges={reactUiEdges}
140
+ relations={reactUiEdges.relations} walkthroughs={reactUiEdges.walkthroughs}
141
141
  />
142
142
  </div>
143
143
  ),
@@ -209,7 +209,7 @@ export const NestControllerStack: Story = {
209
209
  title="Nest framework stereotypes"
210
210
  description="Same optional fields work outside React: class/function constructs plus nestjs controller / guard / middleware / injectable stereotypes."
211
211
  components={nestComponents}
212
- edges={nestEdges}
212
+ relations={nestEdges.relations} walkthroughs={nestEdges.walkthroughs}
213
213
  />
214
214
  </div>
215
215
  ),
@@ -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, edges } from './fixtures';
6
+ import { components, graphSpecFromEdges, relations } 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 = edges([
33
+ const graphOnlyEdges = graphSpecFromEdges([
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
- edges={graphOnlyEdges}
44
+ relations={graphOnlyEdges.relations} 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
- edges={graphOnlyEdges}
63
+ relations={graphOnlyEdges.relations} 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"
@@ -2,7 +2,7 @@ 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 { components, edges } from './fixtures';
5
+ import { components, graphSpecFromEdges, relations } from './fixtures';
6
6
 
7
7
  const meta = {
8
8
  title: 'Subsystem/ComponentGraph/Processes',
@@ -47,7 +47,7 @@ const processComponents = [
47
47
  : c,
48
48
  );
49
49
 
50
- const processEdges = edges([
50
+ const processEdges = graphSpecFromEdges([
51
51
  ['main', 'store', 'writes'],
52
52
  ['main', 'bridge', 'calls'],
53
53
  ['bridge', 'view', 'feeds'],
@@ -61,7 +61,7 @@ export const ProcessBoundaries: Story = {
61
61
  title="Process boundaries"
62
62
  description="Host and renderer each render in their own ELK-aware boundary frame. The telemetry service has no `process` and sits outside every boundary."
63
63
  components={processComponents}
64
- edges={processEdges}
64
+ relations={processEdges.relations} walkthroughs={processEdges.walkthroughs}
65
65
  />
66
66
  </div>
67
67
  ),