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/opencode/plugin.js
CHANGED
|
@@ -330,8 +330,8 @@ var DECISION_OPTION_KEY = "option";
|
|
|
330
330
|
var DECISION_LABEL_JOIN = " | ";
|
|
331
331
|
var RELEASE_REPO_URL = "https://github.com/mksglu/context-mode.git";
|
|
332
332
|
var RELEASE_BRANCH = "release";
|
|
333
|
-
var BUNDLE_SHA = true ? "
|
|
334
|
-
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10"]);
|
|
333
|
+
var BUNDLE_SHA = true ? "4fb62aa646f6f53db6e655a59f4397d5ef78c0a4" : void 0;
|
|
334
|
+
var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10", "D11"]);
|
|
335
335
|
var DOCTOR_LABEL = Object.freeze({
|
|
336
336
|
D1: "version",
|
|
337
337
|
D2: "node",
|
|
@@ -343,7 +343,8 @@ var DOCTOR_LABEL = Object.freeze({
|
|
|
343
343
|
D7: "project and worktree",
|
|
344
344
|
D8: "context.db",
|
|
345
345
|
D9: "index",
|
|
346
|
-
D10: "enforcement mode"
|
|
346
|
+
D10: "enforcement mode",
|
|
347
|
+
D11: "shell"
|
|
347
348
|
});
|
|
348
349
|
var HOOK_FIXTURE_DIR = "fixtures";
|
|
349
350
|
var HOOK_FIXTURE_FILE = "hook-roundtrip.json";
|
|
@@ -449,6 +450,8 @@ var GIT_NO_PROMPT_ENV = Object.freeze({ GIT_TERMINAL_PROMPT: "0" });
|
|
|
449
450
|
var GIT_NO_CRLF_ENV = Object.freeze({ GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.autocrlf", GIT_CONFIG_VALUE_0: "false" });
|
|
450
451
|
var GIT_NOT_STARTED = "git did not start";
|
|
451
452
|
var GIT_BIN = "git";
|
|
453
|
+
var WIN_SHELL_LANGS = Object.freeze(["shell", "bash", "sh"]);
|
|
454
|
+
var GIT_BASH_RELATIVE = Object.freeze([["..", "bin", "bash.exe"], ["..", "..", "bin", "bash.exe"]]);
|
|
452
455
|
var GIT_EXIT_LABEL = "git exit ";
|
|
453
456
|
var UPGRADE_TRASH_SUFFIX = ".ctx-upgrade-removing";
|
|
454
457
|
var TABLE_ROW_START = "| ";
|
|
@@ -456,7 +459,6 @@ var TABLE_CELL_SEP = " | ";
|
|
|
456
459
|
var TABLE_ROW_END = " |";
|
|
457
460
|
var TABLE_PIPE = "|";
|
|
458
461
|
var TABLE_PIPE_ESCAPED = "\\|";
|
|
459
|
-
var TOML_TABLE_OPEN = "[";
|
|
460
462
|
var OPS_SPLIT_FILES = Object.freeze([
|
|
461
463
|
"doctor-env.ts",
|
|
462
464
|
"doctor-config.ts",
|
|
@@ -484,10 +486,10 @@ function D3_DETAIL(parts) {
|
|
|
484
486
|
var HOOK_HOST_FILE = Object.freeze({
|
|
485
487
|
"claude-code": { root: "plugin", file: ["hooks", "claude-code.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
486
488
|
codex: { root: "home", file: [".codex", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
487
|
-
gemini: { root: "
|
|
488
|
-
qwen: { root: "
|
|
489
|
+
gemini: { root: "plugin", file: ["hooks", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: false },
|
|
490
|
+
qwen: { root: "plugin", file: ["hooks", "qwen.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
|
|
489
491
|
"copilot-cli": { root: "home", file: [".copilot", "hooks", "context-mode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeoutSec", matcher: false },
|
|
490
|
-
vscode: { root: "
|
|
492
|
+
vscode: { root: "home", file: [".copilot", "hooks", "context-mode-vscode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeout", matcher: false },
|
|
491
493
|
kiro: { root: "home", file: [".kiro", "hooks", "context-mode.json"], key: ["hooks"], shape: "kiro", timeoutKey: "timeout", matcher: false },
|
|
492
494
|
zcode: { root: "home", file: [".zcode", "cli", "config.json"], key: ["hooks", "events"], shape: "zcode", timeoutKey: "timeoutMs", matcher: true },
|
|
493
495
|
pi: null,
|
|
@@ -520,6 +522,13 @@ var PRAGMA_INTEGRITY_CHECK = "PRAGMA integrity_check";
|
|
|
520
522
|
function D10_DETAIL(mode) {
|
|
521
523
|
return `enforcement mode: ${mode}`;
|
|
522
524
|
}
|
|
525
|
+
var D11_WIN_DETAIL = "Git Bash not found";
|
|
526
|
+
var D11_WIN_FIX = "install Git for Windows";
|
|
527
|
+
var D11_POSIX_DETAIL = "no sh on PATH";
|
|
528
|
+
var D11_POSIX_FIX = "install sh or add it to PATH";
|
|
529
|
+
function D11_PASS_DETAIL(shell, win) {
|
|
530
|
+
return `${win ? "Git Bash" : "sh"}: ${shell}`;
|
|
531
|
+
}
|
|
523
532
|
var DB_SIBLING_SUFFIXES = Object.freeze(["", DB_WAL_SUFFIX, DB_SHM_SUFFIX]);
|
|
524
533
|
var HEAL_TMP_SUFFIX = ".heal";
|
|
525
534
|
var HEAL_TS_SEP = ".";
|
|
@@ -528,6 +537,7 @@ var HASH_ENCODING = "hex";
|
|
|
528
537
|
var PLUGIN_LINK_TMP_SUFFIX = ".swap";
|
|
529
538
|
var PLUGIN_LINK_OLD_SUFFIX = ".old";
|
|
530
539
|
var PLUGIN_LINK_TYPE = "dir";
|
|
540
|
+
var PLUGIN_LINK_TYPE_WIN32 = "junction";
|
|
531
541
|
var OWNER_STOP_EXT = ".stop";
|
|
532
542
|
var UPGRADE_DATA_DELETED = "user data deleted";
|
|
533
543
|
var UPGRADE_HOST_COMMAND = Object.freeze({
|
|
@@ -568,7 +578,14 @@ var V1_HOOKS_DIR_NAME = "hooks";
|
|
|
568
578
|
var SETTINGS_FILE = "settings.json";
|
|
569
579
|
var CLAUDE_USER_CONFIG_FILE = ".claude.json";
|
|
570
580
|
var HOOKS_JSON_FILE = "hooks.json";
|
|
581
|
+
var CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR";
|
|
571
582
|
var CODEX_HOME_ENV = "CODEX_HOME";
|
|
583
|
+
var COPILOT_HOME_ENV = "COPILOT_HOME";
|
|
584
|
+
var KIRO_HOME_ENV = "KIRO_HOME";
|
|
585
|
+
var OPENCODE_CONFIG_DIR_ENV = "OPENCODE_CONFIG_DIR";
|
|
586
|
+
var APPDATA_ENV = "APPDATA";
|
|
587
|
+
var VSCODE_USER_DIR_SEGMENTS = Object.freeze(["Code", "User"]);
|
|
588
|
+
var XDG_CONFIG_HOME_ENV = "XDG_CONFIG_HOME";
|
|
572
589
|
var CONFIG_TOML_FILE = "config.toml";
|
|
573
590
|
var CONFIG_JSON_FILE = "config.json";
|
|
574
591
|
var ZCODE_CLI_DIR = "cli";
|
|
@@ -602,6 +619,8 @@ var PI_ROLE = "custom";
|
|
|
602
619
|
var PI_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
|
|
603
620
|
var PI_PACKAGE_SOURCE_KEY = "source";
|
|
604
621
|
var V1_PATH_SEPS = Object.freeze(["/", "\\"]);
|
|
622
|
+
var HOST_SEP_TOKEN = "${/}";
|
|
623
|
+
var HOOK_SCRIPT_SEPS = Object.freeze([...V1_PATH_SEPS, HOST_SEP_TOKEN]);
|
|
605
624
|
var V1_REASON = Object.freeze({
|
|
606
625
|
hook: "old context-mode hook entry: command contains context-mode and an old script name or context-mode hook",
|
|
607
626
|
cacheHealHook: "old context-mode cache-heal SessionStart hook entry",
|
|
@@ -629,7 +648,13 @@ var PLUGIN_NAME = SERVER_KEY;
|
|
|
629
648
|
var OPENCODE_TOOL_PREFIX = SERVER_KEY + "_";
|
|
630
649
|
var SERVER_ENTRY_FILE = "server.mjs";
|
|
631
650
|
var HOST_NODE_COMMAND = "node";
|
|
651
|
+
var EXE_SUFFIX = ".exe";
|
|
632
652
|
var HOST_CONFIG_TMP_SUFFIX = ".tmp";
|
|
653
|
+
var ATOMIC_RENAME_RETRIES = 5;
|
|
654
|
+
var ATOMIC_RENAME_DELAY_MS = 50;
|
|
655
|
+
var ATOMIC_RENAME_BUSY_CODES = ["EPERM", "EBUSY", "EACCES"];
|
|
656
|
+
var ATOMIC_TMP_PREFIX = ".";
|
|
657
|
+
var ATOMIC_TMP_MARK = ".cm-tmp-";
|
|
633
658
|
var HOST_CONFIG_TEXT_PATH = "(given text)";
|
|
634
659
|
var JSON_INDENT_UNIT = " ";
|
|
635
660
|
var MCP_COMMAND_FIELD = "command";
|
|
@@ -641,7 +666,7 @@ var CODEX_APPROVAL_MODE_FIELD = "default_tools_approval_mode";
|
|
|
641
666
|
var CODEX_APPROVAL_APPROVE = "approve";
|
|
642
667
|
var OWN_MCP_ENTRY = Object.freeze({
|
|
643
668
|
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 } },
|
|
644
|
-
vscode: { file: [
|
|
669
|
+
vscode: { file: [VSCODE_MCP_FILE], key: ["servers", SERVER_KEY] },
|
|
645
670
|
kiro: { file: [".kiro", "settings", "mcp.json"], key: ["mcpServers", SERVER_KEY] },
|
|
646
671
|
zcode: {
|
|
647
672
|
file: [".zcode", "cli", "config.json"],
|
|
@@ -664,6 +689,8 @@ var ERROR_TEXT = Object.freeze({
|
|
|
664
689
|
NO_PROJECT: "Project source <kind> is missing. Fix: run ctx_doctor.",
|
|
665
690
|
UNKNOWN_FIELD: 'Unknown field "<f>". Fix: use "queries".',
|
|
666
691
|
TIMEOUT: "Timed out after <ms> ms. Fix: pass background: true.",
|
|
692
|
+
NO_GIT_BASH: "Git Bash not found. Fix: install Git for Windows.",
|
|
693
|
+
// D-VT-WINBASH-1
|
|
667
694
|
NO_RUNTIME: "No <lang> runtime on PATH. Fix: install it or pick another language.",
|
|
668
695
|
FETCH_FAILED: "Fetch failed: <code>. Fix: check the URL or proxy.",
|
|
669
696
|
SSRF: "Blocked private address <host>. Fix: use a public URL.",
|
|
@@ -1087,8 +1114,14 @@ var VSCODE_EVENTS = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostTool
|
|
|
1087
1114
|
var MCP_PREFIX2 = "mcp_";
|
|
1088
1115
|
var MCP_SEP2 = "_";
|
|
1089
1116
|
var SESSION_START_NEW = "new";
|
|
1090
|
-
var
|
|
1091
|
-
var
|
|
1117
|
+
var SHELL_TOOL_NAMES = Object.freeze(["run_in_terminal", "runTerminalCommand", "bash", "powershell"]);
|
|
1118
|
+
var READ_TOOL_NAMES = Object.freeze(["read_file", "view"]);
|
|
1119
|
+
var WEBFETCH_TOOL_NAMES = Object.freeze(["fetch_webpage", "web_fetch"]);
|
|
1120
|
+
var NATIVE_TO_CANONICAL4 = Object.fromEntries([
|
|
1121
|
+
...SHELL_TOOL_NAMES.map((n) => [n, "Bash"]),
|
|
1122
|
+
...READ_TOOL_NAMES.map((n) => [n, "Read"]),
|
|
1123
|
+
...WEBFETCH_TOOL_NAMES.map((n) => [n, "WebFetch"])
|
|
1124
|
+
]);
|
|
1092
1125
|
function canonicalName4(name) {
|
|
1093
1126
|
if (name.startsWith(TOOL_NAME_PREFIX6)) return name.slice(TOOL_NAME_PREFIX6.length);
|
|
1094
1127
|
if (Object.hasOwn(NATIVE_TO_CANONICAL4, name)) return NATIVE_TO_CANONICAL4[name];
|
|
@@ -1098,6 +1131,26 @@ function canonicalName4(name) {
|
|
|
1098
1131
|
if (sep3 <= 0 || sep3 === rest.length - 1) return name;
|
|
1099
1132
|
return "mcp:" + rest.slice(0, sep3) + ":" + rest.slice(sep3 + MCP_SEP2.length);
|
|
1100
1133
|
}
|
|
1134
|
+
var isNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
1135
|
+
function policyInput(name, canonical, input) {
|
|
1136
|
+
if (canonical === "Read" && READ_TOOL_NAMES.includes(name)) {
|
|
1137
|
+
const out = { ...input };
|
|
1138
|
+
if (name === "read_file") {
|
|
1139
|
+
if (typeof input.filePath === "string") out.file_path = input.filePath;
|
|
1140
|
+
if (isNum(input.startLine)) out.offset = input.startLine;
|
|
1141
|
+
if (isNum(input.startLine) && isNum(input.endLine) && input.endLine >= input.startLine) out.limit = input.endLine - input.startLine + 1;
|
|
1142
|
+
} else if (Array.isArray(input.view_range) && isNum(input.view_range[0])) {
|
|
1143
|
+
out.offset = input.view_range[0];
|
|
1144
|
+
const end = input.view_range[1];
|
|
1145
|
+
if (isNum(end) && end >= input.view_range[0]) out.limit = end - input.view_range[0] + 1;
|
|
1146
|
+
}
|
|
1147
|
+
return out;
|
|
1148
|
+
}
|
|
1149
|
+
if (canonical === "WebFetch" && name === "fetch_webpage" && Array.isArray(input.urls) && typeof input.urls[0] === "string") {
|
|
1150
|
+
return { ...input, url: input.urls[0] };
|
|
1151
|
+
}
|
|
1152
|
+
return input;
|
|
1153
|
+
}
|
|
1101
1154
|
function readResult4(resp) {
|
|
1102
1155
|
const text = resp === void 0 ? "" : typeof resp === "string" ? resp : JSON.stringify(resp);
|
|
1103
1156
|
const isError = typeof resp === "object" && resp !== null && resp.is_error === true;
|
|
@@ -1145,7 +1198,8 @@ function decodeCamel(p, name) {
|
|
|
1145
1198
|
if (event === "UserPromptSubmit" && typeof p.prompt === "string") ev.prompt = p.prompt;
|
|
1146
1199
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
1147
1200
|
const toolName = String(p.toolName ?? "");
|
|
1148
|
-
|
|
1201
|
+
const canonical = canonicalName4(toolName);
|
|
1202
|
+
ev.tool = { name: toolName, canonicalName: canonical, input: policyInput(toolName, canonical, readArgs2(p.toolArgs)) };
|
|
1149
1203
|
}
|
|
1150
1204
|
if (event === "PostToolUse") ev.result = readCamelResult(p.toolResult);
|
|
1151
1205
|
return ev;
|
|
@@ -1167,7 +1221,8 @@ function decode6(raw) {
|
|
|
1167
1221
|
if (event === "PreToolUse" || event === "PostToolUse") {
|
|
1168
1222
|
const name = String(p.tool_name ?? "");
|
|
1169
1223
|
const input = isRecord2(p.tool_input) ? p.tool_input : {};
|
|
1170
|
-
|
|
1224
|
+
const canonical = canonicalName4(name);
|
|
1225
|
+
ev.tool = { name, canonicalName: canonical, input: policyInput(name, canonical, input) };
|
|
1171
1226
|
}
|
|
1172
1227
|
if (event === "PostToolUse") ev.result = readResult4(p.tool_response);
|
|
1173
1228
|
return ev;
|
|
@@ -1191,8 +1246,8 @@ var KIRO_EVENTS = {
|
|
|
1191
1246
|
};
|
|
1192
1247
|
var PROMPT_ENV = "USER_PROMPT";
|
|
1193
1248
|
var MCP_PREFIX3 = "mcp_";
|
|
1194
|
-
var
|
|
1195
|
-
var NATIVE_TO_CANONICAL5 = Object.fromEntries(
|
|
1249
|
+
var SHELL_TOOL_NAMES2 = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
|
|
1250
|
+
var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES2.map((n) => [n, "Bash"]));
|
|
1196
1251
|
var MCP_SEP3 = "_";
|
|
1197
1252
|
var KIRO_SOURCES = { startup: "startup", resume: "resume", clear: "clear", compact: "compact" };
|
|
1198
1253
|
function canonicalName5(name) {
|
|
@@ -1333,8 +1388,8 @@ var OPENCODE_EVENTS = {
|
|
|
1333
1388
|
compaction: "PreCompact",
|
|
1334
1389
|
"step-finish": "Usage"
|
|
1335
1390
|
};
|
|
1336
|
-
var
|
|
1337
|
-
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [
|
|
1391
|
+
var SHELL_TOOL_NAME = "bash";
|
|
1392
|
+
var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME]: "Bash" };
|
|
1338
1393
|
function toCanonicalTool(name) {
|
|
1339
1394
|
if (name.startsWith(OWN_WIRE_PREFIX)) return name.slice(OWN_WIRE_PREFIX.length);
|
|
1340
1395
|
return Object.prototype.hasOwnProperty.call(NATIVE_TO_CANONICAL7, name) ? NATIVE_TO_CANONICAL7[name] : name;
|
|
@@ -1483,7 +1538,8 @@ var ADAPTERS = Object.freeze([
|
|
|
1483
1538
|
projectSource: "arg:workspaceFolder",
|
|
1484
1539
|
toolNamePrefix: TOOL_NAME_PREFIX6,
|
|
1485
1540
|
// PreCompact sets the pending flag (ADR-0009 §6, DEVIATIONS D-M3-A4-1).
|
|
1486
|
-
nativeTools: { shell: [
|
|
1541
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES], read: [...READ_TOOL_NAMES], webfetch: [...WEBFETCH_TOOL_NAMES] },
|
|
1542
|
+
// D-HF-VSCODE-PROJECT-1, D-N7-VSCODE-TOOLS-1
|
|
1487
1543
|
execReadOnlyHint: false,
|
|
1488
1544
|
eventMap: { ...CLAUDE_EVENTS, PreCompact: "PreCompact" },
|
|
1489
1545
|
compactDelivery: "pending-flag",
|
|
@@ -1501,7 +1557,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1501
1557
|
installMode: "mcp-entry",
|
|
1502
1558
|
projectSource: "arg:--agent+cwd",
|
|
1503
1559
|
toolNamePrefix: TOOL_NAME_PREFIX7,
|
|
1504
|
-
nativeTools: { shell: [...
|
|
1560
|
+
nativeTools: { shell: [...SHELL_TOOL_NAMES2] },
|
|
1505
1561
|
execReadOnlyHint: false,
|
|
1506
1562
|
// D-HF-KIRO-SHELL-1, D-N7-KIRO-1
|
|
1507
1563
|
eventMap: { SessionStart: "SessionStart", UserPromptSubmit: "UserPromptSubmit", PreToolUse: "PreToolUse", PostToolUse: "PostToolUse" },
|
|
@@ -1558,7 +1614,7 @@ var ADAPTERS = Object.freeze([
|
|
|
1558
1614
|
installMode: "in-process",
|
|
1559
1615
|
projectSource: "spawn-cwd",
|
|
1560
1616
|
toolNamePrefix: TOOL_NAME_PREFIX10,
|
|
1561
|
-
nativeTools: { shell: [
|
|
1617
|
+
nativeTools: { shell: [SHELL_TOOL_NAME] },
|
|
1562
1618
|
execReadOnlyHint: false,
|
|
1563
1619
|
// D-HF-OPENCODE-SHELL-1
|
|
1564
1620
|
// Usage: step-finish cost row (DEVIATIONS D-M5-arch-2).
|
|
@@ -2482,10 +2538,10 @@ function element(p) {
|
|
|
2482
2538
|
function pipeline(p) {
|
|
2483
2539
|
if (isWord(at(p), NOT)) p.i++;
|
|
2484
2540
|
const all = [];
|
|
2485
|
-
let
|
|
2541
|
+
let last2 = EMPTY3();
|
|
2486
2542
|
while (p.err === null) {
|
|
2487
|
-
|
|
2488
|
-
all.push(...
|
|
2543
|
+
last2 = element(p);
|
|
2544
|
+
all.push(...last2.cmds);
|
|
2489
2545
|
const t = at(p);
|
|
2490
2546
|
if (t !== void 0 && t.kind === "op" && PIPES.includes(t.text)) {
|
|
2491
2547
|
p.i++;
|
|
@@ -2493,7 +2549,7 @@ function pipeline(p) {
|
|
|
2493
2549
|
}
|
|
2494
2550
|
break;
|
|
2495
2551
|
}
|
|
2496
|
-
if (
|
|
2552
|
+
if (last2.simple !== null && isBoundedSink(last2.simple)) for (const c of all) c.endsInBoundedSink = true;
|
|
2497
2553
|
return all;
|
|
2498
2554
|
}
|
|
2499
2555
|
function list(p, stop) {
|
|
@@ -2536,27 +2592,95 @@ function parseShell(cmd) {
|
|
|
2536
2592
|
// src/core/policy/subagent.ts
|
|
2537
2593
|
import { join as join2 } from "node:path";
|
|
2538
2594
|
|
|
2595
|
+
// src/core/ops/host-text.ts
|
|
2596
|
+
var BOM_CODE = 65279;
|
|
2597
|
+
var CR_CODE = 13;
|
|
2598
|
+
var CRLF2 = "\r\n";
|
|
2599
|
+
var LF = "\n";
|
|
2600
|
+
function hostLayout(raw) {
|
|
2601
|
+
let crlf = 0;
|
|
2602
|
+
let lf = 0;
|
|
2603
|
+
for (let i = raw.indexOf(LF); i >= 0; i = raw.indexOf(LF, i + 1)) {
|
|
2604
|
+
if (i > 0 && raw.charCodeAt(i - 1) === CR_CODE) crlf += 1;
|
|
2605
|
+
else lf += 1;
|
|
2606
|
+
}
|
|
2607
|
+
return { bom: raw.length > 0 && raw.charCodeAt(0) === BOM_CODE, crlf: crlf > 0 && crlf >= lf };
|
|
2608
|
+
}
|
|
2609
|
+
function hostText(raw) {
|
|
2610
|
+
const bare2 = raw.length > 0 && raw.charCodeAt(0) === BOM_CODE ? raw.slice(1) : raw;
|
|
2611
|
+
return bare2.indexOf(CRLF2) < 0 ? bare2 : bare2.split(CRLF2).join(LF);
|
|
2612
|
+
}
|
|
2613
|
+
function withLayout(text, layout) {
|
|
2614
|
+
const eol = layout.crlf ? text.split(LF).join(CRLF2) : text;
|
|
2615
|
+
return layout.bom ? String.fromCharCode(BOM_CODE) + eol : eol;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2539
2618
|
// src/core/project/config-dir.ts
|
|
2540
|
-
import { join } from "node:path";
|
|
2619
|
+
import { join, posix, win32 } from "node:path";
|
|
2541
2620
|
var { mkdirSync, realpathSync } = process.getBuiltinModule("node:fs");
|
|
2542
|
-
function homeDirOf(env) {
|
|
2543
|
-
const
|
|
2544
|
-
if (
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2621
|
+
function homeDirOf(env, platform = process.platform) {
|
|
2622
|
+
const set3 = (v) => v !== void 0 && v !== "";
|
|
2623
|
+
if (platform === "win32") {
|
|
2624
|
+
if (set3(env.USERPROFILE)) return env.USERPROFILE;
|
|
2625
|
+
if (set3(env.HOMEDRIVE) && set3(env.HOMEPATH)) return env.HOMEDRIVE + env.HOMEPATH;
|
|
2626
|
+
return set3(env.HOME) ? env.HOME : null;
|
|
2627
|
+
}
|
|
2628
|
+
if (set3(env.HOME)) return env.HOME;
|
|
2629
|
+
return set3(env.USERPROFILE) ? env.USERPROFILE : null;
|
|
2548
2630
|
}
|
|
2549
2631
|
function codexDirOf(env, home) {
|
|
2550
2632
|
const dir = env[CODEX_HOME_ENV];
|
|
2551
2633
|
return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR.codex);
|
|
2552
2634
|
}
|
|
2553
|
-
function
|
|
2554
|
-
const
|
|
2635
|
+
function copilotDirOf(env, home) {
|
|
2636
|
+
const dir = env[COPILOT_HOME_ENV];
|
|
2637
|
+
return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR["copilot-cli"]);
|
|
2638
|
+
}
|
|
2639
|
+
function kiroDirOf(env, home, platform = process.platform) {
|
|
2640
|
+
const p = platform === "win32" ? win32 : posix;
|
|
2641
|
+
const fallback = p.join(home, ...AGENT_HOME_DIR.kiro);
|
|
2642
|
+
const dir = env[KIRO_HOME_ENV];
|
|
2643
|
+
if (dir === void 0 || dir === "" || !p.isAbsolute(dir)) return fallback;
|
|
2644
|
+
if (platform === "win32" && p.parse(dir).root.length < 2) return fallback;
|
|
2645
|
+
const abs = p.resolve(dir);
|
|
2646
|
+
if (p.dirname(abs) === abs) return fallback;
|
|
2647
|
+
const up = p.relative(abs, p.resolve(home));
|
|
2648
|
+
if (!p.isAbsolute(up) && up.split(p.sep)[0] !== "..") return fallback;
|
|
2649
|
+
return dir;
|
|
2650
|
+
}
|
|
2651
|
+
function claudeDirOf(env, home) {
|
|
2652
|
+
const dir = env[CLAUDE_CONFIG_DIR_ENV];
|
|
2653
|
+
return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR["claude-code"]);
|
|
2654
|
+
}
|
|
2655
|
+
function opencodeDirOf(env, home) {
|
|
2656
|
+
const own2 = env[OPENCODE_CONFIG_DIR_ENV];
|
|
2657
|
+
if (own2 !== void 0 && own2 !== "") return own2;
|
|
2658
|
+
const xdg = env[XDG_CONFIG_HOME_ENV];
|
|
2659
|
+
if (xdg !== void 0 && xdg !== "") return join(xdg, AGENT_HOME_DIR.opencode[AGENT_HOME_DIR.opencode.length - 1]);
|
|
2660
|
+
return join(home, ...AGENT_HOME_DIR.opencode);
|
|
2661
|
+
}
|
|
2662
|
+
function piAgentDirOf(env, home) {
|
|
2663
|
+
const dir = env[PI_AGENT_DIR_ENV];
|
|
2664
|
+
return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR);
|
|
2665
|
+
}
|
|
2666
|
+
function vscodeUserDirOf(env, home, platform = process.platform) {
|
|
2667
|
+
const set3 = (v) => v !== void 0 && v !== "";
|
|
2668
|
+
const p = platform === "win32" ? win32 : posix;
|
|
2669
|
+
if (platform === "win32") return p.join(set3(env[APPDATA_ENV]) ? env[APPDATA_ENV] : p.join(home, "AppData", "Roaming"), ...VSCODE_USER_DIR_SEGMENTS);
|
|
2670
|
+
if (platform === "darwin") return p.join(home, "Library", "Application Support", ...VSCODE_USER_DIR_SEGMENTS);
|
|
2671
|
+
return p.join(set3(env[XDG_CONFIG_HOME_ENV]) ? env[XDG_CONFIG_HOME_ENV] : p.join(home, ".config"), ...VSCODE_USER_DIR_SEGMENTS);
|
|
2672
|
+
}
|
|
2673
|
+
function ownMcpFileOf(agent, file2, env, home) {
|
|
2674
|
+
if (agent === "kiro") return join(kiroDirOf(env, home), ...file2.slice(1));
|
|
2675
|
+
return agent === "vscode" ? join(vscodeUserDirOf(env, home), ...file2) : join(home, ...file2);
|
|
2676
|
+
}
|
|
2677
|
+
function requireHomeDir(env, platform = process.platform) {
|
|
2678
|
+
const home = homeDirOf(env, platform);
|
|
2555
2679
|
if (home !== null) return home;
|
|
2556
|
-
throw new CtxError("NO_HOME", { name:
|
|
2680
|
+
throw new CtxError("NO_HOME", { name: platform === "win32" ? "USERPROFILE" : "HOME" });
|
|
2557
2681
|
}
|
|
2558
2682
|
function resolveConfigDir(env) {
|
|
2559
|
-
const dir = join(
|
|
2683
|
+
const dir = join(requireHomeDir(env), DATA_ROOT.slice(1));
|
|
2560
2684
|
mkdirSync(dir, { recursive: true });
|
|
2561
2685
|
return realpathSync.native(dir);
|
|
2562
2686
|
}
|
|
@@ -2593,11 +2717,11 @@ function findDef(type, src) {
|
|
|
2593
2717
|
const p = readAgentFile(join2(src.projectDir, HOST_CONFIG_DIR_NAME, AGENTS_DIR_NAME, type + AGENT_FILE_EXT));
|
|
2594
2718
|
if (p !== null) return p;
|
|
2595
2719
|
if (home !== null) {
|
|
2596
|
-
const u = readAgentFile(join2(
|
|
2720
|
+
const u = readAgentFile(join2(claudeDirOf(src.env, home), AGENTS_DIR_NAME, type + AGENT_FILE_EXT));
|
|
2597
2721
|
if (u !== null) return u;
|
|
2598
2722
|
}
|
|
2599
2723
|
} else if (home !== null) {
|
|
2600
|
-
const pl = readPluginAgent(home, type);
|
|
2724
|
+
const pl = readPluginAgent(claudeDirOf(src.env, home), type);
|
|
2601
2725
|
if (pl !== null) return pl;
|
|
2602
2726
|
}
|
|
2603
2727
|
const cli = src.cliAgents;
|
|
@@ -2616,14 +2740,14 @@ function safeType(type) {
|
|
|
2616
2740
|
function homeDir(env) {
|
|
2617
2741
|
return homeDirOf(env);
|
|
2618
2742
|
}
|
|
2619
|
-
function readPluginAgent(
|
|
2743
|
+
function readPluginAgent(claudeDir, type) {
|
|
2620
2744
|
const cut = type.indexOf(PLUGIN_AGENT_SEPARATOR);
|
|
2621
2745
|
const plugin = type.slice(0, cut);
|
|
2622
2746
|
const agent = type.slice(cut + PLUGIN_AGENT_SEPARATOR.length);
|
|
2623
2747
|
if (agent.indexOf(PLUGIN_AGENT_SEPARATOR) >= 0) return null;
|
|
2624
2748
|
let parsed;
|
|
2625
2749
|
try {
|
|
2626
|
-
parsed = JSON.parse(readFileSync(join2(
|
|
2750
|
+
parsed = JSON.parse(hostText(readFileSync(join2(claudeDir, HOST_PLUGINS_DIR_NAME, INSTALLED_PLUGINS_FILE), "utf8")));
|
|
2627
2751
|
} catch {
|
|
2628
2752
|
return null;
|
|
2629
2753
|
}
|
|
@@ -2643,10 +2767,10 @@ function readPluginAgent(home, type) {
|
|
|
2643
2767
|
}
|
|
2644
2768
|
return null;
|
|
2645
2769
|
}
|
|
2646
|
-
function readAgentFile(
|
|
2770
|
+
function readAgentFile(path5) {
|
|
2647
2771
|
let text;
|
|
2648
2772
|
try {
|
|
2649
|
-
text = readFileSync(
|
|
2773
|
+
text = readFileSync(path5, "utf8");
|
|
2650
2774
|
} catch {
|
|
2651
2775
|
return null;
|
|
2652
2776
|
}
|
|
@@ -2856,7 +2980,6 @@ function unwrap(commands) {
|
|
|
2856
2980
|
import { isAbsolute, join as join3, relative, sep } from "node:path";
|
|
2857
2981
|
var { readFileSync: readFileSync2 } = process.getBuiltinModule("node:fs");
|
|
2858
2982
|
var CLAUDE_DIR = ".claude";
|
|
2859
|
-
var CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR";
|
|
2860
2983
|
var LOCAL_SETTINGS = "settings.local.json";
|
|
2861
2984
|
var SETTINGS = "settings.json";
|
|
2862
2985
|
var BASH_TOOL = "Bash";
|
|
@@ -2870,9 +2993,9 @@ var WHITESPACE = " \n\r";
|
|
|
2870
2993
|
var BASH_SUBJECT = Object.freeze({ tool: BASH_TOOL });
|
|
2871
2994
|
function denyFiles(projectDir, agent) {
|
|
2872
2995
|
if (agent !== "claude-code") return [];
|
|
2873
|
-
const cfg = process.env[CLAUDE_CONFIG_DIR_ENV];
|
|
2874
2996
|
const home = homeDirOf(process.env);
|
|
2875
|
-
const
|
|
2997
|
+
const cfg = process.env[CLAUDE_CONFIG_DIR_ENV];
|
|
2998
|
+
const userDir = cfg !== void 0 && cfg !== "" ? cfg : home === null ? null : claudeDirOf(process.env, home);
|
|
2876
2999
|
const project = [join3(projectDir, CLAUDE_DIR, LOCAL_SETTINGS), join3(projectDir, CLAUDE_DIR, SETTINGS)];
|
|
2877
3000
|
return userDir === null ? project : [...project, join3(userDir, SETTINGS)];
|
|
2878
3001
|
}
|
|
@@ -2882,7 +3005,7 @@ function isObject(v) {
|
|
|
2882
3005
|
function readOne(file2) {
|
|
2883
3006
|
let text;
|
|
2884
3007
|
try {
|
|
2885
|
-
text = readFileSync2(file2, "utf8");
|
|
3008
|
+
text = hostText(readFileSync2(file2, "utf8"));
|
|
2886
3009
|
} catch (err) {
|
|
2887
3010
|
return err.code === "ENOENT" ? { kind: "absent" } : { kind: "bad" };
|
|
2888
3011
|
}
|
|
@@ -2910,12 +3033,12 @@ function readUserDeny(projectDir, agent) {
|
|
|
2910
3033
|
}
|
|
2911
3034
|
return out;
|
|
2912
3035
|
}
|
|
2913
|
-
function tokenize(glob,
|
|
3036
|
+
function tokenize(glob, path5) {
|
|
2914
3037
|
const toks = [];
|
|
2915
3038
|
let i = 0;
|
|
2916
3039
|
while (i < glob.length) {
|
|
2917
3040
|
const c = glob[i];
|
|
2918
|
-
if (c === "*" &&
|
|
3041
|
+
if (c === "*" && path5 && glob[i + 1] === "*") {
|
|
2919
3042
|
const dir = glob[i + "**".length] === "/";
|
|
2920
3043
|
toks.push({ t: dir ? "globstarDir" : "globstar" });
|
|
2921
3044
|
i += dir ? "**/".length : "**".length;
|
|
@@ -2929,8 +3052,8 @@ function tokenize(glob, path4) {
|
|
|
2929
3052
|
}
|
|
2930
3053
|
return toks;
|
|
2931
3054
|
}
|
|
2932
|
-
function globMatch(glob, text,
|
|
2933
|
-
const toks = tokenize(glob,
|
|
3055
|
+
function globMatch(glob, text, path5) {
|
|
3056
|
+
const toks = tokenize(glob, path5);
|
|
2934
3057
|
const n = text.length;
|
|
2935
3058
|
let next = new Uint8Array(n + 1);
|
|
2936
3059
|
next[n] = 1;
|
|
@@ -2946,10 +3069,10 @@ function globMatch(glob, text, path4) {
|
|
|
2946
3069
|
cur[j] = has2 && ch === tok.c ? next[j + 1] : 0;
|
|
2947
3070
|
break;
|
|
2948
3071
|
case "any1":
|
|
2949
|
-
cur[j] = has2 && !(
|
|
3072
|
+
cur[j] = has2 && !(path5 && ch === "/") ? next[j + 1] : 0;
|
|
2950
3073
|
break;
|
|
2951
3074
|
case "star":
|
|
2952
|
-
cur[j] = next[j] || (has2 && !(
|
|
3075
|
+
cur[j] = next[j] || (has2 && !(path5 && ch === "/") ? cur[j + 1] : 0);
|
|
2953
3076
|
break;
|
|
2954
3077
|
case "globstar":
|
|
2955
3078
|
cur[j] = next[j] || (has2 ? cur[j + 1] : 0);
|
|
@@ -3029,8 +3152,8 @@ var READ_DENY_TEMPLATE = 'context-mode: {size}-byte file, over the one-read limi
|
|
|
3029
3152
|
// src/core/policy/read-deny.ts
|
|
3030
3153
|
var SIZE = "{size}";
|
|
3031
3154
|
var PATH = "{path}";
|
|
3032
|
-
function READ_DENY_MESSAGE(
|
|
3033
|
-
return prefixToolNames(READ_DENY_TEMPLATE, prefix).split(SIZE).join(String(size)).split(PATH).join(
|
|
3155
|
+
function READ_DENY_MESSAGE(path5, size, prefix = "") {
|
|
3156
|
+
return prefixToolNames(READ_DENY_TEMPLATE, prefix).split(SIZE).join(String(size)).split(PATH).join(path5);
|
|
3034
3157
|
}
|
|
3035
3158
|
|
|
3036
3159
|
// src/core/policy/decide.ts
|
|
@@ -3517,7 +3640,7 @@ function firstLine(file2) {
|
|
|
3517
3640
|
}
|
|
3518
3641
|
function git(dir, args) {
|
|
3519
3642
|
const { spawnSync } = process.getBuiltinModule("node:child_process");
|
|
3520
|
-
const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
3643
|
+
const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
|
|
3521
3644
|
if (r.error !== void 0 || r.status !== 0) throw new CtxError("NO_GIT_DIR", { path: dir });
|
|
3522
3645
|
return r.stdout.split("\n").filter((l) => l !== "");
|
|
3523
3646
|
}
|
|
@@ -3709,9 +3832,9 @@ function readUserVersion(raw) {
|
|
|
3709
3832
|
const row5 = raw.prepare("PRAGMA user_version").get();
|
|
3710
3833
|
return row5.user_version;
|
|
3711
3834
|
}
|
|
3712
|
-
function createAtomically(sqlite,
|
|
3835
|
+
function createAtomically(sqlite, path5) {
|
|
3713
3836
|
const { randomUUID } = process.getBuiltinModule("node:crypto");
|
|
3714
|
-
const tmp =
|
|
3837
|
+
const tmp = path5 + "." + randomUUID() + DB_TMP_SUFFIX;
|
|
3715
3838
|
try {
|
|
3716
3839
|
const raw = new sqlite.DatabaseSync(tmp, { timeout: DB_TIMEOUT_MS });
|
|
3717
3840
|
try {
|
|
@@ -3720,7 +3843,7 @@ function createAtomically(sqlite, path4) {
|
|
|
3720
3843
|
raw.close();
|
|
3721
3844
|
}
|
|
3722
3845
|
try {
|
|
3723
|
-
linkSync(tmp,
|
|
3846
|
+
linkSync(tmp, path5);
|
|
3724
3847
|
} catch (err) {
|
|
3725
3848
|
if (err.code !== "EEXIST") throw err;
|
|
3726
3849
|
}
|
|
@@ -3728,11 +3851,11 @@ function createAtomically(sqlite, path4) {
|
|
|
3728
3851
|
for (const suffix of ["", DB_WAL_SUFFIX, DB_SHM_SUFFIX]) rmSync(tmp + suffix, { force: true });
|
|
3729
3852
|
}
|
|
3730
3853
|
}
|
|
3731
|
-
function openWritable(sqlite,
|
|
3854
|
+
function openWritable(sqlite, path5) {
|
|
3732
3855
|
let raw = null;
|
|
3733
3856
|
try {
|
|
3734
|
-
if (!existsSync2(
|
|
3735
|
-
raw = new sqlite.DatabaseSync(
|
|
3857
|
+
if (!existsSync2(path5)) createAtomically(sqlite, path5);
|
|
3858
|
+
raw = new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS });
|
|
3736
3859
|
applyMigrations(raw, readUserVersion(raw));
|
|
3737
3860
|
return raw;
|
|
3738
3861
|
} catch (err) {
|
|
@@ -3740,8 +3863,8 @@ function openWritable(sqlite, path4) {
|
|
|
3740
3863
|
throw err;
|
|
3741
3864
|
}
|
|
3742
3865
|
}
|
|
3743
|
-
function openReadOnly(sqlite,
|
|
3744
|
-
const raw = new sqlite.DatabaseSync(
|
|
3866
|
+
function openReadOnly(sqlite, path5) {
|
|
3867
|
+
const raw = new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS, readOnly: true });
|
|
3745
3868
|
try {
|
|
3746
3869
|
const found = readUserVersion(raw);
|
|
3747
3870
|
if (found !== SCHEMA_VERSION) throw new CtxError("SCHEMA_STALE", { found, want: SCHEMA_VERSION });
|
|
@@ -3755,20 +3878,20 @@ async function openDb(project, opts) {
|
|
|
3755
3878
|
if (isBelow(process.version, NODE_MIN)) throw new CtxError("NODE_TOO_OLD", { v: process.version });
|
|
3756
3879
|
const sqlite = await loadSqlite();
|
|
3757
3880
|
mkdirSync2(project.projectDir, { recursive: true });
|
|
3758
|
-
const
|
|
3759
|
-
const sibling = existsSync2(
|
|
3760
|
-
if (sibling && !existsSync2(
|
|
3881
|
+
const path5 = project.dbPath;
|
|
3882
|
+
const sibling = existsSync2(path5 + DB_WAL_SUFFIX) || existsSync2(path5 + DB_SHM_SUFFIX);
|
|
3883
|
+
if (sibling && !existsSync2(path5)) {
|
|
3761
3884
|
throw new CtxError("DB_GONE");
|
|
3762
3885
|
}
|
|
3763
3886
|
try {
|
|
3764
3887
|
let raw;
|
|
3765
3888
|
if (opts?.readOnly === true) {
|
|
3766
|
-
if (!existsSync2(
|
|
3767
|
-
raw = openReadOnly(sqlite,
|
|
3889
|
+
if (!existsSync2(path5)) openWritable(sqlite, path5).close();
|
|
3890
|
+
raw = openReadOnly(sqlite, path5);
|
|
3768
3891
|
} else {
|
|
3769
|
-
raw = openWritable(sqlite,
|
|
3892
|
+
raw = openWritable(sqlite, path5);
|
|
3770
3893
|
}
|
|
3771
|
-
return { raw, projectKey: project.projectKey, path:
|
|
3894
|
+
return { raw, projectKey: project.projectKey, path: path5 };
|
|
3772
3895
|
} catch (err) {
|
|
3773
3896
|
if (isCorrupt(err)) throw new CtxError("DB_CORRUPT");
|
|
3774
3897
|
throw err;
|
|
@@ -5805,9 +5928,9 @@ function isWordChar2(cp) {
|
|
|
5805
5928
|
while (lo <= hi) {
|
|
5806
5929
|
const mid = lo + hi >> 1;
|
|
5807
5930
|
const first = WORD_RANGES[2 * mid];
|
|
5808
|
-
const
|
|
5931
|
+
const last2 = WORD_RANGES[2 * mid + 1];
|
|
5809
5932
|
if (cp < first) hi = mid - 1;
|
|
5810
|
-
else if (cp >
|
|
5933
|
+
else if (cp > last2) lo = mid + 1;
|
|
5811
5934
|
else return true;
|
|
5812
5935
|
}
|
|
5813
5936
|
return false;
|
|
@@ -6306,8 +6429,8 @@ function ftsQueryTimeline(db, scope, ctx, sessionId, limit, after, source, memor
|
|
|
6306
6429
|
merged.sort(timelineOrder);
|
|
6307
6430
|
let end = Math.min(limit, merged.length);
|
|
6308
6431
|
if (end > 0) {
|
|
6309
|
-
const
|
|
6310
|
-
while (end < merged.length && merged[end].ts ===
|
|
6432
|
+
const last2 = merged[end - 1].ts;
|
|
6433
|
+
while (end < merged.length && merged[end].ts === last2) end++;
|
|
6311
6434
|
}
|
|
6312
6435
|
const rows = merged.slice(0, end);
|
|
6313
6436
|
if (rows.length === 0) return { rows, more: false };
|
|
@@ -6446,8 +6569,8 @@ function buildCandidates(rows, sessionId) {
|
|
|
6446
6569
|
if (!sessionId) return emptySet();
|
|
6447
6570
|
const own2 = rows.filter((r) => r.session_id === sessionId).sort((a, b) => a.seq - b.seq);
|
|
6448
6571
|
const prompts = own2.filter((r) => r.kind === "prompt");
|
|
6449
|
-
const
|
|
6450
|
-
const lastRequest =
|
|
6572
|
+
const last2 = prompts.length > 0 ? prompts[prompts.length - 1] : void 0;
|
|
6573
|
+
const lastRequest = last2 === void 0 ? null : make("last_request", last2, "now: " + firstLine2(last2.body), 1, null);
|
|
6451
6574
|
const earlierRequests = prompts.slice(0, prompts.length - 1).map((r) => make("earlier_requests", r, "asked #" + r.seq + ": " + firstLine2(r.body), 1, null));
|
|
6452
6575
|
const failures = /* @__PURE__ */ new Map();
|
|
6453
6576
|
const lastOk = /* @__PURE__ */ new Map();
|
|
@@ -6471,8 +6594,8 @@ function buildCandidates(rows, sessionId) {
|
|
|
6471
6594
|
edits.set(r.path, { row: r, count: (edits.get(r.path)?.count ?? 0) + 1 });
|
|
6472
6595
|
}
|
|
6473
6596
|
const changedFiles = [];
|
|
6474
|
-
for (const [
|
|
6475
|
-
const c = make("changed_files", e.row, "edited " +
|
|
6597
|
+
for (const [path5, e] of edits) {
|
|
6598
|
+
const c = make("changed_files", e.row, "edited " + path5 + " x" + e.count, e.count, path5);
|
|
6476
6599
|
changedFiles.push({ ...c, editCount: e.count });
|
|
6477
6600
|
}
|
|
6478
6601
|
changedFiles.sort((a, b) => a.seq - b.seq);
|
|
@@ -6486,7 +6609,7 @@ function buildCandidates(rows, sessionId) {
|
|
|
6486
6609
|
for (const [key, d] of decided) decisions.push(make("decisions", d.row, "decided #" + d.row.seq + ": " + firstLine2(d.row.body), d.count, key));
|
|
6487
6610
|
decisions.sort((a, b) => a.seq - b.seq);
|
|
6488
6611
|
const indexedSources = own2.filter((r) => r.kind === "index").map((r) => make("indexed_sources", r, "indexed " + (r.key ?? ""), 1, r.key));
|
|
6489
|
-
const
|
|
6612
|
+
const set3 = {
|
|
6490
6613
|
lastRequest,
|
|
6491
6614
|
openErrors: capSection(openErrors),
|
|
6492
6615
|
changedFiles: capSection(changedFiles),
|
|
@@ -6494,17 +6617,17 @@ function buildCandidates(rows, sessionId) {
|
|
|
6494
6617
|
earlierRequests: capSection(earlierRequests),
|
|
6495
6618
|
indexedSources: capSection(indexedSources)
|
|
6496
6619
|
};
|
|
6497
|
-
const rest = [...
|
|
6620
|
+
const rest = [...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources];
|
|
6498
6621
|
const total = rest.length + (lastRequest === null ? 0 : 1);
|
|
6499
|
-
if (total <= MAX_CANDIDATES_TOTAL) return
|
|
6622
|
+
if (total <= MAX_CANDIDATES_TOTAL) return set3;
|
|
6500
6623
|
const drop = new Set(rest.map((c) => c.seq).sort((a, b) => a - b).slice(0, total - MAX_CANDIDATES_TOTAL));
|
|
6501
6624
|
return {
|
|
6502
6625
|
lastRequest,
|
|
6503
|
-
openErrors:
|
|
6504
|
-
changedFiles:
|
|
6505
|
-
decisions:
|
|
6506
|
-
earlierRequests:
|
|
6507
|
-
indexedSources:
|
|
6626
|
+
openErrors: set3.openErrors.filter((c) => !drop.has(c.seq)),
|
|
6627
|
+
changedFiles: set3.changedFiles.filter((c) => !drop.has(c.seq)),
|
|
6628
|
+
decisions: set3.decisions.filter((c) => !drop.has(c.seq)),
|
|
6629
|
+
earlierRequests: set3.earlierRequests.filter((c) => !drop.has(c.seq)),
|
|
6630
|
+
indexedSources: set3.indexedSources.filter((c) => !drop.has(c.seq))
|
|
6508
6631
|
};
|
|
6509
6632
|
}
|
|
6510
6633
|
|
|
@@ -6629,15 +6752,15 @@ function renderState(rows, turn, extras, prefix = "") {
|
|
|
6629
6752
|
for (const r of rows) if (newest === void 0 || r.seq > newest.seq) newest = r;
|
|
6630
6753
|
const sessionId = newest === void 0 ? "" : newest.session_id;
|
|
6631
6754
|
const upto = newest === void 0 || sessionId === "" ? 0 : newest.seq;
|
|
6632
|
-
const
|
|
6755
|
+
const set3 = buildCandidates(rows, sessionId);
|
|
6633
6756
|
const openTag = `<context_mode_state session="${sessionId}" upto="${upto}">`;
|
|
6634
6757
|
const emptyMoreBytes = bytesOf2(moreLine([], prefix));
|
|
6635
6758
|
const budget = STATE_BUDGET - (bytesOf2(openTag) + 1 + emptyMoreBytes + 1 + bytesOf2(STATE_CLOSE_TAG));
|
|
6636
6759
|
let used = 0;
|
|
6637
|
-
const pinnedLine =
|
|
6760
|
+
const pinnedLine = set3.lastRequest === null ? null : lineOf(set3.lastRequest, prefix);
|
|
6638
6761
|
if (pinnedLine !== null) used += bytesOf2(pinnedLine) + 1;
|
|
6639
6762
|
const remaining = scoreCandidates(
|
|
6640
|
-
[...
|
|
6763
|
+
[...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources],
|
|
6641
6764
|
turn
|
|
6642
6765
|
);
|
|
6643
6766
|
const k = /* @__PURE__ */ new Map();
|
|
@@ -7637,9 +7760,9 @@ function askDetached(ev, project, tool, text) {
|
|
|
7637
7760
|
void openDb(project).then((db) => {
|
|
7638
7761
|
if (parts.length > 0) return writeDecisions(db, ev, project, parts);
|
|
7639
7762
|
const prompts = readSessionEvents(db, ev.sessionId, "prompt");
|
|
7640
|
-
const
|
|
7641
|
-
if (
|
|
7642
|
-
metaSet(db, optionsKey(ev.sessionId), JSON.stringify({ seq:
|
|
7763
|
+
const last2 = prompts[prompts.length - 1];
|
|
7764
|
+
if (last2 === void 0 || ev.sessionId === "") return;
|
|
7765
|
+
metaSet(db, optionsKey(ev.sessionId), JSON.stringify({ seq: last2.seq, labels }));
|
|
7643
7766
|
}).catch((err) => {
|
|
7644
7767
|
process.stderr.write("hooks: decision write failed: " + message(err) + "\n");
|
|
7645
7768
|
});
|
|
@@ -8443,10 +8566,10 @@ function jsonStringifyReplacer(_, value) {
|
|
|
8443
8566
|
return value;
|
|
8444
8567
|
}
|
|
8445
8568
|
function cached(getter) {
|
|
8446
|
-
const
|
|
8569
|
+
const set3 = false;
|
|
8447
8570
|
return {
|
|
8448
8571
|
get value() {
|
|
8449
|
-
if (!
|
|
8572
|
+
if (!set3) {
|
|
8450
8573
|
const value = getter();
|
|
8451
8574
|
Object.defineProperty(this, "value", { value });
|
|
8452
8575
|
return value;
|
|
@@ -8472,10 +8595,10 @@ function floatSafeRemainder(val, step) {
|
|
|
8472
8595
|
return valInt % stepInt / 10 ** decCount;
|
|
8473
8596
|
}
|
|
8474
8597
|
function defineLazy(object2, key, getter) {
|
|
8475
|
-
const
|
|
8598
|
+
const set3 = false;
|
|
8476
8599
|
Object.defineProperty(object2, key, {
|
|
8477
8600
|
get() {
|
|
8478
|
-
if (!
|
|
8601
|
+
if (!set3) {
|
|
8479
8602
|
const value = getter();
|
|
8480
8603
|
object2[key] = value;
|
|
8481
8604
|
return value;
|
|
@@ -8499,10 +8622,10 @@ function assignProp(target, prop, value) {
|
|
|
8499
8622
|
configurable: true
|
|
8500
8623
|
});
|
|
8501
8624
|
}
|
|
8502
|
-
function getElementAtPath(obj,
|
|
8503
|
-
if (!
|
|
8625
|
+
function getElementAtPath(obj, path5) {
|
|
8626
|
+
if (!path5)
|
|
8504
8627
|
return obj;
|
|
8505
|
-
return
|
|
8628
|
+
return path5.reduce((acc, key) => acc?.[key], obj);
|
|
8506
8629
|
}
|
|
8507
8630
|
function promiseAllObject(promisesObj) {
|
|
8508
8631
|
const keys = Object.keys(promisesObj);
|
|
@@ -8822,11 +8945,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8822
8945
|
}
|
|
8823
8946
|
return false;
|
|
8824
8947
|
}
|
|
8825
|
-
function prefixIssues(
|
|
8948
|
+
function prefixIssues(path5, issues) {
|
|
8826
8949
|
return issues.map((iss) => {
|
|
8827
8950
|
var _a;
|
|
8828
8951
|
(_a = iss).path ?? (_a.path = []);
|
|
8829
|
-
iss.path.unshift(
|
|
8952
|
+
iss.path.unshift(path5);
|
|
8830
8953
|
return iss;
|
|
8831
8954
|
});
|
|
8832
8955
|
}
|
|
@@ -8963,7 +9086,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8963
9086
|
return issue2.message;
|
|
8964
9087
|
};
|
|
8965
9088
|
const result = { errors: [] };
|
|
8966
|
-
const processError = (error41,
|
|
9089
|
+
const processError = (error41, path5 = []) => {
|
|
8967
9090
|
var _a, _b;
|
|
8968
9091
|
for (const issue2 of error41.issues) {
|
|
8969
9092
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -8973,7 +9096,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8973
9096
|
} else if (issue2.code === "invalid_element") {
|
|
8974
9097
|
processError({ issues: issue2.issues }, issue2.path);
|
|
8975
9098
|
} else {
|
|
8976
|
-
const fullpath = [...
|
|
9099
|
+
const fullpath = [...path5, ...issue2.path];
|
|
8977
9100
|
if (fullpath.length === 0) {
|
|
8978
9101
|
result.errors.push(mapper(issue2));
|
|
8979
9102
|
continue;
|
|
@@ -9003,9 +9126,9 @@ function treeifyError(error40, _mapper) {
|
|
|
9003
9126
|
processError(error40);
|
|
9004
9127
|
return result;
|
|
9005
9128
|
}
|
|
9006
|
-
function toDotPath(
|
|
9129
|
+
function toDotPath(path5) {
|
|
9007
9130
|
const segs = [];
|
|
9008
|
-
for (const seg of
|
|
9131
|
+
for (const seg of path5) {
|
|
9009
9132
|
if (typeof seg === "number")
|
|
9010
9133
|
segs.push(`[${seg}]`);
|
|
9011
9134
|
else if (typeof seg === "symbol")
|
|
@@ -10345,8 +10468,8 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
|
|
|
10345
10468
|
}
|
|
10346
10469
|
const input = payload.value;
|
|
10347
10470
|
const isDate = input instanceof Date;
|
|
10348
|
-
const
|
|
10349
|
-
if (
|
|
10471
|
+
const isValidDate2 = isDate && !Number.isNaN(input.getTime());
|
|
10472
|
+
if (isValidDate2)
|
|
10350
10473
|
return payload;
|
|
10351
10474
|
payload.issues.push({
|
|
10352
10475
|
expected: "date",
|
|
@@ -19027,6 +19150,14 @@ function buildChildEnv(parent, extra) {
|
|
|
19027
19150
|
// src/core/sandbox/runtimes.ts
|
|
19028
19151
|
import { accessSync, constants as fsConstants, statSync as statSync3 } from "node:fs";
|
|
19029
19152
|
import path from "node:path";
|
|
19153
|
+
|
|
19154
|
+
// src/core/sandbox/path-entries.ts
|
|
19155
|
+
function pathEntries(value, platform = process.platform, delimiter = platform === "win32" ? ";" : ":") {
|
|
19156
|
+
const win = platform === "win32";
|
|
19157
|
+
return value.split(delimiter).map((e) => win && e.length >= 2 && e.startsWith('"') && e.endsWith('"') ? e.slice(1, -1) : e).filter(Boolean);
|
|
19158
|
+
}
|
|
19159
|
+
|
|
19160
|
+
// src/core/sandbox/runtimes.ts
|
|
19030
19161
|
var PATHEXT_SEPARATOR = ";";
|
|
19031
19162
|
var WIN_STARTABLE_EXT = Object.freeze([".exe", ".com"]);
|
|
19032
19163
|
function isWin() {
|
|
@@ -19036,7 +19167,7 @@ function candidates(lang) {
|
|
|
19036
19167
|
const win = isWin();
|
|
19037
19168
|
switch (lang) {
|
|
19038
19169
|
case "shell":
|
|
19039
|
-
return win ? [
|
|
19170
|
+
return win ? [] : ["sh"];
|
|
19040
19171
|
case "powershell":
|
|
19041
19172
|
return ["pwsh", "pwsh.exe", "powershell.exe"];
|
|
19042
19173
|
case "javascript":
|
|
@@ -19067,7 +19198,8 @@ function isRunnable(full) {
|
|
|
19067
19198
|
}
|
|
19068
19199
|
}
|
|
19069
19200
|
function findRuntime(lang, env = process.env) {
|
|
19070
|
-
|
|
19201
|
+
if (isWin() && WIN_SHELL_LANGS.includes(lang)) return findGitBash(env);
|
|
19202
|
+
const dirs = pathEntries(env.PATH ?? "", process.platform, path.delimiter);
|
|
19071
19203
|
const pathExt = isWin() ? (env.PATHEXT ?? PATHEXT_DEFAULT).split(PATHEXT_SEPARATOR).filter((e) => e !== "") : [];
|
|
19072
19204
|
const names = candidates(lang);
|
|
19073
19205
|
let shim = null;
|
|
@@ -19083,6 +19215,18 @@ function findRuntime(lang, env = process.env) {
|
|
|
19083
19215
|
}
|
|
19084
19216
|
return shim;
|
|
19085
19217
|
}
|
|
19218
|
+
function findGitBash(env) {
|
|
19219
|
+
const git3 = findRuntime(GIT_BIN, env);
|
|
19220
|
+
if (git3 === null) return null;
|
|
19221
|
+
for (const rel of GIT_BASH_RELATIVE) {
|
|
19222
|
+
const full = path.resolve(path.dirname(git3), ...rel);
|
|
19223
|
+
if (isRunnable(full)) return full;
|
|
19224
|
+
}
|
|
19225
|
+
return null;
|
|
19226
|
+
}
|
|
19227
|
+
function noRuntimeError(lang) {
|
|
19228
|
+
return isWin() && WIN_SHELL_LANGS.includes(lang) ? new CtxError("NO_GIT_BASH") : new CtxError("NO_RUNTIME", { lang });
|
|
19229
|
+
}
|
|
19086
19230
|
|
|
19087
19231
|
// src/core/sandbox/spawn.ts
|
|
19088
19232
|
import { spawn } from "node:child_process";
|
|
@@ -19190,19 +19334,19 @@ function readAutoMemory(project) {
|
|
|
19190
19334
|
if (project.agent !== "claude-code") return [];
|
|
19191
19335
|
const rows = [];
|
|
19192
19336
|
for (const segs of CLAUDE_CODE_MEMORY_FILES) {
|
|
19193
|
-
const
|
|
19194
|
-
if (!isInside(project.worktree,
|
|
19337
|
+
const path5 = join6(project.worktree, ...segs);
|
|
19338
|
+
if (!isInside(project.worktree, path5)) continue;
|
|
19195
19339
|
try {
|
|
19196
|
-
const st = statSync4(
|
|
19340
|
+
const st = statSync4(path5);
|
|
19197
19341
|
if (!st.isFile()) continue;
|
|
19198
19342
|
rows.push({
|
|
19199
19343
|
origin: "memory",
|
|
19200
19344
|
ts: Math.trunc(st.mtimeMs),
|
|
19201
19345
|
seq: null,
|
|
19202
19346
|
sourceId: null,
|
|
19203
|
-
path:
|
|
19347
|
+
path: path5,
|
|
19204
19348
|
label: segs.join("/"),
|
|
19205
|
-
text: readFileSync5(
|
|
19349
|
+
text: readFileSync5(path5, "utf8")
|
|
19206
19350
|
});
|
|
19207
19351
|
} catch {
|
|
19208
19352
|
}
|
|
@@ -19453,7 +19597,7 @@ function stoppedAt(cmd, error40) {
|
|
|
19453
19597
|
return { head: headOf(cmd), block: headOf(cmd) + error40, exitCode: null, bytes: 0, error: error40 };
|
|
19454
19598
|
}
|
|
19455
19599
|
async function runCommand(cmd, shell, ctx, deadline, boundMs) {
|
|
19456
|
-
if (shell === null) return stoppedAt(cmd,
|
|
19600
|
+
if (shell === null) return stoppedAt(cmd, noRuntimeError(SHELL).toLine());
|
|
19457
19601
|
const left = deadline - Date.now();
|
|
19458
19602
|
if (left <= 0) return stoppedAt(cmd, formatError("TIMEOUT", { ms: boundMs }));
|
|
19459
19603
|
const r = await runProcess([shell, SHELL_INLINE_FLAG, cmd], {
|
|
@@ -19573,19 +19717,19 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
|
|
|
19573
19717
|
const shell = findRuntime(SHELL);
|
|
19574
19718
|
const pool = await runPool(commands.map((c) => () => runCommand(c, shell, ctx, deadline, boundMs)), ONE_AT_A_TIME, (r) => r.error !== null);
|
|
19575
19719
|
const ran = pool.results;
|
|
19576
|
-
const
|
|
19720
|
+
const last2 = ran[ran.length - 1];
|
|
19577
19721
|
const sandboxBytes = ran.reduce((n, r) => n + r.bytes, 0);
|
|
19578
19722
|
const label = LABEL_PREFIX + ctx.turn;
|
|
19579
19723
|
try {
|
|
19580
19724
|
const db = await openDb(ctx.project);
|
|
19581
19725
|
let sections;
|
|
19582
19726
|
let idx;
|
|
19583
|
-
const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " +
|
|
19727
|
+
const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " + last2.exitCode;
|
|
19584
19728
|
const footer = "more: ctx_search({queries:[...], source:" + JSON.stringify(label) + "})";
|
|
19585
19729
|
let notice;
|
|
19586
19730
|
try {
|
|
19587
19731
|
idx = indexCombined(db, ctx, label, ran, deadline, budgetBytes);
|
|
19588
|
-
const stop =
|
|
19732
|
+
const stop = last2.error;
|
|
19589
19733
|
const cut = idx.indexed < idx.total ? "Indexed " + idx.indexed + " of " + idx.total + " B." : null;
|
|
19590
19734
|
const timeout = formatError("TIMEOUT", { ms: boundMs });
|
|
19591
19735
|
const cause = stop ?? (ctx.signal.aborted ? CANCELLED_LINE : idx.stop === "deadline" ? timeout : null);
|
|
@@ -19603,7 +19747,7 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
|
|
|
19603
19747
|
isError: false,
|
|
19604
19748
|
// step 11
|
|
19605
19749
|
sandboxBytes,
|
|
19606
|
-
journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code:
|
|
19750
|
+
journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code: last2.exitCode }
|
|
19607
19751
|
};
|
|
19608
19752
|
} catch (err) {
|
|
19609
19753
|
if (err instanceof CtxError) return { text: err.toLine(), isError: true, sandboxBytes };
|
|
@@ -19627,305 +19771,2134 @@ import { basename as basename3, dirname as dirname6, join as join12 } from "node
|
|
|
19627
19771
|
import { join as join10 } from "node:path";
|
|
19628
19772
|
|
|
19629
19773
|
// src/core/ops/detect-v1.ts
|
|
19630
|
-
import { existsSync as
|
|
19774
|
+
import { existsSync as existsSync4, opendirSync, readdirSync, readFileSync as readFileSync7 } from "node:fs";
|
|
19631
19775
|
import { tmpdir } from "node:os";
|
|
19632
|
-
import { join as
|
|
19633
|
-
|
|
19634
|
-
|
|
19635
|
-
|
|
19636
|
-
|
|
19637
|
-
|
|
19638
|
-
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
|
|
19644
|
-
|
|
19645
|
-
|
|
19646
|
-
|
|
19647
|
-
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19660
|
-
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19776
|
+
import { join as join8 } from "node:path";
|
|
19777
|
+
|
|
19778
|
+
// src/core/ops/host-config.ts
|
|
19779
|
+
import { existsSync as existsSync3, readFileSync as readFileSync6 } from "node:fs";
|
|
19780
|
+
import { dirname as dirname4, join as join7 } from "node:path";
|
|
19781
|
+
|
|
19782
|
+
// node_modules/eslint-visitor-keys/lib/visitor-keys.js
|
|
19783
|
+
var KEYS2 = {
|
|
19784
|
+
ArrayExpression: ["elements"],
|
|
19785
|
+
ArrayPattern: ["elements"],
|
|
19786
|
+
ArrowFunctionExpression: ["params", "body"],
|
|
19787
|
+
AssignmentExpression: ["left", "right"],
|
|
19788
|
+
AssignmentPattern: ["left", "right"],
|
|
19789
|
+
AwaitExpression: ["argument"],
|
|
19790
|
+
BinaryExpression: ["left", "right"],
|
|
19791
|
+
BlockStatement: ["body"],
|
|
19792
|
+
BreakStatement: ["label"],
|
|
19793
|
+
CallExpression: ["callee", "arguments"],
|
|
19794
|
+
CatchClause: ["param", "body"],
|
|
19795
|
+
ChainExpression: ["expression"],
|
|
19796
|
+
ClassBody: ["body"],
|
|
19797
|
+
ClassDeclaration: ["id", "superClass", "body"],
|
|
19798
|
+
ClassExpression: ["id", "superClass", "body"],
|
|
19799
|
+
ConditionalExpression: ["test", "consequent", "alternate"],
|
|
19800
|
+
ContinueStatement: ["label"],
|
|
19801
|
+
DebuggerStatement: [],
|
|
19802
|
+
DoWhileStatement: ["body", "test"],
|
|
19803
|
+
EmptyStatement: [],
|
|
19804
|
+
ExperimentalRestProperty: ["argument"],
|
|
19805
|
+
ExperimentalSpreadProperty: ["argument"],
|
|
19806
|
+
ExportAllDeclaration: ["exported", "source", "attributes"],
|
|
19807
|
+
ExportDefaultDeclaration: ["declaration"],
|
|
19808
|
+
ExportNamedDeclaration: [
|
|
19809
|
+
"declaration",
|
|
19810
|
+
"specifiers",
|
|
19811
|
+
"source",
|
|
19812
|
+
"attributes"
|
|
19813
|
+
],
|
|
19814
|
+
ExportSpecifier: ["local", "exported"],
|
|
19815
|
+
ExpressionStatement: ["expression"],
|
|
19816
|
+
ForInStatement: ["left", "right", "body"],
|
|
19817
|
+
ForOfStatement: ["left", "right", "body"],
|
|
19818
|
+
ForStatement: ["init", "test", "update", "body"],
|
|
19819
|
+
FunctionDeclaration: ["id", "params", "body"],
|
|
19820
|
+
FunctionExpression: ["id", "params", "body"],
|
|
19821
|
+
Identifier: [],
|
|
19822
|
+
IfStatement: ["test", "consequent", "alternate"],
|
|
19823
|
+
ImportAttribute: ["key", "value"],
|
|
19824
|
+
ImportDeclaration: ["specifiers", "source", "attributes"],
|
|
19825
|
+
ImportDefaultSpecifier: ["local"],
|
|
19826
|
+
ImportExpression: ["source", "options"],
|
|
19827
|
+
ImportNamespaceSpecifier: ["local"],
|
|
19828
|
+
ImportSpecifier: ["imported", "local"],
|
|
19829
|
+
JSXAttribute: ["name", "value"],
|
|
19830
|
+
JSXClosingElement: ["name"],
|
|
19831
|
+
JSXClosingFragment: [],
|
|
19832
|
+
JSXElement: ["openingElement", "children", "closingElement"],
|
|
19833
|
+
JSXEmptyExpression: [],
|
|
19834
|
+
JSXExpressionContainer: ["expression"],
|
|
19835
|
+
JSXFragment: ["openingFragment", "children", "closingFragment"],
|
|
19836
|
+
JSXIdentifier: [],
|
|
19837
|
+
JSXMemberExpression: ["object", "property"],
|
|
19838
|
+
JSXNamespacedName: ["namespace", "name"],
|
|
19839
|
+
JSXOpeningElement: ["name", "attributes"],
|
|
19840
|
+
JSXOpeningFragment: [],
|
|
19841
|
+
JSXSpreadAttribute: ["argument"],
|
|
19842
|
+
JSXSpreadChild: ["expression"],
|
|
19843
|
+
JSXText: [],
|
|
19844
|
+
LabeledStatement: ["label", "body"],
|
|
19845
|
+
Literal: [],
|
|
19846
|
+
LogicalExpression: ["left", "right"],
|
|
19847
|
+
MemberExpression: ["object", "property"],
|
|
19848
|
+
MetaProperty: ["meta", "property"],
|
|
19849
|
+
MethodDefinition: ["key", "value"],
|
|
19850
|
+
NewExpression: ["callee", "arguments"],
|
|
19851
|
+
ObjectExpression: ["properties"],
|
|
19852
|
+
ObjectPattern: ["properties"],
|
|
19853
|
+
PrivateIdentifier: [],
|
|
19854
|
+
Program: ["body"],
|
|
19855
|
+
Property: ["key", "value"],
|
|
19856
|
+
PropertyDefinition: ["key", "value"],
|
|
19857
|
+
RestElement: ["argument"],
|
|
19858
|
+
ReturnStatement: ["argument"],
|
|
19859
|
+
SequenceExpression: ["expressions"],
|
|
19860
|
+
SpreadElement: ["argument"],
|
|
19861
|
+
StaticBlock: ["body"],
|
|
19862
|
+
Super: [],
|
|
19863
|
+
SwitchCase: ["test", "consequent"],
|
|
19864
|
+
SwitchStatement: ["discriminant", "cases"],
|
|
19865
|
+
TaggedTemplateExpression: ["tag", "quasi"],
|
|
19866
|
+
TemplateElement: [],
|
|
19867
|
+
TemplateLiteral: ["quasis", "expressions"],
|
|
19868
|
+
ThisExpression: [],
|
|
19869
|
+
ThrowStatement: ["argument"],
|
|
19870
|
+
TryStatement: ["block", "handler", "finalizer"],
|
|
19871
|
+
UnaryExpression: ["argument"],
|
|
19872
|
+
UpdateExpression: ["argument"],
|
|
19873
|
+
VariableDeclaration: ["declarations"],
|
|
19874
|
+
VariableDeclarator: ["id", "init"],
|
|
19875
|
+
WhileStatement: ["test", "body"],
|
|
19876
|
+
WithStatement: ["object", "body"],
|
|
19877
|
+
YieldExpression: ["argument"]
|
|
19878
|
+
};
|
|
19879
|
+
var NODE_TYPES = Object.keys(KEYS2);
|
|
19880
|
+
for (const type of NODE_TYPES) {
|
|
19881
|
+
Object.freeze(KEYS2[type]);
|
|
19882
|
+
}
|
|
19883
|
+
Object.freeze(KEYS2);
|
|
19884
|
+
var visitor_keys_default = KEYS2;
|
|
19885
|
+
|
|
19886
|
+
// node_modules/eslint-visitor-keys/lib/index.js
|
|
19887
|
+
function unionWith(additionalKeys) {
|
|
19888
|
+
const retv = (
|
|
19889
|
+
/** @type {{ [type: string]: ReadonlyArray<string> }} */
|
|
19890
|
+
Object.assign({}, visitor_keys_default)
|
|
19891
|
+
);
|
|
19892
|
+
for (const type of Object.keys(additionalKeys)) {
|
|
19893
|
+
if (Object.hasOwn(retv, type)) {
|
|
19894
|
+
const keys = new Set(additionalKeys[type]);
|
|
19895
|
+
for (const key of retv[type]) {
|
|
19896
|
+
keys.add(key);
|
|
19897
|
+
}
|
|
19898
|
+
retv[type] = Object.freeze(Array.from(keys));
|
|
19899
|
+
} else {
|
|
19900
|
+
retv[type] = Object.freeze(Array.from(additionalKeys[type]));
|
|
19668
19901
|
}
|
|
19669
|
-
out += c;
|
|
19670
19902
|
}
|
|
19671
|
-
return
|
|
19903
|
+
return Object.freeze(retv);
|
|
19672
19904
|
}
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
|
|
19676
|
-
|
|
19677
|
-
return void 0;
|
|
19678
|
-
}
|
|
19905
|
+
|
|
19906
|
+
// node_modules/toml-eslint-parser/lib/index.mjs
|
|
19907
|
+
function last(arr) {
|
|
19908
|
+
return arr[arr.length - 1] ?? null;
|
|
19679
19909
|
}
|
|
19680
|
-
function
|
|
19681
|
-
|
|
19682
|
-
return readFileSync6(file2, "utf8");
|
|
19683
|
-
} catch {
|
|
19684
|
-
return "";
|
|
19685
|
-
}
|
|
19910
|
+
function toKeyName(node) {
|
|
19911
|
+
return node.type === "TOMLBare" ? node.name : node.value;
|
|
19686
19912
|
}
|
|
19687
|
-
var
|
|
19688
|
-
|
|
19689
|
-
|
|
19690
|
-
|
|
19691
|
-
if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out;
|
|
19692
|
-
for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
|
|
19693
|
-
listOf(groups).forEach((group, i) => {
|
|
19694
|
-
if (!isObj(group)) return;
|
|
19695
|
-
listOf(group[HOOKS_KEY]).forEach((inner, j) => {
|
|
19696
|
-
const command = commandOf(inner);
|
|
19697
|
-
if (command !== null) out.push({ path: keyPath(HOOKS_KEY, event, i, HOOKS_KEY, j), command });
|
|
19698
|
-
});
|
|
19699
|
-
});
|
|
19913
|
+
var TOMLVerImpl = class {
|
|
19914
|
+
constructor(major, minor) {
|
|
19915
|
+
this.major = major;
|
|
19916
|
+
this.minor = minor;
|
|
19700
19917
|
}
|
|
19701
|
-
|
|
19702
|
-
|
|
19703
|
-
function flatCommands(events, prefix) {
|
|
19704
|
-
const out = [];
|
|
19705
|
-
if (!isObj(events)) return out;
|
|
19706
|
-
for (const [event, entries] of Object.entries(events)) {
|
|
19707
|
-
listOf(entries).forEach((entry, i) => {
|
|
19708
|
-
const command = commandOf(entry);
|
|
19709
|
-
if (command !== null) out.push({ path: keyPath(...prefix, event, i), command });
|
|
19710
|
-
});
|
|
19918
|
+
lt(major, minor) {
|
|
19919
|
+
return this.major < major || this.major === major && this.minor < minor;
|
|
19711
19920
|
}
|
|
19712
|
-
|
|
19921
|
+
gte(major, minor) {
|
|
19922
|
+
return this.major > major || this.major === major && this.minor >= minor;
|
|
19923
|
+
}
|
|
19924
|
+
};
|
|
19925
|
+
var TOML_VERSION_1_0 = new TOMLVerImpl(1, 0);
|
|
19926
|
+
var TOML_VERSION_1_1 = new TOMLVerImpl(1, 1);
|
|
19927
|
+
var DEFAULT_TOML_VERSION = TOML_VERSION_1_1;
|
|
19928
|
+
var SUPPORTED_TOML_VERSIONS = {
|
|
19929
|
+
"1.0": TOML_VERSION_1_0,
|
|
19930
|
+
"1.0.0": TOML_VERSION_1_0,
|
|
19931
|
+
"1.1": TOML_VERSION_1_1,
|
|
19932
|
+
"1.1.0": TOML_VERSION_1_1,
|
|
19933
|
+
latest: TOML_VERSION_1_1,
|
|
19934
|
+
next: TOML_VERSION_1_1
|
|
19935
|
+
};
|
|
19936
|
+
function getTOMLVer(v) {
|
|
19937
|
+
return v && SUPPORTED_TOML_VERSIONS[v] || DEFAULT_TOML_VERSION;
|
|
19938
|
+
}
|
|
19939
|
+
var MESSAGES = {
|
|
19940
|
+
"unterminated-string": "Unterminated string constant",
|
|
19941
|
+
"unterminated-table-key": "Unterminated table-key",
|
|
19942
|
+
"unterminated-array": "Unterminated array",
|
|
19943
|
+
"unterminated-inline-table": "Unterminated inline table",
|
|
19944
|
+
"missing-key": "Empty bare keys are not allowed",
|
|
19945
|
+
"missing-newline": "Must be a newline",
|
|
19946
|
+
"missing-equals-sign": "Expected equal (=) token",
|
|
19947
|
+
"missing-value": "Unspecified values are invalid",
|
|
19948
|
+
"missing-comma": "Expected comma (,) token",
|
|
19949
|
+
"dupe-keys": "Defining a key multiple times is invalid",
|
|
19950
|
+
"unexpected-char": "Unexpected character",
|
|
19951
|
+
"unexpected-token": "Unexpected token",
|
|
19952
|
+
"invalid-control-character": "Control characters (codes < 0x1f and 0x7f) are not allowed",
|
|
19953
|
+
"invalid-comment-character": "Invalid code point {{cp}} within comments",
|
|
19954
|
+
"invalid-key-value-newline": "The key, equals sign, and value must be on the same line",
|
|
19955
|
+
"invalid-inline-table-newline": "No newlines are allowed between the curly braces unless they are valid within a value",
|
|
19956
|
+
"invalid-underscore": "Underscores are allowed between digits",
|
|
19957
|
+
"invalid-space": "Unexpected spaces",
|
|
19958
|
+
"invalid-three-quotes": "Three or more quotes are not permitted",
|
|
19959
|
+
"invalid-date": "Unexpected invalid date",
|
|
19960
|
+
"invalid-time": "Unexpected invalid time",
|
|
19961
|
+
"invalid-leading-zero": "Leading zeros are not allowed",
|
|
19962
|
+
"invalid-trailing-comma-in-inline-table": "Trailing comma is not permitted in an inline table",
|
|
19963
|
+
"invalid-char-in-escape-sequence": "Invalid character in escape sequence",
|
|
19964
|
+
"invalid-consecutive-dots-in-key": "Consecutive dots are not permitted in keys",
|
|
19965
|
+
"invalid-code-point": "Invalid code point {{cp}}",
|
|
19966
|
+
"invalid-trailing-dot-in-key": "Keys cannot end with a dot",
|
|
19967
|
+
"invalid-leading-dot-in-key": "Keys cannot start with a dot"
|
|
19968
|
+
};
|
|
19969
|
+
function getMessage(code, data) {
|
|
19970
|
+
if (data) return MESSAGES[code].replace(/\{\{(.*?)\}\}/gu, (_, name$2) => {
|
|
19971
|
+
if (name$2 in data) return data[name$2];
|
|
19972
|
+
return `{{${name$2}}}`;
|
|
19973
|
+
});
|
|
19974
|
+
return MESSAGES[code];
|
|
19975
|
+
}
|
|
19976
|
+
var ParseError = class extends SyntaxError {
|
|
19977
|
+
/**
|
|
19978
|
+
* Initialize this ParseError instance.
|
|
19979
|
+
*
|
|
19980
|
+
*/
|
|
19981
|
+
constructor(code, offset, line, column, data) {
|
|
19982
|
+
super(getMessage(code, data));
|
|
19983
|
+
this.index = offset;
|
|
19984
|
+
this.lineNumber = line;
|
|
19985
|
+
this.column = column;
|
|
19986
|
+
}
|
|
19987
|
+
};
|
|
19988
|
+
var CodePoint = {
|
|
19989
|
+
EOF: -1,
|
|
19990
|
+
NULL: 0,
|
|
19991
|
+
SOH: 1,
|
|
19992
|
+
BACKSPACE: 8,
|
|
19993
|
+
TABULATION: 9,
|
|
19994
|
+
LINE_FEED: 10,
|
|
19995
|
+
FORM_FEED: 12,
|
|
19996
|
+
CARRIAGE_RETURN: 13,
|
|
19997
|
+
ESCAPE: 27,
|
|
19998
|
+
SO: 14,
|
|
19999
|
+
US: 31,
|
|
20000
|
+
SPACE: 32,
|
|
20001
|
+
QUOTATION_MARK: 34,
|
|
20002
|
+
HASH: 35,
|
|
20003
|
+
SINGLE_QUOTE: 39,
|
|
20004
|
+
PLUS_SIGN: 43,
|
|
20005
|
+
COMMA: 44,
|
|
20006
|
+
DASH: 45,
|
|
20007
|
+
DOT: 46,
|
|
20008
|
+
DIGIT_0: 48,
|
|
20009
|
+
DIGIT_1: 49,
|
|
20010
|
+
DIGIT_2: 50,
|
|
20011
|
+
DIGIT_3: 51,
|
|
20012
|
+
DIGIT_7: 55,
|
|
20013
|
+
DIGIT_9: 57,
|
|
20014
|
+
COLON: 58,
|
|
20015
|
+
EQUALS_SIGN: 61,
|
|
20016
|
+
LATIN_CAPITAL_A: 65,
|
|
20017
|
+
LATIN_CAPITAL_E: 69,
|
|
20018
|
+
LATIN_CAPITAL_F: 70,
|
|
20019
|
+
LATIN_CAPITAL_T: 84,
|
|
20020
|
+
LATIN_CAPITAL_U: 85,
|
|
20021
|
+
LATIN_CAPITAL_Z: 90,
|
|
20022
|
+
LEFT_BRACKET: 91,
|
|
20023
|
+
BACKSLASH: 92,
|
|
20024
|
+
RIGHT_BRACKET: 93,
|
|
20025
|
+
UNDERSCORE: 95,
|
|
20026
|
+
LATIN_SMALL_A: 97,
|
|
20027
|
+
LATIN_SMALL_B: 98,
|
|
20028
|
+
LATIN_SMALL_E: 101,
|
|
20029
|
+
LATIN_SMALL_F: 102,
|
|
20030
|
+
LATIN_SMALL_I: 105,
|
|
20031
|
+
LATIN_SMALL_L: 108,
|
|
20032
|
+
LATIN_SMALL_N: 110,
|
|
20033
|
+
LATIN_SMALL_O: 111,
|
|
20034
|
+
LATIN_SMALL_R: 114,
|
|
20035
|
+
LATIN_SMALL_S: 115,
|
|
20036
|
+
LATIN_SMALL_T: 116,
|
|
20037
|
+
LATIN_SMALL_U: 117,
|
|
20038
|
+
LATIN_SMALL_X: 120,
|
|
20039
|
+
LATIN_SMALL_Z: 122,
|
|
20040
|
+
LEFT_BRACE: 123,
|
|
20041
|
+
RIGHT_BRACE: 125,
|
|
20042
|
+
TILDE: 126,
|
|
20043
|
+
DELETE: 127,
|
|
20044
|
+
PAD: 128,
|
|
20045
|
+
SUPERSCRIPT_TWO: 178,
|
|
20046
|
+
SUPERSCRIPT_THREE: 179,
|
|
20047
|
+
SUPERSCRIPT_ONE: 185,
|
|
20048
|
+
VULGAR_FRACTION_ONE_QUARTER: 188,
|
|
20049
|
+
VULGAR_FRACTION_THREE_QUARTERS: 190,
|
|
20050
|
+
LATIN_CAPITAL_LETTER_A_WITH_GRAVE: 192,
|
|
20051
|
+
LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS: 214,
|
|
20052
|
+
LATIN_CAPITAL_LETTER_O_WITH_STROKE: 216,
|
|
20053
|
+
LATIN_SMALL_LETTER_O_WITH_DIAERESIS: 246,
|
|
20054
|
+
LATIN_SMALL_LETTER_O_WITH_STROKE: 248,
|
|
20055
|
+
GREEK_SMALL_REVERSED_DOTTED_LUNATE_SIGMA_SYMBOL: 891,
|
|
20056
|
+
GREEK_CAPITAL_LETTER_YOT: 895,
|
|
20057
|
+
CP_1FFF: 8191,
|
|
20058
|
+
ZERO_WIDTH_NON_JOINER: 8204,
|
|
20059
|
+
ZERO_WIDTH_JOINER: 8205,
|
|
20060
|
+
UNDERTIE: 8255,
|
|
20061
|
+
CHARACTER_TIE: 8256,
|
|
20062
|
+
SUPERSCRIPT_ZERO: 8304,
|
|
20063
|
+
CP_218F: 8591,
|
|
20064
|
+
CIRCLED_DIGIT_ONE: 9312,
|
|
20065
|
+
NEGATIVE_CIRCLED_DIGIT_ZERO: 9471,
|
|
20066
|
+
GLAGOLITIC_CAPITAL_LETTER_AZU: 11264,
|
|
20067
|
+
CP_2FEF: 12271,
|
|
20068
|
+
IDEOGRAPHIC_COMMA: 12289,
|
|
20069
|
+
CP_D7FF: 55295,
|
|
20070
|
+
CP_E000: 57344,
|
|
20071
|
+
CJK_COMPATIBILITY_IDEOGRAPH_F900: 63744,
|
|
20072
|
+
ARABIC_LIGATURE_SALAAMUHU_ALAYNAA: 64975,
|
|
20073
|
+
ARABIC_LIGATURE_SALLA_USED_AS_KORANIC_STOP_SIGN_ISOLATED_FORM: 65008,
|
|
20074
|
+
REPLACEMENT_CHARACTER: 65533,
|
|
20075
|
+
LINEAR_B_SYLLABLE_B008_A: 65536,
|
|
20076
|
+
CP_EFFFF: 983039,
|
|
20077
|
+
CP_10FFFF: 1114111
|
|
20078
|
+
};
|
|
20079
|
+
function isControl(cp) {
|
|
20080
|
+
return cp >= CodePoint.NULL && cp <= CodePoint.US;
|
|
19713
20081
|
}
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
function dataDir(dir, reason, out) {
|
|
19717
|
-
if (existsSync3(dir)) out.push(finding(dir, "", reason));
|
|
20082
|
+
function isWhitespace(cp) {
|
|
20083
|
+
return cp === CodePoint.TABULATION || cp === CodePoint.SPACE;
|
|
19718
20084
|
}
|
|
19719
|
-
function
|
|
19720
|
-
|
|
19721
|
-
out.push(finding(file2, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
|
|
19722
|
-
}
|
|
20085
|
+
function isEOL(cp) {
|
|
20086
|
+
return cp === CodePoint.LINE_FEED || cp === CodePoint.CARRIAGE_RETURN;
|
|
19723
20087
|
}
|
|
19724
|
-
function
|
|
19725
|
-
|
|
19726
|
-
const doc = readJson(file2);
|
|
19727
|
-
for (const c of nestedCommands(doc)) {
|
|
19728
|
-
if (c.command.includes(V1_CACHE_HEAL_NAME)) out.push(finding(file2, c.path, V1_REASON.cacheHealHook));
|
|
19729
|
-
else if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.hook));
|
|
19730
|
-
}
|
|
19731
|
-
const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
|
|
19732
|
-
if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
|
|
19733
|
-
out.push(finding(file2, STATUS_LINE_KEY, V1_REASON.statusLine));
|
|
19734
|
-
}
|
|
19735
|
-
mcpEntry(file2, doc, out);
|
|
20088
|
+
function isUpperLetter(cp) {
|
|
20089
|
+
return cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_Z;
|
|
19736
20090
|
}
|
|
19737
|
-
function
|
|
19738
|
-
|
|
19739
|
-
const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
|
|
19740
|
-
if (cmds.some((c) => c.command.includes(V1_HOOK_COMMAND))) out.push(finding(file2, "", V1_REASON.hookFile));
|
|
20091
|
+
function isLowerLetter(cp) {
|
|
20092
|
+
return cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_Z;
|
|
19741
20093
|
}
|
|
19742
|
-
function
|
|
19743
|
-
|
|
19744
|
-
for (const ext of V1_CACHE_HEAL_EXTS) {
|
|
19745
|
-
const file2 = join7(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
|
|
19746
|
-
if (existsSync3(file2)) out.push(finding(file2, "", V1_REASON.cacheHealFile));
|
|
19747
|
-
}
|
|
19748
|
-
const userFile = join7(home, CLAUDE_USER_CONFIG_FILE);
|
|
19749
|
-
mcpEntry(userFile, readJson(userFile), out);
|
|
19750
|
-
dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20094
|
+
function isLetter2(cp) {
|
|
20095
|
+
return isLowerLetter(cp) || isUpperLetter(cp);
|
|
19751
20096
|
}
|
|
19752
|
-
function
|
|
19753
|
-
|
|
19754
|
-
for (const c of nestedCommands(readJson(hooksFile))) {
|
|
19755
|
-
if (c.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c.command)) {
|
|
19756
|
-
out.push(finding(hooksFile, c.path, V1_REASON.codexHook));
|
|
19757
|
-
}
|
|
19758
|
-
}
|
|
19759
|
-
const tomlFile = join7(agentHome, CONFIG_TOML_FILE);
|
|
19760
|
-
for (const line of readText(tomlFile).split("\n")) {
|
|
19761
|
-
const header = line.trim();
|
|
19762
|
-
if (header.startsWith(V1_TOML_SECTION_PREFIX)) out.push(finding(tomlFile, header, V1_REASON.codexToml));
|
|
19763
|
-
}
|
|
19764
|
-
dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20097
|
+
function isDigit4(cp) {
|
|
20098
|
+
return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_9;
|
|
19765
20099
|
}
|
|
19766
|
-
function
|
|
19767
|
-
|
|
19768
|
-
for (const c of nestedCommands(readJson(file2))) {
|
|
19769
|
-
if (c.command.includes(SERVER_KEY)) out.push(finding(file2, c.path, V1_REASON.hook));
|
|
19770
|
-
}
|
|
19771
|
-
dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out);
|
|
20100
|
+
function isHexDig(cp) {
|
|
20101
|
+
return isDigit4(cp) || cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_F || cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_F;
|
|
19772
20102
|
}
|
|
19773
|
-
function
|
|
19774
|
-
|
|
19775
|
-
v1HookFile(join7(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
|
|
19776
|
-
const mcpFile2 = join7(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
|
|
19777
|
-
const doc = readJson(mcpFile2);
|
|
19778
|
-
const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
|
|
19779
|
-
const entry = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
|
|
19780
|
-
if (isObj(entry) && (entry.command === V1_BIN_COMMAND || listOf(entry.args).some((a) => a === V1_BIN_COMMAND))) {
|
|
19781
|
-
out.push(finding(mcpFile2, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
|
|
19782
|
-
}
|
|
19783
|
-
dataDir(join7(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
|
|
19784
|
-
}
|
|
19785
|
-
dataDir(join7(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
|
|
20103
|
+
function isOctalDig(cp) {
|
|
20104
|
+
return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_7;
|
|
19786
20105
|
}
|
|
19787
|
-
function
|
|
19788
|
-
|
|
19789
|
-
|
|
19790
|
-
|
|
19791
|
-
|
|
20106
|
+
function isUnicodeScalarValue(cp) {
|
|
20107
|
+
return cp >= 0 && cp <= 55295 || cp >= 57344 && cp <= 1114111;
|
|
20108
|
+
}
|
|
20109
|
+
function sortedLastIndex(array2, value) {
|
|
20110
|
+
let low = 0;
|
|
20111
|
+
let high = array2.length;
|
|
20112
|
+
while (low < high) {
|
|
20113
|
+
const mid = low + high >>> 1;
|
|
20114
|
+
const val = array2[mid];
|
|
20115
|
+
if (val === value) return mid + 1;
|
|
20116
|
+
if (val < value) low = mid + 1;
|
|
20117
|
+
else high = mid;
|
|
19792
20118
|
}
|
|
20119
|
+
return low;
|
|
19793
20120
|
}
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
19803
|
-
}
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
|
|
20121
|
+
var Locations = class {
|
|
20122
|
+
constructor() {
|
|
20123
|
+
this.offsets = [];
|
|
20124
|
+
}
|
|
20125
|
+
addOffset(offset) {
|
|
20126
|
+
for (let i = this.offsets.length - 1; i >= 0; i--) {
|
|
20127
|
+
const element2 = this.offsets[i];
|
|
20128
|
+
if (element2 === offset) return;
|
|
20129
|
+
if (element2 < offset) break;
|
|
20130
|
+
}
|
|
20131
|
+
this.offsets.push(offset);
|
|
20132
|
+
}
|
|
20133
|
+
/**
|
|
20134
|
+
* Calculate the location of the given index.
|
|
20135
|
+
* @param index The index to calculate their location.
|
|
20136
|
+
* @returns The location of the index.
|
|
20137
|
+
*/
|
|
20138
|
+
getLocFromIndex(offset) {
|
|
20139
|
+
const line = sortedLastIndex(this.offsets, offset) + 1;
|
|
20140
|
+
return {
|
|
20141
|
+
line,
|
|
20142
|
+
column: offset - (line === 1 ? 0 : this.offsets[line - 2])
|
|
20143
|
+
};
|
|
20144
|
+
}
|
|
20145
|
+
};
|
|
20146
|
+
var CodePointIterator = class {
|
|
20147
|
+
/**
|
|
20148
|
+
* Initialize this char iterator.
|
|
20149
|
+
*/
|
|
20150
|
+
constructor(text) {
|
|
20151
|
+
this.locs = new Locations();
|
|
20152
|
+
this.lastCodePoint = CodePoint.NULL;
|
|
20153
|
+
this.start = -1;
|
|
20154
|
+
this.end = 0;
|
|
20155
|
+
this.text = text;
|
|
20156
|
+
}
|
|
20157
|
+
next() {
|
|
20158
|
+
if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
|
|
20159
|
+
return this.lastCodePoint = this.moveAt(this.end);
|
|
20160
|
+
}
|
|
20161
|
+
getLocFromIndex(index) {
|
|
20162
|
+
return this.locs.getLocFromIndex(index);
|
|
20163
|
+
}
|
|
20164
|
+
eat(cp) {
|
|
20165
|
+
if (this.text.codePointAt(this.end) === cp) {
|
|
20166
|
+
this.next();
|
|
20167
|
+
return true;
|
|
19807
20168
|
}
|
|
20169
|
+
return false;
|
|
19808
20170
|
}
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
if (
|
|
20171
|
+
moveAt(offset) {
|
|
20172
|
+
this.start = this.end = offset;
|
|
20173
|
+
const cp = this.text.codePointAt(this.start) ?? CodePoint.EOF;
|
|
20174
|
+
if (cp === CodePoint.EOF) {
|
|
20175
|
+
this.end = this.start;
|
|
20176
|
+
return cp;
|
|
20177
|
+
}
|
|
20178
|
+
this.end += cp >= 65536 ? 2 : 1;
|
|
20179
|
+
if (cp === CodePoint.LINE_FEED) this.locs.addOffset(this.end);
|
|
20180
|
+
else if (cp === CodePoint.CARRIAGE_RETURN) {
|
|
20181
|
+
if (this.text.codePointAt(this.end) === CodePoint.LINE_FEED) {
|
|
20182
|
+
this.end++;
|
|
20183
|
+
this.locs.addOffset(this.end);
|
|
20184
|
+
}
|
|
20185
|
+
return CodePoint.LINE_FEED;
|
|
20186
|
+
}
|
|
20187
|
+
return cp;
|
|
19813
20188
|
}
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
20189
|
+
};
|
|
20190
|
+
var HAS_BIGINT = typeof BigInt !== "undefined";
|
|
20191
|
+
var RADIX_PREFIXES = {
|
|
20192
|
+
16: "0x",
|
|
20193
|
+
10: "",
|
|
20194
|
+
8: "0o",
|
|
20195
|
+
2: "0b"
|
|
20196
|
+
};
|
|
20197
|
+
var ESCAPES_1_0 = {
|
|
20198
|
+
[CodePoint.QUOTATION_MARK]: CodePoint.QUOTATION_MARK,
|
|
20199
|
+
[CodePoint.BACKSLASH]: CodePoint.BACKSLASH,
|
|
20200
|
+
[CodePoint.LATIN_SMALL_B]: CodePoint.BACKSPACE,
|
|
20201
|
+
[CodePoint.LATIN_SMALL_F]: CodePoint.FORM_FEED,
|
|
20202
|
+
[CodePoint.LATIN_SMALL_N]: CodePoint.LINE_FEED,
|
|
20203
|
+
[CodePoint.LATIN_SMALL_R]: CodePoint.CARRIAGE_RETURN,
|
|
20204
|
+
[CodePoint.LATIN_SMALL_T]: CodePoint.TABULATION
|
|
20205
|
+
};
|
|
20206
|
+
var ESCAPES_LATEST = {
|
|
20207
|
+
...ESCAPES_1_0,
|
|
20208
|
+
[CodePoint.LATIN_SMALL_E]: CodePoint.ESCAPE
|
|
20209
|
+
};
|
|
20210
|
+
var Tokenizer = class {
|
|
20211
|
+
/**
|
|
20212
|
+
* Initialize this tokenizer.
|
|
20213
|
+
*/
|
|
20214
|
+
constructor(text, parserOptions) {
|
|
20215
|
+
this.backCode = false;
|
|
20216
|
+
this.lastCodePoint = CodePoint.NULL;
|
|
20217
|
+
this.state = "DATA";
|
|
20218
|
+
this.token = null;
|
|
20219
|
+
this.tokenStart = -1;
|
|
20220
|
+
this.valuesEnabled = false;
|
|
20221
|
+
this.text = text;
|
|
20222
|
+
this.parserOptions = parserOptions || {};
|
|
20223
|
+
this.codePointIterator = new CodePointIterator(text);
|
|
20224
|
+
this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
|
|
20225
|
+
this.ESCAPES = this.tomlVersion.gte(1, 1) ? ESCAPES_LATEST : ESCAPES_1_0;
|
|
20226
|
+
}
|
|
20227
|
+
get start() {
|
|
20228
|
+
return this.codePointIterator.start;
|
|
20229
|
+
}
|
|
20230
|
+
get end() {
|
|
20231
|
+
return this.codePointIterator.end;
|
|
20232
|
+
}
|
|
20233
|
+
getLocFromIndex(index) {
|
|
20234
|
+
return this.codePointIterator.getLocFromIndex(index);
|
|
20235
|
+
}
|
|
20236
|
+
/**
|
|
20237
|
+
* Report an invalid character error.
|
|
20238
|
+
*/
|
|
20239
|
+
reportParseError(code, data) {
|
|
20240
|
+
const offset = this.codePointIterator.start;
|
|
20241
|
+
const loc = this.codePointIterator.getLocFromIndex(offset);
|
|
20242
|
+
throw new ParseError(code, offset, loc.line, loc.column, data);
|
|
20243
|
+
}
|
|
20244
|
+
/**
|
|
20245
|
+
* Get the next token.
|
|
20246
|
+
*/
|
|
20247
|
+
nextToken() {
|
|
20248
|
+
let token = this.token;
|
|
20249
|
+
if (token != null) {
|
|
20250
|
+
this.token = null;
|
|
20251
|
+
return token;
|
|
20252
|
+
}
|
|
20253
|
+
let cp = this.lastCodePoint;
|
|
20254
|
+
while (cp !== CodePoint.EOF && !this.token) {
|
|
20255
|
+
cp = this.nextCode();
|
|
20256
|
+
const nextState = this[this.state](cp);
|
|
20257
|
+
if (!nextState) throw new Error(`Unknown error: pre state=${this.state}`);
|
|
20258
|
+
this.state = nextState;
|
|
20259
|
+
}
|
|
20260
|
+
token = this.token;
|
|
20261
|
+
this.token = null;
|
|
20262
|
+
return token;
|
|
20263
|
+
}
|
|
20264
|
+
/**
|
|
20265
|
+
* Get the next code point.
|
|
20266
|
+
*/
|
|
20267
|
+
nextCode() {
|
|
20268
|
+
if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
|
|
20269
|
+
if (this.backCode) {
|
|
20270
|
+
this.backCode = false;
|
|
20271
|
+
return this.lastCodePoint;
|
|
20272
|
+
}
|
|
20273
|
+
return this.lastCodePoint = this.codePointIterator.next();
|
|
20274
|
+
}
|
|
20275
|
+
/**
|
|
20276
|
+
* Eat the next code point.
|
|
20277
|
+
*/
|
|
20278
|
+
eatCode(cp) {
|
|
20279
|
+
if (this.lastCodePoint === CodePoint.EOF) return false;
|
|
20280
|
+
if (this.backCode) {
|
|
20281
|
+
if (this.lastCodePoint === cp) {
|
|
20282
|
+
this.backCode = false;
|
|
20283
|
+
return true;
|
|
20284
|
+
}
|
|
20285
|
+
return false;
|
|
20286
|
+
}
|
|
20287
|
+
return this.codePointIterator.eat(cp);
|
|
20288
|
+
}
|
|
20289
|
+
/**
|
|
20290
|
+
* Moves the character position to the given position.
|
|
20291
|
+
*/
|
|
20292
|
+
moveAt(loc) {
|
|
20293
|
+
if (this.backCode) this.backCode = false;
|
|
20294
|
+
this.lastCodePoint = this.codePointIterator.moveAt(loc);
|
|
20295
|
+
}
|
|
20296
|
+
/**
|
|
20297
|
+
* Back the current code point as the given state.
|
|
20298
|
+
*/
|
|
20299
|
+
back(state) {
|
|
20300
|
+
this.backCode = true;
|
|
20301
|
+
return state;
|
|
20302
|
+
}
|
|
20303
|
+
punctuatorToken() {
|
|
20304
|
+
this.startToken();
|
|
20305
|
+
this.endToken("Punctuator", "end");
|
|
20306
|
+
}
|
|
20307
|
+
startToken() {
|
|
20308
|
+
this.tokenStart = this.codePointIterator.start;
|
|
20309
|
+
}
|
|
20310
|
+
/**
|
|
20311
|
+
* Commit the current token.
|
|
20312
|
+
*/
|
|
20313
|
+
endToken(type, pos, option1, option2) {
|
|
20314
|
+
const { tokenStart } = this;
|
|
20315
|
+
const end = this.codePointIterator[pos];
|
|
20316
|
+
const range = [tokenStart, end];
|
|
20317
|
+
const loc = {
|
|
20318
|
+
start: this.codePointIterator.getLocFromIndex(tokenStart),
|
|
20319
|
+
end: this.codePointIterator.getLocFromIndex(end)
|
|
20320
|
+
};
|
|
20321
|
+
if (type === "Block") this.token = {
|
|
20322
|
+
type,
|
|
20323
|
+
value: this.text.slice(tokenStart + 1, end),
|
|
20324
|
+
range,
|
|
20325
|
+
loc
|
|
20326
|
+
};
|
|
20327
|
+
else {
|
|
20328
|
+
let token;
|
|
20329
|
+
const value = this.text.slice(tokenStart, end);
|
|
20330
|
+
if (type === "BasicString" || type === "LiteralString" || type === "MultiLineBasicString" || type === "MultiLineLiteralString") token = {
|
|
20331
|
+
type,
|
|
20332
|
+
value,
|
|
20333
|
+
string: option1,
|
|
20334
|
+
range,
|
|
20335
|
+
loc
|
|
20336
|
+
};
|
|
20337
|
+
else if (type === "Integer") {
|
|
20338
|
+
const text = option1;
|
|
20339
|
+
token = {
|
|
20340
|
+
type,
|
|
20341
|
+
value,
|
|
20342
|
+
number: parseInt(text, option2),
|
|
20343
|
+
bigint: HAS_BIGINT ? BigInt(RADIX_PREFIXES[option2] + text) : null,
|
|
20344
|
+
range,
|
|
20345
|
+
loc
|
|
20346
|
+
};
|
|
20347
|
+
} else if (type === "Float") token = {
|
|
20348
|
+
type,
|
|
20349
|
+
value,
|
|
20350
|
+
number: option1,
|
|
20351
|
+
range,
|
|
20352
|
+
loc
|
|
20353
|
+
};
|
|
20354
|
+
else if (type === "Boolean") token = {
|
|
20355
|
+
type,
|
|
20356
|
+
value,
|
|
20357
|
+
boolean: option1,
|
|
20358
|
+
range,
|
|
20359
|
+
loc
|
|
20360
|
+
};
|
|
20361
|
+
else if (type === "LocalDate" || type === "LocalTime" || type === "LocalDateTime" || type === "OffsetDateTime") token = {
|
|
20362
|
+
type,
|
|
20363
|
+
value,
|
|
20364
|
+
date: option1,
|
|
20365
|
+
range,
|
|
20366
|
+
loc
|
|
20367
|
+
};
|
|
20368
|
+
else token = {
|
|
20369
|
+
type,
|
|
20370
|
+
value,
|
|
20371
|
+
range,
|
|
20372
|
+
loc
|
|
20373
|
+
};
|
|
20374
|
+
this.token = token;
|
|
20375
|
+
}
|
|
19834
20376
|
}
|
|
19835
|
-
|
|
19836
|
-
|
|
19837
|
-
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
if (
|
|
20377
|
+
DATA(cp) {
|
|
20378
|
+
while (isWhitespace(cp) || isEOL(cp)) cp = this.nextCode();
|
|
20379
|
+
if (cp === CodePoint.HASH) {
|
|
20380
|
+
this.startToken();
|
|
20381
|
+
return "COMMENT";
|
|
20382
|
+
}
|
|
20383
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
20384
|
+
this.startToken();
|
|
20385
|
+
return "BASIC_STRING";
|
|
20386
|
+
}
|
|
20387
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
20388
|
+
this.startToken();
|
|
20389
|
+
return "LITERAL_STRING";
|
|
20390
|
+
}
|
|
20391
|
+
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) {
|
|
20392
|
+
this.punctuatorToken();
|
|
20393
|
+
return "DATA";
|
|
20394
|
+
}
|
|
20395
|
+
if (this.valuesEnabled) {
|
|
20396
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
20397
|
+
this.startToken();
|
|
20398
|
+
return "SIGN";
|
|
20399
|
+
}
|
|
20400
|
+
if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) {
|
|
20401
|
+
this.startToken();
|
|
20402
|
+
return this.back("NAN_OR_INF");
|
|
20403
|
+
}
|
|
20404
|
+
if (isDigit4(cp)) {
|
|
20405
|
+
this.startToken();
|
|
20406
|
+
return this.back("NUMBER");
|
|
20407
|
+
}
|
|
20408
|
+
if (cp === CodePoint.LATIN_SMALL_T || cp === CodePoint.LATIN_SMALL_F) {
|
|
20409
|
+
this.startToken();
|
|
20410
|
+
return this.back("BOOLEAN");
|
|
20411
|
+
}
|
|
20412
|
+
} else if (isUnquotedKeyChar(cp, this.tomlVersion)) {
|
|
20413
|
+
this.startToken();
|
|
20414
|
+
return "BARE";
|
|
20415
|
+
}
|
|
20416
|
+
if (cp === CodePoint.EOF) return "DATA";
|
|
20417
|
+
return this.reportParseError("unexpected-char");
|
|
19842
20418
|
}
|
|
19843
|
-
|
|
19844
|
-
|
|
19845
|
-
|
|
20419
|
+
COMMENT(cp) {
|
|
20420
|
+
const processCommentChar = this.tomlVersion.gte(1, 1) ? (c) => {
|
|
20421
|
+
if (!isNonEOL(c)) this.reportParseError("invalid-comment-character", { cp: JSON.stringify(String.fromCodePoint(c)).slice(1, -1) });
|
|
20422
|
+
} : (c) => {
|
|
20423
|
+
if (isControlOtherThanTab(c)) this.reportParseErrorControlChar();
|
|
20424
|
+
};
|
|
20425
|
+
while (!isEOL(cp) && cp !== CodePoint.EOF) {
|
|
20426
|
+
processCommentChar(cp);
|
|
20427
|
+
cp = this.nextCode();
|
|
20428
|
+
}
|
|
20429
|
+
this.endToken("Block", "start");
|
|
20430
|
+
return "DATA";
|
|
19846
20431
|
}
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
|
|
19851
|
-
handle = opendirSync(dir);
|
|
19852
|
-
} catch {
|
|
19853
|
-
return null;
|
|
20432
|
+
BARE(cp) {
|
|
20433
|
+
while (isUnquotedKeyChar(cp, this.tomlVersion)) cp = this.nextCode();
|
|
20434
|
+
this.endToken("Bare", "start");
|
|
20435
|
+
return this.back("DATA");
|
|
19854
20436
|
}
|
|
19855
|
-
|
|
19856
|
-
|
|
19857
|
-
|
|
20437
|
+
BASIC_STRING(cp) {
|
|
20438
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
20439
|
+
cp = this.nextCode();
|
|
20440
|
+
if (cp === CodePoint.QUOTATION_MARK) return "MULTI_LINE_BASIC_STRING";
|
|
20441
|
+
this.endToken("BasicString", "start", "");
|
|
20442
|
+
return this.back("DATA");
|
|
19858
20443
|
}
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
20444
|
+
const out = [];
|
|
20445
|
+
while (cp !== CodePoint.QUOTATION_MARK && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
|
|
20446
|
+
if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
20447
|
+
if (cp === CodePoint.BACKSLASH) {
|
|
20448
|
+
cp = this.nextCode();
|
|
20449
|
+
const ecp = this.ESCAPES[cp];
|
|
20450
|
+
if (ecp) {
|
|
20451
|
+
out.push(ecp);
|
|
20452
|
+
cp = this.nextCode();
|
|
20453
|
+
continue;
|
|
20454
|
+
} else if (cp === CodePoint.LATIN_SMALL_U) {
|
|
20455
|
+
const code = this.parseUnicode(4);
|
|
20456
|
+
out.push(code);
|
|
20457
|
+
cp = this.nextCode();
|
|
20458
|
+
continue;
|
|
20459
|
+
} else if (cp === CodePoint.LATIN_CAPITAL_U) {
|
|
20460
|
+
const code = this.parseUnicode(8);
|
|
20461
|
+
out.push(code);
|
|
20462
|
+
cp = this.nextCode();
|
|
20463
|
+
continue;
|
|
20464
|
+
} else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
|
|
20465
|
+
const code = this.parseUnicode(2);
|
|
20466
|
+
out.push(code);
|
|
20467
|
+
cp = this.nextCode();
|
|
20468
|
+
continue;
|
|
20469
|
+
}
|
|
20470
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
20471
|
+
}
|
|
20472
|
+
out.push(cp);
|
|
20473
|
+
cp = this.nextCode();
|
|
20474
|
+
}
|
|
20475
|
+
if (cp !== CodePoint.QUOTATION_MARK) return this.reportParseError("unterminated-string");
|
|
20476
|
+
this.endToken("BasicString", "end", String.fromCodePoint(...out));
|
|
20477
|
+
return "DATA";
|
|
20478
|
+
}
|
|
20479
|
+
MULTI_LINE_BASIC_STRING(cp) {
|
|
20480
|
+
const out = [];
|
|
20481
|
+
if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
20482
|
+
while (cp !== CodePoint.EOF) {
|
|
20483
|
+
if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
20484
|
+
if (cp === CodePoint.QUOTATION_MARK) {
|
|
20485
|
+
const startPos = this.codePointIterator.start;
|
|
20486
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK) && this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
20487
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
20488
|
+
out.push(CodePoint.QUOTATION_MARK);
|
|
20489
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
20490
|
+
out.push(CodePoint.QUOTATION_MARK);
|
|
20491
|
+
if (this.eatCode(CodePoint.QUOTATION_MARK)) {
|
|
20492
|
+
this.moveAt(startPos);
|
|
20493
|
+
return this.reportParseError("invalid-three-quotes");
|
|
20494
|
+
}
|
|
20495
|
+
}
|
|
20496
|
+
}
|
|
20497
|
+
this.endToken("MultiLineBasicString", "end", String.fromCodePoint(...out));
|
|
20498
|
+
return "DATA";
|
|
20499
|
+
}
|
|
20500
|
+
this.moveAt(startPos);
|
|
20501
|
+
}
|
|
20502
|
+
if (cp === CodePoint.BACKSLASH) {
|
|
20503
|
+
cp = this.nextCode();
|
|
20504
|
+
const ecp = this.ESCAPES[cp];
|
|
20505
|
+
if (ecp) {
|
|
20506
|
+
out.push(ecp);
|
|
20507
|
+
cp = this.nextCode();
|
|
20508
|
+
continue;
|
|
20509
|
+
} else if (cp === CodePoint.LATIN_SMALL_U) {
|
|
20510
|
+
const code = this.parseUnicode(4);
|
|
20511
|
+
out.push(code);
|
|
20512
|
+
cp = this.nextCode();
|
|
20513
|
+
continue;
|
|
20514
|
+
} else if (cp === CodePoint.LATIN_CAPITAL_U) {
|
|
20515
|
+
const code = this.parseUnicode(8);
|
|
20516
|
+
out.push(code);
|
|
20517
|
+
cp = this.nextCode();
|
|
20518
|
+
continue;
|
|
20519
|
+
} else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
|
|
20520
|
+
const code = this.parseUnicode(2);
|
|
20521
|
+
out.push(code);
|
|
20522
|
+
cp = this.nextCode();
|
|
20523
|
+
continue;
|
|
20524
|
+
} else if (cp === CodePoint.LINE_FEED) {
|
|
20525
|
+
cp = this.nextCode();
|
|
20526
|
+
while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
20527
|
+
continue;
|
|
20528
|
+
} else if (isWhitespace(cp)) {
|
|
20529
|
+
let valid = true;
|
|
20530
|
+
const startPos = this.codePointIterator.start;
|
|
20531
|
+
let nextCp;
|
|
20532
|
+
while ((nextCp = this.nextCode()) !== CodePoint.EOF) {
|
|
20533
|
+
if (nextCp === CodePoint.LINE_FEED) break;
|
|
20534
|
+
if (!isWhitespace(nextCp)) {
|
|
20535
|
+
this.moveAt(startPos);
|
|
20536
|
+
valid = false;
|
|
20537
|
+
break;
|
|
20538
|
+
}
|
|
20539
|
+
}
|
|
20540
|
+
if (valid) {
|
|
20541
|
+
cp = this.nextCode();
|
|
20542
|
+
while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
20543
|
+
continue;
|
|
20544
|
+
}
|
|
20545
|
+
}
|
|
20546
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
20547
|
+
}
|
|
20548
|
+
out.push(cp);
|
|
20549
|
+
cp = this.nextCode();
|
|
20550
|
+
}
|
|
20551
|
+
return this.reportParseError("unterminated-string");
|
|
20552
|
+
}
|
|
20553
|
+
LITERAL_STRING(cp) {
|
|
20554
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
20555
|
+
cp = this.nextCode();
|
|
20556
|
+
if (cp === CodePoint.SINGLE_QUOTE) return "MULTI_LINE_LITERAL_STRING";
|
|
20557
|
+
this.endToken("LiteralString", "start", "");
|
|
20558
|
+
return this.back("DATA");
|
|
20559
|
+
}
|
|
20560
|
+
const out = [];
|
|
20561
|
+
while (cp !== CodePoint.SINGLE_QUOTE && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
|
|
20562
|
+
if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
20563
|
+
out.push(cp);
|
|
20564
|
+
cp = this.nextCode();
|
|
20565
|
+
}
|
|
20566
|
+
if (cp !== CodePoint.SINGLE_QUOTE) return this.reportParseError("unterminated-string");
|
|
20567
|
+
this.endToken("LiteralString", "end", String.fromCodePoint(...out));
|
|
20568
|
+
return "DATA";
|
|
19864
20569
|
}
|
|
20570
|
+
MULTI_LINE_LITERAL_STRING(cp) {
|
|
20571
|
+
const out = [];
|
|
20572
|
+
if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
|
|
20573
|
+
while (cp !== CodePoint.EOF) {
|
|
20574
|
+
if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
|
|
20575
|
+
if (cp === CodePoint.SINGLE_QUOTE) {
|
|
20576
|
+
const startPos = this.codePointIterator.start;
|
|
20577
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE) && this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
20578
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
20579
|
+
out.push(CodePoint.SINGLE_QUOTE);
|
|
20580
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
20581
|
+
out.push(CodePoint.SINGLE_QUOTE);
|
|
20582
|
+
if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
|
|
20583
|
+
this.moveAt(startPos);
|
|
20584
|
+
return this.reportParseError("invalid-three-quotes");
|
|
20585
|
+
}
|
|
20586
|
+
}
|
|
20587
|
+
}
|
|
20588
|
+
this.endToken("MultiLineLiteralString", "end", String.fromCodePoint(...out));
|
|
20589
|
+
return "DATA";
|
|
20590
|
+
}
|
|
20591
|
+
this.moveAt(startPos);
|
|
20592
|
+
}
|
|
20593
|
+
out.push(cp);
|
|
20594
|
+
cp = this.nextCode();
|
|
20595
|
+
}
|
|
20596
|
+
return this.reportParseError("unterminated-string");
|
|
20597
|
+
}
|
|
20598
|
+
SIGN(cp) {
|
|
20599
|
+
if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) return this.back("NAN_OR_INF");
|
|
20600
|
+
if (isDigit4(cp)) return this.back("NUMBER");
|
|
20601
|
+
return this.reportParseError("unexpected-char");
|
|
20602
|
+
}
|
|
20603
|
+
NAN_OR_INF(cp) {
|
|
20604
|
+
if (cp === CodePoint.LATIN_SMALL_N) {
|
|
20605
|
+
const startPos = this.codePointIterator.start;
|
|
20606
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_A) && this.eatCode(CodePoint.LATIN_SMALL_N)) {
|
|
20607
|
+
this.endToken("Float", "end", NaN);
|
|
20608
|
+
return "DATA";
|
|
20609
|
+
}
|
|
20610
|
+
this.moveAt(startPos);
|
|
20611
|
+
} else if (cp === CodePoint.LATIN_SMALL_I) {
|
|
20612
|
+
const startPos = this.codePointIterator.start;
|
|
20613
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_N) && this.eatCode(CodePoint.LATIN_SMALL_F)) {
|
|
20614
|
+
this.endToken("Float", "end", this.text[this.tokenStart] === "-" ? -Infinity : Infinity);
|
|
20615
|
+
return "DATA";
|
|
20616
|
+
}
|
|
20617
|
+
this.moveAt(startPos);
|
|
20618
|
+
}
|
|
20619
|
+
return this.reportParseError("unexpected-char");
|
|
20620
|
+
}
|
|
20621
|
+
NUMBER(cp) {
|
|
20622
|
+
const start = this.text[this.tokenStart];
|
|
20623
|
+
const sign = start === "+" ? CodePoint.PLUS_SIGN : start === "-" ? CodePoint.DASH : CodePoint.NULL;
|
|
20624
|
+
if (cp === CodePoint.DIGIT_0) {
|
|
20625
|
+
if (sign === CodePoint.NULL) {
|
|
20626
|
+
const startPos = this.codePointIterator.start;
|
|
20627
|
+
const nextCp$1 = this.nextCode();
|
|
20628
|
+
if (isDigit4(nextCp$1)) {
|
|
20629
|
+
const nextNextCp = this.nextCode();
|
|
20630
|
+
if (nextNextCp === CodePoint.COLON) {
|
|
20631
|
+
this.data = {
|
|
20632
|
+
hasDate: false,
|
|
20633
|
+
year: 0,
|
|
20634
|
+
month: 0,
|
|
20635
|
+
day: 0,
|
|
20636
|
+
hour: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1)),
|
|
20637
|
+
minute: 0,
|
|
20638
|
+
second: 0
|
|
20639
|
+
};
|
|
20640
|
+
return "TIME_MINUTE";
|
|
20641
|
+
}
|
|
20642
|
+
if (isDigit4(nextNextCp)) {
|
|
20643
|
+
const nextNextNextCp = this.nextCode();
|
|
20644
|
+
if (isDigit4(nextNextNextCp) && this.eatCode(CodePoint.DASH)) {
|
|
20645
|
+
this.data = {
|
|
20646
|
+
hasDate: true,
|
|
20647
|
+
year: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1, nextNextCp, nextNextNextCp)),
|
|
20648
|
+
month: 0,
|
|
20649
|
+
day: 0,
|
|
20650
|
+
hour: 0,
|
|
20651
|
+
minute: 0,
|
|
20652
|
+
second: 0
|
|
20653
|
+
};
|
|
20654
|
+
return "DATE_MONTH";
|
|
20655
|
+
}
|
|
20656
|
+
}
|
|
20657
|
+
this.moveAt(startPos);
|
|
20658
|
+
return this.reportParseError("invalid-leading-zero");
|
|
20659
|
+
}
|
|
20660
|
+
this.moveAt(startPos);
|
|
20661
|
+
}
|
|
20662
|
+
cp = this.nextCode();
|
|
20663
|
+
if (cp === CodePoint.LATIN_SMALL_X || cp === CodePoint.LATIN_SMALL_O || cp === CodePoint.LATIN_SMALL_B) {
|
|
20664
|
+
if (sign !== CodePoint.NULL) return this.reportParseError("unexpected-char");
|
|
20665
|
+
return cp === CodePoint.LATIN_SMALL_X ? "HEX" : cp === CodePoint.LATIN_SMALL_O ? "OCTAL" : "BINARY";
|
|
20666
|
+
}
|
|
20667
|
+
if (cp === CodePoint.LATIN_SMALL_E || cp === CodePoint.LATIN_CAPITAL_E) {
|
|
20668
|
+
this.data = {
|
|
20669
|
+
minus: sign === CodePoint.DASH,
|
|
20670
|
+
left: [CodePoint.DIGIT_0]
|
|
20671
|
+
};
|
|
20672
|
+
return "EXPONENT_RIGHT";
|
|
20673
|
+
}
|
|
20674
|
+
if (cp === CodePoint.DOT) {
|
|
20675
|
+
this.data = {
|
|
20676
|
+
minus: sign === CodePoint.DASH,
|
|
20677
|
+
absInt: [CodePoint.DIGIT_0]
|
|
20678
|
+
};
|
|
20679
|
+
return "FRACTIONAL_RIGHT";
|
|
20680
|
+
}
|
|
20681
|
+
this.endToken("Integer", "start", "0", 10);
|
|
20682
|
+
return this.back("DATA");
|
|
20683
|
+
}
|
|
20684
|
+
const { out, nextCp, hasUnderscore } = this.parseDigits(cp, isDigit4);
|
|
20685
|
+
if (nextCp === CodePoint.DASH && sign === CodePoint.NULL && !hasUnderscore && out.length === 4) {
|
|
20686
|
+
this.data = {
|
|
20687
|
+
hasDate: true,
|
|
20688
|
+
year: Number(String.fromCodePoint(...out)),
|
|
20689
|
+
month: 0,
|
|
20690
|
+
day: 0,
|
|
20691
|
+
hour: 0,
|
|
20692
|
+
minute: 0,
|
|
20693
|
+
second: 0
|
|
20694
|
+
};
|
|
20695
|
+
return "DATE_MONTH";
|
|
20696
|
+
}
|
|
20697
|
+
if (nextCp === CodePoint.COLON && sign === CodePoint.NULL && !hasUnderscore && out.length === 2) {
|
|
20698
|
+
this.data = {
|
|
20699
|
+
hasDate: false,
|
|
20700
|
+
year: 0,
|
|
20701
|
+
month: 0,
|
|
20702
|
+
day: 0,
|
|
20703
|
+
hour: Number(String.fromCodePoint(...out)),
|
|
20704
|
+
minute: 0,
|
|
20705
|
+
second: 0
|
|
20706
|
+
};
|
|
20707
|
+
return "TIME_MINUTE";
|
|
20708
|
+
}
|
|
20709
|
+
if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
|
|
20710
|
+
this.data = {
|
|
20711
|
+
minus: sign === CodePoint.DASH,
|
|
20712
|
+
left: out
|
|
20713
|
+
};
|
|
20714
|
+
return "EXPONENT_RIGHT";
|
|
20715
|
+
}
|
|
20716
|
+
if (nextCp === CodePoint.DOT) {
|
|
20717
|
+
this.data = {
|
|
20718
|
+
minus: sign === CodePoint.DASH,
|
|
20719
|
+
absInt: out
|
|
20720
|
+
};
|
|
20721
|
+
return "FRACTIONAL_RIGHT";
|
|
20722
|
+
}
|
|
20723
|
+
this.endToken("Integer", "start", sign === CodePoint.DASH ? String.fromCodePoint(CodePoint.DASH, ...out) : String.fromCodePoint(...out), 10);
|
|
20724
|
+
return this.back("DATA");
|
|
20725
|
+
}
|
|
20726
|
+
HEX(cp) {
|
|
20727
|
+
const { out } = this.parseDigits(cp, isHexDig);
|
|
20728
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out), 16);
|
|
20729
|
+
return this.back("DATA");
|
|
20730
|
+
}
|
|
20731
|
+
OCTAL(cp) {
|
|
20732
|
+
const { out } = this.parseDigits(cp, isOctalDig);
|
|
20733
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out), 8);
|
|
20734
|
+
return this.back("DATA");
|
|
20735
|
+
}
|
|
20736
|
+
BINARY(cp) {
|
|
20737
|
+
const { out } = this.parseDigits(cp, (c) => c === CodePoint.DIGIT_0 || c === CodePoint.DIGIT_1);
|
|
20738
|
+
this.endToken("Integer", "start", String.fromCodePoint(...out), 2);
|
|
20739
|
+
return this.back("DATA");
|
|
20740
|
+
}
|
|
20741
|
+
FRACTIONAL_RIGHT(cp) {
|
|
20742
|
+
const { minus, absInt } = this.data;
|
|
20743
|
+
const { out, nextCp } = this.parseDigits(cp, isDigit4);
|
|
20744
|
+
const absNum = [
|
|
20745
|
+
...absInt,
|
|
20746
|
+
CodePoint.DOT,
|
|
20747
|
+
...out
|
|
20748
|
+
];
|
|
20749
|
+
if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
|
|
20750
|
+
this.data = {
|
|
20751
|
+
minus,
|
|
20752
|
+
left: absNum
|
|
20753
|
+
};
|
|
20754
|
+
return "EXPONENT_RIGHT";
|
|
20755
|
+
}
|
|
20756
|
+
const value = Number(minus ? String.fromCodePoint(CodePoint.DASH, ...absNum) : String.fromCodePoint(...absNum));
|
|
20757
|
+
this.endToken("Float", "start", value);
|
|
20758
|
+
return this.back("DATA");
|
|
20759
|
+
}
|
|
20760
|
+
EXPONENT_RIGHT(cp) {
|
|
20761
|
+
const { left, minus: leftMinus } = this.data;
|
|
20762
|
+
let minus = false;
|
|
20763
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
20764
|
+
minus = cp === CodePoint.DASH;
|
|
20765
|
+
cp = this.nextCode();
|
|
20766
|
+
}
|
|
20767
|
+
const { out } = this.parseDigits(cp, isDigit4);
|
|
20768
|
+
const right = out;
|
|
20769
|
+
if (minus) right.unshift(CodePoint.DASH);
|
|
20770
|
+
const value = Number(leftMinus ? String.fromCodePoint(CodePoint.DASH, ...left, CodePoint.LATIN_SMALL_E, ...right) : String.fromCodePoint(...left, CodePoint.LATIN_SMALL_E, ...right));
|
|
20771
|
+
this.endToken("Float", "start", value);
|
|
20772
|
+
return this.back("DATA");
|
|
20773
|
+
}
|
|
20774
|
+
BOOLEAN(cp) {
|
|
20775
|
+
if (cp === CodePoint.LATIN_SMALL_T) {
|
|
20776
|
+
const startPos = this.codePointIterator.start;
|
|
20777
|
+
if (this.eatCode(CodePoint.LATIN_SMALL_R) && this.eatCode(CodePoint.LATIN_SMALL_U) && this.eatCode(CodePoint.LATIN_SMALL_E)) {
|
|
20778
|
+
this.endToken("Boolean", "end", true);
|
|
20779
|
+
return "DATA";
|
|
20780
|
+
}
|
|
20781
|
+
this.moveAt(startPos);
|
|
20782
|
+
} else if (cp === CodePoint.LATIN_SMALL_F) {
|
|
20783
|
+
const startPos = this.codePointIterator.start;
|
|
20784
|
+
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)) {
|
|
20785
|
+
this.endToken("Boolean", "end", false);
|
|
20786
|
+
return "DATA";
|
|
20787
|
+
}
|
|
20788
|
+
this.moveAt(startPos);
|
|
20789
|
+
}
|
|
20790
|
+
return this.reportParseError("unexpected-char");
|
|
20791
|
+
}
|
|
20792
|
+
DATE_MONTH(cp) {
|
|
20793
|
+
const start = this.codePointIterator.start;
|
|
20794
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20795
|
+
cp = this.nextCode();
|
|
20796
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20797
|
+
cp = this.nextCode();
|
|
20798
|
+
if (cp !== CodePoint.DASH) return this.reportParseError("unexpected-char");
|
|
20799
|
+
const end = this.codePointIterator.start;
|
|
20800
|
+
const data = this.data;
|
|
20801
|
+
data.month = Number(this.text.slice(start, end));
|
|
20802
|
+
return "DATE_DAY";
|
|
20803
|
+
}
|
|
20804
|
+
DATE_DAY(cp) {
|
|
20805
|
+
const start = this.codePointIterator.start;
|
|
20806
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20807
|
+
cp = this.nextCode();
|
|
20808
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20809
|
+
const end = this.codePointIterator.end;
|
|
20810
|
+
const data = this.data;
|
|
20811
|
+
data.day = Number(this.text.slice(start, end));
|
|
20812
|
+
if (!isValidDate(data.year, data.month, data.day)) return this.reportParseError("invalid-date");
|
|
20813
|
+
cp = this.nextCode();
|
|
20814
|
+
if (cp === CodePoint.LATIN_CAPITAL_T || cp === CodePoint.LATIN_SMALL_T) return "TIME_HOUR";
|
|
20815
|
+
if (cp === CodePoint.SPACE) {
|
|
20816
|
+
const startPos = this.codePointIterator.start;
|
|
20817
|
+
if (isDigit4(this.nextCode()) && isDigit4(this.nextCode())) {
|
|
20818
|
+
this.moveAt(startPos);
|
|
20819
|
+
return "TIME_HOUR";
|
|
20820
|
+
}
|
|
20821
|
+
this.moveAt(startPos);
|
|
20822
|
+
}
|
|
20823
|
+
const dateValue = getDateFromDateTimeData(data, "");
|
|
20824
|
+
this.endToken("LocalDate", "start", dateValue);
|
|
20825
|
+
return this.back("DATA");
|
|
20826
|
+
}
|
|
20827
|
+
TIME_HOUR(cp) {
|
|
20828
|
+
const start = this.codePointIterator.start;
|
|
20829
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20830
|
+
cp = this.nextCode();
|
|
20831
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20832
|
+
cp = this.nextCode();
|
|
20833
|
+
if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
|
|
20834
|
+
const end = this.codePointIterator.start;
|
|
20835
|
+
const data = this.data;
|
|
20836
|
+
data.hour = Number(this.text.slice(start, end));
|
|
20837
|
+
return "TIME_MINUTE";
|
|
20838
|
+
}
|
|
20839
|
+
TIME_MINUTE(cp) {
|
|
20840
|
+
const start = this.codePointIterator.start;
|
|
20841
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20842
|
+
cp = this.nextCode();
|
|
20843
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20844
|
+
const end = this.codePointIterator.end;
|
|
20845
|
+
const data = this.data;
|
|
20846
|
+
data.minute = Number(this.text.slice(start, end));
|
|
20847
|
+
cp = this.nextCode();
|
|
20848
|
+
if (cp === CodePoint.COLON) return "TIME_SECOND";
|
|
20849
|
+
if (this.tomlVersion.lt(1, 1)) return this.reportParseError("unexpected-char");
|
|
20850
|
+
if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
|
|
20851
|
+
return this.processTimeEnd(cp, data);
|
|
20852
|
+
}
|
|
20853
|
+
TIME_SECOND(cp) {
|
|
20854
|
+
const start = this.codePointIterator.start;
|
|
20855
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20856
|
+
cp = this.nextCode();
|
|
20857
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20858
|
+
const end = this.codePointIterator.end;
|
|
20859
|
+
const data = this.data;
|
|
20860
|
+
data.second = Number(this.text.slice(start, end));
|
|
20861
|
+
if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
|
|
20862
|
+
cp = this.nextCode();
|
|
20863
|
+
if (cp === CodePoint.DOT) return "TIME_SEC_FRAC";
|
|
20864
|
+
return this.processTimeEnd(cp, data);
|
|
20865
|
+
}
|
|
20866
|
+
TIME_SEC_FRAC(cp) {
|
|
20867
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20868
|
+
const start = this.codePointIterator.start;
|
|
20869
|
+
while (isDigit4(cp)) cp = this.nextCode();
|
|
20870
|
+
const end = this.codePointIterator.start;
|
|
20871
|
+
const data = this.data;
|
|
20872
|
+
data.frac = this.text.slice(start, end);
|
|
20873
|
+
return this.processTimeEnd(cp, data);
|
|
20874
|
+
}
|
|
20875
|
+
processTimeEnd(cp, data) {
|
|
20876
|
+
if (data.hasDate) {
|
|
20877
|
+
if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
|
|
20878
|
+
data.offsetSign = cp;
|
|
20879
|
+
return "TIME_OFFSET";
|
|
20880
|
+
}
|
|
20881
|
+
if (cp === CodePoint.LATIN_CAPITAL_Z || cp === CodePoint.LATIN_SMALL_Z) {
|
|
20882
|
+
const dateValue$2 = getDateFromDateTimeData(data, "Z");
|
|
20883
|
+
this.endToken("OffsetDateTime", "end", dateValue$2);
|
|
20884
|
+
return "DATA";
|
|
20885
|
+
}
|
|
20886
|
+
const dateValue$1 = getDateFromDateTimeData(data, "");
|
|
20887
|
+
this.endToken("LocalDateTime", "start", dateValue$1);
|
|
20888
|
+
return this.back("DATA");
|
|
20889
|
+
}
|
|
20890
|
+
const dateValue = getDateFromDateTimeData(data, "");
|
|
20891
|
+
this.endToken("LocalTime", "start", dateValue);
|
|
20892
|
+
return this.back("DATA");
|
|
20893
|
+
}
|
|
20894
|
+
TIME_OFFSET(cp) {
|
|
20895
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20896
|
+
const hourStart = this.codePointIterator.start;
|
|
20897
|
+
cp = this.nextCode();
|
|
20898
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20899
|
+
cp = this.nextCode();
|
|
20900
|
+
if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
|
|
20901
|
+
const hourEnd = this.codePointIterator.start;
|
|
20902
|
+
cp = this.nextCode();
|
|
20903
|
+
const minuteStart = this.codePointIterator.start;
|
|
20904
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20905
|
+
cp = this.nextCode();
|
|
20906
|
+
if (!isDigit4(cp)) return this.reportParseError("unexpected-char");
|
|
20907
|
+
const minuteEnd = this.codePointIterator.end;
|
|
20908
|
+
const hour = Number(this.text.slice(hourStart, hourEnd));
|
|
20909
|
+
const minute = Number(this.text.slice(minuteStart, minuteEnd));
|
|
20910
|
+
if (!isValidTime(hour, minute, 0)) return this.reportParseError("invalid-time");
|
|
20911
|
+
const data = this.data;
|
|
20912
|
+
const dateValue = getDateFromDateTimeData(data, `${String.fromCodePoint(data.offsetSign)}${padStart(hour, 2)}:${padStart(minute, 2)}`);
|
|
20913
|
+
this.endToken("OffsetDateTime", "end", dateValue);
|
|
20914
|
+
return "DATA";
|
|
20915
|
+
}
|
|
20916
|
+
parseDigits(cp, checkDigit) {
|
|
20917
|
+
if (cp === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
20918
|
+
if (!checkDigit(cp)) return this.reportParseError("unexpected-char");
|
|
20919
|
+
const out = [];
|
|
20920
|
+
let before = CodePoint.NULL;
|
|
20921
|
+
let hasUnderscore = false;
|
|
20922
|
+
while (checkDigit(cp) || cp === CodePoint.UNDERSCORE) {
|
|
20923
|
+
if (cp === CodePoint.UNDERSCORE) {
|
|
20924
|
+
hasUnderscore = true;
|
|
20925
|
+
if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
20926
|
+
} else out.push(cp);
|
|
20927
|
+
before = cp;
|
|
20928
|
+
cp = this.nextCode();
|
|
20929
|
+
}
|
|
20930
|
+
if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
|
|
20931
|
+
return {
|
|
20932
|
+
out,
|
|
20933
|
+
nextCp: cp,
|
|
20934
|
+
hasUnderscore
|
|
20935
|
+
};
|
|
20936
|
+
}
|
|
20937
|
+
parseUnicode(count) {
|
|
20938
|
+
const startLoc = this.codePointIterator.start;
|
|
20939
|
+
const start = this.codePointIterator.end;
|
|
20940
|
+
let charCount = 0;
|
|
20941
|
+
let cp;
|
|
20942
|
+
while ((cp = this.nextCode()) !== CodePoint.EOF) {
|
|
20943
|
+
if (!isHexDig(cp)) {
|
|
20944
|
+
this.moveAt(startLoc);
|
|
20945
|
+
return this.reportParseError("invalid-char-in-escape-sequence");
|
|
20946
|
+
}
|
|
20947
|
+
charCount++;
|
|
20948
|
+
if (charCount >= count) break;
|
|
20949
|
+
}
|
|
20950
|
+
const end = this.codePointIterator.end;
|
|
20951
|
+
const code = this.text.slice(start, end);
|
|
20952
|
+
const codePoint = parseInt(code, 16);
|
|
20953
|
+
if (!isUnicodeScalarValue(codePoint)) return this.reportParseError("invalid-code-point", { cp: code });
|
|
20954
|
+
return codePoint;
|
|
20955
|
+
}
|
|
20956
|
+
reportParseErrorControlChar() {
|
|
20957
|
+
return this.reportParseError("invalid-control-character");
|
|
20958
|
+
}
|
|
20959
|
+
};
|
|
20960
|
+
function isUnquotedKeyChar(cp, tomlVersion) {
|
|
20961
|
+
if (isLetter2(cp) || isDigit4(cp) || cp === CodePoint.UNDERSCORE || cp === CodePoint.DASH) return true;
|
|
20962
|
+
if (tomlVersion.lt(1, 1)) return false;
|
|
20963
|
+
return false;
|
|
19865
20964
|
}
|
|
19866
|
-
function
|
|
19867
|
-
|
|
19868
|
-
for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join7(root, name), V1_REASON.dataRoot, out);
|
|
19869
|
-
if (firstTmpMatch(tmp) !== null) out.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
|
|
20965
|
+
function isControlOtherThanTab(cp) {
|
|
20966
|
+
return isControl(cp) && cp !== CodePoint.TABULATION || cp === CodePoint.DELETE;
|
|
19870
20967
|
}
|
|
19871
|
-
function
|
|
19872
|
-
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
|
|
19878
|
-
|
|
19879
|
-
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
19886
|
-
|
|
19887
|
-
|
|
19888
|
-
|
|
19889
|
-
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
|
|
19897
|
-
|
|
19898
|
-
|
|
19899
|
-
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
|
|
20968
|
+
function isNonEOL(cp) {
|
|
20969
|
+
return cp === CodePoint.TABULATION || CodePoint.SPACE <= cp && cp <= CodePoint.TILDE || isNonAscii(cp);
|
|
20970
|
+
}
|
|
20971
|
+
function isNonAscii(cp) {
|
|
20972
|
+
return CodePoint.PAD <= cp && cp <= CodePoint.CP_D7FF || CodePoint.CP_E000 <= cp && cp <= CodePoint.CP_10FFFF;
|
|
20973
|
+
}
|
|
20974
|
+
function isValidDate(y, m, d) {
|
|
20975
|
+
if (y >= 0 && m <= 12 && m >= 1 && d >= 1) return d <= (m === 2 ? y & 3 || !(y % 25) && y & 15 ? 28 : 29 : 30 + (m + (m >> 3) & 1));
|
|
20976
|
+
return false;
|
|
20977
|
+
}
|
|
20978
|
+
function isValidTime(h, m, s) {
|
|
20979
|
+
if (h >= 24 || h < 0 || m > 59 || m < 0 || s > 60 || s < 0) return false;
|
|
20980
|
+
return true;
|
|
20981
|
+
}
|
|
20982
|
+
function getDateFromDateTimeData(data, timeZone) {
|
|
20983
|
+
const year = padStart(data.year, 4);
|
|
20984
|
+
const month = data.month ? padStart(data.month, 2) : "01";
|
|
20985
|
+
const day = data.day ? padStart(data.day, 2) : "01";
|
|
20986
|
+
const hour = padStart(data.hour, 2);
|
|
20987
|
+
const minute = padStart(data.minute, 2);
|
|
20988
|
+
const second = padStart(data.second, 2);
|
|
20989
|
+
const textDate = `${year}-${month}-${day}`;
|
|
20990
|
+
const frac = data.frac ? `.${data.frac}` : "";
|
|
20991
|
+
const dateValue = /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:${second}${frac}${timeZone}`);
|
|
20992
|
+
if (!isNaN(dateValue.getTime()) || data.second !== 60) return dateValue;
|
|
20993
|
+
return /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:59${frac}${timeZone}`);
|
|
20994
|
+
}
|
|
20995
|
+
function padStart(num, maxLength) {
|
|
20996
|
+
return String(num).padStart(maxLength, "0");
|
|
20997
|
+
}
|
|
20998
|
+
var VALUE_KIND_VALUE = Symbol("VALUE_KIND_VALUE");
|
|
20999
|
+
var VALUE_KIND_INTERMEDIATE = Symbol("VALUE_KIND_INTERMEDIATE");
|
|
21000
|
+
var KeysResolver = class {
|
|
21001
|
+
constructor(ctx) {
|
|
21002
|
+
this.rootKeys = /* @__PURE__ */ new Map();
|
|
21003
|
+
this.tables = [];
|
|
21004
|
+
this.ctx = ctx;
|
|
21005
|
+
}
|
|
21006
|
+
applyResolveKeyForTable(node) {
|
|
21007
|
+
let keys = this.rootKeys;
|
|
21008
|
+
const peekKeyIndex = node.key.keys.length - 1;
|
|
21009
|
+
for (let index = 0; index < peekKeyIndex; index++) {
|
|
21010
|
+
const keyNode = node.key.keys[index];
|
|
21011
|
+
const keyName = toKeyName(keyNode);
|
|
21012
|
+
node.resolvedKey.push(keyName);
|
|
21013
|
+
let keyStore = keys.get(keyName);
|
|
21014
|
+
if (!keyStore) {
|
|
21015
|
+
keyStore = {
|
|
21016
|
+
node: keyNode,
|
|
21017
|
+
keys: /* @__PURE__ */ new Map()
|
|
21018
|
+
};
|
|
21019
|
+
keys.set(keyName, keyStore);
|
|
21020
|
+
} else if (keyStore.table === "array") {
|
|
21021
|
+
const peekIndex = keyStore.peekIndex;
|
|
21022
|
+
node.resolvedKey.push(peekIndex);
|
|
21023
|
+
keyStore = keyStore.keys.get(peekIndex);
|
|
21024
|
+
}
|
|
21025
|
+
keys = keyStore.keys;
|
|
21026
|
+
}
|
|
21027
|
+
const lastKeyNode = node.key.keys[peekKeyIndex];
|
|
21028
|
+
const lastKeyName = toKeyName(lastKeyNode);
|
|
21029
|
+
node.resolvedKey.push(lastKeyName);
|
|
21030
|
+
const lastKeyStore = keys.get(lastKeyName);
|
|
21031
|
+
if (!lastKeyStore) if (node.kind === "array") {
|
|
21032
|
+
node.resolvedKey.push(0);
|
|
21033
|
+
const newKeyStore = {
|
|
21034
|
+
node: lastKeyNode,
|
|
21035
|
+
keys: /* @__PURE__ */ new Map()
|
|
21036
|
+
};
|
|
21037
|
+
keys.set(lastKeyName, {
|
|
21038
|
+
table: node.kind,
|
|
21039
|
+
node: lastKeyNode,
|
|
21040
|
+
keys: /* @__PURE__ */ new Map([[0, newKeyStore]]),
|
|
21041
|
+
peekIndex: 0
|
|
21042
|
+
});
|
|
21043
|
+
this.tables.push({
|
|
21044
|
+
node,
|
|
21045
|
+
keys: newKeyStore.keys
|
|
21046
|
+
});
|
|
21047
|
+
} else {
|
|
21048
|
+
const newKeyStore = {
|
|
21049
|
+
table: node.kind,
|
|
21050
|
+
node: lastKeyNode,
|
|
21051
|
+
keys: /* @__PURE__ */ new Map()
|
|
21052
|
+
};
|
|
21053
|
+
keys.set(lastKeyName, newKeyStore);
|
|
21054
|
+
this.tables.push({
|
|
21055
|
+
node,
|
|
21056
|
+
keys: newKeyStore.keys
|
|
21057
|
+
});
|
|
21058
|
+
}
|
|
21059
|
+
else if (!lastKeyStore.table) if (node.kind === "array") this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
21060
|
+
else {
|
|
21061
|
+
const transformKey = {
|
|
21062
|
+
table: node.kind,
|
|
21063
|
+
node: lastKeyNode,
|
|
21064
|
+
keys: lastKeyStore.keys
|
|
21065
|
+
};
|
|
21066
|
+
keys.set(lastKeyName, transformKey);
|
|
21067
|
+
this.tables.push({
|
|
21068
|
+
node,
|
|
21069
|
+
keys: transformKey.keys
|
|
21070
|
+
});
|
|
21071
|
+
}
|
|
21072
|
+
else if (lastKeyStore.table === "array") if (node.kind === "array") {
|
|
21073
|
+
const newKeyStore = {
|
|
21074
|
+
node: lastKeyNode,
|
|
21075
|
+
keys: /* @__PURE__ */ new Map()
|
|
21076
|
+
};
|
|
21077
|
+
const newIndex = lastKeyStore.peekIndex + 1;
|
|
21078
|
+
node.resolvedKey.push(newIndex);
|
|
21079
|
+
lastKeyStore.keys.set(newIndex, newKeyStore);
|
|
21080
|
+
lastKeyStore.peekIndex = newIndex;
|
|
21081
|
+
this.tables.push({
|
|
21082
|
+
node,
|
|
21083
|
+
keys: newKeyStore.keys
|
|
21084
|
+
});
|
|
21085
|
+
} else this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
21086
|
+
else this.ctx.reportParseError("dupe-keys", lastKeyNode);
|
|
21087
|
+
}
|
|
21088
|
+
verifyDuplicateKeys(node) {
|
|
21089
|
+
for (const body of node.body) if (body.type === "TOMLKeyValue") verifyDuplicateKeysForKeyValue(this.ctx, this.rootKeys, body);
|
|
21090
|
+
for (const { node: tableNode, keys } of this.tables) for (const body of tableNode.body) verifyDuplicateKeysForKeyValue(this.ctx, keys, body);
|
|
21091
|
+
}
|
|
21092
|
+
};
|
|
21093
|
+
function verifyDuplicateKeysForKeyValue(ctx, defineKeys, node) {
|
|
21094
|
+
let keys = defineKeys;
|
|
21095
|
+
const lastKey = last(node.key.keys);
|
|
21096
|
+
for (const keyNode of node.key.keys) {
|
|
21097
|
+
const key = toKeyName(keyNode);
|
|
21098
|
+
let defineKey = keys.get(key);
|
|
21099
|
+
if (defineKey) {
|
|
21100
|
+
if (defineKey.value === VALUE_KIND_VALUE) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
21101
|
+
else if (lastKey === keyNode) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
21102
|
+
else if (defineKey.table) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
|
|
21103
|
+
defineKey.value = VALUE_KIND_INTERMEDIATE;
|
|
21104
|
+
} else {
|
|
21105
|
+
if (lastKey === keyNode) defineKey = {
|
|
21106
|
+
value: VALUE_KIND_VALUE,
|
|
21107
|
+
node: keyNode,
|
|
21108
|
+
keys: /* @__PURE__ */ new Map()
|
|
21109
|
+
};
|
|
21110
|
+
else defineKey = {
|
|
21111
|
+
value: VALUE_KIND_INTERMEDIATE,
|
|
21112
|
+
node: keyNode,
|
|
21113
|
+
keys: /* @__PURE__ */ new Map()
|
|
21114
|
+
};
|
|
21115
|
+
keys.set(key, defineKey);
|
|
21116
|
+
}
|
|
21117
|
+
keys = defineKey.keys;
|
|
21118
|
+
}
|
|
21119
|
+
if (node.value.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, keys, node.value);
|
|
21120
|
+
else if (node.value.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, keys, node.value);
|
|
21121
|
+
}
|
|
21122
|
+
function verifyDuplicateKeysForInlineTable(ctx, defineKeys, node) {
|
|
21123
|
+
for (const body of node.body) verifyDuplicateKeysForKeyValue(ctx, defineKeys, body);
|
|
21124
|
+
}
|
|
21125
|
+
function verifyDuplicateKeysForArray(ctx, defineKeys, node) {
|
|
21126
|
+
const keys = defineKeys;
|
|
21127
|
+
for (let index = 0; index < node.elements.length; index++) {
|
|
21128
|
+
const element2 = node.elements[index];
|
|
21129
|
+
let defineKey = keys.get(index);
|
|
21130
|
+
if (defineKey) ctx.reportParseError("dupe-keys", getAfterNode(element2, defineKey.node));
|
|
21131
|
+
else {
|
|
21132
|
+
defineKey = {
|
|
21133
|
+
value: VALUE_KIND_VALUE,
|
|
21134
|
+
node: element2,
|
|
21135
|
+
keys: /* @__PURE__ */ new Map()
|
|
21136
|
+
};
|
|
21137
|
+
defineKeys.set(index, defineKey);
|
|
21138
|
+
if (element2.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, defineKey.keys, element2);
|
|
21139
|
+
else if (element2.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, defineKey.keys, element2);
|
|
21140
|
+
}
|
|
21141
|
+
}
|
|
21142
|
+
}
|
|
21143
|
+
function getAfterNode(a, b) {
|
|
21144
|
+
return a.range[0] <= b.range[0] ? b : a;
|
|
21145
|
+
}
|
|
21146
|
+
var Context = class {
|
|
21147
|
+
constructor(data) {
|
|
21148
|
+
this.tokens = [];
|
|
21149
|
+
this.comments = [];
|
|
21150
|
+
this.back = null;
|
|
21151
|
+
this.stateStack = [];
|
|
21152
|
+
this.needNewLine = false;
|
|
21153
|
+
this.needSameLine = false;
|
|
21154
|
+
this.currToken = null;
|
|
21155
|
+
this.prevToken = null;
|
|
21156
|
+
this.valueContainerStack = [];
|
|
21157
|
+
this.tokenizer = new Tokenizer(data.text, data.parserOptions);
|
|
21158
|
+
this.topLevelTable = data.topLevelTable;
|
|
21159
|
+
this.table = data.topLevelTable;
|
|
21160
|
+
this.keysResolver = new KeysResolver(this);
|
|
21161
|
+
}
|
|
21162
|
+
/**
|
|
21163
|
+
* Get the next token.
|
|
21164
|
+
*/
|
|
21165
|
+
nextToken(option) {
|
|
21166
|
+
this.prevToken = this.currToken;
|
|
21167
|
+
if (this.back) {
|
|
21168
|
+
this.currToken = this.back;
|
|
21169
|
+
this.back = null;
|
|
21170
|
+
} else this.currToken = this._nextTokenFromTokenizer(option);
|
|
21171
|
+
if ((this.needNewLine || this.needSameLine || option?.needSameLine) && this.prevToken && this.currToken) if (this.prevToken.loc.end.line === this.currToken.loc.start.line) {
|
|
21172
|
+
if (this.needNewLine) return this.reportParseError("missing-newline", this.currToken);
|
|
21173
|
+
} else {
|
|
21174
|
+
const needSameLine = this.needSameLine || option?.needSameLine;
|
|
21175
|
+
if (needSameLine) return this.reportParseError(needSameLine, this.currToken);
|
|
21176
|
+
}
|
|
21177
|
+
this.needNewLine = false;
|
|
21178
|
+
this.needSameLine = false;
|
|
21179
|
+
return this.currToken;
|
|
21180
|
+
}
|
|
21181
|
+
_nextTokenFromTokenizer(option) {
|
|
21182
|
+
const valuesEnabled = this.tokenizer.valuesEnabled;
|
|
21183
|
+
if (option?.valuesEnabled) this.tokenizer.valuesEnabled = option.valuesEnabled;
|
|
21184
|
+
let token = this.tokenizer.nextToken();
|
|
21185
|
+
while (token && token.type === "Block") {
|
|
21186
|
+
this.comments.push(token);
|
|
21187
|
+
token = this.tokenizer.nextToken();
|
|
21188
|
+
}
|
|
21189
|
+
if (token) this.tokens.push(token);
|
|
21190
|
+
this.tokenizer.valuesEnabled = valuesEnabled;
|
|
21191
|
+
return token;
|
|
21192
|
+
}
|
|
21193
|
+
backToken() {
|
|
21194
|
+
if (this.back) throw new Error("Illegal state");
|
|
21195
|
+
this.back = this.currToken;
|
|
21196
|
+
this.currToken = this.prevToken;
|
|
21197
|
+
}
|
|
21198
|
+
addValueContainer(valueContainer) {
|
|
21199
|
+
this.valueContainerStack.push(valueContainer);
|
|
21200
|
+
this.tokenizer.valuesEnabled = true;
|
|
21201
|
+
}
|
|
21202
|
+
consumeValueContainer() {
|
|
21203
|
+
const valueContainer = this.valueContainerStack.pop();
|
|
21204
|
+
this.tokenizer.valuesEnabled = this.valueContainerStack.length > 0;
|
|
21205
|
+
return valueContainer;
|
|
21206
|
+
}
|
|
21207
|
+
applyResolveKeyForTable(node) {
|
|
21208
|
+
this.keysResolver.applyResolveKeyForTable(node);
|
|
21209
|
+
}
|
|
21210
|
+
verifyDuplicateKeys() {
|
|
21211
|
+
this.keysResolver.verifyDuplicateKeys(this.topLevelTable);
|
|
21212
|
+
}
|
|
21213
|
+
/**
|
|
21214
|
+
* Report an invalid token error.
|
|
21215
|
+
*/
|
|
21216
|
+
reportParseError(code, token) {
|
|
21217
|
+
let offset, line, column;
|
|
21218
|
+
if (token) {
|
|
21219
|
+
offset = token.range[0];
|
|
21220
|
+
line = token.loc.start.line;
|
|
21221
|
+
column = token.loc.start.column;
|
|
21222
|
+
} else {
|
|
21223
|
+
offset = this.tokenizer.start;
|
|
21224
|
+
const startPos = this.tokenizer.getLocFromIndex(offset);
|
|
21225
|
+
line = startPos.line;
|
|
21226
|
+
column = startPos.column;
|
|
21227
|
+
}
|
|
21228
|
+
throw new ParseError(code, offset, line, column);
|
|
21229
|
+
}
|
|
21230
|
+
};
|
|
21231
|
+
var STATE_FOR_ERROR = { VALUE: "missing-value" };
|
|
21232
|
+
var STRING_VALUE_STYLE_MAP = {
|
|
21233
|
+
BasicString: "basic",
|
|
21234
|
+
MultiLineBasicString: "basic",
|
|
21235
|
+
LiteralString: "literal",
|
|
21236
|
+
MultiLineLiteralString: "literal"
|
|
21237
|
+
};
|
|
21238
|
+
var STRING_KEY_STYLE_MAP = {
|
|
21239
|
+
BasicString: "basic",
|
|
21240
|
+
LiteralString: "literal"
|
|
21241
|
+
};
|
|
21242
|
+
var DATETIME_VALUE_KIND_MAP = {
|
|
21243
|
+
OffsetDateTime: "offset-date-time",
|
|
21244
|
+
LocalDateTime: "local-date-time",
|
|
21245
|
+
LocalDate: "local-date",
|
|
21246
|
+
LocalTime: "local-time"
|
|
21247
|
+
};
|
|
21248
|
+
var TOMLParser = class {
|
|
21249
|
+
/**
|
|
21250
|
+
* Initialize this parser.
|
|
21251
|
+
*/
|
|
21252
|
+
constructor(text, parserOptions) {
|
|
21253
|
+
this.text = text;
|
|
21254
|
+
this.parserOptions = parserOptions || {};
|
|
21255
|
+
this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
|
|
21256
|
+
}
|
|
21257
|
+
/**
|
|
21258
|
+
* Parse TOML
|
|
21259
|
+
*/
|
|
21260
|
+
parse() {
|
|
21261
|
+
const ast = {
|
|
21262
|
+
type: "Program",
|
|
21263
|
+
body: [],
|
|
21264
|
+
sourceType: "module",
|
|
21265
|
+
tokens: [],
|
|
21266
|
+
comments: [],
|
|
21267
|
+
parent: null,
|
|
21268
|
+
range: [0, 0],
|
|
21269
|
+
loc: {
|
|
21270
|
+
start: {
|
|
21271
|
+
line: 1,
|
|
21272
|
+
column: 0
|
|
21273
|
+
},
|
|
21274
|
+
end: {
|
|
21275
|
+
line: 1,
|
|
21276
|
+
column: 0
|
|
21277
|
+
}
|
|
21278
|
+
}
|
|
21279
|
+
};
|
|
21280
|
+
const node = {
|
|
21281
|
+
type: "TOMLTopLevelTable",
|
|
21282
|
+
body: [],
|
|
21283
|
+
parent: ast,
|
|
21284
|
+
range: cloneRange(ast.range),
|
|
21285
|
+
loc: cloneLoc(ast.loc)
|
|
21286
|
+
};
|
|
21287
|
+
ast.body = [node];
|
|
21288
|
+
const ctx = new Context({
|
|
21289
|
+
text: this.text,
|
|
21290
|
+
parserOptions: this.parserOptions,
|
|
21291
|
+
topLevelTable: node
|
|
21292
|
+
});
|
|
21293
|
+
let token = ctx.nextToken();
|
|
21294
|
+
if (token) {
|
|
21295
|
+
node.range[0] = token.range[0];
|
|
21296
|
+
node.loc.start = clonePos(token.loc.start);
|
|
21297
|
+
while (token) {
|
|
21298
|
+
const state$1 = ctx.stateStack.pop() || "TABLE";
|
|
21299
|
+
ctx.stateStack.push(...this[state$1](token, ctx));
|
|
21300
|
+
token = ctx.nextToken();
|
|
21301
|
+
}
|
|
21302
|
+
const state = ctx.stateStack.pop() || "TABLE";
|
|
21303
|
+
if (state in STATE_FOR_ERROR) return ctx.reportParseError(STATE_FOR_ERROR[state], null);
|
|
21304
|
+
if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
|
|
21305
|
+
applyEndLoc(node, last(node.body));
|
|
21306
|
+
}
|
|
21307
|
+
ctx.verifyDuplicateKeys();
|
|
21308
|
+
ast.tokens = ctx.tokens;
|
|
21309
|
+
ast.comments = ctx.comments;
|
|
21310
|
+
const endOffset = ctx.tokenizer.end;
|
|
21311
|
+
const endPos = ctx.tokenizer.getLocFromIndex(endOffset);
|
|
21312
|
+
ast.range[1] = endOffset;
|
|
21313
|
+
ast.loc.end = {
|
|
21314
|
+
line: endPos.line,
|
|
21315
|
+
column: endPos.column
|
|
21316
|
+
};
|
|
21317
|
+
return ast;
|
|
21318
|
+
}
|
|
21319
|
+
TABLE(token, ctx) {
|
|
21320
|
+
if (isBare(token) || isString(token)) return this.processKeyValue(token, ctx.table, ctx);
|
|
21321
|
+
if (isLeftBracket(token)) return this.processTable(token, ctx.topLevelTable, ctx);
|
|
21322
|
+
return ctx.reportParseError("unexpected-token", token);
|
|
21323
|
+
}
|
|
21324
|
+
VALUE(token, ctx) {
|
|
21325
|
+
if (isString(token) || isMultiLineString(token)) return this.processStringValue(token, ctx);
|
|
21326
|
+
if (isNumber(token)) return this.processNumberValue(token, ctx);
|
|
21327
|
+
if (isBoolean(token)) return this.processBooleanValue(token, ctx);
|
|
21328
|
+
if (isDateTime(token)) return this.processDateTimeValue(token, ctx);
|
|
21329
|
+
if (isLeftBracket(token)) return this.processArray(token, ctx);
|
|
21330
|
+
if (isLeftBrace(token)) return this.processInlineTable(token, ctx);
|
|
21331
|
+
return ctx.reportParseError("unexpected-token", token);
|
|
21332
|
+
}
|
|
21333
|
+
processTable(token, topLevelTableNode, ctx) {
|
|
21334
|
+
const tableNode = {
|
|
21335
|
+
type: "TOMLTable",
|
|
21336
|
+
kind: "standard",
|
|
21337
|
+
key: null,
|
|
21338
|
+
resolvedKey: [],
|
|
21339
|
+
body: [],
|
|
21340
|
+
parent: topLevelTableNode,
|
|
21341
|
+
range: cloneRange(token.range),
|
|
21342
|
+
loc: cloneLoc(token.loc)
|
|
21343
|
+
};
|
|
21344
|
+
if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
|
|
21345
|
+
topLevelTableNode.body.push(tableNode);
|
|
21346
|
+
ctx.table = tableNode;
|
|
21347
|
+
let targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
21348
|
+
if (isLeftBracket(targetToken)) {
|
|
21349
|
+
if (token.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
|
|
21350
|
+
tableNode.kind = "array";
|
|
21351
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
21352
|
+
}
|
|
21353
|
+
if (isRightBracket(targetToken)) return ctx.reportParseError("missing-key", targetToken);
|
|
21354
|
+
if (!targetToken) return ctx.reportParseError("unterminated-table-key", null);
|
|
21355
|
+
targetToken = this.processKeyNode(targetToken, tableNode, ctx).nextToken;
|
|
21356
|
+
if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
|
|
21357
|
+
if (tableNode.kind === "array") {
|
|
21358
|
+
const rightBracket = targetToken;
|
|
21359
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
21360
|
+
if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
|
|
21361
|
+
if (rightBracket.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
|
|
21362
|
+
}
|
|
21363
|
+
applyEndLoc(tableNode, targetToken);
|
|
21364
|
+
ctx.applyResolveKeyForTable(tableNode);
|
|
21365
|
+
ctx.needNewLine = true;
|
|
21366
|
+
return [];
|
|
21367
|
+
}
|
|
21368
|
+
processKeyValue(token, tableNode, ctx) {
|
|
21369
|
+
const keyValueNode = {
|
|
21370
|
+
type: "TOMLKeyValue",
|
|
21371
|
+
key: null,
|
|
21372
|
+
value: null,
|
|
21373
|
+
parent: tableNode,
|
|
21374
|
+
range: cloneRange(token.range),
|
|
21375
|
+
loc: cloneLoc(token.loc)
|
|
21376
|
+
};
|
|
21377
|
+
tableNode.body.push(keyValueNode);
|
|
21378
|
+
const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
|
|
21379
|
+
if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
|
|
21380
|
+
ctx.addValueContainer({
|
|
21381
|
+
parent: keyValueNode,
|
|
21382
|
+
set: (valNode) => {
|
|
21383
|
+
keyValueNode.value = valNode;
|
|
21384
|
+
applyEndLoc(keyValueNode, valNode);
|
|
21385
|
+
ctx.needNewLine = true;
|
|
21386
|
+
return [];
|
|
21387
|
+
}
|
|
21388
|
+
});
|
|
21389
|
+
ctx.needSameLine = "invalid-key-value-newline";
|
|
21390
|
+
return ["VALUE"];
|
|
21391
|
+
}
|
|
21392
|
+
processKeyNode(token, parent, ctx) {
|
|
21393
|
+
if (isDot(token)) ctx.reportParseError("invalid-leading-dot-in-key", token);
|
|
21394
|
+
const keyNode = {
|
|
21395
|
+
type: "TOMLKey",
|
|
21396
|
+
keys: [],
|
|
21397
|
+
parent,
|
|
21398
|
+
range: cloneRange(token.range),
|
|
21399
|
+
loc: cloneLoc(token.loc)
|
|
21400
|
+
};
|
|
21401
|
+
parent.key = keyNode;
|
|
21402
|
+
let targetToken = token;
|
|
21403
|
+
let dotToken = null;
|
|
21404
|
+
do {
|
|
21405
|
+
if (isBare(targetToken)) this.processBareKey(targetToken, keyNode);
|
|
21406
|
+
else if (isString(targetToken)) this.processStringKey(targetToken, keyNode);
|
|
21407
|
+
else break;
|
|
21408
|
+
dotToken = null;
|
|
21409
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
21410
|
+
if (!isDot(targetToken)) break;
|
|
21411
|
+
dotToken = targetToken;
|
|
21412
|
+
targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
|
|
21413
|
+
} while (targetToken);
|
|
21414
|
+
if (dotToken) ctx.reportParseError(isDot(targetToken) ? "invalid-consecutive-dots-in-key" : "invalid-trailing-dot-in-key", dotToken);
|
|
21415
|
+
applyEndLoc(keyNode, last(keyNode.keys));
|
|
21416
|
+
return {
|
|
21417
|
+
keyNode,
|
|
21418
|
+
nextToken: targetToken
|
|
21419
|
+
};
|
|
21420
|
+
}
|
|
21421
|
+
processBareKey(token, keyNode) {
|
|
21422
|
+
const node = {
|
|
21423
|
+
type: "TOMLBare",
|
|
21424
|
+
name: token.value,
|
|
21425
|
+
parent: keyNode,
|
|
21426
|
+
range: cloneRange(token.range),
|
|
21427
|
+
loc: cloneLoc(token.loc)
|
|
21428
|
+
};
|
|
21429
|
+
keyNode.keys.push(node);
|
|
21430
|
+
}
|
|
21431
|
+
processStringKey(token, keyNode) {
|
|
21432
|
+
const node = {
|
|
21433
|
+
type: "TOMLQuoted",
|
|
21434
|
+
kind: "string",
|
|
21435
|
+
value: token.string,
|
|
21436
|
+
style: STRING_KEY_STYLE_MAP[token.type],
|
|
21437
|
+
multiline: false,
|
|
21438
|
+
parent: keyNode,
|
|
21439
|
+
range: cloneRange(token.range),
|
|
21440
|
+
loc: cloneLoc(token.loc)
|
|
21441
|
+
};
|
|
21442
|
+
keyNode.keys.push(node);
|
|
21443
|
+
}
|
|
21444
|
+
processStringValue(token, ctx) {
|
|
21445
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21446
|
+
const node = {
|
|
21447
|
+
type: "TOMLValue",
|
|
21448
|
+
kind: "string",
|
|
21449
|
+
value: token.string,
|
|
21450
|
+
style: STRING_VALUE_STYLE_MAP[token.type],
|
|
21451
|
+
multiline: isMultiLineString(token),
|
|
21452
|
+
parent: valueContainer.parent,
|
|
21453
|
+
range: cloneRange(token.range),
|
|
21454
|
+
loc: cloneLoc(token.loc)
|
|
21455
|
+
};
|
|
21456
|
+
return valueContainer.set(node);
|
|
21457
|
+
}
|
|
21458
|
+
processNumberValue(token, ctx) {
|
|
21459
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21460
|
+
const text = this.text;
|
|
21461
|
+
const [startRange, endRange] = token.range;
|
|
21462
|
+
let numberString = null;
|
|
21463
|
+
const getNumberText = () => {
|
|
21464
|
+
return numberString ?? (numberString = text.slice(startRange, endRange).replace(/_/g, ""));
|
|
21465
|
+
};
|
|
21466
|
+
let node;
|
|
21467
|
+
if (token.type === "Integer") node = {
|
|
21468
|
+
type: "TOMLValue",
|
|
21469
|
+
kind: "integer",
|
|
21470
|
+
value: token.number,
|
|
21471
|
+
bigint: token.bigint,
|
|
21472
|
+
get number() {
|
|
21473
|
+
return getNumberText();
|
|
21474
|
+
},
|
|
21475
|
+
parent: valueContainer.parent,
|
|
21476
|
+
range: cloneRange(token.range),
|
|
21477
|
+
loc: cloneLoc(token.loc)
|
|
21478
|
+
};
|
|
21479
|
+
else node = {
|
|
21480
|
+
type: "TOMLValue",
|
|
21481
|
+
kind: "float",
|
|
21482
|
+
value: token.number,
|
|
21483
|
+
get number() {
|
|
21484
|
+
return getNumberText();
|
|
21485
|
+
},
|
|
21486
|
+
parent: valueContainer.parent,
|
|
21487
|
+
range: cloneRange(token.range),
|
|
21488
|
+
loc: cloneLoc(token.loc)
|
|
21489
|
+
};
|
|
21490
|
+
return valueContainer.set(node);
|
|
21491
|
+
}
|
|
21492
|
+
processBooleanValue(token, ctx) {
|
|
21493
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21494
|
+
const node = {
|
|
21495
|
+
type: "TOMLValue",
|
|
21496
|
+
kind: "boolean",
|
|
21497
|
+
value: token.boolean,
|
|
21498
|
+
parent: valueContainer.parent,
|
|
21499
|
+
range: cloneRange(token.range),
|
|
21500
|
+
loc: cloneLoc(token.loc)
|
|
21501
|
+
};
|
|
21502
|
+
return valueContainer.set(node);
|
|
21503
|
+
}
|
|
21504
|
+
processDateTimeValue(token, ctx) {
|
|
21505
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21506
|
+
const node = {
|
|
21507
|
+
type: "TOMLValue",
|
|
21508
|
+
kind: DATETIME_VALUE_KIND_MAP[token.type],
|
|
21509
|
+
value: token.date,
|
|
21510
|
+
datetime: token.value,
|
|
21511
|
+
parent: valueContainer.parent,
|
|
21512
|
+
range: cloneRange(token.range),
|
|
21513
|
+
loc: cloneLoc(token.loc)
|
|
21514
|
+
};
|
|
21515
|
+
return valueContainer.set(node);
|
|
21516
|
+
}
|
|
21517
|
+
processArray(token, ctx) {
|
|
21518
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21519
|
+
const node = {
|
|
21520
|
+
type: "TOMLArray",
|
|
21521
|
+
elements: [],
|
|
21522
|
+
parent: valueContainer.parent,
|
|
21523
|
+
range: cloneRange(token.range),
|
|
21524
|
+
loc: cloneLoc(token.loc)
|
|
21525
|
+
};
|
|
21526
|
+
const nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
21527
|
+
if (isRightBracket(nextToken)) {
|
|
21528
|
+
applyEndLoc(node, nextToken);
|
|
21529
|
+
return valueContainer.set(node);
|
|
21530
|
+
}
|
|
21531
|
+
ctx.backToken();
|
|
21532
|
+
return this.processArrayValue(node, valueContainer, ctx);
|
|
21533
|
+
}
|
|
21534
|
+
processArrayValue(node, valueContainer, ctx) {
|
|
21535
|
+
ctx.addValueContainer({
|
|
21536
|
+
parent: node,
|
|
21537
|
+
set: (valNode) => {
|
|
21538
|
+
node.elements.push(valNode);
|
|
21539
|
+
let nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
21540
|
+
const hasComma = isComma(nextToken);
|
|
21541
|
+
if (hasComma) nextToken = ctx.nextToken({ valuesEnabled: true });
|
|
21542
|
+
if (isRightBracket(nextToken)) {
|
|
21543
|
+
applyEndLoc(node, nextToken);
|
|
21544
|
+
return valueContainer.set(node);
|
|
21545
|
+
}
|
|
21546
|
+
if (hasComma) {
|
|
21547
|
+
ctx.backToken();
|
|
21548
|
+
return this.processArrayValue(node, valueContainer, ctx);
|
|
21549
|
+
}
|
|
21550
|
+
return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-array", nextToken);
|
|
21551
|
+
}
|
|
21552
|
+
});
|
|
21553
|
+
return ["VALUE"];
|
|
21554
|
+
}
|
|
21555
|
+
processInlineTable(token, ctx) {
|
|
21556
|
+
const valueContainer = ctx.consumeValueContainer();
|
|
21557
|
+
const node = {
|
|
21558
|
+
type: "TOMLInlineTable",
|
|
21559
|
+
body: [],
|
|
21560
|
+
parent: valueContainer.parent,
|
|
21561
|
+
range: cloneRange(token.range),
|
|
21562
|
+
loc: cloneLoc(token.loc)
|
|
21563
|
+
};
|
|
21564
|
+
const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
|
|
21565
|
+
const nextToken = ctx.nextToken({ needSameLine });
|
|
21566
|
+
if (nextToken) {
|
|
21567
|
+
if (isBare(nextToken) || isString(nextToken)) return this.processInlineTableKeyValue(nextToken, node, valueContainer, ctx);
|
|
21568
|
+
if (isRightBrace(nextToken)) {
|
|
21569
|
+
applyEndLoc(node, nextToken);
|
|
21570
|
+
return valueContainer.set(node);
|
|
21571
|
+
}
|
|
21572
|
+
}
|
|
21573
|
+
return ctx.reportParseError("unexpected-token", nextToken);
|
|
21574
|
+
}
|
|
21575
|
+
processInlineTableKeyValue(token, inlineTableNode, valueContainer, ctx) {
|
|
21576
|
+
const keyValueNode = {
|
|
21577
|
+
type: "TOMLKeyValue",
|
|
21578
|
+
key: null,
|
|
21579
|
+
value: null,
|
|
21580
|
+
parent: inlineTableNode,
|
|
21581
|
+
range: cloneRange(token.range),
|
|
21582
|
+
loc: cloneLoc(token.loc)
|
|
21583
|
+
};
|
|
21584
|
+
inlineTableNode.body.push(keyValueNode);
|
|
21585
|
+
const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
|
|
21586
|
+
if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
|
|
21587
|
+
const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
|
|
21588
|
+
ctx.addValueContainer({
|
|
21589
|
+
parent: keyValueNode,
|
|
21590
|
+
set: (valNode) => {
|
|
21591
|
+
keyValueNode.value = valNode;
|
|
21592
|
+
applyEndLoc(keyValueNode, valNode);
|
|
21593
|
+
let nextToken = ctx.nextToken({ needSameLine });
|
|
21594
|
+
if (isComma(nextToken)) {
|
|
21595
|
+
nextToken = ctx.nextToken({ needSameLine });
|
|
21596
|
+
if (nextToken && (isBare(nextToken) || isString(nextToken))) return this.processInlineTableKeyValue(nextToken, inlineTableNode, valueContainer, ctx);
|
|
21597
|
+
if (isRightBrace(nextToken)) {
|
|
21598
|
+
if (this.tomlVersion.lt(1, 1)) return ctx.reportParseError("invalid-trailing-comma-in-inline-table", nextToken);
|
|
21599
|
+
} else return ctx.reportParseError(nextToken ? "unexpected-token" : "unterminated-inline-table", nextToken);
|
|
21600
|
+
}
|
|
21601
|
+
if (isRightBrace(nextToken)) {
|
|
21602
|
+
applyEndLoc(inlineTableNode, nextToken);
|
|
21603
|
+
return valueContainer.set(inlineTableNode);
|
|
21604
|
+
}
|
|
21605
|
+
return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-inline-table", nextToken);
|
|
21606
|
+
}
|
|
21607
|
+
});
|
|
21608
|
+
ctx.needSameLine = "invalid-key-value-newline";
|
|
21609
|
+
return ["VALUE"];
|
|
21610
|
+
}
|
|
21611
|
+
};
|
|
21612
|
+
function isDot(token) {
|
|
21613
|
+
return isPunctuator(token) && token.value === ".";
|
|
21614
|
+
}
|
|
21615
|
+
function isEq(token) {
|
|
21616
|
+
return isPunctuator(token) && token.value === "=";
|
|
21617
|
+
}
|
|
21618
|
+
function isLeftBracket(token) {
|
|
21619
|
+
return isPunctuator(token) && token.value === "[";
|
|
21620
|
+
}
|
|
21621
|
+
function isRightBracket(token) {
|
|
21622
|
+
return isPunctuator(token) && token.value === "]";
|
|
21623
|
+
}
|
|
21624
|
+
function isLeftBrace(token) {
|
|
21625
|
+
return isPunctuator(token) && token.value === "{";
|
|
21626
|
+
}
|
|
21627
|
+
function isRightBrace(token) {
|
|
21628
|
+
return isPunctuator(token) && token.value === "}";
|
|
21629
|
+
}
|
|
21630
|
+
function isComma(token) {
|
|
21631
|
+
return isPunctuator(token) && token.value === ",";
|
|
21632
|
+
}
|
|
21633
|
+
function isPunctuator(token) {
|
|
21634
|
+
return Boolean(token && token.type === "Punctuator");
|
|
21635
|
+
}
|
|
21636
|
+
function isBare(token) {
|
|
21637
|
+
return token.type === "Bare";
|
|
21638
|
+
}
|
|
21639
|
+
function isString(token) {
|
|
21640
|
+
return token.type === "BasicString" || token.type === "LiteralString";
|
|
21641
|
+
}
|
|
21642
|
+
function isMultiLineString(token) {
|
|
21643
|
+
return token.type === "MultiLineBasicString" || token.type === "MultiLineLiteralString";
|
|
21644
|
+
}
|
|
21645
|
+
function isNumber(token) {
|
|
21646
|
+
return token.type === "Integer" || token.type === "Float";
|
|
21647
|
+
}
|
|
21648
|
+
function isBoolean(token) {
|
|
21649
|
+
return token.type === "Boolean";
|
|
21650
|
+
}
|
|
21651
|
+
function isDateTime(token) {
|
|
21652
|
+
return token.type === "OffsetDateTime" || token.type === "LocalDateTime" || token.type === "LocalDate" || token.type === "LocalTime";
|
|
21653
|
+
}
|
|
21654
|
+
function applyEndLoc(node, child) {
|
|
21655
|
+
if (child) {
|
|
21656
|
+
node.range[1] = child.range[1];
|
|
21657
|
+
node.loc.end = clonePos(child.loc.end);
|
|
21658
|
+
}
|
|
21659
|
+
}
|
|
21660
|
+
function cloneRange(range) {
|
|
21661
|
+
return [range[0], range[1]];
|
|
21662
|
+
}
|
|
21663
|
+
function cloneLoc(loc) {
|
|
21664
|
+
return {
|
|
21665
|
+
start: clonePos(loc.start),
|
|
21666
|
+
end: clonePos(loc.end)
|
|
21667
|
+
};
|
|
21668
|
+
}
|
|
21669
|
+
function clonePos(pos) {
|
|
21670
|
+
return {
|
|
21671
|
+
line: pos.line,
|
|
21672
|
+
column: pos.column
|
|
21673
|
+
};
|
|
21674
|
+
}
|
|
21675
|
+
var tomlKeys = {
|
|
21676
|
+
Program: ["body"],
|
|
21677
|
+
TOMLTopLevelTable: ["body"],
|
|
21678
|
+
TOMLTable: ["key", "body"],
|
|
21679
|
+
TOMLKeyValue: ["key", "value"],
|
|
21680
|
+
TOMLKey: ["keys"],
|
|
21681
|
+
TOMLArray: ["elements"],
|
|
21682
|
+
TOMLInlineTable: ["body"],
|
|
21683
|
+
TOMLBare: [],
|
|
21684
|
+
TOMLQuoted: [],
|
|
21685
|
+
TOMLValue: []
|
|
21686
|
+
};
|
|
21687
|
+
var KEYS3 = unionWith(tomlKeys);
|
|
21688
|
+
function parseForESLint(code, options) {
|
|
21689
|
+
return {
|
|
21690
|
+
ast: new TOMLParser(code, options).parse(),
|
|
21691
|
+
visitorKeys: KEYS3,
|
|
21692
|
+
services: { isTOML: true }
|
|
21693
|
+
};
|
|
21694
|
+
}
|
|
21695
|
+
var getStaticTOMLValue = generateConvertTOMLValue((node) => node.value);
|
|
21696
|
+
function generateConvertTOMLValue(convertValue) {
|
|
21697
|
+
function resolveValue(node, baseTable) {
|
|
21698
|
+
return resolver[node.type](node, baseTable);
|
|
21699
|
+
}
|
|
21700
|
+
const resolver = {
|
|
21701
|
+
Program(node, baseTable = {}) {
|
|
21702
|
+
return resolveValue(node.body[0], baseTable);
|
|
21703
|
+
},
|
|
21704
|
+
TOMLTopLevelTable(node, baseTable = {}) {
|
|
21705
|
+
for (const body of node.body) resolveValue(body, baseTable);
|
|
21706
|
+
return baseTable;
|
|
21707
|
+
},
|
|
21708
|
+
TOMLKeyValue(node, baseTable = {}) {
|
|
21709
|
+
const value = resolveValue(node.value);
|
|
21710
|
+
set2(baseTable, resolveValue(node.key), value);
|
|
21711
|
+
return baseTable;
|
|
21712
|
+
},
|
|
21713
|
+
TOMLTable(node, baseTable = {}) {
|
|
21714
|
+
const table = getTable(baseTable, resolveValue(node.key), node.kind === "array");
|
|
21715
|
+
for (const body of node.body) resolveValue(body, table);
|
|
21716
|
+
return baseTable;
|
|
21717
|
+
},
|
|
21718
|
+
TOMLArray(node) {
|
|
21719
|
+
return node.elements.map((e) => resolveValue(e));
|
|
21720
|
+
},
|
|
21721
|
+
TOMLInlineTable(node) {
|
|
21722
|
+
const table = {};
|
|
21723
|
+
for (const body of node.body) resolveValue(body, table);
|
|
21724
|
+
return table;
|
|
21725
|
+
},
|
|
21726
|
+
TOMLKey(node) {
|
|
21727
|
+
return node.keys.map((key) => resolveValue(key));
|
|
21728
|
+
},
|
|
21729
|
+
TOMLBare(node) {
|
|
21730
|
+
return node.name;
|
|
21731
|
+
},
|
|
21732
|
+
TOMLQuoted(node) {
|
|
21733
|
+
return node.value;
|
|
21734
|
+
},
|
|
21735
|
+
TOMLValue(node) {
|
|
21736
|
+
return convertValue(node);
|
|
21737
|
+
}
|
|
21738
|
+
};
|
|
21739
|
+
return (node) => resolveValue(node);
|
|
21740
|
+
}
|
|
21741
|
+
function getTable(baseTable, keys, array2) {
|
|
21742
|
+
let target = baseTable;
|
|
21743
|
+
for (let index = 0; index < keys.length - 1; index++) {
|
|
21744
|
+
const key = keys[index];
|
|
21745
|
+
target = getNextTargetFromKey(target, key);
|
|
21746
|
+
}
|
|
21747
|
+
const lastKey = last(keys);
|
|
21748
|
+
const lastTarget = target[lastKey];
|
|
21749
|
+
if (lastTarget == null) {
|
|
21750
|
+
const tableValue$1 = {};
|
|
21751
|
+
target[lastKey] = array2 ? [tableValue$1] : tableValue$1;
|
|
21752
|
+
return tableValue$1;
|
|
21753
|
+
}
|
|
21754
|
+
if (isValue(lastTarget)) {
|
|
21755
|
+
const tableValue$1 = {};
|
|
21756
|
+
target[lastKey] = array2 ? [tableValue$1] : tableValue$1;
|
|
21757
|
+
return tableValue$1;
|
|
21758
|
+
}
|
|
21759
|
+
if (!array2) {
|
|
21760
|
+
if (Array.isArray(lastTarget)) {
|
|
21761
|
+
const tableValue$1 = {};
|
|
21762
|
+
target[lastKey] = tableValue$1;
|
|
21763
|
+
return tableValue$1;
|
|
21764
|
+
}
|
|
21765
|
+
return lastTarget;
|
|
21766
|
+
}
|
|
21767
|
+
if (Array.isArray(lastTarget)) {
|
|
21768
|
+
const tableValue$1 = {};
|
|
21769
|
+
lastTarget.push(tableValue$1);
|
|
21770
|
+
return tableValue$1;
|
|
21771
|
+
}
|
|
21772
|
+
const tableValue = {};
|
|
21773
|
+
target[lastKey] = [tableValue];
|
|
21774
|
+
return tableValue;
|
|
21775
|
+
function getNextTargetFromKey(currTarget, key) {
|
|
21776
|
+
const nextTarget = currTarget[key];
|
|
21777
|
+
if (nextTarget == null) {
|
|
21778
|
+
const val = {};
|
|
21779
|
+
currTarget[key] = val;
|
|
21780
|
+
return val;
|
|
21781
|
+
}
|
|
21782
|
+
if (isValue(nextTarget)) {
|
|
21783
|
+
const val = {};
|
|
21784
|
+
currTarget[key] = val;
|
|
21785
|
+
return val;
|
|
21786
|
+
}
|
|
21787
|
+
let resultTarget = nextTarget;
|
|
21788
|
+
while (Array.isArray(resultTarget)) {
|
|
21789
|
+
const lastIndex = resultTarget.length - 1;
|
|
21790
|
+
const nextElement = resultTarget[lastIndex];
|
|
21791
|
+
if (isValue(nextElement)) {
|
|
21792
|
+
const val = {};
|
|
21793
|
+
resultTarget[lastIndex] = val;
|
|
21794
|
+
return val;
|
|
21795
|
+
}
|
|
21796
|
+
resultTarget = nextElement;
|
|
21797
|
+
}
|
|
21798
|
+
return resultTarget;
|
|
21799
|
+
}
|
|
21800
|
+
}
|
|
21801
|
+
function set2(baseTable, keys, value) {
|
|
21802
|
+
let target = baseTable;
|
|
21803
|
+
for (let index = 0; index < keys.length - 1; index++) {
|
|
21804
|
+
const key = keys[index];
|
|
21805
|
+
const nextTarget = target[key];
|
|
21806
|
+
if (nextTarget == null) {
|
|
21807
|
+
const val = {};
|
|
21808
|
+
target[key] = val;
|
|
21809
|
+
target = val;
|
|
21810
|
+
} else if (isValue(nextTarget) || Array.isArray(nextTarget)) {
|
|
21811
|
+
const val = {};
|
|
21812
|
+
target[key] = val;
|
|
21813
|
+
target = val;
|
|
21814
|
+
} else target = nextTarget;
|
|
21815
|
+
}
|
|
21816
|
+
target[last(keys)] = value;
|
|
21817
|
+
}
|
|
21818
|
+
function isValue(value) {
|
|
21819
|
+
return typeof value !== "object" || value instanceof Date;
|
|
21820
|
+
}
|
|
21821
|
+
function parseTOML(code, options) {
|
|
21822
|
+
return parseForESLint(code, options).ast;
|
|
21823
|
+
}
|
|
21824
|
+
|
|
21825
|
+
// src/core/ops/atomic-file.ts
|
|
21826
|
+
import { mkdirSync as mkdirSync3, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
21827
|
+
import path3 from "node:path";
|
|
21828
|
+
function sleepSync(ms) {
|
|
21829
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
21830
|
+
}
|
|
21831
|
+
function errCode(e) {
|
|
21832
|
+
return e.code;
|
|
21833
|
+
}
|
|
21834
|
+
function renameWithRetry(from, to, opts = {}) {
|
|
21835
|
+
const rename = opts.rename ?? renameSync;
|
|
21836
|
+
const sleep = opts.sleep ?? sleepSync;
|
|
21837
|
+
const win = (opts.platform ?? process.platform) === "win32";
|
|
21838
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
21839
|
+
try {
|
|
21840
|
+
rename(from, to);
|
|
21841
|
+
return;
|
|
21842
|
+
} catch (e) {
|
|
21843
|
+
const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
21844
|
+
if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw e;
|
|
21845
|
+
sleep(ATOMIC_RENAME_DELAY_MS);
|
|
21846
|
+
}
|
|
21847
|
+
}
|
|
21848
|
+
}
|
|
21849
|
+
function unlinkWithRetry(file2, opts = {}) {
|
|
21850
|
+
const unlink = opts.unlink ?? unlinkSync;
|
|
21851
|
+
const sleep = opts.sleep ?? sleepSync;
|
|
21852
|
+
const win = (opts.platform ?? process.platform) === "win32";
|
|
21853
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
21854
|
+
try {
|
|
21855
|
+
unlink(file2);
|
|
21856
|
+
return;
|
|
21857
|
+
} catch (e) {
|
|
21858
|
+
if (errCode(e) === "ENOENT") return;
|
|
21859
|
+
const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
21860
|
+
if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw replaceFailure(file2, e);
|
|
21861
|
+
sleep(ATOMIC_RENAME_DELAY_MS);
|
|
21862
|
+
}
|
|
21863
|
+
}
|
|
21864
|
+
}
|
|
21865
|
+
function replaceFailure(file2, e) {
|
|
21866
|
+
const busy = ATOMIC_RENAME_BUSY_CODES.includes(errCode(e) ?? "");
|
|
21867
|
+
const cause = e.message;
|
|
21868
|
+
return new Error(busy ? `Could not replace ${file2}: ${cause}. Fix: close the program using ${file2}, then re-run` : `Could not write ${file2}: ${cause}. Fix: check the path and its permissions, then re-run`, { cause: e });
|
|
21869
|
+
}
|
|
21870
|
+
function removeTmpFile(tmp, opts = {}) {
|
|
21871
|
+
try {
|
|
21872
|
+
unlinkWithRetry(tmp, opts);
|
|
21873
|
+
} catch {
|
|
21874
|
+
}
|
|
21875
|
+
}
|
|
21876
|
+
function atomicWriteFile(file2, text, opts = {}) {
|
|
21877
|
+
mkdirSync3(path3.dirname(file2), { recursive: true });
|
|
21878
|
+
const tmp = path3.join(path3.dirname(file2), `${ATOMIC_TMP_PREFIX}${path3.basename(file2)}${ATOMIC_TMP_MARK}${process.pid}`);
|
|
21879
|
+
try {
|
|
21880
|
+
writeFileSync(tmp, text);
|
|
21881
|
+
renameWithRetry(tmp, file2, opts);
|
|
21882
|
+
} catch (e) {
|
|
21883
|
+
removeTmpFile(tmp, opts);
|
|
21884
|
+
throw replaceFailure(file2, e);
|
|
19908
21885
|
}
|
|
19909
|
-
scanAll(home, scope.tmp ?? tmpdir(), out);
|
|
19910
|
-
return out;
|
|
19911
21886
|
}
|
|
19912
21887
|
|
|
19913
21888
|
// src/core/ops/host-config.ts
|
|
19914
|
-
|
|
19915
|
-
|
|
19916
|
-
|
|
19917
|
-
if (path4.endsWith(JSONC_EXT)) return "jsonc";
|
|
19918
|
-
if (path4.endsWith(TOML_EXT)) return "toml";
|
|
21889
|
+
function formatOf(path5) {
|
|
21890
|
+
if (path5.endsWith(JSONC_EXT)) return "jsonc";
|
|
21891
|
+
if (path5.endsWith(TOML_EXT)) return "toml";
|
|
19919
21892
|
return "json";
|
|
19920
21893
|
}
|
|
19921
|
-
function readHostConfig(agent,
|
|
19922
|
-
let file2 =
|
|
21894
|
+
function readHostConfig(agent, path5) {
|
|
21895
|
+
let file2 = path5;
|
|
19923
21896
|
if (agent === "opencode") {
|
|
19924
|
-
const jsonc =
|
|
19925
|
-
if (
|
|
21897
|
+
const jsonc = join7(dirname4(path5), OPENCODE_CONFIG_FILES[0]);
|
|
21898
|
+
if (existsSync3(jsonc)) file2 = jsonc;
|
|
19926
21899
|
}
|
|
19927
|
-
const
|
|
19928
|
-
return { agent, text, format: formatOf(file2), path: file2 };
|
|
21900
|
+
const raw = existsSync3(file2) ? readFileSync6(file2, "utf8") : "";
|
|
21901
|
+
return { agent, text: hostText(raw), format: agent === "opencode" && !file2.endsWith(TOML_EXT) ? "jsonc" : formatOf(file2), path: file2, layout: hostLayout(raw) };
|
|
19929
21902
|
}
|
|
19930
21903
|
function stripJsonComments(text) {
|
|
19931
21904
|
let out = "";
|
|
@@ -20059,354 +22032,567 @@ function scanJson(text, format) {
|
|
|
20059
22032
|
if (sc.i !== clean.length) sc.fail();
|
|
20060
22033
|
return { clean, root, value };
|
|
20061
22034
|
}
|
|
20062
|
-
function
|
|
20063
|
-
|
|
20064
|
-
|
|
20065
|
-
|
|
20066
|
-
|
|
20067
|
-
|
|
20068
|
-
|
|
20069
|
-
|
|
20070
|
-
|
|
20071
|
-
|
|
20072
|
-
|
|
20073
|
-
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
|
|
20077
|
-
|
|
20078
|
-
|
|
20079
|
-
|
|
20080
|
-
|
|
22035
|
+
function keyNames(key) {
|
|
22036
|
+
return key.keys.map((k) => k.type === "TOMLBare" ? k.name : k.value);
|
|
22037
|
+
}
|
|
22038
|
+
function lineStartOf(text, at2) {
|
|
22039
|
+
return at2 === 0 ? 0 : text.lastIndexOf("\n", at2 - 1) + 1;
|
|
22040
|
+
}
|
|
22041
|
+
function lineEndOf(text, at2) {
|
|
22042
|
+
const nl = text.indexOf("\n", at2);
|
|
22043
|
+
return nl < 0 ? text.length : nl + 1;
|
|
22044
|
+
}
|
|
22045
|
+
function tomlValue(text) {
|
|
22046
|
+
return getStaticTOMLValue(parseTOML(text));
|
|
22047
|
+
}
|
|
22048
|
+
function scanToml(text) {
|
|
22049
|
+
const program = parseTOML(text);
|
|
22050
|
+
const tables = [];
|
|
22051
|
+
const keys = [];
|
|
22052
|
+
const addKey = (base, kv) => {
|
|
22053
|
+
keys.push({ base, full: [...base, ...keyNames(kv.key)], start: kv.range[0], end: kv.range[1], inline: kv.value.type === "TOMLInlineTable" });
|
|
22054
|
+
};
|
|
22055
|
+
for (const node of program.body[0].body) {
|
|
22056
|
+
if (node.type === "TOMLKeyValue") {
|
|
22057
|
+
addKey([], node);
|
|
22058
|
+
continue;
|
|
20081
22059
|
}
|
|
20082
|
-
|
|
20083
|
-
|
|
20084
|
-
|
|
20085
|
-
if (
|
|
20086
|
-
|
|
22060
|
+
if (!node.resolvedKey.every((seg) => typeof seg === "string")) continue;
|
|
22061
|
+
const path5 = node.resolvedKey;
|
|
22062
|
+
for (const kv of node.body) addKey(path5, kv);
|
|
22063
|
+
if (node.kind !== "standard") continue;
|
|
22064
|
+
const start = lineStartOf(text, node.range[0]);
|
|
22065
|
+
const headEnd = lineEndOf(text, node.key.range[1]);
|
|
22066
|
+
const last2 = node.body[node.body.length - 1];
|
|
22067
|
+
tables.push({
|
|
22068
|
+
path: path5,
|
|
22069
|
+
header: text.slice(start, text[headEnd - 1] === "\n" ? headEnd - 1 : headEnd),
|
|
22070
|
+
start,
|
|
22071
|
+
end: last2 === void 0 ? headEnd : lineEndOf(text, last2.range[1])
|
|
22072
|
+
});
|
|
20087
22073
|
}
|
|
22074
|
+
return { value: getStaticTOMLValue(program), tables, keys };
|
|
20088
22075
|
}
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
20093
|
-
|
|
22076
|
+
function tomlTableSpans(text) {
|
|
22077
|
+
return scanToml(text).tables;
|
|
22078
|
+
}
|
|
22079
|
+
function tomlHeaderText(path5) {
|
|
22080
|
+
return "[" + path5.map(tomlHeaderKey).join(".") + "]";
|
|
22081
|
+
}
|
|
22082
|
+
function parseHostConfig(agent, path5, text, format) {
|
|
22083
|
+
try {
|
|
22084
|
+
return format === "toml" ? scanToml(text).value : scanJson(text, format).value;
|
|
22085
|
+
} catch {
|
|
22086
|
+
throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
|
|
20094
22087
|
}
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
22088
|
+
}
|
|
22089
|
+
function hostConfigValueAt(value, path5) {
|
|
22090
|
+
let cur = value;
|
|
22091
|
+
for (const seg of path5) {
|
|
22092
|
+
if (!isPlainObject3(cur)) return void 0;
|
|
22093
|
+
cur = cur[seg];
|
|
20101
22094
|
}
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
|
|
20105
|
-
|
|
20106
|
-
|
|
20107
|
-
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
22095
|
+
return cur;
|
|
22096
|
+
}
|
|
22097
|
+
function isPlainObject3(v) {
|
|
22098
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22099
|
+
}
|
|
22100
|
+
function sameValue(a, b) {
|
|
22101
|
+
if (a === b) return true;
|
|
22102
|
+
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((x, k) => sameValue(x, b[k]));
|
|
22103
|
+
if (isPlainObject3(a) && isPlainObject3(b)) {
|
|
22104
|
+
const ka = Object.keys(a);
|
|
22105
|
+
return ka.length === Object.keys(b).length && ka.every((k) => sameValue(a[k], b[k]));
|
|
22106
|
+
}
|
|
22107
|
+
return false;
|
|
22108
|
+
}
|
|
22109
|
+
function lineIndent(text, at2) {
|
|
22110
|
+
let s = at2;
|
|
22111
|
+
while (s > 0 && text[s - 1] !== "\n") s -= 1;
|
|
22112
|
+
let e = s;
|
|
22113
|
+
while (text[e] === " " || text[e] === " ") e += 1;
|
|
22114
|
+
return text.slice(s, e);
|
|
22115
|
+
}
|
|
22116
|
+
function indentUnit(root, clean) {
|
|
22117
|
+
if (root === null || root.kind !== "object" || root.members.length === 0) return JSON_INDENT_UNIT;
|
|
22118
|
+
const own2 = lineIndent(clean, root.members[0].keyStart);
|
|
22119
|
+
return own2 === "" ? JSON_INDENT_UNIT : own2;
|
|
22120
|
+
}
|
|
22121
|
+
function render(value, unit, base) {
|
|
22122
|
+
return JSON.stringify(value, null, unit).split("\n").join("\n" + base);
|
|
22123
|
+
}
|
|
22124
|
+
function nest(path5, value) {
|
|
22125
|
+
let out = value;
|
|
22126
|
+
for (let k = path5.length - 1; k >= 0; k -= 1) out = { [path5[k]]: out };
|
|
22127
|
+
return out;
|
|
22128
|
+
}
|
|
22129
|
+
function setJsonText(text, format, path5, value) {
|
|
22130
|
+
const doc = scanJson(text, format);
|
|
22131
|
+
const unit = indentUnit(doc.root, doc.clean);
|
|
22132
|
+
if (doc.root === null) return render(nest(path5, value), unit, "") + "\n";
|
|
22133
|
+
let node = doc.root;
|
|
22134
|
+
let depth = 0;
|
|
22135
|
+
while (depth < path5.length && node.kind === "object") {
|
|
22136
|
+
const hit = node.members.find((m) => m.key === path5[depth]);
|
|
22137
|
+
if (hit === void 0) break;
|
|
22138
|
+
node = hit.node;
|
|
22139
|
+
depth += 1;
|
|
22140
|
+
}
|
|
22141
|
+
if (depth === path5.length) {
|
|
22142
|
+
return text.slice(0, node.start) + render(value, unit, lineIndent(doc.clean, node.start)) + text.slice(node.end);
|
|
22143
|
+
}
|
|
22144
|
+
if (node.kind !== "object") throw new SyntaxError("not an object at " + path5.slice(0, depth).join("."));
|
|
22145
|
+
const rest = nest(path5.slice(depth + 1), value);
|
|
22146
|
+
const last2 = node.members[node.members.length - 1];
|
|
22147
|
+
if (last2 === void 0) {
|
|
22148
|
+
const base2 = lineIndent(doc.clean, node.start);
|
|
22149
|
+
const member2 = "\n" + base2 + unit + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
|
|
22150
|
+
return text.slice(0, node.start + 1) + member2 + text.slice(node.end - 1);
|
|
22151
|
+
}
|
|
22152
|
+
const base = lineIndent(doc.clean, last2.keyStart);
|
|
22153
|
+
let at2 = last2.node.end;
|
|
22154
|
+
while (" \r\n".includes(doc.clean[at2])) at2 += 1;
|
|
22155
|
+
const trailing = doc.clean[at2] === ",";
|
|
22156
|
+
const insertAt = trailing ? at2 + 1 : last2.node.end;
|
|
22157
|
+
const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base);
|
|
22158
|
+
return text.slice(0, insertAt) + member + text.slice(insertAt);
|
|
22159
|
+
}
|
|
22160
|
+
function tomlScalar(v) {
|
|
22161
|
+
if (Array.isArray(v)) return "[" + v.map(tomlScalar).join(", ") + "]";
|
|
22162
|
+
if (isPlainObject3(v)) return "{ " + Object.entries(v).map(([k, x]) => tomlHeaderKey(k) + " = " + tomlScalar(x)).join(", ") + " }";
|
|
22163
|
+
if (typeof v === "string") return JSON.stringify(v);
|
|
22164
|
+
if (typeof v === "number" || typeof v === "boolean") return String(v);
|
|
22165
|
+
throw new SyntaxError("unsupported TOML value");
|
|
22166
|
+
}
|
|
22167
|
+
function tomlHeaderKey(seg) {
|
|
22168
|
+
if (seg === "") return '""';
|
|
22169
|
+
for (const ch of seg) {
|
|
22170
|
+
const bare2 = ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-";
|
|
22171
|
+
if (!bare2) return JSON.stringify(seg);
|
|
22172
|
+
}
|
|
22173
|
+
return seg;
|
|
22174
|
+
}
|
|
22175
|
+
function tomlBlock(path5, value) {
|
|
22176
|
+
let out = "[" + path5.map(tomlHeaderKey).join(".") + "]\n";
|
|
22177
|
+
const subs = [];
|
|
22178
|
+
for (const [k, v] of Object.entries(value)) {
|
|
22179
|
+
if (isPlainObject3(v)) subs.push(tomlBlock([...path5, k], v));
|
|
22180
|
+
else out += tomlHeaderKey(k) + " = " + tomlScalar(v) + "\n";
|
|
22181
|
+
}
|
|
22182
|
+
return [out, ...subs].join("\n");
|
|
22183
|
+
}
|
|
22184
|
+
function under(path5, prefix) {
|
|
22185
|
+
return path5.length >= prefix.length && prefix.every((seg, k) => path5[k] === seg);
|
|
22186
|
+
}
|
|
22187
|
+
function keyLineRange(text, k) {
|
|
22188
|
+
const ls = lineStartOf(text, k.start);
|
|
22189
|
+
const le = lineEndOf(text, k.end);
|
|
22190
|
+
const rest = text.slice(k.end, le).trim();
|
|
22191
|
+
const alone = text.slice(ls, k.start).trim() === "" && (rest === "" || rest.startsWith("#"));
|
|
22192
|
+
return alone ? [ls, le] : [k.start, k.end];
|
|
22193
|
+
}
|
|
22194
|
+
function withValueAt(root, rel, value) {
|
|
22195
|
+
if (rel.length === 0) return value;
|
|
22196
|
+
const base = isPlainObject3(root) ? { ...root } : {};
|
|
22197
|
+
const next = withValueAt(base[rel[0]], rel.slice(1), value);
|
|
22198
|
+
if (next === void 0) delete base[rel[0]];
|
|
22199
|
+
else base[rel[0]] = next;
|
|
22200
|
+
return base;
|
|
22201
|
+
}
|
|
22202
|
+
function replaceToml(text, doc, path5, value) {
|
|
22203
|
+
const block = value === void 0 ? "" : tomlBlock(path5, value);
|
|
22204
|
+
const owned = doc.tables.filter((t) => under(t.path, path5));
|
|
22205
|
+
const cuts = doc.keys.filter((k) => under(k.full, path5) && !under(k.base, path5)).map((k) => [...keyLineRange(text, k), ""]);
|
|
22206
|
+
owned.forEach((t, n) => cuts.push([t.start, t.end, n === 0 ? block : ""]));
|
|
22207
|
+
cuts.sort((a, b) => b[0] - a[0]);
|
|
22208
|
+
let out = text;
|
|
22209
|
+
for (const [s, e, put] of cuts) out = out.slice(0, s) + put + out.slice(e);
|
|
22210
|
+
if (owned.length > 0 || block === "") return out;
|
|
22211
|
+
const sep3 = out === "" ? "" : out.endsWith("\n\n") ? "" : out.endsWith("\n") ? "\n" : "\n\n";
|
|
22212
|
+
return out + sep3 + block;
|
|
22213
|
+
}
|
|
22214
|
+
var tableLike = (v) => v === void 0 || isPlainObject3(v);
|
|
22215
|
+
function setTomlText(text, path5, value) {
|
|
22216
|
+
if (value !== void 0 && !isPlainObject3(value)) throw new SyntaxError("TOML edits replace a whole table");
|
|
22217
|
+
const doc = scanToml(text);
|
|
22218
|
+
const cur = hostConfigValueAt(doc.value, path5);
|
|
22219
|
+
if (sameValue(cur, value)) return text;
|
|
22220
|
+
const inline = doc.keys.find((k) => k.inline && k.full.length < path5.length && under(path5, k.full));
|
|
22221
|
+
if (inline !== void 0) {
|
|
22222
|
+
const whole = withValueAt(hostConfigValueAt(doc.value, inline.full), path5.slice(inline.full.length), value);
|
|
22223
|
+
return replaceToml(text, doc, inline.full, whole);
|
|
22224
|
+
}
|
|
22225
|
+
if (isPlainObject3(cur) && isPlainObject3(value)) {
|
|
22226
|
+
const names = [.../* @__PURE__ */ new Set([...Object.keys(cur), ...Object.keys(value)])].filter((k) => !sameValue(cur[k], value[k]));
|
|
22227
|
+
if (names.every((k) => tableLike(cur[k]) && tableLike(value[k]))) {
|
|
22228
|
+
let out = text;
|
|
22229
|
+
for (const k of names) out = setTomlText(out, [...path5, k], value[k]);
|
|
22230
|
+
return out;
|
|
20112
22231
|
}
|
|
20113
|
-
|
|
20114
|
-
|
|
20115
|
-
|
|
20116
|
-
|
|
20117
|
-
|
|
20118
|
-
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
22232
|
+
}
|
|
22233
|
+
return replaceToml(text, doc, path5, value);
|
|
22234
|
+
}
|
|
22235
|
+
function setText(agent, path5, text, format, key, value) {
|
|
22236
|
+
try {
|
|
22237
|
+
if (format !== "toml") return setJsonText(text, format, key, value);
|
|
22238
|
+
const out = setTomlText(text, key, value);
|
|
22239
|
+
const landed = hostConfigValueAt(tomlValue(out), key);
|
|
22240
|
+
const emptyTable = isPlainObject3(value) && Object.keys(value).length === 0;
|
|
22241
|
+
if (!sameValue(landed, value) && !(emptyTable && landed === void 0)) throw new SyntaxError("edit did not land");
|
|
22242
|
+
return out;
|
|
22243
|
+
} catch {
|
|
22244
|
+
throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
|
|
22245
|
+
}
|
|
22246
|
+
}
|
|
22247
|
+
function serverScript() {
|
|
22248
|
+
return join7(dirname4(process.argv[1] ?? ""), SERVER_ENTRY_FILE);
|
|
22249
|
+
}
|
|
22250
|
+
function listTarget(key, own2, v1) {
|
|
22251
|
+
return {
|
|
22252
|
+
key: [key],
|
|
22253
|
+
next(current) {
|
|
22254
|
+
const list3 = Array.isArray(current) ? current.filter((x) => x !== v1) : [];
|
|
22255
|
+
return list3.includes(own2) ? list3 : [...list3, own2];
|
|
20130
22256
|
}
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
}
|
|
20140
|
-
|
|
20141
|
-
if (eq < 0) throw new SyntaxError("inline table");
|
|
20142
|
-
const key = tomlKeyPath(this.s.slice(this.i, eq));
|
|
20143
|
-
this.i = eq + 1;
|
|
20144
|
-
setPath(out, key, this.read());
|
|
20145
|
-
this.ws();
|
|
20146
|
-
if (this.s[this.i] === ",") {
|
|
20147
|
-
this.i += 1;
|
|
20148
|
-
continue;
|
|
20149
|
-
}
|
|
20150
|
-
if (this.s[this.i] !== "}") throw new SyntaxError("inline table");
|
|
22257
|
+
};
|
|
22258
|
+
}
|
|
22259
|
+
function ownTargets(agent) {
|
|
22260
|
+
const mcp = OWN_MCP_ENTRY[agent];
|
|
22261
|
+
if (mcp !== void 0) {
|
|
22262
|
+
return [{
|
|
22263
|
+
key: mcp.key,
|
|
22264
|
+
next(current) {
|
|
22265
|
+
const keep = isPlainObject3(current) ? current : {};
|
|
22266
|
+
return { ...keep, ...mcp.fields, [MCP_COMMAND_FIELD]: HOST_NODE_COMMAND, [MCP_ARGS_FIELD]: [serverScript(), AGENT_ARG, agent] };
|
|
20151
22267
|
}
|
|
20152
|
-
}
|
|
20153
|
-
let j = this.i;
|
|
20154
|
-
while (j < this.s.length && !" \r\n,]}#".includes(this.s[j])) j += 1;
|
|
20155
|
-
const word = this.s.slice(this.i, j);
|
|
20156
|
-
this.i = j;
|
|
20157
|
-
if (word === "true") return true;
|
|
20158
|
-
if (word === "false") return false;
|
|
20159
|
-
const n = Number(word.split("_").join(""));
|
|
20160
|
-
if (word === "" || Number.isNaN(n)) throw new SyntaxError("value");
|
|
20161
|
-
return n;
|
|
22268
|
+
}, ...(mcp.also ?? []).map(([key, value]) => ({ key, next: () => value }))];
|
|
20162
22269
|
}
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
22270
|
+
if (agent === "opencode") return [listTarget(OPENCODE_PLUGIN_KEY, OPENCODE_GIT_SPEC, V1_OPENCODE_PLUGIN_SPEC)];
|
|
22271
|
+
if (agent === "pi") return [listTarget(PI_PACKAGES_KEY, PI_GIT_PACKAGE, V1_PI_PACKAGE)];
|
|
22272
|
+
return [];
|
|
22273
|
+
}
|
|
22274
|
+
function applyEdits(agent, path5, text, format, wanted) {
|
|
22275
|
+
const parsed = parseHostConfig(agent, path5, text, format);
|
|
22276
|
+
let out = text;
|
|
22277
|
+
const edits = [];
|
|
22278
|
+
for (const [key, after] of wanted) {
|
|
22279
|
+
const before = hostConfigValueAt(parsed, key);
|
|
22280
|
+
if (sameValue(before, after)) continue;
|
|
22281
|
+
out = setText(agent, path5, out, format, key, after);
|
|
22282
|
+
edits.push({ path: key.join("."), before, after });
|
|
20171
22283
|
}
|
|
20172
|
-
|
|
20173
|
-
cur[path4[path4.length - 1]] = value;
|
|
22284
|
+
return { text: out, format, edits };
|
|
20174
22285
|
}
|
|
20175
|
-
function
|
|
20176
|
-
const
|
|
20177
|
-
const
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
22286
|
+
function mergeOwnEntries(agent, current, format, row5) {
|
|
22287
|
+
const parsed = parseHostConfig(row5.id, HOST_CONFIG_TEXT_PATH, current, format);
|
|
22288
|
+
const wanted = ownTargets(agent).map((t) => [t.key, t.next(hostConfigValueAt(parsed, t.key))]);
|
|
22289
|
+
return applyEdits(agent, HOST_CONFIG_TEXT_PATH, current, format, wanted);
|
|
22290
|
+
}
|
|
22291
|
+
function writeHostConfigEdit(_requested, current, patch) {
|
|
22292
|
+
const wanted = Object.entries(patch).map(([k, v]) => [[k], v]);
|
|
22293
|
+
const result = applyEdits(current.agent, current.path, current.text, current.format, wanted);
|
|
22294
|
+
if (result.edits.length === 0) return [];
|
|
22295
|
+
atomicWriteFile(current.path, current.layout === void 0 ? result.text : withLayout(result.text, current.layout));
|
|
22296
|
+
return result.edits;
|
|
22297
|
+
}
|
|
22298
|
+
|
|
22299
|
+
// src/core/ops/detect-v1.ts
|
|
22300
|
+
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22301
|
+
var keyPath = (...parts) => parts.join(".");
|
|
22302
|
+
var finding = (file2, path5, reason) => ({ file: file2, path: path5, reason });
|
|
22303
|
+
function stripJsonc(text) {
|
|
22304
|
+
let out = "";
|
|
22305
|
+
let inStr = false;
|
|
22306
|
+
let esc2 = false;
|
|
22307
|
+
for (let i = 0; i < text.length; i++) {
|
|
22308
|
+
const c = text[i];
|
|
22309
|
+
if (inStr) {
|
|
22310
|
+
out += c;
|
|
22311
|
+
if (esc2) esc2 = false;
|
|
22312
|
+
else if (c === "\\") esc2 = true;
|
|
22313
|
+
else if (c === '"') inStr = false;
|
|
20185
22314
|
continue;
|
|
20186
22315
|
}
|
|
20187
|
-
if (
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
if (close < 0) throw new SyntaxError("header");
|
|
20191
|
-
const path4 = tomlKeyPath(line.slice(1, close));
|
|
20192
|
-
if (tables.length > 0) tables[tables.length - 1].end = i;
|
|
20193
|
-
tables.push({ path: path4, start: i, end: text.length });
|
|
20194
|
-
let cur = value;
|
|
20195
|
-
for (const seg of path4) {
|
|
20196
|
-
if (cur[seg] === void 0) cur[seg] = {};
|
|
20197
|
-
if (!isPlainObject3(cur[seg])) throw new SyntaxError("table conflict");
|
|
20198
|
-
cur = cur[seg];
|
|
20199
|
-
}
|
|
20200
|
-
table = cur;
|
|
20201
|
-
i = lineEnd;
|
|
22316
|
+
if (c === '"') {
|
|
22317
|
+
inStr = true;
|
|
22318
|
+
out += c;
|
|
20202
22319
|
continue;
|
|
20203
22320
|
}
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
22321
|
+
if (c === "/" && text[i + 1] === "/") {
|
|
22322
|
+
while (i < text.length && text[i] !== "\n") i++;
|
|
22323
|
+
out += "\n";
|
|
22324
|
+
continue;
|
|
22325
|
+
}
|
|
22326
|
+
if (c === "/" && text[i + 1] === "*") {
|
|
22327
|
+
const end = text.indexOf("*/", i + 2);
|
|
22328
|
+
i = end === -1 ? text.length : end + 1;
|
|
22329
|
+
continue;
|
|
22330
|
+
}
|
|
22331
|
+
if (c === ",") {
|
|
22332
|
+
let j = i + 1;
|
|
22333
|
+
while (j < text.length && " \r\n".includes(text[j])) j++;
|
|
22334
|
+
if (text[j] === "}" || text[j] === "]") continue;
|
|
22335
|
+
}
|
|
22336
|
+
out += c;
|
|
22337
|
+
}
|
|
22338
|
+
return out;
|
|
22339
|
+
}
|
|
22340
|
+
function readJson(file2) {
|
|
22341
|
+
try {
|
|
22342
|
+
return JSON.parse(stripJsonc(hostText(readFileSync7(file2, "utf8"))));
|
|
22343
|
+
} catch {
|
|
22344
|
+
return void 0;
|
|
22345
|
+
}
|
|
22346
|
+
}
|
|
22347
|
+
function readText(file2) {
|
|
22348
|
+
try {
|
|
22349
|
+
return hostText(readFileSync7(file2, "utf8"));
|
|
22350
|
+
} catch {
|
|
22351
|
+
return "";
|
|
22352
|
+
}
|
|
22353
|
+
}
|
|
22354
|
+
function readTomlTables(file2) {
|
|
22355
|
+
try {
|
|
22356
|
+
return tomlTableSpans(readText(file2));
|
|
22357
|
+
} catch {
|
|
22358
|
+
return [];
|
|
20214
22359
|
}
|
|
20215
|
-
return { value, tables };
|
|
20216
22360
|
}
|
|
20217
|
-
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20221
|
-
|
|
22361
|
+
var listOf = (v) => Array.isArray(v) ? v : [];
|
|
22362
|
+
var commandOf = (v) => isObj(v) && typeof v.command === "string" ? v.command : null;
|
|
22363
|
+
function nestedCommands(doc) {
|
|
22364
|
+
const out = [];
|
|
22365
|
+
if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out;
|
|
22366
|
+
for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
|
|
22367
|
+
listOf(groups).forEach((group, i) => {
|
|
22368
|
+
if (!isObj(group)) return;
|
|
22369
|
+
listOf(group[HOOKS_KEY]).forEach((inner, j) => {
|
|
22370
|
+
const command = commandOf(inner);
|
|
22371
|
+
if (command !== null) out.push({ path: keyPath(HOOKS_KEY, event, i, HOOKS_KEY, j), command });
|
|
22372
|
+
});
|
|
22373
|
+
});
|
|
22374
|
+
}
|
|
22375
|
+
return out;
|
|
22376
|
+
}
|
|
22377
|
+
function flatCommands(events, prefix) {
|
|
22378
|
+
const out = [];
|
|
22379
|
+
if (!isObj(events)) return out;
|
|
22380
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
22381
|
+
listOf(entries).forEach((entry, i) => {
|
|
22382
|
+
const command = commandOf(entry);
|
|
22383
|
+
if (command !== null) out.push({ path: keyPath(...prefix, event, i), command });
|
|
22384
|
+
});
|
|
22385
|
+
}
|
|
22386
|
+
return out;
|
|
22387
|
+
}
|
|
22388
|
+
var isV1Hook = (cmd) => cmd.includes(SERVER_KEY) && (V1_SCRIPT_NAMES.some((name) => cmd.includes(name)) || cmd.includes(V1_HOOK_COMMAND));
|
|
22389
|
+
var isCodexScript = (cmd) => cmd.includes(V1_SCRIPT_EXT) && V1_PATH_SEPS.some((sep3) => cmd.includes(V1_CODEX_HOOKS_DIR.join(sep3) + sep3));
|
|
22390
|
+
function dataDir(dir, reason, out) {
|
|
22391
|
+
if (existsSync4(dir)) out.push(finding(dir, "", reason));
|
|
22392
|
+
}
|
|
22393
|
+
function mcpEntry(file2, doc, out) {
|
|
22394
|
+
if (isObj(doc) && isObj(doc[MCP_SERVERS_KEY]) && Object.hasOwn(doc[MCP_SERVERS_KEY], SERVER_KEY)) {
|
|
22395
|
+
out.push(finding(file2, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
|
|
20222
22396
|
}
|
|
20223
22397
|
}
|
|
20224
|
-
function
|
|
20225
|
-
|
|
20226
|
-
|
|
20227
|
-
|
|
20228
|
-
|
|
22398
|
+
function claudeShapeSettings(agentHome, out) {
|
|
22399
|
+
const file2 = join8(agentHome, SETTINGS_FILE);
|
|
22400
|
+
const doc = readJson(file2);
|
|
22401
|
+
for (const c of nestedCommands(doc)) {
|
|
22402
|
+
if (c.command.includes(V1_CACHE_HEAL_NAME)) out.push(finding(file2, c.path, V1_REASON.cacheHealHook));
|
|
22403
|
+
else if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.hook));
|
|
20229
22404
|
}
|
|
20230
|
-
|
|
22405
|
+
const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
|
|
22406
|
+
if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
|
|
22407
|
+
out.push(finding(file2, STATUS_LINE_KEY, V1_REASON.statusLine));
|
|
22408
|
+
}
|
|
22409
|
+
mcpEntry(file2, doc, out);
|
|
20231
22410
|
}
|
|
20232
|
-
function
|
|
20233
|
-
|
|
22411
|
+
function v1HookFile(file2, out) {
|
|
22412
|
+
const doc = readJson(file2);
|
|
22413
|
+
const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
|
|
22414
|
+
if (cmds.some((c) => c.command.includes(V1_HOOK_COMMAND))) out.push(finding(file2, "", V1_REASON.hookFile));
|
|
20234
22415
|
}
|
|
20235
|
-
function
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
return ka.length === Object.keys(b).length && ka.every((k) => sameValue(a[k], b[k]));
|
|
22416
|
+
function scanClaudeCode(home, agentHome, out) {
|
|
22417
|
+
claudeShapeSettings(agentHome, out);
|
|
22418
|
+
for (const ext of V1_CACHE_HEAL_EXTS) {
|
|
22419
|
+
const file2 = join8(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
|
|
22420
|
+
if (existsSync4(file2)) out.push(finding(file2, "", V1_REASON.cacheHealFile));
|
|
20241
22421
|
}
|
|
20242
|
-
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
let s = at2;
|
|
20246
|
-
while (s > 0 && text[s - 1] !== "\n") s -= 1;
|
|
20247
|
-
let e = s;
|
|
20248
|
-
while (text[e] === " " || text[e] === " ") e += 1;
|
|
20249
|
-
return text.slice(s, e);
|
|
22422
|
+
const userFile = join8(home, CLAUDE_USER_CONFIG_FILE);
|
|
22423
|
+
mcpEntry(userFile, readJson(userFile), out);
|
|
22424
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20250
22425
|
}
|
|
20251
|
-
function
|
|
20252
|
-
|
|
20253
|
-
const
|
|
20254
|
-
|
|
22426
|
+
function scanCodex(agentHome, out) {
|
|
22427
|
+
const hooksFile = join8(agentHome, HOOKS_JSON_FILE);
|
|
22428
|
+
for (const c of nestedCommands(readJson(hooksFile))) {
|
|
22429
|
+
if (c.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c.command)) {
|
|
22430
|
+
out.push(finding(hooksFile, c.path, V1_REASON.codexHook));
|
|
22431
|
+
}
|
|
22432
|
+
}
|
|
22433
|
+
const tomlFile = join8(agentHome, CONFIG_TOML_FILE);
|
|
22434
|
+
for (const span of readTomlTables(tomlFile)) {
|
|
22435
|
+
if (tomlHeaderText(span.path).startsWith(V1_TOML_SECTION_PREFIX)) out.push(finding(tomlFile, span.header.trim(), V1_REASON.codexToml));
|
|
22436
|
+
}
|
|
22437
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20255
22438
|
}
|
|
20256
|
-
function
|
|
20257
|
-
|
|
22439
|
+
function scanGemini(agentHome, out) {
|
|
22440
|
+
const file2 = join8(agentHome, SETTINGS_FILE);
|
|
22441
|
+
for (const c of nestedCommands(readJson(file2))) {
|
|
22442
|
+
if (c.command.includes(SERVER_KEY)) out.push(finding(file2, c.path, V1_REASON.hook));
|
|
22443
|
+
}
|
|
22444
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out);
|
|
20258
22445
|
}
|
|
20259
|
-
function
|
|
20260
|
-
|
|
20261
|
-
|
|
20262
|
-
|
|
22446
|
+
function scanVscode(agentHome, project, out) {
|
|
22447
|
+
if (project !== void 0) {
|
|
22448
|
+
v1HookFile(join8(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
|
|
22449
|
+
const mcpFile2 = join8(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
|
|
22450
|
+
const doc = readJson(mcpFile2);
|
|
22451
|
+
const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
|
|
22452
|
+
const entry = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
|
|
22453
|
+
if (isObj(entry) && (entry.command === V1_BIN_COMMAND || listOf(entry.args).some((a) => a === V1_BIN_COMMAND))) {
|
|
22454
|
+
out.push(finding(mcpFile2, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
|
|
22455
|
+
}
|
|
22456
|
+
dataDir(join8(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
|
|
22457
|
+
}
|
|
22458
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
|
|
20263
22459
|
}
|
|
20264
|
-
function
|
|
20265
|
-
|
|
20266
|
-
|
|
20267
|
-
|
|
20268
|
-
|
|
20269
|
-
let depth = 0;
|
|
20270
|
-
while (depth < path4.length && node.kind === "object") {
|
|
20271
|
-
const hit = node.members.find((m) => m.key === path4[depth]);
|
|
20272
|
-
if (hit === void 0) break;
|
|
20273
|
-
node = hit.node;
|
|
20274
|
-
depth += 1;
|
|
22460
|
+
function jsonFiles(dir) {
|
|
22461
|
+
try {
|
|
22462
|
+
return readdirSync(dir).filter((name) => name.endsWith(KIRO_AGENT_FILE_EXT)).sort();
|
|
22463
|
+
} catch {
|
|
22464
|
+
return [];
|
|
20275
22465
|
}
|
|
20276
|
-
|
|
20277
|
-
|
|
22466
|
+
}
|
|
22467
|
+
function scanKiro(agentHome, project, out) {
|
|
22468
|
+
const agentsDir = join8(agentHome, KIRO_AGENTS_DIR);
|
|
22469
|
+
const defaultFile = join8(agentHome, ...KIRO_AGENT_FILE);
|
|
22470
|
+
for (const name of jsonFiles(agentsDir)) {
|
|
22471
|
+
const file2 = join8(agentsDir, name);
|
|
22472
|
+
const doc = readJson(file2);
|
|
22473
|
+
if (isObj(doc) && doc[KIRO_AGENT_NAME_KEY] === SERVER_KEY) {
|
|
22474
|
+
out.push(finding(file2, "", V1_REASON.kiroAgentFile));
|
|
22475
|
+
continue;
|
|
22476
|
+
}
|
|
22477
|
+
if (file2 !== defaultFile) continue;
|
|
22478
|
+
for (const c of isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : []) {
|
|
22479
|
+
if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.kiroHook));
|
|
22480
|
+
}
|
|
20278
22481
|
}
|
|
20279
|
-
|
|
20280
|
-
|
|
20281
|
-
const
|
|
20282
|
-
|
|
20283
|
-
const base2 = lineIndent(doc.clean, node.start);
|
|
20284
|
-
const member2 = "\n" + base2 + unit + JSON.stringify(path4[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
|
|
20285
|
-
return text.slice(0, node.start + 1) + member2 + text.slice(node.end - 1);
|
|
22482
|
+
const steeringDocs = [join8(agentHome, ...KIRO_STEERING_FILE)];
|
|
22483
|
+
if (project !== void 0) steeringDocs.push(join8(project, ...AGENT_HOME_DIR.kiro, ...KIRO_STEERING_FILE));
|
|
22484
|
+
for (const file2 of steeringDocs) {
|
|
22485
|
+
if (existsSync4(file2)) out.push(finding(file2, "", V1_REASON.kiroSteering));
|
|
20286
22486
|
}
|
|
20287
|
-
|
|
20288
|
-
let at2 = last.node.end;
|
|
20289
|
-
while (" \r\n".includes(doc.clean[at2])) at2 += 1;
|
|
20290
|
-
const trailing = doc.clean[at2] === ",";
|
|
20291
|
-
const insertAt = trailing ? at2 + 1 : last.node.end;
|
|
20292
|
-
const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path4[depth]) + ": " + render(rest, unit, base);
|
|
20293
|
-
return text.slice(0, insertAt) + member + text.slice(insertAt);
|
|
22487
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20294
22488
|
}
|
|
20295
|
-
function
|
|
20296
|
-
|
|
20297
|
-
|
|
20298
|
-
|
|
20299
|
-
|
|
22489
|
+
function scanPi(piAgentDir, agentHome, out) {
|
|
22490
|
+
const file2 = join8(piAgentDir, SETTINGS_FILE);
|
|
22491
|
+
const doc = readJson(file2);
|
|
22492
|
+
listOf(isObj(doc) ? doc[PI_PACKAGES_KEY] : void 0).forEach((pkg, i) => {
|
|
22493
|
+
const spec = isObj(pkg) ? pkg[PI_PACKAGE_SOURCE_KEY] : pkg;
|
|
22494
|
+
if (spec === V1_PI_PACKAGE) out.push(finding(file2, keyPath(PI_PACKAGES_KEY, i), V1_REASON.piNpm));
|
|
22495
|
+
});
|
|
22496
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
20300
22497
|
}
|
|
20301
|
-
function
|
|
20302
|
-
for (const
|
|
20303
|
-
const
|
|
20304
|
-
|
|
22498
|
+
function scanOpencode(agentHome, out) {
|
|
22499
|
+
for (const name of OPENCODE_CONFIG_FILES) {
|
|
22500
|
+
const file2 = join8(agentHome, name);
|
|
22501
|
+
const doc = readJson(file2);
|
|
22502
|
+
if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
|
|
22503
|
+
doc[OPENCODE_PLUGIN_KEY].forEach((spec, i) => {
|
|
22504
|
+
if (spec === V1_OPENCODE_PLUGIN_SPEC) out.push(finding(file2, keyPath(OPENCODE_PLUGIN_KEY, i), V1_REASON.opencodePlugin));
|
|
22505
|
+
});
|
|
22506
|
+
return;
|
|
20305
22507
|
}
|
|
20306
|
-
return seg;
|
|
20307
22508
|
}
|
|
20308
|
-
function
|
|
20309
|
-
|
|
20310
|
-
const
|
|
20311
|
-
|
|
20312
|
-
|
|
20313
|
-
|
|
22509
|
+
function scanZcode(agentHome, out) {
|
|
22510
|
+
const configFile = join8(agentHome, ZCODE_CLI_DIR, CONFIG_JSON_FILE);
|
|
22511
|
+
const config2 = readJson(configFile);
|
|
22512
|
+
const events = isObj(config2) && isObj(config2[HOOKS_KEY]) ? config2[HOOKS_KEY][ZCODE_EVENTS_KEY] : void 0;
|
|
22513
|
+
for (const c of flatCommands(events, [HOOKS_KEY, ZCODE_EVENTS_KEY])) {
|
|
22514
|
+
if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(configFile, c.path, V1_REASON.zcodeHook));
|
|
22515
|
+
}
|
|
22516
|
+
const hooksFile = join8(agentHome, ZCODE_CLI_DIR, HOOKS_JSON_FILE);
|
|
22517
|
+
for (const c of nestedCommands(readJson(hooksFile))) {
|
|
22518
|
+
if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(hooksFile, c.path, V1_REASON.zcodeHook));
|
|
20314
22519
|
}
|
|
20315
|
-
return [out, ...subs].join("\n");
|
|
20316
22520
|
}
|
|
20317
|
-
function
|
|
20318
|
-
|
|
20319
|
-
const doc = scanToml(text);
|
|
20320
|
-
const owned = doc.tables.filter((t) => t.path.length >= path4.length && path4.every((seg, k) => t.path[k] === seg));
|
|
20321
|
-
const block = tomlBlock(path4, value);
|
|
20322
|
-
if (owned.length === 0) {
|
|
20323
|
-
const sep3 = text === "" ? "" : text.endsWith("\n\n") ? "" : text.endsWith("\n") ? "\n" : "\n\n";
|
|
20324
|
-
return text + sep3 + block;
|
|
20325
|
-
}
|
|
20326
|
-
let out = text.slice(0, owned[0].start) + block;
|
|
20327
|
-
let cursor = owned[0].end;
|
|
20328
|
-
for (const t of owned.slice(1)) {
|
|
20329
|
-
out += text.slice(cursor, t.start).trim() === "" ? "" : text.slice(cursor, t.start);
|
|
20330
|
-
cursor = t.end;
|
|
20331
|
-
}
|
|
20332
|
-
const tail = text.slice(cursor);
|
|
20333
|
-
return out + (tail === "" || block.endsWith("\n\n") ? "" : "\n") + tail;
|
|
20334
|
-
}
|
|
20335
|
-
function setText(agent, path4, text, format, key, value) {
|
|
22521
|
+
function firstTmpMatch(dir) {
|
|
22522
|
+
let handle;
|
|
20336
22523
|
try {
|
|
20337
|
-
|
|
22524
|
+
handle = opendirSync(dir);
|
|
20338
22525
|
} catch {
|
|
20339
|
-
|
|
22526
|
+
return null;
|
|
20340
22527
|
}
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
}
|
|
20345
|
-
function listTarget(key, own2, v1) {
|
|
20346
|
-
return {
|
|
20347
|
-
key: [key],
|
|
20348
|
-
next(current) {
|
|
20349
|
-
const list3 = Array.isArray(current) ? current.filter((x) => x !== v1) : [];
|
|
20350
|
-
return list3.includes(own2) ? list3 : [...list3, own2];
|
|
22528
|
+
try {
|
|
22529
|
+
for (let e = handle.readSync(); e !== null; e = handle.readSync()) {
|
|
22530
|
+
if (e.name.startsWith(V1_TMP_PREFIX)) return e.name;
|
|
20351
22531
|
}
|
|
20352
|
-
|
|
20353
|
-
}
|
|
20354
|
-
|
|
20355
|
-
|
|
20356
|
-
|
|
20357
|
-
return [{
|
|
20358
|
-
key: mcp.key,
|
|
20359
|
-
next(current) {
|
|
20360
|
-
const keep = isPlainObject3(current) ? current : {};
|
|
20361
|
-
return { ...keep, ...mcp.fields, [MCP_COMMAND_FIELD]: HOST_NODE_COMMAND, [MCP_ARGS_FIELD]: [serverScript(), AGENT_ARG, agent] };
|
|
20362
|
-
}
|
|
20363
|
-
}, ...(mcp.also ?? []).map(([key, value]) => ({ key, next: () => value }))];
|
|
20364
|
-
}
|
|
20365
|
-
if (agent === "opencode") return [listTarget(OPENCODE_PLUGIN_KEY, OPENCODE_GIT_SPEC, V1_OPENCODE_PLUGIN_SPEC)];
|
|
20366
|
-
if (agent === "pi") return [listTarget(PI_PACKAGES_KEY, PI_GIT_PACKAGE, V1_PI_PACKAGE)];
|
|
20367
|
-
return [];
|
|
20368
|
-
}
|
|
20369
|
-
function applyEdits(agent, path4, text, format, wanted) {
|
|
20370
|
-
const parsed = parseHostConfig(agent, path4, text, format);
|
|
20371
|
-
let out = text;
|
|
20372
|
-
const edits = [];
|
|
20373
|
-
for (const [key, after] of wanted) {
|
|
20374
|
-
const before = hostConfigValueAt(parsed, key);
|
|
20375
|
-
if (sameValue(before, after)) continue;
|
|
20376
|
-
out = setText(agent, path4, out, format, key, after);
|
|
20377
|
-
edits.push({ path: key.join("."), before, after });
|
|
22532
|
+
return null;
|
|
22533
|
+
} catch {
|
|
22534
|
+
return null;
|
|
22535
|
+
} finally {
|
|
22536
|
+
handle.closeSync();
|
|
20378
22537
|
}
|
|
20379
|
-
return { text: out, format, edits };
|
|
20380
22538
|
}
|
|
20381
|
-
function
|
|
20382
|
-
const
|
|
20383
|
-
const
|
|
20384
|
-
|
|
22539
|
+
function scanAll(home, tmp, out) {
|
|
22540
|
+
const root = join8(home, DATA_ROOT.slice(1));
|
|
22541
|
+
for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join8(root, name), V1_REASON.dataRoot, out);
|
|
22542
|
+
if (firstTmpMatch(tmp) !== null) out.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
|
|
20385
22543
|
}
|
|
20386
|
-
function
|
|
20387
|
-
const
|
|
20388
|
-
const
|
|
20389
|
-
|
|
20390
|
-
|
|
20391
|
-
|
|
20392
|
-
|
|
20393
|
-
|
|
22544
|
+
function detectV1(agent, home, scope = {}) {
|
|
22545
|
+
const out = [];
|
|
22546
|
+
const project = scope.project;
|
|
22547
|
+
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 : join8(home, ...AGENT_HOME_DIR[agent]);
|
|
22548
|
+
switch (agent) {
|
|
22549
|
+
case "claude-code":
|
|
22550
|
+
scanClaudeCode(home, agentHome, out);
|
|
22551
|
+
break;
|
|
22552
|
+
case "codex":
|
|
22553
|
+
scanCodex(agentHome, out);
|
|
22554
|
+
break;
|
|
22555
|
+
case "gemini":
|
|
22556
|
+
scanGemini(agentHome, out);
|
|
22557
|
+
break;
|
|
22558
|
+
case "qwen":
|
|
22559
|
+
claudeShapeSettings(agentHome, out);
|
|
22560
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
22561
|
+
break;
|
|
22562
|
+
case "copilot-cli":
|
|
22563
|
+
v1HookFile(join8(agentHome, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
|
|
22564
|
+
dataDir(join8(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
|
|
22565
|
+
break;
|
|
22566
|
+
case "vscode":
|
|
22567
|
+
scanVscode(agentHome, project, out);
|
|
22568
|
+
break;
|
|
22569
|
+
case "kiro":
|
|
22570
|
+
scanKiro(agentHome, project, out);
|
|
22571
|
+
break;
|
|
22572
|
+
case "pi":
|
|
22573
|
+
scanPi(scope.piAgentDir !== void 0 && scope.piAgentDir !== "" ? scope.piAgentDir : join8(agentHome, PI_AGENT_DIR), agentHome, out);
|
|
22574
|
+
break;
|
|
22575
|
+
// D-WIN-PIDIR-1: empty is unset
|
|
22576
|
+
case "opencode":
|
|
22577
|
+
scanOpencode(agentHome, out);
|
|
22578
|
+
break;
|
|
22579
|
+
case "zcode":
|
|
22580
|
+
scanZcode(agentHome, out);
|
|
22581
|
+
break;
|
|
22582
|
+
}
|
|
22583
|
+
scanAll(home, scope.tmp ?? tmpdir(), out);
|
|
22584
|
+
return out;
|
|
20394
22585
|
}
|
|
20395
22586
|
|
|
20396
22587
|
// src/core/ops/plugin-root.ts
|
|
20397
22588
|
import { existsSync as existsSync5, readdirSync as readdirSync2, realpathSync as realpathSync4 } from "node:fs";
|
|
20398
22589
|
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join9 } from "node:path";
|
|
20399
22590
|
import { fileURLToPath } from "node:url";
|
|
20400
|
-
function
|
|
20401
|
-
|
|
20402
|
-
if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
|
|
20403
|
-
return home;
|
|
20404
|
-
}
|
|
20405
|
-
function missing(agent, path4) {
|
|
20406
|
-
return new CtxError("PLUGIN_ROOT_MISSING", { agent, path: path4 });
|
|
22591
|
+
function missing(agent, path5) {
|
|
22592
|
+
return new CtxError("PLUGIN_ROOT_MISSING", { agent, path: path5 });
|
|
20407
22593
|
}
|
|
20408
22594
|
function marketplaceRoot(adapter, env) {
|
|
20409
|
-
const cache = join9(
|
|
22595
|
+
const cache = join9(claudeDirOf(env, requireHomeDir(env)), HOST_PLUGINS_DIR_NAME, PLUGIN_CACHE_DIR_NAME);
|
|
20410
22596
|
const pattern = join9(cache, "*", PLUGIN_NAME);
|
|
20411
22597
|
if (!existsSync5(cache)) throw missing(adapter.id, pattern);
|
|
20412
22598
|
const found = readdirSync2(cache).sort().map((marketplace) => join9(cache, marketplace, PLUGIN_NAME)).filter((dir) => existsSync5(dir));
|
|
@@ -20416,7 +22602,7 @@ function marketplaceRoot(adapter, env) {
|
|
|
20416
22602
|
function configEntryRoot(adapter, env) {
|
|
20417
22603
|
const spec = OWN_MCP_ENTRY[adapter.id];
|
|
20418
22604
|
if (spec === void 0) throw missing(adapter.id, SERVER_KEY);
|
|
20419
|
-
const file2 =
|
|
22605
|
+
const file2 = ownMcpFileOf(adapter.id, spec.file, env, requireHomeDir(env));
|
|
20420
22606
|
if (!existsSync5(file2)) throw missing(adapter.id, file2);
|
|
20421
22607
|
const current = readHostConfig(adapter.id, file2);
|
|
20422
22608
|
const value = parseHostConfig(adapter.id, file2, current.text, current.format);
|
|
@@ -20434,7 +22620,7 @@ function candidate(adapter, env) {
|
|
|
20434
22620
|
case "hooks+mcp":
|
|
20435
22621
|
return configEntryRoot(adapter, env);
|
|
20436
22622
|
case "extension":
|
|
20437
|
-
return join9(
|
|
22623
|
+
return join9(requireHomeDir(env), ...AGENT_HOME_DIR[adapter.id], EXTENSIONS_DIR_NAME, PLUGIN_NAME);
|
|
20438
22624
|
case "plugin":
|
|
20439
22625
|
return join9(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, adapter.id, PLUGIN_CURRENT_LINK);
|
|
20440
22626
|
case "in-process":
|
|
@@ -20442,11 +22628,11 @@ function candidate(adapter, env) {
|
|
|
20442
22628
|
}
|
|
20443
22629
|
}
|
|
20444
22630
|
function resolvePluginRoot(adapter, env) {
|
|
20445
|
-
const
|
|
22631
|
+
const path5 = candidate(adapter, env);
|
|
20446
22632
|
try {
|
|
20447
|
-
return realpathSync4.native(
|
|
22633
|
+
return realpathSync4.native(path5);
|
|
20448
22634
|
} catch {
|
|
20449
|
-
throw missing(adapter.id,
|
|
22635
|
+
throw missing(adapter.id, path5);
|
|
20450
22636
|
}
|
|
20451
22637
|
}
|
|
20452
22638
|
|
|
@@ -20472,14 +22658,31 @@ function composeMatcher(row5, event) {
|
|
|
20472
22658
|
if (event === POST_TOOL_USE && hasReplace(row5)) alts.push(MCP_ANY_MATCH);
|
|
20473
22659
|
return MATCHER_OPEN + alts.join(MATCHER_ALT) + MATCHER_CLOSE;
|
|
20474
22660
|
}
|
|
22661
|
+
var lastSegment = (p) => {
|
|
22662
|
+
let at2 = -1;
|
|
22663
|
+
for (const sep3 of V1_PATH_SEPS) at2 = Math.max(at2, p.lastIndexOf(sep3));
|
|
22664
|
+
return p.slice(at2 + 1);
|
|
22665
|
+
};
|
|
22666
|
+
function splitHead(command) {
|
|
22667
|
+
if (command.startsWith(SHELL_QUOTE)) {
|
|
22668
|
+
const close = command.indexOf(SHELL_QUOTE, 1);
|
|
22669
|
+
if (close < 0 || command.slice(close + 1, close + 1 + HOOK_COMMAND_SEP.length) !== HOOK_COMMAND_SEP) return null;
|
|
22670
|
+
return { head: command.slice(1, close), rest: command.slice(close + 1 + HOOK_COMMAND_SEP.length) };
|
|
22671
|
+
}
|
|
22672
|
+
const end = command.indexOf(HOOK_COMMAND_SEP);
|
|
22673
|
+
return end < 0 ? null : { head: command.slice(0, end), rest: command.slice(end + HOOK_COMMAND_SEP.length) };
|
|
22674
|
+
}
|
|
20475
22675
|
function isOwnCommand(command, agent) {
|
|
20476
22676
|
if (typeof command !== "string") return false;
|
|
20477
|
-
const
|
|
22677
|
+
const split = splitHead(command);
|
|
22678
|
+
if (split === null) return false;
|
|
22679
|
+
const exe = lastSegment(split.head).toLowerCase();
|
|
22680
|
+
if (exe !== HOST_NODE_COMMAND && exe !== HOST_NODE_COMMAND + EXE_SUFFIX) return false;
|
|
20478
22681
|
const tail = HOOK_COMMAND_SEP + AGENT_ARG + HOOK_COMMAND_SEP + agent;
|
|
20479
|
-
if (!
|
|
20480
|
-
let script =
|
|
22682
|
+
if (!split.rest.endsWith(tail) || split.rest.length <= tail.length) return false;
|
|
22683
|
+
let script = split.rest.slice(0, split.rest.length - tail.length);
|
|
20481
22684
|
if (script.startsWith(SHELL_QUOTE) && script.endsWith(SHELL_QUOTE) && script.length > 1) script = script.slice(1, -1);
|
|
20482
|
-
return script === HOOK_ENTRY_FILE ||
|
|
22685
|
+
return script === HOOK_ENTRY_FILE || HOOK_SCRIPT_SEPS.some((sep3) => script.endsWith(sep3 + HOOK_ENTRY_FILE));
|
|
20483
22686
|
}
|
|
20484
22687
|
function ownHooks(block, shape, timeoutKey, native, agent) {
|
|
20485
22688
|
const out = [];
|
|
@@ -20511,11 +22714,10 @@ var validTimeout = (v) => typeof v === "number" && Number.isFinite(v) && v > 0;
|
|
|
20511
22714
|
function mcpFile(row5, home, env) {
|
|
20512
22715
|
const spec = OWN_MCP_ENTRY[row5.id];
|
|
20513
22716
|
if (row5.id === "codex") return join10(codexDirOf(env, home), CONFIG_TOML_FILE);
|
|
20514
|
-
if (spec !== void 0) return
|
|
20515
|
-
if (row5.id === "opencode") return join10(
|
|
22717
|
+
if (spec !== void 0) return ownMcpFileOf(row5.id, spec.file, env, home);
|
|
22718
|
+
if (row5.id === "opencode") return join10(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
|
|
20516
22719
|
if (row5.id === "pi") {
|
|
20517
|
-
|
|
20518
|
-
return join10(dir !== void 0 && dir !== "" ? dir : join10(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR), SETTINGS_FILE);
|
|
22720
|
+
return join10(piAgentDirOf(env, home), SETTINGS_FILE);
|
|
20519
22721
|
}
|
|
20520
22722
|
return null;
|
|
20521
22723
|
}
|
|
@@ -20538,7 +22740,7 @@ function hookParts(row5, home, env, worktree) {
|
|
|
20538
22740
|
let block;
|
|
20539
22741
|
try {
|
|
20540
22742
|
const root = spec.root === "plugin" ? resolvePluginRoot(row5, env) : spec.root === "home" ? home : worktree;
|
|
20541
|
-
const file2 = row5.id === "codex" ? join10(codexDirOf(env, home), HOOKS_JSON_FILE) : join10(root, ...spec.file);
|
|
22743
|
+
const file2 = row5.id === "codex" ? join10(codexDirOf(env, home), HOOKS_JSON_FILE) : row5.id === "copilot-cli" ? join10(copilotDirOf(env, home), ...spec.file.slice(1)) : row5.id === "kiro" ? join10(kiroDirOf(env, home), ...spec.file.slice(1)) : join10(root, ...spec.file);
|
|
20542
22744
|
block = hostConfigValueAt(readParsed(row5.id, file2).value, spec.key);
|
|
20543
22745
|
if (row5.id === "codex") {
|
|
20544
22746
|
const config2 = readParsed(row5.id, join10(codexDirOf(env, home), CONFIG_TOML_FILE)).value;
|
|
@@ -20620,8 +22822,8 @@ async function loadSqlite2() {
|
|
|
20620
22822
|
return null;
|
|
20621
22823
|
}
|
|
20622
22824
|
}
|
|
20623
|
-
function openRead(sqlite,
|
|
20624
|
-
return new sqlite.DatabaseSync(
|
|
22825
|
+
function openRead(sqlite, path5) {
|
|
22826
|
+
return new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS, readOnly: true });
|
|
20625
22827
|
}
|
|
20626
22828
|
var cell = (row5) => Object.values(row5)[0];
|
|
20627
22829
|
function readSchema(raw) {
|
|
@@ -20755,20 +22957,26 @@ function checkProject(i) {
|
|
|
20755
22957
|
function checkMode(adapter) {
|
|
20756
22958
|
return pass3("D10", D10_DETAIL(adapter.denyChannel));
|
|
20757
22959
|
}
|
|
22960
|
+
function checkShell(env) {
|
|
22961
|
+
const win = process.platform === "win32";
|
|
22962
|
+
const shell = findRuntime("shell", env);
|
|
22963
|
+
if (shell !== null) return pass3("D11", D11_PASS_DETAIL(shell, win));
|
|
22964
|
+
return win ? fail4("D11", D11_WIN_DETAIL, D11_WIN_FIX) : fail4("D11", D11_POSIX_DETAIL, D11_POSIX_FIX);
|
|
22965
|
+
}
|
|
20758
22966
|
|
|
20759
22967
|
// src/core/ops/doctor-hook.ts
|
|
20760
22968
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
|
|
20761
|
-
import
|
|
22969
|
+
import path4 from "node:path";
|
|
20762
22970
|
var row = (status, detail, fixCommand) => fixCommand === void 0 ? { id: "D5", label: DOCTOR_LABEL.D5, status, detail } : { id: "D5", label: DOCTOR_LABEL.D5, status, detail, fixCommand };
|
|
20763
22971
|
function isObject5(v) {
|
|
20764
22972
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
20765
22973
|
}
|
|
20766
22974
|
function loadFixture(bundleDir2, agent) {
|
|
20767
|
-
const file2 =
|
|
22975
|
+
const file2 = path4.join(bundleDir2, HOOK_FIXTURE_DIR, HOOK_FIXTURE_FILE);
|
|
20768
22976
|
if (!existsSync8(file2)) return null;
|
|
20769
22977
|
let all;
|
|
20770
22978
|
try {
|
|
20771
|
-
all = JSON.parse(readFileSync8(file2, "utf8"));
|
|
22979
|
+
all = JSON.parse(hostText(readFileSync8(file2, "utf8")));
|
|
20772
22980
|
} catch {
|
|
20773
22981
|
return null;
|
|
20774
22982
|
}
|
|
@@ -20793,14 +23001,14 @@ function codexHookJournaled(db) {
|
|
|
20793
23001
|
return db.raw.prepare("SELECT 1 FROM events WHERE agent = ? LIMIT 1").get("codex") !== void 0;
|
|
20794
23002
|
}
|
|
20795
23003
|
async function checkHookRoundTrip(i) {
|
|
20796
|
-
if (i.agent === "codex" && existsSync8(
|
|
23004
|
+
if (i.agent === "codex" && existsSync8(path4.join(i.codexConfigDir, HOOKS_JSON_FILE)) && !codexHookJournaled(i.db)) {
|
|
20797
23005
|
return row("UNKNOWN", D5_CODEX_UNTRUSTED_DETAIL);
|
|
20798
23006
|
}
|
|
20799
23007
|
const fixture = loadFixture(i.bundleDir, i.agent);
|
|
20800
23008
|
if (fixture === null) return row("UNKNOWN", D5_NO_FIXTURE_DETAIL(i.agent));
|
|
20801
23009
|
const now = i.now ?? (() => performance.now());
|
|
20802
23010
|
const start = now();
|
|
20803
|
-
const r = await runProcess([process.execPath,
|
|
23011
|
+
const r = await runProcess([process.execPath, path4.join(i.bundleDir, HOOK_ENTRY_FILE), AGENT_ARG, i.agent], {
|
|
20804
23012
|
cwd: i.bundleDir,
|
|
20805
23013
|
env: i.env,
|
|
20806
23014
|
signal: i.signal,
|
|
@@ -20814,15 +23022,15 @@ async function checkHookRoundTrip(i) {
|
|
|
20814
23022
|
}
|
|
20815
23023
|
|
|
20816
23024
|
// src/core/ops/db-heal.ts
|
|
20817
|
-
import { existsSync as existsSync9,
|
|
23025
|
+
import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
|
|
20818
23026
|
|
|
20819
23027
|
// src/core/store/owners.ts
|
|
20820
|
-
import { mkdirSync as
|
|
23028
|
+
import { mkdirSync as mkdirSync4, readdirSync as readdirSync3, readFileSync as readFileSync9, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
20821
23029
|
import { basename as basename2, join as join11 } from "node:path";
|
|
20822
23030
|
function ownersDir(configDir, projectKey) {
|
|
20823
23031
|
return join11(configDir, PROJECTS_DIR_NAME, projectKey, OWNERS_DIR_NAME);
|
|
20824
23032
|
}
|
|
20825
|
-
function
|
|
23033
|
+
function errCode2(err) {
|
|
20826
23034
|
return err.code;
|
|
20827
23035
|
}
|
|
20828
23036
|
function isLive(pid) {
|
|
@@ -20831,8 +23039,8 @@ function isLive(pid) {
|
|
|
20831
23039
|
process.kill(pid, 0);
|
|
20832
23040
|
return true;
|
|
20833
23041
|
} catch (err) {
|
|
20834
|
-
if (
|
|
20835
|
-
if (
|
|
23042
|
+
if (errCode2(err) === "ESRCH") return false;
|
|
23043
|
+
if (errCode2(err) === "EPERM") return true;
|
|
20836
23044
|
throw err;
|
|
20837
23045
|
}
|
|
20838
23046
|
}
|
|
@@ -20842,7 +23050,7 @@ function listLiveOwners(configDir, projectKey) {
|
|
|
20842
23050
|
try {
|
|
20843
23051
|
names = readdirSync3(dir);
|
|
20844
23052
|
} catch (err) {
|
|
20845
|
-
if (
|
|
23053
|
+
if (errCode2(err) === "ENOENT") return [];
|
|
20846
23054
|
throw err;
|
|
20847
23055
|
}
|
|
20848
23056
|
const live = [];
|
|
@@ -20853,7 +23061,7 @@ function listLiveOwners(configDir, projectKey) {
|
|
|
20853
23061
|
try {
|
|
20854
23062
|
text = readFileSync9(file2, "utf8");
|
|
20855
23063
|
} catch (err) {
|
|
20856
|
-
if (
|
|
23064
|
+
if (errCode2(err) === "ENOENT") continue;
|
|
20857
23065
|
throw err;
|
|
20858
23066
|
}
|
|
20859
23067
|
const serverId = basename2(name, OWNER_PID_EXT);
|
|
@@ -20888,7 +23096,7 @@ async function healLossless(dbPath) {
|
|
|
20888
23096
|
}
|
|
20889
23097
|
rmSync3(dbPath + DB_WAL_SUFFIX, { force: true });
|
|
20890
23098
|
rmSync3(dbPath + DB_SHM_SUFFIX, { force: true });
|
|
20891
|
-
|
|
23099
|
+
renameWithRetry(tmp, dbPath);
|
|
20892
23100
|
} finally {
|
|
20893
23101
|
rmSync3(tmp, { force: true });
|
|
20894
23102
|
}
|
|
@@ -20897,7 +23105,7 @@ function renameAside(dbPath) {
|
|
|
20897
23105
|
const ts = String(Date.now());
|
|
20898
23106
|
for (const suffix of DB_SIBLING_SUFFIXES) {
|
|
20899
23107
|
const file2 = dbPath + suffix;
|
|
20900
|
-
if (existsSync9(file2))
|
|
23108
|
+
if (existsSync9(file2)) renameWithRetry(file2, file2 + HEAL_TS_SEP + ts + HEAL_BACKUP_SUFFIX);
|
|
20901
23109
|
}
|
|
20902
23110
|
return ts;
|
|
20903
23111
|
}
|
|
@@ -20965,11 +23173,6 @@ async function guard(id2, run) {
|
|
|
20965
23173
|
return { id: id2, label: DOCTOR_LABEL[id2], status: "UNKNOWN", detail: lineOf2(err) };
|
|
20966
23174
|
}
|
|
20967
23175
|
}
|
|
20968
|
-
function needHome(env) {
|
|
20969
|
-
const home = homeDirOf(env);
|
|
20970
|
-
if (home === null) throw new CtxError("NO_HOME", { name: "HOME" });
|
|
20971
|
-
return home;
|
|
20972
|
-
}
|
|
20973
23176
|
async function codexDb(ctx, adapter) {
|
|
20974
23177
|
if (adapter.id !== "codex" || !existsSync10(ctx.project.dbPath)) return null;
|
|
20975
23178
|
try {
|
|
@@ -20986,7 +23189,7 @@ async function hookRow(ctx, adapter, host) {
|
|
|
20986
23189
|
bundleDir: host.bundleDir,
|
|
20987
23190
|
env: buildChildEnv(host.env),
|
|
20988
23191
|
signal: ctx.signal,
|
|
20989
|
-
codexConfigDir: codexDirOf(host.env,
|
|
23192
|
+
codexConfigDir: codexDirOf(host.env, requireHomeDir(host.env)),
|
|
20990
23193
|
// same Codex dir D3 reads (D-N6-CODEX-HOME-2)
|
|
20991
23194
|
db
|
|
20992
23195
|
});
|
|
@@ -21011,7 +23214,7 @@ async function runDoctorChecks(ctx, adapter, host) {
|
|
|
21011
23214
|
D1: () => checkVersion({ bundleSha: BUNDLE_SHA, env: buildChildEnv(env), cwd: project.worktree, signal: ctx.signal }),
|
|
21012
23215
|
D2: () => checkNode({ nodeVersion: process.version, bunVersion: process.versions.bun }),
|
|
21013
23216
|
D3: () => checkHostConfig(adapter, env, project.worktree),
|
|
21014
|
-
D4: () => checkV1Leftovers(adapter.id,
|
|
23217
|
+
D4: () => checkV1Leftovers(adapter.id, requireHomeDir(env), { project: project.worktree, piAgentDir: piAgentDirOf(env, requireHomeDir(env)), claudeDir: claudeDirOf(env, requireHomeDir(env)), copilotDir: copilotDirOf(env, requireHomeDir(env)), kiroDir: kiroDirOf(env, requireHomeDir(env)), opencodeDir: opencodeDirOf(env, requireHomeDir(env)) }),
|
|
21015
23218
|
D5: () => hookRow(ctx, adapter, host),
|
|
21016
23219
|
D5b: () => checkDoubleFire(adapter.id, project.worktree),
|
|
21017
23220
|
D6: () => checkMcp(ctx),
|
|
@@ -21022,7 +23225,8 @@ async function runDoctorChecks(ctx, adapter, host) {
|
|
|
21022
23225
|
return r.row;
|
|
21023
23226
|
},
|
|
21024
23227
|
D9: () => checkIndex(project),
|
|
21025
|
-
D10: () => checkMode(adapter)
|
|
23228
|
+
D10: () => checkMode(adapter),
|
|
23229
|
+
D11: () => checkShell(env)
|
|
21026
23230
|
};
|
|
21027
23231
|
const rows = [];
|
|
21028
23232
|
for (const id2 of DOCTOR_CHECK_ORDER) rows.push(await guard(id2, checks[id2]));
|
|
@@ -21214,7 +23418,7 @@ async function handler3(raw, ctx) {
|
|
|
21214
23418
|
extra.CTX_FILE = abs;
|
|
21215
23419
|
}
|
|
21216
23420
|
const runtime = findRuntime(input.language);
|
|
21217
|
-
if (runtime === null) return fail5(
|
|
23421
|
+
if (runtime === null) return fail5(noRuntimeError(input.language).toLine());
|
|
21218
23422
|
const env = buildChildEnv(process.env, extra);
|
|
21219
23423
|
const timeoutMs = input.timeoutMs ?? EXEC_TIMEOUT_MS;
|
|
21220
23424
|
const journal = { kind: "cmd", key: canonicalKey(TOOL2, input.code), path: input.file ?? null, exit_code: null };
|
|
@@ -21287,14 +23491,14 @@ function visit(abs, rel, parent, contain, seen, found) {
|
|
|
21287
23491
|
const rules = entries.some((e) => e.name === GITIGNORE && e.isFile()) ? parent.concat(readRules(join14(abs, GITIGNORE), rel)) : parent;
|
|
21288
23492
|
for (const e of entries) {
|
|
21289
23493
|
if (e.name === GIT_DIR) continue;
|
|
21290
|
-
const
|
|
23494
|
+
const path5 = join14(abs, e.name);
|
|
21291
23495
|
let isDir = e.isDirectory();
|
|
21292
23496
|
let isFile = e.isFile();
|
|
21293
|
-
let target =
|
|
23497
|
+
let target = path5;
|
|
21294
23498
|
if (e.isSymbolicLink()) {
|
|
21295
23499
|
let resolved;
|
|
21296
23500
|
try {
|
|
21297
|
-
resolved = realpathSync6(
|
|
23501
|
+
resolved = realpathSync6(path5);
|
|
21298
23502
|
} catch {
|
|
21299
23503
|
continue;
|
|
21300
23504
|
}
|
|
@@ -21307,12 +23511,12 @@ function visit(abs, rel, parent, contain, seen, found) {
|
|
|
21307
23511
|
const segs = rel.concat(e.name);
|
|
21308
23512
|
if (ignored(rules, segs, isDir)) continue;
|
|
21309
23513
|
if (isFile) {
|
|
21310
|
-
found.push({ dir: rel, name: e.name, absPath:
|
|
23514
|
+
found.push({ dir: rel, name: e.name, absPath: path5 });
|
|
21311
23515
|
} else if (isDir) {
|
|
21312
|
-
const key = e.isSymbolicLink() ? target : realpathSync6(
|
|
23516
|
+
const key = e.isSymbolicLink() ? target : realpathSync6(path5);
|
|
21313
23517
|
if (seen.has(key)) continue;
|
|
21314
23518
|
seen.add(key);
|
|
21315
|
-
visit(
|
|
23519
|
+
visit(path5, segs, rules, contain, seen, found);
|
|
21316
23520
|
}
|
|
21317
23521
|
}
|
|
21318
23522
|
}
|
|
@@ -21503,12 +23707,12 @@ function tlsName(host) {
|
|
|
21503
23707
|
function request(u, conn, proxy, signal) {
|
|
21504
23708
|
const host = bare(u.hostname);
|
|
21505
23709
|
const port = u.port === "" ? defaultPort(u.protocol) : Number(u.port);
|
|
21506
|
-
const
|
|
23710
|
+
const path5 = u.pathname + u.search;
|
|
21507
23711
|
return new Promise((resolve5, reject) => {
|
|
21508
23712
|
const onErr = (err) => reject(fail6(causeCode(err)));
|
|
21509
23713
|
if (proxy === void 0) {
|
|
21510
23714
|
const mod = u.protocol === "https:" ? https : http;
|
|
21511
|
-
const req = mod.request({ host: conn.address, port, path:
|
|
23715
|
+
const req = mod.request({ host: conn.address, port, path: path5, signal, servername: tlsName(host), headers: { host: u.host } });
|
|
21512
23716
|
req.on("response", resolve5).on("error", onErr).end();
|
|
21513
23717
|
return;
|
|
21514
23718
|
}
|
|
@@ -21530,7 +23734,7 @@ function request(u, conn, proxy, signal) {
|
|
|
21530
23734
|
const req = https.request({
|
|
21531
23735
|
host,
|
|
21532
23736
|
port,
|
|
21533
|
-
path:
|
|
23737
|
+
path: path5,
|
|
21534
23738
|
signal,
|
|
21535
23739
|
headers: { host: u.host },
|
|
21536
23740
|
createConnection: () => tlsConnect({ socket, host, servername: tlsName(host) })
|
|
@@ -21702,12 +23906,12 @@ function reply2(text, isError) {
|
|
|
21702
23906
|
return { text, isError, sandboxBytes: 0 };
|
|
21703
23907
|
}
|
|
21704
23908
|
function scopesOf(input) {
|
|
21705
|
-
const
|
|
23909
|
+
const set3 = {
|
|
21706
23910
|
session: input.session !== void 0,
|
|
21707
23911
|
source: input.source !== void 0,
|
|
21708
23912
|
project: input.project === true
|
|
21709
23913
|
};
|
|
21710
|
-
return PURGE_SCOPES.filter((s) =>
|
|
23914
|
+
return PURGE_SCOPES.filter((s) => set3[s]);
|
|
21711
23915
|
}
|
|
21712
23916
|
function changes(raw, sql, ...args) {
|
|
21713
23917
|
return Number(raw.prepare(sql).run(...args).changes);
|
|
@@ -21777,8 +23981,8 @@ async function handler6(input, ctx) {
|
|
|
21777
23981
|
if (newest === void 0) return reply3(RESUME_EMPTY_LINE, false);
|
|
21778
23982
|
const sources = listSessionSources(db, sessionId, MAX_CANDIDATES).map((r) => "source " + sourceHandle(r.id) + ": " + r.label + " (" + r.bytes + " B)");
|
|
21779
23983
|
const goal = readFirstPrompt(db, sessionId);
|
|
21780
|
-
const
|
|
21781
|
-
const units = queryUnits(db, sessionId, recallQueryText(
|
|
23984
|
+
const last2 = readLastPrompt(db, sessionId);
|
|
23985
|
+
const units = queryUnits(db, sessionId, recallQueryText(last2, goal), RECALL_UNIT_CANDIDATES).map((u) => ({ ...u, label: sourceHandle(u.sourceId) }));
|
|
21782
23986
|
const block = renderState(rows, newest.turn, { sources, units });
|
|
21783
23987
|
if (Buffer.byteLength(block, "utf8") > RESUME_CAP) throw new Error("ctx_resume: state block over RESUME_CAP (render bug).");
|
|
21784
23988
|
return reply3(block, false);
|
|
@@ -21820,8 +24024,8 @@ function reductionPct(t) {
|
|
|
21820
24024
|
return Number((t.saved * PERCENT_SCALE / Math.max(1, t.produced)).toFixed(1));
|
|
21821
24025
|
}
|
|
21822
24026
|
function tableRow(label, t) {
|
|
21823
|
-
const
|
|
21824
|
-
return "| " + [label, t.produced + " B", t.returned + " B", t.saved + " B",
|
|
24027
|
+
const last2 = t.calls === 0 ? STATS_NO_DATA : String(reductionPct(t));
|
|
24028
|
+
return "| " + [label, t.produced + " B", t.returned + " B", t.saved + " B", last2].join(" | ") + " |";
|
|
21825
24029
|
}
|
|
21826
24030
|
async function handler7(_input, ctx) {
|
|
21827
24031
|
const db = await openDb(ctx.project, { readOnly: true });
|
|
@@ -21855,23 +24059,24 @@ var ctxStats = Object.freeze({
|
|
|
21855
24059
|
});
|
|
21856
24060
|
|
|
21857
24061
|
// src/core/tools/upgrade.ts
|
|
21858
|
-
import { existsSync as existsSync18, realpathSync as realpathSync7, rmSync as
|
|
24062
|
+
import { existsSync as existsSync18, realpathSync as realpathSync7, rmSync as rmSync9 } from "node:fs";
|
|
21859
24063
|
import { basename as basename5, dirname as dirname10, join as join21 } from "node:path";
|
|
21860
24064
|
|
|
21861
24065
|
// src/core/ops/host-write.ts
|
|
21862
|
-
import { copyFileSync, existsSync as existsSync13, mkdirSync as
|
|
24066
|
+
import { copyFileSync, existsSync as existsSync13, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
21863
24067
|
import { dirname as dirname9, join as join16 } from "node:path";
|
|
21864
24068
|
function defaultWrite(file2, text) {
|
|
21865
24069
|
writeFileSync4(file2, text, "utf8");
|
|
21866
24070
|
}
|
|
21867
24071
|
function hostConfigPath(agent, home, env) {
|
|
21868
24072
|
const own2 = OWN_MCP_ENTRY[agent];
|
|
21869
|
-
if (own2 !== void 0) return
|
|
24073
|
+
if (own2 !== void 0) return ownMcpFileOf(agent, own2.file, env, home);
|
|
21870
24074
|
switch (agent) {
|
|
21871
24075
|
case "opencode":
|
|
21872
|
-
return join16(
|
|
24076
|
+
return join16(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
|
|
24077
|
+
// D-WIN-OPENCODE-DIR-1
|
|
21873
24078
|
case "pi":
|
|
21874
|
-
return join16(env
|
|
24079
|
+
return join16(piAgentDirOf(env, home), SETTINGS_FILE);
|
|
21875
24080
|
case "copilot-cli":
|
|
21876
24081
|
return null;
|
|
21877
24082
|
default:
|
|
@@ -21884,22 +24089,32 @@ function cell2(value) {
|
|
|
21884
24089
|
function toRow(file2, edit) {
|
|
21885
24090
|
return { area: file2 + UPGRADE_AREA_KEY_SEP + edit.path, before: cell2(edit.before), after: cell2(edit.after) };
|
|
21886
24091
|
}
|
|
21887
|
-
function writeWithRollback(file2, text, write2) {
|
|
24092
|
+
function writeWithRollback(file2, text, write2, atomic) {
|
|
21888
24093
|
const trash = file2 + UPGRADE_TRASH_SUFFIX;
|
|
21889
|
-
const tmp = file2
|
|
24094
|
+
const tmp = `${file2}${HOST_CONFIG_TMP_SUFFIX}.${process.pid}`;
|
|
21890
24095
|
const had = existsSync13(file2);
|
|
21891
|
-
|
|
24096
|
+
mkdirSync5(dirname9(file2), { recursive: true });
|
|
21892
24097
|
if (had) copyFileSync(file2, trash);
|
|
21893
24098
|
try {
|
|
21894
24099
|
write2(tmp, text);
|
|
21895
|
-
|
|
24100
|
+
renameWithRetry(tmp, file2, atomic);
|
|
21896
24101
|
} catch (err) {
|
|
21897
|
-
|
|
21898
|
-
if (had)
|
|
21899
|
-
|
|
21900
|
-
|
|
24102
|
+
removeTmpFile(tmp, atomic);
|
|
24103
|
+
if (!had) {
|
|
24104
|
+
removeTmpFile(file2, atomic);
|
|
24105
|
+
throw replaceFailure(file2, err);
|
|
24106
|
+
}
|
|
24107
|
+
try {
|
|
24108
|
+
renameWithRetry(trash, file2, atomic);
|
|
24109
|
+
} catch (restoreErr) {
|
|
24110
|
+
throw new Error(`${replaceFailure(file2, err).message}. The original is kept at ${trash}`, { cause: restoreErr });
|
|
24111
|
+
}
|
|
24112
|
+
throw replaceFailure(file2, err);
|
|
24113
|
+
}
|
|
24114
|
+
try {
|
|
24115
|
+
unlinkWithRetry(trash, atomic);
|
|
24116
|
+
} catch {
|
|
21901
24117
|
}
|
|
21902
|
-
rmSync5(trash, { force: true });
|
|
21903
24118
|
}
|
|
21904
24119
|
function regenerateHostConfig(row5, home, opts = {}) {
|
|
21905
24120
|
const env = opts.env ?? process.env;
|
|
@@ -21910,29 +24125,31 @@ function regenerateHostConfig(row5, home, opts = {}) {
|
|
|
21910
24125
|
const exists = existsSync13(current.path);
|
|
21911
24126
|
if (exists && result.text === current.text) return [];
|
|
21912
24127
|
const text = result.text === "" && current.format !== "toml" ? JSON.stringify({}) : result.text;
|
|
21913
|
-
writeWithRollback(current.path, text, opts.write ?? defaultWrite);
|
|
24128
|
+
writeWithRollback(current.path, current.layout === void 0 ? text : withLayout(text, current.layout), opts.write ?? defaultWrite, opts.atomic ?? {});
|
|
21914
24129
|
return result.edits.map((e) => toRow(current.path, e));
|
|
21915
24130
|
}
|
|
21916
24131
|
|
|
21917
24132
|
// src/core/ops/plugin-swap.ts
|
|
21918
|
-
import { existsSync as existsSync14, lstatSync, readdirSync as readdirSync6, readlinkSync,
|
|
21919
|
-
import { basename as basename4, join as join17 } from "node:path";
|
|
21920
|
-
function linkTarget(
|
|
21921
|
-
|
|
24133
|
+
import { existsSync as existsSync14, lstatSync, readdirSync as readdirSync6, readlinkSync, rmSync as rmSync5, symlinkSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
24134
|
+
import { basename as basename4, join as join17, win32 as win322 } from "node:path";
|
|
24135
|
+
function linkTarget(path5, win) {
|
|
24136
|
+
if (!isLink(path5)) return null;
|
|
24137
|
+
const target = readlinkSync(path5);
|
|
24138
|
+
return win ? win322.basename(target) : target;
|
|
21922
24139
|
}
|
|
21923
|
-
function isLink(
|
|
21924
|
-
return lstatSync(
|
|
24140
|
+
function isLink(path5) {
|
|
24141
|
+
return lstatSync(path5, { throwIfNoEntry: false })?.isSymbolicLink() === true;
|
|
21925
24142
|
}
|
|
21926
24143
|
function generations(agentDir) {
|
|
21927
24144
|
return readdirSync6(agentDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(UPGRADE_FETCH_DIR_PREFIX) && !name.endsWith(UPGRADE_TRASH_SUFFIX)).sort();
|
|
21928
24145
|
}
|
|
21929
|
-
function settleLinks(link, tmp, old) {
|
|
21930
|
-
if (isLink(tmp))
|
|
24146
|
+
function settleLinks(link, tmp, old, opts) {
|
|
24147
|
+
if (isLink(tmp)) unlinkSync2(tmp);
|
|
21931
24148
|
if (!isLink(old)) return;
|
|
21932
|
-
if (isLink(link))
|
|
21933
|
-
else
|
|
24149
|
+
if (isLink(link)) unlinkSync2(old);
|
|
24150
|
+
else renameWithRetry(old, link, opts);
|
|
21934
24151
|
}
|
|
21935
|
-
function swapPluginCurrent(agentDir, sha) {
|
|
24152
|
+
function swapPluginCurrent(agentDir, sha, opts = {}) {
|
|
21936
24153
|
const next = join17(agentDir, sha);
|
|
21937
24154
|
if (!existsSync14(next) || !lstatSync(next).isDirectory()) {
|
|
21938
24155
|
throw new CtxError("PLUGIN_ROOT_MISSING", { agent: basename4(agentDir), path: next });
|
|
@@ -21940,23 +24157,26 @@ function swapPluginCurrent(agentDir, sha) {
|
|
|
21940
24157
|
const link = join17(agentDir, PLUGIN_CURRENT_LINK);
|
|
21941
24158
|
const tmp = link + PLUGIN_LINK_TMP_SUFFIX;
|
|
21942
24159
|
const old = link + PLUGIN_LINK_OLD_SUFFIX;
|
|
21943
|
-
settleLinks(link, tmp, old);
|
|
21944
|
-
const
|
|
24160
|
+
settleLinks(link, tmp, old, opts);
|
|
24161
|
+
const win = (opts.platform ?? process.platform) === "win32";
|
|
24162
|
+
const before = linkTarget(link, win);
|
|
21945
24163
|
if (before === sha) return { current: next, previous: null, removed: [] };
|
|
21946
|
-
|
|
21947
|
-
if (
|
|
21948
|
-
|
|
21949
|
-
if (before !== null)
|
|
24164
|
+
const symlink = opts.symlink ?? symlinkSync;
|
|
24165
|
+
if (win) symlink(next, tmp, PLUGIN_LINK_TYPE_WIN32);
|
|
24166
|
+
else symlink(sha, tmp, PLUGIN_LINK_TYPE);
|
|
24167
|
+
if (before !== null) renameWithRetry(link, old, opts);
|
|
24168
|
+
renameWithRetry(tmp, link, opts);
|
|
24169
|
+
if (before !== null) unlinkSync2(old);
|
|
21950
24170
|
const keep = /* @__PURE__ */ new Set([sha]);
|
|
21951
24171
|
if (before !== null) keep.add(before);
|
|
21952
24172
|
const removed = generations(agentDir).filter((name) => !keep.has(name)).map((name) => join17(agentDir, name));
|
|
21953
|
-
for (const dir of removed)
|
|
24173
|
+
for (const dir of removed) rmSync5(dir, { recursive: true, force: true });
|
|
21954
24174
|
const previous = before !== null && existsSync14(join17(agentDir, before)) ? join17(agentDir, before) : null;
|
|
21955
24175
|
return { current: next, previous, removed };
|
|
21956
24176
|
}
|
|
21957
24177
|
|
|
21958
24178
|
// src/core/ops/release-fetch.ts
|
|
21959
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
24179
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, rmSync as rmSync6 } from "node:fs";
|
|
21960
24180
|
import { join as join18 } from "node:path";
|
|
21961
24181
|
function failed(r) {
|
|
21962
24182
|
if (r.exitCode === null && r.killed === null) return new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
|
|
@@ -21968,11 +24188,11 @@ async function git2(bin, args, cwd, env, signal) {
|
|
|
21968
24188
|
if (r.exitCode !== 0 || r.killed !== null) throw failed(r);
|
|
21969
24189
|
return r.stdout.toString().trim();
|
|
21970
24190
|
}
|
|
21971
|
-
async function fetchRelease(agent, url2, env, signal) {
|
|
24191
|
+
async function fetchRelease(agent, url2, env, signal, opts = {}) {
|
|
21972
24192
|
const agentDir = join18(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, agent);
|
|
21973
|
-
|
|
24193
|
+
mkdirSync6(agentDir, { recursive: true });
|
|
21974
24194
|
const fetchDir = join18(agentDir, UPGRADE_FETCH_DIR_PREFIX + process.pid);
|
|
21975
|
-
|
|
24195
|
+
rmSync6(fetchDir, { recursive: true, force: true });
|
|
21976
24196
|
const gitBin = findRuntime(GIT_BIN, env);
|
|
21977
24197
|
if (gitBin === null) throw new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
|
|
21978
24198
|
const childEnv = buildChildEnv(env, { ...GIT_NO_PROMPT_ENV, ...GIT_NO_CRLF_ENV });
|
|
@@ -21980,26 +24200,21 @@ async function fetchRelease(agent, url2, env, signal) {
|
|
|
21980
24200
|
await git2(gitBin, [...GIT_CLONE_ARGS, RELEASE_BRANCH, url2, fetchDir], agentDir, childEnv, signal);
|
|
21981
24201
|
const sha = await git2(gitBin, GIT_HEAD_SHA_ARGS, fetchDir, childEnv, signal);
|
|
21982
24202
|
const dir = join18(agentDir, sha);
|
|
21983
|
-
if (existsSync15(dir))
|
|
21984
|
-
else
|
|
24203
|
+
if (existsSync15(dir)) rmSync6(fetchDir, { recursive: true, force: true });
|
|
24204
|
+
else renameWithRetry(fetchDir, dir, opts);
|
|
21985
24205
|
return { sha, dir };
|
|
21986
24206
|
} catch (e) {
|
|
21987
|
-
|
|
24207
|
+
rmSync6(fetchDir, { recursive: true, force: true });
|
|
21988
24208
|
throw e;
|
|
21989
24209
|
}
|
|
21990
24210
|
}
|
|
21991
24211
|
|
|
21992
24212
|
// src/core/ops/uninstall.ts
|
|
21993
|
-
import { existsSync as existsSync16, readdirSync as readdirSync7, rmSync as
|
|
24213
|
+
import { existsSync as existsSync16, readdirSync as readdirSync7, rmSync as rmSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
21994
24214
|
import { join as join19 } from "node:path";
|
|
21995
24215
|
function row2(area, before, after) {
|
|
21996
24216
|
return { area, before, after };
|
|
21997
24217
|
}
|
|
21998
|
-
function homeOf3(env) {
|
|
21999
|
-
const home = homeDirOf(env);
|
|
22000
|
-
if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
|
|
22001
|
-
return home;
|
|
22002
|
-
}
|
|
22003
24218
|
function stopServers(configDir, projectKey) {
|
|
22004
24219
|
const stopped = listLiveOwners(configDir, projectKey);
|
|
22005
24220
|
const dir = join19(configDir, PROJECTS_DIR_NAME, projectKey, OWNERS_DIR_NAME);
|
|
@@ -22020,13 +24235,13 @@ function removeCache(adapter, env, configDir) {
|
|
|
22020
24235
|
case "extension": {
|
|
22021
24236
|
const root = rootOrNull(adapter, env);
|
|
22022
24237
|
if (root === null) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
|
|
22023
|
-
|
|
24238
|
+
rmSync7(root, { recursive: true, force: true });
|
|
22024
24239
|
return row2(UPGRADE_CACHE_AREA, root, UPGRADE_REMOVED);
|
|
22025
24240
|
}
|
|
22026
24241
|
case "plugin": {
|
|
22027
24242
|
const agentDir = join19(configDir, DATA_PLUGINS_DIR_NAME, adapter.id);
|
|
22028
24243
|
if (!existsSync16(agentDir)) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
|
|
22029
|
-
|
|
24244
|
+
rmSync7(agentDir, { recursive: true, force: true });
|
|
22030
24245
|
return row2(UPGRADE_CACHE_AREA, agentDir, UPGRADE_REMOVED);
|
|
22031
24246
|
}
|
|
22032
24247
|
case "config-mcp":
|
|
@@ -22045,20 +24260,20 @@ function piSource(entry) {
|
|
|
22045
24260
|
return isObj2(entry) ? entry[PI_PACKAGE_SOURCE_KEY] : entry;
|
|
22046
24261
|
}
|
|
22047
24262
|
function ownEntries(agent, env) {
|
|
22048
|
-
const home =
|
|
24263
|
+
const home = requireHomeDir(env);
|
|
22049
24264
|
const mcp = OWN_MCP_ENTRY[agent];
|
|
22050
24265
|
if (mcp !== void 0) {
|
|
22051
24266
|
const top = mcp.key[0];
|
|
22052
24267
|
const inner = mcp.key.slice(1, -1);
|
|
22053
24268
|
const own2 = mcp.key[mcp.key.length - 1];
|
|
22054
24269
|
const holder = (v) => inner.reduce((cur, k) => isObj2(cur) ? cur[k] : void 0, v);
|
|
22055
|
-
const without = (v,
|
|
24270
|
+
const without = (v, path5) => {
|
|
22056
24271
|
const o = v;
|
|
22057
|
-
if (
|
|
22058
|
-
return { ...o, [
|
|
24272
|
+
if (path5.length === 0) return Object.fromEntries(Object.entries(o).filter(([k]) => k !== own2));
|
|
24273
|
+
return { ...o, [path5[0]]: without(o[path5[0]], path5.slice(1)) };
|
|
22059
24274
|
};
|
|
22060
24275
|
return [{
|
|
22061
|
-
file:
|
|
24276
|
+
file: ownMcpFileOf(agent, mcp.file, env, home),
|
|
22062
24277
|
key: top,
|
|
22063
24278
|
shown: mcp.key.join(V1_KEY_PATH_SEP),
|
|
22064
24279
|
has: (v) => {
|
|
@@ -22070,7 +24285,8 @@ function ownEntries(agent, env) {
|
|
|
22070
24285
|
}
|
|
22071
24286
|
if (agent === "opencode") {
|
|
22072
24287
|
return [{
|
|
22073
|
-
file: join19(
|
|
24288
|
+
file: join19(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE),
|
|
24289
|
+
// D-WIN-OPENCODE-DIR-1
|
|
22074
24290
|
key: OPENCODE_PLUGIN_KEY,
|
|
22075
24291
|
shown: OPENCODE_PLUGIN_KEY,
|
|
22076
24292
|
has: (v) => Array.isArray(v) && v.includes(OPENCODE_GIT_SPEC),
|
|
@@ -22078,7 +24294,7 @@ function ownEntries(agent, env) {
|
|
|
22078
24294
|
}];
|
|
22079
24295
|
}
|
|
22080
24296
|
if (agent === "pi") {
|
|
22081
|
-
const agentDir = env
|
|
24297
|
+
const agentDir = piAgentDirOf(env, home);
|
|
22082
24298
|
return [{
|
|
22083
24299
|
file: join19(agentDir, SETTINGS_FILE),
|
|
22084
24300
|
key: PI_PACKAGES_KEY,
|
|
@@ -22107,7 +24323,7 @@ function removeProjectData(configDir, projectKey) {
|
|
|
22107
24323
|
if (!existsSync16(dir)) return row2(UPGRADE_DATA_AREA, "", UPGRADE_NOT_FOUND);
|
|
22108
24324
|
if (dir === projects || !isInside(projects, dir)) throw new CtxError("OUTSIDE_ROOT", { p: dir, root: projects });
|
|
22109
24325
|
for (const name of readdirSync7(dir)) {
|
|
22110
|
-
if (name !== OWNERS_DIR_NAME)
|
|
24326
|
+
if (name !== OWNERS_DIR_NAME) rmSync7(join19(dir, name), { recursive: true, force: true });
|
|
22111
24327
|
}
|
|
22112
24328
|
return row2(UPGRADE_DATA_AREA, dir, UPGRADE_DATA_DELETED);
|
|
22113
24329
|
}
|
|
@@ -22120,52 +24336,52 @@ function runUninstall(input) {
|
|
|
22120
24336
|
}
|
|
22121
24337
|
|
|
22122
24338
|
// src/core/ops/v1-remove.ts
|
|
22123
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync17, readFileSync as readFileSync13,
|
|
24339
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync17, readFileSync as readFileSync13, rmSync as rmSync8 } from "node:fs";
|
|
22124
24340
|
var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
22125
24341
|
var areaOf = (f) => f.path === "" ? f.file : f.file + UPGRADE_AREA_KEY_SEP + f.path;
|
|
22126
24342
|
var row3 = (f, after) => ({ area: areaOf(f), before: f.reason, after });
|
|
22127
24343
|
function moveAside(target, undo) {
|
|
22128
24344
|
const trash = target + UPGRADE_TRASH_SUFFIX;
|
|
22129
|
-
|
|
22130
|
-
|
|
24345
|
+
rmSync8(trash, { recursive: true, force: true });
|
|
24346
|
+
renameWithRetry(target, trash);
|
|
22131
24347
|
undo.push({ trash, target });
|
|
22132
24348
|
}
|
|
22133
24349
|
function keepOriginal(file2, kept, undo) {
|
|
22134
24350
|
if (kept.has(file2)) return;
|
|
22135
24351
|
const trash = file2 + UPGRADE_TRASH_SUFFIX;
|
|
22136
|
-
|
|
24352
|
+
rmSync8(trash, { recursive: true, force: true });
|
|
22137
24353
|
copyFileSync2(file2, trash);
|
|
22138
24354
|
kept.add(file2);
|
|
22139
24355
|
undo.push({ trash, target: file2 });
|
|
22140
24356
|
}
|
|
22141
24357
|
function cutTomlTable(text, header) {
|
|
22142
|
-
|
|
22143
|
-
|
|
22144
|
-
|
|
22145
|
-
|
|
22146
|
-
|
|
22147
|
-
|
|
24358
|
+
let span;
|
|
24359
|
+
try {
|
|
24360
|
+
span = tomlTableSpans(text).find((t) => t.header.trim() === header);
|
|
24361
|
+
} catch {
|
|
24362
|
+
return null;
|
|
24363
|
+
}
|
|
24364
|
+
return span === void 0 ? null : text.slice(0, span.start) + text.slice(span.end);
|
|
22148
24365
|
}
|
|
22149
24366
|
function writeAtomic(file2, text) {
|
|
22150
|
-
|
|
22151
|
-
writeFileSync6(tmp, text, "utf8");
|
|
22152
|
-
renameSync6(tmp, file2);
|
|
24367
|
+
atomicWriteFile(file2, text);
|
|
22153
24368
|
}
|
|
22154
|
-
function locate(doc,
|
|
22155
|
-
const segs =
|
|
24369
|
+
function locate(doc, path5) {
|
|
24370
|
+
const segs = path5.split(V1_KEY_PATH_SEP);
|
|
22156
24371
|
let cur = doc;
|
|
22157
24372
|
for (const seg of segs.slice(0, -1)) {
|
|
22158
24373
|
if (Array.isArray(cur)) cur = cur[Number(seg)];
|
|
22159
24374
|
else if (isObj3(cur)) cur = cur[seg];
|
|
22160
24375
|
else return null;
|
|
22161
24376
|
}
|
|
22162
|
-
const
|
|
22163
|
-
if (Array.isArray(cur)) return Number(
|
|
22164
|
-
if (isObj3(cur)) return Object.hasOwn(cur,
|
|
24377
|
+
const last2 = segs[segs.length - 1];
|
|
24378
|
+
if (Array.isArray(cur)) return Number(last2) < cur.length ? [cur, last2] : null;
|
|
24379
|
+
if (isObj3(cur)) return Object.hasOwn(cur, last2) ? [cur, last2] : null;
|
|
22165
24380
|
return null;
|
|
22166
24381
|
}
|
|
22167
24382
|
function stripJsonEntries(agent, file2, findings, kept, undo) {
|
|
22168
|
-
const
|
|
24383
|
+
const layout = hostLayout(readFileSync13(file2, "utf8"));
|
|
24384
|
+
const text = hostText(readFileSync13(file2, "utf8"));
|
|
22169
24385
|
const doc = parseHostConfig(agent, file2, text, "jsonc");
|
|
22170
24386
|
const hit = /* @__PURE__ */ new Set();
|
|
22171
24387
|
const byContainer = /* @__PURE__ */ new Map();
|
|
@@ -22190,7 +24406,7 @@ function stripJsonEntries(agent, file2, findings, kept, undo) {
|
|
|
22190
24406
|
const patch = {};
|
|
22191
24407
|
for (const k of topKeys) patch[k] = doc[k];
|
|
22192
24408
|
keepOriginal(file2, kept, undo);
|
|
22193
|
-
writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2 }, patch);
|
|
24409
|
+
writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2, layout }, patch);
|
|
22194
24410
|
return hit;
|
|
22195
24411
|
}
|
|
22196
24412
|
function removeV1(agent, findings) {
|
|
@@ -22213,7 +24429,9 @@ function removeV1(agent, findings) {
|
|
|
22213
24429
|
continue;
|
|
22214
24430
|
}
|
|
22215
24431
|
if (file2.endsWith(TOML_EXT)) {
|
|
22216
|
-
|
|
24432
|
+
const rawToml = readFileSync13(file2, "utf8");
|
|
24433
|
+
const tomlLayout = hostLayout(rawToml);
|
|
24434
|
+
let text = hostText(rawToml);
|
|
22217
24435
|
for (const f of list3) {
|
|
22218
24436
|
const next = cutTomlTable(text, f.path);
|
|
22219
24437
|
if (next === null) {
|
|
@@ -22225,7 +24443,7 @@ function removeV1(agent, findings) {
|
|
|
22225
24443
|
}
|
|
22226
24444
|
if (list3.some((f) => done.get(f) === UPGRADE_REMOVED)) {
|
|
22227
24445
|
keepOriginal(file2, kept, undo);
|
|
22228
|
-
writeAtomic(file2, text);
|
|
24446
|
+
writeAtomic(file2, withLayout(text, tomlLayout));
|
|
22229
24447
|
}
|
|
22230
24448
|
continue;
|
|
22231
24449
|
}
|
|
@@ -22235,13 +24453,13 @@ function removeV1(agent, findings) {
|
|
|
22235
24453
|
return {
|
|
22236
24454
|
rows: findings.map((f) => row3(f, done.get(f) ?? UPGRADE_NOT_FOUND)),
|
|
22237
24455
|
commit() {
|
|
22238
|
-
for (const u of undo.splice(0))
|
|
24456
|
+
for (const u of undo.splice(0)) rmSync8(u.trash, { recursive: true, force: true });
|
|
22239
24457
|
},
|
|
22240
24458
|
rollback() {
|
|
22241
24459
|
for (const u of undo.splice(0).reverse()) {
|
|
22242
24460
|
if (!existsSync17(u.trash)) continue;
|
|
22243
|
-
|
|
22244
|
-
|
|
24461
|
+
rmSync8(u.target, { recursive: true, force: true });
|
|
24462
|
+
renameWithRetry(u.trash, u.target);
|
|
22245
24463
|
}
|
|
22246
24464
|
}
|
|
22247
24465
|
};
|
|
@@ -22301,11 +24519,6 @@ var ctxUpgradeSchema = external_exports.object({
|
|
|
22301
24519
|
function row4(area, before, after) {
|
|
22302
24520
|
return { area, before, after };
|
|
22303
24521
|
}
|
|
22304
|
-
function homeOf4(env) {
|
|
22305
|
-
const home = homeDirOf(env);
|
|
22306
|
-
if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
|
|
22307
|
-
return home;
|
|
22308
|
-
}
|
|
22309
24522
|
function bundleDir() {
|
|
22310
24523
|
return dirname10(process.argv[1] ?? "");
|
|
22311
24524
|
}
|
|
@@ -22330,7 +24543,7 @@ async function checkout(adapter, deps) {
|
|
|
22330
24543
|
try {
|
|
22331
24544
|
verifySums(fetched.dir);
|
|
22332
24545
|
} catch (err) {
|
|
22333
|
-
if (!isCurrent(agentDir, fetched.dir))
|
|
24546
|
+
if (!isCurrent(agentDir, fetched.dir)) rmSync9(fetched.dir, { recursive: true, force: true });
|
|
22334
24547
|
throw err;
|
|
22335
24548
|
}
|
|
22336
24549
|
const swap = swapPluginCurrent(agentDir, fetched.sha);
|
|
@@ -22347,7 +24560,7 @@ async function upgrade(adapter, deps, home) {
|
|
|
22347
24560
|
try {
|
|
22348
24561
|
const step4 = UPGRADE_GIT_CHECKOUT_AGENTS.includes(adapter.id) ? (done = await checkout(adapter, deps)).rows : [hostRow(adapter)];
|
|
22349
24562
|
const step5 = regenerateHostConfig(adapter, home, { env: deps.env, write: deps.write });
|
|
22350
|
-
const findings = detectV1(adapter.id, home, { project: deps.project.worktree, piAgentDir: deps.env
|
|
24563
|
+
const findings = detectV1(adapter.id, home, { project: deps.project.worktree, piAgentDir: piAgentDirOf(deps.env, home), claudeDir: claudeDirOf(deps.env, home), copilotDir: copilotDirOf(deps.env, home), kiroDir: kiroDirOf(deps.env, home), opencodeDir: opencodeDirOf(deps.env, home) });
|
|
22351
24564
|
removal = removeV1(adapter.id, findings);
|
|
22352
24565
|
const rows = [...step4, ...step5, ...removal.rows];
|
|
22353
24566
|
removal.commit();
|
|
@@ -22368,7 +24581,7 @@ function renderTable(rows) {
|
|
|
22368
24581
|
}
|
|
22369
24582
|
async function runUpgrade(input, deps) {
|
|
22370
24583
|
const adapter = getAdapter(deps.project.agent);
|
|
22371
|
-
const home =
|
|
24584
|
+
const home = requireHomeDir(deps.env);
|
|
22372
24585
|
const rows = pluginRootRow(adapter, deps.env);
|
|
22373
24586
|
if ((input.mode ?? UPGRADE_DEFAULT_MODE) === "uninstall") {
|
|
22374
24587
|
const result = runUninstall({ adapter, project: deps.project, env: deps.env, confirmDelete: input.confirmDelete === true });
|