fix(codex): escape-aware closing-quote scan, honest symlink coverage
readTomlMeta's trailing-comment stripper found the first quote character regardless of escaping, so a description containing \"escaped quotes\" before a real comment got silently truncated instead of dropped. The scan now skips a quote preceded by a backslash. The "never walks outside" containment test passed by construction (row.file is always built off a fixed root) and would not fail if the isUnder guard were removed. Replaced it with two tests that actually pin the regression risk: a skill dir and an agent .toml symlinked in from outside CODEX_HOME, asserting the row is discovered and its content read through the link. isUnder stays as a defensive check (matches cc-discovery.js), now commented as such.
This commit is contained in:
@@ -93,6 +93,11 @@ describe("codex-discovery", () => {
|
||||
assert.equal(meta.description, "uses # for headings");
|
||||
});
|
||||
|
||||
it("does not let an escaped quote before a real trailing comment truncate the value", () => {
|
||||
const meta = cx.readTomlMeta('description = "say \\"hi\\"" # not a comment\n');
|
||||
assert.equal(meta.description, 'say \\"hi\\"');
|
||||
});
|
||||
|
||||
it("reads a rule file's preview", () => {
|
||||
write(
|
||||
path.join(TMP, "rules", "no-force-push.rules"),
|
||||
@@ -127,19 +132,33 @@ describe("codex-discovery", () => {
|
||||
assert.equal(project.exists, false);
|
||||
});
|
||||
|
||||
it("follows a symlinked skill dir (a supported install pattern) without ever reporting a path outside the codex roots", () => {
|
||||
it("follows a skill directory symlinked in from outside CODEX_HOME — a supported install pattern", () => {
|
||||
const outside = fs.mkdtempSync(path.join(os.tmpdir(), "codex-disc-outside-"));
|
||||
write(path.join(outside, "SKILL.md"), "---\nname: linked\n---\nbody");
|
||||
fs.symlinkSync(outside, path.join(TMP, "skills", "linked"), "dir");
|
||||
const linkPath = path.join(TMP, "skills", "linked");
|
||||
fs.symlinkSync(outside, linkPath, "dir");
|
||||
|
||||
const rows = cx.readSkills({ cwd: REPO });
|
||||
const linked = rows.find((r) => r.name === "linked");
|
||||
assert.ok(linked, "a symlinked skill directory must still be discovered");
|
||||
assert.equal(linked.frontmatter.name, "linked");
|
||||
for (const row of rows) {
|
||||
assert.ok(row.file.startsWith(TMP) || row.file.startsWith(REPO));
|
||||
assert.ok(!row.file.startsWith(outside));
|
||||
}
|
||||
const [linked] = cx.readSkills({ cwd: REPO, scope: "user" });
|
||||
assert.equal(linked.scope, "user");
|
||||
assert.equal(linked.name, "linked");
|
||||
assert.equal(linked.frontmatter.name, "linked", "frontmatter must be read through the link");
|
||||
assert.equal(linked.file, path.join(linkPath, "SKILL.md"));
|
||||
fs.rmSync(outside, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("follows an agent .toml symlinked in from outside CODEX_HOME", () => {
|
||||
const outside = fs.mkdtempSync(path.join(os.tmpdir(), "codex-disc-outside-"));
|
||||
const realFile = path.join(outside, "reviewer.toml");
|
||||
write(realFile, 'name = "reviewer"\n');
|
||||
const linkPath = path.join(TMP, "agents", "reviewer.toml");
|
||||
fs.mkdirSync(path.dirname(linkPath), { recursive: true });
|
||||
fs.symlinkSync(realFile, linkPath, "file");
|
||||
|
||||
const [agent] = cx.readAgents({ cwd: REPO, scope: "user" });
|
||||
assert.equal(agent.scope, "user");
|
||||
assert.equal(agent.name, "reviewer");
|
||||
assert.equal(agent.meta.name, "reviewer", "meta must be read through the link");
|
||||
assert.equal(agent.file, linkPath);
|
||||
fs.rmSync(outside, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user