-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcodexAgentHome.ts
More file actions
60 lines (54 loc) · 2.51 KB
/
Copy pathcodexAgentHome.ts
File metadata and controls
60 lines (54 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* @file codexAgentHome.ts
* @description Per-agent CODEX_HOME provisioning.
*
* Each Codex agent gets its own `~/.codex-agents/{agentId}/` directory that
* contains AGENTS.md (from the agent description) and optionally a config.toml
* copied from the shared CODEX_HOME. The directory is created once at agent
* registration and reused on every task run.
*/
import fs from 'fs';
import path from 'path';
import { CTRLNODE_ROOT } from './config.js';
import { logger } from './logger.js';
/**
* Returns the per-agent CODEX_HOME path: {CTRLNODE_ROOT}/.codex-agents/{agentId}/
*/
export function getCodexAgentHome(agentId: string): string {
return path.join(CTRLNODE_ROOT, '.codex-agents', agentId);
}
/**
* Provisions the per-agent CODEX_HOME directory with AGENTS.md and optionally
* config.toml (copied from the shared CODEX_HOME if set). Called once when the
* agent is registered via sync_codex_agents — not on every task execution.
*/
export function setupCodexAgentHome(agentId: string, agentDescription: string): void {
try {
const agentHome = getCodexAgentHome(agentId);
fs.mkdirSync(agentHome, { recursive: true });
fs.writeFileSync(path.join(agentHome, 'AGENTS.md'), agentDescription, 'utf8');
// Copy shared config.toml when available (e.g. openrouter provider config).
const sharedConfig = process.env.CODEX_HOME ? path.join(process.env.CODEX_HOME, 'config.toml') : null;
if (sharedConfig && fs.existsSync(sharedConfig)) {
fs.copyFileSync(sharedConfig, path.join(agentHome, 'config.toml'));
}
// Ensure the ctrlnode root workspace is trusted so Codex CLI permits workspace-write sandbox.
// Also set [windows] sandbox = "unelevated" — without it Codex ignores --sandbox workspace-write
// and falls back to read-only on Windows machines that aren't running as admin.
const configPath = path.join(agentHome, 'config.toml');
if (fs.existsSync(configPath)) {
const existing = fs.readFileSync(configPath, 'utf8');
let extra = '';
if (!existing.toLowerCase().includes(CTRLNODE_ROOT.toLowerCase())) {
extra += `\n[projects.'${CTRLNODE_ROOT}']\ntrust_level = "trusted"\n`;
}
if (!existing.toLowerCase().includes('[windows]')) {
extra += `\n[windows]\nsandbox = "unelevated"\n`;
}
if (extra) fs.appendFileSync(configPath, extra, 'utf8');
}
logger.debug('codex_agent_home.provisioned', { agentId, path: agentHome });
} catch (e) {
logger.warn('codex_agent_home.provision_failed', { agentId, err: String(e) });
}
}