safeword 0.75.0 → 0.76.0
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/dist/{architecture-KKL2LBNN.js → architecture-MLLLP2QN.js} +2 -2
- package/dist/{architecture-document-3IZGQHGU.js → architecture-document-OFBN5ZAO.js} +2 -2
- package/dist/{architecture-monorepo-RKR4FT2Y.js → architecture-monorepo-MYENEFSR.js} +2 -2
- package/dist/{boundary-4ETEMTY3.js → boundary-OWTJP7DH.js} +2 -2
- package/dist/{chunk-C7HR7OK2.js → chunk-2MBSWVT2.js} +164 -90
- package/dist/chunk-2MBSWVT2.js.map +1 -0
- package/dist/{chunk-Q6TQYWG5.js → chunk-37ZTQ3NL.js} +4 -4
- package/dist/{chunk-C7ITU7HB.js → chunk-6DKB2H5U.js} +2 -2
- package/dist/{chunk-C7ITU7HB.js.map → chunk-6DKB2H5U.js.map} +1 -1
- package/dist/{chunk-2CRRUMI2.js → chunk-7ASEPZRH.js} +64 -27
- package/dist/chunk-7ASEPZRH.js.map +1 -0
- package/dist/{chunk-DGZ4ULMX.js → chunk-AMGSSOTT.js} +2 -2
- package/dist/{chunk-S7RI3VQ3.js → chunk-BPQESZJI.js} +4 -4
- package/dist/{chunk-2LZCGPTG.js → chunk-BQTC6YGN.js} +2 -2
- package/dist/chunk-CFWDNJLQ.js +200 -0
- package/dist/chunk-CFWDNJLQ.js.map +1 -0
- package/dist/{chunk-SX7PUJAL.js → chunk-MQIOSUHE.js} +6 -6
- package/dist/{chunk-RZDWJVAU.js → chunk-PFVH6RET.js} +6 -5
- package/dist/{chunk-IQQO3URI.js → chunk-U5BIKVUL.js} +5 -2
- package/dist/chunk-U5BIKVUL.js.map +1 -0
- package/dist/{chunk-YURMDDJT.js → chunk-V63TSN3C.js} +13 -4
- package/dist/chunk-V63TSN3C.js.map +1 -0
- package/dist/{chunk-57TP2GNA.js → chunk-VN2SBPDX.js} +3 -3
- package/dist/{chunk-M7E4TRRB.js → chunk-WRUXO3WA.js} +2 -2
- package/dist/{chunk-TA5H73XP.js → chunk-XD26W4MT.js} +2 -2
- package/dist/{chunk-MYZGBQGQ.js → chunk-ZRV7TOCX.js} +2 -2
- package/dist/{cleanup-PUBXGIJJ.js → cleanup-YLTC244U.js} +4 -4
- package/dist/{cleanup-command-RASRW2DA.js → cleanup-command-4WXNQCMP.js} +8 -8
- package/dist/cli.js +111 -62
- package/dist/cli.js.map +1 -1
- package/dist/{clients-2IL3MBIE.js → clients-54SNTYLV.js} +2 -2
- package/dist/{codex-bootstrap-F3U7BELN.js → codex-bootstrap-3XVVIOJ6.js} +8 -8
- package/dist/{codex-hook-2WRPYIQZ.js → codex-hook-6NBOO6BO.js} +4 -4
- package/dist/{codify-IJTPTPML.js → codify-DYMOC3I6.js} +3 -3
- package/dist/{commands-MW27XF42.js → commands-DZ3YICLQ.js} +391 -68
- package/dist/commands-DZ3YICLQ.js.map +1 -0
- package/dist/{config-TRF23XJ7.js → config-56DVFORI.js} +2 -2
- package/dist/{configured-paths-673TQWOO.js → configured-paths-FKHX74N4.js} +2 -2
- package/dist/{contract-VREO5Z5I.js → contract-ARHWUCBL.js} +2 -2
- package/dist/contract-ARHWUCBL.js.map +1 -0
- package/dist/{coordinator-CKC6MZZ7.js → coordinator-YNT636VE.js} +95 -204
- package/dist/coordinator-YNT636VE.js.map +1 -0
- package/dist/{corpus-W2XWU3V5.js → corpus-32QZRB5Z.js} +2 -2
- package/dist/{doctor-VVSMO463.js → doctor-JK7TUG5R.js} +9 -9
- package/dist/{feature-directories-BDUSAF25.js → feature-directories-5YGBVQFK.js} +2 -2
- package/dist/{finalization-DBQYEMSH.js → finalization-YZ3MACEB.js} +2 -2
- package/dist/{gh-cli-6RRODYFX.js → gh-cli-TCMPLTFK.js} +2 -2
- package/dist/{github-rest-FBK75SE2.js → github-rest-ONSGEF2E.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{learning-sync-QYZRE2F5.js → learning-sync-7E6WZGQ5.js} +2 -2
- package/dist/{legacy-global-guidance-YOLALLBG.js → legacy-global-guidance-SQJFZAKL.js} +5 -5
- package/dist/{lint-gherkin-5HZD7JNM.js → lint-gherkin-JE2I4DB7.js} +3 -3
- package/dist/{operations-3PLVK2ME.js → operations-3VCNJMVX.js} +8 -8
- package/dist/{output-ENM6VQ46.js → output-IPI7PJMA.js} +2 -2
- package/dist/packet-3XZYADS3.js +10 -0
- package/dist/presets/typescript/index.js +1 -1
- package/dist/{profile-6JFE7CN4.js → profile-SZMHCSBZ.js} +5 -5
- package/dist/{prompt-QRDN7OOW.js → prompt-LUTZ27E4.js} +2 -2
- package/dist/{remove-W7K627WA.js → remove-QRMVWCJJ.js} +7 -7
- package/dist/{retro-DSAE2JYV.js → retro-FZH6ERN2.js} +8 -8
- package/dist/{retro-draft-spool-CPVRVMDV.js → retro-draft-spool-7ZAURNYG.js} +2 -2
- package/dist/{retro-extract-ECWXSFML.js → retro-extract-OMAIIR5F.js} +2 -2
- package/dist/{review-pr-CDSF4ONC.js → review-pr-MO66DIXC.js} +2 -2
- package/dist/{review-pr-publication-IAA74JYT.js → review-pr-publication-64TR3FDG.js} +2 -2
- package/dist/{run-EXSRQCIU.js → run-DTVISMLB.js} +2 -2
- package/dist/{self-report-S2WIBZJY.js → self-report-LTYM6EWR.js} +2 -2
- package/dist/{status-6PGYYP3X.js → status-ECVVBPEH.js} +6 -6
- package/dist/{status-KNZRPSOF.js → status-MYY4XKEA.js} +9 -9
- package/dist/{sync-config-NPPOTR67.js → sync-config-3TDU5CY6.js} +2 -2
- package/dist/{sync-tracker-2D2POJU5.js → sync-tracker-7DFOGVOT.js} +2 -2
- package/dist/{test-execution-VRCJRWPU.js → test-execution-6ZJQQLYS.js} +3 -3
- package/dist/{test-plan-2UFKKWIZ.js → test-plan-R63XUAFZ.js} +3 -3
- package/dist/{ticket-new-KCEJV2IZ.js → ticket-new-M4UL4XP4.js} +3 -3
- package/dist/{ticket-sync-L3S4TGCW.js → ticket-sync-5R7VRCG5.js} +2 -2
- package/dist/{tracker-map-FSNOURGV.js → tracker-map-KFPGE4HB.js} +2 -2
- package/dist/{tracker-sync-4I7TAH5I.js → tracker-sync-KAVU4N7T.js} +2 -2
- package/dist/tracker-sync-KAVU4N7T.js.map +1 -0
- package/package.json +2 -2
- package/templates/SAFEWORD.md +2 -0
- package/templates/cucumber/cucumber.mjs +1 -1
- package/templates/hooks/lib/quality.ts +289 -57
- package/templates/hooks/session-version.ts +1 -1
- package/templates/hooks/stop-quality.ts +123 -27
- package/dist/chunk-2CRRUMI2.js.map +0 -1
- package/dist/chunk-C7HR7OK2.js.map +0 -1
- package/dist/chunk-IQQO3URI.js.map +0 -1
- package/dist/chunk-YURMDDJT.js.map +0 -1
- package/dist/commands-MW27XF42.js.map +0 -1
- package/dist/contract-VREO5Z5I.js.map +0 -1
- package/dist/coordinator-CKC6MZZ7.js.map +0 -1
- /package/dist/{architecture-KKL2LBNN.js.map → architecture-MLLLP2QN.js.map} +0 -0
- /package/dist/{architecture-document-3IZGQHGU.js.map → architecture-document-OFBN5ZAO.js.map} +0 -0
- /package/dist/{architecture-monorepo-RKR4FT2Y.js.map → architecture-monorepo-MYENEFSR.js.map} +0 -0
- /package/dist/{boundary-4ETEMTY3.js.map → boundary-OWTJP7DH.js.map} +0 -0
- /package/dist/{chunk-Q6TQYWG5.js.map → chunk-37ZTQ3NL.js.map} +0 -0
- /package/dist/{chunk-DGZ4ULMX.js.map → chunk-AMGSSOTT.js.map} +0 -0
- /package/dist/{chunk-S7RI3VQ3.js.map → chunk-BPQESZJI.js.map} +0 -0
- /package/dist/{chunk-2LZCGPTG.js.map → chunk-BQTC6YGN.js.map} +0 -0
- /package/dist/{chunk-SX7PUJAL.js.map → chunk-MQIOSUHE.js.map} +0 -0
- /package/dist/{chunk-RZDWJVAU.js.map → chunk-PFVH6RET.js.map} +0 -0
- /package/dist/{chunk-57TP2GNA.js.map → chunk-VN2SBPDX.js.map} +0 -0
- /package/dist/{chunk-M7E4TRRB.js.map → chunk-WRUXO3WA.js.map} +0 -0
- /package/dist/{chunk-TA5H73XP.js.map → chunk-XD26W4MT.js.map} +0 -0
- /package/dist/{chunk-MYZGBQGQ.js.map → chunk-ZRV7TOCX.js.map} +0 -0
- /package/dist/{cleanup-PUBXGIJJ.js.map → cleanup-YLTC244U.js.map} +0 -0
- /package/dist/{cleanup-command-RASRW2DA.js.map → cleanup-command-4WXNQCMP.js.map} +0 -0
- /package/dist/{clients-2IL3MBIE.js.map → clients-54SNTYLV.js.map} +0 -0
- /package/dist/{codex-bootstrap-F3U7BELN.js.map → codex-bootstrap-3XVVIOJ6.js.map} +0 -0
- /package/dist/{codex-hook-2WRPYIQZ.js.map → codex-hook-6NBOO6BO.js.map} +0 -0
- /package/dist/{codify-IJTPTPML.js.map → codify-DYMOC3I6.js.map} +0 -0
- /package/dist/{config-TRF23XJ7.js.map → config-56DVFORI.js.map} +0 -0
- /package/dist/{configured-paths-673TQWOO.js.map → configured-paths-FKHX74N4.js.map} +0 -0
- /package/dist/{corpus-W2XWU3V5.js.map → corpus-32QZRB5Z.js.map} +0 -0
- /package/dist/{doctor-VVSMO463.js.map → doctor-JK7TUG5R.js.map} +0 -0
- /package/dist/{feature-directories-BDUSAF25.js.map → feature-directories-5YGBVQFK.js.map} +0 -0
- /package/dist/{finalization-DBQYEMSH.js.map → finalization-YZ3MACEB.js.map} +0 -0
- /package/dist/{gh-cli-6RRODYFX.js.map → gh-cli-TCMPLTFK.js.map} +0 -0
- /package/dist/{github-rest-FBK75SE2.js.map → github-rest-ONSGEF2E.js.map} +0 -0
- /package/dist/{learning-sync-QYZRE2F5.js.map → learning-sync-7E6WZGQ5.js.map} +0 -0
- /package/dist/{legacy-global-guidance-YOLALLBG.js.map → legacy-global-guidance-SQJFZAKL.js.map} +0 -0
- /package/dist/{lint-gherkin-5HZD7JNM.js.map → lint-gherkin-JE2I4DB7.js.map} +0 -0
- /package/dist/{operations-3PLVK2ME.js.map → operations-3VCNJMVX.js.map} +0 -0
- /package/dist/{output-ENM6VQ46.js.map → output-IPI7PJMA.js.map} +0 -0
- /package/dist/{profile-6JFE7CN4.js.map → packet-3XZYADS3.js.map} +0 -0
- /package/dist/{prompt-QRDN7OOW.js.map → profile-SZMHCSBZ.js.map} +0 -0
- /package/dist/{remove-W7K627WA.js.map → prompt-LUTZ27E4.js.map} +0 -0
- /package/dist/{retro-draft-spool-CPVRVMDV.js.map → remove-QRMVWCJJ.js.map} +0 -0
- /package/dist/{retro-DSAE2JYV.js.map → retro-FZH6ERN2.js.map} +0 -0
- /package/dist/{retro-extract-ECWXSFML.js.map → retro-draft-spool-7ZAURNYG.js.map} +0 -0
- /package/dist/{self-report-S2WIBZJY.js.map → retro-extract-OMAIIR5F.js.map} +0 -0
- /package/dist/{review-pr-CDSF4ONC.js.map → review-pr-MO66DIXC.js.map} +0 -0
- /package/dist/{review-pr-publication-IAA74JYT.js.map → review-pr-publication-64TR3FDG.js.map} +0 -0
- /package/dist/{run-EXSRQCIU.js.map → run-DTVISMLB.js.map} +0 -0
- /package/dist/{status-6PGYYP3X.js.map → self-report-LTYM6EWR.js.map} +0 -0
- /package/dist/{status-KNZRPSOF.js.map → status-ECVVBPEH.js.map} +0 -0
- /package/dist/{sync-config-NPPOTR67.js.map → status-MYY4XKEA.js.map} +0 -0
- /package/dist/{ticket-sync-L3S4TGCW.js.map → sync-config-3TDU5CY6.js.map} +0 -0
- /package/dist/{sync-tracker-2D2POJU5.js.map → sync-tracker-7DFOGVOT.js.map} +0 -0
- /package/dist/{test-execution-VRCJRWPU.js.map → test-execution-6ZJQQLYS.js.map} +0 -0
- /package/dist/{test-plan-2UFKKWIZ.js.map → test-plan-R63XUAFZ.js.map} +0 -0
- /package/dist/{ticket-new-KCEJV2IZ.js.map → ticket-new-M4UL4XP4.js.map} +0 -0
- /package/dist/{tracker-map-FSNOURGV.js.map → ticket-sync-5R7VRCG5.js.map} +0 -0
- /package/dist/{tracker-sync-4I7TAH5I.js.map → tracker-map-KFPGE4HB.js.map} +0 -0
package/codex-plugin/hooks.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"hooks": [
|
|
7
7
|
{
|
|
8
8
|
"type": "command",
|
|
9
|
-
"command": "bunx --bun safeword@0.
|
|
9
|
+
"command": "bunx --bun safeword@0.76.0 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.
|
|
22
|
+
"command": "bunx --bun safeword@0.76.0 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.
|
|
35
|
+
"command": "bunx --bun safeword@0.76.0 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.
|
|
48
|
+
"command": "bunx --bun safeword@0.76.0 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.
|
|
61
|
+
"command": "bunx --bun safeword@0.76.0 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-7G6OSNIV.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-6DKB2H5U.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-
|
|
653
|
+
//# sourceMappingURL=architecture-MLLLP2QN.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import "./chunk-YP2V3YUV.js";
|
|
12
12
|
import "./chunk-2MI7M2CO.js";
|
|
13
13
|
import "./chunk-7G6OSNIV.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-6DKB2H5U.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-
|
|
25
|
+
//# sourceMappingURL=architecture-document-OFBN5ZAO.js.map
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
monorepoFingerprintOf
|
|
6
6
|
} from "./chunk-YP2V3YUV.js";
|
|
7
7
|
import "./chunk-7G6OSNIV.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-6DKB2H5U.js";
|
|
9
9
|
export {
|
|
10
10
|
discoverUnreadableWorkspaces,
|
|
11
11
|
discoverWorkspaces,
|
|
12
12
|
extractMonorepoArchitectureSnapshot,
|
|
13
13
|
monorepoFingerprintOf
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=architecture-monorepo-
|
|
15
|
+
//# sourceMappingURL=architecture-monorepo-MYENEFSR.js.map
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
readFileSafe
|
|
27
27
|
} from "./chunk-7G6OSNIV.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-6DKB2H5U.js";
|
|
29
29
|
|
|
30
30
|
// src/commands/boundary.ts
|
|
31
31
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
@@ -628,4 +628,4 @@ function boundary(options) {
|
|
|
628
628
|
export {
|
|
629
629
|
boundary
|
|
630
630
|
};
|
|
631
|
-
//# sourceMappingURL=boundary-
|
|
631
|
+
//# sourceMappingURL=boundary-OWTJP7DH.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-URVJZ4NL.js";
|
|
5
5
|
import {
|
|
6
6
|
setupPythonTooling
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-U5BIKVUL.js";
|
|
8
8
|
import {
|
|
9
9
|
SAFEWORD_PRIMARY_LINT_SCRIPT,
|
|
10
10
|
detect
|
|
@@ -876,69 +876,17 @@ function shouldRemoveTextPatchTarget(content, definition) {
|
|
|
876
876
|
return definition.removeFileIfContentEquals?.some((candidate) => trimmed === candidate.trim()) ?? false;
|
|
877
877
|
}
|
|
878
878
|
|
|
879
|
-
// src/packs/config.ts
|
|
880
|
-
import nodePath2 from "path";
|
|
881
|
-
import process from "process";
|
|
882
|
-
var CONFIG_PATH = ".safeword/config.json";
|
|
883
|
-
function readConfig(cwd) {
|
|
884
|
-
const configPath = nodePath2.join(cwd, CONFIG_PATH);
|
|
885
|
-
const content = readFileSafe(configPath);
|
|
886
|
-
if (!content) return void 0;
|
|
887
|
-
return JSON.parse(content);
|
|
888
|
-
}
|
|
889
|
-
function writeConfig(cwd, config) {
|
|
890
|
-
const configPath = nodePath2.join(cwd, CONFIG_PATH);
|
|
891
|
-
writeFile(configPath, JSON.stringify(config, void 0, 2));
|
|
892
|
-
}
|
|
893
|
-
function getInstalledPacks(cwd) {
|
|
894
|
-
const config = readConfig(cwd);
|
|
895
|
-
return config?.installedPacks ?? [];
|
|
896
|
-
}
|
|
897
|
-
function isPackInstalled(cwd, packId) {
|
|
898
|
-
return getInstalledPacks(cwd).includes(packId);
|
|
899
|
-
}
|
|
900
|
-
function addInstalledPack(cwd, packId) {
|
|
901
|
-
const config = readConfig(cwd) ?? { installedPacks: [] };
|
|
902
|
-
if (!config.installedPacks.includes(packId)) {
|
|
903
|
-
config.installedPacks.push(packId);
|
|
904
|
-
writeConfig(cwd, config);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
// src/packs/golang/setup.ts
|
|
909
|
-
function setupGoTooling() {
|
|
910
|
-
return { files: [] };
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
// src/packs/golang/index.ts
|
|
914
|
-
var golangPack = {
|
|
915
|
-
id: "golang",
|
|
916
|
-
name: "Go",
|
|
917
|
-
extensions: [".go"],
|
|
918
|
-
detect(cwd) {
|
|
919
|
-
return existsInTree(cwd, "go.mod");
|
|
920
|
-
},
|
|
921
|
-
setup(_cwd, _ctx) {
|
|
922
|
-
return setupGoTooling();
|
|
923
|
-
}
|
|
924
|
-
};
|
|
925
|
-
|
|
926
|
-
// src/packs/python/index.ts
|
|
927
|
-
var pythonPack = {
|
|
928
|
-
id: "python",
|
|
929
|
-
name: "Python",
|
|
930
|
-
extensions: [".py", ".pyi"],
|
|
931
|
-
detect(cwd) {
|
|
932
|
-
return existsInTree(cwd, "pyproject.toml") || existsInTree(cwd, "requirements.txt");
|
|
933
|
-
},
|
|
934
|
-
setup(_cwd, _ctx) {
|
|
935
|
-
return setupPythonTooling();
|
|
936
|
-
}
|
|
937
|
-
};
|
|
938
|
-
|
|
939
879
|
// src/packs/rust/setup.ts
|
|
940
|
-
import {
|
|
941
|
-
|
|
880
|
+
import {
|
|
881
|
+
existsSync,
|
|
882
|
+
lstatSync as lstatSync2,
|
|
883
|
+
readdirSync,
|
|
884
|
+
readFileSync,
|
|
885
|
+
realpathSync,
|
|
886
|
+
writeFileSync
|
|
887
|
+
} from "fs";
|
|
888
|
+
import nodePath2 from "path";
|
|
889
|
+
import { parse } from "smol-toml";
|
|
942
890
|
var SAFEWORD_CLIPPY_LINTS = `[lints.clippy]
|
|
943
891
|
# Enable pedantic for stricter linting (priority -1 allows individual overrides)
|
|
944
892
|
pedantic = { level = "deny", priority = -1 }
|
|
@@ -957,6 +905,25 @@ module_name_repetitions = "allow"
|
|
|
957
905
|
# Deny unsafe code by default (LLMs shouldn't write unsafe)
|
|
958
906
|
unsafe_code = "deny"
|
|
959
907
|
`;
|
|
908
|
+
function isContainedPath(root, candidate) {
|
|
909
|
+
const relative = nodePath2.relative(root, candidate);
|
|
910
|
+
return relative === "" || !relative.startsWith(`..${nodePath2.sep}`) && !nodePath2.isAbsolute(relative);
|
|
911
|
+
}
|
|
912
|
+
function containedWorkspaceMember(cwd, member) {
|
|
913
|
+
if (nodePath2.isAbsolute(member)) return void 0;
|
|
914
|
+
const root = nodePath2.resolve(cwd);
|
|
915
|
+
const candidate = nodePath2.resolve(root, member);
|
|
916
|
+
if (!isContainedPath(root, candidate)) return void 0;
|
|
917
|
+
if (existsSync(candidate) && !isContainedPath(realpathSync(root), realpathSync(candidate))) {
|
|
918
|
+
return void 0;
|
|
919
|
+
}
|
|
920
|
+
return nodePath2.relative(root, candidate);
|
|
921
|
+
}
|
|
922
|
+
function isSafeCargoManifest(cwd, cargoPath) {
|
|
923
|
+
if (!existsSync(cargoPath)) return false;
|
|
924
|
+
const stat = lstatSync2(cargoPath);
|
|
925
|
+
return stat.isFile() && !stat.isSymbolicLink() && isContainedPath(realpathSync(cwd), realpathSync(cargoPath));
|
|
926
|
+
}
|
|
960
927
|
var SAFEWORD_WORKSPACE_LINTS = `[workspace.lints.clippy]
|
|
961
928
|
# Enable pedantic for stricter linting (priority -1 allows individual overrides)
|
|
962
929
|
pedantic = { level = "deny", priority = -1 }
|
|
@@ -976,53 +943,97 @@ module_name_repetitions = "allow"
|
|
|
976
943
|
unsafe_code = "deny"
|
|
977
944
|
`;
|
|
978
945
|
function detectWorkspaceType(cargoContent) {
|
|
979
|
-
const hasWorkspace = cargoContent
|
|
980
|
-
const hasPackage = cargoContent
|
|
946
|
+
const hasWorkspace = hasExactTableHeader(cargoContent, "workspace");
|
|
947
|
+
const hasPackage = hasExactTableHeader(cargoContent, "package");
|
|
981
948
|
if (hasWorkspace && !hasPackage) return "virtual";
|
|
982
949
|
if (hasWorkspace && hasPackage) return "root-package";
|
|
983
950
|
return "single-crate";
|
|
984
951
|
}
|
|
952
|
+
function hasExactTableHeader(content, table) {
|
|
953
|
+
let multilineDelimiter;
|
|
954
|
+
const header = `[${table}]`;
|
|
955
|
+
for (const line of content.split(/\r?\n/u)) {
|
|
956
|
+
if (multilineDelimiter !== void 0) {
|
|
957
|
+
if (hasOddOccurrences(line, multilineDelimiter)) multilineDelimiter = void 0;
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
const trimmed = line.trim();
|
|
961
|
+
if (trimmed === header || trimmed.startsWith(`${header} #`)) return true;
|
|
962
|
+
multilineDelimiter = openingMultilineDelimiter(line);
|
|
963
|
+
}
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
function hasOddOccurrences(line, delimiter) {
|
|
967
|
+
return line.split(delimiter).length % 2 === 0;
|
|
968
|
+
}
|
|
969
|
+
function openingMultilineDelimiter(line) {
|
|
970
|
+
const candidates = ['"""', "'''"];
|
|
971
|
+
return candidates.filter((delimiter) => hasOddOccurrences(line, delimiter)).toSorted((left, right) => line.indexOf(left) - line.indexOf(right))[0];
|
|
972
|
+
}
|
|
985
973
|
function hasExistingLints(cargoContent) {
|
|
986
|
-
|
|
974
|
+
const manifest = parseCargoManifest(cargoContent);
|
|
975
|
+
const workspace = isTomlTable(manifest?.workspace) ? manifest.workspace : void 0;
|
|
976
|
+
return isTomlTable(manifest?.lints) || isTomlTable(workspace?.lints);
|
|
977
|
+
}
|
|
978
|
+
function isTomlTable(value) {
|
|
979
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
980
|
+
}
|
|
981
|
+
function parseCargoManifest(content) {
|
|
982
|
+
try {
|
|
983
|
+
const manifest = parse(content);
|
|
984
|
+
return isTomlTable(manifest) ? manifest : void 0;
|
|
985
|
+
} catch {
|
|
986
|
+
return void 0;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
function rustToolingTargets(cwd) {
|
|
990
|
+
const rootTarget = "Cargo.toml";
|
|
991
|
+
const cargoPath = nodePath2.join(cwd, rootTarget);
|
|
992
|
+
if (!isSafeCargoManifest(cwd, cargoPath)) return [];
|
|
993
|
+
const content = readFileSync(cargoPath, "utf8");
|
|
994
|
+
const targets = hasExistingLints(content) ? [] : [rootTarget];
|
|
995
|
+
if (detectWorkspaceType(content) === "single-crate") return targets;
|
|
996
|
+
for (const member of parseWorkspaceMembers(content, cwd)) {
|
|
997
|
+
const target = nodePath2.join(member, "Cargo.toml");
|
|
998
|
+
const memberPath = nodePath2.join(cwd, target);
|
|
999
|
+
if (!isSafeCargoManifest(cwd, memberPath)) continue;
|
|
1000
|
+
if (!hasExistingLints(readFileSync(memberPath, "utf8"))) targets.push(target);
|
|
1001
|
+
}
|
|
1002
|
+
return targets;
|
|
987
1003
|
}
|
|
988
1004
|
function expandMemberPattern(cwd, pattern) {
|
|
989
1005
|
if (pattern.endsWith("/*")) {
|
|
990
|
-
const baseDirectory = pattern.slice(0, -2);
|
|
991
|
-
|
|
1006
|
+
const baseDirectory = containedWorkspaceMember(cwd, pattern.slice(0, -2));
|
|
1007
|
+
if (baseDirectory === void 0) return [];
|
|
1008
|
+
const fullPath = nodePath2.join(cwd, baseDirectory);
|
|
992
1009
|
if (!existsSync(fullPath)) return [];
|
|
993
1010
|
try {
|
|
994
1011
|
const entries = readdirSync(fullPath, { withFileTypes: true });
|
|
995
1012
|
return entries.filter((entry) => {
|
|
996
1013
|
if (!entry.isDirectory()) return false;
|
|
997
|
-
const cargoPath =
|
|
1014
|
+
const cargoPath = nodePath2.join(fullPath, entry.name, "Cargo.toml");
|
|
998
1015
|
return existsSync(cargoPath);
|
|
999
|
-
}).map((entry) =>
|
|
1016
|
+
}).map((entry) => nodePath2.join(baseDirectory, entry.name));
|
|
1000
1017
|
} catch {
|
|
1001
1018
|
return [];
|
|
1002
1019
|
}
|
|
1003
1020
|
}
|
|
1004
|
-
|
|
1021
|
+
const member = containedWorkspaceMember(cwd, pattern);
|
|
1022
|
+
return member === void 0 ? [] : [member];
|
|
1005
1023
|
}
|
|
1006
1024
|
function parseWorkspaceMembers(cargoContent, cwd) {
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
const rawMembers =
|
|
1011
|
-
const stringRegex = /"([^"]+)"/g;
|
|
1012
|
-
let match;
|
|
1013
|
-
while ((match = stringRegex.exec(membersBlock)) !== null) {
|
|
1014
|
-
if (match[1]) {
|
|
1015
|
-
rawMembers.push(match[1]);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1025
|
+
const manifest = parseCargoManifest(cargoContent);
|
|
1026
|
+
const members = isTomlTable(manifest?.workspace) ? manifest.workspace.members : void 0;
|
|
1027
|
+
if (!Array.isArray(members)) return [];
|
|
1028
|
+
const rawMembers = members.filter((member) => typeof member === "string");
|
|
1018
1029
|
const expandedMembers = [];
|
|
1019
1030
|
for (const member of rawMembers) {
|
|
1020
1031
|
expandedMembers.push(...expandMemberPattern(cwd, member));
|
|
1021
1032
|
}
|
|
1022
1033
|
return expandedMembers;
|
|
1023
1034
|
}
|
|
1024
|
-
function addWorkspaceLints(memberCargoPath) {
|
|
1025
|
-
if (!
|
|
1035
|
+
function addWorkspaceLints(cwd, memberCargoPath) {
|
|
1036
|
+
if (!isSafeCargoManifest(cwd, memberCargoPath)) return;
|
|
1026
1037
|
const content = readFileSync(memberCargoPath, "utf8");
|
|
1027
1038
|
if (hasExistingLints(content)) return;
|
|
1028
1039
|
const lintsSection = `[lints]
|
|
@@ -1044,13 +1055,13 @@ ${lintsToAdd}`;
|
|
|
1044
1055
|
function addMemberLints(cwd, content) {
|
|
1045
1056
|
const members = parseWorkspaceMembers(content, cwd);
|
|
1046
1057
|
for (const member of members) {
|
|
1047
|
-
const memberCargoPath =
|
|
1048
|
-
addWorkspaceLints(memberCargoPath);
|
|
1058
|
+
const memberCargoPath = nodePath2.join(cwd, member, "Cargo.toml");
|
|
1059
|
+
addWorkspaceLints(cwd, memberCargoPath);
|
|
1049
1060
|
}
|
|
1050
1061
|
}
|
|
1051
1062
|
function setupRustTooling(cwd) {
|
|
1052
|
-
const cargoPath =
|
|
1053
|
-
if (!
|
|
1063
|
+
const cargoPath = nodePath2.join(cwd, "Cargo.toml");
|
|
1064
|
+
if (!isSafeCargoManifest(cwd, cargoPath)) return { files: [] };
|
|
1054
1065
|
const content = readFileSync(cargoPath, "utf8");
|
|
1055
1066
|
const workspaceType = detectWorkspaceType(content);
|
|
1056
1067
|
const isWorkspace = workspaceType !== "single-crate";
|
|
@@ -1061,6 +1072,66 @@ function setupRustTooling(cwd) {
|
|
|
1061
1072
|
return { files: [] };
|
|
1062
1073
|
}
|
|
1063
1074
|
|
|
1075
|
+
// src/packs/config.ts
|
|
1076
|
+
import nodePath3 from "path";
|
|
1077
|
+
import process from "process";
|
|
1078
|
+
var CONFIG_PATH = ".safeword/config.json";
|
|
1079
|
+
function readConfig(cwd) {
|
|
1080
|
+
const configPath = nodePath3.join(cwd, CONFIG_PATH);
|
|
1081
|
+
const content = readFileSafe(configPath);
|
|
1082
|
+
if (!content) return void 0;
|
|
1083
|
+
return JSON.parse(content);
|
|
1084
|
+
}
|
|
1085
|
+
function writeConfig(cwd, config) {
|
|
1086
|
+
const configPath = nodePath3.join(cwd, CONFIG_PATH);
|
|
1087
|
+
writeFile(configPath, JSON.stringify(config, void 0, 2));
|
|
1088
|
+
}
|
|
1089
|
+
function getInstalledPacks(cwd) {
|
|
1090
|
+
const config = readConfig(cwd);
|
|
1091
|
+
return config?.installedPacks ?? [];
|
|
1092
|
+
}
|
|
1093
|
+
function isPackInstalled(cwd, packId) {
|
|
1094
|
+
return getInstalledPacks(cwd).includes(packId);
|
|
1095
|
+
}
|
|
1096
|
+
function addInstalledPack(cwd, packId) {
|
|
1097
|
+
const config = readConfig(cwd) ?? { installedPacks: [] };
|
|
1098
|
+
if (!config.installedPacks.includes(packId)) {
|
|
1099
|
+
config.installedPacks.push(packId);
|
|
1100
|
+
writeConfig(cwd, config);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// src/packs/golang/setup.ts
|
|
1105
|
+
function setupGoTooling() {
|
|
1106
|
+
return { files: [] };
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// src/packs/golang/index.ts
|
|
1110
|
+
var golangPack = {
|
|
1111
|
+
id: "golang",
|
|
1112
|
+
name: "Go",
|
|
1113
|
+
extensions: [".go"],
|
|
1114
|
+
detect(cwd) {
|
|
1115
|
+
return existsInTree(cwd, "go.mod");
|
|
1116
|
+
},
|
|
1117
|
+
setup(_cwd, _ctx) {
|
|
1118
|
+
return setupGoTooling();
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
// src/packs/python/index.ts
|
|
1123
|
+
var pythonPack = {
|
|
1124
|
+
id: "python",
|
|
1125
|
+
name: "Python",
|
|
1126
|
+
extensions: [".py", ".pyi"],
|
|
1127
|
+
detect(cwd) {
|
|
1128
|
+
return existsInTree(cwd, "pyproject.toml") || existsInTree(cwd, "requirements.txt");
|
|
1129
|
+
},
|
|
1130
|
+
setup(_cwd, _ctx) {
|
|
1131
|
+
return setupPythonTooling();
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1064
1135
|
// src/packs/rust/index.ts
|
|
1065
1136
|
var rustPack = {
|
|
1066
1137
|
id: "rust",
|
|
@@ -1249,7 +1320,9 @@ var CUCUMBER_TEMPLATE_REVISION_HASHES = /* @__PURE__ */ new Set([
|
|
|
1249
1320
|
// 56JCFZ — runtime paths.features/paths.steps config read (current)
|
|
1250
1321
|
"929014fb4ce6ca1483b292757b6044be89932028f5bb21ba82c28ffd66b09e53",
|
|
1251
1322
|
// 4DK9H4 — live profile excludes @manual while selecting @live scenarios
|
|
1252
|
-
"1295e832b1b3bdd0faa963e218bd489c9c252a981fc8e315d4814d4208384a5f"
|
|
1323
|
+
"1295e832b1b3bdd0faa963e218bd489c9c252a981fc8e315d4814d4208384a5f",
|
|
1324
|
+
// ECGEP9 — automated lane distinguishes Vitest-backed proof from unfinished work
|
|
1325
|
+
"0ec4cb6d65b39e01f8aff27c4ca3841e0271a43b5435492676450f0fb3cfac27"
|
|
1253
1326
|
]);
|
|
1254
1327
|
function isShippedCucumberTemplateRevision(content) {
|
|
1255
1328
|
const hash = createHash("sha256").update(content).digest("hex");
|
|
@@ -1563,6 +1636,7 @@ function createProjectContext(cwd) {
|
|
|
1563
1636
|
export {
|
|
1564
1637
|
isPackInstalled,
|
|
1565
1638
|
addInstalledPack,
|
|
1639
|
+
rustToolingTargets,
|
|
1566
1640
|
LANGUAGE_PACKS,
|
|
1567
1641
|
getMissingPacks,
|
|
1568
1642
|
reconcile,
|
|
@@ -1572,4 +1646,4 @@ export {
|
|
|
1572
1646
|
LEFTHOOK_CONFIGS,
|
|
1573
1647
|
createProjectContext
|
|
1574
1648
|
};
|
|
1575
|
-
//# sourceMappingURL=chunk-
|
|
1649
|
+
//# sourceMappingURL=chunk-2MBSWVT2.js.map
|