@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.
Files changed (153) hide show
  1. package/LICENSE +75 -0
  2. package/README.md +40 -0
  3. package/bin/arachne +2 -0
  4. package/bin/arachne.js +2 -0
  5. package/dist/arachne.d.ts +3 -0
  6. package/dist/arachne.d.ts.map +1 -0
  7. package/dist/arachne.js +4 -0
  8. package/dist/arachne.js.map +1 -0
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +145 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/serve.d.ts +6 -0
  14. package/dist/serve.d.ts.map +1 -0
  15. package/dist/serve.js +83 -0
  16. package/dist/serve.js.map +1 -0
  17. package/dist/templates.d.ts +3 -0
  18. package/dist/templates.d.ts.map +1 -0
  19. package/dist/templates.js +22 -0
  20. package/dist/templates.js.map +1 -0
  21. package/dist/tui/App.d.ts +2 -0
  22. package/dist/tui/App.d.ts.map +1 -0
  23. package/dist/tui/App.js +1078 -0
  24. package/dist/tui/App.js.map +1 -0
  25. package/dist/tui/components/Box.d.ts +19 -0
  26. package/dist/tui/components/Box.d.ts.map +1 -0
  27. package/dist/tui/components/Box.js +9 -0
  28. package/dist/tui/components/Box.js.map +1 -0
  29. package/dist/tui/components/ChatInput.d.ts +12 -0
  30. package/dist/tui/components/ChatInput.d.ts.map +1 -0
  31. package/dist/tui/components/ChatInput.js +10 -0
  32. package/dist/tui/components/ChatInput.js.map +1 -0
  33. package/dist/tui/components/CommandInput.d.ts +15 -0
  34. package/dist/tui/components/CommandInput.d.ts.map +1 -0
  35. package/dist/tui/components/CommandInput.js +92 -0
  36. package/dist/tui/components/CommandInput.js.map +1 -0
  37. package/dist/tui/components/Content.d.ts +18 -0
  38. package/dist/tui/components/Content.d.ts.map +1 -0
  39. package/dist/tui/components/Content.js +22 -0
  40. package/dist/tui/components/Content.js.map +1 -0
  41. package/dist/tui/components/DagView.d.ts +8 -0
  42. package/dist/tui/components/DagView.d.ts.map +1 -0
  43. package/dist/tui/components/DagView.js +49 -0
  44. package/dist/tui/components/DagView.js.map +1 -0
  45. package/dist/tui/components/Footer.d.ts +9 -0
  46. package/dist/tui/components/Footer.d.ts.map +1 -0
  47. package/dist/tui/components/Footer.js +6 -0
  48. package/dist/tui/components/Footer.js.map +1 -0
  49. package/dist/tui/components/Frame.d.ts +6 -0
  50. package/dist/tui/components/Frame.d.ts.map +1 -0
  51. package/dist/tui/components/Frame.js +10 -0
  52. package/dist/tui/components/Frame.js.map +1 -0
  53. package/dist/tui/components/GoalInput.d.ts +10 -0
  54. package/dist/tui/components/GoalInput.d.ts.map +1 -0
  55. package/dist/tui/components/GoalInput.js +8 -0
  56. package/dist/tui/components/GoalInput.js.map +1 -0
  57. package/dist/tui/components/Header.d.ts +8 -0
  58. package/dist/tui/components/Header.d.ts.map +1 -0
  59. package/dist/tui/components/Header.js +8 -0
  60. package/dist/tui/components/Header.js.map +1 -0
  61. package/dist/tui/components/Help.d.ts +6 -0
  62. package/dist/tui/components/Help.d.ts.map +1 -0
  63. package/dist/tui/components/Help.js +8 -0
  64. package/dist/tui/components/Help.js.map +1 -0
  65. package/dist/tui/components/HomeView.d.ts +2 -0
  66. package/dist/tui/components/HomeView.d.ts.map +1 -0
  67. package/dist/tui/components/HomeView.js +8 -0
  68. package/dist/tui/components/HomeView.js.map +1 -0
  69. package/dist/tui/components/OutputView.d.ts +9 -0
  70. package/dist/tui/components/OutputView.d.ts.map +1 -0
  71. package/dist/tui/components/OutputView.js +40 -0
  72. package/dist/tui/components/OutputView.js.map +1 -0
  73. package/dist/tui/components/PlannerView.d.ts +17 -0
  74. package/dist/tui/components/PlannerView.d.ts.map +1 -0
  75. package/dist/tui/components/PlannerView.js +62 -0
  76. package/dist/tui/components/PlannerView.js.map +1 -0
  77. package/dist/tui/components/Settings.d.ts +6 -0
  78. package/dist/tui/components/Settings.d.ts.map +1 -0
  79. package/dist/tui/components/Settings.js +210 -0
  80. package/dist/tui/components/Settings.js.map +1 -0
  81. package/dist/tui/components/Sidebar.d.ts +12 -0
  82. package/dist/tui/components/Sidebar.d.ts.map +1 -0
  83. package/dist/tui/components/Sidebar.js +9 -0
  84. package/dist/tui/components/Sidebar.js.map +1 -0
  85. package/dist/tui/components/Splash.d.ts +7 -0
  86. package/dist/tui/components/Splash.d.ts.map +1 -0
  87. package/dist/tui/components/Splash.js +56 -0
  88. package/dist/tui/components/Splash.js.map +1 -0
  89. package/dist/tui/components/StepEditor.d.ts +13 -0
  90. package/dist/tui/components/StepEditor.d.ts.map +1 -0
  91. package/dist/tui/components/StepEditor.js +33 -0
  92. package/dist/tui/components/StepEditor.js.map +1 -0
  93. package/dist/tui/components/ThemeDesigner.d.ts +9 -0
  94. package/dist/tui/components/ThemeDesigner.d.ts.map +1 -0
  95. package/dist/tui/components/ThemeDesigner.js +45 -0
  96. package/dist/tui/components/ThemeDesigner.js.map +1 -0
  97. package/dist/tui/components/WorkflowPicker.d.ts +8 -0
  98. package/dist/tui/components/WorkflowPicker.d.ts.map +1 -0
  99. package/dist/tui/components/WorkflowPicker.js +11 -0
  100. package/dist/tui/components/WorkflowPicker.js.map +1 -0
  101. package/dist/tui/components/index.d.ts +20 -0
  102. package/dist/tui/components/index.d.ts.map +1 -0
  103. package/dist/tui/components/index.js +20 -0
  104. package/dist/tui/components/index.js.map +1 -0
  105. package/dist/tui/index.d.ts +2 -0
  106. package/dist/tui/index.d.ts.map +1 -0
  107. package/dist/tui/index.js +7 -0
  108. package/dist/tui/index.js.map +1 -0
  109. package/dist/tui/services/context.d.ts +11 -0
  110. package/dist/tui/services/context.d.ts.map +1 -0
  111. package/dist/tui/services/context.js +134 -0
  112. package/dist/tui/services/context.js.map +1 -0
  113. package/dist/tui/services/executor.d.ts +13 -0
  114. package/dist/tui/services/executor.d.ts.map +1 -0
  115. package/dist/tui/services/executor.js +186 -0
  116. package/dist/tui/services/executor.js.map +1 -0
  117. package/dist/tui/services/generateSteps.d.ts +7 -0
  118. package/dist/tui/services/generateSteps.d.ts.map +1 -0
  119. package/dist/tui/services/generateSteps.js +238 -0
  120. package/dist/tui/services/generateSteps.js.map +1 -0
  121. package/dist/tui/services/providers.d.ts +16 -0
  122. package/dist/tui/services/providers.d.ts.map +1 -0
  123. package/dist/tui/services/providers.js +246 -0
  124. package/dist/tui/services/providers.js.map +1 -0
  125. package/dist/tui/services/settings.d.ts +29 -0
  126. package/dist/tui/services/settings.d.ts.map +1 -0
  127. package/dist/tui/services/settings.js +107 -0
  128. package/dist/tui/services/settings.js.map +1 -0
  129. package/dist/tui/services/theme.d.ts +45 -0
  130. package/dist/tui/services/theme.d.ts.map +1 -0
  131. package/dist/tui/services/theme.js +205 -0
  132. package/dist/tui/services/theme.js.map +1 -0
  133. package/dist/tui/services/themeGenerator.d.ts +4 -0
  134. package/dist/tui/services/themeGenerator.d.ts.map +1 -0
  135. package/dist/tui/services/themeGenerator.js +93 -0
  136. package/dist/tui/services/themeGenerator.js.map +1 -0
  137. package/dist/tui/services/user.d.ts +3 -0
  138. package/dist/tui/services/user.d.ts.map +1 -0
  139. package/dist/tui/services/user.js +40 -0
  140. package/dist/tui/services/user.js.map +1 -0
  141. package/dist/tui/theme-context.d.ts +4 -0
  142. package/dist/tui/theme-context.d.ts.map +1 -0
  143. package/dist/tui/theme-context.js +6 -0
  144. package/dist/tui/theme-context.js.map +1 -0
  145. package/dist/tui/types.d.ts +81 -0
  146. package/dist/tui/types.d.ts.map +1 -0
  147. package/dist/tui/types.js +3 -0
  148. package/dist/tui/types.js.map +1 -0
  149. package/dist/tui.d.ts +2 -0
  150. package/dist/tui.d.ts.map +1 -0
  151. package/dist/tui.js +241 -0
  152. package/dist/tui.js.map +1 -0
  153. 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