prompt-language-shell 0.3.4 → 0.3.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/services/components.js +28 -4
- package/dist/tools/plan.tool.js +1 -1
- package/dist/types/components.js +1 -28
- package/dist/types/types.js +29 -0
- package/dist/ui/Command.js +8 -2
- package/dist/ui/Component.js +7 -1
- package/dist/ui/Config.js +1 -1
- package/dist/ui/Feedback.js +1 -1
- package/dist/ui/Main.js +71 -23
- package/dist/ui/Message.js +2 -2
- package/dist/ui/Plan.js +28 -10
- package/dist/ui/Refinement.js +14 -0
- package/package.json +3 -2
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { ComponentName
|
|
3
|
-
import { StepType } from '../ui/Config.js';
|
|
2
|
+
import { ComponentName } from '../types/types.js';
|
|
4
3
|
import { AnthropicModel, isValidAnthropicApiKey, isValidAnthropicModel, } from './config.js';
|
|
4
|
+
import { StepType } from '../ui/Config.js';
|
|
5
5
|
export function markAsDone(component) {
|
|
6
6
|
return { ...component, state: { ...component.state, done: true } };
|
|
7
7
|
}
|
|
8
|
+
export function getRefiningMessage() {
|
|
9
|
+
const messages = [
|
|
10
|
+
'Let me work out the specifics for you.',
|
|
11
|
+
"I'll figure out the concrete steps.",
|
|
12
|
+
'Let me break this down into tasks.',
|
|
13
|
+
"I'll plan out the details.",
|
|
14
|
+
'Let me arrange the steps.',
|
|
15
|
+
"I'll prepare everything you need.",
|
|
16
|
+
];
|
|
17
|
+
return messages[Math.floor(Math.random() * messages.length)];
|
|
18
|
+
}
|
|
8
19
|
export function createWelcomeDefinition(app) {
|
|
9
20
|
return {
|
|
10
21
|
id: randomUUID(),
|
|
@@ -47,7 +58,7 @@ export function createConfigDefinition(onFinished, onAborted) {
|
|
|
47
58
|
},
|
|
48
59
|
};
|
|
49
60
|
}
|
|
50
|
-
export function createCommandDefinition(command, service, onError, onComplete) {
|
|
61
|
+
export function createCommandDefinition(command, service, onError, onComplete, onAborted) {
|
|
51
62
|
return {
|
|
52
63
|
id: randomUUID(),
|
|
53
64
|
name: ComponentName.Command,
|
|
@@ -60,10 +71,11 @@ export function createCommandDefinition(command, service, onError, onComplete) {
|
|
|
60
71
|
service,
|
|
61
72
|
onError,
|
|
62
73
|
onComplete,
|
|
74
|
+
onAborted,
|
|
63
75
|
},
|
|
64
76
|
};
|
|
65
77
|
}
|
|
66
|
-
export function createPlanDefinition(message, tasks, onSelectionConfirmed) {
|
|
78
|
+
export function createPlanDefinition(message, tasks, onAborted, onSelectionConfirmed) {
|
|
67
79
|
return {
|
|
68
80
|
id: randomUUID(),
|
|
69
81
|
name: ComponentName.Plan,
|
|
@@ -77,6 +89,7 @@ export function createPlanDefinition(message, tasks, onSelectionConfirmed) {
|
|
|
77
89
|
message,
|
|
78
90
|
tasks,
|
|
79
91
|
onSelectionConfirmed,
|
|
92
|
+
onAborted,
|
|
80
93
|
},
|
|
81
94
|
};
|
|
82
95
|
}
|
|
@@ -99,6 +112,17 @@ export function createMessage(text) {
|
|
|
99
112
|
},
|
|
100
113
|
};
|
|
101
114
|
}
|
|
115
|
+
export function createRefinement(text, onAborted) {
|
|
116
|
+
return {
|
|
117
|
+
id: randomUUID(),
|
|
118
|
+
name: ComponentName.Refinement,
|
|
119
|
+
state: { done: false },
|
|
120
|
+
props: {
|
|
121
|
+
text,
|
|
122
|
+
onAborted,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
102
126
|
export function isStateless(component) {
|
|
103
127
|
return !('state' in component);
|
|
104
128
|
}
|
package/dist/tools/plan.tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const planTool = {
|
|
2
2
|
name: 'plan',
|
|
3
|
-
description: 'Plan and structure tasks from a user command. Break down the request into clear, actionable steps with type information and parameters.',
|
|
3
|
+
description: 'Plan and structure tasks from a user command. Break down the request into clear, actionable steps with type information and parameters. When refining previously selected tasks, the input will be formatted as lowercase actions with types in brackets, e.g., "install the python development environment (type: execute), explain how virtual environments work (type: answer)".',
|
|
4
4
|
input_schema: {
|
|
5
5
|
type: 'object',
|
|
6
6
|
properties: {
|
package/dist/types/components.js
CHANGED
|
@@ -1,28 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
(function (ComponentName) {
|
|
3
|
-
ComponentName["Welcome"] = "welcome";
|
|
4
|
-
ComponentName["Config"] = "config";
|
|
5
|
-
ComponentName["Feedback"] = "feedback";
|
|
6
|
-
ComponentName["Message"] = "message";
|
|
7
|
-
ComponentName["Plan"] = "plan";
|
|
8
|
-
ComponentName["Command"] = "command";
|
|
9
|
-
})(ComponentName || (ComponentName = {}));
|
|
10
|
-
export var TaskType;
|
|
11
|
-
(function (TaskType) {
|
|
12
|
-
TaskType["Config"] = "config";
|
|
13
|
-
TaskType["Plan"] = "plan";
|
|
14
|
-
TaskType["Execute"] = "execute";
|
|
15
|
-
TaskType["Answer"] = "answer";
|
|
16
|
-
TaskType["Report"] = "report";
|
|
17
|
-
TaskType["Define"] = "define";
|
|
18
|
-
TaskType["Ignore"] = "ignore";
|
|
19
|
-
TaskType["Select"] = "select";
|
|
20
|
-
TaskType["Discard"] = "discard";
|
|
21
|
-
})(TaskType || (TaskType = {}));
|
|
22
|
-
export var FeedbackType;
|
|
23
|
-
(function (FeedbackType) {
|
|
24
|
-
FeedbackType["Info"] = "info";
|
|
25
|
-
FeedbackType["Succeeded"] = "succeeded";
|
|
26
|
-
FeedbackType["Aborted"] = "aborted";
|
|
27
|
-
FeedbackType["Failed"] = "failed";
|
|
28
|
-
})(FeedbackType || (FeedbackType = {}));
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export var ComponentName;
|
|
2
|
+
(function (ComponentName) {
|
|
3
|
+
ComponentName["Welcome"] = "welcome";
|
|
4
|
+
ComponentName["Config"] = "config";
|
|
5
|
+
ComponentName["Message"] = "message";
|
|
6
|
+
ComponentName["Command"] = "command";
|
|
7
|
+
ComponentName["Plan"] = "plan";
|
|
8
|
+
ComponentName["Refinement"] = "refinement";
|
|
9
|
+
ComponentName["Feedback"] = "feedback";
|
|
10
|
+
})(ComponentName || (ComponentName = {}));
|
|
11
|
+
export var TaskType;
|
|
12
|
+
(function (TaskType) {
|
|
13
|
+
TaskType["Config"] = "config";
|
|
14
|
+
TaskType["Plan"] = "plan";
|
|
15
|
+
TaskType["Execute"] = "execute";
|
|
16
|
+
TaskType["Answer"] = "answer";
|
|
17
|
+
TaskType["Report"] = "report";
|
|
18
|
+
TaskType["Define"] = "define";
|
|
19
|
+
TaskType["Ignore"] = "ignore";
|
|
20
|
+
TaskType["Select"] = "select";
|
|
21
|
+
TaskType["Discard"] = "discard";
|
|
22
|
+
})(TaskType || (TaskType = {}));
|
|
23
|
+
export var FeedbackType;
|
|
24
|
+
(function (FeedbackType) {
|
|
25
|
+
FeedbackType["Info"] = "info";
|
|
26
|
+
FeedbackType["Succeeded"] = "succeeded";
|
|
27
|
+
FeedbackType["Aborted"] = "aborted";
|
|
28
|
+
FeedbackType["Failed"] = "failed";
|
|
29
|
+
})(FeedbackType || (FeedbackType = {}));
|
package/dist/ui/Command.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
-
import { Box, Text } from 'ink';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
4
|
import { Spinner } from './Spinner.js';
|
|
5
5
|
const MIN_PROCESSING_TIME = 1000; // purely for visual effect
|
|
6
|
-
export function Command({ command, state, service, children, onError, onComplete, }) {
|
|
6
|
+
export function Command({ command, state, service, children, onError, onComplete, onAborted, }) {
|
|
7
7
|
const done = state?.done ?? false;
|
|
8
8
|
const [error, setError] = useState(null);
|
|
9
9
|
const [isLoading, setIsLoading] = useState(state?.isLoading ?? !done);
|
|
10
|
+
useInput((input, key) => {
|
|
11
|
+
if (key.escape && isLoading && !done) {
|
|
12
|
+
setIsLoading(false);
|
|
13
|
+
onAborted();
|
|
14
|
+
}
|
|
15
|
+
}, { isActive: isLoading && !done });
|
|
10
16
|
useEffect(() => {
|
|
11
17
|
// Skip processing if done (showing historical/final state)
|
|
12
18
|
if (done) {
|
package/dist/ui/Component.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { ComponentName } from '../types/
|
|
2
|
+
import { ComponentName } from '../types/types.js';
|
|
3
3
|
import { Command } from './Command.js';
|
|
4
4
|
import { Config } from './Config.js';
|
|
5
5
|
import { Feedback } from './Feedback.js';
|
|
6
6
|
import { Message } from './Message.js';
|
|
7
7
|
import { Plan } from './Plan.js';
|
|
8
|
+
import { Refinement } from './Refinement.js';
|
|
8
9
|
import { Welcome } from './Welcome.js';
|
|
9
10
|
export function Component({ def }) {
|
|
10
11
|
switch (def.name) {
|
|
@@ -26,5 +27,10 @@ export function Component({ def }) {
|
|
|
26
27
|
return _jsx(Feedback, { ...def.props });
|
|
27
28
|
case ComponentName.Message:
|
|
28
29
|
return _jsx(Message, { ...def.props });
|
|
30
|
+
case ComponentName.Refinement: {
|
|
31
|
+
const props = def.props;
|
|
32
|
+
const state = def.state;
|
|
33
|
+
return _jsx(Refinement, { ...props, state: state });
|
|
34
|
+
}
|
|
29
35
|
}
|
|
30
36
|
}
|
package/dist/ui/Config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Box, Text,
|
|
3
|
+
import { Box, Text, useFocus, useInput } from 'ink';
|
|
4
4
|
import TextInput from 'ink-text-input';
|
|
5
5
|
export var StepType;
|
|
6
6
|
(function (StepType) {
|
package/dist/ui/Feedback.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import { FeedbackType } from '../types/
|
|
3
|
+
import { FeedbackType } from '../types/types.js';
|
|
4
4
|
function getSymbol(type) {
|
|
5
5
|
return {
|
|
6
6
|
[FeedbackType.Info]: 'ℹ',
|
package/dist/ui/Main.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { ComponentName, TaskType, } from '../types/
|
|
3
|
+
import { ComponentName, FeedbackType, TaskType, } from '../types/types.js';
|
|
4
4
|
import { createAnthropicService, } from '../services/anthropic.js';
|
|
5
|
-
import { FeedbackType } from '../types/components.js';
|
|
6
5
|
import { getConfigurationRequiredMessage, hasValidAnthropicKey, loadConfig, saveAnthropicConfig, } from '../services/config.js';
|
|
7
|
-
import { createCommandDefinition, createConfigDefinition, createFeedback, createMessage, createPlanDefinition, createWelcomeDefinition, isStateless, markAsDone, } from '../services/components.js';
|
|
6
|
+
import { createCommandDefinition, createConfigDefinition, createFeedback, createMessage, createRefinement, createPlanDefinition, createWelcomeDefinition, getRefiningMessage, isStateless, markAsDone, } from '../services/components.js';
|
|
8
7
|
import { exitApp } from '../services/process.js';
|
|
9
8
|
import { Column } from './Column.js';
|
|
10
9
|
export const Main = ({ app, command }) => {
|
|
@@ -46,20 +45,81 @@ export const Main = ({ app, command }) => {
|
|
|
46
45
|
return [];
|
|
47
46
|
});
|
|
48
47
|
}, [addToTimeline]);
|
|
49
|
-
const
|
|
48
|
+
const handleAborted = React.useCallback((operationName) => {
|
|
50
49
|
setQueue((currentQueue) => {
|
|
51
50
|
if (currentQueue.length === 0)
|
|
52
51
|
return currentQueue;
|
|
53
52
|
const [first] = currentQueue;
|
|
54
|
-
if (first
|
|
55
|
-
|
|
56
|
-
addToTimeline(markAsDone(first));
|
|
53
|
+
if (!isStateless(first)) {
|
|
54
|
+
addToTimeline(markAsDone(first), createFeedback(FeedbackType.Aborted, `${operationName} was aborted by user`));
|
|
57
55
|
}
|
|
58
|
-
// Exit after selection is confirmed
|
|
59
56
|
exitApp(0);
|
|
60
57
|
return [];
|
|
61
58
|
});
|
|
62
59
|
}, [addToTimeline]);
|
|
60
|
+
const handleConfigAborted = React.useCallback(() => {
|
|
61
|
+
handleAborted('Configuration');
|
|
62
|
+
}, [handleAborted]);
|
|
63
|
+
const handlePlanAborted = React.useCallback(() => {
|
|
64
|
+
handleAborted('Task selection');
|
|
65
|
+
}, [handleAborted]);
|
|
66
|
+
const handleCommandAborted = React.useCallback(() => {
|
|
67
|
+
handleAborted('Request');
|
|
68
|
+
}, [handleAborted]);
|
|
69
|
+
const handleRefinementAborted = React.useCallback(() => {
|
|
70
|
+
handleAborted('Plan refinement');
|
|
71
|
+
}, [handleAborted]);
|
|
72
|
+
const handlePlanSelectionConfirmed = React.useCallback(async (selectedTasks) => {
|
|
73
|
+
// Mark current plan as done and add refinement to queue
|
|
74
|
+
let refinementDef = null;
|
|
75
|
+
refinementDef = createRefinement(getRefiningMessage(), handleRefinementAborted);
|
|
76
|
+
setQueue((currentQueue) => {
|
|
77
|
+
if (currentQueue.length === 0)
|
|
78
|
+
return currentQueue;
|
|
79
|
+
const [first] = currentQueue;
|
|
80
|
+
if (first.name === ComponentName.Plan) {
|
|
81
|
+
addToTimeline(markAsDone(first));
|
|
82
|
+
}
|
|
83
|
+
// Add refinement to queue so it becomes the active component
|
|
84
|
+
return [refinementDef];
|
|
85
|
+
});
|
|
86
|
+
// Process refined command in background
|
|
87
|
+
try {
|
|
88
|
+
const refinedCommand = selectedTasks
|
|
89
|
+
.map((task) => {
|
|
90
|
+
const action = task.action.toLowerCase().replace(/,/g, ' -');
|
|
91
|
+
const type = task.type || 'execute';
|
|
92
|
+
return `${action} (type: ${type})`;
|
|
93
|
+
})
|
|
94
|
+
.join(', ');
|
|
95
|
+
const result = await service.processWithTool(refinedCommand, 'plan');
|
|
96
|
+
// Mark refinement as done and move to timeline
|
|
97
|
+
setQueue((currentQueue) => {
|
|
98
|
+
if (currentQueue.length > 0 &&
|
|
99
|
+
currentQueue[0].id === refinementDef.id) {
|
|
100
|
+
addToTimeline(markAsDone(currentQueue[0]));
|
|
101
|
+
}
|
|
102
|
+
return [];
|
|
103
|
+
});
|
|
104
|
+
// Show final execution plan
|
|
105
|
+
const planDefinition = createPlanDefinition(result.message, result.tasks, handlePlanAborted, undefined);
|
|
106
|
+
addToTimeline(planDefinition);
|
|
107
|
+
exitApp(0);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
111
|
+
// Mark refinement as done and move to timeline before showing error
|
|
112
|
+
setQueue((currentQueue) => {
|
|
113
|
+
if (currentQueue.length > 0 &&
|
|
114
|
+
currentQueue[0].id === refinementDef.id) {
|
|
115
|
+
addToTimeline(markAsDone(currentQueue[0]));
|
|
116
|
+
}
|
|
117
|
+
return [];
|
|
118
|
+
});
|
|
119
|
+
addToTimeline(createFeedback(FeedbackType.Failed, 'Unexpected error occurred:', errorMessage));
|
|
120
|
+
exitApp(1);
|
|
121
|
+
}
|
|
122
|
+
}, [addToTimeline, service, handleRefinementAborted]);
|
|
63
123
|
const handleCommandComplete = React.useCallback((message, tasks) => {
|
|
64
124
|
setQueue((currentQueue) => {
|
|
65
125
|
if (currentQueue.length === 0)
|
|
@@ -68,7 +128,7 @@ export const Main = ({ app, command }) => {
|
|
|
68
128
|
// Check if tasks contain a Define task that requires user interaction
|
|
69
129
|
const hasDefineTask = tasks.some((task) => task.type === TaskType.Define);
|
|
70
130
|
if (first.name === ComponentName.Command) {
|
|
71
|
-
const planDefinition = createPlanDefinition(message, tasks, hasDefineTask ? handlePlanSelectionConfirmed : undefined);
|
|
131
|
+
const planDefinition = createPlanDefinition(message, tasks, handlePlanAborted, hasDefineTask ? handlePlanSelectionConfirmed : undefined);
|
|
72
132
|
if (hasDefineTask) {
|
|
73
133
|
// Don't exit - keep the plan in the queue for interaction
|
|
74
134
|
addToTimeline(markAsDone(first));
|
|
@@ -102,7 +162,7 @@ export const Main = ({ app, command }) => {
|
|
|
102
162
|
if (command) {
|
|
103
163
|
return [
|
|
104
164
|
...rest,
|
|
105
|
-
createCommandDefinition(command, newService, handleCommandError, handleCommandComplete),
|
|
165
|
+
createCommandDefinition(command, newService, handleCommandError, handleCommandComplete, handleCommandAborted),
|
|
106
166
|
];
|
|
107
167
|
}
|
|
108
168
|
// No command - exit after showing completion message
|
|
@@ -110,25 +170,13 @@ export const Main = ({ app, command }) => {
|
|
|
110
170
|
return rest;
|
|
111
171
|
});
|
|
112
172
|
}, [addToTimeline, command, handleCommandError, handleCommandComplete]);
|
|
113
|
-
const handleConfigAborted = React.useCallback(() => {
|
|
114
|
-
setQueue((currentQueue) => {
|
|
115
|
-
if (currentQueue.length === 0)
|
|
116
|
-
return currentQueue;
|
|
117
|
-
const [first] = currentQueue;
|
|
118
|
-
if (first.name === ComponentName.Config) {
|
|
119
|
-
addToTimeline(markAsDone(first), createFeedback(FeedbackType.Aborted, 'Configuration aborted by user'));
|
|
120
|
-
}
|
|
121
|
-
exitApp(0);
|
|
122
|
-
return [];
|
|
123
|
-
});
|
|
124
|
-
}, [addToTimeline]);
|
|
125
173
|
// Initialize queue on mount
|
|
126
174
|
React.useEffect(() => {
|
|
127
175
|
const hasConfig = !!service;
|
|
128
176
|
if (command && hasConfig) {
|
|
129
177
|
// With command + valid config: [Command]
|
|
130
178
|
setQueue([
|
|
131
|
-
createCommandDefinition(command, service, handleCommandError, handleCommandComplete),
|
|
179
|
+
createCommandDefinition(command, service, handleCommandError, handleCommandComplete, handleCommandAborted),
|
|
132
180
|
]);
|
|
133
181
|
}
|
|
134
182
|
else if (command && !hasConfig) {
|
package/dist/ui/Message.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Text } from 'ink';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
3
|
export const Message = ({ text }) => {
|
|
4
|
-
return _jsx(Text, { children: text });
|
|
4
|
+
return (_jsx(Box, { children: _jsx(Text, { children: text }) }));
|
|
5
5
|
};
|
package/dist/ui/Plan.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Box, useInput } from 'ink';
|
|
4
|
-
import { TaskType } from '../types/
|
|
4
|
+
import { TaskType } from '../types/types.js';
|
|
5
5
|
import { Label } from './Label.js';
|
|
6
6
|
import { List } from './List.js';
|
|
7
7
|
const ColorPalette = {
|
|
@@ -82,7 +82,7 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
|
|
|
82
82
|
}
|
|
83
83
|
return item;
|
|
84
84
|
}
|
|
85
|
-
export function Plan({ message, tasks, state, onSelectionConfirmed, }) {
|
|
85
|
+
export function Plan({ message, tasks, state, onSelectionConfirmed, onAborted, }) {
|
|
86
86
|
const [highlightedIndex, setHighlightedIndex] = useState(state?.highlightedIndex ?? null);
|
|
87
87
|
const [currentDefineGroupIndex, setCurrentDefineGroupIndex] = useState(state?.currentDefineGroupIndex ?? 0);
|
|
88
88
|
const [completedSelections, setCompletedSelections] = useState(state?.completedSelections ?? []);
|
|
@@ -103,6 +103,10 @@ export function Plan({ message, tasks, state, onSelectionConfirmed, }) {
|
|
|
103
103
|
if (isDone || !defineTask) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
+
if (key.escape) {
|
|
107
|
+
onAborted();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
106
110
|
if (key.downArrow) {
|
|
107
111
|
setHighlightedIndex((prev) => {
|
|
108
112
|
if (prev === null) {
|
|
@@ -136,14 +140,27 @@ export function Plan({ message, tasks, state, onSelectionConfirmed, }) {
|
|
|
136
140
|
if (state) {
|
|
137
141
|
state.done = true;
|
|
138
142
|
}
|
|
139
|
-
//
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
// Build refined task list with only selected options (no discarded or ignored ones)
|
|
144
|
+
const refinedTasks = [];
|
|
145
|
+
tasks.forEach((task, idx) => {
|
|
146
|
+
const defineGroupIndex = defineTaskIndices.indexOf(idx);
|
|
147
|
+
if (defineGroupIndex !== -1 &&
|
|
148
|
+
Array.isArray(task.params?.options)) {
|
|
149
|
+
// This is a Define task - only include the selected option
|
|
150
|
+
const options = task.params.options;
|
|
151
|
+
const selectedIndex = newCompletedSelections[defineGroupIndex];
|
|
152
|
+
refinedTasks.push({
|
|
153
|
+
action: String(options[selectedIndex]),
|
|
154
|
+
type: TaskType.Execute,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else if (task.type !== TaskType.Ignore &&
|
|
158
|
+
task.type !== TaskType.Discard) {
|
|
159
|
+
// Regular task - keep as is, but skip Ignore and Discard tasks
|
|
160
|
+
refinedTasks.push(task);
|
|
143
161
|
}
|
|
144
|
-
return task;
|
|
145
162
|
});
|
|
146
|
-
onSelectionConfirmed?.(
|
|
163
|
+
onSelectionConfirmed?.(refinedTasks);
|
|
147
164
|
}
|
|
148
165
|
}
|
|
149
166
|
}, { isActive: !isDone && defineTask !== null });
|
|
@@ -184,10 +201,11 @@ export function Plan({ message, tasks, state, onSelectionConfirmed, }) {
|
|
|
184
201
|
}
|
|
185
202
|
}
|
|
186
203
|
}
|
|
187
|
-
// Show arrow on current active define task when no child is highlighted
|
|
204
|
+
// Show arrow on current active define task when no child is highlighted and not done
|
|
188
205
|
const isDefineWithoutSelection = isDefineTask &&
|
|
189
206
|
defineGroupIndex === currentDefineGroupIndex &&
|
|
190
|
-
highlightedIndex === null
|
|
207
|
+
highlightedIndex === null &&
|
|
208
|
+
!isDone;
|
|
191
209
|
return taskToListItem(task, childIndex, isDefineWithoutSelection);
|
|
192
210
|
});
|
|
193
211
|
return (_jsxs(Box, { flexDirection: "column", children: [message && (_jsx(Box, { marginBottom: 1, children: _jsx(Label, { description: message, descriptionColor: ColorPalette[TaskType.Plan].description, type: TaskType.Plan, typeColor: ColorPalette[TaskType.Plan].type }) })), _jsx(List, { items: listItems, highlightedIndex: currentDefineTaskIndex >= 0 ? highlightedIndex : null, highlightedParentIndex: currentDefineTaskIndex })] }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, useInput } from 'ink';
|
|
3
|
+
import { Message } from './Message.js';
|
|
4
|
+
import { Spinner } from './Spinner.js';
|
|
5
|
+
export const Refinement = ({ text, state, onAborted }) => {
|
|
6
|
+
const isDone = state?.done ?? false;
|
|
7
|
+
useInput((input, key) => {
|
|
8
|
+
if (key.escape && !isDone) {
|
|
9
|
+
onAborted();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
}, { isActive: !isDone });
|
|
13
|
+
return (_jsxs(Box, { gap: 1, children: [_jsx(Message, { text: text }), !isDone && _jsx(Spinner, {})] }));
|
|
14
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-language-shell",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Your personal command-line concierge. Ask politely, and it gets things done.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"clean": "rm -rf dist",
|
|
15
|
-
"
|
|
15
|
+
"typecheck": "tsc --project tsconfig.eslint.json",
|
|
16
|
+
"build": "npm run typecheck && npm run clean && tsc && chmod +x dist/index.js && mkdir -p dist/config && cp src/config/*.md dist/config/",
|
|
16
17
|
"dev": "npm run build && tsc --watch",
|
|
17
18
|
"prepare": "husky",
|
|
18
19
|
"prepublishOnly": "npm run check",
|