Skip to content

Commit ed35531

Browse files
author
Codex
committed
Fix Codex home handling for services
1 parent 8ca68d0 commit ed35531

2 files changed

Lines changed: 42 additions & 14 deletions

File tree

src/codex-catalog.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,12 @@ export function restoreCodexCatalog(): { removed: number; kept: number; path: st
328328
}
329329

330330
/**
331-
* Delete Codex's models cache (~/.codex/models_cache.json) so the next turn re-fetches /v1/models.
331+
* Delete Codex's models cache ($CODEX_HOME/models_cache.json) so the next turn re-fetches /v1/models.
332332
* Codex caches the model list for 5 min (DEFAULT_MODEL_CACHE_TTL); invalidating makes catalog edits
333333
* (enable/disable, subagent reorder) apply on the next turn instead of waiting for the TTL.
334334
*/
335335
export function invalidateCodexModelsCache(): void {
336336
try {
337-
const p = join(homedir(), ".codex", "models_cache.json");
338-
if (existsSync(p)) unlinkSync(p);
337+
if (existsSync(CODEX_MODELS_CACHE_PATH)) unlinkSync(CODEX_MODELS_CACHE_PATH);
339338
} catch { /* best-effort */ }
340339
}

src/service.ts

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,59 @@ function logPath(): string {
2828
return join(getConfigDir(), "service.log");
2929
}
3030

31+
function plistString(value: string): string {
32+
return value
33+
.replace(/&/g, "&")
34+
.replace(/</g, "&lt;")
35+
.replace(/>/g, "&gt;")
36+
.replace(/"/g, "&quot;")
37+
.replace(/'/g, "&apos;");
38+
}
39+
3140
export function buildPlist(): string {
3241
const { bun, cli } = cliEntry();
3342
const log = logPath();
3443
const path = process.env.PATH ?? "/usr/local/bin:/usr/bin:/bin";
44+
const codexHome = process.env.CODEX_HOME?.trim();
45+
const codexHomeXml = codexHome ? ` <key>CODEX_HOME</key><string>${plistString(codexHome)}</string>` : "";
3546
return `<?xml version="1.0" encoding="UTF-8"?>
3647
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3748
<plist version="1.0">
3849
<dict>
3950
<key>Label</key><string>${LABEL}</string>
4051
<key>ProgramArguments</key>
4152
<array>
42-
<string>${bun}</string>
43-
<string>${cli}</string>
53+
<string>${plistString(bun)}</string>
54+
<string>${plistString(cli)}</string>
4455
<string>start</string>
4556
</array>
4657
<key>RunAtLoad</key><true/>
4758
<key>KeepAlive</key><true/>
4859
<key>EnvironmentVariables</key>
4960
<dict>
5061
<key>OCX_SERVICE</key><string>1</string>
51-
<key>PATH</key><string>${path}</string>
52-
</dict>
53-
<key>StandardOutPath</key><string>${log}</string>
54-
<key>StandardErrorPath</key><string>${log}</string>
62+
<key>PATH</key><string>${plistString(path)}</string>
63+
${codexHomeXml ? `${codexHomeXml}\n` : ""} </dict>
64+
<key>StandardOutPath</key><string>${plistString(log)}</string>
65+
<key>StandardErrorPath</key><string>${plistString(log)}</string>
5566
</dict>
5667
</plist>
5768
`;
5869
}
5970

71+
function systemdQuote(value: string): string {
72+
return `"${value
73+
.replace(/\\/g, "\\\\")
74+
.replace(/"/g, "\\\"")
75+
.replace(/%/g, "%%")
76+
.replace(/\n/g, "\\n")}"`;
77+
}
78+
79+
function systemdEnvironmentAssignment(name: string, value: string | undefined): string | null {
80+
if (!value) return null;
81+
return `Environment=${systemdQuote(`${name}=${value}`)}`;
82+
}
83+
6084
function sh(cmd: string): string {
6185
return execSync(cmd, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
6286
}
@@ -104,20 +128,25 @@ export function buildUnit(): string {
104128
const { bun, cli } = cliEntry();
105129
const log = logPath();
106130
const path = process.env.PATH ?? "/usr/local/bin:/usr/bin:/bin";
131+
const codexHome = systemdEnvironmentAssignment("CODEX_HOME", process.env.CODEX_HOME?.trim());
132+
const envLines = [
133+
systemdEnvironmentAssignment("OCX_SERVICE", "1"),
134+
systemdEnvironmentAssignment("PATH", path),
135+
codexHome,
136+
].filter((line): line is string => Boolean(line)).join("\n");
107137
return `[Unit]
108138
Description=OpenCodex Proxy Server
109139
After=network-online.target
110140
Wants=network-online.target
111141
112142
[Service]
113143
Type=simple
114-
ExecStart=${bun} ${cli} start
144+
ExecStart=${systemdQuote(bun)} ${systemdQuote(cli)} start
115145
Restart=on-failure
116146
RestartSec=5
117-
Environment=OCX_SERVICE=1
118-
Environment=PATH=${path}
119-
StandardOutput=append:${log}
120-
StandardError=append:${log}
147+
${envLines}
148+
StandardOutput=${systemdQuote(`append:${log}`)}
149+
StandardError=${systemdQuote(`append:${log}`)}
121150
122151
[Install]
123152
WantedBy=default.target

0 commit comments

Comments
 (0)