@agentclientprotocol/claude-agent-acp 0.69.0 → 0.71.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 +10 -9
- package/dist/acp-agent.d.ts +118 -39
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +1199 -682
- package/dist/acp-subagents.d.ts +82 -0
- package/dist/acp-subagents.d.ts.map +1 -0
- package/dist/acp-subagents.js +13 -0
- package/dist/air-extension.d.ts +23 -0
- package/dist/air-extension.d.ts.map +1 -0
- package/dist/air-extension.js +63 -0
- package/dist/async-tasks.d.ts +109 -0
- package/dist/async-tasks.d.ts.map +1 -0
- package/dist/async-tasks.js +613 -0
- package/dist/clear-context-coordinator.d.ts +60 -0
- package/dist/clear-context-coordinator.d.ts.map +1 -0
- package/dist/clear-context-coordinator.js +80 -0
- package/dist/exit-plan.d.ts +42 -0
- package/dist/exit-plan.d.ts.map +1 -0
- package/dist/exit-plan.js +154 -0
- package/dist/file-change-audit.d.ts.map +1 -1
- package/dist/file-change-audit.js +4 -33
- package/dist/fork-session.d.ts +12 -0
- package/dist/fork-session.d.ts.map +1 -0
- package/dist/fork-session.js +41 -0
- package/dist/index.js +24 -1
- package/dist/native-subagents.d.ts +71 -0
- package/dist/native-subagents.d.ts.map +1 -0
- package/dist/native-subagents.js +422 -0
- package/dist/permissions/effects.d.ts +19 -0
- package/dist/permissions/effects.d.ts.map +1 -0
- package/dist/permissions/effects.js +166 -0
- package/dist/permissions/modes.d.ts +8 -0
- package/dist/permissions/modes.d.ts.map +1 -0
- package/dist/permissions/modes.js +41 -0
- package/dist/permissions/normalization.d.ts +6 -0
- package/dist/permissions/normalization.d.ts.map +1 -0
- package/dist/permissions/normalization.js +100 -0
- package/dist/permissions/options/filesystem.d.ts +9 -0
- package/dist/permissions/options/filesystem.d.ts.map +1 -0
- package/dist/permissions/options/filesystem.js +124 -0
- package/dist/permissions/options/shared.d.ts +39 -0
- package/dist/permissions/options/shared.d.ts.map +1 -0
- package/dist/permissions/options/shared.js +64 -0
- package/dist/permissions/options/shell.d.ts +5 -0
- package/dist/permissions/options/shell.d.ts.map +1 -0
- package/dist/permissions/options/shell.js +100 -0
- package/dist/permissions/options/tools.d.ts +11 -0
- package/dist/permissions/options/tools.d.ts.map +1 -0
- package/dist/permissions/options/tools.js +135 -0
- package/dist/permissions/options.d.ts +5 -0
- package/dist/permissions/options.d.ts.map +1 -0
- package/dist/permissions/options.js +60 -0
- package/dist/permissions/presentation.d.ts +15 -0
- package/dist/permissions/presentation.d.ts.map +1 -0
- package/dist/permissions/presentation.js +83 -0
- package/dist/permissions/response.d.ts +11 -0
- package/dist/permissions/response.d.ts.map +1 -0
- package/dist/permissions/response.js +19 -0
- package/dist/session-config-ids.d.ts +5 -0
- package/dist/session-config-ids.d.ts.map +1 -0
- package/dist/session-config-ids.js +4 -0
- package/dist/session-failure-extension.d.ts +2 -24
- package/dist/session-failure-extension.d.ts.map +1 -1
- package/dist/session-failure-extension.js +13 -40
- package/dist/session-mode.d.ts +66 -0
- package/dist/session-mode.d.ts.map +1 -0
- package/dist/session-mode.js +234 -0
- package/dist/session-titles.d.ts +77 -0
- package/dist/session-titles.d.ts.map +1 -0
- package/dist/session-titles.js +199 -0
- package/dist/tool-result-meta.d.ts +8 -0
- package/dist/tool-result-meta.d.ts.map +1 -0
- package/dist/tool-result-meta.js +19 -0
- package/dist/tools.d.ts +6 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +39 -18
- package/package.json +6 -6
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DEFAULT_AGENT_ID, DEFAULT_MODEL_ID, EFFORT_CONFIG_ID } from "./session-config-ids.js";
|
|
2
|
+
function restartParams(session) {
|
|
3
|
+
const originalParams = session.creationParams ?? { cwd: session.cwd, mcpServers: [] };
|
|
4
|
+
const currentEffort = session.configOptions.find((option) => option.id === EFFORT_CONFIG_ID)?.currentValue;
|
|
5
|
+
const originalMeta = originalParams._meta;
|
|
6
|
+
const originalOptions = originalMeta?.claudeCode?.options;
|
|
7
|
+
const unmanagedOptions = { ...(originalOptions ?? {}) };
|
|
8
|
+
delete unmanagedOptions.model;
|
|
9
|
+
delete unmanagedOptions.agent;
|
|
10
|
+
delete unmanagedOptions.effort;
|
|
11
|
+
return {
|
|
12
|
+
...originalParams,
|
|
13
|
+
_meta: {
|
|
14
|
+
...(originalMeta ?? {}),
|
|
15
|
+
claudeCode: {
|
|
16
|
+
...(originalMeta?.claudeCode ?? {}),
|
|
17
|
+
options: {
|
|
18
|
+
...unmanagedOptions,
|
|
19
|
+
...(session.models.currentModelId !== DEFAULT_MODEL_ID
|
|
20
|
+
? { model: session.models.currentModelId }
|
|
21
|
+
: {}),
|
|
22
|
+
...(session.currentAgent !== DEFAULT_AGENT_ID ? { agent: session.currentAgent } : {}),
|
|
23
|
+
...(typeof currentEffort === "string" && currentEffort !== "default"
|
|
24
|
+
? { effort: currentEffort }
|
|
25
|
+
: {}),
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Replace Claude's private conversation and attach the still-pending ACP turn
|
|
32
|
+
* to it. The host owns provider-specific creation and stream mechanics; this
|
|
33
|
+
* coordinator owns the ordering and state transfer invariants. */
|
|
34
|
+
export async function continuePlanInFreshContext(sessionId, oldSession, reset, host, signal) {
|
|
35
|
+
const assertRestartActive = (session) => {
|
|
36
|
+
if (signal?.aborted || (session && host.currentSession(sessionId) !== session)) {
|
|
37
|
+
throw new Error("Clear-context restart aborted");
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
assertRestartActive();
|
|
41
|
+
const turn = oldSession.activeTurn;
|
|
42
|
+
if (!turn || turn.settled || host.currentSession(sessionId) !== oldSession) {
|
|
43
|
+
throw new Error("Cannot clear context without an active ACP turn");
|
|
44
|
+
}
|
|
45
|
+
const params = restartParams(oldSession);
|
|
46
|
+
host.closeQueryStream(oldSession);
|
|
47
|
+
const freshSession = await host.restartSession(params, {
|
|
48
|
+
publicSessionId: sessionId,
|
|
49
|
+
permissionMode: reset.mode,
|
|
50
|
+
});
|
|
51
|
+
assertRestartActive(freshSession);
|
|
52
|
+
// Do not consume the reset or mutate the turn until a replacement exists.
|
|
53
|
+
// A failed restart must remain distinguishable from a lost query transport.
|
|
54
|
+
turn.carriedUsage = { ...oldSession.accumulatedUsage };
|
|
55
|
+
turn.carriedModelUsage = { ...oldSession.accumulatedModelUsage };
|
|
56
|
+
oldSession.pendingExitPlanContextReset = undefined;
|
|
57
|
+
if (oldSession.fastModeEnabled !== freshSession.fastModeEnabled) {
|
|
58
|
+
try {
|
|
59
|
+
await host.applyFastMode(freshSession, oldSession.fastModeEnabled);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
host.logError("Failed to restore Fast mode after clearing context:", error);
|
|
63
|
+
}
|
|
64
|
+
assertRestartActive(freshSession);
|
|
65
|
+
}
|
|
66
|
+
oldSession.activeTurn = null;
|
|
67
|
+
oldSession.turnQueue = [];
|
|
68
|
+
freshSession.turnQueue = [turn];
|
|
69
|
+
freshSession.contextUsedTokens = 0;
|
|
70
|
+
try {
|
|
71
|
+
await host.publishSessionState(sessionId, reset.mode, freshSession.configOptions);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
host.logError("Failed to publish clear-context session state:", error);
|
|
75
|
+
}
|
|
76
|
+
assertRestartActive(freshSession);
|
|
77
|
+
freshSession.input.push(host.continuationMessage(sessionId, reset.plan, turn.promptUuid));
|
|
78
|
+
assertRestartActive(freshSession);
|
|
79
|
+
host.ensureConsumer(freshSession, sessionId);
|
|
80
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SessionNotification } from "@agentclientprotocol/sdk";
|
|
2
|
+
import type { SDKResultMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
3
|
+
import { type ClearContextCoordinatorHost, type ClearContextReset, type ClearContextSession, type ClearContextTurn } from "./clear-context-coordinator.js";
|
|
4
|
+
export declare function acceptedPlanToolResult(notification: SessionNotification, toolUseId: string | undefined): SessionNotification;
|
|
5
|
+
type ExitPlanState = {
|
|
6
|
+
toolUseCache: Record<string, {
|
|
7
|
+
name: string;
|
|
8
|
+
} | undefined>;
|
|
9
|
+
pendingExitPlanModeInterruption?: {
|
|
10
|
+
toolUseId: string;
|
|
11
|
+
toolResultSeen: boolean;
|
|
12
|
+
};
|
|
13
|
+
pendingExitPlanContextReset?: ClearContextReset;
|
|
14
|
+
};
|
|
15
|
+
/** Reconcile an SDK user message with the two pending ExitPlanMode lanes and
|
|
16
|
+
* return the accepted plan tool id whose rendered update must be completed. */
|
|
17
|
+
export declare function observeExitPlanToolResults(message: {
|
|
18
|
+
type: string;
|
|
19
|
+
tool_result_meta?: unknown;
|
|
20
|
+
}, content: unknown, state: ExitPlanState): string | undefined;
|
|
21
|
+
export declare function executionDiagnostic(message: SDKResultMessage): string | undefined;
|
|
22
|
+
/** Claude wraps a rejected ExitPlanMode explanation in a Markdown code fence.
|
|
23
|
+
* Strip exactly one complete outer fence for that tool only. */
|
|
24
|
+
export declare function exitPlanModeRawOutput(toolName: string, content: unknown): unknown;
|
|
25
|
+
export type ExitPlanRestartHost<Session extends ClearContextSession<Turn>, Turn extends ClearContextTurn> = Omit<ClearContextCoordinatorHost<Session, Turn>, "publishSessionState" | "continuationMessage"> & {
|
|
26
|
+
sessionUpdate(notification: SessionNotification): Promise<void>;
|
|
27
|
+
destroyReplacement(sessionId: string, session: Session): void;
|
|
28
|
+
settleCancelledTurn(oldSession: Session, turnSession: Session, turn: Turn): void;
|
|
29
|
+
settleFailedTurn(turnSession: Session, turn: Turn, error: unknown): void;
|
|
30
|
+
};
|
|
31
|
+
/** Owns the lifetime of accepted-plan context replacements. In particular, a
|
|
32
|
+
* session cancellation invalidates an in-progress async restart so a late
|
|
33
|
+
* restartSession result cannot recreate a closed public session. */
|
|
34
|
+
export declare class ExitPlanCoordinator<Session extends ClearContextSession<Turn>, Turn extends ClearContextTurn> {
|
|
35
|
+
private readonly host;
|
|
36
|
+
private readonly restarts;
|
|
37
|
+
constructor(host: ExitPlanRestartHost<Session, Turn>);
|
|
38
|
+
cancel(sessionId: string): void;
|
|
39
|
+
restart(sessionId: string, oldSession: Session, reset: ClearContextReset): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=exit-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-plan.d.ts","sourceRoot":"","sources":["../src/exit-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAEtB,MAAM,gCAAgC,CAAC;AAGxC,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,mBAAmB,EACjC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,mBAAmB,CAarB;AAeD,KAAK,aAAa,GAAG;IACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IAC3D,+BAA+B,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IACjF,2BAA2B,CAAC,EAAE,iBAAiB,CAAC;CACjD,CAAC;AA0BF;+EAC+E;AAC/E,wBAAgB,0BAA0B,CACxC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,EACrD,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,aAAa,GACnB,MAAM,GAAG,SAAS,CA0BpB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAKjF;AAED;gEACgE;AAChE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAMjF;AAED,MAAM,MAAM,mBAAmB,CAC7B,OAAO,SAAS,mBAAmB,CAAC,IAAI,CAAC,EACzC,IAAI,SAAS,gBAAgB,IAC3B,IAAI,CACN,2BAA2B,CAAC,OAAO,EAAE,IAAI,CAAC,EAC1C,qBAAqB,GAAG,qBAAqB,CAC9C,GAAG;IACF,aAAa,CAAC,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9D,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IACjF,gBAAgB,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1E,CAAC;AAEF;;oEAEoE;AACpE,qBAAa,mBAAmB,CAC9B,OAAO,SAAS,mBAAmB,CAAC,IAAI,CAAC,EACzC,IAAI,SAAS,gBAAgB;IAIjB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;gBAElC,IAAI,EAAE,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC;IAErE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAiE/F"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { continuePlanInFreshContext, } from "./clear-context-coordinator.js";
|
|
2
|
+
import { parseToolResultMeta } from "./tool-result-meta.js";
|
|
3
|
+
export function acceptedPlanToolResult(notification, toolUseId) {
|
|
4
|
+
const update = notification.update;
|
|
5
|
+
if (!toolUseId ||
|
|
6
|
+
update.sessionUpdate !== "tool_call_update" ||
|
|
7
|
+
update.toolCallId !== toolUseId) {
|
|
8
|
+
return notification;
|
|
9
|
+
}
|
|
10
|
+
const completed = { ...update };
|
|
11
|
+
delete completed.rawOutput;
|
|
12
|
+
delete completed.content;
|
|
13
|
+
return { ...notification, update: { ...completed, status: "completed" } };
|
|
14
|
+
}
|
|
15
|
+
function containsToolResultFor(content, toolUseId) {
|
|
16
|
+
return (Array.isArray(content) &&
|
|
17
|
+
content.some((block) => typeof block === "object" &&
|
|
18
|
+
block !== null &&
|
|
19
|
+
block.type === "tool_result" &&
|
|
20
|
+
block.tool_use_id === toolUseId));
|
|
21
|
+
}
|
|
22
|
+
function rejectedExitPlanToolUseId(content, toolUseCache, rawToolResultMeta) {
|
|
23
|
+
if (!Array.isArray(content))
|
|
24
|
+
return undefined;
|
|
25
|
+
const toolResultMeta = parseToolResultMeta(rawToolResultMeta);
|
|
26
|
+
if (!toolResultMeta)
|
|
27
|
+
return undefined;
|
|
28
|
+
for (const block of content) {
|
|
29
|
+
if (typeof block !== "object" || block === null)
|
|
30
|
+
continue;
|
|
31
|
+
const { type, tool_use_id: toolUseId, is_error: isError } = block;
|
|
32
|
+
if (type === "tool_result" &&
|
|
33
|
+
typeof toolUseId === "string" &&
|
|
34
|
+
isError === true &&
|
|
35
|
+
toolResultMeta.get(toolUseId)?.nonExecutionKind === "user-rejected" &&
|
|
36
|
+
toolUseCache[toolUseId]?.name === "ExitPlanMode") {
|
|
37
|
+
return toolUseId;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/** Reconcile an SDK user message with the two pending ExitPlanMode lanes and
|
|
43
|
+
* return the accepted plan tool id whose rendered update must be completed. */
|
|
44
|
+
export function observeExitPlanToolResults(message, content, state) {
|
|
45
|
+
if (message.type !== "user")
|
|
46
|
+
return undefined;
|
|
47
|
+
const rejectedToolUseId = rejectedExitPlanToolUseId(content, state.toolUseCache, message.tool_result_meta);
|
|
48
|
+
if (rejectedToolUseId) {
|
|
49
|
+
// The stream is authoritative: resumed queries can lose the short-lived
|
|
50
|
+
// marker installed by canUseTool, while metadata preserves correlation.
|
|
51
|
+
state.pendingExitPlanModeInterruption = {
|
|
52
|
+
toolUseId: rejectedToolUseId,
|
|
53
|
+
toolResultSeen: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const pendingInterruption = state.pendingExitPlanModeInterruption;
|
|
57
|
+
if (pendingInterruption && containsToolResultFor(content, pendingInterruption.toolUseId)) {
|
|
58
|
+
pendingInterruption.toolResultSeen = true;
|
|
59
|
+
}
|
|
60
|
+
const pendingReset = state.pendingExitPlanContextReset;
|
|
61
|
+
return pendingReset && containsToolResultFor(content, pendingReset.toolUseId)
|
|
62
|
+
? pendingReset.toolUseId
|
|
63
|
+
: undefined;
|
|
64
|
+
}
|
|
65
|
+
export function executionDiagnostic(message) {
|
|
66
|
+
if (message.subtype === "success") {
|
|
67
|
+
return message.result.startsWith("[ede_diagnostic]") ? message.result : undefined;
|
|
68
|
+
}
|
|
69
|
+
return message.errors.find((error) => error.startsWith("[ede_diagnostic]"));
|
|
70
|
+
}
|
|
71
|
+
/** Claude wraps a rejected ExitPlanMode explanation in a Markdown code fence.
|
|
72
|
+
* Strip exactly one complete outer fence for that tool only. */
|
|
73
|
+
export function exitPlanModeRawOutput(toolName, content) {
|
|
74
|
+
if (toolName !== "ExitPlanMode" || typeof content !== "string") {
|
|
75
|
+
return content;
|
|
76
|
+
}
|
|
77
|
+
const fenced = /^\s*```[^\r\n]*\r?\n([\s\S]*?)\r?\n```\s*$/.exec(content);
|
|
78
|
+
return fenced?.[1] ?? content;
|
|
79
|
+
}
|
|
80
|
+
/** Owns the lifetime of accepted-plan context replacements. In particular, a
|
|
81
|
+
* session cancellation invalidates an in-progress async restart so a late
|
|
82
|
+
* restartSession result cannot recreate a closed public session. */
|
|
83
|
+
export class ExitPlanCoordinator {
|
|
84
|
+
host;
|
|
85
|
+
restarts = new Map();
|
|
86
|
+
constructor(host) {
|
|
87
|
+
this.host = host;
|
|
88
|
+
}
|
|
89
|
+
cancel(sessionId) {
|
|
90
|
+
this.restarts.get(sessionId)?.abort();
|
|
91
|
+
}
|
|
92
|
+
async restart(sessionId, oldSession, reset) {
|
|
93
|
+
this.cancel(sessionId);
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
this.restarts.set(sessionId, controller);
|
|
96
|
+
try {
|
|
97
|
+
const clearContextHost = {
|
|
98
|
+
...this.host,
|
|
99
|
+
publishSessionState: async (id, mode, configOptions) => {
|
|
100
|
+
await this.host.sessionUpdate({
|
|
101
|
+
sessionId: id,
|
|
102
|
+
update: { sessionUpdate: "current_mode_update", currentModeId: mode },
|
|
103
|
+
});
|
|
104
|
+
await this.host.sessionUpdate({
|
|
105
|
+
sessionId: id,
|
|
106
|
+
update: { sessionUpdate: "config_option_update", configOptions },
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
continuationMessage: (id, plan, promptUuid) => ({
|
|
110
|
+
type: "user",
|
|
111
|
+
message: {
|
|
112
|
+
role: "user",
|
|
113
|
+
content: [{ type: "text", text: `Implement the following plan:\n\n${plan}` }],
|
|
114
|
+
},
|
|
115
|
+
session_id: id,
|
|
116
|
+
parent_tool_use_id: null,
|
|
117
|
+
origin: { kind: "human" },
|
|
118
|
+
uuid: promptUuid,
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
await continuePlanInFreshContext(sessionId, oldSession, reset, clearContextHost, controller.signal);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
const currentSession = this.host.currentSession(sessionId);
|
|
125
|
+
const replacement = currentSession !== oldSession ? currentSession : undefined;
|
|
126
|
+
if (replacement)
|
|
127
|
+
this.host.destroyReplacement(sessionId, replacement);
|
|
128
|
+
const turn = replacement?.activeTurn ?? oldSession.activeTurn;
|
|
129
|
+
if (turn && !turn.settled) {
|
|
130
|
+
const turnSession = replacement?.activeTurn === turn ? replacement : oldSession;
|
|
131
|
+
if (controller.signal.aborted) {
|
|
132
|
+
this.host.settleCancelledTurn(oldSession, turnSession, turn);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// A provider/session-creation failure is turn-scoped. Settling it
|
|
136
|
+
// here keeps it out of the query consumer's transport-loss catch.
|
|
137
|
+
this.host.settleFailedTurn(turnSession, turn, error);
|
|
138
|
+
}
|
|
139
|
+
oldSession.activeTurn = null;
|
|
140
|
+
oldSession.turnQueue = (oldSession.turnQueue ?? []).filter((queued) => queued !== turn);
|
|
141
|
+
if (replacement) {
|
|
142
|
+
replacement.activeTurn = null;
|
|
143
|
+
replacement.turnQueue = (replacement.turnQueue ?? []).filter((queued) => queued !== turn);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
oldSession.pendingExitPlanContextReset = undefined;
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
if (this.restarts.get(sessionId) === controller) {
|
|
150
|
+
this.restarts.delete(sessionId);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,8BAA8B,EAEpC,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,8BAA8B,EAEpC,MAAM,gCAAgC,CAAC;AAMxC,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAC3E,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAChE,eAAO,MAAM,2BAA2B,yBAAyB,CAAC;AAClE,eAAO,MAAM,gCAAgC,gDAA0E,CAAC;AAKxH,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAG7D,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iCAAiC,CAAC;CAC3C,CACJ,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAC3C,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,CAAC;AAE9E,KAAK,6BAA6B,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,wBAAwB,GAAG,SAAS,CAAC;IAC3D,OAAO,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,8BAA8B,CAAC;IAC1C,cAAc,EAAE,YAAY,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,iBAAiB,EAAE,CACjB,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE,iCAAiC,KACtC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAoBF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBhF;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAE5E;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,2BAA2B,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,wBAAwB,CAK1F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAEjG;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,CAmJxB"}
|
|
@@ -2,6 +2,7 @@ import { createSdkMcpServer, } from "@anthropic-ai/claude-agent-sdk";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { airExtensionMeta, clientSupportsAirCapability, withAirMeta } from "./air-extension.js";
|
|
5
6
|
export const AGENT_FILE_CHANGE_REPORT_CAPABILITY = "agentFileChangeReport";
|
|
6
7
|
export const FILE_CHANGE_AUDIT_SERVER_NAME = "claude_agent_acp";
|
|
7
8
|
export const FILE_CHANGE_AUDIT_TOOL_NAME = "report_changed_files";
|
|
@@ -11,11 +12,6 @@ const MAX_REPORTED_PATHS = 1024;
|
|
|
11
12
|
const MAX_REPORTED_PATH_LENGTH = 4096;
|
|
12
13
|
export const AGENT_FILE_CHANGE_REPORT_MAX_BYTES = 256 * 1024;
|
|
13
14
|
const REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
14
|
-
const JETBRAINS_META_KEY = "jetbrains";
|
|
15
|
-
const AIR_META_KEY = "air";
|
|
16
|
-
const AIR_EXTENSION_VERSION = 1;
|
|
17
|
-
const AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
18
|
-
const AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
19
15
|
const reportInputSchema = {
|
|
20
16
|
paths: z
|
|
21
17
|
.array(z.string())
|
|
@@ -32,7 +28,7 @@ const reportInputSchema = {
|
|
|
32
28
|
.describe("Why the report may be incomplete or uncertain."),
|
|
33
29
|
};
|
|
34
30
|
export function agentFileChangeReportRequestId(meta) {
|
|
35
|
-
const air =
|
|
31
|
+
const air = airExtensionMeta(meta);
|
|
36
32
|
const request = air?.agentFileChangeReportRequest;
|
|
37
33
|
if (!request || typeof request !== "object" || Array.isArray(request))
|
|
38
34
|
return undefined;
|
|
@@ -49,35 +45,10 @@ export function agentFileChangeReportRequestId(meta) {
|
|
|
49
45
|
: undefined;
|
|
50
46
|
}
|
|
51
47
|
export function supportsAgentFileChangeReport(capabilities) {
|
|
52
|
-
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
const air = airExtension(capabilities._meta);
|
|
56
|
-
const advertised = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
57
|
-
return (air?.version === AIR_EXTENSION_VERSION &&
|
|
58
|
-
Array.isArray(advertised) &&
|
|
59
|
-
advertised.includes(AGENT_FILE_CHANGE_REPORT_CAPABILITY));
|
|
48
|
+
return clientSupportsAirCapability(capabilities, AGENT_FILE_CHANGE_REPORT_CAPABILITY);
|
|
60
49
|
}
|
|
61
50
|
export function agentFileChangeReportMeta(result) {
|
|
62
|
-
return
|
|
63
|
-
[JETBRAINS_META_KEY]: {
|
|
64
|
-
[AIR_META_KEY]: {
|
|
65
|
-
version: AIR_EXTENSION_VERSION,
|
|
66
|
-
[AIR_AGENT_FILE_CHANGE_REPORT_KEY]: result,
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function airExtension(meta) {
|
|
72
|
-
if (!meta || typeof meta !== "object" || Array.isArray(meta))
|
|
73
|
-
return undefined;
|
|
74
|
-
const jetbrains = meta[JETBRAINS_META_KEY];
|
|
75
|
-
if (!jetbrains || typeof jetbrains !== "object" || Array.isArray(jetbrains))
|
|
76
|
-
return undefined;
|
|
77
|
-
const air = jetbrains[AIR_META_KEY];
|
|
78
|
-
return air && typeof air === "object" && !Array.isArray(air)
|
|
79
|
-
? air
|
|
80
|
-
: undefined;
|
|
51
|
+
return withAirMeta(undefined, AGENT_FILE_CHANGE_REPORT_CAPABILITY, result);
|
|
81
52
|
}
|
|
82
53
|
export function createFileChangeAuditTurnState(requestId) {
|
|
83
54
|
return {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ForkSessionRequest, ForkSessionResponse } from "@agentclientprotocol/sdk";
|
|
2
|
+
type ForkSessionDependencies = {
|
|
3
|
+
liveMessageIdToUuid?: ReadonlyMap<string, string>;
|
|
4
|
+
messageIdForGrouping: (message: {
|
|
5
|
+
type?: string;
|
|
6
|
+
uuid?: string | null;
|
|
7
|
+
message?: unknown;
|
|
8
|
+
}) => string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare function forkSession(params: ForkSessionRequest, dependencies: ForkSessionDependencies): Promise<ForkSessionResponse>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=fork-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fork-session.d.ts","sourceRoot":"","sources":["../src/fork-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAgB,MAAM,0BAA0B,CAAC;AAkBjG,KAAK,uBAAuB,GAAG;IAC7B,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,oBAAoB,EAAE,CAAC,OAAO,EAAE;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,KAAK,MAAM,GAAG,SAAS,CAAC;CAC1B,CAAC;AAeF,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,uBAAuB,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAoC9B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RequestError } from "@agentclientprotocol/sdk";
|
|
2
|
+
import { forkSession as forkClaudeSession, getSessionMessages, } from "@anthropic-ai/claude-agent-sdk";
|
|
3
|
+
function forkPointMessageId(meta) {
|
|
4
|
+
const fork = meta?.jetbrains?.air?.fork;
|
|
5
|
+
if (fork?.version !== 1)
|
|
6
|
+
return undefined;
|
|
7
|
+
const messageId = fork.messageId?.trim();
|
|
8
|
+
return messageId || undefined;
|
|
9
|
+
}
|
|
10
|
+
function forkPointMessageIdCandidates(messageId) {
|
|
11
|
+
// Older AIR builds sent their visible segment id. Prefer the exact id before its ACP source id.
|
|
12
|
+
const protocolMessageId = messageId.replace(/:segment:\d+$/, "");
|
|
13
|
+
return protocolMessageId === messageId ? [messageId] : [messageId, protocolMessageId];
|
|
14
|
+
}
|
|
15
|
+
export async function forkSession(params, dependencies) {
|
|
16
|
+
const messageId = forkPointMessageId(params._meta);
|
|
17
|
+
if (!messageId) {
|
|
18
|
+
const forked = await forkClaudeSession(params.sessionId, { dir: params.cwd });
|
|
19
|
+
return { sessionId: forked.sessionId };
|
|
20
|
+
}
|
|
21
|
+
const candidateIds = forkPointMessageIdCandidates(messageId);
|
|
22
|
+
const liveUuid = candidateIds
|
|
23
|
+
.map((candidateId) => dependencies.liveMessageIdToUuid?.get(candidateId))
|
|
24
|
+
.find(Boolean);
|
|
25
|
+
const history = liveUuid
|
|
26
|
+
? undefined
|
|
27
|
+
: await getSessionMessages(params.sessionId, { dir: params.cwd });
|
|
28
|
+
const messageUuid = liveUuid ??
|
|
29
|
+
candidateIds
|
|
30
|
+
.map((candidateId) => history?.find((message) => dependencies.messageIdForGrouping(message) === candidateId)
|
|
31
|
+
?.uuid)
|
|
32
|
+
.find(Boolean);
|
|
33
|
+
if (!messageUuid) {
|
|
34
|
+
throw RequestError.invalidParams({ messageId }, `Fork point message ${messageId} was not found in session ${params.sessionId}`);
|
|
35
|
+
}
|
|
36
|
+
const forked = await forkClaudeSession(params.sessionId, {
|
|
37
|
+
dir: params.cwd,
|
|
38
|
+
upToMessageId: messageUuid,
|
|
39
|
+
});
|
|
40
|
+
return { sessionId: forked.sessionId };
|
|
41
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { resolveSettings } from "@anthropic-ai/claude-agent-sdk";
|
|
3
3
|
import { claudeCliPath, runAcp } from "./acp-agent.js";
|
|
4
4
|
import packageJson from "../package.json" with { type: "json" };
|
|
5
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
5
7
|
// `--cli` is checked first so that `--version`/`-v` (and any other flags) are
|
|
6
8
|
// forwarded to the wrapped native CLI rather than swallowed by our own version
|
|
7
9
|
// handler below. Our version flag only applies when not delegating.
|
|
@@ -57,7 +59,28 @@ else {
|
|
|
57
59
|
process.on("unhandledRejection", (reason, promise) => {
|
|
58
60
|
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
59
61
|
});
|
|
60
|
-
const
|
|
62
|
+
const logDirectory = process.env.CLAUDE_AGENT_LOGS;
|
|
63
|
+
const logger = logDirectory
|
|
64
|
+
? (() => {
|
|
65
|
+
mkdirSync(logDirectory, { recursive: true });
|
|
66
|
+
const logFile = join(logDirectory, "agent.log");
|
|
67
|
+
const writeLog = (...args) => {
|
|
68
|
+
const rendered = args
|
|
69
|
+
.map((arg) => (arg instanceof Error ? (arg.stack ?? arg.message) : String(arg)))
|
|
70
|
+
.join(" ");
|
|
71
|
+
appendFileSync(logFile, `${new Date().toISOString()} pid=${process.pid} ${rendered}\n`);
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
log: writeLog,
|
|
75
|
+
error: (...args) => {
|
|
76
|
+
console.error(...args);
|
|
77
|
+
writeLog(...args);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
})()
|
|
81
|
+
: undefined;
|
|
82
|
+
logger?.log("Claude ACP started");
|
|
83
|
+
const { connection, agent } = runAcp(logger);
|
|
61
84
|
async function shutdown() {
|
|
62
85
|
await agent.dispose().catch((err) => {
|
|
63
86
|
console.error("Error during cleanup:", err);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { AcpSessionNotification, SubagentState } from "./acp-subagents.js";
|
|
2
|
+
export type NativeSubagent = {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
parentSessionId: string;
|
|
5
|
+
parentToolUseId?: string;
|
|
6
|
+
name: string;
|
|
7
|
+
task: string;
|
|
8
|
+
announced?: boolean;
|
|
9
|
+
terminalState?: SubagentState;
|
|
10
|
+
/** Connection-local single-flight state; never serialized on the wire. */
|
|
11
|
+
announcePromise?: Promise<void>;
|
|
12
|
+
/** Connection-local single-flight state; never serialized on the wire. */
|
|
13
|
+
terminalPromise?: Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
export type NativeSubagentSession = {
|
|
16
|
+
nativeSubagentsByTaskId?: Map<string, NativeSubagent>;
|
|
17
|
+
nativeSubagentTaskIdByToolUseId?: Map<string, string>;
|
|
18
|
+
nativeSubagentParentByToolUseId?: Map<string, string>;
|
|
19
|
+
};
|
|
20
|
+
type Publish = (notification: AcpSessionNotification) => Promise<void>;
|
|
21
|
+
type Logger = {
|
|
22
|
+
log(message: string): void;
|
|
23
|
+
};
|
|
24
|
+
type TaskStarted = {
|
|
25
|
+
taskId: string;
|
|
26
|
+
toolUseId?: string | null;
|
|
27
|
+
subagentType?: unknown;
|
|
28
|
+
description?: unknown;
|
|
29
|
+
prompt?: unknown;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Owns the connection-local native subagent registry and all ACP lifecycle
|
|
33
|
+
* ordering. The main agent only supplies SDK facts and delivers routed output.
|
|
34
|
+
*/
|
|
35
|
+
export declare class NativeSubagentRuntime {
|
|
36
|
+
private readonly rootSessionId;
|
|
37
|
+
private readonly session;
|
|
38
|
+
private readonly publish;
|
|
39
|
+
private readonly logger;
|
|
40
|
+
readonly enabled: boolean;
|
|
41
|
+
private readonly children;
|
|
42
|
+
private readonly taskByToolUse;
|
|
43
|
+
private readonly parentByToolUse;
|
|
44
|
+
private readonly identityByToolUse;
|
|
45
|
+
private readonly controlByToolUse;
|
|
46
|
+
private readonly childByParentToolUse;
|
|
47
|
+
private readonly taskFinishPromises;
|
|
48
|
+
private readonly generationByTaskId;
|
|
49
|
+
private readonly pending;
|
|
50
|
+
private pendingCount;
|
|
51
|
+
constructor(enabled: boolean, rootSessionId: string, session: NativeSubagentSession, publish: Publish, logger: Logger);
|
|
52
|
+
route(notification: AcpSessionNotification, deliver: Publish, forcedSessionId?: string): Promise<AcpSessionNotification | null>;
|
|
53
|
+
taskStarted(task: TaskStarted, deliver: Publish): Promise<void>;
|
|
54
|
+
finishTask(taskId: string, status: unknown, deliver: Publish, toolUseId?: string | null): Promise<void>;
|
|
55
|
+
finishAll(state: SubagentState, deliver: Publish): Promise<void>;
|
|
56
|
+
discardPending(parentToolUseId: string): void;
|
|
57
|
+
clear(): void;
|
|
58
|
+
private takePending;
|
|
59
|
+
private buffer;
|
|
60
|
+
private cleanupControl;
|
|
61
|
+
private nextChildSessionId;
|
|
62
|
+
}
|
|
63
|
+
export declare function announceNativeSubagent(child: NativeSubagent, publish: Publish): Promise<void>;
|
|
64
|
+
export declare function finishNativeSubagent(session: NativeSubagentSession, taskId: string, state: SubagentState, publish: Publish): Promise<void>;
|
|
65
|
+
export declare function nativeSubagentState(status: unknown): SubagentState | undefined;
|
|
66
|
+
export declare function isNativeSubagentControlUpdate(update: AcpSessionNotification["update"]): update is Extract<AcpSessionNotification["update"], {
|
|
67
|
+
sessionUpdate: "tool_call" | "tool_call_update";
|
|
68
|
+
}>;
|
|
69
|
+
export declare function isNativeSubagentControlTool(toolName: unknown): boolean;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=native-subagents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-subagents.d.ts","sourceRoot":"","sources":["../src/native-subagents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,uBAAuB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACtD,+BAA+B,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,+BAA+B,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvD,CAAC;AAEF,KAAK,OAAO,GAAG,CAAC,YAAY,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACvE,KAAK,MAAM,GAAG;IAAE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAE7C,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAaF;;;GAGG;AACH,qBAAa,qBAAqB;IAgB9B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlBzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;IACtD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuC;IACzE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6C;IAC9E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqC;IAC1E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoC;IACvE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;IACvE,OAAO,CAAC,YAAY,CAAK;gBAGvB,OAAO,EAAE,OAAO,EACC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM;IAa3B,KAAK,CACT,YAAY,EAAE,sBAAsB,EACpC,OAAO,EAAE,OAAO,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAoEnC,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD/D,UAAU,CACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,IAAI,CAAC;IA8BV,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtE,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAI7C,KAAK,IAAI,IAAI;IAab,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,kBAAkB;CAS3B;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAM9E;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GACvC,MAAM,IAAI,OAAO,CAClB,sBAAsB,CAAC,QAAQ,CAAC,EAChC;IAAE,aAAa,EAAE,WAAW,GAAG,kBAAkB,CAAA;CAAE,CACpD,CAMA;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAEtE"}
|