prompt-language-shell 0.1.4 → 0.1.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/README.md +11 -32
- package/dist/index.js +10 -15
- package/dist/services/anthropic.js +7 -7
- package/dist/services/config.js +11 -15
- package/dist/services/skills.js +1 -1
- package/dist/types/components.js +1 -0
- package/dist/ui/Command.js +22 -11
- package/dist/ui/Configure.js +23 -0
- package/dist/ui/History.js +2 -1
- package/dist/ui/Main.js +55 -0
- package/dist/ui/Welcome.js +2 -2
- package/dist/ui/renderComponent.js +14 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,61 +10,40 @@ npm install -g prompt-language-shell
|
|
|
10
10
|
|
|
11
11
|
## Setup
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
1. Get your API key from [Anthropic Console](https://console.anthropic.com/)
|
|
16
|
-
2. Create the configuration directory and file:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
mkdir -p ~/.pls
|
|
20
|
-
echo "CLAUDE_API_KEY=sk-ant-your-api-key-here" > ~/.pls/.env
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Replace `sk-ant-your-api-key-here` with your actual API key.
|
|
13
|
+
On first run, `pls` walks you through a quick setup. Your settings will be saved to `~/.plsrc`.
|
|
24
14
|
|
|
25
15
|
## Usage
|
|
26
16
|
|
|
27
|
-
|
|
17
|
+
Type `pls` followed by your request in natural language:
|
|
28
18
|
|
|
29
19
|
```bash
|
|
30
20
|
pls change dir to ~
|
|
31
21
|
```
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- Display your original command
|
|
36
|
-
- Process it to grammatically correct and clarify it
|
|
37
|
-
- Show the interpreted task
|
|
38
|
-
|
|
39
|
-
Example output:
|
|
23
|
+
Your command will be interpreted and organized into a list of tasks:
|
|
40
24
|
|
|
41
25
|
```
|
|
42
26
|
> pls change dir to ~
|
|
43
|
-
-
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
You can provide multiple tasks separated by commas (`,`), semicolons (`;`), or the word "and":
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pls install deps, run tests and deploy
|
|
27
|
+
- Change directory to the home folder
|
|
50
28
|
```
|
|
51
29
|
|
|
52
|
-
|
|
30
|
+
You can provide multiple requests at once:
|
|
53
31
|
|
|
54
32
|
```
|
|
55
33
|
> pls install deps, run tests and deploy
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
34
|
+
- Install dependencies
|
|
35
|
+
- Run tests
|
|
36
|
+
- Deploy to server
|
|
59
37
|
```
|
|
60
38
|
|
|
61
39
|
Run `pls` without arguments to see the welcome screen.
|
|
62
40
|
|
|
63
41
|
## Configuration
|
|
64
42
|
|
|
65
|
-
|
|
43
|
+
Your configuration is stored in `~/.plsrc` as a YAML file. Supported settings:
|
|
66
44
|
|
|
67
|
-
- `
|
|
45
|
+
- `anthropic.api-key` - Your Anthropic API key
|
|
46
|
+
- `anthropic.model` - The Claude model to use for task planning
|
|
68
47
|
|
|
69
48
|
## Development
|
|
70
49
|
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { dirname, join } from 'path';
|
|
|
6
6
|
import { render, Text } from 'ink';
|
|
7
7
|
import { loadConfig, ConfigError, configExists, saveConfig, } from './services/config.js';
|
|
8
8
|
import { createAnthropicService } from './services/anthropic.js';
|
|
9
|
-
import {
|
|
9
|
+
import { Main } from './ui/Main.js';
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = dirname(__filename);
|
|
12
12
|
// Get package info
|
|
@@ -17,7 +17,7 @@ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
|
17
17
|
// In production, we're in node_modules and src/ doesn't exist alongside
|
|
18
18
|
const srcPath = join(__dirname, '../src');
|
|
19
19
|
const isDev = existsSync(srcPath);
|
|
20
|
-
const
|
|
20
|
+
const app = {
|
|
21
21
|
name: packageJson.name,
|
|
22
22
|
version: packageJson.version,
|
|
23
23
|
description: packageJson.description,
|
|
@@ -25,13 +25,14 @@ const appInfo = {
|
|
|
25
25
|
};
|
|
26
26
|
// Get command from command-line arguments
|
|
27
27
|
const args = process.argv.slice(2);
|
|
28
|
-
const
|
|
28
|
+
const command = args.join(' ').trim() || null;
|
|
29
29
|
async function runApp() {
|
|
30
30
|
// First-time setup: config doesn't exist
|
|
31
31
|
if (!configExists()) {
|
|
32
|
-
const { waitUntilExit } = render(_jsx(
|
|
33
|
-
saveConfig(
|
|
34
|
-
|
|
32
|
+
const { waitUntilExit } = render(_jsx(Main, { app: app, command: command, isReady: false, onConfigured: (config) => {
|
|
33
|
+
saveConfig('anthropic', config);
|
|
34
|
+
// Create service once for the session
|
|
35
|
+
return command ? createAnthropicService(config) : undefined;
|
|
35
36
|
} }));
|
|
36
37
|
await waitUntilExit();
|
|
37
38
|
return;
|
|
@@ -39,15 +40,9 @@ async function runApp() {
|
|
|
39
40
|
// Try to load and validate config
|
|
40
41
|
try {
|
|
41
42
|
const config = loadConfig();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
// "pls do stuff": fetch and show the plan
|
|
48
|
-
const claudeService = createAnthropicService(config.anthropic.apiKey, config.anthropic.model);
|
|
49
|
-
render(_jsx(PLS, { app: appInfo, command: rawCommand, claudeService: claudeService }));
|
|
50
|
-
}
|
|
43
|
+
// Create service once at app initialization
|
|
44
|
+
const service = createAnthropicService(config.anthropic);
|
|
45
|
+
render(_jsx(Main, { app: app, command: command, service: service, isReady: true }));
|
|
51
46
|
}
|
|
52
47
|
catch (error) {
|
|
53
48
|
if (error instanceof ConfigError) {
|
|
@@ -9,23 +9,23 @@ const PLAN_PROMPT = readFileSync(join(__dirname, '../config/PLAN.md'), 'utf-8');
|
|
|
9
9
|
export class AnthropicService {
|
|
10
10
|
client;
|
|
11
11
|
model;
|
|
12
|
-
constructor(
|
|
13
|
-
this.client = new Anthropic({ apiKey });
|
|
12
|
+
constructor(key, model = 'claude-haiku-4-5-20251001') {
|
|
13
|
+
this.client = new Anthropic({ apiKey: key });
|
|
14
14
|
this.model = model;
|
|
15
15
|
}
|
|
16
|
-
async processCommand(
|
|
16
|
+
async processCommand(command) {
|
|
17
17
|
// Load skills and augment the planning prompt
|
|
18
18
|
const skills = loadSkills();
|
|
19
19
|
const skillsSection = formatSkillsForPrompt(skills);
|
|
20
20
|
const systemPrompt = PLAN_PROMPT + skillsSection;
|
|
21
21
|
const response = await this.client.messages.create({
|
|
22
22
|
model: this.model,
|
|
23
|
-
max_tokens:
|
|
23
|
+
max_tokens: 512,
|
|
24
24
|
system: systemPrompt,
|
|
25
25
|
messages: [
|
|
26
26
|
{
|
|
27
27
|
role: 'user',
|
|
28
|
-
content:
|
|
28
|
+
content: command,
|
|
29
29
|
},
|
|
30
30
|
],
|
|
31
31
|
});
|
|
@@ -69,6 +69,6 @@ export class AnthropicService {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
export function createAnthropicService(
|
|
73
|
-
return new AnthropicService(
|
|
72
|
+
export function createAnthropicService(config) {
|
|
73
|
+
return new AnthropicService(config.key, config.model);
|
|
74
74
|
}
|
package/dist/services/config.js
CHANGED
|
@@ -29,20 +29,19 @@ function validateConfig(parsed) {
|
|
|
29
29
|
throw new ConfigError(`\nMissing or invalid 'anthropic' section in ${CONFIG_FILE}\n` +
|
|
30
30
|
'Please add:\n' +
|
|
31
31
|
'anthropic:\n' +
|
|
32
|
-
'
|
|
32
|
+
' key: sk-ant-...');
|
|
33
33
|
}
|
|
34
34
|
const anthropic = config.anthropic;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
throw new ConfigError(`\nMissing or invalid 'anthropic.api-key' in ${CONFIG_FILE}\n` +
|
|
35
|
+
const key = anthropic['key'];
|
|
36
|
+
if (!key || typeof key !== 'string') {
|
|
37
|
+
throw new ConfigError(`\nMissing or invalid 'anthropic.key' in ${CONFIG_FILE}\n` +
|
|
39
38
|
'Please add your Anthropic API key:\n' +
|
|
40
39
|
'anthropic:\n' +
|
|
41
|
-
'
|
|
40
|
+
' key: sk-ant-...');
|
|
42
41
|
}
|
|
43
42
|
const validatedConfig = {
|
|
44
43
|
anthropic: {
|
|
45
|
-
|
|
44
|
+
key,
|
|
46
45
|
},
|
|
47
46
|
};
|
|
48
47
|
// Optional model
|
|
@@ -57,7 +56,7 @@ export function loadConfig() {
|
|
|
57
56
|
'Please create it with your Anthropic API key.\n' +
|
|
58
57
|
'Example:\n\n' +
|
|
59
58
|
'anthropic:\n' +
|
|
60
|
-
'
|
|
59
|
+
' key: sk-ant-...\n' +
|
|
61
60
|
' model: claude-haiku-4-5-20251001\n');
|
|
62
61
|
}
|
|
63
62
|
const content = readFileSync(CONFIG_FILE, 'utf-8');
|
|
@@ -72,10 +71,10 @@ export function configExists() {
|
|
|
72
71
|
}
|
|
73
72
|
export function mergeConfig(existingContent, sectionName, newValues) {
|
|
74
73
|
const parsed = existingContent.trim()
|
|
75
|
-
? YAML.parse(existingContent)
|
|
74
|
+
? YAML.parse(existingContent)
|
|
76
75
|
: {};
|
|
77
76
|
// Update or add section
|
|
78
|
-
const section = parsed[sectionName]
|
|
77
|
+
const section = parsed[sectionName] ?? {};
|
|
79
78
|
for (const [key, value] of Object.entries(newValues)) {
|
|
80
79
|
section[key] = value;
|
|
81
80
|
}
|
|
@@ -89,13 +88,10 @@ export function mergeConfig(existingContent, sectionName, newValues) {
|
|
|
89
88
|
// Convert back to YAML
|
|
90
89
|
return YAML.stringify(sortedConfig);
|
|
91
90
|
}
|
|
92
|
-
export function saveConfig(
|
|
91
|
+
export function saveConfig(section, config) {
|
|
93
92
|
const existingContent = existsSync(CONFIG_FILE)
|
|
94
93
|
? readFileSync(CONFIG_FILE, 'utf-8')
|
|
95
94
|
: '';
|
|
96
|
-
const newContent = mergeConfig(existingContent,
|
|
97
|
-
'api-key': apiKey,
|
|
98
|
-
model: model,
|
|
99
|
-
});
|
|
95
|
+
const newContent = mergeConfig(existingContent, section, config);
|
|
100
96
|
writeFileSync(CONFIG_FILE, newContent, 'utf-8');
|
|
101
97
|
}
|
package/dist/services/skills.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/ui/Command.js
CHANGED
|
@@ -2,18 +2,29 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
3
|
import { Box, Text } from 'ink';
|
|
4
4
|
import { Spinner } from './Spinner.js';
|
|
5
|
-
const MIN_PROCESSING_TIME = 2000; //
|
|
6
|
-
export function Command({
|
|
7
|
-
const
|
|
8
|
-
const [
|
|
9
|
-
const [
|
|
10
|
-
const [
|
|
5
|
+
const MIN_PROCESSING_TIME = 2000; // purely for visual effect
|
|
6
|
+
export function Command({ command, state, service, tasks, error: errorProp, systemPrompt: systemPromptProp, }) {
|
|
7
|
+
const done = state?.done ?? false;
|
|
8
|
+
const [processedTasks, setProcessedTasks] = useState(tasks || []);
|
|
9
|
+
const [systemPrompt, setSystemPrompt] = useState(systemPromptProp);
|
|
10
|
+
const [error, setError] = useState(state?.error || errorProp || null);
|
|
11
|
+
const [isLoading, setIsLoading] = useState(state?.isLoading ?? !done);
|
|
11
12
|
useEffect(() => {
|
|
13
|
+
// Skip processing if done (showing historical/final state)
|
|
14
|
+
if (done) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// Skip processing if no service available
|
|
18
|
+
if (!service) {
|
|
19
|
+
setError('No service available');
|
|
20
|
+
setIsLoading(false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
12
23
|
let mounted = true;
|
|
13
|
-
async function process() {
|
|
24
|
+
async function process(svc) {
|
|
14
25
|
const startTime = Date.now();
|
|
15
26
|
try {
|
|
16
|
-
const result = await
|
|
27
|
+
const result = await svc.processCommand(command);
|
|
17
28
|
const elapsed = Date.now() - startTime;
|
|
18
29
|
const remainingTime = Math.max(0, MIN_PROCESSING_TIME - elapsed);
|
|
19
30
|
await new Promise((resolve) => setTimeout(resolve, remainingTime));
|
|
@@ -33,10 +44,10 @@ export function Command({ rawCommand, claudeService }) {
|
|
|
33
44
|
}
|
|
34
45
|
}
|
|
35
46
|
}
|
|
36
|
-
process();
|
|
47
|
+
process(service);
|
|
37
48
|
return () => {
|
|
38
49
|
mounted = false;
|
|
39
50
|
};
|
|
40
|
-
}, [
|
|
41
|
-
return (_jsxs(Box, { alignSelf: "flex-start", marginBottom: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["> pls ",
|
|
51
|
+
}, [command, done, service]);
|
|
52
|
+
return (_jsxs(Box, { alignSelf: "flex-start", marginBottom: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["> pls ", command] }), isLoading && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Spinner, {})] }))] }), error && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), processedTasks.length > 0 && (_jsx(Box, { flexDirection: "column", children: processedTasks.map((task, index) => (_jsxs(Box, { children: [_jsx(Text, { color: "whiteBright", children: ' - ' }), _jsx(Text, { color: "white", children: task })] }, index))) }))] }));
|
|
42
53
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import TextInput from 'ink-text-input';
|
|
5
|
+
export function Configure({ state, key: keyProp, model: modelProp, onComplete, }) {
|
|
6
|
+
const done = state?.done ?? false;
|
|
7
|
+
const [step, setStep] = React.useState(state?.step ?? (done ? 'done' : 'key'));
|
|
8
|
+
const [key, setKey] = React.useState(keyProp || '');
|
|
9
|
+
const [model, setModel] = React.useState(modelProp || 'claude-haiku-4-5-20251001');
|
|
10
|
+
const handleKeySubmit = (value) => {
|
|
11
|
+
setKey(value);
|
|
12
|
+
setStep('model');
|
|
13
|
+
};
|
|
14
|
+
const handleModelSubmit = (value) => {
|
|
15
|
+
const finalModel = value.trim() || 'claude-haiku-4-5-20251001';
|
|
16
|
+
setModel(finalModel);
|
|
17
|
+
setStep('done');
|
|
18
|
+
if (onComplete) {
|
|
19
|
+
onComplete({ key, model: finalModel });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [!done && _jsx(Text, { children: "Configuration required." }), !done && (_jsx(Box, { children: _jsxs(Text, { color: "whiteBright", dimColor: true, children: ['==>', " Get your API key from: https://platform.claude.com/"] }) })), _jsx(Box, { marginTop: done ? 0 : 1, children: _jsx(Text, { children: "Anthropic API key:" }) }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: "> " }), step === 'key' && !done ? (_jsx(TextInput, { value: key, onChange: setKey, onSubmit: handleKeySubmit, mask: "*" })) : (_jsx(Text, { dimColor: true, children: '*'.repeat(12) }))] }), (step === 'model' || step === 'done') && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { children: _jsxs(Text, { children: ["Model", ' ', !done && (_jsx(Text, { dimColor: true, children: "(default: claude-haiku-4-5-20251001)" })), ":"] }) }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: "> " }), step === 'model' && !done ? (_jsx(TextInput, { value: model, onChange: setModel, onSubmit: handleModelSubmit })) : (_jsx(Text, { dimColor: true, children: model }))] })] })), step === 'done' && !done && (_jsx(Box, { marginY: 1, children: _jsx(Text, { color: "green", children: "\u2713 Configuration saved" }) }))] }));
|
|
23
|
+
}
|
package/dist/ui/History.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box } from 'ink';
|
|
3
|
+
import { renderComponent } from './renderComponent.js';
|
|
3
4
|
export function History({ items }) {
|
|
4
5
|
if (items.length === 0) {
|
|
5
6
|
return null;
|
|
6
7
|
}
|
|
7
|
-
return (_jsx(Box, { flexDirection: "column", gap: 1, children: items.map((item, index) => (_jsx(Box, { children: item }, index))) }));
|
|
8
|
+
return (_jsx(Box, { flexDirection: "column", gap: 1, children: items.map((item, index) => (_jsx(Box, { children: renderComponent(item) }, `${item.name}-${index}`))) }));
|
|
8
9
|
}
|
package/dist/ui/Main.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box } from 'ink';
|
|
4
|
+
import { History } from './History.js';
|
|
5
|
+
import { renderComponent } from './renderComponent.js';
|
|
6
|
+
export const Main = ({ app, command, service, isReady, onConfigured, }) => {
|
|
7
|
+
const [history, setHistory] = React.useState([]);
|
|
8
|
+
const [current, setCurrent] = React.useState(null);
|
|
9
|
+
React.useEffect(() => {
|
|
10
|
+
// Initialize history and current component based on props
|
|
11
|
+
if (!isReady) {
|
|
12
|
+
// Not configured - show welcome in history, configure as current
|
|
13
|
+
setHistory([
|
|
14
|
+
{
|
|
15
|
+
name: 'welcome',
|
|
16
|
+
props: {
|
|
17
|
+
app,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
setCurrent({
|
|
22
|
+
name: 'configure',
|
|
23
|
+
state: {
|
|
24
|
+
done: false,
|
|
25
|
+
step: 'key',
|
|
26
|
+
},
|
|
27
|
+
props: {
|
|
28
|
+
onComplete: onConfigured,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else if (command && service) {
|
|
33
|
+
setCurrent({
|
|
34
|
+
name: 'command',
|
|
35
|
+
state: {
|
|
36
|
+
done: false,
|
|
37
|
+
isLoading: true,
|
|
38
|
+
},
|
|
39
|
+
props: {
|
|
40
|
+
command,
|
|
41
|
+
service,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
setCurrent({
|
|
47
|
+
name: 'welcome',
|
|
48
|
+
props: {
|
|
49
|
+
app,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}, [isReady, command, service, app, onConfigured]);
|
|
54
|
+
return (_jsxs(Box, { marginTop: 1, flexDirection: "column", gap: 1, children: [_jsx(History, { items: history }), current && renderComponent(current)] }));
|
|
55
|
+
};
|
package/dist/ui/Welcome.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Text, Box } from 'ink';
|
|
3
|
-
export function Welcome({
|
|
3
|
+
export function Welcome({ app: app }) {
|
|
4
4
|
const descriptionLines = app.description
|
|
5
5
|
.split('. ')
|
|
6
6
|
.map((line) => line.replace(/\.$/, ''))
|
|
@@ -9,5 +9,5 @@ export function Welcome({ info: app }) {
|
|
|
9
9
|
const words = app.name
|
|
10
10
|
.split('-')
|
|
11
11
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1));
|
|
12
|
-
return (_jsx(Box, { alignSelf: "flex-start", children: _jsxs(Box, { borderStyle: "round", borderColor: "green", paddingX: 3, paddingY: 1, flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, gap: 1, children: [words.map((word, index) => (_jsx(Text, { color: "greenBright", bold: true, children: word }, index))), _jsxs(Text, { color: "whiteBright", dimColor: true, children: ["v", app.version] }), app.isDev && _jsx(Text, { color: "yellowBright", children: "dev" })] }), descriptionLines.map((line, index) => (_jsx(Box, { children: _jsxs(Text, { color: "white", children: [line, "."] }) }, index))), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "brightWhite", bold: true, children: "Usage:" }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "whiteBright", dimColor: true, children: ">" }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "greenBright", bold: true, children: "pls" }), _jsx(Text, { color: "yellow", bold: true, children: "[describe your request]" })] })] })] })] }) }));
|
|
12
|
+
return (_jsx(Box, { alignSelf: "flex-start", marginBottom: 1, children: _jsxs(Box, { borderStyle: "round", borderColor: "green", paddingX: 3, paddingY: 1, flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, gap: 1, children: [words.map((word, index) => (_jsx(Text, { color: "greenBright", bold: true, children: word }, index))), _jsxs(Text, { color: "whiteBright", dimColor: true, children: ["v", app.version] }), app.isDev && _jsx(Text, { color: "yellowBright", children: "dev" })] }), descriptionLines.map((line, index) => (_jsx(Box, { children: _jsxs(Text, { color: "white", children: [line, "."] }) }, index))), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "brightWhite", bold: true, children: "Usage:" }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "whiteBright", dimColor: true, children: ">" }), _jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "greenBright", bold: true, children: "pls" }), _jsx(Text, { color: "yellow", bold: true, children: "[describe your request]" })] })] })] })] }) }));
|
|
13
13
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Welcome } from './Welcome.js';
|
|
3
|
+
import { Configure } from './Configure.js';
|
|
4
|
+
import { Command } from './Command.js';
|
|
5
|
+
export function renderComponent(def) {
|
|
6
|
+
switch (def.name) {
|
|
7
|
+
case 'welcome':
|
|
8
|
+
return _jsx(Welcome, { ...def.props });
|
|
9
|
+
case 'configure':
|
|
10
|
+
return (_jsx(Configure, { ...def.props, state: 'state' in def ? def.state : undefined }));
|
|
11
|
+
case 'command':
|
|
12
|
+
return (_jsx(Command, { ...def.props, state: 'state' in def ? def.state : undefined }));
|
|
13
|
+
}
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-language-shell",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.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",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"prepare": "npm run build",
|
|
17
17
|
"test": "vitest run",
|
|
18
18
|
"test:watch": "vitest",
|
|
19
|
-
"format": "prettier --write
|
|
20
|
-
"format:check": "prettier --check
|
|
19
|
+
"format": "prettier --write '**/*.{ts,tsx}'",
|
|
20
|
+
"format:check": "prettier --check '**/*.{ts,tsx}'",
|
|
21
21
|
"lint": "eslint .",
|
|
22
22
|
"lint:fix": "eslint --fix ."
|
|
23
23
|
},
|