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
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
windowsPowerShellPath
|
|
5
|
+
} from "./token-goat-chunk-65N4RHP4.mjs";
|
|
6
|
+
import {
|
|
7
|
+
powerShellCommandArgs
|
|
8
|
+
} from "./token-goat-chunk-X2SUP3EI.mjs";
|
|
9
|
+
import {
|
|
10
|
+
init_define_import_meta_env
|
|
11
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
12
|
+
|
|
13
|
+
// src/claude_hidden_rules.ts
|
|
14
|
+
init_define_import_meta_env();
|
|
15
|
+
import { execFile, spawnSync } from "node:child_process";
|
|
16
|
+
import * as fs from "node:fs";
|
|
17
|
+
import * as path from "node:path";
|
|
18
|
+
var HARMLESS_FLAGS = /* @__PURE__ */ new Set(["--resume", "-r", "--continue", "-c", "--fork-session", "--session-id", "--name", "-n", "--model", "--fallback-model", "--effort", "--thinking", "--max-thinking-tokens", "--dangerously-skip-permissions", "--allow-dangerously-skip-permissions", "--permission-mode", "--enable-auto-mode", "--verbose", "--debug", "-d", "--debug-file", "--print", "-p", "--output-format", "--include-partial-messages", "--ide", "--chrome", "--no-chrome", "--mcp-config", "--strict-mcp-config", "--append-system-prompt", "--append-system-prompt-file", "--system-prompt", "--system-prompt-file", "--max-turns", "--max-budget-usd", "--worktree", "-w", "--tmux", "--version", "-v", "--allowedtools", "--allowed-tools", "--tools", "--disable-slash-commands", "--no-session-persistence"]);
|
|
19
|
+
var CLI_ENTRYPOINTS = /* @__PURE__ */ new Set(["cli", "sdk-cli"]);
|
|
20
|
+
var BUILTIN_AGENTS = /* @__PURE__ */ new Set(["Explore", "Plan", "general-purpose", "statusline-setup", "claude-code-guide", "web-fetch", "fork", "claude", "worker", "workflow-subagent", "comment-thread-analyst"]);
|
|
21
|
+
var RULE_DIRS = ["skills", "commands", "agents"];
|
|
22
|
+
var RULE_PATH = /(?:^|\/)\.claude\/(?:skills|commands|agents)(?:\/|$)/;
|
|
23
|
+
var AGENT_PATH = /(?:^|\/)\.claude\/agents(?:\/|$)/;
|
|
24
|
+
var CLAUDE_INSIDE = /(?:^|\/)\.claude\//;
|
|
25
|
+
var SCAN_BUDGET = 2e4;
|
|
26
|
+
var NESTED_STAMP_DEPTH = 3;
|
|
27
|
+
var NESTED_STAMP_DIRS = 2e3;
|
|
28
|
+
var SCAN_TTL_MS = 6e4;
|
|
29
|
+
var RACY_MS = 2e3;
|
|
30
|
+
var FILE_HEAD_BYTES = 256 * 1024;
|
|
31
|
+
var OPENS_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n/;
|
|
32
|
+
var processCache;
|
|
33
|
+
var fixedCache;
|
|
34
|
+
var nestedCache;
|
|
35
|
+
function resetHiddenRuleCache() {
|
|
36
|
+
processCache = void 0;
|
|
37
|
+
fixedCache = void 0;
|
|
38
|
+
nestedCache = void 0;
|
|
39
|
+
}
|
|
40
|
+
function hasProc() {
|
|
41
|
+
return process.platform !== "win32" && fs.existsSync("/proc/self/cmdline");
|
|
42
|
+
}
|
|
43
|
+
function procCommandLine(pid) {
|
|
44
|
+
if (!hasProc()) return void 0;
|
|
45
|
+
const raw = fs.readFileSync(`/proc/${pid}/cmdline`, "utf8");
|
|
46
|
+
return raw.includes("\0\0") ? null : raw.split("\0").join(" ").trim();
|
|
47
|
+
}
|
|
48
|
+
function commandLineQuery(pid) {
|
|
49
|
+
if (process.platform === "win32") return [windowsPowerShellPath(), powerShellCommandArgs(`(Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}').CommandLine`)];
|
|
50
|
+
return ["ps", ["-ww", "-o", "args=", "-p", pid]];
|
|
51
|
+
}
|
|
52
|
+
function executableQuery(pid) {
|
|
53
|
+
return ["ps", ["-ww", "-o", "comm=", "-p", pid]];
|
|
54
|
+
}
|
|
55
|
+
function resolveCommand(word) {
|
|
56
|
+
const candidates = word.includes("/") ? [path.resolve(word)] : (process.env["PATH"] ?? "").split(path.delimiter).filter((d) => d !== "").map((d) => path.join(d, word));
|
|
57
|
+
for (const candidate of candidates) {
|
|
58
|
+
try {
|
|
59
|
+
return fs.realpathSync(candidate);
|
|
60
|
+
} catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function untitledLine(printed, executable) {
|
|
67
|
+
const line = printed.replace(/\r?\n$/, "");
|
|
68
|
+
if (/\s$/.test(line) || executable === null) return null;
|
|
69
|
+
const first = line.trim().split(/\s+/)[0] ?? "";
|
|
70
|
+
const real = first === "" ? null : resolveCommand(first);
|
|
71
|
+
const exec = executable.trim();
|
|
72
|
+
let execReal;
|
|
73
|
+
try {
|
|
74
|
+
execReal = exec === "" ? null : fs.realpathSync(exec);
|
|
75
|
+
} catch {
|
|
76
|
+
execReal = null;
|
|
77
|
+
}
|
|
78
|
+
return real !== null && real === execReal ? line.trim() : null;
|
|
79
|
+
}
|
|
80
|
+
function commandLine(pid) {
|
|
81
|
+
try {
|
|
82
|
+
const proc = procCommandLine(pid);
|
|
83
|
+
if (proc !== void 0) return proc;
|
|
84
|
+
const [file, args] = commandLineQuery(pid);
|
|
85
|
+
const res = spawnSync(file, args, { encoding: "utf8", windowsHide: true, timeout: 15e3 });
|
|
86
|
+
if (res.error !== void 0 || res.status !== 0) return null;
|
|
87
|
+
if (process.platform === "win32") return res.stdout.trim();
|
|
88
|
+
const [exeFile, exeArgs] = executableQuery(pid);
|
|
89
|
+
const exe = spawnSync(exeFile, exeArgs, { encoding: "utf8", windowsHide: true, timeout: 15e3 });
|
|
90
|
+
return untitledLine(res.stdout, exe.error === void 0 && exe.status === 0 ? exe.stdout : null);
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function queryAsync(file, args) {
|
|
96
|
+
return new Promise((resolve2) => {
|
|
97
|
+
execFile(file, args, { encoding: "utf8", windowsHide: true, timeout: 15e3 }, (err, stdout) => resolve2(err === null ? stdout : null));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async function commandLineAsync(pid) {
|
|
101
|
+
try {
|
|
102
|
+
const proc = procCommandLine(pid);
|
|
103
|
+
if (proc !== void 0) return proc;
|
|
104
|
+
const [file, args] = commandLineQuery(pid);
|
|
105
|
+
const printed = await queryAsync(file, args);
|
|
106
|
+
if (printed === null) return null;
|
|
107
|
+
if (process.platform === "win32") return printed.trim();
|
|
108
|
+
const [exeFile, exeArgs] = executableQuery(pid);
|
|
109
|
+
return untitledLine(printed, await queryAsync(exeFile, exeArgs));
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function processKeyOf(env) {
|
|
115
|
+
return `${env["CLAUDE_CODE_SESSION_ID"] ?? ""}:${env["CLAUDE_PID"] ?? ""}:${env["CLAUDE_CODE_ENTRYPOINT"] ?? ""}`;
|
|
116
|
+
}
|
|
117
|
+
function entryReason(env) {
|
|
118
|
+
const entrypoint = env["CLAUDE_CODE_ENTRYPOINT"] ?? "";
|
|
119
|
+
if (!CLI_ENTRYPOINTS.has(entrypoint)) return `entry point ${entrypoint === "" ? "unknown" : entrypoint}`;
|
|
120
|
+
if (!/^[1-9]\d{0,9}$/.test(env["CLAUDE_PID"] ?? "")) return "claude process unknown";
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
function flagsOf(line) {
|
|
124
|
+
const flags = [];
|
|
125
|
+
const words = (line.match(/"[^"]*"?|\S+/g) ?? []).map((raw) => raw.replace(/^"/, "").replace(/"$/, ""));
|
|
126
|
+
for (let i = 0; i < words.length; i++) {
|
|
127
|
+
const token = words[i];
|
|
128
|
+
if (token === "--") break;
|
|
129
|
+
if (!token.startsWith("-")) continue;
|
|
130
|
+
const eq = token.indexOf("=");
|
|
131
|
+
const next = words[i + 1];
|
|
132
|
+
flags.push({ name: (eq < 0 ? token : token.slice(0, eq)).toLowerCase(), value: eq >= 0 ? token.slice(eq + 1) : next !== void 0 && !next.startsWith("-") ? next : void 0 });
|
|
133
|
+
}
|
|
134
|
+
return flags;
|
|
135
|
+
}
|
|
136
|
+
var PROOF_SOURCES = ["user", "project", "local"];
|
|
137
|
+
function flagsReason(flags) {
|
|
138
|
+
for (const { name, value } of flags) {
|
|
139
|
+
if (name === "--setting-sources") {
|
|
140
|
+
const given = new Set((value ?? "").toLowerCase().split(",").map((v) => v.trim()));
|
|
141
|
+
const dropped = PROOF_SOURCES.find((source) => !given.has(source));
|
|
142
|
+
if (dropped !== void 0) return `claude started with --setting-sources without ${dropped}`;
|
|
143
|
+
} else if (!HARMLESS_FLAGS.has(name)) return `claude started with ${name}`;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
function commandLineReason(line) {
|
|
148
|
+
return line === null || line === "" ? "claude command line unreadable" : flagsReason(flagsOf(line));
|
|
149
|
+
}
|
|
150
|
+
function processReason(env) {
|
|
151
|
+
const key = processKeyOf(env);
|
|
152
|
+
if (processCache?.key === key) return processCache.reason;
|
|
153
|
+
const entry = entryReason(env);
|
|
154
|
+
const line = entry === null ? commandLine(env["CLAUDE_PID"]) : null;
|
|
155
|
+
const reason = entry ?? commandLineReason(line);
|
|
156
|
+
if (entry !== null || line !== null) processCache = { key, reason };
|
|
157
|
+
return reason;
|
|
158
|
+
}
|
|
159
|
+
function isOtherHost(env) {
|
|
160
|
+
const entrypoint = env["CLAUDE_CODE_ENTRYPOINT"] ?? "";
|
|
161
|
+
return entrypoint !== "" && !CLI_ENTRYPOINTS.has(entrypoint);
|
|
162
|
+
}
|
|
163
|
+
function commandLineRuleSource(env) {
|
|
164
|
+
return isOtherHost(env) ? null : processReason(env);
|
|
165
|
+
}
|
|
166
|
+
async function primeProcessReason(env) {
|
|
167
|
+
const key = processKeyOf(env);
|
|
168
|
+
if (processCache?.key === key) return;
|
|
169
|
+
const entry = entryReason(env);
|
|
170
|
+
const line = entry === null ? await commandLineAsync(env["CLAUDE_PID"]) : null;
|
|
171
|
+
if (entry !== null || line !== null) processCache = { key, reason: entry ?? commandLineReason(line) };
|
|
172
|
+
}
|
|
173
|
+
function frontmatter(text) {
|
|
174
|
+
return /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(text)?.[1];
|
|
175
|
+
}
|
|
176
|
+
function frontmatterAddsRule(front) {
|
|
177
|
+
if (front.includes("PermissionRequest")) return true;
|
|
178
|
+
const lines = front.split(/\r?\n/);
|
|
179
|
+
for (let i = 0; i < lines.length; i++) {
|
|
180
|
+
const m = /^\s*["']?disallowed[-_]?tools["']?\s*:(.*)$/i.exec(lines[i]);
|
|
181
|
+
if (m === null) continue;
|
|
182
|
+
let value = m[1];
|
|
183
|
+
for (let j = i + 1; j < lines.length && /^[\s-]/.test(lines[j]); j++) value += ` ${lines[j]}`;
|
|
184
|
+
if (value.split(/[\s,[\]"'-]+/).some((t) => t !== "" && !/^[A-Za-z0-9_*.]+$/.test(t))) return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
function newScan(helpers, stamped) {
|
|
189
|
+
return { helpers, budget: SCAN_BUDGET, reason: null, stamps: stamped ? /* @__PURE__ */ new Map() : void 0, agents: /* @__PURE__ */ new Set(), pluginAgents: /* @__PURE__ */ new Set(), startedAt: Date.now(), volatile: false, walked: /* @__PURE__ */ new Set() };
|
|
190
|
+
}
|
|
191
|
+
function result(scan) {
|
|
192
|
+
return { reason: scan.reason, stamps: scan.stamps ?? /* @__PURE__ */ new Map(), agents: scan.agents, pluginAgents: scan.pluginAgents, volatile: scan.volatile };
|
|
193
|
+
}
|
|
194
|
+
function stamp(file) {
|
|
195
|
+
try {
|
|
196
|
+
const st = fs.statSync(file);
|
|
197
|
+
return `${st.mtimeMs}:${st.isDirectory() ? "dir" : st.size}`;
|
|
198
|
+
} catch (err) {
|
|
199
|
+
const code = err.code;
|
|
200
|
+
return code === "ENOENT" || code === "ENOTDIR" ? "absent" : "unreadable";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function record(scan, file) {
|
|
204
|
+
if (scan.stamps === void 0) return;
|
|
205
|
+
const was = stamp(file);
|
|
206
|
+
scan.stamps.set(file, was);
|
|
207
|
+
if (was === "unreadable" || Number(was.slice(0, was.indexOf(":"))) > scan.startedAt - RACY_MS) scan.volatile = true;
|
|
208
|
+
}
|
|
209
|
+
function stillCurrent(stamps) {
|
|
210
|
+
for (const [file, was] of stamps) if (stamp(file) !== was) return false;
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
function head(file) {
|
|
214
|
+
let fd;
|
|
215
|
+
try {
|
|
216
|
+
fd = fs.openSync(file, "r");
|
|
217
|
+
const buf = Buffer.alloc(FILE_HEAD_BYTES);
|
|
218
|
+
const got = fs.readSync(fd, buf, 0, FILE_HEAD_BYTES, 0);
|
|
219
|
+
return { text: buf.subarray(0, got).toString("utf8"), cut: got === FILE_HEAD_BYTES && fs.fstatSync(fd).size > got };
|
|
220
|
+
} catch (err) {
|
|
221
|
+
const code = err.code;
|
|
222
|
+
return { failure: code === "ENOENT" || code === "ENOTDIR" ? "missing" : "unreadable" };
|
|
223
|
+
} finally {
|
|
224
|
+
if (fd !== void 0) fs.closeSync(fd);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function checkFile(file, scan, place) {
|
|
228
|
+
const lower = file.toLowerCase();
|
|
229
|
+
const json = lower.endsWith(".json");
|
|
230
|
+
if (!json && !lower.endsWith(".md")) return;
|
|
231
|
+
record(scan, file);
|
|
232
|
+
const read = head(file);
|
|
233
|
+
let text;
|
|
234
|
+
let cut;
|
|
235
|
+
if ("failure" in read) {
|
|
236
|
+
if (read.failure === "unreadable") {
|
|
237
|
+
scan.reason = `cannot read ${file}`;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const indexed = scan.indexedText?.(file);
|
|
241
|
+
if (indexed === void 0) return;
|
|
242
|
+
if (indexed === null) {
|
|
243
|
+
scan.reason = `cannot read ${file} from the index`;
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
text = indexed.slice(0, FILE_HEAD_BYTES);
|
|
247
|
+
cut = indexed.length > FILE_HEAD_BYTES;
|
|
248
|
+
} else {
|
|
249
|
+
text = read.text;
|
|
250
|
+
cut = read.cut;
|
|
251
|
+
}
|
|
252
|
+
const front = json ? void 0 : frontmatter(text) ?? "";
|
|
253
|
+
const unfinished = cut && (json || OPENS_FRONTMATTER.test(text) && frontmatter(text) === void 0);
|
|
254
|
+
if (front === void 0 ? text.includes("PermissionRequest") : frontmatterAddsRule(front)) scan.reason = `rule source ${file}`;
|
|
255
|
+
else if (unfinished) scan.reason = `cannot scan ${file}: it runs past the first ${FILE_HEAD_BYTES} bytes read`;
|
|
256
|
+
else if (front !== void 0 && place.agents) {
|
|
257
|
+
const name = /^name[ \t]*:(.*)$/m.exec(front)?.[1]?.trim().replace(/^(["'])(.*)\1$/, "$2");
|
|
258
|
+
if (name !== void 0 && name !== "") (place.plugin ? scan.pluginAgents : scan.agents).add(name);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function linksToDir(full) {
|
|
262
|
+
try {
|
|
263
|
+
return fs.lstatSync(full).isSymbolicLink() && fs.statSync(full).isDirectory();
|
|
264
|
+
} catch {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function scanDir(dir, scan, place) {
|
|
269
|
+
if (scan.reason !== null || !scan.helpers.sourceAllowed(dir)) return;
|
|
270
|
+
record(scan, dir);
|
|
271
|
+
let entries;
|
|
272
|
+
try {
|
|
273
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
274
|
+
} catch (err) {
|
|
275
|
+
const code = err.code;
|
|
276
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") scan.reason = `cannot read ${dir}`;
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
for (const entry of entries) {
|
|
280
|
+
if (scan.reason !== null) return;
|
|
281
|
+
if (--scan.budget < 0) {
|
|
282
|
+
scan.reason = "too many files to check";
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const full = path.join(dir, entry.name);
|
|
286
|
+
let isDir = entry.isDirectory();
|
|
287
|
+
let isFile = entry.isFile();
|
|
288
|
+
if (entry.isSymbolicLink()) {
|
|
289
|
+
try {
|
|
290
|
+
const st = fs.statSync(full);
|
|
291
|
+
isDir = st.isDirectory();
|
|
292
|
+
isFile = st.isFile();
|
|
293
|
+
} catch {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (isDir && entry.name !== "node_modules" && entry.name !== ".git") {
|
|
298
|
+
if (place.depth >= 32) scan.reason = `too deep under ${dir}`;
|
|
299
|
+
else scanDir(full, scan, { ...place, depth: place.depth + 1, agents: place.agents || entry.name === "agents" });
|
|
300
|
+
} else if (isFile) {
|
|
301
|
+
checkFile(full, scan, place);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function scanClaudeDir(claudeDir, scan) {
|
|
306
|
+
for (const sub of RULE_DIRS) scanDir(path.join(claudeDir, sub), scan, { depth: 0, agents: sub === "agents", plugin: false });
|
|
307
|
+
}
|
|
308
|
+
function firstWalk(dir, scan) {
|
|
309
|
+
let real;
|
|
310
|
+
try {
|
|
311
|
+
real = fs.realpathSync.native(dir);
|
|
312
|
+
} catch {
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
const key = process.platform === "win32" ? real.toLowerCase() : real;
|
|
316
|
+
if (scan.walked.has(key)) return false;
|
|
317
|
+
scan.walked.add(key);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
function walkForClaudeDirs(dir, scan, depth = 0) {
|
|
321
|
+
if (scan.reason !== null || !scan.helpers.sourceAllowed(dir) || !firstWalk(dir, scan)) return;
|
|
322
|
+
let entries;
|
|
323
|
+
try {
|
|
324
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
325
|
+
} catch (err) {
|
|
326
|
+
const code = err.code;
|
|
327
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") scan.reason = `cannot read ${dir}`;
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
for (const entry of entries) {
|
|
331
|
+
if (scan.reason !== null) return;
|
|
332
|
+
if (--scan.budget < 0) {
|
|
333
|
+
scan.reason = "too many files to check";
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (entry.name === ".git") continue;
|
|
337
|
+
const full = path.join(dir, entry.name);
|
|
338
|
+
if (!entry.isDirectory() && !(entry.isSymbolicLink() && linksToDir(full))) continue;
|
|
339
|
+
if (entry.name === ".claude") scanClaudeDir(full, scan);
|
|
340
|
+
else if (depth >= 32) scan.reason = `too deep under ${dir}`;
|
|
341
|
+
else walkForClaudeDirs(full, scan, depth + 1);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function scanGitCheckout(project, scan) {
|
|
345
|
+
const list = (args) => {
|
|
346
|
+
const res = scan.helpers.runGit(["ls-files", "-z", ...args], { cwd: project, timeoutMs: 15e3 });
|
|
347
|
+
return res.exitCode === 0 ? res.stdout.split("\0").filter((entry) => entry !== "") : null;
|
|
348
|
+
};
|
|
349
|
+
const tracked = list(["-s"]);
|
|
350
|
+
const untracked = list(["-o", "--exclude-standard"]);
|
|
351
|
+
const ignored = list(["-o", "-i", "--exclude-standard", "--directory"]);
|
|
352
|
+
if (tracked === null || untracked === null || ignored === null) {
|
|
353
|
+
scan.reason = "cannot list nested skills";
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
stampListedDirs(project, [...tracked.map((record2) => record2.slice(record2.indexOf(" ") + 1)), ...untracked, ...ignored], scan);
|
|
357
|
+
const candidates = [...untracked, ...ignored.filter((rel) => !rel.endsWith("/"))];
|
|
358
|
+
const objects = /* @__PURE__ */ new Map();
|
|
359
|
+
for (const record2 of tracked) {
|
|
360
|
+
const tab = record2.indexOf(" ");
|
|
361
|
+
const rel = record2.slice(tab + 1);
|
|
362
|
+
if (record2.startsWith("120000 ") || RULE_PATH.test(rel)) candidates.push(rel);
|
|
363
|
+
if (RULE_PATH.test(rel)) objects.set(path.join(project, rel), record2.slice(0, tab).split(" ")[1]);
|
|
364
|
+
}
|
|
365
|
+
scan.indexedText = (file) => {
|
|
366
|
+
const object = objects.get(file);
|
|
367
|
+
if (object === void 0) return void 0;
|
|
368
|
+
const res = scan.helpers.runGit(["cat-file", "blob", object], { cwd: project, timeoutMs: 15e3 });
|
|
369
|
+
return res.exitCode === 0 ? res.stdout : null;
|
|
370
|
+
};
|
|
371
|
+
const sorted = [...ignored].sort();
|
|
372
|
+
const ignoredDirs = sorted.filter((rel, i) => rel.endsWith("/") && sorted[i + 1]?.startsWith(rel) !== true && CLAUDE_INSIDE.test(rel));
|
|
373
|
+
for (const rel of [...candidates, ...ignoredDirs]) {
|
|
374
|
+
if (scan.reason !== null) return;
|
|
375
|
+
if (--scan.budget < 0) {
|
|
376
|
+
scan.reason = "too many files to check";
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const full = path.join(project, rel);
|
|
380
|
+
const place = { depth: 0, agents: AGENT_PATH.test(rel), plugin: false };
|
|
381
|
+
if (rel.endsWith("/") || linksToDir(full)) {
|
|
382
|
+
if (RULE_PATH.test(rel)) scanDir(full, scan, place);
|
|
383
|
+
else if (path.basename(full) === ".claude") scanClaudeDir(full, scan);
|
|
384
|
+
else if (!rel.endsWith("/")) walkForClaudeDirs(full, scan);
|
|
385
|
+
} else if (RULE_PATH.test(rel)) {
|
|
386
|
+
checkFile(full, scan, place);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function scanFixed(cwd, project, helpers) {
|
|
391
|
+
const scan = newScan(helpers, true);
|
|
392
|
+
const configDir = helpers.configDir();
|
|
393
|
+
const roots = [configDir, ...[cwd, project].flatMap(helpers.selfAndAncestors).map((d) => path.join(d, ".claude")), ...helpers.managedDirs().map((d) => path.join(d, ".claude"))];
|
|
394
|
+
const seen = /* @__PURE__ */ new Set();
|
|
395
|
+
for (const root of roots) {
|
|
396
|
+
const key = process.platform === "win32" ? root.toLowerCase() : root;
|
|
397
|
+
if (seen.has(key)) continue;
|
|
398
|
+
seen.add(key);
|
|
399
|
+
scanClaudeDir(root, scan);
|
|
400
|
+
}
|
|
401
|
+
scanDir(path.join(configDir, "plugins", "cache"), scan, { depth: 0, agents: false, plugin: true });
|
|
402
|
+
return result(scan);
|
|
403
|
+
}
|
|
404
|
+
function gitDirOf(root) {
|
|
405
|
+
const dot = path.join(root, ".git");
|
|
406
|
+
try {
|
|
407
|
+
if (fs.statSync(dot).isDirectory()) return dot;
|
|
408
|
+
const line = fs.readFileSync(dot, "utf8").split("\n").find((l) => l.startsWith("gitdir:"));
|
|
409
|
+
const named = line?.slice("gitdir:".length).trim();
|
|
410
|
+
return named === void 0 || named === "" ? dot : path.resolve(root, named);
|
|
411
|
+
} catch {
|
|
412
|
+
return dot;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function stampGitState(root, scan) {
|
|
416
|
+
const gitDir = gitDirOf(root);
|
|
417
|
+
for (const name of ["index", "HEAD"]) record(scan, path.join(gitDir, name));
|
|
418
|
+
}
|
|
419
|
+
function stampListedDirs(project, listed, scan) {
|
|
420
|
+
const dirs = /* @__PURE__ */ new Set([project]);
|
|
421
|
+
for (const rel of listed) {
|
|
422
|
+
const parts = rel.split("/").filter((part) => part !== "");
|
|
423
|
+
const claude = parts.indexOf(".claude");
|
|
424
|
+
const add = (from, to) => {
|
|
425
|
+
for (let n = from; n <= to; n++) dirs.add(path.join(project, ...parts.slice(0, n)));
|
|
426
|
+
};
|
|
427
|
+
add(1, Math.min(parts.length - 1, NESTED_STAMP_DEPTH));
|
|
428
|
+
if (claude >= 0) add(claude, parts.length - 1);
|
|
429
|
+
if (dirs.size >= NESTED_STAMP_DIRS) {
|
|
430
|
+
scan.volatile = true;
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
for (const dir of dirs) record(scan, dir);
|
|
435
|
+
}
|
|
436
|
+
function scanNested(project, helpers) {
|
|
437
|
+
const scan = newScan(helpers, true);
|
|
438
|
+
const root = helpers.selfAndAncestors(project).find((d) => fs.existsSync(path.join(d, ".git")));
|
|
439
|
+
if (root !== void 0) {
|
|
440
|
+
stampGitState(root, scan);
|
|
441
|
+
scanGitCheckout(project, scan);
|
|
442
|
+
} else walkForClaudeDirs(project, scan);
|
|
443
|
+
return result(scan);
|
|
444
|
+
}
|
|
445
|
+
function agentReason(agentType, scans) {
|
|
446
|
+
if (agentType === void 0 || BUILTIN_AGENTS.has(agentType)) return null;
|
|
447
|
+
const colon = agentType.lastIndexOf(":");
|
|
448
|
+
const known = colon < 0 ? scans.some((s) => s.agents.has(agentType)) : scans.some((s) => s.pluginAgents.has(agentType.slice(colon + 1)));
|
|
449
|
+
return known ? null : `agent ${agentType} not checked`;
|
|
450
|
+
}
|
|
451
|
+
function hiddenRuleSource(cwd, projectDir, env, helpers, query = {}) {
|
|
452
|
+
const now = query.now ?? Date.now();
|
|
453
|
+
const processKey = processKeyOf(env);
|
|
454
|
+
const processReasonNow = query.filesOnly === true ? null : processReason(env);
|
|
455
|
+
if (processReasonNow !== null) return processReasonNow;
|
|
456
|
+
const here = path.resolve(cwd);
|
|
457
|
+
const project = projectDir !== void 0 && path.isAbsolute(projectDir) ? path.resolve(projectDir) : here;
|
|
458
|
+
const scanKey = `${processKey}:${here}:${project}`;
|
|
459
|
+
if (fixedCache?.key !== scanKey || (fixedCache.reason !== null ? now - fixedCache.at > SCAN_TTL_MS : fixedCache.volatile || !stillCurrent(fixedCache.stamps))) fixedCache = { key: scanKey, at: now, ...scanFixed(here, project, helpers) };
|
|
460
|
+
if (fixedCache.reason !== null) return fixedCache.reason;
|
|
461
|
+
if (nestedCache?.key !== scanKey || now - nestedCache.at > SCAN_TTL_MS || nestedCache.reason === null && (nestedCache.volatile || !stillCurrent(nestedCache.stamps))) nestedCache = { key: scanKey, at: now, ...scanNested(project, helpers) };
|
|
462
|
+
return nestedCache.reason ?? agentReason(query.agentType, [fixedCache, nestedCache]);
|
|
463
|
+
}
|
|
464
|
+
function hiddenRules(helpers) {
|
|
465
|
+
return {
|
|
466
|
+
hidden: (cwd, agentType, filesOnly) => hiddenRuleSource(cwd, process.env["CLAUDE_PROJECT_DIR"], process.env, helpers, { agentType, filesOnly }) !== null,
|
|
467
|
+
lineRules: () => commandLineRuleSource(process.env) !== null,
|
|
468
|
+
prime: (env) => primeProcessReason(env)
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
export {
|
|
472
|
+
commandLineRuleSource,
|
|
473
|
+
frontmatterAddsRule,
|
|
474
|
+
hiddenRuleSource,
|
|
475
|
+
hiddenRules,
|
|
476
|
+
primeProcessReason,
|
|
477
|
+
resetHiddenRuleCache,
|
|
478
|
+
stamp
|
|
479
|
+
};
|
|
@@ -3,12 +3,13 @@ const require = __cjsRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
copyFromSharedCache,
|
|
5
5
|
downloadPinned
|
|
6
|
-
} from "./token-goat-chunk-
|
|
7
|
-
import "./token-goat-chunk-
|
|
6
|
+
} from "./token-goat-chunk-AUNGYYQX.mjs";
|
|
7
|
+
import "./token-goat-chunk-2UPZGKKY.mjs";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig
|
|
10
|
-
} from "./token-goat-chunk-
|
|
11
|
-
import "./token-goat-chunk-
|
|
10
|
+
} from "./token-goat-chunk-7EZTZOMC.mjs";
|
|
11
|
+
import "./token-goat-chunk-QYHO5CPH.mjs";
|
|
12
|
+
import "./token-goat-chunk-4GBVPH3D.mjs";
|
|
12
13
|
import {
|
|
13
14
|
registerReset
|
|
14
15
|
} from "./token-goat-chunk-YZAAZU2S.mjs";
|
|
@@ -16,12 +17,13 @@ import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
|
16
17
|
import {
|
|
17
18
|
atomicWriteText,
|
|
18
19
|
ensureDirSync
|
|
19
|
-
} from "./token-goat-chunk-
|
|
20
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
21
|
+
import "./token-goat-chunk-GGGG7RWB.mjs";
|
|
20
22
|
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
21
23
|
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
22
24
|
import {
|
|
23
25
|
ensureDataDirPrivate
|
|
24
|
-
} from "./token-goat-chunk-
|
|
26
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
25
27
|
import {
|
|
26
28
|
init_define_import_meta_env
|
|
27
29
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
formatCommandError,
|
|
5
|
+
writeCommandFailure
|
|
6
|
+
} from "./token-goat-chunk-CBIQ7WTD.mjs";
|
|
3
7
|
import {
|
|
4
8
|
loadConfig
|
|
5
|
-
} from "./token-goat-chunk-
|
|
9
|
+
} from "./token-goat-chunk-7EZTZOMC.mjs";
|
|
6
10
|
import {
|
|
7
11
|
ensureDirSync
|
|
8
|
-
} from "./token-goat-chunk-
|
|
12
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
13
|
+
import {
|
|
14
|
+
fencedCommand
|
|
15
|
+
} from "./token-goat-chunk-GGGG7RWB.mjs";
|
|
9
16
|
import {
|
|
10
17
|
displaySafeJson
|
|
11
18
|
} from "./token-goat-chunk-FNFBKLRD.mjs";
|
|
12
19
|
import {
|
|
13
20
|
VERSION,
|
|
14
21
|
dataDir
|
|
15
|
-
} from "./token-goat-chunk-
|
|
22
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
16
23
|
import {
|
|
17
24
|
init_define_import_meta_env
|
|
18
25
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -102,7 +109,7 @@ function currentUpgradeDecision(status) {
|
|
|
102
109
|
}
|
|
103
110
|
var DEV_CHECKOUT_ADVICE = "git pull && npm run build && token-goat install";
|
|
104
111
|
function updateAdvice(decision) {
|
|
105
|
-
if (decision === "install") return "Run
|
|
112
|
+
if (decision === "install") return "Run `token-goat upgrade` to update.";
|
|
106
113
|
if (decision === "dev-checkout") return `This token-goat runs from a development checkout. To update it, run: ${DEV_CHECKOUT_ADVICE}`;
|
|
107
114
|
return null;
|
|
108
115
|
}
|
|
@@ -137,6 +144,8 @@ async function fetchViaHttp(registryUrl, timeoutMs = 3500) {
|
|
|
137
144
|
targetUrl,
|
|
138
145
|
{
|
|
139
146
|
headers: { "User-Agent": `token-goat/${VERSION} (node/${process.version})` },
|
|
147
|
+
// A fresh connection, never one pooled by the global agent: after npm's blocking spawn the registry may have closed the pooled one, and reusing it fails with ECONNRESET.
|
|
148
|
+
agent: false,
|
|
140
149
|
timeout: timeoutMs
|
|
141
150
|
},
|
|
142
151
|
(res) => {
|
|
@@ -247,18 +256,18 @@ async function checkUpdateStatus(timeoutMs = 3500, forceFresh = false) {
|
|
|
247
256
|
async function cmdUpgrade(opts = {}, onSyncHooks) {
|
|
248
257
|
const status = await checkUpdateStatus(3500, true);
|
|
249
258
|
if (opts.check) {
|
|
250
|
-
|
|
251
|
-
|
|
259
|
+
const failure = status.error ?? (status.latest ? void 0 : "could not determine the latest version");
|
|
260
|
+
if (failure !== void 0) {
|
|
261
|
+
writeCommandFailure(opts.json === true, { ...status }, [`${failure}.`, `Current version: v${status.current}`]);
|
|
252
262
|
return;
|
|
253
263
|
}
|
|
254
|
-
if (
|
|
255
|
-
console.log(
|
|
256
|
-
console.log(`[!] ${status.error}`);
|
|
264
|
+
if (opts.json) {
|
|
265
|
+
console.log(displaySafeJson(status, 2));
|
|
257
266
|
return;
|
|
258
267
|
}
|
|
259
268
|
if (status.updateAvailable && status.latest) {
|
|
260
269
|
console.log(`Update available: v${status.current} -> v${status.latest}`);
|
|
261
|
-
console.log(`Run
|
|
270
|
+
console.log(`Run \`token-goat upgrade\` to update.`);
|
|
262
271
|
} else {
|
|
263
272
|
console.log(`token-goat is up to date (v${status.current})`);
|
|
264
273
|
}
|
|
@@ -267,11 +276,11 @@ async function cmdUpgrade(opts = {}, onSyncHooks) {
|
|
|
267
276
|
const decision = currentUpgradeDecision(status);
|
|
268
277
|
switch (decision) {
|
|
269
278
|
case "offline":
|
|
270
|
-
console.error(
|
|
279
|
+
console.error(formatCommandError("network.offline is set, so no update check was made and nothing was installed. Unset it (or TOKEN_GOAT_OFFLINE) to upgrade."));
|
|
271
280
|
process.exitCode = 1;
|
|
272
281
|
return;
|
|
273
282
|
case "unreachable":
|
|
274
|
-
console.error(
|
|
283
|
+
console.error(formatCommandError(`${status.error ?? "could not determine the latest version"}. Nothing was installed.`));
|
|
275
284
|
process.exitCode = 1;
|
|
276
285
|
return;
|
|
277
286
|
case "up-to-date":
|
|
@@ -288,7 +297,7 @@ async function cmdUpgrade(opts = {}, onSyncHooks) {
|
|
|
288
297
|
console.log(`Upgrading token-goat v${status.current} -> v${status.latest}...`);
|
|
289
298
|
const outcome = await performUpgrade(onSyncHooks);
|
|
290
299
|
if (!outcome.ok) {
|
|
291
|
-
console.error(
|
|
300
|
+
console.error(formatCommandError(outcome.message));
|
|
292
301
|
process.exitCode = 1;
|
|
293
302
|
return;
|
|
294
303
|
}
|
|
@@ -296,35 +305,43 @@ async function cmdUpgrade(opts = {}, onSyncHooks) {
|
|
|
296
305
|
}
|
|
297
306
|
var MANUAL_INSTALL = "npm install -g token-goat@latest";
|
|
298
307
|
async function performUpgrade(onSyncHooks, npm = hostNpm()) {
|
|
299
|
-
if (!npm) return { ok: false, message: `npm was not found next to this Node.js, so token-goat could not upgrade itself. Run
|
|
308
|
+
if (!npm) return { ok: false, message: `npm was not found next to this Node.js, so token-goat could not upgrade itself. Run ${fencedCommand(MANUAL_INSTALL)} yourself.` };
|
|
309
|
+
let stoppedPid = [];
|
|
300
310
|
try {
|
|
301
|
-
const { stopWorker } = await import("./token-goat-chunk-
|
|
311
|
+
const { stopWorker, readPidFile } = await import("./token-goat-chunk-NSNSPPBG.mjs");
|
|
302
312
|
const { queryServers } = await import("./token-goat-hook-client.mjs");
|
|
303
313
|
await queryServers("stop");
|
|
304
|
-
|
|
314
|
+
const tracked = readPidFile(dataDir());
|
|
315
|
+
if (stopWorker() && tracked !== null) stoppedPid = [tracked];
|
|
316
|
+
} catch {
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const { retireStrayResidents, describeRetirement, UPGRADE_RESIDENT_KINDS } = await import("./token-goat-chunk-TAUZ4OFS.mjs");
|
|
320
|
+
const note = describeRetirement(await retireStrayResidents({ kinds: UPGRADE_RESIDENT_KINDS, skip: stoppedPid }));
|
|
321
|
+
if (note !== null) console.log(note);
|
|
305
322
|
} catch {
|
|
306
323
|
}
|
|
307
324
|
const install = spawnSync(npm.file, [...npm.prefix, "install", "-g", "token-goat@latest"], { stdio: "inherit", windowsHide: true });
|
|
308
325
|
if (install.status !== 0) {
|
|
309
326
|
const why = install.error ? install.error.message : `exit code ${install.status ?? "unknown"}`;
|
|
310
|
-
return { ok: false, message: `npm install failed (${why}). If npm reported EPERM or EBUSY, another program still has token-goat's files open: close running agent sessions and run
|
|
327
|
+
return { ok: false, message: `npm install failed (${why}). If npm reported EPERM or EBUSY, another program still has token-goat's files open: close running agent sessions and run ${fencedCommand(MANUAL_INSTALL)}.` };
|
|
311
328
|
}
|
|
312
329
|
console.log(`Syncing token-goat hooks and integration manifests...`);
|
|
313
330
|
const launcher = installedLauncher(npm);
|
|
314
331
|
if (launcher) {
|
|
315
332
|
const sync = spawnSync(process.execPath, [launcher, "install"], { stdio: "inherit", windowsHide: true });
|
|
316
|
-
if (sync.status !== 0) return { ok: false, message: `the new version installed, but
|
|
333
|
+
if (sync.status !== 0) return { ok: false, message: `the new version installed, but \`token-goat install\` failed (exit code ${sync.status ?? "unknown"}). Run \`token-goat install\` to finish.` };
|
|
317
334
|
return { ok: true };
|
|
318
335
|
}
|
|
319
336
|
try {
|
|
320
337
|
if (onSyncHooks) await onSyncHooks();
|
|
321
338
|
} catch (e) {
|
|
322
|
-
return { ok: false, message: `the new version installed, but syncing hooks failed (${e instanceof Error ? e.message : String(e)}). Run
|
|
339
|
+
return { ok: false, message: `the new version installed, but syncing hooks failed (${e instanceof Error ? e.message : String(e)}). Run \`token-goat install\` to finish.` };
|
|
323
340
|
}
|
|
324
341
|
return { ok: true };
|
|
325
342
|
}
|
|
326
343
|
function installedLauncher(npm) {
|
|
327
|
-
const res = spawnSync(npm.file, [...npm.prefix, "root", "-g"], { encoding: "utf8",
|
|
344
|
+
const res = spawnSync(npm.file, [...npm.prefix, "root", "-g"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
328
345
|
const root = res.status === 0 && typeof res.stdout === "string" ? res.stdout.trim() : "";
|
|
329
346
|
if (!root) return null;
|
|
330
347
|
const launcher = path.join(root, "token-goat", "dist", "token-goat.mjs");
|