@contentful/experience-design-system-cli 2.37.1-dev-build-799db3ac.0 → 2.37.1-dev-build-e5882940.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/app.js +6717 -574
  2. package/dist/index.js +7971 -1380
  3. package/dist/package.json +4 -2
  4. package/dist/src/tui/import/spawn-v1-import.d.ts +3 -3
  5. package/dist/src/tui/import/steps/05-token-reuse/logic.d.ts +1 -2
  6. package/dist/src/tui/import/steps/06-extraction/logic.d.ts +69 -0
  7. package/dist/src/tui/import/steps/06-extraction/processes.d.ts +45 -0
  8. package/dist/src/tui/import/steps/06-extraction/run.d.ts +24 -0
  9. package/dist/src/tui/import/steps/06-extraction/screen.d.ts +10 -0
  10. package/dist/src/tui/import/steps/06-extraction/selection.d.ts +18 -0
  11. package/dist/src/tui/import/steps/06-extraction/types.d.ts +44 -0
  12. package/dist/src/tui/import/steps/06-extraction/use-extraction.d.ts +14 -0
  13. package/dist/src/tui/import/steps/07-scope-gate/cache-check.d.ts +29 -0
  14. package/{legacy/dist/src/import/tui/scope-gate-columns.d.ts → dist/src/tui/import/steps/07-scope-gate/columns.d.ts} +22 -2
  15. package/dist/src/tui/import/steps/07-scope-gate/graph/composite-closure.d.ts +26 -0
  16. package/dist/src/tui/import/steps/07-scope-gate/graph/cycle-detection.d.ts +22 -0
  17. package/dist/src/tui/import/steps/07-scope-gate/graph/fuzzy-search.d.ts +3 -0
  18. package/dist/src/tui/import/steps/07-scope-gate/graph/index.d.ts +33 -0
  19. package/dist/src/tui/import/steps/07-scope-gate/graph/lineage.d.ts +29 -0
  20. package/dist/src/tui/import/steps/07-scope-gate/graph/search-neighborhood.d.ts +3 -0
  21. package/dist/src/tui/import/steps/07-scope-gate/graph/slot-graph.d.ts +11 -0
  22. package/dist/src/tui/import/steps/07-scope-gate/keymap.d.ts +84 -0
  23. package/dist/src/tui/import/steps/07-scope-gate/load.d.ts +8 -0
  24. package/dist/src/tui/import/steps/07-scope-gate/panels/added-column.d.ts +15 -0
  25. package/dist/src/tui/import/steps/07-scope-gate/panels/cycles-panel.d.ts +8 -0
  26. package/dist/src/tui/import/steps/07-scope-gate/panels/reject-prompt.d.ts +5 -0
  27. package/dist/src/tui/import/steps/07-scope-gate/screen.d.ts +9 -0
  28. package/dist/src/tui/import/steps/07-scope-gate/sidebar/autocomplete.d.ts +5 -0
  29. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/CompactControlBar.d.ts +4 -0
  30. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/GotoBanner.d.ts +32 -0
  31. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/GroupedSidebar.d.ts +93 -0
  32. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/HelpOverlay.d.ts +21 -0
  33. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/LegendEntry.d.ts +2 -0
  34. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/SearchMatchSummary.d.ts +11 -0
  35. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/badge.d.ts +13 -0
  36. package/dist/src/tui/import/steps/07-scope-gate/sidebar/components/windowed-panel.d.ts +17 -0
  37. package/dist/src/tui/import/steps/07-scope-gate/sidebar/group-collapse.d.ts +2 -0
  38. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/sidebar-search-state.d.ts +17 -0
  39. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.d.ts +6 -0
  40. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/useImmediateInput.d.ts +20 -0
  41. package/dist/src/tui/import/steps/07-scope-gate/sidebar/hooks/useOverlayPanel.d.ts +13 -0
  42. package/dist/src/tui/import/steps/07-scope-gate/sidebar/lineage-layout.d.ts +68 -0
  43. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-help.d.ts +2 -0
  44. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-input.d.ts +13 -0
  45. package/dist/src/tui/import/steps/07-scope-gate/sidebar/sidebar-navigation.d.ts +18 -0
  46. package/dist/src/tui/import/steps/07-scope-gate/sidebar/step-filters.d.ts +19 -0
  47. package/dist/src/tui/import/steps/07-scope-gate/sidebar/theme.d.ts +8 -0
  48. package/dist/src/tui/import/steps/07-scope-gate/sidebar/types.d.ts +7 -0
  49. package/dist/src/tui/import/steps/07-scope-gate/state.d.ts +19 -0
  50. package/dist/src/tui/import/steps/07-scope-gate/types.d.ts +24 -0
  51. package/dist/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.d.ts +31 -0
  52. package/dist/src/tui/import/steps/07-scope-gate/use-scope-gate.d.ts +76 -0
  53. package/dist/src/tui/import/steps/index.d.ts +1 -0
  54. package/legacy/dist/src/import/tui/WizardApp.d.ts +0 -8
  55. package/legacy/dist/src/import/tui/handoff.d.ts +37 -0
  56. package/legacy/dist/src/index.js +1635 -3407
  57. package/legacy/package.json +4 -2
  58. package/package.json +6 -4
  59. package/skills/generate-components.md +612 -0
  60. package/skills/generate-tokens.md +194 -0
  61. package/skills/map-tokens.md +102 -0
  62. package/skills/select-components.md +235 -0
  63. package/legacy/dist/src/import/tui/run-selection-agent.d.ts +0 -9
  64. package/legacy/dist/src/import/tui/steps/ScopeGateStep.d.ts +0 -48
  65. /package/{legacy/dist/src/analyze → dist/src/tui/import/steps/07-scope-gate/graph}/scope-gate-cascade.d.ts +0 -0
  66. /package/{legacy/dist/src/import/tui → dist/src/tui/import/steps/07-scope-gate/sidebar}/ai-flag.d.ts +0 -0
  67. /package/{legacy/dist/src/import/tui → dist/src/tui/import/steps/07-scope-gate/sidebar}/components/CounterStrip.d.ts +0 -0
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-799db3ac.0",
3
+ "version": "2.37.1-dev-build-e5882940.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,7 +25,8 @@
25
25
  "files": [
26
26
  "bin/",
27
27
  "dist/",
28
- "legacy/"
28
+ "legacy/",
29
+ "skills/"
29
30
  ],
30
31
  "scripts": {
31
32
  "build": "nx build experience-design-system-cli",
@@ -38,6 +39,7 @@
38
39
  },
39
40
  "dependencies": {
40
41
  "@contentful/experience-design-system-backend-pipeline": "workspace:*",
42
+ "@contentful/experience-design-system-generation": "workspace:*",
41
43
  "@contentful/experience-design-system-types": "workspace:*",
42
44
  "@inkjs/ui": "^2.0.0",
43
45
  "@segment/analytics-node": "^3.0.0",
@@ -1,5 +1,5 @@
1
1
  import { type ImportOptions } from '../../commands/import-options.js';
2
- import type { TokenStrategy } from './steps/05-token-reuse/logic.js';
2
+ import { type ImportHandoff } from '@contentful/experience-design-system-types/handoff';
3
3
  interface StepResult {
4
4
  step: string;
5
5
  status: 'complete' | 'failed' | 'skipped';
@@ -20,8 +20,8 @@ export interface SpawnV1ImportOptions extends Partial<ImportOptions> {
20
20
  projectPath?: string;
21
21
  tokens?: string;
22
22
  filePaths?: string[];
23
- skipCredentials?: boolean;
24
- tokenStrategy?: TokenStrategy;
23
+ /** What the CLI already settled and did; the legacy wizard starts from it. */
24
+ handoff?: ImportHandoff;
25
25
  onProgress?: (line: string) => void;
26
26
  }
27
27
  export interface SpawnV1ImportResult {
@@ -1,4 +1,4 @@
1
- export type TokenStrategy = 'reuse' | 'regenerate' | 'generate';
1
+ export type { TokenStrategy } from '../06-extraction/types.js';
2
2
  export type TokensState = {
3
3
  kind: 'none';
4
4
  } | {
@@ -19,4 +19,3 @@ export declare function gateText({ tokensPath, sourceChanged }: {
19
19
  summary: string;
20
20
  context?: string;
21
21
  };
22
- export {};
@@ -0,0 +1,69 @@
1
+ import type { CompositionPhase, ExtractionProgress } from './types.js';
2
+ /** One line of the extract subprocess's stderr, decoded. Lines it does not recognise are ignored. */
3
+ export type ProgressEvent = {
4
+ kind: 'scan';
5
+ scanned: number;
6
+ } | {
7
+ kind: 'scan-done';
8
+ total: number;
9
+ } | {
10
+ kind: 'extract';
11
+ totalFiles: number;
12
+ } | {
13
+ kind: 'composition';
14
+ phase: CompositionPhase;
15
+ };
16
+ /** `progress=scan:12`, `progress=scan-done:40`, `progress=extract:3/40:7`, `progress=composition:cache-hit`. */
17
+ export declare function parseProgressLine(line: string): ProgressEvent | null;
18
+ /** `session=<id>` on the extract subprocess's stdout. It arrives before composition finishes, which is when selection starts. */
19
+ export declare function parseSessionLine(line: string): string | null;
20
+ /** The first `session=<id>` anywhere in a command's stdout. */
21
+ export declare function findSession(stdout: string): string | null;
22
+ /** `Extracted 7 components` in the extract command's stderr; 0 when it never printed one. */
23
+ export declare function parseExtractedCount(stderr: string): number;
24
+ /** `(12 tokens` in the output of `print tokens`. */
25
+ export declare function parsePrintTokensCount(stdout: string): number;
26
+ /**
27
+ * Every job the stage will run starts on the first frame, so no row appears later as a surprise. A job that does not
28
+ * apply stays 'idle' and has no row: existing entities need credentials, token definitions need a raw tokens file, and
29
+ * reused tokens are already complete.
30
+ */
31
+ export declare function initialProgress(input: {
32
+ hasCredentials: boolean;
33
+ hasRawTokens: boolean;
34
+ reuseTokens: boolean;
35
+ }): ExtractionProgress;
36
+ export declare function applyProgressEvent(progress: ExtractionProgress, event: ProgressEvent): ExtractionProgress;
37
+ /** The rows the screen shows, in the order the wizard showed them. Rows that do not apply are left out. */
38
+ export declare function progressRows(progress: ExtractionProgress, agent: string): Array<{
39
+ text: string;
40
+ complete: boolean;
41
+ }>;
42
+ /** True when every job is already done, so the screen would only flash. The wizard shows nothing in this case. */
43
+ export declare function isFullCacheHit(progress: ExtractionProgress): boolean;
44
+ /**
45
+ * The wizard's step counts: three fixed steps, one more when there is a token stage, two more when components are
46
+ * imported, and one more when the tokens can be mapped (not known yet at this stage, so it adds nothing here).
47
+ * Extraction is step 2 when there is a token stage, otherwise step 1.
48
+ */
49
+ export declare function stepNumbers(input: {
50
+ hasRawTokens: boolean;
51
+ skipComponents?: boolean;
52
+ mapTokensEligible?: boolean | null;
53
+ }): {
54
+ stepNumber: number;
55
+ totalSteps: number;
56
+ };
57
+ export declare function noComponentsMessage(projectPath: string): string;
58
+ export declare function agentAuthMessage(agent: string, status: 'not-found' | 'unauthenticated'): string;
59
+ /**
60
+ * The agent and model the import runs with: what was typed after `--agent` (either `agent` or `agent:model`), else
61
+ * what `experiences setup` saved, else Claude with no model. Same chain the legacy import command uses.
62
+ */
63
+ export declare function resolveAgentChoice(flag: string | undefined, stored: {
64
+ agent?: unknown;
65
+ agentModel?: unknown;
66
+ }): {
67
+ agent: string;
68
+ agentModel?: string;
69
+ };
@@ -0,0 +1,45 @@
1
+ /** The legacy commands the stage drives, started the way the wizard starts them. */
2
+ export interface SpawnedResult {
3
+ exitCode: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ }
7
+ export interface ExtractCommand {
8
+ projectPath: string;
9
+ agent: string;
10
+ promptOverrides: string[];
11
+ noCache: boolean;
12
+ }
13
+ export interface TokenGenerationInput {
14
+ rawTokensPath: string;
15
+ outDir: string;
16
+ agent: string;
17
+ agentModel?: string;
18
+ promptOverrides: string[];
19
+ noCache: boolean;
20
+ }
21
+ export type TokenGenerationResult = {
22
+ ok: true;
23
+ tokensPath: string;
24
+ tokenSessionId: string | null;
25
+ tokenCount: number;
26
+ } | {
27
+ ok: false;
28
+ step: 'generate tokens' | 'print tokens';
29
+ message: string;
30
+ };
31
+ /** Splits a stream into lines as chunks arrive, holding back a trailing partial line until the next chunk completes it. */
32
+ export declare function lineSplitter(onLine: (line: string) => void): (chunk: string) => void;
33
+ /** Arguments for `__extract`, in the order the wizard passes them. The extract command takes an agent but no model. */
34
+ export declare function buildExtractArgs(cliPath: string, command: ExtractCommand): string[];
35
+ /** Arguments for `__generate tokens`, in the order the wizard passes them. */
36
+ export declare function buildGenerateTokensArgs(cliPath: string, input: TokenGenerationInput): string[];
37
+ /** Arguments for `print tokens`, which writes the generated catalog next to the project. */
38
+ export declare function buildPrintTokensArgs(tokensPath: string, tokenSessionId: string | null): string[];
39
+ /** `node <legacy cli> __extract …`, with stderr and stdout delivered line by line while it runs. */
40
+ export declare function spawnExtract(command: ExtractCommand, handlers: {
41
+ onStderrLine: (line: string) => void;
42
+ onStdoutLine: (line: string) => void;
43
+ }): Promise<SpawnedResult>;
44
+ /** `__generate tokens`, then `print tokens` to write `<outDir>/tokens.json`. */
45
+ export declare function runTokenGeneration(input: TokenGenerationInput): Promise<TokenGenerationResult>;
@@ -0,0 +1,24 @@
1
+ import { checkAgentAuth } from '@contentful/experience-design-system-generation';
2
+ import { runTokenGeneration, spawnExtract } from './processes.js';
3
+ import { runSelection } from './selection.js';
4
+ import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './types.js';
5
+ /** The outside world the stage talks to, so the order of events can be tested without a network, an agent or a CLI. */
6
+ export interface ExtractionDeps {
7
+ checkAgentAuth: typeof checkAgentAuth;
8
+ fetchEntities: (credentials: NonNullable<ExtractionInput['credentials']>, outDir: string) => Promise<string | null>;
9
+ spawnExtract: typeof spawnExtract;
10
+ runTokenGeneration: typeof runTokenGeneration;
11
+ runSelection: typeof runSelection;
12
+ }
13
+ /**
14
+ * Runs the stage. The jobs overlap exactly as they do in the legacy wizard:
15
+ *
16
+ * entities fetch ───────┐
17
+ * __extract ── session= ┴─ selection agent (waits for the fetch) ──┐
18
+ * └──────────────────────────────── exits (composition done) ─┴─ result
19
+ * __generate tokens → print tokens (only when the tokens are not being reused)
20
+ *
21
+ * Selection starts the moment the session id is printed, so it overlaps with composition. When more than one job
22
+ * fails, the error reported is the first of: extract, no components, selection, token generation.
23
+ */
24
+ export declare function runExtraction(input: ExtractionInput, onProgress: (progress: ExtractionProgress) => void, deps?: ExtractionDeps): Promise<ExtractionResult>;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { ExtractionProgress } from './types.js';
3
+ interface ExtractionScreenProps {
4
+ progress: ExtractionProgress;
5
+ agent: string;
6
+ stepNumber: number;
7
+ totalSteps: number;
8
+ }
9
+ export declare function ExtractionScreen({ progress, agent, stepNumber, totalSteps, }: ExtractionScreenProps): React.ReactElement;
10
+ export {};
@@ -0,0 +1,18 @@
1
+ import { type AgentName } from '@contentful/experience-design-system-generation';
2
+ export interface SelectionOptions {
3
+ sessionId: string;
4
+ agent: AgentName;
5
+ model?: string;
6
+ promptText?: string;
7
+ promptPath?: string;
8
+ noCache: boolean;
9
+ }
10
+ /**
11
+ * The selection agent run, as the legacy wizard ran it.
12
+ *
13
+ * Reads the extracted components from the session database and skips the ones already decided (cache keyed by
14
+ * component hash, prompt hash and CLI version). It asks the agent about the rest, then writes accepted or rejected to
15
+ * raw_components and stores the new decisions in the cache in one transaction. Throws on a timeout, a non-zero exit,
16
+ * or a database error.
17
+ */
18
+ export declare function runSelection(options: SelectionOptions): Promise<void>;
@@ -0,0 +1,44 @@
1
+ import type { ExtractionHandoff, ImportHandoff } from '@contentful/experience-design-system-types/handoff';
2
+ export type TokenStrategy = ImportHandoff['tokens']['strategy'];
3
+ export interface ExtractionInput {
4
+ projectPath: string;
5
+ /** Raw tokens file the user pointed at (always set: v2 asks for one). */
6
+ rawTokensPath: string;
7
+ /** From the token reuse step. 'reuse' skips token generation entirely. */
8
+ tokenStrategy: TokenStrategy;
9
+ /** Null when the user skipped credentials: no existing-entities fetch happens. */
10
+ credentials: {
11
+ spaceId: string;
12
+ environmentId: string;
13
+ cmaToken: string;
14
+ host: string;
15
+ } | null;
16
+ agent: string;
17
+ agentModel?: string;
18
+ promptOverrides: string[];
19
+ noCache: boolean;
20
+ }
21
+ export type CompositionPhase = 'resolving' | 'cache-hit' | 'done' | `agent:${string}`;
22
+ type JobStatus = 'idle' | 'running' | 'complete' | 'failed';
23
+ /** Everything the extracting screen shows. One field per row. */
24
+ export interface ExtractionProgress {
25
+ scan: {
26
+ scanned: number;
27
+ total: number | null;
28
+ } | null;
29
+ composition: CompositionPhase;
30
+ selection: 'running' | 'complete';
31
+ existingEntities: JobStatus;
32
+ tokens: JobStatus;
33
+ }
34
+ /** The label the error screen shows, as the wizard labelled it. */
35
+ type ExtractionStepName = 'analyze extract' | 'selection agent' | 'generate tokens' | 'print tokens' | `${string} auth check`;
36
+ export type ExtractionResult = {
37
+ ok: true;
38
+ extraction: ExtractionHandoff;
39
+ } | {
40
+ ok: false;
41
+ step: ExtractionStepName;
42
+ message: string;
43
+ };
44
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { ExtractionInput, ExtractionProgress, ExtractionResult } from './types.js';
2
+ export type ExtractionState = {
3
+ status: 'running';
4
+ progress: ExtractionProgress;
5
+ } | {
6
+ status: 'done';
7
+ result: ExtractionResult;
8
+ };
9
+ /**
10
+ * Runs the extraction stage once for the given input and reports its progress. Passing a different input starts a new
11
+ * run; passing nothing leaves the stage idle. A run that finishes after the input changed or the screen went away is
12
+ * ignored.
13
+ */
14
+ export declare function useExtraction(input: ExtractionInput | undefined): ExtractionState | undefined;
@@ -0,0 +1,29 @@
1
+ export interface CacheCheckInput {
2
+ sessionId: string;
3
+ tokensPath: string;
4
+ agent: string;
5
+ agentModel?: string;
6
+ promptOverrides: string[];
7
+ existingEntitiesPath: string | null;
8
+ noCache: boolean;
9
+ }
10
+ interface CacheCheckProcess {
11
+ exitCode: number;
12
+ stdout: string;
13
+ stderr: string;
14
+ }
15
+ /** Runs the legacy CLI with these arguments and waits for it to exit. */
16
+ export type RunLegacyCli = (args: string[]) => Promise<CacheCheckProcess>;
17
+ /**
18
+ * The arguments of `generate components --cache-status --restore-cache`, in the order the wizard built them: the
19
+ * generate arguments first, then the two cache flags. Arguments are not shell-quoted; they go straight to `node`.
20
+ */
21
+ export declare function buildCacheCheckArgs(input: CacheCheckInput): string[];
22
+ /** The names on the `cache-components=["A","B"]` line. Anything missing or unreadable is an empty list. */
23
+ export declare function parseCacheComponents(stdout: string): string[];
24
+ /**
25
+ * Never throws: any failure (spawn error, non-zero exit, no output line, bad JSON) resolves to an empty list. With the
26
+ * cache off there is nothing to restore, so the command is not run at all.
27
+ */
28
+ export declare function checkGenerationCache(input: CacheCheckInput, run?: RunLegacyCli): Promise<string[]>;
29
+ export {};
@@ -1,9 +1,9 @@
1
- import type { Closure } from '../../analyze/composite-closure.js';
1
+ import type { Closure } from './graph/composite-closure.js';
2
2
  /** Structural subset of ScopeComponent needed by these helpers. */
3
3
  export interface ScopeComponentLike {
4
4
  name: string;
5
5
  }
6
- export type Decision = 'accepted' | 'rejected' | 'undecided';
6
+ import type { Decision } from './types.js';
7
7
  export declare const SCOPE_GATE_MAIN_COLUMN_WIDTH = 54;
8
8
  export declare const ACCEPTED_COMPONENTS_COLUMN_WIDTH = 36;
9
9
  export interface ScopeGatePanelLayout {
@@ -34,3 +34,23 @@ export declare function computeCounters(components: ScopeComponentLike[], closur
34
34
  groups: number;
35
35
  total: number;
36
36
  };
37
+ export declare function sideColumnLabelStyle(input: {
38
+ isCycle: boolean;
39
+ isSelected: boolean;
40
+ focused: boolean;
41
+ }): {
42
+ nameColor: string | undefined;
43
+ nameBold: boolean;
44
+ nameInverse: boolean;
45
+ nameUnderline: boolean;
46
+ suffixColor: string | undefined;
47
+ suffixDim: boolean;
48
+ suffixInverse: boolean;
49
+ suffixUnderline: boolean;
50
+ };
51
+ export declare function computeColumnWindow(total: number, cursor: number, visibleCount: number): {
52
+ start: number;
53
+ end: number;
54
+ above: number;
55
+ below: number;
56
+ };
@@ -0,0 +1,26 @@
1
+ export interface ComponentGraphNode {
2
+ name: string;
3
+ slots: Array<{
4
+ name: string;
5
+ allowedComponents?: string[];
6
+ }>;
7
+ }
8
+ interface ClosureNode {
9
+ name: string;
10
+ depth: number;
11
+ path: string[];
12
+ parents: string[];
13
+ }
14
+ export interface Closure {
15
+ root: string;
16
+ nodes: ClosureNode[];
17
+ containsCycle: boolean;
18
+ cyclePath?: string[];
19
+ }
20
+ export type NodeStatus = 'ok' | 'warning' | 'error';
21
+ export declare function findRoots(components: ComponentGraphNode[], selected?: Set<string>): string[];
22
+ export declare function computeClosure(root: string, components: ComponentGraphNode[]): Closure;
23
+ export declare function computeAllClosures(components: ComponentGraphNode[], selected?: Set<string>): Map<string, Closure>;
24
+ export declare function aggregateStatus(closure: Closure, perNodeStatus: Map<string, NodeStatus>): NodeStatus;
25
+ export declare function findSharedDeps(closures: Map<string, Closure>): Map<string, string[]>;
26
+ export {};
@@ -0,0 +1,22 @@
1
+ /** A directed edge in the slot-dependency graph. */
2
+ export interface SlotEdge {
3
+ fromComponent: string;
4
+ slotName: string;
5
+ toComponent: string;
6
+ }
7
+ /** A single elementary cycle, with `path[0] === path[path.length - 1]`. */
8
+ export interface SlotCycle {
9
+ path: string[];
10
+ edges: SlotEdge[];
11
+ }
12
+ /** Input shape mirroring the slot definition on CDFComponentEntry. */
13
+ export interface ComponentSlotInfo {
14
+ name: string;
15
+ slots: Array<{
16
+ name: string;
17
+ allowedComponents?: string[];
18
+ }>;
19
+ }
20
+ export declare function findSlotCycles(components: ComponentSlotInfo[]): SlotCycle[];
21
+ export declare function suggestCycleBreakEdge(cycle: SlotCycle, allCycles: SlotCycle[]): SlotEdge;
22
+ export declare function formatCyclePath(cycle: SlotCycle, maxHops?: number): string;
@@ -0,0 +1,3 @@
1
+ export declare function fuzzyMatches(query: string, text: string): boolean;
2
+ export declare function fuzzyScore(query: string, text: string): number | null;
3
+ export declare function fuzzyFilter(query: string, candidates: string[]): string[];
@@ -0,0 +1,33 @@
1
+ import type { CDFComponentEntry } from '@contentful/experience-design-system-types';
2
+ import type { ScopeComponent } from '../types.js';
3
+ import { type Closure, type ComponentGraphNode, type NodeStatus } from './composite-closure.js';
4
+ import { type SlotCycle } from './cycle-detection.js';
5
+ export interface ScopeGraph {
6
+ /** The slot dependency graph, one node per component. */
7
+ nodes: ComponentGraphNode[];
8
+ /** Every slot cycle. A graph that cannot be searched for cycles has none, as in legacy. */
9
+ cycles: SlotCycle[];
10
+ /** Names in at least one cycle. */
11
+ cycleParticipants: Set<string>;
12
+ /** For each cycle member, the whole set of members that has to be accepted or rejected with it. */
13
+ cycleUnits: Map<string, Set<string>>;
14
+ /** For each root, what it needs. A root with more than one node is a group. */
15
+ closures: Map<string, Closure>;
16
+ }
17
+ export interface SidebarItem {
18
+ key: string;
19
+ entry: CDFComponentEntry;
20
+ status: NodeStatus;
21
+ }
22
+ /** What the sidebar draws a row from: an entry standing in for the component (its slots are what matter), and its status. */
23
+ export declare function sidebarItems(components: ScopeComponent[]): SidebarItem[];
24
+ export declare function buildScopeGraph(components: ScopeComponent[]): ScopeGraph;
25
+ /** Names that change when `target` is accepted. Pulls in everything it needs, whole cycles together. */
26
+ export declare function acceptCascade(graph: ScopeGraph, target: string): string[];
27
+ /** Rejecting rejects every ancestor and deselects the descendants. The screen asks first when it is 2 or more. */
28
+ export declare function rejectCascade(graph: ScopeGraph, target: string): {
29
+ toReject: string[];
30
+ toDeselect: string[];
31
+ };
32
+ /** Everything reachable from the seeds, including the cycles they depend on. Used by "toggle all" and "accept non-flagged". */
33
+ export declare function reachableCycleMembers(graph: ScopeGraph, seeds: string[]): string[];
@@ -0,0 +1,29 @@
1
+ import type { ComponentGraphNode } from './composite-closure.js';
2
+ export interface LineageParentEdge {
3
+ parent: string;
4
+ slotName: string;
5
+ }
6
+ export interface LineageEdge {
7
+ from: string;
8
+ slotName: string;
9
+ to: string;
10
+ }
11
+ export type LineageChain = LineageEdge[];
12
+ export declare function findDirectParents(target: string, components: ComponentGraphNode[]): LineageParentEdge[];
13
+ export declare function findAllAncestors(target: string, components: ComponentGraphNode[]): Set<string>;
14
+ export declare function findAllAncestorChains(target: string, components: ComponentGraphNode[]): LineageChain[];
15
+ export interface AncestorTreeNode {
16
+ name: string;
17
+ incomingSlotName?: string;
18
+ depth: number;
19
+ shared: boolean;
20
+ cycle: boolean;
21
+ parents: AncestorTreeNode[];
22
+ }
23
+ export declare function buildAncestorTree(target: string, components: ComponentGraphNode[]): AncestorTreeNode;
24
+ export interface AncestorTreeLine {
25
+ text: string;
26
+ jumpTarget?: string;
27
+ depth: number;
28
+ }
29
+ export declare function renderAncestorTree(node: AncestorTreeNode): AncestorTreeLine[];
@@ -0,0 +1,3 @@
1
+ import type { ComponentGraphNode } from './composite-closure.js';
2
+ export declare function computeDirectNeighborhood(matches: Iterable<string>, graph: ComponentGraphNode[]): Set<string>;
3
+ export declare function findAllAncestors(target: string, graph: ComponentGraphNode[]): Set<string>;
@@ -0,0 +1,11 @@
1
+ import type { CDFComponentEntry } from '@contentful/experience-design-system-types';
2
+ import type { ComponentGraphNode } from './composite-closure.js';
3
+ export interface SlotGraphInput {
4
+ key: string;
5
+ entry: CDFComponentEntry;
6
+ status?: string;
7
+ }
8
+ export interface BuildOptions {
9
+ stripRejectedEdges?: boolean;
10
+ }
11
+ export declare function buildComponentGraph(components: SlotGraphInput[], opts?: BuildOptions): ComponentGraphNode[];
@@ -0,0 +1,84 @@
1
+ export type GateMode = 'help' | 'reject-prompt' | 'search' | 'cycles' | 'flags' | 'main';
2
+ export interface KeyPress {
3
+ input: string;
4
+ upArrow?: boolean;
5
+ downArrow?: boolean;
6
+ return?: boolean;
7
+ escape?: boolean;
8
+ tab?: boolean;
9
+ shiftTab?: boolean;
10
+ ctrl?: boolean;
11
+ }
12
+ /** What legacy looked at besides the key and the open panel. */
13
+ export interface GateContext {
14
+ focusedColumn: 'main' | 'added-components';
15
+ /** The layout has only the main column, so Tab has nowhere to go. */
16
+ singleColumn: boolean;
17
+ hasCycles: boolean;
18
+ /** Some component was flagged by the AI with a reason to show. */
19
+ hasFlagReasons: boolean;
20
+ /** A jump filter is on, so Esc clears it before it quits. */
21
+ jumpFilterActive: boolean;
22
+ /** Search text is set, so Esc clears it before it quits. */
23
+ searchActive: boolean;
24
+ /** The list in the focused column has no rows, so the arrows have nothing to move. */
25
+ focusedListEmpty: boolean;
26
+ }
27
+ export type GateAction = {
28
+ type: 'none';
29
+ } | {
30
+ type: 'quit';
31
+ } | {
32
+ type: 'confirm';
33
+ } | {
34
+ type: 'close-help';
35
+ } | {
36
+ type: 'answer-reject-prompt';
37
+ confirm: boolean;
38
+ } | {
39
+ type: 'close-panel';
40
+ } | {
41
+ type: 'close-search';
42
+ } | {
43
+ type: 'submit-search';
44
+ } | {
45
+ type: 'search-input';
46
+ } | {
47
+ type: 'clear-jump-filter';
48
+ } | {
49
+ type: 'clear-search';
50
+ } | {
51
+ type: 'move';
52
+ delta: -1 | 1;
53
+ } | {
54
+ type: 'jump-to-selected';
55
+ } | {
56
+ type: 'accept';
57
+ } | {
58
+ type: 'reject';
59
+ } | {
60
+ type: 'toggle-all';
61
+ } | {
62
+ type: 'accept-unflagged';
63
+ } | {
64
+ type: 'toggle-group';
65
+ } | {
66
+ type: 'expand-all';
67
+ } | {
68
+ type: 'collapse-all';
69
+ } | {
70
+ type: 'switch-column';
71
+ delta: -1 | 1;
72
+ } | {
73
+ type: 'open-panel';
74
+ panel: 'cycles' | 'flags' | 'help' | 'search';
75
+ } | {
76
+ type: 'toggle-dependencies';
77
+ } | {
78
+ type: 'toggle-cycle-filter';
79
+ } | {
80
+ type: 'toggle-jump-filter';
81
+ } | {
82
+ type: 'toggle-view';
83
+ };
84
+ export declare function resolveKey(mode: GateMode, key: KeyPress, ctx: GateContext): GateAction;
@@ -0,0 +1,8 @@
1
+ import type { ScopeGateLoad } from './types.js';
2
+ /**
3
+ * Reads the components for the gate, once, before the screen renders. Replaces legacy's database read inside render
4
+ * (and its "remember the last list" workaround for the resize that happened after confirming): with nothing written
5
+ * until the wizard saves the decisions, the list cannot change under the screen.
6
+ * Uses `loadScopeComponents` from backend-pipeline, which is identical to legacy's.
7
+ */
8
+ export declare function loadScopeGate(sessionId: string): ScopeGateLoad;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { type AddedComponentEntry } from '../columns.js';
3
+ interface AddedColumnProps {
4
+ title: string;
5
+ width: number;
6
+ height: number;
7
+ entries: AddedComponentEntry[];
8
+ cursor: number;
9
+ focused: boolean;
10
+ aiFlaggedByKey?: Map<string, boolean>;
11
+ visibleCount: number;
12
+ }
13
+ /** The accepted components, cycle members first. Rejecting from here is the only decision it allows. */
14
+ export declare function AddedColumn(props: AddedColumnProps): React.ReactElement;
15
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { SlotCycle } from '../graph/cycle-detection.js';
3
+ interface CyclesPanelProps {
4
+ cycles: SlotCycle[];
5
+ cursor: number;
6
+ }
7
+ export declare function CyclesPanel({ cycles, cursor }: CyclesPanelProps): React.ReactElement;
8
+ export {};
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { PendingRejectCascade } from '../use-scope-gate.js';
3
+ export declare function RejectPrompt({ pending }: {
4
+ pending: PendingRejectCascade;
5
+ }): React.ReactElement;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { ScopeComponent, ScopeDecisions } from './types.js';
3
+ interface ScopeGateScreenProps {
4
+ components: ScopeComponent[];
5
+ onConfirm: (decisions: ScopeDecisions) => void;
6
+ onQuit: () => void;
7
+ }
8
+ export declare function ScopeGateScreen(props: ScopeGateScreenProps): React.ReactElement;
9
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface AutocompleteResult {
2
+ completion: string;
3
+ candidates: string[];
4
+ }
5
+ export declare function computeAutocomplete(query: string, names: string[]): AutocompleteResult;
@@ -0,0 +1,4 @@
1
+ export declare function CompactControlBar({ hasGroupRoots, searchActive }: {
2
+ hasGroupRoots: boolean;
3
+ searchActive: boolean;
4
+ }): import("react/jsx-runtime").JSX.Element;