@agentclientprotocol/claude-agent-acp 0.89.2-preview.9 → 0.90.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/README.md +51 -8
- package/dist/acp-agent.d.ts +50 -1
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +493 -135
- package/dist/acp-subagents.d.ts +16 -6
- package/dist/acp-subagents.d.ts.map +1 -1
- package/dist/acp-subagents.js +8 -2
- package/dist/async-tasks.d.ts +4 -1
- package/dist/async-tasks.d.ts.map +1 -1
- package/dist/auth-status.d.ts +2 -2
- package/dist/auth-status.d.ts.map +1 -1
- package/dist/auth-status.js +18 -4
- package/dist/exit-plan.d.ts +17 -0
- package/dist/exit-plan.d.ts.map +1 -1
- package/dist/exit-plan.js +34 -0
- package/dist/native-subagents.d.ts +190 -11
- package/dist/native-subagents.d.ts.map +1 -1
- package/dist/native-subagents.js +419 -40
- package/dist/settings.d.ts +6 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +13 -0
- package/dist/subagent-history.d.ts +27 -2
- package/dist/subagent-history.d.ts.map +1 -1
- package/dist/subagent-history.js +38 -10
- package/dist/subagent-replay.d.ts +108 -0
- package/dist/subagent-replay.d.ts.map +1 -0
- package/dist/subagent-replay.js +261 -0
- package/dist/tool-calls/background.d.ts +9 -0
- package/dist/tool-calls/background.d.ts.map +1 -1
- package/dist/tool-calls/background.js +25 -0
- package/dist/tool-calls/renderer.d.ts +30 -9
- package/dist/tool-calls/renderer.d.ts.map +1 -1
- package/dist/tool-calls/renderer.js +48 -22
- package/dist/tool-calls/reporters/bash.d.ts +7 -0
- package/dist/tool-calls/reporters/bash.d.ts.map +1 -1
- package/dist/tool-calls/reporters/bash.js +16 -1
- package/dist/tool-calls/reporters/search.d.ts.map +1 -1
- package/dist/tool-calls/reporters/search.js +20 -2
- package/dist/v2/agent.d.ts.map +1 -1
- package/dist/v2/agent.js +45 -12
- package/dist/v2/initialize.d.ts.map +1 -1
- package/dist/v2/initialize.js +10 -1
- package/dist/v2/session-update.d.ts +11 -0
- package/dist/v2/session-update.d.ts.map +1 -1
- package/dist/v2/session-update.js +67 -0
- package/dist/v2/session.d.ts +3 -12
- package/dist/v2/session.d.ts.map +1 -1
- package/dist/v2/session.js +5 -18
- package/dist/v2/tool-call-meta.d.ts +44 -0
- package/dist/v2/tool-call-meta.d.ts.map +1 -0
- package/dist/v2/tool-call-meta.js +72 -0
- package/package.json +9 -9
|
@@ -84,16 +84,32 @@ export declare class AcpToolCallRenderer {
|
|
|
84
84
|
/** True when the renderer reports the history of a loaded session. */
|
|
85
85
|
replay?: boolean);
|
|
86
86
|
static for(capabilities: AcpClientCapabilities | null | undefined, replay?: boolean): AcpToolCallRenderer;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the client keeps a tool call's `_meta` across reports: AIR merges
|
|
89
|
+
* its keys, and v2 stores it. Such a client gets no `toolResponse` text that
|
|
90
|
+
* the tool call's content already shows, which it would otherwise keep.
|
|
91
|
+
*/
|
|
92
|
+
private get keepsMeta();
|
|
87
93
|
/**
|
|
88
94
|
* The status of a tool result. Claude Code reports a run that it aborted in
|
|
89
|
-
* one of
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
+
* one of three ways:
|
|
96
|
+
* - an error result whose `nonExecution` kind says so (`interrupted`,
|
|
97
|
+
* `cancelled`);
|
|
98
|
+
* - a command result that says `interrupted` (for example, a steering
|
|
99
|
+
* message landed just before the command started);
|
|
100
|
+
* - any error result of the work that a `session/cancel` stopped
|
|
101
|
+
* (`run.cancelled`). The kind does not say so there: CLI 2.1.293 stamps a
|
|
102
|
+
* command that the interrupt killed `user-rejected`, as if the user had
|
|
103
|
+
* refused it.
|
|
104
|
+
*
|
|
105
|
+
* Such a run is `cancelled` for a v2 client, which has that status. Every
|
|
106
|
+
* other client gets `failed` for the error, with the kind in
|
|
107
|
+
* `_meta.claudeCode.nonExecutionKind`, and `completed` for the command.
|
|
95
108
|
*/
|
|
96
|
-
resultStatus(isError: boolean, nonExecution: ToolResultMeta | undefined,
|
|
109
|
+
resultStatus(isError: boolean, nonExecution: ToolResultMeta | undefined, run?: {
|
|
110
|
+
interrupted?: boolean;
|
|
111
|
+
cancelled?: boolean;
|
|
112
|
+
}): ToolCallStatus;
|
|
97
113
|
/** The facts of a tool use. */
|
|
98
114
|
facts(toolUse: Pick<ToolUse, "name" | "input">, cwd?: string): ToolUseFacts;
|
|
99
115
|
/** The standard fields of a tool use: the title, the kind, the content, and the locations. */
|
|
@@ -159,6 +175,7 @@ export declare class AcpToolCallRenderer {
|
|
|
159
175
|
result(toolUse: ToolUse, result: ResultBlock, options?: {
|
|
160
176
|
structured?: unknown;
|
|
161
177
|
nonExecution?: ToolResultMeta;
|
|
178
|
+
cancelled?: boolean;
|
|
162
179
|
}): ToolCallUpdate[];
|
|
163
180
|
/**
|
|
164
181
|
* Whether AIR shows [toolUse] as the list of viewed files: a read or a
|
|
@@ -169,7 +186,8 @@ export declare class AcpToolCallRenderer {
|
|
|
169
186
|
/**
|
|
170
187
|
* The report of a PostToolUse hook: the final change of an edit tool, and
|
|
171
188
|
* the `status` and `isAsync` markers of the `tool_response`. The rest of the
|
|
172
|
-
* `tool_response` repeats output that the content already carries
|
|
189
|
+
* `tool_response` repeats output that the content already carries, such as
|
|
190
|
+
* the whole text of a written file.
|
|
173
191
|
*/
|
|
174
192
|
hookResult(toolUse: Pick<ToolUse, "id" | "name">, toolResponse: unknown, cwd?: string): Promise<ToolCallUpdate | undefined>;
|
|
175
193
|
/**
|
|
@@ -203,11 +221,14 @@ export declare class AcpToolCallRenderer {
|
|
|
203
221
|
* reached a complete assistant message, for example because Claude switched
|
|
204
222
|
* to a steering message), a v2 client gets `cancelled` and every other
|
|
205
223
|
* client `failed`, since v1 has no `cancelled`. If Claude Code ran it but
|
|
206
|
-
* returned no result, it failed
|
|
224
|
+
* returned no result, it failed, unless a `session/cancel` ended the turn
|
|
225
|
+
* (`cancelled`): the cancel stopped the run, so a v2 client gets `cancelled`
|
|
226
|
+
* for it too.
|
|
207
227
|
*/
|
|
208
228
|
unfinished(call: {
|
|
209
229
|
toolCallId: string;
|
|
210
230
|
ran: boolean;
|
|
231
|
+
cancelled?: boolean;
|
|
211
232
|
}): ToolCallUpdate;
|
|
212
233
|
/**
|
|
213
234
|
* The report of a tool progress beat. The field tracker sends the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/tool-calls/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,IAAI,qBAAqB,EAC3C,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAQlC,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/tool-calls/renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { ClientCapabilities } from "./client-capabilities.js";
|
|
|
5
5
|
import { resultText, textContent, toAcpContentUpdate, toolResponseMarkers } from "./content.js";
|
|
6
6
|
import { reporterFor } from "./reporters/index.js";
|
|
7
7
|
import { resolveSkillPath } from "./reporters/interaction.js";
|
|
8
|
+
import { shellDescription } from "./reporters/bash.js";
|
|
8
9
|
import { grepPath } from "./reporters/search.js";
|
|
9
10
|
/** The id suffix of the call that clears the plan file of an approved plan for AIR. */
|
|
10
11
|
const PLAN_FILE_CLEAR_SUFFIX = ":plan-file-clear";
|
|
@@ -40,17 +41,33 @@ export class AcpToolCallRenderer {
|
|
|
40
41
|
static for(capabilities, replay = false) {
|
|
41
42
|
return new AcpToolCallRenderer(ClientCapabilities.from(capabilities), replay);
|
|
42
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Whether the client keeps a tool call's `_meta` across reports: AIR merges
|
|
46
|
+
* its keys, and v2 stores it. Such a client gets no `toolResponse` text that
|
|
47
|
+
* the tool call's content already shows, which it would otherwise keep.
|
|
48
|
+
*/
|
|
49
|
+
get keepsMeta() {
|
|
50
|
+
return this.capabilities.air.client || this.capabilities.v2;
|
|
51
|
+
}
|
|
43
52
|
/**
|
|
44
53
|
* The status of a tool result. Claude Code reports a run that it aborted in
|
|
45
|
-
* one of
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
54
|
+
* one of three ways:
|
|
55
|
+
* - an error result whose `nonExecution` kind says so (`interrupted`,
|
|
56
|
+
* `cancelled`);
|
|
57
|
+
* - a command result that says `interrupted` (for example, a steering
|
|
58
|
+
* message landed just before the command started);
|
|
59
|
+
* - any error result of the work that a `session/cancel` stopped
|
|
60
|
+
* (`run.cancelled`). The kind does not say so there: CLI 2.1.293 stamps a
|
|
61
|
+
* command that the interrupt killed `user-rejected`, as if the user had
|
|
62
|
+
* refused it.
|
|
63
|
+
*
|
|
64
|
+
* Such a run is `cancelled` for a v2 client, which has that status. Every
|
|
65
|
+
* other client gets `failed` for the error, with the kind in
|
|
66
|
+
* `_meta.claudeCode.nonExecutionKind`, and `completed` for the command.
|
|
51
67
|
*/
|
|
52
|
-
resultStatus(isError, nonExecution,
|
|
53
|
-
const aborted = interrupted
|
|
68
|
+
resultStatus(isError, nonExecution, run = {}) {
|
|
69
|
+
const aborted = run.interrupted === true ||
|
|
70
|
+
(isError && (run.cancelled === true || isAbortedToolResult(nonExecution)));
|
|
54
71
|
if (this.capabilities.v2 && aborted)
|
|
55
72
|
return V2_CANCELLED;
|
|
56
73
|
return isError ? "failed" : "completed";
|
|
@@ -306,7 +323,10 @@ export class AcpToolCallRenderer {
|
|
|
306
323
|
},
|
|
307
324
|
toolCallId: toolUse.id,
|
|
308
325
|
sessionUpdate: "tool_call_update",
|
|
309
|
-
status: this.resultStatus(result.is_error === true, options.nonExecution,
|
|
326
|
+
status: this.resultStatus(result.is_error === true, options.nonExecution, {
|
|
327
|
+
interrupted: facts.command?.interrupted === true,
|
|
328
|
+
cancelled: options.cancelled,
|
|
329
|
+
}),
|
|
310
330
|
...(rawOutput !== undefined ? { rawOutput } : {}),
|
|
311
331
|
...(planFilePath ? { rawInput: planFileInput(toolUse.input, planFilePath) } : {}),
|
|
312
332
|
...fields,
|
|
@@ -346,14 +366,15 @@ export class AcpToolCallRenderer {
|
|
|
346
366
|
/**
|
|
347
367
|
* The report of a PostToolUse hook: the final change of an edit tool, and
|
|
348
368
|
* the `status` and `isAsync` markers of the `tool_response`. The rest of the
|
|
349
|
-
* `tool_response` repeats output that the content already carries
|
|
369
|
+
* `tool_response` repeats output that the content already carries, such as
|
|
370
|
+
* the whole text of a written file.
|
|
350
371
|
*/
|
|
351
372
|
async hookResult(toolUse, toolResponse, cwd) {
|
|
352
373
|
const reporter = reporterFor(toolUse.name);
|
|
353
374
|
const change = reporter.hookResult
|
|
354
375
|
? await reporter.hookResult(toolResponse, { cwd, capabilities: this.capabilities })
|
|
355
376
|
: {};
|
|
356
|
-
if (!this.
|
|
377
|
+
if (!this.keepsMeta) {
|
|
357
378
|
// The upstream shape: the whole tool_response, on every hook.
|
|
358
379
|
return {
|
|
359
380
|
_meta: { claudeCode: { toolResponse, toolName: toolUse.name } },
|
|
@@ -409,9 +430,10 @@ export class AcpToolCallRenderer {
|
|
|
409
430
|
*/
|
|
410
431
|
permissionDenied(denial) {
|
|
411
432
|
const reason = denial.decisionReason ?? denial.message;
|
|
412
|
-
// AIR
|
|
413
|
-
// the content shows. Every other client gets the upstream
|
|
414
|
-
|
|
433
|
+
// AIR and v2 get the SDK message only when it differs from the reason,
|
|
434
|
+
// which the content shows. Every other client gets the upstream
|
|
435
|
+
// toolResponse.
|
|
436
|
+
const extraMessage = !this.keepsMeta
|
|
415
437
|
? { decisionReason: denial.decisionReason, message: denial.message }
|
|
416
438
|
: denial.decisionReason !== undefined &&
|
|
417
439
|
denial.message !== undefined &&
|
|
@@ -438,17 +460,22 @@ export class AcpToolCallRenderer {
|
|
|
438
460
|
* reached a complete assistant message, for example because Claude switched
|
|
439
461
|
* to a steering message), a v2 client gets `cancelled` and every other
|
|
440
462
|
* client `failed`, since v1 has no `cancelled`. If Claude Code ran it but
|
|
441
|
-
* returned no result, it failed
|
|
463
|
+
* returned no result, it failed, unless a `session/cancel` ended the turn
|
|
464
|
+
* (`cancelled`): the cancel stopped the run, so a v2 client gets `cancelled`
|
|
465
|
+
* for it too.
|
|
442
466
|
*/
|
|
443
467
|
unfinished(call) {
|
|
468
|
+
const stopped = !call.ran || call.cancelled === true;
|
|
444
469
|
return {
|
|
445
470
|
sessionUpdate: "tool_call_update",
|
|
446
471
|
toolCallId: call.toolCallId,
|
|
447
|
-
status:
|
|
472
|
+
status: stopped && this.capabilities.v2 ? V2_CANCELLED : "failed",
|
|
448
473
|
content: [
|
|
449
|
-
textContent(call.ran
|
|
450
|
-
? "Claude
|
|
451
|
-
:
|
|
474
|
+
textContent(!call.ran
|
|
475
|
+
? "Claude stopped this tool call before it ran."
|
|
476
|
+
: call.cancelled
|
|
477
|
+
? "The turn was cancelled before this tool call returned a result."
|
|
478
|
+
: "Claude ended the turn without returning a result for this tool."),
|
|
452
479
|
],
|
|
453
480
|
};
|
|
454
481
|
}
|
|
@@ -519,9 +546,8 @@ export class AcpToolCallRenderer {
|
|
|
519
546
|
const input = toolUse.input !== null && typeof toolUse.input === "object"
|
|
520
547
|
? toolUse.input
|
|
521
548
|
: {};
|
|
522
|
-
const description =
|
|
523
|
-
|
|
524
|
-
? input.description
|
|
549
|
+
const description = toolUse.name === "Bash" || toolUse.name === "PowerShell"
|
|
550
|
+
? shellDescription(input)
|
|
525
551
|
: undefined;
|
|
526
552
|
const skillName = toolUse.name === "Skill" && typeof input.skill === "string" ? input.skill : undefined;
|
|
527
553
|
const subagent = toolUse.name === "Agent" || toolUse.name === "Task";
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { ToolReporter, ToolResultContext, ToolResultFacts, ToolUseFacts } from "../facts.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reads a Bash or PowerShell input's description the way the CLI validates it.
|
|
4
|
+
* Since CLI 2.1.295 the CLI accepts `command_description` for `description`.
|
|
5
|
+
* The streamed tool use keeps the original key. The canonical key wins when
|
|
6
|
+
* both spellings are present.
|
|
7
|
+
*/
|
|
8
|
+
export declare function shellDescription(input: unknown): string | undefined;
|
|
2
9
|
/** Bash and PowerShell: a command whose output goes to the terminal channel. */
|
|
3
10
|
export declare class BashReporter implements ToolReporter {
|
|
4
11
|
toolUse(input: unknown): ToolUseFacts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/bash.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAElG,gFAAgF;AAChF,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/bash.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAElG;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED,gFAAgF;AAChF,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;IAWrC,iFAAiF;IACjF,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,GAAG,SAAS;IAIpE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,iBAAiB,GAAG,eAAe;CAsFvE"}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { structuredResult, textContent, toAcpContentUpdate } from "../content.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reads a Bash or PowerShell input's description the way the CLI validates it.
|
|
4
|
+
* Since CLI 2.1.295 the CLI accepts `command_description` for `description`.
|
|
5
|
+
* The streamed tool use keeps the original key. The canonical key wins when
|
|
6
|
+
* both spellings are present.
|
|
7
|
+
*/
|
|
8
|
+
export function shellDescription(input) {
|
|
9
|
+
if (!input || typeof input !== "object")
|
|
10
|
+
return undefined;
|
|
11
|
+
const raw = input;
|
|
12
|
+
if (typeof raw.description === "string")
|
|
13
|
+
return raw.description;
|
|
14
|
+
return typeof raw.command_description === "string" ? raw.command_description : undefined;
|
|
15
|
+
}
|
|
2
16
|
/** Bash and PowerShell: a command whose output goes to the terminal channel. */
|
|
3
17
|
export class BashReporter {
|
|
4
18
|
toolUse(input) {
|
|
5
19
|
const bash = input;
|
|
20
|
+
const description = shellDescription(input);
|
|
6
21
|
return {
|
|
7
22
|
title: bash?.command ? bash.command : "Terminal",
|
|
8
23
|
kind: "execute",
|
|
9
24
|
command: true,
|
|
10
|
-
...(
|
|
25
|
+
...(description ? { display: [textContent(description)] } : {}),
|
|
11
26
|
};
|
|
12
27
|
}
|
|
13
28
|
/** A client with a terminal reads a failed command from the terminal channel. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,iDAAiD;AACjD,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;CAWtC;AAED,2DAA2D;AAC3D,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tool-calls/reporters/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,iDAAiD;AACjD,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;CAWtC;AAED,2DAA2D;AAC3D,qBAAa,YAAa,YAAW,YAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;CAoBtC;AAgBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK3D"}
|
|
@@ -29,9 +29,10 @@ export class GrepReporter {
|
|
|
29
29
|
label += ` -B ${grep["-B"]}`;
|
|
30
30
|
if (grep?.["-C"] !== undefined)
|
|
31
31
|
label += ` -C ${grep["-C"]}`;
|
|
32
|
-
|
|
32
|
+
const outputMode = grepOutputMode(input);
|
|
33
|
+
if (outputMode === "files_with_matches")
|
|
33
34
|
label += " -l";
|
|
34
|
-
else if (
|
|
35
|
+
else if (outputMode === "count")
|
|
35
36
|
label += " -c";
|
|
36
37
|
if (grep?.head_limit !== undefined)
|
|
37
38
|
label += ` | head -${grep.head_limit}`;
|
|
@@ -49,6 +50,23 @@ export class GrepReporter {
|
|
|
49
50
|
return { title: label, kind: "search" };
|
|
50
51
|
}
|
|
51
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Reads a Grep input's output mode the way the CLI validates it. Since CLI
|
|
55
|
+
* 2.1.295 the CLI reads a `-l` or `-c` flag (`true` or `"true"`) as
|
|
56
|
+
* `output_mode: "files_with_matches"` or `"count"` when `output_mode` is unset.
|
|
57
|
+
*/
|
|
58
|
+
function grepOutputMode(input) {
|
|
59
|
+
if (!input || typeof input !== "object")
|
|
60
|
+
return undefined;
|
|
61
|
+
const raw = input;
|
|
62
|
+
if (typeof raw.output_mode === "string")
|
|
63
|
+
return raw.output_mode;
|
|
64
|
+
if (raw["-l"] === true || raw["-l"] === "true")
|
|
65
|
+
return "files_with_matches";
|
|
66
|
+
if (raw["-c"] === true || raw["-c"] === "true")
|
|
67
|
+
return "count";
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
52
70
|
/**
|
|
53
71
|
* Reads a Grep input's path the way the CLI validates it. Since CLI 2.1.292
|
|
54
72
|
* the CLI accepts `file_path` for `path`. The streamed tool use keeps the
|
package/dist/v2/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/v2/agent.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAkB,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/v2/agent.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAkB,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAoB9E;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,EAAE,CAAC,QAAQ,CA2Eb"}
|
package/dist/v2/agent.js
CHANGED
|
@@ -3,9 +3,10 @@ import { ClaudeAcpAgent } from "../acp-agent.js";
|
|
|
3
3
|
import { v1InitializeRequest, v2InitializeResponse } from "./initialize.js";
|
|
4
4
|
import { v1PermissionResponse, v2PermissionRequest } from "./permission.js";
|
|
5
5
|
import { v2Foreground, v2Prompt } from "./prompt.js";
|
|
6
|
-
import {
|
|
7
|
-
import { v2SessionUpdate } from "./session-update.js";
|
|
6
|
+
import { v1ForkSessionRequest, v1NewSessionRequest, v1RestoreSessionRequest, v1SetSessionConfigOptionRequest, v2AvailableCommands, v2ConfigOptions, v2NewSessionResponse, v2ResumeSessionResponse, } from "./session.js";
|
|
7
|
+
import { v2ChildStateUpdate, v2SessionUpdate } from "./session-update.js";
|
|
8
8
|
import { V2Terminals } from "./terminal.js";
|
|
9
|
+
import { V2ToolCallMeta } from "./tool-call-meta.js";
|
|
9
10
|
/**
|
|
10
11
|
* The ACP v2 surface, for one connection.
|
|
11
12
|
*
|
|
@@ -55,17 +56,18 @@ export function v2AgentApp(logger, onAgent) {
|
|
|
55
56
|
};
|
|
56
57
|
})
|
|
57
58
|
.onRequest(v2.methods.agent.session.fork, async ({ params }) => {
|
|
58
|
-
|
|
59
|
-
const
|
|
59
|
+
// The agent starts the forked session, so the client can prompt it.
|
|
60
|
+
const response = await agent.unstable_forkSession(v1ForkSessionRequest(params));
|
|
60
61
|
return {
|
|
61
|
-
sessionId,
|
|
62
|
-
...v2ResumeSessionResponse(
|
|
63
|
-
...(await setupCommands(agent, sessionId, logger)),
|
|
62
|
+
sessionId: response.sessionId,
|
|
63
|
+
...v2ResumeSessionResponse(response),
|
|
64
|
+
...(await setupCommands(agent, response.sessionId, logger)),
|
|
64
65
|
};
|
|
65
66
|
})
|
|
66
67
|
.onRequest(v2.methods.agent.session.close, async ({ params }) => {
|
|
67
68
|
const response = await agent.closeSession(params);
|
|
68
69
|
client.terminals.forget(params.sessionId);
|
|
70
|
+
client.toolCallMeta.forget(params.sessionId);
|
|
69
71
|
return response;
|
|
70
72
|
})
|
|
71
73
|
.onRequest(v2.methods.agent.session.delete, ({ params }) => agent.deleteSession(params))
|
|
@@ -105,11 +107,16 @@ class V2ClientConnection {
|
|
|
105
107
|
logger;
|
|
106
108
|
/**
|
|
107
109
|
* The sessions whose history replays, each with the messages that the
|
|
108
|
-
* replay has cleared so far.
|
|
110
|
+
* replay has cleared so far. A subagent that a replay announces replays
|
|
111
|
+
* with it.
|
|
109
112
|
*/
|
|
110
113
|
replays = new Map();
|
|
114
|
+
/** The session whose replay announced each replaying subagent. */
|
|
115
|
+
replayRoots = new Map();
|
|
111
116
|
/** The display terminals of the commands that the agent runs. */
|
|
112
117
|
terminals = new V2Terminals();
|
|
118
|
+
/** The `_meta` that the client stores for each tool call. */
|
|
119
|
+
toolCallMeta = new V2ToolCallMeta();
|
|
113
120
|
constructor(ctx, logger) {
|
|
114
121
|
this.ctx = ctx;
|
|
115
122
|
this.logger = logger;
|
|
@@ -129,6 +136,12 @@ class V2ClientConnection {
|
|
|
129
136
|
}
|
|
130
137
|
finally {
|
|
131
138
|
this.replays.delete(sessionId);
|
|
139
|
+
for (const [child, root] of this.replayRoots) {
|
|
140
|
+
if (root !== sessionId)
|
|
141
|
+
continue;
|
|
142
|
+
this.replays.delete(child);
|
|
143
|
+
this.replayRoots.delete(child);
|
|
144
|
+
}
|
|
132
145
|
}
|
|
133
146
|
}
|
|
134
147
|
/**
|
|
@@ -152,17 +165,32 @@ class V2ClientConnection {
|
|
|
152
165
|
return this.ctx.notify(method, params);
|
|
153
166
|
}
|
|
154
167
|
async sessionUpdate({ update, ...notification }) {
|
|
168
|
+
// A subagent that a replay announces replays too, so its messages are
|
|
169
|
+
// cleared before their first replayed chunk, as the parent's are.
|
|
170
|
+
if (update.sessionUpdate === "subagent_update" &&
|
|
171
|
+
this.replays.has(notification.sessionId) &&
|
|
172
|
+
!this.replays.has(update.sessionId)) {
|
|
173
|
+
this.replays.set(update.sessionId, new Set());
|
|
174
|
+
this.replayRoots.set(update.sessionId, this.replayRoots.get(notification.sessionId) ?? notification.sessionId);
|
|
175
|
+
}
|
|
155
176
|
const updates = this.v2Updates(notification.sessionId, update).flatMap((v2Update) => {
|
|
156
177
|
const clear = this.replayClear(notification.sessionId, v2Update);
|
|
157
178
|
return clear ? [clear, v2Update] : [v2Update];
|
|
158
179
|
});
|
|
180
|
+
// A subagent's work state also goes to the child's own stream, after the
|
|
181
|
+
// parent's copy.
|
|
182
|
+
const childState = v2ChildStateUpdate(update);
|
|
159
183
|
// Every update goes to the connection before any is awaited, so an update
|
|
160
184
|
// that another call sends meanwhile cannot come between them.
|
|
161
|
-
await Promise.all(
|
|
185
|
+
await Promise.all([
|
|
186
|
+
...updates.map((v2Update) => this.ctx.notify(v2.methods.client.session.update, { ...notification, update: v2Update })),
|
|
187
|
+
...(childState ? [this.ctx.notify(v2.methods.client.session.update, childState)] : []),
|
|
188
|
+
]);
|
|
162
189
|
}
|
|
163
190
|
/**
|
|
164
191
|
* The v2 updates of a v1 update: for a tool call report, the updates of its
|
|
165
|
-
* terminal first, then the report itself
|
|
192
|
+
* terminal first (see {@link V2Terminals}), then the report itself, with the
|
|
193
|
+
* `_meta` that the client stores (see {@link V2ToolCallMeta}).
|
|
166
194
|
*/
|
|
167
195
|
v2Updates(sessionId, update) {
|
|
168
196
|
if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
|
|
@@ -170,7 +198,10 @@ class V2ClientConnection {
|
|
|
170
198
|
return v2Update ? [v2Update] : [];
|
|
171
199
|
}
|
|
172
200
|
const { terminal, report } = this.terminals.split(sessionId, update);
|
|
173
|
-
|
|
201
|
+
if (!report)
|
|
202
|
+
return terminal;
|
|
203
|
+
const starts = report.sessionUpdate === "tool_call";
|
|
204
|
+
const reportUpdate = v2SessionUpdate(this.toolCallMeta.apply(sessionId, report, starts));
|
|
174
205
|
return [...terminal, ...(reportUpdate ? [reportUpdate] : [])];
|
|
175
206
|
}
|
|
176
207
|
/**
|
|
@@ -192,7 +223,9 @@ class V2ClientConnection {
|
|
|
192
223
|
return emptyMessage(kind, messageId);
|
|
193
224
|
}
|
|
194
225
|
async requestPermission(params, signal) {
|
|
195
|
-
|
|
226
|
+
// The subject is an update of the tool call, with its stored `_meta`.
|
|
227
|
+
const toolCall = this.toolCallMeta.subject(params.sessionId, params.toolCall);
|
|
228
|
+
const response = await this.ctx.request(v2.methods.client.session.requestPermission, v2PermissionRequest({ ...params, toolCall }), { cancellationSignal: signal });
|
|
196
229
|
return v1PermissionResponse(response);
|
|
197
230
|
}
|
|
198
231
|
// Elicitation is the same in v1 and v2.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/v2/initialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAE/D,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/v2/initialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAE/D,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,GAAG,iBAAiB,CAmCpF;AASD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,EAAE,CAAC,kBAAkB,CAuBxF"}
|
package/dist/v2/initialize.js
CHANGED
|
@@ -26,6 +26,15 @@ export function v1InitializeRequest(request) {
|
|
|
26
26
|
// compaction as a compaction entity rather than as a "Compact
|
|
27
27
|
// conversation" tool call, also on replay.
|
|
28
28
|
session: { configOptions: { boolean: {} }, notices: {}, compaction: {} },
|
|
29
|
+
// Every v2 client takes `plan_update`, with the draft's markdown and file
|
|
30
|
+
// plans, and `plan_removed`; v1 asks for the `plan` marker. With it, the
|
|
31
|
+
// agent shows an approved ExitPlanMode plan as a markdown plan.
|
|
32
|
+
plan: {},
|
|
33
|
+
// Subagent updates are part of v2's baseline session model (the subagents
|
|
34
|
+
// RFD), so every v2 client takes them; v1 asks for the `subagents`
|
|
35
|
+
// capability. With it, the agent reports each Agent or Task subagent as a
|
|
36
|
+
// child session.
|
|
37
|
+
subagents: {},
|
|
29
38
|
// v1 marks terminal auth support with a boolean, v2 with an object.
|
|
30
39
|
auth: {
|
|
31
40
|
terminal: capabilities?.auth?.terminal != null,
|
|
@@ -78,7 +87,7 @@ export function v2InitializeResponse(response) {
|
|
|
78
87
|
* - The session baseline: `session/new`, `list`, `resume` (with replay),
|
|
79
88
|
* `close`, `prompt`, `cancel`, and `update`.
|
|
80
89
|
* - `session/delete`, `session/fork` (which returns a session the client can
|
|
81
|
-
* prompt
|
|
90
|
+
* prompt at once), and `additionalDirectories`.
|
|
82
91
|
* - The prompt content and MCP transports that the agent's v1 `initialize`
|
|
83
92
|
* lists: images, embedded context, and HTTP servers. Stdio servers are in the
|
|
84
93
|
* v1 baseline; v2 has no SSE transport.
|
|
@@ -18,4 +18,15 @@ export declare const SESSION_PLAN_ID = "plan";
|
|
|
18
18
|
* an error rather than a silently missing update.
|
|
19
19
|
*/
|
|
20
20
|
export declare function v2SessionUpdate(update: AcpSessionNotification["update"]): v2.SessionUpdate | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* The child's own `state_update` for a v1 `subagent_update` that reports the
|
|
23
|
+
* child's work state, or `undefined` when it reports none.
|
|
24
|
+
*
|
|
25
|
+
* v1 reports a child's work state only on its parent, as the `state` of the
|
|
26
|
+
* `subagent_update`. v2 reports it on the child's own stream, as for any
|
|
27
|
+
* session, and mirrors it on the parent (the subagents RFD). The child's copy
|
|
28
|
+
* goes right after the parent's: never before the announcement, and both
|
|
29
|
+
* copies of a state before any later state.
|
|
30
|
+
*/
|
|
31
|
+
export declare function v2ChildStateUpdate(update: AcpSessionNotification["update"]): v2.UpdateSessionNotification | undefined;
|
|
21
32
|
//# sourceMappingURL=session-update.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-update.d.ts","sourceRoot":"","sources":["../../src/v2/session-update.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE;;;;GAIG;AACH,eAAO,MAAM,eAAe,SAAS,CAAC;AAEtC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACvC,EAAE,CAAC,aAAa,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"session-update.d.ts","sourceRoot":"","sources":["../../src/v2/session-update.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE;;;;GAIG;AACH,eAAO,MAAM,eAAe,SAAS,CAAC;AAEtC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACvC,EAAE,CAAC,aAAa,GAAG,SAAS,CAyD9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACvC,EAAE,CAAC,yBAAyB,GAAG,SAAS,CAM1C"}
|
|
@@ -45,6 +45,21 @@ export function v2SessionUpdate(update) {
|
|
|
45
45
|
plan: { type: "items", planId: SESSION_PLAN_ID, entries: update.entries },
|
|
46
46
|
...(update._meta != null ? { _meta: update._meta } : {}),
|
|
47
47
|
};
|
|
48
|
+
case "plan_update":
|
|
49
|
+
case "plan_removed":
|
|
50
|
+
// v1's draft plan operations have v2's shape.
|
|
51
|
+
return update;
|
|
52
|
+
case "subagent_update": {
|
|
53
|
+
// The subagents RFD gives it the same shape in v1 and v2. One that
|
|
54
|
+
// reports a state also has a copy on the child's stream (see
|
|
55
|
+
// `v2ChildStateUpdate`).
|
|
56
|
+
const { state, ...association } = update;
|
|
57
|
+
return { ...association, ...(state != null ? { state: v2SubagentState(state) } : {}) };
|
|
58
|
+
}
|
|
59
|
+
case "session_message":
|
|
60
|
+
case "session_message_chunk":
|
|
61
|
+
// The subagents RFD gives these the same shape in v1 and v2.
|
|
62
|
+
return update;
|
|
48
63
|
case "current_mode_update":
|
|
49
64
|
// v2 has no modes: the mode is the `mode` config option. Every mode
|
|
50
65
|
// change also reaches the client as a `config_option_update` or in the
|
|
@@ -54,3 +69,55 @@ export function v2SessionUpdate(update) {
|
|
|
54
69
|
throw new Error(`The ACP v2 surface does not translate ${update.sessionUpdate} session updates yet`);
|
|
55
70
|
}
|
|
56
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* The child's own `state_update` for a v1 `subagent_update` that reports the
|
|
74
|
+
* child's work state, or `undefined` when it reports none.
|
|
75
|
+
*
|
|
76
|
+
* v1 reports a child's work state only on its parent, as the `state` of the
|
|
77
|
+
* `subagent_update`. v2 reports it on the child's own stream, as for any
|
|
78
|
+
* session, and mirrors it on the parent (the subagents RFD). The child's copy
|
|
79
|
+
* goes right after the parent's: never before the announcement, and both
|
|
80
|
+
* copies of a state before any later state.
|
|
81
|
+
*/
|
|
82
|
+
export function v2ChildStateUpdate(update) {
|
|
83
|
+
if (update.sessionUpdate !== "subagent_update" || update.state == null)
|
|
84
|
+
return undefined;
|
|
85
|
+
return {
|
|
86
|
+
sessionId: update.sessionId,
|
|
87
|
+
update: { sessionUpdate: "state_update", ...v2SubagentState(update.state) },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** The work states of the subagents RFD, and the stop reasons of its `idle`. */
|
|
91
|
+
const SUBAGENT_STATES = new Set([
|
|
92
|
+
"running",
|
|
93
|
+
"requires_action",
|
|
94
|
+
"unknown",
|
|
95
|
+
"idle",
|
|
96
|
+
]);
|
|
97
|
+
const IDLE_STOP_REASONS = new Set([
|
|
98
|
+
undefined,
|
|
99
|
+
null,
|
|
100
|
+
"end_turn",
|
|
101
|
+
"max_tokens",
|
|
102
|
+
"max_turn_requests",
|
|
103
|
+
"refusal",
|
|
104
|
+
"cancelled",
|
|
105
|
+
"error",
|
|
106
|
+
]);
|
|
107
|
+
/**
|
|
108
|
+
* The v2 form of a subagent's v1 work state.
|
|
109
|
+
*
|
|
110
|
+
* The RFD's states have the same shape in v1 and v2. Each version also types
|
|
111
|
+
* an open member for states and stop reasons it does not know, and those two
|
|
112
|
+
* members are typed apart. So the state is checked to be one of the RFD's, and
|
|
113
|
+
* any other throws, as an update kind that this surface does not translate
|
|
114
|
+
* does.
|
|
115
|
+
*/
|
|
116
|
+
function v2SubagentState(state) {
|
|
117
|
+
const stopReason = state.stopReason;
|
|
118
|
+
if (!SUBAGENT_STATES.has(state.state) ||
|
|
119
|
+
(state.state === "idle" && !IDLE_STOP_REASONS.has(stopReason))) {
|
|
120
|
+
throw new Error(`The ACP v2 surface does not translate the subagent state ${state.state}${state.state === "idle" ? ` with the stop reason ${String(stopReason)}` : ""}`);
|
|
121
|
+
}
|
|
122
|
+
return state;
|
|
123
|
+
}
|
package/dist/v2/session.d.ts
CHANGED
|
@@ -23,19 +23,10 @@ export declare function v1RestoreSessionRequest(params: v2.ResumeSessionRequest)
|
|
|
23
23
|
request: LoadSessionRequest;
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
|
-
* The v1
|
|
27
|
-
*
|
|
28
|
-
* The agent's v1 fork copies the transcript into a new session and returns
|
|
29
|
-
* only its id; a v1 client then resumes or loads it. A v2 fork returns the new
|
|
30
|
-
* session with its config options, like `session/new`, so the client can
|
|
31
|
-
* prompt it. The v2 surface therefore forks, then resumes the fork without
|
|
32
|
-
* replay, with the request's `cwd`, `additionalDirectories`, and
|
|
33
|
-
* `mcpServers`. The request's `_meta` goes to the fork alone.
|
|
26
|
+
* The v1 request of a v2 `session/fork`. In both versions the agent's fork
|
|
27
|
+
* returns a session that the client can prompt, with its config options.
|
|
34
28
|
*/
|
|
35
|
-
export declare function
|
|
36
|
-
fork: ForkSessionRequest;
|
|
37
|
-
resume: (sessionId: string) => ResumeSessionRequest;
|
|
38
|
-
};
|
|
29
|
+
export declare function v1ForkSessionRequest(params: v2.ForkSessionRequest): ForkSessionRequest;
|
|
39
30
|
/** v2 drops `modes`: the session mode is the `mode` config option, which the agent always lists. */
|
|
40
31
|
export declare function v2NewSessionResponse(response: NewSessionResponse): v2.NewSessionResponse;
|
|
41
32
|
export declare function v2ResumeSessionResponse(response: ResumeSessionResponse): v2.ResumeSessionResponse;
|
package/dist/v2/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/v2/session.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAEvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAGxB,KAAK,6BAA6B,EACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAE/D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,GAAG,iBAAiB,CAInF;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,EAAE,CAAC,oBAAoB,GAE7B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAkBlD;AAED
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/v2/session.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAEvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAGxB,KAAK,6BAA6B,EACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAE/D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,GAAG,iBAAiB,CAInF;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,EAAE,CAAC,oBAAoB,GAE7B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAkBlD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,GAAG,kBAAkB,CAGtF;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,EAAE,CAAC,kBAAkB,CAExF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,EAAE,CAAC,qBAAqB,CAKjG;AAED,uEAAuE;AACvE,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,EAAE,CAAC,6BAA6B,GACvC,6BAA6B,CAgB/B;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAQxF;AAWD,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAKvF"}
|