prompt-language-shell 0.7.2 → 0.7.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.
@@ -4,7 +4,7 @@ import { Box, Text } from 'ink';
4
4
  import { ComponentStatus, } from '../types/components.js';
5
5
  import { TaskType } from '../types/types.js';
6
6
  import { Colors } from '../services/colors.js';
7
- import { createPlanDefinition } from '../services/components.js';
7
+ import { createScheduleDefinition } from '../services/components.js';
8
8
  import { formatErrorMessage } from '../services/messages.js';
9
9
  import { useInput } from '../services/keyboard.js';
10
10
  import { handleRefinement } from '../services/refinement.js';
@@ -36,7 +36,9 @@ export function Command({ command, state, status, service, handlers, onAborted,
36
36
  async function process(svc) {
37
37
  const startTime = Date.now();
38
38
  try {
39
- let result = await svc.processWithTool(command, 'plan');
39
+ let result = await svc.processWithTool(command, 'schedule');
40
+ // Save schedule debug output before potentially delegating
41
+ const scheduleDebug = result.debug || [];
40
42
  // If all tasks are configure type, delegate to CONFIGURE tool
41
43
  const allConfig = result.tasks.length > 0 &&
42
44
  result.tasks.every((task) => task.type === TaskType.Config);
@@ -49,8 +51,13 @@ export function Command({ command, state, status, service, handlers, onAborted,
49
51
  await ensureMinimumTime(startTime, MIN_PROCESSING_TIME);
50
52
  if (mounted) {
51
53
  // Add debug components to timeline if present
52
- if (result.debug && result.debug.length > 0) {
53
- handlers?.addToTimeline(...result.debug);
54
+ // If we delegated to configure, include both schedule and configure debug
55
+ // If not, only include schedule debug (result.debug is same as scheduleDebug)
56
+ const allDebug = allConfig
57
+ ? [...scheduleDebug, ...(result.debug || [])]
58
+ : scheduleDebug;
59
+ if (allDebug.length > 0) {
60
+ handlers?.addToTimeline(...allDebug);
54
61
  }
55
62
  // Save result to state for timeline display
56
63
  handlers?.updateState({
@@ -59,17 +66,17 @@ export function Command({ command, state, status, service, handlers, onAborted,
59
66
  });
60
67
  // Check if tasks contain DEFINE type (variant selection needed)
61
68
  const hasDefineTask = result.tasks.some((task) => task.type === TaskType.Define);
62
- // Create Plan definition
63
- const planDefinition = createPlanDefinition(result.message, result.tasks, hasDefineTask
69
+ // Create Schedule definition
70
+ const scheduleDefinition = createScheduleDefinition(result.message, result.tasks, hasDefineTask
64
71
  ? async (selectedTasks) => {
65
72
  // Refinement flow for DEFINE tasks
66
73
  await handleRefinement(selectedTasks, svc, command, handlers);
67
74
  }
68
75
  : undefined);
69
76
  if (hasDefineTask) {
70
- // DEFINE tasks: Move Command to timeline, add Plan to queue
77
+ // DEFINE tasks: Move Command to timeline, add Schedule to queue
71
78
  handlers?.completeActive();
72
- handlers?.addToQueue(planDefinition);
79
+ handlers?.addToQueue(scheduleDefinition);
73
80
  }
74
81
  else {
75
82
  // No DEFINE tasks: Complete Command, then route to Confirm flow
@@ -10,7 +10,7 @@ import { Execute } from './Execute.js';
10
10
  import { Feedback } from './Feedback.js';
11
11
  import { Introspect } from './Introspect.js';
12
12
  import { Message } from './Message.js';
13
- import { Plan } from './Plan.js';
13
+ import { Schedule } from './Schedule.js';
14
14
  import { Refinement } from './Refinement.js';
15
15
  import { Report } from './Report.js';
16
16
  import { Validate } from './Validate.js';
@@ -23,8 +23,8 @@ export const Component = memo(function Component({ def, debug, }) {
23
23
  return (_jsx(Config, { ...def.props, state: def.state, status: def.status, debug: debug }));
24
24
  case ComponentName.Command:
25
25
  return _jsx(Command, { ...def.props, state: def.state, status: def.status });
26
- case ComponentName.Plan:
27
- return (_jsx(Plan, { ...def.props, state: def.state, status: def.status, debug: debug }));
26
+ case ComponentName.Schedule:
27
+ return (_jsx(Schedule, { ...def.props, state: def.state, status: def.status, debug: debug }));
28
28
  case ComponentName.Feedback:
29
29
  return _jsx(Feedback, { ...def.props, status: def.status });
30
30
  case ComponentName.Message:
package/dist/ui/Debug.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from 'ink';
3
- const MIN_CONTENT_WIDTH = 80;
3
+ const CONTENT_WIDTH = 80;
4
4
  const HORIZONTAL_PADDING = 2;
5
- const BORDER_WIDTH = 1;
6
5
  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 })] }));
6
+ return (_jsxs(Box, { flexDirection: "column", paddingX: HORIZONTAL_PADDING, paddingY: 1, borderStyle: "single", borderColor: color, width: CONTENT_WIDTH, children: [_jsx(Text, { color: color, wrap: "wrap", children: title }), _jsx(Text, { color: color, wrap: "wrap", children: content })] }));
8
7
  };
@@ -11,15 +11,15 @@ import { ensureMinimumTime } from '../services/timing.js';
11
11
  import { Spinner } from './Spinner.js';
12
12
  const MIN_PROCESSING_TIME = 1000;
13
13
  const BUILT_IN_CAPABILITIES = new Set([
14
- 'CONFIG',
15
- 'PLAN',
14
+ 'CONFIGURE',
15
+ 'SCHEDULE',
16
16
  'INTROSPECT',
17
17
  'ANSWER',
18
18
  'EXECUTE',
19
19
  'VALIDATE',
20
20
  'REPORT',
21
21
  ]);
22
- const INDIRECT_CAPABILITIES = new Set(['PLAN', 'VALIDATE', 'REPORT']);
22
+ const INDIRECT_CAPABILITIES = new Set(['SCHEDULE', 'VALIDATE', 'REPORT']);
23
23
  function parseCapabilityFromTask(task) {
24
24
  // Parse "NAME: Description" format from task.action
25
25
  const colonIndex = task.action.indexOf(':');
@@ -85,7 +85,7 @@ export function Introspect({ tasks, state, status, service, children, debug = De
85
85
  let capabilities = result.tasks.map(parseCapabilityFromTask);
86
86
  // Filter out internal capabilities when not in debug mode
87
87
  if (debug === DebugLevel.None) {
88
- capabilities = capabilities.filter((cap) => cap.name.toUpperCase() !== 'PLAN' &&
88
+ capabilities = capabilities.filter((cap) => cap.name.toUpperCase() !== 'SCHEDULE' &&
89
89
  cap.name.toUpperCase() !== 'VALIDATE' &&
90
90
  cap.name.toUpperCase() !== 'REPORT');
91
91
  }
package/dist/ui/List.js CHANGED
@@ -2,13 +2,14 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { Box, Text } from 'ink';
3
3
  import { Separator } from './Separator.js';
4
4
  export const List = ({ items, level = 0, highlightedIndex = null, highlightedParentIndex = null, showType = false, }) => {
5
- const marginLeft = level > 0 ? 4 : 0;
5
+ const marginLeft = level > 0 ? 2 : 0;
6
6
  return (_jsx(Box, { flexDirection: "column", marginLeft: marginLeft, children: items.map((item, index) => {
7
7
  // At level 0, track which parent is active for child highlighting
8
8
  // At level > 0, only highlight if this parent is the active one
9
9
  const shouldHighlightChildren = level === 0 ? highlightedParentIndex === index : false;
10
10
  const isHighlighted = item.highlighted || (level > 0 && index === highlightedIndex);
11
- const marker = item.marker || (isHighlighted ? ' ' : ' - ');
11
+ const defaultMarker = level > 0 ? ' · ' : ' - ';
12
+ const marker = item.marker || (isHighlighted ? ' → ' : defaultMarker);
12
13
  // Use highlighted colors if available and item is highlighted
13
14
  const descriptionColor = isHighlighted && item.description.highlightedColor
14
15
  ? item.description.highlightedColor
@@ -21,7 +21,7 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
21
21
  // Mark define tasks with right arrow when no selection has been made
22
22
  if (isDefineTaskWithoutSelection) {
23
23
  item.marker = ' → ';
24
- item.markerColor = getTaskColors(TaskType.Plan, isCurrent).type;
24
+ item.markerColor = getTaskColors(TaskType.Schedule, isCurrent).type;
25
25
  }
26
26
  // Add children for Define tasks with options
27
27
  if (task.type === TaskType.Define && Array.isArray(task.params?.options)) {
@@ -34,7 +34,7 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
34
34
  index === highlightedChildIndex ? TaskType.Execute : TaskType.Discard;
35
35
  }
36
36
  const colors = getTaskColors(childType, isCurrent);
37
- const planColors = getTaskColors(TaskType.Plan, isCurrent);
37
+ const planColors = getTaskColors(TaskType.Schedule, isCurrent);
38
38
  return {
39
39
  description: {
40
40
  text: String(option),
@@ -49,9 +49,29 @@ function taskToListItem(task, highlightedChildIndex = null, isDefineTaskWithoutS
49
49
  };
50
50
  });
51
51
  }
52
+ // Add children for Group tasks with subtasks
53
+ const scheduledTask = task;
54
+ if (task.type === TaskType.Group &&
55
+ scheduledTask.subtasks &&
56
+ Array.isArray(scheduledTask.subtasks) &&
57
+ scheduledTask.subtasks.length > 0) {
58
+ item.children = scheduledTask.subtasks.map((subtask) => {
59
+ const subtaskColors = getTaskColors(subtask.type, isCurrent);
60
+ return {
61
+ description: {
62
+ text: subtask.action,
63
+ color: subtaskColors.description,
64
+ },
65
+ type: {
66
+ text: getTaskTypeLabel(subtask.type, debug),
67
+ color: subtaskColors.type,
68
+ },
69
+ };
70
+ });
71
+ }
52
72
  return item;
53
73
  }
54
- export function Plan({ message, tasks, state, status, debug = DebugLevel.None, handlers, onSelectionConfirmed, }) {
74
+ export function Schedule({ message, tasks, state, status, debug = DebugLevel.None, handlers, onSelectionConfirmed, }) {
55
75
  const isActive = status === ComponentStatus.Active;
56
76
  // isActive passed as prop
57
77
  const [highlightedIndex, setHighlightedIndex] = useState(state?.highlightedIndex ?? null);
@@ -138,6 +158,7 @@ export function Plan({ message, tasks, state, status, debug = DebugLevel.None, h
138
158
  refinedTasks.push({
139
159
  action: selectedOption,
140
160
  type: TaskType.Execute,
161
+ config: [],
141
162
  });
142
163
  }
143
164
  else if (task.type !== TaskType.Ignore &&
@@ -202,5 +223,5 @@ export function Plan({ message, tasks, state, status, debug = DebugLevel.None, h
202
223
  isActive;
203
224
  return taskToListItem(task, childIndex, isDefineWithoutSelection, isActive, debug);
204
225
  });
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 }) })] }));
226
+ return (_jsxs(Box, { flexDirection: "column", children: [message && (_jsx(Box, { marginBottom: 1, marginLeft: 1, children: _jsx(Label, { description: message, taskType: TaskType.Schedule, 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 }) })] }));
206
227
  }
@@ -139,7 +139,7 @@ export function Validate({ missingConfig, userRequest, state, status, service, c
139
139
  handlers?.completeActive();
140
140
  onAborted(operation);
141
141
  };
142
- return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isActive && !completionMessage && !error && (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: getTextColor(isActive), children: ["Validating configuration requirements.", ' '] }), _jsx(Spinner, {})] })), completionMessage && (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: completionMessage }) })), error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) })), configSteps && !error && (_jsx(Box, { marginTop: 1, children: _jsx(Config, { steps: configSteps, status: status, debug: debug, onFinished: handleConfigFinished, onAborted: handleConfigAborted, handlers: handlers }) })), children] }));
142
+ return (_jsxs(Box, { alignSelf: "flex-start", flexDirection: "column", children: [isActive && !completionMessage && !error && (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: getTextColor(isActive), children: ["Validating configuration requirements.", ' '] }), _jsx(Spinner, {})] })), completionMessage && (_jsx(Box, { marginLeft: 1, children: _jsx(Text, { color: getTextColor(isActive), children: completionMessage }) })), error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.Status.Error, children: ["Error: ", error] }) })), configSteps && configSteps.length > 0 && !error && (_jsx(Box, { marginTop: 1, children: _jsx(Config, { steps: configSteps, status: status, debug: debug, onFinished: handleConfigFinished, onAborted: handleConfigAborted, handlers: handlers }) })), configSteps && configSteps.length === 0 && !error && (_jsx(Box, { marginTop: 1, marginLeft: 1, children: _jsx(Text, { color: Colors.Status.Error, children: "Error: No configuration steps generated. Please try again." }) })), children] }));
143
143
  }
144
144
  /**
145
145
  * Build prompt for VALIDATE tool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-language-shell",
3
- "version": "0.7.2",
3
+ "version": "0.7.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",
@@ -17,8 +17,9 @@
17
17
  "dev": "npm run build && tsc --watch",
18
18
  "prepare": "husky",
19
19
  "prepublishOnly": "npm run check",
20
- "test": "vitest run",
21
- "test:watch": "vitest",
20
+ "test": "vitest run --exclude 'tests/integration/*.test.tsx'",
21
+ "test:watch": "vitest --exclude 'tests/integration/*.test.tsx'",
22
+ "test:llm": "vitest run tests/integration/schedule*.test.tsx",
22
23
  "format": "prettier --write '**/*.{ts,tsx}'",
23
24
  "format:check": "prettier --check '**/*.{ts,tsx}'",
24
25
  "lint": "eslint .",