@agentclientprotocol/claude-agent-acp 0.81.2 → 0.81.3-preview.2

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.
Files changed (99) hide show
  1. package/README.md +8 -5
  2. package/dist/acp-agent.d.ts +32 -40
  3. package/dist/acp-agent.d.ts.map +1 -1
  4. package/dist/acp-agent.js +557 -577
  5. package/dist/acp-subagents.d.ts +6 -0
  6. package/dist/acp-subagents.d.ts.map +1 -1
  7. package/dist/air-extension.d.ts +31 -1
  8. package/dist/air-extension.d.ts.map +1 -1
  9. package/dist/air-extension.js +35 -1
  10. package/dist/async-tasks.d.ts +39 -2
  11. package/dist/async-tasks.d.ts.map +1 -1
  12. package/dist/async-tasks.js +147 -44
  13. package/dist/context-compaction-meta.d.ts +6 -5
  14. package/dist/context-compaction-meta.d.ts.map +1 -1
  15. package/dist/context-compaction-meta.js +10 -10
  16. package/dist/context-compaction.d.ts +3 -0
  17. package/dist/context-compaction.d.ts.map +1 -1
  18. package/dist/context-compaction.js +23 -57
  19. package/dist/diff.d.ts +73 -5
  20. package/dist/diff.d.ts.map +1 -1
  21. package/dist/diff.js +435 -64
  22. package/dist/elicitation.d.ts +1 -1
  23. package/dist/elicitation.d.ts.map +1 -1
  24. package/dist/elicitation.js +12 -14
  25. package/dist/hide-claude-auth.d.ts +2 -6
  26. package/dist/hide-claude-auth.d.ts.map +1 -1
  27. package/dist/hide-claude-auth.js +3 -21
  28. package/dist/native-subagents.d.ts +58 -0
  29. package/dist/native-subagents.d.ts.map +1 -1
  30. package/dist/native-subagents.js +186 -34
  31. package/dist/paths.d.ts +3 -0
  32. package/dist/paths.d.ts.map +1 -0
  33. package/dist/paths.js +6 -0
  34. package/dist/permissions/presentation.d.ts +13 -2
  35. package/dist/permissions/presentation.d.ts.map +1 -1
  36. package/dist/permissions/presentation.js +49 -44
  37. package/dist/resumed-session.d.ts +11 -0
  38. package/dist/resumed-session.d.ts.map +1 -1
  39. package/dist/resumed-session.js +106 -4
  40. package/dist/session-failure-extension.js +1 -1
  41. package/dist/session-mode.d.ts +2 -0
  42. package/dist/session-mode.d.ts.map +1 -1
  43. package/dist/session-mode.js +12 -5
  44. package/dist/settings.js +2 -2
  45. package/dist/subagent-history.d.ts +20 -0
  46. package/dist/subagent-history.d.ts.map +1 -0
  47. package/dist/subagent-history.js +46 -0
  48. package/dist/tool-calls/background.d.ts +20 -0
  49. package/dist/tool-calls/background.d.ts.map +1 -0
  50. package/dist/tool-calls/background.js +41 -0
  51. package/dist/tool-calls/changed-meta-filter.d.ts +27 -0
  52. package/dist/tool-calls/changed-meta-filter.d.ts.map +1 -0
  53. package/dist/tool-calls/changed-meta-filter.js +102 -0
  54. package/dist/tool-calls/client-capabilities.d.ts +51 -0
  55. package/dist/tool-calls/client-capabilities.d.ts.map +1 -0
  56. package/dist/tool-calls/client-capabilities.js +43 -0
  57. package/dist/tool-calls/content.d.ts +59 -0
  58. package/dist/tool-calls/content.d.ts.map +1 -0
  59. package/dist/tool-calls/content.js +194 -0
  60. package/dist/tool-calls/facts.d.ts +116 -0
  61. package/dist/tool-calls/facts.d.ts.map +1 -0
  62. package/dist/tool-calls/facts.js +1 -0
  63. package/dist/tool-calls/field-tracker.d.ts +58 -0
  64. package/dist/tool-calls/field-tracker.d.ts.map +1 -0
  65. package/dist/tool-calls/field-tracker.js +167 -0
  66. package/dist/tool-calls/renderer.d.ts +216 -0
  67. package/dist/tool-calls/renderer.d.ts.map +1 -0
  68. package/dist/tool-calls/renderer.js +487 -0
  69. package/dist/tool-calls/reporters/agent.d.ts +7 -0
  70. package/dist/tool-calls/reporters/agent.d.ts.map +1 -0
  71. package/dist/tool-calls/reporters/agent.js +190 -0
  72. package/dist/tool-calls/reporters/bash.d.ts +9 -0
  73. package/dist/tool-calls/reporters/bash.d.ts.map +1 -0
  74. package/dist/tool-calls/reporters/bash.js +83 -0
  75. package/dist/tool-calls/reporters/compaction.d.ts +24 -0
  76. package/dist/tool-calls/reporters/compaction.d.ts.map +1 -0
  77. package/dist/tool-calls/reporters/compaction.js +66 -0
  78. package/dist/tool-calls/reporters/file-edit.d.ts +46 -0
  79. package/dist/tool-calls/reporters/file-edit.d.ts.map +1 -0
  80. package/dist/tool-calls/reporters/file-edit.js +180 -0
  81. package/dist/tool-calls/reporters/index.d.ts +4 -0
  82. package/dist/tool-calls/reporters/index.d.ts.map +1 -0
  83. package/dist/tool-calls/reporters/index.js +40 -0
  84. package/dist/tool-calls/reporters/interaction.d.ts +71 -0
  85. package/dist/tool-calls/reporters/interaction.d.ts.map +1 -0
  86. package/dist/tool-calls/reporters/interaction.js +222 -0
  87. package/dist/tool-calls/reporters/read.d.ts +7 -0
  88. package/dist/tool-calls/reporters/read.d.ts.map +1 -0
  89. package/dist/tool-calls/reporters/read.js +64 -0
  90. package/dist/tool-calls/reporters/search.d.ts +10 -0
  91. package/dist/tool-calls/reporters/search.d.ts.map +1 -0
  92. package/dist/tool-calls/reporters/search.js +50 -0
  93. package/dist/tool-calls/reporters/web.d.ts +11 -0
  94. package/dist/tool-calls/reporters/web.d.ts.map +1 -0
  95. package/dist/tool-calls/reporters/web.js +42 -0
  96. package/dist/tools.d.ts +32 -37
  97. package/dist/tools.d.ts.map +1 -1
  98. package/dist/tools.js +48 -970
  99. package/package.json +4 -1
@@ -0,0 +1,102 @@
1
+ /** The `_meta` namespaces whose keys a client merges one by one. */
2
+ const MERGED_NAMESPACES = ["claudeCode"];
3
+ /** The top-level `_meta` flags that stay the same for a tool call. */
4
+ const FLAGS = ["is_mcp_tool_call", "terminal_info"];
5
+ /** The number of tool calls whose `_meta` the filter remembers. */
6
+ const TOOL_CALL_LIMIT = 2048;
7
+ /**
8
+ * Removes the `_meta` keys of a `tool_call_update` that an earlier report of
9
+ * the same tool call already sent with the same value.
10
+ *
11
+ * Only an AIR client gets the filtered updates, because AIR merges these
12
+ * `_meta` keys. ACP does not define a merge for `_meta` keys, so another
13
+ * client gets every key on every update.
14
+ *
15
+ * It runs on the final notification, after the native subagent routing,
16
+ * because the routing reads `claudeCode.toolName` and
17
+ * `claudeCode.parentToolUseId` on every update. It compares the keys of
18
+ * `claudeCode`, of `jetbrains.air`, and the flags `is_mcp_tool_call` and
19
+ * `terminal_info`. It never compares `terminal_output`,
20
+ * `terminal_output_delta`, `terminal_exit`, or `mcp_output_delta`: a client
21
+ * appends their data. An update with nothing left is dropped.
22
+ */
23
+ export class ChangedMetaFilter {
24
+ sent = new Map();
25
+ /** Returns the update without the unchanged keys, or null when nothing is left. */
26
+ apply(update) {
27
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
28
+ return update;
29
+ }
30
+ let held = this.sent.get(update.toolCallId);
31
+ if (update.sessionUpdate === "tool_call" || !held) {
32
+ held = new Map();
33
+ this.remember(update.toolCallId, held);
34
+ recordAndStrip(held, update._meta, false);
35
+ return update;
36
+ }
37
+ this.remember(update.toolCallId, held);
38
+ if (!update._meta)
39
+ return update;
40
+ const meta = structuredClone(update._meta);
41
+ recordAndStrip(held, meta, true);
42
+ const filtered = { ...update, _meta: meta };
43
+ if (Object.keys(meta).length === 0)
44
+ delete filtered._meta;
45
+ const carriesSomething = Object.keys(filtered).some((key) => key !== "sessionUpdate" && key !== "toolCallId");
46
+ return carriesSomething ? filtered : null;
47
+ }
48
+ /** Stores the entry as the most recent one, and forgets the oldest one past the limit. */
49
+ remember(toolCallId, held) {
50
+ this.sent.delete(toolCallId);
51
+ this.sent.set(toolCallId, held);
52
+ if (this.sent.size > TOOL_CALL_LIMIT) {
53
+ const oldest = this.sent.keys().next().value;
54
+ if (oldest !== undefined)
55
+ this.sent.delete(oldest);
56
+ }
57
+ }
58
+ }
59
+ /** Records the compared keys of `meta`. With `strip`, deletes the unchanged ones. */
60
+ function recordAndStrip(held, meta, strip) {
61
+ if (!meta)
62
+ return;
63
+ const keep = (key, value) => {
64
+ const json = JSON.stringify(value);
65
+ if (strip && held.get(key) === json)
66
+ return false;
67
+ held.set(key, json);
68
+ return true;
69
+ };
70
+ const mergeKeys = (prefix, values) => {
71
+ for (const [key, value] of Object.entries(values)) {
72
+ if (!keep(prefix + key, value))
73
+ delete values[key];
74
+ }
75
+ };
76
+ for (const namespace of MERGED_NAMESPACES) {
77
+ const values = asRecord(meta[namespace]);
78
+ if (!values)
79
+ continue;
80
+ mergeKeys(`${namespace}.`, values);
81
+ if (Object.keys(values).length === 0)
82
+ delete meta[namespace];
83
+ }
84
+ const jetbrains = asRecord(meta.jetbrains);
85
+ const air = asRecord(jetbrains?.air);
86
+ if (jetbrains && air) {
87
+ mergeKeys("jetbrains.air.", air);
88
+ if (Object.keys(air).length === 0)
89
+ delete jetbrains.air;
90
+ if (Object.keys(jetbrains).length === 0)
91
+ delete meta.jetbrains;
92
+ }
93
+ for (const flag of FLAGS) {
94
+ if (meta[flag] !== undefined && !keep(flag, meta[flag]))
95
+ delete meta[flag];
96
+ }
97
+ }
98
+ function asRecord(value) {
99
+ return value && typeof value === "object" && !Array.isArray(value)
100
+ ? value
101
+ : undefined;
102
+ }
@@ -0,0 +1,51 @@
1
+ import type { ClientCapabilities as AcpClientCapabilities } from "@agentclientprotocol/sdk";
2
+ /**
3
+ * The client choices that decide the shape of a tool call report.
4
+ *
5
+ * The agent reads them once from `initialize.clientCapabilities`. The public
6
+ * `toAcpNotifications` functions take the ACP capabilities and read them on
7
+ * each call. The {@link AcpToolCallRenderer} reads nothing else, so one object
8
+ * holds every capability choice of a tool call report.
9
+ */
10
+ export declare class ClientCapabilities {
11
+ /** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
12
+ readonly terminalOutput: boolean;
13
+ /** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
14
+ readonly terminalOutputDelta: boolean;
15
+ /** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
16
+ readonly diffPatch: boolean;
17
+ /** The capabilities that only JetBrains AIR declares. */
18
+ readonly air: AirCapabilities;
19
+ constructor(
20
+ /** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
21
+ terminalOutput?: boolean,
22
+ /** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
23
+ terminalOutputDelta?: boolean,
24
+ /** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
25
+ diffPatch?: boolean,
26
+ /** The capabilities that only JetBrains AIR declares. */
27
+ air?: AirCapabilities);
28
+ static from(capabilities: AcpClientCapabilities | null | undefined): ClientCapabilities;
29
+ }
30
+ /** The capabilities of JetBrains AIR, read from `_meta.jetbrains.air`. */
31
+ export interface AirCapabilities {
32
+ /**
33
+ * The client declared `_meta.jetbrains.air`. Only then does a report follow
34
+ * the tool call contract of `docs/air-extensions.md`. Every other client
35
+ * gets the fields of the upstream adapter, and only the unchanged fields of
36
+ * an update are left out.
37
+ */
38
+ readonly client: boolean;
39
+ /**
40
+ * AIR renders `rawInput` itself. A tool call report for AIR then carries no
41
+ * display copy of the input in `content`.
42
+ */
43
+ readonly rawInputRendering: boolean;
44
+ /**
45
+ * AIR reads the plan of an ExitPlanMode from the file that
46
+ * `rawInput.planFilePath` names. A report then carries the path and not the
47
+ * plan text, when the plan file exists.
48
+ */
49
+ readonly planFile: boolean;
50
+ }
51
+ //# sourceMappingURL=client-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-capabilities.d.ts","sourceRoot":"","sources":["../../src/tool-calls/client-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAS5F;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAE3B,wGAAwG;IACxG,QAAQ,CAAC,cAAc,EAAE,OAAO;IAChC,4FAA4F;IAC5F,QAAQ,CAAC,mBAAmB,EAAE,OAAO;IACrC,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,OAAO;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,eAAe;;IAP7B,wGAAwG;IAC/F,cAAc,GAAE,OAAe;IACxC,4FAA4F;IACnF,mBAAmB,GAAE,OAAe;IAC7C,qFAAqF;IAC5E,SAAS,GAAE,OAAe;IACnC,yDAAyD;IAChD,GAAG,GAAE,eAAwB;IAGxC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB;CAiBxF;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B"}
@@ -0,0 +1,43 @@
1
+ import { AIR_DIFF_PATCH_CAPABILITY, AIR_PLAN_FILE_CAPABILITY, AIR_RAW_INPUT_RENDERING_CAPABILITY, clientSupportsAirCapability, isAirClient, } from "../air-extension.js";
2
+ /**
3
+ * The client choices that decide the shape of a tool call report.
4
+ *
5
+ * The agent reads them once from `initialize.clientCapabilities`. The public
6
+ * `toAcpNotifications` functions take the ACP capabilities and read them on
7
+ * each call. The {@link AcpToolCallRenderer} reads nothing else, so one object
8
+ * holds every capability choice of a tool call report.
9
+ */
10
+ export class ClientCapabilities {
11
+ terminalOutput;
12
+ terminalOutputDelta;
13
+ diffPatch;
14
+ air;
15
+ constructor(
16
+ /** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
17
+ terminalOutput = false,
18
+ /** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
19
+ terminalOutputDelta = false,
20
+ /** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
21
+ diffPatch = false,
22
+ /** The capabilities that only JetBrains AIR declares. */
23
+ air = NO_AIR) {
24
+ this.terminalOutput = terminalOutput;
25
+ this.terminalOutputDelta = terminalOutputDelta;
26
+ this.diffPatch = diffPatch;
27
+ this.air = air;
28
+ }
29
+ static from(capabilities) {
30
+ const meta = capabilities?._meta;
31
+ const terminalOutputDelta = meta?.["terminal_output_delta"] === true;
32
+ return new ClientCapabilities(terminalOutputDelta || meta?.["terminal_output"] === true, terminalOutputDelta, clientSupportsAirCapability(capabilities, AIR_DIFF_PATCH_CAPABILITY), {
33
+ client: isAirClient(capabilities),
34
+ rawInputRendering: clientSupportsAirCapability(capabilities, AIR_RAW_INPUT_RENDERING_CAPABILITY),
35
+ planFile: clientSupportsAirCapability(capabilities, AIR_PLAN_FILE_CAPABILITY),
36
+ });
37
+ }
38
+ }
39
+ const NO_AIR = {
40
+ client: false,
41
+ rawInputRendering: false,
42
+ planFile: false,
43
+ };
@@ -0,0 +1,59 @@
1
+ import type { ContentBlock, ToolCallContent } from "@agentclientprotocol/sdk";
2
+ import { DocumentBlockParam, ImageBlockParam, TextBlockParam, ToolResultBlockParam, WebSearchResultBlock, WebSearchToolResultBlockParam, WebSearchToolResultError } from "@anthropic-ai/sdk/resources";
3
+ import { BetaBashCodeExecutionResultBlock, BetaBashCodeExecutionToolResultBlockParam, BetaBashCodeExecutionToolResultError, BetaCodeExecutionResultBlock, BetaCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultError, BetaImageBlockParam, BetaRequestMCPToolResultBlockParam, BetaTextEditorCodeExecutionCreateResultBlock, BetaTextEditorCodeExecutionStrReplaceResultBlock, BetaTextEditorCodeExecutionToolResultBlockParam, BetaTextEditorCodeExecutionToolResultError, BetaTextEditorCodeExecutionViewResultBlock, BetaToolReferenceBlock, BetaToolResultBlockParam, BetaToolSearchToolResultBlockParam, BetaToolSearchToolResultError, BetaToolSearchToolSearchResultBlock, BetaWebFetchBlock, BetaWebFetchToolResultBlockParam, BetaWebFetchToolResultErrorBlock, BetaWebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources/beta.mjs";
4
+ /**
5
+ * Union of all possible content types that can appear in tool results from the Anthropic SDK.
6
+ * These are transformed to valid ACP ContentBlock types by toValidAcpContent().
7
+ */
8
+ export type ToolResultContent = TextBlockParam | DocumentBlockParam | ImageBlockParam | BetaImageBlockParam | BetaToolReferenceBlock | BetaToolSearchToolSearchResultBlock | BetaToolSearchToolResultError | WebSearchResultBlock | WebSearchToolResultError | BetaWebFetchBlock | BetaWebFetchToolResultErrorBlock | BetaCodeExecutionResultBlock | BetaCodeExecutionToolResultError | BetaBashCodeExecutionResultBlock | BetaBashCodeExecutionToolResultError | BetaTextEditorCodeExecutionViewResultBlock | BetaTextEditorCodeExecutionCreateResultBlock | BetaTextEditorCodeExecutionStrReplaceResultBlock | BetaTextEditorCodeExecutionToolResultError;
9
+ /**
10
+ * Convert an absolute file path to a project-relative path for display.
11
+ * Returns the original path if it's outside the project directory or if no cwd is provided.
12
+ */
13
+ export declare function toDisplayPath(filePath: string, cwd?: string): string;
14
+ /**
15
+ * Narrow the untyped message-level `tool_use_result` toward a per-tool Output
16
+ * shape: rejects everything but a plain non-null object (arrays pass a bare
17
+ * `typeof === "object"` check, so they're excluded here). The returned value
18
+ * is only *nominally* typed — it arrives over the wire from arbitrary CLI
19
+ * versions, so each caller must still guard the specific fields it reads
20
+ * before trusting them.
21
+ */
22
+ export declare function structuredResult<T extends object>(toolUseResult: unknown): T | undefined;
23
+ /** One display format for a web-search hit, shared by the structured
24
+ * WebSearchOutput render and the server-side `web_search_result` block so
25
+ * the two paths can't drift. */
26
+ export declare function formatWebSearchHit(hit: {
27
+ title: string;
28
+ url: string;
29
+ }): string;
30
+ export declare function toAcpContentUpdate(content: any, isError?: boolean): {
31
+ content?: ToolCallContent[];
32
+ };
33
+ export declare function toAcpContentBlock(content: ToolResultContent, isError: boolean): ContentBlock;
34
+ export declare function markdownEscape(text: string): string;
35
+ /** Every SDK block that reports the result of a tool use. */
36
+ export type ToolResultBlock = ToolResultBlockParam | BetaToolResultBlockParam | BetaWebSearchToolResultBlockParam | BetaWebFetchToolResultBlockParam | WebSearchToolResultBlockParam | BetaCodeExecutionToolResultBlockParam | BetaBashCodeExecutionToolResultBlockParam | BetaTextEditorCodeExecutionToolResultBlockParam | BetaRequestMCPToolResultBlockParam | BetaToolSearchToolResultBlockParam;
37
+ /** One text content block. */
38
+ export declare function textContent(text: string): ToolCallContent;
39
+ /** The result text that the model saw, as the result to show. */
40
+ export declare function resultText(result: {
41
+ content?: unknown;
42
+ is_error?: boolean | null;
43
+ }): {
44
+ content?: ToolCallContent[];
45
+ };
46
+ /**
47
+ * The marker fields of a PostToolUse `tool_response` that clients read.
48
+ *
49
+ * The full `tool_response` repeats the tool output. A Read holds the whole
50
+ * file, a Bash holds stdout and stderr, and a Write holds the content. The
51
+ * tool-call content already carries that output. JetBrains AIR reads
52
+ * `status` and `isAsync` to detect an async subagent launch, so only those
53
+ * fields stay. Returns undefined when neither field is present.
54
+ */
55
+ export declare function toolResponseMarkers(toolResponse: unknown): {
56
+ status?: string;
57
+ isAsync?: boolean;
58
+ } | undefined;
59
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/tool-calls/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gCAAgC,EAChC,yCAAyC,EACzC,oCAAoC,EACpC,4BAA4B,EAC5B,qCAAqC,EACrC,gCAAgC,EAChC,mBAAmB,EACnB,kCAAkC,EAClC,4CAA4C,EAC5C,gDAAgD,EAChD,+CAA+C,EAC/C,0CAA0C,EAC1C,0CAA0C,EAC1C,sBAAsB,EACtB,wBAAwB,EACxB,kCAAkC,EAClC,6BAA6B,EAC7B,mCAAmC,EACnC,iBAAiB,EACjB,gCAAgC,EAChC,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,sCAAsC,CAAC;AAG9C;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB,cAAc,GACd,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,sBAAsB,GACtB,mCAAmC,GACnC,6BAA6B,GAC7B,oBAAoB,GACpB,wBAAwB,GACxB,iBAAiB,GACjB,gCAAgC,GAChC,4BAA4B,GAC5B,gCAAgC,GAChC,gCAAgC,GAChC,oCAAoC,GACpC,0CAA0C,GAC1C,4CAA4C,GAC5C,gDAAgD,GAChD,0CAA0C,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,CAMxF;AAED;;iCAEiC;AACjC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9E;AAUD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,OAAO,GAAE,OAAe,GACvB;IAAE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,CA+BjC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CA6F5F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,wBAAwB,GACxB,iCAAiC,GACjC,gCAAgC,GAChC,6BAA6B,GAC7B,qCAAqC,GACrC,yCAAyC,GACzC,+CAA+C,GAC/C,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,8BAA8B;AAC9B,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAEzD;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAAG;IACpF,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC7B,CAEA;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,OAAO,GACpB;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAUpD"}
@@ -0,0 +1,194 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Convert an absolute file path to a project-relative path for display.
4
+ * Returns the original path if it's outside the project directory or if no cwd is provided.
5
+ */
6
+ export function toDisplayPath(filePath, cwd) {
7
+ if (!cwd)
8
+ return filePath;
9
+ const resolvedCwd = path.resolve(cwd);
10
+ const resolvedFile = path.resolve(filePath);
11
+ if (resolvedFile.startsWith(resolvedCwd + path.sep) || resolvedFile === resolvedCwd) {
12
+ return path.relative(resolvedCwd, resolvedFile);
13
+ }
14
+ return filePath;
15
+ }
16
+ /**
17
+ * Narrow the untyped message-level `tool_use_result` toward a per-tool Output
18
+ * shape: rejects everything but a plain non-null object (arrays pass a bare
19
+ * `typeof === "object"` check, so they're excluded here). The returned value
20
+ * is only *nominally* typed — it arrives over the wire from arbitrary CLI
21
+ * versions, so each caller must still guard the specific fields it reads
22
+ * before trusting them.
23
+ */
24
+ export function structuredResult(toolUseResult) {
25
+ return toolUseResult !== null &&
26
+ typeof toolUseResult === "object" &&
27
+ !Array.isArray(toolUseResult)
28
+ ? toolUseResult
29
+ : undefined;
30
+ }
31
+ /** One display format for a web-search hit, shared by the structured
32
+ * WebSearchOutput render and the server-side `web_search_result` block so
33
+ * the two paths can't drift. */
34
+ export function formatWebSearchHit(hit) {
35
+ return `${hit.title} (${hit.url})`;
36
+ }
37
+ /** Human-readable size for the document placeholder ("312 B", "2.4 KB",
38
+ * "1.3 MB"). */
39
+ function formatByteSize(bytes) {
40
+ if (bytes < 1024)
41
+ return `${bytes} B`;
42
+ if (bytes < 1024 * 1024)
43
+ return `${(bytes / 1024).toFixed(1)} KB`;
44
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
45
+ }
46
+ export function toAcpContentUpdate(content, isError = false) {
47
+ if (Array.isArray(content) && content.length > 0) {
48
+ return {
49
+ content: content.map((c) => ({
50
+ type: "content",
51
+ content: toAcpContentBlock(c, isError),
52
+ })),
53
+ };
54
+ }
55
+ else if (typeof content === "object" && content !== null && "type" in content) {
56
+ return {
57
+ content: [
58
+ {
59
+ type: "content",
60
+ content: toAcpContentBlock(content, isError),
61
+ },
62
+ ],
63
+ };
64
+ }
65
+ else if (typeof content === "string" && content.length > 0) {
66
+ return {
67
+ content: [
68
+ {
69
+ type: "content",
70
+ content: {
71
+ type: "text",
72
+ text: isError ? `\`\`\`\n${content}\n\`\`\`` : content,
73
+ },
74
+ },
75
+ ],
76
+ };
77
+ }
78
+ return {};
79
+ }
80
+ export function toAcpContentBlock(content, isError) {
81
+ const wrapText = (text) => ({
82
+ type: "text",
83
+ text: isError ? `\`\`\`\n${text}\n\`\`\`` : text,
84
+ });
85
+ switch (content.type) {
86
+ case "text":
87
+ return {
88
+ type: "text",
89
+ text: isError ? `\`\`\`\n${content.text}\n\`\`\`` : content.text,
90
+ };
91
+ case "image":
92
+ if (content.source.type === "base64") {
93
+ return {
94
+ type: "image",
95
+ data: content.source.data,
96
+ mimeType: content.source.media_type,
97
+ };
98
+ }
99
+ // URL and file-based images can't be converted to ACP format (requires data)
100
+ return wrapText(content.source.type === "url"
101
+ ? `[image: ${content.source.url}]`
102
+ : "[image: file reference]");
103
+ case "document": {
104
+ // A PDF Read delivers its raw `document` block inside the tool_result
105
+ // content (SDK 0.3.243 moved it here from a separate follow-up user
106
+ // message; the MultiRead documents lane always lived here). ACP has no
107
+ // document block and the base64 payload can be megabytes — render a
108
+ // compact placeholder, never the data, matching the CLI's own compact
109
+ // "Read PDF (size)" rendering.
110
+ const title = typeof content.title === "string" && content.title.length > 0 ? ` "${content.title}"` : "";
111
+ const source = content.source;
112
+ switch (source.type) {
113
+ case "url":
114
+ return wrapText(`[document${title}: ${source.url}]`);
115
+ case "base64":
116
+ case "text":
117
+ // base64 inflates the byte count by 4/3; plain text is 1:1.
118
+ return wrapText(`[document${title}: ${source.media_type}, ${formatByteSize(source.type === "base64"
119
+ ? Math.floor((source.data.length * 3) / 4)
120
+ : source.data.length)}]`);
121
+ default:
122
+ return wrapText(`[document${title}]`);
123
+ }
124
+ }
125
+ case "tool_reference":
126
+ return wrapText(`Tool: ${content.tool_name}`);
127
+ case "tool_search_tool_search_result":
128
+ return wrapText(`Tools found: ${content.tool_references.map((r) => r.tool_name).join(", ") || "none"}`);
129
+ case "tool_search_tool_result_error":
130
+ return wrapText(`Error: ${content.error_code}${content.error_message ? ` - ${content.error_message}` : ""}`);
131
+ case "web_search_result":
132
+ return wrapText(formatWebSearchHit(content));
133
+ case "web_search_tool_result_error":
134
+ return wrapText(`Error: ${content.error_code}`);
135
+ case "web_fetch_result":
136
+ return wrapText(`Fetched: ${content.url}`);
137
+ case "web_fetch_tool_result_error":
138
+ return wrapText(`Error: ${content.error_code}`);
139
+ case "code_execution_result":
140
+ return wrapText(`Output: ${content.stdout || content.stderr || ""}`);
141
+ case "bash_code_execution_result":
142
+ return wrapText(`Output: ${content.stdout || content.stderr || ""}`);
143
+ case "code_execution_tool_result_error":
144
+ case "bash_code_execution_tool_result_error":
145
+ return wrapText(`Error: ${content.error_code}`);
146
+ case "text_editor_code_execution_view_result":
147
+ return wrapText(content.content);
148
+ case "text_editor_code_execution_create_result":
149
+ return wrapText(content.is_file_update ? "File updated" : "File created");
150
+ case "text_editor_code_execution_str_replace_result":
151
+ return wrapText(content.lines?.join("\n") || "");
152
+ case "text_editor_code_execution_tool_result_error":
153
+ return wrapText(`Error: ${content.error_code}${content.error_message ? ` - ${content.error_message}` : ""}`);
154
+ default:
155
+ return wrapText(JSON.stringify(content));
156
+ }
157
+ }
158
+ export function markdownEscape(text) {
159
+ let escape = "```";
160
+ for (const [m] of text.matchAll(/^```+/gm)) {
161
+ while (m.length >= escape.length) {
162
+ escape += "`";
163
+ }
164
+ }
165
+ return escape + "\n" + text + (text.endsWith("\n") ? "" : "\n") + escape;
166
+ }
167
+ /** One text content block. */
168
+ export function textContent(text) {
169
+ return { type: "content", content: { type: "text", text } };
170
+ }
171
+ /** The result text that the model saw, as the result to show. */
172
+ export function resultText(result) {
173
+ return toAcpContentUpdate(result.content, result.is_error === true);
174
+ }
175
+ /**
176
+ * The marker fields of a PostToolUse `tool_response` that clients read.
177
+ *
178
+ * The full `tool_response` repeats the tool output. A Read holds the whole
179
+ * file, a Bash holds stdout and stderr, and a Write holds the content. The
180
+ * tool-call content already carries that output. JetBrains AIR reads
181
+ * `status` and `isAsync` to detect an async subagent launch, so only those
182
+ * fields stay. Returns undefined when neither field is present.
183
+ */
184
+ export function toolResponseMarkers(toolResponse) {
185
+ if (!toolResponse || typeof toolResponse !== "object" || Array.isArray(toolResponse)) {
186
+ return undefined;
187
+ }
188
+ const { status, isAsync } = toolResponse;
189
+ const markers = {
190
+ ...(typeof status === "string" ? { status } : {}),
191
+ ...(typeof isAsync === "boolean" ? { isAsync } : {}),
192
+ };
193
+ return Object.keys(markers).length > 0 ? markers : undefined;
194
+ }
@@ -0,0 +1,116 @@
1
+ import type { ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk";
2
+ import type { ClientCapabilities } from "./client-capabilities.js";
3
+ /** A tool use as the SDK reports it. */
4
+ export interface ToolUse {
5
+ id: string;
6
+ name: string;
7
+ input: unknown;
8
+ }
9
+ /**
10
+ * The facts of a tool use, read once from its input. The
11
+ * {@link AcpToolCallRenderer} decides which ACP field carries each fact.
12
+ */
13
+ export interface ToolUseFacts {
14
+ /** A short label. Not the input and not the output. */
15
+ title: string;
16
+ kind: ToolKind;
17
+ locations?: ToolCallLocation[];
18
+ /** The file change that the input makes, as diff content. */
19
+ change?: ToolCallContent[];
20
+ /**
21
+ * The input keys whose text a diff holds: {@link change}, or for a Write of a
22
+ * client with diffPatch, the approval preview or the hook patch. `rawInput`
23
+ * leaves them out.
24
+ */
25
+ fileTextKeys?: readonly string[];
26
+ /**
27
+ * A display copy of the input that the user reads: a plan, a subagent
28
+ * prompt, a question, a command description. A client that renders
29
+ * `rawInput` itself gets no display copy.
30
+ */
31
+ display?: ToolCallContent[];
32
+ /** The tool runs a command. Its output goes to the terminal channel. */
33
+ command?: boolean;
34
+ /**
35
+ * The absolute path of the plan file that holds the plan text of the input.
36
+ * Set only for a `planFile` client and an existing file. `rawInput` then
37
+ * carries this path and not the plan text.
38
+ */
39
+ planFilePath?: string;
40
+ }
41
+ /** The output of a command, for the terminal channel. */
42
+ export interface CommandOutput {
43
+ output: string;
44
+ exitCode: number;
45
+ }
46
+ /**
47
+ * The facts of a tool result, read once from the SDK tool_result.
48
+ *
49
+ * `rawOutput` is present when the reporter decided what the raw output is.
50
+ * Otherwise the renderer sends the raw tool_result as `rawOutput` only when
51
+ * nothing else carries the result.
52
+ */
53
+ export interface ToolResultFacts {
54
+ title?: string;
55
+ /** The result to show. */
56
+ content?: ToolCallContent[];
57
+ /** The final locations of an edit. */
58
+ locations?: ToolCallLocation[];
59
+ /** The output of a command. */
60
+ command?: CommandOutput;
61
+ /** A result that has no display form. */
62
+ rawOutput?: unknown;
63
+ /** The plan file of the tool use, as {@link ToolUseFacts.planFilePath} defines it. */
64
+ planFilePath?: string;
65
+ /**
66
+ * The plan is done with its file: the user approved it and the session left
67
+ * Plan mode. AIR then gets the clear signal of the plan file.
68
+ */
69
+ planFileReleased?: boolean;
70
+ }
71
+ /** What a reporter reads besides the input of the tool use. */
72
+ export interface ToolUseContext {
73
+ cwd?: string;
74
+ capabilities: ClientCapabilities;
75
+ /**
76
+ * True when the tool use comes from the history of a loaded session. The
77
+ * files on disk then show a later state, so a reporter must not read them.
78
+ */
79
+ replay?: boolean;
80
+ }
81
+ /** What a reporter reads to report a tool result. */
82
+ export interface ToolResultContext {
83
+ toolUse: ToolUse;
84
+ /** The SDK tool_result block. */
85
+ result: {
86
+ content?: unknown;
87
+ is_error?: boolean | null;
88
+ tool_use_id?: string;
89
+ };
90
+ /** The structured `tool_use_result` of the SDK message, when it is known. */
91
+ structured?: unknown;
92
+ capabilities: ClientCapabilities;
93
+ }
94
+ /**
95
+ * Turns the SDK data of one tool kind into tool facts. A reporter holds no
96
+ * state and knows nothing about the ACP fields.
97
+ */
98
+ export interface ToolReporter {
99
+ toolUse(input: unknown, context: ToolUseContext): ToolUseFacts;
100
+ /**
101
+ * The facts of a successful result. Without this method, the result text
102
+ * that the model saw is the result to show.
103
+ */
104
+ toolResult?(context: ToolResultContext): ToolResultFacts;
105
+ /**
106
+ * The facts of an error result. Without this method, the error text is the
107
+ * result to show.
108
+ */
109
+ errorResult?(context: ToolResultContext): ToolResultFacts | undefined;
110
+ /**
111
+ * The facts of the PostToolUse hook `tool_response`: the final file change
112
+ * of an edit tool.
113
+ */
114
+ hookResult?(toolResponse: unknown, context: ToolUseContext): Promise<ToolResultFacts>;
115
+ }
116
+ //# sourceMappingURL=facts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../../src/tool-calls/facts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,sCAAsC;IACtC,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,yCAAyC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,kBAAkB,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY,CAAC;IAC/D;;;OAGG;IACH,UAAU,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,CAAC;IACzD;;;OAGG;IACH,WAAW,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,GAAG,SAAS,CAAC;IACtE;;;OAGG;IACH,UAAU,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACvF"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import type { SessionNotification, ToolCallContent } from "@agentclientprotocol/sdk";
2
+ type SessionUpdate = SessionNotification["update"];
3
+ /**
4
+ * Remembers what the client holds for each open tool call, so that a
5
+ * `tool_call_update` carries only the fields that changed.
6
+ *
7
+ * A client overwrites a field that an update carries and merges `_meta` by
8
+ * key. An update that repeats a field value therefore only costs bandwidth,
9
+ * and for a Write it repeats the whole file. The tracker drops such fields.
10
+ * It never drops `_meta`, because a client appends `terminal_output_delta`
11
+ * data.
12
+ *
13
+ * An entry starts at the `tool_call` and ends after both the tool_result and
14
+ * the PostToolUse hook callback, or when the session is torn down.
15
+ */
16
+ export declare class ToolCallFieldTracker {
17
+ private readonly calls;
18
+ /**
19
+ * Records a `tool_call`, or removes the unchanged fields of a
20
+ * `tool_call_update` and records the rest.
21
+ *
22
+ * Returns false when the update carries nothing new: no replaced field
23
+ * remains, `_meta` has no key besides `claudeCode` and `jetbrains`, and
24
+ * every `claudeCode` and `jetbrains.air` key repeats its value. The caller
25
+ * then skips the update. An update for a tool call that the tracker does
26
+ * not know passes through unchanged.
27
+ *
28
+ * `replacePinnedContent` lets the final result of the tool replace an exact
29
+ * approval patch (see {@link pinContent}).
30
+ */
31
+ apply(update: SessionUpdate, options?: {
32
+ replacePinnedContent?: boolean;
33
+ }): boolean;
34
+ /**
35
+ * Records the exact approval patch that the client shows for a tool call.
36
+ *
37
+ * The streamed tool input later refines the call with a standard diff of
38
+ * the Edit snippet. That diff must not replace the exact patch, so the
39
+ * content stays until an update passes `replacePinnedContent`.
40
+ */
41
+ pinContent(toolCallId: string, content: ToolCallContent[]): void;
42
+ /**
43
+ * Marks the tool_result of a tool call. The entry ends now, or after the
44
+ * PostToolUse hook callback when `hookPending` is true.
45
+ */
46
+ finishResult(toolCallId: string, hookPending: boolean): void;
47
+ /**
48
+ * Marks the end of the PostToolUse hook callback of a tool call. The entry
49
+ * ends when the tool_result was seen. Otherwise the tool_result ends it.
50
+ */
51
+ finishHook(toolCallId: string): void;
52
+ /** Forgets one tool call. */
53
+ delete(toolCallId: string): void;
54
+ /** Forgets every tool call, when the session is torn down. */
55
+ clear(): void;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=field-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-tracker.d.ts","sourceRoot":"","sources":["../../src/tool-calls/field-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAErF,KAAK,aAAa,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AA+BnD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IA8CnF;;;;;;OAMG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAOhE;;;OAGG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI;IAO5D;;;OAGG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIpC,6BAA6B;IAC7B,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,8DAA8D;IAC9D,KAAK,IAAI,IAAI;CAGd"}