lvwerra HF Staff Claude Fable 5 commited on
Commit
a5a7b57
·
1 Parent(s): b60e122

Seed autonomous defaults for Codex and Claude Code on the Space

Browse files

Both 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>

Files changed (1) hide show
  1. server/src/index.js +42 -0
server/src/index.js CHANGED
@@ -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