codex-toolkit 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -5
- package/bin/codex-toolkit.js +13 -1
- package/package.json +1 -1
- package/src/installer.js +27 -4
- package/src/scope-guard.js +19 -1
package/README.md
CHANGED
|
@@ -69,10 +69,22 @@ Both points emit a JSON decision `{ "decision": "allow" | "ask" | "deny", "reaso
|
|
|
69
69
|
## Install
|
|
70
70
|
|
|
71
71
|
```sh
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
# 1. Pull the package (no global install needed):
|
|
73
|
+
npx codex-toolkit@latest init
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
That one command copies every bundled hook into `~/.codex/hooks/`, writes `~/.codex/hooks.json` registering them with Codex CLI, and appends a `[hooks]` section to `~/.codex/config.toml` (only if you don't already have one).
|
|
77
|
+
|
|
78
|
+
Verify:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
npx codex-toolkit@latest list # see what is installed
|
|
82
|
+
npx codex-toolkit@latest doctor # run sanity checks + smoke test
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If you'd rather install from source (e.g. to hack on a hook), clone the repo and run the same `init` command directly:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
76
88
|
git clone https://github.com/fox328230966-alt/codex-toolkit.git
|
|
77
89
|
cd codex-toolkit
|
|
78
90
|
node bin/codex-toolkit.js init
|
|
@@ -254,7 +266,7 @@ no extra deps). CI runs the suite on Node 18, 20, and 22.
|
|
|
254
266
|
- [x] `shield-destructive-cmd` — v0.3.0
|
|
255
267
|
- [x] `shield-env-guard` — v0.3.0
|
|
256
268
|
- [x] `auto-lint` — v0.4.0
|
|
257
|
-
- [
|
|
269
|
+
- [x] `npx codex-toolkit init` published to npm — v0.4.0
|
|
258
270
|
- [ ] Per-hook "explain why" debug output — v0.5.0
|
|
259
271
|
- [ ] Codex IDE extension parity — v0.6.0
|
|
260
272
|
|
package/bin/codex-toolkit.js
CHANGED
|
@@ -2,5 +2,17 @@
|
|
|
2
2
|
// codex-toolkit — main CLI shim. Forwards to src/installer.js#main.
|
|
3
3
|
// This file is the `bin` entry; the real implementation lives in src/ so
|
|
4
4
|
// it can be unit-tested without spawning a subprocess.
|
|
5
|
+
//
|
|
6
|
+
// We can't rely on a top-level "am I the entry point?" check inside
|
|
7
|
+
// src/installer.js: when this bin is invoked through `npx codex-toolkit …`,
|
|
8
|
+
// `process.argv[1]` points at the npx launcher, not at this file, so a
|
|
9
|
+
// argv-based check would (and did) silently skip the main() call. Instead
|
|
10
|
+
// we explicitly invoke the entry function from here.
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
(async () => {
|
|
13
|
+
const mod = await import('../src/installer.js');
|
|
14
|
+
mod.main();
|
|
15
|
+
})().catch((err) => {
|
|
16
|
+
process.stderr.write(`[codex-toolkit] fatal: ${err.stack || err.message}\n`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
package/package.json
CHANGED
package/src/installer.js
CHANGED
|
@@ -83,6 +83,19 @@ function copyHook(file) {
|
|
|
83
83
|
const dst = path.join(HOOKS_INSTALLED, file);
|
|
84
84
|
fs.copyFileSync(src, dst);
|
|
85
85
|
fs.chmodSync(dst, 0o755);
|
|
86
|
+
// Also copy the shared support modules so the installed hook can
|
|
87
|
+
// resolve its relative `import './hook-protocol.js'` etc. The hooks
|
|
88
|
+
// run from ~/.codex/hooks/ as a fresh subprocess, so they need their
|
|
89
|
+
// deps next to them — they cannot import from src/ inside the npm
|
|
90
|
+
// package because that path varies by install location.
|
|
91
|
+
for (const dep of ['hook-protocol.js', 'state-store.js']) {
|
|
92
|
+
const depSrc = path.join(HOOKS_DIR, dep);
|
|
93
|
+
const depDst = path.join(HOOKS_INSTALLED, dep);
|
|
94
|
+
if (fs.existsSync(depSrc)) {
|
|
95
|
+
fs.copyFileSync(depSrc, depDst);
|
|
96
|
+
fs.chmodSync(depDst, 0o644);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
86
99
|
return dst;
|
|
87
100
|
}
|
|
88
101
|
|
|
@@ -323,9 +336,19 @@ function main() {
|
|
|
323
336
|
}
|
|
324
337
|
}
|
|
325
338
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
339
|
+
// Export main so bin/codex-toolkit.js can invoke it explicitly. (The
|
|
340
|
+
// previous top-level "am I the entry point?" check was unreliable: when
|
|
341
|
+
// invoked through `npx codex-toolkit …`, process.argv[1] points at the
|
|
342
|
+
// npx launcher, not at this file, so the check silently returned false
|
|
343
|
+
// and the CLI produced no output.)
|
|
344
|
+
export { main };
|
|
345
|
+
|
|
346
|
+
// Fallback for direct invocation: `node src/installer.js` (used in unit
|
|
347
|
+
// tests and local debugging). When loaded via the bin, the IIFE in
|
|
348
|
+
// bin/codex-toolkit.js handles the call — and we must NOT also fire here,
|
|
349
|
+
// otherwise every command runs twice.
|
|
350
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
351
|
+
const entryPoint = process.argv[1] ? path.resolve(process.argv[1]) : null;
|
|
352
|
+
if (entryPoint && entryPoint === __filename) {
|
|
330
353
|
main();
|
|
331
354
|
}
|
package/src/scope-guard.js
CHANGED
|
@@ -33,8 +33,26 @@ import {
|
|
|
33
33
|
|
|
34
34
|
const DEFAULT_CONFIG = {
|
|
35
35
|
mode: 'enforce',
|
|
36
|
+
// Default allow: everything except the deny list. Users override this
|
|
37
|
+
// with their own scope-guard.json when they want a tighter scope.
|
|
36
38
|
allow: ['**/*'],
|
|
37
|
-
deny:
|
|
39
|
+
// Default deny: paths that almost never should be AI-edited, even when
|
|
40
|
+
// the user has not configured anything. v0.1.0–v0.4.1 had `deny: []`,
|
|
41
|
+
// which meant "default mode: enforce" was a no-op for users who never
|
|
42
|
+
// wrote a config. The P1 bug found in v0.4.1 dogfooding was that the
|
|
43
|
+
// installed hook also broke (couldn't find its deps), so users
|
|
44
|
+
// installed + doctor reported green even though real Codex sessions
|
|
45
|
+
// would never fire the guard. This default deny list means a brand
|
|
46
|
+
// new install now refuses the most common dangerous writes out of
|
|
47
|
+
// the box, which matches the README's "default mode: enforce" claim.
|
|
48
|
+
deny: [
|
|
49
|
+
'.env',
|
|
50
|
+
'.env.*',
|
|
51
|
+
'**/.env',
|
|
52
|
+
'**/.env.*',
|
|
53
|
+
'**/secrets/**',
|
|
54
|
+
'**/.git/**',
|
|
55
|
+
],
|
|
38
56
|
log: true,
|
|
39
57
|
};
|
|
40
58
|
|