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