Files
codex/prs/bolinfest/study/PR-2237-study.md
2025-09-02 15:17:45 -07:00

122 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**DOs**
- **Keep Prettier Coverage For JS**: ensure `codex-cli` JavaScript stays formatted in CI.
```json
// package.json
{
"scripts": {
"format": "prettier --check *.json *.md .github/workflows/*.yml **/*.js",
"format:fix": "prettier --write *.json *.md .github/workflows/*.yml **/*.js"
},
"devDependencies": {
"prettier": "^3.5.3"
}
}
```
- **Use A Safe Dynamic Import Helper**: return `null` on failure; dont throw here.
```js
async function tryImport(moduleName) {
try {
return await import(moduleName);
} catch {
return null;
}
}
```
- **Name Functions For What They Return**: `resolveRgDir()` returns a directory, not a file path. Also, avoid double catches—check for `null`.
```js
import path from "node:path";
async function resolveRgDir() {
const mod = await tryImport("@vscode/ripgrep");
if (!mod?.rgPath) return null;
return path.dirname(mod.rgPath);
}
```
- **Prepend To PATH With Correct Separator**: prefer `process.env.PATH` only; make new dirs take precedence.
```js
function getUpdatedPath(newDirs) {
const sep = process.platform === "win32" ? ";" : ":";
const existing = process.env.PATH || "";
return [...newDirs, ...existing.split(sep).filter(Boolean)].join(sep);
}
```
- **Degrade Gracefully If ripgrep Missing**: only add the rg dir when available; still run the CLI.
```js
const extraDirs = [];
const rgDir = await resolveRgDir();
if (rgDir) extraDirs.push(rgDir);
const updatedPath = getUpdatedPath(extraDirs);
```
- **Pass Updated PATH Only To The Child**: dont mutate global env; include `CODEX_MANAGED_BY_NPM`.
```js
const child = spawn(binaryPath, process.argv.slice(2), {
stdio: "inherit",
env: { ...process.env, PATH: updatedPath, CODEX_MANAGED_BY_NPM: "1" }
});
```
- **Validate Against Node 20**: if module type is ambiguous, avoid toplevel `await`; wrap in an async entry point.
```js
(async function main() {
const { spawn } = await import("node:child_process");
// ...rest of startup logic...
})().catch((err) => {
console.error("codex failed:", err);
process.exit(1);
});
```
**DONTs**
- **Dont Treat Env Vars As CaseSensitive On Windows**: skip `process.env.Path`.
```js
// ❌ Dont
const existingPath = process.env.PATH || process.env.Path || "";
```
- **Dont Throw When ripgrep Isnt Installed**: it may be missing due to `--ignore-scripts` or network issues.
```js
// ❌ Dont
if (!mod?.rgPath) {
throw new Error("ripgrep not found");
}
```
- **Dont DoubleCatch And Hide Logic Errors**: rely on `tryImport()` and test for `null`.
```js
// ❌ Dont
async function resolveRgDir() {
try {
const { rgPath } = await import("@vscode/ripgrep");
return path.dirname(rgPath);
} catch (err) {
console.error("unable to import ripgrep", err);
return null;
}
}
```
- **Dont Append New Dirs To The End Of PATH**: rg should win precedence.
```js
// ❌ Dont
const updatedPath = `${process.env.PATH}${sep}${newDirs.join(sep)}`;
```
- **Dont Spam Errors For Optional Deps**: missing ripgrep isnt fatal; keep logs minimal.
```js
// ❌ Dont
console.error("rg missing; aborting startup");
// ✅ Prefer silent skip or a lownoise debug log
```
- **Dont Rely On TopLevel Await In CJS**: it may break under the Node 20 minimum if the file isnt ESM.
```js
// ❌ Dont (in CommonJS)
const { spawn } = await import("node:child_process");
```