prompt-language-shell 0.8.2 → 0.8.6
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.
- package/dist/configuration/io.js +85 -0
- package/dist/configuration/messages.js +30 -0
- package/dist/configuration/schema.js +167 -0
- package/dist/configuration/transformation.js +55 -0
- package/dist/configuration/types.js +30 -0
- package/dist/configuration/validation.js +52 -0
- package/dist/execution/handlers.js +135 -0
- package/dist/execution/processing.js +35 -0
- package/dist/execution/reducer.js +148 -0
- package/dist/execution/types.js +12 -0
- package/dist/execution/validation.js +12 -0
- package/dist/index.js +1 -1
- package/dist/services/anthropic.js +43 -56
- package/dist/services/colors.js +2 -1
- package/dist/services/components.js +40 -24
- package/dist/services/config-labels.js +15 -15
- package/dist/services/filesystem.js +114 -0
- package/dist/services/loader.js +8 -5
- package/dist/services/logger.js +26 -1
- package/dist/services/messages.js +32 -1
- package/dist/services/parser.js +3 -1
- package/dist/services/refinement.js +10 -10
- package/dist/services/router.js +43 -27
- package/dist/services/skills.js +12 -11
- package/dist/services/validator.js +4 -3
- package/dist/types/guards.js +4 -6
- package/dist/types/handlers.js +1 -0
- package/dist/types/schemas.js +103 -0
- package/dist/types/types.js +1 -0
- package/dist/ui/Answer.js +38 -16
- package/dist/ui/Command.js +48 -22
- package/dist/ui/Component.js +147 -33
- package/dist/ui/Config.js +69 -78
- package/dist/ui/Confirm.js +34 -21
- package/dist/ui/Execute.js +151 -178
- package/dist/ui/Feedback.js +1 -0
- package/dist/ui/Introspect.js +54 -25
- package/dist/ui/Label.js +1 -1
- package/dist/ui/Main.js +10 -6
- package/dist/ui/Refinement.js +8 -1
- package/dist/ui/Schedule.js +76 -53
- package/dist/ui/Validate.js +77 -77
- package/dist/ui/Workflow.js +60 -61
- package/package.json +3 -2
- package/dist/services/configuration.js +0 -409
package/dist/ui/Config.js
CHANGED
|
@@ -6,7 +6,7 @@ import { ComponentStatus } from '../types/components.js';
|
|
|
6
6
|
import { FeedbackType } from '../types/types.js';
|
|
7
7
|
import { Colors } from '../services/colors.js';
|
|
8
8
|
import { createFeedback } from '../services/components.js';
|
|
9
|
-
import { DebugLevel } from '../
|
|
9
|
+
import { DebugLevel } from '../configuration/types.js';
|
|
10
10
|
import { useInput } from '../services/keyboard.js';
|
|
11
11
|
/**
|
|
12
12
|
* Get postfix with debug brackets if debug is enabled
|
|
@@ -78,15 +78,52 @@ function SelectionStep({ options, selectedIndex, isCurrentStep, }) {
|
|
|
78
78
|
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { dimColor: !isSelected || !isCurrentStep, bold: isSelected, children: option.label }) }, option.value));
|
|
79
79
|
}) }));
|
|
80
80
|
}
|
|
81
|
-
export
|
|
81
|
+
export const ConfigView = ({ steps, state, status, debug = DebugLevel.None, onInputChange, onInputSubmit, }) => {
|
|
82
82
|
const isActive = status === ComponentStatus.Active;
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
+
}
|
|
88
104
|
}
|
|
89
|
-
|
|
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
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Config controller: Multi-step wizard logic
|
|
120
|
+
*/
|
|
121
|
+
export function Config(props) {
|
|
122
|
+
const { steps, status, debug = DebugLevel.None, requestHandlers, lifecycleHandlers, onFinished, onAborted, } = props;
|
|
123
|
+
const isActive = status === ComponentStatus.Active;
|
|
124
|
+
const [step, setStep] = useState(0);
|
|
125
|
+
const [values, setValues] = useState(() => {
|
|
126
|
+
// Initialize from step defaults
|
|
90
127
|
const initial = {};
|
|
91
128
|
steps.forEach((stepConfig) => {
|
|
92
129
|
// Use full path if available, otherwise use key
|
|
@@ -111,26 +148,14 @@ export function Config({ steps, state, status, debug = DebugLevel.None, handlers
|
|
|
111
148
|
});
|
|
112
149
|
const [inputValue, setInputValue] = useState(() => {
|
|
113
150
|
// Initialize with the current step's value if available
|
|
114
|
-
if (
|
|
151
|
+
if (step < steps.length) {
|
|
115
152
|
const stepConfig = steps[step];
|
|
116
153
|
const configKey = stepConfig.path || stepConfig.key;
|
|
117
154
|
return values[configKey] || '';
|
|
118
155
|
}
|
|
119
156
|
return '';
|
|
120
157
|
});
|
|
121
|
-
const [selectedIndex, setSelectedIndex] = useState(
|
|
122
|
-
// If not active, use saved state
|
|
123
|
-
if (!isActive && state?.selectedIndex !== undefined) {
|
|
124
|
-
return state.selectedIndex;
|
|
125
|
-
}
|
|
126
|
-
// Initialize selectedIndex based on current step's defaultIndex
|
|
127
|
-
if (isActive &&
|
|
128
|
-
step < steps.length &&
|
|
129
|
-
steps[step].type === StepType.Selection) {
|
|
130
|
-
return steps[step].defaultIndex;
|
|
131
|
-
}
|
|
132
|
-
return 0;
|
|
133
|
-
});
|
|
158
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
134
159
|
const normalizeValue = (value) => {
|
|
135
160
|
if (value === null || value === undefined) {
|
|
136
161
|
return '';
|
|
@@ -166,20 +191,21 @@ export function Config({ steps, state, status, debug = DebugLevel.None, handlers
|
|
|
166
191
|
throw new Error('Unsupported step type');
|
|
167
192
|
}
|
|
168
193
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
values,
|
|
194
|
+
const finalValues = currentValue
|
|
195
|
+
? { ...values, [configKey]: currentValue }
|
|
196
|
+
: values;
|
|
197
|
+
// Expose final state
|
|
198
|
+
const finalState = {
|
|
199
|
+
values: finalValues,
|
|
175
200
|
completedStep: step,
|
|
176
201
|
selectedIndex,
|
|
177
|
-
}
|
|
202
|
+
};
|
|
203
|
+
requestHandlers.onCompleted(finalState);
|
|
178
204
|
if (onAborted) {
|
|
179
205
|
onAborted('configuration');
|
|
180
206
|
}
|
|
181
207
|
// Complete with abort feedback
|
|
182
|
-
|
|
208
|
+
lifecycleHandlers.completeActive(createFeedback(FeedbackType.Aborted, 'Configuration cancelled.'));
|
|
183
209
|
return;
|
|
184
210
|
}
|
|
185
211
|
// Handle selection step navigation
|
|
@@ -191,7 +217,7 @@ export function Config({ steps, state, status, debug = DebugLevel.None, handlers
|
|
|
191
217
|
handleSubmit(currentStepConfig.options[selectedIndex].value);
|
|
192
218
|
}
|
|
193
219
|
}
|
|
194
|
-
});
|
|
220
|
+
}, { isActive });
|
|
195
221
|
const handleSubmit = (value) => {
|
|
196
222
|
const currentStepConfig = steps[step];
|
|
197
223
|
let finalValue = '';
|
|
@@ -229,37 +255,29 @@ export function Config({ steps, state, status, debug = DebugLevel.None, handlers
|
|
|
229
255
|
setInputValue('');
|
|
230
256
|
if (step === steps.length - 1) {
|
|
231
257
|
// Last step completed
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
const stateUpdate = {
|
|
258
|
+
// Expose final state
|
|
259
|
+
const finalState = {
|
|
235
260
|
values: newValues,
|
|
236
261
|
completedStep: steps.length,
|
|
237
262
|
selectedIndex,
|
|
238
263
|
};
|
|
239
|
-
|
|
264
|
+
requestHandlers.onCompleted(finalState);
|
|
240
265
|
// Call onFinished callback and handle result
|
|
241
266
|
try {
|
|
242
267
|
if (onFinished) {
|
|
243
268
|
onFinished(newValues);
|
|
244
269
|
}
|
|
245
270
|
// Success - complete with success feedback
|
|
246
|
-
|
|
271
|
+
lifecycleHandlers.completeActive(createFeedback(FeedbackType.Succeeded, 'Configuration saved successfully.'));
|
|
247
272
|
}
|
|
248
273
|
catch (error) {
|
|
249
274
|
// Failure - complete with error feedback
|
|
250
275
|
const errorMessage = error instanceof Error ? error.message : 'Configuration failed';
|
|
251
|
-
|
|
276
|
+
lifecycleHandlers.completeActive(createFeedback(FeedbackType.Failed, errorMessage));
|
|
252
277
|
}
|
|
253
278
|
setStep(steps.length);
|
|
254
279
|
}
|
|
255
280
|
else {
|
|
256
|
-
// Save state after each step
|
|
257
|
-
const stateUpdate = {
|
|
258
|
-
values: newValues,
|
|
259
|
-
completedStep: step + 1,
|
|
260
|
-
selectedIndex,
|
|
261
|
-
};
|
|
262
|
-
handlers?.updateState(stateUpdate);
|
|
263
281
|
const nextStep = step + 1;
|
|
264
282
|
setStep(nextStep);
|
|
265
283
|
// Reset selectedIndex for next step
|
|
@@ -269,39 +287,12 @@ export function Config({ steps, state, status, debug = DebugLevel.None, handlers
|
|
|
269
287
|
}
|
|
270
288
|
}
|
|
271
289
|
};
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (isCurrentStep) {
|
|
279
|
-
return (_jsx(TextStep, { value: inputValue, placeholder: stepConfig.value || undefined, validate: stepConfig.validate, onChange: setInputValue, onSubmit: handleSubmit }));
|
|
280
|
-
}
|
|
281
|
-
return (_jsx(Text, { dimColor: true, wrap: "truncate-end", children: displayValue || '' }));
|
|
282
|
-
case StepType.Selection: {
|
|
283
|
-
if (!isCurrentStep) {
|
|
284
|
-
// Find the option that matches the saved/current value
|
|
285
|
-
const option = stepConfig.options.find((opt) => opt.value === displayValue);
|
|
286
|
-
return _jsx(Text, { dimColor: true, children: option?.label || '' });
|
|
287
|
-
}
|
|
288
|
-
return (_jsx(SelectionStep, { options: stepConfig.options, selectedIndex: selectedIndex, isCurrentStep: true }));
|
|
289
|
-
}
|
|
290
|
-
default: {
|
|
291
|
-
const _exhaustiveCheck = stepConfig;
|
|
292
|
-
throw new Error('Unsupported step type');
|
|
293
|
-
}
|
|
294
|
-
}
|
|
290
|
+
// Build current state for View
|
|
291
|
+
// Controller always renders View, passing current state and callbacks
|
|
292
|
+
const state = {
|
|
293
|
+
values,
|
|
294
|
+
completedStep: step,
|
|
295
|
+
selectedIndex,
|
|
295
296
|
};
|
|
296
|
-
return (_jsx(
|
|
297
|
-
const isCurrentStep = index === step && isActive;
|
|
298
|
-
const isCompleted = index < step;
|
|
299
|
-
const wasAborted = index === step && !isActive;
|
|
300
|
-
const shouldShow = isCompleted || isCurrentStep || wasAborted;
|
|
301
|
-
if (!shouldShow) {
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
const postfix = getPostfix(stepConfig.path, debug);
|
|
305
|
-
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));
|
|
306
|
-
}) }));
|
|
297
|
+
return (_jsx(ConfigView, { steps: steps, state: state, status: status, debug: debug, onInputChange: setInputValue, onInputSubmit: handleSubmit }));
|
|
307
298
|
}
|
package/dist/ui/Confirm.js
CHANGED
|
@@ -1,31 +1,53 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Box, Text } from 'ink';
|
|
4
|
-
import { ComponentStatus } from '../types/components.js';
|
|
4
|
+
import { ComponentStatus, } from '../types/components.js';
|
|
5
5
|
import { Colors, getTextColor, Palette } from '../services/colors.js';
|
|
6
6
|
import { useInput } from '../services/keyboard.js';
|
|
7
7
|
import { UserQuery } from './UserQuery.js';
|
|
8
|
-
export
|
|
8
|
+
export const ConfirmView = ({ message, state, status }) => {
|
|
9
9
|
const isActive = status === ComponentStatus.Active;
|
|
10
|
-
const
|
|
10
|
+
const { selectedIndex } = state;
|
|
11
|
+
const options = [
|
|
12
|
+
{ label: 'yes', value: 'yes', color: Palette.BrightGreen },
|
|
13
|
+
{ label: 'no', value: 'no', color: Colors.Status.Error },
|
|
14
|
+
];
|
|
15
|
+
// Timeline rendering (Done status)
|
|
16
|
+
if (status === ComponentStatus.Done) {
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: undefined, children: message }) }), _jsxs(UserQuery, { children: ["> ", options[selectedIndex].label] })] }));
|
|
18
|
+
}
|
|
19
|
+
// Active/Pending rendering
|
|
20
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: message }) }), _jsxs(Box, { marginLeft: 1, children: [_jsx(Text, { color: Colors.Action.Select, children: ">" }), _jsx(Text, { children: " " }), _jsx(Box, { children: options.map((option, index) => {
|
|
21
|
+
const isSelected = index === selectedIndex;
|
|
22
|
+
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { color: isSelected ? option.color : undefined, dimColor: !isSelected, children: option.label }) }, option.value));
|
|
23
|
+
}) })] })] }));
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Confirm controller: Manages yes/no selection
|
|
27
|
+
*/
|
|
28
|
+
export function Confirm({ message, status, requestHandlers, onConfirmed, onCancelled, }) {
|
|
29
|
+
const isActive = status === ComponentStatus.Active;
|
|
30
|
+
const [selectedIndex, setSelectedIndex] = useState(0); // 0 = Yes, 1 = No
|
|
11
31
|
useInput((input, key) => {
|
|
12
32
|
if (!isActive)
|
|
13
33
|
return;
|
|
14
34
|
if (key.escape) {
|
|
15
35
|
// Escape: highlight "No" and cancel
|
|
16
|
-
|
|
17
|
-
|
|
36
|
+
const finalState = { selectedIndex: 1, confirmed: false };
|
|
37
|
+
requestHandlers.onCompleted(finalState);
|
|
18
38
|
onCancelled();
|
|
19
39
|
}
|
|
20
40
|
else if (key.tab) {
|
|
21
41
|
// Toggle between Yes (0) and No (1)
|
|
22
|
-
|
|
23
|
-
setSelectedIndex(newIndex);
|
|
24
|
-
handlers?.updateState({ selectedIndex: newIndex });
|
|
42
|
+
setSelectedIndex((prev) => (prev === 0 ? 1 : 0));
|
|
25
43
|
}
|
|
26
44
|
else if (key.return) {
|
|
27
45
|
// Confirm selection
|
|
28
|
-
|
|
46
|
+
const finalState = {
|
|
47
|
+
selectedIndex,
|
|
48
|
+
confirmed: true,
|
|
49
|
+
};
|
|
50
|
+
requestHandlers.onCompleted(finalState);
|
|
29
51
|
if (selectedIndex === 0) {
|
|
30
52
|
onConfirmed();
|
|
31
53
|
}
|
|
@@ -34,16 +56,7 @@ export function Confirm({ message, state, status, handlers, onConfirmed, onCance
|
|
|
34
56
|
}
|
|
35
57
|
}
|
|
36
58
|
}, { isActive });
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
];
|
|
41
|
-
if (!isActive) {
|
|
42
|
-
// When done, show both the message and user's choice in timeline
|
|
43
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: undefined, children: message }) }), _jsxs(UserQuery, { children: ["> ", options[selectedIndex].label] })] }));
|
|
44
|
-
}
|
|
45
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: message }) }), _jsxs(Box, { marginLeft: 1, children: [_jsx(Text, { color: Colors.Action.Select, children: ">" }), _jsx(Text, { children: " " }), _jsx(Box, { children: options.map((option, index) => {
|
|
46
|
-
const isSelected = index === selectedIndex;
|
|
47
|
-
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { color: isSelected ? option.color : undefined, dimColor: !isSelected, children: option.label }) }, option.value));
|
|
48
|
-
}) })] })] }));
|
|
59
|
+
// Controller always renders View, passing current state
|
|
60
|
+
const state = { selectedIndex, confirmed: false };
|
|
61
|
+
return _jsx(ConfirmView, { message: message, state: state, status: status });
|
|
49
62
|
}
|