* test(#4667): add failing-first coverage for the codex @-include rewrite Behavioral end-to-end: a real in-process install(true,'codex') into a temp CODEX_HOME must leave zero @~/.claude includes in GSD-owned .md artifacts, rewrite the issue's own example include to @~/.codex/, keep the deliberate _GSD_RUNTIME_ROOT .claude fallback chains byte-identical, and stay idempotent across a reinstall (no doubled prefix). All four are RED until the installer grows the manifest-scoped rewrite pass. * fix(#4667): rewrite codex @ includes to the codex install root Codex-installed agents and commands kept @~/.claude/gsd-core/... (and @/Users/trekkie/.claude/gsd-core/...) include references pointing into the Claude install: silent wrong-copy reads on dual-runtime machines at divergent versions, missing files on codex-only ones. Several emitters bypass the per-runtime converters, so the per-emitter fixes since #570 rotted. Adds a manifest-scoped rewrite pass in install() beside the leak scanner: for codex, every manifest-tracked .md/.toml artifact has the @-include forms rewritten to the codex root. The pass matches the exact include literal only — the _GSD_RUNTIME_ROOT/$PREFERRED_CONFIG_DIR fallback chains, prose .claude mentions, and CHANGELOG.md are untouched — and runs before the scanner, which remains the verification backstop for anything a future emitter introduces. * test(#4667): cover the HOME-anchored include form and sync the pass comment Adds behavioral coverage for the second rewrite literal (@$HOME/.claude/gsd-core/ -> @$HOME/.codex/gsd-core/) via the plan-review-convergence command, and corrects the pass's comment: the agent .tomls are generated after it and prefix themselves, so the .toml branch of the rewrite is inert by design. * test(#4667): baseline the offline upgrade against the deployed tree (sanctioned) * chore(#4667): backfill changeset PR number (4858) * test(#4667): sandbox the install home in the include-rewrite tests (#3712 guard) * test(#4667): install via subprocess with an isolated env in the include-rewrite tests --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -12354,6 +12354,42 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
||||
manifestFiles = null;
|
||||
}
|
||||
if (manifestFiles !== null) {
|
||||
// #4667: codex-installed artifacts must not keep `@~/.claude/gsd-core/…`
|
||||
// include references — the `@` form resolves into the CLAUDE install
|
||||
// (wrong copy on dual-runtime machines at divergent versions, nothing at
|
||||
// all on codex-only ones; #570 cause 2 residue). Every target ships in
|
||||
// the codex install, so rewriting the `@~/` include form to the codex
|
||||
// root is mechanical and correct. This runs after all .md emitters
|
||||
// (several bypass the per-runtime converters — that is how the leak
|
||||
// survived the per-emitter fixes; the agent .tomls are generated later
|
||||
// and prefix themselves), and before the scan below, which stays as the
|
||||
// verification backstop. The `_GSD_RUNTIME_ROOT`/`$PREFERRED_CONFIG_DIR`
|
||||
// fallback chains and prose `.claude` mentions carry no `@~/` prefix and
|
||||
// are deliberately untouched, as is CHANGELOG.md.
|
||||
if (runtime === 'codex') {
|
||||
for (const relPath of manifestFiles) {
|
||||
const fileName = path.basename(relPath);
|
||||
if (!(fileName.endsWith('.md') || fileName.endsWith('.toml'))) continue;
|
||||
if (fileName === 'CHANGELOG.md') continue;
|
||||
const rewritePath = path.join(targetDir, relPath);
|
||||
let rewriteContent;
|
||||
try {
|
||||
rewriteContent = fs.readFileSync(rewritePath, 'utf8');
|
||||
} catch (rewriteErr) {
|
||||
continue; // inaccessible or missing — the scan below reports or skips it
|
||||
}
|
||||
const rewritten = rewriteContent
|
||||
.split('@~/.claude/gsd-core/').join('@~/.codex/gsd-core/')
|
||||
.split('@$HOME/.claude/gsd-core/').join('@$HOME/.codex/gsd-core/');
|
||||
if (rewritten !== rewriteContent) {
|
||||
try {
|
||||
fs.writeFileSync(rewritePath, rewritten);
|
||||
} catch (writeErr) {
|
||||
continue; // never fail the install over the rewrite; the scan still warns
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const relPath of manifestFiles) {
|
||||
const fileName = path.basename(relPath);
|
||||
if (!(fileName.endsWith('.md') || fileName.endsWith('.toml'))) continue;
|
||||
|
||||
Reference in New Issue
Block a user