prompt-language-shell 0.9.2 → 0.9.4

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 (56) hide show
  1. package/dist/{ui/Main.js → Main.js} +12 -12
  2. package/dist/{ui → components}/Component.js +28 -26
  3. package/dist/{ui → components}/Workflow.js +2 -3
  4. package/dist/{ui → components/controllers}/Answer.js +18 -17
  5. package/dist/{ui → components/controllers}/Command.js +11 -18
  6. package/dist/{ui → components/controllers}/Config.js +8 -116
  7. package/dist/components/controllers/Confirm.js +42 -0
  8. package/dist/{ui → components/controllers}/Execute.js +75 -144
  9. package/dist/{ui → components/controllers}/Introspect.js +12 -28
  10. package/dist/components/controllers/Refinement.js +18 -0
  11. package/dist/components/controllers/Schedule.js +139 -0
  12. package/dist/{ui → components/controllers}/Validate.js +14 -32
  13. package/dist/components/views/Answer.js +28 -0
  14. package/dist/components/views/Command.js +11 -0
  15. package/dist/components/views/Config.js +115 -0
  16. package/dist/components/views/Confirm.js +24 -0
  17. package/dist/components/views/Execute.js +60 -0
  18. package/dist/{ui → components/views}/Feedback.js +3 -3
  19. package/dist/components/views/Introspect.js +17 -0
  20. package/dist/{ui → components/views}/Label.js +3 -3
  21. package/dist/{ui → components/views}/List.js +1 -1
  22. package/dist/{ui → components/views}/Output.js +2 -2
  23. package/dist/components/views/Refinement.js +9 -0
  24. package/dist/{ui → components/views}/Report.js +1 -1
  25. package/dist/components/views/Schedule.js +120 -0
  26. package/dist/{ui → components/views}/Separator.js +1 -1
  27. package/dist/{ui → components/views}/Spinner.js +1 -1
  28. package/dist/{ui → components/views}/Subtask.js +4 -4
  29. package/dist/components/views/Task.js +18 -0
  30. package/dist/components/views/Upcoming.js +30 -0
  31. package/dist/{ui → components/views}/UserQuery.js +1 -1
  32. package/dist/components/views/Validate.js +17 -0
  33. package/dist/{ui → components/views}/Welcome.js +1 -1
  34. package/dist/configuration/steps.js +1 -1
  35. package/dist/execution/handlers.js +19 -53
  36. package/dist/execution/reducer.js +26 -38
  37. package/dist/execution/runner.js +43 -25
  38. package/dist/execution/types.js +3 -4
  39. package/dist/execution/utils.js +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/services/messages.js +19 -0
  42. package/dist/services/router.js +69 -11
  43. package/dist/services/shell.js +26 -6
  44. package/dist/services/timing.js +1 -0
  45. package/dist/skills/execute.md +15 -7
  46. package/dist/tools/execute.tool.js +0 -4
  47. package/dist/types/schemas.js +0 -1
  48. package/package.json +1 -1
  49. package/dist/execution/hooks.js +0 -291
  50. package/dist/ui/Confirm.js +0 -62
  51. package/dist/ui/Refinement.js +0 -23
  52. package/dist/ui/Schedule.js +0 -257
  53. package/dist/ui/Task.js +0 -11
  54. /package/dist/{ui → components/views}/Debug.js +0 -0
  55. /package/dist/{ui → components/views}/Message.js +0 -0
  56. /package/dist/{ui → components/views}/Panel.js +0 -0
@@ -1,17 +1,17 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
- import { DebugLevel } from '../configuration/types.js';
4
- import { FeedbackType } from '../types/types.js';
5
- import { loadConfig, loadDebugSetting, saveConfig, saveDebugSetting, } from '../configuration/io.js';
6
- import { getConfigurationRequiredMessage } from '../configuration/messages.js';
7
- import { getMissingConfigKeys } from '../configuration/schema.js';
8
- import { createConfigStepsFromSchema } from '../configuration/steps.js';
9
- import { unflattenConfig } from '../configuration/transformation.js';
10
- import { createAnthropicService } from '../services/anthropic.js';
11
- import { createCommand, createConfig, createFeedback, createMessage, createWelcome, } from '../services/components.js';
12
- import { registerGlobalShortcut } from '../services/keyboard.js';
13
- import { initializeLogger, setDebugLevel } from '../services/logger.js';
14
- import { Workflow } from './Workflow.js';
3
+ import { DebugLevel } from './configuration/types.js';
4
+ import { FeedbackType } from './types/types.js';
5
+ import { loadConfig, loadDebugSetting, saveConfig, saveDebugSetting, } from './configuration/io.js';
6
+ import { getConfigurationRequiredMessage } from './configuration/messages.js';
7
+ import { getMissingConfigKeys } from './configuration/schema.js';
8
+ import { createConfigStepsFromSchema } from './configuration/steps.js';
9
+ import { unflattenConfig } from './configuration/transformation.js';
10
+ import { createAnthropicService } from './services/anthropic.js';
11
+ import { createCommand, createConfig, createFeedback, createMessage, createWelcome, } from './services/components.js';
12
+ import { registerGlobalShortcut } from './services/keyboard.js';
13
+ import { initializeLogger, setDebugLevel } from './services/logger.js';
14
+ import { Workflow } from './components/Workflow.js';
15
15
  export const Main = ({ app, command, serviceFactory = createAnthropicService, }) => {
16
16
  const [service, setService] = useState(null);
17
17
  const [initialQueue, setInitialQueue] = useState(null);
@@ -2,20 +2,20 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { memo } from 'react';
3
3
  import { ComponentStatus, } from '../types/components.js';
4
4
  import { ComponentName } from '../types/types.js';
5
- import { Answer, AnswerView } from './Answer.js';
6
- import { Command, CommandView } from './Command.js';
7
- import { Config, ConfigView } from './Config.js';
8
- import { Confirm, ConfirmView } from './Confirm.js';
9
- import { Debug } from './Debug.js';
10
- import { Execute, ExecuteView, mapStateToViewProps } from './Execute.js';
11
- import { Feedback } from './Feedback.js';
12
- import { Introspect, IntrospectView } from './Introspect.js';
13
- import { Message } from './Message.js';
14
- import { Refinement, RefinementView } from './Refinement.js';
15
- import { Report } from './Report.js';
16
- import { Schedule, ScheduleView } from './Schedule.js';
17
- import { Validate, ValidateView } from './Validate.js';
18
- import { Welcome } from './Welcome.js';
5
+ import { Answer, AnswerView } from './controllers/Answer.js';
6
+ import { Command, CommandView } from './controllers/Command.js';
7
+ import { Config, ConfigView } from './controllers/Config.js';
8
+ import { Confirm, ConfirmView } from './controllers/Confirm.js';
9
+ import { Debug } from './views/Debug.js';
10
+ import { Execute, ExecuteView, mapStateToViewProps, } from './controllers/Execute.js';
11
+ import { Feedback } from './views/Feedback.js';
12
+ import { Introspect, IntrospectView } from './controllers/Introspect.js';
13
+ import { Message } from './views/Message.js';
14
+ import { Refinement, RefinementView } from './controllers/Refinement.js';
15
+ import { Report } from './views/Report.js';
16
+ import { Schedule, ScheduleView } from './controllers/Schedule.js';
17
+ import { Validate, ValidateView } from './controllers/Validate.js';
18
+ import { Welcome } from './views/Welcome.js';
19
19
  /**
20
20
  * Render a simple component (no lifecycle management)
21
21
  */
@@ -75,16 +75,16 @@ export const ControllerComponent = memo(function ControllerComponent({ def, debu
75
75
  return (_jsx(Introspect, { tasks: tasks, service: service, children: children, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status, debug: debug }));
76
76
  }
77
77
  case ComponentName.Answer: {
78
- const { props: { question, service }, status, } = def;
79
- return (_jsx(Answer, { question: question, service: service, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status }));
78
+ const { props: { question, service, upcoming }, status, } = def;
79
+ return (_jsx(Answer, { question: question, service: service, upcoming: upcoming, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status }));
80
80
  }
81
81
  case ComponentName.Validate: {
82
82
  const { props: { missingConfig, userRequest, service, onError, onValidationComplete, onAborted, }, status, } = def;
83
83
  return (_jsx(Validate, { missingConfig: missingConfig, userRequest: userRequest, service: service, onError: onError, onValidationComplete: onValidationComplete, onAborted: onAborted, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status }));
84
84
  }
85
85
  case ComponentName.Execute: {
86
- const { props: { tasks, service }, status, } = def;
87
- return (_jsx(Execute, { tasks: tasks, service: service, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status }));
86
+ const { props: { tasks, service, upcoming, label }, status, } = def;
87
+ return (_jsx(Execute, { tasks: tasks, service: service, upcoming: upcoming, label: label, requestHandlers: requestHandlers, lifecycleHandlers: lifecycleHandlers, workflowHandlers: workflowHandlers, status: status }));
88
88
  }
89
89
  default:
90
90
  throw new Error(`Unknown managed component: ${def.name}`);
@@ -97,7 +97,7 @@ export const ViewComponent = memo(function ViewComponent({ def, }) {
97
97
  switch (def.name) {
98
98
  case ComponentName.Confirm: {
99
99
  const { props: { message }, state, status, } = def;
100
- return _jsx(ConfirmView, { message: message, state: state, status: status });
100
+ return (_jsx(ConfirmView, { status: status, message: message, selectedIndex: state.selectedIndex }));
101
101
  }
102
102
  case ComponentName.Config: {
103
103
  const { props: { steps }, state, status, } = def;
@@ -105,17 +105,18 @@ export const ViewComponent = memo(function ViewComponent({ def, }) {
105
105
  }
106
106
  case ComponentName.Schedule: {
107
107
  const { props: { message, tasks }, state, status, } = def;
108
- return (_jsx(ScheduleView, { message: message, tasks: tasks, state: state, status: status }));
108
+ return (_jsx(ScheduleView, { status: status, message: message, tasks: tasks, highlightedIndex: state.highlightedIndex, currentDefineGroupIndex: state.currentDefineGroupIndex, completedSelections: state.completedSelections }));
109
109
  }
110
110
  case ComponentName.Execute: {
111
- const { state, status } = def;
111
+ const { props: { upcoming, label }, state, status, } = def;
112
112
  const isActive = status === ComponentStatus.Active;
113
- const viewProps = mapStateToViewProps(state, isActive);
113
+ const viewProps = mapStateToViewProps(state, isActive, upcoming, label);
114
114
  return _jsx(ExecuteView, { ...viewProps });
115
115
  }
116
116
  case ComponentName.Answer: {
117
- const { props: { question }, state, status, } = def;
118
- return _jsx(AnswerView, { question: question, state: state, status: status });
117
+ const { props: { question, upcoming }, state, status, } = def;
118
+ const lines = state.answer ? state.answer.split('\n') : null;
119
+ return (_jsx(AnswerView, { status: status, question: question, lines: lines, error: state.error, upcoming: upcoming, cancelled: state.cancelled }));
119
120
  }
120
121
  case ComponentName.Command: {
121
122
  const { props: { command }, state, status, } = def;
@@ -123,11 +124,12 @@ export const ViewComponent = memo(function ViewComponent({ def, }) {
123
124
  }
124
125
  case ComponentName.Introspect: {
125
126
  const { props: { children }, state, status, } = def;
126
- return (_jsx(IntrospectView, { state: state, status: status, children: children }));
127
+ const hasCapabilities = state.capabilities.length > 0;
128
+ return (_jsx(IntrospectView, { status: status, hasCapabilities: hasCapabilities, error: state.error, children: children }));
127
129
  }
128
130
  case ComponentName.Validate: {
129
131
  const { state, status } = def;
130
- return _jsx(ValidateView, { state: state, status: status });
132
+ return (_jsx(ValidateView, { status: status, completionMessage: state.completionMessage, error: state.error }));
131
133
  }
132
134
  case ComponentName.Refinement: {
133
135
  const { props: { text }, status, } = def;
@@ -47,9 +47,8 @@ export const Workflow = ({ initialQueue, debug }) => {
47
47
  const requestHandlers = useMemo(() => ({
48
48
  onError: (error) => {
49
49
  moveActiveToTimeline();
50
- // Add feedback to queue
51
- setQueue((queue) => [
52
- ...queue,
50
+ // Clear queue and add only feedback to prevent subsequent components from executing
51
+ setQueue([
53
52
  createFeedback({ type: FeedbackType.Failed, message: error }),
54
53
  ]);
55
54
  },
@@ -1,28 +1,29 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
- import { Box, Text } from 'ink';
4
- import { ComponentStatus, } from '../types/components.js';
5
- import { Colors, getTextColor } from '../services/colors.js';
6
- import { useInput } from '../services/keyboard.js';
7
- import { formatErrorMessage } from '../services/messages.js';
8
- import { withMinimumTime } from '../services/timing.js';
9
- import { Spinner } from './Spinner.js';
3
+ import { ComponentStatus, } from '../../types/components.js';
4
+ import { useInput } from '../../services/keyboard.js';
5
+ import { formatErrorMessage } from '../../services/messages.js';
6
+ import { withMinimumTime } from '../../services/timing.js';
7
+ import { AnswerView } from '../views/Answer.js';
8
+ export { AnswerView } from '../views/Answer.js';
10
9
  const MINIMUM_PROCESSING_TIME = 400;
11
- export const AnswerView = ({ question, state, status }) => {
12
- const isActive = status === ComponentStatus.Active;
13
- const { error, answer } = state;
14
- const lines = answer ? answer.split('\n') : [];
15
- return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isActive && !answer && !error && (_jsxs(Box, { marginLeft: 1, children: [_jsx(Text, { color: getTextColor(isActive), children: "Finding answer. " }), _jsx(Spinner, {})] })), answer && (_jsxs(_Fragment, { children: [_jsx(Box, { marginLeft: 1, marginBottom: 1, children: _jsx(Text, { color: getTextColor(isActive), children: question }) }), _jsx(Box, { flexDirection: "column", paddingLeft: 3, children: lines.map((line, index) => (_jsx(Text, { color: getTextColor(isActive), children: line }, index))) })] })), error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) }))] }));
16
- };
17
10
  /**
18
11
  * Answer controller: Fetches answer from LLM
19
12
  */
20
- export function Answer({ question, status, service, requestHandlers, lifecycleHandlers, workflowHandlers, }) {
13
+ export function Answer({ question, status, service, upcoming, requestHandlers, lifecycleHandlers, workflowHandlers, }) {
21
14
  const isActive = status === ComponentStatus.Active;
22
15
  const [error, setError] = useState(null);
23
16
  const [answer, setAnswer] = useState(null);
17
+ const [cancelled, setCancelled] = useState(false);
24
18
  useInput((input, key) => {
25
19
  if (key.escape && isActive) {
20
+ setCancelled(true);
21
+ const finalState = {
22
+ answer: null,
23
+ error: null,
24
+ cancelled: true,
25
+ };
26
+ requestHandlers.onCompleted(finalState);
26
27
  requestHandlers.onAborted('answer');
27
28
  }
28
29
  }, { isActive });
@@ -80,6 +81,6 @@ export function Answer({ question, status, service, requestHandlers, lifecycleHa
80
81
  lifecycleHandlers,
81
82
  workflowHandlers,
82
83
  ]);
83
- const state = { error, answer };
84
- return _jsx(AnswerView, { question: question, state: state, status: status });
84
+ const lines = answer ? answer.split('\n') : null;
85
+ return (_jsx(AnswerView, { status: status, question: question, lines: lines, error: error, upcoming: upcoming, cancelled: cancelled }));
85
86
  }
@@ -1,23 +1,16 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
- import { Box, Text } from 'ink';
4
- import { ComponentStatus, } from '../types/components.js';
5
- import { TaskType } from '../types/types.js';
6
- import { Colors } from '../services/colors.js';
7
- import { createSchedule } from '../services/components.js';
8
- import { useInput } from '../services/keyboard.js';
9
- import { formatErrorMessage } from '../services/messages.js';
10
- import { handleRefinement } from '../services/refinement.js';
11
- import { routeTasksWithConfirm } from '../services/router.js';
12
- import { ensureMinimumTime } from '../services/timing.js';
13
- import { Spinner } from './Spinner.js';
14
- import { UserQuery } from './UserQuery.js';
3
+ import { ComponentStatus, } from '../../types/components.js';
4
+ import { TaskType } from '../../types/types.js';
5
+ import { createSchedule } from '../../services/components.js';
6
+ import { useInput } from '../../services/keyboard.js';
7
+ import { formatErrorMessage } from '../../services/messages.js';
8
+ import { handleRefinement } from '../../services/refinement.js';
9
+ import { routeTasksWithConfirm } from '../../services/router.js';
10
+ import { ensureMinimumTime } from '../../services/timing.js';
11
+ import { CommandView } from '../views/Command.js';
12
+ export { CommandView } from '../views/Command.js';
15
13
  const MIN_PROCESSING_TIME = 400; // purely for visual effect
16
- export const CommandView = ({ command, state, status }) => {
17
- const isActive = status === ComponentStatus.Active;
18
- const { error } = state;
19
- return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [!isActive ? (_jsxs(UserQuery, { children: ["> pls ", command] })) : (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: Colors.Text.Active, children: ["> pls ", command] }), _jsx(Text, { children: " " }), _jsx(Spinner, {})] })), error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) }))] }));
20
- };
21
14
  /**
22
15
  * Command controller: Processes and routes command
23
16
  */
@@ -1,120 +1,12 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
- import { Box, Text, useFocus } from 'ink';
4
- import TextInput from 'ink-text-input';
5
- import { ComponentStatus } from '../types/components.js';
6
- import { FeedbackType } from '../types/types.js';
7
- import { Colors } from '../services/colors.js';
8
- import { createFeedback } from '../services/components.js';
9
- import { DebugLevel } from '../configuration/types.js';
10
- import { useInput } from '../services/keyboard.js';
11
- /**
12
- * Get postfix with debug brackets if debug is enabled
13
- * Info: {key} | Verbose: {key} entry
14
- */
15
- function getPostfix(text, debugLevel) {
16
- if (debugLevel === DebugLevel.None || !text) {
17
- return '';
18
- }
19
- if (debugLevel === DebugLevel.Info) {
20
- return `{${text}}`;
21
- }
22
- return `{${text}} entry`;
23
- }
24
- export var StepType;
25
- (function (StepType) {
26
- StepType["Text"] = "text";
27
- StepType["Selection"] = "selection";
28
- })(StepType || (StepType = {}));
29
- function TextStep({ value, placeholder, validate, onChange, onSubmit, }) {
30
- const [inputValue, setInputValue] = useState(value);
31
- const [validationFailed, setValidationFailed] = useState(false);
32
- const { isFocused } = useFocus({ autoFocus: true });
33
- // Sync internal state with prop changes
34
- useEffect(() => {
35
- setInputValue(value);
36
- }, [value]);
37
- const handleChange = (newValue) => {
38
- setInputValue(newValue);
39
- onChange(newValue);
40
- if (validationFailed) {
41
- setValidationFailed(false);
42
- }
43
- };
44
- const handleSubmit = (value) => {
45
- // Use placeholder if input is empty
46
- const finalValue = value || placeholder || '';
47
- if (!validate(finalValue)) {
48
- setValidationFailed(true);
49
- return;
50
- }
51
- onSubmit(finalValue);
52
- };
53
- // Handle input manually when validation fails
54
- useInput((input, key) => {
55
- if (!validationFailed)
56
- return;
57
- if (key.return) {
58
- handleSubmit(inputValue);
59
- }
60
- else if (key.backspace || key.delete) {
61
- const newValue = inputValue.slice(0, -1);
62
- handleChange(newValue);
63
- }
64
- else if (!key.ctrl && !key.meta && input) {
65
- const newValue = inputValue + input;
66
- handleChange(newValue);
67
- }
68
- }, { isActive: validationFailed });
69
- // When validation fails, show colored text
70
- if (validationFailed) {
71
- return (_jsxs(Text, { color: Colors.Status.Error, children: [inputValue || placeholder, isFocused && _jsx(Text, { inverse: true, children: " " })] }));
72
- }
73
- return (_jsx(TextInput, { value: inputValue, onChange: handleChange, onSubmit: handleSubmit, placeholder: placeholder }));
74
- }
75
- function SelectionStep({ options, selectedIndex, isCurrentStep, }) {
76
- return (_jsx(Box, { children: options.map((option, optIndex) => {
77
- const isSelected = optIndex === selectedIndex;
78
- return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { dimColor: !isSelected || !isCurrentStep, bold: isSelected, children: option.label }) }, option.value));
79
- }) }));
80
- }
81
- export const ConfigView = ({ steps, state, status, debug = DebugLevel.None, onInputChange, onInputSubmit, }) => {
82
- const isActive = status === ComponentStatus.Active;
83
- const { values, completedStep, selectedIndex } = state;
84
- const renderStepInput = (stepConfig, isCurrentStep) => {
85
- const configKey = stepConfig.path || stepConfig.key;
86
- const displayValue = values[configKey];
87
- switch (stepConfig.type) {
88
- case StepType.Text:
89
- if (isCurrentStep && onInputChange && onInputSubmit) {
90
- return (_jsx(TextStep, { value: values[configKey] || '', placeholder: stepConfig.value || undefined, validate: stepConfig.validate, onChange: onInputChange, onSubmit: onInputSubmit }));
91
- }
92
- return (_jsx(Text, { dimColor: true, wrap: "truncate-end", children: displayValue || '' }));
93
- case StepType.Selection: {
94
- if (!isCurrentStep) {
95
- const option = stepConfig.options.find((opt) => opt.value === displayValue);
96
- return _jsx(Text, { dimColor: true, children: option?.label || '' });
97
- }
98
- return (_jsx(SelectionStep, { options: stepConfig.options, selectedIndex: selectedIndex, isCurrentStep: true }));
99
- }
100
- default: {
101
- const _exhaustiveCheck = stepConfig;
102
- throw new Error('Unsupported step type');
103
- }
104
- }
105
- };
106
- return (_jsx(Box, { flexDirection: "column", marginLeft: 1, children: steps.map((stepConfig, index) => {
107
- const isCurrentStep = index === completedStep && isActive;
108
- const isCompleted = index < completedStep;
109
- const wasAborted = index === completedStep && !isActive;
110
- const shouldShow = isCompleted || isCurrentStep || wasAborted;
111
- if (!shouldShow) {
112
- return null;
113
- }
114
- const postfix = getPostfix(stepConfig.path, debug);
115
- return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { children: [_jsx(Text, { children: stepConfig.description }), _jsx(Text, { children: ": " }), postfix && _jsx(Text, { color: Colors.Type.Config, children: postfix })] }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: Colors.Action.Select, dimColor: !isCurrentStep, children: ">" }), _jsx(Text, { children: " " }), renderStepInput(stepConfig, isCurrentStep)] })] }, stepConfig.path || stepConfig.key));
116
- }) }));
117
- };
3
+ import { ComponentStatus } from '../../types/components.js';
4
+ import { FeedbackType } from '../../types/types.js';
5
+ import { createFeedback } from '../../services/components.js';
6
+ import { DebugLevel } from '../../configuration/types.js';
7
+ import { useInput } from '../../services/keyboard.js';
8
+ import { ConfigView, StepType } from '../views/Config.js';
9
+ export { ConfigView, StepType, } from '../views/Config.js';
118
10
  /**
119
11
  * Config controller: Multi-step wizard logic
120
12
  */
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { ComponentStatus, } from '../../types/components.js';
4
+ import { useInput } from '../../services/keyboard.js';
5
+ import { ConfirmView } from '../views/Confirm.js';
6
+ export { ConfirmView } from '../views/Confirm.js';
7
+ /**
8
+ * Confirm controller: Manages yes/no selection
9
+ */
10
+ export function Confirm({ message, status, requestHandlers, onConfirmed, onCancelled, }) {
11
+ const isActive = status === ComponentStatus.Active;
12
+ const [selectedIndex, setSelectedIndex] = useState(0); // 0 = Yes, 1 = No
13
+ useInput((input, key) => {
14
+ if (!isActive)
15
+ return;
16
+ if (key.escape) {
17
+ // Escape: highlight "No" and cancel
18
+ const finalState = { selectedIndex: 1, confirmed: false };
19
+ requestHandlers.onCompleted(finalState);
20
+ onCancelled();
21
+ }
22
+ else if (key.tab) {
23
+ // Toggle between Yes (0) and No (1)
24
+ setSelectedIndex((prev) => (prev === 0 ? 1 : 0));
25
+ }
26
+ else if (key.return) {
27
+ // Confirm selection
28
+ const finalState = {
29
+ selectedIndex,
30
+ confirmed: true,
31
+ };
32
+ requestHandlers.onCompleted(finalState);
33
+ if (selectedIndex === 0) {
34
+ onConfirmed();
35
+ }
36
+ else {
37
+ onCancelled();
38
+ }
39
+ }
40
+ }, { isActive });
41
+ return (_jsx(ConfirmView, { status: status, message: message, selectedIndex: selectedIndex }));
42
+ }