agentbox-sdk 0.1.323 → 0.1.400

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,5 +1,5 @@
1
- import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a3 as RawAgentEvent, b as AgentAttachRequest, y as AttachedRun, aa as SetupLayout } from '../types-t01PuLUJ.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, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as OpenRouterPlugin, a5 as RepoSkillConfig, ac as TextPart, ag as UserContent, ah as UserContentPart } from '../types-t01PuLUJ.js';
1
+ import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a3 as RawAgentEvent, b as AgentAttachRequest, y as AttachedRun, aa as SetupLayout } from '../types-vOsvzkcO.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, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as OpenRouterPlugin, a5 as RepoSkillConfig, ac as TextPart, ag as UserContent, ah as UserContentPart } from '../types-vOsvzkcO.js';
3
3
  import { S as Sandbox } from '../Sandbox-DcKAU-E3.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -2,7 +2,7 @@ import {
2
2
  Agent,
3
3
  agentboxRoot,
4
4
  getAgentLayout
5
- } from "../chunk-XONT46YC.js";
5
+ } from "../chunk-KFMFNBVC.js";
6
6
  import "../chunk-775FIGGL.js";
7
7
  import {
8
8
  AGENT_RESERVED_PORTS,
@@ -583,6 +583,9 @@ function buildClaudeHookSettings(hooks) {
583
583
  }
584
584
  return { hooks };
585
585
  }
586
+ function buildClaudeWorkflowSettings(ultracode) {
587
+ return ultracode ? { enableWorkflows: true, ultracode: true } : {};
588
+ }
586
589
  function buildCodexHooksFile(hooks) {
587
590
  if (!hasHookEntries(hooks)) {
588
591
  return void 0;
@@ -1228,13 +1231,14 @@ async function preflightSetup(target, setupId, daemon) {
1228
1231
  ];
1229
1232
  if (daemon) {
1230
1233
  const url = `http://127.0.0.1:${daemon.port}${daemon.healthPath}`;
1234
+ const auth = daemon.curlAuthArg ? `${daemon.curlAuthArg} ` : "";
1231
1235
  if (daemon.expectedVersionMatch) {
1232
1236
  checks.push(
1233
- `curl -fsS --max-time 2 ${shellQuote(url)} 2>/dev/null | grep -q ${shellQuote(daemon.expectedVersionMatch)}`
1237
+ `curl -fsS --max-time 2 ${auth}${shellQuote(url)} 2>/dev/null | grep -q ${shellQuote(daemon.expectedVersionMatch)}`
1234
1238
  );
1235
1239
  } else {
1236
1240
  checks.push(
1237
- `curl -fsS --max-time 2 ${shellQuote(url)} >/dev/null 2>&1`
1241
+ `curl -fsS --max-time 2 ${auth}${shellQuote(url)} >/dev/null 2>&1`
1238
1242
  );
1239
1243
  }
1240
1244
  }
@@ -1513,6 +1517,46 @@ function buildCodexSubagentArtifacts(subAgents, layout) {
1513
1517
  };
1514
1518
  }
1515
1519
 
1520
+ // src/agents/config/capability-token.ts
1521
+ import crypto from "crypto";
1522
+ var tokenCache = /* @__PURE__ */ new WeakMap();
1523
+ async function readCapabilityTokenFile(sandbox, tokenFilePath) {
1524
+ const result = await sandbox.run(
1525
+ `if [ -f ${shellQuote(tokenFilePath)} ]; then cat ${shellQuote(tokenFilePath)}; fi`
1526
+ );
1527
+ if (result.exitCode !== 0) return void 0;
1528
+ const value = result.stdout.trim();
1529
+ return value.length > 0 ? value : void 0;
1530
+ }
1531
+ function resolveCapabilityToken(sandbox, tokenFilePath, create) {
1532
+ let byPath = tokenCache.get(sandbox);
1533
+ if (!byPath) {
1534
+ byPath = /* @__PURE__ */ new Map();
1535
+ tokenCache.set(sandbox, byPath);
1536
+ }
1537
+ const map = byPath;
1538
+ let cached = map.get(tokenFilePath);
1539
+ if (!cached) {
1540
+ const pending = (async () => {
1541
+ const existing = await readCapabilityTokenFile(sandbox, tokenFilePath);
1542
+ if (existing) return existing;
1543
+ if (create) return crypto.randomBytes(32).toString("hex");
1544
+ throw new Error(
1545
+ `Capability token file is missing at ${tokenFilePath}. setup() must run before connecting to this sandbox server.`
1546
+ );
1547
+ })().catch((error) => {
1548
+ map.delete(tokenFilePath);
1549
+ throw error;
1550
+ });
1551
+ map.set(tokenFilePath, pending);
1552
+ cached = pending;
1553
+ }
1554
+ return cached;
1555
+ }
1556
+ function withBearerToken(base, token) {
1557
+ return { ...base, Authorization: `Bearer ${token}` };
1558
+ }
1559
+
1516
1560
  // src/agents/cost.ts
1517
1561
  function addIfNumber(target, key, value) {
1518
1562
  if (typeof value !== "number" || !Number.isFinite(value)) {
@@ -1643,11 +1687,12 @@ function extractOpenCodeCostData(events) {
1643
1687
  }
1644
1688
 
1645
1689
  // src/agents/providers/claude-code.ts
1646
- var DAEMON_PROTOCOL_VERSION = "2";
1690
+ var DAEMON_PROTOCOL_VERSION = "3";
1647
1691
  var DAEMON_PORT = 43180;
1648
1692
  var DAEMON_PATH = "/tmp/agentbox/claude-code/daemon.mjs";
1649
1693
  var DAEMON_LOG_PATH = "/tmp/agentbox/claude-code/daemon.log";
1650
1694
  var DAEMON_PID_PATH = "/tmp/agentbox/claude-code/daemon.pid";
1695
+ var DAEMON_TOKEN_PATH = "/tmp/agentbox/claude-code/daemon-token";
1651
1696
  var DAEMON_READY_TIMEOUT_MS = 3e4;
1652
1697
  var DAEMON_READY_POLL_INTERVAL_MS = 250;
1653
1698
  function claudeConfigDir(options) {
@@ -1672,6 +1717,7 @@ function buildClaudeQueryOptions(params) {
1672
1717
  extraArgs["append-system-prompt"] = run.systemPrompt;
1673
1718
  }
1674
1719
  const includeHookEvents = provider?.includeHookEvents ?? false;
1720
+ const effort = provider?.ultracode ? "xhigh" : run.reasoning;
1675
1721
  return {
1676
1722
  cwd: params.cwd ?? params.request.options.cwd,
1677
1723
  env: params.env,
@@ -1684,7 +1730,7 @@ function buildClaudeQueryOptions(params) {
1684
1730
  thinking: { type: "adaptive", display: "summarized" },
1685
1731
  ...provider?.additionalDirectories?.length ? { additionalDirectories: provider.additionalDirectories } : {},
1686
1732
  ...run.model ? { model: run.model } : {},
1687
- ...run.reasoning ? { effort: run.reasoning } : {},
1733
+ ...effort ? { effort } : {},
1688
1734
  ...provider?.permissionMode ? { permissionMode: provider.permissionMode } : {},
1689
1735
  ...provider?.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
1690
1736
  ...provider?.allowedTools?.length ? { allowedTools: provider.allowedTools } : {},
@@ -1741,11 +1787,30 @@ function createClaudeCodeDaemonScript() {
1741
1787
  const version = JSON.stringify(DAEMON_PROTOCOL_VERSION);
1742
1788
  return `import http from "node:http";
1743
1789
  import { execSync } from "node:child_process";
1744
- import { existsSync } from "node:fs";
1790
+ import { existsSync, readFileSync } from "node:fs";
1791
+ import { timingSafeEqual } from "node:crypto";
1745
1792
  import { query, getSessionInfo } from "@anthropic-ai/claude-agent-sdk";
1746
1793
 
1747
1794
  const VERSION = ${version};
1748
1795
  const port = Number(process.argv[2] ?? "${DAEMON_PORT}");
1796
+ // Capability token: every route except the loopback /__version probe
1797
+ // requires \`Authorization: Bearer <token>\`. Loaded once at boot from the
1798
+ // 0600 file the host writes alongside this script. Fails closed (rejects
1799
+ // all run-control requests) when the file is missing or empty.
1800
+ const tokenFilePath = process.argv[3] ?? "";
1801
+ let AUTH_TOKEN = "";
1802
+ try { if (tokenFilePath) AUTH_TOKEN = readFileSync(tokenFilePath, "utf8").trim(); } catch {}
1803
+
1804
+ function isAuthorized(req) {
1805
+ if (!AUTH_TOKEN) return false;
1806
+ const header = req.headers["authorization"] || "";
1807
+ const presented = header.startsWith("Bearer ") ? header.slice(7) : "";
1808
+ if (!presented) return false;
1809
+ const a = Buffer.from(presented);
1810
+ const b = Buffer.from(AUTH_TOKEN);
1811
+ return a.length === b.length && timingSafeEqual(a, b);
1812
+ }
1813
+
1749
1814
  const liveRuns = new Map();
1750
1815
 
1751
1816
  // The SDK's default spawn does \`existsSync(pathToClaudeCodeExecutable)\`
@@ -1982,6 +2047,14 @@ const server = http.createServer((req, res) => {
1982
2047
  res.end(VERSION);
1983
2048
  return;
1984
2049
  }
2050
+ // Capability-token gate for every run-control route. The /__version probe
2051
+ // above stays open: it carries no secret and the host probes it over
2052
+ // loopback (no bearer) to detect daemon liveness/version.
2053
+ if (!isAuthorized(req)) {
2054
+ res.writeHead(401, { "content-type": "text/plain" });
2055
+ res.end("unauthorized");
2056
+ return;
2057
+ }
1985
2058
  const url = req.url ?? "";
1986
2059
  let m;
1987
2060
  if (req.method === "POST" && (m = url.match(/^\\/runs\\/([^/]+)\\/start$/))) {
@@ -2052,6 +2125,11 @@ async function ensureClaudeCodeDaemonUncached(options, env) {
2052
2125
  );
2053
2126
  return;
2054
2127
  }
2128
+ const daemonToken = await resolveCapabilityToken(
2129
+ sandbox,
2130
+ DAEMON_TOKEN_PATH,
2131
+ true
2132
+ );
2055
2133
  const daemonDir = path8.posix.dirname(DAEMON_PATH);
2056
2134
  const daemonNodeModules = `${daemonDir}/node_modules/@anthropic-ai`;
2057
2135
  const launchCommand = [
@@ -2059,13 +2137,18 @@ async function ensureClaudeCodeDaemonUncached(options, env) {
2059
2137
  `if [ -z "$NPM_ROOT" ] || [ ! -d "$NPM_ROOT/@anthropic-ai/claude-agent-sdk" ]; then echo "claude-code daemon launch: @anthropic-ai/claude-agent-sdk not found under $NPM_ROOT" >&2; exit 1; fi`,
2060
2138
  `mkdir -p ${shellQuote(daemonNodeModules)}`,
2061
2139
  `ln -sfn "$NPM_ROOT/@anthropic-ai/claude-agent-sdk" ${shellQuote(daemonNodeModules + "/claude-agent-sdk")}`,
2140
+ // The base uploadAndRun only chmods execute-bit artifacts, so the 0600
2141
+ // tarball mode is dropped on Daytona (and other non-Modal providers).
2142
+ // Tighten the just-written token file explicitly — matching codex —
2143
+ // so the bearer is never group/world-readable inside the sandbox.
2144
+ `chmod 600 ${shellQuote(DAEMON_TOKEN_PATH)}`,
2062
2145
  `if [ -f ${shellQuote(DAEMON_PID_PATH)} ]; then kill -TERM "$(cat ${shellQuote(DAEMON_PID_PATH)})" 2>/dev/null || true; fi`,
2063
2146
  `(fuser -k -n tcp ${DAEMON_PORT} 2>/dev/null || true)`,
2064
2147
  // Brief grace so the kernel releases the port before the new
2065
2148
  // daemon's listen() — only matters on warm-sandbox respawns;
2066
2149
  // adds 200ms otherwise.
2067
2150
  `sleep 0.2`,
2068
- `(nohup node ${shellQuote(DAEMON_PATH)} ${DAEMON_PORT} > ${shellQuote(DAEMON_LOG_PATH)} 2>&1 & echo $! > ${shellQuote(DAEMON_PID_PATH)})`
2151
+ `(nohup node ${shellQuote(DAEMON_PATH)} ${DAEMON_PORT} ${shellQuote(DAEMON_TOKEN_PATH)} > ${shellQuote(DAEMON_LOG_PATH)} 2>&1 & echo $! > ${shellQuote(DAEMON_PID_PATH)})`
2069
2152
  ].join(" && ");
2070
2153
  const launch = await time(
2071
2154
  debugRelay,
@@ -2076,6 +2159,11 @@ async function ensureClaudeCodeDaemonUncached(options, env) {
2076
2159
  path: DAEMON_PATH,
2077
2160
  content: createClaudeCodeDaemonScript(),
2078
2161
  mode: 420
2162
+ },
2163
+ {
2164
+ path: DAEMON_TOKEN_PATH,
2165
+ content: daemonToken,
2166
+ mode: 384
2079
2167
  }
2080
2168
  ],
2081
2169
  launchCommand,
@@ -2171,6 +2259,10 @@ async function daemonBaseUrl(sandbox) {
2171
2259
  const url = await sandbox.getPreviewLink(DAEMON_PORT);
2172
2260
  return url.replace(/\/$/, "");
2173
2261
  }
2262
+ async function daemonAuthHeaders(sandbox) {
2263
+ const token = await resolveCapabilityToken(sandbox, DAEMON_TOKEN_PATH, false);
2264
+ return withBearerToken(sandbox.previewHeaders, token);
2265
+ }
2174
2266
  var ClaudeCodeAgentAdapter = class {
2175
2267
  /**
2176
2268
  * Sandbox-side preparation. Uploads `.claude/` artifacts and ensures
@@ -2223,12 +2315,19 @@ var ClaudeCodeAgentAdapter = class {
2223
2315
  () => prepareSkillArtifacts(provider, options.skills, target.layout)
2224
2316
  );
2225
2317
  const hookSettings = buildClaudeHookSettings(hooks) ?? {};
2318
+ const workflowSettings = buildClaudeWorkflowSettings(
2319
+ options.provider?.ultracode
2320
+ );
2321
+ const claudeSettings = { ...hookSettings, ...workflowSettings };
2226
2322
  const mcpConfigJson = buildClaudeMcpConfig(options.mcps) ?? JSON.stringify({ mcpServers: {} }, null, 2);
2227
2323
  const artifacts = [
2228
2324
  ...skillArtifacts,
2229
2325
  ...buildClaudeCommandArtifacts(options.commands, target.layout),
2230
2326
  ...buildClaudeSubagentArtifacts(options.subAgents, target.layout),
2231
- { path: settingsPath, content: JSON.stringify(hookSettings, null, 2) },
2327
+ {
2328
+ path: settingsPath,
2329
+ content: JSON.stringify(claudeSettings, null, 2)
2330
+ },
2232
2331
  { path: mcpConfigPath, content: mcpConfigJson }
2233
2332
  ];
2234
2333
  const enableRtk = options.enableRtk === true;
@@ -2297,6 +2396,7 @@ var ClaudeCodeAgentAdapter = class {
2297
2396
  "getPreviewLink daemon",
2298
2397
  () => daemonBaseUrl(sandbox)
2299
2398
  );
2399
+ const authHeaders = await daemonAuthHeaders(sandbox);
2300
2400
  const startUrl = `${baseUrl}/runs/${encodeURIComponent(request.runId)}/start`;
2301
2401
  const sdkOptions = buildClaudeQueryOptions({
2302
2402
  request,
@@ -2328,7 +2428,7 @@ var ClaudeCodeAgentAdapter = class {
2328
2428
  try {
2329
2429
  await fetch(
2330
2430
  `${baseUrl}/runs/${encodeURIComponent(request.runId)}/abort`,
2331
- { method: "POST", headers: sandbox.previewHeaders }
2431
+ { method: "POST", headers: authHeaders }
2332
2432
  );
2333
2433
  } catch {
2334
2434
  }
@@ -2345,7 +2445,7 @@ var ClaudeCodeAgentAdapter = class {
2345
2445
  method: "POST",
2346
2446
  headers: {
2347
2447
  "content-type": "application/json",
2348
- ...sandbox.previewHeaders
2448
+ ...authHeaders
2349
2449
  },
2350
2450
  body: JSON.stringify({ content: mapped })
2351
2451
  }
@@ -2360,7 +2460,7 @@ var ClaudeCodeAgentAdapter = class {
2360
2460
  signal: fetchAbort.signal,
2361
2461
  headers: {
2362
2462
  "content-type": "application/json",
2363
- ...sandbox.previewHeaders
2463
+ ...authHeaders
2364
2464
  },
2365
2465
  body: JSON.stringify(requestBody)
2366
2466
  })
@@ -2588,6 +2688,7 @@ var ClaudeCodeAgentAdapter = class {
2588
2688
  */
2589
2689
  async attachAbort(request) {
2590
2690
  const baseUrl = await daemonBaseUrl(request.sandbox);
2691
+ const authHeaders = await daemonAuthHeaders(request.sandbox);
2591
2692
  const controller = new AbortController();
2592
2693
  const timeout = setTimeout(() => controller.abort(), 3e3);
2593
2694
  try {
@@ -2596,7 +2697,7 @@ var ClaudeCodeAgentAdapter = class {
2596
2697
  {
2597
2698
  method: "POST",
2598
2699
  signal: controller.signal,
2599
- headers: request.sandbox.previewHeaders
2700
+ headers: authHeaders
2600
2701
  }
2601
2702
  ).catch((error) => {
2602
2703
  debugClaude("attachAbort POST failed: %o", error);
@@ -2613,6 +2714,7 @@ var ClaudeCodeAgentAdapter = class {
2613
2714
  */
2614
2715
  async attachSendMessage(request, content) {
2615
2716
  const baseUrl = await daemonBaseUrl(request.sandbox);
2717
+ const authHeaders = await daemonAuthHeaders(request.sandbox);
2616
2718
  const inputParts = await validateProviderUserInput(
2617
2719
  AgentProvider.ClaudeCode,
2618
2720
  content
@@ -2624,7 +2726,7 @@ var ClaudeCodeAgentAdapter = class {
2624
2726
  method: "POST",
2625
2727
  headers: {
2626
2728
  "content-type": "application/json",
2627
- ...request.sandbox.previewHeaders
2729
+ ...authHeaders
2628
2730
  },
2629
2731
  body: JSON.stringify({ content: mapped })
2630
2732
  }
@@ -2638,7 +2740,7 @@ var ClaudeCodeAgentAdapter = class {
2638
2740
  };
2639
2741
 
2640
2742
  // src/agents/providers/codex.ts
2641
- import crypto from "crypto";
2743
+ import crypto2 from "crypto";
2642
2744
  import path9 from "path";
2643
2745
 
2644
2746
  // src/agents/transports/app-server.ts
@@ -2895,7 +2997,7 @@ function resolveCodexAppServerToken(sandbox, tokenFilePath, create) {
2895
2997
  return existing;
2896
2998
  }
2897
2999
  if (create) {
2898
- return crypto.randomBytes(32).toString("hex");
3000
+ return crypto2.randomBytes(32).toString("hex");
2899
3001
  }
2900
3002
  throw new Error(
2901
3003
  `Codex app-server token file is missing at ${tokenFilePath}. setup() must run before connecting to the codex app-server.`
@@ -3967,6 +4069,37 @@ var LOCAL_OPENCODE_PORT = 4096;
3967
4069
  var SANDBOX_OPENCODE_READY_TIMEOUT_MS = 9e4;
3968
4070
  var LOCAL_OPENCODE_READY_TIMEOUT_MS = 2e4;
3969
4071
  var SHARED_OPENCODE_TARGET_ID = "shared-opencode-server";
4072
+ var OPENCODE_AUTH_USERNAME = "opencode";
4073
+ function opencodeServerTokenPath() {
4074
+ return path10.posix.join(
4075
+ agentboxRoot(AgentProvider.OpenCode, true),
4076
+ "opencode-auth-token"
4077
+ );
4078
+ }
4079
+ function opencodeCurlAuthArg() {
4080
+ return `-u "opencode:$(cat ${shellQuote(opencodeServerTokenPath())} 2>/dev/null)"`;
4081
+ }
4082
+ function opencodeHealthCurl(port) {
4083
+ return `curl -fsS --max-time 2 ${opencodeCurlAuthArg()} http://127.0.0.1:${port}/global/health >/dev/null 2>&1`;
4084
+ }
4085
+ async function isSandboxOpenCodeServerAuthEnforced(sandbox, cwd, port) {
4086
+ const probe = await sandbox.run(
4087
+ `test "$(curl -s -o /dev/null -w '%{http_code}' --max-time 2 http://127.0.0.1:${port}/global/health)" = "401"`,
4088
+ { cwd, timeoutMs: 5e3 }
4089
+ ).catch(() => void 0);
4090
+ return probe?.exitCode === 0;
4091
+ }
4092
+ async function opencodeAuthHeaders(sandbox) {
4093
+ const token = await resolveCapabilityToken(
4094
+ sandbox,
4095
+ opencodeServerTokenPath(),
4096
+ false
4097
+ );
4098
+ const basic = Buffer.from(`${OPENCODE_AUTH_USERNAME}:${token}`).toString(
4099
+ "base64"
4100
+ );
4101
+ return { ...sandbox.previewHeaders, Authorization: `Basic ${basic}` };
4102
+ }
3970
4103
  var LLM_API_KEY_ENV_VARS = [
3971
4104
  "OPENROUTER_API_KEY",
3972
4105
  "OPENAI_API_KEY",
@@ -4017,10 +4150,10 @@ async function killSandboxOpenCodeServer(sandbox, pidFilePath, cwd, port) {
4017
4150
  ).catch(() => void 0);
4018
4151
  const deadline = Date.now() + 5e3;
4019
4152
  while (Date.now() < deadline) {
4020
- const probe = await sandbox.run(
4021
- `curl -fsS --max-time 2 http://127.0.0.1:${port}/global/health >/dev/null 2>&1`,
4022
- { cwd, timeoutMs: 5e3 }
4023
- );
4153
+ const probe = await sandbox.run(opencodeHealthCurl(port), {
4154
+ cwd,
4155
+ timeoutMs: 5e3
4156
+ });
4024
4157
  if (probe.exitCode !== 0) {
4025
4158
  return;
4026
4159
  }
@@ -4160,6 +4293,12 @@ async function ensureSandboxOpenCodeServer(request) {
4160
4293
  SHARED_OPENCODE_TARGET_ID,
4161
4294
  options
4162
4295
  );
4296
+ const serverTokenPath = opencodeServerTokenPath();
4297
+ const serverToken = await resolveCapabilityToken(
4298
+ sandbox,
4299
+ serverTokenPath,
4300
+ true
4301
+ );
4163
4302
  const { artifacts: skillArtifacts, installCommands } = await prepareSkillArtifacts(
4164
4303
  request.provider,
4165
4304
  options.skills,
@@ -4177,10 +4316,18 @@ async function ensureSandboxOpenCodeServer(request) {
4177
4316
  {
4178
4317
  path: configPath,
4179
4318
  content: JSON.stringify(openCodeConfig, null, 2)
4319
+ },
4320
+ {
4321
+ path: serverTokenPath,
4322
+ content: serverToken
4180
4323
  }
4181
4324
  ];
4182
4325
  const enableRtk = options.enableRtk === true;
4183
- const daemonInfo = { port, healthPath: "/global/health" };
4326
+ const daemonInfo = {
4327
+ port,
4328
+ healthPath: "/global/health",
4329
+ curlAuthArg: opencodeCurlAuthArg()
4330
+ };
4184
4331
  const setupId = computeSetupId({
4185
4332
  artifacts: allArtifacts,
4186
4333
  installCommands,
@@ -4195,10 +4342,15 @@ async function ensureSandboxOpenCodeServer(request) {
4195
4342
  return;
4196
4343
  }
4197
4344
  if (await isSandboxOpenCodeServerHealthy(sandbox, options.cwd, port)) {
4345
+ if (await isSandboxOpenCodeServerAuthEnforced(sandbox, options.cwd, port)) {
4346
+ debugOpencode(
4347
+ "opencode server already running but setup drifted \u2014 reusing it without restart; call agent.killServer() to apply the new config"
4348
+ );
4349
+ return;
4350
+ }
4198
4351
  debugOpencode(
4199
- "opencode server already running but setup drifted \u2014 reusing it without restart; call agent.killServer() to apply the new config"
4352
+ "opencode server running without capability auth \u2014 restarting to enforce it"
4200
4353
  );
4201
- return;
4202
4354
  }
4203
4355
  const commonEnv = {
4204
4356
  OPENCODE_CONFIG: configPath,
@@ -4218,9 +4370,18 @@ async function ensureSandboxOpenCodeServer(request) {
4218
4370
  target.layout.rootDir,
4219
4371
  "opencode-serve.log"
4220
4372
  );
4221
- const serveEnv = { ...options.env ?? {}, ...commonEnv };
4373
+ const serveEnv = {
4374
+ ...options.env ?? {},
4375
+ ...commonEnv,
4376
+ // Native opencode HTTP basic auth. The host presents this token on
4377
+ // every request (see opencodeAuthHeaders); the in-sandbox health probes
4378
+ // present it too (see opencodeHealthCurl).
4379
+ OPENCODE_SERVER_USERNAME: OPENCODE_AUTH_USERNAME,
4380
+ OPENCODE_SERVER_PASSWORD: serverToken
4381
+ };
4222
4382
  const launchCommand = [
4223
4383
  `mkdir -p ${shellQuote(target.layout.rootDir)}`,
4384
+ `chmod 600 ${shellQuote(serverTokenPath)} 2>/dev/null || true`,
4224
4385
  `(${[
4225
4386
  `setsid nohup ${[
4226
4387
  binary,
@@ -4263,10 +4424,10 @@ async function ensureSandboxOpenCodeServer(request) {
4263
4424
  );
4264
4425
  }
4265
4426
  while (Date.now() < readyDeadline) {
4266
- const probe = await sandbox.run(
4267
- `curl -fsS http://127.0.0.1:${port}/global/health >/dev/null 2>&1`,
4268
- { cwd: options.cwd, timeoutMs: 5e3 }
4269
- );
4427
+ const probe = await sandbox.run(opencodeHealthCurl(port), {
4428
+ cwd: options.cwd,
4429
+ timeoutMs: 5e3
4430
+ });
4270
4431
  if (probe.exitCode === 0) {
4271
4432
  debugOpencode("ready on attempt %d", attempt);
4272
4433
  return true;
@@ -4308,6 +4469,18 @@ opencode log:
4308
4469
  ${lastLog}` : "")
4309
4470
  );
4310
4471
  }
4472
+ if (!await isSandboxOpenCodeServerAuthEnforced(sandbox, options.cwd, port)) {
4473
+ await killSandboxOpenCodeServer(
4474
+ sandbox,
4475
+ pidFilePath,
4476
+ options.cwd,
4477
+ port
4478
+ ).catch(() => void 0);
4479
+ await target.cleanup().catch(() => void 0);
4480
+ throw new Error(
4481
+ "OpenCode server started but is not enforcing the capability token (OPENCODE_SERVER_PASSWORD ignored). Upgrade opencode-ai to a version that supports server authentication."
4482
+ );
4483
+ }
4311
4484
  await markSetupComplete(target, setupId);
4312
4485
  });
4313
4486
  }
@@ -4399,10 +4572,7 @@ async function setupOpenCode(request) {
4399
4572
  await ensureLocalOpenCodeServer(request);
4400
4573
  }
4401
4574
  async function isSandboxOpenCodeServerHealthy(sandbox, cwd, port) {
4402
- const probe = await sandbox.run(
4403
- `curl -fsS --max-time 2 http://127.0.0.1:${port}/global/health >/dev/null 2>&1`,
4404
- { cwd, timeoutMs: 5e3 }
4405
- ).catch(() => void 0);
4575
+ const probe = await sandbox.run(opencodeHealthCurl(port), { cwd, timeoutMs: 5e3 }).catch(() => void 0);
4406
4576
  return probe?.exitCode === 0;
4407
4577
  }
4408
4578
  async function isLocalOpenCodeServerHealthy() {
@@ -4443,7 +4613,7 @@ async function buildOpenCodeRuntime(options) {
4443
4613
  const baseUrl2 = (await sandbox.getPreviewLink(SANDBOX_OPENCODE_PORT)).replace(/\/$/, "");
4444
4614
  return {
4445
4615
  baseUrl: baseUrl2,
4446
- previewHeaders: sandbox.previewHeaders,
4616
+ previewHeaders: await opencodeAuthHeaders(sandbox),
4447
4617
  raw: { baseUrl: baseUrl2, port: SANDBOX_OPENCODE_PORT }
4448
4618
  };
4449
4619
  }
@@ -4977,6 +5147,7 @@ var OpenCodeAgentAdapter = class {
4977
5147
  );
4978
5148
  }
4979
5149
  const baseUrl = (await request.sandbox.getPreviewLink(SANDBOX_OPENCODE_PORT)).replace(/\/$/, "");
5150
+ const authHeaders = await opencodeAuthHeaders(request.sandbox);
4980
5151
  const controller = new AbortController();
4981
5152
  const timeout = setTimeout(() => controller.abort(), 3e3);
4982
5153
  try {
@@ -4985,7 +5156,7 @@ var OpenCodeAgentAdapter = class {
4985
5156
  signal: controller.signal,
4986
5157
  headers: {
4987
5158
  "content-type": "application/json",
4988
- ...request.sandbox.previewHeaders
5159
+ ...authHeaders
4989
5160
  }
4990
5161
  }).catch((error) => {
4991
5162
  debugOpencode(
@@ -5016,12 +5187,13 @@ var OpenCodeAgentAdapter = class {
5016
5187
  content
5017
5188
  );
5018
5189
  const parts = mapToOpenCodeParts(inputParts);
5190
+ const authHeaders = await opencodeAuthHeaders(request.sandbox);
5019
5191
  const url = `${baseUrl}/session/${request.sessionId}/prompt_async`;
5020
5192
  const response = await fetch(url, {
5021
5193
  method: "POST",
5022
5194
  headers: {
5023
5195
  "content-type": "application/json",
5024
- ...request.sandbox.previewHeaders
5196
+ ...authHeaders
5025
5197
  },
5026
5198
  body: JSON.stringify({
5027
5199
  agent: openCodeAgentSlug(void 0),
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, ab as TextDeltaEvent, ad as ToolCallCompletedEvent, ae as ToolCallDeltaEvent, af as ToolCallStartedEvent, ai as createNormalizedEvent, aj as normalizeRawAgentEvent, ak as toAISDKEvent, al as toAISDKStream } from '../types-t01PuLUJ.js';
1
+ export { A as AISDKEvent, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, ab as TextDeltaEvent, ad as ToolCallCompletedEvent, ae as ToolCallDeltaEvent, af as ToolCallStartedEvent, ai as createNormalizedEvent, aj as normalizeRawAgentEvent, ak as toAISDKEvent, al as toAISDKStream } from '../types-vOsvzkcO.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 AttachedRun, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as OpenRouterPlugin, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a5 as RepoSkillConfig, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, aa as SetupLayout, ab as TextDeltaEvent, ac as TextPart, ad as ToolCallCompletedEvent, ae as ToolCallDeltaEvent, af as ToolCallStartedEvent, ag as UserContent, ah as UserContentPart, ai as createNormalizedEvent, aj as normalizeRawAgentEvent, ak as toAISDKEvent, al as toAISDKStream } from './types-t01PuLUJ.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 AttachedRun, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as OpenRouterPlugin, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a5 as RepoSkillConfig, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, aa as SetupLayout, ab as TextDeltaEvent, ac as TextPart, ad as ToolCallCompletedEvent, ae as ToolCallDeltaEvent, af as ToolCallStartedEvent, ag as UserContent, ah as UserContentPart, ai as createNormalizedEvent, aj as normalizeRawAgentEvent, ak as toAISDKEvent, al as toAISDKStream } from './types-vOsvzkcO.js';
2
2
  export { AGENT_RESERVED_PORTS, Agent, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout } 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
@@ -2,7 +2,7 @@ import {
2
2
  Agent,
3
3
  agentboxRoot,
4
4
  getAgentLayout
5
- } from "./chunk-XONT46YC.js";
5
+ } from "./chunk-KFMFNBVC.js";
6
6
  import {
7
7
  ProviderLogAssembler,
8
8
  createNormalizedEvent,
@@ -418,6 +418,18 @@ interface ClaudeCodeProviderOptions {
418
418
  * silence them when hook noise drowns out the rest of the event stream.
419
419
  */
420
420
  includeHookEvents?: boolean;
421
+ /**
422
+ * Enable "ultracode" for claude-code runs: xhigh reasoning effort plus
423
+ * standing dynamic-workflow orchestration (the built-in `Workflow` tool).
424
+ *
425
+ * When `true`, agentbox writes `enableWorkflows: true` + `ultracode: true`
426
+ * into the managed `settings.json` and forces `effort: "xhigh"` on the query.
427
+ *
428
+ * Requires an xhigh-capable model (e.g. Opus) and a recent runtime — the
429
+ * Workflows feature shipped around Claude Code 2.1.154 / Agent SDK 0.3.149.
430
+ * On older CLIs the settings keys are simply ignored.
431
+ */
432
+ ultracode?: boolean;
421
433
  }
422
434
  interface CodexAgentOptions extends AgentOptionsBase {
423
435
  provider?: CodexProviderOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbox-sdk",
3
- "version": "0.1.323",
3
+ "version": "0.1.400",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {