@rosthq/cli 0.7.48 → 0.7.50

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/dist/index.js CHANGED
@@ -52647,6 +52647,7 @@ function subpath(value) {
52647
52647
  function literal2(value) {
52648
52648
  return `(literal ${sbplString(value)})`;
52649
52649
  }
52650
+ var CLAUDE_TEMP_SBPL_REGEX = '(regex #"^/private/tmp/claude-[^/]+")';
52650
52651
  var STRICT_SYSTEM_READ_SUBPATHS = [
52651
52652
  "/usr",
52652
52653
  "/bin",
@@ -52693,7 +52694,7 @@ function buildSeatbeltProfile(input) {
52693
52694
  if (denyReadBaseSubpaths.length > 0) {
52694
52695
  lines.push(`(deny file-read* ${denyReadBaseSubpaths.join(" ")})`);
52695
52696
  }
52696
- const workspaceReads = [subpath(input.workspaceDir), ...input.allowWritePaths.map(subpath)];
52697
+ const workspaceReads = [subpath(input.workspaceDir), ...input.allowWritePaths.map(subpath), CLAUDE_TEMP_SBPL_REGEX];
52697
52698
  lines.push(`(allow file-read* ${workspaceReads.join(" ")})`);
52698
52699
  lines.push("(deny file-write*)");
52699
52700
  const allowWrites = [
@@ -52702,6 +52703,8 @@ function buildSeatbeltProfile(input) {
52702
52703
  subpath(`${home}/.claude`),
52703
52704
  subpath(`${home}/.codex`),
52704
52705
  ...input.allowWritePaths.map(subpath),
52706
+ CLAUDE_TEMP_SBPL_REGEX,
52707
+ // DER-1398: Claude Code's per-session + per-command temp dirs.
52705
52708
  subpath("/dev/fd"),
52706
52709
  literal2("/dev/null"),
52707
52710
  literal2("/dev/stdout"),
@@ -52747,9 +52750,6 @@ function isSandboxExecAvailable() {
52747
52750
  return false;
52748
52751
  }
52749
52752
  }
52750
- function claudeBashTempRoot(uid) {
52751
- return `/private/tmp/claude-${uid}`;
52752
- }
52753
52753
  function resolveSandboxSpec(options) {
52754
52754
  if (options.mode === "off") {
52755
52755
  return { kind: "none", reason: "RUNNER_SANDBOX=off (loosened fallback - OS confinement disabled)" };
@@ -52772,11 +52772,7 @@ function resolveSandboxSpec(options) {
52772
52772
  const denyWritePaths = (options.denyWritePaths ?? []).map(
52773
52773
  (p) => p.endsWith("/") ? `${canonical(p.replace(/\/+$/, ""))}/` : canonicalFile(p)
52774
52774
  );
52775
- const uid = typeof process.getuid === "function" ? process.getuid() : null;
52776
- const allowWritePaths = [
52777
- ...(options.allowWritePaths ?? []).map(canonical),
52778
- ...uid !== null ? [canonicalFile(claudeBashTempRoot(uid))] : []
52779
- ];
52775
+ const allowWritePaths = (options.allowWritePaths ?? []).map(canonical);
52780
52776
  const profile = buildSeatbeltProfile({
52781
52777
  workspaceDir,
52782
52778
  tmpDir,
@@ -53459,7 +53455,7 @@ function resolveTurnPlan(input) {
53459
53455
  };
53460
53456
  }
53461
53457
  function buildTurnCommand(input) {
53462
- const { runtime, prompt, configPath, plan, resumeSessionId } = input;
53458
+ const { runtime, prompt, configPath, plan, resumeSessionId, disableClaudeBashSandbox } = input;
53463
53459
  if (runtime === "codex") {
53464
53460
  return {
53465
53461
  command: "codex",
@@ -53488,6 +53484,9 @@ function buildTurnCommand(input) {
53488
53484
  plan.claudeAllowedTools.join(","),
53489
53485
  "--output-format",
53490
53486
  plan.outputFormat,
53487
+ // DER-1397: turn off Claude Code's own nested Bash sandbox when the outer seatbelt confines
53488
+ // us — the JSON is passed inline (no secret; sandbox-exec reads its profile from a file).
53489
+ ...disableClaudeBashSandbox ? ["--settings", '{"sandbox":{"enabled":false}}'] : [],
53491
53490
  ...plan.repoDir !== null ? ["--add-dir", plan.repoDir] : [],
53492
53491
  ...resumeSessionId ? ["--resume", resumeSessionId] : []
53493
53492
  ]
@@ -53728,7 +53727,15 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
53728
53727
  `, { mode: 384 });
53729
53728
  await chmod2(configPath, 384);
53730
53729
  const resumeSessionId = runtime === "claude" ? getClaudeResumeSessionId(ctx.state, workOrder) : void 0;
53731
- const built = buildTurnCommand({ runtime, prompt, configPath, plan, resumeSessionId });
53730
+ const built = buildTurnCommand({
53731
+ runtime,
53732
+ prompt,
53733
+ configPath,
53734
+ plan,
53735
+ resumeSessionId,
53736
+ // DER-1397: outer seatbelt active ⇒ disable claude's nested bash sandbox (bash runs in the repo cwd).
53737
+ disableClaudeBashSandbox: sandbox.kind === "seatbelt"
53738
+ });
53732
53739
  let sandboxProfilePath = null;
53733
53740
  if (sandbox.kind === "seatbelt") {
53734
53741
  sandboxProfilePath = path5.join(
@@ -53935,7 +53942,14 @@ async function spawnMergeConflictModel(ctx, input) {
53935
53942
  await writeFile3(sandboxProfilePath, input.sandbox.profile, { mode: 384 });
53936
53943
  await chmod2(sandboxProfilePath, 384);
53937
53944
  }
53938
- const built = buildTurnCommand({ runtime: input.runtime, prompt, configPath, plan });
53945
+ const built = buildTurnCommand({
53946
+ runtime: input.runtime,
53947
+ prompt,
53948
+ configPath,
53949
+ plan,
53950
+ // DER-1397: outer seatbelt active ⇒ disable claude's nested bash sandbox (bash runs in the repo cwd).
53951
+ disableClaudeBashSandbox: input.sandbox.kind === "seatbelt"
53952
+ });
53939
53953
  const { command, args } = wrapCommandWithSandbox(input.sandbox, built.command, built.args, sandboxProfilePath);
53940
53954
  const spawnStartedAt = (/* @__PURE__ */ new Date()).toISOString();
53941
53955
  const result = await runModelProcess({