@projectarachne/cli 0.1.0-beta.1
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/LICENSE +75 -0
- package/README.md +40 -0
- package/bin/arachne +2 -0
- package/bin/arachne.js +2 -0
- package/dist/arachne.d.ts +3 -0
- package/dist/arachne.d.ts.map +1 -0
- package/dist/arachne.js +4 -0
- package/dist/arachne.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -0
- package/dist/serve.d.ts +6 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +83 -0
- package/dist/serve.js.map +1 -0
- package/dist/templates.d.ts +3 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +22 -0
- package/dist/templates.js.map +1 -0
- package/dist/tui/App.d.ts +2 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +1078 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/Box.d.ts +19 -0
- package/dist/tui/components/Box.d.ts.map +1 -0
- package/dist/tui/components/Box.js +9 -0
- package/dist/tui/components/Box.js.map +1 -0
- package/dist/tui/components/ChatInput.d.ts +12 -0
- package/dist/tui/components/ChatInput.d.ts.map +1 -0
- package/dist/tui/components/ChatInput.js +10 -0
- package/dist/tui/components/ChatInput.js.map +1 -0
- package/dist/tui/components/CommandInput.d.ts +15 -0
- package/dist/tui/components/CommandInput.d.ts.map +1 -0
- package/dist/tui/components/CommandInput.js +92 -0
- package/dist/tui/components/CommandInput.js.map +1 -0
- package/dist/tui/components/Content.d.ts +18 -0
- package/dist/tui/components/Content.d.ts.map +1 -0
- package/dist/tui/components/Content.js +22 -0
- package/dist/tui/components/Content.js.map +1 -0
- package/dist/tui/components/DagView.d.ts +8 -0
- package/dist/tui/components/DagView.d.ts.map +1 -0
- package/dist/tui/components/DagView.js +49 -0
- package/dist/tui/components/DagView.js.map +1 -0
- package/dist/tui/components/Footer.d.ts +9 -0
- package/dist/tui/components/Footer.d.ts.map +1 -0
- package/dist/tui/components/Footer.js +6 -0
- package/dist/tui/components/Footer.js.map +1 -0
- package/dist/tui/components/Frame.d.ts +6 -0
- package/dist/tui/components/Frame.d.ts.map +1 -0
- package/dist/tui/components/Frame.js +10 -0
- package/dist/tui/components/Frame.js.map +1 -0
- package/dist/tui/components/GoalInput.d.ts +10 -0
- package/dist/tui/components/GoalInput.d.ts.map +1 -0
- package/dist/tui/components/GoalInput.js +8 -0
- package/dist/tui/components/GoalInput.js.map +1 -0
- package/dist/tui/components/Header.d.ts +8 -0
- package/dist/tui/components/Header.d.ts.map +1 -0
- package/dist/tui/components/Header.js +8 -0
- package/dist/tui/components/Header.js.map +1 -0
- package/dist/tui/components/Help.d.ts +6 -0
- package/dist/tui/components/Help.d.ts.map +1 -0
- package/dist/tui/components/Help.js +8 -0
- package/dist/tui/components/Help.js.map +1 -0
- package/dist/tui/components/HomeView.d.ts +2 -0
- package/dist/tui/components/HomeView.d.ts.map +1 -0
- package/dist/tui/components/HomeView.js +8 -0
- package/dist/tui/components/HomeView.js.map +1 -0
- package/dist/tui/components/OutputView.d.ts +9 -0
- package/dist/tui/components/OutputView.d.ts.map +1 -0
- package/dist/tui/components/OutputView.js +40 -0
- package/dist/tui/components/OutputView.js.map +1 -0
- package/dist/tui/components/PlannerView.d.ts +17 -0
- package/dist/tui/components/PlannerView.d.ts.map +1 -0
- package/dist/tui/components/PlannerView.js +62 -0
- package/dist/tui/components/PlannerView.js.map +1 -0
- package/dist/tui/components/Settings.d.ts +6 -0
- package/dist/tui/components/Settings.d.ts.map +1 -0
- package/dist/tui/components/Settings.js +210 -0
- package/dist/tui/components/Settings.js.map +1 -0
- package/dist/tui/components/Sidebar.d.ts +12 -0
- package/dist/tui/components/Sidebar.d.ts.map +1 -0
- package/dist/tui/components/Sidebar.js +9 -0
- package/dist/tui/components/Sidebar.js.map +1 -0
- package/dist/tui/components/Splash.d.ts +7 -0
- package/dist/tui/components/Splash.d.ts.map +1 -0
- package/dist/tui/components/Splash.js +56 -0
- package/dist/tui/components/Splash.js.map +1 -0
- package/dist/tui/components/StepEditor.d.ts +13 -0
- package/dist/tui/components/StepEditor.d.ts.map +1 -0
- package/dist/tui/components/StepEditor.js +33 -0
- package/dist/tui/components/StepEditor.js.map +1 -0
- package/dist/tui/components/ThemeDesigner.d.ts +9 -0
- package/dist/tui/components/ThemeDesigner.d.ts.map +1 -0
- package/dist/tui/components/ThemeDesigner.js +45 -0
- package/dist/tui/components/ThemeDesigner.js.map +1 -0
- package/dist/tui/components/WorkflowPicker.d.ts +8 -0
- package/dist/tui/components/WorkflowPicker.d.ts.map +1 -0
- package/dist/tui/components/WorkflowPicker.js +11 -0
- package/dist/tui/components/WorkflowPicker.js.map +1 -0
- package/dist/tui/components/index.d.ts +20 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +20 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +7 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/services/context.d.ts +11 -0
- package/dist/tui/services/context.d.ts.map +1 -0
- package/dist/tui/services/context.js +134 -0
- package/dist/tui/services/context.js.map +1 -0
- package/dist/tui/services/executor.d.ts +13 -0
- package/dist/tui/services/executor.d.ts.map +1 -0
- package/dist/tui/services/executor.js +186 -0
- package/dist/tui/services/executor.js.map +1 -0
- package/dist/tui/services/generateSteps.d.ts +7 -0
- package/dist/tui/services/generateSteps.d.ts.map +1 -0
- package/dist/tui/services/generateSteps.js +238 -0
- package/dist/tui/services/generateSteps.js.map +1 -0
- package/dist/tui/services/providers.d.ts +16 -0
- package/dist/tui/services/providers.d.ts.map +1 -0
- package/dist/tui/services/providers.js +246 -0
- package/dist/tui/services/providers.js.map +1 -0
- package/dist/tui/services/settings.d.ts +29 -0
- package/dist/tui/services/settings.d.ts.map +1 -0
- package/dist/tui/services/settings.js +107 -0
- package/dist/tui/services/settings.js.map +1 -0
- package/dist/tui/services/theme.d.ts +45 -0
- package/dist/tui/services/theme.d.ts.map +1 -0
- package/dist/tui/services/theme.js +205 -0
- package/dist/tui/services/theme.js.map +1 -0
- package/dist/tui/services/themeGenerator.d.ts +4 -0
- package/dist/tui/services/themeGenerator.d.ts.map +1 -0
- package/dist/tui/services/themeGenerator.js +93 -0
- package/dist/tui/services/themeGenerator.js.map +1 -0
- package/dist/tui/services/user.d.ts +3 -0
- package/dist/tui/services/user.d.ts.map +1 -0
- package/dist/tui/services/user.js +40 -0
- package/dist/tui/services/user.js.map +1 -0
- package/dist/tui/theme-context.d.ts +4 -0
- package/dist/tui/theme-context.d.ts.map +1 -0
- package/dist/tui/theme-context.js +6 -0
- package/dist/tui/theme-context.js.map +1 -0
- package/dist/tui/types.d.ts +81 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +3 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/tui.d.ts +2 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +241 -0
- package/dist/tui.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
const PLANNER_PROMPT = `You are a workflow planner for an AI coding assistant. Given a goal and project context, break it down into discrete steps that will be executed by AI agents with FULL FILESYSTEM ACCESS.
|
|
3
|
+
|
|
4
|
+
Each step will be executed by an AI agent (claude/codex/gemini) that can:
|
|
5
|
+
- Read any file in the project
|
|
6
|
+
- Create new files
|
|
7
|
+
- Modify existing files
|
|
8
|
+
- Run shell commands
|
|
9
|
+
- Install dependencies
|
|
10
|
+
|
|
11
|
+
Generate steps that are:
|
|
12
|
+
1. Specific and actionable (reference actual file paths)
|
|
13
|
+
2. Ordered correctly (dependencies first)
|
|
14
|
+
3. Self-contained (each step should complete one task)
|
|
15
|
+
|
|
16
|
+
Respond with ONLY a JSON array, no markdown, no explanation:
|
|
17
|
+
[
|
|
18
|
+
{"id": "step_1", "provider": "codex", "title": "Short title", "prompt": "Detailed instruction..."},
|
|
19
|
+
{"id": "step_2", "provider": "codex", "title": "Short title", "prompt": "..."},
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
Use providers appropriately:
|
|
23
|
+
- codex: Code generation, file modifications, running commands (PREFERRED for coding tasks)
|
|
24
|
+
- claude: Analysis, planning, documentation, complex reasoning
|
|
25
|
+
- gemini: Multi-modal tasks, alternative to claude
|
|
26
|
+
|
|
27
|
+
PROJECT CONTEXT:
|
|
28
|
+
`;
|
|
29
|
+
const PHASED_PLANNER_PROMPT = `You are a workflow planner for an AI coding assistant. Given a goal and project context, break it down into PHASES with concrete steps for each phase.
|
|
30
|
+
|
|
31
|
+
Each step will be executed by an AI agent (claude/codex/gemini) that can:
|
|
32
|
+
- Read any file in the project
|
|
33
|
+
- Create new files
|
|
34
|
+
- Modify existing files
|
|
35
|
+
- Run shell commands
|
|
36
|
+
- Install dependencies
|
|
37
|
+
|
|
38
|
+
Return ONLY JSON (no markdown) in this exact shape:
|
|
39
|
+
{
|
|
40
|
+
"phases": [
|
|
41
|
+
{
|
|
42
|
+
"id": "phase_1",
|
|
43
|
+
"title": "Phase title",
|
|
44
|
+
"steps": [
|
|
45
|
+
{ "id": "step_1", "provider": "codex", "title": "Short title", "prompt": "Detailed instruction..." }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Rules:
|
|
52
|
+
- 2-5 phases max
|
|
53
|
+
- 2-6 steps per phase
|
|
54
|
+
- Steps must be actionable and reference real files where possible
|
|
55
|
+
- Use providers appropriately: codex for coding, claude for analysis/planning
|
|
56
|
+
|
|
57
|
+
PROJECT CONTEXT:
|
|
58
|
+
`;
|
|
59
|
+
export const generateStepsFromGoal = async (goal, context, provider = 'claude', onStatus, onStream) => {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
onStatus?.('Analyzing project...');
|
|
62
|
+
const fullPrompt = PLANNER_PROMPT + context.summary + '\n\nGOAL: ' + goal;
|
|
63
|
+
let command;
|
|
64
|
+
let args;
|
|
65
|
+
switch (provider) {
|
|
66
|
+
case 'codex':
|
|
67
|
+
command = 'codex';
|
|
68
|
+
args = ['exec', '--skip-git-repo-check', fullPrompt];
|
|
69
|
+
break;
|
|
70
|
+
case 'gemini':
|
|
71
|
+
command = 'gemini';
|
|
72
|
+
args = [fullPrompt]; // positional prompt
|
|
73
|
+
break;
|
|
74
|
+
case 'claude':
|
|
75
|
+
default:
|
|
76
|
+
command = 'claude';
|
|
77
|
+
args = ['-p', fullPrompt, '--output-format', 'text'];
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
onStatus?.(`Planning with ${provider}...`);
|
|
81
|
+
const child = spawn(command, args, {
|
|
82
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
83
|
+
cwd: context.workingDir,
|
|
84
|
+
});
|
|
85
|
+
let stdout = '';
|
|
86
|
+
let stderr = '';
|
|
87
|
+
child.stdout.on('data', (data) => {
|
|
88
|
+
const chunk = data.toString();
|
|
89
|
+
stdout += chunk;
|
|
90
|
+
onStream?.(chunk, 'stdout');
|
|
91
|
+
onStatus?.('Generating steps...');
|
|
92
|
+
});
|
|
93
|
+
child.stderr.on('data', (data) => {
|
|
94
|
+
const chunk = data.toString();
|
|
95
|
+
stderr += chunk;
|
|
96
|
+
onStream?.(chunk, 'stderr');
|
|
97
|
+
});
|
|
98
|
+
child.on('close', (code) => {
|
|
99
|
+
if (code !== 0) {
|
|
100
|
+
reject(new Error(`${provider} failed: ${stderr || 'Unknown error'}`));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
onStatus?.('Parsing response...');
|
|
104
|
+
try {
|
|
105
|
+
// Try to extract JSON array from response
|
|
106
|
+
const jsonMatch = stdout.match(/\[[\s\S]*\]/);
|
|
107
|
+
if (!jsonMatch) {
|
|
108
|
+
reject(new Error('No valid JSON array in response'));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
112
|
+
if (!Array.isArray(parsed)) {
|
|
113
|
+
reject(new Error('Response is not an array'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const steps = parsed.map((item, index) => ({
|
|
117
|
+
id: item.id || `step_${index + 1}`,
|
|
118
|
+
provider: (item.provider || item.agent || 'codex'),
|
|
119
|
+
model: item.model,
|
|
120
|
+
title: item.title || `Step ${index + 1}`,
|
|
121
|
+
prompt: item.prompt || '',
|
|
122
|
+
status: 'pending',
|
|
123
|
+
}));
|
|
124
|
+
if (steps.length === 0) {
|
|
125
|
+
reject(new Error('No steps generated'));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
resolve(steps);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
reject(new Error(`Failed to parse response: ${error}`));
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
child.on('error', (error) => {
|
|
135
|
+
reject(new Error(`Failed to spawn ${provider}: ${error.message}`));
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
export const generatePlanFromGoal = async (goal, context, provider = 'claude', onStatus, onStream) => {
|
|
140
|
+
return new Promise((resolve, reject) => {
|
|
141
|
+
onStatus?.('Analyzing project...');
|
|
142
|
+
const fullPrompt = PHASED_PLANNER_PROMPT + context.summary + '\n\nGOAL: ' + goal;
|
|
143
|
+
let command;
|
|
144
|
+
let args;
|
|
145
|
+
switch (provider) {
|
|
146
|
+
case 'codex':
|
|
147
|
+
command = 'codex';
|
|
148
|
+
args = ['exec', '--skip-git-repo-check', fullPrompt];
|
|
149
|
+
break;
|
|
150
|
+
case 'gemini':
|
|
151
|
+
command = 'gemini';
|
|
152
|
+
args = [fullPrompt];
|
|
153
|
+
break;
|
|
154
|
+
case 'claude':
|
|
155
|
+
default:
|
|
156
|
+
command = 'claude';
|
|
157
|
+
args = ['-p', fullPrompt, '--output-format', 'text'];
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
onStatus?.(`Planning with ${provider}...`);
|
|
161
|
+
const child = spawn(command, args, {
|
|
162
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
163
|
+
cwd: context.workingDir,
|
|
164
|
+
});
|
|
165
|
+
let stdout = '';
|
|
166
|
+
let stderr = '';
|
|
167
|
+
child.stdout.on('data', (data) => {
|
|
168
|
+
const chunk = data.toString();
|
|
169
|
+
stdout += chunk;
|
|
170
|
+
onStream?.(chunk, 'stdout');
|
|
171
|
+
onStatus?.('Generating phases...');
|
|
172
|
+
});
|
|
173
|
+
child.stderr.on('data', (data) => {
|
|
174
|
+
const chunk = data.toString();
|
|
175
|
+
stderr += chunk;
|
|
176
|
+
onStream?.(chunk, 'stderr');
|
|
177
|
+
});
|
|
178
|
+
child.on('close', (code) => {
|
|
179
|
+
if (code !== 0) {
|
|
180
|
+
reject(new Error(`${provider} failed: ${stderr || 'Unknown error'}`));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
onStatus?.('Parsing response...');
|
|
184
|
+
try {
|
|
185
|
+
const jsonMatch = stdout.match(/\{[\s\S]*\}/);
|
|
186
|
+
if (!jsonMatch) {
|
|
187
|
+
reject(new Error('No valid JSON object in response'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
191
|
+
let phases = [];
|
|
192
|
+
if (Array.isArray(parsed)) {
|
|
193
|
+
const steps = parsed.map((item, index) => ({
|
|
194
|
+
id: item.id || `step_${index + 1}`,
|
|
195
|
+
provider: (item.provider || item.agent || 'codex'),
|
|
196
|
+
model: item.model,
|
|
197
|
+
title: item.title || `Step ${index + 1}`,
|
|
198
|
+
prompt: item.prompt || '',
|
|
199
|
+
status: 'pending',
|
|
200
|
+
}));
|
|
201
|
+
phases = [
|
|
202
|
+
{
|
|
203
|
+
id: 'phase_1',
|
|
204
|
+
title: 'Execution',
|
|
205
|
+
steps,
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
else if (parsed && Array.isArray(parsed.phases)) {
|
|
210
|
+
phases = parsed.phases.map((phase, phaseIndex) => ({
|
|
211
|
+
id: phase.id || `phase_${phaseIndex + 1}`,
|
|
212
|
+
title: phase.title || `Phase ${phaseIndex + 1}`,
|
|
213
|
+
steps: (phase.steps || []).map((item, stepIndex) => ({
|
|
214
|
+
id: item.id || `step_${phaseIndex + 1}_${stepIndex + 1}`,
|
|
215
|
+
provider: (item.provider || item.agent || 'codex'),
|
|
216
|
+
model: item.model,
|
|
217
|
+
title: item.title || `Step ${stepIndex + 1}`,
|
|
218
|
+
prompt: item.prompt || '',
|
|
219
|
+
status: 'pending',
|
|
220
|
+
})),
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
if (phases.length === 0 || phases.some((p) => p.steps.length === 0)) {
|
|
224
|
+
reject(new Error('No phases generated'));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
resolve(phases);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
reject(new Error(`Failed to parse response: ${error}`));
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
child.on('error', (error) => {
|
|
234
|
+
reject(new Error(`Failed to spawn ${provider}: ${error.message}`));
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=generateSteps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateSteps.js","sourceRoot":"","sources":["../../../src/tui/services/generateSteps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Provider, ProviderName, Model, ApprovalMode } from '../types.js';
|
|
2
|
+
export declare function detectProviders(): Promise<Provider[]>;
|
|
3
|
+
export declare function detectProvidersSync(): Provider[];
|
|
4
|
+
export declare function getProvider(providers: Provider[], name: ProviderName): Provider | undefined;
|
|
5
|
+
export declare function getModelsForProvider(providers: Provider[], name: ProviderName): Model[];
|
|
6
|
+
export declare function buildExecutionCommand(provider: ProviderName, model: string | undefined, approvalMode: ApprovalMode, prompt: string): {
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
};
|
|
10
|
+
export declare const DEFAULT_SETTINGS: {
|
|
11
|
+
defaultProvider: ProviderName;
|
|
12
|
+
defaultModel: string;
|
|
13
|
+
defaultApprovalMode: ApprovalMode;
|
|
14
|
+
defaultRunMode: "auto";
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../../src/tui/services/providers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA4H/E,wBAAsB,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAqB3D;AAGD,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAQhD;AAGD,wBAAgB,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,SAAS,CAE3F;AAGD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,KAAK,EAAE,CAGvF;AAGD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,GACb;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAwGrC;AAGD,eAAO,MAAM,gBAAgB;qBACC,YAAY;;yBAET,YAAY;;CAE5C,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
// Model definitions per provider
|
|
3
|
+
const CLAUDE_MODELS = [
|
|
4
|
+
{ id: 'claude-opus-4-5', name: 'Claude Opus 4.5' },
|
|
5
|
+
{ id: 'claude-opus-4-1', name: 'Claude Opus 4.1' },
|
|
6
|
+
{ id: 'claude-opus-4-0', name: 'Claude Opus 4' },
|
|
7
|
+
{ id: 'claude-sonnet-4-0', name: 'Claude Sonnet 4' },
|
|
8
|
+
{ id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4 (2025-05-14)' },
|
|
9
|
+
{ id: 'claude-3-7-sonnet-latest', name: 'Claude Sonnet 3.7 (latest)' },
|
|
10
|
+
{ id: 'claude-3-5-haiku-latest', name: 'Claude Haiku 3.5 (latest)' },
|
|
11
|
+
];
|
|
12
|
+
const CODEX_MODELS = [
|
|
13
|
+
{ id: 'gpt-5.2-codex', name: 'GPT-5.2 Codex' },
|
|
14
|
+
{ id: 'gpt-5.1-codex-max', name: 'GPT-5.1 Codex Max' },
|
|
15
|
+
{ id: 'gpt-5.1-codex-mini', name: 'GPT-5.1 Codex Mini' },
|
|
16
|
+
{ id: 'gpt-5.2', name: 'GPT-5.2' },
|
|
17
|
+
{ id: 'gpt-5.1', name: 'GPT-5.1' },
|
|
18
|
+
{ id: 'gpt-5.1-codex', name: 'GPT-5.1 Codex' },
|
|
19
|
+
{ id: 'gpt-5-codex', name: 'GPT-5 Codex' },
|
|
20
|
+
{ id: 'gpt-5-codex-mini', name: 'GPT-5 Codex Mini' },
|
|
21
|
+
{ id: 'gpt-5', name: 'GPT-5' },
|
|
22
|
+
];
|
|
23
|
+
const GEMINI_MODELS = [
|
|
24
|
+
{ id: 'gemini-3-pro-preview', name: 'Gemini 3 Pro (preview)' },
|
|
25
|
+
{ id: 'gemini-3-flash-preview', name: 'Gemini 3 Flash (preview)' },
|
|
26
|
+
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro' },
|
|
27
|
+
{ id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash' },
|
|
28
|
+
{ id: 'gemini-2.5-flash-lite', name: 'Gemini 2.5 Flash-Lite' },
|
|
29
|
+
];
|
|
30
|
+
const OLLAMA_MODELS = [
|
|
31
|
+
{ id: 'qwen2.5-coder:32b', name: 'Qwen 2.5 Coder 32B' },
|
|
32
|
+
{ id: 'qwen2.5-coder:7b', name: 'Qwen 2.5 Coder 7B' },
|
|
33
|
+
{ id: 'codellama:34b', name: 'Code Llama 34B' },
|
|
34
|
+
{ id: 'deepseek-coder:33b', name: 'DeepSeek Coder 33B' },
|
|
35
|
+
{ id: 'llama3.3:70b', name: 'Llama 3.3 70B' },
|
|
36
|
+
];
|
|
37
|
+
const CODEX_REASONING_EFFORTS = {
|
|
38
|
+
'gpt-5.2-codex': 'xhigh',
|
|
39
|
+
'gpt-5.1-codex-max': 'xhigh',
|
|
40
|
+
'gpt-5.2': 'xhigh',
|
|
41
|
+
'gpt-5.1-codex-mini': 'high',
|
|
42
|
+
'gpt-5.1': 'high',
|
|
43
|
+
'gpt-5.1-codex': 'high',
|
|
44
|
+
'gpt-5-codex': 'high',
|
|
45
|
+
'gpt-5-codex-mini': 'high',
|
|
46
|
+
'gpt-5': 'high',
|
|
47
|
+
};
|
|
48
|
+
function getCodexReasoningEffort(model) {
|
|
49
|
+
if (!model)
|
|
50
|
+
return null;
|
|
51
|
+
return CODEX_REASONING_EFFORTS[model] ?? null;
|
|
52
|
+
}
|
|
53
|
+
// Provider configurations
|
|
54
|
+
const PROVIDER_CONFIGS = {
|
|
55
|
+
claude: {
|
|
56
|
+
name: 'claude',
|
|
57
|
+
displayName: 'Claude',
|
|
58
|
+
command: 'claude',
|
|
59
|
+
models: CLAUDE_MODELS,
|
|
60
|
+
defaultModel: 'claude-sonnet-4-0',
|
|
61
|
+
supportsAgentic: true,
|
|
62
|
+
approvalModes: ['auto', 'manual', 'auto_edit'],
|
|
63
|
+
},
|
|
64
|
+
codex: {
|
|
65
|
+
name: 'codex',
|
|
66
|
+
displayName: 'Codex',
|
|
67
|
+
command: 'codex',
|
|
68
|
+
models: CODEX_MODELS,
|
|
69
|
+
defaultModel: 'gpt-5.2-codex',
|
|
70
|
+
supportsAgentic: true,
|
|
71
|
+
approvalModes: ['auto', 'manual'],
|
|
72
|
+
},
|
|
73
|
+
gemini: {
|
|
74
|
+
name: 'gemini',
|
|
75
|
+
displayName: 'Gemini',
|
|
76
|
+
command: 'gemini',
|
|
77
|
+
models: GEMINI_MODELS,
|
|
78
|
+
defaultModel: 'gemini-2.5-flash',
|
|
79
|
+
supportsAgentic: true,
|
|
80
|
+
approvalModes: ['auto', 'manual', 'auto_edit'],
|
|
81
|
+
},
|
|
82
|
+
ollama: {
|
|
83
|
+
name: 'ollama',
|
|
84
|
+
displayName: 'Ollama (Local)',
|
|
85
|
+
command: 'ollama',
|
|
86
|
+
models: OLLAMA_MODELS,
|
|
87
|
+
defaultModel: 'qwen2.5-coder:32b',
|
|
88
|
+
supportsAgentic: false, // Needs to go through codex
|
|
89
|
+
approvalModes: ['auto'], // When routed through codex
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// Check if a CLI command is available
|
|
93
|
+
function isCommandAvailable(command) {
|
|
94
|
+
try {
|
|
95
|
+
execSync(`which ${command}`, { stdio: 'ignore' });
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Check if Ollama server is running
|
|
103
|
+
async function isOllamaRunning() {
|
|
104
|
+
try {
|
|
105
|
+
const response = await fetch('http://localhost:11434/api/tags', {
|
|
106
|
+
method: 'GET',
|
|
107
|
+
signal: AbortSignal.timeout(2000),
|
|
108
|
+
});
|
|
109
|
+
return response.ok;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Detect available providers
|
|
116
|
+
export async function detectProviders() {
|
|
117
|
+
const providers = [];
|
|
118
|
+
for (const name of Object.keys(PROVIDER_CONFIGS)) {
|
|
119
|
+
const config = PROVIDER_CONFIGS[name];
|
|
120
|
+
let available = false;
|
|
121
|
+
if (name === 'ollama') {
|
|
122
|
+
// Ollama needs both CLI and running server
|
|
123
|
+
available = isCommandAvailable(config.command) && await isOllamaRunning();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
available = isCommandAvailable(config.command);
|
|
127
|
+
}
|
|
128
|
+
providers.push({
|
|
129
|
+
...config,
|
|
130
|
+
available,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return providers;
|
|
134
|
+
}
|
|
135
|
+
// Synchronous version for initial load (doesn't check ollama server)
|
|
136
|
+
export function detectProvidersSync() {
|
|
137
|
+
return Object.keys(PROVIDER_CONFIGS).map((name) => {
|
|
138
|
+
const config = PROVIDER_CONFIGS[name];
|
|
139
|
+
return {
|
|
140
|
+
...config,
|
|
141
|
+
available: isCommandAvailable(config.command),
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Get provider by name
|
|
146
|
+
export function getProvider(providers, name) {
|
|
147
|
+
return providers.find((p) => p.name === name);
|
|
148
|
+
}
|
|
149
|
+
// Get models for a provider
|
|
150
|
+
export function getModelsForProvider(providers, name) {
|
|
151
|
+
const provider = getProvider(providers, name);
|
|
152
|
+
return provider?.models || [];
|
|
153
|
+
}
|
|
154
|
+
// Build CLI command for execution
|
|
155
|
+
export function buildExecutionCommand(provider, model, approvalMode, prompt) {
|
|
156
|
+
switch (provider) {
|
|
157
|
+
case 'claude': {
|
|
158
|
+
const args = [];
|
|
159
|
+
// Model
|
|
160
|
+
if (model) {
|
|
161
|
+
args.push('--model', model);
|
|
162
|
+
}
|
|
163
|
+
// Approval mode
|
|
164
|
+
switch (approvalMode) {
|
|
165
|
+
case 'auto':
|
|
166
|
+
args.push('--permission-mode', 'bypassPermissions');
|
|
167
|
+
break;
|
|
168
|
+
case 'auto_edit':
|
|
169
|
+
args.push('--permission-mode', 'acceptEdits');
|
|
170
|
+
break;
|
|
171
|
+
case 'manual':
|
|
172
|
+
args.push('--permission-mode', 'default');
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
// Prompt as argument (not -p which is print-only)
|
|
176
|
+
args.push(prompt);
|
|
177
|
+
return { command: 'claude', args };
|
|
178
|
+
}
|
|
179
|
+
case 'codex': {
|
|
180
|
+
const args = ['exec', '--skip-git-repo-check'];
|
|
181
|
+
// Model
|
|
182
|
+
if (model) {
|
|
183
|
+
args.push('-m', model);
|
|
184
|
+
}
|
|
185
|
+
const effort = getCodexReasoningEffort(model);
|
|
186
|
+
if (effort) {
|
|
187
|
+
args.push('-c', `model_reasoning_effort=${effort}`);
|
|
188
|
+
}
|
|
189
|
+
// Sandbox and approval mode
|
|
190
|
+
switch (approvalMode) {
|
|
191
|
+
case 'auto':
|
|
192
|
+
args.push('--sandbox', 'danger-full-access');
|
|
193
|
+
break;
|
|
194
|
+
case 'manual':
|
|
195
|
+
args.push('--sandbox', 'workspace-write');
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
// Prompt
|
|
199
|
+
args.push(prompt);
|
|
200
|
+
return { command: 'codex', args };
|
|
201
|
+
}
|
|
202
|
+
case 'gemini': {
|
|
203
|
+
const args = [];
|
|
204
|
+
// Model
|
|
205
|
+
if (model) {
|
|
206
|
+
args.push('-m', model);
|
|
207
|
+
}
|
|
208
|
+
// Approval mode
|
|
209
|
+
switch (approvalMode) {
|
|
210
|
+
case 'auto':
|
|
211
|
+
args.push('--yolo');
|
|
212
|
+
break;
|
|
213
|
+
case 'auto_edit':
|
|
214
|
+
args.push('--approval-mode', 'auto_edit');
|
|
215
|
+
break;
|
|
216
|
+
case 'manual':
|
|
217
|
+
args.push('--approval-mode', 'default');
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
// Prompt as positional argument (preferred)
|
|
221
|
+
args.push(prompt);
|
|
222
|
+
return { command: 'gemini', args };
|
|
223
|
+
}
|
|
224
|
+
case 'ollama': {
|
|
225
|
+
// Route through codex with --oss flag
|
|
226
|
+
const args = ['exec', '--skip-git-repo-check', '--oss', '--local-provider', 'ollama'];
|
|
227
|
+
if (model) {
|
|
228
|
+
args.push('-m', model);
|
|
229
|
+
}
|
|
230
|
+
// Always auto for ollama (through codex)
|
|
231
|
+
args.push('--sandbox', 'danger-full-access');
|
|
232
|
+
args.push(prompt);
|
|
233
|
+
return { command: 'codex', args };
|
|
234
|
+
}
|
|
235
|
+
default:
|
|
236
|
+
throw new Error(`Unknown provider: ${provider}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Default settings
|
|
240
|
+
export const DEFAULT_SETTINGS = {
|
|
241
|
+
defaultProvider: 'codex',
|
|
242
|
+
defaultModel: 'o4-mini',
|
|
243
|
+
defaultApprovalMode: 'auto',
|
|
244
|
+
defaultRunMode: 'auto',
|
|
245
|
+
};
|
|
246
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../../src/tui/services/providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ProviderName, ApprovalMode, RunMode } from '../types.js';
|
|
2
|
+
export declare const API_KEY_ENV_VARS: Record<ProviderName, string>;
|
|
3
|
+
export interface ArachneConfig {
|
|
4
|
+
apiKeys: {
|
|
5
|
+
claude?: string;
|
|
6
|
+
codex?: string;
|
|
7
|
+
gemini?: string;
|
|
8
|
+
};
|
|
9
|
+
defaults: {
|
|
10
|
+
provider: ProviderName;
|
|
11
|
+
model: string;
|
|
12
|
+
approvalMode: ApprovalMode;
|
|
13
|
+
runMode: RunMode;
|
|
14
|
+
};
|
|
15
|
+
ui: {
|
|
16
|
+
showSplash: boolean;
|
|
17
|
+
theme?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function loadConfig(): ArachneConfig;
|
|
21
|
+
export declare function saveConfig(config: ArachneConfig): void;
|
|
22
|
+
export declare function getApiKey(provider: ProviderName): string | undefined;
|
|
23
|
+
export declare function setApiKey(provider: ProviderName, key: string | undefined): void;
|
|
24
|
+
export declare function getProviderEnv(provider: ProviderName): Record<string, string>;
|
|
25
|
+
export declare function hasApiKey(provider: ProviderName): boolean;
|
|
26
|
+
export declare function maskApiKey(key: string): string;
|
|
27
|
+
export declare function getDefaults(): ArachneConfig['defaults'];
|
|
28
|
+
export declare function setDefaults(defaults: Partial<ArachneConfig['defaults']>): void;
|
|
29
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/tui/services/settings.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAOvE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKzD,CAAC;AAGF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE,YAAY,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,YAAY,CAAC;QAC3B,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,EAAE,EAAE;QACF,UAAU,EAAE,OAAO,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAwBD,wBAAgB,UAAU,IAAI,aAAa,CAmB1C;AAGD,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAGtD;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAGpE;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQ/E;AAGD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAGzD;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C;AAGD,wBAAgB,WAAW,IAAI,aAAa,CAAC,UAAU,CAAC,CAEvD;AAGD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAI9E"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
// Config directory and file paths
|
|
5
|
+
const CONFIG_DIR = join(homedir(), '.arachne');
|
|
6
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
7
|
+
// API key environment variable names per provider
|
|
8
|
+
export const API_KEY_ENV_VARS = {
|
|
9
|
+
claude: 'ANTHROPIC_API_KEY',
|
|
10
|
+
codex: 'OPENAI_API_KEY',
|
|
11
|
+
gemini: 'GOOGLE_API_KEY',
|
|
12
|
+
ollama: '', // Ollama doesn't use API keys
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_CONFIG = {
|
|
15
|
+
apiKeys: {},
|
|
16
|
+
defaults: {
|
|
17
|
+
provider: 'codex',
|
|
18
|
+
model: 'o4-mini',
|
|
19
|
+
approvalMode: 'auto',
|
|
20
|
+
runMode: 'auto',
|
|
21
|
+
},
|
|
22
|
+
ui: {
|
|
23
|
+
showSplash: true,
|
|
24
|
+
theme: 'obsidian-web',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
// Ensure config directory exists
|
|
28
|
+
function ensureConfigDir() {
|
|
29
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
30
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Load config from disk
|
|
34
|
+
export function loadConfig() {
|
|
35
|
+
try {
|
|
36
|
+
ensureConfigDir();
|
|
37
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
38
|
+
return { ...DEFAULT_CONFIG };
|
|
39
|
+
}
|
|
40
|
+
const content = readFileSync(CONFIG_FILE, 'utf-8');
|
|
41
|
+
const parsed = JSON.parse(content);
|
|
42
|
+
// Merge with defaults to handle missing fields
|
|
43
|
+
return {
|
|
44
|
+
...DEFAULT_CONFIG,
|
|
45
|
+
...parsed,
|
|
46
|
+
apiKeys: { ...DEFAULT_CONFIG.apiKeys, ...parsed.apiKeys },
|
|
47
|
+
defaults: { ...DEFAULT_CONFIG.defaults, ...parsed.defaults },
|
|
48
|
+
ui: { ...DEFAULT_CONFIG.ui, ...parsed.ui },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { ...DEFAULT_CONFIG };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Save config to disk
|
|
56
|
+
export function saveConfig(config) {
|
|
57
|
+
ensureConfigDir();
|
|
58
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
// Get API key for a provider
|
|
61
|
+
export function getApiKey(provider) {
|
|
62
|
+
const config = loadConfig();
|
|
63
|
+
return config.apiKeys[provider];
|
|
64
|
+
}
|
|
65
|
+
// Set API key for a provider
|
|
66
|
+
export function setApiKey(provider, key) {
|
|
67
|
+
const config = loadConfig();
|
|
68
|
+
if (key) {
|
|
69
|
+
config.apiKeys[provider] = key;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
delete config.apiKeys[provider];
|
|
73
|
+
}
|
|
74
|
+
saveConfig(config);
|
|
75
|
+
}
|
|
76
|
+
// Get environment variables for a provider (includes API key if set)
|
|
77
|
+
export function getProviderEnv(provider) {
|
|
78
|
+
const env = {};
|
|
79
|
+
const apiKey = getApiKey(provider);
|
|
80
|
+
const envVar = API_KEY_ENV_VARS[provider];
|
|
81
|
+
if (apiKey && envVar) {
|
|
82
|
+
env[envVar] = apiKey;
|
|
83
|
+
}
|
|
84
|
+
return env;
|
|
85
|
+
}
|
|
86
|
+
// Check if provider has API key configured
|
|
87
|
+
export function hasApiKey(provider) {
|
|
88
|
+
const key = getApiKey(provider);
|
|
89
|
+
return !!key && key.length > 0;
|
|
90
|
+
}
|
|
91
|
+
// Mask API key for display (show first 4 and last 4 chars)
|
|
92
|
+
export function maskApiKey(key) {
|
|
93
|
+
if (!key || key.length < 12)
|
|
94
|
+
return '****';
|
|
95
|
+
return `${key.slice(0, 4)}...${key.slice(-4)}`;
|
|
96
|
+
}
|
|
97
|
+
// Get default settings
|
|
98
|
+
export function getDefaults() {
|
|
99
|
+
return loadConfig().defaults;
|
|
100
|
+
}
|
|
101
|
+
// Update default settings
|
|
102
|
+
export function setDefaults(defaults) {
|
|
103
|
+
const config = loadConfig();
|
|
104
|
+
config.defaults = { ...config.defaults, ...defaults };
|
|
105
|
+
saveConfig(config);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=settings.js.map
|