token-goat 2.9.13 → 2.9.15
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 +28 -1
- package/dist/token-goat-chunk-2X2EBBC6.mjs +277 -0
- package/dist/token-goat-chunk-3BTK54F3.mjs +1733 -0
- package/dist/token-goat-chunk-3NSDDTGL.mjs +34 -0
- package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
- package/dist/token-goat-chunk-5V7DAC7V.mjs +123 -0
- package/dist/token-goat-chunk-6DLVZDB6.mjs +34 -0
- package/dist/token-goat-chunk-7ZYK25AO.mjs +24 -0
- package/dist/token-goat-chunk-A4JYKD5H.mjs +144 -0
- package/dist/token-goat-chunk-AH6QILZM.mjs +26 -0
- package/dist/token-goat-chunk-ASYEPR3S.mjs +212 -0
- package/dist/{token-goat-chunk-RDITECDL.mjs → token-goat-chunk-ATIFTMRC.mjs} +31 -13
- package/dist/{token-goat-chunk-ZZI3IDQZ.mjs → token-goat-chunk-BL5LNGBG.mjs} +3935 -11949
- package/dist/{token-goat-chunk-4NXUKV7D.mjs → token-goat-chunk-C5JIO6HK.mjs} +8 -4
- package/dist/{token-goat-chunk-FZU7GMUS.mjs → token-goat-chunk-DQ4J5AFF.mjs} +50 -18
- package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
- package/dist/{token-goat-chunk-6B44WLIF.mjs → token-goat-chunk-GIIHUSZX.mjs} +142 -21
- package/dist/token-goat-chunk-GMOUBOX4.mjs +386 -0
- package/dist/{token-goat-chunk-3ESRORNM.mjs → token-goat-chunk-GMQQA7E4.mjs} +12576 -12326
- package/dist/token-goat-chunk-IVUQLQWN.mjs +2046 -0
- package/dist/token-goat-chunk-K7F2BFIK.mjs +2430 -0
- package/dist/{token-goat-chunk-U7X6LQD2.mjs → token-goat-chunk-LCZBPOIN.mjs} +10197 -9717
- package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
- package/dist/token-goat-chunk-LT7JRU6K.mjs +22 -0
- package/dist/token-goat-chunk-MZDIJJ3R.mjs +420 -0
- package/dist/token-goat-chunk-NDPO7GAH.mjs +177 -0
- package/dist/token-goat-chunk-NDRP4KJQ.mjs +4371 -0
- package/dist/token-goat-chunk-NEI4NC54.mjs +424 -0
- package/dist/token-goat-chunk-NU7TLMQK.mjs +585 -0
- package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
- package/dist/token-goat-chunk-OUGNPMDA.mjs +959 -0
- package/dist/token-goat-chunk-PM76YS22.mjs +1341 -0
- package/dist/token-goat-chunk-S4XRY446.mjs +2637 -0
- package/dist/{token-goat-chunk-YOA4N6WA.mjs → token-goat-chunk-SFAS46RE.mjs} +5 -3
- package/dist/{token-goat-chunk-QWSUZWFP.mjs → token-goat-chunk-SZWYESBS.mjs} +793 -650
- package/dist/{token-goat-chunk-B3CTCQTH.mjs → token-goat-chunk-XEPXYDPI.mjs} +3 -2
- package/dist/token-goat-chunk-XTQAOTSO.mjs +89 -0
- package/dist/token-goat-chunk-Y4AFKTHK.mjs +22 -0
- package/dist/token-goat-chunk-YKG35VHC.mjs +228 -0
- package/dist/{token-goat-chunk-JOXLE672.mjs → token-goat-chunk-YQ7WI2CO.mjs} +990 -106
- package/dist/{token-goat-chunk-2WC4ZUXN.mjs → token-goat-chunk-YZX7EFG4.mjs} +1 -1
- package/dist/token-goat-chunk-Z6UXPYJA.mjs +62 -0
- package/dist/token-goat-hook.mjs +16 -8
- package/dist/token-goat.core.mjs +27 -10
- package/docs/cli.md +9 -6
- package/package.json +4 -2
- package/dist/token-goat-chunk-FQCNJV4V.mjs +0 -693
- package/dist/token-goat-chunk-JVNPCQB7.mjs +0 -31
- package/dist/token-goat-chunk-P2PU4CR5.mjs +0 -26
- package/dist/token-goat-chunk-QKXBGBQR.mjs +0 -3653
- package/dist/token-goat-chunk-UM47DRD3.mjs +0 -242
- package/dist/token-goat-chunk-UMXJN7DI.mjs +0 -5521
|
@@ -0,0 +1,2637 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
registerReset
|
|
5
|
+
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
6
|
+
import {
|
|
7
|
+
ENV_KEYS,
|
|
8
|
+
atomicWriteText,
|
|
9
|
+
canonicalize,
|
|
10
|
+
configPath,
|
|
11
|
+
decodeSource,
|
|
12
|
+
extractErrorMessage,
|
|
13
|
+
foldPath,
|
|
14
|
+
projectConfigPath,
|
|
15
|
+
runGit
|
|
16
|
+
} from "./token-goat-chunk-PM76YS22.mjs";
|
|
17
|
+
import {
|
|
18
|
+
normalizeDarwinSystemAlias
|
|
19
|
+
} from "./token-goat-chunk-ERTXEKB6.mjs";
|
|
20
|
+
import {
|
|
21
|
+
init_define_import_meta_env
|
|
22
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
23
|
+
|
|
24
|
+
// src/bridges/registry.ts
|
|
25
|
+
init_define_import_meta_env();
|
|
26
|
+
var KNOWN_HARNESS_NAMES = /* @__PURE__ */ new Set([
|
|
27
|
+
"claudecode",
|
|
28
|
+
"codex",
|
|
29
|
+
"opencode",
|
|
30
|
+
"gemini",
|
|
31
|
+
"hermes",
|
|
32
|
+
"openclaw",
|
|
33
|
+
"pi",
|
|
34
|
+
"copilot_cli",
|
|
35
|
+
"grok",
|
|
36
|
+
"qwen",
|
|
37
|
+
"kimi",
|
|
38
|
+
"vscode",
|
|
39
|
+
"visualstudio",
|
|
40
|
+
"generic"
|
|
41
|
+
]);
|
|
42
|
+
function detectHarness() {
|
|
43
|
+
const env = process.env;
|
|
44
|
+
const override = (env[ENV_KEYS.HARNESS_OVERRIDE] ?? "").toLowerCase().trim();
|
|
45
|
+
if (override && KNOWN_HARNESS_NAMES.has(override)) {
|
|
46
|
+
return override;
|
|
47
|
+
}
|
|
48
|
+
if (env["HERMES_SESSION_ID"] || env["HERMES_HOME"]) {
|
|
49
|
+
return "hermes";
|
|
50
|
+
}
|
|
51
|
+
if (env["TERM_PROGRAM"] === "claude-code" || env["CLAUDE_CODE_VERSION"] !== void 0 || env["CLAUDE_CODE_SESSION_ID"]) {
|
|
52
|
+
return "claudecode";
|
|
53
|
+
}
|
|
54
|
+
if (env["CODEX_SESSION_ID"] !== void 0 || env["CODEX_SESSION"]) {
|
|
55
|
+
return "codex";
|
|
56
|
+
}
|
|
57
|
+
if (env["OPENCODE_SESSION_ID"] !== void 0 || env["OPENCODE_SESSION"]) {
|
|
58
|
+
return "opencode";
|
|
59
|
+
}
|
|
60
|
+
if (env["GROK_SESSION_ID"] !== void 0) {
|
|
61
|
+
return "grok";
|
|
62
|
+
}
|
|
63
|
+
if (env["OPENCLAW_SESSION_ID"] !== void 0) {
|
|
64
|
+
return "openclaw";
|
|
65
|
+
}
|
|
66
|
+
if (env["ANTHROPIC_API_KEY"]) {
|
|
67
|
+
return "claudecode";
|
|
68
|
+
}
|
|
69
|
+
if (env["OPENAI_API_KEY"] && !env["ANTHROPIC_API_KEY"]) {
|
|
70
|
+
return "codex";
|
|
71
|
+
}
|
|
72
|
+
if ((env["GEMINI_API_KEY"] || env["GOOGLE_API_KEY"]) && !env["ANTHROPIC_API_KEY"]) {
|
|
73
|
+
return "gemini";
|
|
74
|
+
}
|
|
75
|
+
return "generic";
|
|
76
|
+
}
|
|
77
|
+
var _cached = null;
|
|
78
|
+
function getHarnessName() {
|
|
79
|
+
if (_cached === null) {
|
|
80
|
+
_cached = detectHarness();
|
|
81
|
+
}
|
|
82
|
+
return _cached;
|
|
83
|
+
}
|
|
84
|
+
function resetHarnessCache() {
|
|
85
|
+
_cached = null;
|
|
86
|
+
}
|
|
87
|
+
registerReset(resetHarnessCache);
|
|
88
|
+
|
|
89
|
+
// src/env.ts
|
|
90
|
+
init_define_import_meta_env();
|
|
91
|
+
var FALSY_ENV_VALUES = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
|
|
92
|
+
var TRUTHY_ENV_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
93
|
+
function envStr(key, defaultVal) {
|
|
94
|
+
const raw = process.env[key];
|
|
95
|
+
if (raw === void 0) return defaultVal;
|
|
96
|
+
const trimmed = raw.trim();
|
|
97
|
+
return trimmed === "" ? defaultVal : trimmed;
|
|
98
|
+
}
|
|
99
|
+
function envBool(key, defaultVal) {
|
|
100
|
+
const raw = process.env[key];
|
|
101
|
+
if (raw === void 0) return defaultVal;
|
|
102
|
+
const norm = raw.trim().toLowerCase();
|
|
103
|
+
if (norm === "") return defaultVal;
|
|
104
|
+
if (TRUTHY_ENV_VALUES.has(norm)) return true;
|
|
105
|
+
if (FALSY_ENV_VALUES.has(norm)) return false;
|
|
106
|
+
return defaultVal;
|
|
107
|
+
}
|
|
108
|
+
function envInt(key, defaultVal, min, max) {
|
|
109
|
+
const raw = process.env[key];
|
|
110
|
+
if (raw === void 0) return defaultVal;
|
|
111
|
+
const norm = raw.trim();
|
|
112
|
+
if (norm === "") return defaultVal;
|
|
113
|
+
if (!/^[+-]?\d+$/.test(norm)) return defaultVal;
|
|
114
|
+
const val = parseInt(norm, 10);
|
|
115
|
+
if (!Number.isFinite(val)) return defaultVal;
|
|
116
|
+
let clamped = val;
|
|
117
|
+
if (min !== void 0) clamped = Math.max(min, clamped);
|
|
118
|
+
if (max !== void 0) clamped = Math.min(max, clamped);
|
|
119
|
+
return clamped;
|
|
120
|
+
}
|
|
121
|
+
function envStrList(key, defaultVal, delimiter2) {
|
|
122
|
+
const raw = process.env[key];
|
|
123
|
+
if (raw === void 0) return defaultVal;
|
|
124
|
+
const entries = raw.split(delimiter2).map((s) => s.trim()).filter((s) => s !== "");
|
|
125
|
+
return entries.length > 0 ? entries : defaultVal;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/fingerprint.ts
|
|
129
|
+
init_define_import_meta_env();
|
|
130
|
+
import { createHash } from "node:crypto";
|
|
131
|
+
import * as fs from "node:fs";
|
|
132
|
+
function fingerprintContent(content) {
|
|
133
|
+
const hash = createHash("sha256");
|
|
134
|
+
hash.update(typeof content === "string" ? Buffer.from(content, "utf-8") : content);
|
|
135
|
+
return hash.digest("hex");
|
|
136
|
+
}
|
|
137
|
+
function shortFingerprint(content) {
|
|
138
|
+
return fingerprintContent(content).slice(0, 16);
|
|
139
|
+
}
|
|
140
|
+
function fingerprintFile(filePath) {
|
|
141
|
+
let data;
|
|
142
|
+
try {
|
|
143
|
+
data = fs.readFileSync(filePath);
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return fingerprintContent(data);
|
|
148
|
+
}
|
|
149
|
+
function fileIsAbsent(filePath) {
|
|
150
|
+
try {
|
|
151
|
+
return fs.statSync(filePath, { throwIfNoEntry: false }) === void 0;
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/ocr_languages.ts
|
|
158
|
+
init_define_import_meta_env();
|
|
159
|
+
var DEFAULT_OCR_LANG = "eng";
|
|
160
|
+
var SUPPORTED_OCR_LANG_CODES = [
|
|
161
|
+
"eng",
|
|
162
|
+
"fra",
|
|
163
|
+
"spa",
|
|
164
|
+
"deu",
|
|
165
|
+
"ita",
|
|
166
|
+
"por",
|
|
167
|
+
"nld",
|
|
168
|
+
"pol",
|
|
169
|
+
"rus",
|
|
170
|
+
"tur",
|
|
171
|
+
"swe",
|
|
172
|
+
"ara",
|
|
173
|
+
"chi_sim",
|
|
174
|
+
"chi_tra",
|
|
175
|
+
"jpn",
|
|
176
|
+
"kor"
|
|
177
|
+
];
|
|
178
|
+
var SUPPORTED_SET = new Set(SUPPORTED_OCR_LANG_CODES);
|
|
179
|
+
function isSupportedOcrLang(lang) {
|
|
180
|
+
return SUPPORTED_SET.has(lang);
|
|
181
|
+
}
|
|
182
|
+
function resolveOcrLangs(input) {
|
|
183
|
+
const result = [DEFAULT_OCR_LANG];
|
|
184
|
+
if (!input) return result;
|
|
185
|
+
const tokens = input.split(/[+,;\s]+/).map((s) => s.trim().toLowerCase());
|
|
186
|
+
for (const token of tokens) {
|
|
187
|
+
if (token && isSupportedOcrLang(token) && !result.includes(token)) {
|
|
188
|
+
result.push(token);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/project.ts
|
|
195
|
+
init_define_import_meta_env();
|
|
196
|
+
import * as fs2 from "node:fs";
|
|
197
|
+
import * as os from "node:os";
|
|
198
|
+
import * as path from "node:path";
|
|
199
|
+
var PROJECT_MARKERS = [
|
|
200
|
+
".git",
|
|
201
|
+
"package.json",
|
|
202
|
+
"pyproject.toml",
|
|
203
|
+
"Cargo.toml",
|
|
204
|
+
"go.mod",
|
|
205
|
+
"shopify.app.toml",
|
|
206
|
+
"_config.yml",
|
|
207
|
+
"deno.json",
|
|
208
|
+
"deno.jsonc"
|
|
209
|
+
];
|
|
210
|
+
var REPO_CONTAINER_THRESHOLD = 3;
|
|
211
|
+
function projectHash(canonicalRoot) {
|
|
212
|
+
return shortFingerprint(foldPath(canonicalRoot));
|
|
213
|
+
}
|
|
214
|
+
function makeProjectAt(root) {
|
|
215
|
+
let canonical;
|
|
216
|
+
try {
|
|
217
|
+
canonical = canonicalize(root);
|
|
218
|
+
} catch (exc) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
`makeProjectAt: could not resolve path: ${extractErrorMessage(exc)}`,
|
|
221
|
+
{ cause: exc }
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
const stat = fs2.statSync(canonical);
|
|
226
|
+
if (!stat.isDirectory()) {
|
|
227
|
+
throw new Error(`makeProjectAt: path is not a directory: ${canonical}`);
|
|
228
|
+
}
|
|
229
|
+
} catch (exc) {
|
|
230
|
+
if (exc instanceof Error && exc.message.includes("ENOENT")) {
|
|
231
|
+
throw new Error(`makeProjectAt: path does not exist: ${canonical}`, { cause: exc });
|
|
232
|
+
}
|
|
233
|
+
throw exc;
|
|
234
|
+
}
|
|
235
|
+
const hash = projectHash(canonical);
|
|
236
|
+
return { root: canonical, hash, marker: "manual" };
|
|
237
|
+
}
|
|
238
|
+
function isRepoContainer(pathStr) {
|
|
239
|
+
let nestedRepos = 0;
|
|
240
|
+
try {
|
|
241
|
+
const entries = fs2.readdirSync(pathStr, { withFileTypes: true });
|
|
242
|
+
for (const entry of entries) {
|
|
243
|
+
if (entry.isDirectory()) {
|
|
244
|
+
const gitPath = path.join(pathStr, entry.name, ".git");
|
|
245
|
+
if (fs2.existsSync(gitPath)) {
|
|
246
|
+
let isGitDir = false;
|
|
247
|
+
try {
|
|
248
|
+
isGitDir = fs2.statSync(gitPath).isDirectory();
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
if (isGitDir) {
|
|
252
|
+
nestedRepos++;
|
|
253
|
+
if (nestedRepos >= REPO_CONTAINER_THRESHOLD) {
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} catch {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
function markerExists(current, marker) {
|
|
266
|
+
const markerPath = path.join(current, marker);
|
|
267
|
+
try {
|
|
268
|
+
if (!fs2.existsSync(markerPath)) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
const stat = fs2.lstatSync(markerPath);
|
|
272
|
+
if (!stat.isSymbolicLink()) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
const resolved = fs2.realpathSync(markerPath);
|
|
276
|
+
const rel = path.relative(path.resolve(current), path.resolve(resolved));
|
|
277
|
+
return !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
278
|
+
} catch {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function findProject(cwd) {
|
|
283
|
+
let p;
|
|
284
|
+
try {
|
|
285
|
+
p = canonicalize(cwd);
|
|
286
|
+
} catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
let sysTemp = null;
|
|
290
|
+
try {
|
|
291
|
+
sysTemp = canonicalize(os.tmpdir());
|
|
292
|
+
} catch {
|
|
293
|
+
}
|
|
294
|
+
let current = p;
|
|
295
|
+
while (true) {
|
|
296
|
+
if (sysTemp && normalizeDarwinSystemAlias(foldPath(current)) === normalizeDarwinSystemAlias(foldPath(sysTemp))) {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
for (const marker of PROJECT_MARKERS) {
|
|
300
|
+
if (markerExists(current, marker)) {
|
|
301
|
+
if (!isRepoContainer(current)) {
|
|
302
|
+
return {
|
|
303
|
+
root: current,
|
|
304
|
+
hash: projectHash(current),
|
|
305
|
+
marker
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const parent = path.dirname(current);
|
|
312
|
+
if (parent === current) {
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
current = parent;
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
var _displayRootCache = null;
|
|
320
|
+
function getDisplayRoot(explicitRoot) {
|
|
321
|
+
if (explicitRoot !== void 0) return explicitRoot;
|
|
322
|
+
const cwd = process.cwd();
|
|
323
|
+
if (_displayRootCache !== null && _displayRootCache.cwd === cwd) return _displayRootCache.root;
|
|
324
|
+
const project = findProject(cwd);
|
|
325
|
+
const root = project !== null ? project.root : void 0;
|
|
326
|
+
_displayRootCache = { cwd, root };
|
|
327
|
+
return root;
|
|
328
|
+
}
|
|
329
|
+
registerReset(() => {
|
|
330
|
+
_displayRootCache = null;
|
|
331
|
+
});
|
|
332
|
+
function isUnderSystemTemp(filePath) {
|
|
333
|
+
let sysTemp;
|
|
334
|
+
try {
|
|
335
|
+
sysTemp = canonicalize(os.tmpdir());
|
|
336
|
+
} catch {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
let target;
|
|
340
|
+
try {
|
|
341
|
+
target = canonicalize(filePath);
|
|
342
|
+
} catch {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
const foldedTemp = normalizeDarwinSystemAlias(foldPath(sysTemp));
|
|
346
|
+
const foldedTarget = normalizeDarwinSystemAlias(foldPath(target));
|
|
347
|
+
return foldedTarget === foldedTemp || foldedTarget.startsWith(`${foldedTemp}/`);
|
|
348
|
+
}
|
|
349
|
+
function resolveProjectRoot(opts) {
|
|
350
|
+
const base = opts?.project !== void 0 ? path.resolve(opts.project) : process.cwd();
|
|
351
|
+
const toplevel = runGit(["rev-parse", "--show-toplevel"], { cwd: base });
|
|
352
|
+
if (toplevel.exitCode === 0) {
|
|
353
|
+
const trimmed = toplevel.stdout.trim();
|
|
354
|
+
if (trimmed.length > 0) return canonicalize(trimmed);
|
|
355
|
+
}
|
|
356
|
+
const project = findProject(base);
|
|
357
|
+
if (project !== null) return project.root;
|
|
358
|
+
return canonicalize(base);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// src/config_project.ts
|
|
362
|
+
init_define_import_meta_env();
|
|
363
|
+
import * as fs3 from "node:fs";
|
|
364
|
+
|
|
365
|
+
// node_modules/smol-toml/dist/index.js
|
|
366
|
+
init_define_import_meta_env();
|
|
367
|
+
|
|
368
|
+
// node_modules/smol-toml/dist/parse.js
|
|
369
|
+
init_define_import_meta_env();
|
|
370
|
+
|
|
371
|
+
// node_modules/smol-toml/dist/struct.js
|
|
372
|
+
init_define_import_meta_env();
|
|
373
|
+
|
|
374
|
+
// node_modules/smol-toml/dist/primitive.js
|
|
375
|
+
init_define_import_meta_env();
|
|
376
|
+
|
|
377
|
+
// node_modules/smol-toml/dist/date.js
|
|
378
|
+
init_define_import_meta_env();
|
|
379
|
+
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
380
|
+
var TomlDate = class _TomlDate extends Date {
|
|
381
|
+
#hasDate = false;
|
|
382
|
+
#hasTime = false;
|
|
383
|
+
#offset = null;
|
|
384
|
+
constructor(date) {
|
|
385
|
+
let hasDate = true;
|
|
386
|
+
let hasTime = true;
|
|
387
|
+
let offset = "Z";
|
|
388
|
+
if (typeof date === "string") {
|
|
389
|
+
let match = date.match(DATE_TIME_RE);
|
|
390
|
+
if (match) {
|
|
391
|
+
if (!match[1]) {
|
|
392
|
+
hasDate = false;
|
|
393
|
+
date = `0000-01-01T${date}`;
|
|
394
|
+
}
|
|
395
|
+
hasTime = !!match[2];
|
|
396
|
+
hasTime && date[10] === " " && (date = date.replace(" ", "T"));
|
|
397
|
+
if (match[2] && +match[2] > 23) {
|
|
398
|
+
date = "";
|
|
399
|
+
} else {
|
|
400
|
+
offset = match[3] || null;
|
|
401
|
+
date = date.toUpperCase();
|
|
402
|
+
if (!offset && hasTime)
|
|
403
|
+
date += "Z";
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
date = "";
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
super(date);
|
|
410
|
+
if (!isNaN(this.getTime())) {
|
|
411
|
+
this.#hasDate = hasDate;
|
|
412
|
+
this.#hasTime = hasTime;
|
|
413
|
+
this.#offset = offset;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
isDateTime() {
|
|
417
|
+
return this.#hasDate && this.#hasTime;
|
|
418
|
+
}
|
|
419
|
+
isLocal() {
|
|
420
|
+
return !this.#hasDate || !this.#hasTime || !this.#offset;
|
|
421
|
+
}
|
|
422
|
+
isDate() {
|
|
423
|
+
return this.#hasDate && !this.#hasTime;
|
|
424
|
+
}
|
|
425
|
+
isTime() {
|
|
426
|
+
return this.#hasTime && !this.#hasDate;
|
|
427
|
+
}
|
|
428
|
+
isValid() {
|
|
429
|
+
return this.#hasDate || this.#hasTime;
|
|
430
|
+
}
|
|
431
|
+
toISOString() {
|
|
432
|
+
let iso = super.toISOString();
|
|
433
|
+
if (this.isDate())
|
|
434
|
+
return iso.slice(0, 10);
|
|
435
|
+
if (this.isTime())
|
|
436
|
+
return iso.slice(11, 23);
|
|
437
|
+
if (this.#offset === null)
|
|
438
|
+
return iso.slice(0, -1);
|
|
439
|
+
if (this.#offset === "Z")
|
|
440
|
+
return iso;
|
|
441
|
+
let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
|
|
442
|
+
offset = this.#offset[0] === "-" ? offset : -offset;
|
|
443
|
+
let offsetDate = new Date(this.getTime() - offset * 6e4);
|
|
444
|
+
return offsetDate.toISOString().slice(0, -1) + this.#offset;
|
|
445
|
+
}
|
|
446
|
+
static wrapAsOffsetDateTime(jsDate, offset = "Z") {
|
|
447
|
+
let date = new _TomlDate(jsDate);
|
|
448
|
+
date.#offset = offset;
|
|
449
|
+
return date;
|
|
450
|
+
}
|
|
451
|
+
static wrapAsLocalDateTime(jsDate) {
|
|
452
|
+
let date = new _TomlDate(jsDate);
|
|
453
|
+
date.#offset = null;
|
|
454
|
+
return date;
|
|
455
|
+
}
|
|
456
|
+
static wrapAsLocalDate(jsDate) {
|
|
457
|
+
let date = new _TomlDate(jsDate);
|
|
458
|
+
date.#hasTime = false;
|
|
459
|
+
date.#offset = null;
|
|
460
|
+
return date;
|
|
461
|
+
}
|
|
462
|
+
static wrapAsLocalTime(jsDate) {
|
|
463
|
+
let date = new _TomlDate(jsDate);
|
|
464
|
+
date.#hasDate = false;
|
|
465
|
+
date.#offset = null;
|
|
466
|
+
return date;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// node_modules/smol-toml/dist/error.js
|
|
471
|
+
init_define_import_meta_env();
|
|
472
|
+
function getLineColFromPtr(string, ptr) {
|
|
473
|
+
let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
|
|
474
|
+
return [lines.length, lines.pop().length + 1];
|
|
475
|
+
}
|
|
476
|
+
function makeCodeBlock(string, line, column) {
|
|
477
|
+
let lines = string.split(/\r\n|\n|\r/g);
|
|
478
|
+
let codeblock = "";
|
|
479
|
+
let numberLen = (Math.log10(line + 1) | 0) + 1;
|
|
480
|
+
for (let i = line - 1; i <= line + 1; i++) {
|
|
481
|
+
let l = lines[i - 1];
|
|
482
|
+
if (!l)
|
|
483
|
+
continue;
|
|
484
|
+
codeblock += i.toString().padEnd(numberLen, " ");
|
|
485
|
+
codeblock += ": ";
|
|
486
|
+
codeblock += l;
|
|
487
|
+
codeblock += "\n";
|
|
488
|
+
if (i === line) {
|
|
489
|
+
codeblock += " ".repeat(numberLen + column + 2);
|
|
490
|
+
codeblock += "^\n";
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return codeblock;
|
|
494
|
+
}
|
|
495
|
+
var TomlError = class extends Error {
|
|
496
|
+
line;
|
|
497
|
+
column;
|
|
498
|
+
codeblock;
|
|
499
|
+
constructor(message, options) {
|
|
500
|
+
const [line, column] = getLineColFromPtr(options.toml, options.ptr);
|
|
501
|
+
const codeblock = makeCodeBlock(options.toml, line, column);
|
|
502
|
+
super(`Invalid TOML document: ${message}
|
|
503
|
+
|
|
504
|
+
${codeblock}`, options);
|
|
505
|
+
this.line = line;
|
|
506
|
+
this.column = column;
|
|
507
|
+
this.codeblock = codeblock;
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// node_modules/smol-toml/dist/util.js
|
|
512
|
+
init_define_import_meta_env();
|
|
513
|
+
function indexOfNewline(str, start = 0) {
|
|
514
|
+
let idx = str.indexOf("\n", start);
|
|
515
|
+
if (str.charCodeAt(idx - 1) === 13)
|
|
516
|
+
idx--;
|
|
517
|
+
return idx;
|
|
518
|
+
}
|
|
519
|
+
function skipComment(ctx) {
|
|
520
|
+
for (; ctx.p < ctx.s.length; ctx.p++) {
|
|
521
|
+
let c = ctx.s.charCodeAt(ctx.p);
|
|
522
|
+
if (c === 10)
|
|
523
|
+
break;
|
|
524
|
+
if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) {
|
|
525
|
+
ctx.p++;
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
if (c < 32 && c !== 9 || c === 127) {
|
|
529
|
+
throw new TomlError("control characters are not allowed in comments", {
|
|
530
|
+
toml: ctx.s,
|
|
531
|
+
ptr: ctx.p
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
function skipVoid(ctx, banNewLines, banComments) {
|
|
537
|
+
let c;
|
|
538
|
+
while (1) {
|
|
539
|
+
while ((c = ctx.s.charCodeAt(ctx.p)) === 32 || c === 9 || !banNewLines && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10))
|
|
540
|
+
ctx.p++;
|
|
541
|
+
if (banComments || c !== 35)
|
|
542
|
+
break;
|
|
543
|
+
skipComment(ctx);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function skipUntil(ctx, sep, end) {
|
|
547
|
+
let ptr = ctx.p;
|
|
548
|
+
if (!end) {
|
|
549
|
+
ptr = indexOfNewline(ctx.s, ptr);
|
|
550
|
+
ctx.p = ptr < 0 ? ctx.s.length : ptr;
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
for (; ctx.p < ctx.s.length; ctx.p++) {
|
|
554
|
+
let c = ctx.s.charCodeAt(ctx.p);
|
|
555
|
+
if (c === 35) {
|
|
556
|
+
skipComment(ctx);
|
|
557
|
+
} else if (c === end || c === sep) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
throw new TomlError("cannot find end of structure", {
|
|
562
|
+
toml: ctx.s,
|
|
563
|
+
ptr
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// node_modules/smol-toml/dist/primitive.js
|
|
568
|
+
var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
569
|
+
var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
570
|
+
var LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
571
|
+
function parseString(ctx) {
|
|
572
|
+
let start = ctx.p;
|
|
573
|
+
let c = ctx.s.charCodeAt(ctx.p++);
|
|
574
|
+
let first = c;
|
|
575
|
+
let isLiteral = c === 39;
|
|
576
|
+
let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);
|
|
577
|
+
if (isMultiline) {
|
|
578
|
+
if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 10)
|
|
579
|
+
ctx.p++;
|
|
580
|
+
else if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)
|
|
581
|
+
ctx.p += 2;
|
|
582
|
+
}
|
|
583
|
+
let parsed = "";
|
|
584
|
+
let sliceStart = ctx.p;
|
|
585
|
+
let state = 0;
|
|
586
|
+
for (; ctx.p < ctx.s.length; ctx.p++) {
|
|
587
|
+
c = ctx.s.charCodeAt(ctx.p);
|
|
588
|
+
if (isMultiline && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)) {
|
|
589
|
+
state = state && 3;
|
|
590
|
+
} else if (c < 32 && c !== 9 || c === 127) {
|
|
591
|
+
throw new TomlError("control characters are not allowed in strings", {
|
|
592
|
+
toml: ctx.s,
|
|
593
|
+
ptr: ctx.p
|
|
594
|
+
});
|
|
595
|
+
} else if ((!state || state === 3) && c === first && (!isMultiline || ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first)) {
|
|
596
|
+
if (isMultiline) {
|
|
597
|
+
if (ctx.s.charCodeAt(ctx.p + 3) === first)
|
|
598
|
+
ctx.p++;
|
|
599
|
+
if (ctx.s.charCodeAt(ctx.p + 3) === first)
|
|
600
|
+
ctx.p++;
|
|
601
|
+
}
|
|
602
|
+
if (!state)
|
|
603
|
+
parsed += ctx.s.slice(sliceStart, ctx.p);
|
|
604
|
+
ctx.p += isMultiline ? 3 : 1;
|
|
605
|
+
return parsed;
|
|
606
|
+
} else if (!state) {
|
|
607
|
+
if (!isLiteral && c === 92) {
|
|
608
|
+
parsed += ctx.s.slice(sliceStart, sliceStart = ctx.p);
|
|
609
|
+
state = 1;
|
|
610
|
+
}
|
|
611
|
+
} else if (state === 1) {
|
|
612
|
+
if (c === 120 || c === 117 || c === 85) {
|
|
613
|
+
let value = 0;
|
|
614
|
+
let len = c === 120 ? 2 : c === 117 ? 4 : 8;
|
|
615
|
+
for (let j = 0; j < len; j++, ctx.p++) {
|
|
616
|
+
let hex = ctx.s.charCodeAt(ctx.p + 1);
|
|
617
|
+
let digit = (
|
|
618
|
+
/* 0-9 */
|
|
619
|
+
hex >= 48 && hex <= 57 ? hex - 48 : (
|
|
620
|
+
/* A-F */
|
|
621
|
+
hex >= 65 && hex <= 70 ? hex - 65 + 10 : (
|
|
622
|
+
/* a-f */
|
|
623
|
+
hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1
|
|
624
|
+
)
|
|
625
|
+
)
|
|
626
|
+
);
|
|
627
|
+
if (digit < 0)
|
|
628
|
+
throw new TomlError("invalid non-hex character in unicode escape", { toml: ctx.s, ptr: ctx.p + 1 });
|
|
629
|
+
value = value << 4 | digit;
|
|
630
|
+
}
|
|
631
|
+
if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) {
|
|
632
|
+
throw new TomlError("invalid unicode escape", { toml: ctx.s, ptr: ctx.p });
|
|
633
|
+
}
|
|
634
|
+
parsed += String.fromCodePoint(value);
|
|
635
|
+
sliceStart = ctx.p + 1;
|
|
636
|
+
state = 0;
|
|
637
|
+
} else if (c === 32 || c === 9) {
|
|
638
|
+
state = 2;
|
|
639
|
+
} else {
|
|
640
|
+
if (c === 98)
|
|
641
|
+
parsed += "\b";
|
|
642
|
+
else if (c === 116)
|
|
643
|
+
parsed += " ";
|
|
644
|
+
else if (c === 110)
|
|
645
|
+
parsed += "\n";
|
|
646
|
+
else if (c === 102)
|
|
647
|
+
parsed += "\f";
|
|
648
|
+
else if (c === 114)
|
|
649
|
+
parsed += "\r";
|
|
650
|
+
else if (c === 101)
|
|
651
|
+
parsed += "\x1B";
|
|
652
|
+
else if (c === 34)
|
|
653
|
+
parsed += '"';
|
|
654
|
+
else if (c === 92)
|
|
655
|
+
parsed += "\\";
|
|
656
|
+
else
|
|
657
|
+
throw new TomlError("unrecognized escape sequence", { toml: ctx.s, ptr: ctx.p });
|
|
658
|
+
sliceStart = ctx.p + 1;
|
|
659
|
+
state = 0;
|
|
660
|
+
}
|
|
661
|
+
} else if (c !== 32 && c !== 9) {
|
|
662
|
+
if (state === 2) {
|
|
663
|
+
throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
|
|
664
|
+
toml: ctx.s,
|
|
665
|
+
ptr: sliceStart
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
state = !isLiteral && c === 92 ? 1 : 0;
|
|
669
|
+
sliceStart = ctx.p;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
throw new TomlError("unfinished string", { toml: ctx.s, ptr: start });
|
|
673
|
+
}
|
|
674
|
+
function sliceAndTrimEndOf(ctx, start, end) {
|
|
675
|
+
let value = ctx.s.slice(start, end);
|
|
676
|
+
let commentIdx = value.indexOf("#");
|
|
677
|
+
if (commentIdx > 0) {
|
|
678
|
+
skipComment({ s: value, p: commentIdx, d: 0 });
|
|
679
|
+
value = value.slice(0, commentIdx);
|
|
680
|
+
}
|
|
681
|
+
return value.trimEnd();
|
|
682
|
+
}
|
|
683
|
+
function parseValue(ctx, integersAsBigInt, end) {
|
|
684
|
+
let ptr = ctx.p;
|
|
685
|
+
let err = { toml: ctx.s, ptr };
|
|
686
|
+
skipUntil(ctx, 44, end);
|
|
687
|
+
let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);
|
|
688
|
+
if (!value)
|
|
689
|
+
throw new TomlError("incomplete declaration: value expected", err);
|
|
690
|
+
if (value === "-inf")
|
|
691
|
+
return -Infinity;
|
|
692
|
+
if (value === "inf" || value === "+inf")
|
|
693
|
+
return Infinity;
|
|
694
|
+
if (value === "nan" || value === "+nan" || value === "-nan")
|
|
695
|
+
return NaN;
|
|
696
|
+
if (value === "-0")
|
|
697
|
+
return integersAsBigInt ? 0n : 0;
|
|
698
|
+
let isInt = INT_REGEX.test(value);
|
|
699
|
+
if (isInt || FLOAT_REGEX.test(value)) {
|
|
700
|
+
if (LEADING_ZERO.test(value)) {
|
|
701
|
+
throw new TomlError("leading zeroes are not allowed", err);
|
|
702
|
+
}
|
|
703
|
+
value = value.replace(/_/g, "");
|
|
704
|
+
let numeric = +value;
|
|
705
|
+
if (isNaN(numeric)) {
|
|
706
|
+
throw new TomlError("invalid number", err);
|
|
707
|
+
}
|
|
708
|
+
if (isInt) {
|
|
709
|
+
if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
|
|
710
|
+
throw new TomlError("integer value cannot be represented losslessly", err);
|
|
711
|
+
}
|
|
712
|
+
if (isInt || integersAsBigInt === true)
|
|
713
|
+
numeric = BigInt(value);
|
|
714
|
+
}
|
|
715
|
+
return numeric;
|
|
716
|
+
}
|
|
717
|
+
const date = new TomlDate(value);
|
|
718
|
+
if (!date.isValid())
|
|
719
|
+
throw new TomlError("invalid value", err);
|
|
720
|
+
return date;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// node_modules/smol-toml/dist/extract.js
|
|
724
|
+
init_define_import_meta_env();
|
|
725
|
+
function extractValue(ctx, end, integersAsBigInt) {
|
|
726
|
+
let ptr = ctx.p;
|
|
727
|
+
let c = ctx.s.charCodeAt(ptr);
|
|
728
|
+
if (c === 91 || c === 123) {
|
|
729
|
+
if (!ctx.d--) {
|
|
730
|
+
throw new TomlError("document contains excessively nested structures. aborting.", {
|
|
731
|
+
toml: ctx.s,
|
|
732
|
+
ptr
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
let value = c === 91 ? parseArray(ctx, integersAsBigInt) : parseInlineTable(ctx, integersAsBigInt);
|
|
736
|
+
ctx.d++;
|
|
737
|
+
return value;
|
|
738
|
+
}
|
|
739
|
+
if (c === 34 || c === 39) {
|
|
740
|
+
return parseString(ctx);
|
|
741
|
+
}
|
|
742
|
+
if (c === 116) {
|
|
743
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 114 || ctx.s.charCodeAt(++ctx.p) !== 117 || ctx.s.charCodeAt(++ctx.p) !== 101)
|
|
744
|
+
throw new TomlError("invalid value", { toml: ctx.s, ptr });
|
|
745
|
+
ctx.p++;
|
|
746
|
+
return true;
|
|
747
|
+
}
|
|
748
|
+
if (c === 102) {
|
|
749
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 108 || ctx.s.charCodeAt(++ctx.p) !== 115 || ctx.s.charCodeAt(++ctx.p) !== 101)
|
|
750
|
+
throw new TomlError("invalid value", { toml: ctx.s, ptr });
|
|
751
|
+
ctx.p++;
|
|
752
|
+
return false;
|
|
753
|
+
}
|
|
754
|
+
return parseValue(ctx, integersAsBigInt, end);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// node_modules/smol-toml/dist/struct.js
|
|
758
|
+
var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
|
759
|
+
function parseKey(ctx, end = "=") {
|
|
760
|
+
let start = ctx.p;
|
|
761
|
+
let dot = start - 1;
|
|
762
|
+
let parsed = [];
|
|
763
|
+
let endPtr = ctx.s.indexOf(end, start);
|
|
764
|
+
if (endPtr < 0) {
|
|
765
|
+
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
766
|
+
toml: ctx.s,
|
|
767
|
+
ptr: start
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
do {
|
|
771
|
+
let c = ctx.s.charCodeAt(ctx.p = ++dot);
|
|
772
|
+
if (c !== 32 && c !== 9) {
|
|
773
|
+
if (c === 34 || c === 39) {
|
|
774
|
+
if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) {
|
|
775
|
+
throw new TomlError("multiline strings are not allowed in keys", {
|
|
776
|
+
toml: ctx.s,
|
|
777
|
+
ptr: ctx.p
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
let part = parseString(ctx);
|
|
781
|
+
dot = ctx.s.indexOf(".", ctx.p);
|
|
782
|
+
let strEnd = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
783
|
+
let newLine = indexOfNewline(strEnd);
|
|
784
|
+
if (newLine > -1) {
|
|
785
|
+
throw new TomlError("newlines are not allowed in keys", {
|
|
786
|
+
toml: ctx.s,
|
|
787
|
+
ptr: newLine
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
if (strEnd.trimStart()) {
|
|
791
|
+
throw new TomlError("found extra tokens after the string part", {
|
|
792
|
+
toml: ctx.s,
|
|
793
|
+
ptr: ctx.p
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
if (endPtr < ctx.p) {
|
|
797
|
+
endPtr = ctx.s.indexOf(end, ctx.p);
|
|
798
|
+
if (endPtr < 0) {
|
|
799
|
+
throw new TomlError("incomplete key-value: cannot find end of key", {
|
|
800
|
+
toml: ctx.s,
|
|
801
|
+
ptr: start
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
parsed.push(part);
|
|
806
|
+
} else {
|
|
807
|
+
dot = ctx.s.indexOf(".", ctx.p);
|
|
808
|
+
let part = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);
|
|
809
|
+
if (!KEY_PART_RE.test(part)) {
|
|
810
|
+
throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
|
|
811
|
+
toml: ctx.s,
|
|
812
|
+
ptr: ctx.p
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
parsed.push(part.trimEnd());
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
} while (dot + 1 && dot < endPtr);
|
|
819
|
+
ctx.p = endPtr + 1;
|
|
820
|
+
skipVoid(ctx, true, true);
|
|
821
|
+
return parsed;
|
|
822
|
+
}
|
|
823
|
+
function parseInlineTable(ctx, integersAsBigInt) {
|
|
824
|
+
let res = {};
|
|
825
|
+
let seen = /* @__PURE__ */ new Set();
|
|
826
|
+
let c;
|
|
827
|
+
ctx.p++;
|
|
828
|
+
while (ctx.p < ctx.s.length) {
|
|
829
|
+
skipVoid(ctx);
|
|
830
|
+
if ((c = ctx.s.charCodeAt(ctx.p)) === 125) {
|
|
831
|
+
ctx.p++;
|
|
832
|
+
return res;
|
|
833
|
+
}
|
|
834
|
+
let k;
|
|
835
|
+
let t = res;
|
|
836
|
+
let hasOwn = false;
|
|
837
|
+
let p = ctx.p;
|
|
838
|
+
let key = parseKey(ctx);
|
|
839
|
+
for (let i = 0; i < key.length; i++) {
|
|
840
|
+
if (i)
|
|
841
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
842
|
+
k = key[i];
|
|
843
|
+
if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
|
|
844
|
+
throw new TomlError("trying to redefine an already defined value", {
|
|
845
|
+
toml: ctx.s,
|
|
846
|
+
ptr: p
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
if (!hasOwn && k === "__proto__") {
|
|
850
|
+
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
if (hasOwn) {
|
|
854
|
+
throw new TomlError("trying to redefine an already defined value", {
|
|
855
|
+
toml: ctx.s,
|
|
856
|
+
ptr: ctx.p
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
let value = extractValue(ctx, 125, integersAsBigInt);
|
|
860
|
+
seen.add(t[k] = value);
|
|
861
|
+
skipVoid(ctx);
|
|
862
|
+
if ((c = ctx.s.charCodeAt(ctx.p++)) === 125) {
|
|
863
|
+
return res;
|
|
864
|
+
}
|
|
865
|
+
if (c !== 44) {
|
|
866
|
+
throw new TomlError("expected comma or end of structure", { toml: ctx.s, ptr: ctx.p - 1 });
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
throw new TomlError("unfinished table encountered", {
|
|
870
|
+
toml: ctx.s,
|
|
871
|
+
ptr: ctx.p
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
function parseArray(ctx, integersAsBigInt) {
|
|
875
|
+
let res = [];
|
|
876
|
+
let c;
|
|
877
|
+
ctx.p++;
|
|
878
|
+
while (ctx.p < ctx.s.length) {
|
|
879
|
+
skipVoid(ctx);
|
|
880
|
+
if ((c = ctx.s.charCodeAt(ctx.p)) === 93) {
|
|
881
|
+
ctx.p++;
|
|
882
|
+
return res;
|
|
883
|
+
}
|
|
884
|
+
res.push(extractValue(ctx, 93, integersAsBigInt));
|
|
885
|
+
skipVoid(ctx);
|
|
886
|
+
if ((c = ctx.s.charCodeAt(ctx.p++)) === 93) {
|
|
887
|
+
return res;
|
|
888
|
+
}
|
|
889
|
+
if (c !== 44) {
|
|
890
|
+
throw new TomlError("expected comma or end of structure", { toml: ctx.s, ptr: ctx.p - 1 });
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
throw new TomlError("unfinished array encountered", {
|
|
894
|
+
toml: ctx.s,
|
|
895
|
+
ptr: ctx.p
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// node_modules/smol-toml/dist/parse.js
|
|
900
|
+
function peekTable(key, table, meta, type) {
|
|
901
|
+
let t = table;
|
|
902
|
+
let m = meta;
|
|
903
|
+
let k;
|
|
904
|
+
let hasOwn = false;
|
|
905
|
+
let state;
|
|
906
|
+
for (let i = 0; i < key.length; i++) {
|
|
907
|
+
if (i) {
|
|
908
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
909
|
+
m = (state = m[k]).c;
|
|
910
|
+
if (type === 0 && (state.t === 1 || state.t === 2)) {
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
if (state.t === 2) {
|
|
914
|
+
let l = t.length - 1;
|
|
915
|
+
t = t[l];
|
|
916
|
+
m = m[l].c;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
k = key[i];
|
|
920
|
+
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
|
|
921
|
+
return null;
|
|
922
|
+
}
|
|
923
|
+
if (!hasOwn) {
|
|
924
|
+
if (k === "__proto__") {
|
|
925
|
+
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
926
|
+
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
927
|
+
}
|
|
928
|
+
m[k] = {
|
|
929
|
+
t: i < key.length - 1 && type === 2 ? 3 : type,
|
|
930
|
+
d: false,
|
|
931
|
+
i: 0,
|
|
932
|
+
c: {}
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
state = m[k];
|
|
937
|
+
if (state.t !== type && !(type === 1 && state.t === 3)) {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
if (type === 2) {
|
|
941
|
+
if (!state.d) {
|
|
942
|
+
state.d = true;
|
|
943
|
+
t[k] = [];
|
|
944
|
+
}
|
|
945
|
+
t[k].push(t = {});
|
|
946
|
+
state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
|
|
947
|
+
}
|
|
948
|
+
if (state.d) {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
951
|
+
state.d = true;
|
|
952
|
+
if (type === 1) {
|
|
953
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
954
|
+
} else if (type === 0 && hasOwn) {
|
|
955
|
+
return null;
|
|
956
|
+
}
|
|
957
|
+
return [k, t, state.c];
|
|
958
|
+
}
|
|
959
|
+
function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
|
|
960
|
+
let ctx = { s: toml, p: 0, d: maxDepth };
|
|
961
|
+
let res = {};
|
|
962
|
+
let meta = {};
|
|
963
|
+
let tmp;
|
|
964
|
+
let tbl = res;
|
|
965
|
+
let m = meta;
|
|
966
|
+
skipVoid(ctx);
|
|
967
|
+
while (ctx.p < toml.length) {
|
|
968
|
+
if (toml.charCodeAt(ctx.p) === 91) {
|
|
969
|
+
let isTableArray = toml.charCodeAt(++ctx.p) === 91;
|
|
970
|
+
tmp = ctx.p += +isTableArray;
|
|
971
|
+
let k = parseKey(ctx, "]");
|
|
972
|
+
if (isTableArray) {
|
|
973
|
+
if (toml.charCodeAt(ctx.p - 1) !== 93) {
|
|
974
|
+
throw new TomlError("expected end of table declaration", {
|
|
975
|
+
toml,
|
|
976
|
+
ptr: ctx.p - 1
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
ctx.p++;
|
|
980
|
+
}
|
|
981
|
+
let p = peekTable(
|
|
982
|
+
k,
|
|
983
|
+
res,
|
|
984
|
+
meta,
|
|
985
|
+
isTableArray ? 2 : 1
|
|
986
|
+
/* Type.EXPLICIT */
|
|
987
|
+
);
|
|
988
|
+
if (!p) {
|
|
989
|
+
throw new TomlError("trying to redefine an already defined table or value", {
|
|
990
|
+
toml,
|
|
991
|
+
ptr: tmp
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
m = p[2];
|
|
995
|
+
tbl = p[1];
|
|
996
|
+
} else {
|
|
997
|
+
tmp = ctx.p;
|
|
998
|
+
let k = parseKey(ctx);
|
|
999
|
+
let p = peekTable(
|
|
1000
|
+
k,
|
|
1001
|
+
tbl,
|
|
1002
|
+
m,
|
|
1003
|
+
0
|
|
1004
|
+
/* Type.DOTTED */
|
|
1005
|
+
);
|
|
1006
|
+
if (!p) {
|
|
1007
|
+
throw new TomlError("trying to redefine an already defined table or value", {
|
|
1008
|
+
toml,
|
|
1009
|
+
ptr: tmp
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);
|
|
1013
|
+
}
|
|
1014
|
+
skipVoid(ctx, true);
|
|
1015
|
+
if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 10 && tmp !== 13) {
|
|
1016
|
+
throw new TomlError("each key-value declaration must be followed by an end-of-line", {
|
|
1017
|
+
toml,
|
|
1018
|
+
ptr: ctx.p
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
skipVoid(ctx);
|
|
1022
|
+
}
|
|
1023
|
+
return res;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// node_modules/smol-toml/dist/stringify.js
|
|
1027
|
+
init_define_import_meta_env();
|
|
1028
|
+
var BARE_KEY = /^[a-z0-9-_]+$/i;
|
|
1029
|
+
function extendedTypeOf(obj) {
|
|
1030
|
+
let type = typeof obj;
|
|
1031
|
+
if (type === "object") {
|
|
1032
|
+
if (Array.isArray(obj))
|
|
1033
|
+
return "array";
|
|
1034
|
+
if (typeof obj?.getUTCDate === "function" && obj instanceof Date)
|
|
1035
|
+
return "date";
|
|
1036
|
+
if (globalThis.Temporal && // check for the 'since' property as an early bailout that avoids running all 5 instanceof checks
|
|
1037
|
+
typeof obj?.since === "function" && (obj instanceof Temporal.Instant || obj instanceof Temporal.PlainDate || obj instanceof Temporal.PlainDateTime || obj instanceof Temporal.PlainTime || obj instanceof Temporal.ZonedDateTime)) {
|
|
1038
|
+
return "temporal";
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return type;
|
|
1042
|
+
}
|
|
1043
|
+
function isArrayOfTables(obj) {
|
|
1044
|
+
for (let i = 0; i < obj.length; i++) {
|
|
1045
|
+
if (extendedTypeOf(obj[i]) !== "object")
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
return obj.length != 0;
|
|
1049
|
+
}
|
|
1050
|
+
function formatString(s) {
|
|
1051
|
+
return JSON.stringify(s).replace(/\x7f/g, "\\u007f");
|
|
1052
|
+
}
|
|
1053
|
+
function stringifyTemporal(temporal) {
|
|
1054
|
+
return temporal.toString({
|
|
1055
|
+
calendarName: "never",
|
|
1056
|
+
timeZoneName: "never"
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
function stringifyValue(val, type, depth, numberAsFloat) {
|
|
1060
|
+
if (depth === 0) {
|
|
1061
|
+
throw new Error("Could not stringify the object: maximum object depth exceeded");
|
|
1062
|
+
}
|
|
1063
|
+
switch (type) {
|
|
1064
|
+
// @ts-expect-error -- intentional fallthrough case
|
|
1065
|
+
case "number":
|
|
1066
|
+
if (isNaN(val))
|
|
1067
|
+
return "nan";
|
|
1068
|
+
if (val === Infinity)
|
|
1069
|
+
return "inf";
|
|
1070
|
+
if (val === -Infinity)
|
|
1071
|
+
return "-inf";
|
|
1072
|
+
if (Number.isInteger(val) && (numberAsFloat || !Number.isSafeInteger(val)))
|
|
1073
|
+
return val.toFixed(1);
|
|
1074
|
+
case "bigint":
|
|
1075
|
+
case "boolean":
|
|
1076
|
+
return val.toString();
|
|
1077
|
+
case "string":
|
|
1078
|
+
return formatString(val);
|
|
1079
|
+
case "date":
|
|
1080
|
+
if (isNaN(val.getTime()))
|
|
1081
|
+
throw new TypeError("cannot serialize invalid date");
|
|
1082
|
+
return val.toISOString();
|
|
1083
|
+
case "object":
|
|
1084
|
+
return stringifyInlineTable(val, depth, numberAsFloat);
|
|
1085
|
+
case "array":
|
|
1086
|
+
return stringifyArray(val, depth, numberAsFloat);
|
|
1087
|
+
case "temporal":
|
|
1088
|
+
return stringifyTemporal(val);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
function stringifyInlineTable(obj, depth, numberAsFloat) {
|
|
1092
|
+
let keys = Object.keys(obj);
|
|
1093
|
+
if (keys.length === 0)
|
|
1094
|
+
return "{}";
|
|
1095
|
+
let res = "{ ";
|
|
1096
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1097
|
+
let k = keys[i];
|
|
1098
|
+
if (i)
|
|
1099
|
+
res += ", ";
|
|
1100
|
+
res += BARE_KEY.test(k) ? k : formatString(k);
|
|
1101
|
+
res += " = ";
|
|
1102
|
+
res += stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat);
|
|
1103
|
+
}
|
|
1104
|
+
return res + " }";
|
|
1105
|
+
}
|
|
1106
|
+
function stringifyArray(array, depth, numberAsFloat) {
|
|
1107
|
+
if (array.length === 0)
|
|
1108
|
+
return "[]";
|
|
1109
|
+
let res = "[ ";
|
|
1110
|
+
for (let i = 0; i < array.length; i++) {
|
|
1111
|
+
if (i)
|
|
1112
|
+
res += ", ";
|
|
1113
|
+
if (array[i] === null || array[i] === void 0) {
|
|
1114
|
+
throw new TypeError("arrays cannot contain null or undefined values");
|
|
1115
|
+
}
|
|
1116
|
+
res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat);
|
|
1117
|
+
}
|
|
1118
|
+
return res + " ]";
|
|
1119
|
+
}
|
|
1120
|
+
function stringifyArrayTable(array, key, depth, numberAsFloat) {
|
|
1121
|
+
if (depth === 0) {
|
|
1122
|
+
throw new Error("Could not stringify the object: maximum object depth exceeded");
|
|
1123
|
+
}
|
|
1124
|
+
let res = "";
|
|
1125
|
+
for (let i = 0; i < array.length; i++) {
|
|
1126
|
+
res += `${res && "\n"}[[${key}]]
|
|
1127
|
+
`;
|
|
1128
|
+
res += stringifyTable(0, array[i], key, depth, numberAsFloat);
|
|
1129
|
+
}
|
|
1130
|
+
return res;
|
|
1131
|
+
}
|
|
1132
|
+
function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
|
|
1133
|
+
if (depth === 0) {
|
|
1134
|
+
throw new Error("Could not stringify the object: maximum object depth exceeded");
|
|
1135
|
+
}
|
|
1136
|
+
let preamble = "";
|
|
1137
|
+
let tables = "";
|
|
1138
|
+
let keys = Object.keys(obj);
|
|
1139
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1140
|
+
let k = keys[i];
|
|
1141
|
+
if (obj[k] !== null && obj[k] !== void 0) {
|
|
1142
|
+
let type = extendedTypeOf(obj[k]);
|
|
1143
|
+
if (type === "symbol" || type === "function") {
|
|
1144
|
+
throw new TypeError(`cannot serialize values of type '${type}'`);
|
|
1145
|
+
}
|
|
1146
|
+
let key = BARE_KEY.test(k) ? k : formatString(k);
|
|
1147
|
+
if (type === "array" && isArrayOfTables(obj[k])) {
|
|
1148
|
+
tables += (tables && "\n") + stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
|
|
1149
|
+
} else if (type === "object") {
|
|
1150
|
+
let tblKey = prefix ? `${prefix}.${key}` : key;
|
|
1151
|
+
tables += (tables && "\n") + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat);
|
|
1152
|
+
} else {
|
|
1153
|
+
preamble += key;
|
|
1154
|
+
preamble += " = ";
|
|
1155
|
+
preamble += stringifyValue(obj[k], type, depth, numberAsFloat);
|
|
1156
|
+
preamble += "\n";
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
if (tableKey && (preamble || !tables))
|
|
1161
|
+
preamble = preamble ? `[${tableKey}]
|
|
1162
|
+
${preamble}` : `[${tableKey}]`;
|
|
1163
|
+
return preamble && tables ? `${preamble}
|
|
1164
|
+
${tables}` : preamble || tables;
|
|
1165
|
+
}
|
|
1166
|
+
function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
1167
|
+
if (extendedTypeOf(obj) !== "object") {
|
|
1168
|
+
throw new TypeError("stringify can only be called with an object");
|
|
1169
|
+
}
|
|
1170
|
+
let str = stringifyTable(0, obj, "", maxDepth, numbersAsFloat);
|
|
1171
|
+
if (str[str.length - 1] !== "\n")
|
|
1172
|
+
return str + "\n";
|
|
1173
|
+
return str;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// src/config_project.ts
|
|
1177
|
+
var PROJECT_LOCKED_SECTIONS = [
|
|
1178
|
+
"injection",
|
|
1179
|
+
"webfetch",
|
|
1180
|
+
"gdrive",
|
|
1181
|
+
"redaction",
|
|
1182
|
+
"mcp",
|
|
1183
|
+
"network",
|
|
1184
|
+
"screenshot"
|
|
1185
|
+
];
|
|
1186
|
+
var PROJECT_LOCKED_KEYS = [
|
|
1187
|
+
// A repository must not be able to decide how much of its own source an agent gets to see. Turning this on folds function bodies out of every Read of this project's files, so a checked-in `.token-goat.toml` setting it true would shrink what a reviewing agent is shown of the very code it came to review -- and the fold is silent about intent, so it reads as normal output. The user's own global config and TOKEN_GOAT_FOLD_CODE_BODIES still set it freely; only the project-supplied layer is refused.
|
|
1188
|
+
"hints.fold_code_bodies",
|
|
1189
|
+
// Same reasoning as the body fold above, on the comments rather than the code: a checked-in project file must not be able to fold a repository's own explanatory comments out of what a reviewing agent is shown, which is precisely where an intent that disagrees with the code would be written down. The user's global config and TOKEN_GOAT_FOLD_COMMENT_BLOCKS still set it freely.
|
|
1190
|
+
"hints.fold_comment_blocks",
|
|
1191
|
+
// Same reasoning one document over: a repository must not be able to fold its own README or changelog out of what a reviewing agent is shown. The user's global config and TOKEN_GOAT_FOLD_PROSE_PARAGRAPHS still set it freely.
|
|
1192
|
+
"hints.fold_prose_paragraphs",
|
|
1193
|
+
// Same reasoning again: a repository must not be able to hide its own documentation's structure from a reviewing agent by disabling the heading-tree replacement, nor -- more to the point here -- by leaving it on to shrink what a reviewing agent sees of a doc the repo itself ships. The user's global config and TOKEN_GOAT_OUTLINE_LARGE_DOCUMENTS still set it freely.
|
|
1194
|
+
"hints.outline_large_documents",
|
|
1195
|
+
// Same reasoning one file type over: a repository must not be able to decide, from its own checked-in config, how much of its source a reviewing agent is shown -- neither by turning the skeleton off to bury a declaration in a wall of bodies, nor by leaving it on to withhold the bodies themselves. The user's global config and TOKEN_GOAT_SKELETON_LARGE_SOURCES still set it freely.
|
|
1196
|
+
"hints.skeleton_large_sources",
|
|
1197
|
+
// The widest blast radius of anything on this list. The fold keys above decide how much of a file an agent is shown; this decides how much of the whole session survives compaction. A checked-in `.token-goat.toml` setting it to a handful of characters would ask the summarizer to discard the session's accumulated state at every compaction boundary, and the loss is silent -- what comes back is a well-formed short summary, not an error. The user's own global config still sets it freely; only the project-supplied layer is refused.
|
|
1198
|
+
"compact_assist.summary_budget_chars",
|
|
1199
|
+
"image_shrink.max_image_pixels",
|
|
1200
|
+
// The same principle as the four fold keys above, applied one layer earlier and with a wider blast radius: those decide how much of an indexed file is shown, these decide whether it is indexed at all. A checked-in `.token-goat.toml` adding its own attack surface to `skip_dirs` -- or dropping `large_file_skip_kb` to a handful of kilobytes -- removes those files from `symbol`, `read`, `refs`, `semantic` and `graph` for a reviewing agent, and every one of them then answers "not found" in the same words it uses for a name that genuinely does not exist. There is no notice to read, because from the index's point of view nothing was hidden. The user's own global config still sets all three freely; only the project-supplied layer is refused.
|
|
1201
|
+
"indexing.skip_dirs",
|
|
1202
|
+
"indexing.skip_files",
|
|
1203
|
+
"indexing.large_file_skip_kb",
|
|
1204
|
+
"indexing.large_file_symbol_only_kb",
|
|
1205
|
+
"indexing.cross_project_symbols",
|
|
1206
|
+
"worker.blocked_roots"
|
|
1207
|
+
];
|
|
1208
|
+
var _lastProjectConfigLockedKeys = [];
|
|
1209
|
+
function lastProjectConfigLockedKeys() {
|
|
1210
|
+
return _lastProjectConfigLockedKeys;
|
|
1211
|
+
}
|
|
1212
|
+
function setLastProjectConfigLockedKeys(keys) {
|
|
1213
|
+
_lastProjectConfigLockedKeys = keys;
|
|
1214
|
+
}
|
|
1215
|
+
function resetLastProjectConfigLockedKeys() {
|
|
1216
|
+
_lastProjectConfigLockedKeys = [];
|
|
1217
|
+
}
|
|
1218
|
+
function stripLockedProjectKeys(projectRaw) {
|
|
1219
|
+
const cleaned = {};
|
|
1220
|
+
const dropped = [];
|
|
1221
|
+
for (const [section2, value] of Object.entries(projectRaw)) {
|
|
1222
|
+
if (PROJECT_LOCKED_SECTIONS.includes(section2)) {
|
|
1223
|
+
dropped.push(section2);
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1226
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
1227
|
+
const kept = {};
|
|
1228
|
+
for (const [key, keyValue] of Object.entries(value)) {
|
|
1229
|
+
if (PROJECT_LOCKED_KEYS.includes(`${section2}.${key}`)) dropped.push(`${section2}.${key}`);
|
|
1230
|
+
else kept[key] = keyValue;
|
|
1231
|
+
}
|
|
1232
|
+
cleaned[section2] = kept;
|
|
1233
|
+
continue;
|
|
1234
|
+
}
|
|
1235
|
+
cleaned[section2] = value;
|
|
1236
|
+
}
|
|
1237
|
+
return { cleaned, dropped };
|
|
1238
|
+
}
|
|
1239
|
+
function flattenRawKeys(raw) {
|
|
1240
|
+
const keys = [];
|
|
1241
|
+
for (const [sectionName, val] of Object.entries(raw)) {
|
|
1242
|
+
if (val !== null && typeof val === "object" && !Array.isArray(val)) {
|
|
1243
|
+
for (const sub of Object.keys(val)) {
|
|
1244
|
+
keys.push(`${sectionName}.${sub}`);
|
|
1245
|
+
}
|
|
1246
|
+
} else {
|
|
1247
|
+
keys.push(sectionName);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
return keys;
|
|
1251
|
+
}
|
|
1252
|
+
function flattenRawValues(raw) {
|
|
1253
|
+
const out = {};
|
|
1254
|
+
for (const [sectionName, val] of Object.entries(raw)) {
|
|
1255
|
+
if (val !== null && typeof val === "object" && !Array.isArray(val)) {
|
|
1256
|
+
for (const [sub, v] of Object.entries(val)) {
|
|
1257
|
+
out[`${sectionName}.${sub}`] = v;
|
|
1258
|
+
}
|
|
1259
|
+
} else {
|
|
1260
|
+
out[sectionName] = val;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
return out;
|
|
1264
|
+
}
|
|
1265
|
+
function readConfigSource(p) {
|
|
1266
|
+
return decodeSource(fs3.readFileSync(p));
|
|
1267
|
+
}
|
|
1268
|
+
function readConfigToml(p) {
|
|
1269
|
+
try {
|
|
1270
|
+
return { raw: parse(readConfigSource(p)), parseError: null };
|
|
1271
|
+
} catch (e) {
|
|
1272
|
+
const code = e.code;
|
|
1273
|
+
if (code === "ENOENT") return { raw: {}, parseError: null };
|
|
1274
|
+
return { raw: {}, parseError: extractErrorMessage(e) };
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
function readConfigText(p) {
|
|
1278
|
+
try {
|
|
1279
|
+
return { text: readConfigSource(p), readError: null };
|
|
1280
|
+
} catch (e) {
|
|
1281
|
+
const code = e.code;
|
|
1282
|
+
if (code === "ENOENT") return { text: null, readError: null };
|
|
1283
|
+
return { text: null, readError: extractErrorMessage(e) };
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
function mergeRawConfig(base, override) {
|
|
1287
|
+
const merged = { ...base };
|
|
1288
|
+
for (const [key, overrideVal] of Object.entries(override)) {
|
|
1289
|
+
if (overrideVal !== null && typeof overrideVal === "object" && !Array.isArray(overrideVal)) {
|
|
1290
|
+
const baseVal = base[key];
|
|
1291
|
+
const baseSection = baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal) ? baseVal : {};
|
|
1292
|
+
merged[key] = { ...baseSection, ...overrideVal };
|
|
1293
|
+
} else {
|
|
1294
|
+
const baseVal = base[key];
|
|
1295
|
+
if (baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal)) continue;
|
|
1296
|
+
merged[key] = overrideVal;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
return merged;
|
|
1300
|
+
}
|
|
1301
|
+
var _projectRootCache = null;
|
|
1302
|
+
function resolveConfigProjectRoot() {
|
|
1303
|
+
const cwd = process.cwd();
|
|
1304
|
+
if (_projectRootCache !== null && _projectRootCache.cwd === cwd) return _projectRootCache.root;
|
|
1305
|
+
const project = findProject(cwd);
|
|
1306
|
+
const root = project !== null ? project.root : cwd;
|
|
1307
|
+
_projectRootCache = { cwd, root };
|
|
1308
|
+
return root;
|
|
1309
|
+
}
|
|
1310
|
+
registerReset(() => {
|
|
1311
|
+
_projectRootCache = null;
|
|
1312
|
+
});
|
|
1313
|
+
function getProjectConfigInfo(projectRoot) {
|
|
1314
|
+
const root = projectRoot ?? resolveConfigProjectRoot();
|
|
1315
|
+
const p = projectConfigPath(root);
|
|
1316
|
+
if (!fs3.existsSync(p)) return null;
|
|
1317
|
+
const { raw, parseError } = readConfigToml(p);
|
|
1318
|
+
if (parseError !== null) return { path: p, keys: [], values: {}, parseError };
|
|
1319
|
+
return { path: p, keys: flattenRawKeys(raw), values: flattenRawValues(raw), parseError };
|
|
1320
|
+
}
|
|
1321
|
+
function isAutoTriggerMultiplierExplicit() {
|
|
1322
|
+
const setsMultiplier = (text) => {
|
|
1323
|
+
const raw = parse(text);
|
|
1324
|
+
const ca_raw = raw["compact_assist"];
|
|
1325
|
+
if (ca_raw === null || typeof ca_raw !== "object" || Array.isArray(ca_raw)) {
|
|
1326
|
+
return false;
|
|
1327
|
+
}
|
|
1328
|
+
return ca_raw["auto_trigger_multiplier"] !== void 0;
|
|
1329
|
+
};
|
|
1330
|
+
try {
|
|
1331
|
+
if (setsMultiplier(readConfigSource(configPath()))) return true;
|
|
1332
|
+
} catch {
|
|
1333
|
+
}
|
|
1334
|
+
try {
|
|
1335
|
+
return setsMultiplier(readConfigSource(projectConfigPath(resolveConfigProjectRoot())));
|
|
1336
|
+
} catch {
|
|
1337
|
+
return false;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
// src/config.ts
|
|
1342
|
+
init_define_import_meta_env();
|
|
1343
|
+
import * as path2 from "node:path";
|
|
1344
|
+
|
|
1345
|
+
// src/config_types.ts
|
|
1346
|
+
init_define_import_meta_env();
|
|
1347
|
+
|
|
1348
|
+
// src/config_defaults.ts
|
|
1349
|
+
init_define_import_meta_env();
|
|
1350
|
+
var CONFIG_DEFAULTS = {
|
|
1351
|
+
compact_assist: {
|
|
1352
|
+
enabled: true,
|
|
1353
|
+
triggers: ["manual", "auto"],
|
|
1354
|
+
min_events: 3,
|
|
1355
|
+
max_manifest_tokens: 400,
|
|
1356
|
+
auto_trigger_multiplier: 2,
|
|
1357
|
+
compact_skip_ttl_secs: 300,
|
|
1358
|
+
noise_floor_tokens: 0,
|
|
1359
|
+
edited_dir_group_threshold: 3,
|
|
1360
|
+
max_section_lines: 0,
|
|
1361
|
+
wide_session_threshold: 15,
|
|
1362
|
+
orchestrator_commit_threshold: 5,
|
|
1363
|
+
max_manifest_chars: 1600,
|
|
1364
|
+
summary_budget_chars: 24e3,
|
|
1365
|
+
harness: "auto"
|
|
1366
|
+
},
|
|
1367
|
+
bash_compress: {
|
|
1368
|
+
enabled: true,
|
|
1369
|
+
disabled_filters: [],
|
|
1370
|
+
max_lines: 1e3,
|
|
1371
|
+
max_bytes: 64 * 1024,
|
|
1372
|
+
timeout_seconds: 600,
|
|
1373
|
+
// Matches the hardcoded MIN_CACHE_BYTES floor hooks_bash.ts used before this
|
|
1374
|
+
// knob was wired to a real consumer, so untouched-config installs see no
|
|
1375
|
+
// behavior change now that hooks_bash.ts reads this value instead.
|
|
1376
|
+
cache_min_bytes: 512,
|
|
1377
|
+
cache_max_file_count: 4096,
|
|
1378
|
+
cache_max_bytes: 16 * 1024 * 1024,
|
|
1379
|
+
cache_max_bytes_per_output: 50 * 1024 * 1024,
|
|
1380
|
+
// Measured against the filter test-fixture corpus (424 apply() calls, 298 with
|
|
1381
|
+
// bytesSaved > 0): net-of-marker savings (bytesSaved - ~70-79B marker cost) is
|
|
1382
|
+
// <= 0 for 130/298 (44%) of "compressed" results and <= 100 for 170/298 (57%),
|
|
1383
|
+
// while the real-win half sits at p75=393B / p90=952B net. 100 kills the
|
|
1384
|
+
// marker-doesn't-even-pay-for-itself tier without touching genuine wins.
|
|
1385
|
+
min_net_savings_bytes: 100,
|
|
1386
|
+
// Extends the per-file already-served elision (which only reaches cat/head/tail/sed/awk-shaped reads) to every other Bash command's output -- npm test, git, rg, build runs -- matched against a session-wide served-output list instead of a per-file one. On by default: it goes through the same isRewriteWorthwhile net-benefit gate as every other rewrite here, so it never ships a notice that costs more than the lines it withholds.
|
|
1387
|
+
elide_served_shell_output: true
|
|
1388
|
+
},
|
|
1389
|
+
agent_report: {
|
|
1390
|
+
// Well above the ~2,220 char/call average measured from real claude-skills session transcripts, so only genuine outlier reports are touched. Preserves the hardcoded AGENT_RESULT_CACHE_MIN_BYTES this replaced, so untouched-config installs see no behavior change.
|
|
1391
|
+
min_bytes: 8e3,
|
|
1392
|
+
fence_collapse_min_lines: 20,
|
|
1393
|
+
fence_collapse_keep_lines: 6
|
|
1394
|
+
},
|
|
1395
|
+
bash_diff: {
|
|
1396
|
+
max_hunks_per_file: 10
|
|
1397
|
+
},
|
|
1398
|
+
bash_severity_log: {
|
|
1399
|
+
context_lines: 3,
|
|
1400
|
+
score_threshold: 0.5
|
|
1401
|
+
},
|
|
1402
|
+
post_read_code_compress: {
|
|
1403
|
+
min_lines: 200
|
|
1404
|
+
},
|
|
1405
|
+
session_brief: {
|
|
1406
|
+
enabled: true
|
|
1407
|
+
},
|
|
1408
|
+
skill_preservation: {
|
|
1409
|
+
enabled: true,
|
|
1410
|
+
max_cache_bytes: 5 * 1024 * 1024,
|
|
1411
|
+
orphan_sweep_enabled: true,
|
|
1412
|
+
orphan_age_secs: 604800,
|
|
1413
|
+
truncation_budget_tokens: 800,
|
|
1414
|
+
compress_bodies: true,
|
|
1415
|
+
compress_min_bytes: 16 * 1024,
|
|
1416
|
+
inline_snippets: true,
|
|
1417
|
+
pre_skill_enabled: true,
|
|
1418
|
+
first_load_compact: false,
|
|
1419
|
+
post_compact_full_loads: false
|
|
1420
|
+
},
|
|
1421
|
+
image_shrink: {
|
|
1422
|
+
enabled: true,
|
|
1423
|
+
jpeg_quality: 75,
|
|
1424
|
+
max_image_pixels: 16e6,
|
|
1425
|
+
screenshot_redirect: true,
|
|
1426
|
+
ocr_enabled: true,
|
|
1427
|
+
// Confidence is Tesseract's own 0-100 mean-word-confidence score. 65 is a deliberately
|
|
1428
|
+
// conservative floor: a real screenshot of terminal/code/prose text routinely scores
|
|
1429
|
+
// 85+, while a photo with an incidental sign or logo in frame scores much lower and
|
|
1430
|
+
// noisier -- padding the threshold below the terminal/code norm still comfortably
|
|
1431
|
+
// excludes photographic false positives without needing a second heuristic.
|
|
1432
|
+
ocr_min_confidence: 65,
|
|
1433
|
+
ocr_lang: DEFAULT_OCR_LANG,
|
|
1434
|
+
// Which resolution tier the model being shown the image is on, which decides what its pixels
|
|
1435
|
+
// cost. 'standard' (1568px long edge, 1568 visual tokens) is every model before Claude 4.7;
|
|
1436
|
+
// 'high' (2576px, 4784 tokens) is 4.7 and later, and bills the same large image up to roughly
|
|
1437
|
+
// three times higher. Only the saving *reported* by `token-goat stats` depends on this -- no
|
|
1438
|
+
// image is encoded differently -- and 'standard' is the default because it is the floor: it
|
|
1439
|
+
// caps the counterfactual at the smaller of the two bills and so can never credit a saving
|
|
1440
|
+
// that was not there. Set it to 'high' on a Claude 4.7+ model to see the larger real figure.
|
|
1441
|
+
vision_tier: "standard"
|
|
1442
|
+
},
|
|
1443
|
+
screenshot: {
|
|
1444
|
+
chrome_path: "",
|
|
1445
|
+
block_private_targets: true
|
|
1446
|
+
},
|
|
1447
|
+
repomap: {
|
|
1448
|
+
compact_file_threshold: 50,
|
|
1449
|
+
exclude_tests: true
|
|
1450
|
+
},
|
|
1451
|
+
overflow_guard: {
|
|
1452
|
+
enabled: true,
|
|
1453
|
+
max_tokens: 25e3
|
|
1454
|
+
},
|
|
1455
|
+
stats: {
|
|
1456
|
+
record_zero_savings: false
|
|
1457
|
+
},
|
|
1458
|
+
hints: {
|
|
1459
|
+
quiet_hours: "",
|
|
1460
|
+
json_sidecar: false,
|
|
1461
|
+
min_file_lines_for_hint: 0,
|
|
1462
|
+
bash_dedup_min_bytes: 200,
|
|
1463
|
+
web_dedup_min_bytes: 200,
|
|
1464
|
+
grep_dedup_min_matches: 5,
|
|
1465
|
+
glob_dedup_min_matches: 5,
|
|
1466
|
+
// Existing on-disk file must have at least this many lines before a Write rewrite is even
|
|
1467
|
+
// considered -- rewriting a small file whole is fine, so hooks_write.ts's detector skips
|
|
1468
|
+
// comparison entirely below this floor rather than firing on trivial files.
|
|
1469
|
+
write_rewrite_min_lines: 40,
|
|
1470
|
+
// Minimum percentage of the existing file's lines that must survive unchanged (by LCS) in
|
|
1471
|
+
// the incoming Write content for hooks_write.ts to advise Edit instead. High by design: this
|
|
1472
|
+
// is only meant to catch the "mostly untouched, a few lines changed" case, not a genuine
|
|
1473
|
+
// rewrite that happens to share some boilerplate.
|
|
1474
|
+
write_rewrite_unchanged_pct: 75,
|
|
1475
|
+
serve_diff_on_reread: true,
|
|
1476
|
+
elide_served_lines: true,
|
|
1477
|
+
subagent_markdown_first_read_deny: false,
|
|
1478
|
+
backoff_thresholds: [1, 3, 10, 30],
|
|
1479
|
+
git_hint_max_ms: 50,
|
|
1480
|
+
min_session_hint_savings_bytes: 512,
|
|
1481
|
+
pre_skill_advisory: true,
|
|
1482
|
+
context_threshold_advisory: true,
|
|
1483
|
+
diff_hint_min_tokens_saved: 1e3,
|
|
1484
|
+
// Base for the pressure-scaled first-read deny gate in hooks_read.ts (large file, never read
|
|
1485
|
+
// before). Matches that gate's long-tuned 500KB threshold at 'cool' context pressure; warm/hot/
|
|
1486
|
+
// critical scale it down from there so the same read gets redirected to a surgical read sooner
|
|
1487
|
+
// once the context window is nearly full.
|
|
1488
|
+
large_read_redirect_bytes: 512e3,
|
|
1489
|
+
reread_deny: true,
|
|
1490
|
+
// Matches hooks_read.ts's previously-hardcoded REREAD_DENY_BYTES (50 * 1024) so wiring this
|
|
1491
|
+
// key up as the real gate for that logic does not silently change default behavior for
|
|
1492
|
+
// existing users -- see the reread_deny/reread_deny_min_bytes fix's commit message.
|
|
1493
|
+
reread_deny_min_bytes: 51200,
|
|
1494
|
+
stable_doc_compacts: true,
|
|
1495
|
+
// On. It has now run. The gate that finds the spans answered only from the index, and the index carried the shipping parser stamp on 46 of 17,952 files, so the lever was very nearly dead in practice: a disk parse of the delivered file is now the fallback, worth +3.0 points of withheld bytes on shell reads with no index at all. The cost side is the one this comment used to call unobservable, and it is observable: joining folds to later reads of the folded symbol scores 62.3% recovery, but the same window measured backwards scores 55.8% and a shuffled pairing scores 24.3%, so the excess attributable to the fold is 6.6 points rather than 62. Unlike every re-read mechanism beside it this rewrites a FIRST look, where the reader has no prior copy to notice an omission against, which is why the notice names the symbol and the command that returns it verbatim.
|
|
1496
|
+
fold_code_bodies: true,
|
|
1497
|
+
// On, and separate from the body fold above because the two do not carry the same risk. A body fold needs symbol spans from the index, so it can cut at the wrong line when the index is stale, and it hides the implementation an agent came to read. A comment fold reads the block boundaries off the delivered text itself, so it cannot be stale and works on the first read of a file the indexer has never seen, which is exactly the surface nothing else here reaches. It keeps the opening two lines of a block of 12 or more, so the summary sentence a reader navigates by survives and only the elaboration is replaced, and it alters the text of no line it keeps, its notice naming the absolute range removed so the recall is exact. Measured across this project's own 259 source files it removes 8.07% of the delivered bytes over 420 folds in 170 files. The nearest published measurement is stronger and cruder: removing docstrings outright cost 3 points of resolution rate on SWE-bench Verified for 22% of the tokens (arXiv:2606.01326), and keeping the opening summary is the gentler trade on that curve.
|
|
1498
|
+
fold_comment_blocks: true,
|
|
1499
|
+
// On. It has now run: measured over 2,032 real document reads it removes 43.4% of the pool and 57.4% of the reads it touches, keeping every heading, table, block quote and fenced line, and replacing only the tail of a paragraph whose opening sentence is already a complete one. The recall it needs is a ranged Read of the single line named in the notice, which costs one call and is printed at the point of the cut rather than left for the reader to work out. The project-config lock below stays regardless of this default: a repository still cannot set this key, so the choice to fold is the reader's environment and never the code being read.
|
|
1500
|
+
fold_prose_paragraphs: true,
|
|
1501
|
+
// On. Fires on an untargeted (no offset/limit) Read of a markdown document at least 8,000 bytes with at least 6 headings, replacing the delivered body with a heading tree plus the document preamble when that replacement is meaningfully smaller. Built from the delivered text itself, never the index, so it works on a document the indexer has never seen. Measured over 5,104 real session transcripts (13,870 Read deliveries, 130,249,204 bytes): untargeted markdown reads with >=6 headings at this 8,000-byte floor withhold 41.03% of all Read bytes, within 1.8 points of the best floor tried (2,000 B) while firing far less often on small documents where the interruption is least worth it.
|
|
1502
|
+
outline_large_documents: true,
|
|
1503
|
+
// On. The source-code sibling of outline_large_documents directly above, and gated the same way: an untargeted (no offset/limit) Read of a tree-sitter language at least 12,000 bytes with at least 8 symbols is replaced by its structural skeleton, the preamble plus one declaration line per symbol, with each withheld run named and pointed at the command that returns it. Symbols come from tree-sitter over the delivered text, never the index and never the regex extractors, so a partial symbol list turns the fold off rather than shipping a skeleton missing declarations nothing signals. Measured over 5,104 real session transcripts (130,325,670 delivered Read bytes): 558 reads clear this floor, and the fold withholds 11,241,796 B, 8.63% of all Read bytes.
|
|
1504
|
+
skeleton_large_sources: true,
|
|
1505
|
+
truncated_read_min_lines: 200,
|
|
1506
|
+
protect_recent_reads: 4,
|
|
1507
|
+
warn_unbalanced_shell_quoting: true,
|
|
1508
|
+
prompt_triggers: [],
|
|
1509
|
+
log_large_file_hint_outcomes: false,
|
|
1510
|
+
cross_session_read_dedup: false,
|
|
1511
|
+
cross_session_read_dedup_ttl_secs: 2700,
|
|
1512
|
+
mcp_dedup_ttl_secs: 45,
|
|
1513
|
+
session_start_reminder: true
|
|
1514
|
+
},
|
|
1515
|
+
hooks: {
|
|
1516
|
+
watchdog_ms: 700
|
|
1517
|
+
},
|
|
1518
|
+
webfetch: {
|
|
1519
|
+
allow: [],
|
|
1520
|
+
deny: [],
|
|
1521
|
+
max_file_count: 4096,
|
|
1522
|
+
max_bytes: 32 * 1024 * 1024,
|
|
1523
|
+
compress_bodies: true,
|
|
1524
|
+
compress_min_bytes: 16 * 1024
|
|
1525
|
+
},
|
|
1526
|
+
worker: {
|
|
1527
|
+
blocked_roots: [],
|
|
1528
|
+
max_pool_workers: 4,
|
|
1529
|
+
// 4, not 2. Measured on a 26-core Windows host with a foreground CPU probe: at `priority`
|
|
1530
|
+
// below_normal, 2, 4 and 6 threads are all indistinguishable from an idle machine, including
|
|
1531
|
+
// when the indexer and the probe are pinned to the same 4 cores, and including 4 threads pinned
|
|
1532
|
+
// to 2 cores, which is genuine oversubscription. The same probe reads -10% at 16 threads and
|
|
1533
|
+
// -69% with a 292 ms stall at 4 threads on 2 cores once the priority is normal instead. So the
|
|
1534
|
+
// priority below is what keeps the foreground responsive, not this number, and 4 buys a
|
|
1535
|
+
// measured 1.77x on indexing for no foreground cost. It stays a cap rather than tracking the
|
|
1536
|
+
// core count, because where the platform refuses the priority change (some hardened Linux
|
|
1537
|
+
// setups, sandboxes) this is the only thing left holding indexing back.
|
|
1538
|
+
embed_threads: 4,
|
|
1539
|
+
priority: "below_normal"
|
|
1540
|
+
},
|
|
1541
|
+
indexing: {
|
|
1542
|
+
large_file_symbol_only_kb: 500,
|
|
1543
|
+
large_file_skip_kb: 2048,
|
|
1544
|
+
skip_dirs: [],
|
|
1545
|
+
skip_files: ["coverage.json", "coverage-final.json"],
|
|
1546
|
+
embeddings_enabled: true,
|
|
1547
|
+
cross_project_symbols: true
|
|
1548
|
+
},
|
|
1549
|
+
compression: {
|
|
1550
|
+
profile: "auto"
|
|
1551
|
+
},
|
|
1552
|
+
context: {
|
|
1553
|
+
model_window_tokens: 2e5
|
|
1554
|
+
},
|
|
1555
|
+
injection: {
|
|
1556
|
+
enabled: true
|
|
1557
|
+
},
|
|
1558
|
+
gdrive: {
|
|
1559
|
+
enabled: true
|
|
1560
|
+
},
|
|
1561
|
+
redaction: {
|
|
1562
|
+
custom_patterns: [],
|
|
1563
|
+
strict: false
|
|
1564
|
+
},
|
|
1565
|
+
network: {
|
|
1566
|
+
offline: false
|
|
1567
|
+
},
|
|
1568
|
+
mcp: {
|
|
1569
|
+
confine_reads_to_project_root: true,
|
|
1570
|
+
allowed_roots: []
|
|
1571
|
+
},
|
|
1572
|
+
hint_stats: {
|
|
1573
|
+
suppress_threshold_pct: 15,
|
|
1574
|
+
min_sample_size: 5
|
|
1575
|
+
},
|
|
1576
|
+
semantic: {
|
|
1577
|
+
archive_weight: 0.7,
|
|
1578
|
+
docs_weight: 0.92
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
function getDefaultConfig(section2) {
|
|
1582
|
+
return structuredClone(CONFIG_DEFAULTS[section2] ?? {});
|
|
1583
|
+
}
|
|
1584
|
+
function defaultConfig() {
|
|
1585
|
+
return {
|
|
1586
|
+
compact_assist: getDefaultConfig("compact_assist"),
|
|
1587
|
+
bash_compress: getDefaultConfig("bash_compress"),
|
|
1588
|
+
agent_report: getDefaultConfig("agent_report"),
|
|
1589
|
+
bash_diff: getDefaultConfig("bash_diff"),
|
|
1590
|
+
bash_severity_log: getDefaultConfig("bash_severity_log"),
|
|
1591
|
+
post_read_code_compress: getDefaultConfig("post_read_code_compress"),
|
|
1592
|
+
session_brief: getDefaultConfig("session_brief"),
|
|
1593
|
+
skill_preservation: getDefaultConfig("skill_preservation"),
|
|
1594
|
+
image_shrink: getDefaultConfig("image_shrink"),
|
|
1595
|
+
screenshot: getDefaultConfig("screenshot"),
|
|
1596
|
+
repomap: getDefaultConfig("repomap"),
|
|
1597
|
+
overflow_guard: getDefaultConfig("overflow_guard"),
|
|
1598
|
+
stats: getDefaultConfig("stats"),
|
|
1599
|
+
hints: getDefaultConfig("hints"),
|
|
1600
|
+
hooks: getDefaultConfig("hooks"),
|
|
1601
|
+
webfetch: getDefaultConfig("webfetch"),
|
|
1602
|
+
worker: getDefaultConfig("worker"),
|
|
1603
|
+
indexing: getDefaultConfig("indexing"),
|
|
1604
|
+
compression: getDefaultConfig("compression"),
|
|
1605
|
+
context: getDefaultConfig("context"),
|
|
1606
|
+
injection: getDefaultConfig("injection"),
|
|
1607
|
+
gdrive: getDefaultConfig("gdrive"),
|
|
1608
|
+
redaction: getDefaultConfig("redaction"),
|
|
1609
|
+
network: getDefaultConfig("network"),
|
|
1610
|
+
mcp: getDefaultConfig("mcp"),
|
|
1611
|
+
hint_stats: getDefaultConfig("hint_stats"),
|
|
1612
|
+
semantic: getDefaultConfig("semantic")
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
// src/config.ts
|
|
1617
|
+
function validatedBool(raw, def) {
|
|
1618
|
+
if (typeof raw === "boolean") return raw;
|
|
1619
|
+
return def;
|
|
1620
|
+
}
|
|
1621
|
+
function validatedInt(raw, def, min, max) {
|
|
1622
|
+
const n = typeof raw === "number" ? Math.trunc(raw) : def;
|
|
1623
|
+
if (!Number.isFinite(n)) return def;
|
|
1624
|
+
return Math.max(min, Math.min(max, n));
|
|
1625
|
+
}
|
|
1626
|
+
function validatedFloat(raw, def, min, max) {
|
|
1627
|
+
const n = typeof raw === "number" ? raw : def;
|
|
1628
|
+
if (!Number.isFinite(n)) return def;
|
|
1629
|
+
return Math.max(min, Math.min(max, n));
|
|
1630
|
+
}
|
|
1631
|
+
function validatedVisionTier(raw, def) {
|
|
1632
|
+
return raw === "standard" || raw === "high" ? raw : def;
|
|
1633
|
+
}
|
|
1634
|
+
function validatedOcrLang(raw, def) {
|
|
1635
|
+
if (typeof raw !== "string") return def;
|
|
1636
|
+
const tokens = raw.split(/[+,;\s]+/).map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
1637
|
+
const valid = tokens.filter((t) => isSupportedOcrLang(t));
|
|
1638
|
+
return valid.length > 0 ? valid.join("+") : def;
|
|
1639
|
+
}
|
|
1640
|
+
function validatedStr(raw, def) {
|
|
1641
|
+
return typeof raw === "string" ? raw : def;
|
|
1642
|
+
}
|
|
1643
|
+
function validatedStrList(raw, def) {
|
|
1644
|
+
if (!Array.isArray(raw)) return def;
|
|
1645
|
+
return raw.filter((x) => typeof x === "string");
|
|
1646
|
+
}
|
|
1647
|
+
function validatedIntList(raw, def) {
|
|
1648
|
+
if (!Array.isArray(raw)) return def;
|
|
1649
|
+
return raw.filter((x) => typeof x === "number" && Number.isFinite(x)).map(Math.trunc);
|
|
1650
|
+
}
|
|
1651
|
+
function validatedIntWithLegacySentinel(raw, def, sentinel, min, max) {
|
|
1652
|
+
return raw === sentinel ? def : validatedInt(raw, def, min, max);
|
|
1653
|
+
}
|
|
1654
|
+
function section(raw, key) {
|
|
1655
|
+
const val = raw[key];
|
|
1656
|
+
return val !== null && typeof val === "object" && !Array.isArray(val) ? val : {};
|
|
1657
|
+
}
|
|
1658
|
+
var NUMERIC_FIELD_BOUNDS = {
|
|
1659
|
+
"compact_assist.min_events": { min: 0, max: 1e3 },
|
|
1660
|
+
"compact_assist.max_manifest_tokens": { min: 50, max: 1e4 },
|
|
1661
|
+
"compact_assist.auto_trigger_multiplier": { min: 1, max: 10 },
|
|
1662
|
+
"compact_assist.compact_skip_ttl_secs": { min: 1, max: 3600 },
|
|
1663
|
+
"compact_assist.noise_floor_tokens": { min: 0, max: 1e4 },
|
|
1664
|
+
"compact_assist.edited_dir_group_threshold": { min: 0, max: 100 },
|
|
1665
|
+
"compact_assist.max_section_lines": { min: 0, max: 1e4 },
|
|
1666
|
+
"compact_assist.wide_session_threshold": { min: 1, max: 1e4 },
|
|
1667
|
+
"compact_assist.orchestrator_commit_threshold": { min: 1, max: 1e4 },
|
|
1668
|
+
"compact_assist.max_manifest_chars": { min: 0, max: 16e3 },
|
|
1669
|
+
"compact_assist.summary_budget_chars": { min: 0, max: 2e5 },
|
|
1670
|
+
"bash_compress.max_lines": { min: 50, max: 1e5 },
|
|
1671
|
+
"bash_compress.max_bytes": { min: 1024, max: 16 * 1024 * 1024 },
|
|
1672
|
+
"bash_compress.timeout_seconds": { min: 5, max: 7200 },
|
|
1673
|
+
"bash_compress.cache_min_bytes": { min: 0, max: 100 * 1024 * 1024 },
|
|
1674
|
+
"bash_compress.cache_max_file_count": { min: 1, max: 1e6 },
|
|
1675
|
+
"bash_compress.cache_max_bytes": { min: 1024, max: 4 * 1024 * 1024 * 1024 },
|
|
1676
|
+
"bash_compress.cache_max_bytes_per_output": { min: 1024, max: 4 * 1024 * 1024 * 1024, clampTo: "bash_compress.cache_max_bytes" },
|
|
1677
|
+
"bash_compress.min_net_savings_bytes": { min: 0, max: 1024 * 1024 },
|
|
1678
|
+
"agent_report.min_bytes": { min: 0, max: 100 * 1024 * 1024 },
|
|
1679
|
+
"agent_report.fence_collapse_min_lines": { min: 1, max: 1e5 },
|
|
1680
|
+
// Bounded below the min-lines floor's own minimum is NOT enforceable here (bounds are per-key), so the loader clamps keep_lines against min_lines after both are read -- see the clamp comment there.
|
|
1681
|
+
"agent_report.fence_collapse_keep_lines": { min: 0, max: 1e5 },
|
|
1682
|
+
"bash_diff.max_hunks_per_file": { min: 1, max: 1e4 },
|
|
1683
|
+
"bash_severity_log.context_lines": { min: 0, max: 100 },
|
|
1684
|
+
"bash_severity_log.score_threshold": { min: 0, max: 1 },
|
|
1685
|
+
"post_read_code_compress.min_lines": { min: 0, max: 1e6 },
|
|
1686
|
+
"skill_preservation.max_cache_bytes": { min: 64 * 1024, max: 512 * 1024 * 1024 },
|
|
1687
|
+
"skill_preservation.orphan_age_secs": { min: 1, max: 2592e3 },
|
|
1688
|
+
"skill_preservation.truncation_budget_tokens": { min: 0, max: 8e3 },
|
|
1689
|
+
"skill_preservation.compress_min_bytes": { min: 1024, max: 10 * 1024 * 1024 },
|
|
1690
|
+
"image_shrink.jpeg_quality": { min: 1, max: 100 },
|
|
1691
|
+
"image_shrink.max_image_pixels": { min: 0, max: 1e9 },
|
|
1692
|
+
"image_shrink.ocr_min_confidence": { min: 0, max: 100 },
|
|
1693
|
+
"repomap.compact_file_threshold": { min: 0, max: 1e5 },
|
|
1694
|
+
"overflow_guard.max_tokens": { min: 1e3, max: 1e6 },
|
|
1695
|
+
"hints.min_file_lines_for_hint": { min: 0, max: 1e6 },
|
|
1696
|
+
"hints.bash_dedup_min_bytes": { min: 0, max: 1e5 },
|
|
1697
|
+
"hints.web_dedup_min_bytes": { min: 0, max: 1e5 },
|
|
1698
|
+
"hints.grep_dedup_min_matches": { min: 0, max: 1e5 },
|
|
1699
|
+
"hints.glob_dedup_min_matches": { min: 0, max: 1e5 },
|
|
1700
|
+
"hints.write_rewrite_min_lines": { min: 0, max: 1e6 },
|
|
1701
|
+
"hints.write_rewrite_unchanged_pct": { min: 0, max: 100 },
|
|
1702
|
+
"hints.git_hint_max_ms": { min: 0, max: 1e4 },
|
|
1703
|
+
"hints.min_session_hint_savings_bytes": { min: 0, max: 1e6 },
|
|
1704
|
+
"hints.diff_hint_min_tokens_saved": { min: 0, max: 1e5 },
|
|
1705
|
+
"hints.large_read_redirect_bytes": { min: 0, max: 1e8 },
|
|
1706
|
+
"hints.reread_deny_min_bytes": { min: 0, max: 1e8 },
|
|
1707
|
+
"hints.truncated_read_min_lines": { min: 0, max: 1e6 },
|
|
1708
|
+
"hints.protect_recent_reads": { min: 0, max: 100 },
|
|
1709
|
+
"hints.cross_session_read_dedup_ttl_secs": { min: 1, max: 86400 },
|
|
1710
|
+
"hints.mcp_dedup_ttl_secs": { min: 1, max: 3600 },
|
|
1711
|
+
"hooks.watchdog_ms": { min: 100, max: 3e4 },
|
|
1712
|
+
"webfetch.max_file_count": { min: 0, max: 1e7 },
|
|
1713
|
+
"webfetch.max_bytes": { min: 0, max: 100 * 1024 * 1024 * 1024 },
|
|
1714
|
+
"webfetch.compress_min_bytes": { min: 1024, max: 10 * 1024 * 1024 },
|
|
1715
|
+
"worker.max_pool_workers": { min: 1, max: 8 },
|
|
1716
|
+
"worker.embed_threads": { min: 1, max: 16 },
|
|
1717
|
+
"indexing.large_file_symbol_only_kb": { min: 1, max: 1048576, clampTo: "indexing.large_file_skip_kb" },
|
|
1718
|
+
"indexing.large_file_skip_kb": { min: 1, max: 1048576 },
|
|
1719
|
+
"context.model_window_tokens": { min: 1e4, max: 1e7 },
|
|
1720
|
+
"hint_stats.suppress_threshold_pct": { min: 0, max: 100 },
|
|
1721
|
+
"hint_stats.min_sample_size": { min: 1, max: 1e4 },
|
|
1722
|
+
"semantic.archive_weight": { min: 0.05, max: 1 },
|
|
1723
|
+
"semantic.docs_weight": { min: 0.05, max: 1 }
|
|
1724
|
+
};
|
|
1725
|
+
function boundsOf(key) {
|
|
1726
|
+
const b = NUMERIC_FIELD_BOUNDS[key];
|
|
1727
|
+
if (!b) throw new Error(`token-goat: no NUMERIC_FIELD_BOUNDS entry for '${key}'`);
|
|
1728
|
+
return [b.min, b.max];
|
|
1729
|
+
}
|
|
1730
|
+
function walkGetNumeric(obj, parts) {
|
|
1731
|
+
let cur = obj;
|
|
1732
|
+
for (const part of parts) {
|
|
1733
|
+
if (typeof cur !== "object" || cur === null) return void 0;
|
|
1734
|
+
cur = cur[part];
|
|
1735
|
+
if (cur === void 0) return void 0;
|
|
1736
|
+
}
|
|
1737
|
+
return typeof cur === "number" ? cur : void 0;
|
|
1738
|
+
}
|
|
1739
|
+
function validateNumericField(fieldKey, value, cfg) {
|
|
1740
|
+
const bounds = NUMERIC_FIELD_BOUNDS[fieldKey];
|
|
1741
|
+
if (!bounds) return void 0;
|
|
1742
|
+
let clamped = Math.max(bounds.min, Math.min(bounds.max, value));
|
|
1743
|
+
if (bounds.clampTo) {
|
|
1744
|
+
const clampToValue = walkGetNumeric(cfg, bounds.clampTo.split("."));
|
|
1745
|
+
if (typeof clampToValue === "number") {
|
|
1746
|
+
clamped = Math.min(clamped, clampToValue);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
return clamped;
|
|
1750
|
+
}
|
|
1751
|
+
var ENUM_FIELD_VALUES = {
|
|
1752
|
+
"compression.profile": ["auto", "aggressive", "balanced", "minimal"],
|
|
1753
|
+
"compact_assist.harness": ["auto", ...KNOWN_HARNESS_NAMES],
|
|
1754
|
+
"image_shrink.ocr_lang": [...SUPPORTED_OCR_LANG_CODES],
|
|
1755
|
+
// Deliberately has no entry above `normal`. This table is what `config set` checks; a
|
|
1756
|
+
// hand-edited TOML bypasses it, which is why resolveWorkerPriority (process_priority.ts) maps an
|
|
1757
|
+
// unrecognized value back to the default rather than trusting whatever the file said.
|
|
1758
|
+
"worker.priority": ["below_normal", "low", "normal"]
|
|
1759
|
+
};
|
|
1760
|
+
function validateEnumField(fieldKey, value) {
|
|
1761
|
+
if (fieldKey === "image_shrink.ocr_lang") {
|
|
1762
|
+
const tokens = value.split(/[+,;\s]+/).map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
1763
|
+
const allowed2 = [...SUPPORTED_OCR_LANG_CODES];
|
|
1764
|
+
return tokens.length > 0 && tokens.every((t) => isSupportedOcrLang(t)) ? void 0 : allowed2;
|
|
1765
|
+
}
|
|
1766
|
+
const allowed = ENUM_FIELD_VALUES[fieldKey];
|
|
1767
|
+
if (!allowed) return void 0;
|
|
1768
|
+
return allowed.includes(value) ? void 0 : allowed;
|
|
1769
|
+
}
|
|
1770
|
+
var ENV_KEYS2 = [
|
|
1771
|
+
"TOKEN_GOAT_COMPACT_ASSIST",
|
|
1772
|
+
"TOKENWISE_COMPACT_ASSIST",
|
|
1773
|
+
"TOKEN_GOAT_BASH_COMPRESS",
|
|
1774
|
+
"TOKEN_GOAT_SESSION_BRIEF",
|
|
1775
|
+
"TOKEN_GOAT_SKILL_PRESERVATION",
|
|
1776
|
+
"TOKEN_GOAT_MAX_IMAGE_PIXELS",
|
|
1777
|
+
"TOKEN_GOAT_OCR_LANG",
|
|
1778
|
+
"TOKEN_GOAT_REPOMAP_COMPACT_THRESHOLD",
|
|
1779
|
+
"TOKEN_GOAT_REPOMAP_EXCLUDE_TESTS",
|
|
1780
|
+
"TOKEN_GOAT_OVERFLOW_GUARD",
|
|
1781
|
+
"TOKEN_GOAT_OVERFLOW_MAX_TOKENS",
|
|
1782
|
+
"TOKEN_GOAT_HINT_JSON_SIDECAR",
|
|
1783
|
+
"TOKEN_GOAT_LARGE_READ_BYTES",
|
|
1784
|
+
"TOKEN_GOAT_HINT_BUDGET",
|
|
1785
|
+
"TOKEN_GOAT_HOOK_WATCHDOG_MS",
|
|
1786
|
+
"TOKEN_GOAT_WEB_COMPRESS",
|
|
1787
|
+
"TOKEN_GOAT_WORKER_WATCHDOG",
|
|
1788
|
+
"TOKEN_GOAT_WORKER_MAX_POOL",
|
|
1789
|
+
"TOKEN_GOAT_COMPRESS_PROFILE",
|
|
1790
|
+
"TOKEN_GOAT_MODEL_WINDOW_TOKENS",
|
|
1791
|
+
"TOKEN_GOAT_INJECTION_ENABLED",
|
|
1792
|
+
"TOKEN_GOAT_MCP_CONFINE_READS",
|
|
1793
|
+
"TOKEN_GOAT_SERVE_DIFF_ON_REREAD",
|
|
1794
|
+
"TOKEN_GOAT_ELIDE_SERVED_LINES",
|
|
1795
|
+
"TOKEN_GOAT_BASH_CACHE_MIN_BYTES",
|
|
1796
|
+
"TOKEN_GOAT_BASH_CACHE_MAX_FILES",
|
|
1797
|
+
"TOKEN_GOAT_BASH_CACHE_MAX_BYTES",
|
|
1798
|
+
"TOKEN_GOAT_BASH_CACHE_MAX_BYTES_PER_OUTPUT",
|
|
1799
|
+
"TOKEN_GOAT_SESSION_HINT_MIN_BYTES",
|
|
1800
|
+
"TOKEN_GOAT_SKILL_COMPRESS",
|
|
1801
|
+
"TOKEN_GOAT_PRE_SKILL",
|
|
1802
|
+
"TOKEN_GOAT_ORPHAN_SWEEP",
|
|
1803
|
+
"TOKEN_GOAT_WARN_UNBALANCED_SHELL_QUOTING",
|
|
1804
|
+
"TOKEN_GOAT_LOG_LARGE_FILE_HINT_OUTCOMES",
|
|
1805
|
+
"TOKEN_GOAT_CROSS_SESSION_READ_DEDUP",
|
|
1806
|
+
"TOKEN_GOAT_CROSS_SESSION_READ_DEDUP_TTL_SECS",
|
|
1807
|
+
"TOKEN_GOAT_MCP_DEDUP_TTL_SECS",
|
|
1808
|
+
"TOKEN_GOAT_EMBEDDINGS_ENABLED",
|
|
1809
|
+
"TOKEN_GOAT_BASH_DEDUP_MIN_BYTES",
|
|
1810
|
+
"TOKEN_GOAT_WEB_DEDUP_MIN_BYTES",
|
|
1811
|
+
"TOKEN_GOAT_GREP_DEDUP_MIN_MATCHES",
|
|
1812
|
+
"TOKEN_GOAT_WEB_CACHE_MAX_FILES",
|
|
1813
|
+
"TOKEN_GOAT_WEB_CACHE_MAX_BYTES",
|
|
1814
|
+
"TOKEN_GOAT_WRITE_REWRITE_MIN_LINES",
|
|
1815
|
+
"TOKEN_GOAT_WRITE_REWRITE_UNCHANGED_PCT"
|
|
1816
|
+
];
|
|
1817
|
+
function allEnvKeys() {
|
|
1818
|
+
return [.../* @__PURE__ */ new Set([...ENV_KEYS2, ...Object.values(CONFIG_KEY_ENV_OVERRIDES).flat()])];
|
|
1819
|
+
}
|
|
1820
|
+
function configEnvFingerprint() {
|
|
1821
|
+
const snap = {};
|
|
1822
|
+
for (const k of allEnvKeys()) {
|
|
1823
|
+
snap[k] = process.env[k];
|
|
1824
|
+
}
|
|
1825
|
+
return JSON.stringify(snap);
|
|
1826
|
+
}
|
|
1827
|
+
var _cached2 = null;
|
|
1828
|
+
function deepFreeze(value) {
|
|
1829
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
1830
|
+
Object.freeze(value);
|
|
1831
|
+
for (const v of Object.values(value)) {
|
|
1832
|
+
deepFreeze(v);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
return value;
|
|
1836
|
+
}
|
|
1837
|
+
var _lastConfigParseError = null;
|
|
1838
|
+
function getLastConfigParseError() {
|
|
1839
|
+
return _lastConfigParseError;
|
|
1840
|
+
}
|
|
1841
|
+
var _lastProjectConfigParseError = null;
|
|
1842
|
+
function getLastProjectConfigParseError() {
|
|
1843
|
+
return _lastProjectConfigParseError;
|
|
1844
|
+
}
|
|
1845
|
+
function rawValueEquals(a, b) {
|
|
1846
|
+
if (a === b) return true;
|
|
1847
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
1848
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
1849
|
+
return a.every((el, i) => rawValueEquals(el, b[i]));
|
|
1850
|
+
}
|
|
1851
|
+
if (typeof a === "object" && typeof b === "object" && a !== null && b !== null) {
|
|
1852
|
+
const ka = Object.keys(a);
|
|
1853
|
+
const kb = Object.keys(b);
|
|
1854
|
+
if (ka.length !== kb.length) return false;
|
|
1855
|
+
return ka.every((k) => Object.prototype.hasOwnProperty.call(b, k) && rawValueEquals(a[k], b[k]));
|
|
1856
|
+
}
|
|
1857
|
+
return false;
|
|
1858
|
+
}
|
|
1859
|
+
function rejectionReason(key, rawValue, effectiveValue, cfg) {
|
|
1860
|
+
if (typeof rawValue === "number") {
|
|
1861
|
+
const bounds = NUMERIC_FIELD_BOUNDS[key];
|
|
1862
|
+
if (bounds !== void 0) {
|
|
1863
|
+
if (rawValue < bounds.min || rawValue > bounds.max) return `outside the allowed range ${bounds.min}-${bounds.max}`;
|
|
1864
|
+
if (!Number.isInteger(rawValue) && Number.isInteger(effectiveValue)) return "not a whole number";
|
|
1865
|
+
const clamped = validateNumericField(key, rawValue, cfg);
|
|
1866
|
+
if (clamped !== void 0 && clamped !== rawValue && bounds.clampTo !== void 0) return `above ${bounds.clampTo}, which caps it`;
|
|
1867
|
+
}
|
|
1868
|
+
return null;
|
|
1869
|
+
}
|
|
1870
|
+
if (typeof rawValue === "string") {
|
|
1871
|
+
const allowed = validateEnumField(key, rawValue);
|
|
1872
|
+
if (allowed !== void 0) return `not one of: ${allowed.join(", ")}`;
|
|
1873
|
+
}
|
|
1874
|
+
if (effectiveValue !== void 0 && typeof rawValue !== typeof effectiveValue) {
|
|
1875
|
+
return `expected ${Array.isArray(effectiveValue) ? "a list" : `a ${typeof effectiveValue}`}, got ${Array.isArray(rawValue) ? "a list" : `a ${typeof rawValue}`}`;
|
|
1876
|
+
}
|
|
1877
|
+
return null;
|
|
1878
|
+
}
|
|
1879
|
+
function coerceEnvLike(rawStr, effectiveValue) {
|
|
1880
|
+
const norm = rawStr.trim();
|
|
1881
|
+
if (typeof effectiveValue === "number") {
|
|
1882
|
+
if (norm === "" || !/^[+-]?\d+$/.test(norm)) return "unusable";
|
|
1883
|
+
const val = parseInt(norm, 10);
|
|
1884
|
+
return Number.isFinite(val) ? { parsed: val } : "unusable";
|
|
1885
|
+
}
|
|
1886
|
+
if (typeof effectiveValue === "boolean") {
|
|
1887
|
+
const lower = norm.toLowerCase();
|
|
1888
|
+
if (TRUTHY_ENV_VALUES.has(lower)) return { parsed: true };
|
|
1889
|
+
if (FALSY_ENV_VALUES.has(lower)) return { parsed: false };
|
|
1890
|
+
return "unusable";
|
|
1891
|
+
}
|
|
1892
|
+
if (typeof effectiveValue === "string") {
|
|
1893
|
+
return norm === "" ? "unusable" : { parsed: norm };
|
|
1894
|
+
}
|
|
1895
|
+
return null;
|
|
1896
|
+
}
|
|
1897
|
+
function resolveConfigKeyLayer(key, effectiveValue, cfg, projectInfo) {
|
|
1898
|
+
const envVar = (CONFIG_KEY_ENV_OVERRIDES[key] ?? []).find((name) => process.env[name] !== void 0);
|
|
1899
|
+
if (envVar !== void 0) {
|
|
1900
|
+
const rawStr = process.env[envVar] ?? "";
|
|
1901
|
+
const judged = coerceEnvLike(rawStr, effectiveValue);
|
|
1902
|
+
if (judged === null) return { layer: "env", envVar };
|
|
1903
|
+
if (judged === "unusable") {
|
|
1904
|
+
return { layer: "env-invalid", envVar, rawValue: rawStr, effectiveValue, reason: rawStr.trim() === "" ? "empty" : rejectionReason(key, rawStr, effectiveValue, cfg) };
|
|
1905
|
+
}
|
|
1906
|
+
if (rawValueEquals(judged.parsed, effectiveValue)) return { layer: "env", envVar };
|
|
1907
|
+
return { layer: "env-invalid", envVar, rawValue: judged.parsed, effectiveValue, reason: rejectionReason(key, judged.parsed, effectiveValue, cfg) };
|
|
1908
|
+
}
|
|
1909
|
+
if (projectInfo === null) return { layer: "global" };
|
|
1910
|
+
if (projectInfo.parseError !== null) return { layer: "project-unparsed", path: projectInfo.path, parseError: projectInfo.parseError };
|
|
1911
|
+
if (!Object.prototype.hasOwnProperty.call(projectInfo.values, key)) return { layer: "global" };
|
|
1912
|
+
const rawValue = projectInfo.values[key];
|
|
1913
|
+
if (rawValueEquals(rawValue, effectiveValue)) return { layer: "project", path: projectInfo.path };
|
|
1914
|
+
return { layer: "project-invalid", path: projectInfo.path, rawValue, effectiveValue, reason: rejectionReason(key, rawValue, effectiveValue, cfg) };
|
|
1915
|
+
}
|
|
1916
|
+
function loadConfig(projectRoot) {
|
|
1917
|
+
const p = configPath();
|
|
1918
|
+
const root = projectRoot ?? resolveConfigProjectRoot();
|
|
1919
|
+
const projPath = projectConfigPath(root);
|
|
1920
|
+
const { text, readError } = readConfigText(p);
|
|
1921
|
+
const contentFp = text !== null ? shortFingerprint(text) : "";
|
|
1922
|
+
const { text: projText, readError: projReadError } = readConfigText(projPath);
|
|
1923
|
+
const projectContentFp = projText !== null ? shortFingerprint(projText) : "";
|
|
1924
|
+
const envFp = configEnvFingerprint();
|
|
1925
|
+
if (_cached2 !== null && _cached2.contentFp === contentFp && _cached2.envFp === envFp && _cached2.projectRoot === root && _cached2.projectContentFp === projectContentFp) {
|
|
1926
|
+
return _cached2.config;
|
|
1927
|
+
}
|
|
1928
|
+
let raw = {};
|
|
1929
|
+
if (text !== null) {
|
|
1930
|
+
try {
|
|
1931
|
+
raw = parse(text);
|
|
1932
|
+
_lastConfigParseError = null;
|
|
1933
|
+
} catch (e) {
|
|
1934
|
+
_lastConfigParseError = extractErrorMessage(e);
|
|
1935
|
+
}
|
|
1936
|
+
} else {
|
|
1937
|
+
_lastConfigParseError = readError;
|
|
1938
|
+
}
|
|
1939
|
+
let projectRaw = {};
|
|
1940
|
+
if (projText !== null) {
|
|
1941
|
+
try {
|
|
1942
|
+
projectRaw = parse(projText);
|
|
1943
|
+
_lastProjectConfigParseError = null;
|
|
1944
|
+
} catch (e) {
|
|
1945
|
+
_lastProjectConfigParseError = extractErrorMessage(e);
|
|
1946
|
+
}
|
|
1947
|
+
} else {
|
|
1948
|
+
_lastProjectConfigParseError = projReadError;
|
|
1949
|
+
}
|
|
1950
|
+
const cfg = deepFreeze(_buildConfig(raw, projectRaw));
|
|
1951
|
+
_cached2 = { config: cfg, contentFp, envFp, projectRoot: root, projectContentFp };
|
|
1952
|
+
return cfg;
|
|
1953
|
+
}
|
|
1954
|
+
function invalidateConfigCache() {
|
|
1955
|
+
_cached2 = null;
|
|
1956
|
+
resetLastProjectConfigLockedKeys();
|
|
1957
|
+
}
|
|
1958
|
+
registerReset(invalidateConfigCache);
|
|
1959
|
+
function withoutConfigEnv(fn) {
|
|
1960
|
+
const keys = allEnvKeys();
|
|
1961
|
+
const saved = {};
|
|
1962
|
+
for (const k of keys) {
|
|
1963
|
+
saved[k] = process.env[k];
|
|
1964
|
+
delete process.env[k];
|
|
1965
|
+
}
|
|
1966
|
+
try {
|
|
1967
|
+
return fn();
|
|
1968
|
+
} finally {
|
|
1969
|
+
for (const k of keys) {
|
|
1970
|
+
const v = saved[k];
|
|
1971
|
+
if (v === void 0) delete process.env[k];
|
|
1972
|
+
else process.env[k] = v;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
function buildPersistedConfig(raw) {
|
|
1977
|
+
return withoutConfigEnv(() => _buildConfig(raw));
|
|
1978
|
+
}
|
|
1979
|
+
function loadPersistedConfig() {
|
|
1980
|
+
const p = configPath();
|
|
1981
|
+
const { raw, parseError } = readConfigToml(p);
|
|
1982
|
+
_lastConfigParseError = parseError;
|
|
1983
|
+
return buildPersistedConfig(raw);
|
|
1984
|
+
}
|
|
1985
|
+
function _buildConfig(raw, projectRaw = {}) {
|
|
1986
|
+
const { cleaned: safeProjectRaw, dropped: lockedKeys } = stripLockedProjectKeys(projectRaw);
|
|
1987
|
+
setLastProjectConfigLockedKeys(lockedKeys);
|
|
1988
|
+
if (Object.keys(safeProjectRaw).length > 0) {
|
|
1989
|
+
raw = mergeRawConfig(raw, safeProjectRaw);
|
|
1990
|
+
}
|
|
1991
|
+
const ca_raw = section(raw, "compact_assist");
|
|
1992
|
+
const ca = getDefaultConfig("compact_assist");
|
|
1993
|
+
ca.enabled = validatedBool(ca_raw["enabled"], ca.enabled);
|
|
1994
|
+
ca.triggers = validatedStrList(ca_raw["triggers"], ca.triggers);
|
|
1995
|
+
ca.min_events = validatedInt(ca_raw["min_events"], ca.min_events, ...boundsOf("compact_assist.min_events"));
|
|
1996
|
+
ca.max_manifest_tokens = validatedInt(ca_raw["max_manifest_tokens"], ca.max_manifest_tokens, ...boundsOf("compact_assist.max_manifest_tokens"));
|
|
1997
|
+
ca.auto_trigger_multiplier = validatedFloat(ca_raw["auto_trigger_multiplier"], ca.auto_trigger_multiplier, ...boundsOf("compact_assist.auto_trigger_multiplier"));
|
|
1998
|
+
ca.compact_skip_ttl_secs = validatedFloat(ca_raw["compact_skip_ttl_secs"], ca.compact_skip_ttl_secs, ...boundsOf("compact_assist.compact_skip_ttl_secs"));
|
|
1999
|
+
ca.noise_floor_tokens = validatedInt(ca_raw["noise_floor_tokens"], ca.noise_floor_tokens, ...boundsOf("compact_assist.noise_floor_tokens"));
|
|
2000
|
+
ca.edited_dir_group_threshold = validatedInt(ca_raw["edited_dir_group_threshold"], ca.edited_dir_group_threshold, ...boundsOf("compact_assist.edited_dir_group_threshold"));
|
|
2001
|
+
ca.max_section_lines = validatedInt(ca_raw["max_section_lines"], ca.max_section_lines, ...boundsOf("compact_assist.max_section_lines"));
|
|
2002
|
+
ca.wide_session_threshold = validatedInt(ca_raw["wide_session_threshold"], ca.wide_session_threshold, ...boundsOf("compact_assist.wide_session_threshold"));
|
|
2003
|
+
ca.orchestrator_commit_threshold = validatedInt(ca_raw["orchestrator_commit_threshold"], ca.orchestrator_commit_threshold, ...boundsOf("compact_assist.orchestrator_commit_threshold"));
|
|
2004
|
+
ca.max_manifest_chars = validatedInt(ca_raw["max_manifest_chars"], ca.max_manifest_chars, ...boundsOf("compact_assist.max_manifest_chars"));
|
|
2005
|
+
ca.summary_budget_chars = validatedInt(ca_raw["summary_budget_chars"], ca.summary_budget_chars, ...boundsOf("compact_assist.summary_budget_chars"));
|
|
2006
|
+
ca.harness = validatedStr(ca_raw["harness"], ca.harness);
|
|
2007
|
+
ca.enabled = envBool("TOKEN_GOAT_COMPACT_ASSIST", envBool("TOKENWISE_COMPACT_ASSIST", ca.enabled));
|
|
2008
|
+
const bc_raw = section(raw, "bash_compress");
|
|
2009
|
+
const bc = getDefaultConfig("bash_compress");
|
|
2010
|
+
bc.enabled = validatedBool(bc_raw["enabled"], bc.enabled);
|
|
2011
|
+
bc.disabled_filters = validatedStrList(bc_raw["disabled_filters"], bc.disabled_filters);
|
|
2012
|
+
bc.max_lines = validatedInt(bc_raw["max_lines"], bc.max_lines, ...boundsOf("bash_compress.max_lines"));
|
|
2013
|
+
bc.max_bytes = validatedInt(bc_raw["max_bytes"], bc.max_bytes, ...boundsOf("bash_compress.max_bytes"));
|
|
2014
|
+
bc.timeout_seconds = validatedInt(bc_raw["timeout_seconds"], bc.timeout_seconds, ...boundsOf("bash_compress.timeout_seconds"));
|
|
2015
|
+
bc.cache_min_bytes = validatedIntWithLegacySentinel(bc_raw["cache_min_bytes"], bc.cache_min_bytes, 0, ...boundsOf("bash_compress.cache_min_bytes"));
|
|
2016
|
+
bc.cache_max_file_count = validatedInt(bc_raw["cache_max_file_count"], bc.cache_max_file_count, ...boundsOf("bash_compress.cache_max_file_count"));
|
|
2017
|
+
bc.cache_max_bytes = validatedInt(bc_raw["cache_max_bytes"], bc.cache_max_bytes, ...boundsOf("bash_compress.cache_max_bytes"));
|
|
2018
|
+
bc.cache_max_bytes_per_output = validatedInt(bc_raw["cache_max_bytes_per_output"], bc.cache_max_bytes_per_output, ...boundsOf("bash_compress.cache_max_bytes_per_output"));
|
|
2019
|
+
bc.min_net_savings_bytes = validatedInt(bc_raw["min_net_savings_bytes"], bc.min_net_savings_bytes, ...boundsOf("bash_compress.min_net_savings_bytes"));
|
|
2020
|
+
bc.elide_served_shell_output = validatedBool(bc_raw["elide_served_shell_output"], bc.elide_served_shell_output);
|
|
2021
|
+
bc.enabled = envBool("TOKEN_GOAT_BASH_COMPRESS", bc.enabled);
|
|
2022
|
+
bc.cache_min_bytes = envInt("TOKEN_GOAT_BASH_CACHE_MIN_BYTES", bc.cache_min_bytes, ...boundsOf("bash_compress.cache_min_bytes"));
|
|
2023
|
+
bc.cache_max_file_count = envInt("TOKEN_GOAT_BASH_CACHE_MAX_FILES", bc.cache_max_file_count, ...boundsOf("bash_compress.cache_max_file_count"));
|
|
2024
|
+
bc.cache_max_bytes = envInt("TOKEN_GOAT_BASH_CACHE_MAX_BYTES", bc.cache_max_bytes, ...boundsOf("bash_compress.cache_max_bytes"));
|
|
2025
|
+
bc.cache_max_bytes_per_output = envInt("TOKEN_GOAT_BASH_CACHE_MAX_BYTES_PER_OUTPUT", bc.cache_max_bytes_per_output, ...boundsOf("bash_compress.cache_max_bytes_per_output"));
|
|
2026
|
+
bc.min_net_savings_bytes = envInt("TOKEN_GOAT_BASH_MIN_NET_SAVINGS_BYTES", bc.min_net_savings_bytes, ...boundsOf("bash_compress.min_net_savings_bytes"));
|
|
2027
|
+
bc.cache_max_bytes_per_output = Math.min(bc.cache_max_bytes_per_output, bc.cache_max_bytes);
|
|
2028
|
+
const ar_raw = section(raw, "agent_report");
|
|
2029
|
+
const ar = getDefaultConfig("agent_report");
|
|
2030
|
+
ar.min_bytes = validatedInt(ar_raw["min_bytes"], ar.min_bytes, ...boundsOf("agent_report.min_bytes"));
|
|
2031
|
+
ar.fence_collapse_min_lines = validatedInt(ar_raw["fence_collapse_min_lines"], ar.fence_collapse_min_lines, ...boundsOf("agent_report.fence_collapse_min_lines"));
|
|
2032
|
+
ar.fence_collapse_keep_lines = validatedInt(ar_raw["fence_collapse_keep_lines"], ar.fence_collapse_keep_lines, ...boundsOf("agent_report.fence_collapse_keep_lines"));
|
|
2033
|
+
ar.min_bytes = envInt("TOKEN_GOAT_AGENT_REPORT_MIN_BYTES", ar.min_bytes, ...boundsOf("agent_report.min_bytes"));
|
|
2034
|
+
ar.fence_collapse_min_lines = envInt("TOKEN_GOAT_AGENT_REPORT_FENCE_MIN_LINES", ar.fence_collapse_min_lines, ...boundsOf("agent_report.fence_collapse_min_lines"));
|
|
2035
|
+
ar.fence_collapse_keep_lines = envInt("TOKEN_GOAT_AGENT_REPORT_FENCE_KEEP_LINES", ar.fence_collapse_keep_lines, ...boundsOf("agent_report.fence_collapse_keep_lines"));
|
|
2036
|
+
ar.fence_collapse_keep_lines = Math.min(ar.fence_collapse_keep_lines, Math.floor((ar.fence_collapse_min_lines - 1) / 2));
|
|
2037
|
+
const bd_raw = section(raw, "bash_diff");
|
|
2038
|
+
const bd = getDefaultConfig("bash_diff");
|
|
2039
|
+
bd.max_hunks_per_file = validatedInt(bd_raw["max_hunks_per_file"], bd.max_hunks_per_file, ...boundsOf("bash_diff.max_hunks_per_file"));
|
|
2040
|
+
const sl_raw = section(raw, "bash_severity_log");
|
|
2041
|
+
const sl = getDefaultConfig("bash_severity_log");
|
|
2042
|
+
sl.context_lines = validatedInt(sl_raw["context_lines"], sl.context_lines, ...boundsOf("bash_severity_log.context_lines"));
|
|
2043
|
+
sl.score_threshold = validatedFloat(sl_raw["score_threshold"], sl.score_threshold, ...boundsOf("bash_severity_log.score_threshold"));
|
|
2044
|
+
const cc_raw = section(raw, "post_read_code_compress");
|
|
2045
|
+
const cc = getDefaultConfig("post_read_code_compress");
|
|
2046
|
+
cc.min_lines = validatedInt(cc_raw["min_lines"], cc.min_lines, ...boundsOf("post_read_code_compress.min_lines"));
|
|
2047
|
+
const sb_raw = section(raw, "session_brief");
|
|
2048
|
+
const sb = getDefaultConfig("session_brief");
|
|
2049
|
+
sb.enabled = validatedBool(sb_raw["enabled"], sb.enabled);
|
|
2050
|
+
sb.enabled = envBool("TOKEN_GOAT_SESSION_BRIEF", sb.enabled);
|
|
2051
|
+
const sp_raw = section(raw, "skill_preservation");
|
|
2052
|
+
const sp = getDefaultConfig("skill_preservation");
|
|
2053
|
+
sp.enabled = validatedBool(sp_raw["enabled"], sp.enabled);
|
|
2054
|
+
sp.max_cache_bytes = validatedInt(sp_raw["max_cache_bytes"], sp.max_cache_bytes, ...boundsOf("skill_preservation.max_cache_bytes"));
|
|
2055
|
+
sp.orphan_sweep_enabled = validatedBool(sp_raw["orphan_sweep_enabled"], sp.orphan_sweep_enabled);
|
|
2056
|
+
sp.orphan_age_secs = validatedInt(sp_raw["orphan_age_secs"], sp.orphan_age_secs, ...boundsOf("skill_preservation.orphan_age_secs"));
|
|
2057
|
+
sp.truncation_budget_tokens = validatedInt(sp_raw["truncation_budget_tokens"], sp.truncation_budget_tokens, ...boundsOf("skill_preservation.truncation_budget_tokens"));
|
|
2058
|
+
sp.compress_bodies = validatedBool(sp_raw["compress_bodies"], sp.compress_bodies);
|
|
2059
|
+
sp.compress_min_bytes = validatedInt(sp_raw["compress_min_bytes"], sp.compress_min_bytes, ...boundsOf("skill_preservation.compress_min_bytes"));
|
|
2060
|
+
sp.inline_snippets = validatedBool(sp_raw["inline_snippets"], sp.inline_snippets);
|
|
2061
|
+
sp.pre_skill_enabled = validatedBool(sp_raw["pre_skill_enabled"], sp.pre_skill_enabled);
|
|
2062
|
+
sp.first_load_compact = validatedBool(sp_raw["first_load_compact"], sp.first_load_compact);
|
|
2063
|
+
sp.post_compact_full_loads = validatedBool(sp_raw["post_compact_full_loads"], sp.post_compact_full_loads);
|
|
2064
|
+
sp.enabled = envBool("TOKEN_GOAT_SKILL_PRESERVATION", sp.enabled);
|
|
2065
|
+
sp.compress_bodies = envBool("TOKEN_GOAT_SKILL_COMPRESS", sp.compress_bodies);
|
|
2066
|
+
sp.pre_skill_enabled = envBool("TOKEN_GOAT_PRE_SKILL", sp.pre_skill_enabled);
|
|
2067
|
+
sp.orphan_sweep_enabled = envBool("TOKEN_GOAT_ORPHAN_SWEEP", sp.orphan_sweep_enabled);
|
|
2068
|
+
const is_raw = section(raw, "image_shrink");
|
|
2069
|
+
const is_cfg = getDefaultConfig("image_shrink");
|
|
2070
|
+
is_cfg.enabled = validatedBool(is_raw["enabled"], is_cfg.enabled);
|
|
2071
|
+
is_cfg.jpeg_quality = validatedInt(is_raw["jpeg_quality"], is_cfg.jpeg_quality, ...boundsOf("image_shrink.jpeg_quality"));
|
|
2072
|
+
is_cfg.max_image_pixels = validatedInt(is_raw["max_image_pixels"], is_cfg.max_image_pixels, ...boundsOf("image_shrink.max_image_pixels"));
|
|
2073
|
+
is_cfg.screenshot_redirect = validatedBool(is_raw["screenshot_redirect"], is_cfg.screenshot_redirect);
|
|
2074
|
+
is_cfg.ocr_enabled = validatedBool(is_raw["ocr_enabled"], is_cfg.ocr_enabled);
|
|
2075
|
+
is_cfg.ocr_min_confidence = validatedInt(is_raw["ocr_min_confidence"], is_cfg.ocr_min_confidence, ...boundsOf("image_shrink.ocr_min_confidence"));
|
|
2076
|
+
is_cfg.ocr_lang = validatedOcrLang(is_raw["ocr_lang"], is_cfg.ocr_lang);
|
|
2077
|
+
is_cfg.vision_tier = validatedVisionTier(is_raw["vision_tier"], is_cfg.vision_tier);
|
|
2078
|
+
is_cfg.max_image_pixels = envInt("TOKEN_GOAT_MAX_IMAGE_PIXELS", is_cfg.max_image_pixels, ...boundsOf("image_shrink.max_image_pixels"));
|
|
2079
|
+
is_cfg.ocr_enabled = envBool("TOKEN_GOAT_OCR_ENABLED", is_cfg.ocr_enabled);
|
|
2080
|
+
is_cfg.ocr_lang = validatedOcrLang(process.env["TOKEN_GOAT_OCR_LANG"], is_cfg.ocr_lang);
|
|
2081
|
+
is_cfg.vision_tier = validatedVisionTier(process.env["TOKEN_GOAT_VISION_TIER"], is_cfg.vision_tier);
|
|
2082
|
+
const sc_raw = section(raw, "screenshot");
|
|
2083
|
+
const sc_cfg = getDefaultConfig("screenshot");
|
|
2084
|
+
sc_cfg.chrome_path = validatedStr(sc_raw["chrome_path"], sc_cfg.chrome_path);
|
|
2085
|
+
sc_cfg.block_private_targets = validatedBool(sc_raw["block_private_targets"], sc_cfg.block_private_targets);
|
|
2086
|
+
sc_cfg.block_private_targets = envBool("TOKEN_GOAT_SCREENSHOT_BLOCK_PRIVATE_TARGETS", sc_cfg.block_private_targets);
|
|
2087
|
+
const rm_raw = section(raw, "repomap");
|
|
2088
|
+
const rm = getDefaultConfig("repomap");
|
|
2089
|
+
rm.compact_file_threshold = validatedInt(rm_raw["compact_file_threshold"], rm.compact_file_threshold, ...boundsOf("repomap.compact_file_threshold"));
|
|
2090
|
+
rm.exclude_tests = validatedBool(rm_raw["exclude_tests"], rm.exclude_tests);
|
|
2091
|
+
rm.compact_file_threshold = envInt("TOKEN_GOAT_REPOMAP_COMPACT_THRESHOLD", rm.compact_file_threshold, ...boundsOf("repomap.compact_file_threshold"));
|
|
2092
|
+
rm.exclude_tests = envBool("TOKEN_GOAT_REPOMAP_EXCLUDE_TESTS", rm.exclude_tests);
|
|
2093
|
+
const og_raw = section(raw, "overflow_guard");
|
|
2094
|
+
const og = getDefaultConfig("overflow_guard");
|
|
2095
|
+
og.enabled = validatedBool(og_raw["enabled"], og.enabled);
|
|
2096
|
+
og.max_tokens = validatedInt(og_raw["max_tokens"], og.max_tokens, ...boundsOf("overflow_guard.max_tokens"));
|
|
2097
|
+
og.enabled = envBool("TOKEN_GOAT_OVERFLOW_GUARD", og.enabled);
|
|
2098
|
+
og.max_tokens = envInt("TOKEN_GOAT_OVERFLOW_MAX_TOKENS", og.max_tokens, ...boundsOf("overflow_guard.max_tokens"));
|
|
2099
|
+
const st_raw = section(raw, "stats");
|
|
2100
|
+
const st = getDefaultConfig("stats");
|
|
2101
|
+
st.record_zero_savings = validatedBool(st_raw["record_zero_savings"], st.record_zero_savings);
|
|
2102
|
+
const hi_raw = section(raw, "hints");
|
|
2103
|
+
const hi = getDefaultConfig("hints");
|
|
2104
|
+
hi.quiet_hours = validatedStr(hi_raw["quiet_hours"], hi.quiet_hours);
|
|
2105
|
+
hi.json_sidecar = validatedBool(hi_raw["json_sidecar"], hi.json_sidecar);
|
|
2106
|
+
hi.min_file_lines_for_hint = validatedInt(hi_raw["min_file_lines_for_hint"], hi.min_file_lines_for_hint, ...boundsOf("hints.min_file_lines_for_hint"));
|
|
2107
|
+
hi.bash_dedup_min_bytes = validatedInt(hi_raw["bash_dedup_min_bytes"], hi.bash_dedup_min_bytes, ...boundsOf("hints.bash_dedup_min_bytes"));
|
|
2108
|
+
hi.bash_dedup_min_bytes = envInt("TOKEN_GOAT_BASH_DEDUP_MIN_BYTES", hi.bash_dedup_min_bytes, ...boundsOf("hints.bash_dedup_min_bytes"));
|
|
2109
|
+
hi.web_dedup_min_bytes = validatedInt(hi_raw["web_dedup_min_bytes"], hi.web_dedup_min_bytes, ...boundsOf("hints.web_dedup_min_bytes"));
|
|
2110
|
+
hi.web_dedup_min_bytes = envInt("TOKEN_GOAT_WEB_DEDUP_MIN_BYTES", hi.web_dedup_min_bytes, ...boundsOf("hints.web_dedup_min_bytes"));
|
|
2111
|
+
hi.grep_dedup_min_matches = validatedInt(hi_raw["grep_dedup_min_matches"], hi.grep_dedup_min_matches, ...boundsOf("hints.grep_dedup_min_matches"));
|
|
2112
|
+
hi.grep_dedup_min_matches = envInt("TOKEN_GOAT_GREP_DEDUP_MIN_MATCHES", hi.grep_dedup_min_matches, ...boundsOf("hints.grep_dedup_min_matches"));
|
|
2113
|
+
hi.glob_dedup_min_matches = validatedInt(hi_raw["glob_dedup_min_matches"], hi.glob_dedup_min_matches, ...boundsOf("hints.glob_dedup_min_matches"));
|
|
2114
|
+
hi.glob_dedup_min_matches = envInt("TOKEN_GOAT_GLOB_DEDUP_MIN_MATCHES", hi.glob_dedup_min_matches, ...boundsOf("hints.glob_dedup_min_matches"));
|
|
2115
|
+
hi.write_rewrite_min_lines = validatedInt(hi_raw["write_rewrite_min_lines"], hi.write_rewrite_min_lines, ...boundsOf("hints.write_rewrite_min_lines"));
|
|
2116
|
+
hi.write_rewrite_min_lines = envInt("TOKEN_GOAT_WRITE_REWRITE_MIN_LINES", hi.write_rewrite_min_lines, ...boundsOf("hints.write_rewrite_min_lines"));
|
|
2117
|
+
hi.write_rewrite_unchanged_pct = validatedInt(hi_raw["write_rewrite_unchanged_pct"], hi.write_rewrite_unchanged_pct, ...boundsOf("hints.write_rewrite_unchanged_pct"));
|
|
2118
|
+
hi.write_rewrite_unchanged_pct = envInt("TOKEN_GOAT_WRITE_REWRITE_UNCHANGED_PCT", hi.write_rewrite_unchanged_pct, ...boundsOf("hints.write_rewrite_unchanged_pct"));
|
|
2119
|
+
hi.serve_diff_on_reread = validatedBool(hi_raw["serve_diff_on_reread"], hi.serve_diff_on_reread);
|
|
2120
|
+
hi.elide_served_lines = validatedBool(hi_raw["elide_served_lines"], hi.elide_served_lines);
|
|
2121
|
+
hi.subagent_markdown_first_read_deny = validatedBool(hi_raw["subagent_markdown_first_read_deny"], hi.subagent_markdown_first_read_deny);
|
|
2122
|
+
hi.backoff_thresholds = validatedIntList(hi_raw["backoff_thresholds"], hi.backoff_thresholds);
|
|
2123
|
+
hi.git_hint_max_ms = validatedInt(hi_raw["git_hint_max_ms"], hi.git_hint_max_ms, ...boundsOf("hints.git_hint_max_ms"));
|
|
2124
|
+
hi.min_session_hint_savings_bytes = validatedInt(hi_raw["min_session_hint_savings_bytes"], hi.min_session_hint_savings_bytes, ...boundsOf("hints.min_session_hint_savings_bytes"));
|
|
2125
|
+
hi.pre_skill_advisory = validatedBool(hi_raw["pre_skill_advisory"], hi.pre_skill_advisory);
|
|
2126
|
+
hi.context_threshold_advisory = validatedBool(hi_raw["context_threshold_advisory"], hi.context_threshold_advisory);
|
|
2127
|
+
hi.diff_hint_min_tokens_saved = validatedInt(hi_raw["diff_hint_min_tokens_saved"], hi.diff_hint_min_tokens_saved, ...boundsOf("hints.diff_hint_min_tokens_saved"));
|
|
2128
|
+
hi.large_read_redirect_bytes = validatedIntWithLegacySentinel(hi_raw["large_read_redirect_bytes"], hi.large_read_redirect_bytes, 45e3, ...boundsOf("hints.large_read_redirect_bytes"));
|
|
2129
|
+
hi.reread_deny = validatedBool(hi_raw["reread_deny"], hi.reread_deny);
|
|
2130
|
+
hi.reread_deny_min_bytes = validatedIntWithLegacySentinel(hi_raw["reread_deny_min_bytes"], hi.reread_deny_min_bytes, 2048, ...boundsOf("hints.reread_deny_min_bytes"));
|
|
2131
|
+
hi.stable_doc_compacts = validatedBool(hi_raw["stable_doc_compacts"], hi.stable_doc_compacts);
|
|
2132
|
+
hi.fold_code_bodies = validatedBool(hi_raw["fold_code_bodies"], hi.fold_code_bodies);
|
|
2133
|
+
hi.fold_comment_blocks = validatedBool(hi_raw["fold_comment_blocks"], hi.fold_comment_blocks);
|
|
2134
|
+
hi.fold_prose_paragraphs = validatedBool(hi_raw["fold_prose_paragraphs"], hi.fold_prose_paragraphs);
|
|
2135
|
+
hi.outline_large_documents = validatedBool(hi_raw["outline_large_documents"], hi.outline_large_documents);
|
|
2136
|
+
hi.skeleton_large_sources = validatedBool(hi_raw["skeleton_large_sources"], hi.skeleton_large_sources);
|
|
2137
|
+
hi.truncated_read_min_lines = validatedInt(hi_raw["truncated_read_min_lines"], hi.truncated_read_min_lines, ...boundsOf("hints.truncated_read_min_lines"));
|
|
2138
|
+
hi.protect_recent_reads = validatedInt(hi_raw["protect_recent_reads"], hi.protect_recent_reads, ...boundsOf("hints.protect_recent_reads"));
|
|
2139
|
+
hi.warn_unbalanced_shell_quoting = validatedBool(hi_raw["warn_unbalanced_shell_quoting"], hi.warn_unbalanced_shell_quoting);
|
|
2140
|
+
hi.log_large_file_hint_outcomes = validatedBool(hi_raw["log_large_file_hint_outcomes"], hi.log_large_file_hint_outcomes);
|
|
2141
|
+
hi.warn_unbalanced_shell_quoting = envBool("TOKEN_GOAT_WARN_UNBALANCED_SHELL_QUOTING", hi.warn_unbalanced_shell_quoting);
|
|
2142
|
+
hi.serve_diff_on_reread = envBool("TOKEN_GOAT_SERVE_DIFF_ON_REREAD", hi.serve_diff_on_reread);
|
|
2143
|
+
hi.elide_served_lines = envBool("TOKEN_GOAT_ELIDE_SERVED_LINES", hi.elide_served_lines);
|
|
2144
|
+
hi.subagent_markdown_first_read_deny = envBool("TOKEN_GOAT_SUBAGENT_MARKDOWN_FIRST_READ_DENY", hi.subagent_markdown_first_read_deny);
|
|
2145
|
+
hi.log_large_file_hint_outcomes = envBool("TOKEN_GOAT_LOG_LARGE_FILE_HINT_OUTCOMES", hi.log_large_file_hint_outcomes);
|
|
2146
|
+
hi.json_sidecar = envBool("TOKEN_GOAT_HINT_JSON_SIDECAR", hi.json_sidecar);
|
|
2147
|
+
hi.large_read_redirect_bytes = envInt("TOKEN_GOAT_LARGE_READ_BYTES", hi.large_read_redirect_bytes, ...boundsOf("hints.large_read_redirect_bytes"));
|
|
2148
|
+
hi.cross_session_read_dedup = validatedBool(hi_raw["cross_session_read_dedup"], hi.cross_session_read_dedup);
|
|
2149
|
+
hi.cross_session_read_dedup_ttl_secs = validatedInt(hi_raw["cross_session_read_dedup_ttl_secs"], hi.cross_session_read_dedup_ttl_secs, ...boundsOf("hints.cross_session_read_dedup_ttl_secs"));
|
|
2150
|
+
hi.cross_session_read_dedup = envBool("TOKEN_GOAT_CROSS_SESSION_READ_DEDUP", hi.cross_session_read_dedup);
|
|
2151
|
+
hi.cross_session_read_dedup_ttl_secs = envInt("TOKEN_GOAT_CROSS_SESSION_READ_DEDUP_TTL_SECS", hi.cross_session_read_dedup_ttl_secs, ...boundsOf("hints.cross_session_read_dedup_ttl_secs"));
|
|
2152
|
+
hi.mcp_dedup_ttl_secs = validatedInt(hi_raw["mcp_dedup_ttl_secs"], hi.mcp_dedup_ttl_secs, ...boundsOf("hints.mcp_dedup_ttl_secs"));
|
|
2153
|
+
hi.mcp_dedup_ttl_secs = envInt("TOKEN_GOAT_MCP_DEDUP_TTL_SECS", hi.mcp_dedup_ttl_secs, ...boundsOf("hints.mcp_dedup_ttl_secs"));
|
|
2154
|
+
hi.session_start_reminder = validatedBool(hi_raw["session_start_reminder"], hi.session_start_reminder);
|
|
2155
|
+
hi.session_start_reminder = envBool("TOKEN_GOAT_SESSION_START_REMINDER", hi.session_start_reminder);
|
|
2156
|
+
hi.min_session_hint_savings_bytes = envInt("TOKEN_GOAT_SESSION_HINT_MIN_BYTES", hi.min_session_hint_savings_bytes, ...boundsOf("hints.min_session_hint_savings_bytes"));
|
|
2157
|
+
hi.reread_deny = envBool("TOKEN_GOAT_REREAD_DENY", hi.reread_deny);
|
|
2158
|
+
hi.reread_deny_min_bytes = envInt("TOKEN_GOAT_REREAD_DENY_MIN_BYTES", hi.reread_deny_min_bytes, ...boundsOf("hints.reread_deny_min_bytes"));
|
|
2159
|
+
hi.protect_recent_reads = envInt("TOKEN_GOAT_PROTECT_RECENT_READS", hi.protect_recent_reads, ...boundsOf("hints.protect_recent_reads"));
|
|
2160
|
+
hi.truncated_read_min_lines = envInt("TOKEN_GOAT_TRUNCATED_READ_MIN_LINES", hi.truncated_read_min_lines, ...boundsOf("hints.truncated_read_min_lines"));
|
|
2161
|
+
hi.diff_hint_min_tokens_saved = envInt("TOKEN_GOAT_DIFF_HINT_MIN_TOKENS_SAVED", hi.diff_hint_min_tokens_saved, ...boundsOf("hints.diff_hint_min_tokens_saved"));
|
|
2162
|
+
hi.min_file_lines_for_hint = envInt("TOKEN_GOAT_MIN_FILE_LINES_FOR_HINT", hi.min_file_lines_for_hint, ...boundsOf("hints.min_file_lines_for_hint"));
|
|
2163
|
+
hi.git_hint_max_ms = envInt("TOKEN_GOAT_GIT_HINT_MAX_MS", hi.git_hint_max_ms, ...boundsOf("hints.git_hint_max_ms"));
|
|
2164
|
+
hi.stable_doc_compacts = envBool("TOKEN_GOAT_STABLE_DOC_COMPACTS", hi.stable_doc_compacts);
|
|
2165
|
+
hi.fold_code_bodies = envBool("TOKEN_GOAT_FOLD_CODE_BODIES", hi.fold_code_bodies);
|
|
2166
|
+
hi.fold_comment_blocks = envBool("TOKEN_GOAT_FOLD_COMMENT_BLOCKS", hi.fold_comment_blocks);
|
|
2167
|
+
hi.fold_prose_paragraphs = envBool("TOKEN_GOAT_FOLD_PROSE_PARAGRAPHS", hi.fold_prose_paragraphs);
|
|
2168
|
+
hi.outline_large_documents = envBool("TOKEN_GOAT_OUTLINE_LARGE_DOCUMENTS", hi.outline_large_documents);
|
|
2169
|
+
hi.skeleton_large_sources = envBool("TOKEN_GOAT_SKELETON_LARGE_SOURCES", hi.skeleton_large_sources);
|
|
2170
|
+
hi.context_threshold_advisory = envBool("TOKEN_GOAT_CONTEXT_THRESHOLD_ADVISORY", hi.context_threshold_advisory);
|
|
2171
|
+
hi.pre_skill_advisory = envBool("TOKEN_GOAT_PRE_SKILL_ADVISORY", hi.pre_skill_advisory);
|
|
2172
|
+
hi.quiet_hours = envStr("TOKEN_GOAT_QUIET_HOURS", hi.quiet_hours);
|
|
2173
|
+
const triggers_raw = hi_raw["prompt_triggers"];
|
|
2174
|
+
if (Array.isArray(triggers_raw)) {
|
|
2175
|
+
hi.prompt_triggers = triggers_raw.filter((t) => t !== null && typeof t === "object" && !Array.isArray(t)).map((t) => ({
|
|
2176
|
+
keywords: validatedStrList(t["keywords"], []),
|
|
2177
|
+
hint: validatedStr(t["hint"], "")
|
|
2178
|
+
})).filter((t) => t.keywords.length > 0 && t.hint.length > 0);
|
|
2179
|
+
}
|
|
2180
|
+
const hk_raw = section(raw, "hooks");
|
|
2181
|
+
const hk = getDefaultConfig("hooks");
|
|
2182
|
+
hk.watchdog_ms = validatedInt(hk_raw["watchdog_ms"], hk.watchdog_ms, ...boundsOf("hooks.watchdog_ms"));
|
|
2183
|
+
hk.watchdog_ms = envInt("TOKEN_GOAT_HOOK_WATCHDOG_MS", hk.watchdog_ms, ...boundsOf("hooks.watchdog_ms"));
|
|
2184
|
+
const wf_raw = section(raw, "webfetch");
|
|
2185
|
+
const wf = getDefaultConfig("webfetch");
|
|
2186
|
+
wf.allow = validatedStrList(wf_raw["allow"], wf.allow);
|
|
2187
|
+
wf.deny = validatedStrList(wf_raw["deny"], wf.deny);
|
|
2188
|
+
wf.allow = envStrList("TOKEN_GOAT_WEBFETCH_ALLOW", wf.allow, ",");
|
|
2189
|
+
wf.deny = envStrList("TOKEN_GOAT_WEBFETCH_DENY", wf.deny, ",");
|
|
2190
|
+
wf.max_file_count = validatedInt(wf_raw["max_file_count"], wf.max_file_count, ...boundsOf("webfetch.max_file_count"));
|
|
2191
|
+
wf.max_file_count = envInt("TOKEN_GOAT_WEB_CACHE_MAX_FILES", wf.max_file_count, ...boundsOf("webfetch.max_file_count"));
|
|
2192
|
+
wf.max_bytes = validatedInt(wf_raw["max_bytes"], wf.max_bytes, ...boundsOf("webfetch.max_bytes"));
|
|
2193
|
+
wf.max_bytes = envInt("TOKEN_GOAT_WEB_CACHE_MAX_BYTES", wf.max_bytes, ...boundsOf("webfetch.max_bytes"));
|
|
2194
|
+
wf.compress_bodies = validatedBool(wf_raw["compress_bodies"], wf.compress_bodies);
|
|
2195
|
+
wf.compress_min_bytes = validatedInt(wf_raw["compress_min_bytes"], wf.compress_min_bytes, ...boundsOf("webfetch.compress_min_bytes"));
|
|
2196
|
+
wf.compress_bodies = envBool("TOKEN_GOAT_WEB_COMPRESS", wf.compress_bodies);
|
|
2197
|
+
const wk_raw = section(raw, "worker");
|
|
2198
|
+
const wk = getDefaultConfig("worker");
|
|
2199
|
+
wk.blocked_roots = validatedStrList(wk_raw["blocked_roots"], wk.blocked_roots);
|
|
2200
|
+
wk.max_pool_workers = validatedInt(wk_raw["max_pool_workers"], wk.max_pool_workers, ...boundsOf("worker.max_pool_workers"));
|
|
2201
|
+
wk.max_pool_workers = envInt("TOKEN_GOAT_WORKER_MAX_POOL", wk.max_pool_workers, ...boundsOf("worker.max_pool_workers"));
|
|
2202
|
+
wk.embed_threads = validatedInt(wk_raw["embed_threads"], wk.embed_threads, ...boundsOf("worker.embed_threads"));
|
|
2203
|
+
wk.embed_threads = envInt("TOKEN_GOAT_EMBED_THREADS", wk.embed_threads, ...boundsOf("worker.embed_threads"));
|
|
2204
|
+
wk.priority = validatedStr(wk_raw["priority"], wk.priority);
|
|
2205
|
+
wk.priority = envStr("TOKEN_GOAT_WORKER_PRIORITY", wk.priority);
|
|
2206
|
+
const ix_raw = section(raw, "indexing");
|
|
2207
|
+
const ix = getDefaultConfig("indexing");
|
|
2208
|
+
ix.large_file_symbol_only_kb = validatedInt(ix_raw["large_file_symbol_only_kb"], ix.large_file_symbol_only_kb, ...boundsOf("indexing.large_file_symbol_only_kb"));
|
|
2209
|
+
ix.large_file_skip_kb = validatedInt(ix_raw["large_file_skip_kb"], ix.large_file_skip_kb, ...boundsOf("indexing.large_file_skip_kb"));
|
|
2210
|
+
ix.large_file_symbol_only_kb = Math.min(ix.large_file_symbol_only_kb, ix.large_file_skip_kb);
|
|
2211
|
+
ix.skip_dirs = validatedStrList(ix_raw["skip_dirs"], ix.skip_dirs);
|
|
2212
|
+
ix.skip_files = validatedStrList(ix_raw["skip_files"], ix.skip_files);
|
|
2213
|
+
ix.embeddings_enabled = validatedBool(ix_raw["embeddings_enabled"], ix.embeddings_enabled);
|
|
2214
|
+
ix.embeddings_enabled = envBool("TOKEN_GOAT_EMBEDDINGS_ENABLED", ix.embeddings_enabled);
|
|
2215
|
+
ix.cross_project_symbols = validatedBool(ix_raw["cross_project_symbols"], ix.cross_project_symbols);
|
|
2216
|
+
ix.cross_project_symbols = envBool("TOKEN_GOAT_CROSS_PROJECT_SYMBOLS", ix.cross_project_symbols);
|
|
2217
|
+
const cpr_raw = section(raw, "compression");
|
|
2218
|
+
const cpr = getDefaultConfig("compression");
|
|
2219
|
+
cpr.profile = validatedStr(cpr_raw["profile"], cpr.profile);
|
|
2220
|
+
cpr.profile = envStr("TOKEN_GOAT_COMPRESS_PROFILE", cpr.profile);
|
|
2221
|
+
const ctx_raw = section(raw, "context");
|
|
2222
|
+
const ctx = getDefaultConfig("context");
|
|
2223
|
+
ctx.model_window_tokens = validatedInt(ctx_raw["model_window_tokens"], ctx.model_window_tokens, ...boundsOf("context.model_window_tokens"));
|
|
2224
|
+
ctx.model_window_tokens = envInt("TOKEN_GOAT_MODEL_WINDOW_TOKENS", ctx.model_window_tokens, ...boundsOf("context.model_window_tokens"));
|
|
2225
|
+
const inj_raw = section(raw, "injection");
|
|
2226
|
+
const inj = getDefaultConfig("injection");
|
|
2227
|
+
inj.enabled = validatedBool(inj_raw["enabled"], inj.enabled);
|
|
2228
|
+
inj.enabled = envBool("TOKEN_GOAT_INJECTION_ENABLED", inj.enabled);
|
|
2229
|
+
const gd_raw = section(raw, "gdrive");
|
|
2230
|
+
const gd = getDefaultConfig("gdrive");
|
|
2231
|
+
gd.enabled = validatedBool(gd_raw["enabled"], gd.enabled);
|
|
2232
|
+
gd.enabled = envBool("TOKEN_GOAT_GDRIVE_ENABLED", gd.enabled);
|
|
2233
|
+
const red_raw = section(raw, "redaction");
|
|
2234
|
+
const red = getDefaultConfig("redaction");
|
|
2235
|
+
red.custom_patterns = validatedStrList(red_raw["custom_patterns"], red.custom_patterns);
|
|
2236
|
+
red.custom_patterns = envStrList("TOKEN_GOAT_REDACTION_CUSTOM_PATTERNS", red.custom_patterns, "\n");
|
|
2237
|
+
red.strict = validatedBool(red_raw["strict"], red.strict);
|
|
2238
|
+
red.strict = envBool("TOKEN_GOAT_REDACTION_STRICT", red.strict);
|
|
2239
|
+
const net_raw = section(raw, "network");
|
|
2240
|
+
const net = getDefaultConfig("network");
|
|
2241
|
+
net.offline = validatedBool(net_raw["offline"], net.offline);
|
|
2242
|
+
net.offline = envBool("TOKEN_GOAT_OFFLINE", net.offline);
|
|
2243
|
+
const mcp_raw = section(raw, "mcp");
|
|
2244
|
+
const mcp = getDefaultConfig("mcp");
|
|
2245
|
+
mcp.confine_reads_to_project_root = validatedBool(mcp_raw["confine_reads_to_project_root"], mcp.confine_reads_to_project_root);
|
|
2246
|
+
mcp.confine_reads_to_project_root = envBool("TOKEN_GOAT_MCP_CONFINE_READS", mcp.confine_reads_to_project_root);
|
|
2247
|
+
mcp.allowed_roots = validatedStrList(mcp_raw["allowed_roots"], mcp.allowed_roots);
|
|
2248
|
+
mcp.allowed_roots = envStrList("TOKEN_GOAT_MCP_ALLOWED_ROOTS", mcp.allowed_roots, path2.delimiter);
|
|
2249
|
+
const hs_raw = section(raw, "hint_stats");
|
|
2250
|
+
const hs = getDefaultConfig("hint_stats");
|
|
2251
|
+
hs.suppress_threshold_pct = validatedInt(hs_raw["suppress_threshold_pct"], hs.suppress_threshold_pct, ...boundsOf("hint_stats.suppress_threshold_pct"));
|
|
2252
|
+
hs.min_sample_size = validatedInt(hs_raw["min_sample_size"], hs.min_sample_size, ...boundsOf("hint_stats.min_sample_size"));
|
|
2253
|
+
const sem_raw = section(raw, "semantic");
|
|
2254
|
+
const sem = getDefaultConfig("semantic");
|
|
2255
|
+
sem.archive_weight = validatedFloat(sem_raw["archive_weight"], sem.archive_weight, ...boundsOf("semantic.archive_weight"));
|
|
2256
|
+
sem.docs_weight = validatedFloat(sem_raw["docs_weight"], sem.docs_weight, ...boundsOf("semantic.docs_weight"));
|
|
2257
|
+
return {
|
|
2258
|
+
compact_assist: ca,
|
|
2259
|
+
bash_compress: bc,
|
|
2260
|
+
agent_report: ar,
|
|
2261
|
+
bash_diff: bd,
|
|
2262
|
+
bash_severity_log: sl,
|
|
2263
|
+
post_read_code_compress: cc,
|
|
2264
|
+
session_brief: sb,
|
|
2265
|
+
skill_preservation: sp,
|
|
2266
|
+
image_shrink: is_cfg,
|
|
2267
|
+
screenshot: sc_cfg,
|
|
2268
|
+
repomap: rm,
|
|
2269
|
+
overflow_guard: og,
|
|
2270
|
+
stats: st,
|
|
2271
|
+
hints: hi,
|
|
2272
|
+
hooks: hk,
|
|
2273
|
+
webfetch: wf,
|
|
2274
|
+
worker: wk,
|
|
2275
|
+
indexing: ix,
|
|
2276
|
+
compression: cpr,
|
|
2277
|
+
context: ctx,
|
|
2278
|
+
injection: inj,
|
|
2279
|
+
gdrive: gd,
|
|
2280
|
+
redaction: red,
|
|
2281
|
+
network: net,
|
|
2282
|
+
mcp,
|
|
2283
|
+
hint_stats: hs,
|
|
2284
|
+
semantic: sem
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
var CONFIG_KEY_ENV_OVERRIDES = {
|
|
2288
|
+
"compact_assist.enabled": ["TOKEN_GOAT_COMPACT_ASSIST", "TOKENWISE_COMPACT_ASSIST"],
|
|
2289
|
+
"bash_compress.enabled": ["TOKEN_GOAT_BASH_COMPRESS"],
|
|
2290
|
+
"bash_compress.cache_min_bytes": ["TOKEN_GOAT_BASH_CACHE_MIN_BYTES"],
|
|
2291
|
+
"bash_compress.cache_max_file_count": ["TOKEN_GOAT_BASH_CACHE_MAX_FILES"],
|
|
2292
|
+
"bash_compress.cache_max_bytes": ["TOKEN_GOAT_BASH_CACHE_MAX_BYTES"],
|
|
2293
|
+
"bash_compress.cache_max_bytes_per_output": ["TOKEN_GOAT_BASH_CACHE_MAX_BYTES_PER_OUTPUT"],
|
|
2294
|
+
"bash_compress.min_net_savings_bytes": ["TOKEN_GOAT_BASH_MIN_NET_SAVINGS_BYTES"],
|
|
2295
|
+
"agent_report.min_bytes": ["TOKEN_GOAT_AGENT_REPORT_MIN_BYTES"],
|
|
2296
|
+
"agent_report.fence_collapse_min_lines": ["TOKEN_GOAT_AGENT_REPORT_FENCE_MIN_LINES"],
|
|
2297
|
+
"agent_report.fence_collapse_keep_lines": ["TOKEN_GOAT_AGENT_REPORT_FENCE_KEEP_LINES"],
|
|
2298
|
+
"session_brief.enabled": ["TOKEN_GOAT_SESSION_BRIEF"],
|
|
2299
|
+
"skill_preservation.enabled": ["TOKEN_GOAT_SKILL_PRESERVATION"],
|
|
2300
|
+
"skill_preservation.compress_bodies": ["TOKEN_GOAT_SKILL_COMPRESS"],
|
|
2301
|
+
"skill_preservation.pre_skill_enabled": ["TOKEN_GOAT_PRE_SKILL"],
|
|
2302
|
+
"skill_preservation.orphan_sweep_enabled": ["TOKEN_GOAT_ORPHAN_SWEEP"],
|
|
2303
|
+
"image_shrink.max_image_pixels": ["TOKEN_GOAT_MAX_IMAGE_PIXELS"],
|
|
2304
|
+
"image_shrink.ocr_enabled": ["TOKEN_GOAT_OCR_ENABLED"],
|
|
2305
|
+
"image_shrink.ocr_lang": ["TOKEN_GOAT_OCR_LANG"],
|
|
2306
|
+
"image_shrink.vision_tier": ["TOKEN_GOAT_VISION_TIER"],
|
|
2307
|
+
"screenshot.block_private_targets": ["TOKEN_GOAT_SCREENSHOT_BLOCK_PRIVATE_TARGETS"],
|
|
2308
|
+
"repomap.compact_file_threshold": ["TOKEN_GOAT_REPOMAP_COMPACT_THRESHOLD"],
|
|
2309
|
+
"repomap.exclude_tests": ["TOKEN_GOAT_REPOMAP_EXCLUDE_TESTS"],
|
|
2310
|
+
"overflow_guard.enabled": ["TOKEN_GOAT_OVERFLOW_GUARD"],
|
|
2311
|
+
"overflow_guard.max_tokens": ["TOKEN_GOAT_OVERFLOW_MAX_TOKENS"],
|
|
2312
|
+
"hints.json_sidecar": ["TOKEN_GOAT_HINT_JSON_SIDECAR"],
|
|
2313
|
+
"hints.bash_dedup_min_bytes": ["TOKEN_GOAT_BASH_DEDUP_MIN_BYTES"],
|
|
2314
|
+
"hints.web_dedup_min_bytes": ["TOKEN_GOAT_WEB_DEDUP_MIN_BYTES"],
|
|
2315
|
+
"hints.grep_dedup_min_matches": ["TOKEN_GOAT_GREP_DEDUP_MIN_MATCHES"],
|
|
2316
|
+
"hints.glob_dedup_min_matches": ["TOKEN_GOAT_GLOB_DEDUP_MIN_MATCHES"],
|
|
2317
|
+
"hints.write_rewrite_min_lines": ["TOKEN_GOAT_WRITE_REWRITE_MIN_LINES"],
|
|
2318
|
+
"hints.write_rewrite_unchanged_pct": ["TOKEN_GOAT_WRITE_REWRITE_UNCHANGED_PCT"],
|
|
2319
|
+
"hints.large_read_redirect_bytes": ["TOKEN_GOAT_LARGE_READ_BYTES"],
|
|
2320
|
+
"hints.warn_unbalanced_shell_quoting": ["TOKEN_GOAT_WARN_UNBALANCED_SHELL_QUOTING"],
|
|
2321
|
+
"hints.serve_diff_on_reread": ["TOKEN_GOAT_SERVE_DIFF_ON_REREAD"],
|
|
2322
|
+
"hints.elide_served_lines": ["TOKEN_GOAT_ELIDE_SERVED_LINES"],
|
|
2323
|
+
"hints.subagent_markdown_first_read_deny": ["TOKEN_GOAT_SUBAGENT_MARKDOWN_FIRST_READ_DENY"],
|
|
2324
|
+
"hints.log_large_file_hint_outcomes": ["TOKEN_GOAT_LOG_LARGE_FILE_HINT_OUTCOMES"],
|
|
2325
|
+
"hints.cross_session_read_dedup": ["TOKEN_GOAT_CROSS_SESSION_READ_DEDUP"],
|
|
2326
|
+
"hints.cross_session_read_dedup_ttl_secs": ["TOKEN_GOAT_CROSS_SESSION_READ_DEDUP_TTL_SECS"],
|
|
2327
|
+
"hints.mcp_dedup_ttl_secs": ["TOKEN_GOAT_MCP_DEDUP_TTL_SECS"],
|
|
2328
|
+
"hints.session_start_reminder": ["TOKEN_GOAT_SESSION_START_REMINDER"],
|
|
2329
|
+
"hints.min_session_hint_savings_bytes": ["TOKEN_GOAT_SESSION_HINT_MIN_BYTES"],
|
|
2330
|
+
"hints.reread_deny": ["TOKEN_GOAT_REREAD_DENY"],
|
|
2331
|
+
"hints.reread_deny_min_bytes": ["TOKEN_GOAT_REREAD_DENY_MIN_BYTES"],
|
|
2332
|
+
"hints.protect_recent_reads": ["TOKEN_GOAT_PROTECT_RECENT_READS"],
|
|
2333
|
+
"hints.truncated_read_min_lines": ["TOKEN_GOAT_TRUNCATED_READ_MIN_LINES"],
|
|
2334
|
+
"hints.diff_hint_min_tokens_saved": ["TOKEN_GOAT_DIFF_HINT_MIN_TOKENS_SAVED"],
|
|
2335
|
+
"hints.min_file_lines_for_hint": ["TOKEN_GOAT_MIN_FILE_LINES_FOR_HINT"],
|
|
2336
|
+
"hints.git_hint_max_ms": ["TOKEN_GOAT_GIT_HINT_MAX_MS"],
|
|
2337
|
+
"hints.stable_doc_compacts": ["TOKEN_GOAT_STABLE_DOC_COMPACTS"],
|
|
2338
|
+
"hints.fold_code_bodies": ["TOKEN_GOAT_FOLD_CODE_BODIES"],
|
|
2339
|
+
"hints.fold_comment_blocks": ["TOKEN_GOAT_FOLD_COMMENT_BLOCKS"],
|
|
2340
|
+
"hints.fold_prose_paragraphs": ["TOKEN_GOAT_FOLD_PROSE_PARAGRAPHS"],
|
|
2341
|
+
"hints.outline_large_documents": ["TOKEN_GOAT_OUTLINE_LARGE_DOCUMENTS"],
|
|
2342
|
+
"hints.skeleton_large_sources": ["TOKEN_GOAT_SKELETON_LARGE_SOURCES"],
|
|
2343
|
+
"hints.context_threshold_advisory": ["TOKEN_GOAT_CONTEXT_THRESHOLD_ADVISORY"],
|
|
2344
|
+
"hints.pre_skill_advisory": ["TOKEN_GOAT_PRE_SKILL_ADVISORY"],
|
|
2345
|
+
"hints.quiet_hours": ["TOKEN_GOAT_QUIET_HOURS"],
|
|
2346
|
+
"hooks.watchdog_ms": ["TOKEN_GOAT_HOOK_WATCHDOG_MS"],
|
|
2347
|
+
"webfetch.max_file_count": ["TOKEN_GOAT_WEB_CACHE_MAX_FILES"],
|
|
2348
|
+
"webfetch.max_bytes": ["TOKEN_GOAT_WEB_CACHE_MAX_BYTES"],
|
|
2349
|
+
"webfetch.compress_bodies": ["TOKEN_GOAT_WEB_COMPRESS"],
|
|
2350
|
+
"worker.max_pool_workers": ["TOKEN_GOAT_WORKER_MAX_POOL"],
|
|
2351
|
+
"worker.embed_threads": ["TOKEN_GOAT_EMBED_THREADS"],
|
|
2352
|
+
"worker.priority": ["TOKEN_GOAT_WORKER_PRIORITY"],
|
|
2353
|
+
"compression.profile": ["TOKEN_GOAT_COMPRESS_PROFILE"],
|
|
2354
|
+
"context.model_window_tokens": ["TOKEN_GOAT_MODEL_WINDOW_TOKENS"],
|
|
2355
|
+
"indexing.cross_project_symbols": ["TOKEN_GOAT_CROSS_PROJECT_SYMBOLS"],
|
|
2356
|
+
"injection.enabled": ["TOKEN_GOAT_INJECTION_ENABLED"],
|
|
2357
|
+
"gdrive.enabled": ["TOKEN_GOAT_GDRIVE_ENABLED"],
|
|
2358
|
+
"redaction.custom_patterns": ["TOKEN_GOAT_REDACTION_CUSTOM_PATTERNS"],
|
|
2359
|
+
"redaction.strict": ["TOKEN_GOAT_REDACTION_STRICT"],
|
|
2360
|
+
"network.offline": ["TOKEN_GOAT_OFFLINE"],
|
|
2361
|
+
"mcp.confine_reads_to_project_root": ["TOKEN_GOAT_MCP_CONFINE_READS"],
|
|
2362
|
+
"mcp.allowed_roots": ["TOKEN_GOAT_MCP_ALLOWED_ROOTS"],
|
|
2363
|
+
"webfetch.allow": ["TOKEN_GOAT_WEBFETCH_ALLOW"],
|
|
2364
|
+
"webfetch.deny": ["TOKEN_GOAT_WEBFETCH_DENY"],
|
|
2365
|
+
"indexing.embeddings_enabled": ["TOKEN_GOAT_EMBEDDINGS_ENABLED"]
|
|
2366
|
+
};
|
|
2367
|
+
function saveConfig(config) {
|
|
2368
|
+
const ca = config.compact_assist;
|
|
2369
|
+
const bc = config.bash_compress;
|
|
2370
|
+
const sp = config.skill_preservation;
|
|
2371
|
+
const is_cfg = config.image_shrink;
|
|
2372
|
+
const wasExplicit = isAutoTriggerMultiplierExplicit();
|
|
2373
|
+
const defaultMultiplier = getDefaultConfig("compact_assist").auto_trigger_multiplier;
|
|
2374
|
+
const keepsMultiplierDefault = !wasExplicit && ca.auto_trigger_multiplier === defaultMultiplier;
|
|
2375
|
+
const data = {
|
|
2376
|
+
compact_assist: {
|
|
2377
|
+
enabled: ca.enabled,
|
|
2378
|
+
triggers: ca.triggers,
|
|
2379
|
+
min_events: ca.min_events,
|
|
2380
|
+
max_manifest_tokens: ca.max_manifest_tokens,
|
|
2381
|
+
...keepsMultiplierDefault ? {} : { auto_trigger_multiplier: ca.auto_trigger_multiplier },
|
|
2382
|
+
compact_skip_ttl_secs: ca.compact_skip_ttl_secs,
|
|
2383
|
+
noise_floor_tokens: ca.noise_floor_tokens,
|
|
2384
|
+
edited_dir_group_threshold: ca.edited_dir_group_threshold,
|
|
2385
|
+
max_section_lines: ca.max_section_lines,
|
|
2386
|
+
wide_session_threshold: ca.wide_session_threshold,
|
|
2387
|
+
orchestrator_commit_threshold: ca.orchestrator_commit_threshold,
|
|
2388
|
+
max_manifest_chars: ca.max_manifest_chars,
|
|
2389
|
+
summary_budget_chars: ca.summary_budget_chars,
|
|
2390
|
+
harness: ca.harness
|
|
2391
|
+
},
|
|
2392
|
+
bash_compress: {
|
|
2393
|
+
enabled: bc.enabled,
|
|
2394
|
+
disabled_filters: bc.disabled_filters,
|
|
2395
|
+
max_lines: bc.max_lines,
|
|
2396
|
+
max_bytes: bc.max_bytes,
|
|
2397
|
+
timeout_seconds: bc.timeout_seconds,
|
|
2398
|
+
cache_min_bytes: bc.cache_min_bytes,
|
|
2399
|
+
cache_max_file_count: bc.cache_max_file_count,
|
|
2400
|
+
cache_max_bytes: bc.cache_max_bytes,
|
|
2401
|
+
cache_max_bytes_per_output: bc.cache_max_bytes_per_output,
|
|
2402
|
+
min_net_savings_bytes: bc.min_net_savings_bytes,
|
|
2403
|
+
elide_served_shell_output: bc.elide_served_shell_output
|
|
2404
|
+
},
|
|
2405
|
+
agent_report: {
|
|
2406
|
+
min_bytes: config.agent_report.min_bytes,
|
|
2407
|
+
fence_collapse_min_lines: config.agent_report.fence_collapse_min_lines,
|
|
2408
|
+
fence_collapse_keep_lines: config.agent_report.fence_collapse_keep_lines
|
|
2409
|
+
},
|
|
2410
|
+
bash_diff: {
|
|
2411
|
+
max_hunks_per_file: config.bash_diff.max_hunks_per_file
|
|
2412
|
+
},
|
|
2413
|
+
bash_severity_log: {
|
|
2414
|
+
context_lines: config.bash_severity_log.context_lines,
|
|
2415
|
+
score_threshold: config.bash_severity_log.score_threshold
|
|
2416
|
+
},
|
|
2417
|
+
post_read_code_compress: {
|
|
2418
|
+
min_lines: config.post_read_code_compress.min_lines
|
|
2419
|
+
},
|
|
2420
|
+
session_brief: {
|
|
2421
|
+
enabled: config.session_brief.enabled
|
|
2422
|
+
},
|
|
2423
|
+
skill_preservation: {
|
|
2424
|
+
enabled: sp.enabled,
|
|
2425
|
+
max_cache_bytes: sp.max_cache_bytes,
|
|
2426
|
+
orphan_sweep_enabled: sp.orphan_sweep_enabled,
|
|
2427
|
+
orphan_age_secs: sp.orphan_age_secs,
|
|
2428
|
+
truncation_budget_tokens: sp.truncation_budget_tokens,
|
|
2429
|
+
compress_bodies: sp.compress_bodies,
|
|
2430
|
+
compress_min_bytes: sp.compress_min_bytes,
|
|
2431
|
+
inline_snippets: sp.inline_snippets,
|
|
2432
|
+
pre_skill_enabled: sp.pre_skill_enabled,
|
|
2433
|
+
first_load_compact: sp.first_load_compact,
|
|
2434
|
+
post_compact_full_loads: sp.post_compact_full_loads
|
|
2435
|
+
},
|
|
2436
|
+
image_shrink: {
|
|
2437
|
+
enabled: is_cfg.enabled,
|
|
2438
|
+
jpeg_quality: is_cfg.jpeg_quality,
|
|
2439
|
+
max_image_pixels: is_cfg.max_image_pixels,
|
|
2440
|
+
screenshot_redirect: is_cfg.screenshot_redirect,
|
|
2441
|
+
ocr_enabled: is_cfg.ocr_enabled,
|
|
2442
|
+
ocr_min_confidence: is_cfg.ocr_min_confidence,
|
|
2443
|
+
ocr_lang: is_cfg.ocr_lang,
|
|
2444
|
+
vision_tier: is_cfg.vision_tier
|
|
2445
|
+
},
|
|
2446
|
+
screenshot: {
|
|
2447
|
+
chrome_path: config.screenshot.chrome_path,
|
|
2448
|
+
block_private_targets: config.screenshot.block_private_targets
|
|
2449
|
+
},
|
|
2450
|
+
repomap: {
|
|
2451
|
+
compact_file_threshold: config.repomap.compact_file_threshold,
|
|
2452
|
+
exclude_tests: config.repomap.exclude_tests
|
|
2453
|
+
},
|
|
2454
|
+
overflow_guard: {
|
|
2455
|
+
enabled: config.overflow_guard.enabled,
|
|
2456
|
+
max_tokens: config.overflow_guard.max_tokens
|
|
2457
|
+
},
|
|
2458
|
+
stats: {
|
|
2459
|
+
record_zero_savings: config.stats.record_zero_savings
|
|
2460
|
+
},
|
|
2461
|
+
hints: {
|
|
2462
|
+
quiet_hours: config.hints.quiet_hours,
|
|
2463
|
+
json_sidecar: config.hints.json_sidecar,
|
|
2464
|
+
min_file_lines_for_hint: config.hints.min_file_lines_for_hint,
|
|
2465
|
+
bash_dedup_min_bytes: config.hints.bash_dedup_min_bytes,
|
|
2466
|
+
web_dedup_min_bytes: config.hints.web_dedup_min_bytes,
|
|
2467
|
+
grep_dedup_min_matches: config.hints.grep_dedup_min_matches,
|
|
2468
|
+
glob_dedup_min_matches: config.hints.glob_dedup_min_matches,
|
|
2469
|
+
write_rewrite_min_lines: config.hints.write_rewrite_min_lines,
|
|
2470
|
+
write_rewrite_unchanged_pct: config.hints.write_rewrite_unchanged_pct,
|
|
2471
|
+
serve_diff_on_reread: config.hints.serve_diff_on_reread,
|
|
2472
|
+
elide_served_lines: config.hints.elide_served_lines,
|
|
2473
|
+
subagent_markdown_first_read_deny: config.hints.subagent_markdown_first_read_deny,
|
|
2474
|
+
backoff_thresholds: config.hints.backoff_thresholds,
|
|
2475
|
+
git_hint_max_ms: config.hints.git_hint_max_ms,
|
|
2476
|
+
min_session_hint_savings_bytes: config.hints.min_session_hint_savings_bytes,
|
|
2477
|
+
pre_skill_advisory: config.hints.pre_skill_advisory,
|
|
2478
|
+
context_threshold_advisory: config.hints.context_threshold_advisory,
|
|
2479
|
+
diff_hint_min_tokens_saved: config.hints.diff_hint_min_tokens_saved,
|
|
2480
|
+
large_read_redirect_bytes: config.hints.large_read_redirect_bytes,
|
|
2481
|
+
reread_deny: config.hints.reread_deny,
|
|
2482
|
+
reread_deny_min_bytes: config.hints.reread_deny_min_bytes,
|
|
2483
|
+
stable_doc_compacts: config.hints.stable_doc_compacts,
|
|
2484
|
+
fold_code_bodies: config.hints.fold_code_bodies,
|
|
2485
|
+
fold_comment_blocks: config.hints.fold_comment_blocks,
|
|
2486
|
+
fold_prose_paragraphs: config.hints.fold_prose_paragraphs,
|
|
2487
|
+
outline_large_documents: config.hints.outline_large_documents,
|
|
2488
|
+
skeleton_large_sources: config.hints.skeleton_large_sources,
|
|
2489
|
+
truncated_read_min_lines: config.hints.truncated_read_min_lines,
|
|
2490
|
+
protect_recent_reads: config.hints.protect_recent_reads,
|
|
2491
|
+
prompt_triggers: config.hints.prompt_triggers,
|
|
2492
|
+
warn_unbalanced_shell_quoting: config.hints.warn_unbalanced_shell_quoting,
|
|
2493
|
+
log_large_file_hint_outcomes: config.hints.log_large_file_hint_outcomes,
|
|
2494
|
+
cross_session_read_dedup: config.hints.cross_session_read_dedup,
|
|
2495
|
+
cross_session_read_dedup_ttl_secs: config.hints.cross_session_read_dedup_ttl_secs,
|
|
2496
|
+
mcp_dedup_ttl_secs: config.hints.mcp_dedup_ttl_secs,
|
|
2497
|
+
session_start_reminder: config.hints.session_start_reminder
|
|
2498
|
+
},
|
|
2499
|
+
hooks: {
|
|
2500
|
+
watchdog_ms: config.hooks.watchdog_ms
|
|
2501
|
+
},
|
|
2502
|
+
webfetch: {
|
|
2503
|
+
allow: config.webfetch.allow,
|
|
2504
|
+
deny: config.webfetch.deny,
|
|
2505
|
+
max_file_count: config.webfetch.max_file_count,
|
|
2506
|
+
max_bytes: config.webfetch.max_bytes,
|
|
2507
|
+
compress_bodies: config.webfetch.compress_bodies,
|
|
2508
|
+
compress_min_bytes: config.webfetch.compress_min_bytes
|
|
2509
|
+
},
|
|
2510
|
+
worker: {
|
|
2511
|
+
blocked_roots: config.worker.blocked_roots,
|
|
2512
|
+
max_pool_workers: config.worker.max_pool_workers,
|
|
2513
|
+
embed_threads: config.worker.embed_threads,
|
|
2514
|
+
priority: config.worker.priority
|
|
2515
|
+
},
|
|
2516
|
+
indexing: {
|
|
2517
|
+
large_file_symbol_only_kb: config.indexing.large_file_symbol_only_kb,
|
|
2518
|
+
large_file_skip_kb: config.indexing.large_file_skip_kb,
|
|
2519
|
+
skip_dirs: config.indexing.skip_dirs,
|
|
2520
|
+
skip_files: config.indexing.skip_files,
|
|
2521
|
+
embeddings_enabled: config.indexing.embeddings_enabled,
|
|
2522
|
+
cross_project_symbols: config.indexing.cross_project_symbols
|
|
2523
|
+
},
|
|
2524
|
+
compression: {
|
|
2525
|
+
profile: config.compression.profile
|
|
2526
|
+
},
|
|
2527
|
+
context: {
|
|
2528
|
+
model_window_tokens: config.context.model_window_tokens
|
|
2529
|
+
},
|
|
2530
|
+
injection: {
|
|
2531
|
+
enabled: config.injection.enabled
|
|
2532
|
+
},
|
|
2533
|
+
gdrive: {
|
|
2534
|
+
enabled: config.gdrive.enabled
|
|
2535
|
+
},
|
|
2536
|
+
redaction: {
|
|
2537
|
+
custom_patterns: config.redaction.custom_patterns,
|
|
2538
|
+
strict: config.redaction.strict
|
|
2539
|
+
},
|
|
2540
|
+
network: {
|
|
2541
|
+
offline: config.network.offline
|
|
2542
|
+
},
|
|
2543
|
+
mcp: {
|
|
2544
|
+
confine_reads_to_project_root: config.mcp.confine_reads_to_project_root
|
|
2545
|
+
},
|
|
2546
|
+
hint_stats: {
|
|
2547
|
+
suppress_threshold_pct: config.hint_stats.suppress_threshold_pct,
|
|
2548
|
+
min_sample_size: config.hint_stats.min_sample_size
|
|
2549
|
+
},
|
|
2550
|
+
semantic: {
|
|
2551
|
+
archive_weight: config.semantic.archive_weight,
|
|
2552
|
+
docs_weight: config.semantic.docs_weight
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
const toml = stringify(data);
|
|
2556
|
+
atomicWriteText(configPath(), toml);
|
|
2557
|
+
_cached2 = null;
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
export {
|
|
2561
|
+
parse,
|
|
2562
|
+
stringify,
|
|
2563
|
+
detectHarness,
|
|
2564
|
+
getHarnessName,
|
|
2565
|
+
envBool,
|
|
2566
|
+
envInt,
|
|
2567
|
+
envStrList,
|
|
2568
|
+
fingerprintContent,
|
|
2569
|
+
shortFingerprint,
|
|
2570
|
+
fingerprintFile,
|
|
2571
|
+
fileIsAbsent,
|
|
2572
|
+
DEFAULT_OCR_LANG,
|
|
2573
|
+
SUPPORTED_OCR_LANG_CODES,
|
|
2574
|
+
isSupportedOcrLang,
|
|
2575
|
+
resolveOcrLangs,
|
|
2576
|
+
defaultConfig,
|
|
2577
|
+
makeProjectAt,
|
|
2578
|
+
findProject,
|
|
2579
|
+
getDisplayRoot,
|
|
2580
|
+
isUnderSystemTemp,
|
|
2581
|
+
resolveProjectRoot,
|
|
2582
|
+
PROJECT_LOCKED_SECTIONS,
|
|
2583
|
+
PROJECT_LOCKED_KEYS,
|
|
2584
|
+
lastProjectConfigLockedKeys,
|
|
2585
|
+
readConfigSource,
|
|
2586
|
+
getProjectConfigInfo,
|
|
2587
|
+
isAutoTriggerMultiplierExplicit,
|
|
2588
|
+
validateNumericField,
|
|
2589
|
+
validateEnumField,
|
|
2590
|
+
getLastConfigParseError,
|
|
2591
|
+
getLastProjectConfigParseError,
|
|
2592
|
+
resolveConfigKeyLayer,
|
|
2593
|
+
loadConfig,
|
|
2594
|
+
invalidateConfigCache,
|
|
2595
|
+
loadPersistedConfig,
|
|
2596
|
+
CONFIG_KEY_ENV_OVERRIDES,
|
|
2597
|
+
saveConfig
|
|
2598
|
+
};
|
|
2599
|
+
/*! Bundled license information:
|
|
2600
|
+
|
|
2601
|
+
smol-toml/dist/date.js:
|
|
2602
|
+
smol-toml/dist/error.js:
|
|
2603
|
+
smol-toml/dist/util.js:
|
|
2604
|
+
smol-toml/dist/primitive.js:
|
|
2605
|
+
smol-toml/dist/extract.js:
|
|
2606
|
+
smol-toml/dist/struct.js:
|
|
2607
|
+
smol-toml/dist/parse.js:
|
|
2608
|
+
smol-toml/dist/stringify.js:
|
|
2609
|
+
smol-toml/dist/index.js:
|
|
2610
|
+
(*!
|
|
2611
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
2612
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
2613
|
+
*
|
|
2614
|
+
* Redistribution and use in source and binary forms, with or without
|
|
2615
|
+
* modification, are permitted provided that the following conditions are met:
|
|
2616
|
+
*
|
|
2617
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
2618
|
+
* list of conditions and the following disclaimer.
|
|
2619
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
2620
|
+
* this list of conditions and the following disclaimer in the
|
|
2621
|
+
* documentation and/or other materials provided with the distribution.
|
|
2622
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
2623
|
+
* may be used to endorse or promote products derived from this software without
|
|
2624
|
+
* specific prior written permission.
|
|
2625
|
+
*
|
|
2626
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
2627
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
2628
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
2629
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
2630
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2631
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
2632
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
2633
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
2634
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
2635
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
2636
|
+
*)
|
|
2637
|
+
*/
|