@posthog/wizard 2.1.0 → 2.2.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 (79) hide show
  1. package/dist/bin.js +5 -0
  2. package/dist/bin.js.map +1 -1
  3. package/dist/src/__tests__/run.test.js +4 -2
  4. package/dist/src/__tests__/run.test.js.map +1 -1
  5. package/dist/src/lib/__tests__/agent-interface.test.js +2 -1
  6. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  7. package/dist/src/lib/agent-interface.d.ts +2 -1
  8. package/dist/src/lib/agent-interface.js +35 -13
  9. package/dist/src/lib/agent-interface.js.map +1 -1
  10. package/dist/src/lib/agent-runner.js +26 -22
  11. package/dist/src/lib/agent-runner.js.map +1 -1
  12. package/dist/src/lib/commandments.js +2 -1
  13. package/dist/src/lib/commandments.js.map +1 -1
  14. package/dist/src/lib/constants.d.ts +1 -1
  15. package/dist/src/lib/health-checks/readiness.d.ts +5 -0
  16. package/dist/src/lib/health-checks/readiness.js +79 -19
  17. package/dist/src/lib/health-checks/readiness.js.map +1 -1
  18. package/dist/src/lib/version.d.ts +1 -1
  19. package/dist/src/lib/version.js +1 -1
  20. package/dist/src/lib/version.js.map +1 -1
  21. package/dist/src/lib/wizard-session.d.ts +3 -4
  22. package/dist/src/lib/wizard-session.js +2 -1
  23. package/dist/src/lib/wizard-session.js.map +1 -1
  24. package/dist/src/lib/wizard-tools.d.ts +2 -0
  25. package/dist/src/lib/wizard-tools.js +119 -2
  26. package/dist/src/lib/wizard-tools.js.map +1 -1
  27. package/dist/src/ui/logging-ui.d.ts +2 -4
  28. package/dist/src/ui/logging-ui.js +12 -4
  29. package/dist/src/ui/logging-ui.js.map +1 -1
  30. package/dist/src/ui/tui/__tests__/store.test.js +81 -29
  31. package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
  32. package/dist/src/ui/tui/components/ServiceHealthList.d.ts +15 -0
  33. package/dist/src/ui/tui/components/ServiceHealthList.js +57 -0
  34. package/dist/src/ui/tui/components/ServiceHealthList.js.map +1 -0
  35. package/dist/src/ui/tui/flows.d.ts +1 -0
  36. package/dist/src/ui/tui/flows.js +12 -0
  37. package/dist/src/ui/tui/flows.js.map +1 -1
  38. package/dist/src/ui/tui/ink-ui.d.ts +2 -4
  39. package/dist/src/ui/tui/ink-ui.js +8 -4
  40. package/dist/src/ui/tui/ink-ui.js.map +1 -1
  41. package/dist/src/ui/tui/playground/PlaygroundApp.js +12 -0
  42. package/dist/src/ui/tui/playground/PlaygroundApp.js.map +1 -1
  43. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.d.ts +11 -0
  44. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js +56 -0
  45. package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js.map +1 -0
  46. package/dist/src/ui/tui/playground/demos/ModalDemo.d.ts +6 -0
  47. package/dist/src/ui/tui/playground/demos/ModalDemo.js +13 -0
  48. package/dist/src/ui/tui/playground/demos/ModalDemo.js.map +1 -0
  49. package/dist/src/ui/tui/primitives/ModalOverlay.d.ts +25 -0
  50. package/dist/src/ui/tui/primitives/ModalOverlay.js +7 -0
  51. package/dist/src/ui/tui/primitives/ModalOverlay.js.map +1 -0
  52. package/dist/src/ui/tui/primitives/ProgressList.js +3 -1
  53. package/dist/src/ui/tui/primitives/ProgressList.js.map +1 -1
  54. package/dist/src/ui/tui/primitives/index.d.ts +1 -0
  55. package/dist/src/ui/tui/primitives/index.js +1 -0
  56. package/dist/src/ui/tui/primitives/index.js.map +1 -1
  57. package/dist/src/ui/tui/router.d.ts +0 -1
  58. package/dist/src/ui/tui/router.js +0 -1
  59. package/dist/src/ui/tui/router.js.map +1 -1
  60. package/dist/src/ui/tui/screen-registry.js +2 -2
  61. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  62. package/dist/src/ui/tui/screens/PortConflictScreen.js +13 -13
  63. package/dist/src/ui/tui/screens/PortConflictScreen.js.map +1 -1
  64. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +8 -8
  65. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  66. package/dist/src/ui/tui/screens/health/HealthCheckScreen.d.ts +14 -0
  67. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +32 -0
  68. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -0
  69. package/dist/src/ui/tui/store.d.ts +15 -5
  70. package/dist/src/ui/tui/store.js +47 -3
  71. package/dist/src/ui/tui/store.js.map +1 -1
  72. package/dist/src/ui/wizard-ui.d.ts +4 -5
  73. package/dist/src/ui/wizard-ui.js.map +1 -1
  74. package/dist/src/utils/__tests__/setup-utils.test.js +2 -1
  75. package/dist/src/utils/__tests__/setup-utils.test.js.map +1 -1
  76. package/package.json +2 -2
  77. package/dist/src/ui/tui/screens/OutageScreen.d.ts +0 -10
  78. package/dist/src/ui/tui/screens/OutageScreen.js +0 -17
  79. package/dist/src/ui/tui/screens/OutageScreen.js.map +0 -1
@@ -12,6 +12,7 @@ import { type WizardSession } from '../../lib/wizard-session.js';
12
12
  /** Screens that participate in linear flows */
13
13
  export declare enum Screen {
14
14
  Intro = "intro",
15
+ HealthCheck = "health-check",
15
16
  Setup = "setup",
16
17
  Auth = "auth",
17
18
  Run = "run",
@@ -9,11 +9,13 @@
9
9
  * to resolve which screen to show.
10
10
  */
11
11
  import { RunPhase } from '../../lib/wizard-session.js';
12
+ import { WizardReadiness } from '../../lib/health-checks/readiness.js';
12
13
  // ── Screen + Flow enums ──────────────────────────────────────────────
13
14
  /** Screens that participate in linear flows */
14
15
  export var Screen;
15
16
  (function (Screen) {
16
17
  Screen["Intro"] = "intro";
18
+ Screen["HealthCheck"] = "health-check";
17
19
  Screen["Setup"] = "setup";
18
20
  Screen["Auth"] = "auth";
19
21
  Screen["Run"] = "run";
@@ -45,6 +47,16 @@ export const FLOWS = {
45
47
  screen: Screen.Intro,
46
48
  isComplete: (s) => s.setupConfirmed,
47
49
  },
50
+ {
51
+ screen: Screen.HealthCheck,
52
+ isComplete: (s) => {
53
+ if (!s.readinessResult)
54
+ return false;
55
+ if (s.readinessResult.decision === WizardReadiness.No)
56
+ return s.outageDismissed;
57
+ return true;
58
+ },
59
+ },
48
60
  {
49
61
  screen: Screen.Setup,
50
62
  show: needsSetup,
@@ -1 +1 @@
1
- {"version":3,"file":"flows.js","sourceRoot":"","sources":["../../../../src/ui/tui/flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAsB,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE3E,wEAAwE;AAExE,+CAA+C;AAC/C,MAAM,CAAN,IAAY,MASX;AATD,WAAY,MAAM;IAChB,yBAAe,CAAA;IACf,yBAAe,CAAA;IACf,uBAAa,CAAA;IACb,qBAAW,CAAA;IACX,qBAAW,CAAA;IACX,yBAAe,CAAA;IACf,4BAAkB,CAAA;IAClB,kCAAwB,CAAA;AAC1B,CAAC,EATW,MAAM,KAAN,MAAM,QASjB;AAED,qCAAqC;AACrC,MAAM,CAAN,IAAY,IAIX;AAJD,WAAY,IAAI;IACd,yBAAiB,CAAA;IACjB,0BAAkB,CAAA;IAClB,gCAAwB,CAAA;AAC1B,CAAC,EAJW,IAAI,KAAJ,IAAI,QAIf;AAaD;;GAEG;AACH,SAAS,UAAU,CAAC,OAAsB;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,OAAO,KAAK,CAAC;IAErD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CACzC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAC7D,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,KAAK,GAA8B;IAC9C,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACb;YACE,MAAM,EAAE,MAAM,CAAC,KAAK;YACpB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc;SACpC;QACD;YACE,MAAM,EAAE,MAAM,CAAC,KAAK;YACpB,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;SAClC;QACD;YACE,MAAM,EAAE,MAAM,CAAC,IAAI;YACnB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI;SAC1C;QACD;YACE,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAChB,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,KAAK;SACrE;QACD;YACE,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW;SACjC;QACD,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;KACzB;IAED,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACb;YACE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW;SACjC;QACD,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;KACzB;IAED,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;QAChB;YACE,MAAM,EAAE,MAAM,CAAC,SAAS;YACxB,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW;SACjC;QACD,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;KACzB;CACF,CAAC","sourcesContent":["/**\n * Flow pipelines — declarative screen sequences for each wizard flow.\n *\n * Owns the Screen and Flow enums (re-exported by router.ts) to avoid\n * circular imports between router ↔ flows.\n *\n * Each entry defines a screen, optional visibility predicate, and\n * optional completion predicate. The router walks the active flow\n * to resolve which screen to show.\n */\n\nimport { type WizardSession, RunPhase } from '../../lib/wizard-session.js';\n\n// ── Screen + Flow enums ──────────────────────────────────────────────\n\n/** Screens that participate in linear flows */\nexport enum Screen {\n Intro = 'intro',\n Setup = 'setup',\n Auth = 'auth',\n Run = 'run',\n Mcp = 'mcp',\n Outro = 'outro',\n McpAdd = 'mcp-add',\n McpRemove = 'mcp-remove',\n}\n\n/** Named flows the router can run */\nexport enum Flow {\n Wizard = 'wizard',\n McpAdd = 'mcp-add',\n McpRemove = 'mcp-remove',\n}\n\n// ── Flow definitions ─────────────────────────────────────────────────\n\nexport interface FlowEntry {\n /** Screen to show */\n screen: Screen;\n /** If provided, screen is skipped when this returns false. Omit = always show. */\n show?: (session: WizardSession) => boolean;\n /** If provided, screen is considered complete when this returns true. */\n isComplete?: (session: WizardSession) => boolean;\n}\n\n/**\n * Check if the SetupScreen is needed (unresolved framework questions).\n */\nfunction needsSetup(session: WizardSession): boolean {\n const config = session.frameworkConfig;\n if (!config?.metadata.setup?.questions) return false;\n\n return config.metadata.setup.questions.some(\n (q: { key: string }) => !(q.key in session.frameworkContext),\n );\n}\n\n/** All flow pipelines. Add new screens by appending entries. */\nexport const FLOWS: Record<Flow, FlowEntry[]> = {\n [Flow.Wizard]: [\n {\n screen: Screen.Intro,\n isComplete: (s) => s.setupConfirmed,\n },\n {\n screen: Screen.Setup,\n show: needsSetup,\n isComplete: (s) => !needsSetup(s),\n },\n {\n screen: Screen.Auth,\n isComplete: (s) => s.credentials !== null,\n },\n {\n screen: Screen.Run,\n isComplete: (s) =>\n s.runPhase === RunPhase.Completed || s.runPhase === RunPhase.Error,\n },\n {\n screen: Screen.Mcp,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n\n [Flow.McpAdd]: [\n {\n screen: Screen.McpAdd,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n\n [Flow.McpRemove]: [\n {\n screen: Screen.McpRemove,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n};\n"]}
1
+ {"version":3,"file":"flows.js","sourceRoot":"","sources":["../../../../src/ui/tui/flows.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Flow pipelines — declarative screen sequences for each wizard flow.\n *\n * Owns the Screen and Flow enums (re-exported by router.ts) to avoid\n * circular imports between router ↔ flows.\n *\n * Each entry defines a screen, optional visibility predicate, and\n * optional completion predicate. The router walks the active flow\n * to resolve which screen to show.\n */\n\nimport { type WizardSession, RunPhase } from '../../lib/wizard-session.js';\nimport { WizardReadiness } from '../../lib/health-checks/readiness.js';\n\n// ── Screen + Flow enums ──────────────────────────────────────────────\n\n/** Screens that participate in linear flows */\nexport enum Screen {\n Intro = 'intro',\n HealthCheck = 'health-check',\n Setup = 'setup',\n Auth = 'auth',\n Run = 'run',\n Mcp = 'mcp',\n Outro = 'outro',\n McpAdd = 'mcp-add',\n McpRemove = 'mcp-remove',\n}\n\n/** Named flows the router can run */\nexport enum Flow {\n Wizard = 'wizard',\n McpAdd = 'mcp-add',\n McpRemove = 'mcp-remove',\n}\n\n// ── Flow definitions ─────────────────────────────────────────────────\n\nexport interface FlowEntry {\n /** Screen to show */\n screen: Screen;\n /** If provided, screen is skipped when this returns false. Omit = always show. */\n show?: (session: WizardSession) => boolean;\n /** If provided, screen is considered complete when this returns true. */\n isComplete?: (session: WizardSession) => boolean;\n}\n\n/**\n * Check if the SetupScreen is needed (unresolved framework questions).\n */\nfunction needsSetup(session: WizardSession): boolean {\n const config = session.frameworkConfig;\n if (!config?.metadata.setup?.questions) return false;\n\n return config.metadata.setup.questions.some(\n (q: { key: string }) => !(q.key in session.frameworkContext),\n );\n}\n\n/** All flow pipelines. Add new screens by appending entries. */\nexport const FLOWS: Record<Flow, FlowEntry[]> = {\n [Flow.Wizard]: [\n {\n screen: Screen.Intro,\n isComplete: (s) => s.setupConfirmed,\n },\n {\n screen: Screen.HealthCheck,\n isComplete: (s) => {\n if (!s.readinessResult) return false;\n if (s.readinessResult.decision === WizardReadiness.No)\n return s.outageDismissed;\n return true;\n },\n },\n {\n screen: Screen.Setup,\n show: needsSetup,\n isComplete: (s) => !needsSetup(s),\n },\n {\n screen: Screen.Auth,\n isComplete: (s) => s.credentials !== null,\n },\n {\n screen: Screen.Run,\n isComplete: (s) =>\n s.runPhase === RunPhase.Completed || s.runPhase === RunPhase.Error,\n },\n {\n screen: Screen.Mcp,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n\n [Flow.McpAdd]: [\n {\n screen: Screen.McpAdd,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n\n [Flow.McpRemove]: [\n {\n screen: Screen.McpRemove,\n isComplete: (s) => s.mcpComplete,\n },\n { screen: Screen.Outro },\n ],\n};\n"]}
@@ -21,10 +21,8 @@ export declare class InkUI implements WizardUI {
21
21
  setDetectedFramework(label: string): void;
22
22
  onEnterScreen(screen: string, fn: () => void): void;
23
23
  setLoginUrl(url: string | null): void;
24
- showServiceStatus(data: {
25
- description: string;
26
- statusPageUrl: string;
27
- }): void;
24
+ showBlockingOutage(result: import('../../lib/health-checks/readiness.js').WizardReadinessResult): Promise<void>;
25
+ setReadinessWarnings(result: import('../../lib/health-checks/readiness.js').WizardReadinessResult): void;
28
26
  showPortConflict(processInfo: {
29
27
  command: string;
30
28
  pid: string;
@@ -5,7 +5,6 @@
5
5
  * No direct session mutation. No imperative screen transitions.
6
6
  * The router derives the active screen from session state.
7
7
  */
8
- import { Overlay } from './router.js';
9
8
  import { RunPhase, OutroKind } from '../../lib/wizard-session.js';
10
9
  // Strip ANSI escape codes (chalk formatting) from strings
11
10
  // eslint-disable-next-line no-control-regex
@@ -46,9 +45,14 @@ export class InkUI {
46
45
  setLoginUrl(url) {
47
46
  this.store.setLoginUrl(url);
48
47
  }
49
- showServiceStatus(data) {
50
- this.store.setServiceStatus(data);
51
- this.store.pushOverlay(Overlay.Outage);
48
+ showBlockingOutage(result) {
49
+ // In the TUI, the HealthCheckScreen handles outage display.
50
+ // This is only called from agent-runner for the CI fallback path.
51
+ this.store.setReadinessResult(result);
52
+ return Promise.resolve();
53
+ }
54
+ setReadinessWarnings(result) {
55
+ this.store.setReadinessResult(result);
52
56
  }
53
57
  showPortConflict(processInfo) {
54
58
  return this.store.showPortConflict(processInfo);
@@ -1 +1 @@
1
- {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport { Overlay } from './router.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showServiceStatus(data: {\n description: string;\n statusPageUrl: string;\n }): void {\n this.store.setServiceStatus(data);\n this.store.pushOverlay(Overlay.Outage);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n keys: string[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(keys, backupAndFix);\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
1
+ {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n keys: string[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(keys, backupAndFix);\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
@@ -12,6 +12,8 @@ import { InputDemo } from './demos/InputDemo.js';
12
12
  import { ProgressDemo } from './demos/ProgressDemo.js';
13
13
  import { LogDemo } from './demos/LogDemo.js';
14
14
  import { RunScreenDemo } from './demos/RunScreenDemo.js';
15
+ import { HealthCheckDemo } from './demos/HealthCheckDemo.js';
16
+ import { ModalDemo } from './demos/ModalDemo.js';
15
17
  export const PlaygroundApp = ({ store }) => {
16
18
  const tabs = [
17
19
  { id: 'layout', label: 'Layout', component: _jsx(LayoutDemo, {}) },
@@ -23,6 +25,16 @@ export const PlaygroundApp = ({ store }) => {
23
25
  label: 'RunScreen',
24
26
  component: _jsx(RunScreenDemo, { store: store }),
25
27
  },
28
+ {
29
+ id: 'health',
30
+ label: 'HealthCheck',
31
+ component: _jsx(HealthCheckDemo, {}),
32
+ },
33
+ {
34
+ id: 'modal',
35
+ label: 'Modal',
36
+ component: _jsx(ModalDemo, {}),
37
+ },
26
38
  ];
27
39
  return (_jsx(ScreenContainer, { store: store, screens: {
28
40
  intro: _jsx(WelcomeDemo, { store: store }),
@@ -1 +1 @@
1
- {"version":3,"file":"PlaygroundApp.js","sourceRoot":"","sources":["../../../../../src/ui/tui/playground/PlaygroundApp.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAsB,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAC,UAAU,KAAG,EAAE;QAC5D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAC,SAAS,KAAG,EAAE;QACzD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAC,YAAY,KAAG,EAAE;QAClE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAC,OAAO,KAAG,EAAE;QACrD;YACE,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI;SAC3C;KACF,CAAC;IAEF,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;YACP,KAAK,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;YACpC,GAAG,EAAE,CACH,KAAC,YAAY,IACX,IAAI,EAAE,IAAI,EACV,aAAa,EAAC,4DAAuD,GACrE,CACH;SACF,GACD,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '../primitives/index.js';\nimport type { WizardStore } from '../store.js';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n"]}
1
+ {"version":3,"file":"PlaygroundApp.js","sourceRoot":"","sources":["../../../../../src/ui/tui/playground/PlaygroundApp.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAMjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAsB,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAC,UAAU,KAAG,EAAE;QAC5D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAC,SAAS,KAAG,EAAE;QACzD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAC,YAAY,KAAG,EAAE;QAClE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAC,OAAO,KAAG,EAAE;QACrD;YACE,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI;SAC3C;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,aAAa;YACpB,SAAS,EAAE,KAAC,eAAe,KAAG;SAC/B;QACD;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,KAAC,SAAS,KAAG;SACzB;KACF,CAAC;IAEF,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;YACP,KAAK,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;YACpC,GAAG,EAAE,CACH,KAAC,YAAY,IACX,IAAI,EAAE,IAAI,EACV,aAAa,EAAC,4DAAuD,GACrE,CACH;SACF,GACD,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '../primitives/index.js';\nimport type { WizardStore } from '../store.js';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\nimport { HealthCheckDemo } from './demos/HealthCheckDemo.js';\nimport { ModalDemo } from './demos/ModalDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n {\n id: 'health',\n label: 'HealthCheck',\n component: <HealthCheckDemo />,\n },\n {\n id: 'modal',\n label: 'Modal',\n component: <ModalDemo />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HealthCheckDemo — Playground demo for health check UI components.
3
+ *
4
+ * Shows the ModalOverlay with ServiceHealthList, cycling through states:
5
+ * 1. Checking (spinner) — 2 seconds
6
+ * 2. Blocking outage modal (Anthropic down, npm degraded)
7
+ *
8
+ * Renders components directly (not HealthCheckScreen) to avoid useInput
9
+ * conflicts with TabContainer's key handling.
10
+ */
11
+ export declare const HealthCheckDemo: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * HealthCheckDemo — Playground demo for health check UI components.
4
+ *
5
+ * Shows the ModalOverlay with ServiceHealthList, cycling through states:
6
+ * 1. Checking (spinner) — 2 seconds
7
+ * 2. Blocking outage modal (Anthropic down, npm degraded)
8
+ *
9
+ * Renders components directly (not HealthCheckScreen) to avoid useInput
10
+ * conflicts with TabContainer's key handling.
11
+ */
12
+ import { useEffect, useState } from 'react';
13
+ import { Box, Text } from 'ink';
14
+ import { LoadingBox, ModalOverlay } from '../../primitives/index.js';
15
+ import { Icons } from '../../styles.js';
16
+ import { ServiceHealthList } from '../../components/ServiceHealthList.js';
17
+ import { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';
18
+ import { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';
19
+ const HEALTHY = { status: ServiceHealthStatus.Healthy };
20
+ const MOCK_HEALTH = {
21
+ anthropic: { status: ServiceHealthStatus.Down, rawIndicator: 'major' },
22
+ posthogOverall: HEALTHY,
23
+ posthogComponents: { status: ServiceHealthStatus.Healthy },
24
+ github: HEALTHY,
25
+ npmOverall: {
26
+ status: ServiceHealthStatus.Degraded,
27
+ rawIndicator: 'minor',
28
+ },
29
+ npmComponents: {
30
+ status: ServiceHealthStatus.Degraded,
31
+ degradedOrDownComponents: [
32
+ {
33
+ name: 'Registry API',
34
+ status: ServiceHealthStatus.Degraded,
35
+ rawStatus: 'degraded_performance',
36
+ },
37
+ ],
38
+ },
39
+ cloudflareOverall: HEALTHY,
40
+ cloudflareComponents: { status: ServiceHealthStatus.Healthy },
41
+ llmGateway: HEALTHY,
42
+ mcp: HEALTHY,
43
+ };
44
+ export const HealthCheckDemo = () => {
45
+ const [showOutage, setShowOutage] = useState(false);
46
+ useEffect(() => {
47
+ const timer = setTimeout(() => setShowOutage(true), 2000);
48
+ return () => clearTimeout(timer);
49
+ }, []);
50
+ if (!showOutage) {
51
+ return (_jsx(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: _jsx(LoadingBox, { message: "Checking service status..." }) }));
52
+ }
53
+ const blockingKeys = getBlockingServiceKeys(MOCK_HEALTH);
54
+ return (_jsxs(ModalOverlay, { borderColor: "red", title: `${Icons.warning} Ongoing service disruptions`, width: 72, footer: _jsx(Box, { marginLeft: 2, children: _jsx(Text, { dimColor: true, children: "Continue [Enter] / Exit [Esc] (disabled in playground)" }) }), children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: [_jsx(Text, { color: "red", children: Icons.squareFilled }), _jsx(Text, { dimColor: true, children: " Down " }), _jsx(Text, { color: "#DC9300", children: Icons.squareFilled }), _jsx(Text, { dimColor: true, children: " Degraded" })] }) }), _jsx(ServiceHealthList, { health: MOCK_HEALTH, filterKeys: blockingKeys, showHealthy: false })] }), _jsx(Text, { dimColor: true, children: "The wizard may not work reliably while services are affected." })] }));
55
+ };
56
+ //# sourceMappingURL=HealthCheckDemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HealthCheckDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/HealthCheckDemo.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * HealthCheckDemo — Playground demo for health check UI components.\n *\n * Shows the ModalOverlay with ServiceHealthList, cycling through states:\n * 1. Checking (spinner) — 2 seconds\n * 2. Blocking outage modal (Anthropic down, npm degraded)\n *\n * Renders components directly (not HealthCheckScreen) to avoid useInput\n * conflicts with TabContainer's key handling.\n */\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { LoadingBox, ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\nimport { ServiceHealthList } from '../../components/ServiceHealthList.js';\nimport { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';\nimport { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';\nimport type { AllServicesHealth } from '../../../../lib/health-checks/types.js';\n\nconst HEALTHY = { status: ServiceHealthStatus.Healthy } as const;\n\nconst MOCK_HEALTH: AllServicesHealth = {\n anthropic: { status: ServiceHealthStatus.Down, rawIndicator: 'major' },\n posthogOverall: HEALTHY,\n posthogComponents: { status: ServiceHealthStatus.Healthy },\n github: HEALTHY,\n npmOverall: {\n status: ServiceHealthStatus.Degraded,\n rawIndicator: 'minor',\n },\n npmComponents: {\n status: ServiceHealthStatus.Degraded,\n degradedOrDownComponents: [\n {\n name: 'Registry API',\n status: ServiceHealthStatus.Degraded,\n rawStatus: 'degraded_performance',\n },\n ],\n },\n cloudflareOverall: HEALTHY,\n cloudflareComponents: { status: ServiceHealthStatus.Healthy },\n llmGateway: HEALTHY,\n mcp: HEALTHY,\n};\n\nexport const HealthCheckDemo = () => {\n const [showOutage, setShowOutage] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setShowOutage(true), 2000);\n return () => clearTimeout(timer);\n }, []);\n\n if (!showOutage) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const blockingKeys = getBlockingServiceKeys(MOCK_HEALTH);\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Ongoing service disruptions`}\n width={72}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={MOCK_HEALTH}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>\n The wizard may not work reliably while services are affected.\n </Text>\n </ModalOverlay>\n );\n};\n"]}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * ModalDemo — Playground demo for the ModalOverlay primitive.
3
+ *
4
+ * Shows several modal variants: info, warning, error, and one with feedback text.
5
+ */
6
+ export declare const ModalDemo: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ModalDemo — Playground demo for the ModalOverlay primitive.
4
+ *
5
+ * Shows several modal variants: info, warning, error, and one with feedback text.
6
+ */
7
+ import { Box, Text } from 'ink';
8
+ import { ModalOverlay } from '../../primitives/index.js';
9
+ import { Icons } from '../../styles.js';
10
+ export const ModalDemo = () => {
11
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, flexGrow: 1, children: [_jsx(ModalOverlay, { borderColor: "cyan", title: "Info Modal", width: 60, children: _jsx(Text, { children: "A simple informational modal with default styling." }) }), _jsx(ModalOverlay, { borderColor: "#DC9300", title: `${Icons.warning} Warning Modal`, width: 60, feedback: "Something needs your attention.", children: _jsx(Text, { children: "This modal includes a feedback message shown in yellow." }) }), _jsx(ModalOverlay, { borderColor: "red", title: `${Icons.warning} Error Modal`, width: 60, footer: _jsx(Box, { marginLeft: 2, children: _jsx(Text, { dimColor: true, children: "Continue [Enter] / Exit [Esc] (disabled in playground)" }) }), children: _jsx(Text, { children: "This modal has a footer section below a divider." }) })] }));
12
+ };
13
+ //# sourceMappingURL=ModalDemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/ModalDemo.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,aAC7C,KAAC,YAAY,IAAC,WAAW,EAAC,MAAM,EAAC,KAAK,EAAC,YAAY,EAAC,KAAK,EAAE,EAAE,YAC3D,KAAC,IAAI,qEAA0D,GAClD,EAEf,KAAC,YAAY,IACX,WAAW,EAAC,SAAS,EACrB,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,gBAAgB,EACvC,KAAK,EAAE,EAAE,EACT,QAAQ,EAAC,iCAAiC,YAE1C,KAAC,IAAI,0EAA+D,GACvD,EAEf,KAAC,YAAY,IACX,WAAW,EAAC,KAAK,EACjB,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,cAAc,EACrC,KAAK,EAAE,EAAE,EACT,MAAM,EACJ,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,YAChB,KAAC,IAAI,IAAC,QAAQ,6EAEP,GACH,YAGR,KAAC,IAAI,mEAAwD,GAChD,IACX,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ModalDemo — Playground demo for the ModalOverlay primitive.\n *\n * Shows several modal variants: info, warning, error, and one with feedback text.\n */\n\nimport { Box, Text } from 'ink';\nimport { ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\n\nexport const ModalDemo = () => {\n return (\n <Box flexDirection=\"column\" gap={1} flexGrow={1}>\n <ModalOverlay borderColor=\"cyan\" title=\"Info Modal\" width={60}>\n <Text>A simple informational modal with default styling.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"#DC9300\"\n title={`${Icons.warning} Warning Modal`}\n width={60}\n feedback=\"Something needs your attention.\"\n >\n <Text>This modal includes a feedback message shown in yellow.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Error Modal`}\n width={60}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Text>This modal has a footer section below a divider.</Text>\n </ModalOverlay>\n </Box>\n );\n};\n"]}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * ModalOverlay — Reusable centered card for overlay screens.
3
+ *
4
+ * Shared layout for HealthCheckScreen, SettingsOverrideScreen, PortConflictScreen, etc.
5
+ * Provides: centered card with border, title, body, optional feedback, divider, and actions.
6
+ */
7
+ import type { ReactNode } from 'react';
8
+ interface ModalOverlayProps {
9
+ /** Card border color */
10
+ borderColor: string;
11
+ /** Title text */
12
+ title: string;
13
+ /** Title text color (defaults to borderColor) */
14
+ titleColor?: string;
15
+ /** Card width (default 68) */
16
+ width?: number;
17
+ /** Body content */
18
+ children: ReactNode;
19
+ /** Optional feedback message (shown in yellow above the divider) */
20
+ feedback?: string | null;
21
+ /** Footer content below the divider (typically ConfirmationInput) */
22
+ footer?: ReactNode;
23
+ }
24
+ export declare const ModalOverlay: ({ borderColor, title, titleColor, width, children, feedback, footer, }: ModalOverlayProps) => import("react/jsx-runtime").JSX.Element;
25
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { Divider } from './Divider.js';
4
+ export const ModalOverlay = ({ borderColor, title, titleColor, width = 68, children, feedback, footer, }) => {
5
+ return (_jsx(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: borderColor, paddingX: 3, paddingY: 1, width: width, children: [_jsx(Box, { justifyContent: "center", marginBottom: 1, children: _jsx(Text, { color: titleColor ?? borderColor, bold: true, children: title }) }), children, feedback && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: feedback }) })), footer && (_jsxs(_Fragment, { children: [_jsx(Box, { marginY: 1, children: _jsx(Divider, {}) }), footer] }))] }) }));
6
+ };
7
+ //# sourceMappingURL=ModalOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalOverlay.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/ModalOverlay.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAmBvC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,WAAW,EACX,KAAK,EACL,UAAU,EACV,KAAK,GAAG,EAAE,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,GACY,EAAE,EAAE;IACtB,OAAO,CACL,KAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,QAAQ,EAAE,CAAC,EACX,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,QAAQ,YAEvB,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,KAAK,aAEZ,KAAC,GAAG,IAAC,cAAc,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,YAC1C,KAAC,IAAI,IAAC,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,IAAI,kBACzC,KAAK,GACD,GACH,EAEL,QAAQ,EAER,QAAQ,IAAI,CACX,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,QAAQ,GAAQ,GAClC,CACP,EAEA,MAAM,IAAI,CACT,8BACE,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,OAAO,KAAG,GACP,EACL,MAAM,IACN,CACJ,IACG,GACF,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ModalOverlay — Reusable centered card for overlay screens.\n *\n * Shared layout for HealthCheckScreen, SettingsOverrideScreen, PortConflictScreen, etc.\n * Provides: centered card with border, title, body, optional feedback, divider, and actions.\n */\n\nimport type { ReactNode } from 'react';\nimport { Box, Text } from 'ink';\nimport { Divider } from './Divider.js';\n\ninterface ModalOverlayProps {\n /** Card border color */\n borderColor: string;\n /** Title text */\n title: string;\n /** Title text color (defaults to borderColor) */\n titleColor?: string;\n /** Card width (default 68) */\n width?: number;\n /** Body content */\n children: ReactNode;\n /** Optional feedback message (shown in yellow above the divider) */\n feedback?: string | null;\n /** Footer content below the divider (typically ConfirmationInput) */\n footer?: ReactNode;\n}\n\nexport const ModalOverlay = ({\n borderColor,\n title,\n titleColor,\n width = 68,\n children,\n feedback,\n footer,\n}: ModalOverlayProps) => {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={borderColor}\n paddingX={3}\n paddingY={1}\n width={width}\n >\n <Box justifyContent=\"center\" marginBottom={1}>\n <Text color={titleColor ?? borderColor} bold>\n {title}\n </Text>\n </Box>\n\n {children}\n\n {feedback && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{feedback}</Text>\n </Box>\n )}\n\n {footer && (\n <>\n <Box marginY={1}>\n <Divider />\n </Box>\n {footer}\n </>\n )}\n </Box>\n </Box>\n );\n};\n"]}
@@ -25,6 +25,8 @@ export const ProgressList = ({ items, title }) => {
25
25
  ? item.activeForm
26
26
  : item.label;
27
27
  return (_jsxs(Text, { children: [_jsx(Text, { color: color, children: icon }), _jsxs(Text, { dimColor: item.status === 'pending', children: [" ", label] })] }, i));
28
- }), total > 0 && (_jsxs(Box, { marginTop: 1, gap: 1, children: [completed < total && _jsx(Spinner, {}), _jsxs(Text, { dimColor: true, children: ["Progress: ", completed, "/", total, " completed"] })] }))] }));
28
+ }), total > 0 && (_jsxs(Box, { marginTop: 1, gap: 1, children: [_jsx(Spinner, {}), _jsx(Text, { dimColor: true, children: completed < total
29
+ ? `Progress: ${completed}/${total} completed`
30
+ : 'Cleaning up...' })] }))] }));
29
31
  };
30
32
  //# sourceMappingURL=ProgressList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressList.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/ProgressList.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAa7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAqB,EAAE,EAAE;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,KAAK,IAAI,CACR,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACzB,KAAC,IAAI,oBAAS,IACb,CACJ,EACA,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAC,UAAU,IAAC,OAAO,EAAC,sBAAsB,GAAG,EACnE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACrB,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,KAAK,CAAC,YAAY;oBACpB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,KAAK,CAAC,aAAa;wBACrB,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,MAAM,CAAC,OAAO;oBAChB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,MAAM,CAAC,OAAO;wBAChB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBACnB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU;oBAC9C,CAAC,CAAC,IAAI,CAAC,UAAU;oBACjB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBAEjB,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,EACjC,MAAC,IAAI,IAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,kBAAI,KAAK,IAAQ,KAFjD,CAAC,CAGL,CACR,CAAC;YACJ,CAAC,CAAC,EACD,KAAK,GAAG,CAAC,IAAI,CACZ,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,aACtB,SAAS,GAAG,KAAK,IAAI,KAAC,OAAO,KAAG,EACjC,MAAC,IAAI,IAAC,QAAQ,iCACD,SAAS,OAAG,KAAK,kBACvB,IACH,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ProgressList — Reusable task checklist with status icons.\n * Extracted from StatusTab logic.\n */\n\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport { Colors, Icons } from '../styles.js';\nimport { LoadingBox } from './LoadingBox.js';\n\nexport interface ProgressItem {\n label: string;\n activeForm?: string;\n status: 'pending' | 'in_progress' | 'completed';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n title?: string;\n}\n\nexport const ProgressList = ({ items, title }: ProgressListProps) => {\n const completed = items.filter((t) => t.status === 'completed').length;\n const total = items.length;\n\n return (\n <Box flexDirection=\"column\">\n {title && (\n <>\n <Text bold>{title}</Text>\n <Text> </Text>\n </>\n )}\n {items.length === 0 && <LoadingBox message=\"Analyzing project...\" />}\n {items.map((item, i) => {\n const icon =\n item.status === 'completed'\n ? Icons.squareFilled\n : item.status === 'in_progress'\n ? Icons.triangleRight\n : Icons.squareOpen;\n const color =\n item.status === 'completed'\n ? Colors.success\n : item.status === 'in_progress'\n ? Colors.primary\n : Colors.muted;\n const label =\n item.status === 'in_progress' && item.activeForm\n ? item.activeForm\n : item.label;\n\n return (\n <Text key={i}>\n <Text color={color}>{icon}</Text>\n <Text dimColor={item.status === 'pending'}> {label}</Text>\n </Text>\n );\n })}\n {total > 0 && (\n <Box marginTop={1} gap={1}>\n {completed < total && <Spinner />}\n <Text dimColor>\n Progress: {completed}/{total} completed\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n"]}
1
+ {"version":3,"file":"ProgressList.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/ProgressList.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAa7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAqB,EAAE,EAAE;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,KAAK,IAAI,CACR,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACzB,KAAC,IAAI,oBAAS,IACb,CACJ,EACA,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAC,UAAU,IAAC,OAAO,EAAC,sBAAsB,GAAG,EACnE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACrB,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,KAAK,CAAC,YAAY;oBACpB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,KAAK,CAAC,aAAa;wBACrB,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,MAAM,CAAC,OAAO;oBAChB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,MAAM,CAAC,OAAO;wBAChB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBACnB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU;oBAC9C,CAAC,CAAC,IAAI,CAAC,UAAU;oBACjB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBAEjB,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,EACjC,MAAC,IAAI,IAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,kBAAI,KAAK,IAAQ,KAFjD,CAAC,CAGL,CACR,CAAC;YACJ,CAAC,CAAC,EACD,KAAK,GAAG,CAAC,IAAI,CACZ,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,aACvB,KAAC,OAAO,KAAG,EACX,KAAC,IAAI,IAAC,QAAQ,kBACX,SAAS,GAAG,KAAK;4BAChB,CAAC,CAAC,aAAa,SAAS,IAAI,KAAK,YAAY;4BAC7C,CAAC,CAAC,gBAAgB,GACf,IACH,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ProgressList — Reusable task checklist with status icons.\n * Extracted from StatusTab logic.\n */\n\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport { Colors, Icons } from '../styles.js';\nimport { LoadingBox } from './LoadingBox.js';\n\nexport interface ProgressItem {\n label: string;\n activeForm?: string;\n status: 'pending' | 'in_progress' | 'completed';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n title?: string;\n}\n\nexport const ProgressList = ({ items, title }: ProgressListProps) => {\n const completed = items.filter((t) => t.status === 'completed').length;\n const total = items.length;\n\n return (\n <Box flexDirection=\"column\">\n {title && (\n <>\n <Text bold>{title}</Text>\n <Text> </Text>\n </>\n )}\n {items.length === 0 && <LoadingBox message=\"Analyzing project...\" />}\n {items.map((item, i) => {\n const icon =\n item.status === 'completed'\n ? Icons.squareFilled\n : item.status === 'in_progress'\n ? Icons.triangleRight\n : Icons.squareOpen;\n const color =\n item.status === 'completed'\n ? Colors.success\n : item.status === 'in_progress'\n ? Colors.primary\n : Colors.muted;\n const label =\n item.status === 'in_progress' && item.activeForm\n ? item.activeForm\n : item.label;\n\n return (\n <Text key={i}>\n <Text color={color}>{icon}</Text>\n <Text dimColor={item.status === 'pending'}> {label}</Text>\n </Text>\n );\n })}\n {total > 0 && (\n <Box marginTop={1} gap={1}>\n <Spinner />\n <Text dimColor>\n {completed < total\n ? `Progress: ${completed}/${total} completed`\n : 'Cleaning up...'}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n"]}
@@ -10,6 +10,7 @@ export { PromptLabel } from './PromptLabel.js';
10
10
  export { PickerMenu } from './PickerMenu.js';
11
11
  export { ConfirmationInput } from './ConfirmationInput.js';
12
12
  export { Divider } from './Divider.js';
13
+ export { ModalOverlay } from './ModalOverlay.js';
13
14
  export { LogViewer } from './LogViewer.js';
14
15
  export { EventPlanViewer } from './EventPlanViewer.js';
15
16
  export { ScreenContainer } from './ScreenContainer.js';
@@ -9,6 +9,7 @@ export { PromptLabel } from './PromptLabel.js';
9
9
  export { PickerMenu } from './PickerMenu.js';
10
10
  export { ConfirmationInput } from './ConfirmationInput.js';
11
11
  export { Divider } from './Divider.js';
12
+ export { ModalOverlay } from './ModalOverlay.js';
12
13
  export { LogViewer } from './LogViewer.js';
13
14
  export { EventPlanViewer } from './EventPlanViewer.js';
14
15
  export { ScreenContainer } from './ScreenContainer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * Barrel export for all TUI layout primitives.\n */\n\nexport { CardLayout } from './CardLayout.js';\nexport { SplitView } from './SplitView.js';\nexport { LoadingBox } from './LoadingBox.js';\nexport { ProgressList } from './ProgressList.js';\nexport type { ProgressItem } from './ProgressList.js';\nexport { PromptLabel } from './PromptLabel.js';\nexport { PickerMenu } from './PickerMenu.js';\nexport { ConfirmationInput } from './ConfirmationInput.js';\nexport { Divider } from './Divider.js';\nexport { LogViewer } from './LogViewer.js';\nexport { EventPlanViewer } from './EventPlanViewer.js';\nexport { ScreenContainer } from './ScreenContainer.js';\nexport { ScreenErrorBoundary } from './ScreenErrorBoundary.js';\nexport { TabContainer } from './TabContainer.js';\nexport type { TabDefinition } from './TabContainer.js';\nexport { HNViewer } from './HNViewer.js';\nexport { DissolveTransition } from './DissolveTransition.js';\nexport type { WipeDirection } from './DissolveTransition.js';\nexport { ContentSequencer } from './ContentSequencer.js';\nexport type {\n ContentBlock,\n ContentObjectBlock,\n ContentLinesBlock,\n ContentClearBlock,\n} from './ContentSequencer.js';\nexport {\n estimateBlockHeight,\n computeVisibleRange,\n wordWrap,\n wrapAndTruncate,\n} from './layout-helpers.js';\nexport {\n TextRevealMode,\n TEXT_REVEAL_MODE_LABELS,\n TEXT_REVEAL_MODE_COUNT,\n TEXT_REVEAL_MODE_DEFAULTS,\n} from './TextBlock.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * Barrel export for all TUI layout primitives.\n */\n\nexport { CardLayout } from './CardLayout.js';\nexport { SplitView } from './SplitView.js';\nexport { LoadingBox } from './LoadingBox.js';\nexport { ProgressList } from './ProgressList.js';\nexport type { ProgressItem } from './ProgressList.js';\nexport { PromptLabel } from './PromptLabel.js';\nexport { PickerMenu } from './PickerMenu.js';\nexport { ConfirmationInput } from './ConfirmationInput.js';\nexport { Divider } from './Divider.js';\nexport { ModalOverlay } from './ModalOverlay.js';\nexport { LogViewer } from './LogViewer.js';\nexport { EventPlanViewer } from './EventPlanViewer.js';\nexport { ScreenContainer } from './ScreenContainer.js';\nexport { ScreenErrorBoundary } from './ScreenErrorBoundary.js';\nexport { TabContainer } from './TabContainer.js';\nexport type { TabDefinition } from './TabContainer.js';\nexport { HNViewer } from './HNViewer.js';\nexport { DissolveTransition } from './DissolveTransition.js';\nexport type { WipeDirection } from './DissolveTransition.js';\nexport { ContentSequencer } from './ContentSequencer.js';\nexport type {\n ContentBlock,\n ContentObjectBlock,\n ContentLinesBlock,\n ContentClearBlock,\n} from './ContentSequencer.js';\nexport {\n estimateBlockHeight,\n computeVisibleRange,\n wordWrap,\n wrapAndTruncate,\n} from './layout-helpers.js';\nexport {\n TextRevealMode,\n TEXT_REVEAL_MODE_LABELS,\n TEXT_REVEAL_MODE_COUNT,\n TEXT_REVEAL_MODE_DEFAULTS,\n} from './TextBlock.js';\n"]}
@@ -17,7 +17,6 @@ export { Screen, Flow };
17
17
  export type { FlowEntry };
18
18
  /** Screens that interrupt flows as overlays */
19
19
  export declare enum Overlay {
20
- Outage = "outage",
21
20
  SettingsOverride = "settings-override",
22
21
  PortConflict = "port-conflict"
23
22
  }
@@ -18,7 +18,6 @@ export { Screen, Flow };
18
18
  /** Screens that interrupt flows as overlays */
19
19
  export var Overlay;
20
20
  (function (Overlay) {
21
- Overlay["Outage"] = "outage";
22
21
  Overlay["SettingsOverride"] = "settings-override";
23
22
  Overlay["PortConflict"] = "port-conflict";
24
23
  })(Overlay || (Overlay = {}));
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/ui/tui/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAC;AAEjE,gEAAgE;AAChE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAGxB,yEAAyE;AAEzE,+CAA+C;AAC/C,MAAM,CAAN,IAAY,OAIX;AAJD,WAAY,OAAO;IACjB,4BAAiB,CAAA;IACjB,iDAAsC,CAAA;IACtC,yCAA8B,CAAA;AAChC,CAAC,EAJW,OAAO,KAAP,OAAO,QAIlB;AAKD,yEAAyE;AAEzE,MAAM,OAAO,YAAY;IACf,IAAI,CAAc;IAClB,QAAQ,CAAO;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,YAAY,WAAiB,IAAI,CAAC,MAAM;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAsB;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACjD,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC5D,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QAED,sDAAsD;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,CAAC;IAED,oDAAoD;IACpD,IAAI,YAAY;QACd,uDAAuD;QACvD,uEAAuE;QACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,8CAA8C;IAC9C,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc,GAA0B,IAAI,CAAC;IAErD,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6DAA6D;IAC7D,aAAa,CAAC,GAA0B;QACtC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/**\n * WizardRouter — declarative flow pipelines + overlay stack.\n *\n * Two layers:\n * Flow cursor — linear pipeline of screens, advanced with next()\n * Overlay stack — interrupts (outage, auth-expired, etc.) that push/pop\n *\n * The visible screen is: top of overlay stack if non-empty, otherwise the flow cursor.\n *\n * Adding a flow screen = append to a pipeline array.\n * Adding an overlay = call pushOverlay() from anywhere.\n * No switch statements, no hardcoded transitions in business logic.\n */\n\nimport type { WizardSession } from '../../lib/wizard-session.js';\nimport { FLOWS, Screen, Flow, type FlowEntry } from './flows.js';\n\n// Re-export so existing imports from './router.js' keep working\nexport { Screen, Flow };\nexport type { FlowEntry };\n\n// ── Screen name taxonomy ──────────────────────────────────────────────\n\n/** Screens that interrupt flows as overlays */\nexport enum Overlay {\n Outage = 'outage',\n SettingsOverride = 'settings-override',\n PortConflict = 'port-conflict',\n}\n\n/** Union of all screen names */\nexport type ScreenName = Screen | Overlay;\n\n// ── Router ────────────────────────────────────────────────────────────\n\nexport class WizardRouter {\n private flow: FlowEntry[];\n private flowName: Flow;\n private overlays: Overlay[] = [];\n\n constructor(flowName: Flow = Flow.Wizard) {\n this.flowName = flowName;\n this.flow = FLOWS[flowName];\n }\n\n /**\n * Resolve which screen should be active based on session state.\n * Walks the flow pipeline, skipping hidden entries and completed entries,\n * returns the first incomplete screen.\n */\n resolve(session: WizardSession): ScreenName {\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n\n for (const entry of this.flow) {\n if (entry.show && !entry.show(session)) continue;\n if (entry.isComplete && entry.isComplete(session)) continue;\n return entry.screen;\n }\n\n // All entries complete — show the last screen (outro)\n return this.flow[this.flow.length - 1].screen;\n }\n\n /** The screen that should be rendered right now. */\n get activeScreen(): ScreenName {\n // Overlays take priority — resolve() handles this too,\n // but activeScreen is called before session is available in some paths\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n return this.flow[0].screen;\n }\n\n /** The name of the active flow. */\n get activeFlow(): Flow {\n return this.flowName;\n }\n\n /** Whether an overlay is currently active. */\n get hasOverlay(): boolean {\n return this.overlays.length > 0;\n }\n\n /**\n * Push an overlay that interrupts the current flow.\n * The flow resumes when the overlay is dismissed via popOverlay().\n */\n pushOverlay(overlay: Overlay): void {\n this.overlays.push(overlay);\n }\n\n /**\n * Dismiss the topmost overlay. The flow screen underneath resumes.\n */\n popOverlay(): void {\n this.overlays.pop();\n }\n\n /**\n * Direction hint for screen transitions.\n */\n private _lastDirection: 'push' | 'pop' | null = null;\n\n get lastNavDirection(): 'push' | 'pop' | null {\n return this._lastDirection;\n }\n\n /** @internal — called by store wrapper to track direction */\n _setDirection(dir: 'push' | 'pop' | null): void {\n this._lastDirection = dir;\n }\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/ui/tui/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAC;AAEjE,gEAAgE;AAChE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAGxB,yEAAyE;AAEzE,+CAA+C;AAC/C,MAAM,CAAN,IAAY,OAGX;AAHD,WAAY,OAAO;IACjB,iDAAsC,CAAA;IACtC,yCAA8B,CAAA;AAChC,CAAC,EAHW,OAAO,KAAP,OAAO,QAGlB;AAKD,yEAAyE;AAEzE,MAAM,OAAO,YAAY;IACf,IAAI,CAAc;IAClB,QAAQ,CAAO;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,YAAY,WAAiB,IAAI,CAAC,MAAM;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAsB;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACjD,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC5D,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QAED,sDAAsD;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,CAAC;IAED,oDAAoD;IACpD,IAAI,YAAY;QACd,uDAAuD;QACvD,uEAAuE;QACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,8CAA8C;IAC9C,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc,GAA0B,IAAI,CAAC;IAErD,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6DAA6D;IAC7D,aAAa,CAAC,GAA0B;QACtC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/**\n * WizardRouter — declarative flow pipelines + overlay stack.\n *\n * Two layers:\n * Flow cursor — linear pipeline of screens, advanced with next()\n * Overlay stack — interrupts (outage, auth-expired, etc.) that push/pop\n *\n * The visible screen is: top of overlay stack if non-empty, otherwise the flow cursor.\n *\n * Adding a flow screen = append to a pipeline array.\n * Adding an overlay = call pushOverlay() from anywhere.\n * No switch statements, no hardcoded transitions in business logic.\n */\n\nimport type { WizardSession } from '../../lib/wizard-session.js';\nimport { FLOWS, Screen, Flow, type FlowEntry } from './flows.js';\n\n// Re-export so existing imports from './router.js' keep working\nexport { Screen, Flow };\nexport type { FlowEntry };\n\n// ── Screen name taxonomy ──────────────────────────────────────────────\n\n/** Screens that interrupt flows as overlays */\nexport enum Overlay {\n SettingsOverride = 'settings-override',\n PortConflict = 'port-conflict',\n}\n\n/** Union of all screen names */\nexport type ScreenName = Screen | Overlay;\n\n// ── Router ────────────────────────────────────────────────────────────\n\nexport class WizardRouter {\n private flow: FlowEntry[];\n private flowName: Flow;\n private overlays: Overlay[] = [];\n\n constructor(flowName: Flow = Flow.Wizard) {\n this.flowName = flowName;\n this.flow = FLOWS[flowName];\n }\n\n /**\n * Resolve which screen should be active based on session state.\n * Walks the flow pipeline, skipping hidden entries and completed entries,\n * returns the first incomplete screen.\n */\n resolve(session: WizardSession): ScreenName {\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n\n for (const entry of this.flow) {\n if (entry.show && !entry.show(session)) continue;\n if (entry.isComplete && entry.isComplete(session)) continue;\n return entry.screen;\n }\n\n // All entries complete — show the last screen (outro)\n return this.flow[this.flow.length - 1].screen;\n }\n\n /** The screen that should be rendered right now. */\n get activeScreen(): ScreenName {\n // Overlays take priority — resolve() handles this too,\n // but activeScreen is called before session is available in some paths\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n return this.flow[0].screen;\n }\n\n /** The name of the active flow. */\n get activeFlow(): Flow {\n return this.flowName;\n }\n\n /** Whether an overlay is currently active. */\n get hasOverlay(): boolean {\n return this.overlays.length > 0;\n }\n\n /**\n * Push an overlay that interrupts the current flow.\n * The flow resumes when the overlay is dismissed via popOverlay().\n */\n pushOverlay(overlay: Overlay): void {\n this.overlays.push(overlay);\n }\n\n /**\n * Dismiss the topmost overlay. The flow screen underneath resumes.\n */\n popOverlay(): void {\n this.overlays.pop();\n }\n\n /**\n * Direction hint for screen transitions.\n */\n private _lastDirection: 'push' | 'pop' | null = null;\n\n get lastNavDirection(): 'push' | 'pop' | null {\n return this._lastDirection;\n }\n\n /** @internal — called by store wrapper to track direction */\n _setDirection(dir: 'push' | 'pop' | null): void {\n this._lastDirection = dir;\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Screen, Overlay } from './router.js';
3
- import { OutageScreen } from './screens/OutageScreen.js';
3
+ import { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';
4
4
  import { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';
5
5
  import { PortConflictScreen } from './screens/PortConflictScreen.js';
6
6
  import { IntroScreen } from './screens/IntroScreen.js';
@@ -18,11 +18,11 @@ export function createServices() {
18
18
  export function createScreens(store, services) {
19
19
  return {
20
20
  // Overlays
21
- [Overlay.Outage]: _jsx(OutageScreen, { store: store }),
22
21
  [Overlay.SettingsOverride]: _jsx(SettingsOverrideScreen, { store: store }),
23
22
  [Overlay.PortConflict]: _jsx(PortConflictScreen, { store: store }),
24
23
  // Wizard flow
25
24
  [Screen.Intro]: _jsx(IntroScreen, { store: store }),
25
+ [Screen.HealthCheck]: _jsx(HealthCheckScreen, { store: store }),
26
26
  [Screen.Setup]: _jsx(SetupScreen, { store: store }),
27
27
  [Screen.Auth]: _jsx(AuthScreen, { store: store }),
28
28
  [Screen.Run]: _jsx(RunScreen, { store: store }),
@@ -1 +1 @@
1
- {"version":3,"file":"screen-registry.js","sourceRoot":"","sources":["../../../../src/ui/tui/screen-registry.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAmB,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOjE,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,YAAY,EAAE,kBAAkB,EAAE;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,QAAwB;IAExB,OAAO;QACL,WAAW;QACX,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI;QAChD,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,KAAC,sBAAsB,IAAC,KAAK,EAAE,KAAK,GAAI;QACpE,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,GAAI;QAE5D,cAAc;QACd,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI;QAC3C,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,GAAI;QACzC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,GAAI;QAC3E,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAE7C,uBAAuB;QACvB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CACf,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,EAAE,UAAU,SAAG,CACzE;QACD,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAClB,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,QAAQ,CAAC,YAAY,EAChC,IAAI,EAAC,QAAQ,EACb,UAAU,SACV,CACH;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Screen registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/\n * 2. Add an entry here\n * 3. Add the screen name to the router flow (router.ts)\n *\n * App.tsx never needs to change.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { Screen, Overlay, type ScreenName } from './router.js';\n\nimport { OutageScreen } from './screens/OutageScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { IntroScreen } from './screens/IntroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.Outage]: <OutageScreen store={store} />,\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n\n // Wizard flow\n [Screen.Intro]: <IntroScreen store={store} />,\n [Screen.Setup]: <SetupScreen store={store} />,\n [Screen.Auth]: <AuthScreen store={store} />,\n [Screen.Run]: <RunScreen store={store} />,\n [Screen.Mcp]: <McpScreen store={store} installer={services.mcpInstaller} />,\n [Screen.Outro]: <OutroScreen store={store} />,\n\n // Standalone MCP flows\n [Screen.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} standalone />\n ),\n [Screen.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n standalone\n />\n ),\n };\n}\n"]}
1
+ {"version":3,"file":"screen-registry.js","sourceRoot":"","sources":["../../../../src/ui/tui/screen-registry.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAmB,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOjE,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,YAAY,EAAE,kBAAkB,EAAE;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,QAAwB;IAExB,OAAO;QACL,WAAW;QACX,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,KAAC,sBAAsB,IAAC,KAAK,EAAE,KAAK,GAAI;QACpE,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,GAAI;QAE5D,cAAc;QACd,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,GAAI;QACzD,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI;QAC3C,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,GAAI;QACzC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,GAAI;QAC3E,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAE7C,uBAAuB;QACvB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CACf,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,EAAE,UAAU,SAAG,CACzE;QACD,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAClB,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,QAAQ,CAAC,YAAY,EAChC,IAAI,EAAC,QAAQ,EACb,UAAU,SACV,CACH;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Screen registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/\n * 2. Add an entry here\n * 3. Add the screen name to the router flow (router.ts)\n *\n * App.tsx never needs to change.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { Screen, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { IntroScreen } from './screens/IntroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n\n // Wizard flow\n [Screen.Intro]: <IntroScreen store={store} />,\n [Screen.HealthCheck]: <HealthCheckScreen store={store} />,\n [Screen.Setup]: <SetupScreen store={store} />,\n [Screen.Auth]: <AuthScreen store={store} />,\n [Screen.Run]: <RunScreen store={store} />,\n [Screen.Mcp]: <McpScreen store={store} installer={services.mcpInstaller} />,\n [Screen.Outro]: <OutroScreen store={store} />,\n\n // Standalone MCP flows\n [Screen.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} standalone />\n ),\n [Screen.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n standalone\n />\n ),\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * PortConflictScreen — Modal when another process is blocking the OAuth port.
4
4
  *
@@ -7,7 +7,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
7
7
  import { Box, Text } from 'ink';
8
8
  import { useState, useSyncExternalStore } from 'react';
9
9
  import { execSync } from 'node:child_process';
10
- import { ConfirmationInput, Divider } from '../primitives/index.js';
10
+ import { ConfirmationInput, ModalOverlay } from '../primitives/index.js';
11
11
  import { OAUTH_PORT } from '../../../lib/constants.js';
12
12
  export const PortConflictScreen = ({ store }) => {
13
13
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
@@ -15,16 +15,16 @@ export const PortConflictScreen = ({ store }) => {
15
15
  const processInfo = store.session.portConflictProcess;
16
16
  if (!processInfo)
17
17
  return null;
18
- return (_jsx(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#DC9300", paddingX: 3, paddingY: 2, width: 72, children: [_jsx(Box, { justifyContent: "center", marginBottom: 1, children: _jsxs(Text, { color: "#DC9300", bold: true, children: ["Port ", OAUTH_PORT, " in use"] }) }), _jsx(Text, { children: "Another process is blocking the authentication server:" }), _jsxs(Box, { flexDirection: "column", marginY: 1, paddingLeft: 2, gap: 0, children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Command " }), _jsx(Text, { bold: true, children: processInfo.command })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "PID " }), _jsx(Text, { bold: true, children: processInfo.pid })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "User " }), _jsx(Text, { bold: true, children: processInfo.user })] })] }), _jsx(Text, { dimColor: true, children: "Kill this process to continue, or exit and free the port manually." }), feedback && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: feedback }) })), _jsx(Box, { marginY: 1, children: _jsx(Divider, {}) }), _jsx(ConfirmationInput, { message: `Kill process and continue?`, confirmLabel: "Kill & continue [Enter]", cancelLabel: "Exit [Esc]", onConfirm: () => {
19
- try {
20
- execSync(`lsof -ti :${OAUTH_PORT} | xargs kill`, {
21
- stdio: 'ignore',
22
- });
23
- store.resolvePortConflict();
24
- }
25
- catch {
26
- setFeedback(`Could not kill the process. Try running: lsof -ti :${OAUTH_PORT} | xargs kill`);
27
- }
28
- }, onCancel: () => process.exit(1) })] }) }));
18
+ return (_jsxs(ModalOverlay, { borderColor: "#DC9300", title: `Port ${OAUTH_PORT} in use`, width: 72, feedback: feedback, footer: _jsx(ConfirmationInput, { message: "Kill process and continue?", confirmLabel: "Kill & continue [Enter]", cancelLabel: "Exit [Esc]", onConfirm: () => {
19
+ try {
20
+ execSync(`lsof -ti :${OAUTH_PORT} | xargs kill`, {
21
+ stdio: 'ignore',
22
+ });
23
+ store.resolvePortConflict();
24
+ }
25
+ catch {
26
+ setFeedback(`Could not kill the process. Try running: lsof -ti :${OAUTH_PORT} | xargs kill`);
27
+ }
28
+ }, onCancel: () => process.exit(1) }), children: [_jsx(Text, { children: "Another process is blocking the authentication server:" }), _jsxs(Box, { flexDirection: "column", marginY: 1, paddingLeft: 2, gap: 0, children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Command " }), _jsx(Text, { bold: true, children: processInfo.command })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "PID " }), _jsx(Text, { bold: true, children: processInfo.pid })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "User " }), _jsx(Text, { bold: true, children: processInfo.user })] })] }), _jsx(Text, { dimColor: true, children: "Kill this process to continue, or exit and free the port manually." })] }));
29
29
  };
30
30
  //# sourceMappingURL=PortConflictScreen.js.map