safeword 0.78.2 → 0.78.4
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/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/codex-plugin/hooks.json +5 -5
- package/codex-plugin/skills/bdd/references/SCENARIOS.md +3 -0
- package/codex-plugin/skills/bdd/references/TDD.md +11 -5
- package/codex-plugin/skills/closeout/SKILL.md +24 -16
- package/codex-plugin/skills/finish-review/SKILL.md +4 -3
- package/codex-plugin/skills/lint/SKILL.md +1 -1
- package/codex-plugin/skills/review-spec/SKILL.md +5 -1
- package/codex-plugin/skills/self-review/SKILL.md +2 -2
- package/codex-plugin/skills/ticket-system/SKILL.md +3 -0
- package/dist/{architecture-N5ZC4CDU.js → architecture-TCSDEFKH.js} +9 -9
- package/dist/{architecture-document-UBA5UT4J.js → architecture-document-L2ADWVMV.js} +6 -6
- package/dist/{architecture-monorepo-E4JUYJGV.js → architecture-monorepo-NKOQZBEY.js} +4 -4
- package/dist/{boundary-HLJILY7R.js → boundary-QP2H7C46.js} +6 -6
- package/dist/{chunk-NOTBZCKG.js → chunk-2XR7J5WL.js} +93 -42
- package/dist/chunk-2XR7J5WL.js.map +1 -0
- package/dist/{chunk-4CZS4YJV.js → chunk-3OKZ3X4O.js} +3 -3
- package/dist/{chunk-GZ36UZJG.js → chunk-73TABQRT.js} +10 -10
- package/dist/{chunk-4CKCRZDO.js → chunk-7ULZND56.js} +2 -2
- package/dist/{chunk-34NCOTP5.js → chunk-7XELS325.js} +2 -2
- package/dist/{chunk-USPVNZ63.js → chunk-BZWO3BVD.js} +11 -7
- package/dist/chunk-BZWO3BVD.js.map +1 -0
- package/dist/{chunk-BQTC6YGN.js → chunk-D5ENZR6N.js} +2 -2
- package/dist/{chunk-SME5SU3O.js → chunk-DBXX5K74.js} +258 -48
- package/dist/chunk-DBXX5K74.js.map +1 -0
- package/dist/{chunk-V63TSN3C.js → chunk-FOYGZ4MK.js} +31 -10
- package/dist/chunk-FOYGZ4MK.js.map +1 -0
- package/dist/{chunk-ZRV7TOCX.js → chunk-G5AFQXXW.js} +2 -2
- package/dist/{chunk-AXAGJLMP.js → chunk-G757F3EU.js} +4 -4
- package/dist/{chunk-KXHVFCDT.js → chunk-GFDINP7M.js} +153 -27
- package/dist/chunk-GFDINP7M.js.map +1 -0
- package/dist/{chunk-S2T356DA.js → chunk-HF3DXZEA.js} +7 -10
- package/dist/chunk-HF3DXZEA.js.map +1 -0
- package/dist/{chunk-NSZGI7HK.js → chunk-HNCUIXDY.js} +9 -9
- package/dist/{chunk-NSZGI7HK.js.map → chunk-HNCUIXDY.js.map} +1 -1
- package/dist/{chunk-BSOUMHMQ.js → chunk-IPTM5VE7.js} +101 -1094
- package/dist/chunk-IPTM5VE7.js.map +1 -0
- package/dist/chunk-JBOLNV2L.js +21 -0
- package/dist/chunk-JBOLNV2L.js.map +1 -0
- package/dist/chunk-JSR3HXFT.js +1231 -0
- package/dist/chunk-JSR3HXFT.js.map +1 -0
- package/dist/{chunk-BAVDDAN3.js → chunk-KS2ESRQL.js} +9 -9
- package/dist/chunk-LFC6CMMX.js +136 -0
- package/dist/chunk-LFC6CMMX.js.map +1 -0
- package/dist/{chunk-QTG2EXFT.js → chunk-LUNHU6Z3.js} +2 -2
- package/dist/{chunk-QTG2EXFT.js.map → chunk-LUNHU6Z3.js.map} +1 -1
- package/dist/{chunk-WVDRXD67.js → chunk-MLBZFB5A.js} +1 -1
- package/dist/chunk-MLBZFB5A.js.map +1 -0
- package/dist/{chunk-KFVEPQ7X.js → chunk-MVFHTUQ3.js} +2 -2
- package/dist/{chunk-TJ627SKI.js → chunk-O3GZ77F7.js} +15 -1
- package/dist/chunk-O3GZ77F7.js.map +1 -0
- package/dist/{chunk-Q5KLE6ZF.js → chunk-OKPRQGFG.js} +2 -2
- package/dist/{chunk-QUDIOBHP.js → chunk-PD7ZXRHV.js} +139 -18
- package/dist/chunk-PD7ZXRHV.js.map +1 -0
- package/dist/chunk-QAHJSG53.js +30 -0
- package/dist/chunk-QAHJSG53.js.map +1 -0
- package/dist/{chunk-3SOJBMM6.js → chunk-R6BSRNU4.js} +6 -6
- package/dist/{chunk-3SOJBMM6.js.map → chunk-R6BSRNU4.js.map} +1 -1
- package/dist/{chunk-J7UDLLTK.js → chunk-RQ7RZYNB.js} +39 -25
- package/dist/chunk-RQ7RZYNB.js.map +1 -0
- package/dist/{chunk-664YNAMR.js → chunk-RTFPKJJV.js} +5 -5
- package/dist/{chunk-GKR44BCH.js → chunk-RVDXBHUG.js} +2 -2
- package/dist/chunk-THLEVFEX.js +22 -0
- package/dist/chunk-THLEVFEX.js.map +1 -0
- package/dist/{chunk-A7Z27COA.js → chunk-VFWAZLEF.js} +3 -3
- package/dist/{chunk-I4KBHRZW.js → chunk-VJUPD7JI.js} +7 -7
- package/dist/{chunk-3EJNDIAO.js → chunk-VZ5B2SIO.js} +2 -2
- package/dist/chunk-WAMQTZAH.js +19 -0
- package/dist/chunk-WAMQTZAH.js.map +1 -0
- package/dist/{chunk-FDHJ63FZ.js → chunk-WVA4Q6BX.js} +1 -1
- package/dist/{chunk-FDHJ63FZ.js.map → chunk-WVA4Q6BX.js.map} +1 -1
- package/dist/{chunk-AV5LTEME.js → chunk-YZ5JGDOV.js} +30 -134
- package/dist/chunk-YZ5JGDOV.js.map +1 -0
- package/dist/{cleanup-X556LNWM.js → cleanup-JNLZ7AXA.js} +9 -9
- package/dist/{cleanup-command-RV2Q7G72.js → cleanup-command-MFAYNYRW.js} +15 -15
- package/dist/cli.js +152 -109
- package/dist/cli.js.map +1 -1
- package/dist/{clients-HP23HRN2.js → clients-7AJBKEWF.js} +2 -2
- package/dist/codex-bootstrap-KFNUS63Y.js +252 -0
- package/dist/codex-bootstrap-KFNUS63Y.js.map +1 -0
- package/dist/{codex-hook-IPX3PDXX.js → codex-hook-TNMYVOR7.js} +57 -49
- package/dist/codex-hook-TNMYVOR7.js.map +1 -0
- package/dist/{codify-J5ZLJ3HK.js → codify-RBWBRXQO.js} +11 -8
- package/dist/codify-RBWBRXQO.js.map +1 -0
- package/dist/{commands-L4AINARC.js → commands-4UXHBZFD.js} +127 -71
- package/dist/commands-4UXHBZFD.js.map +1 -0
- package/dist/{config-LUSJAK6B.js → config-GS7BTZJD.js} +2 -2
- package/dist/{configured-paths-SPQ5XWOM.js → configured-paths-CREUDQF3.js} +4 -4
- package/dist/contract-42CIWIWV.js +8 -0
- package/dist/{coordinator-SA75UB3C.js → coordinator-WOPGWDXK.js} +231 -144
- package/dist/coordinator-WOPGWDXK.js.map +1 -0
- package/dist/corpus-CAFYEMBO.js +15 -0
- package/dist/{doctor-DSC36R4U.js → doctor-AZP5D7QP.js} +21 -21
- package/dist/{feature-directories-VOHVV26X.js → feature-directories-6TLM7Y4H.js} +6 -6
- package/dist/{finalization-7SMLMVLV.js → finalization-AQT3SOP7.js} +4 -4
- package/dist/{gh-cli-ZMO7D2KE.js → gh-cli-XCQT5ST7.js} +2 -2
- package/dist/{github-rest-KGKS4V2H.js → github-rest-CXFJ2NFF.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{job-CDADLJDF.js → job-4POTQJZK.js} +20 -21
- package/dist/job-4POTQJZK.js.map +1 -0
- package/dist/{learning-sync-6BTHM6ZC.js → learning-sync-QVXBOP6J.js} +4 -4
- package/dist/{legacy-global-guidance-2JL4Y5EB.js → legacy-global-guidance-CPGUUNJI.js} +5 -5
- package/dist/{lint-gherkin-COSHVS6Z.js → lint-gherkin-LZ45NG4A.js} +7 -7
- package/dist/{operations-XVRQSLJG.js → operations-ODOA5CDG.js} +18 -16
- package/dist/{output-3LB2OEHN.js → output-QTZCFLAY.js} +2 -2
- package/dist/{packet-5WT5M3OS.js → packet-5G6RT2EW.js} +2 -2
- package/dist/presets/typescript/index.js +2 -2
- package/dist/{profile-UMKQ5JVO.js → profile-QGLZNLRU.js} +7 -7
- package/dist/{prompt-GWYDFMLO.js → prompt-UCTSCXSS.js} +2 -2
- package/dist/remove-UQPEXXNP.js +23 -0
- package/dist/{retro-IFSVU5KS.js → retro-ELKR6GHF.js} +8 -8
- package/dist/{retro-draft-spool-4S3TCHWL.js → retro-draft-spool-M75BTT32.js} +2 -2
- package/dist/{retro-extract-OSBFAXLU.js → retro-extract-RA6THOC4.js} +2 -2
- package/dist/{review-pr-6S2352CK.js → review-pr-MN6QESAJ.js} +2 -2
- package/dist/{review-pr-publication-CGHCRRUI.js → review-pr-publication-6AVOGWR2.js} +2 -2
- package/dist/{run-5JESKXUR.js → run-JFDGRAH2.js} +4 -4
- package/dist/{self-report-VPHBPPSJ.js → self-report-5APRPB5P.js} +2 -2
- package/dist/status-ATFG6Q3K.js +21 -0
- package/dist/{status-EX4L3ELO.js → status-HIQSP3F5.js} +21 -21
- package/dist/{sync-config-O7J7IDGE.js → sync-config-XPAJKBRO.js} +5 -5
- package/dist/{sync-tracker-U2GYOFUO.js → sync-tracker-3E5BWX73.js} +6 -6
- package/dist/{test-execution-6LIPMBIH.js → test-execution-VDECX7TO.js} +8 -7
- package/dist/{test-execution-6LIPMBIH.js.map → test-execution-VDECX7TO.js.map} +1 -1
- package/dist/{test-plan-VASHZXJ7.js → test-plan-2L7A7UZV.js} +7 -6
- package/dist/{test-plan-VASHZXJ7.js.map → test-plan-2L7A7UZV.js.map} +1 -1
- package/dist/{ticket-new-3YXDIWPC.js → ticket-new-HZKNZ5GO.js} +11 -11
- package/dist/ticket-new-HZKNZ5GO.js.map +1 -0
- package/dist/{ticket-sync-LLUBXZ2R.js → ticket-sync-4QJD3KOL.js} +5 -5
- package/dist/{tracker-map-HR4MBYG5.js → tracker-map-CFMFIEER.js} +2 -2
- package/dist/{tracker-sync-YDICZN66.js → tracker-sync-MOPJE6M7.js} +2 -2
- package/package.json +1 -1
- package/templates/SAFEWORD.md +2 -2
- package/templates/commands/lint.md +1 -1
- package/templates/scripts/closeout-cleanup.ts +127 -31
- package/templates/skills/bdd/SCENARIOS.md +3 -0
- package/templates/skills/bdd/TDD.md +11 -5
- package/templates/skills/closeout/SKILL.md +25 -17
- package/templates/skills/finish-review/SKILL.md +4 -3
- package/templates/skills/lint/SKILL.md +1 -1
- package/templates/skills/review-spec/SKILL.md +5 -1
- package/templates/skills/self-review/SKILL.md +2 -2
- package/templates/skills/ticket-system/SKILL.md +3 -0
- package/dist/chunk-6S7CTKGC.js +0 -128
- package/dist/chunk-6S7CTKGC.js.map +0 -1
- package/dist/chunk-AV5LTEME.js.map +0 -1
- package/dist/chunk-BSOUMHMQ.js.map +0 -1
- package/dist/chunk-J7UDLLTK.js.map +0 -1
- package/dist/chunk-KXHVFCDT.js.map +0 -1
- package/dist/chunk-NOTBZCKG.js.map +0 -1
- package/dist/chunk-QUDIOBHP.js.map +0 -1
- package/dist/chunk-S2T356DA.js.map +0 -1
- package/dist/chunk-SME5SU3O.js.map +0 -1
- package/dist/chunk-TJ627SKI.js.map +0 -1
- package/dist/chunk-USPVNZ63.js.map +0 -1
- package/dist/chunk-V63TSN3C.js.map +0 -1
- package/dist/chunk-WRUXO3WA.js +0 -48
- package/dist/chunk-WRUXO3WA.js.map +0 -1
- package/dist/chunk-WVDRXD67.js.map +0 -1
- package/dist/codex-bootstrap-MGY2D6HU.js +0 -178
- package/dist/codex-bootstrap-MGY2D6HU.js.map +0 -1
- package/dist/codex-hook-IPX3PDXX.js.map +0 -1
- package/dist/codify-J5ZLJ3HK.js.map +0 -1
- package/dist/commands-L4AINARC.js.map +0 -1
- package/dist/contract-KEZY6YC3.js +0 -8
- package/dist/coordinator-SA75UB3C.js.map +0 -1
- package/dist/corpus-PPOBTF4J.js +0 -15
- package/dist/job-CDADLJDF.js.map +0 -1
- package/dist/remove-E6HGNHOU.js +0 -22
- package/dist/status-7VIGNTUI.js +0 -21
- package/dist/ticket-new-3YXDIWPC.js.map +0 -1
- /package/dist/{architecture-N5ZC4CDU.js.map → architecture-TCSDEFKH.js.map} +0 -0
- /package/dist/{architecture-document-UBA5UT4J.js.map → architecture-document-L2ADWVMV.js.map} +0 -0
- /package/dist/{architecture-monorepo-E4JUYJGV.js.map → architecture-monorepo-NKOQZBEY.js.map} +0 -0
- /package/dist/{boundary-HLJILY7R.js.map → boundary-QP2H7C46.js.map} +0 -0
- /package/dist/{chunk-4CZS4YJV.js.map → chunk-3OKZ3X4O.js.map} +0 -0
- /package/dist/{chunk-GZ36UZJG.js.map → chunk-73TABQRT.js.map} +0 -0
- /package/dist/{chunk-4CKCRZDO.js.map → chunk-7ULZND56.js.map} +0 -0
- /package/dist/{chunk-34NCOTP5.js.map → chunk-7XELS325.js.map} +0 -0
- /package/dist/{chunk-BQTC6YGN.js.map → chunk-D5ENZR6N.js.map} +0 -0
- /package/dist/{chunk-ZRV7TOCX.js.map → chunk-G5AFQXXW.js.map} +0 -0
- /package/dist/{chunk-AXAGJLMP.js.map → chunk-G757F3EU.js.map} +0 -0
- /package/dist/{chunk-BAVDDAN3.js.map → chunk-KS2ESRQL.js.map} +0 -0
- /package/dist/{chunk-KFVEPQ7X.js.map → chunk-MVFHTUQ3.js.map} +0 -0
- /package/dist/{chunk-Q5KLE6ZF.js.map → chunk-OKPRQGFG.js.map} +0 -0
- /package/dist/{chunk-664YNAMR.js.map → chunk-RTFPKJJV.js.map} +0 -0
- /package/dist/{chunk-GKR44BCH.js.map → chunk-RVDXBHUG.js.map} +0 -0
- /package/dist/{chunk-A7Z27COA.js.map → chunk-VFWAZLEF.js.map} +0 -0
- /package/dist/{chunk-I4KBHRZW.js.map → chunk-VJUPD7JI.js.map} +0 -0
- /package/dist/{chunk-3EJNDIAO.js.map → chunk-VZ5B2SIO.js.map} +0 -0
- /package/dist/{cleanup-X556LNWM.js.map → cleanup-JNLZ7AXA.js.map} +0 -0
- /package/dist/{cleanup-command-RV2Q7G72.js.map → cleanup-command-MFAYNYRW.js.map} +0 -0
- /package/dist/{clients-HP23HRN2.js.map → clients-7AJBKEWF.js.map} +0 -0
- /package/dist/{config-LUSJAK6B.js.map → config-GS7BTZJD.js.map} +0 -0
- /package/dist/{configured-paths-SPQ5XWOM.js.map → configured-paths-CREUDQF3.js.map} +0 -0
- /package/dist/{contract-KEZY6YC3.js.map → contract-42CIWIWV.js.map} +0 -0
- /package/dist/{corpus-PPOBTF4J.js.map → corpus-CAFYEMBO.js.map} +0 -0
- /package/dist/{doctor-DSC36R4U.js.map → doctor-AZP5D7QP.js.map} +0 -0
- /package/dist/{feature-directories-VOHVV26X.js.map → feature-directories-6TLM7Y4H.js.map} +0 -0
- /package/dist/{finalization-7SMLMVLV.js.map → finalization-AQT3SOP7.js.map} +0 -0
- /package/dist/{gh-cli-ZMO7D2KE.js.map → gh-cli-XCQT5ST7.js.map} +0 -0
- /package/dist/{github-rest-KGKS4V2H.js.map → github-rest-CXFJ2NFF.js.map} +0 -0
- /package/dist/{learning-sync-6BTHM6ZC.js.map → learning-sync-QVXBOP6J.js.map} +0 -0
- /package/dist/{legacy-global-guidance-2JL4Y5EB.js.map → legacy-global-guidance-CPGUUNJI.js.map} +0 -0
- /package/dist/{lint-gherkin-COSHVS6Z.js.map → lint-gherkin-LZ45NG4A.js.map} +0 -0
- /package/dist/{operations-XVRQSLJG.js.map → operations-ODOA5CDG.js.map} +0 -0
- /package/dist/{output-3LB2OEHN.js.map → output-QTZCFLAY.js.map} +0 -0
- /package/dist/{packet-5WT5M3OS.js.map → packet-5G6RT2EW.js.map} +0 -0
- /package/dist/{profile-UMKQ5JVO.js.map → profile-QGLZNLRU.js.map} +0 -0
- /package/dist/{prompt-GWYDFMLO.js.map → prompt-UCTSCXSS.js.map} +0 -0
- /package/dist/{remove-E6HGNHOU.js.map → remove-UQPEXXNP.js.map} +0 -0
- /package/dist/{retro-IFSVU5KS.js.map → retro-ELKR6GHF.js.map} +0 -0
- /package/dist/{retro-draft-spool-4S3TCHWL.js.map → retro-draft-spool-M75BTT32.js.map} +0 -0
- /package/dist/{retro-extract-OSBFAXLU.js.map → retro-extract-RA6THOC4.js.map} +0 -0
- /package/dist/{review-pr-6S2352CK.js.map → review-pr-MN6QESAJ.js.map} +0 -0
- /package/dist/{review-pr-publication-CGHCRRUI.js.map → review-pr-publication-6AVOGWR2.js.map} +0 -0
- /package/dist/{run-5JESKXUR.js.map → run-JFDGRAH2.js.map} +0 -0
- /package/dist/{self-report-VPHBPPSJ.js.map → self-report-5APRPB5P.js.map} +0 -0
- /package/dist/{status-7VIGNTUI.js.map → status-ATFG6Q3K.js.map} +0 -0
- /package/dist/{status-EX4L3ELO.js.map → status-HIQSP3F5.js.map} +0 -0
- /package/dist/{sync-config-O7J7IDGE.js.map → sync-config-XPAJKBRO.js.map} +0 -0
- /package/dist/{sync-tracker-U2GYOFUO.js.map → sync-tracker-3E5BWX73.js.map} +0 -0
- /package/dist/{ticket-sync-LLUBXZ2R.js.map → ticket-sync-4QJD3KOL.js.map} +0 -0
- /package/dist/{tracker-map-HR4MBYG5.js.map → tracker-map-CFMFIEER.js.map} +0 -0
- /package/dist/{tracker-sync-YDICZN66.js.map → tracker-sync-MOPJE6M7.js.map} +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
writeDurableFile
|
|
3
|
+
} from "./chunk-QOLHGAD5.js";
|
|
4
|
+
import {
|
|
5
|
+
SAFEWORD_SCHEMA
|
|
6
|
+
} from "./chunk-IPTM5VE7.js";
|
|
7
|
+
import {
|
|
3
8
|
parse
|
|
4
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JSR3HXFT.js";
|
|
5
10
|
import {
|
|
6
11
|
CODEX_MIGRATION_SCHEMA
|
|
7
12
|
} from "./chunk-AVAUUIDB.js";
|
|
8
|
-
import {
|
|
9
|
-
writeDurableFile
|
|
10
|
-
} from "./chunk-QOLHGAD5.js";
|
|
11
13
|
|
|
12
14
|
// src/codex-plugin/legacy-authority.ts
|
|
13
15
|
import { accessSync, constants, lstatSync, readFileSync } from "fs";
|
|
@@ -120,10 +122,13 @@ import {
|
|
|
120
122
|
constants as fsConstants,
|
|
121
123
|
existsSync,
|
|
122
124
|
fstatSync,
|
|
125
|
+
lstatSync as lstatSync2,
|
|
123
126
|
openSync,
|
|
127
|
+
readdirSync,
|
|
124
128
|
readFileSync as readFileSync2,
|
|
125
129
|
readSync,
|
|
126
130
|
realpathSync,
|
|
131
|
+
rmdirSync,
|
|
127
132
|
rmSync
|
|
128
133
|
} from "fs";
|
|
129
134
|
import { homedir } from "os";
|
|
@@ -210,15 +215,17 @@ function observeCodexHostProcesses() {
|
|
|
210
215
|
if (result.status !== 0) return { available: false, running: [], current: null };
|
|
211
216
|
return codexHostsFromProcessTable(result.stdout, process.ppid);
|
|
212
217
|
}
|
|
213
|
-
function observeRunningCodexHosts() {
|
|
214
|
-
const observation = observeCodexHostProcesses();
|
|
215
|
-
return observation.available ? observation.running : null;
|
|
216
|
-
}
|
|
217
218
|
function sameCodexHost(left, right) {
|
|
218
219
|
return left.pid === right.pid && left.started_at === right.started_at;
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
// src/codex-plugin/profile-proof.ts
|
|
223
|
+
var SHA256_PATTERN = /^[a-f\d]{64}$/u;
|
|
224
|
+
var NUMERIC_VERSION_PART_PATTERN = /^\d+$/u;
|
|
225
|
+
var VERSION_IDENTIFIER_PATTERN = /^[\dA-Za-z-]+$/u;
|
|
226
|
+
var MAX_PLUGIN_VERSION_LENGTH = 128;
|
|
227
|
+
var MAX_RETAINED_SESSION_PROOFS_PER_PROJECT = 256;
|
|
228
|
+
var MAX_RETAINED_SESSION_PROOF_PROJECTS = 64;
|
|
222
229
|
var CODEX_PLUGIN_HOOK_EVENTS = [
|
|
223
230
|
"session-start",
|
|
224
231
|
"pre-tool-use",
|
|
@@ -227,7 +234,8 @@ var CODEX_PLUGIN_HOOK_EVENTS = [
|
|
|
227
234
|
"stop"
|
|
228
235
|
];
|
|
229
236
|
function codexProfileDirectory(environment = process.env) {
|
|
230
|
-
|
|
237
|
+
const configuredHome = environment.CODEX_HOME?.trim();
|
|
238
|
+
return configuredHome || nodePath2.join(homedir(), ".codex");
|
|
231
239
|
}
|
|
232
240
|
function codexProofPath(environment = process.env, event = "session-start") {
|
|
233
241
|
return nodePath2.join(
|
|
@@ -267,7 +275,13 @@ function legacyCodexRestartMarkerPath(environment = process.env) {
|
|
|
267
275
|
return nodePath2.join(codexProfileDirectory(environment), "safeword/restart-pending-v1.json");
|
|
268
276
|
}
|
|
269
277
|
function codexActivationIsPending(environment = process.env) {
|
|
270
|
-
|
|
278
|
+
try {
|
|
279
|
+
return activationIsPendingForIdentity(environment, currentCodexPluginIdentity());
|
|
280
|
+
} catch {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function activationIsPendingForIdentity(environment, identity) {
|
|
271
285
|
return (
|
|
272
286
|
// The canonical marker is written atomically. If it exists but cannot be
|
|
273
287
|
// parsed or matched, fail closed instead of accepting unbound hook proof.
|
|
@@ -276,6 +290,23 @@ function codexActivationIsPending(environment = process.env) {
|
|
|
276
290
|
)
|
|
277
291
|
);
|
|
278
292
|
}
|
|
293
|
+
function codexActivationMarkerIssue(environment = process.env) {
|
|
294
|
+
const markerPath = codexActivationMarkerPath(environment);
|
|
295
|
+
if (!existsSync(markerPath)) return void 0;
|
|
296
|
+
let identity;
|
|
297
|
+
try {
|
|
298
|
+
identity = currentCodexPluginIdentity();
|
|
299
|
+
} catch {
|
|
300
|
+
return "package-unavailable";
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const marker = readTrustedHookProofJson(markerPath);
|
|
304
|
+
if (!isActivationMarkerV2(marker)) return "malformed";
|
|
305
|
+
return matchesCodexPluginIdentity(marker, identity) ? void 0 : "identity-mismatch";
|
|
306
|
+
} catch {
|
|
307
|
+
return "malformed";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
279
310
|
function packagedHookManifestPath() {
|
|
280
311
|
const candidates = [
|
|
281
312
|
nodePath2.resolve(import.meta.dirname, "../codex-plugin/hooks.json"),
|
|
@@ -287,19 +318,25 @@ function packagedHookManifestPath() {
|
|
|
287
318
|
}
|
|
288
319
|
return manifest;
|
|
289
320
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
|
|
294
|
-
|
|
321
|
+
var currentCodexPluginIdentity = /* @__PURE__ */ (() => {
|
|
322
|
+
let cachedIdentity;
|
|
323
|
+
return () => {
|
|
324
|
+
cachedIdentity ??= (() => {
|
|
325
|
+
const manifest = readFileSync2(packagedHookManifestPath());
|
|
326
|
+
return {
|
|
327
|
+
plugin_version: SAFEWORD_SCHEMA.version,
|
|
328
|
+
manifest_sha256: createHash("sha256").update(manifest).digest("hex")
|
|
329
|
+
};
|
|
330
|
+
})();
|
|
331
|
+
return cachedIdentity;
|
|
295
332
|
};
|
|
296
|
-
}
|
|
333
|
+
})();
|
|
297
334
|
function matchesCodexPluginIdentity(value, identity) {
|
|
298
335
|
return value.plugin_version === identity.plugin_version && value.manifest_sha256 === identity.manifest_sha256;
|
|
299
336
|
}
|
|
300
337
|
function writeCodexActivationMarker(environment = process.env, now = /* @__PURE__ */ new Date(), options = {}) {
|
|
301
338
|
const path = codexActivationMarkerPath(environment);
|
|
302
|
-
const activeHosts = options
|
|
339
|
+
const activeHosts = activeHostsForMarker(options);
|
|
303
340
|
const marker = {
|
|
304
341
|
schema_version: 2,
|
|
305
342
|
...currentCodexPluginIdentity(),
|
|
@@ -315,15 +352,24 @@ function writeCodexActivationMarker(environment = process.env, now = /* @__PURE_
|
|
|
315
352
|
recursive: true,
|
|
316
353
|
force: true
|
|
317
354
|
});
|
|
318
|
-
rmSync(nodePath2.join(codexProfileDirectory(environment), "safeword/session-proof-v1"), {
|
|
319
|
-
recursive: true,
|
|
320
|
-
force: true
|
|
321
|
-
});
|
|
322
355
|
rmSync(codexActivationReceiptPath(environment), { force: true });
|
|
323
356
|
rmSync(legacyCodexActivationMarkerPath(environment), { force: true });
|
|
324
357
|
rmSync(legacyCodexRestartMarkerPath(environment), { force: true });
|
|
325
358
|
return marker;
|
|
326
359
|
}
|
|
360
|
+
function activeHostsForMarker(options) {
|
|
361
|
+
if (options.activeHosts !== void 0) {
|
|
362
|
+
return options.activeHosts === null || options.activeHosts.length === 0 ? null : options.activeHosts;
|
|
363
|
+
}
|
|
364
|
+
const observation = options.hostObservation ?? observeCodexHostProcesses();
|
|
365
|
+
if (!observation.available) return null;
|
|
366
|
+
const activeHosts = [...observation.running];
|
|
367
|
+
const currentHost = observation.current;
|
|
368
|
+
if (currentHost !== null && activeHosts.every((host) => !sameCodexHost(host, currentHost))) {
|
|
369
|
+
activeHosts.push(currentHost);
|
|
370
|
+
}
|
|
371
|
+
return activeHosts.length === 0 ? null : activeHosts;
|
|
372
|
+
}
|
|
327
373
|
function hostObservationForOverride(current = null) {
|
|
328
374
|
return {
|
|
329
375
|
available: true,
|
|
@@ -333,7 +379,7 @@ function hostObservationForOverride(current = null) {
|
|
|
333
379
|
}
|
|
334
380
|
function activationReceiptForRestart(marker, hostObservation, identity, now) {
|
|
335
381
|
const currentHost = hostObservation.current;
|
|
336
|
-
if (!hostObservation.available || currentHost === null || marker.host_observation !== "observed" || now.getTime() < Date.parse(marker.installed_at) || marker.active_hosts.some(
|
|
382
|
+
if (!hostObservation.available || currentHost === null || marker.host_observation !== "observed" || marker.active_hosts.length === 0 || now.getTime() < Date.parse(marker.installed_at) || marker.active_hosts.some((installedHost) => sameCodexHost(installedHost, currentHost)) || marker.active_hosts.some(
|
|
337
383
|
(installedHost) => hostObservation.running.some((runningHost) => sameCodexHost(installedHost, runningHost))
|
|
338
384
|
)) {
|
|
339
385
|
return null;
|
|
@@ -361,36 +407,174 @@ function recordCodexHookProof(event, environment = process.env, now = /* @__PURE
|
|
|
361
407
|
}
|
|
362
408
|
const projectDirectory = writeOptions.projectDirectory === void 0 ? void 0 : canonicalProjectDirectory(writeOptions.projectDirectory);
|
|
363
409
|
const sessionId = writeOptions.sessionId?.trim();
|
|
364
|
-
const
|
|
365
|
-
|
|
410
|
+
const activationId = activeCodexActivationId(marker, receipt);
|
|
411
|
+
const recordedAt = now.toISOString();
|
|
412
|
+
const proof = projectDirectory !== void 0 && sessionId ? {
|
|
413
|
+
schema_version: 3,
|
|
366
414
|
event,
|
|
367
415
|
...identity,
|
|
368
|
-
activation_id:
|
|
369
|
-
|
|
370
|
-
|
|
416
|
+
activation_id: activationId,
|
|
417
|
+
project_directory: projectDirectory,
|
|
418
|
+
session_id: sessionId,
|
|
419
|
+
recorded_at: recordedAt
|
|
420
|
+
} : {
|
|
421
|
+
schema_version: 2,
|
|
422
|
+
event,
|
|
423
|
+
...identity,
|
|
424
|
+
activation_id: activationId,
|
|
425
|
+
recorded_at: recordedAt
|
|
371
426
|
};
|
|
372
427
|
writeAtomicJson(codexProofPath(environment, event), proof, writeOptions);
|
|
373
428
|
if (event === "session-start" && projectDirectory !== void 0 && sessionId) {
|
|
374
429
|
const sessionProof = {
|
|
375
|
-
schema_version:
|
|
430
|
+
schema_version: 2,
|
|
376
431
|
...identity,
|
|
432
|
+
activation_id: activationId,
|
|
377
433
|
project_directory: projectDirectory,
|
|
378
434
|
session_id: sessionId,
|
|
379
|
-
recorded_at:
|
|
435
|
+
recorded_at: recordedAt
|
|
380
436
|
};
|
|
381
|
-
|
|
437
|
+
const path = codexSessionProofPath(projectDirectory, sessionId, environment);
|
|
438
|
+
writeAtomicJson(path, sessionProof);
|
|
439
|
+
pruneCodexSessionProofs(path);
|
|
382
440
|
}
|
|
383
441
|
return proof;
|
|
384
442
|
}
|
|
385
|
-
function
|
|
443
|
+
function validSessionProof(value, canonicalProject, sessionId) {
|
|
444
|
+
if (typeof value !== "object" || value === null) return false;
|
|
445
|
+
const proof = value;
|
|
446
|
+
return sessionProofBindingMatches(proof, canonicalProject, sessionId) && sessionProofIdentityIsWellFormed(proof) && sessionProofTimeIsWellFormed(proof);
|
|
447
|
+
}
|
|
448
|
+
function sessionProofBindingMatches(proof, canonicalProject, sessionId) {
|
|
449
|
+
return (proof.schema_version === 1 || proof.schema_version === 2) && proof.project_directory === canonicalProject && proof.session_id === sessionId && (proof.schema_version === 1 || typeof proof.activation_id === "string" || proof.activation_id === null);
|
|
450
|
+
}
|
|
451
|
+
function sessionProofIdentityIsWellFormed(proof) {
|
|
452
|
+
return pluginVersionIsWellFormed(proof.plugin_version) && typeof proof.manifest_sha256 === "string" && SHA256_PATTERN.test(proof.manifest_sha256);
|
|
453
|
+
}
|
|
454
|
+
function numericVersionPartIsWellFormed(part) {
|
|
455
|
+
return part.length > 0 && NUMERIC_VERSION_PART_PATTERN.test(part) && (part === "0" || !part.startsWith("0"));
|
|
456
|
+
}
|
|
457
|
+
function versionIdentifiersAreWellFormed(value) {
|
|
458
|
+
return value === void 0 || value.split(".").every(
|
|
459
|
+
(identifier) => identifier.length > 0 ? VERSION_IDENTIFIER_PATTERN.test(identifier) : false
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
function pluginVersionIsWellFormed(value) {
|
|
463
|
+
if (typeof value !== "string" || value.length > MAX_PLUGIN_VERSION_LENGTH) return false;
|
|
464
|
+
const buildSplit = value.split("+");
|
|
465
|
+
if (buildSplit.length > 2) return false;
|
|
466
|
+
const coreAndPrerelease = buildSplit[0] ?? "";
|
|
467
|
+
const prereleaseSeparator = coreAndPrerelease.indexOf("-");
|
|
468
|
+
const coreText = prereleaseSeparator === -1 ? coreAndPrerelease : coreAndPrerelease.slice(0, prereleaseSeparator);
|
|
469
|
+
const prerelease = prereleaseSeparator === -1 ? void 0 : coreAndPrerelease.slice(prereleaseSeparator + 1);
|
|
470
|
+
const core = coreText.split(".");
|
|
471
|
+
return core.length === 3 && core.every((part) => numericVersionPartIsWellFormed(part)) && versionIdentifiersAreWellFormed(prerelease) && versionIdentifiersAreWellFormed(buildSplit[1]);
|
|
472
|
+
}
|
|
473
|
+
function sessionProofTimeIsWellFormed(proof) {
|
|
474
|
+
return typeof proof.recorded_at === "string" && !Number.isNaN(Date.parse(proof.recorded_at));
|
|
475
|
+
}
|
|
476
|
+
function classifySessionProof(proof, identity, marker, receipt, activationPending) {
|
|
477
|
+
if (proof.schema_version === 1) return "prior-observed";
|
|
478
|
+
if (!matchesCodexPluginIdentity(proof, identity)) return "prior-observed";
|
|
479
|
+
if (marker !== null && Date.parse(proof.recorded_at) < Date.parse(marker.installed_at)) {
|
|
480
|
+
return "prior-observed";
|
|
481
|
+
}
|
|
482
|
+
if (activationPending) return "activation-pending";
|
|
483
|
+
if (receipt === null) return proof.activation_id === null ? "current" : "prior-observed";
|
|
484
|
+
return proof.activation_id === receipt.activation_id && Date.parse(proof.recorded_at) >= Date.parse(receipt.activated_at) ? "current" : "prior-observed";
|
|
485
|
+
}
|
|
486
|
+
function observeCodexSessionProof(projectDirectory, sessionId, environment = process.env) {
|
|
386
487
|
const canonicalProject = canonicalProjectDirectory(projectDirectory);
|
|
488
|
+
const path = codexSessionProofPath(canonicalProject, sessionId, environment);
|
|
489
|
+
if (!existsSync(path)) {
|
|
490
|
+
return {
|
|
491
|
+
status: "missing",
|
|
492
|
+
plugin_version: null,
|
|
493
|
+
manifest_sha256: null,
|
|
494
|
+
recorded_at: null
|
|
495
|
+
};
|
|
496
|
+
}
|
|
387
497
|
try {
|
|
388
|
-
const value =
|
|
389
|
-
|
|
498
|
+
const value = readTrustedHookProofJson(path);
|
|
499
|
+
if (!validSessionProof(value, canonicalProject, sessionId)) throw new Error("Invalid proof.");
|
|
500
|
+
const identity = currentCodexPluginIdentity();
|
|
501
|
+
const marker = readActivationMarkerV2(environment, identity);
|
|
502
|
+
const receipt = readActivationReceipt(environment, identity);
|
|
503
|
+
const status = classifySessionProof(
|
|
504
|
+
value,
|
|
505
|
+
identity,
|
|
506
|
+
marker,
|
|
507
|
+
receipt,
|
|
508
|
+
activationIsPendingForIdentity(environment, identity)
|
|
390
509
|
);
|
|
391
|
-
return
|
|
510
|
+
return {
|
|
511
|
+
status,
|
|
512
|
+
plugin_version: value.plugin_version,
|
|
513
|
+
manifest_sha256: value.manifest_sha256,
|
|
514
|
+
recorded_at: value.recorded_at
|
|
515
|
+
};
|
|
392
516
|
} catch {
|
|
393
|
-
return
|
|
517
|
+
return {
|
|
518
|
+
status: "untrusted",
|
|
519
|
+
plugin_version: null,
|
|
520
|
+
manifest_sha256: null,
|
|
521
|
+
recorded_at: null
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
function sessionProofProjectDirectories(root) {
|
|
526
|
+
try {
|
|
527
|
+
return readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).flatMap((projectEntry) => {
|
|
528
|
+
const path = nodePath2.join(root, projectEntry.name);
|
|
529
|
+
try {
|
|
530
|
+
if (sessionProofProjectFiles(path).length === 0) return [];
|
|
531
|
+
return [{ modifiedAt: lstatSync2(path).mtimeMs, path }];
|
|
532
|
+
} catch {
|
|
533
|
+
return [];
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
} catch {
|
|
537
|
+
return [];
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function sessionProofProjectFiles(projectPath) {
|
|
541
|
+
try {
|
|
542
|
+
return readdirSync(projectPath, { withFileTypes: true }).flatMap((entry) => {
|
|
543
|
+
if (!entry.isFile() || entry.isSymbolicLink() || entry.name.startsWith(".") || !entry.name.endsWith(".json"))
|
|
544
|
+
return [];
|
|
545
|
+
const path = nodePath2.join(projectPath, entry.name);
|
|
546
|
+
try {
|
|
547
|
+
return [{ modifiedAt: lstatSync2(path).mtimeMs, path }];
|
|
548
|
+
} catch {
|
|
549
|
+
return [];
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
} catch {
|
|
553
|
+
return [];
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function pruneCodexSessionProofs(retainedPath) {
|
|
557
|
+
const retainedProjectPath = nodePath2.dirname(retainedPath);
|
|
558
|
+
const files = sessionProofProjectFiles(retainedProjectPath).toSorted((left, right) => {
|
|
559
|
+
if (left.path === retainedPath) return -1;
|
|
560
|
+
if (right.path === retainedPath) return 1;
|
|
561
|
+
return right.modifiedAt - left.modifiedAt || left.path.localeCompare(right.path);
|
|
562
|
+
});
|
|
563
|
+
for (const stale of files.slice(MAX_RETAINED_SESSION_PROOFS_PER_PROJECT)) {
|
|
564
|
+
rmSync(stale.path, { force: true });
|
|
565
|
+
}
|
|
566
|
+
const root = nodePath2.dirname(retainedProjectPath);
|
|
567
|
+
const projects = sessionProofProjectDirectories(root).toSorted((left, right) => {
|
|
568
|
+
if (left.path === retainedProjectPath) return -1;
|
|
569
|
+
if (right.path === retainedProjectPath) return 1;
|
|
570
|
+
return right.modifiedAt - left.modifiedAt || left.path.localeCompare(right.path);
|
|
571
|
+
});
|
|
572
|
+
for (const stale of projects.slice(MAX_RETAINED_SESSION_PROOF_PROJECTS)) {
|
|
573
|
+
for (const proof of sessionProofProjectFiles(stale.path)) rmSync(proof.path, { force: true });
|
|
574
|
+
try {
|
|
575
|
+
rmdirSync(stale.path);
|
|
576
|
+
} catch {
|
|
577
|
+
}
|
|
394
578
|
}
|
|
395
579
|
}
|
|
396
580
|
function writeAtomicJson(path, value, options = {}) {
|
|
@@ -423,10 +607,13 @@ function readActivationReceipt(environment, identity) {
|
|
|
423
607
|
isActivationReceiptV1
|
|
424
608
|
);
|
|
425
609
|
}
|
|
610
|
+
function activeCodexActivationId(marker, receipt) {
|
|
611
|
+
return receipt?.activation_id ?? marker?.activation_id ?? null;
|
|
612
|
+
}
|
|
426
613
|
function readIdentityBoundJson(path, identity, validator) {
|
|
427
614
|
if (!existsSync(path)) return null;
|
|
428
615
|
try {
|
|
429
|
-
const value =
|
|
616
|
+
const value = readTrustedHookProofJson(path);
|
|
430
617
|
return validator(value) && matchesCodexPluginIdentity(value, identity) ? value : null;
|
|
431
618
|
} catch {
|
|
432
619
|
return null;
|
|
@@ -442,8 +629,8 @@ function readEventProof(path, expectedEvent) {
|
|
|
442
629
|
}
|
|
443
630
|
var MAX_CODEX_HOOK_PROOF_BYTES = 64 * 1024;
|
|
444
631
|
function assertTrustedHookProofMetadata(metadata) {
|
|
445
|
-
const
|
|
446
|
-
if (!metadata.isFile() || metadata.nlink !== 1 || !
|
|
632
|
+
const posixPermissionsAreTrusted = process.getuid === void 0 || metadata.uid === process.getuid() && (metadata.mode & 63) === 0;
|
|
633
|
+
if (!metadata.isFile() || metadata.nlink !== 1 || !posixPermissionsAreTrusted || metadata.size > MAX_CODEX_HOOK_PROOF_BYTES) {
|
|
447
634
|
throw new Error("Untrusted Codex hook proof file.");
|
|
448
635
|
}
|
|
449
636
|
}
|
|
@@ -496,15 +683,25 @@ function observeCodexHookProof(environment = process.env, binding) {
|
|
|
496
683
|
const parsed = existing.map((item) => readEventProof(item.path, item.event));
|
|
497
684
|
if (parsed.includes(null)) return malformedObservation();
|
|
498
685
|
const validProofs = parsed.filter((proof) => proof !== null);
|
|
499
|
-
|
|
500
|
-
|
|
686
|
+
let identity;
|
|
687
|
+
try {
|
|
688
|
+
identity = currentCodexPluginIdentity();
|
|
689
|
+
} catch {
|
|
690
|
+
return malformedObservation();
|
|
691
|
+
}
|
|
692
|
+
const marker = readActivationMarkerV2(environment, identity);
|
|
693
|
+
const receipt = readActivationReceipt(environment, identity);
|
|
694
|
+
const activationId = activeCodexActivationId(marker, receipt);
|
|
695
|
+
if (activationIsPendingForIdentity(environment, identity)) {
|
|
696
|
+
return staleHookObservation(validProofs, activationId);
|
|
697
|
+
}
|
|
501
698
|
const canonicalProject = binding === void 0 ? void 0 : canonicalProjectDirectory(binding.projectDirectory);
|
|
502
699
|
const current = validProofs.filter(
|
|
503
|
-
(proof) => matchesCodexPluginIdentity(proof, identity) && (activationId === null
|
|
700
|
+
(proof) => matchesCodexPluginIdentity(proof, identity) && (activationId === null ? proof.activation_id === null : proof.activation_id === activationId) && (receipt === null || Date.parse(proof.recorded_at) >= Date.parse(receipt.activated_at)) && (binding === void 0 || proof.schema_version === 3 && proof.project_directory === canonicalProject && proof.session_id === binding.sessionId)
|
|
504
701
|
);
|
|
505
702
|
const events = current.map((proof) => proof.event);
|
|
506
703
|
const missingEvents = CODEX_PLUGIN_HOOK_EVENTS.filter((event) => !events.includes(event));
|
|
507
|
-
const latest = current.toSorted((left, right) => right.recorded_at.
|
|
704
|
+
const latest = current.toSorted((left, right) => Date.parse(right.recorded_at) - Date.parse(left.recorded_at)).at(0);
|
|
508
705
|
let status = "stale";
|
|
509
706
|
if (current.length === CODEX_PLUGIN_HOOK_EVENTS.length) status = "current";
|
|
510
707
|
else if (current.length > 0) status = "partial";
|
|
@@ -518,6 +715,17 @@ function observeCodexHookProof(environment = process.env, binding) {
|
|
|
518
715
|
missing_events: missingEvents
|
|
519
716
|
};
|
|
520
717
|
}
|
|
718
|
+
function staleHookObservation(proofs, activationId) {
|
|
719
|
+
return {
|
|
720
|
+
status: "stale",
|
|
721
|
+
plugin_version: proofs[0]?.plugin_version ?? null,
|
|
722
|
+
manifest_sha256: proofs[0]?.manifest_sha256 ?? null,
|
|
723
|
+
recorded_at: null,
|
|
724
|
+
activation_id: activationId,
|
|
725
|
+
events: [],
|
|
726
|
+
missing_events: CODEX_PLUGIN_HOOK_EVENTS
|
|
727
|
+
};
|
|
728
|
+
}
|
|
521
729
|
function malformedObservation() {
|
|
522
730
|
return {
|
|
523
731
|
status: "malformed",
|
|
@@ -532,17 +740,17 @@ function malformedObservation() {
|
|
|
532
740
|
function isCodexHookProof(value) {
|
|
533
741
|
if (typeof value !== "object" || value === null) return false;
|
|
534
742
|
const proof = value;
|
|
535
|
-
return
|
|
743
|
+
return (proof.schema_version === 2 || proof.schema_version === 3) && isCodexPluginHookEvent(proof.event) && pluginVersionIsWellFormed(proof.plugin_version) && typeof proof.manifest_sha256 === "string" && SHA256_PATTERN.test(proof.manifest_sha256) && "activation_id" in proof && (typeof proof.activation_id === "string" || proof.activation_id === null) && (proof.schema_version !== 3 || typeof proof.project_directory === "string" && typeof proof.session_id === "string" && proof.session_id.trim() !== "") && typeof proof.recorded_at === "string" && !Number.isNaN(Date.parse(proof.recorded_at));
|
|
536
744
|
}
|
|
537
745
|
function isActivationMarkerV2(value) {
|
|
538
746
|
if (typeof value !== "object" || value === null) return false;
|
|
539
747
|
const marker = value;
|
|
540
|
-
return marker.schema_version === 2 &&
|
|
748
|
+
return marker.schema_version === 2 && pluginVersionIsWellFormed(marker.plugin_version) && typeof marker.manifest_sha256 === "string" && SHA256_PATTERN.test(marker.manifest_sha256) && typeof marker.activation_id === "string" && typeof marker.installed_at === "string" && !Number.isNaN(Date.parse(marker.installed_at)) && (marker.host_observation === "observed" || marker.host_observation === "unavailable") && Array.isArray(marker.active_hosts) && marker.active_hosts.every(isCodexHostProcessIdentity) && (marker.host_observation === "observed" ? marker.active_hosts.length > 0 : marker.active_hosts.length === 0);
|
|
541
749
|
}
|
|
542
750
|
function isActivationReceiptV1(value) {
|
|
543
751
|
if (typeof value !== "object" || value === null) return false;
|
|
544
752
|
const receipt = value;
|
|
545
|
-
return receipt.schema_version === 1 &&
|
|
753
|
+
return receipt.schema_version === 1 && pluginVersionIsWellFormed(receipt.plugin_version) && typeof receipt.manifest_sha256 === "string" && SHA256_PATTERN.test(receipt.manifest_sha256) && typeof receipt.activation_id === "string" && typeof receipt.activated_at === "string" && !Number.isNaN(Date.parse(receipt.activated_at)) && isCodexHostProcessIdentity(receipt.host);
|
|
546
754
|
}
|
|
547
755
|
function isCodexHostProcessIdentity(value) {
|
|
548
756
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -556,10 +764,12 @@ function isCodexPluginHookEvent(value) {
|
|
|
556
764
|
export {
|
|
557
765
|
legacyCommandIdentity,
|
|
558
766
|
legacyCodexEventIsViable,
|
|
767
|
+
CODEX_PLUGIN_HOOK_EVENTS,
|
|
559
768
|
codexActivationIsPending,
|
|
769
|
+
codexActivationMarkerIssue,
|
|
560
770
|
writeCodexActivationMarker,
|
|
561
771
|
recordCodexHookProof,
|
|
562
|
-
|
|
772
|
+
observeCodexSessionProof,
|
|
563
773
|
observeCodexHookProof
|
|
564
774
|
};
|
|
565
|
-
//# sourceMappingURL=chunk-
|
|
775
|
+
//# sourceMappingURL=chunk-DBXX5K74.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/codex-plugin/legacy-authority.ts","../src/codex-plugin/legacy-command.ts","../src/codex-plugin/profile-proof.ts","../src/codex-plugin/host-process.ts"],"sourcesContent":["import { accessSync, constants, lstatSync, readFileSync } from 'node:fs';\nimport nodePath from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport { SAFEWORD_SCHEMA } from '../schema.js';\nimport { CODEX_MIGRATION_SCHEMA } from './inventory.js';\nimport { legacyCommandIdentity } from './legacy-command.js';\n\ntype LegacyHook = { command?: unknown; type?: unknown };\ntype LegacyHookGroup = { hooks?: unknown };\ntype LegacyConfig = { hooks?: unknown };\n\nfunction regularFile(path: string): boolean {\n try {\n return lstatSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nfunction eventCommands(config: LegacyConfig, eventName: string): string[] {\n if (typeof config.hooks !== 'object' || config.hooks === null) return [];\n const groups = (config.hooks as Record<string, unknown>)[eventName];\n if (!Array.isArray(groups)) return [];\n\n return groups.flatMap(group => {\n const hooks = (group as LegacyHookGroup).hooks;\n if (!Array.isArray(hooks)) return [];\n return hooks.flatMap(hook => {\n const candidate = hook as LegacyHook;\n return candidate.type === 'command' && typeof candidate.command === 'string'\n ? [candidate.command]\n : [];\n });\n });\n}\n\nfunction packageRunnerIsAvailable(cwd: string, environment: NodeJS.ProcessEnv): boolean {\n const runner = SAFEWORD_SCHEMA.codexMigration.packageRunner;\n const pathEntries = (environment.PATH ?? '').split(nodePath.delimiter).filter(Boolean);\n const extensions =\n process.platform === 'win32' ? (environment.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';') : [''];\n return pathEntries.some(entry =>\n extensions.some(extension => {\n const candidate = nodePath.resolve(cwd, entry, `${runner}${extension.toLowerCase()}`);\n try {\n accessSync(candidate, process.platform === 'win32' ? constants.F_OK : constants.X_OK);\n return regularFile(candidate);\n } catch {\n return false;\n }\n }),\n );\n}\n\nfunction commandIsViable(\n command: string,\n event: string,\n cwd: string,\n environment: NodeJS.ProcessEnv,\n): boolean {\n const identity = legacyCommandIdentity(command);\n if (identity?.event !== event) return false;\n if (identity.kind === 'package') {\n return (\n regularFile(nodePath.join(cwd, SAFEWORD_SCHEMA.codexMigration.projectMarker)) &&\n packageRunnerIsAvailable(cwd, environment)\n );\n }\n return (\n identity.kind === 'script' &&\n regularFile(nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.hookRuntimeRoot, identity.script))\n );\n}\n\nexport function legacyCodexEventIsViable(\n cwd: string,\n event: string,\n environment: NodeJS.ProcessEnv = process.env,\n): boolean {\n const eventName = SAFEWORD_SCHEMA.codexMigration.hookEventNames[event];\n if (eventName === undefined) return false;\n\n const configPath = nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.config);\n if (!regularFile(configPath)) return false;\n\n let config: LegacyConfig;\n try {\n config = parse(readFileSync(configPath, 'utf8'));\n } catch {\n return false;\n }\n\n return eventCommands(config, eventName).some(command =>\n commandIsViable(command, event, cwd, environment),\n );\n}\n","import { CODEX_MIGRATION_SCHEMA } from './inventory.js';\n\nexport type LegacyCommandIdentity =\n | {\n readonly kind: 'package';\n readonly event: string;\n }\n | {\n readonly kind: 'script';\n readonly event: string;\n readonly script: string;\n };\n\nfunction commandParts(command: string): string[] {\n return command\n .trim()\n .split(' ')\n .filter(part => part !== '');\n}\n\nfunction isHistoricalPackagePrefix(parts: readonly string[]): boolean {\n return (\n parts[0] === CODEX_MIGRATION_SCHEMA.packageRunner &&\n parts[1] === '--yes' &&\n parts[2] === 'safeword'\n );\n}\n\nfunction packagedHookEvent(hook: readonly string[]): string | undefined {\n if (\n hook.length === 3 &&\n hook[0] === 'hook' &&\n hook[1] === 'codex' &&\n CODEX_MIGRATION_SCHEMA.hookEvents.includes(hook[2] ?? '')\n ) {\n return hook[2];\n }\n if (\n hook.length === 2 &&\n hook[0] === 'codex-hook' &&\n CODEX_MIGRATION_SCHEMA.hookEvents.includes(hook[1] ?? '')\n ) {\n return hook[1];\n }\n return undefined;\n}\n\nfunction packageIdentity(command: string): LegacyCommandIdentity | undefined {\n const parts = commandParts(command);\n if (!isHistoricalPackagePrefix(parts)) return undefined;\n const event = packagedHookEvent(parts.slice(3));\n return event === undefined ? undefined : { kind: 'package', event };\n}\n\nfunction scriptIdentity(command: string): LegacyCommandIdentity | undefined {\n const prefix = CODEX_MIGRATION_SCHEMA.hookScriptPrefix;\n if (!command.startsWith(prefix)) return undefined;\n const remainder = command.slice(prefix.length);\n const quote = remainder.indexOf('\"');\n if (quote === -1) return undefined;\n const script = remainder.slice(0, quote);\n const event = CODEX_MIGRATION_SCHEMA.hookScriptEvents[script];\n if (event === undefined) return undefined;\n const arguments_ = remainder.slice(quote + 1);\n const supportedArguments =\n arguments_ === '' ||\n (script === 'session-safeword-context.ts' && arguments_ === ' --agent=codex');\n return supportedArguments ? { kind: 'script', event, script } : undefined;\n}\n\nexport function legacyCommandIdentity(command: string): LegacyCommandIdentity | undefined {\n return packageIdentity(command) ?? scriptIdentity(command);\n}\n","/* eslint-disable unicorn/no-null -- versioned JSON uses explicit null for unavailable values */\n\nimport { createHash, randomUUID } from 'node:crypto';\nimport {\n closeSync,\n constants as fsConstants,\n existsSync,\n fstatSync,\n lstatSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n realpathSync,\n rmdirSync,\n rmSync,\n type Stats,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport nodePath from 'node:path';\n\nimport { SAFEWORD_SCHEMA } from '../schema.js';\nimport { writeDurableFile } from './durable-write.js';\nimport {\n type CodexHostProcessIdentity,\n type CodexHostProcessObservation,\n observeCodexHostProcesses,\n sameCodexHost,\n} from './host-process.js';\n\nexport type { CodexHostProcessIdentity } from './host-process.js';\n\nexport interface CodexPluginIdentity {\n plugin_version: string;\n manifest_sha256: string;\n}\n\nexport interface CodexHookProofV2 {\n schema_version: 2;\n event: CodexPluginHookEvent;\n plugin_version: string;\n manifest_sha256: string;\n activation_id: string | null;\n recorded_at: string;\n}\n\nexport interface CodexHookProofV3 extends CodexPluginIdentity {\n schema_version: 3;\n event: CodexPluginHookEvent;\n activation_id: string | null;\n project_directory: string;\n session_id: string;\n recorded_at: string;\n}\n\ninterface CodexSessionProofV1 extends CodexPluginIdentity {\n schema_version: 1;\n project_directory: string;\n session_id: string;\n recorded_at: string;\n}\n\ninterface CodexSessionProofV2 extends CodexPluginIdentity {\n schema_version: 2;\n activation_id: string | null;\n project_directory: string;\n session_id: string;\n recorded_at: string;\n}\n\ntype CodexSessionProof = CodexSessionProofV1 | CodexSessionProofV2;\n\nexport type CodexSessionProofStatus =\n 'activation-pending' | 'current' | 'prior-observed' | 'missing' | 'untrusted';\n\nexport interface CodexSessionProofObservation {\n status: CodexSessionProofStatus;\n plugin_version: string | null;\n manifest_sha256: string | null;\n recorded_at: string | null;\n}\n\nconst SHA256_PATTERN = /^[a-f\\d]{64}$/u;\nconst NUMERIC_VERSION_PART_PATTERN = /^\\d+$/u;\nconst VERSION_IDENTIFIER_PATTERN = /^[\\dA-Za-z-]+$/u;\nconst MAX_PLUGIN_VERSION_LENGTH = 128;\nconst MAX_RETAINED_SESSION_PROOFS_PER_PROJECT = 256;\nconst MAX_RETAINED_SESSION_PROOF_PROJECTS = 64;\n\ninterface CodexActivationMarkerV1 {\n schema_version: 1;\n plugin_version: string;\n manifest_sha256: string;\n}\n\nexport interface CodexActivationMarkerV2 {\n schema_version: 2;\n plugin_version: string;\n manifest_sha256: string;\n activation_id: string;\n installed_at: string;\n host_observation: 'observed' | 'unavailable';\n active_hosts: CodexHostProcessIdentity[];\n}\n\ninterface CodexActivationReceiptV1 {\n schema_version: 1;\n plugin_version: string;\n manifest_sha256: string;\n activation_id: string;\n activated_at: string;\n host: CodexHostProcessIdentity;\n}\n\nexport const CODEX_PLUGIN_HOOK_EVENTS = [\n 'session-start',\n 'pre-tool-use',\n 'post-tool-use',\n 'user-prompt-submit',\n 'stop',\n] as const;\nexport type CodexPluginHookEvent = (typeof CODEX_PLUGIN_HOOK_EVENTS)[number];\n\ntype CodexHookProofStatus = 'current' | 'partial' | 'missing' | 'stale' | 'malformed';\n\nexport interface CodexHookProofObservation {\n status: CodexHookProofStatus;\n plugin_version: string | null;\n manifest_sha256: string | null;\n recorded_at: string | null;\n activation_id: string | null;\n events: readonly CodexPluginHookEvent[];\n missing_events: readonly CodexPluginHookEvent[];\n}\n\nfunction codexProfileDirectory(environment: NodeJS.ProcessEnv = process.env): string {\n const configuredHome = environment.CODEX_HOME?.trim();\n return configuredHome || nodePath.join(homedir(), '.codex');\n}\n\nexport function codexProofPath(\n environment: NodeJS.ProcessEnv = process.env,\n event: CodexPluginHookEvent = 'session-start',\n): string {\n return nodePath.join(\n codexProfileDirectory(environment),\n 'safeword/hook-proof-v2',\n `${event}.json`,\n );\n}\n\nfunction canonicalProjectDirectory(projectDirectory: string): string {\n try {\n return realpathSync(projectDirectory);\n } catch {\n return nodePath.resolve(projectDirectory);\n }\n}\n\nfunction codexSessionProofPath(\n projectDirectory: string,\n sessionId: string,\n environment: NodeJS.ProcessEnv,\n): string {\n // The directory suffix versions the storage layout, independently from the\n // schema_version inside each retained proof record.\n const project = canonicalProjectDirectory(projectDirectory);\n const projectDigest = createHash('sha256').update(project).digest('hex');\n const sessionDigest = createHash('sha256').update(sessionId).digest('hex');\n return nodePath.join(\n codexProfileDirectory(environment),\n 'safeword/session-proof-v1',\n projectDigest,\n `${sessionDigest}.json`,\n );\n}\n\nfunction legacyCodexActivationMarkerPath(environment: NodeJS.ProcessEnv = process.env): string {\n return nodePath.join(codexProfileDirectory(environment), 'safeword/activation-pending-v1.json');\n}\n\nfunction codexActivationMarkerPath(environment: NodeJS.ProcessEnv = process.env): string {\n return nodePath.join(codexProfileDirectory(environment), 'safeword/activation-pending-v2.json');\n}\n\nfunction codexActivationReceiptPath(environment: NodeJS.ProcessEnv = process.env): string {\n return nodePath.join(codexProfileDirectory(environment), 'safeword/activation-current-v1.json');\n}\n\nfunction legacyCodexRestartMarkerPath(environment: NodeJS.ProcessEnv = process.env): string {\n return nodePath.join(codexProfileDirectory(environment), 'safeword/restart-pending-v1.json');\n}\n\nexport function codexActivationIsPending(environment: NodeJS.ProcessEnv = process.env): boolean {\n try {\n return activationIsPendingForIdentity(environment, currentCodexPluginIdentity());\n } catch {\n return true;\n }\n}\n\nfunction activationIsPendingForIdentity(\n environment: NodeJS.ProcessEnv,\n identity: CodexPluginIdentity,\n): boolean {\n return (\n // The canonical marker is written atomically. If it exists but cannot be\n // parsed or matched, fail closed instead of accepting unbound hook proof.\n existsSync(codexActivationMarkerPath(environment)) ||\n [legacyCodexActivationMarkerPath(environment), legacyCodexRestartMarkerPath(environment)].some(\n path => legacyActivationMarkerMatches(path, identity),\n )\n );\n}\n\nexport type CodexActivationMarkerIssue = 'identity-mismatch' | 'malformed' | 'package-unavailable';\n\nexport function codexActivationMarkerIssue(\n environment: NodeJS.ProcessEnv = process.env,\n): CodexActivationMarkerIssue | undefined {\n const markerPath = codexActivationMarkerPath(environment);\n if (!existsSync(markerPath)) return undefined;\n let identity: CodexPluginIdentity;\n try {\n identity = currentCodexPluginIdentity();\n } catch {\n return 'package-unavailable';\n }\n try {\n const marker = readTrustedHookProofJson(markerPath);\n if (!isActivationMarkerV2(marker)) return 'malformed';\n return matchesCodexPluginIdentity(marker, identity) ? undefined : 'identity-mismatch';\n } catch {\n return 'malformed';\n }\n}\n\nfunction packagedHookManifestPath(): string {\n const candidates = [\n nodePath.resolve(import.meta.dirname, '../codex-plugin/hooks.json'),\n nodePath.resolve(import.meta.dirname, '../../codex-plugin/hooks.json'),\n ];\n const manifest = candidates.find(candidate => existsSync(candidate));\n if (manifest === undefined) {\n throw new Error('Could not locate the packaged Codex hook manifest.');\n }\n return manifest;\n}\n\nexport const currentCodexPluginIdentity = (() => {\n let cachedIdentity: CodexPluginIdentity | undefined;\n return (): CodexPluginIdentity => {\n cachedIdentity ??= (() => {\n const manifest = readFileSync(packagedHookManifestPath());\n return {\n plugin_version: SAFEWORD_SCHEMA.version,\n manifest_sha256: createHash('sha256').update(manifest).digest('hex'),\n };\n })();\n return cachedIdentity;\n };\n})();\n\nfunction matchesCodexPluginIdentity(\n value: { plugin_version?: unknown; manifest_sha256?: unknown },\n identity: CodexPluginIdentity,\n): boolean {\n return (\n value.plugin_version === identity.plugin_version &&\n value.manifest_sha256 === identity.manifest_sha256\n );\n}\n\nexport function writeCodexActivationMarker(\n environment: NodeJS.ProcessEnv = process.env,\n now = new Date(),\n options: {\n activationId?: string;\n activeHosts?: CodexHostProcessIdentity[] | null;\n hostObservation?: CodexHostProcessObservation;\n } = {},\n): CodexActivationMarkerV2 {\n const path = codexActivationMarkerPath(environment);\n const activeHosts = activeHostsForMarker(options);\n const marker: CodexActivationMarkerV2 = {\n schema_version: 2,\n ...currentCodexPluginIdentity(),\n activation_id: options.activationId ?? randomUUID(),\n installed_at: now.toISOString(),\n host_observation: activeHosts === null ? 'unavailable' : 'observed',\n active_hosts: activeHosts ?? [],\n };\n writeAtomicJson(path, marker);\n // A new installation invalidates every earlier execution proof. The v2\n // marker is the only authority until SessionStart proves a different Codex\n // app-server loaded the installed plugin catalogue.\n for (const event of CODEX_PLUGIN_HOOK_EVENTS)\n rmSync(codexProofPath(environment, event), { force: true });\n rmSync(nodePath.join(codexProfileDirectory(environment), 'safeword/hook-proof-v1'), {\n recursive: true,\n force: true,\n });\n // Task-bound SessionStart history is intentionally retained. Exact-current\n // checks still reject it after this marker is written, while bootstrap can\n // distinguish a previously observed runtime from wholly unobserved\n // protection in the already-open task.\n rmSync(codexActivationReceiptPath(environment), { force: true });\n rmSync(legacyCodexActivationMarkerPath(environment), { force: true });\n rmSync(legacyCodexRestartMarkerPath(environment), { force: true });\n return marker;\n}\n\nfunction activeHostsForMarker(options: {\n activeHosts?: CodexHostProcessIdentity[] | null;\n hostObservation?: CodexHostProcessObservation;\n}): CodexHostProcessIdentity[] | null {\n if (options.activeHosts !== undefined) {\n return options.activeHosts === null || options.activeHosts.length === 0\n ? null\n : options.activeHosts;\n }\n const observation = options.hostObservation ?? observeCodexHostProcesses();\n if (!observation.available) return null;\n const activeHosts = [...observation.running];\n const currentHost = observation.current;\n if (currentHost !== null && activeHosts.every(host => !sameCodexHost(host, currentHost))) {\n activeHosts.push(currentHost);\n }\n return activeHosts.length === 0 ? null : activeHosts;\n}\n\nfunction hostObservationForOverride(\n current: CodexHostProcessIdentity | null = null,\n): CodexHostProcessObservation {\n return {\n available: true,\n current,\n running: current === null ? [] : [current],\n };\n}\n\nfunction activationReceiptForRestart(\n marker: CodexActivationMarkerV2,\n hostObservation: CodexHostProcessObservation,\n identity: CodexPluginIdentity,\n now: Date,\n): CodexActivationReceiptV1 | null {\n const currentHost = hostObservation.current;\n if (\n !hostObservation.available ||\n currentHost === null ||\n marker.host_observation !== 'observed' ||\n marker.active_hosts.length === 0 ||\n now.getTime() < Date.parse(marker.installed_at) ||\n marker.active_hosts.some(installedHost => sameCodexHost(installedHost, currentHost)) ||\n marker.active_hosts.some(installedHost =>\n hostObservation.running.some(runningHost => sameCodexHost(installedHost, runningHost)),\n )\n ) {\n return null;\n }\n return {\n schema_version: 1,\n ...identity,\n activation_id: marker.activation_id,\n activated_at: now.toISOString(),\n host: currentHost,\n };\n}\n\n// eslint-disable-next-line complexity -- coordinates optional host overrides with durable proof writes\nexport function recordCodexHookProof(\n event: CodexPluginHookEvent,\n environment: NodeJS.ProcessEnv = process.env,\n now = new Date(),\n writeOptions: {\n beforeRename?: () => void;\n currentHost?: CodexHostProcessIdentity | null;\n hostObservation?: CodexHostProcessObservation;\n projectDirectory?: string;\n sessionId?: string;\n } = {},\n): CodexHookProofV2 | CodexHookProofV3 {\n const identity = currentCodexPluginIdentity();\n const marker = readActivationMarkerV2(environment, identity);\n let receipt = readActivationReceipt(environment, identity);\n if (event === 'session-start' && marker !== null) {\n const hostObservation =\n writeOptions.hostObservation ??\n ('currentHost' in writeOptions\n ? hostObservationForOverride(writeOptions.currentHost)\n : observeCodexHostProcesses());\n const restartedReceipt = activationReceiptForRestart(marker, hostObservation, identity, now);\n if (restartedReceipt !== null) {\n receipt = restartedReceipt;\n writeAtomicJson(codexActivationReceiptPath(environment), receipt);\n rmSync(codexActivationMarkerPath(environment), { force: true });\n }\n }\n const projectDirectory =\n writeOptions.projectDirectory === undefined\n ? undefined\n : canonicalProjectDirectory(writeOptions.projectDirectory);\n const sessionId = writeOptions.sessionId?.trim();\n const activationId = activeCodexActivationId(marker, receipt);\n const recordedAt = now.toISOString();\n const proof: CodexHookProofV2 | CodexHookProofV3 =\n projectDirectory !== undefined && sessionId\n ? {\n schema_version: 3,\n event,\n ...identity,\n activation_id: activationId,\n project_directory: projectDirectory,\n session_id: sessionId,\n recorded_at: recordedAt,\n }\n : {\n schema_version: 2,\n event,\n ...identity,\n activation_id: activationId,\n recorded_at: recordedAt,\n };\n writeAtomicJson(codexProofPath(environment, event), proof, writeOptions);\n if (event === 'session-start' && projectDirectory !== undefined && sessionId) {\n const sessionProof: CodexSessionProofV2 = {\n schema_version: 2,\n ...identity,\n activation_id: activationId,\n project_directory: projectDirectory,\n session_id: sessionId,\n recorded_at: recordedAt,\n };\n const path = codexSessionProofPath(projectDirectory, sessionId, environment);\n writeAtomicJson(path, sessionProof);\n pruneCodexSessionProofs(path);\n }\n return proof;\n}\n\nexport function codexSessionProofIsCurrent(\n projectDirectory: string,\n sessionId: string,\n environment: NodeJS.ProcessEnv = process.env,\n): boolean {\n return observeCodexSessionProof(projectDirectory, sessionId, environment).status === 'current';\n}\n\nfunction validSessionProof(\n value: unknown,\n canonicalProject: string,\n sessionId: string,\n): value is CodexSessionProof {\n if (typeof value !== 'object' || value === null) return false;\n const proof = value as Record<string, unknown>;\n return (\n sessionProofBindingMatches(proof, canonicalProject, sessionId) &&\n sessionProofIdentityIsWellFormed(proof) &&\n sessionProofTimeIsWellFormed(proof)\n );\n}\n\nfunction sessionProofBindingMatches(\n proof: Record<string, unknown>,\n canonicalProject: string,\n sessionId: string,\n): boolean {\n return (\n (proof.schema_version === 1 || proof.schema_version === 2) &&\n proof.project_directory === canonicalProject &&\n proof.session_id === sessionId &&\n (proof.schema_version === 1 ||\n typeof proof.activation_id === 'string' ||\n proof.activation_id === null)\n );\n}\n\nfunction sessionProofIdentityIsWellFormed(proof: Record<string, unknown>): boolean {\n return (\n pluginVersionIsWellFormed(proof.plugin_version) &&\n typeof proof.manifest_sha256 === 'string' &&\n SHA256_PATTERN.test(proof.manifest_sha256)\n );\n}\n\nfunction numericVersionPartIsWellFormed(part: string): boolean {\n return (\n part.length > 0 &&\n NUMERIC_VERSION_PART_PATTERN.test(part) &&\n (part === '0' || !part.startsWith('0'))\n );\n}\n\nfunction versionIdentifiersAreWellFormed(value: string | undefined): boolean {\n return (\n value === undefined ||\n value\n .split('.')\n .every(identifier =>\n identifier.length > 0 ? VERSION_IDENTIFIER_PATTERN.test(identifier) : false,\n )\n );\n}\n\nfunction pluginVersionIsWellFormed(value: unknown): value is string {\n if (typeof value !== 'string' || value.length > MAX_PLUGIN_VERSION_LENGTH) return false;\n const buildSplit = value.split('+');\n if (buildSplit.length > 2) return false;\n const coreAndPrerelease = buildSplit[0] ?? '';\n const prereleaseSeparator = coreAndPrerelease.indexOf('-');\n const coreText =\n prereleaseSeparator === -1\n ? coreAndPrerelease\n : coreAndPrerelease.slice(0, prereleaseSeparator);\n const prerelease =\n prereleaseSeparator === -1 ? undefined : coreAndPrerelease.slice(prereleaseSeparator + 1);\n const core = coreText.split('.');\n return (\n core.length === 3 &&\n core.every(part => numericVersionPartIsWellFormed(part)) &&\n versionIdentifiersAreWellFormed(prerelease) &&\n versionIdentifiersAreWellFormed(buildSplit[1])\n );\n}\n\nfunction sessionProofTimeIsWellFormed(proof: Record<string, unknown>): boolean {\n return typeof proof.recorded_at === 'string' && !Number.isNaN(Date.parse(proof.recorded_at));\n}\n\nfunction classifySessionProof(\n proof: CodexSessionProof,\n identity: CodexPluginIdentity,\n marker: CodexActivationMarkerV2 | null,\n receipt: CodexActivationReceiptV1 | null,\n activationPending: boolean,\n): CodexSessionProofStatus {\n if (proof.schema_version === 1) return 'prior-observed';\n if (!matchesCodexPluginIdentity(proof, identity)) return 'prior-observed';\n if (marker !== null && Date.parse(proof.recorded_at) < Date.parse(marker.installed_at)) {\n return 'prior-observed';\n }\n if (activationPending) return 'activation-pending';\n if (receipt === null) return proof.activation_id === null ? 'current' : 'prior-observed';\n return proof.activation_id === receipt.activation_id &&\n Date.parse(proof.recorded_at) >= Date.parse(receipt.activated_at)\n ? 'current'\n : 'prior-observed';\n}\n\nexport function observeCodexSessionProof(\n projectDirectory: string,\n sessionId: string,\n environment: NodeJS.ProcessEnv = process.env,\n): CodexSessionProofObservation {\n const canonicalProject = canonicalProjectDirectory(projectDirectory);\n const path = codexSessionProofPath(canonicalProject, sessionId, environment);\n if (!existsSync(path)) {\n return {\n status: 'missing',\n plugin_version: null,\n manifest_sha256: null,\n recorded_at: null,\n };\n }\n try {\n const value = readTrustedHookProofJson(path);\n if (!validSessionProof(value, canonicalProject, sessionId)) throw new Error('Invalid proof.');\n const identity = currentCodexPluginIdentity();\n const marker = readActivationMarkerV2(environment, identity);\n const receipt = readActivationReceipt(environment, identity);\n const status = classifySessionProof(\n value,\n identity,\n marker,\n receipt,\n activationIsPendingForIdentity(environment, identity),\n );\n return {\n status,\n plugin_version: value.plugin_version,\n manifest_sha256: value.manifest_sha256,\n recorded_at: value.recorded_at,\n };\n } catch {\n return {\n status: 'untrusted',\n plugin_version: null,\n manifest_sha256: null,\n recorded_at: null,\n };\n }\n}\n\nfunction sessionProofProjectDirectories(root: string): {\n modifiedAt: number;\n path: string;\n}[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter(entry => entry.isDirectory() && !entry.isSymbolicLink())\n .flatMap(projectEntry => {\n const path = nodePath.join(root, projectEntry.name);\n try {\n // A crash may leave only a durable-write temporary file. Such a\n // directory is not retained proof and must not consume a project\n // retention slot or evict a live sibling project.\n if (sessionProofProjectFiles(path).length === 0) return [];\n return [{ modifiedAt: lstatSync(path).mtimeMs, path }];\n } catch {\n // An unreadable directory is not evidence that its retained history\n // is empty. Leave it untouched and retry on a later SessionStart.\n return [];\n }\n });\n } catch {\n return [];\n }\n}\n\nfunction sessionProofProjectFiles(projectPath: string): { modifiedAt: number; path: string }[] {\n try {\n return readdirSync(projectPath, { withFileTypes: true }).flatMap(entry => {\n if (\n !entry.isFile() ||\n entry.isSymbolicLink() ||\n entry.name.startsWith('.') ||\n !entry.name.endsWith('.json')\n )\n return [];\n const path = nodePath.join(projectPath, entry.name);\n try {\n return [{ modifiedAt: lstatSync(path).mtimeMs, path }];\n } catch {\n // Another task may prune the same proof between listing and metadata\n // lookup. Keep the remaining bounded history instead of abandoning it.\n return [];\n }\n });\n } catch {\n return [];\n }\n}\n\nfunction pruneCodexSessionProofs(retainedPath: string): void {\n const retainedProjectPath = nodePath.dirname(retainedPath);\n const files = sessionProofProjectFiles(retainedProjectPath).toSorted((left, right) => {\n if (left.path === retainedPath) return -1;\n if (right.path === retainedPath) return 1;\n return right.modifiedAt - left.modifiedAt || left.path.localeCompare(right.path);\n });\n for (const stale of files.slice(MAX_RETAINED_SESSION_PROOFS_PER_PROJECT)) {\n rmSync(stale.path, { force: true });\n }\n const root = nodePath.dirname(retainedProjectPath);\n const projects = sessionProofProjectDirectories(root).toSorted((left, right) => {\n if (left.path === retainedProjectPath) return -1;\n if (right.path === retainedProjectPath) return 1;\n return right.modifiedAt - left.modifiedAt || left.path.localeCompare(right.path);\n });\n for (const stale of projects.slice(MAX_RETAINED_SESSION_PROOF_PROJECTS)) {\n for (const proof of sessionProofProjectFiles(stale.path)) rmSync(proof.path, { force: true });\n try {\n // Non-recursive removal cannot erase a concurrent writer's temporary or\n // newly published proof. A non-empty directory is retried later.\n rmdirSync(stale.path);\n } catch {\n // Advisory history remains bounded per project even when a concurrent\n // writer keeps this project directory alive.\n }\n }\n}\n\nfunction writeAtomicJson(\n path: string,\n value: unknown,\n options: { beforeRename?: () => void } = {},\n): void {\n writeDurableFile(path, `${JSON.stringify(value)}\\n`, {\n mode: 0o600,\n beforeRename: options.beforeRename,\n });\n}\n\nfunction legacyActivationMarkerMatches(path: string, identity: CodexPluginIdentity): boolean {\n if (!existsSync(path)) return false;\n try {\n const marker = JSON.parse(readFileSync(path, 'utf8')) as Partial<CodexActivationMarkerV1>;\n return marker.schema_version === 1 && matchesCodexPluginIdentity(marker, identity);\n } catch {\n return false;\n }\n}\n\nfunction readActivationMarkerV2(\n environment: NodeJS.ProcessEnv,\n identity: CodexPluginIdentity,\n): CodexActivationMarkerV2 | null {\n return readIdentityBoundJson(\n codexActivationMarkerPath(environment),\n identity,\n isActivationMarkerV2,\n );\n}\n\nfunction readActivationReceipt(\n environment: NodeJS.ProcessEnv,\n identity: CodexPluginIdentity,\n): CodexActivationReceiptV1 | null {\n return readIdentityBoundJson(\n codexActivationReceiptPath(environment),\n identity,\n isActivationReceiptV1,\n );\n}\n\nfunction activeCodexActivationId(\n marker: CodexActivationMarkerV2 | null,\n receipt: CodexActivationReceiptV1 | null,\n): string | null {\n // A completed restart receipt supersedes a leftover pending marker. Sharing\n // this precedence keeps the proof writer and observer on the same identity.\n return receipt?.activation_id ?? marker?.activation_id ?? null;\n}\n\nfunction readIdentityBoundJson<T extends CodexPluginIdentity>(\n path: string,\n identity: CodexPluginIdentity,\n validator: (value: unknown) => value is T,\n): T | null {\n if (!existsSync(path)) return null;\n try {\n const value = readTrustedHookProofJson(path);\n return validator(value) && matchesCodexPluginIdentity(value, identity) ? value : null;\n } catch {\n return null;\n }\n}\n\nfunction readEventProof(\n path: string,\n expectedEvent: CodexPluginHookEvent,\n): CodexHookProofV2 | CodexHookProofV3 | null {\n try {\n const proof = readTrustedHookProofJson(path);\n return isCodexHookProof(proof) && proof.event === expectedEvent ? proof : null;\n } catch {\n return null;\n }\n}\n\nconst MAX_CODEX_HOOK_PROOF_BYTES = 64 * 1024;\n\nfunction assertTrustedHookProofMetadata(metadata: Stats): void {\n const posixPermissionsAreTrusted =\n process.getuid === undefined ||\n (metadata.uid === process.getuid() && (metadata.mode & 0o077) === 0);\n if (\n !metadata.isFile() ||\n metadata.nlink !== 1 ||\n !posixPermissionsAreTrusted ||\n metadata.size > MAX_CODEX_HOOK_PROOF_BYTES\n ) {\n throw new Error('Untrusted Codex hook proof file.');\n }\n}\n\nfunction readDescriptorFully(descriptor: number, size: number): Buffer {\n const buffer = Buffer.alloc(size);\n let offset = 0;\n while (offset < buffer.length) {\n const count = readSync(descriptor, buffer, offset, buffer.length - offset, offset);\n if (count === 0) break;\n offset += count;\n }\n if (offset !== buffer.length)\n throw new Error('Codex hook proof changed while it was being read.');\n return buffer;\n}\n\nfunction assertHookProofUnchanged(before: Stats, after: Stats): void {\n if (\n after.size !== before.size ||\n after.mtimeMs !== before.mtimeMs ||\n after.ctimeMs !== before.ctimeMs\n ) {\n throw new Error('Codex hook proof changed while it was being read.');\n }\n}\n\nfunction readTrustedHookProofJson(path: string): unknown {\n const descriptor = openSync(path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));\n try {\n const metadata = fstatSync(descriptor);\n assertTrustedHookProofMetadata(metadata);\n const buffer = readDescriptorFully(descriptor, metadata.size);\n assertHookProofUnchanged(metadata, fstatSync(descriptor));\n return JSON.parse(buffer.toString('utf8')) as unknown;\n } finally {\n closeSync(descriptor);\n }\n}\n\n// eslint-disable-next-line complexity -- aggregates independently written event proofs and preserves malformed/stale distinctions\nexport function observeCodexHookProof(\n environment: NodeJS.ProcessEnv = process.env,\n binding?: { projectDirectory: string; sessionId: string },\n): CodexHookProofObservation {\n const candidates = CODEX_PLUGIN_HOOK_EVENTS.map(event => ({\n event,\n path: codexProofPath(environment, event),\n }));\n const existing = candidates.filter(candidate => existsSync(candidate.path));\n if (existing.length === 0) {\n return {\n status: 'missing',\n plugin_version: null,\n manifest_sha256: null,\n recorded_at: null,\n activation_id: null,\n events: [],\n missing_events: CODEX_PLUGIN_HOOK_EVENTS,\n };\n }\n\n const parsed = existing.map(item => readEventProof(item.path, item.event));\n if (parsed.includes(null)) return malformedObservation();\n const validProofs = parsed.filter(proof => proof !== null);\n\n let identity: CodexPluginIdentity;\n try {\n identity = currentCodexPluginIdentity();\n } catch {\n return malformedObservation();\n }\n const marker = readActivationMarkerV2(environment, identity);\n const receipt = readActivationReceipt(environment, identity);\n const activationId = activeCodexActivationId(marker, receipt);\n if (activationIsPendingForIdentity(environment, identity)) {\n return staleHookObservation(validProofs, activationId);\n }\n const canonicalProject =\n binding === undefined ? undefined : canonicalProjectDirectory(binding.projectDirectory);\n const current = validProofs.filter(\n proof =>\n matchesCodexPluginIdentity(proof, identity) &&\n (activationId === null\n ? proof.activation_id === null\n : proof.activation_id === activationId) &&\n (receipt === null || Date.parse(proof.recorded_at) >= Date.parse(receipt.activated_at)) &&\n (binding === undefined ||\n (proof.schema_version === 3 &&\n proof.project_directory === canonicalProject &&\n proof.session_id === binding.sessionId)),\n );\n const events = current.map(proof => proof.event);\n const missingEvents = CODEX_PLUGIN_HOOK_EVENTS.filter(event => !events.includes(event));\n const latest = current\n .toSorted((left, right) => Date.parse(right.recorded_at) - Date.parse(left.recorded_at))\n .at(0);\n let status: CodexHookProofStatus = 'stale';\n if (current.length === CODEX_PLUGIN_HOOK_EVENTS.length) status = 'current';\n else if (current.length > 0) status = 'partial';\n return {\n status,\n plugin_version: latest?.plugin_version ?? validProofs[0]?.plugin_version ?? null,\n manifest_sha256: latest?.manifest_sha256 ?? validProofs[0]?.manifest_sha256 ?? null,\n recorded_at: latest?.recorded_at ?? null,\n activation_id: activationId,\n events,\n missing_events: missingEvents,\n };\n}\n\nfunction staleHookObservation(\n proofs: (CodexHookProofV2 | CodexHookProofV3)[],\n activationId: string | null,\n): CodexHookProofObservation {\n return {\n status: 'stale',\n plugin_version: proofs[0]?.plugin_version ?? null,\n manifest_sha256: proofs[0]?.manifest_sha256 ?? null,\n recorded_at: null,\n activation_id: activationId,\n events: [],\n missing_events: CODEX_PLUGIN_HOOK_EVENTS,\n };\n}\n\nfunction malformedObservation(): CodexHookProofObservation {\n return {\n status: 'malformed',\n plugin_version: null,\n manifest_sha256: null,\n recorded_at: null,\n activation_id: null,\n events: [],\n missing_events: CODEX_PLUGIN_HOOK_EVENTS,\n };\n}\n\n/*\n Each manifest entry is trusted independently by Codex, so finalization proof\n is intentionally one file per event. Separate files also avoid concurrent\n hook processes racing on a shared read-modify-write document.\n*/\n\n// eslint-disable-next-line complexity -- validates every field of two persisted proof schema versions\nfunction isCodexHookProof(value: unknown): value is CodexHookProofV2 | CodexHookProofV3 {\n if (typeof value !== 'object' || value === null) return false;\n const proof = value as Record<string, unknown>;\n return (\n (proof.schema_version === 2 || proof.schema_version === 3) &&\n isCodexPluginHookEvent(proof.event) &&\n pluginVersionIsWellFormed(proof.plugin_version) &&\n typeof proof.manifest_sha256 === 'string' &&\n SHA256_PATTERN.test(proof.manifest_sha256) &&\n 'activation_id' in proof &&\n (typeof proof.activation_id === 'string' || proof.activation_id === null) &&\n (proof.schema_version !== 3 ||\n (typeof proof.project_directory === 'string' &&\n typeof proof.session_id === 'string' &&\n proof.session_id.trim() !== '')) &&\n typeof proof.recorded_at === 'string' &&\n !Number.isNaN(Date.parse(proof.recorded_at))\n );\n}\n\n// eslint-disable-next-line complexity -- validates each untrusted persisted marker field\nfunction isActivationMarkerV2(value: unknown): value is CodexActivationMarkerV2 {\n if (typeof value !== 'object' || value === null) return false;\n const marker = value as Partial<CodexActivationMarkerV2>;\n return (\n marker.schema_version === 2 &&\n pluginVersionIsWellFormed(marker.plugin_version) &&\n typeof marker.manifest_sha256 === 'string' &&\n SHA256_PATTERN.test(marker.manifest_sha256) &&\n typeof marker.activation_id === 'string' &&\n typeof marker.installed_at === 'string' &&\n !Number.isNaN(Date.parse(marker.installed_at)) &&\n (marker.host_observation === 'observed' || marker.host_observation === 'unavailable') &&\n Array.isArray(marker.active_hosts) &&\n marker.active_hosts.every(isCodexHostProcessIdentity) &&\n (marker.host_observation === 'observed'\n ? marker.active_hosts.length > 0\n : marker.active_hosts.length === 0)\n );\n}\n\nfunction isActivationReceiptV1(value: unknown): value is CodexActivationReceiptV1 {\n if (typeof value !== 'object' || value === null) return false;\n const receipt = value as Partial<CodexActivationReceiptV1>;\n return (\n receipt.schema_version === 1 &&\n pluginVersionIsWellFormed(receipt.plugin_version) &&\n typeof receipt.manifest_sha256 === 'string' &&\n SHA256_PATTERN.test(receipt.manifest_sha256) &&\n typeof receipt.activation_id === 'string' &&\n typeof receipt.activated_at === 'string' &&\n !Number.isNaN(Date.parse(receipt.activated_at)) &&\n isCodexHostProcessIdentity(receipt.host)\n );\n}\n\nfunction isCodexHostProcessIdentity(value: unknown): value is CodexHostProcessIdentity {\n if (typeof value !== 'object' || value === null) return false;\n const host = value as Partial<CodexHostProcessIdentity>;\n return (\n Number.isSafeInteger(host.pid) &&\n (host.pid ?? 0) > 0 &&\n typeof host.started_at === 'string' &&\n !Number.isNaN(Date.parse(host.started_at))\n );\n}\n\nfunction isCodexPluginHookEvent(value: unknown): value is CodexPluginHookEvent {\n return (\n typeof value === 'string' && CODEX_PLUGIN_HOOK_EVENTS.includes(value as CodexPluginHookEvent)\n );\n}\n","/* eslint-disable unicorn/no-null -- host observations use explicit null when ancestry is unavailable */\n\nimport { spawnSync } from 'node:child_process';\n\nexport interface CodexHostProcessIdentity {\n pid: number;\n started_at: string;\n}\n\ninterface ProcessRow extends CodexHostProcessIdentity {\n parentPid: number;\n command: string;\n}\n\nexport interface CodexHostProcessObservation {\n available: boolean;\n running: CodexHostProcessIdentity[];\n current: CodexHostProcessIdentity | null;\n}\n\nconst WINDOWS_PROCESS_COMMAND =\n 'Get-CimInstance Win32_Process | ForEach-Object { $started = [DateTimeOffset]$_.CreationDate; Write-Output (\"{0}`t{1}`t{2}`t{3}\" -f $_.ProcessId, $_.ParentProcessId, $started.ToUnixTimeMilliseconds(), $_.CommandLine) }';\n\nfunction parseProcessRows(output: string): ProcessRow[] {\n return output.split('\\n').flatMap(line => {\n const columns = line.trim().split(/\\s+/u);\n if (columns.length < 8) return [];\n const pid = Number(columns[0]);\n const parentPid = Number(columns[1]);\n if (!Number.isSafeInteger(pid) || !Number.isSafeInteger(parentPid)) return [];\n const startedAt = new Date(columns.slice(2, 7).join(' '));\n if (Number.isNaN(startedAt.getTime())) return [];\n return [\n {\n pid,\n parentPid,\n started_at: startedAt.toISOString(),\n command: columns.slice(7).join(' '),\n },\n ];\n });\n}\n\nfunction parseWindowsProcessRows(output: string): ProcessRow[] {\n return output.split('\\n').flatMap(line => {\n const [pidText, parentPidText, startedAtText, ...command] = line.trimEnd().split('\\t');\n const pid = Number(pidText);\n const parentPid = Number(parentPidText);\n const startedAt = new Date(Number(startedAtText));\n if (!Number.isSafeInteger(pid) || !Number.isSafeInteger(parentPid) || command.length === 0)\n return [];\n if (Number.isNaN(startedAt.getTime())) return [];\n return [\n {\n pid,\n parentPid,\n started_at: startedAt.toISOString(),\n command: command.join('\\t'),\n },\n ];\n });\n}\n\nfunction isCodexAppServer(row: ProcessRow): boolean {\n const command = row.command.replaceAll('\\\\', '/');\n return (\n /(?:^|\\/)codex(?:\\.exe)?[\"']?\\s/iu.test(command) && /(?:^|\\s)app-server(?:\\s|$)/u.test(command)\n );\n}\n\nexport function codexHostsFromProcessTable(\n output: string,\n parentPid: number,\n format: 'posix' | 'windows' = 'posix',\n): CodexHostProcessObservation {\n const rows = format === 'windows' ? parseWindowsProcessRows(output) : parseProcessRows(output);\n const running = rows\n .filter(row => isCodexAppServer(row))\n .map(({ pid, started_at }) => ({ pid, started_at }));\n const byPid = new Map(rows.map(row => [row.pid, row]));\n let candidate = byPid.get(parentPid);\n const visited = new Set<number>();\n while (candidate !== undefined && !visited.has(candidate.pid)) {\n if (isCodexAppServer(candidate)) {\n return {\n available: true,\n running,\n current: { pid: candidate.pid, started_at: candidate.started_at },\n };\n }\n visited.add(candidate.pid);\n candidate = byPid.get(candidate.parentPid);\n }\n return { available: true, running, current: null };\n}\n\nexport function observeCodexHostProcesses(): CodexHostProcessObservation {\n if (process.platform === 'win32') {\n const result = spawnSync(\n 'powershell.exe',\n ['-NoProfile', '-NonInteractive', '-Command', WINDOWS_PROCESS_COMMAND],\n { encoding: 'utf8', timeout: 2000 },\n );\n if (result.status !== 0) return { available: false, running: [], current: null };\n return codexHostsFromProcessTable(result.stdout, process.ppid, 'windows');\n }\n const result = spawnSync('ps', ['-axo', 'pid=,ppid=,lstart=,command='], {\n encoding: 'utf8',\n timeout: 2000,\n });\n if (result.status !== 0) return { available: false, running: [], current: null };\n return codexHostsFromProcessTable(result.stdout, process.ppid);\n}\n\nexport function observeRunningCodexHosts(): CodexHostProcessIdentity[] | null {\n const observation = observeCodexHostProcesses();\n return observation.available ? observation.running : null;\n}\n\nexport function sameCodexHost(\n left: CodexHostProcessIdentity,\n right: CodexHostProcessIdentity,\n): boolean {\n return left.pid === right.pid && left.started_at === right.started_at;\n}\n"],"mappings":"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","names":["lstatSync","readFileSync","nodePath","result","nodePath","readFileSync","nodePath","lstatSync","readFileSync"]}
|