@principal-ai/subsystems-react 0.44.4 → 0.46.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.
- package/README.md +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/pierre/{PierreWalkthroughCodeView.d.ts → PierreTrailCodeView.d.ts} +11 -11
- package/dist/pierre/PierreTrailCodeView.d.ts.map +1 -0
- package/dist/pierre/{PierreWalkthroughCodeView.js → PierreTrailCodeView.js} +36 -36
- package/dist/pierre/PierreTrailCodeView.js.map +1 -0
- package/dist/pierre/index.d.ts +2 -2
- package/dist/pierre/index.d.ts.map +1 -1
- package/dist/pierre/index.js +1 -1
- package/dist/pierre/index.js.map +1 -1
- package/dist/stories/Subsystem/AggregateGraph/aggregateViewFixture.d.ts.map +1 -1
- package/dist/stories/Subsystem/AggregateGraph/aggregateViewFixture.js +1 -1
- package/dist/stories/Subsystem/AggregateGraph/aggregateViewFixture.js.map +1 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js +1 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +1 -1
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +7 -11
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -1
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js +10 -26
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -1
- package/dist/subsystem/C4Graph.d.ts +2 -2
- package/dist/subsystem/C4Graph.js +2 -2
- package/dist/subsystem/ConstructsCatalog.d.ts +2 -3
- package/dist/subsystem/ConstructsCatalog.d.ts.map +1 -1
- package/dist/subsystem/ConstructsCatalog.js +3 -14
- package/dist/subsystem/ConstructsCatalog.js.map +1 -1
- package/dist/subsystem/DiagnosticToggle.d.ts +1 -1
- package/dist/subsystem/DiagnosticToggle.js +1 -1
- package/dist/subsystem/FileDrawer.d.ts +2 -2
- package/dist/subsystem/FileDrawer.js +2 -2
- package/dist/subsystem/IssueList.d.ts +6 -6
- package/dist/subsystem/IssueList.d.ts.map +1 -1
- package/dist/subsystem/IssueList.js +9 -9
- package/dist/subsystem/IssueList.js.map +1 -1
- package/dist/subsystem/SubsystemAggregateGraph.d.ts +3 -3
- package/dist/subsystem/SubsystemAggregateGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemAggregateGraph.js +2 -2
- package/dist/subsystem/SubsystemComponentGraph.d.ts +45 -51
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +288 -292
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/SubsystemModelTransition.d.ts +10 -10
- package/dist/subsystem/SubsystemModelTransition.d.ts.map +1 -1
- package/dist/subsystem/SubsystemModelTransition.js +42 -42
- package/dist/subsystem/SubsystemModelTransition.js.map +1 -1
- package/dist/subsystem/TrailsPanel.d.ts +55 -0
- package/dist/subsystem/TrailsPanel.d.ts.map +1 -0
- package/dist/subsystem/{WalkthroughsPanel.js → TrailsPanel.js} +51 -51
- package/dist/subsystem/TrailsPanel.js.map +1 -0
- package/dist/subsystem/declarationRef.d.ts +1 -1
- package/dist/subsystem/declarationRef.d.ts.map +1 -1
- package/dist/subsystem/model.d.ts +40 -40
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +17 -17
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts +1 -1
- package/dist/subsystem/nodes.js +1 -1
- package/dist/subsystem/toC4.d.ts +2 -2
- package/dist/subsystem/toC4.d.ts.map +1 -1
- package/dist/subsystem/toC4.js +2 -2
- package/dist/subsystem/toC4.js.map +1 -1
- package/dist/subsystem/trailBrief.d.ts +18 -0
- package/dist/subsystem/trailBrief.d.ts.map +1 -0
- package/dist/subsystem/{walkthroughBrief.js → trailBrief.js} +8 -8
- package/dist/subsystem/trailBrief.js.map +1 -0
- package/package.json +3 -3
- package/src/index.ts +15 -15
- package/src/pierre/{PierreWalkthroughCodeView.tsx → PierreTrailCodeView.tsx} +56 -56
- package/src/pierre/index.ts +2 -2
- package/src/stories/Pierre/CodeView.stories.tsx +3 -3
- package/src/stories/Subsystem/AggregateGraph/AggregateFrameGraph.stories.tsx +1 -1
- package/src/stories/Subsystem/AggregateGraph/aggregateViewFixture.ts +1 -1
- package/src/stories/Subsystem/C4Graph/c4Fixture.ts +1 -1
- package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +8 -8
- package/src/stories/Subsystem/ComponentGraph/AnimatedProgression.stories.tsx +13 -13
- package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +2 -2
- package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +5 -5
- package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +8 -8
- package/src/stories/Subsystem/ComponentGraph/CustomEntities.stories.tsx +3 -3
- package/src/stories/Subsystem/ComponentGraph/Diagnostics.stories.tsx +6 -6
- package/src/stories/Subsystem/ComponentGraph/EdgeViews.stories.tsx +12 -12
- package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +36 -36
- package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +7 -7
- package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +4 -4
- package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +8 -8
- package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +4 -4
- package/src/stories/Subsystem/ComponentGraph/ModuleBadges.stories.tsx +3 -3
- package/src/stories/Subsystem/ComponentGraph/Modules.stories.tsx +5 -5
- package/src/stories/Subsystem/ComponentGraph/Packages.stories.tsx +6 -6
- package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +3 -3
- package/src/stories/Subsystem/ComponentGraph/Proposed.stories.tsx +4 -4
- package/src/stories/Subsystem/ComponentGraph/{ProposedWalkthroughs.stories.tsx → ProposedTrails.stories.tsx} +9 -9
- package/src/stories/Subsystem/ComponentGraph/Reorder.stories.tsx +19 -19
- package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +21 -21
- package/src/stories/Subsystem/ComponentGraph/{WalkthroughAutoplay.stories.tsx → TrailAutoplay.stories.tsx} +22 -22
- package/src/stories/Subsystem/ComponentGraph/WorkspacePackageFrames.stories.tsx +3 -3
- package/src/stories/Subsystem/ComponentGraph/fixtures.ts +17 -37
- package/src/subsystem/C4Graph.tsx +2 -2
- package/src/subsystem/ConstructsCatalog.tsx +2 -16
- package/src/subsystem/DiagnosticToggle.tsx +1 -1
- package/src/subsystem/FileDrawer.tsx +2 -2
- package/src/subsystem/IssueList.focus.test.tsx +4 -4
- package/src/subsystem/IssueList.icon.test.tsx +3 -3
- package/src/subsystem/IssueList.tsx +14 -14
- package/src/subsystem/SubsystemAggregateGraph.tsx +3 -3
- package/src/subsystem/SubsystemComponentGraph.tsx +380 -393
- package/src/subsystem/SubsystemModelTransition.tsx +61 -61
- package/src/subsystem/{WalkthroughsPanel.test.tsx → TrailsPanel.test.tsx} +16 -16
- package/src/subsystem/{WalkthroughsPanel.tsx → TrailsPanel.tsx} +81 -81
- package/src/subsystem/declarationRef.ts +1 -1
- package/src/subsystem/formatDeclaration.test.ts +6 -6
- package/src/subsystem/model.test.ts +25 -25
- package/src/subsystem/model.ts +51 -51
- package/src/subsystem/nodes.tsx +1 -1
- package/src/subsystem/toC4.test.ts +1 -1
- package/src/subsystem/toC4.ts +3 -3
- package/src/subsystem/{walkthroughBrief.test.ts → trailBrief.test.ts} +10 -10
- package/src/subsystem/{walkthroughBrief.ts → trailBrief.ts} +8 -8
- package/dist/pierre/PierreWalkthroughCodeView.d.ts.map +0 -1
- package/dist/pierre/PierreWalkthroughCodeView.js.map +0 -1
- package/dist/subsystem/WalkthroughsPanel.d.ts +0 -55
- package/dist/subsystem/WalkthroughsPanel.d.ts.map +0 -1
- package/dist/subsystem/WalkthroughsPanel.js.map +0 -1
- package/dist/subsystem/walkthroughBrief.d.ts +0 -18
- package/dist/subsystem/walkthroughBrief.d.ts.map +0 -1
- package/dist/subsystem/walkthroughBrief.js.map +0 -1
|
@@ -3,20 +3,20 @@ import '@xyflow/react/dist/style.css';
|
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
4
|
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
5
5
|
import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
|
|
6
|
-
import type { SubsystemComponent,
|
|
6
|
+
import type { SubsystemComponent, SubsystemTrail } from '../../../subsystem/model';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Autoplay-through-steps harness. Drives `
|
|
9
|
+
* Autoplay-through-steps harness. Drives `autoPlayTrails` with the
|
|
10
10
|
* camera/focus knobs exposed as Storybook controls so the step-focus behavior
|
|
11
11
|
* can be tuned live.
|
|
12
12
|
*
|
|
13
13
|
* Note on current behavior: the autoplay loop advances by setting the
|
|
14
14
|
* *hovered* step (dim-highlight) — it does not camera-focus each step, so
|
|
15
|
-
* `
|
|
15
|
+
* `trailStepMode` / `zoomOnTrailFocus` don't change the autoplay
|
|
16
16
|
* camera today. This story exists to expose that gap and iterate on it.
|
|
17
17
|
*/
|
|
18
18
|
const meta = {
|
|
19
|
-
title: 'Subsystem/ComponentGraph/
|
|
19
|
+
title: 'Subsystem/ComponentGraph/TrailAutoplay',
|
|
20
20
|
component: SubsystemComponentGraph,
|
|
21
21
|
parameters: { layout: 'fullscreen' },
|
|
22
22
|
tags: ['autodocs'],
|
|
@@ -77,7 +77,7 @@ const components: SubsystemComponent[] = [
|
|
|
77
77
|
},
|
|
78
78
|
];
|
|
79
79
|
|
|
80
|
-
const
|
|
80
|
+
const trails: SubsystemTrail[] = [
|
|
81
81
|
{
|
|
82
82
|
id: 'wt-book',
|
|
83
83
|
title: 'Book a slot',
|
|
@@ -172,38 +172,38 @@ const readFile = (path: string): Promise<string> =>
|
|
|
172
172
|
|
|
173
173
|
export const AutoplayFocus: Story = {
|
|
174
174
|
args: {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
175
|
+
autoPlayTrails: true,
|
|
176
|
+
trailStepMode: 'focus',
|
|
177
|
+
zoomOnTrailFocus: true,
|
|
178
|
+
trailAutoPlayIntervalMs: 5000,
|
|
179
|
+
trailFocusDurationMs: 800,
|
|
180
|
+
showTrailTitle: true,
|
|
181
|
+
initialTrailId: 'wt-book',
|
|
182
182
|
},
|
|
183
183
|
argTypes: {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
autoPlayTrails: { control: 'boolean' },
|
|
185
|
+
trailStepMode: { control: 'inline-radio', options: ['focus', 'dim'] },
|
|
186
|
+
zoomOnTrailFocus: { control: 'boolean' },
|
|
187
|
+
trailAutoPlayIntervalMs: {
|
|
188
188
|
control: { type: 'range', min: 400, max: 8000, step: 100 },
|
|
189
189
|
},
|
|
190
|
-
|
|
190
|
+
trailFocusDurationMs: {
|
|
191
191
|
control: { type: 'range', min: 100, max: 2000, step: 50 },
|
|
192
192
|
},
|
|
193
|
-
|
|
193
|
+
showTrailTitle: { control: 'boolean' },
|
|
194
194
|
},
|
|
195
195
|
render: (args) => (
|
|
196
196
|
<div style={{ width: '100%', height: '100vh' }}>
|
|
197
197
|
<SubsystemComponentGraph
|
|
198
198
|
{...args}
|
|
199
199
|
components={components}
|
|
200
|
-
|
|
200
|
+
trails={trails}
|
|
201
201
|
hideSidebar
|
|
202
202
|
hideDrawer
|
|
203
|
-
edgeView="
|
|
204
|
-
|
|
203
|
+
edgeView="trails"
|
|
204
|
+
initialTrailId="wt-book"
|
|
205
205
|
title="Autoplay through steps"
|
|
206
|
-
description="Autoplay cycles the
|
|
206
|
+
description="Autoplay cycles the trail steps. **Goal to refine:** each advance should camera-focus the step (and optionally open its snippet), not just dim the rest of the graph. Use the controls to compare `focus` vs `dim` and the zoom gate."
|
|
207
207
|
renderFileViewer={(file, opts) => (
|
|
208
208
|
<div style={{ padding: 12, fontFamily: 'monospace', fontSize: 12, color: '#bbb', whiteSpace: 'pre' }}>
|
|
209
209
|
{`// ${file}`}
|
|
@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
3
3
|
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
4
4
|
import { SubsystemComponentGraph } from '../../../subsystem/SubsystemComponentGraph';
|
|
5
5
|
import type { SubsystemComponent } from '../../../subsystem/model';
|
|
6
|
-
import {
|
|
6
|
+
import { graphSpecFromSteps } from './fixtures';
|
|
7
7
|
|
|
8
8
|
const meta = {
|
|
9
9
|
title: 'Subsystem/ComponentGraph/WorkspacePackages',
|
|
@@ -114,7 +114,7 @@ const components: SubsystemComponent[] = [
|
|
|
114
114
|
},
|
|
115
115
|
];
|
|
116
116
|
|
|
117
|
-
const spec =
|
|
117
|
+
const spec = graphSpecFromSteps([
|
|
118
118
|
['read-file', 'get-model', 'calls'],
|
|
119
119
|
['model-view', 'component-graph', 'uses'],
|
|
120
120
|
['component-graph', 'file-drawer', 'calls'],
|
|
@@ -125,7 +125,7 @@ export const PackageOwnedProcess: Story = {
|
|
|
125
125
|
name: 'Package-owned process · library outside',
|
|
126
126
|
args: {
|
|
127
127
|
components,
|
|
128
|
-
|
|
128
|
+
trails: spec.trails,
|
|
129
129
|
graphTitle: 'Opening a file — app package owns the process',
|
|
130
130
|
},
|
|
131
131
|
render: (args) => (
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
SubsystemComponent,
|
|
3
3
|
SubsystemComponentEdge,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
SubsystemTrail,
|
|
5
|
+
SubsystemTrailMechanism,
|
|
6
6
|
} from '../../../subsystem/model';
|
|
7
7
|
import type { GraphifyComponentDetail } from '../../../graphify';
|
|
8
8
|
|
|
@@ -24,16 +24,16 @@ export function components(
|
|
|
24
24
|
}));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** Story helper: one
|
|
28
|
-
export function
|
|
27
|
+
/** Story helper: one trail whose steps derive Set B display edges. */
|
|
28
|
+
export function trailFromSteps(
|
|
29
29
|
id: string,
|
|
30
30
|
title: string,
|
|
31
|
-
|
|
32
|
-
):
|
|
31
|
+
steps: Array<[from: string, to: string, mechanism: SubsystemTrailMechanism, file: string, line: number, symbol?: string]>,
|
|
32
|
+
): SubsystemTrail {
|
|
33
33
|
return {
|
|
34
34
|
id,
|
|
35
35
|
title,
|
|
36
|
-
steps:
|
|
36
|
+
steps: steps.map(([from, to, mechanism, file, line, symbol]) => ({
|
|
37
37
|
from,
|
|
38
38
|
to,
|
|
39
39
|
mechanism,
|
|
@@ -45,35 +45,23 @@ export function walkthroughFromHops(
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/**
|
|
49
|
-
export function
|
|
48
|
+
/** Turn every spec entry into a trail step — the sole authored edge form. */
|
|
49
|
+
export function graphSpecFromSteps(
|
|
50
50
|
spec: Array<[from: string, to: string, mechanism: SubsystemComponentEdge['mechanism']]>,
|
|
51
|
-
):
|
|
52
|
-
|
|
53
|
-
id: `e${i}`,
|
|
51
|
+
): { trails?: SubsystemTrail[] } {
|
|
52
|
+
const steps: SubsystemTrail['steps'] = spec.map(([from, to, mechanism]) => ({
|
|
54
53
|
from,
|
|
55
54
|
to,
|
|
56
|
-
mechanism,
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Turn every spec entry into a walkthrough hop — the sole authored edge form. */
|
|
61
|
-
export function graphSpecFromHops(
|
|
62
|
-
spec: Array<[from: string, to: string, mechanism: SubsystemComponentEdge['mechanism']]>,
|
|
63
|
-
): { walkthroughs?: SubsystemWalkthrough[] } {
|
|
64
|
-
const hops: SubsystemWalkthrough['steps'] = spec.map(([from, to, mechanism]) => ({
|
|
65
|
-
from,
|
|
66
|
-
to,
|
|
67
|
-
mechanism: mechanism as SubsystemWalkthroughMechanism,
|
|
55
|
+
mechanism: mechanism as SubsystemTrailMechanism,
|
|
68
56
|
file: 'story-placeholder.ts',
|
|
69
57
|
line: 1,
|
|
70
58
|
purl: 'pkg:github/storybook/fixture#story-placeholder.ts',
|
|
71
59
|
symbol: from,
|
|
72
60
|
}));
|
|
73
61
|
return {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
? [{ id: 'story-
|
|
62
|
+
trails:
|
|
63
|
+
steps.length > 0
|
|
64
|
+
? [{ id: 'story-steps', title: 'Story steps', steps: steps }]
|
|
77
65
|
: undefined,
|
|
78
66
|
};
|
|
79
67
|
}
|
|
@@ -153,19 +141,11 @@ export const investigateOnlyComponents: SubsystemComponent[] = [
|
|
|
153
141
|
},
|
|
154
142
|
];
|
|
155
143
|
|
|
156
|
-
const investigateSpec =
|
|
144
|
+
const investigateSpec = graphSpecFromSteps([
|
|
157
145
|
['v1', 'input', 'produces'],
|
|
158
146
|
['v2', 'input', 'produces'],
|
|
159
147
|
['input', 'acc', 'feeds'],
|
|
160
148
|
['acc', 'out', 'produces'],
|
|
161
149
|
]);
|
|
162
150
|
|
|
163
|
-
export const
|
|
164
|
-
|
|
165
|
-
/** @deprecated use investigateOnlyWalkthroughs */
|
|
166
|
-
export const investigateOnlyEdges: SubsystemComponentEdge[] = edges([
|
|
167
|
-
['v1', 'input', 'produces'],
|
|
168
|
-
['v2', 'input', 'produces'],
|
|
169
|
-
['input', 'acc', 'feeds'],
|
|
170
|
-
['acc', 'out', 'produces'],
|
|
171
|
-
]);
|
|
151
|
+
export const investigateOnlyTrails = investigateSpec.trails;
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Prototype test case: feed it a `C4Model` from `toC4()` and it draws the
|
|
5
5
|
* system as a compound frame, its containers (or components) as boxes, and
|
|
6
|
-
* externals/actors outside the system. `
|
|
6
|
+
* externals/actors outside the system. `trail` steps render as flow
|
|
7
7
|
* edges. Click a box to list the source components it rolled up.
|
|
8
8
|
*
|
|
9
9
|
* Same interaction language as the other graphs: React Flow + ELK + the shared
|
|
10
10
|
* `GRAPH_NAV_PROPS` chrome. Deliberately small — no measurement passes, no
|
|
11
|
-
* drawers, no
|
|
11
|
+
* drawers, no trail playback.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { useEffect, useMemo, useState } from 'react';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ConstructsCatalog — master/detail for a constructs-only subsystem
|
|
3
|
-
* (components, no topology or
|
|
3
|
+
* (components, no topology or trail edges).
|
|
4
4
|
*
|
|
5
5
|
* Left: the model's files as a tree; clicking a file toggles its
|
|
6
6
|
* constructs. Right: signatures grouped by repo, and within a repo stacked
|
|
@@ -60,7 +60,6 @@ export interface ConstructsCatalogProps {
|
|
|
60
60
|
sidebarExtra?: ReactNode;
|
|
61
61
|
sidebarAfterDescription?: ReactNode;
|
|
62
62
|
renderFileViewer?: (file: string, opts?: SubsystemOpenFileOptions) => ReactNode;
|
|
63
|
-
renderFileView?: (component: SubsystemComponent) => ReactNode;
|
|
64
63
|
onFileSelect?: (file: string) => void;
|
|
65
64
|
componentVerification?: ComponentVerificationState | null;
|
|
66
65
|
/** Referenced-symbol click → host graphify lookup (purl/file from the card). */
|
|
@@ -192,7 +191,6 @@ export function ConstructsCatalog({
|
|
|
192
191
|
sidebarExtra,
|
|
193
192
|
sidebarAfterDescription,
|
|
194
193
|
renderFileViewer,
|
|
195
|
-
renderFileView,
|
|
196
194
|
onFileSelect,
|
|
197
195
|
componentVerification,
|
|
198
196
|
onInspectSymbol,
|
|
@@ -537,19 +535,7 @@ export function ConstructsCatalog({
|
|
|
537
535
|
[components, show, searchActive],
|
|
538
536
|
);
|
|
539
537
|
|
|
540
|
-
const fileViewer =
|
|
541
|
-
if (renderFileViewer) return renderFileViewer;
|
|
542
|
-
if (renderFileView) {
|
|
543
|
-
const byFile = new Map(
|
|
544
|
-
components.filter((c) => c.file).map((c) => [c.file, c] as const),
|
|
545
|
-
);
|
|
546
|
-
return (file: string, _opts?: SubsystemOpenFileOptions) => {
|
|
547
|
-
const comp = byFile.get(file);
|
|
548
|
-
return comp ? renderFileView(comp) : null;
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
return undefined;
|
|
552
|
-
}, [renderFileViewer, renderFileView, components]);
|
|
538
|
+
const fileViewer = renderFileViewer;
|
|
553
539
|
|
|
554
540
|
const fileViewerRef = useRef(fileViewer);
|
|
555
541
|
fileViewerRef.current = fileViewer;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* A compact button that lives in the sidebar title row (beside the description
|
|
5
5
|
* toggle). It carries the *status* of the graph's last verification pass in its
|
|
6
6
|
* icon color + count, and toggles the sidebar between the diagnostics list and
|
|
7
|
-
* the normal files/
|
|
7
|
+
* the normal files/trails view. The graph owns that view; this component
|
|
8
8
|
* only surfaces state and calls `onToggle`.
|
|
9
9
|
*
|
|
10
10
|
* Status → color (theme):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FileDrawer — bottom panel that slides up from the bottom of the graph area
|
|
3
|
-
* to show file /
|
|
4
|
-
* declaration links, and
|
|
3
|
+
* to show file / trail code. Opened by sidebar file-tree clicks,
|
|
4
|
+
* declaration links, and trail step focus; content is injected as
|
|
5
5
|
* children by the graph component.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -35,9 +35,9 @@ const issues: SubsystemIssue[] = [
|
|
|
35
35
|
{
|
|
36
36
|
id: 'wl',
|
|
37
37
|
severity: 'info',
|
|
38
|
-
kind: '
|
|
39
|
-
message: '
|
|
40
|
-
target: { kind: '
|
|
38
|
+
kind: 'trail',
|
|
39
|
+
message: 'trail finding',
|
|
40
|
+
target: { kind: 'trail', id: 'w', label: 'Trail' },
|
|
41
41
|
},
|
|
42
42
|
];
|
|
43
43
|
|
|
@@ -87,7 +87,7 @@ describe('collapsing a category retracts the focus it established', () => {
|
|
|
87
87
|
fireEvent.click(category('Constructs'));
|
|
88
88
|
fireEvent.click(card('Alpha'));
|
|
89
89
|
|
|
90
|
-
fireEvent.click(category('
|
|
90
|
+
fireEvent.click(category('Trail'));
|
|
91
91
|
expect(events).toEqual(['select:ct', 'deselect:ct']);
|
|
92
92
|
});
|
|
93
93
|
|
|
@@ -27,7 +27,7 @@ afterEach(cleanup);
|
|
|
27
27
|
const issue: SubsystemIssue = {
|
|
28
28
|
id: 'i1',
|
|
29
29
|
severity: 'info',
|
|
30
|
-
kind: '
|
|
30
|
+
kind: 'trail',
|
|
31
31
|
message: 'Step 2 references a line that moved.',
|
|
32
32
|
target: {
|
|
33
33
|
kind: 'step',
|
|
@@ -59,7 +59,7 @@ const hasIcon = (container: HTMLElement, name: string) =>
|
|
|
59
59
|
|
|
60
60
|
describe('issue card icon', () => {
|
|
61
61
|
test('a step finding wears the step icon, not the flow lane icon', () => {
|
|
62
|
-
// The audit kind is `
|
|
62
|
+
// The audit kind is `trail` (the whole flow), so without a
|
|
63
63
|
// target-shape icon this card would read as a comment on the flow rather
|
|
64
64
|
// than on the one step that is wrong.
|
|
65
65
|
const { container } = renderCard();
|
|
@@ -69,7 +69,7 @@ describe('issue card icon', () => {
|
|
|
69
69
|
|
|
70
70
|
test('a finding about the flow as a whole keeps the lane icon', () => {
|
|
71
71
|
const { container } = renderCard({
|
|
72
|
-
target: { kind: '
|
|
72
|
+
target: { kind: 'trail', id: 'flow-1', label: 'Checkout' },
|
|
73
73
|
});
|
|
74
74
|
expect(hasIcon(container, 'route')).toBe(true);
|
|
75
75
|
expect(hasIcon(container, 'footprints')).toBe(false);
|
|
@@ -39,14 +39,14 @@ export type SubsystemIssueSeverity = 'error' | 'info';
|
|
|
39
39
|
export type SubsystemIssueTargetKind =
|
|
40
40
|
| 'component'
|
|
41
41
|
| 'module'
|
|
42
|
-
| '
|
|
42
|
+
| 'trail'
|
|
43
43
|
| 'step'
|
|
44
44
|
| 'repo'
|
|
45
45
|
| 'graph';
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* The four verification layers, in order. Mirrors the docs' progression:
|
|
49
|
-
* constructs → static topology → dynamic topology →
|
|
49
|
+
* constructs → static topology → dynamic topology → trail.
|
|
50
50
|
* Static topology = package/module (containment); dynamic topology = process
|
|
51
51
|
* (runtime).
|
|
52
52
|
*/
|
|
@@ -55,7 +55,7 @@ export type SubsystemIssueCategory =
|
|
|
55
55
|
| 'construct'
|
|
56
56
|
| 'static-topology'
|
|
57
57
|
| 'dynamic-topology'
|
|
58
|
-
| '
|
|
58
|
+
| 'trail';
|
|
59
59
|
|
|
60
60
|
/** Layer order + display names, shared by the list and its headers. */
|
|
61
61
|
export const SUBSYSTEM_ISSUE_CATEGORIES: SubsystemIssueCategory[] = [
|
|
@@ -63,7 +63,7 @@ export const SUBSYSTEM_ISSUE_CATEGORIES: SubsystemIssueCategory[] = [
|
|
|
63
63
|
'construct',
|
|
64
64
|
'static-topology',
|
|
65
65
|
'dynamic-topology',
|
|
66
|
-
'
|
|
66
|
+
'trail',
|
|
67
67
|
];
|
|
68
68
|
|
|
69
69
|
/** Per-category header icon — mirrors the Maintainer tab's lane icons. */
|
|
@@ -75,7 +75,7 @@ export const SUBSYSTEM_ISSUE_CATEGORY_ICON: Record<
|
|
|
75
75
|
construct: Component,
|
|
76
76
|
'static-topology': Network,
|
|
77
77
|
'dynamic-topology': Server,
|
|
78
|
-
|
|
78
|
+
trail: Route,
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
export const SUBSYSTEM_ISSUE_CATEGORY_LABEL: Record<
|
|
@@ -86,7 +86,7 @@ export const SUBSYSTEM_ISSUE_CATEGORY_LABEL: Record<
|
|
|
86
86
|
construct: 'Constructs',
|
|
87
87
|
'static-topology': 'Static topology',
|
|
88
88
|
'dynamic-topology': 'Dynamic topology',
|
|
89
|
-
|
|
89
|
+
trail: 'Trail',
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
/** Default `kind` → layer. Module containment is static; process nest is dynamic. */
|
|
@@ -103,7 +103,7 @@ const KIND_CATEGORY: Record<string, SubsystemIssueCategory> = {
|
|
|
103
103
|
graphify_unavailable: 'repo',
|
|
104
104
|
boundary_module_file_mismatch: 'static-topology',
|
|
105
105
|
boundary_process_nest_disagree: 'dynamic-topology',
|
|
106
|
-
|
|
106
|
+
trail: 'trail',
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
/**
|
|
@@ -117,7 +117,7 @@ export function issueCategory(issue: SubsystemIssue): SubsystemIssueCategory {
|
|
|
117
117
|
/**
|
|
118
118
|
* Construct-layer verification rung for a finding kind (file → symbol →
|
|
119
119
|
* declaration → type → signature), or null for findings outside that ladder
|
|
120
|
-
* (topology /
|
|
120
|
+
* (topology / trail / repo). Drives the node overlay's earliest-rung chip.
|
|
121
121
|
*/
|
|
122
122
|
const KIND_RUNG: Record<string, SubsystemIssueRung> = {
|
|
123
123
|
missing_file: 'file',
|
|
@@ -168,7 +168,7 @@ export const ISSUE_KIND_ICON: Record<string, LucideIcon> = {
|
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Icons for target SHAPES that are more specific than their verification lane.
|
|
171
|
-
* An audit `kind` of `
|
|
171
|
+
* An audit `kind` of `trail` covers the whole flow, so a finding about
|
|
172
172
|
* one step of it would otherwise wear the lane's `Route` icon and read as a
|
|
173
173
|
* comment on the flow rather than on the step that is actually wrong.
|
|
174
174
|
*/
|
|
@@ -188,8 +188,8 @@ export interface SubsystemIssueTarget {
|
|
|
188
188
|
/** Optional sub-label (step number, …). */
|
|
189
189
|
detail?: string;
|
|
190
190
|
/**
|
|
191
|
-
* For a `step` target: the
|
|
192
|
-
*
|
|
191
|
+
* For a `step` target: the trail id, plus a 0-based index into that
|
|
192
|
+
* trail's steps. Carried structurally rather than parsed back out of
|
|
193
193
|
* `detail` ("step 7") so focusing a step is exact rather than best-effort —
|
|
194
194
|
* `detail` is a display string and is free to change its phrasing.
|
|
195
195
|
*/
|
|
@@ -243,7 +243,7 @@ const KIND_LABEL: Record<string, string> = {
|
|
|
243
243
|
graphify_unavailable: 'Graphify cache unavailable',
|
|
244
244
|
boundary_module_file_mismatch: 'Declaration file outside module',
|
|
245
245
|
boundary_process_nest_disagree: 'Module spans multiple process contexts',
|
|
246
|
-
|
|
246
|
+
trail: 'Step issue',
|
|
247
247
|
};
|
|
248
248
|
|
|
249
249
|
/** Label for an issue's kind. Explicit `kindLabel` wins; unknown kinds humanize. */
|
|
@@ -275,8 +275,8 @@ const KIND_ORDER: Record<string, number> = {
|
|
|
275
275
|
boundary_module_file_mismatch: 23,
|
|
276
276
|
// Runtime topology — process containment
|
|
277
277
|
boundary_process_nest_disagree: 30,
|
|
278
|
-
//
|
|
279
|
-
|
|
278
|
+
// Trail
|
|
279
|
+
trail: 40,
|
|
280
280
|
};
|
|
281
281
|
|
|
282
282
|
const KIND_ORDER_FALLBACK = 100;
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Same stack and interaction language as SubsystemComponentGraph
|
|
5
5
|
* (React Flow + ELK + custom nodes + select/hover), but purpose-built for
|
|
6
6
|
* composed views: nodes are process / module frames (plus one ungrouped
|
|
7
|
-
* bucket), edges are the deduped
|
|
7
|
+
* bucket), edges are the deduped trail flows between them.
|
|
8
8
|
*
|
|
9
9
|
* Deliberately leaner than the component graph: fixed node sizes (no
|
|
10
10
|
* measurement passes), flat ELK layout (no compound groups, so the
|
|
11
11
|
* double-parent failure mode is structurally impossible), no edge labels,
|
|
12
|
-
* no
|
|
12
|
+
* no trail playback, no drawers. Frame detail (members, models)
|
|
13
13
|
* renders in a side panel.
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -57,7 +57,7 @@ export interface AggregateFrameEdge {
|
|
|
57
57
|
from: string;
|
|
58
58
|
to: string;
|
|
59
59
|
mechanisms: string[];
|
|
60
|
-
|
|
60
|
+
trailIds: string[];
|
|
61
61
|
steps: number;
|
|
62
62
|
/** Real member endpoint behind a hub-routed edge (see aggregate). */
|
|
63
63
|
source?: string;
|