context-mode 2.0.0-next.7 → 2.0.0-next.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/server.mjs CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/entries/server.ts
8
8
  import { randomUUID } from "node:crypto";
9
- import { existsSync as existsSync20, rmSync as rmSync12 } from "node:fs";
9
+ import { existsSync as existsSync20, rmSync as rmSync11 } from "node:fs";
10
10
  import { join as join20 } from "node:path";
11
11
 
12
12
  // node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
@@ -303,10 +303,10 @@ function mergeDefs(...defs) {
303
303
  function cloneDef(schema) {
304
304
  return mergeDefs(schema._zod.def);
305
305
  }
306
- function getElementAtPath(obj, path4) {
307
- if (!path4)
306
+ function getElementAtPath(obj, path5) {
307
+ if (!path5)
308
308
  return obj;
309
- return path4.reduce((acc, key) => acc?.[key], obj);
309
+ return path5.reduce((acc, key) => acc?.[key], obj);
310
310
  }
311
311
  function promiseAllObject(promisesObj) {
312
312
  const keys = Object.keys(promisesObj);
@@ -646,11 +646,11 @@ function explicitlyAborted(x, startIndex = 0) {
646
646
  }
647
647
  return false;
648
648
  }
649
- function prefixIssues(path4, issues) {
649
+ function prefixIssues(path5, issues) {
650
650
  return issues.map((iss) => {
651
651
  var _a5;
652
652
  (_a5 = iss).path ?? (_a5.path = []);
653
- iss.path.unshift(path4);
653
+ iss.path.unshift(path5);
654
654
  return iss;
655
655
  });
656
656
  }
@@ -1111,16 +1111,16 @@ function flattenError(error42, mapper = (issue4) => issue4.message) {
1111
1111
  }
1112
1112
  function formatError(error42, mapper = (issue4) => issue4.message) {
1113
1113
  const fieldErrors = { _errors: [] };
1114
- const processError = (error43, path4 = []) => {
1114
+ const processError = (error43, path5 = []) => {
1115
1115
  for (const issue4 of error43.issues) {
1116
1116
  if (issue4.code === "invalid_union" && issue4.errors.length) {
1117
- issue4.errors.map((issues) => processError({ issues }, [...path4, ...issue4.path]));
1117
+ issue4.errors.map((issues) => processError({ issues }, [...path5, ...issue4.path]));
1118
1118
  } else if (issue4.code === "invalid_key") {
1119
- processError({ issues: issue4.issues }, [...path4, ...issue4.path]);
1119
+ processError({ issues: issue4.issues }, [...path5, ...issue4.path]);
1120
1120
  } else if (issue4.code === "invalid_element") {
1121
- processError({ issues: issue4.issues }, [...path4, ...issue4.path]);
1121
+ processError({ issues: issue4.issues }, [...path5, ...issue4.path]);
1122
1122
  } else {
1123
- const fullpath = [...path4, ...issue4.path];
1123
+ const fullpath = [...path5, ...issue4.path];
1124
1124
  if (fullpath.length === 0) {
1125
1125
  fieldErrors._errors.push(mapper(issue4));
1126
1126
  } else {
@@ -2340,8 +2340,8 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
2340
2340
  }
2341
2341
  const input = payload.value;
2342
2342
  const isDate = input instanceof Date;
2343
- const isValidDate = isDate && !Number.isNaN(input.getTime());
2344
- if (isValidDate)
2343
+ const isValidDate2 = isDate && !Number.isNaN(input.getTime());
2344
+ if (isValidDate2)
2345
2345
  return payload;
2346
2346
  payload.issues.push({
2347
2347
  expected: "date",
@@ -7884,10 +7884,10 @@ function mergeDefs2(...defs) {
7884
7884
  function cloneDef2(schema) {
7885
7885
  return mergeDefs2(schema._zod.def);
7886
7886
  }
7887
- function getElementAtPath2(obj, path4) {
7888
- if (!path4)
7887
+ function getElementAtPath2(obj, path5) {
7888
+ if (!path5)
7889
7889
  return obj;
7890
- return path4.reduce((acc, key) => acc?.[key], obj);
7890
+ return path5.reduce((acc, key) => acc?.[key], obj);
7891
7891
  }
7892
7892
  function promiseAllObject2(promisesObj) {
7893
7893
  const keys = Object.keys(promisesObj);
@@ -8227,11 +8227,11 @@ function explicitlyAborted2(x, startIndex = 0) {
8227
8227
  }
8228
8228
  return false;
8229
8229
  }
8230
- function prefixIssues2(path4, issues) {
8230
+ function prefixIssues2(path5, issues) {
8231
8231
  return issues.map((iss) => {
8232
8232
  var _a5;
8233
8233
  (_a5 = iss).path ?? (_a5.path = []);
8234
- iss.path.unshift(path4);
8234
+ iss.path.unshift(path5);
8235
8235
  return iss;
8236
8236
  });
8237
8237
  }
@@ -8689,16 +8689,16 @@ function flattenError2(error42, mapper = (issue4) => issue4.message) {
8689
8689
  }
8690
8690
  function formatError2(error42, mapper = (issue4) => issue4.message) {
8691
8691
  const fieldErrors = { _errors: [] };
8692
- const processError = (error43, path4 = []) => {
8692
+ const processError = (error43, path5 = []) => {
8693
8693
  for (const issue4 of error43.issues) {
8694
8694
  if (issue4.code === "invalid_union" && issue4.errors.length) {
8695
- issue4.errors.map((issues) => processError({ issues }, [...path4, ...issue4.path]));
8695
+ issue4.errors.map((issues) => processError({ issues }, [...path5, ...issue4.path]));
8696
8696
  } else if (issue4.code === "invalid_key") {
8697
- processError({ issues: issue4.issues }, [...path4, ...issue4.path]);
8697
+ processError({ issues: issue4.issues }, [...path5, ...issue4.path]);
8698
8698
  } else if (issue4.code === "invalid_element") {
8699
- processError({ issues: issue4.issues }, [...path4, ...issue4.path]);
8699
+ processError({ issues: issue4.issues }, [...path5, ...issue4.path]);
8700
8700
  } else {
8701
- const fullpath = [...path4, ...issue4.path];
8701
+ const fullpath = [...path5, ...issue4.path];
8702
8702
  if (fullpath.length === 0) {
8703
8703
  fieldErrors._errors.push(mapper(issue4));
8704
8704
  } else {
@@ -16914,9 +16914,9 @@ var rev2026Codec = {
16914
16914
  });
16915
16915
  const parsed = buildSchemas2026().RequestMetaEnvelopeSchema.safeParse(meta3);
16916
16916
  if (!parsed.success) for (const issue4 of parsed.error.issues) {
16917
- const path4 = issue4.path.map(String);
16918
- const key = path4.length > 0 ? path4.join(".") : "_meta";
16919
- if (path4.length === 1 && issues.some((existing) => existing.key === key && existing.problem === "missing")) continue;
16917
+ const path5 = issue4.path.map(String);
16918
+ const key = path5.length > 0 ? path5.join(".") : "_meta";
16919
+ if (path5.length === 1 && issues.some((existing) => existing.key === key && existing.problem === "missing")) continue;
16920
16920
  issues.push({
16921
16921
  key,
16922
16922
  problem: issue4.message
@@ -17243,29 +17243,29 @@ var PERMITTED_X_MCP_HEADER_TYPES = /* @__PURE__ */ new Set([
17243
17243
  function scanXMcpHeaderDeclarations(inputSchema) {
17244
17244
  const declarations = [];
17245
17245
  const seenLower = /* @__PURE__ */ new Map();
17246
- const visit2 = (node3, path4, reachable) => {
17246
+ const visit2 = (node3, path5, reachable) => {
17247
17247
  if (node3 === null || typeof node3 !== "object") return void 0;
17248
17248
  const schema = node3;
17249
17249
  if (X_MCP_HEADER_KEY in schema) {
17250
- if (!reachable || path4.length === 0) return `${pathName(path4)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;
17250
+ if (!reachable || path5.length === 0) return `${pathName(path5)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;
17251
17251
  const raw = schema[X_MCP_HEADER_KEY];
17252
- if (typeof raw !== "string" || raw.length === 0) return `${pathName(path4)}: x-mcp-header MUST be a non-empty string`;
17253
- if (!RFC9110_TOKEN.test(raw)) return `${pathName(path4)}: x-mcp-header '${raw}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;
17252
+ if (typeof raw !== "string" || raw.length === 0) return `${pathName(path5)}: x-mcp-header MUST be a non-empty string`;
17253
+ if (!RFC9110_TOKEN.test(raw)) return `${pathName(path5)}: x-mcp-header '${raw}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;
17254
17254
  const type = typeof schema.type === "string" ? schema.type : void 0;
17255
- if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(path4)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${type ?? "<none>"}`;
17255
+ if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(path5)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${type ?? "<none>"}`;
17256
17256
  const lower = raw.toLowerCase();
17257
17257
  const prior = seenLower.get(lower);
17258
17258
  if (prior !== void 0) return `x-mcp-header '${raw}' is not case-insensitively unique (also declared as '${prior}')`;
17259
17259
  seenLower.set(lower, raw);
17260
17260
  declarations.push({
17261
- path: path4,
17261
+ path: path5,
17262
17262
  headerName: raw,
17263
17263
  type
17264
17264
  });
17265
17265
  }
17266
17266
  const properties = schema.properties;
17267
17267
  if (properties !== null && typeof properties === "object") for (const [key, child] of Object.entries(properties)) {
17268
- const fault$1 = visit2(child, [...path4, key], reachable);
17268
+ const fault$1 = visit2(child, [...path5, key], reachable);
17269
17269
  if (fault$1 !== void 0) return fault$1;
17270
17270
  }
17271
17271
  for (const k of NON_REACHABLE_SUBSCHEMA_KEYWORDS) {
@@ -17273,7 +17273,7 @@ function scanXMcpHeaderDeclarations(inputSchema) {
17273
17273
  if (sub === void 0) continue;
17274
17274
  const branches = Array.isArray(sub) ? sub : sub !== null && typeof sub === "object" && OBJECT_VALUED_SUBSCHEMA_KEYWORDS.has(k) ? Object.values(sub) : [sub];
17275
17275
  for (const branch of branches) {
17276
- const fault$1 = visit2(branch, [...path4, `<${k}>`], false);
17276
+ const fault$1 = visit2(branch, [...path5, `<${k}>`], false);
17277
17277
  if (fault$1 !== void 0) return fault$1;
17278
17278
  }
17279
17279
  }
@@ -17313,8 +17313,8 @@ var OBJECT_VALUED_SUBSCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
17313
17313
  "$defs",
17314
17314
  "definitions"
17315
17315
  ]);
17316
- function pathName(path4) {
17317
- return path4.length === 0 ? "<root>" : path4.join(".");
17316
+ function pathName(path5) {
17317
+ return path5.length === 0 ? "<root>" : path5.join(".");
17318
17318
  }
17319
17319
  var HEADER_MISMATCH_ERROR_CODE = -32020;
17320
17320
  var INBOUND_VALIDATION_LADDER = [
@@ -17603,7 +17603,7 @@ var PROPERTY_KEYS_BY_TYPE = {
17603
17603
  array: shapeKeys([UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema])
17604
17604
  };
17605
17605
  var SUPPORTED_STRING_FORMATS = new Set(StringSchemaSchema.shape.format.unwrap().options);
17606
- function walkProperty(node3, path4, vendor, unsupported) {
17606
+ function walkProperty(node3, path5, vendor, unsupported) {
17607
17607
  if (!isJsonObject(node3)) return node3;
17608
17608
  const allowedKeys = typeof node3.type === "string" && Object.hasOwn(PROPERTY_KEYS_BY_TYPE, node3.type) ? PROPERTY_KEYS_BY_TYPE[node3.type] : void 0;
17609
17609
  if (allowedKeys === void 0) return node3;
@@ -17611,8 +17611,8 @@ function walkProperty(node3, path4, vendor, unsupported) {
17611
17611
  for (const [key, value] of Object.entries(node3)) if (allowedKeys.has(key) || isAnnotationOnlyJsonSchemaKeyword(key)) pruned[key] = value;
17612
17612
  else if (key === "pattern" && node3.type === "string" && typeof node3.format === "string") {
17613
17613
  if (!SUPPORTED_STRING_FORMATS.has(node3.format)) pruned[key] = value;
17614
- else if (typeof value !== "string" || !isLibraryFormatPattern(node3.format, value, vendor)) unsupported.push(`${path4}.${key}`);
17615
- } else unsupported.push(`${path4}.${key}`);
17614
+ else if (typeof value !== "string" || !isLibraryFormatPattern(node3.format, value, vendor)) unsupported.push(`${path5}.${key}`);
17615
+ } else unsupported.push(`${path5}.${key}`);
17616
17616
  return pruned;
17617
17617
  }
17618
17618
  function walkRequestedSchema(converted, vendor) {
@@ -17629,11 +17629,11 @@ function describeUnsupportedProperties(pruned, fallback) {
17629
17629
  const offenders = Object.entries(pruned.properties).filter(([, node3]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node3).success).map(([name]) => `properties.${name}`);
17630
17630
  return offenders.length > 0 ? offenders.join(", ") : fallback;
17631
17631
  }
17632
- function findDroppedConstraintPaths(original, parsed, path4 = "") {
17633
- if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${path4}[${index}]`));
17632
+ function findDroppedConstraintPaths(original, parsed, path5 = "") {
17633
+ if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${path5}[${index}]`));
17634
17634
  if (!isJsonObject(original) || !isJsonObject(parsed)) return [];
17635
17635
  return Object.entries(original).flatMap(([key, value]) => {
17636
- const childPath = path4 ? `${path4}.${key}` : key;
17636
+ const childPath = path5 ? `${path5}.${key}` : key;
17637
17637
  if (!Object.prototype.hasOwnProperty.call(parsed, key)) return isAnnotationOnlyJsonSchemaKeyword(key) ? [] : [childPath];
17638
17638
  return findDroppedConstraintPaths(value, parsed[key], childPath);
17639
17639
  });
@@ -20002,8 +20002,8 @@ var require_util = /* @__PURE__ */ __commonJSMin((exports) => {
20002
20002
  })(Type || (exports.Type = Type = {}));
20003
20003
  function getErrorPath(dataProp, dataPropType, jsPropertySyntax) {
20004
20004
  if (dataProp instanceof codegen_1.Name) {
20005
- const isNumber = dataPropType === Type.Num;
20006
- return jsPropertySyntax ? isNumber ? (0, codegen_1._)`"[" + ${dataProp} + "]"` : (0, codegen_1._)`"['" + ${dataProp} + "']"` : isNumber ? (0, codegen_1._)`"/" + ${dataProp}` : (0, codegen_1._)`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")`;
20005
+ const isNumber2 = dataPropType === Type.Num;
20006
+ return jsPropertySyntax ? isNumber2 ? (0, codegen_1._)`"[" + ${dataProp} + "]"` : (0, codegen_1._)`"['" + ${dataProp} + "']"` : isNumber2 ? (0, codegen_1._)`"/" + ${dataProp}` : (0, codegen_1._)`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")`;
20007
20007
  }
20008
20008
  return jsPropertySyntax ? (0, codegen_1.getProperty)(dataProp).toString() : "/" + escapeJsonPointer(dataProp);
20009
20009
  }
@@ -21721,8 +21721,8 @@ var require_utils = /* @__PURE__ */ __commonJSMin((exports, module) => {
21721
21721
  for (let i = 0; i < str.length; i++) if (str[i] === token) ind++;
21722
21722
  return ind;
21723
21723
  }
21724
- function removeDotSegments(path4) {
21725
- let input = path4;
21724
+ function removeDotSegments(path5) {
21725
+ let input = path5;
21726
21726
  const output = [];
21727
21727
  let nextSlash = -1;
21728
21728
  let len = 0;
@@ -21875,8 +21875,8 @@ var require_schemes = /* @__PURE__ */ __commonJSMin((exports, module) => {
21875
21875
  wsComponent.secure = void 0;
21876
21876
  }
21877
21877
  if (wsComponent.resourceName) {
21878
- const [path4, query] = wsComponent.resourceName.split("?");
21879
- wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
21878
+ const [path5, query] = wsComponent.resourceName.split("?");
21879
+ wsComponent.path = path5 && path5 !== "/" ? path5 : void 0;
21880
21880
  wsComponent.query = query;
21881
21881
  wsComponent.resourceName = void 0;
21882
21882
  }
@@ -28312,8 +28312,8 @@ var DECISION_SOURCE = "decision";
28312
28312
  var DECISION_USER_LABEL = "decision (user)";
28313
28313
  var RELEASE_REPO_URL = "https://github.com/mksglu/context-mode.git";
28314
28314
  var RELEASE_BRANCH = "release";
28315
- var BUNDLE_SHA = true ? "f61b6973877b47851ac5938c46fee1399946289e" : void 0;
28316
- var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10"]);
28315
+ var BUNDLE_SHA = true ? "4fb62aa646f6f53db6e655a59f4397d5ef78c0a4" : void 0;
28316
+ var DOCTOR_CHECK_ORDER = Object.freeze(["D1", "D2", "D3", "D4", "D5", "D5b", "D6", "D7", "D8", "D9", "D10", "D11"]);
28317
28317
  var DOCTOR_LABEL = Object.freeze({
28318
28318
  D1: "version",
28319
28319
  D2: "node",
@@ -28325,7 +28325,8 @@ var DOCTOR_LABEL = Object.freeze({
28325
28325
  D7: "project and worktree",
28326
28326
  D8: "context.db",
28327
28327
  D9: "index",
28328
- D10: "enforcement mode"
28328
+ D10: "enforcement mode",
28329
+ D11: "shell"
28329
28330
  });
28330
28331
  var HOOK_FIXTURE_DIR = "fixtures";
28331
28332
  var HOOK_FIXTURE_FILE = "hook-roundtrip.json";
@@ -28432,6 +28433,8 @@ var GIT_NO_PROMPT_ENV = Object.freeze({ GIT_TERMINAL_PROMPT: "0" });
28432
28433
  var GIT_NO_CRLF_ENV = Object.freeze({ GIT_CONFIG_COUNT: "1", GIT_CONFIG_KEY_0: "core.autocrlf", GIT_CONFIG_VALUE_0: "false" });
28433
28434
  var GIT_NOT_STARTED = "git did not start";
28434
28435
  var GIT_BIN = "git";
28436
+ var WIN_SHELL_LANGS = Object.freeze(["shell", "bash", "sh"]);
28437
+ var GIT_BASH_RELATIVE = Object.freeze([["..", "bin", "bash.exe"], ["..", "..", "bin", "bash.exe"]]);
28435
28438
  var GIT_EXIT_LABEL = "git exit ";
28436
28439
  var UPGRADE_TRASH_SUFFIX = ".ctx-upgrade-removing";
28437
28440
  var TABLE_ROW_START = "| ";
@@ -28439,7 +28442,6 @@ var TABLE_CELL_SEP = " | ";
28439
28442
  var TABLE_ROW_END = " |";
28440
28443
  var TABLE_PIPE = "|";
28441
28444
  var TABLE_PIPE_ESCAPED = "\\|";
28442
- var TOML_TABLE_OPEN = "[";
28443
28445
  var OPS_SPLIT_FILES = Object.freeze([
28444
28446
  "doctor-env.ts",
28445
28447
  "doctor-config.ts",
@@ -28467,10 +28469,10 @@ function D3_DETAIL(parts) {
28467
28469
  var HOOK_HOST_FILE = Object.freeze({
28468
28470
  "claude-code": { root: "plugin", file: ["hooks", "claude-code.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
28469
28471
  codex: { root: "home", file: [".codex", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
28470
- gemini: { root: "home", file: [".gemini", "settings.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: false },
28471
- qwen: { root: "home", file: [".qwen", "settings.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
28472
+ gemini: { root: "plugin", file: ["hooks", "hooks.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: false },
28473
+ qwen: { root: "plugin", file: ["hooks", "qwen.json"], key: ["hooks"], shape: "nested", timeoutKey: "timeout", matcher: true },
28472
28474
  "copilot-cli": { root: "home", file: [".copilot", "hooks", "context-mode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeoutSec", matcher: false },
28473
- vscode: { root: "project", file: [".github", "hooks", "context-mode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeout", matcher: false },
28475
+ vscode: { root: "home", file: [".copilot", "hooks", "context-mode-vscode.json"], key: ["hooks"], shape: "flat", timeoutKey: "timeout", matcher: false },
28474
28476
  kiro: { root: "home", file: [".kiro", "hooks", "context-mode.json"], key: ["hooks"], shape: "kiro", timeoutKey: "timeout", matcher: false },
28475
28477
  zcode: { root: "home", file: [".zcode", "cli", "config.json"], key: ["hooks", "events"], shape: "zcode", timeoutKey: "timeoutMs", matcher: true },
28476
28478
  pi: null,
@@ -28503,6 +28505,13 @@ var PRAGMA_INTEGRITY_CHECK = "PRAGMA integrity_check";
28503
28505
  function D10_DETAIL(mode) {
28504
28506
  return `enforcement mode: ${mode}`;
28505
28507
  }
28508
+ var D11_WIN_DETAIL = "Git Bash not found";
28509
+ var D11_WIN_FIX = "install Git for Windows";
28510
+ var D11_POSIX_DETAIL = "no sh on PATH";
28511
+ var D11_POSIX_FIX = "install sh or add it to PATH";
28512
+ function D11_PASS_DETAIL(shell, win) {
28513
+ return `${win ? "Git Bash" : "sh"}: ${shell}`;
28514
+ }
28506
28515
  var DB_SIBLING_SUFFIXES = Object.freeze(["", DB_WAL_SUFFIX, DB_SHM_SUFFIX]);
28507
28516
  var HEAL_TMP_SUFFIX = ".heal";
28508
28517
  var HEAL_TS_SEP = ".";
@@ -28511,6 +28520,7 @@ var HASH_ENCODING = "hex";
28511
28520
  var PLUGIN_LINK_TMP_SUFFIX = ".swap";
28512
28521
  var PLUGIN_LINK_OLD_SUFFIX = ".old";
28513
28522
  var PLUGIN_LINK_TYPE = "dir";
28523
+ var PLUGIN_LINK_TYPE_WIN32 = "junction";
28514
28524
  var OWNER_STOP_EXT = ".stop";
28515
28525
  var UPGRADE_DATA_DELETED = "user data deleted";
28516
28526
  var UPGRADE_HOST_COMMAND = Object.freeze({
@@ -28551,7 +28561,14 @@ var V1_HOOKS_DIR_NAME = "hooks";
28551
28561
  var SETTINGS_FILE = "settings.json";
28552
28562
  var CLAUDE_USER_CONFIG_FILE = ".claude.json";
28553
28563
  var HOOKS_JSON_FILE = "hooks.json";
28564
+ var CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR";
28554
28565
  var CODEX_HOME_ENV = "CODEX_HOME";
28566
+ var COPILOT_HOME_ENV = "COPILOT_HOME";
28567
+ var KIRO_HOME_ENV = "KIRO_HOME";
28568
+ var OPENCODE_CONFIG_DIR_ENV = "OPENCODE_CONFIG_DIR";
28569
+ var APPDATA_ENV = "APPDATA";
28570
+ var VSCODE_USER_DIR_SEGMENTS = Object.freeze(["Code", "User"]);
28571
+ var XDG_CONFIG_HOME_ENV = "XDG_CONFIG_HOME";
28555
28572
  var CONFIG_TOML_FILE = "config.toml";
28556
28573
  var CONFIG_JSON_FILE = "config.json";
28557
28574
  var ZCODE_CLI_DIR = "cli";
@@ -28585,6 +28602,8 @@ var PI_ROLE = "custom";
28585
28602
  var PI_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
28586
28603
  var PI_PACKAGE_SOURCE_KEY = "source";
28587
28604
  var V1_PATH_SEPS = Object.freeze(["/", "\\"]);
28605
+ var HOST_SEP_TOKEN = "${/}";
28606
+ var HOOK_SCRIPT_SEPS = Object.freeze([...V1_PATH_SEPS, HOST_SEP_TOKEN]);
28588
28607
  var V1_REASON = Object.freeze({
28589
28608
  hook: "old context-mode hook entry: command contains context-mode and an old script name or context-mode hook",
28590
28609
  cacheHealHook: "old context-mode cache-heal SessionStart hook entry",
@@ -28611,7 +28630,13 @@ var PLUGIN_NAME = SERVER_KEY;
28611
28630
  var OPENCODE_TOOL_PREFIX = SERVER_KEY + "_";
28612
28631
  var SERVER_ENTRY_FILE = "server.mjs";
28613
28632
  var HOST_NODE_COMMAND = "node";
28633
+ var EXE_SUFFIX = ".exe";
28614
28634
  var HOST_CONFIG_TMP_SUFFIX = ".tmp";
28635
+ var ATOMIC_RENAME_RETRIES = 5;
28636
+ var ATOMIC_RENAME_DELAY_MS = 50;
28637
+ var ATOMIC_RENAME_BUSY_CODES = ["EPERM", "EBUSY", "EACCES"];
28638
+ var ATOMIC_TMP_PREFIX = ".";
28639
+ var ATOMIC_TMP_MARK = ".cm-tmp-";
28615
28640
  var HOST_CONFIG_TEXT_PATH = "(given text)";
28616
28641
  var JSON_INDENT_UNIT = " ";
28617
28642
  var MCP_COMMAND_FIELD = "command";
@@ -28623,7 +28648,7 @@ var CODEX_APPROVAL_MODE_FIELD = "default_tools_approval_mode";
28623
28648
  var CODEX_APPROVAL_APPROVE = "approve";
28624
28649
  var OWN_MCP_ENTRY = Object.freeze({
28625
28650
  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 } },
28626
- vscode: { file: [".vscode", "mcp.json"], key: ["servers", SERVER_KEY] },
28651
+ vscode: { file: [VSCODE_MCP_FILE], key: ["servers", SERVER_KEY] },
28627
28652
  kiro: { file: [".kiro", "settings", "mcp.json"], key: ["mcpServers", SERVER_KEY] },
28628
28653
  zcode: {
28629
28654
  file: [".zcode", "cli", "config.json"],
@@ -28646,6 +28671,8 @@ var ERROR_TEXT = Object.freeze({
28646
28671
  NO_PROJECT: "Project source <kind> is missing. Fix: run ctx_doctor.",
28647
28672
  UNKNOWN_FIELD: 'Unknown field "<f>". Fix: use "queries".',
28648
28673
  TIMEOUT: "Timed out after <ms> ms. Fix: pass background: true.",
28674
+ NO_GIT_BASH: "Git Bash not found. Fix: install Git for Windows.",
28675
+ // D-VT-WINBASH-1
28649
28676
  NO_RUNTIME: "No <lang> runtime on PATH. Fix: install it or pick another language.",
28650
28677
  FETCH_FAILED: "Fetch failed: <code>. Fix: check the URL or proxy.",
28651
28678
  SSRF: "Blocked private address <host>. Fix: use a public URL.",
@@ -28864,9 +28891,9 @@ function readUserVersion(raw) {
28864
28891
  const row5 = raw.prepare("PRAGMA user_version").get();
28865
28892
  return row5.user_version;
28866
28893
  }
28867
- function createAtomically(sqlite, path4) {
28894
+ function createAtomically(sqlite, path5) {
28868
28895
  const { randomUUID: randomUUID2 } = process.getBuiltinModule("node:crypto");
28869
- const tmp = path4 + "." + randomUUID2() + DB_TMP_SUFFIX;
28896
+ const tmp = path5 + "." + randomUUID2() + DB_TMP_SUFFIX;
28870
28897
  try {
28871
28898
  const raw = new sqlite.DatabaseSync(tmp, { timeout: DB_TIMEOUT_MS });
28872
28899
  try {
@@ -28875,7 +28902,7 @@ function createAtomically(sqlite, path4) {
28875
28902
  raw.close();
28876
28903
  }
28877
28904
  try {
28878
- linkSync(tmp, path4);
28905
+ linkSync(tmp, path5);
28879
28906
  } catch (err) {
28880
28907
  if (err.code !== "EEXIST") throw err;
28881
28908
  }
@@ -28883,11 +28910,11 @@ function createAtomically(sqlite, path4) {
28883
28910
  for (const suffix of ["", DB_WAL_SUFFIX, DB_SHM_SUFFIX]) rmSync(tmp + suffix, { force: true });
28884
28911
  }
28885
28912
  }
28886
- function openWritable(sqlite, path4) {
28913
+ function openWritable(sqlite, path5) {
28887
28914
  let raw = null;
28888
28915
  try {
28889
- if (!existsSync(path4)) createAtomically(sqlite, path4);
28890
- raw = new sqlite.DatabaseSync(path4, { timeout: DB_TIMEOUT_MS });
28916
+ if (!existsSync(path5)) createAtomically(sqlite, path5);
28917
+ raw = new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS });
28891
28918
  applyMigrations(raw, readUserVersion(raw));
28892
28919
  return raw;
28893
28920
  } catch (err) {
@@ -28895,8 +28922,8 @@ function openWritable(sqlite, path4) {
28895
28922
  throw err;
28896
28923
  }
28897
28924
  }
28898
- function openReadOnly(sqlite, path4) {
28899
- const raw = new sqlite.DatabaseSync(path4, { timeout: DB_TIMEOUT_MS, readOnly: true });
28925
+ function openReadOnly(sqlite, path5) {
28926
+ const raw = new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS, readOnly: true });
28900
28927
  try {
28901
28928
  const found = readUserVersion(raw);
28902
28929
  if (found !== SCHEMA_VERSION) throw new CtxError("SCHEMA_STALE", { found, want: SCHEMA_VERSION });
@@ -28910,20 +28937,20 @@ async function openDb(project, opts) {
28910
28937
  if (isBelow(process.version, NODE_MIN)) throw new CtxError("NODE_TOO_OLD", { v: process.version });
28911
28938
  const sqlite = await loadSqlite();
28912
28939
  mkdirSync(project.projectDir, { recursive: true });
28913
- const path4 = project.dbPath;
28914
- const sibling = existsSync(path4 + DB_WAL_SUFFIX) || existsSync(path4 + DB_SHM_SUFFIX);
28915
- if (sibling && !existsSync(path4)) {
28940
+ const path5 = project.dbPath;
28941
+ const sibling = existsSync(path5 + DB_WAL_SUFFIX) || existsSync(path5 + DB_SHM_SUFFIX);
28942
+ if (sibling && !existsSync(path5)) {
28916
28943
  throw new CtxError("DB_GONE");
28917
28944
  }
28918
28945
  try {
28919
28946
  let raw;
28920
28947
  if (opts?.readOnly === true) {
28921
- if (!existsSync(path4)) openWritable(sqlite, path4).close();
28922
- raw = openReadOnly(sqlite, path4);
28948
+ if (!existsSync(path5)) openWritable(sqlite, path5).close();
28949
+ raw = openReadOnly(sqlite, path5);
28923
28950
  } else {
28924
- raw = openWritable(sqlite, path4);
28951
+ raw = openWritable(sqlite, path5);
28925
28952
  }
28926
- return { raw, projectKey: project.projectKey, path: path4 };
28953
+ return { raw, projectKey: project.projectKey, path: path5 };
28927
28954
  } catch (err) {
28928
28955
  if (isCorrupt(err)) throw new CtxError("DB_CORRUPT");
28929
28956
  throw err;
@@ -29053,26 +29080,71 @@ function installExitGuard(opts) {
29053
29080
  }
29054
29081
 
29055
29082
  // src/core/project/config-dir.ts
29056
- import { join } from "node:path";
29083
+ import { join, posix, win32 } from "node:path";
29057
29084
  var { mkdirSync: mkdirSync2, realpathSync } = process.getBuiltinModule("node:fs");
29058
- function homeDirOf(env) {
29059
- const home = env.HOME;
29060
- if (home !== void 0 && home !== "") return home;
29061
- const profile = env.USERPROFILE;
29062
- if (profile !== void 0 && profile !== "") return profile;
29063
- return null;
29085
+ function homeDirOf(env, platform = process.platform) {
29086
+ const set3 = (v) => v !== void 0 && v !== "";
29087
+ if (platform === "win32") {
29088
+ if (set3(env.USERPROFILE)) return env.USERPROFILE;
29089
+ if (set3(env.HOMEDRIVE) && set3(env.HOMEPATH)) return env.HOMEDRIVE + env.HOMEPATH;
29090
+ return set3(env.HOME) ? env.HOME : null;
29091
+ }
29092
+ if (set3(env.HOME)) return env.HOME;
29093
+ return set3(env.USERPROFILE) ? env.USERPROFILE : null;
29064
29094
  }
29065
29095
  function codexDirOf(env, home) {
29066
29096
  const dir = env[CODEX_HOME_ENV];
29067
29097
  return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR.codex);
29068
29098
  }
29069
- function homeOf(env) {
29070
- const home = homeDirOf(env);
29099
+ function copilotDirOf(env, home) {
29100
+ const dir = env[COPILOT_HOME_ENV];
29101
+ return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR["copilot-cli"]);
29102
+ }
29103
+ function kiroDirOf(env, home, platform = process.platform) {
29104
+ const p = platform === "win32" ? win32 : posix;
29105
+ const fallback = p.join(home, ...AGENT_HOME_DIR.kiro);
29106
+ const dir = env[KIRO_HOME_ENV];
29107
+ if (dir === void 0 || dir === "" || !p.isAbsolute(dir)) return fallback;
29108
+ if (platform === "win32" && p.parse(dir).root.length < 2) return fallback;
29109
+ const abs = p.resolve(dir);
29110
+ if (p.dirname(abs) === abs) return fallback;
29111
+ const up = p.relative(abs, p.resolve(home));
29112
+ if (!p.isAbsolute(up) && up.split(p.sep)[0] !== "..") return fallback;
29113
+ return dir;
29114
+ }
29115
+ function claudeDirOf(env, home) {
29116
+ const dir = env[CLAUDE_CONFIG_DIR_ENV];
29117
+ return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR["claude-code"]);
29118
+ }
29119
+ function opencodeDirOf(env, home) {
29120
+ const own4 = env[OPENCODE_CONFIG_DIR_ENV];
29121
+ if (own4 !== void 0 && own4 !== "") return own4;
29122
+ const xdg = env[XDG_CONFIG_HOME_ENV];
29123
+ if (xdg !== void 0 && xdg !== "") return join(xdg, AGENT_HOME_DIR.opencode[AGENT_HOME_DIR.opencode.length - 1]);
29124
+ return join(home, ...AGENT_HOME_DIR.opencode);
29125
+ }
29126
+ function piAgentDirOf(env, home) {
29127
+ const dir = env[PI_AGENT_DIR_ENV];
29128
+ return dir !== void 0 && dir !== "" ? dir : join(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR);
29129
+ }
29130
+ function vscodeUserDirOf(env, home, platform = process.platform) {
29131
+ const set3 = (v) => v !== void 0 && v !== "";
29132
+ const p = platform === "win32" ? win32 : posix;
29133
+ if (platform === "win32") return p.join(set3(env[APPDATA_ENV]) ? env[APPDATA_ENV] : p.join(home, "AppData", "Roaming"), ...VSCODE_USER_DIR_SEGMENTS);
29134
+ if (platform === "darwin") return p.join(home, "Library", "Application Support", ...VSCODE_USER_DIR_SEGMENTS);
29135
+ return p.join(set3(env[XDG_CONFIG_HOME_ENV]) ? env[XDG_CONFIG_HOME_ENV] : p.join(home, ".config"), ...VSCODE_USER_DIR_SEGMENTS);
29136
+ }
29137
+ function ownMcpFileOf(agent, file2, env, home) {
29138
+ if (agent === "kiro") return join(kiroDirOf(env, home), ...file2.slice(1));
29139
+ return agent === "vscode" ? join(vscodeUserDirOf(env, home), ...file2) : join(home, ...file2);
29140
+ }
29141
+ function requireHomeDir(env, platform = process.platform) {
29142
+ const home = homeDirOf(env, platform);
29071
29143
  if (home !== null) return home;
29072
- throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
29144
+ throw new CtxError("NO_HOME", { name: platform === "win32" ? "USERPROFILE" : "HOME" });
29073
29145
  }
29074
29146
  function resolveConfigDir(env) {
29075
- const dir = join(homeOf(env), DATA_ROOT.slice(1));
29147
+ const dir = join(requireHomeDir(env), DATA_ROOT.slice(1));
29076
29148
  mkdirSync2(dir, { recursive: true });
29077
29149
  return realpathSync.native(dir);
29078
29150
  }
@@ -29319,7 +29391,7 @@ function firstLine(file2) {
29319
29391
  }
29320
29392
  function git(dir, args) {
29321
29393
  const { spawnSync } = process.getBuiltinModule("node:child_process");
29322
- const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
29394
+ const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
29323
29395
  if (r.error !== void 0 || r.status !== 0) throw new CtxError("NO_GIT_DIR", { path: dir });
29324
29396
  return r.stdout.split("\n").filter((l) => l !== "");
29325
29397
  }
@@ -31235,9 +31307,9 @@ function isWordChar(cp) {
31235
31307
  while (lo <= hi) {
31236
31308
  const mid = lo + hi >> 1;
31237
31309
  const first = WORD_RANGES[2 * mid];
31238
- const last = WORD_RANGES[2 * mid + 1];
31310
+ const last2 = WORD_RANGES[2 * mid + 1];
31239
31311
  if (cp < first) hi = mid - 1;
31240
- else if (cp > last) lo = mid + 1;
31312
+ else if (cp > last2) lo = mid + 1;
31241
31313
  else return true;
31242
31314
  }
31243
31315
  return false;
@@ -31724,8 +31796,8 @@ function ftsQueryTimeline(db, scope, ctx, sessionId, limit, after, source, memor
31724
31796
  merged.sort(timelineOrder);
31725
31797
  let end = Math.min(limit, merged.length);
31726
31798
  if (end > 0) {
31727
- const last = merged[end - 1].ts;
31728
- while (end < merged.length && merged[end].ts === last) end++;
31799
+ const last2 = merged[end - 1].ts;
31800
+ while (end < merged.length && merged[end].ts === last2) end++;
31729
31801
  }
31730
31802
  const rows = merged.slice(0, end);
31731
31803
  if (rows.length === 0) return { rows, more: false };
@@ -32558,10 +32630,10 @@ function jsonStringifyReplacer3(_, value) {
32558
32630
  return value;
32559
32631
  }
32560
32632
  function cached3(getter) {
32561
- const set2 = false;
32633
+ const set3 = false;
32562
32634
  return {
32563
32635
  get value() {
32564
- if (!set2) {
32636
+ if (!set3) {
32565
32637
  const value = getter();
32566
32638
  Object.defineProperty(this, "value", { value });
32567
32639
  return value;
@@ -32587,10 +32659,10 @@ function floatSafeRemainder3(val, step) {
32587
32659
  return valInt % stepInt / 10 ** decCount;
32588
32660
  }
32589
32661
  function defineLazy3(object4, key, getter) {
32590
- const set2 = false;
32662
+ const set3 = false;
32591
32663
  Object.defineProperty(object4, key, {
32592
32664
  get() {
32593
- if (!set2) {
32665
+ if (!set3) {
32594
32666
  const value = getter();
32595
32667
  object4[key] = value;
32596
32668
  return value;
@@ -32614,10 +32686,10 @@ function assignProp3(target, prop, value) {
32614
32686
  configurable: true
32615
32687
  });
32616
32688
  }
32617
- function getElementAtPath3(obj, path4) {
32618
- if (!path4)
32689
+ function getElementAtPath3(obj, path5) {
32690
+ if (!path5)
32619
32691
  return obj;
32620
- return path4.reduce((acc, key) => acc?.[key], obj);
32692
+ return path5.reduce((acc, key) => acc?.[key], obj);
32621
32693
  }
32622
32694
  function promiseAllObject3(promisesObj) {
32623
32695
  const keys = Object.keys(promisesObj);
@@ -32937,11 +33009,11 @@ function aborted3(x, startIndex = 0) {
32937
33009
  }
32938
33010
  return false;
32939
33011
  }
32940
- function prefixIssues3(path4, issues) {
33012
+ function prefixIssues3(path5, issues) {
32941
33013
  return issues.map((iss) => {
32942
33014
  var _a5;
32943
33015
  (_a5 = iss).path ?? (_a5.path = []);
32944
- iss.path.unshift(path4);
33016
+ iss.path.unshift(path5);
32945
33017
  return iss;
32946
33018
  });
32947
33019
  }
@@ -33078,7 +33150,7 @@ function treeifyError2(error42, _mapper) {
33078
33150
  return issue4.message;
33079
33151
  };
33080
33152
  const result = { errors: [] };
33081
- const processError = (error43, path4 = []) => {
33153
+ const processError = (error43, path5 = []) => {
33082
33154
  var _a5, _b;
33083
33155
  for (const issue4 of error43.issues) {
33084
33156
  if (issue4.code === "invalid_union" && issue4.errors.length) {
@@ -33088,7 +33160,7 @@ function treeifyError2(error42, _mapper) {
33088
33160
  } else if (issue4.code === "invalid_element") {
33089
33161
  processError({ issues: issue4.issues }, issue4.path);
33090
33162
  } else {
33091
- const fullpath = [...path4, ...issue4.path];
33163
+ const fullpath = [...path5, ...issue4.path];
33092
33164
  if (fullpath.length === 0) {
33093
33165
  result.errors.push(mapper(issue4));
33094
33166
  continue;
@@ -33118,9 +33190,9 @@ function treeifyError2(error42, _mapper) {
33118
33190
  processError(error42);
33119
33191
  return result;
33120
33192
  }
33121
- function toDotPath(path4) {
33193
+ function toDotPath(path5) {
33122
33194
  const segs = [];
33123
- for (const seg of path4) {
33195
+ for (const seg of path5) {
33124
33196
  if (typeof seg === "number")
33125
33197
  segs.push(`[${seg}]`);
33126
33198
  else if (typeof seg === "symbol")
@@ -34460,8 +34532,8 @@ var $ZodDate3 = /* @__PURE__ */ $constructor3("$ZodDate", (inst, def) => {
34460
34532
  }
34461
34533
  const input = payload.value;
34462
34534
  const isDate = input instanceof Date;
34463
- const isValidDate = isDate && !Number.isNaN(input.getTime());
34464
- if (isValidDate)
34535
+ const isValidDate2 = isDate && !Number.isNaN(input.getTime());
34536
+ if (isValidDate2)
34465
34537
  return payload;
34466
34538
  payload.issues.push({
34467
34539
  expected: "date",
@@ -43485,6 +43557,14 @@ function buildChildEnv(parent, extra) {
43485
43557
  // src/core/sandbox/runtimes.ts
43486
43558
  import { accessSync, constants as fsConstants, statSync as statSync2 } from "node:fs";
43487
43559
  import path from "node:path";
43560
+
43561
+ // src/core/sandbox/path-entries.ts
43562
+ function pathEntries(value, platform = process.platform, delimiter = platform === "win32" ? ";" : ":") {
43563
+ const win = platform === "win32";
43564
+ return value.split(delimiter).map((e) => win && e.length >= 2 && e.startsWith('"') && e.endsWith('"') ? e.slice(1, -1) : e).filter(Boolean);
43565
+ }
43566
+
43567
+ // src/core/sandbox/runtimes.ts
43488
43568
  var PATHEXT_SEPARATOR = ";";
43489
43569
  var WIN_STARTABLE_EXT = Object.freeze([".exe", ".com"]);
43490
43570
  function isWin() {
@@ -43494,7 +43574,7 @@ function candidates(lang) {
43494
43574
  const win = isWin();
43495
43575
  switch (lang) {
43496
43576
  case "shell":
43497
- return win ? ["sh.exe", "bash.exe"] : ["sh"];
43577
+ return win ? [] : ["sh"];
43498
43578
  case "powershell":
43499
43579
  return ["pwsh", "pwsh.exe", "powershell.exe"];
43500
43580
  case "javascript":
@@ -43525,7 +43605,8 @@ function isRunnable(full) {
43525
43605
  }
43526
43606
  }
43527
43607
  function findRuntime(lang, env = process.env) {
43528
- const dirs = (env.PATH ?? "").split(path.delimiter).filter((d) => d !== "");
43608
+ if (isWin() && WIN_SHELL_LANGS.includes(lang)) return findGitBash(env);
43609
+ const dirs = pathEntries(env.PATH ?? "", process.platform, path.delimiter);
43529
43610
  const pathExt = isWin() ? (env.PATHEXT ?? PATHEXT_DEFAULT).split(PATHEXT_SEPARATOR).filter((e) => e !== "") : [];
43530
43611
  const names = candidates(lang);
43531
43612
  let shim = null;
@@ -43541,6 +43622,18 @@ function findRuntime(lang, env = process.env) {
43541
43622
  }
43542
43623
  return shim;
43543
43624
  }
43625
+ function findGitBash(env) {
43626
+ const git3 = findRuntime(GIT_BIN, env);
43627
+ if (git3 === null) return null;
43628
+ for (const rel of GIT_BASH_RELATIVE) {
43629
+ const full = path.resolve(path.dirname(git3), ...rel);
43630
+ if (isRunnable(full)) return full;
43631
+ }
43632
+ return null;
43633
+ }
43634
+ function noRuntimeError(lang) {
43635
+ return isWin() && WIN_SHELL_LANGS.includes(lang) ? new CtxError("NO_GIT_BASH") : new CtxError("NO_RUNTIME", { lang });
43636
+ }
43544
43637
 
43545
43638
  // src/core/sandbox/spawn.ts
43546
43639
  import { spawn } from "node:child_process";
@@ -43648,19 +43741,19 @@ function readAutoMemory(project) {
43648
43741
  if (project.agent !== "claude-code") return [];
43649
43742
  const rows = [];
43650
43743
  for (const segs of CLAUDE_CODE_MEMORY_FILES) {
43651
- const path4 = join5(project.worktree, ...segs);
43652
- if (!isInside(project.worktree, path4)) continue;
43744
+ const path5 = join5(project.worktree, ...segs);
43745
+ if (!isInside(project.worktree, path5)) continue;
43653
43746
  try {
43654
- const st = statSync3(path4);
43747
+ const st = statSync3(path5);
43655
43748
  if (!st.isFile()) continue;
43656
43749
  rows.push({
43657
43750
  origin: "memory",
43658
43751
  ts: Math.trunc(st.mtimeMs),
43659
43752
  seq: null,
43660
43753
  sourceId: null,
43661
- path: path4,
43754
+ path: path5,
43662
43755
  label: segs.join("/"),
43663
- text: readFileSync3(path4, "utf8")
43756
+ text: readFileSync3(path5, "utf8")
43664
43757
  });
43665
43758
  } catch {
43666
43759
  }
@@ -43965,7 +44058,7 @@ function stoppedAt(cmd, error42) {
43965
44058
  return { head: headOf(cmd), block: headOf(cmd) + error42, exitCode: null, bytes: 0, error: error42 };
43966
44059
  }
43967
44060
  async function runCommand(cmd, shell, ctx, deadline, boundMs) {
43968
- if (shell === null) return stoppedAt(cmd, formatError3("NO_RUNTIME", { lang: SHELL }));
44061
+ if (shell === null) return stoppedAt(cmd, noRuntimeError(SHELL).toLine());
43969
44062
  const left = deadline - Date.now();
43970
44063
  if (left <= 0) return stoppedAt(cmd, formatError3("TIMEOUT", { ms: boundMs }));
43971
44064
  const r = await runProcess([shell, SHELL_INLINE_FLAG, cmd], {
@@ -44085,19 +44178,19 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
44085
44178
  const shell = findRuntime(SHELL);
44086
44179
  const pool = await runPool(commands.map((c) => () => runCommand(c, shell, ctx, deadline, boundMs)), ONE_AT_A_TIME, (r) => r.error !== null);
44087
44180
  const ran = pool.results;
44088
- const last = ran[ran.length - 1];
44181
+ const last2 = ran[ran.length - 1];
44089
44182
  const sandboxBytes = ran.reduce((n, r) => n + r.bytes, 0);
44090
44183
  const label = LABEL_PREFIX + ctx.turn;
44091
44184
  try {
44092
44185
  const db = await openDb(ctx.project);
44093
44186
  let sections;
44094
44187
  let idx;
44095
- const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " + last.exitCode;
44188
+ const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " + last2.exitCode;
44096
44189
  const footer = "more: ctx_search({queries:[...], source:" + JSON.stringify(label) + "})";
44097
44190
  let notice;
44098
44191
  try {
44099
44192
  idx = indexCombined(db, ctx, label, ran, deadline, budgetBytes);
44100
- const stop = last.error;
44193
+ const stop = last2.error;
44101
44194
  const cut = idx.indexed < idx.total ? "Indexed " + idx.indexed + " of " + idx.total + " B." : null;
44102
44195
  const timeout = formatError3("TIMEOUT", { ms: boundMs });
44103
44196
  const cause = stop ?? (ctx.signal.aborted ? CANCELLED_LINE : idx.stop === "deadline" ? timeout : null);
@@ -44115,7 +44208,7 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
44115
44208
  isError: false,
44116
44209
  // step 11
44117
44210
  sandboxBytes,
44118
- journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code: last.exitCode }
44211
+ journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code: last2.exitCode }
44119
44212
  };
44120
44213
  } catch (err) {
44121
44214
  if (err instanceof CtxError) return { text: err.toLine(), isError: true, sandboxBytes };
@@ -44492,8 +44585,14 @@ var VSCODE_EVENTS = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostTool
44492
44585
  var MCP_PREFIX2 = "mcp_";
44493
44586
  var MCP_SEP2 = "_";
44494
44587
  var SESSION_START_NEW = "new";
44495
- var SHELL_TOOL_NAME = "run_in_terminal";
44496
- var NATIVE_TO_CANONICAL4 = { [SHELL_TOOL_NAME]: "Bash" };
44588
+ var SHELL_TOOL_NAMES = Object.freeze(["run_in_terminal", "runTerminalCommand", "bash", "powershell"]);
44589
+ var READ_TOOL_NAMES = Object.freeze(["read_file", "view"]);
44590
+ var WEBFETCH_TOOL_NAMES = Object.freeze(["fetch_webpage", "web_fetch"]);
44591
+ var NATIVE_TO_CANONICAL4 = Object.fromEntries([
44592
+ ...SHELL_TOOL_NAMES.map((n) => [n, "Bash"]),
44593
+ ...READ_TOOL_NAMES.map((n) => [n, "Read"]),
44594
+ ...WEBFETCH_TOOL_NAMES.map((n) => [n, "WebFetch"])
44595
+ ]);
44497
44596
  function canonicalName4(name) {
44498
44597
  if (name.startsWith(TOOL_NAME_PREFIX6)) return name.slice(TOOL_NAME_PREFIX6.length);
44499
44598
  if (Object.hasOwn(NATIVE_TO_CANONICAL4, name)) return NATIVE_TO_CANONICAL4[name];
@@ -44503,6 +44602,26 @@ function canonicalName4(name) {
44503
44602
  if (sep2 <= 0 || sep2 === rest.length - 1) return name;
44504
44603
  return "mcp:" + rest.slice(0, sep2) + ":" + rest.slice(sep2 + MCP_SEP2.length);
44505
44604
  }
44605
+ var isNum = (v) => typeof v === "number" && Number.isFinite(v);
44606
+ function policyInput(name, canonical, input) {
44607
+ if (canonical === "Read" && READ_TOOL_NAMES.includes(name)) {
44608
+ const out = { ...input };
44609
+ if (name === "read_file") {
44610
+ if (typeof input.filePath === "string") out.file_path = input.filePath;
44611
+ if (isNum(input.startLine)) out.offset = input.startLine;
44612
+ if (isNum(input.startLine) && isNum(input.endLine) && input.endLine >= input.startLine) out.limit = input.endLine - input.startLine + 1;
44613
+ } else if (Array.isArray(input.view_range) && isNum(input.view_range[0])) {
44614
+ out.offset = input.view_range[0];
44615
+ const end = input.view_range[1];
44616
+ if (isNum(end) && end >= input.view_range[0]) out.limit = end - input.view_range[0] + 1;
44617
+ }
44618
+ return out;
44619
+ }
44620
+ if (canonical === "WebFetch" && name === "fetch_webpage" && Array.isArray(input.urls) && typeof input.urls[0] === "string") {
44621
+ return { ...input, url: input.urls[0] };
44622
+ }
44623
+ return input;
44624
+ }
44506
44625
  function readResult4(resp) {
44507
44626
  const text = resp === void 0 ? "" : typeof resp === "string" ? resp : JSON.stringify(resp);
44508
44627
  const isError = typeof resp === "object" && resp !== null && resp.is_error === true;
@@ -44550,7 +44669,8 @@ function decodeCamel(p, name) {
44550
44669
  if (event === "UserPromptSubmit" && typeof p.prompt === "string") ev.prompt = p.prompt;
44551
44670
  if (event === "PreToolUse" || event === "PostToolUse") {
44552
44671
  const toolName = String(p.toolName ?? "");
44553
- ev.tool = { name: toolName, canonicalName: canonicalName4(toolName), input: readArgs2(p.toolArgs) };
44672
+ const canonical = canonicalName4(toolName);
44673
+ ev.tool = { name: toolName, canonicalName: canonical, input: policyInput(toolName, canonical, readArgs2(p.toolArgs)) };
44554
44674
  }
44555
44675
  if (event === "PostToolUse") ev.result = readCamelResult(p.toolResult);
44556
44676
  return ev;
@@ -44572,7 +44692,8 @@ function decode8(raw) {
44572
44692
  if (event === "PreToolUse" || event === "PostToolUse") {
44573
44693
  const name = String(p.tool_name ?? "");
44574
44694
  const input = isRecord2(p.tool_input) ? p.tool_input : {};
44575
- ev.tool = { name, canonicalName: canonicalName4(name), input };
44695
+ const canonical = canonicalName4(name);
44696
+ ev.tool = { name, canonicalName: canonical, input: policyInput(name, canonical, input) };
44576
44697
  }
44577
44698
  if (event === "PostToolUse") ev.result = readResult4(p.tool_response);
44578
44699
  return ev;
@@ -44596,8 +44717,8 @@ var KIRO_EVENTS = {
44596
44717
  };
44597
44718
  var PROMPT_ENV = "USER_PROMPT";
44598
44719
  var MCP_PREFIX3 = "mcp_";
44599
- var SHELL_TOOL_NAMES = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
44600
- var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES.map((n) => [n, "Bash"]));
44720
+ var SHELL_TOOL_NAMES2 = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
44721
+ var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES2.map((n) => [n, "Bash"]));
44601
44722
  var MCP_SEP3 = "_";
44602
44723
  var KIRO_SOURCES = { startup: "startup", resume: "resume", clear: "clear", compact: "compact" };
44603
44724
  function canonicalName5(name) {
@@ -44738,8 +44859,8 @@ var OPENCODE_EVENTS = {
44738
44859
  compaction: "PreCompact",
44739
44860
  "step-finish": "Usage"
44740
44861
  };
44741
- var SHELL_TOOL_NAME2 = "bash";
44742
- var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME2]: "Bash" };
44862
+ var SHELL_TOOL_NAME = "bash";
44863
+ var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME]: "Bash" };
44743
44864
  function toCanonicalTool(name) {
44744
44865
  if (name.startsWith(OWN_WIRE_PREFIX)) return name.slice(OWN_WIRE_PREFIX.length);
44745
44866
  return Object.prototype.hasOwnProperty.call(NATIVE_TO_CANONICAL7, name) ? NATIVE_TO_CANONICAL7[name] : name;
@@ -44888,7 +45009,8 @@ var ADAPTERS = Object.freeze([
44888
45009
  projectSource: "arg:workspaceFolder",
44889
45010
  toolNamePrefix: TOOL_NAME_PREFIX6,
44890
45011
  // PreCompact sets the pending flag (ADR-0009 §6, DEVIATIONS D-M3-A4-1).
44891
- nativeTools: { shell: [SHELL_TOOL_NAME] },
45012
+ nativeTools: { shell: [...SHELL_TOOL_NAMES], read: [...READ_TOOL_NAMES], webfetch: [...WEBFETCH_TOOL_NAMES] },
45013
+ // D-HF-VSCODE-PROJECT-1, D-N7-VSCODE-TOOLS-1
44892
45014
  execReadOnlyHint: false,
44893
45015
  eventMap: { ...CLAUDE_EVENTS, PreCompact: "PreCompact" },
44894
45016
  compactDelivery: "pending-flag",
@@ -44906,7 +45028,7 @@ var ADAPTERS = Object.freeze([
44906
45028
  installMode: "mcp-entry",
44907
45029
  projectSource: "arg:--agent+cwd",
44908
45030
  toolNamePrefix: TOOL_NAME_PREFIX7,
44909
- nativeTools: { shell: [...SHELL_TOOL_NAMES] },
45031
+ nativeTools: { shell: [...SHELL_TOOL_NAMES2] },
44910
45032
  execReadOnlyHint: false,
44911
45033
  // D-HF-KIRO-SHELL-1, D-N7-KIRO-1
44912
45034
  eventMap: { SessionStart: "SessionStart", UserPromptSubmit: "UserPromptSubmit", PreToolUse: "PreToolUse", PostToolUse: "PostToolUse" },
@@ -44963,7 +45085,7 @@ var ADAPTERS = Object.freeze([
44963
45085
  installMode: "in-process",
44964
45086
  projectSource: "spawn-cwd",
44965
45087
  toolNamePrefix: TOOL_NAME_PREFIX10,
44966
- nativeTools: { shell: [SHELL_TOOL_NAME2] },
45088
+ nativeTools: { shell: [SHELL_TOOL_NAME] },
44967
45089
  execReadOnlyHint: false,
44968
45090
  // D-HF-OPENCODE-SHELL-1
44969
45091
  // Usage: step-finish cost row (DEVIATIONS D-M5-arch-2).
@@ -44993,305 +45115,2157 @@ function getAdapter(id) {
44993
45115
  import { join as join9 } from "node:path";
44994
45116
 
44995
45117
  // src/core/ops/detect-v1.ts
44996
- import { existsSync as existsSync4, opendirSync, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
45118
+ import { existsSync as existsSync5, opendirSync, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
44997
45119
  import { tmpdir } from "node:os";
44998
- import { join as join6 } from "node:path";
44999
- var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
45000
- var keyPath = (...parts) => parts.join(".");
45001
- var finding = (file2, path4, reason) => ({ file: file2, path: path4, reason });
45002
- function stripJsonc(text) {
45003
- let out = "";
45004
- let inStr = false;
45005
- let esc4 = false;
45006
- for (let i = 0; i < text.length; i++) {
45007
- const c = text[i];
45008
- if (inStr) {
45009
- out += c;
45010
- if (esc4) esc4 = false;
45011
- else if (c === "\\") esc4 = true;
45012
- else if (c === '"') inStr = false;
45013
- continue;
45120
+ import { join as join7 } from "node:path";
45121
+
45122
+ // src/core/ops/host-config.ts
45123
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
45124
+ import { dirname as dirname3, join as join6 } from "node:path";
45125
+
45126
+ // node_modules/eslint-visitor-keys/lib/visitor-keys.js
45127
+ var KEYS2 = {
45128
+ ArrayExpression: ["elements"],
45129
+ ArrayPattern: ["elements"],
45130
+ ArrowFunctionExpression: ["params", "body"],
45131
+ AssignmentExpression: ["left", "right"],
45132
+ AssignmentPattern: ["left", "right"],
45133
+ AwaitExpression: ["argument"],
45134
+ BinaryExpression: ["left", "right"],
45135
+ BlockStatement: ["body"],
45136
+ BreakStatement: ["label"],
45137
+ CallExpression: ["callee", "arguments"],
45138
+ CatchClause: ["param", "body"],
45139
+ ChainExpression: ["expression"],
45140
+ ClassBody: ["body"],
45141
+ ClassDeclaration: ["id", "superClass", "body"],
45142
+ ClassExpression: ["id", "superClass", "body"],
45143
+ ConditionalExpression: ["test", "consequent", "alternate"],
45144
+ ContinueStatement: ["label"],
45145
+ DebuggerStatement: [],
45146
+ DoWhileStatement: ["body", "test"],
45147
+ EmptyStatement: [],
45148
+ ExperimentalRestProperty: ["argument"],
45149
+ ExperimentalSpreadProperty: ["argument"],
45150
+ ExportAllDeclaration: ["exported", "source", "attributes"],
45151
+ ExportDefaultDeclaration: ["declaration"],
45152
+ ExportNamedDeclaration: [
45153
+ "declaration",
45154
+ "specifiers",
45155
+ "source",
45156
+ "attributes"
45157
+ ],
45158
+ ExportSpecifier: ["local", "exported"],
45159
+ ExpressionStatement: ["expression"],
45160
+ ForInStatement: ["left", "right", "body"],
45161
+ ForOfStatement: ["left", "right", "body"],
45162
+ ForStatement: ["init", "test", "update", "body"],
45163
+ FunctionDeclaration: ["id", "params", "body"],
45164
+ FunctionExpression: ["id", "params", "body"],
45165
+ Identifier: [],
45166
+ IfStatement: ["test", "consequent", "alternate"],
45167
+ ImportAttribute: ["key", "value"],
45168
+ ImportDeclaration: ["specifiers", "source", "attributes"],
45169
+ ImportDefaultSpecifier: ["local"],
45170
+ ImportExpression: ["source", "options"],
45171
+ ImportNamespaceSpecifier: ["local"],
45172
+ ImportSpecifier: ["imported", "local"],
45173
+ JSXAttribute: ["name", "value"],
45174
+ JSXClosingElement: ["name"],
45175
+ JSXClosingFragment: [],
45176
+ JSXElement: ["openingElement", "children", "closingElement"],
45177
+ JSXEmptyExpression: [],
45178
+ JSXExpressionContainer: ["expression"],
45179
+ JSXFragment: ["openingFragment", "children", "closingFragment"],
45180
+ JSXIdentifier: [],
45181
+ JSXMemberExpression: ["object", "property"],
45182
+ JSXNamespacedName: ["namespace", "name"],
45183
+ JSXOpeningElement: ["name", "attributes"],
45184
+ JSXOpeningFragment: [],
45185
+ JSXSpreadAttribute: ["argument"],
45186
+ JSXSpreadChild: ["expression"],
45187
+ JSXText: [],
45188
+ LabeledStatement: ["label", "body"],
45189
+ Literal: [],
45190
+ LogicalExpression: ["left", "right"],
45191
+ MemberExpression: ["object", "property"],
45192
+ MetaProperty: ["meta", "property"],
45193
+ MethodDefinition: ["key", "value"],
45194
+ NewExpression: ["callee", "arguments"],
45195
+ ObjectExpression: ["properties"],
45196
+ ObjectPattern: ["properties"],
45197
+ PrivateIdentifier: [],
45198
+ Program: ["body"],
45199
+ Property: ["key", "value"],
45200
+ PropertyDefinition: ["key", "value"],
45201
+ RestElement: ["argument"],
45202
+ ReturnStatement: ["argument"],
45203
+ SequenceExpression: ["expressions"],
45204
+ SpreadElement: ["argument"],
45205
+ StaticBlock: ["body"],
45206
+ Super: [],
45207
+ SwitchCase: ["test", "consequent"],
45208
+ SwitchStatement: ["discriminant", "cases"],
45209
+ TaggedTemplateExpression: ["tag", "quasi"],
45210
+ TemplateElement: [],
45211
+ TemplateLiteral: ["quasis", "expressions"],
45212
+ ThisExpression: [],
45213
+ ThrowStatement: ["argument"],
45214
+ TryStatement: ["block", "handler", "finalizer"],
45215
+ UnaryExpression: ["argument"],
45216
+ UpdateExpression: ["argument"],
45217
+ VariableDeclaration: ["declarations"],
45218
+ VariableDeclarator: ["id", "init"],
45219
+ WhileStatement: ["test", "body"],
45220
+ WithStatement: ["object", "body"],
45221
+ YieldExpression: ["argument"]
45222
+ };
45223
+ var NODE_TYPES = Object.keys(KEYS2);
45224
+ for (const type of NODE_TYPES) {
45225
+ Object.freeze(KEYS2[type]);
45226
+ }
45227
+ Object.freeze(KEYS2);
45228
+ var visitor_keys_default = KEYS2;
45229
+
45230
+ // node_modules/eslint-visitor-keys/lib/index.js
45231
+ function unionWith(additionalKeys) {
45232
+ const retv = (
45233
+ /** @type {{ [type: string]: ReadonlyArray<string> }} */
45234
+ Object.assign({}, visitor_keys_default)
45235
+ );
45236
+ for (const type of Object.keys(additionalKeys)) {
45237
+ if (Object.hasOwn(retv, type)) {
45238
+ const keys = new Set(additionalKeys[type]);
45239
+ for (const key of retv[type]) {
45240
+ keys.add(key);
45241
+ }
45242
+ retv[type] = Object.freeze(Array.from(keys));
45243
+ } else {
45244
+ retv[type] = Object.freeze(Array.from(additionalKeys[type]));
45014
45245
  }
45015
- if (c === '"') {
45016
- inStr = true;
45017
- out += c;
45018
- continue;
45246
+ }
45247
+ return Object.freeze(retv);
45248
+ }
45249
+
45250
+ // node_modules/toml-eslint-parser/lib/index.mjs
45251
+ function last(arr) {
45252
+ return arr[arr.length - 1] ?? null;
45253
+ }
45254
+ function toKeyName(node3) {
45255
+ return node3.type === "TOMLBare" ? node3.name : node3.value;
45256
+ }
45257
+ var TOMLVerImpl = class {
45258
+ constructor(major, minor) {
45259
+ this.major = major;
45260
+ this.minor = minor;
45261
+ }
45262
+ lt(major, minor) {
45263
+ return this.major < major || this.major === major && this.minor < minor;
45264
+ }
45265
+ gte(major, minor) {
45266
+ return this.major > major || this.major === major && this.minor >= minor;
45267
+ }
45268
+ };
45269
+ var TOML_VERSION_1_0 = new TOMLVerImpl(1, 0);
45270
+ var TOML_VERSION_1_1 = new TOMLVerImpl(1, 1);
45271
+ var DEFAULT_TOML_VERSION = TOML_VERSION_1_1;
45272
+ var SUPPORTED_TOML_VERSIONS = {
45273
+ "1.0": TOML_VERSION_1_0,
45274
+ "1.0.0": TOML_VERSION_1_0,
45275
+ "1.1": TOML_VERSION_1_1,
45276
+ "1.1.0": TOML_VERSION_1_1,
45277
+ latest: TOML_VERSION_1_1,
45278
+ next: TOML_VERSION_1_1
45279
+ };
45280
+ function getTOMLVer(v) {
45281
+ return v && SUPPORTED_TOML_VERSIONS[v] || DEFAULT_TOML_VERSION;
45282
+ }
45283
+ var MESSAGES = {
45284
+ "unterminated-string": "Unterminated string constant",
45285
+ "unterminated-table-key": "Unterminated table-key",
45286
+ "unterminated-array": "Unterminated array",
45287
+ "unterminated-inline-table": "Unterminated inline table",
45288
+ "missing-key": "Empty bare keys are not allowed",
45289
+ "missing-newline": "Must be a newline",
45290
+ "missing-equals-sign": "Expected equal (=) token",
45291
+ "missing-value": "Unspecified values are invalid",
45292
+ "missing-comma": "Expected comma (,) token",
45293
+ "dupe-keys": "Defining a key multiple times is invalid",
45294
+ "unexpected-char": "Unexpected character",
45295
+ "unexpected-token": "Unexpected token",
45296
+ "invalid-control-character": "Control characters (codes < 0x1f and 0x7f) are not allowed",
45297
+ "invalid-comment-character": "Invalid code point {{cp}} within comments",
45298
+ "invalid-key-value-newline": "The key, equals sign, and value must be on the same line",
45299
+ "invalid-inline-table-newline": "No newlines are allowed between the curly braces unless they are valid within a value",
45300
+ "invalid-underscore": "Underscores are allowed between digits",
45301
+ "invalid-space": "Unexpected spaces",
45302
+ "invalid-three-quotes": "Three or more quotes are not permitted",
45303
+ "invalid-date": "Unexpected invalid date",
45304
+ "invalid-time": "Unexpected invalid time",
45305
+ "invalid-leading-zero": "Leading zeros are not allowed",
45306
+ "invalid-trailing-comma-in-inline-table": "Trailing comma is not permitted in an inline table",
45307
+ "invalid-char-in-escape-sequence": "Invalid character in escape sequence",
45308
+ "invalid-consecutive-dots-in-key": "Consecutive dots are not permitted in keys",
45309
+ "invalid-code-point": "Invalid code point {{cp}}",
45310
+ "invalid-trailing-dot-in-key": "Keys cannot end with a dot",
45311
+ "invalid-leading-dot-in-key": "Keys cannot start with a dot"
45312
+ };
45313
+ function getMessage(code, data) {
45314
+ if (data) return MESSAGES[code].replace(/\{\{(.*?)\}\}/gu, (_, name$2) => {
45315
+ if (name$2 in data) return data[name$2];
45316
+ return `{{${name$2}}}`;
45317
+ });
45318
+ return MESSAGES[code];
45319
+ }
45320
+ var ParseError = class extends SyntaxError {
45321
+ /**
45322
+ * Initialize this ParseError instance.
45323
+ *
45324
+ */
45325
+ constructor(code, offset, line, column, data) {
45326
+ super(getMessage(code, data));
45327
+ this.index = offset;
45328
+ this.lineNumber = line;
45329
+ this.column = column;
45330
+ }
45331
+ };
45332
+ var CodePoint = {
45333
+ EOF: -1,
45334
+ NULL: 0,
45335
+ SOH: 1,
45336
+ BACKSPACE: 8,
45337
+ TABULATION: 9,
45338
+ LINE_FEED: 10,
45339
+ FORM_FEED: 12,
45340
+ CARRIAGE_RETURN: 13,
45341
+ ESCAPE: 27,
45342
+ SO: 14,
45343
+ US: 31,
45344
+ SPACE: 32,
45345
+ QUOTATION_MARK: 34,
45346
+ HASH: 35,
45347
+ SINGLE_QUOTE: 39,
45348
+ PLUS_SIGN: 43,
45349
+ COMMA: 44,
45350
+ DASH: 45,
45351
+ DOT: 46,
45352
+ DIGIT_0: 48,
45353
+ DIGIT_1: 49,
45354
+ DIGIT_2: 50,
45355
+ DIGIT_3: 51,
45356
+ DIGIT_7: 55,
45357
+ DIGIT_9: 57,
45358
+ COLON: 58,
45359
+ EQUALS_SIGN: 61,
45360
+ LATIN_CAPITAL_A: 65,
45361
+ LATIN_CAPITAL_E: 69,
45362
+ LATIN_CAPITAL_F: 70,
45363
+ LATIN_CAPITAL_T: 84,
45364
+ LATIN_CAPITAL_U: 85,
45365
+ LATIN_CAPITAL_Z: 90,
45366
+ LEFT_BRACKET: 91,
45367
+ BACKSLASH: 92,
45368
+ RIGHT_BRACKET: 93,
45369
+ UNDERSCORE: 95,
45370
+ LATIN_SMALL_A: 97,
45371
+ LATIN_SMALL_B: 98,
45372
+ LATIN_SMALL_E: 101,
45373
+ LATIN_SMALL_F: 102,
45374
+ LATIN_SMALL_I: 105,
45375
+ LATIN_SMALL_L: 108,
45376
+ LATIN_SMALL_N: 110,
45377
+ LATIN_SMALL_O: 111,
45378
+ LATIN_SMALL_R: 114,
45379
+ LATIN_SMALL_S: 115,
45380
+ LATIN_SMALL_T: 116,
45381
+ LATIN_SMALL_U: 117,
45382
+ LATIN_SMALL_X: 120,
45383
+ LATIN_SMALL_Z: 122,
45384
+ LEFT_BRACE: 123,
45385
+ RIGHT_BRACE: 125,
45386
+ TILDE: 126,
45387
+ DELETE: 127,
45388
+ PAD: 128,
45389
+ SUPERSCRIPT_TWO: 178,
45390
+ SUPERSCRIPT_THREE: 179,
45391
+ SUPERSCRIPT_ONE: 185,
45392
+ VULGAR_FRACTION_ONE_QUARTER: 188,
45393
+ VULGAR_FRACTION_THREE_QUARTERS: 190,
45394
+ LATIN_CAPITAL_LETTER_A_WITH_GRAVE: 192,
45395
+ LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS: 214,
45396
+ LATIN_CAPITAL_LETTER_O_WITH_STROKE: 216,
45397
+ LATIN_SMALL_LETTER_O_WITH_DIAERESIS: 246,
45398
+ LATIN_SMALL_LETTER_O_WITH_STROKE: 248,
45399
+ GREEK_SMALL_REVERSED_DOTTED_LUNATE_SIGMA_SYMBOL: 891,
45400
+ GREEK_CAPITAL_LETTER_YOT: 895,
45401
+ CP_1FFF: 8191,
45402
+ ZERO_WIDTH_NON_JOINER: 8204,
45403
+ ZERO_WIDTH_JOINER: 8205,
45404
+ UNDERTIE: 8255,
45405
+ CHARACTER_TIE: 8256,
45406
+ SUPERSCRIPT_ZERO: 8304,
45407
+ CP_218F: 8591,
45408
+ CIRCLED_DIGIT_ONE: 9312,
45409
+ NEGATIVE_CIRCLED_DIGIT_ZERO: 9471,
45410
+ GLAGOLITIC_CAPITAL_LETTER_AZU: 11264,
45411
+ CP_2FEF: 12271,
45412
+ IDEOGRAPHIC_COMMA: 12289,
45413
+ CP_D7FF: 55295,
45414
+ CP_E000: 57344,
45415
+ CJK_COMPATIBILITY_IDEOGRAPH_F900: 63744,
45416
+ ARABIC_LIGATURE_SALAAMUHU_ALAYNAA: 64975,
45417
+ ARABIC_LIGATURE_SALLA_USED_AS_KORANIC_STOP_SIGN_ISOLATED_FORM: 65008,
45418
+ REPLACEMENT_CHARACTER: 65533,
45419
+ LINEAR_B_SYLLABLE_B008_A: 65536,
45420
+ CP_EFFFF: 983039,
45421
+ CP_10FFFF: 1114111
45422
+ };
45423
+ function isControl(cp) {
45424
+ return cp >= CodePoint.NULL && cp <= CodePoint.US;
45425
+ }
45426
+ function isWhitespace(cp) {
45427
+ return cp === CodePoint.TABULATION || cp === CodePoint.SPACE;
45428
+ }
45429
+ function isEOL(cp) {
45430
+ return cp === CodePoint.LINE_FEED || cp === CodePoint.CARRIAGE_RETURN;
45431
+ }
45432
+ function isUpperLetter(cp) {
45433
+ return cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_Z;
45434
+ }
45435
+ function isLowerLetter(cp) {
45436
+ return cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_Z;
45437
+ }
45438
+ function isLetter2(cp) {
45439
+ return isLowerLetter(cp) || isUpperLetter(cp);
45440
+ }
45441
+ function isDigit(cp) {
45442
+ return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_9;
45443
+ }
45444
+ function isHexDig(cp) {
45445
+ return isDigit(cp) || cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_F || cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_F;
45446
+ }
45447
+ function isOctalDig(cp) {
45448
+ return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_7;
45449
+ }
45450
+ function isUnicodeScalarValue(cp) {
45451
+ return cp >= 0 && cp <= 55295 || cp >= 57344 && cp <= 1114111;
45452
+ }
45453
+ function sortedLastIndex(array4, value) {
45454
+ let low = 0;
45455
+ let high = array4.length;
45456
+ while (low < high) {
45457
+ const mid = low + high >>> 1;
45458
+ const val = array4[mid];
45459
+ if (val === value) return mid + 1;
45460
+ if (val < value) low = mid + 1;
45461
+ else high = mid;
45462
+ }
45463
+ return low;
45464
+ }
45465
+ var Locations = class {
45466
+ constructor() {
45467
+ this.offsets = [];
45468
+ }
45469
+ addOffset(offset) {
45470
+ for (let i = this.offsets.length - 1; i >= 0; i--) {
45471
+ const element = this.offsets[i];
45472
+ if (element === offset) return;
45473
+ if (element < offset) break;
45019
45474
  }
45020
- if (c === "/" && text[i + 1] === "/") {
45021
- while (i < text.length && text[i] !== "\n") i++;
45022
- out += "\n";
45023
- continue;
45475
+ this.offsets.push(offset);
45476
+ }
45477
+ /**
45478
+ * Calculate the location of the given index.
45479
+ * @param index The index to calculate their location.
45480
+ * @returns The location of the index.
45481
+ */
45482
+ getLocFromIndex(offset) {
45483
+ const line = sortedLastIndex(this.offsets, offset) + 1;
45484
+ return {
45485
+ line,
45486
+ column: offset - (line === 1 ? 0 : this.offsets[line - 2])
45487
+ };
45488
+ }
45489
+ };
45490
+ var CodePointIterator = class {
45491
+ /**
45492
+ * Initialize this char iterator.
45493
+ */
45494
+ constructor(text) {
45495
+ this.locs = new Locations();
45496
+ this.lastCodePoint = CodePoint.NULL;
45497
+ this.start = -1;
45498
+ this.end = 0;
45499
+ this.text = text;
45500
+ }
45501
+ next() {
45502
+ if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
45503
+ return this.lastCodePoint = this.moveAt(this.end);
45504
+ }
45505
+ getLocFromIndex(index) {
45506
+ return this.locs.getLocFromIndex(index);
45507
+ }
45508
+ eat(cp) {
45509
+ if (this.text.codePointAt(this.end) === cp) {
45510
+ this.next();
45511
+ return true;
45024
45512
  }
45025
- if (c === "/" && text[i + 1] === "*") {
45026
- const end = text.indexOf("*/", i + 2);
45027
- i = end === -1 ? text.length : end + 1;
45028
- continue;
45513
+ return false;
45514
+ }
45515
+ moveAt(offset) {
45516
+ this.start = this.end = offset;
45517
+ const cp = this.text.codePointAt(this.start) ?? CodePoint.EOF;
45518
+ if (cp === CodePoint.EOF) {
45519
+ this.end = this.start;
45520
+ return cp;
45521
+ }
45522
+ this.end += cp >= 65536 ? 2 : 1;
45523
+ if (cp === CodePoint.LINE_FEED) this.locs.addOffset(this.end);
45524
+ else if (cp === CodePoint.CARRIAGE_RETURN) {
45525
+ if (this.text.codePointAt(this.end) === CodePoint.LINE_FEED) {
45526
+ this.end++;
45527
+ this.locs.addOffset(this.end);
45528
+ }
45529
+ return CodePoint.LINE_FEED;
45530
+ }
45531
+ return cp;
45532
+ }
45533
+ };
45534
+ var HAS_BIGINT = typeof BigInt !== "undefined";
45535
+ var RADIX_PREFIXES = {
45536
+ 16: "0x",
45537
+ 10: "",
45538
+ 8: "0o",
45539
+ 2: "0b"
45540
+ };
45541
+ var ESCAPES_1_0 = {
45542
+ [CodePoint.QUOTATION_MARK]: CodePoint.QUOTATION_MARK,
45543
+ [CodePoint.BACKSLASH]: CodePoint.BACKSLASH,
45544
+ [CodePoint.LATIN_SMALL_B]: CodePoint.BACKSPACE,
45545
+ [CodePoint.LATIN_SMALL_F]: CodePoint.FORM_FEED,
45546
+ [CodePoint.LATIN_SMALL_N]: CodePoint.LINE_FEED,
45547
+ [CodePoint.LATIN_SMALL_R]: CodePoint.CARRIAGE_RETURN,
45548
+ [CodePoint.LATIN_SMALL_T]: CodePoint.TABULATION
45549
+ };
45550
+ var ESCAPES_LATEST = {
45551
+ ...ESCAPES_1_0,
45552
+ [CodePoint.LATIN_SMALL_E]: CodePoint.ESCAPE
45553
+ };
45554
+ var Tokenizer = class {
45555
+ /**
45556
+ * Initialize this tokenizer.
45557
+ */
45558
+ constructor(text, parserOptions) {
45559
+ this.backCode = false;
45560
+ this.lastCodePoint = CodePoint.NULL;
45561
+ this.state = "DATA";
45562
+ this.token = null;
45563
+ this.tokenStart = -1;
45564
+ this.valuesEnabled = false;
45565
+ this.text = text;
45566
+ this.parserOptions = parserOptions || {};
45567
+ this.codePointIterator = new CodePointIterator(text);
45568
+ this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
45569
+ this.ESCAPES = this.tomlVersion.gte(1, 1) ? ESCAPES_LATEST : ESCAPES_1_0;
45570
+ }
45571
+ get start() {
45572
+ return this.codePointIterator.start;
45573
+ }
45574
+ get end() {
45575
+ return this.codePointIterator.end;
45576
+ }
45577
+ getLocFromIndex(index) {
45578
+ return this.codePointIterator.getLocFromIndex(index);
45579
+ }
45580
+ /**
45581
+ * Report an invalid character error.
45582
+ */
45583
+ reportParseError(code, data) {
45584
+ const offset = this.codePointIterator.start;
45585
+ const loc = this.codePointIterator.getLocFromIndex(offset);
45586
+ throw new ParseError(code, offset, loc.line, loc.column, data);
45587
+ }
45588
+ /**
45589
+ * Get the next token.
45590
+ */
45591
+ nextToken() {
45592
+ let token = this.token;
45593
+ if (token != null) {
45594
+ this.token = null;
45595
+ return token;
45596
+ }
45597
+ let cp = this.lastCodePoint;
45598
+ while (cp !== CodePoint.EOF && !this.token) {
45599
+ cp = this.nextCode();
45600
+ const nextState = this[this.state](cp);
45601
+ if (!nextState) throw new Error(`Unknown error: pre state=${this.state}`);
45602
+ this.state = nextState;
45603
+ }
45604
+ token = this.token;
45605
+ this.token = null;
45606
+ return token;
45607
+ }
45608
+ /**
45609
+ * Get the next code point.
45610
+ */
45611
+ nextCode() {
45612
+ if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
45613
+ if (this.backCode) {
45614
+ this.backCode = false;
45615
+ return this.lastCodePoint;
45029
45616
  }
45030
- if (c === ",") {
45031
- let j = i + 1;
45032
- while (j < text.length && " \r\n".includes(text[j])) j++;
45033
- if (text[j] === "}" || text[j] === "]") continue;
45617
+ return this.lastCodePoint = this.codePointIterator.next();
45618
+ }
45619
+ /**
45620
+ * Eat the next code point.
45621
+ */
45622
+ eatCode(cp) {
45623
+ if (this.lastCodePoint === CodePoint.EOF) return false;
45624
+ if (this.backCode) {
45625
+ if (this.lastCodePoint === cp) {
45626
+ this.backCode = false;
45627
+ return true;
45628
+ }
45629
+ return false;
45034
45630
  }
45035
- out += c;
45631
+ return this.codePointIterator.eat(cp);
45036
45632
  }
45037
- return out;
45038
- }
45039
- function readJson(file2) {
45040
- try {
45041
- return JSON.parse(stripJsonc(readFileSync4(file2, "utf8")));
45042
- } catch {
45043
- return void 0;
45633
+ /**
45634
+ * Moves the character position to the given position.
45635
+ */
45636
+ moveAt(loc) {
45637
+ if (this.backCode) this.backCode = false;
45638
+ this.lastCodePoint = this.codePointIterator.moveAt(loc);
45044
45639
  }
45045
- }
45046
- function readText(file2) {
45047
- try {
45048
- return readFileSync4(file2, "utf8");
45049
- } catch {
45050
- return "";
45640
+ /**
45641
+ * Back the current code point as the given state.
45642
+ */
45643
+ back(state) {
45644
+ this.backCode = true;
45645
+ return state;
45051
45646
  }
45052
- }
45053
- var listOf = (v) => Array.isArray(v) ? v : [];
45054
- var commandOf = (v) => isObj(v) && typeof v.command === "string" ? v.command : null;
45055
- function nestedCommands(doc) {
45056
- const out = [];
45057
- if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out;
45058
- for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
45059
- listOf(groups).forEach((group, i) => {
45060
- if (!isObj(group)) return;
45061
- listOf(group[HOOKS_KEY]).forEach((inner, j) => {
45062
- const command = commandOf(inner);
45063
- if (command !== null) out.push({ path: keyPath(HOOKS_KEY, event, i, HOOKS_KEY, j), command });
45064
- });
45065
- });
45647
+ punctuatorToken() {
45648
+ this.startToken();
45649
+ this.endToken("Punctuator", "end");
45066
45650
  }
45067
- return out;
45068
- }
45069
- function flatCommands(events, prefix) {
45070
- const out = [];
45071
- if (!isObj(events)) return out;
45072
- for (const [event, entries] of Object.entries(events)) {
45073
- listOf(entries).forEach((entry, i) => {
45074
- const command = commandOf(entry);
45075
- if (command !== null) out.push({ path: keyPath(...prefix, event, i), command });
45076
- });
45651
+ startToken() {
45652
+ this.tokenStart = this.codePointIterator.start;
45077
45653
  }
45078
- return out;
45079
- }
45080
- var isV1Hook = (cmd) => cmd.includes(SERVER_KEY) && (V1_SCRIPT_NAMES.some((name) => cmd.includes(name)) || cmd.includes(V1_HOOK_COMMAND));
45081
- var isCodexScript = (cmd) => cmd.includes(V1_SCRIPT_EXT) && V1_PATH_SEPS.some((sep2) => cmd.includes(V1_CODEX_HOOKS_DIR.join(sep2) + sep2));
45082
- function dataDir(dir, reason, out) {
45083
- if (existsSync4(dir)) out.push(finding(dir, "", reason));
45084
- }
45085
- function mcpEntry(file2, doc, out) {
45086
- if (isObj(doc) && isObj(doc[MCP_SERVERS_KEY]) && Object.hasOwn(doc[MCP_SERVERS_KEY], SERVER_KEY)) {
45087
- out.push(finding(file2, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
45654
+ /**
45655
+ * Commit the current token.
45656
+ */
45657
+ endToken(type, pos, option1, option2) {
45658
+ const { tokenStart } = this;
45659
+ const end = this.codePointIterator[pos];
45660
+ const range = [tokenStart, end];
45661
+ const loc = {
45662
+ start: this.codePointIterator.getLocFromIndex(tokenStart),
45663
+ end: this.codePointIterator.getLocFromIndex(end)
45664
+ };
45665
+ if (type === "Block") this.token = {
45666
+ type,
45667
+ value: this.text.slice(tokenStart + 1, end),
45668
+ range,
45669
+ loc
45670
+ };
45671
+ else {
45672
+ let token;
45673
+ const value = this.text.slice(tokenStart, end);
45674
+ if (type === "BasicString" || type === "LiteralString" || type === "MultiLineBasicString" || type === "MultiLineLiteralString") token = {
45675
+ type,
45676
+ value,
45677
+ string: option1,
45678
+ range,
45679
+ loc
45680
+ };
45681
+ else if (type === "Integer") {
45682
+ const text = option1;
45683
+ token = {
45684
+ type,
45685
+ value,
45686
+ number: parseInt(text, option2),
45687
+ bigint: HAS_BIGINT ? BigInt(RADIX_PREFIXES[option2] + text) : null,
45688
+ range,
45689
+ loc
45690
+ };
45691
+ } else if (type === "Float") token = {
45692
+ type,
45693
+ value,
45694
+ number: option1,
45695
+ range,
45696
+ loc
45697
+ };
45698
+ else if (type === "Boolean") token = {
45699
+ type,
45700
+ value,
45701
+ boolean: option1,
45702
+ range,
45703
+ loc
45704
+ };
45705
+ else if (type === "LocalDate" || type === "LocalTime" || type === "LocalDateTime" || type === "OffsetDateTime") token = {
45706
+ type,
45707
+ value,
45708
+ date: option1,
45709
+ range,
45710
+ loc
45711
+ };
45712
+ else token = {
45713
+ type,
45714
+ value,
45715
+ range,
45716
+ loc
45717
+ };
45718
+ this.token = token;
45719
+ }
45088
45720
  }
45089
- }
45090
- function claudeShapeSettings(agentHome, out) {
45091
- const file2 = join6(agentHome, SETTINGS_FILE);
45092
- const doc = readJson(file2);
45093
- for (const c of nestedCommands(doc)) {
45094
- if (c.command.includes(V1_CACHE_HEAL_NAME)) out.push(finding(file2, c.path, V1_REASON.cacheHealHook));
45095
- else if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.hook));
45721
+ DATA(cp) {
45722
+ while (isWhitespace(cp) || isEOL(cp)) cp = this.nextCode();
45723
+ if (cp === CodePoint.HASH) {
45724
+ this.startToken();
45725
+ return "COMMENT";
45726
+ }
45727
+ if (cp === CodePoint.QUOTATION_MARK) {
45728
+ this.startToken();
45729
+ return "BASIC_STRING";
45730
+ }
45731
+ if (cp === CodePoint.SINGLE_QUOTE) {
45732
+ this.startToken();
45733
+ return "LITERAL_STRING";
45734
+ }
45735
+ 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) {
45736
+ this.punctuatorToken();
45737
+ return "DATA";
45738
+ }
45739
+ if (this.valuesEnabled) {
45740
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
45741
+ this.startToken();
45742
+ return "SIGN";
45743
+ }
45744
+ if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) {
45745
+ this.startToken();
45746
+ return this.back("NAN_OR_INF");
45747
+ }
45748
+ if (isDigit(cp)) {
45749
+ this.startToken();
45750
+ return this.back("NUMBER");
45751
+ }
45752
+ if (cp === CodePoint.LATIN_SMALL_T || cp === CodePoint.LATIN_SMALL_F) {
45753
+ this.startToken();
45754
+ return this.back("BOOLEAN");
45755
+ }
45756
+ } else if (isUnquotedKeyChar(cp, this.tomlVersion)) {
45757
+ this.startToken();
45758
+ return "BARE";
45759
+ }
45760
+ if (cp === CodePoint.EOF) return "DATA";
45761
+ return this.reportParseError("unexpected-char");
45096
45762
  }
45097
- const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
45098
- if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
45099
- out.push(finding(file2, STATUS_LINE_KEY, V1_REASON.statusLine));
45763
+ COMMENT(cp) {
45764
+ const processCommentChar = this.tomlVersion.gte(1, 1) ? (c) => {
45765
+ if (!isNonEOL(c)) this.reportParseError("invalid-comment-character", { cp: JSON.stringify(String.fromCodePoint(c)).slice(1, -1) });
45766
+ } : (c) => {
45767
+ if (isControlOtherThanTab(c)) this.reportParseErrorControlChar();
45768
+ };
45769
+ while (!isEOL(cp) && cp !== CodePoint.EOF) {
45770
+ processCommentChar(cp);
45771
+ cp = this.nextCode();
45772
+ }
45773
+ this.endToken("Block", "start");
45774
+ return "DATA";
45100
45775
  }
45101
- mcpEntry(file2, doc, out);
45776
+ BARE(cp) {
45777
+ while (isUnquotedKeyChar(cp, this.tomlVersion)) cp = this.nextCode();
45778
+ this.endToken("Bare", "start");
45779
+ return this.back("DATA");
45780
+ }
45781
+ BASIC_STRING(cp) {
45782
+ if (cp === CodePoint.QUOTATION_MARK) {
45783
+ cp = this.nextCode();
45784
+ if (cp === CodePoint.QUOTATION_MARK) return "MULTI_LINE_BASIC_STRING";
45785
+ this.endToken("BasicString", "start", "");
45786
+ return this.back("DATA");
45787
+ }
45788
+ const out = [];
45789
+ while (cp !== CodePoint.QUOTATION_MARK && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
45790
+ if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45791
+ if (cp === CodePoint.BACKSLASH) {
45792
+ cp = this.nextCode();
45793
+ const ecp = this.ESCAPES[cp];
45794
+ if (ecp) {
45795
+ out.push(ecp);
45796
+ cp = this.nextCode();
45797
+ continue;
45798
+ } else if (cp === CodePoint.LATIN_SMALL_U) {
45799
+ const code = this.parseUnicode(4);
45800
+ out.push(code);
45801
+ cp = this.nextCode();
45802
+ continue;
45803
+ } else if (cp === CodePoint.LATIN_CAPITAL_U) {
45804
+ const code = this.parseUnicode(8);
45805
+ out.push(code);
45806
+ cp = this.nextCode();
45807
+ continue;
45808
+ } else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
45809
+ const code = this.parseUnicode(2);
45810
+ out.push(code);
45811
+ cp = this.nextCode();
45812
+ continue;
45813
+ }
45814
+ return this.reportParseError("invalid-char-in-escape-sequence");
45815
+ }
45816
+ out.push(cp);
45817
+ cp = this.nextCode();
45818
+ }
45819
+ if (cp !== CodePoint.QUOTATION_MARK) return this.reportParseError("unterminated-string");
45820
+ this.endToken("BasicString", "end", String.fromCodePoint(...out));
45821
+ return "DATA";
45822
+ }
45823
+ MULTI_LINE_BASIC_STRING(cp) {
45824
+ const out = [];
45825
+ if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
45826
+ while (cp !== CodePoint.EOF) {
45827
+ if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45828
+ if (cp === CodePoint.QUOTATION_MARK) {
45829
+ const startPos = this.codePointIterator.start;
45830
+ if (this.eatCode(CodePoint.QUOTATION_MARK) && this.eatCode(CodePoint.QUOTATION_MARK)) {
45831
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45832
+ out.push(CodePoint.QUOTATION_MARK);
45833
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45834
+ out.push(CodePoint.QUOTATION_MARK);
45835
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45836
+ this.moveAt(startPos);
45837
+ return this.reportParseError("invalid-three-quotes");
45838
+ }
45839
+ }
45840
+ }
45841
+ this.endToken("MultiLineBasicString", "end", String.fromCodePoint(...out));
45842
+ return "DATA";
45843
+ }
45844
+ this.moveAt(startPos);
45845
+ }
45846
+ if (cp === CodePoint.BACKSLASH) {
45847
+ cp = this.nextCode();
45848
+ const ecp = this.ESCAPES[cp];
45849
+ if (ecp) {
45850
+ out.push(ecp);
45851
+ cp = this.nextCode();
45852
+ continue;
45853
+ } else if (cp === CodePoint.LATIN_SMALL_U) {
45854
+ const code = this.parseUnicode(4);
45855
+ out.push(code);
45856
+ cp = this.nextCode();
45857
+ continue;
45858
+ } else if (cp === CodePoint.LATIN_CAPITAL_U) {
45859
+ const code = this.parseUnicode(8);
45860
+ out.push(code);
45861
+ cp = this.nextCode();
45862
+ continue;
45863
+ } else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
45864
+ const code = this.parseUnicode(2);
45865
+ out.push(code);
45866
+ cp = this.nextCode();
45867
+ continue;
45868
+ } else if (cp === CodePoint.LINE_FEED) {
45869
+ cp = this.nextCode();
45870
+ while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
45871
+ continue;
45872
+ } else if (isWhitespace(cp)) {
45873
+ let valid = true;
45874
+ const startPos = this.codePointIterator.start;
45875
+ let nextCp;
45876
+ while ((nextCp = this.nextCode()) !== CodePoint.EOF) {
45877
+ if (nextCp === CodePoint.LINE_FEED) break;
45878
+ if (!isWhitespace(nextCp)) {
45879
+ this.moveAt(startPos);
45880
+ valid = false;
45881
+ break;
45882
+ }
45883
+ }
45884
+ if (valid) {
45885
+ cp = this.nextCode();
45886
+ while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
45887
+ continue;
45888
+ }
45889
+ }
45890
+ return this.reportParseError("invalid-char-in-escape-sequence");
45891
+ }
45892
+ out.push(cp);
45893
+ cp = this.nextCode();
45894
+ }
45895
+ return this.reportParseError("unterminated-string");
45896
+ }
45897
+ LITERAL_STRING(cp) {
45898
+ if (cp === CodePoint.SINGLE_QUOTE) {
45899
+ cp = this.nextCode();
45900
+ if (cp === CodePoint.SINGLE_QUOTE) return "MULTI_LINE_LITERAL_STRING";
45901
+ this.endToken("LiteralString", "start", "");
45902
+ return this.back("DATA");
45903
+ }
45904
+ const out = [];
45905
+ while (cp !== CodePoint.SINGLE_QUOTE && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
45906
+ if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45907
+ out.push(cp);
45908
+ cp = this.nextCode();
45909
+ }
45910
+ if (cp !== CodePoint.SINGLE_QUOTE) return this.reportParseError("unterminated-string");
45911
+ this.endToken("LiteralString", "end", String.fromCodePoint(...out));
45912
+ return "DATA";
45913
+ }
45914
+ MULTI_LINE_LITERAL_STRING(cp) {
45915
+ const out = [];
45916
+ if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
45917
+ while (cp !== CodePoint.EOF) {
45918
+ if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45919
+ if (cp === CodePoint.SINGLE_QUOTE) {
45920
+ const startPos = this.codePointIterator.start;
45921
+ if (this.eatCode(CodePoint.SINGLE_QUOTE) && this.eatCode(CodePoint.SINGLE_QUOTE)) {
45922
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45923
+ out.push(CodePoint.SINGLE_QUOTE);
45924
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45925
+ out.push(CodePoint.SINGLE_QUOTE);
45926
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45927
+ this.moveAt(startPos);
45928
+ return this.reportParseError("invalid-three-quotes");
45929
+ }
45930
+ }
45931
+ }
45932
+ this.endToken("MultiLineLiteralString", "end", String.fromCodePoint(...out));
45933
+ return "DATA";
45934
+ }
45935
+ this.moveAt(startPos);
45936
+ }
45937
+ out.push(cp);
45938
+ cp = this.nextCode();
45939
+ }
45940
+ return this.reportParseError("unterminated-string");
45941
+ }
45942
+ SIGN(cp) {
45943
+ if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) return this.back("NAN_OR_INF");
45944
+ if (isDigit(cp)) return this.back("NUMBER");
45945
+ return this.reportParseError("unexpected-char");
45946
+ }
45947
+ NAN_OR_INF(cp) {
45948
+ if (cp === CodePoint.LATIN_SMALL_N) {
45949
+ const startPos = this.codePointIterator.start;
45950
+ if (this.eatCode(CodePoint.LATIN_SMALL_A) && this.eatCode(CodePoint.LATIN_SMALL_N)) {
45951
+ this.endToken("Float", "end", NaN);
45952
+ return "DATA";
45953
+ }
45954
+ this.moveAt(startPos);
45955
+ } else if (cp === CodePoint.LATIN_SMALL_I) {
45956
+ const startPos = this.codePointIterator.start;
45957
+ if (this.eatCode(CodePoint.LATIN_SMALL_N) && this.eatCode(CodePoint.LATIN_SMALL_F)) {
45958
+ this.endToken("Float", "end", this.text[this.tokenStart] === "-" ? -Infinity : Infinity);
45959
+ return "DATA";
45960
+ }
45961
+ this.moveAt(startPos);
45962
+ }
45963
+ return this.reportParseError("unexpected-char");
45964
+ }
45965
+ NUMBER(cp) {
45966
+ const start = this.text[this.tokenStart];
45967
+ const sign = start === "+" ? CodePoint.PLUS_SIGN : start === "-" ? CodePoint.DASH : CodePoint.NULL;
45968
+ if (cp === CodePoint.DIGIT_0) {
45969
+ if (sign === CodePoint.NULL) {
45970
+ const startPos = this.codePointIterator.start;
45971
+ const nextCp$1 = this.nextCode();
45972
+ if (isDigit(nextCp$1)) {
45973
+ const nextNextCp = this.nextCode();
45974
+ if (nextNextCp === CodePoint.COLON) {
45975
+ this.data = {
45976
+ hasDate: false,
45977
+ year: 0,
45978
+ month: 0,
45979
+ day: 0,
45980
+ hour: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1)),
45981
+ minute: 0,
45982
+ second: 0
45983
+ };
45984
+ return "TIME_MINUTE";
45985
+ }
45986
+ if (isDigit(nextNextCp)) {
45987
+ const nextNextNextCp = this.nextCode();
45988
+ if (isDigit(nextNextNextCp) && this.eatCode(CodePoint.DASH)) {
45989
+ this.data = {
45990
+ hasDate: true,
45991
+ year: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1, nextNextCp, nextNextNextCp)),
45992
+ month: 0,
45993
+ day: 0,
45994
+ hour: 0,
45995
+ minute: 0,
45996
+ second: 0
45997
+ };
45998
+ return "DATE_MONTH";
45999
+ }
46000
+ }
46001
+ this.moveAt(startPos);
46002
+ return this.reportParseError("invalid-leading-zero");
46003
+ }
46004
+ this.moveAt(startPos);
46005
+ }
46006
+ cp = this.nextCode();
46007
+ if (cp === CodePoint.LATIN_SMALL_X || cp === CodePoint.LATIN_SMALL_O || cp === CodePoint.LATIN_SMALL_B) {
46008
+ if (sign !== CodePoint.NULL) return this.reportParseError("unexpected-char");
46009
+ return cp === CodePoint.LATIN_SMALL_X ? "HEX" : cp === CodePoint.LATIN_SMALL_O ? "OCTAL" : "BINARY";
46010
+ }
46011
+ if (cp === CodePoint.LATIN_SMALL_E || cp === CodePoint.LATIN_CAPITAL_E) {
46012
+ this.data = {
46013
+ minus: sign === CodePoint.DASH,
46014
+ left: [CodePoint.DIGIT_0]
46015
+ };
46016
+ return "EXPONENT_RIGHT";
46017
+ }
46018
+ if (cp === CodePoint.DOT) {
46019
+ this.data = {
46020
+ minus: sign === CodePoint.DASH,
46021
+ absInt: [CodePoint.DIGIT_0]
46022
+ };
46023
+ return "FRACTIONAL_RIGHT";
46024
+ }
46025
+ this.endToken("Integer", "start", "0", 10);
46026
+ return this.back("DATA");
46027
+ }
46028
+ const { out, nextCp, hasUnderscore } = this.parseDigits(cp, isDigit);
46029
+ if (nextCp === CodePoint.DASH && sign === CodePoint.NULL && !hasUnderscore && out.length === 4) {
46030
+ this.data = {
46031
+ hasDate: true,
46032
+ year: Number(String.fromCodePoint(...out)),
46033
+ month: 0,
46034
+ day: 0,
46035
+ hour: 0,
46036
+ minute: 0,
46037
+ second: 0
46038
+ };
46039
+ return "DATE_MONTH";
46040
+ }
46041
+ if (nextCp === CodePoint.COLON && sign === CodePoint.NULL && !hasUnderscore && out.length === 2) {
46042
+ this.data = {
46043
+ hasDate: false,
46044
+ year: 0,
46045
+ month: 0,
46046
+ day: 0,
46047
+ hour: Number(String.fromCodePoint(...out)),
46048
+ minute: 0,
46049
+ second: 0
46050
+ };
46051
+ return "TIME_MINUTE";
46052
+ }
46053
+ if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
46054
+ this.data = {
46055
+ minus: sign === CodePoint.DASH,
46056
+ left: out
46057
+ };
46058
+ return "EXPONENT_RIGHT";
46059
+ }
46060
+ if (nextCp === CodePoint.DOT) {
46061
+ this.data = {
46062
+ minus: sign === CodePoint.DASH,
46063
+ absInt: out
46064
+ };
46065
+ return "FRACTIONAL_RIGHT";
46066
+ }
46067
+ this.endToken("Integer", "start", sign === CodePoint.DASH ? String.fromCodePoint(CodePoint.DASH, ...out) : String.fromCodePoint(...out), 10);
46068
+ return this.back("DATA");
46069
+ }
46070
+ HEX(cp) {
46071
+ const { out } = this.parseDigits(cp, isHexDig);
46072
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 16);
46073
+ return this.back("DATA");
46074
+ }
46075
+ OCTAL(cp) {
46076
+ const { out } = this.parseDigits(cp, isOctalDig);
46077
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 8);
46078
+ return this.back("DATA");
46079
+ }
46080
+ BINARY(cp) {
46081
+ const { out } = this.parseDigits(cp, (c) => c === CodePoint.DIGIT_0 || c === CodePoint.DIGIT_1);
46082
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 2);
46083
+ return this.back("DATA");
46084
+ }
46085
+ FRACTIONAL_RIGHT(cp) {
46086
+ const { minus, absInt } = this.data;
46087
+ const { out, nextCp } = this.parseDigits(cp, isDigit);
46088
+ const absNum = [
46089
+ ...absInt,
46090
+ CodePoint.DOT,
46091
+ ...out
46092
+ ];
46093
+ if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
46094
+ this.data = {
46095
+ minus,
46096
+ left: absNum
46097
+ };
46098
+ return "EXPONENT_RIGHT";
46099
+ }
46100
+ const value = Number(minus ? String.fromCodePoint(CodePoint.DASH, ...absNum) : String.fromCodePoint(...absNum));
46101
+ this.endToken("Float", "start", value);
46102
+ return this.back("DATA");
46103
+ }
46104
+ EXPONENT_RIGHT(cp) {
46105
+ const { left, minus: leftMinus } = this.data;
46106
+ let minus = false;
46107
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
46108
+ minus = cp === CodePoint.DASH;
46109
+ cp = this.nextCode();
46110
+ }
46111
+ const { out } = this.parseDigits(cp, isDigit);
46112
+ const right = out;
46113
+ if (minus) right.unshift(CodePoint.DASH);
46114
+ const value = Number(leftMinus ? String.fromCodePoint(CodePoint.DASH, ...left, CodePoint.LATIN_SMALL_E, ...right) : String.fromCodePoint(...left, CodePoint.LATIN_SMALL_E, ...right));
46115
+ this.endToken("Float", "start", value);
46116
+ return this.back("DATA");
46117
+ }
46118
+ BOOLEAN(cp) {
46119
+ if (cp === CodePoint.LATIN_SMALL_T) {
46120
+ const startPos = this.codePointIterator.start;
46121
+ if (this.eatCode(CodePoint.LATIN_SMALL_R) && this.eatCode(CodePoint.LATIN_SMALL_U) && this.eatCode(CodePoint.LATIN_SMALL_E)) {
46122
+ this.endToken("Boolean", "end", true);
46123
+ return "DATA";
46124
+ }
46125
+ this.moveAt(startPos);
46126
+ } else if (cp === CodePoint.LATIN_SMALL_F) {
46127
+ const startPos = this.codePointIterator.start;
46128
+ 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)) {
46129
+ this.endToken("Boolean", "end", false);
46130
+ return "DATA";
46131
+ }
46132
+ this.moveAt(startPos);
46133
+ }
46134
+ return this.reportParseError("unexpected-char");
46135
+ }
46136
+ DATE_MONTH(cp) {
46137
+ const start = this.codePointIterator.start;
46138
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46139
+ cp = this.nextCode();
46140
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46141
+ cp = this.nextCode();
46142
+ if (cp !== CodePoint.DASH) return this.reportParseError("unexpected-char");
46143
+ const end = this.codePointIterator.start;
46144
+ const data = this.data;
46145
+ data.month = Number(this.text.slice(start, end));
46146
+ return "DATE_DAY";
46147
+ }
46148
+ DATE_DAY(cp) {
46149
+ const start = this.codePointIterator.start;
46150
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46151
+ cp = this.nextCode();
46152
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46153
+ const end = this.codePointIterator.end;
46154
+ const data = this.data;
46155
+ data.day = Number(this.text.slice(start, end));
46156
+ if (!isValidDate(data.year, data.month, data.day)) return this.reportParseError("invalid-date");
46157
+ cp = this.nextCode();
46158
+ if (cp === CodePoint.LATIN_CAPITAL_T || cp === CodePoint.LATIN_SMALL_T) return "TIME_HOUR";
46159
+ if (cp === CodePoint.SPACE) {
46160
+ const startPos = this.codePointIterator.start;
46161
+ if (isDigit(this.nextCode()) && isDigit(this.nextCode())) {
46162
+ this.moveAt(startPos);
46163
+ return "TIME_HOUR";
46164
+ }
46165
+ this.moveAt(startPos);
46166
+ }
46167
+ const dateValue = getDateFromDateTimeData(data, "");
46168
+ this.endToken("LocalDate", "start", dateValue);
46169
+ return this.back("DATA");
46170
+ }
46171
+ TIME_HOUR(cp) {
46172
+ const start = this.codePointIterator.start;
46173
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46174
+ cp = this.nextCode();
46175
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46176
+ cp = this.nextCode();
46177
+ if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
46178
+ const end = this.codePointIterator.start;
46179
+ const data = this.data;
46180
+ data.hour = Number(this.text.slice(start, end));
46181
+ return "TIME_MINUTE";
46182
+ }
46183
+ TIME_MINUTE(cp) {
46184
+ const start = this.codePointIterator.start;
46185
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46186
+ cp = this.nextCode();
46187
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46188
+ const end = this.codePointIterator.end;
46189
+ const data = this.data;
46190
+ data.minute = Number(this.text.slice(start, end));
46191
+ cp = this.nextCode();
46192
+ if (cp === CodePoint.COLON) return "TIME_SECOND";
46193
+ if (this.tomlVersion.lt(1, 1)) return this.reportParseError("unexpected-char");
46194
+ if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
46195
+ return this.processTimeEnd(cp, data);
46196
+ }
46197
+ TIME_SECOND(cp) {
46198
+ const start = this.codePointIterator.start;
46199
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46200
+ cp = this.nextCode();
46201
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46202
+ const end = this.codePointIterator.end;
46203
+ const data = this.data;
46204
+ data.second = Number(this.text.slice(start, end));
46205
+ if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
46206
+ cp = this.nextCode();
46207
+ if (cp === CodePoint.DOT) return "TIME_SEC_FRAC";
46208
+ return this.processTimeEnd(cp, data);
46209
+ }
46210
+ TIME_SEC_FRAC(cp) {
46211
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46212
+ const start = this.codePointIterator.start;
46213
+ while (isDigit(cp)) cp = this.nextCode();
46214
+ const end = this.codePointIterator.start;
46215
+ const data = this.data;
46216
+ data.frac = this.text.slice(start, end);
46217
+ return this.processTimeEnd(cp, data);
46218
+ }
46219
+ processTimeEnd(cp, data) {
46220
+ if (data.hasDate) {
46221
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
46222
+ data.offsetSign = cp;
46223
+ return "TIME_OFFSET";
46224
+ }
46225
+ if (cp === CodePoint.LATIN_CAPITAL_Z || cp === CodePoint.LATIN_SMALL_Z) {
46226
+ const dateValue$2 = getDateFromDateTimeData(data, "Z");
46227
+ this.endToken("OffsetDateTime", "end", dateValue$2);
46228
+ return "DATA";
46229
+ }
46230
+ const dateValue$1 = getDateFromDateTimeData(data, "");
46231
+ this.endToken("LocalDateTime", "start", dateValue$1);
46232
+ return this.back("DATA");
46233
+ }
46234
+ const dateValue = getDateFromDateTimeData(data, "");
46235
+ this.endToken("LocalTime", "start", dateValue);
46236
+ return this.back("DATA");
46237
+ }
46238
+ TIME_OFFSET(cp) {
46239
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46240
+ const hourStart = this.codePointIterator.start;
46241
+ cp = this.nextCode();
46242
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46243
+ cp = this.nextCode();
46244
+ if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
46245
+ const hourEnd = this.codePointIterator.start;
46246
+ cp = this.nextCode();
46247
+ const minuteStart = this.codePointIterator.start;
46248
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46249
+ cp = this.nextCode();
46250
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46251
+ const minuteEnd = this.codePointIterator.end;
46252
+ const hour = Number(this.text.slice(hourStart, hourEnd));
46253
+ const minute = Number(this.text.slice(minuteStart, minuteEnd));
46254
+ if (!isValidTime(hour, minute, 0)) return this.reportParseError("invalid-time");
46255
+ const data = this.data;
46256
+ const dateValue = getDateFromDateTimeData(data, `${String.fromCodePoint(data.offsetSign)}${padStart(hour, 2)}:${padStart(minute, 2)}`);
46257
+ this.endToken("OffsetDateTime", "end", dateValue);
46258
+ return "DATA";
46259
+ }
46260
+ parseDigits(cp, checkDigit) {
46261
+ if (cp === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46262
+ if (!checkDigit(cp)) return this.reportParseError("unexpected-char");
46263
+ const out = [];
46264
+ let before = CodePoint.NULL;
46265
+ let hasUnderscore = false;
46266
+ while (checkDigit(cp) || cp === CodePoint.UNDERSCORE) {
46267
+ if (cp === CodePoint.UNDERSCORE) {
46268
+ hasUnderscore = true;
46269
+ if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46270
+ } else out.push(cp);
46271
+ before = cp;
46272
+ cp = this.nextCode();
46273
+ }
46274
+ if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46275
+ return {
46276
+ out,
46277
+ nextCp: cp,
46278
+ hasUnderscore
46279
+ };
46280
+ }
46281
+ parseUnicode(count) {
46282
+ const startLoc = this.codePointIterator.start;
46283
+ const start = this.codePointIterator.end;
46284
+ let charCount = 0;
46285
+ let cp;
46286
+ while ((cp = this.nextCode()) !== CodePoint.EOF) {
46287
+ if (!isHexDig(cp)) {
46288
+ this.moveAt(startLoc);
46289
+ return this.reportParseError("invalid-char-in-escape-sequence");
46290
+ }
46291
+ charCount++;
46292
+ if (charCount >= count) break;
46293
+ }
46294
+ const end = this.codePointIterator.end;
46295
+ const code = this.text.slice(start, end);
46296
+ const codePoint = parseInt(code, 16);
46297
+ if (!isUnicodeScalarValue(codePoint)) return this.reportParseError("invalid-code-point", { cp: code });
46298
+ return codePoint;
46299
+ }
46300
+ reportParseErrorControlChar() {
46301
+ return this.reportParseError("invalid-control-character");
46302
+ }
46303
+ };
46304
+ function isUnquotedKeyChar(cp, tomlVersion) {
46305
+ if (isLetter2(cp) || isDigit(cp) || cp === CodePoint.UNDERSCORE || cp === CodePoint.DASH) return true;
46306
+ if (tomlVersion.lt(1, 1)) return false;
46307
+ return false;
45102
46308
  }
45103
- function v1HookFile(file2, out) {
45104
- const doc = readJson(file2);
45105
- const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
45106
- if (cmds.some((c) => c.command.includes(V1_HOOK_COMMAND))) out.push(finding(file2, "", V1_REASON.hookFile));
46309
+ function isControlOtherThanTab(cp) {
46310
+ return isControl(cp) && cp !== CodePoint.TABULATION || cp === CodePoint.DELETE;
45107
46311
  }
45108
- function scanClaudeCode(home, agentHome, out) {
45109
- claudeShapeSettings(agentHome, out);
45110
- for (const ext of V1_CACHE_HEAL_EXTS) {
45111
- const file2 = join6(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
45112
- if (existsSync4(file2)) out.push(finding(file2, "", V1_REASON.cacheHealFile));
46312
+ function isNonEOL(cp) {
46313
+ return cp === CodePoint.TABULATION || CodePoint.SPACE <= cp && cp <= CodePoint.TILDE || isNonAscii(cp);
46314
+ }
46315
+ function isNonAscii(cp) {
46316
+ return CodePoint.PAD <= cp && cp <= CodePoint.CP_D7FF || CodePoint.CP_E000 <= cp && cp <= CodePoint.CP_10FFFF;
46317
+ }
46318
+ function isValidDate(y, m, d) {
46319
+ if (y >= 0 && m <= 12 && m >= 1 && d >= 1) return d <= (m === 2 ? y & 3 || !(y % 25) && y & 15 ? 28 : 29 : 30 + (m + (m >> 3) & 1));
46320
+ return false;
46321
+ }
46322
+ function isValidTime(h, m, s) {
46323
+ if (h >= 24 || h < 0 || m > 59 || m < 0 || s > 60 || s < 0) return false;
46324
+ return true;
46325
+ }
46326
+ function getDateFromDateTimeData(data, timeZone) {
46327
+ const year = padStart(data.year, 4);
46328
+ const month = data.month ? padStart(data.month, 2) : "01";
46329
+ const day = data.day ? padStart(data.day, 2) : "01";
46330
+ const hour = padStart(data.hour, 2);
46331
+ const minute = padStart(data.minute, 2);
46332
+ const second = padStart(data.second, 2);
46333
+ const textDate = `${year}-${month}-${day}`;
46334
+ const frac = data.frac ? `.${data.frac}` : "";
46335
+ const dateValue = /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:${second}${frac}${timeZone}`);
46336
+ if (!isNaN(dateValue.getTime()) || data.second !== 60) return dateValue;
46337
+ return /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:59${frac}${timeZone}`);
46338
+ }
46339
+ function padStart(num, maxLength) {
46340
+ return String(num).padStart(maxLength, "0");
46341
+ }
46342
+ var VALUE_KIND_VALUE = Symbol("VALUE_KIND_VALUE");
46343
+ var VALUE_KIND_INTERMEDIATE = Symbol("VALUE_KIND_INTERMEDIATE");
46344
+ var KeysResolver = class {
46345
+ constructor(ctx) {
46346
+ this.rootKeys = /* @__PURE__ */ new Map();
46347
+ this.tables = [];
46348
+ this.ctx = ctx;
46349
+ }
46350
+ applyResolveKeyForTable(node3) {
46351
+ let keys = this.rootKeys;
46352
+ const peekKeyIndex = node3.key.keys.length - 1;
46353
+ for (let index = 0; index < peekKeyIndex; index++) {
46354
+ const keyNode = node3.key.keys[index];
46355
+ const keyName = toKeyName(keyNode);
46356
+ node3.resolvedKey.push(keyName);
46357
+ let keyStore = keys.get(keyName);
46358
+ if (!keyStore) {
46359
+ keyStore = {
46360
+ node: keyNode,
46361
+ keys: /* @__PURE__ */ new Map()
46362
+ };
46363
+ keys.set(keyName, keyStore);
46364
+ } else if (keyStore.table === "array") {
46365
+ const peekIndex = keyStore.peekIndex;
46366
+ node3.resolvedKey.push(peekIndex);
46367
+ keyStore = keyStore.keys.get(peekIndex);
46368
+ }
46369
+ keys = keyStore.keys;
46370
+ }
46371
+ const lastKeyNode = node3.key.keys[peekKeyIndex];
46372
+ const lastKeyName = toKeyName(lastKeyNode);
46373
+ node3.resolvedKey.push(lastKeyName);
46374
+ const lastKeyStore = keys.get(lastKeyName);
46375
+ if (!lastKeyStore) if (node3.kind === "array") {
46376
+ node3.resolvedKey.push(0);
46377
+ const newKeyStore = {
46378
+ node: lastKeyNode,
46379
+ keys: /* @__PURE__ */ new Map()
46380
+ };
46381
+ keys.set(lastKeyName, {
46382
+ table: node3.kind,
46383
+ node: lastKeyNode,
46384
+ keys: /* @__PURE__ */ new Map([[0, newKeyStore]]),
46385
+ peekIndex: 0
46386
+ });
46387
+ this.tables.push({
46388
+ node: node3,
46389
+ keys: newKeyStore.keys
46390
+ });
46391
+ } else {
46392
+ const newKeyStore = {
46393
+ table: node3.kind,
46394
+ node: lastKeyNode,
46395
+ keys: /* @__PURE__ */ new Map()
46396
+ };
46397
+ keys.set(lastKeyName, newKeyStore);
46398
+ this.tables.push({
46399
+ node: node3,
46400
+ keys: newKeyStore.keys
46401
+ });
46402
+ }
46403
+ else if (!lastKeyStore.table) if (node3.kind === "array") this.ctx.reportParseError("dupe-keys", lastKeyNode);
46404
+ else {
46405
+ const transformKey = {
46406
+ table: node3.kind,
46407
+ node: lastKeyNode,
46408
+ keys: lastKeyStore.keys
46409
+ };
46410
+ keys.set(lastKeyName, transformKey);
46411
+ this.tables.push({
46412
+ node: node3,
46413
+ keys: transformKey.keys
46414
+ });
46415
+ }
46416
+ else if (lastKeyStore.table === "array") if (node3.kind === "array") {
46417
+ const newKeyStore = {
46418
+ node: lastKeyNode,
46419
+ keys: /* @__PURE__ */ new Map()
46420
+ };
46421
+ const newIndex = lastKeyStore.peekIndex + 1;
46422
+ node3.resolvedKey.push(newIndex);
46423
+ lastKeyStore.keys.set(newIndex, newKeyStore);
46424
+ lastKeyStore.peekIndex = newIndex;
46425
+ this.tables.push({
46426
+ node: node3,
46427
+ keys: newKeyStore.keys
46428
+ });
46429
+ } else this.ctx.reportParseError("dupe-keys", lastKeyNode);
46430
+ else this.ctx.reportParseError("dupe-keys", lastKeyNode);
46431
+ }
46432
+ verifyDuplicateKeys(node3) {
46433
+ for (const body of node3.body) if (body.type === "TOMLKeyValue") verifyDuplicateKeysForKeyValue(this.ctx, this.rootKeys, body);
46434
+ for (const { node: tableNode, keys } of this.tables) for (const body of tableNode.body) verifyDuplicateKeysForKeyValue(this.ctx, keys, body);
46435
+ }
46436
+ };
46437
+ function verifyDuplicateKeysForKeyValue(ctx, defineKeys, node3) {
46438
+ let keys = defineKeys;
46439
+ const lastKey = last(node3.key.keys);
46440
+ for (const keyNode of node3.key.keys) {
46441
+ const key = toKeyName(keyNode);
46442
+ let defineKey = keys.get(key);
46443
+ if (defineKey) {
46444
+ if (defineKey.value === VALUE_KIND_VALUE) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46445
+ else if (lastKey === keyNode) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46446
+ else if (defineKey.table) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46447
+ defineKey.value = VALUE_KIND_INTERMEDIATE;
46448
+ } else {
46449
+ if (lastKey === keyNode) defineKey = {
46450
+ value: VALUE_KIND_VALUE,
46451
+ node: keyNode,
46452
+ keys: /* @__PURE__ */ new Map()
46453
+ };
46454
+ else defineKey = {
46455
+ value: VALUE_KIND_INTERMEDIATE,
46456
+ node: keyNode,
46457
+ keys: /* @__PURE__ */ new Map()
46458
+ };
46459
+ keys.set(key, defineKey);
46460
+ }
46461
+ keys = defineKey.keys;
45113
46462
  }
45114
- const userFile = join6(home, CLAUDE_USER_CONFIG_FILE);
45115
- mcpEntry(userFile, readJson(userFile), out);
45116
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
46463
+ if (node3.value.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, keys, node3.value);
46464
+ else if (node3.value.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, keys, node3.value);
45117
46465
  }
45118
- function scanCodex(agentHome, out) {
45119
- const hooksFile = join6(agentHome, HOOKS_JSON_FILE);
45120
- for (const c of nestedCommands(readJson(hooksFile))) {
45121
- if (c.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c.command)) {
45122
- out.push(finding(hooksFile, c.path, V1_REASON.codexHook));
46466
+ function verifyDuplicateKeysForInlineTable(ctx, defineKeys, node3) {
46467
+ for (const body of node3.body) verifyDuplicateKeysForKeyValue(ctx, defineKeys, body);
46468
+ }
46469
+ function verifyDuplicateKeysForArray(ctx, defineKeys, node3) {
46470
+ const keys = defineKeys;
46471
+ for (let index = 0; index < node3.elements.length; index++) {
46472
+ const element = node3.elements[index];
46473
+ let defineKey = keys.get(index);
46474
+ if (defineKey) ctx.reportParseError("dupe-keys", getAfterNode(element, defineKey.node));
46475
+ else {
46476
+ defineKey = {
46477
+ value: VALUE_KIND_VALUE,
46478
+ node: element,
46479
+ keys: /* @__PURE__ */ new Map()
46480
+ };
46481
+ defineKeys.set(index, defineKey);
46482
+ if (element.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, defineKey.keys, element);
46483
+ else if (element.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, defineKey.keys, element);
46484
+ }
46485
+ }
46486
+ }
46487
+ function getAfterNode(a, b) {
46488
+ return a.range[0] <= b.range[0] ? b : a;
46489
+ }
46490
+ var Context = class {
46491
+ constructor(data) {
46492
+ this.tokens = [];
46493
+ this.comments = [];
46494
+ this.back = null;
46495
+ this.stateStack = [];
46496
+ this.needNewLine = false;
46497
+ this.needSameLine = false;
46498
+ this.currToken = null;
46499
+ this.prevToken = null;
46500
+ this.valueContainerStack = [];
46501
+ this.tokenizer = new Tokenizer(data.text, data.parserOptions);
46502
+ this.topLevelTable = data.topLevelTable;
46503
+ this.table = data.topLevelTable;
46504
+ this.keysResolver = new KeysResolver(this);
46505
+ }
46506
+ /**
46507
+ * Get the next token.
46508
+ */
46509
+ nextToken(option) {
46510
+ this.prevToken = this.currToken;
46511
+ if (this.back) {
46512
+ this.currToken = this.back;
46513
+ this.back = null;
46514
+ } else this.currToken = this._nextTokenFromTokenizer(option);
46515
+ if ((this.needNewLine || this.needSameLine || option?.needSameLine) && this.prevToken && this.currToken) if (this.prevToken.loc.end.line === this.currToken.loc.start.line) {
46516
+ if (this.needNewLine) return this.reportParseError("missing-newline", this.currToken);
46517
+ } else {
46518
+ const needSameLine = this.needSameLine || option?.needSameLine;
46519
+ if (needSameLine) return this.reportParseError(needSameLine, this.currToken);
45123
46520
  }
46521
+ this.needNewLine = false;
46522
+ this.needSameLine = false;
46523
+ return this.currToken;
45124
46524
  }
45125
- const tomlFile = join6(agentHome, CONFIG_TOML_FILE);
45126
- for (const line of readText(tomlFile).split("\n")) {
45127
- const header = line.trim();
45128
- if (header.startsWith(V1_TOML_SECTION_PREFIX)) out.push(finding(tomlFile, header, V1_REASON.codexToml));
46525
+ _nextTokenFromTokenizer(option) {
46526
+ const valuesEnabled = this.tokenizer.valuesEnabled;
46527
+ if (option?.valuesEnabled) this.tokenizer.valuesEnabled = option.valuesEnabled;
46528
+ let token = this.tokenizer.nextToken();
46529
+ while (token && token.type === "Block") {
46530
+ this.comments.push(token);
46531
+ token = this.tokenizer.nextToken();
46532
+ }
46533
+ if (token) this.tokens.push(token);
46534
+ this.tokenizer.valuesEnabled = valuesEnabled;
46535
+ return token;
45129
46536
  }
45130
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
45131
- }
45132
- function scanGemini(agentHome, out) {
45133
- const file2 = join6(agentHome, SETTINGS_FILE);
45134
- for (const c of nestedCommands(readJson(file2))) {
45135
- if (c.command.includes(SERVER_KEY)) out.push(finding(file2, c.path, V1_REASON.hook));
46537
+ backToken() {
46538
+ if (this.back) throw new Error("Illegal state");
46539
+ this.back = this.currToken;
46540
+ this.currToken = this.prevToken;
45136
46541
  }
45137
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out);
45138
- }
45139
- function scanVscode(agentHome, project, out) {
45140
- if (project !== void 0) {
45141
- v1HookFile(join6(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
45142
- const mcpFile2 = join6(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
45143
- const doc = readJson(mcpFile2);
45144
- const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
45145
- const entry = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
45146
- if (isObj(entry) && (entry.command === V1_BIN_COMMAND || listOf(entry.args).some((a) => a === V1_BIN_COMMAND))) {
45147
- out.push(finding(mcpFile2, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
46542
+ addValueContainer(valueContainer) {
46543
+ this.valueContainerStack.push(valueContainer);
46544
+ this.tokenizer.valuesEnabled = true;
46545
+ }
46546
+ consumeValueContainer() {
46547
+ const valueContainer = this.valueContainerStack.pop();
46548
+ this.tokenizer.valuesEnabled = this.valueContainerStack.length > 0;
46549
+ return valueContainer;
46550
+ }
46551
+ applyResolveKeyForTable(node3) {
46552
+ this.keysResolver.applyResolveKeyForTable(node3);
46553
+ }
46554
+ verifyDuplicateKeys() {
46555
+ this.keysResolver.verifyDuplicateKeys(this.topLevelTable);
46556
+ }
46557
+ /**
46558
+ * Report an invalid token error.
46559
+ */
46560
+ reportParseError(code, token) {
46561
+ let offset, line, column;
46562
+ if (token) {
46563
+ offset = token.range[0];
46564
+ line = token.loc.start.line;
46565
+ column = token.loc.start.column;
46566
+ } else {
46567
+ offset = this.tokenizer.start;
46568
+ const startPos = this.tokenizer.getLocFromIndex(offset);
46569
+ line = startPos.line;
46570
+ column = startPos.column;
45148
46571
  }
45149
- dataDir(join6(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
46572
+ throw new ParseError(code, offset, line, column);
45150
46573
  }
45151
- dataDir(join6(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
45152
- }
45153
- function jsonFiles(dir) {
45154
- try {
45155
- return readdirSync3(dir).filter((name) => name.endsWith(KIRO_AGENT_FILE_EXT)).sort();
45156
- } catch {
46574
+ };
46575
+ var STATE_FOR_ERROR = { VALUE: "missing-value" };
46576
+ var STRING_VALUE_STYLE_MAP = {
46577
+ BasicString: "basic",
46578
+ MultiLineBasicString: "basic",
46579
+ LiteralString: "literal",
46580
+ MultiLineLiteralString: "literal"
46581
+ };
46582
+ var STRING_KEY_STYLE_MAP = {
46583
+ BasicString: "basic",
46584
+ LiteralString: "literal"
46585
+ };
46586
+ var DATETIME_VALUE_KIND_MAP = {
46587
+ OffsetDateTime: "offset-date-time",
46588
+ LocalDateTime: "local-date-time",
46589
+ LocalDate: "local-date",
46590
+ LocalTime: "local-time"
46591
+ };
46592
+ var TOMLParser = class {
46593
+ /**
46594
+ * Initialize this parser.
46595
+ */
46596
+ constructor(text, parserOptions) {
46597
+ this.text = text;
46598
+ this.parserOptions = parserOptions || {};
46599
+ this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
46600
+ }
46601
+ /**
46602
+ * Parse TOML
46603
+ */
46604
+ parse() {
46605
+ const ast = {
46606
+ type: "Program",
46607
+ body: [],
46608
+ sourceType: "module",
46609
+ tokens: [],
46610
+ comments: [],
46611
+ parent: null,
46612
+ range: [0, 0],
46613
+ loc: {
46614
+ start: {
46615
+ line: 1,
46616
+ column: 0
46617
+ },
46618
+ end: {
46619
+ line: 1,
46620
+ column: 0
46621
+ }
46622
+ }
46623
+ };
46624
+ const node3 = {
46625
+ type: "TOMLTopLevelTable",
46626
+ body: [],
46627
+ parent: ast,
46628
+ range: cloneRange(ast.range),
46629
+ loc: cloneLoc(ast.loc)
46630
+ };
46631
+ ast.body = [node3];
46632
+ const ctx = new Context({
46633
+ text: this.text,
46634
+ parserOptions: this.parserOptions,
46635
+ topLevelTable: node3
46636
+ });
46637
+ let token = ctx.nextToken();
46638
+ if (token) {
46639
+ node3.range[0] = token.range[0];
46640
+ node3.loc.start = clonePos(token.loc.start);
46641
+ while (token) {
46642
+ const state$1 = ctx.stateStack.pop() || "TABLE";
46643
+ ctx.stateStack.push(...this[state$1](token, ctx));
46644
+ token = ctx.nextToken();
46645
+ }
46646
+ const state = ctx.stateStack.pop() || "TABLE";
46647
+ if (state in STATE_FOR_ERROR) return ctx.reportParseError(STATE_FOR_ERROR[state], null);
46648
+ if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
46649
+ applyEndLoc(node3, last(node3.body));
46650
+ }
46651
+ ctx.verifyDuplicateKeys();
46652
+ ast.tokens = ctx.tokens;
46653
+ ast.comments = ctx.comments;
46654
+ const endOffset = ctx.tokenizer.end;
46655
+ const endPos = ctx.tokenizer.getLocFromIndex(endOffset);
46656
+ ast.range[1] = endOffset;
46657
+ ast.loc.end = {
46658
+ line: endPos.line,
46659
+ column: endPos.column
46660
+ };
46661
+ return ast;
46662
+ }
46663
+ TABLE(token, ctx) {
46664
+ if (isBare(token) || isString(token)) return this.processKeyValue(token, ctx.table, ctx);
46665
+ if (isLeftBracket(token)) return this.processTable(token, ctx.topLevelTable, ctx);
46666
+ return ctx.reportParseError("unexpected-token", token);
46667
+ }
46668
+ VALUE(token, ctx) {
46669
+ if (isString(token) || isMultiLineString(token)) return this.processStringValue(token, ctx);
46670
+ if (isNumber(token)) return this.processNumberValue(token, ctx);
46671
+ if (isBoolean(token)) return this.processBooleanValue(token, ctx);
46672
+ if (isDateTime(token)) return this.processDateTimeValue(token, ctx);
46673
+ if (isLeftBracket(token)) return this.processArray(token, ctx);
46674
+ if (isLeftBrace(token)) return this.processInlineTable(token, ctx);
46675
+ return ctx.reportParseError("unexpected-token", token);
46676
+ }
46677
+ processTable(token, topLevelTableNode, ctx) {
46678
+ const tableNode = {
46679
+ type: "TOMLTable",
46680
+ kind: "standard",
46681
+ key: null,
46682
+ resolvedKey: [],
46683
+ body: [],
46684
+ parent: topLevelTableNode,
46685
+ range: cloneRange(token.range),
46686
+ loc: cloneLoc(token.loc)
46687
+ };
46688
+ if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
46689
+ topLevelTableNode.body.push(tableNode);
46690
+ ctx.table = tableNode;
46691
+ let targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46692
+ if (isLeftBracket(targetToken)) {
46693
+ if (token.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
46694
+ tableNode.kind = "array";
46695
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46696
+ }
46697
+ if (isRightBracket(targetToken)) return ctx.reportParseError("missing-key", targetToken);
46698
+ if (!targetToken) return ctx.reportParseError("unterminated-table-key", null);
46699
+ targetToken = this.processKeyNode(targetToken, tableNode, ctx).nextToken;
46700
+ if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
46701
+ if (tableNode.kind === "array") {
46702
+ const rightBracket = targetToken;
46703
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46704
+ if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
46705
+ if (rightBracket.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
46706
+ }
46707
+ applyEndLoc(tableNode, targetToken);
46708
+ ctx.applyResolveKeyForTable(tableNode);
46709
+ ctx.needNewLine = true;
45157
46710
  return [];
45158
46711
  }
46712
+ processKeyValue(token, tableNode, ctx) {
46713
+ const keyValueNode = {
46714
+ type: "TOMLKeyValue",
46715
+ key: null,
46716
+ value: null,
46717
+ parent: tableNode,
46718
+ range: cloneRange(token.range),
46719
+ loc: cloneLoc(token.loc)
46720
+ };
46721
+ tableNode.body.push(keyValueNode);
46722
+ const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
46723
+ if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
46724
+ ctx.addValueContainer({
46725
+ parent: keyValueNode,
46726
+ set: (valNode) => {
46727
+ keyValueNode.value = valNode;
46728
+ applyEndLoc(keyValueNode, valNode);
46729
+ ctx.needNewLine = true;
46730
+ return [];
46731
+ }
46732
+ });
46733
+ ctx.needSameLine = "invalid-key-value-newline";
46734
+ return ["VALUE"];
46735
+ }
46736
+ processKeyNode(token, parent, ctx) {
46737
+ if (isDot(token)) ctx.reportParseError("invalid-leading-dot-in-key", token);
46738
+ const keyNode = {
46739
+ type: "TOMLKey",
46740
+ keys: [],
46741
+ parent,
46742
+ range: cloneRange(token.range),
46743
+ loc: cloneLoc(token.loc)
46744
+ };
46745
+ parent.key = keyNode;
46746
+ let targetToken = token;
46747
+ let dotToken = null;
46748
+ do {
46749
+ if (isBare(targetToken)) this.processBareKey(targetToken, keyNode);
46750
+ else if (isString(targetToken)) this.processStringKey(targetToken, keyNode);
46751
+ else break;
46752
+ dotToken = null;
46753
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46754
+ if (!isDot(targetToken)) break;
46755
+ dotToken = targetToken;
46756
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46757
+ } while (targetToken);
46758
+ if (dotToken) ctx.reportParseError(isDot(targetToken) ? "invalid-consecutive-dots-in-key" : "invalid-trailing-dot-in-key", dotToken);
46759
+ applyEndLoc(keyNode, last(keyNode.keys));
46760
+ return {
46761
+ keyNode,
46762
+ nextToken: targetToken
46763
+ };
46764
+ }
46765
+ processBareKey(token, keyNode) {
46766
+ const node3 = {
46767
+ type: "TOMLBare",
46768
+ name: token.value,
46769
+ parent: keyNode,
46770
+ range: cloneRange(token.range),
46771
+ loc: cloneLoc(token.loc)
46772
+ };
46773
+ keyNode.keys.push(node3);
46774
+ }
46775
+ processStringKey(token, keyNode) {
46776
+ const node3 = {
46777
+ type: "TOMLQuoted",
46778
+ kind: "string",
46779
+ value: token.string,
46780
+ style: STRING_KEY_STYLE_MAP[token.type],
46781
+ multiline: false,
46782
+ parent: keyNode,
46783
+ range: cloneRange(token.range),
46784
+ loc: cloneLoc(token.loc)
46785
+ };
46786
+ keyNode.keys.push(node3);
46787
+ }
46788
+ processStringValue(token, ctx) {
46789
+ const valueContainer = ctx.consumeValueContainer();
46790
+ const node3 = {
46791
+ type: "TOMLValue",
46792
+ kind: "string",
46793
+ value: token.string,
46794
+ style: STRING_VALUE_STYLE_MAP[token.type],
46795
+ multiline: isMultiLineString(token),
46796
+ parent: valueContainer.parent,
46797
+ range: cloneRange(token.range),
46798
+ loc: cloneLoc(token.loc)
46799
+ };
46800
+ return valueContainer.set(node3);
46801
+ }
46802
+ processNumberValue(token, ctx) {
46803
+ const valueContainer = ctx.consumeValueContainer();
46804
+ const text = this.text;
46805
+ const [startRange, endRange] = token.range;
46806
+ let numberString = null;
46807
+ const getNumberText = () => {
46808
+ return numberString ?? (numberString = text.slice(startRange, endRange).replace(/_/g, ""));
46809
+ };
46810
+ let node3;
46811
+ if (token.type === "Integer") node3 = {
46812
+ type: "TOMLValue",
46813
+ kind: "integer",
46814
+ value: token.number,
46815
+ bigint: token.bigint,
46816
+ get number() {
46817
+ return getNumberText();
46818
+ },
46819
+ parent: valueContainer.parent,
46820
+ range: cloneRange(token.range),
46821
+ loc: cloneLoc(token.loc)
46822
+ };
46823
+ else node3 = {
46824
+ type: "TOMLValue",
46825
+ kind: "float",
46826
+ value: token.number,
46827
+ get number() {
46828
+ return getNumberText();
46829
+ },
46830
+ parent: valueContainer.parent,
46831
+ range: cloneRange(token.range),
46832
+ loc: cloneLoc(token.loc)
46833
+ };
46834
+ return valueContainer.set(node3);
46835
+ }
46836
+ processBooleanValue(token, ctx) {
46837
+ const valueContainer = ctx.consumeValueContainer();
46838
+ const node3 = {
46839
+ type: "TOMLValue",
46840
+ kind: "boolean",
46841
+ value: token.boolean,
46842
+ parent: valueContainer.parent,
46843
+ range: cloneRange(token.range),
46844
+ loc: cloneLoc(token.loc)
46845
+ };
46846
+ return valueContainer.set(node3);
46847
+ }
46848
+ processDateTimeValue(token, ctx) {
46849
+ const valueContainer = ctx.consumeValueContainer();
46850
+ const node3 = {
46851
+ type: "TOMLValue",
46852
+ kind: DATETIME_VALUE_KIND_MAP[token.type],
46853
+ value: token.date,
46854
+ datetime: token.value,
46855
+ parent: valueContainer.parent,
46856
+ range: cloneRange(token.range),
46857
+ loc: cloneLoc(token.loc)
46858
+ };
46859
+ return valueContainer.set(node3);
46860
+ }
46861
+ processArray(token, ctx) {
46862
+ const valueContainer = ctx.consumeValueContainer();
46863
+ const node3 = {
46864
+ type: "TOMLArray",
46865
+ elements: [],
46866
+ parent: valueContainer.parent,
46867
+ range: cloneRange(token.range),
46868
+ loc: cloneLoc(token.loc)
46869
+ };
46870
+ const nextToken = ctx.nextToken({ valuesEnabled: true });
46871
+ if (isRightBracket(nextToken)) {
46872
+ applyEndLoc(node3, nextToken);
46873
+ return valueContainer.set(node3);
46874
+ }
46875
+ ctx.backToken();
46876
+ return this.processArrayValue(node3, valueContainer, ctx);
46877
+ }
46878
+ processArrayValue(node3, valueContainer, ctx) {
46879
+ ctx.addValueContainer({
46880
+ parent: node3,
46881
+ set: (valNode) => {
46882
+ node3.elements.push(valNode);
46883
+ let nextToken = ctx.nextToken({ valuesEnabled: true });
46884
+ const hasComma = isComma(nextToken);
46885
+ if (hasComma) nextToken = ctx.nextToken({ valuesEnabled: true });
46886
+ if (isRightBracket(nextToken)) {
46887
+ applyEndLoc(node3, nextToken);
46888
+ return valueContainer.set(node3);
46889
+ }
46890
+ if (hasComma) {
46891
+ ctx.backToken();
46892
+ return this.processArrayValue(node3, valueContainer, ctx);
46893
+ }
46894
+ return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-array", nextToken);
46895
+ }
46896
+ });
46897
+ return ["VALUE"];
46898
+ }
46899
+ processInlineTable(token, ctx) {
46900
+ const valueContainer = ctx.consumeValueContainer();
46901
+ const node3 = {
46902
+ type: "TOMLInlineTable",
46903
+ body: [],
46904
+ parent: valueContainer.parent,
46905
+ range: cloneRange(token.range),
46906
+ loc: cloneLoc(token.loc)
46907
+ };
46908
+ const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
46909
+ const nextToken = ctx.nextToken({ needSameLine });
46910
+ if (nextToken) {
46911
+ if (isBare(nextToken) || isString(nextToken)) return this.processInlineTableKeyValue(nextToken, node3, valueContainer, ctx);
46912
+ if (isRightBrace(nextToken)) {
46913
+ applyEndLoc(node3, nextToken);
46914
+ return valueContainer.set(node3);
46915
+ }
46916
+ }
46917
+ return ctx.reportParseError("unexpected-token", nextToken);
46918
+ }
46919
+ processInlineTableKeyValue(token, inlineTableNode, valueContainer, ctx) {
46920
+ const keyValueNode = {
46921
+ type: "TOMLKeyValue",
46922
+ key: null,
46923
+ value: null,
46924
+ parent: inlineTableNode,
46925
+ range: cloneRange(token.range),
46926
+ loc: cloneLoc(token.loc)
46927
+ };
46928
+ inlineTableNode.body.push(keyValueNode);
46929
+ const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
46930
+ if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
46931
+ const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
46932
+ ctx.addValueContainer({
46933
+ parent: keyValueNode,
46934
+ set: (valNode) => {
46935
+ keyValueNode.value = valNode;
46936
+ applyEndLoc(keyValueNode, valNode);
46937
+ let nextToken = ctx.nextToken({ needSameLine });
46938
+ if (isComma(nextToken)) {
46939
+ nextToken = ctx.nextToken({ needSameLine });
46940
+ if (nextToken && (isBare(nextToken) || isString(nextToken))) return this.processInlineTableKeyValue(nextToken, inlineTableNode, valueContainer, ctx);
46941
+ if (isRightBrace(nextToken)) {
46942
+ if (this.tomlVersion.lt(1, 1)) return ctx.reportParseError("invalid-trailing-comma-in-inline-table", nextToken);
46943
+ } else return ctx.reportParseError(nextToken ? "unexpected-token" : "unterminated-inline-table", nextToken);
46944
+ }
46945
+ if (isRightBrace(nextToken)) {
46946
+ applyEndLoc(inlineTableNode, nextToken);
46947
+ return valueContainer.set(inlineTableNode);
46948
+ }
46949
+ return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-inline-table", nextToken);
46950
+ }
46951
+ });
46952
+ ctx.needSameLine = "invalid-key-value-newline";
46953
+ return ["VALUE"];
46954
+ }
46955
+ };
46956
+ function isDot(token) {
46957
+ return isPunctuator(token) && token.value === ".";
45159
46958
  }
45160
- function scanKiro(agentHome, project, out) {
45161
- const agentsDir = join6(agentHome, KIRO_AGENTS_DIR);
45162
- const defaultFile = join6(agentHome, ...KIRO_AGENT_FILE);
45163
- for (const name of jsonFiles(agentsDir)) {
45164
- const file2 = join6(agentsDir, name);
45165
- const doc = readJson(file2);
45166
- if (isObj(doc) && doc[KIRO_AGENT_NAME_KEY] === SERVER_KEY) {
45167
- out.push(finding(file2, "", V1_REASON.kiroAgentFile));
45168
- continue;
46959
+ function isEq(token) {
46960
+ return isPunctuator(token) && token.value === "=";
46961
+ }
46962
+ function isLeftBracket(token) {
46963
+ return isPunctuator(token) && token.value === "[";
46964
+ }
46965
+ function isRightBracket(token) {
46966
+ return isPunctuator(token) && token.value === "]";
46967
+ }
46968
+ function isLeftBrace(token) {
46969
+ return isPunctuator(token) && token.value === "{";
46970
+ }
46971
+ function isRightBrace(token) {
46972
+ return isPunctuator(token) && token.value === "}";
46973
+ }
46974
+ function isComma(token) {
46975
+ return isPunctuator(token) && token.value === ",";
46976
+ }
46977
+ function isPunctuator(token) {
46978
+ return Boolean(token && token.type === "Punctuator");
46979
+ }
46980
+ function isBare(token) {
46981
+ return token.type === "Bare";
46982
+ }
46983
+ function isString(token) {
46984
+ return token.type === "BasicString" || token.type === "LiteralString";
46985
+ }
46986
+ function isMultiLineString(token) {
46987
+ return token.type === "MultiLineBasicString" || token.type === "MultiLineLiteralString";
46988
+ }
46989
+ function isNumber(token) {
46990
+ return token.type === "Integer" || token.type === "Float";
46991
+ }
46992
+ function isBoolean(token) {
46993
+ return token.type === "Boolean";
46994
+ }
46995
+ function isDateTime(token) {
46996
+ return token.type === "OffsetDateTime" || token.type === "LocalDateTime" || token.type === "LocalDate" || token.type === "LocalTime";
46997
+ }
46998
+ function applyEndLoc(node3, child) {
46999
+ if (child) {
47000
+ node3.range[1] = child.range[1];
47001
+ node3.loc.end = clonePos(child.loc.end);
47002
+ }
47003
+ }
47004
+ function cloneRange(range) {
47005
+ return [range[0], range[1]];
47006
+ }
47007
+ function cloneLoc(loc) {
47008
+ return {
47009
+ start: clonePos(loc.start),
47010
+ end: clonePos(loc.end)
47011
+ };
47012
+ }
47013
+ function clonePos(pos) {
47014
+ return {
47015
+ line: pos.line,
47016
+ column: pos.column
47017
+ };
47018
+ }
47019
+ var tomlKeys = {
47020
+ Program: ["body"],
47021
+ TOMLTopLevelTable: ["body"],
47022
+ TOMLTable: ["key", "body"],
47023
+ TOMLKeyValue: ["key", "value"],
47024
+ TOMLKey: ["keys"],
47025
+ TOMLArray: ["elements"],
47026
+ TOMLInlineTable: ["body"],
47027
+ TOMLBare: [],
47028
+ TOMLQuoted: [],
47029
+ TOMLValue: []
47030
+ };
47031
+ var KEYS3 = unionWith(tomlKeys);
47032
+ function parseForESLint(code, options) {
47033
+ return {
47034
+ ast: new TOMLParser(code, options).parse(),
47035
+ visitorKeys: KEYS3,
47036
+ services: { isTOML: true }
47037
+ };
47038
+ }
47039
+ var getStaticTOMLValue = generateConvertTOMLValue((node3) => node3.value);
47040
+ function generateConvertTOMLValue(convertValue) {
47041
+ function resolveValue(node3, baseTable) {
47042
+ return resolver[node3.type](node3, baseTable);
47043
+ }
47044
+ const resolver = {
47045
+ Program(node3, baseTable = {}) {
47046
+ return resolveValue(node3.body[0], baseTable);
47047
+ },
47048
+ TOMLTopLevelTable(node3, baseTable = {}) {
47049
+ for (const body of node3.body) resolveValue(body, baseTable);
47050
+ return baseTable;
47051
+ },
47052
+ TOMLKeyValue(node3, baseTable = {}) {
47053
+ const value = resolveValue(node3.value);
47054
+ set2(baseTable, resolveValue(node3.key), value);
47055
+ return baseTable;
47056
+ },
47057
+ TOMLTable(node3, baseTable = {}) {
47058
+ const table = getTable(baseTable, resolveValue(node3.key), node3.kind === "array");
47059
+ for (const body of node3.body) resolveValue(body, table);
47060
+ return baseTable;
47061
+ },
47062
+ TOMLArray(node3) {
47063
+ return node3.elements.map((e) => resolveValue(e));
47064
+ },
47065
+ TOMLInlineTable(node3) {
47066
+ const table = {};
47067
+ for (const body of node3.body) resolveValue(body, table);
47068
+ return table;
47069
+ },
47070
+ TOMLKey(node3) {
47071
+ return node3.keys.map((key) => resolveValue(key));
47072
+ },
47073
+ TOMLBare(node3) {
47074
+ return node3.name;
47075
+ },
47076
+ TOMLQuoted(node3) {
47077
+ return node3.value;
47078
+ },
47079
+ TOMLValue(node3) {
47080
+ return convertValue(node3);
47081
+ }
47082
+ };
47083
+ return (node3) => resolveValue(node3);
47084
+ }
47085
+ function getTable(baseTable, keys, array4) {
47086
+ let target = baseTable;
47087
+ for (let index = 0; index < keys.length - 1; index++) {
47088
+ const key = keys[index];
47089
+ target = getNextTargetFromKey(target, key);
47090
+ }
47091
+ const lastKey = last(keys);
47092
+ const lastTarget = target[lastKey];
47093
+ if (lastTarget == null) {
47094
+ const tableValue$1 = {};
47095
+ target[lastKey] = array4 ? [tableValue$1] : tableValue$1;
47096
+ return tableValue$1;
47097
+ }
47098
+ if (isValue(lastTarget)) {
47099
+ const tableValue$1 = {};
47100
+ target[lastKey] = array4 ? [tableValue$1] : tableValue$1;
47101
+ return tableValue$1;
47102
+ }
47103
+ if (!array4) {
47104
+ if (Array.isArray(lastTarget)) {
47105
+ const tableValue$1 = {};
47106
+ target[lastKey] = tableValue$1;
47107
+ return tableValue$1;
47108
+ }
47109
+ return lastTarget;
47110
+ }
47111
+ if (Array.isArray(lastTarget)) {
47112
+ const tableValue$1 = {};
47113
+ lastTarget.push(tableValue$1);
47114
+ return tableValue$1;
47115
+ }
47116
+ const tableValue = {};
47117
+ target[lastKey] = [tableValue];
47118
+ return tableValue;
47119
+ function getNextTargetFromKey(currTarget, key) {
47120
+ const nextTarget = currTarget[key];
47121
+ if (nextTarget == null) {
47122
+ const val = {};
47123
+ currTarget[key] = val;
47124
+ return val;
45169
47125
  }
45170
- if (file2 !== defaultFile) continue;
45171
- for (const c of isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : []) {
45172
- if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.kiroHook));
47126
+ if (isValue(nextTarget)) {
47127
+ const val = {};
47128
+ currTarget[key] = val;
47129
+ return val;
47130
+ }
47131
+ let resultTarget = nextTarget;
47132
+ while (Array.isArray(resultTarget)) {
47133
+ const lastIndex = resultTarget.length - 1;
47134
+ const nextElement = resultTarget[lastIndex];
47135
+ if (isValue(nextElement)) {
47136
+ const val = {};
47137
+ resultTarget[lastIndex] = val;
47138
+ return val;
47139
+ }
47140
+ resultTarget = nextElement;
45173
47141
  }
47142
+ return resultTarget;
45174
47143
  }
45175
- const steeringDocs = [join6(agentHome, ...KIRO_STEERING_FILE)];
45176
- if (project !== void 0) steeringDocs.push(join6(project, ...AGENT_HOME_DIR.kiro, ...KIRO_STEERING_FILE));
45177
- for (const file2 of steeringDocs) {
45178
- if (existsSync4(file2)) out.push(finding(file2, "", V1_REASON.kiroSteering));
47144
+ }
47145
+ function set2(baseTable, keys, value) {
47146
+ let target = baseTable;
47147
+ for (let index = 0; index < keys.length - 1; index++) {
47148
+ const key = keys[index];
47149
+ const nextTarget = target[key];
47150
+ if (nextTarget == null) {
47151
+ const val = {};
47152
+ target[key] = val;
47153
+ target = val;
47154
+ } else if (isValue(nextTarget) || Array.isArray(nextTarget)) {
47155
+ const val = {};
47156
+ target[key] = val;
47157
+ target = val;
47158
+ } else target = nextTarget;
45179
47159
  }
45180
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47160
+ target[last(keys)] = value;
45181
47161
  }
45182
- function scanPi(piAgentDir, agentHome, out) {
45183
- const file2 = join6(piAgentDir, SETTINGS_FILE);
45184
- const doc = readJson(file2);
45185
- listOf(isObj(doc) ? doc[PI_PACKAGES_KEY] : void 0).forEach((pkg, i) => {
45186
- const spec = isObj(pkg) ? pkg[PI_PACKAGE_SOURCE_KEY] : pkg;
45187
- if (spec === V1_PI_PACKAGE) out.push(finding(file2, keyPath(PI_PACKAGES_KEY, i), V1_REASON.piNpm));
45188
- });
45189
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47162
+ function isValue(value) {
47163
+ return typeof value !== "object" || value instanceof Date;
45190
47164
  }
45191
- function scanOpencode(agentHome, out) {
45192
- for (const name of OPENCODE_CONFIG_FILES) {
45193
- const file2 = join6(agentHome, name);
45194
- const doc = readJson(file2);
45195
- if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
45196
- doc[OPENCODE_PLUGIN_KEY].forEach((spec, i) => {
45197
- if (spec === V1_OPENCODE_PLUGIN_SPEC) out.push(finding(file2, keyPath(OPENCODE_PLUGIN_KEY, i), V1_REASON.opencodePlugin));
45198
- });
45199
- return;
45200
- }
47165
+ function parseTOML(code, options) {
47166
+ return parseForESLint(code, options).ast;
45201
47167
  }
45202
- function scanZcode(agentHome, out) {
45203
- const configFile = join6(agentHome, ZCODE_CLI_DIR, CONFIG_JSON_FILE);
45204
- const config4 = readJson(configFile);
45205
- const events = isObj(config4) && isObj(config4[HOOKS_KEY]) ? config4[HOOKS_KEY][ZCODE_EVENTS_KEY] : void 0;
45206
- for (const c of flatCommands(events, [HOOKS_KEY, ZCODE_EVENTS_KEY])) {
45207
- if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(configFile, c.path, V1_REASON.zcodeHook));
47168
+
47169
+ // src/core/ops/atomic-file.ts
47170
+ import { mkdirSync as mkdirSync4, renameSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
47171
+ import path3 from "node:path";
47172
+ function sleepSync(ms) {
47173
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
47174
+ }
47175
+ function errCode2(e) {
47176
+ return e.code;
47177
+ }
47178
+ function renameWithRetry(from, to, opts = {}) {
47179
+ const rename = opts.rename ?? renameSync;
47180
+ const sleep2 = opts.sleep ?? sleepSync;
47181
+ const win = (opts.platform ?? process.platform) === "win32";
47182
+ for (let attempt = 0; ; attempt += 1) {
47183
+ try {
47184
+ rename(from, to);
47185
+ return;
47186
+ } catch (e) {
47187
+ const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47188
+ if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw e;
47189
+ sleep2(ATOMIC_RENAME_DELAY_MS);
47190
+ }
45208
47191
  }
45209
- const hooksFile = join6(agentHome, ZCODE_CLI_DIR, HOOKS_JSON_FILE);
45210
- for (const c of nestedCommands(readJson(hooksFile))) {
45211
- if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(hooksFile, c.path, V1_REASON.zcodeHook));
47192
+ }
47193
+ function unlinkWithRetry(file2, opts = {}) {
47194
+ const unlink = opts.unlink ?? unlinkSync;
47195
+ const sleep2 = opts.sleep ?? sleepSync;
47196
+ const win = (opts.platform ?? process.platform) === "win32";
47197
+ for (let attempt = 0; ; attempt += 1) {
47198
+ try {
47199
+ unlink(file2);
47200
+ return;
47201
+ } catch (e) {
47202
+ if (errCode2(e) === "ENOENT") return;
47203
+ const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47204
+ if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw replaceFailure(file2, e);
47205
+ sleep2(ATOMIC_RENAME_DELAY_MS);
47206
+ }
45212
47207
  }
45213
47208
  }
45214
- function firstTmpMatch(dir) {
45215
- let handle;
47209
+ function replaceFailure(file2, e) {
47210
+ const busy = ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47211
+ const cause = e.message;
47212
+ return new Error(busy ? `Could not replace ${file2}: ${cause}. Fix: close the program using ${file2}, then re-run` : `Could not write ${file2}: ${cause}. Fix: check the path and its permissions, then re-run`, { cause: e });
47213
+ }
47214
+ function removeTmpFile(tmp, opts = {}) {
45216
47215
  try {
45217
- handle = opendirSync(dir);
47216
+ unlinkWithRetry(tmp, opts);
45218
47217
  } catch {
45219
- return null;
45220
47218
  }
47219
+ }
47220
+ function atomicWriteFile(file2, text, opts = {}) {
47221
+ mkdirSync4(path3.dirname(file2), { recursive: true });
47222
+ const tmp = path3.join(path3.dirname(file2), `${ATOMIC_TMP_PREFIX}${path3.basename(file2)}${ATOMIC_TMP_MARK}${process.pid}`);
45221
47223
  try {
45222
- for (let e = handle.readSync(); e !== null; e = handle.readSync()) {
45223
- if (e.name.startsWith(V1_TMP_PREFIX)) return e.name;
45224
- }
45225
- return null;
45226
- } catch {
45227
- return null;
45228
- } finally {
45229
- handle.closeSync();
47224
+ writeFileSync2(tmp, text);
47225
+ renameWithRetry(tmp, file2, opts);
47226
+ } catch (e) {
47227
+ removeTmpFile(tmp, opts);
47228
+ throw replaceFailure(file2, e);
45230
47229
  }
45231
47230
  }
45232
- function scanAll(home, tmp, out) {
45233
- const root = join6(home, DATA_ROOT.slice(1));
45234
- for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join6(root, name), V1_REASON.dataRoot, out);
45235
- if (firstTmpMatch(tmp) !== null) out.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
45236
- }
45237
- function detectV1(agent, home, scope = {}) {
45238
- const out = [];
45239
- const project = scope.project;
45240
- const agentHome = join6(home, ...AGENT_HOME_DIR[agent]);
45241
- switch (agent) {
45242
- case "claude-code":
45243
- scanClaudeCode(home, agentHome, out);
45244
- break;
45245
- case "codex":
45246
- scanCodex(agentHome, out);
45247
- break;
45248
- case "gemini":
45249
- scanGemini(agentHome, out);
45250
- break;
45251
- case "qwen":
45252
- claudeShapeSettings(agentHome, out);
45253
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
45254
- break;
45255
- case "copilot-cli":
45256
- v1HookFile(join6(agentHome, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
45257
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
45258
- break;
45259
- case "vscode":
45260
- scanVscode(agentHome, project, out);
45261
- break;
45262
- case "kiro":
45263
- scanKiro(agentHome, project, out);
45264
- break;
45265
- case "pi":
45266
- scanPi(scope.piAgentDir ?? join6(agentHome, PI_AGENT_DIR), agentHome, out);
45267
- break;
45268
- case "opencode":
45269
- scanOpencode(agentHome, out);
45270
- break;
45271
- case "zcode":
45272
- scanZcode(agentHome, out);
45273
- break;
45274
- }
45275
- scanAll(home, scope.tmp ?? tmpdir(), out);
45276
- return out;
47231
+
47232
+ // src/core/ops/host-text.ts
47233
+ var BOM_CODE = 65279;
47234
+ var CR_CODE = 13;
47235
+ var CRLF = "\r\n";
47236
+ var LF = "\n";
47237
+ function hostLayout(raw) {
47238
+ let crlf = 0;
47239
+ let lf = 0;
47240
+ for (let i = raw.indexOf(LF); i >= 0; i = raw.indexOf(LF, i + 1)) {
47241
+ if (i > 0 && raw.charCodeAt(i - 1) === CR_CODE) crlf += 1;
47242
+ else lf += 1;
47243
+ }
47244
+ return { bom: raw.length > 0 && raw.charCodeAt(0) === BOM_CODE, crlf: crlf > 0 && crlf >= lf };
47245
+ }
47246
+ function hostText(raw) {
47247
+ const bare2 = raw.length > 0 && raw.charCodeAt(0) === BOM_CODE ? raw.slice(1) : raw;
47248
+ return bare2.indexOf(CRLF) < 0 ? bare2 : bare2.split(CRLF).join(LF);
47249
+ }
47250
+ function withLayout(text, layout) {
47251
+ const eol = layout.crlf ? text.split(LF).join(CRLF) : text;
47252
+ return layout.bom ? String.fromCharCode(BOM_CODE) + eol : eol;
45277
47253
  }
45278
47254
 
45279
47255
  // src/core/ops/host-config.ts
45280
- import { existsSync as existsSync5, readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
45281
- import { dirname as dirname3, join as join7 } from "node:path";
45282
- function formatOf(path4) {
45283
- if (path4.endsWith(JSONC_EXT)) return "jsonc";
45284
- if (path4.endsWith(TOML_EXT)) return "toml";
47256
+ function formatOf(path5) {
47257
+ if (path5.endsWith(JSONC_EXT)) return "jsonc";
47258
+ if (path5.endsWith(TOML_EXT)) return "toml";
45285
47259
  return "json";
45286
47260
  }
45287
- function readHostConfig(agent, path4) {
45288
- let file2 = path4;
47261
+ function readHostConfig(agent, path5) {
47262
+ let file2 = path5;
45289
47263
  if (agent === "opencode") {
45290
- const jsonc = join7(dirname3(path4), OPENCODE_CONFIG_FILES[0]);
45291
- if (existsSync5(jsonc)) file2 = jsonc;
47264
+ const jsonc = join6(dirname3(path5), OPENCODE_CONFIG_FILES[0]);
47265
+ if (existsSync4(jsonc)) file2 = jsonc;
45292
47266
  }
45293
- const text = existsSync5(file2) ? readFileSync5(file2, "utf8") : "";
45294
- return { agent, text, format: formatOf(file2), path: file2 };
47267
+ const raw = existsSync4(file2) ? readFileSync4(file2, "utf8") : "";
47268
+ return { agent, text: hostText(raw), format: agent === "opencode" && !file2.endsWith(TOML_EXT) ? "jsonc" : formatOf(file2), path: file2, layout: hostLayout(raw) };
45295
47269
  }
45296
47270
  function stripJsonComments(text) {
45297
47271
  let out = "";
@@ -45425,171 +47399,63 @@ function scanJson(text, format) {
45425
47399
  if (sc.i !== clean.length) sc.fail();
45426
47400
  return { clean, root, value };
45427
47401
  }
45428
- function tomlKeyPath(s) {
45429
- const out = [];
45430
- let i = 0;
45431
- for (; ; ) {
45432
- while (s[i] === " " || s[i] === " ") i += 1;
45433
- let seg = "";
45434
- if (s[i] === '"' || s[i] === "'") {
45435
- const q = s[i];
45436
- let j = i + 1;
45437
- while (j < s.length && s[j] !== q) j += q === '"' && s[j] === "\\" ? 2 : 1;
45438
- if (j >= s.length) throw new SyntaxError("key");
45439
- seg = q === '"' ? JSON.parse(s.slice(i, j + 1)) : s.slice(i + 1, j);
45440
- i = j + 1;
45441
- } else {
45442
- while (i < s.length && !" .".includes(s[i])) {
45443
- seg += s[i];
45444
- i += 1;
45445
- }
45446
- if (seg === "") throw new SyntaxError("key");
45447
- }
45448
- out.push(seg);
45449
- while (s[i] === " " || s[i] === " ") i += 1;
45450
- if (i >= s.length) return out;
45451
- if (s[i] !== ".") throw new SyntaxError("key");
45452
- i += 1;
45453
- }
47402
+ function keyNames(key) {
47403
+ return key.keys.map((k) => k.type === "TOMLBare" ? k.name : k.value);
45454
47404
  }
45455
- var TomlValue = class {
45456
- i = 0;
45457
- s;
45458
- constructor(s) {
45459
- this.s = s;
45460
- }
45461
- ws() {
45462
- for (; ; ) {
45463
- while (this.i < this.s.length && " \r\n".includes(this.s[this.i])) this.i += 1;
45464
- if (this.s[this.i] !== "#") return;
45465
- while (this.i < this.s.length && this.s[this.i] !== "\n") this.i += 1;
45466
- }
45467
- }
45468
- read() {
45469
- this.ws();
45470
- const c = this.s[this.i];
45471
- if (c === '"' || c === "'") {
45472
- let j2 = this.i + 1;
45473
- while (j2 < this.s.length && this.s[j2] !== c && this.s[j2] !== "\n") j2 += c === '"' && this.s[j2] === "\\" ? 2 : 1;
45474
- if (this.s[j2] !== c) throw new SyntaxError("string");
45475
- const raw = this.s.slice(this.i, j2 + 1);
45476
- this.i = j2 + 1;
45477
- return c === '"' ? JSON.parse(raw) : raw.slice(1, -1);
45478
- }
45479
- if (c === "[") {
45480
- this.i += 1;
45481
- const out = [];
45482
- for (; ; ) {
45483
- this.ws();
45484
- if (this.s[this.i] === "]") {
45485
- this.i += 1;
45486
- return out;
45487
- }
45488
- out.push(this.read());
45489
- this.ws();
45490
- if (this.s[this.i] === ",") {
45491
- this.i += 1;
45492
- continue;
45493
- }
45494
- if (this.s[this.i] !== "]") throw new SyntaxError("array");
45495
- }
45496
- }
45497
- if (c === "{") {
45498
- this.i += 1;
45499
- const out = {};
45500
- for (; ; ) {
45501
- this.ws();
45502
- if (this.s[this.i] === "}") {
45503
- this.i += 1;
45504
- return out;
45505
- }
45506
- const eq = this.s.indexOf("=", this.i);
45507
- if (eq < 0) throw new SyntaxError("inline table");
45508
- const key = tomlKeyPath(this.s.slice(this.i, eq));
45509
- this.i = eq + 1;
45510
- setPath(out, key, this.read());
45511
- this.ws();
45512
- if (this.s[this.i] === ",") {
45513
- this.i += 1;
45514
- continue;
45515
- }
45516
- if (this.s[this.i] !== "}") throw new SyntaxError("inline table");
45517
- }
45518
- }
45519
- let j = this.i;
45520
- while (j < this.s.length && !" \r\n,]}#".includes(this.s[j])) j += 1;
45521
- const word = this.s.slice(this.i, j);
45522
- this.i = j;
45523
- if (word === "true") return true;
45524
- if (word === "false") return false;
45525
- const n = Number(word.split("_").join(""));
45526
- if (word === "" || Number.isNaN(n)) throw new SyntaxError("value");
45527
- return n;
45528
- }
45529
- };
45530
- function setPath(target, path4, value) {
45531
- let cur = target;
45532
- for (let k = 0; k < path4.length - 1; k += 1) {
45533
- const next = cur[path4[k]];
45534
- if (next === void 0) cur[path4[k]] = {};
45535
- else if (!isPlainObject6(next)) throw new SyntaxError("key conflict");
45536
- cur = cur[path4[k]];
45537
- }
45538
- if (cur[path4[path4.length - 1]] !== void 0) throw new SyntaxError("duplicate key");
45539
- cur[path4[path4.length - 1]] = value;
47405
+ function lineStartOf(text, at) {
47406
+ return at === 0 ? 0 : text.lastIndexOf("\n", at - 1) + 1;
47407
+ }
47408
+ function lineEndOf(text, at) {
47409
+ const nl = text.indexOf("\n", at);
47410
+ return nl < 0 ? text.length : nl + 1;
47411
+ }
47412
+ function tomlValue(text) {
47413
+ return getStaticTOMLValue(parseTOML(text));
45540
47414
  }
45541
47415
  function scanToml(text) {
45542
- const value = {};
47416
+ const program = parseTOML(text);
45543
47417
  const tables = [];
45544
- let table = value;
45545
- let i = 0;
45546
- while (i < text.length) {
45547
- const lineEnd = text.indexOf("\n", i) < 0 ? text.length : text.indexOf("\n", i) + 1;
45548
- const line = text.slice(i, lineEnd).trim();
45549
- if (line === "" || line.startsWith("#")) {
45550
- i = lineEnd;
45551
- continue;
45552
- }
45553
- if (line.startsWith("[")) {
45554
- if (line.startsWith("[[")) throw new SyntaxError("array of tables");
45555
- const close = line.indexOf("]");
45556
- if (close < 0) throw new SyntaxError("header");
45557
- const path4 = tomlKeyPath(line.slice(1, close));
45558
- if (tables.length > 0) tables[tables.length - 1].end = i;
45559
- tables.push({ path: path4, start: i, end: text.length });
45560
- let cur = value;
45561
- for (const seg of path4) {
45562
- if (cur[seg] === void 0) cur[seg] = {};
45563
- if (!isPlainObject6(cur[seg])) throw new SyntaxError("table conflict");
45564
- cur = cur[seg];
45565
- }
45566
- table = cur;
45567
- i = lineEnd;
47418
+ const keys = [];
47419
+ const addKey = (base, kv) => {
47420
+ keys.push({ base, full: [...base, ...keyNames(kv.key)], start: kv.range[0], end: kv.range[1], inline: kv.value.type === "TOMLInlineTable" });
47421
+ };
47422
+ for (const node3 of program.body[0].body) {
47423
+ if (node3.type === "TOMLKeyValue") {
47424
+ addKey([], node3);
45568
47425
  continue;
45569
47426
  }
45570
- const eq = text.indexOf("=", i);
45571
- if (eq < 0 || eq >= lineEnd) throw new SyntaxError("key/value");
45572
- const key = tomlKeyPath(text.slice(i, eq));
45573
- const reader = new TomlValue(text);
45574
- reader.i = eq + 1;
45575
- setPath(table, key, reader.read());
45576
- while (reader.i < text.length && (text[reader.i] === " " || text[reader.i] === " ")) reader.i += 1;
45577
- if (text[reader.i] === "#") while (reader.i < text.length && text[reader.i] !== "\n") reader.i += 1;
45578
- if (reader.i < text.length && text[reader.i] !== "\n" && text[reader.i] !== "\r") throw new SyntaxError("trailing text");
45579
- i = text.indexOf("\n", reader.i) < 0 ? text.length : text.indexOf("\n", reader.i) + 1;
47427
+ if (!node3.resolvedKey.every((seg) => typeof seg === "string")) continue;
47428
+ const path5 = node3.resolvedKey;
47429
+ for (const kv of node3.body) addKey(path5, kv);
47430
+ if (node3.kind !== "standard") continue;
47431
+ const start = lineStartOf(text, node3.range[0]);
47432
+ const headEnd = lineEndOf(text, node3.key.range[1]);
47433
+ const last2 = node3.body[node3.body.length - 1];
47434
+ tables.push({
47435
+ path: path5,
47436
+ header: text.slice(start, text[headEnd - 1] === "\n" ? headEnd - 1 : headEnd),
47437
+ start,
47438
+ end: last2 === void 0 ? headEnd : lineEndOf(text, last2.range[1])
47439
+ });
45580
47440
  }
45581
- return { value, tables };
47441
+ return { value: getStaticTOMLValue(program), tables, keys };
45582
47442
  }
45583
- function parseHostConfig(agent, path4, text, format) {
47443
+ function tomlTableSpans(text) {
47444
+ return scanToml(text).tables;
47445
+ }
47446
+ function tomlHeaderText(path5) {
47447
+ return "[" + path5.map(tomlHeaderKey).join(".") + "]";
47448
+ }
47449
+ function parseHostConfig(agent, path5, text, format) {
45584
47450
  try {
45585
47451
  return format === "toml" ? scanToml(text).value : scanJson(text, format).value;
45586
47452
  } catch {
45587
- throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path4, format });
47453
+ throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
45588
47454
  }
45589
47455
  }
45590
- function hostConfigValueAt(value, path4) {
47456
+ function hostConfigValueAt(value, path5) {
45591
47457
  let cur = value;
45592
- for (const seg of path4) {
47458
+ for (const seg of path5) {
45593
47459
  if (!isPlainObject6(cur)) return void 0;
45594
47460
  cur = cur[seg];
45595
47461
  }
@@ -45622,91 +47488,131 @@ function indentUnit(root, clean) {
45622
47488
  function render(value, unit, base) {
45623
47489
  return JSON.stringify(value, null, unit).split("\n").join("\n" + base);
45624
47490
  }
45625
- function nest(path4, value) {
47491
+ function nest(path5, value) {
45626
47492
  let out = value;
45627
- for (let k = path4.length - 1; k >= 0; k -= 1) out = { [path4[k]]: out };
47493
+ for (let k = path5.length - 1; k >= 0; k -= 1) out = { [path5[k]]: out };
45628
47494
  return out;
45629
47495
  }
45630
- function setJsonText(text, format, path4, value) {
47496
+ function setJsonText(text, format, path5, value) {
45631
47497
  const doc = scanJson(text, format);
45632
47498
  const unit = indentUnit(doc.root, doc.clean);
45633
- if (doc.root === null) return render(nest(path4, value), unit, "") + "\n";
47499
+ if (doc.root === null) return render(nest(path5, value), unit, "") + "\n";
45634
47500
  let node3 = doc.root;
45635
47501
  let depth = 0;
45636
- while (depth < path4.length && node3.kind === "object") {
45637
- const hit = node3.members.find((m) => m.key === path4[depth]);
47502
+ while (depth < path5.length && node3.kind === "object") {
47503
+ const hit = node3.members.find((m) => m.key === path5[depth]);
45638
47504
  if (hit === void 0) break;
45639
47505
  node3 = hit.node;
45640
47506
  depth += 1;
45641
47507
  }
45642
- if (depth === path4.length) {
47508
+ if (depth === path5.length) {
45643
47509
  return text.slice(0, node3.start) + render(value, unit, lineIndent(doc.clean, node3.start)) + text.slice(node3.end);
45644
47510
  }
45645
- if (node3.kind !== "object") throw new SyntaxError("not an object at " + path4.slice(0, depth).join("."));
45646
- const rest = nest(path4.slice(depth + 1), value);
45647
- const last = node3.members[node3.members.length - 1];
45648
- if (last === void 0) {
47511
+ if (node3.kind !== "object") throw new SyntaxError("not an object at " + path5.slice(0, depth).join("."));
47512
+ const rest = nest(path5.slice(depth + 1), value);
47513
+ const last2 = node3.members[node3.members.length - 1];
47514
+ if (last2 === void 0) {
45649
47515
  const base2 = lineIndent(doc.clean, node3.start);
45650
- const member2 = "\n" + base2 + unit + JSON.stringify(path4[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
47516
+ const member2 = "\n" + base2 + unit + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
45651
47517
  return text.slice(0, node3.start + 1) + member2 + text.slice(node3.end - 1);
45652
47518
  }
45653
- const base = lineIndent(doc.clean, last.keyStart);
45654
- let at = last.node.end;
47519
+ const base = lineIndent(doc.clean, last2.keyStart);
47520
+ let at = last2.node.end;
45655
47521
  while (" \r\n".includes(doc.clean[at])) at += 1;
45656
47522
  const trailing = doc.clean[at] === ",";
45657
- const insertAt = trailing ? at + 1 : last.node.end;
45658
- const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path4[depth]) + ": " + render(rest, unit, base);
47523
+ const insertAt = trailing ? at + 1 : last2.node.end;
47524
+ const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base);
45659
47525
  return text.slice(0, insertAt) + member + text.slice(insertAt);
45660
47526
  }
45661
47527
  function tomlScalar(v) {
45662
47528
  if (Array.isArray(v)) return "[" + v.map(tomlScalar).join(", ") + "]";
47529
+ if (isPlainObject6(v)) return "{ " + Object.entries(v).map(([k, x]) => tomlHeaderKey(k) + " = " + tomlScalar(x)).join(", ") + " }";
45663
47530
  if (typeof v === "string") return JSON.stringify(v);
45664
47531
  if (typeof v === "number" || typeof v === "boolean") return String(v);
45665
47532
  throw new SyntaxError("unsupported TOML value");
45666
47533
  }
45667
47534
  function tomlHeaderKey(seg) {
47535
+ if (seg === "") return '""';
45668
47536
  for (const ch of seg) {
45669
47537
  const bare2 = ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-";
45670
47538
  if (!bare2) return JSON.stringify(seg);
45671
47539
  }
45672
47540
  return seg;
45673
47541
  }
45674
- function tomlBlock(path4, value) {
45675
- let out = "[" + path4.map(tomlHeaderKey).join(".") + "]\n";
47542
+ function tomlBlock(path5, value) {
47543
+ let out = "[" + path5.map(tomlHeaderKey).join(".") + "]\n";
45676
47544
  const subs = [];
45677
47545
  for (const [k, v] of Object.entries(value)) {
45678
- if (isPlainObject6(v)) subs.push(tomlBlock([...path4, k], v));
47546
+ if (isPlainObject6(v)) subs.push(tomlBlock([...path5, k], v));
45679
47547
  else out += tomlHeaderKey(k) + " = " + tomlScalar(v) + "\n";
45680
47548
  }
45681
47549
  return [out, ...subs].join("\n");
45682
47550
  }
45683
- function setTomlText(text, path4, value) {
45684
- if (!isPlainObject6(value)) throw new SyntaxError("TOML edits replace a whole table");
47551
+ function under(path5, prefix) {
47552
+ return path5.length >= prefix.length && prefix.every((seg, k) => path5[k] === seg);
47553
+ }
47554
+ function keyLineRange(text, k) {
47555
+ const ls = lineStartOf(text, k.start);
47556
+ const le = lineEndOf(text, k.end);
47557
+ const rest = text.slice(k.end, le).trim();
47558
+ const alone = text.slice(ls, k.start).trim() === "" && (rest === "" || rest.startsWith("#"));
47559
+ return alone ? [ls, le] : [k.start, k.end];
47560
+ }
47561
+ function withValueAt(root, rel, value) {
47562
+ if (rel.length === 0) return value;
47563
+ const base = isPlainObject6(root) ? { ...root } : {};
47564
+ const next = withValueAt(base[rel[0]], rel.slice(1), value);
47565
+ if (next === void 0) delete base[rel[0]];
47566
+ else base[rel[0]] = next;
47567
+ return base;
47568
+ }
47569
+ function replaceToml(text, doc, path5, value) {
47570
+ const block = value === void 0 ? "" : tomlBlock(path5, value);
47571
+ const owned = doc.tables.filter((t) => under(t.path, path5));
47572
+ const cuts = doc.keys.filter((k) => under(k.full, path5) && !under(k.base, path5)).map((k) => [...keyLineRange(text, k), ""]);
47573
+ owned.forEach((t, n) => cuts.push([t.start, t.end, n === 0 ? block : ""]));
47574
+ cuts.sort((a, b) => b[0] - a[0]);
47575
+ let out = text;
47576
+ for (const [s, e, put] of cuts) out = out.slice(0, s) + put + out.slice(e);
47577
+ if (owned.length > 0 || block === "") return out;
47578
+ const sep2 = out === "" ? "" : out.endsWith("\n\n") ? "" : out.endsWith("\n") ? "\n" : "\n\n";
47579
+ return out + sep2 + block;
47580
+ }
47581
+ var tableLike = (v) => v === void 0 || isPlainObject6(v);
47582
+ function setTomlText(text, path5, value) {
47583
+ if (value !== void 0 && !isPlainObject6(value)) throw new SyntaxError("TOML edits replace a whole table");
45685
47584
  const doc = scanToml(text);
45686
- const owned = doc.tables.filter((t) => t.path.length >= path4.length && path4.every((seg, k) => t.path[k] === seg));
45687
- const block = tomlBlock(path4, value);
45688
- if (owned.length === 0) {
45689
- const sep2 = text === "" ? "" : text.endsWith("\n\n") ? "" : text.endsWith("\n") ? "\n" : "\n\n";
45690
- return text + sep2 + block;
45691
- }
45692
- let out = text.slice(0, owned[0].start) + block;
45693
- let cursor = owned[0].end;
45694
- for (const t of owned.slice(1)) {
45695
- out += text.slice(cursor, t.start).trim() === "" ? "" : text.slice(cursor, t.start);
45696
- cursor = t.end;
45697
- }
45698
- const tail = text.slice(cursor);
45699
- return out + (tail === "" || block.endsWith("\n\n") ? "" : "\n") + tail;
45700
- }
45701
- function setText(agent, path4, text, format, key, value) {
47585
+ const cur = hostConfigValueAt(doc.value, path5);
47586
+ if (sameValue(cur, value)) return text;
47587
+ const inline = doc.keys.find((k) => k.inline && k.full.length < path5.length && under(path5, k.full));
47588
+ if (inline !== void 0) {
47589
+ const whole = withValueAt(hostConfigValueAt(doc.value, inline.full), path5.slice(inline.full.length), value);
47590
+ return replaceToml(text, doc, inline.full, whole);
47591
+ }
47592
+ if (isPlainObject6(cur) && isPlainObject6(value)) {
47593
+ const names = [.../* @__PURE__ */ new Set([...Object.keys(cur), ...Object.keys(value)])].filter((k) => !sameValue(cur[k], value[k]));
47594
+ if (names.every((k) => tableLike(cur[k]) && tableLike(value[k]))) {
47595
+ let out = text;
47596
+ for (const k of names) out = setTomlText(out, [...path5, k], value[k]);
47597
+ return out;
47598
+ }
47599
+ }
47600
+ return replaceToml(text, doc, path5, value);
47601
+ }
47602
+ function setText(agent, path5, text, format, key, value) {
45702
47603
  try {
45703
- return format === "toml" ? setTomlText(text, key, value) : setJsonText(text, format, key, value);
47604
+ if (format !== "toml") return setJsonText(text, format, key, value);
47605
+ const out = setTomlText(text, key, value);
47606
+ const landed = hostConfigValueAt(tomlValue(out), key);
47607
+ const emptyTable = isPlainObject6(value) && Object.keys(value).length === 0;
47608
+ if (!sameValue(landed, value) && !(emptyTable && landed === void 0)) throw new SyntaxError("edit did not land");
47609
+ return out;
45704
47610
  } catch {
45705
- throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path4, format });
47611
+ throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
45706
47612
  }
45707
47613
  }
45708
47614
  function serverScript() {
45709
- return join7(dirname3(process.argv[1] ?? ""), SERVER_ENTRY_FILE);
47615
+ return join6(dirname3(process.argv[1] ?? ""), SERVER_ENTRY_FILE);
45710
47616
  }
45711
47617
  function listTarget(key, own4, v1) {
45712
47618
  return {
@@ -45732,14 +47638,14 @@ function ownTargets(agent) {
45732
47638
  if (agent === "pi") return [listTarget(PI_PACKAGES_KEY, PI_GIT_PACKAGE, V1_PI_PACKAGE)];
45733
47639
  return [];
45734
47640
  }
45735
- function applyEdits(agent, path4, text, format, wanted) {
45736
- const parsed = parseHostConfig(agent, path4, text, format);
47641
+ function applyEdits(agent, path5, text, format, wanted) {
47642
+ const parsed = parseHostConfig(agent, path5, text, format);
45737
47643
  let out = text;
45738
47644
  const edits = [];
45739
47645
  for (const [key, after] of wanted) {
45740
47646
  const before = hostConfigValueAt(parsed, key);
45741
47647
  if (sameValue(before, after)) continue;
45742
- out = setText(agent, path4, out, format, key, after);
47648
+ out = setText(agent, path5, out, format, key, after);
45743
47649
  edits.push({ path: key.join("."), before, after });
45744
47650
  }
45745
47651
  return { text: out, format, edits };
@@ -45753,26 +47659,307 @@ function writeHostConfigEdit(_requested, current, patch) {
45753
47659
  const wanted = Object.entries(patch).map(([k, v]) => [[k], v]);
45754
47660
  const result = applyEdits(current.agent, current.path, current.text, current.format, wanted);
45755
47661
  if (result.edits.length === 0) return [];
45756
- const tmp = current.path + HOST_CONFIG_TMP_SUFFIX;
45757
- writeFileSync2(tmp, result.text, "utf8");
45758
- renameSync(tmp, current.path);
47662
+ atomicWriteFile(current.path, current.layout === void 0 ? result.text : withLayout(result.text, current.layout));
45759
47663
  return result.edits;
45760
47664
  }
45761
47665
 
47666
+ // src/core/ops/detect-v1.ts
47667
+ var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
47668
+ var keyPath = (...parts) => parts.join(".");
47669
+ var finding = (file2, path5, reason) => ({ file: file2, path: path5, reason });
47670
+ function stripJsonc(text) {
47671
+ let out = "";
47672
+ let inStr = false;
47673
+ let esc4 = false;
47674
+ for (let i = 0; i < text.length; i++) {
47675
+ const c = text[i];
47676
+ if (inStr) {
47677
+ out += c;
47678
+ if (esc4) esc4 = false;
47679
+ else if (c === "\\") esc4 = true;
47680
+ else if (c === '"') inStr = false;
47681
+ continue;
47682
+ }
47683
+ if (c === '"') {
47684
+ inStr = true;
47685
+ out += c;
47686
+ continue;
47687
+ }
47688
+ if (c === "/" && text[i + 1] === "/") {
47689
+ while (i < text.length && text[i] !== "\n") i++;
47690
+ out += "\n";
47691
+ continue;
47692
+ }
47693
+ if (c === "/" && text[i + 1] === "*") {
47694
+ const end = text.indexOf("*/", i + 2);
47695
+ i = end === -1 ? text.length : end + 1;
47696
+ continue;
47697
+ }
47698
+ if (c === ",") {
47699
+ let j = i + 1;
47700
+ while (j < text.length && " \r\n".includes(text[j])) j++;
47701
+ if (text[j] === "}" || text[j] === "]") continue;
47702
+ }
47703
+ out += c;
47704
+ }
47705
+ return out;
47706
+ }
47707
+ function readJson(file2) {
47708
+ try {
47709
+ return JSON.parse(stripJsonc(hostText(readFileSync5(file2, "utf8"))));
47710
+ } catch {
47711
+ return void 0;
47712
+ }
47713
+ }
47714
+ function readText(file2) {
47715
+ try {
47716
+ return hostText(readFileSync5(file2, "utf8"));
47717
+ } catch {
47718
+ return "";
47719
+ }
47720
+ }
47721
+ function readTomlTables(file2) {
47722
+ try {
47723
+ return tomlTableSpans(readText(file2));
47724
+ } catch {
47725
+ return [];
47726
+ }
47727
+ }
47728
+ var listOf = (v) => Array.isArray(v) ? v : [];
47729
+ var commandOf = (v) => isObj(v) && typeof v.command === "string" ? v.command : null;
47730
+ function nestedCommands(doc) {
47731
+ const out = [];
47732
+ if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out;
47733
+ for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
47734
+ listOf(groups).forEach((group, i) => {
47735
+ if (!isObj(group)) return;
47736
+ listOf(group[HOOKS_KEY]).forEach((inner, j) => {
47737
+ const command = commandOf(inner);
47738
+ if (command !== null) out.push({ path: keyPath(HOOKS_KEY, event, i, HOOKS_KEY, j), command });
47739
+ });
47740
+ });
47741
+ }
47742
+ return out;
47743
+ }
47744
+ function flatCommands(events, prefix) {
47745
+ const out = [];
47746
+ if (!isObj(events)) return out;
47747
+ for (const [event, entries] of Object.entries(events)) {
47748
+ listOf(entries).forEach((entry, i) => {
47749
+ const command = commandOf(entry);
47750
+ if (command !== null) out.push({ path: keyPath(...prefix, event, i), command });
47751
+ });
47752
+ }
47753
+ return out;
47754
+ }
47755
+ var isV1Hook = (cmd) => cmd.includes(SERVER_KEY) && (V1_SCRIPT_NAMES.some((name) => cmd.includes(name)) || cmd.includes(V1_HOOK_COMMAND));
47756
+ var isCodexScript = (cmd) => cmd.includes(V1_SCRIPT_EXT) && V1_PATH_SEPS.some((sep2) => cmd.includes(V1_CODEX_HOOKS_DIR.join(sep2) + sep2));
47757
+ function dataDir(dir, reason, out) {
47758
+ if (existsSync5(dir)) out.push(finding(dir, "", reason));
47759
+ }
47760
+ function mcpEntry(file2, doc, out) {
47761
+ if (isObj(doc) && isObj(doc[MCP_SERVERS_KEY]) && Object.hasOwn(doc[MCP_SERVERS_KEY], SERVER_KEY)) {
47762
+ out.push(finding(file2, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
47763
+ }
47764
+ }
47765
+ function claudeShapeSettings(agentHome, out) {
47766
+ const file2 = join7(agentHome, SETTINGS_FILE);
47767
+ const doc = readJson(file2);
47768
+ for (const c of nestedCommands(doc)) {
47769
+ if (c.command.includes(V1_CACHE_HEAL_NAME)) out.push(finding(file2, c.path, V1_REASON.cacheHealHook));
47770
+ else if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.hook));
47771
+ }
47772
+ const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
47773
+ if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
47774
+ out.push(finding(file2, STATUS_LINE_KEY, V1_REASON.statusLine));
47775
+ }
47776
+ mcpEntry(file2, doc, out);
47777
+ }
47778
+ function v1HookFile(file2, out) {
47779
+ const doc = readJson(file2);
47780
+ const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
47781
+ if (cmds.some((c) => c.command.includes(V1_HOOK_COMMAND))) out.push(finding(file2, "", V1_REASON.hookFile));
47782
+ }
47783
+ function scanClaudeCode(home, agentHome, out) {
47784
+ claudeShapeSettings(agentHome, out);
47785
+ for (const ext of V1_CACHE_HEAL_EXTS) {
47786
+ const file2 = join7(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
47787
+ if (existsSync5(file2)) out.push(finding(file2, "", V1_REASON.cacheHealFile));
47788
+ }
47789
+ const userFile = join7(home, CLAUDE_USER_CONFIG_FILE);
47790
+ mcpEntry(userFile, readJson(userFile), out);
47791
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47792
+ }
47793
+ function scanCodex(agentHome, out) {
47794
+ const hooksFile = join7(agentHome, HOOKS_JSON_FILE);
47795
+ for (const c of nestedCommands(readJson(hooksFile))) {
47796
+ if (c.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c.command)) {
47797
+ out.push(finding(hooksFile, c.path, V1_REASON.codexHook));
47798
+ }
47799
+ }
47800
+ const tomlFile = join7(agentHome, CONFIG_TOML_FILE);
47801
+ for (const span of readTomlTables(tomlFile)) {
47802
+ if (tomlHeaderText(span.path).startsWith(V1_TOML_SECTION_PREFIX)) out.push(finding(tomlFile, span.header.trim(), V1_REASON.codexToml));
47803
+ }
47804
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47805
+ }
47806
+ function scanGemini(agentHome, out) {
47807
+ const file2 = join7(agentHome, SETTINGS_FILE);
47808
+ for (const c of nestedCommands(readJson(file2))) {
47809
+ if (c.command.includes(SERVER_KEY)) out.push(finding(file2, c.path, V1_REASON.hook));
47810
+ }
47811
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out);
47812
+ }
47813
+ function scanVscode(agentHome, project, out) {
47814
+ if (project !== void 0) {
47815
+ v1HookFile(join7(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
47816
+ const mcpFile2 = join7(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
47817
+ const doc = readJson(mcpFile2);
47818
+ const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
47819
+ const entry = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
47820
+ if (isObj(entry) && (entry.command === V1_BIN_COMMAND || listOf(entry.args).some((a) => a === V1_BIN_COMMAND))) {
47821
+ out.push(finding(mcpFile2, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
47822
+ }
47823
+ dataDir(join7(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
47824
+ }
47825
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
47826
+ }
47827
+ function jsonFiles(dir) {
47828
+ try {
47829
+ return readdirSync3(dir).filter((name) => name.endsWith(KIRO_AGENT_FILE_EXT)).sort();
47830
+ } catch {
47831
+ return [];
47832
+ }
47833
+ }
47834
+ function scanKiro(agentHome, project, out) {
47835
+ const agentsDir = join7(agentHome, KIRO_AGENTS_DIR);
47836
+ const defaultFile = join7(agentHome, ...KIRO_AGENT_FILE);
47837
+ for (const name of jsonFiles(agentsDir)) {
47838
+ const file2 = join7(agentsDir, name);
47839
+ const doc = readJson(file2);
47840
+ if (isObj(doc) && doc[KIRO_AGENT_NAME_KEY] === SERVER_KEY) {
47841
+ out.push(finding(file2, "", V1_REASON.kiroAgentFile));
47842
+ continue;
47843
+ }
47844
+ if (file2 !== defaultFile) continue;
47845
+ for (const c of isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : []) {
47846
+ if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.kiroHook));
47847
+ }
47848
+ }
47849
+ const steeringDocs = [join7(agentHome, ...KIRO_STEERING_FILE)];
47850
+ if (project !== void 0) steeringDocs.push(join7(project, ...AGENT_HOME_DIR.kiro, ...KIRO_STEERING_FILE));
47851
+ for (const file2 of steeringDocs) {
47852
+ if (existsSync5(file2)) out.push(finding(file2, "", V1_REASON.kiroSteering));
47853
+ }
47854
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47855
+ }
47856
+ function scanPi(piAgentDir, agentHome, out) {
47857
+ const file2 = join7(piAgentDir, SETTINGS_FILE);
47858
+ const doc = readJson(file2);
47859
+ listOf(isObj(doc) ? doc[PI_PACKAGES_KEY] : void 0).forEach((pkg, i) => {
47860
+ const spec = isObj(pkg) ? pkg[PI_PACKAGE_SOURCE_KEY] : pkg;
47861
+ if (spec === V1_PI_PACKAGE) out.push(finding(file2, keyPath(PI_PACKAGES_KEY, i), V1_REASON.piNpm));
47862
+ });
47863
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47864
+ }
47865
+ function scanOpencode(agentHome, out) {
47866
+ for (const name of OPENCODE_CONFIG_FILES) {
47867
+ const file2 = join7(agentHome, name);
47868
+ const doc = readJson(file2);
47869
+ if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
47870
+ doc[OPENCODE_PLUGIN_KEY].forEach((spec, i) => {
47871
+ if (spec === V1_OPENCODE_PLUGIN_SPEC) out.push(finding(file2, keyPath(OPENCODE_PLUGIN_KEY, i), V1_REASON.opencodePlugin));
47872
+ });
47873
+ return;
47874
+ }
47875
+ }
47876
+ function scanZcode(agentHome, out) {
47877
+ const configFile = join7(agentHome, ZCODE_CLI_DIR, CONFIG_JSON_FILE);
47878
+ const config4 = readJson(configFile);
47879
+ const events = isObj(config4) && isObj(config4[HOOKS_KEY]) ? config4[HOOKS_KEY][ZCODE_EVENTS_KEY] : void 0;
47880
+ for (const c of flatCommands(events, [HOOKS_KEY, ZCODE_EVENTS_KEY])) {
47881
+ if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(configFile, c.path, V1_REASON.zcodeHook));
47882
+ }
47883
+ const hooksFile = join7(agentHome, ZCODE_CLI_DIR, HOOKS_JSON_FILE);
47884
+ for (const c of nestedCommands(readJson(hooksFile))) {
47885
+ if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(hooksFile, c.path, V1_REASON.zcodeHook));
47886
+ }
47887
+ }
47888
+ function firstTmpMatch(dir) {
47889
+ let handle;
47890
+ try {
47891
+ handle = opendirSync(dir);
47892
+ } catch {
47893
+ return null;
47894
+ }
47895
+ try {
47896
+ for (let e = handle.readSync(); e !== null; e = handle.readSync()) {
47897
+ if (e.name.startsWith(V1_TMP_PREFIX)) return e.name;
47898
+ }
47899
+ return null;
47900
+ } catch {
47901
+ return null;
47902
+ } finally {
47903
+ handle.closeSync();
47904
+ }
47905
+ }
47906
+ function scanAll(home, tmp, out) {
47907
+ const root = join7(home, DATA_ROOT.slice(1));
47908
+ for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join7(root, name), V1_REASON.dataRoot, out);
47909
+ if (firstTmpMatch(tmp) !== null) out.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
47910
+ }
47911
+ function detectV1(agent, home, scope = {}) {
47912
+ const out = [];
47913
+ const project = scope.project;
47914
+ 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 : join7(home, ...AGENT_HOME_DIR[agent]);
47915
+ switch (agent) {
47916
+ case "claude-code":
47917
+ scanClaudeCode(home, agentHome, out);
47918
+ break;
47919
+ case "codex":
47920
+ scanCodex(agentHome, out);
47921
+ break;
47922
+ case "gemini":
47923
+ scanGemini(agentHome, out);
47924
+ break;
47925
+ case "qwen":
47926
+ claudeShapeSettings(agentHome, out);
47927
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47928
+ break;
47929
+ case "copilot-cli":
47930
+ v1HookFile(join7(agentHome, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
47931
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47932
+ break;
47933
+ case "vscode":
47934
+ scanVscode(agentHome, project, out);
47935
+ break;
47936
+ case "kiro":
47937
+ scanKiro(agentHome, project, out);
47938
+ break;
47939
+ case "pi":
47940
+ scanPi(scope.piAgentDir !== void 0 && scope.piAgentDir !== "" ? scope.piAgentDir : join7(agentHome, PI_AGENT_DIR), agentHome, out);
47941
+ break;
47942
+ // D-WIN-PIDIR-1: empty is unset
47943
+ case "opencode":
47944
+ scanOpencode(agentHome, out);
47945
+ break;
47946
+ case "zcode":
47947
+ scanZcode(agentHome, out);
47948
+ break;
47949
+ }
47950
+ scanAll(home, scope.tmp ?? tmpdir(), out);
47951
+ return out;
47952
+ }
47953
+
45762
47954
  // src/core/ops/plugin-root.ts
45763
47955
  import { existsSync as existsSync6, readdirSync as readdirSync4, realpathSync as realpathSync4 } from "node:fs";
45764
47956
  import { dirname as dirname4, isAbsolute, join as join8 } from "node:path";
45765
47957
  import { fileURLToPath } from "node:url";
45766
- function homeOf2(env) {
45767
- const home = homeDirOf(env);
45768
- if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
45769
- return home;
45770
- }
45771
- function missing(agent, path4) {
45772
- return new CtxError("PLUGIN_ROOT_MISSING", { agent, path: path4 });
47958
+ function missing(agent, path5) {
47959
+ return new CtxError("PLUGIN_ROOT_MISSING", { agent, path: path5 });
45773
47960
  }
45774
47961
  function marketplaceRoot(adapter, env) {
45775
- const cache = join8(homeOf2(env), HOST_CONFIG_DIR_NAME, HOST_PLUGINS_DIR_NAME, PLUGIN_CACHE_DIR_NAME);
47962
+ const cache = join8(claudeDirOf(env, requireHomeDir(env)), HOST_PLUGINS_DIR_NAME, PLUGIN_CACHE_DIR_NAME);
45776
47963
  const pattern = join8(cache, "*", PLUGIN_NAME);
45777
47964
  if (!existsSync6(cache)) throw missing(adapter.id, pattern);
45778
47965
  const found = readdirSync4(cache).sort().map((marketplace) => join8(cache, marketplace, PLUGIN_NAME)).filter((dir) => existsSync6(dir));
@@ -45782,7 +47969,7 @@ function marketplaceRoot(adapter, env) {
45782
47969
  function configEntryRoot(adapter, env) {
45783
47970
  const spec = OWN_MCP_ENTRY[adapter.id];
45784
47971
  if (spec === void 0) throw missing(adapter.id, SERVER_KEY);
45785
- const file2 = join8(homeOf2(env), ...spec.file);
47972
+ const file2 = ownMcpFileOf(adapter.id, spec.file, env, requireHomeDir(env));
45786
47973
  if (!existsSync6(file2)) throw missing(adapter.id, file2);
45787
47974
  const current = readHostConfig(adapter.id, file2);
45788
47975
  const value = parseHostConfig(adapter.id, file2, current.text, current.format);
@@ -45800,7 +47987,7 @@ function candidate(adapter, env) {
45800
47987
  case "hooks+mcp":
45801
47988
  return configEntryRoot(adapter, env);
45802
47989
  case "extension":
45803
- return join8(homeOf2(env), ...AGENT_HOME_DIR[adapter.id], EXTENSIONS_DIR_NAME, PLUGIN_NAME);
47990
+ return join8(requireHomeDir(env), ...AGENT_HOME_DIR[adapter.id], EXTENSIONS_DIR_NAME, PLUGIN_NAME);
45804
47991
  case "plugin":
45805
47992
  return join8(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, adapter.id, PLUGIN_CURRENT_LINK);
45806
47993
  case "in-process":
@@ -45808,11 +47995,11 @@ function candidate(adapter, env) {
45808
47995
  }
45809
47996
  }
45810
47997
  function resolvePluginRoot(adapter, env) {
45811
- const path4 = candidate(adapter, env);
47998
+ const path5 = candidate(adapter, env);
45812
47999
  try {
45813
- return realpathSync4.native(path4);
48000
+ return realpathSync4.native(path5);
45814
48001
  } catch {
45815
- throw missing(adapter.id, path4);
48002
+ throw missing(adapter.id, path5);
45816
48003
  }
45817
48004
  }
45818
48005
 
@@ -45838,14 +48025,31 @@ function composeMatcher(row5, event) {
45838
48025
  if (event === POST_TOOL_USE && hasReplace(row5)) alts.push(MCP_ANY_MATCH);
45839
48026
  return MATCHER_OPEN + alts.join(MATCHER_ALT) + MATCHER_CLOSE;
45840
48027
  }
48028
+ var lastSegment = (p) => {
48029
+ let at = -1;
48030
+ for (const sep2 of V1_PATH_SEPS) at = Math.max(at, p.lastIndexOf(sep2));
48031
+ return p.slice(at + 1);
48032
+ };
48033
+ function splitHead(command) {
48034
+ if (command.startsWith(SHELL_QUOTE)) {
48035
+ const close = command.indexOf(SHELL_QUOTE, 1);
48036
+ if (close < 0 || command.slice(close + 1, close + 1 + HOOK_COMMAND_SEP.length) !== HOOK_COMMAND_SEP) return null;
48037
+ return { head: command.slice(1, close), rest: command.slice(close + 1 + HOOK_COMMAND_SEP.length) };
48038
+ }
48039
+ const end = command.indexOf(HOOK_COMMAND_SEP);
48040
+ return end < 0 ? null : { head: command.slice(0, end), rest: command.slice(end + HOOK_COMMAND_SEP.length) };
48041
+ }
45841
48042
  function isOwnCommand(command, agent) {
45842
48043
  if (typeof command !== "string") return false;
45843
- const head = HOST_NODE_COMMAND + HOOK_COMMAND_SEP;
48044
+ const split = splitHead(command);
48045
+ if (split === null) return false;
48046
+ const exe = lastSegment(split.head).toLowerCase();
48047
+ if (exe !== HOST_NODE_COMMAND && exe !== HOST_NODE_COMMAND + EXE_SUFFIX) return false;
45844
48048
  const tail = HOOK_COMMAND_SEP + AGENT_ARG + HOOK_COMMAND_SEP + agent;
45845
- if (!command.startsWith(head) || !command.endsWith(tail) || command.length <= head.length + tail.length) return false;
45846
- let script = command.slice(head.length, command.length - tail.length);
48049
+ if (!split.rest.endsWith(tail) || split.rest.length <= tail.length) return false;
48050
+ let script = split.rest.slice(0, split.rest.length - tail.length);
45847
48051
  if (script.startsWith(SHELL_QUOTE) && script.endsWith(SHELL_QUOTE) && script.length > 1) script = script.slice(1, -1);
45848
- return script === HOOK_ENTRY_FILE || V1_PATH_SEPS.some((sep2) => script.endsWith(sep2 + HOOK_ENTRY_FILE));
48052
+ return script === HOOK_ENTRY_FILE || HOOK_SCRIPT_SEPS.some((sep2) => script.endsWith(sep2 + HOOK_ENTRY_FILE));
45849
48053
  }
45850
48054
  function ownHooks(block, shape, timeoutKey, native, agent) {
45851
48055
  const out = [];
@@ -45877,11 +48081,10 @@ var validTimeout = (v) => typeof v === "number" && Number.isFinite(v) && v > 0;
45877
48081
  function mcpFile(row5, home, env) {
45878
48082
  const spec = OWN_MCP_ENTRY[row5.id];
45879
48083
  if (row5.id === "codex") return join9(codexDirOf(env, home), CONFIG_TOML_FILE);
45880
- if (spec !== void 0) return join9(home, ...spec.file);
45881
- if (row5.id === "opencode") return join9(home, ...AGENT_HOME_DIR.opencode, OPENCODE_BASE_CONFIG_FILE);
48084
+ if (spec !== void 0) return ownMcpFileOf(row5.id, spec.file, env, home);
48085
+ if (row5.id === "opencode") return join9(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
45882
48086
  if (row5.id === "pi") {
45883
- const dir = env[PI_AGENT_DIR_ENV];
45884
- return join9(dir !== void 0 && dir !== "" ? dir : join9(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR), SETTINGS_FILE);
48087
+ return join9(piAgentDirOf(env, home), SETTINGS_FILE);
45885
48088
  }
45886
48089
  return null;
45887
48090
  }
@@ -45904,7 +48107,7 @@ function hookParts(row5, home, env, worktree) {
45904
48107
  let block;
45905
48108
  try {
45906
48109
  const root = spec.root === "plugin" ? resolvePluginRoot(row5, env) : spec.root === "home" ? home : worktree;
45907
- const file2 = row5.id === "codex" ? join9(codexDirOf(env, home), HOOKS_JSON_FILE) : join9(root, ...spec.file);
48110
+ const file2 = row5.id === "codex" ? join9(codexDirOf(env, home), HOOKS_JSON_FILE) : row5.id === "copilot-cli" ? join9(copilotDirOf(env, home), ...spec.file.slice(1)) : row5.id === "kiro" ? join9(kiroDirOf(env, home), ...spec.file.slice(1)) : join9(root, ...spec.file);
45908
48111
  block = hostConfigValueAt(readParsed(row5.id, file2).value, spec.key);
45909
48112
  if (row5.id === "codex") {
45910
48113
  const config4 = readParsed(row5.id, join9(codexDirOf(env, home), CONFIG_TOML_FILE)).value;
@@ -45986,8 +48189,8 @@ async function loadSqlite2() {
45986
48189
  return null;
45987
48190
  }
45988
48191
  }
45989
- function openRead(sqlite, path4) {
45990
- return new sqlite.DatabaseSync(path4, { timeout: DB_TIMEOUT_MS, readOnly: true });
48192
+ function openRead(sqlite, path5) {
48193
+ return new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS, readOnly: true });
45991
48194
  }
45992
48195
  var cell = (row5) => Object.values(row5)[0];
45993
48196
  function readSchema(raw) {
@@ -46121,20 +48324,26 @@ function checkProject(i) {
46121
48324
  function checkMode(adapter) {
46122
48325
  return pass3("D10", D10_DETAIL(adapter.denyChannel));
46123
48326
  }
48327
+ function checkShell(env) {
48328
+ const win = process.platform === "win32";
48329
+ const shell = findRuntime("shell", env);
48330
+ if (shell !== null) return pass3("D11", D11_PASS_DETAIL(shell, win));
48331
+ return win ? fail3("D11", D11_WIN_DETAIL, D11_WIN_FIX) : fail3("D11", D11_POSIX_DETAIL, D11_POSIX_FIX);
48332
+ }
46124
48333
 
46125
48334
  // src/core/ops/doctor-hook.ts
46126
48335
  import { existsSync as existsSync9, readFileSync as readFileSync6 } from "node:fs";
46127
- import path3 from "node:path";
48336
+ import path4 from "node:path";
46128
48337
  var row = (status, detail, fixCommand) => fixCommand === void 0 ? { id: "D5", label: DOCTOR_LABEL.D5, status, detail } : { id: "D5", label: DOCTOR_LABEL.D5, status, detail, fixCommand };
46129
48338
  function isObject5(v) {
46130
48339
  return typeof v === "object" && v !== null && !Array.isArray(v);
46131
48340
  }
46132
48341
  function loadFixture(bundleDir2, agent) {
46133
- const file2 = path3.join(bundleDir2, HOOK_FIXTURE_DIR, HOOK_FIXTURE_FILE);
48342
+ const file2 = path4.join(bundleDir2, HOOK_FIXTURE_DIR, HOOK_FIXTURE_FILE);
46134
48343
  if (!existsSync9(file2)) return null;
46135
48344
  let all;
46136
48345
  try {
46137
- all = JSON.parse(readFileSync6(file2, "utf8"));
48346
+ all = JSON.parse(hostText(readFileSync6(file2, "utf8")));
46138
48347
  } catch {
46139
48348
  return null;
46140
48349
  }
@@ -46159,14 +48368,14 @@ function codexHookJournaled(db) {
46159
48368
  return db.raw.prepare("SELECT 1 FROM events WHERE agent = ? LIMIT 1").get("codex") !== void 0;
46160
48369
  }
46161
48370
  async function checkHookRoundTrip(i) {
46162
- if (i.agent === "codex" && existsSync9(path3.join(i.codexConfigDir, HOOKS_JSON_FILE)) && !codexHookJournaled(i.db)) {
48371
+ if (i.agent === "codex" && existsSync9(path4.join(i.codexConfigDir, HOOKS_JSON_FILE)) && !codexHookJournaled(i.db)) {
46163
48372
  return row("UNKNOWN", D5_CODEX_UNTRUSTED_DETAIL);
46164
48373
  }
46165
48374
  const fixture = loadFixture(i.bundleDir, i.agent);
46166
48375
  if (fixture === null) return row("UNKNOWN", D5_NO_FIXTURE_DETAIL(i.agent));
46167
48376
  const now = i.now ?? (() => performance.now());
46168
48377
  const start = now();
46169
- const r = await runProcess([process.execPath, path3.join(i.bundleDir, HOOK_ENTRY_FILE), AGENT_ARG, i.agent], {
48378
+ const r = await runProcess([process.execPath, path4.join(i.bundleDir, HOOK_ENTRY_FILE), AGENT_ARG, i.agent], {
46170
48379
  cwd: i.bundleDir,
46171
48380
  env: i.env,
46172
48381
  signal: i.signal,
@@ -46180,7 +48389,7 @@ async function checkHookRoundTrip(i) {
46180
48389
  }
46181
48390
 
46182
48391
  // src/core/ops/db-heal.ts
46183
- import { existsSync as existsSync10, renameSync as renameSync2, rmSync as rmSync4 } from "node:fs";
48392
+ import { existsSync as existsSync10, rmSync as rmSync4 } from "node:fs";
46184
48393
  function integrityOk2(rows) {
46185
48394
  return rows.length === 1 && rows[0].integrity_check === INTEGRITY_OK;
46186
48395
  }
@@ -46205,7 +48414,7 @@ async function healLossless(dbPath) {
46205
48414
  }
46206
48415
  rmSync4(dbPath + DB_WAL_SUFFIX, { force: true });
46207
48416
  rmSync4(dbPath + DB_SHM_SUFFIX, { force: true });
46208
- renameSync2(tmp, dbPath);
48417
+ renameWithRetry(tmp, dbPath);
46209
48418
  } finally {
46210
48419
  rmSync4(tmp, { force: true });
46211
48420
  }
@@ -46214,7 +48423,7 @@ function renameAside(dbPath) {
46214
48423
  const ts = String(Date.now());
46215
48424
  for (const suffix of DB_SIBLING_SUFFIXES) {
46216
48425
  const file2 = dbPath + suffix;
46217
- if (existsSync10(file2)) renameSync2(file2, file2 + HEAL_TS_SEP + ts + HEAL_BACKUP_SUFFIX);
48426
+ if (existsSync10(file2)) renameWithRetry(file2, file2 + HEAL_TS_SEP + ts + HEAL_BACKUP_SUFFIX);
46218
48427
  }
46219
48428
  return ts;
46220
48429
  }
@@ -46282,11 +48491,6 @@ async function guard(id, run) {
46282
48491
  return { id, label: DOCTOR_LABEL[id], status: "UNKNOWN", detail: lineOf(err) };
46283
48492
  }
46284
48493
  }
46285
- function needHome(env) {
46286
- const home = homeDirOf(env);
46287
- if (home === null) throw new CtxError("NO_HOME", { name: "HOME" });
46288
- return home;
46289
- }
46290
48494
  async function codexDb(ctx, adapter) {
46291
48495
  if (adapter.id !== "codex" || !existsSync11(ctx.project.dbPath)) return null;
46292
48496
  try {
@@ -46303,7 +48507,7 @@ async function hookRow(ctx, adapter, host) {
46303
48507
  bundleDir: host.bundleDir,
46304
48508
  env: buildChildEnv(host.env),
46305
48509
  signal: ctx.signal,
46306
- codexConfigDir: codexDirOf(host.env, needHome(host.env)),
48510
+ codexConfigDir: codexDirOf(host.env, requireHomeDir(host.env)),
46307
48511
  // same Codex dir D3 reads (D-N6-CODEX-HOME-2)
46308
48512
  db
46309
48513
  });
@@ -46328,7 +48532,7 @@ async function runDoctorChecks(ctx, adapter, host) {
46328
48532
  D1: () => checkVersion({ bundleSha: BUNDLE_SHA, env: buildChildEnv(env), cwd: project.worktree, signal: ctx.signal }),
46329
48533
  D2: () => checkNode({ nodeVersion: process.version, bunVersion: process.versions.bun }),
46330
48534
  D3: () => checkHostConfig(adapter, env, project.worktree),
46331
- D4: () => checkV1Leftovers(adapter.id, needHome(env), { project: project.worktree, piAgentDir: env[PI_AGENT_DIR_ENV] }),
48535
+ D4: () => checkV1Leftovers(adapter.id, requireHomeDir(env), { project: project.worktree, piAgentDir: piAgentDirOf(env, requireHomeDir(env)), claudeDir: claudeDirOf(env, requireHomeDir(env)), copilotDir: copilotDirOf(env, requireHomeDir(env)), kiroDir: kiroDirOf(env, requireHomeDir(env)), opencodeDir: opencodeDirOf(env, requireHomeDir(env)) }),
46332
48536
  D5: () => hookRow(ctx, adapter, host),
46333
48537
  D5b: () => checkDoubleFire(adapter.id, project.worktree),
46334
48538
  D6: () => checkMcp(ctx),
@@ -46339,7 +48543,8 @@ async function runDoctorChecks(ctx, adapter, host) {
46339
48543
  return r.row;
46340
48544
  },
46341
48545
  D9: () => checkIndex(project),
46342
- D10: () => checkMode(adapter)
48546
+ D10: () => checkMode(adapter),
48547
+ D11: () => checkShell(env)
46343
48548
  };
46344
48549
  const rows = [];
46345
48550
  for (const id of DOCTOR_CHECK_ORDER) rows.push(await guard(id, checks[id]));
@@ -46588,7 +48793,7 @@ async function handler3(raw, ctx) {
46588
48793
  extra.CTX_FILE = abs;
46589
48794
  }
46590
48795
  const runtime = findRuntime(input.language);
46591
- if (runtime === null) return fail4(new CtxError("NO_RUNTIME", { lang: input.language }).toLine());
48796
+ if (runtime === null) return fail4(noRuntimeError(input.language).toLine());
46592
48797
  const env = buildChildEnv(process.env, extra);
46593
48798
  const timeoutMs = input.timeoutMs ?? EXEC_TIMEOUT_MS;
46594
48799
  const journal = { kind: "cmd", key: canonicalKey(TOOL2, input.code), path: input.file ?? null, exit_code: null };
@@ -46661,14 +48866,14 @@ function visit(abs, rel, parent, contain, seen, found) {
46661
48866
  const rules = entries.some((e) => e.name === GITIGNORE && e.isFile()) ? parent.concat(readRules(join12(abs, GITIGNORE), rel)) : parent;
46662
48867
  for (const e of entries) {
46663
48868
  if (e.name === GIT_DIR) continue;
46664
- const path4 = join12(abs, e.name);
48869
+ const path5 = join12(abs, e.name);
46665
48870
  let isDir = e.isDirectory();
46666
48871
  let isFile = e.isFile();
46667
- let target = path4;
48872
+ let target = path5;
46668
48873
  if (e.isSymbolicLink()) {
46669
48874
  let resolved;
46670
48875
  try {
46671
- resolved = realpathSync6(path4);
48876
+ resolved = realpathSync6(path5);
46672
48877
  } catch {
46673
48878
  continue;
46674
48879
  }
@@ -46681,12 +48886,12 @@ function visit(abs, rel, parent, contain, seen, found) {
46681
48886
  const segs = rel.concat(e.name);
46682
48887
  if (ignored(rules, segs, isDir)) continue;
46683
48888
  if (isFile) {
46684
- found.push({ dir: rel, name: e.name, absPath: path4 });
48889
+ found.push({ dir: rel, name: e.name, absPath: path5 });
46685
48890
  } else if (isDir) {
46686
- const key = e.isSymbolicLink() ? target : realpathSync6(path4);
48891
+ const key = e.isSymbolicLink() ? target : realpathSync6(path5);
46687
48892
  if (seen.has(key)) continue;
46688
48893
  seen.add(key);
46689
- visit(path4, segs, rules, contain, seen, found);
48894
+ visit(path5, segs, rules, contain, seen, found);
46690
48895
  }
46691
48896
  }
46692
48897
  }
@@ -46877,12 +49082,12 @@ function tlsName(host) {
46877
49082
  function request(u, conn, proxy, signal) {
46878
49083
  const host = bare(u.hostname);
46879
49084
  const port = u.port === "" ? defaultPort(u.protocol) : Number(u.port);
46880
- const path4 = u.pathname + u.search;
49085
+ const path5 = u.pathname + u.search;
46881
49086
  return new Promise((resolve4, reject) => {
46882
49087
  const onErr = (err) => reject(fail5(causeCode(err)));
46883
49088
  if (proxy === void 0) {
46884
49089
  const mod = u.protocol === "https:" ? https : http;
46885
- const req = mod.request({ host: conn.address, port, path: path4, signal, servername: tlsName(host), headers: { host: u.host } });
49090
+ const req = mod.request({ host: conn.address, port, path: path5, signal, servername: tlsName(host), headers: { host: u.host } });
46886
49091
  req.on("response", resolve4).on("error", onErr).end();
46887
49092
  return;
46888
49093
  }
@@ -46904,7 +49109,7 @@ function request(u, conn, proxy, signal) {
46904
49109
  const req = https.request({
46905
49110
  host,
46906
49111
  port,
46907
- path: path4,
49112
+ path: path5,
46908
49113
  signal,
46909
49114
  headers: { host: u.host },
46910
49115
  createConnection: () => tlsConnect({ socket, host, servername: tlsName(host) })
@@ -47076,12 +49281,12 @@ function reply2(text, isError) {
47076
49281
  return { text, isError, sandboxBytes: 0 };
47077
49282
  }
47078
49283
  function scopesOf(input) {
47079
- const set2 = {
49284
+ const set3 = {
47080
49285
  session: input.session !== void 0,
47081
49286
  source: input.source !== void 0,
47082
49287
  project: input.project === true
47083
49288
  };
47084
- return PURGE_SCOPES.filter((s) => set2[s]);
49289
+ return PURGE_SCOPES.filter((s) => set3[s]);
47085
49290
  }
47086
49291
  function changes(raw, sql, ...args) {
47087
49292
  return Number(raw.prepare(sql).run(...args).changes);
@@ -47146,8 +49351,8 @@ function buildCandidates(rows, sessionId) {
47146
49351
  if (!sessionId) return emptySet();
47147
49352
  const own4 = rows.filter((r) => r.session_id === sessionId).sort((a, b) => a.seq - b.seq);
47148
49353
  const prompts = own4.filter((r) => r.kind === "prompt");
47149
- const last = prompts.length > 0 ? prompts[prompts.length - 1] : void 0;
47150
- const lastRequest = last === void 0 ? null : make("last_request", last, "now: " + firstLine2(last.body), 1, null);
49354
+ const last2 = prompts.length > 0 ? prompts[prompts.length - 1] : void 0;
49355
+ const lastRequest = last2 === void 0 ? null : make("last_request", last2, "now: " + firstLine2(last2.body), 1, null);
47151
49356
  const earlierRequests = prompts.slice(0, prompts.length - 1).map((r) => make("earlier_requests", r, "asked #" + r.seq + ": " + firstLine2(r.body), 1, null));
47152
49357
  const failures = /* @__PURE__ */ new Map();
47153
49358
  const lastOk = /* @__PURE__ */ new Map();
@@ -47171,8 +49376,8 @@ function buildCandidates(rows, sessionId) {
47171
49376
  edits.set(r.path, { row: r, count: (edits.get(r.path)?.count ?? 0) + 1 });
47172
49377
  }
47173
49378
  const changedFiles = [];
47174
- for (const [path4, e] of edits) {
47175
- const c = make("changed_files", e.row, "edited " + path4 + " x" + e.count, e.count, path4);
49379
+ for (const [path5, e] of edits) {
49380
+ const c = make("changed_files", e.row, "edited " + path5 + " x" + e.count, e.count, path5);
47176
49381
  changedFiles.push({ ...c, editCount: e.count });
47177
49382
  }
47178
49383
  changedFiles.sort((a, b) => a.seq - b.seq);
@@ -47186,7 +49391,7 @@ function buildCandidates(rows, sessionId) {
47186
49391
  for (const [key, d] of decided) decisions.push(make("decisions", d.row, "decided #" + d.row.seq + ": " + firstLine2(d.row.body), d.count, key));
47187
49392
  decisions.sort((a, b) => a.seq - b.seq);
47188
49393
  const indexedSources = own4.filter((r) => r.kind === "index").map((r) => make("indexed_sources", r, "indexed " + (r.key ?? ""), 1, r.key));
47189
- const set2 = {
49394
+ const set3 = {
47190
49395
  lastRequest,
47191
49396
  openErrors: capSection(openErrors),
47192
49397
  changedFiles: capSection(changedFiles),
@@ -47194,17 +49399,17 @@ function buildCandidates(rows, sessionId) {
47194
49399
  earlierRequests: capSection(earlierRequests),
47195
49400
  indexedSources: capSection(indexedSources)
47196
49401
  };
47197
- const rest = [...set2.openErrors, ...set2.changedFiles, ...set2.decisions, ...set2.earlierRequests, ...set2.indexedSources];
49402
+ const rest = [...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources];
47198
49403
  const total = rest.length + (lastRequest === null ? 0 : 1);
47199
- if (total <= MAX_CANDIDATES_TOTAL) return set2;
49404
+ if (total <= MAX_CANDIDATES_TOTAL) return set3;
47200
49405
  const drop = new Set(rest.map((c) => c.seq).sort((a, b) => a - b).slice(0, total - MAX_CANDIDATES_TOTAL));
47201
49406
  return {
47202
49407
  lastRequest,
47203
- openErrors: set2.openErrors.filter((c) => !drop.has(c.seq)),
47204
- changedFiles: set2.changedFiles.filter((c) => !drop.has(c.seq)),
47205
- decisions: set2.decisions.filter((c) => !drop.has(c.seq)),
47206
- earlierRequests: set2.earlierRequests.filter((c) => !drop.has(c.seq)),
47207
- indexedSources: set2.indexedSources.filter((c) => !drop.has(c.seq))
49408
+ openErrors: set3.openErrors.filter((c) => !drop.has(c.seq)),
49409
+ changedFiles: set3.changedFiles.filter((c) => !drop.has(c.seq)),
49410
+ decisions: set3.decisions.filter((c) => !drop.has(c.seq)),
49411
+ earlierRequests: set3.earlierRequests.filter((c) => !drop.has(c.seq)),
49412
+ indexedSources: set3.indexedSources.filter((c) => !drop.has(c.seq))
47208
49413
  };
47209
49414
  }
47210
49415
 
@@ -47303,15 +49508,15 @@ function renderState(rows, turn, extras, prefix = "") {
47303
49508
  for (const r of rows) if (newest === void 0 || r.seq > newest.seq) newest = r;
47304
49509
  const sessionId = newest === void 0 ? "" : newest.session_id;
47305
49510
  const upto = newest === void 0 || sessionId === "" ? 0 : newest.seq;
47306
- const set2 = buildCandidates(rows, sessionId);
49511
+ const set3 = buildCandidates(rows, sessionId);
47307
49512
  const openTag = `<context_mode_state session="${sessionId}" upto="${upto}">`;
47308
49513
  const emptyMoreBytes = bytesOf2(moreLine2([], prefix));
47309
49514
  const budget = STATE_BUDGET - (bytesOf2(openTag) + 1 + emptyMoreBytes + 1 + bytesOf2(STATE_CLOSE_TAG));
47310
49515
  let used = 0;
47311
- const pinnedLine = set2.lastRequest === null ? null : lineOf2(set2.lastRequest, prefix);
49516
+ const pinnedLine = set3.lastRequest === null ? null : lineOf2(set3.lastRequest, prefix);
47312
49517
  if (pinnedLine !== null) used += bytesOf2(pinnedLine) + 1;
47313
49518
  const remaining = scoreCandidates(
47314
- [...set2.openErrors, ...set2.changedFiles, ...set2.decisions, ...set2.earlierRequests, ...set2.indexedSources],
49519
+ [...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources],
47315
49520
  turn
47316
49521
  );
47317
49522
  const k = /* @__PURE__ */ new Map();
@@ -47416,8 +49621,8 @@ async function handler6(input, ctx) {
47416
49621
  if (newest === void 0) return reply3(RESUME_EMPTY_LINE, false);
47417
49622
  const sources = listSessionSources(db, sessionId, MAX_CANDIDATES).map((r) => "source " + sourceHandle(r.id) + ": " + r.label + " (" + r.bytes + " B)");
47418
49623
  const goal = readFirstPrompt(db, sessionId);
47419
- const last = readLastPrompt(db, sessionId);
47420
- const units = queryUnits(db, sessionId, recallQueryText(last, goal), RECALL_UNIT_CANDIDATES).map((u) => ({ ...u, label: sourceHandle(u.sourceId) }));
49624
+ const last2 = readLastPrompt(db, sessionId);
49625
+ const units = queryUnits(db, sessionId, recallQueryText(last2, goal), RECALL_UNIT_CANDIDATES).map((u) => ({ ...u, label: sourceHandle(u.sourceId) }));
47421
49626
  const block = renderState(rows, newest.turn, { sources, units });
47422
49627
  if (Buffer.byteLength(block, "utf8") > RESUME_CAP) throw new Error("ctx_resume: state block over RESUME_CAP (render bug).");
47423
49628
  return reply3(block, false);
@@ -47459,8 +49664,8 @@ function reductionPct(t) {
47459
49664
  return Number((t.saved * PERCENT_SCALE / Math.max(1, t.produced)).toFixed(1));
47460
49665
  }
47461
49666
  function tableRow(label, t) {
47462
- const last = t.calls === 0 ? STATS_NO_DATA : String(reductionPct(t));
47463
- return "| " + [label, t.produced + " B", t.returned + " B", t.saved + " B", last].join(" | ") + " |";
49667
+ const last2 = t.calls === 0 ? STATS_NO_DATA : String(reductionPct(t));
49668
+ return "| " + [label, t.produced + " B", t.returned + " B", t.saved + " B", last2].join(" | ") + " |";
47464
49669
  }
47465
49670
  async function handler7(_input, ctx) {
47466
49671
  const db = await openDb(ctx.project, { readOnly: true });
@@ -47494,23 +49699,24 @@ var ctxStats = Object.freeze({
47494
49699
  });
47495
49700
 
47496
49701
  // src/core/tools/upgrade.ts
47497
- import { existsSync as existsSync19, realpathSync as realpathSync7, rmSync as rmSync11 } from "node:fs";
49702
+ import { existsSync as existsSync19, realpathSync as realpathSync7, rmSync as rmSync10 } from "node:fs";
47498
49703
  import { basename as basename5, dirname as dirname9, join as join19 } from "node:path";
47499
49704
 
47500
49705
  // src/core/ops/host-write.ts
47501
- import { copyFileSync, existsSync as existsSync14, mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync6, writeFileSync as writeFileSync4 } from "node:fs";
49706
+ import { copyFileSync, existsSync as existsSync14, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
47502
49707
  import { dirname as dirname8, join as join14 } from "node:path";
47503
49708
  function defaultWrite(file2, text) {
47504
49709
  writeFileSync4(file2, text, "utf8");
47505
49710
  }
47506
49711
  function hostConfigPath(agent, home, env) {
47507
49712
  const own4 = OWN_MCP_ENTRY[agent];
47508
- if (own4 !== void 0) return join14(home, ...own4.file);
49713
+ if (own4 !== void 0) return ownMcpFileOf(agent, own4.file, env, home);
47509
49714
  switch (agent) {
47510
49715
  case "opencode":
47511
- return join14(home, ...AGENT_HOME_DIR.opencode, OPENCODE_BASE_CONFIG_FILE);
49716
+ return join14(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
49717
+ // D-WIN-OPENCODE-DIR-1
47512
49718
  case "pi":
47513
- return join14(env[PI_AGENT_DIR_ENV] ?? join14(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR), SETTINGS_FILE);
49719
+ return join14(piAgentDirOf(env, home), SETTINGS_FILE);
47514
49720
  case "copilot-cli":
47515
49721
  return null;
47516
49722
  default:
@@ -47523,22 +49729,32 @@ function cell2(value) {
47523
49729
  function toRow(file2, edit) {
47524
49730
  return { area: file2 + UPGRADE_AREA_KEY_SEP + edit.path, before: cell2(edit.before), after: cell2(edit.after) };
47525
49731
  }
47526
- function writeWithRollback(file2, text, write) {
49732
+ function writeWithRollback(file2, text, write, atomic) {
47527
49733
  const trash = file2 + UPGRADE_TRASH_SUFFIX;
47528
- const tmp = file2 + HOST_CONFIG_TMP_SUFFIX;
49734
+ const tmp = `${file2}${HOST_CONFIG_TMP_SUFFIX}.${process.pid}`;
47529
49735
  const had = existsSync14(file2);
47530
- mkdirSync4(dirname8(file2), { recursive: true });
49736
+ mkdirSync5(dirname8(file2), { recursive: true });
47531
49737
  if (had) copyFileSync(file2, trash);
47532
49738
  try {
47533
49739
  write(tmp, text);
47534
- renameSync3(tmp, file2);
49740
+ renameWithRetry(tmp, file2, atomic);
47535
49741
  } catch (err) {
47536
- rmSync6(tmp, { force: true });
47537
- if (had) renameSync3(trash, file2);
47538
- else rmSync6(file2, { force: true });
47539
- throw err;
49742
+ removeTmpFile(tmp, atomic);
49743
+ if (!had) {
49744
+ removeTmpFile(file2, atomic);
49745
+ throw replaceFailure(file2, err);
49746
+ }
49747
+ try {
49748
+ renameWithRetry(trash, file2, atomic);
49749
+ } catch (restoreErr) {
49750
+ throw new Error(`${replaceFailure(file2, err).message}. The original is kept at ${trash}`, { cause: restoreErr });
49751
+ }
49752
+ throw replaceFailure(file2, err);
49753
+ }
49754
+ try {
49755
+ unlinkWithRetry(trash, atomic);
49756
+ } catch {
47540
49757
  }
47541
- rmSync6(trash, { force: true });
47542
49758
  }
47543
49759
  function regenerateHostConfig(row5, home, opts = {}) {
47544
49760
  const env = opts.env ?? process.env;
@@ -47549,29 +49765,31 @@ function regenerateHostConfig(row5, home, opts = {}) {
47549
49765
  const exists = existsSync14(current.path);
47550
49766
  if (exists && result.text === current.text) return [];
47551
49767
  const text = result.text === "" && current.format !== "toml" ? JSON.stringify({}) : result.text;
47552
- writeWithRollback(current.path, text, opts.write ?? defaultWrite);
49768
+ writeWithRollback(current.path, current.layout === void 0 ? text : withLayout(text, current.layout), opts.write ?? defaultWrite, opts.atomic ?? {});
47553
49769
  return result.edits.map((e) => toRow(current.path, e));
47554
49770
  }
47555
49771
 
47556
49772
  // src/core/ops/plugin-swap.ts
47557
- import { existsSync as existsSync15, lstatSync, readdirSync as readdirSync7, readlinkSync, renameSync as renameSync4, rmSync as rmSync7, symlinkSync, unlinkSync } from "node:fs";
47558
- import { basename as basename4, join as join15 } from "node:path";
47559
- function linkTarget(path4) {
47560
- return isLink(path4) ? readlinkSync(path4) : null;
49773
+ import { existsSync as existsSync15, lstatSync, readdirSync as readdirSync7, readlinkSync, rmSync as rmSync6, symlinkSync, unlinkSync as unlinkSync2 } from "node:fs";
49774
+ import { basename as basename4, join as join15, win32 as win322 } from "node:path";
49775
+ function linkTarget(path5, win) {
49776
+ if (!isLink(path5)) return null;
49777
+ const target = readlinkSync(path5);
49778
+ return win ? win322.basename(target) : target;
47561
49779
  }
47562
- function isLink(path4) {
47563
- return lstatSync(path4, { throwIfNoEntry: false })?.isSymbolicLink() === true;
49780
+ function isLink(path5) {
49781
+ return lstatSync(path5, { throwIfNoEntry: false })?.isSymbolicLink() === true;
47564
49782
  }
47565
49783
  function generations(agentDir) {
47566
49784
  return readdirSync7(agentDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(UPGRADE_FETCH_DIR_PREFIX) && !name.endsWith(UPGRADE_TRASH_SUFFIX)).sort();
47567
49785
  }
47568
- function settleLinks(link, tmp, old) {
47569
- if (isLink(tmp)) unlinkSync(tmp);
49786
+ function settleLinks(link, tmp, old, opts) {
49787
+ if (isLink(tmp)) unlinkSync2(tmp);
47570
49788
  if (!isLink(old)) return;
47571
- if (isLink(link)) unlinkSync(old);
47572
- else renameSync4(old, link);
49789
+ if (isLink(link)) unlinkSync2(old);
49790
+ else renameWithRetry(old, link, opts);
47573
49791
  }
47574
- function swapPluginCurrent(agentDir, sha) {
49792
+ function swapPluginCurrent(agentDir, sha, opts = {}) {
47575
49793
  const next = join15(agentDir, sha);
47576
49794
  if (!existsSync15(next) || !lstatSync(next).isDirectory()) {
47577
49795
  throw new CtxError("PLUGIN_ROOT_MISSING", { agent: basename4(agentDir), path: next });
@@ -47579,23 +49797,26 @@ function swapPluginCurrent(agentDir, sha) {
47579
49797
  const link = join15(agentDir, PLUGIN_CURRENT_LINK);
47580
49798
  const tmp = link + PLUGIN_LINK_TMP_SUFFIX;
47581
49799
  const old = link + PLUGIN_LINK_OLD_SUFFIX;
47582
- settleLinks(link, tmp, old);
47583
- const before = linkTarget(link);
49800
+ settleLinks(link, tmp, old, opts);
49801
+ const win = (opts.platform ?? process.platform) === "win32";
49802
+ const before = linkTarget(link, win);
47584
49803
  if (before === sha) return { current: next, previous: null, removed: [] };
47585
- symlinkSync(sha, tmp, PLUGIN_LINK_TYPE);
47586
- if (before !== null) renameSync4(link, old);
47587
- renameSync4(tmp, link);
47588
- if (before !== null) unlinkSync(old);
49804
+ const symlink = opts.symlink ?? symlinkSync;
49805
+ if (win) symlink(next, tmp, PLUGIN_LINK_TYPE_WIN32);
49806
+ else symlink(sha, tmp, PLUGIN_LINK_TYPE);
49807
+ if (before !== null) renameWithRetry(link, old, opts);
49808
+ renameWithRetry(tmp, link, opts);
49809
+ if (before !== null) unlinkSync2(old);
47589
49810
  const keep = /* @__PURE__ */ new Set([sha]);
47590
49811
  if (before !== null) keep.add(before);
47591
49812
  const removed = generations(agentDir).filter((name) => !keep.has(name)).map((name) => join15(agentDir, name));
47592
- for (const dir of removed) rmSync7(dir, { recursive: true, force: true });
49813
+ for (const dir of removed) rmSync6(dir, { recursive: true, force: true });
47593
49814
  const previous = before !== null && existsSync15(join15(agentDir, before)) ? join15(agentDir, before) : null;
47594
49815
  return { current: next, previous, removed };
47595
49816
  }
47596
49817
 
47597
49818
  // src/core/ops/release-fetch.ts
47598
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, renameSync as renameSync5, rmSync as rmSync8 } from "node:fs";
49819
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, rmSync as rmSync7 } from "node:fs";
47599
49820
  import { join as join16 } from "node:path";
47600
49821
  function failed(r) {
47601
49822
  if (r.exitCode === null && r.killed === null) return new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
@@ -47607,11 +49828,11 @@ async function git2(bin, args, cwd, env, signal) {
47607
49828
  if (r.exitCode !== 0 || r.killed !== null) throw failed(r);
47608
49829
  return r.stdout.toString().trim();
47609
49830
  }
47610
- async function fetchRelease(agent, url4, env, signal) {
49831
+ async function fetchRelease(agent, url4, env, signal, opts = {}) {
47611
49832
  const agentDir = join16(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, agent);
47612
- mkdirSync5(agentDir, { recursive: true });
49833
+ mkdirSync6(agentDir, { recursive: true });
47613
49834
  const fetchDir = join16(agentDir, UPGRADE_FETCH_DIR_PREFIX + process.pid);
47614
- rmSync8(fetchDir, { recursive: true, force: true });
49835
+ rmSync7(fetchDir, { recursive: true, force: true });
47615
49836
  const gitBin = findRuntime(GIT_BIN, env);
47616
49837
  if (gitBin === null) throw new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
47617
49838
  const childEnv = buildChildEnv(env, { ...GIT_NO_PROMPT_ENV, ...GIT_NO_CRLF_ENV });
@@ -47619,26 +49840,21 @@ async function fetchRelease(agent, url4, env, signal) {
47619
49840
  await git2(gitBin, [...GIT_CLONE_ARGS, RELEASE_BRANCH, url4, fetchDir], agentDir, childEnv, signal);
47620
49841
  const sha = await git2(gitBin, GIT_HEAD_SHA_ARGS, fetchDir, childEnv, signal);
47621
49842
  const dir = join16(agentDir, sha);
47622
- if (existsSync16(dir)) rmSync8(fetchDir, { recursive: true, force: true });
47623
- else renameSync5(fetchDir, dir);
49843
+ if (existsSync16(dir)) rmSync7(fetchDir, { recursive: true, force: true });
49844
+ else renameWithRetry(fetchDir, dir, opts);
47624
49845
  return { sha, dir };
47625
49846
  } catch (e) {
47626
- rmSync8(fetchDir, { recursive: true, force: true });
49847
+ rmSync7(fetchDir, { recursive: true, force: true });
47627
49848
  throw e;
47628
49849
  }
47629
49850
  }
47630
49851
 
47631
49852
  // src/core/ops/uninstall.ts
47632
- import { existsSync as existsSync17, readdirSync as readdirSync8, rmSync as rmSync9, writeFileSync as writeFileSync5 } from "node:fs";
49853
+ import { existsSync as existsSync17, readdirSync as readdirSync8, rmSync as rmSync8, writeFileSync as writeFileSync5 } from "node:fs";
47633
49854
  import { join as join17 } from "node:path";
47634
49855
  function row2(area, before, after) {
47635
49856
  return { area, before, after };
47636
49857
  }
47637
- function homeOf3(env) {
47638
- const home = homeDirOf(env);
47639
- if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
47640
- return home;
47641
- }
47642
49858
  function stopServers(configDir, projectKey) {
47643
49859
  const stopped = listLiveOwners(configDir, projectKey);
47644
49860
  const dir = join17(configDir, PROJECTS_DIR_NAME, projectKey, OWNERS_DIR_NAME);
@@ -47659,13 +49875,13 @@ function removeCache(adapter, env, configDir) {
47659
49875
  case "extension": {
47660
49876
  const root = rootOrNull(adapter, env);
47661
49877
  if (root === null) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
47662
- rmSync9(root, { recursive: true, force: true });
49878
+ rmSync8(root, { recursive: true, force: true });
47663
49879
  return row2(UPGRADE_CACHE_AREA, root, UPGRADE_REMOVED);
47664
49880
  }
47665
49881
  case "plugin": {
47666
49882
  const agentDir = join17(configDir, DATA_PLUGINS_DIR_NAME, adapter.id);
47667
49883
  if (!existsSync17(agentDir)) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
47668
- rmSync9(agentDir, { recursive: true, force: true });
49884
+ rmSync8(agentDir, { recursive: true, force: true });
47669
49885
  return row2(UPGRADE_CACHE_AREA, agentDir, UPGRADE_REMOVED);
47670
49886
  }
47671
49887
  case "config-mcp":
@@ -47684,20 +49900,20 @@ function piSource(entry) {
47684
49900
  return isObj2(entry) ? entry[PI_PACKAGE_SOURCE_KEY] : entry;
47685
49901
  }
47686
49902
  function ownEntries(agent, env) {
47687
- const home = homeOf3(env);
49903
+ const home = requireHomeDir(env);
47688
49904
  const mcp = OWN_MCP_ENTRY[agent];
47689
49905
  if (mcp !== void 0) {
47690
49906
  const top = mcp.key[0];
47691
49907
  const inner = mcp.key.slice(1, -1);
47692
49908
  const own4 = mcp.key[mcp.key.length - 1];
47693
49909
  const holder = (v) => inner.reduce((cur, k) => isObj2(cur) ? cur[k] : void 0, v);
47694
- const without = (v, path4) => {
49910
+ const without = (v, path5) => {
47695
49911
  const o = v;
47696
- if (path4.length === 0) return Object.fromEntries(Object.entries(o).filter(([k]) => k !== own4));
47697
- return { ...o, [path4[0]]: without(o[path4[0]], path4.slice(1)) };
49912
+ if (path5.length === 0) return Object.fromEntries(Object.entries(o).filter(([k]) => k !== own4));
49913
+ return { ...o, [path5[0]]: without(o[path5[0]], path5.slice(1)) };
47698
49914
  };
47699
49915
  return [{
47700
- file: join17(home, ...mcp.file),
49916
+ file: ownMcpFileOf(agent, mcp.file, env, home),
47701
49917
  key: top,
47702
49918
  shown: mcp.key.join(V1_KEY_PATH_SEP),
47703
49919
  has: (v) => {
@@ -47709,7 +49925,8 @@ function ownEntries(agent, env) {
47709
49925
  }
47710
49926
  if (agent === "opencode") {
47711
49927
  return [{
47712
- file: join17(home, ...AGENT_HOME_DIR.opencode, OPENCODE_BASE_CONFIG_FILE),
49928
+ file: join17(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE),
49929
+ // D-WIN-OPENCODE-DIR-1
47713
49930
  key: OPENCODE_PLUGIN_KEY,
47714
49931
  shown: OPENCODE_PLUGIN_KEY,
47715
49932
  has: (v) => Array.isArray(v) && v.includes(OPENCODE_GIT_SPEC),
@@ -47717,7 +49934,7 @@ function ownEntries(agent, env) {
47717
49934
  }];
47718
49935
  }
47719
49936
  if (agent === "pi") {
47720
- const agentDir = env[PI_AGENT_DIR_ENV] ?? join17(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR);
49937
+ const agentDir = piAgentDirOf(env, home);
47721
49938
  return [{
47722
49939
  file: join17(agentDir, SETTINGS_FILE),
47723
49940
  key: PI_PACKAGES_KEY,
@@ -47746,7 +49963,7 @@ function removeProjectData(configDir, projectKey) {
47746
49963
  if (!existsSync17(dir)) return row2(UPGRADE_DATA_AREA, "", UPGRADE_NOT_FOUND);
47747
49964
  if (dir === projects || !isInside(projects, dir)) throw new CtxError("OUTSIDE_ROOT", { p: dir, root: projects });
47748
49965
  for (const name of readdirSync8(dir)) {
47749
- if (name !== OWNERS_DIR_NAME) rmSync9(join17(dir, name), { recursive: true, force: true });
49966
+ if (name !== OWNERS_DIR_NAME) rmSync8(join17(dir, name), { recursive: true, force: true });
47750
49967
  }
47751
49968
  return row2(UPGRADE_DATA_AREA, dir, UPGRADE_DATA_DELETED);
47752
49969
  }
@@ -47759,52 +49976,52 @@ function runUninstall(input) {
47759
49976
  }
47760
49977
 
47761
49978
  // src/core/ops/v1-remove.ts
47762
- import { copyFileSync as copyFileSync2, existsSync as existsSync18, readFileSync as readFileSync10, renameSync as renameSync6, rmSync as rmSync10, writeFileSync as writeFileSync6 } from "node:fs";
49979
+ import { copyFileSync as copyFileSync2, existsSync as existsSync18, readFileSync as readFileSync10, rmSync as rmSync9 } from "node:fs";
47763
49980
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
47764
49981
  var areaOf = (f) => f.path === "" ? f.file : f.file + UPGRADE_AREA_KEY_SEP + f.path;
47765
49982
  var row3 = (f, after) => ({ area: areaOf(f), before: f.reason, after });
47766
49983
  function moveAside(target, undo) {
47767
49984
  const trash = target + UPGRADE_TRASH_SUFFIX;
47768
- rmSync10(trash, { recursive: true, force: true });
47769
- renameSync6(target, trash);
49985
+ rmSync9(trash, { recursive: true, force: true });
49986
+ renameWithRetry(target, trash);
47770
49987
  undo.push({ trash, target });
47771
49988
  }
47772
49989
  function keepOriginal(file2, kept, undo) {
47773
49990
  if (kept.has(file2)) return;
47774
49991
  const trash = file2 + UPGRADE_TRASH_SUFFIX;
47775
- rmSync10(trash, { recursive: true, force: true });
49992
+ rmSync9(trash, { recursive: true, force: true });
47776
49993
  copyFileSync2(file2, trash);
47777
49994
  kept.add(file2);
47778
49995
  undo.push({ trash, target: file2 });
47779
49996
  }
47780
49997
  function cutTomlTable(text, header) {
47781
- const lines = text.split("\n");
47782
- const start = lines.findIndex((l) => l.trim() === header);
47783
- if (start === -1) return null;
47784
- let end = start + 1;
47785
- while (end < lines.length && !lines[end].trim().startsWith(TOML_TABLE_OPEN)) end += 1;
47786
- return [...lines.slice(0, start), ...lines.slice(end)].join("\n");
49998
+ let span;
49999
+ try {
50000
+ span = tomlTableSpans(text).find((t) => t.header.trim() === header);
50001
+ } catch {
50002
+ return null;
50003
+ }
50004
+ return span === void 0 ? null : text.slice(0, span.start) + text.slice(span.end);
47787
50005
  }
47788
50006
  function writeAtomic(file2, text) {
47789
- const tmp = file2 + HOST_CONFIG_TMP_SUFFIX;
47790
- writeFileSync6(tmp, text, "utf8");
47791
- renameSync6(tmp, file2);
50007
+ atomicWriteFile(file2, text);
47792
50008
  }
47793
- function locate(doc, path4) {
47794
- const segs = path4.split(V1_KEY_PATH_SEP);
50009
+ function locate(doc, path5) {
50010
+ const segs = path5.split(V1_KEY_PATH_SEP);
47795
50011
  let cur = doc;
47796
50012
  for (const seg of segs.slice(0, -1)) {
47797
50013
  if (Array.isArray(cur)) cur = cur[Number(seg)];
47798
50014
  else if (isObj3(cur)) cur = cur[seg];
47799
50015
  else return null;
47800
50016
  }
47801
- const last = segs[segs.length - 1];
47802
- if (Array.isArray(cur)) return Number(last) < cur.length ? [cur, last] : null;
47803
- if (isObj3(cur)) return Object.hasOwn(cur, last) ? [cur, last] : null;
50017
+ const last2 = segs[segs.length - 1];
50018
+ if (Array.isArray(cur)) return Number(last2) < cur.length ? [cur, last2] : null;
50019
+ if (isObj3(cur)) return Object.hasOwn(cur, last2) ? [cur, last2] : null;
47804
50020
  return null;
47805
50021
  }
47806
50022
  function stripJsonEntries(agent, file2, findings, kept, undo) {
47807
- const text = readFileSync10(file2, "utf8");
50023
+ const layout = hostLayout(readFileSync10(file2, "utf8"));
50024
+ const text = hostText(readFileSync10(file2, "utf8"));
47808
50025
  const doc = parseHostConfig(agent, file2, text, "jsonc");
47809
50026
  const hit = /* @__PURE__ */ new Set();
47810
50027
  const byContainer = /* @__PURE__ */ new Map();
@@ -47829,7 +50046,7 @@ function stripJsonEntries(agent, file2, findings, kept, undo) {
47829
50046
  const patch = {};
47830
50047
  for (const k of topKeys) patch[k] = doc[k];
47831
50048
  keepOriginal(file2, kept, undo);
47832
- writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2 }, patch);
50049
+ writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2, layout }, patch);
47833
50050
  return hit;
47834
50051
  }
47835
50052
  function removeV1(agent, findings) {
@@ -47852,7 +50069,9 @@ function removeV1(agent, findings) {
47852
50069
  continue;
47853
50070
  }
47854
50071
  if (file2.endsWith(TOML_EXT)) {
47855
- let text = readFileSync10(file2, "utf8");
50072
+ const rawToml = readFileSync10(file2, "utf8");
50073
+ const tomlLayout = hostLayout(rawToml);
50074
+ let text = hostText(rawToml);
47856
50075
  for (const f of list2) {
47857
50076
  const next = cutTomlTable(text, f.path);
47858
50077
  if (next === null) {
@@ -47864,7 +50083,7 @@ function removeV1(agent, findings) {
47864
50083
  }
47865
50084
  if (list2.some((f) => done.get(f) === UPGRADE_REMOVED)) {
47866
50085
  keepOriginal(file2, kept, undo);
47867
- writeAtomic(file2, text);
50086
+ writeAtomic(file2, withLayout(text, tomlLayout));
47868
50087
  }
47869
50088
  continue;
47870
50089
  }
@@ -47874,13 +50093,13 @@ function removeV1(agent, findings) {
47874
50093
  return {
47875
50094
  rows: findings.map((f) => row3(f, done.get(f) ?? UPGRADE_NOT_FOUND)),
47876
50095
  commit() {
47877
- for (const u of undo.splice(0)) rmSync10(u.trash, { recursive: true, force: true });
50096
+ for (const u of undo.splice(0)) rmSync9(u.trash, { recursive: true, force: true });
47878
50097
  },
47879
50098
  rollback() {
47880
50099
  for (const u of undo.splice(0).reverse()) {
47881
50100
  if (!existsSync18(u.trash)) continue;
47882
- rmSync10(u.target, { recursive: true, force: true });
47883
- renameSync6(u.trash, u.target);
50101
+ rmSync9(u.target, { recursive: true, force: true });
50102
+ renameWithRetry(u.trash, u.target);
47884
50103
  }
47885
50104
  }
47886
50105
  };
@@ -47940,11 +50159,6 @@ var ctxUpgradeSchema = external_exports.object({
47940
50159
  function row4(area, before, after) {
47941
50160
  return { area, before, after };
47942
50161
  }
47943
- function homeOf4(env) {
47944
- const home = homeDirOf(env);
47945
- if (home === null) throw new CtxError("NO_HOME", { name: process.platform === "win32" ? "USERPROFILE" : "HOME" });
47946
- return home;
47947
- }
47948
50162
  function bundleDir() {
47949
50163
  return dirname9(process.argv[1] ?? "");
47950
50164
  }
@@ -47969,7 +50183,7 @@ async function checkout(adapter, deps) {
47969
50183
  try {
47970
50184
  verifySums(fetched.dir);
47971
50185
  } catch (err) {
47972
- if (!isCurrent(agentDir, fetched.dir)) rmSync11(fetched.dir, { recursive: true, force: true });
50186
+ if (!isCurrent(agentDir, fetched.dir)) rmSync10(fetched.dir, { recursive: true, force: true });
47973
50187
  throw err;
47974
50188
  }
47975
50189
  const swap = swapPluginCurrent(agentDir, fetched.sha);
@@ -47986,7 +50200,7 @@ async function upgrade(adapter, deps, home) {
47986
50200
  try {
47987
50201
  const step4 = UPGRADE_GIT_CHECKOUT_AGENTS.includes(adapter.id) ? (done = await checkout(adapter, deps)).rows : [hostRow(adapter)];
47988
50202
  const step5 = regenerateHostConfig(adapter, home, { env: deps.env, write: deps.write });
47989
- const findings = detectV1(adapter.id, home, { project: deps.project.worktree, piAgentDir: deps.env[PI_AGENT_DIR_ENV] });
50203
+ const findings = detectV1(adapter.id, home, { project: deps.project.worktree, piAgentDir: piAgentDirOf(deps.env, home), claudeDir: claudeDirOf(deps.env, home), copilotDir: copilotDirOf(deps.env, home), kiroDir: kiroDirOf(deps.env, home), opencodeDir: opencodeDirOf(deps.env, home) });
47990
50204
  removal = removeV1(adapter.id, findings);
47991
50205
  const rows = [...step4, ...step5, ...removal.rows];
47992
50206
  removal.commit();
@@ -48007,7 +50221,7 @@ function renderTable(rows) {
48007
50221
  }
48008
50222
  async function runUpgrade(input, deps) {
48009
50223
  const adapter = getAdapter(deps.project.agent);
48010
- const home = homeOf4(deps.env);
50224
+ const home = requireHomeDir(deps.env);
48011
50225
  const rows = pluginRootRow(adapter, deps.env);
48012
50226
  if ((input.mode ?? UPGRADE_DEFAULT_MODE) === "uninstall") {
48013
50227
  const result = runUninstall({ adapter, project: deps.project, env: deps.env, confirmDelete: input.confirmDelete === true });
@@ -48235,7 +50449,7 @@ async function startServer(argv, env) {
48235
50449
  try {
48236
50450
  const configDir = resolveConfigDir(process.env);
48237
50451
  removeOwnerPid(configDir, db.projectKey, serverId);
48238
- rmSync12(stopMarker(configDir, db.projectKey), { force: true });
50452
+ rmSync11(stopMarker(configDir, db.projectKey), { force: true });
48239
50453
  } catch (err) {
48240
50454
  console.error(err);
48241
50455
  }