wiggum-cli 0.8.0 → 0.9.1

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 (80) hide show
  1. package/dist/ai/conversation/conversation-manager.d.ts +11 -0
  2. package/dist/ai/conversation/conversation-manager.d.ts.map +1 -1
  3. package/dist/ai/conversation/conversation-manager.js +14 -0
  4. package/dist/ai/conversation/conversation-manager.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +4 -0
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/new.d.ts +2 -0
  9. package/dist/commands/new.d.ts.map +1 -1
  10. package/dist/commands/new.js +63 -22
  11. package/dist/commands/new.js.map +1 -1
  12. package/dist/index.d.ts +3 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +97 -22
  15. package/dist/index.js.map +1 -1
  16. package/dist/tui/app.d.ts +46 -36
  17. package/dist/tui/app.d.ts.map +1 -1
  18. package/dist/tui/app.js +136 -37
  19. package/dist/tui/app.js.map +1 -1
  20. package/dist/tui/components/WiggumBanner.d.ts +30 -0
  21. package/dist/tui/components/WiggumBanner.d.ts.map +1 -0
  22. package/dist/tui/components/WiggumBanner.js +34 -0
  23. package/dist/tui/components/WiggumBanner.js.map +1 -0
  24. package/dist/tui/demo.d.ts +8 -0
  25. package/dist/tui/demo.d.ts.map +1 -0
  26. package/dist/tui/demo.js +69 -0
  27. package/dist/tui/demo.js.map +1 -0
  28. package/dist/tui/hooks/useSpecGenerator.d.ts +16 -0
  29. package/dist/tui/hooks/useSpecGenerator.d.ts.map +1 -1
  30. package/dist/tui/hooks/useSpecGenerator.js +47 -0
  31. package/dist/tui/hooks/useSpecGenerator.js.map +1 -1
  32. package/dist/tui/orchestration/index.d.ts +6 -0
  33. package/dist/tui/orchestration/index.d.ts.map +1 -0
  34. package/dist/tui/orchestration/index.js +6 -0
  35. package/dist/tui/orchestration/index.js.map +1 -0
  36. package/dist/tui/orchestration/interview-orchestrator.d.ts +136 -0
  37. package/dist/tui/orchestration/interview-orchestrator.d.ts.map +1 -0
  38. package/dist/tui/orchestration/interview-orchestrator.js +437 -0
  39. package/dist/tui/orchestration/interview-orchestrator.js.map +1 -0
  40. package/dist/tui/screens/InitScreen.d.ts +26 -0
  41. package/dist/tui/screens/InitScreen.d.ts.map +1 -0
  42. package/dist/tui/screens/InitScreen.js +30 -0
  43. package/dist/tui/screens/InitScreen.js.map +1 -0
  44. package/dist/tui/screens/InterviewScreen.d.ts +2 -13
  45. package/dist/tui/screens/InterviewScreen.d.ts.map +1 -1
  46. package/dist/tui/screens/InterviewScreen.js +162 -34
  47. package/dist/tui/screens/InterviewScreen.js.map +1 -1
  48. package/dist/tui/screens/MainShell.d.ts +46 -0
  49. package/dist/tui/screens/MainShell.d.ts.map +1 -0
  50. package/dist/tui/screens/MainShell.js +196 -0
  51. package/dist/tui/screens/MainShell.js.map +1 -0
  52. package/dist/tui/screens/WelcomeScreen.d.ts +45 -0
  53. package/dist/tui/screens/WelcomeScreen.d.ts.map +1 -0
  54. package/dist/tui/screens/WelcomeScreen.js +56 -0
  55. package/dist/tui/screens/WelcomeScreen.js.map +1 -0
  56. package/dist/tui/theme.d.ts +4 -0
  57. package/dist/tui/theme.d.ts.map +1 -1
  58. package/dist/tui/theme.js +4 -0
  59. package/dist/tui/theme.js.map +1 -1
  60. package/dist/utils/repl-prompts.d.ts +1 -1
  61. package/dist/utils/repl-prompts.d.ts.map +1 -1
  62. package/dist/utils/repl-prompts.js +77 -22
  63. package/dist/utils/repl-prompts.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/ai/conversation/conversation-manager.ts +22 -0
  66. package/src/cli.ts +4 -0
  67. package/src/commands/new.ts +79 -27
  68. package/src/index.ts +109 -27
  69. package/src/tui/app.tsx +222 -63
  70. package/src/tui/components/WiggumBanner.tsx +66 -0
  71. package/src/tui/demo.tsx +111 -0
  72. package/src/tui/hooks/useSpecGenerator.ts +73 -0
  73. package/src/tui/orchestration/index.ts +10 -0
  74. package/src/tui/orchestration/interview-orchestrator.ts +559 -0
  75. package/src/tui/screens/InitScreen.tsx +63 -0
  76. package/src/tui/screens/InterviewScreen.tsx +201 -46
  77. package/src/tui/screens/MainShell.tsx +290 -0
  78. package/src/tui/screens/WelcomeScreen.tsx +141 -0
  79. package/src/tui/theme.ts +4 -0
  80. package/src/utils/repl-prompts.ts +83 -25
package/dist/tui/app.d.ts CHANGED
@@ -2,14 +2,17 @@
2
2
  * Main Ink Application Entry Point
3
3
  *
4
4
  * The root component for the Ink-based TUI. Routes to different screens
5
- * based on the mode/screen prop. Currently supports the interview screen
6
- * for the /new command, with room to add more screens (init, main shell,
7
- * monitor) as needed.
5
+ * based on the current screen state. Manages session state and navigation.
8
6
  */
9
7
  import React from 'react';
10
8
  import { type Instance } from 'ink';
11
9
  import type { AIProvider } from '../ai/providers.js';
12
10
  import type { ScanResult } from '../scanner/types.js';
11
+ import type { SessionState } from '../repl/session-state.js';
12
+ /**
13
+ * Available screen types for the App component
14
+ */
15
+ export type AppScreen = 'welcome' | 'shell' | 'interview' | 'init';
13
16
  /**
14
17
  * Props for the interview screen
15
18
  */
@@ -25,74 +28,81 @@ export interface InterviewAppProps {
25
28
  /** Optional scan result with detected tech stack */
26
29
  scanResult?: ScanResult;
27
30
  }
28
- /**
29
- * Available screen types for the App component
30
- * Start with just 'interview', add more screens later as needed:
31
- * - 'init' - Project initialization wizard
32
- * - 'shell' - Main interactive shell
33
- * - 'monitor' - Agent monitoring dashboard
34
- */
35
- export type AppScreen = 'interview';
36
31
  /**
37
32
  * Props for the main App component
38
33
  */
39
34
  export interface AppProps {
40
- /** Screen to display */
35
+ /** Initial screen to display */
41
36
  screen: AppScreen;
37
+ /** Initial session state */
38
+ initialSessionState: SessionState;
39
+ /** CLI version */
40
+ version?: string;
42
41
  /** Props for the interview screen (required when screen is 'interview') */
43
42
  interviewProps?: InterviewAppProps;
44
43
  /** Called when the screen completes successfully */
45
44
  onComplete?: (result: string) => void;
46
45
  /** Called when the user exits/cancels */
47
46
  onExit?: () => void;
47
+ /** Called when init workflow should run (outside of Ink) */
48
+ onRunInit?: () => void;
48
49
  }
49
50
  /**
50
51
  * Main App component for the Ink-based TUI
51
52
  *
52
- * Routes to different screens based on the `screen` prop. Currently
53
- * only supports the interview screen for spec generation. The component
54
- * structure allows easy addition of new screens in the future.
53
+ * Routes to different screens based on the current screen state.
54
+ * Manages session state and provides navigation between screens.
55
55
  *
56
56
  * @example
57
57
  * ```tsx
58
- * // Render the interview screen
59
58
  * renderApp({
60
- * screen: 'interview',
61
- * interviewProps: {
62
- * featureName: 'user-auth',
63
- * projectRoot: '/path/to/project',
64
- * provider: 'anthropic',
65
- * model: 'claude-sonnet-4-5-20250514',
66
- * },
67
- * onComplete: (spec) => {
68
- * fs.writeFileSync('spec.md', spec);
69
- * },
70
- * onExit: () => {
71
- * process.exit(0);
72
- * },
59
+ * screen: 'welcome',
60
+ * initialSessionState: sessionState,
61
+ * version: '0.8.0',
62
+ * onExit: () => process.exit(0),
73
63
  * });
74
64
  * ```
75
65
  */
76
- export declare function App({ screen, interviewProps, onComplete, onExit, }: AppProps): React.ReactElement | null;
66
+ export declare function App({ screen: initialScreen, initialSessionState, version, interviewProps, onComplete, onExit, onRunInit, }: AppProps): React.ReactElement | null;
67
+ /**
68
+ * Render options for renderApp
69
+ */
70
+ export interface RenderAppOptions {
71
+ /** Initial screen to display */
72
+ screen: AppScreen;
73
+ /** Initial session state */
74
+ initialSessionState: SessionState;
75
+ /** CLI version */
76
+ version?: string;
77
+ /** Props for interview screen (if starting directly on interview) */
78
+ interviewProps?: InterviewAppProps;
79
+ /** Called when spec generation completes */
80
+ onComplete?: (result: string) => void;
81
+ /** Called when user exits */
82
+ onExit?: () => void;
83
+ /** Called when init workflow should run (outside of Ink) */
84
+ onRunInit?: () => void;
85
+ }
77
86
  /**
78
87
  * Render the App component to the terminal
79
88
  *
80
89
  * Helper function that wraps Ink's render() to provide a clean API
81
90
  * for starting the TUI from command handlers.
82
91
  *
83
- * @param props - App component props
92
+ * @param options - Render options
84
93
  * @returns Ink Instance that can be used to control/cleanup the render
85
94
  *
86
95
  * @example
87
96
  * ```typescript
88
- * // In a command handler
89
97
  * const instance = renderApp({
90
- * screen: 'interview',
91
- * interviewProps: { ... },
92
- * onComplete: (spec) => { ... },
98
+ * screen: 'welcome',
99
+ * initialSessionState: state,
100
+ * version: '0.8.0',
93
101
  * onExit: () => instance.unmount(),
94
102
  * });
103
+ *
104
+ * await instance.waitUntilExit();
95
105
  * ```
96
106
  */
97
- export declare function renderApp(props: AppProps): Instance;
107
+ export declare function renderApp(options: RenderAppOptions): Instance;
98
108
  //# sourceMappingURL=app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,UAAU,CAAC;IACrB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,wBAAwB;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,oDAAoD;IACpD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,GAAG,CAAC,EAClB,MAAM,EACN,cAAc,EACd,UAAU,EACV,MAAM,GACP,EAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA2BtC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAEnD"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAO7D;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,UAAU,CAAC;IACrB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,gCAAgC;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,4BAA4B;IAC5B,mBAAmB,EAAE,YAAY,CAAC;IAClC,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,oDAAoD;IACpD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,GAAG,CAAC,EAClB,MAAM,EAAE,aAAa,EACrB,mBAAmB,EACnB,OAAiB,EACjB,cAAc,EACd,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,QAAQ,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA4JtC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,MAAM,EAAE,SAAS,CAAC;IAClB,4BAA4B;IAC5B,mBAAmB,EAAE,YAAY,CAAC;IAClC,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ,CAY7D"}
package/dist/tui/app.js CHANGED
@@ -1,48 +1,146 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Main Ink Application Entry Point
4
+ *
5
+ * The root component for the Ink-based TUI. Routes to different screens
6
+ * based on the current screen state. Manages session state and navigation.
7
+ */
8
+ import { useState, useCallback } from 'react';
2
9
  import { render } from 'ink';
10
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ import { loadConfigWithDefaults } from '../utils/config.js';
3
13
  import { InterviewScreen } from './screens/InterviewScreen.js';
14
+ import { WelcomeScreen } from './screens/WelcomeScreen.js';
15
+ import { InitScreen } from './screens/InitScreen.js';
16
+ import { MainShell } from './screens/MainShell.js';
4
17
  /**
5
18
  * Main App component for the Ink-based TUI
6
19
  *
7
- * Routes to different screens based on the `screen` prop. Currently
8
- * only supports the interview screen for spec generation. The component
9
- * structure allows easy addition of new screens in the future.
20
+ * Routes to different screens based on the current screen state.
21
+ * Manages session state and provides navigation between screens.
10
22
  *
11
23
  * @example
12
24
  * ```tsx
13
- * // Render the interview screen
14
25
  * renderApp({
15
- * screen: 'interview',
16
- * interviewProps: {
17
- * featureName: 'user-auth',
18
- * projectRoot: '/path/to/project',
19
- * provider: 'anthropic',
20
- * model: 'claude-sonnet-4-5-20250514',
21
- * },
22
- * onComplete: (spec) => {
23
- * fs.writeFileSync('spec.md', spec);
24
- * },
25
- * onExit: () => {
26
- * process.exit(0);
27
- * },
26
+ * screen: 'welcome',
27
+ * initialSessionState: sessionState,
28
+ * version: '0.8.0',
29
+ * onExit: () => process.exit(0),
28
30
  * });
29
31
  * ```
30
32
  */
31
- export function App({ screen, interviewProps, onComplete, onExit, }) {
32
- // Route to the appropriate screen based on the screen prop
33
- if (screen === 'interview' && interviewProps) {
34
- return (_jsx(InterviewScreen, { featureName: interviewProps.featureName, projectRoot: interviewProps.projectRoot, provider: interviewProps.provider, model: interviewProps.model, scanResult: interviewProps.scanResult, onComplete: (spec) => {
33
+ export function App({ screen: initialScreen, initialSessionState, version = '0.8.0', interviewProps, onComplete, onExit, onRunInit, }) {
34
+ const [currentScreen, setCurrentScreen] = useState(initialScreen);
35
+ const [screenProps, setScreenProps] = useState(interviewProps ? { featureName: interviewProps.featureName } : null);
36
+ const [sessionState, setSessionState] = useState(initialSessionState);
37
+ /**
38
+ * Navigate to a different screen
39
+ */
40
+ const navigate = useCallback((target, props) => {
41
+ setScreenProps(props || null);
42
+ setCurrentScreen(target);
43
+ }, []);
44
+ /**
45
+ * Handle interview completion - save spec to disk and notify
46
+ */
47
+ const handleInterviewComplete = useCallback(async (spec) => {
48
+ // Get feature name from navigation props or initial interview props
49
+ const featureName = screenProps?.featureName || interviewProps?.featureName;
50
+ if (featureName && typeof featureName === 'string') {
51
+ try {
52
+ // Load config to get specs directory
53
+ const config = await loadConfigWithDefaults(sessionState.projectRoot);
54
+ const specsDir = join(sessionState.projectRoot, config.paths.specs);
55
+ // Create specs directory if it doesn't exist
56
+ if (!existsSync(specsDir)) {
57
+ mkdirSync(specsDir, { recursive: true });
58
+ }
59
+ // Write spec to file
60
+ const specPath = join(specsDir, `${featureName}.md`);
61
+ writeFileSync(specPath, spec, 'utf-8');
62
+ // Call onComplete with the spec path for logging
63
+ onComplete?.(specPath);
64
+ }
65
+ catch (error) {
66
+ // If saving fails, still call onComplete with spec content
35
67
  onComplete?.(spec);
36
- }, onCancel: () => {
37
- onExit?.();
38
- } }));
68
+ }
69
+ }
70
+ else {
71
+ onComplete?.(spec);
72
+ }
73
+ // If started on interview (--tui mode), call onExit to resolve promise
74
+ // Otherwise, return to shell
75
+ if (initialScreen === 'interview') {
76
+ onExit?.();
77
+ }
78
+ else {
79
+ navigate('shell');
80
+ }
81
+ }, [onComplete, navigate, initialScreen, onExit, screenProps, interviewProps, sessionState.projectRoot]);
82
+ /**
83
+ * Handle interview cancel
84
+ */
85
+ const handleInterviewCancel = useCallback(() => {
86
+ // If started on interview (--tui mode), call onExit to resolve promise
87
+ // Otherwise, return to shell
88
+ if (initialScreen === 'interview') {
89
+ onExit?.();
90
+ }
91
+ else {
92
+ navigate('shell');
93
+ }
94
+ }, [navigate, initialScreen, onExit]);
95
+ /**
96
+ * Handle welcome continue
97
+ */
98
+ const handleWelcomeContinue = useCallback(() => {
99
+ navigate('shell');
100
+ }, [navigate]);
101
+ /**
102
+ * Handle session state changes
103
+ */
104
+ const handleSessionStateChange = useCallback((newState) => {
105
+ setSessionState(newState);
106
+ }, []);
107
+ // Route to the appropriate screen
108
+ switch (currentScreen) {
109
+ case 'welcome':
110
+ return (_jsx(WelcomeScreen, { provider: sessionState.provider, model: sessionState.model, version: version, isInitialized: sessionState.initialized, onContinue: handleWelcomeContinue }));
111
+ case 'shell':
112
+ return (_jsx(MainShell, { sessionState: sessionState, onNavigate: navigate, onSessionStateChange: handleSessionStateChange }));
113
+ case 'interview': {
114
+ // Get feature name from props or navigation
115
+ const featureName = screenProps?.featureName || interviewProps?.featureName;
116
+ if (!featureName || typeof featureName !== 'string') {
117
+ // Missing feature name, go back to shell
118
+ navigate('shell');
119
+ return null;
120
+ }
121
+ if (!sessionState.provider) {
122
+ // No provider configured, can't run interview
123
+ navigate('shell');
124
+ return null;
125
+ }
126
+ return (_jsx(InterviewScreen, { featureName: featureName, projectRoot: sessionState.projectRoot, provider: sessionState.provider, model: sessionState.model, scanResult: sessionState.scanResult, onComplete: handleInterviewComplete, onCancel: handleInterviewCancel }));
127
+ }
128
+ case 'init': {
129
+ // Handle init workflow - requires running outside Ink due to readline prompts
130
+ const handleRunInit = () => {
131
+ if (onRunInit) {
132
+ onRunInit();
133
+ }
134
+ else {
135
+ // No init handler provided, return to shell with message
136
+ navigate('shell');
137
+ }
138
+ };
139
+ return (_jsx(InitScreen, { onRunInit: handleRunInit, onCancel: () => navigate('shell') }));
140
+ }
141
+ default:
142
+ return null;
39
143
  }
40
- // Future screens would be added here:
41
- // if (screen === 'init' && initProps) { ... }
42
- // if (screen === 'shell' && shellProps) { ... }
43
- // if (screen === 'monitor' && monitorProps) { ... }
44
- // Fallback - shouldn't happen in normal usage
45
- return null;
46
144
  }
47
145
  /**
48
146
  * Render the App component to the terminal
@@ -50,21 +148,22 @@ export function App({ screen, interviewProps, onComplete, onExit, }) {
50
148
  * Helper function that wraps Ink's render() to provide a clean API
51
149
  * for starting the TUI from command handlers.
52
150
  *
53
- * @param props - App component props
151
+ * @param options - Render options
54
152
  * @returns Ink Instance that can be used to control/cleanup the render
55
153
  *
56
154
  * @example
57
155
  * ```typescript
58
- * // In a command handler
59
156
  * const instance = renderApp({
60
- * screen: 'interview',
61
- * interviewProps: { ... },
62
- * onComplete: (spec) => { ... },
157
+ * screen: 'welcome',
158
+ * initialSessionState: state,
159
+ * version: '0.8.0',
63
160
  * onExit: () => instance.unmount(),
64
161
  * });
162
+ *
163
+ * await instance.waitUntilExit();
65
164
  * ```
66
165
  */
67
- export function renderApp(props) {
68
- return render(_jsx(App, { ...props }));
166
+ export function renderApp(options) {
167
+ return render(_jsx(App, { screen: options.screen, initialSessionState: options.initialSessionState, version: options.version, interviewProps: options.interviewProps, onComplete: options.onComplete, onExit: options.onExit, onRunInit: options.onRunInit }));
69
168
  }
70
169
  //# sourceMappingURL=app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":";AAUA,OAAO,EAAE,MAAM,EAAiB,MAAM,KAAK,CAAC;AAG5C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAyC/D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,GAAG,CAAC,EAClB,MAAM,EACN,cAAc,EACd,UAAU,EACV,MAAM,GACG;IACT,2DAA2D;IAC3D,IAAI,MAAM,KAAK,WAAW,IAAI,cAAc,EAAE,CAAC;QAC7C,OAAO,CACL,KAAC,eAAe,IACd,WAAW,EAAE,cAAc,CAAC,WAAW,EACvC,WAAW,EAAE,cAAc,CAAC,WAAW,EACvC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EACjC,KAAK,EAAE,cAAc,CAAC,KAAK,EAC3B,UAAU,EAAE,cAAc,CAAC,UAAU,EACrC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnB,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC,EACD,QAAQ,EAAE,GAAG,EAAE;gBACb,MAAM,EAAE,EAAE,CAAC;YACb,CAAC,GACD,CACH,CAAC;IACJ,CAAC;IAED,sCAAsC;IACtC,8CAA8C;IAC9C,gDAAgD;IAChD,oDAAoD;IAEpD,8CAA8C;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,SAAS,CAAC,KAAe;IACvC,OAAO,MAAM,CAAC,KAAC,GAAG,OAAK,KAAK,GAAI,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WiggumBanner - ASCII art banner component
3
+ *
4
+ * Displays the Wiggum CLI ASCII art logo in Simpson yellow.
5
+ * Inspired by Claude Code's welcome banner style.
6
+ */
7
+ import React from 'react';
8
+ /**
9
+ * Props for WiggumBanner component
10
+ */
11
+ export interface WiggumBannerProps {
12
+ /** Optional color override (defaults to Simpson yellow) */
13
+ color?: string;
14
+ /** Whether to show a compact version */
15
+ compact?: boolean;
16
+ }
17
+ /**
18
+ * WiggumBanner component
19
+ *
20
+ * Displays the Wiggum CLI ASCII art logo.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <WiggumBanner />
25
+ * <WiggumBanner color="blue" />
26
+ * <WiggumBanner compact />
27
+ * ```
28
+ */
29
+ export declare function WiggumBanner({ color, compact, }: WiggumBannerProps): React.ReactElement;
30
+ //# sourceMappingURL=WiggumBanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WiggumBanner.d.ts","sourceRoot":"","sources":["../../../src/tui/components/WiggumBanner.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAiB1B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAqB,EACrB,OAAe,GAChB,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAgBxC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text, Box } from 'ink';
3
+ import { colors } from '../theme.js';
4
+ /**
5
+ * ASCII art banner for Wiggum CLI
6
+ * Block-style font to match the cfonts 'block' style
7
+ */
8
+ const BANNER = `
9
+ ██╗ ██╗██╗ ██████╗ ██████╗ ██╗ ██╗███╗ ███╗
10
+ ██║ ██║██║██╔════╝ ██╔════╝ ██║ ██║████╗ ████║
11
+ ██║ █╗ ██║██║██║ ███╗██║ ███╗██║ ██║██╔████╔██║
12
+ ██║███╗██║██║██║ ██║██║ ██║██║ ██║██║╚██╔╝██║
13
+ ╚███╔███╔╝██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
14
+ ╚══╝╚══╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝
15
+ `;
16
+ /**
17
+ * WiggumBanner component
18
+ *
19
+ * Displays the Wiggum CLI ASCII art logo.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <WiggumBanner />
24
+ * <WiggumBanner color="blue" />
25
+ * <WiggumBanner compact />
26
+ * ```
27
+ */
28
+ export function WiggumBanner({ color = colors.yellow, compact = false, }) {
29
+ if (compact) {
30
+ return (_jsx(Box, { children: _jsx(Text, { color: color, bold: true, children: "WIGGUM CLI" }) }));
31
+ }
32
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { color: color, children: BANNER }) }));
33
+ }
34
+ //# sourceMappingURL=WiggumBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WiggumBanner.js","sourceRoot":"","sources":["../../../src/tui/components/WiggumBanner.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;GAGG;AACH,MAAM,MAAM,GAAG;;;;;;;CAOd,CAAC;AAYF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,GAAG,MAAM,CAAC,MAAM,EACrB,OAAO,GAAG,KAAK,GACG;IAClB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,IAAI,iCAEjB,GACH,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACzB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,MAAM,GAAQ,GAC/B,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * TUI Demo - Test the Ink components visually
4
+ *
5
+ * Run with: npx tsx src/tui/demo.tsx
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/tui/demo.tsx"],"names":[],"mappings":";AACA;;;;GAIG"}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * TUI Demo - Test the Ink components visually
5
+ *
6
+ * Run with: npx tsx src/tui/demo.tsx
7
+ */
8
+ import { useState } from 'react';
9
+ import { render, Box, Text, useInput } from 'ink';
10
+ import { PhaseHeader } from './components/PhaseHeader.js';
11
+ import { MessageList } from './components/MessageList.js';
12
+ import { WorkingIndicator } from './components/WorkingIndicator.js';
13
+ import { ChatInput } from './components/ChatInput.js';
14
+ import { colors } from './theme.js';
15
+ function Demo() {
16
+ const [messages, setMessages] = useState([
17
+ { id: '1', role: 'system', content: 'Spec Generator initialized for feature: demo-feature' },
18
+ { id: '2', role: 'assistant', content: 'Welcome! Let\'s create a specification for your feature.' },
19
+ ]);
20
+ const [phase, setPhase] = useState(1);
21
+ const [isWorking, setIsWorking] = useState(false);
22
+ const [workingStatus, setWorkingStatus] = useState('');
23
+ // Handle user input
24
+ const handleSubmit = (value) => {
25
+ // Add user message
26
+ setMessages(prev => [...prev, {
27
+ id: String(Date.now()),
28
+ role: 'user',
29
+ content: value || '(empty - continue)',
30
+ }]);
31
+ // Simulate AI working
32
+ setIsWorking(true);
33
+ setWorkingStatus('Thinking...');
34
+ setTimeout(() => {
35
+ // Simulate tool call
36
+ setMessages(prev => [...prev, {
37
+ id: String(Date.now()),
38
+ role: 'assistant',
39
+ content: 'Great! Let me analyze that...',
40
+ toolCalls: [{
41
+ toolName: 'Read File',
42
+ status: 'complete',
43
+ input: 'package.json',
44
+ output: '42 lines read',
45
+ }],
46
+ }]);
47
+ setIsWorking(false);
48
+ setPhase(p => Math.min(p + 1, 4));
49
+ }, 1500);
50
+ };
51
+ // Handle escape to exit
52
+ useInput((input, key) => {
53
+ if (key.escape) {
54
+ process.exit(0);
55
+ }
56
+ });
57
+ const phaseNames = ['Context', 'Goals', 'Interview', 'Generation'];
58
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: colors.yellow, bold: true, children: "Ink TUI Demo" }), _jsx(Text, { color: colors.brown, children: " - Press Esc to exit" })] }), _jsx(PhaseHeader, { currentPhase: phase, totalPhases: 4, phaseName: phaseNames[phase - 1] }), _jsx(Box, { marginY: 1, children: _jsx(MessageList, { messages: messages }) }), _jsx(Box, { marginY: 1, children: _jsx(WorkingIndicator, { state: {
59
+ isWorking,
60
+ status: workingStatus,
61
+ hint: 'esc to cancel',
62
+ } }) }), _jsx(Box, { marginTop: 1, children: _jsx(ChatInput, { onSubmit: handleSubmit, disabled: isWorking, allowEmpty: phase === 1, placeholder: phase === 1
63
+ ? 'Enter URL or file path, or press Enter to continue...'
64
+ : 'Type your response...' }) })] }));
65
+ }
66
+ // Render the demo
67
+ console.clear();
68
+ render(_jsx(Demo, {}));
69
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/tui/demo.tsx"],"names":[],"mappings":"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"}
@@ -129,6 +129,22 @@ export interface UseSpecGeneratorReturn {
129
129
  * Complete a tool execution
130
130
  */
131
131
  completeToolCall: (toolId: string, output?: string, error?: string) => void;
132
+ /**
133
+ * Set the current phase (used by orchestrator)
134
+ */
135
+ setPhase: (phase: GeneratorPhase) => void;
136
+ /**
137
+ * Set the generated spec (used by orchestrator on completion)
138
+ */
139
+ setGeneratedSpec: (spec: string) => void;
140
+ /**
141
+ * Set an error state (used by orchestrator on error)
142
+ */
143
+ setError: (error: string) => void;
144
+ /**
145
+ * Set working state with status message (used by orchestrator)
146
+ */
147
+ setWorking: (isWorking: boolean, status: string) => void;
132
148
  }
133
149
  /**
134
150
  * useSpecGenerator - React hook wrapping SpecGenerator for TUI use
@@ -1 +1 @@
1
- {"version":3,"file":"useSpecGenerator.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useSpecGenerator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSpecGenerator.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useSpecGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGtE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CA0B7D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,KAAK,EAAE,cAAc,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,qCAAqC;IACrC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,UAAU,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,oBAAoB;IACpB,KAAK,EAAE,kBAAkB,CAAC;IAI1B;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD;;OAEG;IACH,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;OAEG;IACH,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB;;OAEG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAIpD;;OAEG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAErG;;OAEG;IACH,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,wBAAwB,EAAE,MAAM,IAAI,CAAC;IAErC;;;OAGG;IACH,QAAQ,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;IAE5E;;OAEG;IACH,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAI5E;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AA+CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,gBAAgB,IAAI,sBAAsB,CA0XzD"}
@@ -386,6 +386,48 @@ export function useSpecGenerator() {
386
386
  optionsRef.current = null;
387
387
  setState(initialState);
388
388
  }, []);
389
+ /**
390
+ * Set the current phase (used by orchestrator)
391
+ */
392
+ const setPhase = useCallback((phase) => {
393
+ setState((prev) => ({
394
+ ...prev,
395
+ phase,
396
+ }));
397
+ }, []);
398
+ /**
399
+ * Set the generated spec (used by orchestrator on completion)
400
+ */
401
+ const setGeneratedSpec = useCallback((spec) => {
402
+ setState((prev) => ({
403
+ ...prev,
404
+ generatedSpec: spec,
405
+ phase: 'complete',
406
+ isWorking: false,
407
+ awaitingInput: false,
408
+ }));
409
+ }, []);
410
+ /**
411
+ * Set an error state (used by orchestrator on error)
412
+ */
413
+ const setError = useCallback((error) => {
414
+ setState((prev) => ({
415
+ ...prev,
416
+ error,
417
+ isWorking: false,
418
+ }));
419
+ }, []);
420
+ /**
421
+ * Set working state with status message (used by orchestrator)
422
+ */
423
+ const setWorking = useCallback((isWorking, status) => {
424
+ setState((prev) => ({
425
+ ...prev,
426
+ isWorking,
427
+ workingStatus: status,
428
+ awaitingInput: !isWorking && prev.phase !== 'complete',
429
+ }));
430
+ }, []);
389
431
  return {
390
432
  state,
391
433
  submitAnswer,
@@ -400,6 +442,11 @@ export function useSpecGenerator() {
400
442
  setReady,
401
443
  startToolCall,
402
444
  completeToolCall,
445
+ // Orchestrator-specific actions
446
+ setPhase,
447
+ setGeneratedSpec,
448
+ setError,
449
+ setWorking,
403
450
  };
404
451
  }
405
452
  //# sourceMappingURL=useSpecGenerator.js.map