@agentproto/driver-agent-cli 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -242,6 +242,13 @@ var capabilitiesSchema = z.object({
242
242
  * as a PTY session. Distinct from ACP-level `resumable`.
243
243
  */
244
244
  nativeTerminalResume: z.boolean().optional(),
245
+ /**
246
+ * Harness defers mounted MCP tools behind its own native search tool
247
+ * (Claude Code `ToolSearch`). Makes the daemon's `/mcp` self-mount default
248
+ * to eager for this adapter instead of double-deferring behind the
249
+ * daemon's `tool_search`. Defaults to false (conservative).
250
+ */
251
+ nativeToolSearch: z.boolean().optional(),
245
252
  /**
246
253
  * Adapter can ingest a filesystem path that the host UI just placed
247
254
  * on disk (host-side drag-drop into a terminal pastes the path
@@ -504,6 +511,7 @@ function createAcpProtocolArm(options) {
504
511
  let client = null;
505
512
  let session = null;
506
513
  const pendingByTurn = /* @__PURE__ */ new Map();
514
+ const earlyDisconnectListeners = [];
507
515
  return {
508
516
  get sessionId() {
509
517
  return session?.sessionId;
@@ -520,6 +528,13 @@ function createAcpProtocolArm(options) {
520
528
  get currentModeId() {
521
529
  return session?.currentModeId;
522
530
  },
531
+ isConnected() {
532
+ return client?.isConnected() ?? true;
533
+ },
534
+ onDisconnect(listener) {
535
+ if (client) client.onDisconnect(listener);
536
+ else earlyDisconnectListeners.push(listener);
537
+ },
523
538
  async connect(opts) {
524
539
  const permissionHandler = options.onPermissionRequest ?? defaultPermissionHandlerForMode(options.requestedMode);
525
540
  client = await createAcpClient({
@@ -546,6 +561,9 @@ function createAcpProtocolArm(options) {
546
561
  requestPermission: async (params) => permissionHandler(params)
547
562
  }
548
563
  });
564
+ for (const listener of earlyDisconnectListeners.splice(0)) {
565
+ client.onDisconnect(listener);
566
+ }
549
567
  if (opts.resumeSessionId) {
550
568
  session = await client.loadSession({
551
569
  sessionId: opts.resumeSessionId,
@@ -1899,18 +1917,93 @@ async function applyModelCommand(arm, modelId) {
1899
1917
  }
1900
1918
  return { applied: true, model: modelId };
1901
1919
  }
1902
- async function* promptTurn(arm, turnId, message) {
1903
- await arm.send(turnId, message);
1920
+ function parseLogfmtLine(line) {
1921
+ const out = {};
1922
+ const re = /([A-Za-z0-9_.-]+)=("(?:[^"\\]|\\.)*"|\S+)/g;
1923
+ let m;
1924
+ while ((m = re.exec(line)) !== null) {
1925
+ const key = m[1];
1926
+ let value = m[2];
1927
+ if (value.startsWith('"')) {
1928
+ value = value.slice(1, -1).replace(/\\(.)/g, "$1");
1929
+ }
1930
+ out[key] = value;
1931
+ }
1932
+ return out;
1933
+ }
1934
+ function providerMessageFromError(raw) {
1935
+ const m = raw.match(/^[A-Za-z_][\w.]*(?:Error|Exception)\s*:\s*([\s\S]+)$/);
1936
+ return (m ? m[1] : raw).trim();
1937
+ }
1938
+ function parseStderrStreamError(line) {
1939
+ if (!line.includes("stream error")) return void 0;
1940
+ const fields = parseLogfmtLine(line);
1941
+ if ((fields.level ?? "").toUpperCase() !== "ERROR") return void 0;
1942
+ if (fields.message !== "stream error") return void 0;
1943
+ if (fields.small === "true") return void 0;
1944
+ if (fields.agent === "title") return void 0;
1945
+ const raw = fields["error.error"] ?? fields.error;
1946
+ if (!raw) return void 0;
1947
+ return providerMessageFromError(raw);
1948
+ }
1949
+ async function* promptTurn(arm, turnId, message, stderrTurnError) {
1904
1950
  const stderrTail = arm._stderrTail;
1905
- for await (const evt of arm.events()) {
1906
- if (evt.kind === "error" && typeof stderrTail === "function") {
1907
- const tail = stderrTail();
1908
- if (tail) {
1909
- const existing = evt.error.data ?? {};
1910
- evt.error.data = { ...existing, stderr: tail };
1951
+ const pendingErrors = [];
1952
+ let wake;
1953
+ const unsubscribe = stderrTurnError && arm._onStderrLine ? arm._onStderrLine((line) => {
1954
+ const parsed = stderrTurnError(line);
1955
+ if (parsed === void 0) return;
1956
+ pendingErrors.push(parsed);
1957
+ wake?.();
1958
+ wake = void 0;
1959
+ }) : void 0;
1960
+ let iterator;
1961
+ try {
1962
+ await arm.send(turnId, message);
1963
+ iterator = arm.events()[Symbol.asyncIterator]();
1964
+ while (true) {
1965
+ if (pendingErrors.length > 0) {
1966
+ await arm.cancel(turnId).catch(() => {
1967
+ });
1968
+ yield {
1969
+ kind: "error",
1970
+ sessionId: arm.sessionId,
1971
+ error: {
1972
+ message: pendingErrors.join("\n"),
1973
+ data: { stderr: stderrTail?.() ?? "" }
1974
+ }
1975
+ };
1976
+ yield {
1977
+ kind: "turn-end",
1978
+ sessionId: arm.sessionId ?? "",
1979
+ reason: "error"
1980
+ };
1981
+ return;
1911
1982
  }
1983
+ const nextEvent = iterator.next();
1984
+ const stderrArrived = new Promise((resolve2) => {
1985
+ wake = resolve2;
1986
+ });
1987
+ const winner = await Promise.race([
1988
+ nextEvent.then((result) => ({ source: "event", result })),
1989
+ stderrArrived.then(() => ({ source: "stderr" }))
1990
+ ]);
1991
+ if (winner.source === "stderr") continue;
1992
+ if (winner.result.done) return;
1993
+ const evt = winner.result.value;
1994
+ if (evt.kind === "error" && typeof stderrTail === "function") {
1995
+ const tail = stderrTail();
1996
+ if (tail) {
1997
+ const existing = evt.error.data ?? {};
1998
+ evt.error.data = { ...existing, stderr: tail };
1999
+ }
2000
+ }
2001
+ yield evt;
1912
2002
  }
1913
- yield evt;
2003
+ } finally {
2004
+ unsubscribe?.();
2005
+ void iterator?.return?.()?.catch?.(() => {
2006
+ });
1914
2007
  }
1915
2008
  }
1916
2009
  function npxCacheKey(packages) {
@@ -2139,6 +2232,7 @@ function createAgentCliRuntime(definition) {
2139
2232
  }
2140
2233
  let child;
2141
2234
  const stderrBuf = [];
2235
+ const stderrLineListeners = /* @__PURE__ */ new Set();
2142
2236
  if (definition.protocol !== "proprietary") {
2143
2237
  const [execBin, execArgs] = await wrapAgentCliSpawn(
2144
2238
  finalBin,
@@ -2194,6 +2288,7 @@ cwd '${cwd}' does not exist \u2014 Node reports a missing working directory with
2194
2288
  if (!line) continue;
2195
2289
  stderrBuf.push(line);
2196
2290
  if (stderrBuf.length > STDERR_KEEP_LINES) stderrBuf.shift();
2291
+ for (const listener of stderrLineListeners) listener(line);
2197
2292
  }
2198
2293
  });
2199
2294
  }
@@ -2205,6 +2300,10 @@ cwd '${cwd}' does not exist \u2014 Node reports a missing working directory with
2205
2300
  opts?.permissionHold ?? false
2206
2301
  );
2207
2302
  arm._stderrTail = () => stderrBuf.join("\n");
2303
+ arm._onStderrLine = (listener) => {
2304
+ stderrLineListeners.add(listener);
2305
+ return () => stderrLineListeners.delete(listener);
2306
+ };
2208
2307
  const abortController = new AbortController();
2209
2308
  if (opts?.signal) {
2210
2309
  opts.signal.addEventListener("abort", () => abortController.abort(), {
@@ -2257,6 +2356,12 @@ cwd '${cwd}' does not exist \u2014 Node reports a missing working directory with
2257
2356
  return {
2258
2357
  sessionId,
2259
2358
  pid: child?.pid,
2359
+ // Transport liveness, delegated to the arm (see the fields' docs on
2360
+ // AgentCliRuntimeSession). An arm that models no long-lived
2361
+ // connection reports nothing, which reads as "connected" — there is
2362
+ // no stream for it to have lost, and nothing to subscribe to.
2363
+ isConnected: () => arm.isConnected?.() ?? true,
2364
+ ...arm.onDisconnect ? { onDisconnect: (listener) => arm.onDisconnect(listener) } : {},
2260
2365
  // Live model/mode/effort switches + the capability read-surface,
2261
2366
  // all pure arm delegation — shared with every host that builds
2262
2367
  // its own session over another transport. See session-controls.ts.
@@ -2265,7 +2370,8 @@ cwd '${cwd}' does not exist \u2014 Node reports a missing working directory with
2265
2370
  send(message) {
2266
2371
  const turnId = randomUUID();
2267
2372
  currentTurnId = turnId;
2268
- return promptTurn(arm, turnId, message);
2373
+ const stderrTurnError = definition.id === "opencode" ? parseStderrStreamError : void 0;
2374
+ return promptTurn(arm, turnId, message, stderrTurnError);
2269
2375
  },
2270
2376
  /**
2271
2377
  * Cancel the in-flight turn — the wire equivalent of Ctrl-C at the
@@ -2381,5 +2487,5 @@ function derivedModelRefusalError(definition, requested, reason) {
2381
2487
  }
2382
2488
 
2383
2489
  export { LEGACY_GATEWAY_MODE_IDS, LEGACY_POSTURE_MODE_IDS, RuntimeConfigError, agentCliFrontmatterSchema, agentCliSupportsHostContextIsolation, applyModelCommand, autoAllowPermissionHandler, composeSpawn, createAcpProtocolArm, createAgentCliRuntime, createArmSessionControls, createJcodeMapperState, createMastraMapperState, createPrintSession, createProprietaryProtocolArm, defineAgentCli, hostContextExcludes, inferLegacyModeKind, isLegacyExtractedModeId, isModelSwitchAcknowledgement, mapJcodeEvent, mapMastraEvent, parseModelSwitchCommand, planModePermissionHandler, promptTurn, resolveContinuationStrategy, runtimeConfigSchema, toFileBasedMcpServers };
2384
- //# sourceMappingURL=chunk-D4NQQ2C7.mjs.map
2385
- //# sourceMappingURL=chunk-D4NQQ2C7.mjs.map
2490
+ //# sourceMappingURL=chunk-E45SX7GU.mjs.map
2491
+ //# sourceMappingURL=chunk-E45SX7GU.mjs.map