-
Notifications
You must be signed in to change notification settings - Fork 451
fix(windows): follow active Codex home for tray listener #644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
34493b1
89837d8
7cb15bf
74e2747
fe146fe
000ddd0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| import { execFile, execFileSync, spawn } from "node:child_process"; | ||
| import { createHash } from "node:crypto"; | ||
| import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs"; | ||
| import { homedir } from "node:os"; | ||
| import { join, resolve } from "node:path"; | ||
| import { expandUserPath, getConfigDir } from "../config"; | ||
| import { getConfigDir } from "../config"; | ||
| import { durableBunPath } from "../lib/bun-runtime"; | ||
| import { hardenSecretDir, hardenSecretPath } from "../lib/windows-secret-acl"; | ||
| import { resolveCodexHomeDir } from "../codex/home"; | ||
|
|
||
| const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"; | ||
| const RUN_PARENT_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion"; | ||
|
|
@@ -75,8 +75,10 @@ function sourceTrayIconPaths(): string[] { | |
| } | ||
|
|
||
| function currentCodexHome(): string { | ||
| const raw = process.env.CODEX_HOME?.trim(); | ||
| return raw ? resolve(expandUserPath(raw)) : join(homedir(), ".codex"); | ||
| // Keep the tray's listener/launcher target aligned with Codex's active home. | ||
| // This matters on the Windows desktop setup, where CODEX_HOME is E:\\codex | ||
| // instead of the historical %USERPROFILE%\\.codex fallback. | ||
| return resolveCodexHomeDir(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On Windows, AGENTS.md reference: AGENTS.md:L93-L95 Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| function currentEntry(): WindowsTrayEntry { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import { describe, expect, test } from "bun:test"; | ||
| import { fileURLToPath } from "node:url"; | ||
|
|
||
| const repoRoot = fileURLToPath(new URL("../", import.meta.url)); | ||
|
|
||
| /** | ||
| * Local agent/session state must never reach a commit. | ||
| * | ||
| * `.gitignore` alone does not enforce this: `git add -f` overrides it silently, | ||
| * and once a path is tracked the ignore rule stops applying to it entirely. The | ||
| * `.codexclaw/` goalplans and ledgers were committed exactly that way and rode | ||
| * along into `main` and `preview` before anyone noticed. | ||
| * | ||
| * This test closes that gap by asserting against the real index instead of the | ||
| * ignore file, so a forced add fails CI on the commit that introduces it. | ||
| */ | ||
| const FORBIDDEN_TRACKED_DIRS = [".codexclaw", ".omo", ".claude", "node_modules", ".tmp"]; | ||
|
|
||
| const FORBIDDEN_TRACKED_FILENAMES = [".DS_Store", "Thumbs.db"]; | ||
|
|
||
| function trackedFiles(): string[] { | ||
| const result = Bun.spawnSync(["git", "ls-files"], { cwd: repoRoot }); | ||
| if (result.exitCode !== 0) { | ||
| throw new Error(`git ls-files failed: ${new TextDecoder().decode(result.stderr)}`); | ||
| } | ||
| return new TextDecoder() | ||
| .decode(result.stdout) | ||
| .split("\n") | ||
| .map((line) => line.trim()) | ||
| .filter(Boolean); | ||
| } | ||
|
|
||
| describe("repository hygiene", () => { | ||
| test("no local agent or session state is tracked", () => { | ||
| const offenders = trackedFiles().filter((path) => | ||
| path.split("/").some((segment) => FORBIDDEN_TRACKED_DIRS.includes(segment)), | ||
| ); | ||
|
|
||
| expect(offenders).toEqual([]); | ||
| }); | ||
|
|
||
| test("no OS metadata files are tracked", () => { | ||
| const offenders = trackedFiles().filter((path) => | ||
| FORBIDDEN_TRACKED_FILENAMES.includes(path.split("/").pop() ?? ""), | ||
| ); | ||
|
|
||
| expect(offenders).toEqual([]); | ||
| }); | ||
|
|
||
| test("gitignore still declares the agent-state directories", async () => { | ||
| const ignore = await Bun.file(new URL("../.gitignore", import.meta.url)).text(); | ||
|
|
||
| for (const dir of FORBIDDEN_TRACKED_DIRS) { | ||
| expect(ignore).toContain(`${dir}/`); | ||
| } | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add a focused regression test for the active Codex home.
This changes tray behavior from local resolution to
resolveCodexHomeDir(). Add a test covering a trimmedCODEX_HOMEsuch asE:\codexand the fallback path, so a future tray change cannot silently revert to%USERPROFILE%\.codex.🧰 Tools
🪛 ast-grep (0.45.0)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile, execFileSync, spawn } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🤖 Prompt for AI Agents
Source: Path instructions