Spaces:
Running
Seed autonomous defaults for Codex and Claude Code on the Space
Browse filesBoth CLIs ship with per-command approval prompts tuned for laptops. On
the Space the private container is itself the sandbox, so the prompts
add friction without adding safety, and Codex's own sandbox can't work
anyway (needs Landlock, unavailable in the container).
On boot, seed what's missing and never touch what the operator set:
Codex gets approval_policy = "never" + sandbox_mode =
"danger-full-access" in $CODEX_HOME/config.toml (missing keys prepended
so they stay ahead of any [section]); Claude Code gets
permissions.defaultMode = "bypassPermissions" in settings.json, i.e.
what shift+tab toggles per conversation, as the standing default.
Gated to Space deployments via the entrypoint-set env vars, same idiom
as the statusline hook.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- server/src/index.js +42 -0
|
@@ -65,6 +65,48 @@ function ensureClaudeStatusline() {
|
|
| 65 |
} catch {}
|
| 66 |
}
|
| 67 |
ensureClaudeStatusline();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
initPush();
|
| 69 |
|
| 70 |
// Wait for the visibility verdict before serving: isPublic() fails closed on a
|
|
|
|
| 65 |
} catch {}
|
| 66 |
}
|
| 67 |
ensureClaudeStatusline();
|
| 68 |
+
|
| 69 |
+
// Seed autonomous defaults so agents don't stop to ask for routine commands:
|
| 70 |
+
// the private Space container is itself the sandbox, so in-CLI permission
|
| 71 |
+
// prompts add friction without adding safety. Gated to Space deployments via
|
| 72 |
+
// the entrypoint-set env vars (same idiom as the statusline hook), and only
|
| 73 |
+
// fills in what the operator hasn't set — existing values are never touched.
|
| 74 |
+
function ensureAutonomyDefaults() {
|
| 75 |
+
// Codex: approval_policy + sandbox_mode in $CODEX_HOME/config.toml. Codex's
|
| 76 |
+
// Linux sandbox needs Landlock, which the Space container doesn't provide,
|
| 77 |
+
// so full access with no approvals is the working configuration. Missing
|
| 78 |
+
// keys are PREPENDED: top-level toml keys must precede any [section].
|
| 79 |
+
try {
|
| 80 |
+
const home = process.env.CODEX_HOME;
|
| 81 |
+
if (home) {
|
| 82 |
+
fs.mkdirSync(home, { recursive: true });
|
| 83 |
+
const p = path.join(home, 'config.toml');
|
| 84 |
+
let txt = '';
|
| 85 |
+
try { txt = fs.readFileSync(p, 'utf8'); } catch {}
|
| 86 |
+
const missing = [];
|
| 87 |
+
if (!/^\s*approval_policy\s*=/m.test(txt)) missing.push('approval_policy = "never"');
|
| 88 |
+
if (!/^\s*sandbox_mode\s*=/m.test(txt)) missing.push('sandbox_mode = "danger-full-access" # the Space container is the sandbox');
|
| 89 |
+
if (missing.length) fs.writeFileSync(p, `${missing.join('\n')}\n${txt}`);
|
| 90 |
+
}
|
| 91 |
+
} catch (e) { console.error('[autonomy codex]', e && e.message); }
|
| 92 |
+
// Claude Code: permissions.defaultMode in settings.json — every session
|
| 93 |
+
// starts in bypassPermissions (what shift+tab toggles per conversation).
|
| 94 |
+
try {
|
| 95 |
+
const cfg = process.env.CLAUDE_CONFIG_DIR;
|
| 96 |
+
if (cfg) {
|
| 97 |
+
fs.mkdirSync(cfg, { recursive: true });
|
| 98 |
+
const p = path.join(cfg, 'settings.json');
|
| 99 |
+
let s = {};
|
| 100 |
+
try { s = JSON.parse(fs.readFileSync(p, 'utf8')); } catch {}
|
| 101 |
+
s.permissions = s.permissions || {};
|
| 102 |
+
if (!s.permissions.defaultMode) {
|
| 103 |
+
s.permissions.defaultMode = 'bypassPermissions';
|
| 104 |
+
fs.writeFileSync(p, JSON.stringify(s, null, 2));
|
| 105 |
+
}
|
| 106 |
+
}
|
| 107 |
+
} catch (e) { console.error('[autonomy claude]', e && e.message); }
|
| 108 |
+
}
|
| 109 |
+
ensureAutonomyDefaults();
|
| 110 |
initPush();
|
| 111 |
|
| 112 |
// Wait for the visibility verdict before serving: isPublic() fails closed on a
|