@cargo-ai/cli 1.0.94 → 1.0.96

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 (123) hide show
  1. package/build/commands/ai/chat.d.ts.map +1 -1
  2. package/build/commands/ai/chat.js +2 -1
  3. package/build/commands/ai/message.d.ts.map +1 -1
  4. package/build/commands/ai/message.js +2 -1
  5. package/build/commands/ai/release.d.ts.map +1 -1
  6. package/build/commands/ai/release.js +7 -6
  7. package/build/commands/ask/harness/approvals.d.ts +7 -0
  8. package/build/commands/ask/harness/approvals.d.ts.map +1 -0
  9. package/build/commands/ask/harness/approvals.js +81 -0
  10. package/build/commands/ask/harness/artifacts.d.ts.map +1 -0
  11. package/build/commands/ask/harness/askUserQuestion.d.ts +69 -0
  12. package/build/commands/ask/harness/askUserQuestion.d.ts.map +1 -0
  13. package/build/commands/ask/harness/askUserQuestion.js +218 -0
  14. package/build/commands/ask/harness/claudeConfig.d.ts.map +1 -0
  15. package/build/commands/ask/{claudeConfig.js → harness/claudeConfig.js} +28 -13
  16. package/build/commands/ask/harness/create.d.ts +59 -0
  17. package/build/commands/ask/harness/create.d.ts.map +1 -0
  18. package/build/commands/ask/harness/create.js +314 -0
  19. package/build/commands/ask/harness/index.d.ts +9 -0
  20. package/build/commands/ask/harness/index.d.ts.map +1 -0
  21. package/build/commands/ask/harness/index.js +8 -0
  22. package/build/commands/ask/harness/ingest.d.ts +25 -0
  23. package/build/commands/ask/harness/ingest.d.ts.map +1 -0
  24. package/build/commands/ask/harness/ingest.js +35 -0
  25. package/build/commands/ask/harness/instructions.d.ts +13 -0
  26. package/build/commands/ask/harness/instructions.d.ts.map +1 -0
  27. package/build/commands/ask/harness/instructions.js +43 -0
  28. package/build/commands/ask/harness/layout.d.ts +23 -0
  29. package/build/commands/ask/harness/layout.d.ts.map +1 -0
  30. package/build/commands/ask/harness/layout.js +32 -0
  31. package/build/commands/ask/harness/mcp.d.ts +25 -0
  32. package/build/commands/ask/harness/mcp.d.ts.map +1 -0
  33. package/build/commands/ask/harness/mcp.js +72 -0
  34. package/build/commands/ask/harness/pnpmShim.d.ts.map +1 -0
  35. package/build/commands/ask/harness/release.d.ts +18 -0
  36. package/build/commands/ask/harness/release.d.ts.map +1 -0
  37. package/build/commands/ask/harness/release.js +117 -0
  38. package/build/commands/ask/harness/sandbox.d.ts +9 -0
  39. package/build/commands/ask/harness/sandbox.d.ts.map +1 -0
  40. package/build/commands/ask/harness/sandbox.js +27 -0
  41. package/build/commands/ask/harness/timing.d.ts +16 -0
  42. package/build/commands/ask/harness/timing.d.ts.map +1 -0
  43. package/build/commands/ask/harness/timing.js +72 -0
  44. package/build/commands/ask/harness/turn.d.ts +152 -0
  45. package/build/commands/ask/harness/turn.d.ts.map +1 -0
  46. package/build/commands/ask/harness/turn.js +676 -0
  47. package/build/commands/ask/harness/usage.d.ts +50 -0
  48. package/build/commands/ask/harness/usage.d.ts.map +1 -0
  49. package/build/commands/ask/harness/usage.js +87 -0
  50. package/build/commands/ask/index.d.ts +9 -0
  51. package/build/commands/ask/index.d.ts.map +1 -1
  52. package/build/commands/ask/index.js +7 -7
  53. package/build/commands/ask/input/completer.d.ts.map +1 -0
  54. package/build/commands/ask/input/index.d.ts +5 -0
  55. package/build/commands/ask/input/index.d.ts.map +1 -0
  56. package/build/commands/ask/input/index.js +4 -0
  57. package/build/commands/ask/input/prompt.d.ts.map +1 -0
  58. package/build/commands/ask/{prompt.js → input/prompt.js} +1 -1
  59. package/build/commands/ask/input/slash.d.ts.map +1 -0
  60. package/build/commands/ask/{slash.js → input/slash.js} +1 -1
  61. package/build/commands/ask/input/typeAhead.d.ts.map +1 -0
  62. package/build/commands/ask/{history.d.ts → persist/history.d.ts} +1 -1
  63. package/build/commands/ask/persist/history.d.ts.map +1 -0
  64. package/build/commands/ask/persist/index.d.ts +4 -0
  65. package/build/commands/ask/persist/index.d.ts.map +1 -0
  66. package/build/commands/ask/persist/index.js +3 -0
  67. package/build/commands/ask/persist/persist.d.ts.map +1 -0
  68. package/build/commands/ask/persist/state.d.ts.map +1 -0
  69. package/build/commands/ask/session/claim.d.ts +56 -0
  70. package/build/commands/ask/session/claim.d.ts.map +1 -0
  71. package/build/commands/ask/session/claim.js +76 -0
  72. package/build/commands/ask/session/index.d.ts +5 -0
  73. package/build/commands/ask/session/index.d.ts.map +1 -0
  74. package/build/commands/ask/session/index.js +4 -0
  75. package/build/commands/ask/session/run.d.ts +36 -0
  76. package/build/commands/ask/session/run.d.ts.map +1 -0
  77. package/build/commands/ask/session/run.js +846 -0
  78. package/build/commands/ask/session/thinking.d.ts.map +1 -0
  79. package/build/commands/ask/session/tree.d.ts +99 -0
  80. package/build/commands/ask/session/tree.d.ts.map +1 -0
  81. package/build/commands/ask/session/tree.js +356 -0
  82. package/package.json +6 -5
  83. package/build/commands/ask/artifacts.d.ts.map +0 -1
  84. package/build/commands/ask/binding.d.ts +0 -13
  85. package/build/commands/ask/binding.d.ts.map +0 -1
  86. package/build/commands/ask/binding.js +0 -19
  87. package/build/commands/ask/claudeConfig.d.ts.map +0 -1
  88. package/build/commands/ask/completer.d.ts.map +0 -1
  89. package/build/commands/ask/history.d.ts.map +0 -1
  90. package/build/commands/ask/localHarness.d.ts +0 -278
  91. package/build/commands/ask/localHarness.d.ts.map +0 -1
  92. package/build/commands/ask/localHarness.js +0 -1300
  93. package/build/commands/ask/messageStream.d.ts +0 -33
  94. package/build/commands/ask/messageStream.d.ts.map +0 -1
  95. package/build/commands/ask/messageStream.js +0 -114
  96. package/build/commands/ask/persist.d.ts.map +0 -1
  97. package/build/commands/ask/pnpmShim.d.ts.map +0 -1
  98. package/build/commands/ask/prompt.d.ts.map +0 -1
  99. package/build/commands/ask/session.d.ts +0 -101
  100. package/build/commands/ask/session.d.ts.map +0 -1
  101. package/build/commands/ask/session.js +0 -1328
  102. package/build/commands/ask/slash.d.ts.map +0 -1
  103. package/build/commands/ask/state.d.ts.map +0 -1
  104. package/build/commands/ask/thinking.d.ts.map +0 -1
  105. package/build/commands/ask/typeAhead.d.ts.map +0 -1
  106. /package/build/commands/ask/{artifacts.d.ts → harness/artifacts.d.ts} +0 -0
  107. /package/build/commands/ask/{artifacts.js → harness/artifacts.js} +0 -0
  108. /package/build/commands/ask/{claudeConfig.d.ts → harness/claudeConfig.d.ts} +0 -0
  109. /package/build/commands/ask/{pnpmShim.d.ts → harness/pnpmShim.d.ts} +0 -0
  110. /package/build/commands/ask/{pnpmShim.js → harness/pnpmShim.js} +0 -0
  111. /package/build/commands/ask/{completer.d.ts → input/completer.d.ts} +0 -0
  112. /package/build/commands/ask/{completer.js → input/completer.js} +0 -0
  113. /package/build/commands/ask/{prompt.d.ts → input/prompt.d.ts} +0 -0
  114. /package/build/commands/ask/{slash.d.ts → input/slash.d.ts} +0 -0
  115. /package/build/commands/ask/{typeAhead.d.ts → input/typeAhead.d.ts} +0 -0
  116. /package/build/commands/ask/{typeAhead.js → input/typeAhead.js} +0 -0
  117. /package/build/commands/ask/{history.js → persist/history.js} +0 -0
  118. /package/build/commands/ask/{persist.d.ts → persist/persist.d.ts} +0 -0
  119. /package/build/commands/ask/{persist.js → persist/persist.js} +0 -0
  120. /package/build/commands/ask/{state.d.ts → persist/state.d.ts} +0 -0
  121. /package/build/commands/ask/{state.js → persist/state.js} +0 -0
  122. /package/build/commands/ask/{thinking.d.ts → session/thinking.d.ts} +0 -0
  123. /package/build/commands/ask/{thinking.js → session/thinking.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAyI7E"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/chat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAyI7E"}
@@ -1,3 +1,4 @@
1
+ import { AiUtils } from "@cargo-ai/types";
1
2
  import { handleApiCall, outputJson, parseJson } from "../runHandler.js";
2
3
  export function registerChatCommands(parent, getApi) {
3
4
  const chat = parent
@@ -41,7 +42,7 @@ export function registerChatCommands(parent, getApi) {
41
42
  .option("--name <name>", "Chat name (string)")
42
43
  .option("--agent-uuid <uuid>", "Agent UUID to associate with (string)")
43
44
  .option("--release-uuid <uuid>", "Release UUID to pin to (string)")
44
- .option("--harness-slug <slug>", "Coding-agent runtime. Currently only claudeCode. When omitted, later turns use the agent's pinned release, if any.")
45
+ .option("--harness-slug <slug>", `Coding-agent runtime: ${AiUtils.harnessSlugs.join(", ")}. When omitted, later turns use the agent's pinned release, if any.`)
45
46
  .option("--repository <json>", "Git workspace for a coding harness (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env)")
46
47
  .addHelpText("after", `
47
48
  Examples:
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAoCxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAmTN"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/message.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAoCxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAmTN"}
@@ -1,3 +1,4 @@
1
+ import { AiUtils } from "@cargo-ai/types";
1
2
  import { parseBooleanOption } from "../../utils/booleanOption.js";
2
3
  import { loadCompiledAgent, resolveCompiledAgentFromState, } from "../../utils/loadCompiledAgent.js";
3
4
  import { ExitCodes, failWith, handleApiCall, info, outputJson, parseJson, pollUntilFinished, } from "../runHandler.js";
@@ -27,7 +28,7 @@ export function registerMessageCommands(parent, getApi) {
27
28
  .option("--integration-slug <slug>", "Integration slug (string)")
28
29
  .option("--connector-uuid <uuid>", "Connector UUID (string)")
29
30
  .option("--language-model-slug <slug>", "Language model slug (string)")
30
- .option("--harness-slug <slug>", "Coding-agent runtime. Currently only claudeCode. When omitted, later turns use the agent's pinned release, if any.")
31
+ .option("--harness-slug <slug>", `Coding-agent runtime: ${AiUtils.harnessSlugs.join(", ")}. When omitted, later turns use the agent's pinned release, if any.`)
31
32
  .option("--repository <json>", "Git workspace for a coding harness (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env)")
32
33
  .option("--output <json>", 'Output format for the assistant message (JSON object, e.g. \'{"type":"text"}\' or \'{"type":"jsonSchema","jsonSchema":{...}}\'). Defaults to text when omitted.')
33
34
  .option("--wait-until-finished [true|false]", "Poll the assistant message until finished before returning (defaults to true when passed bare)", parseBooleanOption)
@@ -1 +1 @@
1
- {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/release.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CA0VN"}
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/release.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAoVN"}
@@ -1,3 +1,4 @@
1
+ import { AiUtils } from "@cargo-ai/types";
1
2
  import { parseBooleanOption } from "../../utils/booleanOption.js";
2
3
  import { handleApiCall, outputJson, parseJson } from "../runHandler.js";
3
4
  export function registerReleaseCommands(parent, getApi) {
@@ -63,7 +64,7 @@ export function registerReleaseCommands(parent, getApi) {
63
64
  .option("--integration-slug <slug>", "LLM integration slug (string)")
64
65
  .option("--connector-uuid <uuid>", "Connector UUID (string)")
65
66
  .option("--language-model-slug <slug>", "Language model slug (string)")
66
- .option("--harness-slug <slug>", "Coding-agent runtime. Currently only claudeCode.")
67
+ .option("--harness-slug <slug>", `Coding-agent runtime: ${AiUtils.harnessSlugs.join(", ")}.`)
67
68
  .option("--repository <json>", "Git workspace for a coding harness (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env)")
68
69
  .option("--actions <json>", "Actions configuration (JSON array of action objects)")
69
70
  .option("--mcp-clients <json>", "MCP clients configuration (JSON array of MCP client objects)")
@@ -126,9 +127,9 @@ Set "isReadOnly": false on a model resource to grant the agent write tools (inse
126
127
  .command("deploy-draft")
127
128
  .description("Deploy the draft release to production")
128
129
  .requiredOption("--agent-uuid <uuid>", "Agent UUID (string, required)")
129
- .option("--integration-slug <slug>", "LLM integration slug (string). Unused when --harness-slug is set.")
130
- .option("--language-model-slug <slug>", "Language model slug (string). Unused when --harness-slug is set.")
131
- .option("--harness-slug <slug>", "Coding-agent runtime. Currently only claudeCode. When set, --integration-slug and --language-model-slug are unused.")
130
+ .option("--integration-slug <slug>", "LLM integration slug (string)")
131
+ .option("--language-model-slug <slug>", "Language model slug (string)")
132
+ .option("--harness-slug <slug>", `Coding-agent runtime: ${AiUtils.harnessSlugs.join(", ")}.`)
132
133
  .option("--repository <json>", "Git workspace for a coding harness (JSON object: connectorUuid, repository as owner/name, defaultBranch, rootDirectory, env)")
133
134
  .option("--version <version>", "Semver release version, e.g. 1.0.0 (string, auto-incremented if omitted)")
134
135
  .requiredOption("--actions <json>", "Actions configuration (JSON array of action objects, required)")
@@ -152,12 +153,12 @@ Examples:
152
153
 
153
154
  $ cargo-ai ai release deploy-draft --agent-uuid <uuid> \\
154
155
  --harness-slug claudeCode \\
156
+ --integration-slug anthropic --language-model-slug claude-sonnet-5 \\
155
157
  --repository '{"connectorUuid":"<github-uuid>","repository":"acme/app"}' \\
156
158
  --actions '[]' --mcp-clients '[]' --resources '[]' \\
157
159
  --capabilities '[]' --suggested-actions '[]'
158
160
 
159
- A tool-loop agent needs --integration-slug and --language-model-slug. A
160
- --harness-slug claudeCode agent does not — those flags are unused.`)
161
+ `)
161
162
  .action(async (opts) => {
162
163
  const api = getApi();
163
164
  const result = await handleApiCall(() => api.ai.release.deployDraft({
@@ -0,0 +1,7 @@
1
+ export declare function isAutoApproved(toolName: string, options?: {
2
+ unattended?: boolean;
3
+ }): boolean;
4
+ export declare const DENIED_TOOL_REASON = "Spawning a subagent is not available in this session. Do the work in this turn instead, asking for each tool you need.";
5
+ /** Exported for tests. */
6
+ export declare function isAlwaysDenied(toolName: string): boolean;
7
+ //# sourceMappingURL=approvals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/approvals.ts"],"names":[],"mappings":"AA0CA,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CA2BT;AAqBD,eAAO,MAAM,kBAAkB,2HAC2F,CAAC;AAE3H,0BAA0B;AAC1B,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExD"}
@@ -0,0 +1,81 @@
1
+ import { CARGO_MCP_SERVER_NAME } from "./mcp.js";
2
+ import { CARGO_AGENT_MCP_NAME_PREFIX } from "./release.js";
3
+ /**
4
+ * Claude Code's own bookkeeping. `allow-reads` classifies these as edits
5
+ * because they call a write-shaped tool, but they touch nothing outside the
6
+ * session — prompting for a todo-list update is noise, and Claude Code
7
+ * rewrites its list on every step of any multi-step task.
8
+ */
9
+ const AUTO_APPROVED_TOOL_NAMES = new Set([
10
+ "TodoWrite",
11
+ "EnterPlanMode",
12
+ "ExitPlanMode",
13
+ "TaskCreate",
14
+ "TaskUpdate",
15
+ "TaskStop",
16
+ ]);
17
+ /**
18
+ * Cargo's MCP tools run unattended in an interactive session, `execute_action`
19
+ * included: a turn can spend credits and write to a connected system on its
20
+ * own. That is the deliberate trade for a chat that answers without being
21
+ * nursed, and it is defensible only because this server reaches the workspace
22
+ * with the user's own credentials — it can do nothing they could not do from
23
+ * the CLI. `--print` is the exception: there is nobody to approve, so mutating
24
+ * workspace tools are denied there.
25
+ *
26
+ * Only this server's tools. Claude Code names them `mcp__<server>__<tool>`,
27
+ * and matching the bare `mcp__` was safe only while Ask owned the config
28
+ * directory: `CLAUDE_CONFIG_DIR` reinstates the user's own MCP servers, whose
29
+ * tools write and shell out with none of the above reasoning behind them.
30
+ * Those go through approval like anything else that touches the machine.
31
+ *
32
+ * Built from the mount key so renaming the server cannot silently widen this.
33
+ */
34
+ const CARGO_MCP_TOOL_PREFIX = `mcp__${CARGO_MCP_SERVER_NAME}__`;
35
+ const CARGO_AGENT_MCP_TOOL_PREFIX = `mcp__${CARGO_AGENT_MCP_NAME_PREFIX}`;
36
+ const CARGO_EXECUTE_ACTION_TOOL = `${CARGO_MCP_TOOL_PREFIX}execute_action`;
37
+ const CARGO_EXECUTE_ACTION_BATCH_TOOL = `${CARGO_MCP_TOOL_PREFIX}execute_action_batch`;
38
+ export function isAutoApproved(toolName, options) {
39
+ const unattended = options === undefined ? false : options.unattended === true;
40
+ if (unattended === true) {
41
+ if (toolName === CARGO_EXECUTE_ACTION_TOOL) {
42
+ return false;
43
+ }
44
+ if (toolName === CARGO_EXECUTE_ACTION_BATCH_TOOL) {
45
+ return false;
46
+ }
47
+ if (toolName.startsWith(CARGO_AGENT_MCP_TOOL_PREFIX) === true) {
48
+ return false;
49
+ }
50
+ }
51
+ if (toolName.startsWith(CARGO_MCP_TOOL_PREFIX) === true) {
52
+ return true;
53
+ }
54
+ if (toolName.startsWith(CARGO_AGENT_MCP_TOOL_PREFIX) === true) {
55
+ return true;
56
+ }
57
+ return AUTO_APPROVED_TOOL_NAMES.has(toolName);
58
+ }
59
+ /**
60
+ * `Agent` spawns a subagent to run a task of its own, and approving one is a
61
+ * different kind of decision from approving a `Bash`: the subagent runs its
62
+ * own tools, can be asked for with `mode: "bypassPermissions"`, and whether
63
+ * its calls come back here for individual approval is not something we control
64
+ * or currently know.
65
+ *
66
+ * The refusal that actually stops it is in `claudeConfig.ts`, as a deny rule
67
+ * in Claude Code's own settings — this never fired, because the approval
68
+ * request it waits for is never sent. The bridge writes `ask` rules only for
69
+ * the tools in its `NATIVE_TOOL_KINDS` map, the subagent tools are not in it,
70
+ * and so `allow-reads` left them running unattended.
71
+ *
72
+ * Kept as the second line: a user who points `CLAUDE_CONFIG_DIR` at their own
73
+ * Claude Code config gets no deny rule written for them, and a future bridge
74
+ * that does surface the approval should find an answer waiting.
75
+ */
76
+ const DENIED_TOOL_NAMES = new Set(["Agent", "Task"]);
77
+ export const DENIED_TOOL_REASON = "Spawning a subagent is not available in this session. Do the work in this turn instead, asking for each tool you need.";
78
+ /** Exported for tests. */
79
+ export function isAlwaysDenied(toolName) {
80
+ return DENIED_TOOL_NAMES.has(toolName);
81
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/artifacts.ts"],"names":[],"mappings":"AAwBA,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI,CAGzE"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Claude Code's `AskUserQuestion` — a structured multiple-choice prompt.
3
+ *
4
+ * The native picker cannot run here: `allow-reads` classifies it as readonly,
5
+ * so Claude Code starts it without asking us, then waits on a UI this session
6
+ * does not have. The native tool is withheld for that reason, via session
7
+ * `disallowedTools` — not a settings.json deny of the same name, which would
8
+ * also disable this host replacement. This session implements the tool as a
9
+ * host tool: the questions are shown in Ask's own picker, and the answers are
10
+ * the tool result.
11
+ *
12
+ * The input schema has to name `questions`. The Claude Code bridge turns host
13
+ * tool schemas into a Zod object shape; an empty shape strips every argument,
14
+ * and the picker sees `{}`.
15
+ */
16
+ import { jsonSchema } from "ai";
17
+ export declare const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
18
+ export declare const ASK_USER_QUESTION_DENIED_REASON = "Nobody is at the terminal to answer. Ask in your reply text instead.";
19
+ export declare const ASK_USER_QUESTION_MISSING_INPUT_REASON = "AskUserQuestion requires `questions`: an array of 1\u20134 items, each with `question`, `header`, `options` (each `{ label, description }`), and `multiSelect`. Call it again with those fields filled in.";
20
+ type AskUserQuestionHostTool = {
21
+ description: string;
22
+ inputSchema: ReturnType<typeof jsonSchema>;
23
+ execute: (data: unknown) => Promise<unknown>;
24
+ };
25
+ export type AskUserQuestionAsk = (input: unknown) => Promise<Record<string, string> | undefined>;
26
+ type BuiltinToolFiltering = {
27
+ mode: "allow" | "deny";
28
+ toolNames: string[];
29
+ };
30
+ /**
31
+ * Withhold Claude Code's native `AskUserQuestion` without dropping a host tool
32
+ * of the same name.
33
+ *
34
+ * HarnessAgent `inactiveTools` cannot do this: it also filters the user tool
35
+ * out of `toolSpecs`, so the replacement is never registered. A settings.json
36
+ * deny of `AskUserQuestion` matches the host tool too. Merging a deny into the
37
+ * session's builtin filtering becomes `disallowedTools` for the native tool
38
+ * only; host `execute` still runs.
39
+ */
40
+ export declare function denyNativeAskUserQuestion(existing: BuiltinToolFiltering | undefined): BuiltinToolFiltering;
41
+ /**
42
+ * Host-side `AskUserQuestion`. Same name as the builtin so the model keeps
43
+ * calling it; HarnessAgent runs `execute` on the host instead of Claude Code.
44
+ */
45
+ export declare function buildAskUserQuestionHostTool(getAsk: () => AskUserQuestionAsk | undefined): Record<string, AskUserQuestionHostTool>;
46
+ export type AskUserQuestionOption = {
47
+ label: string;
48
+ description: string | undefined;
49
+ };
50
+ export type AskUserQuestionItem = {
51
+ question: string;
52
+ header: string | undefined;
53
+ options: AskUserQuestionOption[];
54
+ multiSelect: boolean;
55
+ };
56
+ /**
57
+ * Pull the questions out of a tool input, whether the bridge sent a JSON
58
+ * string or the parsed object.
59
+ */
60
+ export declare function readAskUserQuestions(toolInput: unknown): AskUserQuestionItem[] | undefined;
61
+ /** First question, for the spinner — not the whole JSON payload. */
62
+ export declare function summarizeAskUserQuestion(toolInput: unknown): string | undefined;
63
+ /**
64
+ * Told to the model as the denial reason so it can continue with the answers
65
+ * rather than asking again.
66
+ */
67
+ export declare function formatAskUserQuestionAnswers(answers: Record<string, string>): string;
68
+ export {};
69
+ //# sourceMappingURL=askUserQuestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"askUserQuestion.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/askUserQuestion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAoB,MAAM,IAAI,CAAC;AAElD,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D,eAAO,MAAM,+BAA+B,yEAC4B,CAAC;AAEzE,eAAO,MAAM,sCAAsC,+MACsJ,CAAC;AA4C1M,KAAK,uBAAuB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC3C,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,GACzC,oBAAoB,CAsBtB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,kBAAkB,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CA2BzC;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,OAAO,GACjB,mBAAmB,EAAE,GAAG,SAAS,CA0BnC;AAED,oEAAoE;AACpE,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,OAAO,GACjB,MAAM,GAAG,SAAS,CAkBpB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAER"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Claude Code's `AskUserQuestion` — a structured multiple-choice prompt.
3
+ *
4
+ * The native picker cannot run here: `allow-reads` classifies it as readonly,
5
+ * so Claude Code starts it without asking us, then waits on a UI this session
6
+ * does not have. The native tool is withheld for that reason, via session
7
+ * `disallowedTools` — not a settings.json deny of the same name, which would
8
+ * also disable this host replacement. This session implements the tool as a
9
+ * host tool: the questions are shown in Ask's own picker, and the answers are
10
+ * the tool result.
11
+ *
12
+ * The input schema has to name `questions`. The Claude Code bridge turns host
13
+ * tool schemas into a Zod object shape; an empty shape strips every argument,
14
+ * and the picker sees `{}`.
15
+ */
16
+ import { jsonSchema } from "ai";
17
+ export const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
18
+ export const ASK_USER_QUESTION_DENIED_REASON = "Nobody is at the terminal to answer. Ask in your reply text instead.";
19
+ export const ASK_USER_QUESTION_MISSING_INPUT_REASON = "AskUserQuestion requires `questions`: an array of 1–4 items, each with `question`, `header`, `options` (each `{ label, description }`), and `multiSelect`. Call it again with those fields filled in.";
20
+ const ASK_USER_QUESTION_JSON_SCHEMA = {
21
+ type: "object",
22
+ properties: {
23
+ questions: {
24
+ type: "array",
25
+ description: "1–4 multiple-choice questions to present to the user in this terminal.",
26
+ items: {
27
+ type: "object",
28
+ properties: {
29
+ question: {
30
+ type: "string",
31
+ description: "The question to ask.",
32
+ },
33
+ header: {
34
+ type: "string",
35
+ description: "Short label shown above the question.",
36
+ },
37
+ options: {
38
+ type: "array",
39
+ items: {
40
+ type: "object",
41
+ properties: {
42
+ label: { type: "string" },
43
+ description: { type: "string" },
44
+ preview: { type: "string" },
45
+ },
46
+ required: ["label", "description"],
47
+ },
48
+ },
49
+ multiSelect: {
50
+ type: "boolean",
51
+ description: "Whether the user may pick more than one option.",
52
+ },
53
+ },
54
+ required: ["question", "header", "options", "multiSelect"],
55
+ },
56
+ },
57
+ },
58
+ required: ["questions"],
59
+ };
60
+ /**
61
+ * Withhold Claude Code's native `AskUserQuestion` without dropping a host tool
62
+ * of the same name.
63
+ *
64
+ * HarnessAgent `inactiveTools` cannot do this: it also filters the user tool
65
+ * out of `toolSpecs`, so the replacement is never registered. A settings.json
66
+ * deny of `AskUserQuestion` matches the host tool too. Merging a deny into the
67
+ * session's builtin filtering becomes `disallowedTools` for the native tool
68
+ * only; host `execute` still runs.
69
+ */
70
+ export function denyNativeAskUserQuestion(existing) {
71
+ if (existing === undefined) {
72
+ return { mode: "deny", toolNames: [ASK_USER_QUESTION_TOOL_NAME] };
73
+ }
74
+ if (existing.mode === "deny") {
75
+ if (existing.toolNames.includes(ASK_USER_QUESTION_TOOL_NAME) === true) {
76
+ return existing;
77
+ }
78
+ return {
79
+ mode: "deny",
80
+ toolNames: [...existing.toolNames, ASK_USER_QUESTION_TOOL_NAME],
81
+ };
82
+ }
83
+ return {
84
+ mode: "allow",
85
+ toolNames: existing.toolNames.filter((name) => name !== ASK_USER_QUESTION_TOOL_NAME),
86
+ };
87
+ }
88
+ /**
89
+ * Host-side `AskUserQuestion`. Same name as the builtin so the model keeps
90
+ * calling it; HarnessAgent runs `execute` on the host instead of Claude Code.
91
+ */
92
+ export function buildAskUserQuestionHostTool(getAsk) {
93
+ return {
94
+ [ASK_USER_QUESTION_TOOL_NAME]: {
95
+ description: "Ask the user multiple-choice questions via a structured UI. This session presents the options in the terminal and returns their answers.",
96
+ inputSchema: jsonSchema(ASK_USER_QUESTION_JSON_SCHEMA),
97
+ execute: async (data) => {
98
+ const ask = getAsk();
99
+ if (ask === undefined) {
100
+ return { error: ASK_USER_QUESTION_DENIED_REASON };
101
+ }
102
+ if (readAskUserQuestions(data) === undefined) {
103
+ return { error: ASK_USER_QUESTION_MISSING_INPUT_REASON };
104
+ }
105
+ const answers = await ask(data);
106
+ if (answers === undefined || Object.keys(answers).length === 0) {
107
+ return { error: ASK_USER_QUESTION_DENIED_REASON };
108
+ }
109
+ return { answers };
110
+ },
111
+ },
112
+ };
113
+ }
114
+ /**
115
+ * Pull the questions out of a tool input, whether the bridge sent a JSON
116
+ * string or the parsed object.
117
+ */
118
+ export function readAskUserQuestions(toolInput) {
119
+ const record = asRecord(toolInput);
120
+ if (record === undefined) {
121
+ return undefined;
122
+ }
123
+ const rawQuestions = record["questions"];
124
+ if (Array.isArray(rawQuestions) === false || rawQuestions.length === 0) {
125
+ return undefined;
126
+ }
127
+ const questions = [];
128
+ for (const rawQuestion of rawQuestions) {
129
+ const parsed = readQuestion(rawQuestion);
130
+ if (parsed === undefined) {
131
+ return undefined;
132
+ }
133
+ questions.push(parsed);
134
+ }
135
+ return questions;
136
+ }
137
+ /** First question, for the spinner — not the whole JSON payload. */
138
+ export function summarizeAskUserQuestion(toolInput) {
139
+ const questions = readAskUserQuestions(toolInput);
140
+ if (questions === undefined) {
141
+ return undefined;
142
+ }
143
+ const first = questions[0];
144
+ if (first === undefined) {
145
+ return undefined;
146
+ }
147
+ if (questions.length === 1) {
148
+ return first.question;
149
+ }
150
+ return `${first.question} (+${String(questions.length - 1)} more)`;
151
+ }
152
+ /**
153
+ * Told to the model as the denial reason so it can continue with the answers
154
+ * rather than asking again.
155
+ */
156
+ export function formatAskUserQuestionAnswers(answers) {
157
+ return `The user answered: ${JSON.stringify(answers)}. Continue with these answers. Do not call AskUserQuestion again for these questions.`;
158
+ }
159
+ function readQuestion(raw) {
160
+ const record = asRecord(raw);
161
+ if (record === undefined) {
162
+ return undefined;
163
+ }
164
+ const question = record["question"];
165
+ const rawOptions = record["options"];
166
+ if (typeof question !== "string" || question.length === 0) {
167
+ return undefined;
168
+ }
169
+ if (Array.isArray(rawOptions) === false || rawOptions.length === 0) {
170
+ return undefined;
171
+ }
172
+ const options = [];
173
+ for (const rawOption of rawOptions) {
174
+ const parsed = readOption(rawOption);
175
+ if (parsed === undefined) {
176
+ return undefined;
177
+ }
178
+ options.push(parsed);
179
+ }
180
+ const header = record["header"];
181
+ return {
182
+ question,
183
+ header: typeof header === "string" ? header : undefined,
184
+ options,
185
+ multiSelect: record["multiSelect"] === true,
186
+ };
187
+ }
188
+ function readOption(raw) {
189
+ const record = asRecord(raw);
190
+ if (record === undefined) {
191
+ return undefined;
192
+ }
193
+ const label = record["label"];
194
+ const description = record["description"];
195
+ if (typeof label !== "string" || label.length === 0) {
196
+ return undefined;
197
+ }
198
+ return {
199
+ label,
200
+ description: typeof description === "string" ? description : undefined,
201
+ };
202
+ }
203
+ function asRecord(value) {
204
+ if (typeof value === "string") {
205
+ try {
206
+ const parsed = JSON.parse(value);
207
+ return typeof parsed === "object" && parsed !== null
208
+ ? parsed
209
+ : undefined;
210
+ }
211
+ catch {
212
+ return undefined;
213
+ }
214
+ }
215
+ return typeof value === "object" && value !== null
216
+ ? value
217
+ : undefined;
218
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeConfig.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/claudeConfig.ts"],"names":[],"mappings":"AAyCA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAa3C"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { getConfigDir } from "@cargo-ai/cdk/cli";
4
+ import { ASK_USER_QUESTION_TOOL_NAME } from "./askUserQuestion.js";
4
5
  /**
5
6
  * Tools that spawn a subagent, refused at source.
6
7
  *
@@ -22,6 +23,16 @@ import { getConfigDir } from "@cargo-ai/cdk/cli";
22
23
  * Code versions and a rule for a tool that does not exist costs nothing.
23
24
  */
24
25
  const SUBAGENT_TOOL_NAMES = ["Agent", "Task"];
26
+ /**
27
+ * Native `AskUserQuestion` used to live on this list. A deny-by-name rule
28
+ * matches the host replacement of the same name, so model calls came back
29
+ * disabled instead of reaching host `execute`. Native withholding is now
30
+ * session `disallowedTools` — see `denyNativeAskUserQuestion`. Names here
31
+ * are stripped from an existing deny array so a previous Ask run cannot
32
+ * keep the collision around.
33
+ */
34
+ const SETTINGS_DENIED_TOOL_NAMES = SUBAGENT_TOOL_NAMES;
35
+ const SETTINGS_UNDENIED_TOOL_NAMES = [ASK_USER_QUESTION_TOOL_NAME];
25
36
  /**
26
37
  * The Claude Agent SDK loads every filesystem settings source it can find when
27
38
  * `settingSources` is omitted, and the harness bridge omits it. A local turn
@@ -52,24 +63,23 @@ export function askClaudeConfigDir() {
52
63
  }
53
64
  const dir = join(getConfigDir(), "ask-claude-config");
54
65
  mkdirSync(dir, { recursive: true });
55
- denySubagentTools(dir);
66
+ denySettingsTools(dir);
56
67
  return dir;
57
68
  }
58
69
  /**
59
- * Add the subagent deny rules to the settings file in Ask's own config
60
- * directory, keeping whatever else is in there.
70
+ * Add the deny rules to the settings file in Ask's own config directory,
71
+ * keeping whatever else is in there.
61
72
  *
62
73
  * Merged rather than written whole, because Claude Code keeps its own state
63
74
  * under this directory.
64
75
  *
65
76
  * A failure here is reported rather than swallowed. There is no second line of
66
- * defence to fall back on: the approval-time refusal in `isAlwaysDenied` is
67
- * never reached, which is the whole reason this exists — so a settings file
68
- * that could not be written means subagents run unattended, and the user is
69
- * the only one who can tell whether that matters. Reported, not thrown: it
70
- * must not fail the question they just asked.
77
+ * defence to fall back on for tools `allow-reads` never asks about — so a
78
+ * settings file that could not be written means those tools run unattended,
79
+ * and the user is the only one who can tell whether that matters. Reported,
80
+ * not thrown: it must not fail the question they just asked.
71
81
  */
72
- function denySubagentTools(dir) {
82
+ function denySettingsTools(dir) {
73
83
  const path = join(dir, "settings.json");
74
84
  try {
75
85
  const existing = existsSync(path)
@@ -84,16 +94,21 @@ function denySubagentTools(dir) {
84
94
  : {};
85
95
  const denyValue = permissions["deny"];
86
96
  const deny = Array.isArray(denyValue) ? denyValue : [];
87
- const missing = SUBAGENT_TOOL_NAMES.filter((name) => deny.includes(name) === false);
88
- if (missing.length === 0) {
97
+ const kept = deny.filter((name) => {
98
+ return typeof name === "string"
99
+ ? SETTINGS_UNDENIED_TOOL_NAMES.includes(name) === false
100
+ : true;
101
+ });
102
+ const missing = SETTINGS_DENIED_TOOL_NAMES.filter((name) => kept.includes(name) === false);
103
+ if (missing.length === 0 && kept.length === deny.length) {
89
104
  return;
90
105
  }
91
106
  writeFileSync(path, `${JSON.stringify({
92
107
  ...settings,
93
- permissions: { ...permissions, deny: [...deny, ...missing] },
108
+ permissions: { ...permissions, deny: [...kept, ...missing] },
94
109
  }, null, 2)}\n`);
95
110
  }
96
111
  catch (error) {
97
- process.stderr.write(`Could not write ${path}, so subagent tools are not withheld from this session: ${error instanceof Error ? error.message : "unknown error"}\n`);
112
+ process.stderr.write(`Could not write ${path}, so Agent and Task are not withheld from this session: ${error instanceof Error ? error.message : "unknown error"}\n`);
98
113
  }
99
114
  }
@@ -0,0 +1,59 @@
1
+ import type { Ai } from "@cargo-ai/api";
2
+ import type { Api } from "../../../api.js";
3
+ import { type LocalStreamOptions } from "./turn.js";
4
+ export type LocalHarness = {
5
+ streamPrompt: (question: string, options?: LocalStreamOptions) => Promise<string>;
6
+ /**
7
+ * When a turn last reached Anthropic, or undefined if none has. The proxy
8
+ * token re-arms on every call it makes, so this — not the mint time — is
9
+ * what its real expiry runs from.
10
+ */
11
+ proxyLastUsedAtMs: () => number | undefined;
12
+ /** Stops Claude Code and its bridge; the session is not resumable. */
13
+ close: () => Promise<void>;
14
+ };
15
+ export declare function createLocalHarness(input: {
16
+ api: Api;
17
+ /**
18
+ * Cargo API origin (`config.baseUrl`). The Anthropic proxy is mounted on
19
+ * the API as `/sandbox/anthropic` — same host the backend uses via
20
+ * `config.app.url` (which is the API URL, not the web app).
21
+ */
22
+ apiBaseUrl: string;
23
+ dir: string;
24
+ chatUuid: string;
25
+ agentUuid?: string;
26
+ /**
27
+ * Deployed release of the selected agent. Applied the way `/stream` applies
28
+ * a harness agent's release: prompt, actions, resources, MCP, capabilities.
29
+ * Does not change the local harness or --dir.
30
+ */
31
+ release?: Ai.Release;
32
+ proxyToken: string;
33
+ /**
34
+ * Connector the mint picked for this session, plus the integration and
35
+ * model it resolved. Sent with ingest so usage is attributed to the same
36
+ * provider the proxy spent against — not reconstructed from the harness slug.
37
+ */
38
+ connectorUuid: string;
39
+ integrationSlug: string;
40
+ languageModelSlug: string;
41
+ /**
42
+ * Earlier turns of this chat, from `loadChatHistoryPreamble`. The session is
43
+ * always new, so this is the only thing that carries a `--continue` chat
44
+ * across CLI runs.
45
+ */
46
+ history?: string;
47
+ /**
48
+ * The id the caller claimed the chat with. Sent with the ingest so recording
49
+ * a turn releases this session's claim and not one taken after it.
50
+ */
51
+ turnOwnerId?: string;
52
+ /**
53
+ * Interactive Ask can run host tools and custom agent MCP unattended.
54
+ * `--print` cannot: nobody is there to approve, and host tools never
55
+ * prompt under `allow-reads`.
56
+ */
57
+ allowWorkspaceMutations: boolean;
58
+ }): Promise<LocalHarness>;
59
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAuB3C,OAAO,EAGL,KAAK,kBAAkB,EAKxB,MAAM,WAAW,CAAC;AAGnB,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC5C,sEAAsE;IACtE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAcF,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,GAAG,EAAE,GAAG,CAAC;IACT;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,YAAY,CAAC,CAsUxB"}