jinzd-ai-cli 0.4.257 → 0.4.259

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.
Files changed (33) hide show
  1. package/dist/{batch-HCTZJMGR.js → batch-74P2FQWX.js} +2 -2
  2. package/dist/{chunk-GOGDUA4G.js → chunk-3EWST6SE.js} +4 -4
  3. package/dist/{chunk-X2ZXQMN2.js → chunk-3KYUE2MD.js} +1 -1
  4. package/dist/{chunk-QI4AJPRD.js → chunk-4RPJQJBI.js} +69 -49
  5. package/dist/{chunk-5DLLJ67Q.js → chunk-4TDVLTX2.js} +1 -1
  6. package/dist/{chunk-NX55D52V.js → chunk-7DVIAK6J.js} +2 -2
  7. package/dist/{chunk-BQXVQKMH.js → chunk-BWJYDG3C.js} +1 -1
  8. package/dist/{chunk-QEVXWHWN.js → chunk-DLOOIAAD.js} +1 -1
  9. package/dist/{chunk-4VWME5CO.js → chunk-FGONEVTP.js} +1 -1
  10. package/dist/{chunk-DFV7F6S7.js → chunk-G65I4DXP.js} +1 -1
  11. package/dist/{chunk-MJ6JLSPR.js → chunk-GDJII6TK.js} +6 -2
  12. package/dist/{chunk-NRTYNGEZ.js → chunk-KXAVUZKH.js} +1 -1
  13. package/dist/{chunk-HPPK4IA3.js → chunk-PSH5O44I.js} +1 -1
  14. package/dist/{chunk-DGMSS565.js → chunk-V5FB72RK.js} +1 -1
  15. package/dist/{chunk-HOS7CGBI.js → chunk-XPNKMDBH.js} +10 -4
  16. package/dist/{chunk-ELYDRIKV.js → chunk-ZZ5WTHKY.js} +4 -4
  17. package/dist/{ci-OGJDKUEN.js → ci-6BANR65W.js} +6 -6
  18. package/dist/{ci-format-CG6US3KX.js → ci-format-2OVEQK6O.js} +2 -2
  19. package/dist/{constants-3UC2F5GC.js → constants-DKZEF3CE.js} +1 -1
  20. package/dist/{doctor-cli-FPYSCH5H.js → doctor-cli-6MHA7Q7M.js} +6 -6
  21. package/dist/electron-server.js +132 -104
  22. package/dist/{hub-5NRTE7PL.js → hub-L7RSDS4J.js} +1 -1
  23. package/dist/index.js +21 -21
  24. package/dist/{persistent-memory-PNJCHP33.js → persistent-memory-I4JV3CME.js} +2 -2
  25. package/dist/{persistent-memory-CHPNGWN2.js → persistent-memory-WBR2DALU.js} +2 -2
  26. package/dist/{pr-KAEI2IK3.js → pr-UNCWDVN3.js} +6 -6
  27. package/dist/{run-tests-F7Y6POVK.js → run-tests-HFT5RUXF.js} +2 -2
  28. package/dist/{run-tests-EOHLRWQC.js → run-tests-XBODGDFO.js} +2 -2
  29. package/dist/{server-REZPCUHW.js → server-ILKG2672.js} +19 -19
  30. package/dist/{server-4NP2ZVLA.js → server-RNBKZ6TP.js} +6 -6
  31. package/dist/{task-orchestrator-LTPRJVLH.js → task-orchestrator-GXP5HNBZ.js} +6 -6
  32. package/dist/{usage-XPBLQ4FZ.js → usage-KCPH75KI.js} +2 -2
  33. package/package.json +1 -1
@@ -34,14 +34,14 @@ import {
34
34
  touchMemoryReferences,
35
35
  updateMemoryApproval,
36
36
  updateMemoryEntry
37
- } from "./chunk-NRTYNGEZ.js";
37
+ } from "./chunk-KXAVUZKH.js";
38
38
  import {
39
39
  redactJson,
40
40
  scanString
41
41
  } from "./chunk-YVTASHS5.js";
42
42
  import {
43
43
  runTestsTool
44
- } from "./chunk-DGMSS565.js";
44
+ } from "./chunk-V5FB72RK.js";
45
45
  import {
46
46
  AGENTIC_BEHAVIOR_GUIDELINE,
47
47
  APP_NAME,
@@ -73,7 +73,7 @@ import {
73
73
  SUBAGENT_MAX_ROUNDS_LIMIT,
74
74
  VERSION,
75
75
  buildUserIdentityPrompt
76
- } from "./chunk-QEVXWHWN.js";
76
+ } from "./chunk-DLOOIAAD.js";
77
77
  import {
78
78
  hasSemanticIndex,
79
79
  semanticSearch
@@ -92,7 +92,7 @@ import express from "express";
92
92
  import { createServer } from "http";
93
93
  import { WebSocketServer } from "ws";
94
94
  import { join as join25, dirname as dirname10, resolve as resolve10, relative as relative6, sep as sep4 } from "path";
95
- import { existsSync as existsSync30, readFileSync as readFileSync23, readdirSync as readdirSync15, statSync as statSync13, realpathSync as realpathSync3 } from "fs";
95
+ import { existsSync as existsSync30, readFileSync as readFileSync24, readdirSync as readdirSync15, statSync as statSync14, realpathSync as realpathSync3 } from "fs";
96
96
  import { networkInterfaces } from "os";
97
97
 
98
98
  // src/config/config-manager.ts
@@ -2323,7 +2323,7 @@ function parseToolCallArguments(raw, onWarn) {
2323
2323
  onWarn?.("Tool call JSON was truncated and auto-repaired. Some parameters may be missing.");
2324
2324
  return { args: repaired, status: "repaired" };
2325
2325
  } catch {
2326
- onWarn?.("Tool call JSON could not be parsed, using empty arguments.");
2326
+ onWarn?.("Tool call JSON could not be parsed (output was truncated) \u2014 the call will be rejected.");
2327
2327
  return { args: {}, status: "failed" };
2328
2328
  }
2329
2329
  }
@@ -2372,13 +2372,18 @@ async function consumeToolCallStream(stream, hooks = {}) {
2372
2372
  accumulators.set(event.index, { id: event.id, name: event.name, arguments: "" });
2373
2373
  hooks.onToolCallStart?.(event.index, event.id, event.name);
2374
2374
  break;
2375
+ case "tool_call_end": {
2376
+ if (event.argumentsTruncated) {
2377
+ const acc = accumulators.get(event.index);
2378
+ if (acc) acc.truncatedUpstream = event.argumentsTruncated;
2379
+ }
2380
+ break;
2381
+ }
2375
2382
  case "tool_call_delta": {
2376
2383
  const acc = accumulators.get(event.index);
2377
2384
  if (acc) acc.arguments += event.argumentsDelta;
2378
2385
  break;
2379
2386
  }
2380
- case "tool_call_end":
2381
- break;
2382
2387
  case "done":
2383
2388
  if (event.usage) usage = event.usage;
2384
2389
  if (event.rawContent) rawContent = event.rawContent;
@@ -2406,11 +2411,12 @@ async function consumeToolCallStream(stream, hooks = {}) {
2406
2411
  const toolCalls = [];
2407
2412
  for (const [, acc] of accumulators) {
2408
2413
  const parsed = parseToolCallArguments(acc.arguments, hooks.onWarn);
2414
+ const truncated = acc.truncatedUpstream ?? (parsed.status === "ok" ? void 0 : parsed.status);
2409
2415
  toolCalls.push({
2410
2416
  id: acc.id,
2411
2417
  name: acc.name,
2412
2418
  arguments: parsed.args,
2413
- ...parsed.status === "ok" ? {} : { argumentsTruncated: parsed.status }
2419
+ ...truncated ? { argumentsTruncated: truncated } : {}
2414
2420
  });
2415
2421
  }
2416
2422
  if (toolCalls.length > 0) {
@@ -3075,7 +3081,11 @@ var OpenAICompatibleProvider = class extends BaseProvider {
3075
3081
  const tc = result.toolCalls[i];
3076
3082
  yield { type: "tool_call_start", index: i, id: tc.id, name: tc.name };
3077
3083
  yield { type: "tool_call_delta", index: i, argumentsDelta: JSON.stringify(tc.arguments) };
3078
- yield { type: "tool_call_end", index: i };
3084
+ yield {
3085
+ type: "tool_call_end",
3086
+ index: i,
3087
+ ...tc.argumentsTruncated ? { argumentsTruncated: tc.argumentsTruncated } : {}
3088
+ };
3079
3089
  }
3080
3090
  } else {
3081
3091
  yield { type: "text_delta", delta: result.content };
@@ -6088,7 +6098,7 @@ ${content}`;
6088
6098
  };
6089
6099
 
6090
6100
  // src/tools/builtin/write-file.ts
6091
- import { appendFileSync, mkdirSync as mkdirSync6 } from "fs";
6101
+ import { appendFileSync, mkdirSync as mkdirSync6, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
6092
6102
  import { dirname as dirname5 } from "path";
6093
6103
 
6094
6104
  // src/tools/executor.ts
@@ -6146,6 +6156,37 @@ async function runSafePhases(phase, execute, results, logTag = "executor") {
6146
6156
  return Date.now() - t0;
6147
6157
  }
6148
6158
 
6159
+ // src/tools/arg-aliases.ts
6160
+ function pickArg(args, canonical, aliases) {
6161
+ if (args[canonical] !== void 0 && args[canonical] !== null) return args[canonical];
6162
+ for (const alias of aliases) {
6163
+ if (args[alias] !== void 0 && args[alias] !== null) return args[alias];
6164
+ }
6165
+ return void 0;
6166
+ }
6167
+ var OLD_STR_ALIASES = ["old_string", "oldStr", "oldString", "old_text", "search"];
6168
+ var NEW_STR_ALIASES = ["new_string", "newStr", "newString", "new_text", "replace"];
6169
+ var CONTENT_ALIASES = ["file_text", "text", "contents", "data"];
6170
+ var INSERT_LINE_ALIASES = ["insert_line", "line", "after_line"];
6171
+ var INSERT_CONTENT_ALIASES = ["content", "new_str", "text"];
6172
+ function normalizeReplaceArgs(raw) {
6173
+ const oldStr = pickArg(raw, "old_str", OLD_STR_ALIASES);
6174
+ if (oldStr === void 0) return void 0;
6175
+ return { old_str: oldStr, new_str: pickArg(raw, "new_str", NEW_STR_ALIASES) };
6176
+ }
6177
+ function resolveWriteFileArgs(args) {
6178
+ return {
6179
+ path: String(pickArg(args, "path", ["file"]) ?? ""),
6180
+ content: String(pickArg(args, "content", CONTENT_ALIASES) ?? ""),
6181
+ append: String(args["append"] ?? "false").toLowerCase() === "true"
6182
+ };
6183
+ }
6184
+ function describeReceivedKeys(args) {
6185
+ const keys = Object.keys(args).filter((k) => args[k] !== void 0);
6186
+ if (keys.length === 0) return " (no arguments received)";
6187
+ return ` Received keys: ${keys.join(", ")}.`;
6188
+ }
6189
+
6149
6190
  // src/tools/diff-utils.ts
6150
6191
  import chalk from "chalk";
6151
6192
  function renderDiff(oldText, newText, opts = {}) {
@@ -7614,8 +7655,7 @@ var ToolExecutor = class {
7614
7655
  */
7615
7656
  printDiffPreview(call) {
7616
7657
  if (call.name === "write_file") {
7617
- const filePath = String(call.arguments["path"] ?? "");
7618
- const newContent = String(call.arguments["content"] ?? "");
7658
+ const { path: filePath, content: chunk, append } = resolveWriteFileArgs(call.arguments);
7619
7659
  if (!filePath) return;
7620
7660
  if (existsSync11(filePath)) {
7621
7661
  let oldContent;
@@ -7624,16 +7664,17 @@ var ToolExecutor = class {
7624
7664
  } catch {
7625
7665
  return;
7626
7666
  }
7667
+ const newContent = append ? oldContent + chunk : chunk;
7627
7668
  if (oldContent === newContent) {
7628
7669
  console.log(theme.dim(" (file content unchanged)"));
7629
7670
  return;
7630
7671
  }
7631
7672
  const diff = renderDiff(oldContent, newContent, { filePath, contextLines: 3 });
7632
- console.log(theme.dim(" \u2500\u2500 diff preview \u2500\u2500"));
7673
+ console.log(theme.dim(append ? " \u2500\u2500 append preview \u2500\u2500" : " \u2500\u2500 diff preview \u2500\u2500"));
7633
7674
  console.log(diff);
7634
7675
  console.log();
7635
7676
  } else {
7636
- const lines = newContent.split("\n");
7677
+ const lines = chunk.split("\n");
7637
7678
  const preview = lines.slice(0, 20).map((l) => theme.success(`+ ${l}`)).join("\n");
7638
7679
  const more = lines.length > 20 ? theme.dim(`
7639
7680
  ... (+${lines.length - 20} more lines)`) : "";
@@ -7854,31 +7895,10 @@ var subAgentGuard = {
7854
7895
  active: false
7855
7896
  };
7856
7897
 
7857
- // src/tools/arg-aliases.ts
7858
- function pickArg(args, canonical, aliases) {
7859
- if (args[canonical] !== void 0 && args[canonical] !== null) return args[canonical];
7860
- for (const alias of aliases) {
7861
- if (args[alias] !== void 0 && args[alias] !== null) return args[alias];
7862
- }
7863
- return void 0;
7864
- }
7865
- var OLD_STR_ALIASES = ["old_string", "oldStr", "oldString", "old_text", "search"];
7866
- var NEW_STR_ALIASES = ["new_string", "newStr", "newString", "new_text", "replace"];
7867
- var CONTENT_ALIASES = ["file_text", "text", "contents", "data"];
7868
- var INSERT_LINE_ALIASES = ["insert_line", "line", "after_line"];
7869
- var INSERT_CONTENT_ALIASES = ["content", "new_str", "text"];
7870
- function normalizeReplaceArgs(raw) {
7871
- const oldStr = pickArg(raw, "old_str", OLD_STR_ALIASES);
7872
- if (oldStr === void 0) return void 0;
7873
- return { old_str: oldStr, new_str: pickArg(raw, "new_str", NEW_STR_ALIASES) };
7874
- }
7875
- function describeReceivedKeys(args) {
7876
- const keys = Object.keys(args).filter((k) => args[k] !== void 0);
7877
- if (keys.length === 0) return " (no arguments received)";
7878
- return ` Received keys: ${keys.join(", ")}.`;
7879
- }
7880
-
7881
7898
  // src/tools/builtin/write-file.ts
7899
+ function countFileLines(filePath) {
7900
+ return readFileSync10(filePath, "utf-8").split("\n").length;
7901
+ }
7882
7902
  var writeFileTool = {
7883
7903
  definition: {
7884
7904
  name: "write_file",
@@ -7946,12 +7966,21 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
7946
7966
  } catch {
7947
7967
  }
7948
7968
  })();
7969
+ if (appendMode) {
7970
+ let total = "";
7971
+ try {
7972
+ const st = statSync4(filePath);
7973
+ total = `; file now ${countFileLines(filePath)} lines, ${st.size} bytes`;
7974
+ } catch {
7975
+ }
7976
+ return `File appended: ${filePath} (+${lines} lines, +${bytes} bytes${total})`;
7977
+ }
7949
7978
  return `File ${mode}: ${filePath} (${lines} lines, ${bytes} bytes)`;
7950
7979
  }
7951
7980
  };
7952
7981
 
7953
7982
  // src/tools/builtin/edit-file.ts
7954
- import { readFileSync as readFileSync10, existsSync as existsSync12 } from "fs";
7983
+ import { readFileSync as readFileSync11, existsSync as existsSync12 } from "fs";
7955
7984
 
7956
7985
  // src/tools/builtin/patch-apply.ts
7957
7986
  function parseUnifiedDiff(patch) {
@@ -8327,7 +8356,7 @@ Note: Path can be absolute or relative to cwd.`,
8327
8356
  `Refused: sub-agents cannot edit sensitive paths \u2014 ${verdict.reason}. If this is genuinely needed, ask the parent agent to perform the edit so the user can approve it.`
8328
8357
  );
8329
8358
  }
8330
- const original = readFileSync10(filePath, encoding);
8359
+ const original = readFileSync11(filePath, encoding);
8331
8360
  if (args["patch"] !== void 0) {
8332
8361
  const patchText = String(args["patch"] ?? "");
8333
8362
  const stopOnError = args["stop_on_error"] !== false;
@@ -8496,7 +8525,7 @@ function truncatePreview(str, maxLen = 80) {
8496
8525
  }
8497
8526
 
8498
8527
  // src/tools/builtin/list-dir.ts
8499
- import { readdirSync as readdirSync4, statSync as statSync4, existsSync as existsSync13 } from "fs";
8528
+ import { readdirSync as readdirSync4, statSync as statSync5, existsSync as existsSync13 } from "fs";
8500
8529
  import { join as join7, basename as basename4 } from "path";
8501
8530
  var listDirTool = {
8502
8531
  definition: {
@@ -8581,7 +8610,7 @@ function listRecursive(basePath, indent, recursive, lines) {
8581
8610
  }
8582
8611
  } else {
8583
8612
  try {
8584
- const stat = statSync4(join7(basePath, entry.name));
8613
+ const stat = statSync5(join7(basePath, entry.name));
8585
8614
  const size = formatSize(stat.size);
8586
8615
  lines.push(`${indent}\u{1F4C4} ${entry.name} (${size})`);
8587
8616
  } catch {
@@ -8597,7 +8626,7 @@ function formatSize(bytes) {
8597
8626
  }
8598
8627
 
8599
8628
  // src/tools/builtin/grep-files.ts
8600
- import { readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync5, existsSync as existsSync14 } from "fs";
8629
+ import { readdirSync as readdirSync5, readFileSync as readFileSync12, statSync as statSync6, existsSync as existsSync14 } from "fs";
8601
8630
  import { readFile } from "fs/promises";
8602
8631
  import { join as join8, relative } from "path";
8603
8632
  var grepFilesTool = {
@@ -8663,7 +8692,7 @@ Supports regex. Automatically skips node_modules, dist, .git directories.`,
8663
8692
  regex = new RegExp(escaped, ignoreCase ? "gi" : "g");
8664
8693
  }
8665
8694
  const results = [];
8666
- const stat = statSync5(rootPath);
8695
+ const stat = statSync6(rootPath);
8667
8696
  if (stat.isFile()) {
8668
8697
  searchInFile(rootPath, rootPath, regex, contextLines, maxResults, results);
8669
8698
  } else {
@@ -8750,7 +8779,7 @@ function collectFilePaths(rootPath, filePattern, maxFiles) {
8750
8779
  if (filePattern && !matchesFilePattern(entry.name, filePattern)) continue;
8751
8780
  const fullPath = join8(dirPath, entry.name);
8752
8781
  try {
8753
- if (statSync5(fullPath).size > 1e6) continue;
8782
+ if (statSync6(fullPath).size > 1e6) continue;
8754
8783
  } catch {
8755
8784
  continue;
8756
8785
  }
@@ -8796,14 +8825,14 @@ async function searchInFileAsync(fullPath, displayPath2, regex, contextLines, ma
8796
8825
  }
8797
8826
  function searchInFile(fullPath, displayPath2, regex, contextLines, maxResults, results) {
8798
8827
  try {
8799
- const stat = statSync5(fullPath);
8828
+ const stat = statSync6(fullPath);
8800
8829
  if (stat.size > 1e6) return;
8801
8830
  } catch {
8802
8831
  return;
8803
8832
  }
8804
8833
  let content;
8805
8834
  try {
8806
- content = readFileSync11(fullPath, "utf-8");
8835
+ content = readFileSync12(fullPath, "utf-8");
8807
8836
  } catch {
8808
8837
  return;
8809
8838
  }
@@ -8834,7 +8863,7 @@ function searchInFile(fullPath, displayPath2, regex, contextLines, maxResults, r
8834
8863
  }
8835
8864
 
8836
8865
  // src/tools/builtin/glob-files.ts
8837
- import { readdirSync as readdirSync6, statSync as statSync6, existsSync as existsSync15 } from "fs";
8866
+ import { readdirSync as readdirSync6, statSync as statSync7, existsSync as existsSync15 } from "fs";
8838
8867
  import { join as join9, relative as relative2, basename as basename5 } from "path";
8839
8868
  var globFilesTool = {
8840
8869
  definition: {
@@ -8953,7 +8982,7 @@ function collectMatchingFiles(dirPath, rootPath, regex, results, maxResults) {
8953
8982
  const relPath = relative2(rootPath, fullPath).replace(/\\/g, "/");
8954
8983
  if (regex.test(relPath) || regex.test(basename5(relPath))) {
8955
8984
  try {
8956
- const stat = statSync6(fullPath);
8985
+ const stat = statSync7(fullPath);
8957
8986
  results.push({ relPath, absPath: fullPath, mtime: stat.mtimeMs });
8958
8987
  } catch {
8959
8988
  results.push({ relPath, absPath: fullPath, mtime: 0 });
@@ -10139,12 +10168,12 @@ function formatResults2(query, data, _requested) {
10139
10168
  }
10140
10169
 
10141
10170
  // src/agents/agent-config.ts
10142
- import { existsSync as existsSync17, readdirSync as readdirSync8, readFileSync as readFileSync13 } from "fs";
10171
+ import { existsSync as existsSync17, readdirSync as readdirSync8, readFileSync as readFileSync14 } from "fs";
10143
10172
  import { join as join12 } from "path";
10144
10173
  import { homedir as homedir6 } from "os";
10145
10174
 
10146
10175
  // src/plugins/plugin-manager.ts
10147
- import { existsSync as existsSync16, mkdirSync as mkdirSync8, readdirSync as readdirSync7, readFileSync as readFileSync12, realpathSync as realpathSync2, cpSync, rmSync, statSync as statSync7 } from "fs";
10176
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, readdirSync as readdirSync7, readFileSync as readFileSync13, realpathSync as realpathSync2, cpSync, rmSync, statSync as statSync8 } from "fs";
10148
10177
  import { basename as basename6, dirname as dirname7, join as join11, relative as relative3, resolve as resolve6, sep as sep3 } from "path";
10149
10178
  import { createHash as createHash2 } from "crypto";
10150
10179
  import { z as z2 } from "zod";
@@ -10217,7 +10246,7 @@ function loadState(configDir) {
10217
10246
  const file = statePath(configDir);
10218
10247
  if (!existsSync16(file)) return { version: 2, plugins: [] };
10219
10248
  try {
10220
- const parsed = JSON.parse(readFileSync12(file, "utf-8"));
10249
+ const parsed = JSON.parse(readFileSync13(file, "utf-8"));
10221
10250
  const rawPlugins = Array.isArray(parsed.plugins) ? parsed.plugins : [];
10222
10251
  return { version: 2, plugins: rawPlugins.map((p) => migrateEntry(p)) };
10223
10252
  } catch {
@@ -10308,7 +10337,7 @@ function hashPluginContent(pluginDir, manifest) {
10308
10337
  const sorted = [...assetRels].sort();
10309
10338
  const hasher = createHash2("sha256");
10310
10339
  const manifestPath = join11(resolvedDir, MANIFEST_RELATIVE);
10311
- hasher.update(normalizeForHash(readFileSync12(manifestPath)));
10340
+ hasher.update(normalizeForHash(readFileSync13(manifestPath)));
10312
10341
  for (const rel of sorted) {
10313
10342
  const abs = resolve6(resolvedDir, rel);
10314
10343
  if (!abs.startsWith(resolvedDir + sep3)) {
@@ -10321,14 +10350,14 @@ function hashPluginContent(pluginDir, manifest) {
10321
10350
  continue;
10322
10351
  }
10323
10352
  try {
10324
- if (statSync7(realPath).isDirectory()) continue;
10353
+ if (statSync8(realPath).isDirectory()) continue;
10325
10354
  } catch {
10326
10355
  continue;
10327
10356
  }
10328
10357
  if (!realPath.startsWith(resolvedDir + sep3)) {
10329
10358
  throw new Error(`plugin asset symlink escapes plugin dir: ${rel} \u2192 ${realPath}`);
10330
10359
  }
10331
- hasher.update(normalizeForHash(readFileSync12(abs)));
10360
+ hasher.update(normalizeForHash(readFileSync13(abs)));
10332
10361
  }
10333
10362
  return hasher.digest("hex");
10334
10363
  }
@@ -10336,11 +10365,11 @@ function effectiveHash(entry) {
10336
10365
  return entry.contentHash ?? entry.hash ?? "";
10337
10366
  }
10338
10367
  function readPluginManifest(manifestPath) {
10339
- return PluginManifestSchema.parse(JSON.parse(readFileSync12(manifestPath, "utf-8")));
10368
+ return PluginManifestSchema.parse(JSON.parse(readFileSync13(manifestPath, "utf-8")));
10340
10369
  }
10341
10370
  function findPluginSourceDir(inputPath) {
10342
10371
  const abs = resolve6(inputPath);
10343
- const direct = statSync7(abs).isDirectory() ? abs : dirname7(abs);
10372
+ const direct = statSync8(abs).isDirectory() ? abs : dirname7(abs);
10344
10373
  if (existsSync16(pluginManifestPath(direct))) return direct;
10345
10374
  const nested = join11(direct, ".aicli-plugin");
10346
10375
  if (existsSync16(join11(nested, "plugin.json"))) return direct;
@@ -10415,7 +10444,7 @@ function listInstalledPlugins(configDir) {
10415
10444
  for (const entry of readdirSync7(root)) {
10416
10445
  const dir = join11(root, entry);
10417
10446
  try {
10418
- if (!statSync7(dir).isDirectory()) continue;
10447
+ if (!statSync8(dir).isDirectory()) continue;
10419
10448
  } catch {
10420
10449
  continue;
10421
10450
  }
@@ -10460,7 +10489,7 @@ function uniqueDirs(plugin, rels) {
10460
10489
  for (const rel of rels) {
10461
10490
  const abs = resolve6(plugin.dir, rel);
10462
10491
  if (!abs.startsWith(resolve6(plugin.dir))) continue;
10463
- if (existsSync16(abs)) dirs.add(statSync7(abs).isDirectory() ? abs : dirname7(abs));
10492
+ if (existsSync16(abs)) dirs.add(statSync8(abs).isDirectory() ? abs : dirname7(abs));
10464
10493
  }
10465
10494
  return [...dirs];
10466
10495
  }
@@ -10629,7 +10658,7 @@ function loadAgentDir(dir, source) {
10629
10658
  if (!file.endsWith(".json")) continue;
10630
10659
  const path3 = join12(dir, file);
10631
10660
  try {
10632
- const parsed = JSON.parse(readFileSync13(path3, "utf-8"));
10661
+ const parsed = JSON.parse(readFileSync14(path3, "utf-8"));
10633
10662
  const cfg = parseAgentConfig(parsed, source, path3);
10634
10663
  if (cfg) out.push(cfg);
10635
10664
  } catch {
@@ -11629,7 +11658,7 @@ ${commitOutput.trim()}`;
11629
11658
  };
11630
11659
 
11631
11660
  // src/tools/builtin/notebook-edit.ts
11632
- import { readFileSync as readFileSync14, existsSync as existsSync19 } from "fs";
11661
+ import { readFileSync as readFileSync15, existsSync as existsSync19 } from "fs";
11633
11662
  import { writeFile } from "fs/promises";
11634
11663
  import { resolve as resolve7, extname as extname2 } from "path";
11635
11664
  var notebookEditTool = {
@@ -11687,7 +11716,7 @@ var notebookEditTool = {
11687
11716
  if (!existsSync19(absPath)) {
11688
11717
  throw new ToolError("notebook_edit", `Notebook not found: ${filePath}`);
11689
11718
  }
11690
- const raw = readFileSync14(absPath, "utf-8");
11719
+ const raw = readFileSync15(absPath, "utf-8");
11691
11720
  const nb = parseNotebook(raw);
11692
11721
  const cellIdx0 = cellIndexRaw - 1;
11693
11722
  undoStack.push(absPath, `notebook_edit (${action}): ${filePath}`);
@@ -12856,11 +12885,11 @@ var McpManager = class {
12856
12885
  };
12857
12886
 
12858
12887
  // src/skills/manager.ts
12859
- import { existsSync as existsSync21, readdirSync as readdirSync10, mkdirSync as mkdirSync10, statSync as statSync8 } from "fs";
12888
+ import { existsSync as existsSync21, readdirSync as readdirSync10, mkdirSync as mkdirSync10, statSync as statSync9 } from "fs";
12860
12889
  import { join as join16 } from "path";
12861
12890
 
12862
12891
  // src/skills/types.ts
12863
- import { readFileSync as readFileSync15 } from "fs";
12892
+ import { readFileSync as readFileSync16 } from "fs";
12864
12893
  import { basename as basename7 } from "path";
12865
12894
  function parseSimpleYaml(yaml) {
12866
12895
  const result = {};
@@ -12882,7 +12911,7 @@ function parseYamlArray(value) {
12882
12911
  function parseSkillFile(filePath) {
12883
12912
  let raw;
12884
12913
  try {
12885
- raw = readFileSync15(filePath, "utf-8");
12914
+ raw = readFileSync16(filePath, "utf-8");
12886
12915
  } catch {
12887
12916
  return null;
12888
12917
  }
@@ -12952,7 +12981,7 @@ var SkillManager = class {
12952
12981
  filePath = fullPath;
12953
12982
  } else {
12954
12983
  try {
12955
- if (statSync8(fullPath).isDirectory()) {
12984
+ if (statSync9(fullPath).isDirectory()) {
12956
12985
  const skillMd = join16(fullPath, "SKILL.md");
12957
12986
  if (existsSync21(skillMd)) filePath = skillMd;
12958
12987
  else continue;
@@ -13013,7 +13042,7 @@ var SkillManager = class {
13013
13042
  // src/web/tool-executor-web.ts
13014
13043
  import { randomUUID as randomUUID2 } from "crypto";
13015
13044
  import { tmpdir as tmpdir2 } from "os";
13016
- import { existsSync as existsSync22, readFileSync as readFileSync16 } from "fs";
13045
+ import { existsSync as existsSync22, readFileSync as readFileSync17 } from "fs";
13017
13046
  var ToolExecutorWeb = class _ToolExecutorWeb {
13018
13047
  constructor(registry, ws) {
13019
13048
  this.registry = registry;
@@ -13152,18 +13181,17 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
13152
13181
  }
13153
13182
  getDiffPreview(call) {
13154
13183
  if (call.name === "write_file") {
13155
- const filePath = String(call.arguments["path"] ?? "");
13156
- const newContent = String(call.arguments["content"] ?? "");
13184
+ const { path: filePath, content: chunk, append } = resolveWriteFileArgs(call.arguments);
13157
13185
  if (filePath && existsSync22(filePath)) {
13158
13186
  try {
13159
- const old = readFileSync16(filePath, "utf-8");
13160
- return renderDiff(old, newContent, { filePath });
13187
+ const old = readFileSync17(filePath, "utf-8");
13188
+ return renderDiff(old, append ? old + chunk : chunk, { filePath });
13161
13189
  } catch {
13162
13190
  }
13163
13191
  }
13164
- const lines = newContent.split("\n").slice(0, 20);
13165
- return lines.map((l) => `+ ${l}`).join("\n") + (newContent.split("\n").length > 20 ? `
13166
- ... (+${newContent.split("\n").length - 20} more lines)` : "");
13192
+ const lines = chunk.split("\n").slice(0, 20);
13193
+ return lines.map((l) => `+ ${l}`).join("\n") + (chunk.split("\n").length > 20 ? `
13194
+ ... (+${chunk.split("\n").length - 20} more lines)` : "");
13167
13195
  }
13168
13196
  if (call.name === "edit_file") {
13169
13197
  const oldStr = String(call.arguments["old_str"] ?? "");
@@ -13469,7 +13497,7 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
13469
13497
  };
13470
13498
 
13471
13499
  // src/repl/dev-state.ts
13472
- import { existsSync as existsSync23, readFileSync as readFileSync17, unlinkSync as unlinkSync5, mkdirSync as mkdirSync11 } from "fs";
13500
+ import { existsSync as existsSync23, readFileSync as readFileSync18, unlinkSync as unlinkSync5, mkdirSync as mkdirSync11 } from "fs";
13473
13501
  import { join as join17 } from "path";
13474
13502
  import { homedir as homedir8 } from "os";
13475
13503
  function getDevStatePath() {
@@ -13478,7 +13506,7 @@ function getDevStatePath() {
13478
13506
  function loadDevState() {
13479
13507
  const path3 = getDevStatePath();
13480
13508
  if (!existsSync23(path3)) return null;
13481
- const content = readFileSync17(path3, "utf-8").trim();
13509
+ const content = readFileSync18(path3, "utf-8").trim();
13482
13510
  return content || null;
13483
13511
  }
13484
13512
 
@@ -13744,7 +13772,7 @@ function autoTrimSessionIfNeeded(session, sizeLimit = SESSION_SIZE_LIMIT) {
13744
13772
  }
13745
13773
 
13746
13774
  // src/core/context-files.ts
13747
- import { existsSync as existsSync24, readFileSync as readFileSync18 } from "fs";
13775
+ import { existsSync as existsSync24, readFileSync as readFileSync19 } from "fs";
13748
13776
  import { join as join18, relative as relative4, resolve as resolve8 } from "path";
13749
13777
  function uniqueNonEmpty(values) {
13750
13778
  const seen = /* @__PURE__ */ new Set();
@@ -13775,7 +13803,7 @@ function readContextFile(level, filePath, cwd, maxBytes) {
13775
13803
  const name = filePath.split(/[\\/]/).pop() ?? filePath;
13776
13804
  const shown = displayPath(filePath, cwd);
13777
13805
  try {
13778
- const raw = readFileSync18(filePath);
13806
+ const raw = readFileSync19(filePath);
13779
13807
  const byteCount = raw.byteLength;
13780
13808
  if (byteCount === 0) {
13781
13809
  return {
@@ -13905,7 +13933,7 @@ import { mkdirSync as mkdirSync14, createWriteStream as createWriteStream2 } fro
13905
13933
  import { dirname as dirname9 } from "path";
13906
13934
 
13907
13935
  // src/repl/commands/project-init.ts
13908
- import { existsSync as existsSync25, readFileSync as readFileSync19, readdirSync as readdirSync11, statSync as statSync9 } from "fs";
13936
+ import { existsSync as existsSync25, readFileSync as readFileSync20, readdirSync as readdirSync11, statSync as statSync10 } from "fs";
13909
13937
  import { join as join19 } from "path";
13910
13938
  var SCAN_SKIP_DIRS = /* @__PURE__ */ new Set([
13911
13939
  "node_modules",
@@ -13950,11 +13978,11 @@ function scanDirTree(dir, maxDepth = 2, maxEntries = 80) {
13950
13978
  const sorted = filtered.sort((a, b) => {
13951
13979
  let aIsDir = false, bIsDir = false;
13952
13980
  try {
13953
- aIsDir = statSync9(join19(d, a)).isDirectory();
13981
+ aIsDir = statSync10(join19(d, a)).isDirectory();
13954
13982
  } catch {
13955
13983
  }
13956
13984
  try {
13957
- bIsDir = statSync9(join19(d, b)).isDirectory();
13985
+ bIsDir = statSync10(join19(d, b)).isDirectory();
13958
13986
  } catch {
13959
13987
  }
13960
13988
  if (aIsDir !== bIsDir) return aIsDir ? -1 : 1;
@@ -13967,7 +13995,7 @@ function scanDirTree(dir, maxDepth = 2, maxEntries = 80) {
13967
13995
  const connector = isLast ? "+-- " : "|-- ";
13968
13996
  let isDir;
13969
13997
  try {
13970
- isDir = statSync9(fullPath).isDirectory();
13998
+ isDir = statSync10(fullPath).isDirectory();
13971
13999
  } catch {
13972
14000
  continue;
13973
14001
  }
@@ -14016,7 +14044,7 @@ function scanProject(cwd) {
14016
14044
  info.type = "node";
14017
14045
  info.language = check("tsconfig.json") ? "TypeScript" : "JavaScript";
14018
14046
  try {
14019
- const pkg = JSON.parse(readFileSync19(join19(cwd, "package.json"), "utf-8"));
14047
+ const pkg = JSON.parse(readFileSync20(join19(cwd, "package.json"), "utf-8"));
14020
14048
  const scripts = pkg.scripts ?? {};
14021
14049
  info.buildCommand = scripts.build ? "npm run build" : void 0;
14022
14050
  info.testCommand = scripts.test ? "npm test" : void 0;
@@ -14791,7 +14819,7 @@ async function handlePlan(args, ctx) {
14791
14819
  }
14792
14820
 
14793
14821
  // src/web/commands/_shared.ts
14794
- import { existsSync as existsSync28, readFileSync as readFileSync21, writeFileSync as writeFileSync3, mkdirSync as mkdirSync13, readdirSync as readdirSync13, statSync as statSync12, createWriteStream } from "fs";
14822
+ import { existsSync as existsSync28, readFileSync as readFileSync22, writeFileSync as writeFileSync3, mkdirSync as mkdirSync13, readdirSync as readdirSync13, statSync as statSync13, createWriteStream } from "fs";
14795
14823
  import { join as join23, resolve as resolve9, dirname as dirname8 } from "path";
14796
14824
 
14797
14825
  // src/cli/review-prompts.ts
@@ -14864,7 +14892,7 @@ function readGitDiff(options = {}) {
14864
14892
  }
14865
14893
 
14866
14894
  // src/diagnostics/doctor-report.ts
14867
- import { existsSync as existsSync27, statSync as statSync11 } from "fs";
14895
+ import { existsSync as existsSync27, statSync as statSync12 } from "fs";
14868
14896
  import { join as join22 } from "path";
14869
14897
  import { arch as arch2, platform as platform7, release as release2 } from "os";
14870
14898
 
@@ -14873,8 +14901,8 @@ import {
14873
14901
  existsSync as existsSync26,
14874
14902
  mkdirSync as mkdirSync12,
14875
14903
  readdirSync as readdirSync12,
14876
- readFileSync as readFileSync20,
14877
- statSync as statSync10,
14904
+ readFileSync as readFileSync21,
14905
+ statSync as statSync11,
14878
14906
  unlinkSync as unlinkSync6,
14879
14907
  writeFileSync as writeFileSync2
14880
14908
  } from "fs";
@@ -14903,8 +14931,8 @@ function listRecentCrashes(limit = 10, configDir) {
14903
14931
  if (!name.startsWith(CRASH_LOG_PREFIX) || !name.endsWith(".log")) continue;
14904
14932
  const full = join21(dir, name);
14905
14933
  try {
14906
- const st = statSync10(full);
14907
- const head = readFileSync20(full, "utf-8").split("\n").slice(0, 20);
14934
+ const st = statSync11(full);
14935
+ const head = readFileSync21(full, "utf-8").split("\n").slice(0, 20);
14908
14936
  const tsLine = head.find((l) => l.startsWith("timestamp:"));
14909
14937
  const kindLine = head.find((l) => l.startsWith("kind:"));
14910
14938
  const msgIdx = head.findIndex((l) => l.trim() === "## message");
@@ -14944,7 +14972,7 @@ function getConfigDirUsage(configDir) {
14944
14972
  }
14945
14973
  function dirSize(path3) {
14946
14974
  try {
14947
- const st = statSync10(path3);
14975
+ const st = statSync11(path3);
14948
14976
  if (st.isFile()) return st.size;
14949
14977
  if (!st.isDirectory()) return 0;
14950
14978
  let sum = 0;
@@ -14963,7 +14991,7 @@ function checkFile(label, path3) {
14963
14991
  let sizeBytes = null;
14964
14992
  if (exists) {
14965
14993
  try {
14966
- sizeBytes = statSync11(path3).size;
14994
+ sizeBytes = statSync12(path3).size;
14967
14995
  } catch {
14968
14996
  }
14969
14997
  }
@@ -15285,7 +15313,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
15285
15313
  Cost: ${formatCost(cost)}` : "";
15286
15314
  let memoryLine = "";
15287
15315
  try {
15288
- const { countPendingMemories } = await import("./persistent-memory-PNJCHP33.js");
15316
+ const { countPendingMemories } = await import("./persistent-memory-I4JV3CME.js");
15289
15317
  const pending = countPendingMemories(ctx.config.getConfigDir());
15290
15318
  if (pending > 0) memoryLine = `
15291
15319
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -16094,7 +16122,7 @@ async function handleSecurityReview(args, ctx) {
16094
16122
  async function handleTest(args, ctx) {
16095
16123
  ctx.send({ type: "info", message: "\u{1F9EA} Running tests..." });
16096
16124
  try {
16097
- const { executeTests } = await import("./run-tests-F7Y6POVK.js");
16125
+ const { executeTests } = await import("./run-tests-HFT5RUXF.js");
16098
16126
  const argStr = args.join(" ").trim();
16099
16127
  let testArgs = {};
16100
16128
  if (argStr) {
@@ -16126,7 +16154,7 @@ async function handleDiff(args, ctx) {
16126
16154
  for (const [filePath, { earliest }] of fileMap) {
16127
16155
  const currentContent = existsSync28(filePath) ? (() => {
16128
16156
  try {
16129
- return readFileSync21(filePath, "utf-8");
16157
+ return readFileSync22(filePath, "utf-8");
16130
16158
  } catch {
16131
16159
  return null;
16132
16160
  }
@@ -16358,7 +16386,7 @@ async function handleMemory(args, ctx) {
16358
16386
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
16359
16387
  } else if (sub === "export") {
16360
16388
  if (args[1] === "md") {
16361
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-PNJCHP33.js");
16389
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-I4JV3CME.js");
16362
16390
  ctx.send({
16363
16391
  type: "export_data",
16364
16392
  format: "md",
@@ -16400,7 +16428,7 @@ Use /add-dir remove to clear.` : "No directories added.\nUsage: /add-dir <path>
16400
16428
  ctx.send({ type: "error", message: `Directory not found: ${dirPath}` });
16401
16429
  return;
16402
16430
  }
16403
- if (!statSync12(dirPath).isDirectory()) {
16431
+ if (!statSync13(dirPath).isDirectory()) {
16404
16432
  ctx.send({ type: "error", message: `Not a directory: ${dirPath}` });
16405
16433
  return;
16406
16434
  }
@@ -18271,7 +18299,7 @@ async function setupProxy(configProxy) {
18271
18299
  }
18272
18300
 
18273
18301
  // src/web/auth.ts
18274
- import { existsSync as existsSync29, readFileSync as readFileSync22, writeFileSync as writeFileSync4, mkdirSync as mkdirSync15, readdirSync as readdirSync14, copyFileSync } from "fs";
18302
+ import { existsSync as existsSync29, readFileSync as readFileSync23, writeFileSync as writeFileSync4, mkdirSync as mkdirSync15, readdirSync as readdirSync14, copyFileSync } from "fs";
18275
18303
  import { isAbsolute as isAbsolute3, join as join24, relative as relative5 } from "path";
18276
18304
  import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
18277
18305
  var USERS_FILE = "users.json";
@@ -18472,7 +18500,7 @@ var AuthManager = class {
18472
18500
  const globalConfig = join24(this.baseDir, "config.json");
18473
18501
  if (existsSync29(globalConfig)) {
18474
18502
  try {
18475
- const content = readFileSync22(globalConfig, "utf-8");
18503
+ const content = readFileSync23(globalConfig, "utf-8");
18476
18504
  writeFileSync4(join24(userDir, "config.json"), content, "utf-8");
18477
18505
  } catch {
18478
18506
  }
@@ -18480,7 +18508,7 @@ var AuthManager = class {
18480
18508
  const globalMemory = join24(this.baseDir, "memory.md");
18481
18509
  if (existsSync29(globalMemory)) {
18482
18510
  try {
18483
- const content = readFileSync22(globalMemory, "utf-8");
18511
+ const content = readFileSync23(globalMemory, "utf-8");
18484
18512
  writeFileSync4(join24(userDir, "memory.md"), content, "utf-8");
18485
18513
  } catch {
18486
18514
  }
@@ -18505,7 +18533,7 @@ var AuthManager = class {
18505
18533
  loadOrCreate() {
18506
18534
  if (existsSync29(this.usersFile)) {
18507
18535
  try {
18508
- const parsed = JSON.parse(readFileSync22(this.usersFile, "utf-8"));
18536
+ const parsed = JSON.parse(readFileSync23(this.usersFile, "utf-8"));
18509
18537
  if (!this.isValidUsersDB(parsed)) {
18510
18538
  throw new Error("database structure is invalid");
18511
18539
  }
@@ -18882,7 +18910,7 @@ async function startWebServer(options = {}) {
18882
18910
  res.status(404).json({ error: "Session not found" });
18883
18911
  return;
18884
18912
  }
18885
- const data = JSON.parse(readFileSync23(filePath, "utf-8"));
18913
+ const data = JSON.parse(readFileSync24(filePath, "utf-8"));
18886
18914
  res.json({ session: data });
18887
18915
  } catch (err) {
18888
18916
  res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
@@ -18908,12 +18936,12 @@ async function startWebServer(options = {}) {
18908
18936
  return;
18909
18937
  }
18910
18938
  try {
18911
- const stat = statSync13(fullPath);
18939
+ const stat = statSync14(fullPath);
18912
18940
  if (stat.size > 512 * 1024) {
18913
18941
  res.json({ error: `File too large (${(stat.size / 1024).toFixed(0)} KB, max 512 KB)` });
18914
18942
  return;
18915
18943
  }
18916
- const content = readFileSync23(fullPath, "utf-8");
18944
+ const content = readFileSync24(fullPath, "utf-8");
18917
18945
  res.json({ content, size: stat.size });
18918
18946
  } catch {
18919
18947
  res.json({ error: "Cannot read file" });
@@ -19178,7 +19206,7 @@ function loadProjectMcpConfig() {
19178
19206
  const configPath = join25(projectRoot, MCP_PROJECT_CONFIG_NAME);
19179
19207
  if (!existsSync30(configPath)) return null;
19180
19208
  try {
19181
- const raw = JSON.parse(readFileSync23(configPath, "utf-8"));
19209
+ const raw = JSON.parse(readFileSync24(configPath, "utf-8"));
19182
19210
  return raw.mcpServers ?? raw;
19183
19211
  } catch {
19184
19212
  return null;