Skip to content

Commit 0ae6ba9

Browse files
committed
fix: pid mismatch
1 parent 490e7b6 commit 0ae6ba9

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

src/lib/paths.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,21 @@ const APP_DIR = path.join(os.homedir(), ".local", "share", "copilot-api")
66

77
const GITHUB_TOKEN_PATH = path.join(APP_DIR, "github_token")
88
const CLAUDE_CODE_CONFIG_PATH = path.join(APP_DIR, "claude-code.json")
9+
const CODEX_CONFIG_PATH = path.join(APP_DIR, "codex.json")
910
const PID_PATH = path.join(APP_DIR, "server.pid")
1011

1112
export const PATHS = {
1213
APP_DIR,
1314
GITHUB_TOKEN_PATH,
1415
CLAUDE_CODE_CONFIG_PATH,
16+
CODEX_CONFIG_PATH,
1517
PID_PATH,
1618
}
1719

1820
export async function ensurePaths(): Promise<void> {
1921
await fs.mkdir(PATHS.APP_DIR, { recursive: true })
2022
await ensureFile(PATHS.GITHUB_TOKEN_PATH)
23+
await ensureFile(PATHS.CODEX_CONFIG_PATH)
2124
}
2225

2326
async function ensureFile(filePath: string): Promise<void> {

src/start.ts

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,28 @@ async function prepareDaemon(
196196

197197
if (options.codex) {
198198
invariant(state.models, "Models should be loaded by now")
199-
const selectedModel = await consola.prompt(
200-
"Select a model to use with Codex",
201-
{
199+
const storedCodex = await loadCodexConfig()
200+
const hasStored =
201+
storedCodex !== null
202+
&& state.models.data.some((model) => model.id === storedCodex.model)
203+
204+
const envCodexModel =
205+
options.claudeCodeReset ? null : (
206+
(process.env.COPILOT_API_CODEX_MODEL
207+
?? (hasStored ? storedCodex.model : null))
208+
)
209+
210+
const selectedModel =
211+
envCodexModel
212+
?? (await consola.prompt("Select a model to use with Codex", {
202213
type: "select",
203214
options: state.models.data.map((model) => model.id),
204-
},
205-
)
215+
}))
206216

207217
envExtras.COPILOT_API_CODEX_MODEL = selectedModel
218+
if (!hasStored || options.claudeCodeReset) {
219+
await saveCodexConfig({ model: selectedModel })
220+
}
208221

209222
const codexCommand = buildCodexCommand(serverUrl, selectedModel)
210223

@@ -329,8 +342,15 @@ async function handleClaudeCode(options: RunServerOptions, serverUrl: string) {
329342
async function handleCodex(options: RunServerOptions, serverUrl: string) {
330343
invariant(state.models, "Models should be loaded by now")
331344

345+
const stored = await loadCodexConfig()
346+
const hasStored =
347+
stored !== null
348+
&& state.models.data.some((model) => model.id === stored.model)
349+
332350
const envCodexModel =
333-
options.claudeCodeReset ? null : process.env.COPILOT_API_CODEX_MODEL
351+
options.claudeCodeReset ? null : (
352+
(process.env.COPILOT_API_CODEX_MODEL ?? (hasStored ? stored.model : null))
353+
)
334354

335355
const selectedModel =
336356
envCodexModel
@@ -339,6 +359,10 @@ async function handleCodex(options: RunServerOptions, serverUrl: string) {
339359
options: state.models.data.map((model) => model.id),
340360
}))
341361

362+
if (!hasStored || options.claudeCodeReset) {
363+
await saveCodexConfig({ model: selectedModel })
364+
}
365+
342366
const codexCommand = buildCodexCommand(serverUrl, selectedModel)
343367

344368
if (!options.daemon || !envCodexModel) {
@@ -504,9 +528,17 @@ export const start = defineCommand({
504528
env: { ...process.env, COPILOT_API_IS_DAEMON: "1", ...envExtras },
505529
})
506530

507-
await fs.writeFile(PATHS.PID_PATH, String(child.pid))
531+
const childPid = Number(child.pid)
532+
if (!Number.isFinite(childPid)) {
533+
consola.error("Failed to determine daemon pid; not writing pid file.")
534+
process.exit(1)
535+
}
536+
537+
const pidString = `${childPid}`
538+
await fs.writeFile(PATHS.PID_PATH, pidString, "utf8")
539+
508540
consola.info(
509-
`Copilot API server is starting in the background (pid ${child.pid}).`,
541+
`Copilot API server is starting in the background (pid ${childPid}).`,
510542
)
511543
child.unref()
512544
// Ensure parent process exits after spawning daemon
@@ -522,6 +554,10 @@ interface ClaudeCodeConfig {
522554
smallModel: string
523555
}
524556

557+
interface CodexConfig {
558+
model: string
559+
}
560+
525561
const loadClaudeCodeConfig = async (): Promise<ClaudeCodeConfig | null> => {
526562
try {
527563
const content = await fs.readFile(PATHS.CLAUDE_CODE_CONFIG_PATH, "utf8")
@@ -546,3 +582,17 @@ const clearClaudeCodeConfig = async () => {
546582
// ignore
547583
}
548584
}
585+
586+
const loadCodexConfig = async (): Promise<CodexConfig | null> => {
587+
try {
588+
const content = await fs.readFile(PATHS.CODEX_CONFIG_PATH, "utf8")
589+
if (!content) return null
590+
return JSON.parse(content) as CodexConfig
591+
} catch {
592+
return null
593+
}
594+
}
595+
596+
const saveCodexConfig = async (config: CodexConfig) => {
597+
await fs.writeFile(PATHS.CODEX_CONFIG_PATH, JSON.stringify(config, null, 2))
598+
}

0 commit comments

Comments
 (0)