jinzd-ai-cli 0.4.189 → 0.4.191

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 (61) hide show
  1. package/dist/{agent-client-25TIQ6AP.js → agent-client-6GX6QQDU.js} +0 -1
  2. package/dist/{auth-OI4YRVRG.js → auth-FSTAKSYF.js} +2 -2
  3. package/dist/{batch-FPPAYC6L.js → batch-4XSN4VF7.js} +7 -15
  4. package/dist/{chat-index-JXTYDRCY.js → chat-index-FDSGKWQV.js} +2 -2
  5. package/dist/{chat-index-WDMVP7BN.js → chat-index-UBCWHBLR.js} +2 -2
  6. package/dist/chunk-6BUTA5VW.js +38 -0
  7. package/dist/{chunk-UTO2YO3K.js → chunk-6Z42O3DN.js} +1 -1
  8. package/dist/{chunk-VRCBXH2W.js → chunk-A4GUGWEY.js} +1 -1
  9. package/dist/{chunk-YKVFZLSI.js → chunk-AEAYUKSY.js} +2 -2
  10. package/dist/{chunk-RFXZQBU4.js → chunk-ASVBZIUE.js} +1 -1
  11. package/dist/{chunk-ZWVIDFGY.js → chunk-BXP6YZ2P.js} +4 -3
  12. package/dist/{chunk-OVWE4E46.js → chunk-CKH4KQ4E.js} +4 -3
  13. package/dist/{chunk-5FV2V3TB.js → chunk-HSQAKOYX.js} +1 -1
  14. package/dist/{chunk-D6U75FHP.js → chunk-IEQAE3QG.js} +4 -3
  15. package/dist/{chunk-TEJ4HYLM.js → chunk-IMSENBJ6.js} +2 -2
  16. package/dist/chunk-IW3Q7AE5.js +40 -0
  17. package/dist/{chunk-IQ7JE43O.js → chunk-JTLPYPT3.js} +48 -4
  18. package/dist/{chunk-GXB7YKF2.js → chunk-JVKAL5Q3.js} +5 -12
  19. package/dist/{chunk-RIVZNS3K.js → chunk-MC34ISJU.js} +5 -4
  20. package/dist/{chunk-VNNYHW6N.js → chunk-O6UFCEUZ.js} +1 -1
  21. package/dist/{chunk-SH73ZVHY.js → chunk-RQ7JVLFM.js} +8 -8
  22. package/dist/{chunk-DQ2OHJNF.js → chunk-RWM2GFRC.js} +5 -3
  23. package/dist/{chunk-SEFOKYYP.js → chunk-SQB66GP6.js} +1 -1
  24. package/dist/{chunk-HDSKW7Q3.js → chunk-T2NL5ZIA.js} +2 -2
  25. package/dist/{chunk-4UZE4ADL.js → chunk-TB4W4Y4T.js} +18 -52
  26. package/dist/{chunk-MH3AFJGV.js → chunk-TRV47UK4.js} +1 -1
  27. package/dist/{chunk-KIGVJVX4.js → chunk-W7UKO3PS.js} +18 -50
  28. package/dist/{chunk-NBZ443LN.js → chunk-XDH5EFWC.js} +1 -1
  29. package/dist/{chunk-3SZ7SREY.js → chunk-Y3PNCW7A.js} +6 -5
  30. package/dist/{chunk-A3I5WP5L.js → chunk-YUBD7T2R.js} +5 -4
  31. package/dist/{ci-CGNVIV6U.js → ci-USJCTRP7.js} +3 -4
  32. package/dist/{constants-EJF3DOM5.js → constants-3T5G34S5.js} +1 -2
  33. package/dist/{doctor-cli-WFH6DYVL.js → doctor-cli-3QE7FZKB.js} +6 -6
  34. package/dist/electron-server.js +101 -99
  35. package/dist/{file-checkpoint-UHSMHCRU.js → file-checkpoint-CGH6OJVI.js} +0 -1
  36. package/dist/{file-checkpoint-ZN7KE3TN.js → file-checkpoint-NKBHGC7L.js} +0 -1
  37. package/dist/{git-context-7KIP4X2V.js → git-context-EXOEHQSF.js} +0 -1
  38. package/dist/{hub-LCB3RGVQ.js → hub-LABDYMAE.js} +3 -4
  39. package/dist/{hub-server-GSTG5MNE.js → hub-server-LJ2JSKZ2.js} +0 -1
  40. package/dist/index.js +78 -121
  41. package/dist/{indexer-S6UMGQKA.js → indexer-AKWMYNJI.js} +3 -3
  42. package/dist/indexer-BMYUUDLH.js +10 -0
  43. package/dist/{persist-A3R2IAYU.js → persist-L54DPLI7.js} +3 -3
  44. package/dist/{project-trust-EBGHD7LE.js → project-trust-MUG325AW.js} +4 -11
  45. package/dist/{project-trust-IFM7FXEV.js → project-trust-NKYHL3VZ.js} +4 -11
  46. package/dist/{run-tests-XANJLGXT.js → run-tests-H3VCHOJB.js} +1 -2
  47. package/dist/{run-tests-R7QATG6O.js → run-tests-X2MCBIKN.js} +2 -3
  48. package/dist/{semantic-GJJWTI3A.js → semantic-FF6DDJI6.js} +4 -4
  49. package/dist/{semantic-FKOEXY75.js → semantic-PK7AUOJT.js} +4 -4
  50. package/dist/{server-HYLAZODW.js → server-FE7XTYVC.js} +10 -10
  51. package/dist/{server-ULMPX3CS.js → server-TJDKEECG.js} +40 -74
  52. package/dist/{store-VMK543OQ.js → store-MWNHVGJT.js} +2 -2
  53. package/dist/{store-A3TZM6PS.js → store-VO37H6LS.js} +2 -2
  54. package/dist/{task-orchestrator-UKU2O6IE.js → task-orchestrator-VFCQGTYA.js} +14 -14
  55. package/dist/{usage-4R36JZFP.js → usage-FYKIOPJI.js} +4 -4
  56. package/dist/{vector-store-Z5OF4WWJ.js → vector-store-BBDXB5IQ.js} +2 -2
  57. package/dist/{vector-store-PLDSXF3V.js → vector-store-JBAE6PS4.js} +2 -2
  58. package/package.json +1 -1
  59. package/dist/chunk-3RG5ZIWI.js +0 -10
  60. package/dist/chunk-PDX44BCA.js +0 -11
  61. package/dist/indexer-ISSNIFQY.js +0 -10
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-PDX44BCA.js";
3
2
 
4
3
  // src/hub/agent-client.ts
5
4
  import WebSocket from "ws";
@@ -3,8 +3,8 @@ import {
3
3
  AuthManager,
4
4
  TOKEN_EXPIRY_MS,
5
5
  __resetLoginAttemptsForTests
6
- } from "./chunk-GXB7YKF2.js";
7
- import "./chunk-PDX44BCA.js";
6
+ } from "./chunk-JVKAL5Q3.js";
7
+ import "./chunk-IW3Q7AE5.js";
8
8
  export {
9
9
  AuthManager,
10
10
  TOKEN_EXPIRY_MS,
@@ -1,14 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-NBZ443LN.js";
4
+ } from "./chunk-XDH5EFWC.js";
5
5
  import "./chunk-TZQHYZKT.js";
6
- import "./chunk-RFXZQBU4.js";
7
- import "./chunk-PDX44BCA.js";
6
+ import "./chunk-ASVBZIUE.js";
7
+ import {
8
+ atomicWriteFileSync
9
+ } from "./chunk-IW3Q7AE5.js";
8
10
 
9
11
  // src/cli/batch.ts
10
12
  import Anthropic from "@anthropic-ai/sdk";
11
- import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, unlinkSync } from "fs";
13
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
12
14
  import { join } from "path";
13
15
  function parseBatchInput(jsonl) {
14
16
  const lines = jsonl.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -74,17 +76,7 @@ function loadTrackedBatches(config) {
74
76
  function saveTrackedBatches(config, batches) {
75
77
  mkdirSync(config.getConfigDir(), { recursive: true });
76
78
  const finalPath = getBatchesPath(config);
77
- const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
78
- try {
79
- writeFileSync(tmpPath, JSON.stringify({ batches }, null, 2), "utf-8");
80
- renameSync(tmpPath, finalPath);
81
- } catch (err) {
82
- try {
83
- unlinkSync(tmpPath);
84
- } catch {
85
- }
86
- throw err;
87
- }
79
+ atomicWriteFileSync(finalPath, JSON.stringify({ batches }, null, 2));
88
80
  }
89
81
  function getClaudeClient(config) {
90
82
  const apiKey = config.getApiKey("claude");
@@ -6,10 +6,10 @@ import {
6
6
  getChatIndexStatus,
7
7
  loadChatIndex,
8
8
  searchChatMemory
9
- } from "./chunk-4UZE4ADL.js";
9
+ } from "./chunk-TB4W4Y4T.js";
10
10
  import "./chunk-KHYD3WXE.js";
11
11
  import "./chunk-SLSWPBK3.js";
12
- import "./chunk-PDX44BCA.js";
12
+ import "./chunk-IW3Q7AE5.js";
13
13
  export {
14
14
  buildChatIndex,
15
15
  chunkSession,
@@ -5,9 +5,9 @@ import {
5
5
  getChatIndexStatus,
6
6
  loadChatIndex,
7
7
  searchChatMemory
8
- } from "./chunk-KIGVJVX4.js";
8
+ } from "./chunk-W7UKO3PS.js";
9
9
  import "./chunk-JV5N65KN.js";
10
- import "./chunk-3RG5ZIWI.js";
10
+ import "./chunk-6BUTA5VW.js";
11
11
  export {
12
12
  buildChatIndex,
13
13
  chunkSession,
@@ -0,0 +1,38 @@
1
+ // src/core/atomic-write.ts
2
+ import fs from "fs";
3
+ var RETRYABLE_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
4
+ var MAX_RENAME_RETRIES = 10;
5
+ function sleepSync(ms) {
6
+ const sab = new Int32Array(new SharedArrayBuffer(4));
7
+ Atomics.wait(sab, 0, 0, ms);
8
+ }
9
+ function atomicWriteFileSync(target, data) {
10
+ const tmp = `${target}.tmp`;
11
+ fs.writeFileSync(tmp, data);
12
+ for (let attempt = 0; ; attempt++) {
13
+ try {
14
+ fs.renameSync(tmp, target);
15
+ return;
16
+ } catch (err) {
17
+ const code = err.code;
18
+ if (attempt < MAX_RENAME_RETRIES && code && RETRYABLE_CODES.has(code)) {
19
+ sleepSync(5 * (attempt + 1));
20
+ continue;
21
+ }
22
+ try {
23
+ fs.writeFileSync(target, data);
24
+ try {
25
+ fs.unlinkSync(tmp);
26
+ } catch {
27
+ }
28
+ return;
29
+ } catch {
30
+ throw err;
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ export {
37
+ atomicWriteFileSync
38
+ };
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.189";
9
+ var VERSION = "0.4.191";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SessionManager
4
- } from "./chunk-RIVZNS3K.js";
4
+ } from "./chunk-MC34ISJU.js";
5
5
 
6
6
  // src/hub/persist.ts
7
7
  import { join } from "path";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  loadIndex
3
- } from "./chunk-DQ2OHJNF.js";
3
+ } from "./chunk-RWM2GFRC.js";
4
4
  import {
5
5
  loadVectorStore,
6
6
  saveVectorStore,
7
7
  searchVectorStore
8
- } from "./chunk-D6U75FHP.js";
8
+ } from "./chunk-IEQAE3QG.js";
9
9
  import {
10
10
  EMBEDDING_DIM,
11
11
  embed,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.189";
4
+ var VERSION = "0.4.191";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -2,6 +2,9 @@
2
2
  import {
3
3
  EMBEDDING_DIM
4
4
  } from "./chunk-KHYD3WXE.js";
5
+ import {
6
+ atomicWriteFileSync
7
+ } from "./chunk-IW3Q7AE5.js";
5
8
 
6
9
  // src/symbols/vector-store.ts
7
10
  import fs from "fs";
@@ -47,9 +50,7 @@ function saveVectorStore(root, indices, vectors) {
47
50
  Buffer.from(indices.buffer, indices.byteOffset, indices.byteLength).copy(buf, HEADER_BYTES);
48
51
  Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength).copy(buf, HEADER_BYTES + count * 4);
49
52
  const target = vecPath(root);
50
- const tmp = `${target}.tmp`;
51
- fs.writeFileSync(tmp, buf);
52
- fs.renameSync(tmp, target);
53
+ atomicWriteFileSync(target, buf);
53
54
  }
54
55
  function loadVectorStore(root) {
55
56
  const p = vecPath(root);
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ atomicWriteFileSync
4
+ } from "./chunk-IW3Q7AE5.js";
2
5
 
3
6
  // src/symbols/store.ts
4
7
  import fs from "fs";
@@ -75,9 +78,7 @@ function saveIndex(index) {
75
78
  const dir = indexDir();
76
79
  fs.mkdirSync(dir, { recursive: true });
77
80
  const target = indexPath(index.root);
78
- const tmp = `${target}.tmp`;
79
- fs.writeFileSync(tmp, JSON.stringify(index), "utf-8");
80
- fs.renameSync(tmp, target);
81
+ atomicWriteFileSync(target, JSON.stringify(index));
81
82
  }
82
83
  function clearIndex(root) {
83
84
  const p = indexPath(root);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-RFXZQBU4.js";
4
+ } from "./chunk-ASVBZIUE.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  EMBEDDING_DIM
3
3
  } from "./chunk-JV5N65KN.js";
4
+ import {
5
+ atomicWriteFileSync
6
+ } from "./chunk-6BUTA5VW.js";
4
7
 
5
8
  // src/symbols/vector-store.ts
6
9
  import fs from "fs";
@@ -46,9 +49,7 @@ function saveVectorStore(root, indices, vectors) {
46
49
  Buffer.from(indices.buffer, indices.byteOffset, indices.byteLength).copy(buf, HEADER_BYTES);
47
50
  Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength).copy(buf, HEADER_BYTES + count * 4);
48
51
  const target = vecPath(root);
49
- const tmp = `${target}.tmp`;
50
- fs.writeFileSync(tmp, buf);
51
- fs.renameSync(tmp, target);
52
+ atomicWriteFileSync(target, buf);
52
53
  }
53
54
  function loadVectorStore(root) {
54
55
  const p = vecPath(root);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-SH73ZVHY.js";
4
+ } from "./chunk-RQ7JVLFM.js";
5
5
  import {
6
6
  APP_NAME,
7
7
  CONFIG_DIR_NAME,
@@ -11,7 +11,7 @@ import {
11
11
  MCP_PROTOCOL_VERSION,
12
12
  MCP_TOOL_PREFIX,
13
13
  VERSION
14
- } from "./chunk-RFXZQBU4.js";
14
+ } from "./chunk-ASVBZIUE.js";
15
15
 
16
16
  // src/mcp/client.ts
17
17
  import { spawn } from "child_process";
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/core/atomic-write.ts
4
+ import fs from "fs";
5
+ var RETRYABLE_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
6
+ var MAX_RENAME_RETRIES = 10;
7
+ function sleepSync(ms) {
8
+ const sab = new Int32Array(new SharedArrayBuffer(4));
9
+ Atomics.wait(sab, 0, 0, ms);
10
+ }
11
+ function atomicWriteFileSync(target, data) {
12
+ const tmp = `${target}.tmp`;
13
+ fs.writeFileSync(tmp, data);
14
+ for (let attempt = 0; ; attempt++) {
15
+ try {
16
+ fs.renameSync(tmp, target);
17
+ return;
18
+ } catch (err) {
19
+ const code = err.code;
20
+ if (attempt < MAX_RENAME_RETRIES && code && RETRYABLE_CODES.has(code)) {
21
+ sleepSync(5 * (attempt + 1));
22
+ continue;
23
+ }
24
+ try {
25
+ fs.writeFileSync(target, data);
26
+ try {
27
+ fs.unlinkSync(tmp);
28
+ } catch {
29
+ }
30
+ return;
31
+ } catch {
32
+ throw err;
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ export {
39
+ atomicWriteFileSync
40
+ };
@@ -1320,6 +1320,52 @@ You are now in a CONTENT-ONLY streaming pass. The file at the configured path wi
1320
1320
  - If you accidentally start a <tool_call>, STOP and produce the document body instead.
1321
1321
 
1322
1322
  The file is closed and named when this stream ends. If your output contains pseudo-tool-call markup, the save will be REJECTED and you will be asked to retry.`;
1323
+ function teeFileStats(content) {
1324
+ return { lines: content.split("\n").length, bytes: Buffer.byteLength(content, "utf-8") };
1325
+ }
1326
+ function evaluateTeeContent(rawContent, saveToFile) {
1327
+ const metaMatch = detectMetaNarration(rawContent);
1328
+ if (metaMatch) {
1329
+ return {
1330
+ kind: "reject",
1331
+ reason: "meta-narration",
1332
+ matched: metaMatch,
1333
+ summary: `[save_last_response REJECTED] Your output was internal reasoning / meta-narration (e.g. "Let me re-read\u2026", "the user is asking me to\u2026") instead of the requested document body (matched: ${metaMatch}). ${saveToFile} was NOT saved.
1334
+
1335
+ This fresh stream has NO tools. Produce ONLY the document body: start with a markdown heading like "# \u5BA1\u8BA1\u62A5\u544A" / "# Audit Report" and write the full content. Do NOT narrate that you will produce the document \u2014 produce it.`
1336
+ };
1337
+ }
1338
+ const pseudoMatch = detectPseudoToolCalls(rawContent);
1339
+ if (pseudoMatch) {
1340
+ const cleaned = stripPseudoToolCalls(rawContent);
1341
+ if (looksLikeDocumentBody(cleaned)) {
1342
+ const { lines: lines2, bytes: bytes2 } = teeFileStats(cleaned);
1343
+ return {
1344
+ kind: "salvaged",
1345
+ content: cleaned,
1346
+ matched: pseudoMatch,
1347
+ summary: `File saved (with cleanup): ${saveToFile} (${lines2} lines, ${bytes2} bytes; pseudo-tool-call markup matching ${pseudoMatch} was stripped before save)`
1348
+ };
1349
+ }
1350
+ return {
1351
+ kind: "reject",
1352
+ reason: "pseudo-tool-call",
1353
+ matched: pseudoMatch,
1354
+ summary: `[save_last_response REJECTED] Your output was tool-call markup with no usable document body (matched: ${pseudoMatch}). ${saveToFile} was NOT saved.
1355
+
1356
+ This fresh stream has NO tools \u2014 output is captured verbatim. STOP emitting <tool_call>, <function_calls>, <invoke>, <think>, or JSON tool blocks. Produce the document body NOW: start with a markdown heading like "# \u5BA1\u8BA1\u62A5\u544A" and write the full report.`
1357
+ };
1358
+ }
1359
+ const { lines, bytes } = teeFileStats(rawContent);
1360
+ return {
1361
+ kind: "ok",
1362
+ content: rawContent,
1363
+ summary: `File saved: ${saveToFile} (${lines} lines, ${bytes} bytes)`
1364
+ };
1365
+ }
1366
+ function teeStreamErrorSummary(saveToFile, errMsg) {
1367
+ return `[save_last_response failed] streaming was interrupted: ${errMsg}. ${saveToFile} (partial) was deleted. Retry \u2014 and consider producing a more compact output (split very large reports across multiple save_last_response calls if the previous attempt timed out).`;
1368
+ }
1323
1369
 
1324
1370
  // src/core/agent-loop.ts
1325
1371
  function partialTagTail(s, tag) {
@@ -3125,13 +3171,11 @@ export {
3125
3171
  TOOL_CALL_REMINDER,
3126
3172
  buildWriteRoundReminder,
3127
3173
  extractWrittenFilePaths,
3128
- detectPseudoToolCalls,
3129
- stripPseudoToolCalls,
3130
- detectMetaNarration,
3131
- looksLikeDocumentBody,
3132
3174
  stripToolCallReminder,
3133
3175
  TEE_FINAL_USER_NUDGE,
3134
3176
  CONTENT_ONLY_STREAM_REMINDER,
3177
+ evaluateTeeContent,
3178
+ teeStreamErrorSummary,
3135
3179
  ThinkTagFilter,
3136
3180
  consumeToolCallStream,
3137
3181
  accumulateUsage,
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ atomicWriteFileSync
4
+ } from "./chunk-IW3Q7AE5.js";
2
5
 
3
6
  // src/web/auth.ts
4
- import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, copyFileSync, renameSync, unlinkSync } from "fs";
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, copyFileSync } from "fs";
5
8
  import { join } from "path";
6
9
  import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
7
10
  var USERS_FILE = "users.json";
@@ -255,17 +258,7 @@ var AuthManager = class {
255
258
  }
256
259
  saveDB(db) {
257
260
  mkdirSync(this.baseDir, { recursive: true });
258
- const tmp = `${this.usersFile}.tmp`;
259
- try {
260
- writeFileSync(tmp, JSON.stringify(db, null, 2), "utf-8");
261
- renameSync(tmp, this.usersFile);
262
- } catch (err) {
263
- try {
264
- unlinkSync(tmp);
265
- } catch {
266
- }
267
- throw err;
268
- }
261
+ atomicWriteFileSync(this.usersFile, JSON.stringify(db, null, 2));
269
262
  }
270
263
  /** Legacy hash — kept only for migrating old users (v0.2.x) */
271
264
  hashPasswordLegacy(password, salt) {
@@ -2,9 +2,12 @@
2
2
  import {
3
3
  redactJson
4
4
  } from "./chunk-SLSWPBK3.js";
5
+ import {
6
+ atomicWriteFileSync
7
+ } from "./chunk-IW3Q7AE5.js";
5
8
 
6
9
  // src/session/session-manager.ts
7
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync, renameSync, openSync, readSync, closeSync } from "fs";
10
+ import { readFileSync, existsSync, mkdirSync, readdirSync, unlinkSync, openSync, readSync, closeSync } from "fs";
8
11
  import { join } from "path";
9
12
  import { v4 as uuidv4 } from "uuid";
10
13
 
@@ -590,9 +593,7 @@ var SessionManager = class {
590
593
  const opts = this.redactOptionsForSave();
591
594
  const { value: payload, hits } = redactJson(raw, opts);
592
595
  this.lastRedactionHits = hits.length;
593
- const tmpPath = filePath + ".tmp";
594
- writeFileSync(tmpPath, JSON.stringify(payload, null, 2), "utf-8");
595
- renameSync(tmpPath, filePath);
596
+ atomicWriteFileSync(filePath, JSON.stringify(payload, null, 2));
596
597
  }
597
598
  loadSession(id) {
598
599
  const filePath = join(this.historyDir, `${id}.json`);
@@ -6,7 +6,7 @@ import {
6
6
  removeFile,
7
7
  saveIndex,
8
8
  upsertFileSymbols
9
- } from "./chunk-OVWE4E46.js";
9
+ } from "./chunk-CKH4KQ4E.js";
10
10
 
11
11
  // src/symbols/indexer.ts
12
12
  import fs2 from "fs";
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  hasSemanticIndex,
4
4
  semanticSearch
5
- } from "./chunk-HDSKW7Q3.js";
5
+ } from "./chunk-T2NL5ZIA.js";
6
6
  import {
7
7
  runTestsTool
8
- } from "./chunk-5FV2V3TB.js";
8
+ } from "./chunk-HSQAKOYX.js";
9
9
  import {
10
10
  runTool
11
- } from "./chunk-3SZ7SREY.js";
11
+ } from "./chunk-Y3PNCW7A.js";
12
12
  import {
13
13
  getDangerLevel,
14
14
  isFileWriteTool
@@ -25,20 +25,20 @@ import {
25
25
  SUBAGENT_ALLOWED_TOOLS,
26
26
  SUBAGENT_DEFAULT_MAX_ROUNDS,
27
27
  SUBAGENT_MAX_ROUNDS_LIMIT
28
- } from "./chunk-RFXZQBU4.js";
28
+ } from "./chunk-ASVBZIUE.js";
29
29
  import {
30
30
  fileCheckpoints
31
31
  } from "./chunk-4BKXL7SM.js";
32
32
  import {
33
33
  loadChatIndex,
34
34
  searchChatMemory
35
- } from "./chunk-4UZE4ADL.js";
35
+ } from "./chunk-TB4W4Y4T.js";
36
36
  import {
37
37
  indexProject
38
- } from "./chunk-VNNYHW6N.js";
38
+ } from "./chunk-O6UFCEUZ.js";
39
39
  import {
40
40
  loadIndex
41
- } from "./chunk-OVWE4E46.js";
41
+ } from "./chunk-CKH4KQ4E.js";
42
42
 
43
43
  // src/tools/builtin/bash.ts
44
44
  import { spawn } from "child_process";
@@ -2089,7 +2089,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
2089
2089
  const mode = appendMode ? "appended" : "written";
2090
2090
  void (async () => {
2091
2091
  try {
2092
- const { updateFile } = await import("./indexer-S6UMGQKA.js");
2092
+ const { updateFile } = await import("./indexer-AKWMYNJI.js");
2093
2093
  await updateFile(process.cwd(), filePath);
2094
2094
  } catch {
2095
2095
  }
@@ -1,3 +1,7 @@
1
+ import {
2
+ atomicWriteFileSync
3
+ } from "./chunk-6BUTA5VW.js";
4
+
1
5
  // src/symbols/store.ts
2
6
  import fs from "fs";
3
7
  import path from "path";
@@ -73,9 +77,7 @@ function saveIndex(index) {
73
77
  const dir = indexDir();
74
78
  fs.mkdirSync(dir, { recursive: true });
75
79
  const target = indexPath(index.root);
76
- const tmp = `${target}.tmp`;
77
- fs.writeFileSync(tmp, JSON.stringify(index), "utf-8");
78
- fs.renameSync(tmp, target);
80
+ atomicWriteFileSync(target, JSON.stringify(index));
79
81
  }
80
82
  function clearIndex(root) {
81
83
  const p = indexPath(root);
@@ -5,7 +5,7 @@ import {
5
5
  removeFile,
6
6
  saveIndex,
7
7
  upsertFileSymbols
8
- } from "./chunk-DQ2OHJNF.js";
8
+ } from "./chunk-RWM2GFRC.js";
9
9
 
10
10
  // src/symbols/indexer.ts
11
11
  import fs2 from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  loadVectorStore,
4
4
  saveVectorStore,
5
5
  searchVectorStore
6
- } from "./chunk-ZWVIDFGY.js";
6
+ } from "./chunk-BXP6YZ2P.js";
7
7
  import {
8
8
  EMBEDDING_DIM,
9
9
  embed,
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-KHYD3WXE.js";
12
12
  import {
13
13
  loadIndex
14
- } from "./chunk-OVWE4E46.js";
14
+ } from "./chunk-CKH4KQ4E.js";
15
15
 
16
16
  // src/symbols/semantic.ts
17
17
  function pathTokens(absFile, root) {