@principal-ai/subsystems-react 0.20.6 → 0.21.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 (270) 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/{PierreThroughlineCodeView.d.ts → PierreWalkthroughCodeView.d.ts} +7 -7
  13. package/dist/pierre/{PierreThroughlineCodeView.d.ts.map → PierreWalkthroughCodeView.d.ts.map} +1 -1
  14. package/dist/pierre/{PierreThroughlineCodeView.js → PierreWalkthroughCodeView.js} +28 -36
  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
  74. package/dist/components/ConfigurationSelector.d.ts +0 -35
  75. package/dist/components/ConfigurationSelector.d.ts.map +0 -1
  76. package/dist/components/ConfigurationSelector.js +0 -63
  77. package/dist/components/ConfigurationSelector.js.map +0 -1
  78. package/dist/components/GraphRenderer.d.ts +0 -295
  79. package/dist/components/GraphRenderer.d.ts.map +0 -1
  80. package/dist/components/GraphRenderer.js +0 -2008
  81. package/dist/components/GraphRenderer.js.map +0 -1
  82. package/dist/components/MultiCanvasRenderer.d.ts +0 -75
  83. package/dist/components/MultiCanvasRenderer.d.ts.map +0 -1
  84. package/dist/components/MultiCanvasRenderer.js +0 -203
  85. package/dist/components/MultiCanvasRenderer.js.map +0 -1
  86. package/dist/components/NodeTooltip.d.ts +0 -24
  87. package/dist/components/NodeTooltip.d.ts.map +0 -1
  88. package/dist/components/NodeTooltip.js +0 -160
  89. package/dist/components/NodeTooltip.js.map +0 -1
  90. package/dist/components/SelectionSidebar.d.ts +0 -18
  91. package/dist/components/SelectionSidebar.d.ts.map +0 -1
  92. package/dist/components/SelectionSidebar.js +0 -190
  93. package/dist/components/SelectionSidebar.js.map +0 -1
  94. package/dist/components/SequenceDiagramRenderer.d.ts +0 -77
  95. package/dist/components/SequenceDiagramRenderer.d.ts.map +0 -1
  96. package/dist/components/SequenceDiagramRenderer.js +0 -604
  97. package/dist/components/SequenceDiagramRenderer.js.map +0 -1
  98. package/dist/components/WorkflowSequenceDiagram.d.ts +0 -63
  99. package/dist/components/WorkflowSequenceDiagram.d.ts.map +0 -1
  100. package/dist/components/WorkflowSequenceDiagram.js +0 -147
  101. package/dist/components/WorkflowSequenceDiagram.js.map +0 -1
  102. package/dist/components/dashboard/DashboardRenderer.d.ts +0 -10
  103. package/dist/components/dashboard/DashboardRenderer.d.ts.map +0 -1
  104. package/dist/components/dashboard/DashboardRenderer.js +0 -179
  105. package/dist/components/dashboard/DashboardRenderer.js.map +0 -1
  106. package/dist/components/dashboard/MetricPanel.d.ts +0 -10
  107. package/dist/components/dashboard/MetricPanel.d.ts.map +0 -1
  108. package/dist/components/dashboard/MetricPanel.js +0 -103
  109. package/dist/components/dashboard/MetricPanel.js.map +0 -1
  110. package/dist/components/dashboard/MockDataProvider.d.ts +0 -30
  111. package/dist/components/dashboard/MockDataProvider.d.ts.map +0 -1
  112. package/dist/components/dashboard/MockDataProvider.js +0 -270
  113. package/dist/components/dashboard/MockDataProvider.js.map +0 -1
  114. package/dist/components/dashboard/components/BarChart.d.ts +0 -10
  115. package/dist/components/dashboard/components/BarChart.d.ts.map +0 -1
  116. package/dist/components/dashboard/components/BarChart.js +0 -167
  117. package/dist/components/dashboard/components/BarChart.js.map +0 -1
  118. package/dist/components/dashboard/components/LineChart.d.ts +0 -10
  119. package/dist/components/dashboard/components/LineChart.d.ts.map +0 -1
  120. package/dist/components/dashboard/components/LineChart.js +0 -141
  121. package/dist/components/dashboard/components/LineChart.js.map +0 -1
  122. package/dist/components/dashboard/components/MetricCard.d.ts +0 -9
  123. package/dist/components/dashboard/components/MetricCard.d.ts.map +0 -1
  124. package/dist/components/dashboard/components/MetricCard.js +0 -163
  125. package/dist/components/dashboard/components/MetricCard.js.map +0 -1
  126. package/dist/components/dashboard/components/SourceLink.d.ts +0 -9
  127. package/dist/components/dashboard/components/SourceLink.d.ts.map +0 -1
  128. package/dist/components/dashboard/components/SourceLink.js +0 -39
  129. package/dist/components/dashboard/components/SourceLink.js.map +0 -1
  130. package/dist/components/dashboard/components/TimeRangeSelector.d.ts +0 -9
  131. package/dist/components/dashboard/components/TimeRangeSelector.d.ts.map +0 -1
  132. package/dist/components/dashboard/components/TimeRangeSelector.js +0 -167
  133. package/dist/components/dashboard/components/TimeRangeSelector.js.map +0 -1
  134. package/dist/components/dashboard/components/index.d.ts +0 -6
  135. package/dist/components/dashboard/components/index.d.ts.map +0 -1
  136. package/dist/components/dashboard/components/index.js +0 -6
  137. package/dist/components/dashboard/components/index.js.map +0 -1
  138. package/dist/components/dashboard/index.d.ts +0 -6
  139. package/dist/components/dashboard/index.d.ts.map +0 -1
  140. package/dist/components/dashboard/index.js +0 -8
  141. package/dist/components/dashboard/index.js.map +0 -1
  142. package/dist/components/dashboard/types.d.ts +0 -74
  143. package/dist/components/dashboard/types.d.ts.map +0 -1
  144. package/dist/components/dashboard/types.js +0 -8
  145. package/dist/components/dashboard/types.js.map +0 -1
  146. package/dist/components/state-view/PipelineView.d.ts +0 -14
  147. package/dist/components/state-view/PipelineView.d.ts.map +0 -1
  148. package/dist/components/state-view/PipelineView.js +0 -195
  149. package/dist/components/state-view/PipelineView.js.map +0 -1
  150. package/dist/components/state-view/index.d.ts +0 -14
  151. package/dist/components/state-view/index.d.ts.map +0 -1
  152. package/dist/components/state-view/index.js +0 -12
  153. package/dist/components/state-view/index.js.map +0 -1
  154. package/dist/components/state-view/types.d.ts +0 -188
  155. package/dist/components/state-view/types.d.ts.map +0 -1
  156. package/dist/components/state-view/types.js +0 -10
  157. package/dist/components/state-view/types.js.map +0 -1
  158. package/dist/components/state-view/useStateView.d.ts +0 -32
  159. package/dist/components/state-view/useStateView.d.ts.map +0 -1
  160. package/dist/components/state-view/useStateView.js +0 -129
  161. package/dist/components/state-view/useStateView.js.map +0 -1
  162. package/dist/contexts/GraphEditContext.d.ts +0 -20
  163. package/dist/contexts/GraphEditContext.d.ts.map +0 -1
  164. package/dist/contexts/GraphEditContext.js +0 -8
  165. package/dist/contexts/GraphEditContext.js.map +0 -1
  166. package/dist/contexts/TooltipPortalContext.d.ts +0 -8
  167. package/dist/contexts/TooltipPortalContext.d.ts.map +0 -1
  168. package/dist/contexts/TooltipPortalContext.js +0 -8
  169. package/dist/contexts/TooltipPortalContext.js.map +0 -1
  170. package/dist/edges/CustomEdge.d.ts +0 -24
  171. package/dist/edges/CustomEdge.d.ts.map +0 -1
  172. package/dist/edges/CustomEdge.js +0 -222
  173. package/dist/edges/CustomEdge.js.map +0 -1
  174. package/dist/edges/GenericEdge.d.ts +0 -18
  175. package/dist/edges/GenericEdge.d.ts.map +0 -1
  176. package/dist/edges/GenericEdge.js +0 -10
  177. package/dist/edges/GenericEdge.js.map +0 -1
  178. package/dist/graphify/kind.d.ts +0 -23
  179. package/dist/graphify/kind.d.ts.map +0 -1
  180. package/dist/graphify/kind.js +0 -77
  181. package/dist/graphify/kind.js.map +0 -1
  182. package/dist/hooks/usePathBasedEvents.d.ts +0 -42
  183. package/dist/hooks/usePathBasedEvents.d.ts.map +0 -1
  184. package/dist/hooks/usePathBasedEvents.js +0 -119
  185. package/dist/hooks/usePathBasedEvents.js.map +0 -1
  186. package/dist/hooks/useSequenceLayout.d.ts +0 -186
  187. package/dist/hooks/useSequenceLayout.d.ts.map +0 -1
  188. package/dist/hooks/useSequenceLayout.js +0 -327
  189. package/dist/hooks/useSequenceLayout.js.map +0 -1
  190. package/dist/hooks/useUndoRedo.d.ts +0 -80
  191. package/dist/hooks/useUndoRedo.d.ts.map +0 -1
  192. package/dist/hooks/useUndoRedo.js +0 -70
  193. package/dist/hooks/useUndoRedo.js.map +0 -1
  194. package/dist/nodes/CustomNode.d.ts +0 -28
  195. package/dist/nodes/CustomNode.d.ts.map +0 -1
  196. package/dist/nodes/CustomNode.js +0 -820
  197. package/dist/nodes/CustomNode.js.map +0 -1
  198. package/dist/nodes/GenericNode.d.ts +0 -20
  199. package/dist/nodes/GenericNode.d.ts.map +0 -1
  200. package/dist/nodes/GenericNode.js +0 -20
  201. package/dist/nodes/GenericNode.js.map +0 -1
  202. package/dist/nodes/otel/OtelBoundaryNode.d.ts +0 -55
  203. package/dist/nodes/otel/OtelBoundaryNode.d.ts.map +0 -1
  204. package/dist/nodes/otel/OtelBoundaryNode.js +0 -81
  205. package/dist/nodes/otel/OtelBoundaryNode.js.map +0 -1
  206. package/dist/nodes/otel/OtelEventNode.d.ts +0 -59
  207. package/dist/nodes/otel/OtelEventNode.d.ts.map +0 -1
  208. package/dist/nodes/otel/OtelEventNode.js +0 -82
  209. package/dist/nodes/otel/OtelEventNode.js.map +0 -1
  210. package/dist/nodes/otel/OtelResourceNode.d.ts +0 -53
  211. package/dist/nodes/otel/OtelResourceNode.d.ts.map +0 -1
  212. package/dist/nodes/otel/OtelResourceNode.js +0 -105
  213. package/dist/nodes/otel/OtelResourceNode.js.map +0 -1
  214. package/dist/nodes/otel/OtelScopeNode.d.ts +0 -53
  215. package/dist/nodes/otel/OtelScopeNode.d.ts.map +0 -1
  216. package/dist/nodes/otel/OtelScopeNode.js +0 -81
  217. package/dist/nodes/otel/OtelScopeNode.js.map +0 -1
  218. package/dist/nodes/otel/OtelSpanConventionNode.d.ts +0 -61
  219. package/dist/nodes/otel/OtelSpanConventionNode.d.ts.map +0 -1
  220. package/dist/nodes/otel/OtelSpanConventionNode.js +0 -131
  221. package/dist/nodes/otel/OtelSpanConventionNode.js.map +0 -1
  222. package/dist/nodes/otel/index.d.ts +0 -17
  223. package/dist/nodes/otel/index.d.ts.map +0 -1
  224. package/dist/nodes/otel/index.js +0 -13
  225. package/dist/nodes/otel/index.js.map +0 -1
  226. package/dist/nodes/otel/shared/NodeBadges.d.ts +0 -10
  227. package/dist/nodes/otel/shared/NodeBadges.d.ts.map +0 -1
  228. package/dist/nodes/otel/shared/NodeBadges.js +0 -178
  229. package/dist/nodes/otel/shared/NodeBadges.js.map +0 -1
  230. package/dist/nodes/otel/shared/NodeContent.d.ts +0 -10
  231. package/dist/nodes/otel/shared/NodeContent.d.ts.map +0 -1
  232. package/dist/nodes/otel/shared/NodeContent.js +0 -96
  233. package/dist/nodes/otel/shared/NodeContent.js.map +0 -1
  234. package/dist/nodes/otel/shared/index.d.ts +0 -8
  235. package/dist/nodes/otel/shared/index.d.ts.map +0 -1
  236. package/dist/nodes/otel/shared/index.js +0 -8
  237. package/dist/nodes/otel/shared/index.js.map +0 -1
  238. package/dist/nodes/otel/shared/types.d.ts +0 -129
  239. package/dist/nodes/otel/shared/types.d.ts.map +0 -1
  240. package/dist/nodes/otel/shared/types.js +0 -5
  241. package/dist/nodes/otel/shared/types.js.map +0 -1
  242. package/dist/nodes/otel/shared/useNodeBehavior.d.ts +0 -42
  243. package/dist/nodes/otel/shared/useNodeBehavior.d.ts.map +0 -1
  244. package/dist/nodes/otel/shared/useNodeBehavior.js +0 -61
  245. package/dist/nodes/otel/shared/useNodeBehavior.js.map +0 -1
  246. package/dist/pierre/PierreThroughlineCodeView.js.map +0 -1
  247. package/dist/subsystem/SubsystemCarousel.d.ts +0 -36
  248. package/dist/subsystem/SubsystemCarousel.d.ts.map +0 -1
  249. package/dist/subsystem/SubsystemCarousel.js +0 -163
  250. package/dist/subsystem/SubsystemCarousel.js.map +0 -1
  251. package/dist/utils/animationMapping.d.ts +0 -53
  252. package/dist/utils/animationMapping.d.ts.map +0 -1
  253. package/dist/utils/animationMapping.js +0 -126
  254. package/dist/utils/animationMapping.js.map +0 -1
  255. package/dist/utils/canvasBounds.d.ts +0 -50
  256. package/dist/utils/canvasBounds.d.ts.map +0 -1
  257. package/dist/utils/canvasBounds.js +0 -88
  258. package/dist/utils/canvasBounds.js.map +0 -1
  259. package/dist/utils/graphConverter.d.ts +0 -18
  260. package/dist/utils/graphConverter.d.ts.map +0 -1
  261. package/dist/utils/graphConverter.js +0 -114
  262. package/dist/utils/graphConverter.js.map +0 -1
  263. package/dist/utils/iconResolver.d.ts +0 -29
  264. package/dist/utils/iconResolver.d.ts.map +0 -1
  265. package/dist/utils/iconResolver.js +0 -30
  266. package/dist/utils/iconResolver.js.map +0 -1
  267. package/dist/utils/orientationUtils.d.ts +0 -19
  268. package/dist/utils/orientationUtils.d.ts.map +0 -1
  269. package/dist/utils/orientationUtils.js +0 -62
  270. package/dist/utils/orientationUtils.js.map +0 -1
@@ -25,7 +25,7 @@ describe('generateDeclarationString — custom_entity', () => {
25
25
  entityKind: 'agent',
26
26
  file: '',
27
27
  purl: 'pkg:github/novatech/facilities-ops',
28
- detail: {
28
+ declaration: {
29
29
  kind: 'custom_entity',
30
30
  attributes: [
31
31
  { key: 'slack', value: 'novatech/facilities-ops' },
@@ -37,4 +37,79 @@ describe('generateDeclarationString — custom_entity', () => {
37
37
  "entity 'OpsInsightAgent' — agent\n slack: novatech/facilities-ops\n permission: propose-only",
38
38
  );
39
39
  });
40
+ });
41
+
42
+ describe('generateDeclarationString — type family', () => {
43
+ const typed = (declaration: SubsystemComponent['declaration'], construct: SubsystemComponent['construct'] = 'type_alias') => {
44
+ const component: SubsystemComponent = {
45
+ id: 't',
46
+ name: 'StudioMessageSubscriber',
47
+ symbol: 'StudioMessageSubscriber',
48
+ construct,
49
+ file: 'packages/subsystems-studio/src/mainview/rpc.ts',
50
+ purl: 'pkg:github/principal-ai/subsystem-modeling',
51
+ declaration,
52
+ };
53
+ return generateDeclarationString(component);
54
+ };
55
+
56
+ test('generic callable alias renders its signature, not `= unknown`', () => {
57
+ expect(
58
+ typed({
59
+ kind: 'type',
60
+ generics: [{ name: 'K', constraint: 'keyof StudioMessages' }],
61
+ signature: {
62
+ parameters: [{ name: 'payload', type: 'StudioMessages[K]' }],
63
+ returnType: 'void',
64
+ },
65
+ }),
66
+ ).toBe('type StudioMessageSubscriber<K extends keyof StudioMessages> = (payload: StudioMessages[K]) => void;');
67
+ });
68
+
69
+ test('plain callable alias defaults return type to void', () => {
70
+ expect(
71
+ typed({
72
+ kind: 'type',
73
+ signature: { parameters: [{ name: 'req', type: 'Request' }] },
74
+ }),
75
+ ).toBe('type StudioMessageSubscriber = (req: Request) => void;');
76
+ });
77
+
78
+ test('rhs override wins over the structured shapes', () => {
79
+ expect(
80
+ typed({
81
+ kind: 'type',
82
+ properties: [{ name: 'id', type: 'string' }],
83
+ rhs: '{ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] }',
84
+ }),
85
+ ).toBe('type StudioMessageSubscriber = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] };');
86
+ });
87
+
88
+ test('generic + rhs render the type parameters in the header', () => {
89
+ expect(
90
+ typed({
91
+ kind: 'type',
92
+ generics: [{ name: 'T' }],
93
+ rhs: '{ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] }',
94
+ }),
95
+ ).toBe('type StudioMessageSubscriber<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] };');
96
+ });
97
+
98
+ test('plain reference alias renders through aliasOf', () => {
99
+ expect(typed({ kind: 'type', aliasOf: 'ServerSessionRow[]' })).toBe(
100
+ 'type StudioMessageSubscriber = ServerSessionRow[];',
101
+ );
102
+ });
103
+
104
+ test('union alias joins its alternatives', () => {
105
+ expect(
106
+ typed({ kind: 'type', unionOf: ["'idle'", "'busy'", "'error'"] }),
107
+ ).toBe("type StudioMessageSubscriber = 'idle' | 'busy' | 'error';");
108
+ });
109
+
110
+ test('enum renders named members with values', () => {
111
+ expect(
112
+ typed({ kind: 'type', enumMembers: [{ name: 'Running', value: "'running'" }] }, 'enum'),
113
+ ).toBe("enum StudioMessageSubscriber { Running = 'running' }");
114
+ });
40
115
  });
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Generate a TypeScript declaration string from a SubsystemComponent's detail.
2
+ * Generate a TypeScript declaration string from a SubsystemComponent's
3
+ * structured `declaration`.
3
4
  *
4
5
  * This is the "source code" that Prettier will format. The output is valid
5
6
  * TypeScript (except for `external`, which is handled separately). The string
@@ -17,34 +18,34 @@ const TYPE_FAMILY_CONSTRUCTS: ReadonlySet<string> = new Set([
17
18
  ]);
18
19
 
19
20
  export function generateDeclarationString(component: SubsystemComponent): string {
20
- const detail = component.detail;
21
- // Type-family constructs own their rendering even when the detail payload
22
- // is the shared `type` shape — the construct says which keyword is honest.
21
+ const declaration = component.declaration;
22
+ // Type-family constructs own their rendering even when the declaration
23
+ // payload is the shared `type` shape — the construct says which keyword is honest.
23
24
  const construct = TYPE_FAMILY_CONSTRUCTS.has(component.construct)
24
25
  ? component.construct
25
- : detail?.kind ?? component.construct;
26
+ : declaration?.kind ?? component.construct;
26
27
  const rawName = component.symbol || component.name || 'untitled';
27
28
  // Strip class/object prefix from dotted symbols (e.g. "SessionReader.normalize" → "normalize").
28
29
  const name = rawName.includes('.') ? rawName.split('.').pop()! : rawName;
29
30
 
30
31
  switch (construct) {
31
32
  case 'class':
32
- return generateClass(name, detail);
33
+ return generateClass(name, declaration);
33
34
  case 'function':
34
- return generateFunction(name, detail);
35
+ return generateFunction(name, declaration);
35
36
  case 'method':
36
- return generateMethod(name, detail);
37
+ return generateMethod(name, declaration);
37
38
  case 'interface':
38
39
  case 'type_alias':
39
40
  case 'enum':
40
- return generateType(name, component.construct, detail);
41
+ return generateType(name, component.construct, declaration);
41
42
  case 'module':
42
- return generateModule(detail);
43
+ return generateModule(declaration);
43
44
  case 'store':
44
- return generateStore(name, detail);
45
+ return generateStore(name, declaration);
45
46
  case 'external':
46
47
  // Not valid TypeScript — caller should handle formatting.
47
- return `external '${detail?.kind === 'external' ? detail.label : name}'`;
48
+ return `external '${declaration?.kind === 'external' ? declaration.label : name}'`;
48
49
  case 'custom_entity':
49
50
  // An actor, not code — no declaration to generate. Renders as a
50
51
  // non-TypeScript block: `entity 'Name' — kind` followed by the authored
@@ -52,7 +53,7 @@ export function generateDeclarationString(component: SubsystemComponent): string
52
53
  // bypass Prettier.
53
54
  {
54
55
  const kindLabel = component.entityKind ? ` — ${component.entityKind}` : '';
55
- const attrs = detail?.kind === 'custom_entity' ? detail.attributes : [];
56
+ const attrs = declaration?.kind === 'custom_entity' ? declaration.attributes : [];
56
57
  const attrLines = attrs.map((a) => ` ${a.key}: ${a.value}`).join('\n');
57
58
  return attrLines
58
59
  ? `entity '${name}'${kindLabel}\n${attrLines}`
@@ -78,8 +79,8 @@ function formatParams(params: { name?: string; type: string }[]): string {
78
79
  // Per-construct generators
79
80
  // ---------------------------------------------------------------------------
80
81
 
81
- function generateClass(name: string, detail?: GraphifyComponentDetail): string {
82
- const cls = detail?.kind === 'class' ? detail : undefined;
82
+ function generateClass(name: string, declaration?: GraphifyComponentDetail): string {
83
+ const cls = declaration?.kind === 'class' ? declaration : undefined;
83
84
  const parts: string[] = [`class ${name}`];
84
85
 
85
86
  if (cls?.extends && cls.extends.length > 0) {
@@ -110,15 +111,15 @@ function generateClass(name: string, detail?: GraphifyComponentDetail): string {
110
111
  return parts.join(' ');
111
112
  }
112
113
 
113
- function generateFunction(name: string, detail?: GraphifyComponentDetail): string {
114
- const fn = detail?.kind === 'function' ? detail : undefined;
114
+ function generateFunction(name: string, declaration?: GraphifyComponentDetail): string {
115
+ const fn = declaration?.kind === 'function' ? declaration : undefined;
115
116
  const params = formatParams(fn?.parameters ?? []);
116
117
  const ret = fn?.returnType ? `: ${fn.returnType}` : '';
117
118
  return `function ${name}(${params})${ret};`;
118
119
  }
119
120
 
120
- function generateMethod(name: string, detail?: GraphifyComponentDetail): string {
121
- const m = detail?.kind === 'method' ? detail : undefined;
121
+ function generateMethod(name: string, declaration?: GraphifyComponentDetail): string {
122
+ const m = declaration?.kind === 'method' ? declaration : undefined;
122
123
  const hostClass = m?.hostClass ?? 'Host';
123
124
  const params = formatParams(m?.parameters ?? []);
124
125
  const ret = m?.returnType ? `: ${m.returnType}` : '';
@@ -128,32 +129,54 @@ function generateMethod(name: string, detail?: GraphifyComponentDetail): string
128
129
  function generateType(
129
130
  name: string,
130
131
  construct: SubsystemComponentConstruct,
131
- detail?: GraphifyComponentDetail,
132
+ declaration?: GraphifyComponentDetail,
132
133
  ): string {
133
134
  // The type-family constructs render their declaration keyword honestly —
134
135
  // the construct itself says interface / type (alias) / enum / variable.
135
- const tpe = detail?.kind === 'type' ? detail : undefined;
136
+ const tpe = declaration?.kind === 'type' ? declaration : undefined;
137
+ const params = (tpe?.generics ?? [])
138
+ .map((g) => `${g.name}${g.constraint ? ` extends ${g.constraint}` : ''}`)
139
+ .join(', ');
140
+ const header = params ? `${name}<${params}>` : name;
141
+
142
+ // Verbatim RHS escape hatch — shown as-is when the shape doesn't fit one
143
+ // of the structured buckets below. Wins over everything else.
144
+ if (tpe?.rhs) return `type ${header} = ${tpe.rhs};`;
145
+ if (tpe?.aliasOf) return `type ${header} = ${tpe.aliasOf};`;
146
+ if (tpe?.signature) {
147
+ const sigParams = formatParams(tpe.signature.parameters ?? []);
148
+ const ret = tpe.signature.returnType ?? 'void';
149
+ return `type ${header} = (${sigParams}) => ${ret};`;
150
+ }
151
+ if (tpe?.unionOf?.length) {
152
+ return `type ${header} = ${tpe.unionOf.join(' | ')};`;
153
+ }
154
+ if (construct === 'enum') {
155
+ const members = tpe?.enumMembers?.length
156
+ ? tpe.enumMembers.map((m) => `${m.name}${m.value ? ` = ${m.value}` : ''}`).join(', ')
157
+ : (tpe?.properties ?? []).map((p) => p.name).join(', ');
158
+ return `enum ${header} { ${members} }`;
159
+ }
160
+
136
161
  const props = (tpe?.properties ?? [])
137
162
  .map((p) => ` ${p.name}${p.type ? `: ${p.type}` : ''};`)
138
163
  .join('\n');
139
164
 
140
165
  switch (construct) {
141
- case 'enum':
142
- return `enum ${name} { ${(tpe?.properties ?? []).map((p) => p.name).join(', ')} }`;
143
166
  case 'type_alias':
144
167
  return props
145
- ? `type ${name} = {\n${props}\n};`
146
- : `type ${name} = unknown;`;
168
+ ? `type ${header} = {\n${props}\n};`
169
+ : `type ${header} = unknown;`;
147
170
  default:
148
171
  if (props) {
149
- return `interface ${name} {\n${props}\n}`;
172
+ return `interface ${header} {\n${props}\n}`;
150
173
  }
151
- return `interface ${name} {}`;
174
+ return `interface ${header} {}`;
152
175
  }
153
176
  }
154
177
 
155
- function generateModule(detail?: GraphifyComponentDetail): string {
156
- const mod = detail?.kind === 'module' ? detail : undefined;
178
+ function generateModule(declaration?: GraphifyComponentDetail): string {
179
+ const mod = declaration?.kind === 'module' ? declaration : undefined;
157
180
  if (!mod) return 'module {}';
158
181
 
159
182
  const parts: string[] = [];
@@ -174,14 +197,15 @@ function generateModule(detail?: GraphifyComponentDetail): string {
174
197
  * the state members, never a class/method stub. The node's name labels the
175
198
  * block; the access mechanism lives in separate accessor nodes.
176
199
  */
177
- function generateStore(name: string, detail?: GraphifyComponentDetail): string {
178
- const store = detail?.kind === 'store' ? detail : undefined;
200
+ function generateStore(name: string, declaration?: GraphifyComponentDetail): string {
201
+ const store = declaration?.kind === 'store' ? declaration : undefined;
202
+ const backing = store?.storage ? `\n// backing: ${store.storage}` : '';
179
203
  const props = (store?.properties ?? [])
180
204
  .map((p) => `declare const ${p.name}${p.type ? `: ${p.type}` : ''};`)
181
205
  .join('\n');
182
206
 
183
207
  if (!props) {
184
- return `// store: ${name} — no captured state members`;
208
+ return `// store: ${name} — no captured state members${backing}`;
185
209
  }
186
- return `// store: ${name}\n${props}`;
210
+ return `// store: ${name}${backing}\n${props}`;
187
211
  }
@@ -17,26 +17,28 @@ import {
17
17
  import type { SubsystemComponent, SubsystemComponentEdge } from './model';
18
18
 
19
19
  const comps: SubsystemComponent[] = [
20
- { id: 'reader', name: 'SessionReader', kind: 'class', file: 'SessionReader.ts', purl: 'pkg:github/principal-ai/agent-monitoring' },
21
- { id: 'transcript', name: 'transcript', kind: 'module', file: 'transcript.ts', purl: 'pkg:github/principal-ai/agent-monitoring' },
20
+ { id: 'reader', name: 'SessionReader', construct: 'class', file: 'SessionReader.ts', purl: 'pkg:github/principal-ai/agent-monitoring' },
21
+ { id: 'transcript', name: 'transcript', construct: 'function', file: 'transcript.ts', purl: 'pkg:github/principal-ai/agent-monitoring' },
22
22
  ];
23
23
 
24
- const edges: SubsystemComponentEdge[] = [
25
- { id: 'e1', from: 'transcript', to: 'reader', mechanism: 'imports' },
24
+ const relations = [
25
+ { id: 'e1', from: 'transcript', to: 'reader', relationType: 'imports' as const },
26
26
  // 'host' is NOT a component — this is the cross-package external case.
27
- { id: 'e2', from: 'reader', to: 'host', mechanism: 'imports', refs: ['bun/index.ts'] },
27
+ { id: 'e2', from: 'reader', to: 'host', relationType: 'imports' as const, refs: ['bun/index.ts'] },
28
28
  ];
29
29
 
30
+ const doc = { components: comps, relations };
31
+
30
32
  describe('subsystem graph model', () => {
31
33
  test('converts all components to flat component nodes', () => {
32
- const nodes = convertSubsystemToNodes({ components: comps, edges });
34
+ const nodes = convertSubsystemToNodes(doc);
33
35
  const components = nodes.filter((n) => n.type === 'subsystem-component');
34
36
  expect(components).toHaveLength(comps.length);
35
37
  expect(components.every((n) => n.type === 'subsystem-component')).toBe(true);
36
38
  });
37
39
 
38
40
  test('converts edges with directed markers', () => {
39
- const converted = convertSubsystemToEdges({ components: comps, edges });
41
+ const converted = convertSubsystemToEdges(doc);
40
42
  expect(converted).toHaveLength(2);
41
43
  expect(converted[0].source).toBe('transcript');
42
44
  expect(converted[0].target).toBe('reader');
@@ -48,7 +50,7 @@ describe('subsystem graph model', () => {
48
50
  {
49
51
  id: "proposed-watcher",
50
52
  name: "watchDir",
51
- kind: "external",
53
+ construct: "external",
52
54
  // Intentionally omit file/purl — agents often leave these off for externals.
53
55
  file: undefined as unknown as string,
54
56
  purl: undefined as unknown as string,
@@ -56,13 +58,18 @@ describe('subsystem graph model', () => {
56
58
  ];
57
59
  const { nodes } = await buildSubsystemGraph({
58
60
  components: withExternal,
59
- edges: [{ id: 'e3', from: 'reader', to: 'proposed-watcher', mechanism: 'feeds' }],
61
+ relations: [],
62
+ walkthroughs: [{
63
+ id: 'w1',
64
+ title: 'feed',
65
+ steps: [{ from: 'reader', to: 'proposed-watcher', mechanism: 'feeds', file: 'x.ts', line: 1 }],
66
+ }],
60
67
  });
61
68
  expect(nodes.find((n) => n.id === 'proposed-watcher')).toBeDefined();
62
69
  });
63
70
 
64
71
  test('buildSubsystemGraph creates external stub nodes for non-component targets', async () => {
65
- const { nodes, edges: gEdges } = await buildSubsystemGraph({ components: comps, edges });
72
+ const { nodes, edges: gEdges } = await buildSubsystemGraph(doc);
66
73
  const external = nodes.find((n) => n.id === 'external:host');
67
74
  expect(external).toBeDefined();
68
75
  expect(external!.data.component.construct).toBe('external');
@@ -71,7 +78,7 @@ describe('subsystem graph model', () => {
71
78
  });
72
79
 
73
80
  test('buildSubsystemGraph positions nodes via ELK (non-zero coords)', async () => {
74
- const { nodes } = await buildSubsystemGraph({ components: comps, edges });
81
+ const { nodes } = await buildSubsystemGraph(doc);
75
82
  const placed = nodes.filter((n) => n.type === 'subsystem-component' && n.position);
76
83
  expect(placed.length).toBeGreaterThan(0);
77
84
  // ELK (or the grid fallback) gives finite coordinates.
@@ -218,7 +225,7 @@ describe('subsystem graph model', () => {
218
225
  { id: 'a', name: 'a', construct: 'function', file: 'a.ts', purl: 'pkg:github/acme/app', process: 'app/host' },
219
226
  { id: 'd', name: 'd', construct: 'function', file: 'd.ts', purl: 'pkg:github/acme/app' },
220
227
  ],
221
- edges: [],
228
+ relations: [],
222
229
  });
223
230
  expect((nodes.find((n) => n.id === 'a') as { parentId?: string }).parentId).toBe(
224
231
  processGroupNodeId('app/host'),
@@ -245,7 +252,12 @@ describe('subsystem graph model', () => {
245
252
  { id: 'b', name: 'b', construct: 'function', file: 'b.ts', purl: 'pkg:github/acme/app', process: 'app/host' },
246
253
  { id: 'solo', name: 'solo', construct: 'function', file: 's.ts', purl: 'pkg:github/acme/app', process: 'app/lonely' },
247
254
  ],
248
- edges: [{ id: 'e1', from: 'a', to: 'b', mechanism: 'calls' }],
255
+ relations: [],
256
+ walkthroughs: [{
257
+ id: 'w1',
258
+ title: 'call',
259
+ steps: [{ from: 'a', to: 'b', mechanism: 'calls', file: 'a.ts', line: 1 }],
260
+ }],
249
261
  });
250
262
  expect(regions.map((r) => r.key)).toEqual(['app/host']);
251
263
  expect((nodes.find((n) => n.id === 'solo') as { parentId?: string }).parentId).toBeUndefined();
@@ -253,7 +265,7 @@ describe('subsystem graph model', () => {
253
265
  });
254
266
 
255
267
  test('subsystemGraphLayoutKey ignores declarationRef-only changes', () => {
256
- const base = { components: comps, edges };
268
+ const base = doc;
257
269
  const withRef = {
258
270
  components: comps.map((c, i) =>
259
271
  i === 0
@@ -268,7 +280,7 @@ describe('subsystem graph model', () => {
268
280
  }
269
281
  : c,
270
282
  ),
271
- edges,
283
+ relations,
272
284
  };
273
285
  expect(subsystemGraphLayoutKey(base)).toBe(subsystemGraphLayoutKey(withRef));
274
286
  });