token-goat 2.9.30 → 2.9.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -7
- package/SECURITY.md +10 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/native/win32-arm64/tg-hook.exe +0 -0
- package/dist/native/win32-x64/tg-hook.exe +0 -0
- package/dist/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
- package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
- package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
- package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
- package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
- package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
- package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
- package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
- package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
- package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
- package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
- package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
- package/dist/token-goat-chunk-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
- package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
- package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
- package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
- package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
- package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
- package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
- package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
- package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
- package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
- package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
- package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
- package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
- package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
- package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
- package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
- package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
- package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
- package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
- package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
- package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
- package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
- package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
- package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
- package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
- package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
- package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
- package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
- package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
- package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
- package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
- package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
- package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
- package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
- package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
- package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
- package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
- package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
- package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
- package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
- package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
- package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
- package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
- package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
- package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
- package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
- package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
- package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
- package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
- package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
- package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
- package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
- package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +1 -1
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +67 -38
- package/dist/token-goat.core.mjs +4 -4
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +40 -21
- package/docs/install.md +19 -9
- package/docs/security.md +5 -3
- package/package.json +2 -1
- package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
- package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
- package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
- package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
- package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
- package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
- package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
- package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
- package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
- package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
- package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
- package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
- package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
|
@@ -2,6 +2,8 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
GROK_HOOK_SCRIPT,
|
|
5
|
+
VSCODE_CLAUDE_HOOKS_TURNED_OFF_TEXT,
|
|
6
|
+
disableVscodeClaudeHooks,
|
|
5
7
|
grokConfigPath,
|
|
6
8
|
grokHookScriptPath,
|
|
7
9
|
installAntigravity,
|
|
@@ -22,9 +24,11 @@ import {
|
|
|
22
24
|
isQwenInstalled,
|
|
23
25
|
kimiConfigPath,
|
|
24
26
|
kimiHookScriptPath,
|
|
27
|
+
vscodeHooksInstalled,
|
|
28
|
+
vscodeRunsTokenGoatClaudeHooks,
|
|
25
29
|
wiredGrokHookWords,
|
|
26
30
|
wiredKimiHookWords
|
|
27
|
-
} from "./token-goat-chunk-
|
|
31
|
+
} from "./token-goat-chunk-AUQYRMMH.mjs";
|
|
28
32
|
import {
|
|
29
33
|
CLAUDECODE_HOOK_SCRIPT,
|
|
30
34
|
CODEX_HOOK_SCRIPT,
|
|
@@ -33,42 +37,47 @@ import {
|
|
|
33
37
|
codexConfigPath,
|
|
34
38
|
codexHookScriptPath,
|
|
35
39
|
copilotCliConfigPath,
|
|
36
|
-
copilotCliHooksDir,
|
|
37
|
-
copilotCliInstructionsPath,
|
|
38
40
|
copilotCliScriptPath,
|
|
39
41
|
hookEventGaps,
|
|
40
42
|
installCodex,
|
|
41
|
-
installCopilotHooksFile,
|
|
42
43
|
installHooks,
|
|
43
44
|
isCodexInstalled,
|
|
44
45
|
isCopilotCliInstalled,
|
|
45
46
|
isInstalled,
|
|
47
|
+
parseNativeInvocation,
|
|
48
|
+
repairCopilotCliHooks,
|
|
46
49
|
wiredCodexHookWords,
|
|
47
|
-
wiredCopilotHookWords
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
import "./token-goat-chunk-
|
|
51
|
-
import "./token-goat-chunk-XKI4SEMX.mjs";
|
|
50
|
+
wiredCopilotHookWords
|
|
51
|
+
} from "./token-goat-chunk-7MAOA6X4.mjs";
|
|
52
|
+
import "./token-goat-chunk-CXHOFN7R.mjs";
|
|
53
|
+
import "./token-goat-chunk-QQTWJY2O.mjs";
|
|
52
54
|
import "./token-goat-chunk-G5PJ7AGM.mjs";
|
|
53
|
-
import "./token-goat-chunk-P4QMM4WK.mjs";
|
|
54
|
-
import "./token-goat-chunk-VPBBTSJR.mjs";
|
|
55
55
|
import "./token-goat-chunk-BPGCUMR7.mjs";
|
|
56
|
-
import "./token-goat-chunk-
|
|
57
|
-
import "./token-goat-chunk-
|
|
58
|
-
import "./token-goat-chunk-
|
|
56
|
+
import "./token-goat-chunk-C75NA7PL.mjs";
|
|
57
|
+
import "./token-goat-chunk-CBIQ7WTD.mjs";
|
|
58
|
+
import "./token-goat-chunk-76FGDLRO.mjs";
|
|
59
|
+
import "./token-goat-chunk-U4WHMG6Y.mjs";
|
|
60
|
+
import "./token-goat-chunk-GVB2MUST.mjs";
|
|
59
61
|
import "./token-goat-chunk-XB5KKOCG.mjs";
|
|
60
|
-
import "./token-goat-chunk-
|
|
61
|
-
import "./token-goat-chunk-
|
|
62
|
-
import "./token-goat-chunk-
|
|
62
|
+
import "./token-goat-chunk-OUKDTVNU.mjs";
|
|
63
|
+
import "./token-goat-chunk-BFCWY73P.mjs";
|
|
64
|
+
import "./token-goat-chunk-KGEFFSHD.mjs";
|
|
65
|
+
import "./token-goat-chunk-XX6O25RN.mjs";
|
|
66
|
+
import "./token-goat-chunk-HAVAOB3S.mjs";
|
|
67
|
+
import "./token-goat-chunk-T5P5ACNQ.mjs";
|
|
68
|
+
import "./token-goat-chunk-7EZTZOMC.mjs";
|
|
69
|
+
import "./token-goat-chunk-QYHO5CPH.mjs";
|
|
70
|
+
import "./token-goat-chunk-4GBVPH3D.mjs";
|
|
63
71
|
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
64
72
|
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
65
73
|
import {
|
|
66
|
-
extractErrorMessage
|
|
67
|
-
|
|
74
|
+
extractErrorMessage,
|
|
75
|
+
hasCreatedConfig
|
|
76
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
77
|
+
import "./token-goat-chunk-GGGG7RWB.mjs";
|
|
68
78
|
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
69
79
|
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
70
|
-
import "./token-goat-chunk-
|
|
71
|
-
import "./token-goat-chunk-HAVAOB3S.mjs";
|
|
80
|
+
import "./token-goat-chunk-CO3UYX6G.mjs";
|
|
72
81
|
import {
|
|
73
82
|
init_define_import_meta_env
|
|
74
83
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -84,6 +93,14 @@ function shimIsCurrent(scriptPath, expected) {
|
|
|
84
93
|
return false;
|
|
85
94
|
}
|
|
86
95
|
}
|
|
96
|
+
var SHIM_FILE_WORD = /(?:^|[\\/])token-goat-shim\.c?js$/;
|
|
97
|
+
function wiringPointsAtMissingFile(entries) {
|
|
98
|
+
return entries.some(({ words }) => {
|
|
99
|
+
const native = parseNativeInvocation(words);
|
|
100
|
+
if (native !== void 0 && !fs.existsSync(native.bin)) return true;
|
|
101
|
+
return words.some((word) => SHIM_FILE_WORD.test(word) && !fs.existsSync(word));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
87
104
|
function hasHookEventGaps(gaps) {
|
|
88
105
|
return gaps !== null && (gaps.missing.length > 0 || gaps.outdated.length > 0 || gaps.broken.length > 0);
|
|
89
106
|
}
|
|
@@ -93,10 +110,11 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
93
110
|
const projectRoot = path.resolve(rootDir ?? process.cwd());
|
|
94
111
|
try {
|
|
95
112
|
const userShim = claudeHookScriptPath();
|
|
96
|
-
const
|
|
113
|
+
const userGaps = hookEventGaps("user");
|
|
114
|
+
const userInstalled = isInstalled("user") || fs.existsSync(userShim) || userGaps !== null;
|
|
97
115
|
if (userInstalled) {
|
|
98
116
|
const isStaleShim = fs.existsSync(userShim) && !shimIsCurrent(userShim, CLAUDECODE_HOOK_SCRIPT);
|
|
99
|
-
if (isStaleShim || hasHookEventGaps(
|
|
117
|
+
if (isStaleShim || hasHookEventGaps(userGaps)) {
|
|
100
118
|
installHooks("user");
|
|
101
119
|
repairs.push("Repaired Claude Code (user) hooks and shim");
|
|
102
120
|
}
|
|
@@ -106,10 +124,11 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
106
124
|
}
|
|
107
125
|
try {
|
|
108
126
|
const projShim = claudeHookScriptPath();
|
|
109
|
-
const
|
|
127
|
+
const projGaps = hookEventGaps("project");
|
|
128
|
+
const projInstalled = isInstalled("project") || projGaps !== null;
|
|
110
129
|
if (projInstalled) {
|
|
111
130
|
const isStaleShim = fs.existsSync(projShim) && !shimIsCurrent(projShim, CLAUDECODE_HOOK_SCRIPT);
|
|
112
|
-
if (isStaleShim || hasHookEventGaps(
|
|
131
|
+
if (isStaleShim || hasHookEventGaps(projGaps)) {
|
|
113
132
|
installHooks("project");
|
|
114
133
|
repairs.push("Repaired Claude Code (project) hooks and shim");
|
|
115
134
|
}
|
|
@@ -123,10 +142,10 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
123
142
|
const userInstalled = isCopilotCliInstalled() || fs.existsSync(userConfig) || fs.existsSync(userShim);
|
|
124
143
|
if (userInstalled) {
|
|
125
144
|
const isStaleShim = fs.existsSync(userShim) && !shimIsCurrent(userShim, COPILOT_CLI_HOOK_SCRIPT);
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
145
|
+
const wired = wiredCopilotHookWords();
|
|
146
|
+
const hasOutdatedEntries = wired.some((e) => e.current === false);
|
|
147
|
+
if (isStaleShim || hasOutdatedEntries || wiringPointsAtMissingFile(wired)) {
|
|
148
|
+
repairCopilotCliHooks();
|
|
130
149
|
repairs.push("Repaired Copilot CLI (user) hooks and shim");
|
|
131
150
|
}
|
|
132
151
|
}
|
|
@@ -140,10 +159,11 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
140
159
|
const projInstalled = isCopilotCliInstalled(copilotLocalOpts) || fs.existsSync(projConfig) || fs.existsSync(projShim);
|
|
141
160
|
if (projInstalled) {
|
|
142
161
|
const isStaleShim = fs.existsSync(projShim) && !shimIsCurrent(projShim, COPILOT_CLI_HOOK_SCRIPT);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
162
|
+
const wired = wiredCopilotHookWords(copilotLocalOpts);
|
|
163
|
+
const hasOutdatedEntries = wired.some((e) => e.current === false);
|
|
164
|
+
const pointsAtMissing = hasCreatedConfig(projConfig) && wiringPointsAtMissingFile(wired);
|
|
165
|
+
if (isStaleShim || hasOutdatedEntries || pointsAtMissing) {
|
|
166
|
+
repairCopilotCliHooks(copilotLocalOpts);
|
|
147
167
|
repairs.push("Repaired Copilot CLI (project) hooks and shim");
|
|
148
168
|
}
|
|
149
169
|
}
|
|
@@ -156,8 +176,9 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
156
176
|
const codexInstalled = isCodexInstalled() || fs.existsSync(codexCfg) || fs.existsSync(codexShim);
|
|
157
177
|
if (codexInstalled) {
|
|
158
178
|
const isStaleShim = fs.existsSync(codexShim) && !shimIsCurrent(codexShim, CODEX_HOOK_SCRIPT);
|
|
159
|
-
const
|
|
160
|
-
|
|
179
|
+
const wired = wiredCodexHookWords();
|
|
180
|
+
const hasOutdatedEntries = wired.some((e) => e.current === false);
|
|
181
|
+
if (isStaleShim || hasOutdatedEntries || wiringPointsAtMissingFile(wired)) {
|
|
161
182
|
installCodex();
|
|
162
183
|
repairs.push("Repaired Codex CLI hooks and shim");
|
|
163
184
|
}
|
|
@@ -171,8 +192,9 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
171
192
|
const grokInstalled = isGrokInstalled() || fs.existsSync(grokCfg) || fs.existsSync(grokShim);
|
|
172
193
|
if (grokInstalled) {
|
|
173
194
|
const isStaleShim = fs.existsSync(grokShim) && !shimIsCurrent(grokShim, GROK_HOOK_SCRIPT);
|
|
174
|
-
const
|
|
175
|
-
|
|
195
|
+
const wired = wiredGrokHookWords();
|
|
196
|
+
const hasOutdatedEntries = wired.some((e) => e.current === false);
|
|
197
|
+
if (isStaleShim || hasOutdatedEntries || wiringPointsAtMissingFile(wired)) {
|
|
176
198
|
installGrok();
|
|
177
199
|
repairs.push("Repaired Grok CLI hooks and shim");
|
|
178
200
|
}
|
|
@@ -185,8 +207,9 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
185
207
|
const kimiCfg = kimiConfigPath();
|
|
186
208
|
const kimiInstalled = isKimiInstalled() || fs.existsSync(kimiCfg) || fs.existsSync(kimiShim);
|
|
187
209
|
if (kimiInstalled) {
|
|
188
|
-
const
|
|
189
|
-
|
|
210
|
+
const wired = wiredKimiHookWords();
|
|
211
|
+
const hasOutdatedEntries = wired.some((e) => e.current === false);
|
|
212
|
+
if (hasOutdatedEntries || wiringPointsAtMissingFile(wired) || fs.existsSync(kimiShim) && fs.statSync(kimiShim).size === 0) {
|
|
190
213
|
installKimi();
|
|
191
214
|
repairs.push("Repaired Kimi Code hooks and shim");
|
|
192
215
|
}
|
|
@@ -245,9 +268,19 @@ function repairHarnessHooks(rootDir = process.cwd()) {
|
|
|
245
268
|
} catch (e) {
|
|
246
269
|
errors.push(`Failed to repair Antigravity CLI integration: ${extractErrorMessage(e)}`);
|
|
247
270
|
}
|
|
271
|
+
try {
|
|
272
|
+
if (vscodeRunsTokenGoatClaudeHooks() && vscodeHooksInstalled()) {
|
|
273
|
+
if (disableVscodeClaudeHooks()) {
|
|
274
|
+
repairs.push(VSCODE_CLAUDE_HOOKS_TURNED_OFF_TEXT);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
} catch (e) {
|
|
278
|
+
errors.push(`Failed to repair VS Code chat.useClaudeHooks: ${extractErrorMessage(e)}`);
|
|
279
|
+
}
|
|
248
280
|
return { repairs, errors };
|
|
249
281
|
}
|
|
250
282
|
export {
|
|
251
283
|
repairHarnessHooks,
|
|
252
|
-
shimIsCurrent
|
|
284
|
+
shimIsCurrent,
|
|
285
|
+
wiringPointsAtMissingFile
|
|
253
286
|
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
sessionSidecarPath
|
|
5
|
+
} from "./token-goat-chunk-WBA5SKT4.mjs";
|
|
6
|
+
import {
|
|
7
|
+
ensureDirSync
|
|
8
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
9
|
+
import {
|
|
10
|
+
init_define_import_meta_env
|
|
11
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
12
|
+
|
|
13
|
+
// src/read_shape.ts
|
|
14
|
+
init_define_import_meta_env();
|
|
15
|
+
import { readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname } from "node:path";
|
|
17
|
+
var SHAPES = /* @__PURE__ */ new Set(["outline", "skeleton", "fold", "truncated", "partial"]);
|
|
18
|
+
var SHAPE_SUFFIX = ".read-shape";
|
|
19
|
+
var MAX_ENTRIES = 512;
|
|
20
|
+
function load(target) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(readFileSync(target, "utf8"));
|
|
23
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function recordReadShape(stateKey, file, shape) {
|
|
29
|
+
const target = sessionSidecarPath(stateKey, SHAPE_SUFFIX);
|
|
30
|
+
if (target === null) return;
|
|
31
|
+
try {
|
|
32
|
+
const shapes = load(target);
|
|
33
|
+
if (shape === null) {
|
|
34
|
+
if (!Object.hasOwn(shapes, file)) return;
|
|
35
|
+
delete shapes[file];
|
|
36
|
+
} else {
|
|
37
|
+
delete shapes[file];
|
|
38
|
+
shapes[file] = shape;
|
|
39
|
+
}
|
|
40
|
+
const keys = Object.keys(shapes);
|
|
41
|
+
if (keys.length === 0) {
|
|
42
|
+
rmSync(target, { force: true });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
for (const k of keys.slice(0, Math.max(0, keys.length - MAX_ENTRIES))) delete shapes[k];
|
|
46
|
+
ensureDirSync(dirname(target));
|
|
47
|
+
writeFileSync(target, JSON.stringify(shapes), "utf8");
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function readShapeOf(stateKey, file) {
|
|
52
|
+
const target = sessionSidecarPath(stateKey, SHAPE_SUFFIX);
|
|
53
|
+
if (target === null) return null;
|
|
54
|
+
const shapes = load(target);
|
|
55
|
+
const shape = Object.hasOwn(shapes, file) ? shapes[file] : void 0;
|
|
56
|
+
return shape !== void 0 && SHAPES.has(shape) ? shape : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/line_diff.ts
|
|
60
|
+
init_define_import_meta_env();
|
|
61
|
+
function splitLines(text) {
|
|
62
|
+
const lines = text.split(/\r\n|\r|\n/);
|
|
63
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
64
|
+
return lines;
|
|
65
|
+
}
|
|
66
|
+
function lcsLength(a, b) {
|
|
67
|
+
const [shortArr, longArr] = a.length <= b.length ? [a, b] : [b, a];
|
|
68
|
+
const n = shortArr.length;
|
|
69
|
+
let prev = new Array(n + 1).fill(0);
|
|
70
|
+
let curr = new Array(n + 1).fill(0);
|
|
71
|
+
for (let i = 1; i <= longArr.length; i++) {
|
|
72
|
+
for (let j = 1; j <= n; j++) {
|
|
73
|
+
curr[j] = shortArr[j - 1] === longArr[i - 1] ? (prev[j - 1] ?? 0) + 1 : Math.max(prev[j] ?? 0, curr[j - 1] ?? 0);
|
|
74
|
+
}
|
|
75
|
+
const swap = prev;
|
|
76
|
+
prev = curr;
|
|
77
|
+
curr = swap;
|
|
78
|
+
}
|
|
79
|
+
return prev[n] ?? 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/write_target.ts
|
|
83
|
+
init_define_import_meta_env();
|
|
84
|
+
import { readFileSync as readFileSync2, statSync } from "node:fs";
|
|
85
|
+
var MAX_LINES_FOR_DIFF = 4e3;
|
|
86
|
+
var MAX_OLD_FILE_BYTES_FOR_DIFF = 4 * 1024 * 1024;
|
|
87
|
+
function inspectFile(filePath) {
|
|
88
|
+
let stat;
|
|
89
|
+
try {
|
|
90
|
+
stat = statSync(filePath);
|
|
91
|
+
} catch {
|
|
92
|
+
return { state: "absent" };
|
|
93
|
+
}
|
|
94
|
+
if (!stat.isFile()) return { state: "unusable" };
|
|
95
|
+
if (stat.size > MAX_OLD_FILE_BYTES_FOR_DIFF) return { state: "unread" };
|
|
96
|
+
try {
|
|
97
|
+
return { state: "text", text: readFileSync2(filePath, "utf-8") };
|
|
98
|
+
} catch {
|
|
99
|
+
return { state: "unread" };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function readKnownText(filePath) {
|
|
103
|
+
const onDisk = inspectFile(filePath);
|
|
104
|
+
return onDisk.state === "text" ? onDisk.text : "";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
recordReadShape,
|
|
109
|
+
readShapeOf,
|
|
110
|
+
splitLines,
|
|
111
|
+
lcsLength,
|
|
112
|
+
MAX_LINES_FOR_DIFF,
|
|
113
|
+
inspectFile,
|
|
114
|
+
readKnownText
|
|
115
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
isSecretFileName
|
|
5
|
+
} from "./token-goat-chunk-32ZOY4N5.mjs";
|
|
6
|
+
import {
|
|
7
|
+
fenceFileText
|
|
8
|
+
} from "./token-goat-chunk-4NAPX7BA.mjs";
|
|
9
|
+
import "./token-goat-chunk-U4WHMG6Y.mjs";
|
|
10
|
+
import "./token-goat-chunk-GVB2MUST.mjs";
|
|
11
|
+
import "./token-goat-chunk-XB5KKOCG.mjs";
|
|
12
|
+
import "./token-goat-chunk-OUKDTVNU.mjs";
|
|
13
|
+
import "./token-goat-chunk-XX6O25RN.mjs";
|
|
14
|
+
import {
|
|
15
|
+
redactSecrets
|
|
16
|
+
} from "./token-goat-chunk-T5P5ACNQ.mjs";
|
|
17
|
+
import "./token-goat-chunk-7EZTZOMC.mjs";
|
|
18
|
+
import "./token-goat-chunk-QYHO5CPH.mjs";
|
|
19
|
+
import "./token-goat-chunk-4GBVPH3D.mjs";
|
|
20
|
+
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
21
|
+
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
22
|
+
import "./token-goat-chunk-HU4TORC5.mjs";
|
|
23
|
+
import "./token-goat-chunk-GGGG7RWB.mjs";
|
|
24
|
+
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
25
|
+
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
26
|
+
import "./token-goat-chunk-CO3UYX6G.mjs";
|
|
27
|
+
import {
|
|
28
|
+
init_define_import_meta_env
|
|
29
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
30
|
+
|
|
31
|
+
// src/edit_near_miss.ts
|
|
32
|
+
init_define_import_meta_env();
|
|
33
|
+
var MAX_HITS = 20;
|
|
34
|
+
var MAX_OLD_LINES = 200;
|
|
35
|
+
var MAX_OLD_CHARS = 16384;
|
|
36
|
+
var MIN_LINE_COVERAGE = 0.5;
|
|
37
|
+
var FOLDS = [
|
|
38
|
+
[/[‘’‚‛′]/g, "'"],
|
|
39
|
+
[/[“”„‟″]/g, '"'],
|
|
40
|
+
[/[‐‑‒–—―−]/g, "-"]
|
|
41
|
+
];
|
|
42
|
+
function foldPunctuation(line) {
|
|
43
|
+
let out = line.normalize("NFKC");
|
|
44
|
+
for (const [pattern, replacement] of FOLDS) out = out.replace(pattern, replacement);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function trimEndBlanks(line) {
|
|
48
|
+
let end = line.length;
|
|
49
|
+
while (end > 0 && " \r\f\v".includes(line[end - 1])) end--;
|
|
50
|
+
return line.slice(0, end);
|
|
51
|
+
}
|
|
52
|
+
var RUNGS = [
|
|
53
|
+
{ rung: "trailing-whitespace", normalize: trimEndBlanks },
|
|
54
|
+
{ rung: "unicode-punctuation", normalize: (line) => trimEndBlanks(foldPunctuation(line)) },
|
|
55
|
+
{ rung: "indentation", normalize: (line) => foldPunctuation(line).trim() }
|
|
56
|
+
];
|
|
57
|
+
function splitLines(text) {
|
|
58
|
+
const lines = [];
|
|
59
|
+
let start = 0;
|
|
60
|
+
while (start <= text.length) {
|
|
61
|
+
const nl = text.indexOf("\n", start);
|
|
62
|
+
const end = nl === -1 ? text.length : nl;
|
|
63
|
+
lines.push({ text: text.slice(start, end), start, end });
|
|
64
|
+
if (nl === -1) break;
|
|
65
|
+
start = nl + 1;
|
|
66
|
+
}
|
|
67
|
+
return lines;
|
|
68
|
+
}
|
|
69
|
+
function matchesAt(fileLines, oldLines, at, tailAnchored) {
|
|
70
|
+
const last = oldLines.length - 1;
|
|
71
|
+
if (last === 0) {
|
|
72
|
+
const line = fileLines[at];
|
|
73
|
+
const old = oldLines[0];
|
|
74
|
+
return tailAnchored ? line.endsWith(old) : old.length >= line.length * MIN_LINE_COVERAGE && line.includes(old);
|
|
75
|
+
}
|
|
76
|
+
if (!fileLines[at].endsWith(oldLines[0])) return false;
|
|
77
|
+
for (let i = 1; i < last; i++) {
|
|
78
|
+
if (fileLines[at + i] !== oldLines[i]) return false;
|
|
79
|
+
}
|
|
80
|
+
const tail = fileLines[at + last];
|
|
81
|
+
return tailAnchored ? tail === oldLines[last] : tail.startsWith(oldLines[last]);
|
|
82
|
+
}
|
|
83
|
+
function findNearMiss(fileText, oldString) {
|
|
84
|
+
if (oldString === "" || fileText.includes(oldString)) return null;
|
|
85
|
+
const lines = splitLines(fileText);
|
|
86
|
+
const rawOld = oldString.split("\n");
|
|
87
|
+
if (rawOld.length > 1 && rawOld[rawOld.length - 1] === "") rawOld.pop();
|
|
88
|
+
if (rawOld.length > lines.length || rawOld.length > MAX_OLD_LINES || oldString.length > MAX_OLD_CHARS) return null;
|
|
89
|
+
for (const { rung, normalize } of RUNGS) {
|
|
90
|
+
const oldLines = rawOld.map(normalize);
|
|
91
|
+
const tailAnchored = /[ \t\r\f\v]$/.test(rawOld[rawOld.length - 1]);
|
|
92
|
+
if (oldLines.every((line) => line === "")) return null;
|
|
93
|
+
const normalized = lines.map((line) => normalize(line.text));
|
|
94
|
+
const hits = [];
|
|
95
|
+
let truncated = false;
|
|
96
|
+
for (let at = 0; at + oldLines.length <= lines.length; at++) {
|
|
97
|
+
if (!matchesAt(normalized, oldLines, at, tailAnchored)) continue;
|
|
98
|
+
if (hits.length === MAX_HITS) {
|
|
99
|
+
truncated = true;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
const first = lines[at];
|
|
103
|
+
const final = lines[at + oldLines.length - 1];
|
|
104
|
+
hits.push({ startLine: at + 1, endLine: at + oldLines.length, start: first.start, end: final.end });
|
|
105
|
+
}
|
|
106
|
+
if (hits.length > 0) return { rung, hits, truncated };
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
var NEAR_MISS_RUNG_NOTE = {
|
|
111
|
+
"trailing-whitespace": "ignoring trailing whitespace",
|
|
112
|
+
"unicode-punctuation": "ignoring quote, dash and space-character differences",
|
|
113
|
+
indentation: "ignoring indentation"
|
|
114
|
+
};
|
|
115
|
+
var MAX_SPAN_LINES = 20;
|
|
116
|
+
var MAX_SPAN_BYTES = 1536;
|
|
117
|
+
function isNearMissAdvice(text) {
|
|
118
|
+
return /^\[token-goat\] Edit failed: string not found in [^\n]*?, but (?:line \d+ matches|lines \d+-\d+ match|\d+\+? places match),/.test(text);
|
|
119
|
+
}
|
|
120
|
+
function describeNearMiss(fileText, display, miss) {
|
|
121
|
+
const [only, ...rest] = miss.hits;
|
|
122
|
+
if (only === void 0) return null;
|
|
123
|
+
const note = NEAR_MISS_RUNG_NOTE[miss.rung];
|
|
124
|
+
const head = `[token-goat] Edit failed: string not found in ${display}`;
|
|
125
|
+
if (rest.length > 0) {
|
|
126
|
+
const where = miss.hits.slice(0, 5).map((hit) => hit.startLine === hit.endLine ? `${hit.startLine}` : `${hit.startLine}-${hit.endLine}`);
|
|
127
|
+
const count = `${miss.hits.length}${miss.truncated ? "+" : ""}`;
|
|
128
|
+
return `${head}, but ${count} places match, ${note} (lines ${where.join(", ")}). View one range and add surrounding context to old_string.`;
|
|
129
|
+
}
|
|
130
|
+
const range = only.startLine === only.endLine ? `line ${only.startLine} matches` : `lines ${only.startLine}-${only.endLine} match`;
|
|
131
|
+
const span = redactSecrets(fileText.slice(only.start, only.end)).text;
|
|
132
|
+
if (isSecretFileName(display) || only.endLine - only.startLine + 1 > MAX_SPAN_LINES || Buffer.byteLength(span, "utf8") > MAX_SPAN_BYTES) {
|
|
133
|
+
return `${head}, but ${range}, ${note}. View that range to copy the exact text.`;
|
|
134
|
+
}
|
|
135
|
+
return `${head}, but ${range}, ${note}. Copy the on-disk text below into old_string exactly:
|
|
136
|
+
${fenceFileText(span)}`;
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
MAX_SPAN_BYTES,
|
|
140
|
+
MAX_SPAN_LINES,
|
|
141
|
+
NEAR_MISS_RUNG_NOTE,
|
|
142
|
+
describeNearMiss,
|
|
143
|
+
findNearMiss,
|
|
144
|
+
isNearMissAdvice
|
|
145
|
+
};
|