@agentclientprotocol/claude-agent-acp 0.47.0 → 0.49.0
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-agent.d.ts +40 -8
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +283 -74
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +16 -6
- package/package.json +5 -5
package/dist/acp-agent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CanUseTool, ModelInfo, Options, PermissionMode, PermissionUpdate, Query, SDKMessageOrigin, SDKPartialAssistantMessage, SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
1
|
+
import { AuthenticateRequest, CancelNotification, ClientCapabilities, CompleteElicitationNotification, CreateElicitationRequest, CreateElicitationResponse, ForkSessionRequest, ForkSessionResponse, InitializeRequest, InitializeResponse, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, ReadTextFileRequest, ReadTextFileResponse, RequestPermissionRequest, RequestPermissionResponse, ResumeSessionRequest, ResumeSessionResponse, SessionConfigOption, SessionModeState, SessionNotification, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModeRequest, SetSessionModeResponse, CloseSessionRequest, CloseSessionResponse, DeleteSessionRequest, DeleteSessionResponse, WriteTextFileRequest, WriteTextFileResponse } from "@agentclientprotocol/sdk";
|
|
2
|
+
import { AgentInfo, CanUseTool, ModelInfo, Options, PermissionMode, PermissionUpdate, Query, SDKMessageOrigin, SDKPartialAssistantMessage, SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
3
3
|
import { ContentBlockParam } from "@anthropic-ai/sdk/resources";
|
|
4
4
|
import { BetaContentBlock, BetaRawContentBlockDelta } from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
5
5
|
import { SettingsManager } from "./settings.js";
|
|
@@ -89,6 +89,14 @@ type Session = {
|
|
|
89
89
|
models: SessionModelState;
|
|
90
90
|
modelInfos: ModelInfo[];
|
|
91
91
|
configOptions: SessionConfigOption[];
|
|
92
|
+
/** Custom main-thread agent personas the user (or a plugin/project) has
|
|
93
|
+
* configured, discovered via `supportedAgents()` with Claude Code's built-in
|
|
94
|
+
* subagents filtered out. Empty when none are configured, in which case the
|
|
95
|
+
* "agent" config option is omitted entirely. */
|
|
96
|
+
agents: AgentInfo[];
|
|
97
|
+
/** The currently selected main-thread agent name, or "default" for the
|
|
98
|
+
* standard Claude Code agent (no `agent` flag applied). */
|
|
99
|
+
currentAgent: string;
|
|
92
100
|
abortController: AbortController;
|
|
93
101
|
/** Signal the consumer races `query.next()` against. Aborted by cancel()
|
|
94
102
|
* (after a grace period) to force the active turn to settle "cancelled" when
|
|
@@ -237,11 +245,27 @@ export declare function resolvePermissionMode(defaultMode?: unknown, logger?: Lo
|
|
|
237
245
|
* tool so "Always Allow" is never a blank check without disclosure.
|
|
238
246
|
*/
|
|
239
247
|
export declare function describeAlwaysAllow(suggestions: PermissionUpdate[] | undefined, toolName: string): string;
|
|
240
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Client-facing surface the agent calls back into. This is the subset of ACP
|
|
250
|
+
* client methods the agent actually uses, expressed as a narrow interface so
|
|
251
|
+
* tests can supply lightweight mocks. In production it is backed by
|
|
252
|
+
* {@link ClientConnection} over the SDK's typed `AgentContext`.
|
|
253
|
+
*/
|
|
254
|
+
export interface AcpClient {
|
|
255
|
+
sessionUpdate(params: SessionNotification): Promise<void>;
|
|
256
|
+
requestPermission(params: RequestPermissionRequest): Promise<RequestPermissionResponse>;
|
|
257
|
+
readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse>;
|
|
258
|
+
writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse>;
|
|
259
|
+
unstable_createElicitation(params: CreateElicitationRequest): Promise<CreateElicitationResponse>;
|
|
260
|
+
unstable_completeElicitation(params: CompleteElicitationNotification): Promise<void>;
|
|
261
|
+
/** Send a custom (extension) notification, e.g. `_claude/sdkMessage`. */
|
|
262
|
+
extNotification(method: string, params: Record<string, unknown>): Promise<void>;
|
|
263
|
+
}
|
|
264
|
+
export declare class ClaudeAcpAgent {
|
|
241
265
|
sessions: {
|
|
242
266
|
[key: string]: Session;
|
|
243
267
|
};
|
|
244
|
-
client:
|
|
268
|
+
client: AcpClient;
|
|
245
269
|
clientCapabilities?: ClientCapabilities;
|
|
246
270
|
logger: Logger;
|
|
247
271
|
gatewayAuthRequest?: GatewayAuthRequest;
|
|
@@ -249,7 +273,7 @@ export declare class ClaudeAcpAgent implements Agent {
|
|
|
249
273
|
* return "cancelled". See {@link DEFAULT_FORCE_CANCEL_GRACE_MS}. Mutable so
|
|
250
274
|
* tests can shrink it. */
|
|
251
275
|
forceCancelGraceMs: number;
|
|
252
|
-
constructor(client:
|
|
276
|
+
constructor(client: AcpClient, logger?: Logger);
|
|
253
277
|
initialize(request: InitializeRequest): Promise<InitializeResponse>;
|
|
254
278
|
newSession(params: NewSessionRequest): Promise<NewSessionResponse>;
|
|
255
279
|
unstable_forkSession(params: ForkSessionRequest): Promise<ForkSessionResponse>;
|
|
@@ -327,6 +351,14 @@ export declare class ClaudeAcpAgent implements Agent {
|
|
|
327
351
|
private validateCwd;
|
|
328
352
|
private createSession;
|
|
329
353
|
}
|
|
354
|
+
export declare const BUILTIN_AGENT_NAMES: Set<string>;
|
|
355
|
+
export declare const DEFAULT_AGENT_ID = "default";
|
|
356
|
+
/** Discover user/plugin/project-configured main-thread agents, excluding the
|
|
357
|
+
* built-in subagents and the reserved "default" sentinel. Returns an empty
|
|
358
|
+
* list if discovery fails so a flaky control request never blocks session
|
|
359
|
+
* creation. */
|
|
360
|
+
export declare function discoverCustomAgents(q: Query): Promise<AgentInfo[]>;
|
|
361
|
+
export declare function buildConfigOptions(modes: SessionModeState, models: SessionModelState, modelInfos: ModelInfo[], currentEffortLevel?: string, agents?: AgentInfo[], currentAgent?: string): SessionConfigOption[];
|
|
330
362
|
export declare function promptToClaude(prompt: PromptRequest): SDKUserMessage;
|
|
331
363
|
/**
|
|
332
364
|
* Resolves the ACP `messageId` for a Claude SDK message (live) or a persisted
|
|
@@ -348,7 +380,7 @@ export declare function messageIdForGrouping(message: {
|
|
|
348
380
|
* Convert an SDKAssistantMessage (Claude) to a SessionNotification (ACP).
|
|
349
381
|
* Only handles text, image, and thinking chunks for now.
|
|
350
382
|
*/
|
|
351
|
-
export declare function toAcpNotifications(content: string | ContentBlockParam[] | BetaContentBlock[] | BetaRawContentBlockDelta[], role: "assistant" | "user", sessionId: string, toolUseCache: ToolUseCache, client:
|
|
383
|
+
export declare function toAcpNotifications(content: string | ContentBlockParam[] | BetaContentBlock[] | BetaRawContentBlockDelta[], role: "assistant" | "user", sessionId: string, toolUseCache: ToolUseCache, client: AcpClient, logger: Logger, options?: {
|
|
352
384
|
registerHooks?: boolean;
|
|
353
385
|
clientCapabilities?: ClientCapabilities;
|
|
354
386
|
parentToolUseId?: string | null;
|
|
@@ -356,14 +388,14 @@ export declare function toAcpNotifications(content: string | ContentBlockParam[]
|
|
|
356
388
|
taskState?: TaskState;
|
|
357
389
|
messageId?: string;
|
|
358
390
|
}): SessionNotification[];
|
|
359
|
-
export declare function streamEventToAcpNotifications(message: SDKPartialAssistantMessage, sessionId: string, toolUseCache: ToolUseCache, client:
|
|
391
|
+
export declare function streamEventToAcpNotifications(message: SDKPartialAssistantMessage, sessionId: string, toolUseCache: ToolUseCache, client: AcpClient, logger: Logger, options?: {
|
|
360
392
|
clientCapabilities?: ClientCapabilities;
|
|
361
393
|
cwd?: string;
|
|
362
394
|
taskState?: TaskState;
|
|
363
395
|
messageId?: string;
|
|
364
396
|
}): SessionNotification[];
|
|
365
397
|
export declare function runAcp(): {
|
|
366
|
-
connection:
|
|
398
|
+
connection: import("@agentclientprotocol/sdk").AgentConnection;
|
|
367
399
|
agent: ClaudeAcpAgent;
|
|
368
400
|
};
|
|
369
401
|
export {};
|
package/dist/acp-agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"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"}
|
package/dist/acp-agent.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { agent as acpAgent, methods, ndJsonStream, RequestError, } from "@agentclientprotocol/sdk";
|
|
2
2
|
import { deleteSession, getSessionMessages, listSessions, query, } from "@anthropic-ai/claude-agent-sdk";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
@@ -246,7 +246,38 @@ export function describeAlwaysAllow(suggestions, toolName) {
|
|
|
246
246
|
}
|
|
247
247
|
return `Always Allow ${parts.join(" and ")}`;
|
|
248
248
|
}
|
|
249
|
-
|
|
249
|
+
/**
|
|
250
|
+
* Bridges {@link AcpClient} to the connection-scoped {@link AgentContext}
|
|
251
|
+
* exposed by `AgentApp.connect(...)` as `connection.client`. The peer handle is
|
|
252
|
+
* valid for the entire connection lifetime, so it is captured once at
|
|
253
|
+
* construction.
|
|
254
|
+
*/
|
|
255
|
+
class ClientConnection {
|
|
256
|
+
constructor(ctx) {
|
|
257
|
+
this.ctx = ctx;
|
|
258
|
+
}
|
|
259
|
+
sessionUpdate(params) {
|
|
260
|
+
return this.ctx.notify(methods.client.session.update, params);
|
|
261
|
+
}
|
|
262
|
+
requestPermission(params) {
|
|
263
|
+
return this.ctx.request(methods.client.session.requestPermission, params);
|
|
264
|
+
}
|
|
265
|
+
readTextFile(params) {
|
|
266
|
+
return this.ctx.request(methods.client.fs.readTextFile, params);
|
|
267
|
+
}
|
|
268
|
+
writeTextFile(params) {
|
|
269
|
+
return this.ctx.request(methods.client.fs.writeTextFile, params);
|
|
270
|
+
}
|
|
271
|
+
unstable_createElicitation(params) {
|
|
272
|
+
return this.ctx.request(methods.client.elicitation.create, params);
|
|
273
|
+
}
|
|
274
|
+
unstable_completeElicitation(params) {
|
|
275
|
+
return this.ctx.notify(methods.client.elicitation.complete, params);
|
|
276
|
+
}
|
|
277
|
+
extNotification(method, params) {
|
|
278
|
+
return this.ctx.notify(method, params);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
250
281
|
export class ClaudeAcpAgent {
|
|
251
282
|
constructor(client, logger) {
|
|
252
283
|
/** Grace period before a `session/cancel` forces a wedged prompt loop to
|
|
@@ -546,12 +577,17 @@ export class ClaudeAcpAgent {
|
|
|
546
577
|
// (whose delta events don't carry it) can all be tagged with the same,
|
|
547
578
|
// replay-stable id.
|
|
548
579
|
let currentStreamMessageId;
|
|
549
|
-
//
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
|
|
554
|
-
|
|
580
|
+
// The text/thinking blocks that have actually streamed live as
|
|
581
|
+
// `stream_event` deltas for the message the next consolidated `assistant`
|
|
582
|
+
// will repeat, in stream order, each accumulated to its full streamed text.
|
|
583
|
+
// The consolidated handler diffs each assembled block against these and
|
|
584
|
+
// forwards only the un-streamed remainder — nothing if it streamed in full
|
|
585
|
+
// (the common case), the whole block if it never streamed (a non-streaming
|
|
586
|
+
// gateway), or just the tail if the stream was cut short mid-block. Matching
|
|
587
|
+
// on content rather than the Anthropic message id makes dedupe robust to
|
|
588
|
+
// gateways that don't carry a stable/matching id across the stream and the
|
|
589
|
+
// consolidated message. Reset after each consolidated message consumes it.
|
|
590
|
+
const streamedBlocks = [];
|
|
555
591
|
// Stop reason accumulated for the active turn (result subtype, refusal,
|
|
556
592
|
// max_tokens, …). Reset per turn; read when the turn settles at idle.
|
|
557
593
|
let stopReason = "end_turn";
|
|
@@ -562,7 +598,14 @@ export class ClaudeAcpAgent {
|
|
|
562
598
|
lastAssistantError = undefined;
|
|
563
599
|
lastRefusalExplanation = null;
|
|
564
600
|
compactionInProgress = false;
|
|
565
|
-
currentStreamMessageId
|
|
601
|
+
// Do NOT reset currentStreamMessageId or streamedBlocks here. Turn
|
|
602
|
+
// activation can fire mid-message (the replayed user echo with
|
|
603
|
+
// --replay-user-messages lands between a message's blocks); clearing the
|
|
604
|
+
// streamed-content record on activation would drop the blocks that
|
|
605
|
+
// streamed before the echo, so the consolidated assistant message would
|
|
606
|
+
// re-emit them as duplicates. streamedBlocks is bounded instead by being
|
|
607
|
+
// cleared when each consolidated message consumes it. #785 stopped
|
|
608
|
+
// resetting the streamed-content tracking here but left this line.
|
|
566
609
|
stopReason = "end_turn";
|
|
567
610
|
session.accumulatedUsage = {
|
|
568
611
|
inputTokens: 0,
|
|
@@ -1153,20 +1196,50 @@ export class ClaudeAcpAgent {
|
|
|
1153
1196
|
// it) can all be tagged with the same, replay-stable id.
|
|
1154
1197
|
if (message.event.type === "message_start") {
|
|
1155
1198
|
currentStreamMessageId = message.event.message.id || undefined;
|
|
1199
|
+
// A new top-level message starts: clear any streamed-content
|
|
1200
|
+
// residue from a prior message that never reached its
|
|
1201
|
+
// consolidated reset — a cancelled turn breaks out before the
|
|
1202
|
+
// reset, and the synthetic-auth/system/local-command paths
|
|
1203
|
+
// `break` early too. Block indices restart at 0 each message, so
|
|
1204
|
+
// leftover entries would otherwise collide with this message's
|
|
1205
|
+
// blocks and re-emit (or truncate) already-streamed text. Gated on
|
|
1206
|
+
// `parent_tool_use_id === null` so a subagent stream can't clear
|
|
1207
|
+
// the top-level record. Fires once, before any of this message's
|
|
1208
|
+
// blocks, so it doesn't disturb the mid-message turn-activation
|
|
1209
|
+
// path the way resetting on turn activation would.
|
|
1210
|
+
if (message.parent_tool_use_id === null) {
|
|
1211
|
+
streamedBlocks.length = 0;
|
|
1212
|
+
}
|
|
1156
1213
|
}
|
|
1157
|
-
//
|
|
1158
|
-
//
|
|
1159
|
-
//
|
|
1160
|
-
//
|
|
1161
|
-
// can't attribute its content to the top-level message
|
|
1162
|
-
|
|
1163
|
-
|
|
1214
|
+
// Accumulate the text/thinking actually streamed live, so the
|
|
1215
|
+
// `assistant` case below can diff its assembled blocks against what
|
|
1216
|
+
// already reached the client as chunks and forward only the
|
|
1217
|
+
// remainder. Gated on `parent_tool_use_id === null` so a subagent
|
|
1218
|
+
// stream can't attribute its content to the top-level message.
|
|
1219
|
+
// Contiguous deltas of the same block (same index and type) extend
|
|
1220
|
+
// the current entry; anything else opens a new one.
|
|
1221
|
+
if (message.parent_tool_use_id === null &&
|
|
1164
1222
|
message.event.type === "content_block_delta") {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1223
|
+
const delta = message.event.delta;
|
|
1224
|
+
const chunk = delta.type === "text_delta"
|
|
1225
|
+
? { type: "text", text: delta.text }
|
|
1226
|
+
: delta.type === "thinking_delta"
|
|
1227
|
+
? { type: "thinking", text: delta.thinking }
|
|
1228
|
+
: undefined;
|
|
1229
|
+
// Skip empty deltas (some gateways emit empty thinking chunks —
|
|
1230
|
+
// #793): appending "" is a no-op, but pushing a "" entry would
|
|
1231
|
+
// create a block the consolidated handler's `text.length > 0`
|
|
1232
|
+
// guard can never consume, stalling the diff cursor and
|
|
1233
|
+
// re-emitting the next block as a duplicate.
|
|
1234
|
+
if (chunk && chunk.text.length > 0) {
|
|
1235
|
+
const index = message.event.index;
|
|
1236
|
+
const last = streamedBlocks[streamedBlocks.length - 1];
|
|
1237
|
+
if (last && last.index === index && last.type === chunk.type) {
|
|
1238
|
+
last.text += chunk.text;
|
|
1239
|
+
}
|
|
1240
|
+
else {
|
|
1241
|
+
streamedBlocks.push({ index, type: chunk.type, text: chunk.text });
|
|
1242
|
+
}
|
|
1170
1243
|
}
|
|
1171
1244
|
}
|
|
1172
1245
|
if (message.parent_tool_use_id === null &&
|
|
@@ -1340,40 +1413,65 @@ export class ClaudeAcpAgent {
|
|
|
1340
1413
|
}
|
|
1341
1414
|
let content;
|
|
1342
1415
|
if (message.type === "assistant" && message.parent_tool_use_id === null) {
|
|
1343
|
-
// Top-level assistant message:
|
|
1344
|
-
// streamed live as
|
|
1345
|
-
//
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1416
|
+
// Top-level assistant message: each text/thinking block may have
|
|
1417
|
+
// already been streamed live as deltas. Diff each against what
|
|
1418
|
+
// streamed (`streamedBlocks`, in document order) and forward only
|
|
1419
|
+
// the un-streamed remainder — nothing if it streamed in full (the
|
|
1420
|
+
// common case), the whole block if it never streamed (a
|
|
1421
|
+
// non-streaming gateway), or just the tail if the stream was cut
|
|
1422
|
+
// short mid-block. `streamPos` walks the streamed blocks in step
|
|
1423
|
+
// with the assembled text/thinking blocks; tool_use and other
|
|
1424
|
+
// blocks pass through untouched (their own `toolUseCache` collapses
|
|
1425
|
+
// the streamed/assembled pair) without advancing it.
|
|
1426
|
+
const blocks = message.message.content;
|
|
1427
|
+
const kept = [];
|
|
1428
|
+
let streamPos = 0;
|
|
1429
|
+
for (const item of blocks) {
|
|
1350
1430
|
if (item.type !== "text" && item.type !== "thinking") {
|
|
1351
|
-
|
|
1431
|
+
kept.push(item);
|
|
1432
|
+
continue;
|
|
1352
1433
|
}
|
|
1353
|
-
|
|
1354
|
-
//
|
|
1355
|
-
//
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
if (streamedLive) {
|
|
1359
|
-
return false;
|
|
1434
|
+
const full = item.type === "text" ? item.text : item.thinking;
|
|
1435
|
+
// Empty assembled blocks carry nothing (some gateways emit an
|
|
1436
|
+
// empty `thinking` block before the real text) — drop them.
|
|
1437
|
+
if (full.length === 0) {
|
|
1438
|
+
continue;
|
|
1360
1439
|
}
|
|
1361
|
-
//
|
|
1362
|
-
//
|
|
1363
|
-
//
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1440
|
+
// A streamed block of the same type whose accumulated text is a
|
|
1441
|
+
// prefix of this one was already (at least partly) delivered as
|
|
1442
|
+
// chunks; consume it and forward only what's left. A non-empty
|
|
1443
|
+
// streamed text is required so an empty/aborted streamed block
|
|
1444
|
+
// doesn't swallow the assembled copy.
|
|
1445
|
+
const streamed = streamedBlocks[streamPos];
|
|
1446
|
+
if (streamed &&
|
|
1447
|
+
streamed.type === item.type &&
|
|
1448
|
+
streamed.text.length > 0 &&
|
|
1449
|
+
full.startsWith(streamed.text)) {
|
|
1450
|
+
streamPos++;
|
|
1451
|
+
const remainder = full.slice(streamed.text.length);
|
|
1452
|
+
if (remainder.length === 0) {
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
// Overwrite in place with just the un-streamed tail (the
|
|
1456
|
+
// assembled message isn't read again after this) so the block
|
|
1457
|
+
// keeps its exact SDK type.
|
|
1458
|
+
if (item.type === "text") {
|
|
1459
|
+
item.text = remainder;
|
|
1460
|
+
}
|
|
1461
|
+
else {
|
|
1462
|
+
item.thinking = remainder;
|
|
1463
|
+
}
|
|
1464
|
+
kept.push(item);
|
|
1465
|
+
continue;
|
|
1367
1466
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
// dedupe — drop it so the streamed-id sets stay bounded to in-flight
|
|
1372
|
-
// streams rather than growing for the session's whole life.
|
|
1373
|
-
if (id !== undefined) {
|
|
1374
|
-
streamedTextIds.delete(id);
|
|
1375
|
-
streamedThinkingIds.delete(id);
|
|
1467
|
+
// Not matched: never streamed (or the stream diverged from the
|
|
1468
|
+
// assembled text) — forward the block in full.
|
|
1469
|
+
kept.push(item);
|
|
1376
1470
|
}
|
|
1471
|
+
content = kept;
|
|
1472
|
+
// Consumed: reset so the next message's blocks accumulate fresh and
|
|
1473
|
+
// the record stays bounded to the in-flight message.
|
|
1474
|
+
streamedBlocks.length = 0;
|
|
1377
1475
|
}
|
|
1378
1476
|
else if (message.type === "assistant") {
|
|
1379
1477
|
// Subagent assistant message (`parent_tool_use_id !== null`). It is
|
|
@@ -1989,18 +2087,22 @@ export class ClaudeAcpAgent {
|
|
|
1989
2087
|
session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
|
|
1990
2088
|
}
|
|
1991
2089
|
else if (configId === "model") {
|
|
2090
|
+
// `ModelInfo.supportsAutoMode` is the canonical SDK signal for clamping
|
|
2091
|
+
// modes below; its `displayName`/`description` also let us infer the
|
|
2092
|
+
// context window for semantic aliases (e.g. `default`) whose ID alone
|
|
2093
|
+
// carries no "1m" token.
|
|
2094
|
+
const newModelInfo = session.modelInfos.find((m) => m.value === value);
|
|
1992
2095
|
if (session.models.currentModelId !== value) {
|
|
1993
2096
|
// The cached context window was learned for the previous model; reset
|
|
1994
2097
|
// to the new model's heuristic so mid-stream updates between now and
|
|
1995
2098
|
// the next `result` reflect the user's selection instead of the old
|
|
1996
2099
|
// model's window.
|
|
1997
|
-
session.contextWindowSize =
|
|
2100
|
+
session.contextWindowSize =
|
|
2101
|
+
inferContextWindowFromModel(value, newModelInfo?.displayName, newModelInfo?.description) ?? DEFAULT_CONTEXT_WINDOW;
|
|
1998
2102
|
}
|
|
1999
2103
|
session.models = { ...session.models, currentModelId: value };
|
|
2000
2104
|
// Recompute availableModes for the new model and clamp the current
|
|
2001
2105
|
// mode if the SDK no longer offers it (today: "auto" on Haiku).
|
|
2002
|
-
// `ModelInfo.supportsAutoMode` is the canonical SDK signal.
|
|
2003
|
-
const newModelInfo = session.modelInfos.find((m) => m.value === value);
|
|
2004
2106
|
const newAvailableModes = buildAvailableModes(newModelInfo);
|
|
2005
2107
|
// Capture BEFORE mutating session.modes so the log message reflects
|
|
2006
2108
|
// the invalidated mode rather than "default".
|
|
@@ -2029,7 +2131,7 @@ export class ClaudeAcpAgent {
|
|
|
2029
2131
|
// Rebuild config options since effort levels depend on the selected model
|
|
2030
2132
|
const effortOpt = session.configOptions.find((o) => o.id === "effort");
|
|
2031
2133
|
const currentEffort = typeof effortOpt?.currentValue === "string" ? effortOpt.currentValue : undefined;
|
|
2032
|
-
session.configOptions = buildConfigOptions(session.modes, session.models, session.modelInfos, currentEffort);
|
|
2134
|
+
session.configOptions = buildConfigOptions(session.modes, session.models, session.modelInfos, currentEffort, session.agents, session.currentAgent);
|
|
2033
2135
|
// Sync effort with the SDK if it changed after the model switch
|
|
2034
2136
|
const newEffortOpt = session.configOptions.find((o) => o.id === "effort");
|
|
2035
2137
|
const newEffort = typeof newEffortOpt?.currentValue === "string" ? newEffortOpt.currentValue : undefined;
|
|
@@ -2054,6 +2156,18 @@ export class ClaudeAcpAgent {
|
|
|
2054
2156
|
});
|
|
2055
2157
|
}
|
|
2056
2158
|
}
|
|
2159
|
+
else if (configId === "agent") {
|
|
2160
|
+
// Live agent switch — no subprocess restart needed. Apply the SDK flag
|
|
2161
|
+
// first so a rejected control request leaves both `currentAgent` and the
|
|
2162
|
+
// config option untouched (no UI/SDK desync). Passing `null` clears the
|
|
2163
|
+
// flag layer back to the standard Claude Code agent; the change takes
|
|
2164
|
+
// effect on the next turn (SDK >= 0.3.161).
|
|
2165
|
+
await session.query.applyFlagSettings({
|
|
2166
|
+
agent: value === DEFAULT_AGENT_ID ? null : value,
|
|
2167
|
+
});
|
|
2168
|
+
session.currentAgent = value;
|
|
2169
|
+
session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
|
|
2170
|
+
}
|
|
2057
2171
|
else {
|
|
2058
2172
|
session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
|
|
2059
2173
|
if (configId === "effort") {
|
|
@@ -2405,7 +2519,17 @@ export class ClaudeAcpAgent {
|
|
|
2405
2519
|
currentModeId: effectiveMode,
|
|
2406
2520
|
availableModes,
|
|
2407
2521
|
};
|
|
2408
|
-
const
|
|
2522
|
+
const agents = await discoverCustomAgents(q);
|
|
2523
|
+
// Only adopt the requested agent as the selected value if it's one we
|
|
2524
|
+
// actually surface in the picker. A built-in (filtered out above) or
|
|
2525
|
+
// otherwise-unknown name would leave the config option's `currentValue`
|
|
2526
|
+
// pointing at an entry not in its own `options` list, which clients render
|
|
2527
|
+
// as a blank/invalid selection.
|
|
2528
|
+
const requestedAgent = userProvidedOptions?.agent;
|
|
2529
|
+
const currentAgent = requestedAgent && agents.some((a) => a.name === requestedAgent)
|
|
2530
|
+
? requestedAgent
|
|
2531
|
+
: DEFAULT_AGENT_ID;
|
|
2532
|
+
const configOptions = buildConfigOptions(modes, models, allowedModels, settingsManager.getSettings().effortLevel, agents, currentAgent);
|
|
2409
2533
|
// Apply the initial effort level to the SDK so it matches the UI default
|
|
2410
2534
|
const initialEffort = configOptions.find((o) => o.id === "effort");
|
|
2411
2535
|
if (initialEffort &&
|
|
@@ -2432,9 +2556,11 @@ export class ClaudeAcpAgent {
|
|
|
2432
2556
|
models,
|
|
2433
2557
|
modelInfos: allowedModels,
|
|
2434
2558
|
configOptions,
|
|
2559
|
+
agents,
|
|
2560
|
+
currentAgent,
|
|
2435
2561
|
abortController,
|
|
2436
2562
|
emitRawSDKMessages: sessionMeta?.claudeCode?.emitRawSDKMessages ?? false,
|
|
2437
|
-
contextWindowSize: inferContextWindowFromModel(models.currentModelId) ?? DEFAULT_CONTEXT_WINDOW,
|
|
2563
|
+
contextWindowSize: inferContextWindowFromModel(models.currentModelId, currentModelInfo?.displayName, currentModelInfo?.description) ?? DEFAULT_CONTEXT_WINDOW,
|
|
2438
2564
|
taskState,
|
|
2439
2565
|
toolUseCache: {},
|
|
2440
2566
|
messageIdToUuid: new Map(),
|
|
@@ -2578,7 +2704,39 @@ function buildAvailableModes(modelInfo) {
|
|
|
2578
2704
|
function toSdkEffortLevel(value) {
|
|
2579
2705
|
return value === undefined || value === "default" ? null : value;
|
|
2580
2706
|
}
|
|
2581
|
-
|
|
2707
|
+
// `supportedAgents()` always returns Claude Code's built-in subagents — the
|
|
2708
|
+
// ones used for Task-tool delegation (Explore, Plan, etc.) — even when the user
|
|
2709
|
+
// has configured none of their own. Those aren't meaningful *main-thread*
|
|
2710
|
+
// personas, so we filter them out and only surface the Agent picker when the
|
|
2711
|
+
// user (or a plugin/project) has configured custom agents. Update this set if
|
|
2712
|
+
// the SDK's built-in roster changes.
|
|
2713
|
+
export const BUILTIN_AGENT_NAMES = new Set([
|
|
2714
|
+
"claude",
|
|
2715
|
+
"general-purpose",
|
|
2716
|
+
"Explore",
|
|
2717
|
+
"Plan",
|
|
2718
|
+
"statusline-setup",
|
|
2719
|
+
]);
|
|
2720
|
+
// Value of the synthetic "Default" entry in the agent picker, which maps to the
|
|
2721
|
+
// standard Claude Code agent (`applyFlagSettings({ agent: null })`). It is a
|
|
2722
|
+
// reserved sentinel: a custom agent named exactly this would collide with it
|
|
2723
|
+
// (two options sharing the value, selection silently routing to `null`), so we
|
|
2724
|
+
// exclude that name from discovery.
|
|
2725
|
+
export const DEFAULT_AGENT_ID = "default";
|
|
2726
|
+
/** Discover user/plugin/project-configured main-thread agents, excluding the
|
|
2727
|
+
* built-in subagents and the reserved "default" sentinel. Returns an empty
|
|
2728
|
+
* list if discovery fails so a flaky control request never blocks session
|
|
2729
|
+
* creation. */
|
|
2730
|
+
export async function discoverCustomAgents(q) {
|
|
2731
|
+
try {
|
|
2732
|
+
const agents = await q.supportedAgents();
|
|
2733
|
+
return agents.filter((a) => !BUILTIN_AGENT_NAMES.has(a.name) && a.name !== DEFAULT_AGENT_ID);
|
|
2734
|
+
}
|
|
2735
|
+
catch {
|
|
2736
|
+
return [];
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
export function buildConfigOptions(modes, models, modelInfos, currentEffortLevel, agents = [], currentAgent = DEFAULT_AGENT_ID) {
|
|
2582
2740
|
const options = [
|
|
2583
2741
|
{
|
|
2584
2742
|
id: "mode",
|
|
@@ -2635,6 +2793,27 @@ function buildConfigOptions(modes, models, modelInfos, currentEffortLevel) {
|
|
|
2635
2793
|
options: effortOptions,
|
|
2636
2794
|
});
|
|
2637
2795
|
}
|
|
2796
|
+
// Only surface the Agent picker when there's a real choice — i.e. the user
|
|
2797
|
+
// has configured at least one custom agent (built-ins are filtered out in
|
|
2798
|
+
// discoverCustomAgents). With none configured, "Default" would be the only
|
|
2799
|
+
// entry, so we omit the option entirely.
|
|
2800
|
+
if (agents.length > 0) {
|
|
2801
|
+
options.push({
|
|
2802
|
+
id: "agent",
|
|
2803
|
+
name: "Agent",
|
|
2804
|
+
description: "Main-thread agent persona",
|
|
2805
|
+
type: "select",
|
|
2806
|
+
currentValue: currentAgent,
|
|
2807
|
+
options: [
|
|
2808
|
+
{ value: DEFAULT_AGENT_ID, name: "Default", description: "Standard Claude Code agent" },
|
|
2809
|
+
...agents.map((a) => ({
|
|
2810
|
+
value: a.name,
|
|
2811
|
+
name: a.name,
|
|
2812
|
+
description: a.description || undefined,
|
|
2813
|
+
})),
|
|
2814
|
+
],
|
|
2815
|
+
});
|
|
2816
|
+
}
|
|
2638
2817
|
return options;
|
|
2639
2818
|
}
|
|
2640
2819
|
// Claude Code CLI persists display strings like "opus[1m]" in settings,
|
|
@@ -3062,13 +3241,17 @@ export function toAcpNotifications(content, role, sessionId, toolUseCache, clien
|
|
|
3062
3241
|
break;
|
|
3063
3242
|
case "thinking":
|
|
3064
3243
|
case "thinking_delta":
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3244
|
+
// Recent models default `thinking.display` to "omitted", which streams
|
|
3245
|
+
// signature-only thinking blocks whose text is empty.
|
|
3246
|
+
if (chunk.thinking.length > 0) {
|
|
3247
|
+
update = {
|
|
3248
|
+
sessionUpdate: "agent_thought_chunk",
|
|
3249
|
+
content: {
|
|
3250
|
+
type: "text",
|
|
3251
|
+
text: chunk.thinking,
|
|
3252
|
+
},
|
|
3253
|
+
};
|
|
3254
|
+
}
|
|
3072
3255
|
break;
|
|
3073
3256
|
case "tool_use":
|
|
3074
3257
|
case "server_tool_use":
|
|
@@ -3329,11 +3512,30 @@ export function runAcp() {
|
|
|
3329
3512
|
const input = nodeToWebWritable(process.stdout);
|
|
3330
3513
|
const output = nodeToWebReadable(process.stdin);
|
|
3331
3514
|
const stream = ndJsonStream(input, output);
|
|
3515
|
+
// `connect(...)` returns a connection-scoped peer handle (`connection.client`)
|
|
3516
|
+
// that stays valid for the whole connection, so the agent captures it once.
|
|
3517
|
+
// Handlers close over `agent`, which is assigned synchronously right after
|
|
3518
|
+
// `connect()` returns — before the connection processes any inbound message.
|
|
3519
|
+
// It cannot be `const`: its value depends on `connection.client`, which does
|
|
3520
|
+
// not exist until `connect()` has been called.
|
|
3521
|
+
// eslint-disable-next-line prefer-const
|
|
3332
3522
|
let agent;
|
|
3333
|
-
const connection =
|
|
3334
|
-
agent
|
|
3335
|
-
|
|
3336
|
-
|
|
3523
|
+
const connection = acpAgent({ name: "claude-code-acp" })
|
|
3524
|
+
.onRequest(methods.agent.initialize, (ctx) => agent.initialize(ctx.params))
|
|
3525
|
+
.onRequest(methods.agent.session.new, (ctx) => agent.newSession(ctx.params))
|
|
3526
|
+
.onRequest(methods.agent.session.load, (ctx) => agent.loadSession(ctx.params))
|
|
3527
|
+
.onRequest(methods.agent.session.fork, (ctx) => agent.unstable_forkSession(ctx.params))
|
|
3528
|
+
.onRequest(methods.agent.session.list, (ctx) => agent.listSessions(ctx.params))
|
|
3529
|
+
.onRequest(methods.agent.session.delete, (ctx) => agent.deleteSession(ctx.params))
|
|
3530
|
+
.onRequest(methods.agent.session.resume, (ctx) => agent.resumeSession(ctx.params))
|
|
3531
|
+
.onRequest(methods.agent.session.close, (ctx) => agent.closeSession(ctx.params))
|
|
3532
|
+
.onRequest(methods.agent.session.setMode, (ctx) => agent.setSessionMode(ctx.params))
|
|
3533
|
+
.onRequest(methods.agent.session.setConfigOption, (ctx) => agent.setSessionConfigOption(ctx.params))
|
|
3534
|
+
.onRequest(methods.agent.authenticate, (ctx) => agent.authenticate(ctx.params))
|
|
3535
|
+
.onRequest(methods.agent.session.prompt, (ctx) => agent.prompt(ctx.params))
|
|
3536
|
+
.onNotification(methods.agent.session.cancel, (ctx) => agent.cancel(ctx.params))
|
|
3537
|
+
.connect(stream);
|
|
3538
|
+
agent = new ClaudeAcpAgent(new ClientConnection(connection.client));
|
|
3337
3539
|
return { connection, agent };
|
|
3338
3540
|
}
|
|
3339
3541
|
function commonPrefixLength(a, b) {
|
|
@@ -3343,14 +3545,21 @@ function commonPrefixLength(a, b) {
|
|
|
3343
3545
|
}
|
|
3344
3546
|
return i;
|
|
3345
3547
|
}
|
|
3346
|
-
/** Best-effort first guess of a model's context window
|
|
3347
|
-
*
|
|
3348
|
-
*
|
|
3548
|
+
/** Best-effort first guess of a model's context window, used only as a
|
|
3549
|
+
* fallback when the SDK's authoritative `getContextUsage` is unavailable (and
|
|
3550
|
+
* until a `result` message arrives with the `modelUsage` value).
|
|
3551
|
+
*
|
|
3349
3552
|
* Anthropic 1M-context variants encode "1m" as a distinct token in the SDK
|
|
3350
3553
|
* model ID (e.g., "claude-opus-4-6-1m"), which `\b1m\b` catches without also
|
|
3351
|
-
* matching things like "10m" or embedded substrings.
|
|
3352
|
-
|
|
3353
|
-
|
|
3554
|
+
* matching things like "10m" or embedded substrings. Semantic aliases like
|
|
3555
|
+
* `default` carry no such token in the ID, but the SDK's human-facing
|
|
3556
|
+
* `displayName`/`description` do (e.g. "Opus 4.7 (1M context)"), so callers
|
|
3557
|
+
* pass those too — the same `\b1m\b` token appears in "1M context". The SDK's
|
|
3558
|
+
* `ModelInfo` exposes no structured context-window field, so this text scan is
|
|
3559
|
+
* the only pre-`result` signal available. A miss falls back to the default
|
|
3560
|
+
* window and is corrected by `result.modelUsage` within one turn. */
|
|
3561
|
+
function inferContextWindowFromModel(...texts) {
|
|
3562
|
+
if (texts.some((text) => text != null && /\b1m\b/i.test(text)))
|
|
3354
3563
|
return 1_000_000;
|
|
3355
3564
|
return null;
|
|
3356
3565
|
}
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EASL,eAAe,EACf,gBAAgB,EAChB,eAAe,EAIhB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAGL,oBAAoB,EAEpB,6BAA6B,EAE9B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,yCAAyC,EAGzC,qCAAqC,EAGrC,kCAAkC,EAGlC,+CAA+C,EAI/C,wBAAwB,EACxB,kCAAkC,EAIlC,gCAAgC,EAEhC,iCAAiC,EAClC,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AA0BxC,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE;QACN,aAAa,CAAC,EAAE;YACd,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,eAAe,CAAC,EAAE;YAChB,WAAW,EAAE,MAAM,CAAC;YACpB,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,aAAa,CAAC,EAAE;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;YAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;SACvB,CAAC;KACH,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,GAAG,EACZ,sBAAsB,GAAE,OAAe,EACvC,GAAG,CAAC,EAAE,MAAM,GACX,QAAQ,CAkVV;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EACN,oBAAoB,GACpB,wBAAwB,GACxB,iCAAiC,GACjC,gCAAgC,GAChC,6BAA6B,GAC7B,qCAAqC,GACrC,yCAAyC,GACzC,+CAA+C,GAC/C,kCAAkC,GAClC,kCAAkC,EACtC,OAAO,EAAE,GAAG,GAAG,SAAS,EACxB,sBAAsB,GAAE,OAAe,GACtC,UAAU,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
CHANGED
|
@@ -366,7 +366,9 @@ export function toolUpdateFromToolResult(toolResult, toolUse, supportsTerminalOu
|
|
|
366
366
|
// Extract output and exit code from either format:
|
|
367
367
|
// 1. BetaBashCodeExecutionResultBlock: { type: "bash_code_execution_result", stdout, stderr, return_code }
|
|
368
368
|
// 2. Plain string content from a regular tool_result
|
|
369
|
-
// 3. Array content (e.g. [{ type: "text", text: "..." }]
|
|
369
|
+
// 3. Array content (e.g. [{ type: "text", text: "..." }] for stdout,
|
|
370
|
+
// or [{ type: "image", source: {...} }] when the local Bash tool
|
|
371
|
+
// produces an image, e.g. piping a base64 data URI)
|
|
370
372
|
let output = "";
|
|
371
373
|
let exitCode = isError ? 1 : 0;
|
|
372
374
|
if (result &&
|
|
@@ -380,11 +382,19 @@ export function toolUpdateFromToolResult(toolResult, toolUse, supportsTerminalOu
|
|
|
380
382
|
else if (typeof result === "string") {
|
|
381
383
|
output = result;
|
|
382
384
|
}
|
|
383
|
-
else if (Array.isArray(result) &&
|
|
384
|
-
result.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
385
|
+
else if (Array.isArray(result) && result.length > 0) {
|
|
386
|
+
const textOnly = result.every((c) => c && typeof c === "object" && typeof c.text === "string");
|
|
387
|
+
if (textOnly) {
|
|
388
|
+
output = result.map((c) => c.text).join("\n");
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
// Image (or mixed non-text) content. Binary payloads can't be
|
|
392
|
+
// streamed through the terminal-output _meta channel, so bypass
|
|
393
|
+
// it and surface the blocks as ACP content. This handles the
|
|
394
|
+
// local Bash tool's image output, which previously failed the
|
|
395
|
+
// text-only guard and was silently dropped.
|
|
396
|
+
return toAcpContentUpdate(result, isError);
|
|
397
|
+
}
|
|
388
398
|
}
|
|
389
399
|
if (supportsTerminalOutput) {
|
|
390
400
|
return {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.49.0",
|
|
7
7
|
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
|
8
8
|
"main": "dist/lib.js",
|
|
9
9
|
"types": "dist/lib.d.ts",
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
"author": "Zed Industries",
|
|
61
61
|
"license": "Apache-2.0",
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@agentclientprotocol/sdk": "0.
|
|
64
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
63
|
+
"@agentclientprotocol/sdk": "0.28.1",
|
|
64
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.185",
|
|
65
65
|
"zod": "^3.25.0 || ^4.0.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@anthropic-ai/sdk": "0.
|
|
68
|
+
"@anthropic-ai/sdk": "0.105.0",
|
|
69
69
|
"@eslint/js": "10.0.1",
|
|
70
|
-
"@types/node": "
|
|
70
|
+
"@types/node": "26.0.0",
|
|
71
71
|
"@typescript-eslint/eslint-plugin": "8.61.1",
|
|
72
72
|
"@typescript-eslint/parser": "8.61.1",
|
|
73
73
|
"eslint": "10.5.0",
|