prompt-language-shell 0.6.8 → 0.7.2
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/index.js +2 -1
- package/dist/services/anthropic.js +21 -2
- package/dist/services/colors.js +30 -0
- package/dist/services/components.js +11 -0
- package/dist/services/configuration.js +23 -5
- package/dist/services/logger.js +64 -0
- package/dist/services/messages.js +2 -2
- package/dist/services/refinement.js +4 -0
- package/dist/services/registry.js +2 -2
- package/dist/services/router.js +2 -4
- package/dist/services/skills.js +1 -2
- package/dist/skills/answer.md +10 -9
- package/dist/skills/{config.md → configure.md} +19 -12
- package/dist/skills/execute.md +91 -53
- package/dist/skills/introspect.md +63 -47
- package/dist/skills/plan.md +426 -339
- package/dist/skills/validate.md +36 -20
- package/dist/tools/{config.tool.js → configure.tool.js} +7 -7
- package/dist/types/types.js +2 -1
- package/dist/ui/Command.js +7 -3
- package/dist/ui/Component.js +3 -0
- package/dist/ui/Config.js +24 -5
- package/dist/ui/Debug.js +8 -0
- package/dist/ui/Introspect.js +3 -2
- package/dist/ui/Label.js +4 -3
- package/dist/ui/Main.js +28 -9
- package/dist/ui/Plan.js +8 -7
- package/dist/ui/Validate.js +2 -2
- package/dist/ui/Workflow.js +2 -1
- package/package.json +1 -1
package/dist/skills/validate.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
## Overview
|
|
2
2
|
|
|
3
|
-
You are the validation component of "pls" (please), responsible for
|
|
3
|
+
You are the validation component of "pls" (please), responsible for
|
|
4
|
+
validating skill requirements and generating natural language descriptions
|
|
5
|
+
for missing configuration values.
|
|
4
6
|
|
|
5
|
-
Your role is to help users understand what configuration values are needed
|
|
7
|
+
Your role is to help users understand what configuration values are needed
|
|
8
|
+
and why, using context from skill descriptions to create clear, helpful
|
|
9
|
+
prompts.
|
|
6
10
|
|
|
7
11
|
## Input
|
|
8
12
|
|
|
@@ -17,22 +21,27 @@ You will receive information about missing configuration values:
|
|
|
17
21
|
Generate a response with two required fields:
|
|
18
22
|
|
|
19
23
|
1. **message**: An empty string `""`
|
|
20
|
-
2. **tasks**: An array of
|
|
24
|
+
2. **tasks**: An array of CONFIGURE tasks, one for each missing config
|
|
25
|
+
value
|
|
21
26
|
|
|
22
|
-
For each
|
|
27
|
+
For each CONFIGURE task, create a natural language description that:
|
|
23
28
|
|
|
24
|
-
1. **Explains what the value is for** using context from the skill's
|
|
29
|
+
1. **Explains what the value is for** using context from the skill's
|
|
30
|
+
description
|
|
25
31
|
2. **Keeps it SHORT** - one brief phrase (3-6 words max)
|
|
26
|
-
3. **Does NOT include the config path** - the path will be shown
|
|
32
|
+
3. **Does NOT include the config path** - the path will be shown
|
|
33
|
+
separately in debug mode
|
|
27
34
|
|
|
28
|
-
**CRITICAL**: You MUST include both the `message` field (set to empty
|
|
35
|
+
**CRITICAL**: You MUST include both the `message` field (set to empty
|
|
36
|
+
string) and the `tasks` array in your response.
|
|
29
37
|
|
|
30
38
|
## Description Format
|
|
31
39
|
|
|
32
40
|
**Format:** "Brief description" (DO NOT include {config.path}!)
|
|
33
41
|
|
|
34
42
|
The description should:
|
|
35
|
-
- Start with what the config value represents (e.g., "Path to...", "URL
|
|
43
|
+
- Start with what the config value represents (e.g., "Path to...", "URL
|
|
44
|
+
for...", "Name of...")
|
|
36
45
|
- Be SHORT and direct - no extra details or variant explanations
|
|
37
46
|
- NEVER include the config path in curly brackets like {config.path}
|
|
38
47
|
|
|
@@ -51,7 +60,7 @@ message: ""
|
|
|
51
60
|
tasks: [
|
|
52
61
|
{
|
|
53
62
|
action: "Path to Alpha repository",
|
|
54
|
-
type: "
|
|
63
|
+
type: "configure",
|
|
55
64
|
params: { key: "project.alpha.repo" }
|
|
56
65
|
}
|
|
57
66
|
]
|
|
@@ -70,7 +79,7 @@ message: ""
|
|
|
70
79
|
tasks: [
|
|
71
80
|
{
|
|
72
81
|
action: "Staging environment URL",
|
|
73
|
-
type: "
|
|
82
|
+
type: "configure",
|
|
74
83
|
params: { key: "env.staging.url" }
|
|
75
84
|
}
|
|
76
85
|
]
|
|
@@ -89,7 +98,7 @@ message: ""
|
|
|
89
98
|
tasks: [
|
|
90
99
|
{
|
|
91
100
|
action: "Path to Beta workspace",
|
|
92
|
-
type: "
|
|
101
|
+
type: "configure",
|
|
93
102
|
params: { key: "workspace.beta.path" }
|
|
94
103
|
}
|
|
95
104
|
]
|
|
@@ -97,11 +106,16 @@ tasks: [
|
|
|
97
106
|
|
|
98
107
|
## Guidelines
|
|
99
108
|
|
|
100
|
-
1. **Use skill context**: Read the skill's Description section to
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
1. **Use skill context**: Read the skill's Description section to
|
|
110
|
+
understand what the variant represents
|
|
111
|
+
2. **Be specific**: Don't just say "Repository path" - say "Path to Alpha
|
|
112
|
+
repository"
|
|
113
|
+
3. **Add helpful details**: Include information from the description when
|
|
114
|
+
relevant
|
|
115
|
+
4. **Keep it concise**: One brief phrase that clearly explains what's
|
|
116
|
+
needed
|
|
117
|
+
5. **Never include the path**: Do not append `{config.path}` - it's shown
|
|
118
|
+
separately in debug mode
|
|
105
119
|
|
|
106
120
|
## Common Config Types
|
|
107
121
|
|
|
@@ -116,14 +130,15 @@ tasks: [
|
|
|
116
130
|
|
|
117
131
|
## Response Format
|
|
118
132
|
|
|
119
|
-
Return a message field (can be empty string) and an array of
|
|
133
|
+
Return a message field (can be empty string) and an array of CONFIGURE
|
|
134
|
+
tasks:
|
|
120
135
|
|
|
121
136
|
```
|
|
122
137
|
message: ""
|
|
123
138
|
tasks: [
|
|
124
139
|
{
|
|
125
140
|
action: "Natural description without config path",
|
|
126
|
-
type: "
|
|
141
|
+
type: "configure",
|
|
127
142
|
params: { key: "config.path" }
|
|
128
143
|
},
|
|
129
144
|
// ... more tasks
|
|
@@ -132,9 +147,10 @@ tasks: [
|
|
|
132
147
|
|
|
133
148
|
## Important Notes
|
|
134
149
|
|
|
135
|
-
- All tasks must have type "
|
|
150
|
+
- All tasks must have type "configure"
|
|
136
151
|
- All tasks must include params.key with the config path
|
|
137
152
|
- Descriptions should be helpful and contextual, not just technical
|
|
138
153
|
- Use information from Available Skills section to provide context
|
|
139
154
|
- Keep descriptions to one brief phrase (3-6 words)
|
|
140
|
-
- NEVER include the config path in the action/description - it's shown
|
|
155
|
+
- NEVER include the config path in the action/description - it's shown
|
|
156
|
+
separately
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const
|
|
2
|
-
name: '
|
|
1
|
+
export const configureTool = {
|
|
2
|
+
name: 'configure',
|
|
3
3
|
description: 'Determine which configuration settings to show based on user query. Receives available config keys with descriptions and returns which keys the user wants to configure.',
|
|
4
4
|
input_schema: {
|
|
5
5
|
type: 'object',
|
|
@@ -10,25 +10,25 @@ export const configTool = {
|
|
|
10
10
|
},
|
|
11
11
|
tasks: {
|
|
12
12
|
type: 'array',
|
|
13
|
-
description: '
|
|
13
|
+
description: 'Settings the user wants to configure. Each task specifies which setting to configure.',
|
|
14
14
|
items: {
|
|
15
15
|
type: 'object',
|
|
16
16
|
properties: {
|
|
17
17
|
action: {
|
|
18
18
|
type: 'string',
|
|
19
|
-
description: 'Description of the
|
|
19
|
+
description: 'Description of the setting (from the provided descriptions). Maximum 64 characters.',
|
|
20
20
|
},
|
|
21
21
|
type: {
|
|
22
22
|
type: 'string',
|
|
23
|
-
description: 'Always "
|
|
23
|
+
description: 'Task type. Always "configure" for settings.',
|
|
24
24
|
},
|
|
25
25
|
params: {
|
|
26
26
|
type: 'object',
|
|
27
|
-
description: '
|
|
27
|
+
description: 'Task parameters.',
|
|
28
28
|
properties: {
|
|
29
29
|
key: {
|
|
30
30
|
type: 'string',
|
|
31
|
-
description: 'The
|
|
31
|
+
description: 'The setting key to configure (e.g., "anthropic.key", "settings.debug").',
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
required: ['key'],
|
package/dist/types/types.js
CHANGED
|
@@ -3,6 +3,7 @@ export var ComponentName;
|
|
|
3
3
|
ComponentName["Welcome"] = "welcome";
|
|
4
4
|
ComponentName["Config"] = "config";
|
|
5
5
|
ComponentName["Message"] = "message";
|
|
6
|
+
ComponentName["Debug"] = "debug";
|
|
6
7
|
ComponentName["Command"] = "command";
|
|
7
8
|
ComponentName["Plan"] = "plan";
|
|
8
9
|
ComponentName["Refinement"] = "refinement";
|
|
@@ -16,7 +17,7 @@ export var ComponentName;
|
|
|
16
17
|
})(ComponentName || (ComponentName = {}));
|
|
17
18
|
export var TaskType;
|
|
18
19
|
(function (TaskType) {
|
|
19
|
-
TaskType["Config"] = "
|
|
20
|
+
TaskType["Config"] = "configure";
|
|
20
21
|
TaskType["Plan"] = "plan";
|
|
21
22
|
TaskType["Execute"] = "execute";
|
|
22
23
|
TaskType["Answer"] = "answer";
|
package/dist/ui/Command.js
CHANGED
|
@@ -37,17 +37,21 @@ export function Command({ command, state, status, service, handlers, onAborted,
|
|
|
37
37
|
const startTime = Date.now();
|
|
38
38
|
try {
|
|
39
39
|
let result = await svc.processWithTool(command, 'plan');
|
|
40
|
-
// If all tasks are
|
|
40
|
+
// If all tasks are configure type, delegate to CONFIGURE tool
|
|
41
41
|
const allConfig = result.tasks.length > 0 &&
|
|
42
42
|
result.tasks.every((task) => task.type === TaskType.Config);
|
|
43
43
|
if (allConfig) {
|
|
44
44
|
// Extract query from first config task params, default to 'app'
|
|
45
45
|
const query = result.tasks[0].params?.query || 'app';
|
|
46
|
-
// Call
|
|
47
|
-
result = await svc.processWithTool(query, '
|
|
46
|
+
// Call CONFIGURE tool to get specific config keys
|
|
47
|
+
result = await svc.processWithTool(query, 'configure');
|
|
48
48
|
}
|
|
49
49
|
await ensureMinimumTime(startTime, MIN_PROCESSING_TIME);
|
|
50
50
|
if (mounted) {
|
|
51
|
+
// Add debug components to timeline if present
|
|
52
|
+
if (result.debug && result.debug.length > 0) {
|
|
53
|
+
handlers?.addToTimeline(...result.debug);
|
|
54
|
+
}
|
|
51
55
|
// Save result to state for timeline display
|
|
52
56
|
handlers?.updateState({
|
|
53
57
|
message: result.message,
|
package/dist/ui/Component.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Answer } from './Answer.js';
|
|
|
5
5
|
import { Command } from './Command.js';
|
|
6
6
|
import { Confirm } from './Confirm.js';
|
|
7
7
|
import { Config } from './Config.js';
|
|
8
|
+
import { Debug } from './Debug.js';
|
|
8
9
|
import { Execute } from './Execute.js';
|
|
9
10
|
import { Feedback } from './Feedback.js';
|
|
10
11
|
import { Introspect } from './Introspect.js';
|
|
@@ -28,6 +29,8 @@ export const Component = memo(function Component({ def, debug, }) {
|
|
|
28
29
|
return _jsx(Feedback, { ...def.props, status: def.status });
|
|
29
30
|
case ComponentName.Message:
|
|
30
31
|
return _jsx(Message, { ...def.props, status: def.status });
|
|
32
|
+
case ComponentName.Debug:
|
|
33
|
+
return _jsx(Debug, { ...def.props, status: def.status });
|
|
31
34
|
case ComponentName.Refinement:
|
|
32
35
|
return (_jsx(Refinement, { ...def.props, state: def.state, status: def.status }));
|
|
33
36
|
case ComponentName.Confirm:
|
package/dist/ui/Config.js
CHANGED
|
@@ -3,7 +3,10 @@ import { useState } from 'react';
|
|
|
3
3
|
import { Box, Text, useFocus } from 'ink';
|
|
4
4
|
import TextInput from 'ink-text-input';
|
|
5
5
|
import { ComponentStatus } from '../types/components.js';
|
|
6
|
+
import { FeedbackType } from '../types/types.js';
|
|
6
7
|
import { Colors } from '../services/colors.js';
|
|
8
|
+
import { createFeedback } from '../services/components.js';
|
|
9
|
+
import { DebugLevel } from '../services/configuration.js';
|
|
7
10
|
import { useInput } from '../services/keyboard.js';
|
|
8
11
|
export var StepType;
|
|
9
12
|
(function (StepType) {
|
|
@@ -58,7 +61,7 @@ function SelectionStep({ options, selectedIndex, isCurrentStep, }) {
|
|
|
58
61
|
return (_jsx(Box, { marginRight: 2, children: _jsx(Text, { dimColor: !isSelected || !isCurrentStep, bold: isSelected, children: option.label }) }, option.value));
|
|
59
62
|
}) }));
|
|
60
63
|
}
|
|
61
|
-
export function Config({ steps, state, status, debug, handlers, onFinished, onAborted, }) {
|
|
64
|
+
export function Config({ steps, state, status, debug = DebugLevel.None, handlers, onFinished, onAborted, }) {
|
|
62
65
|
const isActive = status === ComponentStatus.Active;
|
|
63
66
|
const [step, setStep] = useState(!isActive ? (state?.completedStep ?? steps.length) : 0);
|
|
64
67
|
const [values, setValues] = useState(() => {
|
|
@@ -130,9 +133,16 @@ export function Config({ steps, state, status, debug, handlers, onFinished, onAb
|
|
|
130
133
|
setValues({ ...values, [configKey]: currentValue });
|
|
131
134
|
}
|
|
132
135
|
}
|
|
136
|
+
// Save state before aborting
|
|
137
|
+
handlers?.updateState({
|
|
138
|
+
values,
|
|
139
|
+
completedStep: step,
|
|
140
|
+
});
|
|
133
141
|
if (onAborted) {
|
|
134
142
|
onAborted('configuration');
|
|
135
143
|
}
|
|
144
|
+
// Complete with abort feedback
|
|
145
|
+
handlers?.completeActive(createFeedback(FeedbackType.Aborted, 'Configuration cancelled.'));
|
|
136
146
|
return;
|
|
137
147
|
}
|
|
138
148
|
// Handle selection step navigation
|
|
@@ -189,9 +199,18 @@ export function Config({ steps, state, status, debug, handlers, onFinished, onAb
|
|
|
189
199
|
completedStep: steps.length,
|
|
190
200
|
};
|
|
191
201
|
handlers?.updateState(stateUpdate);
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
onFinished
|
|
202
|
+
// Call onFinished callback and handle result
|
|
203
|
+
try {
|
|
204
|
+
if (onFinished) {
|
|
205
|
+
onFinished(newValues);
|
|
206
|
+
}
|
|
207
|
+
// Success - complete with success feedback
|
|
208
|
+
handlers?.completeActive(createFeedback(FeedbackType.Succeeded, 'Configuration saved successfully.'));
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
// Failure - complete with error feedback
|
|
212
|
+
const errorMessage = error instanceof Error ? error.message : 'Configuration failed';
|
|
213
|
+
handlers?.completeActive(createFeedback(FeedbackType.Failed, errorMessage));
|
|
195
214
|
}
|
|
196
215
|
setStep(steps.length);
|
|
197
216
|
}
|
|
@@ -243,6 +262,6 @@ export function Config({ steps, state, status, debug, handlers, onFinished, onAb
|
|
|
243
262
|
if (!shouldShow) {
|
|
244
263
|
return null;
|
|
245
264
|
}
|
|
246
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { children: [_jsx(Text, { children: stepConfig.description }), _jsx(Text, { children: ": " }), debug && stepConfig.path && (_jsxs(Text, { color: Colors.Type.Define, children: ['{', stepConfig.path, '}'] }))] }), _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));
|
|
265
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { children: [_jsx(Text, { children: stepConfig.description }), _jsx(Text, { children: ": " }), debug !== DebugLevel.None && stepConfig.path && (_jsxs(Text, { color: Colors.Type.Define, children: ['{', stepConfig.path, '}'] }))] }), _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));
|
|
247
266
|
}) }));
|
|
248
267
|
}
|
package/dist/ui/Debug.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
const MIN_CONTENT_WIDTH = 80;
|
|
4
|
+
const HORIZONTAL_PADDING = 2;
|
|
5
|
+
const BORDER_WIDTH = 1;
|
|
6
|
+
export const Debug = ({ title, content, color }) => {
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: HORIZONTAL_PADDING, paddingY: 1, borderStyle: "single", borderColor: color, alignSelf: "flex-start", minWidth: MIN_CONTENT_WIDTH + 2 * HORIZONTAL_PADDING + 2 * BORDER_WIDTH, children: [_jsx(Text, { color: color, children: title }), _jsx(Text, { color: color, children: content })] }));
|
|
8
|
+
};
|
package/dist/ui/Introspect.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Box, Text } from 'ink';
|
|
|
4
4
|
import { ComponentStatus, } from '../types/components.js';
|
|
5
5
|
import { Colors, getTextColor } from '../services/colors.js';
|
|
6
6
|
import { createReportDefinition } from '../services/components.js';
|
|
7
|
+
import { DebugLevel } from '../services/configuration.js';
|
|
7
8
|
import { useInput } from '../services/keyboard.js';
|
|
8
9
|
import { formatErrorMessage } from '../services/messages.js';
|
|
9
10
|
import { ensureMinimumTime } from '../services/timing.js';
|
|
@@ -51,7 +52,7 @@ function parseCapabilityFromTask(task) {
|
|
|
51
52
|
isIncomplete,
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
|
-
export function Introspect({ tasks, state, status, service, children, debug =
|
|
55
|
+
export function Introspect({ tasks, state, status, service, children, debug = DebugLevel.None, handlers, }) {
|
|
55
56
|
const isActive = status === ComponentStatus.Active;
|
|
56
57
|
// isActive passed as prop
|
|
57
58
|
const [error, setError] = useState(null);
|
|
@@ -83,7 +84,7 @@ export function Introspect({ tasks, state, status, service, children, debug = fa
|
|
|
83
84
|
// Parse capabilities from returned tasks
|
|
84
85
|
let capabilities = result.tasks.map(parseCapabilityFromTask);
|
|
85
86
|
// Filter out internal capabilities when not in debug mode
|
|
86
|
-
if (
|
|
87
|
+
if (debug === DebugLevel.None) {
|
|
87
88
|
capabilities = capabilities.filter((cap) => cap.name.toUpperCase() !== 'PLAN' &&
|
|
88
89
|
cap.name.toUpperCase() !== 'VALIDATE' &&
|
|
89
90
|
cap.name.toUpperCase() !== 'REPORT');
|
package/dist/ui/Label.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
-
import {
|
|
3
|
+
import { DebugLevel } from '../services/configuration.js';
|
|
4
|
+
import { getTaskColors, getTaskTypeLabel } from '../services/colors.js';
|
|
4
5
|
import { Separator } from './Separator.js';
|
|
5
|
-
export function Label({ description, taskType, showType = false, isCurrent = false, }) {
|
|
6
|
+
export function Label({ description, taskType, showType = false, isCurrent = false, debug = DebugLevel.None, }) {
|
|
6
7
|
const colors = getTaskColors(taskType, isCurrent);
|
|
7
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: colors.description, children: description }), showType && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(Text, { color: colors.type, children: taskType })] }))] }));
|
|
8
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: colors.description, children: description }), showType && (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(Text, { color: colors.type, children: getTaskTypeLabel(taskType, debug) })] }))] }));
|
|
8
9
|
}
|
package/dist/ui/Main.js
CHANGED
|
@@ -3,18 +3,32 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { FeedbackType } from '../types/types.js';
|
|
4
4
|
import { createAnthropicService, } from '../services/anthropic.js';
|
|
5
5
|
import { createCommandDefinition, createConfigDefinitionWithKeys, createFeedback, createMessage, createWelcomeDefinition, } from '../services/components.js';
|
|
6
|
-
import { getConfigurationRequiredMessage, getMissingConfigKeys, loadConfig, loadDebugSetting,
|
|
6
|
+
import { DebugLevel, getConfigurationRequiredMessage, getMissingConfigKeys, loadConfig, loadDebugSetting, saveConfig, saveDebugSetting, unflattenConfig, } from '../services/configuration.js';
|
|
7
7
|
import { registerGlobalShortcut } from '../services/keyboard.js';
|
|
8
|
+
import { initializeLogger, setDebugLevel } from '../services/logger.js';
|
|
8
9
|
import { Workflow } from './Workflow.js';
|
|
9
10
|
export const Main = ({ app, command }) => {
|
|
10
11
|
const [service, setService] = useState(null);
|
|
11
12
|
const [initialQueue, setInitialQueue] = useState(null);
|
|
12
|
-
const [
|
|
13
|
+
const [debug, setDebugLevelState] = useState(() => loadDebugSetting());
|
|
14
|
+
// Initialize logger on mount
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
initializeLogger();
|
|
17
|
+
}, []);
|
|
18
|
+
// Update logger when debug level changes
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
setDebugLevel(debug);
|
|
21
|
+
}, [debug]);
|
|
13
22
|
// Register global keyboard shortcuts
|
|
14
23
|
useEffect(() => {
|
|
15
24
|
registerGlobalShortcut('shift+tab', () => {
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
setDebugLevelState((prev) => {
|
|
26
|
+
// Cycle through: None -> Info -> Verbose -> None
|
|
27
|
+
const newValue = prev === DebugLevel.None
|
|
28
|
+
? DebugLevel.Info
|
|
29
|
+
: prev === DebugLevel.Info
|
|
30
|
+
? DebugLevel.Verbose
|
|
31
|
+
: DebugLevel.None;
|
|
18
32
|
saveDebugSetting(newValue);
|
|
19
33
|
return newValue;
|
|
20
34
|
});
|
|
@@ -55,20 +69,25 @@ export const Main = ({ app, command }) => {
|
|
|
55
69
|
const handleConfigFinished = (config) => {
|
|
56
70
|
// Save config and create service
|
|
57
71
|
try {
|
|
58
|
-
const
|
|
72
|
+
const configBySection = unflattenConfig(config);
|
|
73
|
+
for (const [section, sectionConfig] of Object.entries(configBySection)) {
|
|
74
|
+
saveConfig(section, sectionConfig);
|
|
75
|
+
}
|
|
76
|
+
// Load config and create service
|
|
77
|
+
const newConfig = loadConfig();
|
|
59
78
|
const newService = createAnthropicService(newConfig.anthropic);
|
|
60
79
|
setService(newService);
|
|
61
80
|
}
|
|
62
81
|
catch (error) {
|
|
63
|
-
// Config
|
|
82
|
+
// Config save failed
|
|
64
83
|
const errorMessage = error instanceof Error
|
|
65
84
|
? error.message
|
|
66
85
|
: 'Failed to save configuration';
|
|
67
|
-
|
|
86
|
+
throw new Error(errorMessage);
|
|
68
87
|
}
|
|
69
88
|
};
|
|
70
89
|
const handleConfigAborted = (operation) => {
|
|
71
|
-
// Config was cancelled
|
|
90
|
+
// Config was cancelled
|
|
72
91
|
};
|
|
73
92
|
setInitialQueue([
|
|
74
93
|
createWelcomeDefinition(app),
|
|
@@ -90,5 +109,5 @@ export const Main = ({ app, command }) => {
|
|
|
90
109
|
if (initialQueue === null) {
|
|
91
110
|
return null;
|
|
92
111
|
}
|
|
93
|
-
return _jsx(Workflow, { initialQueue: initialQueue, debug:
|
|
112
|
+
return _jsx(Workflow, { initialQueue: initialQueue, debug: debug });
|
|
94
113
|
};
|
package/dist/ui/Plan.js
CHANGED
|
@@ -3,18 +3,19 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { Box } from 'ink';
|
|
4
4
|
import { ComponentStatus } from '../types/components.js';
|
|
5
5
|
import { TaskType } from '../types/types.js';
|
|
6
|
-
import {
|
|
6
|
+
import { DebugLevel } from '../services/configuration.js';
|
|
7
|
+
import { getTaskColors, getTaskTypeLabel } from '../services/colors.js';
|
|
7
8
|
import { useInput } from '../services/keyboard.js';
|
|
8
9
|
import { Label } from './Label.js';
|
|
9
10
|
import { List } from './List.js';
|
|
10
|
-
function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutSelection = false, isCurrent = false) {
|
|
11
|
+
function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutSelection = false, isCurrent = false, debug = DebugLevel.None) {
|
|
11
12
|
const taskColors = getTaskColors(task.type, isCurrent);
|
|
12
13
|
const item = {
|
|
13
14
|
description: {
|
|
14
15
|
text: task.action,
|
|
15
16
|
color: taskColors.description,
|
|
16
17
|
},
|
|
17
|
-
type: { text: task.type, color: taskColors.type },
|
|
18
|
+
type: { text: getTaskTypeLabel(task.type, debug), color: taskColors.type },
|
|
18
19
|
children: [],
|
|
19
20
|
};
|
|
20
21
|
// Mark define tasks with right arrow when no selection has been made
|
|
@@ -41,7 +42,7 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
|
|
|
41
42
|
highlightedColor: planColors.description,
|
|
42
43
|
},
|
|
43
44
|
type: {
|
|
44
|
-
text: childType,
|
|
45
|
+
text: getTaskTypeLabel(childType, debug),
|
|
45
46
|
color: colors.type,
|
|
46
47
|
highlightedColor: planColors.type,
|
|
47
48
|
},
|
|
@@ -50,7 +51,7 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
|
|
|
50
51
|
}
|
|
51
52
|
return item;
|
|
52
53
|
}
|
|
53
|
-
export function Plan({ message, tasks, state, status, debug =
|
|
54
|
+
export function Plan({ message, tasks, state, status, debug = DebugLevel.None, handlers, onSelectionConfirmed, }) {
|
|
54
55
|
const isActive = status === ComponentStatus.Active;
|
|
55
56
|
// isActive passed as prop
|
|
56
57
|
const [highlightedIndex, setHighlightedIndex] = useState(state?.highlightedIndex ?? null);
|
|
@@ -199,7 +200,7 @@ export function Plan({ message, tasks, state, status, debug = false, handlers, o
|
|
|
199
200
|
defineGroupIndex === currentDefineGroupIndex &&
|
|
200
201
|
highlightedIndex === null &&
|
|
201
202
|
isActive;
|
|
202
|
-
return taskToListItem(task, childIndex, isDefineWithoutSelection, isActive);
|
|
203
|
+
return taskToListItem(task, childIndex, isDefineWithoutSelection, isActive, debug);
|
|
203
204
|
});
|
|
204
|
-
return (_jsxs(Box, { flexDirection: "column", children: [message && (_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Label, { description: message, taskType: TaskType.Plan, showType: debug, isCurrent: isActive }) })), _jsx(Box, { marginLeft: 1, children: _jsx(List, { items: listItems, highlightedIndex: currentDefineTaskIndex >= 0 ? highlightedIndex : null, highlightedParentIndex: currentDefineTaskIndex, showType: debug }) })] }));
|
|
205
|
+
return (_jsxs(Box, { flexDirection: "column", children: [message && (_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Label, { description: message, taskType: TaskType.Plan, showType: debug !== DebugLevel.None, isCurrent: isActive, debug: debug }) })), _jsx(Box, { marginLeft: 1, children: _jsx(List, { items: listItems, highlightedIndex: currentDefineTaskIndex >= 0 ? highlightedIndex : null, highlightedParentIndex: currentDefineTaskIndex, showType: debug !== DebugLevel.None }) })] }));
|
|
205
206
|
}
|
package/dist/ui/Validate.js
CHANGED
|
@@ -7,11 +7,11 @@ import { Colors, getTextColor } from '../services/colors.js';
|
|
|
7
7
|
import { useInput } from '../services/keyboard.js';
|
|
8
8
|
import { formatErrorMessage } from '../services/messages.js';
|
|
9
9
|
import { ensureMinimumTime } from '../services/timing.js';
|
|
10
|
-
import { saveConfig, unflattenConfig } from '../services/configuration.js';
|
|
10
|
+
import { DebugLevel, saveConfig, unflattenConfig, } from '../services/configuration.js';
|
|
11
11
|
import { Config, StepType } from './Config.js';
|
|
12
12
|
import { Spinner } from './Spinner.js';
|
|
13
13
|
const MIN_PROCESSING_TIME = 1000;
|
|
14
|
-
export function Validate({ missingConfig, userRequest, state, status, service, children, debug, onError, onComplete, onAborted, handlers, }) {
|
|
14
|
+
export function Validate({ missingConfig, userRequest, state, status, service, children, debug = DebugLevel.None, onError, onComplete, onAborted, handlers, }) {
|
|
15
15
|
const isActive = status === ComponentStatus.Active;
|
|
16
16
|
const [error, setError] = useState(null);
|
|
17
17
|
const [completionMessage, setCompletionMessage] = useState(null);
|
package/dist/ui/Workflow.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Box, Static } from 'ink';
|
|
|
4
4
|
import { ComponentStatus, } from '../types/components.js';
|
|
5
5
|
import { ComponentName, FeedbackType } from '../types/types.js';
|
|
6
6
|
import { createFeedback, isStateless, markAsDone, } from '../services/components.js';
|
|
7
|
+
import { DebugLevel } from '../services/configuration.js';
|
|
7
8
|
import { exitApp } from '../services/process.js';
|
|
8
9
|
import { getCancellationMessage } from '../services/messages.js';
|
|
9
10
|
import { Component } from './Component.js';
|
|
@@ -188,5 +189,5 @@ export const Workflow = ({ initialQueue, debug }) => {
|
|
|
188
189
|
// Pending components don't receive input
|
|
189
190
|
return _jsx(Component, { def: pending, debug: debug }, pending.id);
|
|
190
191
|
}, [current, debug]);
|
|
191
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: timeline, children: (item) => (_jsx(Box, { marginTop: 1, children: _jsx(Component, { def: item, debug:
|
|
192
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: timeline, children: (item) => (_jsx(Box, { marginTop: 1, children: _jsx(Component, { def: item, debug: DebugLevel.None }) }, item.id)) }, "timeline"), pendingComponent && _jsx(Box, { marginTop: 1, children: pendingComponent }), activeComponent && _jsx(Box, { marginTop: 1, children: activeComponent })] }));
|
|
192
193
|
};
|