@principal-ai/principal-view-react 0.16.25 → 0.16.26
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.
- package/dist/subsystem/model.d.ts +1 -1
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +8 -18
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +11 -85
- package/dist/subsystem/nodes.js.map +1 -1
- package/package.json +1 -1
- package/src/stories/SubsystemComponentGraph.stories.tsx +7 -7
- package/src/subsystem/model.test.ts +2 -4
- package/src/subsystem/model.ts +11 -26
- package/src/subsystem/nodes.tsx +11 -98
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { type Edge, type Node } from '@xyflow/react';
|
|
15
15
|
import type { GraphifyComponentDetail } from '../graphify';
|
|
16
|
-
export type SubsystemComponentKind = 'class' | '
|
|
16
|
+
export type SubsystemComponentKind = 'class' | 'function' | 'type' | 'module' | 'external';
|
|
17
17
|
export type SubsystemEdgeMechanism = 'imports' | 'imports_from' | 're_exports' | 'defines' | 'calls' | 'extends' | 'inherits' | 'implements' | 'mixes_in' | 'uses' | 'method' | 'references' | 'contains' | 'feeds' | 'produces' | 'registers-into';
|
|
18
18
|
/** A component node — the named unit, kind-tagged; `file` is its location. */
|
|
19
19
|
export interface SubsystemComponent {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAEL,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"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"}
|
package/dist/subsystem/model.js
CHANGED
|
@@ -26,10 +26,6 @@ import { computeElkLayout } from '../utils/elkLayout';
|
|
|
26
26
|
*/
|
|
27
27
|
export function deriveNameFromSymbol(symbol, kind, existingName, file) {
|
|
28
28
|
if (symbol && symbol.trim()) {
|
|
29
|
-
if (kind === 'method') {
|
|
30
|
-
const idx = symbol.lastIndexOf('.');
|
|
31
|
-
return idx >= 0 ? symbol.slice(idx + 1) : symbol;
|
|
32
|
-
}
|
|
33
29
|
return symbol;
|
|
34
30
|
}
|
|
35
31
|
// Module nodes without a symbol are whole files → use the file basename.
|
|
@@ -95,15 +91,10 @@ export function packageColor(name) {
|
|
|
95
91
|
/** Color per component kind — the informative signal (rather than package). */
|
|
96
92
|
export const KIND_COLOR = {
|
|
97
93
|
class: '#0893d2',
|
|
98
|
-
module: '#4ec9b0',
|
|
99
|
-
script: '#ff6b35',
|
|
100
|
-
registry: '#b48ead',
|
|
101
|
-
service: '#e3b341',
|
|
102
|
-
consumer: '#5aa9e6',
|
|
103
94
|
function: '#6c5ce7',
|
|
104
|
-
method: '#c586c0',
|
|
105
95
|
type: '#e07a5f',
|
|
106
|
-
|
|
96
|
+
module: '#4ec9b0',
|
|
97
|
+
external: '#b48ead', // purple
|
|
107
98
|
};
|
|
108
99
|
/**
|
|
109
100
|
* Convert a subsystem graph document into React Flow nodes. We render **flat**
|
|
@@ -135,27 +126,26 @@ export function convertSubsystemToNodes(doc, opts = {}) {
|
|
|
135
126
|
comps.forEach((c, i) => {
|
|
136
127
|
const col = i % COLS;
|
|
137
128
|
const row = Math.floor(i / COLS);
|
|
138
|
-
const isPkg = c.kind === 'package';
|
|
139
129
|
// Estimate rendered node width from the longest text line so ELK reserves
|
|
140
130
|
// the right space (names can wrap, so we cap at the configurable max).
|
|
141
131
|
const text = [c.symbol, c.name, c.file.split('/').pop() ?? '']
|
|
142
132
|
.filter((t) => !!t)
|
|
143
133
|
.sort((a, b) => b.length - a.length)[0];
|
|
144
|
-
const cap = maxNodeWidth ??
|
|
134
|
+
const cap = maxNodeWidth ?? 300;
|
|
145
135
|
const textWidth = Math.min(cap, Math.max(60, (text?.length ?? 10) * 8));
|
|
146
136
|
// Account for CSS minWidth and padding/border so ELK's port positions match
|
|
147
137
|
// the actual rendered node boundaries.
|
|
148
|
-
const cssMinWidth =
|
|
149
|
-
const cssPadding =
|
|
138
|
+
const cssMinWidth = 150;
|
|
139
|
+
const cssPadding = 20; // horizontal padding (left + right)
|
|
150
140
|
const cssBorder = 4; // 2px border each side
|
|
151
|
-
const rawWidth = Math.max(cssMinWidth,
|
|
141
|
+
const rawWidth = Math.max(cssMinWidth, textWidth + cssPadding + cssBorder);
|
|
152
142
|
const nodeWidth = Math.max(cssMinWidth, Math.min(cap, rawWidth));
|
|
153
143
|
nodes.push({
|
|
154
144
|
id: c.id,
|
|
155
145
|
type: 'subsystem-component',
|
|
156
146
|
position: { x: PAD + col * COL_W, y: cursorY + row * ROW_H },
|
|
157
147
|
width: nodeWidth,
|
|
158
|
-
height:
|
|
148
|
+
height: 84,
|
|
159
149
|
data: { component: c },
|
|
160
150
|
});
|
|
161
151
|
});
|
|
@@ -227,7 +217,7 @@ export async function buildSubsystemGraph(doc, opts = {}) {
|
|
|
227
217
|
component: {
|
|
228
218
|
id: extId,
|
|
229
219
|
name: label,
|
|
230
|
-
kind: '
|
|
220
|
+
kind: 'external',
|
|
231
221
|
purl: 'external',
|
|
232
222
|
file: '',
|
|
233
223
|
purpose: 'cross-package integration target (not a member node)',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,UAAU,GAGX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../src/subsystem/nodes.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../src/subsystem/nodes.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM7C,CAAC;AAgBF,MAAM,WAAW,uBAAuB;IACtC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,EAAE,uBAA4B,CAAC;AAE/D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,kBAAkB,CAAC,2CAkK1E;AAED;;;cAGc;AACd,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,GACV,EAAE,SAAS,CAAC,kBAAkB,CAAC,2CAkC/B"}
|
package/dist/subsystem/nodes.js
CHANGED
|
@@ -13,63 +13,11 @@ import { useTheme } from '@principal-ade/industry-theme';
|
|
|
13
13
|
import { KIND_COLOR, MECHANISM_COLOR, deriveNameFromSymbol, } from './model';
|
|
14
14
|
export const KIND_LABEL = {
|
|
15
15
|
class: 'class',
|
|
16
|
-
module: 'module',
|
|
17
|
-
script: 'script',
|
|
18
|
-
registry: 'registry',
|
|
19
|
-
service: 'service',
|
|
20
|
-
consumer: 'consumer',
|
|
21
16
|
function: 'function',
|
|
22
|
-
method: 'method',
|
|
23
17
|
type: 'type',
|
|
24
|
-
|
|
18
|
+
module: 'module',
|
|
19
|
+
external: 'external',
|
|
25
20
|
};
|
|
26
|
-
/** Owning class of a method, derived from its `Symbol.Class.method` symbol. */
|
|
27
|
-
function ownerClass(symbol) {
|
|
28
|
-
if (!symbol)
|
|
29
|
-
return undefined;
|
|
30
|
-
const idx = symbol.lastIndexOf('.');
|
|
31
|
-
return idx > 0 ? symbol.slice(0, idx) : undefined;
|
|
32
|
-
}
|
|
33
|
-
/** Namespace/owner extracted from a PURL or npm scope. */
|
|
34
|
-
function purlNamespace(purl) {
|
|
35
|
-
if (!purl)
|
|
36
|
-
return undefined;
|
|
37
|
-
// pkg:github/owner/repo → owner
|
|
38
|
-
const hosted = purl.match(/^pkg:(github|gitlab|bitbucket)\/([^/]+)\//);
|
|
39
|
-
if (hosted)
|
|
40
|
-
return hosted[2];
|
|
41
|
-
// pkg:npm/@scope/name → @scope
|
|
42
|
-
const scoped = purl.match(/^pkg:npm\/(@[^/]+)\//);
|
|
43
|
-
if (scoped)
|
|
44
|
-
return scoped[1];
|
|
45
|
-
// pkg:generic/local/... → local
|
|
46
|
-
if (purl.startsWith('pkg:generic/local/'))
|
|
47
|
-
return 'local';
|
|
48
|
-
// @scope/name → @scope (legacy npm)
|
|
49
|
-
if (purl.startsWith('@')) {
|
|
50
|
-
const idx = purl.indexOf('/');
|
|
51
|
-
return idx > 0 ? purl.slice(0, idx) : undefined;
|
|
52
|
-
}
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
/** Short label for the hosting platform of a PURL. */
|
|
56
|
-
function purlRegistry(purl) {
|
|
57
|
-
if (!purl)
|
|
58
|
-
return '';
|
|
59
|
-
if (purl.startsWith('pkg:github/'))
|
|
60
|
-
return ' · github';
|
|
61
|
-
if (purl.startsWith('pkg:gitlab/'))
|
|
62
|
-
return ' · gitlab';
|
|
63
|
-
if (purl.startsWith('pkg:bitbucket/'))
|
|
64
|
-
return ' · bitbucket';
|
|
65
|
-
if (purl.startsWith('pkg:generic/local/'))
|
|
66
|
-
return ' · local';
|
|
67
|
-
if (purl.startsWith('pkg:npm/'))
|
|
68
|
-
return ' · npm';
|
|
69
|
-
if (purl.startsWith('@'))
|
|
70
|
-
return ' · npm';
|
|
71
|
-
return '';
|
|
72
|
-
}
|
|
73
21
|
/** Insert zero-width spaces at identifier word boundaries so long names wrap
|
|
74
22
|
* on naming conventions (snake_case `foo_`|`bar`, camelCase `foo`|`Bar`,
|
|
75
23
|
* PascalCase `Foo`|`Bar`, acronym `ABC`|`Def`) instead of mid-character. */
|
|
@@ -90,11 +38,9 @@ export function SubsystemComponentNode(props) {
|
|
|
90
38
|
const { data, selected, width: nodeWidth, height: nodeHeight } = props;
|
|
91
39
|
const c = data.component;
|
|
92
40
|
const color = KIND_COLOR[c.kind] ?? '#888';
|
|
93
|
-
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
94
41
|
const [hover, setHover] = useState(false);
|
|
95
|
-
const isPackage = c.kind === 'package';
|
|
96
42
|
const configuredMax = SUBSYSTEM_CALLBACKS.maxNodeWidth;
|
|
97
|
-
const maxWidth =
|
|
43
|
+
const maxWidth = configuredMax ?? 300;
|
|
98
44
|
// `symbol` is the source of truth; `name` is derived from it consistently.
|
|
99
45
|
const displayName = deriveNameFromSymbol(c.symbol, c.kind, c.name, c.file);
|
|
100
46
|
return (_jsxs("div", { onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), onClick: (e) => {
|
|
@@ -109,12 +55,12 @@ export function SubsystemComponentNode(props) {
|
|
|
109
55
|
boxSizing: 'border-box',
|
|
110
56
|
width: nodeWidth,
|
|
111
57
|
height: nodeHeight,
|
|
112
|
-
minWidth:
|
|
58
|
+
minWidth: 150,
|
|
113
59
|
maxWidth,
|
|
114
|
-
padding:
|
|
115
|
-
borderRadius:
|
|
60
|
+
padding: '6px 10px',
|
|
61
|
+
borderRadius: 8,
|
|
116
62
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
117
|
-
border: `2px
|
|
63
|
+
border: `2px solid ${selected ? theme.colors.primary : color}`,
|
|
118
64
|
boxShadow: '0 1px 4px rgba(0,0,0,0.25)',
|
|
119
65
|
cursor: 'pointer',
|
|
120
66
|
fontFamily: theme.fonts.body,
|
|
@@ -136,7 +82,7 @@ export function SubsystemComponentNode(props) {
|
|
|
136
82
|
border: `1px solid ${theme.colors.border}`,
|
|
137
83
|
borderRadius: 4,
|
|
138
84
|
padding: '1px 6px',
|
|
139
|
-
}, children: [KIND_LABEL[c.kind] ?? c.kind, c.
|
|
85
|
+
}, children: [KIND_LABEL[c.kind] ?? c.kind, c.purl ? ` · ${c.purl}` : '', c.capture && c.capture !== 'edited' ? ` · ${c.capture}` : ''] })), hover && c.purpose && (_jsx("div", { style: {
|
|
140
86
|
position: 'absolute',
|
|
141
87
|
top: '100%',
|
|
142
88
|
left: 0,
|
|
@@ -152,27 +98,7 @@ export function SubsystemComponentNode(props) {
|
|
|
152
98
|
padding: '4px 8px',
|
|
153
99
|
boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
154
100
|
lineHeight: 1.4,
|
|
155
|
-
}, children: c.purpose })),
|
|
156
|
-
fontSize: theme.fontSizes[0] * 0.78,
|
|
157
|
-
fontFamily: theme.fonts.monospace,
|
|
158
|
-
color: muted,
|
|
159
|
-
textAlign: 'center',
|
|
160
|
-
whiteSpace: 'nowrap',
|
|
161
|
-
overflow: 'hidden',
|
|
162
|
-
textOverflow: 'ellipsis',
|
|
163
|
-
maxWidth: '100%',
|
|
164
|
-
marginBottom: 1,
|
|
165
|
-
}, title: ownerClass(c.symbol), children: ownerClass(c.symbol) })), c.kind === 'package' && purlNamespace(c.purl) && (_jsx("div", { style: {
|
|
166
|
-
fontSize: theme.fontSizes[0] * 0.78,
|
|
167
|
-
fontFamily: theme.fonts.monospace,
|
|
168
|
-
color: muted,
|
|
169
|
-
textAlign: 'center',
|
|
170
|
-
whiteSpace: 'nowrap',
|
|
171
|
-
overflow: 'hidden',
|
|
172
|
-
textOverflow: 'ellipsis',
|
|
173
|
-
maxWidth: '100%',
|
|
174
|
-
marginBottom: 1,
|
|
175
|
-
}, title: c.purl, children: purlNamespace(c.purl) })), _jsx("div", { style: {
|
|
101
|
+
}, children: c.purpose })), _jsx("div", { style: {
|
|
176
102
|
fontSize: theme.fontSizes[2],
|
|
177
103
|
fontWeight: 600,
|
|
178
104
|
color: theme.colors.text,
|
|
@@ -185,7 +111,7 @@ export function SubsystemComponentNode(props) {
|
|
|
185
111
|
maxWidth: '100%',
|
|
186
112
|
// Types get a serif name to distinguish them from runtime units.
|
|
187
113
|
fontFamily: c.kind === 'type' ? 'Georgia, "Times New Roman", serif' : theme.fonts.body,
|
|
188
|
-
}, children:
|
|
114
|
+
}, children: breakWords(displayName) }), c.symbol && c.symbol !== displayName && (_jsx("div", { style: {
|
|
189
115
|
fontSize: theme.fontSizes[0] * 0.82,
|
|
190
116
|
fontFamily: theme.fonts.monospace,
|
|
191
117
|
color: color,
|
|
@@ -195,7 +121,7 @@ export function SubsystemComponentNode(props) {
|
|
|
195
121
|
overflow: 'hidden',
|
|
196
122
|
textOverflow: 'ellipsis',
|
|
197
123
|
maxWidth: '100%',
|
|
198
|
-
}, title: c.symbol, children: c.symbol })), c.file &&
|
|
124
|
+
}, title: c.symbol, children: c.symbol })), c.file && (_jsx("div", { onClick: (e) => {
|
|
199
125
|
e.stopPropagation();
|
|
200
126
|
SUBSYSTEM_CALLBACKS.onSelect?.(c.id);
|
|
201
127
|
}, style: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../src/subsystem/nodes.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EACL,MAAM,EACN,QAAQ,GAGT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EACL,UAAU,EACV,eAAe,EACf,oBAAoB,GAGrB,MAAM,SAAS,CAAC;AAEjB,MAAM,CAAC,MAAM,UAAU,GAA2B;IAChD,KAAK,EAAE,OAAO;IACd,
|
|
1
|
+
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../src/subsystem/nodes.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -172,11 +172,11 @@ const readerDetail: GraphifyComponentDetail = {
|
|
|
172
172
|
};
|
|
173
173
|
|
|
174
174
|
const v2ReaderComponents = components([
|
|
175
|
-
['capture', 'capture script', '
|
|
175
|
+
['capture', 'capture script', 'function', 'scripts/capture-session.ts', 'pkg:github/principal-ai/agent-monitoring', 'captures a real session for fixtures'],
|
|
176
176
|
['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards'],
|
|
177
177
|
['paths', 'paths', 'module', 'paths.ts', 'pkg:github/principal-ai/agent-monitoring', 'extracts tool names + file paths'],
|
|
178
178
|
['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader.normalize', readerDetail],
|
|
179
|
-
['registry', 'supported-agents', '
|
|
179
|
+
['registry', 'supported-agents', 'module', 'supported-agents.ts', 'pkg:github/principal-ai/agent-monitoring', 'registry of supported agents (the shared seam)', 'registerAgent'],
|
|
180
180
|
]);
|
|
181
181
|
|
|
182
182
|
const v2ReaderEdges = edges([
|
|
@@ -367,7 +367,7 @@ const namingConventionComponents: SubsystemComponent[] = [
|
|
|
367
367
|
{
|
|
368
368
|
id: 'method',
|
|
369
369
|
name: 'normalize',
|
|
370
|
-
kind: '
|
|
370
|
+
kind: 'function',
|
|
371
371
|
file: 'src/session/SessionReader.ts',
|
|
372
372
|
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
373
373
|
symbol: 'SessionReader.normalize',
|
|
@@ -375,7 +375,7 @@ const namingConventionComponents: SubsystemComponent[] = [
|
|
|
375
375
|
{
|
|
376
376
|
id: 'pkg',
|
|
377
377
|
name: 'trail-viewer',
|
|
378
|
-
kind: '
|
|
378
|
+
kind: 'external',
|
|
379
379
|
file: '',
|
|
380
380
|
purl: 'pkg:npm/@principal-ai/trail-viewer',
|
|
381
381
|
symbol: '',
|
|
@@ -413,7 +413,7 @@ const detailKindComponents: SubsystemComponent[] = [
|
|
|
413
413
|
{
|
|
414
414
|
id: 'detail-method',
|
|
415
415
|
name: 'normalize',
|
|
416
|
-
kind: '
|
|
416
|
+
kind: 'function',
|
|
417
417
|
file: 'src/session/SessionReader.ts',
|
|
418
418
|
purl: 'pkg:github/principal-ai/agent-monitoring',
|
|
419
419
|
purpose: 'a class method — the specific thing this session focused on',
|
|
@@ -485,7 +485,7 @@ const detailKindComponents: SubsystemComponent[] = [
|
|
|
485
485
|
id: 'detail-external',
|
|
486
486
|
// name = the package's name after the namespace; namespace shown above.
|
|
487
487
|
name: 'trail-viewer',
|
|
488
|
-
kind: '
|
|
488
|
+
kind: 'external',
|
|
489
489
|
file: '',
|
|
490
490
|
purl: 'pkg:npm/@principal-ai/trail-viewer',
|
|
491
491
|
purpose: 'an npm package consumer — the whole package as a node',
|
|
@@ -525,7 +525,7 @@ export const DetailKinds: Story = {
|
|
|
525
525
|
/** The minimal LLM-authored substrate: symbols only, no `detail`. */
|
|
526
526
|
const minimalComponents = components([
|
|
527
527
|
['reader', 'SessionReader', 'class', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'normalizes a session into universal events', 'SessionReader'],
|
|
528
|
-
['normalize', 'normalize', '
|
|
528
|
+
['normalize', 'normalize', 'function', 'SessionReader.ts', 'pkg:github/principal-ai/agent-monitoring', 'maps a session into universal events', 'SessionReader.normalize'],
|
|
529
529
|
['record', 'SessionRecord', 'type', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'the parsed codex session record', 'SessionRecord'],
|
|
530
530
|
['transcript', 'transcript', 'module', 'transcript.ts', 'pkg:github/principal-ai/agent-monitoring', 'parses session records + type guards', 'transcript'],
|
|
531
531
|
]);
|
|
@@ -38,7 +38,7 @@ describe('subsystem graph model', () => {
|
|
|
38
38
|
const { nodes, edges: gEdges } = await buildSubsystemGraph({ components: comps, edges });
|
|
39
39
|
const external = nodes.find((n) => n.id === 'external:host');
|
|
40
40
|
expect(external).toBeDefined();
|
|
41
|
-
expect(external!.data.component.kind).toBe('
|
|
41
|
+
expect(external!.data.component.kind).toBe('external');
|
|
42
42
|
const crossEdge = gEdges.find((e) => e.target === 'external:host');
|
|
43
43
|
expect(crossEdge).toBeDefined();
|
|
44
44
|
});
|
|
@@ -63,11 +63,9 @@ describe('subsystem graph model', () => {
|
|
|
63
63
|
// class/type/module/function use the symbol as-is.
|
|
64
64
|
expect(deriveNameFromSymbol('SessionReader', 'class')).toBe('SessionReader');
|
|
65
65
|
expect(deriveNameFromSymbol('SessionRecord', 'type')).toBe('SessionRecord');
|
|
66
|
-
// method uses the last dotted segment.
|
|
67
|
-
expect(deriveNameFromSymbol('SessionReader.normalize', 'method')).toBe('normalize');
|
|
68
66
|
// falls back to existing name when no symbol.
|
|
69
67
|
expect(deriveNameFromSymbol(undefined, 'class', 'SessionReader')).toBe('SessionReader');
|
|
70
|
-
expect(deriveNameFromSymbol('', '
|
|
68
|
+
expect(deriveNameFromSymbol('', 'external', 'trail-viewer-host')).toBe('trail-viewer-host');
|
|
71
69
|
});
|
|
72
70
|
|
|
73
71
|
test('deriveNameFromSymbol falls back to file basename for modules', () => {
|
package/src/subsystem/model.ts
CHANGED
|
@@ -22,15 +22,10 @@ import type { GraphifyComponentDetail } from '../graphify';
|
|
|
22
22
|
|
|
23
23
|
export type SubsystemComponentKind =
|
|
24
24
|
| 'class'
|
|
25
|
-
| 'module'
|
|
26
|
-
| 'script'
|
|
27
|
-
| 'registry'
|
|
28
|
-
| 'service'
|
|
29
|
-
| 'consumer'
|
|
30
25
|
| 'function'
|
|
31
|
-
| 'method'
|
|
32
26
|
| 'type'
|
|
33
|
-
| '
|
|
27
|
+
| 'module'
|
|
28
|
+
| 'external';
|
|
34
29
|
|
|
35
30
|
export type SubsystemEdgeMechanism =
|
|
36
31
|
| 'imports'
|
|
@@ -113,10 +108,6 @@ export function deriveNameFromSymbol(
|
|
|
113
108
|
file?: string,
|
|
114
109
|
): string {
|
|
115
110
|
if (symbol && symbol.trim()) {
|
|
116
|
-
if (kind === 'method') {
|
|
117
|
-
const idx = symbol.lastIndexOf('.');
|
|
118
|
-
return idx >= 0 ? symbol.slice(idx + 1) : symbol;
|
|
119
|
-
}
|
|
120
111
|
return symbol;
|
|
121
112
|
}
|
|
122
113
|
// Module nodes without a symbol are whole files → use the file basename.
|
|
@@ -216,15 +207,10 @@ export function packageColor(name: string): string {
|
|
|
216
207
|
/** Color per component kind — the informative signal (rather than package). */
|
|
217
208
|
export const KIND_COLOR: Record<SubsystemComponentKind, string> = {
|
|
218
209
|
class: '#0893d2', // blue
|
|
219
|
-
|
|
220
|
-
script: '#ff6b35', // orange
|
|
221
|
-
registry: '#b48ead', // purple
|
|
222
|
-
service: '#e3b341', // gold
|
|
223
|
-
consumer: '#5aa9e6', // light blue
|
|
224
|
-
function: '#6c5ce7', // indigo (distinct from module teal + script orange)
|
|
225
|
-
method: '#c586c0', // magenta
|
|
210
|
+
function: '#6c5ce7', // indigo
|
|
226
211
|
type: '#e07a5f', // terracotta
|
|
227
|
-
|
|
212
|
+
module: '#4ec9b0', // teal
|
|
213
|
+
external: '#b48ead', // purple
|
|
228
214
|
};
|
|
229
215
|
|
|
230
216
|
/**
|
|
@@ -263,27 +249,26 @@ export function convertSubsystemToNodes(
|
|
|
263
249
|
comps.forEach((c, i) => {
|
|
264
250
|
const col = i % COLS;
|
|
265
251
|
const row = Math.floor(i / COLS);
|
|
266
|
-
const isPkg = c.kind === 'package';
|
|
267
252
|
// Estimate rendered node width from the longest text line so ELK reserves
|
|
268
253
|
// the right space (names can wrap, so we cap at the configurable max).
|
|
269
254
|
const text = [c.symbol, c.name, c.file.split('/').pop() ?? '']
|
|
270
255
|
.filter((t): t is string => !!t)
|
|
271
256
|
.sort((a, b) => b.length - a.length)[0];
|
|
272
|
-
const cap = maxNodeWidth ??
|
|
257
|
+
const cap = maxNodeWidth ?? 300;
|
|
273
258
|
const textWidth = Math.min(cap, Math.max(60, (text?.length ?? 10) * 8));
|
|
274
259
|
// Account for CSS minWidth and padding/border so ELK's port positions match
|
|
275
260
|
// the actual rendered node boundaries.
|
|
276
|
-
const cssMinWidth =
|
|
277
|
-
const cssPadding =
|
|
261
|
+
const cssMinWidth = 150;
|
|
262
|
+
const cssPadding = 20; // horizontal padding (left + right)
|
|
278
263
|
const cssBorder = 4; // 2px border each side
|
|
279
|
-
const rawWidth = Math.max(cssMinWidth,
|
|
264
|
+
const rawWidth = Math.max(cssMinWidth, textWidth + cssPadding + cssBorder);
|
|
280
265
|
const nodeWidth = Math.max(cssMinWidth, Math.min(cap, rawWidth));
|
|
281
266
|
nodes.push({
|
|
282
267
|
id: c.id,
|
|
283
268
|
type: 'subsystem-component',
|
|
284
269
|
position: { x: PAD + col * COL_W, y: cursorY + row * ROW_H },
|
|
285
270
|
width: nodeWidth,
|
|
286
|
-
height:
|
|
271
|
+
height: 84,
|
|
287
272
|
data: { component: c },
|
|
288
273
|
});
|
|
289
274
|
});
|
|
@@ -365,7 +350,7 @@ export async function buildSubsystemGraph(
|
|
|
365
350
|
component: {
|
|
366
351
|
id: extId,
|
|
367
352
|
name: label,
|
|
368
|
-
kind: '
|
|
353
|
+
kind: 'external',
|
|
369
354
|
purl: 'external',
|
|
370
355
|
file: '',
|
|
371
356
|
purpose: 'cross-package integration target (not a member node)',
|
package/src/subsystem/nodes.tsx
CHANGED
|
@@ -25,55 +25,12 @@ import {
|
|
|
25
25
|
|
|
26
26
|
export const KIND_LABEL: Record<string, string> = {
|
|
27
27
|
class: 'class',
|
|
28
|
-
module: 'module',
|
|
29
|
-
script: 'script',
|
|
30
|
-
registry: 'registry',
|
|
31
|
-
service: 'service',
|
|
32
|
-
consumer: 'consumer',
|
|
33
28
|
function: 'function',
|
|
34
|
-
method: 'method',
|
|
35
29
|
type: 'type',
|
|
36
|
-
|
|
30
|
+
module: 'module',
|
|
31
|
+
external: 'external',
|
|
37
32
|
};
|
|
38
33
|
|
|
39
|
-
/** Owning class of a method, derived from its `Symbol.Class.method` symbol. */
|
|
40
|
-
function ownerClass(symbol?: string): string | undefined {
|
|
41
|
-
if (!symbol) return undefined;
|
|
42
|
-
const idx = symbol.lastIndexOf('.');
|
|
43
|
-
return idx > 0 ? symbol.slice(0, idx) : undefined;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Namespace/owner extracted from a PURL or npm scope. */
|
|
47
|
-
function purlNamespace(purl?: string): string | undefined {
|
|
48
|
-
if (!purl) return undefined;
|
|
49
|
-
// pkg:github/owner/repo → owner
|
|
50
|
-
const hosted = purl.match(/^pkg:(github|gitlab|bitbucket)\/([^/]+)\//);
|
|
51
|
-
if (hosted) return hosted[2];
|
|
52
|
-
// pkg:npm/@scope/name → @scope
|
|
53
|
-
const scoped = purl.match(/^pkg:npm\/(@[^/]+)\//);
|
|
54
|
-
if (scoped) return scoped[1];
|
|
55
|
-
// pkg:generic/local/... → local
|
|
56
|
-
if (purl.startsWith('pkg:generic/local/')) return 'local';
|
|
57
|
-
// @scope/name → @scope (legacy npm)
|
|
58
|
-
if (purl.startsWith('@')) {
|
|
59
|
-
const idx = purl.indexOf('/');
|
|
60
|
-
return idx > 0 ? purl.slice(0, idx) : undefined;
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Short label for the hosting platform of a PURL. */
|
|
66
|
-
function purlRegistry(purl?: string): string {
|
|
67
|
-
if (!purl) return '';
|
|
68
|
-
if (purl.startsWith('pkg:github/')) return ' · github';
|
|
69
|
-
if (purl.startsWith('pkg:gitlab/')) return ' · gitlab';
|
|
70
|
-
if (purl.startsWith('pkg:bitbucket/')) return ' · bitbucket';
|
|
71
|
-
if (purl.startsWith('pkg:generic/local/')) return ' · local';
|
|
72
|
-
if (purl.startsWith('pkg:npm/')) return ' · npm';
|
|
73
|
-
if (purl.startsWith('@')) return ' · npm';
|
|
74
|
-
return '';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
34
|
/** Insert zero-width spaces at identifier word boundaries so long names wrap
|
|
78
35
|
* on naming conventions (snake_case `foo_`|`bar`, camelCase `foo`|`Bar`,
|
|
79
36
|
* PascalCase `Foo`|`Bar`, acronym `ABC`|`Def`) instead of mid-character. */
|
|
@@ -105,11 +62,9 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
105
62
|
const { data, selected, width: nodeWidth, height: nodeHeight } = props;
|
|
106
63
|
const c = data.component;
|
|
107
64
|
const color = KIND_COLOR[c.kind] ?? '#888';
|
|
108
|
-
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
109
65
|
const [hover, setHover] = useState(false);
|
|
110
|
-
const isPackage = c.kind === 'package';
|
|
111
66
|
const configuredMax = SUBSYSTEM_CALLBACKS.maxNodeWidth;
|
|
112
|
-
const maxWidth =
|
|
67
|
+
const maxWidth = configuredMax ?? 300;
|
|
113
68
|
// `symbol` is the source of truth; `name` is derived from it consistently.
|
|
114
69
|
const displayName = deriveNameFromSymbol(c.symbol, c.kind, c.name, c.file);
|
|
115
70
|
|
|
@@ -130,12 +85,12 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
130
85
|
boxSizing: 'border-box',
|
|
131
86
|
width: nodeWidth,
|
|
132
87
|
height: nodeHeight,
|
|
133
|
-
minWidth:
|
|
88
|
+
minWidth: 150,
|
|
134
89
|
maxWidth,
|
|
135
|
-
padding:
|
|
136
|
-
borderRadius:
|
|
90
|
+
padding: '6px 10px',
|
|
91
|
+
borderRadius: 8,
|
|
137
92
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
138
|
-
border: `2px
|
|
93
|
+
border: `2px solid ${selected ? theme.colors.primary : color}`,
|
|
139
94
|
boxShadow: '0 1px 4px rgba(0,0,0,0.25)',
|
|
140
95
|
cursor: 'pointer',
|
|
141
96
|
fontFamily: theme.fonts.body,
|
|
@@ -165,9 +120,7 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
165
120
|
}}
|
|
166
121
|
>
|
|
167
122
|
{KIND_LABEL[c.kind] ?? c.kind}
|
|
168
|
-
{
|
|
169
|
-
package name; for other kinds, show the owning package. */}
|
|
170
|
-
{c.kind === 'package' ? purlRegistry(c.purl) : c.purl ? ` · ${c.purl}` : ''}
|
|
123
|
+
{c.purl ? ` · ${c.purl}` : ''}
|
|
171
124
|
{c.capture && c.capture !== 'edited' ? ` · ${c.capture}` : ''}
|
|
172
125
|
</div>
|
|
173
126
|
)}
|
|
@@ -197,46 +150,6 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
197
150
|
</div>
|
|
198
151
|
)}
|
|
199
152
|
|
|
200
|
-
{/* Method nodes show their owning class above the method name. */}
|
|
201
|
-
{c.kind === 'method' && ownerClass(c.symbol) && (
|
|
202
|
-
<div
|
|
203
|
-
style={{
|
|
204
|
-
fontSize: theme.fontSizes[0] * 0.78,
|
|
205
|
-
fontFamily: theme.fonts.monospace,
|
|
206
|
-
color: muted,
|
|
207
|
-
textAlign: 'center',
|
|
208
|
-
whiteSpace: 'nowrap',
|
|
209
|
-
overflow: 'hidden',
|
|
210
|
-
textOverflow: 'ellipsis',
|
|
211
|
-
maxWidth: '100%',
|
|
212
|
-
marginBottom: 1,
|
|
213
|
-
}}
|
|
214
|
-
title={ownerClass(c.symbol)}
|
|
215
|
-
>
|
|
216
|
-
{ownerClass(c.symbol)}
|
|
217
|
-
</div>
|
|
218
|
-
)}
|
|
219
|
-
|
|
220
|
-
{/* Package nodes show their namespace (@scope) above the package name. */}
|
|
221
|
-
{c.kind === 'package' && purlNamespace(c.purl) && (
|
|
222
|
-
<div
|
|
223
|
-
style={{
|
|
224
|
-
fontSize: theme.fontSizes[0] * 0.78,
|
|
225
|
-
fontFamily: theme.fonts.monospace,
|
|
226
|
-
color: muted,
|
|
227
|
-
textAlign: 'center',
|
|
228
|
-
whiteSpace: 'nowrap',
|
|
229
|
-
overflow: 'hidden',
|
|
230
|
-
textOverflow: 'ellipsis',
|
|
231
|
-
maxWidth: '100%',
|
|
232
|
-
marginBottom: 1,
|
|
233
|
-
}}
|
|
234
|
-
title={c.purl}
|
|
235
|
-
>
|
|
236
|
-
{purlNamespace(c.purl)}
|
|
237
|
-
</div>
|
|
238
|
-
)}
|
|
239
|
-
|
|
240
153
|
<div
|
|
241
154
|
style={{
|
|
242
155
|
fontSize: theme.fontSizes[2],
|
|
@@ -254,10 +167,10 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
254
167
|
c.kind === 'type' ? 'Georgia, "Times New Roman", serif' : theme.fonts.body,
|
|
255
168
|
}}
|
|
256
169
|
>
|
|
257
|
-
{
|
|
170
|
+
{breakWords(displayName)}
|
|
258
171
|
</div>
|
|
259
172
|
|
|
260
|
-
{c.symbol && c.
|
|
173
|
+
{c.symbol && c.symbol !== displayName && (
|
|
261
174
|
<div
|
|
262
175
|
style={{
|
|
263
176
|
fontSize: theme.fontSizes[0] * 0.82,
|
|
@@ -276,7 +189,7 @@ export function SubsystemComponentNode(props: NodeProps<SubsystemGraphNode>) {
|
|
|
276
189
|
</div>
|
|
277
190
|
)}
|
|
278
191
|
|
|
279
|
-
{c.file &&
|
|
192
|
+
{c.file && (
|
|
280
193
|
<div
|
|
281
194
|
onClick={(e) => {
|
|
282
195
|
e.stopPropagation();
|