@involvex/prompt-enhancer 0.0.5 → 0.0.8
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/package.json +109 -0
- package/dist/prompt-enhancer.exe +0 -0
- package/dist/{app.js → src/app.js} +4 -0
- package/dist/src/components/enhance-prompt.d.ts +6 -0
- package/dist/{components → src/components}/enhance-prompt.js +54 -5
- package/dist/{lib → src/lib}/enhancement/engine.d.ts +2 -2
- package/dist/{lib → src/lib}/enhancement/engine.js +1 -1
- package/dist/src/lib/utils/clipboard.d.ts +11 -0
- package/dist/src/lib/utils/clipboard.js +143 -0
- package/package.json +11 -3
- package/dist/components/enhance-prompt.d.ts +0 -5
- package/dist/lib/utils/clipboard.d.ts +0 -5
- package/dist/lib/utils/clipboard.js +0 -69
- /package/dist/{app.d.ts → src/app.d.ts} +0 -0
- /package/dist/{cli.d.ts → src/cli.d.ts} +0 -0
- /package/dist/{cli.js → src/cli.js} +0 -0
- /package/dist/{commands → src/commands}/about.d.ts +0 -0
- /package/dist/{commands → src/commands}/about.js +0 -0
- /package/dist/{commands → src/commands}/direct-enhance.d.ts +0 -0
- /package/dist/{commands → src/commands}/direct-enhance.js +0 -0
- /package/dist/{commands → src/commands}/enhanceprompt.d.ts +0 -0
- /package/dist/{commands → src/commands}/enhanceprompt.js +0 -0
- /package/dist/{commands → src/commands}/help.d.ts +0 -0
- /package/dist/{commands → src/commands}/help.js +0 -0
- /package/dist/{commands → src/commands}/settings.d.ts +0 -0
- /package/dist/{commands → src/commands}/settings.js +0 -0
- /package/dist/{commands → src/commands}/version.d.ts +0 -0
- /package/dist/{commands → src/commands}/version.js +0 -0
- /package/dist/{components → src/components}/history-viewer.d.ts +0 -0
- /package/dist/{components → src/components}/history-viewer.js +0 -0
- /package/dist/{components → src/components}/menu.d.ts +0 -0
- /package/dist/{components → src/components}/menu.js +0 -0
- /package/dist/{components → src/components}/select-input.d.ts +0 -0
- /package/dist/{components → src/components}/select-input.js +0 -0
- /package/dist/{components → src/components}/settings.d.ts +0 -0
- /package/dist/{components → src/components}/settings.js +0 -0
- /package/dist/{lib → src/lib}/config/manager.d.ts +0 -0
- /package/dist/{lib → src/lib}/config/manager.js +0 -0
- /package/dist/{lib → src/lib}/config/schema.d.ts +0 -0
- /package/dist/{lib → src/lib}/config/schema.js +0 -0
- /package/dist/{lib → src/lib}/config/types.d.ts +0 -0
- /package/dist/{lib → src/lib}/config/types.js +0 -0
- /package/dist/{lib → src/lib}/history/manager.d.ts +0 -0
- /package/dist/{lib → src/lib}/history/manager.js +0 -0
- /package/dist/{lib → src/lib}/providers/base.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/base.js +0 -0
- /package/dist/{lib → src/lib}/providers/copilot.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/copilot.js +0 -0
- /package/dist/{lib → src/lib}/providers/gemini.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/gemini.js +0 -0
- /package/dist/{lib → src/lib}/providers/index.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/index.js +0 -0
- /package/dist/{lib → src/lib}/providers/kilo.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/kilo.js +0 -0
- /package/dist/{lib → src/lib}/providers/opencode.d.ts +0 -0
- /package/dist/{lib → src/lib}/providers/opencode.js +0 -0
- /package/dist/{lib → src/lib}/types/index.d.ts +0 -0
- /package/dist/{lib → src/lib}/types/index.js +0 -0
- /package/dist/{lib → src/lib}/utils/copilot-auth.d.ts +0 -0
- /package/dist/{lib → src/lib}/utils/copilot-auth.js +0 -0
- /package/dist/{lib → src/lib}/utils/models-cache.d.ts +0 -0
- /package/dist/{lib → src/lib}/utils/models-cache.js +0 -0
- /package/dist/{lib → src/lib}/utils/output-writer.d.ts +0 -0
- /package/dist/{lib → src/lib}/utils/output-writer.js +0 -0
- /package/dist/{lib → src/lib}/utils/paths.d.ts +0 -0
- /package/dist/{lib → src/lib}/utils/paths.js +0 -0
- /package/dist/{lib → src/lib}/utils/runtime-logging.d.ts +0 -0
- /package/dist/{lib → src/lib}/utils/runtime-logging.js +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@involvex/prompt-enhancer",
|
|
3
|
+
"description": "A Cli to enhance your prompts",
|
|
4
|
+
"author": "involvex",
|
|
5
|
+
"version": "0.0.8",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"prompt-enhancer": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"funding": {
|
|
12
|
+
"type": "github",
|
|
13
|
+
"url": "https://github.com/sponsors/involvex"
|
|
14
|
+
},
|
|
15
|
+
"sponsor": {
|
|
16
|
+
"url": "https://github.com/sponsors/involvex"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"url": "git+https://github.com/involvex/prompt-enhancer-cli.git",
|
|
20
|
+
"type": "git"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=16"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "bun run src/cli.tsx",
|
|
28
|
+
"format": "prettier --write .",
|
|
29
|
+
"lint": "eslint src",
|
|
30
|
+
"lint:fix": "eslint src --fix",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"prebuild": "bun run format && bun run lint:fix && bun run typecheck",
|
|
33
|
+
"test": "prettier --check . && eslint src && bun test",
|
|
34
|
+
"test:jest": "bun test",
|
|
35
|
+
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
|
36
|
+
"compile": "bun run prebuild && bun build src/cli.tsx --compile --outfile dist/prompt-enhancer.exe",
|
|
37
|
+
"clean": "del-cli dist",
|
|
38
|
+
"release": "bun run clean && powershell -File scripts/release.ps1"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"readme.md",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
".github/FUNDING.yml"
|
|
45
|
+
],
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@google/generative-ai": "^0.24.1",
|
|
48
|
+
"@types/ink": "^0.5.2",
|
|
49
|
+
"@types/meow": "^6.0.0",
|
|
50
|
+
"del-cli": "^7.0.0",
|
|
51
|
+
"has-flag": "^5.0.1",
|
|
52
|
+
"ink": "^5.0.0",
|
|
53
|
+
"ink-select-input": "^6.2.0",
|
|
54
|
+
"ink-text-input": "^6.0.0",
|
|
55
|
+
"meow": "^14.1.0",
|
|
56
|
+
"openai": "^6.27.0",
|
|
57
|
+
"react": "^18.3.1",
|
|
58
|
+
"react-devtools-core": "^7.0.1",
|
|
59
|
+
"react-dom": "^18.3.1",
|
|
60
|
+
"zod": "^4.3.6"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@eslint/js": "latest",
|
|
64
|
+
"@sindresorhus/tsconfig": "^8.1.0",
|
|
65
|
+
"@types/react": "^18.0.32",
|
|
66
|
+
"@vdemedes/prettier-config": "^2.0.1",
|
|
67
|
+
"ava": "^5.2.0",
|
|
68
|
+
"chalk": "^5.2.0",
|
|
69
|
+
"conventional-changelog-cli": "^5.0.0",
|
|
70
|
+
"eslint": "latest",
|
|
71
|
+
"eslint-config-xo-react": "^0.29.0",
|
|
72
|
+
"eslint-plugin-react": "^7.32.2",
|
|
73
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
74
|
+
"ink-testing-library": "^4.0.0",
|
|
75
|
+
"jiti": "latest",
|
|
76
|
+
"prettier": "latest",
|
|
77
|
+
"prettier-plugin-organize-imports": "^4.3.0",
|
|
78
|
+
"prettier-plugin-packagejson": "^3.0.0",
|
|
79
|
+
"prettier-plugin-sort-imports": "^1.8.10",
|
|
80
|
+
"ts-node": "^10.9.1",
|
|
81
|
+
"typescript": "^5.0.3",
|
|
82
|
+
"typescript-eslint": "latest",
|
|
83
|
+
"xo": "^0.53.1",
|
|
84
|
+
"jest": "^29.6.1",
|
|
85
|
+
"ts-jest": "^29.1.0",
|
|
86
|
+
"@types/jest": "^29.5.3",
|
|
87
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
88
|
+
"@testing-library/react": "^14.0.0",
|
|
89
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
90
|
+
"@testing-library/user-event": "^14.4.3"
|
|
91
|
+
},
|
|
92
|
+
"ava": {
|
|
93
|
+
"extensions": {
|
|
94
|
+
"ts": "module",
|
|
95
|
+
"tsx": "module"
|
|
96
|
+
},
|
|
97
|
+
"nodeArguments": [
|
|
98
|
+
"--loader=ts-node/esm"
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"xo": {
|
|
102
|
+
"extends": "xo-react",
|
|
103
|
+
"prettier": true,
|
|
104
|
+
"rules": {
|
|
105
|
+
"react/prop-types": "off"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"prettier": "@vdemedes/prettier-config"
|
|
109
|
+
}
|
package/dist/prompt-enhancer.exe
CHANGED
|
Binary file
|
|
@@ -9,6 +9,7 @@ export default function App({ prompt: _prompt }) {
|
|
|
9
9
|
const [state, setState] = useState('menu');
|
|
10
10
|
const menuItems = [
|
|
11
11
|
{ label: 'Enhance Prompt', value: 'enhance' },
|
|
12
|
+
{ label: '📋 Enhance from clipboard', value: 'enhance-clipboard' },
|
|
12
13
|
{ label: 'Settings', value: 'settings' },
|
|
13
14
|
{ label: 'View History', value: 'history' },
|
|
14
15
|
{ label: 'Help', value: 'help' },
|
|
@@ -26,6 +27,9 @@ export default function App({ prompt: _prompt }) {
|
|
|
26
27
|
if (state === 'enhance') {
|
|
27
28
|
return _jsx(EnhancePromptComponent, { onBack: () => setState('menu') });
|
|
28
29
|
}
|
|
30
|
+
if (state === 'enhance-clipboard') {
|
|
31
|
+
return (_jsx(EnhancePromptComponent, { fromClipboard: true, onBack: () => setState('menu') }));
|
|
32
|
+
}
|
|
29
33
|
if (state === 'settings') {
|
|
30
34
|
return _jsx(SettingsComponent, { onBack: () => setState('menu') });
|
|
31
35
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
|
-
import { Box, Text } from 'ink';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
4
|
import TextInput from 'ink-text-input';
|
|
5
5
|
import SelectInput from './select-input.js';
|
|
6
6
|
import { ConfigManager } from '../lib/config/manager.js';
|
|
7
7
|
import { HistoryManager } from '../lib/history/manager.js';
|
|
8
8
|
import { EnhancementEngine } from '../lib/enhancement/engine.js';
|
|
9
|
-
import { writeToClipboard } from '../lib/utils/clipboard.js';
|
|
9
|
+
import { writeToClipboard, readFromClipboard } from '../lib/utils/clipboard.js';
|
|
10
10
|
const PROVIDERS = ['gemini', 'copilot', 'kilo', 'opencode'];
|
|
11
11
|
const DEFAULT_SYSTEM_PROMPT = 'You are an expert at enhancing and improving user prompts for LLMs. Analyze the given prompt and return an improved version that is clearer, more specific, and more likely to produce better results. Return ONLY the enhanced prompt, no explanations.';
|
|
12
12
|
const PRESETS = {
|
|
@@ -34,8 +34,8 @@ function createPresetSystemPrompt(presetId) {
|
|
|
34
34
|
const preset = PRESETS[presetId];
|
|
35
35
|
return `${DEFAULT_SYSTEM_PROMPT}\n\nAdditional enhancement direction:\n${preset.instruction}\n\nKeep your response as ONLY the improved prompt text.`;
|
|
36
36
|
}
|
|
37
|
-
export default function EnhancePrompt({ onBack }) {
|
|
38
|
-
const [state, setState] = useState('input');
|
|
37
|
+
export default function EnhancePrompt({ onBack, fromClipboard, }) {
|
|
38
|
+
const [state, setState] = useState(fromClipboard ? 'clipboard-loading' : 'input');
|
|
39
39
|
const [prompt, setPrompt] = useState('');
|
|
40
40
|
const [sourcePrompt, setSourcePrompt] = useState('');
|
|
41
41
|
const [enhancedText, setEnhancedText] = useState('');
|
|
@@ -61,6 +61,46 @@ export default function EnhancePrompt({ onBack }) {
|
|
|
61
61
|
}
|
|
62
62
|
})();
|
|
63
63
|
}, []);
|
|
64
|
+
// Read clipboard when launched via "Enhance from clipboard" menu option
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!fromClipboard)
|
|
67
|
+
return;
|
|
68
|
+
(async () => {
|
|
69
|
+
const result = await readFromClipboard();
|
|
70
|
+
if (result.success && result.text) {
|
|
71
|
+
setPrompt(result.text);
|
|
72
|
+
setState('clipboard-preview');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
setError(result.message);
|
|
76
|
+
setState('error');
|
|
77
|
+
}
|
|
78
|
+
})();
|
|
79
|
+
}, [fromClipboard]);
|
|
80
|
+
// Ctrl+V: paste full clipboard content into the prompt input
|
|
81
|
+
useInput((_input, key) => {
|
|
82
|
+
if (key.ctrl && _input === 'v') {
|
|
83
|
+
void (async () => {
|
|
84
|
+
const result = await readFromClipboard();
|
|
85
|
+
if (result.success && result.text) {
|
|
86
|
+
setPrompt(result.text);
|
|
87
|
+
setStatusMessage('📋 Pasted from clipboard');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
setStatusMessage(`Paste failed: ${result.message}`);
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
}
|
|
94
|
+
}, { isActive: state === 'input' });
|
|
95
|
+
// clipboard-preview: Enter to enhance, Esc to cancel
|
|
96
|
+
useInput((_input, key) => {
|
|
97
|
+
if (key.return) {
|
|
98
|
+
void runEnhancement(prompt);
|
|
99
|
+
}
|
|
100
|
+
else if (key.escape) {
|
|
101
|
+
onBack();
|
|
102
|
+
}
|
|
103
|
+
}, { isActive: state === 'clipboard-preview' });
|
|
64
104
|
const handleInputComplete = () => {
|
|
65
105
|
if (!prompt.trim()) {
|
|
66
106
|
setError('Prompt cannot be empty');
|
|
@@ -141,8 +181,17 @@ export default function EnhancePrompt({ onBack }) {
|
|
|
141
181
|
if (loading) {
|
|
142
182
|
return (_jsx(Box, { paddingX: 2, children: _jsx(Text, { color: "yellow", children: "Loading configuration..." }) }));
|
|
143
183
|
}
|
|
184
|
+
if (state === 'clipboard-loading') {
|
|
185
|
+
return (_jsx(Box, { paddingX: 2, children: _jsx(Text, { color: "yellow", children: "\uD83D\uDCCB Reading clipboard..." }) }));
|
|
186
|
+
}
|
|
187
|
+
if (state === 'clipboard-preview') {
|
|
188
|
+
const lines = prompt.split('\n');
|
|
189
|
+
const previewLines = lines.slice(0, 5);
|
|
190
|
+
const truncated = lines.length > 5;
|
|
191
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["\uD83D\uDCCB Clipboard content (", lines.length, " line", lines.length === 1 ? '' : 's', ", ", prompt.length, " char", prompt.length === 1 ? '' : 's', "):"] }), _jsxs(Box, { marginY: 1, flexDirection: "column", children: [previewLines.map((line, i) => (_jsx(Text, { color: "white", children: line || ' ' }, i))), truncated && (_jsxs(Text, { color: "gray", children: ["\u2026 (", lines.length - 5, " more lines)"] }))] }), _jsx(Text, { color: "gray", children: "[Enter] Enhance \u00B7 [Esc] Cancel" })] }));
|
|
192
|
+
}
|
|
144
193
|
if (state === 'input') {
|
|
145
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, color: "cyan", children: "Enter prompt to enhance:" }), _jsxs(Box, { marginY: 1, children: [_jsx(Text, { children: "Prompt: " }), _jsx(TextInput, { value: prompt, onChange: setPrompt, onSubmit: handleInputComplete, placeholder: "Type your prompt here..." })] }), error && _jsxs(Text, { color: "red", children: ["Error: ", error] })] }));
|
|
194
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, color: "cyan", children: "Enter prompt to enhance:" }), _jsxs(Box, { marginY: 1, children: [_jsx(Text, { children: "Prompt: " }), _jsx(TextInput, { value: prompt, onChange: setPrompt, onSubmit: handleInputComplete, placeholder: "Type your prompt here..." })] }), statusMessage && (_jsx(Text, { color: statusMessage.startsWith('📋') ? 'green' : 'red', children: statusMessage })), error && _jsxs(Text, { color: "red", children: ["Error: ", error] }), _jsx(Text, { color: "gray", children: "Tip: Press Ctrl+V to paste from clipboard" })] }));
|
|
146
195
|
}
|
|
147
196
|
if (state === 'enhancing') {
|
|
148
197
|
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Enhancing with ", defaultProvider, "..."] }), _jsx(Box, { marginY: 1, children: _jsx(Text, { children: enhancedText }) }), _jsx(Text, { color: "gray", children: "Streaming response..." })] }));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhancement engine - orchestrates prompt enhancement across providers
|
|
3
3
|
*/
|
|
4
|
-
import { HistoryManager } from '../history/manager.
|
|
5
|
-
import { ConfigManager } from '../config/manager.
|
|
4
|
+
import { HistoryManager } from '../history/manager.ts';
|
|
5
|
+
import { ConfigManager } from '../config/manager.ts';
|
|
6
6
|
export interface EnhancementRequest {
|
|
7
7
|
prompt: string;
|
|
8
8
|
provider?: string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ClipboardResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ClipboardReadResult {
|
|
6
|
+
success: boolean;
|
|
7
|
+
text?: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function writeToClipboard(text: string): Promise<ClipboardResult>;
|
|
11
|
+
export declare function readFromClipboard(): Promise<ClipboardReadResult>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
function runClipboardCommand(command, args, text) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const child = spawn(command, args);
|
|
6
|
+
let stderr = '';
|
|
7
|
+
child.on('error', error => {
|
|
8
|
+
reject(error);
|
|
9
|
+
});
|
|
10
|
+
child.stderr.on('data', chunk => {
|
|
11
|
+
stderr += chunk.toString();
|
|
12
|
+
});
|
|
13
|
+
child.on('close', code => {
|
|
14
|
+
if (code === 0) {
|
|
15
|
+
resolve();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
reject(new Error(stderr.trim() ||
|
|
19
|
+
`Command "${command}" failed with exit code ${code}.`));
|
|
20
|
+
});
|
|
21
|
+
child.stdin.write(text);
|
|
22
|
+
child.stdin.end();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function readClipboardContent(command, args) {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const child = spawn(command, args);
|
|
28
|
+
let stdout = '';
|
|
29
|
+
let stderr = '';
|
|
30
|
+
child.on('error', error => {
|
|
31
|
+
reject(error);
|
|
32
|
+
});
|
|
33
|
+
child.stdout.on('data', (chunk) => {
|
|
34
|
+
stdout += chunk.toString();
|
|
35
|
+
});
|
|
36
|
+
child.stderr.on('data', (chunk) => {
|
|
37
|
+
stderr += chunk.toString();
|
|
38
|
+
});
|
|
39
|
+
child.on('close', code => {
|
|
40
|
+
if (code === 0) {
|
|
41
|
+
resolve(stdout);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
reject(new Error(stderr.trim() ||
|
|
45
|
+
`Command "${command}" failed with exit code ${code}.`));
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function getClipboardCommands() {
|
|
50
|
+
switch (process.platform) {
|
|
51
|
+
case 'win32': {
|
|
52
|
+
return [{ command: 'clip', args: [] }];
|
|
53
|
+
}
|
|
54
|
+
case 'darwin': {
|
|
55
|
+
return [{ command: 'pbcopy', args: [] }];
|
|
56
|
+
}
|
|
57
|
+
default: {
|
|
58
|
+
return [
|
|
59
|
+
{ command: 'xclip', args: ['-selection', 'clipboard'] },
|
|
60
|
+
{ command: 'xsel', args: ['--clipboard', '--input'] },
|
|
61
|
+
{ command: 'wl-copy', args: [] },
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function getReadClipboardCommands() {
|
|
67
|
+
switch (process.platform) {
|
|
68
|
+
case 'win32': {
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
command: 'powershell',
|
|
72
|
+
args: ['-NoProfile', '-NonInteractive', '-Command', 'Get-Clipboard'],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
case 'darwin': {
|
|
77
|
+
return [{ command: 'pbpaste', args: [] }];
|
|
78
|
+
}
|
|
79
|
+
default: {
|
|
80
|
+
return [
|
|
81
|
+
{ command: 'xclip', args: ['-selection', 'clipboard', '-o'] },
|
|
82
|
+
{ command: 'xsel', args: ['--clipboard', '--output'] },
|
|
83
|
+
{ command: 'wl-paste', args: [] },
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export async function writeToClipboard(text) {
|
|
89
|
+
if (!text.trim()) {
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
message: 'Cannot copy an empty enhanced prompt.',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const errors = [];
|
|
96
|
+
const commands = getClipboardCommands();
|
|
97
|
+
for (const clipboardCommand of commands) {
|
|
98
|
+
try {
|
|
99
|
+
await runClipboardCommand(clipboardCommand.command, clipboardCommand.args, text);
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
message: `Copied using ${clipboardCommand.command}.`,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
errors.push(`${clipboardCommand.command}: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
message: errors.length > 0
|
|
112
|
+
? errors.join(' | ')
|
|
113
|
+
: 'No clipboard command is available on this system.',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export async function readFromClipboard() {
|
|
117
|
+
const commands = getReadClipboardCommands();
|
|
118
|
+
const errors = [];
|
|
119
|
+
for (const clipboardCommand of commands) {
|
|
120
|
+
try {
|
|
121
|
+
const text = await readClipboardContent(clipboardCommand.command, clipboardCommand.args);
|
|
122
|
+
// Trim trailing whitespace/newlines that tools like pbpaste add
|
|
123
|
+
const trimmed = text.trimEnd();
|
|
124
|
+
if (!trimmed) {
|
|
125
|
+
return { success: false, message: 'Clipboard is empty.' };
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
text: trimmed,
|
|
130
|
+
message: `Read using ${clipboardCommand.command}.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
errors.push(`${clipboardCommand.command}: ${error instanceof Error ? error.message : String(error)}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
message: errors.length > 0
|
|
140
|
+
? errors.join(' | ')
|
|
141
|
+
: 'No clipboard command is available on this system.',
|
|
142
|
+
};
|
|
143
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@involvex/prompt-enhancer",
|
|
3
3
|
"description": "A Cli to enhance your prompts",
|
|
4
4
|
"author": "involvex",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.8",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
8
8
|
"prompt-enhancer": "dist/cli.js"
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"lint:fix": "eslint src --fix",
|
|
31
31
|
"typecheck": "tsc --noEmit",
|
|
32
32
|
"prebuild": "bun run format && bun run lint:fix && bun run typecheck",
|
|
33
|
-
"test": "prettier --check . &&
|
|
33
|
+
"test": "prettier --check . && eslint src && bun test",
|
|
34
|
+
"test:jest": "bun test",
|
|
34
35
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
|
35
36
|
"compile": "bun run prebuild && bun build src/cli.tsx --compile --outfile dist/prompt-enhancer.exe",
|
|
36
37
|
"clean": "del-cli dist",
|
|
@@ -79,7 +80,14 @@
|
|
|
79
80
|
"ts-node": "^10.9.1",
|
|
80
81
|
"typescript": "^5.0.3",
|
|
81
82
|
"typescript-eslint": "latest",
|
|
82
|
-
"xo": "^0.53.1"
|
|
83
|
+
"xo": "^0.53.1",
|
|
84
|
+
"jest": "^29.6.1",
|
|
85
|
+
"ts-jest": "^29.1.0",
|
|
86
|
+
"@types/jest": "^29.5.3",
|
|
87
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
88
|
+
"@testing-library/react": "^14.0.0",
|
|
89
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
90
|
+
"@testing-library/user-event": "^14.4.3"
|
|
83
91
|
},
|
|
84
92
|
"ava": {
|
|
85
93
|
"extensions": {
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import process from 'node:process';
|
|
3
|
-
function runClipboardCommand(command, args, text) {
|
|
4
|
-
return new Promise((resolve, reject) => {
|
|
5
|
-
const child = spawn(command, args);
|
|
6
|
-
let stderr = '';
|
|
7
|
-
child.on('error', error => {
|
|
8
|
-
reject(error);
|
|
9
|
-
});
|
|
10
|
-
child.stderr.on('data', chunk => {
|
|
11
|
-
stderr += chunk.toString();
|
|
12
|
-
});
|
|
13
|
-
child.on('close', code => {
|
|
14
|
-
if (code === 0) {
|
|
15
|
-
resolve();
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
reject(new Error(stderr.trim() ||
|
|
19
|
-
`Command "${command}" failed with exit code ${code}.`));
|
|
20
|
-
});
|
|
21
|
-
child.stdin.write(text);
|
|
22
|
-
child.stdin.end();
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
function getClipboardCommands() {
|
|
26
|
-
switch (process.platform) {
|
|
27
|
-
case 'win32': {
|
|
28
|
-
return [{ command: 'clip', args: [] }];
|
|
29
|
-
}
|
|
30
|
-
case 'darwin': {
|
|
31
|
-
return [{ command: 'pbcopy', args: [] }];
|
|
32
|
-
}
|
|
33
|
-
default: {
|
|
34
|
-
return [
|
|
35
|
-
{ command: 'xclip', args: ['-selection', 'clipboard'] },
|
|
36
|
-
{ command: 'xsel', args: ['--clipboard', '--input'] },
|
|
37
|
-
{ command: 'wl-copy', args: [] },
|
|
38
|
-
];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export async function writeToClipboard(text) {
|
|
43
|
-
if (!text.trim()) {
|
|
44
|
-
return {
|
|
45
|
-
success: false,
|
|
46
|
-
message: 'Cannot copy an empty enhanced prompt.',
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
const errors = [];
|
|
50
|
-
const commands = getClipboardCommands();
|
|
51
|
-
for (const clipboardCommand of commands) {
|
|
52
|
-
try {
|
|
53
|
-
await runClipboardCommand(clipboardCommand.command, clipboardCommand.args, text);
|
|
54
|
-
return {
|
|
55
|
-
success: true,
|
|
56
|
-
message: `Copied using ${clipboardCommand.command}.`,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
errors.push(`${clipboardCommand.command}: ${error instanceof Error ? error.message : String(error)}`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
success: false,
|
|
65
|
-
message: errors.length > 0
|
|
66
|
-
? errors.join(' | ')
|
|
67
|
-
: 'No clipboard command is available on this system.',
|
|
68
|
-
};
|
|
69
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|