safeword 0.78.4 → 0.78.6

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.
Files changed (124) hide show
  1. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  2. package/codex-plugin/hooks.json +5 -5
  3. package/dist/{architecture-TCSDEFKH.js → architecture-EYI67W6S.js} +2 -2
  4. package/dist/{architecture-document-L2ADWVMV.js → architecture-document-POY2JD6A.js} +2 -2
  5. package/dist/{architecture-monorepo-NKOQZBEY.js → architecture-monorepo-QHE76WMY.js} +2 -2
  6. package/dist/{boundary-QP2H7C46.js → boundary-WSADIER3.js} +2 -2
  7. package/dist/{chunk-YZ5JGDOV.js → chunk-2AI2HQ7L.js} +7 -7
  8. package/dist/chunk-2AI2HQ7L.js.map +1 -0
  9. package/dist/{chunk-IPTM5VE7.js → chunk-5VNZBVCI.js} +8 -1
  10. package/dist/chunk-5VNZBVCI.js.map +1 -0
  11. package/dist/{chunk-LFC6CMMX.js → chunk-6SAAJTBH.js} +5 -3
  12. package/dist/chunk-6SAAJTBH.js.map +1 -0
  13. package/dist/{chunk-DBXX5K74.js → chunk-F7P4OBBC.js} +2 -2
  14. package/dist/{chunk-LUNHU6Z3.js → chunk-HACUY7Y5.js} +2 -2
  15. package/dist/{chunk-LUNHU6Z3.js.map → chunk-HACUY7Y5.js.map} +1 -1
  16. package/dist/{chunk-GFDINP7M.js → chunk-HFSC7Z5R.js} +2 -2
  17. package/dist/{chunk-KS2ESRQL.js → chunk-MABDUP6D.js} +4 -4
  18. package/dist/{chunk-RQ7RZYNB.js → chunk-O6CZUNZM.js} +2 -2
  19. package/dist/{cleanup-JNLZ7AXA.js → cleanup-OHREIPHP.js} +2 -2
  20. package/dist/{cleanup-command-MFAYNYRW.js → cleanup-command-7VIOIVYQ.js} +2 -2
  21. package/dist/cli.js +67 -67
  22. package/dist/cli.js.map +1 -1
  23. package/dist/{clients-7AJBKEWF.js → clients-A3J24PUD.js} +2 -2
  24. package/dist/{codex-bootstrap-KFNUS63Y.js → codex-bootstrap-AMKZKL7W.js} +10 -9
  25. package/dist/codex-bootstrap-AMKZKL7W.js.map +1 -0
  26. package/dist/{codex-hook-TNMYVOR7.js → codex-hook-54PI57SW.js} +4 -4
  27. package/dist/{codify-RBWBRXQO.js → codify-L3TMN33S.js} +2 -2
  28. package/dist/{commands-4UXHBZFD.js → commands-Q6EI2OQV.js} +12 -12
  29. package/dist/{config-GS7BTZJD.js → config-6VMQBZG7.js} +2 -2
  30. package/dist/{configured-paths-CREUDQF3.js → configured-paths-46JFU2QD.js} +2 -2
  31. package/dist/{contract-42CIWIWV.js → contract-VGEZQMHA.js} +2 -2
  32. package/dist/{coordinator-WOPGWDXK.js → coordinator-J6P7QRCZ.js} +2 -2
  33. package/dist/{corpus-CAFYEMBO.js → corpus-TMBO2ZSE.js} +2 -2
  34. package/dist/{doctor-AZP5D7QP.js → doctor-IPPAQE2B.js} +5 -5
  35. package/dist/{feature-directories-6TLM7Y4H.js → feature-directories-APLFXF4B.js} +2 -2
  36. package/dist/{finalization-AQT3SOP7.js → finalization-OC6CL7HS.js} +2 -2
  37. package/dist/{gh-cli-XCQT5ST7.js → gh-cli-TID7W2BQ.js} +2 -2
  38. package/dist/{github-rest-CXFJ2NFF.js → github-rest-DKX7CH4A.js} +2 -2
  39. package/dist/index.js +1 -1
  40. package/dist/{job-4POTQJZK.js → job-F6V67VEO.js} +2 -2
  41. package/dist/{learning-sync-QVXBOP6J.js → learning-sync-XS77XE4T.js} +2 -2
  42. package/dist/{legacy-global-guidance-CPGUUNJI.js → legacy-global-guidance-RHPESBI6.js} +2 -2
  43. package/dist/{lint-gherkin-LZ45NG4A.js → lint-gherkin-L4NSBOEG.js} +2 -2
  44. package/dist/{operations-ODOA5CDG.js → operations-6II5G2QM.js} +6 -6
  45. package/dist/{output-QTZCFLAY.js → output-56LB2BSK.js} +2 -2
  46. package/dist/{packet-5G6RT2EW.js → packet-ODPLXYD2.js} +2 -2
  47. package/dist/presets/typescript/index.js +1 -1
  48. package/dist/{profile-QGLZNLRU.js → profile-US32OF6J.js} +2 -2
  49. package/dist/{prompt-UCTSCXSS.js → prompt-5ZDHWYE5.js} +2 -2
  50. package/dist/{remove-UQPEXXNP.js → remove-CXZGMTE6.js} +4 -4
  51. package/dist/{retro-ELKR6GHF.js → retro-KSGI53CI.js} +8 -8
  52. package/dist/{retro-draft-spool-M75BTT32.js → retro-draft-spool-HT4EFCZR.js} +2 -2
  53. package/dist/{retro-extract-RA6THOC4.js → retro-extract-QLVKJI4Q.js} +2 -2
  54. package/dist/{review-pr-MN6QESAJ.js → review-pr-XKYDGBWE.js} +2 -2
  55. package/dist/{review-pr-publication-6AVOGWR2.js → review-pr-publication-N2K73Z3I.js} +2 -2
  56. package/dist/{run-JFDGRAH2.js → run-FXER5EE7.js} +2 -2
  57. package/dist/{self-report-5APRPB5P.js → self-report-JCIK3224.js} +2 -2
  58. package/dist/{status-ATFG6Q3K.js → status-GB4BWGKE.js} +2 -2
  59. package/dist/{status-HIQSP3F5.js → status-S6MDXBPT.js} +5 -5
  60. package/dist/{sync-config-XPAJKBRO.js → sync-config-PZFOXXFJ.js} +2 -2
  61. package/dist/{sync-tracker-3E5BWX73.js → sync-tracker-S7P4XD6Z.js} +2 -2
  62. package/dist/{test-execution-VDECX7TO.js → test-execution-7NLV6VDF.js} +2 -2
  63. package/dist/{test-plan-2L7A7UZV.js → test-plan-WTSBM3EL.js} +2 -2
  64. package/dist/{ticket-new-HZKNZ5GO.js → ticket-new-4EA7YPXP.js} +2 -2
  65. package/dist/{ticket-sync-4QJD3KOL.js → ticket-sync-5X2YAME4.js} +2 -2
  66. package/dist/{tracker-map-CFMFIEER.js → tracker-map-2XYCUZMJ.js} +2 -2
  67. package/dist/{tracker-sync-MOPJE6M7.js → tracker-sync-SHYSJZ4R.js} +2 -2
  68. package/package.json +1 -1
  69. package/templates/workflows/remote-tests.yml +119 -0
  70. package/dist/chunk-IPTM5VE7.js.map +0 -1
  71. package/dist/chunk-LFC6CMMX.js.map +0 -1
  72. package/dist/chunk-YZ5JGDOV.js.map +0 -1
  73. package/dist/codex-bootstrap-KFNUS63Y.js.map +0 -1
  74. /package/dist/{architecture-TCSDEFKH.js.map → architecture-EYI67W6S.js.map} +0 -0
  75. /package/dist/{architecture-document-L2ADWVMV.js.map → architecture-document-POY2JD6A.js.map} +0 -0
  76. /package/dist/{architecture-monorepo-NKOQZBEY.js.map → architecture-monorepo-QHE76WMY.js.map} +0 -0
  77. /package/dist/{boundary-QP2H7C46.js.map → boundary-WSADIER3.js.map} +0 -0
  78. /package/dist/{chunk-DBXX5K74.js.map → chunk-F7P4OBBC.js.map} +0 -0
  79. /package/dist/{chunk-GFDINP7M.js.map → chunk-HFSC7Z5R.js.map} +0 -0
  80. /package/dist/{chunk-KS2ESRQL.js.map → chunk-MABDUP6D.js.map} +0 -0
  81. /package/dist/{chunk-RQ7RZYNB.js.map → chunk-O6CZUNZM.js.map} +0 -0
  82. /package/dist/{cleanup-JNLZ7AXA.js.map → cleanup-OHREIPHP.js.map} +0 -0
  83. /package/dist/{cleanup-command-MFAYNYRW.js.map → cleanup-command-7VIOIVYQ.js.map} +0 -0
  84. /package/dist/{clients-7AJBKEWF.js.map → clients-A3J24PUD.js.map} +0 -0
  85. /package/dist/{codex-hook-TNMYVOR7.js.map → codex-hook-54PI57SW.js.map} +0 -0
  86. /package/dist/{codify-RBWBRXQO.js.map → codify-L3TMN33S.js.map} +0 -0
  87. /package/dist/{commands-4UXHBZFD.js.map → commands-Q6EI2OQV.js.map} +0 -0
  88. /package/dist/{config-GS7BTZJD.js.map → config-6VMQBZG7.js.map} +0 -0
  89. /package/dist/{configured-paths-CREUDQF3.js.map → configured-paths-46JFU2QD.js.map} +0 -0
  90. /package/dist/{contract-42CIWIWV.js.map → contract-VGEZQMHA.js.map} +0 -0
  91. /package/dist/{coordinator-WOPGWDXK.js.map → coordinator-J6P7QRCZ.js.map} +0 -0
  92. /package/dist/{corpus-CAFYEMBO.js.map → corpus-TMBO2ZSE.js.map} +0 -0
  93. /package/dist/{doctor-AZP5D7QP.js.map → doctor-IPPAQE2B.js.map} +0 -0
  94. /package/dist/{feature-directories-6TLM7Y4H.js.map → feature-directories-APLFXF4B.js.map} +0 -0
  95. /package/dist/{finalization-AQT3SOP7.js.map → finalization-OC6CL7HS.js.map} +0 -0
  96. /package/dist/{gh-cli-XCQT5ST7.js.map → gh-cli-TID7W2BQ.js.map} +0 -0
  97. /package/dist/{github-rest-CXFJ2NFF.js.map → github-rest-DKX7CH4A.js.map} +0 -0
  98. /package/dist/{job-4POTQJZK.js.map → job-F6V67VEO.js.map} +0 -0
  99. /package/dist/{learning-sync-QVXBOP6J.js.map → learning-sync-XS77XE4T.js.map} +0 -0
  100. /package/dist/{legacy-global-guidance-CPGUUNJI.js.map → legacy-global-guidance-RHPESBI6.js.map} +0 -0
  101. /package/dist/{lint-gherkin-LZ45NG4A.js.map → lint-gherkin-L4NSBOEG.js.map} +0 -0
  102. /package/dist/{operations-ODOA5CDG.js.map → operations-6II5G2QM.js.map} +0 -0
  103. /package/dist/{output-QTZCFLAY.js.map → output-56LB2BSK.js.map} +0 -0
  104. /package/dist/{packet-5G6RT2EW.js.map → packet-ODPLXYD2.js.map} +0 -0
  105. /package/dist/{profile-QGLZNLRU.js.map → profile-US32OF6J.js.map} +0 -0
  106. /package/dist/{prompt-UCTSCXSS.js.map → prompt-5ZDHWYE5.js.map} +0 -0
  107. /package/dist/{remove-UQPEXXNP.js.map → remove-CXZGMTE6.js.map} +0 -0
  108. /package/dist/{retro-ELKR6GHF.js.map → retro-KSGI53CI.js.map} +0 -0
  109. /package/dist/{retro-draft-spool-M75BTT32.js.map → retro-draft-spool-HT4EFCZR.js.map} +0 -0
  110. /package/dist/{retro-extract-RA6THOC4.js.map → retro-extract-QLVKJI4Q.js.map} +0 -0
  111. /package/dist/{review-pr-MN6QESAJ.js.map → review-pr-XKYDGBWE.js.map} +0 -0
  112. /package/dist/{review-pr-publication-6AVOGWR2.js.map → review-pr-publication-N2K73Z3I.js.map} +0 -0
  113. /package/dist/{run-JFDGRAH2.js.map → run-FXER5EE7.js.map} +0 -0
  114. /package/dist/{self-report-5APRPB5P.js.map → self-report-JCIK3224.js.map} +0 -0
  115. /package/dist/{status-ATFG6Q3K.js.map → status-GB4BWGKE.js.map} +0 -0
  116. /package/dist/{status-HIQSP3F5.js.map → status-S6MDXBPT.js.map} +0 -0
  117. /package/dist/{sync-config-XPAJKBRO.js.map → sync-config-PZFOXXFJ.js.map} +0 -0
  118. /package/dist/{sync-tracker-3E5BWX73.js.map → sync-tracker-S7P4XD6Z.js.map} +0 -0
  119. /package/dist/{test-execution-VDECX7TO.js.map → test-execution-7NLV6VDF.js.map} +0 -0
  120. /package/dist/{test-plan-2L7A7UZV.js.map → test-plan-WTSBM3EL.js.map} +0 -0
  121. /package/dist/{ticket-new-HZKNZ5GO.js.map → ticket-new-4EA7YPXP.js.map} +0 -0
  122. /package/dist/{ticket-sync-4QJD3KOL.js.map → ticket-sync-5X2YAME4.js.map} +0 -0
  123. /package/dist/{tracker-map-CFMFIEER.js.map → tracker-map-2XYCUZMJ.js.map} +0 -0
  124. /package/dist/{tracker-sync-MOPJE6M7.js.map → tracker-sync-SHYSJZ4R.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safeword",
3
- "version": "0.78.4",
3
+ "version": "0.78.6",
4
4
  "description": "Safeword workflow guidance and gates for Codex.",
5
5
  "author": {
6
6
  "name": "Arcade AI"
@@ -6,7 +6,7 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "bunx --bun safeword@0.78.4 hook codex session-start --plugin-hook",
9
+ "command": "bunx --bun safeword@0.78.6 hook codex session-start --plugin-hook",
10
10
  "timeout": 120,
11
11
  "statusMessage": "Loading Safeword standing instructions"
12
12
  }
@@ -19,7 +19,7 @@
19
19
  "hooks": [
20
20
  {
21
21
  "type": "command",
22
- "command": "bunx --bun safeword@0.78.4 hook codex pre-tool-use --plugin-hook",
22
+ "command": "bunx --bun safeword@0.78.6 hook codex pre-tool-use --plugin-hook",
23
23
  "timeout": 30,
24
24
  "statusMessage": "Checking Safeword edit gates"
25
25
  }
@@ -32,7 +32,7 @@
32
32
  "hooks": [
33
33
  {
34
34
  "type": "command",
35
- "command": "bunx --bun safeword@0.78.4 hook codex post-tool-use --plugin-hook",
35
+ "command": "bunx --bun safeword@0.78.6 hook codex post-tool-use --plugin-hook",
36
36
  "timeout": 30,
37
37
  "statusMessage": "Surfacing Safeword post-tool context"
38
38
  }
@@ -45,7 +45,7 @@
45
45
  "hooks": [
46
46
  {
47
47
  "type": "command",
48
- "command": "bunx --bun safeword@0.78.4 hook codex user-prompt-submit --plugin-hook",
48
+ "command": "bunx --bun safeword@0.78.6 hook codex user-prompt-submit --plugin-hook",
49
49
  "timeout": 30,
50
50
  "statusMessage": "Checking queued Safeword prompt context"
51
51
  }
@@ -58,7 +58,7 @@
58
58
  "hooks": [
59
59
  {
60
60
  "type": "command",
61
- "command": "bunx --bun safeword@0.78.4 hook codex stop --plugin-hook",
61
+ "command": "bunx --bun safeword@0.78.6 hook codex stop --plugin-hook",
62
62
  "timeout": 600,
63
63
  "statusMessage": "Checking Safeword stop continuation"
64
64
  }
@@ -25,7 +25,7 @@ import {
25
25
  readJson,
26
26
  writeJson
27
27
  } from "./chunk-HF3DXZEA.js";
28
- import "./chunk-LUNHU6Z3.js";
28
+ import "./chunk-HACUY7Y5.js";
29
29
 
30
30
  // src/commands/architecture.ts
31
31
  import { execFileSync } from "child_process";
@@ -650,4 +650,4 @@ export {
650
650
  architectureStage,
651
651
  architectureStaged
652
652
  };
653
- //# sourceMappingURL=architecture-TCSDEFKH.js.map
653
+ //# sourceMappingURL=architecture-EYI67W6S.js.map
@@ -11,7 +11,7 @@ import {
11
11
  import "./chunk-RVDXBHUG.js";
12
12
  import "./chunk-VZ5B2SIO.js";
13
13
  import "./chunk-HF3DXZEA.js";
14
- import "./chunk-LUNHU6Z3.js";
14
+ import "./chunk-HACUY7Y5.js";
15
15
  export {
16
16
  isSafewordOwned,
17
17
  isWouldChangeAction,
@@ -22,4 +22,4 @@ export {
22
22
  selfHealProject,
23
23
  selfHealProjectPreservingProse
24
24
  };
25
- //# sourceMappingURL=architecture-document-L2ADWVMV.js.map
25
+ //# sourceMappingURL=architecture-document-POY2JD6A.js.map
@@ -5,11 +5,11 @@ import {
5
5
  monorepoFingerprintOf
6
6
  } from "./chunk-VZ5B2SIO.js";
7
7
  import "./chunk-HF3DXZEA.js";
8
- import "./chunk-LUNHU6Z3.js";
8
+ import "./chunk-HACUY7Y5.js";
9
9
  export {
10
10
  discoverUnreadableWorkspaces,
11
11
  discoverWorkspaces,
12
12
  extractMonorepoArchitectureSnapshot,
13
13
  monorepoFingerprintOf
14
14
  };
15
- //# sourceMappingURL=architecture-monorepo-NKOQZBEY.js.map
15
+ //# sourceMappingURL=architecture-monorepo-QHE76WMY.js.map
@@ -25,7 +25,7 @@ import {
25
25
  import {
26
26
  readFileSafe
27
27
  } from "./chunk-HF3DXZEA.js";
28
- import "./chunk-LUNHU6Z3.js";
28
+ import "./chunk-HACUY7Y5.js";
29
29
 
30
30
  // src/commands/boundary.ts
31
31
  import { execFileSync as execFileSync2 } from "child_process";
@@ -630,4 +630,4 @@ function boundary(options) {
630
630
  export {
631
631
  boundary
632
632
  };
633
- //# sourceMappingURL=boundary-QP2H7C46.js.map
633
+ //# sourceMappingURL=boundary-WSADIER3.js.map
@@ -4,7 +4,7 @@ import {
4
4
  legacyCommandIdentity,
5
5
  observeCodexHookProof,
6
6
  writeCodexActivationMarker
7
- } from "./chunk-DBXX5K74.js";
7
+ } from "./chunk-F7P4OBBC.js";
8
8
  import {
9
9
  legacyGlobalGuidanceDiagnostic,
10
10
  observeLegacyGlobalGuidance
@@ -25,16 +25,16 @@ import {
25
25
  writeDurableFile
26
26
  } from "./chunk-QOLHGAD5.js";
27
27
  import {
28
- CODEX_RESTART_ACTION,
29
28
  CODEX_RESTART_CONTEXT,
29
+ CODEX_REVIEW_THEN_RESTART_ACTION,
30
30
  codexMigrationExitCode,
31
31
  codexPluginVersionMatchesPackage,
32
32
  deriveCodexMigrationResult,
33
33
  renderCodexMigrationHuman
34
- } from "./chunk-LFC6CMMX.js";
34
+ } from "./chunk-6SAAJTBH.js";
35
35
  import {
36
36
  SAFEWORD_SCHEMA
37
- } from "./chunk-IPTM5VE7.js";
37
+ } from "./chunk-5VNZBVCI.js";
38
38
  import {
39
39
  parse
40
40
  } from "./chunk-JSR3HXFT.js";
@@ -934,7 +934,7 @@ function installCodexPlugin(options = {}) {
934
934
  if (options.json !== true) {
935
935
  success("Safeword Codex plugin is enabled for this profile.");
936
936
  info(
937
- `This Codex app may keep its loaded Safeword catalogue. ${CODEX_RESTART_ACTION} and review the installed skills and hooks with /hooks. If this project uses Safeword legacy hooks, run \`safeword codex migrate --remove-legacy-hooks\` to remove only those hooks.`
937
+ `This Codex app may keep its loaded Safeword catalogue. ${CODEX_REVIEW_THEN_RESTART_ACTION}. If this project uses Safeword legacy hooks, run \`safeword codex migrate --remove-legacy-hooks\` to remove only those hooks.`
938
938
  );
939
939
  }
940
940
  if (options.reportMigrationState === true) {
@@ -983,7 +983,7 @@ name: safeword-plugin-setup
983
983
  description: Restore the Safeword Codex profile plugin for this project.
984
984
  ---
985
985
 
986
- Run \`safeword codex migrate\` to install or re-enable the profile plugin. ${CODEX_RESTART_ACTION} and review its hooks with \`/hooks\`. Run \`safeword codex status\` to verify this project is protected.
986
+ Run \`safeword codex migrate\` to install or re-enable the profile plugin. ${CODEX_REVIEW_THEN_RESTART_ACTION}. Run \`safeword codex status\` to verify this project is protected.
987
987
  `
988
988
  }
989
989
  );
@@ -1238,4 +1238,4 @@ export {
1238
1238
  migrateCodexPlugin,
1239
1239
  recoverCodexMigration
1240
1240
  };
1241
- //# sourceMappingURL=chunk-YZ5JGDOV.js.map
1241
+ //# sourceMappingURL=chunk-2AI2HQ7L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/codex-plugin/operations.ts","../src/codex-plugin/legacy-config.ts","../src/codex-plugin/profile-lock.ts","../src/codex-plugin/project-bootstrap.ts"],"sourcesContent":["/* eslint-disable unicorn/no-null -- Codex migration JSON uses explicit null */\n\nimport { spawnSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { existsSync, lstatSync, readFileSync, type Stats } from 'node:fs';\nimport { homedir } from 'node:os';\nimport nodePath from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport { type CliResult, createResult } from '../cli-protocol/result.js';\nimport { SAFEWORD_SCHEMA } from '../schema.js';\nimport { info, success } from '../utils/output.js';\nimport { compareVersions, isSafePackageVersion } from '../utils/version.js';\nimport {\n applyCodexFinalization,\n codexFinalizationIsComplete,\n type CodexFinalizationMutation,\n codexRecoveryIsRequired,\n recoverCodexFinalization,\n resolveCodexFinalizationConfirmation,\n validateCodexFinalizationPaths,\n} from './finalization.js';\nimport { CODEX_MIGRATION_SCHEMA } from './inventory.js';\nimport { legacyCodexEventIsViable } from './legacy-authority.js';\nimport {\n CodexConfigObservationError,\n observeLegacyEvents,\n type PreparedLegacyHookRemoval,\n prepareLegacyHookRemoval,\n regularCodexConfigMetadata,\n} from './legacy-config.js';\nimport {\n legacyGlobalGuidanceDiagnostic,\n observeLegacyGlobalGuidance,\n} from './legacy-global-guidance.js';\nimport {\n CODEX_RESTART_CONTEXT,\n CODEX_REVIEW_THEN_RESTART_ACTION,\n codexMigrationExitCode,\n type CodexMigrationResultV2,\n type CodexPluginObservation,\n codexPluginVersionMatchesPackage,\n deriveCodexMigrationResult,\n renderCodexMigrationHuman,\n} from './migration.js';\nimport { CodexMigrationError } from './migration-error.js';\nimport { acquireCodexProfileLock, releaseCodexProfileLock } from './profile-lock.js';\nimport {\n codexActivationIsPending,\n type CodexHookProofObservation,\n observeCodexHookProof,\n writeCodexActivationMarker,\n} from './profile-proof.js';\nimport { preparedCodexProjectBootstrap } from './project-bootstrap.js';\n\nexport { codexInstallRequiresMutation } from './migration.js';\n\nconst MARKETPLACE_SOURCE = 'ArcadeAI/safeword';\nconst PLUGIN_ID = 'safeword@safeword';\nconst CODEX_CONFIG_PATH = CODEX_MIGRATION_SCHEMA.paths.config;\ntype CodexPluginList = {\n installed?: {\n enabled?: boolean;\n marketplaceName?: string;\n marketplaceSource?: { sourceType?: string; source?: string };\n pluginId?: string;\n version?: string;\n }[];\n};\ntype CodexMarketplaceList = {\n marketplaces: {\n name?: string;\n marketplaceSource?: { sourceType?: string; source?: string };\n }[];\n};\n\nfunction run(command: string, arguments_: string[]): string {\n const result = spawnSync(command, arguments_, { encoding: 'utf8' });\n if (result.error)\n throw new Error(`${command} is required. Install it, then re-run this command.`);\n if (result.status !== 0) {\n const detail = (result.stderr || result.stdout).trim();\n throw new Error(detail || `${command} ${arguments_.join(' ')} failed.`);\n }\n return result.stdout;\n}\n\nfunction pluginObservationFromList(output: string): CodexPluginObservation {\n const parsed = JSON.parse(output) as CodexPluginList;\n const plugin = parsed.installed?.find(candidate => candidate.pluginId === PLUGIN_ID);\n return {\n installed: plugin !== undefined,\n enabled: plugin?.enabled ?? (plugin === undefined ? false : null),\n version: plugin?.version ?? null,\n observation: 'observed',\n };\n}\n\nfunction isOfficialSafewordGitSource(source: string | undefined): boolean {\n if (source === undefined) return false;\n const normalized = source\n .toLowerCase()\n .replace(/\\/$/u, '')\n .replace(/\\.git$/u, '');\n return new Set([\n 'arcadeai/safeword',\n 'git@github.com:arcadeai/safeword',\n 'https://github.com/arcadeai/safeword',\n 'ssh://git@github.com/arcadeai/safeword',\n ]).has(normalized);\n}\n\nfunction observeCodexPlugin(): CodexPluginObservation {\n return pluginObservationFromList(run('codex', ['plugin', 'list', '--json']));\n}\n\nfunction marketplaceListFromOutput(output: string): CodexMarketplaceList {\n let parsed: unknown;\n try {\n parsed = JSON.parse(output);\n } catch (error) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n 'Codex returned malformed marketplace discovery JSON; plugin installation did not run.',\n { cause: error },\n );\n }\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n !Array.isArray((parsed as Partial<CodexMarketplaceList>).marketplaces) ||\n !(parsed as Partial<CodexMarketplaceList>).marketplaces?.every(\n marketplace => typeof marketplace === 'object' && marketplace !== null,\n )\n ) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n 'Codex returned an unsupported marketplace discovery result; plugin installation did not run.',\n );\n }\n return parsed as CodexMarketplaceList;\n}\n\nfunction runCodexMarketplace(arguments_: string[], failureContext: string): string {\n try {\n return run('codex', ['plugin', 'marketplace', ...arguments_]);\n } catch (error) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n `${failureContext}; plugin installation did not run: ${String(error)}`,\n { cause: error },\n );\n }\n}\n\ninterface ConfiguredMarketplace {\n ref?: string;\n source?: string;\n}\n\nfunction configuredSafewordMarketplace(\n environment: NodeJS.ProcessEnv = process.env,\n): ConfiguredMarketplace | undefined {\n const configPath = nodePath.join(\n environment.CODEX_HOME ?? nodePath.join(homedir(), '.codex'),\n 'config.toml',\n );\n if (!existsSync(configPath)) return;\n try {\n const document = parse(readFileSync(configPath, 'utf8')) as {\n marketplaces?: { safeword?: ConfiguredMarketplace };\n };\n return document.marketplaces?.safeword;\n } catch (error) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n 'The Codex profile configuration is invalid TOML; the Safeword marketplace was not changed.',\n { cause: error },\n );\n }\n}\n\nfunction marketplaceAddArguments(source: string, ref: string, includeJson = true): string[] {\n const args = [\n 'add',\n source,\n '--ref',\n ref,\n '--sparse',\n '.agents/plugins',\n '--sparse',\n 'packages/cli/codex-plugin',\n ];\n return includeJson ? [...args, '--json'] : args;\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"'\\\"'\\\"'\")}'`;\n}\n\nfunction exactVersionReference(ref: string): string | undefined {\n const version = ref.startsWith('v') ? ref.slice(1) : ref;\n return isSafePackageVersion(version) ? version : undefined;\n}\n\nfunction replaceCodexMarketplaceWithStable(configured: ConfiguredMarketplace): void {\n const source = configured.source ?? MARKETPLACE_SOURCE;\n runCodexMarketplace(\n ['remove', 'safeword', '--json'],\n 'Could not replace the Safeword marketplace',\n );\n try {\n runCodexMarketplace(\n marketplaceAddArguments(MARKETPLACE_SOURCE, 'stable'),\n 'Could not enroll the Safeword stable marketplace channel',\n );\n } catch (error) {\n try {\n runCodexMarketplace(\n marketplaceAddArguments(source, configured.ref ?? 'main'),\n 'Could not restore the previous Safeword marketplace after stable enrollment failed',\n );\n } catch (restorationError) {\n const restoreCommand = [\n 'codex',\n 'plugin',\n 'marketplace',\n ...marketplaceAddArguments(source, configured.ref ?? 'main', false),\n ]\n .map(argument => shellQuote(argument))\n .join(' ');\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n `Stable marketplace enrollment failed and the previous Safeword marketplace could not be restored. The profile no longer has that marketplace; restore it with \\`${restoreCommand}\\`. Stable error: ${String(error)}. Restore error: ${String(restorationError)}`,\n { cause: error, profileChanged: true, recoveryCommand: restoreCommand },\n );\n }\n throw error;\n }\n}\n\nfunction assertMarketplacePinIsNotNewer(\n ref: string | undefined,\n pinnedVersion: string | undefined,\n): void {\n if (pinnedVersion === undefined || compareVersions(pinnedVersion, SAFEWORD_SCHEMA.version) <= 0) {\n return;\n }\n throw new CodexMigrationError(\n 'PLUGIN_NEWER_PIN_PRESERVED',\n `Codex is pinned to newer Safeword ${ref}; Safeword left that explicit profile pin unchanged.`,\n );\n}\n\nfunction refreshOfficialGitMarketplace(\n marketplace: CodexMarketplaceList['marketplaces'][number],\n environment: NodeJS.ProcessEnv,\n): void {\n const source = marketplace.marketplaceSource?.source;\n if (!isOfficialSafewordGitSource(source)) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n `The configured Codex marketplace named safeword does not point to ${MARKETPLACE_SOURCE}; plugin installation did not run.`,\n );\n }\n const configured = configuredSafewordMarketplace(environment);\n const ref = configured?.ref;\n const pinnedVersion = ref === undefined ? undefined : exactVersionReference(ref);\n assertMarketplacePinIsNotNewer(ref, pinnedVersion);\n if (ref === 'main' || pinnedVersion !== undefined) {\n replaceCodexMarketplaceWithStable({ ...configured, source: configured?.source ?? source });\n return;\n }\n runCodexMarketplace(\n ['upgrade', 'safeword', '--json'],\n 'Could not refresh the configured Safeword Codex marketplace',\n );\n}\n\nfunction refreshOrAddCodexMarketplace(\n marketplaceSource: string | undefined,\n environment: NodeJS.ProcessEnv = process.env,\n): void {\n if (marketplaceSource === undefined) {\n const output = runCodexMarketplace(\n ['list', '--json'],\n 'Could not inspect configured Codex marketplaces',\n );\n const marketplace = marketplaceListFromOutput(output).marketplaces.find(\n candidate => candidate.name === 'safeword',\n );\n if (marketplace?.marketplaceSource?.sourceType === 'git') {\n refreshOfficialGitMarketplace(marketplace, environment);\n return;\n }\n if (marketplace !== undefined) {\n throw new CodexMigrationError(\n 'PLUGIN_MARKETPLACE_FAILED',\n 'The configured Codex marketplace named safeword is not a Git marketplace. Safeword left it unchanged because replacing an unknown marketplace type is not safely reversible.',\n );\n }\n }\n\n runCodexMarketplace(\n [\n 'add',\n marketplaceSource ?? MARKETPLACE_SOURCE,\n ...(marketplaceSource === undefined ? ['--ref', 'stable'] : []),\n '--sparse',\n '.agents/plugins',\n '--sparse',\n 'packages/cli/codex-plugin',\n '--json',\n ],\n 'Could not add the Safeword Codex marketplace',\n );\n}\n\nfunction addCodexPluginToProfile(\n marketplaceSource: string | undefined,\n environment: NodeJS.ProcessEnv = process.env,\n): void {\n refreshOrAddCodexMarketplace(marketplaceSource, environment);\n run('codex', ['plugin', 'add', PLUGIN_ID, '--json']);\n}\n\nfunction verifyCodexPluginIsEnabled(options: { installationCompleted?: boolean } = {}): void {\n let pluginList: string;\n try {\n pluginList = run('codex', ['plugin', 'list', '--json']);\n } catch (error) {\n const prefix =\n options.installationCompleted === true\n ? 'Plugin installation succeeded, but enablement is unknown'\n : 'Could not verify the Safeword Codex plugin';\n throw new CodexMigrationError(\n options.installationCompleted === true\n ? 'PLUGIN_ENABLEMENT_UNKNOWN'\n : 'PLUGIN_ENABLEMENT_FAILED',\n `${prefix}: ${String(error)}`,\n { cause: error },\n );\n }\n const plugin = pluginObservationFromList(pluginList);\n if (plugin.enabled !== true) {\n throw new CodexMigrationError(\n 'PLUGIN_ENABLEMENT_FAILED',\n 'Codex did not report the Safeword plugin as enabled. Enable safeword@safeword, then re-run this command; project hooks were left unchanged.',\n );\n }\n if (plugin.version !== null && plugin.version !== SAFEWORD_SCHEMA.version) {\n throw new CodexMigrationError(\n 'PLUGIN_ENABLEMENT_FAILED',\n `Codex reported Safeword plugin ${plugin.version}, but ${SAFEWORD_SCHEMA.version} is required. Re-run safeword install --agents=codex to update it; project hooks were left unchanged.`,\n { profileChanged: options.installationCompleted === true },\n );\n }\n}\n\nfunction pathExistsIncludingDanglingSymlink(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT' || code === 'ENOTDIR') return false;\n throw error;\n }\n}\n\nfunction observeLegacyAssets(cwd: string): string[] {\n return SAFEWORD_SCHEMA.codexMigration.cleanupFiles.filter(path =>\n pathExistsIncludingDanglingSymlink(nodePath.join(cwd, path)),\n );\n}\n\nfunction observeViableLegacyEvents(\n cwd: string,\n legacyEvents: string[],\n environment: NodeJS.ProcessEnv,\n): string[] {\n const eventIdsByName = new Map(\n Object.entries(SAFEWORD_SCHEMA.codexMigration.hookEventNames).map(([event, name]) => [\n name,\n event,\n ]),\n );\n return legacyEvents.filter(eventName => {\n const event = eventIdsByName.get(eventName);\n return event !== undefined && legacyCodexEventIsViable(cwd, event, environment);\n });\n}\n\nexport function observeCodexMigrationResult(\n cwd = process.cwd(),\n environment: NodeJS.ProcessEnv = process.env,\n): CodexMigrationResultV2 {\n let legacyEvents: string[] = [];\n let configObservationError: CodexConfigObservationError | undefined;\n try {\n legacyEvents = observeLegacyEvents(cwd);\n } catch (error) {\n if (!(error instanceof CodexConfigObservationError)) throw error;\n configObservationError = error;\n }\n const recoveryRequired = codexRecoveryIsRequired(cwd);\n let plugin: CodexPluginObservation;\n let pluginObservationError: Error | undefined;\n if (recoveryRequired) {\n plugin = { installed: false, enabled: null, version: null, observation: 'unknown' };\n } else {\n try {\n plugin = observeCodexPlugin();\n } catch (error) {\n plugin = { installed: false, enabled: null, version: null, observation: 'unknown' };\n pluginObservationError = error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = deriveCodexMigrationResult({\n plugin,\n proof: observeCodexHookProof(environment),\n legacyAssets: observeLegacyAssets(cwd),\n legacyEvents,\n viableLegacyEvents: observeViableLegacyEvents(cwd, legacyEvents, environment),\n finalized: codexFinalizationIsComplete(cwd),\n recoveryRequired,\n activationPending: codexActivationIsPending(environment),\n });\n if (pluginObservationError !== undefined) {\n result.errors.push({\n code: 'PLUGIN_OBSERVATION_FAILED',\n message: pluginObservationError.message,\n retryable: true,\n });\n }\n if (configObservationError !== undefined) {\n result.errors.push({\n code: 'CODEX_CONFIG_UNREADABLE',\n message: configObservationError.message,\n retryable: false,\n });\n }\n return result;\n}\n\nconst CODEX_MIGRATION_MESSAGES: Partial<Readonly<Record<CodexMigrationResultV2['state'], string>>> =\n {\n plugin_installed_app_restart_required: CODEX_RESTART_CONTEXT,\n compatibility:\n 'Codex is protected by the current profile plugin; verified legacy protection remains until explicit finalization.',\n plugin_enabled_hook_unproven:\n 'Codex migration state: plugin_enabled_hook_unproven. Review /hooks in the restarted Codex app; when protection is confirmed, run safeword codex migrate --finalize.',\n recovery_required:\n 'Codex migration state: recovery_required. Recovery is required before migration can continue.',\n };\n\nfunction codexMigrationMessage(\n state: CodexMigrationResultV2['state'],\n proof?: CodexHookProofObservation,\n): string {\n if (state === 'plugin_enabled_hook_unproven' && proof !== undefined) {\n return `Codex migration state: plugin_enabled_hook_unproven. In the restarted Codex app, review /hooks and exercise these missing hooks: ${proof.missing_events.join(', ')}. Then run safeword codex migrate --finalize.`;\n }\n return CODEX_MIGRATION_MESSAGES[state] ?? `Codex migration state: ${state}.`;\n}\n\nfunction legacyCodexMigrationState(\n state: CodexMigrationResultV2['state'],\n): CodexMigrationResultV2['state'] | 'plugin_installed_restart_required' {\n return state === 'plugin_installed_app_restart_required'\n ? 'plugin_installed_restart_required'\n : state;\n}\n\nexport function observeCodexMigration(\n cwd = process.cwd(),\n environment: NodeJS.ProcessEnv = process.env,\n): CliResult {\n const result = observeCodexMigrationResult(cwd, environment);\n const legacyState = legacyCodexMigrationState(result.state);\n const globalGuidance = legacyGlobalGuidanceDiagnostic(observeLegacyGlobalGuidance(environment));\n let state: CliResult['state'] = 'action_required';\n if (result.errors.length > 0) state = 'failed';\n else if (result.ok && globalGuidance.finding === undefined) state = 'healthy';\n return createResult({\n state,\n findings:\n result.errors.length > 0\n ? []\n : [\n {\n code: `CODEX_${legacyState.toUpperCase()}`,\n message: codexMigrationMessage(result.state, result.proof),\n severity: result.ok ? 'info' : 'warning',\n metadata: {\n migration_schema_version: result.schema_version,\n migration_state: result.state,\n },\n },\n ...(globalGuidance.finding === undefined ? [] : [globalGuidance.finding]),\n ],\n errors: result.errors,\n nextActions: [\n ...result.next_actions.map(action =>\n 'command' in action\n ? {\n command: action.command,\n mutates: action.mutates,\n requiresHuman: action.requires_human,\n }\n : {\n kind: action.kind,\n instruction: action.instruction,\n mutates: action.mutates,\n requiresHuman: action.requires_human,\n },\n ),\n ...(globalGuidance.nextAction === undefined ? [] : [globalGuidance.nextAction]),\n ],\n data: {\n command: 'codex status',\n // Compatibility field for schema-1 public-envelope consumers. New code\n // reads the explicitly versioned `migration` object below.\n migration_state: legacyState,\n migration: {\n schema_version: result.schema_version,\n state: result.state,\n },\n protected: result.protected,\n plugin: result.plugin,\n proof: result.proof,\n legacy: result.legacy,\n global_guidance: globalGuidance.observation,\n },\n });\n}\n\nfunction reportCodexMigration(\n cwd: string,\n options: {\n json?: boolean;\n environment?: NodeJS.ProcessEnv;\n changed?: boolean;\n effects?: CodexMigrationResultV2['effects']['files'];\n },\n): void {\n const result = observeCodexMigrationResult(cwd, options.environment);\n result.changed = options.changed === true;\n if (options.effects !== undefined) result.effects.files = options.effects;\n process.stdout.write(\n options.json === true ? `${JSON.stringify(result)}\\n` : renderCodexMigrationHuman(result),\n );\n process.exitCode = codexMigrationExitCode(result);\n}\n\nexport function installCodexPlugin(\n // The CLI always uses MARKETPLACE_SOURCE. The source override lets the live\n // test validate a pushed release branch before its marketplace reaches main.\n options: {\n marketplaceSource?: string;\n reportMigrationState?: boolean;\n recordActivationPending?: boolean;\n json?: boolean;\n cwd?: string;\n environment?: NodeJS.ProcessEnv;\n } = {},\n): void {\n const cwd = options.cwd ?? process.cwd();\n if (shouldReportExistingMigrationState(cwd, options)) {\n reportCodexMigration(cwd, { json: options.json, environment: options.environment });\n return;\n }\n const lock = acquireCodexProfileLock(options.environment);\n if (lock === undefined) {\n throw new CodexMigrationError(\n 'PLUGIN_PROFILE_BUSY',\n 'Another Safeword task is updating this Codex profile. No profile changes were made; retry `safeword codex install` in a moment.',\n );\n }\n try {\n run('bun', ['--version']);\n run('codex', ['--version']);\n addCodexPluginToProfile(options.marketplaceSource, options.environment);\n verifyCodexPluginIsEnabled({ installationCompleted: true });\n if (options.recordActivationPending !== false) writeCodexActivationMarker(options.environment);\n } finally {\n releaseCodexProfileLock(lock);\n }\n\n if (options.json !== true) {\n success('Safeword Codex plugin is enabled for this profile.');\n info(\n `This Codex app may keep its loaded Safeword catalogue. ${CODEX_REVIEW_THEN_RESTART_ACTION}. If this project uses Safeword legacy hooks, run \\`safeword codex migrate --remove-legacy-hooks\\` to remove only those hooks.`,\n );\n }\n if (options.reportMigrationState === true) {\n reportCodexMigration(cwd, {\n json: options.json,\n environment: options.environment,\n changed: true,\n });\n }\n}\n\nfunction shouldReportExistingMigrationState(\n cwd: string,\n options: {\n reportMigrationState?: boolean;\n environment?: NodeJS.ProcessEnv;\n },\n): boolean {\n if (codexRecoveryIsRequired(cwd)) return true;\n if (options.reportMigrationState !== true) return false;\n const plugin = observeCodexMigrationResult(cwd, options.environment).plugin;\n return plugin.enabled === true && codexPluginVersionMatchesPackage(plugin);\n}\n\nfunction buildCodexFinalizationMutations(\n cwd: string,\n preparedLegacyHookRemoval: PreparedLegacyHookRemoval | undefined,\n): CodexFinalizationMutation[] {\n const mutations: CodexFinalizationMutation[] = [];\n let configBase: string | undefined;\n if (preparedLegacyHookRemoval !== undefined) {\n if (\n regularCodexConfigMetadata(preparedLegacyHookRemoval.configPath).kind === 'missing' ||\n readFileSync(preparedLegacyHookRemoval.configPath, 'utf8') !==\n preparedLegacyHookRemoval.original\n ) {\n throw new Error(\n 'Codex configuration changed during plugin verification; no legacy hooks were removed.',\n );\n }\n configBase = preparedLegacyHookRemoval.cleaned;\n }\n const configPath = nodePath.join(cwd, CODEX_CONFIG_PATH);\n const configMetadata = regularCodexConfigMetadata(configPath);\n const originalConfig = configMetadata.kind === 'missing' ? '' : readFileSync(configPath, 'utf8');\n const bootstrappedConfig = preparedCodexProjectBootstrap(cwd, configBase);\n if (bootstrappedConfig !== originalConfig) {\n mutations.push({ path: CODEX_CONFIG_PATH, content: bootstrappedConfig });\n }\n for (const path of observeLegacyAssets(cwd)) mutations.push({ path, content: null });\n mutations.push(\n {\n path: CODEX_MIGRATION_SCHEMA.paths.pluginMarker,\n content: `${JSON.stringify({ schema_version: 1, mode: 'plugin' })}\\n`,\n },\n {\n path: CODEX_MIGRATION_SCHEMA.paths.bootstrapSkill,\n content: `---\\nname: safeword-plugin-setup\\ndescription: Restore the Safeword Codex profile plugin for this project.\\n---\\n\\nRun \\`safeword codex migrate\\` to install or re-enable the profile plugin. ${CODEX_REVIEW_THEN_RESTART_ACTION}. Run \\`safeword codex status\\` to verify this project is protected.\\n`,\n },\n );\n return mutations;\n}\n\nfunction finalizationEffects(\n cwd: string,\n mutations: CodexFinalizationMutation[],\n): CodexMigrationResultV2['effects']['files'] {\n return mutations.map(mutation => {\n let action: 'create' | 'update' | 'remove';\n if (mutation.content === null) action = 'remove';\n else if (pathExistsIncludingDanglingSymlink(nodePath.join(cwd, mutation.path)))\n action = 'update';\n else action = 'create';\n return { path: mutation.path, action };\n });\n}\n\nexport function uninstallCodexPlugin(): CliResult {\n try {\n if (!observeCodexPlugin().installed) {\n return createResult({\n state: 'healthy',\n data: { command: 'codex uninstall', plugin: PLUGIN_ID },\n });\n }\n run('codex', ['plugin', 'remove', PLUGIN_ID, '--json']);\n if (observeCodexPlugin().installed) {\n throw new Error(`Codex still reports ${PLUGIN_ID} after uninstall.`);\n }\n return createResult({\n state: 'changed',\n effects: {\n destructive: [{ kind: 'remove', target: PLUGIN_ID, operation: 'profile' }],\n },\n recovery: [\n {\n command: 'safeword install --agents=codex',\n description: 'Reinstall the Codex profile plugin if this removal must be reversed.',\n requiresHuman: true,\n },\n ],\n data: { command: 'codex uninstall', plugin: PLUGIN_ID },\n });\n } catch (error) {\n return createResult({\n state: 'failed',\n errors: [\n {\n code: 'CODEX_PLUGIN_UNINSTALL_FAILED',\n message: error instanceof Error ? error.message : String(error),\n retryable: true,\n },\n ],\n recovery: [\n {\n command: 'safeword install --agents=codex',\n description: 'Repair or restore the Codex profile plugin.',\n requiresHuman: true,\n },\n ],\n data: { command: 'codex uninstall', plugin: PLUGIN_ID },\n });\n }\n}\n\nexport function observeCodexFinalizationEffects(\n cwd: string,\n): CodexMigrationResultV2['effects']['files'] {\n return observeCodexFinalizationPlan(cwd).effects;\n}\n\nfunction renderCodexFinalizationPlan(\n cwd: string,\n mutations: CodexFinalizationMutation[],\n preparedLegacyHookRemoval: PreparedLegacyHookRemoval | undefined,\n): string {\n const lines = ['Finalization plan:'];\n for (const effect of finalizationEffects(cwd, mutations)) {\n lines.push(`- ${effect.action} ${effect.path}`);\n if (effect.path !== CODEX_CONFIG_PATH || preparedLegacyHookRemoval === undefined) continue;\n for (const block of preparedLegacyHookRemoval.removedBlocks) {\n lines.push(\n ' exact config block:',\n ' --- begin block ---',\n block.trimEnd(),\n ' --- end block ---',\n );\n }\n }\n return `${lines.join('\\n')}\\n`;\n}\n\ntype FinalizationInputSnapshot = {\n path: string;\n state: 'absent' | 'file';\n mode?: number;\n content?: string;\n}[];\n\nexport interface ObservedCodexFinalizationPlan {\n readonly effects: CodexMigrationResultV2['effects']['files'];\n readonly exactConfigBlocks: readonly string[];\n readonly preconditionDigest: string;\n}\n\nfunction snapshotCodexFinalizationInputs(\n cwd: string,\n mutations: CodexFinalizationMutation[],\n): FinalizationInputSnapshot {\n validateCodexFinalizationPaths(cwd, mutations);\n return mutations.map(mutation => {\n const path = nodePath.join(cwd, mutation.path);\n let metadata: Stats;\n try {\n metadata = lstatSync(path);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { path: mutation.path, state: 'absent' };\n }\n throw error;\n }\n if (!metadata.isFile()) {\n throw new Error(`Unsafe Codex migration path is not a regular file: ${mutation.path}`);\n }\n return {\n path: mutation.path,\n state: 'file',\n mode: metadata.mode & 0o777,\n content: readFileSync(path).toString('base64'),\n };\n });\n}\n\nexport function observeCodexFinalizationPlan(cwd: string): ObservedCodexFinalizationPlan {\n const prepared = prepareLegacyHookRemoval(cwd);\n const mutations = buildCodexFinalizationMutations(cwd, prepared);\n const effects = finalizationEffects(cwd, mutations);\n const inputs = snapshotCodexFinalizationInputs(cwd, mutations);\n const preconditionDigest = createHash('sha256')\n .update(JSON.stringify({ mutations, effects, inputs }))\n .digest('hex');\n return {\n effects,\n exactConfigBlocks: prepared?.removedBlocks ?? [],\n preconditionDigest,\n };\n}\n\nfunction assertCodexFinalizationPlanUnchanged(\n cwd: string,\n preparedLegacyHookRemoval: PreparedLegacyHookRemoval | undefined,\n mutations: CodexFinalizationMutation[],\n effects: CodexMigrationResultV2['effects']['files'],\n inputs: FinalizationInputSnapshot,\n): void {\n const currentMutations = buildCodexFinalizationMutations(cwd, preparedLegacyHookRemoval);\n const currentEffects = finalizationEffects(cwd, currentMutations);\n if (\n JSON.stringify(currentMutations) !== JSON.stringify(mutations) ||\n JSON.stringify(currentEffects) !== JSON.stringify(effects) ||\n JSON.stringify(snapshotCodexFinalizationInputs(cwd, mutations)) !== JSON.stringify(inputs)\n ) {\n throw new CodexMigrationError(\n 'PLAN_STALE',\n 'Codex finalization plan changed after confirmation; no repository files were modified.',\n );\n }\n}\n\nfunction reportCompletedFinalization(\n cwd: string,\n options: { json?: boolean; environment?: NodeJS.ProcessEnv },\n): void {\n if (options.json === true) reportCodexMigration(cwd, options);\n else success('Safeword Codex migration is already finalized.');\n}\n\nfunction reportAppliedFinalization(\n cwd: string,\n input: {\n options: { json?: boolean; environment?: NodeJS.ProcessEnv };\n effects: CodexMigrationResultV2['effects']['files'];\n removedLegacyHooks: boolean;\n },\n): void {\n if (input.options.json === true) {\n reportCodexMigration(cwd, {\n ...input.options,\n changed: true,\n effects: input.effects,\n });\n return;\n }\n info('Backed up the complete legacy Codex state for conflict-safe recovery.');\n info(\n input.removedLegacyHooks\n ? 'Removed Safeword legacy Codex project protection after the verified plugin handoff.'\n : 'No Safeword legacy Codex hooks were found in this project.',\n );\n}\n\nfunction reportCodexWhen(enabled: boolean, report: () => void): void {\n if (enabled) report();\n}\n\nexport async function removeLegacyCodexHooks(\n cwd = process.cwd(),\n options: {\n yes?: boolean;\n confirm?: (plan: string) => Promise<boolean>;\n environment?: NodeJS.ProcessEnv;\n json?: boolean;\n report?: boolean;\n } = {},\n): Promise<boolean> {\n if (codexRecoveryIsRequired(cwd)) {\n reportCodexWhen(options.report !== false, () => {\n reportCodexMigration(cwd, options);\n });\n return false;\n }\n if (observeCodexHookProof(options.environment).status !== 'current') {\n throw new CodexMigrationError(\n 'FINALIZATION_PROOF_REQUIRED',\n 'Finalization requires current plugin hook proof from the restarted Codex app. Review /hooks, then retry.',\n );\n }\n if (codexFinalizationIsComplete(cwd)) {\n reportCodexWhen(options.report !== false, () => {\n reportCompletedFinalization(cwd, options);\n });\n return false;\n }\n // Validate cleanup before verifying the profile. A malformed project config\n // leaves both it and the Codex profile unchanged.\n const preparedLegacyHookRemoval = prepareLegacyHookRemoval(cwd);\n const plannedMutations = buildCodexFinalizationMutations(cwd, preparedLegacyHookRemoval);\n const plannedEffects = finalizationEffects(cwd, plannedMutations);\n const plannedInputs = snapshotCodexFinalizationInputs(cwd, plannedMutations);\n const plan = renderCodexFinalizationPlan(cwd, plannedMutations, preparedLegacyHookRemoval);\n const confirm = options.confirm;\n const confirmed = await resolveCodexFinalizationConfirmation({\n assumeYes: options.yes === true,\n confirm: confirm === undefined ? undefined : () => confirm(plan),\n });\n if (!confirmed) {\n reportCodexWhen(options.report !== false, () => {\n info('Codex migration finalization was declined; the project was left unchanged.');\n });\n return false;\n }\n\n run('bun', ['--version']);\n run('codex', ['--version']);\n verifyCodexPluginIsEnabled();\n\n reportCodexWhen(options.report !== false && options.json !== true, () => {\n success('Safeword Codex plugin is enabled for this profile.');\n });\n\n assertCodexFinalizationPlanUnchanged(\n cwd,\n preparedLegacyHookRemoval,\n plannedMutations,\n plannedEffects,\n plannedInputs,\n );\n applyCodexFinalization(cwd, plannedMutations);\n\n reportCodexWhen(options.report !== false, () => {\n reportAppliedFinalization(cwd, {\n options,\n effects: plannedEffects,\n removedLegacyHooks: preparedLegacyHookRemoval !== undefined,\n });\n });\n return true;\n}\n\nexport function automaticallyMigrateLegacyCodex(\n cwd = process.cwd(),\n environment: NodeJS.ProcessEnv = process.env,\n): boolean {\n if (codexFinalizationIsComplete(cwd) || codexRecoveryIsRequired(cwd)) return false;\n const preparedLegacyHookRemoval = prepareLegacyHookRemoval(cwd);\n const hasLegacy = preparedLegacyHookRemoval !== undefined || observeLegacyAssets(cwd).length > 0;\n if (!hasLegacy) return false;\n\n installCodexPlugin({ cwd, environment, json: true, reportMigrationState: false });\n return true;\n}\n\n/**\n * Compatibility facade for the pre-`install --agents=codex` command shape. New\n * users should use `safeword install --agents=codex`; existing scripts retain\n * their behavior.\n */\nexport async function migrateCodexPlugin(\n cwd = process.cwd(),\n options: {\n marketplaceSource?: string;\n removeLegacyHooks?: boolean;\n yes?: boolean;\n confirm?: (plan: string) => Promise<boolean>;\n } = {},\n): Promise<void> {\n if (options.removeLegacyHooks) {\n await removeLegacyCodexHooks(cwd, { yes: options.yes, confirm: options.confirm });\n return;\n }\n installCodexPlugin({\n marketplaceSource: options.marketplaceSource,\n recordActivationPending: false,\n });\n}\n\nexport function recoverCodexMigration(\n cwd = process.cwd(),\n options: { json?: boolean; environment?: NodeJS.ProcessEnv; report?: boolean } = {},\n): boolean {\n if (options.report === false) {\n return recoverCodexFinalization(cwd);\n }\n const changed = recoverCodexFinalization(cwd);\n if (options.json === true) {\n reportCodexMigration(cwd, { ...options, changed });\n } else {\n success(\n changed\n ? 'Restored the backed-up Safeword legacy Codex project state.'\n : 'No Safeword Codex migration recovery was needed.',\n );\n }\n return changed;\n}\n","import { lstatSync, readFileSync, type Stats } from 'node:fs';\nimport nodePath from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport { CODEX_MIGRATION_SCHEMA } from './inventory.js';\nimport { legacyCommandIdentity } from './legacy-command.js';\n\nconst KNOWN_HOOK_EVENTS = new Set([\n 'SessionStart',\n 'SubagentStart',\n 'PreToolUse',\n 'PermissionRequest',\n 'PostToolUse',\n 'PreCompact',\n 'PostCompact',\n 'UserPromptSubmit',\n 'SubagentStop',\n 'Stop',\n]);\n\nconst TOML_HOOK_KEYS = ['hooks', '\"hooks\"', \"'hooks'\"] as const;\ntype ParsedHookHeader = { event: string; kind: 'parent' | 'nested' };\n\nfunction hookHeaderEntries(event: string): [string, ParsedHookHeader][] {\n const eventKeys = [event, `\"${event}\"`, `'${event}'`];\n return TOML_HOOK_KEYS.flatMap(hookKey =>\n eventKeys.flatMap(eventKey => [\n [`[[${hookKey}.${eventKey}]]`, { event, kind: 'parent' }],\n ...TOML_HOOK_KEYS.map(\n nestedHookKey =>\n [`[[${hookKey}.${eventKey}.${nestedHookKey}]]`, { event, kind: 'nested' }] as [\n string,\n ParsedHookHeader,\n ],\n ),\n ]),\n ) as [string, ParsedHookHeader][];\n}\n\nconst HOOK_HEADER_LOOKUP = new Map(\n [...KNOWN_HOOK_EVENTS].flatMap(event => hookHeaderEntries(event)),\n);\n\ninterface TextRange {\n start: number;\n end: number;\n}\n\ninterface HookBlock {\n range: TextRange;\n safeWordOwned: boolean;\n safeWordAmbiguous: boolean;\n}\n\nfunction splitLines(content: string): string[] {\n if (content === '') return [];\n const lines = content.split('\\n');\n return lines.map((line, index) => (index < lines.length - 1 ? `${line}\\n` : line));\n}\n\nfunction uncommented(line: string): string {\n const comment = line.indexOf('#');\n return (comment === -1 ? line : line.slice(0, comment)).trim();\n}\n\nfunction hookHeader(line: string): ParsedHookHeader | undefined {\n return HOOK_HEADER_LOOKUP.get(uncommented(line).replaceAll(/\\s+/gu, ''));\n}\n\nfunction eventHeader(line: string): string | undefined {\n const header = hookHeader(line);\n return header?.kind === 'parent' ? header.event : undefined;\n}\n\nfunction isNestedHookHeader(line: string, event: string): boolean {\n const header = hookHeader(line);\n return header?.kind === 'nested' && header.event === event;\n}\n\nfunction startsNewTopLevelSection(line: string, event: string): boolean {\n const header = uncommented(line);\n return header.startsWith('[') && !isNestedHookHeader(line, event);\n}\n\nfunction assignmentValue(line: string, key: string): string | undefined {\n const equals = line.indexOf('=');\n if (equals === -1 || line.slice(0, equals).trim() !== key) return undefined;\n return line.slice(equals + 1).trim();\n}\n\nfunction quotedValue(value: string): string | undefined {\n const quote = value[0];\n if (quote !== '\"' && quote !== \"'\") return undefined;\n\n for (let index = 1; index < value.length; index += 1) {\n const character = value[index];\n if (quote === '\"' && character === '\\\\') {\n index += 1;\n continue;\n }\n if (character !== quote) continue;\n const trailing = value.slice(index + 1).trim();\n return trailing === '' || trailing.startsWith('#') ? value.slice(1, index) : undefined;\n }\n return undefined;\n}\n\nfunction bareCommandValue(line: string): string | undefined {\n const value = assignmentValue(line, 'command');\n return value === undefined ? undefined : quotedValue(value);\n}\n\nfunction blockCommandValues(lines: string[], range: TextRange): string[] {\n const commands: string[] = [];\n for (let index = range.start + 1; index < range.end; index += 1) {\n const command = bareCommandValue(lines[index] ?? '');\n if (command !== undefined) commands.push(command);\n }\n return commands;\n}\n\nfunction allowedHookLine(line: string): boolean {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith('#')) return true;\n const type = quotedValue(assignmentValue(line, 'type') ?? '');\n if (type === 'command') return true;\n if (bareCommandValue(line) !== undefined) return true;\n if (quotedValue(assignmentValue(line, 'statusMessage') ?? '') !== undefined) return true;\n const timeout = assignmentValue(line, 'timeout');\n return timeout !== undefined && Number.isSafeInteger(Number(timeout));\n}\n\nfunction containsOnlyAllowedHookLines(lines: string[], range: TextRange): boolean {\n for (let index = range.start + 1; index < range.end; index += 1) {\n if (!allowedHookLine(lines[index] ?? '')) return false;\n }\n return true;\n}\n\nfunction classifyHookBlock(lines: string[], range: TextRange): HookBlock {\n const commands = blockCommandValues(lines, range);\n const safeWordCommand = commands.some(command => legacyCommandIdentity(command) !== undefined);\n const safeWordAmbiguous =\n safeWordCommand && (commands.length !== 1 || !containsOnlyAllowedHookLines(lines, range));\n return {\n range,\n safeWordOwned:\n commands.length === 1 &&\n legacyCommandIdentity(commands[0] ?? '') !== undefined &&\n !safeWordAmbiguous,\n safeWordAmbiguous,\n };\n}\n\nfunction isKnownParentScaffold(lines: string[], range: TextRange): boolean {\n for (let index = range.start + 1; index < range.end; index += 1) {\n const trimmed = (lines[index] ?? '').trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n if (quotedValue(assignmentValue(lines[index] ?? '', 'matcher') ?? '') === undefined)\n return false;\n }\n return true;\n}\n\nfunction sectionEnd(lines: string[], start: number, event: string): number {\n let end = start + 1;\n while (end < lines.length && !startsNewTopLevelSection(lines[end] ?? '', event)) end += 1;\n return end;\n}\n\nfunction nestedHookStarts(lines: string[], start: number, end: number, event: string): number[] {\n const starts: number[] = [];\n for (let index = start + 1; index < end; index += 1) {\n if (isNestedHookHeader(lines[index] ?? '', event)) starts.push(index);\n }\n return starts;\n}\n\nfunction eventRemovalRanges(\n lines: string[],\n start: number,\n end: number,\n event: string,\n): TextRange[] {\n const nestedStarts = nestedHookStarts(lines, start, end, event);\n if (nestedStarts.length === 0) return [];\n const blocks = nestedStarts.map((nestedStart, index) =>\n classifyHookBlock(lines, { start: nestedStart, end: nestedStarts[index + 1] ?? end }),\n );\n if (blocks.some(block => block.safeWordAmbiguous)) {\n throw new Error(\n 'Legacy Safeword hook cleanup found an ambiguous hook block; no changes were made.',\n );\n }\n const ownedBlocks = blocks.filter(block => block.safeWordOwned);\n if (ownedBlocks.length === 0) return [];\n const parentRange = { start, end: nestedStarts[0] ?? end };\n // Unknown parent metadata is user-owned. Preserve that now-inert scaffold\n // and remove only the recognized Safeword child block.\n return ownedBlocks.length === blocks.length && isKnownParentScaffold(lines, parentRange)\n ? [{ start, end }]\n : ownedBlocks.map(block => block.range);\n}\n\nfunction removalRanges(lines: string[]): TextRange[] {\n const removals: TextRange[] = [];\n let cursor = 0;\n while (cursor < lines.length) {\n const event = eventHeader(lines[cursor] ?? '');\n if (event === undefined) {\n cursor += 1;\n continue;\n }\n const end = sectionEnd(lines, cursor, event);\n removals.push(...eventRemovalRanges(lines, cursor, end, event));\n cursor = end;\n }\n return removals;\n}\n\nfunction tomlObject(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction semanticNestedHookCount(value: unknown): number {\n const command = tomlObject(value)?.command;\n return typeof command === 'string' && legacyCommandIdentity(command) !== undefined ? 1 : 0;\n}\n\nfunction semanticParentHookCount(value: unknown): number {\n const nestedHooks = tomlObject(value)?.hooks;\n return Array.isArray(nestedHooks)\n ? nestedHooks.reduce<number>((count, hook) => count + semanticNestedHookCount(hook), 0)\n : 0;\n}\n\nfunction semanticEventHookCount(value: unknown): number {\n return Array.isArray(value)\n ? value.reduce<number>((count, parent) => count + semanticParentHookCount(parent), 0)\n : 0;\n}\n\nfunction semanticLegacyCommandCounts(document: unknown): Map<string, number> {\n const counts = new Map<string, number>();\n const hooks = tomlObject(tomlObject(document)?.hooks);\n if (hooks === undefined) return counts;\n for (const event of KNOWN_HOOK_EVENTS) {\n const count = semanticEventHookCount(hooks[event]);\n if (count > 0) counts.set(event, count);\n }\n return counts;\n}\n\nfunction sourceLegacyCommandCounts(lines: string[]): Map<string, number> {\n const counts = new Map<string, number>();\n let cursor = 0;\n while (cursor < lines.length) {\n const event = eventHeader(lines[cursor] ?? '');\n if (event === undefined) {\n cursor += 1;\n continue;\n }\n const end = sectionEnd(lines, cursor, event);\n const count = nestedHookStarts(lines, cursor, end, event)\n .flatMap((start, index, starts) =>\n blockCommandValues(lines, { start, end: starts[index + 1] ?? end }),\n )\n .filter(command => legacyCommandIdentity(command) !== undefined).length;\n if (count > 0) counts.set(event, (counts.get(event) ?? 0) + count);\n cursor = end;\n }\n return counts;\n}\n\nfunction countsMatch(left: Map<string, number>, right: Map<string, number>): boolean {\n for (const event of KNOWN_HOOK_EVENTS) {\n if ((left.get(event) ?? 0) !== (right.get(event) ?? 0)) return false;\n }\n return true;\n}\n\nfunction prepareLegacyCodexHookBlocks(content: string): {\n cleaned: string;\n removedBlocks: string[];\n} {\n let document: unknown;\n try {\n document = parse(content);\n } catch (error) {\n throw new Error('Codex configuration is invalid TOML; no legacy hooks were removed.', {\n cause: error,\n });\n }\n\n const lines = splitLines(content);\n if (!countsMatch(semanticLegacyCommandCounts(document), sourceLegacyCommandCounts(lines))) {\n throw new Error(\n 'Codex configuration uses unsupported Safeword hook formatting; no legacy hooks were removed.',\n );\n }\n const ranges = removalRanges(lines);\n const removedBlocks = ranges.map(range => lines.slice(range.start, range.end).join(''));\n const reverseOrderedRanges = ranges.toSorted((left, right) => right.start - left.start);\n for (const range of reverseOrderedRanges) {\n lines.splice(range.start, range.end - range.start);\n }\n return { cleaned: lines.join(''), removedBlocks };\n}\n\ntype CodexConfigMetadata = { kind: 'missing' } | { kind: 'regular'; metadata: Stats };\n\nexport class CodexConfigObservationError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'CodexConfigObservationError';\n }\n}\n\nfunction metadataOrMissing(path: string): Stats | undefined {\n try {\n return lstatSync(path);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT' || code === 'ENOTDIR') return undefined;\n throw error;\n }\n}\n\nfunction unsafeConfigEntry(\n label: 'Codex configuration' | 'Codex configuration directory',\n metadata: Stats,\n operation: 'cleanup' | 'observe',\n): never {\n let kind = 'not a regular file';\n if (metadata.isSymbolicLink()) kind = 'a symbolic link';\n else if (label === 'Codex configuration directory') kind = 'not an ordinary directory';\n if (operation === 'observe') {\n throw new CodexConfigObservationError(`${label} is ${kind} and cannot be observed safely.`);\n }\n throw new Error(`${label} is ${kind}; no legacy hooks were removed.`);\n}\n\nexport function regularCodexConfigMetadata(\n configPath: string,\n operation: 'cleanup' | 'observe' = 'cleanup',\n): CodexConfigMetadata {\n const directoryMetadata = metadataOrMissing(nodePath.dirname(configPath));\n if (directoryMetadata === undefined) return { kind: 'missing' };\n if (!directoryMetadata.isDirectory()) {\n unsafeConfigEntry('Codex configuration directory', directoryMetadata, operation);\n }\n\n const metadata = metadataOrMissing(configPath);\n if (metadata === undefined) return { kind: 'missing' };\n if (!metadata.isFile()) unsafeConfigEntry('Codex configuration', metadata, operation);\n return { kind: 'regular', metadata };\n}\n\nexport interface PreparedLegacyHookRemoval {\n configPath: string;\n original: string;\n cleaned: string;\n removedBlocks: string[];\n}\n\nexport function prepareLegacyHookRemoval(cwd: string): PreparedLegacyHookRemoval | undefined {\n const configPath = nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.config);\n if (regularCodexConfigMetadata(configPath).kind === 'missing') return;\n const original = readFileSync(configPath, 'utf8');\n const { cleaned, removedBlocks } = prepareLegacyCodexHookBlocks(original);\n if (cleaned === original) return undefined;\n return { configPath, original, cleaned, removedBlocks };\n}\n\nexport function observeLegacyEvents(cwd: string): string[] {\n const configPath = nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.config);\n if (regularCodexConfigMetadata(configPath, 'observe').kind === 'missing') return [];\n try {\n return semanticLegacyCommandCounts(parse(readFileSync(configPath, 'utf8')))\n .keys()\n .toArray()\n .toSorted((left, right) => left.localeCompare(right));\n } catch (error) {\n if (error instanceof CodexConfigObservationError) throw error;\n throw new CodexConfigObservationError('Codex configuration cannot be read or parsed safely.', {\n cause: error,\n });\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport nodePath from 'node:path';\n\nconst DEFAULT_MAX_AGE_MS = 10 * 60 * 1000;\n\ninterface LockRecord {\n owner: string;\n acquired_at: number;\n}\n\nexport interface CodexProfileLock {\n readonly path: string;\n readonly owner: string;\n}\n\nfunction profileDirectory(environment: NodeJS.ProcessEnv): string {\n return environment.CODEX_HOME ?? nodePath.join(homedir(), '.codex');\n}\n\nfunction lockPath(environment: NodeJS.ProcessEnv): string {\n return nodePath.join(profileDirectory(environment), 'safeword/profile-mutation.lock');\n}\n\nfunction acquisitionGatePath(path: string): string {\n return `${path}.acquire`;\n}\n\nfunction readRecord(path: string): LockRecord | undefined {\n try {\n const value = JSON.parse(\n readFileSync(nodePath.join(path, 'owner.json'), 'utf8'),\n ) as Partial<LockRecord>;\n return typeof value.owner === 'string' && typeof value.acquired_at === 'number'\n ? { owner: value.owner, acquired_at: value.acquired_at }\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction lockAge(path: string, now: number): number {\n const record = readRecord(path);\n if (record !== undefined) return now - record.acquired_at;\n try {\n return now - statSync(path).mtimeMs;\n } catch {\n return 0;\n }\n}\n\nfunction createLock(path: string, owner: string, now: number): CodexProfileLock | undefined {\n try {\n mkdirSync(path);\n writeFileSync(\n nodePath.join(path, 'owner.json'),\n `${JSON.stringify({ owner, acquired_at: now })}\\n`,\n { encoding: 'utf8', flag: 'wx', mode: 0o600 },\n );\n return { path, owner };\n } catch {\n return undefined;\n }\n}\n\nexport function acquireCodexProfileLock(\n environment: NodeJS.ProcessEnv = process.env,\n options: { owner?: string; now?: () => number; maxAgeMs?: number } = {},\n): CodexProfileLock | undefined {\n const path = lockPath(environment);\n const owner = options.owner ?? randomUUID();\n const now = (options.now ?? Date.now)();\n mkdirSync(nodePath.dirname(path), { recursive: true });\n const gate = acquisitionGatePath(path);\n try {\n mkdirSync(gate);\n } catch {\n return undefined;\n }\n try {\n const acquired = createLock(path, owner, now);\n if (acquired !== undefined) return acquired;\n if (lockAge(path, now) <= (options.maxAgeMs ?? DEFAULT_MAX_AGE_MS)) return undefined;\n rmSync(path, { recursive: true, force: true });\n return createLock(path, owner, now);\n } finally {\n rmSync(gate, { recursive: true, force: true });\n }\n}\n\nexport function releaseCodexProfileLock(lock: CodexProfileLock): boolean {\n if (readRecord(lock.path)?.owner !== lock.owner) return false;\n rmSync(lock.path, { recursive: true, force: true });\n return true;\n}\n","import { readFileSync } from 'node:fs';\nimport nodePath from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport { writeDurableFile } from './durable-write.js';\nimport { CODEX_MIGRATION_SCHEMA } from './inventory.js';\nimport { regularCodexConfigMetadata } from './legacy-config.js';\n\nconst BEGIN_MARKER = '# --- safeword codex bootstrap: begin ---';\nconst END_MARKER = '# --- safeword codex bootstrap: end ---';\nconst BOOTSTRAP_COMMAND = 'bunx --bun safeword@latest codex bootstrap';\nconst DEPENDENCY_BOOTSTRAP_COMMAND =\n 'SAFEWORD_PROJECT_ROOT=\"$(git rev-parse --show-toplevel 2>/dev/null || pwd)\" && { [ ! -f \"$SAFEWORD_PROJECT_ROOT/.safeword/hooks/dependency-bootstrap.ts\" ] || bun \"$SAFEWORD_PROJECT_ROOT/.safeword/hooks/dependency-bootstrap.ts\" \"$SAFEWORD_PROJECT_ROOT\"; }';\n\nconst BOOTSTRAP_BLOCK = `${BEGIN_MARKER}\n[[hooks.SessionStart]]\nmatcher = \"\"\n\n[[hooks.SessionStart.hooks]]\ntype = \"command\"\ncommand = \"${BOOTSTRAP_COMMAND}\"\ntimeout = 120\nstatusMessage = \"Checking Safeword for this project\"\n\n[[hooks.SessionStart]]\nmatcher = \"\"\n\n[[hooks.SessionStart.hooks]]\ntype = \"command\"\ncommand = '${DEPENDENCY_BOOTSTRAP_COMMAND}'\ntimeout = 120\nstatusMessage = \"Preparing safeword dependencies\"\n${END_MARKER}\n`;\n\nfunction withoutManagedBlock(content: string): string {\n const begin = content.indexOf(BEGIN_MARKER);\n const end = content.indexOf(END_MARKER);\n if (begin === -1 && end === -1) {\n if (content.includes(BOOTSTRAP_COMMAND) || content.includes('dependency-bootstrap.ts')) {\n throw new Error(\n 'Codex configuration contains an unrecognized Safeword bootstrap command; no changes were made.',\n );\n }\n return content;\n }\n if (begin === -1 || end === -1 || end < begin || content.includes(BEGIN_MARKER, begin + 1)) {\n throw new Error(\n 'Codex configuration contains malformed Safeword bootstrap markers; no changes were made.',\n );\n }\n const afterEnd = end + END_MARKER.length;\n if (content.includes(END_MARKER, afterEnd)) {\n throw new Error(\n 'Codex configuration contains duplicate Safeword bootstrap markers; no changes were made.',\n );\n }\n const before = content.slice(0, begin).trimEnd();\n const after = content.slice(afterEnd).trimStart();\n return [before, after].filter(section => section !== '').join('\\n\\n');\n}\n\nexport function codexProjectBootstrapContent(content: string): string {\n try {\n parse(content);\n } catch (error) {\n throw new Error('Codex configuration is invalid TOML; no bootstrap was installed.', {\n cause: error,\n });\n }\n const preserved = withoutManagedBlock(content).trimEnd();\n const prefix = preserved === '' ? '' : `${preserved}\\n\\n`;\n const next = `${prefix}${BOOTSTRAP_BLOCK}`;\n try {\n parse(next);\n } catch (error) {\n throw new Error('Safeword could not safely merge its Codex bootstrap configuration.', {\n cause: error,\n });\n }\n return next;\n}\n\nexport function preparedCodexProjectBootstrap(cwd: string, baseContent?: string): string {\n const configPath = nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.config);\n let content = baseContent;\n if (content === undefined) {\n content =\n regularCodexConfigMetadata(configPath).kind === 'missing'\n ? ''\n : readFileSync(configPath, 'utf8');\n }\n return codexProjectBootstrapContent(content);\n}\n\nexport function installCodexProjectBootstrap(cwd: string): boolean {\n const configPath = nodePath.join(cwd, CODEX_MIGRATION_SCHEMA.paths.config);\n const metadata = regularCodexConfigMetadata(configPath);\n const original = metadata.kind === 'missing' ? '' : readFileSync(configPath, 'utf8');\n const content = codexProjectBootstrapContent(original);\n if (content === original) return false;\n writeDurableFile(configPath, content, {\n mode: metadata.kind === 'regular' ? metadata.metadata.mode : 0o644,\n });\n return true;\n}\n"],"mappings":"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","names":["lstatSync","readFileSync","homedir","nodePath","readFileSync","nodePath","readFileSync","nodePath","nodePath","readFileSync","nodePath","homedir","readFileSync","lstatSync"]}
@@ -2519,6 +2519,13 @@ var SAFEWORD_SCHEMA = {
2519
2519
  // Project-root audit config is scaffolded when absent, then customer-owned.
2520
2520
  // Full uninstall removes it only while it still matches Safeword's template.
2521
2521
  ".jscpd.json": { template: ".jscpd.json" },
2522
+ // Explicit remote-test setup owns publication; ordinary reconciliation
2523
+ // catalogues these bytes without installing them.
2524
+ ".github/workflows/safeword-remote-tests.yml": {
2525
+ template: "workflows/remote-tests.yml",
2526
+ generator: () => void 0,
2527
+ dogfoodParity: true
2528
+ },
2522
2529
  // Package-owned Codex runtime adapters. Their generator intentionally
2523
2530
  // returns undefined: the plugin CLI executes them from the npm package,
2524
2531
  // never from a customer repository.
@@ -2898,4 +2905,4 @@ export {
2898
2905
  isCursorProjectPath,
2899
2906
  schemaForProjectSurfaces
2900
2907
  };
2901
- //# sourceMappingURL=chunk-IPTM5VE7.js.map
2908
+ //# sourceMappingURL=chunk-5VNZBVCI.js.map