@sagentlab/navarch-runtime 0.1.36 → 0.1.37

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
@@ -361,6 +361,12 @@ as an explicit read-only mount.
361
361
  user or checked-in legacy `sandbox_mode` from silently disabling the
362
362
  generated profile; Codex authentication still comes from `CODEX_HOME`, and
363
363
  repository instructions such as `AGENTS.md` still load.
364
+ On macOS the profile also grants read access to `/Library/Developer` and
365
+ `/Applications` (Xcode and CoreSimulator, which `xcrun simctl` and
366
+ `xcodebuild` load) and write access to `~/Library/Developer` (simulator
367
+ devices and DerivedData); the Claude hook gets the same write root. Without
368
+ these, iOS builds and simulator tests fail under the sandbox with
369
+ `access to /Library/Developer/PrivateFrameworks/CoreSimulator.framework is blocked`.
364
370
  - **Gemini:** the runtime uses Gemini CLI's native sandbox with only the
365
371
  current worktree, shared gitdir, session `gh` config, and approved extra
366
372
  roots mounted. The `gh` config and lease MCP settings are read-only; header
@@ -7,6 +7,7 @@ exports.guardHookScriptPath = guardHookScriptPath;
7
7
  exports.readClaudeApiKeyHelper = readClaudeApiKeyHelper;
8
8
  exports.prepareWorktreeGuard = prepareWorktreeGuard;
9
9
  exports.codexToolReadRoots = codexToolReadRoots;
10
+ exports.macosDeveloperWriteRoots = macosDeveloperWriteRoots;
10
11
  exports.sessionGhConfigDir = sessionGhConfigDir;
11
12
  exports.codexWorktreeGuardArgs = codexWorktreeGuardArgs;
12
13
  exports.geminiSandboxMounts = geminiSandboxMounts;
@@ -74,9 +75,12 @@ async function prepareWorktreeGuard(options) {
74
75
  const hookScriptPath = guardHookScriptPath();
75
76
  const configPath = node_path_1.default.join(options.workDir, "worktree-guard.json");
76
77
  const settingsPath = node_path_1.default.join(options.workDir, "claude-settings.json");
78
+ const workspaceRoot = node_path_1.default.resolve(options.workspaceRoot);
77
79
  const allowedRoots = [
78
80
  options.worktreePath,
79
81
  options.repositoryPath,
82
+ // Xcode's per-user simulator/DerivedData state; see macosDeveloperWriteRoots.
83
+ ...macosDeveloperWriteRoots().filter((root) => !isPathInside(node_path_1.default.resolve(root), workspaceRoot)),
80
84
  ...(options.extraRoots ?? []),
81
85
  ];
82
86
  const deniedRoots = [options.workspaceRoot];
@@ -110,7 +114,7 @@ async function prepareWorktreeGuard(options) {
110
114
  * installations are sufficient for helpers such as apply_patch, npm, gh, and
111
115
  * browser evidence tooling.
112
116
  */
113
- function codexToolReadRoots(env = process.env) {
117
+ function codexToolReadRoots(env = process.env, platform = process.platform) {
114
118
  const homeDir = env.HOME?.trim() || node_os_1.default.homedir();
115
119
  const codexHome = env.CODEX_HOME?.trim() || node_path_1.default.join(homeDir, ".codex");
116
120
  return [
@@ -126,8 +130,31 @@ function codexToolReadRoots(env = process.env) {
126
130
  "/System/Library/CoreServices/SystemAppearance.bundle",
127
131
  node_path_1.default.join(homeDir, "Library", "Caches", "ms-playwright"),
128
132
  node_path_1.default.join(homeDir, ".cache", "ms-playwright"),
133
+ ...(platform === "darwin" ? MACOS_TOOLCHAIN_READ_ROOTS : []),
129
134
  ];
130
135
  }
136
+ /**
137
+ * World-readable macOS toolchain locations. `xcrun simctl` / `xcodebuild`
138
+ * load /Library/Developer/PrivateFrameworks/CoreSimulator.framework and the
139
+ * Xcode bundle itself; without these an iOS build or simulator test dies
140
+ * under Codex's seatbelt with "access to ... is blocked". Both are already
141
+ * system prefixes for the Claude hook (bin/worktree-guard-hook.cjs), so this
142
+ * only brings the Codex profile level with it.
143
+ */
144
+ const MACOS_TOOLCHAIN_READ_ROOTS = ["/Library/Developer", "/Applications"];
145
+ /**
146
+ * Per-user macOS developer state that Xcode writes during a build or test
147
+ * run: simulator devices under `~/Library/Developer/CoreSimulator` and
148
+ * DerivedData under `~/Library/Developer/Xcode`. Shared between sessions on
149
+ * one machine (that is inherent to Xcode), but nothing under it is Navarch
150
+ * session state or credentials. Empty off macOS.
151
+ */
152
+ function macosDeveloperWriteRoots(env = process.env, platform = process.platform) {
153
+ if (platform !== "darwin")
154
+ return [];
155
+ const homeDir = env.HOME?.trim() || node_os_1.default.homedir();
156
+ return [node_path_1.default.join(homeDir, "Library", "Developer")];
157
+ }
131
158
  /**
132
159
  * Isolated gh configuration root for one coding-agent session.
133
160
  *
@@ -169,7 +196,7 @@ function codexWorktreeGuardArgs(options) {
169
196
  continue;
170
197
  filesystem[resolved] = "read";
171
198
  }
172
- for (const root of options.extraRoots ?? []) {
199
+ for (const root of [...macosDeveloperWriteRoots(), ...(options.extraRoots ?? [])]) {
173
200
  const resolved = node_path_1.default.resolve(root);
174
201
  // Match the Claude hook's denied-root precedence: an extra root cannot
175
202
  // reopen sibling sessions or metadata inside the Navarch workspace.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sagentlab/navarch-runtime",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "Navarch machine-side session manager: claims delivery tasks and runs them through Claude Code, Codex, Gemini, or OpenCode.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",