@principal-ai/subsystems-react 0.21.1 → 0.22.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 (67) hide show
  1. package/dist/graphify/consolidated.d.ts +5 -24
  2. package/dist/graphify/consolidated.d.ts.map +1 -1
  3. package/dist/graphify/index.d.ts +1 -1
  4. package/dist/graphify/index.d.ts.map +1 -1
  5. package/dist/graphify/index.js.map +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/pierre/PierreSnippetView.d.ts.map +1 -1
  10. package/dist/pierre/PierreSnippetView.js +4 -19
  11. package/dist/pierre/PierreSnippetView.js.map +1 -1
  12. package/dist/pierre/PierreWalkthroughCodeView.d.ts.map +1 -1
  13. package/dist/pierre/PierreWalkthroughCodeView.js +20 -3
  14. package/dist/pierre/PierreWalkthroughCodeView.js.map +1 -1
  15. package/dist/pierre/constructColors.d.ts.map +1 -1
  16. package/dist/pierre/constructColors.js +0 -5
  17. package/dist/pierre/constructColors.js.map +1 -1
  18. package/dist/pierre/index.d.ts +1 -1
  19. package/dist/pierre/index.d.ts.map +1 -1
  20. package/dist/pierre/index.js +1 -1
  21. package/dist/pierre/index.js.map +1 -1
  22. package/dist/pierre/sliceSnippet.d.ts +6 -0
  23. package/dist/pierre/sliceSnippet.d.ts.map +1 -1
  24. package/dist/pierre/sliceSnippet.js +25 -0
  25. package/dist/pierre/sliceSnippet.js.map +1 -1
  26. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -1
  27. package/dist/stories/Subsystem/ComponentGraph/fixtures.js +0 -3
  28. package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -1
  29. package/dist/subsystem/formatDeclaration.d.ts.map +1 -1
  30. package/dist/subsystem/formatDeclaration.js +0 -15
  31. package/dist/subsystem/formatDeclaration.js.map +1 -1
  32. package/dist/subsystem/model.d.ts +61 -22
  33. package/dist/subsystem/model.d.ts.map +1 -1
  34. package/dist/subsystem/model.js +186 -63
  35. package/dist/subsystem/model.js.map +1 -1
  36. package/dist/subsystem/nodes.d.ts +3 -4
  37. package/dist/subsystem/nodes.d.ts.map +1 -1
  38. package/dist/subsystem/nodes.js +5 -6
  39. package/dist/subsystem/nodes.js.map +1 -1
  40. package/dist/utils/elkLayout.d.ts +6 -4
  41. package/dist/utils/elkLayout.d.ts.map +1 -1
  42. package/dist/utils/elkLayout.js +144 -54
  43. package/dist/utils/elkLayout.js.map +1 -1
  44. package/package.json +3 -3
  45. package/src/graphify/consolidated.ts +4 -26
  46. package/src/graphify/index.ts +0 -2
  47. package/src/index.ts +0 -2
  48. package/src/pierre/PierreSnippetView.tsx +4 -18
  49. package/src/pierre/PierreWalkthroughCodeView.tsx +39 -3
  50. package/src/pierre/constructColors.test.ts +1 -2
  51. package/src/pierre/constructColors.ts +0 -5
  52. package/src/pierre/index.ts +1 -1
  53. package/src/pierre/sliceSnippet.test.ts +44 -1
  54. package/src/pierre/sliceSnippet.ts +28 -0
  55. package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +0 -31
  56. package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +2 -46
  57. package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +9 -24
  58. package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +2 -2
  59. package/src/stories/Subsystem/ComponentGraph/Modules.stories.tsx +287 -0
  60. package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +1 -1
  61. package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +6 -6
  62. package/src/stories/Subsystem/ComponentGraph/fixtures.ts +0 -3
  63. package/src/subsystem/formatDeclaration.ts +0 -19
  64. package/src/subsystem/model.test.ts +190 -9
  65. package/src/subsystem/model.ts +219 -73
  66. package/src/subsystem/nodes.tsx +6 -6
  67. package/src/utils/elkLayout.ts +148 -58
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/subsystems-react",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
4
4
  "description": "React UI for Subsystem Models — graph, Pierre code views, and session-event feeds",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "peerDependencies": {
38
38
  "@pierre/diffs": ">=1.1.20",
39
39
  "@principal-ade/industry-theme": "^0.1.7",
40
- "@principal-ai/subsystems-core": ">=0.32.0",
40
+ "@principal-ai/subsystems-core": ">=0.33.0",
41
41
  "react": "^18.0.0 || ^19.0.0",
42
42
  "react-dom": "^18.0.0 || ^19.0.0"
43
43
  },
@@ -45,7 +45,7 @@
45
45
  "@pierre/diffs": "1.3.6",
46
46
  "@principal-ade/industry-theme": "0.1.7",
47
47
  "@principal-ai/agent-monitoring": "^0.3.38",
48
- "@principal-ai/subsystems-core": "0.32.0",
48
+ "@principal-ai/subsystems-core": "0.33.0",
49
49
  "@storybook/addon-docs": "10.1.2",
50
50
  "@storybook/addon-links": "10.1.2",
51
51
  "@storybook/addon-onboarding": "10.1.2",
@@ -113,18 +113,6 @@ export interface GraphifyReferenceInfo {
113
113
  source_location?: string;
114
114
  }
115
115
 
116
- /** An import relationship (`imports` / `imports_from` / `re_exports`). */
117
- export interface GraphifyImportInfo {
118
- /** The imported module/file node id. */
119
- nodeId: string;
120
- /** The imported module/file label. */
121
- name: string;
122
- /** Which relation carried the import. */
123
- relation?: GraphifyRelation;
124
- /** `L<line>` of the import statement. */
125
- source_location?: string;
126
- }
127
-
128
116
  // ---------------------------------------------------------------------------
129
117
  // Discriminated union — the drill-down payload
130
118
  // ---------------------------------------------------------------------------
@@ -207,17 +195,6 @@ export interface GraphifyTypeDetail {
207
195
  rhs?: string;
208
196
  }
209
197
 
210
- /** A module/file-like node: a `contains` target with a filename label. */
211
- export interface GraphifyModuleDetail {
212
- kind: 'module';
213
- /** `re_exports` targets / contained public symbols. */
214
- exports: string[];
215
- /** `imports` / `imports_from` relationships. */
216
- imports: GraphifyImportInfo[];
217
- /** Symbols contained in the module (`contains` targets). */
218
- symbols: string[];
219
- }
220
-
221
198
  /** A facet-only component with no graphify node (external consumer stub). */
222
199
  export interface GraphifyExternalDetail {
223
200
  kind: 'external';
@@ -281,15 +258,16 @@ export interface GraphifyMethodDetail {
281
258
  *
282
259
  * The discriminant is derived from graph structure, not read off the node:
283
260
  * method edges → class; `()` label + no method edges → function; incoming
284
- * `implements` → type; else module. `external` covers consumer stubs.
285
- * `method` covers standalone method components selected from a class.
261
+ * `implements` → type. File/module Graphify nodes are not subsystem
262
+ * declaration kinds — anchor to a concrete export instead. `external`
263
+ * covers consumer stubs. `method` covers standalone method components
264
+ * selected from a class.
286
265
  */
287
266
  export type GraphifyComponentDetail =
288
267
  | GraphifyClassDetail
289
268
  | GraphifyFunctionDetail
290
269
  | GraphifyMethodDetail
291
270
  | GraphifyTypeDetail
292
- | GraphifyModuleDetail
293
271
  | GraphifyExternalDetail
294
272
  | GraphifyCustomEntityDetail
295
273
  | GraphifyStoreDetail;
@@ -25,11 +25,9 @@ export type {
25
25
  GraphifyParamInfo,
26
26
  GraphifyCallInfo,
27
27
  GraphifyReferenceInfo,
28
- GraphifyImportInfo,
29
28
  GraphifyClassDetail,
30
29
  GraphifyFunctionDetail,
31
30
  GraphifyTypeDetail,
32
- GraphifyModuleDetail,
33
31
  GraphifyExternalDetail,
34
32
  GraphifyCustomEntityDetail,
35
33
  GraphifyCustomEntityAttribute,
package/src/index.ts CHANGED
@@ -37,11 +37,9 @@ export type {
37
37
  GraphifyParamInfo,
38
38
  GraphifyCallInfo,
39
39
  GraphifyReferenceInfo,
40
- GraphifyImportInfo,
41
40
  GraphifyClassDetail,
42
41
  GraphifyFunctionDetail,
43
42
  GraphifyTypeDetail,
44
- GraphifyModuleDetail,
45
43
  GraphifyExternalDetail,
46
44
  GraphifyCustomEntityDetail,
47
45
  GraphifyCustomEntityAttribute,
@@ -13,7 +13,7 @@ import { File } from '@pierre/diffs/react';
13
13
  import { useTheme } from '@principal-ade/industry-theme';
14
14
  import { buildPierreOptions, PIERRE_FILE_STYLE } from './pierreBackground';
15
15
  import { pierreLangForPath } from './pierreFileLang';
16
- import { sliceSnippetWindow } from './sliceSnippet';
16
+ import { remapSnippetLineNumbers, sliceSnippetWindow } from './sliceSnippet';
17
17
 
18
18
  import { scrollAnchorLine } from './scrollAnchor';
19
19
 
@@ -101,30 +101,16 @@ export function PierreSnippetView({
101
101
  [fileName, filePath, slice],
102
102
  );
103
103
 
104
- const lineNumberOffset = slice ? slice.sliceStart - 1 : 0;
105
-
106
104
  const onPostRender = useCallback(
107
105
  (fileContainer: HTMLElement) => {
108
- if (lineNumberOffset !== 0) {
109
- const root = fileContainer.shadowRoot ?? fileContainer;
110
- const items = root.querySelectorAll('[data-column-number][data-line-index]');
111
- items.forEach((el) => {
112
- const idxStr = (el as HTMLElement).dataset.lineIndex;
113
- if (idxStr == null) return;
114
- const idx = Number.parseInt(idxStr, 10);
115
- if (Number.isNaN(idx)) return;
116
- const display = String(idx + 1 + lineNumberOffset);
117
- const span = el.querySelector('[data-line-number-content]');
118
- if (span && span.textContent !== display) {
119
- span.textContent = display;
120
- }
121
- });
106
+ if (slice != null) {
107
+ remapSnippetLineNumbers(fileContainer, slice.sliceStart);
122
108
  }
123
109
  if (slice?.focusOffset != null) {
124
110
  scrollFocusLineIntoView(fileContainer, slice.focusOffset);
125
111
  }
126
112
  },
127
- [lineNumberOffset, slice?.focusOffset],
113
+ [slice],
128
114
  );
129
115
 
130
116
  const options = useMemo(
@@ -7,7 +7,14 @@
7
7
  * `PierreSnippetView`).
8
8
  */
9
9
 
10
- import { useEffect, useMemo, useRef, useState, type ReactElement } from 'react';
10
+ import {
11
+ useCallback,
12
+ useEffect,
13
+ useMemo,
14
+ useRef,
15
+ useState,
16
+ type ReactElement,
17
+ } from 'react';
11
18
  import {
12
19
  CodeView,
13
20
  type CodeViewHandle,
@@ -32,7 +39,11 @@ import {
32
39
  pierreLangForPath,
33
40
  } from './pierreFileLang';
34
41
  import { resolvePierreSyntaxThemeName } from './pierreSyntaxTheme';
35
- import { sliceSnippetWindow, type SnippetSlice } from './sliceSnippet';
42
+ import {
43
+ remapSnippetLineNumbers,
44
+ sliceSnippetWindow,
45
+ type SnippetSlice,
46
+ } from './sliceSnippet';
36
47
 
37
48
  export interface PierreWalkthroughCodeViewProps {
38
49
  walkthrough: SubsystemWalkthrough;
@@ -154,6 +165,30 @@ const items = useMemo((): CodeViewItem<WalkthroughStepAnnotation>[] => {
154
165
  };
155
166
  }, [stepIndex, slices, walkthrough.id]);
156
167
 
168
+ const sliceStartByItemId = useMemo(() => {
169
+ const map = new Map<string, number>();
170
+ for (let i = 0; i < slices.length; i++) {
171
+ map.set(stepItemId(walkthrough.id, i), slices[i]!.sliceStart);
172
+ }
173
+ return map;
174
+ }, [slices, walkthrough.id]);
175
+
176
+ const onPostRender = useCallback(
177
+ (
178
+ node: HTMLElement,
179
+ _instance: unknown,
180
+ _phase: unknown,
181
+ context?: { item?: { id?: string } },
182
+ ) => {
183
+ const id = context?.item?.id;
184
+ if (id == null) return;
185
+ const sliceStart = sliceStartByItemId.get(id);
186
+ if (sliceStart == null) return;
187
+ remapSnippetLineNumbers(node, sliceStart);
188
+ },
189
+ [sliceStartByItemId],
190
+ );
191
+
157
192
  const renderHeaderPrefix = useMemo(() => {
158
193
  return (item: CodeViewItem) => {
159
194
  const index = Number.parseInt(item.id.split(':').pop() ?? '', 10);
@@ -235,10 +270,11 @@ const items = useMemo((): CodeViewItem<WalkthroughStepAnnotation>[] => {
235
270
  stickyHeaders: true,
236
271
  disableFileHeader: false,
237
272
  layout: { paddingTop: 8, paddingBottom: 16, gap: 12 },
273
+ onPostRender,
238
274
  ...(background ? buildPierreOptions(background) : {}),
239
275
  ...(mode === 'light' || mode === 'dark' ? { themeType: mode } : {}),
240
276
  };
241
- }, [background, mode]);
277
+ }, [background, mode, onPostRender]);
242
278
 
243
279
  useEffect(() => {
244
280
  if (load.status !== 'ready' || stepIndex == null) return;
@@ -13,7 +13,6 @@ const CONSTRUCTS: SubsystemComponentConstruct[] = [
13
13
  'interface',
14
14
  'type_alias',
15
15
  'enum',
16
- 'module',
17
16
  'store',
18
17
  'external',
19
18
  'custom_entity',
@@ -31,7 +30,7 @@ describe('constructColorsFromPierreTheme', () => {
31
30
  }
32
31
  });
33
32
 
34
- test('all ten constructs are distinguishable within a theme', () => {
33
+ test('all nine constructs are distinguishable within a theme', () => {
35
34
  for (const themeName of ['pierre-dark', 'pierre-light'] as const) {
36
35
  const colors = constructColorsFromPierreTheme(themeName);
37
36
  const values = CONSTRUCTS.map((c) => colors[c]);
@@ -89,7 +89,6 @@ export function constructColorsFromPierreTheme(
89
89
  const classColor = pick('entity.name.class');
90
90
  const functionColor = pick('entity.name.function');
91
91
  const typeColor = pick('support.type');
92
- const moduleColor = pick('entity.name.namespace');
93
92
 
94
93
  return {
95
94
  class: classColor,
@@ -101,10 +100,6 @@ export function constructColorsFromPierreTheme(
101
100
  method: towardBackground(functionColor, 0.14),
102
101
  // enum members are constants — the generic constant hue
103
102
  enum: pick('constant'),
104
- // module and store share the constant hue — the module holds the store,
105
- // and the store IS the retained value, so the store keeps the pure
106
- // `variable.other.constant` color and the module takes the shade
107
- module: towardBackground(moduleColor, 0.18),
108
103
  store: pick('variable.other.constant'),
109
104
  external: pick('comment'),
110
105
  // custom entities are actors, not code — the heading/emphasis coral reads
@@ -4,7 +4,7 @@ export { PierreSnippetView } from './PierreSnippetView';
4
4
  export type { PierreSnippetViewProps } from './PierreSnippetView';
5
5
  export { PierreWalkthroughCodeView } from './PierreWalkthroughCodeView';
6
6
  export type { PierreWalkthroughCodeViewProps } from './PierreWalkthroughCodeView';
7
- export { sliceSnippetWindow } from './sliceSnippet';
7
+ export { remapSnippetLineNumbers, sliceSnippetWindow } from './sliceSnippet';
8
8
  export type { SnippetSlice } from './sliceSnippet';
9
9
  export {
10
10
  isPierreCFamilyPath,
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
- import { sliceSnippetWindow } from './sliceSnippet';
2
+ import { Window } from 'happy-dom';
3
+ import { remapSnippetLineNumbers, sliceSnippetWindow } from './sliceSnippet';
3
4
 
4
5
  describe('sliceSnippetWindow', () => {
5
6
  const content = ['line1', 'line2', 'line3', 'line4', 'line5'].join('\n');
@@ -19,3 +20,45 @@ describe('sliceSnippetWindow', () => {
19
20
  expect(s.focusOffset).toBe(95);
20
21
  });
21
22
  });
23
+
24
+ describe('remapSnippetLineNumbers', () => {
25
+ function gutter(doc: Document, lineIndex: number, label: string): HTMLElement {
26
+ const el = doc.createElement('div');
27
+ el.setAttribute('data-column-number', '');
28
+ el.dataset.lineIndex = String(lineIndex);
29
+ const span = doc.createElement('span');
30
+ span.setAttribute('data-line-number-content', '');
31
+ span.textContent = label;
32
+ el.appendChild(span);
33
+ return el;
34
+ }
35
+
36
+ test('rewrites gutters to absolute file lines', () => {
37
+ const win = new Window();
38
+ const doc = win.document;
39
+ const root = doc.createElement('div');
40
+ root.appendChild(gutter(doc, 0, '1'));
41
+ root.appendChild(gutter(doc, 1, '2'));
42
+ root.appendChild(gutter(doc, 2, '3'));
43
+
44
+ remapSnippetLineNumbers(root as unknown as HTMLElement, 250);
45
+
46
+ const labels = [...root.querySelectorAll('[data-line-number-content]')].map(
47
+ (n) => n.textContent,
48
+ );
49
+ expect(labels).toEqual(['250', '251', '252']);
50
+ });
51
+
52
+ test('no-ops when slice already starts at line 1', () => {
53
+ const win = new Window();
54
+ const doc = win.document;
55
+ const root = doc.createElement('div');
56
+ root.appendChild(gutter(doc, 0, '1'));
57
+
58
+ remapSnippetLineNumbers(root as unknown as HTMLElement, 1);
59
+
60
+ expect(
61
+ root.querySelector('[data-line-number-content]')?.textContent,
62
+ ).toBe('1');
63
+ });
64
+ });
@@ -29,3 +29,31 @@ export function sliceSnippetWindow(
29
29
  focusLine == null ? null : Math.max(1, focusLine - sliceStart + 1),
30
30
  };
31
31
  }
32
+
33
+ /**
34
+ * Remap Pierre gutter numbers from slice-local (1-based) to absolute file lines.
35
+ * Pierre numbers whatever `contents` it receives starting at 1; sliced snippets
36
+ * need `sliceStart` applied so the gutter matches the source file.
37
+ */
38
+ export function remapSnippetLineNumbers(
39
+ fileContainer: HTMLElement,
40
+ sliceStart: number,
41
+ ): void {
42
+ const lineNumberOffset = sliceStart - 1;
43
+ if (lineNumberOffset === 0) return;
44
+ const root = fileContainer.shadowRoot ?? fileContainer;
45
+ const items = root.querySelectorAll(
46
+ '[data-column-number][data-line-index]',
47
+ );
48
+ items.forEach((el) => {
49
+ const idxStr = (el as HTMLElement).dataset.lineIndex;
50
+ if (idxStr == null) return;
51
+ const idx = Number.parseInt(idxStr, 10);
52
+ if (Number.isNaN(idx)) return;
53
+ const display = String(idx + 1 + lineNumberOffset);
54
+ const span = el.querySelector('[data-line-number-content]');
55
+ if (span && span.textContent !== display) {
56
+ span.textContent = display;
57
+ }
58
+ });
59
+ }
@@ -197,37 +197,6 @@ const cases: { label: string; component: SubsystemComponent }[] = [
197
197
  } satisfies GraphifyComponentDetail,
198
198
  },
199
199
  },
200
- {
201
- label: 'module — imports + exports',
202
- component: {
203
- id: 'mod-full',
204
- name: 'index',
205
- construct: 'module',
206
- file: 'src/index.ts',
207
- purl: 'pkg:github/principal-ai/agent-monitoring',
208
- symbol: 'index',
209
- declaration: {
210
- kind: 'module',
211
- imports: [
212
- { name: './session/SessionReader' },
213
- { name: './event-processing/EventProcessor' },
214
- ],
215
- exports: ['SessionReader', 'EventProcessor'],
216
- symbols: ['SessionReader', 'EventProcessor', 'normalizeSession'],
217
- } satisfies GraphifyComponentDetail,
218
- },
219
- },
220
- {
221
- label: 'module — no detail (fallback)',
222
- component: {
223
- id: 'mod-plain',
224
- name: 'utils',
225
- construct: 'module',
226
- file: 'src/utils.ts',
227
- purl: 'pkg:github/principal-ai/agent-monitoring',
228
- symbol: 'utils',
229
- },
230
- },
231
200
  {
232
201
  label: 'external',
233
202
  component: {
@@ -109,7 +109,7 @@ export const NamingConventions: Story = {
109
109
  };
110
110
 
111
111
  // ---------------------------------------------------------------------------
112
- // Kind variations — one column per kind (class / function / type / module /
112
+ // Kind variations — one column per kind (class / function / type / external —
113
113
  // external), rows going bare → detailed. Click a node to see its declaration
114
114
  // panel; type names inside it are clickable when they match another node here.
115
115
  // ---------------------------------------------------------------------------
@@ -269,50 +269,6 @@ const kindVariationComponents: SubsystemComponent[] = [
269
269
  } satisfies GraphifyComponentDetail,
270
270
  },
271
271
 
272
- // --- module: bare → exports only → exports + imports
273
- {
274
- id: 'mod-bare',
275
- name: 'transcript',
276
- construct: 'module',
277
- file: 'src/session/transcript.ts',
278
- purl: variationPurl,
279
- purpose: 'no drill-down — symbol-less module named from its file basename',
280
- symbol: '',
281
- layer: 4,
282
- },
283
- {
284
- id: 'mod-exports',
285
- name: 'paths',
286
- construct: 'module',
287
- file: 'src/session/paths.ts',
288
- purl: variationPurl,
289
- purpose: 'exports only — export statement + defines comment',
290
- symbol: '',
291
- layer: 4,
292
- declaration: {
293
- kind: 'module',
294
- exports: ['extractToolName', 'extractFilePath'],
295
- imports: [],
296
- symbols: ['extractToolName', 'extractFilePath'],
297
- } satisfies GraphifyComponentDetail,
298
- },
299
- {
300
- id: 'mod-full',
301
- name: 'index',
302
- construct: 'module',
303
- file: 'src/index.ts',
304
- purl: variationPurl,
305
- purpose: 'full — import statements + re-export statement + defines comment',
306
- symbol: '',
307
- layer: 4,
308
- declaration: {
309
- kind: 'module',
310
- exports: ['SessionReader', 'SessionStore'],
311
- imports: [{ nodeId: 'i1', name: 'transcript', relation: 'imports_from' }],
312
- symbols: ['SessionReader', 'SessionStore'],
313
- } satisfies GraphifyComponentDetail,
314
- },
315
-
316
272
  // --- external: bare → labeled
317
273
  {
318
274
  id: 'ext-bare',
@@ -351,7 +307,7 @@ function KindVariationsDemo() {
351
307
  onSelect={(id) => setSelected(id)}
352
308
  />
353
309
  <div style={{ marginTop: 8, fontFamily: 'monospace', fontSize: 12, color: '#aaa' }}>
354
- columns: class · function · type · module · external — each goes bare → detailed
310
+ columns: class · function · type · external — each goes bare → detailed
355
311
  {selected ? ` · selected: ${selected}` : ''}
356
312
  </div>
357
313
  </div>
@@ -31,10 +31,10 @@ type Story = StoryObj<typeof meta>;
31
31
  // ---------------------------------------------------------------------------
32
32
  const v2ReaderComponents = components([
33
33
  ['capture', 'capture script', 'function', 'scripts/capture-session.ts', 'pkg:github/principal-ai/agent-monitoring', 'captures a real session for fixtures'],
34
- ['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards'],
35
- ['paths', 'paths', 'module', 'paths.ts', 'pkg:github/principal-ai/agent-monitoring', 'extracts tool names + file paths'],
34
+ ['transcript', 'transcript', 'function', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards'],
35
+ ['paths', 'paths', 'function', 'paths.ts', 'pkg:github/principal-ai/agent-monitoring', 'extracts tool names + file paths'],
36
36
  ['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader.normalize', readerDetail],
37
- ['registry', 'supported-agents', 'module', 'supported-agents.ts', 'pkg:github/principal-ai/agent-monitoring', 'registry of supported agents (the shared seam)', 'registerAgent'],
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
40
  const v2ReaderEdges = graphSpecFromEdges([
@@ -95,11 +95,11 @@ const minimalComponents = components([
95
95
  ['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader'],
96
96
  ['normalize', 'normalize', 'function', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'maps a session into universal events', 'SessionReader.normalize'],
97
97
  ['record', 'SessionRecord', 'type', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'the parsed codex session record', 'SessionRecord'],
98
- ['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
98
+ ['transcript', 'transcript', 'function', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
99
99
  ]);
100
100
 
101
101
  const sharedEdges = graphSpecFromEdges([
102
- ['transcript', 'record', 'defines'],
102
+ ['transcript', 'record', 'references'],
103
103
  ['reader', 'normalize', 'method'],
104
104
  ['normalize', 'record', 'references'],
105
105
  ]);
@@ -129,15 +129,6 @@ const resolvedComponents: SubsystemComponent[] = [
129
129
  implementors: ['SessionReaderLike'],
130
130
  } satisfies GraphifyComponentDetail,
131
131
  },
132
- {
133
- ...minimalComponents[3],
134
- declaration: {
135
- kind: 'module',
136
- exports: ['CodexRolloutRecord', 'CodexSessionMeta'],
137
- imports: [{ nodeId: 'i1', name: 'paths', relation: 'imports_from' }],
138
- symbols: ['CodexRolloutRecord', 'CodexSessionMeta'],
139
- } satisfies GraphifyComponentDetail,
140
- },
141
132
  ];
142
133
 
143
134
  function MinimalVsResolvedDemo({ resolved }: { resolved: boolean }) {
@@ -174,22 +165,16 @@ const investigationComponents: SubsystemComponent[] = [
174
165
  {
175
166
  id: 'adapter',
176
167
  name: 'OpenCodeAdapter',
177
- construct: 'module',
168
+ construct: 'function',
178
169
  file: 'apps/server/src/provider/Layers/OpenCodeAdapter.ts',
179
170
  purl: 'pkg:github/t3code/t3code',
180
171
  purpose: 'adapts opencode session/threads + events to the t3 runtime',
181
172
  symbol: 'makeOpenCodeAdapter',
182
- declaration: {
183
- kind: 'module',
184
- exports: ['makeOpenCodeAdapter', 'OpenCodeAdapterLiveOptions'],
185
- imports: [{ nodeId: 'i1', name: 'orchestration', relation: 'imports_from' }],
186
- symbols: ['makeOpenCodeAdapter', 'isOpenCodeNotFound', 'OpenCodeSessionContext'],
187
- } satisfies GraphifyComponentDetail,
188
173
  },
189
174
  {
190
175
  id: 'ingestion',
191
176
  name: 'ProviderRuntimeIngestion',
192
- construct: 'module',
177
+ construct: 'function',
193
178
  file: 'apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts',
194
179
  purl: 'pkg:github/t3code/t3code',
195
180
  purpose: 'ingests provider events into the runtime',
@@ -198,7 +183,7 @@ const investigationComponents: SubsystemComponent[] = [
198
183
  {
199
184
  id: 'contracts',
200
185
  name: 'orchestration',
201
- construct: 'module',
186
+ construct: 'function',
202
187
  file: 'packages/contracts/src/orchestration.ts',
203
188
  purl: 'pkg:github/t3code/t3code',
204
189
  purpose: 'contracts for orchestration/providers',
@@ -207,7 +192,7 @@ const investigationComponents: SubsystemComponent[] = [
207
192
  ];
208
193
 
209
194
  const investigationEdges = graphSpecFromEdges([
210
- ['adapter', 'contracts', 'imports_from'],
195
+ ['adapter', 'contracts', 'imports'],
211
196
  ['ingestion', 'adapter', 'uses'],
212
197
  ['ingestion', 'contracts', 'references'],
213
198
  ]);
@@ -234,7 +234,7 @@ const declarationOpenComponents: SubsystemComponent[] = [
234
234
  {
235
235
  id: 'detail',
236
236
  name: 'ComponentDeclaration',
237
- construct: 'module',
237
+ construct: 'function',
238
238
  file: 'packages/subsystems-react/src/subsystem/ComponentDeclaration.tsx',
239
239
  purl: 'pkg:github/principal-ai/principal-view-core-library',
240
240
  purpose: 'declaration panel — click file or L251 to open the drawer at the export line',
@@ -249,7 +249,7 @@ const declarationOpenComponents: SubsystemComponent[] = [
249
249
  {
250
250
  id: 'resolver',
251
251
  name: 'resolve.ts',
252
- construct: 'module',
252
+ construct: 'function',
253
253
  file: 'packages/subsystems-react/src/graphify/resolve.ts',
254
254
  purl: 'pkg:github/principal-ai/principal-view-core-library',
255
255
  purpose: 'graphify type-ref resolver (second file for tree navigation)',