codeep 1.2.74 → 1.2.75
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/README.md +1 -1
- package/dist/acp/protocol.d.ts +54 -1
- package/dist/acp/server.js +88 -0
- package/dist/acp/session.d.ts +8 -0
- package/dist/acp/session.js +2 -0
- package/dist/acp/transport.d.ts +7 -0
- package/dist/acp/transport.js +23 -0
- package/dist/config/index.js +1 -1
- package/dist/renderer/components/Settings.js +1 -1
- package/dist/utils/agent.d.ts +7 -0
- package/dist/utils/agent.js +57 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -681,7 +681,7 @@ With write access enabled:
|
|
|
681
681
|
| Agent Mode | ON | `ON` = agent runs automatically (requires write permission via `/grant`), `Manual` = use /agent |
|
|
682
682
|
| Agent API Timeout | 180000ms | Timeout per agent API call (auto-adjusted for complexity) |
|
|
683
683
|
| Agent Max Duration | 20 min | Maximum time for agent to run (5-60 min) |
|
|
684
|
-
| Agent Max Iterations |
|
|
684
|
+
| Agent Max Iterations | 200 | Maximum agent iterations (10-500) |
|
|
685
685
|
| Agent Confirmation | Dangerous | `Never`, `Dangerous` (default), or `Always` |
|
|
686
686
|
| Agent Auto-Commit | Off | Automatically commit after agent completes |
|
|
687
687
|
| Agent Branch | Off | Create new branch for agent commits |
|
package/dist/acp/protocol.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export interface InitializeParams {
|
|
|
34
34
|
}
|
|
35
35
|
export interface AgentCapabilities {
|
|
36
36
|
loadSession?: boolean;
|
|
37
|
+
terminal?: boolean;
|
|
37
38
|
promptCapabilities?: {
|
|
38
39
|
image?: boolean;
|
|
39
40
|
audio?: boolean;
|
|
@@ -174,7 +175,17 @@ export interface SessionUpdateSessionInfo {
|
|
|
174
175
|
title: string;
|
|
175
176
|
updatedAt?: string;
|
|
176
177
|
}
|
|
177
|
-
export
|
|
178
|
+
export interface PlanEntry {
|
|
179
|
+
id: string;
|
|
180
|
+
content: string;
|
|
181
|
+
priority: 'high' | 'medium' | 'low';
|
|
182
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
183
|
+
}
|
|
184
|
+
export interface SessionUpdatePlan {
|
|
185
|
+
sessionUpdate: 'plan';
|
|
186
|
+
entries: PlanEntry[];
|
|
187
|
+
}
|
|
188
|
+
export type SessionUpdateInner = SessionUpdateAgentMessageChunk | SessionUpdateAgentThoughtChunk | SessionUpdateToolCall | SessionUpdateToolCallUpdate | SessionUpdatePlan | SessionUpdateAvailableCommands | SessionUpdateCurrentMode | SessionUpdateConfigOption | SessionUpdateSessionInfo;
|
|
178
189
|
export interface SessionUpdateParams {
|
|
179
190
|
sessionId: string;
|
|
180
191
|
update: SessionUpdateInner;
|
|
@@ -237,4 +248,46 @@ export interface FsWriteTextFileParams {
|
|
|
237
248
|
path: string;
|
|
238
249
|
content: string;
|
|
239
250
|
}
|
|
251
|
+
export interface TerminalCreateParams {
|
|
252
|
+
sessionId: string;
|
|
253
|
+
command: string;
|
|
254
|
+
args: string[];
|
|
255
|
+
cwd: string;
|
|
256
|
+
env?: Record<string, string>;
|
|
257
|
+
outputByteLimit?: number;
|
|
258
|
+
}
|
|
259
|
+
export interface TerminalCreateResult {
|
|
260
|
+
terminalId: string;
|
|
261
|
+
}
|
|
262
|
+
export interface TerminalWaitForExitParams {
|
|
263
|
+
sessionId: string;
|
|
264
|
+
terminalId: string;
|
|
265
|
+
timeoutMs?: number;
|
|
266
|
+
}
|
|
267
|
+
export type TerminalExitStatus = {
|
|
268
|
+
type: 'exited';
|
|
269
|
+
code: number;
|
|
270
|
+
} | {
|
|
271
|
+
type: 'killed';
|
|
272
|
+
signal?: string;
|
|
273
|
+
};
|
|
274
|
+
export interface TerminalWaitForExitResult {
|
|
275
|
+
exitStatus: TerminalExitStatus;
|
|
276
|
+
}
|
|
277
|
+
export interface TerminalOutputParams {
|
|
278
|
+
sessionId: string;
|
|
279
|
+
terminalId: string;
|
|
280
|
+
offset?: number;
|
|
281
|
+
}
|
|
282
|
+
export interface TerminalOutputResult {
|
|
283
|
+
output: string;
|
|
284
|
+
/** Absent while the process is still running; present once the process has exited. */
|
|
285
|
+
exitStatus?: TerminalExitStatus;
|
|
286
|
+
}
|
|
287
|
+
export interface TerminalReleaseParams {
|
|
288
|
+
sessionId: string;
|
|
289
|
+
terminalId: string;
|
|
290
|
+
}
|
|
291
|
+
export interface TerminalReleaseResult {
|
|
292
|
+
}
|
|
240
293
|
export type AcpMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;
|
package/dist/acp/server.js
CHANGED
|
@@ -4,6 +4,7 @@ import { randomUUID } from 'crypto';
|
|
|
4
4
|
import { basename as pathBasename } from 'path';
|
|
5
5
|
import { StdioTransport } from './transport.js';
|
|
6
6
|
import { runAgentSession } from './session.js';
|
|
7
|
+
import { executeCommandAsync } from '../utils/shell.js';
|
|
7
8
|
import { initWorkspace, loadWorkspace, handleCommand } from './commands.js';
|
|
8
9
|
import { autoSaveSession, config, setProvider, listSessionsWithInfo, deleteSession as deleteSessionFile } from '../config/index.js';
|
|
9
10
|
import { PROVIDERS } from '../config/providers.js';
|
|
@@ -165,6 +166,7 @@ export function startAcpServer() {
|
|
|
165
166
|
protocolVersion: 1,
|
|
166
167
|
agentCapabilities: {
|
|
167
168
|
loadSession: true,
|
|
169
|
+
terminal: true,
|
|
168
170
|
sessionCapabilities: { list: {} },
|
|
169
171
|
},
|
|
170
172
|
agentInfo: {
|
|
@@ -381,6 +383,18 @@ export function startAcpServer() {
|
|
|
381
383
|
.join('\n');
|
|
382
384
|
const abortController = new AbortController();
|
|
383
385
|
session.abortController = abortController;
|
|
386
|
+
// Plan tracking: build a live plan from tool calls as the agent works
|
|
387
|
+
// ACP spec: send complete list on every update, client replaces current plan
|
|
388
|
+
const planEntries = new Map();
|
|
389
|
+
const sendPlan = () => {
|
|
390
|
+
transport.notify('session/update', {
|
|
391
|
+
sessionId: params.sessionId,
|
|
392
|
+
update: {
|
|
393
|
+
sessionUpdate: 'plan',
|
|
394
|
+
entries: [...planEntries.values()],
|
|
395
|
+
},
|
|
396
|
+
});
|
|
397
|
+
};
|
|
384
398
|
const agentResponseChunks = [];
|
|
385
399
|
const sendChunk = (text) => {
|
|
386
400
|
agentResponseChunks.push(text);
|
|
@@ -456,6 +470,16 @@ export function startAcpServer() {
|
|
|
456
470
|
: {}),
|
|
457
471
|
},
|
|
458
472
|
});
|
|
473
|
+
// Add to plan as in_progress — only meaningful actions (not reads)
|
|
474
|
+
if (kind === 'edit' || kind === 'execute' || kind === 'delete') {
|
|
475
|
+
planEntries.set(toolCallId, {
|
|
476
|
+
id: toolCallId,
|
|
477
|
+
content: title || toolName,
|
|
478
|
+
priority: kind === 'execute' ? 'high' : 'medium',
|
|
479
|
+
status: 'in_progress',
|
|
480
|
+
});
|
|
481
|
+
sendPlan();
|
|
482
|
+
}
|
|
459
483
|
}
|
|
460
484
|
else {
|
|
461
485
|
// tool_call_update: update status to completed/failed, with optional content
|
|
@@ -468,6 +492,70 @@ export function startAcpServer() {
|
|
|
468
492
|
...(rawOutput !== undefined ? { rawOutput } : {}),
|
|
469
493
|
},
|
|
470
494
|
});
|
|
495
|
+
// Mark plan entry as completed
|
|
496
|
+
const entry = planEntries.get(toolCallId);
|
|
497
|
+
if (entry) {
|
|
498
|
+
entry.status = 'completed';
|
|
499
|
+
sendPlan();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
// Only request permission in Manual mode
|
|
504
|
+
onRequestPermission: session.currentModeId === 'manual'
|
|
505
|
+
? async (toolCall) => {
|
|
506
|
+
const permToolCallId = `perm_${randomUUID()}`;
|
|
507
|
+
const result = await transport.request('session/request_permission', {
|
|
508
|
+
sessionId: params.sessionId,
|
|
509
|
+
toolCall: {
|
|
510
|
+
toolCallId: permToolCallId,
|
|
511
|
+
toolName: toolCall.tool,
|
|
512
|
+
toolInput: toolCall.parameters,
|
|
513
|
+
status: 'pending',
|
|
514
|
+
content: [],
|
|
515
|
+
},
|
|
516
|
+
options: [
|
|
517
|
+
{ optionId: 'allow_once', name: 'Allow once', kind: 'allow_once' },
|
|
518
|
+
{ optionId: 'allow_always', name: 'Allow always', kind: 'allow_always' },
|
|
519
|
+
{ optionId: 'reject_once', name: 'Reject once', kind: 'reject_once' },
|
|
520
|
+
{ optionId: 'reject_always', name: 'Reject always', kind: 'reject_always' },
|
|
521
|
+
],
|
|
522
|
+
});
|
|
523
|
+
// Map ACP outcome back to PermissionOutcome
|
|
524
|
+
if (!result || result.outcome.type === 'cancelled')
|
|
525
|
+
return 'reject_once';
|
|
526
|
+
return result.outcome.optionId;
|
|
527
|
+
}
|
|
528
|
+
: undefined,
|
|
529
|
+
onExecuteCommand: async (command, args, cwd) => {
|
|
530
|
+
try {
|
|
531
|
+
const createResult = await transport.request('terminal/create', {
|
|
532
|
+
sessionId: params.sessionId,
|
|
533
|
+
command,
|
|
534
|
+
args,
|
|
535
|
+
cwd,
|
|
536
|
+
outputByteLimit: 1_000_000,
|
|
537
|
+
});
|
|
538
|
+
const { terminalId } = createResult;
|
|
539
|
+
const waitResult = await transport.request('terminal/waitForExit', {
|
|
540
|
+
sessionId: params.sessionId,
|
|
541
|
+
terminalId,
|
|
542
|
+
timeoutMs: 120_000,
|
|
543
|
+
});
|
|
544
|
+
const outputResult = await transport.request('terminal/output', {
|
|
545
|
+
sessionId: params.sessionId,
|
|
546
|
+
terminalId,
|
|
547
|
+
});
|
|
548
|
+
await transport.request('terminal/release', {
|
|
549
|
+
sessionId: params.sessionId,
|
|
550
|
+
terminalId,
|
|
551
|
+
});
|
|
552
|
+
const exitCode = waitResult.exitStatus.type === 'exited' ? waitResult.exitStatus.code : 1;
|
|
553
|
+
return { stdout: outputResult.output ?? '', stderr: '', exitCode };
|
|
554
|
+
}
|
|
555
|
+
catch (err) {
|
|
556
|
+
// Zed terminal unavailable — fall back to local execution
|
|
557
|
+
const r = await executeCommandAsync(command, args, { cwd, projectRoot: cwd, timeout: 120000 });
|
|
558
|
+
return { stdout: r.stdout ?? '', stderr: r.stderr ?? '', exitCode: r.exitCode ?? 0 };
|
|
471
559
|
}
|
|
472
560
|
},
|
|
473
561
|
}).then(() => {
|
package/dist/acp/session.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { PermissionOutcome } from '../utils/agent.js';
|
|
1
2
|
import { ProjectContext } from '../utils/project.js';
|
|
3
|
+
import { ToolCall } from '../utils/tools.js';
|
|
2
4
|
export interface AgentSessionOptions {
|
|
3
5
|
prompt: string;
|
|
4
6
|
workspaceRoot: string;
|
|
@@ -7,6 +9,12 @@ export interface AgentSessionOptions {
|
|
|
7
9
|
onChunk: (text: string) => void;
|
|
8
10
|
onThought?: (text: string) => void;
|
|
9
11
|
onToolCall?: (toolCallId: string, toolName: string, kind: string, title: string, status: 'pending' | 'running' | 'finished' | 'error', locations?: string[], rawOutput?: string) => void;
|
|
12
|
+
onRequestPermission?: (toolCall: ToolCall) => Promise<PermissionOutcome>;
|
|
13
|
+
onExecuteCommand?: (command: string, args: string[], cwd: string) => Promise<{
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}>;
|
|
10
18
|
}
|
|
11
19
|
/**
|
|
12
20
|
* Build a ProjectContext from a workspace root directory.
|
package/dist/acp/session.js
CHANGED
|
@@ -140,6 +140,8 @@ export async function runAgentSession(opts) {
|
|
|
140
140
|
toolCallIdMap.delete(mapKey);
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
|
+
onRequestPermission: opts.onRequestPermission,
|
|
144
|
+
onExecuteCommand: opts.onExecuteCommand,
|
|
143
145
|
});
|
|
144
146
|
// result.finalResponse is already emitted via onChunk streaming above;
|
|
145
147
|
// only emit it here if nothing was streamed (e.g. non-streaming fallback path)
|
package/dist/acp/transport.d.ts
CHANGED
|
@@ -3,11 +3,18 @@ type MessageHandler = (msg: JsonRpcRequest | JsonRpcNotification) => void;
|
|
|
3
3
|
export declare class StdioTransport {
|
|
4
4
|
private buffer;
|
|
5
5
|
private handler;
|
|
6
|
+
private pendingRequests;
|
|
7
|
+
private requestIdCounter;
|
|
6
8
|
start(handler: MessageHandler): void;
|
|
7
9
|
private onData;
|
|
8
10
|
send(msg: JsonRpcResponse | JsonRpcNotification): void;
|
|
9
11
|
respond(id: number | string, result: unknown): void;
|
|
10
12
|
error(id: number | string, code: number, message: string): void;
|
|
11
13
|
notify(method: string, params: unknown): void;
|
|
14
|
+
/**
|
|
15
|
+
* Send a JSON-RPC request to the client and wait for the response.
|
|
16
|
+
* Used for agent-initiated requests like session/request_permission.
|
|
17
|
+
*/
|
|
18
|
+
request(method: string, params: unknown): Promise<unknown>;
|
|
12
19
|
}
|
|
13
20
|
export {};
|
package/dist/acp/transport.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
export class StdioTransport {
|
|
4
4
|
buffer = '';
|
|
5
5
|
handler = null;
|
|
6
|
+
pendingRequests = new Map();
|
|
7
|
+
requestIdCounter = 1000;
|
|
6
8
|
start(handler) {
|
|
7
9
|
this.handler = handler;
|
|
8
10
|
process.stdin.setEncoding('utf8');
|
|
@@ -19,6 +21,16 @@ export class StdioTransport {
|
|
|
19
21
|
continue;
|
|
20
22
|
try {
|
|
21
23
|
const msg = JSON.parse(trimmed);
|
|
24
|
+
// Check if this is a response to one of our outbound requests
|
|
25
|
+
if ('result' in msg || 'error' in msg) {
|
|
26
|
+
const response = msg;
|
|
27
|
+
const resolve = this.pendingRequests.get(response.id);
|
|
28
|
+
if (resolve) {
|
|
29
|
+
this.pendingRequests.delete(response.id);
|
|
30
|
+
resolve(response.result ?? null);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
22
34
|
this.handler?.(msg);
|
|
23
35
|
}
|
|
24
36
|
catch {
|
|
@@ -38,4 +50,15 @@ export class StdioTransport {
|
|
|
38
50
|
notify(method, params) {
|
|
39
51
|
this.send({ jsonrpc: '2.0', method, params });
|
|
40
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Send a JSON-RPC request to the client and wait for the response.
|
|
55
|
+
* Used for agent-initiated requests like session/request_permission.
|
|
56
|
+
*/
|
|
57
|
+
request(method, params) {
|
|
58
|
+
const id = ++this.requestIdCounter;
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
this.pendingRequests.set(id, resolve);
|
|
61
|
+
process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
41
64
|
}
|
package/dist/config/index.js
CHANGED
|
@@ -148,7 +148,7 @@ function createConfig() {
|
|
|
148
148
|
agentAutoCommitBranch: false,
|
|
149
149
|
agentAutoVerify: 'off',
|
|
150
150
|
agentMaxFixAttempts: 3,
|
|
151
|
-
agentMaxIterations:
|
|
151
|
+
agentMaxIterations: 200,
|
|
152
152
|
agentMaxDuration: 20,
|
|
153
153
|
agentApiTimeout: 180000,
|
|
154
154
|
protocol: 'openai',
|
package/dist/utils/agent.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { ToolCall, ToolResult, ActionLog } from './tools';
|
|
|
12
12
|
import { undoLastAction, undoAllActions, getCurrentSession, getRecentSessions, formatSession, ActionSession } from './history';
|
|
13
13
|
import { VerifyResult } from './verify';
|
|
14
14
|
import { TaskPlan, SubTask } from './taskPlanner';
|
|
15
|
+
export type PermissionOutcome = 'allow_once' | 'allow_always' | 'reject_once' | 'reject_always';
|
|
15
16
|
export interface AgentOptions {
|
|
16
17
|
maxIterations: number;
|
|
17
18
|
maxDuration: number;
|
|
@@ -23,6 +24,12 @@ export interface AgentOptions {
|
|
|
23
24
|
onVerification?: (results: VerifyResult[]) => void;
|
|
24
25
|
onTaskPlan?: (plan: TaskPlan) => void;
|
|
25
26
|
onTaskUpdate?: (task: SubTask) => void;
|
|
27
|
+
onRequestPermission?: (toolCall: ToolCall) => Promise<PermissionOutcome>;
|
|
28
|
+
onExecuteCommand?: (command: string, args: string[], cwd: string) => Promise<{
|
|
29
|
+
stdout: string;
|
|
30
|
+
stderr: string;
|
|
31
|
+
exitCode: number;
|
|
32
|
+
}>;
|
|
26
33
|
abortSignal?: AbortSignal;
|
|
27
34
|
dryRun?: boolean;
|
|
28
35
|
autoVerify?: 'off' | 'build' | 'typecheck' | 'test' | 'all' | boolean;
|
package/dist/utils/agent.js
CHANGED
|
@@ -176,6 +176,10 @@ export async function runAgent(prompt, projectContext, options = {}) {
|
|
|
176
176
|
let consecutiveTimeouts = 0;
|
|
177
177
|
let incompleteWorkRetries = 0;
|
|
178
178
|
const maxIncompleteWorkRetries = 2;
|
|
179
|
+
// Track tools permanently allowed this session via allow_always
|
|
180
|
+
const alwaysAllowedTools = new Set();
|
|
181
|
+
// Tools that require permission when onRequestPermission is set
|
|
182
|
+
const dangerousTools = new Set(['delete_file', 'execute_command']);
|
|
179
183
|
const maxTimeoutRetries = 3;
|
|
180
184
|
const maxConsecutiveTimeouts = 9; // Allow more consecutive timeouts before giving up
|
|
181
185
|
const baseTimeout = config.get('agentApiTimeout');
|
|
@@ -376,9 +380,28 @@ export async function runAgent(prompt, projectContext, options = {}) {
|
|
|
376
380
|
const toolResults = [];
|
|
377
381
|
for (const toolCall of toolCalls) {
|
|
378
382
|
opts.onToolCall?.(toolCall);
|
|
383
|
+
// Permission check for dangerous tools (only when callback is provided, e.g. ACP/Zed)
|
|
384
|
+
if (opts.onRequestPermission && dangerousTools.has(toolCall.tool) && !alwaysAllowedTools.has(toolCall.tool)) {
|
|
385
|
+
const outcome = await opts.onRequestPermission(toolCall);
|
|
386
|
+
if (outcome === 'allow_always') {
|
|
387
|
+
alwaysAllowedTools.add(toolCall.tool);
|
|
388
|
+
}
|
|
389
|
+
else if (outcome === 'reject_once' || outcome === 'reject_always') {
|
|
390
|
+
const toolResult = {
|
|
391
|
+
success: false,
|
|
392
|
+
output: '',
|
|
393
|
+
error: `User rejected permission for ${toolCall.tool}`,
|
|
394
|
+
tool: toolCall.tool,
|
|
395
|
+
parameters: toolCall.parameters,
|
|
396
|
+
};
|
|
397
|
+
opts.onToolResult?.(toolResult, toolCall);
|
|
398
|
+
actions.push(createActionLog(toolCall, toolResult));
|
|
399
|
+
toolResults.push(`Tool ${toolCall.tool} was rejected by user.`);
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
379
403
|
let toolResult;
|
|
380
404
|
if (opts.dryRun) {
|
|
381
|
-
// In dry run mode, simulate success
|
|
382
405
|
toolResult = {
|
|
383
406
|
success: true,
|
|
384
407
|
output: `[DRY RUN] Would execute: ${toolCall.tool}`,
|
|
@@ -386,8 +409,40 @@ export async function runAgent(prompt, projectContext, options = {}) {
|
|
|
386
409
|
parameters: toolCall.parameters,
|
|
387
410
|
};
|
|
388
411
|
}
|
|
412
|
+
else if (opts.onExecuteCommand && toolCall.tool === 'execute_command') {
|
|
413
|
+
// Delegate to external terminal (e.g. Zed ACP terminal)
|
|
414
|
+
// Note: onExecuteCommand runs after the permission gate above
|
|
415
|
+
const command = toolCall.parameters.command;
|
|
416
|
+
const args = toolCall.parameters.args || [];
|
|
417
|
+
const cwd = projectContext.root || process.cwd();
|
|
418
|
+
if (!command) {
|
|
419
|
+
toolResult = {
|
|
420
|
+
success: false,
|
|
421
|
+
output: '',
|
|
422
|
+
error: 'execute_command called with missing command field',
|
|
423
|
+
tool: toolCall.tool,
|
|
424
|
+
parameters: toolCall.parameters,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
try {
|
|
429
|
+
const commandResult = await opts.onExecuteCommand(command, args, cwd);
|
|
430
|
+
toolResult = {
|
|
431
|
+
success: commandResult.exitCode === 0,
|
|
432
|
+
output: commandResult.stdout || '(no output)',
|
|
433
|
+
error: commandResult.exitCode !== 0 ? (commandResult.stderr || `exited with code ${commandResult.exitCode}`) : undefined,
|
|
434
|
+
tool: toolCall.tool,
|
|
435
|
+
parameters: toolCall.parameters,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
catch (err) {
|
|
439
|
+
debug('onExecuteCommand callback threw, falling back to local execution:', err);
|
|
440
|
+
// Fallback to local execution if callback throws
|
|
441
|
+
toolResult = await executeTool(toolCall, cwd);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
389
445
|
else {
|
|
390
|
-
// Actually execute the tool
|
|
391
446
|
toolResult = await executeTool(toolCall, projectContext.root || process.cwd());
|
|
392
447
|
}
|
|
393
448
|
opts.onToolResult?.(toolResult, toolCall);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.75",
|
|
4
4
|
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|