prompt-language-shell 0.8.4 → 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 +1 -1
- package/dist/services/colors.js +1 -1
- package/dist/services/components.js +35 -11
- package/dist/services/config-labels.js +15 -15
- package/dist/services/logger.js +2 -1
- package/dist/services/messages.js +32 -1
- package/dist/services/refinement.js +6 -6
- package/dist/services/router.js +43 -27
- package/dist/ui/Answer.js +36 -15
- package/dist/ui/Command.js +43 -23
- package/dist/ui/Component.js +147 -33
- package/dist/ui/Config.js +68 -78
- package/dist/ui/Confirm.js +34 -21
- package/dist/ui/Execute.js +107 -328
- package/dist/ui/Introspect.js +51 -24
- package/dist/ui/Label.js +1 -1
- package/dist/ui/Main.js +5 -1
- package/dist/ui/Refinement.js +8 -1
- package/dist/ui/Schedule.js +75 -52
- package/dist/ui/Validate.js +75 -77
- package/dist/ui/Workflow.js +50 -123
- package/package.json +1 -1
- package/dist/services/configuration.js +0 -409
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { ExecutionStatus } from '../services/shell.js';
|
|
2
|
+
import { formatDuration } from '../services/utils.js';
|
|
3
|
+
import { ExecuteActionType, } from './types.js';
|
|
4
|
+
export const initialState = {
|
|
5
|
+
error: null,
|
|
6
|
+
taskInfos: [],
|
|
7
|
+
message: '',
|
|
8
|
+
completed: 0,
|
|
9
|
+
hasProcessed: false,
|
|
10
|
+
taskExecutionTimes: [],
|
|
11
|
+
completionMessage: null,
|
|
12
|
+
summary: '',
|
|
13
|
+
};
|
|
14
|
+
export function executeReducer(state, action) {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case ExecuteActionType.ProcessingComplete:
|
|
17
|
+
return {
|
|
18
|
+
...state,
|
|
19
|
+
message: action.payload.message,
|
|
20
|
+
hasProcessed: true,
|
|
21
|
+
};
|
|
22
|
+
case ExecuteActionType.CommandsReady:
|
|
23
|
+
return {
|
|
24
|
+
...state,
|
|
25
|
+
message: action.payload.message,
|
|
26
|
+
summary: action.payload.summary,
|
|
27
|
+
taskInfos: action.payload.taskInfos,
|
|
28
|
+
completed: 0,
|
|
29
|
+
};
|
|
30
|
+
case ExecuteActionType.ProcessingError:
|
|
31
|
+
return {
|
|
32
|
+
...state,
|
|
33
|
+
error: action.payload.error,
|
|
34
|
+
hasProcessed: true,
|
|
35
|
+
};
|
|
36
|
+
case ExecuteActionType.TaskComplete: {
|
|
37
|
+
const updatedTimes = [
|
|
38
|
+
...state.taskExecutionTimes,
|
|
39
|
+
action.payload.elapsed,
|
|
40
|
+
];
|
|
41
|
+
const updatedTaskInfos = state.taskInfos.map((task, i) => i === action.payload.index
|
|
42
|
+
? {
|
|
43
|
+
...task,
|
|
44
|
+
status: ExecutionStatus.Success,
|
|
45
|
+
elapsed: action.payload.elapsed,
|
|
46
|
+
}
|
|
47
|
+
: task);
|
|
48
|
+
return {
|
|
49
|
+
...state,
|
|
50
|
+
taskInfos: updatedTaskInfos,
|
|
51
|
+
taskExecutionTimes: updatedTimes,
|
|
52
|
+
completed: action.payload.index + 1,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
case ExecuteActionType.AllTasksComplete: {
|
|
56
|
+
const updatedTimes = [
|
|
57
|
+
...state.taskExecutionTimes,
|
|
58
|
+
action.payload.elapsed,
|
|
59
|
+
];
|
|
60
|
+
const updatedTaskInfos = state.taskInfos.map((task, i) => i === action.payload.index
|
|
61
|
+
? {
|
|
62
|
+
...task,
|
|
63
|
+
status: ExecutionStatus.Success,
|
|
64
|
+
elapsed: action.payload.elapsed,
|
|
65
|
+
}
|
|
66
|
+
: task);
|
|
67
|
+
const totalElapsed = updatedTimes.reduce((sum, time) => sum + time, 0);
|
|
68
|
+
const completion = `${action.payload.summaryText} in ${formatDuration(totalElapsed)}.`;
|
|
69
|
+
return {
|
|
70
|
+
...state,
|
|
71
|
+
taskInfos: updatedTaskInfos,
|
|
72
|
+
taskExecutionTimes: updatedTimes,
|
|
73
|
+
completed: action.payload.index + 1,
|
|
74
|
+
completionMessage: completion,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
case ExecuteActionType.TaskErrorCritical: {
|
|
78
|
+
const updatedTaskInfos = state.taskInfos.map((task, i) => i === action.payload.index
|
|
79
|
+
? { ...task, status: ExecutionStatus.Failed, elapsed: 0 }
|
|
80
|
+
: task);
|
|
81
|
+
return {
|
|
82
|
+
...state,
|
|
83
|
+
taskInfos: updatedTaskInfos,
|
|
84
|
+
error: action.payload.error,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
case ExecuteActionType.TaskErrorContinue: {
|
|
88
|
+
const updatedTimes = [
|
|
89
|
+
...state.taskExecutionTimes,
|
|
90
|
+
action.payload.elapsed,
|
|
91
|
+
];
|
|
92
|
+
const updatedTaskInfos = state.taskInfos.map((task, i) => i === action.payload.index
|
|
93
|
+
? {
|
|
94
|
+
...task,
|
|
95
|
+
status: ExecutionStatus.Failed,
|
|
96
|
+
elapsed: action.payload.elapsed,
|
|
97
|
+
}
|
|
98
|
+
: task);
|
|
99
|
+
return {
|
|
100
|
+
...state,
|
|
101
|
+
taskInfos: updatedTaskInfos,
|
|
102
|
+
taskExecutionTimes: updatedTimes,
|
|
103
|
+
completed: action.payload.index + 1,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
case ExecuteActionType.LastTaskError: {
|
|
107
|
+
const updatedTimes = [
|
|
108
|
+
...state.taskExecutionTimes,
|
|
109
|
+
action.payload.elapsed,
|
|
110
|
+
];
|
|
111
|
+
const updatedTaskInfos = state.taskInfos.map((task, i) => i === action.payload.index
|
|
112
|
+
? {
|
|
113
|
+
...task,
|
|
114
|
+
status: ExecutionStatus.Failed,
|
|
115
|
+
elapsed: action.payload.elapsed,
|
|
116
|
+
}
|
|
117
|
+
: task);
|
|
118
|
+
const totalElapsed = updatedTimes.reduce((sum, time) => sum + time, 0);
|
|
119
|
+
const completion = `${action.payload.summaryText} in ${formatDuration(totalElapsed)}.`;
|
|
120
|
+
return {
|
|
121
|
+
...state,
|
|
122
|
+
taskInfos: updatedTaskInfos,
|
|
123
|
+
taskExecutionTimes: updatedTimes,
|
|
124
|
+
completed: action.payload.index + 1,
|
|
125
|
+
completionMessage: completion,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
case ExecuteActionType.CancelExecution: {
|
|
129
|
+
const updatedTaskInfos = state.taskInfos.map((task, taskIndex) => {
|
|
130
|
+
if (taskIndex < action.payload.completed) {
|
|
131
|
+
return { ...task, status: ExecutionStatus.Success };
|
|
132
|
+
}
|
|
133
|
+
else if (taskIndex === action.payload.completed) {
|
|
134
|
+
return { ...task, status: ExecutionStatus.Aborted };
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
return { ...task, status: ExecutionStatus.Cancelled };
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
...state,
|
|
142
|
+
taskInfos: updatedTaskInfos,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
default:
|
|
146
|
+
return state;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export var ExecuteActionType;
|
|
2
|
+
(function (ExecuteActionType) {
|
|
3
|
+
ExecuteActionType["ProcessingComplete"] = "PROCESSING_COMPLETE";
|
|
4
|
+
ExecuteActionType["CommandsReady"] = "COMMANDS_READY";
|
|
5
|
+
ExecuteActionType["ProcessingError"] = "PROCESSING_ERROR";
|
|
6
|
+
ExecuteActionType["TaskComplete"] = "TASK_COMPLETE";
|
|
7
|
+
ExecuteActionType["AllTasksComplete"] = "ALL_TASKS_COMPLETE";
|
|
8
|
+
ExecuteActionType["TaskErrorCritical"] = "TASK_ERROR_CRITICAL";
|
|
9
|
+
ExecuteActionType["TaskErrorContinue"] = "TASK_ERROR_CONTINUE";
|
|
10
|
+
ExecuteActionType["LastTaskError"] = "LAST_TASK_ERROR";
|
|
11
|
+
ExecuteActionType["CancelExecution"] = "CANCEL_EXECUTION";
|
|
12
|
+
})(ExecuteActionType || (ExecuteActionType = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getUnresolvedPlaceholdersMessage } from '../services/messages.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that all placeholders in a command have been resolved.
|
|
4
|
+
* Throws an error if unresolved placeholders are found.
|
|
5
|
+
*/
|
|
6
|
+
export function validatePlaceholderResolution(command) {
|
|
7
|
+
const unresolvedPattern = /\{[^}]+\}/g;
|
|
8
|
+
const matches = command.match(unresolvedPattern);
|
|
9
|
+
if (matches && matches.length > 0) {
|
|
10
|
+
throw new Error(getUnresolvedPlaceholdersMessage(matches.length));
|
|
11
|
+
}
|
|
12
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { existsSync, readFileSync } from 'fs';
|
|
|
4
4
|
import { dirname, join } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { render } from 'ink';
|
|
7
|
-
import { DebugLevel } from './
|
|
7
|
+
import { DebugLevel } from './configuration/types.js';
|
|
8
8
|
import { Main } from './ui/Main.js';
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = dirname(__filename);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { getAvailableConfigStructure, getConfiguredKeys, } from '
|
|
2
|
+
import { getAvailableConfigStructure, getConfiguredKeys, } from '../configuration/schema.js';
|
|
3
3
|
import { logPrompt, logResponse } from './logger.js';
|
|
4
4
|
import { formatSkillsForPrompt, loadSkillsWithValidation } from './skills.js';
|
|
5
5
|
import { toolRegistry } from './registry.js';
|
package/dist/services/colors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { DebugLevel } from '../configuration/types.js';
|
|
1
2
|
import { FeedbackType, Origin, TaskType } from '../types/types.js';
|
|
2
|
-
import { DebugLevel } from './configuration.js';
|
|
3
3
|
import { ExecutionStatus } from './shell.js';
|
|
4
4
|
/**
|
|
5
5
|
* Base color palette - raw color values with descriptive names.
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { parse as parseYaml } from 'yaml';
|
|
3
|
+
import { ConfigDefinitionType, } from '../configuration/types.js';
|
|
3
4
|
import { ComponentStatus, } from '../types/components.js';
|
|
4
5
|
import { ComponentName } from '../types/types.js';
|
|
5
|
-
import {
|
|
6
|
+
import { getConfigPath, loadConfig } from '../configuration/io.js';
|
|
7
|
+
import { getConfigSchema } from '../configuration/schema.js';
|
|
8
|
+
import { getConfigLabel } from './config-labels.js';
|
|
6
9
|
import { defaultFileSystem } from './filesystem.js';
|
|
7
10
|
import { getConfirmationMessage } from './messages.js';
|
|
8
11
|
import { StepType } from '../ui/Config.js';
|
|
@@ -11,6 +14,7 @@ export function createWelcomeDefinition(app) {
|
|
|
11
14
|
id: randomUUID(),
|
|
12
15
|
name: ComponentName.Welcome,
|
|
13
16
|
props: { app },
|
|
17
|
+
status: ComponentStatus.Awaiting,
|
|
14
18
|
};
|
|
15
19
|
}
|
|
16
20
|
export function createConfigSteps() {
|
|
@@ -81,7 +85,7 @@ export function createConfigStepsFromSchema(keys, fs = defaultFileSystem) {
|
|
|
81
85
|
// Check if key is in schema (system config)
|
|
82
86
|
if (!(key in schema)) {
|
|
83
87
|
// Key is not in schema - it's from a skill or discovered config
|
|
84
|
-
// Create a simple text step with
|
|
88
|
+
// Create a simple text step with cached label or full path as description
|
|
85
89
|
const keyParts = key.split('.');
|
|
86
90
|
const shortKey = keyParts[keyParts.length - 1];
|
|
87
91
|
// Load current value if it exists (use rawConfig since discovered keys aren't in validated config)
|
|
@@ -89,8 +93,10 @@ export function createConfigStepsFromSchema(keys, fs = defaultFileSystem) {
|
|
|
89
93
|
const value = currentValue !== undefined && typeof currentValue === 'string'
|
|
90
94
|
? currentValue
|
|
91
95
|
: null;
|
|
96
|
+
// Use cached label if available, fallback to key path
|
|
97
|
+
const cachedLabel = getConfigLabel(key, fs);
|
|
92
98
|
return {
|
|
93
|
-
description: key,
|
|
99
|
+
description: cachedLabel ?? key,
|
|
94
100
|
key: shortKey,
|
|
95
101
|
path: key,
|
|
96
102
|
type: StepType.Text,
|
|
@@ -217,7 +223,11 @@ export function createCommandDefinition(command, service) {
|
|
|
217
223
|
id: randomUUID(),
|
|
218
224
|
name: ComponentName.Command,
|
|
219
225
|
status: ComponentStatus.Awaiting,
|
|
220
|
-
state: {
|
|
226
|
+
state: {
|
|
227
|
+
error: null,
|
|
228
|
+
message: null,
|
|
229
|
+
tasks: [],
|
|
230
|
+
},
|
|
221
231
|
props: {
|
|
222
232
|
command,
|
|
223
233
|
service,
|
|
@@ -249,6 +259,7 @@ export function createFeedback(type, ...messages) {
|
|
|
249
259
|
type,
|
|
250
260
|
message: messages.join('\n\n'),
|
|
251
261
|
},
|
|
262
|
+
status: ComponentStatus.Awaiting,
|
|
252
263
|
};
|
|
253
264
|
}
|
|
254
265
|
export function createMessage(text) {
|
|
@@ -258,6 +269,7 @@ export function createMessage(text) {
|
|
|
258
269
|
props: {
|
|
259
270
|
text,
|
|
260
271
|
},
|
|
272
|
+
status: ComponentStatus.Awaiting,
|
|
261
273
|
};
|
|
262
274
|
}
|
|
263
275
|
export function createDebugDefinition(title, content, color) {
|
|
@@ -269,6 +281,7 @@ export function createDebugDefinition(title, content, color) {
|
|
|
269
281
|
content,
|
|
270
282
|
color,
|
|
271
283
|
},
|
|
284
|
+
status: ComponentStatus.Awaiting,
|
|
272
285
|
};
|
|
273
286
|
}
|
|
274
287
|
export function createRefinement(text, onAborted) {
|
|
@@ -288,7 +301,10 @@ export function createConfirmDefinition(onConfirmed, onCancelled) {
|
|
|
288
301
|
id: randomUUID(),
|
|
289
302
|
name: ComponentName.Confirm,
|
|
290
303
|
status: ComponentStatus.Awaiting,
|
|
291
|
-
state: {
|
|
304
|
+
state: {
|
|
305
|
+
confirmed: false,
|
|
306
|
+
selectedIndex: 0,
|
|
307
|
+
},
|
|
292
308
|
props: {
|
|
293
309
|
message: getConfirmationMessage(),
|
|
294
310
|
onConfirmed,
|
|
@@ -301,7 +317,11 @@ export function createIntrospectDefinition(tasks, service) {
|
|
|
301
317
|
id: randomUUID(),
|
|
302
318
|
name: ComponentName.Introspect,
|
|
303
319
|
status: ComponentStatus.Awaiting,
|
|
304
|
-
state: {
|
|
320
|
+
state: {
|
|
321
|
+
error: null,
|
|
322
|
+
capabilities: [],
|
|
323
|
+
message: null,
|
|
324
|
+
},
|
|
305
325
|
props: {
|
|
306
326
|
tasks,
|
|
307
327
|
service,
|
|
@@ -316,6 +336,7 @@ export function createReportDefinition(message, capabilities) {
|
|
|
316
336
|
message,
|
|
317
337
|
capabilities,
|
|
318
338
|
},
|
|
339
|
+
status: ComponentStatus.Awaiting,
|
|
319
340
|
};
|
|
320
341
|
}
|
|
321
342
|
export function createAnswerDefinition(question, service) {
|
|
@@ -323,14 +344,17 @@ export function createAnswerDefinition(question, service) {
|
|
|
323
344
|
id: randomUUID(),
|
|
324
345
|
name: ComponentName.Answer,
|
|
325
346
|
status: ComponentStatus.Awaiting,
|
|
326
|
-
state: {
|
|
347
|
+
state: {
|
|
348
|
+
error: null,
|
|
349
|
+
answer: null,
|
|
350
|
+
},
|
|
327
351
|
props: {
|
|
328
352
|
question,
|
|
329
353
|
service,
|
|
330
354
|
},
|
|
331
355
|
};
|
|
332
356
|
}
|
|
333
|
-
export function
|
|
357
|
+
export function isSimple(component) {
|
|
334
358
|
return !('state' in component);
|
|
335
359
|
}
|
|
336
360
|
/**
|
|
@@ -361,7 +385,7 @@ export function createExecuteDefinition(tasks, service) {
|
|
|
361
385
|
},
|
|
362
386
|
};
|
|
363
387
|
}
|
|
364
|
-
export function createValidateDefinition(missingConfig, userRequest, service, onError,
|
|
388
|
+
export function createValidateDefinition(missingConfig, userRequest, service, onError, onValidationComplete, onAborted) {
|
|
365
389
|
return {
|
|
366
390
|
id: randomUUID(),
|
|
367
391
|
name: ComponentName.Validate,
|
|
@@ -369,7 +393,7 @@ export function createValidateDefinition(missingConfig, userRequest, service, on
|
|
|
369
393
|
state: {
|
|
370
394
|
error: null,
|
|
371
395
|
completionMessage: null,
|
|
372
|
-
configRequirements:
|
|
396
|
+
configRequirements: [],
|
|
373
397
|
validated: false,
|
|
374
398
|
},
|
|
375
399
|
props: {
|
|
@@ -377,7 +401,7 @@ export function createValidateDefinition(missingConfig, userRequest, service, on
|
|
|
377
401
|
userRequest,
|
|
378
402
|
service,
|
|
379
403
|
onError,
|
|
380
|
-
|
|
404
|
+
onValidationComplete,
|
|
381
405
|
onAborted,
|
|
382
406
|
},
|
|
383
407
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
1
|
import { homedir } from 'os';
|
|
3
2
|
import { join } from 'path';
|
|
3
|
+
import { defaultFileSystem } from './filesystem.js';
|
|
4
4
|
/**
|
|
5
5
|
* Get the path to the config labels cache file
|
|
6
6
|
*/
|
|
@@ -16,23 +16,23 @@ function getCacheDirectoryPath() {
|
|
|
16
16
|
/**
|
|
17
17
|
* Ensure the cache directory exists
|
|
18
18
|
*/
|
|
19
|
-
function ensureCacheDirectoryExists() {
|
|
19
|
+
function ensureCacheDirectoryExists(fs = defaultFileSystem) {
|
|
20
20
|
const cacheDir = getCacheDirectoryPath();
|
|
21
|
-
if (!
|
|
22
|
-
|
|
21
|
+
if (!fs.exists(cacheDir)) {
|
|
22
|
+
fs.createDirectory(cacheDir, { recursive: true });
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Load config labels from cache file
|
|
27
27
|
* Returns empty object if file doesn't exist or is corrupted
|
|
28
28
|
*/
|
|
29
|
-
export function loadConfigLabels() {
|
|
29
|
+
export function loadConfigLabels(fs = defaultFileSystem) {
|
|
30
30
|
try {
|
|
31
31
|
const cachePath = getConfigLabelsCachePath();
|
|
32
|
-
if (!
|
|
32
|
+
if (!fs.exists(cachePath)) {
|
|
33
33
|
return {};
|
|
34
34
|
}
|
|
35
|
-
const content =
|
|
35
|
+
const content = fs.readFile(cachePath, 'utf-8');
|
|
36
36
|
const parsed = JSON.parse(content);
|
|
37
37
|
// Validate that parsed content is an object
|
|
38
38
|
if (typeof parsed !== 'object' ||
|
|
@@ -50,26 +50,26 @@ export function loadConfigLabels() {
|
|
|
50
50
|
/**
|
|
51
51
|
* Save multiple config labels to cache
|
|
52
52
|
*/
|
|
53
|
-
export function saveConfigLabels(labels) {
|
|
54
|
-
ensureCacheDirectoryExists();
|
|
53
|
+
export function saveConfigLabels(labels, fs = defaultFileSystem) {
|
|
54
|
+
ensureCacheDirectoryExists(fs);
|
|
55
55
|
// Load existing labels and merge with new ones
|
|
56
|
-
const existing = loadConfigLabels();
|
|
56
|
+
const existing = loadConfigLabels(fs);
|
|
57
57
|
const merged = { ...existing, ...labels };
|
|
58
58
|
const cachePath = getConfigLabelsCachePath();
|
|
59
59
|
const content = JSON.stringify(merged, null, 2);
|
|
60
|
-
|
|
60
|
+
fs.writeFile(cachePath, content);
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
63
|
* Save a single config label to cache
|
|
64
64
|
*/
|
|
65
|
-
export function saveConfigLabel(key, label) {
|
|
66
|
-
saveConfigLabels({ [key]: label });
|
|
65
|
+
export function saveConfigLabel(key, label, fs = defaultFileSystem) {
|
|
66
|
+
saveConfigLabels({ [key]: label }, fs);
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Get a config label from cache
|
|
70
70
|
* Returns undefined if label doesn't exist
|
|
71
71
|
*/
|
|
72
|
-
export function getConfigLabel(key) {
|
|
73
|
-
const labels = loadConfigLabels();
|
|
72
|
+
export function getConfigLabel(key, fs = defaultFileSystem) {
|
|
73
|
+
const labels = loadConfigLabels(fs);
|
|
74
74
|
return labels[key];
|
|
75
75
|
}
|
package/dist/services/logger.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { DebugLevel } from '../configuration/types.js';
|
|
1
2
|
import { createDebugDefinition } from './components.js';
|
|
2
|
-
import {
|
|
3
|
+
import { loadDebugSetting } from '../configuration/io.js';
|
|
3
4
|
import { Palette } from './colors.js';
|
|
4
5
|
/**
|
|
5
6
|
* Debug logger for the application
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DebugLevel
|
|
1
|
+
import { DebugLevel } from '../configuration/types.js';
|
|
2
|
+
import { loadDebugSetting } from '../configuration/io.js';
|
|
2
3
|
export { formatDuration } from './utils.js';
|
|
3
4
|
/**
|
|
4
5
|
* Returns a natural language confirmation message for plan execution.
|
|
@@ -80,6 +81,36 @@ export function getMixedTaskTypesError(types) {
|
|
|
80
81
|
const typeList = types.join(', ');
|
|
81
82
|
return `Mixed task types are not supported. Found: ${typeList}. All tasks in a plan must have the same type.`;
|
|
82
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Returns a message for unresolved placeholders/missing configuration.
|
|
86
|
+
* Each message has two sentences: what's missing + what will be done.
|
|
87
|
+
* Both sentences are randomly selected independently for variety.
|
|
88
|
+
* Supports singular and plural forms.
|
|
89
|
+
*/
|
|
90
|
+
export function getUnresolvedPlaceholdersMessage(count) {
|
|
91
|
+
const plural = count === 1 ? '' : 's';
|
|
92
|
+
const it = count === 1 ? 'it' : 'them';
|
|
93
|
+
const valueWord = count === 1 ? 'value' : 'values';
|
|
94
|
+
// First sentence: what's missing
|
|
95
|
+
const firstSentences = [
|
|
96
|
+
`Missing configuration ${valueWord} detected.`,
|
|
97
|
+
`Configuration ${valueWord} needed.`,
|
|
98
|
+
`Found unresolved placeholder${plural}.`,
|
|
99
|
+
`Additional configuration ${valueWord} required.`,
|
|
100
|
+
`Setup requires configuration ${valueWord}.`,
|
|
101
|
+
];
|
|
102
|
+
// Second sentence: what will be done
|
|
103
|
+
const secondSentences = [
|
|
104
|
+
`Let me gather ${it} now.`,
|
|
105
|
+
`I'll set ${it} up for you.`,
|
|
106
|
+
`Let me configure ${it} first.`,
|
|
107
|
+
`I'll help you provide ${it}.`,
|
|
108
|
+
`Let me collect ${it} from you.`,
|
|
109
|
+
];
|
|
110
|
+
const first = firstSentences[Math.floor(Math.random() * firstSentences.length)];
|
|
111
|
+
const second = secondSentences[Math.floor(Math.random() * secondSentences.length)];
|
|
112
|
+
return `${first} ${second}`;
|
|
113
|
+
}
|
|
83
114
|
/**
|
|
84
115
|
* Feedback messages for various operations
|
|
85
116
|
*/
|
|
@@ -5,12 +5,12 @@ import { routeTasksWithConfirm } from './router.js';
|
|
|
5
5
|
* Handle refinement flow for DEFINE tasks
|
|
6
6
|
* Called when user selects options from a plan with DEFINE tasks
|
|
7
7
|
*/
|
|
8
|
-
export async function handleRefinement(selectedTasks, service, originalCommand,
|
|
8
|
+
export async function handleRefinement(selectedTasks, service, originalCommand, lifecycleHandlers, workflowHandlers, requestHandlers) {
|
|
9
9
|
// Create and add refinement component to queue
|
|
10
10
|
const refinementDef = createRefinement(getRefiningMessage(), (operation) => {
|
|
11
|
-
|
|
11
|
+
requestHandlers.onAborted(operation);
|
|
12
12
|
});
|
|
13
|
-
|
|
13
|
+
workflowHandlers.addToQueue(refinementDef);
|
|
14
14
|
try {
|
|
15
15
|
// Build refined command from selected tasks
|
|
16
16
|
const refinedCommand = selectedTasks
|
|
@@ -22,19 +22,19 @@ export async function handleRefinement(selectedTasks, service, originalCommand,
|
|
|
22
22
|
.join(', ');
|
|
23
23
|
// Call LLM to refine plan with selected tasks
|
|
24
24
|
const refinedResult = await service.processWithTool(refinedCommand, 'schedule');
|
|
25
|
-
// Complete the Refinement component
|
|
25
|
+
// Complete the Refinement component with success state
|
|
26
26
|
lifecycleHandlers.completeActive();
|
|
27
27
|
// Add debug components to timeline if present
|
|
28
28
|
if (refinedResult.debug?.length) {
|
|
29
29
|
workflowHandlers.addToTimeline(...refinedResult.debug);
|
|
30
30
|
}
|
|
31
31
|
// Route refined tasks to appropriate components
|
|
32
|
-
routeTasksWithConfirm(refinedResult.tasks, refinedResult.message, service, originalCommand,
|
|
32
|
+
routeTasksWithConfirm(refinedResult.tasks, refinedResult.message, service, originalCommand, lifecycleHandlers, workflowHandlers, requestHandlers, false // No DEFINE tasks in refined result
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
catch (err) {
|
|
36
36
|
lifecycleHandlers.completeActive();
|
|
37
37
|
const errorMessage = formatErrorMessage(err);
|
|
38
|
-
|
|
38
|
+
requestHandlers.onError(errorMessage);
|
|
39
39
|
}
|
|
40
40
|
}
|