@involvex/prompt-enhancer 0.0.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.
Files changed (60) hide show
  1. package/.github/FUNDING.yml +9 -0
  2. package/LICENSE +21 -0
  3. package/dist/app.d.ts +5 -0
  4. package/dist/app.js +39 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +53 -0
  7. package/dist/commands/about.d.ts +1 -0
  8. package/dist/commands/about.js +6 -0
  9. package/dist/commands/direct-enhance.d.ts +5 -0
  10. package/dist/commands/direct-enhance.js +52 -0
  11. package/dist/commands/enhanceprompt.d.ts +1 -0
  12. package/dist/commands/enhanceprompt.js +6 -0
  13. package/dist/commands/help.d.ts +1 -0
  14. package/dist/commands/help.js +6 -0
  15. package/dist/commands/settings.d.ts +1 -0
  16. package/dist/commands/settings.js +1 -0
  17. package/dist/commands/version.d.ts +1 -0
  18. package/dist/commands/version.js +6 -0
  19. package/dist/components/enhance-prompt.d.ts +5 -0
  20. package/dist/components/enhance-prompt.js +82 -0
  21. package/dist/components/history-viewer.d.ts +5 -0
  22. package/dist/components/history-viewer.js +64 -0
  23. package/dist/components/menu.d.ts +11 -0
  24. package/dist/components/menu.js +6 -0
  25. package/dist/components/select-input.d.ts +19 -0
  26. package/dist/components/select-input.js +51 -0
  27. package/dist/components/settings.d.ts +5 -0
  28. package/dist/components/settings.js +246 -0
  29. package/dist/lib/config/manager.d.ts +49 -0
  30. package/dist/lib/config/manager.js +152 -0
  31. package/dist/lib/config/schema.d.ts +69 -0
  32. package/dist/lib/config/schema.js +37 -0
  33. package/dist/lib/config/types.d.ts +34 -0
  34. package/dist/lib/config/types.js +4 -0
  35. package/dist/lib/enhancement/engine.d.ts +41 -0
  36. package/dist/lib/enhancement/engine.js +163 -0
  37. package/dist/lib/history/manager.d.ts +45 -0
  38. package/dist/lib/history/manager.js +120 -0
  39. package/dist/lib/providers/base.d.ts +47 -0
  40. package/dist/lib/providers/base.js +30 -0
  41. package/dist/lib/providers/copilot.d.ts +18 -0
  42. package/dist/lib/providers/copilot.js +112 -0
  43. package/dist/lib/providers/gemini.d.ts +13 -0
  44. package/dist/lib/providers/gemini.js +86 -0
  45. package/dist/lib/providers/index.d.ts +26 -0
  46. package/dist/lib/providers/index.js +86 -0
  47. package/dist/lib/providers/kilo.d.ts +22 -0
  48. package/dist/lib/providers/kilo.js +174 -0
  49. package/dist/lib/providers/opencode.d.ts +22 -0
  50. package/dist/lib/providers/opencode.js +174 -0
  51. package/dist/lib/types/index.d.ts +26 -0
  52. package/dist/lib/types/index.js +4 -0
  53. package/dist/lib/utils/copilot-auth.d.ts +14 -0
  54. package/dist/lib/utils/copilot-auth.js +84 -0
  55. package/dist/lib/utils/models-cache.d.ts +12 -0
  56. package/dist/lib/utils/models-cache.js +139 -0
  57. package/dist/lib/utils/paths.d.ts +10 -0
  58. package/dist/lib/utils/paths.js +18 -0
  59. package/package.json +101 -0
  60. package/readme.md +271 -0
@@ -0,0 +1,246 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import TextInput from 'ink-text-input';
5
+ import SelectInput from './select-input.js';
6
+ import { ConfigManager } from '../lib/config/manager.js';
7
+ import { getModelsForProvider } from '../lib/utils/models-cache.js';
8
+ function getStep(provider, stepIndex, useOAuth) {
9
+ if (provider === 'copilot') {
10
+ if (stepIndex === 0)
11
+ return 'useOAuth';
12
+ if (stepIndex === 1 && !useOAuth)
13
+ return 'apiKey';
14
+ return 'model';
15
+ }
16
+ return stepIndex === 0 ? 'apiKey' : 'model';
17
+ }
18
+ export default function Settings({ onBack }) {
19
+ const [state, setState] = useState('menu');
20
+ const [selectedProvider, setSelectedProvider] = useState('');
21
+ const [apiKey, setApiKey] = useState('');
22
+ const [modelText, setModelText] = useState('');
23
+ const [useOAuth, setUseOAuth] = useState(false);
24
+ const [stepIndex, setStepIndex] = useState(0);
25
+ const [message, setMessage] = useState('');
26
+ const [config, setConfig] = useState(null);
27
+ const [models, setModels] = useState([]);
28
+ const [modelsLoading, setModelsLoading] = useState(false);
29
+ useEffect(() => {
30
+ (async () => {
31
+ try {
32
+ const mgr = new ConfigManager();
33
+ await mgr.load();
34
+ setConfig(mgr.getConfig());
35
+ }
36
+ catch {
37
+ setMessage('Failed to load configuration');
38
+ }
39
+ })();
40
+ }, []);
41
+ useEffect(() => {
42
+ if (state === 'success') {
43
+ const t = setTimeout(() => onBack(), 2000);
44
+ return () => clearTimeout(t);
45
+ }
46
+ return undefined;
47
+ }, [state, onBack]);
48
+ const loadModels = async (provider, key) => {
49
+ setModelsLoading(true);
50
+ setModels([]);
51
+ try {
52
+ const entries = await getModelsForProvider(provider, key);
53
+ setModels(entries);
54
+ }
55
+ catch {
56
+ setModels([]);
57
+ }
58
+ finally {
59
+ setModelsLoading(false);
60
+ }
61
+ };
62
+ const advanceStep = (nextUseOAuth) => {
63
+ const nextIndex = stepIndex + 1;
64
+ const nextStep = getStep(selectedProvider, nextIndex, nextUseOAuth ?? useOAuth);
65
+ if (nextStep === 'model' && selectedProvider) {
66
+ void loadModels(selectedProvider, selectedProvider === 'opencode' ? apiKey : undefined);
67
+ }
68
+ setStepIndex(nextIndex);
69
+ };
70
+ const saveProvider = async (chosenModel) => {
71
+ try {
72
+ const mgr = new ConfigManager();
73
+ await mgr.load();
74
+ const cfg = mgr.getConfig();
75
+ const entry = {
76
+ name: selectedProvider,
77
+ enabled: true,
78
+ model: chosenModel,
79
+ };
80
+ if (selectedProvider === 'copilot') {
81
+ entry.useOAuth = useOAuth;
82
+ if (!useOAuth && apiKey.trim())
83
+ entry.apiKey = apiKey.trim();
84
+ }
85
+ else if (apiKey.trim()) {
86
+ entry.apiKey = apiKey.trim();
87
+ }
88
+ const updated = {
89
+ ...cfg,
90
+ providers: {
91
+ ...cfg.providers,
92
+ [selectedProvider]: entry,
93
+ },
94
+ };
95
+ await mgr.setConfig(updated);
96
+ setConfig(updated);
97
+ setMessage(`✓ ${selectedProvider} configured successfully!`);
98
+ setState('success');
99
+ }
100
+ catch (err) {
101
+ setMessage(`Error: ${err instanceof Error ? err.message : String(err)}`);
102
+ setState('error');
103
+ }
104
+ };
105
+ const saveDefaultProvider = async (provider) => {
106
+ try {
107
+ const mgr = new ConfigManager();
108
+ await mgr.load();
109
+ const cfg = mgr.getConfig();
110
+ const updated = { ...cfg, defaultProvider: provider };
111
+ await mgr.setConfig(updated);
112
+ setConfig(updated);
113
+ setMessage(`✓ Default provider set to ${provider}`);
114
+ setState('success');
115
+ }
116
+ catch (err) {
117
+ setMessage(`Error: ${err instanceof Error ? err.message : String(err)}`);
118
+ setState('error');
119
+ }
120
+ };
121
+ const saveDefaultModel = async (model) => {
122
+ try {
123
+ const mgr = new ConfigManager();
124
+ await mgr.load();
125
+ const cfg = mgr.getConfig();
126
+ const updated = { ...cfg, defaultModel: model };
127
+ await mgr.setConfig(updated);
128
+ setConfig(updated);
129
+ setMessage(`✓ Default model set to ${model}`);
130
+ setState('success');
131
+ }
132
+ catch (err) {
133
+ setMessage(`Error: ${err instanceof Error ? err.message : String(err)}`);
134
+ setState('error');
135
+ }
136
+ };
137
+ const providers = ['gemini', 'copilot', 'kilo', 'opencode'];
138
+ const menuItems = [
139
+ ...providers.map(p => ({ label: `Configure ${p}`, value: p })),
140
+ { label: 'Set Default Provider', value: '__default-provider__' },
141
+ { label: 'Set Default Model', value: '__default-model__' },
142
+ { label: 'Back', value: '__back__' },
143
+ ];
144
+ if (state === 'menu') {
145
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, color: "cyan", children: "\u2699 Settings" }), config && (_jsxs(Text, { color: "gray", children: ["default: ", config.defaultProvider ?? 'kilo', " /", ' ', config.defaultModel ?? 'minimax/minimax-m2.5'] })), _jsx(Box, { marginY: 1, children: _jsx(SelectInput, { items: menuItems, onSelect: item => {
146
+ if (item.value === '__back__') {
147
+ onBack();
148
+ }
149
+ else if (item.value === '__default-provider__') {
150
+ setState('set-default-provider');
151
+ }
152
+ else if (item.value === '__default-model__') {
153
+ const p = config?.defaultProvider ?? 'kilo';
154
+ void loadModels(p);
155
+ setState('set-default-model');
156
+ }
157
+ else {
158
+ setSelectedProvider(item.value);
159
+ setApiKey('');
160
+ setModelText('');
161
+ setUseOAuth(false);
162
+ setStepIndex(0);
163
+ setModels([]);
164
+ setMessage('');
165
+ setState('configure-provider');
166
+ }
167
+ } }) })] }));
168
+ }
169
+ if (state === 'set-default-provider') {
170
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, color: "cyan", children: "Set Default Provider" }), _jsx(Box, { marginY: 1, children: _jsx(SelectInput, { items: providers.map(p => ({ label: p, value: p })), onSelect: item => void saveDefaultProvider(item.value) }) })] }));
171
+ }
172
+ if (state === 'set-default-model') {
173
+ const defaultProvider = config?.defaultProvider ?? 'kilo';
174
+ if (modelsLoading) {
175
+ return (_jsx(Box, { paddingX: 2, children: _jsxs(Text, { color: "yellow", children: ["Loading models for ", defaultProvider, "\u2026"] }) }));
176
+ }
177
+ if (models.length === 0) {
178
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Set Default Model (", defaultProvider, ")"] }), _jsxs(Box, { marginY: 1, children: [_jsx(Text, { children: "Model ID: " }), _jsx(TextInput, { value: modelText, onChange: setModelText, onSubmit: () => {
179
+ if (modelText.trim())
180
+ void saveDefaultModel(modelText.trim());
181
+ }, placeholder: "Enter model ID\u2026" })] })] }));
182
+ }
183
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Set Default Model (", defaultProvider, ")"] }), _jsx(Box, { marginY: 1, children: _jsx(SelectInput, { items: models.map(m => ({
184
+ label: `${m.name} (${m.id})`,
185
+ value: m.id,
186
+ })), onSelect: item => void saveDefaultModel(item.value) }) })] }));
187
+ }
188
+ if (state === 'configure-provider') {
189
+ const step = getStep(selectedProvider, stepIndex, useOAuth);
190
+ if (step === 'useOAuth') {
191
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { bold: true, color: "cyan", children: "Configure copilot \u2014 Authentication" }), _jsx(Box, { marginY: 1, children: _jsx(SelectInput, { items: [
192
+ {
193
+ label: 'Auto-detect token from ~/.copilot/ (recommended)',
194
+ value: 'auto',
195
+ },
196
+ { label: 'Enter API key manually', value: 'manual' },
197
+ ], onSelect: item => {
198
+ const auto = item.value === 'auto';
199
+ setUseOAuth(auto);
200
+ advanceStep(auto);
201
+ } }) })] }));
202
+ }
203
+ if (step === 'apiKey') {
204
+ const isRequired = selectedProvider === 'gemini' || selectedProvider === 'opencode';
205
+ const hint = selectedProvider === 'kilo'
206
+ ? 'Free models still need an API key — get one at https://app.kilo.ai'
207
+ : selectedProvider === 'copilot'
208
+ ? 'Enter your GitHub Copilot API key'
209
+ : selectedProvider === 'opencode'
210
+ ? 'Enter your OpenCode API key — get one at https://opencode.ai'
211
+ : undefined;
212
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Configure ", selectedProvider] }), hint && (_jsx(Text, { color: "gray", dimColor: true, children: hint })), _jsxs(Box, { marginY: 1, children: [_jsxs(Text, { children: ["API Key", isRequired ? '' : ' (optional)', ": "] }), _jsx(TextInput, { value: apiKey, onChange: setApiKey, onSubmit: () => {
213
+ if (isRequired && !apiKey.trim()) {
214
+ setMessage(`API key is required for ${selectedProvider}`);
215
+ return;
216
+ }
217
+ setMessage('');
218
+ advanceStep();
219
+ }, placeholder: selectedProvider === 'kilo'
220
+ ? 'Skip or enter key…'
221
+ : 'Enter API key…', mask: "*" })] }), message && _jsx(Text, { color: "red", children: message })] }));
222
+ }
223
+ if (step === 'model') {
224
+ if (modelsLoading) {
225
+ return (_jsx(Box, { paddingX: 2, children: _jsxs(Text, { color: "yellow", children: ["Loading models for ", selectedProvider, "\u2026"] }) }));
226
+ }
227
+ if (models.length === 0) {
228
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Configure ", selectedProvider, " \u2014 Model"] }), _jsxs(Box, { marginY: 1, children: [_jsx(Text, { children: "Model ID: " }), _jsx(TextInput, { value: modelText, onChange: setModelText, onSubmit: () => {
229
+ if (modelText.trim())
230
+ void saveProvider(modelText.trim());
231
+ }, placeholder: "Enter model ID\u2026" })] })] }));
232
+ }
233
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Configure ", selectedProvider, " \u2014 Choose Model"] }), _jsx(Box, { marginY: 1, children: _jsx(SelectInput, { items: models.map(m => ({
234
+ label: `${m.name} (${m.id})`,
235
+ value: m.id,
236
+ })), onSelect: item => void saveProvider(item.value) }) })] }));
237
+ }
238
+ }
239
+ if (state === 'success') {
240
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { color: "green", children: message }), _jsx(Text, {}), _jsx(Text, { color: "gray", children: "(returning to menu\u2026)" })] }));
241
+ }
242
+ if (state === 'error') {
243
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsx(Text, { color: "red", children: message }), _jsx(Text, {}), _jsx(Text, { color: "gray", children: "(Press Ctrl+C to exit)" })] }));
244
+ }
245
+ return null;
246
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Configuration manager for reading and writing app config
3
+ */
4
+ import type { AppConfig } from './schema.js';
5
+ export declare class ConfigManager {
6
+ private config;
7
+ private configPath;
8
+ constructor(configPath?: string);
9
+ /**
10
+ * Load config from file, creating it if it doesn't exist
11
+ */
12
+ load(): Promise<AppConfig>;
13
+ /**
14
+ * Save current config to file
15
+ */
16
+ save(): Promise<void>;
17
+ /**
18
+ * Get the current config object
19
+ */
20
+ getConfig(): AppConfig;
21
+ /**
22
+ * Set the entire config object (and save)
23
+ */
24
+ setConfig(config: AppConfig): Promise<void>;
25
+ /**
26
+ * Update a specific setting
27
+ */
28
+ setSetting<K extends keyof AppConfig>(key: K, value: AppConfig[K]): void;
29
+ /**
30
+ * Get a specific setting
31
+ */
32
+ getSetting<K extends keyof AppConfig>(key: K): AppConfig[K];
33
+ /**
34
+ * Update provider config
35
+ */
36
+ setProvider(providerName: string, config: Partial<AppConfig['providers'][string]>): void;
37
+ /**
38
+ * Get provider config
39
+ */
40
+ getProvider(providerName: string): AppConfig['providers'][string] | undefined;
41
+ /**
42
+ * Get all enabled providers
43
+ */
44
+ getEnabledProviders(): string[];
45
+ /**
46
+ * Reset config to defaults
47
+ */
48
+ reset(): Promise<void>;
49
+ }
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Configuration manager for reading and writing app config
3
+ */
4
+ import { readFile, writeFile, mkdir } from 'fs/promises';
5
+ import { existsSync } from 'fs';
6
+ import { AppConfigSchema } from './schema.js';
7
+ import { CONFIG_DIR, CONFIG_FILE } from '../utils/paths.js';
8
+ import { KILO_DEFAULT_ENDPOINT, KILO_DEFAULT_MODEL } from '../providers/kilo.js';
9
+ import { OPENCODE_CHAT_ENDPOINT } from '../providers/opencode.js';
10
+ const DEFAULT_CONFIG = {
11
+ version: '1.0.0',
12
+ defaultProvider: 'kilo',
13
+ defaultModel: KILO_DEFAULT_MODEL,
14
+ streaming: true,
15
+ saveHistory: true,
16
+ providers: {
17
+ gemini: {
18
+ name: 'gemini',
19
+ enabled: false,
20
+ },
21
+ copilot: {
22
+ name: 'copilot',
23
+ enabled: false,
24
+ },
25
+ kilo: {
26
+ name: 'kilo',
27
+ enabled: true,
28
+ endpoint: KILO_DEFAULT_ENDPOINT,
29
+ },
30
+ opencode: {
31
+ name: 'opencode',
32
+ enabled: false,
33
+ endpoint: OPENCODE_CHAT_ENDPOINT,
34
+ },
35
+ },
36
+ temperature: 0.7,
37
+ maxTokens: 1000,
38
+ theme: 'dark',
39
+ };
40
+ export class ConfigManager {
41
+ config;
42
+ configPath;
43
+ constructor(configPath) {
44
+ this.configPath = configPath || CONFIG_FILE;
45
+ this.config = structuredClone(DEFAULT_CONFIG);
46
+ }
47
+ /**
48
+ * Load config from file, creating it if it doesn't exist
49
+ */
50
+ async load() {
51
+ try {
52
+ // Ensure config directory exists
53
+ if (!existsSync(CONFIG_DIR)) {
54
+ await mkdir(CONFIG_DIR, { recursive: true });
55
+ }
56
+ // If config file doesn't exist, create it with defaults
57
+ if (!existsSync(this.configPath)) {
58
+ await this.save();
59
+ return this.config;
60
+ }
61
+ // Read and parse config file
62
+ const content = await readFile(this.configPath, 'utf-8');
63
+ const parsed = JSON.parse(content);
64
+ // Validate using schema
65
+ const validated = AppConfigSchema.parse(parsed);
66
+ this.config = validated;
67
+ return this.config;
68
+ }
69
+ catch (error) {
70
+ console.error('Failed to load config:', error);
71
+ throw error;
72
+ }
73
+ }
74
+ /**
75
+ * Save current config to file
76
+ */
77
+ async save() {
78
+ try {
79
+ // Ensure directory exists
80
+ if (!existsSync(CONFIG_DIR)) {
81
+ await mkdir(CONFIG_DIR, { recursive: true });
82
+ }
83
+ // Write config file
84
+ await writeFile(this.configPath, JSON.stringify(this.config, null, 2), 'utf-8');
85
+ }
86
+ catch (error) {
87
+ console.error('Failed to save config:', error);
88
+ throw error;
89
+ }
90
+ }
91
+ /**
92
+ * Get the current config object
93
+ */
94
+ getConfig() {
95
+ return this.config;
96
+ }
97
+ /**
98
+ * Set the entire config object (and save)
99
+ */
100
+ async setConfig(config) {
101
+ this.config = config;
102
+ await this.save();
103
+ }
104
+ /**
105
+ * Update a specific setting
106
+ */
107
+ setSetting(key, value) {
108
+ this.config[key] = value;
109
+ }
110
+ /**
111
+ * Get a specific setting
112
+ */
113
+ getSetting(key) {
114
+ return this.config[key];
115
+ }
116
+ /**
117
+ * Update provider config
118
+ */
119
+ setProvider(providerName, config) {
120
+ if (!this.config.providers[providerName]) {
121
+ this.config.providers[providerName] = {
122
+ name: providerName,
123
+ enabled: false,
124
+ };
125
+ }
126
+ this.config.providers[providerName] = {
127
+ ...this.config.providers[providerName],
128
+ ...config,
129
+ };
130
+ }
131
+ /**
132
+ * Get provider config
133
+ */
134
+ getProvider(providerName) {
135
+ return this.config.providers[providerName];
136
+ }
137
+ /**
138
+ * Get all enabled providers
139
+ */
140
+ getEnabledProviders() {
141
+ return Object.entries(this.config.providers)
142
+ .filter(([, config]) => config.enabled)
143
+ .map(([name]) => name);
144
+ }
145
+ /**
146
+ * Reset config to defaults
147
+ */
148
+ async reset() {
149
+ this.config = structuredClone(DEFAULT_CONFIG);
150
+ await this.save();
151
+ }
152
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Zod schemas for configuration validation
3
+ */
4
+ import { z } from 'zod';
5
+ export declare const ProviderConfigSchema: z.ZodObject<{
6
+ name: z.ZodEnum<{
7
+ gemini: "gemini";
8
+ copilot: "copilot";
9
+ kilo: "kilo";
10
+ opencode: "opencode";
11
+ }>;
12
+ apiKey: z.ZodOptional<z.ZodString>;
13
+ model: z.ZodOptional<z.ZodString>;
14
+ endpoint: z.ZodOptional<z.ZodString>;
15
+ enabled: z.ZodBoolean;
16
+ useOAuth: z.ZodOptional<z.ZodBoolean>;
17
+ }, z.core.$strip>;
18
+ export declare const AppConfigSchema: z.ZodObject<{
19
+ version: z.ZodString;
20
+ defaultProvider: z.ZodString;
21
+ defaultModel: z.ZodOptional<z.ZodString>;
22
+ streaming: z.ZodBoolean;
23
+ saveHistory: z.ZodBoolean;
24
+ providers: z.ZodRecord<z.ZodString, z.ZodObject<{
25
+ name: z.ZodEnum<{
26
+ gemini: "gemini";
27
+ copilot: "copilot";
28
+ kilo: "kilo";
29
+ opencode: "opencode";
30
+ }>;
31
+ apiKey: z.ZodOptional<z.ZodString>;
32
+ model: z.ZodOptional<z.ZodString>;
33
+ endpoint: z.ZodOptional<z.ZodString>;
34
+ enabled: z.ZodBoolean;
35
+ useOAuth: z.ZodOptional<z.ZodBoolean>;
36
+ }, z.core.$strip>>;
37
+ theme: z.ZodOptional<z.ZodEnum<{
38
+ dark: "dark";
39
+ light: "light";
40
+ }>>;
41
+ temperature: z.ZodOptional<z.ZodNumber>;
42
+ maxTokens: z.ZodOptional<z.ZodNumber>;
43
+ }, z.core.$strip>;
44
+ export declare const HistoryEntrySchema: z.ZodObject<{
45
+ id: z.ZodString;
46
+ timestamp: z.ZodNumber;
47
+ originalPrompt: z.ZodString;
48
+ enhancedPrompt: z.ZodString;
49
+ provider: z.ZodString;
50
+ model: z.ZodString;
51
+ temperature: z.ZodOptional<z.ZodNumber>;
52
+ tokens: z.ZodOptional<z.ZodNumber>;
53
+ }, z.core.$strip>;
54
+ export declare const HistoryDataSchema: z.ZodObject<{
55
+ entries: z.ZodArray<z.ZodObject<{
56
+ id: z.ZodString;
57
+ timestamp: z.ZodNumber;
58
+ originalPrompt: z.ZodString;
59
+ enhancedPrompt: z.ZodString;
60
+ provider: z.ZodString;
61
+ model: z.ZodString;
62
+ temperature: z.ZodOptional<z.ZodNumber>;
63
+ tokens: z.ZodOptional<z.ZodNumber>;
64
+ }, z.core.$strip>>;
65
+ version: z.ZodString;
66
+ }, z.core.$strip>;
67
+ export type AppConfig = z.infer<typeof AppConfigSchema>;
68
+ export type HistoryEntry = z.infer<typeof HistoryEntrySchema>;
69
+ export type HistoryData = z.infer<typeof HistoryDataSchema>;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Zod schemas for configuration validation
3
+ */
4
+ import { z } from 'zod';
5
+ export const ProviderConfigSchema = z.object({
6
+ name: z.enum(['gemini', 'copilot', 'kilo', 'opencode']),
7
+ apiKey: z.string().optional(),
8
+ model: z.string().optional(),
9
+ endpoint: z.string().url().optional(),
10
+ enabled: z.boolean(),
11
+ useOAuth: z.boolean().optional(),
12
+ });
13
+ export const AppConfigSchema = z.object({
14
+ version: z.string(),
15
+ defaultProvider: z.string(),
16
+ defaultModel: z.string().optional(),
17
+ streaming: z.boolean(),
18
+ saveHistory: z.boolean(),
19
+ providers: z.record(z.string(), ProviderConfigSchema),
20
+ theme: z.enum(['dark', 'light']).optional(),
21
+ temperature: z.number().min(0).max(2).optional(),
22
+ maxTokens: z.number().min(1).optional(),
23
+ });
24
+ export const HistoryEntrySchema = z.object({
25
+ id: z.string(),
26
+ timestamp: z.number(),
27
+ originalPrompt: z.string(),
28
+ enhancedPrompt: z.string(),
29
+ provider: z.string(),
30
+ model: z.string(),
31
+ temperature: z.number().optional(),
32
+ tokens: z.number().optional(),
33
+ });
34
+ export const HistoryDataSchema = z.object({
35
+ entries: z.array(HistoryEntrySchema),
36
+ version: z.string(),
37
+ });
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Configuration types for prompt-enhancer
3
+ */
4
+ export interface ProviderConfig {
5
+ name: string;
6
+ apiKey?: string;
7
+ endpoint?: string;
8
+ enabled: boolean;
9
+ }
10
+ export interface AppConfig {
11
+ version: string;
12
+ defaultProvider: string;
13
+ defaultModel?: string;
14
+ streaming: boolean;
15
+ saveHistory: boolean;
16
+ providers: Record<string, ProviderConfig>;
17
+ theme?: 'dark' | 'light';
18
+ temperature?: number;
19
+ maxTokens?: number;
20
+ }
21
+ export interface HistoryEntry {
22
+ id: string;
23
+ timestamp: number;
24
+ originalPrompt: string;
25
+ enhancedPrompt: string;
26
+ provider: string;
27
+ model: string;
28
+ temperature?: number;
29
+ tokens?: number;
30
+ }
31
+ export interface HistoryData {
32
+ entries: HistoryEntry[];
33
+ version: string;
34
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Configuration types for prompt-enhancer
3
+ */
4
+ export {};
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Enhancement engine - orchestrates prompt enhancement across providers
3
+ */
4
+ import { HistoryManager } from '../history/manager.js';
5
+ import { ConfigManager } from '../config/manager.js';
6
+ export interface EnhancementRequest {
7
+ prompt: string;
8
+ provider?: string;
9
+ model?: string;
10
+ temperature?: number;
11
+ maxTokens?: number;
12
+ saveToHistory?: boolean;
13
+ }
14
+ export interface EnhancementResponse {
15
+ originalPrompt: string;
16
+ enhancedPrompt: string;
17
+ provider: string;
18
+ model: string;
19
+ duration: number;
20
+ }
21
+ export declare class EnhancementEngine {
22
+ private configManager;
23
+ private historyManager;
24
+ constructor(configManager: ConfigManager, historyManager: HistoryManager);
25
+ /**
26
+ * Enhance a prompt using the specified (or default) provider
27
+ */
28
+ enhance(request: EnhancementRequest): Promise<EnhancementResponse>;
29
+ /**
30
+ * Enhance a prompt with streaming output
31
+ */
32
+ enhanceStream(request: EnhancementRequest): AsyncGenerator<string, EnhancementResponse>;
33
+ /**
34
+ * Get available models for a provider
35
+ */
36
+ getAvailableModels(providerName?: string): Promise<Record<string, string[]>>;
37
+ /**
38
+ * Validate provider credentials
39
+ */
40
+ validateProvider(providerName: string): Promise<boolean>;
41
+ }