token-goat 2.9.26 → 2.9.29
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 +30 -88
- package/SECURITY.md +14 -0
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-2AWQ2R5X.mjs} +2 -2
- package/dist/{token-goat-chunk-BH4ZVRB2.mjs → token-goat-chunk-2NNUA2LR.mjs} +4 -4
- package/dist/token-goat-chunk-2WOUYWLM.mjs +955 -0
- package/dist/{token-goat-chunk-IKZLSRII.mjs → token-goat-chunk-435UQTKD.mjs} +5 -3
- package/dist/{token-goat-chunk-62IHOU6L.mjs → token-goat-chunk-44BM7DDQ.mjs} +5 -3
- package/dist/token-goat-chunk-52NSDWYY.mjs +96 -0
- package/dist/{token-goat-chunk-CXBOFPF4.mjs → token-goat-chunk-67BNIKKO.mjs} +32 -18
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-6AK46ZT7.mjs} +2 -3
- package/dist/{token-goat-chunk-7SXPJOSZ.mjs → token-goat-chunk-7CPMDFGB.mjs} +166 -40
- package/dist/token-goat-chunk-ASLWOQ3I.mjs +14 -0
- package/dist/{token-goat-chunk-MWID3YOY.mjs → token-goat-chunk-BGYOZ6DO.mjs} +6 -4
- package/dist/{token-goat-chunk-PAV6NNY7.mjs → token-goat-chunk-C5YPNZKQ.mjs} +22 -8
- package/dist/{token-goat-chunk-D2X7XN5M.mjs → token-goat-chunk-CIQ2FTY3.mjs} +23 -242
- package/dist/token-goat-chunk-D4ETHJD6.mjs +246 -0
- package/dist/{token-goat-chunk-7Y6GWTII.mjs → token-goat-chunk-DNRPXHYH.mjs} +25 -17
- package/dist/{token-goat-chunk-L43RKNHA.mjs → token-goat-chunk-DNSPXQXQ.mjs} +2 -2
- package/dist/token-goat-chunk-DPNLUJWB.mjs +220 -0
- package/dist/token-goat-chunk-E4ZOJIZK.mjs +1382 -0
- package/dist/token-goat-chunk-E5TK5DNO.mjs +718 -0
- package/dist/{token-goat-chunk-VVROQBQJ.mjs → token-goat-chunk-EUSDXRXU.mjs} +62 -12
- package/dist/{token-goat-chunk-POOI26O6.mjs → token-goat-chunk-FTP4U4QA.mjs} +12 -8
- package/dist/token-goat-chunk-G23DWHV4.mjs +142 -0
- package/dist/{token-goat-chunk-MDV5VWF4.mjs → token-goat-chunk-G7IWXCFF.mjs} +223 -15
- package/dist/{token-goat-chunk-C2PG4K5D.mjs → token-goat-chunk-GLXRTTLE.mjs} +7 -5
- package/dist/{token-goat-chunk-M6CVNHTW.mjs → token-goat-chunk-H5J3C56Q.mjs} +95 -573
- package/dist/{token-goat-chunk-BAWKGODL.mjs → token-goat-chunk-HNFZZHFW.mjs} +2 -2
- package/dist/{token-goat-chunk-TG5ZPD6B.mjs → token-goat-chunk-HUYUHODZ.mjs} +1036 -759
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-ZZT6PVB3.mjs → token-goat-chunk-IVWI2OCK.mjs} +72 -45
- package/dist/{token-goat-chunk-GMOUBOX4.mjs → token-goat-chunk-JTKCQMQA.mjs} +37 -5
- package/dist/{token-goat-chunk-H2CPLEMP.mjs → token-goat-chunk-KOPIR3KZ.mjs} +46 -23
- package/dist/token-goat-chunk-L7H3U27L.mjs +35 -0
- package/dist/{token-goat-chunk-FLEYOCAS.mjs → token-goat-chunk-LZNBQTDK.mjs} +6 -4
- package/dist/token-goat-chunk-MELOKFDJ.mjs +199 -0
- package/dist/{token-goat-chunk-RH27ZSPF.mjs → token-goat-chunk-NMBWLRHW.mjs} +164 -50
- package/dist/{token-goat-chunk-43JFN26X.mjs → token-goat-chunk-O6I2XU4P.mjs} +27 -967
- package/dist/{token-goat-chunk-G6EYO5CD.mjs → token-goat-chunk-ONXH6NZ5.mjs} +2 -87
- package/dist/token-goat-chunk-ORNFMIER.mjs +295 -0
- package/dist/{token-goat-chunk-LHUP4DXZ.mjs → token-goat-chunk-PGTH2U4C.mjs} +1 -1
- package/dist/{token-goat-chunk-5BQ7W7D7.mjs → token-goat-chunk-PKRWMHVP.mjs} +76 -59
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-PQ53BSCF.mjs} +1 -1
- package/dist/{token-goat-chunk-STYRLQIW.mjs → token-goat-chunk-PYSUADX4.mjs} +2 -2
- package/dist/{token-goat-chunk-JALB3KWJ.mjs → token-goat-chunk-QO3LXVVR.mjs} +4247 -5005
- package/dist/{token-goat-chunk-L45IWWMC.mjs → token-goat-chunk-RLP6J7WR.mjs} +6 -6
- package/dist/token-goat-chunk-RQGGMPCR.mjs +205 -0
- package/dist/{token-goat-chunk-MBDJR6HU.mjs → token-goat-chunk-RTMVLHWX.mjs} +3708 -4003
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-S4VSXURL.mjs} +8 -6
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-SE6E4BKJ.mjs} +1 -1
- package/dist/token-goat-chunk-TCQANXYC.mjs +351 -0
- package/dist/token-goat-chunk-TDUT2CL6.mjs +564 -0
- package/dist/{token-goat-chunk-LRIZ7K3F.mjs → token-goat-chunk-TGOXNAHW.mjs} +54 -111
- package/dist/{token-goat-chunk-WNBSCSAI.mjs → token-goat-chunk-UA5BKWWQ.mjs} +1 -1
- package/dist/{token-goat-chunk-RIB6XY2V.mjs → token-goat-chunk-UXSXQQIY.mjs} +1 -1
- package/dist/{token-goat-chunk-7EPYB34H.mjs → token-goat-chunk-VMFWNHGR.mjs} +84 -73
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +36 -0
- package/dist/{token-goat-chunk-5M3NRJD2.mjs → token-goat-chunk-VZQEWRVH.mjs} +6 -4
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/{token-goat-chunk-6E2IDLHF.mjs → token-goat-chunk-XYWPOSCN.mjs} +57 -615
- package/dist/{token-goat-chunk-CQHY4SL7.mjs → token-goat-chunk-YAGLESS3.mjs} +8 -5
- package/dist/token-goat-chunk-YKSRAWUU.mjs +33 -0
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-YOOVFPTP.mjs} +2 -2
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +53 -0
- package/dist/{token-goat-chunk-4GEDH2WU.mjs → token-goat-chunk-ZER6EAXZ.mjs} +81 -70
- package/dist/token-goat-hook-client.cjs +475 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +31 -21
- package/dist/token-goat.core.mjs +9 -39
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +35 -23
- package/docs/install.md +18 -14
- package/package.json +1 -1
- package/dist/token-goat-chunk-ADMR3QVF.mjs +0 -41
- package/dist/token-goat-chunk-E6B2UFDF.mjs +0 -30
- package/dist/token-goat-chunk-GKZ2US5B.mjs +0 -187
- package/dist/token-goat-chunk-MZTO4FXH.mjs +0 -26
|
@@ -1,533 +1,27 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
foldPath,
|
|
5
|
+
isInsideRoot,
|
|
6
|
+
quotePowershellPath,
|
|
7
|
+
quoteShellPath,
|
|
8
|
+
sleepSync
|
|
9
|
+
} from "./token-goat-chunk-TCQANXYC.mjs";
|
|
10
|
+
import {
|
|
10
11
|
normalizePath
|
|
11
12
|
} from "./token-goat-chunk-NMTKNYGF.mjs";
|
|
13
|
+
import {
|
|
14
|
+
dataDir,
|
|
15
|
+
ensureStorageRootPrivate,
|
|
16
|
+
isTokenGoatStorage
|
|
17
|
+
} from "./token-goat-chunk-MELOKFDJ.mjs";
|
|
12
18
|
import {
|
|
13
19
|
compileGuardedRegex
|
|
14
|
-
} from "./token-goat-chunk-
|
|
20
|
+
} from "./token-goat-chunk-JTKCQMQA.mjs";
|
|
15
21
|
import {
|
|
16
22
|
init_define_import_meta_env
|
|
17
23
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
18
24
|
|
|
19
|
-
// src/version.ts
|
|
20
|
-
init_define_import_meta_env();
|
|
21
|
-
import { createRequire } from "node:module";
|
|
22
|
-
function resolveVersion() {
|
|
23
|
-
if (true) {
|
|
24
|
-
return "2.9.26";
|
|
25
|
-
}
|
|
26
|
-
const require2 = createRequire(import.meta.url);
|
|
27
|
-
const pkg = require2("../package.json");
|
|
28
|
-
return pkg.version ?? "0.0.0";
|
|
29
|
-
}
|
|
30
|
-
var VERSION = resolveVersion();
|
|
31
|
-
function resolvePackageName() {
|
|
32
|
-
try {
|
|
33
|
-
const require2 = createRequire(import.meta.url);
|
|
34
|
-
const pkg = require2("../package.json");
|
|
35
|
-
if (typeof pkg.name === "string" && pkg.name !== "") return pkg.name;
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
return "token-goat";
|
|
39
|
-
}
|
|
40
|
-
var PACKAGE_NAME = resolvePackageName();
|
|
41
|
-
function resolveIssuesUrl() {
|
|
42
|
-
try {
|
|
43
|
-
const require2 = createRequire(import.meta.url);
|
|
44
|
-
const pkg = require2("../package.json");
|
|
45
|
-
if (typeof pkg.bugs?.url === "string" && pkg.bugs.url !== "") return pkg.bugs.url;
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
return "https://github.com/DFKHelper/token-goat/issues";
|
|
49
|
-
}
|
|
50
|
-
var ISSUES_URL = resolveIssuesUrl();
|
|
51
|
-
var SUPPORT_EMAIL = "token-goat@dfkhelper.com";
|
|
52
|
-
function supportRequestLine(what) {
|
|
53
|
-
return `To ask for ${what} support, open an issue at ${ISSUES_URL} or email ${SUPPORT_EMAIL}.`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// src/constants.ts
|
|
57
|
-
init_define_import_meta_env();
|
|
58
|
-
import * as fs from "node:fs";
|
|
59
|
-
import * as os from "node:os";
|
|
60
|
-
import * as path from "node:path";
|
|
61
|
-
function safeEnvDir(value) {
|
|
62
|
-
const stripped = value.trim();
|
|
63
|
-
if (stripped === "") return void 0;
|
|
64
|
-
if (!path.isAbsolute(stripped)) return void 0;
|
|
65
|
-
if (process.platform === "win32") {
|
|
66
|
-
const root = path.parse(stripped).root;
|
|
67
|
-
if (root === "" || root === "\\" || root === "/") return void 0;
|
|
68
|
-
}
|
|
69
|
-
return stripped;
|
|
70
|
-
}
|
|
71
|
-
function dataDirForHome(homeDir) {
|
|
72
|
-
const platform = process.platform;
|
|
73
|
-
if (platform === "win32") {
|
|
74
|
-
return path.join(homeDir, "AppData", "Local", "dfk-helper", "token-goat");
|
|
75
|
-
}
|
|
76
|
-
if (platform === "darwin") {
|
|
77
|
-
return path.join(homeDir, "Library", "Application Support", "token-goat");
|
|
78
|
-
}
|
|
79
|
-
return path.join(homeDir, ".local", "share", "token-goat");
|
|
80
|
-
}
|
|
81
|
-
function homeFallbackOrGuard() {
|
|
82
|
-
const inVitest = process.env["VITEST_WORKER_ID"] !== void 0 || process.env["VITEST"] === "true";
|
|
83
|
-
if (inVitest && process.env["VITEST_ALLOW_REAL_DATA_DIR"] !== "1") {
|
|
84
|
-
throw new Error(
|
|
85
|
-
"token-goat: refusing to resolve DATA_DIR against the real home directory inside a Vitest worker (LOCALAPPDATA/XDG_DATA_HOME is unset). This would read or write the developer's real global.db/config.toml. Set LOCALAPPDATA/XDG_DATA_HOME explicitly for this process, or VITEST_ALLOW_REAL_DATA_DIR=1 if this is an intentional mocked-home test."
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
return dataDirForHome(os.homedir());
|
|
89
|
-
}
|
|
90
|
-
function defaultDataDir() {
|
|
91
|
-
const platform = process.platform;
|
|
92
|
-
if (platform === "win32") {
|
|
93
|
-
const raw = process.env["LOCALAPPDATA"] ?? "";
|
|
94
|
-
const base2 = raw ? safeEnvDir(raw) : void 0;
|
|
95
|
-
if (base2 !== void 0) {
|
|
96
|
-
return path.join(base2, "dfk-helper", "token-goat");
|
|
97
|
-
}
|
|
98
|
-
return homeFallbackOrGuard();
|
|
99
|
-
}
|
|
100
|
-
if (platform === "darwin") {
|
|
101
|
-
const raw = process.env["XDG_DATA_HOME"] ?? "";
|
|
102
|
-
const base2 = raw ? safeEnvDir(raw) : void 0;
|
|
103
|
-
if (base2 !== void 0) {
|
|
104
|
-
return path.join(base2, "token-goat");
|
|
105
|
-
}
|
|
106
|
-
return homeFallbackOrGuard();
|
|
107
|
-
}
|
|
108
|
-
const xdg = process.env["XDG_DATA_HOME"] ?? "";
|
|
109
|
-
const base = xdg ? safeEnvDir(xdg) : void 0;
|
|
110
|
-
if (base !== void 0) {
|
|
111
|
-
return path.join(base, "token-goat");
|
|
112
|
-
}
|
|
113
|
-
return homeFallbackOrGuard();
|
|
114
|
-
}
|
|
115
|
-
var DATA_DIR = defaultDataDir();
|
|
116
|
-
function dataDir() {
|
|
117
|
-
return DATA_DIR;
|
|
118
|
-
}
|
|
119
|
-
var dataDirHardened = false;
|
|
120
|
-
function ensureDataDirPrivate() {
|
|
121
|
-
if (dataDirHardened) return;
|
|
122
|
-
try {
|
|
123
|
-
fs.mkdirSync(path.dirname(DATA_DIR), { recursive: true });
|
|
124
|
-
fs.mkdirSync(DATA_DIR, { recursive: true, mode: 448 });
|
|
125
|
-
if (process.platform !== "win32") {
|
|
126
|
-
const current = fs.statSync(DATA_DIR).mode & 511;
|
|
127
|
-
if ((current & 63) !== 0) fs.chmodSync(DATA_DIR, 448);
|
|
128
|
-
}
|
|
129
|
-
dataDirHardened = true;
|
|
130
|
-
} catch {
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function tokenGoatHome() {
|
|
134
|
-
const override = safeEnvDir(process.env["TOKEN_GOAT_HOME"] ?? "");
|
|
135
|
-
if (override !== void 0) return override;
|
|
136
|
-
return path.join(os.homedir(), ".token-goat");
|
|
137
|
-
}
|
|
138
|
-
var hardenedHomes = /* @__PURE__ */ new Set();
|
|
139
|
-
function ensureHomeDirPrivate() {
|
|
140
|
-
const home = tokenGoatHome();
|
|
141
|
-
if (hardenedHomes.has(home)) return;
|
|
142
|
-
try {
|
|
143
|
-
fs.mkdirSync(path.dirname(home), { recursive: true });
|
|
144
|
-
fs.mkdirSync(home, { recursive: true, mode: 448 });
|
|
145
|
-
if (process.platform !== "win32") {
|
|
146
|
-
const current = fs.statSync(home).mode & 511;
|
|
147
|
-
if ((current & 63) !== 0) fs.chmodSync(home, 448);
|
|
148
|
-
}
|
|
149
|
-
hardenedHomes.add(home);
|
|
150
|
-
} catch {
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
function isUnderRoot(child, parent) {
|
|
154
|
-
const rel = path.relative(parent, child);
|
|
155
|
-
return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
156
|
-
}
|
|
157
|
-
function isTokenGoatStorage(p) {
|
|
158
|
-
return isUnderRoot(p, DATA_DIR) || isUnderRoot(p, tokenGoatHome());
|
|
159
|
-
}
|
|
160
|
-
function ensureStorageRootPrivate(dir) {
|
|
161
|
-
if (isUnderRoot(dir, DATA_DIR)) ensureDataDirPrivate();
|
|
162
|
-
if (isUnderRoot(dir, tokenGoatHome())) ensureHomeDirPrivate();
|
|
163
|
-
}
|
|
164
|
-
function globalDbPath() {
|
|
165
|
-
return path.join(DATA_DIR, "global.db");
|
|
166
|
-
}
|
|
167
|
-
function configPath() {
|
|
168
|
-
return path.join(DATA_DIR, "config.toml");
|
|
169
|
-
}
|
|
170
|
-
var PROJECT_CONFIG_FILENAME = ".token-goat.toml";
|
|
171
|
-
function projectConfigPath(projectRoot) {
|
|
172
|
-
return path.join(projectRoot, PROJECT_CONFIG_FILENAME);
|
|
173
|
-
}
|
|
174
|
-
var ENV_KEYS = {
|
|
175
|
-
COMPACT_ASSIST: "TOKEN_GOAT_COMPACT_ASSIST",
|
|
176
|
-
COMPACT_ASSIST_LEGACY: "TOKENWISE_COMPACT_ASSIST",
|
|
177
|
-
BASH_COMPRESS: "TOKEN_GOAT_BASH_COMPRESS",
|
|
178
|
-
SESSION_BRIEF: "TOKEN_GOAT_SESSION_BRIEF",
|
|
179
|
-
SKILL_PRESERVATION: "TOKEN_GOAT_SKILL_PRESERVATION",
|
|
180
|
-
ORPHAN_SWEEP: "TOKEN_GOAT_ORPHAN_SWEEP",
|
|
181
|
-
HINT_BUDGET: "TOKEN_GOAT_HINT_BUDGET",
|
|
182
|
-
HINT_JSON_SIDECAR: "TOKEN_GOAT_HINT_JSON_SIDECAR",
|
|
183
|
-
BASH_DEDUP_MIN_BYTES: "TOKEN_GOAT_BASH_DEDUP_MIN_BYTES",
|
|
184
|
-
WEB_DEDUP_MIN_BYTES: "TOKEN_GOAT_WEB_DEDUP_MIN_BYTES",
|
|
185
|
-
GREP_DEDUP_MIN_MATCHES: "TOKEN_GOAT_GREP_DEDUP_MIN_MATCHES",
|
|
186
|
-
GLOB_DEDUP_MIN_MATCHES: "TOKEN_GOAT_GLOB_DEDUP_MIN_MATCHES",
|
|
187
|
-
LARGE_READ_BYTES: "TOKEN_GOAT_LARGE_READ_BYTES",
|
|
188
|
-
REPOMAP_COMPACT_THRESHOLD: "TOKEN_GOAT_REPOMAP_COMPACT_THRESHOLD",
|
|
189
|
-
WEB_CACHE_MAX_FILES: "TOKEN_GOAT_WEB_CACHE_MAX_FILES",
|
|
190
|
-
WEB_CACHE_MAX_BYTES: "TOKEN_GOAT_WEB_CACHE_MAX_BYTES",
|
|
191
|
-
WEB_COMPRESS: "TOKEN_GOAT_WEB_COMPRESS",
|
|
192
|
-
BASH_CACHE_MIN_BYTES: "TOKEN_GOAT_BASH_CACHE_MIN_BYTES",
|
|
193
|
-
BASH_CACHE_MAX_FILES: "TOKEN_GOAT_BASH_CACHE_MAX_FILES",
|
|
194
|
-
BASH_CACHE_MAX_BYTES: "TOKEN_GOAT_BASH_CACHE_MAX_BYTES",
|
|
195
|
-
BASH_CACHE_MAX_BYTES_PER_OUTPUT: "TOKEN_GOAT_BASH_CACHE_MAX_BYTES_PER_OUTPUT",
|
|
196
|
-
WORKER_WATCHDOG: "TOKEN_GOAT_WORKER_WATCHDOG",
|
|
197
|
-
WORKER_MAX_POOL: "TOKEN_GOAT_WORKER_MAX_POOL",
|
|
198
|
-
COMPRESS_PROFILE: "TOKEN_GOAT_COMPRESS_PROFILE",
|
|
199
|
-
SKILL_COMPRESS: "TOKEN_GOAT_SKILL_COMPRESS",
|
|
200
|
-
SERVE_DIFF_ON_REREAD: "TOKEN_GOAT_SERVE_DIFF_ON_REREAD",
|
|
201
|
-
ELIDE_SERVED_LINES: "TOKEN_GOAT_ELIDE_SERVED_LINES",
|
|
202
|
-
OVERFLOW_GUARD: "TOKEN_GOAT_OVERFLOW_GUARD",
|
|
203
|
-
OVERFLOW_MAX_TOKENS: "TOKEN_GOAT_OVERFLOW_MAX_TOKENS",
|
|
204
|
-
HARNESS_OVERRIDE: "TOKEN_GOAT_HARNESS_OVERRIDE",
|
|
205
|
-
RECONCILE: "TOKEN_GOAT_RECONCILE",
|
|
206
|
-
RECONCILE_BUDGET_MS: "TOKEN_GOAT_RECONCILE_BUDGET_MS",
|
|
207
|
-
MCP_TOOLS: "TOKEN_GOAT_MCP_TOOLS"
|
|
208
|
-
};
|
|
209
|
-
var SYMBOL_BODY_CHAR_CAP = 128 * 1024;
|
|
210
|
-
var SKELETON_SYMBOL_CAP = 5e3;
|
|
211
|
-
|
|
212
|
-
// src/path_containment.ts
|
|
213
|
-
init_define_import_meta_env();
|
|
214
|
-
import * as fs2 from "node:fs";
|
|
215
|
-
import * as path2 from "node:path";
|
|
216
|
-
function isCaseInsensitiveFs() {
|
|
217
|
-
const o = process.env["TOKEN_GOAT_CASE_INSENSITIVE_FS"];
|
|
218
|
-
if (o === "1") return true;
|
|
219
|
-
if (o === "0") return false;
|
|
220
|
-
return process.platform === "win32" || process.platform === "darwin";
|
|
221
|
-
}
|
|
222
|
-
function foldPath(p) {
|
|
223
|
-
return isCaseInsensitiveFs() ? foldCase(p) : p;
|
|
224
|
-
}
|
|
225
|
-
function isNodeModulesPath(p) {
|
|
226
|
-
const check = foldPath(p);
|
|
227
|
-
return check.includes("/node_modules/") || check.includes("\\node_modules\\");
|
|
228
|
-
}
|
|
229
|
-
function foldCase(s) {
|
|
230
|
-
return s.toLowerCase();
|
|
231
|
-
}
|
|
232
|
-
function foldCaseForContainment(s) {
|
|
233
|
-
return s.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
234
|
-
}
|
|
235
|
-
function foldPathForContainment(p) {
|
|
236
|
-
return isCaseInsensitiveFs() ? foldCaseForContainment(p) : p;
|
|
237
|
-
}
|
|
238
|
-
var CYGWIN_PREFIX_RE = /^\/cygdrive\/([a-zA-Z])\/(.*)$/s;
|
|
239
|
-
function normalizeShellDrivePrefix(posixStr) {
|
|
240
|
-
let m = WSL_PATH_RE.exec(posixStr);
|
|
241
|
-
if (m) {
|
|
242
|
-
return `${m[1].toLowerCase()}:/${m[2]}`;
|
|
243
|
-
}
|
|
244
|
-
m = CYGWIN_PREFIX_RE.exec(posixStr);
|
|
245
|
-
if (m) {
|
|
246
|
-
return `${m[1].toLowerCase()}:/${m[2]}`;
|
|
247
|
-
}
|
|
248
|
-
m = MSYS_PATH_RE.exec(posixStr);
|
|
249
|
-
if (m) {
|
|
250
|
-
return `${m[1].toLowerCase()}:${m[2] ?? "/"}`;
|
|
251
|
-
}
|
|
252
|
-
return posixStr;
|
|
253
|
-
}
|
|
254
|
-
function canonicalize(inputPath, baseDir) {
|
|
255
|
-
const pathStr = typeof inputPath === "string" ? inputPath : inputPath.pathname;
|
|
256
|
-
const isWin32 = process.platform === "win32";
|
|
257
|
-
const base = baseDir ?? process.cwd();
|
|
258
|
-
const slashed = pathStr.replace(/\\/g, "/");
|
|
259
|
-
let pre = isWin32 ? normalizeShellDrivePrefix(slashed) : slashed;
|
|
260
|
-
if (pre !== slashed) {
|
|
261
|
-
pre = (isWin32 ? path2.win32.resolve : path2.resolve)(base, pre);
|
|
262
|
-
} else {
|
|
263
|
-
pre = (isWin32 ? path2.win32.resolve : path2.resolve)(base, pathStr);
|
|
264
|
-
}
|
|
265
|
-
let normalized = pre.replace(/\\/g, "/");
|
|
266
|
-
if (isWin32) {
|
|
267
|
-
normalized = normalizeShellDrivePrefix(normalized);
|
|
268
|
-
}
|
|
269
|
-
normalized = expandShortPath(normalized);
|
|
270
|
-
normalized = normalizeDarwinSystemAlias(normalized);
|
|
271
|
-
normalized = lowercaseDriveLetter(normalized);
|
|
272
|
-
return normalized;
|
|
273
|
-
}
|
|
274
|
-
var UNRESOLVABLE_PATH = "unresolvable-link-chain";
|
|
275
|
-
var MAX_LINK_HOPS = 40;
|
|
276
|
-
var MAX_RESOLVE_PATH_BYTES = 4096;
|
|
277
|
-
var MAX_WALK_SEGMENTS = MAX_RESOLVE_PATH_BYTES * (MAX_LINK_HOPS + 1);
|
|
278
|
-
function rootAndSegments(p) {
|
|
279
|
-
const parts = p.replace(/\\/g, "/").split("/");
|
|
280
|
-
const up = parts.indexOf("..");
|
|
281
|
-
const head = up === -1 ? parts.join("/") : parts.slice(0, up).join("/");
|
|
282
|
-
const canon = canonicalize(head === "" ? "." : head);
|
|
283
|
-
const m = /^(\/\/[^/]+\/[^/]+|[a-z]:\/|\/)/i.exec(canon);
|
|
284
|
-
const root = m === null ? "/" : m[1];
|
|
285
|
-
const rest = canon.slice(root.length).split("/");
|
|
286
|
-
return { root, segs: up === -1 ? rest : [...rest, ...parts.slice(up)] };
|
|
287
|
-
}
|
|
288
|
-
function joinSegment(base, seg) {
|
|
289
|
-
return base.endsWith("/") ? base + seg : `${base}/${seg}`;
|
|
290
|
-
}
|
|
291
|
-
function parentSegment(base, root) {
|
|
292
|
-
const cut = base.lastIndexOf("/");
|
|
293
|
-
return cut < root.length ? root : base.slice(0, cut);
|
|
294
|
-
}
|
|
295
|
-
var DRIVE_RELATIVE_PATH = /^[a-z]:(?![\\/])/i;
|
|
296
|
-
function linkTarget(link) {
|
|
297
|
-
const raw = link.replace(/\\/g, "/").replace(/^\/\/\?\/(UNC\/)?/i, (_m, unc) => unc === void 0 ? "" : "//");
|
|
298
|
-
if (!/^(\/\/[^/]+\/|[a-z]:\/|\/)/i.test(raw)) return { root: null, segs: raw.split("/") };
|
|
299
|
-
const abs = rootAndSegments(raw);
|
|
300
|
-
return { root: abs.root, segs: abs.segs };
|
|
301
|
-
}
|
|
302
|
-
function resolveThroughLinks(p) {
|
|
303
|
-
if (Buffer.byteLength(p, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
|
|
304
|
-
const start = rootAndSegments(p);
|
|
305
|
-
let root = start.root;
|
|
306
|
-
let base = root;
|
|
307
|
-
const stack = start.segs.slice().reverse();
|
|
308
|
-
let hops = 0;
|
|
309
|
-
let walked = 0;
|
|
310
|
-
while (stack.length > 0) {
|
|
311
|
-
if (++walked > MAX_WALK_SEGMENTS) return UNRESOLVABLE_PATH;
|
|
312
|
-
const seg = stack.pop();
|
|
313
|
-
if (seg === "" || seg === ".") continue;
|
|
314
|
-
if (seg === "..") {
|
|
315
|
-
base = parentSegment(base, root);
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
const candidate = joinSegment(base, seg);
|
|
319
|
-
if (Buffer.byteLength(candidate, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
|
|
320
|
-
let link = null;
|
|
321
|
-
try {
|
|
322
|
-
if (fs2.lstatSync(candidate).isSymbolicLink()) link = fs2.readlinkSync(candidate);
|
|
323
|
-
} catch (err) {
|
|
324
|
-
const code = err.code;
|
|
325
|
-
if (code !== "ENOENT" && code !== "ENOTDIR") return UNRESOLVABLE_PATH;
|
|
326
|
-
link = null;
|
|
327
|
-
}
|
|
328
|
-
if (link === null) {
|
|
329
|
-
base = candidate;
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (++hops > MAX_LINK_HOPS) return UNRESOLVABLE_PATH;
|
|
333
|
-
if (DRIVE_RELATIVE_PATH.test(link)) return UNRESOLVABLE_PATH;
|
|
334
|
-
const target = linkTarget(link);
|
|
335
|
-
if (target.root !== null) {
|
|
336
|
-
if (!isUncOrDevicePath(root) && isUncOrDevicePath(target.root)) return UNRESOLVABLE_PATH;
|
|
337
|
-
root = target.root;
|
|
338
|
-
base = target.root;
|
|
339
|
-
}
|
|
340
|
-
for (let i = target.segs.length - 1; i >= 0; i--) stack.push(target.segs[i]);
|
|
341
|
-
}
|
|
342
|
-
return base;
|
|
343
|
-
}
|
|
344
|
-
function normalizeForFs(p) {
|
|
345
|
-
return process.platform === "darwin" ? p.normalize("NFC") : p;
|
|
346
|
-
}
|
|
347
|
-
function escapesOntoNetworkThroughLinks(target, cwd) {
|
|
348
|
-
if (isUncOrDevicePath(target)) return true;
|
|
349
|
-
let absolute;
|
|
350
|
-
try {
|
|
351
|
-
absolute = path2.resolve(cwd ?? process.cwd(), target);
|
|
352
|
-
} catch {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
if (isUncOrDevicePath(absolute)) return true;
|
|
356
|
-
const resolved = resolveThroughLinks(absolute);
|
|
357
|
-
return resolved === UNRESOLVABLE_PATH || isUncOrDevicePath(resolved);
|
|
358
|
-
}
|
|
359
|
-
function isInsideRoot(target, root) {
|
|
360
|
-
if (reachesForeignShare(target, root)) return false;
|
|
361
|
-
const rt = resolveThroughLinks(target);
|
|
362
|
-
const rr = resolveThroughLinks(root);
|
|
363
|
-
if (rt === UNRESOLVABLE_PATH || rr === UNRESOLVABLE_PATH) return false;
|
|
364
|
-
const nt = normalizeForFs(rt);
|
|
365
|
-
const nr = normalizeForFs(rr);
|
|
366
|
-
const t = foldPathForContainment(nt);
|
|
367
|
-
const r = foldPathForContainment(nr);
|
|
368
|
-
if (t !== r && !t.startsWith(r.endsWith("/") ? r : r + "/")) return false;
|
|
369
|
-
if (nt.slice(0, nr.length) === nr) return true;
|
|
370
|
-
return sameDirectory(nt.slice(0, nr.length), nr);
|
|
371
|
-
}
|
|
372
|
-
function isNetworkPath(p, platform = process.platform) {
|
|
373
|
-
return networkShareRoot(p, platform) !== null;
|
|
374
|
-
}
|
|
375
|
-
function networkShareRoot(p, platform = process.platform) {
|
|
376
|
-
if (platform !== "win32") return null;
|
|
377
|
-
const device = /^[\\/]{2}([?.][\\/])?/.exec(p);
|
|
378
|
-
if (device === null) return null;
|
|
379
|
-
let rest = p.slice(device[0].length);
|
|
380
|
-
if (device[1] !== void 0) {
|
|
381
|
-
const unc = /^UNC[\\/]/i.exec(rest);
|
|
382
|
-
if (unc === null) return null;
|
|
383
|
-
rest = rest.slice(unc[0].length);
|
|
384
|
-
}
|
|
385
|
-
const [host = "", share = ""] = rest.split(/[\\/]/);
|
|
386
|
-
return `//${foldCase(host)}/${foldCase(share)}`;
|
|
387
|
-
}
|
|
388
|
-
function reachesForeignShare(target, root, platform = process.platform) {
|
|
389
|
-
const share = networkShareRoot(target, platform);
|
|
390
|
-
return share !== null && share !== networkShareRoot(root, platform);
|
|
391
|
-
}
|
|
392
|
-
function sameDirectory(a, b, platform = process.platform) {
|
|
393
|
-
if (isNetworkPath(a, platform) || isNetworkPath(b, platform)) return false;
|
|
394
|
-
let canonicalRoot;
|
|
395
|
-
try {
|
|
396
|
-
canonicalRoot = fs2.realpathSync.native(b);
|
|
397
|
-
} catch {
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
try {
|
|
401
|
-
return fs2.realpathSync.native(a) === canonicalRoot;
|
|
402
|
-
} catch {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// src/process_util.ts
|
|
408
|
-
init_define_import_meta_env();
|
|
409
|
-
import { existsSync, realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
410
|
-
import * as path3 from "node:path";
|
|
411
|
-
function sleepSync(ms) {
|
|
412
|
-
if (ms <= 0) return;
|
|
413
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
414
|
-
}
|
|
415
|
-
function isWindows() {
|
|
416
|
-
return process.platform === "win32";
|
|
417
|
-
}
|
|
418
|
-
function windowsCmdQuoteArg(arg) {
|
|
419
|
-
if (arg === "") return '""';
|
|
420
|
-
if (arg[0] === '"' && arg[arg.length - 1] === '"') {
|
|
421
|
-
throw new Error(`windowsCmdQuoteArg: cannot faithfully encode an argument that both starts and ends with a literal double quote for cmd.exe: ${JSON.stringify(arg)}`);
|
|
422
|
-
}
|
|
423
|
-
let out = "";
|
|
424
|
-
let inQuote = false;
|
|
425
|
-
let backslashes = 0;
|
|
426
|
-
const flushBackslashesPlain = () => {
|
|
427
|
-
if (backslashes > 0) {
|
|
428
|
-
out += "\\".repeat(backslashes);
|
|
429
|
-
backslashes = 0;
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
const flushBackslashesDoubled = () => {
|
|
433
|
-
out += "\\".repeat(backslashes * 2);
|
|
434
|
-
backslashes = 0;
|
|
435
|
-
};
|
|
436
|
-
const ensureQuoteOpen = () => {
|
|
437
|
-
if (!inQuote) {
|
|
438
|
-
flushBackslashesDoubled();
|
|
439
|
-
out += '"';
|
|
440
|
-
inQuote = true;
|
|
441
|
-
} else {
|
|
442
|
-
flushBackslashesPlain();
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
const ensureQuoteClosed = () => {
|
|
446
|
-
if (inQuote) {
|
|
447
|
-
flushBackslashesDoubled();
|
|
448
|
-
out += '"';
|
|
449
|
-
inQuote = false;
|
|
450
|
-
} else {
|
|
451
|
-
flushBackslashesPlain();
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
for (const ch of arg) {
|
|
455
|
-
if (ch === "\\") {
|
|
456
|
-
backslashes++;
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
if (ch === '"') {
|
|
460
|
-
flushBackslashesDoubled();
|
|
461
|
-
if (inQuote) {
|
|
462
|
-
out += '"';
|
|
463
|
-
inQuote = false;
|
|
464
|
-
}
|
|
465
|
-
out += '\\^"';
|
|
466
|
-
continue;
|
|
467
|
-
}
|
|
468
|
-
if (ch === "%" || ch === "!") {
|
|
469
|
-
ensureQuoteClosed();
|
|
470
|
-
out += `^${ch}`;
|
|
471
|
-
continue;
|
|
472
|
-
}
|
|
473
|
-
ensureQuoteOpen();
|
|
474
|
-
out += ch;
|
|
475
|
-
}
|
|
476
|
-
ensureQuoteClosed();
|
|
477
|
-
return out;
|
|
478
|
-
}
|
|
479
|
-
function quoteShellPath(value) {
|
|
480
|
-
if (process.platform === "win32") return `"${value}"`;
|
|
481
|
-
return `"${value.replace(/[\\$`"]/g, "\\$&")}"`;
|
|
482
|
-
}
|
|
483
|
-
function quotePowershellPath(value) {
|
|
484
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
485
|
-
}
|
|
486
|
-
function resolveOnPath(label) {
|
|
487
|
-
if (path3.isAbsolute(label)) return existsSync(label) ? label : null;
|
|
488
|
-
if (label.includes("/") || label.includes("\\")) return null;
|
|
489
|
-
const onWindows = process.platform === "win32";
|
|
490
|
-
const exts = onWindows ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter((e) => e.trim() !== "") : [""];
|
|
491
|
-
let cwd;
|
|
492
|
-
try {
|
|
493
|
-
cwd = realpathSync2(process.cwd());
|
|
494
|
-
} catch {
|
|
495
|
-
cwd = path3.resolve(process.cwd());
|
|
496
|
-
}
|
|
497
|
-
for (const rawDir of (process.env["PATH"] ?? "").split(path3.delimiter)) {
|
|
498
|
-
const dir = rawDir.trim().replace(/^"|"$/g, "");
|
|
499
|
-
if (dir === "" || dir === ".") continue;
|
|
500
|
-
let resolvedDir;
|
|
501
|
-
try {
|
|
502
|
-
resolvedDir = realpathSync2(path3.resolve(dir));
|
|
503
|
-
} catch {
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
if (foldPath(resolvedDir) === foldPath(cwd)) continue;
|
|
507
|
-
for (const ext of exts) {
|
|
508
|
-
const candidate = path3.join(resolvedDir, label + ext);
|
|
509
|
-
try {
|
|
510
|
-
if (statSync2(candidate).isFile()) return candidate;
|
|
511
|
-
} catch {
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return null;
|
|
516
|
-
}
|
|
517
|
-
function installEpipeGuard(streams) {
|
|
518
|
-
const targets = (streams ?? [process.stdout, process.stderr]).filter((s) => s !== void 0);
|
|
519
|
-
for (const stream of targets) {
|
|
520
|
-
stream.on("error", (err) => {
|
|
521
|
-
if (err.code === "EPIPE") {
|
|
522
|
-
process.exitCode = 0;
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
throw err;
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
return targets;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
25
|
// src/encoding.ts
|
|
532
26
|
init_define_import_meta_env();
|
|
533
27
|
function stripBom(text) {
|
|
@@ -602,26 +96,25 @@ function encodeUtf32(text, littleEndian) {
|
|
|
602
96
|
|
|
603
97
|
// src/util.ts
|
|
604
98
|
init_define_import_meta_env();
|
|
605
|
-
import {
|
|
606
|
-
import
|
|
607
|
-
import * as path7 from "node:path";
|
|
99
|
+
import { chmodSync, closeSync, constants as fsConstants, copyFileSync, existsSync as existsSync2, mkdirSync, openSync, readdirSync, readFileSync as readFileSync3, renameSync, rmdirSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
100
|
+
import * as path4 from "node:path";
|
|
608
101
|
|
|
609
102
|
// src/bridges/created_configs.ts
|
|
610
103
|
init_define_import_meta_env();
|
|
611
|
-
import * as
|
|
612
|
-
import * as
|
|
104
|
+
import * as fs from "fs";
|
|
105
|
+
import * as path from "path";
|
|
613
106
|
function ledgerPath() {
|
|
614
|
-
return
|
|
107
|
+
return path.join(dataDir(), "created-configs.json");
|
|
615
108
|
}
|
|
616
109
|
function keyOf(filePath) {
|
|
617
|
-
return normalizePath(
|
|
110
|
+
return normalizePath(path.resolve(filePath));
|
|
618
111
|
}
|
|
619
112
|
function foldKey(key) {
|
|
620
113
|
return foldPath(key);
|
|
621
114
|
}
|
|
622
115
|
function readLedger() {
|
|
623
116
|
try {
|
|
624
|
-
const parsed = JSON.parse(
|
|
117
|
+
const parsed = JSON.parse(fs.readFileSync(ledgerPath(), "utf8"));
|
|
625
118
|
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
626
119
|
} catch {
|
|
627
120
|
return [];
|
|
@@ -629,7 +122,7 @@ function readLedger() {
|
|
|
629
122
|
}
|
|
630
123
|
function writeLedger(entries) {
|
|
631
124
|
try {
|
|
632
|
-
ensureDirSync(
|
|
125
|
+
ensureDirSync(path.dirname(ledgerPath()));
|
|
633
126
|
atomicWriteText(ledgerPath(), `${JSON.stringify(entries)}
|
|
634
127
|
`);
|
|
635
128
|
} catch {
|
|
@@ -658,12 +151,12 @@ function recordCreatedBackup(backupPath) {
|
|
|
658
151
|
function forgetCreatedBackup(backupPath) {
|
|
659
152
|
takeCreatedConfig(backupPath);
|
|
660
153
|
}
|
|
661
|
-
function createdBackupsFor(
|
|
662
|
-
const prefix = foldKey(`${keyOf(
|
|
154
|
+
function createdBackupsFor(configPath) {
|
|
155
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
663
156
|
return readLedger().filter((entry) => foldKey(entry).startsWith(prefix)).sort();
|
|
664
157
|
}
|
|
665
|
-
function removeCreatedBackups(
|
|
666
|
-
const prefix = foldKey(`${keyOf(
|
|
158
|
+
function removeCreatedBackups(configPath) {
|
|
159
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
667
160
|
const entries = readLedger();
|
|
668
161
|
const ours = entries.filter((entry) => foldKey(entry).startsWith(prefix));
|
|
669
162
|
if (ours.length === 0) return 0;
|
|
@@ -671,7 +164,7 @@ function removeCreatedBackups(configPath2) {
|
|
|
671
164
|
let removed = 0;
|
|
672
165
|
for (const target of ours) {
|
|
673
166
|
try {
|
|
674
|
-
if (
|
|
167
|
+
if (fs.existsSync(target) && removeFileInScope(target)) {
|
|
675
168
|
removed++;
|
|
676
169
|
}
|
|
677
170
|
} catch {
|
|
@@ -684,7 +177,7 @@ function removeCreatedBackups(configPath2) {
|
|
|
684
177
|
|
|
685
178
|
// src/bridges/project_scope_guard.ts
|
|
686
179
|
init_define_import_meta_env();
|
|
687
|
-
import * as
|
|
180
|
+
import * as path2 from "node:path";
|
|
688
181
|
function assertProjectScopeTarget(target, projectRoot) {
|
|
689
182
|
if (projectRoot === void 0) return;
|
|
690
183
|
if (isInsideRoot(target, projectRoot)) return;
|
|
@@ -695,7 +188,7 @@ function assertProjectScopeTarget(target, projectRoot) {
|
|
|
695
188
|
var installProjectRoot;
|
|
696
189
|
function withInstallScope(projectRoot, fn) {
|
|
697
190
|
const previous = installProjectRoot;
|
|
698
|
-
installProjectRoot = projectRoot === void 0 ? void 0 :
|
|
191
|
+
installProjectRoot = projectRoot === void 0 ? void 0 : path2.resolve(projectRoot);
|
|
699
192
|
try {
|
|
700
193
|
const result = fn();
|
|
701
194
|
if (typeof result?.then === "function") {
|
|
@@ -711,7 +204,7 @@ function withInstallScope(projectRoot, fn) {
|
|
|
711
204
|
function projectScopeRoot(opts) {
|
|
712
205
|
if (opts === void 0) return void 0;
|
|
713
206
|
if (opts.project !== true && opts.local !== true) return void 0;
|
|
714
|
-
return
|
|
207
|
+
return path2.resolve(opts.projectRoot ?? process.cwd());
|
|
715
208
|
}
|
|
716
209
|
function assertWriteInScope(target) {
|
|
717
210
|
const root = installProjectRoot;
|
|
@@ -729,7 +222,7 @@ import { spawnSync } from "node:child_process";
|
|
|
729
222
|
// src/util_config.ts
|
|
730
223
|
init_define_import_meta_env();
|
|
731
224
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
732
|
-
import * as
|
|
225
|
+
import * as path3 from "node:path";
|
|
733
226
|
function stripOwnHooksFromMap(hooks, isOurs) {
|
|
734
227
|
let removed = false;
|
|
735
228
|
for (const eventKey of Object.keys(hooks)) {
|
|
@@ -816,7 +309,7 @@ function upsertDelimitedBlock(p, beginMarker, endMarker, block) {
|
|
|
816
309
|
const after = existing.slice(endIdx + endMarker.length);
|
|
817
310
|
const current = existing.slice(beginIdx, endIdx + endMarker.length);
|
|
818
311
|
if (current === block) return false;
|
|
819
|
-
ensureDirSync(
|
|
312
|
+
ensureDirSync(path3.dirname(p));
|
|
820
313
|
backupFile(p);
|
|
821
314
|
atomicWriteText(p, `${before}${block}${after}`);
|
|
822
315
|
return true;
|
|
@@ -827,13 +320,13 @@ function upsertDelimitedBlock(p, beginMarker, endMarker, block) {
|
|
|
827
320
|
${block}
|
|
828
321
|
` : `${block}
|
|
829
322
|
`;
|
|
830
|
-
ensureDirSync(
|
|
323
|
+
ensureDirSync(path3.dirname(p));
|
|
831
324
|
backupFile(p);
|
|
832
325
|
atomicWriteText(p, next);
|
|
833
326
|
return true;
|
|
834
327
|
}
|
|
835
328
|
function writeJsonSettings(p, settings) {
|
|
836
|
-
ensureDirSync(
|
|
329
|
+
ensureDirSync(path3.dirname(p));
|
|
837
330
|
backupFile(p);
|
|
838
331
|
atomicWriteText(p, `${JSON.stringify(settings, null, 2)}
|
|
839
332
|
`);
|
|
@@ -847,7 +340,7 @@ function writeIfDifferent(p, content, backup = false) {
|
|
|
847
340
|
}
|
|
848
341
|
if (existing === content) return false;
|
|
849
342
|
if (backup) backupFile(p);
|
|
850
|
-
ensureDirSync(
|
|
343
|
+
ensureDirSync(path3.dirname(p));
|
|
851
344
|
atomicWriteText(p, content);
|
|
852
345
|
return true;
|
|
853
346
|
}
|
|
@@ -881,7 +374,7 @@ function runGit(args, opts = {}) {
|
|
|
881
374
|
}
|
|
882
375
|
function statSize(absPath) {
|
|
883
376
|
try {
|
|
884
|
-
const st =
|
|
377
|
+
const st = statSync(absPath);
|
|
885
378
|
return st.isFile() ? st.size : null;
|
|
886
379
|
} catch {
|
|
887
380
|
return null;
|
|
@@ -901,7 +394,7 @@ function ensureDirSync(dir) {
|
|
|
901
394
|
assertWriteInScope(dir);
|
|
902
395
|
ensureStorageRootPrivate(dir);
|
|
903
396
|
try {
|
|
904
|
-
|
|
397
|
+
mkdirSync(dir, { recursive: true });
|
|
905
398
|
} catch (err) {
|
|
906
399
|
if (!isEExist(err)) {
|
|
907
400
|
throw err;
|
|
@@ -925,7 +418,7 @@ function withRetryOnLock(fn) {
|
|
|
925
418
|
function atomicWriteCore(dest, content) {
|
|
926
419
|
assertWriteInScope(dest);
|
|
927
420
|
const tmp = `${dest}.${process.pid}.${process.hrtime.bigint().toString()}.tmp`;
|
|
928
|
-
ensureDirSync(
|
|
421
|
+
ensureDirSync(path4.dirname(dest));
|
|
929
422
|
try {
|
|
930
423
|
const fd = openSync(tmp, "w", 384);
|
|
931
424
|
try {
|
|
@@ -938,8 +431,8 @@ function atomicWriteCore(dest, content) {
|
|
|
938
431
|
closeSync(fd);
|
|
939
432
|
}
|
|
940
433
|
try {
|
|
941
|
-
const destMode =
|
|
942
|
-
|
|
434
|
+
const destMode = statSync(dest).mode;
|
|
435
|
+
chmodSync(tmp, destMode);
|
|
943
436
|
} catch (e) {
|
|
944
437
|
if (e.code !== "ENOENT") throw e;
|
|
945
438
|
}
|
|
@@ -967,13 +460,13 @@ function installSingleFilePlugin(filePath, sidecarPath, template) {
|
|
|
967
460
|
}
|
|
968
461
|
const entryPath = process.argv[1];
|
|
969
462
|
if (entryPath) {
|
|
970
|
-
ensureDirSync(
|
|
463
|
+
ensureDirSync(path4.dirname(filePath));
|
|
971
464
|
atomicWriteText(sidecarPath, JSON.stringify({ entryPath }));
|
|
972
465
|
}
|
|
973
466
|
if (existing === template) {
|
|
974
467
|
return { filePath, alreadyInstalled: true };
|
|
975
468
|
}
|
|
976
|
-
ensureDirSync(
|
|
469
|
+
ensureDirSync(path4.dirname(filePath));
|
|
977
470
|
atomicWriteText(filePath, template);
|
|
978
471
|
return { filePath, alreadyInstalled: false };
|
|
979
472
|
}
|
|
@@ -1007,7 +500,7 @@ var MAX_BACKUPS_PER_FILE = 5;
|
|
|
1007
500
|
var MAX_BACKUP_NAME_ATTEMPTS = 16;
|
|
1008
501
|
function backupFile(p) {
|
|
1009
502
|
assertWriteInScope(p);
|
|
1010
|
-
if (!
|
|
503
|
+
if (!existsSync2(p)) return;
|
|
1011
504
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1012
505
|
let backupPath;
|
|
1013
506
|
for (let attempt = 0; ; attempt++) {
|
|
@@ -1047,33 +540,15 @@ function containsLineRun(haystack, needle) {
|
|
|
1047
540
|
var LOCK_WAIT_MS = 2e3;
|
|
1048
541
|
var LOCK_STALE_MS = 5e3;
|
|
1049
542
|
var LOCK_WAIT_MS_HARDENED = 15e3;
|
|
1050
|
-
var
|
|
1051
|
-
|
|
1052
|
-
const
|
|
1053
|
-
|
|
1054
|
-
function tick() {
|
|
1055
|
-
try {
|
|
1056
|
-
process.kill(ppid, 0)
|
|
1057
|
-
} catch {
|
|
1058
|
-
// Parent is gone (crashed, killed, ...): stop ticking so a genuinely dead holder's lock still goes stale and gets reclaimed. Windows ties this child's lifetime to its parent's Job Object automatically, but POSIX does not -- without this check, a plain spawn() child outlives a crashed parent as an orphan and would refresh the lock file forever, permanently wedging it. This is the actual enforcement mechanism on POSIX (this project's CI runs on ubuntu-latest); on Windows it is a harmless backstop.
|
|
1059
|
-
process.exit(0)
|
|
1060
|
-
}
|
|
543
|
+
var LOCK_LIVE_HOLDER_MAX_MS = 6e4;
|
|
544
|
+
function lockHolderAlive(token) {
|
|
545
|
+
const pid = Number(/^(\d+):/.exec(token)?.[1]);
|
|
546
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
1061
547
|
try {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
} catch {
|
|
1065
|
-
|
|
1066
|
-
setInterval(tick, Number(ms))
|
|
1067
|
-
`;
|
|
1068
|
-
function startHeartbeat(lockPath, token, staleMs) {
|
|
1069
|
-
const intervalMs = Math.max(20, Math.floor(staleMs / 3));
|
|
1070
|
-
try {
|
|
1071
|
-
return spawn(process.execPath, ["-e", HEARTBEAT_SCRIPT, lockPath, token, String(intervalMs)], {
|
|
1072
|
-
stdio: "ignore",
|
|
1073
|
-
windowsHide: true
|
|
1074
|
-
});
|
|
1075
|
-
} catch {
|
|
1076
|
-
return void 0;
|
|
548
|
+
process.kill(pid, 0);
|
|
549
|
+
return true;
|
|
550
|
+
} catch (err) {
|
|
551
|
+
return err.code === "EPERM";
|
|
1077
552
|
}
|
|
1078
553
|
}
|
|
1079
554
|
function withFileLock(lockPath, fn, opts = {}) {
|
|
@@ -1091,8 +566,8 @@ function withFileLock(lockPath, fn, opts = {}) {
|
|
|
1091
566
|
}
|
|
1092
567
|
let stale;
|
|
1093
568
|
try {
|
|
1094
|
-
const
|
|
1095
|
-
stale =
|
|
569
|
+
const age = Date.now() - statSync(lockPath).mtimeMs;
|
|
570
|
+
stale = age > staleMs && (age > Math.max(staleMs, LOCK_LIVE_HOLDER_MAX_MS) || !lockHolderAlive(readFileSync3(lockPath, "utf8")));
|
|
1096
571
|
} catch {
|
|
1097
572
|
stale = true;
|
|
1098
573
|
}
|
|
@@ -1106,14 +581,9 @@ function withFileLock(lockPath, fn, opts = {}) {
|
|
|
1106
581
|
if (Date.now() >= deadline) return void 0;
|
|
1107
582
|
sleepSync(Math.min(20 * ++attempt, 200));
|
|
1108
583
|
}
|
|
1109
|
-
const heartbeat = startHeartbeat(lockPath, token, staleMs);
|
|
1110
584
|
try {
|
|
1111
585
|
return fn();
|
|
1112
586
|
} finally {
|
|
1113
|
-
try {
|
|
1114
|
-
heartbeat?.kill();
|
|
1115
|
-
} catch {
|
|
1116
|
-
}
|
|
1117
587
|
try {
|
|
1118
588
|
if (readFileSync3(lockPath, "utf8") === token) unlinkSync(lockPath);
|
|
1119
589
|
} catch {
|
|
@@ -1173,9 +643,9 @@ function redactUrlQuery(raw) {
|
|
|
1173
643
|
}
|
|
1174
644
|
function withExtension(filePath, format) {
|
|
1175
645
|
const ext = format === "jpeg" ? ".jpg" : `.${format}`;
|
|
1176
|
-
const dir =
|
|
1177
|
-
const base =
|
|
1178
|
-
return
|
|
646
|
+
const dir = path4.dirname(filePath);
|
|
647
|
+
const base = path4.basename(filePath, path4.extname(filePath));
|
|
648
|
+
return path4.join(dir, `${base}${ext}`);
|
|
1179
649
|
}
|
|
1180
650
|
function ensureNewline(text) {
|
|
1181
651
|
return text.endsWith("\n") ? text : text + "\n";
|
|
@@ -1234,10 +704,10 @@ function isTestFile(p) {
|
|
|
1234
704
|
}
|
|
1235
705
|
function isUnderBlockedRoot(filePath, blockedRoots) {
|
|
1236
706
|
if (blockedRoots.length === 0) return false;
|
|
1237
|
-
const target = foldPath(normalizePath(
|
|
707
|
+
const target = foldPath(normalizePath(path4.resolve(filePath)));
|
|
1238
708
|
for (const root of blockedRoots) {
|
|
1239
709
|
if (!root) continue;
|
|
1240
|
-
const normRoot = foldPath(normalizePath(
|
|
710
|
+
const normRoot = foldPath(normalizePath(path4.resolve(root)));
|
|
1241
711
|
if (target === normRoot) return true;
|
|
1242
712
|
const boundary = normRoot.endsWith("/") ? normRoot : `${normRoot}/`;
|
|
1243
713
|
if (target.startsWith(boundary)) return true;
|
|
@@ -1271,32 +741,10 @@ function hookPowershellCommand(scriptPath, event) {
|
|
|
1271
741
|
}
|
|
1272
742
|
|
|
1273
743
|
export {
|
|
1274
|
-
VERSION,
|
|
1275
|
-
PACKAGE_NAME,
|
|
1276
|
-
supportRequestLine,
|
|
1277
|
-
dataDirForHome,
|
|
1278
|
-
dataDir,
|
|
1279
|
-
ensureDataDirPrivate,
|
|
1280
|
-
tokenGoatHome,
|
|
1281
|
-
globalDbPath,
|
|
1282
|
-
configPath,
|
|
1283
|
-
projectConfigPath,
|
|
1284
|
-
ENV_KEYS,
|
|
1285
|
-
SYMBOL_BODY_CHAR_CAP,
|
|
1286
|
-
SKELETON_SYMBOL_CAP,
|
|
1287
744
|
recordCreatedConfig,
|
|
1288
745
|
hasCreatedConfig,
|
|
1289
746
|
takeCreatedConfig,
|
|
1290
747
|
removeCreatedBackups,
|
|
1291
|
-
isCaseInsensitiveFs,
|
|
1292
|
-
foldPath,
|
|
1293
|
-
isNodeModulesPath,
|
|
1294
|
-
foldCase,
|
|
1295
|
-
foldCaseForContainment,
|
|
1296
|
-
foldPathForContainment,
|
|
1297
|
-
canonicalize,
|
|
1298
|
-
escapesOntoNetworkThroughLinks,
|
|
1299
|
-
isInsideRoot,
|
|
1300
748
|
assertProjectScopeTarget,
|
|
1301
749
|
withInstallScope,
|
|
1302
750
|
projectScopeRoot,
|
|
@@ -1308,12 +756,6 @@ export {
|
|
|
1308
756
|
upsertDelimitedBlock,
|
|
1309
757
|
writeJsonSettings,
|
|
1310
758
|
writeIfDifferent,
|
|
1311
|
-
sleepSync,
|
|
1312
|
-
isWindows,
|
|
1313
|
-
windowsCmdQuoteArg,
|
|
1314
|
-
quoteShellPath,
|
|
1315
|
-
resolveOnPath,
|
|
1316
|
-
installEpipeGuard,
|
|
1317
759
|
stripBom,
|
|
1318
760
|
detectSourceEncoding,
|
|
1319
761
|
decodeSource,
|