context-mode 2.0.0-next.7 → 2.0.0-next.8
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/SHA256SUMS +14 -14
- package/cli.mjs +2988 -684
- package/copilot/plugin.json +1 -1
- package/gemini-extension.json +1 -1
- package/hook.mjs +84 -82
- package/opencode/plugin.js +3031 -818
- package/package.json +1 -1
- package/pi/index.js +2982 -769
- package/qwen-extension.json +1 -1
- package/run.mjs +96 -33
- package/search.mjs +96 -33
- package/server.mjs +2946 -732
package/cli.mjs
CHANGED
|
@@ -88,7 +88,7 @@ var require_src = __commonJS({
|
|
|
88
88
|
// src/entries/cli.ts
|
|
89
89
|
import { spawn as spawn2 } from "node:child_process";
|
|
90
90
|
import { readFileSync as readFileSync5, realpathSync as realpathSync5 } from "node:fs";
|
|
91
|
-
import
|
|
91
|
+
import path8 from "node:path";
|
|
92
92
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
93
93
|
|
|
94
94
|
// src/core/contracts/constants.ts
|
|
@@ -240,7 +240,6 @@ var PLAIN_OUTPUT_ENV = Object.freeze({ NO_COLOR: "1", FORCE_COLOR: "0" });
|
|
|
240
240
|
var HOST_SESSION_ENV = Object.freeze({ "claude-code": "CLAUDE_CODE_SESSION_ID" });
|
|
241
241
|
var NODE_MIN = "24.15.0";
|
|
242
242
|
var DATA_ROOT = "~/.context-mode";
|
|
243
|
-
var HOST_CONFIG_DIR_NAME = ".claude";
|
|
244
243
|
var HOST_PLUGINS_DIR_NAME = "plugins";
|
|
245
244
|
var INSTALLED_PLUGINS_FILE = "installed_plugins.json";
|
|
246
245
|
var MCP_HINT_EVERY_DEFAULT = 10;
|
|
@@ -280,7 +279,7 @@ var EDIT_PATH_KEYS = Object.freeze(["file_path", "path"]);
|
|
|
280
279
|
var AGENT_ARG = "--agent";
|
|
281
280
|
var STATS_COLUMNS = Object.freeze(["Scope", "Produced", "Returned", "Saved", "Reduction %"]);
|
|
282
281
|
var PURGE_SCOPES = Object.freeze(["session", "source", "project"]);
|
|
283
|
-
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10"]);
|
|
282
|
+
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10", "D11"]);
|
|
284
283
|
var DOCTOR_LABEL = Object.freeze({
|
|
285
284
|
D1: "version",
|
|
286
285
|
D2: "node",
|
|
@@ -292,7 +291,8 @@ var DOCTOR_LABEL = Object.freeze({
|
|
|
292
291
|
D7: "project and worktree",
|
|
293
292
|
D8: "context.db",
|
|
294
293
|
D9: "index",
|
|
295
|
-
D10: "enforcement mode"
|
|
294
|
+
D10: "enforcement mode",
|
|
295
|
+
D11: "shell"
|
|
296
296
|
});
|
|
297
297
|
var REPORT_TRUNCATED_LINE = `(report truncated at ${REPORT_CAP} B; run ctx_doctor again after the first fix)`;
|
|
298
298
|
var D2_NODE_FIX = `install Node ${NODE_MIN} or later`;
|
|
@@ -315,6 +315,8 @@ var GIT_HEAD_SHA_ARGS = Object.freeze(["rev-parse", "HEAD"]);
|
|
|
315
315
|
var UPGRADE_GIT_CHECKOUT_AGENTS = Object.freeze(["pi", "opencode"]);
|
|
316
316
|
var GIT_NO_PROMPT_ENV = Object.freeze({ GIT_TERMINAL_PROMPT: "0" });
|
|
317
317
|
var GIT_NO_CRLF_ENV = Object.freeze({ GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.autocrlf", GIT_CONFIG_VALUE_0: "false" });
|
|
318
|
+
var WIN_SHELL_LANGS = Object.freeze(["shell", "bash", "sh"]);
|
|
319
|
+
var GIT_BASH_RELATIVE = Object.freeze([["..", "bin", "bash.exe"], ["..", "..", "bin", "bash.exe"]]);
|
|
318
320
|
var OPS_SPLIT_FILES = Object.freeze([
|
|
319
321
|
"doctor-env.ts",
|
|
320
322
|
"doctor-config.ts",
|
|
@@ -331,10 +333,10 @@ var OPS_SPLIT_FILES = Object.freeze([
|
|
|
331
333
|
var HOOK_HOST_FILE = Object.freeze({
|
|
332
334
|
"claude-code": { root: "plugin", file: ["hooks", "claude-code.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
333
335
|
codex: { root: "home", file: [".codex", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
334
|
-
gemini: { root: "
|
|
335
|
-
qwen: { root: "
|
|
336
|
+
gemini: { root: "plugin", file: ["hooks", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: false },
|
|
337
|
+
qwen: { root: "plugin", file: ["hooks", "qwen.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
336
338
|
"copilot-cli": { root: "home", file: [".copilot", "hooks", "context-mode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeoutSec", matcher: false },
|
|
337
|
-
vscode: { root: "
|
|
339
|
+
vscode: { root: "home", file: [".copilot", "hooks", "context-mode-vscode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeout", matcher: false },
|
|
338
340
|
kiro: { root: "home", file: [".kiro", "hooks", "context-mode.json"], key: ["hooks"], shape: "kiro", timeoutKey: "timeout", matcher: false },
|
|
339
341
|
zcode: { root: "home", file: [".zcode", "cli", "config.json"], key: ["hooks", "events"], shape: "zcode", timeoutKey: "timeoutMs", matcher: true },
|
|
340
342
|
pi: null,
|
|
@@ -388,6 +390,13 @@ var V1_HOOKS_DIR_NAME = "hooks";
|
|
|
388
390
|
var SETTINGS_FILE = "settings.json";
|
|
389
391
|
var CLAUDE_USER_CONFIG_FILE = ".claude.json";
|
|
390
392
|
var HOOKS_JSON_FILE = "hooks.json";
|
|
393
|
+
var CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR";
|
|
394
|
+
var COPILOT_HOME_ENV = "COPILOT_HOME";
|
|
395
|
+
var KIRO_HOME_ENV = "KIRO_HOME";
|
|
396
|
+
var OPENCODE_CONFIG_DIR_ENV = "OPENCODE_CONFIG_DIR";
|
|
397
|
+
var APPDATA_ENV = "APPDATA";
|
|
398
|
+
var VSCODE_USER_DIR_SEGMENTS = Object.freeze(["Code", "User"]);
|
|
399
|
+
var XDG_CONFIG_HOME_ENV = "XDG_CONFIG_HOME";
|
|
391
400
|
var CONFIG_TOML_FILE = "config.toml";
|
|
392
401
|
var CONFIG_JSON_FILE = "config.json";
|
|
393
402
|
var ZCODE_CLI_DIR = "cli";
|
|
@@ -402,6 +411,7 @@ var KIRO_AGENT_NAME_KEY = "name";
|
|
|
402
411
|
var KIRO_STEERING_FILE = Object.freeze(["steering", "KIRO.md"]);
|
|
403
412
|
var PI_AGENT_DIR = "agent";
|
|
404
413
|
var OPENCODE_CONFIG_FILES = Object.freeze(["opencode.jsonc", "opencode.json"]);
|
|
414
|
+
var OPENCODE_BASE_CONFIG_FILE = "opencode.json";
|
|
405
415
|
var MCP_SERVERS_KEY = "mcpServers";
|
|
406
416
|
var HOOKS_KEY = "hooks";
|
|
407
417
|
var STATUS_LINE_KEY = "statusLine";
|
|
@@ -417,6 +427,8 @@ var ZCODE_EVENTS_KEY = "events";
|
|
|
417
427
|
var PI_ROLE = "custom";
|
|
418
428
|
var PI_PACKAGE_SOURCE_KEY = "source";
|
|
419
429
|
var V1_PATH_SEPS = Object.freeze(["/", "\\"]);
|
|
430
|
+
var HOST_SEP_TOKEN = "${/}";
|
|
431
|
+
var HOOK_SCRIPT_SEPS = Object.freeze([...V1_PATH_SEPS, HOST_SEP_TOKEN]);
|
|
420
432
|
var V1_REASON = Object.freeze({
|
|
421
433
|
hook: "old context-mode hook entry: command contains context-mode and an old script name or context-mode hook",
|
|
422
434
|
cacheHealHook: "old context-mode cache-heal SessionStart hook entry",
|
|
@@ -440,6 +452,11 @@ var V1_REASON = Object.freeze({
|
|
|
440
452
|
});
|
|
441
453
|
var UPGRADE_REPORT_ONLY_REASONS = Object.freeze([V1_REASON.statusLine, V1_REASON.vscodeMcp, V1_REASON.dataDirShared, V1_REASON.tmpFile, V1_REASON.kiroSteering]);
|
|
442
454
|
var OPENCODE_TOOL_PREFIX = SERVER_KEY + "_";
|
|
455
|
+
var ATOMIC_RENAME_RETRIES = 5;
|
|
456
|
+
var ATOMIC_RENAME_DELAY_MS = 50;
|
|
457
|
+
var ATOMIC_RENAME_BUSY_CODES = ["EPERM", "EBUSY", "EACCES"];
|
|
458
|
+
var ATOMIC_TMP_PREFIX = ".";
|
|
459
|
+
var ATOMIC_TMP_MARK = ".cm-tmp-";
|
|
443
460
|
var JSON_INDENT_UNIT = " ";
|
|
444
461
|
var ZCODE_MCP_FEATURE_KEY = Object.freeze(["features", "mcp"]);
|
|
445
462
|
var CODEX_OMIT_TOOLS_FROM_FIELD = "omit_tools_from";
|
|
@@ -448,7 +465,7 @@ var CODEX_APPROVAL_MODE_FIELD = "default_tools_approval_mode";
|
|
|
448
465
|
var CODEX_APPROVAL_APPROVE = "approve";
|
|
449
466
|
var OWN_MCP_ENTRY = Object.freeze({
|
|
450
467
|
codex: { file: [".codex", "config.toml"], key: ["mcp_servers", SERVER_KEY], fields: { [CODEX_OMIT_TOOLS_FROM_FIELD]: CODEX_OMIT_DEFERRED, [CODEX_APPROVAL_MODE_FIELD]: CODEX_APPROVAL_APPROVE } },
|
|
451
|
-
vscode: { file: [
|
|
468
|
+
vscode: { file: [VSCODE_MCP_FILE], key: ["servers", SERVER_KEY] },
|
|
452
469
|
kiro: { file: [".kiro", "settings", "mcp.json"], key: ["mcpServers", SERVER_KEY] },
|
|
453
470
|
zcode: {
|
|
454
471
|
file: [".zcode", "cli", "config.json"],
|
|
@@ -818,8 +835,14 @@ var VSCODE_EVENTS = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostTool
|
|
|
818
835
|
var MCP_PREFIX2 = "mcp_";
|
|
819
836
|
var MCP_SEP2 = "_";
|
|
820
837
|
var SESSION_START_NEW = "new";
|
|
821
|
-
var
|
|
822
|
-
var
|
|
838
|
+
var SHELL_TOOL_NAMES = Object.freeze(["run_in_terminal", "runTerminalCommand", "bash", "powershell"]);
|
|
839
|
+
var READ_TOOL_NAMES = Object.freeze(["read_file", "view"]);
|
|
840
|
+
var WEBFETCH_TOOL_NAMES = Object.freeze(["fetch_webpage", "web_fetch"]);
|
|
841
|
+
var NATIVE_TO_CANONICAL4 = Object.fromEntries([
|
|
842
|
+
...SHELL_TOOL_NAMES.map((n3) => [n3, "Bash"]),
|
|
843
|
+
...READ_TOOL_NAMES.map((n3) => [n3, "Read"]),
|
|
844
|
+
...WEBFETCH_TOOL_NAMES.map((n3) => [n3, "WebFetch"])
|
|
845
|
+
]);
|
|
823
846
|
function canonicalName4(name) {
|
|
824
847
|
if (name.startsWith(TOOL_NAME_PREFIX6)) return name.slice(TOOL_NAME_PREFIX6.length);
|
|
825
848
|
if (Object.hasOwn(NATIVE_TO_CANONICAL4, name)) return NATIVE_TO_CANONICAL4[name];
|
|
@@ -829,6 +852,26 @@ function canonicalName4(name) {
|
|
|
829
852
|
if (sep <= 0 || sep === rest.length - 1) return name;
|
|
830
853
|
return "mcp:" + rest.slice(0, sep) + ":" + rest.slice(sep + MCP_SEP2.length);
|
|
831
854
|
}
|
|
855
|
+
var isNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
856
|
+
function policyInput(name, canonical, input) {
|
|
857
|
+
if (canonical === "Read" && READ_TOOL_NAMES.includes(name)) {
|
|
858
|
+
const out2 = { ...input };
|
|
859
|
+
if (name === "read_file") {
|
|
860
|
+
if (typeof input.filePath === "string") out2.file_path = input.filePath;
|
|
861
|
+
if (isNum(input.startLine)) out2.offset = input.startLine;
|
|
862
|
+
if (isNum(input.startLine) && isNum(input.endLine) && input.endLine >= input.startLine) out2.limit = input.endLine - input.startLine + 1;
|
|
863
|
+
} else if (Array.isArray(input.view_range) && isNum(input.view_range[0])) {
|
|
864
|
+
out2.offset = input.view_range[0];
|
|
865
|
+
const end = input.view_range[1];
|
|
866
|
+
if (isNum(end) && end >= input.view_range[0]) out2.limit = end - input.view_range[0] + 1;
|
|
867
|
+
}
|
|
868
|
+
return out2;
|
|
869
|
+
}
|
|
870
|
+
if (canonical === "WebFetch" && name === "fetch_webpage" && Array.isArray(input.urls) && typeof input.urls[0] === "string") {
|
|
871
|
+
return { ...input, url: input.urls[0] };
|
|
872
|
+
}
|
|
873
|
+
return input;
|
|
874
|
+
}
|
|
832
875
|
function readResult4(resp) {
|
|
833
876
|
const text2 = resp === void 0 ? "" : typeof resp === "string" ? resp : JSON.stringify(resp);
|
|
834
877
|
const isError = typeof resp === "object" && resp !== null && resp.is_error === true;
|
|
@@ -876,7 +919,8 @@ function decodeCamel(p3, name) {
|
|
|
876
919
|
if (event === "UserPromptSubmit" && typeof p3.prompt === "string") ev.prompt = p3.prompt;
|
|
877
920
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
878
921
|
const toolName = String(p3.toolName ?? "");
|
|
879
|
-
|
|
922
|
+
const canonical = canonicalName4(toolName);
|
|
923
|
+
ev.tool = { name: toolName, canonicalName: canonical, input: policyInput(toolName, canonical, readArgs2(p3.toolArgs)) };
|
|
880
924
|
}
|
|
881
925
|
if (event === "PostToolUse") ev.result = readCamelResult(p3.toolResult);
|
|
882
926
|
return ev;
|
|
@@ -898,7 +942,8 @@ function decode6(raw) {
|
|
|
898
942
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
899
943
|
const name = String(p3.tool_name ?? "");
|
|
900
944
|
const input = isRecord2(p3.tool_input) ? p3.tool_input : {};
|
|
901
|
-
|
|
945
|
+
const canonical = canonicalName4(name);
|
|
946
|
+
ev.tool = { name, canonicalName: canonical, input: policyInput(name, canonical, input) };
|
|
902
947
|
}
|
|
903
948
|
if (event === "PostToolUse") ev.result = readResult4(p3.tool_response);
|
|
904
949
|
return ev;
|
|
@@ -922,8 +967,8 @@ var KIRO_EVENTS = {
|
|
|
922
967
|
};
|
|
923
968
|
var PROMPT_ENV = "USER_PROMPT";
|
|
924
969
|
var MCP_PREFIX3 = "mcp_";
|
|
925
|
-
var
|
|
926
|
-
var NATIVE_TO_CANONICAL5 = Object.fromEntries(
|
|
970
|
+
var SHELL_TOOL_NAMES2 = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
|
|
971
|
+
var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES2.map((n3) => [n3, "Bash"]));
|
|
927
972
|
var MCP_SEP3 = "_";
|
|
928
973
|
var KIRO_SOURCES = { startup: "startup", resume: "resume", clear: "clear", compact: "compact" };
|
|
929
974
|
function canonicalName5(name) {
|
|
@@ -1064,8 +1109,8 @@ var OPENCODE_EVENTS = {
|
|
|
1064
1109
|
compaction: "PreCompact",
|
|
1065
1110
|
"step-finish": "Usage"
|
|
1066
1111
|
};
|
|
1067
|
-
var
|
|
1068
|
-
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [
|
|
1112
|
+
var SHELL_TOOL_NAME = "bash";
|
|
1113
|
+
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME]: "Bash" };
|
|
1069
1114
|
function toCanonicalTool(name) {
|
|
1070
1115
|
if (name.startsWith(OWN_WIRE_PREFIX)) return name.slice(OWN_WIRE_PREFIX.length);
|
|
1071
1116
|
return Object.prototype.hasOwnProperty.call(NATIVE_TO_CANONICAL7, name) ? NATIVE_TO_CANONICAL7[name] : name;
|
|
@@ -1214,7 +1259,8 @@ var ADAPTERS = Object.freeze([
|
|
|
1214
1259
|
projectSource: "arg:workspaceFolder",
|
|
1215
1260
|
toolNamePrefix: TOOL_NAME_PREFIX6,
|
|
1216
1261
|
// PreCompact sets the pending flag (ADR-0009 §6, DEVIATIONS D-M3-A4-1).
|
|
1217
|
-
nativeTools: { shell: [
|
|
1262
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES], read: [...READ_TOOL_NAMES], webfetch: [...WEBFETCH_TOOL_NAMES] },
|
|
1263
|
+
// D-HF-VSCODE-PROJECT-1, D-N7-VSCODE-TOOLS-1
|
|
1218
1264
|
execReadOnlyHint: false,
|
|
1219
1265
|
eventMap: { ...CLAUDE_EVENTS, PreCompact: "PreCompact" },
|
|
1220
1266
|
compactDelivery: "pending-flag",
|
|
@@ -1232,7 +1278,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1232
1278
|
installMode: "mcp-entry",
|
|
1233
1279
|
projectSource: "arg:--agent+cwd",
|
|
1234
1280
|
toolNamePrefix: TOOL_NAME_PREFIX7,
|
|
1235
|
-
nativeTools: { shell: [...
|
|
1281
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES2] },
|
|
1236
1282
|
execReadOnlyHint: false,
|
|
1237
1283
|
// D-HF-KIRO-SHELL-1, D-N7-KIRO-1
|
|
1238
1284
|
eventMap: { SessionStart: "SessionStart", UserPromptSubmit: "UserPromptSubmit", PreToolUse: "PreToolUse", PostToolUse: "PostToolUse" },
|
|
@@ -1289,7 +1335,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1289
1335
|
installMode: "in-process",
|
|
1290
1336
|
projectSource: "spawn-cwd",
|
|
1291
1337
|
toolNamePrefix: TOOL_NAME_PREFIX10,
|
|
1292
|
-
nativeTools: { shell: [
|
|
1338
|
+
nativeTools: { shell: [SHELL_TOOL_NAME] },
|
|
1293
1339
|
execReadOnlyHint: false,
|
|
1294
1340
|
// D-HF-OPENCODE-SHELL-1
|
|
1295
1341
|
// Usage: step-finish cost row (DEVIATIONS D-M5-arch-2).
|
|
@@ -1519,11 +1565,11 @@ Examples:
|
|
|
1519
1565
|
};
|
|
1520
1566
|
|
|
1521
1567
|
// src/cli/commands.ts
|
|
1522
|
-
import { spawnSync as
|
|
1568
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
1523
1569
|
import { createHash as createHash2 } from "node:crypto";
|
|
1524
|
-
import { existsSync as existsSync7, mkdirSync as
|
|
1570
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1525
1571
|
import os from "node:os";
|
|
1526
|
-
import
|
|
1572
|
+
import path7 from "node:path";
|
|
1527
1573
|
|
|
1528
1574
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
1529
1575
|
var dist_exports = {};
|
|
@@ -1813,17 +1859,17 @@ var wrapWord = (rows, word, columns) => {
|
|
|
1813
1859
|
};
|
|
1814
1860
|
var stringVisibleTrimSpacesRight = (string) => {
|
|
1815
1861
|
const words = string.split(" ");
|
|
1816
|
-
let
|
|
1817
|
-
while (
|
|
1818
|
-
if (dist_default2(words[
|
|
1862
|
+
let last2 = words.length;
|
|
1863
|
+
while (last2) {
|
|
1864
|
+
if (dist_default2(words[last2 - 1])) {
|
|
1819
1865
|
break;
|
|
1820
1866
|
}
|
|
1821
|
-
|
|
1867
|
+
last2--;
|
|
1822
1868
|
}
|
|
1823
|
-
if (
|
|
1869
|
+
if (last2 === words.length) {
|
|
1824
1870
|
return string;
|
|
1825
1871
|
}
|
|
1826
|
-
return words.slice(0,
|
|
1872
|
+
return words.slice(0, last2).join(" ") + words.slice(last2).join("");
|
|
1827
1873
|
};
|
|
1828
1874
|
var exec = (string, columns, options = {}) => {
|
|
1829
1875
|
if (options.trim !== false && string.trim() === "") {
|
|
@@ -4340,14 +4386,8 @@ ${i2}
|
|
|
4340
4386
|
}
|
|
4341
4387
|
}).prompt();
|
|
4342
4388
|
|
|
4343
|
-
// src/setup/registry.ts
|
|
4344
|
-
import path2 from "node:path";
|
|
4345
|
-
|
|
4346
|
-
// src/core/ops/doctor-config.ts
|
|
4347
|
-
import { join as join6 } from "node:path";
|
|
4348
|
-
|
|
4349
4389
|
// src/core/project/config-dir.ts
|
|
4350
|
-
import { join as join2 } from "node:path";
|
|
4390
|
+
import { join as join2, posix, win32 } from "node:path";
|
|
4351
4391
|
|
|
4352
4392
|
// src/core/contracts/errors.ts
|
|
4353
4393
|
var ERROR_TEXT = Object.freeze({
|
|
@@ -4357,6 +4397,8 @@ var ERROR_TEXT = Object.freeze({
|
|
|
4357
4397
|
NO_PROJECT: "Project source <kind> is missing. Fix: run ctx_doctor.",
|
|
4358
4398
|
UNKNOWN_FIELD: 'Unknown field "<f>". Fix: use "queries".',
|
|
4359
4399
|
TIMEOUT: "Timed out after <ms> ms. Fix: pass background: true.",
|
|
4400
|
+
NO_GIT_BASH: "Git Bash not found. Fix: install Git for Windows.",
|
|
4401
|
+
// D-VT-WINBASH-1
|
|
4360
4402
|
NO_RUNTIME: "No <lang> runtime on PATH. Fix: install it or pick another language.",
|
|
4361
4403
|
FETCH_FAILED: "Fetch failed: <code>. Fix: check the URL or proxy.",
|
|
4362
4404
|
SSRF: "Blocked private address <host>. Fix: use a public URL.",
|
|
@@ -4419,294 +4461,2200 @@ var CtxError = class extends Error {
|
|
|
4419
4461
|
|
|
4420
4462
|
// src/core/project/config-dir.ts
|
|
4421
4463
|
var { mkdirSync, realpathSync } = process.getBuiltinModule("node:fs");
|
|
4464
|
+
function homeDirOf(env, platform = process.platform) {
|
|
4465
|
+
const set2 = (v) => v !== void 0 && v !== "";
|
|
4466
|
+
if (platform === "win32") {
|
|
4467
|
+
if (set2(env.USERPROFILE)) return env.USERPROFILE;
|
|
4468
|
+
if (set2(env.HOMEDRIVE) && set2(env.HOMEPATH)) return env.HOMEDRIVE + env.HOMEPATH;
|
|
4469
|
+
return set2(env.HOME) ? env.HOME : null;
|
|
4470
|
+
}
|
|
4471
|
+
if (set2(env.HOME)) return env.HOME;
|
|
4472
|
+
return set2(env.USERPROFILE) ? env.USERPROFILE : null;
|
|
4473
|
+
}
|
|
4474
|
+
function copilotDirOf(env, home) {
|
|
4475
|
+
const dir = env[COPILOT_HOME_ENV];
|
|
4476
|
+
return dir !== void 0 && dir !== "" ? dir : join2(home, ...AGENT_HOME_DIR["copilot-cli"]);
|
|
4477
|
+
}
|
|
4478
|
+
function kiroDirOf(env, home, platform = process.platform) {
|
|
4479
|
+
const p3 = platform === "win32" ? win32 : posix;
|
|
4480
|
+
const fallback = p3.join(home, ...AGENT_HOME_DIR.kiro);
|
|
4481
|
+
const dir = env[KIRO_HOME_ENV];
|
|
4482
|
+
if (dir === void 0 || dir === "" || !p3.isAbsolute(dir)) return fallback;
|
|
4483
|
+
if (platform === "win32" && p3.parse(dir).root.length < 2) return fallback;
|
|
4484
|
+
const abs = p3.resolve(dir);
|
|
4485
|
+
if (p3.dirname(abs) === abs) return fallback;
|
|
4486
|
+
const up = p3.relative(abs, p3.resolve(home));
|
|
4487
|
+
if (!p3.isAbsolute(up) && up.split(p3.sep)[0] !== "..") return fallback;
|
|
4488
|
+
return dir;
|
|
4489
|
+
}
|
|
4490
|
+
function claudeDirOf(env, home) {
|
|
4491
|
+
const dir = env[CLAUDE_CONFIG_DIR_ENV];
|
|
4492
|
+
return dir !== void 0 && dir !== "" ? dir : join2(home, ...AGENT_HOME_DIR["claude-code"]);
|
|
4493
|
+
}
|
|
4494
|
+
function opencodeDirOf(env, home) {
|
|
4495
|
+
const own2 = env[OPENCODE_CONFIG_DIR_ENV];
|
|
4496
|
+
if (own2 !== void 0 && own2 !== "") return own2;
|
|
4497
|
+
const xdg = env[XDG_CONFIG_HOME_ENV];
|
|
4498
|
+
if (xdg !== void 0 && xdg !== "") return join2(xdg, AGENT_HOME_DIR.opencode[AGENT_HOME_DIR.opencode.length - 1]);
|
|
4499
|
+
return join2(home, ...AGENT_HOME_DIR.opencode);
|
|
4500
|
+
}
|
|
4501
|
+
function vscodeUserDirOf(env, home, platform = process.platform) {
|
|
4502
|
+
const set2 = (v) => v !== void 0 && v !== "";
|
|
4503
|
+
const p3 = platform === "win32" ? win32 : posix;
|
|
4504
|
+
if (platform === "win32") return p3.join(set2(env[APPDATA_ENV]) ? env[APPDATA_ENV] : p3.join(home, "AppData", "Roaming"), ...VSCODE_USER_DIR_SEGMENTS);
|
|
4505
|
+
if (platform === "darwin") return p3.join(home, "Library", "Application Support", ...VSCODE_USER_DIR_SEGMENTS);
|
|
4506
|
+
return p3.join(set2(env[XDG_CONFIG_HOME_ENV]) ? env[XDG_CONFIG_HOME_ENV] : p3.join(home, ".config"), ...VSCODE_USER_DIR_SEGMENTS);
|
|
4507
|
+
}
|
|
4508
|
+
function ownMcpFileOf(agent, file, env, home) {
|
|
4509
|
+
if (agent === "kiro") return join2(kiroDirOf(env, home), ...file.slice(1));
|
|
4510
|
+
return agent === "vscode" ? join2(vscodeUserDirOf(env, home), ...file) : join2(home, ...file);
|
|
4511
|
+
}
|
|
4512
|
+
|
|
4513
|
+
// src/setup/registry.ts
|
|
4514
|
+
import path3 from "node:path";
|
|
4515
|
+
|
|
4516
|
+
// src/core/ops/doctor-config.ts
|
|
4517
|
+
import { join as join6 } from "node:path";
|
|
4422
4518
|
|
|
4423
4519
|
// src/core/ops/detect-v1.ts
|
|
4424
|
-
import { existsSync as
|
|
4520
|
+
import { existsSync as existsSync3, opendirSync, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
4425
4521
|
import { tmpdir } from "node:os";
|
|
4426
|
-
import { join as
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4522
|
+
import { join as join4 } from "node:path";
|
|
4523
|
+
|
|
4524
|
+
// src/core/ops/host-config.ts
|
|
4525
|
+
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
4526
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
4527
|
+
|
|
4528
|
+
// node_modules/eslint-visitor-keys/lib/visitor-keys.js
|
|
4529
|
+
var KEYS2 = {
|
|
4530
|
+
ArrayExpression: ["elements"],
|
|
4531
|
+
ArrayPattern: ["elements"],
|
|
4532
|
+
ArrowFunctionExpression: ["params", "body"],
|
|
4533
|
+
AssignmentExpression: ["left", "right"],
|
|
4534
|
+
AssignmentPattern: ["left", "right"],
|
|
4535
|
+
AwaitExpression: ["argument"],
|
|
4536
|
+
BinaryExpression: ["left", "right"],
|
|
4537
|
+
BlockStatement: ["body"],
|
|
4538
|
+
BreakStatement: ["label"],
|
|
4539
|
+
CallExpression: ["callee", "arguments"],
|
|
4540
|
+
CatchClause: ["param", "body"],
|
|
4541
|
+
ChainExpression: ["expression"],
|
|
4542
|
+
ClassBody: ["body"],
|
|
4543
|
+
ClassDeclaration: ["id", "superClass", "body"],
|
|
4544
|
+
ClassExpression: ["id", "superClass", "body"],
|
|
4545
|
+
ConditionalExpression: ["test", "consequent", "alternate"],
|
|
4546
|
+
ContinueStatement: ["label"],
|
|
4547
|
+
DebuggerStatement: [],
|
|
4548
|
+
DoWhileStatement: ["body", "test"],
|
|
4549
|
+
EmptyStatement: [],
|
|
4550
|
+
ExperimentalRestProperty: ["argument"],
|
|
4551
|
+
ExperimentalSpreadProperty: ["argument"],
|
|
4552
|
+
ExportAllDeclaration: ["exported", "source", "attributes"],
|
|
4553
|
+
ExportDefaultDeclaration: ["declaration"],
|
|
4554
|
+
ExportNamedDeclaration: [
|
|
4555
|
+
"declaration",
|
|
4556
|
+
"specifiers",
|
|
4557
|
+
"source",
|
|
4558
|
+
"attributes"
|
|
4559
|
+
],
|
|
4560
|
+
ExportSpecifier: ["local", "exported"],
|
|
4561
|
+
ExpressionStatement: ["expression"],
|
|
4562
|
+
ForInStatement: ["left", "right", "body"],
|
|
4563
|
+
ForOfStatement: ["left", "right", "body"],
|
|
4564
|
+
ForStatement: ["init", "test", "update", "body"],
|
|
4565
|
+
FunctionDeclaration: ["id", "params", "body"],
|
|
4566
|
+
FunctionExpression: ["id", "params", "body"],
|
|
4567
|
+
Identifier: [],
|
|
4568
|
+
IfStatement: ["test", "consequent", "alternate"],
|
|
4569
|
+
ImportAttribute: ["key", "value"],
|
|
4570
|
+
ImportDeclaration: ["specifiers", "source", "attributes"],
|
|
4571
|
+
ImportDefaultSpecifier: ["local"],
|
|
4572
|
+
ImportExpression: ["source", "options"],
|
|
4573
|
+
ImportNamespaceSpecifier: ["local"],
|
|
4574
|
+
ImportSpecifier: ["imported", "local"],
|
|
4575
|
+
JSXAttribute: ["name", "value"],
|
|
4576
|
+
JSXClosingElement: ["name"],
|
|
4577
|
+
JSXClosingFragment: [],
|
|
4578
|
+
JSXElement: ["openingElement", "children", "closingElement"],
|
|
4579
|
+
JSXEmptyExpression: [],
|
|
4580
|
+
JSXExpressionContainer: ["expression"],
|
|
4581
|
+
JSXFragment: ["openingFragment", "children", "closingFragment"],
|
|
4582
|
+
JSXIdentifier: [],
|
|
4583
|
+
JSXMemberExpression: ["object", "property"],
|
|
4584
|
+
JSXNamespacedName: ["namespace", "name"],
|
|
4585
|
+
JSXOpeningElement: ["name", "attributes"],
|
|
4586
|
+
JSXOpeningFragment: [],
|
|
4587
|
+
JSXSpreadAttribute: ["argument"],
|
|
4588
|
+
JSXSpreadChild: ["expression"],
|
|
4589
|
+
JSXText: [],
|
|
4590
|
+
LabeledStatement: ["label", "body"],
|
|
4591
|
+
Literal: [],
|
|
4592
|
+
LogicalExpression: ["left", "right"],
|
|
4593
|
+
MemberExpression: ["object", "property"],
|
|
4594
|
+
MetaProperty: ["meta", "property"],
|
|
4595
|
+
MethodDefinition: ["key", "value"],
|
|
4596
|
+
NewExpression: ["callee", "arguments"],
|
|
4597
|
+
ObjectExpression: ["properties"],
|
|
4598
|
+
ObjectPattern: ["properties"],
|
|
4599
|
+
PrivateIdentifier: [],
|
|
4600
|
+
Program: ["body"],
|
|
4601
|
+
Property: ["key", "value"],
|
|
4602
|
+
PropertyDefinition: ["key", "value"],
|
|
4603
|
+
RestElement: ["argument"],
|
|
4604
|
+
ReturnStatement: ["argument"],
|
|
4605
|
+
SequenceExpression: ["expressions"],
|
|
4606
|
+
SpreadElement: ["argument"],
|
|
4607
|
+
StaticBlock: ["body"],
|
|
4608
|
+
Super: [],
|
|
4609
|
+
SwitchCase: ["test", "consequent"],
|
|
4610
|
+
SwitchStatement: ["discriminant", "cases"],
|
|
4611
|
+
TaggedTemplateExpression: ["tag", "quasi"],
|
|
4612
|
+
TemplateElement: [],
|
|
4613
|
+
TemplateLiteral: ["quasis", "expressions"],
|
|
4614
|
+
ThisExpression: [],
|
|
4615
|
+
ThrowStatement: ["argument"],
|
|
4616
|
+
TryStatement: ["block", "handler", "finalizer"],
|
|
4617
|
+
UnaryExpression: ["argument"],
|
|
4618
|
+
UpdateExpression: ["argument"],
|
|
4619
|
+
VariableDeclaration: ["declarations"],
|
|
4620
|
+
VariableDeclarator: ["id", "init"],
|
|
4621
|
+
WhileStatement: ["test", "body"],
|
|
4622
|
+
WithStatement: ["object", "body"],
|
|
4623
|
+
YieldExpression: ["argument"]
|
|
4624
|
+
};
|
|
4625
|
+
var NODE_TYPES = Object.keys(KEYS2);
|
|
4626
|
+
for (const type of NODE_TYPES) {
|
|
4627
|
+
Object.freeze(KEYS2[type]);
|
|
4628
|
+
}
|
|
4629
|
+
Object.freeze(KEYS2);
|
|
4630
|
+
var visitor_keys_default = KEYS2;
|
|
4631
|
+
|
|
4632
|
+
// node_modules/eslint-visitor-keys/lib/index.js
|
|
4633
|
+
function unionWith(additionalKeys) {
|
|
4634
|
+
const retv = (
|
|
4635
|
+
/** @type {{ [type: string]: ReadonlyArray<string> }} */
|
|
4636
|
+
Object.assign({}, visitor_keys_default)
|
|
4637
|
+
);
|
|
4638
|
+
for (const type of Object.keys(additionalKeys)) {
|
|
4639
|
+
if (Object.hasOwn(retv, type)) {
|
|
4640
|
+
const keys = new Set(additionalKeys[type]);
|
|
4641
|
+
for (const key of retv[type]) {
|
|
4642
|
+
keys.add(key);
|
|
4643
|
+
}
|
|
4644
|
+
retv[type] = Object.freeze(Array.from(keys));
|
|
4645
|
+
} else {
|
|
4646
|
+
retv[type] = Object.freeze(Array.from(additionalKeys[type]));
|
|
4462
4647
|
}
|
|
4463
|
-
out2 += c3;
|
|
4464
4648
|
}
|
|
4465
|
-
return
|
|
4649
|
+
return Object.freeze(retv);
|
|
4466
4650
|
}
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
return void 0;
|
|
4472
|
-
}
|
|
4651
|
+
|
|
4652
|
+
// node_modules/toml-eslint-parser/lib/index.mjs
|
|
4653
|
+
function last(arr) {
|
|
4654
|
+
return arr[arr.length - 1] ?? null;
|
|
4473
4655
|
}
|
|
4474
|
-
function
|
|
4475
|
-
|
|
4476
|
-
return readFileSync(file, "utf8");
|
|
4477
|
-
} catch {
|
|
4478
|
-
return "";
|
|
4479
|
-
}
|
|
4656
|
+
function toKeyName(node) {
|
|
4657
|
+
return node.type === "TOMLBare" ? node.name : node.value;
|
|
4480
4658
|
}
|
|
4481
|
-
var
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out2;
|
|
4486
|
-
for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
|
|
4487
|
-
listOf(groups).forEach((group2, i2) => {
|
|
4488
|
-
if (!isObj(group2)) return;
|
|
4489
|
-
listOf(group2[HOOKS_KEY]).forEach((inner, j2) => {
|
|
4490
|
-
const command = commandOf(inner);
|
|
4491
|
-
if (command !== null) out2.push({ path: keyPath(HOOKS_KEY, event, i2, HOOKS_KEY, j2), command });
|
|
4492
|
-
});
|
|
4493
|
-
});
|
|
4659
|
+
var TOMLVerImpl = class {
|
|
4660
|
+
constructor(major, minor) {
|
|
4661
|
+
this.major = major;
|
|
4662
|
+
this.minor = minor;
|
|
4494
4663
|
}
|
|
4495
|
-
|
|
4664
|
+
lt(major, minor) {
|
|
4665
|
+
return this.major < major || this.major === major && this.minor < minor;
|
|
4666
|
+
}
|
|
4667
|
+
gte(major, minor) {
|
|
4668
|
+
return this.major > major || this.major === major && this.minor >= minor;
|
|
4669
|
+
}
|
|
4670
|
+
};
|
|
4671
|
+
var TOML_VERSION_1_0 = new TOMLVerImpl(1, 0);
|
|
4672
|
+
var TOML_VERSION_1_1 = new TOMLVerImpl(1, 1);
|
|
4673
|
+
var DEFAULT_TOML_VERSION = TOML_VERSION_1_1;
|
|
4674
|
+
var SUPPORTED_TOML_VERSIONS = {
|
|
4675
|
+
"1.0": TOML_VERSION_1_0,
|
|
4676
|
+
"1.0.0": TOML_VERSION_1_0,
|
|
4677
|
+
"1.1": TOML_VERSION_1_1,
|
|
4678
|
+
"1.1.0": TOML_VERSION_1_1,
|
|
4679
|
+
latest: TOML_VERSION_1_1,
|
|
4680
|
+
next: TOML_VERSION_1_1
|
|
4681
|
+
};
|
|
4682
|
+
function getTOMLVer(v) {
|
|
4683
|
+
return v && SUPPORTED_TOML_VERSIONS[v] || DEFAULT_TOML_VERSION;
|
|
4684
|
+
}
|
|
4685
|
+
var MESSAGES = {
|
|
4686
|
+
"unterminated-string": "Unterminated string constant",
|
|
4687
|
+
"unterminated-table-key": "Unterminated table-key",
|
|
4688
|
+
"unterminated-array": "Unterminated array",
|
|
4689
|
+
"unterminated-inline-table": "Unterminated inline table",
|
|
4690
|
+
"missing-key": "Empty bare keys are not allowed",
|
|
4691
|
+
"missing-newline": "Must be a newline",
|
|
4692
|
+
"missing-equals-sign": "Expected equal (=) token",
|
|
4693
|
+
"missing-value": "Unspecified values are invalid",
|
|
4694
|
+
"missing-comma": "Expected comma (,) token",
|
|
4695
|
+
"dupe-keys": "Defining a key multiple times is invalid",
|
|
4696
|
+
"unexpected-char": "Unexpected character",
|
|
4697
|
+
"unexpected-token": "Unexpected token",
|
|
4698
|
+
"invalid-control-character": "Control characters (codes < 0x1f and 0x7f) are not allowed",
|
|
4699
|
+
"invalid-comment-character": "Invalid code point {{cp}} within comments",
|
|
4700
|
+
"invalid-key-value-newline": "The key, equals sign, and value must be on the same line",
|
|
4701
|
+
"invalid-inline-table-newline": "No newlines are allowed between the curly braces unless they are valid within a value",
|
|
4702
|
+
"invalid-underscore": "Underscores are allowed between digits",
|
|
4703
|
+
"invalid-space": "Unexpected spaces",
|
|
4704
|
+
"invalid-three-quotes": "Three or more quotes are not permitted",
|
|
4705
|
+
"invalid-date": "Unexpected invalid date",
|
|
4706
|
+
"invalid-time": "Unexpected invalid time",
|
|
4707
|
+
"invalid-leading-zero": "Leading zeros are not allowed",
|
|
4708
|
+
"invalid-trailing-comma-in-inline-table": "Trailing comma is not permitted in an inline table",
|
|
4709
|
+
"invalid-char-in-escape-sequence": "Invalid character in escape sequence",
|
|
4710
|
+
"invalid-consecutive-dots-in-key": "Consecutive dots are not permitted in keys",
|
|
4711
|
+
"invalid-code-point": "Invalid code point {{cp}}",
|
|
4712
|
+
"invalid-trailing-dot-in-key": "Keys cannot end with a dot",
|
|
4713
|
+
"invalid-leading-dot-in-key": "Keys cannot start with a dot"
|
|
4714
|
+
};
|
|
4715
|
+
function getMessage(code, data) {
|
|
4716
|
+
if (data) return MESSAGES[code].replace(/\{\{(.*?)\}\}/gu, (_2, name$2) => {
|
|
4717
|
+
if (name$2 in data) return data[name$2];
|
|
4718
|
+
return `{{${name$2}}}`;
|
|
4719
|
+
});
|
|
4720
|
+
return MESSAGES[code];
|
|
4496
4721
|
}
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4722
|
+
var ParseError = class extends SyntaxError {
|
|
4723
|
+
/**
|
|
4724
|
+
* Initialize this ParseError instance.
|
|
4725
|
+
*
|
|
4726
|
+
*/
|
|
4727
|
+
constructor(code, offset, line, column, data) {
|
|
4728
|
+
super(getMessage(code, data));
|
|
4729
|
+
this.index = offset;
|
|
4730
|
+
this.lineNumber = line;
|
|
4731
|
+
this.column = column;
|
|
4505
4732
|
}
|
|
4506
|
-
|
|
4733
|
+
};
|
|
4734
|
+
var CodePoint = {
|
|
4735
|
+
EOF: -1,
|
|
4736
|
+
NULL: 0,
|
|
4737
|
+
SOH: 1,
|
|
4738
|
+
BACKSPACE: 8,
|
|
4739
|
+
TABULATION: 9,
|
|
4740
|
+
LINE_FEED: 10,
|
|
4741
|
+
FORM_FEED: 12,
|
|
4742
|
+
CARRIAGE_RETURN: 13,
|
|
4743
|
+
ESCAPE: 27,
|
|
4744
|
+
SO: 14,
|
|
4745
|
+
US: 31,
|
|
4746
|
+
SPACE: 32,
|
|
4747
|
+
QUOTATION_MARK: 34,
|
|
4748
|
+
HASH: 35,
|
|
4749
|
+
SINGLE_QUOTE: 39,
|
|
4750
|
+
PLUS_SIGN: 43,
|
|
4751
|
+
COMMA: 44,
|
|
4752
|
+
DASH: 45,
|
|
4753
|
+
DOT: 46,
|
|
4754
|
+
DIGIT_0: 48,
|
|
4755
|
+
DIGIT_1: 49,
|
|
4756
|
+
DIGIT_2: 50,
|
|
4757
|
+
DIGIT_3: 51,
|
|
4758
|
+
DIGIT_7: 55,
|
|
4759
|
+
DIGIT_9: 57,
|
|
4760
|
+
COLON: 58,
|
|
4761
|
+
EQUALS_SIGN: 61,
|
|
4762
|
+
LATIN_CAPITAL_A: 65,
|
|
4763
|
+
LATIN_CAPITAL_E: 69,
|
|
4764
|
+
LATIN_CAPITAL_F: 70,
|
|
4765
|
+
LATIN_CAPITAL_T: 84,
|
|
4766
|
+
LATIN_CAPITAL_U: 85,
|
|
4767
|
+
LATIN_CAPITAL_Z: 90,
|
|
4768
|
+
LEFT_BRACKET: 91,
|
|
4769
|
+
BACKSLASH: 92,
|
|
4770
|
+
RIGHT_BRACKET: 93,
|
|
4771
|
+
UNDERSCORE: 95,
|
|
4772
|
+
LATIN_SMALL_A: 97,
|
|
4773
|
+
LATIN_SMALL_B: 98,
|
|
4774
|
+
LATIN_SMALL_E: 101,
|
|
4775
|
+
LATIN_SMALL_F: 102,
|
|
4776
|
+
LATIN_SMALL_I: 105,
|
|
4777
|
+
LATIN_SMALL_L: 108,
|
|
4778
|
+
LATIN_SMALL_N: 110,
|
|
4779
|
+
LATIN_SMALL_O: 111,
|
|
4780
|
+
LATIN_SMALL_R: 114,
|
|
4781
|
+
LATIN_SMALL_S: 115,
|
|
4782
|
+
LATIN_SMALL_T: 116,
|
|
4783
|
+
LATIN_SMALL_U: 117,
|
|
4784
|
+
LATIN_SMALL_X: 120,
|
|
4785
|
+
LATIN_SMALL_Z: 122,
|
|
4786
|
+
LEFT_BRACE: 123,
|
|
4787
|
+
RIGHT_BRACE: 125,
|
|
4788
|
+
TILDE: 126,
|
|
4789
|
+
DELETE: 127,
|
|
4790
|
+
PAD: 128,
|
|
4791
|
+
SUPERSCRIPT_TWO: 178,
|
|
4792
|
+
SUPERSCRIPT_THREE: 179,
|
|
4793
|
+
SUPERSCRIPT_ONE: 185,
|
|
4794
|
+
VULGAR_FRACTION_ONE_QUARTER: 188,
|
|
4795
|
+
VULGAR_FRACTION_THREE_QUARTERS: 190,
|
|
4796
|
+
LATIN_CAPITAL_LETTER_A_WITH_GRAVE: 192,
|
|
4797
|
+
LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS: 214,
|
|
4798
|
+
LATIN_CAPITAL_LETTER_O_WITH_STROKE: 216,
|
|
4799
|
+
LATIN_SMALL_LETTER_O_WITH_DIAERESIS: 246,
|
|
4800
|
+
LATIN_SMALL_LETTER_O_WITH_STROKE: 248,
|
|
4801
|
+
GREEK_SMALL_REVERSED_DOTTED_LUNATE_SIGMA_SYMBOL: 891,
|
|
4802
|
+
GREEK_CAPITAL_LETTER_YOT: 895,
|
|
4803
|
+
CP_1FFF: 8191,
|
|
4804
|
+
ZERO_WIDTH_NON_JOINER: 8204,
|
|
4805
|
+
ZERO_WIDTH_JOINER: 8205,
|
|
4806
|
+
UNDERTIE: 8255,
|
|
4807
|
+
CHARACTER_TIE: 8256,
|
|
4808
|
+
SUPERSCRIPT_ZERO: 8304,
|
|
4809
|
+
CP_218F: 8591,
|
|
4810
|
+
CIRCLED_DIGIT_ONE: 9312,
|
|
4811
|
+
NEGATIVE_CIRCLED_DIGIT_ZERO: 9471,
|
|
4812
|
+
GLAGOLITIC_CAPITAL_LETTER_AZU: 11264,
|
|
4813
|
+
CP_2FEF: 12271,
|
|
4814
|
+
IDEOGRAPHIC_COMMA: 12289,
|
|
4815
|
+
CP_D7FF: 55295,
|
|
4816
|
+
CP_E000: 57344,
|
|
4817
|
+
CJK_COMPATIBILITY_IDEOGRAPH_F900: 63744,
|
|
4818
|
+
ARABIC_LIGATURE_SALAAMUHU_ALAYNAA: 64975,
|
|
4819
|
+
ARABIC_LIGATURE_SALLA_USED_AS_KORANIC_STOP_SIGN_ISOLATED_FORM: 65008,
|
|
4820
|
+
REPLACEMENT_CHARACTER: 65533,
|
|
4821
|
+
LINEAR_B_SYLLABLE_B008_A: 65536,
|
|
4822
|
+
CP_EFFFF: 983039,
|
|
4823
|
+
CP_10FFFF: 1114111
|
|
4824
|
+
};
|
|
4825
|
+
function isControl(cp) {
|
|
4826
|
+
return cp >= CodePoint.NULL && cp <= CodePoint.US;
|
|
4507
4827
|
}
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
function dataDir(dir, reason, out2) {
|
|
4511
|
-
if (existsSync2(dir)) out2.push(finding(dir, "", reason));
|
|
4828
|
+
function isWhitespace(cp) {
|
|
4829
|
+
return cp === CodePoint.TABULATION || cp === CodePoint.SPACE;
|
|
4512
4830
|
}
|
|
4513
|
-
function
|
|
4514
|
-
|
|
4515
|
-
out2.push(finding(file, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
|
|
4516
|
-
}
|
|
4831
|
+
function isEOL(cp) {
|
|
4832
|
+
return cp === CodePoint.LINE_FEED || cp === CodePoint.CARRIAGE_RETURN;
|
|
4517
4833
|
}
|
|
4518
|
-
function
|
|
4519
|
-
|
|
4520
|
-
const doc = readJson(file);
|
|
4521
|
-
for (const c3 of nestedCommands(doc)) {
|
|
4522
|
-
if (c3.command.includes(V1_CACHE_HEAL_NAME)) out2.push(finding(file, c3.path, V1_REASON.cacheHealHook));
|
|
4523
|
-
else if (isV1Hook(c3.command)) out2.push(finding(file, c3.path, V1_REASON.hook));
|
|
4524
|
-
}
|
|
4525
|
-
const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
|
|
4526
|
-
if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
|
|
4527
|
-
out2.push(finding(file, STATUS_LINE_KEY, V1_REASON.statusLine));
|
|
4528
|
-
}
|
|
4529
|
-
mcpEntry(file, doc, out2);
|
|
4834
|
+
function isUpperLetter(cp) {
|
|
4835
|
+
return cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_Z;
|
|
4530
4836
|
}
|
|
4531
|
-
function
|
|
4532
|
-
|
|
4533
|
-
const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
|
|
4534
|
-
if (cmds.some((c3) => c3.command.includes(V1_HOOK_COMMAND))) out2.push(finding(file, "", V1_REASON.hookFile));
|
|
4837
|
+
function isLowerLetter(cp) {
|
|
4838
|
+
return cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_Z;
|
|
4535
4839
|
}
|
|
4536
|
-
function
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4840
|
+
function isLetter(cp) {
|
|
4841
|
+
return isLowerLetter(cp) || isUpperLetter(cp);
|
|
4842
|
+
}
|
|
4843
|
+
function isDigit(cp) {
|
|
4844
|
+
return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_9;
|
|
4845
|
+
}
|
|
4846
|
+
function isHexDig(cp) {
|
|
4847
|
+
return isDigit(cp) || cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_F || cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_F;
|
|
4848
|
+
}
|
|
4849
|
+
function isOctalDig(cp) {
|
|
4850
|
+
return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_7;
|
|
4851
|
+
}
|
|
4852
|
+
function isUnicodeScalarValue(cp) {
|
|
4853
|
+
return cp >= 0 && cp <= 55295 || cp >= 57344 && cp <= 1114111;
|
|
4854
|
+
}
|
|
4855
|
+
function sortedLastIndex(array, value) {
|
|
4856
|
+
let low = 0;
|
|
4857
|
+
let high = array.length;
|
|
4858
|
+
while (low < high) {
|
|
4859
|
+
const mid = low + high >>> 1;
|
|
4860
|
+
const val = array[mid];
|
|
4861
|
+
if (val === value) return mid + 1;
|
|
4862
|
+
if (val < value) low = mid + 1;
|
|
4863
|
+
else high = mid;
|
|
4541
4864
|
}
|
|
4542
|
-
|
|
4543
|
-
mcpEntry(userFile, readJson(userFile), out2);
|
|
4544
|
-
dataDir(join3(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
4865
|
+
return low;
|
|
4545
4866
|
}
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
if (c3.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c3.command)) {
|
|
4550
|
-
out2.push(finding(hooksFile, c3.path, V1_REASON.codexHook));
|
|
4551
|
-
}
|
|
4867
|
+
var Locations = class {
|
|
4868
|
+
constructor() {
|
|
4869
|
+
this.offsets = [];
|
|
4552
4870
|
}
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4871
|
+
addOffset(offset) {
|
|
4872
|
+
for (let i2 = this.offsets.length - 1; i2 >= 0; i2--) {
|
|
4873
|
+
const element = this.offsets[i2];
|
|
4874
|
+
if (element === offset) return;
|
|
4875
|
+
if (element < offset) break;
|
|
4876
|
+
}
|
|
4877
|
+
this.offsets.push(offset);
|
|
4557
4878
|
}
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4879
|
+
/**
|
|
4880
|
+
* Calculate the location of the given index.
|
|
4881
|
+
* @param index The index to calculate their location.
|
|
4882
|
+
* @returns The location of the index.
|
|
4883
|
+
*/
|
|
4884
|
+
getLocFromIndex(offset) {
|
|
4885
|
+
const line = sortedLastIndex(this.offsets, offset) + 1;
|
|
4886
|
+
return {
|
|
4887
|
+
line,
|
|
4888
|
+
column: offset - (line === 1 ? 0 : this.offsets[line - 2])
|
|
4889
|
+
};
|
|
4564
4890
|
}
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4891
|
+
};
|
|
4892
|
+
var CodePointIterator = class {
|
|
4893
|
+
/**
|
|
4894
|
+
* Initialize this char iterator.
|
|
4895
|
+
*/
|
|
4896
|
+
constructor(text2) {
|
|
4897
|
+
this.locs = new Locations();
|
|
4898
|
+
this.lastCodePoint = CodePoint.NULL;
|
|
4899
|
+
this.start = -1;
|
|
4900
|
+
this.end = 0;
|
|
4901
|
+
this.text = text2;
|
|
4902
|
+
}
|
|
4903
|
+
next() {
|
|
4904
|
+
if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
|
|
4905
|
+
return this.lastCodePoint = this.moveAt(this.end);
|
|
4906
|
+
}
|
|
4907
|
+
getLocFromIndex(index) {
|
|
4908
|
+
return this.locs.getLocFromIndex(index);
|
|
4909
|
+
}
|
|
4910
|
+
eat(cp) {
|
|
4911
|
+
if (this.text.codePointAt(this.end) === cp) {
|
|
4912
|
+
this.next();
|
|
4913
|
+
return true;
|
|
4914
|
+
}
|
|
4915
|
+
return false;
|
|
4916
|
+
}
|
|
4917
|
+
moveAt(offset) {
|
|
4918
|
+
this.start = this.end = offset;
|
|
4919
|
+
const cp = this.text.codePointAt(this.start) ?? CodePoint.EOF;
|
|
4920
|
+
if (cp === CodePoint.EOF) {
|
|
4921
|
+
this.end = this.start;
|
|
4922
|
+
return cp;
|
|
4576
4923
|
}
|
|
4577
|
-
|
|
4924
|
+
this.end += cp >= 65536 ? 2 : 1;
|
|
4925
|
+
if (cp === CodePoint.LINE_FEED) this.locs.addOffset(this.end);
|
|
4926
|
+
else if (cp === CodePoint.CARRIAGE_RETURN) {
|
|
4927
|
+
if (this.text.codePointAt(this.end) === CodePoint.LINE_FEED) {
|
|
4928
|
+
this.end++;
|
|
4929
|
+
this.locs.addOffset(this.end);
|
|
4930
|
+
}
|
|
4931
|
+
return CodePoint.LINE_FEED;
|
|
4932
|
+
}
|
|
4933
|
+
return cp;
|
|
4578
4934
|
}
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4935
|
+
};
|
|
4936
|
+
var HAS_BIGINT = typeof BigInt !== "undefined";
|
|
4937
|
+
var RADIX_PREFIXES = {
|
|
4938
|
+
16: "0x",
|
|
4939
|
+
10: "",
|
|
4940
|
+
8: "0o",
|
|
4941
|
+
2: "0b"
|
|
4942
|
+
};
|
|
4943
|
+
var ESCAPES_1_0 = {
|
|
4944
|
+
[CodePoint.QUOTATION_MARK]: CodePoint.QUOTATION_MARK,
|
|
4945
|
+
[CodePoint.BACKSLASH]: CodePoint.BACKSLASH,
|
|
4946
|
+
[CodePoint.LATIN_SMALL_B]: CodePoint.BACKSPACE,
|
|
4947
|
+
[CodePoint.LATIN_SMALL_F]: CodePoint.FORM_FEED,
|
|
4948
|
+
[CodePoint.LATIN_SMALL_N]: CodePoint.LINE_FEED,
|
|
4949
|
+
[CodePoint.LATIN_SMALL_R]: CodePoint.CARRIAGE_RETURN,
|
|
4950
|
+
[CodePoint.LATIN_SMALL_T]: CodePoint.TABULATION
|
|
4951
|
+
};
|
|
4952
|
+
var ESCAPES_LATEST = {
|
|
4953
|
+
...ESCAPES_1_0,
|
|
4954
|
+
[CodePoint.LATIN_SMALL_E]: CodePoint.ESCAPE
|
|
4955
|
+
};
|
|
4956
|
+
var Tokenizer = class {
|
|
4957
|
+
/**
|
|
4958
|
+
* Initialize this tokenizer.
|
|
4959
|
+
*/
|
|
4960
|
+
constructor(text2, parserOptions) {
|
|
4961
|
+
this.backCode = false;
|
|
4962
|
+
this.lastCodePoint = CodePoint.NULL;
|
|
4963
|
+
this.state = "DATA";
|
|
4964
|
+
this.token = null;
|
|
4965
|
+
this.tokenStart = -1;
|
|
4966
|
+
this.valuesEnabled = false;
|
|
4967
|
+
this.text = text2;
|
|
4968
|
+
this.parserOptions = parserOptions || {};
|
|
4969
|
+
this.codePointIterator = new CodePointIterator(text2);
|
|
4970
|
+
this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
|
|
4971
|
+
this.ESCAPES = this.tomlVersion.gte(1, 1) ? ESCAPES_LATEST : ESCAPES_1_0;
|
|
4972
|
+
}
|
|
4973
|
+
get start() {
|
|
4974
|
+
return this.codePointIterator.start;
|
|
4975
|
+
}
|
|
4976
|
+
get end() {
|
|
4977
|
+
return this.codePointIterator.end;
|
|
4978
|
+
}
|
|
4979
|
+
getLocFromIndex(index) {
|
|
4980
|
+
return this.codePointIterator.getLocFromIndex(index);
|
|
4586
4981
|
}
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
const
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4982
|
+
/**
|
|
4983
|
+
* Report an invalid character error.
|
|
4984
|
+
*/
|
|
4985
|
+
reportParseError(code, data) {
|
|
4986
|
+
const offset = this.codePointIterator.start;
|
|
4987
|
+
const loc = this.codePointIterator.getLocFromIndex(offset);
|
|
4988
|
+
throw new ParseError(code, offset, loc.line, loc.column, data);
|
|
4989
|
+
}
|
|
4990
|
+
/**
|
|
4991
|
+
* Get the next token.
|
|
4992
|
+
*/
|
|
4993
|
+
nextToken() {
|
|
4994
|
+
let token = this.token;
|
|
4995
|
+
if (token != null) {
|
|
4996
|
+
this.token = null;
|
|
4997
|
+
return token;
|
|
4597
4998
|
}
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4999
|
+
let cp = this.lastCodePoint;
|
|
5000
|
+
while (cp !== CodePoint.EOF && !this.token) {
|
|
5001
|
+
cp = this.nextCode();
|
|
5002
|
+
const nextState = this[this.state](cp);
|
|
5003
|
+
if (!nextState) throw new Error(`Unknown error: pre state=${this.state}`);
|
|
5004
|
+
this.state = nextState;
|
|
4601
5005
|
}
|
|
5006
|
+
token = this.token;
|
|
5007
|
+
this.token = null;
|
|
5008
|
+
return token;
|
|
4602
5009
|
}
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
5010
|
+
/**
|
|
5011
|
+
* Get the next code point.
|
|
5012
|
+
*/
|
|
5013
|
+
nextCode() {
|
|
5014
|
+
if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
|
|
5015
|
+
if (this.backCode) {
|
|
5016
|
+
this.backCode = false;
|
|
5017
|
+
return this.lastCodePoint;
|
|
5018
|
+
}
|
|
5019
|
+
return this.lastCodePoint = this.codePointIterator.next();
|
|
4607
5020
|
}
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
const file = join3(agentHome, name);
|
|
4622
|
-
const doc = readJson(file);
|
|
4623
|
-
if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
|
|
4624
|
-
doc[OPENCODE_PLUGIN_KEY].forEach((spec, i2) => {
|
|
4625
|
-
if (spec === V1_OPENCODE_PLUGIN_SPEC) out2.push(finding(file, keyPath(OPENCODE_PLUGIN_KEY, i2), V1_REASON.opencodePlugin));
|
|
4626
|
-
});
|
|
4627
|
-
return;
|
|
5021
|
+
/**
|
|
5022
|
+
* Eat the next code point.
|
|
5023
|
+
*/
|
|
5024
|
+
eatCode(cp) {
|
|
5025
|
+
if (this.lastCodePoint === CodePoint.EOF) return false;
|
|
5026
|
+
if (this.backCode) {
|
|
5027
|
+
if (this.lastCodePoint === cp) {
|
|
5028
|
+
this.backCode = false;
|
|
5029
|
+
return true;
|
|
5030
|
+
}
|
|
5031
|
+
return false;
|
|
5032
|
+
}
|
|
5033
|
+
return this.codePointIterator.eat(cp);
|
|
4628
5034
|
}
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
if (c3.command.includes(V1_HOOK_COMMAND)) out2.push(finding(configFile, c3.path, V1_REASON.zcodeHook));
|
|
5035
|
+
/**
|
|
5036
|
+
* Moves the character position to the given position.
|
|
5037
|
+
*/
|
|
5038
|
+
moveAt(loc) {
|
|
5039
|
+
if (this.backCode) this.backCode = false;
|
|
5040
|
+
this.lastCodePoint = this.codePointIterator.moveAt(loc);
|
|
4636
5041
|
}
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
5042
|
+
/**
|
|
5043
|
+
* Back the current code point as the given state.
|
|
5044
|
+
*/
|
|
5045
|
+
back(state) {
|
|
5046
|
+
this.backCode = true;
|
|
5047
|
+
return state;
|
|
4640
5048
|
}
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
try {
|
|
4645
|
-
handle = opendirSync(dir);
|
|
4646
|
-
} catch {
|
|
4647
|
-
return null;
|
|
5049
|
+
punctuatorToken() {
|
|
5050
|
+
this.startToken();
|
|
5051
|
+
this.endToken("Punctuator", "end");
|
|
4648
5052
|
}
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
5053
|
+
startToken() {
|
|
5054
|
+
this.tokenStart = this.codePointIterator.start;
|
|
5055
|
+
}
|
|
5056
|
+
/**
|
|
5057
|
+
* Commit the current token.
|
|
5058
|
+
*/
|
|
5059
|
+
endToken(type, pos, option1, option2) {
|
|
5060
|
+
const { tokenStart } = this;
|
|
5061
|
+
const end = this.codePointIterator[pos];
|
|
5062
|
+
const range = [tokenStart, end];
|
|
5063
|
+
const loc = {
|
|
5064
|
+
start: this.codePointIterator.getLocFromIndex(tokenStart),
|
|
5065
|
+
end: this.codePointIterator.getLocFromIndex(end)
|
|
5066
|
+
};
|
|
5067
|
+
if (type === "Block") this.token = {
|
|
5068
|
+
type,
|
|
5069
|
+
value: this.text.slice(tokenStart + 1, end),
|
|
5070
|
+
range,
|
|
5071
|
+
loc
|
|
5072
|
+
};
|
|
5073
|
+
else {
|
|
5074
|
+
let token;
|
|
5075
|
+
const value = this.text.slice(tokenStart, end);
|
|
5076
|
+
if (type === "BasicString" || type === "LiteralString" || type === "MultiLineBasicString" || type === "MultiLineLiteralString") token = {
|
|
5077
|
+
type,
|
|
5078
|
+
value,
|
|
5079
|
+
string: option1,
|
|
5080
|
+
range,
|
|
5081
|
+
loc
|
|
5082
|
+
};
|
|
5083
|
+
else if (type === "Integer") {
|
|
5084
|
+
const text2 = option1;
|
|
5085
|
+
token = {
|
|
5086
|
+
type,
|
|
5087
|
+
value,
|
|
5088
|
+
number: parseInt(text2, option2),
|
|
5089
|
+
bigint: HAS_BIGINT ? BigInt(RADIX_PREFIXES[option2] + text2) : null,
|
|
5090
|
+
range,
|
|
5091
|
+
loc
|
|
5092
|
+
};
|
|
5093
|
+
} else if (type === "Float") token = {
|
|
5094
|
+
type,
|
|
5095
|
+
value,
|
|
5096
|
+
number: option1,
|
|
5097
|
+
range,
|
|
5098
|
+
loc
|
|
5099
|
+
};
|
|
5100
|
+
else if (type === "Boolean") token = {
|
|
5101
|
+
type,
|
|
5102
|
+
value,
|
|
5103
|
+
boolean: option1,
|
|
5104
|
+
range,
|
|
5105
|
+
loc
|
|
5106
|
+
};
|
|
5107
|
+
else if (type === "LocalDate" || type === "LocalTime" || type === "LocalDateTime" || type === "OffsetDateTime") token = {
|
|
5108
|
+
type,
|
|
5109
|
+
value,
|
|
5110
|
+
date: option1,
|
|
5111
|
+
range,
|
|
5112
|
+
loc
|
|
5113
|
+
};
|
|
5114
|
+
else token = {
|
|
5115
|
+
type,
|
|
5116
|
+
value,
|
|
5117
|
+
range,
|
|
5118
|
+
loc
|
|
5119
|
+
};
|
|
5120
|
+
this.token = token;
|
|
4652
5121
|
}
|
|
4653
|
-
return null;
|
|
4654
|
-
} catch {
|
|
4655
|
-
return null;
|
|
4656
|
-
} finally {
|
|
4657
|
-
handle.closeSync();
|
|
4658
5122
|
}
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
}
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
5123
|
+
DATA(cp) {
|
|
5124
|
+
while (isWhitespace(cp) || isEOL(cp)) cp = this.nextCode();
|
|
5125
|
+
if (cp === CodePoint.HASH) {
|
|
5126
|
+
this.startToken();
|
|
5127
|
+
return "COMMENT";
|
|
5128
|
+
}
|
|
5129
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
5130
|
+
this.startToken();
|
|
5131
|
+
return "BASIC_STRING";
|
|
5132
|
+
}
|
|
5133
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
5134
|
+
this.startToken();
|
|
5135
|
+
return "LITERAL_STRING";
|
|
5136
|
+
}
|
|
5137
|
+
if (cp === CodePoint.DOT || cp === CodePoint.EQUALS_SIGN || cp === CodePoint.LEFT_BRACKET || cp === CodePoint.RIGHT_BRACKET || cp === CodePoint.LEFT_BRACE || cp === CodePoint.RIGHT_BRACE || cp === CodePoint.COMMA) {
|
|
5138
|
+
this.punctuatorToken();
|
|
5139
|
+
return "DATA";
|
|
5140
|
+
}
|
|
5141
|
+
if (this.valuesEnabled) {
|
|
5142
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
5143
|
+
this.startToken();
|
|
5144
|
+
return "SIGN";
|
|
5145
|
+
}
|
|
5146
|
+
if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) {
|
|
5147
|
+
this.startToken();
|
|
5148
|
+
return this.back("NAN_OR_INF");
|
|
5149
|
+
}
|
|
5150
|
+
if (isDigit(cp)) {
|
|
5151
|
+
this.startToken();
|
|
5152
|
+
return this.back("NUMBER");
|
|
5153
|
+
}
|
|
5154
|
+
if (cp === CodePoint.LATIN_SMALL_T || cp === CodePoint.LATIN_SMALL_F) {
|
|
5155
|
+
this.startToken();
|
|
5156
|
+
return this.back("BOOLEAN");
|
|
5157
|
+
}
|
|
5158
|
+
} else if (isUnquotedKeyChar(cp, this.tomlVersion)) {
|
|
5159
|
+
this.startToken();
|
|
5160
|
+
return "BARE";
|
|
5161
|
+
}
|
|
5162
|
+
if (cp === CodePoint.EOF) return "DATA";
|
|
5163
|
+
return this.reportParseError("unexpected-char");
|
|
5164
|
+
}
|
|
5165
|
+
COMMENT(cp) {
|
|
5166
|
+
const processCommentChar = this.tomlVersion.gte(1, 1) ? (c3) => {
|
|
5167
|
+
if (!isNonEOL(c3)) this.reportParseError("invalid-comment-character", { cp: JSON.stringify(String.fromCodePoint(c3)).slice(1, -1) });
|
|
5168
|
+
} : (c3) => {
|
|
5169
|
+
if (isControlOtherThanTab(c3)) this.reportParseErrorControlChar();
|
|
5170
|
+
};
|
|
5171
|
+
while (!isEOL(cp) && cp !== CodePoint.EOF) {
|
|
5172
|
+
processCommentChar(cp);
|
|
5173
|
+
cp = this.nextCode();
|
|
5174
|
+
}
|
|
5175
|
+
this.endToken("Block", "start");
|
|
5176
|
+
return "DATA";
|
|
5177
|
+
}
|
|
5178
|
+
BARE(cp) {
|
|
5179
|
+
while (isUnquotedKeyChar(cp, this.tomlVersion)) cp = this.nextCode();
|
|
5180
|
+
this.endToken("Bare", "start");
|
|
5181
|
+
return this.back("DATA");
|
|
5182
|
+
}
|
|
5183
|
+
BASIC_STRING(cp) {
|
|
5184
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
5185
|
+
cp = this.nextCode();
|
|
5186
|
+
if (cp === CodePoint.QUOTATION_MARK) return "MULTI_LINE_BASIC_STRING";
|
|
5187
|
+
this.endToken("BasicString", "start", "");
|
|
5188
|
+
return this.back("DATA");
|
|
5189
|
+
}
|
|
5190
|
+
const out2 = [];
|
|
5191
|
+
while (cp !== CodePoint.QUOTATION_MARK && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
|
|
5192
|
+
if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
5193
|
+
if (cp === CodePoint.BACKSLASH) {
|
|
5194
|
+
cp = this.nextCode();
|
|
5195
|
+
const ecp = this.ESCAPES[cp];
|
|
5196
|
+
if (ecp) {
|
|
5197
|
+
out2.push(ecp);
|
|
5198
|
+
cp = this.nextCode();
|
|
5199
|
+
continue;
|
|
5200
|
+
} else if (cp === CodePoint.LATIN_SMALL_U) {
|
|
5201
|
+
const code = this.parseUnicode(4);
|
|
5202
|
+
out2.push(code);
|
|
5203
|
+
cp = this.nextCode();
|
|
5204
|
+
continue;
|
|
5205
|
+
} else if (cp === CodePoint.LATIN_CAPITAL_U) {
|
|
5206
|
+
const code = this.parseUnicode(8);
|
|
5207
|
+
out2.push(code);
|
|
5208
|
+
cp = this.nextCode();
|
|
5209
|
+
continue;
|
|
5210
|
+
} else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
|
|
5211
|
+
const code = this.parseUnicode(2);
|
|
5212
|
+
out2.push(code);
|
|
5213
|
+
cp = this.nextCode();
|
|
5214
|
+
continue;
|
|
5215
|
+
}
|
|
5216
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
5217
|
+
}
|
|
5218
|
+
out2.push(cp);
|
|
5219
|
+
cp = this.nextCode();
|
|
5220
|
+
}
|
|
5221
|
+
if (cp !== CodePoint.QUOTATION_MARK) return this.reportParseError("unterminated-string");
|
|
5222
|
+
this.endToken("BasicString", "end", String.fromCodePoint(...out2));
|
|
5223
|
+
return "DATA";
|
|
5224
|
+
}
|
|
5225
|
+
MULTI_LINE_BASIC_STRING(cp) {
|
|
5226
|
+
const out2 = [];
|
|
5227
|
+
if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
5228
|
+
while (cp !== CodePoint.EOF) {
|
|
5229
|
+
if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
5230
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
5231
|
+
const startPos = this.codePointIterator.start;
|
|
5232
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK) && this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
5233
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
5234
|
+
out2.push(CodePoint.QUOTATION_MARK);
|
|
5235
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
5236
|
+
out2.push(CodePoint.QUOTATION_MARK);
|
|
5237
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
5238
|
+
this.moveAt(startPos);
|
|
5239
|
+
return this.reportParseError("invalid-three-quotes");
|
|
5240
|
+
}
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5243
|
+
this.endToken("MultiLineBasicString", "end", String.fromCodePoint(...out2));
|
|
5244
|
+
return "DATA";
|
|
5245
|
+
}
|
|
5246
|
+
this.moveAt(startPos);
|
|
5247
|
+
}
|
|
5248
|
+
if (cp === CodePoint.BACKSLASH) {
|
|
5249
|
+
cp = this.nextCode();
|
|
5250
|
+
const ecp = this.ESCAPES[cp];
|
|
5251
|
+
if (ecp) {
|
|
5252
|
+
out2.push(ecp);
|
|
5253
|
+
cp = this.nextCode();
|
|
5254
|
+
continue;
|
|
5255
|
+
} else if (cp === CodePoint.LATIN_SMALL_U) {
|
|
5256
|
+
const code = this.parseUnicode(4);
|
|
5257
|
+
out2.push(code);
|
|
5258
|
+
cp = this.nextCode();
|
|
5259
|
+
continue;
|
|
5260
|
+
} else if (cp === CodePoint.LATIN_CAPITAL_U) {
|
|
5261
|
+
const code = this.parseUnicode(8);
|
|
5262
|
+
out2.push(code);
|
|
5263
|
+
cp = this.nextCode();
|
|
5264
|
+
continue;
|
|
5265
|
+
} else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
|
|
5266
|
+
const code = this.parseUnicode(2);
|
|
5267
|
+
out2.push(code);
|
|
5268
|
+
cp = this.nextCode();
|
|
5269
|
+
continue;
|
|
5270
|
+
} else if (cp === CodePoint.LINE_FEED) {
|
|
5271
|
+
cp = this.nextCode();
|
|
5272
|
+
while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
5273
|
+
continue;
|
|
5274
|
+
} else if (isWhitespace(cp)) {
|
|
5275
|
+
let valid = true;
|
|
5276
|
+
const startPos = this.codePointIterator.start;
|
|
5277
|
+
let nextCp;
|
|
5278
|
+
while ((nextCp = this.nextCode()) !== CodePoint.EOF) {
|
|
5279
|
+
if (nextCp === CodePoint.LINE_FEED) break;
|
|
5280
|
+
if (!isWhitespace(nextCp)) {
|
|
5281
|
+
this.moveAt(startPos);
|
|
5282
|
+
valid = false;
|
|
5283
|
+
break;
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
if (valid) {
|
|
5287
|
+
cp = this.nextCode();
|
|
5288
|
+
while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
5289
|
+
continue;
|
|
5290
|
+
}
|
|
5291
|
+
}
|
|
5292
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
5293
|
+
}
|
|
5294
|
+
out2.push(cp);
|
|
5295
|
+
cp = this.nextCode();
|
|
5296
|
+
}
|
|
5297
|
+
return this.reportParseError("unterminated-string");
|
|
5298
|
+
}
|
|
5299
|
+
LITERAL_STRING(cp) {
|
|
5300
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
5301
|
+
cp = this.nextCode();
|
|
5302
|
+
if (cp === CodePoint.SINGLE_QUOTE) return "MULTI_LINE_LITERAL_STRING";
|
|
5303
|
+
this.endToken("LiteralString", "start", "");
|
|
5304
|
+
return this.back("DATA");
|
|
5305
|
+
}
|
|
5306
|
+
const out2 = [];
|
|
5307
|
+
while (cp !== CodePoint.SINGLE_QUOTE && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
|
|
5308
|
+
if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
5309
|
+
out2.push(cp);
|
|
5310
|
+
cp = this.nextCode();
|
|
5311
|
+
}
|
|
5312
|
+
if (cp !== CodePoint.SINGLE_QUOTE) return this.reportParseError("unterminated-string");
|
|
5313
|
+
this.endToken("LiteralString", "end", String.fromCodePoint(...out2));
|
|
5314
|
+
return "DATA";
|
|
5315
|
+
}
|
|
5316
|
+
MULTI_LINE_LITERAL_STRING(cp) {
|
|
5317
|
+
const out2 = [];
|
|
5318
|
+
if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
5319
|
+
while (cp !== CodePoint.EOF) {
|
|
5320
|
+
if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
5321
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
5322
|
+
const startPos = this.codePointIterator.start;
|
|
5323
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE) && this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
5324
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
5325
|
+
out2.push(CodePoint.SINGLE_QUOTE);
|
|
5326
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
5327
|
+
out2.push(CodePoint.SINGLE_QUOTE);
|
|
5328
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
5329
|
+
this.moveAt(startPos);
|
|
5330
|
+
return this.reportParseError("invalid-three-quotes");
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
}
|
|
5334
|
+
this.endToken("MultiLineLiteralString", "end", String.fromCodePoint(...out2));
|
|
5335
|
+
return "DATA";
|
|
5336
|
+
}
|
|
5337
|
+
this.moveAt(startPos);
|
|
5338
|
+
}
|
|
5339
|
+
out2.push(cp);
|
|
5340
|
+
cp = this.nextCode();
|
|
5341
|
+
}
|
|
5342
|
+
return this.reportParseError("unterminated-string");
|
|
5343
|
+
}
|
|
5344
|
+
SIGN(cp) {
|
|
5345
|
+
if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) return this.back("NAN_OR_INF");
|
|
5346
|
+
if (isDigit(cp)) return this.back("NUMBER");
|
|
5347
|
+
return this.reportParseError("unexpected-char");
|
|
5348
|
+
}
|
|
5349
|
+
NAN_OR_INF(cp) {
|
|
5350
|
+
if (cp === CodePoint.LATIN_SMALL_N) {
|
|
5351
|
+
const startPos = this.codePointIterator.start;
|
|
5352
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_A) && this.eatCode(CodePoint.LATIN_SMALL_N)) {
|
|
5353
|
+
this.endToken("Float", "end", NaN);
|
|
5354
|
+
return "DATA";
|
|
5355
|
+
}
|
|
5356
|
+
this.moveAt(startPos);
|
|
5357
|
+
} else if (cp === CodePoint.LATIN_SMALL_I) {
|
|
5358
|
+
const startPos = this.codePointIterator.start;
|
|
5359
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_N) && this.eatCode(CodePoint.LATIN_SMALL_F)) {
|
|
5360
|
+
this.endToken("Float", "end", this.text[this.tokenStart] === "-" ? -Infinity : Infinity);
|
|
5361
|
+
return "DATA";
|
|
5362
|
+
}
|
|
5363
|
+
this.moveAt(startPos);
|
|
5364
|
+
}
|
|
5365
|
+
return this.reportParseError("unexpected-char");
|
|
5366
|
+
}
|
|
5367
|
+
NUMBER(cp) {
|
|
5368
|
+
const start = this.text[this.tokenStart];
|
|
5369
|
+
const sign = start === "+" ? CodePoint.PLUS_SIGN : start === "-" ? CodePoint.DASH : CodePoint.NULL;
|
|
5370
|
+
if (cp === CodePoint.DIGIT_0) {
|
|
5371
|
+
if (sign === CodePoint.NULL) {
|
|
5372
|
+
const startPos = this.codePointIterator.start;
|
|
5373
|
+
const nextCp$1 = this.nextCode();
|
|
5374
|
+
if (isDigit(nextCp$1)) {
|
|
5375
|
+
const nextNextCp = this.nextCode();
|
|
5376
|
+
if (nextNextCp === CodePoint.COLON) {
|
|
5377
|
+
this.data = {
|
|
5378
|
+
hasDate: false,
|
|
5379
|
+
year: 0,
|
|
5380
|
+
month: 0,
|
|
5381
|
+
day: 0,
|
|
5382
|
+
hour: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1)),
|
|
5383
|
+
minute: 0,
|
|
5384
|
+
second: 0
|
|
5385
|
+
};
|
|
5386
|
+
return "TIME_MINUTE";
|
|
5387
|
+
}
|
|
5388
|
+
if (isDigit(nextNextCp)) {
|
|
5389
|
+
const nextNextNextCp = this.nextCode();
|
|
5390
|
+
if (isDigit(nextNextNextCp) && this.eatCode(CodePoint.DASH)) {
|
|
5391
|
+
this.data = {
|
|
5392
|
+
hasDate: true,
|
|
5393
|
+
year: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1, nextNextCp, nextNextNextCp)),
|
|
5394
|
+
month: 0,
|
|
5395
|
+
day: 0,
|
|
5396
|
+
hour: 0,
|
|
5397
|
+
minute: 0,
|
|
5398
|
+
second: 0
|
|
5399
|
+
};
|
|
5400
|
+
return "DATE_MONTH";
|
|
5401
|
+
}
|
|
5402
|
+
}
|
|
5403
|
+
this.moveAt(startPos);
|
|
5404
|
+
return this.reportParseError("invalid-leading-zero");
|
|
5405
|
+
}
|
|
5406
|
+
this.moveAt(startPos);
|
|
5407
|
+
}
|
|
5408
|
+
cp = this.nextCode();
|
|
5409
|
+
if (cp === CodePoint.LATIN_SMALL_X || cp === CodePoint.LATIN_SMALL_O || cp === CodePoint.LATIN_SMALL_B) {
|
|
5410
|
+
if (sign !== CodePoint.NULL) return this.reportParseError("unexpected-char");
|
|
5411
|
+
return cp === CodePoint.LATIN_SMALL_X ? "HEX" : cp === CodePoint.LATIN_SMALL_O ? "OCTAL" : "BINARY";
|
|
5412
|
+
}
|
|
5413
|
+
if (cp === CodePoint.LATIN_SMALL_E || cp === CodePoint.LATIN_CAPITAL_E) {
|
|
5414
|
+
this.data = {
|
|
5415
|
+
minus: sign === CodePoint.DASH,
|
|
5416
|
+
left: [CodePoint.DIGIT_0]
|
|
5417
|
+
};
|
|
5418
|
+
return "EXPONENT_RIGHT";
|
|
5419
|
+
}
|
|
5420
|
+
if (cp === CodePoint.DOT) {
|
|
5421
|
+
this.data = {
|
|
5422
|
+
minus: sign === CodePoint.DASH,
|
|
5423
|
+
absInt: [CodePoint.DIGIT_0]
|
|
5424
|
+
};
|
|
5425
|
+
return "FRACTIONAL_RIGHT";
|
|
5426
|
+
}
|
|
5427
|
+
this.endToken("Integer", "start", "0", 10);
|
|
5428
|
+
return this.back("DATA");
|
|
5429
|
+
}
|
|
5430
|
+
const { out: out2, nextCp, hasUnderscore } = this.parseDigits(cp, isDigit);
|
|
5431
|
+
if (nextCp === CodePoint.DASH && sign === CodePoint.NULL && !hasUnderscore && out2.length === 4) {
|
|
5432
|
+
this.data = {
|
|
5433
|
+
hasDate: true,
|
|
5434
|
+
year: Number(String.fromCodePoint(...out2)),
|
|
5435
|
+
month: 0,
|
|
5436
|
+
day: 0,
|
|
5437
|
+
hour: 0,
|
|
5438
|
+
minute: 0,
|
|
5439
|
+
second: 0
|
|
5440
|
+
};
|
|
5441
|
+
return "DATE_MONTH";
|
|
5442
|
+
}
|
|
5443
|
+
if (nextCp === CodePoint.COLON && sign === CodePoint.NULL && !hasUnderscore && out2.length === 2) {
|
|
5444
|
+
this.data = {
|
|
5445
|
+
hasDate: false,
|
|
5446
|
+
year: 0,
|
|
5447
|
+
month: 0,
|
|
5448
|
+
day: 0,
|
|
5449
|
+
hour: Number(String.fromCodePoint(...out2)),
|
|
5450
|
+
minute: 0,
|
|
5451
|
+
second: 0
|
|
5452
|
+
};
|
|
5453
|
+
return "TIME_MINUTE";
|
|
5454
|
+
}
|
|
5455
|
+
if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
|
|
5456
|
+
this.data = {
|
|
5457
|
+
minus: sign === CodePoint.DASH,
|
|
5458
|
+
left: out2
|
|
5459
|
+
};
|
|
5460
|
+
return "EXPONENT_RIGHT";
|
|
5461
|
+
}
|
|
5462
|
+
if (nextCp === CodePoint.DOT) {
|
|
5463
|
+
this.data = {
|
|
5464
|
+
minus: sign === CodePoint.DASH,
|
|
5465
|
+
absInt: out2
|
|
5466
|
+
};
|
|
5467
|
+
return "FRACTIONAL_RIGHT";
|
|
5468
|
+
}
|
|
5469
|
+
this.endToken("Integer", "start", sign === CodePoint.DASH ? String.fromCodePoint(CodePoint.DASH, ...out2) : String.fromCodePoint(...out2), 10);
|
|
5470
|
+
return this.back("DATA");
|
|
5471
|
+
}
|
|
5472
|
+
HEX(cp) {
|
|
5473
|
+
const { out: out2 } = this.parseDigits(cp, isHexDig);
|
|
5474
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out2), 16);
|
|
5475
|
+
return this.back("DATA");
|
|
5476
|
+
}
|
|
5477
|
+
OCTAL(cp) {
|
|
5478
|
+
const { out: out2 } = this.parseDigits(cp, isOctalDig);
|
|
5479
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out2), 8);
|
|
5480
|
+
return this.back("DATA");
|
|
5481
|
+
}
|
|
5482
|
+
BINARY(cp) {
|
|
5483
|
+
const { out: out2 } = this.parseDigits(cp, (c3) => c3 === CodePoint.DIGIT_0 || c3 === CodePoint.DIGIT_1);
|
|
5484
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out2), 2);
|
|
5485
|
+
return this.back("DATA");
|
|
5486
|
+
}
|
|
5487
|
+
FRACTIONAL_RIGHT(cp) {
|
|
5488
|
+
const { minus, absInt } = this.data;
|
|
5489
|
+
const { out: out2, nextCp } = this.parseDigits(cp, isDigit);
|
|
5490
|
+
const absNum = [
|
|
5491
|
+
...absInt,
|
|
5492
|
+
CodePoint.DOT,
|
|
5493
|
+
...out2
|
|
5494
|
+
];
|
|
5495
|
+
if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
|
|
5496
|
+
this.data = {
|
|
5497
|
+
minus,
|
|
5498
|
+
left: absNum
|
|
5499
|
+
};
|
|
5500
|
+
return "EXPONENT_RIGHT";
|
|
5501
|
+
}
|
|
5502
|
+
const value = Number(minus ? String.fromCodePoint(CodePoint.DASH, ...absNum) : String.fromCodePoint(...absNum));
|
|
5503
|
+
this.endToken("Float", "start", value);
|
|
5504
|
+
return this.back("DATA");
|
|
5505
|
+
}
|
|
5506
|
+
EXPONENT_RIGHT(cp) {
|
|
5507
|
+
const { left, minus: leftMinus } = this.data;
|
|
5508
|
+
let minus = false;
|
|
5509
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
5510
|
+
minus = cp === CodePoint.DASH;
|
|
5511
|
+
cp = this.nextCode();
|
|
5512
|
+
}
|
|
5513
|
+
const { out: out2 } = this.parseDigits(cp, isDigit);
|
|
5514
|
+
const right = out2;
|
|
5515
|
+
if (minus) right.unshift(CodePoint.DASH);
|
|
5516
|
+
const value = Number(leftMinus ? String.fromCodePoint(CodePoint.DASH, ...left, CodePoint.LATIN_SMALL_E, ...right) : String.fromCodePoint(...left, CodePoint.LATIN_SMALL_E, ...right));
|
|
5517
|
+
this.endToken("Float", "start", value);
|
|
5518
|
+
return this.back("DATA");
|
|
5519
|
+
}
|
|
5520
|
+
BOOLEAN(cp) {
|
|
5521
|
+
if (cp === CodePoint.LATIN_SMALL_T) {
|
|
5522
|
+
const startPos = this.codePointIterator.start;
|
|
5523
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_R) && this.eatCode(CodePoint.LATIN_SMALL_U) && this.eatCode(CodePoint.LATIN_SMALL_E)) {
|
|
5524
|
+
this.endToken("Boolean", "end", true);
|
|
5525
|
+
return "DATA";
|
|
5526
|
+
}
|
|
5527
|
+
this.moveAt(startPos);
|
|
5528
|
+
} else if (cp === CodePoint.LATIN_SMALL_F) {
|
|
5529
|
+
const startPos = this.codePointIterator.start;
|
|
5530
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_A) && this.eatCode(CodePoint.LATIN_SMALL_L) && this.eatCode(CodePoint.LATIN_SMALL_S) && this.eatCode(CodePoint.LATIN_SMALL_E)) {
|
|
5531
|
+
this.endToken("Boolean", "end", false);
|
|
5532
|
+
return "DATA";
|
|
5533
|
+
}
|
|
5534
|
+
this.moveAt(startPos);
|
|
5535
|
+
}
|
|
5536
|
+
return this.reportParseError("unexpected-char");
|
|
5537
|
+
}
|
|
5538
|
+
DATE_MONTH(cp) {
|
|
5539
|
+
const start = this.codePointIterator.start;
|
|
5540
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5541
|
+
cp = this.nextCode();
|
|
5542
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5543
|
+
cp = this.nextCode();
|
|
5544
|
+
if (cp !== CodePoint.DASH) return this.reportParseError("unexpected-char");
|
|
5545
|
+
const end = this.codePointIterator.start;
|
|
5546
|
+
const data = this.data;
|
|
5547
|
+
data.month = Number(this.text.slice(start, end));
|
|
5548
|
+
return "DATE_DAY";
|
|
5549
|
+
}
|
|
5550
|
+
DATE_DAY(cp) {
|
|
5551
|
+
const start = this.codePointIterator.start;
|
|
5552
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5553
|
+
cp = this.nextCode();
|
|
5554
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5555
|
+
const end = this.codePointIterator.end;
|
|
5556
|
+
const data = this.data;
|
|
5557
|
+
data.day = Number(this.text.slice(start, end));
|
|
5558
|
+
if (!isValidDate(data.year, data.month, data.day)) return this.reportParseError("invalid-date");
|
|
5559
|
+
cp = this.nextCode();
|
|
5560
|
+
if (cp === CodePoint.LATIN_CAPITAL_T || cp === CodePoint.LATIN_SMALL_T) return "TIME_HOUR";
|
|
5561
|
+
if (cp === CodePoint.SPACE) {
|
|
5562
|
+
const startPos = this.codePointIterator.start;
|
|
5563
|
+
if (isDigit(this.nextCode()) && isDigit(this.nextCode())) {
|
|
5564
|
+
this.moveAt(startPos);
|
|
5565
|
+
return "TIME_HOUR";
|
|
5566
|
+
}
|
|
5567
|
+
this.moveAt(startPos);
|
|
5568
|
+
}
|
|
5569
|
+
const dateValue = getDateFromDateTimeData(data, "");
|
|
5570
|
+
this.endToken("LocalDate", "start", dateValue);
|
|
5571
|
+
return this.back("DATA");
|
|
5572
|
+
}
|
|
5573
|
+
TIME_HOUR(cp) {
|
|
5574
|
+
const start = this.codePointIterator.start;
|
|
5575
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5576
|
+
cp = this.nextCode();
|
|
5577
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5578
|
+
cp = this.nextCode();
|
|
5579
|
+
if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
|
|
5580
|
+
const end = this.codePointIterator.start;
|
|
5581
|
+
const data = this.data;
|
|
5582
|
+
data.hour = Number(this.text.slice(start, end));
|
|
5583
|
+
return "TIME_MINUTE";
|
|
5584
|
+
}
|
|
5585
|
+
TIME_MINUTE(cp) {
|
|
5586
|
+
const start = this.codePointIterator.start;
|
|
5587
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5588
|
+
cp = this.nextCode();
|
|
5589
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5590
|
+
const end = this.codePointIterator.end;
|
|
5591
|
+
const data = this.data;
|
|
5592
|
+
data.minute = Number(this.text.slice(start, end));
|
|
5593
|
+
cp = this.nextCode();
|
|
5594
|
+
if (cp === CodePoint.COLON) return "TIME_SECOND";
|
|
5595
|
+
if (this.tomlVersion.lt(1, 1)) return this.reportParseError("unexpected-char");
|
|
5596
|
+
if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
|
|
5597
|
+
return this.processTimeEnd(cp, data);
|
|
5598
|
+
}
|
|
5599
|
+
TIME_SECOND(cp) {
|
|
5600
|
+
const start = this.codePointIterator.start;
|
|
5601
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5602
|
+
cp = this.nextCode();
|
|
5603
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5604
|
+
const end = this.codePointIterator.end;
|
|
5605
|
+
const data = this.data;
|
|
5606
|
+
data.second = Number(this.text.slice(start, end));
|
|
5607
|
+
if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
|
|
5608
|
+
cp = this.nextCode();
|
|
5609
|
+
if (cp === CodePoint.DOT) return "TIME_SEC_FRAC";
|
|
5610
|
+
return this.processTimeEnd(cp, data);
|
|
5611
|
+
}
|
|
5612
|
+
TIME_SEC_FRAC(cp) {
|
|
5613
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5614
|
+
const start = this.codePointIterator.start;
|
|
5615
|
+
while (isDigit(cp)) cp = this.nextCode();
|
|
5616
|
+
const end = this.codePointIterator.start;
|
|
5617
|
+
const data = this.data;
|
|
5618
|
+
data.frac = this.text.slice(start, end);
|
|
5619
|
+
return this.processTimeEnd(cp, data);
|
|
5620
|
+
}
|
|
5621
|
+
processTimeEnd(cp, data) {
|
|
5622
|
+
if (data.hasDate) {
|
|
5623
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
5624
|
+
data.offsetSign = cp;
|
|
5625
|
+
return "TIME_OFFSET";
|
|
5626
|
+
}
|
|
5627
|
+
if (cp === CodePoint.LATIN_CAPITAL_Z || cp === CodePoint.LATIN_SMALL_Z) {
|
|
5628
|
+
const dateValue$2 = getDateFromDateTimeData(data, "Z");
|
|
5629
|
+
this.endToken("OffsetDateTime", "end", dateValue$2);
|
|
5630
|
+
return "DATA";
|
|
5631
|
+
}
|
|
5632
|
+
const dateValue$1 = getDateFromDateTimeData(data, "");
|
|
5633
|
+
this.endToken("LocalDateTime", "start", dateValue$1);
|
|
5634
|
+
return this.back("DATA");
|
|
5635
|
+
}
|
|
5636
|
+
const dateValue = getDateFromDateTimeData(data, "");
|
|
5637
|
+
this.endToken("LocalTime", "start", dateValue);
|
|
5638
|
+
return this.back("DATA");
|
|
5639
|
+
}
|
|
5640
|
+
TIME_OFFSET(cp) {
|
|
5641
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5642
|
+
const hourStart = this.codePointIterator.start;
|
|
5643
|
+
cp = this.nextCode();
|
|
5644
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5645
|
+
cp = this.nextCode();
|
|
5646
|
+
if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
|
|
5647
|
+
const hourEnd = this.codePointIterator.start;
|
|
5648
|
+
cp = this.nextCode();
|
|
5649
|
+
const minuteStart = this.codePointIterator.start;
|
|
5650
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5651
|
+
cp = this.nextCode();
|
|
5652
|
+
if (!isDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5653
|
+
const minuteEnd = this.codePointIterator.end;
|
|
5654
|
+
const hour = Number(this.text.slice(hourStart, hourEnd));
|
|
5655
|
+
const minute = Number(this.text.slice(minuteStart, minuteEnd));
|
|
5656
|
+
if (!isValidTime(hour, minute, 0)) return this.reportParseError("invalid-time");
|
|
5657
|
+
const data = this.data;
|
|
5658
|
+
const dateValue = getDateFromDateTimeData(data, `${String.fromCodePoint(data.offsetSign)}${padStart(hour, 2)}:${padStart(minute, 2)}`);
|
|
5659
|
+
this.endToken("OffsetDateTime", "end", dateValue);
|
|
5660
|
+
return "DATA";
|
|
5661
|
+
}
|
|
5662
|
+
parseDigits(cp, checkDigit) {
|
|
5663
|
+
if (cp === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
5664
|
+
if (!checkDigit(cp)) return this.reportParseError("unexpected-char");
|
|
5665
|
+
const out2 = [];
|
|
5666
|
+
let before = CodePoint.NULL;
|
|
5667
|
+
let hasUnderscore = false;
|
|
5668
|
+
while (checkDigit(cp) || cp === CodePoint.UNDERSCORE) {
|
|
5669
|
+
if (cp === CodePoint.UNDERSCORE) {
|
|
5670
|
+
hasUnderscore = true;
|
|
5671
|
+
if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
5672
|
+
} else out2.push(cp);
|
|
5673
|
+
before = cp;
|
|
5674
|
+
cp = this.nextCode();
|
|
5675
|
+
}
|
|
5676
|
+
if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
5677
|
+
return {
|
|
5678
|
+
out: out2,
|
|
5679
|
+
nextCp: cp,
|
|
5680
|
+
hasUnderscore
|
|
5681
|
+
};
|
|
5682
|
+
}
|
|
5683
|
+
parseUnicode(count) {
|
|
5684
|
+
const startLoc = this.codePointIterator.start;
|
|
5685
|
+
const start = this.codePointIterator.end;
|
|
5686
|
+
let charCount = 0;
|
|
5687
|
+
let cp;
|
|
5688
|
+
while ((cp = this.nextCode()) !== CodePoint.EOF) {
|
|
5689
|
+
if (!isHexDig(cp)) {
|
|
5690
|
+
this.moveAt(startLoc);
|
|
5691
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
5692
|
+
}
|
|
5693
|
+
charCount++;
|
|
5694
|
+
if (charCount >= count) break;
|
|
5695
|
+
}
|
|
5696
|
+
const end = this.codePointIterator.end;
|
|
5697
|
+
const code = this.text.slice(start, end);
|
|
5698
|
+
const codePoint = parseInt(code, 16);
|
|
5699
|
+
if (!isUnicodeScalarValue(codePoint)) return this.reportParseError("invalid-code-point", { cp: code });
|
|
5700
|
+
return codePoint;
|
|
5701
|
+
}
|
|
5702
|
+
reportParseErrorControlChar() {
|
|
5703
|
+
return this.reportParseError("invalid-control-character");
|
|
5704
|
+
}
|
|
5705
|
+
};
|
|
5706
|
+
function isUnquotedKeyChar(cp, tomlVersion) {
|
|
5707
|
+
if (isLetter(cp) || isDigit(cp) || cp === CodePoint.UNDERSCORE || cp === CodePoint.DASH) return true;
|
|
5708
|
+
if (tomlVersion.lt(1, 1)) return false;
|
|
5709
|
+
return false;
|
|
5710
|
+
}
|
|
5711
|
+
function isControlOtherThanTab(cp) {
|
|
5712
|
+
return isControl(cp) && cp !== CodePoint.TABULATION || cp === CodePoint.DELETE;
|
|
5713
|
+
}
|
|
5714
|
+
function isNonEOL(cp) {
|
|
5715
|
+
return cp === CodePoint.TABULATION || CodePoint.SPACE <= cp && cp <= CodePoint.TILDE || isNonAscii(cp);
|
|
5716
|
+
}
|
|
5717
|
+
function isNonAscii(cp) {
|
|
5718
|
+
return CodePoint.PAD <= cp && cp <= CodePoint.CP_D7FF || CodePoint.CP_E000 <= cp && cp <= CodePoint.CP_10FFFF;
|
|
5719
|
+
}
|
|
5720
|
+
function isValidDate(y2, m3, d) {
|
|
5721
|
+
if (y2 >= 0 && m3 <= 12 && m3 >= 1 && d >= 1) return d <= (m3 === 2 ? y2 & 3 || !(y2 % 25) && y2 & 15 ? 28 : 29 : 30 + (m3 + (m3 >> 3) & 1));
|
|
5722
|
+
return false;
|
|
5723
|
+
}
|
|
5724
|
+
function isValidTime(h2, m3, s) {
|
|
5725
|
+
if (h2 >= 24 || h2 < 0 || m3 > 59 || m3 < 0 || s > 60 || s < 0) return false;
|
|
5726
|
+
return true;
|
|
5727
|
+
}
|
|
5728
|
+
function getDateFromDateTimeData(data, timeZone) {
|
|
5729
|
+
const year = padStart(data.year, 4);
|
|
5730
|
+
const month = data.month ? padStart(data.month, 2) : "01";
|
|
5731
|
+
const day = data.day ? padStart(data.day, 2) : "01";
|
|
5732
|
+
const hour = padStart(data.hour, 2);
|
|
5733
|
+
const minute = padStart(data.minute, 2);
|
|
5734
|
+
const second = padStart(data.second, 2);
|
|
5735
|
+
const textDate = `${year}-${month}-${day}`;
|
|
5736
|
+
const frac = data.frac ? `.${data.frac}` : "";
|
|
5737
|
+
const dateValue = /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:${second}${frac}${timeZone}`);
|
|
5738
|
+
if (!isNaN(dateValue.getTime()) || data.second !== 60) return dateValue;
|
|
5739
|
+
return /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:59${frac}${timeZone}`);
|
|
5740
|
+
}
|
|
5741
|
+
function padStart(num, maxLength) {
|
|
5742
|
+
return String(num).padStart(maxLength, "0");
|
|
5743
|
+
}
|
|
5744
|
+
var VALUE_KIND_VALUE = Symbol("VALUE_KIND_VALUE");
|
|
5745
|
+
var VALUE_KIND_INTERMEDIATE = Symbol("VALUE_KIND_INTERMEDIATE");
|
|
5746
|
+
var KeysResolver = class {
|
|
5747
|
+
constructor(ctx) {
|
|
5748
|
+
this.rootKeys = /* @__PURE__ */ new Map();
|
|
5749
|
+
this.tables = [];
|
|
5750
|
+
this.ctx = ctx;
|
|
5751
|
+
}
|
|
5752
|
+
applyResolveKeyForTable(node) {
|
|
5753
|
+
let keys = this.rootKeys;
|
|
5754
|
+
const peekKeyIndex = node.key.keys.length - 1;
|
|
5755
|
+
for (let index = 0; index < peekKeyIndex; index++) {
|
|
5756
|
+
const keyNode = node.key.keys[index];
|
|
5757
|
+
const keyName = toKeyName(keyNode);
|
|
5758
|
+
node.resolvedKey.push(keyName);
|
|
5759
|
+
let keyStore = keys.get(keyName);
|
|
5760
|
+
if (!keyStore) {
|
|
5761
|
+
keyStore = {
|
|
5762
|
+
node: keyNode,
|
|
5763
|
+
keys: /* @__PURE__ */ new Map()
|
|
5764
|
+
};
|
|
5765
|
+
keys.set(keyName, keyStore);
|
|
5766
|
+
} else if (keyStore.table === "array") {
|
|
5767
|
+
const peekIndex = keyStore.peekIndex;
|
|
5768
|
+
node.resolvedKey.push(peekIndex);
|
|
5769
|
+
keyStore = keyStore.keys.get(peekIndex);
|
|
5770
|
+
}
|
|
5771
|
+
keys = keyStore.keys;
|
|
5772
|
+
}
|
|
5773
|
+
const lastKeyNode = node.key.keys[peekKeyIndex];
|
|
5774
|
+
const lastKeyName = toKeyName(lastKeyNode);
|
|
5775
|
+
node.resolvedKey.push(lastKeyName);
|
|
5776
|
+
const lastKeyStore = keys.get(lastKeyName);
|
|
5777
|
+
if (!lastKeyStore) if (node.kind === "array") {
|
|
5778
|
+
node.resolvedKey.push(0);
|
|
5779
|
+
const newKeyStore = {
|
|
5780
|
+
node: lastKeyNode,
|
|
5781
|
+
keys: /* @__PURE__ */ new Map()
|
|
5782
|
+
};
|
|
5783
|
+
keys.set(lastKeyName, {
|
|
5784
|
+
table: node.kind,
|
|
5785
|
+
node: lastKeyNode,
|
|
5786
|
+
keys: /* @__PURE__ */ new Map([[0, newKeyStore]]),
|
|
5787
|
+
peekIndex: 0
|
|
5788
|
+
});
|
|
5789
|
+
this.tables.push({
|
|
5790
|
+
node,
|
|
5791
|
+
keys: newKeyStore.keys
|
|
5792
|
+
});
|
|
5793
|
+
} else {
|
|
5794
|
+
const newKeyStore = {
|
|
5795
|
+
table: node.kind,
|
|
5796
|
+
node: lastKeyNode,
|
|
5797
|
+
keys: /* @__PURE__ */ new Map()
|
|
5798
|
+
};
|
|
5799
|
+
keys.set(lastKeyName, newKeyStore);
|
|
5800
|
+
this.tables.push({
|
|
5801
|
+
node,
|
|
5802
|
+
keys: newKeyStore.keys
|
|
5803
|
+
});
|
|
5804
|
+
}
|
|
5805
|
+
else if (!lastKeyStore.table) if (node.kind === "array") this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
5806
|
+
else {
|
|
5807
|
+
const transformKey = {
|
|
5808
|
+
table: node.kind,
|
|
5809
|
+
node: lastKeyNode,
|
|
5810
|
+
keys: lastKeyStore.keys
|
|
5811
|
+
};
|
|
5812
|
+
keys.set(lastKeyName, transformKey);
|
|
5813
|
+
this.tables.push({
|
|
5814
|
+
node,
|
|
5815
|
+
keys: transformKey.keys
|
|
5816
|
+
});
|
|
5817
|
+
}
|
|
5818
|
+
else if (lastKeyStore.table === "array") if (node.kind === "array") {
|
|
5819
|
+
const newKeyStore = {
|
|
5820
|
+
node: lastKeyNode,
|
|
5821
|
+
keys: /* @__PURE__ */ new Map()
|
|
5822
|
+
};
|
|
5823
|
+
const newIndex = lastKeyStore.peekIndex + 1;
|
|
5824
|
+
node.resolvedKey.push(newIndex);
|
|
5825
|
+
lastKeyStore.keys.set(newIndex, newKeyStore);
|
|
5826
|
+
lastKeyStore.peekIndex = newIndex;
|
|
5827
|
+
this.tables.push({
|
|
5828
|
+
node,
|
|
5829
|
+
keys: newKeyStore.keys
|
|
5830
|
+
});
|
|
5831
|
+
} else this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
5832
|
+
else this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
5833
|
+
}
|
|
5834
|
+
verifyDuplicateKeys(node) {
|
|
5835
|
+
for (const body of node.body) if (body.type === "TOMLKeyValue") verifyDuplicateKeysForKeyValue(this.ctx, this.rootKeys, body);
|
|
5836
|
+
for (const { node: tableNode, keys } of this.tables) for (const body of tableNode.body) verifyDuplicateKeysForKeyValue(this.ctx, keys, body);
|
|
5837
|
+
}
|
|
5838
|
+
};
|
|
5839
|
+
function verifyDuplicateKeysForKeyValue(ctx, defineKeys, node) {
|
|
5840
|
+
let keys = defineKeys;
|
|
5841
|
+
const lastKey = last(node.key.keys);
|
|
5842
|
+
for (const keyNode of node.key.keys) {
|
|
5843
|
+
const key = toKeyName(keyNode);
|
|
5844
|
+
let defineKey = keys.get(key);
|
|
5845
|
+
if (defineKey) {
|
|
5846
|
+
if (defineKey.value === VALUE_KIND_VALUE) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
5847
|
+
else if (lastKey === keyNode) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
5848
|
+
else if (defineKey.table) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
5849
|
+
defineKey.value = VALUE_KIND_INTERMEDIATE;
|
|
5850
|
+
} else {
|
|
5851
|
+
if (lastKey === keyNode) defineKey = {
|
|
5852
|
+
value: VALUE_KIND_VALUE,
|
|
5853
|
+
node: keyNode,
|
|
5854
|
+
keys: /* @__PURE__ */ new Map()
|
|
5855
|
+
};
|
|
5856
|
+
else defineKey = {
|
|
5857
|
+
value: VALUE_KIND_INTERMEDIATE,
|
|
5858
|
+
node: keyNode,
|
|
5859
|
+
keys: /* @__PURE__ */ new Map()
|
|
5860
|
+
};
|
|
5861
|
+
keys.set(key, defineKey);
|
|
5862
|
+
}
|
|
5863
|
+
keys = defineKey.keys;
|
|
5864
|
+
}
|
|
5865
|
+
if (node.value.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, keys, node.value);
|
|
5866
|
+
else if (node.value.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, keys, node.value);
|
|
5867
|
+
}
|
|
5868
|
+
function verifyDuplicateKeysForInlineTable(ctx, defineKeys, node) {
|
|
5869
|
+
for (const body of node.body) verifyDuplicateKeysForKeyValue(ctx, defineKeys, body);
|
|
5870
|
+
}
|
|
5871
|
+
function verifyDuplicateKeysForArray(ctx, defineKeys, node) {
|
|
5872
|
+
const keys = defineKeys;
|
|
5873
|
+
for (let index = 0; index < node.elements.length; index++) {
|
|
5874
|
+
const element = node.elements[index];
|
|
5875
|
+
let defineKey = keys.get(index);
|
|
5876
|
+
if (defineKey) ctx.reportParseError("dupe-keys", getAfterNode(element, defineKey.node));
|
|
5877
|
+
else {
|
|
5878
|
+
defineKey = {
|
|
5879
|
+
value: VALUE_KIND_VALUE,
|
|
5880
|
+
node: element,
|
|
5881
|
+
keys: /* @__PURE__ */ new Map()
|
|
5882
|
+
};
|
|
5883
|
+
defineKeys.set(index, defineKey);
|
|
5884
|
+
if (element.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, defineKey.keys, element);
|
|
5885
|
+
else if (element.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, defineKey.keys, element);
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
function getAfterNode(a2, b3) {
|
|
5890
|
+
return a2.range[0] <= b3.range[0] ? b3 : a2;
|
|
5891
|
+
}
|
|
5892
|
+
var Context = class {
|
|
5893
|
+
constructor(data) {
|
|
5894
|
+
this.tokens = [];
|
|
5895
|
+
this.comments = [];
|
|
5896
|
+
this.back = null;
|
|
5897
|
+
this.stateStack = [];
|
|
5898
|
+
this.needNewLine = false;
|
|
5899
|
+
this.needSameLine = false;
|
|
5900
|
+
this.currToken = null;
|
|
5901
|
+
this.prevToken = null;
|
|
5902
|
+
this.valueContainerStack = [];
|
|
5903
|
+
this.tokenizer = new Tokenizer(data.text, data.parserOptions);
|
|
5904
|
+
this.topLevelTable = data.topLevelTable;
|
|
5905
|
+
this.table = data.topLevelTable;
|
|
5906
|
+
this.keysResolver = new KeysResolver(this);
|
|
5907
|
+
}
|
|
5908
|
+
/**
|
|
5909
|
+
* Get the next token.
|
|
5910
|
+
*/
|
|
5911
|
+
nextToken(option) {
|
|
5912
|
+
this.prevToken = this.currToken;
|
|
5913
|
+
if (this.back) {
|
|
5914
|
+
this.currToken = this.back;
|
|
5915
|
+
this.back = null;
|
|
5916
|
+
} else this.currToken = this._nextTokenFromTokenizer(option);
|
|
5917
|
+
if ((this.needNewLine || this.needSameLine || option?.needSameLine) && this.prevToken && this.currToken) if (this.prevToken.loc.end.line === this.currToken.loc.start.line) {
|
|
5918
|
+
if (this.needNewLine) return this.reportParseError("missing-newline", this.currToken);
|
|
5919
|
+
} else {
|
|
5920
|
+
const needSameLine = this.needSameLine || option?.needSameLine;
|
|
5921
|
+
if (needSameLine) return this.reportParseError(needSameLine, this.currToken);
|
|
5922
|
+
}
|
|
5923
|
+
this.needNewLine = false;
|
|
5924
|
+
this.needSameLine = false;
|
|
5925
|
+
return this.currToken;
|
|
5926
|
+
}
|
|
5927
|
+
_nextTokenFromTokenizer(option) {
|
|
5928
|
+
const valuesEnabled = this.tokenizer.valuesEnabled;
|
|
5929
|
+
if (option?.valuesEnabled) this.tokenizer.valuesEnabled = option.valuesEnabled;
|
|
5930
|
+
let token = this.tokenizer.nextToken();
|
|
5931
|
+
while (token && token.type === "Block") {
|
|
5932
|
+
this.comments.push(token);
|
|
5933
|
+
token = this.tokenizer.nextToken();
|
|
5934
|
+
}
|
|
5935
|
+
if (token) this.tokens.push(token);
|
|
5936
|
+
this.tokenizer.valuesEnabled = valuesEnabled;
|
|
5937
|
+
return token;
|
|
5938
|
+
}
|
|
5939
|
+
backToken() {
|
|
5940
|
+
if (this.back) throw new Error("Illegal state");
|
|
5941
|
+
this.back = this.currToken;
|
|
5942
|
+
this.currToken = this.prevToken;
|
|
5943
|
+
}
|
|
5944
|
+
addValueContainer(valueContainer) {
|
|
5945
|
+
this.valueContainerStack.push(valueContainer);
|
|
5946
|
+
this.tokenizer.valuesEnabled = true;
|
|
5947
|
+
}
|
|
5948
|
+
consumeValueContainer() {
|
|
5949
|
+
const valueContainer = this.valueContainerStack.pop();
|
|
5950
|
+
this.tokenizer.valuesEnabled = this.valueContainerStack.length > 0;
|
|
5951
|
+
return valueContainer;
|
|
5952
|
+
}
|
|
5953
|
+
applyResolveKeyForTable(node) {
|
|
5954
|
+
this.keysResolver.applyResolveKeyForTable(node);
|
|
5955
|
+
}
|
|
5956
|
+
verifyDuplicateKeys() {
|
|
5957
|
+
this.keysResolver.verifyDuplicateKeys(this.topLevelTable);
|
|
5958
|
+
}
|
|
5959
|
+
/**
|
|
5960
|
+
* Report an invalid token error.
|
|
5961
|
+
*/
|
|
5962
|
+
reportParseError(code, token) {
|
|
5963
|
+
let offset, line, column;
|
|
5964
|
+
if (token) {
|
|
5965
|
+
offset = token.range[0];
|
|
5966
|
+
line = token.loc.start.line;
|
|
5967
|
+
column = token.loc.start.column;
|
|
5968
|
+
} else {
|
|
5969
|
+
offset = this.tokenizer.start;
|
|
5970
|
+
const startPos = this.tokenizer.getLocFromIndex(offset);
|
|
5971
|
+
line = startPos.line;
|
|
5972
|
+
column = startPos.column;
|
|
5973
|
+
}
|
|
5974
|
+
throw new ParseError(code, offset, line, column);
|
|
5975
|
+
}
|
|
5976
|
+
};
|
|
5977
|
+
var STATE_FOR_ERROR = { VALUE: "missing-value" };
|
|
5978
|
+
var STRING_VALUE_STYLE_MAP = {
|
|
5979
|
+
BasicString: "basic",
|
|
5980
|
+
MultiLineBasicString: "basic",
|
|
5981
|
+
LiteralString: "literal",
|
|
5982
|
+
MultiLineLiteralString: "literal"
|
|
5983
|
+
};
|
|
5984
|
+
var STRING_KEY_STYLE_MAP = {
|
|
5985
|
+
BasicString: "basic",
|
|
5986
|
+
LiteralString: "literal"
|
|
5987
|
+
};
|
|
5988
|
+
var DATETIME_VALUE_KIND_MAP = {
|
|
5989
|
+
OffsetDateTime: "offset-date-time",
|
|
5990
|
+
LocalDateTime: "local-date-time",
|
|
5991
|
+
LocalDate: "local-date",
|
|
5992
|
+
LocalTime: "local-time"
|
|
5993
|
+
};
|
|
5994
|
+
var TOMLParser = class {
|
|
5995
|
+
/**
|
|
5996
|
+
* Initialize this parser.
|
|
5997
|
+
*/
|
|
5998
|
+
constructor(text2, parserOptions) {
|
|
5999
|
+
this.text = text2;
|
|
6000
|
+
this.parserOptions = parserOptions || {};
|
|
6001
|
+
this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
|
|
6002
|
+
}
|
|
6003
|
+
/**
|
|
6004
|
+
* Parse TOML
|
|
6005
|
+
*/
|
|
6006
|
+
parse() {
|
|
6007
|
+
const ast = {
|
|
6008
|
+
type: "Program",
|
|
6009
|
+
body: [],
|
|
6010
|
+
sourceType: "module",
|
|
6011
|
+
tokens: [],
|
|
6012
|
+
comments: [],
|
|
6013
|
+
parent: null,
|
|
6014
|
+
range: [0, 0],
|
|
6015
|
+
loc: {
|
|
6016
|
+
start: {
|
|
6017
|
+
line: 1,
|
|
6018
|
+
column: 0
|
|
6019
|
+
},
|
|
6020
|
+
end: {
|
|
6021
|
+
line: 1,
|
|
6022
|
+
column: 0
|
|
6023
|
+
}
|
|
6024
|
+
}
|
|
6025
|
+
};
|
|
6026
|
+
const node = {
|
|
6027
|
+
type: "TOMLTopLevelTable",
|
|
6028
|
+
body: [],
|
|
6029
|
+
parent: ast,
|
|
6030
|
+
range: cloneRange(ast.range),
|
|
6031
|
+
loc: cloneLoc(ast.loc)
|
|
6032
|
+
};
|
|
6033
|
+
ast.body = [node];
|
|
6034
|
+
const ctx = new Context({
|
|
6035
|
+
text: this.text,
|
|
6036
|
+
parserOptions: this.parserOptions,
|
|
6037
|
+
topLevelTable: node
|
|
6038
|
+
});
|
|
6039
|
+
let token = ctx.nextToken();
|
|
6040
|
+
if (token) {
|
|
6041
|
+
node.range[0] = token.range[0];
|
|
6042
|
+
node.loc.start = clonePos(token.loc.start);
|
|
6043
|
+
while (token) {
|
|
6044
|
+
const state$1 = ctx.stateStack.pop() || "TABLE";
|
|
6045
|
+
ctx.stateStack.push(...this[state$1](token, ctx));
|
|
6046
|
+
token = ctx.nextToken();
|
|
6047
|
+
}
|
|
6048
|
+
const state = ctx.stateStack.pop() || "TABLE";
|
|
6049
|
+
if (state in STATE_FOR_ERROR) return ctx.reportParseError(STATE_FOR_ERROR[state], null);
|
|
6050
|
+
if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
|
|
6051
|
+
applyEndLoc(node, last(node.body));
|
|
6052
|
+
}
|
|
6053
|
+
ctx.verifyDuplicateKeys();
|
|
6054
|
+
ast.tokens = ctx.tokens;
|
|
6055
|
+
ast.comments = ctx.comments;
|
|
6056
|
+
const endOffset = ctx.tokenizer.end;
|
|
6057
|
+
const endPos = ctx.tokenizer.getLocFromIndex(endOffset);
|
|
6058
|
+
ast.range[1] = endOffset;
|
|
6059
|
+
ast.loc.end = {
|
|
6060
|
+
line: endPos.line,
|
|
6061
|
+
column: endPos.column
|
|
6062
|
+
};
|
|
6063
|
+
return ast;
|
|
6064
|
+
}
|
|
6065
|
+
TABLE(token, ctx) {
|
|
6066
|
+
if (isBare(token) || isString(token)) return this.processKeyValue(token, ctx.table, ctx);
|
|
6067
|
+
if (isLeftBracket(token)) return this.processTable(token, ctx.topLevelTable, ctx);
|
|
6068
|
+
return ctx.reportParseError("unexpected-token", token);
|
|
6069
|
+
}
|
|
6070
|
+
VALUE(token, ctx) {
|
|
6071
|
+
if (isString(token) || isMultiLineString(token)) return this.processStringValue(token, ctx);
|
|
6072
|
+
if (isNumber(token)) return this.processNumberValue(token, ctx);
|
|
6073
|
+
if (isBoolean(token)) return this.processBooleanValue(token, ctx);
|
|
6074
|
+
if (isDateTime(token)) return this.processDateTimeValue(token, ctx);
|
|
6075
|
+
if (isLeftBracket(token)) return this.processArray(token, ctx);
|
|
6076
|
+
if (isLeftBrace(token)) return this.processInlineTable(token, ctx);
|
|
6077
|
+
return ctx.reportParseError("unexpected-token", token);
|
|
6078
|
+
}
|
|
6079
|
+
processTable(token, topLevelTableNode, ctx) {
|
|
6080
|
+
const tableNode = {
|
|
6081
|
+
type: "TOMLTable",
|
|
6082
|
+
kind: "standard",
|
|
6083
|
+
key: null,
|
|
6084
|
+
resolvedKey: [],
|
|
6085
|
+
body: [],
|
|
6086
|
+
parent: topLevelTableNode,
|
|
6087
|
+
range: cloneRange(token.range),
|
|
6088
|
+
loc: cloneLoc(token.loc)
|
|
6089
|
+
};
|
|
6090
|
+
if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
|
|
6091
|
+
topLevelTableNode.body.push(tableNode);
|
|
6092
|
+
ctx.table = tableNode;
|
|
6093
|
+
let targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
6094
|
+
if (isLeftBracket(targetToken)) {
|
|
6095
|
+
if (token.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
|
|
6096
|
+
tableNode.kind = "array";
|
|
6097
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
6098
|
+
}
|
|
6099
|
+
if (isRightBracket(targetToken)) return ctx.reportParseError("missing-key", targetToken);
|
|
6100
|
+
if (!targetToken) return ctx.reportParseError("unterminated-table-key", null);
|
|
6101
|
+
targetToken = this.processKeyNode(targetToken, tableNode, ctx).nextToken;
|
|
6102
|
+
if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
|
|
6103
|
+
if (tableNode.kind === "array") {
|
|
6104
|
+
const rightBracket = targetToken;
|
|
6105
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
6106
|
+
if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
|
|
6107
|
+
if (rightBracket.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
|
|
6108
|
+
}
|
|
6109
|
+
applyEndLoc(tableNode, targetToken);
|
|
6110
|
+
ctx.applyResolveKeyForTable(tableNode);
|
|
6111
|
+
ctx.needNewLine = true;
|
|
6112
|
+
return [];
|
|
6113
|
+
}
|
|
6114
|
+
processKeyValue(token, tableNode, ctx) {
|
|
6115
|
+
const keyValueNode = {
|
|
6116
|
+
type: "TOMLKeyValue",
|
|
6117
|
+
key: null,
|
|
6118
|
+
value: null,
|
|
6119
|
+
parent: tableNode,
|
|
6120
|
+
range: cloneRange(token.range),
|
|
6121
|
+
loc: cloneLoc(token.loc)
|
|
6122
|
+
};
|
|
6123
|
+
tableNode.body.push(keyValueNode);
|
|
6124
|
+
const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
|
|
6125
|
+
if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
|
|
6126
|
+
ctx.addValueContainer({
|
|
6127
|
+
parent: keyValueNode,
|
|
6128
|
+
set: (valNode) => {
|
|
6129
|
+
keyValueNode.value = valNode;
|
|
6130
|
+
applyEndLoc(keyValueNode, valNode);
|
|
6131
|
+
ctx.needNewLine = true;
|
|
6132
|
+
return [];
|
|
6133
|
+
}
|
|
6134
|
+
});
|
|
6135
|
+
ctx.needSameLine = "invalid-key-value-newline";
|
|
6136
|
+
return ["VALUE"];
|
|
6137
|
+
}
|
|
6138
|
+
processKeyNode(token, parent, ctx) {
|
|
6139
|
+
if (isDot(token)) ctx.reportParseError("invalid-leading-dot-in-key", token);
|
|
6140
|
+
const keyNode = {
|
|
6141
|
+
type: "TOMLKey",
|
|
6142
|
+
keys: [],
|
|
6143
|
+
parent,
|
|
6144
|
+
range: cloneRange(token.range),
|
|
6145
|
+
loc: cloneLoc(token.loc)
|
|
6146
|
+
};
|
|
6147
|
+
parent.key = keyNode;
|
|
6148
|
+
let targetToken = token;
|
|
6149
|
+
let dotToken = null;
|
|
6150
|
+
do {
|
|
6151
|
+
if (isBare(targetToken)) this.processBareKey(targetToken, keyNode);
|
|
6152
|
+
else if (isString(targetToken)) this.processStringKey(targetToken, keyNode);
|
|
6153
|
+
else break;
|
|
6154
|
+
dotToken = null;
|
|
6155
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
6156
|
+
if (!isDot(targetToken)) break;
|
|
6157
|
+
dotToken = targetToken;
|
|
6158
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
6159
|
+
} while (targetToken);
|
|
6160
|
+
if (dotToken) ctx.reportParseError(isDot(targetToken) ? "invalid-consecutive-dots-in-key" : "invalid-trailing-dot-in-key", dotToken);
|
|
6161
|
+
applyEndLoc(keyNode, last(keyNode.keys));
|
|
6162
|
+
return {
|
|
6163
|
+
keyNode,
|
|
6164
|
+
nextToken: targetToken
|
|
6165
|
+
};
|
|
6166
|
+
}
|
|
6167
|
+
processBareKey(token, keyNode) {
|
|
6168
|
+
const node = {
|
|
6169
|
+
type: "TOMLBare",
|
|
6170
|
+
name: token.value,
|
|
6171
|
+
parent: keyNode,
|
|
6172
|
+
range: cloneRange(token.range),
|
|
6173
|
+
loc: cloneLoc(token.loc)
|
|
6174
|
+
};
|
|
6175
|
+
keyNode.keys.push(node);
|
|
6176
|
+
}
|
|
6177
|
+
processStringKey(token, keyNode) {
|
|
6178
|
+
const node = {
|
|
6179
|
+
type: "TOMLQuoted",
|
|
6180
|
+
kind: "string",
|
|
6181
|
+
value: token.string,
|
|
6182
|
+
style: STRING_KEY_STYLE_MAP[token.type],
|
|
6183
|
+
multiline: false,
|
|
6184
|
+
parent: keyNode,
|
|
6185
|
+
range: cloneRange(token.range),
|
|
6186
|
+
loc: cloneLoc(token.loc)
|
|
6187
|
+
};
|
|
6188
|
+
keyNode.keys.push(node);
|
|
6189
|
+
}
|
|
6190
|
+
processStringValue(token, ctx) {
|
|
6191
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6192
|
+
const node = {
|
|
6193
|
+
type: "TOMLValue",
|
|
6194
|
+
kind: "string",
|
|
6195
|
+
value: token.string,
|
|
6196
|
+
style: STRING_VALUE_STYLE_MAP[token.type],
|
|
6197
|
+
multiline: isMultiLineString(token),
|
|
6198
|
+
parent: valueContainer.parent,
|
|
6199
|
+
range: cloneRange(token.range),
|
|
6200
|
+
loc: cloneLoc(token.loc)
|
|
6201
|
+
};
|
|
6202
|
+
return valueContainer.set(node);
|
|
6203
|
+
}
|
|
6204
|
+
processNumberValue(token, ctx) {
|
|
6205
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6206
|
+
const text2 = this.text;
|
|
6207
|
+
const [startRange, endRange] = token.range;
|
|
6208
|
+
let numberString = null;
|
|
6209
|
+
const getNumberText = () => {
|
|
6210
|
+
return numberString ?? (numberString = text2.slice(startRange, endRange).replace(/_/g, ""));
|
|
6211
|
+
};
|
|
6212
|
+
let node;
|
|
6213
|
+
if (token.type === "Integer") node = {
|
|
6214
|
+
type: "TOMLValue",
|
|
6215
|
+
kind: "integer",
|
|
6216
|
+
value: token.number,
|
|
6217
|
+
bigint: token.bigint,
|
|
6218
|
+
get number() {
|
|
6219
|
+
return getNumberText();
|
|
6220
|
+
},
|
|
6221
|
+
parent: valueContainer.parent,
|
|
6222
|
+
range: cloneRange(token.range),
|
|
6223
|
+
loc: cloneLoc(token.loc)
|
|
6224
|
+
};
|
|
6225
|
+
else node = {
|
|
6226
|
+
type: "TOMLValue",
|
|
6227
|
+
kind: "float",
|
|
6228
|
+
value: token.number,
|
|
6229
|
+
get number() {
|
|
6230
|
+
return getNumberText();
|
|
6231
|
+
},
|
|
6232
|
+
parent: valueContainer.parent,
|
|
6233
|
+
range: cloneRange(token.range),
|
|
6234
|
+
loc: cloneLoc(token.loc)
|
|
6235
|
+
};
|
|
6236
|
+
return valueContainer.set(node);
|
|
6237
|
+
}
|
|
6238
|
+
processBooleanValue(token, ctx) {
|
|
6239
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6240
|
+
const node = {
|
|
6241
|
+
type: "TOMLValue",
|
|
6242
|
+
kind: "boolean",
|
|
6243
|
+
value: token.boolean,
|
|
6244
|
+
parent: valueContainer.parent,
|
|
6245
|
+
range: cloneRange(token.range),
|
|
6246
|
+
loc: cloneLoc(token.loc)
|
|
6247
|
+
};
|
|
6248
|
+
return valueContainer.set(node);
|
|
6249
|
+
}
|
|
6250
|
+
processDateTimeValue(token, ctx) {
|
|
6251
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6252
|
+
const node = {
|
|
6253
|
+
type: "TOMLValue",
|
|
6254
|
+
kind: DATETIME_VALUE_KIND_MAP[token.type],
|
|
6255
|
+
value: token.date,
|
|
6256
|
+
datetime: token.value,
|
|
6257
|
+
parent: valueContainer.parent,
|
|
6258
|
+
range: cloneRange(token.range),
|
|
6259
|
+
loc: cloneLoc(token.loc)
|
|
6260
|
+
};
|
|
6261
|
+
return valueContainer.set(node);
|
|
6262
|
+
}
|
|
6263
|
+
processArray(token, ctx) {
|
|
6264
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6265
|
+
const node = {
|
|
6266
|
+
type: "TOMLArray",
|
|
6267
|
+
elements: [],
|
|
6268
|
+
parent: valueContainer.parent,
|
|
6269
|
+
range: cloneRange(token.range),
|
|
6270
|
+
loc: cloneLoc(token.loc)
|
|
6271
|
+
};
|
|
6272
|
+
const nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
6273
|
+
if (isRightBracket(nextToken)) {
|
|
6274
|
+
applyEndLoc(node, nextToken);
|
|
6275
|
+
return valueContainer.set(node);
|
|
6276
|
+
}
|
|
6277
|
+
ctx.backToken();
|
|
6278
|
+
return this.processArrayValue(node, valueContainer, ctx);
|
|
6279
|
+
}
|
|
6280
|
+
processArrayValue(node, valueContainer, ctx) {
|
|
6281
|
+
ctx.addValueContainer({
|
|
6282
|
+
parent: node,
|
|
6283
|
+
set: (valNode) => {
|
|
6284
|
+
node.elements.push(valNode);
|
|
6285
|
+
let nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
6286
|
+
const hasComma = isComma(nextToken);
|
|
6287
|
+
if (hasComma) nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
6288
|
+
if (isRightBracket(nextToken)) {
|
|
6289
|
+
applyEndLoc(node, nextToken);
|
|
6290
|
+
return valueContainer.set(node);
|
|
6291
|
+
}
|
|
6292
|
+
if (hasComma) {
|
|
6293
|
+
ctx.backToken();
|
|
6294
|
+
return this.processArrayValue(node, valueContainer, ctx);
|
|
6295
|
+
}
|
|
6296
|
+
return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-array", nextToken);
|
|
6297
|
+
}
|
|
6298
|
+
});
|
|
6299
|
+
return ["VALUE"];
|
|
6300
|
+
}
|
|
6301
|
+
processInlineTable(token, ctx) {
|
|
6302
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
6303
|
+
const node = {
|
|
6304
|
+
type: "TOMLInlineTable",
|
|
6305
|
+
body: [],
|
|
6306
|
+
parent: valueContainer.parent,
|
|
6307
|
+
range: cloneRange(token.range),
|
|
6308
|
+
loc: cloneLoc(token.loc)
|
|
6309
|
+
};
|
|
6310
|
+
const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
|
|
6311
|
+
const nextToken = ctx.nextToken({ needSameLine });
|
|
6312
|
+
if (nextToken) {
|
|
6313
|
+
if (isBare(nextToken) || isString(nextToken)) return this.processInlineTableKeyValue(nextToken, node, valueContainer, ctx);
|
|
6314
|
+
if (isRightBrace(nextToken)) {
|
|
6315
|
+
applyEndLoc(node, nextToken);
|
|
6316
|
+
return valueContainer.set(node);
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
return ctx.reportParseError("unexpected-token", nextToken);
|
|
6320
|
+
}
|
|
6321
|
+
processInlineTableKeyValue(token, inlineTableNode, valueContainer, ctx) {
|
|
6322
|
+
const keyValueNode = {
|
|
6323
|
+
type: "TOMLKeyValue",
|
|
6324
|
+
key: null,
|
|
6325
|
+
value: null,
|
|
6326
|
+
parent: inlineTableNode,
|
|
6327
|
+
range: cloneRange(token.range),
|
|
6328
|
+
loc: cloneLoc(token.loc)
|
|
6329
|
+
};
|
|
6330
|
+
inlineTableNode.body.push(keyValueNode);
|
|
6331
|
+
const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
|
|
6332
|
+
if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
|
|
6333
|
+
const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
|
|
6334
|
+
ctx.addValueContainer({
|
|
6335
|
+
parent: keyValueNode,
|
|
6336
|
+
set: (valNode) => {
|
|
6337
|
+
keyValueNode.value = valNode;
|
|
6338
|
+
applyEndLoc(keyValueNode, valNode);
|
|
6339
|
+
let nextToken = ctx.nextToken({ needSameLine });
|
|
6340
|
+
if (isComma(nextToken)) {
|
|
6341
|
+
nextToken = ctx.nextToken({ needSameLine });
|
|
6342
|
+
if (nextToken && (isBare(nextToken) || isString(nextToken))) return this.processInlineTableKeyValue(nextToken, inlineTableNode, valueContainer, ctx);
|
|
6343
|
+
if (isRightBrace(nextToken)) {
|
|
6344
|
+
if (this.tomlVersion.lt(1, 1)) return ctx.reportParseError("invalid-trailing-comma-in-inline-table", nextToken);
|
|
6345
|
+
} else return ctx.reportParseError(nextToken ? "unexpected-token" : "unterminated-inline-table", nextToken);
|
|
6346
|
+
}
|
|
6347
|
+
if (isRightBrace(nextToken)) {
|
|
6348
|
+
applyEndLoc(inlineTableNode, nextToken);
|
|
6349
|
+
return valueContainer.set(inlineTableNode);
|
|
6350
|
+
}
|
|
6351
|
+
return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-inline-table", nextToken);
|
|
6352
|
+
}
|
|
6353
|
+
});
|
|
6354
|
+
ctx.needSameLine = "invalid-key-value-newline";
|
|
6355
|
+
return ["VALUE"];
|
|
6356
|
+
}
|
|
6357
|
+
};
|
|
6358
|
+
function isDot(token) {
|
|
6359
|
+
return isPunctuator(token) && token.value === ".";
|
|
6360
|
+
}
|
|
6361
|
+
function isEq(token) {
|
|
6362
|
+
return isPunctuator(token) && token.value === "=";
|
|
6363
|
+
}
|
|
6364
|
+
function isLeftBracket(token) {
|
|
6365
|
+
return isPunctuator(token) && token.value === "[";
|
|
6366
|
+
}
|
|
6367
|
+
function isRightBracket(token) {
|
|
6368
|
+
return isPunctuator(token) && token.value === "]";
|
|
6369
|
+
}
|
|
6370
|
+
function isLeftBrace(token) {
|
|
6371
|
+
return isPunctuator(token) && token.value === "{";
|
|
6372
|
+
}
|
|
6373
|
+
function isRightBrace(token) {
|
|
6374
|
+
return isPunctuator(token) && token.value === "}";
|
|
6375
|
+
}
|
|
6376
|
+
function isComma(token) {
|
|
6377
|
+
return isPunctuator(token) && token.value === ",";
|
|
6378
|
+
}
|
|
6379
|
+
function isPunctuator(token) {
|
|
6380
|
+
return Boolean(token && token.type === "Punctuator");
|
|
6381
|
+
}
|
|
6382
|
+
function isBare(token) {
|
|
6383
|
+
return token.type === "Bare";
|
|
6384
|
+
}
|
|
6385
|
+
function isString(token) {
|
|
6386
|
+
return token.type === "BasicString" || token.type === "LiteralString";
|
|
6387
|
+
}
|
|
6388
|
+
function isMultiLineString(token) {
|
|
6389
|
+
return token.type === "MultiLineBasicString" || token.type === "MultiLineLiteralString";
|
|
6390
|
+
}
|
|
6391
|
+
function isNumber(token) {
|
|
6392
|
+
return token.type === "Integer" || token.type === "Float";
|
|
6393
|
+
}
|
|
6394
|
+
function isBoolean(token) {
|
|
6395
|
+
return token.type === "Boolean";
|
|
6396
|
+
}
|
|
6397
|
+
function isDateTime(token) {
|
|
6398
|
+
return token.type === "OffsetDateTime" || token.type === "LocalDateTime" || token.type === "LocalDate" || token.type === "LocalTime";
|
|
6399
|
+
}
|
|
6400
|
+
function applyEndLoc(node, child) {
|
|
6401
|
+
if (child) {
|
|
6402
|
+
node.range[1] = child.range[1];
|
|
6403
|
+
node.loc.end = clonePos(child.loc.end);
|
|
6404
|
+
}
|
|
6405
|
+
}
|
|
6406
|
+
function cloneRange(range) {
|
|
6407
|
+
return [range[0], range[1]];
|
|
6408
|
+
}
|
|
6409
|
+
function cloneLoc(loc) {
|
|
6410
|
+
return {
|
|
6411
|
+
start: clonePos(loc.start),
|
|
6412
|
+
end: clonePos(loc.end)
|
|
6413
|
+
};
|
|
6414
|
+
}
|
|
6415
|
+
function clonePos(pos) {
|
|
6416
|
+
return {
|
|
6417
|
+
line: pos.line,
|
|
6418
|
+
column: pos.column
|
|
6419
|
+
};
|
|
6420
|
+
}
|
|
6421
|
+
var tomlKeys = {
|
|
6422
|
+
Program: ["body"],
|
|
6423
|
+
TOMLTopLevelTable: ["body"],
|
|
6424
|
+
TOMLTable: ["key", "body"],
|
|
6425
|
+
TOMLKeyValue: ["key", "value"],
|
|
6426
|
+
TOMLKey: ["keys"],
|
|
6427
|
+
TOMLArray: ["elements"],
|
|
6428
|
+
TOMLInlineTable: ["body"],
|
|
6429
|
+
TOMLBare: [],
|
|
6430
|
+
TOMLQuoted: [],
|
|
6431
|
+
TOMLValue: []
|
|
6432
|
+
};
|
|
6433
|
+
var KEYS3 = unionWith(tomlKeys);
|
|
6434
|
+
function parseForESLint(code, options) {
|
|
6435
|
+
return {
|
|
6436
|
+
ast: new TOMLParser(code, options).parse(),
|
|
6437
|
+
visitorKeys: KEYS3,
|
|
6438
|
+
services: { isTOML: true }
|
|
6439
|
+
};
|
|
6440
|
+
}
|
|
6441
|
+
var getStaticTOMLValue = generateConvertTOMLValue((node) => node.value);
|
|
6442
|
+
function generateConvertTOMLValue(convertValue) {
|
|
6443
|
+
function resolveValue(node, baseTable) {
|
|
6444
|
+
return resolver[node.type](node, baseTable);
|
|
6445
|
+
}
|
|
6446
|
+
const resolver = {
|
|
6447
|
+
Program(node, baseTable = {}) {
|
|
6448
|
+
return resolveValue(node.body[0], baseTable);
|
|
6449
|
+
},
|
|
6450
|
+
TOMLTopLevelTable(node, baseTable = {}) {
|
|
6451
|
+
for (const body of node.body) resolveValue(body, baseTable);
|
|
6452
|
+
return baseTable;
|
|
6453
|
+
},
|
|
6454
|
+
TOMLKeyValue(node, baseTable = {}) {
|
|
6455
|
+
const value = resolveValue(node.value);
|
|
6456
|
+
set(baseTable, resolveValue(node.key), value);
|
|
6457
|
+
return baseTable;
|
|
6458
|
+
},
|
|
6459
|
+
TOMLTable(node, baseTable = {}) {
|
|
6460
|
+
const table2 = getTable(baseTable, resolveValue(node.key), node.kind === "array");
|
|
6461
|
+
for (const body of node.body) resolveValue(body, table2);
|
|
6462
|
+
return baseTable;
|
|
6463
|
+
},
|
|
6464
|
+
TOMLArray(node) {
|
|
6465
|
+
return node.elements.map((e) => resolveValue(e));
|
|
6466
|
+
},
|
|
6467
|
+
TOMLInlineTable(node) {
|
|
6468
|
+
const table2 = {};
|
|
6469
|
+
for (const body of node.body) resolveValue(body, table2);
|
|
6470
|
+
return table2;
|
|
6471
|
+
},
|
|
6472
|
+
TOMLKey(node) {
|
|
6473
|
+
return node.keys.map((key) => resolveValue(key));
|
|
6474
|
+
},
|
|
6475
|
+
TOMLBare(node) {
|
|
6476
|
+
return node.name;
|
|
6477
|
+
},
|
|
6478
|
+
TOMLQuoted(node) {
|
|
6479
|
+
return node.value;
|
|
6480
|
+
},
|
|
6481
|
+
TOMLValue(node) {
|
|
6482
|
+
return convertValue(node);
|
|
6483
|
+
}
|
|
6484
|
+
};
|
|
6485
|
+
return (node) => resolveValue(node);
|
|
6486
|
+
}
|
|
6487
|
+
function getTable(baseTable, keys, array) {
|
|
6488
|
+
let target = baseTable;
|
|
6489
|
+
for (let index = 0; index < keys.length - 1; index++) {
|
|
6490
|
+
const key = keys[index];
|
|
6491
|
+
target = getNextTargetFromKey(target, key);
|
|
6492
|
+
}
|
|
6493
|
+
const lastKey = last(keys);
|
|
6494
|
+
const lastTarget = target[lastKey];
|
|
6495
|
+
if (lastTarget == null) {
|
|
6496
|
+
const tableValue$1 = {};
|
|
6497
|
+
target[lastKey] = array ? [tableValue$1] : tableValue$1;
|
|
6498
|
+
return tableValue$1;
|
|
6499
|
+
}
|
|
6500
|
+
if (isValue(lastTarget)) {
|
|
6501
|
+
const tableValue$1 = {};
|
|
6502
|
+
target[lastKey] = array ? [tableValue$1] : tableValue$1;
|
|
6503
|
+
return tableValue$1;
|
|
6504
|
+
}
|
|
6505
|
+
if (!array) {
|
|
6506
|
+
if (Array.isArray(lastTarget)) {
|
|
6507
|
+
const tableValue$1 = {};
|
|
6508
|
+
target[lastKey] = tableValue$1;
|
|
6509
|
+
return tableValue$1;
|
|
6510
|
+
}
|
|
6511
|
+
return lastTarget;
|
|
6512
|
+
}
|
|
6513
|
+
if (Array.isArray(lastTarget)) {
|
|
6514
|
+
const tableValue$1 = {};
|
|
6515
|
+
lastTarget.push(tableValue$1);
|
|
6516
|
+
return tableValue$1;
|
|
6517
|
+
}
|
|
6518
|
+
const tableValue = {};
|
|
6519
|
+
target[lastKey] = [tableValue];
|
|
6520
|
+
return tableValue;
|
|
6521
|
+
function getNextTargetFromKey(currTarget, key) {
|
|
6522
|
+
const nextTarget = currTarget[key];
|
|
6523
|
+
if (nextTarget == null) {
|
|
6524
|
+
const val = {};
|
|
6525
|
+
currTarget[key] = val;
|
|
6526
|
+
return val;
|
|
6527
|
+
}
|
|
6528
|
+
if (isValue(nextTarget)) {
|
|
6529
|
+
const val = {};
|
|
6530
|
+
currTarget[key] = val;
|
|
6531
|
+
return val;
|
|
6532
|
+
}
|
|
6533
|
+
let resultTarget = nextTarget;
|
|
6534
|
+
while (Array.isArray(resultTarget)) {
|
|
6535
|
+
const lastIndex = resultTarget.length - 1;
|
|
6536
|
+
const nextElement = resultTarget[lastIndex];
|
|
6537
|
+
if (isValue(nextElement)) {
|
|
6538
|
+
const val = {};
|
|
6539
|
+
resultTarget[lastIndex] = val;
|
|
6540
|
+
return val;
|
|
6541
|
+
}
|
|
6542
|
+
resultTarget = nextElement;
|
|
6543
|
+
}
|
|
6544
|
+
return resultTarget;
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
function set(baseTable, keys, value) {
|
|
6548
|
+
let target = baseTable;
|
|
6549
|
+
for (let index = 0; index < keys.length - 1; index++) {
|
|
6550
|
+
const key = keys[index];
|
|
6551
|
+
const nextTarget = target[key];
|
|
6552
|
+
if (nextTarget == null) {
|
|
6553
|
+
const val = {};
|
|
6554
|
+
target[key] = val;
|
|
6555
|
+
target = val;
|
|
6556
|
+
} else if (isValue(nextTarget) || Array.isArray(nextTarget)) {
|
|
6557
|
+
const val = {};
|
|
6558
|
+
target[key] = val;
|
|
6559
|
+
target = val;
|
|
6560
|
+
} else target = nextTarget;
|
|
6561
|
+
}
|
|
6562
|
+
target[last(keys)] = value;
|
|
6563
|
+
}
|
|
6564
|
+
function isValue(value) {
|
|
6565
|
+
return typeof value !== "object" || value instanceof Date;
|
|
6566
|
+
}
|
|
6567
|
+
function parseTOML(code, options) {
|
|
6568
|
+
return parseForESLint(code, options).ast;
|
|
6569
|
+
}
|
|
6570
|
+
|
|
6571
|
+
// src/core/ops/atomic-file.ts
|
|
6572
|
+
import { mkdirSync as mkdirSync2, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6573
|
+
import path2 from "node:path";
|
|
6574
|
+
function sleepSync(ms) {
|
|
6575
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
6576
|
+
}
|
|
6577
|
+
function errCode(e) {
|
|
6578
|
+
return e.code;
|
|
6579
|
+
}
|
|
6580
|
+
function renameWithRetry(from, to, opts = {}) {
|
|
6581
|
+
const rename = opts.rename ?? renameSync;
|
|
6582
|
+
const sleep = opts.sleep ?? sleepSync;
|
|
6583
|
+
const win = (opts.platform ?? process.platform) === "win32";
|
|
6584
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
6585
|
+
try {
|
|
6586
|
+
rename(from, to);
|
|
6587
|
+
return;
|
|
6588
|
+
} catch (e) {
|
|
6589
|
+
const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
6590
|
+
if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw e;
|
|
6591
|
+
sleep(ATOMIC_RENAME_DELAY_MS);
|
|
6592
|
+
}
|
|
6593
|
+
}
|
|
6594
|
+
}
|
|
6595
|
+
function unlinkWithRetry(file, opts = {}) {
|
|
6596
|
+
const unlink = opts.unlink ?? unlinkSync;
|
|
6597
|
+
const sleep = opts.sleep ?? sleepSync;
|
|
6598
|
+
const win = (opts.platform ?? process.platform) === "win32";
|
|
6599
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
6600
|
+
try {
|
|
6601
|
+
unlink(file);
|
|
6602
|
+
return;
|
|
6603
|
+
} catch (e) {
|
|
6604
|
+
if (errCode(e) === "ENOENT") return;
|
|
6605
|
+
const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
6606
|
+
if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw replaceFailure(file, e);
|
|
6607
|
+
sleep(ATOMIC_RENAME_DELAY_MS);
|
|
6608
|
+
}
|
|
6609
|
+
}
|
|
6610
|
+
}
|
|
6611
|
+
function replaceFailure(file, e) {
|
|
6612
|
+
const busy = ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
6613
|
+
const cause = e.message;
|
|
6614
|
+
return new Error(busy ? `Could not replace ${file}: ${cause}. Fix: close the program using ${file}, then re-run` : `Could not write ${file}: ${cause}. Fix: check the path and its permissions, then re-run`, { cause: e });
|
|
6615
|
+
}
|
|
6616
|
+
function removeTmpFile(tmp, opts = {}) {
|
|
6617
|
+
try {
|
|
6618
|
+
unlinkWithRetry(tmp, opts);
|
|
6619
|
+
} catch {
|
|
4702
6620
|
}
|
|
4703
|
-
|
|
4704
|
-
|
|
6621
|
+
}
|
|
6622
|
+
function atomicWriteFile(file, text2, opts = {}) {
|
|
6623
|
+
mkdirSync2(path2.dirname(file), { recursive: true });
|
|
6624
|
+
const tmp = path2.join(path2.dirname(file), `${ATOMIC_TMP_PREFIX}${path2.basename(file)}${ATOMIC_TMP_MARK}${process.pid}`);
|
|
6625
|
+
try {
|
|
6626
|
+
writeFileSync(tmp, text2);
|
|
6627
|
+
renameWithRetry(tmp, file, opts);
|
|
6628
|
+
} catch (e) {
|
|
6629
|
+
removeTmpFile(tmp, opts);
|
|
6630
|
+
throw replaceFailure(file, e);
|
|
6631
|
+
}
|
|
6632
|
+
}
|
|
6633
|
+
|
|
6634
|
+
// src/core/ops/host-text.ts
|
|
6635
|
+
var BOM_CODE = 65279;
|
|
6636
|
+
var CR_CODE = 13;
|
|
6637
|
+
var CRLF = "\r\n";
|
|
6638
|
+
var LF = "\n";
|
|
6639
|
+
function hostLayout(raw) {
|
|
6640
|
+
let crlf = 0;
|
|
6641
|
+
let lf = 0;
|
|
6642
|
+
for (let i2 = raw.indexOf(LF); i2 >= 0; i2 = raw.indexOf(LF, i2 + 1)) {
|
|
6643
|
+
if (i2 > 0 && raw.charCodeAt(i2 - 1) === CR_CODE) crlf += 1;
|
|
6644
|
+
else lf += 1;
|
|
6645
|
+
}
|
|
6646
|
+
return { bom: raw.length > 0 && raw.charCodeAt(0) === BOM_CODE, crlf: crlf > 0 && crlf >= lf };
|
|
6647
|
+
}
|
|
6648
|
+
function hostText(raw) {
|
|
6649
|
+
const bare = raw.length > 0 && raw.charCodeAt(0) === BOM_CODE ? raw.slice(1) : raw;
|
|
6650
|
+
return bare.indexOf(CRLF) < 0 ? bare : bare.split(CRLF).join(LF);
|
|
6651
|
+
}
|
|
6652
|
+
function withLayout(text2, layout) {
|
|
6653
|
+
const eol = layout.crlf ? text2.split(LF).join(CRLF) : text2;
|
|
6654
|
+
return layout.bom ? String.fromCharCode(BOM_CODE) + eol : eol;
|
|
4705
6655
|
}
|
|
4706
6656
|
|
|
4707
6657
|
// src/core/ops/host-config.ts
|
|
4708
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, renameSync, writeFileSync } from "node:fs";
|
|
4709
|
-
import { dirname as dirname2, join as join4 } from "node:path";
|
|
4710
6658
|
function stripJsonComments(text2) {
|
|
4711
6659
|
let out2 = "";
|
|
4712
6660
|
let i2 = 0;
|
|
@@ -4839,171 +6787,63 @@ function scanJson(text2, format) {
|
|
|
4839
6787
|
if (sc.i !== clean.length) sc.fail();
|
|
4840
6788
|
return { clean, root, value };
|
|
4841
6789
|
}
|
|
4842
|
-
function
|
|
4843
|
-
|
|
4844
|
-
let i2 = 0;
|
|
4845
|
-
for (; ; ) {
|
|
4846
|
-
while (s[i2] === " " || s[i2] === " ") i2 += 1;
|
|
4847
|
-
let seg = "";
|
|
4848
|
-
if (s[i2] === '"' || s[i2] === "'") {
|
|
4849
|
-
const q = s[i2];
|
|
4850
|
-
let j2 = i2 + 1;
|
|
4851
|
-
while (j2 < s.length && s[j2] !== q) j2 += q === '"' && s[j2] === "\\" ? 2 : 1;
|
|
4852
|
-
if (j2 >= s.length) throw new SyntaxError("key");
|
|
4853
|
-
seg = q === '"' ? JSON.parse(s.slice(i2, j2 + 1)) : s.slice(i2 + 1, j2);
|
|
4854
|
-
i2 = j2 + 1;
|
|
4855
|
-
} else {
|
|
4856
|
-
while (i2 < s.length && !" .".includes(s[i2])) {
|
|
4857
|
-
seg += s[i2];
|
|
4858
|
-
i2 += 1;
|
|
4859
|
-
}
|
|
4860
|
-
if (seg === "") throw new SyntaxError("key");
|
|
4861
|
-
}
|
|
4862
|
-
out2.push(seg);
|
|
4863
|
-
while (s[i2] === " " || s[i2] === " ") i2 += 1;
|
|
4864
|
-
if (i2 >= s.length) return out2;
|
|
4865
|
-
if (s[i2] !== ".") throw new SyntaxError("key");
|
|
4866
|
-
i2 += 1;
|
|
4867
|
-
}
|
|
6790
|
+
function keyNames(key) {
|
|
6791
|
+
return key.keys.map((k) => k.type === "TOMLBare" ? k.name : k.value);
|
|
4868
6792
|
}
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
if (this.s[this.i] !== "#") return;
|
|
4879
|
-
while (this.i < this.s.length && this.s[this.i] !== "\n") this.i += 1;
|
|
4880
|
-
}
|
|
4881
|
-
}
|
|
4882
|
-
read() {
|
|
4883
|
-
this.ws();
|
|
4884
|
-
const c3 = this.s[this.i];
|
|
4885
|
-
if (c3 === '"' || c3 === "'") {
|
|
4886
|
-
let j3 = this.i + 1;
|
|
4887
|
-
while (j3 < this.s.length && this.s[j3] !== c3 && this.s[j3] !== "\n") j3 += c3 === '"' && this.s[j3] === "\\" ? 2 : 1;
|
|
4888
|
-
if (this.s[j3] !== c3) throw new SyntaxError("string");
|
|
4889
|
-
const raw = this.s.slice(this.i, j3 + 1);
|
|
4890
|
-
this.i = j3 + 1;
|
|
4891
|
-
return c3 === '"' ? JSON.parse(raw) : raw.slice(1, -1);
|
|
4892
|
-
}
|
|
4893
|
-
if (c3 === "[") {
|
|
4894
|
-
this.i += 1;
|
|
4895
|
-
const out2 = [];
|
|
4896
|
-
for (; ; ) {
|
|
4897
|
-
this.ws();
|
|
4898
|
-
if (this.s[this.i] === "]") {
|
|
4899
|
-
this.i += 1;
|
|
4900
|
-
return out2;
|
|
4901
|
-
}
|
|
4902
|
-
out2.push(this.read());
|
|
4903
|
-
this.ws();
|
|
4904
|
-
if (this.s[this.i] === ",") {
|
|
4905
|
-
this.i += 1;
|
|
4906
|
-
continue;
|
|
4907
|
-
}
|
|
4908
|
-
if (this.s[this.i] !== "]") throw new SyntaxError("array");
|
|
4909
|
-
}
|
|
4910
|
-
}
|
|
4911
|
-
if (c3 === "{") {
|
|
4912
|
-
this.i += 1;
|
|
4913
|
-
const out2 = {};
|
|
4914
|
-
for (; ; ) {
|
|
4915
|
-
this.ws();
|
|
4916
|
-
if (this.s[this.i] === "}") {
|
|
4917
|
-
this.i += 1;
|
|
4918
|
-
return out2;
|
|
4919
|
-
}
|
|
4920
|
-
const eq = this.s.indexOf("=", this.i);
|
|
4921
|
-
if (eq < 0) throw new SyntaxError("inline table");
|
|
4922
|
-
const key = tomlKeyPath(this.s.slice(this.i, eq));
|
|
4923
|
-
this.i = eq + 1;
|
|
4924
|
-
setPath(out2, key, this.read());
|
|
4925
|
-
this.ws();
|
|
4926
|
-
if (this.s[this.i] === ",") {
|
|
4927
|
-
this.i += 1;
|
|
4928
|
-
continue;
|
|
4929
|
-
}
|
|
4930
|
-
if (this.s[this.i] !== "}") throw new SyntaxError("inline table");
|
|
4931
|
-
}
|
|
4932
|
-
}
|
|
4933
|
-
let j2 = this.i;
|
|
4934
|
-
while (j2 < this.s.length && !" \r\n,]}#".includes(this.s[j2])) j2 += 1;
|
|
4935
|
-
const word = this.s.slice(this.i, j2);
|
|
4936
|
-
this.i = j2;
|
|
4937
|
-
if (word === "true") return true;
|
|
4938
|
-
if (word === "false") return false;
|
|
4939
|
-
const n3 = Number(word.split("_").join(""));
|
|
4940
|
-
if (word === "" || Number.isNaN(n3)) throw new SyntaxError("value");
|
|
4941
|
-
return n3;
|
|
4942
|
-
}
|
|
4943
|
-
};
|
|
4944
|
-
function setPath(target, path8, value) {
|
|
4945
|
-
let cur = target;
|
|
4946
|
-
for (let k = 0; k < path8.length - 1; k += 1) {
|
|
4947
|
-
const next = cur[path8[k]];
|
|
4948
|
-
if (next === void 0) cur[path8[k]] = {};
|
|
4949
|
-
else if (!isPlainObject(next)) throw new SyntaxError("key conflict");
|
|
4950
|
-
cur = cur[path8[k]];
|
|
4951
|
-
}
|
|
4952
|
-
if (cur[path8[path8.length - 1]] !== void 0) throw new SyntaxError("duplicate key");
|
|
4953
|
-
cur[path8[path8.length - 1]] = value;
|
|
6793
|
+
function lineStartOf(text2, at) {
|
|
6794
|
+
return at === 0 ? 0 : text2.lastIndexOf("\n", at - 1) + 1;
|
|
6795
|
+
}
|
|
6796
|
+
function lineEndOf(text2, at) {
|
|
6797
|
+
const nl = text2.indexOf("\n", at);
|
|
6798
|
+
return nl < 0 ? text2.length : nl + 1;
|
|
6799
|
+
}
|
|
6800
|
+
function tomlValue(text2) {
|
|
6801
|
+
return getStaticTOMLValue(parseTOML(text2));
|
|
4954
6802
|
}
|
|
4955
6803
|
function scanToml(text2) {
|
|
4956
|
-
const
|
|
6804
|
+
const program = parseTOML(text2);
|
|
4957
6805
|
const tables = [];
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
if (
|
|
4964
|
-
|
|
4965
|
-
continue;
|
|
4966
|
-
}
|
|
4967
|
-
if (line.startsWith("[")) {
|
|
4968
|
-
if (line.startsWith("[[")) throw new SyntaxError("array of tables");
|
|
4969
|
-
const close = line.indexOf("]");
|
|
4970
|
-
if (close < 0) throw new SyntaxError("header");
|
|
4971
|
-
const path8 = tomlKeyPath(line.slice(1, close));
|
|
4972
|
-
if (tables.length > 0) tables[tables.length - 1].end = i2;
|
|
4973
|
-
tables.push({ path: path8, start: i2, end: text2.length });
|
|
4974
|
-
let cur = value;
|
|
4975
|
-
for (const seg of path8) {
|
|
4976
|
-
if (cur[seg] === void 0) cur[seg] = {};
|
|
4977
|
-
if (!isPlainObject(cur[seg])) throw new SyntaxError("table conflict");
|
|
4978
|
-
cur = cur[seg];
|
|
4979
|
-
}
|
|
4980
|
-
table2 = cur;
|
|
4981
|
-
i2 = lineEnd;
|
|
6806
|
+
const keys = [];
|
|
6807
|
+
const addKey = (base, kv) => {
|
|
6808
|
+
keys.push({ base, full: [...base, ...keyNames(kv.key)], start: kv.range[0], end: kv.range[1], inline: kv.value.type === "TOMLInlineTable" });
|
|
6809
|
+
};
|
|
6810
|
+
for (const node of program.body[0].body) {
|
|
6811
|
+
if (node.type === "TOMLKeyValue") {
|
|
6812
|
+
addKey([], node);
|
|
4982
6813
|
continue;
|
|
4983
6814
|
}
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
6815
|
+
if (!node.resolvedKey.every((seg) => typeof seg === "string")) continue;
|
|
6816
|
+
const path9 = node.resolvedKey;
|
|
6817
|
+
for (const kv of node.body) addKey(path9, kv);
|
|
6818
|
+
if (node.kind !== "standard") continue;
|
|
6819
|
+
const start = lineStartOf(text2, node.range[0]);
|
|
6820
|
+
const headEnd = lineEndOf(text2, node.key.range[1]);
|
|
6821
|
+
const last2 = node.body[node.body.length - 1];
|
|
6822
|
+
tables.push({
|
|
6823
|
+
path: path9,
|
|
6824
|
+
header: text2.slice(start, text2[headEnd - 1] === "\n" ? headEnd - 1 : headEnd),
|
|
6825
|
+
start,
|
|
6826
|
+
end: last2 === void 0 ? headEnd : lineEndOf(text2, last2.range[1])
|
|
6827
|
+
});
|
|
4994
6828
|
}
|
|
4995
|
-
return { value, tables };
|
|
6829
|
+
return { value: getStaticTOMLValue(program), tables, keys };
|
|
6830
|
+
}
|
|
6831
|
+
function tomlTableSpans(text2) {
|
|
6832
|
+
return scanToml(text2).tables;
|
|
6833
|
+
}
|
|
6834
|
+
function tomlHeaderText(path9) {
|
|
6835
|
+
return "[" + path9.map(tomlHeaderKey).join(".") + "]";
|
|
4996
6836
|
}
|
|
4997
|
-
function parseHostConfig(agent,
|
|
6837
|
+
function parseHostConfig(agent, path9, text2, format) {
|
|
4998
6838
|
try {
|
|
4999
6839
|
return format === "toml" ? scanToml(text2).value : scanJson(text2, format).value;
|
|
5000
6840
|
} catch {
|
|
5001
|
-
throw new CtxError("CONFIG_PARSE_FAILED", { agent, path:
|
|
6841
|
+
throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path9, format });
|
|
5002
6842
|
}
|
|
5003
6843
|
}
|
|
5004
|
-
function hostConfigValueAt(value,
|
|
6844
|
+
function hostConfigValueAt(value, path9) {
|
|
5005
6845
|
let cur = value;
|
|
5006
|
-
for (const seg of
|
|
6846
|
+
for (const seg of path9) {
|
|
5007
6847
|
if (!isPlainObject(cur)) return void 0;
|
|
5008
6848
|
cur = cur[seg];
|
|
5009
6849
|
}
|
|
@@ -5036,103 +6876,431 @@ function indentUnit(root, clean) {
|
|
|
5036
6876
|
function render(value, unit, base) {
|
|
5037
6877
|
return JSON.stringify(value, null, unit).split("\n").join("\n" + base);
|
|
5038
6878
|
}
|
|
5039
|
-
function nest(
|
|
5040
|
-
let out2 = value;
|
|
5041
|
-
for (let k =
|
|
5042
|
-
return out2;
|
|
6879
|
+
function nest(path9, value) {
|
|
6880
|
+
let out2 = value;
|
|
6881
|
+
for (let k = path9.length - 1; k >= 0; k -= 1) out2 = { [path9[k]]: out2 };
|
|
6882
|
+
return out2;
|
|
6883
|
+
}
|
|
6884
|
+
function setJsonText(text2, format, path9, value) {
|
|
6885
|
+
const doc = scanJson(text2, format);
|
|
6886
|
+
const unit = indentUnit(doc.root, doc.clean);
|
|
6887
|
+
if (doc.root === null) return render(nest(path9, value), unit, "") + "\n";
|
|
6888
|
+
let node = doc.root;
|
|
6889
|
+
let depth = 0;
|
|
6890
|
+
while (depth < path9.length && node.kind === "object") {
|
|
6891
|
+
const hit = node.members.find((m3) => m3.key === path9[depth]);
|
|
6892
|
+
if (hit === void 0) break;
|
|
6893
|
+
node = hit.node;
|
|
6894
|
+
depth += 1;
|
|
6895
|
+
}
|
|
6896
|
+
if (depth === path9.length) {
|
|
6897
|
+
return text2.slice(0, node.start) + render(value, unit, lineIndent(doc.clean, node.start)) + text2.slice(node.end);
|
|
6898
|
+
}
|
|
6899
|
+
if (node.kind !== "object") throw new SyntaxError("not an object at " + path9.slice(0, depth).join("."));
|
|
6900
|
+
const rest = nest(path9.slice(depth + 1), value);
|
|
6901
|
+
const last2 = node.members[node.members.length - 1];
|
|
6902
|
+
if (last2 === void 0) {
|
|
6903
|
+
const base2 = lineIndent(doc.clean, node.start);
|
|
6904
|
+
const member2 = "\n" + base2 + unit + JSON.stringify(path9[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
|
|
6905
|
+
return text2.slice(0, node.start + 1) + member2 + text2.slice(node.end - 1);
|
|
6906
|
+
}
|
|
6907
|
+
const base = lineIndent(doc.clean, last2.keyStart);
|
|
6908
|
+
let at = last2.node.end;
|
|
6909
|
+
while (" \r\n".includes(doc.clean[at])) at += 1;
|
|
6910
|
+
const trailing = doc.clean[at] === ",";
|
|
6911
|
+
const insertAt = trailing ? at + 1 : last2.node.end;
|
|
6912
|
+
const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path9[depth]) + ": " + render(rest, unit, base);
|
|
6913
|
+
return text2.slice(0, insertAt) + member + text2.slice(insertAt);
|
|
6914
|
+
}
|
|
6915
|
+
function tomlScalar(v) {
|
|
6916
|
+
if (Array.isArray(v)) return "[" + v.map(tomlScalar).join(", ") + "]";
|
|
6917
|
+
if (isPlainObject(v)) return "{ " + Object.entries(v).map(([k, x2]) => tomlHeaderKey(k) + " = " + tomlScalar(x2)).join(", ") + " }";
|
|
6918
|
+
if (typeof v === "string") return JSON.stringify(v);
|
|
6919
|
+
if (typeof v === "number" || typeof v === "boolean") return String(v);
|
|
6920
|
+
throw new SyntaxError("unsupported TOML value");
|
|
6921
|
+
}
|
|
6922
|
+
function tomlHeaderKey(seg) {
|
|
6923
|
+
if (seg === "") return '""';
|
|
6924
|
+
for (const ch of seg) {
|
|
6925
|
+
const bare = ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-";
|
|
6926
|
+
if (!bare) return JSON.stringify(seg);
|
|
6927
|
+
}
|
|
6928
|
+
return seg;
|
|
6929
|
+
}
|
|
6930
|
+
function tomlBlock(path9, value) {
|
|
6931
|
+
let out2 = "[" + path9.map(tomlHeaderKey).join(".") + "]\n";
|
|
6932
|
+
const subs = [];
|
|
6933
|
+
for (const [k, v] of Object.entries(value)) {
|
|
6934
|
+
if (isPlainObject(v)) subs.push(tomlBlock([...path9, k], v));
|
|
6935
|
+
else out2 += tomlHeaderKey(k) + " = " + tomlScalar(v) + "\n";
|
|
6936
|
+
}
|
|
6937
|
+
return [out2, ...subs].join("\n");
|
|
6938
|
+
}
|
|
6939
|
+
function under(path9, prefix) {
|
|
6940
|
+
return path9.length >= prefix.length && prefix.every((seg, k) => path9[k] === seg);
|
|
6941
|
+
}
|
|
6942
|
+
function keyLineRange(text2, k) {
|
|
6943
|
+
const ls = lineStartOf(text2, k.start);
|
|
6944
|
+
const le = lineEndOf(text2, k.end);
|
|
6945
|
+
const rest = text2.slice(k.end, le).trim();
|
|
6946
|
+
const alone = text2.slice(ls, k.start).trim() === "" && (rest === "" || rest.startsWith("#"));
|
|
6947
|
+
return alone ? [ls, le] : [k.start, k.end];
|
|
6948
|
+
}
|
|
6949
|
+
function withValueAt(root, rel, value) {
|
|
6950
|
+
if (rel.length === 0) return value;
|
|
6951
|
+
const base = isPlainObject(root) ? { ...root } : {};
|
|
6952
|
+
const next = withValueAt(base[rel[0]], rel.slice(1), value);
|
|
6953
|
+
if (next === void 0) delete base[rel[0]];
|
|
6954
|
+
else base[rel[0]] = next;
|
|
6955
|
+
return base;
|
|
6956
|
+
}
|
|
6957
|
+
function replaceToml(text2, doc, path9, value) {
|
|
6958
|
+
const block2 = value === void 0 ? "" : tomlBlock(path9, value);
|
|
6959
|
+
const owned = doc.tables.filter((t2) => under(t2.path, path9));
|
|
6960
|
+
const cuts = doc.keys.filter((k) => under(k.full, path9) && !under(k.base, path9)).map((k) => [...keyLineRange(text2, k), ""]);
|
|
6961
|
+
owned.forEach((t2, n3) => cuts.push([t2.start, t2.end, n3 === 0 ? block2 : ""]));
|
|
6962
|
+
cuts.sort((a2, b3) => b3[0] - a2[0]);
|
|
6963
|
+
let out2 = text2;
|
|
6964
|
+
for (const [s, e, put] of cuts) out2 = out2.slice(0, s) + put + out2.slice(e);
|
|
6965
|
+
if (owned.length > 0 || block2 === "") return out2;
|
|
6966
|
+
const sep = out2 === "" ? "" : out2.endsWith("\n\n") ? "" : out2.endsWith("\n") ? "\n" : "\n\n";
|
|
6967
|
+
return out2 + sep + block2;
|
|
6968
|
+
}
|
|
6969
|
+
var tableLike = (v) => v === void 0 || isPlainObject(v);
|
|
6970
|
+
function setTomlText(text2, path9, value) {
|
|
6971
|
+
if (value !== void 0 && !isPlainObject(value)) throw new SyntaxError("TOML edits replace a whole table");
|
|
6972
|
+
const doc = scanToml(text2);
|
|
6973
|
+
const cur = hostConfigValueAt(doc.value, path9);
|
|
6974
|
+
if (sameValue(cur, value)) return text2;
|
|
6975
|
+
const inline = doc.keys.find((k) => k.inline && k.full.length < path9.length && under(path9, k.full));
|
|
6976
|
+
if (inline !== void 0) {
|
|
6977
|
+
const whole = withValueAt(hostConfigValueAt(doc.value, inline.full), path9.slice(inline.full.length), value);
|
|
6978
|
+
return replaceToml(text2, doc, inline.full, whole);
|
|
6979
|
+
}
|
|
6980
|
+
if (isPlainObject(cur) && isPlainObject(value)) {
|
|
6981
|
+
const names = [.../* @__PURE__ */ new Set([...Object.keys(cur), ...Object.keys(value)])].filter((k) => !sameValue(cur[k], value[k]));
|
|
6982
|
+
if (names.every((k) => tableLike(cur[k]) && tableLike(value[k]))) {
|
|
6983
|
+
let out2 = text2;
|
|
6984
|
+
for (const k of names) out2 = setTomlText(out2, [...path9, k], value[k]);
|
|
6985
|
+
return out2;
|
|
6986
|
+
}
|
|
6987
|
+
}
|
|
6988
|
+
return replaceToml(text2, doc, path9, value);
|
|
6989
|
+
}
|
|
6990
|
+
function setText(agent, path9, text2, format, key, value) {
|
|
6991
|
+
try {
|
|
6992
|
+
if (format !== "toml") return setJsonText(text2, format, key, value);
|
|
6993
|
+
const out2 = setTomlText(text2, key, value);
|
|
6994
|
+
const landed = hostConfigValueAt(tomlValue(out2), key);
|
|
6995
|
+
const emptyTable = isPlainObject(value) && Object.keys(value).length === 0;
|
|
6996
|
+
if (!sameValue(landed, value) && !(emptyTable && landed === void 0)) throw new SyntaxError("edit did not land");
|
|
6997
|
+
return out2;
|
|
6998
|
+
} catch {
|
|
6999
|
+
throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path9, format });
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
7002
|
+
function applyEdits(agent, path9, text2, format, wanted) {
|
|
7003
|
+
const parsed = parseHostConfig(agent, path9, text2, format);
|
|
7004
|
+
let out2 = text2;
|
|
7005
|
+
const edits = [];
|
|
7006
|
+
for (const [key, after] of wanted) {
|
|
7007
|
+
const before = hostConfigValueAt(parsed, key);
|
|
7008
|
+
if (sameValue(before, after)) continue;
|
|
7009
|
+
out2 = setText(agent, path9, out2, format, key, after);
|
|
7010
|
+
edits.push({ path: key.join("."), before, after });
|
|
7011
|
+
}
|
|
7012
|
+
return { text: out2, format, edits };
|
|
7013
|
+
}
|
|
7014
|
+
function editHostConfigText(agent, path9, text2, format, wanted) {
|
|
7015
|
+
return applyEdits(agent, path9, text2, format, wanted);
|
|
7016
|
+
}
|
|
7017
|
+
|
|
7018
|
+
// src/core/ops/detect-v1.ts
|
|
7019
|
+
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
7020
|
+
var keyPath = (...parts) => parts.join(".");
|
|
7021
|
+
var finding = (file, path9, reason) => ({ file, path: path9, reason });
|
|
7022
|
+
function stripJsonc(text2) {
|
|
7023
|
+
let out2 = "";
|
|
7024
|
+
let inStr = false;
|
|
7025
|
+
let esc = false;
|
|
7026
|
+
for (let i2 = 0; i2 < text2.length; i2++) {
|
|
7027
|
+
const c3 = text2[i2];
|
|
7028
|
+
if (inStr) {
|
|
7029
|
+
out2 += c3;
|
|
7030
|
+
if (esc) esc = false;
|
|
7031
|
+
else if (c3 === "\\") esc = true;
|
|
7032
|
+
else if (c3 === '"') inStr = false;
|
|
7033
|
+
continue;
|
|
7034
|
+
}
|
|
7035
|
+
if (c3 === '"') {
|
|
7036
|
+
inStr = true;
|
|
7037
|
+
out2 += c3;
|
|
7038
|
+
continue;
|
|
7039
|
+
}
|
|
7040
|
+
if (c3 === "/" && text2[i2 + 1] === "/") {
|
|
7041
|
+
while (i2 < text2.length && text2[i2] !== "\n") i2++;
|
|
7042
|
+
out2 += "\n";
|
|
7043
|
+
continue;
|
|
7044
|
+
}
|
|
7045
|
+
if (c3 === "/" && text2[i2 + 1] === "*") {
|
|
7046
|
+
const end = text2.indexOf("*/", i2 + 2);
|
|
7047
|
+
i2 = end === -1 ? text2.length : end + 1;
|
|
7048
|
+
continue;
|
|
7049
|
+
}
|
|
7050
|
+
if (c3 === ",") {
|
|
7051
|
+
let j2 = i2 + 1;
|
|
7052
|
+
while (j2 < text2.length && " \r\n".includes(text2[j2])) j2++;
|
|
7053
|
+
if (text2[j2] === "}" || text2[j2] === "]") continue;
|
|
7054
|
+
}
|
|
7055
|
+
out2 += c3;
|
|
7056
|
+
}
|
|
7057
|
+
return out2;
|
|
7058
|
+
}
|
|
7059
|
+
function readJson(file) {
|
|
7060
|
+
try {
|
|
7061
|
+
return JSON.parse(stripJsonc(hostText(readFileSync2(file, "utf8"))));
|
|
7062
|
+
} catch {
|
|
7063
|
+
return void 0;
|
|
7064
|
+
}
|
|
7065
|
+
}
|
|
7066
|
+
function readText(file) {
|
|
7067
|
+
try {
|
|
7068
|
+
return hostText(readFileSync2(file, "utf8"));
|
|
7069
|
+
} catch {
|
|
7070
|
+
return "";
|
|
7071
|
+
}
|
|
7072
|
+
}
|
|
7073
|
+
function readTomlTables(file) {
|
|
7074
|
+
try {
|
|
7075
|
+
return tomlTableSpans(readText(file));
|
|
7076
|
+
} catch {
|
|
7077
|
+
return [];
|
|
7078
|
+
}
|
|
7079
|
+
}
|
|
7080
|
+
var listOf = (v) => Array.isArray(v) ? v : [];
|
|
7081
|
+
var commandOf = (v) => isObj(v) && typeof v.command === "string" ? v.command : null;
|
|
7082
|
+
function nestedCommands(doc) {
|
|
7083
|
+
const out2 = [];
|
|
7084
|
+
if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out2;
|
|
7085
|
+
for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
|
|
7086
|
+
listOf(groups).forEach((group2, i2) => {
|
|
7087
|
+
if (!isObj(group2)) return;
|
|
7088
|
+
listOf(group2[HOOKS_KEY]).forEach((inner, j2) => {
|
|
7089
|
+
const command = commandOf(inner);
|
|
7090
|
+
if (command !== null) out2.push({ path: keyPath(HOOKS_KEY, event, i2, HOOKS_KEY, j2), command });
|
|
7091
|
+
});
|
|
7092
|
+
});
|
|
7093
|
+
}
|
|
7094
|
+
return out2;
|
|
7095
|
+
}
|
|
7096
|
+
function flatCommands(events2, prefix) {
|
|
7097
|
+
const out2 = [];
|
|
7098
|
+
if (!isObj(events2)) return out2;
|
|
7099
|
+
for (const [event, entries] of Object.entries(events2)) {
|
|
7100
|
+
listOf(entries).forEach((entry2, i2) => {
|
|
7101
|
+
const command = commandOf(entry2);
|
|
7102
|
+
if (command !== null) out2.push({ path: keyPath(...prefix, event, i2), command });
|
|
7103
|
+
});
|
|
7104
|
+
}
|
|
7105
|
+
return out2;
|
|
7106
|
+
}
|
|
7107
|
+
var isV1Hook = (cmd) => cmd.includes(SERVER_KEY) && (V1_SCRIPT_NAMES.some((name) => cmd.includes(name)) || cmd.includes(V1_HOOK_COMMAND));
|
|
7108
|
+
var isCodexScript = (cmd) => cmd.includes(V1_SCRIPT_EXT) && V1_PATH_SEPS.some((sep) => cmd.includes(V1_CODEX_HOOKS_DIR.join(sep) + sep));
|
|
7109
|
+
function dataDir(dir, reason, out2) {
|
|
7110
|
+
if (existsSync3(dir)) out2.push(finding(dir, "", reason));
|
|
7111
|
+
}
|
|
7112
|
+
function mcpEntry(file, doc, out2) {
|
|
7113
|
+
if (isObj(doc) && isObj(doc[MCP_SERVERS_KEY]) && Object.hasOwn(doc[MCP_SERVERS_KEY], SERVER_KEY)) {
|
|
7114
|
+
out2.push(finding(file, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
|
|
7115
|
+
}
|
|
7116
|
+
}
|
|
7117
|
+
function claudeShapeSettings(agentHome, out2) {
|
|
7118
|
+
const file = join4(agentHome, SETTINGS_FILE);
|
|
7119
|
+
const doc = readJson(file);
|
|
7120
|
+
for (const c3 of nestedCommands(doc)) {
|
|
7121
|
+
if (c3.command.includes(V1_CACHE_HEAL_NAME)) out2.push(finding(file, c3.path, V1_REASON.cacheHealHook));
|
|
7122
|
+
else if (isV1Hook(c3.command)) out2.push(finding(file, c3.path, V1_REASON.hook));
|
|
7123
|
+
}
|
|
7124
|
+
const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
|
|
7125
|
+
if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
|
|
7126
|
+
out2.push(finding(file, STATUS_LINE_KEY, V1_REASON.statusLine));
|
|
7127
|
+
}
|
|
7128
|
+
mcpEntry(file, doc, out2);
|
|
7129
|
+
}
|
|
7130
|
+
function v1HookFile(file, out2) {
|
|
7131
|
+
const doc = readJson(file);
|
|
7132
|
+
const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
|
|
7133
|
+
if (cmds.some((c3) => c3.command.includes(V1_HOOK_COMMAND))) out2.push(finding(file, "", V1_REASON.hookFile));
|
|
7134
|
+
}
|
|
7135
|
+
function scanClaudeCode(home, agentHome, out2) {
|
|
7136
|
+
claudeShapeSettings(agentHome, out2);
|
|
7137
|
+
for (const ext of V1_CACHE_HEAL_EXTS) {
|
|
7138
|
+
const file = join4(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
|
|
7139
|
+
if (existsSync3(file)) out2.push(finding(file, "", V1_REASON.cacheHealFile));
|
|
7140
|
+
}
|
|
7141
|
+
const userFile = join4(home, CLAUDE_USER_CONFIG_FILE);
|
|
7142
|
+
mcpEntry(userFile, readJson(userFile), out2);
|
|
7143
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
7144
|
+
}
|
|
7145
|
+
function scanCodex(agentHome, out2) {
|
|
7146
|
+
const hooksFile = join4(agentHome, HOOKS_JSON_FILE);
|
|
7147
|
+
for (const c3 of nestedCommands(readJson(hooksFile))) {
|
|
7148
|
+
if (c3.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c3.command)) {
|
|
7149
|
+
out2.push(finding(hooksFile, c3.path, V1_REASON.codexHook));
|
|
7150
|
+
}
|
|
7151
|
+
}
|
|
7152
|
+
const tomlFile = join4(agentHome, CONFIG_TOML_FILE);
|
|
7153
|
+
for (const span of readTomlTables(tomlFile)) {
|
|
7154
|
+
if (tomlHeaderText(span.path).startsWith(V1_TOML_SECTION_PREFIX)) out2.push(finding(tomlFile, span.header.trim(), V1_REASON.codexToml));
|
|
7155
|
+
}
|
|
7156
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
7157
|
+
}
|
|
7158
|
+
function scanGemini(agentHome, out2) {
|
|
7159
|
+
const file = join4(agentHome, SETTINGS_FILE);
|
|
7160
|
+
for (const c3 of nestedCommands(readJson(file))) {
|
|
7161
|
+
if (c3.command.includes(SERVER_KEY)) out2.push(finding(file, c3.path, V1_REASON.hook));
|
|
7162
|
+
}
|
|
7163
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out2);
|
|
5043
7164
|
}
|
|
5044
|
-
function
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
7165
|
+
function scanVscode(agentHome, project, out2) {
|
|
7166
|
+
if (project !== void 0) {
|
|
7167
|
+
v1HookFile(join4(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out2);
|
|
7168
|
+
const mcpFile = join4(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
|
|
7169
|
+
const doc = readJson(mcpFile);
|
|
7170
|
+
const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
|
|
7171
|
+
const entry2 = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
|
|
7172
|
+
if (isObj(entry2) && (entry2.command === V1_BIN_COMMAND || listOf(entry2.args).some((a2) => a2 === V1_BIN_COMMAND))) {
|
|
7173
|
+
out2.push(finding(mcpFile, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
|
|
7174
|
+
}
|
|
7175
|
+
dataDir(join4(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out2);
|
|
5055
7176
|
}
|
|
5056
|
-
|
|
5057
|
-
|
|
7177
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out2);
|
|
7178
|
+
}
|
|
7179
|
+
function jsonFiles(dir) {
|
|
7180
|
+
try {
|
|
7181
|
+
return readdirSync2(dir).filter((name) => name.endsWith(KIRO_AGENT_FILE_EXT)).sort();
|
|
7182
|
+
} catch {
|
|
7183
|
+
return [];
|
|
5058
7184
|
}
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
const
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
const
|
|
5065
|
-
|
|
7185
|
+
}
|
|
7186
|
+
function scanKiro(agentHome, project, out2) {
|
|
7187
|
+
const agentsDir = join4(agentHome, KIRO_AGENTS_DIR);
|
|
7188
|
+
const defaultFile = join4(agentHome, ...KIRO_AGENT_FILE);
|
|
7189
|
+
for (const name of jsonFiles(agentsDir)) {
|
|
7190
|
+
const file = join4(agentsDir, name);
|
|
7191
|
+
const doc = readJson(file);
|
|
7192
|
+
if (isObj(doc) && doc[KIRO_AGENT_NAME_KEY] === SERVER_KEY) {
|
|
7193
|
+
out2.push(finding(file, "", V1_REASON.kiroAgentFile));
|
|
7194
|
+
continue;
|
|
7195
|
+
}
|
|
7196
|
+
if (file !== defaultFile) continue;
|
|
7197
|
+
for (const c3 of isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : []) {
|
|
7198
|
+
if (isV1Hook(c3.command)) out2.push(finding(file, c3.path, V1_REASON.kiroHook));
|
|
7199
|
+
}
|
|
5066
7200
|
}
|
|
5067
|
-
const
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
return text2.slice(0, insertAt) + member + text2.slice(insertAt);
|
|
7201
|
+
const steeringDocs = [join4(agentHome, ...KIRO_STEERING_FILE)];
|
|
7202
|
+
if (project !== void 0) steeringDocs.push(join4(project, ...AGENT_HOME_DIR.kiro, ...KIRO_STEERING_FILE));
|
|
7203
|
+
for (const file of steeringDocs) {
|
|
7204
|
+
if (existsSync3(file)) out2.push(finding(file, "", V1_REASON.kiroSteering));
|
|
7205
|
+
}
|
|
7206
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
5074
7207
|
}
|
|
5075
|
-
function
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
7208
|
+
function scanPi(piAgentDir, agentHome, out2) {
|
|
7209
|
+
const file = join4(piAgentDir, SETTINGS_FILE);
|
|
7210
|
+
const doc = readJson(file);
|
|
7211
|
+
listOf(isObj(doc) ? doc[PI_PACKAGES_KEY] : void 0).forEach((pkg, i2) => {
|
|
7212
|
+
const spec = isObj(pkg) ? pkg[PI_PACKAGE_SOURCE_KEY] : pkg;
|
|
7213
|
+
if (spec === V1_PI_PACKAGE) out2.push(finding(file, keyPath(PI_PACKAGES_KEY, i2), V1_REASON.piNpm));
|
|
7214
|
+
});
|
|
7215
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
5080
7216
|
}
|
|
5081
|
-
function
|
|
5082
|
-
for (const
|
|
5083
|
-
const
|
|
5084
|
-
|
|
7217
|
+
function scanOpencode(agentHome, out2) {
|
|
7218
|
+
for (const name of OPENCODE_CONFIG_FILES) {
|
|
7219
|
+
const file = join4(agentHome, name);
|
|
7220
|
+
const doc = readJson(file);
|
|
7221
|
+
if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
|
|
7222
|
+
doc[OPENCODE_PLUGIN_KEY].forEach((spec, i2) => {
|
|
7223
|
+
if (spec === V1_OPENCODE_PLUGIN_SPEC) out2.push(finding(file, keyPath(OPENCODE_PLUGIN_KEY, i2), V1_REASON.opencodePlugin));
|
|
7224
|
+
});
|
|
7225
|
+
return;
|
|
5085
7226
|
}
|
|
5086
|
-
return seg;
|
|
5087
7227
|
}
|
|
5088
|
-
function
|
|
5089
|
-
|
|
5090
|
-
const
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
7228
|
+
function scanZcode(agentHome, out2) {
|
|
7229
|
+
const configFile = join4(agentHome, ZCODE_CLI_DIR, CONFIG_JSON_FILE);
|
|
7230
|
+
const config = readJson(configFile);
|
|
7231
|
+
const events2 = isObj(config) && isObj(config[HOOKS_KEY]) ? config[HOOKS_KEY][ZCODE_EVENTS_KEY] : void 0;
|
|
7232
|
+
for (const c3 of flatCommands(events2, [HOOKS_KEY, ZCODE_EVENTS_KEY])) {
|
|
7233
|
+
if (c3.command.includes(V1_HOOK_COMMAND)) out2.push(finding(configFile, c3.path, V1_REASON.zcodeHook));
|
|
7234
|
+
}
|
|
7235
|
+
const hooksFile = join4(agentHome, ZCODE_CLI_DIR, HOOKS_JSON_FILE);
|
|
7236
|
+
for (const c3 of nestedCommands(readJson(hooksFile))) {
|
|
7237
|
+
if (c3.command.includes(V1_HOOK_COMMAND)) out2.push(finding(hooksFile, c3.path, V1_REASON.zcodeHook));
|
|
5094
7238
|
}
|
|
5095
|
-
return [out2, ...subs].join("\n");
|
|
5096
7239
|
}
|
|
5097
|
-
function
|
|
5098
|
-
|
|
5099
|
-
const doc = scanToml(text2);
|
|
5100
|
-
const owned = doc.tables.filter((t2) => t2.path.length >= path8.length && path8.every((seg, k) => t2.path[k] === seg));
|
|
5101
|
-
const block2 = tomlBlock(path8, value);
|
|
5102
|
-
if (owned.length === 0) {
|
|
5103
|
-
const sep = text2 === "" ? "" : text2.endsWith("\n\n") ? "" : text2.endsWith("\n") ? "\n" : "\n\n";
|
|
5104
|
-
return text2 + sep + block2;
|
|
5105
|
-
}
|
|
5106
|
-
let out2 = text2.slice(0, owned[0].start) + block2;
|
|
5107
|
-
let cursor3 = owned[0].end;
|
|
5108
|
-
for (const t2 of owned.slice(1)) {
|
|
5109
|
-
out2 += text2.slice(cursor3, t2.start).trim() === "" ? "" : text2.slice(cursor3, t2.start);
|
|
5110
|
-
cursor3 = t2.end;
|
|
5111
|
-
}
|
|
5112
|
-
const tail = text2.slice(cursor3);
|
|
5113
|
-
return out2 + (tail === "" || block2.endsWith("\n\n") ? "" : "\n") + tail;
|
|
5114
|
-
}
|
|
5115
|
-
function setText(agent, path8, text2, format, key, value) {
|
|
7240
|
+
function firstTmpMatch(dir) {
|
|
7241
|
+
let handle;
|
|
5116
7242
|
try {
|
|
5117
|
-
|
|
7243
|
+
handle = opendirSync(dir);
|
|
5118
7244
|
} catch {
|
|
5119
|
-
|
|
7245
|
+
return null;
|
|
5120
7246
|
}
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
edits.push({ path: key.join("."), before, after });
|
|
7247
|
+
try {
|
|
7248
|
+
for (let e = handle.readSync(); e !== null; e = handle.readSync()) {
|
|
7249
|
+
if (e.name.startsWith(V1_TMP_PREFIX)) return e.name;
|
|
7250
|
+
}
|
|
7251
|
+
return null;
|
|
7252
|
+
} catch {
|
|
7253
|
+
return null;
|
|
7254
|
+
} finally {
|
|
7255
|
+
handle.closeSync();
|
|
5131
7256
|
}
|
|
5132
|
-
return { text: out2, format, edits };
|
|
5133
7257
|
}
|
|
5134
|
-
function
|
|
5135
|
-
|
|
7258
|
+
function scanAll(home, tmp, out2) {
|
|
7259
|
+
const root = join4(home, DATA_ROOT.slice(1));
|
|
7260
|
+
for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join4(root, name), V1_REASON.dataRoot, out2);
|
|
7261
|
+
if (firstTmpMatch(tmp) !== null) out2.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
|
|
7262
|
+
}
|
|
7263
|
+
function detectV1(agent, home, scope = {}) {
|
|
7264
|
+
const out2 = [];
|
|
7265
|
+
const project = scope.project;
|
|
7266
|
+
const agentHome = agent === "claude-code" && scope.claudeDir !== void 0 ? scope.claudeDir : agent === "copilot-cli" && scope.copilotDir !== void 0 ? scope.copilotDir : agent === "kiro" && scope.kiroDir !== void 0 ? scope.kiroDir : agent === "opencode" && scope.opencodeDir !== void 0 ? scope.opencodeDir : join4(home, ...AGENT_HOME_DIR[agent]);
|
|
7267
|
+
switch (agent) {
|
|
7268
|
+
case "claude-code":
|
|
7269
|
+
scanClaudeCode(home, agentHome, out2);
|
|
7270
|
+
break;
|
|
7271
|
+
case "codex":
|
|
7272
|
+
scanCodex(agentHome, out2);
|
|
7273
|
+
break;
|
|
7274
|
+
case "gemini":
|
|
7275
|
+
scanGemini(agentHome, out2);
|
|
7276
|
+
break;
|
|
7277
|
+
case "qwen":
|
|
7278
|
+
claudeShapeSettings(agentHome, out2);
|
|
7279
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
7280
|
+
break;
|
|
7281
|
+
case "copilot-cli":
|
|
7282
|
+
v1HookFile(join4(agentHome, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out2);
|
|
7283
|
+
dataDir(join4(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out2);
|
|
7284
|
+
break;
|
|
7285
|
+
case "vscode":
|
|
7286
|
+
scanVscode(agentHome, project, out2);
|
|
7287
|
+
break;
|
|
7288
|
+
case "kiro":
|
|
7289
|
+
scanKiro(agentHome, project, out2);
|
|
7290
|
+
break;
|
|
7291
|
+
case "pi":
|
|
7292
|
+
scanPi(scope.piAgentDir !== void 0 && scope.piAgentDir !== "" ? scope.piAgentDir : join4(agentHome, PI_AGENT_DIR), agentHome, out2);
|
|
7293
|
+
break;
|
|
7294
|
+
// D-WIN-PIDIR-1: empty is unset
|
|
7295
|
+
case "opencode":
|
|
7296
|
+
scanOpencode(agentHome, out2);
|
|
7297
|
+
break;
|
|
7298
|
+
case "zcode":
|
|
7299
|
+
scanZcode(agentHome, out2);
|
|
7300
|
+
break;
|
|
7301
|
+
}
|
|
7302
|
+
scanAll(home, scope.tmp ?? tmpdir(), out2);
|
|
7303
|
+
return out2;
|
|
5136
7304
|
}
|
|
5137
7305
|
|
|
5138
7306
|
// src/core/ops/plugin-root.ts
|
|
@@ -5167,9 +7335,10 @@ function nestedShape(row, cmd, timeout, withMatcher) {
|
|
|
5167
7335
|
}
|
|
5168
7336
|
return { hooks };
|
|
5169
7337
|
}
|
|
7338
|
+
var POWERSHELL_CALL = "& ";
|
|
5170
7339
|
function flatShape(row, cmd, timeoutKey) {
|
|
5171
7340
|
const hooks = {};
|
|
5172
|
-
for (const [, native] of events(row)) hooks[native] = [{ ...entry(cmd), [timeoutKey]: seconds(row) }];
|
|
7341
|
+
for (const [, native] of events(row)) hooks[native] = [{ ...entry(cmd), powershell: POWERSHELL_CALL + cmd, [timeoutKey]: seconds(row) }];
|
|
5173
7342
|
return { version: 1, hooks };
|
|
5174
7343
|
}
|
|
5175
7344
|
function kiroShape(row, cmd) {
|
|
@@ -5229,11 +7398,17 @@ var OPENCODE_PLUGIN = ["opencode", "plugin.js"];
|
|
|
5229
7398
|
var CODEX_CONFIG_FILE = "config.toml";
|
|
5230
7399
|
var CODEX_HOME_ENV2 = "CODEX_HOME";
|
|
5231
7400
|
var CODEX_DIR = ".codex";
|
|
7401
|
+
var COPILOT_DIR = ".copilot";
|
|
7402
|
+
var KIRO_DIR = AGENT_HOME_DIR.kiro[0];
|
|
7403
|
+
var OPENCODE_HOME_SEGS = AGENT_HOME_DIR.opencode;
|
|
5232
7404
|
function agentPath(ctx, id, rel) {
|
|
5233
7405
|
const segs = typeof rel === "string" ? rel.split("/") : [...rel];
|
|
5234
7406
|
const codexHome = ctx.env[CODEX_HOME_ENV2];
|
|
5235
|
-
if (id === "codex" && segs[0] === CODEX_DIR && codexHome !== void 0 && codexHome !== "") return
|
|
5236
|
-
return
|
|
7407
|
+
if (id === "codex" && segs[0] === CODEX_DIR && codexHome !== void 0 && codexHome !== "") return path3.join(codexHome, ...segs.slice(1));
|
|
7408
|
+
if (id === "copilot-cli" && segs[0] === COPILOT_DIR) return path3.join(copilotDirOf(ctx.env, ctx.home), ...segs.slice(1));
|
|
7409
|
+
if (id === "kiro" && segs[0] === KIRO_DIR) return path3.join(kiroDirOf(ctx.env, ctx.home), ...segs.slice(1));
|
|
7410
|
+
if (id === "opencode" && segs[0] === OPENCODE_HOME_SEGS[0] && segs[1] === OPENCODE_HOME_SEGS[1]) return path3.join(opencodeDirOf(ctx.env, ctx.home), ...segs.slice(2));
|
|
7411
|
+
return path3.join(ctx.home, ...segs);
|
|
5237
7412
|
}
|
|
5238
7413
|
function renderSkill(text2, prefix) {
|
|
5239
7414
|
const prefixes = typeof prefix === "string" ? [prefix] : prefix;
|
|
@@ -5263,12 +7438,12 @@ function extensionPlugin(bin, id) {
|
|
|
5263
7438
|
};
|
|
5264
7439
|
}
|
|
5265
7440
|
var NATIVE_PLUGIN = {
|
|
5266
|
-
codex: { bin: "codex", args: ["plugin", "list"], plugin: PLUGIN_ID, hooksVia: ".codex-plugin", skillsVia:
|
|
7441
|
+
codex: { bin: "codex", args: ["plugin", "list"], plugin: PLUGIN_ID, hooksVia: ".codex-plugin", skillsVia: path3.join("codex", SKILLS_DIR_NAME), format: "table" },
|
|
5267
7442
|
qwen: extensionPlugin("qwen", "qwen"),
|
|
5268
7443
|
gemini: extensionPlugin("gemini", "gemini")
|
|
5269
7444
|
};
|
|
5270
7445
|
function serverCmd(ctx, id) {
|
|
5271
|
-
return [process.execPath,
|
|
7446
|
+
return [process.execPath, path3.join(ctx.pkgDir, SERVER_BUNDLE), AGENT_FLAG, id];
|
|
5272
7447
|
}
|
|
5273
7448
|
function hookCommandString(row) {
|
|
5274
7449
|
const [node, file, flag, id] = row.hookCommand ?? [];
|
|
@@ -5289,7 +7464,7 @@ function configFor(ctx, id) {
|
|
|
5289
7464
|
const [node, server, flag, agent] = serverCmd(ctx, id);
|
|
5290
7465
|
const own2 = OWN_MCP_ENTRY[id];
|
|
5291
7466
|
if (own2) {
|
|
5292
|
-
const file = agentPath(ctx, id, own2.file);
|
|
7467
|
+
const file = id === "vscode" ? ownMcpFileOf(id, own2.file, ctx.env, ctx.home) : agentPath(ctx, id, own2.file);
|
|
5293
7468
|
const format = file.endsWith(".toml") ? "toml" : id === "vscode" ? "jsonc" : "json";
|
|
5294
7469
|
const args = id === "vscode" ? [server, flag, agent, WORKSPACE_FOLDER_FLAG, VSCODE_WORKSPACE_VAR] : [server, flag, agent];
|
|
5295
7470
|
const also = own2.also?.map(([k, v]) => [k, v]);
|
|
@@ -5297,8 +7472,8 @@ function configFor(ctx, id) {
|
|
|
5297
7472
|
}
|
|
5298
7473
|
if (id === "opencode") {
|
|
5299
7474
|
return {
|
|
5300
|
-
file:
|
|
5301
|
-
format: "
|
|
7475
|
+
file: path3.join(opencodeDirOf(ctx.env, ctx.home), OPENCODE_BASE_CONFIG_FILE),
|
|
7476
|
+
format: "jsonc",
|
|
5302
7477
|
key: ["mcp", SERVER_KEY],
|
|
5303
7478
|
value: { type: "local", command: [node, server, flag, agent], enabled: true }
|
|
5304
7479
|
};
|
|
@@ -5326,7 +7501,7 @@ function cliFor(ctx, id) {
|
|
|
5326
7501
|
}
|
|
5327
7502
|
function copyFor(ctx, id) {
|
|
5328
7503
|
if (id !== "claude-code") return void 0;
|
|
5329
|
-
const file =
|
|
7504
|
+
const file = path3.join(claudeDirOf(ctx.env, ctx.home), HOST_PLUGINS_DIR_NAME, INSTALLED_PLUGINS_FILE);
|
|
5330
7505
|
return { host: "Claude Code", bin: "claude", plugin: PLUGIN_ID, file, refresh: ["plugin", "update", PLUGIN_ID] };
|
|
5331
7506
|
}
|
|
5332
7507
|
var LIST = {
|
|
@@ -5345,13 +7520,13 @@ function hookFilesFor(ctx, id) {
|
|
|
5345
7520
|
case "codex":
|
|
5346
7521
|
return [{ file: agentPath(ctx, id, [CODEX_DIR, "hooks.json"]), mode: "rewrite" }];
|
|
5347
7522
|
case "copilot-cli":
|
|
5348
|
-
return [{ file:
|
|
7523
|
+
return [{ file: agentPath(ctx, id, [COPILOT_DIR, "hooks", "context-mode.json"]), mode: "rewrite" }];
|
|
5349
7524
|
case "claude-code":
|
|
5350
|
-
return [{ file:
|
|
7525
|
+
return [{ file: path3.join(claudeDirOf(ctx.env, home), "settings.json"), mode: "drop" }];
|
|
5351
7526
|
case "gemini":
|
|
5352
|
-
return [{ file:
|
|
7527
|
+
return [{ file: path3.join(home, ".gemini", "settings.json"), mode: "drop" }];
|
|
5353
7528
|
case "qwen":
|
|
5354
|
-
return [{ file:
|
|
7529
|
+
return [{ file: path3.join(home, ".qwen", "settings.json"), mode: "drop" }];
|
|
5355
7530
|
default:
|
|
5356
7531
|
return [];
|
|
5357
7532
|
}
|
|
@@ -5362,15 +7537,15 @@ function hookInstallFor(ctx, row, command) {
|
|
|
5362
7537
|
const shape = HOOK_SHAPES[row.id];
|
|
5363
7538
|
if (!shape) throw new Error(`setup: ${row.id} has a home-file hook channel and no hook shape`);
|
|
5364
7539
|
const file = agentPath(ctx, row.id, ch.path);
|
|
5365
|
-
if (row.id === "codex") return { kind: "file", file, shape: shape(row, command), command, trust:
|
|
7540
|
+
if (row.id === "codex") return { kind: "file", file, shape: shape(row, command), command, trust: path3.join(path3.dirname(file), CODEX_CONFIG_FILE) };
|
|
5366
7541
|
return { kind: "file", file, shape: shape(row, command), command };
|
|
5367
7542
|
}
|
|
5368
7543
|
if (row.id === "opencode") {
|
|
5369
7544
|
return {
|
|
5370
7545
|
kind: "plugin-list",
|
|
5371
|
-
file:
|
|
7546
|
+
file: path3.join(opencodeDirOf(ctx.env, ctx.home), OPENCODE_BASE_CONFIG_FILE),
|
|
5372
7547
|
key: ["plugin"],
|
|
5373
|
-
entry:
|
|
7548
|
+
entry: path3.join(ctx.pkgDir, ...OPENCODE_PLUGIN)
|
|
5374
7549
|
};
|
|
5375
7550
|
}
|
|
5376
7551
|
return { kind: "package", via: ch.path };
|
|
@@ -5384,11 +7559,11 @@ function skillInstallFor(ctx, row) {
|
|
|
5384
7559
|
const ch = row.skillChannel;
|
|
5385
7560
|
if (ch.kind === "package") return { kind: "package", via: ch.path };
|
|
5386
7561
|
const dir = agentPath(ctx, row.id, ch.path);
|
|
5387
|
-
const src =
|
|
7562
|
+
const src = path3.join(ctx.pkgDir, bareSkillDir());
|
|
5388
7563
|
return { kind: "dir", dir, prefixes: skillDirPrefixes(ch.path), files: COMMAND_SKILLS.map((name) => ({
|
|
5389
7564
|
name,
|
|
5390
|
-
src:
|
|
5391
|
-
file:
|
|
7565
|
+
src: path3.join(src, name, SKILL_FILE),
|
|
7566
|
+
file: path3.join(dir, name, SKILL_FILE)
|
|
5392
7567
|
})) };
|
|
5393
7568
|
}
|
|
5394
7569
|
function buildRegistry(ctx) {
|
|
@@ -5396,7 +7571,7 @@ function buildRegistry(ctx) {
|
|
|
5396
7571
|
const id = row.id;
|
|
5397
7572
|
const config = configFor(ctx, id);
|
|
5398
7573
|
const hookFiles = hookFilesFor(ctx, id);
|
|
5399
|
-
const hookCommand = [process.execPath,
|
|
7574
|
+
const hookCommand = [process.execPath, path3.join(ctx.pkgDir, HOOK_BUNDLE), AGENT_FLAG, id];
|
|
5400
7575
|
const command = `"${hookCommand[0]}" "${hookCommand[1]}" ${AGENT_FLAG} ${id}`;
|
|
5401
7576
|
const hookInstall = hookInstallFor(ctx, getAdapter(id), command);
|
|
5402
7577
|
const skillInstall = skillInstallFor(ctx, row);
|
|
@@ -5418,7 +7593,7 @@ function buildRegistry(ctx) {
|
|
|
5418
7593
|
hookInstall,
|
|
5419
7594
|
skillInstall,
|
|
5420
7595
|
hookRunCommand: hookCommand,
|
|
5421
|
-
allowedWrites: [...new Set(writes.map((f2) =>
|
|
7596
|
+
allowedWrites: [...new Set(writes.map((f2) => path3.resolve(f2)))],
|
|
5422
7597
|
goldenPayload: golden(row, ctx.home)
|
|
5423
7598
|
};
|
|
5424
7599
|
if (row.installMode !== "in-process") out2.hookCommand = hookCommand;
|
|
@@ -5430,8 +7605,8 @@ function buildRegistry(ctx) {
|
|
|
5430
7605
|
});
|
|
5431
7606
|
}
|
|
5432
7607
|
function assertWritable(row, file) {
|
|
5433
|
-
const abs =
|
|
5434
|
-
if (INSTRUCTION_FILES.includes(
|
|
7608
|
+
const abs = path3.resolve(file);
|
|
7609
|
+
if (INSTRUCTION_FILES.includes(path3.basename(abs)) || !row.allowedWrites.includes(abs)) {
|
|
5435
7610
|
throw new Error(`setup: write to ${abs} is not allowed for ${row.id}`);
|
|
5436
7611
|
}
|
|
5437
7612
|
}
|
|
@@ -5439,7 +7614,91 @@ function assertWritable(row, file) {
|
|
|
5439
7614
|
// src/setup/codex-trust.ts
|
|
5440
7615
|
import { createHash } from "node:crypto";
|
|
5441
7616
|
import { existsSync as existsSync5, realpathSync as realpathSync3 } from "node:fs";
|
|
5442
|
-
import
|
|
7617
|
+
import path5 from "node:path";
|
|
7618
|
+
|
|
7619
|
+
// src/setup/spawn-bin.ts
|
|
7620
|
+
import { spawnSync } from "node:child_process";
|
|
7621
|
+
import { accessSync, constants as fsc, statSync } from "node:fs";
|
|
7622
|
+
import path4 from "node:path";
|
|
7623
|
+
|
|
7624
|
+
// src/core/sandbox/path-entries.ts
|
|
7625
|
+
function pathEntries(value, platform = process.platform, delimiter = platform === "win32" ? ";" : ":") {
|
|
7626
|
+
const win = platform === "win32";
|
|
7627
|
+
return value.split(delimiter).map((e) => win && e.length >= 2 && e.startsWith('"') && e.endsWith('"') ? e.slice(1, -1) : e).filter(Boolean);
|
|
7628
|
+
}
|
|
7629
|
+
|
|
7630
|
+
// src/setup/spawn-bin.ts
|
|
7631
|
+
var WIN_EXT = ".COM;.EXE;.BAT;.CMD";
|
|
7632
|
+
var WIN_SHIM_EXTS = Object.freeze([".cmd", ".bat"]);
|
|
7633
|
+
var DEFAULT_COMSPEC = "cmd.exe";
|
|
7634
|
+
function envGet(env, k) {
|
|
7635
|
+
return env[Object.keys(env).find((x2) => x2.toUpperCase() === k) ?? k];
|
|
7636
|
+
}
|
|
7637
|
+
function whichBin(bin, env, platform = process.platform) {
|
|
7638
|
+
const get = (k) => envGet(env, k);
|
|
7639
|
+
const win = platform === "win32";
|
|
7640
|
+
const exts = win ? (get("PATHEXT") || WIN_EXT).split(";").filter(Boolean) : [""];
|
|
7641
|
+
const names = win && path4.extname(bin) ? [bin] : exts.map((e) => bin + e.toLowerCase());
|
|
7642
|
+
for (const dir of pathEntries(get("PATH") ?? "", platform)) {
|
|
7643
|
+
for (const n3 of names) {
|
|
7644
|
+
const f2 = path4.join(dir, n3);
|
|
7645
|
+
try {
|
|
7646
|
+
accessSync(f2, fsc.X_OK);
|
|
7647
|
+
if (statSync(f2).isFile()) return f2;
|
|
7648
|
+
} catch {
|
|
7649
|
+
}
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
return void 0;
|
|
7653
|
+
}
|
|
7654
|
+
var CMD_QUOTE_CHARS = '"&|<>^()!';
|
|
7655
|
+
var CMD_PERCENT = "%";
|
|
7656
|
+
var CMD_SUBSTRING_MARK = ":";
|
|
7657
|
+
var CMD_DYNAMIC_VARS = Object.freeze(["CD", "DATE", "TIME", "RANDOM", "ERRORLEVEL", "CMDEXTVERSION", "CMDCMDLINE", "HIGHESTNUMANODENUMBER"]);
|
|
7658
|
+
function needsCmdQuotes(a2) {
|
|
7659
|
+
if (a2 === "") return true;
|
|
7660
|
+
for (const c3 of a2) if (c3.trim() === "" || CMD_QUOTE_CHARS.includes(c3)) return true;
|
|
7661
|
+
return false;
|
|
7662
|
+
}
|
|
7663
|
+
function expandablePercent(text2, env) {
|
|
7664
|
+
const names = new Set(CMD_DYNAMIC_VARS);
|
|
7665
|
+
for (const k of Object.keys(env)) names.add(k.toUpperCase());
|
|
7666
|
+
for (let i2 = text2.indexOf(CMD_PERCENT); i2 >= 0; i2 = text2.indexOf(CMD_PERCENT, i2 + 1)) {
|
|
7667
|
+
for (let j2 = text2.indexOf(CMD_PERCENT, i2 + 1); j2 >= 0; j2 = text2.indexOf(CMD_PERCENT, j2 + 1)) {
|
|
7668
|
+
const inner = text2.slice(i2 + 1, j2);
|
|
7669
|
+
const cut = inner.indexOf(CMD_SUBSTRING_MARK);
|
|
7670
|
+
const name = cut < 0 ? inner : inner.slice(0, cut);
|
|
7671
|
+
if (name !== "" && names.has(name.toUpperCase())) return `${CMD_PERCENT}${inner}${CMD_PERCENT}`;
|
|
7672
|
+
}
|
|
7673
|
+
}
|
|
7674
|
+
return void 0;
|
|
7675
|
+
}
|
|
7676
|
+
function winCmdLine(file, args, env = {}) {
|
|
7677
|
+
for (const a2 of [file, ...args]) {
|
|
7678
|
+
const hit = expandablePercent(a2, env);
|
|
7679
|
+
if (hit !== void 0) throw new Error(`cannot run ${file} through cmd.exe: cmd.exe expands ${hit} inside quotes, so the value ${JSON.stringify(a2)} would change. Use a path and arguments without it`);
|
|
7680
|
+
}
|
|
7681
|
+
const q = (a2) => needsCmdQuotes(a2) ? `"${a2.split('"').join('""')}"` : a2;
|
|
7682
|
+
return `"${[file, ...args].map(q).join(" ")}"`;
|
|
7683
|
+
}
|
|
7684
|
+
function spawnForm(file, args, env, platform = process.platform) {
|
|
7685
|
+
if (platform === "win32" && WIN_SHIM_EXTS.includes(path4.extname(file).toLowerCase())) {
|
|
7686
|
+
return { command: envGet(env, "COMSPEC") || DEFAULT_COMSPEC, args: ["/d", "/v:off", "/s", "/c", winCmdLine(file, args, env)], windowsVerbatimArguments: true };
|
|
7687
|
+
}
|
|
7688
|
+
return { command: file, args, windowsVerbatimArguments: false };
|
|
7689
|
+
}
|
|
7690
|
+
function spawnShim(file, args, env, opts, platform = process.platform) {
|
|
7691
|
+
let f2;
|
|
7692
|
+
try {
|
|
7693
|
+
f2 = spawnForm(file, args, env, platform);
|
|
7694
|
+
} catch (e) {
|
|
7695
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
7696
|
+
return { pid: 0, output: [null, "", error.message], stdout: "", stderr: error.message, status: null, signal: null, error };
|
|
7697
|
+
}
|
|
7698
|
+
return spawnSync(f2.command, f2.args, { ...opts, env, windowsVerbatimArguments: f2.windowsVerbatimArguments, windowsHide: true });
|
|
7699
|
+
}
|
|
7700
|
+
|
|
7701
|
+
// src/setup/codex-trust.ts
|
|
5443
7702
|
var isObj2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
5444
7703
|
var TRUST_KEY = ["hooks", "state"];
|
|
5445
7704
|
var CODEX_TRUST_PATH = TRUST_KEY.join(".") + ".";
|
|
@@ -5459,18 +7718,58 @@ function snake(name) {
|
|
|
5459
7718
|
return out2;
|
|
5460
7719
|
}
|
|
5461
7720
|
function realFile(file) {
|
|
5462
|
-
let dir =
|
|
7721
|
+
let dir = path5.resolve(file);
|
|
5463
7722
|
const rest = [];
|
|
5464
|
-
while (!existsSync5(dir) &&
|
|
5465
|
-
rest.unshift(
|
|
5466
|
-
dir =
|
|
7723
|
+
while (!existsSync5(dir) && path5.dirname(dir) !== dir) {
|
|
7724
|
+
rest.unshift(path5.basename(dir));
|
|
7725
|
+
dir = path5.dirname(dir);
|
|
7726
|
+
}
|
|
7727
|
+
return path5.join(realpathSync3(dir), ...rest);
|
|
7728
|
+
}
|
|
7729
|
+
var ASK_TIMEOUT_MS = 1e4;
|
|
7730
|
+
var ASK_TRIES = 3;
|
|
7731
|
+
var WIN_VERBATIM_PREFIX = "\\\\?\\";
|
|
7732
|
+
function codexHomeFromReply(out2) {
|
|
7733
|
+
for (const line of out2.split("\n")) {
|
|
7734
|
+
let m3;
|
|
7735
|
+
try {
|
|
7736
|
+
m3 = JSON.parse(line);
|
|
7737
|
+
} catch {
|
|
7738
|
+
continue;
|
|
7739
|
+
}
|
|
7740
|
+
if (isObj2(m3) && isObj2(m3.result) && typeof m3.result.codexHome === "string" && m3.result.codexHome !== "") return m3.result.codexHome;
|
|
7741
|
+
}
|
|
7742
|
+
return void 0;
|
|
7743
|
+
}
|
|
7744
|
+
function askCodexHome(env) {
|
|
7745
|
+
const bin = whichBin("codex", env);
|
|
7746
|
+
if (!bin) return void 0;
|
|
7747
|
+
const input = JSON.stringify({ id: 1, method: "initialize", params: { clientInfo: { name: "context-mode-setup", version: "2.0.0" } } }) + "\n";
|
|
7748
|
+
for (let i2 = 0; i2 < ASK_TRIES; i2++) {
|
|
7749
|
+
const r2 = spawnShim(bin, ["app-server"], env, { input, encoding: "utf8", timeout: ASK_TIMEOUT_MS });
|
|
7750
|
+
const home = typeof r2.stdout === "string" ? codexHomeFromReply(r2.stdout) : void 0;
|
|
7751
|
+
if (home !== void 0) return home;
|
|
5467
7752
|
}
|
|
5468
|
-
return
|
|
7753
|
+
return void 0;
|
|
7754
|
+
}
|
|
7755
|
+
function sameDir(a2, b3, platform) {
|
|
7756
|
+
if (platform !== "win32") return path5.posix.normalize(a2) === path5.posix.normalize(b3);
|
|
7757
|
+
const norm = (p3) => {
|
|
7758
|
+
const bare = p3.startsWith(WIN_VERBATIM_PREFIX) ? p3.slice(WIN_VERBATIM_PREFIX.length) : p3;
|
|
7759
|
+
const n3 = path5.win32.normalize(bare).toLowerCase();
|
|
7760
|
+
return n3.length > 3 && n3.endsWith("\\") ? n3.slice(0, -1) : n3;
|
|
7761
|
+
};
|
|
7762
|
+
return norm(a2) === norm(b3);
|
|
7763
|
+
}
|
|
7764
|
+
function codexKeyDir(o2, platform = process.platform) {
|
|
7765
|
+
return o2.asked !== void 0 && sameDir(o2.dir, o2.asked, platform) ? o2.asked : o2.real(o2.dir);
|
|
5469
7766
|
}
|
|
5470
|
-
function codexTrustEntries(hooksFile, doc, command) {
|
|
7767
|
+
function codexTrustEntries(hooksFile, doc, command, env) {
|
|
5471
7768
|
const out2 = [];
|
|
5472
7769
|
if (!isObj2(doc) || !isObj2(doc.hooks)) return out2;
|
|
5473
|
-
const
|
|
7770
|
+
const abs = path5.resolve(hooksFile);
|
|
7771
|
+
const dir = codexKeyDir({ dir: path5.dirname(abs), asked: env ? askCodexHome(env) : void 0, real: env && !env.CODEX_HOME ? (p3) => path5.resolve(p3) : realFile });
|
|
7772
|
+
const real = (dir.startsWith(WIN_VERBATIM_PREFIX) ? path5.win32 : path5).join(dir, path5.basename(abs));
|
|
5474
7773
|
for (const [event, groups] of Object.entries(doc.hooks)) {
|
|
5475
7774
|
if (!Array.isArray(groups)) continue;
|
|
5476
7775
|
groups.forEach((g2, gi) => {
|
|
@@ -5488,47 +7787,10 @@ function codexTrustEntries(hooksFile, doc, command) {
|
|
|
5488
7787
|
}
|
|
5489
7788
|
|
|
5490
7789
|
// src/setup/engine.ts
|
|
5491
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
5492
|
-
import { closeSync, existsSync as existsSync6, mkdirSync as
|
|
7790
|
+
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
7791
|
+
import { closeSync, existsSync as existsSync6, mkdirSync as mkdirSync3, mkdtempSync, openSync, readFileSync as readFileSync3, readSync, readdirSync as readdirSync4, realpathSync as realpathSync4, rmSync, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
5493
7792
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
5494
|
-
import
|
|
5495
|
-
|
|
5496
|
-
// src/setup/spawn-bin.ts
|
|
5497
|
-
import { accessSync, constants as fsc, statSync } from "node:fs";
|
|
5498
|
-
import path4 from "node:path";
|
|
5499
|
-
var WIN_EXT = ".COM;.EXE;.BAT;.CMD";
|
|
5500
|
-
var WIN_SHIM_EXTS = Object.freeze([".cmd", ".bat"]);
|
|
5501
|
-
var DEFAULT_COMSPEC = "cmd.exe";
|
|
5502
|
-
function envGet(env, k) {
|
|
5503
|
-
return env[Object.keys(env).find((x2) => x2.toUpperCase() === k) ?? k];
|
|
5504
|
-
}
|
|
5505
|
-
function whichBin(bin, env, platform = process.platform) {
|
|
5506
|
-
const get = (k) => envGet(env, k);
|
|
5507
|
-
const win = platform === "win32";
|
|
5508
|
-
const exts = win ? (get("PATHEXT") || WIN_EXT).split(";").filter(Boolean) : [""];
|
|
5509
|
-
const names = win && path4.extname(bin) ? [bin] : exts.map((e) => bin + e.toLowerCase());
|
|
5510
|
-
for (const dir of (get("PATH") ?? "").split(win ? ";" : ":").filter(Boolean)) {
|
|
5511
|
-
for (const n3 of names) {
|
|
5512
|
-
const f2 = path4.join(dir, n3);
|
|
5513
|
-
try {
|
|
5514
|
-
accessSync(f2, fsc.X_OK);
|
|
5515
|
-
if (statSync(f2).isFile()) return f2;
|
|
5516
|
-
} catch {
|
|
5517
|
-
}
|
|
5518
|
-
}
|
|
5519
|
-
}
|
|
5520
|
-
return void 0;
|
|
5521
|
-
}
|
|
5522
|
-
function winCmdLine(file, args) {
|
|
5523
|
-
const q = (a2) => a2 === "" || /[\s"&|<>^()%!]/.test(a2) ? `"${a2.replace(/"/g, '""')}"` : a2;
|
|
5524
|
-
return `"${[file, ...args].map(q).join(" ")}"`;
|
|
5525
|
-
}
|
|
5526
|
-
function spawnForm(file, args, env, platform = process.platform) {
|
|
5527
|
-
if (platform === "win32" && WIN_SHIM_EXTS.includes(path4.extname(file).toLowerCase())) {
|
|
5528
|
-
return { command: envGet(env, "COMSPEC") || DEFAULT_COMSPEC, args: ["/d", "/s", "/c", winCmdLine(file, args)], windowsVerbatimArguments: true };
|
|
5529
|
-
}
|
|
5530
|
-
return { command: file, args, windowsVerbatimArguments: false };
|
|
5531
|
-
}
|
|
7793
|
+
import path6 from "node:path";
|
|
5532
7794
|
|
|
5533
7795
|
// src/setup/hook-sample.ts
|
|
5534
7796
|
var SAMPLE_FILE = "big.log";
|
|
@@ -5621,16 +7883,16 @@ function isNativeBinary(file) {
|
|
|
5621
7883
|
return BINARY_MAGICS.some((m3) => hex.startsWith(m3));
|
|
5622
7884
|
}
|
|
5623
7885
|
function owningPackage(dir) {
|
|
5624
|
-
for (let d = dir; ; d =
|
|
5625
|
-
const f2 =
|
|
7886
|
+
for (let d = dir; ; d = path6.dirname(d)) {
|
|
7887
|
+
const f2 = path6.join(d, "package.json");
|
|
5626
7888
|
if (existsSync6(f2)) {
|
|
5627
7889
|
try {
|
|
5628
|
-
return String(JSON.parse(readFileSync3(f2, "utf8")).name);
|
|
7890
|
+
return String(JSON.parse(hostText(readFileSync3(f2, "utf8"))).name);
|
|
5629
7891
|
} catch {
|
|
5630
7892
|
return void 0;
|
|
5631
7893
|
}
|
|
5632
7894
|
}
|
|
5633
|
-
if (
|
|
7895
|
+
if (path6.dirname(d) === d) return void 0;
|
|
5634
7896
|
}
|
|
5635
7897
|
}
|
|
5636
7898
|
function hostBin(bin, env, platform = process.platform) {
|
|
@@ -5638,30 +7900,32 @@ function hostBin(bin, env, platform = process.platform) {
|
|
|
5638
7900
|
if (!real) return { file: which(bin, env, platform), shims: [] };
|
|
5639
7901
|
const get = (k) => env[Object.keys(env).find((x2) => x2.toUpperCase() === k) ?? k];
|
|
5640
7902
|
const shims = [];
|
|
5641
|
-
for (const dir of (get("PATH") ?? ""
|
|
7903
|
+
for (const dir of pathEntries(get("PATH") ?? "", platform)) {
|
|
5642
7904
|
const own2 = which(bin, { PATH: dir, ...get("PATHEXT") ? { PATHEXT: get("PATHEXT") } : {} }, platform);
|
|
5643
|
-
for (const f2 of [own2, ...real.extra.map((p3) =>
|
|
7905
|
+
for (const f2 of [own2, ...real.extra.map((p3) => path6.join(dir, ...p3))]) {
|
|
5644
7906
|
if (!f2 || !existsSync6(f2) || !statSync2(f2).isFile()) continue;
|
|
5645
7907
|
const file = realpathSync4(f2);
|
|
5646
|
-
if (isNativeBinary(file) || owningPackage(
|
|
7908
|
+
if (isNativeBinary(file) || owningPackage(path6.dirname(file)) === real.pkg) return { file, shims };
|
|
5647
7909
|
shims.push(f2);
|
|
5648
7910
|
}
|
|
5649
7911
|
}
|
|
5650
7912
|
return { file: void 0, shims };
|
|
5651
7913
|
}
|
|
7914
|
+
var WIN_EXIT_CRASH = 3221226505;
|
|
7915
|
+
function installExitOk(status, listed, platform = process.platform) {
|
|
7916
|
+
if (status === 0) return true;
|
|
7917
|
+
return platform === "win32" && status === WIN_EXIT_CRASH && listed;
|
|
7918
|
+
}
|
|
5652
7919
|
function runBin(bin, args, env, input) {
|
|
5653
|
-
|
|
5654
|
-
return spawnSync(f2.command, f2.args, { env, encoding: "utf8", input, timeout: VERIFY_TIMEOUT_MS, windowsVerbatimArguments: f2.windowsVerbatimArguments, windowsHide: true });
|
|
7920
|
+
return spawnShim(hostBin(bin, env).file ?? bin, args, env, { encoding: "utf8", input, timeout: VERIFY_TIMEOUT_MS });
|
|
5655
7921
|
}
|
|
5656
7922
|
function readOr(file) {
|
|
5657
|
-
return existsSync6(file) ? readFileSync3(file, "utf8") : void 0;
|
|
7923
|
+
return existsSync6(file) ? hostText(readFileSync3(file, "utf8")) : void 0;
|
|
5658
7924
|
}
|
|
5659
|
-
function
|
|
5660
|
-
|
|
5661
|
-
const tmp = path5.join(path5.dirname(file), `.${path5.basename(file)}.cm-tmp-${process.pid}`);
|
|
5662
|
-
writeFileSync2(tmp, text2);
|
|
5663
|
-
renameSync2(tmp, file);
|
|
7925
|
+
function readRaw(file) {
|
|
7926
|
+
return existsSync6(file) ? readFileSync3(file, "utf8") : void 0;
|
|
5664
7927
|
}
|
|
7928
|
+
var atomicWrite = atomicWriteFile;
|
|
5665
7929
|
function pidAlive(pid) {
|
|
5666
7930
|
try {
|
|
5667
7931
|
process.kill(pid, 0);
|
|
@@ -5693,7 +7957,20 @@ function planHookFile(row, hf) {
|
|
|
5693
7957
|
for (const [event, groups] of Object.entries(doc.hooks)) {
|
|
5694
7958
|
if (!Array.isArray(groups)) continue;
|
|
5695
7959
|
for (let g2 = groups.length - 1; g2 >= 0; g2--) {
|
|
5696
|
-
const
|
|
7960
|
+
const group2 = groups[g2];
|
|
7961
|
+
if (isObj3(group2) && typeof group2.command === "string" && !Array.isArray(group2.hooks)) {
|
|
7962
|
+
if (!group2.command.includes(V1_HOOK_MARK)) continue;
|
|
7963
|
+
const at = `hooks.${event}[${g2}].command`;
|
|
7964
|
+
if (hf.mode === "rewrite") {
|
|
7965
|
+
changes.push({ file: hf.file, path: at, before: group2.command, after: want });
|
|
7966
|
+
group2.command = want;
|
|
7967
|
+
} else {
|
|
7968
|
+
changes.push({ file: hf.file, path: at, before: group2.command, after: null });
|
|
7969
|
+
groups.splice(g2, 1);
|
|
7970
|
+
}
|
|
7971
|
+
continue;
|
|
7972
|
+
}
|
|
7973
|
+
const list2 = isObj3(group2) ? group2.hooks : void 0;
|
|
5697
7974
|
if (!Array.isArray(list2)) continue;
|
|
5698
7975
|
for (let h2 = list2.length - 1; h2 >= 0; h2--) {
|
|
5699
7976
|
const cmd = isObj3(list2[h2]) ? list2[h2].command : void 0;
|
|
@@ -5712,28 +7989,38 @@ function planHookFile(row, hf) {
|
|
|
5712
7989
|
}
|
|
5713
7990
|
return changes.length ? { file: hf.file, before, after: JSON.stringify(doc, null, 2) + "\n", changes } : void 0;
|
|
5714
7991
|
}
|
|
5715
|
-
var
|
|
7992
|
+
var MARK_LEFT = ["/", "\\", '"'];
|
|
7993
|
+
function isOwnHookCommand(cmd, agent) {
|
|
7994
|
+
if (typeof cmd !== "string") return false;
|
|
7995
|
+
const at = cmd.lastIndexOf(HOOK_BUNDLE);
|
|
7996
|
+
if (at <= 0 || !MARK_LEFT.includes(cmd[at - 1])) return false;
|
|
7997
|
+
let tail = cmd.slice(at + HOOK_BUNDLE.length);
|
|
7998
|
+
if (tail.startsWith('"')) tail = tail.slice(1);
|
|
7999
|
+
return tail.trim() === `${AGENT_FLAG} ${agent}`;
|
|
8000
|
+
}
|
|
8001
|
+
var holdsOwn = (v, agent) => typeof v === "string" ? isOwnHookCommand(v, agent) : Array.isArray(v) ? v.some((x2) => holdsOwn(x2, agent)) : isObj3(v) ? Object.values(v).some((x2) => holdsOwn(x2, agent)) : false;
|
|
5716
8002
|
var same = (a2, b3) => JSON.stringify(a2) === JSON.stringify(b3);
|
|
5717
|
-
function mergeOwn(cur, want,
|
|
8003
|
+
function mergeOwn(cur, want, agent) {
|
|
5718
8004
|
if (isObj3(want)) {
|
|
5719
8005
|
const base = isObj3(cur) ? { ...cur } : {};
|
|
5720
|
-
for (const [k, v] of Object.entries(want)) base[k] = mergeOwn(base[k], v,
|
|
8006
|
+
for (const [k, v] of Object.entries(want)) base[k] = mergeOwn(base[k], v, agent);
|
|
5721
8007
|
return base;
|
|
5722
8008
|
}
|
|
5723
8009
|
if (Array.isArray(want)) {
|
|
5724
|
-
const base = Array.isArray(cur) ? cur.filter((x2) => !
|
|
8010
|
+
const base = Array.isArray(cur) ? cur.filter((x2) => !holdsOwn(x2, agent) || want.some((w) => same(w, x2))) : [];
|
|
5725
8011
|
for (const w of want) if (!base.some((x2) => same(x2, w))) base.push(w);
|
|
5726
8012
|
return base;
|
|
5727
8013
|
}
|
|
5728
8014
|
return want;
|
|
5729
8015
|
}
|
|
5730
|
-
|
|
8016
|
+
var fileFormat = (row, file) => row.config?.file === file ? row.config.format : "json";
|
|
8017
|
+
function planJsonKeys(row, edits, file, format, want) {
|
|
5731
8018
|
const prior = edits.find((e) => e.file === file);
|
|
5732
8019
|
const text2 = prior ? prior.after : readOr(file);
|
|
5733
8020
|
let doc = {};
|
|
5734
8021
|
if (text2 !== void 0 && text2.trim() !== "") {
|
|
5735
8022
|
try {
|
|
5736
|
-
doc =
|
|
8023
|
+
doc = parseHostConfig(row.id, file, text2, format);
|
|
5737
8024
|
} catch {
|
|
5738
8025
|
throw new Error(parseFail(row, file));
|
|
5739
8026
|
}
|
|
@@ -5741,7 +8028,7 @@ function planJsonKeys(row, edits, file, want) {
|
|
|
5741
8028
|
if (!isObj3(doc)) throw new Error(parseFail(row, file));
|
|
5742
8029
|
let res;
|
|
5743
8030
|
try {
|
|
5744
|
-
res = editHostConfigText(row.id, file, text2 ?? "",
|
|
8031
|
+
res = editHostConfigText(row.id, file, text2 ?? "", format, want(doc));
|
|
5745
8032
|
} catch (e) {
|
|
5746
8033
|
if (e instanceof CtxError) throw new Error(parseFail(row, file));
|
|
5747
8034
|
throw e;
|
|
@@ -5753,10 +8040,10 @@ function planJsonKeys(row, edits, file, want) {
|
|
|
5753
8040
|
prior.changes.push(...changes);
|
|
5754
8041
|
} else edits.push({ file, before: text2, after: res.text, changes });
|
|
5755
8042
|
}
|
|
5756
|
-
function planCodexTrust(row, edits, hooksFile, file, command) {
|
|
8043
|
+
function planCodexTrust(row, edits, hooksFile, file, command, env) {
|
|
5757
8044
|
const hooksText = edits.find((e) => e.file === hooksFile)?.after ?? readOr(hooksFile);
|
|
5758
8045
|
if (hooksText === void 0) return;
|
|
5759
|
-
const want = codexTrustEntries(hooksFile, JSON.parse(hooksText), command);
|
|
8046
|
+
const want = codexTrustEntries(hooksFile, JSON.parse(hooksText), command, env);
|
|
5760
8047
|
if (!want.length) return;
|
|
5761
8048
|
const prior = edits.find((e) => e.file === file);
|
|
5762
8049
|
const text2 = prior ? prior.after : readOr(file);
|
|
@@ -5774,13 +8061,13 @@ function planCodexTrust(row, edits, hooksFile, file, command) {
|
|
|
5774
8061
|
prior.changes.push(...changes);
|
|
5775
8062
|
} else edits.push({ file, before: text2, after: res.text, changes });
|
|
5776
8063
|
}
|
|
5777
|
-
function planHookInstall(row, edits) {
|
|
8064
|
+
function planHookInstall(row, edits, env) {
|
|
5778
8065
|
const h2 = row.hookInstall;
|
|
5779
8066
|
if (h2.kind === "file") {
|
|
5780
|
-
planJsonKeys(row, edits, h2.file, (doc) => Object.keys(h2.shape).map((k) => [[k], mergeOwn(doc[k], h2.shape[k],
|
|
5781
|
-
if (h2.trust) planCodexTrust(row, edits, h2.file, h2.trust, h2.command);
|
|
8067
|
+
planJsonKeys(row, edits, h2.file, fileFormat(row, h2.file), (doc) => Object.keys(h2.shape).map((k) => [[k], mergeOwn(doc[k], h2.shape[k], row.id)]));
|
|
8068
|
+
if (h2.trust) planCodexTrust(row, edits, h2.file, h2.trust, h2.command, env);
|
|
5782
8069
|
} else if (h2.kind === "plugin-list") {
|
|
5783
|
-
planJsonKeys(row, edits, h2.file, (doc) => {
|
|
8070
|
+
planJsonKeys(row, edits, h2.file, fileFormat(row, h2.file), (doc) => {
|
|
5784
8071
|
const cur = doc[h2.key[0]];
|
|
5785
8072
|
const list2 = Array.isArray(cur) ? cur : [];
|
|
5786
8073
|
return [[h2.key, list2.includes(h2.entry) ? list2 : [...list2, h2.entry]]];
|
|
@@ -5793,11 +8080,11 @@ function planSkills(row, edits) {
|
|
|
5793
8080
|
for (const f2 of s.files) {
|
|
5794
8081
|
if (!existsSync6(f2.src)) throw new Error(`preflight: ${f2.src} is missing`);
|
|
5795
8082
|
const after = renderSkill(readFileSync3(f2.src, "utf8"), s.prefixes);
|
|
5796
|
-
const before =
|
|
5797
|
-
if (before !== after) edits.push({ file: f2.file, before, after, changes: [{ file: f2.file, path: f2.name, before: before === void 0 ? null : "old", after: "SKILL.md" }] });
|
|
8083
|
+
const before = readRaw(f2.file);
|
|
8084
|
+
if (before !== after) edits.push({ plain: true, file: f2.file, before, after, changes: [{ file: f2.file, path: f2.name, before: before === void 0 ? null : "old", after: "SKILL.md" }] });
|
|
5798
8085
|
}
|
|
5799
8086
|
}
|
|
5800
|
-
function planRow(row, listed, stale) {
|
|
8087
|
+
function planRow(row, listed, stale, env) {
|
|
5801
8088
|
const edits = [];
|
|
5802
8089
|
if (row.config) {
|
|
5803
8090
|
const c3 = row.config;
|
|
@@ -5815,7 +8102,7 @@ function planRow(row, listed, stale) {
|
|
|
5815
8102
|
const e = planHookFile(row, hf);
|
|
5816
8103
|
if (e) edits.push(e);
|
|
5817
8104
|
}
|
|
5818
|
-
planHookInstall(row, edits);
|
|
8105
|
+
planHookInstall(row, edits, env);
|
|
5819
8106
|
planSkills(row, edits);
|
|
5820
8107
|
const cli = row.config || !row.cli || listed ? [] : row.cli.install;
|
|
5821
8108
|
const refresh = listed && stale && row.copy ? [row.copy.refresh] : [];
|
|
@@ -5830,7 +8117,7 @@ function listCheck(row, env) {
|
|
|
5830
8117
|
}
|
|
5831
8118
|
function packageVersion(pkgDir) {
|
|
5832
8119
|
try {
|
|
5833
|
-
const v = JSON.parse(readFileSync3(
|
|
8120
|
+
const v = JSON.parse(hostText(readFileSync3(path6.join(pkgDir, "package.json"), "utf8"))).version;
|
|
5834
8121
|
return typeof v === "string" ? v : void 0;
|
|
5835
8122
|
} catch {
|
|
5836
8123
|
return void 0;
|
|
@@ -5857,7 +8144,7 @@ function copyCheck(row, pkgDir) {
|
|
|
5857
8144
|
}
|
|
5858
8145
|
function mcpCheck(cmd, env) {
|
|
5859
8146
|
return new Promise((resolve) => {
|
|
5860
|
-
const child = spawn(cmd[0], cmd.slice(1), { env, stdio: ["pipe", "pipe", "ignore"], detached: process.platform !== "win32" });
|
|
8147
|
+
const child = spawn(cmd[0], cmd.slice(1), { env, stdio: ["pipe", "pipe", "ignore"], detached: process.platform !== "win32", windowsHide: true });
|
|
5861
8148
|
const reap = () => {
|
|
5862
8149
|
child.kill();
|
|
5863
8150
|
};
|
|
@@ -5912,7 +8199,7 @@ function hookRound(row, env) {
|
|
|
5912
8199
|
const bare = [];
|
|
5913
8200
|
for (let i2 = 0; i2 < HOOK_SAMPLES; i2++) {
|
|
5914
8201
|
let t2 = performance.now();
|
|
5915
|
-
const r2 =
|
|
8202
|
+
const r2 = spawnSync2(cmd[0], cmd.slice(1), { env, input, encoding: "utf8", timeout: VERIFY_TIMEOUT_MS, windowsHide: true });
|
|
5916
8203
|
wall.push(performance.now() - t2);
|
|
5917
8204
|
if (r2.status !== 0) return { name: "hook", ok: false, detail: `hook exited ${r2.status}: ${`${r2.stderr}`.trim()}` };
|
|
5918
8205
|
const out2 = `${r2.stdout}`.trim();
|
|
@@ -5925,7 +8212,7 @@ function hookRound(row, env) {
|
|
|
5925
8212
|
if (!isObj3(j2)) return { name: "hook", ok: false, detail: `hook answer is not a JSON object: ${out2.slice(0, 200)}` };
|
|
5926
8213
|
}
|
|
5927
8214
|
t2 = performance.now();
|
|
5928
|
-
|
|
8215
|
+
spawnSync2(cmd[0], ["-e", ""], { env, timeout: VERIFY_TIMEOUT_MS, windowsHide: true });
|
|
5929
8216
|
bare.push(performance.now() - t2);
|
|
5930
8217
|
}
|
|
5931
8218
|
const wallP95Ms = Math.round(p95(wall));
|
|
@@ -5949,7 +8236,7 @@ function parseCheck(row) {
|
|
|
5949
8236
|
const c3 = row.config;
|
|
5950
8237
|
if (!c3) return { name: "parse", ok: true };
|
|
5951
8238
|
try {
|
|
5952
|
-
const r2 = editHostConfigText(row.id, c3.file,
|
|
8239
|
+
const r2 = editHostConfigText(row.id, c3.file, readOr(c3.file) ?? "", c3.format, configEdits(c3));
|
|
5953
8240
|
return { name: "parse", ok: r2.edits.length === 0, detail: r2.edits.length ? "entry differs after write" : void 0 };
|
|
5954
8241
|
} catch (e) {
|
|
5955
8242
|
return { name: "parse", ok: false, detail: e.message };
|
|
@@ -5965,7 +8252,7 @@ function hookRegisteredCheck(row, env, list2) {
|
|
|
5965
8252
|
}
|
|
5966
8253
|
const edits = [];
|
|
5967
8254
|
try {
|
|
5968
|
-
planHookInstall(row, edits);
|
|
8255
|
+
planHookInstall(row, edits, env);
|
|
5969
8256
|
} catch (e) {
|
|
5970
8257
|
return { name: "hook-registered", ok: false, detail: e.message };
|
|
5971
8258
|
}
|
|
@@ -5975,19 +8262,19 @@ function hookRegisteredCheck(row, env, list2) {
|
|
|
5975
8262
|
return { name: "hook-registered", ok: false, detail: `${h2.file} lacks the context-mode hook entry` };
|
|
5976
8263
|
}
|
|
5977
8264
|
function hookRunsCheck(row, env) {
|
|
5978
|
-
const root = mkdtempSync(
|
|
8265
|
+
const root = mkdtempSync(path6.join(tmpdir2(), "cm-doctor-runs-"));
|
|
5979
8266
|
try {
|
|
5980
|
-
const home =
|
|
5981
|
-
const proj =
|
|
5982
|
-
|
|
5983
|
-
|
|
8267
|
+
const home = path6.join(root, "home");
|
|
8268
|
+
const proj = path6.join(root, "proj");
|
|
8269
|
+
mkdirSync3(home);
|
|
8270
|
+
mkdirSync3(proj);
|
|
5984
8271
|
const text2 = sampleText();
|
|
5985
|
-
writeFileSync2(
|
|
8272
|
+
writeFileSync2(path6.join(proj, SAMPLE_FILE), text2);
|
|
5986
8273
|
const { effect, payload } = hookSample(row.id, proj, text2);
|
|
5987
8274
|
const sampleEnv = { ...env, HOME: home, USERPROFILE: home };
|
|
5988
8275
|
delete sampleEnv.CLAUDE_PROJECT_DIR;
|
|
5989
8276
|
const cmd = row.hookRunCommand;
|
|
5990
|
-
const r2 =
|
|
8277
|
+
const r2 = spawnSync2(cmd[0], cmd.slice(1), { env: sampleEnv, cwd: proj, input: JSON.stringify(payload), encoding: "utf8", timeout: VERIFY_TIMEOUT_MS, windowsHide: true });
|
|
5991
8278
|
const bad = sampleVerdict(row.id, effect, text2, { status: r2.status, stdout: `${r2.stdout ?? ""}`, stderr: `${r2.stderr ?? ""}` });
|
|
5992
8279
|
return bad === null ? { name: "hook-runs", ok: true } : { name: "hook-runs", ok: false, detail: bad };
|
|
5993
8280
|
} finally {
|
|
@@ -5997,7 +8284,7 @@ function hookRunsCheck(row, env) {
|
|
|
5997
8284
|
var SEEN_SQL = "SELECT 1 FROM events WHERE agent = ? LIMIT 1";
|
|
5998
8285
|
var NOT_SEEN_LINE = "not seen yet, run one tool call";
|
|
5999
8286
|
function hookSeenCheck(row, home) {
|
|
6000
|
-
const base =
|
|
8287
|
+
const base = path6.join(home, STATE_DIR, PROJECTS_DIR_NAME);
|
|
6001
8288
|
const dirs = existsSync6(base) ? readdirSync4(base) : [];
|
|
6002
8289
|
let sqlite;
|
|
6003
8290
|
try {
|
|
@@ -6006,7 +8293,7 @@ function hookSeenCheck(row, home) {
|
|
|
6006
8293
|
sqlite = void 0;
|
|
6007
8294
|
}
|
|
6008
8295
|
for (const d of dirs) {
|
|
6009
|
-
const file =
|
|
8296
|
+
const file = path6.join(base, d, DB_FILE_NAME);
|
|
6010
8297
|
if (!sqlite || !existsSync6(file)) continue;
|
|
6011
8298
|
let db;
|
|
6012
8299
|
try {
|
|
@@ -6022,10 +8309,10 @@ function hookSeenCheck(row, home) {
|
|
|
6022
8309
|
function skillsCheck(row, pkgDir) {
|
|
6023
8310
|
const s = row.skillInstall;
|
|
6024
8311
|
if (s.kind === "package") {
|
|
6025
|
-
const miss = COMMAND_SKILLS.map((n3) =>
|
|
8312
|
+
const miss = COMMAND_SKILLS.map((n3) => path6.join(pkgDir, s.via, n3, SKILL_FILE)).filter((f2) => !existsSync6(f2));
|
|
6026
8313
|
return { name: "skills", ok: miss.length === 0, detail: miss.length ? `missing ${miss.join(", ")}` : void 0 };
|
|
6027
8314
|
}
|
|
6028
|
-
const bad = s.files.filter((f2) =>
|
|
8315
|
+
const bad = s.files.filter((f2) => readRaw(f2.file) !== (existsSync6(f2.src) ? renderSkill(readFileSync3(f2.src, "utf8"), s.prefixes) : void 0));
|
|
6029
8316
|
return { name: "skills", ok: bad.length === 0, detail: bad.length ? `${bad.map((f2) => f2.file).join(", ")} missing or without the ${s.prefixes.join(" / ") || "plain"} tool prefix` : void 0 };
|
|
6030
8317
|
}
|
|
6031
8318
|
var PLUGIN_ENABLED = "enabled";
|
|
@@ -6122,16 +8409,16 @@ var Run = class {
|
|
|
6122
8409
|
this.runId = runId;
|
|
6123
8410
|
}
|
|
6124
8411
|
get dir() {
|
|
6125
|
-
return
|
|
8412
|
+
return path6.join(this.root, BACKUP_DIR, this.runId);
|
|
6126
8413
|
}
|
|
6127
8414
|
save() {
|
|
6128
|
-
if (this.manifest) atomicWrite(
|
|
8415
|
+
if (this.manifest) atomicWrite(path6.join(this.dir, MANIFEST), JSON.stringify(this.manifest, null, 2));
|
|
6129
8416
|
}
|
|
6130
8417
|
record(e, bytes) {
|
|
6131
8418
|
if (!this.manifest) this.manifest = { runId: this.runId, path: this.dir, entries: [] };
|
|
6132
8419
|
if (bytes !== void 0) {
|
|
6133
|
-
const rel =
|
|
6134
|
-
atomicWrite(
|
|
8420
|
+
const rel = path6.join(FILES, String(this.manifest.entries.length));
|
|
8421
|
+
atomicWrite(path6.join(this.dir, rel), bytes);
|
|
6135
8422
|
e.backup = rel;
|
|
6136
8423
|
}
|
|
6137
8424
|
this.manifest.entries.push(e);
|
|
@@ -6151,13 +8438,13 @@ function undo(dir, entries, env) {
|
|
|
6151
8438
|
continue;
|
|
6152
8439
|
}
|
|
6153
8440
|
if (!e.file) continue;
|
|
6154
|
-
if (e.existed && e.backup) atomicWrite(e.file, readFileSync3(
|
|
6155
|
-
else
|
|
8441
|
+
if (e.existed && e.backup) atomicWrite(e.file, readFileSync3(path6.join(dir, e.backup), "utf8"));
|
|
8442
|
+
else unlinkWithRetry(e.file);
|
|
6156
8443
|
}
|
|
6157
8444
|
}
|
|
6158
8445
|
function takeLock(root, runId) {
|
|
6159
|
-
const file =
|
|
6160
|
-
|
|
8446
|
+
const file = path6.join(root, LOCK_FILE);
|
|
8447
|
+
mkdirSync3(root, { recursive: true });
|
|
6161
8448
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
6162
8449
|
try {
|
|
6163
8450
|
writeFileSync2(file, JSON.stringify({ pid: process.pid, runId }), { flag: "wx" });
|
|
@@ -6175,18 +8462,25 @@ function takeLock(root, runId) {
|
|
|
6175
8462
|
}
|
|
6176
8463
|
return `setup lock ${file} could not be taken`;
|
|
6177
8464
|
}
|
|
8465
|
+
function agentHomeDir(id, ctx) {
|
|
8466
|
+
if (id === "claude-code") return claudeDirOf(ctx.env, ctx.home);
|
|
8467
|
+
if (id === "copilot-cli") return copilotDirOf(ctx.env, ctx.home);
|
|
8468
|
+
if (id === "kiro") return kiroDirOf(ctx.env, ctx.home);
|
|
8469
|
+
if (id === "opencode") return opencodeDirOf(ctx.env, ctx.home);
|
|
8470
|
+
return path6.join(ctx.home, ...AGENT_HOME_DIR[id]);
|
|
8471
|
+
}
|
|
6178
8472
|
function detectAgents(reg, ctx) {
|
|
6179
|
-
return reg.filter((r2) => existsSync6(
|
|
8473
|
+
return reg.filter((r2) => existsSync6(agentHomeDir(r2.id, ctx)) || r2.listCommand && which(r2.listCommand.bin, ctx.env)).map((r2) => r2.id);
|
|
6180
8474
|
}
|
|
6181
8475
|
async function runSetup(opts) {
|
|
6182
8476
|
const ctx = { home: opts.home, pkgDir: opts.pkgDir, env: opts.env };
|
|
6183
|
-
const runId = opts.runId ?? (/* @__PURE__ */ new Date()).toISOString().
|
|
8477
|
+
const runId = opts.runId ?? (/* @__PURE__ */ new Date()).toISOString().split(":").join("-").split(".").join("-");
|
|
6184
8478
|
const reg = buildRegistry(ctx);
|
|
6185
8479
|
for (const f2 of ["server.mjs", "hook.mjs"]) {
|
|
6186
|
-
if (!existsSync6(
|
|
8480
|
+
if (!existsSync6(path6.join(ctx.pkgDir, f2))) return { exitCode: 1, agents: [], error: `preflight: ${path6.join(ctx.pkgDir, f2)} is missing` };
|
|
6187
8481
|
}
|
|
6188
8482
|
const ids = opts.agents ?? detectAgents(reg, ctx);
|
|
6189
|
-
const root =
|
|
8483
|
+
const root = path6.join(ctx.home, STATE_DIR);
|
|
6190
8484
|
if (!opts.dryRun) {
|
|
6191
8485
|
const held = takeLock(root, runId);
|
|
6192
8486
|
if (held) return { exitCode: 1, agents: [], error: held };
|
|
@@ -6196,7 +8490,7 @@ async function runSetup(opts) {
|
|
|
6196
8490
|
let current;
|
|
6197
8491
|
const onAbort = () => {
|
|
6198
8492
|
if (current !== void 0 && !opts.dryRun) run.rollback(current, ctx.env);
|
|
6199
|
-
if (!opts.dryRun) rmSync(
|
|
8493
|
+
if (!opts.dryRun) rmSync(path6.join(root, LOCK_FILE), { force: true });
|
|
6200
8494
|
};
|
|
6201
8495
|
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
6202
8496
|
try {
|
|
@@ -6215,7 +8509,7 @@ async function runSetup(opts) {
|
|
|
6215
8509
|
}
|
|
6216
8510
|
} finally {
|
|
6217
8511
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
6218
|
-
if (!opts.dryRun) rmSync(
|
|
8512
|
+
if (!opts.dryRun) rmSync(path6.join(root, LOCK_FILE), { force: true });
|
|
6219
8513
|
}
|
|
6220
8514
|
return { exitCode: agents.some((a2) => a2.status === "FAIL") ? 1 : 0, agents, backupDir: run.manifest ? run.dir : void 0 };
|
|
6221
8515
|
}
|
|
@@ -6232,23 +8526,24 @@ async function setupRow(row, ctx, run, dryRun) {
|
|
|
6232
8526
|
let plan;
|
|
6233
8527
|
try {
|
|
6234
8528
|
const listed = needsBin ? listCheck(row, ctx.env)?.ok === true : false;
|
|
6235
|
-
plan = planRow(row, listed, copyCheck(row, ctx.pkgDir)?.ok === false);
|
|
8529
|
+
plan = planRow(row, listed, copyCheck(row, ctx.pkgDir)?.ok === false, ctx.env);
|
|
6236
8530
|
} catch (e) {
|
|
6237
8531
|
return { ...res, status: "FAIL", reason: e.message };
|
|
6238
8532
|
}
|
|
6239
8533
|
const configEdited = (file) => plan.edits.some((e) => e.file === file && e.changes.some((c3) => !isTrust(row, c3)));
|
|
6240
|
-
res.v1 = detectV1(row.id, ctx.home).filter((f2) => !(row.config && f2.file === row.config.file && !configEdited(f2.file)));
|
|
8534
|
+
res.v1 = detectV1(row.id, ctx.home, { claudeDir: claudeDirOf(ctx.env, ctx.home), copilotDir: copilotDirOf(ctx.env, ctx.home), kiroDir: kiroDirOf(ctx.env, ctx.home), opencodeDir: opencodeDirOf(ctx.env, ctx.home) }).filter((f2) => !(row.config && f2.file === row.config.file && !configEdited(f2.file)));
|
|
6241
8535
|
res.changes = [...plan.edits.flatMap((e) => e.changes), ...[...plan.cli, ...plan.refresh].map((args) => ({ command: [row.cli.bin, ...args] }))];
|
|
6242
8536
|
if (dryRun) return res;
|
|
6243
8537
|
try {
|
|
6244
8538
|
for (const e of plan.edits) {
|
|
6245
8539
|
assertWritable(row, e.file);
|
|
6246
|
-
|
|
6247
|
-
|
|
8540
|
+
const raw = readRaw(e.file);
|
|
8541
|
+
run.record({ agent: row.id, file: e.file, existed: raw !== void 0 }, raw);
|
|
8542
|
+
atomicWrite(e.file, e.plain || raw === void 0 ? e.after : withLayout(e.after, hostLayout(raw)));
|
|
6248
8543
|
}
|
|
6249
8544
|
for (const args of plan.cli) {
|
|
6250
8545
|
const r2 = runBin(row.cli.bin, args, ctx.env, row.cli.input ?? "");
|
|
6251
|
-
if (r2.status
|
|
8546
|
+
if (!installExitOk(r2.status, r2.status === WIN_EXIT_CRASH && listCheck(row, ctx.env)?.ok === true)) throw new Error(`${row.cli.bin} ${args.join(" ")} exited ${r2.status}: ${`${r2.stderr}`.trim()}`);
|
|
6252
8547
|
}
|
|
6253
8548
|
if (plan.cli.length) for (const args of row.cli.remove) run.record({ agent: row.id, undo: { bin: row.cli.bin, args } });
|
|
6254
8549
|
for (const args of plan.refresh) {
|
|
@@ -6271,10 +8566,10 @@ async function runDoctor(opts) {
|
|
|
6271
8566
|
const ctx = { home: opts.home, pkgDir: opts.pkgDir, env: opts.env };
|
|
6272
8567
|
const reg = buildRegistry(ctx);
|
|
6273
8568
|
for (const f2 of ["server.mjs", "hook.mjs"]) {
|
|
6274
|
-
if (!existsSync6(
|
|
8569
|
+
if (!existsSync6(path6.join(ctx.pkgDir, f2))) return { exitCode: 1, agents: [], error: `preflight: ${path6.join(ctx.pkgDir, f2)} is missing` };
|
|
6275
8570
|
}
|
|
6276
8571
|
const ids = opts.agents ?? detectAgents(reg, ctx);
|
|
6277
|
-
const run = new Run(
|
|
8572
|
+
const run = new Run(path6.join(ctx.home, STATE_DIR), "doctor");
|
|
6278
8573
|
const agents = [];
|
|
6279
8574
|
for (const id of ids) {
|
|
6280
8575
|
const row = reg.find((r2) => r2.id === id);
|
|
@@ -6324,37 +8619,46 @@ function isTrust(row, c3) {
|
|
|
6324
8619
|
}
|
|
6325
8620
|
function runRemove(opts) {
|
|
6326
8621
|
const env = opts.env ?? process.env;
|
|
6327
|
-
const root =
|
|
6328
|
-
const base =
|
|
8622
|
+
const root = path6.join(opts.home, STATE_DIR);
|
|
8623
|
+
const base = path6.join(root, BACKUP_DIR);
|
|
6329
8624
|
if (!existsSync6(base)) return { exitCode: 0, restored: 0 };
|
|
6330
8625
|
const held = takeLock(root, "remove");
|
|
6331
8626
|
if (held) return { exitCode: 1, restored: 0, error: held };
|
|
6332
8627
|
let restored = 0;
|
|
6333
8628
|
try {
|
|
6334
|
-
const runs = readdirSync4(base).map((r2) =>
|
|
8629
|
+
const runs = readdirSync4(base).map((r2) => path6.join(base, r2)).filter((d) => existsSync6(path6.join(d, MANIFEST))).sort().reverse();
|
|
6335
8630
|
for (const dir of runs) {
|
|
6336
|
-
const m3 = JSON.parse(readFileSync3(
|
|
8631
|
+
const m3 = JSON.parse(readFileSync3(path6.join(dir, MANIFEST), "utf8"));
|
|
6337
8632
|
undo(dir, m3.entries, env);
|
|
6338
8633
|
restored += m3.entries.length;
|
|
6339
|
-
|
|
8634
|
+
renameWithRetry(path6.join(dir, MANIFEST), path6.join(dir, MANIFEST_DONE));
|
|
6340
8635
|
}
|
|
6341
8636
|
} finally {
|
|
6342
|
-
rmSync(
|
|
8637
|
+
rmSync(path6.join(root, LOCK_FILE), { force: true });
|
|
6343
8638
|
}
|
|
6344
8639
|
return { exitCode: 0, restored };
|
|
6345
8640
|
}
|
|
6346
8641
|
|
|
6347
8642
|
// src/setup/print.ts
|
|
6348
8643
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
8644
|
+
var SHELL_SAFE_PUNCT = "@%+=:,./-_";
|
|
8645
|
+
function isShellSafe(s) {
|
|
8646
|
+
if (s === "") return false;
|
|
8647
|
+
for (const c3 of s) {
|
|
8648
|
+
const alnum = c3 >= "a" && c3 <= "z" || c3 >= "A" && c3 <= "Z" || c3 >= "0" && c3 <= "9";
|
|
8649
|
+
if (!alnum && !SHELL_SAFE_PUNCT.includes(c3)) return false;
|
|
8650
|
+
}
|
|
8651
|
+
return true;
|
|
8652
|
+
}
|
|
6349
8653
|
function shellWord(s) {
|
|
6350
|
-
return
|
|
8654
|
+
return isShellSafe(s) ? s : `'${s.replaceAll("'", `'"'"'`)}'`;
|
|
6351
8655
|
}
|
|
6352
|
-
function printPlan(row) {
|
|
8656
|
+
function printPlan(row, env) {
|
|
6353
8657
|
const steps = [];
|
|
6354
8658
|
const h2 = row.hookInstall;
|
|
6355
8659
|
if (row.config) {
|
|
6356
8660
|
const c3 = row.config;
|
|
6357
|
-
const trust = h2.kind === "file" && h2.trust === c3.file ? codexTrustEntries(h2.file, h2.shape, h2.command) : [];
|
|
8661
|
+
const trust = h2.kind === "file" && h2.trust === c3.file ? codexTrustEntries(h2.file, h2.shape, h2.command, env) : [];
|
|
6358
8662
|
const block2 = editHostConfigText(row.id, c3.file, "", c3.format, [...configEdits(c3), ...trust]).text;
|
|
6359
8663
|
steps.push({ kind: "config", file: c3.file, format: c3.format, key: c3.key, block: block2 });
|
|
6360
8664
|
} else if (row.cli) {
|
|
@@ -6525,7 +8829,7 @@ function buildIssueReport(command, res, ui) {
|
|
|
6525
8829
|
return { text: redact(lines.join("\n"), ui.ctx), title };
|
|
6526
8830
|
}
|
|
6527
8831
|
function ghReady(env) {
|
|
6528
|
-
const r2 =
|
|
8832
|
+
const r2 = spawnSync3("gh", ["auth", "status"], { env, stdio: "ignore", timeout: 1e4, windowsHide: true });
|
|
6529
8833
|
return r2.status === 0;
|
|
6530
8834
|
}
|
|
6531
8835
|
function issueUrl(title, body) {
|
|
@@ -6536,9 +8840,9 @@ async function report(ui, command, res, write) {
|
|
|
6536
8840
|
const { text: text2, title } = buildIssueReport(command, res, ui);
|
|
6537
8841
|
let file = "";
|
|
6538
8842
|
if (write) {
|
|
6539
|
-
const dir =
|
|
6540
|
-
|
|
6541
|
-
file =
|
|
8843
|
+
const dir = path7.join(ui.ctx.home, STATE_DIR, REPORT_DIR);
|
|
8844
|
+
mkdirSync4(dir, { recursive: true });
|
|
8845
|
+
file = path7.join(dir, `${command}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.md`);
|
|
6542
8846
|
writeFileSync3(file, text2);
|
|
6543
8847
|
}
|
|
6544
8848
|
const gh = `gh issue create --repo ${ISSUE_REPO} --title ${JSON.stringify(title)} --body-file ${JSON.stringify(file || "<report>")}`;
|
|
@@ -6556,7 +8860,7 @@ async function report(ui, command, res, write) {
|
|
|
6556
8860
|
return;
|
|
6557
8861
|
}
|
|
6558
8862
|
if (file && ghReady(ui.ctx.env)) {
|
|
6559
|
-
const r2 =
|
|
8863
|
+
const r2 = spawnSync3("gh", ["issue", "create", "--repo", ISSUE_REPO, "--title", title, "--body-file", file], { env: ui.ctx.env, encoding: "utf8", timeout: 6e4, windowsHide: true });
|
|
6560
8864
|
if (r2.status === 0) {
|
|
6561
8865
|
p3.log.success(`Issue opened: ${`${r2.stdout}`.trim()}`);
|
|
6562
8866
|
return;
|
|
@@ -6646,7 +8950,7 @@ async function remove(ui) {
|
|
|
6646
8950
|
}
|
|
6647
8951
|
}
|
|
6648
8952
|
if (ui.f.dryRun) {
|
|
6649
|
-
out(`Would restore every file recorded under ${
|
|
8953
|
+
out(`Would restore every file recorded under ${path7.join(ui.ctx.home, STATE_DIR, "backups")}`);
|
|
6650
8954
|
return EXIT_OK;
|
|
6651
8955
|
}
|
|
6652
8956
|
const r2 = runRemove({ home: ui.ctx.home, env: ui.ctx.env });
|
|
@@ -6657,7 +8961,7 @@ async function remove(ui) {
|
|
|
6657
8961
|
}
|
|
6658
8962
|
function printManual(ui, id) {
|
|
6659
8963
|
const row = buildRegistry(ui.ctx).find((r2) => r2.id === id);
|
|
6660
|
-
const p3 = printPlan(row);
|
|
8964
|
+
const p3 = printPlan(row, ui.ctx.env);
|
|
6661
8965
|
if (ui.f.json) out(JSON.stringify({ command: "setup", print: p3 }));
|
|
6662
8966
|
else out(printText(p3));
|
|
6663
8967
|
return EXIT_OK;
|
|
@@ -6778,20 +9082,20 @@ async function upgrade(ui) {
|
|
|
6778
9082
|
}
|
|
6779
9083
|
const shell = process.platform === "win32";
|
|
6780
9084
|
progress2(ui, `running ${install}`);
|
|
6781
|
-
const r2 =
|
|
9085
|
+
const r2 = spawnSync3(npm, ["i", "-g", spec], { env: ui.ctx.env, encoding: "utf8", shell, windowsHide: true });
|
|
6782
9086
|
if (r2.status !== 0) {
|
|
6783
9087
|
const why = (`${r2.stderr ?? ""}`.trim().split("\n").pop() ?? "") || (r2.error?.message ?? "");
|
|
6784
9088
|
err(`FAIL upgrade: ${install} exited ${r2.status ?? "?"}${why ? `: ${why}` : ""}. Fix: ${install}`);
|
|
6785
9089
|
return EXIT_FAIL;
|
|
6786
9090
|
}
|
|
6787
|
-
const root = `${
|
|
6788
|
-
const cli =
|
|
9091
|
+
const root = `${spawnSync3(npm, ["root", "-g"], { env: ui.ctx.env, encoding: "utf8", shell, windowsHide: true }).stdout ?? ""}`.trim();
|
|
9092
|
+
const cli = path7.join(root, "context-mode", "cli.mjs");
|
|
6789
9093
|
if (!root || !existsSync7(cli)) {
|
|
6790
9094
|
err(`FAIL upgrade: ${cli} not found after ${install}. Fix: ${install}`);
|
|
6791
9095
|
return EXIT_FAIL;
|
|
6792
9096
|
}
|
|
6793
9097
|
progress2(ui, `running context-mode ${repairArgs.join(" ")}`);
|
|
6794
|
-
const c3 =
|
|
9098
|
+
const c3 = spawnSync3(process.execPath, [cli, ...repairArgs], { env: ui.ctx.env, stdio: "inherit", windowsHide: true });
|
|
6795
9099
|
return c3.status ?? (c3.signal === "SIGINT" ? EXIT_SIGINT : EXIT_FAIL);
|
|
6796
9100
|
}
|
|
6797
9101
|
async function runCommand(cmd, args, env) {
|
|
@@ -6808,7 +9112,7 @@ Run context-mode ${cmd} --help.`);
|
|
|
6808
9112
|
out(HELP[cmd].trimEnd());
|
|
6809
9113
|
return EXIT_OK;
|
|
6810
9114
|
}
|
|
6811
|
-
const ctx = { home: process.env
|
|
9115
|
+
const ctx = { home: homeDirOf(process.env) ?? os.homedir(), pkgDir: env.pkgDir, env: process.env };
|
|
6812
9116
|
const tty = !!process.stdin.isTTY && !!process.stdout.isTTY;
|
|
6813
9117
|
const interactive = tty && !f2.yes && !f2.noInput && !f2.json && !f2.list && !f2.print;
|
|
6814
9118
|
if (interactive && !process.stdout.columns) Object.defineProperty(process.stdout, "columns", { value: 80, configurable: true });
|
|
@@ -6869,10 +9173,10 @@ function route(argv, version) {
|
|
|
6869
9173
|
` };
|
|
6870
9174
|
}
|
|
6871
9175
|
function main() {
|
|
6872
|
-
const dir =
|
|
9176
|
+
const dir = path8.dirname(realpathSync5(fileURLToPath2(import.meta.url)));
|
|
6873
9177
|
let version = "";
|
|
6874
9178
|
try {
|
|
6875
|
-
version = String(JSON.parse(readFileSync5(
|
|
9179
|
+
version = String(JSON.parse(readFileSync5(path8.join(dir, PACKAGE_FILE), "utf8")).version);
|
|
6876
9180
|
} catch (err2) {
|
|
6877
9181
|
process.stderr.write(`${SERVER_KEY}: cannot read ${PACKAGE_FILE}: ${err2.message}
|
|
6878
9182
|
`);
|
|
@@ -6896,7 +9200,7 @@ function main() {
|
|
|
6896
9200
|
process.exitCode = r2.code;
|
|
6897
9201
|
return;
|
|
6898
9202
|
}
|
|
6899
|
-
const child = spawn2(process.execPath, [
|
|
9203
|
+
const child = spawn2(process.execPath, [path8.join(dir, r2.file), ...r2.args], { stdio: "inherit", windowsHide: true });
|
|
6900
9204
|
process.on("SIGINT", () => {
|
|
6901
9205
|
});
|
|
6902
9206
|
child.on("error", (err2) => {
|