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,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
MCP_SERVERS
|
|
3
|
-
|
|
2
|
+
MCP_SERVERS,
|
|
3
|
+
detectPythonLayers,
|
|
4
|
+
detectRootPackage,
|
|
5
|
+
detectSolePackage
|
|
6
|
+
} from "./chunk-JSR3HXFT.js";
|
|
4
7
|
import {
|
|
5
8
|
CODEX_MIGRATION_SCHEMA
|
|
6
9
|
} from "./chunk-AVAUUIDB.js";
|
|
@@ -14,7 +17,7 @@ import {
|
|
|
14
17
|
acceptedHistoricalHookEntries,
|
|
15
18
|
filterOutEquivalentSafewordHooks,
|
|
16
19
|
filterOutSafewordHooks
|
|
17
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-HNCUIXDY.js";
|
|
18
21
|
import {
|
|
19
22
|
VERSION
|
|
20
23
|
} from "./chunk-UAFM77KW.js";
|
|
@@ -23,696 +26,14 @@ import {
|
|
|
23
26
|
} from "./chunk-QSLVO4XF.js";
|
|
24
27
|
import {
|
|
25
28
|
resolveNamespaceRoot
|
|
26
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-RVDXBHUG.js";
|
|
27
30
|
import {
|
|
28
31
|
exists,
|
|
29
32
|
findInTree,
|
|
30
33
|
getTemplatesDirectory,
|
|
31
34
|
readFile,
|
|
32
35
|
readFileSafe
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
|
|
35
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/date.js
|
|
36
|
-
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
37
|
-
var TomlDate = class _TomlDate extends Date {
|
|
38
|
-
#hasDate = false;
|
|
39
|
-
#hasTime = false;
|
|
40
|
-
#offset = null;
|
|
41
|
-
constructor(date) {
|
|
42
|
-
let hasDate = true;
|
|
43
|
-
let hasTime = true;
|
|
44
|
-
let offset = "Z";
|
|
45
|
-
if (typeof date === "string") {
|
|
46
|
-
let match = date.match(DATE_TIME_RE);
|
|
47
|
-
if (match) {
|
|
48
|
-
if (!match[1]) {
|
|
49
|
-
hasDate = false;
|
|
50
|
-
date = `0000-01-01T${date}`;
|
|
51
|
-
}
|
|
52
|
-
hasTime = !!match[2];
|
|
53
|
-
hasTime && date[10] === " " && (date = date.replace(" ", "T"));
|
|
54
|
-
if (match[2] && +match[2] > 23) {
|
|
55
|
-
date = "";
|
|
56
|
-
} else {
|
|
57
|
-
offset = match[3] || null;
|
|
58
|
-
date = date.toUpperCase();
|
|
59
|
-
if (!offset && hasTime)
|
|
60
|
-
date += "Z";
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
date = "";
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
super(date);
|
|
67
|
-
if (!isNaN(this.getTime())) {
|
|
68
|
-
this.#hasDate = hasDate;
|
|
69
|
-
this.#hasTime = hasTime;
|
|
70
|
-
this.#offset = offset;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
isDateTime() {
|
|
74
|
-
return this.#hasDate && this.#hasTime;
|
|
75
|
-
}
|
|
76
|
-
isLocal() {
|
|
77
|
-
return !this.#hasDate || !this.#hasTime || !this.#offset;
|
|
78
|
-
}
|
|
79
|
-
isDate() {
|
|
80
|
-
return this.#hasDate && !this.#hasTime;
|
|
81
|
-
}
|
|
82
|
-
isTime() {
|
|
83
|
-
return this.#hasTime && !this.#hasDate;
|
|
84
|
-
}
|
|
85
|
-
isValid() {
|
|
86
|
-
return this.#hasDate || this.#hasTime;
|
|
87
|
-
}
|
|
88
|
-
toISOString() {
|
|
89
|
-
let iso = super.toISOString();
|
|
90
|
-
if (this.isDate())
|
|
91
|
-
return iso.slice(0, 10);
|
|
92
|
-
if (this.isTime())
|
|
93
|
-
return iso.slice(11, 23);
|
|
94
|
-
if (this.#offset === null)
|
|
95
|
-
return iso.slice(0, -1);
|
|
96
|
-
if (this.#offset === "Z")
|
|
97
|
-
return iso;
|
|
98
|
-
let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
|
|
99
|
-
offset = this.#offset[0] === "-" ? offset : -offset;
|
|
100
|
-
let offsetDate = new Date(this.getTime() - offset * 6e4);
|
|
101
|
-
return offsetDate.toISOString().slice(0, -1) + this.#offset;
|
|
102
|
-
}
|
|
103
|
-
static wrapAsOffsetDateTime(jsDate, offset = "Z") {
|
|
104
|
-
let date = new _TomlDate(jsDate);
|
|
105
|
-
date.#offset = offset;
|
|
106
|
-
return date;
|
|
107
|
-
}
|
|
108
|
-
static wrapAsLocalDateTime(jsDate) {
|
|
109
|
-
let date = new _TomlDate(jsDate);
|
|
110
|
-
date.#offset = null;
|
|
111
|
-
return date;
|
|
112
|
-
}
|
|
113
|
-
static wrapAsLocalDate(jsDate) {
|
|
114
|
-
let date = new _TomlDate(jsDate);
|
|
115
|
-
date.#hasTime = false;
|
|
116
|
-
date.#offset = null;
|
|
117
|
-
return date;
|
|
118
|
-
}
|
|
119
|
-
static wrapAsLocalTime(jsDate) {
|
|
120
|
-
let date = new _TomlDate(jsDate);
|
|
121
|
-
date.#hasDate = false;
|
|
122
|
-
date.#offset = null;
|
|
123
|
-
return date;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/error.js
|
|
128
|
-
function getLineColFromPtr(string, ptr) {
|
|
129
|
-
let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
|
|
130
|
-
return [lines.length, lines.pop().length + 1];
|
|
131
|
-
}
|
|
132
|
-
function makeCodeBlock(string, line, column) {
|
|
133
|
-
let lines = string.split(/\r\n|\n|\r/g);
|
|
134
|
-
let codeblock = "";
|
|
135
|
-
let numberLen = (Math.log10(line + 1) | 0) + 1;
|
|
136
|
-
for (let i = line - 1; i <= line + 1; i++) {
|
|
137
|
-
let l = lines[i - 1];
|
|
138
|
-
if (!l)
|
|
139
|
-
continue;
|
|
140
|
-
codeblock += i.toString().padEnd(numberLen, " ");
|
|
141
|
-
codeblock += ": ";
|
|
142
|
-
codeblock += l;
|
|
143
|
-
codeblock += "\n";
|
|
144
|
-
if (i === line) {
|
|
145
|
-
codeblock += " ".repeat(numberLen + column + 2);
|
|
146
|
-
codeblock += "^\n";
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return codeblock;
|
|
150
|
-
}
|
|
151
|
-
var TomlError = class extends Error {
|
|
152
|
-
line;
|
|
153
|
-
column;
|
|
154
|
-
codeblock;
|
|
155
|
-
constructor(message, options) {
|
|
156
|
-
const [line, column] = getLineColFromPtr(options.toml, options.ptr);
|
|
157
|
-
const codeblock = makeCodeBlock(options.toml, line, column);
|
|
158
|
-
super(`Invalid TOML document: ${message}
|
|
159
|
-
|
|
160
|
-
${codeblock}`, options);
|
|
161
|
-
this.line = line;
|
|
162
|
-
this.column = column;
|
|
163
|
-
this.codeblock = codeblock;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/primitive.js
|
|
168
|
-
var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
169
|
-
var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
170
|
-
var LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
171
|
-
function parseString(str, ptr) {
|
|
172
|
-
let c = str[ptr++];
|
|
173
|
-
let first = c;
|
|
174
|
-
let isLiteral = c === "'";
|
|
175
|
-
let isMultiline = c === str[ptr] && c === str[ptr + 1];
|
|
176
|
-
if (isMultiline) {
|
|
177
|
-
if (str[ptr += 2] === "\n")
|
|
178
|
-
ptr++;
|
|
179
|
-
else if (str[ptr] === "\r" && str[ptr + 1] === "\n")
|
|
180
|
-
ptr += 2;
|
|
181
|
-
}
|
|
182
|
-
let parsed = "";
|
|
183
|
-
let sliceStart = ptr;
|
|
184
|
-
let state = 0;
|
|
185
|
-
for (let i = ptr; i < str.length; i++) {
|
|
186
|
-
c = str[i];
|
|
187
|
-
if (isMultiline && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
188
|
-
state = state && 3;
|
|
189
|
-
} else if (c < " " && c !== " " || c === "\x7F") {
|
|
190
|
-
throw new TomlError("control characters are not allowed in strings", {
|
|
191
|
-
toml: str,
|
|
192
|
-
ptr: i
|
|
193
|
-
});
|
|
194
|
-
} else if ((!state || state === 3) && c === first && (!isMultiline || str[i + 1] === first && str[i + 2] === first)) {
|
|
195
|
-
if (isMultiline) {
|
|
196
|
-
if (str[i + 3] === first)
|
|
197
|
-
i++;
|
|
198
|
-
if (str[i + 3] === first)
|
|
199
|
-
i++;
|
|
200
|
-
}
|
|
201
|
-
return [
|
|
202
|
-
// If we're in a newline escape still, then there's nothing to add.
|
|
203
|
-
// Also try to avoid concat if there's nothing to add to parsed, or nothing has been added to parsed.
|
|
204
|
-
state ? parsed : parsed + str.slice(sliceStart, i),
|
|
205
|
-
i + (isMultiline ? 3 : 1)
|
|
206
|
-
];
|
|
207
|
-
} else if (!state) {
|
|
208
|
-
if (!isLiteral && c === "\\") {
|
|
209
|
-
parsed += str.slice(sliceStart, sliceStart = i);
|
|
210
|
-
state = 1;
|
|
211
|
-
}
|
|
212
|
-
} else if (state === 1) {
|
|
213
|
-
if (c === "x" || c === "u" || c === "U") {
|
|
214
|
-
let value = 0;
|
|
215
|
-
let len = c === "x" ? 2 : c === "u" ? 4 : 8;
|
|
216
|
-
for (let j = 0; j < len; j++, i++) {
|
|
217
|
-
let hex = str.charCodeAt(i + 1);
|
|
218
|
-
let digit = (
|
|
219
|
-
/* 0-9 */
|
|
220
|
-
hex >= 48 && hex <= 57 ? hex - 48 : (
|
|
221
|
-
/* A-F */
|
|
222
|
-
hex >= 65 && hex <= 70 ? hex - 65 + 10 : (
|
|
223
|
-
/* a-f */
|
|
224
|
-
hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1
|
|
225
|
-
)
|
|
226
|
-
)
|
|
227
|
-
);
|
|
228
|
-
if (digit < 0)
|
|
229
|
-
throw new TomlError("invalid non-hex character in unicode escape", { toml: str, ptr: i + 1 });
|
|
230
|
-
value = value << 4 | digit;
|
|
231
|
-
}
|
|
232
|
-
if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) {
|
|
233
|
-
throw new TomlError("invalid unicode escape", { toml: str, ptr: i });
|
|
234
|
-
}
|
|
235
|
-
parsed += String.fromCodePoint(value);
|
|
236
|
-
sliceStart = i + 1;
|
|
237
|
-
state = 0;
|
|
238
|
-
} else if (c === " " || c === " ") {
|
|
239
|
-
state = 2;
|
|
240
|
-
} else {
|
|
241
|
-
if (c === "b")
|
|
242
|
-
parsed += "\b";
|
|
243
|
-
else if (c === "t")
|
|
244
|
-
parsed += " ";
|
|
245
|
-
else if (c === "n")
|
|
246
|
-
parsed += "\n";
|
|
247
|
-
else if (c === "f")
|
|
248
|
-
parsed += "\f";
|
|
249
|
-
else if (c === "r")
|
|
250
|
-
parsed += "\r";
|
|
251
|
-
else if (c === "e")
|
|
252
|
-
parsed += "\x1B";
|
|
253
|
-
else if (c === '"')
|
|
254
|
-
parsed += '"';
|
|
255
|
-
else if (c === "\\")
|
|
256
|
-
parsed += "\\";
|
|
257
|
-
else
|
|
258
|
-
throw new TomlError("unrecognized escape sequence", { toml: str, ptr: i });
|
|
259
|
-
sliceStart = i + 1;
|
|
260
|
-
state = 0;
|
|
261
|
-
}
|
|
262
|
-
} else if (c !== " " && c !== " ") {
|
|
263
|
-
if (state === 2) {
|
|
264
|
-
throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
|
|
265
|
-
toml: str,
|
|
266
|
-
ptr: sliceStart
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
state = !isLiteral && c === "\\" ? 1 : 0;
|
|
270
|
-
sliceStart = i;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
throw new TomlError("unfinished string", { toml: str, ptr });
|
|
274
|
-
}
|
|
275
|
-
function parseValue(value, toml, ptr, integersAsBigInt) {
|
|
276
|
-
if (value === "true")
|
|
277
|
-
return true;
|
|
278
|
-
if (value === "false")
|
|
279
|
-
return false;
|
|
280
|
-
if (value === "-inf")
|
|
281
|
-
return -Infinity;
|
|
282
|
-
if (value === "inf" || value === "+inf")
|
|
283
|
-
return Infinity;
|
|
284
|
-
if (value === "nan" || value === "+nan" || value === "-nan")
|
|
285
|
-
return NaN;
|
|
286
|
-
if (value === "-0")
|
|
287
|
-
return integersAsBigInt ? 0n : 0;
|
|
288
|
-
let isInt = INT_REGEX.test(value);
|
|
289
|
-
if (isInt || FLOAT_REGEX.test(value)) {
|
|
290
|
-
if (LEADING_ZERO.test(value)) {
|
|
291
|
-
throw new TomlError("leading zeroes are not allowed", {
|
|
292
|
-
toml,
|
|
293
|
-
ptr
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
value = value.replace(/_/g, "");
|
|
297
|
-
let numeric = +value;
|
|
298
|
-
if (isNaN(numeric)) {
|
|
299
|
-
throw new TomlError("invalid number", {
|
|
300
|
-
toml,
|
|
301
|
-
ptr
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
if (isInt) {
|
|
305
|
-
if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
|
|
306
|
-
throw new TomlError("integer value cannot be represented losslessly", {
|
|
307
|
-
toml,
|
|
308
|
-
ptr
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
if (isInt || integersAsBigInt === true)
|
|
312
|
-
numeric = BigInt(value);
|
|
313
|
-
}
|
|
314
|
-
return numeric;
|
|
315
|
-
}
|
|
316
|
-
const date = new TomlDate(value);
|
|
317
|
-
if (!date.isValid()) {
|
|
318
|
-
throw new TomlError("invalid value", {
|
|
319
|
-
toml,
|
|
320
|
-
ptr
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
return date;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/util.js
|
|
327
|
-
function indexOfNewline(str, start = 0, end = str.length) {
|
|
328
|
-
let idx = str.indexOf("\n", start);
|
|
329
|
-
if (str[idx - 1] === "\r")
|
|
330
|
-
idx--;
|
|
331
|
-
return idx <= end ? idx : -1;
|
|
332
|
-
}
|
|
333
|
-
function skipComment(str, ptr) {
|
|
334
|
-
for (let i = ptr; i < str.length; i++) {
|
|
335
|
-
let c = str[i];
|
|
336
|
-
if (c === "\n")
|
|
337
|
-
return i;
|
|
338
|
-
if (c === "\r" && str[i + 1] === "\n")
|
|
339
|
-
return i + 1;
|
|
340
|
-
if (c < " " && c !== " " || c === "\x7F") {
|
|
341
|
-
throw new TomlError("control characters are not allowed in comments", {
|
|
342
|
-
toml: str,
|
|
343
|
-
ptr
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
return str.length;
|
|
348
|
-
}
|
|
349
|
-
function skipVoid(str, ptr, banNewLines, banComments) {
|
|
350
|
-
let c;
|
|
351
|
-
while (1) {
|
|
352
|
-
while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
|
|
353
|
-
ptr++;
|
|
354
|
-
if (banComments || c !== "#")
|
|
355
|
-
break;
|
|
356
|
-
ptr = skipComment(str, ptr);
|
|
357
|
-
}
|
|
358
|
-
return ptr;
|
|
359
|
-
}
|
|
360
|
-
function skipUntil(str, ptr, sep, end, banNewLines = false) {
|
|
361
|
-
if (!end) {
|
|
362
|
-
ptr = indexOfNewline(str, ptr);
|
|
363
|
-
return ptr < 0 ? str.length : ptr;
|
|
364
|
-
}
|
|
365
|
-
for (let i = ptr; i < str.length; i++) {
|
|
366
|
-
let c = str[i];
|
|
367
|
-
if (c === "#") {
|
|
368
|
-
i = indexOfNewline(str, i);
|
|
369
|
-
if (i < 0)
|
|
370
|
-
break;
|
|
371
|
-
} else if (c === sep) {
|
|
372
|
-
return i + 1;
|
|
373
|
-
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
374
|
-
return i;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
throw new TomlError("cannot find end of structure", {
|
|
378
|
-
toml: str,
|
|
379
|
-
ptr
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/extract.js
|
|
384
|
-
function sliceAndTrimEndOf(str, startPtr, endPtr) {
|
|
385
|
-
let value = str.slice(startPtr, endPtr);
|
|
386
|
-
let commentIdx = value.indexOf("#");
|
|
387
|
-
if (commentIdx > -1) {
|
|
388
|
-
skipComment(str, commentIdx);
|
|
389
|
-
value = value.slice(0, commentIdx);
|
|
390
|
-
}
|
|
391
|
-
return [value.trimEnd(), commentIdx];
|
|
392
|
-
}
|
|
393
|
-
function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
394
|
-
if (depth === 0) {
|
|
395
|
-
throw new TomlError("document contains excessively nested structures. aborting.", {
|
|
396
|
-
toml: str,
|
|
397
|
-
ptr
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
let c = str[ptr];
|
|
401
|
-
if (c === "[" || c === "{") {
|
|
402
|
-
let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
|
|
403
|
-
if (end) {
|
|
404
|
-
endPtr2 = skipVoid(str, endPtr2);
|
|
405
|
-
if (str[endPtr2] === ",")
|
|
406
|
-
endPtr2++;
|
|
407
|
-
else if (str[endPtr2] !== end) {
|
|
408
|
-
throw new TomlError("expected comma or end of structure", {
|
|
409
|
-
toml: str,
|
|
410
|
-
ptr: endPtr2
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return [value, endPtr2];
|
|
415
|
-
}
|
|
416
|
-
if (c === '"' || c === "'") {
|
|
417
|
-
let [parsed, endPtr2] = parseString(str, ptr);
|
|
418
|
-
if (end) {
|
|
419
|
-
endPtr2 = skipVoid(str, endPtr2);
|
|
420
|
-
if (str[endPtr2] && str[endPtr2] !== "," && str[endPtr2] !== end && str[endPtr2] !== "\n" && str[endPtr2] !== "\r") {
|
|
421
|
-
throw new TomlError("unexpected character encountered", {
|
|
422
|
-
toml: str,
|
|
423
|
-
ptr: endPtr2
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
if (str[endPtr2] === ",")
|
|
427
|
-
endPtr2++;
|
|
428
|
-
}
|
|
429
|
-
return [parsed, endPtr2];
|
|
430
|
-
}
|
|
431
|
-
let endPtr = skipUntil(str, ptr, ",", end);
|
|
432
|
-
let slice = sliceAndTrimEndOf(str, ptr, endPtr - (str[endPtr - 1] === "," ? 1 : 0));
|
|
433
|
-
if (!slice[0]) {
|
|
434
|
-
throw new TomlError("incomplete key-value declaration: no value specified", {
|
|
435
|
-
toml: str,
|
|
436
|
-
ptr
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
if (end && slice[1] > -1) {
|
|
440
|
-
endPtr = skipVoid(str, ptr + slice[1]);
|
|
441
|
-
if (str[endPtr] === ",")
|
|
442
|
-
endPtr++;
|
|
443
|
-
}
|
|
444
|
-
return [
|
|
445
|
-
parseValue(slice[0], str, ptr, integersAsBigInt),
|
|
446
|
-
endPtr
|
|
447
|
-
];
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/struct.js
|
|
451
|
-
var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
|
452
|
-
function parseKey(str, ptr, end = "=") {
|
|
453
|
-
let dot = ptr - 1;
|
|
454
|
-
let parsed = [];
|
|
455
|
-
let endPtr = str.indexOf(end, ptr);
|
|
456
|
-
if (endPtr < 0) {
|
|
457
|
-
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
458
|
-
toml: str,
|
|
459
|
-
ptr
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
do {
|
|
463
|
-
let c = str[ptr = ++dot];
|
|
464
|
-
if (c !== " " && c !== " ") {
|
|
465
|
-
if (c === '"' || c === "'") {
|
|
466
|
-
if (c === str[ptr + 1] && c === str[ptr + 2]) {
|
|
467
|
-
throw new TomlError("multiline strings are not allowed in keys", {
|
|
468
|
-
toml: str,
|
|
469
|
-
ptr
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
let [part, eos] = parseString(str, ptr);
|
|
473
|
-
dot = str.indexOf(".", eos);
|
|
474
|
-
let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
475
|
-
let newLine = indexOfNewline(strEnd);
|
|
476
|
-
if (newLine > -1) {
|
|
477
|
-
throw new TomlError("newlines are not allowed in keys", {
|
|
478
|
-
toml: str,
|
|
479
|
-
ptr: ptr + dot + newLine
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
if (strEnd.trimStart()) {
|
|
483
|
-
throw new TomlError("found extra tokens after the string part", {
|
|
484
|
-
toml: str,
|
|
485
|
-
ptr: eos
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
if (endPtr < eos) {
|
|
489
|
-
endPtr = str.indexOf(end, eos);
|
|
490
|
-
if (endPtr < 0) {
|
|
491
|
-
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
492
|
-
toml: str,
|
|
493
|
-
ptr
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
parsed.push(part);
|
|
498
|
-
} else {
|
|
499
|
-
dot = str.indexOf(".", ptr);
|
|
500
|
-
let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
501
|
-
if (!KEY_PART_RE.test(part)) {
|
|
502
|
-
throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
|
|
503
|
-
toml: str,
|
|
504
|
-
ptr
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
parsed.push(part.trimEnd());
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
} while (dot + 1 && dot < endPtr);
|
|
511
|
-
return [parsed, skipVoid(str, endPtr + 1, true, true)];
|
|
512
|
-
}
|
|
513
|
-
function parseInlineTable(str, ptr, depth, integersAsBigInt) {
|
|
514
|
-
let res = {};
|
|
515
|
-
let seen = /* @__PURE__ */ new Set();
|
|
516
|
-
let c;
|
|
517
|
-
ptr++;
|
|
518
|
-
while ((c = str[ptr++]) !== "}" && c) {
|
|
519
|
-
if (c === ",") {
|
|
520
|
-
throw new TomlError("expected value, found comma", {
|
|
521
|
-
toml: str,
|
|
522
|
-
ptr: ptr - 1
|
|
523
|
-
});
|
|
524
|
-
} else if (c === "#")
|
|
525
|
-
ptr = skipComment(str, ptr);
|
|
526
|
-
else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
|
|
527
|
-
let k;
|
|
528
|
-
let t = res;
|
|
529
|
-
let hasOwn = false;
|
|
530
|
-
let [key, keyEndPtr] = parseKey(str, ptr - 1);
|
|
531
|
-
for (let i = 0; i < key.length; i++) {
|
|
532
|
-
if (i)
|
|
533
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
534
|
-
k = key[i];
|
|
535
|
-
if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
|
|
536
|
-
throw new TomlError("trying to redefine an already defined value", {
|
|
537
|
-
toml: str,
|
|
538
|
-
ptr
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
if (!hasOwn && k === "__proto__") {
|
|
542
|
-
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
if (hasOwn) {
|
|
546
|
-
throw new TomlError("trying to redefine an already defined value", {
|
|
547
|
-
toml: str,
|
|
548
|
-
ptr
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
|
|
552
|
-
seen.add(value);
|
|
553
|
-
t[k] = value;
|
|
554
|
-
ptr = valueEndPtr;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
if (!c) {
|
|
558
|
-
throw new TomlError("unfinished table encountered", {
|
|
559
|
-
toml: str,
|
|
560
|
-
ptr
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
return [res, ptr];
|
|
564
|
-
}
|
|
565
|
-
function parseArray(str, ptr, depth, integersAsBigInt) {
|
|
566
|
-
let res = [];
|
|
567
|
-
let c;
|
|
568
|
-
ptr++;
|
|
569
|
-
while ((c = str[ptr++]) !== "]" && c) {
|
|
570
|
-
if (c === ",") {
|
|
571
|
-
throw new TomlError("expected value, found comma", {
|
|
572
|
-
toml: str,
|
|
573
|
-
ptr: ptr - 1
|
|
574
|
-
});
|
|
575
|
-
} else if (c === "#")
|
|
576
|
-
ptr = skipComment(str, ptr);
|
|
577
|
-
else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
|
|
578
|
-
let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
|
|
579
|
-
res.push(e[0]);
|
|
580
|
-
ptr = e[1];
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
if (!c) {
|
|
584
|
-
throw new TomlError("unfinished array encountered", {
|
|
585
|
-
toml: str,
|
|
586
|
-
ptr
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
return [res, ptr];
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// ../../node_modules/.bun/smol-toml@1.7.1/node_modules/smol-toml/dist/parse.js
|
|
593
|
-
function peekTable(key, table, meta, type) {
|
|
594
|
-
let t = table;
|
|
595
|
-
let m = meta;
|
|
596
|
-
let k;
|
|
597
|
-
let hasOwn = false;
|
|
598
|
-
let state;
|
|
599
|
-
for (let i = 0; i < key.length; i++) {
|
|
600
|
-
if (i) {
|
|
601
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
602
|
-
m = (state = m[k]).c;
|
|
603
|
-
if (type === 0 && (state.t === 1 || state.t === 2)) {
|
|
604
|
-
return null;
|
|
605
|
-
}
|
|
606
|
-
if (state.t === 2) {
|
|
607
|
-
let l = t.length - 1;
|
|
608
|
-
t = t[l];
|
|
609
|
-
m = m[l].c;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
k = key[i];
|
|
613
|
-
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
|
|
614
|
-
return null;
|
|
615
|
-
}
|
|
616
|
-
if (!hasOwn) {
|
|
617
|
-
if (k === "__proto__") {
|
|
618
|
-
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
619
|
-
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
620
|
-
}
|
|
621
|
-
m[k] = {
|
|
622
|
-
t: i < key.length - 1 && type === 2 ? 3 : type,
|
|
623
|
-
d: false,
|
|
624
|
-
i: 0,
|
|
625
|
-
c: {}
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
state = m[k];
|
|
630
|
-
if (state.t !== type && !(type === 1 && state.t === 3)) {
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
if (type === 2) {
|
|
634
|
-
if (!state.d) {
|
|
635
|
-
state.d = true;
|
|
636
|
-
t[k] = [];
|
|
637
|
-
}
|
|
638
|
-
t[k].push(t = {});
|
|
639
|
-
state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
|
|
640
|
-
}
|
|
641
|
-
if (state.d) {
|
|
642
|
-
return null;
|
|
643
|
-
}
|
|
644
|
-
state.d = true;
|
|
645
|
-
if (type === 1) {
|
|
646
|
-
t = hasOwn ? t[k] : t[k] = {};
|
|
647
|
-
} else if (type === 0 && hasOwn) {
|
|
648
|
-
return null;
|
|
649
|
-
}
|
|
650
|
-
return [k, t, state.c];
|
|
651
|
-
}
|
|
652
|
-
function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
|
|
653
|
-
let res = {};
|
|
654
|
-
let meta = {};
|
|
655
|
-
let tbl = res;
|
|
656
|
-
let m = meta;
|
|
657
|
-
for (let ptr = skipVoid(toml, 0); ptr < toml.length; ) {
|
|
658
|
-
if (toml[ptr] === "[") {
|
|
659
|
-
let isTableArray = toml[++ptr] === "[";
|
|
660
|
-
let k = parseKey(toml, ptr += +isTableArray, "]");
|
|
661
|
-
if (isTableArray) {
|
|
662
|
-
if (toml[k[1] - 1] !== "]") {
|
|
663
|
-
throw new TomlError("expected end of table declaration", {
|
|
664
|
-
toml,
|
|
665
|
-
ptr: k[1] - 1
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
k[1]++;
|
|
669
|
-
}
|
|
670
|
-
let p = peekTable(
|
|
671
|
-
k[0],
|
|
672
|
-
res,
|
|
673
|
-
meta,
|
|
674
|
-
isTableArray ? 2 : 1
|
|
675
|
-
/* Type.EXPLICIT */
|
|
676
|
-
);
|
|
677
|
-
if (!p) {
|
|
678
|
-
throw new TomlError("trying to redefine an already defined table or value", {
|
|
679
|
-
toml,
|
|
680
|
-
ptr
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
m = p[2];
|
|
684
|
-
tbl = p[1];
|
|
685
|
-
ptr = k[1];
|
|
686
|
-
} else {
|
|
687
|
-
let k = parseKey(toml, ptr);
|
|
688
|
-
let p = peekTable(
|
|
689
|
-
k[0],
|
|
690
|
-
tbl,
|
|
691
|
-
m,
|
|
692
|
-
0
|
|
693
|
-
/* Type.DOTTED */
|
|
694
|
-
);
|
|
695
|
-
if (!p) {
|
|
696
|
-
throw new TomlError("trying to redefine an already defined table or value", {
|
|
697
|
-
toml,
|
|
698
|
-
ptr
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
let v = extractValue(toml, k[1], void 0, maxDepth, integersAsBigInt);
|
|
702
|
-
p[1][p[0]] = v[0];
|
|
703
|
-
ptr = v[1];
|
|
704
|
-
}
|
|
705
|
-
ptr = skipVoid(toml, ptr, true);
|
|
706
|
-
if (toml[ptr] && toml[ptr] !== "\n" && toml[ptr] !== "\r") {
|
|
707
|
-
throw new TomlError("each key-value declaration must be followed by an end-of-line", {
|
|
708
|
-
toml,
|
|
709
|
-
ptr
|
|
710
|
-
});
|
|
711
|
-
}
|
|
712
|
-
ptr = skipVoid(toml, ptr);
|
|
713
|
-
}
|
|
714
|
-
return res;
|
|
715
|
-
}
|
|
36
|
+
} from "./chunk-HF3DXZEA.js";
|
|
716
37
|
|
|
717
38
|
// src/owned-paths.ts
|
|
718
39
|
import nodePath from "path";
|
|
@@ -730,18 +51,22 @@ function safewordIgnoreDirectories(namespaceRootLabel) {
|
|
|
730
51
|
}
|
|
731
52
|
function resolvedNamespaceDirectory(ctx) {
|
|
732
53
|
const label = resolvedNamespaceRootLabel(ctx);
|
|
733
|
-
if (label === "." || label.startsWith("
|
|
54
|
+
if (label === "." || label === ".." || label.startsWith("../") || SAFEWORD_IGNORE_DIRS.includes(label)) {
|
|
734
55
|
return void 0;
|
|
735
56
|
}
|
|
736
57
|
return label;
|
|
737
58
|
}
|
|
738
59
|
function resolvedNamespaceRootLabel(ctx) {
|
|
739
60
|
const root = ctx.namespaceRoot ?? resolveNamespaceRoot(ctx.cwd);
|
|
740
|
-
return nodePath.relative(ctx.cwd, root) || ".";
|
|
61
|
+
return (nodePath.relative(ctx.cwd, root) || ".").replaceAll(nodePath.sep, "/");
|
|
741
62
|
}
|
|
742
63
|
function resolvedIgnoreDirectories(ctx) {
|
|
743
64
|
return safewordIgnoreDirectories(resolvedNamespaceDirectory(ctx));
|
|
744
65
|
}
|
|
66
|
+
function durableNamespaceDirectories(ctx) {
|
|
67
|
+
const custom = resolvedNamespaceDirectory(ctx);
|
|
68
|
+
return custom === void 0 ? [".project", ".safeword-project"] : [".project", ".safeword-project", custom];
|
|
69
|
+
}
|
|
745
70
|
function dirGlobExcludeMerge(field, globForDirectory = (dir) => `${dir}/**`) {
|
|
746
71
|
return {
|
|
747
72
|
keys: [field],
|
|
@@ -759,8 +84,11 @@ function dirGlobExcludeMerge(field, globForDirectory = (dir) => `${dir}/**`) {
|
|
|
759
84
|
const safewordGlobs = new Set(
|
|
760
85
|
resolvedIgnoreDirectories(ctx).map((dir) => globForDirectory(dir))
|
|
761
86
|
);
|
|
87
|
+
const durableGlobs = new Set(
|
|
88
|
+
durableNamespaceDirectories(ctx).map((dir) => globForDirectory(dir))
|
|
89
|
+
);
|
|
762
90
|
const current = Array.isArray(existing[field]) ? existing[field] : [];
|
|
763
|
-
const cleaned = current.filter((entry) => !safewordGlobs.has(entry));
|
|
91
|
+
const cleaned = current.filter((entry) => !safewordGlobs.has(entry) || durableGlobs.has(entry));
|
|
764
92
|
const rest = Object.fromEntries(Object.entries(existing).filter(([key]) => key !== field));
|
|
765
93
|
return cleaned.length > 0 ? { ...rest, [field]: cleaned } : rest;
|
|
766
94
|
}
|
|
@@ -830,7 +158,7 @@ export function filterSafewordFiles(
|
|
|
830
158
|
}
|
|
831
159
|
|
|
832
160
|
// src/schema.ts
|
|
833
|
-
import
|
|
161
|
+
import nodePath6 from "path";
|
|
834
162
|
|
|
835
163
|
// src/packs/golang/files.ts
|
|
836
164
|
import { readFileSync } from "fs";
|
|
@@ -879,6 +207,10 @@ var SAFEWORD_ENABLE = [
|
|
|
879
207
|
// error wrapping conventions
|
|
880
208
|
"gocritic",
|
|
881
209
|
// opinionated but high-signal
|
|
210
|
+
"lll",
|
|
211
|
+
// keep code and comments readable at the shared 100-column limit
|
|
212
|
+
"godoclint",
|
|
213
|
+
// enforce readable Go documentation without requiring docs everywhere
|
|
882
214
|
"revive",
|
|
883
215
|
// flexible metalinter
|
|
884
216
|
"perfsprint",
|
|
@@ -894,7 +226,14 @@ var SAFEWORD_DISABLE = [
|
|
|
894
226
|
];
|
|
895
227
|
var SAFEWORD_EXCLUSION_PRESETS = ["std-error-handling", "common-false-positives"];
|
|
896
228
|
var SAFEWORD_SETTINGS = {
|
|
897
|
-
nestif: { "min-complexity": 4 }
|
|
229
|
+
nestif: { "min-complexity": 4 },
|
|
230
|
+
lll: { "line-length": 100 },
|
|
231
|
+
gocritic: { commentedOutCode: { minLength: 50 } },
|
|
232
|
+
godoclint: {
|
|
233
|
+
default: "none",
|
|
234
|
+
enable: ["max-len"],
|
|
235
|
+
options: { "max-len": { length: 100 } }
|
|
236
|
+
}
|
|
898
237
|
};
|
|
899
238
|
function buildStandaloneConfig() {
|
|
900
239
|
return {
|
|
@@ -1042,310 +381,9 @@ var golangManagedFiles = {
|
|
|
1042
381
|
|
|
1043
382
|
// src/packs/python/files.ts
|
|
1044
383
|
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
1045
|
-
import nodePath4 from "path";
|
|
1046
|
-
|
|
1047
|
-
// src/packs/python/setup.ts
|
|
1048
|
-
import { execFileSync } from "child_process";
|
|
1049
|
-
import { readdirSync, realpathSync } from "fs";
|
|
1050
384
|
import nodePath3 from "path";
|
|
1051
|
-
var PYTHON_LAYERS = {
|
|
1052
|
-
domain: ["domain", "models", "entities", "core"],
|
|
1053
|
-
services: ["services", "usecases", "application"],
|
|
1054
|
-
infra: ["infra", "infrastructure", "adapters", "repositories"],
|
|
1055
|
-
api: ["api", "routes", "handlers", "views", "controllers"]
|
|
1056
|
-
};
|
|
1057
|
-
function hasAnyLayerPattern(cwd, patterns) {
|
|
1058
|
-
for (const pattern of patterns) {
|
|
1059
|
-
const srcPath = nodePath3.join(cwd, "src", pattern);
|
|
1060
|
-
const rootPath = nodePath3.join(cwd, pattern);
|
|
1061
|
-
if (exists(srcPath) || exists(rootPath)) {
|
|
1062
|
-
return true;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
return false;
|
|
1066
|
-
}
|
|
1067
|
-
function detectPythonLayers(cwd) {
|
|
1068
|
-
const detected = [];
|
|
1069
|
-
for (const [layer, patterns] of Object.entries(PYTHON_LAYERS)) {
|
|
1070
|
-
if (hasAnyLayerPattern(cwd, patterns)) {
|
|
1071
|
-
detected.push(layer);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
const layerOrder = ["domain", "services", "infra", "api"];
|
|
1075
|
-
return layerOrder.filter((layer) => detected.includes(layer));
|
|
1076
|
-
}
|
|
1077
|
-
function detectRootPackage(cwd) {
|
|
1078
|
-
const pyprojectPath = nodePath3.join(cwd, "pyproject.toml");
|
|
1079
|
-
const content = readFileSafe(pyprojectPath);
|
|
1080
|
-
if (content) {
|
|
1081
|
-
const nameMatch = /^name\s*=\s*"([^"]+)"/m.exec(content);
|
|
1082
|
-
if (nameMatch?.[1]) {
|
|
1083
|
-
return nameMatch[1].replaceAll("-", "_");
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
if (exists(nodePath3.join(cwd, "src"))) {
|
|
1087
|
-
return "src";
|
|
1088
|
-
}
|
|
1089
|
-
return nodePath3.basename(cwd).replaceAll("-", "_");
|
|
1090
|
-
}
|
|
1091
|
-
var NON_PACKAGE_DIRS = /* @__PURE__ */ new Set([
|
|
1092
|
-
"tests",
|
|
1093
|
-
"test",
|
|
1094
|
-
"docs",
|
|
1095
|
-
"examples",
|
|
1096
|
-
"scripts",
|
|
1097
|
-
"node_modules",
|
|
1098
|
-
"venv"
|
|
1099
|
-
]);
|
|
1100
|
-
function importablePackagesIn(dir) {
|
|
1101
|
-
if (!exists(dir)) return [];
|
|
1102
|
-
try {
|
|
1103
|
-
return readdirSync(dir, { withFileTypes: true }).filter(
|
|
1104
|
-
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !NON_PACKAGE_DIRS.has(entry.name) && exists(nodePath3.join(dir, entry.name, "__init__.py"))
|
|
1105
|
-
).map((entry) => entry.name);
|
|
1106
|
-
} catch {
|
|
1107
|
-
return [];
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
function detectSolePackage(cwd) {
|
|
1111
|
-
const candidates = [
|
|
1112
|
-
...importablePackagesIn(cwd),
|
|
1113
|
-
...importablePackagesIn(nodePath3.join(cwd, "src"))
|
|
1114
|
-
];
|
|
1115
|
-
return candidates.length === 1 ? candidates[0] : void 0;
|
|
1116
|
-
}
|
|
1117
|
-
var PYTHON_DEPENDENCY_SEPARATORS = /* @__PURE__ */ new Set(["[", "<", ">", "=", "!", "~", ";", "@"]);
|
|
1118
|
-
function normalizePythonDistributionName(value) {
|
|
1119
|
-
return value.trim().toLowerCase().replaceAll(/[-_.]+/g, "-");
|
|
1120
|
-
}
|
|
1121
|
-
function startsPythonDependency(value, dependency) {
|
|
1122
|
-
const candidate = normalizePythonDistributionName(value);
|
|
1123
|
-
const normalizedDependency = normalizePythonDistributionName(dependency);
|
|
1124
|
-
if (!candidate.startsWith(normalizedDependency)) return false;
|
|
1125
|
-
const next = candidate.at(normalizedDependency.length);
|
|
1126
|
-
return next === void 0 || PYTHON_DEPENDENCY_SEPARATORS.has(next) || next.trim() === "";
|
|
1127
|
-
}
|
|
1128
|
-
function asTomlTable(value) {
|
|
1129
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1130
|
-
}
|
|
1131
|
-
function parseTomlTable(content) {
|
|
1132
|
-
try {
|
|
1133
|
-
return asTomlTable(parse(content));
|
|
1134
|
-
} catch {
|
|
1135
|
-
return void 0;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
function tomlTableAt(table, path) {
|
|
1139
|
-
let current = table;
|
|
1140
|
-
for (const key of path) {
|
|
1141
|
-
current = current === void 0 ? void 0 : asTomlTable(current[key]);
|
|
1142
|
-
}
|
|
1143
|
-
return current;
|
|
1144
|
-
}
|
|
1145
|
-
function tomlStringArray(value) {
|
|
1146
|
-
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
1147
|
-
}
|
|
1148
|
-
function dependencyGroupSpecs(groups, groupName, visited = /* @__PURE__ */ new Set()) {
|
|
1149
|
-
if (visited.has(groupName)) return [];
|
|
1150
|
-
visited.add(groupName);
|
|
1151
|
-
return (Array.isArray(groups[groupName]) ? groups[groupName] : []).flatMap((item) => {
|
|
1152
|
-
if (typeof item === "string") return [item];
|
|
1153
|
-
const includeGroup = asTomlTable(item)?.["include-group"];
|
|
1154
|
-
return typeof includeGroup === "string" ? dependencyGroupSpecs(groups, includeGroup, visited) : [];
|
|
1155
|
-
});
|
|
1156
|
-
}
|
|
1157
|
-
function pyprojectDependencySpecs(document) {
|
|
1158
|
-
const project = asTomlTable(document.project);
|
|
1159
|
-
const optionalDependencies = asTomlTable(project?.["optional-dependencies"]);
|
|
1160
|
-
const dependencyGroups = asTomlTable(document["dependency-groups"]);
|
|
1161
|
-
const uv = tomlTableAt(document, ["tool", "uv"]);
|
|
1162
|
-
return [
|
|
1163
|
-
...tomlStringArray(project?.dependencies),
|
|
1164
|
-
...Object.values(optionalDependencies ?? {}).flatMap((value) => tomlStringArray(value)),
|
|
1165
|
-
...dependencyGroups === void 0 ? [] : Object.keys(dependencyGroups).flatMap(
|
|
1166
|
-
(groupName) => dependencyGroupSpecs(dependencyGroups, groupName)
|
|
1167
|
-
),
|
|
1168
|
-
...tomlStringArray(uv?.["dev-dependencies"])
|
|
1169
|
-
];
|
|
1170
|
-
}
|
|
1171
|
-
function poetryDependencyNames(document) {
|
|
1172
|
-
const poetry = tomlTableAt(document, ["tool", "poetry"]);
|
|
1173
|
-
const groups = asTomlTable(poetry?.group);
|
|
1174
|
-
const groupNames = Object.values(groups ?? {}).flatMap(
|
|
1175
|
-
(group) => Object.keys(asTomlTable(asTomlTable(group)?.dependencies) ?? {})
|
|
1176
|
-
);
|
|
1177
|
-
return [
|
|
1178
|
-
...Object.keys(asTomlTable(poetry?.dependencies) ?? {}),
|
|
1179
|
-
...Object.keys(asTomlTable(poetry?.["dev-dependencies"]) ?? {}),
|
|
1180
|
-
...groupNames
|
|
1181
|
-
];
|
|
1182
|
-
}
|
|
1183
|
-
function hasPythonDependencyName(names, dependency) {
|
|
1184
|
-
const normalizedDependency = normalizePythonDistributionName(dependency);
|
|
1185
|
-
return names.some((name) => normalizePythonDistributionName(name) === normalizedDependency);
|
|
1186
|
-
}
|
|
1187
|
-
function containsPyprojectPythonDependency(content, dependency) {
|
|
1188
|
-
const document = parseTomlTable(content);
|
|
1189
|
-
if (document === void 0) return false;
|
|
1190
|
-
return hasPythonDependencyName(poetryDependencyNames(document), dependency) || pyprojectDependencySpecs(document).some(
|
|
1191
|
-
(specification) => startsPythonDependency(specification, dependency)
|
|
1192
|
-
);
|
|
1193
|
-
}
|
|
1194
|
-
function containsPipfilePythonDependency(content, dependency) {
|
|
1195
|
-
const document = parseTomlTable(content);
|
|
1196
|
-
if (document === void 0) return false;
|
|
1197
|
-
return hasPythonDependencyName(
|
|
1198
|
-
[
|
|
1199
|
-
...Object.keys(asTomlTable(document.packages) ?? {}),
|
|
1200
|
-
...Object.keys(asTomlTable(document["dev-packages"]) ?? {})
|
|
1201
|
-
],
|
|
1202
|
-
dependency
|
|
1203
|
-
);
|
|
1204
|
-
}
|
|
1205
|
-
function shortRequirementsInclude(declaration) {
|
|
1206
|
-
if (!declaration.startsWith("-r")) return void 0;
|
|
1207
|
-
return declaration.slice(2).trim() || void 0;
|
|
1208
|
-
}
|
|
1209
|
-
function longRequirementsInclude(declaration) {
|
|
1210
|
-
const longOption = "--requirement";
|
|
1211
|
-
if (!declaration.startsWith(longOption)) return void 0;
|
|
1212
|
-
const suffix = declaration.slice(longOption.length);
|
|
1213
|
-
if (suffix.startsWith("=")) return suffix.slice(1).trim() || void 0;
|
|
1214
|
-
if (suffix.trimStart().length === suffix.length) return void 0;
|
|
1215
|
-
return suffix.trim() || void 0;
|
|
1216
|
-
}
|
|
1217
|
-
function unquoteRequirementsInclude(include) {
|
|
1218
|
-
if (include.startsWith('"') && include.endsWith('"') || include.startsWith("'") && include.endsWith("'")) {
|
|
1219
|
-
return include.slice(1, -1);
|
|
1220
|
-
}
|
|
1221
|
-
return include;
|
|
1222
|
-
}
|
|
1223
|
-
function requirementsIncludePath(line) {
|
|
1224
|
-
const declaration = (line.split("#", 1)[0] ?? "").trim();
|
|
1225
|
-
const include = shortRequirementsInclude(declaration) ?? longRequirementsInclude(declaration);
|
|
1226
|
-
return include === void 0 ? void 0 : unquoteRequirementsInclude(include);
|
|
1227
|
-
}
|
|
1228
|
-
function isPathWithinDirectory(candidate, directory) {
|
|
1229
|
-
const relative = nodePath3.relative(directory, candidate);
|
|
1230
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${nodePath3.sep}`);
|
|
1231
|
-
}
|
|
1232
|
-
function isRealPathWithinDirectory(candidate, directory) {
|
|
1233
|
-
try {
|
|
1234
|
-
return isPathWithinDirectory(realpathSync(candidate), realpathSync(directory));
|
|
1235
|
-
} catch {
|
|
1236
|
-
return false;
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
function containsRequirementsPythonDependency(projectDirectory, requirementsPath, dependency, visited = /* @__PURE__ */ new Set()) {
|
|
1240
|
-
const resolvedRequirementsPath = nodePath3.resolve(requirementsPath);
|
|
1241
|
-
if (!isRealPathWithinDirectory(resolvedRequirementsPath, projectDirectory) || visited.has(resolvedRequirementsPath)) {
|
|
1242
|
-
return false;
|
|
1243
|
-
}
|
|
1244
|
-
visited.add(resolvedRequirementsPath);
|
|
1245
|
-
const content = readFileSafe(resolvedRequirementsPath);
|
|
1246
|
-
if (content === void 0) return false;
|
|
1247
|
-
return content.split("\n").some((line) => {
|
|
1248
|
-
if (line.trimStart().startsWith("#")) return false;
|
|
1249
|
-
const declaration = line.split("#", 1)[0] ?? "";
|
|
1250
|
-
if (startsPythonDependency(declaration, dependency)) return true;
|
|
1251
|
-
const include = requirementsIncludePath(line);
|
|
1252
|
-
if (include === void 0 || nodePath3.isAbsolute(include)) return false;
|
|
1253
|
-
const includePath = nodePath3.resolve(nodePath3.dirname(resolvedRequirementsPath), include);
|
|
1254
|
-
return containsRequirementsPythonDependency(projectDirectory, includePath, dependency, visited);
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
1257
|
-
function hasPythonDependency(cwd, dependency) {
|
|
1258
|
-
const pyprojectContent = readFileSafe(nodePath3.join(cwd, "pyproject.toml"));
|
|
1259
|
-
const pipfileContent = readFileSafe(nodePath3.join(cwd, "Pipfile"));
|
|
1260
|
-
return pyprojectContent !== void 0 && containsPyprojectPythonDependency(pyprojectContent, dependency) || pipfileContent !== void 0 && containsPipfilePythonDependency(pipfileContent, dependency) || containsRequirementsPythonDependency(cwd, nodePath3.join(cwd, "requirements.txt"), dependency);
|
|
1261
|
-
}
|
|
1262
|
-
function hasRuffDependency(cwd) {
|
|
1263
|
-
return hasPythonDependency(cwd, "ruff");
|
|
1264
|
-
}
|
|
1265
|
-
function detectPythonPackageManager(cwd) {
|
|
1266
|
-
if (exists(nodePath3.join(cwd, "uv.lock"))) {
|
|
1267
|
-
return "uv";
|
|
1268
|
-
}
|
|
1269
|
-
if (exists(nodePath3.join(cwd, "poetry.lock"))) {
|
|
1270
|
-
return "poetry";
|
|
1271
|
-
}
|
|
1272
|
-
const pyprojectPath = nodePath3.join(cwd, "pyproject.toml");
|
|
1273
|
-
const pyprojectContent = readFileSafe(pyprojectPath);
|
|
1274
|
-
if (pyprojectContent?.includes("[tool.poetry]")) {
|
|
1275
|
-
return "poetry";
|
|
1276
|
-
}
|
|
1277
|
-
if (exists(nodePath3.join(cwd, "Pipfile"))) {
|
|
1278
|
-
return "pipenv";
|
|
1279
|
-
}
|
|
1280
|
-
return "pip";
|
|
1281
|
-
}
|
|
1282
|
-
function getPythonInstallCommand(cwd, tools = ["ruff"]) {
|
|
1283
|
-
const pm = detectPythonPackageManager(cwd);
|
|
1284
|
-
const toolList = tools.join(" ");
|
|
1285
|
-
switch (pm) {
|
|
1286
|
-
case "uv": {
|
|
1287
|
-
return `uv add --dev ${toolList}`;
|
|
1288
|
-
}
|
|
1289
|
-
case "poetry": {
|
|
1290
|
-
return `poetry add --group dev ${toolList}`;
|
|
1291
|
-
}
|
|
1292
|
-
case "pipenv": {
|
|
1293
|
-
return `pipenv install --dev ${toolList}`;
|
|
1294
|
-
}
|
|
1295
|
-
case "pip": {
|
|
1296
|
-
return `pip install ${toolList}`;
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
function pythonInstallInvocation(cwd, tools) {
|
|
1301
|
-
switch (detectPythonPackageManager(cwd)) {
|
|
1302
|
-
case "uv": {
|
|
1303
|
-
return { command: "uv", arguments: ["add", "--dev", ...tools] };
|
|
1304
|
-
}
|
|
1305
|
-
case "poetry": {
|
|
1306
|
-
return { command: "poetry", arguments: ["add", "--group", "dev", ...tools] };
|
|
1307
|
-
}
|
|
1308
|
-
case "pipenv": {
|
|
1309
|
-
return { command: "pipenv", arguments: ["install", "--dev", ...tools] };
|
|
1310
|
-
}
|
|
1311
|
-
case "pip": {
|
|
1312
|
-
return { command: "pip", arguments: ["install", ...tools] };
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
function getPythonTools(includeImportLinter) {
|
|
1317
|
-
const tools = ["ruff", "mypy", "deadcode"];
|
|
1318
|
-
if (includeImportLinter) tools.push("import-linter");
|
|
1319
|
-
return tools;
|
|
1320
|
-
}
|
|
1321
|
-
function getMissingPythonToolDependencies(cwd, includeImportLinter) {
|
|
1322
|
-
return getPythonTools(includeImportLinter).filter((tool) => !hasPythonDependency(cwd, tool));
|
|
1323
|
-
}
|
|
1324
|
-
function installPythonDependencies(cwd, tools) {
|
|
1325
|
-
if (tools.length === 0) return true;
|
|
1326
|
-
if (process.env.SAFEWORD_SKIP_INSTALL) return true;
|
|
1327
|
-
const pm = detectPythonPackageManager(cwd);
|
|
1328
|
-
if (pm === "pip") return false;
|
|
1329
|
-
try {
|
|
1330
|
-
const invocation = pythonInstallInvocation(cwd, tools);
|
|
1331
|
-
execFileSync(invocation.command, invocation.arguments, {
|
|
1332
|
-
cwd,
|
|
1333
|
-
stdio: "pipe",
|
|
1334
|
-
timeout: 6e4
|
|
1335
|
-
// 60s timeout to prevent hanging on network/resolution issues
|
|
1336
|
-
});
|
|
1337
|
-
return true;
|
|
1338
|
-
} catch {
|
|
1339
|
-
return false;
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
function setupPythonTooling() {
|
|
1343
|
-
return { files: [] };
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
// src/packs/python/files.ts
|
|
1347
385
|
function hasLegacyCustomerRuffExtend(cwd) {
|
|
1348
|
-
const ruffPath =
|
|
386
|
+
const ruffPath = nodePath3.join(cwd, "ruff.toml");
|
|
1349
387
|
if (!existsSync(ruffPath)) return false;
|
|
1350
388
|
try {
|
|
1351
389
|
const content = readFileSync2(ruffPath, "utf8");
|
|
@@ -1395,7 +433,6 @@ var SAFEWORD_RULES = [
|
|
|
1395
433
|
var RUFF_SHARED_SETTINGS = `ignore = [
|
|
1396
434
|
"COM812", # missing trailing comma - conflicts with formatter
|
|
1397
435
|
"ISC001", # single-line-implicit-string-concatenation - conflicts with formatter
|
|
1398
|
-
"E501", # line too long - formatter handles this
|
|
1399
436
|
]
|
|
1400
437
|
|
|
1401
438
|
[lint.per-file-ignores]
|
|
@@ -1539,7 +576,7 @@ function importLinterScaffoldContent(cwd) {
|
|
|
1539
576
|
|
|
1540
577
|
// src/packs/rust/files.ts
|
|
1541
578
|
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
|
|
1542
|
-
import
|
|
579
|
+
import nodePath4 from "path";
|
|
1543
580
|
var SAFEWORD_CLIPPY_THRESHOLDS = {
|
|
1544
581
|
"cognitive-complexity-threshold": 10,
|
|
1545
582
|
"too-many-arguments-threshold": 5,
|
|
@@ -1562,7 +599,7 @@ function generateSafewordClippyConfig(existingConfig, cwd) {
|
|
|
1562
599
|
${generateClippyThresholds()}
|
|
1563
600
|
`;
|
|
1564
601
|
}
|
|
1565
|
-
const configPath =
|
|
602
|
+
const configPath = nodePath4.join(cwd, existingConfig);
|
|
1566
603
|
if (!existsSync2(configPath)) {
|
|
1567
604
|
return `# Safeword clippy config - standalone (no project config to merge)
|
|
1568
605
|
# Used by hooks for LLM enforcement.
|
|
@@ -1626,7 +663,7 @@ function editionInSection(content, header) {
|
|
|
1626
663
|
function resolveRustEdition(cwd) {
|
|
1627
664
|
let content;
|
|
1628
665
|
try {
|
|
1629
|
-
content = readFileSync3(
|
|
666
|
+
content = readFileSync3(nodePath4.join(cwd, "Cargo.toml"), "utf8");
|
|
1630
667
|
} catch {
|
|
1631
668
|
return FALLBACK_RUST_EDITION;
|
|
1632
669
|
}
|
|
@@ -1728,8 +765,8 @@ var rustManagedFiles = {
|
|
|
1728
765
|
|
|
1729
766
|
// src/packs/sql/dialect.ts
|
|
1730
767
|
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1731
|
-
import
|
|
1732
|
-
import
|
|
768
|
+
import nodePath5 from "path";
|
|
769
|
+
import process from "process";
|
|
1733
770
|
import YAML2 from "yaml";
|
|
1734
771
|
var ADAPTER_TO_DIALECT = {
|
|
1735
772
|
postgres: "postgres",
|
|
@@ -1816,16 +853,16 @@ function detectFromProfiles(cwd) {
|
|
|
1816
853
|
if (!dbtProjectDirectory) return void 0;
|
|
1817
854
|
try {
|
|
1818
855
|
const projectContent = readFileSync4(
|
|
1819
|
-
|
|
856
|
+
nodePath5.join(dbtProjectDirectory, "dbt_project.yml"),
|
|
1820
857
|
"utf8"
|
|
1821
858
|
);
|
|
1822
859
|
const project = YAML2.parse(projectContent, { schema: "failsafe" });
|
|
1823
860
|
const profileName = project.profile;
|
|
1824
861
|
if (typeof profileName !== "string") return void 0;
|
|
1825
862
|
const candidates = [
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
863
|
+
nodePath5.join(dbtProjectDirectory, "profiles.yml"),
|
|
864
|
+
nodePath5.join(dbtProjectDirectory, "dbt", "profiles.yml"),
|
|
865
|
+
nodePath5.join(process.env.HOME ?? "", ".dbt", "profiles.yml")
|
|
1829
866
|
];
|
|
1830
867
|
for (const profilesPath of candidates) {
|
|
1831
868
|
const adapterType = resolveProfileType(profilesPath, profileName);
|
|
@@ -1839,8 +876,8 @@ function detectFromProfiles(cwd) {
|
|
|
1839
876
|
function detectFromPythonDependencies(cwd) {
|
|
1840
877
|
const directory = findInTree(cwd, "requirements.txt") ?? findInTree(cwd, "pyproject.toml");
|
|
1841
878
|
if (!directory) return void 0;
|
|
1842
|
-
const requirementsPath =
|
|
1843
|
-
const pyprojectPath =
|
|
879
|
+
const requirementsPath = nodePath5.join(directory, "requirements.txt");
|
|
880
|
+
const pyprojectPath = nodePath5.join(directory, "pyproject.toml");
|
|
1844
881
|
try {
|
|
1845
882
|
let content;
|
|
1846
883
|
if (existsSync3(requirementsPath)) {
|
|
@@ -1864,7 +901,7 @@ function detectFromSqlcConfig(cwd) {
|
|
|
1864
901
|
const directory = findInTree(cwd, filename);
|
|
1865
902
|
if (!directory) continue;
|
|
1866
903
|
try {
|
|
1867
|
-
const content = readFileSync4(
|
|
904
|
+
const content = readFileSync4(nodePath5.join(directory, filename), "utf8");
|
|
1868
905
|
const match = /engine['":\s]+(\w+)/.exec(content);
|
|
1869
906
|
if (match?.[1]) return ADAPTER_TO_DIALECT[match[1]] ?? match[1];
|
|
1870
907
|
} catch {
|
|
@@ -1874,7 +911,7 @@ function detectFromSqlcConfig(cwd) {
|
|
|
1874
911
|
return void 0;
|
|
1875
912
|
}
|
|
1876
913
|
function detectFromPrismaSchema(cwd) {
|
|
1877
|
-
const schemaPath =
|
|
914
|
+
const schemaPath = nodePath5.join(cwd, "prisma", "schema.prisma");
|
|
1878
915
|
if (!existsSync3(schemaPath)) return void 0;
|
|
1879
916
|
try {
|
|
1880
917
|
const content = readFileSync4(schemaPath, "utf8");
|
|
@@ -1887,7 +924,7 @@ function detectFromPrismaSchema(cwd) {
|
|
|
1887
924
|
}
|
|
1888
925
|
function detectFromDrizzleConfig(cwd) {
|
|
1889
926
|
for (const filename of ["drizzle.config.ts", "drizzle.config.js", "drizzle.config.mjs"]) {
|
|
1890
|
-
const filePath =
|
|
927
|
+
const filePath = nodePath5.join(cwd, filename);
|
|
1891
928
|
if (!existsSync3(filePath)) continue;
|
|
1892
929
|
try {
|
|
1893
930
|
const content = readFileSync4(filePath, "utf8");
|
|
@@ -1900,7 +937,7 @@ function detectFromDrizzleConfig(cwd) {
|
|
|
1900
937
|
return void 0;
|
|
1901
938
|
}
|
|
1902
939
|
function detectFromDatabaseUrl(cwd) {
|
|
1903
|
-
const envPath =
|
|
940
|
+
const envPath = nodePath5.join(cwd, ".env");
|
|
1904
941
|
if (!existsSync3(envPath)) return void 0;
|
|
1905
942
|
try {
|
|
1906
943
|
const content = readFileSync4(envPath, "utf8");
|
|
@@ -2099,8 +1136,9 @@ var BIOME_JSON_MERGE = {
|
|
|
2099
1136
|
"!.safeword/**",
|
|
2100
1137
|
...resolvedIgnoreDirectories(ctx).map((dir) => `!${dir}`)
|
|
2101
1138
|
]);
|
|
1139
|
+
const durableExcludes = new Set(durableNamespaceDirectories(ctx).map((dir) => `!${dir}`));
|
|
2102
1140
|
const cleanedIncludes = existingIncludes.filter(
|
|
2103
|
-
(entry) => !safewordExcludes.has(entry)
|
|
1141
|
+
(entry) => !safewordExcludes.has(entry) || durableExcludes.has(entry)
|
|
2104
1142
|
);
|
|
2105
1143
|
const cleanedFiles = { ...files };
|
|
2106
1144
|
if (cleanedIncludes.length > 0) {
|
|
@@ -2197,6 +1235,9 @@ function addScriptIfMissing(scripts, name, command) {
|
|
|
2197
1235
|
if (!existing) scripts[name] = command;
|
|
2198
1236
|
}
|
|
2199
1237
|
var GHERKIN_LINT_SCRIPT = "safeword project lint-gherkin";
|
|
1238
|
+
function removeScriptIfEqual(scripts, name, safewordValue) {
|
|
1239
|
+
return scripts[name] === safewordValue ? Object.fromEntries(Object.entries(scripts).filter(([key]) => key !== name)) : scripts;
|
|
1240
|
+
}
|
|
2200
1241
|
function mergeLintScripts(scripts, projectType) {
|
|
2201
1242
|
addScriptIfMissing(scripts, "lint:gherkin", GHERKIN_LINT_SCRIPT);
|
|
2202
1243
|
if (projectType.existingLinter) {
|
|
@@ -2253,13 +1294,10 @@ var typescriptJsonMerges = {
|
|
|
2253
1294
|
},
|
|
2254
1295
|
unmerge: (existing, _ctx) => {
|
|
2255
1296
|
const result = { ...existing };
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
delete scripts.knip;
|
|
2261
|
-
delete scripts.publint;
|
|
2262
|
-
delete scripts["test:bdd"];
|
|
1297
|
+
let scripts = { ...existing.scripts };
|
|
1298
|
+
scripts = removeScriptIfEqual(scripts, "lint", SAFEWORD_PRIMARY_LINT_SCRIPT);
|
|
1299
|
+
scripts = removeScriptIfEqual(scripts, "lint:gherkin", GHERKIN_LINT_SCRIPT);
|
|
1300
|
+
scripts = removeScriptIfEqual(scripts, "test:bdd", "cucumber-js");
|
|
2263
1301
|
assignOrPrune(result, "scripts", scripts);
|
|
2264
1302
|
return result;
|
|
2265
1303
|
}
|
|
@@ -2299,6 +1337,7 @@ var typescriptJsonMerges = {
|
|
|
2299
1337
|
return result;
|
|
2300
1338
|
},
|
|
2301
1339
|
unmerge: (existing, ctx) => {
|
|
1340
|
+
if (ctx.projectType.existingPrettierConfig) return existing;
|
|
2302
1341
|
const result = { ...existing };
|
|
2303
1342
|
const safewordPlugins = new Set(getPrettierPlugins(ctx.projectType));
|
|
2304
1343
|
if (Array.isArray(result.plugins)) {
|
|
@@ -2624,9 +1663,12 @@ var MCP_JSON_MERGE = {
|
|
|
2624
1663
|
},
|
|
2625
1664
|
unmerge: (existing) => {
|
|
2626
1665
|
const result = { ...existing };
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
1666
|
+
let mcpServers = { ...existing.mcpServers };
|
|
1667
|
+
for (const name of ["context7", "playwright"]) {
|
|
1668
|
+
if (JSON.stringify(mcpServers[name]) === JSON.stringify(MCP_SERVERS[name])) {
|
|
1669
|
+
mcpServers = Object.fromEntries(Object.entries(mcpServers).filter(([key]) => key !== name));
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
2630
1672
|
assignOrPrune(result, "mcpServers", mcpServers);
|
|
2631
1673
|
return result;
|
|
2632
1674
|
}
|
|
@@ -2759,15 +1801,17 @@ var BDD_LANE_FILE_PATHS = [
|
|
|
2759
1801
|
];
|
|
2760
1802
|
var BDD_LANE_SCRIPT = "test:bdd";
|
|
2761
1803
|
function bddLaneFile(templatePath) {
|
|
1804
|
+
const templateContent = () => readFile(nodePath6.join(getTemplatesDirectory(), templatePath));
|
|
2762
1805
|
return {
|
|
2763
1806
|
// `template` declares provenance for the schema↔templates contract;
|
|
2764
1807
|
// the generator (which takes precedence) gates on harness detection.
|
|
2765
1808
|
template: templatePath,
|
|
2766
|
-
generator: (ctx) => ctx.projectType.scaffoldBddLane ?
|
|
1809
|
+
generator: (ctx) => ctx.projectType.scaffoldBddLane ? templateContent() : void 0,
|
|
1810
|
+
removeIfUnmodified: templateContent
|
|
2767
1811
|
};
|
|
2768
1812
|
}
|
|
2769
1813
|
function prReviewEnabled(cwd) {
|
|
2770
|
-
const content = readFileSafe(
|
|
1814
|
+
const content = readFileSafe(nodePath6.join(cwd, ".safeword", "config.json"));
|
|
2771
1815
|
if (content === void 0) return false;
|
|
2772
1816
|
try {
|
|
2773
1817
|
const config = JSON.parse(content);
|
|
@@ -2781,7 +1825,7 @@ function normalizePrReviewWorkflowVersionPins(content) {
|
|
|
2781
1825
|
const segments = content.split(commandPrefix);
|
|
2782
1826
|
return segments.map((segment, index) => {
|
|
2783
1827
|
if (index === 0) return segment;
|
|
2784
|
-
const end = segment.
|
|
1828
|
+
const end = segment.search(/\s/u);
|
|
2785
1829
|
if (end === -1) return segment;
|
|
2786
1830
|
const version = segment.slice(0, end);
|
|
2787
1831
|
const coreIdentifiers = version.split("-", 1)[0]?.split(".") ?? [];
|
|
@@ -2793,7 +1837,7 @@ function normalizePrReviewWorkflowVersionPins(content) {
|
|
|
2793
1837
|
}).join(commandPrefix);
|
|
2794
1838
|
}
|
|
2795
1839
|
function prReviewWorkflowFile(templatePath) {
|
|
2796
|
-
const workflowContent = () => readFile(
|
|
1840
|
+
const workflowContent = () => readFile(nodePath6.join(getTemplatesDirectory(), templatePath)).split("__SAFEWORD_VERSION__").join(VERSION);
|
|
2797
1841
|
return {
|
|
2798
1842
|
template: templatePath,
|
|
2799
1843
|
generator: (ctx) => prReviewEnabled(ctx.cwd) ? workflowContent() : void 0,
|
|
@@ -2852,11 +1896,16 @@ var SAFEWORD_SCHEMA = {
|
|
|
2852
1896
|
".claude/commands",
|
|
2853
1897
|
// Custom-agent homes (GH628F): users keep their own agents in this dir —
|
|
2854
1898
|
// add-to, never own. Codex is plugin-only and receives no project scaffold.
|
|
2855
|
-
".claude/agents"
|
|
1899
|
+
".claude/agents",
|
|
1900
|
+
// Project-owned namespace directories. Safeword creates these when missing,
|
|
1901
|
+
// but uninstall must leave the resolved namespace byte-for-byte untouched.
|
|
1902
|
+
".safeword-project/learnings",
|
|
1903
|
+
".safeword-project/tickets",
|
|
1904
|
+
".safeword-project/tickets/completed",
|
|
1905
|
+
".safeword-project/tmp"
|
|
2856
1906
|
],
|
|
2857
|
-
//
|
|
1907
|
+
// Runtime data directories removed on reset only when empty.
|
|
2858
1908
|
preservedDirs: [
|
|
2859
|
-
".safeword-project/learnings",
|
|
2860
1909
|
".safeword/logs",
|
|
2861
1910
|
// Runtime cloud-filing spool (BNGK9W) — per-session drafts + nudge markers the
|
|
2862
1911
|
// retro writes at runtime; user/runtime data the schema does not own.
|
|
@@ -2867,10 +1916,7 @@ var SAFEWORD_SCHEMA = {
|
|
|
2867
1916
|
".safeword/self-reports",
|
|
2868
1917
|
// Authored collisions retained during automatic .safeword-project → .project
|
|
2869
1918
|
// migration. Recovery copies are user data, not deployed framework assets.
|
|
2870
|
-
".safeword/namespace-migration-conflicts-v1"
|
|
2871
|
-
".safeword-project/tickets",
|
|
2872
|
-
".safeword-project/tickets/completed",
|
|
2873
|
-
".safeword-project/tmp"
|
|
1919
|
+
".safeword/namespace-migration-conflicts-v1"
|
|
2874
1920
|
],
|
|
2875
1921
|
// Files to delete on upgrade (renamed or removed in newer versions)
|
|
2876
1922
|
deprecatedFiles: [
|
|
@@ -3000,8 +2046,6 @@ var SAFEWORD_SCHEMA = {
|
|
|
3000
2046
|
// Files owned by safeword (overwritten on upgrade if content changed)
|
|
3001
2047
|
// (bddLaneFile entries: see the helper defined above the schema)
|
|
3002
2048
|
ownedFiles: {
|
|
3003
|
-
// Project root config files (for audit/quality tools)
|
|
3004
|
-
".jscpd.json": { template: ".jscpd.json" },
|
|
3005
2049
|
// BDD acceptance lane config (ticket 102b) — safeword-owned; the lane's
|
|
3006
2050
|
// working files (features/, steps/) are customer-owned in managedFiles.
|
|
3007
2051
|
// Suppressed when the repo has its own cucumber harness (56JCFZ).
|
|
@@ -3472,6 +2516,9 @@ var SAFEWORD_SCHEMA = {
|
|
|
3472
2516
|
},
|
|
3473
2517
|
// Files created if missing, updated only if content matches current template
|
|
3474
2518
|
managedFiles: {
|
|
2519
|
+
// Project-root audit config is scaffolded when absent, then customer-owned.
|
|
2520
|
+
// Full uninstall removes it only while it still matches Safeword's template.
|
|
2521
|
+
".jscpd.json": { template: ".jscpd.json" },
|
|
3475
2522
|
// Package-owned Codex runtime adapters. Their generator intentionally
|
|
3476
2523
|
// returns undefined: the plugin CLI executes them from the npm package,
|
|
3477
2524
|
// never from a customer repository.
|
|
@@ -3660,16 +2707,17 @@ var SAFEWORD_SCHEMA = {
|
|
|
3660
2707
|
# Safeword - Local cache and transient state
|
|
3661
2708
|
${SAFEWORD_TRANSIENT_PATHS.join("\n")}
|
|
3662
2709
|
`,
|
|
3663
|
-
//
|
|
3664
|
-
//
|
|
3665
|
-
|
|
3666
|
-
//
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
2710
|
+
// A stable header plus rerender heals the block whenever the transient
|
|
2711
|
+
// path list grows and lets uninstall recognize older variants.
|
|
2712
|
+
rerender: true,
|
|
2713
|
+
// eslint-disable-next-line security/detect-non-literal-regexp -- derived only from the source-controlled constant above
|
|
2714
|
+
rerenderOwnedLinePattern: new RegExp(
|
|
2715
|
+
`^(?:${SAFEWORD_TRANSIENT_PATHS.map(
|
|
2716
|
+
(path) => path.replaceAll(/[.*+?^${}()|[\]\\]/gu, String.raw`\$&`)
|
|
2717
|
+
).join("|")})$`,
|
|
2718
|
+
"u"
|
|
2719
|
+
),
|
|
2720
|
+
marker: "# Safeword - Local cache and transient state"
|
|
3673
2721
|
},
|
|
3674
2722
|
// Prettier ignores: safeword owns the dot-directories in SAFEWORD_IGNORE_DIRS
|
|
3675
2723
|
// (.safeword/, .claude/, .cursor/, .codex/, .agents/, and both namespace
|
|
@@ -3692,7 +2740,13 @@ ${PRETTIER_EXCLUSIONS_HEADER}
|
|
|
3692
2740
|
${managedPrettierPaths(ctx).join("\n")}
|
|
3693
2741
|
`,
|
|
3694
2742
|
rerender: true,
|
|
3695
|
-
marker: PRETTIER_EXCLUSIONS_HEADER
|
|
2743
|
+
marker: PRETTIER_EXCLUSIONS_HEADER,
|
|
2744
|
+
replacementAfterUnpatch: (ctx) => `
|
|
2745
|
+
# Project namespace exclusions (preserved after Safeword uninstall)
|
|
2746
|
+
${durableNamespaceDirectories(
|
|
2747
|
+
ctx
|
|
2748
|
+
).map((dir) => `${dir}/`).join("\n")}
|
|
2749
|
+
`
|
|
3696
2750
|
},
|
|
3697
2751
|
".gitattributes": {
|
|
3698
2752
|
// ctx factory + rerender (issue #566), same shape as .prettierignore: a custom
|
|
@@ -3706,6 +2760,7 @@ ${managedPrettierPaths(ctx).join("\n")}
|
|
|
3706
2760
|
content: (ctx) => `${managedGitattributes(ctx)}
|
|
3707
2761
|
`,
|
|
3708
2762
|
rerender: true,
|
|
2763
|
+
rerenderOwnedLinePattern: /^(?:\*\*\/architecture\.generated\.md|.+\/tickets\/INDEX(?:-completed)?\.md) merge=union linguist-generated=true$/u,
|
|
3709
2764
|
marker: GITATTRIBUTES_HEADER
|
|
3710
2765
|
}
|
|
3711
2766
|
},
|
|
@@ -3805,7 +2860,6 @@ ${managedPrettierPaths(ctx).join("\n")}
|
|
|
3805
2860
|
packages: typescriptPackages
|
|
3806
2861
|
};
|
|
3807
2862
|
var CURSOR_PROJECT_PATHS = /* @__PURE__ */ new Set([
|
|
3808
|
-
".safeword/hooks/lib/cursor-run-identity.ts",
|
|
3809
2863
|
".safeword/hooks/lib/cursor-state.ts",
|
|
3810
2864
|
".safeword/hooks/session-cursor-auto-upgrade.ts"
|
|
3811
2865
|
]);
|
|
@@ -3834,14 +2888,6 @@ function schemaForProjectSurfaces(schema, surfaces) {
|
|
|
3834
2888
|
}
|
|
3835
2889
|
|
|
3836
2890
|
export {
|
|
3837
|
-
parse,
|
|
3838
|
-
hasRuffDependency,
|
|
3839
|
-
detectPythonPackageManager,
|
|
3840
|
-
getPythonInstallCommand,
|
|
3841
|
-
getPythonTools,
|
|
3842
|
-
getMissingPythonToolDependencies,
|
|
3843
|
-
installPythonDependencies,
|
|
3844
|
-
setupPythonTooling,
|
|
3845
2891
|
hasImportLinterScaffoldTarget,
|
|
3846
2892
|
generateOwnedPathsModule,
|
|
3847
2893
|
typescriptPackages,
|
|
@@ -3852,43 +2898,4 @@ export {
|
|
|
3852
2898
|
isCursorProjectPath,
|
|
3853
2899
|
schemaForProjectSurfaces
|
|
3854
2900
|
};
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
smol-toml/dist/date.js:
|
|
3858
|
-
smol-toml/dist/error.js:
|
|
3859
|
-
smol-toml/dist/primitive.js:
|
|
3860
|
-
smol-toml/dist/util.js:
|
|
3861
|
-
smol-toml/dist/extract.js:
|
|
3862
|
-
smol-toml/dist/struct.js:
|
|
3863
|
-
smol-toml/dist/parse.js:
|
|
3864
|
-
smol-toml/dist/stringify.js:
|
|
3865
|
-
smol-toml/dist/index.js:
|
|
3866
|
-
(*!
|
|
3867
|
-
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3868
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
3869
|
-
*
|
|
3870
|
-
* Redistribution and use in source and binary forms, with or without
|
|
3871
|
-
* modification, are permitted provided that the following conditions are met:
|
|
3872
|
-
*
|
|
3873
|
-
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
3874
|
-
* list of conditions and the following disclaimer.
|
|
3875
|
-
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
3876
|
-
* this list of conditions and the following disclaimer in the
|
|
3877
|
-
* documentation and/or other materials provided with the distribution.
|
|
3878
|
-
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
3879
|
-
* may be used to endorse or promote products derived from this software without
|
|
3880
|
-
* specific prior written permission.
|
|
3881
|
-
*
|
|
3882
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
3883
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
3884
|
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
3885
|
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
3886
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
3887
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
3888
|
-
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
3889
|
-
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
3890
|
-
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
3891
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3892
|
-
*)
|
|
3893
|
-
*/
|
|
3894
|
-
//# sourceMappingURL=chunk-BSOUMHMQ.js.map
|
|
2901
|
+
//# sourceMappingURL=chunk-IPTM5VE7.js.map
|