codeep 1.3.40 → 1.3.42
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/acp/server.js +40 -45
- package/dist/acp/transport.js +26 -6
- package/dist/config/index.js +1 -1
- package/dist/utils/tokenTracker.js +0 -4
- package/package.json +1 -1
package/dist/acp/server.js
CHANGED
|
@@ -402,19 +402,17 @@ export function startAcpServer() {
|
|
|
402
402
|
transport.respond(msg.id, result);
|
|
403
403
|
}
|
|
404
404
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
},
|
|
417
|
-
});
|
|
405
|
+
// Title hint to the client. The ACP spec does NOT define a
|
|
406
|
+
// `session_info_update` variant — sending it caused Zed's internally-tagged
|
|
407
|
+
// SessionUpdate deserializer to reject the notification, which (depending
|
|
408
|
+
// on client recovery logic) could swallow following valid notifications
|
|
409
|
+
// like `available_commands_update`. We now no-op here and rely on
|
|
410
|
+
// session/list (which has a proper `title` field per spec) for any
|
|
411
|
+
// client-side session naming. Kept as a function with no body so callers
|
|
412
|
+
// don't need to be touched — easy to wire back up via `_meta` extension if
|
|
413
|
+
// a future client needs an explicit hint.
|
|
414
|
+
function sendSessionTitle(_sessionId, _history, _fallback) {
|
|
415
|
+
// intentionally empty — see comment above
|
|
418
416
|
}
|
|
419
417
|
// ── session/new ─────────────────────────────────────────────────────────────
|
|
420
418
|
function handleSessionNew(msg) {
|
|
@@ -438,14 +436,14 @@ export function startAcpServer() {
|
|
|
438
436
|
configOptions: buildConfigOptions(),
|
|
439
437
|
};
|
|
440
438
|
transport.respond(msg.id, result);
|
|
441
|
-
// Advertise slash commands
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
439
|
+
// Advertise slash commands AFTER a short delay. Zed processes
|
|
440
|
+
// `AvailableCommandsUpdated` events synchronously and silently drops them
|
|
441
|
+
// if `thread_view(&session_id)` returns None — which is the case for ~tens
|
|
442
|
+
// of ms after session/new response is sent (Zed needs to spin up the view
|
|
443
|
+
// in a separate task). Without the delay the notification arrives ~1 ms
|
|
444
|
+
// after the response and gets lost, which manifests as
|
|
445
|
+
// "Available commands: none" in the slash menu.
|
|
446
|
+
sendCommandsDelayed(acpSessionId);
|
|
449
447
|
// Send title immediately so Zed "Recent" panel shows something useful
|
|
450
448
|
sendSessionTitle(acpSessionId, history, pathBasename(params.cwd));
|
|
451
449
|
// Send welcome message
|
|
@@ -457,6 +455,21 @@ export function startAcpServer() {
|
|
|
457
455
|
},
|
|
458
456
|
});
|
|
459
457
|
}
|
|
458
|
+
// Delay configurable via env so we can experimentally tune in production.
|
|
459
|
+
// 200 ms is comfortably above the observed ~1 ms race window without
|
|
460
|
+
// making the slash menu feel laggy on first paint.
|
|
461
|
+
const COMMANDS_DELAY_MS = Number(process.env.CODEEP_ACP_COMMANDS_DELAY_MS ?? 200);
|
|
462
|
+
function sendCommandsDelayed(sessionId) {
|
|
463
|
+
setTimeout(() => {
|
|
464
|
+
transport.notify('session/update', {
|
|
465
|
+
sessionId,
|
|
466
|
+
update: {
|
|
467
|
+
sessionUpdate: 'available_commands_update',
|
|
468
|
+
availableCommands: AVAILABLE_COMMANDS,
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
}, COMMANDS_DELAY_MS);
|
|
472
|
+
}
|
|
460
473
|
// ── session/load ────────────────────────────────────────────────────────────
|
|
461
474
|
function handleSessionLoad(msg) {
|
|
462
475
|
const params = msg.params;
|
|
@@ -493,16 +506,9 @@ export function startAcpServer() {
|
|
|
493
506
|
configOptions: buildConfigOptions(),
|
|
494
507
|
};
|
|
495
508
|
transport.respond(msg.id, result);
|
|
496
|
-
// Re-advertise
|
|
497
|
-
//
|
|
498
|
-
|
|
499
|
-
transport.notify('session/update', {
|
|
500
|
-
sessionId: acpSessionId,
|
|
501
|
-
update: {
|
|
502
|
-
sessionUpdate: 'available_commands_update',
|
|
503
|
-
availableCommands: AVAILABLE_COMMANDS,
|
|
504
|
-
},
|
|
505
|
-
});
|
|
509
|
+
// Re-advertise commands (delayed for the same race-condition reason as
|
|
510
|
+
// session/new — see sendCommandsDelayed comment).
|
|
511
|
+
sendCommandsDelayed(acpSessionId);
|
|
506
512
|
// Send title immediately so Zed "Recent" panel shows something useful
|
|
507
513
|
sendSessionTitle(params.sessionId, history, pathBasename(params.cwd));
|
|
508
514
|
// Send restored session welcome
|
|
@@ -521,18 +527,6 @@ export function startAcpServer() {
|
|
|
521
527
|
// Falls back to `session/load` semantics if the session isn't in memory yet.
|
|
522
528
|
function handleSessionResume(msg) {
|
|
523
529
|
const params = msg.params;
|
|
524
|
-
// Helper — re-advertise commands so `/` autocomplete works after a panel
|
|
525
|
-
// reload. Without this the slash menu stays empty until a new session is
|
|
526
|
-
// created. Same notification shape as session/new.
|
|
527
|
-
const advertiseCommands = (sessionId) => {
|
|
528
|
-
transport.notify('session/update', {
|
|
529
|
-
sessionId,
|
|
530
|
-
update: {
|
|
531
|
-
sessionUpdate: 'available_commands_update',
|
|
532
|
-
availableCommands: AVAILABLE_COMMANDS,
|
|
533
|
-
},
|
|
534
|
-
});
|
|
535
|
-
};
|
|
536
530
|
const existing = sessions.get(params.sessionId);
|
|
537
531
|
if (existing) {
|
|
538
532
|
existing.workspaceRoot = params.cwd;
|
|
@@ -542,7 +536,8 @@ export function startAcpServer() {
|
|
|
542
536
|
configOptions: buildConfigOptions(),
|
|
543
537
|
};
|
|
544
538
|
transport.respond(msg.id, result);
|
|
545
|
-
|
|
539
|
+
// Delayed — see sendCommandsDelayed comment for the race-condition rationale.
|
|
540
|
+
sendCommandsDelayed(params.sessionId);
|
|
546
541
|
return;
|
|
547
542
|
}
|
|
548
543
|
// Session not in memory — load from disk but skip the welcome banner and
|
|
@@ -566,7 +561,7 @@ export function startAcpServer() {
|
|
|
566
561
|
configOptions: buildConfigOptions(),
|
|
567
562
|
};
|
|
568
563
|
transport.respond(msg.id, result);
|
|
569
|
-
|
|
564
|
+
sendCommandsDelayed(acpSessionId);
|
|
570
565
|
}
|
|
571
566
|
// ── session/set_mode ────────────────────────────────────────────────────────
|
|
572
567
|
function handleSetMode(msg) {
|
package/dist/acp/transport.js
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
// acp/transport.ts
|
|
2
2
|
// Newline-delimited JSON-RPC over stdio
|
|
3
|
+
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { join, dirname } from 'node:path';
|
|
6
|
+
// Debug log destination — when CODEEP_ACP_DEBUG is set we mirror every
|
|
7
|
+
// inbound and outbound JSON-RPC frame here. Using a file (not stderr) because
|
|
8
|
+
// most ACP clients (Zed included) do not pipe agent stderr to anywhere the
|
|
9
|
+
// user can easily read; a known on-disk path is reliable everywhere.
|
|
10
|
+
const ACP_DEBUG_PATH = process.env.CODEEP_ACP_DEBUG_FILE
|
|
11
|
+
|| join(homedir(), '.cache', 'codeep', 'acp-debug.log');
|
|
12
|
+
const ACP_DEBUG = !!process.env.CODEEP_ACP_DEBUG;
|
|
13
|
+
if (ACP_DEBUG) {
|
|
14
|
+
try {
|
|
15
|
+
mkdirSync(dirname(ACP_DEBUG_PATH), { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
catch { /* ignore */ }
|
|
18
|
+
}
|
|
19
|
+
function debugLog(direction, payload) {
|
|
20
|
+
if (!ACP_DEBUG)
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
appendFileSync(ACP_DEBUG_PATH, `${new Date().toISOString()} [ACP${direction}client] ${payload}\n`);
|
|
24
|
+
}
|
|
25
|
+
catch { /* swallow — never break the protocol over a logging failure */ }
|
|
26
|
+
}
|
|
3
27
|
const MAX_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
|
|
4
28
|
const REQUEST_TIMEOUT_MS = 30_000; // 30s
|
|
5
29
|
export class StdioTransport {
|
|
@@ -26,9 +50,7 @@ export class StdioTransport {
|
|
|
26
50
|
if (!trimmed)
|
|
27
51
|
continue;
|
|
28
52
|
try {
|
|
29
|
-
|
|
30
|
-
process.stderr.write(`[ACP←client] ${trimmed}\n`);
|
|
31
|
-
}
|
|
53
|
+
debugLog('←', trimmed);
|
|
32
54
|
const msg = JSON.parse(trimmed);
|
|
33
55
|
// Check if this is a response to one of our outbound requests
|
|
34
56
|
if ('result' in msg || 'error' in msg) {
|
|
@@ -49,9 +71,7 @@ export class StdioTransport {
|
|
|
49
71
|
}
|
|
50
72
|
send(msg) {
|
|
51
73
|
const line = JSON.stringify(msg);
|
|
52
|
-
|
|
53
|
-
process.stderr.write(`[ACP→client] ${line}\n`);
|
|
54
|
-
}
|
|
74
|
+
debugLog('→', line);
|
|
55
75
|
process.stdout.write(line + '\n');
|
|
56
76
|
}
|
|
57
77
|
respond(id, result) {
|
package/dist/config/index.js
CHANGED
|
@@ -7,8 +7,6 @@ const MODEL_CONTEXT_WINDOWS = {
|
|
|
7
7
|
'glm-5.1': 131_072,
|
|
8
8
|
'glm-5': 80_000,
|
|
9
9
|
'glm-5-turbo': 202_752,
|
|
10
|
-
'glm-4.5-air': 131_072,
|
|
11
|
-
'glm-4.7-flash': 202_752,
|
|
12
10
|
// OpenAI
|
|
13
11
|
'gpt-5.5': 1_200_000,
|
|
14
12
|
'gpt-5.4': 1_050_000,
|
|
@@ -58,8 +56,6 @@ const MODEL_PRICING = {
|
|
|
58
56
|
'glm-5.1': { inputPer1M: 1.00, outputPer1M: 3.20 },
|
|
59
57
|
'glm-5': { inputPer1M: 0.72, outputPer1M: 2.30 },
|
|
60
58
|
'glm-5-turbo': { inputPer1M: 1.20, outputPer1M: 4.00 },
|
|
61
|
-
'glm-4.5-air': { inputPer1M: 0.20, outputPer1M: 1.10 },
|
|
62
|
-
'glm-4.7-flash': { inputPer1M: 0.06, outputPer1M: 0.40 },
|
|
63
59
|
// OpenAI
|
|
64
60
|
'gpt-5.5': { inputPer1M: 5.00, outputPer1M: 30.00 },
|
|
65
61
|
'gpt-5.4': { inputPer1M: 2.50, outputPer1M: 15.00 },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.42",
|
|
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",
|