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

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 ? "b808edb09ed5aa8e48225f4c77d0d966f0dbc228" : 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
  }
@@ -29280,14 +29352,15 @@ function gitDirs(dir) {
29280
29352
  } catch {
29281
29353
  throw new CtxError("NO_GIT_DIR", { path: dir });
29282
29354
  }
29355
+ const start = cur;
29283
29356
  for (; ; ) {
29284
29357
  const gitDir = gitDirAt(join2(cur, GIT_DIR_NAME));
29285
29358
  if (gitDir !== null) {
29286
29359
  const common = firstLine(join2(gitDir, GIT_COMMONDIR_FILE));
29287
- return { commonDir: realpathSync3.native(common === null ? gitDir : resolve(gitDir, common)), worktree: cur };
29360
+ return { commonDir: realpathSync3.native(common === null ? gitDir : resolve(gitDir, common)), worktree: cur, start };
29288
29361
  }
29289
29362
  const up = dirname2(cur);
29290
- if (up === cur) return null;
29363
+ if (up === cur) return { commonDir: null, start };
29291
29364
  cur = up;
29292
29365
  }
29293
29366
  }
@@ -29319,7 +29392,7 @@ function firstLine(file2) {
29319
29392
  }
29320
29393
  function git(dir, args) {
29321
29394
  const { spawnSync } = process.getBuiltinModule("node:child_process");
29322
- const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
29395
+ const r = spawnSync("git", args, { cwd: dir, shell: false, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
29323
29396
  if (r.error !== void 0 || r.status !== 0) throw new CtxError("NO_GIT_DIR", { path: dir });
29324
29397
  return r.stdout.split("\n").filter((l) => l !== "");
29325
29398
  }
@@ -29333,16 +29406,24 @@ function resolveProject(agent, src) {
29333
29406
  const dir = dirOf(source, src);
29334
29407
  if (dir === void 0) throw new CtxError("NO_PROJECT", { kind: source });
29335
29408
  const repo = gitDirs(dir);
29336
- const plain = repo === null ? realpathSync3.native(dir) : void 0;
29337
- const commonDir = repo?.commonDir ?? plain;
29338
- const worktree = repo?.worktree ?? plain;
29339
- const projectKey = sha256Hex(commonDir).slice(0, PROJECT_KEY_HEX_LEN);
29340
- const projectDir = join2(resolveConfigDir(process.env), PROJECTS_DIR_NAME, projectKey);
29409
+ const plain = repo.commonDir === null ? repo.start : void 0;
29410
+ const commonDir = repo.commonDir ?? repo.start;
29411
+ const worktree = repo.commonDir === null ? repo.start : repo.worktree;
29412
+ let key;
29413
+ let pdir;
29341
29414
  let root;
29342
29415
  return {
29343
- projectKey,
29344
- projectDir,
29345
- dbPath: join2(projectDir, DB_FILE_NAME),
29416
+ get projectKey() {
29417
+ key ??= sha256Hex(commonDir).slice(0, PROJECT_KEY_HEX_LEN);
29418
+ return key;
29419
+ },
29420
+ get projectDir() {
29421
+ pdir ??= join2(resolveConfigDir(process.env), PROJECTS_DIR_NAME, this.projectKey);
29422
+ return pdir;
29423
+ },
29424
+ get dbPath() {
29425
+ return join2(this.projectDir, DB_FILE_NAME);
29426
+ },
29346
29427
  worktree,
29347
29428
  get containmentRoot() {
29348
29429
  root ??= plain ?? containmentRootOf(dir, commonDir);
@@ -31235,9 +31316,9 @@ function isWordChar(cp) {
31235
31316
  while (lo <= hi) {
31236
31317
  const mid = lo + hi >> 1;
31237
31318
  const first = WORD_RANGES[2 * mid];
31238
- const last = WORD_RANGES[2 * mid + 1];
31319
+ const last2 = WORD_RANGES[2 * mid + 1];
31239
31320
  if (cp < first) hi = mid - 1;
31240
- else if (cp > last) lo = mid + 1;
31321
+ else if (cp > last2) lo = mid + 1;
31241
31322
  else return true;
31242
31323
  }
31243
31324
  return false;
@@ -31724,8 +31805,8 @@ function ftsQueryTimeline(db, scope, ctx, sessionId, limit, after, source, memor
31724
31805
  merged.sort(timelineOrder);
31725
31806
  let end = Math.min(limit, merged.length);
31726
31807
  if (end > 0) {
31727
- const last = merged[end - 1].ts;
31728
- while (end < merged.length && merged[end].ts === last) end++;
31808
+ const last2 = merged[end - 1].ts;
31809
+ while (end < merged.length && merged[end].ts === last2) end++;
31729
31810
  }
31730
31811
  const rows = merged.slice(0, end);
31731
31812
  if (rows.length === 0) return { rows, more: false };
@@ -32558,10 +32639,10 @@ function jsonStringifyReplacer3(_, value) {
32558
32639
  return value;
32559
32640
  }
32560
32641
  function cached3(getter) {
32561
- const set2 = false;
32642
+ const set3 = false;
32562
32643
  return {
32563
32644
  get value() {
32564
- if (!set2) {
32645
+ if (!set3) {
32565
32646
  const value = getter();
32566
32647
  Object.defineProperty(this, "value", { value });
32567
32648
  return value;
@@ -32587,10 +32668,10 @@ function floatSafeRemainder3(val, step) {
32587
32668
  return valInt % stepInt / 10 ** decCount;
32588
32669
  }
32589
32670
  function defineLazy3(object4, key, getter) {
32590
- const set2 = false;
32671
+ const set3 = false;
32591
32672
  Object.defineProperty(object4, key, {
32592
32673
  get() {
32593
- if (!set2) {
32674
+ if (!set3) {
32594
32675
  const value = getter();
32595
32676
  object4[key] = value;
32596
32677
  return value;
@@ -32614,10 +32695,10 @@ function assignProp3(target, prop, value) {
32614
32695
  configurable: true
32615
32696
  });
32616
32697
  }
32617
- function getElementAtPath3(obj, path4) {
32618
- if (!path4)
32698
+ function getElementAtPath3(obj, path5) {
32699
+ if (!path5)
32619
32700
  return obj;
32620
- return path4.reduce((acc, key) => acc?.[key], obj);
32701
+ return path5.reduce((acc, key) => acc?.[key], obj);
32621
32702
  }
32622
32703
  function promiseAllObject3(promisesObj) {
32623
32704
  const keys = Object.keys(promisesObj);
@@ -32937,11 +33018,11 @@ function aborted3(x, startIndex = 0) {
32937
33018
  }
32938
33019
  return false;
32939
33020
  }
32940
- function prefixIssues3(path4, issues) {
33021
+ function prefixIssues3(path5, issues) {
32941
33022
  return issues.map((iss) => {
32942
33023
  var _a5;
32943
33024
  (_a5 = iss).path ?? (_a5.path = []);
32944
- iss.path.unshift(path4);
33025
+ iss.path.unshift(path5);
32945
33026
  return iss;
32946
33027
  });
32947
33028
  }
@@ -33078,7 +33159,7 @@ function treeifyError2(error42, _mapper) {
33078
33159
  return issue4.message;
33079
33160
  };
33080
33161
  const result = { errors: [] };
33081
- const processError = (error43, path4 = []) => {
33162
+ const processError = (error43, path5 = []) => {
33082
33163
  var _a5, _b;
33083
33164
  for (const issue4 of error43.issues) {
33084
33165
  if (issue4.code === "invalid_union" && issue4.errors.length) {
@@ -33088,7 +33169,7 @@ function treeifyError2(error42, _mapper) {
33088
33169
  } else if (issue4.code === "invalid_element") {
33089
33170
  processError({ issues: issue4.issues }, issue4.path);
33090
33171
  } else {
33091
- const fullpath = [...path4, ...issue4.path];
33172
+ const fullpath = [...path5, ...issue4.path];
33092
33173
  if (fullpath.length === 0) {
33093
33174
  result.errors.push(mapper(issue4));
33094
33175
  continue;
@@ -33118,9 +33199,9 @@ function treeifyError2(error42, _mapper) {
33118
33199
  processError(error42);
33119
33200
  return result;
33120
33201
  }
33121
- function toDotPath(path4) {
33202
+ function toDotPath(path5) {
33122
33203
  const segs = [];
33123
- for (const seg of path4) {
33204
+ for (const seg of path5) {
33124
33205
  if (typeof seg === "number")
33125
33206
  segs.push(`[${seg}]`);
33126
33207
  else if (typeof seg === "symbol")
@@ -34460,8 +34541,8 @@ var $ZodDate3 = /* @__PURE__ */ $constructor3("$ZodDate", (inst, def) => {
34460
34541
  }
34461
34542
  const input = payload.value;
34462
34543
  const isDate = input instanceof Date;
34463
- const isValidDate = isDate && !Number.isNaN(input.getTime());
34464
- if (isValidDate)
34544
+ const isValidDate2 = isDate && !Number.isNaN(input.getTime());
34545
+ if (isValidDate2)
34465
34546
  return payload;
34466
34547
  payload.issues.push({
34467
34548
  expected: "date",
@@ -43485,6 +43566,14 @@ function buildChildEnv(parent, extra) {
43485
43566
  // src/core/sandbox/runtimes.ts
43486
43567
  import { accessSync, constants as fsConstants, statSync as statSync2 } from "node:fs";
43487
43568
  import path from "node:path";
43569
+
43570
+ // src/core/sandbox/path-entries.ts
43571
+ function pathEntries(value, platform = process.platform, delimiter = platform === "win32" ? ";" : ":") {
43572
+ const win = platform === "win32";
43573
+ return value.split(delimiter).map((e) => win && e.length >= 2 && e.startsWith('"') && e.endsWith('"') ? e.slice(1, -1) : e).filter(Boolean);
43574
+ }
43575
+
43576
+ // src/core/sandbox/runtimes.ts
43488
43577
  var PATHEXT_SEPARATOR = ";";
43489
43578
  var WIN_STARTABLE_EXT = Object.freeze([".exe", ".com"]);
43490
43579
  function isWin() {
@@ -43494,7 +43583,7 @@ function candidates(lang) {
43494
43583
  const win = isWin();
43495
43584
  switch (lang) {
43496
43585
  case "shell":
43497
- return win ? ["sh.exe", "bash.exe"] : ["sh"];
43586
+ return win ? [] : ["sh"];
43498
43587
  case "powershell":
43499
43588
  return ["pwsh", "pwsh.exe", "powershell.exe"];
43500
43589
  case "javascript":
@@ -43525,7 +43614,8 @@ function isRunnable(full) {
43525
43614
  }
43526
43615
  }
43527
43616
  function findRuntime(lang, env = process.env) {
43528
- const dirs = (env.PATH ?? "").split(path.delimiter).filter((d) => d !== "");
43617
+ if (isWin() && WIN_SHELL_LANGS.includes(lang)) return findGitBash(env);
43618
+ const dirs = pathEntries(env.PATH ?? "", process.platform, path.delimiter);
43529
43619
  const pathExt = isWin() ? (env.PATHEXT ?? PATHEXT_DEFAULT).split(PATHEXT_SEPARATOR).filter((e) => e !== "") : [];
43530
43620
  const names = candidates(lang);
43531
43621
  let shim = null;
@@ -43541,6 +43631,18 @@ function findRuntime(lang, env = process.env) {
43541
43631
  }
43542
43632
  return shim;
43543
43633
  }
43634
+ function findGitBash(env) {
43635
+ const git3 = findRuntime(GIT_BIN, env);
43636
+ if (git3 === null) return null;
43637
+ for (const rel of GIT_BASH_RELATIVE) {
43638
+ const full = path.resolve(path.dirname(git3), ...rel);
43639
+ if (isRunnable(full)) return full;
43640
+ }
43641
+ return null;
43642
+ }
43643
+ function noRuntimeError(lang) {
43644
+ return isWin() && WIN_SHELL_LANGS.includes(lang) ? new CtxError("NO_GIT_BASH") : new CtxError("NO_RUNTIME", { lang });
43645
+ }
43544
43646
 
43545
43647
  // src/core/sandbox/spawn.ts
43546
43648
  import { spawn } from "node:child_process";
@@ -43648,19 +43750,19 @@ function readAutoMemory(project) {
43648
43750
  if (project.agent !== "claude-code") return [];
43649
43751
  const rows = [];
43650
43752
  for (const segs of CLAUDE_CODE_MEMORY_FILES) {
43651
- const path4 = join5(project.worktree, ...segs);
43652
- if (!isInside(project.worktree, path4)) continue;
43753
+ const path5 = join5(project.worktree, ...segs);
43754
+ if (!isInside(project.worktree, path5)) continue;
43653
43755
  try {
43654
- const st = statSync3(path4);
43756
+ const st = statSync3(path5);
43655
43757
  if (!st.isFile()) continue;
43656
43758
  rows.push({
43657
43759
  origin: "memory",
43658
43760
  ts: Math.trunc(st.mtimeMs),
43659
43761
  seq: null,
43660
43762
  sourceId: null,
43661
- path: path4,
43763
+ path: path5,
43662
43764
  label: segs.join("/"),
43663
- text: readFileSync3(path4, "utf8")
43765
+ text: readFileSync3(path5, "utf8")
43664
43766
  });
43665
43767
  } catch {
43666
43768
  }
@@ -43965,7 +44067,7 @@ function stoppedAt(cmd, error42) {
43965
44067
  return { head: headOf(cmd), block: headOf(cmd) + error42, exitCode: null, bytes: 0, error: error42 };
43966
44068
  }
43967
44069
  async function runCommand(cmd, shell, ctx, deadline, boundMs) {
43968
- if (shell === null) return stoppedAt(cmd, formatError3("NO_RUNTIME", { lang: SHELL }));
44070
+ if (shell === null) return stoppedAt(cmd, noRuntimeError(SHELL).toLine());
43969
44071
  const left = deadline - Date.now();
43970
44072
  if (left <= 0) return stoppedAt(cmd, formatError3("TIMEOUT", { ms: boundMs }));
43971
44073
  const r = await runProcess([shell, SHELL_INLINE_FLAG, cmd], {
@@ -44085,19 +44187,19 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
44085
44187
  const shell = findRuntime(SHELL);
44086
44188
  const pool = await runPool(commands.map((c) => () => runCommand(c, shell, ctx, deadline, boundMs)), ONE_AT_A_TIME, (r) => r.error !== null);
44087
44189
  const ran = pool.results;
44088
- const last = ran[ran.length - 1];
44190
+ const last2 = ran[ran.length - 1];
44089
44191
  const sandboxBytes = ran.reduce((n, r) => n + r.bytes, 0);
44090
44192
  const label = LABEL_PREFIX + ctx.turn;
44091
44193
  try {
44092
44194
  const db = await openDb(ctx.project);
44093
44195
  let sections;
44094
44196
  let idx;
44095
- const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " + last.exitCode;
44197
+ const summary = commands.length + " command(s), " + queries.length + " querie(s), exit " + last2.exitCode;
44096
44198
  const footer = "more: ctx_search({queries:[...], source:" + JSON.stringify(label) + "})";
44097
44199
  let notice;
44098
44200
  try {
44099
44201
  idx = indexCombined(db, ctx, label, ran, deadline, budgetBytes);
44100
- const stop = last.error;
44202
+ const stop = last2.error;
44101
44203
  const cut = idx.indexed < idx.total ? "Indexed " + idx.indexed + " of " + idx.total + " B." : null;
44102
44204
  const timeout = formatError3("TIMEOUT", { ms: boundMs });
44103
44205
  const cause = stop ?? (ctx.signal.aborted ? CANCELLED_LINE : idx.stop === "deadline" ? timeout : null);
@@ -44115,7 +44217,7 @@ async function runBatch(input, ctx, boundMs, budgetBytes) {
44115
44217
  isError: false,
44116
44218
  // step 11
44117
44219
  sandboxBytes,
44118
- journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code: last.exitCode }
44220
+ journal: { kind: "cmd", key: canonicalKey(TOOL, commands.join(LINE_SEP)), path: null, exit_code: last2.exitCode }
44119
44221
  };
44120
44222
  } catch (err) {
44121
44223
  if (err instanceof CtxError) return { text: err.toLine(), isError: true, sandboxBytes };
@@ -44492,8 +44594,14 @@ var VSCODE_EVENTS = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostTool
44492
44594
  var MCP_PREFIX2 = "mcp_";
44493
44595
  var MCP_SEP2 = "_";
44494
44596
  var SESSION_START_NEW = "new";
44495
- var SHELL_TOOL_NAME = "run_in_terminal";
44496
- var NATIVE_TO_CANONICAL4 = { [SHELL_TOOL_NAME]: "Bash" };
44597
+ var SHELL_TOOL_NAMES = Object.freeze(["run_in_terminal", "runTerminalCommand", "bash", "powershell"]);
44598
+ var READ_TOOL_NAMES = Object.freeze(["read_file", "view"]);
44599
+ var WEBFETCH_TOOL_NAMES = Object.freeze(["fetch_webpage", "web_fetch"]);
44600
+ var NATIVE_TO_CANONICAL4 = Object.fromEntries([
44601
+ ...SHELL_TOOL_NAMES.map((n) => [n, "Bash"]),
44602
+ ...READ_TOOL_NAMES.map((n) => [n, "Read"]),
44603
+ ...WEBFETCH_TOOL_NAMES.map((n) => [n, "WebFetch"])
44604
+ ]);
44497
44605
  function canonicalName4(name) {
44498
44606
  if (name.startsWith(TOOL_NAME_PREFIX6)) return name.slice(TOOL_NAME_PREFIX6.length);
44499
44607
  if (Object.hasOwn(NATIVE_TO_CANONICAL4, name)) return NATIVE_TO_CANONICAL4[name];
@@ -44503,6 +44611,26 @@ function canonicalName4(name) {
44503
44611
  if (sep2 <= 0 || sep2 === rest.length - 1) return name;
44504
44612
  return "mcp:" + rest.slice(0, sep2) + ":" + rest.slice(sep2 + MCP_SEP2.length);
44505
44613
  }
44614
+ var isNum = (v) => typeof v === "number" && Number.isFinite(v);
44615
+ function policyInput(name, canonical, input) {
44616
+ if (canonical === "Read" && READ_TOOL_NAMES.includes(name)) {
44617
+ const out = { ...input };
44618
+ if (name === "read_file") {
44619
+ if (typeof input.filePath === "string") out.file_path = input.filePath;
44620
+ if (isNum(input.startLine)) out.offset = input.startLine;
44621
+ if (isNum(input.startLine) && isNum(input.endLine) && input.endLine >= input.startLine) out.limit = input.endLine - input.startLine + 1;
44622
+ } else if (Array.isArray(input.view_range) && isNum(input.view_range[0])) {
44623
+ out.offset = input.view_range[0];
44624
+ const end = input.view_range[1];
44625
+ if (isNum(end) && end >= input.view_range[0]) out.limit = end - input.view_range[0] + 1;
44626
+ }
44627
+ return out;
44628
+ }
44629
+ if (canonical === "WebFetch" && name === "fetch_webpage" && Array.isArray(input.urls) && typeof input.urls[0] === "string") {
44630
+ return { ...input, url: input.urls[0] };
44631
+ }
44632
+ return input;
44633
+ }
44506
44634
  function readResult4(resp) {
44507
44635
  const text = resp === void 0 ? "" : typeof resp === "string" ? resp : JSON.stringify(resp);
44508
44636
  const isError = typeof resp === "object" && resp !== null && resp.is_error === true;
@@ -44550,7 +44678,8 @@ function decodeCamel(p, name) {
44550
44678
  if (event === "UserPromptSubmit" && typeof p.prompt === "string") ev.prompt = p.prompt;
44551
44679
  if (event === "PreToolUse" || event === "PostToolUse") {
44552
44680
  const toolName = String(p.toolName ?? "");
44553
- ev.tool = { name: toolName, canonicalName: canonicalName4(toolName), input: readArgs2(p.toolArgs) };
44681
+ const canonical = canonicalName4(toolName);
44682
+ ev.tool = { name: toolName, canonicalName: canonical, input: policyInput(toolName, canonical, readArgs2(p.toolArgs)) };
44554
44683
  }
44555
44684
  if (event === "PostToolUse") ev.result = readCamelResult(p.toolResult);
44556
44685
  return ev;
@@ -44572,7 +44701,8 @@ function decode8(raw) {
44572
44701
  if (event === "PreToolUse" || event === "PostToolUse") {
44573
44702
  const name = String(p.tool_name ?? "");
44574
44703
  const input = isRecord2(p.tool_input) ? p.tool_input : {};
44575
- ev.tool = { name, canonicalName: canonicalName4(name), input };
44704
+ const canonical = canonicalName4(name);
44705
+ ev.tool = { name, canonicalName: canonical, input: policyInput(name, canonical, input) };
44576
44706
  }
44577
44707
  if (event === "PostToolUse") ev.result = readResult4(p.tool_response);
44578
44708
  return ev;
@@ -44596,8 +44726,8 @@ var KIRO_EVENTS = {
44596
44726
  };
44597
44727
  var PROMPT_ENV = "USER_PROMPT";
44598
44728
  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"]));
44729
+ var SHELL_TOOL_NAMES2 = Object.freeze(["execute_bash", "execute_pwsh", "shell"]);
44730
+ var NATIVE_TO_CANONICAL5 = Object.fromEntries(SHELL_TOOL_NAMES2.map((n) => [n, "Bash"]));
44601
44731
  var MCP_SEP3 = "_";
44602
44732
  var KIRO_SOURCES = { startup: "startup", resume: "resume", clear: "clear", compact: "compact" };
44603
44733
  function canonicalName5(name) {
@@ -44738,8 +44868,8 @@ var OPENCODE_EVENTS = {
44738
44868
  compaction: "PreCompact",
44739
44869
  "step-finish": "Usage"
44740
44870
  };
44741
- var SHELL_TOOL_NAME2 = "bash";
44742
- var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME2]: "Bash" };
44871
+ var SHELL_TOOL_NAME = "bash";
44872
+ var NATIVE_TO_CANONICAL7 = { webfetch: "WebFetch", [SHELL_TOOL_NAME]: "Bash" };
44743
44873
  function toCanonicalTool(name) {
44744
44874
  if (name.startsWith(OWN_WIRE_PREFIX)) return name.slice(OWN_WIRE_PREFIX.length);
44745
44875
  return Object.prototype.hasOwnProperty.call(NATIVE_TO_CANONICAL7, name) ? NATIVE_TO_CANONICAL7[name] : name;
@@ -44888,7 +45018,8 @@ var ADAPTERS = Object.freeze([
44888
45018
  projectSource: "arg:workspaceFolder",
44889
45019
  toolNamePrefix: TOOL_NAME_PREFIX6,
44890
45020
  // PreCompact sets the pending flag (ADR-0009 §6, DEVIATIONS D-M3-A4-1).
44891
- nativeTools: { shell: [SHELL_TOOL_NAME] },
45021
+ nativeTools: { shell: [...SHELL_TOOL_NAMES], read: [...READ_TOOL_NAMES], webfetch: [...WEBFETCH_TOOL_NAMES] },
45022
+ // D-HF-VSCODE-PROJECT-1, D-N7-VSCODE-TOOLS-1
44892
45023
  execReadOnlyHint: false,
44893
45024
  eventMap: { ...CLAUDE_EVENTS, PreCompact: "PreCompact" },
44894
45025
  compactDelivery: "pending-flag",
@@ -44906,7 +45037,7 @@ var ADAPTERS = Object.freeze([
44906
45037
  installMode: "mcp-entry",
44907
45038
  projectSource: "arg:--agent+cwd",
44908
45039
  toolNamePrefix: TOOL_NAME_PREFIX7,
44909
- nativeTools: { shell: [...SHELL_TOOL_NAMES] },
45040
+ nativeTools: { shell: [...SHELL_TOOL_NAMES2] },
44910
45041
  execReadOnlyHint: false,
44911
45042
  // D-HF-KIRO-SHELL-1, D-N7-KIRO-1
44912
45043
  eventMap: { SessionStart: "SessionStart", UserPromptSubmit: "UserPromptSubmit", PreToolUse: "PreToolUse", PostToolUse: "PostToolUse" },
@@ -44963,7 +45094,7 @@ var ADAPTERS = Object.freeze([
44963
45094
  installMode: "in-process",
44964
45095
  projectSource: "spawn-cwd",
44965
45096
  toolNamePrefix: TOOL_NAME_PREFIX10,
44966
- nativeTools: { shell: [SHELL_TOOL_NAME2] },
45097
+ nativeTools: { shell: [SHELL_TOOL_NAME] },
44967
45098
  execReadOnlyHint: false,
44968
45099
  // D-HF-OPENCODE-SHELL-1
44969
45100
  // Usage: step-finish cost row (DEVIATIONS D-M5-arch-2).
@@ -44993,305 +45124,2157 @@ function getAdapter(id) {
44993
45124
  import { join as join9 } from "node:path";
44994
45125
 
44995
45126
  // src/core/ops/detect-v1.ts
44996
- import { existsSync as existsSync4, opendirSync, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
45127
+ import { existsSync as existsSync5, opendirSync, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
44997
45128
  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;
45129
+ import { join as join7 } from "node:path";
45130
+
45131
+ // src/core/ops/host-config.ts
45132
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
45133
+ import { dirname as dirname3, join as join6 } from "node:path";
45134
+
45135
+ // node_modules/eslint-visitor-keys/lib/visitor-keys.js
45136
+ var KEYS2 = {
45137
+ ArrayExpression: ["elements"],
45138
+ ArrayPattern: ["elements"],
45139
+ ArrowFunctionExpression: ["params", "body"],
45140
+ AssignmentExpression: ["left", "right"],
45141
+ AssignmentPattern: ["left", "right"],
45142
+ AwaitExpression: ["argument"],
45143
+ BinaryExpression: ["left", "right"],
45144
+ BlockStatement: ["body"],
45145
+ BreakStatement: ["label"],
45146
+ CallExpression: ["callee", "arguments"],
45147
+ CatchClause: ["param", "body"],
45148
+ ChainExpression: ["expression"],
45149
+ ClassBody: ["body"],
45150
+ ClassDeclaration: ["id", "superClass", "body"],
45151
+ ClassExpression: ["id", "superClass", "body"],
45152
+ ConditionalExpression: ["test", "consequent", "alternate"],
45153
+ ContinueStatement: ["label"],
45154
+ DebuggerStatement: [],
45155
+ DoWhileStatement: ["body", "test"],
45156
+ EmptyStatement: [],
45157
+ ExperimentalRestProperty: ["argument"],
45158
+ ExperimentalSpreadProperty: ["argument"],
45159
+ ExportAllDeclaration: ["exported", "source", "attributes"],
45160
+ ExportDefaultDeclaration: ["declaration"],
45161
+ ExportNamedDeclaration: [
45162
+ "declaration",
45163
+ "specifiers",
45164
+ "source",
45165
+ "attributes"
45166
+ ],
45167
+ ExportSpecifier: ["local", "exported"],
45168
+ ExpressionStatement: ["expression"],
45169
+ ForInStatement: ["left", "right", "body"],
45170
+ ForOfStatement: ["left", "right", "body"],
45171
+ ForStatement: ["init", "test", "update", "body"],
45172
+ FunctionDeclaration: ["id", "params", "body"],
45173
+ FunctionExpression: ["id", "params", "body"],
45174
+ Identifier: [],
45175
+ IfStatement: ["test", "consequent", "alternate"],
45176
+ ImportAttribute: ["key", "value"],
45177
+ ImportDeclaration: ["specifiers", "source", "attributes"],
45178
+ ImportDefaultSpecifier: ["local"],
45179
+ ImportExpression: ["source", "options"],
45180
+ ImportNamespaceSpecifier: ["local"],
45181
+ ImportSpecifier: ["imported", "local"],
45182
+ JSXAttribute: ["name", "value"],
45183
+ JSXClosingElement: ["name"],
45184
+ JSXClosingFragment: [],
45185
+ JSXElement: ["openingElement", "children", "closingElement"],
45186
+ JSXEmptyExpression: [],
45187
+ JSXExpressionContainer: ["expression"],
45188
+ JSXFragment: ["openingFragment", "children", "closingFragment"],
45189
+ JSXIdentifier: [],
45190
+ JSXMemberExpression: ["object", "property"],
45191
+ JSXNamespacedName: ["namespace", "name"],
45192
+ JSXOpeningElement: ["name", "attributes"],
45193
+ JSXOpeningFragment: [],
45194
+ JSXSpreadAttribute: ["argument"],
45195
+ JSXSpreadChild: ["expression"],
45196
+ JSXText: [],
45197
+ LabeledStatement: ["label", "body"],
45198
+ Literal: [],
45199
+ LogicalExpression: ["left", "right"],
45200
+ MemberExpression: ["object", "property"],
45201
+ MetaProperty: ["meta", "property"],
45202
+ MethodDefinition: ["key", "value"],
45203
+ NewExpression: ["callee", "arguments"],
45204
+ ObjectExpression: ["properties"],
45205
+ ObjectPattern: ["properties"],
45206
+ PrivateIdentifier: [],
45207
+ Program: ["body"],
45208
+ Property: ["key", "value"],
45209
+ PropertyDefinition: ["key", "value"],
45210
+ RestElement: ["argument"],
45211
+ ReturnStatement: ["argument"],
45212
+ SequenceExpression: ["expressions"],
45213
+ SpreadElement: ["argument"],
45214
+ StaticBlock: ["body"],
45215
+ Super: [],
45216
+ SwitchCase: ["test", "consequent"],
45217
+ SwitchStatement: ["discriminant", "cases"],
45218
+ TaggedTemplateExpression: ["tag", "quasi"],
45219
+ TemplateElement: [],
45220
+ TemplateLiteral: ["quasis", "expressions"],
45221
+ ThisExpression: [],
45222
+ ThrowStatement: ["argument"],
45223
+ TryStatement: ["block", "handler", "finalizer"],
45224
+ UnaryExpression: ["argument"],
45225
+ UpdateExpression: ["argument"],
45226
+ VariableDeclaration: ["declarations"],
45227
+ VariableDeclarator: ["id", "init"],
45228
+ WhileStatement: ["test", "body"],
45229
+ WithStatement: ["object", "body"],
45230
+ YieldExpression: ["argument"]
45231
+ };
45232
+ var NODE_TYPES = Object.keys(KEYS2);
45233
+ for (const type of NODE_TYPES) {
45234
+ Object.freeze(KEYS2[type]);
45235
+ }
45236
+ Object.freeze(KEYS2);
45237
+ var visitor_keys_default = KEYS2;
45238
+
45239
+ // node_modules/eslint-visitor-keys/lib/index.js
45240
+ function unionWith(additionalKeys) {
45241
+ const retv = (
45242
+ /** @type {{ [type: string]: ReadonlyArray<string> }} */
45243
+ Object.assign({}, visitor_keys_default)
45244
+ );
45245
+ for (const type of Object.keys(additionalKeys)) {
45246
+ if (Object.hasOwn(retv, type)) {
45247
+ const keys = new Set(additionalKeys[type]);
45248
+ for (const key of retv[type]) {
45249
+ keys.add(key);
45250
+ }
45251
+ retv[type] = Object.freeze(Array.from(keys));
45252
+ } else {
45253
+ retv[type] = Object.freeze(Array.from(additionalKeys[type]));
45014
45254
  }
45015
- if (c === '"') {
45016
- inStr = true;
45017
- out += c;
45018
- continue;
45255
+ }
45256
+ return Object.freeze(retv);
45257
+ }
45258
+
45259
+ // node_modules/toml-eslint-parser/lib/index.mjs
45260
+ function last(arr) {
45261
+ return arr[arr.length - 1] ?? null;
45262
+ }
45263
+ function toKeyName(node3) {
45264
+ return node3.type === "TOMLBare" ? node3.name : node3.value;
45265
+ }
45266
+ var TOMLVerImpl = class {
45267
+ constructor(major, minor) {
45268
+ this.major = major;
45269
+ this.minor = minor;
45270
+ }
45271
+ lt(major, minor) {
45272
+ return this.major < major || this.major === major && this.minor < minor;
45273
+ }
45274
+ gte(major, minor) {
45275
+ return this.major > major || this.major === major && this.minor >= minor;
45276
+ }
45277
+ };
45278
+ var TOML_VERSION_1_0 = new TOMLVerImpl(1, 0);
45279
+ var TOML_VERSION_1_1 = new TOMLVerImpl(1, 1);
45280
+ var DEFAULT_TOML_VERSION = TOML_VERSION_1_1;
45281
+ var SUPPORTED_TOML_VERSIONS = {
45282
+ "1.0": TOML_VERSION_1_0,
45283
+ "1.0.0": TOML_VERSION_1_0,
45284
+ "1.1": TOML_VERSION_1_1,
45285
+ "1.1.0": TOML_VERSION_1_1,
45286
+ latest: TOML_VERSION_1_1,
45287
+ next: TOML_VERSION_1_1
45288
+ };
45289
+ function getTOMLVer(v) {
45290
+ return v && SUPPORTED_TOML_VERSIONS[v] || DEFAULT_TOML_VERSION;
45291
+ }
45292
+ var MESSAGES = {
45293
+ "unterminated-string": "Unterminated string constant",
45294
+ "unterminated-table-key": "Unterminated table-key",
45295
+ "unterminated-array": "Unterminated array",
45296
+ "unterminated-inline-table": "Unterminated inline table",
45297
+ "missing-key": "Empty bare keys are not allowed",
45298
+ "missing-newline": "Must be a newline",
45299
+ "missing-equals-sign": "Expected equal (=) token",
45300
+ "missing-value": "Unspecified values are invalid",
45301
+ "missing-comma": "Expected comma (,) token",
45302
+ "dupe-keys": "Defining a key multiple times is invalid",
45303
+ "unexpected-char": "Unexpected character",
45304
+ "unexpected-token": "Unexpected token",
45305
+ "invalid-control-character": "Control characters (codes < 0x1f and 0x7f) are not allowed",
45306
+ "invalid-comment-character": "Invalid code point {{cp}} within comments",
45307
+ "invalid-key-value-newline": "The key, equals sign, and value must be on the same line",
45308
+ "invalid-inline-table-newline": "No newlines are allowed between the curly braces unless they are valid within a value",
45309
+ "invalid-underscore": "Underscores are allowed between digits",
45310
+ "invalid-space": "Unexpected spaces",
45311
+ "invalid-three-quotes": "Three or more quotes are not permitted",
45312
+ "invalid-date": "Unexpected invalid date",
45313
+ "invalid-time": "Unexpected invalid time",
45314
+ "invalid-leading-zero": "Leading zeros are not allowed",
45315
+ "invalid-trailing-comma-in-inline-table": "Trailing comma is not permitted in an inline table",
45316
+ "invalid-char-in-escape-sequence": "Invalid character in escape sequence",
45317
+ "invalid-consecutive-dots-in-key": "Consecutive dots are not permitted in keys",
45318
+ "invalid-code-point": "Invalid code point {{cp}}",
45319
+ "invalid-trailing-dot-in-key": "Keys cannot end with a dot",
45320
+ "invalid-leading-dot-in-key": "Keys cannot start with a dot"
45321
+ };
45322
+ function getMessage(code, data) {
45323
+ if (data) return MESSAGES[code].replace(/\{\{(.*?)\}\}/gu, (_, name$2) => {
45324
+ if (name$2 in data) return data[name$2];
45325
+ return `{{${name$2}}}`;
45326
+ });
45327
+ return MESSAGES[code];
45328
+ }
45329
+ var ParseError = class extends SyntaxError {
45330
+ /**
45331
+ * Initialize this ParseError instance.
45332
+ *
45333
+ */
45334
+ constructor(code, offset, line, column, data) {
45335
+ super(getMessage(code, data));
45336
+ this.index = offset;
45337
+ this.lineNumber = line;
45338
+ this.column = column;
45339
+ }
45340
+ };
45341
+ var CodePoint = {
45342
+ EOF: -1,
45343
+ NULL: 0,
45344
+ SOH: 1,
45345
+ BACKSPACE: 8,
45346
+ TABULATION: 9,
45347
+ LINE_FEED: 10,
45348
+ FORM_FEED: 12,
45349
+ CARRIAGE_RETURN: 13,
45350
+ ESCAPE: 27,
45351
+ SO: 14,
45352
+ US: 31,
45353
+ SPACE: 32,
45354
+ QUOTATION_MARK: 34,
45355
+ HASH: 35,
45356
+ SINGLE_QUOTE: 39,
45357
+ PLUS_SIGN: 43,
45358
+ COMMA: 44,
45359
+ DASH: 45,
45360
+ DOT: 46,
45361
+ DIGIT_0: 48,
45362
+ DIGIT_1: 49,
45363
+ DIGIT_2: 50,
45364
+ DIGIT_3: 51,
45365
+ DIGIT_7: 55,
45366
+ DIGIT_9: 57,
45367
+ COLON: 58,
45368
+ EQUALS_SIGN: 61,
45369
+ LATIN_CAPITAL_A: 65,
45370
+ LATIN_CAPITAL_E: 69,
45371
+ LATIN_CAPITAL_F: 70,
45372
+ LATIN_CAPITAL_T: 84,
45373
+ LATIN_CAPITAL_U: 85,
45374
+ LATIN_CAPITAL_Z: 90,
45375
+ LEFT_BRACKET: 91,
45376
+ BACKSLASH: 92,
45377
+ RIGHT_BRACKET: 93,
45378
+ UNDERSCORE: 95,
45379
+ LATIN_SMALL_A: 97,
45380
+ LATIN_SMALL_B: 98,
45381
+ LATIN_SMALL_E: 101,
45382
+ LATIN_SMALL_F: 102,
45383
+ LATIN_SMALL_I: 105,
45384
+ LATIN_SMALL_L: 108,
45385
+ LATIN_SMALL_N: 110,
45386
+ LATIN_SMALL_O: 111,
45387
+ LATIN_SMALL_R: 114,
45388
+ LATIN_SMALL_S: 115,
45389
+ LATIN_SMALL_T: 116,
45390
+ LATIN_SMALL_U: 117,
45391
+ LATIN_SMALL_X: 120,
45392
+ LATIN_SMALL_Z: 122,
45393
+ LEFT_BRACE: 123,
45394
+ RIGHT_BRACE: 125,
45395
+ TILDE: 126,
45396
+ DELETE: 127,
45397
+ PAD: 128,
45398
+ SUPERSCRIPT_TWO: 178,
45399
+ SUPERSCRIPT_THREE: 179,
45400
+ SUPERSCRIPT_ONE: 185,
45401
+ VULGAR_FRACTION_ONE_QUARTER: 188,
45402
+ VULGAR_FRACTION_THREE_QUARTERS: 190,
45403
+ LATIN_CAPITAL_LETTER_A_WITH_GRAVE: 192,
45404
+ LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS: 214,
45405
+ LATIN_CAPITAL_LETTER_O_WITH_STROKE: 216,
45406
+ LATIN_SMALL_LETTER_O_WITH_DIAERESIS: 246,
45407
+ LATIN_SMALL_LETTER_O_WITH_STROKE: 248,
45408
+ GREEK_SMALL_REVERSED_DOTTED_LUNATE_SIGMA_SYMBOL: 891,
45409
+ GREEK_CAPITAL_LETTER_YOT: 895,
45410
+ CP_1FFF: 8191,
45411
+ ZERO_WIDTH_NON_JOINER: 8204,
45412
+ ZERO_WIDTH_JOINER: 8205,
45413
+ UNDERTIE: 8255,
45414
+ CHARACTER_TIE: 8256,
45415
+ SUPERSCRIPT_ZERO: 8304,
45416
+ CP_218F: 8591,
45417
+ CIRCLED_DIGIT_ONE: 9312,
45418
+ NEGATIVE_CIRCLED_DIGIT_ZERO: 9471,
45419
+ GLAGOLITIC_CAPITAL_LETTER_AZU: 11264,
45420
+ CP_2FEF: 12271,
45421
+ IDEOGRAPHIC_COMMA: 12289,
45422
+ CP_D7FF: 55295,
45423
+ CP_E000: 57344,
45424
+ CJK_COMPATIBILITY_IDEOGRAPH_F900: 63744,
45425
+ ARABIC_LIGATURE_SALAAMUHU_ALAYNAA: 64975,
45426
+ ARABIC_LIGATURE_SALLA_USED_AS_KORANIC_STOP_SIGN_ISOLATED_FORM: 65008,
45427
+ REPLACEMENT_CHARACTER: 65533,
45428
+ LINEAR_B_SYLLABLE_B008_A: 65536,
45429
+ CP_EFFFF: 983039,
45430
+ CP_10FFFF: 1114111
45431
+ };
45432
+ function isControl(cp) {
45433
+ return cp >= CodePoint.NULL && cp <= CodePoint.US;
45434
+ }
45435
+ function isWhitespace(cp) {
45436
+ return cp === CodePoint.TABULATION || cp === CodePoint.SPACE;
45437
+ }
45438
+ function isEOL(cp) {
45439
+ return cp === CodePoint.LINE_FEED || cp === CodePoint.CARRIAGE_RETURN;
45440
+ }
45441
+ function isUpperLetter(cp) {
45442
+ return cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_Z;
45443
+ }
45444
+ function isLowerLetter(cp) {
45445
+ return cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_Z;
45446
+ }
45447
+ function isLetter2(cp) {
45448
+ return isLowerLetter(cp) || isUpperLetter(cp);
45449
+ }
45450
+ function isDigit(cp) {
45451
+ return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_9;
45452
+ }
45453
+ function isHexDig(cp) {
45454
+ return isDigit(cp) || cp >= CodePoint.LATIN_SMALL_A && cp <= CodePoint.LATIN_SMALL_F || cp >= CodePoint.LATIN_CAPITAL_A && cp <= CodePoint.LATIN_CAPITAL_F;
45455
+ }
45456
+ function isOctalDig(cp) {
45457
+ return cp >= CodePoint.DIGIT_0 && cp <= CodePoint.DIGIT_7;
45458
+ }
45459
+ function isUnicodeScalarValue(cp) {
45460
+ return cp >= 0 && cp <= 55295 || cp >= 57344 && cp <= 1114111;
45461
+ }
45462
+ function sortedLastIndex(array4, value) {
45463
+ let low = 0;
45464
+ let high = array4.length;
45465
+ while (low < high) {
45466
+ const mid = low + high >>> 1;
45467
+ const val = array4[mid];
45468
+ if (val === value) return mid + 1;
45469
+ if (val < value) low = mid + 1;
45470
+ else high = mid;
45471
+ }
45472
+ return low;
45473
+ }
45474
+ var Locations = class {
45475
+ constructor() {
45476
+ this.offsets = [];
45477
+ }
45478
+ addOffset(offset) {
45479
+ for (let i = this.offsets.length - 1; i >= 0; i--) {
45480
+ const element = this.offsets[i];
45481
+ if (element === offset) return;
45482
+ if (element < offset) break;
45019
45483
  }
45020
- if (c === "/" && text[i + 1] === "/") {
45021
- while (i < text.length && text[i] !== "\n") i++;
45022
- out += "\n";
45023
- continue;
45484
+ this.offsets.push(offset);
45485
+ }
45486
+ /**
45487
+ * Calculate the location of the given index.
45488
+ * @param index The index to calculate their location.
45489
+ * @returns The location of the index.
45490
+ */
45491
+ getLocFromIndex(offset) {
45492
+ const line = sortedLastIndex(this.offsets, offset) + 1;
45493
+ return {
45494
+ line,
45495
+ column: offset - (line === 1 ? 0 : this.offsets[line - 2])
45496
+ };
45497
+ }
45498
+ };
45499
+ var CodePointIterator = class {
45500
+ /**
45501
+ * Initialize this char iterator.
45502
+ */
45503
+ constructor(text) {
45504
+ this.locs = new Locations();
45505
+ this.lastCodePoint = CodePoint.NULL;
45506
+ this.start = -1;
45507
+ this.end = 0;
45508
+ this.text = text;
45509
+ }
45510
+ next() {
45511
+ if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
45512
+ return this.lastCodePoint = this.moveAt(this.end);
45513
+ }
45514
+ getLocFromIndex(index) {
45515
+ return this.locs.getLocFromIndex(index);
45516
+ }
45517
+ eat(cp) {
45518
+ if (this.text.codePointAt(this.end) === cp) {
45519
+ this.next();
45520
+ return true;
45024
45521
  }
45025
- if (c === "/" && text[i + 1] === "*") {
45026
- const end = text.indexOf("*/", i + 2);
45027
- i = end === -1 ? text.length : end + 1;
45028
- continue;
45522
+ return false;
45523
+ }
45524
+ moveAt(offset) {
45525
+ this.start = this.end = offset;
45526
+ const cp = this.text.codePointAt(this.start) ?? CodePoint.EOF;
45527
+ if (cp === CodePoint.EOF) {
45528
+ this.end = this.start;
45529
+ return cp;
45530
+ }
45531
+ this.end += cp >= 65536 ? 2 : 1;
45532
+ if (cp === CodePoint.LINE_FEED) this.locs.addOffset(this.end);
45533
+ else if (cp === CodePoint.CARRIAGE_RETURN) {
45534
+ if (this.text.codePointAt(this.end) === CodePoint.LINE_FEED) {
45535
+ this.end++;
45536
+ this.locs.addOffset(this.end);
45537
+ }
45538
+ return CodePoint.LINE_FEED;
45539
+ }
45540
+ return cp;
45541
+ }
45542
+ };
45543
+ var HAS_BIGINT = typeof BigInt !== "undefined";
45544
+ var RADIX_PREFIXES = {
45545
+ 16: "0x",
45546
+ 10: "",
45547
+ 8: "0o",
45548
+ 2: "0b"
45549
+ };
45550
+ var ESCAPES_1_0 = {
45551
+ [CodePoint.QUOTATION_MARK]: CodePoint.QUOTATION_MARK,
45552
+ [CodePoint.BACKSLASH]: CodePoint.BACKSLASH,
45553
+ [CodePoint.LATIN_SMALL_B]: CodePoint.BACKSPACE,
45554
+ [CodePoint.LATIN_SMALL_F]: CodePoint.FORM_FEED,
45555
+ [CodePoint.LATIN_SMALL_N]: CodePoint.LINE_FEED,
45556
+ [CodePoint.LATIN_SMALL_R]: CodePoint.CARRIAGE_RETURN,
45557
+ [CodePoint.LATIN_SMALL_T]: CodePoint.TABULATION
45558
+ };
45559
+ var ESCAPES_LATEST = {
45560
+ ...ESCAPES_1_0,
45561
+ [CodePoint.LATIN_SMALL_E]: CodePoint.ESCAPE
45562
+ };
45563
+ var Tokenizer = class {
45564
+ /**
45565
+ * Initialize this tokenizer.
45566
+ */
45567
+ constructor(text, parserOptions) {
45568
+ this.backCode = false;
45569
+ this.lastCodePoint = CodePoint.NULL;
45570
+ this.state = "DATA";
45571
+ this.token = null;
45572
+ this.tokenStart = -1;
45573
+ this.valuesEnabled = false;
45574
+ this.text = text;
45575
+ this.parserOptions = parserOptions || {};
45576
+ this.codePointIterator = new CodePointIterator(text);
45577
+ this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
45578
+ this.ESCAPES = this.tomlVersion.gte(1, 1) ? ESCAPES_LATEST : ESCAPES_1_0;
45579
+ }
45580
+ get start() {
45581
+ return this.codePointIterator.start;
45582
+ }
45583
+ get end() {
45584
+ return this.codePointIterator.end;
45585
+ }
45586
+ getLocFromIndex(index) {
45587
+ return this.codePointIterator.getLocFromIndex(index);
45588
+ }
45589
+ /**
45590
+ * Report an invalid character error.
45591
+ */
45592
+ reportParseError(code, data) {
45593
+ const offset = this.codePointIterator.start;
45594
+ const loc = this.codePointIterator.getLocFromIndex(offset);
45595
+ throw new ParseError(code, offset, loc.line, loc.column, data);
45596
+ }
45597
+ /**
45598
+ * Get the next token.
45599
+ */
45600
+ nextToken() {
45601
+ let token = this.token;
45602
+ if (token != null) {
45603
+ this.token = null;
45604
+ return token;
45605
+ }
45606
+ let cp = this.lastCodePoint;
45607
+ while (cp !== CodePoint.EOF && !this.token) {
45608
+ cp = this.nextCode();
45609
+ const nextState = this[this.state](cp);
45610
+ if (!nextState) throw new Error(`Unknown error: pre state=${this.state}`);
45611
+ this.state = nextState;
45612
+ }
45613
+ token = this.token;
45614
+ this.token = null;
45615
+ return token;
45616
+ }
45617
+ /**
45618
+ * Get the next code point.
45619
+ */
45620
+ nextCode() {
45621
+ if (this.lastCodePoint === CodePoint.EOF) return CodePoint.EOF;
45622
+ if (this.backCode) {
45623
+ this.backCode = false;
45624
+ return this.lastCodePoint;
45029
45625
  }
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;
45626
+ return this.lastCodePoint = this.codePointIterator.next();
45627
+ }
45628
+ /**
45629
+ * Eat the next code point.
45630
+ */
45631
+ eatCode(cp) {
45632
+ if (this.lastCodePoint === CodePoint.EOF) return false;
45633
+ if (this.backCode) {
45634
+ if (this.lastCodePoint === cp) {
45635
+ this.backCode = false;
45636
+ return true;
45637
+ }
45638
+ return false;
45034
45639
  }
45035
- out += c;
45640
+ return this.codePointIterator.eat(cp);
45036
45641
  }
45037
- return out;
45038
- }
45039
- function readJson(file2) {
45040
- try {
45041
- return JSON.parse(stripJsonc(readFileSync4(file2, "utf8")));
45042
- } catch {
45043
- return void 0;
45642
+ /**
45643
+ * Moves the character position to the given position.
45644
+ */
45645
+ moveAt(loc) {
45646
+ if (this.backCode) this.backCode = false;
45647
+ this.lastCodePoint = this.codePointIterator.moveAt(loc);
45044
45648
  }
45045
- }
45046
- function readText(file2) {
45047
- try {
45048
- return readFileSync4(file2, "utf8");
45049
- } catch {
45050
- return "";
45649
+ /**
45650
+ * Back the current code point as the given state.
45651
+ */
45652
+ back(state) {
45653
+ this.backCode = true;
45654
+ return state;
45051
45655
  }
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
- });
45656
+ punctuatorToken() {
45657
+ this.startToken();
45658
+ this.endToken("Punctuator", "end");
45066
45659
  }
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
- });
45660
+ startToken() {
45661
+ this.tokenStart = this.codePointIterator.start;
45077
45662
  }
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));
45663
+ /**
45664
+ * Commit the current token.
45665
+ */
45666
+ endToken(type, pos, option1, option2) {
45667
+ const { tokenStart } = this;
45668
+ const end = this.codePointIterator[pos];
45669
+ const range = [tokenStart, end];
45670
+ const loc = {
45671
+ start: this.codePointIterator.getLocFromIndex(tokenStart),
45672
+ end: this.codePointIterator.getLocFromIndex(end)
45673
+ };
45674
+ if (type === "Block") this.token = {
45675
+ type,
45676
+ value: this.text.slice(tokenStart + 1, end),
45677
+ range,
45678
+ loc
45679
+ };
45680
+ else {
45681
+ let token;
45682
+ const value = this.text.slice(tokenStart, end);
45683
+ if (type === "BasicString" || type === "LiteralString" || type === "MultiLineBasicString" || type === "MultiLineLiteralString") token = {
45684
+ type,
45685
+ value,
45686
+ string: option1,
45687
+ range,
45688
+ loc
45689
+ };
45690
+ else if (type === "Integer") {
45691
+ const text = option1;
45692
+ token = {
45693
+ type,
45694
+ value,
45695
+ number: parseInt(text, option2),
45696
+ bigint: HAS_BIGINT ? BigInt(RADIX_PREFIXES[option2] + text) : null,
45697
+ range,
45698
+ loc
45699
+ };
45700
+ } else if (type === "Float") token = {
45701
+ type,
45702
+ value,
45703
+ number: option1,
45704
+ range,
45705
+ loc
45706
+ };
45707
+ else if (type === "Boolean") token = {
45708
+ type,
45709
+ value,
45710
+ boolean: option1,
45711
+ range,
45712
+ loc
45713
+ };
45714
+ else if (type === "LocalDate" || type === "LocalTime" || type === "LocalDateTime" || type === "OffsetDateTime") token = {
45715
+ type,
45716
+ value,
45717
+ date: option1,
45718
+ range,
45719
+ loc
45720
+ };
45721
+ else token = {
45722
+ type,
45723
+ value,
45724
+ range,
45725
+ loc
45726
+ };
45727
+ this.token = token;
45728
+ }
45088
45729
  }
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));
45730
+ DATA(cp) {
45731
+ while (isWhitespace(cp) || isEOL(cp)) cp = this.nextCode();
45732
+ if (cp === CodePoint.HASH) {
45733
+ this.startToken();
45734
+ return "COMMENT";
45735
+ }
45736
+ if (cp === CodePoint.QUOTATION_MARK) {
45737
+ this.startToken();
45738
+ return "BASIC_STRING";
45739
+ }
45740
+ if (cp === CodePoint.SINGLE_QUOTE) {
45741
+ this.startToken();
45742
+ return "LITERAL_STRING";
45743
+ }
45744
+ 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) {
45745
+ this.punctuatorToken();
45746
+ return "DATA";
45747
+ }
45748
+ if (this.valuesEnabled) {
45749
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
45750
+ this.startToken();
45751
+ return "SIGN";
45752
+ }
45753
+ if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) {
45754
+ this.startToken();
45755
+ return this.back("NAN_OR_INF");
45756
+ }
45757
+ if (isDigit(cp)) {
45758
+ this.startToken();
45759
+ return this.back("NUMBER");
45760
+ }
45761
+ if (cp === CodePoint.LATIN_SMALL_T || cp === CodePoint.LATIN_SMALL_F) {
45762
+ this.startToken();
45763
+ return this.back("BOOLEAN");
45764
+ }
45765
+ } else if (isUnquotedKeyChar(cp, this.tomlVersion)) {
45766
+ this.startToken();
45767
+ return "BARE";
45768
+ }
45769
+ if (cp === CodePoint.EOF) return "DATA";
45770
+ return this.reportParseError("unexpected-char");
45096
45771
  }
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));
45772
+ COMMENT(cp) {
45773
+ const processCommentChar = this.tomlVersion.gte(1, 1) ? (c) => {
45774
+ if (!isNonEOL(c)) this.reportParseError("invalid-comment-character", { cp: JSON.stringify(String.fromCodePoint(c)).slice(1, -1) });
45775
+ } : (c) => {
45776
+ if (isControlOtherThanTab(c)) this.reportParseErrorControlChar();
45777
+ };
45778
+ while (!isEOL(cp) && cp !== CodePoint.EOF) {
45779
+ processCommentChar(cp);
45780
+ cp = this.nextCode();
45781
+ }
45782
+ this.endToken("Block", "start");
45783
+ return "DATA";
45100
45784
  }
45101
- mcpEntry(file2, doc, out);
45785
+ BARE(cp) {
45786
+ while (isUnquotedKeyChar(cp, this.tomlVersion)) cp = this.nextCode();
45787
+ this.endToken("Bare", "start");
45788
+ return this.back("DATA");
45789
+ }
45790
+ BASIC_STRING(cp) {
45791
+ if (cp === CodePoint.QUOTATION_MARK) {
45792
+ cp = this.nextCode();
45793
+ if (cp === CodePoint.QUOTATION_MARK) return "MULTI_LINE_BASIC_STRING";
45794
+ this.endToken("BasicString", "start", "");
45795
+ return this.back("DATA");
45796
+ }
45797
+ const out = [];
45798
+ while (cp !== CodePoint.QUOTATION_MARK && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
45799
+ if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45800
+ if (cp === CodePoint.BACKSLASH) {
45801
+ cp = this.nextCode();
45802
+ const ecp = this.ESCAPES[cp];
45803
+ if (ecp) {
45804
+ out.push(ecp);
45805
+ cp = this.nextCode();
45806
+ continue;
45807
+ } else if (cp === CodePoint.LATIN_SMALL_U) {
45808
+ const code = this.parseUnicode(4);
45809
+ out.push(code);
45810
+ cp = this.nextCode();
45811
+ continue;
45812
+ } else if (cp === CodePoint.LATIN_CAPITAL_U) {
45813
+ const code = this.parseUnicode(8);
45814
+ out.push(code);
45815
+ cp = this.nextCode();
45816
+ continue;
45817
+ } else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
45818
+ const code = this.parseUnicode(2);
45819
+ out.push(code);
45820
+ cp = this.nextCode();
45821
+ continue;
45822
+ }
45823
+ return this.reportParseError("invalid-char-in-escape-sequence");
45824
+ }
45825
+ out.push(cp);
45826
+ cp = this.nextCode();
45827
+ }
45828
+ if (cp !== CodePoint.QUOTATION_MARK) return this.reportParseError("unterminated-string");
45829
+ this.endToken("BasicString", "end", String.fromCodePoint(...out));
45830
+ return "DATA";
45831
+ }
45832
+ MULTI_LINE_BASIC_STRING(cp) {
45833
+ const out = [];
45834
+ if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
45835
+ while (cp !== CodePoint.EOF) {
45836
+ if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45837
+ if (cp === CodePoint.QUOTATION_MARK) {
45838
+ const startPos = this.codePointIterator.start;
45839
+ if (this.eatCode(CodePoint.QUOTATION_MARK) && this.eatCode(CodePoint.QUOTATION_MARK)) {
45840
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45841
+ out.push(CodePoint.QUOTATION_MARK);
45842
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45843
+ out.push(CodePoint.QUOTATION_MARK);
45844
+ if (this.eatCode(CodePoint.QUOTATION_MARK)) {
45845
+ this.moveAt(startPos);
45846
+ return this.reportParseError("invalid-three-quotes");
45847
+ }
45848
+ }
45849
+ }
45850
+ this.endToken("MultiLineBasicString", "end", String.fromCodePoint(...out));
45851
+ return "DATA";
45852
+ }
45853
+ this.moveAt(startPos);
45854
+ }
45855
+ if (cp === CodePoint.BACKSLASH) {
45856
+ cp = this.nextCode();
45857
+ const ecp = this.ESCAPES[cp];
45858
+ if (ecp) {
45859
+ out.push(ecp);
45860
+ cp = this.nextCode();
45861
+ continue;
45862
+ } else if (cp === CodePoint.LATIN_SMALL_U) {
45863
+ const code = this.parseUnicode(4);
45864
+ out.push(code);
45865
+ cp = this.nextCode();
45866
+ continue;
45867
+ } else if (cp === CodePoint.LATIN_CAPITAL_U) {
45868
+ const code = this.parseUnicode(8);
45869
+ out.push(code);
45870
+ cp = this.nextCode();
45871
+ continue;
45872
+ } else if (cp === CodePoint.LATIN_SMALL_X && this.tomlVersion.gte(1, 1)) {
45873
+ const code = this.parseUnicode(2);
45874
+ out.push(code);
45875
+ cp = this.nextCode();
45876
+ continue;
45877
+ } else if (cp === CodePoint.LINE_FEED) {
45878
+ cp = this.nextCode();
45879
+ while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
45880
+ continue;
45881
+ } else if (isWhitespace(cp)) {
45882
+ let valid = true;
45883
+ const startPos = this.codePointIterator.start;
45884
+ let nextCp;
45885
+ while ((nextCp = this.nextCode()) !== CodePoint.EOF) {
45886
+ if (nextCp === CodePoint.LINE_FEED) break;
45887
+ if (!isWhitespace(nextCp)) {
45888
+ this.moveAt(startPos);
45889
+ valid = false;
45890
+ break;
45891
+ }
45892
+ }
45893
+ if (valid) {
45894
+ cp = this.nextCode();
45895
+ while (isWhitespace(cp) || cp === CodePoint.LINE_FEED) cp = this.nextCode();
45896
+ continue;
45897
+ }
45898
+ }
45899
+ return this.reportParseError("invalid-char-in-escape-sequence");
45900
+ }
45901
+ out.push(cp);
45902
+ cp = this.nextCode();
45903
+ }
45904
+ return this.reportParseError("unterminated-string");
45905
+ }
45906
+ LITERAL_STRING(cp) {
45907
+ if (cp === CodePoint.SINGLE_QUOTE) {
45908
+ cp = this.nextCode();
45909
+ if (cp === CodePoint.SINGLE_QUOTE) return "MULTI_LINE_LITERAL_STRING";
45910
+ this.endToken("LiteralString", "start", "");
45911
+ return this.back("DATA");
45912
+ }
45913
+ const out = [];
45914
+ while (cp !== CodePoint.SINGLE_QUOTE && cp !== CodePoint.EOF && cp !== CodePoint.LINE_FEED) {
45915
+ if (isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45916
+ out.push(cp);
45917
+ cp = this.nextCode();
45918
+ }
45919
+ if (cp !== CodePoint.SINGLE_QUOTE) return this.reportParseError("unterminated-string");
45920
+ this.endToken("LiteralString", "end", String.fromCodePoint(...out));
45921
+ return "DATA";
45922
+ }
45923
+ MULTI_LINE_LITERAL_STRING(cp) {
45924
+ const out = [];
45925
+ if (cp === CodePoint.LINE_FEED) cp = this.nextCode();
45926
+ while (cp !== CodePoint.EOF) {
45927
+ if (cp !== CodePoint.LINE_FEED && isControlOtherThanTab(cp)) return this.reportParseErrorControlChar();
45928
+ if (cp === CodePoint.SINGLE_QUOTE) {
45929
+ const startPos = this.codePointIterator.start;
45930
+ if (this.eatCode(CodePoint.SINGLE_QUOTE) && this.eatCode(CodePoint.SINGLE_QUOTE)) {
45931
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45932
+ out.push(CodePoint.SINGLE_QUOTE);
45933
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45934
+ out.push(CodePoint.SINGLE_QUOTE);
45935
+ if (this.eatCode(CodePoint.SINGLE_QUOTE)) {
45936
+ this.moveAt(startPos);
45937
+ return this.reportParseError("invalid-three-quotes");
45938
+ }
45939
+ }
45940
+ }
45941
+ this.endToken("MultiLineLiteralString", "end", String.fromCodePoint(...out));
45942
+ return "DATA";
45943
+ }
45944
+ this.moveAt(startPos);
45945
+ }
45946
+ out.push(cp);
45947
+ cp = this.nextCode();
45948
+ }
45949
+ return this.reportParseError("unterminated-string");
45950
+ }
45951
+ SIGN(cp) {
45952
+ if (cp === CodePoint.LATIN_SMALL_N || cp === CodePoint.LATIN_SMALL_I) return this.back("NAN_OR_INF");
45953
+ if (isDigit(cp)) return this.back("NUMBER");
45954
+ return this.reportParseError("unexpected-char");
45955
+ }
45956
+ NAN_OR_INF(cp) {
45957
+ if (cp === CodePoint.LATIN_SMALL_N) {
45958
+ const startPos = this.codePointIterator.start;
45959
+ if (this.eatCode(CodePoint.LATIN_SMALL_A) && this.eatCode(CodePoint.LATIN_SMALL_N)) {
45960
+ this.endToken("Float", "end", NaN);
45961
+ return "DATA";
45962
+ }
45963
+ this.moveAt(startPos);
45964
+ } else if (cp === CodePoint.LATIN_SMALL_I) {
45965
+ const startPos = this.codePointIterator.start;
45966
+ if (this.eatCode(CodePoint.LATIN_SMALL_N) && this.eatCode(CodePoint.LATIN_SMALL_F)) {
45967
+ this.endToken("Float", "end", this.text[this.tokenStart] === "-" ? -Infinity : Infinity);
45968
+ return "DATA";
45969
+ }
45970
+ this.moveAt(startPos);
45971
+ }
45972
+ return this.reportParseError("unexpected-char");
45973
+ }
45974
+ NUMBER(cp) {
45975
+ const start = this.text[this.tokenStart];
45976
+ const sign = start === "+" ? CodePoint.PLUS_SIGN : start === "-" ? CodePoint.DASH : CodePoint.NULL;
45977
+ if (cp === CodePoint.DIGIT_0) {
45978
+ if (sign === CodePoint.NULL) {
45979
+ const startPos = this.codePointIterator.start;
45980
+ const nextCp$1 = this.nextCode();
45981
+ if (isDigit(nextCp$1)) {
45982
+ const nextNextCp = this.nextCode();
45983
+ if (nextNextCp === CodePoint.COLON) {
45984
+ this.data = {
45985
+ hasDate: false,
45986
+ year: 0,
45987
+ month: 0,
45988
+ day: 0,
45989
+ hour: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1)),
45990
+ minute: 0,
45991
+ second: 0
45992
+ };
45993
+ return "TIME_MINUTE";
45994
+ }
45995
+ if (isDigit(nextNextCp)) {
45996
+ const nextNextNextCp = this.nextCode();
45997
+ if (isDigit(nextNextNextCp) && this.eatCode(CodePoint.DASH)) {
45998
+ this.data = {
45999
+ hasDate: true,
46000
+ year: Number(String.fromCodePoint(CodePoint.DIGIT_0, nextCp$1, nextNextCp, nextNextNextCp)),
46001
+ month: 0,
46002
+ day: 0,
46003
+ hour: 0,
46004
+ minute: 0,
46005
+ second: 0
46006
+ };
46007
+ return "DATE_MONTH";
46008
+ }
46009
+ }
46010
+ this.moveAt(startPos);
46011
+ return this.reportParseError("invalid-leading-zero");
46012
+ }
46013
+ this.moveAt(startPos);
46014
+ }
46015
+ cp = this.nextCode();
46016
+ if (cp === CodePoint.LATIN_SMALL_X || cp === CodePoint.LATIN_SMALL_O || cp === CodePoint.LATIN_SMALL_B) {
46017
+ if (sign !== CodePoint.NULL) return this.reportParseError("unexpected-char");
46018
+ return cp === CodePoint.LATIN_SMALL_X ? "HEX" : cp === CodePoint.LATIN_SMALL_O ? "OCTAL" : "BINARY";
46019
+ }
46020
+ if (cp === CodePoint.LATIN_SMALL_E || cp === CodePoint.LATIN_CAPITAL_E) {
46021
+ this.data = {
46022
+ minus: sign === CodePoint.DASH,
46023
+ left: [CodePoint.DIGIT_0]
46024
+ };
46025
+ return "EXPONENT_RIGHT";
46026
+ }
46027
+ if (cp === CodePoint.DOT) {
46028
+ this.data = {
46029
+ minus: sign === CodePoint.DASH,
46030
+ absInt: [CodePoint.DIGIT_0]
46031
+ };
46032
+ return "FRACTIONAL_RIGHT";
46033
+ }
46034
+ this.endToken("Integer", "start", "0", 10);
46035
+ return this.back("DATA");
46036
+ }
46037
+ const { out, nextCp, hasUnderscore } = this.parseDigits(cp, isDigit);
46038
+ if (nextCp === CodePoint.DASH && sign === CodePoint.NULL && !hasUnderscore && out.length === 4) {
46039
+ this.data = {
46040
+ hasDate: true,
46041
+ year: Number(String.fromCodePoint(...out)),
46042
+ month: 0,
46043
+ day: 0,
46044
+ hour: 0,
46045
+ minute: 0,
46046
+ second: 0
46047
+ };
46048
+ return "DATE_MONTH";
46049
+ }
46050
+ if (nextCp === CodePoint.COLON && sign === CodePoint.NULL && !hasUnderscore && out.length === 2) {
46051
+ this.data = {
46052
+ hasDate: false,
46053
+ year: 0,
46054
+ month: 0,
46055
+ day: 0,
46056
+ hour: Number(String.fromCodePoint(...out)),
46057
+ minute: 0,
46058
+ second: 0
46059
+ };
46060
+ return "TIME_MINUTE";
46061
+ }
46062
+ if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
46063
+ this.data = {
46064
+ minus: sign === CodePoint.DASH,
46065
+ left: out
46066
+ };
46067
+ return "EXPONENT_RIGHT";
46068
+ }
46069
+ if (nextCp === CodePoint.DOT) {
46070
+ this.data = {
46071
+ minus: sign === CodePoint.DASH,
46072
+ absInt: out
46073
+ };
46074
+ return "FRACTIONAL_RIGHT";
46075
+ }
46076
+ this.endToken("Integer", "start", sign === CodePoint.DASH ? String.fromCodePoint(CodePoint.DASH, ...out) : String.fromCodePoint(...out), 10);
46077
+ return this.back("DATA");
46078
+ }
46079
+ HEX(cp) {
46080
+ const { out } = this.parseDigits(cp, isHexDig);
46081
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 16);
46082
+ return this.back("DATA");
46083
+ }
46084
+ OCTAL(cp) {
46085
+ const { out } = this.parseDigits(cp, isOctalDig);
46086
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 8);
46087
+ return this.back("DATA");
46088
+ }
46089
+ BINARY(cp) {
46090
+ const { out } = this.parseDigits(cp, (c) => c === CodePoint.DIGIT_0 || c === CodePoint.DIGIT_1);
46091
+ this.endToken("Integer", "start", String.fromCodePoint(...out), 2);
46092
+ return this.back("DATA");
46093
+ }
46094
+ FRACTIONAL_RIGHT(cp) {
46095
+ const { minus, absInt } = this.data;
46096
+ const { out, nextCp } = this.parseDigits(cp, isDigit);
46097
+ const absNum = [
46098
+ ...absInt,
46099
+ CodePoint.DOT,
46100
+ ...out
46101
+ ];
46102
+ if (nextCp === CodePoint.LATIN_SMALL_E || nextCp === CodePoint.LATIN_CAPITAL_E) {
46103
+ this.data = {
46104
+ minus,
46105
+ left: absNum
46106
+ };
46107
+ return "EXPONENT_RIGHT";
46108
+ }
46109
+ const value = Number(minus ? String.fromCodePoint(CodePoint.DASH, ...absNum) : String.fromCodePoint(...absNum));
46110
+ this.endToken("Float", "start", value);
46111
+ return this.back("DATA");
46112
+ }
46113
+ EXPONENT_RIGHT(cp) {
46114
+ const { left, minus: leftMinus } = this.data;
46115
+ let minus = false;
46116
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
46117
+ minus = cp === CodePoint.DASH;
46118
+ cp = this.nextCode();
46119
+ }
46120
+ const { out } = this.parseDigits(cp, isDigit);
46121
+ const right = out;
46122
+ if (minus) right.unshift(CodePoint.DASH);
46123
+ const value = Number(leftMinus ? String.fromCodePoint(CodePoint.DASH, ...left, CodePoint.LATIN_SMALL_E, ...right) : String.fromCodePoint(...left, CodePoint.LATIN_SMALL_E, ...right));
46124
+ this.endToken("Float", "start", value);
46125
+ return this.back("DATA");
46126
+ }
46127
+ BOOLEAN(cp) {
46128
+ if (cp === CodePoint.LATIN_SMALL_T) {
46129
+ const startPos = this.codePointIterator.start;
46130
+ if (this.eatCode(CodePoint.LATIN_SMALL_R) && this.eatCode(CodePoint.LATIN_SMALL_U) && this.eatCode(CodePoint.LATIN_SMALL_E)) {
46131
+ this.endToken("Boolean", "end", true);
46132
+ return "DATA";
46133
+ }
46134
+ this.moveAt(startPos);
46135
+ } else if (cp === CodePoint.LATIN_SMALL_F) {
46136
+ const startPos = this.codePointIterator.start;
46137
+ 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)) {
46138
+ this.endToken("Boolean", "end", false);
46139
+ return "DATA";
46140
+ }
46141
+ this.moveAt(startPos);
46142
+ }
46143
+ return this.reportParseError("unexpected-char");
46144
+ }
46145
+ DATE_MONTH(cp) {
46146
+ const start = this.codePointIterator.start;
46147
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46148
+ cp = this.nextCode();
46149
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46150
+ cp = this.nextCode();
46151
+ if (cp !== CodePoint.DASH) return this.reportParseError("unexpected-char");
46152
+ const end = this.codePointIterator.start;
46153
+ const data = this.data;
46154
+ data.month = Number(this.text.slice(start, end));
46155
+ return "DATE_DAY";
46156
+ }
46157
+ DATE_DAY(cp) {
46158
+ const start = this.codePointIterator.start;
46159
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46160
+ cp = this.nextCode();
46161
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46162
+ const end = this.codePointIterator.end;
46163
+ const data = this.data;
46164
+ data.day = Number(this.text.slice(start, end));
46165
+ if (!isValidDate(data.year, data.month, data.day)) return this.reportParseError("invalid-date");
46166
+ cp = this.nextCode();
46167
+ if (cp === CodePoint.LATIN_CAPITAL_T || cp === CodePoint.LATIN_SMALL_T) return "TIME_HOUR";
46168
+ if (cp === CodePoint.SPACE) {
46169
+ const startPos = this.codePointIterator.start;
46170
+ if (isDigit(this.nextCode()) && isDigit(this.nextCode())) {
46171
+ this.moveAt(startPos);
46172
+ return "TIME_HOUR";
46173
+ }
46174
+ this.moveAt(startPos);
46175
+ }
46176
+ const dateValue = getDateFromDateTimeData(data, "");
46177
+ this.endToken("LocalDate", "start", dateValue);
46178
+ return this.back("DATA");
46179
+ }
46180
+ TIME_HOUR(cp) {
46181
+ const start = this.codePointIterator.start;
46182
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46183
+ cp = this.nextCode();
46184
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46185
+ cp = this.nextCode();
46186
+ if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
46187
+ const end = this.codePointIterator.start;
46188
+ const data = this.data;
46189
+ data.hour = Number(this.text.slice(start, end));
46190
+ return "TIME_MINUTE";
46191
+ }
46192
+ TIME_MINUTE(cp) {
46193
+ const start = this.codePointIterator.start;
46194
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46195
+ cp = this.nextCode();
46196
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46197
+ const end = this.codePointIterator.end;
46198
+ const data = this.data;
46199
+ data.minute = Number(this.text.slice(start, end));
46200
+ cp = this.nextCode();
46201
+ if (cp === CodePoint.COLON) return "TIME_SECOND";
46202
+ if (this.tomlVersion.lt(1, 1)) return this.reportParseError("unexpected-char");
46203
+ if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
46204
+ return this.processTimeEnd(cp, data);
46205
+ }
46206
+ TIME_SECOND(cp) {
46207
+ const start = this.codePointIterator.start;
46208
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46209
+ cp = this.nextCode();
46210
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46211
+ const end = this.codePointIterator.end;
46212
+ const data = this.data;
46213
+ data.second = Number(this.text.slice(start, end));
46214
+ if (!isValidTime(data.hour, data.minute, data.second)) return this.reportParseError("invalid-time");
46215
+ cp = this.nextCode();
46216
+ if (cp === CodePoint.DOT) return "TIME_SEC_FRAC";
46217
+ return this.processTimeEnd(cp, data);
46218
+ }
46219
+ TIME_SEC_FRAC(cp) {
46220
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46221
+ const start = this.codePointIterator.start;
46222
+ while (isDigit(cp)) cp = this.nextCode();
46223
+ const end = this.codePointIterator.start;
46224
+ const data = this.data;
46225
+ data.frac = this.text.slice(start, end);
46226
+ return this.processTimeEnd(cp, data);
46227
+ }
46228
+ processTimeEnd(cp, data) {
46229
+ if (data.hasDate) {
46230
+ if (cp === CodePoint.DASH || cp === CodePoint.PLUS_SIGN) {
46231
+ data.offsetSign = cp;
46232
+ return "TIME_OFFSET";
46233
+ }
46234
+ if (cp === CodePoint.LATIN_CAPITAL_Z || cp === CodePoint.LATIN_SMALL_Z) {
46235
+ const dateValue$2 = getDateFromDateTimeData(data, "Z");
46236
+ this.endToken("OffsetDateTime", "end", dateValue$2);
46237
+ return "DATA";
46238
+ }
46239
+ const dateValue$1 = getDateFromDateTimeData(data, "");
46240
+ this.endToken("LocalDateTime", "start", dateValue$1);
46241
+ return this.back("DATA");
46242
+ }
46243
+ const dateValue = getDateFromDateTimeData(data, "");
46244
+ this.endToken("LocalTime", "start", dateValue);
46245
+ return this.back("DATA");
46246
+ }
46247
+ TIME_OFFSET(cp) {
46248
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46249
+ const hourStart = this.codePointIterator.start;
46250
+ cp = this.nextCode();
46251
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46252
+ cp = this.nextCode();
46253
+ if (cp !== CodePoint.COLON) return this.reportParseError("unexpected-char");
46254
+ const hourEnd = this.codePointIterator.start;
46255
+ cp = this.nextCode();
46256
+ const minuteStart = this.codePointIterator.start;
46257
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46258
+ cp = this.nextCode();
46259
+ if (!isDigit(cp)) return this.reportParseError("unexpected-char");
46260
+ const minuteEnd = this.codePointIterator.end;
46261
+ const hour = Number(this.text.slice(hourStart, hourEnd));
46262
+ const minute = Number(this.text.slice(minuteStart, minuteEnd));
46263
+ if (!isValidTime(hour, minute, 0)) return this.reportParseError("invalid-time");
46264
+ const data = this.data;
46265
+ const dateValue = getDateFromDateTimeData(data, `${String.fromCodePoint(data.offsetSign)}${padStart(hour, 2)}:${padStart(minute, 2)}`);
46266
+ this.endToken("OffsetDateTime", "end", dateValue);
46267
+ return "DATA";
46268
+ }
46269
+ parseDigits(cp, checkDigit) {
46270
+ if (cp === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46271
+ if (!checkDigit(cp)) return this.reportParseError("unexpected-char");
46272
+ const out = [];
46273
+ let before = CodePoint.NULL;
46274
+ let hasUnderscore = false;
46275
+ while (checkDigit(cp) || cp === CodePoint.UNDERSCORE) {
46276
+ if (cp === CodePoint.UNDERSCORE) {
46277
+ hasUnderscore = true;
46278
+ if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46279
+ } else out.push(cp);
46280
+ before = cp;
46281
+ cp = this.nextCode();
46282
+ }
46283
+ if (before === CodePoint.UNDERSCORE) return this.reportParseError("invalid-underscore");
46284
+ return {
46285
+ out,
46286
+ nextCp: cp,
46287
+ hasUnderscore
46288
+ };
46289
+ }
46290
+ parseUnicode(count) {
46291
+ const startLoc = this.codePointIterator.start;
46292
+ const start = this.codePointIterator.end;
46293
+ let charCount = 0;
46294
+ let cp;
46295
+ while ((cp = this.nextCode()) !== CodePoint.EOF) {
46296
+ if (!isHexDig(cp)) {
46297
+ this.moveAt(startLoc);
46298
+ return this.reportParseError("invalid-char-in-escape-sequence");
46299
+ }
46300
+ charCount++;
46301
+ if (charCount >= count) break;
46302
+ }
46303
+ const end = this.codePointIterator.end;
46304
+ const code = this.text.slice(start, end);
46305
+ const codePoint = parseInt(code, 16);
46306
+ if (!isUnicodeScalarValue(codePoint)) return this.reportParseError("invalid-code-point", { cp: code });
46307
+ return codePoint;
46308
+ }
46309
+ reportParseErrorControlChar() {
46310
+ return this.reportParseError("invalid-control-character");
46311
+ }
46312
+ };
46313
+ function isUnquotedKeyChar(cp, tomlVersion) {
46314
+ if (isLetter2(cp) || isDigit(cp) || cp === CodePoint.UNDERSCORE || cp === CodePoint.DASH) return true;
46315
+ if (tomlVersion.lt(1, 1)) return false;
46316
+ return false;
45102
46317
  }
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));
46318
+ function isControlOtherThanTab(cp) {
46319
+ return isControl(cp) && cp !== CodePoint.TABULATION || cp === CodePoint.DELETE;
45107
46320
  }
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));
46321
+ function isNonEOL(cp) {
46322
+ return cp === CodePoint.TABULATION || CodePoint.SPACE <= cp && cp <= CodePoint.TILDE || isNonAscii(cp);
46323
+ }
46324
+ function isNonAscii(cp) {
46325
+ return CodePoint.PAD <= cp && cp <= CodePoint.CP_D7FF || CodePoint.CP_E000 <= cp && cp <= CodePoint.CP_10FFFF;
46326
+ }
46327
+ function isValidDate(y, m, d) {
46328
+ 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));
46329
+ return false;
46330
+ }
46331
+ function isValidTime(h, m, s) {
46332
+ if (h >= 24 || h < 0 || m > 59 || m < 0 || s > 60 || s < 0) return false;
46333
+ return true;
46334
+ }
46335
+ function getDateFromDateTimeData(data, timeZone) {
46336
+ const year = padStart(data.year, 4);
46337
+ const month = data.month ? padStart(data.month, 2) : "01";
46338
+ const day = data.day ? padStart(data.day, 2) : "01";
46339
+ const hour = padStart(data.hour, 2);
46340
+ const minute = padStart(data.minute, 2);
46341
+ const second = padStart(data.second, 2);
46342
+ const textDate = `${year}-${month}-${day}`;
46343
+ const frac = data.frac ? `.${data.frac}` : "";
46344
+ const dateValue = /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:${second}${frac}${timeZone}`);
46345
+ if (!isNaN(dateValue.getTime()) || data.second !== 60) return dateValue;
46346
+ return /* @__PURE__ */ new Date(`${textDate}T${hour}:${minute}:59${frac}${timeZone}`);
46347
+ }
46348
+ function padStart(num, maxLength) {
46349
+ return String(num).padStart(maxLength, "0");
46350
+ }
46351
+ var VALUE_KIND_VALUE = Symbol("VALUE_KIND_VALUE");
46352
+ var VALUE_KIND_INTERMEDIATE = Symbol("VALUE_KIND_INTERMEDIATE");
46353
+ var KeysResolver = class {
46354
+ constructor(ctx) {
46355
+ this.rootKeys = /* @__PURE__ */ new Map();
46356
+ this.tables = [];
46357
+ this.ctx = ctx;
46358
+ }
46359
+ applyResolveKeyForTable(node3) {
46360
+ let keys = this.rootKeys;
46361
+ const peekKeyIndex = node3.key.keys.length - 1;
46362
+ for (let index = 0; index < peekKeyIndex; index++) {
46363
+ const keyNode = node3.key.keys[index];
46364
+ const keyName = toKeyName(keyNode);
46365
+ node3.resolvedKey.push(keyName);
46366
+ let keyStore = keys.get(keyName);
46367
+ if (!keyStore) {
46368
+ keyStore = {
46369
+ node: keyNode,
46370
+ keys: /* @__PURE__ */ new Map()
46371
+ };
46372
+ keys.set(keyName, keyStore);
46373
+ } else if (keyStore.table === "array") {
46374
+ const peekIndex = keyStore.peekIndex;
46375
+ node3.resolvedKey.push(peekIndex);
46376
+ keyStore = keyStore.keys.get(peekIndex);
46377
+ }
46378
+ keys = keyStore.keys;
46379
+ }
46380
+ const lastKeyNode = node3.key.keys[peekKeyIndex];
46381
+ const lastKeyName = toKeyName(lastKeyNode);
46382
+ node3.resolvedKey.push(lastKeyName);
46383
+ const lastKeyStore = keys.get(lastKeyName);
46384
+ if (!lastKeyStore) if (node3.kind === "array") {
46385
+ node3.resolvedKey.push(0);
46386
+ const newKeyStore = {
46387
+ node: lastKeyNode,
46388
+ keys: /* @__PURE__ */ new Map()
46389
+ };
46390
+ keys.set(lastKeyName, {
46391
+ table: node3.kind,
46392
+ node: lastKeyNode,
46393
+ keys: /* @__PURE__ */ new Map([[0, newKeyStore]]),
46394
+ peekIndex: 0
46395
+ });
46396
+ this.tables.push({
46397
+ node: node3,
46398
+ keys: newKeyStore.keys
46399
+ });
46400
+ } else {
46401
+ const newKeyStore = {
46402
+ table: node3.kind,
46403
+ node: lastKeyNode,
46404
+ keys: /* @__PURE__ */ new Map()
46405
+ };
46406
+ keys.set(lastKeyName, newKeyStore);
46407
+ this.tables.push({
46408
+ node: node3,
46409
+ keys: newKeyStore.keys
46410
+ });
46411
+ }
46412
+ else if (!lastKeyStore.table) if (node3.kind === "array") this.ctx.reportParseError("dupe-keys", lastKeyNode);
46413
+ else {
46414
+ const transformKey = {
46415
+ table: node3.kind,
46416
+ node: lastKeyNode,
46417
+ keys: lastKeyStore.keys
46418
+ };
46419
+ keys.set(lastKeyName, transformKey);
46420
+ this.tables.push({
46421
+ node: node3,
46422
+ keys: transformKey.keys
46423
+ });
46424
+ }
46425
+ else if (lastKeyStore.table === "array") if (node3.kind === "array") {
46426
+ const newKeyStore = {
46427
+ node: lastKeyNode,
46428
+ keys: /* @__PURE__ */ new Map()
46429
+ };
46430
+ const newIndex = lastKeyStore.peekIndex + 1;
46431
+ node3.resolvedKey.push(newIndex);
46432
+ lastKeyStore.keys.set(newIndex, newKeyStore);
46433
+ lastKeyStore.peekIndex = newIndex;
46434
+ this.tables.push({
46435
+ node: node3,
46436
+ keys: newKeyStore.keys
46437
+ });
46438
+ } else this.ctx.reportParseError("dupe-keys", lastKeyNode);
46439
+ else this.ctx.reportParseError("dupe-keys", lastKeyNode);
46440
+ }
46441
+ verifyDuplicateKeys(node3) {
46442
+ for (const body of node3.body) if (body.type === "TOMLKeyValue") verifyDuplicateKeysForKeyValue(this.ctx, this.rootKeys, body);
46443
+ for (const { node: tableNode, keys } of this.tables) for (const body of tableNode.body) verifyDuplicateKeysForKeyValue(this.ctx, keys, body);
46444
+ }
46445
+ };
46446
+ function verifyDuplicateKeysForKeyValue(ctx, defineKeys, node3) {
46447
+ let keys = defineKeys;
46448
+ const lastKey = last(node3.key.keys);
46449
+ for (const keyNode of node3.key.keys) {
46450
+ const key = toKeyName(keyNode);
46451
+ let defineKey = keys.get(key);
46452
+ if (defineKey) {
46453
+ if (defineKey.value === VALUE_KIND_VALUE) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46454
+ else if (lastKey === keyNode) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46455
+ else if (defineKey.table) ctx.reportParseError("dupe-keys", getAfterNode(keyNode, defineKey.node));
46456
+ defineKey.value = VALUE_KIND_INTERMEDIATE;
46457
+ } else {
46458
+ if (lastKey === keyNode) defineKey = {
46459
+ value: VALUE_KIND_VALUE,
46460
+ node: keyNode,
46461
+ keys: /* @__PURE__ */ new Map()
46462
+ };
46463
+ else defineKey = {
46464
+ value: VALUE_KIND_INTERMEDIATE,
46465
+ node: keyNode,
46466
+ keys: /* @__PURE__ */ new Map()
46467
+ };
46468
+ keys.set(key, defineKey);
46469
+ }
46470
+ keys = defineKey.keys;
45113
46471
  }
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);
46472
+ if (node3.value.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, keys, node3.value);
46473
+ else if (node3.value.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, keys, node3.value);
45117
46474
  }
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));
46475
+ function verifyDuplicateKeysForInlineTable(ctx, defineKeys, node3) {
46476
+ for (const body of node3.body) verifyDuplicateKeysForKeyValue(ctx, defineKeys, body);
46477
+ }
46478
+ function verifyDuplicateKeysForArray(ctx, defineKeys, node3) {
46479
+ const keys = defineKeys;
46480
+ for (let index = 0; index < node3.elements.length; index++) {
46481
+ const element = node3.elements[index];
46482
+ let defineKey = keys.get(index);
46483
+ if (defineKey) ctx.reportParseError("dupe-keys", getAfterNode(element, defineKey.node));
46484
+ else {
46485
+ defineKey = {
46486
+ value: VALUE_KIND_VALUE,
46487
+ node: element,
46488
+ keys: /* @__PURE__ */ new Map()
46489
+ };
46490
+ defineKeys.set(index, defineKey);
46491
+ if (element.type === "TOMLInlineTable") verifyDuplicateKeysForInlineTable(ctx, defineKey.keys, element);
46492
+ else if (element.type === "TOMLArray") verifyDuplicateKeysForArray(ctx, defineKey.keys, element);
46493
+ }
46494
+ }
46495
+ }
46496
+ function getAfterNode(a, b) {
46497
+ return a.range[0] <= b.range[0] ? b : a;
46498
+ }
46499
+ var Context = class {
46500
+ constructor(data) {
46501
+ this.tokens = [];
46502
+ this.comments = [];
46503
+ this.back = null;
46504
+ this.stateStack = [];
46505
+ this.needNewLine = false;
46506
+ this.needSameLine = false;
46507
+ this.currToken = null;
46508
+ this.prevToken = null;
46509
+ this.valueContainerStack = [];
46510
+ this.tokenizer = new Tokenizer(data.text, data.parserOptions);
46511
+ this.topLevelTable = data.topLevelTable;
46512
+ this.table = data.topLevelTable;
46513
+ this.keysResolver = new KeysResolver(this);
46514
+ }
46515
+ /**
46516
+ * Get the next token.
46517
+ */
46518
+ nextToken(option) {
46519
+ this.prevToken = this.currToken;
46520
+ if (this.back) {
46521
+ this.currToken = this.back;
46522
+ this.back = null;
46523
+ } else this.currToken = this._nextTokenFromTokenizer(option);
46524
+ if ((this.needNewLine || this.needSameLine || option?.needSameLine) && this.prevToken && this.currToken) if (this.prevToken.loc.end.line === this.currToken.loc.start.line) {
46525
+ if (this.needNewLine) return this.reportParseError("missing-newline", this.currToken);
46526
+ } else {
46527
+ const needSameLine = this.needSameLine || option?.needSameLine;
46528
+ if (needSameLine) return this.reportParseError(needSameLine, this.currToken);
45123
46529
  }
46530
+ this.needNewLine = false;
46531
+ this.needSameLine = false;
46532
+ return this.currToken;
45124
46533
  }
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));
46534
+ _nextTokenFromTokenizer(option) {
46535
+ const valuesEnabled = this.tokenizer.valuesEnabled;
46536
+ if (option?.valuesEnabled) this.tokenizer.valuesEnabled = option.valuesEnabled;
46537
+ let token = this.tokenizer.nextToken();
46538
+ while (token && token.type === "Block") {
46539
+ this.comments.push(token);
46540
+ token = this.tokenizer.nextToken();
46541
+ }
46542
+ if (token) this.tokens.push(token);
46543
+ this.tokenizer.valuesEnabled = valuesEnabled;
46544
+ return token;
45129
46545
  }
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));
46546
+ backToken() {
46547
+ if (this.back) throw new Error("Illegal state");
46548
+ this.back = this.currToken;
46549
+ this.currToken = this.prevToken;
45136
46550
  }
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));
46551
+ addValueContainer(valueContainer) {
46552
+ this.valueContainerStack.push(valueContainer);
46553
+ this.tokenizer.valuesEnabled = true;
46554
+ }
46555
+ consumeValueContainer() {
46556
+ const valueContainer = this.valueContainerStack.pop();
46557
+ this.tokenizer.valuesEnabled = this.valueContainerStack.length > 0;
46558
+ return valueContainer;
46559
+ }
46560
+ applyResolveKeyForTable(node3) {
46561
+ this.keysResolver.applyResolveKeyForTable(node3);
46562
+ }
46563
+ verifyDuplicateKeys() {
46564
+ this.keysResolver.verifyDuplicateKeys(this.topLevelTable);
46565
+ }
46566
+ /**
46567
+ * Report an invalid token error.
46568
+ */
46569
+ reportParseError(code, token) {
46570
+ let offset, line, column;
46571
+ if (token) {
46572
+ offset = token.range[0];
46573
+ line = token.loc.start.line;
46574
+ column = token.loc.start.column;
46575
+ } else {
46576
+ offset = this.tokenizer.start;
46577
+ const startPos = this.tokenizer.getLocFromIndex(offset);
46578
+ line = startPos.line;
46579
+ column = startPos.column;
45148
46580
  }
45149
- dataDir(join6(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
46581
+ throw new ParseError(code, offset, line, column);
45150
46582
  }
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 {
46583
+ };
46584
+ var STATE_FOR_ERROR = { VALUE: "missing-value" };
46585
+ var STRING_VALUE_STYLE_MAP = {
46586
+ BasicString: "basic",
46587
+ MultiLineBasicString: "basic",
46588
+ LiteralString: "literal",
46589
+ MultiLineLiteralString: "literal"
46590
+ };
46591
+ var STRING_KEY_STYLE_MAP = {
46592
+ BasicString: "basic",
46593
+ LiteralString: "literal"
46594
+ };
46595
+ var DATETIME_VALUE_KIND_MAP = {
46596
+ OffsetDateTime: "offset-date-time",
46597
+ LocalDateTime: "local-date-time",
46598
+ LocalDate: "local-date",
46599
+ LocalTime: "local-time"
46600
+ };
46601
+ var TOMLParser = class {
46602
+ /**
46603
+ * Initialize this parser.
46604
+ */
46605
+ constructor(text, parserOptions) {
46606
+ this.text = text;
46607
+ this.parserOptions = parserOptions || {};
46608
+ this.tomlVersion = getTOMLVer(this.parserOptions.tomlVersion);
46609
+ }
46610
+ /**
46611
+ * Parse TOML
46612
+ */
46613
+ parse() {
46614
+ const ast = {
46615
+ type: "Program",
46616
+ body: [],
46617
+ sourceType: "module",
46618
+ tokens: [],
46619
+ comments: [],
46620
+ parent: null,
46621
+ range: [0, 0],
46622
+ loc: {
46623
+ start: {
46624
+ line: 1,
46625
+ column: 0
46626
+ },
46627
+ end: {
46628
+ line: 1,
46629
+ column: 0
46630
+ }
46631
+ }
46632
+ };
46633
+ const node3 = {
46634
+ type: "TOMLTopLevelTable",
46635
+ body: [],
46636
+ parent: ast,
46637
+ range: cloneRange(ast.range),
46638
+ loc: cloneLoc(ast.loc)
46639
+ };
46640
+ ast.body = [node3];
46641
+ const ctx = new Context({
46642
+ text: this.text,
46643
+ parserOptions: this.parserOptions,
46644
+ topLevelTable: node3
46645
+ });
46646
+ let token = ctx.nextToken();
46647
+ if (token) {
46648
+ node3.range[0] = token.range[0];
46649
+ node3.loc.start = clonePos(token.loc.start);
46650
+ while (token) {
46651
+ const state$1 = ctx.stateStack.pop() || "TABLE";
46652
+ ctx.stateStack.push(...this[state$1](token, ctx));
46653
+ token = ctx.nextToken();
46654
+ }
46655
+ const state = ctx.stateStack.pop() || "TABLE";
46656
+ if (state in STATE_FOR_ERROR) return ctx.reportParseError(STATE_FOR_ERROR[state], null);
46657
+ if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
46658
+ applyEndLoc(node3, last(node3.body));
46659
+ }
46660
+ ctx.verifyDuplicateKeys();
46661
+ ast.tokens = ctx.tokens;
46662
+ ast.comments = ctx.comments;
46663
+ const endOffset = ctx.tokenizer.end;
46664
+ const endPos = ctx.tokenizer.getLocFromIndex(endOffset);
46665
+ ast.range[1] = endOffset;
46666
+ ast.loc.end = {
46667
+ line: endPos.line,
46668
+ column: endPos.column
46669
+ };
46670
+ return ast;
46671
+ }
46672
+ TABLE(token, ctx) {
46673
+ if (isBare(token) || isString(token)) return this.processKeyValue(token, ctx.table, ctx);
46674
+ if (isLeftBracket(token)) return this.processTable(token, ctx.topLevelTable, ctx);
46675
+ return ctx.reportParseError("unexpected-token", token);
46676
+ }
46677
+ VALUE(token, ctx) {
46678
+ if (isString(token) || isMultiLineString(token)) return this.processStringValue(token, ctx);
46679
+ if (isNumber(token)) return this.processNumberValue(token, ctx);
46680
+ if (isBoolean(token)) return this.processBooleanValue(token, ctx);
46681
+ if (isDateTime(token)) return this.processDateTimeValue(token, ctx);
46682
+ if (isLeftBracket(token)) return this.processArray(token, ctx);
46683
+ if (isLeftBrace(token)) return this.processInlineTable(token, ctx);
46684
+ return ctx.reportParseError("unexpected-token", token);
46685
+ }
46686
+ processTable(token, topLevelTableNode, ctx) {
46687
+ const tableNode = {
46688
+ type: "TOMLTable",
46689
+ kind: "standard",
46690
+ key: null,
46691
+ resolvedKey: [],
46692
+ body: [],
46693
+ parent: topLevelTableNode,
46694
+ range: cloneRange(token.range),
46695
+ loc: cloneLoc(token.loc)
46696
+ };
46697
+ if (ctx.table.type === "TOMLTable") applyEndLoc(ctx.table, last(ctx.table.body));
46698
+ topLevelTableNode.body.push(tableNode);
46699
+ ctx.table = tableNode;
46700
+ let targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46701
+ if (isLeftBracket(targetToken)) {
46702
+ if (token.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
46703
+ tableNode.kind = "array";
46704
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46705
+ }
46706
+ if (isRightBracket(targetToken)) return ctx.reportParseError("missing-key", targetToken);
46707
+ if (!targetToken) return ctx.reportParseError("unterminated-table-key", null);
46708
+ targetToken = this.processKeyNode(targetToken, tableNode, ctx).nextToken;
46709
+ if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
46710
+ if (tableNode.kind === "array") {
46711
+ const rightBracket = targetToken;
46712
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46713
+ if (!isRightBracket(targetToken)) return ctx.reportParseError("unterminated-table-key", targetToken);
46714
+ if (rightBracket.range[1] < targetToken.range[0]) return ctx.reportParseError("invalid-space", targetToken);
46715
+ }
46716
+ applyEndLoc(tableNode, targetToken);
46717
+ ctx.applyResolveKeyForTable(tableNode);
46718
+ ctx.needNewLine = true;
45157
46719
  return [];
45158
46720
  }
46721
+ processKeyValue(token, tableNode, ctx) {
46722
+ const keyValueNode = {
46723
+ type: "TOMLKeyValue",
46724
+ key: null,
46725
+ value: null,
46726
+ parent: tableNode,
46727
+ range: cloneRange(token.range),
46728
+ loc: cloneLoc(token.loc)
46729
+ };
46730
+ tableNode.body.push(keyValueNode);
46731
+ const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
46732
+ if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
46733
+ ctx.addValueContainer({
46734
+ parent: keyValueNode,
46735
+ set: (valNode) => {
46736
+ keyValueNode.value = valNode;
46737
+ applyEndLoc(keyValueNode, valNode);
46738
+ ctx.needNewLine = true;
46739
+ return [];
46740
+ }
46741
+ });
46742
+ ctx.needSameLine = "invalid-key-value-newline";
46743
+ return ["VALUE"];
46744
+ }
46745
+ processKeyNode(token, parent, ctx) {
46746
+ if (isDot(token)) ctx.reportParseError("invalid-leading-dot-in-key", token);
46747
+ const keyNode = {
46748
+ type: "TOMLKey",
46749
+ keys: [],
46750
+ parent,
46751
+ range: cloneRange(token.range),
46752
+ loc: cloneLoc(token.loc)
46753
+ };
46754
+ parent.key = keyNode;
46755
+ let targetToken = token;
46756
+ let dotToken = null;
46757
+ do {
46758
+ if (isBare(targetToken)) this.processBareKey(targetToken, keyNode);
46759
+ else if (isString(targetToken)) this.processStringKey(targetToken, keyNode);
46760
+ else break;
46761
+ dotToken = null;
46762
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46763
+ if (!isDot(targetToken)) break;
46764
+ dotToken = targetToken;
46765
+ targetToken = ctx.nextToken({ needSameLine: "invalid-key-value-newline" });
46766
+ } while (targetToken);
46767
+ if (dotToken) ctx.reportParseError(isDot(targetToken) ? "invalid-consecutive-dots-in-key" : "invalid-trailing-dot-in-key", dotToken);
46768
+ applyEndLoc(keyNode, last(keyNode.keys));
46769
+ return {
46770
+ keyNode,
46771
+ nextToken: targetToken
46772
+ };
46773
+ }
46774
+ processBareKey(token, keyNode) {
46775
+ const node3 = {
46776
+ type: "TOMLBare",
46777
+ name: token.value,
46778
+ parent: keyNode,
46779
+ range: cloneRange(token.range),
46780
+ loc: cloneLoc(token.loc)
46781
+ };
46782
+ keyNode.keys.push(node3);
46783
+ }
46784
+ processStringKey(token, keyNode) {
46785
+ const node3 = {
46786
+ type: "TOMLQuoted",
46787
+ kind: "string",
46788
+ value: token.string,
46789
+ style: STRING_KEY_STYLE_MAP[token.type],
46790
+ multiline: false,
46791
+ parent: keyNode,
46792
+ range: cloneRange(token.range),
46793
+ loc: cloneLoc(token.loc)
46794
+ };
46795
+ keyNode.keys.push(node3);
46796
+ }
46797
+ processStringValue(token, ctx) {
46798
+ const valueContainer = ctx.consumeValueContainer();
46799
+ const node3 = {
46800
+ type: "TOMLValue",
46801
+ kind: "string",
46802
+ value: token.string,
46803
+ style: STRING_VALUE_STYLE_MAP[token.type],
46804
+ multiline: isMultiLineString(token),
46805
+ parent: valueContainer.parent,
46806
+ range: cloneRange(token.range),
46807
+ loc: cloneLoc(token.loc)
46808
+ };
46809
+ return valueContainer.set(node3);
46810
+ }
46811
+ processNumberValue(token, ctx) {
46812
+ const valueContainer = ctx.consumeValueContainer();
46813
+ const text = this.text;
46814
+ const [startRange, endRange] = token.range;
46815
+ let numberString = null;
46816
+ const getNumberText = () => {
46817
+ return numberString ?? (numberString = text.slice(startRange, endRange).replace(/_/g, ""));
46818
+ };
46819
+ let node3;
46820
+ if (token.type === "Integer") node3 = {
46821
+ type: "TOMLValue",
46822
+ kind: "integer",
46823
+ value: token.number,
46824
+ bigint: token.bigint,
46825
+ get number() {
46826
+ return getNumberText();
46827
+ },
46828
+ parent: valueContainer.parent,
46829
+ range: cloneRange(token.range),
46830
+ loc: cloneLoc(token.loc)
46831
+ };
46832
+ else node3 = {
46833
+ type: "TOMLValue",
46834
+ kind: "float",
46835
+ value: token.number,
46836
+ get number() {
46837
+ return getNumberText();
46838
+ },
46839
+ parent: valueContainer.parent,
46840
+ range: cloneRange(token.range),
46841
+ loc: cloneLoc(token.loc)
46842
+ };
46843
+ return valueContainer.set(node3);
46844
+ }
46845
+ processBooleanValue(token, ctx) {
46846
+ const valueContainer = ctx.consumeValueContainer();
46847
+ const node3 = {
46848
+ type: "TOMLValue",
46849
+ kind: "boolean",
46850
+ value: token.boolean,
46851
+ parent: valueContainer.parent,
46852
+ range: cloneRange(token.range),
46853
+ loc: cloneLoc(token.loc)
46854
+ };
46855
+ return valueContainer.set(node3);
46856
+ }
46857
+ processDateTimeValue(token, ctx) {
46858
+ const valueContainer = ctx.consumeValueContainer();
46859
+ const node3 = {
46860
+ type: "TOMLValue",
46861
+ kind: DATETIME_VALUE_KIND_MAP[token.type],
46862
+ value: token.date,
46863
+ datetime: token.value,
46864
+ parent: valueContainer.parent,
46865
+ range: cloneRange(token.range),
46866
+ loc: cloneLoc(token.loc)
46867
+ };
46868
+ return valueContainer.set(node3);
46869
+ }
46870
+ processArray(token, ctx) {
46871
+ const valueContainer = ctx.consumeValueContainer();
46872
+ const node3 = {
46873
+ type: "TOMLArray",
46874
+ elements: [],
46875
+ parent: valueContainer.parent,
46876
+ range: cloneRange(token.range),
46877
+ loc: cloneLoc(token.loc)
46878
+ };
46879
+ const nextToken = ctx.nextToken({ valuesEnabled: true });
46880
+ if (isRightBracket(nextToken)) {
46881
+ applyEndLoc(node3, nextToken);
46882
+ return valueContainer.set(node3);
46883
+ }
46884
+ ctx.backToken();
46885
+ return this.processArrayValue(node3, valueContainer, ctx);
46886
+ }
46887
+ processArrayValue(node3, valueContainer, ctx) {
46888
+ ctx.addValueContainer({
46889
+ parent: node3,
46890
+ set: (valNode) => {
46891
+ node3.elements.push(valNode);
46892
+ let nextToken = ctx.nextToken({ valuesEnabled: true });
46893
+ const hasComma = isComma(nextToken);
46894
+ if (hasComma) nextToken = ctx.nextToken({ valuesEnabled: true });
46895
+ if (isRightBracket(nextToken)) {
46896
+ applyEndLoc(node3, nextToken);
46897
+ return valueContainer.set(node3);
46898
+ }
46899
+ if (hasComma) {
46900
+ ctx.backToken();
46901
+ return this.processArrayValue(node3, valueContainer, ctx);
46902
+ }
46903
+ return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-array", nextToken);
46904
+ }
46905
+ });
46906
+ return ["VALUE"];
46907
+ }
46908
+ processInlineTable(token, ctx) {
46909
+ const valueContainer = ctx.consumeValueContainer();
46910
+ const node3 = {
46911
+ type: "TOMLInlineTable",
46912
+ body: [],
46913
+ parent: valueContainer.parent,
46914
+ range: cloneRange(token.range),
46915
+ loc: cloneLoc(token.loc)
46916
+ };
46917
+ const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
46918
+ const nextToken = ctx.nextToken({ needSameLine });
46919
+ if (nextToken) {
46920
+ if (isBare(nextToken) || isString(nextToken)) return this.processInlineTableKeyValue(nextToken, node3, valueContainer, ctx);
46921
+ if (isRightBrace(nextToken)) {
46922
+ applyEndLoc(node3, nextToken);
46923
+ return valueContainer.set(node3);
46924
+ }
46925
+ }
46926
+ return ctx.reportParseError("unexpected-token", nextToken);
46927
+ }
46928
+ processInlineTableKeyValue(token, inlineTableNode, valueContainer, ctx) {
46929
+ const keyValueNode = {
46930
+ type: "TOMLKeyValue",
46931
+ key: null,
46932
+ value: null,
46933
+ parent: inlineTableNode,
46934
+ range: cloneRange(token.range),
46935
+ loc: cloneLoc(token.loc)
46936
+ };
46937
+ inlineTableNode.body.push(keyValueNode);
46938
+ const { nextToken: targetToken } = this.processKeyNode(token, keyValueNode, ctx);
46939
+ if (!isEq(targetToken)) return ctx.reportParseError("missing-equals-sign", targetToken);
46940
+ const needSameLine = this.tomlVersion.gte(1, 1) ? void 0 : "invalid-inline-table-newline";
46941
+ ctx.addValueContainer({
46942
+ parent: keyValueNode,
46943
+ set: (valNode) => {
46944
+ keyValueNode.value = valNode;
46945
+ applyEndLoc(keyValueNode, valNode);
46946
+ let nextToken = ctx.nextToken({ needSameLine });
46947
+ if (isComma(nextToken)) {
46948
+ nextToken = ctx.nextToken({ needSameLine });
46949
+ if (nextToken && (isBare(nextToken) || isString(nextToken))) return this.processInlineTableKeyValue(nextToken, inlineTableNode, valueContainer, ctx);
46950
+ if (isRightBrace(nextToken)) {
46951
+ if (this.tomlVersion.lt(1, 1)) return ctx.reportParseError("invalid-trailing-comma-in-inline-table", nextToken);
46952
+ } else return ctx.reportParseError(nextToken ? "unexpected-token" : "unterminated-inline-table", nextToken);
46953
+ }
46954
+ if (isRightBrace(nextToken)) {
46955
+ applyEndLoc(inlineTableNode, nextToken);
46956
+ return valueContainer.set(inlineTableNode);
46957
+ }
46958
+ return ctx.reportParseError(nextToken ? "missing-comma" : "unterminated-inline-table", nextToken);
46959
+ }
46960
+ });
46961
+ ctx.needSameLine = "invalid-key-value-newline";
46962
+ return ["VALUE"];
46963
+ }
46964
+ };
46965
+ function isDot(token) {
46966
+ return isPunctuator(token) && token.value === ".";
45159
46967
  }
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;
46968
+ function isEq(token) {
46969
+ return isPunctuator(token) && token.value === "=";
46970
+ }
46971
+ function isLeftBracket(token) {
46972
+ return isPunctuator(token) && token.value === "[";
46973
+ }
46974
+ function isRightBracket(token) {
46975
+ return isPunctuator(token) && token.value === "]";
46976
+ }
46977
+ function isLeftBrace(token) {
46978
+ return isPunctuator(token) && token.value === "{";
46979
+ }
46980
+ function isRightBrace(token) {
46981
+ return isPunctuator(token) && token.value === "}";
46982
+ }
46983
+ function isComma(token) {
46984
+ return isPunctuator(token) && token.value === ",";
46985
+ }
46986
+ function isPunctuator(token) {
46987
+ return Boolean(token && token.type === "Punctuator");
46988
+ }
46989
+ function isBare(token) {
46990
+ return token.type === "Bare";
46991
+ }
46992
+ function isString(token) {
46993
+ return token.type === "BasicString" || token.type === "LiteralString";
46994
+ }
46995
+ function isMultiLineString(token) {
46996
+ return token.type === "MultiLineBasicString" || token.type === "MultiLineLiteralString";
46997
+ }
46998
+ function isNumber(token) {
46999
+ return token.type === "Integer" || token.type === "Float";
47000
+ }
47001
+ function isBoolean(token) {
47002
+ return token.type === "Boolean";
47003
+ }
47004
+ function isDateTime(token) {
47005
+ return token.type === "OffsetDateTime" || token.type === "LocalDateTime" || token.type === "LocalDate" || token.type === "LocalTime";
47006
+ }
47007
+ function applyEndLoc(node3, child) {
47008
+ if (child) {
47009
+ node3.range[1] = child.range[1];
47010
+ node3.loc.end = clonePos(child.loc.end);
47011
+ }
47012
+ }
47013
+ function cloneRange(range) {
47014
+ return [range[0], range[1]];
47015
+ }
47016
+ function cloneLoc(loc) {
47017
+ return {
47018
+ start: clonePos(loc.start),
47019
+ end: clonePos(loc.end)
47020
+ };
47021
+ }
47022
+ function clonePos(pos) {
47023
+ return {
47024
+ line: pos.line,
47025
+ column: pos.column
47026
+ };
47027
+ }
47028
+ var tomlKeys = {
47029
+ Program: ["body"],
47030
+ TOMLTopLevelTable: ["body"],
47031
+ TOMLTable: ["key", "body"],
47032
+ TOMLKeyValue: ["key", "value"],
47033
+ TOMLKey: ["keys"],
47034
+ TOMLArray: ["elements"],
47035
+ TOMLInlineTable: ["body"],
47036
+ TOMLBare: [],
47037
+ TOMLQuoted: [],
47038
+ TOMLValue: []
47039
+ };
47040
+ var KEYS3 = unionWith(tomlKeys);
47041
+ function parseForESLint(code, options) {
47042
+ return {
47043
+ ast: new TOMLParser(code, options).parse(),
47044
+ visitorKeys: KEYS3,
47045
+ services: { isTOML: true }
47046
+ };
47047
+ }
47048
+ var getStaticTOMLValue = generateConvertTOMLValue((node3) => node3.value);
47049
+ function generateConvertTOMLValue(convertValue) {
47050
+ function resolveValue(node3, baseTable) {
47051
+ return resolver[node3.type](node3, baseTable);
47052
+ }
47053
+ const resolver = {
47054
+ Program(node3, baseTable = {}) {
47055
+ return resolveValue(node3.body[0], baseTable);
47056
+ },
47057
+ TOMLTopLevelTable(node3, baseTable = {}) {
47058
+ for (const body of node3.body) resolveValue(body, baseTable);
47059
+ return baseTable;
47060
+ },
47061
+ TOMLKeyValue(node3, baseTable = {}) {
47062
+ const value = resolveValue(node3.value);
47063
+ set2(baseTable, resolveValue(node3.key), value);
47064
+ return baseTable;
47065
+ },
47066
+ TOMLTable(node3, baseTable = {}) {
47067
+ const table = getTable(baseTable, resolveValue(node3.key), node3.kind === "array");
47068
+ for (const body of node3.body) resolveValue(body, table);
47069
+ return baseTable;
47070
+ },
47071
+ TOMLArray(node3) {
47072
+ return node3.elements.map((e) => resolveValue(e));
47073
+ },
47074
+ TOMLInlineTable(node3) {
47075
+ const table = {};
47076
+ for (const body of node3.body) resolveValue(body, table);
47077
+ return table;
47078
+ },
47079
+ TOMLKey(node3) {
47080
+ return node3.keys.map((key) => resolveValue(key));
47081
+ },
47082
+ TOMLBare(node3) {
47083
+ return node3.name;
47084
+ },
47085
+ TOMLQuoted(node3) {
47086
+ return node3.value;
47087
+ },
47088
+ TOMLValue(node3) {
47089
+ return convertValue(node3);
47090
+ }
47091
+ };
47092
+ return (node3) => resolveValue(node3);
47093
+ }
47094
+ function getTable(baseTable, keys, array4) {
47095
+ let target = baseTable;
47096
+ for (let index = 0; index < keys.length - 1; index++) {
47097
+ const key = keys[index];
47098
+ target = getNextTargetFromKey(target, key);
47099
+ }
47100
+ const lastKey = last(keys);
47101
+ const lastTarget = target[lastKey];
47102
+ if (lastTarget == null) {
47103
+ const tableValue$1 = {};
47104
+ target[lastKey] = array4 ? [tableValue$1] : tableValue$1;
47105
+ return tableValue$1;
47106
+ }
47107
+ if (isValue(lastTarget)) {
47108
+ const tableValue$1 = {};
47109
+ target[lastKey] = array4 ? [tableValue$1] : tableValue$1;
47110
+ return tableValue$1;
47111
+ }
47112
+ if (!array4) {
47113
+ if (Array.isArray(lastTarget)) {
47114
+ const tableValue$1 = {};
47115
+ target[lastKey] = tableValue$1;
47116
+ return tableValue$1;
47117
+ }
47118
+ return lastTarget;
47119
+ }
47120
+ if (Array.isArray(lastTarget)) {
47121
+ const tableValue$1 = {};
47122
+ lastTarget.push(tableValue$1);
47123
+ return tableValue$1;
47124
+ }
47125
+ const tableValue = {};
47126
+ target[lastKey] = [tableValue];
47127
+ return tableValue;
47128
+ function getNextTargetFromKey(currTarget, key) {
47129
+ const nextTarget = currTarget[key];
47130
+ if (nextTarget == null) {
47131
+ const val = {};
47132
+ currTarget[key] = val;
47133
+ return val;
45169
47134
  }
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));
47135
+ if (isValue(nextTarget)) {
47136
+ const val = {};
47137
+ currTarget[key] = val;
47138
+ return val;
45173
47139
  }
47140
+ let resultTarget = nextTarget;
47141
+ while (Array.isArray(resultTarget)) {
47142
+ const lastIndex = resultTarget.length - 1;
47143
+ const nextElement = resultTarget[lastIndex];
47144
+ if (isValue(nextElement)) {
47145
+ const val = {};
47146
+ resultTarget[lastIndex] = val;
47147
+ return val;
47148
+ }
47149
+ resultTarget = nextElement;
47150
+ }
47151
+ return resultTarget;
45174
47152
  }
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));
47153
+ }
47154
+ function set2(baseTable, keys, value) {
47155
+ let target = baseTable;
47156
+ for (let index = 0; index < keys.length - 1; index++) {
47157
+ const key = keys[index];
47158
+ const nextTarget = target[key];
47159
+ if (nextTarget == null) {
47160
+ const val = {};
47161
+ target[key] = val;
47162
+ target = val;
47163
+ } else if (isValue(nextTarget) || Array.isArray(nextTarget)) {
47164
+ const val = {};
47165
+ target[key] = val;
47166
+ target = val;
47167
+ } else target = nextTarget;
45179
47168
  }
45180
- dataDir(join6(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47169
+ target[last(keys)] = value;
45181
47170
  }
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);
47171
+ function isValue(value) {
47172
+ return typeof value !== "object" || value instanceof Date;
45190
47173
  }
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
- }
47174
+ function parseTOML(code, options) {
47175
+ return parseForESLint(code, options).ast;
45201
47176
  }
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));
47177
+
47178
+ // src/core/ops/atomic-file.ts
47179
+ import { mkdirSync as mkdirSync4, renameSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
47180
+ import path3 from "node:path";
47181
+ function sleepSync(ms) {
47182
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
47183
+ }
47184
+ function errCode2(e) {
47185
+ return e.code;
47186
+ }
47187
+ function renameWithRetry(from, to, opts = {}) {
47188
+ const rename = opts.rename ?? renameSync;
47189
+ const sleep2 = opts.sleep ?? sleepSync;
47190
+ const win = (opts.platform ?? process.platform) === "win32";
47191
+ for (let attempt = 0; ; attempt += 1) {
47192
+ try {
47193
+ rename(from, to);
47194
+ return;
47195
+ } catch (e) {
47196
+ const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47197
+ if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw e;
47198
+ sleep2(ATOMIC_RENAME_DELAY_MS);
47199
+ }
45208
47200
  }
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));
47201
+ }
47202
+ function unlinkWithRetry(file2, opts = {}) {
47203
+ const unlink = opts.unlink ?? unlinkSync;
47204
+ const sleep2 = opts.sleep ?? sleepSync;
47205
+ const win = (opts.platform ?? process.platform) === "win32";
47206
+ for (let attempt = 0; ; attempt += 1) {
47207
+ try {
47208
+ unlink(file2);
47209
+ return;
47210
+ } catch (e) {
47211
+ if (errCode2(e) === "ENOENT") return;
47212
+ const busy = win && ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47213
+ if (!busy || attempt >= ATOMIC_RENAME_RETRIES) throw replaceFailure(file2, e);
47214
+ sleep2(ATOMIC_RENAME_DELAY_MS);
47215
+ }
45212
47216
  }
45213
47217
  }
45214
- function firstTmpMatch(dir) {
45215
- let handle;
47218
+ function replaceFailure(file2, e) {
47219
+ const busy = ATOMIC_RENAME_BUSY_CODES.includes(errCode2(e) ?? "");
47220
+ const cause = e.message;
47221
+ 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 });
47222
+ }
47223
+ function removeTmpFile(tmp, opts = {}) {
45216
47224
  try {
45217
- handle = opendirSync(dir);
47225
+ unlinkWithRetry(tmp, opts);
45218
47226
  } catch {
45219
- return null;
45220
47227
  }
47228
+ }
47229
+ function atomicWriteFile(file2, text, opts = {}) {
47230
+ mkdirSync4(path3.dirname(file2), { recursive: true });
47231
+ const tmp = path3.join(path3.dirname(file2), `${ATOMIC_TMP_PREFIX}${path3.basename(file2)}${ATOMIC_TMP_MARK}${process.pid}`);
45221
47232
  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();
47233
+ writeFileSync2(tmp, text);
47234
+ renameWithRetry(tmp, file2, opts);
47235
+ } catch (e) {
47236
+ removeTmpFile(tmp, opts);
47237
+ throw replaceFailure(file2, e);
45230
47238
  }
45231
47239
  }
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;
47240
+
47241
+ // src/core/ops/host-text.ts
47242
+ var BOM_CODE = 65279;
47243
+ var CR_CODE = 13;
47244
+ var CRLF = "\r\n";
47245
+ var LF = "\n";
47246
+ function hostLayout(raw) {
47247
+ let crlf = 0;
47248
+ let lf = 0;
47249
+ for (let i = raw.indexOf(LF); i >= 0; i = raw.indexOf(LF, i + 1)) {
47250
+ if (i > 0 && raw.charCodeAt(i - 1) === CR_CODE) crlf += 1;
47251
+ else lf += 1;
47252
+ }
47253
+ return { bom: raw.length > 0 && raw.charCodeAt(0) === BOM_CODE, crlf: crlf > 0 && crlf >= lf };
47254
+ }
47255
+ function hostText(raw) {
47256
+ const bare2 = raw.length > 0 && raw.charCodeAt(0) === BOM_CODE ? raw.slice(1) : raw;
47257
+ return bare2.indexOf(CRLF) < 0 ? bare2 : bare2.split(CRLF).join(LF);
47258
+ }
47259
+ function withLayout(text, layout) {
47260
+ const eol = layout.crlf ? text.split(LF).join(CRLF) : text;
47261
+ return layout.bom ? String.fromCharCode(BOM_CODE) + eol : eol;
45277
47262
  }
45278
47263
 
45279
47264
  // 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";
47265
+ function formatOf(path5) {
47266
+ if (path5.endsWith(JSONC_EXT)) return "jsonc";
47267
+ if (path5.endsWith(TOML_EXT)) return "toml";
45285
47268
  return "json";
45286
47269
  }
45287
- function readHostConfig(agent, path4) {
45288
- let file2 = path4;
47270
+ function readHostConfig(agent, path5) {
47271
+ let file2 = path5;
45289
47272
  if (agent === "opencode") {
45290
- const jsonc = join7(dirname3(path4), OPENCODE_CONFIG_FILES[0]);
45291
- if (existsSync5(jsonc)) file2 = jsonc;
47273
+ const jsonc = join6(dirname3(path5), OPENCODE_CONFIG_FILES[0]);
47274
+ if (existsSync4(jsonc)) file2 = jsonc;
45292
47275
  }
45293
- const text = existsSync5(file2) ? readFileSync5(file2, "utf8") : "";
45294
- return { agent, text, format: formatOf(file2), path: file2 };
47276
+ const raw = existsSync4(file2) ? readFileSync4(file2, "utf8") : "";
47277
+ return { agent, text: hostText(raw), format: agent === "opencode" && !file2.endsWith(TOML_EXT) ? "jsonc" : formatOf(file2), path: file2, layout: hostLayout(raw) };
45295
47278
  }
45296
47279
  function stripJsonComments(text) {
45297
47280
  let out = "";
@@ -45425,171 +47408,63 @@ function scanJson(text, format) {
45425
47408
  if (sc.i !== clean.length) sc.fail();
45426
47409
  return { clean, root, value };
45427
47410
  }
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
- }
47411
+ function keyNames(key) {
47412
+ return key.keys.map((k) => k.type === "TOMLBare" ? k.name : k.value);
45454
47413
  }
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;
47414
+ function lineStartOf(text, at) {
47415
+ return at === 0 ? 0 : text.lastIndexOf("\n", at - 1) + 1;
47416
+ }
47417
+ function lineEndOf(text, at) {
47418
+ const nl = text.indexOf("\n", at);
47419
+ return nl < 0 ? text.length : nl + 1;
47420
+ }
47421
+ function tomlValue(text) {
47422
+ return getStaticTOMLValue(parseTOML(text));
45540
47423
  }
45541
47424
  function scanToml(text) {
45542
- const value = {};
47425
+ const program = parseTOML(text);
45543
47426
  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;
47427
+ const keys = [];
47428
+ const addKey = (base, kv) => {
47429
+ keys.push({ base, full: [...base, ...keyNames(kv.key)], start: kv.range[0], end: kv.range[1], inline: kv.value.type === "TOMLInlineTable" });
47430
+ };
47431
+ for (const node3 of program.body[0].body) {
47432
+ if (node3.type === "TOMLKeyValue") {
47433
+ addKey([], node3);
45568
47434
  continue;
45569
47435
  }
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;
47436
+ if (!node3.resolvedKey.every((seg) => typeof seg === "string")) continue;
47437
+ const path5 = node3.resolvedKey;
47438
+ for (const kv of node3.body) addKey(path5, kv);
47439
+ if (node3.kind !== "standard") continue;
47440
+ const start = lineStartOf(text, node3.range[0]);
47441
+ const headEnd = lineEndOf(text, node3.key.range[1]);
47442
+ const last2 = node3.body[node3.body.length - 1];
47443
+ tables.push({
47444
+ path: path5,
47445
+ header: text.slice(start, text[headEnd - 1] === "\n" ? headEnd - 1 : headEnd),
47446
+ start,
47447
+ end: last2 === void 0 ? headEnd : lineEndOf(text, last2.range[1])
47448
+ });
45580
47449
  }
45581
- return { value, tables };
47450
+ return { value: getStaticTOMLValue(program), tables, keys };
45582
47451
  }
45583
- function parseHostConfig(agent, path4, text, format) {
47452
+ function tomlTableSpans(text) {
47453
+ return scanToml(text).tables;
47454
+ }
47455
+ function tomlHeaderText(path5) {
47456
+ return "[" + path5.map(tomlHeaderKey).join(".") + "]";
47457
+ }
47458
+ function parseHostConfig(agent, path5, text, format) {
45584
47459
  try {
45585
47460
  return format === "toml" ? scanToml(text).value : scanJson(text, format).value;
45586
47461
  } catch {
45587
- throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path4, format });
47462
+ throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
45588
47463
  }
45589
47464
  }
45590
- function hostConfigValueAt(value, path4) {
47465
+ function hostConfigValueAt(value, path5) {
45591
47466
  let cur = value;
45592
- for (const seg of path4) {
47467
+ for (const seg of path5) {
45593
47468
  if (!isPlainObject6(cur)) return void 0;
45594
47469
  cur = cur[seg];
45595
47470
  }
@@ -45622,91 +47497,131 @@ function indentUnit(root, clean) {
45622
47497
  function render(value, unit, base) {
45623
47498
  return JSON.stringify(value, null, unit).split("\n").join("\n" + base);
45624
47499
  }
45625
- function nest(path4, value) {
47500
+ function nest(path5, value) {
45626
47501
  let out = value;
45627
- for (let k = path4.length - 1; k >= 0; k -= 1) out = { [path4[k]]: out };
47502
+ for (let k = path5.length - 1; k >= 0; k -= 1) out = { [path5[k]]: out };
45628
47503
  return out;
45629
47504
  }
45630
- function setJsonText(text, format, path4, value) {
47505
+ function setJsonText(text, format, path5, value) {
45631
47506
  const doc = scanJson(text, format);
45632
47507
  const unit = indentUnit(doc.root, doc.clean);
45633
- if (doc.root === null) return render(nest(path4, value), unit, "") + "\n";
47508
+ if (doc.root === null) return render(nest(path5, value), unit, "") + "\n";
45634
47509
  let node3 = doc.root;
45635
47510
  let depth = 0;
45636
- while (depth < path4.length && node3.kind === "object") {
45637
- const hit = node3.members.find((m) => m.key === path4[depth]);
47511
+ while (depth < path5.length && node3.kind === "object") {
47512
+ const hit = node3.members.find((m) => m.key === path5[depth]);
45638
47513
  if (hit === void 0) break;
45639
47514
  node3 = hit.node;
45640
47515
  depth += 1;
45641
47516
  }
45642
- if (depth === path4.length) {
47517
+ if (depth === path5.length) {
45643
47518
  return text.slice(0, node3.start) + render(value, unit, lineIndent(doc.clean, node3.start)) + text.slice(node3.end);
45644
47519
  }
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) {
47520
+ if (node3.kind !== "object") throw new SyntaxError("not an object at " + path5.slice(0, depth).join("."));
47521
+ const rest = nest(path5.slice(depth + 1), value);
47522
+ const last2 = node3.members[node3.members.length - 1];
47523
+ if (last2 === void 0) {
45649
47524
  const base2 = lineIndent(doc.clean, node3.start);
45650
- const member2 = "\n" + base2 + unit + JSON.stringify(path4[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
47525
+ const member2 = "\n" + base2 + unit + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base2 + unit) + "\n" + base2;
45651
47526
  return text.slice(0, node3.start + 1) + member2 + text.slice(node3.end - 1);
45652
47527
  }
45653
- const base = lineIndent(doc.clean, last.keyStart);
45654
- let at = last.node.end;
47528
+ const base = lineIndent(doc.clean, last2.keyStart);
47529
+ let at = last2.node.end;
45655
47530
  while (" \r\n".includes(doc.clean[at])) at += 1;
45656
47531
  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);
47532
+ const insertAt = trailing ? at + 1 : last2.node.end;
47533
+ const member = (trailing ? "" : ",") + "\n" + base + JSON.stringify(path5[depth]) + ": " + render(rest, unit, base);
45659
47534
  return text.slice(0, insertAt) + member + text.slice(insertAt);
45660
47535
  }
45661
47536
  function tomlScalar(v) {
45662
47537
  if (Array.isArray(v)) return "[" + v.map(tomlScalar).join(", ") + "]";
47538
+ if (isPlainObject6(v)) return "{ " + Object.entries(v).map(([k, x]) => tomlHeaderKey(k) + " = " + tomlScalar(x)).join(", ") + " }";
45663
47539
  if (typeof v === "string") return JSON.stringify(v);
45664
47540
  if (typeof v === "number" || typeof v === "boolean") return String(v);
45665
47541
  throw new SyntaxError("unsupported TOML value");
45666
47542
  }
45667
47543
  function tomlHeaderKey(seg) {
47544
+ if (seg === "") return '""';
45668
47545
  for (const ch of seg) {
45669
47546
  const bare2 = ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-";
45670
47547
  if (!bare2) return JSON.stringify(seg);
45671
47548
  }
45672
47549
  return seg;
45673
47550
  }
45674
- function tomlBlock(path4, value) {
45675
- let out = "[" + path4.map(tomlHeaderKey).join(".") + "]\n";
47551
+ function tomlBlock(path5, value) {
47552
+ let out = "[" + path5.map(tomlHeaderKey).join(".") + "]\n";
45676
47553
  const subs = [];
45677
47554
  for (const [k, v] of Object.entries(value)) {
45678
- if (isPlainObject6(v)) subs.push(tomlBlock([...path4, k], v));
47555
+ if (isPlainObject6(v)) subs.push(tomlBlock([...path5, k], v));
45679
47556
  else out += tomlHeaderKey(k) + " = " + tomlScalar(v) + "\n";
45680
47557
  }
45681
47558
  return [out, ...subs].join("\n");
45682
47559
  }
45683
- function setTomlText(text, path4, value) {
45684
- if (!isPlainObject6(value)) throw new SyntaxError("TOML edits replace a whole table");
47560
+ function under(path5, prefix) {
47561
+ return path5.length >= prefix.length && prefix.every((seg, k) => path5[k] === seg);
47562
+ }
47563
+ function keyLineRange(text, k) {
47564
+ const ls = lineStartOf(text, k.start);
47565
+ const le = lineEndOf(text, k.end);
47566
+ const rest = text.slice(k.end, le).trim();
47567
+ const alone = text.slice(ls, k.start).trim() === "" && (rest === "" || rest.startsWith("#"));
47568
+ return alone ? [ls, le] : [k.start, k.end];
47569
+ }
47570
+ function withValueAt(root, rel, value) {
47571
+ if (rel.length === 0) return value;
47572
+ const base = isPlainObject6(root) ? { ...root } : {};
47573
+ const next = withValueAt(base[rel[0]], rel.slice(1), value);
47574
+ if (next === void 0) delete base[rel[0]];
47575
+ else base[rel[0]] = next;
47576
+ return base;
47577
+ }
47578
+ function replaceToml(text, doc, path5, value) {
47579
+ const block = value === void 0 ? "" : tomlBlock(path5, value);
47580
+ const owned = doc.tables.filter((t) => under(t.path, path5));
47581
+ const cuts = doc.keys.filter((k) => under(k.full, path5) && !under(k.base, path5)).map((k) => [...keyLineRange(text, k), ""]);
47582
+ owned.forEach((t, n) => cuts.push([t.start, t.end, n === 0 ? block : ""]));
47583
+ cuts.sort((a, b) => b[0] - a[0]);
47584
+ let out = text;
47585
+ for (const [s, e, put] of cuts) out = out.slice(0, s) + put + out.slice(e);
47586
+ if (owned.length > 0 || block === "") return out;
47587
+ const sep2 = out === "" ? "" : out.endsWith("\n\n") ? "" : out.endsWith("\n") ? "\n" : "\n\n";
47588
+ return out + sep2 + block;
47589
+ }
47590
+ var tableLike = (v) => v === void 0 || isPlainObject6(v);
47591
+ function setTomlText(text, path5, value) {
47592
+ if (value !== void 0 && !isPlainObject6(value)) throw new SyntaxError("TOML edits replace a whole table");
45685
47593
  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) {
47594
+ const cur = hostConfigValueAt(doc.value, path5);
47595
+ if (sameValue(cur, value)) return text;
47596
+ const inline = doc.keys.find((k) => k.inline && k.full.length < path5.length && under(path5, k.full));
47597
+ if (inline !== void 0) {
47598
+ const whole = withValueAt(hostConfigValueAt(doc.value, inline.full), path5.slice(inline.full.length), value);
47599
+ return replaceToml(text, doc, inline.full, whole);
47600
+ }
47601
+ if (isPlainObject6(cur) && isPlainObject6(value)) {
47602
+ const names = [.../* @__PURE__ */ new Set([...Object.keys(cur), ...Object.keys(value)])].filter((k) => !sameValue(cur[k], value[k]));
47603
+ if (names.every((k) => tableLike(cur[k]) && tableLike(value[k]))) {
47604
+ let out = text;
47605
+ for (const k of names) out = setTomlText(out, [...path5, k], value[k]);
47606
+ return out;
47607
+ }
47608
+ }
47609
+ return replaceToml(text, doc, path5, value);
47610
+ }
47611
+ function setText(agent, path5, text, format, key, value) {
45702
47612
  try {
45703
- return format === "toml" ? setTomlText(text, key, value) : setJsonText(text, format, key, value);
47613
+ if (format !== "toml") return setJsonText(text, format, key, value);
47614
+ const out = setTomlText(text, key, value);
47615
+ const landed = hostConfigValueAt(tomlValue(out), key);
47616
+ const emptyTable = isPlainObject6(value) && Object.keys(value).length === 0;
47617
+ if (!sameValue(landed, value) && !(emptyTable && landed === void 0)) throw new SyntaxError("edit did not land");
47618
+ return out;
45704
47619
  } catch {
45705
- throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path4, format });
47620
+ throw new CtxError("CONFIG_PARSE_FAILED", { agent, path: path5, format });
45706
47621
  }
45707
47622
  }
45708
47623
  function serverScript() {
45709
- return join7(dirname3(process.argv[1] ?? ""), SERVER_ENTRY_FILE);
47624
+ return join6(dirname3(process.argv[1] ?? ""), SERVER_ENTRY_FILE);
45710
47625
  }
45711
47626
  function listTarget(key, own4, v1) {
45712
47627
  return {
@@ -45732,14 +47647,14 @@ function ownTargets(agent) {
45732
47647
  if (agent === "pi") return [listTarget(PI_PACKAGES_KEY, PI_GIT_PACKAGE, V1_PI_PACKAGE)];
45733
47648
  return [];
45734
47649
  }
45735
- function applyEdits(agent, path4, text, format, wanted) {
45736
- const parsed = parseHostConfig(agent, path4, text, format);
47650
+ function applyEdits(agent, path5, text, format, wanted) {
47651
+ const parsed = parseHostConfig(agent, path5, text, format);
45737
47652
  let out = text;
45738
47653
  const edits = [];
45739
47654
  for (const [key, after] of wanted) {
45740
47655
  const before = hostConfigValueAt(parsed, key);
45741
47656
  if (sameValue(before, after)) continue;
45742
- out = setText(agent, path4, out, format, key, after);
47657
+ out = setText(agent, path5, out, format, key, after);
45743
47658
  edits.push({ path: key.join("."), before, after });
45744
47659
  }
45745
47660
  return { text: out, format, edits };
@@ -45753,26 +47668,307 @@ function writeHostConfigEdit(_requested, current, patch) {
45753
47668
  const wanted = Object.entries(patch).map(([k, v]) => [[k], v]);
45754
47669
  const result = applyEdits(current.agent, current.path, current.text, current.format, wanted);
45755
47670
  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);
47671
+ atomicWriteFile(current.path, current.layout === void 0 ? result.text : withLayout(result.text, current.layout));
45759
47672
  return result.edits;
45760
47673
  }
45761
47674
 
47675
+ // src/core/ops/detect-v1.ts
47676
+ var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
47677
+ var keyPath = (...parts) => parts.join(".");
47678
+ var finding = (file2, path5, reason) => ({ file: file2, path: path5, reason });
47679
+ function stripJsonc(text) {
47680
+ let out = "";
47681
+ let inStr = false;
47682
+ let esc4 = false;
47683
+ for (let i = 0; i < text.length; i++) {
47684
+ const c = text[i];
47685
+ if (inStr) {
47686
+ out += c;
47687
+ if (esc4) esc4 = false;
47688
+ else if (c === "\\") esc4 = true;
47689
+ else if (c === '"') inStr = false;
47690
+ continue;
47691
+ }
47692
+ if (c === '"') {
47693
+ inStr = true;
47694
+ out += c;
47695
+ continue;
47696
+ }
47697
+ if (c === "/" && text[i + 1] === "/") {
47698
+ while (i < text.length && text[i] !== "\n") i++;
47699
+ out += "\n";
47700
+ continue;
47701
+ }
47702
+ if (c === "/" && text[i + 1] === "*") {
47703
+ const end = text.indexOf("*/", i + 2);
47704
+ i = end === -1 ? text.length : end + 1;
47705
+ continue;
47706
+ }
47707
+ if (c === ",") {
47708
+ let j = i + 1;
47709
+ while (j < text.length && " \r\n".includes(text[j])) j++;
47710
+ if (text[j] === "}" || text[j] === "]") continue;
47711
+ }
47712
+ out += c;
47713
+ }
47714
+ return out;
47715
+ }
47716
+ function readJson(file2) {
47717
+ try {
47718
+ return JSON.parse(stripJsonc(hostText(readFileSync5(file2, "utf8"))));
47719
+ } catch {
47720
+ return void 0;
47721
+ }
47722
+ }
47723
+ function readText(file2) {
47724
+ try {
47725
+ return hostText(readFileSync5(file2, "utf8"));
47726
+ } catch {
47727
+ return "";
47728
+ }
47729
+ }
47730
+ function readTomlTables(file2) {
47731
+ try {
47732
+ return tomlTableSpans(readText(file2));
47733
+ } catch {
47734
+ return [];
47735
+ }
47736
+ }
47737
+ var listOf = (v) => Array.isArray(v) ? v : [];
47738
+ var commandOf = (v) => isObj(v) && typeof v.command === "string" ? v.command : null;
47739
+ function nestedCommands(doc) {
47740
+ const out = [];
47741
+ if (!isObj(doc) || !isObj(doc[HOOKS_KEY])) return out;
47742
+ for (const [event, groups] of Object.entries(doc[HOOKS_KEY])) {
47743
+ listOf(groups).forEach((group, i) => {
47744
+ if (!isObj(group)) return;
47745
+ listOf(group[HOOKS_KEY]).forEach((inner, j) => {
47746
+ const command = commandOf(inner);
47747
+ if (command !== null) out.push({ path: keyPath(HOOKS_KEY, event, i, HOOKS_KEY, j), command });
47748
+ });
47749
+ });
47750
+ }
47751
+ return out;
47752
+ }
47753
+ function flatCommands(events, prefix) {
47754
+ const out = [];
47755
+ if (!isObj(events)) return out;
47756
+ for (const [event, entries] of Object.entries(events)) {
47757
+ listOf(entries).forEach((entry, i) => {
47758
+ const command = commandOf(entry);
47759
+ if (command !== null) out.push({ path: keyPath(...prefix, event, i), command });
47760
+ });
47761
+ }
47762
+ return out;
47763
+ }
47764
+ var isV1Hook = (cmd) => cmd.includes(SERVER_KEY) && (V1_SCRIPT_NAMES.some((name) => cmd.includes(name)) || cmd.includes(V1_HOOK_COMMAND));
47765
+ var isCodexScript = (cmd) => cmd.includes(V1_SCRIPT_EXT) && V1_PATH_SEPS.some((sep2) => cmd.includes(V1_CODEX_HOOKS_DIR.join(sep2) + sep2));
47766
+ function dataDir(dir, reason, out) {
47767
+ if (existsSync5(dir)) out.push(finding(dir, "", reason));
47768
+ }
47769
+ function mcpEntry(file2, doc, out) {
47770
+ if (isObj(doc) && isObj(doc[MCP_SERVERS_KEY]) && Object.hasOwn(doc[MCP_SERVERS_KEY], SERVER_KEY)) {
47771
+ out.push(finding(file2, keyPath(MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.mcpEntry));
47772
+ }
47773
+ }
47774
+ function claudeShapeSettings(agentHome, out) {
47775
+ const file2 = join7(agentHome, SETTINGS_FILE);
47776
+ const doc = readJson(file2);
47777
+ for (const c of nestedCommands(doc)) {
47778
+ if (c.command.includes(V1_CACHE_HEAL_NAME)) out.push(finding(file2, c.path, V1_REASON.cacheHealHook));
47779
+ else if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.hook));
47780
+ }
47781
+ const status = isObj(doc) ? commandOf(doc[STATUS_LINE_KEY]) : null;
47782
+ if (status !== null && status.includes(V1_STATUSLINE_COMMAND)) {
47783
+ out.push(finding(file2, STATUS_LINE_KEY, V1_REASON.statusLine));
47784
+ }
47785
+ mcpEntry(file2, doc, out);
47786
+ }
47787
+ function v1HookFile(file2, out) {
47788
+ const doc = readJson(file2);
47789
+ const cmds = isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : [];
47790
+ if (cmds.some((c) => c.command.includes(V1_HOOK_COMMAND))) out.push(finding(file2, "", V1_REASON.hookFile));
47791
+ }
47792
+ function scanClaudeCode(home, agentHome, out) {
47793
+ claudeShapeSettings(agentHome, out);
47794
+ for (const ext of V1_CACHE_HEAL_EXTS) {
47795
+ const file2 = join7(agentHome, V1_HOOKS_DIR_NAME, V1_CACHE_HEAL_NAME + ext);
47796
+ if (existsSync5(file2)) out.push(finding(file2, "", V1_REASON.cacheHealFile));
47797
+ }
47798
+ const userFile = join7(home, CLAUDE_USER_CONFIG_FILE);
47799
+ mcpEntry(userFile, readJson(userFile), out);
47800
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47801
+ }
47802
+ function scanCodex(agentHome, out) {
47803
+ const hooksFile = join7(agentHome, HOOKS_JSON_FILE);
47804
+ for (const c of nestedCommands(readJson(hooksFile))) {
47805
+ if (c.command.includes(V1_CODEX_HOOK_COMMAND) || isCodexScript(c.command)) {
47806
+ out.push(finding(hooksFile, c.path, V1_REASON.codexHook));
47807
+ }
47808
+ }
47809
+ const tomlFile = join7(agentHome, CONFIG_TOML_FILE);
47810
+ for (const span of readTomlTables(tomlFile)) {
47811
+ if (tomlHeaderText(span.path).startsWith(V1_TOML_SECTION_PREFIX)) out.push(finding(tomlFile, span.header.trim(), V1_REASON.codexToml));
47812
+ }
47813
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47814
+ }
47815
+ function scanGemini(agentHome, out) {
47816
+ const file2 = join7(agentHome, SETTINGS_FILE);
47817
+ for (const c of nestedCommands(readJson(file2))) {
47818
+ if (c.command.includes(SERVER_KEY)) out.push(finding(file2, c.path, V1_REASON.hook));
47819
+ }
47820
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDirShared, out);
47821
+ }
47822
+ function scanVscode(agentHome, project, out) {
47823
+ if (project !== void 0) {
47824
+ v1HookFile(join7(project, GITHUB_DIR_NAME, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
47825
+ const mcpFile2 = join7(project, VSCODE_DIR_NAME, VSCODE_MCP_FILE);
47826
+ const doc = readJson(mcpFile2);
47827
+ const servers = isObj(doc) && isObj(doc[VSCODE_MCP_SERVERS_KEY]) ? doc[VSCODE_MCP_SERVERS_KEY] : {};
47828
+ const entry = Object.hasOwn(servers, SERVER_KEY) ? servers[SERVER_KEY] : void 0;
47829
+ if (isObj(entry) && (entry.command === V1_BIN_COMMAND || listOf(entry.args).some((a) => a === V1_BIN_COMMAND))) {
47830
+ out.push(finding(mcpFile2, keyPath(VSCODE_MCP_SERVERS_KEY, SERVER_KEY), V1_REASON.vscodeMcp));
47831
+ }
47832
+ dataDir(join7(project, GITHUB_DIR_NAME, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
47833
+ }
47834
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME, V1_SESSIONS_DIR_NAME), V1_REASON.dataDir, out);
47835
+ }
47836
+ function jsonFiles(dir) {
47837
+ try {
47838
+ return readdirSync3(dir).filter((name) => name.endsWith(KIRO_AGENT_FILE_EXT)).sort();
47839
+ } catch {
47840
+ return [];
47841
+ }
47842
+ }
47843
+ function scanKiro(agentHome, project, out) {
47844
+ const agentsDir = join7(agentHome, KIRO_AGENTS_DIR);
47845
+ const defaultFile = join7(agentHome, ...KIRO_AGENT_FILE);
47846
+ for (const name of jsonFiles(agentsDir)) {
47847
+ const file2 = join7(agentsDir, name);
47848
+ const doc = readJson(file2);
47849
+ if (isObj(doc) && doc[KIRO_AGENT_NAME_KEY] === SERVER_KEY) {
47850
+ out.push(finding(file2, "", V1_REASON.kiroAgentFile));
47851
+ continue;
47852
+ }
47853
+ if (file2 !== defaultFile) continue;
47854
+ for (const c of isObj(doc) ? flatCommands(doc[HOOKS_KEY], [HOOKS_KEY]) : []) {
47855
+ if (isV1Hook(c.command)) out.push(finding(file2, c.path, V1_REASON.kiroHook));
47856
+ }
47857
+ }
47858
+ const steeringDocs = [join7(agentHome, ...KIRO_STEERING_FILE)];
47859
+ if (project !== void 0) steeringDocs.push(join7(project, ...AGENT_HOME_DIR.kiro, ...KIRO_STEERING_FILE));
47860
+ for (const file2 of steeringDocs) {
47861
+ if (existsSync5(file2)) out.push(finding(file2, "", V1_REASON.kiroSteering));
47862
+ }
47863
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47864
+ }
47865
+ function scanPi(piAgentDir, agentHome, out) {
47866
+ const file2 = join7(piAgentDir, SETTINGS_FILE);
47867
+ const doc = readJson(file2);
47868
+ listOf(isObj(doc) ? doc[PI_PACKAGES_KEY] : void 0).forEach((pkg, i) => {
47869
+ const spec = isObj(pkg) ? pkg[PI_PACKAGE_SOURCE_KEY] : pkg;
47870
+ if (spec === V1_PI_PACKAGE) out.push(finding(file2, keyPath(PI_PACKAGES_KEY, i), V1_REASON.piNpm));
47871
+ });
47872
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47873
+ }
47874
+ function scanOpencode(agentHome, out) {
47875
+ for (const name of OPENCODE_CONFIG_FILES) {
47876
+ const file2 = join7(agentHome, name);
47877
+ const doc = readJson(file2);
47878
+ if (!isObj(doc) || !Array.isArray(doc[OPENCODE_PLUGIN_KEY])) continue;
47879
+ doc[OPENCODE_PLUGIN_KEY].forEach((spec, i) => {
47880
+ if (spec === V1_OPENCODE_PLUGIN_SPEC) out.push(finding(file2, keyPath(OPENCODE_PLUGIN_KEY, i), V1_REASON.opencodePlugin));
47881
+ });
47882
+ return;
47883
+ }
47884
+ }
47885
+ function scanZcode(agentHome, out) {
47886
+ const configFile = join7(agentHome, ZCODE_CLI_DIR, CONFIG_JSON_FILE);
47887
+ const config4 = readJson(configFile);
47888
+ const events = isObj(config4) && isObj(config4[HOOKS_KEY]) ? config4[HOOKS_KEY][ZCODE_EVENTS_KEY] : void 0;
47889
+ for (const c of flatCommands(events, [HOOKS_KEY, ZCODE_EVENTS_KEY])) {
47890
+ if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(configFile, c.path, V1_REASON.zcodeHook));
47891
+ }
47892
+ const hooksFile = join7(agentHome, ZCODE_CLI_DIR, HOOKS_JSON_FILE);
47893
+ for (const c of nestedCommands(readJson(hooksFile))) {
47894
+ if (c.command.includes(V1_HOOK_COMMAND)) out.push(finding(hooksFile, c.path, V1_REASON.zcodeHook));
47895
+ }
47896
+ }
47897
+ function firstTmpMatch(dir) {
47898
+ let handle;
47899
+ try {
47900
+ handle = opendirSync(dir);
47901
+ } catch {
47902
+ return null;
47903
+ }
47904
+ try {
47905
+ for (let e = handle.readSync(); e !== null; e = handle.readSync()) {
47906
+ if (e.name.startsWith(V1_TMP_PREFIX)) return e.name;
47907
+ }
47908
+ return null;
47909
+ } catch {
47910
+ return null;
47911
+ } finally {
47912
+ handle.closeSync();
47913
+ }
47914
+ }
47915
+ function scanAll(home, tmp, out) {
47916
+ const root = join7(home, DATA_ROOT.slice(1));
47917
+ for (const name of V1_DATA_ROOT_ENTRIES) dataDir(join7(root, name), V1_REASON.dataRoot, out);
47918
+ if (firstTmpMatch(tmp) !== null) out.push(finding(tmp, V1_TMP_PREFIX + "*", V1_REASON.tmpFile));
47919
+ }
47920
+ function detectV1(agent, home, scope = {}) {
47921
+ const out = [];
47922
+ const project = scope.project;
47923
+ 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]);
47924
+ switch (agent) {
47925
+ case "claude-code":
47926
+ scanClaudeCode(home, agentHome, out);
47927
+ break;
47928
+ case "codex":
47929
+ scanCodex(agentHome, out);
47930
+ break;
47931
+ case "gemini":
47932
+ scanGemini(agentHome, out);
47933
+ break;
47934
+ case "qwen":
47935
+ claudeShapeSettings(agentHome, out);
47936
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47937
+ break;
47938
+ case "copilot-cli":
47939
+ v1HookFile(join7(agentHome, V1_HOOKS_DIR_NAME, OWN_HOOK_FILE), out);
47940
+ dataDir(join7(agentHome, V1_DATA_DIR_NAME), V1_REASON.dataDir, out);
47941
+ break;
47942
+ case "vscode":
47943
+ scanVscode(agentHome, project, out);
47944
+ break;
47945
+ case "kiro":
47946
+ scanKiro(agentHome, project, out);
47947
+ break;
47948
+ case "pi":
47949
+ scanPi(scope.piAgentDir !== void 0 && scope.piAgentDir !== "" ? scope.piAgentDir : join7(agentHome, PI_AGENT_DIR), agentHome, out);
47950
+ break;
47951
+ // D-WIN-PIDIR-1: empty is unset
47952
+ case "opencode":
47953
+ scanOpencode(agentHome, out);
47954
+ break;
47955
+ case "zcode":
47956
+ scanZcode(agentHome, out);
47957
+ break;
47958
+ }
47959
+ scanAll(home, scope.tmp ?? tmpdir(), out);
47960
+ return out;
47961
+ }
47962
+
45762
47963
  // src/core/ops/plugin-root.ts
45763
47964
  import { existsSync as existsSync6, readdirSync as readdirSync4, realpathSync as realpathSync4 } from "node:fs";
45764
47965
  import { dirname as dirname4, isAbsolute, join as join8 } from "node:path";
45765
47966
  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 });
47967
+ function missing(agent, path5) {
47968
+ return new CtxError("PLUGIN_ROOT_MISSING", { agent, path: path5 });
45773
47969
  }
45774
47970
  function marketplaceRoot(adapter, env) {
45775
- const cache = join8(homeOf2(env), HOST_CONFIG_DIR_NAME, HOST_PLUGINS_DIR_NAME, PLUGIN_CACHE_DIR_NAME);
47971
+ const cache = join8(claudeDirOf(env, requireHomeDir(env)), HOST_PLUGINS_DIR_NAME, PLUGIN_CACHE_DIR_NAME);
45776
47972
  const pattern = join8(cache, "*", PLUGIN_NAME);
45777
47973
  if (!existsSync6(cache)) throw missing(adapter.id, pattern);
45778
47974
  const found = readdirSync4(cache).sort().map((marketplace) => join8(cache, marketplace, PLUGIN_NAME)).filter((dir) => existsSync6(dir));
@@ -45782,7 +47978,7 @@ function marketplaceRoot(adapter, env) {
45782
47978
  function configEntryRoot(adapter, env) {
45783
47979
  const spec = OWN_MCP_ENTRY[adapter.id];
45784
47980
  if (spec === void 0) throw missing(adapter.id, SERVER_KEY);
45785
- const file2 = join8(homeOf2(env), ...spec.file);
47981
+ const file2 = ownMcpFileOf(adapter.id, spec.file, env, requireHomeDir(env));
45786
47982
  if (!existsSync6(file2)) throw missing(adapter.id, file2);
45787
47983
  const current = readHostConfig(adapter.id, file2);
45788
47984
  const value = parseHostConfig(adapter.id, file2, current.text, current.format);
@@ -45800,7 +47996,7 @@ function candidate(adapter, env) {
45800
47996
  case "hooks+mcp":
45801
47997
  return configEntryRoot(adapter, env);
45802
47998
  case "extension":
45803
- return join8(homeOf2(env), ...AGENT_HOME_DIR[adapter.id], EXTENSIONS_DIR_NAME, PLUGIN_NAME);
47999
+ return join8(requireHomeDir(env), ...AGENT_HOME_DIR[adapter.id], EXTENSIONS_DIR_NAME, PLUGIN_NAME);
45804
48000
  case "plugin":
45805
48001
  return join8(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, adapter.id, PLUGIN_CURRENT_LINK);
45806
48002
  case "in-process":
@@ -45808,11 +48004,11 @@ function candidate(adapter, env) {
45808
48004
  }
45809
48005
  }
45810
48006
  function resolvePluginRoot(adapter, env) {
45811
- const path4 = candidate(adapter, env);
48007
+ const path5 = candidate(adapter, env);
45812
48008
  try {
45813
- return realpathSync4.native(path4);
48009
+ return realpathSync4.native(path5);
45814
48010
  } catch {
45815
- throw missing(adapter.id, path4);
48011
+ throw missing(adapter.id, path5);
45816
48012
  }
45817
48013
  }
45818
48014
 
@@ -45838,14 +48034,31 @@ function composeMatcher(row5, event) {
45838
48034
  if (event === POST_TOOL_USE && hasReplace(row5)) alts.push(MCP_ANY_MATCH);
45839
48035
  return MATCHER_OPEN + alts.join(MATCHER_ALT) + MATCHER_CLOSE;
45840
48036
  }
48037
+ var lastSegment = (p) => {
48038
+ let at = -1;
48039
+ for (const sep2 of V1_PATH_SEPS) at = Math.max(at, p.lastIndexOf(sep2));
48040
+ return p.slice(at + 1);
48041
+ };
48042
+ function splitHead(command) {
48043
+ if (command.startsWith(SHELL_QUOTE)) {
48044
+ const close = command.indexOf(SHELL_QUOTE, 1);
48045
+ if (close < 0 || command.slice(close + 1, close + 1 + HOOK_COMMAND_SEP.length) !== HOOK_COMMAND_SEP) return null;
48046
+ return { head: command.slice(1, close), rest: command.slice(close + 1 + HOOK_COMMAND_SEP.length) };
48047
+ }
48048
+ const end = command.indexOf(HOOK_COMMAND_SEP);
48049
+ return end < 0 ? null : { head: command.slice(0, end), rest: command.slice(end + HOOK_COMMAND_SEP.length) };
48050
+ }
45841
48051
  function isOwnCommand(command, agent) {
45842
48052
  if (typeof command !== "string") return false;
45843
- const head = HOST_NODE_COMMAND + HOOK_COMMAND_SEP;
48053
+ const split = splitHead(command);
48054
+ if (split === null) return false;
48055
+ const exe = lastSegment(split.head).toLowerCase();
48056
+ if (exe !== HOST_NODE_COMMAND && exe !== HOST_NODE_COMMAND + EXE_SUFFIX) return false;
45844
48057
  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);
48058
+ if (!split.rest.endsWith(tail) || split.rest.length <= tail.length) return false;
48059
+ let script = split.rest.slice(0, split.rest.length - tail.length);
45847
48060
  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));
48061
+ return script === HOOK_ENTRY_FILE || HOOK_SCRIPT_SEPS.some((sep2) => script.endsWith(sep2 + HOOK_ENTRY_FILE));
45849
48062
  }
45850
48063
  function ownHooks(block, shape, timeoutKey, native, agent) {
45851
48064
  const out = [];
@@ -45877,11 +48090,10 @@ var validTimeout = (v) => typeof v === "number" && Number.isFinite(v) && v > 0;
45877
48090
  function mcpFile(row5, home, env) {
45878
48091
  const spec = OWN_MCP_ENTRY[row5.id];
45879
48092
  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);
48093
+ if (spec !== void 0) return ownMcpFileOf(row5.id, spec.file, env, home);
48094
+ if (row5.id === "opencode") return join9(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
45882
48095
  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);
48096
+ return join9(piAgentDirOf(env, home), SETTINGS_FILE);
45885
48097
  }
45886
48098
  return null;
45887
48099
  }
@@ -45904,7 +48116,7 @@ function hookParts(row5, home, env, worktree) {
45904
48116
  let block;
45905
48117
  try {
45906
48118
  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);
48119
+ 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
48120
  block = hostConfigValueAt(readParsed(row5.id, file2).value, spec.key);
45909
48121
  if (row5.id === "codex") {
45910
48122
  const config4 = readParsed(row5.id, join9(codexDirOf(env, home), CONFIG_TOML_FILE)).value;
@@ -45986,8 +48198,8 @@ async function loadSqlite2() {
45986
48198
  return null;
45987
48199
  }
45988
48200
  }
45989
- function openRead(sqlite, path4) {
45990
- return new sqlite.DatabaseSync(path4, { timeout: DB_TIMEOUT_MS, readOnly: true });
48201
+ function openRead(sqlite, path5) {
48202
+ return new sqlite.DatabaseSync(path5, { timeout: DB_TIMEOUT_MS, readOnly: true });
45991
48203
  }
45992
48204
  var cell = (row5) => Object.values(row5)[0];
45993
48205
  function readSchema(raw) {
@@ -46121,20 +48333,26 @@ function checkProject(i) {
46121
48333
  function checkMode(adapter) {
46122
48334
  return pass3("D10", D10_DETAIL(adapter.denyChannel));
46123
48335
  }
48336
+ function checkShell(env) {
48337
+ const win = process.platform === "win32";
48338
+ const shell = findRuntime("shell", env);
48339
+ if (shell !== null) return pass3("D11", D11_PASS_DETAIL(shell, win));
48340
+ return win ? fail3("D11", D11_WIN_DETAIL, D11_WIN_FIX) : fail3("D11", D11_POSIX_DETAIL, D11_POSIX_FIX);
48341
+ }
46124
48342
 
46125
48343
  // src/core/ops/doctor-hook.ts
46126
48344
  import { existsSync as existsSync9, readFileSync as readFileSync6 } from "node:fs";
46127
- import path3 from "node:path";
48345
+ import path4 from "node:path";
46128
48346
  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
48347
  function isObject5(v) {
46130
48348
  return typeof v === "object" && v !== null && !Array.isArray(v);
46131
48349
  }
46132
48350
  function loadFixture(bundleDir2, agent) {
46133
- const file2 = path3.join(bundleDir2, HOOK_FIXTURE_DIR, HOOK_FIXTURE_FILE);
48351
+ const file2 = path4.join(bundleDir2, HOOK_FIXTURE_DIR, HOOK_FIXTURE_FILE);
46134
48352
  if (!existsSync9(file2)) return null;
46135
48353
  let all;
46136
48354
  try {
46137
- all = JSON.parse(readFileSync6(file2, "utf8"));
48355
+ all = JSON.parse(hostText(readFileSync6(file2, "utf8")));
46138
48356
  } catch {
46139
48357
  return null;
46140
48358
  }
@@ -46159,14 +48377,14 @@ function codexHookJournaled(db) {
46159
48377
  return db.raw.prepare("SELECT 1 FROM events WHERE agent = ? LIMIT 1").get("codex") !== void 0;
46160
48378
  }
46161
48379
  async function checkHookRoundTrip(i) {
46162
- if (i.agent === "codex" && existsSync9(path3.join(i.codexConfigDir, HOOKS_JSON_FILE)) && !codexHookJournaled(i.db)) {
48380
+ if (i.agent === "codex" && existsSync9(path4.join(i.codexConfigDir, HOOKS_JSON_FILE)) && !codexHookJournaled(i.db)) {
46163
48381
  return row("UNKNOWN", D5_CODEX_UNTRUSTED_DETAIL);
46164
48382
  }
46165
48383
  const fixture = loadFixture(i.bundleDir, i.agent);
46166
48384
  if (fixture === null) return row("UNKNOWN", D5_NO_FIXTURE_DETAIL(i.agent));
46167
48385
  const now = i.now ?? (() => performance.now());
46168
48386
  const start = now();
46169
- const r = await runProcess([process.execPath, path3.join(i.bundleDir, HOOK_ENTRY_FILE), AGENT_ARG, i.agent], {
48387
+ const r = await runProcess([process.execPath, path4.join(i.bundleDir, HOOK_ENTRY_FILE), AGENT_ARG, i.agent], {
46170
48388
  cwd: i.bundleDir,
46171
48389
  env: i.env,
46172
48390
  signal: i.signal,
@@ -46180,7 +48398,7 @@ async function checkHookRoundTrip(i) {
46180
48398
  }
46181
48399
 
46182
48400
  // src/core/ops/db-heal.ts
46183
- import { existsSync as existsSync10, renameSync as renameSync2, rmSync as rmSync4 } from "node:fs";
48401
+ import { existsSync as existsSync10, rmSync as rmSync4 } from "node:fs";
46184
48402
  function integrityOk2(rows) {
46185
48403
  return rows.length === 1 && rows[0].integrity_check === INTEGRITY_OK;
46186
48404
  }
@@ -46205,7 +48423,7 @@ async function healLossless(dbPath) {
46205
48423
  }
46206
48424
  rmSync4(dbPath + DB_WAL_SUFFIX, { force: true });
46207
48425
  rmSync4(dbPath + DB_SHM_SUFFIX, { force: true });
46208
- renameSync2(tmp, dbPath);
48426
+ renameWithRetry(tmp, dbPath);
46209
48427
  } finally {
46210
48428
  rmSync4(tmp, { force: true });
46211
48429
  }
@@ -46214,7 +48432,7 @@ function renameAside(dbPath) {
46214
48432
  const ts = String(Date.now());
46215
48433
  for (const suffix of DB_SIBLING_SUFFIXES) {
46216
48434
  const file2 = dbPath + suffix;
46217
- if (existsSync10(file2)) renameSync2(file2, file2 + HEAL_TS_SEP + ts + HEAL_BACKUP_SUFFIX);
48435
+ if (existsSync10(file2)) renameWithRetry(file2, file2 + HEAL_TS_SEP + ts + HEAL_BACKUP_SUFFIX);
46218
48436
  }
46219
48437
  return ts;
46220
48438
  }
@@ -46282,11 +48500,6 @@ async function guard(id, run) {
46282
48500
  return { id, label: DOCTOR_LABEL[id], status: "UNKNOWN", detail: lineOf(err) };
46283
48501
  }
46284
48502
  }
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
48503
  async function codexDb(ctx, adapter) {
46291
48504
  if (adapter.id !== "codex" || !existsSync11(ctx.project.dbPath)) return null;
46292
48505
  try {
@@ -46303,7 +48516,7 @@ async function hookRow(ctx, adapter, host) {
46303
48516
  bundleDir: host.bundleDir,
46304
48517
  env: buildChildEnv(host.env),
46305
48518
  signal: ctx.signal,
46306
- codexConfigDir: codexDirOf(host.env, needHome(host.env)),
48519
+ codexConfigDir: codexDirOf(host.env, requireHomeDir(host.env)),
46307
48520
  // same Codex dir D3 reads (D-N6-CODEX-HOME-2)
46308
48521
  db
46309
48522
  });
@@ -46328,7 +48541,7 @@ async function runDoctorChecks(ctx, adapter, host) {
46328
48541
  D1: () => checkVersion({ bundleSha: BUNDLE_SHA, env: buildChildEnv(env), cwd: project.worktree, signal: ctx.signal }),
46329
48542
  D2: () => checkNode({ nodeVersion: process.version, bunVersion: process.versions.bun }),
46330
48543
  D3: () => checkHostConfig(adapter, env, project.worktree),
46331
- D4: () => checkV1Leftovers(adapter.id, needHome(env), { project: project.worktree, piAgentDir: env[PI_AGENT_DIR_ENV] }),
48544
+ 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
48545
  D5: () => hookRow(ctx, adapter, host),
46333
48546
  D5b: () => checkDoubleFire(adapter.id, project.worktree),
46334
48547
  D6: () => checkMcp(ctx),
@@ -46339,7 +48552,8 @@ async function runDoctorChecks(ctx, adapter, host) {
46339
48552
  return r.row;
46340
48553
  },
46341
48554
  D9: () => checkIndex(project),
46342
- D10: () => checkMode(adapter)
48555
+ D10: () => checkMode(adapter),
48556
+ D11: () => checkShell(env)
46343
48557
  };
46344
48558
  const rows = [];
46345
48559
  for (const id of DOCTOR_CHECK_ORDER) rows.push(await guard(id, checks[id]));
@@ -46588,7 +48802,7 @@ async function handler3(raw, ctx) {
46588
48802
  extra.CTX_FILE = abs;
46589
48803
  }
46590
48804
  const runtime = findRuntime(input.language);
46591
- if (runtime === null) return fail4(new CtxError("NO_RUNTIME", { lang: input.language }).toLine());
48805
+ if (runtime === null) return fail4(noRuntimeError(input.language).toLine());
46592
48806
  const env = buildChildEnv(process.env, extra);
46593
48807
  const timeoutMs = input.timeoutMs ?? EXEC_TIMEOUT_MS;
46594
48808
  const journal = { kind: "cmd", key: canonicalKey(TOOL2, input.code), path: input.file ?? null, exit_code: null };
@@ -46661,14 +48875,14 @@ function visit(abs, rel, parent, contain, seen, found) {
46661
48875
  const rules = entries.some((e) => e.name === GITIGNORE && e.isFile()) ? parent.concat(readRules(join12(abs, GITIGNORE), rel)) : parent;
46662
48876
  for (const e of entries) {
46663
48877
  if (e.name === GIT_DIR) continue;
46664
- const path4 = join12(abs, e.name);
48878
+ const path5 = join12(abs, e.name);
46665
48879
  let isDir = e.isDirectory();
46666
48880
  let isFile = e.isFile();
46667
- let target = path4;
48881
+ let target = path5;
46668
48882
  if (e.isSymbolicLink()) {
46669
48883
  let resolved;
46670
48884
  try {
46671
- resolved = realpathSync6(path4);
48885
+ resolved = realpathSync6(path5);
46672
48886
  } catch {
46673
48887
  continue;
46674
48888
  }
@@ -46681,12 +48895,12 @@ function visit(abs, rel, parent, contain, seen, found) {
46681
48895
  const segs = rel.concat(e.name);
46682
48896
  if (ignored(rules, segs, isDir)) continue;
46683
48897
  if (isFile) {
46684
- found.push({ dir: rel, name: e.name, absPath: path4 });
48898
+ found.push({ dir: rel, name: e.name, absPath: path5 });
46685
48899
  } else if (isDir) {
46686
- const key = e.isSymbolicLink() ? target : realpathSync6(path4);
48900
+ const key = e.isSymbolicLink() ? target : realpathSync6(path5);
46687
48901
  if (seen.has(key)) continue;
46688
48902
  seen.add(key);
46689
- visit(path4, segs, rules, contain, seen, found);
48903
+ visit(path5, segs, rules, contain, seen, found);
46690
48904
  }
46691
48905
  }
46692
48906
  }
@@ -46877,12 +49091,12 @@ function tlsName(host) {
46877
49091
  function request(u, conn, proxy, signal) {
46878
49092
  const host = bare(u.hostname);
46879
49093
  const port = u.port === "" ? defaultPort(u.protocol) : Number(u.port);
46880
- const path4 = u.pathname + u.search;
49094
+ const path5 = u.pathname + u.search;
46881
49095
  return new Promise((resolve4, reject) => {
46882
49096
  const onErr = (err) => reject(fail5(causeCode(err)));
46883
49097
  if (proxy === void 0) {
46884
49098
  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 } });
49099
+ const req = mod.request({ host: conn.address, port, path: path5, signal, servername: tlsName(host), headers: { host: u.host } });
46886
49100
  req.on("response", resolve4).on("error", onErr).end();
46887
49101
  return;
46888
49102
  }
@@ -46904,7 +49118,7 @@ function request(u, conn, proxy, signal) {
46904
49118
  const req = https.request({
46905
49119
  host,
46906
49120
  port,
46907
- path: path4,
49121
+ path: path5,
46908
49122
  signal,
46909
49123
  headers: { host: u.host },
46910
49124
  createConnection: () => tlsConnect({ socket, host, servername: tlsName(host) })
@@ -47076,12 +49290,12 @@ function reply2(text, isError) {
47076
49290
  return { text, isError, sandboxBytes: 0 };
47077
49291
  }
47078
49292
  function scopesOf(input) {
47079
- const set2 = {
49293
+ const set3 = {
47080
49294
  session: input.session !== void 0,
47081
49295
  source: input.source !== void 0,
47082
49296
  project: input.project === true
47083
49297
  };
47084
- return PURGE_SCOPES.filter((s) => set2[s]);
49298
+ return PURGE_SCOPES.filter((s) => set3[s]);
47085
49299
  }
47086
49300
  function changes(raw, sql, ...args) {
47087
49301
  return Number(raw.prepare(sql).run(...args).changes);
@@ -47146,8 +49360,8 @@ function buildCandidates(rows, sessionId) {
47146
49360
  if (!sessionId) return emptySet();
47147
49361
  const own4 = rows.filter((r) => r.session_id === sessionId).sort((a, b) => a.seq - b.seq);
47148
49362
  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);
49363
+ const last2 = prompts.length > 0 ? prompts[prompts.length - 1] : void 0;
49364
+ const lastRequest = last2 === void 0 ? null : make("last_request", last2, "now: " + firstLine2(last2.body), 1, null);
47151
49365
  const earlierRequests = prompts.slice(0, prompts.length - 1).map((r) => make("earlier_requests", r, "asked #" + r.seq + ": " + firstLine2(r.body), 1, null));
47152
49366
  const failures = /* @__PURE__ */ new Map();
47153
49367
  const lastOk = /* @__PURE__ */ new Map();
@@ -47171,8 +49385,8 @@ function buildCandidates(rows, sessionId) {
47171
49385
  edits.set(r.path, { row: r, count: (edits.get(r.path)?.count ?? 0) + 1 });
47172
49386
  }
47173
49387
  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);
49388
+ for (const [path5, e] of edits) {
49389
+ const c = make("changed_files", e.row, "edited " + path5 + " x" + e.count, e.count, path5);
47176
49390
  changedFiles.push({ ...c, editCount: e.count });
47177
49391
  }
47178
49392
  changedFiles.sort((a, b) => a.seq - b.seq);
@@ -47186,7 +49400,7 @@ function buildCandidates(rows, sessionId) {
47186
49400
  for (const [key, d] of decided) decisions.push(make("decisions", d.row, "decided #" + d.row.seq + ": " + firstLine2(d.row.body), d.count, key));
47187
49401
  decisions.sort((a, b) => a.seq - b.seq);
47188
49402
  const indexedSources = own4.filter((r) => r.kind === "index").map((r) => make("indexed_sources", r, "indexed " + (r.key ?? ""), 1, r.key));
47189
- const set2 = {
49403
+ const set3 = {
47190
49404
  lastRequest,
47191
49405
  openErrors: capSection(openErrors),
47192
49406
  changedFiles: capSection(changedFiles),
@@ -47194,17 +49408,17 @@ function buildCandidates(rows, sessionId) {
47194
49408
  earlierRequests: capSection(earlierRequests),
47195
49409
  indexedSources: capSection(indexedSources)
47196
49410
  };
47197
- const rest = [...set2.openErrors, ...set2.changedFiles, ...set2.decisions, ...set2.earlierRequests, ...set2.indexedSources];
49411
+ const rest = [...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources];
47198
49412
  const total = rest.length + (lastRequest === null ? 0 : 1);
47199
- if (total <= MAX_CANDIDATES_TOTAL) return set2;
49413
+ if (total <= MAX_CANDIDATES_TOTAL) return set3;
47200
49414
  const drop = new Set(rest.map((c) => c.seq).sort((a, b) => a - b).slice(0, total - MAX_CANDIDATES_TOTAL));
47201
49415
  return {
47202
49416
  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))
49417
+ openErrors: set3.openErrors.filter((c) => !drop.has(c.seq)),
49418
+ changedFiles: set3.changedFiles.filter((c) => !drop.has(c.seq)),
49419
+ decisions: set3.decisions.filter((c) => !drop.has(c.seq)),
49420
+ earlierRequests: set3.earlierRequests.filter((c) => !drop.has(c.seq)),
49421
+ indexedSources: set3.indexedSources.filter((c) => !drop.has(c.seq))
47208
49422
  };
47209
49423
  }
47210
49424
 
@@ -47303,15 +49517,15 @@ function renderState(rows, turn, extras, prefix = "") {
47303
49517
  for (const r of rows) if (newest === void 0 || r.seq > newest.seq) newest = r;
47304
49518
  const sessionId = newest === void 0 ? "" : newest.session_id;
47305
49519
  const upto = newest === void 0 || sessionId === "" ? 0 : newest.seq;
47306
- const set2 = buildCandidates(rows, sessionId);
49520
+ const set3 = buildCandidates(rows, sessionId);
47307
49521
  const openTag = `<context_mode_state session="${sessionId}" upto="${upto}">`;
47308
49522
  const emptyMoreBytes = bytesOf2(moreLine2([], prefix));
47309
49523
  const budget = STATE_BUDGET - (bytesOf2(openTag) + 1 + emptyMoreBytes + 1 + bytesOf2(STATE_CLOSE_TAG));
47310
49524
  let used = 0;
47311
- const pinnedLine = set2.lastRequest === null ? null : lineOf2(set2.lastRequest, prefix);
49525
+ const pinnedLine = set3.lastRequest === null ? null : lineOf2(set3.lastRequest, prefix);
47312
49526
  if (pinnedLine !== null) used += bytesOf2(pinnedLine) + 1;
47313
49527
  const remaining = scoreCandidates(
47314
- [...set2.openErrors, ...set2.changedFiles, ...set2.decisions, ...set2.earlierRequests, ...set2.indexedSources],
49528
+ [...set3.openErrors, ...set3.changedFiles, ...set3.decisions, ...set3.earlierRequests, ...set3.indexedSources],
47315
49529
  turn
47316
49530
  );
47317
49531
  const k = /* @__PURE__ */ new Map();
@@ -47416,8 +49630,8 @@ async function handler6(input, ctx) {
47416
49630
  if (newest === void 0) return reply3(RESUME_EMPTY_LINE, false);
47417
49631
  const sources = listSessionSources(db, sessionId, MAX_CANDIDATES).map((r) => "source " + sourceHandle(r.id) + ": " + r.label + " (" + r.bytes + " B)");
47418
49632
  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) }));
49633
+ const last2 = readLastPrompt(db, sessionId);
49634
+ const units = queryUnits(db, sessionId, recallQueryText(last2, goal), RECALL_UNIT_CANDIDATES).map((u) => ({ ...u, label: sourceHandle(u.sourceId) }));
47421
49635
  const block = renderState(rows, newest.turn, { sources, units });
47422
49636
  if (Buffer.byteLength(block, "utf8") > RESUME_CAP) throw new Error("ctx_resume: state block over RESUME_CAP (render bug).");
47423
49637
  return reply3(block, false);
@@ -47459,8 +49673,8 @@ function reductionPct(t) {
47459
49673
  return Number((t.saved * PERCENT_SCALE / Math.max(1, t.produced)).toFixed(1));
47460
49674
  }
47461
49675
  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(" | ") + " |";
49676
+ const last2 = t.calls === 0 ? STATS_NO_DATA : String(reductionPct(t));
49677
+ return "| " + [label, t.produced + " B", t.returned + " B", t.saved + " B", last2].join(" | ") + " |";
47464
49678
  }
47465
49679
  async function handler7(_input, ctx) {
47466
49680
  const db = await openDb(ctx.project, { readOnly: true });
@@ -47494,23 +49708,24 @@ var ctxStats = Object.freeze({
47494
49708
  });
47495
49709
 
47496
49710
  // src/core/tools/upgrade.ts
47497
- import { existsSync as existsSync19, realpathSync as realpathSync7, rmSync as rmSync11 } from "node:fs";
49711
+ import { existsSync as existsSync19, realpathSync as realpathSync7, rmSync as rmSync10 } from "node:fs";
47498
49712
  import { basename as basename5, dirname as dirname9, join as join19 } from "node:path";
47499
49713
 
47500
49714
  // 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";
49715
+ import { copyFileSync, existsSync as existsSync14, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
47502
49716
  import { dirname as dirname8, join as join14 } from "node:path";
47503
49717
  function defaultWrite(file2, text) {
47504
49718
  writeFileSync4(file2, text, "utf8");
47505
49719
  }
47506
49720
  function hostConfigPath(agent, home, env) {
47507
49721
  const own4 = OWN_MCP_ENTRY[agent];
47508
- if (own4 !== void 0) return join14(home, ...own4.file);
49722
+ if (own4 !== void 0) return ownMcpFileOf(agent, own4.file, env, home);
47509
49723
  switch (agent) {
47510
49724
  case "opencode":
47511
- return join14(home, ...AGENT_HOME_DIR.opencode, OPENCODE_BASE_CONFIG_FILE);
49725
+ return join14(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE);
49726
+ // D-WIN-OPENCODE-DIR-1
47512
49727
  case "pi":
47513
- return join14(env[PI_AGENT_DIR_ENV] ?? join14(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR), SETTINGS_FILE);
49728
+ return join14(piAgentDirOf(env, home), SETTINGS_FILE);
47514
49729
  case "copilot-cli":
47515
49730
  return null;
47516
49731
  default:
@@ -47523,22 +49738,32 @@ function cell2(value) {
47523
49738
  function toRow(file2, edit) {
47524
49739
  return { area: file2 + UPGRADE_AREA_KEY_SEP + edit.path, before: cell2(edit.before), after: cell2(edit.after) };
47525
49740
  }
47526
- function writeWithRollback(file2, text, write) {
49741
+ function writeWithRollback(file2, text, write, atomic) {
47527
49742
  const trash = file2 + UPGRADE_TRASH_SUFFIX;
47528
- const tmp = file2 + HOST_CONFIG_TMP_SUFFIX;
49743
+ const tmp = `${file2}${HOST_CONFIG_TMP_SUFFIX}.${process.pid}`;
47529
49744
  const had = existsSync14(file2);
47530
- mkdirSync4(dirname8(file2), { recursive: true });
49745
+ mkdirSync5(dirname8(file2), { recursive: true });
47531
49746
  if (had) copyFileSync(file2, trash);
47532
49747
  try {
47533
49748
  write(tmp, text);
47534
- renameSync3(tmp, file2);
49749
+ renameWithRetry(tmp, file2, atomic);
47535
49750
  } catch (err) {
47536
- rmSync6(tmp, { force: true });
47537
- if (had) renameSync3(trash, file2);
47538
- else rmSync6(file2, { force: true });
47539
- throw err;
49751
+ removeTmpFile(tmp, atomic);
49752
+ if (!had) {
49753
+ removeTmpFile(file2, atomic);
49754
+ throw replaceFailure(file2, err);
49755
+ }
49756
+ try {
49757
+ renameWithRetry(trash, file2, atomic);
49758
+ } catch (restoreErr) {
49759
+ throw new Error(`${replaceFailure(file2, err).message}. The original is kept at ${trash}`, { cause: restoreErr });
49760
+ }
49761
+ throw replaceFailure(file2, err);
49762
+ }
49763
+ try {
49764
+ unlinkWithRetry(trash, atomic);
49765
+ } catch {
47540
49766
  }
47541
- rmSync6(trash, { force: true });
47542
49767
  }
47543
49768
  function regenerateHostConfig(row5, home, opts = {}) {
47544
49769
  const env = opts.env ?? process.env;
@@ -47549,29 +49774,31 @@ function regenerateHostConfig(row5, home, opts = {}) {
47549
49774
  const exists = existsSync14(current.path);
47550
49775
  if (exists && result.text === current.text) return [];
47551
49776
  const text = result.text === "" && current.format !== "toml" ? JSON.stringify({}) : result.text;
47552
- writeWithRollback(current.path, text, opts.write ?? defaultWrite);
49777
+ writeWithRollback(current.path, current.layout === void 0 ? text : withLayout(text, current.layout), opts.write ?? defaultWrite, opts.atomic ?? {});
47553
49778
  return result.edits.map((e) => toRow(current.path, e));
47554
49779
  }
47555
49780
 
47556
49781
  // 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;
49782
+ import { existsSync as existsSync15, lstatSync, readdirSync as readdirSync7, readlinkSync, rmSync as rmSync6, symlinkSync, unlinkSync as unlinkSync2 } from "node:fs";
49783
+ import { basename as basename4, join as join15, win32 as win322 } from "node:path";
49784
+ function linkTarget(path5, win) {
49785
+ if (!isLink(path5)) return null;
49786
+ const target = readlinkSync(path5);
49787
+ return win ? win322.basename(target) : target;
47561
49788
  }
47562
- function isLink(path4) {
47563
- return lstatSync(path4, { throwIfNoEntry: false })?.isSymbolicLink() === true;
49789
+ function isLink(path5) {
49790
+ return lstatSync(path5, { throwIfNoEntry: false })?.isSymbolicLink() === true;
47564
49791
  }
47565
49792
  function generations(agentDir) {
47566
49793
  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
49794
  }
47568
- function settleLinks(link, tmp, old) {
47569
- if (isLink(tmp)) unlinkSync(tmp);
49795
+ function settleLinks(link, tmp, old, opts) {
49796
+ if (isLink(tmp)) unlinkSync2(tmp);
47570
49797
  if (!isLink(old)) return;
47571
- if (isLink(link)) unlinkSync(old);
47572
- else renameSync4(old, link);
49798
+ if (isLink(link)) unlinkSync2(old);
49799
+ else renameWithRetry(old, link, opts);
47573
49800
  }
47574
- function swapPluginCurrent(agentDir, sha) {
49801
+ function swapPluginCurrent(agentDir, sha, opts = {}) {
47575
49802
  const next = join15(agentDir, sha);
47576
49803
  if (!existsSync15(next) || !lstatSync(next).isDirectory()) {
47577
49804
  throw new CtxError("PLUGIN_ROOT_MISSING", { agent: basename4(agentDir), path: next });
@@ -47579,23 +49806,26 @@ function swapPluginCurrent(agentDir, sha) {
47579
49806
  const link = join15(agentDir, PLUGIN_CURRENT_LINK);
47580
49807
  const tmp = link + PLUGIN_LINK_TMP_SUFFIX;
47581
49808
  const old = link + PLUGIN_LINK_OLD_SUFFIX;
47582
- settleLinks(link, tmp, old);
47583
- const before = linkTarget(link);
49809
+ settleLinks(link, tmp, old, opts);
49810
+ const win = (opts.platform ?? process.platform) === "win32";
49811
+ const before = linkTarget(link, win);
47584
49812
  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);
49813
+ const symlink = opts.symlink ?? symlinkSync;
49814
+ if (win) symlink(next, tmp, PLUGIN_LINK_TYPE_WIN32);
49815
+ else symlink(sha, tmp, PLUGIN_LINK_TYPE);
49816
+ if (before !== null) renameWithRetry(link, old, opts);
49817
+ renameWithRetry(tmp, link, opts);
49818
+ if (before !== null) unlinkSync2(old);
47589
49819
  const keep = /* @__PURE__ */ new Set([sha]);
47590
49820
  if (before !== null) keep.add(before);
47591
49821
  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 });
49822
+ for (const dir of removed) rmSync6(dir, { recursive: true, force: true });
47593
49823
  const previous = before !== null && existsSync15(join15(agentDir, before)) ? join15(agentDir, before) : null;
47594
49824
  return { current: next, previous, removed };
47595
49825
  }
47596
49826
 
47597
49827
  // src/core/ops/release-fetch.ts
47598
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, renameSync as renameSync5, rmSync as rmSync8 } from "node:fs";
49828
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, rmSync as rmSync7 } from "node:fs";
47599
49829
  import { join as join16 } from "node:path";
47600
49830
  function failed(r) {
47601
49831
  if (r.exitCode === null && r.killed === null) return new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
@@ -47607,11 +49837,11 @@ async function git2(bin, args, cwd, env, signal) {
47607
49837
  if (r.exitCode !== 0 || r.killed !== null) throw failed(r);
47608
49838
  return r.stdout.toString().trim();
47609
49839
  }
47610
- async function fetchRelease(agent, url4, env, signal) {
49840
+ async function fetchRelease(agent, url4, env, signal, opts = {}) {
47611
49841
  const agentDir = join16(resolveConfigDir(env), DATA_PLUGINS_DIR_NAME, agent);
47612
- mkdirSync5(agentDir, { recursive: true });
49842
+ mkdirSync6(agentDir, { recursive: true });
47613
49843
  const fetchDir = join16(agentDir, UPGRADE_FETCH_DIR_PREFIX + process.pid);
47614
- rmSync8(fetchDir, { recursive: true, force: true });
49844
+ rmSync7(fetchDir, { recursive: true, force: true });
47615
49845
  const gitBin = findRuntime(GIT_BIN, env);
47616
49846
  if (gitBin === null) throw new CtxError("FETCH_FAILED", { code: GIT_NOT_STARTED });
47617
49847
  const childEnv = buildChildEnv(env, { ...GIT_NO_PROMPT_ENV, ...GIT_NO_CRLF_ENV });
@@ -47619,26 +49849,21 @@ async function fetchRelease(agent, url4, env, signal) {
47619
49849
  await git2(gitBin, [...GIT_CLONE_ARGS, RELEASE_BRANCH, url4, fetchDir], agentDir, childEnv, signal);
47620
49850
  const sha = await git2(gitBin, GIT_HEAD_SHA_ARGS, fetchDir, childEnv, signal);
47621
49851
  const dir = join16(agentDir, sha);
47622
- if (existsSync16(dir)) rmSync8(fetchDir, { recursive: true, force: true });
47623
- else renameSync5(fetchDir, dir);
49852
+ if (existsSync16(dir)) rmSync7(fetchDir, { recursive: true, force: true });
49853
+ else renameWithRetry(fetchDir, dir, opts);
47624
49854
  return { sha, dir };
47625
49855
  } catch (e) {
47626
- rmSync8(fetchDir, { recursive: true, force: true });
49856
+ rmSync7(fetchDir, { recursive: true, force: true });
47627
49857
  throw e;
47628
49858
  }
47629
49859
  }
47630
49860
 
47631
49861
  // src/core/ops/uninstall.ts
47632
- import { existsSync as existsSync17, readdirSync as readdirSync8, rmSync as rmSync9, writeFileSync as writeFileSync5 } from "node:fs";
49862
+ import { existsSync as existsSync17, readdirSync as readdirSync8, rmSync as rmSync8, writeFileSync as writeFileSync5 } from "node:fs";
47633
49863
  import { join as join17 } from "node:path";
47634
49864
  function row2(area, before, after) {
47635
49865
  return { area, before, after };
47636
49866
  }
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
49867
  function stopServers(configDir, projectKey) {
47643
49868
  const stopped = listLiveOwners(configDir, projectKey);
47644
49869
  const dir = join17(configDir, PROJECTS_DIR_NAME, projectKey, OWNERS_DIR_NAME);
@@ -47659,13 +49884,13 @@ function removeCache(adapter, env, configDir) {
47659
49884
  case "extension": {
47660
49885
  const root = rootOrNull(adapter, env);
47661
49886
  if (root === null) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
47662
- rmSync9(root, { recursive: true, force: true });
49887
+ rmSync8(root, { recursive: true, force: true });
47663
49888
  return row2(UPGRADE_CACHE_AREA, root, UPGRADE_REMOVED);
47664
49889
  }
47665
49890
  case "plugin": {
47666
49891
  const agentDir = join17(configDir, DATA_PLUGINS_DIR_NAME, adapter.id);
47667
49892
  if (!existsSync17(agentDir)) return row2(UPGRADE_CACHE_AREA, "", UPGRADE_NOT_FOUND);
47668
- rmSync9(agentDir, { recursive: true, force: true });
49893
+ rmSync8(agentDir, { recursive: true, force: true });
47669
49894
  return row2(UPGRADE_CACHE_AREA, agentDir, UPGRADE_REMOVED);
47670
49895
  }
47671
49896
  case "config-mcp":
@@ -47684,20 +49909,20 @@ function piSource(entry) {
47684
49909
  return isObj2(entry) ? entry[PI_PACKAGE_SOURCE_KEY] : entry;
47685
49910
  }
47686
49911
  function ownEntries(agent, env) {
47687
- const home = homeOf3(env);
49912
+ const home = requireHomeDir(env);
47688
49913
  const mcp = OWN_MCP_ENTRY[agent];
47689
49914
  if (mcp !== void 0) {
47690
49915
  const top = mcp.key[0];
47691
49916
  const inner = mcp.key.slice(1, -1);
47692
49917
  const own4 = mcp.key[mcp.key.length - 1];
47693
49918
  const holder = (v) => inner.reduce((cur, k) => isObj2(cur) ? cur[k] : void 0, v);
47694
- const without = (v, path4) => {
49919
+ const without = (v, path5) => {
47695
49920
  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)) };
49921
+ if (path5.length === 0) return Object.fromEntries(Object.entries(o).filter(([k]) => k !== own4));
49922
+ return { ...o, [path5[0]]: without(o[path5[0]], path5.slice(1)) };
47698
49923
  };
47699
49924
  return [{
47700
- file: join17(home, ...mcp.file),
49925
+ file: ownMcpFileOf(agent, mcp.file, env, home),
47701
49926
  key: top,
47702
49927
  shown: mcp.key.join(V1_KEY_PATH_SEP),
47703
49928
  has: (v) => {
@@ -47709,7 +49934,8 @@ function ownEntries(agent, env) {
47709
49934
  }
47710
49935
  if (agent === "opencode") {
47711
49936
  return [{
47712
- file: join17(home, ...AGENT_HOME_DIR.opencode, OPENCODE_BASE_CONFIG_FILE),
49937
+ file: join17(opencodeDirOf(env, home), OPENCODE_BASE_CONFIG_FILE),
49938
+ // D-WIN-OPENCODE-DIR-1
47713
49939
  key: OPENCODE_PLUGIN_KEY,
47714
49940
  shown: OPENCODE_PLUGIN_KEY,
47715
49941
  has: (v) => Array.isArray(v) && v.includes(OPENCODE_GIT_SPEC),
@@ -47717,7 +49943,7 @@ function ownEntries(agent, env) {
47717
49943
  }];
47718
49944
  }
47719
49945
  if (agent === "pi") {
47720
- const agentDir = env[PI_AGENT_DIR_ENV] ?? join17(home, ...AGENT_HOME_DIR.pi, PI_AGENT_DIR);
49946
+ const agentDir = piAgentDirOf(env, home);
47721
49947
  return [{
47722
49948
  file: join17(agentDir, SETTINGS_FILE),
47723
49949
  key: PI_PACKAGES_KEY,
@@ -47746,7 +49972,7 @@ function removeProjectData(configDir, projectKey) {
47746
49972
  if (!existsSync17(dir)) return row2(UPGRADE_DATA_AREA, "", UPGRADE_NOT_FOUND);
47747
49973
  if (dir === projects || !isInside(projects, dir)) throw new CtxError("OUTSIDE_ROOT", { p: dir, root: projects });
47748
49974
  for (const name of readdirSync8(dir)) {
47749
- if (name !== OWNERS_DIR_NAME) rmSync9(join17(dir, name), { recursive: true, force: true });
49975
+ if (name !== OWNERS_DIR_NAME) rmSync8(join17(dir, name), { recursive: true, force: true });
47750
49976
  }
47751
49977
  return row2(UPGRADE_DATA_AREA, dir, UPGRADE_DATA_DELETED);
47752
49978
  }
@@ -47759,52 +49985,52 @@ function runUninstall(input) {
47759
49985
  }
47760
49986
 
47761
49987
  // 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";
49988
+ import { copyFileSync as copyFileSync2, existsSync as existsSync18, readFileSync as readFileSync10, rmSync as rmSync9 } from "node:fs";
47763
49989
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
47764
49990
  var areaOf = (f) => f.path === "" ? f.file : f.file + UPGRADE_AREA_KEY_SEP + f.path;
47765
49991
  var row3 = (f, after) => ({ area: areaOf(f), before: f.reason, after });
47766
49992
  function moveAside(target, undo) {
47767
49993
  const trash = target + UPGRADE_TRASH_SUFFIX;
47768
- rmSync10(trash, { recursive: true, force: true });
47769
- renameSync6(target, trash);
49994
+ rmSync9(trash, { recursive: true, force: true });
49995
+ renameWithRetry(target, trash);
47770
49996
  undo.push({ trash, target });
47771
49997
  }
47772
49998
  function keepOriginal(file2, kept, undo) {
47773
49999
  if (kept.has(file2)) return;
47774
50000
  const trash = file2 + UPGRADE_TRASH_SUFFIX;
47775
- rmSync10(trash, { recursive: true, force: true });
50001
+ rmSync9(trash, { recursive: true, force: true });
47776
50002
  copyFileSync2(file2, trash);
47777
50003
  kept.add(file2);
47778
50004
  undo.push({ trash, target: file2 });
47779
50005
  }
47780
50006
  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");
50007
+ let span;
50008
+ try {
50009
+ span = tomlTableSpans(text).find((t) => t.header.trim() === header);
50010
+ } catch {
50011
+ return null;
50012
+ }
50013
+ return span === void 0 ? null : text.slice(0, span.start) + text.slice(span.end);
47787
50014
  }
47788
50015
  function writeAtomic(file2, text) {
47789
- const tmp = file2 + HOST_CONFIG_TMP_SUFFIX;
47790
- writeFileSync6(tmp, text, "utf8");
47791
- renameSync6(tmp, file2);
50016
+ atomicWriteFile(file2, text);
47792
50017
  }
47793
- function locate(doc, path4) {
47794
- const segs = path4.split(V1_KEY_PATH_SEP);
50018
+ function locate(doc, path5) {
50019
+ const segs = path5.split(V1_KEY_PATH_SEP);
47795
50020
  let cur = doc;
47796
50021
  for (const seg of segs.slice(0, -1)) {
47797
50022
  if (Array.isArray(cur)) cur = cur[Number(seg)];
47798
50023
  else if (isObj3(cur)) cur = cur[seg];
47799
50024
  else return null;
47800
50025
  }
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;
50026
+ const last2 = segs[segs.length - 1];
50027
+ if (Array.isArray(cur)) return Number(last2) < cur.length ? [cur, last2] : null;
50028
+ if (isObj3(cur)) return Object.hasOwn(cur, last2) ? [cur, last2] : null;
47804
50029
  return null;
47805
50030
  }
47806
50031
  function stripJsonEntries(agent, file2, findings, kept, undo) {
47807
- const text = readFileSync10(file2, "utf8");
50032
+ const layout = hostLayout(readFileSync10(file2, "utf8"));
50033
+ const text = hostText(readFileSync10(file2, "utf8"));
47808
50034
  const doc = parseHostConfig(agent, file2, text, "jsonc");
47809
50035
  const hit = /* @__PURE__ */ new Set();
47810
50036
  const byContainer = /* @__PURE__ */ new Map();
@@ -47829,7 +50055,7 @@ function stripJsonEntries(agent, file2, findings, kept, undo) {
47829
50055
  const patch = {};
47830
50056
  for (const k of topKeys) patch[k] = doc[k];
47831
50057
  keepOriginal(file2, kept, undo);
47832
- writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2 }, patch);
50058
+ writeHostConfigEdit(file2, { agent, text, format: "jsonc", path: file2, layout }, patch);
47833
50059
  return hit;
47834
50060
  }
47835
50061
  function removeV1(agent, findings) {
@@ -47852,7 +50078,9 @@ function removeV1(agent, findings) {
47852
50078
  continue;
47853
50079
  }
47854
50080
  if (file2.endsWith(TOML_EXT)) {
47855
- let text = readFileSync10(file2, "utf8");
50081
+ const rawToml = readFileSync10(file2, "utf8");
50082
+ const tomlLayout = hostLayout(rawToml);
50083
+ let text = hostText(rawToml);
47856
50084
  for (const f of list2) {
47857
50085
  const next = cutTomlTable(text, f.path);
47858
50086
  if (next === null) {
@@ -47864,7 +50092,7 @@ function removeV1(agent, findings) {
47864
50092
  }
47865
50093
  if (list2.some((f) => done.get(f) === UPGRADE_REMOVED)) {
47866
50094
  keepOriginal(file2, kept, undo);
47867
- writeAtomic(file2, text);
50095
+ writeAtomic(file2, withLayout(text, tomlLayout));
47868
50096
  }
47869
50097
  continue;
47870
50098
  }
@@ -47874,13 +50102,13 @@ function removeV1(agent, findings) {
47874
50102
  return {
47875
50103
  rows: findings.map((f) => row3(f, done.get(f) ?? UPGRADE_NOT_FOUND)),
47876
50104
  commit() {
47877
- for (const u of undo.splice(0)) rmSync10(u.trash, { recursive: true, force: true });
50105
+ for (const u of undo.splice(0)) rmSync9(u.trash, { recursive: true, force: true });
47878
50106
  },
47879
50107
  rollback() {
47880
50108
  for (const u of undo.splice(0).reverse()) {
47881
50109
  if (!existsSync18(u.trash)) continue;
47882
- rmSync10(u.target, { recursive: true, force: true });
47883
- renameSync6(u.trash, u.target);
50110
+ rmSync9(u.target, { recursive: true, force: true });
50111
+ renameWithRetry(u.trash, u.target);
47884
50112
  }
47885
50113
  }
47886
50114
  };
@@ -47940,11 +50168,6 @@ var ctxUpgradeSchema = external_exports.object({
47940
50168
  function row4(area, before, after) {
47941
50169
  return { area, before, after };
47942
50170
  }
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
50171
  function bundleDir() {
47949
50172
  return dirname9(process.argv[1] ?? "");
47950
50173
  }
@@ -47969,7 +50192,7 @@ async function checkout(adapter, deps) {
47969
50192
  try {
47970
50193
  verifySums(fetched.dir);
47971
50194
  } catch (err) {
47972
- if (!isCurrent(agentDir, fetched.dir)) rmSync11(fetched.dir, { recursive: true, force: true });
50195
+ if (!isCurrent(agentDir, fetched.dir)) rmSync10(fetched.dir, { recursive: true, force: true });
47973
50196
  throw err;
47974
50197
  }
47975
50198
  const swap = swapPluginCurrent(agentDir, fetched.sha);
@@ -47986,7 +50209,7 @@ async function upgrade(adapter, deps, home) {
47986
50209
  try {
47987
50210
  const step4 = UPGRADE_GIT_CHECKOUT_AGENTS.includes(adapter.id) ? (done = await checkout(adapter, deps)).rows : [hostRow(adapter)];
47988
50211
  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] });
50212
+ 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
50213
  removal = removeV1(adapter.id, findings);
47991
50214
  const rows = [...step4, ...step5, ...removal.rows];
47992
50215
  removal.commit();
@@ -48007,7 +50230,7 @@ function renderTable(rows) {
48007
50230
  }
48008
50231
  async function runUpgrade(input, deps) {
48009
50232
  const adapter = getAdapter(deps.project.agent);
48010
- const home = homeOf4(deps.env);
50233
+ const home = requireHomeDir(deps.env);
48011
50234
  const rows = pluginRootRow(adapter, deps.env);
48012
50235
  if ((input.mode ?? UPGRADE_DEFAULT_MODE) === "uninstall") {
48013
50236
  const result = runUninstall({ adapter, project: deps.project, env: deps.env, confirmDelete: input.confirmDelete === true });
@@ -48235,7 +50458,7 @@ async function startServer(argv, env) {
48235
50458
  try {
48236
50459
  const configDir = resolveConfigDir(process.env);
48237
50460
  removeOwnerPid(configDir, db.projectKey, serverId);
48238
- rmSync12(stopMarker(configDir, db.projectKey), { force: true });
50461
+ rmSync11(stopMarker(configDir, db.projectKey), { force: true });
48239
50462
  } catch (err) {
48240
50463
  console.error(err);
48241
50464
  }