orquesta-agent 0.1.81 → 0.1.86
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/executor.d.ts +7 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +222 -86
- package/dist/executor.js.map +1 -1
- package/dist/index.js +79 -15
- package/dist/index.js.map +1 -1
- package/dist/supabase.d.ts +1 -0
- package/dist/supabase.d.ts.map +1 -1
- package/dist/supabase.js +4 -2
- package/dist/supabase.js.map +1 -1
- package/package.json +5 -1
- package/scripts/postinstall.js +2 -0
package/dist/executor.d.ts
CHANGED
|
@@ -38,7 +38,14 @@ export interface AuthConfig {
|
|
|
38
38
|
}
|
|
39
39
|
export declare function configureAuth(config: AuthConfig): void;
|
|
40
40
|
export declare function setPermissionMode(mode: PermissionMode): void;
|
|
41
|
+
export type CliPreference = 'auto' | 'orquesta' | 'claude';
|
|
42
|
+
export declare function setCliPreference(preference: CliPreference): void;
|
|
43
|
+
export declare function isOrquestaCliAvailable(): boolean;
|
|
41
44
|
export declare function isClaudeCliAvailable(): boolean;
|
|
45
|
+
export declare function selectCli(): {
|
|
46
|
+
cli: 'orquesta' | 'claude' | null;
|
|
47
|
+
reason: string;
|
|
48
|
+
};
|
|
42
49
|
export declare function checkClaudeAuth(): {
|
|
43
50
|
authenticated: boolean;
|
|
44
51
|
method: string | null;
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AA4LvD,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEhF;AAGD,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE/D;AAGD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,YAAY,CAAA;AAOlD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAID,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAMtE;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAIlE;AA+DD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,eAAe,CAAA;IACxB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,CAAC,EAAE;QAClB,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAGD,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAgBtD;AAGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAG5D;AAGD,wBAAgB,oBAAoB,IAAI,OAAO,CAQ9C;AAGD,wBAAgB,eAAe,IAAI;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CA2BvG;AAGD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAetG;AAED,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ9D;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBxF;AA8eD,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -261,6 +261,23 @@ export function setPermissionMode(mode) {
|
|
|
261
261
|
globalPermissionMode = mode;
|
|
262
262
|
logger.info(`Permission mode set to: ${mode}`);
|
|
263
263
|
}
|
|
264
|
+
let globalCliPreference = 'auto';
|
|
265
|
+
// Set CLI preference
|
|
266
|
+
export function setCliPreference(preference) {
|
|
267
|
+
globalCliPreference = preference;
|
|
268
|
+
logger.info(`CLI preference set to: ${preference}`);
|
|
269
|
+
}
|
|
270
|
+
// Check if Orquesta CLI command is available in PATH
|
|
271
|
+
export function isOrquestaCliAvailable() {
|
|
272
|
+
try {
|
|
273
|
+
// Try to get Orquesta CLI version - this verifies the command exists
|
|
274
|
+
execSync('orquesta --version', { stdio: 'pipe', timeout: 5000 });
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
264
281
|
// Check if Claude CLI command is available in PATH
|
|
265
282
|
export function isClaudeCliAvailable() {
|
|
266
283
|
try {
|
|
@@ -272,6 +289,39 @@ export function isClaudeCliAvailable() {
|
|
|
272
289
|
return false;
|
|
273
290
|
}
|
|
274
291
|
}
|
|
292
|
+
// Select which CLI to use based on availability and preference
|
|
293
|
+
export function selectCli() {
|
|
294
|
+
const hasOrquesta = isOrquestaCliAvailable();
|
|
295
|
+
const hasClaude = isClaudeCliAvailable();
|
|
296
|
+
// If neither available, return null
|
|
297
|
+
if (!hasOrquesta && !hasClaude) {
|
|
298
|
+
return { cli: null, reason: 'No CLI found (neither orquesta nor claude)' };
|
|
299
|
+
}
|
|
300
|
+
// If preference is explicit and that CLI is available, use it
|
|
301
|
+
if (globalCliPreference === 'orquesta' && hasOrquesta) {
|
|
302
|
+
return { cli: 'orquesta', reason: 'User preference: orquesta' };
|
|
303
|
+
}
|
|
304
|
+
if (globalCliPreference === 'claude' && hasClaude) {
|
|
305
|
+
return { cli: 'claude', reason: 'User preference: claude' };
|
|
306
|
+
}
|
|
307
|
+
// If preference is explicit but that CLI is NOT available, warn and fallback
|
|
308
|
+
if (globalCliPreference === 'orquesta' && !hasOrquesta) {
|
|
309
|
+
logger.warn('Orquesta CLI preferred but not available, falling back to Claude CLI');
|
|
310
|
+
return { cli: 'claude', reason: 'Fallback: orquesta not available' };
|
|
311
|
+
}
|
|
312
|
+
if (globalCliPreference === 'claude' && !hasClaude) {
|
|
313
|
+
logger.warn('Claude CLI preferred but not available, falling back to Orquesta CLI');
|
|
314
|
+
return { cli: 'orquesta', reason: 'Fallback: claude not available' };
|
|
315
|
+
}
|
|
316
|
+
// Auto mode: prefer orquesta if available, fallback to claude
|
|
317
|
+
if (hasOrquesta) {
|
|
318
|
+
return { cli: 'orquesta', reason: 'Auto: orquesta available (local LLM)' };
|
|
319
|
+
}
|
|
320
|
+
if (hasClaude) {
|
|
321
|
+
return { cli: 'claude', reason: 'Auto: claude available (Anthropic API)' };
|
|
322
|
+
}
|
|
323
|
+
return { cli: null, reason: 'No CLI found' };
|
|
324
|
+
}
|
|
275
325
|
// Check if Claude CLI is authenticated
|
|
276
326
|
export function checkClaudeAuth() {
|
|
277
327
|
// First check if claude command is available
|
|
@@ -843,26 +893,36 @@ ${content}${attachmentContext}`;
|
|
|
843
893
|
if (anthropicApiKey) {
|
|
844
894
|
env.ANTHROPIC_API_KEY = anthropicApiKey;
|
|
845
895
|
}
|
|
846
|
-
//
|
|
847
|
-
|
|
896
|
+
// Select CLI based on availability and preference
|
|
897
|
+
const { cli: selectedCli, reason } = selectCli();
|
|
898
|
+
if (!selectedCli) {
|
|
899
|
+
throw new Error('No CLI available. Please install either orquesta-cli or claude CLI.');
|
|
900
|
+
}
|
|
901
|
+
const cliCommand = selectedCli;
|
|
848
902
|
const cwd = workingDirectory || process.cwd();
|
|
849
|
-
logger.info(`
|
|
903
|
+
logger.info(`CLI Selection: ${cliCommand} (${reason})`);
|
|
904
|
+
logger.info(`Spawning: ${cliCommand} -p "${fullContent.slice(0, 50)}..." in ${cwd}`);
|
|
850
905
|
// Escape content for shell - replace single quotes
|
|
851
906
|
const escapedContent = fullContent.replace(/'/g, "'\\''");
|
|
852
907
|
// Build command based on permission mode
|
|
853
908
|
// Use stream-json format to get structured output including thinking
|
|
854
909
|
let command;
|
|
855
|
-
|
|
910
|
+
// Different flags for different CLIs
|
|
911
|
+
// Claude CLI supports --output-format stream-json
|
|
912
|
+
// Orquesta CLI doesn't need special format flags - it outputs directly
|
|
913
|
+
const baseFlags = cliCommand === 'orquesta'
|
|
914
|
+
? '--verbose' // Orquesta: simple verbose output
|
|
915
|
+
: '--verbose --output-format stream-json'; // Claude: stream-json format
|
|
856
916
|
const permFlags = mode === 'auto' ? '--dangerously-skip-permissions' : '';
|
|
857
917
|
// If we have image files, pass them BEFORE the -p flag
|
|
858
|
-
//
|
|
918
|
+
// CLI syntax: [cli-command] [files...] -p "prompt" [flags]
|
|
859
919
|
if (imageReferences.length > 0) {
|
|
860
920
|
const imageArgs = imageReferences.map(f => `'${f.replace(/'/g, "'\\''")}'`).join(' ');
|
|
861
|
-
command =
|
|
921
|
+
command = `${cliCommand} ${imageArgs} -p '${escapedContent}' ${permFlags} ${baseFlags}`;
|
|
862
922
|
logger.info(`Including ${imageReferences.length} image file(s) in command`);
|
|
863
923
|
}
|
|
864
924
|
else {
|
|
865
|
-
command =
|
|
925
|
+
command = `${cliCommand} -p '${escapedContent}' ${permFlags} ${baseFlags}`;
|
|
866
926
|
}
|
|
867
927
|
const claude = spawn('script', ['-q', '-c', command, '/dev/null'], {
|
|
868
928
|
cwd,
|
|
@@ -901,6 +961,68 @@ ${content}${attachmentContext}`;
|
|
|
901
961
|
try {
|
|
902
962
|
const json = JSON.parse(line);
|
|
903
963
|
hadValidJson = true; // Successfully parsed JSON
|
|
964
|
+
// Handle Orquesta CLI eval format (has 'event' field)
|
|
965
|
+
if (json.event) {
|
|
966
|
+
if (json.event === 'start') {
|
|
967
|
+
output += `\n🎯 Starting task...\n`;
|
|
968
|
+
logs.push(createSystemLog('init', 'Task started', 'info', promptId, json.data));
|
|
969
|
+
}
|
|
970
|
+
else if (json.event === 'todo') {
|
|
971
|
+
const { action, id, title } = json.data;
|
|
972
|
+
if (action === 'created') {
|
|
973
|
+
output += `\n📝 Task ${id}: ${title}\n`;
|
|
974
|
+
}
|
|
975
|
+
else if (action === 'started') {
|
|
976
|
+
output += `\n▶️ Working on: ${title}\n`;
|
|
977
|
+
}
|
|
978
|
+
else if (action === 'completed') {
|
|
979
|
+
output += `\n✅ Completed: ${title}\n`;
|
|
980
|
+
}
|
|
981
|
+
else if (action === 'failed') {
|
|
982
|
+
output += `\n❌ Failed: ${title}\n`;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
else if (json.event === 'tool_call') {
|
|
986
|
+
const { tool, args } = json.data;
|
|
987
|
+
output += `\n🔧 Tool: ${tool}\n`;
|
|
988
|
+
const argsStr = JSON.stringify(args, null, 2);
|
|
989
|
+
if (argsStr.length < 500) {
|
|
990
|
+
output += `${argsStr}\n`;
|
|
991
|
+
}
|
|
992
|
+
logs.push(createToolCallLog(tool, args, 'info', promptId));
|
|
993
|
+
currentToolName = tool;
|
|
994
|
+
}
|
|
995
|
+
else if (json.event === 'tool_result') {
|
|
996
|
+
const { tool, success, result, error } = json.data;
|
|
997
|
+
if (success && result) {
|
|
998
|
+
const preview = result.slice(0, 1000);
|
|
999
|
+
output += `\n📋 Result: ${preview}${result.length > 1000 ? '...' : ''}\n`;
|
|
1000
|
+
logs.push(createToolResultLog(tool, true, result.slice(0, 5000), undefined, 'success', promptId));
|
|
1001
|
+
}
|
|
1002
|
+
else if (error) {
|
|
1003
|
+
output += `\n❌ Error: ${error}\n`;
|
|
1004
|
+
logs.push(createToolResultLog(tool, false, undefined, error, 'error', promptId));
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
else if (json.event === 'response') {
|
|
1008
|
+
const { content } = json.data;
|
|
1009
|
+
if (content) {
|
|
1010
|
+
output += `\n${content}\n`;
|
|
1011
|
+
logs.push(createOutputLog(content, 'markdown', 'info', promptId));
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
else if (json.event === 'end') {
|
|
1015
|
+
const { success, duration_ms, usage } = json.data;
|
|
1016
|
+
const duration = (duration_ms / 1000).toFixed(1);
|
|
1017
|
+
output += `\n${success ? '✅' : '❌'} Completed in ${duration}s\n`;
|
|
1018
|
+
if (usage) {
|
|
1019
|
+
output += `📊 Tokens: ${usage.total_tokens || 0}\n`;
|
|
1020
|
+
}
|
|
1021
|
+
logs.push(createSystemLog('complete', `Execution ${success ? 'succeeded' : 'failed'}`, success ? 'success' : 'error', promptId, json.data));
|
|
1022
|
+
}
|
|
1023
|
+
// Continue to next line - don't process as Claude format
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
904
1026
|
// Handle different message types from Claude CLI stream-json
|
|
905
1027
|
if (json.type === 'assistant') {
|
|
906
1028
|
// Assistant message with content blocks
|
|
@@ -1207,80 +1329,85 @@ ${content}${attachmentContext}`;
|
|
|
1207
1329
|
else {
|
|
1208
1330
|
logger.warn('No stderr pipe available');
|
|
1209
1331
|
}
|
|
1210
|
-
//
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1332
|
+
// Wrap process lifecycle in a Promise so callers can await completion
|
|
1333
|
+
return new Promise((resolveExecution) => {
|
|
1334
|
+
// Handle completion
|
|
1335
|
+
claude.on('close', async (code) => {
|
|
1336
|
+
runningProcesses.delete(commandId);
|
|
1337
|
+
if (promptId)
|
|
1338
|
+
promptIdToCommandId.delete(promptId);
|
|
1339
|
+
pendingSupervisionCallbacks.delete(commandId);
|
|
1340
|
+
const exitCode = code ?? 0;
|
|
1341
|
+
const duration = Date.now() - startTime;
|
|
1342
|
+
const status = exitCode === 0 ? 'completed' : 'failed';
|
|
1343
|
+
if (exitCode === 0) {
|
|
1344
|
+
logger.success(`Completed in ${(duration / 1000).toFixed(1)}s`);
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
logger.warn(`Exited with code ${exitCode}`);
|
|
1348
|
+
}
|
|
1349
|
+
// Add completion log entry
|
|
1350
|
+
addLog(promptId, exitCode === 0 ? 'success' : 'error', 'system', `Execution ${status} with exit code ${exitCode} in ${(duration / 1000).toFixed(1)}s`);
|
|
1351
|
+
// Stop periodic log persistence and flush any remaining logs
|
|
1352
|
+
stopLogPersistence(promptId);
|
|
1353
|
+
try {
|
|
1354
|
+
await flushLogs(promptId);
|
|
1355
|
+
logger.debug('All logs flushed to database');
|
|
1356
|
+
}
|
|
1357
|
+
catch (err) {
|
|
1358
|
+
logger.error(`Failed to flush final logs: ${err}`);
|
|
1359
|
+
}
|
|
1360
|
+
// Clear output buffer for this command
|
|
1361
|
+
clearOutputBuffer(commandId);
|
|
1362
|
+
// Clean up attachment temp files
|
|
1363
|
+
if (attachmentCleanup) {
|
|
1364
|
+
attachmentCleanup();
|
|
1365
|
+
}
|
|
1366
|
+
// Send completion via WebSocket (for real-time UI update)
|
|
1367
|
+
sendComplete(channel, commandId, exitCode, startTime);
|
|
1368
|
+
// Generate execution summary for project memory
|
|
1369
|
+
const summary = generateExecutionSummary(promptId, content, exitCode);
|
|
1370
|
+
if (summary) {
|
|
1371
|
+
logger.info(`Generated summary: ${summary.text.slice(0, 100)}...`);
|
|
1372
|
+
logger.debug(`Files modified: ${summary.files_modified.length}, Actions: ${summary.key_actions.length}`);
|
|
1373
|
+
}
|
|
1374
|
+
// Update prompt status in database with summary (backend fix - don't rely on frontend)
|
|
1375
|
+
updatePromptStatus(promptId, status, summary || undefined).catch(err => {
|
|
1376
|
+
logger.error(`Failed to update prompt status: ${err}`);
|
|
1377
|
+
});
|
|
1378
|
+
resolveExecution();
|
|
1379
|
+
});
|
|
1380
|
+
// Handle errors
|
|
1381
|
+
claude.on('error', async (err) => {
|
|
1382
|
+
runningProcesses.delete(commandId);
|
|
1383
|
+
if (promptId)
|
|
1384
|
+
promptIdToCommandId.delete(promptId);
|
|
1385
|
+
pendingSupervisionCallbacks.delete(commandId);
|
|
1386
|
+
logger.error(`Execution error: ${err.message}`);
|
|
1387
|
+
// Add error log entry
|
|
1388
|
+
addLog(promptId, 'error', 'system', `Execution error: ${err.message}`);
|
|
1389
|
+
// Stop log persistence and flush remaining logs
|
|
1390
|
+
stopLogPersistence(promptId);
|
|
1391
|
+
try {
|
|
1392
|
+
await flushLogs(promptId);
|
|
1393
|
+
}
|
|
1394
|
+
catch (flushErr) {
|
|
1395
|
+
logger.error(`Failed to flush logs on error: ${flushErr}`);
|
|
1396
|
+
}
|
|
1397
|
+
// Clear output buffer
|
|
1398
|
+
clearOutputBuffer(commandId);
|
|
1399
|
+
// Clean up attachment temp files
|
|
1400
|
+
if (attachmentCleanup) {
|
|
1401
|
+
attachmentCleanup();
|
|
1402
|
+
}
|
|
1403
|
+
if (err.message.includes('ENOENT')) {
|
|
1404
|
+
sendError(channel, commandId, 'Claude CLI not found. Please install it with: npm install -g @anthropic-ai/claude-code', 'CLAUDE_NOT_FOUND');
|
|
1405
|
+
}
|
|
1406
|
+
else {
|
|
1407
|
+
sendError(channel, commandId, err.message);
|
|
1408
|
+
}
|
|
1409
|
+
resolveExecution();
|
|
1253
1410
|
});
|
|
1254
|
-
});
|
|
1255
|
-
// Handle errors
|
|
1256
|
-
claude.on('error', async (err) => {
|
|
1257
|
-
runningProcesses.delete(commandId);
|
|
1258
|
-
if (promptId)
|
|
1259
|
-
promptIdToCommandId.delete(promptId);
|
|
1260
|
-
pendingSupervisionCallbacks.delete(commandId);
|
|
1261
|
-
logger.error(`Execution error: ${err.message}`);
|
|
1262
|
-
// Add error log entry
|
|
1263
|
-
addLog(promptId, 'error', 'system', `Execution error: ${err.message}`);
|
|
1264
|
-
// Stop log persistence and flush remaining logs
|
|
1265
|
-
stopLogPersistence(promptId);
|
|
1266
|
-
try {
|
|
1267
|
-
await flushLogs(promptId);
|
|
1268
|
-
}
|
|
1269
|
-
catch (flushErr) {
|
|
1270
|
-
logger.error(`Failed to flush logs on error: ${flushErr}`);
|
|
1271
|
-
}
|
|
1272
|
-
// Clear output buffer
|
|
1273
|
-
clearOutputBuffer(commandId);
|
|
1274
|
-
// Clean up attachment temp files
|
|
1275
|
-
if (attachmentCleanup) {
|
|
1276
|
-
attachmentCleanup();
|
|
1277
|
-
}
|
|
1278
|
-
if (err.message.includes('ENOENT')) {
|
|
1279
|
-
sendError(channel, commandId, 'Claude CLI not found. Please install it with: npm install -g @anthropic-ai/claude-code', 'CLAUDE_NOT_FOUND');
|
|
1280
|
-
}
|
|
1281
|
-
else {
|
|
1282
|
-
sendError(channel, commandId, err.message);
|
|
1283
|
-
}
|
|
1284
1411
|
});
|
|
1285
1412
|
}
|
|
1286
1413
|
// Handle a detected permission request
|
|
@@ -1425,8 +1552,11 @@ Return ONLY valid JSON in this exact format (no markdown, no explanation):
|
|
|
1425
1552
|
}
|
|
1426
1553
|
// Escape content for shell
|
|
1427
1554
|
const escapedContent = evaluationPrompt.replace(/'/g, "'\\''");
|
|
1428
|
-
//
|
|
1429
|
-
const
|
|
1555
|
+
// Use selected CLI
|
|
1556
|
+
const { cli: selectedCli } = selectCli();
|
|
1557
|
+
const cliCommand = selectedCli || 'claude';
|
|
1558
|
+
// Run CLI for evaluation (quick, no permissions needed)
|
|
1559
|
+
const command = `${cliCommand} -p '${escapedContent}' --dangerously-skip-permissions --output-format text`;
|
|
1430
1560
|
const { execSync } = await import('child_process');
|
|
1431
1561
|
try {
|
|
1432
1562
|
const output = execSync(`script -q -c "${command.replace(/"/g, '\\"')}" /dev/null`, {
|
|
@@ -1631,8 +1761,11 @@ export async function generatePlanItems(options) {
|
|
|
1631
1761
|
}
|
|
1632
1762
|
// Escape content for shell - handle single quotes properly
|
|
1633
1763
|
const escapedContent = prompt.replace(/'/g, "'\"'\"'");
|
|
1634
|
-
//
|
|
1635
|
-
const
|
|
1764
|
+
// Use selected CLI
|
|
1765
|
+
const { cli: selectedCli } = selectCli();
|
|
1766
|
+
const cliCommand = selectedCli || 'claude';
|
|
1767
|
+
// Run CLI for generation (quick, no permissions needed)
|
|
1768
|
+
const command = `${cliCommand} -p '${escapedContent}' --dangerously-skip-permissions --output-format text`;
|
|
1636
1769
|
logger.debug(`Running Claude CLI...`);
|
|
1637
1770
|
try {
|
|
1638
1771
|
const output = execSync(`script -q -c "${command.replace(/"/g, '\\"')}" /dev/null`, {
|
|
@@ -1724,10 +1857,13 @@ export function startSession(options) {
|
|
|
1724
1857
|
if (anthropicApiKey) {
|
|
1725
1858
|
env.ANTHROPIC_API_KEY = anthropicApiKey;
|
|
1726
1859
|
}
|
|
1727
|
-
//
|
|
1860
|
+
// Use selected CLI
|
|
1861
|
+
const { cli: selectedCli } = selectCli();
|
|
1862
|
+
const cliCommand = selectedCli || 'claude';
|
|
1863
|
+
// Spawn CLI in interactive mode with PTY
|
|
1728
1864
|
// Using script command to provide a proper TTY
|
|
1729
1865
|
// Wrap with stdbuf to disable output buffering for real-time streaming
|
|
1730
|
-
const claude = spawn('script', ['-q', '-c',
|
|
1866
|
+
const claude = spawn('script', ['-q', '-c', `stdbuf -oL -eL ${cliCommand} --dangerously-skip-permissions`, '/dev/null'], {
|
|
1731
1867
|
cwd,
|
|
1732
1868
|
env,
|
|
1733
1869
|
stdio: ['pipe', 'pipe', 'pipe'],
|