jinzd-ai-cli 0.4.208 → 0.4.209

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 (27) hide show
  1. package/README.md +5 -3
  2. package/dist/{batch-3T44NFLG.js → batch-45WLJUVP.js} +4 -4
  3. package/dist/{chunk-TD7JEHCR.js → chunk-ATNYI6JL.js} +19 -4
  4. package/dist/{chunk-SQB66GP6.js → chunk-BNERFXVO.js} +12 -9
  5. package/dist/{chunk-P7JY3SWA.js → chunk-D6M4E7SH.js} +1 -1
  6. package/dist/{chunk-TM4MS63K.js → chunk-DUZRQXIP.js} +6 -3
  7. package/dist/{chunk-VWYUB22Y.js → chunk-EN63JA7N.js} +1 -1
  8. package/dist/{chunk-QDY72ABW.js → chunk-EYID2AIR.js} +1 -1
  9. package/dist/{chunk-2OVMMSGQ.js → chunk-JVLRMIHA.js} +10 -9
  10. package/dist/{chunk-O6UFCEUZ.js → chunk-K3CF65QH.js} +12 -9
  11. package/dist/{chunk-J22B3OSQ.js → chunk-STIEOOOL.js} +1 -1
  12. package/dist/{chunk-KV4GYNEA.js → chunk-UPMBIS4T.js} +1 -1
  13. package/dist/{ci-6QWBVRJX.js → ci-PUE3MQ7J.js} +3 -2
  14. package/dist/{constants-SZTQNN7K.js → constants-VTZLKDAG.js} +1 -1
  15. package/dist/{doctor-cli-I2Y2YR4V.js → doctor-cli-IU6FSVLF.js} +4 -4
  16. package/dist/electron-server.js +82 -49
  17. package/dist/{hub-XVPFBODB.js → hub-4ETK4R2J.js} +1 -1
  18. package/dist/index.js +27 -28
  19. package/dist/{indexer-AKWMYNJI.js → indexer-2AG4G6B5.js} +1 -1
  20. package/dist/{indexer-BMYUUDLH.js → indexer-4WWS3VIL.js} +1 -1
  21. package/dist/{run-tests-D5SNUBYX.js → run-tests-NDS2IEMK.js} +2 -2
  22. package/dist/{run-tests-HZ2CRCTZ.js → run-tests-UAS5NJBM.js} +1 -1
  23. package/dist/{server-4EFTRFTN.js → server-4URLNC7P.js} +44 -22
  24. package/dist/{server-PVKLPRUP.js → server-72SAPLPS.js} +5 -5
  25. package/dist/{task-orchestrator-2A5VCFLS.js → task-orchestrator-6PZTB35T.js} +5 -5
  26. package/dist/{usage-Q24E5636.js → usage-ZNCKGF6U.js} +2 -2
  27. package/package.json +2 -1
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-SKET65WZ.js";
4
4
  import {
5
5
  indexProject
6
- } from "./chunk-SQB66GP6.js";
6
+ } from "./chunk-BNERFXVO.js";
7
7
  import {
8
8
  AGENTIC_BEHAVIOR_GUIDELINE,
9
9
  APP_NAME,
@@ -36,7 +36,7 @@ import {
36
36
  VERSION,
37
37
  buildUserIdentityPrompt,
38
38
  runTestsTool
39
- } from "./chunk-QDY72ABW.js";
39
+ } from "./chunk-EYID2AIR.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -60,11 +60,11 @@ import express from "express";
60
60
  import { createServer } from "http";
61
61
  import { WebSocketServer } from "ws";
62
62
  import { join as join17, dirname as dirname6, resolve as resolve6, relative as relative3, sep as sep3 } from "path";
63
- import { existsSync as existsSync23, readFileSync as readFileSync16, readdirSync as readdirSync11, statSync as statSync9, realpathSync } from "fs";
63
+ import { existsSync as existsSync23, readFileSync as readFileSync17, readdirSync as readdirSync11, statSync as statSync9, realpathSync } from "fs";
64
64
  import { networkInterfaces } from "os";
65
65
 
66
66
  // src/config/config-manager.ts
67
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
67
+ import { readFileSync, existsSync, mkdirSync } from "fs";
68
68
  import { join } from "path";
69
69
  import { homedir } from "os";
70
70
 
@@ -503,7 +503,7 @@ ${err}`
503
503
  }
504
504
  save() {
505
505
  mkdirSync(this.configDir, { recursive: true });
506
- writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
506
+ atomicWriteFileSync(this.configPath, JSON.stringify(this.config, null, 2));
507
507
  }
508
508
  getApiKey(providerId) {
509
509
  const envKey = EnvLoader.getApiKey(providerId);
@@ -4736,7 +4736,7 @@ import { platform as platform2 } from "os";
4736
4736
  import { resolve } from "path";
4737
4737
 
4738
4738
  // src/tools/undo-stack.ts
4739
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, rmdirSync, existsSync as existsSync3 } from "fs";
4739
+ import { readFileSync as readFileSync3, writeFileSync, unlinkSync as unlinkSync2, rmdirSync, existsSync as existsSync3 } from "fs";
4740
4740
  var MAX_UNDO_DEPTH = 20;
4741
4741
  var UndoStack = class {
4742
4742
  stack = [];
@@ -4819,7 +4819,7 @@ var UndoStack = class {
4819
4819
  return { entry, result: `Deleted newly created file: ${entry.filePath}` };
4820
4820
  }
4821
4821
  } else {
4822
- writeFileSync2(entry.filePath, entry.previousContent, "utf-8");
4822
+ writeFileSync(entry.filePath, entry.previousContent, "utf-8");
4823
4823
  const lines = entry.previousContent.split("\n").length;
4824
4824
  return {
4825
4825
  entry,
@@ -6864,7 +6864,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
6864
6864
  const mode = appendMode ? "appended" : "written";
6865
6865
  void (async () => {
6866
6866
  try {
6867
- const { updateFile } = await import("./indexer-BMYUUDLH.js");
6867
+ const { updateFile } = await import("./indexer-4WWS3VIL.js");
6868
6868
  await updateFile(process.cwd(), filePath);
6869
6869
  } catch {
6870
6870
  }
@@ -8648,7 +8648,7 @@ Any of these triggers means use save_last_response, NOT write_file:
8648
8648
  };
8649
8649
 
8650
8650
  // src/tools/builtin/save-memory.ts
8651
- import { existsSync as existsSync12, statSync as statSync6, appendFileSync as appendFileSync2, mkdirSync as mkdirSync6 } from "fs";
8651
+ import { existsSync as existsSync12, readFileSync as readFileSync9, statSync as statSync6, mkdirSync as mkdirSync6 } from "fs";
8652
8652
  import { join as join7 } from "path";
8653
8653
  import { homedir as homedir5 } from "os";
8654
8654
  function getMemoryFilePath() {
@@ -8685,7 +8685,8 @@ var saveMemoryTool = {
8685
8685
  ## ${timestamp}
8686
8686
  ${content}
8687
8687
  `;
8688
- appendFileSync2(memoryPath, entry, "utf-8");
8688
+ const previous = existsSync12(memoryPath) ? readFileSync9(memoryPath, "utf-8") : "";
8689
+ atomicWriteFileSync(memoryPath, previous + entry);
8689
8690
  const byteSize = statSync6(memoryPath).size;
8690
8691
  return `Memory saved successfully. File size: ${byteSize} bytes in ${MEMORY_FILE_NAME}`;
8691
8692
  }
@@ -9750,7 +9751,7 @@ ${commitOutput.trim()}`;
9750
9751
  };
9751
9752
 
9752
9753
  // src/tools/builtin/notebook-edit.ts
9753
- import { readFileSync as readFileSync9, existsSync as existsSync14 } from "fs";
9754
+ import { readFileSync as readFileSync10, existsSync as existsSync14 } from "fs";
9754
9755
  import { writeFile } from "fs/promises";
9755
9756
  import { resolve as resolve4, extname as extname2 } from "path";
9756
9757
  var notebookEditTool = {
@@ -9808,7 +9809,7 @@ var notebookEditTool = {
9808
9809
  if (!existsSync14(absPath)) {
9809
9810
  throw new ToolError("notebook_edit", `Notebook not found: ${filePath}`);
9810
9811
  }
9811
- const raw = readFileSync9(absPath, "utf-8");
9812
+ const raw = readFileSync10(absPath, "utf-8");
9812
9813
  const nb = parseNotebook(raw);
9813
9814
  const cellIdx0 = cellIndexRaw - 1;
9814
9815
  undoStack.push(absPath, `notebook_edit (${action}): ${filePath}`);
@@ -10968,7 +10969,7 @@ import { existsSync as existsSync16, readdirSync as readdirSync8, mkdirSync as m
10968
10969
  import { join as join10 } from "path";
10969
10970
 
10970
10971
  // src/skills/types.ts
10971
- import { readFileSync as readFileSync10 } from "fs";
10972
+ import { readFileSync as readFileSync11 } from "fs";
10972
10973
  import { basename as basename5 } from "path";
10973
10974
  function parseSimpleYaml(yaml) {
10974
10975
  const result = {};
@@ -10990,7 +10991,7 @@ function parseYamlArray(value) {
10990
10991
  function parseSkillFile(filePath) {
10991
10992
  let raw;
10992
10993
  try {
10993
- raw = readFileSync10(filePath, "utf-8");
10994
+ raw = readFileSync11(filePath, "utf-8");
10994
10995
  } catch {
10995
10996
  return null;
10996
10997
  }
@@ -11119,7 +11120,7 @@ var SkillManager = class {
11119
11120
 
11120
11121
  // src/web/tool-executor-web.ts
11121
11122
  import { randomUUID as randomUUID2 } from "crypto";
11122
- import { existsSync as existsSync17, readFileSync as readFileSync11 } from "fs";
11123
+ import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
11123
11124
  var ToolExecutorWeb = class _ToolExecutorWeb {
11124
11125
  constructor(registry, ws) {
11125
11126
  this.registry = registry;
@@ -11246,7 +11247,7 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
11246
11247
  const newContent = String(call.arguments["content"] ?? "");
11247
11248
  if (filePath && existsSync17(filePath)) {
11248
11249
  try {
11249
- const old = readFileSync11(filePath, "utf-8");
11250
+ const old = readFileSync12(filePath, "utf-8");
11250
11251
  return renderDiff(old, newContent, { filePath });
11251
11252
  } catch {
11252
11253
  }
@@ -11447,11 +11448,11 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
11447
11448
  };
11448
11449
 
11449
11450
  // src/core/system-prompt-builder.ts
11450
- import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
11451
+ import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
11451
11452
  import { join as join12 } from "path";
11452
11453
 
11453
11454
  // src/repl/dev-state.ts
11454
- import { existsSync as existsSync18, readFileSync as readFileSync12, writeFileSync as writeFileSync3, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9 } from "fs";
11455
+ import { existsSync as existsSync18, readFileSync as readFileSync13, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9 } from "fs";
11455
11456
  import { join as join11 } from "path";
11456
11457
  import { homedir as homedir6 } from "os";
11457
11458
  function getDevStatePath() {
@@ -11460,7 +11461,7 @@ function getDevStatePath() {
11460
11461
  function loadDevState() {
11461
11462
  const path3 = getDevStatePath();
11462
11463
  if (!existsSync18(path3)) return null;
11463
- const content = readFileSync12(path3, "utf-8").trim();
11464
+ const content = readFileSync13(path3, "utf-8").trim();
11464
11465
  return content || null;
11465
11466
  }
11466
11467
 
@@ -11520,7 +11521,7 @@ ${ctx.activeSkill.content}`);
11520
11521
  function loadMemoryContent(configDir) {
11521
11522
  const memoryPath = join12(configDir, MEMORY_FILE_NAME);
11522
11523
  if (!existsSync19(memoryPath)) return null;
11523
- let content = readFileSync13(memoryPath, "utf-8").trim();
11524
+ let content = readFileSync14(memoryPath, "utf-8").trim();
11524
11525
  if (!content) return null;
11525
11526
  if (content.length > MEMORY_MAX_CHARS) {
11526
11527
  content = content.slice(-MEMORY_MAX_CHARS);
@@ -11729,9 +11730,8 @@ function autoTrimSessionIfNeeded(session, sizeLimit = SESSION_SIZE_LIMIT) {
11729
11730
  }
11730
11731
 
11731
11732
  // src/web/session-handler.ts
11732
- import { existsSync as existsSync21, readFileSync as readFileSync14, appendFileSync as appendFileSync3, writeFileSync as writeFileSync4, mkdirSync as mkdirSync10, readdirSync as readdirSync9, statSync as statSync8, createWriteStream } from "fs";
11733
+ import { existsSync as existsSync21, readFileSync as readFileSync15, writeFileSync as writeFileSync2, mkdirSync as mkdirSync10, readdirSync as readdirSync9, statSync as statSync8, createWriteStream } from "fs";
11733
11734
  import { join as join15, resolve as resolve5, dirname as dirname5 } from "path";
11734
- import { execSync as execSync3 } from "child_process";
11735
11735
 
11736
11736
  // src/tools/git-context.ts
11737
11737
  import { execSync as execSync2 } from "child_process";
@@ -11823,6 +11823,17 @@ function formatGitContextForPrompt(ctx) {
11823
11823
  return lines.join("\n");
11824
11824
  }
11825
11825
 
11826
+ // src/core/git-diff.ts
11827
+ import { execFileSync as execFileSync3 } from "child_process";
11828
+ function readGitDiff(options = {}) {
11829
+ const args = ["diff"];
11830
+ if (options.staged) args.push("--staged");
11831
+ return execFileSync3("git", args, {
11832
+ encoding: "utf-8",
11833
+ timeout: options.timeoutMs ?? 1e4
11834
+ }).trim();
11835
+ }
11836
+
11826
11837
  // src/hub/convergence.ts
11827
11838
  function convergenceThreshold(total) {
11828
11839
  if (total <= 0) return Infinity;
@@ -13855,7 +13866,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
13855
13866
  for (const [filePath, { earliest }] of fileMap) {
13856
13867
  const currentContent = existsSync21(filePath) ? (() => {
13857
13868
  try {
13858
- return readFileSync14(filePath, "utf-8");
13869
+ return readFileSync15(filePath, "utf-8");
13859
13870
  } catch {
13860
13871
  return null;
13861
13872
  }
@@ -14136,7 +14147,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
14136
14147
  const sub = (args[0] ?? "status").toLowerCase();
14137
14148
  const root = process.cwd();
14138
14149
  const { loadIndex: loadIndex2, clearIndex } = await import("./store-VO37H6LS.js");
14139
- const { indexProject: indexProject2 } = await import("./indexer-BMYUUDLH.js");
14150
+ const { indexProject: indexProject2 } = await import("./indexer-4WWS3VIL.js");
14140
14151
  const { loadVectorStore, clearVectorStore } = await import("./vector-store-JBAE6PS4.js");
14141
14152
  if (sub === "status") {
14142
14153
  const idx = loadIndex2(root);
@@ -14255,8 +14266,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
14255
14266
  const detailed = args.includes("--detailed");
14256
14267
  let diff;
14257
14268
  try {
14258
- const cmd = staged ? "git diff --staged" : "git diff";
14259
- diff = execSync3(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
14269
+ diff = readGitDiff({ staged });
14260
14270
  } catch {
14261
14271
  this.send({ type: "error", message: "Failed to run git diff." });
14262
14272
  break;
@@ -14294,8 +14304,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
14294
14304
  const secStaged = args.includes("--staged");
14295
14305
  let secDiff;
14296
14306
  try {
14297
- const cmd = secStaged ? "git diff --staged" : "git diff";
14298
- secDiff = execSync3(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
14307
+ secDiff = readGitDiff({ staged: secStaged });
14299
14308
  } catch {
14300
14309
  this.send({ type: "error", message: "Failed to run git diff." });
14301
14310
  break;
@@ -14373,7 +14382,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
14373
14382
  case "test": {
14374
14383
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
14375
14384
  try {
14376
- const { executeTests } = await import("./run-tests-HZ2CRCTZ.js");
14385
+ const { executeTests } = await import("./run-tests-UAS5NJBM.js");
14377
14386
  const argStr = args.join(" ").trim();
14378
14387
  let testArgs = {};
14379
14388
  if (argStr) {
@@ -14402,7 +14411,7 @@ Use /init --force to overwrite.` });
14402
14411
  const projectInfo = this.scanProject(cwd);
14403
14412
  const prompt = this.buildInitPrompt(projectInfo, cwd);
14404
14413
  const content = await this.chatOnce(prompt, { temperature: 0.3, maxTokens: 4096 });
14405
- writeFileSync4(targetPath, content, "utf-8");
14414
+ writeFileSync2(targetPath, content, "utf-8");
14406
14415
  this.send({ type: "info", message: `\u2713 Generated: ${targetPath} (${content.length} chars)
14407
14416
  Use /context reload to load it.` });
14408
14417
  } catch (err) {
@@ -14851,7 +14860,7 @@ Add .md files to create commands.` });
14851
14860
  let content = "";
14852
14861
  try {
14853
14862
  if (existsSync21(memPath)) {
14854
- content = readFileSync14(memPath, "utf-8");
14863
+ content = readFileSync15(memPath, "utf-8");
14855
14864
  }
14856
14865
  } catch (err) {
14857
14866
  process.stderr.write(`[web] Failed to read memory file: ${err instanceof Error ? err.message : err}
@@ -14869,9 +14878,11 @@ Add .md files to create commands.` });
14869
14878
  try {
14870
14879
  mkdirSync10(configDir, { recursive: true });
14871
14880
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace("T", " ");
14872
- appendFileSync3(memPath, `
14881
+ const previous = existsSync21(memPath) ? readFileSync15(memPath, "utf-8") : "";
14882
+ const entry = `
14873
14883
  - [${timestamp}] ${text}
14874
- `, "utf-8");
14884
+ `;
14885
+ atomicWriteFileSync(memPath, previous + entry);
14875
14886
  this.send({ type: "info", message: `\u{1F4DD} Memory entry added: "${text}"` });
14876
14887
  } catch (err) {
14877
14888
  this.send({ type: "error", message: `Failed to write memory: ${err.message}` });
@@ -14881,7 +14892,7 @@ Add .md files to create commands.` });
14881
14892
  const configDir = this.config.getConfigDir();
14882
14893
  const memPath = join15(configDir, MEMORY_FILE_NAME);
14883
14894
  try {
14884
- writeFileSync4(memPath, "", "utf-8");
14895
+ atomicWriteFileSync(memPath, "");
14885
14896
  this.send({ type: "info", message: "\u{1F5D1}\uFE0F Persistent memory cleared." });
14886
14897
  } catch (err) {
14887
14898
  this.send({ type: "error", message: `Failed to clear memory: ${err.message}` });
@@ -15091,7 +15102,7 @@ Add .md files to create commands.` });
15091
15102
  const fullPath = join15(dir, name);
15092
15103
  try {
15093
15104
  if (existsSync21(fullPath)) {
15094
- const content = readFileSync14(fullPath, "utf-8").trim();
15105
+ const content = readFileSync15(fullPath, "utf-8").trim();
15095
15106
  if (content) return content;
15096
15107
  }
15097
15108
  } catch {
@@ -15207,7 +15218,7 @@ Add .md files to create commands.` });
15207
15218
  info.type = "node";
15208
15219
  info.language = check("tsconfig.json") ? "TypeScript" : "JavaScript";
15209
15220
  try {
15210
- const pkg = JSON.parse(readFileSync14(join15(cwd, "package.json"), "utf-8"));
15221
+ const pkg = JSON.parse(readFileSync15(join15(cwd, "package.json"), "utf-8"));
15211
15222
  const scripts = pkg.scripts ?? {};
15212
15223
  info.buildCommand = scripts.build ? "npm run build" : void 0;
15213
15224
  info.testCommand = scripts.test ? "npm test" : void 0;
@@ -15357,7 +15368,7 @@ async function setupProxy(configProxy) {
15357
15368
  }
15358
15369
 
15359
15370
  // src/web/auth.ts
15360
- import { existsSync as existsSync22, readFileSync as readFileSync15, writeFileSync as writeFileSync5, mkdirSync as mkdirSync11, readdirSync as readdirSync10, copyFileSync } from "fs";
15371
+ import { existsSync as existsSync22, readFileSync as readFileSync16, writeFileSync as writeFileSync3, mkdirSync as mkdirSync11, readdirSync as readdirSync10, copyFileSync } from "fs";
15361
15372
  import { join as join16 } from "path";
15362
15373
  import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
15363
15374
  var USERS_FILE = "users.json";
@@ -15558,16 +15569,16 @@ var AuthManager = class {
15558
15569
  const globalConfig = join16(this.baseDir, "config.json");
15559
15570
  if (existsSync22(globalConfig)) {
15560
15571
  try {
15561
- const content = readFileSync15(globalConfig, "utf-8");
15562
- writeFileSync5(join16(userDir, "config.json"), content, "utf-8");
15572
+ const content = readFileSync16(globalConfig, "utf-8");
15573
+ writeFileSync3(join16(userDir, "config.json"), content, "utf-8");
15563
15574
  } catch {
15564
15575
  }
15565
15576
  }
15566
15577
  const globalMemory = join16(this.baseDir, "memory.md");
15567
15578
  if (existsSync22(globalMemory)) {
15568
15579
  try {
15569
- const content = readFileSync15(globalMemory, "utf-8");
15570
- writeFileSync5(join16(userDir, "memory.md"), content, "utf-8");
15580
+ const content = readFileSync16(globalMemory, "utf-8");
15581
+ writeFileSync3(join16(userDir, "memory.md"), content, "utf-8");
15571
15582
  } catch {
15572
15583
  }
15573
15584
  }
@@ -15591,7 +15602,7 @@ var AuthManager = class {
15591
15602
  loadOrCreate() {
15592
15603
  if (existsSync22(this.usersFile)) {
15593
15604
  try {
15594
- return JSON.parse(readFileSync15(this.usersFile, "utf-8"));
15605
+ return JSON.parse(readFileSync16(this.usersFile, "utf-8"));
15595
15606
  } catch {
15596
15607
  }
15597
15608
  }
@@ -15791,6 +15802,7 @@ async function startWebServer(options = {}) {
15791
15802
  clientDir = join17(process.cwd(), "src", "web", "client");
15792
15803
  }
15793
15804
  console.log(` Static files: ${clientDir}`);
15805
+ app.use("/vendor", express.static(join17(clientDir, "vendor"), { maxAge: "1y", immutable: true }));
15794
15806
  app.use(express.static(clientDir));
15795
15807
  app.get("/api/status", (_req, res) => {
15796
15808
  res.json({
@@ -15833,7 +15845,7 @@ async function startWebServer(options = {}) {
15833
15845
  }
15834
15846
  const token = authManager.login(username, password);
15835
15847
  console.log(` \u2713 User registered via API: ${username}${firstRun ? " (first-run)" : ""}`);
15836
- res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
15848
+ res.cookie("aicli_token", token, authCookieOptions(req));
15837
15849
  res.json({ success: true, username });
15838
15850
  });
15839
15851
  app.post("/api/auth/login", (req, res) => {
@@ -15847,11 +15859,11 @@ async function startWebServer(options = {}) {
15847
15859
  res.status(401).json({ error: "Invalid username or password" });
15848
15860
  return;
15849
15861
  }
15850
- res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
15862
+ res.cookie("aicli_token", token, authCookieOptions(req));
15851
15863
  res.json({ success: true, username });
15852
15864
  });
15853
- app.post("/api/auth/logout", (_req, res) => {
15854
- res.clearCookie("aicli_token", { httpOnly: true, sameSite: "strict" });
15865
+ app.post("/api/auth/logout", (req, res) => {
15866
+ res.clearCookie("aicli_token", clearAuthCookieOptions(req));
15855
15867
  res.json({ success: true });
15856
15868
  });
15857
15869
  app.get("/api/files", requireAuth, (req, res) => {
@@ -15926,7 +15938,7 @@ async function startWebServer(options = {}) {
15926
15938
  res.status(404).json({ error: "Session not found" });
15927
15939
  return;
15928
15940
  }
15929
- const data = JSON.parse(readFileSync16(filePath, "utf-8"));
15941
+ const data = JSON.parse(readFileSync17(filePath, "utf-8"));
15930
15942
  res.json({ session: data });
15931
15943
  } catch (err) {
15932
15944
  res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
@@ -15957,7 +15969,7 @@ async function startWebServer(options = {}) {
15957
15969
  res.json({ error: `File too large (${(stat.size / 1024).toFixed(0)} KB, max 512 KB)` });
15958
15970
  return;
15959
15971
  }
15960
- const content = readFileSync16(fullPath, "utf-8");
15972
+ const content = readFileSync17(fullPath, "utf-8");
15961
15973
  res.json({ content, size: stat.size });
15962
15974
  } catch {
15963
15975
  res.json({ error: "Cannot read file" });
@@ -16222,12 +16234,33 @@ function loadProjectMcpConfig() {
16222
16234
  const configPath = join17(projectRoot, MCP_PROJECT_CONFIG_NAME);
16223
16235
  if (!existsSync23(configPath)) return null;
16224
16236
  try {
16225
- const raw = JSON.parse(readFileSync16(configPath, "utf-8"));
16237
+ const raw = JSON.parse(readFileSync17(configPath, "utf-8"));
16226
16238
  return raw.mcpServers ?? raw;
16227
16239
  } catch {
16228
16240
  return null;
16229
16241
  }
16230
16242
  }
16243
+ function isHttpsRequest(req) {
16244
+ if (req.secure) return true;
16245
+ const forwardedProto = req.headers["x-forwarded-proto"];
16246
+ const proto = Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto;
16247
+ return proto?.split(",")[0]?.trim().toLowerCase() === "https";
16248
+ }
16249
+ function authCookieOptions(req) {
16250
+ return {
16251
+ httpOnly: true,
16252
+ sameSite: "strict",
16253
+ maxAge: TOKEN_EXPIRY_MS,
16254
+ secure: isHttpsRequest(req)
16255
+ };
16256
+ }
16257
+ function clearAuthCookieOptions(req) {
16258
+ return {
16259
+ httpOnly: true,
16260
+ sameSite: "strict",
16261
+ secure: isHttpsRequest(req)
16262
+ };
16263
+ }
16231
16264
  function parseCookie(cookie) {
16232
16265
  const result = {};
16233
16266
  for (const part of cookie.split(";")) {
@@ -154,7 +154,7 @@ ${content}`);
154
154
  }
155
155
  }
156
156
  async function runTaskMode(config, providers, configManager, topic) {
157
- const { TaskOrchestrator } = await import("./task-orchestrator-2A5VCFLS.js");
157
+ const { TaskOrchestrator } = await import("./task-orchestrator-6PZTB35T.js");
158
158
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
159
159
  let interrupted = false;
160
160
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -12,10 +12,11 @@ import {
12
12
  loadDevState,
13
13
  parseSimpleYaml,
14
14
  persistToolRound,
15
+ readGitDiff,
15
16
  saveDevState,
16
17
  sessionHasMeaningfulContent,
17
18
  setupProxy
18
- } from "./chunk-TD7JEHCR.js";
19
+ } from "./chunk-ATNYI6JL.js";
19
20
  import {
20
21
  ToolExecutor,
21
22
  ToolRegistry,
@@ -35,10 +36,10 @@ import {
35
36
  spawnAgentContext,
36
37
  theme,
37
38
  undoStack
38
- } from "./chunk-2OVMMSGQ.js";
39
+ } from "./chunk-JVLRMIHA.js";
39
40
  import "./chunk-T2NL5ZIA.js";
40
41
  import "./chunk-BXP6YZ2P.js";
41
- import "./chunk-VWYUB22Y.js";
42
+ import "./chunk-EN63JA7N.js";
42
43
  import {
43
44
  SessionManager,
44
45
  getContentText
@@ -55,7 +56,7 @@ import {
55
56
  getConfigDirUsage,
56
57
  listRecentCrashes,
57
58
  writeCrashLog
58
- } from "./chunk-P7JY3SWA.js";
59
+ } from "./chunk-D6M4E7SH.js";
59
60
  import {
60
61
  ProviderRegistry
61
62
  } from "./chunk-QMXC327F.js";
@@ -64,7 +65,7 @@ import {
64
65
  getTopFailingTools,
65
66
  getTopUsedTools,
66
67
  installFlushOnExit
67
- } from "./chunk-J22B3OSQ.js";
68
+ } from "./chunk-STIEOOOL.js";
68
69
  import {
69
70
  CONTENT_ONLY_STREAM_REMINDER,
70
71
  TEE_FINAL_USER_NUDGE,
@@ -86,7 +87,7 @@ import {
86
87
  } from "./chunk-XPBEJB27.js";
87
88
  import {
88
89
  ConfigManager
89
- } from "./chunk-TM4MS63K.js";
90
+ } from "./chunk-DUZRQXIP.js";
90
91
  import {
91
92
  AuthError,
92
93
  ProviderError,
@@ -113,7 +114,7 @@ import {
113
114
  SKILLS_DIR_NAME,
114
115
  VERSION,
115
116
  buildUserIdentityPrompt
116
- } from "./chunk-KV4GYNEA.js";
117
+ } from "./chunk-UPMBIS4T.js";
117
118
  import {
118
119
  formatGitContextForPrompt,
119
120
  getGitContext,
@@ -133,7 +134,7 @@ import {
133
134
  DEFAULT_PATTERNS,
134
135
  scanString
135
136
  } from "./chunk-SLSWPBK3.js";
136
- import "./chunk-O6UFCEUZ.js";
137
+ import "./chunk-K3CF65QH.js";
137
138
  import "./chunk-CKH4KQ4E.js";
138
139
  import {
139
140
  atomicWriteFileSync
@@ -637,7 +638,7 @@ Error${typeName}: ${lines.join("\n")}
637
638
  };
638
639
 
639
640
  // src/repl/commands/index.ts
640
- import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync3, appendFileSync } from "fs";
641
+ import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync3 } from "fs";
641
642
  import { execSync as execSync2 } from "child_process";
642
643
  import { platform } from "os";
643
644
  import { resolve, dirname as dirname2, join as join3, basename } from "path";
@@ -1832,7 +1833,7 @@ No tools match "${filter}".
1832
1833
  const { join: join6 } = await import("path");
1833
1834
  const { existsSync: existsSync6 } = await import("fs");
1834
1835
  const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
1835
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-SZTQNN7K.js");
1836
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-VTZLKDAG.js");
1836
1837
  const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
1837
1838
  const cwd = process.cwd();
1838
1839
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2416,8 +2417,7 @@ ${hint}` : "")
2416
2417
  const detailed = args.includes("--detailed");
2417
2418
  let diff;
2418
2419
  try {
2419
- const cmd = staged ? "git diff --staged" : "git diff";
2420
- diff = execSync2(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
2420
+ diff = readGitDiff({ staged });
2421
2421
  } catch {
2422
2422
  ctx.renderer.renderError("Failed to run git diff.");
2423
2423
  return;
@@ -2463,8 +2463,7 @@ ${hint}` : "")
2463
2463
  const staged = args.includes("--staged");
2464
2464
  let diff;
2465
2465
  try {
2466
- const cmd = staged ? "git diff --staged" : "git diff";
2467
- diff = execSync2(cmd, { encoding: "utf-8", timeout: 1e4 }).trim();
2466
+ diff = readGitDiff({ staged });
2468
2467
  } catch {
2469
2468
  ctx.renderer.renderError("Failed to run git diff.");
2470
2469
  return;
@@ -2767,7 +2766,7 @@ ${hint}` : "")
2767
2766
  const sub = (args[0] ?? "status").toLowerCase();
2768
2767
  const root = process.cwd();
2769
2768
  const { loadIndex, clearIndex } = await import("./store-MWNHVGJT.js");
2770
- const { indexProject } = await import("./indexer-AKWMYNJI.js");
2769
+ const { indexProject } = await import("./indexer-2AG4G6B5.js");
2771
2770
  const { loadVectorStore, clearVectorStore } = await import("./vector-store-BBDXB5IQ.js");
2772
2771
  if (sub === "status") {
2773
2772
  const idx = loadIndex(root);
@@ -2893,7 +2892,7 @@ ${hint}` : "")
2893
2892
  usage: "/test [command|filter]",
2894
2893
  async execute(args, ctx) {
2895
2894
  try {
2896
- const { executeTests } = await import("./run-tests-D5SNUBYX.js");
2895
+ const { executeTests } = await import("./run-tests-NDS2IEMK.js");
2897
2896
  const argStr = args.join(" ").trim();
2898
2897
  let testArgs = {};
2899
2898
  if (argStr) {
@@ -3164,7 +3163,8 @@ ${text}
3164
3163
  `;
3165
3164
  try {
3166
3165
  mkdirSync2(dirname2(memoryFile), { recursive: true });
3167
- appendFileSync(memoryFile, entry, "utf-8");
3166
+ const previous = existsSync3(memoryFile) ? readFileSync2(memoryFile, "utf-8") : "";
3167
+ atomicWriteFileSync(memoryFile, previous + entry);
3168
3168
  ctx.renderer.printSuccess(`Added to memory: "${text.slice(0, 60)}${text.length > 60 ? "\u2026" : ""}"`);
3169
3169
  } catch (err) {
3170
3170
  ctx.renderer.renderError(`Failed to write memory: ${err instanceof Error ? err.message : String(err)}`);
@@ -3175,7 +3175,7 @@ ${text}
3175
3175
  return;
3176
3176
  }
3177
3177
  try {
3178
- writeFileSync(memoryFile, "", "utf-8");
3178
+ atomicWriteFileSync(memoryFile, "");
3179
3179
  ctx.renderer.printSuccess("Memory cleared (memory.md emptied)");
3180
3180
  } catch (err) {
3181
3181
  ctx.renderer.renderError(`Failed to clear memory: ${err instanceof Error ? err.message : String(err)}`);
@@ -4203,7 +4203,6 @@ Managing ${displayName} API Key`);
4203
4203
  // src/repl/custom-commands.ts
4204
4204
  import { existsSync as existsSync4, readFileSync as readFileSync3, readdirSync as readdirSync2, mkdirSync as mkdirSync3 } from "fs";
4205
4205
  import { join as join4, extname } from "path";
4206
- import { execSync as execSync3 } from "child_process";
4207
4206
  function parseCommandFile(filePath) {
4208
4207
  let content;
4209
4208
  try {
@@ -4238,7 +4237,7 @@ function expandTemplate(template, args) {
4238
4237
  });
4239
4238
  result = result.replace(/\{\{git-diff\}\}/g, () => {
4240
4239
  try {
4241
- return execSync3("git diff", { encoding: "utf-8", timeout: 1e4 }).trim();
4240
+ return readGitDiff();
4242
4241
  } catch {
4243
4242
  return "[No git diff available]";
4244
4243
  }
@@ -5467,7 +5466,7 @@ Session '${this.resumeSessionId}' not found.
5467
5466
  }
5468
5467
  void (async () => {
5469
5468
  try {
5470
- const { indexProject } = await import("./indexer-AKWMYNJI.js");
5469
+ const { indexProject } = await import("./indexer-2AG4G6B5.js");
5471
5470
  const { loadIndex } = await import("./store-MWNHVGJT.js");
5472
5471
  const root = process.cwd();
5473
5472
  const existed = loadIndex(root);
@@ -7271,7 +7270,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7271
7270
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7272
7271
  process.exit(1);
7273
7272
  }
7274
- const { startWebServer } = await import("./server-4EFTRFTN.js");
7273
+ const { startWebServer } = await import("./server-4URLNC7P.js");
7275
7274
  await startWebServer({ port, host: options.host });
7276
7275
  });
7277
7276
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
@@ -7438,16 +7437,16 @@ program.command("sessions").description("List recent conversation sessions").opt
7438
7437
  console.log(footer + "\n");
7439
7438
  });
7440
7439
  program.command("usage").description("Show token + cost usage grouped by provider/model (cross-session)").option("--days <n>", "Only the last N days (inclusive of today)").option("--month <ym>", "Only a specific month, format YYYY-MM (e.g. 2026-06)").option("--json", "Output as JSON (for scripting)").action(async (options) => {
7441
- const { runUsageCli } = await import("./usage-Q24E5636.js");
7440
+ const { runUsageCli } = await import("./usage-ZNCKGF6U.js");
7442
7441
  await runUsageCli(options);
7443
7442
  });
7444
7443
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
7445
- const { runDoctorCli } = await import("./doctor-cli-I2Y2YR4V.js");
7444
+ const { runDoctorCli } = await import("./doctor-cli-IU6FSVLF.js");
7446
7445
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7447
7446
  });
7448
7447
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
7449
7448
  try {
7450
- const batch = await import("./batch-3T44NFLG.js");
7449
+ const batch = await import("./batch-45WLJUVP.js");
7451
7450
  switch (action) {
7452
7451
  case "submit":
7453
7452
  if (!arg) {
@@ -7490,7 +7489,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7490
7489
  }
7491
7490
  });
7492
7491
  program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
7493
- const { startMcpServer } = await import("./server-PVKLPRUP.js");
7492
+ const { startMcpServer } = await import("./server-72SAPLPS.js");
7494
7493
  await startMcpServer({
7495
7494
  allowDestructive: !!options.allowDestructive,
7496
7495
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7499,7 +7498,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7499
7498
  });
7500
7499
  });
7501
7500
  program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).option("--base <ref>", "Base ref for `git diff <ref>...HEAD` (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").action(async (options) => {
7502
- const { runCi } = await import("./ci-6QWBVRJX.js");
7501
+ const { runCi } = await import("./ci-PUE3MQ7J.js");
7503
7502
  const result = await runCi({
7504
7503
  pr: options.pr,
7505
7504
  base: options.base,
@@ -7645,7 +7644,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7645
7644
  }),
7646
7645
  config.get("customProviders")
7647
7646
  );
7648
- const { startHub } = await import("./hub-XVPFBODB.js");
7647
+ const { startHub } = await import("./hub-4ETK4R2J.js");
7649
7648
  await startHub(
7650
7649
  {
7651
7650
  topic: topic ?? "",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  indexProject,
4
4
  updateFile
5
- } from "./chunk-O6UFCEUZ.js";
5
+ } from "./chunk-K3CF65QH.js";
6
6
  import "./chunk-CKH4KQ4E.js";
7
7
  import "./chunk-IW3Q7AE5.js";
8
8
  export {