prompt-language-shell 0.8.8 → 0.9.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/README.md +0 -1
- package/dist/configuration/io.js +22 -1
- package/dist/{services/config-labels.js → configuration/labels.js} +1 -1
- package/dist/configuration/schema.js +2 -2
- package/dist/configuration/steps.js +171 -0
- package/dist/configuration/transformation.js +17 -0
- package/dist/configuration/types.js +3 -4
- package/dist/execution/handlers.js +20 -35
- package/dist/execution/hooks.js +291 -0
- package/dist/execution/processing.js +15 -2
- package/dist/execution/reducer.js +30 -48
- package/dist/execution/runner.js +81 -0
- package/dist/execution/types.js +1 -0
- package/dist/execution/utils.js +28 -0
- package/dist/services/components.js +109 -395
- package/dist/services/filesystem.js +21 -1
- package/dist/services/logger.js +3 -3
- package/dist/services/messages.js +10 -16
- package/dist/services/process.js +7 -2
- package/dist/services/refinement.js +5 -2
- package/dist/services/router.js +120 -67
- package/dist/services/shell.js +179 -10
- package/dist/services/skills.js +2 -1
- package/dist/skills/answer.md +14 -12
- package/dist/skills/execute.md +98 -39
- package/dist/skills/introspect.md +9 -9
- package/dist/skills/schedule.md +0 -6
- package/dist/types/errors.js +47 -0
- package/dist/types/result.js +40 -0
- package/dist/ui/Command.js +11 -7
- package/dist/ui/Component.js +6 -3
- package/dist/ui/Config.js +9 -3
- package/dist/ui/Execute.js +249 -163
- package/dist/ui/Introspect.js +13 -14
- package/dist/ui/List.js +2 -2
- package/dist/ui/Main.js +14 -7
- package/dist/ui/Output.js +54 -0
- package/dist/ui/Schedule.js +3 -1
- package/dist/ui/Subtask.js +6 -3
- package/dist/ui/Task.js +10 -85
- package/dist/ui/Validate.js +26 -21
- package/dist/ui/Workflow.js +21 -4
- package/package.json +1 -1
- package/dist/parser.js +0 -13
- package/dist/services/config-utils.js +0 -20
|
@@ -1,408 +1,122 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { parse as parseYaml } from 'yaml';
|
|
3
|
-
import { ConfigDefinitionType, } from '../configuration/types.js';
|
|
4
2
|
import { ComponentStatus, } from '../types/components.js';
|
|
5
3
|
import { ComponentName } from '../types/types.js';
|
|
6
|
-
import { getConfigPath, loadConfig } from '../configuration/io.js';
|
|
7
|
-
import { getConfigSchema } from '../configuration/schema.js';
|
|
8
|
-
import { getConfigLabel } from './config-labels.js';
|
|
9
|
-
import { defaultFileSystem } from './filesystem.js';
|
|
10
|
-
import { getConfirmationMessage } from './messages.js';
|
|
11
|
-
import { StepType } from '../ui/Config.js';
|
|
12
|
-
export function createWelcomeDefinition(app) {
|
|
13
|
-
return {
|
|
14
|
-
id: randomUUID(),
|
|
15
|
-
name: ComponentName.Welcome,
|
|
16
|
-
props: { app },
|
|
17
|
-
status: ComponentStatus.Awaiting,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export function createConfigSteps() {
|
|
21
|
-
// Use schema-based config step generation for required Anthropic settings
|
|
22
|
-
return createConfigStepsFromSchema(['anthropic.key', 'anthropic.model']);
|
|
23
|
-
}
|
|
24
4
|
/**
|
|
25
|
-
*
|
|
5
|
+
* Shared component creation utility
|
|
26
6
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
value = value[part];
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return value;
|
|
41
|
-
}
|
|
7
|
+
const createComponent = (name, props, state, status = ComponentStatus.Awaiting) => ({
|
|
8
|
+
id: randomUUID(),
|
|
9
|
+
name,
|
|
10
|
+
props,
|
|
11
|
+
...(state !== undefined ? { state } : {}),
|
|
12
|
+
status,
|
|
13
|
+
});
|
|
42
14
|
/**
|
|
43
|
-
*
|
|
15
|
+
* Create a simple component without state
|
|
44
16
|
*/
|
|
45
|
-
|
|
46
|
-
switch (definition.type) {
|
|
47
|
-
case ConfigDefinitionType.RegExp:
|
|
48
|
-
return (value) => definition.pattern.test(value);
|
|
49
|
-
case ConfigDefinitionType.String:
|
|
50
|
-
return () => true; // Strings are always valid
|
|
51
|
-
case ConfigDefinitionType.Enum:
|
|
52
|
-
return (value) => definition.values.includes(value);
|
|
53
|
-
case ConfigDefinitionType.Number:
|
|
54
|
-
return (value) => !isNaN(Number(value));
|
|
55
|
-
case ConfigDefinitionType.Boolean:
|
|
56
|
-
return (value) => value === 'true' || value === 'false';
|
|
57
|
-
}
|
|
58
|
-
}
|
|
17
|
+
const createSimpleComponent = (name, props, status) => createComponent(name, props, undefined, status);
|
|
59
18
|
/**
|
|
60
|
-
* Create
|
|
19
|
+
* Create a managed component with state
|
|
61
20
|
*/
|
|
62
|
-
|
|
63
|
-
const schema = getConfigSchema();
|
|
64
|
-
let currentConfig = null;
|
|
65
|
-
let rawConfig = null;
|
|
66
|
-
// Load validated config (may fail if config has validation errors)
|
|
67
|
-
try {
|
|
68
|
-
currentConfig = loadConfig(fs);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
// Config doesn't exist or has validation errors, use defaults
|
|
72
|
-
}
|
|
73
|
-
// Load raw config separately (for discovered keys not in schema)
|
|
74
|
-
try {
|
|
75
|
-
const configFile = getConfigPath();
|
|
76
|
-
if (fs.exists(configFile)) {
|
|
77
|
-
const content = fs.readFile(configFile, 'utf-8');
|
|
78
|
-
rawConfig = parseYaml(content);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
// Config file doesn't exist or can't be parsed
|
|
83
|
-
}
|
|
84
|
-
return keys.map((key) => {
|
|
85
|
-
// Check if key is in schema (system config)
|
|
86
|
-
if (!(key in schema)) {
|
|
87
|
-
// Key is not in schema - it's from a skill or discovered config
|
|
88
|
-
// Create a simple text step with cached label or full path as description
|
|
89
|
-
const keyParts = key.split('.');
|
|
90
|
-
const shortKey = keyParts[keyParts.length - 1];
|
|
91
|
-
// Load current value if it exists (use rawConfig since discovered keys aren't in validated config)
|
|
92
|
-
const currentValue = getConfigValue(rawConfig, key);
|
|
93
|
-
const value = currentValue !== undefined && typeof currentValue === 'string'
|
|
94
|
-
? currentValue
|
|
95
|
-
: null;
|
|
96
|
-
// Use cached label if available, fallback to key path
|
|
97
|
-
const cachedLabel = getConfigLabel(key, fs);
|
|
98
|
-
return {
|
|
99
|
-
description: cachedLabel ?? key,
|
|
100
|
-
key: shortKey,
|
|
101
|
-
path: key,
|
|
102
|
-
type: StepType.Text,
|
|
103
|
-
value,
|
|
104
|
-
validate: () => true, // Accept any string for now
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
const definition = schema[key];
|
|
108
|
-
const currentValue = getConfigValue(currentConfig, key);
|
|
109
|
-
const keyParts = key.split('.');
|
|
110
|
-
const shortKey = keyParts[keyParts.length - 1];
|
|
111
|
-
// Map definition to ConfigStep based on type
|
|
112
|
-
switch (definition.type) {
|
|
113
|
-
case ConfigDefinitionType.RegExp:
|
|
114
|
-
case ConfigDefinitionType.String: {
|
|
115
|
-
const value = currentValue !== undefined && typeof currentValue === 'string'
|
|
116
|
-
? currentValue
|
|
117
|
-
: definition.type === ConfigDefinitionType.String
|
|
118
|
-
? (definition.default ?? '')
|
|
119
|
-
: null;
|
|
120
|
-
return {
|
|
121
|
-
description: definition.description,
|
|
122
|
-
key: shortKey,
|
|
123
|
-
path: key,
|
|
124
|
-
type: StepType.Text,
|
|
125
|
-
value,
|
|
126
|
-
validate: getValidator(definition),
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
case ConfigDefinitionType.Number: {
|
|
130
|
-
const value = currentValue !== undefined && typeof currentValue === 'number'
|
|
131
|
-
? String(currentValue)
|
|
132
|
-
: definition.default !== undefined
|
|
133
|
-
? String(definition.default)
|
|
134
|
-
: '0';
|
|
135
|
-
return {
|
|
136
|
-
description: definition.description,
|
|
137
|
-
key: shortKey,
|
|
138
|
-
path: key,
|
|
139
|
-
type: StepType.Text,
|
|
140
|
-
value,
|
|
141
|
-
validate: getValidator(definition),
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
case ConfigDefinitionType.Enum: {
|
|
145
|
-
const currentStr = currentValue !== undefined && typeof currentValue === 'string'
|
|
146
|
-
? currentValue
|
|
147
|
-
: definition.default;
|
|
148
|
-
const defaultIndex = currentStr
|
|
149
|
-
? definition.values.indexOf(currentStr)
|
|
150
|
-
: 0;
|
|
151
|
-
return {
|
|
152
|
-
description: definition.description,
|
|
153
|
-
key: shortKey,
|
|
154
|
-
path: key,
|
|
155
|
-
type: StepType.Selection,
|
|
156
|
-
options: definition.values.map((value) => ({
|
|
157
|
-
label: value,
|
|
158
|
-
value,
|
|
159
|
-
})),
|
|
160
|
-
defaultIndex: Math.max(0, defaultIndex),
|
|
161
|
-
validate: getValidator(definition),
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
case ConfigDefinitionType.Boolean: {
|
|
165
|
-
const currentBool = currentValue !== undefined && typeof currentValue === 'boolean'
|
|
166
|
-
? currentValue
|
|
167
|
-
: undefined;
|
|
168
|
-
return {
|
|
169
|
-
description: definition.description,
|
|
170
|
-
key: shortKey,
|
|
171
|
-
path: key,
|
|
172
|
-
type: StepType.Selection,
|
|
173
|
-
options: [
|
|
174
|
-
{ label: 'yes', value: 'true' },
|
|
175
|
-
{ label: 'no', value: 'false' },
|
|
176
|
-
],
|
|
177
|
-
defaultIndex: currentBool !== undefined ? (currentBool ? 0 : 1) : 0,
|
|
178
|
-
validate: getValidator(definition),
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
export function createConfigDefinition(onFinished, onAborted) {
|
|
185
|
-
return {
|
|
186
|
-
id: randomUUID(),
|
|
187
|
-
name: ComponentName.Config,
|
|
188
|
-
status: ComponentStatus.Awaiting,
|
|
189
|
-
state: {
|
|
190
|
-
values: {},
|
|
191
|
-
completedStep: 0,
|
|
192
|
-
selectedIndex: 0,
|
|
193
|
-
},
|
|
194
|
-
props: {
|
|
195
|
-
steps: createConfigSteps(),
|
|
196
|
-
onFinished,
|
|
197
|
-
onAborted,
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
}
|
|
21
|
+
const createManagedComponent = (name, props, state, status) => createComponent(name, props, state, status);
|
|
201
22
|
/**
|
|
202
|
-
*
|
|
23
|
+
* Initial state constants for managed components
|
|
203
24
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
},
|
|
247
|
-
props: {
|
|
248
|
-
message,
|
|
249
|
-
tasks,
|
|
250
|
-
onSelectionConfirmed,
|
|
251
|
-
},
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
export function createFeedback(type, ...messages) {
|
|
255
|
-
return {
|
|
256
|
-
id: randomUUID(),
|
|
257
|
-
name: ComponentName.Feedback,
|
|
258
|
-
props: {
|
|
259
|
-
type,
|
|
260
|
-
message: messages.join('\n\n'),
|
|
261
|
-
},
|
|
262
|
-
status: ComponentStatus.Awaiting,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
export function createMessage(text) {
|
|
266
|
-
return {
|
|
267
|
-
id: randomUUID(),
|
|
268
|
-
name: ComponentName.Message,
|
|
269
|
-
props: {
|
|
270
|
-
text,
|
|
271
|
-
},
|
|
272
|
-
status: ComponentStatus.Awaiting,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
export function createDebugDefinition(title, content, color) {
|
|
276
|
-
return {
|
|
277
|
-
id: randomUUID(),
|
|
278
|
-
name: ComponentName.Debug,
|
|
279
|
-
props: {
|
|
280
|
-
title,
|
|
281
|
-
content,
|
|
282
|
-
color,
|
|
283
|
-
},
|
|
284
|
-
status: ComponentStatus.Awaiting,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
export function createRefinement(text, onAborted) {
|
|
288
|
-
return {
|
|
289
|
-
id: randomUUID(),
|
|
290
|
-
name: ComponentName.Refinement,
|
|
291
|
-
status: ComponentStatus.Awaiting,
|
|
292
|
-
state: {},
|
|
293
|
-
props: {
|
|
294
|
-
text,
|
|
295
|
-
onAborted,
|
|
296
|
-
},
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
export function createConfirmDefinition(onConfirmed, onCancelled) {
|
|
300
|
-
return {
|
|
301
|
-
id: randomUUID(),
|
|
302
|
-
name: ComponentName.Confirm,
|
|
303
|
-
status: ComponentStatus.Awaiting,
|
|
304
|
-
state: {
|
|
305
|
-
confirmed: false,
|
|
306
|
-
selectedIndex: 0,
|
|
307
|
-
},
|
|
308
|
-
props: {
|
|
309
|
-
message: getConfirmationMessage(),
|
|
310
|
-
onConfirmed,
|
|
311
|
-
onCancelled,
|
|
312
|
-
},
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
export function createIntrospectDefinition(tasks, service) {
|
|
316
|
-
return {
|
|
317
|
-
id: randomUUID(),
|
|
318
|
-
name: ComponentName.Introspect,
|
|
319
|
-
status: ComponentStatus.Awaiting,
|
|
320
|
-
state: {
|
|
321
|
-
error: null,
|
|
322
|
-
capabilities: [],
|
|
323
|
-
message: null,
|
|
324
|
-
},
|
|
325
|
-
props: {
|
|
326
|
-
tasks,
|
|
327
|
-
service,
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
export function createReportDefinition(message, capabilities) {
|
|
332
|
-
return {
|
|
333
|
-
id: randomUUID(),
|
|
334
|
-
name: ComponentName.Report,
|
|
335
|
-
props: {
|
|
336
|
-
message,
|
|
337
|
-
capabilities,
|
|
338
|
-
},
|
|
339
|
-
status: ComponentStatus.Awaiting,
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
export function createAnswerDefinition(question, service) {
|
|
343
|
-
return {
|
|
344
|
-
id: randomUUID(),
|
|
345
|
-
name: ComponentName.Answer,
|
|
346
|
-
status: ComponentStatus.Awaiting,
|
|
347
|
-
state: {
|
|
348
|
-
error: null,
|
|
349
|
-
answer: null,
|
|
350
|
-
},
|
|
351
|
-
props: {
|
|
352
|
-
question,
|
|
353
|
-
service,
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
export function isSimple(component) {
|
|
358
|
-
return !('state' in component);
|
|
359
|
-
}
|
|
25
|
+
const InitialConfigState = {
|
|
26
|
+
values: {},
|
|
27
|
+
completedStep: 0,
|
|
28
|
+
selectedIndex: 0,
|
|
29
|
+
};
|
|
30
|
+
const InitialCommandState = {
|
|
31
|
+
error: null,
|
|
32
|
+
message: null,
|
|
33
|
+
tasks: [],
|
|
34
|
+
};
|
|
35
|
+
const InitialScheduleState = {
|
|
36
|
+
highlightedIndex: null,
|
|
37
|
+
currentDefineGroupIndex: 0,
|
|
38
|
+
completedSelections: [],
|
|
39
|
+
};
|
|
40
|
+
const InitialRefinementState = {};
|
|
41
|
+
const InitialConfirmState = {
|
|
42
|
+
confirmed: false,
|
|
43
|
+
selectedIndex: 0,
|
|
44
|
+
};
|
|
45
|
+
const InitialIntrospectState = {
|
|
46
|
+
error: null,
|
|
47
|
+
capabilities: [],
|
|
48
|
+
message: null,
|
|
49
|
+
};
|
|
50
|
+
const InitialAnswerState = {
|
|
51
|
+
error: null,
|
|
52
|
+
answer: null,
|
|
53
|
+
};
|
|
54
|
+
const InitialExecuteState = {
|
|
55
|
+
error: null,
|
|
56
|
+
message: '',
|
|
57
|
+
summary: '',
|
|
58
|
+
tasks: [],
|
|
59
|
+
completionMessage: null,
|
|
60
|
+
};
|
|
61
|
+
const InitialValidateState = {
|
|
62
|
+
error: null,
|
|
63
|
+
completionMessage: null,
|
|
64
|
+
configRequirements: [],
|
|
65
|
+
validated: false,
|
|
66
|
+
};
|
|
360
67
|
/**
|
|
361
|
-
*
|
|
362
|
-
* Components use handlers.updateState to save their state before completion,
|
|
363
|
-
* so this function sets the status to Done and returns the updated component.
|
|
68
|
+
* Create a welcome component that displays application information
|
|
364
69
|
*/
|
|
365
|
-
export
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
70
|
+
export const createWelcome = (props, status) => createSimpleComponent(ComponentName.Welcome, props, status);
|
|
71
|
+
/**
|
|
72
|
+
* Create a feedback component that displays status messages
|
|
73
|
+
*/
|
|
74
|
+
export const createFeedback = (props, status) => createSimpleComponent(ComponentName.Feedback, props, status);
|
|
75
|
+
/**
|
|
76
|
+
* Create a message component that displays informational text
|
|
77
|
+
*/
|
|
78
|
+
export const createMessage = (props, status) => createSimpleComponent(ComponentName.Message, props, status);
|
|
79
|
+
/**
|
|
80
|
+
* Create a debug component that displays diagnostic information
|
|
81
|
+
*/
|
|
82
|
+
export const createDebug = (props, status) => createSimpleComponent(ComponentName.Debug, props, status);
|
|
83
|
+
/**
|
|
84
|
+
* Create a report component that displays capability listings
|
|
85
|
+
*/
|
|
86
|
+
export const createReport = (props, status) => createSimpleComponent(ComponentName.Report, props, status);
|
|
87
|
+
/**
|
|
88
|
+
* Create a configuration component for multi-step user input
|
|
89
|
+
*/
|
|
90
|
+
export const createConfig = (props, status) => createManagedComponent(ComponentName.Config, props, InitialConfigState, status);
|
|
91
|
+
/**
|
|
92
|
+
* Create a command component that processes user requests via LLM
|
|
93
|
+
*/
|
|
94
|
+
export const createCommand = (props, status) => createManagedComponent(ComponentName.Command, props, InitialCommandState, status);
|
|
95
|
+
/**
|
|
96
|
+
* Create a schedule component that displays and manages task execution plans
|
|
97
|
+
*/
|
|
98
|
+
export const createSchedule = (props, status) => createManagedComponent(ComponentName.Schedule, props, InitialScheduleState, status);
|
|
99
|
+
/**
|
|
100
|
+
* Create a refinement component for interactive task selection
|
|
101
|
+
*/
|
|
102
|
+
export const createRefinement = (props, status) => createManagedComponent(ComponentName.Refinement, props, InitialRefinementState, status);
|
|
103
|
+
/**
|
|
104
|
+
* Create a confirmation component that prompts user for yes/no decisions
|
|
105
|
+
*/
|
|
106
|
+
export const createConfirm = (props, status) => createManagedComponent(ComponentName.Confirm, props, InitialConfirmState, status);
|
|
107
|
+
/**
|
|
108
|
+
* Create an introspect component that lists available capabilities
|
|
109
|
+
*/
|
|
110
|
+
export const createIntrospect = (props, status) => createManagedComponent(ComponentName.Introspect, props, InitialIntrospectState, status);
|
|
111
|
+
/**
|
|
112
|
+
* Create an answer component that responds to information requests via LLM
|
|
113
|
+
*/
|
|
114
|
+
export const createAnswer = (props, status) => createManagedComponent(ComponentName.Answer, props, InitialAnswerState, status);
|
|
115
|
+
/**
|
|
116
|
+
* Create an execute component that runs shell commands and processes operations
|
|
117
|
+
*/
|
|
118
|
+
export const createExecute = (props, status) => createManagedComponent(ComponentName.Execute, props, InitialExecuteState, status);
|
|
119
|
+
/**
|
|
120
|
+
* Create a validate component that checks and collects missing configuration
|
|
121
|
+
*/
|
|
122
|
+
export const createValidate = (props, status) => createManagedComponent(ComponentName.Validate, props, InitialValidateState, status);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from 'fs';
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'fs';
|
|
2
2
|
import { dirname } from 'path';
|
|
3
3
|
/**
|
|
4
4
|
* Real filesystem implementation using Node's fs module
|
|
@@ -19,6 +19,12 @@ export class RealFileSystem {
|
|
|
19
19
|
createDirectory(path, options) {
|
|
20
20
|
mkdirSync(path, options);
|
|
21
21
|
}
|
|
22
|
+
rename(oldPath, newPath) {
|
|
23
|
+
renameSync(oldPath, newPath);
|
|
24
|
+
}
|
|
25
|
+
remove(path) {
|
|
26
|
+
unlinkSync(path);
|
|
27
|
+
}
|
|
22
28
|
}
|
|
23
29
|
/**
|
|
24
30
|
* In-memory filesystem implementation for testing
|
|
@@ -93,6 +99,20 @@ export class MemoryFileSystem {
|
|
|
93
99
|
this.directories.add(path);
|
|
94
100
|
}
|
|
95
101
|
}
|
|
102
|
+
rename(oldPath, newPath) {
|
|
103
|
+
const content = this.files.get(oldPath);
|
|
104
|
+
if (content === undefined) {
|
|
105
|
+
throw new Error(`ENOENT: no such file or directory, rename '${oldPath}'`);
|
|
106
|
+
}
|
|
107
|
+
this.files.delete(oldPath);
|
|
108
|
+
this.files.set(newPath, content);
|
|
109
|
+
}
|
|
110
|
+
remove(path) {
|
|
111
|
+
if (!this.files.has(path)) {
|
|
112
|
+
throw new Error(`ENOENT: no such file or directory, unlink '${path}'`);
|
|
113
|
+
}
|
|
114
|
+
this.files.delete(path);
|
|
115
|
+
}
|
|
96
116
|
/**
|
|
97
117
|
* Clear all files and directories (useful for test cleanup)
|
|
98
118
|
*/
|
package/dist/services/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DebugLevel } from '../configuration/types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createDebug } from './components.js';
|
|
3
3
|
import { loadDebugSetting } from '../configuration/io.js';
|
|
4
4
|
import { Palette } from './colors.js';
|
|
5
5
|
/**
|
|
@@ -68,7 +68,7 @@ export function logPrompt(toolName, command, instructions) {
|
|
|
68
68
|
const lines = instructions.split('\n').length;
|
|
69
69
|
const bytes = Buffer.byteLength(instructions, 'utf-8');
|
|
70
70
|
const title = `SYSTEM PROMPT (${String(lines)} lines, ${String(bytes)} bytes)`;
|
|
71
|
-
return
|
|
71
|
+
return createDebug({ title, content, color: Palette.Gray });
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Create debug component for LLM responses received
|
|
@@ -85,5 +85,5 @@ export function logResponse(toolName, response, durationMs) {
|
|
|
85
85
|
JSON.stringify(response, null, 2),
|
|
86
86
|
].join('\n');
|
|
87
87
|
const title = `LLM RESPONSE (${String(durationMs)} ms)`;
|
|
88
|
-
return
|
|
88
|
+
return createDebug({ title, content, color: Palette.AshGray });
|
|
89
89
|
}
|
|
@@ -149,22 +149,16 @@ export function formatErrorMessage(error) {
|
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
151
151
|
* Returns an execution error message with varied phrasing.
|
|
152
|
-
*
|
|
153
|
-
*
|
|
152
|
+
* Error details are shown in the task output, so this is just a summary.
|
|
153
|
+
* Randomly selects from variations to sound natural.
|
|
154
154
|
*/
|
|
155
|
-
export function getExecutionErrorMessage(
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
'
|
|
155
|
+
export function getExecutionErrorMessage(_error) {
|
|
156
|
+
const messages = [
|
|
157
|
+
'The execution failed.',
|
|
158
|
+
'Execution has failed.',
|
|
159
|
+
'The execution was not successful.',
|
|
160
|
+
'Execution did not succeed.',
|
|
161
|
+
'The execution encountered an error.',
|
|
162
162
|
];
|
|
163
|
-
|
|
164
|
-
// Capitalize first letter of error
|
|
165
|
-
const capitalizedError = error.charAt(0).toUpperCase() + error.slice(1);
|
|
166
|
-
const errorWithPeriod = capitalizedError.endsWith('.')
|
|
167
|
-
? capitalizedError
|
|
168
|
-
: `${capitalizedError}.`;
|
|
169
|
-
return `${prefix}. ${errorWithPeriod}`;
|
|
163
|
+
return messages[Math.floor(Math.random() * messages.length)];
|
|
170
164
|
}
|
package/dist/services/process.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
export const defaultProcessControl = {
|
|
2
|
+
exit: (code) => process.exit(code),
|
|
3
|
+
};
|
|
1
4
|
/**
|
|
2
5
|
* Exit application after brief delay to allow UI to render
|
|
3
6
|
*/
|
|
4
|
-
export function exitApp(code) {
|
|
5
|
-
setTimeout(() =>
|
|
7
|
+
export function exitApp(code, processControl = defaultProcessControl) {
|
|
8
|
+
setTimeout(() => {
|
|
9
|
+
processControl.exit(code);
|
|
10
|
+
}, 100);
|
|
6
11
|
}
|
|
@@ -8,8 +8,11 @@ import { routeTasksWithConfirm } from './router.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export async function handleRefinement(selectedTasks, service, originalCommand, lifecycleHandlers, workflowHandlers, requestHandlers) {
|
|
10
10
|
// Create and add refinement component to queue
|
|
11
|
-
const refinementDef = createRefinement(
|
|
12
|
-
|
|
11
|
+
const refinementDef = createRefinement({
|
|
12
|
+
text: getRefiningMessage(),
|
|
13
|
+
onAborted: (operation) => {
|
|
14
|
+
requestHandlers.onAborted(operation);
|
|
15
|
+
},
|
|
13
16
|
});
|
|
14
17
|
workflowHandlers.addToQueue(refinementDef);
|
|
15
18
|
try {
|