@cargo-ai/cli 1.0.124 → 1.0.125

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.
@@ -1 +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;AAIxC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAuB3C,OAAO,EAEL,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,CA4UxB"}
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;AAIxC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAwB3C,OAAO,EAEL,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,CAgVxB"}
@@ -12,6 +12,7 @@ import { ensureHarnessPnpmOnPath } from "./pnpmShim.js";
12
12
  import { buildReleaseHostTools, buildReleaseMcpServers } from "./release.js";
13
13
  import { withGetPortEndpoint } from "./sandbox.js";
14
14
  import { ASK_TIMING_ENABLED, createPhaseLog, reportHarnessDiagnostic, timeStreamParts, } from "./timing.js";
15
+ import { withToolCallReplay } from "./toolCallReplay.js";
15
16
  import { HarnessTurnStuck, runPromptTurn, settleWithin, } from "./turn.js";
16
17
  import { createTurnAccumulator, didReachAnthropic } from "./usage.js";
17
18
  /**
@@ -62,14 +63,16 @@ export async function createLocalHarness(input) {
62
63
  // through `auth`, not `env`: passing them via `env` alone lets
63
64
  // createClaudeCode auto-detect AI Gateway from the host process and ignore
64
65
  // the Cargo proxy.
65
- const claudeCode = createClaudeCode({
66
+ // Wrapped so a batched tool call stays known to the stream that is asked to
67
+ // approve it (see `toolCallReplay.ts`).
68
+ const claudeCode = withToolCallReplay(createClaudeCode({
66
69
  auth: {
67
70
  ANTHROPIC_BASE_URL: anthropicBaseUrl,
68
71
  ANTHROPIC_API_KEY: input.proxyToken,
69
72
  },
70
73
  env: { CLAUDE_CONFIG_DIR: askClaudeConfigDir() },
71
74
  mcpServers,
72
- });
75
+ }));
73
76
  const harnessAgent = new HarnessAgent({
74
77
  // Native AskUserQuestion is withheld on the session, not via
75
78
  // `inactiveTools` (that would drop the host tool of the same name) and
@@ -4,6 +4,7 @@ export { createLocalHarness, type LocalHarness } from "./create.js";
4
4
  export { localHarnessInstructions, localHarnessSkills, } from "./instructions.js";
5
5
  export { resolveWorkspaceLayout } from "./layout.js";
6
6
  export { CARGO_MCP_SERVER_NAME } from "./mcp.js";
7
+ export { replayKnownToolCalls, withToolCallReplay, wrapSession, } from "./toolCallReplay.js";
7
8
  export { HarnessTurnStalled, HarnessTurnStuck, isBridgeClosedError, type LocalStreamHandlers, type LocalStreamOptions, type LocalToolActivity, type LocalToolApproval, runPromptTurn, settleWithin, type StreamLike, type TurnDriver, } from "./turn.js";
8
9
  export { createTurnAccumulator, type LocalTurnAccumulator, type LocalTurnUsage, readClaudeCodeCostUsd, } from "./usage.js";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,+BAA+B,EAC/B,sCAAsC,EACtC,2BAA2B,EAC3B,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,EAC5B,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,aAAa,EACb,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,+BAA+B,EAC/B,sCAAsC,EACtC,2BAA2B,EAC3B,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,EAC5B,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,aAAa,EACb,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -4,5 +4,6 @@ export { createLocalHarness } from "./create.js";
4
4
  export { localHarnessInstructions, localHarnessSkills, } from "./instructions.js";
5
5
  export { resolveWorkspaceLayout } from "./layout.js";
6
6
  export { CARGO_MCP_SERVER_NAME } from "./mcp.js";
7
+ export { replayKnownToolCalls, withToolCallReplay, wrapSession, } from "./toolCallReplay.js";
7
8
  export { HarnessTurnStalled, HarnessTurnStuck, isBridgeClosedError, runPromptTurn, settleWithin, } from "./turn.js";
8
9
  export { createTurnAccumulator, readClaudeCodeCostUsd, } from "./usage.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Keeps a batched tool call known to the turn that is asked to approve it.
3
+ *
4
+ * When Claude asks for several tools that need approval in one message, the
5
+ * Claude Code bridge emits every `tool-call` up front, then one approval
6
+ * request; the rest come one per stream after each answer. The bridge
7
+ * remembers which calls it emitted for the whole turn, so it does not emit
8
+ * them again. The agent forgets them at the end of every stream, and the next
9
+ * stream throws on the second approval:
10
+ *
11
+ * Harness 'claude-code' emitted approval request '…' for unknown tool call '…'.
12
+ *
13
+ * Upstream: https://github.com/vercel/ai/issues/23499 (open, reproduced on
14
+ * `main`). Each `doPromptTurn` / `doContinueTurn` is one agent stream with its
15
+ * own `emit`, so the session remembers every tool call and replays one into a
16
+ * stream that is about to receive an approval for a call it never saw. Remove
17
+ * this once the agent keeps tool calls for the session.
18
+ */
19
+ import type { HarnessV1, HarnessV1Session, HarnessV1StreamPart } from "@ai-sdk/harness";
20
+ type Emit = (event: HarnessV1StreamPart) => void;
21
+ /** Exported for tests: one stream's `emit`, fed from a session-wide memory. */
22
+ export declare function replayKnownToolCalls(known: Map<string, HarnessV1StreamPart>, emit: Emit): Emit;
23
+ /** Exported for tests. */
24
+ export declare function wrapSession(session: HarnessV1Session): HarnessV1Session;
25
+ /** The harness, with every session it starts keeping its tool calls. */
26
+ export declare function withToolCallReplay(harness: HarnessV1): HarnessV1;
27
+ export {};
28
+ //# sourceMappingURL=toolCallReplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolCallReplay.d.ts","sourceRoot":"","sources":["../../../../src/commands/ask/harness/toolCallReplay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAEjD,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACvC,IAAI,EAAE,IAAI,GACT,IAAI,CAqBN;AAED,0BAA0B;AAC1B,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CA+BvE;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAKhE"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Keeps a batched tool call known to the turn that is asked to approve it.
3
+ *
4
+ * When Claude asks for several tools that need approval in one message, the
5
+ * Claude Code bridge emits every `tool-call` up front, then one approval
6
+ * request; the rest come one per stream after each answer. The bridge
7
+ * remembers which calls it emitted for the whole turn, so it does not emit
8
+ * them again. The agent forgets them at the end of every stream, and the next
9
+ * stream throws on the second approval:
10
+ *
11
+ * Harness 'claude-code' emitted approval request '…' for unknown tool call '…'.
12
+ *
13
+ * Upstream: https://github.com/vercel/ai/issues/23499 (open, reproduced on
14
+ * `main`). Each `doPromptTurn` / `doContinueTurn` is one agent stream with its
15
+ * own `emit`, so the session remembers every tool call and replays one into a
16
+ * stream that is about to receive an approval for a call it never saw. Remove
17
+ * this once the agent keeps tool calls for the session.
18
+ */
19
+ /** Exported for tests: one stream's `emit`, fed from a session-wide memory. */
20
+ export function replayKnownToolCalls(known, emit) {
21
+ const seen = new Set();
22
+ return (event) => {
23
+ if (event.type === "tool-call") {
24
+ known.set(event.toolCallId, event);
25
+ seen.add(event.toolCallId);
26
+ }
27
+ else if (event.type === "tool-approval-request" &&
28
+ seen.has(event.toolCallId) === false) {
29
+ const call = known.get(event.toolCallId);
30
+ if (call !== undefined) {
31
+ seen.add(event.toolCallId);
32
+ emit(call);
33
+ }
34
+ }
35
+ emit(event);
36
+ };
37
+ }
38
+ /** Exported for tests. */
39
+ export function wrapSession(session) {
40
+ const known = new Map();
41
+ const doPromptTurn = (options) => session.doPromptTurn({
42
+ ...options,
43
+ emit: replayKnownToolCalls(known, options.emit),
44
+ });
45
+ const doContinueTurn = (options) => session.doContinueTurn({
46
+ ...options,
47
+ emit: replayKnownToolCalls(known, options.emit),
48
+ });
49
+ // A proxy rather than a spread or a prototype: a session may be a class
50
+ // with private state, so every other member is read from it and its methods
51
+ // run bound to it.
52
+ return new Proxy(session, {
53
+ get(target, key) {
54
+ if (key === "doPromptTurn") {
55
+ return doPromptTurn;
56
+ }
57
+ if (key === "doContinueTurn") {
58
+ return doContinueTurn;
59
+ }
60
+ const value = Reflect.get(target, key, target);
61
+ return typeof value === "function" ? value.bind(target) : value;
62
+ },
63
+ });
64
+ }
65
+ /** The harness, with every session it starts keeping its tool calls. */
66
+ export function withToolCallReplay(harness) {
67
+ return {
68
+ ...harness,
69
+ doStart: async (options) => wrapSession(await harness.doStart(options)),
70
+ };
71
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cargo-ai/cli",
3
- "version": "1.0.124",
3
+ "version": "1.0.125",
4
4
  "mcpName": "io.github.getcargohq/cargo",
5
5
  "private": false,
6
6
  "license": "UNLICENSED",