Re-running the wizard overwrites three hookify files without checking, and
reports every one of them as Created:
$ sed -n '774,778p' packages/setup/index.js
for (const { file, content } of rules) {
const hookPath = path.join('.claude', file);
fs.writeFileSync(hookPath, content);
ok(`Created ${hookPath}`);
}
Three lines earlier, the same function writes .mcp.json and gets this right:
$ sed -n '753p;762p' packages/setup/index.js
const mcpExisted = fs.existsSync(claudeMcpPath);
ok(`${mcpExisted ? 'Updated' : 'Created'} .mcp.json ...`);
Codex's config.toml and AGENTS.md are handled the same careful way further
down: both detect an existing sysknife block and skip rather than clobber.
Why it matters
One of the three files is hookify.require-sysknife-approval.local.md, the
approval gate. An operator who tightens it for a project, then re-runs setup
weeks later to add a second target, silently gets the packaged default back,
logged as Created and therefore indistinguishable from a first install.
The failure is quiet in both directions: nothing warns at the time, and the
log says the opposite of what happened.
Scope
- Check before writing, the way the
.mcp.json line does. At minimum report
Updated rather than Created.
- Decide whether an existing file should be overwritten at all. The Codex
config path chose to skip and warn; say in the PR why you match that or
differ. For a security-relevant hook, leaving a hand-edited file alone and
telling the user is the safer default.
- If you do overwrite, say what changed rather than that a file was written.
Tests first
Write the file with altered contents, run the installer, and assert the
contents survive and the log says so. That fails today.
Then assert the first-install case still reports Created, so the fix does
not trade one wrong label for another.
Difficulty
easy.
Getting started
CONTRIBUTING.md
has the build and test commands. No CLA and no copyright waiver. The project is MIT.
Re-running the wizard overwrites three hookify files without checking, and
reports every one of them as
Created:Three lines earlier, the same function writes
.mcp.jsonand gets this right:Codex's
config.tomlandAGENTS.mdare handled the same careful way furtherdown: both detect an existing sysknife block and skip rather than clobber.
Why it matters
One of the three files is
hookify.require-sysknife-approval.local.md, theapproval gate. An operator who tightens it for a project, then re-runs setup
weeks later to add a second target, silently gets the packaged default back,
logged as
Createdand therefore indistinguishable from a first install.The failure is quiet in both directions: nothing warns at the time, and the
log says the opposite of what happened.
Scope
.mcp.jsonline does. At minimum reportUpdatedrather thanCreated.config path chose to skip and warn; say in the PR why you match that or
differ. For a security-relevant hook, leaving a hand-edited file alone and
telling the user is the safer default.
Tests first
Write the file with altered contents, run the installer, and assert the
contents survive and the log says so. That fails today.
Then assert the first-install case still reports
Created, so the fix doesnot trade one wrong label for another.
Difficulty
easy.Getting started
CONTRIBUTING.md
has the build and test commands. No CLA and no copyright waiver. The project is MIT.