agentbox-sdk 0.1.523 → 0.1.601

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -746,6 +746,17 @@ each run in its own process group can set `processGroup: "inherited"`; that
746
746
  supervisor is then responsible for stopping the complete group before reporting
747
747
  that a run has stopped. This option is unavailable for cloud sandboxes.
748
748
 
749
+ On Windows, host CLIs start through cross-spawn without a shell: it resolves
750
+ `PATHEXT` and script shebangs, and escapes the arguments `cmd.exe` sees when the
751
+ binary is a batch shim. Windows has no process groups or signals, so stopping a
752
+ host CLI ends its whole process tree with `taskkill /T /F`; a supervisor using
753
+ `processGroup: "inherited"` there still owns everything the tree left behind
754
+ (for example through a Job Object).
755
+
756
+ `provider.args` passes native CLI flags for a run without touching the user's
757
+ configuration. Codex places them before its subcommand (`["-c", "key=value"]`);
758
+ Claude Code accepts `--name` and `--name=value` entries.
759
+
749
760
  ## Packaging
750
761
 
751
762
  `npm pack` builds the package from maintained TypeScript source before creating
@@ -1,5 +1,5 @@
1
- import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, al as RawAgentEvent, b as AgentAttachRequest, B as AttachedRun, as as SetupLayout, ay as UserContent } from '../types-DM6zUiv1.js';
2
- export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, a6 as NativeParkBackgroundWork, ab as OpenCodeAgentOptions, ac as OpenCodeCommandEntry, ad as OpenCodePluginConfig, ae as OpenCodePluginEvent, af as OpenCodePluginHookConfig, ag as OpenCodeProviderOptions, ah as OpenCodeSkillEntry, ai as OpenRouterPlugin, an as RepoSkillConfig, au as TextPart, az as UserContentPart, aA as builtinHarnessCommands, aB as claudeHarnessCommands, aC as codexHarnessCommands, aD as codexSkillMention, aG as openCodeHarnessCommands, aH as parseHarnessCommandInvocation, aI as skillDirective } from '../types-DM6zUiv1.js';
1
+ import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, al as RawAgentEvent, b as AgentAttachRequest, B as AttachedRun, as as SetupLayout, ay as UserContent } from '../types-ChkpU7Lf.js';
2
+ export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, a6 as NativeParkBackgroundWork, ab as OpenCodeAgentOptions, ac as OpenCodeCommandEntry, ad as OpenCodePluginConfig, ae as OpenCodePluginEvent, af as OpenCodePluginHookConfig, ag as OpenCodeProviderOptions, ah as OpenCodeSkillEntry, ai as OpenRouterPlugin, an as RepoSkillConfig, au as TextPart, az as UserContentPart, aA as builtinHarnessCommands, aB as claudeHarnessCommands, aC as codexHarnessCommands, aD as codexSkillMention, aG as openCodeHarnessCommands, aH as parseHarnessCommandInvocation, aI as skillDirective } from '../types-ChkpU7Lf.js';
3
3
  import { S as Sandbox } from '../Sandbox-DcKAU-E3.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -15,7 +15,7 @@ import {
15
15
  parseHarnessCommandInvocation,
16
16
  resolveHarnessCommand,
17
17
  skillDirective
18
- } from "../chunk-PFGHRDL4.js";
18
+ } from "../chunk-ZITMGTVR.js";
19
19
  import "../chunk-AE2FQ6YU.js";
20
20
  import {
21
21
  AGENT_RESERVED_PORTS,
@@ -30,24 +30,31 @@ import {
30
30
  } from "./chunk-GOFJNFAD.js";
31
31
 
32
32
  // src/agents/Agent.ts
33
- import { randomUUID as randomUUID3 } from "crypto";
34
- import path11 from "path";
33
+ import { randomUUID as randomUUID4 } from "crypto";
34
+ import path12 from "path";
35
35
 
36
36
  // src/agents/providers/claude-code.ts
37
- import { randomUUID } from "crypto";
37
+ import { randomUUID as randomUUID2 } from "crypto";
38
38
 
39
39
  // src/agents/transports/spawn.ts
40
- import { spawn } from "child_process";
40
+ import { execFile, spawn } from "child_process";
41
+ import path from "path";
41
42
  import { createInterface } from "readline";
43
+ import crossSpawn from "cross-spawn";
44
+ var windows = process.platform === "win32";
45
+ function killWindowsTree(pid) {
46
+ const taskkill = path.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "taskkill.exe");
47
+ execFile(taskkill, ["/pid", String(pid), "/T", "/F"], { windowsHide: true }, () => void 0);
48
+ }
42
49
  function spawnCommand(options) {
43
- const child = spawn(options.command, options.args ?? [], {
50
+ const spawnOptions = {
44
51
  cwd: options.cwd,
45
52
  env: options.env,
46
53
  stdio: "pipe",
47
- shell: process.platform === "win32",
48
54
  windowsHide: true,
49
- detached: options.processGroup === true && process.platform !== "win32"
50
- });
55
+ detached: options.processGroup === true && !windows
56
+ };
57
+ const child = (windows ? crossSpawn : spawn)(options.command, options.args ?? [], spawnOptions);
51
58
  const exitPromise = new Promise((resolve, reject) => {
52
59
  child.once("error", reject);
53
60
  child.once("close", (code) => resolve(code ?? 0));
@@ -56,7 +63,8 @@ function spawnCommand(options) {
56
63
  let killPromise;
57
64
  const signalProcess = (signal) => {
58
65
  try {
59
- if (options.processGroup && process.platform !== "win32" && child.pid) process.kill(-child.pid, signal);
66
+ if (windows && child.pid) killWindowsTree(child.pid);
67
+ else if (options.processGroup && child.pid) process.kill(-child.pid, signal);
60
68
  else child.kill(signal);
61
69
  } catch (error) {
62
70
  if (error.code !== "ESRCH") throw error;
@@ -81,7 +89,7 @@ function spawnCommand(options) {
81
89
  kill: (signal = "SIGTERM") => killPromise ??= (async () => {
82
90
  signalProcess(signal);
83
91
  if (await waitForExit(options.terminationTimeoutMs ?? 3e3)) {
84
- if (options.processGroup && process.platform !== "win32") signalProcess("SIGKILL");
92
+ if (options.processGroup && !windows) signalProcess("SIGKILL");
85
93
  return;
86
94
  }
87
95
  signalProcess("SIGKILL");
@@ -101,7 +109,7 @@ async function* linesFromNodeStream(stream) {
101
109
  }
102
110
 
103
111
  // src/agents/providers/claude-code.ts
104
- import path8 from "path";
112
+ import path9 from "path";
105
113
 
106
114
  // src/agents/harness-commands.ts
107
115
  var MAX_HARNESS_COMMANDS = 500;
@@ -454,7 +462,7 @@ function questionReply(provider, input, answers) {
454
462
 
455
463
  // src/agents/input.ts
456
464
  import { readFile } from "fs/promises";
457
- import path from "path";
465
+ import path2 from "path";
458
466
  import { fileURLToPath } from "url";
459
467
  var IMAGE_MEDIA_TYPE_BY_EXTENSION = {
460
468
  ".gif": "image/gif",
@@ -794,7 +802,7 @@ async function resolveUrlContent(url, options) {
794
802
  const buffer = await readFile(filePath);
795
803
  return {
796
804
  mediaType: resolveMediaType(filePath, options),
797
- filename: options.filename ?? path.basename(filePath),
805
+ filename: options.filename ?? path2.basename(filePath),
798
806
  source: {
799
807
  type: "base64",
800
808
  data: buffer.toString("base64")
@@ -843,11 +851,11 @@ function resolveMediaType(pathname, options, parsedMediaType) {
843
851
  );
844
852
  }
845
853
  function inferMediaType(pathname) {
846
- const extension = path.extname(pathname).toLowerCase();
854
+ const extension = path2.extname(pathname).toLowerCase();
847
855
  return FILE_MEDIA_TYPE_BY_EXTENSION[extension];
848
856
  }
849
857
  function inferFilename(pathname) {
850
- const name = path.basename(pathname);
858
+ const name = path2.basename(pathname);
851
859
  return name && name !== "." ? name : void 0;
852
860
  }
853
861
  function parseStructuredUrl(value) {
@@ -890,7 +898,7 @@ function isClaudeTextLikeMediaType(mediaType) {
890
898
  }
891
899
 
892
900
  // src/agents/config/commands.ts
893
- import path2 from "path";
901
+ import path3 from "path";
894
902
  function buildFrontmatter(values) {
895
903
  const lines = Object.entries(values).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}: ${JSON.stringify(value)}`);
896
904
  return lines.length > 0 ? `---
@@ -901,7 +909,7 @@ ${lines.join("\n")}
901
909
  }
902
910
  function buildClaudeCommandArtifacts(commands, layout) {
903
911
  return (commands ?? []).map((command) => ({
904
- path: path2.join(layout.claudeDir, "commands", `${command.name}.md`),
912
+ path: path3.join(layout.claudeDir, "commands", `${command.name}.md`),
905
913
  content: buildFrontmatter({
906
914
  description: command.description
907
915
  }) + command.template
@@ -936,7 +944,7 @@ function assertCommandsSupported(provider, commands) {
936
944
  }
937
945
 
938
946
  // src/agents/config/hooks.ts
939
- import path3 from "path";
947
+ import path4 from "path";
940
948
  function hasHookEntries(hooks) {
941
949
  if (!hooks || typeof hooks !== "object") {
942
950
  return false;
@@ -1049,7 +1057,7 @@ function buildOpenCodePluginArtifacts(plugins, opencodeDir) {
1049
1057
  }
1050
1058
  seenFileNames.add(fileName);
1051
1059
  return {
1052
- path: path3.join(opencodeDir, "plugins", fileName),
1060
+ path: path4.join(opencodeDir, "plugins", fileName),
1053
1061
  content: buildOpenCodePluginSource(plugin)
1054
1062
  };
1055
1063
  });
@@ -1296,7 +1304,7 @@ function buildCodexConfigToml(opts = {}) {
1296
1304
  // src/agents/config/setup.ts
1297
1305
  import { mkdir, chmod, rm, writeFile } from "fs/promises";
1298
1306
  import os from "os";
1299
- import path4 from "path";
1307
+ import path5 from "path";
1300
1308
  function shortLabel(command) {
1301
1309
  const oneLine = command.replace(/\s+/g, " ").trim();
1302
1310
  return oneLine.length > 60 ? `${oneLine.slice(0, 60)}\u2026` : oneLine;
@@ -1304,21 +1312,21 @@ function shortLabel(command) {
1304
1312
  function agentboxRoot(provider, hasSandbox = true, stateDirectory) {
1305
1313
  if (stateDirectory !== void 0) {
1306
1314
  if (hasSandbox) throw new Error("stateDirectory is only supported for host execution.");
1307
- if (!path4.isAbsolute(stateDirectory)) throw new Error("stateDirectory must be an absolute path.");
1308
- return path4.join(stateDirectory, provider);
1315
+ if (!path5.isAbsolute(stateDirectory)) throw new Error("stateDirectory must be an absolute path.");
1316
+ return path5.join(stateDirectory, provider);
1309
1317
  }
1310
- return hasSandbox ? `/tmp/agentbox/${provider}` : path4.join(os.tmpdir(), `agentbox-${provider}`);
1318
+ return hasSandbox ? `/tmp/agentbox/${provider}` : path5.join(os.tmpdir(), `agentbox-${provider}`);
1311
1319
  }
1312
1320
  function getAgentLayout(rootDir) {
1313
- const xdgConfigHome = path4.join(rootDir, ".config");
1321
+ const xdgConfigHome = path5.join(rootDir, ".config");
1314
1322
  return {
1315
1323
  rootDir,
1316
1324
  homeDir: rootDir,
1317
1325
  xdgConfigHome,
1318
- agentsDir: path4.join(rootDir, ".agents"),
1319
- claudeDir: path4.join(rootDir, ".claude"),
1320
- opencodeDir: path4.join(xdgConfigHome, "opencode"),
1321
- codexDir: path4.join(rootDir, ".codex")
1326
+ agentsDir: path5.join(rootDir, ".agents"),
1327
+ claudeDir: path5.join(rootDir, ".claude"),
1328
+ opencodeDir: path5.join(xdgConfigHome, "opencode"),
1329
+ codexDir: path5.join(rootDir, ".codex")
1322
1330
  };
1323
1331
  }
1324
1332
  function buildLayoutEnv(provider, layout) {
@@ -1329,7 +1337,7 @@ function buildLayoutEnv(provider, layout) {
1329
1337
  return { CODEX_HOME: layout.codexDir };
1330
1338
  case "open-code":
1331
1339
  return {
1332
- OPENCODE_CONFIG: path4.join(layout.opencodeDir, "agentbox.json"),
1340
+ OPENCODE_CONFIG: path5.join(layout.opencodeDir, "agentbox.json"),
1333
1341
  OPENCODE_CONFIG_DIR: layout.opencodeDir
1334
1342
  };
1335
1343
  }
@@ -1359,7 +1367,7 @@ var HostSetupTarget = class {
1359
1367
  async () => {
1360
1368
  await Promise.all(
1361
1369
  files.map(async (entry) => {
1362
- await mkdir(path4.dirname(entry.path), { recursive: true, mode: 448 });
1370
+ await mkdir(path5.dirname(entry.path), { recursive: true, mode: 448 });
1363
1371
  const content = typeof entry.content === "string" ? entry.content : entry.content;
1364
1372
  await writeFile(entry.path, content, { mode: entry.mode ?? 384 });
1365
1373
  if (entry.mode && (entry.mode & 73) !== 0) {
@@ -1577,13 +1585,13 @@ async function activateRtk(target) {
1577
1585
  }
1578
1586
 
1579
1587
  // src/agents/config/setup-manifest.ts
1580
- import { createHash } from "crypto";
1581
- import path5 from "path";
1588
+ import { createHash, randomUUID } from "crypto";
1589
+ import path6 from "path";
1582
1590
  var MANIFEST_FILENAME = "setup-manifest.json";
1583
- var TARGET_MANIFEST_FILENAME = "setup-target.json";
1584
- var INSTALL_SCRIPT_FILENAME = "install.sh";
1591
+ var TARGET_MANIFEST_PREFIX = "setup-target.";
1592
+ var INSTALL_SCRIPT_PREFIX = "install.";
1585
1593
  var SETUP_ID_FILENAME = "setup.id";
1586
- var MANIFEST_VERSION = 1;
1594
+ var MANIFEST_VERSION = 2;
1587
1595
  function hashArtifact(artifact) {
1588
1596
  const hasher = createHash("sha256");
1589
1597
  hasher.update(artifact.executable ? "1" : "0");
@@ -1632,7 +1640,7 @@ async function preflightSetup(target, setupId, daemon) {
1632
1640
  debugSetup,
1633
1641
  `preflightSetup ${target.provider}`,
1634
1642
  async () => {
1635
- const setupIdFile = path5.posix.join(
1643
+ const setupIdFile = path6.posix.join(
1636
1644
  target.layout.rootDir,
1637
1645
  SETUP_ID_FILENAME
1638
1646
  );
@@ -1660,7 +1668,7 @@ async function preflightSetup(target, setupId, daemon) {
1660
1668
  }
1661
1669
  async function markSetupComplete(target, setupId) {
1662
1670
  await time(debugSetup, `markSetupComplete ${target.provider}`, async () => {
1663
- const setupIdFile = path5.posix.join(
1671
+ const setupIdFile = path6.posix.join(
1664
1672
  target.layout.rootDir,
1665
1673
  SETUP_ID_FILENAME
1666
1674
  );
@@ -1677,7 +1685,7 @@ ${detail}` : ""}`
1677
1685
  }
1678
1686
  });
1679
1687
  }
1680
- function buildInstallScript(rootDir, installCommandsByKey) {
1688
+ function buildInstallScript(rootDir, targetManifestPath, installCommandsByKey) {
1681
1689
  const commandsB64 = Buffer.from(
1682
1690
  JSON.stringify(installCommandsByKey),
1683
1691
  "utf8"
@@ -1685,7 +1693,7 @@ function buildInstallScript(rootDir, installCommandsByKey) {
1685
1693
  return `#!/usr/bin/env bash
1686
1694
  set -e
1687
1695
  ROOT_DIR=${shellQuote(rootDir)}
1688
- TARGET_MANIFEST="$ROOT_DIR/${TARGET_MANIFEST_FILENAME}"
1696
+ TARGET_MANIFEST=${shellQuote(targetManifestPath)}
1689
1697
  EXISTING_MANIFEST="$ROOT_DIR/${MANIFEST_FILENAME}"
1690
1698
  export TARGET_MANIFEST EXISTING_MANIFEST
1691
1699
 
@@ -1694,7 +1702,8 @@ export TARGET_MANIFEST EXISTING_MANIFEST
1694
1702
  # emits the commands themselves, NUL-separated, so bash never has to
1695
1703
  # deserialize JSON.
1696
1704
  STALE_CMDS_FILE="$(mktemp)"
1697
- trap 'rm -f "$STALE_CMDS_FILE"' EXIT
1705
+ # This run's target manifest and script are per-run files; remove them.
1706
+ trap 'rm -f "$STALE_CMDS_FILE" "$TARGET_MANIFEST" "$0"' EXIT
1698
1707
  COMMANDS_B64=${shellQuote(commandsB64)} \\
1699
1708
  MANIFEST_VERSION=${MANIFEST_VERSION} \\
1700
1709
  python3 - <<'PY' > "$STALE_CMDS_FILE"
@@ -1720,15 +1729,36 @@ stale = [
1720
1729
  for key, hashed in target_cmds.items()
1721
1730
  if commands.get(key) is not None and existing_cmds.get(key) != hashed
1722
1731
  ]
1723
- sys.stdout.write("\\0".join(stale))
1732
+ # Terminate every entry: \`read -d ''\` drops a last entry with no NUL.
1733
+ sys.stdout.write("".join(cmd + "\\0" for cmd in stale))
1724
1734
  PY
1725
1735
 
1736
+ # Run stale commands in parallel, then retry failures one at a time: parallel
1737
+ # \`npx\` calls race on a cold npx cache, and the cache is warm by the retry.
1738
+ FAILED=0
1726
1739
  if [ -s "$STALE_CMDS_FILE" ]; then
1740
+ CMDS=()
1741
+ PIDS=()
1727
1742
  while IFS= read -r -d '' CMD; do
1728
1743
  [ -z "$CMD" ] && continue
1729
1744
  bash -c "$CMD" &
1745
+ CMDS+=("$CMD")
1746
+ PIDS+=("$!")
1730
1747
  done < "$STALE_CMDS_FILE"
1731
- wait
1748
+ for i in "\${!PIDS[@]}"; do
1749
+ if ! wait "\${PIDS[$i]}"; then
1750
+ echo "agentbox install failed, retrying: \${CMDS[$i]}" >&2
1751
+ if ! bash -c "\${CMDS[$i]}"; then
1752
+ echo "agentbox install failed: \${CMDS[$i]}" >&2
1753
+ FAILED=1
1754
+ fi
1755
+ fi
1756
+ done
1757
+ fi
1758
+
1759
+ # Keep the old manifest when an install failed so the next run retries it.
1760
+ if [ "$FAILED" -ne 0 ]; then
1761
+ exit 1
1732
1762
  fi
1733
1763
 
1734
1764
  # Persist target manifest as the new manifest atomically. Doing this last
@@ -1737,7 +1767,7 @@ mv "$TARGET_MANIFEST" "$EXISTING_MANIFEST"
1737
1767
  `;
1738
1768
  }
1739
1769
  async function applyDifferentialSetup(target, artifacts, installCommands) {
1740
- await time(
1770
+ return time(
1741
1771
  debugSetup,
1742
1772
  `applyDifferentialSetup ${target.provider}`,
1743
1773
  async () => {
@@ -1755,7 +1785,16 @@ async function applyDifferentialSetup(target, artifacts, installCommands) {
1755
1785
  ])
1756
1786
  )
1757
1787
  };
1788
+ const runId = randomUUID();
1758
1789
  const rootDir = target.layout.rootDir;
1790
+ const targetManifestPath = path6.posix.join(
1791
+ rootDir,
1792
+ `${TARGET_MANIFEST_PREFIX}${runId}.json`
1793
+ );
1794
+ const installScriptPath = path6.posix.join(
1795
+ rootDir,
1796
+ `${INSTALL_SCRIPT_PREFIX}${runId}.sh`
1797
+ );
1759
1798
  const tarballEntries = [
1760
1799
  ...artifacts.map((artifact) => ({
1761
1800
  path: artifact.path,
@@ -1763,22 +1802,36 @@ async function applyDifferentialSetup(target, artifacts, installCommands) {
1763
1802
  mode: artifact.executable ? 493 : 420
1764
1803
  })),
1765
1804
  {
1766
- path: path5.posix.join(rootDir, TARGET_MANIFEST_FILENAME),
1805
+ path: targetManifestPath,
1767
1806
  content: JSON.stringify(targetForSandbox),
1768
1807
  mode: 420
1769
1808
  },
1770
1809
  {
1771
- path: path5.posix.join(rootDir, INSTALL_SCRIPT_FILENAME),
1772
- content: buildInstallScript(rootDir, installCommandsByKey),
1810
+ path: installScriptPath,
1811
+ content: buildInstallScript(
1812
+ rootDir,
1813
+ targetManifestPath,
1814
+ installCommandsByKey
1815
+ ),
1773
1816
  mode: 493
1774
1817
  }
1775
1818
  ];
1776
- await target.uploadAndRun(
1819
+ const result = await target.uploadAndRun(
1777
1820
  tarballEntries,
1778
- `bash ${shellQuote(path5.posix.join(rootDir, INSTALL_SCRIPT_FILENAME))}`
1821
+ `bash ${shellQuote(installScriptPath)}`
1779
1822
  );
1823
+ if (result.exitCode !== 0) {
1824
+ const output = result.combinedOutput?.trim();
1825
+ console.warn(
1826
+ `[agentbox] ${target.provider} setup install failed (exit ${result.exitCode}); it will be retried on the next setup${output ? `:
1827
+ ${output.slice(-2e3)}` : ""}`
1828
+ );
1829
+ return false;
1830
+ }
1831
+ return true;
1780
1832
  },
1781
- () => ({
1833
+ (ok) => ({
1834
+ ok,
1782
1835
  artifacts: artifacts.length,
1783
1836
  installCommands: installCommands.length
1784
1837
  })
@@ -1786,15 +1839,15 @@ async function applyDifferentialSetup(target, artifacts, installCommands) {
1786
1839
  }
1787
1840
 
1788
1841
  // src/agents/config/skills.ts
1789
- import path6 from "path";
1842
+ import path7 from "path";
1790
1843
  function getSkillTargetDir(provider, layout, skillName) {
1791
1844
  switch (provider) {
1792
1845
  case AgentProvider.ClaudeCode:
1793
- return path6.join(layout.claudeDir, "skills", skillName);
1846
+ return path7.join(layout.claudeDir, "skills", skillName);
1794
1847
  case AgentProvider.OpenCode:
1795
- return path6.join(layout.opencodeDir, "skills", skillName);
1848
+ return path7.join(layout.opencodeDir, "skills", skillName);
1796
1849
  case AgentProvider.Codex:
1797
- return path6.join(layout.codexDir, "skills", skillName);
1850
+ return path7.join(layout.codexDir, "skills", skillName);
1798
1851
  }
1799
1852
  }
1800
1853
  function skillsCliAgentName(provider) {
@@ -1810,7 +1863,7 @@ async function prepareSkillArtifacts(provider, skills, layout) {
1810
1863
  const preparedSkills = [];
1811
1864
  for (const skill of skills ?? []) {
1812
1865
  const targetDir = getSkillTargetDir(provider, layout, skill.name);
1813
- const skillFilePath = path6.join(targetDir, "SKILL.md");
1866
+ const skillFilePath = path7.join(targetDir, "SKILL.md");
1814
1867
  if (!("files" in skill)) {
1815
1868
  installCommands.push(buildSkillsInstallerCommand(provider, skill));
1816
1869
  preparedSkills.push({ name: skill.name, skillFilePath });
@@ -1818,7 +1871,7 @@ async function prepareSkillArtifacts(provider, skills, layout) {
1818
1871
  }
1819
1872
  for (const [relativePath, content] of Object.entries(skill.files)) {
1820
1873
  artifacts.push({
1821
- path: path6.join(targetDir, relativePath),
1874
+ path: path7.join(targetDir, relativePath),
1822
1875
  content,
1823
1876
  executable: relativePath.startsWith("scripts/")
1824
1877
  });
@@ -1833,7 +1886,7 @@ async function prepareSkillArtifacts(provider, skills, layout) {
1833
1886
  }
1834
1887
 
1835
1888
  // src/agents/config/subagents.ts
1836
- import path7 from "path";
1889
+ import path8 from "path";
1837
1890
  function toToolsArray(tools) {
1838
1891
  const filtered = tools?.map((tool) => tool.trim()).filter(Boolean);
1839
1892
  return filtered && filtered.length > 0 ? filtered : void 0;
@@ -1863,7 +1916,7 @@ ${frontmatterLines.join("\n")}
1863
1916
  ${subAgent.instructions.trim()}
1864
1917
  `;
1865
1918
  return {
1866
- path: path7.join(layout.claudeDir, "agents", `${subAgent.name}.md`),
1919
+ path: path8.join(layout.claudeDir, "agents", `${subAgent.name}.md`),
1867
1920
  content
1868
1921
  };
1869
1922
  });
@@ -1901,7 +1954,7 @@ function buildCodexSubagentArtifacts(subAgents, layout, defaultModel) {
1901
1954
  const roleConfigRelativePath = `./agents/${subAgent.name}.toml`;
1902
1955
  const roleConfigPromptPath = `../prompts/${subAgent.name}.md`;
1903
1956
  artifacts.push({
1904
- path: path7.join(layout.codexDir, "prompts", `${subAgent.name}.md`),
1957
+ path: path8.join(layout.codexDir, "prompts", `${subAgent.name}.md`),
1905
1958
  content: subAgent.instructions
1906
1959
  });
1907
1960
  const tomlLines = [
@@ -1919,7 +1972,7 @@ function buildCodexSubagentArtifacts(subAgents, layout, defaultModel) {
1919
1972
  ""
1920
1973
  );
1921
1974
  artifacts.push({
1922
- path: path7.join(layout.codexDir, "agents", `${subAgent.name}.toml`),
1975
+ path: path8.join(layout.codexDir, "agents", `${subAgent.name}.toml`),
1923
1976
  content: tomlLines.join("\n")
1924
1977
  });
1925
1978
  agentSections.push(
@@ -2608,7 +2661,7 @@ var DAEMON_TOKEN_PATH = "/tmp/agentbox/claude-code/daemon-token";
2608
2661
  var DAEMON_READY_TIMEOUT_MS = 3e4;
2609
2662
  var DAEMON_READY_POLL_INTERVAL_MS = 250;
2610
2663
  function claudeConfigDir(options) {
2611
- return path8.join(
2664
+ return path9.join(
2612
2665
  agentboxRoot(
2613
2666
  AgentProvider.ClaudeCode,
2614
2667
  Boolean(options.sandbox),
@@ -2626,7 +2679,9 @@ function buildClaudeQueryOptions(params) {
2626
2679
  for (const arg of provider?.args ?? []) {
2627
2680
  if (typeof arg !== "string") continue;
2628
2681
  if (arg.startsWith("--")) {
2629
- extraArgs[arg.slice(2)] = null;
2682
+ const separator = arg.indexOf("=");
2683
+ if (separator === -1) extraArgs[arg.slice(2)] = null;
2684
+ else extraArgs[arg.slice(2, separator)] = arg.slice(separator + 1);
2630
2685
  }
2631
2686
  }
2632
2687
  if (run.systemPrompt) {
@@ -3418,7 +3473,7 @@ async function ensureClaudeCodeDaemonUncached(options, env) {
3418
3473
  DAEMON_TOKEN_PATH,
3419
3474
  true
3420
3475
  );
3421
- const daemonDir = path8.posix.dirname(DAEMON_PATH);
3476
+ const daemonDir = path9.posix.dirname(DAEMON_PATH);
3422
3477
  const daemonNodeModules = `${daemonDir}/node_modules/@anthropic-ai`;
3423
3478
  const launchCommand = [
3424
3479
  `NPM_ROOT="$(npm root -g 2>/dev/null)"`,
@@ -3591,8 +3646,8 @@ var ClaudeCodeAgentAdapter = class {
3591
3646
  const provider = request.provider;
3592
3647
  const sandbox = options.sandbox;
3593
3648
  const target = await createSetupTarget(provider, "shared-setup", options);
3594
- const settingsPath = path8.join(target.layout.claudeDir, "settings.json");
3595
- const mcpConfigPath = path8.join(
3649
+ const settingsPath = path9.join(target.layout.claudeDir, "settings.json");
3650
+ const mcpConfigPath = path9.join(
3596
3651
  target.layout.claudeDir,
3597
3652
  "agentbox-mcp.json"
3598
3653
  );
@@ -3616,7 +3671,7 @@ var ClaudeCodeAgentAdapter = class {
3616
3671
  const artifacts = [
3617
3672
  ...!sandbox ? [
3618
3673
  {
3619
- path: path8.join(
3674
+ path: path9.join(
3620
3675
  target.layout.claudeDir,
3621
3676
  ".claude-plugin",
3622
3677
  "plugin.json"
@@ -3650,7 +3705,7 @@ var ClaudeCodeAgentAdapter = class {
3650
3705
  return;
3651
3706
  }
3652
3707
  const env = { ...options.env ?? {}, ...target.env };
3653
- await Promise.all([
3708
+ const [installed] = await Promise.all([
3654
3709
  time(
3655
3710
  debugClaude,
3656
3711
  "applyDifferentialSetup",
@@ -3661,7 +3716,7 @@ var ClaudeCodeAgentAdapter = class {
3661
3716
  if (enableRtk) {
3662
3717
  await time(debugClaude, "activateRtk", () => activateRtk(target));
3663
3718
  }
3664
- await markSetupComplete(target, setupId);
3719
+ if (installed) await markSetupComplete(target, setupId);
3665
3720
  });
3666
3721
  }
3667
3722
  async execute(request, sink) {
@@ -3673,8 +3728,8 @@ var ClaudeCodeAgentAdapter = class {
3673
3728
  return;
3674
3729
  }
3675
3730
  const claudeDir = claudeConfigDir(request.options);
3676
- const settingsPath = path8.join(claudeDir, "settings.json");
3677
- const mcpConfigPath = path8.join(claudeDir, "agentbox-mcp.json");
3731
+ const settingsPath = path9.join(claudeDir, "settings.json");
3732
+ const mcpConfigPath = path9.join(claudeDir, "agentbox-mcp.json");
3678
3733
  const env = {
3679
3734
  ...request.options.env ?? {},
3680
3735
  CLAUDE_CONFIG_DIR: claudeDir,
@@ -3699,8 +3754,8 @@ ${serialized}` : serialized;
3699
3754
  () => validateProviderUserInput(request.provider, request.run.input)
3700
3755
  );
3701
3756
  const userContent = mapToClaudeUserContent(inputParts);
3702
- const initialUuid = randomUUID();
3703
- const presetSessionId = request.run.resumeSessionId ?? randomUUID();
3757
+ const initialUuid = randomUUID2();
3758
+ const presetSessionId = request.run.resumeSessionId ?? randomUUID2();
3704
3759
  sink.setSessionId(presetSessionId);
3705
3760
  const baseUrl = await time(
3706
3761
  debugClaude,
@@ -3765,7 +3820,7 @@ ${serialized}` : serialized;
3765
3820
  sink.onMessage(async (content) => {
3766
3821
  const parts = await validateProviderUserInput(request.provider, content);
3767
3822
  const mapped = mapToClaudeUserContent(parts);
3768
- const messageUuid = randomUUID();
3823
+ const messageUuid = randomUUID2();
3769
3824
  await fetch(
3770
3825
  `${baseUrl}/runs/${encodeURIComponent(request.runId)}/sendMessage`,
3771
3826
  {
@@ -4386,7 +4441,7 @@ async function executeNativeClaude(request, sink, wait = {}) {
4386
4441
  const input = attachOnly ? [] : await validateProviderUserInput(request.provider, request.run.input);
4387
4442
  const parkOption = request.options.provider?.parkBackgroundWork;
4388
4443
  const parking = parkOption && "onWake" in parkOption ? parkOption : void 0;
4389
- const sessionId = request.run.resumeSessionId ?? randomUUID();
4444
+ const sessionId = request.run.resumeSessionId ?? randomUUID2();
4390
4445
  if (request.run.forkSessionId)
4391
4446
  await findParkedNativeSession(request.run.forkSessionId)?.end();
4392
4447
  const adopting = request.run.resumeSessionId ? findParkedNativeSession(request.run.resumeSessionId) : void 0;
@@ -4403,7 +4458,7 @@ async function executeNativeClaude(request, sink, wait = {}) {
4403
4458
  await stop();
4404
4459
  });
4405
4460
  sink.setSessionId(sessionId);
4406
- const messageId = randomUUID();
4461
+ const messageId = randomUUID2();
4407
4462
  const userMessage = {
4408
4463
  type: "user",
4409
4464
  uuid: messageId,
@@ -4432,8 +4487,8 @@ async function executeNativeClaude(request, sink, wait = {}) {
4432
4487
  const options = buildClaudeQueryOptions({
4433
4488
  request,
4434
4489
  ...request.options.configuration === "native" ? {} : {
4435
- settingsPath: path8.join(claudeDir, "settings.json"),
4436
- mcpConfigPath: path8.join(claudeDir, "agentbox-mcp.json")
4490
+ settingsPath: path9.join(claudeDir, "settings.json"),
4491
+ mcpConfigPath: path9.join(claudeDir, "agentbox-mcp.json")
4437
4492
  },
4438
4493
  // Auth is deliberately CLI-owned. Never copy the user's credential files
4439
4494
  // into the generated configuration directory or a task artifact.
@@ -4630,7 +4685,7 @@ async function executeNativeClaude(request, sink, wait = {}) {
4630
4685
 
4631
4686
  // src/agents/providers/codex.ts
4632
4687
  import crypto2 from "crypto";
4633
- import path9 from "path";
4688
+ import path10 from "path";
4634
4689
 
4635
4690
  // src/agents/transports/app-server.ts
4636
4691
  import { createParser } from "eventsource-parser";
@@ -4849,7 +4904,7 @@ var JsonRpcLineClient = class {
4849
4904
 
4850
4905
  // src/agents/providers/codex.ts
4851
4906
  function codexConfigDir(options) {
4852
- return path9.join(
4907
+ return path10.join(
4853
4908
  agentboxRoot(AgentProvider.Codex, Boolean(options.sandbox), options.stateDirectory),
4854
4909
  ".codex"
4855
4910
  );
@@ -4858,7 +4913,7 @@ var REMOTE_CODEX_APP_SERVER_PORT = 43181;
4858
4913
  var REMOTE_CODEX_APP_SERVER_ID = "shared-app-server";
4859
4914
  var CODEX_APP_SERVER_TOKEN_FILENAME = "codex-app-server-token";
4860
4915
  function defaultRemoteCodexTokenPath() {
4861
- return path9.posix.join(
4916
+ return path10.posix.join(
4862
4917
  agentboxRoot(AgentProvider.Codex, true),
4863
4918
  CODEX_APP_SERVER_TOKEN_FILENAME
4864
4919
  );
@@ -5089,12 +5144,15 @@ function shouldIgnoreCodexError(notification) {
5089
5144
  return notification.params?.willRetry === true;
5090
5145
  }
5091
5146
  function buildCodexCommandArgs(binary, args, options) {
5147
+ return [...options?.configuration === "native" ? [] : ["-u", "XDG_CONFIG_HOME"], ...buildCodexCommand(binary, args, options)];
5148
+ }
5149
+ function buildCodexCommand(binary, args, options) {
5092
5150
  const overrides = [];
5093
5151
  if (options?.provider?.supportsWebsockets === false) {
5094
5152
  overrides.push(["supports_websockets", "false"]);
5095
5153
  }
5096
5154
  const overrideArgs = overrides.flatMap(([k, v]) => ["-c", `${k}=${v}`]);
5097
- return [...options?.configuration === "native" ? [] : ["-u", "XDG_CONFIG_HOME"], binary, ...overrideArgs, ...args];
5155
+ return [binary, ...overrideArgs, ...options?.provider?.args ?? [], ...args];
5098
5156
  }
5099
5157
  function toNormalizedCodexEvents(runId, notification) {
5100
5158
  const base = {
@@ -5317,7 +5375,7 @@ async function materializeCodexImage(options, part, index) {
5317
5375
  throw new Error("Cannot attach an empty image to Codex.");
5318
5376
  }
5319
5377
  const root = agentboxRoot(AgentProvider.Codex, Boolean(options.sandbox), options.stateDirectory);
5320
- const imagePath = path9.join(
5378
+ const imagePath = path10.join(
5321
5379
  root,
5322
5380
  "inputs",
5323
5381
  `codex-image-${index}-${crypto2.randomUUID()}${codexImageExtension(part.mediaType)}`
@@ -5336,7 +5394,7 @@ async function materializeCodexImage(options, part, index) {
5336
5394
  return imagePath;
5337
5395
  }
5338
5396
  const fs = await import("fs/promises");
5339
- await fs.mkdir(path9.dirname(imagePath), { recursive: true });
5397
+ await fs.mkdir(path10.dirname(imagePath), { recursive: true });
5340
5398
  await fs.writeFile(imagePath, data);
5341
5399
  return imagePath;
5342
5400
  }
@@ -5498,13 +5556,13 @@ async function setupCodex(request) {
5498
5556
  const artifacts = [...subAgentArtifacts];
5499
5557
  if (configToml) {
5500
5558
  artifacts.push({
5501
- path: path9.join(layoutTarget.layout.codexDir, "config.toml"),
5559
+ path: path10.join(layoutTarget.layout.codexDir, "config.toml"),
5502
5560
  content: configToml
5503
5561
  });
5504
5562
  }
5505
5563
  if (hooksFile) {
5506
5564
  artifacts.push({
5507
- path: path9.join(layoutTarget.layout.codexDir, "hooks.json"),
5565
+ path: path10.join(layoutTarget.layout.codexDir, "hooks.json"),
5508
5566
  content: JSON.stringify(hooksFile, null, 2)
5509
5567
  });
5510
5568
  }
@@ -5523,7 +5581,7 @@ async function setupCodex(request) {
5523
5581
  ...sharedTarget.env,
5524
5582
  ...options.provider?.env ?? {}
5525
5583
  });
5526
- const tokenFilePath = path9.posix.join(
5584
+ const tokenFilePath = path10.posix.join(
5527
5585
  sharedTarget.layout.rootDir,
5528
5586
  CODEX_APP_SERVER_TOKEN_FILENAME
5529
5587
  );
@@ -5559,11 +5617,11 @@ async function setupCodex(request) {
5559
5617
  );
5560
5618
  await applyDifferentialSetup(sharedTarget, serverArtifacts, []);
5561
5619
  const binary = options.provider?.binary ?? "codex";
5562
- const pidFilePath = path9.posix.join(
5620
+ const pidFilePath = path10.posix.join(
5563
5621
  sharedTarget.layout.rootDir,
5564
5622
  "codex-app-server.pid"
5565
5623
  );
5566
- const logFilePath = path9.posix.join(
5624
+ const logFilePath = path10.posix.join(
5567
5625
  sharedTarget.layout.rootDir,
5568
5626
  "codex-app-server.log"
5569
5627
  );
@@ -5618,8 +5676,13 @@ async function setupCodex(request) {
5618
5676
  `Could not start Codex app-server: ${launchResult.combinedOutput || launchResult.stderr}`
5619
5677
  );
5620
5678
  }
5679
+ let installed2;
5621
5680
  try {
5622
- await applyDifferentialSetup(target2, skillArtifacts2, installCommands2);
5681
+ installed2 = await applyDifferentialSetup(
5682
+ target2,
5683
+ skillArtifacts2,
5684
+ installCommands2
5685
+ );
5623
5686
  } catch (error) {
5624
5687
  await target2.cleanup().catch(() => void 0);
5625
5688
  throw error;
@@ -5627,7 +5690,7 @@ async function setupCodex(request) {
5627
5690
  if (enableRtk2) {
5628
5691
  await time(debugCodex, "activateRtk", () => activateRtk(sharedTarget));
5629
5692
  }
5630
- await markSetupComplete(sharedTarget, setupId2);
5693
+ if (installed2) await markSetupComplete(sharedTarget, setupId2);
5631
5694
  return;
5632
5695
  }
5633
5696
  const target = await createSetupTarget(provider, "shared-setup", options);
@@ -5650,11 +5713,15 @@ async function setupCodex(request) {
5650
5713
  await target.cleanup().catch(() => void 0);
5651
5714
  throw error;
5652
5715
  }
5653
- await applyDifferentialSetup(target, allArtifacts, installCommands);
5716
+ const installed = await applyDifferentialSetup(
5717
+ target,
5718
+ allArtifacts,
5719
+ installCommands
5720
+ );
5654
5721
  if (enableRtk) {
5655
5722
  await time(debugCodex, "activateRtk", () => activateRtk(target));
5656
5723
  }
5657
- await markSetupComplete(target, setupId);
5724
+ if (installed) await markSetupComplete(target, setupId);
5658
5725
  }
5659
5726
  async function createRuntime(request, inputParts) {
5660
5727
  const options = request.options;
@@ -5664,7 +5731,7 @@ async function createRuntime(request, inputParts) {
5664
5731
  ...options.configuration === "native" ? {} : { CODEX_HOME: codexDir },
5665
5732
  ...options.provider?.env ?? {}
5666
5733
  });
5667
- const runtimeCwd = options.configuration === "native" ? options.cwd : path9.dirname(codexDir);
5734
+ const runtimeCwd = options.configuration === "native" ? options.cwd : path10.dirname(codexDir);
5668
5735
  const inputItems = await buildCodexInputItems(options, inputParts);
5669
5736
  const usesRemoteWebSocket = options.sandbox && options.sandbox.provider !== SandboxProvider.LocalDocker;
5670
5737
  if (usesRemoteWebSocket && options.sandbox) {
@@ -5695,12 +5762,9 @@ async function createRuntime(request, inputParts) {
5695
5762
  inputItems
5696
5763
  };
5697
5764
  }
5698
- const codexArgs = buildCodexCommandArgs(
5699
- options.provider?.binary ?? "codex",
5700
- ["app-server"],
5701
- options
5702
- );
5765
+ const binary = options.provider?.binary ?? "codex";
5703
5766
  if (options.sandbox) {
5767
+ const codexArgs = buildCodexCommandArgs(binary, ["app-server"], options);
5704
5768
  const handle = await options.sandbox.runAsync(["env", ...codexArgs], {
5705
5769
  cwd: runtimeCwd,
5706
5770
  env
@@ -5733,15 +5797,15 @@ async function createRuntime(request, inputParts) {
5733
5797
  inputItems
5734
5798
  };
5735
5799
  }
5800
+ const [command, ...args] = buildCodexCommand(binary, ["app-server"], options);
5801
+ const hostEnv = { ...process.env, ...env };
5802
+ if (options.configuration !== "native") delete hostEnv.XDG_CONFIG_HOME;
5736
5803
  const processHandle = spawnCommand({
5737
5804
  processGroup: options.processGroup !== "inherited",
5738
- command: "env",
5739
- args: codexArgs,
5805
+ command,
5806
+ args,
5740
5807
  cwd: runtimeCwd,
5741
- env: {
5742
- ...process.env,
5743
- ...env
5744
- }
5808
+ env: hostEnv
5745
5809
  });
5746
5810
  processHandle.child.stderr.resume();
5747
5811
  return {
@@ -5779,7 +5843,7 @@ async function killCodexAppServer(request) {
5779
5843
  REMOTE_CODEX_APP_SERVER_ID,
5780
5844
  options
5781
5845
  );
5782
- const pidFilePath = path9.posix.join(
5846
+ const pidFilePath = path10.posix.join(
5783
5847
  sharedTarget.layout.rootDir,
5784
5848
  "codex-app-server.pid"
5785
5849
  );
@@ -6335,16 +6399,16 @@ var CodexAgentAdapter = class {
6335
6399
  };
6336
6400
 
6337
6401
  // src/agents/providers/opencode.ts
6338
- import { createHash as createHash2, randomBytes, randomUUID as randomUUID2 } from "crypto";
6402
+ import { createHash as createHash2, randomBytes, randomUUID as randomUUID3 } from "crypto";
6339
6403
  import os2 from "os";
6340
- import path10 from "path";
6404
+ import path11 from "path";
6341
6405
  var SANDBOX_OPENCODE_PORT = 4096;
6342
6406
  var SANDBOX_OPENCODE_READY_TIMEOUT_MS = 9e4;
6343
6407
  var LOCAL_OPENCODE_READY_TIMEOUT_MS = 2e4;
6344
6408
  var SHARED_OPENCODE_TARGET_ID = "shared-opencode-server";
6345
6409
  var OPENCODE_AUTH_USERNAME = "opencode";
6346
6410
  function opencodeServerTokenPath() {
6347
- return path10.posix.join(
6411
+ return path11.posix.join(
6348
6412
  agentboxRoot(AgentProvider.OpenCode, true),
6349
6413
  "opencode-auth-token"
6350
6414
  );
@@ -6630,7 +6694,7 @@ async function ensureSandboxOpenCodeServer(request) {
6630
6694
  plugins,
6631
6695
  target.layout.opencodeDir
6632
6696
  );
6633
- const configPath = path10.join(target.layout.opencodeDir, "agentbox.json");
6697
+ const configPath = path11.join(target.layout.opencodeDir, "agentbox.json");
6634
6698
  const openCodeConfig = buildOpenCodeConfig(options, interactiveApproval);
6635
6699
  const allArtifacts = [
6636
6700
  ...skillArtifacts,
@@ -6680,16 +6744,20 @@ async function ensureSandboxOpenCodeServer(request) {
6680
6744
  OPENCODE_DISABLE_DEFAULT_PLUGINS: "true",
6681
6745
  OPENCODE_ENABLE_QUESTION_TOOL: hasInteractiveQuestions(options) ? "true" : "false"
6682
6746
  };
6683
- await applyDifferentialSetup(target, allArtifacts, installCommands);
6747
+ const installed = await applyDifferentialSetup(
6748
+ target,
6749
+ allArtifacts,
6750
+ installCommands
6751
+ );
6684
6752
  if (enableRtk) {
6685
6753
  await time(debugOpencode, "activateRtk", () => activateRtk(target));
6686
6754
  }
6687
6755
  const binary = options.provider?.binary ?? "opencode";
6688
- const pidFilePath = path10.posix.join(
6756
+ const pidFilePath = path11.posix.join(
6689
6757
  target.layout.rootDir,
6690
6758
  "opencode-serve.pid"
6691
6759
  );
6692
- const logFilePath = path10.posix.join(
6760
+ const logFilePath = path11.posix.join(
6693
6761
  target.layout.rootDir,
6694
6762
  "opencode-serve.log"
6695
6763
  );
@@ -6804,14 +6872,14 @@ ${lastLog}` : "")
6804
6872
  "OpenCode server started but is not enforcing the capability token (OPENCODE_SERVER_PASSWORD ignored). Upgrade opencode-ai to a version that supports server authentication."
6805
6873
  );
6806
6874
  }
6807
- await markSetupComplete(target, setupId);
6875
+ if (installed) await markSetupComplete(target, setupId);
6808
6876
  });
6809
6877
  }
6810
6878
  async function startLocalOpenCodeServer(request) {
6811
6879
  const originalOptions = request.options;
6812
6880
  const options = {
6813
6881
  ...originalOptions,
6814
- stateDirectory: path10.join(originalOptions.stateDirectory ?? path10.join(os2.tmpdir(), "agentbox-native"), "instances", randomUUID2())
6882
+ stateDirectory: path11.join(originalOptions.stateDirectory ?? path11.join(os2.tmpdir(), "agentbox-native"), "instances", randomUUID3())
6815
6883
  };
6816
6884
  let generatedEnv = {};
6817
6885
  if (options.configuration !== "native") {
@@ -6819,7 +6887,7 @@ async function startLocalOpenCodeServer(request) {
6819
6887
  assertCommandsSupported(request.provider, options.commands);
6820
6888
  const target = await createSetupTarget(request.provider, "shared-setup", options);
6821
6889
  const { artifacts: skillArtifacts, installCommands } = await prepareSkillArtifacts(request.provider, options.skills, target.layout);
6822
- const configPath = path10.join(target.layout.opencodeDir, "agentbox.json");
6890
+ const configPath = path11.join(target.layout.opencodeDir, "agentbox.json");
6823
6891
  const artifacts = [
6824
6892
  ...skillArtifacts,
6825
6893
  ...buildOpenCodePluginArtifacts(plugins, target.layout.opencodeDir),
@@ -6912,7 +6980,7 @@ async function killOpenCodeServer(request) {
6912
6980
  SHARED_OPENCODE_TARGET_ID,
6913
6981
  options
6914
6982
  );
6915
- const pidFilePath = path10.posix.join(
6983
+ const pidFilePath = path11.posix.join(
6916
6984
  target.layout.rootDir,
6917
6985
  "opencode-serve.pid"
6918
6986
  );
@@ -7866,7 +7934,7 @@ function createAdapter(provider) {
7866
7934
  function prepareAgentOptions(_provider, options) {
7867
7935
  if (options.stateDirectory !== void 0) {
7868
7936
  if (options.sandbox) throw new Error("stateDirectory is only supported for host execution.");
7869
- if (!path11.isAbsolute(options.stateDirectory)) throw new Error("stateDirectory must be an absolute path.");
7937
+ if (!path12.isAbsolute(options.stateDirectory)) throw new Error("stateDirectory must be an absolute path.");
7870
7938
  }
7871
7939
  if (options.sandbox && options.processGroup !== void 0) throw new Error("processGroup is only supported for host execution.");
7872
7940
  resolveBackgroundTaskTimeoutMs(options.backgroundTaskTimeoutMs);
@@ -8307,7 +8375,7 @@ var Agent = class {
8307
8375
  throw new Error("AgentRunConfig.resumeParked requires resumeSessionId.");
8308
8376
  }
8309
8377
  }
8310
- const runId = runConfig.runId ?? randomUUID3();
8378
+ const runId = runConfig.runId ?? randomUUID4();
8311
8379
  const streamCalledAt = Date.now();
8312
8380
  debugAgent("stream() provider=%s runId=%s", this.provider, runId);
8313
8381
  const run = new AgentRunController(
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, C as BackgroundTask, D as BackgroundTasksEvent, Z as HarnessCommandsEvent, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a7 as NativePlanEvent, a8 as NormalizedAgentEvent, a9 as NormalizedAgentEventBase, aa as NormalizedAgentEventType, aj as PermissionRequestedEvent, ak as PermissionResolvedEvent, al as RawAgentEvent, am as ReasoningDeltaEvent, ao as RunCancelledEvent, ap as RunCompletedEvent, aq as RunErrorEvent, ar as RunStartedEvent, at as TextDeltaEvent, av as ToolCallCompletedEvent, aw as ToolCallDeltaEvent, ax as ToolCallStartedEvent, aE as createNormalizedEvent, aF as normalizeRawAgentEvent, aJ as toAISDKEvent, aK as toAISDKStream } from '../types-DM6zUiv1.js';
1
+ export { A as AISDKEvent, C as BackgroundTask, D as BackgroundTasksEvent, Z as HarnessCommandsEvent, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a7 as NativePlanEvent, a8 as NormalizedAgentEvent, a9 as NormalizedAgentEventBase, aa as NormalizedAgentEventType, aj as PermissionRequestedEvent, ak as PermissionResolvedEvent, al as RawAgentEvent, am as ReasoningDeltaEvent, ao as RunCancelledEvent, ap as RunCompletedEvent, aq as RunErrorEvent, ar as RunStartedEvent, at as TextDeltaEvent, av as ToolCallCompletedEvent, aw as ToolCallDeltaEvent, ax as ToolCallStartedEvent, aE as createNormalizedEvent, aF as normalizeRawAgentEvent, aJ as toAISDKEvent, aK as toAISDKStream } from '../types-ChkpU7Lf.js';
2
2
  import { AgentProvider } from '../enums.js';
3
3
  import '../Sandbox-DcKAU-E3.js';
4
4
  import 'e2b';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, B as AttachedRun, C as BackgroundTask, D as BackgroundTasksEvent, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, Z as HarnessCommandsEvent, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a6 as NativeParkBackgroundWork, a7 as NativePlanEvent, a8 as NormalizedAgentEvent, a9 as NormalizedAgentEventBase, aa as NormalizedAgentEventType, ab as OpenCodeAgentOptions, ac as OpenCodeCommandEntry, ad as OpenCodePluginConfig, ae as OpenCodePluginEvent, af as OpenCodePluginHookConfig, ag as OpenCodeProviderOptions, ah as OpenCodeSkillEntry, ai as OpenRouterPlugin, aj as PermissionRequestedEvent, ak as PermissionResolvedEvent, al as RawAgentEvent, am as ReasoningDeltaEvent, an as RepoSkillConfig, ao as RunCancelledEvent, ap as RunCompletedEvent, aq as RunErrorEvent, ar as RunStartedEvent, as as SetupLayout, at as TextDeltaEvent, au as TextPart, av as ToolCallCompletedEvent, aw as ToolCallDeltaEvent, ax as ToolCallStartedEvent, ay as UserContent, az as UserContentPart, aA as builtinHarnessCommands, aB as claudeHarnessCommands, aC as codexHarnessCommands, aD as codexSkillMention, aE as createNormalizedEvent, aF as normalizeRawAgentEvent, aG as openCodeHarnessCommands, aH as parseHarnessCommandInvocation, aI as skillDirective, aJ as toAISDKEvent, aK as toAISDKStream } from './types-DM6zUiv1.js';
1
+ export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, B as AttachedRun, C as BackgroundTask, D as BackgroundTasksEvent, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, Z as HarnessCommandsEvent, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a6 as NativeParkBackgroundWork, a7 as NativePlanEvent, a8 as NormalizedAgentEvent, a9 as NormalizedAgentEventBase, aa as NormalizedAgentEventType, ab as OpenCodeAgentOptions, ac as OpenCodeCommandEntry, ad as OpenCodePluginConfig, ae as OpenCodePluginEvent, af as OpenCodePluginHookConfig, ag as OpenCodeProviderOptions, ah as OpenCodeSkillEntry, ai as OpenRouterPlugin, aj as PermissionRequestedEvent, ak as PermissionResolvedEvent, al as RawAgentEvent, am as ReasoningDeltaEvent, an as RepoSkillConfig, ao as RunCancelledEvent, ap as RunCompletedEvent, aq as RunErrorEvent, ar as RunStartedEvent, as as SetupLayout, at as TextDeltaEvent, au as TextPart, av as ToolCallCompletedEvent, aw as ToolCallDeltaEvent, ax as ToolCallStartedEvent, ay as UserContent, az as UserContentPart, aA as builtinHarnessCommands, aB as claudeHarnessCommands, aC as codexHarnessCommands, aD as codexSkillMention, aE as createNormalizedEvent, aF as normalizeRawAgentEvent, aG as openCodeHarnessCommands, aH as parseHarnessCommandInvocation, aI as skillDirective, aJ as toAISDKEvent, aK as toAISDKStream } from './types-ChkpU7Lf.js';
2
2
  export { AGENT_RESERVED_PORTS, Agent, HarnessCapabilities, HarnessCommand, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout, harnessCapabilities, resolveHarnessCommand } from './agents/index.js';
3
3
  export { A as AsyncCommandHandle, C as CommandEvent, a as CommandOptions, b as CommandResult, D as DaytonaProviderOptions, c as DaytonaSandboxOptions, E as E2bProviderOptions, d as E2bSandboxOptions, G as GitCloneOptions, L as LocalDockerProviderOptions, e as LocalDockerSandboxOptions, M as ModalProviderOptions, f as ModalSandboxOptions, S as Sandbox, g as SandboxDescriptor, h as SandboxListOptions, i as SandboxOptions, j as SandboxOptionsBase, k as SandboxOptionsMap, l as SandboxProviderName, m as SandboxRaw, n as SandboxRawMap, o as SandboxResourceSpec, T as TarballEntry, V as VercelGitSource, p as VercelProviderOptions, q as VercelSandboxOptions } from './Sandbox-DcKAU-E3.js';
4
4
  export { SandboxAdapter, buildGitCloneCommand } from './sandboxes/index.js';
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  parseHarnessCommandInvocation,
16
16
  resolveHarnessCommand,
17
17
  skillDirective
18
- } from "./chunk-PFGHRDL4.js";
18
+ } from "./chunk-ZITMGTVR.js";
19
19
  import {
20
20
  ProviderLogAssembler,
21
21
  createNormalizedEvent,
@@ -665,6 +665,8 @@ interface CodexProviderOptions {
665
665
  /** Network access for an explicit host workspace-write policy; defaults to false. */
666
666
  networkAccess?: boolean;
667
667
  binary?: string;
668
+ /** Global CLI arguments placed before the subcommand, e.g. `["-c", "key=value"]`. */
669
+ args?: string[];
668
670
  env?: Record<string, string>;
669
671
  brokerEndpoint?: string;
670
672
  useBroker?: boolean;
@@ -751,6 +753,7 @@ interface ClaudeCodeProviderOptions {
751
753
  /** Request fast mode explicitly; false overrides inherited fast settings. */
752
754
  fastMode?: boolean;
753
755
  binary?: string;
756
+ /** CLI flags as `--name` or `--name=value`; other entries are ignored. */
754
757
  args?: string[];
755
758
  hooks?: ClaudeCodeHooksConfig;
756
759
  permissionMode?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbox-sdk",
3
- "version": "0.1.523",
3
+ "version": "0.1.601",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -63,6 +63,7 @@
63
63
  "@daytonaio/sdk": "^0.171.0",
64
64
  "@types/debug": "^4.1.13",
65
65
  "@vercel/sandbox": "2.0.0-beta.13",
66
+ "cross-spawn": "^7.0.6",
66
67
  "debug": "^4.4.3",
67
68
  "dockerode": "^4.0.10",
68
69
  "e2b": "^2.19.0",
@@ -74,6 +75,7 @@
74
75
  },
75
76
  "devDependencies": {
76
77
  "@eslint/js": "^10.0.1",
78
+ "@types/cross-spawn": "^6.0.6",
77
79
  "@types/dockerode": "^3.3.42",
78
80
  "@types/node": "^25.5.2",
79
81
  "@types/tar-stream": "^3.1.4",