@contentful/experience-design-system-cli 2.37.1-dev-build-c1d02862.0 → 2.37.1-dev-build-40c29bf0.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 (51) hide show
  1. package/dist/app.js +3191 -317
  2. package/dist/index.js +3462 -316
  3. package/dist/package.json +1 -1
  4. package/dist/src/tui/import/steps/07-scope-gate/cache-check.d.ts +29 -0
  5. package/{legacy/dist/src/import/tui/scope-gate-columns.d.ts → dist/src/tui/import/steps/07-scope-gate/columns.d.ts} +22 -2
  6. package/dist/src/tui/import/steps/07-scope-gate/graph/composite-closure.d.ts +26 -0
  7. package/dist/src/tui/import/steps/07-scope-gate/graph/cycle-detection.d.ts +22 -0
  8. package/dist/src/tui/import/steps/07-scope-gate/graph/fuzzy-search.d.ts +3 -0
  9. package/dist/src/tui/import/steps/07-scope-gate/graph/index.d.ts +33 -0
  10. package/dist/src/tui/import/steps/07-scope-gate/graph/lineage.d.ts +29 -0
  11. package/dist/src/tui/import/steps/07-scope-gate/graph/search-neighborhood.d.ts +3 -0
  12. package/dist/src/tui/import/steps/07-scope-gate/graph/slot-graph.d.ts +11 -0
  13. package/dist/src/tui/import/steps/07-scope-gate/keymap.d.ts +84 -0
  14. package/dist/src/tui/import/steps/07-scope-gate/load.d.ts +8 -0
  15. package/dist/src/tui/import/steps/07-scope-gate/panels/added-column.d.ts +15 -0
  16. package/dist/src/tui/import/steps/07-scope-gate/panels/cycles-panel.d.ts +8 -0
  17. package/dist/src/tui/import/steps/07-scope-gate/panels/reject-prompt.d.ts +5 -0
  18. package/dist/src/tui/import/steps/07-scope-gate/screen.d.ts +9 -0
  19. package/dist/src/tui/import/steps/07-scope-gate/sidebar/autocomplete.d.ts +5 -0
  20. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/CompactControlBar.d.ts +4 -0
  21. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/GotoBanner.d.ts +32 -0
  22. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/GroupedSidebar.d.ts +93 -0
  23. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/HelpOverlay.d.ts +21 -0
  24. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/LegendEntry.d.ts +2 -0
  25. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/SearchMatchSummary.d.ts +11 -0
  26. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/badge.d.ts +13 -0
  27. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/windowed-panel.d.ts +17 -0
  28. package/dist/src/tui/import/steps/07-scope-gate/sidebar/group-collapse.d.ts +2 -0
  29. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/sidebar-search-state.d.ts +17 -0
  30. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.d.ts +6 -0
  31. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/useImmediateInput.d.ts +20 -0
  32. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/useOverlayPanel.d.ts +13 -0
  33. package/dist/src/tui/import/steps/07-scope-gate/sidebar/lineage-layout.d.ts +68 -0
  34. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-help.d.ts +2 -0
  35. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-input.d.ts +13 -0
  36. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-navigation.d.ts +18 -0
  37. package/dist/src/tui/import/steps/07-scope-gate/sidebar/step-filters.d.ts +19 -0
  38. package/dist/src/tui/import/steps/07-scope-gate/sidebar/theme.d.ts +8 -0
  39. package/dist/src/tui/import/steps/07-scope-gate/sidebar/types.d.ts +7 -0
  40. package/dist/src/tui/import/steps/07-scope-gate/state.d.ts +19 -0
  41. package/dist/src/tui/import/steps/07-scope-gate/types.d.ts +24 -0
  42. package/dist/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.d.ts +31 -0
  43. package/dist/src/tui/import/steps/07-scope-gate/use-scope-gate.d.ts +76 -0
  44. package/legacy/dist/src/import/tui/handoff.d.ts +11 -0
  45. package/legacy/dist/src/index.js +1511 -2733
  46. package/legacy/package.json +1 -1
  47. package/package.json +4 -4
  48. package/legacy/dist/src/import/tui/steps/ScopeGateStep.d.ts +0 -48
  49. /package/{legacy/dist/src/analyze → dist/src/tui/import/steps/07-scope-gate/graph}/scope-gate-cascade.d.ts +0 -0
  50. /package/{legacy/dist/src/import/tui → dist/src/tui/import/steps/07-scope-gate/sidebar}/ai-flag.d.ts +0 -0
  51. /package/{legacy/dist/src/import/tui → dist/src/tui/import/steps/07-scope-gate/sidebar}/components/CounterStrip.d.ts +0 -0
package/dist/index.js CHANGED
@@ -125,8 +125,8 @@ function readPackageVersion() {
125
125
  return pkg2.version ?? "unknown";
126
126
  }
127
127
  function parseVersionTag(tag) {
128
- const match = /^v(\d+\.\d+\.\d+)$/.exec(tag);
129
- return match ? match[1] : void 0;
128
+ const match2 = /^v(\d+\.\d+\.\d+)$/.exec(tag);
129
+ return match2 ? match2[1] : void 0;
130
130
  }
131
131
  async function checkForUpgrade() {
132
132
  const current = readPackageVersion();
@@ -1633,8 +1633,8 @@ async function runAgent(options) {
1633
1633
  const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
1634
1634
  const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
1635
1635
  const binary = resolveBinary(agent);
1636
- const useStdin = !!promptViaStdin;
1637
- const args = buildArgs(agent, prompt, model, useStdin, bedrock);
1636
+ const useStdin2 = !!promptViaStdin;
1637
+ const args = buildArgs(agent, prompt, model, useStdin2, bedrock);
1638
1638
  const startedAt = Date.now();
1639
1639
  onDebugEvent?.("run.start", {
1640
1640
  agent,
@@ -1651,7 +1651,7 @@ async function runAgent(options) {
1651
1651
  stdio: ["pipe", "pipe", "pipe"],
1652
1652
  ...bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}
1653
1653
  });
1654
- if (useStdin && child.stdin) {
1654
+ if (useStdin2 && child.stdin) {
1655
1655
  child.stdin.on("error", () => {
1656
1656
  });
1657
1657
  child.stdin.write(prompt, () => {
@@ -3210,6 +3210,34 @@ function parseReviewReasons(raw) {
3210
3210
  return [];
3211
3211
  }
3212
3212
  }
3213
+ function loadScopeComponents(db, sessionId) {
3214
+ const rows = db.prepare(`SELECT name, component_id, status, reject_reason, review_reasons, needs_review FROM raw_components
3215
+ WHERE session_id = ? AND status IN ('extracted', 'accepted', 'rejected')
3216
+ ORDER BY name`).all(sessionId);
3217
+ if (rows.length === 0)
3218
+ return [];
3219
+ const slotRows = db.prepare(`SELECT component_id, name, position
3220
+ FROM raw_slots WHERE session_id = ? ORDER BY component_id, position`).all(sessionId);
3221
+ const allowedRows = db.prepare(`SELECT component_id, slot_name, position, allowed_component
3222
+ FROM raw_slot_allowed_components WHERE session_id = ? ORDER BY component_id, slot_name, position`).all(sessionId);
3223
+ const slotsByComponent = indexRowsByKey(slotRows, (s) => s.component_id);
3224
+ const allowedBySlot = indexRowsByKey(allowedRows, (a) => `${a.component_id}::${a.slot_name}`);
3225
+ return rows.map((r) => {
3226
+ const reviewReasons = parseReviewReasons(r.review_reasons);
3227
+ const nonAuthorableReason = reviewReasons.find((reason) => reason.startsWith("non-authorable:"));
3228
+ return {
3229
+ name: r.name,
3230
+ componentId: r.component_id,
3231
+ aiDecision: r.status === "accepted" ? "accepted" : r.status === "rejected" ? "rejected" : null,
3232
+ aiReason: r.reject_reason ?? nonAuthorableReason?.slice("non-authorable:".length) ?? null,
3233
+ needsReview: Boolean(r.needs_review),
3234
+ slots: (slotsByComponent.get(r.component_id) ?? []).map((s) => ({
3235
+ name: s.name,
3236
+ allowedComponents: (allowedBySlot.get(`${r.component_id}::${s.name}`) ?? []).map((a) => a.allowed_component)
3237
+ }))
3238
+ };
3239
+ });
3240
+ }
3213
3241
  async function getCliCacheVersion() {
3214
3242
  if (_cliCacheVersionCache)
3215
3243
  return _cliCacheVersionCache;
@@ -5232,9 +5260,9 @@ var init_utils_gen = __esm({
5232
5260
  let url = _url;
5233
5261
  const matches = _url.match(PATH_PARAM_RE);
5234
5262
  if (matches) {
5235
- for (const match of matches) {
5263
+ for (const match2 of matches) {
5236
5264
  let explode = false;
5237
- let name = match.substring(1, match.length - 1);
5265
+ let name = match2.substring(1, match2.length - 1);
5238
5266
  let style = "simple";
5239
5267
  if (name.endsWith("*")) {
5240
5268
  explode = true;
@@ -5252,11 +5280,11 @@ var init_utils_gen = __esm({
5252
5280
  continue;
5253
5281
  }
5254
5282
  if (Array.isArray(value)) {
5255
- url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
5283
+ url = url.replace(match2, serializeArrayParam({ explode, name, style, value }));
5256
5284
  continue;
5257
5285
  }
5258
5286
  if (typeof value === "object") {
5259
- url = url.replace(match, serializeObjectParam({
5287
+ url = url.replace(match2, serializeObjectParam({
5260
5288
  explode,
5261
5289
  name,
5262
5290
  style,
@@ -5266,19 +5294,19 @@ var init_utils_gen = __esm({
5266
5294
  continue;
5267
5295
  }
5268
5296
  if (style === "matrix") {
5269
- url = url.replace(match, `;${serializePrimitiveParam({
5297
+ url = url.replace(match2, `;${serializePrimitiveParam({
5270
5298
  name,
5271
5299
  value
5272
5300
  })}`);
5273
5301
  continue;
5274
5302
  }
5275
5303
  const replaceValue = encodeURIComponent(style === "label" ? `.${value}` : value);
5276
- url = url.replace(match, replaceValue);
5304
+ url = url.replace(match2, replaceValue);
5277
5305
  }
5278
5306
  }
5279
5307
  return url;
5280
5308
  };
5281
- createQuerySerializer = ({ allowReserved, array: array3, object: object2 } = {}) => {
5309
+ createQuerySerializer = ({ allowReserved, array: array4, object: object2 } = {}) => {
5282
5310
  const querySerializer = (queryParams) => {
5283
5311
  const search = [];
5284
5312
  if (queryParams && typeof queryParams === "object") {
@@ -5294,7 +5322,7 @@ var init_utils_gen = __esm({
5294
5322
  name,
5295
5323
  style: "form",
5296
5324
  value,
5297
- ...array3
5325
+ ...array4
5298
5326
  });
5299
5327
  if (serializedArray)
5300
5328
  search.push(serializedArray);
@@ -7705,12 +7733,12 @@ function findSession(stdout) {
7705
7733
  return null;
7706
7734
  }
7707
7735
  function parseExtractedCount(stderr) {
7708
- const match = EXTRACTED.exec(stderr);
7709
- return match ? Number(match[1]) : 0;
7736
+ const match2 = EXTRACTED.exec(stderr);
7737
+ return match2 ? Number(match2[1]) : 0;
7710
7738
  }
7711
7739
  function parsePrintTokensCount(stdout) {
7712
- const match = PRINT_TOKENS_COUNT.exec(stdout);
7713
- return match ? Number(match[1]) : 0;
7740
+ const match2 = PRINT_TOKENS_COUNT.exec(stdout);
7741
+ return match2 ? Number(match2[1]) : 0;
7714
7742
  }
7715
7743
  function initialProgress(input) {
7716
7744
  return {
@@ -8705,8 +8733,8 @@ async function runAgent2(options) {
8705
8733
  const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
8706
8734
  const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === "1";
8707
8735
  const binary = resolveAgentBinary(agent);
8708
- const useStdin = !!promptViaStdin;
8709
- const args = buildAgentArgs(agent, prompt, model, useStdin, bedrock);
8736
+ const useStdin2 = !!promptViaStdin;
8737
+ const args = buildAgentArgs(agent, prompt, model, useStdin2, bedrock);
8710
8738
  const startedAt = Date.now();
8711
8739
  onDebugEvent?.("run.start", {
8712
8740
  agent,
@@ -8723,7 +8751,7 @@ async function runAgent2(options) {
8723
8751
  stdio: ["pipe", "pipe", "pipe"],
8724
8752
  ...bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}
8725
8753
  });
8726
- if (useStdin && child.stdin) {
8754
+ if (useStdin2 && child.stdin) {
8727
8755
  child.stdin.on("error", () => {
8728
8756
  });
8729
8757
  child.stdin.write(prompt, () => {
@@ -9373,194 +9401,3259 @@ var init_use_extraction = __esm({
9373
9401
  }
9374
9402
  });
9375
9403
 
9376
- // packages/experience-design-system-types/dist/src/handoff/index.js
9377
- import * as z5 from "zod/mini";
9378
- function serializeHandoff(handoff) {
9379
- return JSON.stringify(handoff);
9380
- }
9381
- var HANDOFF_ENV, NonEmpty, TokensSchema, ExtractionSchema, ImportHandoffSchema;
9382
- var init_handoff = __esm({
9383
- "packages/experience-design-system-types/dist/src/handoff/index.js"() {
9404
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/theme.ts
9405
+ var PALETTE2;
9406
+ var init_theme2 = __esm({
9407
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/theme.ts"() {
9384
9408
  "use strict";
9385
- HANDOFF_ENV = "EDS_IMPORT_HANDOFF";
9386
- NonEmpty = z5.string().check(z5.minLength(1));
9387
- TokensSchema = z5.object({
9388
- /**
9389
- * What to do about an existing `tokens.json`.
9390
- * reuse: keep it. regenerate: build it again with the cache off. generate: nothing was asked, build it as usual.
9391
- */
9392
- strategy: z5.enum(["reuse", "regenerate", "generate"])
9393
- });
9394
- ExtractionSchema = z5.object({
9395
- sessionId: NonEmpty,
9396
- outDir: NonEmpty,
9397
- tokensPath: z5.string(),
9398
- tokenSessionId: z5.nullable(z5.string()),
9399
- tokenCount: z5.number(),
9400
- existingEntitiesPath: z5.nullable(z5.string()),
9401
- /** Never 'running': the wizard starts its background cache check only once this has settled. */
9402
- existingEntitiesStatus: z5.enum(["idle", "complete", "failed"]),
9403
- /** The only phases the scope gate can start from. */
9404
- compositionPhase: z5.enum(["done", "cache-hit"])
9405
- });
9406
- ImportHandoffSchema = z5.object({
9407
- /** The user skipped the credentials screen, so nothing is fetched from or pushed to Contentful. */
9408
- credentialsSkipped: z5.boolean(),
9409
- tokens: TokensSchema,
9410
- /** Present once the CLI has run the extraction stage; the wizard then starts at the scope gate. */
9411
- extraction: z5.optional(ExtractionSchema)
9412
- });
9409
+ init_home_theme();
9410
+ PALETTE2 = {
9411
+ info: PALETTE.accent,
9412
+ success: PALETTE.success,
9413
+ error: PALETTE.error,
9414
+ warning: PALETTE.warning,
9415
+ muted: PALETTE.muted,
9416
+ border: PALETTE.border
9417
+ };
9413
9418
  }
9414
9419
  });
9415
9420
 
9416
- // packages/experience-design-system-cli/src/tui/import/spawn-v1-import.ts
9417
- import { spawn as spawn9 } from "node:child_process";
9418
- function buildArgs2(options) {
9419
- const args = ["import"];
9420
- if (options.projectPath) {
9421
- args.push("--project", options.projectPath);
9421
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/columns.ts
9422
+ function computePanelLayout(mainVisibleCount) {
9423
+ const safeMainVisibleCount = Math.max(1, mainVisibleCount);
9424
+ const height = safeMainVisibleCount + PANEL_BORDER_ROWS + PANEL_INDICATOR_ROWS + PANEL_HEADER_ROWS;
9425
+ const sideVisibleCount = Math.max(1, height - PANEL_BORDER_ROWS - PANEL_INDICATOR_ROWS - PANEL_HEADER_ROWS);
9426
+ return { height, mainVisibleCount: safeMainVisibleCount, sideVisibleCount };
9427
+ }
9428
+ function computeColumnWidths(totalWidth) {
9429
+ if (totalWidth < TWO_COLUMN_MIN_WIDTH) {
9430
+ return { layout: "single", main: SCOPE_GATE_MAIN_COLUMN_WIDTH, added: 0 };
9431
+ }
9432
+ const main = SCOPE_GATE_MAIN_COLUMN_WIDTH;
9433
+ const added = ACCEPTED_COMPONENTS_COLUMN_WIDTH;
9434
+ return { layout: "two-column", main, added };
9435
+ }
9436
+ function sortTieredEntries(cycleTier, restTier) {
9437
+ cycleTier.sort((a, b) => a.name.localeCompare(b.name));
9438
+ restTier.sort((a, b) => a.name.localeCompare(b.name));
9439
+ return [...cycleTier, ...restTier];
9440
+ }
9441
+ function buildAddedComponentsList(components, stateByKey, cycleParticipants = /* @__PURE__ */ new Set()) {
9442
+ const cycleTier = [];
9443
+ const restTier = [];
9444
+ const seen = /* @__PURE__ */ new Set();
9445
+ for (const c2 of components) {
9446
+ if (stateByKey.get(c2.name) !== "accepted") continue;
9447
+ if (seen.has(c2.name)) continue;
9448
+ seen.add(c2.name);
9449
+ if (cycleParticipants.has(c2.name)) cycleTier.push({ name: c2.name, isCycle: true });
9450
+ else restTier.push({ name: c2.name, isCycle: false });
9451
+ }
9452
+ return sortTieredEntries(cycleTier, restTier);
9453
+ }
9454
+ function computeCounters(components, closures, stateByKey) {
9455
+ let accepted = 0;
9456
+ let rejected = 0;
9457
+ let undecided = 0;
9458
+ for (const c2 of components) {
9459
+ const s = stateByKey.get(c2.name) ?? "undecided";
9460
+ if (s === "accepted") accepted++;
9461
+ else if (s === "rejected") rejected++;
9462
+ else undecided++;
9463
+ }
9464
+ let groups = 0;
9465
+ for (const [root, closure] of closures.entries()) {
9466
+ if (closure.nodes.length <= 1) continue;
9467
+ if (stateByKey.get(root) === "accepted") groups++;
9468
+ }
9469
+ return { accepted, rejected, undecided, groups, total: components.length };
9470
+ }
9471
+ function sideColumnLabelStyle(input) {
9472
+ const { isCycle, isSelected, focused } = input;
9473
+ const isCursor = isSelected && focused;
9474
+ if (isCursor) {
9475
+ return {
9476
+ nameColor: PALETTE2.info,
9477
+ nameBold: true,
9478
+ nameInverse: false,
9479
+ nameUnderline: false,
9480
+ suffixColor: PALETTE2.info,
9481
+ suffixDim: false,
9482
+ suffixInverse: false,
9483
+ suffixUnderline: false
9484
+ };
9422
9485
  }
9423
- if (options.tokens) {
9424
- args.push("--tokens", options.tokens);
9486
+ const underline = isSelected && !focused;
9487
+ if (isCycle) {
9488
+ return {
9489
+ nameColor: PALETTE2.warning,
9490
+ nameBold: false,
9491
+ nameInverse: false,
9492
+ nameUnderline: underline,
9493
+ suffixColor: PALETTE2.warning,
9494
+ suffixDim: false,
9495
+ suffixInverse: false,
9496
+ suffixUnderline: underline
9497
+ };
9425
9498
  }
9426
- args.push(...importOptionArgs({ agent: options.agent, prompt: options.prompt ?? [], cache: options.cache ?? true }));
9427
- return args;
9499
+ return {
9500
+ nameColor: PALETTE2.success,
9501
+ nameBold: false,
9502
+ nameInverse: false,
9503
+ nameUnderline: underline,
9504
+ suffixColor: PALETTE2.info,
9505
+ suffixDim: true,
9506
+ suffixInverse: false,
9507
+ suffixUnderline: underline
9508
+ };
9428
9509
  }
9429
- function buildEnv(options, base = process.env) {
9430
- return { ...base, ...options.handoff ? { [HANDOFF_ENV]: serializeHandoff(options.handoff) } : {} };
9510
+ function computeColumnWindow(total, cursor, visibleCount) {
9511
+ if (total <= visibleCount) return { start: 0, end: total, above: 0, below: 0 };
9512
+ let start = Math.max(0, cursor - Math.floor(visibleCount / 2));
9513
+ start = Math.min(start, total - visibleCount);
9514
+ const end = start + visibleCount;
9515
+ return { start, end, above: start, below: total - end };
9516
+ }
9517
+ var TWO_COLUMN_MIN_WIDTH, SCOPE_GATE_MAIN_COLUMN_WIDTH, ACCEPTED_COMPONENTS_COLUMN_WIDTH, PANEL_BORDER_ROWS, PANEL_INDICATOR_ROWS, PANEL_HEADER_ROWS;
9518
+ var init_columns = __esm({
9519
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/columns.ts"() {
9520
+ "use strict";
9521
+ init_theme2();
9522
+ TWO_COLUMN_MIN_WIDTH = 100;
9523
+ SCOPE_GATE_MAIN_COLUMN_WIDTH = 54;
9524
+ ACCEPTED_COMPONENTS_COLUMN_WIDTH = 36;
9525
+ PANEL_BORDER_ROWS = 2;
9526
+ PANEL_INDICATOR_ROWS = 2;
9527
+ PANEL_HEADER_ROWS = 2;
9528
+ }
9529
+ });
9530
+
9531
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/windowed-panel.tsx
9532
+ import { Box as Box10, Text as Text11 } from "ink";
9533
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
9534
+ function terminalPanelHeight(rows, reservedRows = 4) {
9535
+ return Math.max(MIN_TERMINAL_PANEL_HEIGHT, rows - reservedRows);
9536
+ }
9537
+ function FixedPanel({
9538
+ width,
9539
+ height,
9540
+ minHeight,
9541
+ focused = false,
9542
+ borderStyle,
9543
+ borderColor,
9544
+ paddingLeft,
9545
+ clipOverflow = true,
9546
+ children
9547
+ }) {
9548
+ return /* @__PURE__ */ jsx13(
9549
+ Box10,
9550
+ {
9551
+ flexDirection: "column",
9552
+ width,
9553
+ ...height === void 0 ? {} : { height },
9554
+ ...minHeight === void 0 ? {} : { minHeight },
9555
+ ...height === void 0 || !clipOverflow ? {} : { overflowY: "hidden" },
9556
+ flexShrink: 0,
9557
+ borderStyle,
9558
+ borderColor: focused ? borderColor ?? "white" : borderColor,
9559
+ paddingLeft,
9560
+ children
9561
+ }
9562
+ );
9431
9563
  }
9432
- async function spawnV1Import(options = {}) {
9433
- const cliPath = findLegacyCliPath();
9434
- const args = buildArgs2(options);
9435
- return new Promise((resolvePromise) => {
9436
- const child = spawn9("node", [cliPath, ...args], {
9437
- stdio: "inherit",
9438
- env: buildEnv(options)
9439
- });
9440
- child.on("close", (code) => {
9441
- resolvePromise({ exitCode: code ?? 1, result: void 0, stdout: "", stderr: "" });
9442
- });
9443
- child.on("error", (err) => {
9444
- resolvePromise({ exitCode: 1, result: void 0, stdout: "", stderr: err.message });
9445
- });
9446
- });
9564
+ function WindowedPanel({ width, height, title, focused, children }) {
9565
+ return /* @__PURE__ */ jsxs10(
9566
+ FixedPanel,
9567
+ {
9568
+ width,
9569
+ borderStyle: "single",
9570
+ borderColor: focused ? "white" : void 0,
9571
+ ...height === void 0 ? {} : { height },
9572
+ focused,
9573
+ children: [
9574
+ title && /* @__PURE__ */ jsx13(WindowedPanelHeader, { title, width, focused }),
9575
+ children
9576
+ ]
9577
+ }
9578
+ );
9447
9579
  }
9448
- var init_spawn_v1_import = __esm({
9449
- "packages/experience-design-system-cli/src/tui/import/spawn-v1-import.ts"() {
9580
+ function WindowedPanelHeader({
9581
+ title,
9582
+ width,
9583
+ focused
9584
+ }) {
9585
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
9586
+ /* @__PURE__ */ jsx13(Text11, { bold: true, color: PALETTE2.info, inverse: focused, children: title }),
9587
+ /* @__PURE__ */ jsx13(Text11, { dimColor: true, children: "\u2500".repeat(Math.max(0, width - 2)) })
9588
+ ] });
9589
+ }
9590
+ function formatWindowIndicator(direction, count) {
9591
+ if (count <= 0) return " ";
9592
+ return `${direction === "up" ? "\u2191" : "\u2193"} ${count} more`;
9593
+ }
9594
+ function WindowIndicator({ direction, count }) {
9595
+ return /* @__PURE__ */ jsx13(Text11, { color: PALETTE2.muted, children: formatWindowIndicator(direction, count) });
9596
+ }
9597
+ var MIN_TERMINAL_PANEL_HEIGHT;
9598
+ var init_windowed_panel = __esm({
9599
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/windowed-panel.tsx"() {
9450
9600
  "use strict";
9451
- init_legacy_cli_path();
9452
- init_import_options();
9453
- init_handoff();
9601
+ init_theme2();
9602
+ MIN_TERMINAL_PANEL_HEIGHT = 5;
9454
9603
  }
9455
9604
  });
9456
9605
 
9457
- // packages/experience-design-system-cli/src/tui/import/terminal-input.ts
9458
- function getTerminalHandle() {
9459
- return process.stdin._handle;
9606
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/added-column.tsx
9607
+ import React6 from "react";
9608
+ import { Box as Box11, Text as Text12 } from "ink";
9609
+ import figures from "figures";
9610
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
9611
+ function AddedColumn(props) {
9612
+ const { title, width, height, entries, cursor, focused, aiFlaggedByKey, visibleCount } = props;
9613
+ const reserveAiBadge = entries.some((e) => aiFlaggedByKey?.get(e.name) === true);
9614
+ const firstNonCycleIdx = entries.findIndex((e) => !e.isCycle);
9615
+ const window = computeColumnWindow(entries.length, cursor, Math.max(1, visibleCount));
9616
+ return /* @__PURE__ */ jsxs11(WindowedPanel, { width, height, title, focused, children: [
9617
+ /* @__PURE__ */ jsx14(WindowIndicator, { direction: "up", count: window.above }),
9618
+ entries.length === 0 ? /* @__PURE__ */ jsx14(Text12, { color: PALETTE2.muted, children: "(none)" }) : entries.slice(window.start, window.end).map((entry, vi) => {
9619
+ const i = window.start + vi;
9620
+ const isSelected = i === cursor;
9621
+ const isCursor = focused && isSelected;
9622
+ const aiFlagged = aiFlaggedByKey?.get(entry.name) === true;
9623
+ const showSeparator = firstNonCycleIdx > 0 && i === firstNonCycleIdx;
9624
+ const style = sideColumnLabelStyle({ isCycle: entry.isCycle, isSelected, focused });
9625
+ return /* @__PURE__ */ jsxs11(React6.Fragment, { children: [
9626
+ showSeparator && /* @__PURE__ */ jsx14(Text12, { dimColor: true, children: "\u2500".repeat(Math.max(0, width - 2)) }),
9627
+ /* @__PURE__ */ jsxs11(Box11, { children: [
9628
+ isCursor ? /* @__PURE__ */ jsx14(Text12, { color: PALETTE2.info, bold: true, children: figures.pointer }) : /* @__PURE__ */ jsx14(Text12, { children: " " }),
9629
+ reserveAiBadge && (aiFlagged ? /* @__PURE__ */ jsx14(Text12, { color: PALETTE2.warning, bold: true, children: " [\xD7]" }) : /* @__PURE__ */ jsx14(Text12, { children: " " })),
9630
+ entry.isCycle && /* @__PURE__ */ jsx14(Text12, { color: isCursor ? PALETTE2.info : PALETTE2.warning, bold: true, underline: style.nameUnderline, children: " \u26A0" }),
9631
+ /* @__PURE__ */ jsx14(
9632
+ Text12,
9633
+ {
9634
+ color: style.nameColor,
9635
+ bold: style.nameBold,
9636
+ inverse: style.nameInverse,
9637
+ underline: style.nameUnderline,
9638
+ wrap: "wrap",
9639
+ children: " " + entry.name
9640
+ }
9641
+ )
9642
+ ] })
9643
+ ] }, entry.name);
9644
+ }),
9645
+ /* @__PURE__ */ jsx14(WindowIndicator, { direction: "down", count: window.below })
9646
+ ] });
9460
9647
  }
9461
- async function stopReadingTerminal() {
9462
- await new Promise((resolve10) => setImmediate(resolve10));
9463
- const handle = getTerminalHandle();
9464
- if (!handle?.readStop) return;
9465
- handle.reading = false;
9466
- handle.readStop();
9648
+ var init_added_column = __esm({
9649
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/added-column.tsx"() {
9650
+ "use strict";
9651
+ init_columns();
9652
+ init_theme2();
9653
+ init_windowed_panel();
9654
+ }
9655
+ });
9656
+
9657
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/cycles-panel.tsx
9658
+ import { Box as Box12, Text as Text13 } from "ink";
9659
+ import figures2 from "figures";
9660
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
9661
+ function cycleLabel(cycle, index) {
9662
+ const parts = [];
9663
+ for (let i = 0; i < cycle.edges.length; i++) {
9664
+ parts.push(cycle.path[i]);
9665
+ parts.push(`[${cycle.edges[i].slotName}]`);
9666
+ }
9667
+ parts.push(cycle.path[cycle.path.length - 1]);
9668
+ return `Cycle ${index + 1}: ${parts.join(" \u2192 ")}`;
9467
9669
  }
9468
- function startReadingTerminal() {
9469
- const handle = getTerminalHandle();
9470
- if (!handle?.readStart) return;
9471
- handle.reading = true;
9472
- handle.readStart();
9670
+ function CyclesPanel({ cycles, cursor }) {
9671
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "single", borderColor: PALETTE2.warning, paddingX: 1, marginTop: 1, children: [
9672
+ /* @__PURE__ */ jsx15(Text13, { bold: true, color: PALETTE2.warning, children: `Cycles detected (${cycles.length}):` }),
9673
+ /* @__PURE__ */ jsx15(Text13, { children: " " }),
9674
+ cycles.map((cycle, i) => {
9675
+ const isCursor = i === cursor;
9676
+ return /* @__PURE__ */ jsxs12(Text13, { children: [
9677
+ isCursor ? /* @__PURE__ */ jsx15(Text13, { color: PALETTE2.info, bold: true, children: figures2.pointer }) : /* @__PURE__ */ jsx15(Text13, { children: " " }),
9678
+ /* @__PURE__ */ jsx15(Text13, { color: PALETTE2.warning, inverse: isCursor, children: " " + cycleLabel(cycle, i) })
9679
+ ] }, i);
9680
+ }),
9681
+ /* @__PURE__ */ jsx15(Text13, { children: "[\u2191/\u2193] move \xB7 [Enter] jump \xB7 [c/Esc] close" })
9682
+ ] });
9473
9683
  }
9474
- var init_terminal_input = __esm({
9475
- "packages/experience-design-system-cli/src/tui/import/terminal-input.ts"() {
9684
+ var init_cycles_panel = __esm({
9685
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/cycles-panel.tsx"() {
9476
9686
  "use strict";
9687
+ init_theme2();
9477
9688
  }
9478
9689
  });
9479
9690
 
9480
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
9481
- async function readDebugModeSetting() {
9482
- const { debugMode } = await readSettings2();
9483
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
9691
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/reject-prompt.tsx
9692
+ import { Box as Box13, Text as Text14 } from "ink";
9693
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
9694
+ function RejectPrompt({ pending }) {
9695
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "single", borderColor: PALETTE2.warning, paddingX: 1, marginTop: 1, children: [
9696
+ /* @__PURE__ */ jsx16(Text14, { bold: true, color: PALETTE2.warning, children: `Rejecting ${pending.target} will:` }),
9697
+ pending.ancestors.length > 0 && /* @__PURE__ */ jsx16(Text14, { children: `- Reject ancestors: ${pending.ancestors.join(", ")}` }),
9698
+ pending.descendants.length > 0 && /* @__PURE__ */ jsx16(Text14, { children: `- Deselect descendants: ${pending.descendants.join(", ")}` }),
9699
+ /* @__PURE__ */ jsx16(Text14, { children: "[y] confirm \xB7 [n]/[Esc] cancel" })
9700
+ ] });
9484
9701
  }
9485
- async function writeDebugModeSetting(setting) {
9486
- await updateSettings2({ debugMode: setting });
9702
+ var init_reject_prompt = __esm({
9703
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/reject-prompt.tsx"() {
9704
+ "use strict";
9705
+ init_theme2();
9706
+ }
9707
+ });
9708
+
9709
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/LegendEntry.tsx
9710
+ import { Text as Text15 } from "ink";
9711
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
9712
+ function legendEntry(keyBracket, label, active = false) {
9713
+ return /* @__PURE__ */ jsxs14(Text15, { children: [
9714
+ /* @__PURE__ */ jsx17(Text15, { color: active ? PALETTE2.warning : PALETTE2.info, inverse: active, children: keyBracket }),
9715
+ /* @__PURE__ */ jsx17(Text15, { color: active ? PALETTE2.warning : void 0, inverse: active, children: " " + label })
9716
+ ] }, keyBracket + label);
9717
+ }
9718
+ var init_LegendEntry = __esm({
9719
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/LegendEntry.tsx"() {
9720
+ "use strict";
9721
+ init_theme2();
9722
+ }
9723
+ });
9724
+
9725
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/CompactControlBar.tsx
9726
+ import { Box as Box14 } from "ink";
9727
+ import { jsxs as jsxs15 } from "react/jsx-runtime";
9728
+ function CompactControlBar({ hasGroupRoots, searchActive }) {
9729
+ return /* @__PURE__ */ jsxs15(Box14, { borderStyle: "single", borderColor: PALETTE2.border, paddingX: 1, flexWrap: "wrap", columnGap: 2, children: [
9730
+ legendEntry("[\u2191/\u2193]", "move"),
9731
+ legendEntry("[a/r]", "accept/reject"),
9732
+ legendEntry("[f]", "continue/finalize"),
9733
+ hasGroupRoots && legendEntry("[space/E/C]", "expand/collapse"),
9734
+ legendEntry("[/]", "search", searchActive),
9735
+ legendEntry("[h]", "help"),
9736
+ legendEntry("[q]", "quit")
9737
+ ] });
9487
9738
  }
9488
- var DEFAULT_DEBUG_MODE_SETTING;
9489
- var init_debug_mode_store = __esm({
9490
- "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
9739
+ var init_CompactControlBar = __esm({
9740
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/CompactControlBar.tsx"() {
9491
9741
  "use strict";
9492
- init_config();
9493
- DEFAULT_DEBUG_MODE_SETTING = {
9494
- enabled: true
9495
- };
9742
+ init_theme2();
9743
+ init_LegendEntry();
9496
9744
  }
9497
9745
  });
9498
9746
 
9499
- // packages/experience-design-system-cli/src/tui/debug-store.ts
9500
- import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
9501
- import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
9502
- import { join as join13 } from "node:path";
9503
- function generateRunId() {
9504
- const now = /* @__PURE__ */ new Date();
9505
- const pad = (n) => String(n).padStart(2, "0");
9506
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
9747
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/CounterStrip.tsx
9748
+ import { Box as Box15, Text as Text16 } from "ink";
9749
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
9750
+ function CounterStrip(props) {
9751
+ const { counters, totalWidth } = props;
9752
+ const condensed = totalWidth < 60;
9753
+ const labelGrp = condensed ? "Cmp" : "Components with Slots";
9754
+ const labelRej = condensed ? "Rej" : "Rejected";
9755
+ const labelUnd = condensed ? "Und" : "Undecided";
9756
+ const sep = condensed ? " | " : " ";
9757
+ return /* @__PURE__ */ jsx18(Box15, { children: /* @__PURE__ */ jsxs16(Text16, { children: [
9758
+ /* @__PURE__ */ jsxs16(Text16, { color: PALETTE2.muted, children: [
9759
+ labelGrp,
9760
+ " "
9761
+ ] }),
9762
+ /* @__PURE__ */ jsx18(Text16, { bold: true, children: counters.groups }),
9763
+ /* @__PURE__ */ jsx18(Text16, { color: PALETTE2.muted, children: sep }),
9764
+ /* @__PURE__ */ jsxs16(Text16, { color: PALETTE2.muted, children: [
9765
+ labelRej,
9766
+ " "
9767
+ ] }),
9768
+ /* @__PURE__ */ jsx18(Text16, { bold: true, children: counters.rejected }),
9769
+ /* @__PURE__ */ jsx18(Text16, { color: PALETTE2.muted, children: sep }),
9770
+ /* @__PURE__ */ jsxs16(Text16, { color: PALETTE2.muted, children: [
9771
+ labelUnd,
9772
+ " "
9773
+ ] }),
9774
+ /* @__PURE__ */ jsx18(Text16, { bold: true, children: counters.undecided }),
9775
+ /* @__PURE__ */ jsx18(Text16, { color: PALETTE2.muted, children: sep })
9776
+ ] }) });
9507
9777
  }
9508
- function datePrefix(now = /* @__PURE__ */ new Date()) {
9509
- const pad = (n) => String(n).padStart(2, "0");
9510
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
9778
+ var init_CounterStrip = __esm({
9779
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/CounterStrip.tsx"() {
9780
+ "use strict";
9781
+ init_theme2();
9782
+ }
9783
+ });
9784
+
9785
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/GotoBanner.tsx
9786
+ import figures3 from "figures";
9787
+ import { Box as Box16, Text as Text17 } from "ink";
9788
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
9789
+ function windowStart(rowCount, highlightIndex, maxRows) {
9790
+ if (rowCount <= maxRows) return 0;
9791
+ const maxStart = rowCount - maxRows;
9792
+ let start = highlightIndex - Math.floor(maxRows / 2);
9793
+ if (start < 0) start = 0;
9794
+ if (start > maxStart) start = maxStart;
9795
+ return start;
9511
9796
  }
9512
- function slugify(value) {
9513
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
9797
+ function defaultRenderRow(row, index, isCursor) {
9798
+ return /* @__PURE__ */ jsxs17(Text17, { children: [
9799
+ isCursor ? /* @__PURE__ */ jsx19(Text17, { color: PALETTE2.info, bold: true, children: figures3.pointer }) : /* @__PURE__ */ jsx19(Text17, { children: " " }),
9800
+ /* @__PURE__ */ jsx19(Text17, { inverse: isCursor, children: " " + row.label })
9801
+ ] }, index);
9514
9802
  }
9515
- function generateSessionId3() {
9516
- const today = datePrefix();
9517
- const root = debugSessionsDir2();
9518
- const existing = existsSync6(root) ? readdirSync2(root) : [];
9519
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
9520
- const maxSeq = existing.reduce((max, entry) => {
9521
- const match = seqPattern.exec(entry);
9522
- return match ? Math.max(max, Number(match[1])) : max;
9523
- }, 0);
9524
- return `${today}-session-${maxSeq + 1}`;
9803
+ function GotoBanner({
9804
+ title,
9805
+ rows,
9806
+ cursor,
9807
+ cursorRowIndex,
9808
+ maxRows = DEFAULT_MAX_ROWS,
9809
+ width,
9810
+ footerHint,
9811
+ renderRow = defaultRenderRow
9812
+ }) {
9813
+ const highlightIndex = cursorRowIndex ?? cursor;
9814
+ const start = windowStart(rows.length, highlightIndex, maxRows);
9815
+ const end = Math.min(rows.length, start + maxRows);
9816
+ const visible = rows.slice(start, end);
9817
+ const moreAbove = start;
9818
+ const moreBelow = rows.length - end;
9819
+ return /* @__PURE__ */ jsxs17(
9820
+ Box16,
9821
+ {
9822
+ flexDirection: "column",
9823
+ borderStyle: "single",
9824
+ borderColor: PALETTE2.info,
9825
+ paddingX: 1,
9826
+ marginTop: width === void 0 ? 1 : 0,
9827
+ width,
9828
+ flexShrink: 0,
9829
+ children: [
9830
+ /* @__PURE__ */ jsx19(Text17, { bold: true, children: title }),
9831
+ moreAbove > 0 && /* @__PURE__ */ jsx19(Text17, { color: PALETTE2.muted, children: ` \u25B2 ${moreAbove} more` }),
9832
+ visible.map((row, vi) => {
9833
+ const i = start + vi;
9834
+ return renderRow(row, i, i === highlightIndex);
9835
+ }),
9836
+ moreBelow > 0 && /* @__PURE__ */ jsx19(Text17, { color: PALETTE2.muted, children: ` \u25BC ${moreBelow} more` }),
9837
+ footerHint !== void 0 && /* @__PURE__ */ jsx19(Text17, { color: PALETTE2.muted, children: footerHint })
9838
+ ]
9839
+ }
9840
+ );
9525
9841
  }
9526
- function sessionDebugDir() {
9527
- return join13(debugSessionsDir2(), SESSION_ID);
9842
+ var DEFAULT_MAX_ROWS;
9843
+ var init_GotoBanner = __esm({
9844
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/GotoBanner.tsx"() {
9845
+ "use strict";
9846
+ init_theme2();
9847
+ DEFAULT_MAX_ROWS = 15;
9848
+ }
9849
+ });
9850
+
9851
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/cycle-detection.ts
9852
+ function buildGraph(components) {
9853
+ const nodes = [];
9854
+ const seen = /* @__PURE__ */ new Set();
9855
+ for (const c2 of components) {
9856
+ if (seen.has(c2.name)) continue;
9857
+ seen.add(c2.name);
9858
+ nodes.push(c2.name);
9859
+ }
9860
+ const adjacency = /* @__PURE__ */ new Map();
9861
+ for (const node of nodes) adjacency.set(node, []);
9862
+ for (const comp of components) {
9863
+ const outgoing = adjacency.get(comp.name);
9864
+ if (!outgoing) continue;
9865
+ for (const slot of comp.slots) {
9866
+ const allowed = slot.allowedComponents ?? [];
9867
+ for (const target of allowed) {
9868
+ if (!seen.has(target)) continue;
9869
+ outgoing.push({ target, slotName: slot.name });
9870
+ }
9871
+ }
9872
+ }
9873
+ return { nodes, adjacency };
9874
+ }
9875
+ function stronglyConnectedComponents2(nodes, adjacency) {
9876
+ const index = /* @__PURE__ */ new Map();
9877
+ const lowlink = /* @__PURE__ */ new Map();
9878
+ const onStack = /* @__PURE__ */ new Set();
9879
+ const stack = [];
9880
+ const sccs = [];
9881
+ let counter = 0;
9882
+ const nodeSet = new Set(nodes);
9883
+ function strongconnect(v) {
9884
+ index.set(v, counter);
9885
+ lowlink.set(v, counter);
9886
+ counter += 1;
9887
+ stack.push(v);
9888
+ onStack.add(v);
9889
+ const neighbours = adjacency.get(v) ?? [];
9890
+ for (const { target } of neighbours) {
9891
+ if (!nodeSet.has(target)) continue;
9892
+ if (!index.has(target)) {
9893
+ strongconnect(target);
9894
+ lowlink.set(v, Math.min(lowlink.get(v), lowlink.get(target)));
9895
+ } else if (onStack.has(target)) {
9896
+ lowlink.set(v, Math.min(lowlink.get(v), index.get(target)));
9897
+ }
9898
+ }
9899
+ if (lowlink.get(v) === index.get(v)) {
9900
+ const scc = [];
9901
+ let w;
9902
+ do {
9903
+ w = stack.pop();
9904
+ onStack.delete(w);
9905
+ scc.push(w);
9906
+ } while (w !== v);
9907
+ sccs.push(scc);
9908
+ }
9909
+ }
9910
+ for (const node of nodes) {
9911
+ if (!index.has(node)) strongconnect(node);
9912
+ }
9913
+ return sccs;
9914
+ }
9915
+ function makeCycle(path5, edges) {
9916
+ return { path: [...path5, path5[0]], edges: [...edges] };
9917
+ }
9918
+ function findSlotCycles3(components) {
9919
+ if (components.length === 0) return [];
9920
+ const { nodes, adjacency } = buildGraph(components);
9921
+ if (nodes.length === 0) return [];
9922
+ const cycles = [];
9923
+ for (const node of nodes) {
9924
+ const outgoing = adjacency.get(node) ?? [];
9925
+ for (const edge of outgoing) {
9926
+ if (edge.target === node) {
9927
+ cycles.push({
9928
+ path: [node, node],
9929
+ edges: [{ fromComponent: node, slotName: edge.slotName, toComponent: node }]
9930
+ });
9931
+ }
9932
+ }
9933
+ }
9934
+ const nodeOrder = [...nodes].sort();
9935
+ let remaining = [...nodeOrder];
9936
+ while (remaining.length > 0) {
9937
+ let unblock2 = function(u) {
9938
+ blocked.delete(u);
9939
+ const dependents = blockedMap.get(u);
9940
+ if (!dependents) return;
9941
+ for (const w of dependents) {
9942
+ if (blocked.has(w)) unblock2(w);
9943
+ }
9944
+ dependents.clear();
9945
+ }, circuit2 = function(v, root) {
9946
+ let foundCycle = false;
9947
+ pathStack.push(v);
9948
+ blocked.add(v);
9949
+ const outgoing = adjacency.get(v) ?? [];
9950
+ for (const { target: w, slotName } of outgoing) {
9951
+ if (!sccSet.has(w)) continue;
9952
+ edgeStack.push({ fromComponent: v, slotName, toComponent: w });
9953
+ if (w === root) {
9954
+ cycles.push(makeCycle(pathStack, edgeStack));
9955
+ foundCycle = true;
9956
+ } else if (!blocked.has(w)) {
9957
+ if (circuit2(w, root)) foundCycle = true;
9958
+ }
9959
+ edgeStack.pop();
9960
+ }
9961
+ if (foundCycle) {
9962
+ unblock2(v);
9963
+ } else {
9964
+ for (const { target: w } of outgoing) {
9965
+ if (!sccSet.has(w)) continue;
9966
+ let deps = blockedMap.get(w);
9967
+ if (!deps) {
9968
+ deps = /* @__PURE__ */ new Set();
9969
+ blockedMap.set(w, deps);
9970
+ }
9971
+ deps.add(v);
9972
+ }
9973
+ }
9974
+ pathStack.pop();
9975
+ return foundCycle;
9976
+ };
9977
+ var unblock = unblock2, circuit = circuit2;
9978
+ const subgraphNodes = remaining;
9979
+ const sccs = stronglyConnectedComponents2(subgraphNodes, adjacency).filter((scc) => {
9980
+ if (scc.length > 1) return true;
9981
+ return false;
9982
+ });
9983
+ if (sccs.length === 0) break;
9984
+ let startNode = null;
9985
+ let startScc = null;
9986
+ for (const scc of sccs) {
9987
+ const min = [...scc].sort()[0];
9988
+ if (startNode === null || min < startNode) {
9989
+ startNode = min;
9990
+ startScc = scc;
9991
+ }
9992
+ }
9993
+ if (startNode === null || startScc === null) break;
9994
+ const sccSet = new Set(startScc);
9995
+ const blocked = /* @__PURE__ */ new Set();
9996
+ const blockedMap = /* @__PURE__ */ new Map();
9997
+ const pathStack = [];
9998
+ const edgeStack = [];
9999
+ circuit2(startNode, startNode);
10000
+ remaining = remaining.filter((n) => n !== startNode);
10001
+ }
10002
+ return cycles;
9528
10003
  }
9529
- function currentDebugSessionDir() {
9530
- return sessionDebugDir();
10004
+ var init_cycle_detection = __esm({
10005
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/cycle-detection.ts"() {
10006
+ "use strict";
10007
+ }
10008
+ });
10009
+
10010
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/composite-closure.ts
10011
+ function edgesFrom(component, known) {
10012
+ if (!component) return [];
10013
+ const out = [];
10014
+ const seen = /* @__PURE__ */ new Set();
10015
+ for (const slot of component.slots) {
10016
+ for (const target of slot.allowedComponents ?? []) {
10017
+ if (!known.has(target)) continue;
10018
+ if (seen.has(target)) continue;
10019
+ seen.add(target);
10020
+ out.push(target);
10021
+ }
10022
+ }
10023
+ return out.sort();
9531
10024
  }
9532
- async function isDebugModeEnabled() {
9533
- try {
9534
- return (await readDebugModeSetting()).enabled;
9535
- } catch {
9536
- return true;
10025
+ function collectDependents(components) {
10026
+ const known = new Set(components.map((c2) => c2.name));
10027
+ const dependents = /* @__PURE__ */ new Set();
10028
+ for (const c2 of components) {
10029
+ for (const slot of c2.slots) {
10030
+ for (const target of slot.allowedComponents ?? []) {
10031
+ if (known.has(target) && target !== c2.name) dependents.add(target);
10032
+ }
10033
+ }
10034
+ }
10035
+ return dependents;
10036
+ }
10037
+ function findRoots(components, selected) {
10038
+ const scope = selected ? components.filter((c2) => selected.has(c2.name)) : components;
10039
+ const dependents = collectDependents(scope);
10040
+ return scope.map((c2) => c2.name).filter((name) => !dependents.has(name)).sort();
10041
+ }
10042
+ function findCycleInClosure(root, reachable, components) {
10043
+ const scopedComponents = components.filter((c2) => reachable.has(c2.name)).map((c2) => ({ name: c2.name, slots: c2.slots }));
10044
+ const cycles = findSlotCycles3(scopedComponents);
10045
+ if (cycles.length === 0) return null;
10046
+ const involvesRoot = cycles.find((cycle) => cycle.path.includes(root));
10047
+ const picked = involvesRoot ?? cycles[0];
10048
+ return picked.path;
10049
+ }
10050
+ function walkReachable2(root, byName, known) {
10051
+ const reachable = /* @__PURE__ */ new Set();
10052
+ const stack = [root];
10053
+ while (stack.length > 0) {
10054
+ const cur = stack.pop();
10055
+ if (reachable.has(cur)) continue;
10056
+ reachable.add(cur);
10057
+ for (const next of edgesFrom(byName.get(cur), known)) {
10058
+ if (!reachable.has(next)) stack.push(next);
10059
+ }
9537
10060
  }
10061
+ return reachable;
9538
10062
  }
9539
- function redact(value) {
9540
- const clone = { ...value };
9541
- if ("cma_token" in clone) {
9542
- const raw = clone.cma_token;
9543
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
10063
+ function computeClosure(root, components) {
10064
+ const known = new Set(components.map((c2) => c2.name));
10065
+ const byName = new Map(components.map((c2) => [c2.name, c2]));
10066
+ if (!known.has(root)) {
10067
+ return {
10068
+ root,
10069
+ nodes: [{ name: root, depth: 0, path: [root], parents: [] }],
10070
+ containsCycle: false
10071
+ };
9544
10072
  }
9545
- return clone;
10073
+ const reachable = walkReachable2(root, byName, known);
10074
+ const cyclePath = findCycleInClosure(root, reachable, components);
10075
+ if (cyclePath) {
10076
+ const nodes2 = [...reachable].sort().map((name) => ({
10077
+ name,
10078
+ depth: name === root ? 0 : 1,
10079
+ path: [root],
10080
+ parents: []
10081
+ }));
10082
+ return { root, nodes: nodes2, containsCycle: true, cyclePath };
10083
+ }
10084
+ const depth = /* @__PURE__ */ new Map();
10085
+ const parentPath = /* @__PURE__ */ new Map();
10086
+ const parents = /* @__PURE__ */ new Map();
10087
+ depth.set(root, 0);
10088
+ parentPath.set(root, [root]);
10089
+ parents.set(root, /* @__PURE__ */ new Set());
10090
+ const queue = [root];
10091
+ while (queue.length > 0) {
10092
+ const cur = queue.shift();
10093
+ const curDepth = depth.get(cur);
10094
+ const curPath = parentPath.get(cur);
10095
+ for (const next of edgesFrom(byName.get(cur), known)) {
10096
+ if (!parents.has(next)) parents.set(next, /* @__PURE__ */ new Set());
10097
+ parents.get(next).add(cur);
10098
+ const nextDepth = curDepth + 1;
10099
+ const existingDepth = depth.get(next);
10100
+ const nextPath = [...curPath, next];
10101
+ if (existingDepth === void 0 || nextDepth < existingDepth) {
10102
+ depth.set(next, nextDepth);
10103
+ parentPath.set(next, nextPath);
10104
+ queue.push(next);
10105
+ } else if (nextDepth === existingDepth) {
10106
+ const existingPath = parentPath.get(next);
10107
+ if (nextPath.join("\0") < existingPath.join("\0")) {
10108
+ parentPath.set(next, nextPath);
10109
+ }
10110
+ }
10111
+ }
10112
+ }
10113
+ const nodes = [];
10114
+ for (const [name, d] of depth.entries()) {
10115
+ nodes.push({
10116
+ name,
10117
+ depth: d,
10118
+ path: parentPath.get(name),
10119
+ parents: [...parents.get(name) ?? /* @__PURE__ */ new Set()].sort()
10120
+ });
10121
+ }
10122
+ nodes.sort((a, b) => a.depth - b.depth || a.name.localeCompare(b.name));
10123
+ return { root, nodes, containsCycle: false };
9546
10124
  }
9547
- function startDebugRun({
9548
- flow,
9549
- step,
9550
- menuOption,
9551
- inputs
9552
- }) {
9553
- const runId = generateRunId();
9554
- const startedAt = Date.now();
9555
- const redactedInputs = redact(inputs);
9556
- isDebugModeEnabled().then((enabled) => {
9557
- if (!enabled) return;
9558
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
9559
- });
10125
+ function computeAllClosures(components, selected) {
10126
+ const roots = findRoots(components, selected);
10127
+ const scope = selected ? components.filter((c2) => selected.has(c2.name)) : components;
10128
+ const out = /* @__PURE__ */ new Map();
10129
+ for (const root of roots) out.set(root, computeClosure(root, scope));
10130
+ return out;
9560
10131
  }
9561
- async function finishDebugRun({
9562
- outputs,
9563
- status,
10132
+ function findSharedDeps(closures) {
10133
+ const counts = /* @__PURE__ */ new Map();
10134
+ for (const [root, closure] of closures.entries()) {
10135
+ for (const node of closure.nodes) {
10136
+ if (node.name === root) continue;
10137
+ if (!counts.has(node.name)) counts.set(node.name, []);
10138
+ counts.get(node.name).push(root);
10139
+ }
10140
+ }
10141
+ const out = /* @__PURE__ */ new Map();
10142
+ for (const [name, roots] of counts.entries()) {
10143
+ if (roots.length >= 2) out.set(name, [...roots].sort());
10144
+ }
10145
+ return out;
10146
+ }
10147
+ var init_composite_closure = __esm({
10148
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/composite-closure.ts"() {
10149
+ "use strict";
10150
+ init_cycle_detection();
10151
+ }
10152
+ });
10153
+
10154
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/badge.tsx
10155
+ import { Text as Text18 } from "ink";
10156
+ import { jsx as jsx20 } from "react/jsx-runtime";
10157
+ function previewBadge(annotation) {
10158
+ switch (annotation) {
10159
+ case "new":
10160
+ return { char: "+", color: PALETTE2.success };
10161
+ case "changed":
10162
+ return { char: "~", color: PALETTE2.warning };
10163
+ case "removed":
10164
+ return { char: "-", color: PALETTE2.error, dim: true };
10165
+ case "breaking":
10166
+ return { char: "!", color: PALETTE2.error, bold: true };
10167
+ default:
10168
+ return null;
10169
+ }
10170
+ }
10171
+ function PreviewBadge({
10172
+ badge,
10173
+ highlighted = false
10174
+ }) {
10175
+ return badge ? /* @__PURE__ */ jsx20(Text18, { color: !highlighted && badge.dim ? PALETTE2.muted : badge.color, bold: badge.bold, children: badge.char }) : /* @__PURE__ */ jsx20(Text18, { children: " " });
10176
+ }
10177
+ var init_badge = __esm({
10178
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/badge.tsx"() {
10179
+ "use strict";
10180
+ init_theme2();
10181
+ }
10182
+ });
10183
+
10184
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/GroupedSidebar.tsx
10185
+ import figures4 from "figures";
10186
+ import { Box as Box17, Text as Text19 } from "ink";
10187
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
10188
+ function isEmpty(entry) {
10189
+ return Object.keys(entry.$properties ?? {}).length === 0 && Object.keys(entry.$slots ?? {}).length === 0;
10190
+ }
10191
+ function allowedComponentNames(entry) {
10192
+ const names = [];
10193
+ for (const slot of Object.values(entry.$slots ?? {})) {
10194
+ if (!Array.isArray(slot?.$allowedComponents)) continue;
10195
+ names.push(...slot.$allowedComponents.filter((value) => typeof value === "string"));
10196
+ }
10197
+ return names;
10198
+ }
10199
+ function aggregateGlyphFor(closure, statusByName) {
10200
+ let worst = "ok";
10201
+ for (const node of closure.nodes) {
10202
+ const s = statusByName.get(node.name);
10203
+ if (!s) continue;
10204
+ if (s === "error") {
10205
+ worst = "error";
10206
+ break;
10207
+ }
10208
+ if (s === "warning") worst = "warning";
10209
+ }
10210
+ if (worst === "error") return GLYPH_ERROR;
10211
+ if (worst === "warning") return GLYPH_WARN;
10212
+ return null;
10213
+ }
10214
+ function buildVisibleRows(props) {
10215
+ const { items, cycleParticipants, alwaysExpanded, showFlatTier, viewMode, graph, filterVisibleKeys } = props;
10216
+ if (viewMode === "flat") {
10217
+ const rows2 = [];
10218
+ if (items.length === 0) return rows2;
10219
+ const itemByKey2 = new Map(items.map((it, idx) => [it.key, { it, idx }]));
10220
+ const cycleKeys2 = [];
10221
+ const otherKeys2 = [];
10222
+ for (const it of items) {
10223
+ if (cycleParticipants.has(it.key)) cycleKeys2.push(it.key);
10224
+ else otherKeys2.push(it.key);
10225
+ }
10226
+ cycleKeys2.sort();
10227
+ otherKeys2.sort();
10228
+ const otherKeySet2 = new Set(otherKeys2);
10229
+ const flatGraph = graph.filter((n) => otherKeySet2.has(n.name));
10230
+ const closures2 = computeAllClosures(flatGraph);
10231
+ const depCountByKey = /* @__PURE__ */ new Map();
10232
+ for (const [name, closure] of closures2) {
10233
+ if (closure.nodes.length > 1) depCountByKey.set(name, closure.nodes.length - 1);
10234
+ }
10235
+ for (const key of cycleKeys2) {
10236
+ const rec = itemByKey2.get(key);
10237
+ if (!rec) continue;
10238
+ rows2.push({
10239
+ kind: "cycle",
10240
+ key: `cycle:${key}`,
10241
+ label: `${GLYPH_WARN} ${key} (cycle)`,
10242
+ indent: 0,
10243
+ itemIdx: rec.idx
10244
+ });
10245
+ }
10246
+ for (const key of otherKeys2) {
10247
+ const rec = itemByKey2.get(key);
10248
+ if (!rec) continue;
10249
+ const dep = depCountByKey.get(key);
10250
+ const suffix = dep !== void 0 ? ` (${dep} dep${dep === 1 ? "" : "s"})` : "";
10251
+ rows2.push({
10252
+ kind: "flat",
10253
+ key: `flat:${key}`,
10254
+ label: `${key}${suffix}`,
10255
+ indent: 0,
10256
+ itemIdx: rec.idx
10257
+ });
10258
+ }
10259
+ return rows2;
10260
+ }
10261
+ const rows = [];
10262
+ if (items.length === 0) return rows;
10263
+ const itemByKey = new Map(items.map((it, idx) => [it.key, { it, idx }]));
10264
+ const statusByName = new Map(items.map((it) => [it.key, it.status]));
10265
+ const cycleKeys = [];
10266
+ const emptyKeys = [];
10267
+ const otherKeys = [];
10268
+ for (const it of items) {
10269
+ if (cycleParticipants.has(it.key)) cycleKeys.push(it.key);
10270
+ else if (isEmpty(it.entry)) emptyKeys.push(it.key);
10271
+ else otherKeys.push(it.key);
10272
+ }
10273
+ cycleKeys.sort();
10274
+ emptyKeys.sort();
10275
+ const seenCycleTierChildOccurrence = /* @__PURE__ */ new Set();
10276
+ const computeCycleMemberSubtree = (root) => {
10277
+ const out = [];
10278
+ const visited = /* @__PURE__ */ new Set([root]);
10279
+ const queue = [{ name: root, depth: 0 }];
10280
+ while (queue.length > 0) {
10281
+ const cur = queue.shift();
10282
+ const parentItem = itemByKey.get(cur.name)?.it;
10283
+ if (!parentItem) continue;
10284
+ const slotTargets2 = [];
10285
+ const seenTarget = /* @__PURE__ */ new Set();
10286
+ for (const target of allowedComponentNames(parentItem.entry)) {
10287
+ if (!itemByKey.has(target)) continue;
10288
+ if (seenTarget.has(target)) continue;
10289
+ seenTarget.add(target);
10290
+ slotTargets2.push(target);
10291
+ }
10292
+ slotTargets2.sort();
10293
+ for (const target of slotTargets2) {
10294
+ if (visited.has(target)) continue;
10295
+ visited.add(target);
10296
+ const isCycleMember = cycleParticipants.has(target);
10297
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
10298
+ queue.push({ name: target, depth: cur.depth + 1 });
10299
+ }
10300
+ }
10301
+ return out;
10302
+ };
10303
+ for (const key of cycleKeys) {
10304
+ const rec = itemByKey.get(key);
10305
+ if (!rec) continue;
10306
+ const expanded = alwaysExpanded ? true : props.expandedGroups.has(key);
10307
+ const glyphExpand = expanded ? GLYPH_EXPAND_EXPANDED : GLYPH_EXPAND_COLLAPSED;
10308
+ rows.push({
10309
+ kind: "cycle",
10310
+ key: `cycle:${key}`,
10311
+ label: `${glyphExpand} ${GLYPH_WARN} ${key} (cycle)`,
10312
+ indent: 0,
10313
+ itemIdx: rec.idx,
10314
+ rootName: key
10315
+ });
10316
+ if (!expanded) continue;
10317
+ const subtree = computeCycleMemberSubtree(key);
10318
+ const isLastAtDepthSubtree = (idx) => {
10319
+ const own = subtree[idx].depth;
10320
+ for (let j = idx + 1; j < subtree.length; j++) {
10321
+ const d = subtree[j].depth;
10322
+ if (d < own) return true;
10323
+ if (d === own) return false;
10324
+ }
10325
+ return true;
10326
+ };
10327
+ subtree.forEach((child, i) => {
10328
+ const isLast = isLastAtDepthSubtree(i);
10329
+ const glyph = isLast ? GLYPH_TREE_LAST : GLYPH_TREE_MID;
10330
+ let sharedSuffix = false;
10331
+ if (seenCycleTierChildOccurrence.has(child.name)) sharedSuffix = true;
10332
+ else seenCycleTierChildOccurrence.add(child.name);
10333
+ const childRec = itemByKey.get(child.name);
10334
+ const indent = " ".repeat(Math.max(0, child.depth - 1));
10335
+ const labelName = child.isCycleMember ? `${GLYPH_WARN} ${child.name} (cycle)` : child.name;
10336
+ rows.push({
10337
+ kind: "group-child",
10338
+ key: `cycle-child:${key}:${child.name}`,
10339
+ label: `${indent}${glyph} ${labelName}${sharedSuffix ? " (shared)" : ""}`,
10340
+ indent: child.depth,
10341
+ sharedSuffix,
10342
+ cycleChild: child.isCycleMember || void 0,
10343
+ itemIdx: childRec?.idx ?? -1,
10344
+ rootName: key
10345
+ });
10346
+ });
10347
+ }
10348
+ for (const key of emptyKeys) {
10349
+ const rec = itemByKey.get(key);
10350
+ if (!rec) continue;
10351
+ rows.push({
10352
+ kind: "empty",
10353
+ key: `empty:${key}`,
10354
+ label: `${key} (empty)`,
10355
+ indent: 0,
10356
+ itemIdx: rec.idx
10357
+ });
10358
+ }
10359
+ const otherKeySet = new Set(otherKeys);
10360
+ const subgraph = graph.filter((n) => otherKeySet.has(n.name));
10361
+ const closures = computeAllClosures(subgraph);
10362
+ const sharedDeps = findSharedDeps(closures);
10363
+ const hasCycleDepDirect = (name) => {
10364
+ const it = itemByKey.get(name)?.it;
10365
+ if (!it) return false;
10366
+ for (const target of allowedComponentNames(it.entry)) {
10367
+ if (cycleParticipants.has(target)) return true;
10368
+ }
10369
+ return false;
10370
+ };
10371
+ const rootNames = [...closures.keys()].sort();
10372
+ const standaloneRoots = [];
10373
+ const groupRoots = [];
10374
+ for (const root of rootNames) {
10375
+ const c2 = closures.get(root);
10376
+ const promotesForCycle = hasCycleDepDirect(root);
10377
+ if (c2.nodes.length <= 1 && !promotesForCycle) standaloneRoots.push(root);
10378
+ else groupRoots.push(root);
10379
+ }
10380
+ const seenSharedOccurrence = /* @__PURE__ */ new Set();
10381
+ const seenCycleChildOccurrence = /* @__PURE__ */ new Set();
10382
+ for (const root of groupRoots) {
10383
+ const closure = closures.get(root);
10384
+ let injectedCycleCount = 0;
10385
+ const seenInject = /* @__PURE__ */ new Set();
10386
+ const countInjections = (parentName) => {
10387
+ const parentItem = itemByKey.get(parentName)?.it;
10388
+ if (!parentItem) return;
10389
+ for (const target of allowedComponentNames(parentItem.entry)) {
10390
+ if (!cycleParticipants.has(target)) continue;
10391
+ const key = `${parentName}\u2192${target}`;
10392
+ if (seenInject.has(key)) continue;
10393
+ seenInject.add(key);
10394
+ injectedCycleCount += 1;
10395
+ }
10396
+ };
10397
+ countInjections(root);
10398
+ for (const n of closure.nodes) if (n.name !== root) countInjections(n.name);
10399
+ const depCount = closure.nodes.length - 1 + injectedCycleCount;
10400
+ const expanded = alwaysExpanded ? true : props.expandedGroups.has(root);
10401
+ const glyphExpand = expanded ? GLYPH_EXPAND_EXPANDED : GLYPH_EXPAND_COLLAPSED;
10402
+ const aggregate = expanded ? null : aggregateGlyphFor(closure, statusByName);
10403
+ const rec = itemByKey.get(root);
10404
+ rows.push({
10405
+ kind: "group-root",
10406
+ key: `root:${root}`,
10407
+ label: `${glyphExpand} ${root} (${depCount} dep${depCount === 1 ? "" : "s"})${aggregate ? " " + aggregate : ""}`,
10408
+ indent: 0,
10409
+ aggregateGlyph: aggregate,
10410
+ itemIdx: rec.idx,
10411
+ rootName: root
10412
+ });
10413
+ if (!expanded) continue;
10414
+ const closureChildren = closure.nodes.filter((n) => n.name !== root).slice().sort((a, b) => a.depth - b.depth || a.name.localeCompare(b.name));
10415
+ const injectedChildren = [];
10416
+ const emitCycleChildrenOf = (parentName, parentDepth) => {
10417
+ const parentItem = itemByKey.get(parentName)?.it;
10418
+ if (!parentItem) return;
10419
+ const seen = /* @__PURE__ */ new Set();
10420
+ for (const target of allowedComponentNames(parentItem.entry)) {
10421
+ if (!cycleParticipants.has(target)) continue;
10422
+ if (seen.has(target)) continue;
10423
+ seen.add(target);
10424
+ injectedChildren.push({
10425
+ name: target,
10426
+ depth: parentDepth + 1,
10427
+ isCycleChild: true
10428
+ });
10429
+ }
10430
+ };
10431
+ emitCycleChildrenOf(root, 0);
10432
+ for (const c2 of closureChildren) {
10433
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
10434
+ emitCycleChildrenOf(c2.name, c2.depth);
10435
+ }
10436
+ const isLastAtDepth = (idx) => {
10437
+ const own = injectedChildren[idx].depth;
10438
+ for (let j = idx + 1; j < injectedChildren.length; j++) {
10439
+ const d = injectedChildren[j].depth;
10440
+ if (d < own) return true;
10441
+ if (d === own) return false;
10442
+ }
10443
+ return true;
10444
+ };
10445
+ injectedChildren.forEach((child, i) => {
10446
+ const isLast = isLastAtDepth(i);
10447
+ const glyph = isLast ? GLYPH_TREE_LAST : GLYPH_TREE_MID;
10448
+ let sharedSuffix = false;
10449
+ if (child.isCycleChild) {
10450
+ if (seenCycleChildOccurrence.has(child.name)) sharedSuffix = true;
10451
+ else seenCycleChildOccurrence.add(child.name);
10452
+ } else if (sharedDeps.has(child.name)) {
10453
+ if (seenSharedOccurrence.has(child.name)) sharedSuffix = true;
10454
+ else seenSharedOccurrence.add(child.name);
10455
+ }
10456
+ const childRec = itemByKey.get(child.name);
10457
+ const indent = " ".repeat(Math.max(0, child.depth - 1));
10458
+ const labelName = child.isCycleChild ? `${GLYPH_WARN} ${child.name} (cycle)` : child.name;
10459
+ rows.push({
10460
+ kind: "group-child",
10461
+ key: `child:${root}:${child.name}`,
10462
+ label: `${indent}${glyph} ${labelName}${sharedSuffix ? " (shared)" : ""}`,
10463
+ indent: child.depth,
10464
+ sharedSuffix,
10465
+ cycleChild: child.isCycleChild || void 0,
10466
+ itemIdx: childRec?.idx ?? -1,
10467
+ rootName: root
10468
+ });
10469
+ });
10470
+ }
10471
+ for (const name of standaloneRoots) {
10472
+ const rec = itemByKey.get(name);
10473
+ if (!rec) continue;
10474
+ rows.push({
10475
+ kind: "standalone",
10476
+ key: `stand:${name}`,
10477
+ label: name,
10478
+ indent: 0,
10479
+ itemIdx: rec.idx
10480
+ });
10481
+ }
10482
+ const nodeByName = new Map(subgraph.map((n) => [n.name, n]));
10483
+ const sharedLeafNames = [...sharedDeps.keys()].filter((name) => (nodeByName.get(name)?.slots.length ?? 0) === 0).sort();
10484
+ const seenStandaloneNames = new Set(standaloneRoots);
10485
+ for (const name of sharedLeafNames) {
10486
+ if (seenStandaloneNames.has(name)) continue;
10487
+ const rec = itemByKey.get(name);
10488
+ if (!rec) continue;
10489
+ rows.push({
10490
+ kind: "standalone",
10491
+ key: `shared-standalone:${name}`,
10492
+ label: `${name} (shared)`,
10493
+ indent: 0,
10494
+ sharedSuffix: true,
10495
+ itemIdx: rec.idx
10496
+ });
10497
+ }
10498
+ if (showFlatTier) {
10499
+ const flatNames = otherKeys.slice().sort();
10500
+ if (flatNames.length > 0) {
10501
+ rows.push({
10502
+ kind: "flat-header",
10503
+ key: "flat-header",
10504
+ label: "\u2500\u2500 All components \u2500\u2500",
10505
+ indent: 0,
10506
+ itemIdx: -1
10507
+ });
10508
+ for (const name of flatNames) {
10509
+ const rec = itemByKey.get(name);
10510
+ if (!rec) continue;
10511
+ rows.push({
10512
+ kind: "flat",
10513
+ key: `flat:${name}`,
10514
+ label: name,
10515
+ indent: 0,
10516
+ itemIdx: rec.idx
10517
+ });
10518
+ }
10519
+ }
10520
+ }
10521
+ if (filterVisibleKeys !== void 0) {
10522
+ return rows.filter((row) => {
10523
+ if (row.itemIdx < 0) return true;
10524
+ const name = items[row.itemIdx]?.key;
10525
+ if (name === void 0) return true;
10526
+ return filterVisibleKeys.has(name);
10527
+ });
10528
+ }
10529
+ return rows;
10530
+ }
10531
+ function rowColor(row, aggregate) {
10532
+ if (row.kind === "cycle") return PALETTE2.warning;
10533
+ if (row.kind === "group-child" && row.cycleChild) return PALETTE2.warning;
10534
+ if (row.kind === "empty") return PALETTE2.warning;
10535
+ if (row.kind === "group-root" && aggregate === GLYPH_ERROR) return PALETTE2.error;
10536
+ if (row.kind === "group-root" && aggregate === GLYPH_WARN) return PALETTE2.warning;
10537
+ return void 0;
10538
+ }
10539
+ function labelStyleFor(input) {
10540
+ const { row, isCursor, wouldDim } = input;
10541
+ if (isCursor) {
10542
+ return { color: PALETTE2.info, bold: true, dim: false };
10543
+ }
10544
+ return {
10545
+ color: rowColor(row, row.aggregateGlyph),
10546
+ bold: false,
10547
+ dim: wouldDim
10548
+ };
10549
+ }
10550
+ function selectionGlyphStyleFor(selState, isCycleRow) {
10551
+ if (selState === "accepted") {
10552
+ return { glyph: "[\u2713]", color: PALETTE2.success, dim: false, bold: isCycleRow };
10553
+ }
10554
+ if (selState === "rejected") {
10555
+ return { glyph: "[\u2717]", color: PALETTE2.error, dim: false, bold: isCycleRow };
10556
+ }
10557
+ if (selState === "undecided") {
10558
+ return { glyph: "[ ]", color: PALETTE2.muted, dim: !isCycleRow, bold: false };
10559
+ }
10560
+ return { glyph: null, color: void 0, dim: false, bold: false };
10561
+ }
10562
+ function inheritanceGlyphStyleFor(input) {
10563
+ const { status, isOwn, isCursor } = input;
10564
+ if (status === "error") {
10565
+ return { glyph: GLYPH_ERROR, color: PALETTE2.error, dim: !isCursor && !isOwn, bold: isCursor };
10566
+ }
10567
+ if (status === "warning") {
10568
+ return { glyph: GLYPH_WARN, color: PALETTE2.warning, dim: !isCursor && !isOwn, bold: isCursor };
10569
+ }
10570
+ return { glyph: null, color: void 0, dim: false, bold: false };
10571
+ }
10572
+ function GroupedSidebar(props) {
10573
+ const {
10574
+ items,
10575
+ cycleParticipants = /* @__PURE__ */ new Set(),
10576
+ expandedGroups,
10577
+ focused,
10578
+ width,
10579
+ title,
10580
+ wrapLabels = false,
10581
+ selectedIdx,
10582
+ selectedRowIdx,
10583
+ renderStatusByKey,
10584
+ previewAnnotationByKey,
10585
+ scrollOffset,
10586
+ visibleCount,
10587
+ alwaysExpanded,
10588
+ showFlatTier,
10589
+ viewMode,
10590
+ selectionStateByKey,
10591
+ aiFlaggedByKey,
10592
+ dimPredicate,
10593
+ visibleRows: providedRows,
10594
+ graph,
10595
+ filterVisibleKeys
10596
+ } = props;
10597
+ const allRows = providedRows ?? buildVisibleRows({
10598
+ items,
10599
+ cycleParticipants,
10600
+ expandedGroups,
10601
+ alwaysExpanded,
10602
+ showFlatTier,
10603
+ viewMode,
10604
+ graph,
10605
+ filterVisibleKeys
10606
+ });
10607
+ const windowed = scrollOffset !== void 0 && visibleCount !== void 0;
10608
+ const start = windowed ? Math.max(0, scrollOffset ?? 0) : 0;
10609
+ const end = windowed ? start + (visibleCount ?? allRows.length) : allRows.length;
10610
+ const rows = windowed ? allRows.slice(start, end) : allRows;
10611
+ return /* @__PURE__ */ jsxs18(WindowedPanel, { width, height: props.height, title, focused, children: [
10612
+ windowed && /* @__PURE__ */ jsx21(WindowIndicator, { direction: "up", count: start }),
10613
+ rows.map((row, i) => {
10614
+ const absoluteRowIdx = start + i;
10615
+ const isSelected = selectedRowIdx !== void 0 ? absoluteRowIdx === selectedRowIdx && row.itemIdx >= 0 : row.itemIdx >= 0 && row.itemIdx === selectedIdx;
10616
+ const itemName = row.itemIdx >= 0 ? items[row.itemIdx]?.key : void 0;
10617
+ const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
10618
+ const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
10619
+ const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
10620
+ const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "cycle");
10621
+ const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
10622
+ const isCycleRow = row.kind === "cycle";
10623
+ const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
10624
+ const selGlyph = selStyle.glyph;
10625
+ const selColor = selStyle.color;
10626
+ const selDim = selStyle.dim;
10627
+ const selBold = selStyle.bold;
10628
+ const aiFlagged = aiFlaggedByKey !== void 0 && itemName !== void 0 && row.kind !== "flat-header" && aiFlaggedByKey.get(itemName) === true;
10629
+ const canDim = dimPredicate !== void 0 && itemName !== void 0 && row.kind !== "cycle" && row.kind !== "group-root" && row.kind !== "flat-header" && dimPredicate(itemName);
10630
+ const isSynthetic = row.kind === "flat-header";
10631
+ const isCursor = isSelected;
10632
+ const wouldDim = row.kind === "flat-header" || row.sharedSuffix === true || canDim;
10633
+ const labelStyle = labelStyleFor({ row, isCursor, wouldDim });
10634
+ const inheritanceStyle = inheritanceGlyphStyleFor({
10635
+ status: showInheritance ? rs?.status : void 0,
10636
+ isOwn: rs?.isOwn ?? false,
10637
+ isCursor
10638
+ });
10639
+ return /* @__PURE__ */ jsxs18(Box17, { children: [
10640
+ isCursor ? /* @__PURE__ */ jsx21(Text19, { color: PALETTE2.info, bold: true, children: figures4.pointer }) : /* @__PURE__ */ jsx21(Text19, { children: " " }),
10641
+ /* @__PURE__ */ jsx21(PreviewBadge, { badge, highlighted: isSelected }),
10642
+ selectionStateByKey !== void 0 && (selGlyph && !isSynthetic ? /* @__PURE__ */ jsx21(Text19, { color: !isSelected && selDim ? PALETTE2.muted : selColor, bold: selBold, children: " " + selGlyph }) : /* @__PURE__ */ jsx21(Text19, { children: " " })),
10643
+ aiFlaggedByKey !== void 0 && (aiFlagged ? /* @__PURE__ */ jsx21(Text19, { color: PALETTE2.warning, bold: true, children: " [\xD7]" }) : /* @__PURE__ */ jsx21(Text19, { children: " " })),
10644
+ /* @__PURE__ */ jsxs18(
10645
+ Text19,
10646
+ {
10647
+ color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
10648
+ bold: isSelected || labelStyle.bold,
10649
+ inverse: false,
10650
+ underline: isSelected && !focused,
10651
+ wrap: wrapLabels ? "wrap" : "truncate",
10652
+ children: [
10653
+ " ",
10654
+ row.label
10655
+ ]
10656
+ }
10657
+ ),
10658
+ inheritanceStyle.glyph && /* @__PURE__ */ jsx21(Text19, { color: inheritanceStyle.dim ? PALETTE2.muted : inheritanceStyle.color, bold: inheritanceStyle.bold, children: " " + inheritanceStyle.glyph })
10659
+ ] }, row.key);
10660
+ }),
10661
+ windowed && /* @__PURE__ */ jsx21(WindowIndicator, { direction: "down", count: allRows.length - end })
10662
+ ] });
10663
+ }
10664
+ var GLYPH_EXPAND_COLLAPSED, GLYPH_EXPAND_EXPANDED, GLYPH_TREE_MID, GLYPH_TREE_LAST, GLYPH_WARN, GLYPH_ERROR;
10665
+ var init_GroupedSidebar = __esm({
10666
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/GroupedSidebar.tsx"() {
10667
+ "use strict";
10668
+ init_composite_closure();
10669
+ init_badge();
10670
+ init_theme2();
10671
+ init_windowed_panel();
10672
+ GLYPH_EXPAND_COLLAPSED = "\u25B8";
10673
+ GLYPH_EXPAND_EXPANDED = "\u25BE";
10674
+ GLYPH_TREE_MID = "\u251C\u2500";
10675
+ GLYPH_TREE_LAST = "\u2514\u2500";
10676
+ GLYPH_WARN = "\u26A0";
10677
+ GLYPH_ERROR = "\u2717";
10678
+ }
10679
+ });
10680
+
10681
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/useImmediateInput.ts
10682
+ import { useLayoutEffect, useRef as useRef3 } from "react";
10683
+ import { useStdin } from "ink";
10684
+ function parseInput(data) {
10685
+ const isShiftTab = data === "\x1B[Z";
10686
+ const key = {
10687
+ upArrow: data === "\x1B[A",
10688
+ downArrow: data === "\x1B[B",
10689
+ leftArrow: data === "\x1B[D",
10690
+ rightArrow: data === "\x1B[C",
10691
+ pageDown: data === "\x1B[6~",
10692
+ pageUp: data === "\x1B[5~",
10693
+ return: data === "\r" || data === "\n",
10694
+ escape: data === "\x1B",
10695
+ ctrl: false,
10696
+ shift: isShiftTab,
10697
+ tab: data === " " || isShiftTab,
10698
+ shiftTab: isShiftTab,
10699
+ backspace: data === "\x7F" || data === "\b",
10700
+ delete: data === "\x1B[3~",
10701
+ meta: data === "\x1B"
10702
+ };
10703
+ let input = data;
10704
+ if (data.length === 1) {
10705
+ const code = data.charCodeAt(0);
10706
+ if (code >= 1 && code <= 26) {
10707
+ key.ctrl = true;
10708
+ input = String.fromCharCode(code + 96);
10709
+ }
10710
+ }
10711
+ if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.pageUp || key.pageDown || key.return || key.escape || key.tab || key.backspace || key.delete) {
10712
+ if (!key.ctrl) input = "";
10713
+ }
10714
+ return { input, key };
10715
+ }
10716
+ function registerInputHandler(stdin, setRawMode, handler) {
10717
+ let registry = inputRegistries.get(stdin);
10718
+ if (!registry) {
10719
+ const handlers = /* @__PURE__ */ new Set();
10720
+ const onData = (data) => {
10721
+ const str = Buffer.isBuffer(data) ? data.toString("utf8") : data;
10722
+ const { input, key } = parseInput(str);
10723
+ for (const registered of [...handlers]) registered(input, key);
10724
+ };
10725
+ registry = { handlers, onData, setRawMode };
10726
+ inputRegistries.set(stdin, registry);
10727
+ setRawMode(true);
10728
+ stdin.on("data", onData);
10729
+ }
10730
+ registry.handlers.add(handler);
10731
+ return () => {
10732
+ const current = inputRegistries.get(stdin);
10733
+ if (!current) return;
10734
+ current.handlers.delete(handler);
10735
+ if (current.handlers.size === 0) {
10736
+ stdin.off("data", current.onData);
10737
+ current.setRawMode(false);
10738
+ inputRegistries.delete(stdin);
10739
+ }
10740
+ };
10741
+ }
10742
+ function useImmediateInput(handler, enabled = true) {
10743
+ const { stdin, setRawMode } = useStdin();
10744
+ const handlerRef = useRef3(handler);
10745
+ handlerRef.current = handler;
10746
+ useLayoutEffect(() => {
10747
+ if (!enabled) return;
10748
+ const unregister = registerInputHandler(stdin, setRawMode, (input, key) => handlerRef.current(input, key));
10749
+ return unregister;
10750
+ }, [enabled, stdin, setRawMode]);
10751
+ }
10752
+ var inputRegistries;
10753
+ var init_useImmediateInput = __esm({
10754
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/useImmediateInput.ts"() {
10755
+ "use strict";
10756
+ inputRegistries = /* @__PURE__ */ new WeakMap();
10757
+ }
10758
+ });
10759
+
10760
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.ts
10761
+ import { useStdout as useStdout2 } from "ink";
10762
+ import { useEffect as useEffect6, useState as useState9 } from "react";
10763
+ function readTerminalSize(stdout) {
10764
+ return {
10765
+ columns: stdout?.columns ?? 80,
10766
+ rows: stdout?.rows ?? process.stdout.rows ?? 40
10767
+ };
10768
+ }
10769
+ function useTerminalSize() {
10770
+ const { stdout } = useStdout2();
10771
+ const [size, setSize] = useState9(() => readTerminalSize(stdout));
10772
+ useEffect6(() => {
10773
+ const updateSize = () => setSize(readTerminalSize(stdout));
10774
+ stdout?.on("resize", updateSize);
10775
+ updateSize();
10776
+ return () => {
10777
+ stdout?.off("resize", updateSize);
10778
+ };
10779
+ }, [stdout]);
10780
+ return size;
10781
+ }
10782
+ var init_use_terminal_size = __esm({
10783
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.ts"() {
10784
+ "use strict";
10785
+ }
10786
+ });
10787
+
10788
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/HelpOverlay.tsx
10789
+ import React7 from "react";
10790
+ import { Box as Box18, Text as Text20 } from "ink";
10791
+ import { Fragment as Fragment2, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
10792
+ function HelpOverlay(props) {
10793
+ const { onClose } = props;
10794
+ const { columns: terminalColumns, rows: terminalRows } = useTerminalSize();
10795
+ const panelWidth = Math.max(10, Math.min(64, terminalColumns - 2));
10796
+ const panelHeight = terminalPanelHeight(terminalRows, 2);
10797
+ const titleRule = Math.max(0, Math.floor((panelWidth - 10) / 2));
10798
+ useImmediateInput((input, key) => {
10799
+ if (input === "h" || key.escape) onClose();
10800
+ }, props.handleInput !== false);
10801
+ if (props.sections) {
10802
+ return /* @__PURE__ */ jsxs19(
10803
+ Box18,
10804
+ {
10805
+ flexDirection: "column",
10806
+ borderStyle: "round",
10807
+ padding: 1,
10808
+ width: panelWidth,
10809
+ height: panelHeight,
10810
+ overflowY: "hidden",
10811
+ children: [
10812
+ /* @__PURE__ */ jsx22(Text20, { bold: true, children: "\u2500".repeat(titleRule) + " Help " + "\u2500".repeat(titleRule) }),
10813
+ props.sections.map((section) => /* @__PURE__ */ jsxs19(React7.Fragment, { children: [
10814
+ /* @__PURE__ */ jsx22(Text20, { children: " " }),
10815
+ /* @__PURE__ */ jsx22(Text20, { bold: true, children: section.title }),
10816
+ section.entries.map((entry) => /* @__PURE__ */ jsx22(Text20, { children: entry.keys ? " " + entry.keys.padEnd(16) + " " + entry.label : " " + entry.label }, entry.keys + entry.label))
10817
+ ] }, section.title))
10818
+ ]
10819
+ }
10820
+ );
10821
+ }
10822
+ const mode = props.mode;
10823
+ return /* @__PURE__ */ jsxs19(
10824
+ Box18,
10825
+ {
10826
+ flexDirection: "column",
10827
+ borderStyle: "round",
10828
+ padding: 1,
10829
+ width: panelWidth,
10830
+ height: panelHeight,
10831
+ overflowY: "hidden",
10832
+ children: [
10833
+ /* @__PURE__ */ jsx22(Text20, { bold: true, children: "\u2500".repeat(titleRule) + " Help " + "\u2500".repeat(titleRule) }),
10834
+ /* @__PURE__ */ jsx22(Text20, { children: " " }),
10835
+ /* @__PURE__ */ jsx22(Text20, { bold: true, children: "Navigation" }),
10836
+ /* @__PURE__ */ jsx22(Text20, { children: " \u2191 / k / PgUp Scroll up" }),
10837
+ /* @__PURE__ */ jsx22(Text20, { children: " \u2193 / j / PgDn Scroll down" }),
10838
+ /* @__PURE__ */ jsx22(Text20, { children: " g / Home Jump to top" }),
10839
+ /* @__PURE__ */ jsx22(Text20, { children: " G / End Jump to bottom" }),
10840
+ mode === "review" && /* @__PURE__ */ jsxs19(Fragment2, { children: [
10841
+ /* @__PURE__ */ jsx22(Text20, { children: " " }),
10842
+ /* @__PURE__ */ jsx22(Text20, { bold: true, children: "[Review mode only]" }),
10843
+ /* @__PURE__ */ jsx22(Text20, { children: " Tab Toggle sidebar/detail" }),
10844
+ /* @__PURE__ */ jsx22(Text20, { children: " a Accept component" }),
10845
+ /* @__PURE__ */ jsx22(Text20, { children: " r Reject component" }),
10846
+ /* @__PURE__ */ jsx22(Text20, { children: " e Edit proposal" }),
10847
+ /* @__PURE__ */ jsx22(Text20, { children: " s Toggle source code" }),
10848
+ /* @__PURE__ */ jsx22(Text20, { children: " A Approve all" }),
10849
+ /* @__PURE__ */ jsx22(Text20, { children: " F Open finalize dialog" }),
10850
+ /* @__PURE__ */ jsx22(Text20, { children: " Ctrl+S Save draft" }),
10851
+ /* @__PURE__ */ jsx22(Text20, { children: " Ctrl+Z Undo" }),
10852
+ /* @__PURE__ */ jsx22(Text20, { children: " Ctrl+Y Redo" }),
10853
+ /* @__PURE__ */ jsx22(Text20, { children: " Esc Exit edit / close" })
10854
+ ] }),
10855
+ /* @__PURE__ */ jsx22(Text20, { children: " " }),
10856
+ /* @__PURE__ */ jsx22(Text20, { children: " h Close help" }),
10857
+ /* @__PURE__ */ jsx22(Text20, { children: " q Quit" })
10858
+ ]
10859
+ }
10860
+ );
10861
+ }
10862
+ var init_HelpOverlay = __esm({
10863
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/HelpOverlay.tsx"() {
10864
+ "use strict";
10865
+ init_useImmediateInput();
10866
+ init_use_terminal_size();
10867
+ init_windowed_panel();
10868
+ }
10869
+ });
10870
+
10871
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/autocomplete.ts
10872
+ function longestCommonPrefix(names) {
10873
+ if (names.length === 0) return "";
10874
+ let prefixLen = names[0].length;
10875
+ for (let i = 1; i < names.length; i++) {
10876
+ const other = names[i];
10877
+ let j = 0;
10878
+ while (j < prefixLen && j < other.length && names[0][j].toLowerCase() === other[j].toLowerCase()) {
10879
+ j++;
10880
+ }
10881
+ prefixLen = j;
10882
+ if (prefixLen === 0) break;
10883
+ }
10884
+ return names[0].slice(0, prefixLen);
10885
+ }
10886
+ function computeAutocomplete(query, names) {
10887
+ const q = query.toLowerCase();
10888
+ const candidates = names.filter((n) => n.toLowerCase().startsWith(q));
10889
+ if (candidates.length === 0) {
10890
+ return { completion: query, candidates: [] };
10891
+ }
10892
+ if (candidates.length === 1) {
10893
+ return { completion: candidates[0], candidates: [] };
10894
+ }
10895
+ const lcp = longestCommonPrefix(candidates);
10896
+ const completion = lcp.length >= query.length ? lcp : query;
10897
+ const sorted = [...candidates].sort();
10898
+ return { completion, candidates: sorted };
10899
+ }
10900
+ var init_autocomplete = __esm({
10901
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/autocomplete.ts"() {
10902
+ "use strict";
10903
+ }
10904
+ });
10905
+
10906
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-input.ts
10907
+ function handleSidebarSearchInput(input, key, { query, names, setQuery, setCandidates }) {
10908
+ if (key.tab) {
10909
+ const { completion, candidates } = computeAutocomplete(query, names);
10910
+ setQuery(completion);
10911
+ setCandidates(candidates);
10912
+ return true;
10913
+ }
10914
+ if (key.backspace) {
10915
+ setCandidates([]);
10916
+ setQuery((current) => current.slice(0, -1));
10917
+ return true;
10918
+ }
10919
+ if (input && input.length === 1 && input >= " " && input !== "\r" && input !== "\n") {
10920
+ setCandidates([]);
10921
+ setQuery((current) => current + input);
10922
+ return true;
10923
+ }
10924
+ return false;
10925
+ }
10926
+ function formatSearchMatchSummary(matches, total) {
10927
+ return ` (${matches}/${total} matches)`;
10928
+ }
10929
+ var init_sidebar_input = __esm({
10930
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-input.ts"() {
10931
+ "use strict";
10932
+ init_autocomplete();
10933
+ }
10934
+ });
10935
+
10936
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/SearchMatchSummary.tsx
10937
+ import { Box as Box19, Text as Text21 } from "ink";
10938
+ import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
10939
+ function SearchMatchSummary({
10940
+ open,
10941
+ query,
10942
+ matches,
10943
+ total,
10944
+ autocompleteCandidates,
10945
+ hidden = false,
10946
+ marginTop
10947
+ }) {
10948
+ if (hidden) return null;
10949
+ return /* @__PURE__ */ jsxs20(Fragment3, { children: [
10950
+ open && /* @__PURE__ */ jsxs20(Box19, { marginTop, flexDirection: "column", children: [
10951
+ /* @__PURE__ */ jsxs20(Text21, { children: [
10952
+ `/${query}`,
10953
+ /* @__PURE__ */ jsx23(Text21, { color: PALETTE2.info, children: "\u258E" }),
10954
+ query && /* @__PURE__ */ jsx23(Text21, { color: PALETTE2.muted, children: formatSearchMatchSummary(matches, total) }),
10955
+ /* @__PURE__ */ jsx23(Text21, { children: " \xB7 [Esc] leave" })
10956
+ ] }),
10957
+ autocompleteCandidates.length > 1 && /* @__PURE__ */ jsx23(Text21, { color: PALETTE2.muted, children: ` possibilities: ${autocompleteCandidates.join(" \xB7 ").slice(0, 120)}` })
10958
+ ] }),
10959
+ !open && query && /* @__PURE__ */ jsx23(Box19, { marginTop, children: /* @__PURE__ */ jsx23(Text21, { children: `/${query}${formatSearchMatchSummary(matches, total)} \xB7 [Esc] clear` }) })
10960
+ ] });
10961
+ }
10962
+ var init_SearchMatchSummary = __esm({
10963
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/components/SearchMatchSummary.tsx"() {
10964
+ "use strict";
10965
+ init_theme2();
10966
+ init_sidebar_input();
10967
+ }
10968
+ });
10969
+
10970
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-help.ts
10971
+ function createSidebarViewsHelpSection(includeBreaking) {
10972
+ const entries = [
10973
+ { keys: "L", label: "Flat view" },
10974
+ { keys: "i", label: "Focus lineage" }
10975
+ ];
10976
+ if (includeBreaking) entries.push({ keys: "w", label: "Only breaking" });
10977
+ entries.push(
10978
+ { keys: "o", label: "Only cycles" },
10979
+ { keys: "space", label: "Expand/collapse group" },
10980
+ { keys: "E / C", label: "Expand/collapse all" }
10981
+ );
10982
+ return { title: "Sidebar views", entries };
10983
+ }
10984
+ var init_sidebar_help = __esm({
10985
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-help.ts"() {
10986
+ "use strict";
10987
+ }
10988
+ });
10989
+
10990
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/search-neighborhood.ts
10991
+ function computeDirectNeighborhood(matches, graph) {
10992
+ const matchSet = new Set(matches);
10993
+ const out = new Set(matchSet);
10994
+ if (matchSet.size === 0) return out;
10995
+ for (const node of graph) {
10996
+ const targets = [];
10997
+ for (const slot of node.slots) {
10998
+ for (const t of slot.allowedComponents ?? []) targets.push(t);
10999
+ }
11000
+ if (matchSet.has(node.name)) {
11001
+ for (const t of targets) out.add(t);
11002
+ }
11003
+ for (const t of targets) {
11004
+ if (matchSet.has(t)) {
11005
+ out.add(node.name);
11006
+ break;
11007
+ }
11008
+ }
11009
+ }
11010
+ return out;
11011
+ }
11012
+ function findAllAncestors(target, graph) {
11013
+ const out = /* @__PURE__ */ new Set([target]);
11014
+ const parentsOf = /* @__PURE__ */ new Map();
11015
+ for (const node of graph) {
11016
+ for (const slot of node.slots) {
11017
+ for (const child of slot.allowedComponents ?? []) {
11018
+ const list = parentsOf.get(child);
11019
+ if (list) {
11020
+ if (!list.includes(node.name)) list.push(node.name);
11021
+ } else {
11022
+ parentsOf.set(child, [node.name]);
11023
+ }
11024
+ }
11025
+ }
11026
+ }
11027
+ const queue = [target];
11028
+ while (queue.length > 0) {
11029
+ const cur = queue.shift();
11030
+ const parents = parentsOf.get(cur);
11031
+ if (!parents) continue;
11032
+ for (const p of parents) {
11033
+ if (out.has(p)) continue;
11034
+ out.add(p);
11035
+ queue.push(p);
11036
+ }
11037
+ }
11038
+ return out;
11039
+ }
11040
+ var init_search_neighborhood = __esm({
11041
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/search-neighborhood.ts"() {
11042
+ "use strict";
11043
+ }
11044
+ });
11045
+
11046
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/fuzzy-search.ts
11047
+ function match(query, text) {
11048
+ if (query.length === 0) return { score: 0 };
11049
+ if (text.length === 0) return null;
11050
+ const queryLower = query.toLowerCase();
11051
+ const textLower = text.toLowerCase();
11052
+ let score = 0;
11053
+ let qi = 0;
11054
+ let lastMatchIndex = -2;
11055
+ for (let ti = 0; ti < text.length && qi < query.length; ti++) {
11056
+ if (textLower[ti] === queryLower[qi]) {
11057
+ score += 10;
11058
+ if (text[ti] === query[qi]) {
11059
+ score += 5;
11060
+ }
11061
+ if (ti === 0 && qi === 0) {
11062
+ score += 15;
11063
+ }
11064
+ if (ti === lastMatchIndex + 1) {
11065
+ score += 5;
11066
+ }
11067
+ lastMatchIndex = ti;
11068
+ qi++;
11069
+ }
11070
+ }
11071
+ if (qi < query.length) return null;
11072
+ score -= text.length * 0.1;
11073
+ return { score };
11074
+ }
11075
+ function fuzzyMatches(query, text) {
11076
+ return match(query, text) !== null;
11077
+ }
11078
+ var init_fuzzy_search = __esm({
11079
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/fuzzy-search.ts"() {
11080
+ "use strict";
11081
+ }
11082
+ });
11083
+
11084
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/ai-flag.ts
11085
+ function isAiFlagged(row) {
11086
+ return row.needsReview === true || row.aiDecision === "rejected" || row.aiDecision === "failed";
11087
+ }
11088
+ var init_ai_flag = __esm({
11089
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/ai-flag.ts"() {
11090
+ "use strict";
11091
+ }
11092
+ });
11093
+
11094
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/lineage.ts
11095
+ function findDirectParents2(target, components) {
11096
+ const out = [];
11097
+ const seen = /* @__PURE__ */ new Set();
11098
+ for (const c2 of components) {
11099
+ if (c2.name === target) continue;
11100
+ for (const slot of c2.slots) {
11101
+ const allowed = slot.allowedComponents ?? [];
11102
+ if (!allowed.includes(target)) continue;
11103
+ const key = `${c2.name}\0${slot.name}`;
11104
+ if (seen.has(key)) continue;
11105
+ seen.add(key);
11106
+ out.push({ parent: c2.name, slotName: slot.name });
11107
+ }
11108
+ }
11109
+ out.sort((a, b) => a.parent.localeCompare(b.parent) || a.slotName.localeCompare(b.slotName));
11110
+ return out;
11111
+ }
11112
+ var init_lineage = __esm({
11113
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/lineage.ts"() {
11114
+ "use strict";
11115
+ }
11116
+ });
11117
+
11118
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/scope-gate-cascade.ts
11119
+ function buildCycleUnits(slotCycles) {
11120
+ const parent = /* @__PURE__ */ new Map();
11121
+ const find = (x) => {
11122
+ let cur = x;
11123
+ while (parent.get(cur) !== cur) {
11124
+ cur = parent.get(cur);
11125
+ }
11126
+ let walk = x;
11127
+ while (parent.get(walk) !== cur) {
11128
+ const next = parent.get(walk);
11129
+ parent.set(walk, cur);
11130
+ walk = next;
11131
+ }
11132
+ return cur;
11133
+ };
11134
+ const union = (a, b) => {
11135
+ const ra = find(a);
11136
+ const rb = find(b);
11137
+ if (ra !== rb) parent.set(ra, rb);
11138
+ };
11139
+ for (const cycle of slotCycles) {
11140
+ for (const node of cycle.path) {
11141
+ if (!parent.has(node)) parent.set(node, node);
11142
+ }
11143
+ for (let i = 1; i < cycle.path.length; i++) {
11144
+ union(cycle.path[0], cycle.path[i]);
11145
+ }
11146
+ }
11147
+ const groups = /* @__PURE__ */ new Map();
11148
+ for (const node of parent.keys()) {
11149
+ const root = find(node);
11150
+ let group = groups.get(root);
11151
+ if (!group) {
11152
+ group = /* @__PURE__ */ new Set();
11153
+ groups.set(root, group);
11154
+ }
11155
+ group.add(node);
11156
+ }
11157
+ const out = /* @__PURE__ */ new Map();
11158
+ for (const group of groups.values()) {
11159
+ for (const node of group) {
11160
+ out.set(node, group);
11161
+ }
11162
+ }
11163
+ return out;
11164
+ }
11165
+ function slotTargets(node, byName) {
11166
+ const c2 = byName.get(node);
11167
+ if (!c2) return [];
11168
+ const seen = /* @__PURE__ */ new Set();
11169
+ const out = [];
11170
+ for (const slot of c2.slots) {
11171
+ for (const target of slot.allowedComponents ?? []) {
11172
+ if (!byName.has(target)) continue;
11173
+ if (seen.has(target)) continue;
11174
+ seen.add(target);
11175
+ out.push(target);
11176
+ }
11177
+ }
11178
+ return out;
11179
+ }
11180
+ function computeCycleAwareAcceptCascade(target, components, cycleUnits) {
11181
+ const byName = new Map(components.map((c2) => [c2.name, c2]));
11182
+ const visited = /* @__PURE__ */ new Set();
11183
+ const queue = [];
11184
+ const enqueue = (name) => {
11185
+ if (visited.has(name)) return;
11186
+ visited.add(name);
11187
+ queue.push(name);
11188
+ const unit = cycleUnits.get(name);
11189
+ if (unit) {
11190
+ for (const member of unit) {
11191
+ if (!visited.has(member)) {
11192
+ visited.add(member);
11193
+ queue.push(member);
11194
+ }
11195
+ }
11196
+ }
11197
+ };
11198
+ enqueue(target);
11199
+ while (queue.length > 0) {
11200
+ const cur = queue.shift();
11201
+ for (const next of slotTargets(cur, byName)) {
11202
+ enqueue(next);
11203
+ }
11204
+ }
11205
+ return visited;
11206
+ }
11207
+ function computeCycleAwareRejectCascade(target, components, cycleUnits) {
11208
+ const toReject = /* @__PURE__ */ new Set();
11209
+ const targetUnit = cycleUnits.get(target);
11210
+ const initialSeeds = targetUnit ? [...targetUnit] : [target];
11211
+ for (const seed of initialSeeds) toReject.add(seed);
11212
+ const stack = [...toReject];
11213
+ while (stack.length > 0) {
11214
+ const cur = stack.pop();
11215
+ for (const { parent } of findDirectParents2(cur, components)) {
11216
+ if (toReject.has(parent)) continue;
11217
+ toReject.add(parent);
11218
+ stack.push(parent);
11219
+ const unit = cycleUnits.get(parent);
11220
+ if (unit) {
11221
+ for (const member of unit) {
11222
+ if (!toReject.has(member)) {
11223
+ toReject.add(member);
11224
+ stack.push(member);
11225
+ }
11226
+ }
11227
+ }
11228
+ }
11229
+ }
11230
+ const acceptCascade2 = computeCycleAwareAcceptCascade(target, components, cycleUnits);
11231
+ const toDeselect = /* @__PURE__ */ new Set();
11232
+ for (const n of acceptCascade2) {
11233
+ if (toReject.has(n)) continue;
11234
+ toDeselect.add(n);
11235
+ }
11236
+ const cyclePartners = [];
11237
+ if (targetUnit) {
11238
+ for (const m of targetUnit) {
11239
+ if (m !== target) cyclePartners.push(m);
11240
+ }
11241
+ cyclePartners.sort();
11242
+ }
11243
+ return { toReject, toDeselect, cyclePartners };
11244
+ }
11245
+ function collectReachableCycleUnits(seeds, components, cycleUnits) {
11246
+ const out = /* @__PURE__ */ new Set();
11247
+ if (cycleUnits.size === 0) return out;
11248
+ const byName = new Map(components.map((c2) => [c2.name, c2]));
11249
+ const visited = /* @__PURE__ */ new Set();
11250
+ const queue = [...seeds];
11251
+ while (queue.length > 0) {
11252
+ const cur = queue.shift();
11253
+ if (visited.has(cur)) continue;
11254
+ visited.add(cur);
11255
+ const unit = cycleUnits.get(cur);
11256
+ if (unit) {
11257
+ for (const member of unit) {
11258
+ out.add(member);
11259
+ if (!visited.has(member)) queue.push(member);
11260
+ }
11261
+ }
11262
+ for (const next of slotTargets(cur, byName)) {
11263
+ if (!visited.has(next)) queue.push(next);
11264
+ }
11265
+ }
11266
+ return out;
11267
+ }
11268
+ var init_scope_gate_cascade = __esm({
11269
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/scope-gate-cascade.ts"() {
11270
+ "use strict";
11271
+ init_lineage();
11272
+ }
11273
+ });
11274
+
11275
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/slot-graph.ts
11276
+ function buildComponentGraph3(components, opts) {
11277
+ const stripRejectedEdges = opts?.stripRejectedEdges === true;
11278
+ return components.map((row) => {
11279
+ if (stripRejectedEdges && row.status !== void 0 && REJECTED_STATUSES.has(row.status)) {
11280
+ return { name: row.key, slots: [] };
11281
+ }
11282
+ const slotDefs = row.entry.$slots ?? {};
11283
+ const slots = Object.entries(slotDefs).map(([slotName, slotDef]) => ({
11284
+ name: slotName,
11285
+ allowedComponents: Array.isArray(slotDef?.$allowedComponents) ? slotDef.$allowedComponents.filter((v) => typeof v === "string") : []
11286
+ }));
11287
+ return { name: row.key, slots };
11288
+ });
11289
+ }
11290
+ var REJECTED_STATUSES;
11291
+ var init_slot_graph = __esm({
11292
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/slot-graph.ts"() {
11293
+ "use strict";
11294
+ REJECTED_STATUSES = /* @__PURE__ */ new Set(["error", "rejected"]);
11295
+ }
11296
+ });
11297
+
11298
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/index.ts
11299
+ function sidebarItems(components) {
11300
+ return components.map((c2) => ({
11301
+ key: c2.name,
11302
+ entry: toSidebarEntry(c2),
11303
+ status: isAiFlagged(c2) ? "warning" : "ok"
11304
+ }));
11305
+ }
11306
+ function toSidebarEntry(c2) {
11307
+ const $slots = {};
11308
+ for (const s of c2.slots ?? []) $slots[s.name] = { $allowedComponents: s.allowedComponents };
11309
+ const entry = {
11310
+ $type: "component",
11311
+ $properties: { __scopeGate: { $type: "string", $category: "content" } }
11312
+ };
11313
+ if (Object.keys($slots).length > 0) entry.$slots = $slots;
11314
+ return entry;
11315
+ }
11316
+ function buildScopeGraph(components) {
11317
+ const nodes = buildComponentGraph3(sidebarItems(components));
11318
+ let cycles;
11319
+ try {
11320
+ cycles = findSlotCycles3(nodes);
11321
+ } catch {
11322
+ cycles = [];
11323
+ }
11324
+ const cycleParticipants = /* @__PURE__ */ new Set();
11325
+ for (const cycle of cycles) for (const name of cycle.path) cycleParticipants.add(name);
11326
+ return {
11327
+ nodes,
11328
+ cycles,
11329
+ cycleParticipants,
11330
+ cycleUnits: buildCycleUnits(cycles),
11331
+ closures: computeAllClosures(nodes)
11332
+ };
11333
+ }
11334
+ function acceptCascade(graph, target) {
11335
+ return [...computeCycleAwareAcceptCascade(target, graph.nodes, graph.cycleUnits)];
11336
+ }
11337
+ function rejectCascade(graph, target) {
11338
+ const { toReject, toDeselect } = computeCycleAwareRejectCascade(target, graph.nodes, graph.cycleUnits);
11339
+ return { toReject: [...toReject], toDeselect: [...toDeselect] };
11340
+ }
11341
+ function reachableCycleMembers(graph, seeds) {
11342
+ return [...collectReachableCycleUnits(seeds, graph.nodes, graph.cycleUnits)];
11343
+ }
11344
+ var init_graph = __esm({
11345
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/graph/index.ts"() {
11346
+ "use strict";
11347
+ init_ai_flag();
11348
+ init_composite_closure();
11349
+ init_cycle_detection();
11350
+ init_scope_gate_cascade();
11351
+ init_slot_graph();
11352
+ }
11353
+ });
11354
+
11355
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/keymap.ts
11356
+ function resolveKey(mode, key, ctx) {
11357
+ switch (mode) {
11358
+ case "help":
11359
+ return key.input === "h" || key.escape ? { type: "close-help" } : NONE;
11360
+ case "reject-prompt":
11361
+ if (key.input === "y" || key.input === "Y") return { type: "answer-reject-prompt", confirm: true };
11362
+ if (key.input === "n" || key.input === "N" || key.escape) return { type: "answer-reject-prompt", confirm: false };
11363
+ return NONE;
11364
+ case "search":
11365
+ if (key.escape) return { type: "close-search" };
11366
+ if (key.return) return { type: "submit-search" };
11367
+ return { type: "search-input" };
11368
+ case "cycles":
11369
+ if (key.escape || key.input === "c") return { type: "close-panel" };
11370
+ if (key.upArrow) return { type: "move", delta: -1 };
11371
+ if (key.downArrow) return { type: "move", delta: 1 };
11372
+ if (key.return) return { type: "jump-to-selected" };
11373
+ return NONE;
11374
+ case "flags":
11375
+ if (key.upArrow) return { type: "move", delta: -1 };
11376
+ if (key.downArrow) return { type: "move", delta: 1 };
11377
+ if (key.return) return { type: "jump-to-selected" };
11378
+ return NONE;
11379
+ case "main":
11380
+ return resolveMain(key, ctx);
11381
+ }
11382
+ }
11383
+ function resolveMain(key, ctx) {
11384
+ const { input } = key;
11385
+ const inMain = ctx.focusedColumn === "main";
11386
+ if (input === "q" || key.escape) {
11387
+ if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
11388
+ if (key.escape && ctx.searchActive) return { type: "clear-search" };
11389
+ return { type: "quit" };
11390
+ }
11391
+ if (input === "h") return { type: "open-panel", panel: "help" };
11392
+ if (input === "f" || input === "F") return { type: "confirm" };
11393
+ if (input === "c") return ctx.hasCycles ? { type: "open-panel", panel: "cycles" } : NONE;
11394
+ if (input === "d") return { type: "toggle-dependencies" };
11395
+ if (input === "x") return ctx.hasFlagReasons ? { type: "open-panel", panel: "flags" } : NONE;
11396
+ if (input === "/") return { type: "open-panel", panel: "search" };
11397
+ if (input === "o") return ctx.hasCycles ? { type: "toggle-cycle-filter" } : NONE;
11398
+ if (input === "i" && !key.tab && !key.ctrl) return { type: "toggle-jump-filter" };
11399
+ if (input === " ") return inMain ? { type: "toggle-group" } : NONE;
11400
+ if (input === "E") return inMain ? { type: "expand-all" } : NONE;
11401
+ if (input === "C") return inMain ? { type: "collapse-all" } : NONE;
11402
+ if (input === "a") return inMain ? { type: "accept" } : NONE;
11403
+ if (input === "r") return { type: "reject" };
11404
+ if (input === "L") return { type: "toggle-view" };
11405
+ if (input === "A") return { type: "toggle-all" };
11406
+ if (input === "Y") return { type: "accept-unflagged" };
11407
+ if (key.tab) {
11408
+ if (ctx.singleColumn) return NONE;
11409
+ return { type: "switch-column", delta: key.shiftTab ? -1 : 1 };
11410
+ }
11411
+ if (key.return) return inMain ? NONE : { type: "jump-to-selected" };
11412
+ if (key.upArrow) return ctx.focusedListEmpty ? NONE : { type: "move", delta: -1 };
11413
+ if (key.downArrow) return ctx.focusedListEmpty ? NONE : { type: "move", delta: 1 };
11414
+ return NONE;
11415
+ }
11416
+ var NONE;
11417
+ var init_keymap = __esm({
11418
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/keymap.ts"() {
11419
+ "use strict";
11420
+ NONE = { type: "none" };
11421
+ }
11422
+ });
11423
+
11424
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/group-collapse.ts
11425
+ function resolveGroupRoot(key, closures, cycleSet) {
11426
+ if (cycleSet.has(key)) return key;
11427
+ if (closures.has(key)) return key;
11428
+ for (const [root, closure] of closures.entries()) {
11429
+ if (closure.nodes.some((n) => n.name === key)) return root;
11430
+ }
11431
+ return void 0;
11432
+ }
11433
+ var init_group_collapse = __esm({
11434
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/group-collapse.ts"() {
11435
+ "use strict";
11436
+ }
11437
+ });
11438
+
11439
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/sidebar-search-state.ts
11440
+ import { useState as useState10 } from "react";
11441
+ function useSidebarSearchState() {
11442
+ const [searchOpen, setSearchOpen] = useState10(false);
11443
+ const [searchQuery, setSearchQuery] = useState10("");
11444
+ const [autocompleteCandidates, setAutocompleteCandidates] = useState10([]);
11445
+ const [jumpFilterTarget, setJumpFilterTarget] = useState10(null);
11446
+ const [columnOneView, setColumnOneView] = useState10("grouped");
11447
+ const [activeFilters, setActiveFilters] = useState10(/* @__PURE__ */ new Set());
11448
+ const [showHelp, setShowHelp] = useState10(false);
11449
+ return {
11450
+ searchOpen,
11451
+ setSearchOpen,
11452
+ searchQuery,
11453
+ setSearchQuery,
11454
+ autocompleteCandidates,
11455
+ setAutocompleteCandidates,
11456
+ jumpFilterTarget,
11457
+ setJumpFilterTarget,
11458
+ columnOneView,
11459
+ setColumnOneView,
11460
+ activeFilters,
11461
+ setActiveFilters,
11462
+ showHelp,
11463
+ setShowHelp
11464
+ };
11465
+ }
11466
+ var init_sidebar_search_state = __esm({
11467
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/sidebar-search-state.ts"() {
11468
+ "use strict";
11469
+ }
11470
+ });
11471
+
11472
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/useOverlayPanel.ts
11473
+ import { useCallback, useState as useState11 } from "react";
11474
+ function useOverlayPanel(opts) {
11475
+ const { toggleKey, onClose } = opts;
11476
+ const [isOpen, setIsOpen] = useState11(false);
11477
+ const open = useCallback(() => {
11478
+ setIsOpen(true);
11479
+ }, []);
11480
+ const close = useCallback(() => {
11481
+ setIsOpen((prev) => {
11482
+ if (prev && onClose) onClose();
11483
+ return false;
11484
+ });
11485
+ }, [onClose]);
11486
+ const handleInput = useCallback(
11487
+ (input, key) => {
11488
+ if (!isOpen) return false;
11489
+ if (input === toggleKey || key.escape === true) {
11490
+ if (onClose) onClose();
11491
+ setIsOpen(false);
11492
+ return true;
11493
+ }
11494
+ return false;
11495
+ },
11496
+ [isOpen, toggleKey, onClose]
11497
+ );
11498
+ return { isOpen, open, close, handleInput };
11499
+ }
11500
+ var init_useOverlayPanel = __esm({
11501
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/useOverlayPanel.ts"() {
11502
+ "use strict";
11503
+ }
11504
+ });
11505
+
11506
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/lineage-layout.ts
11507
+ function clamp(value, min, max) {
11508
+ return Math.max(min, Math.min(max, value));
11509
+ }
11510
+ function computeLineageLayout({ rows, panelOpen, entryCount }) {
11511
+ const sidebarVisible = clamp(rows - BASE_CHROME_OVERHEAD, SIDEBAR_MIN, VISIBLE_COUNT);
11512
+ if (!panelOpen) {
11513
+ return { sidebarVisible, panelMaxRows: MAX_PANEL_ROWS };
11514
+ }
11515
+ const terminalFit = rows - FIXED_OVERHEAD - PANEL_BOX_CHROME;
11516
+ let panelBase = Math.min(MAX_PANEL_ROWS, terminalFit);
11517
+ if (entryCount !== void 0 && entryCount > 0) {
11518
+ panelBase = Math.min(panelBase, entryCount);
11519
+ }
11520
+ const panelMaxRows = clamp(panelBase, MIN_PANEL_ROWS, MAX_PANEL_ROWS);
11521
+ return { sidebarVisible, panelMaxRows };
11522
+ }
11523
+ function computeSidebarBudget({ rows, panelOpen, entryCount }) {
11524
+ const sidebarVisibleCount = clamp(rows - BASE_CHROME_OVERHEAD, SIDEBAR_MIN, VISIBLE_COUNT);
11525
+ const { panelMaxRows } = computeLineageLayout({ rows, panelOpen, entryCount });
11526
+ return { sidebarVisibleCount, panelMaxRows };
11527
+ }
11528
+ var VISIBLE_COUNT, MAX_PANEL_ROWS, SIDEBAR_MIN, MIN_PANEL_ROWS, FALLBACK_ROWS, HEADER_ROWS, COUNTER_STRIP_ROWS, FOCUSED_DETAIL_ROWS, LEGEND_ROWS, FIXED_OVERHEAD, PANEL_BOX_CHROME, BASE_CHROME_OVERHEAD;
11529
+ var init_lineage_layout = __esm({
11530
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/lineage-layout.ts"() {
11531
+ "use strict";
11532
+ VISIBLE_COUNT = 200;
11533
+ MAX_PANEL_ROWS = 200;
11534
+ SIDEBAR_MIN = 4;
11535
+ MIN_PANEL_ROWS = 4;
11536
+ FALLBACK_ROWS = 40;
11537
+ HEADER_ROWS = 2;
11538
+ COUNTER_STRIP_ROWS = 2;
11539
+ FOCUSED_DETAIL_ROWS = 2;
11540
+ LEGEND_ROWS = 3;
11541
+ FIXED_OVERHEAD = HEADER_ROWS + COUNTER_STRIP_ROWS + FOCUSED_DETAIL_ROWS + LEGEND_ROWS;
11542
+ PANEL_BOX_CHROME = 6;
11543
+ BASE_CHROME_OVERHEAD = 18;
11544
+ }
11545
+ });
11546
+
11547
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-navigation.ts
11548
+ function collectExpandedGroupRoots(closures, cycleParticipants) {
11549
+ const roots = /* @__PURE__ */ new Set();
11550
+ for (const [name, closure] of closures.entries()) {
11551
+ if (closure.nodes.length > 1) roots.add(name);
11552
+ }
11553
+ for (const name of cycleParticipants) roots.add(name);
11554
+ return roots;
11555
+ }
11556
+ function computeSidebarViewToggle({
11557
+ currentView,
11558
+ currentKey,
11559
+ currentScroll,
11560
+ visibleCount,
11561
+ items,
11562
+ cycleParticipants,
11563
+ expandedGroups,
11564
+ graph,
11565
+ showFlatTier = false
11566
+ }) {
11567
+ const view = currentView === "grouped" ? "flat" : "grouped";
11568
+ const rows = buildVisibleRows({
11569
+ items,
11570
+ cycleParticipants,
11571
+ expandedGroups,
11572
+ showFlatTier,
11573
+ viewMode: view,
11574
+ graph
11575
+ });
11576
+ let cursor = 0;
11577
+ if (currentKey) {
11578
+ for (let i = 0; i < rows.length; i++) {
11579
+ const row = rows[i];
11580
+ if (row.itemIdx < 0) continue;
11581
+ if (items[row.itemIdx]?.key === currentKey) {
11582
+ cursor = i;
11583
+ break;
11584
+ }
11585
+ }
11586
+ }
11587
+ const scroll = cursor < currentScroll ? cursor : cursor >= currentScroll + visibleCount ? cursor - visibleCount + 1 : currentScroll;
11588
+ return { view, cursor, scroll };
11589
+ }
11590
+ var init_sidebar_navigation = __esm({
11591
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/sidebar-navigation.ts"() {
11592
+ "use strict";
11593
+ init_GroupedSidebar();
11594
+ }
11595
+ });
11596
+
11597
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/step-filters.ts
11598
+ function computeFilterKeys(input) {
11599
+ const active = new Set(input.filters);
11600
+ if (active.size === 0) return void 0;
11601
+ const out = /* @__PURE__ */ new Set();
11602
+ if (active.has("cycles")) for (const k of input.data.cycles ?? []) out.add(k);
11603
+ if (active.has("broken")) for (const k of input.data.broken ?? []) out.add(k);
11604
+ if (active.has("deleted")) for (const k of input.data.deleted ?? []) out.add(k);
11605
+ return out;
11606
+ }
11607
+ function intersectFilterKeys(a, b) {
11608
+ if (a === void 0) return b;
11609
+ if (b === void 0) return a;
11610
+ const out = /* @__PURE__ */ new Set();
11611
+ for (const k of a) if (b.has(k)) out.add(k);
11612
+ return out;
11613
+ }
11614
+ function buildFlatDimPredicate(input) {
11615
+ const hasSearch = input.searchQuery.length > 0;
11616
+ const isFlat = input.viewMode === "flat";
11617
+ const keys = isFlat ? input.filterVisibleKeys : void 0;
11618
+ if (!hasSearch && keys === void 0) return void 0;
11619
+ return (name) => {
11620
+ if (hasSearch && !fuzzyMatches(input.searchQuery, name)) return true;
11621
+ if (keys !== void 0 && !keys.has(name)) return true;
11622
+ return false;
11623
+ };
11624
+ }
11625
+ var init_step_filters = __esm({
11626
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/step-filters.ts"() {
11627
+ "use strict";
11628
+ init_fuzzy_search();
11629
+ }
11630
+ });
11631
+
11632
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/state.ts
11633
+ function apply(state, entries) {
11634
+ const next = new Map(state);
11635
+ for (const [name, decision] of entries) next.set(name, decision);
11636
+ return next;
11637
+ }
11638
+ function reduceDecisions(state, action, components, graph) {
11639
+ switch (action.type) {
11640
+ case "accept": {
11641
+ if (state.get(action.name) === "accepted") return state;
11642
+ return apply(
11643
+ state,
11644
+ acceptCascade(graph, action.name).map((name) => [name, "accepted"])
11645
+ );
11646
+ }
11647
+ case "reject": {
11648
+ if (state.get(action.name) === "rejected") return state;
11649
+ const { toReject, toDeselect } = rejectCascade(graph, action.name);
11650
+ return apply(state, [
11651
+ ...toReject.map((name) => [name, "rejected"]),
11652
+ ...toDeselect.map((name) => [name, "undecided"])
11653
+ ]);
11654
+ }
11655
+ case "toggle-all": {
11656
+ const nonCycle = components.filter((c2) => !graph.cycleParticipants.has(c2.name)).map((c2) => c2.name);
11657
+ const anyNotAccepted = nonCycle.some((name) => state.get(name) !== "accepted");
11658
+ if (anyNotAccepted) {
11659
+ return apply(state, [
11660
+ ...nonCycle.map((name) => [name, "accepted"]),
11661
+ ...reachableCycleMembers(graph, nonCycle).map((name) => [name, "accepted"])
11662
+ ]);
11663
+ }
11664
+ return apply(state, [
11665
+ ...nonCycle.map((name) => [name, "rejected"]),
11666
+ ...components.filter((c2) => graph.cycleParticipants.has(c2.name) && state.get(c2.name) === "accepted").map((c2) => [c2.name, "undecided"])
11667
+ ]);
11668
+ }
11669
+ case "accept-unflagged": {
11670
+ const seeds = components.filter((c2) => !graph.cycleParticipants.has(c2.name) && !isAiFlagged(c2)).map((c2) => c2.name);
11671
+ return apply(state, [
11672
+ ...seeds.map((name) => [name, "accepted"]),
11673
+ ...reachableCycleMembers(graph, seeds).map((name) => [name, "accepted"])
11674
+ ]);
11675
+ }
11676
+ }
11677
+ }
11678
+ function rejectNeedsConfirmation(graph, name, state) {
11679
+ if (state.get(name) === "rejected") return false;
11680
+ const { toReject, toDeselect } = rejectCascade(graph, name);
11681
+ const ancestors = toReject.filter((n) => n !== name);
11682
+ return ancestors.length + toDeselect.length >= 2;
11683
+ }
11684
+ function partitionDecisions(components, state) {
11685
+ const accepted = [];
11686
+ const rejected = [];
11687
+ for (const c2 of components) {
11688
+ if (state.get(c2.name) === "accepted") accepted.push(c2.name);
11689
+ else rejected.push(c2.name);
11690
+ }
11691
+ return { accepted, rejected };
11692
+ }
11693
+ var init_state = __esm({
11694
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/state.ts"() {
11695
+ "use strict";
11696
+ init_graph();
11697
+ init_ai_flag();
11698
+ }
11699
+ });
11700
+
11701
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
11702
+ import { useEffect as useEffect7, useMemo as useMemo2, useRef as useRef4, useState as useState12 } from "react";
11703
+ function useScopeGate({ components, onConfirm, onQuit }) {
11704
+ const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
11705
+ const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
11706
+ const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
11707
+ const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
11708
+ const [focusedColumn, setFocusedColumn] = useState12("main");
11709
+ const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
11710
+ const [showDependencies, setShowDependencies] = useState12(false);
11711
+ const [cyclesPanelOpen, setCyclesPanelOpen] = useState12(false);
11712
+ const [cyclesCursor, setCyclesCursor] = useState12(0);
11713
+ const aiRationalePanel = useOverlayPanel({ toggleKey: "x" });
11714
+ const [aiCursor, setAiCursor] = useState12(0);
11715
+ const [pendingRejectCascade, setPendingRejectCascade] = useState12(null);
11716
+ const search = useSidebarSearchState();
11717
+ const {
11718
+ searchOpen,
11719
+ setSearchOpen,
11720
+ searchQuery,
11721
+ setSearchQuery,
11722
+ setAutocompleteCandidates,
11723
+ jumpFilterTarget,
11724
+ setJumpFilterTarget,
11725
+ columnOneView,
11726
+ setColumnOneView,
11727
+ activeFilters,
11728
+ setActiveFilters,
11729
+ showHelp,
11730
+ setShowHelp
11731
+ } = search;
11732
+ const groupedItems = useMemo2(() => sidebarItems(components), [components]);
11733
+ const graph = useMemo2(() => buildScopeGraph(components), [components]);
11734
+ const { cycles: slotCycles, cycleParticipants, cycleUnits, closures } = graph;
11735
+ const hasCycles = slotCycles.length > 0;
11736
+ const cyclesJumpables = useMemo2(
11737
+ () => slotCycles.map((c2, i) => ({ cycleIndex: i, jumpTarget: c2.path[0] })),
11738
+ [slotCycles]
11739
+ );
11740
+ const [expandedGroups, setExpandedGroups] = useState12(() => {
11741
+ const seed = new Set(closures.keys());
11742
+ for (const p of cycleParticipants) seed.add(p);
11743
+ return seed;
11744
+ });
11745
+ const seededGroupsRef = useRef4(closures.size > 0 || cycleParticipants.size > 0);
11746
+ useEffect7(() => {
11747
+ if (seededGroupsRef.current) return;
11748
+ if (closures.size === 0 && cycleParticipants.size === 0) return;
11749
+ seededGroupsRef.current = true;
11750
+ const seed = new Set(closures.keys());
11751
+ for (const p of cycleParticipants) seed.add(p);
11752
+ setExpandedGroups(seed);
11753
+ }, [closures, cycleParticipants]);
11754
+ const hasGroupRoots = useMemo2(() => {
11755
+ if (cycleParticipants.size > 0) return true;
11756
+ for (const c2 of closures.values()) if (c2.nodes.length > 1) return true;
11757
+ return false;
11758
+ }, [closures, cycleParticipants]);
11759
+ const toggleExpanded = (rootName) => {
11760
+ setExpandedGroups((prev) => {
11761
+ const next = new Set(prev);
11762
+ if (next.has(rootName)) next.delete(rootName);
11763
+ else next.add(rootName);
11764
+ return next;
11765
+ });
11766
+ };
11767
+ const brokenKeys = useMemo2(() => new Set(components.filter(isAiFlagged).map((c2) => c2.name)), [components]);
11768
+ const dependencyFilterKeys = useMemo2(() => {
11769
+ if (!showDependencies) return void 0;
11770
+ const keys = /* @__PURE__ */ new Set();
11771
+ for (const [root, closure] of closures) {
11772
+ if (closure.nodes.length <= 1 || decisions.get(root) !== "accepted") continue;
11773
+ for (const node of closure.nodes) keys.add(node.name);
11774
+ }
11775
+ for (const unit of cycleUnits.values()) {
11776
+ if (![...unit].some((name) => decisions.get(name) === "accepted")) continue;
11777
+ for (const name of unit) keys.add(name);
11778
+ }
11779
+ return keys;
11780
+ }, [closures, cycleUnits, showDependencies, decisions]);
11781
+ const filterVisibleKeys = useMemo2(() => {
11782
+ if (jumpFilterTarget) return findAllAncestors(jumpFilterTarget, graph.nodes);
11783
+ const categoryKeys = computeFilterKeys({
11784
+ filters: activeFilters,
11785
+ data: { cycles: cycleParticipants, broken: brokenKeys }
11786
+ });
11787
+ const searchKeys = (() => {
11788
+ if (!searchQuery) return void 0;
11789
+ const matches = groupedItems.map((it) => it.key).filter((k) => fuzzyMatches(searchQuery, k));
11790
+ if (matches.length === 0) return void 0;
11791
+ return computeDirectNeighborhood(matches, graph.nodes);
11792
+ })();
11793
+ return intersectFilterKeys(intersectFilterKeys(categoryKeys, searchKeys), dependencyFilterKeys);
11794
+ }, [
11795
+ jumpFilterTarget,
11796
+ activeFilters,
11797
+ cycleParticipants,
11798
+ brokenKeys,
11799
+ searchQuery,
11800
+ groupedItems,
11801
+ graph,
11802
+ dependencyFilterKeys
11803
+ ]);
11804
+ const visibleRows = useMemo2(
11805
+ () => buildVisibleRows({
11806
+ items: groupedItems,
11807
+ cycleParticipants,
11808
+ expandedGroups,
11809
+ showFlatTier: false,
11810
+ viewMode: columnOneView,
11811
+ graph: graph.nodes,
11812
+ filterVisibleKeys
11813
+ }),
11814
+ [groupedItems, cycleParticipants, expandedGroups, columnOneView, graph, filterVisibleKeys]
11815
+ );
11816
+ const total = visibleRows.length;
11817
+ const safeCursor = Math.min(nav.cursor, Math.max(0, total - 1));
11818
+ const currentRow = visibleRows[safeCursor];
11819
+ const currentRowKey = currentRow && currentRow.itemIdx >= 0 ? groupedItems[currentRow.itemIdx]?.key : void 0;
11820
+ const selectionStateByKey = useMemo2(() => {
11821
+ const map = /* @__PURE__ */ new Map();
11822
+ for (const c2 of components) map.set(c2.name, decisions.get(c2.name) ?? "undecided");
11823
+ return map;
11824
+ }, [components, decisions]);
11825
+ const aiFlaggedByKey = useMemo2(() => new Map(components.map((c2) => [c2.name, isAiFlagged(c2)])), [components]);
11826
+ const dimPredicate = useMemo2(
11827
+ () => buildFlatDimPredicate({ viewMode: columnOneView, searchQuery, filterVisibleKeys }),
11828
+ [columnOneView, searchQuery, filterVisibleKeys]
11829
+ );
11830
+ const { sidebarVisibleCount: visibleCount, panelMaxRows } = computeSidebarBudget({
11831
+ rows: terminalRows || FALLBACK_ROWS,
11832
+ panelOpen: false,
11833
+ entryCount: 0
11834
+ });
11835
+ const panelLayout = useMemo2(() => computePanelLayout(visibleCount), [visibleCount]);
11836
+ useEffect7(() => {
11837
+ setNav((prev) => {
11838
+ const maxIdx = Math.max(0, visibleRows.length - 1);
11839
+ const nextCursor = Math.min(prev.cursor, maxIdx);
11840
+ const nextScroll = Math.min(prev.scrollOffset, maxIdx);
11841
+ if (nextCursor === prev.cursor && nextScroll === prev.scrollOffset) return prev;
11842
+ return { cursor: nextCursor, scrollOffset: nextScroll };
11843
+ });
11844
+ }, [visibleRows]);
11845
+ const searchMatches = useMemo2(() => {
11846
+ if (!searchQuery) return [];
11847
+ return components.filter((c2) => fuzzyMatches(searchQuery, c2.name)).map((c2) => c2.name);
11848
+ }, [components, searchQuery]);
11849
+ const aiExcluded = components.filter(isAiFlagged);
11850
+ const aiRows = useMemo2(
11851
+ () => aiExcluded.filter((c2) => c2.aiReason !== null && c2.aiReason !== void 0 && c2.aiReason !== "").map((c2) => ({ label: `${c2.name} \u2014 ${c2.aiReason}`, jumpTarget: c2.name })),
11852
+ [aiExcluded]
11853
+ );
11854
+ const addedComponents = useMemo2(
11855
+ () => buildAddedComponentsList(components, selectionStateByKey, cycleParticipants),
11856
+ [components, selectionStateByKey, cycleParticipants]
11857
+ );
11858
+ const counters = useMemo2(
11859
+ () => computeCounters(components, closures, selectionStateByKey),
11860
+ [components, closures, selectionStateByKey]
11861
+ );
11862
+ const safeAddedComponentsCursor = Math.min(addedComponentsCursor, Math.max(0, addedComponents.length - 1));
11863
+ const focusedRowKey = () => {
11864
+ const row = visibleRows[safeCursor];
11865
+ if (!row) return void 0;
11866
+ switch (row.kind) {
11867
+ case "standalone":
11868
+ case "empty":
11869
+ case "group-root":
11870
+ case "group-child":
11871
+ case "flat":
11872
+ case "cycle":
11873
+ return row.itemIdx >= 0 ? groupedItems[row.itemIdx]?.key : void 0;
11874
+ default:
11875
+ return void 0;
11876
+ }
11877
+ };
11878
+ const jumpCursorTo = (name) => {
11879
+ let idx = -1;
11880
+ for (let i = 0; i < visibleRows.length; i++) {
11881
+ const row = visibleRows[i];
11882
+ if (row.itemIdx < 0) continue;
11883
+ if (groupedItems[row.itemIdx]?.key === name) {
11884
+ idx = i;
11885
+ break;
11886
+ }
11887
+ }
11888
+ if (idx < 0) return;
11889
+ setNav(({ scrollOffset: prev }) => {
11890
+ let nextScroll = prev;
11891
+ if (idx < prev) nextScroll = idx;
11892
+ else if (idx >= prev + visibleCount) nextScroll = idx - visibleCount + 1;
11893
+ return { cursor: idx, scrollOffset: nextScroll };
11894
+ });
11895
+ };
11896
+ const decide = (action) => setDecisions((prev) => reduceDecisions(prev, action, components, graph));
11897
+ const requestReject = (name) => {
11898
+ if (decisions.get(name) === "rejected") return;
11899
+ if (rejectNeedsConfirmation(graph, name, decisions)) {
11900
+ const { toReject, toDeselect } = rejectCascade(graph, name);
11901
+ setPendingRejectCascade({
11902
+ target: name,
11903
+ ancestors: toReject.filter((n) => n !== name).sort(),
11904
+ descendants: [...toDeselect].sort()
11905
+ });
11906
+ return;
11907
+ }
11908
+ decide({ type: "reject", name });
11909
+ };
11910
+ const mode = showHelp ? "help" : pendingRejectCascade ? "reject-prompt" : searchOpen ? "search" : cyclesPanelOpen ? "cycles" : aiRationalePanel.isOpen ? "flags" : "main";
11911
+ const context = {
11912
+ focusedColumn,
11913
+ singleColumn: columnPlan.layout === "single",
11914
+ hasCycles,
11915
+ hasFlagReasons: aiRows.length > 0,
11916
+ jumpFilterActive: jumpFilterTarget !== null,
11917
+ searchActive: searchQuery.length > 0,
11918
+ focusedListEmpty: focusedColumn === "added-components" ? addedComponents.length === 0 : total === 0
11919
+ };
11920
+ const submitSearch = () => {
11921
+ const closeSearch = () => {
11922
+ setSearchOpen(false);
11923
+ setSearchQuery("");
11924
+ setAutocompleteCandidates([]);
11925
+ };
11926
+ if (!searchQuery || searchMatches.length === 0) {
11927
+ closeSearch();
11928
+ return;
11929
+ }
11930
+ const cursorName = currentRow && currentRow.itemIdx >= 0 ? groupedItems[currentRow.itemIdx]?.key : void 0;
11931
+ const rowName = (i) => {
11932
+ const r = visibleRows[i];
11933
+ return r && r.itemIdx >= 0 ? groupedItems[r.itemIdx]?.key : void 0;
11934
+ };
11935
+ let target;
11936
+ for (let i = safeCursor; i < visibleRows.length && !target; i++) {
11937
+ const n = rowName(i);
11938
+ if (n && n !== cursorName && fuzzyMatches(searchQuery, n)) target = n;
11939
+ }
11940
+ for (let i = 0; i < visibleRows.length && !target; i++) {
11941
+ const n = rowName(i);
11942
+ if (n && fuzzyMatches(searchQuery, n)) target = n;
11943
+ }
11944
+ if (target) jumpCursorTo(target);
11945
+ setSearchOpen(false);
11946
+ };
11947
+ const move = (delta) => {
11948
+ if (mode === "cycles") {
11949
+ setCyclesCursor((c2) => Math.max(0, Math.min(Math.max(0, cyclesJumpables.length - 1), c2 + delta)));
11950
+ return;
11951
+ }
11952
+ if (mode === "flags") {
11953
+ setAiCursor((c2) => Math.max(0, Math.min(Math.max(0, aiRows.length - 1), c2 + delta)));
11954
+ return;
11955
+ }
11956
+ if (focusedColumn === "added-components") {
11957
+ setAddedComponentsCursor((c2) => Math.max(0, Math.min(addedComponents.length - 1, c2 + delta)));
11958
+ return;
11959
+ }
11960
+ setNav(({ cursor: c2, scrollOffset: prev }) => {
11961
+ if (delta < 0) {
11962
+ const next2 = c2 <= 0 ? 0 : c2 - 1;
11963
+ return { cursor: next2, scrollOffset: Math.min(prev, next2) };
11964
+ }
11965
+ const next = c2 >= total - 1 ? total - 1 : c2 + 1;
11966
+ return { cursor: next, scrollOffset: next >= prev + visibleCount ? next - visibleCount + 1 : prev };
11967
+ });
11968
+ };
11969
+ const perform = (action) => {
11970
+ switch (action.type) {
11971
+ case "none":
11972
+ return;
11973
+ case "quit":
11974
+ onQuit();
11975
+ return;
11976
+ case "confirm":
11977
+ onConfirm(partitionDecisions(components, decisions));
11978
+ return;
11979
+ case "close-help":
11980
+ setShowHelp(false);
11981
+ return;
11982
+ case "answer-reject-prompt":
11983
+ if (action.confirm && pendingRejectCascade) decide({ type: "reject", name: pendingRejectCascade.target });
11984
+ setPendingRejectCascade(null);
11985
+ return;
11986
+ case "close-panel":
11987
+ setCyclesPanelOpen(false);
11988
+ return;
11989
+ case "close-search":
11990
+ setSearchOpen(false);
11991
+ setSearchQuery("");
11992
+ setAutocompleteCandidates([]);
11993
+ return;
11994
+ case "submit-search":
11995
+ submitSearch();
11996
+ return;
11997
+ case "search-input":
11998
+ return;
11999
+ case "clear-jump-filter":
12000
+ setJumpFilterTarget(null);
12001
+ return;
12002
+ case "clear-search":
12003
+ setSearchQuery("");
12004
+ setAutocompleteCandidates([]);
12005
+ return;
12006
+ case "move":
12007
+ move(action.delta);
12008
+ return;
12009
+ case "jump-to-selected":
12010
+ if (mode === "cycles") {
12011
+ const target = cyclesJumpables[cyclesCursor];
12012
+ if (target) jumpCursorTo(target.jumpTarget);
12013
+ setCyclesPanelOpen(false);
12014
+ } else if (mode === "flags") {
12015
+ const row = aiRows[aiCursor];
12016
+ if (row) jumpCursorTo(row.jumpTarget);
12017
+ aiRationalePanel.close();
12018
+ } else {
12019
+ const entry = addedComponents[safeAddedComponentsCursor];
12020
+ if (entry) jumpCursorTo(entry.name);
12021
+ setFocusedColumn("main");
12022
+ }
12023
+ return;
12024
+ case "accept": {
12025
+ const key = focusedRowKey();
12026
+ if (key) decide({ type: "accept", name: key });
12027
+ return;
12028
+ }
12029
+ case "reject": {
12030
+ const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
12031
+ if (key) requestReject(key);
12032
+ return;
12033
+ }
12034
+ case "toggle-all":
12035
+ decide({ type: "toggle-all" });
12036
+ return;
12037
+ case "accept-unflagged":
12038
+ decide({ type: "accept-unflagged" });
12039
+ return;
12040
+ case "toggle-group": {
12041
+ const key = focusedRowKey();
12042
+ const rootName = key ? resolveGroupRoot(key, closures, cycleParticipants) : void 0;
12043
+ if (rootName) toggleExpanded(rootName);
12044
+ return;
12045
+ }
12046
+ case "expand-all":
12047
+ setExpandedGroups(collectExpandedGroupRoots(closures, cycleParticipants));
12048
+ return;
12049
+ case "collapse-all":
12050
+ setExpandedGroups(/* @__PURE__ */ new Set());
12051
+ return;
12052
+ case "switch-column": {
12053
+ const order = ["main", "added-components"];
12054
+ const at = order.indexOf(focusedColumn);
12055
+ setFocusedColumn(order[(at + action.delta + order.length) % order.length]);
12056
+ return;
12057
+ }
12058
+ case "open-panel":
12059
+ if (action.panel === "help") setShowHelp(true);
12060
+ else if (action.panel === "search") setSearchOpen(true);
12061
+ else if (action.panel === "cycles") {
12062
+ setCyclesPanelOpen(true);
12063
+ setCyclesCursor(0);
12064
+ aiRationalePanel.close();
12065
+ } else {
12066
+ aiRationalePanel.open();
12067
+ setAiCursor(0);
12068
+ setCyclesPanelOpen(false);
12069
+ }
12070
+ return;
12071
+ case "toggle-dependencies":
12072
+ setShowDependencies((current) => !current);
12073
+ setNav({ cursor: 0, scrollOffset: 0 });
12074
+ return;
12075
+ case "toggle-cycle-filter":
12076
+ setActiveFilters((prev) => {
12077
+ const next = new Set(prev);
12078
+ if (next.has("cycles")) next.delete("cycles");
12079
+ else next.add("cycles");
12080
+ return next;
12081
+ });
12082
+ return;
12083
+ case "toggle-jump-filter": {
12084
+ const target = focusedColumn === "main" ? focusedRowKey() : addedComponents[safeAddedComponentsCursor]?.name;
12085
+ if (target) setJumpFilterTarget((prev) => prev === target ? null : target);
12086
+ return;
12087
+ }
12088
+ case "toggle-view": {
12089
+ const next = computeSidebarViewToggle({
12090
+ currentView: columnOneView,
12091
+ currentKey: currentRowKey,
12092
+ currentScroll: nav.scrollOffset,
12093
+ visibleCount,
12094
+ items: groupedItems,
12095
+ cycleParticipants,
12096
+ expandedGroups,
12097
+ graph: graph.nodes
12098
+ });
12099
+ setColumnOneView(next.view);
12100
+ setNav({ cursor: next.cursor, scrollOffset: next.scroll });
12101
+ return;
12102
+ }
12103
+ }
12104
+ };
12105
+ useImmediateInput((input, key) => {
12106
+ if (mode === "flags" && aiRationalePanel.handleInput(input, key)) return;
12107
+ if (mode === "search") {
12108
+ const action = resolveKey(mode, { input, ...key }, context);
12109
+ if (action.type === "search-input") {
12110
+ handleSidebarSearchInput(input, key, {
12111
+ query: searchQuery,
12112
+ names: components.map((c2) => c2.name),
12113
+ setQuery: setSearchQuery,
12114
+ setCandidates: setAutocompleteCandidates
12115
+ });
12116
+ return;
12117
+ }
12118
+ perform(action);
12119
+ return;
12120
+ }
12121
+ perform(resolveKey(mode, { input, ...key }, context));
12122
+ });
12123
+ return {
12124
+ // layout
12125
+ totalWidth,
12126
+ columnPlan,
12127
+ panelLayout,
12128
+ visibleCount,
12129
+ panelMaxRows,
12130
+ // sidebar
12131
+ groupedItems,
12132
+ graph,
12133
+ hasGroupRoots,
12134
+ expandedGroups,
12135
+ toggleExpanded,
12136
+ visibleRows,
12137
+ safeCursor,
12138
+ scrollOffset: nav.scrollOffset,
12139
+ selectionStateByKey,
12140
+ aiFlaggedByKey,
12141
+ dimPredicate,
12142
+ columnOneView,
12143
+ focusedColumn,
12144
+ // panels
12145
+ showHelp,
12146
+ closeHelp: () => setShowHelp(false),
12147
+ cyclesPanelOpen,
12148
+ cyclesCursor,
12149
+ slotCycles,
12150
+ aiRationalePanelOpen: aiRationalePanel.isOpen,
12151
+ aiCursor,
12152
+ aiRows,
12153
+ aiExcludedCount: aiExcluded.length,
12154
+ pendingRejectCascade,
12155
+ // added column
12156
+ addedComponents,
12157
+ safeAddedComponentsCursor,
12158
+ counters,
12159
+ // search
12160
+ search,
12161
+ searchMatches
12162
+ };
12163
+ }
12164
+ var init_use_scope_gate = __esm({
12165
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts"() {
12166
+ "use strict";
12167
+ init_columns();
12168
+ init_search_neighborhood();
12169
+ init_search_neighborhood();
12170
+ init_fuzzy_search();
12171
+ init_graph();
12172
+ init_keymap();
12173
+ init_ai_flag();
12174
+ init_GroupedSidebar();
12175
+ init_group_collapse();
12176
+ init_sidebar_search_state();
12177
+ init_useImmediateInput();
12178
+ init_useOverlayPanel();
12179
+ init_use_terminal_size();
12180
+ init_lineage_layout();
12181
+ init_sidebar_navigation();
12182
+ init_sidebar_input();
12183
+ init_step_filters();
12184
+ init_state();
12185
+ }
12186
+ });
12187
+
12188
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/screen.tsx
12189
+ import { Box as Box20, Text as Text22 } from "ink";
12190
+ import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
12191
+ function ScopeGateScreen(props) {
12192
+ if (props.components.length === 0) {
12193
+ return /* @__PURE__ */ jsx24(Box20, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx24(Text22, { color: PALETTE2.error, children: "Error: no components found for this session \u2014 please re-run analyze extract." }) });
12194
+ }
12195
+ return /* @__PURE__ */ jsx24(ScopeGateView, { ...props });
12196
+ }
12197
+ function ScopeGateView({ components, onConfirm, onQuit }) {
12198
+ const gate = useScopeGate({ components, onConfirm, onQuit });
12199
+ const { search, graph, columnPlan, panelLayout, counters } = gate;
12200
+ if (gate.showHelp) {
12201
+ return /* @__PURE__ */ jsx24(HelpOverlay, { sections: HELP_SECTIONS, handleInput: false, onClose: gate.closeHelp });
12202
+ }
12203
+ return /* @__PURE__ */ jsxs21(Box20, { flexDirection: "column", paddingX: 2, children: [
12204
+ /* @__PURE__ */ jsxs21(Box20, { flexDirection: "row", flexWrap: "wrap", children: [
12205
+ /* @__PURE__ */ jsx24(CounterStrip, { counters, totalWidth: gate.totalWidth }),
12206
+ gate.aiExcludedCount > 0 && /* @__PURE__ */ jsxs21(Text22, { color: PALETTE2.muted, children: [
12207
+ `${gate.aiExcludedCount} component${gate.aiExcludedCount === 1 ? "" : "s"} flagged by AI`,
12208
+ gate.aiRows.length > 0 && /* @__PURE__ */ jsx24(Text22, { color: PALETTE2.info, children: " \u2014 press [x] to see why" })
12209
+ ] })
12210
+ ] }),
12211
+ graph.cycles.length > 0 && /* @__PURE__ */ jsx24(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text22, { color: PALETTE2.muted, children: "If you must have components with cycles, select them together into the generate step and then use the editor to fix them." }) }),
12212
+ /* @__PURE__ */ jsxs21(Box20, { flexDirection: "row", alignItems: "stretch", children: [
12213
+ gate.aiRationalePanelOpen ? /* @__PURE__ */ jsx24(
12214
+ GotoBanner,
12215
+ {
12216
+ title: `Review flags (${gate.aiExcludedCount})`,
12217
+ rows: gate.aiRows,
12218
+ cursor: gate.aiCursor,
12219
+ maxRows: gate.panelMaxRows,
12220
+ width: columnPlan.main,
12221
+ footerHint: "[\u2191/\u2193] move \xB7 [Enter] jump \xB7 [x/Esc] close"
12222
+ }
12223
+ ) : /* @__PURE__ */ jsx24(
12224
+ GroupedSidebar,
12225
+ {
12226
+ items: gate.groupedItems,
12227
+ cycleParticipants: graph.cycleParticipants,
12228
+ selectedIdx: gate.visibleRows[gate.safeCursor]?.itemIdx ?? -1,
12229
+ selectedRowIdx: gate.safeCursor,
12230
+ onSelect: () => {
12231
+ },
12232
+ expandedGroups: gate.expandedGroups,
12233
+ onToggleExpanded: gate.toggleExpanded,
12234
+ width: columnPlan.main,
12235
+ height: panelLayout.height,
12236
+ title: "All components",
12237
+ wrapLabels: true,
12238
+ focused: gate.focusedColumn === "main",
12239
+ scrollOffset: gate.scrollOffset,
12240
+ visibleCount: gate.visibleCount,
12241
+ showFlatTier: false,
12242
+ selectionStateByKey: gate.selectionStateByKey,
12243
+ aiFlaggedByKey: gate.aiFlaggedByKey,
12244
+ dimPredicate: gate.dimPredicate,
12245
+ visibleRows: gate.visibleRows,
12246
+ viewMode: gate.columnOneView,
12247
+ graph: graph.nodes
12248
+ }
12249
+ ),
12250
+ columnPlan.layout === "two-column" && /* @__PURE__ */ jsxs21(Fragment4, { children: [
12251
+ /* @__PURE__ */ jsx24(Box20, { width: 2, flexShrink: 0 }),
12252
+ /* @__PURE__ */ jsx24(
12253
+ AddedColumn,
12254
+ {
12255
+ width: columnPlan.added,
12256
+ entries: gate.addedComponents,
12257
+ cursor: gate.safeAddedComponentsCursor,
12258
+ focused: gate.focusedColumn === "added-components",
12259
+ height: panelLayout.height,
12260
+ title: `Accepted Components (${counters.accepted}/${counters.total})`,
12261
+ aiFlaggedByKey: gate.aiFlaggedByKey,
12262
+ visibleCount: panelLayout.sideVisibleCount
12263
+ }
12264
+ )
12265
+ ] })
12266
+ ] }),
12267
+ gate.cyclesPanelOpen && /* @__PURE__ */ jsx24(CyclesPanel, { cycles: gate.slotCycles, cursor: gate.cyclesCursor }),
12268
+ gate.pendingRejectCascade && /* @__PURE__ */ jsx24(RejectPrompt, { pending: gate.pendingRejectCascade }),
12269
+ /* @__PURE__ */ jsx24(
12270
+ SearchMatchSummary,
12271
+ {
12272
+ open: search.searchOpen,
12273
+ query: search.searchQuery,
12274
+ matches: search.searchQuery ? gate.searchMatches.length : 0,
12275
+ total: components.length,
12276
+ autocompleteCandidates: search.autocompleteCandidates,
12277
+ marginTop: 1
12278
+ }
12279
+ ),
12280
+ /* @__PURE__ */ jsx24(
12281
+ CompactControlBar,
12282
+ {
12283
+ hasGroupRoots: gate.hasGroupRoots,
12284
+ searchActive: search.searchOpen || search.searchQuery.length > 0
12285
+ }
12286
+ )
12287
+ ] });
12288
+ }
12289
+ var HELP_SECTIONS;
12290
+ var init_screen7 = __esm({
12291
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/screen.tsx"() {
12292
+ "use strict";
12293
+ init_added_column();
12294
+ init_cycles_panel();
12295
+ init_reject_prompt();
12296
+ init_CompactControlBar();
12297
+ init_CounterStrip();
12298
+ init_GotoBanner();
12299
+ init_GroupedSidebar();
12300
+ init_HelpOverlay();
12301
+ init_SearchMatchSummary();
12302
+ init_sidebar_help();
12303
+ init_theme2();
12304
+ init_use_scope_gate();
12305
+ HELP_SECTIONS = [
12306
+ {
12307
+ title: "Navigation",
12308
+ entries: [
12309
+ { keys: "\u2191 / \u2193", label: "Move cursor" },
12310
+ { keys: "Tab / Shift-Tab", label: "Switch column" },
12311
+ { keys: "Enter", label: "Jump to row in main column" }
12312
+ ]
12313
+ },
12314
+ {
12315
+ title: "Selection",
12316
+ entries: [
12317
+ { keys: "a", label: "Accept" },
12318
+ { keys: "r", label: "Reject" },
12319
+ { keys: "A", label: "Toggle all" },
12320
+ { keys: "Y", label: "Accept non-flagged" }
12321
+ ]
12322
+ },
12323
+ createSidebarViewsHelpSection(false),
12324
+ {
12325
+ title: "Panels",
12326
+ entries: [
12327
+ { keys: "c", label: "Cycle list" },
12328
+ { keys: "d", label: "Show slot dependencies in main list" },
12329
+ { keys: "x", label: "Review flags" }
12330
+ ]
12331
+ },
12332
+ { title: "Search", entries: [{ keys: "/", label: "Search" }] },
12333
+ {
12334
+ title: "General",
12335
+ entries: [
12336
+ { keys: "f", label: "Continue" },
12337
+ { keys: "h", label: "Close help" },
12338
+ { keys: "q", label: "Quit" }
12339
+ ]
12340
+ }
12341
+ ];
12342
+ }
12343
+ });
12344
+
12345
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts
12346
+ import { execFile as execFile3 } from "node:child_process";
12347
+ function buildCacheCheckArgs(input) {
12348
+ const args = ["__generate", "components", "--agent", input.agent, "--session", input.sessionId];
12349
+ if (input.tokensPath) args.push("--tokens", input.tokensPath);
12350
+ if (input.agentModel) args.push("--model", input.agentModel);
12351
+ if (input.noCache) args.push("--no-cache");
12352
+ for (const prompt of input.promptOverrides) args.push("--prompt", prompt);
12353
+ if (input.existingEntitiesPath) args.push("--existing-entities-path", input.existingEntitiesPath);
12354
+ args.push("--cache-status", "--restore-cache");
12355
+ return args;
12356
+ }
12357
+ function parseCacheComponents(stdout) {
12358
+ const line = /^cache-components=(.+)$/m.exec(stdout)?.[1];
12359
+ if (!line) return [];
12360
+ try {
12361
+ const names = JSON.parse(line);
12362
+ return Array.isArray(names) ? names.filter((name) => typeof name === "string") : [];
12363
+ } catch {
12364
+ return [];
12365
+ }
12366
+ }
12367
+ async function checkGenerationCache(input, run2 = runLegacyCli) {
12368
+ if (input.noCache) return [];
12369
+ try {
12370
+ const result = await run2(buildCacheCheckArgs(input));
12371
+ if (result.exitCode !== 0) return [];
12372
+ return parseCacheComponents(result.stdout);
12373
+ } catch {
12374
+ return [];
12375
+ }
12376
+ }
12377
+ var runLegacyCli;
12378
+ var init_cache_check = __esm({
12379
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts"() {
12380
+ "use strict";
12381
+ init_legacy_cli_path();
12382
+ runLegacyCli = (args) => new Promise((resolve10) => {
12383
+ execFile3("node", [findLegacyCliPath(), ...args], (error, stdout, stderr) => {
12384
+ resolve10({ exitCode: error?.code ? Number(error.code) : 0, stdout, stderr });
12385
+ });
12386
+ });
12387
+ }
12388
+ });
12389
+
12390
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/load.ts
12391
+ function loadScopeGate(sessionId) {
12392
+ try {
12393
+ const db = openPipelineDb();
12394
+ try {
12395
+ const components = loadScopeComponents(db, sessionId);
12396
+ if (components.length === 0) {
12397
+ return { ok: false, message: "No components found for this session. Please run the import again." };
12398
+ }
12399
+ return { ok: true, components };
12400
+ } finally {
12401
+ db.close();
12402
+ }
12403
+ } catch (error) {
12404
+ return {
12405
+ ok: false,
12406
+ message: `Could not read the extracted components: ${error instanceof Error ? error.message : String(error)}`
12407
+ };
12408
+ }
12409
+ }
12410
+ var init_load = __esm({
12411
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/load.ts"() {
12412
+ "use strict";
12413
+ init_src3();
12414
+ }
12415
+ });
12416
+
12417
+ // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.ts
12418
+ import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef5, useState as useState13 } from "react";
12419
+ function useScopeGateFlow(input, deps = realDeps2) {
12420
+ const sessionId = input?.sessionId;
12421
+ const loaded = useMemo3(() => sessionId ? deps.load(sessionId) : void 0, [sessionId]);
12422
+ const cacheCheck = useRef5(void 0);
12423
+ const [confirmed, setConfirmed] = useState13();
12424
+ const [scope, setScope] = useState13();
12425
+ useEffect8(() => {
12426
+ if (!input || !loaded?.ok || cacheCheck.current) return;
12427
+ cacheCheck.current = deps.checkCache(input.cache);
12428
+ }, [input, loaded]);
12429
+ useEffect8(() => {
12430
+ if (!confirmed || !cacheCheck.current) return;
12431
+ let current = true;
12432
+ void cacheCheck.current.then((cachedNames) => {
12433
+ const accepted = new Set(confirmed.accepted);
12434
+ if (current) setScope({ ...confirmed, cachedNames: cachedNames.filter((name) => accepted.has(name)) });
12435
+ });
12436
+ return () => {
12437
+ current = false;
12438
+ };
12439
+ }, [confirmed]);
12440
+ if (!input || !loaded) return void 0;
12441
+ if (!loaded.ok) return { status: "failed", message: loaded.message };
12442
+ if (scope) return { status: "confirmed", scope };
12443
+ if (confirmed) return { status: "preparing" };
12444
+ return { status: "deciding", load: loaded, confirm: setConfirmed };
12445
+ }
12446
+ var realDeps2;
12447
+ var init_use_scope_gate_flow = __esm({
12448
+ "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.ts"() {
12449
+ "use strict";
12450
+ init_cache_check();
12451
+ init_load();
12452
+ realDeps2 = { load: loadScopeGate, checkCache: checkGenerationCache };
12453
+ }
12454
+ });
12455
+
12456
+ // packages/experience-design-system-types/dist/src/handoff/index.js
12457
+ import * as z5 from "zod/mini";
12458
+ function serializeHandoff(handoff) {
12459
+ return JSON.stringify(handoff);
12460
+ }
12461
+ var HANDOFF_ENV, NonEmpty, TokensSchema, ExtractionSchema, ScopeSchema, ImportHandoffSchema;
12462
+ var init_handoff = __esm({
12463
+ "packages/experience-design-system-types/dist/src/handoff/index.js"() {
12464
+ "use strict";
12465
+ HANDOFF_ENV = "EDS_IMPORT_HANDOFF";
12466
+ NonEmpty = z5.string().check(z5.minLength(1));
12467
+ TokensSchema = z5.object({
12468
+ /**
12469
+ * What to do about an existing `tokens.json`.
12470
+ * reuse: keep it. regenerate: build it again with the cache off. generate: nothing was asked, build it as usual.
12471
+ */
12472
+ strategy: z5.enum(["reuse", "regenerate", "generate"])
12473
+ });
12474
+ ExtractionSchema = z5.object({
12475
+ sessionId: NonEmpty,
12476
+ outDir: NonEmpty,
12477
+ tokensPath: z5.string(),
12478
+ tokenSessionId: z5.nullable(z5.string()),
12479
+ tokenCount: z5.number(),
12480
+ existingEntitiesPath: z5.nullable(z5.string()),
12481
+ /** Never 'running': the wizard starts its background cache check only once this has settled. */
12482
+ existingEntitiesStatus: z5.enum(["idle", "complete", "failed"]),
12483
+ /** The only phases the scope gate can start from. */
12484
+ compositionPhase: z5.enum(["done", "cache-hit"])
12485
+ });
12486
+ ScopeSchema = z5.object({
12487
+ /** The components the user kept at the scope gate. The wizard saves these, then generates them. */
12488
+ accepted: z5.array(z5.string()),
12489
+ /** Everything else at the gate, which counts as rejected. */
12490
+ rejected: z5.array(z5.string()),
12491
+ /**
12492
+ * Components the generation cache already holds, found by the check that ran while the gate was open and which has
12493
+ * finished (and restored them) before the wizard starts. Empty when the cache is off or the check failed.
12494
+ */
12495
+ cachedNames: z5.array(z5.string())
12496
+ });
12497
+ ImportHandoffSchema = z5.object({
12498
+ /** The user skipped the credentials screen, so nothing is fetched from or pushed to Contentful. */
12499
+ credentialsSkipped: z5.boolean(),
12500
+ tokens: TokensSchema,
12501
+ /** Present once the CLI has run the extraction stage; the wizard then starts at the scope gate. */
12502
+ extraction: z5.optional(ExtractionSchema),
12503
+ /** Present once the user has confirmed the scope gate; the wizard then saves the decisions and starts generating. */
12504
+ scope: z5.optional(ScopeSchema)
12505
+ });
12506
+ }
12507
+ });
12508
+
12509
+ // packages/experience-design-system-cli/src/tui/import/spawn-v1-import.ts
12510
+ import { spawn as spawn9 } from "node:child_process";
12511
+ function buildArgs2(options) {
12512
+ const args = ["import"];
12513
+ if (options.projectPath) {
12514
+ args.push("--project", options.projectPath);
12515
+ }
12516
+ if (options.tokens) {
12517
+ args.push("--tokens", options.tokens);
12518
+ }
12519
+ args.push(...importOptionArgs({ agent: options.agent, prompt: options.prompt ?? [], cache: options.cache ?? true }));
12520
+ return args;
12521
+ }
12522
+ function buildEnv(options, base = process.env) {
12523
+ return { ...base, ...options.handoff ? { [HANDOFF_ENV]: serializeHandoff(options.handoff) } : {} };
12524
+ }
12525
+ async function spawnV1Import(options = {}) {
12526
+ const cliPath = findLegacyCliPath();
12527
+ const args = buildArgs2(options);
12528
+ return new Promise((resolvePromise) => {
12529
+ const child = spawn9("node", [cliPath, ...args], {
12530
+ stdio: "inherit",
12531
+ env: buildEnv(options)
12532
+ });
12533
+ child.on("close", (code) => {
12534
+ resolvePromise({ exitCode: code ?? 1, result: void 0, stdout: "", stderr: "" });
12535
+ });
12536
+ child.on("error", (err) => {
12537
+ resolvePromise({ exitCode: 1, result: void 0, stdout: "", stderr: err.message });
12538
+ });
12539
+ });
12540
+ }
12541
+ var init_spawn_v1_import = __esm({
12542
+ "packages/experience-design-system-cli/src/tui/import/spawn-v1-import.ts"() {
12543
+ "use strict";
12544
+ init_legacy_cli_path();
12545
+ init_import_options();
12546
+ init_handoff();
12547
+ }
12548
+ });
12549
+
12550
+ // packages/experience-design-system-cli/src/tui/import/terminal-input.ts
12551
+ function getTerminalHandle() {
12552
+ return process.stdin._handle;
12553
+ }
12554
+ async function stopReadingTerminal() {
12555
+ await new Promise((resolve10) => setImmediate(resolve10));
12556
+ const handle = getTerminalHandle();
12557
+ if (!handle?.readStop) return;
12558
+ handle.reading = false;
12559
+ handle.readStop();
12560
+ }
12561
+ function startReadingTerminal() {
12562
+ const handle = getTerminalHandle();
12563
+ if (!handle?.readStart) return;
12564
+ handle.reading = true;
12565
+ handle.readStart();
12566
+ }
12567
+ var init_terminal_input = __esm({
12568
+ "packages/experience-design-system-cli/src/tui/import/terminal-input.ts"() {
12569
+ "use strict";
12570
+ }
12571
+ });
12572
+
12573
+ // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
12574
+ async function readDebugModeSetting() {
12575
+ const { debugMode } = await readSettings2();
12576
+ return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
12577
+ }
12578
+ async function writeDebugModeSetting(setting) {
12579
+ await updateSettings2({ debugMode: setting });
12580
+ }
12581
+ var DEFAULT_DEBUG_MODE_SETTING;
12582
+ var init_debug_mode_store = __esm({
12583
+ "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
12584
+ "use strict";
12585
+ init_config();
12586
+ DEFAULT_DEBUG_MODE_SETTING = {
12587
+ enabled: true
12588
+ };
12589
+ }
12590
+ });
12591
+
12592
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
12593
+ import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
12594
+ import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
12595
+ import { join as join13 } from "node:path";
12596
+ function generateRunId() {
12597
+ const now = /* @__PURE__ */ new Date();
12598
+ const pad = (n) => String(n).padStart(2, "0");
12599
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
12600
+ }
12601
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
12602
+ const pad = (n) => String(n).padStart(2, "0");
12603
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
12604
+ }
12605
+ function slugify(value) {
12606
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
12607
+ }
12608
+ function generateSessionId3() {
12609
+ const today = datePrefix();
12610
+ const root = debugSessionsDir2();
12611
+ const existing = existsSync6(root) ? readdirSync2(root) : [];
12612
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
12613
+ const maxSeq = existing.reduce((max, entry) => {
12614
+ const match2 = seqPattern.exec(entry);
12615
+ return match2 ? Math.max(max, Number(match2[1])) : max;
12616
+ }, 0);
12617
+ return `${today}-session-${maxSeq + 1}`;
12618
+ }
12619
+ function sessionDebugDir() {
12620
+ return join13(debugSessionsDir2(), SESSION_ID);
12621
+ }
12622
+ function currentDebugSessionDir() {
12623
+ return sessionDebugDir();
12624
+ }
12625
+ async function isDebugModeEnabled() {
12626
+ try {
12627
+ return (await readDebugModeSetting()).enabled;
12628
+ } catch {
12629
+ return true;
12630
+ }
12631
+ }
12632
+ function redact(value) {
12633
+ const clone = { ...value };
12634
+ if ("cma_token" in clone) {
12635
+ const raw = clone.cma_token;
12636
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
12637
+ }
12638
+ return clone;
12639
+ }
12640
+ function startDebugRun({
12641
+ flow,
12642
+ step,
12643
+ menuOption,
12644
+ inputs
12645
+ }) {
12646
+ const runId = generateRunId();
12647
+ const startedAt = Date.now();
12648
+ const redactedInputs = redact(inputs);
12649
+ isDebugModeEnabled().then((enabled) => {
12650
+ if (!enabled) return;
12651
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
12652
+ });
12653
+ }
12654
+ async function finishDebugRun({
12655
+ outputs,
12656
+ status,
9564
12657
  exitMethod
9565
12658
  }) {
9566
12659
  const run2 = pendingRun;
@@ -9580,8 +12673,8 @@ function nextAttemptFilename(dir, menuOption) {
9580
12673
  const existing = existsSync6(dir) ? readdirSync2(dir) : [];
9581
12674
  const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
9582
12675
  const maxAttempt = existing.reduce((max, entry) => {
9583
- const match = attemptPattern.exec(entry);
9584
- return match ? Math.max(max, Number(match[1])) : max;
12676
+ const match2 = attemptPattern.exec(entry);
12677
+ return match2 ? Math.max(max, Number(match2[1])) : max;
9585
12678
  }, 0);
9586
12679
  return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
9587
12680
  }
@@ -9678,21 +12771,21 @@ var init_help_info = __esm({
9678
12771
  });
9679
12772
 
9680
12773
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
9681
- import { useEffect as useEffect6, useState as useState9 } from "react";
9682
- import { Box as Box10, Text as Text11, useInput as useInput9 } from "ink";
9683
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
12774
+ import { useEffect as useEffect9, useState as useState14 } from "react";
12775
+ import { Box as Box21, Text as Text23, useInput as useInput9 } from "ink";
12776
+ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
9684
12777
  function Section({ title, rows }) {
9685
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
9686
- /* @__PURE__ */ jsx13(Text11, { bold: true, color: PALETTE.accent, children: title }),
9687
- rows.map((row) => /* @__PURE__ */ jsxs10(Box10, { gap: 1, children: [
9688
- /* @__PURE__ */ jsx13(Box10, { width: 14, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text11, { color: PALETTE.muted, children: row.label }) }),
9689
- /* @__PURE__ */ jsx13(Text11, { children: row.value })
12778
+ return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", children: [
12779
+ /* @__PURE__ */ jsx25(Text23, { bold: true, color: PALETTE.accent, children: title }),
12780
+ rows.map((row) => /* @__PURE__ */ jsxs22(Box21, { gap: 1, children: [
12781
+ /* @__PURE__ */ jsx25(Box21, { width: 14, flexShrink: 0, children: /* @__PURE__ */ jsx25(Text23, { color: PALETTE.muted, children: row.label }) }),
12782
+ /* @__PURE__ */ jsx25(Text23, { children: row.value })
9690
12783
  ] }, row.label))
9691
12784
  ] });
9692
12785
  }
9693
12786
  function HelpScreen({ onDone }) {
9694
- const [info, setInfo] = useState9();
9695
- useEffect6(() => {
12787
+ const [info, setInfo] = useState14();
12788
+ useEffect9(() => {
9696
12789
  startDebugRun({ flow: "help", step: "01-help", menuOption: "Help", inputs: {} });
9697
12790
  void readHelpInfo().then(setInfo);
9698
12791
  }, []);
@@ -9710,14 +12803,14 @@ function HelpScreen({ onDone }) {
9710
12803
  return;
9711
12804
  }
9712
12805
  });
9713
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingX: 2, paddingY: 1, gap: 1, children: [
9714
- /* @__PURE__ */ jsx13(Text11, { bold: true, children: "Help" }),
9715
- info ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
9716
- /* @__PURE__ */ jsx13(Section, { title: "Where things are stored", rows: info.storage }),
9717
- /* @__PURE__ */ jsx13(Section, { title: "Troubleshooting", rows: info.troubleshooting }),
9718
- /* @__PURE__ */ jsx13(Text11, { color: PALETTE.muted, children: "Hit a problem? Turn on Debug Mode in Settings, reproduce it, then share the session folder above. The CMA token is redacted from those logs." })
9719
- ] }) : /* @__PURE__ */ jsx13(Text11, { color: PALETTE.accent, children: "Loading..." }),
9720
- /* @__PURE__ */ jsx13(
12806
+ return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", paddingX: 2, paddingY: 1, gap: 1, children: [
12807
+ /* @__PURE__ */ jsx25(Text23, { bold: true, children: "Help" }),
12808
+ info ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
12809
+ /* @__PURE__ */ jsx25(Section, { title: "Where things are stored", rows: info.storage }),
12810
+ /* @__PURE__ */ jsx25(Section, { title: "Troubleshooting", rows: info.troubleshooting }),
12811
+ /* @__PURE__ */ jsx25(Text23, { color: PALETTE.muted, children: "Hit a problem? Turn on Debug Mode in Settings, reproduce it, then share the session folder above. The CMA token is redacted from those logs." })
12812
+ ] }) : /* @__PURE__ */ jsx25(Text23, { color: PALETTE.accent, children: "Loading..." }),
12813
+ /* @__PURE__ */ jsx25(
9721
12814
  ControlHints,
9722
12815
  {
9723
12816
  hints: [
@@ -9739,14 +12832,14 @@ var init_PageContainer2 = __esm({
9739
12832
  });
9740
12833
 
9741
12834
  // packages/experience-design-system-cli/src/tui/settings/PageContainer.tsx
9742
- import { useState as useState10 } from "react";
9743
- import { Box as Box11, Text as Text12, useInput as useInput10 } from "ink";
9744
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
12835
+ import { useState as useState15 } from "react";
12836
+ import { Box as Box22, Text as Text24, useInput as useInput10 } from "ink";
12837
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
9745
12838
  function SettingsScreen({
9746
12839
  onNavigate,
9747
12840
  onBack
9748
12841
  }) {
9749
- const [focusIdx, setFocusIdx] = useState10(0);
12842
+ const [focusIdx, setFocusIdx] = useState15(0);
9750
12843
  const items = [
9751
12844
  { label: "Configuration", screen: "settings-configuration" },
9752
12845
  { label: "Opt-in Analytics", screen: "settings-opt-in-analytics" },
@@ -9772,15 +12865,15 @@ function SettingsScreen({
9772
12865
  onBack();
9773
12866
  }
9774
12867
  });
9775
- return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
9776
- /* @__PURE__ */ jsx14(Text12, { bold: true, children: "Settings" }),
9777
- /* @__PURE__ */ jsx14(Text12, { children: " " }),
9778
- items.map((item, i) => /* @__PURE__ */ jsxs11(Text12, { color: i === focusIdx ? "cyan" : void 0, children: [
12868
+ return /* @__PURE__ */ jsxs23(Box22, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
12869
+ /* @__PURE__ */ jsx26(Text24, { bold: true, children: "Settings" }),
12870
+ /* @__PURE__ */ jsx26(Text24, { children: " " }),
12871
+ items.map((item, i) => /* @__PURE__ */ jsxs23(Text24, { color: i === focusIdx ? "cyan" : void 0, children: [
9779
12872
  i === focusIdx ? "> " : " ",
9780
12873
  item.label
9781
12874
  ] }, item.label)),
9782
- /* @__PURE__ */ jsx14(Text12, { children: " " }),
9783
- /* @__PURE__ */ jsx14(
12875
+ /* @__PURE__ */ jsx26(Text24, { children: " " }),
12876
+ /* @__PURE__ */ jsx26(
9784
12877
  ControlHints,
9785
12878
  {
9786
12879
  hints: [
@@ -9841,10 +12934,10 @@ var init_config_store = __esm({
9841
12934
  });
9842
12935
 
9843
12936
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
9844
- import { useEffect as useEffect7, useState as useState11 } from "react";
9845
- import { Box as Box12, Text as Text13, useInput as useInput11 } from "ink";
12937
+ import { useEffect as useEffect10, useState as useState16 } from "react";
12938
+ import { Box as Box23, Text as Text25, useInput as useInput11 } from "ink";
9846
12939
  import TextInput4 from "ink-text-input";
9847
- import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
12940
+ import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
9848
12941
  function debugFields(config) {
9849
12942
  return {
9850
12943
  space_id: config?.spaceId ?? "",
@@ -9856,14 +12949,14 @@ function debugFields(config) {
9856
12949
  };
9857
12950
  }
9858
12951
  function ConfigurationScreen({ onDone }) {
9859
- const [stage, setStage] = useState11("loading");
9860
- const [config, setConfig] = useState11(null);
9861
- const [activeField, setActiveField] = useState11("spaceId");
9862
- const [notice, setNotice] = useState11(null);
9863
- const [lastSaved, setLastSaved] = useState11(null);
9864
- const [editing, setEditing] = useState11(false);
9865
- const [valueBeforeEdit, setValueBeforeEdit] = useState11("");
9866
- useEffect7(() => {
12952
+ const [stage, setStage] = useState16("loading");
12953
+ const [config, setConfig] = useState16(null);
12954
+ const [activeField, setActiveField] = useState16("spaceId");
12955
+ const [notice, setNotice] = useState16(null);
12956
+ const [lastSaved, setLastSaved] = useState16(null);
12957
+ const [editing, setEditing] = useState16(false);
12958
+ const [valueBeforeEdit, setValueBeforeEdit] = useState16("");
12959
+ useEffect10(() => {
9867
12960
  readCredentials().then((cfg) => {
9868
12961
  setConfig(cfg);
9869
12962
  setStage("form");
@@ -9940,26 +13033,26 @@ function ConfigurationScreen({ onDone }) {
9940
13033
  }
9941
13034
  });
9942
13035
  if (stage === "loading") {
9943
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
9944
- /* @__PURE__ */ jsx15(Text13, { bold: true, children: "Configuration" }),
9945
- /* @__PURE__ */ jsx15(Text13, { children: " " }),
9946
- /* @__PURE__ */ jsx15(Text13, { color: PALETTE.accent, children: "Loading..." })
13036
+ return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
13037
+ /* @__PURE__ */ jsx27(Text25, { bold: true, children: "Configuration" }),
13038
+ /* @__PURE__ */ jsx27(Text25, { children: " " }),
13039
+ /* @__PURE__ */ jsx27(Text25, { color: PALETTE.accent, children: "Loading..." })
9947
13040
  ] });
9948
13041
  }
9949
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
9950
- /* @__PURE__ */ jsx15(Text13, { bold: true, children: "Configuration" }),
9951
- /* @__PURE__ */ jsx15(Text13, { children: " " }),
9952
- /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
13042
+ return /* @__PURE__ */ jsxs24(Box23, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
13043
+ /* @__PURE__ */ jsx27(Text25, { bold: true, children: "Configuration" }),
13044
+ /* @__PURE__ */ jsx27(Text25, { children: " " }),
13045
+ /* @__PURE__ */ jsx27(Box23, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
9953
13046
  const isActive = activeField === field;
9954
13047
  const value = fieldValue(field);
9955
13048
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
9956
- return /* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
9957
- /* @__PURE__ */ jsx15(Text13, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
9958
- /* @__PURE__ */ jsxs12(Text13, { bold: isActive, children: [
13049
+ return /* @__PURE__ */ jsxs24(Box23, { gap: 1, children: [
13050
+ /* @__PURE__ */ jsx27(Text25, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
13051
+ /* @__PURE__ */ jsxs24(Text25, { bold: isActive, children: [
9959
13052
  FIELD_LABELS[field],
9960
13053
  ":"
9961
13054
  ] }),
9962
- isActive && editing ? /* @__PURE__ */ jsx15(
13055
+ isActive && editing ? /* @__PURE__ */ jsx27(
9963
13056
  TextInput4,
9964
13057
  {
9965
13058
  value,
@@ -9967,19 +13060,19 @@ function ConfigurationScreen({ onDone }) {
9967
13060
  onSubmit: () => setEditing(false),
9968
13061
  mask: field === "cmaToken" ? "\u2022" : void 0
9969
13062
  }
9970
- ) : /* @__PURE__ */ jsx15(Text13, { children: display || /* @__PURE__ */ jsx15(Text13, { color: PALETTE.muted, children: "(empty)" }) })
13063
+ ) : /* @__PURE__ */ jsx27(Text25, { children: display || /* @__PURE__ */ jsx27(Text25, { color: PALETTE.muted, children: "(empty)" }) })
9971
13064
  ] }, field);
9972
13065
  }) }),
9973
- notice && /* @__PURE__ */ jsxs12(Fragment3, { children: [
9974
- /* @__PURE__ */ jsx15(Text13, { children: " " }),
9975
- /* @__PURE__ */ jsxs12(Text13, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
13066
+ notice && /* @__PURE__ */ jsxs24(Fragment6, { children: [
13067
+ /* @__PURE__ */ jsx27(Text25, { children: " " }),
13068
+ /* @__PURE__ */ jsxs24(Text25, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
9976
13069
  notice.kind === "success" ? "\u2713" : "\u2717",
9977
13070
  " ",
9978
13071
  notice.text
9979
13072
  ] })
9980
13073
  ] }),
9981
- /* @__PURE__ */ jsx15(Text13, { children: " " }),
9982
- /* @__PURE__ */ jsx15(
13074
+ /* @__PURE__ */ jsx27(Text25, { children: " " }),
13075
+ /* @__PURE__ */ jsx27(
9983
13076
  ControlHints,
9984
13077
  {
9985
13078
  hints: editing ? [
@@ -10047,13 +13140,13 @@ var init_analytics_store = __esm({
10047
13140
  });
10048
13141
 
10049
13142
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
10050
- import { useEffect as useEffect8, useState as useState12 } from "react";
10051
- import { Box as Box13, Text as Text14, useInput as useInput12 } from "ink";
10052
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
13143
+ import { useEffect as useEffect11, useState as useState17 } from "react";
13144
+ import { Box as Box24, Text as Text26, useInput as useInput12 } from "ink";
13145
+ import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
10053
13146
  function OptInAnalyticsScreen({ onDone }) {
10054
- const [loading, setLoading] = useState12(true);
10055
- const [enabled, setEnabled] = useState12(true);
10056
- useEffect8(() => {
13147
+ const [loading, setLoading] = useState17(true);
13148
+ const [enabled, setEnabled] = useState17(true);
13149
+ useEffect11(() => {
10057
13150
  readAnalyticsSetting().then((setting) => {
10058
13151
  setEnabled(setting.enabled);
10059
13152
  setLoading(false);
@@ -10080,21 +13173,21 @@ function OptInAnalyticsScreen({ onDone }) {
10080
13173
  onDone();
10081
13174
  }
10082
13175
  });
10083
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
10084
- /* @__PURE__ */ jsx16(Text14, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
10085
- /* @__PURE__ */ jsx16(Text14, { children: " " }),
10086
- loading ? /* @__PURE__ */ jsx16(Text14, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
10087
- /* @__PURE__ */ jsxs13(Text14, { children: [
13176
+ return /* @__PURE__ */ jsxs25(Box24, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
13177
+ /* @__PURE__ */ jsx28(Text26, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
13178
+ /* @__PURE__ */ jsx28(Text26, { children: " " }),
13179
+ loading ? /* @__PURE__ */ jsx28(Text26, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs25(Fragment7, { children: [
13180
+ /* @__PURE__ */ jsxs25(Text26, { children: [
10088
13181
  "Share anonymous usage data:",
10089
13182
  " ",
10090
- /* @__PURE__ */ jsx16(Text14, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
13183
+ /* @__PURE__ */ jsx28(Text26, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
10091
13184
  ] }),
10092
- /* @__PURE__ */ jsx16(Text14, { children: " " }),
10093
- /* @__PURE__ */ jsx16(Text14, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
10094
- /* @__PURE__ */ jsx16(Text14, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
13185
+ /* @__PURE__ */ jsx28(Text26, { children: " " }),
13186
+ /* @__PURE__ */ jsx28(Text26, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
13187
+ /* @__PURE__ */ jsx28(Text26, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
10095
13188
  ] }),
10096
- /* @__PURE__ */ jsx16(Text14, { children: " " }),
10097
- /* @__PURE__ */ jsx16(
13189
+ /* @__PURE__ */ jsx28(Text26, { children: " " }),
13190
+ /* @__PURE__ */ jsx28(
10098
13191
  ControlHints,
10099
13192
  {
10100
13193
  hints: [
@@ -10105,7 +13198,7 @@ function OptInAnalyticsScreen({ onDone }) {
10105
13198
  )
10106
13199
  ] });
10107
13200
  }
10108
- var init_screen7 = __esm({
13201
+ var init_screen8 = __esm({
10109
13202
  "packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx"() {
10110
13203
  "use strict";
10111
13204
  init_home_theme();
@@ -10116,12 +13209,12 @@ var init_screen7 = __esm({
10116
13209
  });
10117
13210
 
10118
13211
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
10119
- import { useEffect as useEffect9, useState as useState13 } from "react";
10120
- import { Box as Box14, Text as Text15, useInput as useInput13 } from "ink";
10121
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
13212
+ import { useEffect as useEffect12, useState as useState18 } from "react";
13213
+ import { Box as Box25, Text as Text27, useInput as useInput13 } from "ink";
13214
+ import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
10122
13215
  function UpgradeScreen({ onDone }) {
10123
- const [upgradeCheck, setUpgradeCheck] = useState13();
10124
- useEffect9(() => {
13216
+ const [upgradeCheck, setUpgradeCheck] = useState18();
13217
+ useEffect12(() => {
10125
13218
  startDebugRun({
10126
13219
  flow: "upgrade",
10127
13220
  step: "01-upgrade",
@@ -10141,12 +13234,12 @@ function UpgradeScreen({ onDone }) {
10141
13234
  return;
10142
13235
  }
10143
13236
  });
10144
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
10145
- /* @__PURE__ */ jsx17(Text15, { bold: true, children: "Upgrade" }),
10146
- /* @__PURE__ */ jsx17(Text15, { children: " " }),
13237
+ return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
13238
+ /* @__PURE__ */ jsx29(Text27, { bold: true, children: "Upgrade" }),
13239
+ /* @__PURE__ */ jsx29(Text27, { children: " " }),
10147
13240
  renderBody(upgradeCheck),
10148
- /* @__PURE__ */ jsx17(Text15, { children: " " }),
10149
- /* @__PURE__ */ jsxs14(Text15, { bold: true, color: PALETTE.accent, children: [
13241
+ /* @__PURE__ */ jsx29(Text27, { children: " " }),
13242
+ /* @__PURE__ */ jsxs26(Text27, { bold: true, color: PALETTE.accent, children: [
10150
13243
  FOCUS_MARKER,
10151
13244
  " Go Back"
10152
13245
  ] })
@@ -10154,34 +13247,34 @@ function UpgradeScreen({ onDone }) {
10154
13247
  }
10155
13248
  function renderBody(upgradeCheck) {
10156
13249
  if (!upgradeCheck) {
10157
- return /* @__PURE__ */ jsx17(Text15, { color: PALETTE.muted, children: "Checking for updates\u2026" });
13250
+ return /* @__PURE__ */ jsx29(Text27, { color: PALETTE.muted, children: "Checking for updates\u2026" });
10158
13251
  }
10159
13252
  if (upgradeCheck.status === "error") {
10160
- return /* @__PURE__ */ jsx17(Text15, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
13253
+ return /* @__PURE__ */ jsx29(Text27, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
10161
13254
  }
10162
13255
  if (upgradeCheck.status === "up-to-date") {
10163
- return /* @__PURE__ */ jsxs14(Text15, { color: PALETTE.success, children: [
13256
+ return /* @__PURE__ */ jsxs26(Text27, { color: PALETTE.success, children: [
10164
13257
  "You're already on the latest version (v",
10165
13258
  upgradeCheck.current,
10166
13259
  ")."
10167
13260
  ] });
10168
13261
  }
10169
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
10170
- /* @__PURE__ */ jsxs14(Text15, { color: PALETTE.muted, children: [
10171
- /* @__PURE__ */ jsxs14(Text15, { bold: true, color: PALETTE.success, children: [
13262
+ return /* @__PURE__ */ jsxs26(Box25, { flexDirection: "column", children: [
13263
+ /* @__PURE__ */ jsxs26(Text27, { color: PALETTE.muted, children: [
13264
+ /* @__PURE__ */ jsxs26(Text27, { bold: true, color: PALETTE.success, children: [
10172
13265
  "v",
10173
13266
  upgradeCheck.latest
10174
13267
  ] }),
10175
13268
  " ",
10176
13269
  "is available (you're on ",
10177
- /* @__PURE__ */ jsxs14(Text15, { bold: true, children: [
13270
+ /* @__PURE__ */ jsxs26(Text27, { bold: true, children: [
10178
13271
  "v",
10179
13272
  upgradeCheck.current
10180
13273
  ] }),
10181
13274
  "). Exit this program, cd into the root of your local clone of contentful/experience-design-system-sdk-public, then run:"
10182
13275
  ] }),
10183
- /* @__PURE__ */ jsx17(Text15, { children: " " }),
10184
- /* @__PURE__ */ jsx17(Box14, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx17(Text15, { bold: true, children: cmd }, cmd)) })
13276
+ /* @__PURE__ */ jsx29(Text27, { children: " " }),
13277
+ /* @__PURE__ */ jsx29(Box25, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx29(Text27, { bold: true, children: cmd }, cmd)) })
10185
13278
  ] });
10186
13279
  }
10187
13280
  var UPGRADE_COMMANDS;
@@ -10196,13 +13289,13 @@ var init_PageContainer4 = __esm({
10196
13289
  });
10197
13290
 
10198
13291
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
10199
- import { useEffect as useEffect10, useState as useState14 } from "react";
10200
- import { Box as Box15, Text as Text16, useInput as useInput14 } from "ink";
10201
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
13292
+ import { useEffect as useEffect13, useState as useState19 } from "react";
13293
+ import { Box as Box26, Text as Text28, useInput as useInput14 } from "ink";
13294
+ import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
10202
13295
  function DebugModeScreen({ onDone }) {
10203
- const [loading, setLoading] = useState14(true);
10204
- const [enabled, setEnabled] = useState14(true);
10205
- useEffect10(() => {
13296
+ const [loading, setLoading] = useState19(true);
13297
+ const [enabled, setEnabled] = useState19(true);
13298
+ useEffect13(() => {
10206
13299
  readDebugModeSetting().then((setting) => {
10207
13300
  setEnabled(setting.enabled);
10208
13301
  setLoading(false);
@@ -10229,16 +13322,16 @@ function DebugModeScreen({ onDone }) {
10229
13322
  onDone();
10230
13323
  }
10231
13324
  });
10232
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
10233
- /* @__PURE__ */ jsx18(Text16, { bold: true, children: "Settings \u203A Debug Mode" }),
10234
- /* @__PURE__ */ jsx18(Text16, { children: " " }),
10235
- loading ? /* @__PURE__ */ jsx18(Text16, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs15(Text16, { children: [
13325
+ return /* @__PURE__ */ jsxs27(Box26, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
13326
+ /* @__PURE__ */ jsx30(Text28, { bold: true, children: "Settings \u203A Debug Mode" }),
13327
+ /* @__PURE__ */ jsx30(Text28, { children: " " }),
13328
+ loading ? /* @__PURE__ */ jsx30(Text28, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs27(Text28, { children: [
10236
13329
  "Debug logging:",
10237
13330
  " ",
10238
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
13331
+ /* @__PURE__ */ jsx30(Text28, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
10239
13332
  ] }),
10240
- /* @__PURE__ */ jsx18(Text16, { children: " " }),
10241
- /* @__PURE__ */ jsx18(
13333
+ /* @__PURE__ */ jsx30(Text28, { children: " " }),
13334
+ /* @__PURE__ */ jsx30(
10242
13335
  ControlHints,
10243
13336
  {
10244
13337
  hints: [
@@ -10249,7 +13342,7 @@ function DebugModeScreen({ onDone }) {
10249
13342
  )
10250
13343
  ] });
10251
13344
  }
10252
- var init_screen8 = __esm({
13345
+ var init_screen9 = __esm({
10253
13346
  "packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx"() {
10254
13347
  "use strict";
10255
13348
  init_home_theme();
@@ -10265,20 +13358,35 @@ __export(app_exports, {
10265
13358
  runApp: () => runApp
10266
13359
  });
10267
13360
  import { join as join14 } from "node:path";
10268
- import { useEffect as useEffect11, useState as useState15 } from "react";
10269
- import { Fragment as Fragment5, jsx as jsx19 } from "react/jsx-runtime";
13361
+ import { useEffect as useEffect14, useState as useState20 } from "react";
13362
+ import { Fragment as Fragment8, jsx as jsx31 } from "react/jsx-runtime";
10270
13363
  function App({ importOptions, onLaunchImport, importExitCode }) {
10271
13364
  const returnedFromImport = importExitCode !== void 0;
10272
- const [screen, setScreen] = useState15(returnedFromImport ? "import" : "start");
10273
- const [showImportResult, setShowImportResult] = useState15(returnedFromImport);
10274
- const [projectPath, setProjectPath] = useState15();
10275
- const [tokensPath, setTokensPath] = useState15();
10276
- const [scannedFiles, setScannedFiles] = useState15();
10277
- const [pendingLaunch, setPendingLaunch] = useState15();
10278
- const [extractionRun, setExtractionRun] = useState15();
13365
+ const [screen, setScreen] = useState20(returnedFromImport ? "import" : "start");
13366
+ const [showImportResult, setShowImportResult] = useState20(returnedFromImport);
13367
+ const [projectPath, setProjectPath] = useState20();
13368
+ const [tokensPath, setTokensPath] = useState20();
13369
+ const [scannedFiles, setScannedFiles] = useState20();
13370
+ const [pendingLaunch, setPendingLaunch] = useState20();
13371
+ const [extractionRun, setExtractionRun] = useState20();
10279
13372
  const extraction = useExtraction(extractionRun?.input);
10280
- const [importDefaults, setImportDefaults] = useState15();
10281
- useEffect11(() => {
13373
+ const [scopeRun, setScopeRun] = useState20();
13374
+ const scopeFlow = useScopeGateFlow(
13375
+ scopeRun && {
13376
+ sessionId: scopeRun.extraction.sessionId,
13377
+ cache: {
13378
+ sessionId: scopeRun.extraction.sessionId,
13379
+ tokensPath: scopeRun.extraction.tokensPath,
13380
+ agent: scopeRun.input.agent,
13381
+ ...scopeRun.input.agentModel ? { agentModel: scopeRun.input.agentModel } : {},
13382
+ promptOverrides: scopeRun.input.promptOverrides,
13383
+ existingEntitiesPath: scopeRun.extraction.existingEntitiesPath,
13384
+ noCache: scopeRun.input.noCache
13385
+ }
13386
+ }
13387
+ );
13388
+ const [importDefaults, setImportDefaults] = useState20();
13389
+ useEffect14(() => {
10282
13390
  if (screen !== "import") {
10283
13391
  setImportDefaults(void 0);
10284
13392
  return;
@@ -10332,15 +13440,25 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10332
13440
  }
10333
13441
  });
10334
13442
  };
10335
- useEffect11(() => {
13443
+ useEffect14(() => {
10336
13444
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
10337
- const { launch, credentialsSkipped, tokenStrategy } = extractionRun;
10338
13445
  setExtractionRun(void 0);
13446
+ setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
13447
+ }, [extraction, extractionRun]);
13448
+ useEffect14(() => {
13449
+ if (!scopeRun || scopeFlow?.status !== "confirmed") return;
13450
+ const { launch, credentialsSkipped, tokenStrategy, extraction: produced } = scopeRun;
13451
+ setScopeRun(void 0);
10339
13452
  onLaunchImport?.({
10340
13453
  ...launch,
10341
- handoff: { credentialsSkipped, tokens: { strategy: tokenStrategy }, extraction: extraction.result.extraction }
13454
+ handoff: {
13455
+ credentialsSkipped,
13456
+ tokens: { strategy: tokenStrategy },
13457
+ extraction: produced,
13458
+ scope: scopeFlow.scope
13459
+ }
10342
13460
  });
10343
- }, [extraction, extractionRun]);
13461
+ }, [scopeFlow, scopeRun]);
10344
13462
  const goToStart = () => setScreen("start");
10345
13463
  const goToSettings = () => setScreen("settings");
10346
13464
  const resetImport = () => {
@@ -10349,6 +13467,7 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10349
13467
  setScannedFiles(void 0);
10350
13468
  setPendingLaunch(void 0);
10351
13469
  setExtractionRun(void 0);
13470
+ setScopeRun(void 0);
10352
13471
  };
10353
13472
  const finishImportResult = () => {
10354
13473
  setShowImportResult(false);
@@ -10361,13 +13480,13 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10361
13480
  };
10362
13481
  switch (screen) {
10363
13482
  case "import":
10364
- if (showImportResult) return /* @__PURE__ */ jsx19(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
10365
- if (importDefaults === void 0) return /* @__PURE__ */ jsx19(Fragment5, {});
13483
+ if (showImportResult) return /* @__PURE__ */ jsx31(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
13484
+ if (importDefaults === void 0) return /* @__PURE__ */ jsx31(Fragment8, {});
10366
13485
  if (projectPath === void 0) {
10367
- return /* @__PURE__ */ jsx19(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
13486
+ return /* @__PURE__ */ jsx31(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
10368
13487
  }
10369
13488
  if (tokensPath === void 0) {
10370
- return /* @__PURE__ */ jsx19(
13489
+ return /* @__PURE__ */ jsx31(
10371
13490
  TokenInputScreen,
10372
13491
  {
10373
13492
  initialPath: importDefaults.tokenFile,
@@ -10377,7 +13496,7 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10377
13496
  );
10378
13497
  }
10379
13498
  if (scannedFiles === void 0) {
10380
- return /* @__PURE__ */ jsx19(
13499
+ return /* @__PURE__ */ jsx31(
10381
13500
  PathValidationScreen,
10382
13501
  {
10383
13502
  projectPath,
@@ -10389,10 +13508,10 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10389
13508
  }
10390
13509
  if (extractionRun) {
10391
13510
  if (extraction?.status === "done" && !extraction.result.ok) {
10392
- return /* @__PURE__ */ jsx19(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
13511
+ return /* @__PURE__ */ jsx31(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
10393
13512
  }
10394
13513
  if (extraction?.status === "running") {
10395
- return /* @__PURE__ */ jsx19(
13514
+ return /* @__PURE__ */ jsx31(
10396
13515
  ExtractionScreen,
10397
13516
  {
10398
13517
  progress: extraction.progress,
@@ -10401,10 +13520,35 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10401
13520
  }
10402
13521
  );
10403
13522
  }
10404
- return /* @__PURE__ */ jsx19(Fragment5, {});
13523
+ return /* @__PURE__ */ jsx31(Fragment8, {});
13524
+ }
13525
+ if (scopeRun && scopeFlow) {
13526
+ if (scopeFlow.status === "failed") {
13527
+ return /* @__PURE__ */ jsx31(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
13528
+ }
13529
+ if (scopeFlow.status === "deciding") {
13530
+ return /* @__PURE__ */ jsx31(
13531
+ ScopeGateScreen,
13532
+ {
13533
+ components: scopeFlow.load.components,
13534
+ onConfirm: scopeFlow.confirm,
13535
+ onQuit: leaveImport
13536
+ }
13537
+ );
13538
+ }
13539
+ const numbers = stepNumbers({ hasRawTokens: scopeRun.input.rawTokensPath !== "" });
13540
+ return /* @__PURE__ */ jsx31(
13541
+ RunningStep,
13542
+ {
13543
+ stepNumber: numbers.stepNumber + 1,
13544
+ totalSteps: numbers.totalSteps,
13545
+ title: "Preparing",
13546
+ description: "Checking which components are already generated..."
13547
+ }
13548
+ );
10405
13549
  }
10406
13550
  if (pendingLaunch?.cached) {
10407
- return /* @__PURE__ */ jsx19(
13551
+ return /* @__PURE__ */ jsx31(
10408
13552
  TokenReuseScreen,
10409
13553
  {
10410
13554
  tokensPath: pendingLaunch.cached.tokensPath,
@@ -10415,7 +13559,7 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10415
13559
  }
10416
13560
  );
10417
13561
  }
10418
- return /* @__PURE__ */ jsx19(
13562
+ return /* @__PURE__ */ jsx31(
10419
13563
  CredentialsScreen,
10420
13564
  {
10421
13565
  initial: importDefaults.credentials,
@@ -10424,25 +13568,25 @@ function App({ importOptions, onLaunchImport, importExitCode }) {
10424
13568
  }
10425
13569
  );
10426
13570
  case "help":
10427
- return /* @__PURE__ */ jsx19(HelpScreen, { onDone: goToStart });
13571
+ return /* @__PURE__ */ jsx31(HelpScreen, { onDone: goToStart });
10428
13572
  case "upgrade":
10429
- return /* @__PURE__ */ jsx19(UpgradeScreen, { onDone: goToStart });
13573
+ return /* @__PURE__ */ jsx31(UpgradeScreen, { onDone: goToStart });
10430
13574
  case "settings":
10431
- return /* @__PURE__ */ jsx19(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
13575
+ return /* @__PURE__ */ jsx31(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
10432
13576
  case "settings-configuration":
10433
- return /* @__PURE__ */ jsx19(ConfigurationScreen, { onDone: goToSettings });
13577
+ return /* @__PURE__ */ jsx31(ConfigurationScreen, { onDone: goToSettings });
10434
13578
  case "settings-opt-in-analytics":
10435
- return /* @__PURE__ */ jsx19(OptInAnalyticsScreen, { onDone: goToSettings });
13579
+ return /* @__PURE__ */ jsx31(OptInAnalyticsScreen, { onDone: goToSettings });
10436
13580
  case "settings-debug-mode":
10437
- return /* @__PURE__ */ jsx19(DebugModeScreen, { onDone: goToSettings });
13581
+ return /* @__PURE__ */ jsx31(DebugModeScreen, { onDone: goToSettings });
10438
13582
  case "start":
10439
- return /* @__PURE__ */ jsx19(HomeScreen, { onNavigate: setScreen });
13583
+ return /* @__PURE__ */ jsx31(HomeScreen, { onNavigate: setScreen });
10440
13584
  }
10441
13585
  }
10442
13586
  async function renderUntilImportRequestedOrExit(renderApp, importOptions, importExitCode) {
10443
13587
  let requestedImport;
10444
13588
  const instance = renderApp(
10445
- /* @__PURE__ */ jsx19(
13589
+ /* @__PURE__ */ jsx31(
10446
13590
  App,
10447
13591
  {
10448
13592
  importOptions,
@@ -10481,6 +13625,8 @@ var init_app = __esm({
10481
13625
  init_logic9();
10482
13626
  init_config();
10483
13627
  init_use_extraction();
13628
+ init_screen7();
13629
+ init_use_scope_gate_flow();
10484
13630
  init_logic8();
10485
13631
  init_resolve_user_path();
10486
13632
  init_spawn_v1_import();
@@ -10488,9 +13634,9 @@ var init_app = __esm({
10488
13634
  init_PageContainer2();
10489
13635
  init_PageContainer3();
10490
13636
  init_ContentfulConfigScreen();
10491
- init_screen7();
10492
- init_PageContainer4();
10493
13637
  init_screen8();
13638
+ init_PageContainer4();
13639
+ init_screen9();
10494
13640
  init_config_store();
10495
13641
  CLEAR_SCREEN = "\x1B[2J\x1B[H";
10496
13642
  }