@principal-ai/subsystems-react 0.23.1 → 0.23.3

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.
@@ -278,25 +278,49 @@ export declare function deriveNameFromSymbol(symbol: string | undefined, constru
278
278
  export declare function formatPurl(purl: string): string;
279
279
  export type SubsystemGraphNodeType = 'subsystem-component' | 'subsystem-group';
280
280
  /**
281
- * One boundary region — either a process (runtime deployment unit) or a
282
- * module (source file). Nodes without that field sit outside those frames.
281
+ * One boundary region — process (runtime), module (source file), or package
282
+ * (repo identity from `purl`). Nodes without that membership sit outside
283
+ * those frames. Package frames are derived from `purl` (no separate field);
284
+ * they only appear when the graph spans multiple repos (by default).
283
285
  */
284
286
  export interface SubsystemProcessRegion {
285
- /** Discriminator — which field produced this region. */
286
- kind: 'process' | 'module';
287
- /** The `process` or `module` value (e.g. `principal-studio/host`, `src/a.ts`). */
287
+ /** Discriminator — which field / identity produced this region. */
288
+ kind: 'process' | 'module' | 'package';
289
+ /** The `process` / `module` value, or purl repo key for packages. */
288
290
  key: string;
289
291
  /** Display label for the boundary frame. */
290
292
  label: string;
291
293
  /** Component ids that are members of this region. */
292
294
  memberIds: string[];
293
295
  }
296
+ /** Options for which boundary frames are kept. */
297
+ export interface BoundaryFrameOptions {
298
+ /**
299
+ * Keep 1-member process / module / package frames. Default false
300
+ * (singleton rule — frames need 2+ members).
301
+ */
302
+ showSingletonFrames?: boolean;
303
+ /**
304
+ * When package frames are drawn from component `purl`s.
305
+ * - `multi-repo` (default): only when 2+ distinct repo purls
306
+ * - `always`: frame every multi-member package even in a single-repo graph
307
+ * - `never`: no package frames
308
+ */
309
+ packageFrames?: 'multi-repo' | 'always' | 'never';
310
+ }
294
311
  /** React Flow id for a process boundary group node. */
295
312
  export declare function processGroupNodeId(processKey: string): string;
296
313
  /** React Flow id for a module boundary group node. */
297
314
  export declare function moduleGroupNodeId(moduleKey: string): string;
298
- /** React Flow id for a boundary group of either kind. */
315
+ /** React Flow id for a package (repo) boundary group node. */
316
+ export declare function packageGroupNodeId(packageKey: string): string;
317
+ /** React Flow id for a boundary group of any kind. */
299
318
  export declare function boundaryGroupNodeId(region: Pick<SubsystemProcessRegion, 'kind' | 'key'>): string;
319
+ /**
320
+ * Repo/package key used for package frames — `purl` with fragment stripped.
321
+ * Externals and custom entities are not package-frame members.
322
+ */
323
+ export declare function componentPackageKey(c: Pick<SubsystemComponent, 'purl' | 'construct'>): string | undefined;
300
324
  /**
301
325
  * Derive process boundary regions — one per distinct non-empty `process`
302
326
  * value, in first-appearance order.
@@ -308,23 +332,31 @@ export declare function getSubsystemRegions(doc: Pick<SubsystemModelDocument, 'c
308
332
  */
309
333
  export declare function getSubsystemModuleRegions(doc: Pick<SubsystemModelDocument, 'components'>): SubsystemProcessRegion[];
310
334
  /**
311
- * One compound frame for ELK / React Flow — module frames may nest under a
312
- * process frame via `parentId`.
335
+ * Derive package (repo) boundary regions from component `purl`s — one per
336
+ * distinct repo key. Does not apply multi-repo / singleton filters; callers
337
+ * decide via {@link buildBoundaryLayoutGroups}.
338
+ */
339
+ export declare function getSubsystemPackageRegions(doc: Pick<SubsystemModelDocument, 'components'>): SubsystemProcessRegion[];
340
+ /**
341
+ * One compound frame for ELK / React Flow — modules nest under processes,
342
+ * processes under packages, when membership is shared.
313
343
  */
314
344
  export interface BoundaryLayoutGroup {
315
345
  id: string;
316
346
  memberIds: string[];
317
- /** When set, this group is a child of another boundary group (process). */
347
+ /** When set, this group is a child of another boundary group. */
318
348
  parentId?: string;
319
349
  region: SubsystemProcessRegion;
320
350
  }
321
351
  /**
322
- * Build the process → module → leaf group tree for layout.
323
- * Multi-member modules nest under a process when every member shares that
324
- * process; process ELK children are nested module group ids plus any
325
- * process members that are not inside a kept module frame.
352
+ * Build the package → process → module → leaf group tree for layout.
353
+ *
354
+ * Package frames come from `purl` (no separate component field). By default
355
+ * they only appear when the graph spans 2+ distinct repos. Multi-member
356
+ * modules nest under a process when every member shares that process;
357
+ * processes nest under a package the same way.
326
358
  */
327
- export declare function buildBoundaryLayoutGroups(doc: Pick<SubsystemModelDocument, 'components'>): BoundaryLayoutGroup[];
359
+ export declare function buildBoundaryLayoutGroups(doc: Pick<SubsystemModelDocument, 'components'>, opts?: BoundaryFrameOptions): BoundaryLayoutGroup[];
328
360
  export interface SubsystemGraphNodeData extends Record<string, unknown> {
329
361
  component: SubsystemComponent;
330
362
  /** Set while a file is open in the drawer: true if this node's component
@@ -368,6 +400,11 @@ export declare function packageColor(name: string): string;
368
400
  * are the only surface using it, but pick a distinct value if roles ever
369
401
  * take over node borders. */
370
402
  export declare const ROLE_COLOR: Record<SubsystemComponentRole, string>;
403
+ /**
404
+ * Brand color for the left construct/stereotype badge when a framework owns
405
+ * the label (e.g. `react · component`). Node border stays construct-colored.
406
+ */
407
+ export declare const FRAMEWORK_BADGE_COLOR: Record<string, string>;
371
408
  export declare const ROLE_LABEL: Record<SubsystemComponentRole, string>;
372
409
  /** Right-badge accent for `proposed: true` (no role, or combined with role). */
373
410
  export declare const PROPOSED_COLOR = "#b8860b";
@@ -414,6 +451,15 @@ export declare function constructBadgeLabel(component: {
414
451
  stereotype?: string;
415
452
  entityKind?: string;
416
453
  }): string;
454
+ /**
455
+ * Left-badge accent: framework brand when the badge shows a framework
456
+ * stereotype (e.g. React cyan for `react · component`); otherwise null so
457
+ * the caller falls back to construct color. Border stays construct-colored.
458
+ */
459
+ export declare function constructBadgeColor(component: {
460
+ framework?: string;
461
+ stereotype?: string;
462
+ }): string | null;
417
463
  /** Default CSS floor for component nodes (padding aside). */
418
464
  export declare const NODE_CSS_MIN_WIDTH = 150;
419
465
  /** Inset of each top badge from the node edge (`left` / `right` style). */
@@ -437,21 +483,21 @@ export declare function nodeMinWidthForBadges(component: {
437
483
  /**
438
484
  * Convert a subsystem graph document into React Flow nodes. Components that
439
485
  * carry a `module` get a `parentId` pointing at their module frame
440
- * (`module:<path>`); otherwise a `process` stamps `process:<process>`. Module
441
- * frames may themselves nest under a process frame (stamped on the group node
442
- * in `buildSubsystemGraph`). Nodes without either stay top-level. The initial
443
- * grid clusters by `module ?? process ?? purl`; ELK then refines with compound
444
- * layout.
486
+ * (`module:<path>`); otherwise a `process` stamps `process:<process>`.
487
+ * Package (`purl`) parents are stamped later in `buildSubsystemGraph` only
488
+ * when package frames are kept. Module frames may nest under process →
489
+ * package. The initial grid clusters by `module ?? process ?? purl`; ELK
490
+ * then refines with compound layout.
445
491
  */
446
492
  export declare function convertSubsystemToNodes(doc: SubsystemModelDocument, opts?: {
447
493
  maxNodeWidth?: number;
448
494
  }): SubsystemGraphNode[];
449
495
  /**
450
- * Convert boundary regions into React Flow parent (group) nodes. Module
451
- * frames that share a process nest under that process via `parentId`.
496
+ * Convert boundary regions into React Flow parent (group) nodes. Nesting
497
+ * (package → process → module) is stamped via `parentId` on groups.
452
498
  * Positions/sizes are placeholders — ELK compound layout overwrites them.
453
499
  */
454
- export declare function convertSubsystemToGroups(doc: Pick<SubsystemModelDocument, 'components'>): SubsystemGraphNode[];
500
+ export declare function convertSubsystemToGroups(doc: Pick<SubsystemModelDocument, 'components'>, opts?: BoundaryFrameOptions): SubsystemGraphNode[];
455
501
  /**
456
502
  * Convert a subsystem graph document into React Flow edges. Edges whose target
457
503
  * is an external label (not a component id) point at a synthetic stub so the
@@ -470,7 +516,7 @@ export declare function buildSubsystemGraph(doc: SubsystemModelDocument, opts?:
470
516
  showEdgeLabels?: boolean;
471
517
  measuredWidths?: Map<string, number>;
472
518
  measuredHeights?: Map<string, number>;
473
- }): Promise<{
519
+ } & BoundaryFrameOptions): Promise<{
474
520
  nodes: SubsystemGraphNode[];
475
521
  edges: SubsystemGraphEdge[];
476
522
  regions: SubsystemProcessRegion[];
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/subsystem/model.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@
13
13
  */
14
14
  import { MarkerType, } from '@xyflow/react';
15
15
  import { computeElkLayout, calculatePathLength } from '../utils/elkLayout';
16
+ import { purlOwnerName, purlRepoKey } from './paths';
16
17
  /** Stable id for a derived graph edge from a relation or walkthrough hop. */
17
18
  export function derivedGraphEdgeId(from, to, mechanism) {
18
19
  return `${from}--${mechanism}-->${to}`;
@@ -123,11 +124,32 @@ export function processGroupNodeId(processKey) {
123
124
  export function moduleGroupNodeId(moduleKey) {
124
125
  return `module:${moduleKey}`;
125
126
  }
126
- /** React Flow id for a boundary group of either kind. */
127
+ /** React Flow id for a package (repo) boundary group node. */
128
+ export function packageGroupNodeId(packageKey) {
129
+ return `package:${packageKey}`;
130
+ }
131
+ /** React Flow id for a boundary group of any kind. */
127
132
  export function boundaryGroupNodeId(region) {
128
- return region.kind === 'module'
129
- ? moduleGroupNodeId(region.key)
130
- : processGroupNodeId(region.key);
133
+ if (region.kind === 'module')
134
+ return moduleGroupNodeId(region.key);
135
+ if (region.kind === 'package')
136
+ return packageGroupNodeId(region.key);
137
+ return processGroupNodeId(region.key);
138
+ }
139
+ /**
140
+ * Repo/package key used for package frames — `purl` with fragment stripped.
141
+ * Externals and custom entities are not package-frame members.
142
+ */
143
+ export function componentPackageKey(c) {
144
+ if (c.construct === 'external' || c.construct === 'custom_entity')
145
+ return undefined;
146
+ const key = purlRepoKey(c.purl);
147
+ if (!key || key === 'external')
148
+ return undefined;
149
+ return key;
150
+ }
151
+ function packageRegionLabel(packageKey) {
152
+ return purlOwnerName(packageKey) ?? formatPurl(packageKey);
131
153
  }
132
154
  /**
133
155
  * Derive process boundary regions — one per distinct non-empty `process`
@@ -172,22 +194,66 @@ export function getSubsystemModuleRegions(doc) {
172
194
  }));
173
195
  }
174
196
  /**
175
- * Build the process → module → leaf group tree for layout.
176
- * Multi-member modules nest under a process when every member shares that
177
- * process; process ELK children are nested module group ids plus any
178
- * process members that are not inside a kept module frame.
197
+ * Derive package (repo) boundary regions from component `purl`s — one per
198
+ * distinct repo key. Does not apply multi-repo / singleton filters; callers
199
+ * decide via {@link buildBoundaryLayoutGroups}.
179
200
  */
180
- export function buildBoundaryLayoutGroups(doc) {
201
+ export function getSubsystemPackageRegions(doc) {
202
+ const byPackage = new Map();
203
+ for (const c of doc.components) {
204
+ const key = componentPackageKey(c);
205
+ if (!key)
206
+ continue;
207
+ const list = byPackage.get(key) ?? [];
208
+ list.push(c.id);
209
+ byPackage.set(key, list);
210
+ }
211
+ return [...byPackage.entries()].map(([key, memberIds]) => ({
212
+ kind: 'package',
213
+ key,
214
+ label: packageRegionLabel(key),
215
+ memberIds,
216
+ }));
217
+ }
218
+ function keepRegion(r, showSingletons) {
219
+ return showSingletons || r.memberIds.length >= 2;
220
+ }
221
+ /**
222
+ * Build the package → process → module → leaf group tree for layout.
223
+ *
224
+ * Package frames come from `purl` (no separate component field). By default
225
+ * they only appear when the graph spans 2+ distinct repos. Multi-member
226
+ * modules nest under a process when every member shares that process;
227
+ * processes nest under a package the same way.
228
+ */
229
+ export function buildBoundaryLayoutGroups(doc, opts = {}) {
230
+ const showSingletons = opts.showSingletonFrames === true;
231
+ const packageMode = opts.packageFrames ?? 'multi-repo';
181
232
  const byId = new Map(doc.components.map((c) => [c.id, c]));
182
- const modules = getSubsystemModuleRegions(doc).filter((r) => r.memberIds.length >= 2);
183
- const processes = getSubsystemRegions(doc).filter((r) => r.memberIds.length >= 2);
233
+ const allPackages = getSubsystemPackageRegions(doc);
234
+ const packageEligible = packageMode === 'always'
235
+ ? true
236
+ : packageMode === 'never'
237
+ ? false
238
+ : allPackages.length >= 2;
239
+ const packages = packageEligible
240
+ ? allPackages.filter((r) => keepRegion(r, showSingletons))
241
+ : [];
242
+ const keptPackageKeys = new Set(packages.map((r) => r.key));
243
+ const modules = getSubsystemModuleRegions(doc).filter((r) => keepRegion(r, showSingletons));
244
+ const processes = getSubsystemRegions(doc).filter((r) => keepRegion(r, showSingletons));
184
245
  const keptProcessKeys = new Set(processes.map((r) => r.key));
185
246
  const moduleGroups = modules.map((r) => {
186
247
  const processesOfMembers = new Set();
248
+ const packagesOfMembers = new Set();
187
249
  for (const id of r.memberIds) {
188
- const p = byId.get(id)?.process?.trim();
250
+ const c = byId.get(id);
251
+ const p = c?.process?.trim();
189
252
  if (p)
190
253
  processesOfMembers.add(p);
254
+ const pkg = c ? componentPackageKey(c) : undefined;
255
+ if (pkg)
256
+ packagesOfMembers.add(pkg);
191
257
  }
192
258
  let parentId;
193
259
  if (processesOfMembers.size === 1) {
@@ -195,6 +261,11 @@ export function buildBoundaryLayoutGroups(doc) {
195
261
  if (keptProcessKeys.has(p))
196
262
  parentId = processGroupNodeId(p);
197
263
  }
264
+ if (!parentId && packagesOfMembers.size === 1) {
265
+ const pkg = [...packagesOfMembers][0];
266
+ if (keptPackageKeys.has(pkg))
267
+ parentId = packageGroupNodeId(pkg);
268
+ }
198
269
  return {
199
270
  id: moduleGroupNodeId(r.key),
200
271
  memberIds: [...r.memberIds],
@@ -212,13 +283,51 @@ export function buildBoundaryLayoutGroups(doc) {
212
283
  return true;
213
284
  return !nestedModuleKeys.has(mod);
214
285
  });
286
+ const packagesOfMembers = new Set();
287
+ for (const id of r.memberIds) {
288
+ const c = byId.get(id);
289
+ const pkg = c ? componentPackageKey(c) : undefined;
290
+ if (pkg)
291
+ packagesOfMembers.add(pkg);
292
+ }
293
+ let parentId;
294
+ if (packagesOfMembers.size === 1) {
295
+ const pkg = [...packagesOfMembers][0];
296
+ if (keptPackageKeys.has(pkg))
297
+ parentId = packageGroupNodeId(pkg);
298
+ }
215
299
  return {
216
300
  id: processId,
217
301
  memberIds: [...nestedModules.map((m) => m.id), ...directLeaves],
302
+ parentId,
218
303
  region: r,
219
304
  };
220
305
  });
221
- return [...moduleGroups, ...processGroups];
306
+ const packageGroups = packages.map((r) => {
307
+ const packageId = packageGroupNodeId(r.key);
308
+ const nestedProcesses = processGroups.filter((p) => p.parentId === packageId);
309
+ const nestedModules = moduleGroups.filter((m) => m.parentId === packageId);
310
+ const claimed = new Set();
311
+ for (const p of nestedProcesses) {
312
+ for (const id of p.region.memberIds)
313
+ claimed.add(id);
314
+ }
315
+ for (const m of nestedModules) {
316
+ for (const id of m.region.memberIds)
317
+ claimed.add(id);
318
+ }
319
+ const directLeaves = r.memberIds.filter((id) => !claimed.has(id));
320
+ return {
321
+ id: packageId,
322
+ memberIds: [
323
+ ...nestedProcesses.map((p) => p.id),
324
+ ...nestedModules.map((m) => m.id),
325
+ ...directLeaves,
326
+ ],
327
+ region: r,
328
+ };
329
+ });
330
+ return [...moduleGroups, ...processGroups, ...packageGroups];
222
331
  }
223
332
  export const MECHANISM_COLOR = {
224
333
  imports: '#0893d2',
@@ -297,6 +406,13 @@ export const ROLE_COLOR = {
297
406
  entry: '#ff6b35',
298
407
  service: '#0893d2', // blue — external system
299
408
  };
409
+ /**
410
+ * Brand color for the left construct/stereotype badge when a framework owns
411
+ * the label (e.g. `react · component`). Node border stays construct-colored.
412
+ */
413
+ export const FRAMEWORK_BADGE_COLOR = {
414
+ react: '#61dafb', // React cyan
415
+ };
300
416
  export const ROLE_LABEL = {
301
417
  entry: 'entry',
302
418
  service: 'service',
@@ -375,14 +491,24 @@ export function constructBadgeLabel(component) {
375
491
  return component.stereotype;
376
492
  return constructLabel ?? '';
377
493
  }
494
+ /**
495
+ * Left-badge accent: framework brand when the badge shows a framework
496
+ * stereotype (e.g. React cyan for `react · component`); otherwise null so
497
+ * the caller falls back to construct color. Border stays construct-colored.
498
+ */
499
+ export function constructBadgeColor(component) {
500
+ if (component.framework == null || component.stereotype == null)
501
+ return null;
502
+ return FRAMEWORK_BADGE_COLOR[component.framework] ?? null;
503
+ }
378
504
  /** Default CSS floor for component nodes (padding aside). */
379
505
  export const NODE_CSS_MIN_WIDTH = 150;
380
506
  /** Inset of each top badge from the node edge (`left` / `right` style). */
381
507
  export const BADGE_EDGE_INSET = 5;
382
508
  /** Minimum gap between left construct badge and right role badge. */
383
509
  const BADGE_PAIR_GAP = 8;
384
- /** Badge box chrome: padding 5+5 + border 1+1. */
385
- const BADGE_BOX_CHROME = 12;
510
+ /** Badge box chrome: padding 8+8 + border 2+2. */
511
+ const BADGE_BOX_CHROME = 20;
386
512
  /** Approx monospace uppercase width incl. letter-spacing (~0.5px). */
387
513
  const BADGE_CHAR_WIDTH = 8;
388
514
  /** Estimated rendered width of a top tab badge label. */
@@ -411,11 +537,11 @@ export function nodeMinWidthForBadges(component) {
411
537
  /**
412
538
  * Convert a subsystem graph document into React Flow nodes. Components that
413
539
  * carry a `module` get a `parentId` pointing at their module frame
414
- * (`module:<path>`); otherwise a `process` stamps `process:<process>`. Module
415
- * frames may themselves nest under a process frame (stamped on the group node
416
- * in `buildSubsystemGraph`). Nodes without either stay top-level. The initial
417
- * grid clusters by `module ?? process ?? purl`; ELK then refines with compound
418
- * layout.
540
+ * (`module:<path>`); otherwise a `process` stamps `process:<process>`.
541
+ * Package (`purl`) parents are stamped later in `buildSubsystemGraph` only
542
+ * when package frames are kept. Module frames may nest under process →
543
+ * package. The initial grid clusters by `module ?? process ?? purl`; ELK
544
+ * then refines with compound layout.
419
545
  */
420
546
  export function convertSubsystemToNodes(doc, opts = {}) {
421
547
  const { maxNodeWidth } = opts;
@@ -477,12 +603,12 @@ export function convertSubsystemToNodes(doc, opts = {}) {
477
603
  return nodes;
478
604
  }
479
605
  /**
480
- * Convert boundary regions into React Flow parent (group) nodes. Module
481
- * frames that share a process nest under that process via `parentId`.
606
+ * Convert boundary regions into React Flow parent (group) nodes. Nesting
607
+ * (package → process → module) is stamped via `parentId` on groups.
482
608
  * Positions/sizes are placeholders — ELK compound layout overwrites them.
483
609
  */
484
- export function convertSubsystemToGroups(doc) {
485
- return buildBoundaryLayoutGroups(doc).map((g) => ({
610
+ export function convertSubsystemToGroups(doc, opts = {}) {
611
+ return buildBoundaryLayoutGroups(doc, opts).map((g) => ({
486
612
  id: g.id,
487
613
  type: 'subsystem-group',
488
614
  position: { x: 0, y: 0 },
@@ -541,33 +667,39 @@ export function subsystemGraphLayoutKey(doc) {
541
667
  * layered with minimized crossings.
542
668
  */
543
669
  export async function buildSubsystemGraph(doc, opts = {}) {
544
- const { maxNodeWidth, showEdgeLabels, measuredWidths, measuredHeights } = opts;
670
+ const { maxNodeWidth, showEdgeLabels, measuredWidths, measuredHeights, showSingletonFrames, packageFrames, } = opts;
671
+ const frameOpts = { showSingletonFrames, packageFrames };
545
672
  const nodes = convertSubsystemToNodes(doc, { maxNodeWidth });
546
673
  const edges = convertSubsystemToEdges(doc);
547
- // Nested boundary tree: process → module → leaves (when both fields set).
548
- const layoutGroups = buildBoundaryLayoutGroups(doc);
674
+ // Nested boundary tree: package → process → module → leaves.
675
+ const layoutGroups = buildBoundaryLayoutGroups(doc, frameOpts);
549
676
  const regions = layoutGroups.map((g) => g.region);
550
677
  const regionIds = new Set(layoutGroups.map((g) => g.id));
551
678
  const byId = new Map(doc.components.map((c) => [c.id, c]));
552
- // Drop leaf parentIds that point at singleton / missing frames; fall back
553
- // from a dropped module frame to a kept process frame when possible.
679
+ // Resolve leaf parentIds against kept frames: module → process → package.
680
+ // Stamp package parents here (not in convertSubsystemToNodes) so single-repo
681
+ // graphs never provisionally parent under a package that will be dropped.
554
682
  for (const n of nodes) {
555
683
  if (n.type !== 'subsystem-component')
556
684
  continue;
557
685
  const parentId = n.parentId;
558
- if (!parentId)
559
- continue;
560
- if (regionIds.has(parentId))
686
+ if (parentId && regionIds.has(parentId))
561
687
  continue;
562
- const comp = n.data.component;
563
- const processKey = comp?.process?.trim() || byId.get(n.id)?.process?.trim();
688
+ const comp = n.data.component ?? byId.get(n.id);
689
+ const processKey = comp?.process?.trim();
564
690
  const processId = processKey ? processGroupNodeId(processKey) : undefined;
565
691
  if (processId && regionIds.has(processId)) {
566
692
  n.parentId = processId;
693
+ continue;
567
694
  }
568
- else {
569
- delete n.parentId;
695
+ const packageKey = comp ? componentPackageKey(comp) : undefined;
696
+ const packageId = packageKey ? packageGroupNodeId(packageKey) : undefined;
697
+ if (packageId && regionIds.has(packageId)) {
698
+ n.parentId = packageId;
699
+ continue;
570
700
  }
701
+ if (parentId)
702
+ delete n.parentId;
571
703
  }
572
704
  // External edge targets that aren't real components → create stub nodes so
573
705
  // cross-package edges have something to land on.
@@ -640,7 +772,8 @@ export async function buildSubsystemGraph(doc, opts = {}) {
640
772
  })),
641
773
  });
642
774
  const builtGroupIds = new Set(result.groupBounds.keys());
643
- // Parents before children — process frames, then nested module frames.
775
+ // Parents before children — package, then process, then module frames.
776
+ const packageGroupNodes = [];
644
777
  const processGroupNodes = [];
645
778
  const moduleGroupNodes = [];
646
779
  for (const g of layoutGroups) {
@@ -657,7 +790,9 @@ export async function buildSubsystemGraph(doc, opts = {}) {
657
790
  ...(parentId ? { parentId } : {}),
658
791
  data: { region: g.region },
659
792
  };
660
- if (g.region.kind === 'process')
793
+ if (g.region.kind === 'package')
794
+ packageGroupNodes.push(group);
795
+ else if (g.region.kind === 'process')
661
796
  processGroupNodes.push(group);
662
797
  else
663
798
  moduleGroupNodes.push(group);
@@ -672,6 +807,7 @@ export async function buildSubsystemGraph(doc, opts = {}) {
672
807
  }
673
808
  }
674
809
  placedNodes = [
810
+ ...packageGroupNodes,
675
811
  ...processGroupNodes,
676
812
  ...moduleGroupNodes,
677
813
  ...result.nodes,
@@ -684,6 +820,7 @@ export async function buildSubsystemGraph(doc, opts = {}) {
684
820
  // Fall back to the (unpositioned) grid if ELK is unavailable — still
685
821
  // emit multi-member frames so parentId targets exist.
686
822
  console.warn('[subsystem-graph] ELK layout failed, using manual positions:', err);
823
+ const packageGroupNodes = [];
687
824
  const processGroupNodes = [];
688
825
  const moduleGroupNodes = [];
689
826
  for (const g of layoutGroups) {
@@ -696,12 +833,19 @@ export async function buildSubsystemGraph(doc, opts = {}) {
696
833
  ...(g.parentId ? { parentId: g.parentId } : {}),
697
834
  data: { region: g.region },
698
835
  };
699
- if (g.region.kind === 'process')
836
+ if (g.region.kind === 'package')
837
+ packageGroupNodes.push(group);
838
+ else if (g.region.kind === 'process')
700
839
  processGroupNodes.push(group);
701
840
  else
702
841
  moduleGroupNodes.push(group);
703
842
  }
704
- placedNodes = [...processGroupNodes, ...moduleGroupNodes, ...nodes];
843
+ placedNodes = [
844
+ ...packageGroupNodes,
845
+ ...processGroupNodes,
846
+ ...moduleGroupNodes,
847
+ ...nodes,
848
+ ];
705
849
  }
706
850
  }
707
851
  // Stamp ELK-computed label midpoints onto edge data so the overlay can