prompt-language-shell 0.7.8 → 0.8.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.
@@ -4,35 +4,30 @@ 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, getTextColor } from '../services/colors.js';
7
- import { addDebugToTimeline } from '../services/components.js';
7
+ import { addDebugToTimeline, createConfigStepsFromSchema, } from '../services/components.js';
8
+ import { DebugLevel, saveConfig, unflattenConfig, } from '../services/configuration.js';
9
+ import { saveConfigLabels } from '../services/config-labels.js';
8
10
  import { useInput } from '../services/keyboard.js';
9
11
  import { formatErrorMessage } from '../services/messages.js';
10
12
  import { ensureMinimumTime } from '../services/timing.js';
11
- import { DebugLevel, saveConfig, unflattenConfig, } from '../services/configuration.js';
12
- import { Config, StepType } from './Config.js';
13
+ import { Config } from './Config.js';
13
14
  import { Spinner } from './Spinner.js';
14
15
  const MIN_PROCESSING_TIME = 1000;
15
16
  export function Validate({ missingConfig, userRequest, state, status, service, children, debug = DebugLevel.None, onError, onComplete, onAborted, handlers, }) {
16
17
  const isActive = status === ComponentStatus.Active;
17
- const [error, setError] = useState(null);
18
- const [completionMessage, setCompletionMessage] = useState(null);
19
- const [configRequirements, setConfigRequirements] = useState(null);
20
- const [showConfig, setShowConfig] = useState(false);
18
+ const [error, setError] = useState(state?.error ?? null);
19
+ const [completionMessage, setCompletionMessage] = useState(state?.completionMessage ?? null);
20
+ const [configRequirements, setConfigRequirements] = useState(state?.configRequirements ?? null);
21
21
  useInput((_, key) => {
22
- if (key.escape && isActive && !showConfig) {
22
+ if (key.escape && isActive) {
23
23
  onAborted('validation');
24
24
  }
25
- }, { isActive: isActive && !showConfig });
25
+ }, { isActive });
26
26
  useEffect(() => {
27
27
  // Skip processing if not active
28
28
  if (!isActive) {
29
29
  return;
30
30
  }
31
- // Skip processing if no service available
32
- if (!service) {
33
- setError('No service available');
34
- return;
35
- }
36
31
  let mounted = true;
37
32
  async function process(svc) {
38
33
  const startTime = Date.now();
@@ -74,8 +69,10 @@ export function Validate({ missingConfig, userRequest, state, status, service, c
74
69
  setConfigRequirements(withDescriptions);
75
70
  // Save state after validation completes
76
71
  handlers?.updateState({
72
+ completionMessage: message,
77
73
  configRequirements: withDescriptions,
78
74
  validated: true,
75
+ error: null,
79
76
  });
80
77
  }
81
78
  }
@@ -83,20 +80,19 @@ export function Validate({ missingConfig, userRequest, state, status, service, c
83
80
  await ensureMinimumTime(startTime, MIN_PROCESSING_TIME);
84
81
  if (mounted) {
85
82
  const errorMessage = formatErrorMessage(err);
83
+ setError(errorMessage);
86
84
  // Save error state
87
85
  handlers?.updateState({
88
86
  error: errorMessage,
87
+ completionMessage: null,
88
+ configRequirements: null,
89
+ validated: false,
89
90
  });
90
- if (onError) {
91
- onError(errorMessage);
92
- }
93
- else {
94
- setError(errorMessage);
95
- }
91
+ onError(errorMessage);
96
92
  }
97
93
  }
98
94
  }
99
- process(service);
95
+ void process(service);
100
96
  return () => {
101
97
  mounted = false;
102
98
  };
@@ -113,20 +109,33 @@ export function Validate({ missingConfig, userRequest, state, status, service, c
113
109
  if (!isActive && !completionMessage && !error && !children) {
114
110
  return null;
115
111
  }
116
- // Create ConfigSteps from requirements
112
+ // Create ConfigSteps from requirements using createConfigStepsFromSchema
113
+ // to load current values from config file, then override descriptions
117
114
  const configSteps = configRequirements
118
- ? configRequirements.map((req) => ({
119
- description: req.description || req.path,
120
- key: req.path,
121
- path: req.path,
122
- type: StepType.Text,
123
- value: null,
124
- validate: () => true,
125
- }))
115
+ ? (() => {
116
+ const keys = configRequirements.map((req) => req.path);
117
+ const steps = createConfigStepsFromSchema(keys);
118
+ // Override descriptions with LLM-generated ones
119
+ return steps.map((step, index) => ({
120
+ ...step,
121
+ description: configRequirements[index].description ||
122
+ configRequirements[index].path,
123
+ }));
124
+ })()
126
125
  : null;
127
126
  const handleConfigFinished = (config) => {
128
127
  // Convert flat dotted keys to nested structure grouped by section
129
128
  const configBySection = unflattenConfig(config);
129
+ // Extract and save labels to cache
130
+ if (configRequirements) {
131
+ const labels = {};
132
+ for (const req of configRequirements) {
133
+ if (req.description) {
134
+ labels[req.path] = req.description;
135
+ }
136
+ }
137
+ saveConfigLabels(labels);
138
+ }
130
139
  // Save each section
131
140
  for (const [section, sectionConfig] of Object.entries(configBySection)) {
132
141
  saveConfig(section, sectionConfig);
@@ -135,7 +144,9 @@ export function Validate({ missingConfig, userRequest, state, status, service, c
135
144
  // This allows the workflow to proceed to execution
136
145
  handlers?.completeActive();
137
146
  // Invoke callback which will queue the Execute component
138
- onComplete?.(configRequirements);
147
+ if (configRequirements) {
148
+ onComplete(configRequirements);
149
+ }
139
150
  };
140
151
  const handleConfigAborted = (operation) => {
141
152
  // Mark validation component as complete when aborted
@@ -5,8 +5,8 @@ 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
7
  import { DebugLevel } from '../services/configuration.js';
8
- import { exitApp } from '../services/process.js';
9
8
  import { getCancellationMessage } from '../services/messages.js';
9
+ import { exitApp } from '../services/process.js';
10
10
  import { Component } from './Component.js';
11
11
  export const Workflow = ({ initialQueue, debug }) => {
12
12
  const [timeline, setTimeline] = useState([]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-language-shell",
3
- "version": "0.7.8",
3
+ "version": "0.8.2",
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",
@@ -47,22 +47,22 @@
47
47
  },
48
48
  "homepage": "https://github.com/aswitalski/pls#readme",
49
49
  "dependencies": {
50
- "@anthropic-ai/sdk": "^0.70.1",
51
- "ink": "^6.5.1",
50
+ "@anthropic-ai/sdk": "^0.71.2",
51
+ "ink": "^6.6.0",
52
52
  "ink-text-input": "^6.0.0",
53
- "react": "^19.2.0",
54
- "yaml": "^2.8.1"
53
+ "react": "^19.2.3",
54
+ "yaml": "^2.8.2"
55
55
  },
56
56
  "devDependencies": {
57
- "@types/node": "^24.10.1",
58
- "@types/react": "^19.2.6",
59
- "@vitest/coverage-v8": "^4.0.12",
60
- "eslint": "^9.39.1",
57
+ "@types/node": "^25.0.3",
58
+ "@types/react": "^19.2.7",
59
+ "@vitest/coverage-v8": "^4.0.16",
60
+ "eslint": "^9.39.2",
61
61
  "husky": "^9.1.7",
62
62
  "ink-testing-library": "^4.0.0",
63
- "prettier": "^3.6.2",
63
+ "prettier": "^3.7.4",
64
64
  "typescript": "^5.9.3",
65
- "typescript-eslint": "^8.47.0",
66
- "vitest": "^4.0.12"
65
+ "typescript-eslint": "^8.50.1",
66
+ "vitest": "^4.0.16"
67
67
  }
68
68
  }