chatlab-cli 0.37.1 → 0.37.3

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 (153) hide show
  1. package/dist/{chat-command-YAFRLHMQ.mjs → chat-command-RQC44FPF.mjs} +53 -13
  2. package/dist/chat-command-RQC44FPF.mjs.map +1 -0
  3. package/dist/{chunk-FPVRSXQ4.mjs → chunk-4FAEB4C2.mjs} +12 -12
  4. package/dist/{chunk-MMTEGUQA.mjs → chunk-5OA4QI3Q.mjs} +3 -3
  5. package/dist/{chunk-UP6JIV3S.mjs → chunk-E2ZFGNZQ.mjs} +16 -12
  6. package/dist/chunk-E2ZFGNZQ.mjs.map +1 -0
  7. package/dist/{chunk-JWJREWVN.mjs → chunk-E6IRRNBQ.mjs} +27 -3
  8. package/dist/chunk-E6IRRNBQ.mjs.map +1 -0
  9. package/dist/{chunk-PDQV4RUA.mjs → chunk-GDKQKHJT.mjs} +2 -2
  10. package/dist/{chunk-GKCIRKOH.mjs → chunk-HJWBFHNR.mjs} +4 -4
  11. package/dist/{chunk-73TJ2S7W.mjs → chunk-IDDTW5JN.mjs} +313 -24
  12. package/dist/chunk-IDDTW5JN.mjs.map +1 -0
  13. package/dist/{chunk-2PY4XCH3.mjs → chunk-IMJVOODY.mjs} +2 -2
  14. package/dist/{chunk-ARIBCH47.mjs → chunk-LUENE6L7.mjs} +25 -15
  15. package/dist/chunk-LUENE6L7.mjs.map +1 -0
  16. package/dist/{chunk-WDLO7OLX.mjs → chunk-O57SQSCO.mjs} +2 -2
  17. package/dist/{chunk-N4SB6QZV.mjs → chunk-ZGXXAPLX.mjs} +2 -2
  18. package/dist/{chunk-OTYNMDDL.mjs → chunk-ZOHSWBD2.mjs} +2237 -1977
  19. package/dist/chunk-ZOHSWBD2.mjs.map +1 -0
  20. package/dist/cli.mjs +9 -9
  21. package/dist/contacts-worker.mjs +2 -2
  22. package/dist/global-insight-worker.mjs +1 -1
  23. package/dist/{http-LPFPVTBC.mjs → http-QJDZKDNJ.mjs} +12 -12
  24. package/dist/{import-T4WX2ZJL.mjs → import-XK6YM26A.mjs} +7 -7
  25. package/dist/index.mjs +12 -12
  26. package/dist/{mcp-SMF3NWIN.mjs → mcp-DMGZFSYN.mjs} +24 -17
  27. package/dist/mcp-DMGZFSYN.mjs.map +1 -0
  28. package/dist/people-relationships-worker.mjs +2 -2
  29. package/dist/semantic-index-worker.mjs +1 -1
  30. package/dist/{src-EGLLMTAU.mjs → src-4AHJUFCW.mjs} +6 -6
  31. package/dist/{stream-import-2BXJTTCE.mjs → stream-import-7VQVT5ST.mjs} +7 -7
  32. package/dist/{worker-runtime-RDLSPXFT.mjs → worker-runtime-PQBAV75N.mjs} +5 -5
  33. package/dist-cli-web/assets/{AISettingsTab-CEhrXlYR.js → AISettingsTab-qS3XKnvh.js} +1 -1
  34. package/dist-cli-web/assets/{AboutTab-Bbu0SsMM.js → AboutTab-K-i40dPv.js} +1 -1
  35. package/dist-cli-web/assets/{Alert-510jTN3l.js → Alert-GSvA5B7J.js} +1 -1
  36. package/dist-cli-web/assets/{ApiSettingsTab-Bi1GRMN4.js → ApiSettingsTab-DIVGTR3g.js} +1 -1
  37. package/dist-cli-web/assets/{BatchManageTab-DhnqMCSM.js → BatchManageTab-CJhwvYWV.js} +1 -1
  38. package/dist-cli-web/assets/{BufferResource-CKZxnACp.js → BufferResource-Cjm0m7sF.js} +1 -1
  39. package/dist-cli-web/assets/{CanvasRenderer-BeK5POBy.js → CanvasRenderer-C-fmrahh.js} +1 -1
  40. package/dist-cli-web/assets/{CardDecoration-RuBA3N2j.js → CardDecoration-Cz54ZPyh.js} +1 -1
  41. package/dist-cli-web/assets/{ChatRecordDrawer-BY_-lIEj.js → ChatRecordDrawer-Cst8zTUv.js} +1 -1
  42. package/dist-cli-web/assets/{ChatRecordWorkspace-7prKd-Tq.js → ChatRecordWorkspace-DKVKaimw.js} +1 -1
  43. package/dist-cli-web/assets/{Checkbox-_eH64bb0.js → Checkbox-CrlY3jiJ.js} +1 -1
  44. package/dist-cli-web/assets/{DataDirCleanupNotice-BHaXwlfr.js → DataDirCleanupNotice-Cjqiub4e.js} +1 -1
  45. package/dist-cli-web/assets/{DatePicker.vue_vue_type_script_setup_true_lang-D9Ul_GYz.js → DatePicker.vue_vue_type_script_setup_true_lang-BYY2UmPA.js} +1 -1
  46. package/dist-cli-web/assets/{DebugToolsPanel-ByKItGrS.js → DebugToolsPanel-I00RV_Lr.js} +1 -1
  47. package/dist-cli-web/assets/{EChart.vue_vue_type_script_setup_true_lang-DubnuUXI.js → EChart.vue_vue_type_script_setup_true_lang-CRTZh9kh.js} +1 -1
  48. package/dist-cli-web/assets/{EChartBar.vue_vue_type_script_setup_true_lang-DKNCZuFm.js → EChartBar.vue_vue_type_script_setup_true_lang-DjDFhnN9.js} +1 -1
  49. package/dist-cli-web/assets/{EChartLine.vue_vue_type_script_setup_true_lang-Fl7xAOSR.js → EChartLine.vue_vue_type_script_setup_true_lang-BLqlW9E4.js} +1 -1
  50. package/dist-cli-web/assets/{EChartWordcloud-C6XM4KOX.js → EChartWordcloud-ChKJM8bU.js} +1 -1
  51. package/dist-cli-web/assets/{FileDropZone.vue_vue_type_script_setup_true_lang-DYDdRSNE.js → FileDropZone.vue_vue_type_script_setup_true_lang-CsRmQhVQ.js} +1 -1
  52. package/dist-cli-web/assets/{Filter-CByj_rCR.js → Filter-Duzxgudo.js} +1 -1
  53. package/dist-cli-web/assets/{GlobalTaskBar-BdELjzrs.js → GlobalTaskBar-DL0IJxlt.js} +1 -1
  54. package/dist-cli-web/assets/{GroupRelationshipGalaxyView-CnzPEgUS.js → GroupRelationshipGalaxyView-BZrB2o2g.js} +1 -1
  55. package/dist-cli-web/assets/{Label-DCIcxkhU.js → Label-CaVKlQnJ.js} +1 -1
  56. package/dist-cli-web/assets/{LoadingState.vue_vue_type_script_setup_true_lang-BBcCt_Qm.js → LoadingState.vue_vue_type_script_setup_true_lang-uF54r-dT.js} +1 -1
  57. package/dist-cli-web/assets/{MessageExportModal-DNU16Bs8.js → MessageExportModal-JpurBsUW.js} +1 -1
  58. package/dist-cli-web/assets/{PageHeader-CKeZjNNR.js → PageHeader-BciykZ_-.js} +1 -1
  59. package/dist-cli-web/assets/{PageTabs.vue_vue_type_script_setup_true_lang-C8M3wNNH.js → PageTabs.vue_vue_type_script_setup_true_lang-2Xe2iUFO.js} +1 -1
  60. package/dist-cli-web/assets/{RelationshipGalaxyCanvas-CDhljGyJ.js → RelationshipGalaxyCanvas-BO5-MowG.js} +3 -3
  61. package/dist-cli-web/assets/{RelationshipGalaxyThreeCanvas-BP8fsvvf.js → RelationshipGalaxyThreeCanvas-Dp4CcWU5.js} +1 -1
  62. package/dist-cli-web/assets/{RenderTargetSystem-D76QrDT_.js → RenderTargetSystem-CfuoUG_y.js} +1 -1
  63. package/dist-cli-web/assets/{RovingFocusItem-BJMUQ5DJ.js → RovingFocusItem-FpYwYEP_.js} +1 -1
  64. package/dist-cli-web/assets/{ScreenCaptureModal-DkX4z-M1.js → ScreenCaptureModal-cElYPaSj.js} +1 -1
  65. package/dist-cli-web/assets/SectionTabs.vue_vue_type_script_setup_true_lang-pVQMbTsj.js +1 -0
  66. package/dist-cli-web/assets/{Select-B5oJc5y1.js → Select-H8Fz6RkU.js} +1 -1
  67. package/dist-cli-web/assets/{SettingsModal-BO-QKQ2h.js → SettingsModal-52Fw4fVW.js} +2 -2
  68. package/dist-cli-web/assets/{StorageTab-CPPXXaRm.js → StorageTab-BnugE5BO.js} +1 -1
  69. package/dist-cli-web/assets/{Switch-CDk3LZ4_.js → Switch-K4aqYC4Y.js} +1 -1
  70. package/dist-cli-web/assets/{Tabs-DqWTBV8x.js → Tabs-BXjD45rO.js} +1 -1
  71. package/dist-cli-web/assets/{Tabs-BMq9wODW.js → Tabs-DJ5p8gb6.js} +1 -1
  72. package/dist-cli-web/assets/{ThemeCard.vue_vue_type_script_setup_true_lang-D2outEOV.js → ThemeCard.vue_vue_type_script_setup_true_lang-BLmTpx4f.js} +1 -1
  73. package/dist-cli-web/assets/{TimeSelect.vue_vue_type_script_setup_true_lang-BcflxP_U.js → TimeSelect.vue_vue_type_script_setup_true_lang-geQAlopO.js} +1 -1
  74. package/dist-cli-web/assets/{VisuallyHiddenInput-BAFpkxMI.js → VisuallyHiddenInput-J2KEIQBX.js} +1 -1
  75. package/dist-cli-web/assets/{WebGLRenderer-DjCPvR_O.js → WebGLRenderer-BDFzRniS.js} +1 -1
  76. package/dist-cli-web/assets/{WebGPURenderer-C2B_u03z.js → WebGPURenderer-BKYZyUCZ.js} +1 -1
  77. package/dist-cli-web/assets/aiChat-CdJzpNYW.js +8 -0
  78. package/dist-cli-web/assets/{base-F6s0vTrr.js → base-129JztT1.js} +1 -1
  79. package/dist-cli-web/assets/{browserAll-DiUAZg4L.js → browserAll-CZNZDK1i.js} +1 -1
  80. package/dist-cli-web/assets/{chatMessages-Bd33SSXI.js → chatMessages-zmzHCUCy.js} +3 -3
  81. package/dist-cli-web/assets/{cli-web-DoibEdj2.js → cli-web-_WGCg-ZY.js} +1 -1
  82. package/dist-cli-web/assets/{fetch-CXM-cjDS.js → fetch-B7Tdp7Uo.js} +1 -1
  83. package/dist-cli-web/assets/{fetch-DBpDMy29.js → fetch-BBdyPNj3.js} +1 -1
  84. package/dist-cli-web/assets/{fetch-B_YFABxI.js → fetch-Bafz8jLM.js} +1 -1
  85. package/dist-cli-web/assets/{fetch-CxVcHNid.js → fetch-C4W6tD-D.js} +1 -1
  86. package/dist-cli-web/assets/{fetch-BeX69kpS.js → fetch-DOsmgros.js} +1 -1
  87. package/dist-cli-web/assets/{fetch-CRocA-4C.js → fetch-DTPDtL38.js} +1 -1
  88. package/dist-cli-web/assets/{fetch-CXqeAbnY.js → fetch-DaeoNUip.js} +1 -1
  89. package/dist-cli-web/assets/{fetch-7lUvXbhU.js → fetch-DgHdAlO7.js} +1 -1
  90. package/dist-cli-web/assets/{fetch-DKBBS9Op.js → fetch-Di4QpfqL.js} +1 -1
  91. package/dist-cli-web/assets/{fetch-4nh1LaVF.js → fetch-Dw33HaVP.js} +11 -13
  92. package/dist-cli-web/assets/{fetch-BEaW1j5H.js → fetch-IP6i-mtr.js} +1 -1
  93. package/dist-cli-web/assets/{fetch-epFXmPIQ.js → fetch-sbr95ipd.js} +1 -1
  94. package/dist-cli-web/assets/{host-CtSqR_Zm.js → host-CMnAiJSx.js} +1 -1
  95. package/dist-cli-web/assets/{host-C4rU8pKA.js → host-CuuNLUWx.js} +1 -1
  96. package/dist-cli-web/assets/{index-ekvsNmfe.js → index-BBYtZa7g.js} +1 -1
  97. package/dist-cli-web/assets/{index-mXe1LssU.js → index-BOXh7X5Y.js} +1 -1
  98. package/dist-cli-web/assets/index-BepItDCQ.js +64 -0
  99. package/dist-cli-web/assets/{index-4DVZ2g0M.js → index-BmGA3geF.js} +1 -1
  100. package/dist-cli-web/assets/{index-BvMAw3Zd.js → index-C-u3l4Uh.js} +1 -1
  101. package/dist-cli-web/assets/{index-D8cHMqV-.js → index-CN9WMxb3.js} +2 -2
  102. package/dist-cli-web/assets/{index-BFH1j_R9.js → index-Chh0gCp7.js} +1 -1
  103. package/dist-cli-web/assets/index-DRFMz0cs.css +1 -0
  104. package/dist-cli-web/assets/{index-BgelKQTW.css → index-DbP9vQhR.css} +1 -1
  105. package/dist-cli-web/assets/index-DgCXdbsG.js +2 -0
  106. package/dist-cli-web/assets/{index-CuCQ1d9f.js → index-DhRaZS6z.js} +1 -1
  107. package/dist-cli-web/assets/{index-_m1mf1jm.js → index-Dz4yfeg6.js} +1 -1
  108. package/dist-cli-web/assets/{index-mbLXPIyC.js → index-EtteazuD.js} +1 -1
  109. package/dist-cli-web/assets/index-GNMlsoVH.js +137 -0
  110. package/dist-cli-web/assets/{index-B1oj9KDv.js → index-bQ9oj54q.js} +4 -4
  111. package/dist-cli-web/assets/{index-DlHuILT_.js → index-fsLAooCi.js} +1 -1
  112. package/dist-cli-web/assets/{people-page-header-BbYSSpsO.js → people-page-header-CKXRSnpl.js} +1 -1
  113. package/dist-cli-web/assets/{prompt-C-ofJ7t_.js → prompt-DNxAd1Bj.js} +1 -1
  114. package/dist-cli-web/assets/{semantic-index-config-builder-D3TYVYC-.js → semantic-index-config-builder-CQ27G4TK.js} +1 -1
  115. package/dist-cli-web/assets/{service-CppETV4a.js → service-BwbGKwDn.js} +1 -1
  116. package/dist-cli-web/assets/service-DQjyjQZx.js +1 -0
  117. package/dist-cli-web/assets/service-Dtve_40X.js +1 -0
  118. package/dist-cli-web/assets/useFormControl-CNmp_2bd.js +1 -0
  119. package/dist-cli-web/assets/{ActionToolsPanel.vue_vue_type_script_setup_true_lang-IB1yZxCE.js → useInsightTabAnalytics-DaU_ADbQ.js} +8 -8
  120. package/dist-cli-web/assets/{useTable-Clk7ecq-.js → useTable-BYXxnZMd.js} +1 -1
  121. package/dist-cli-web/assets/{useToast-B5LaA6c-.js → useToast-DPkgv34s.js} +1 -1
  122. package/dist-cli-web/assets/{webworkerAll-CyA4b4LT.js → webworkerAll-Um4PrCaA.js} +1 -1
  123. package/dist-cli-web/index.html +1 -1
  124. package/package.json +1 -1
  125. package/dist/chat-command-YAFRLHMQ.mjs.map +0 -1
  126. package/dist/chunk-73TJ2S7W.mjs.map +0 -1
  127. package/dist/chunk-ARIBCH47.mjs.map +0 -1
  128. package/dist/chunk-JWJREWVN.mjs.map +0 -1
  129. package/dist/chunk-OTYNMDDL.mjs.map +0 -1
  130. package/dist/chunk-UP6JIV3S.mjs.map +0 -1
  131. package/dist/mcp-SMF3NWIN.mjs.map +0 -1
  132. package/dist-cli-web/assets/SectionTabs.vue_vue_type_script_setup_true_lang-qFhJO5B0.js +0 -1
  133. package/dist-cli-web/assets/aiChat--CR4g2M7.js +0 -8
  134. package/dist-cli-web/assets/index-CIIyg_o9.css +0 -1
  135. package/dist-cli-web/assets/index-CaYtkONV.js +0 -64
  136. package/dist-cli-web/assets/index-D3Hyjv4e.js +0 -137
  137. package/dist-cli-web/assets/index-R4LqAnx9.js +0 -2
  138. package/dist-cli-web/assets/service-BYOUkk7V.js +0 -1
  139. package/dist-cli-web/assets/service-tEx-5LUL.js +0 -1
  140. package/dist-cli-web/assets/useFormControl-CrWi_6Hn.js +0 -1
  141. /package/dist/{chunk-FPVRSXQ4.mjs.map → chunk-4FAEB4C2.mjs.map} +0 -0
  142. /package/dist/{chunk-MMTEGUQA.mjs.map → chunk-5OA4QI3Q.mjs.map} +0 -0
  143. /package/dist/{chunk-PDQV4RUA.mjs.map → chunk-GDKQKHJT.mjs.map} +0 -0
  144. /package/dist/{chunk-GKCIRKOH.mjs.map → chunk-HJWBFHNR.mjs.map} +0 -0
  145. /package/dist/{chunk-2PY4XCH3.mjs.map → chunk-IMJVOODY.mjs.map} +0 -0
  146. /package/dist/{chunk-WDLO7OLX.mjs.map → chunk-O57SQSCO.mjs.map} +0 -0
  147. /package/dist/{chunk-N4SB6QZV.mjs.map → chunk-ZGXXAPLX.mjs.map} +0 -0
  148. /package/dist/{http-LPFPVTBC.mjs.map → http-QJDZKDNJ.mjs.map} +0 -0
  149. /package/dist/{import-T4WX2ZJL.mjs.map → import-XK6YM26A.mjs.map} +0 -0
  150. /package/dist/{src-EGLLMTAU.mjs.map → src-4AHJUFCW.mjs.map} +0 -0
  151. /package/dist/{stream-import-2BXJTTCE.mjs.map → stream-import-7VQVT5ST.mjs.map} +0 -0
  152. /package/dist/{worker-runtime-RDLSPXFT.mjs.map → worker-runtime-PQBAV75N.mjs.map} +0 -0
  153. /package/dist-cli-web/assets/{ActionToolsPanel-DDNXXH8v.css → useInsightTabAnalytics-DDNXXH8v.css} +0 -0
@@ -6,16 +6,18 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  createCliRunAgentStream
9
- } from "./chunk-ARIBCH47.mjs";
10
- import "./chunk-73TJ2S7W.mjs";
11
- import "./chunk-JWJREWVN.mjs";
12
- import "./chunk-GKCIRKOH.mjs";
13
- import "./chunk-N4SB6QZV.mjs";
14
- import "./chunk-2PY4XCH3.mjs";
9
+ } from "./chunk-LUENE6L7.mjs";
10
+ import "./chunk-IDDTW5JN.mjs";
11
+ import "./chunk-E6IRRNBQ.mjs";
12
+ import "./chunk-HJWBFHNR.mjs";
13
+ import "./chunk-ZGXXAPLX.mjs";
14
+ import "./chunk-IMJVOODY.mjs";
15
15
  import "./chunk-YKMQLAVP.mjs";
16
16
  import {
17
- getDefaultGeneralAssistantId
18
- } from "./chunk-OTYNMDDL.mjs";
17
+ extractToolResultText,
18
+ getDefaultGeneralAssistantId,
19
+ truncateToolResultText
20
+ } from "./chunk-ZOHSWBD2.mjs";
19
21
  import "./chunk-VSOWNKPA.mjs";
20
22
 
21
23
  // src/ai/chat-command.ts
@@ -110,9 +112,10 @@ async function runChatTurn(options, deps) {
110
112
  const startedAt = Date.now();
111
113
  let answer = "";
112
114
  let tokenUsage = null;
113
- let streamError = null;
115
+ const streamState = { error: null };
114
116
  const events = [];
115
117
  const contentBlocks = [];
118
+ const toolBlocks = /* @__PURE__ */ new Map();
116
119
  let hasReplayContentBlocks = false;
117
120
  const runAgentStream = (deps.createRunAgentStream ?? createCliRunAgentStream)(deps.dbManager, deps.aiChatManager);
118
121
  const appendTextBlock = (text) => {
@@ -204,7 +207,7 @@ async function runChatTurn(options, deps) {
204
207
  }
205
208
  if (chunk.type === "error") {
206
209
  removePlanDraftBlocks();
207
- streamError = createAgentStreamError(chunk.error);
210
+ streamState.error = createAgentStreamError(chunk.error);
208
211
  return;
209
212
  }
210
213
  if (chunk.type === "plan_delta" && chunk.planDelta) {
@@ -227,6 +230,31 @@ async function runChatTurn(options, deps) {
227
230
  appendChartBlocks(extractChartPayloads(chunk.toolResult));
228
231
  return;
229
232
  }
233
+ if (chunk.type === "tool_start" && chunk.toolName && chunk.toolName !== "render_chart" && chunk.toolCallId) {
234
+ const block = {
235
+ type: "tool",
236
+ tool: {
237
+ name: chunk.toolName,
238
+ displayName: chunk.toolName,
239
+ status: "running",
240
+ toolCallId: chunk.toolCallId,
241
+ params: chunk.toolParams
242
+ }
243
+ };
244
+ toolBlocks.set(chunk.toolCallId, block);
245
+ contentBlocks.push(block);
246
+ hasReplayContentBlocks = true;
247
+ return;
248
+ }
249
+ if (chunk.type === "tool_result" && chunk.toolCallId) {
250
+ const block = toolBlocks.get(chunk.toolCallId);
251
+ if (block) {
252
+ block.tool.status = chunk.toolIsError ? "error" : "done";
253
+ block.tool.isError = chunk.toolIsError === true;
254
+ block.tool.result = truncateToolResultText(extractToolResultText(chunk.toolResult));
255
+ }
256
+ return;
257
+ }
230
258
  if (chunk.type === "content" && chunk.content) {
231
259
  answer += chunk.content;
232
260
  appendTextBlock(chunk.content);
@@ -237,7 +265,7 @@ async function runChatTurn(options, deps) {
237
265
  for (let index = contentBlocks.length - 1; index >= 0; index--) {
238
266
  const block = contentBlocks[index];
239
267
  if (block.type === "plan") {
240
- block.status = "done";
268
+ block.status = streamState.error ? "skipped" : "done";
241
269
  break;
242
270
  }
243
271
  }
@@ -245,7 +273,15 @@ async function runChatTurn(options, deps) {
245
273
  },
246
274
  new AbortController().signal
247
275
  );
248
- if (streamError) throw streamError;
276
+ const streamError = streamState.error;
277
+ if (streamError && streamError.name !== "OutputLimitError") throw streamError;
278
+ if (streamError) {
279
+ contentBlocks.push({
280
+ type: "error",
281
+ error: { name: streamError.name, message: streamError.message, stack: null }
282
+ });
283
+ hasReplayContentBlocks = true;
284
+ }
249
285
  if (!options.json && options.stream !== false && answer && !answer.endsWith("\n")) {
250
286
  write(stdout, "\n");
251
287
  }
@@ -263,6 +299,7 @@ async function runChatTurn(options, deps) {
263
299
  aiChatId: target.aiChatId,
264
300
  question: options.question,
265
301
  answer,
302
+ ...streamError ? { error: { name: streamError.name, message: streamError.message } } : {},
266
303
  ...options.includeEvents ? { events } : {},
267
304
  ...hasReplayContentBlocks ? { contentBlocks } : {},
268
305
  usage: {
@@ -283,6 +320,7 @@ async function runChatCommand(options, deps) {
283
320
  write(stdout, `${result.answer}
284
321
  `);
285
322
  }
323
+ if (result.error) throw createAgentStreamError(result.error);
286
324
  return;
287
325
  }
288
326
  const rl = createInterface({
@@ -297,6 +335,8 @@ async function runChatCommand(options, deps) {
297
335
  try {
298
336
  const result = await runChatTurn({ ...options, aiChatId, question, json: false, stream: true }, deps);
299
337
  aiChatId = result.aiChatId;
338
+ if (result.error) write(stderr, `${result.error.message}
339
+ `);
300
340
  } catch (error) {
301
341
  write(stderr, `${error instanceof Error ? error.message : String(error)}
302
342
  `);
@@ -311,4 +351,4 @@ export {
311
351
  runChatCommand,
312
352
  runChatTurn
313
353
  };
314
- //# sourceMappingURL=chat-command-YAFRLHMQ.mjs.map
354
+ //# sourceMappingURL=chat-command-RQC44FPF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ai/chat-command.ts"],"sourcesContent":["import { createInterface } from 'node:readline/promises'\nimport type { Readable, Writable } from 'node:stream'\nimport type {\n DatabaseManager,\n AIChatManager,\n AgentStreamChunk,\n ContentBlock,\n PlanContentBlock,\n PlanDraftContentBlock,\n TokenUsageData,\n} from '@openchatlab/node-runtime'\nimport type { ChartPayload, PathProvider } from '@openchatlab/core'\nimport { extractToolResultText, truncateToolResultText } from '@openchatlab/core'\nimport { getDefaultGeneralAssistantId } from '@openchatlab/shared-types'\nimport { createCliRunAgentStream } from './agent-stream-runner'\n\nexport interface ChatCommandOptions {\n sessionId?: string\n aiChatId?: string\n question?: string\n json?: boolean\n stream?: boolean\n locale?: string\n includeEvents?: boolean\n}\n\nexport interface ChatCommandDeps {\n dbManager: DatabaseManager\n pathProvider: PathProvider\n aiChatManager: AIChatManager\n stdout?: Pick<Writable, 'write'>\n stderr?: Pick<Writable, 'write'>\n stdin?: Readable\n createRunAgentStream?: typeof createCliRunAgentStream\n}\n\nexport interface ResolvedAIChatTarget {\n sessionId: string\n aiChatId: string\n assistantId: string\n created: boolean\n}\n\nexport interface ChatTurnResult {\n sessionId: string\n aiChatId: string\n question: string\n answer: string\n /** Present for a persisted but incomplete turn, never for a successful completion. */\n error?: { name: string; message: string }\n events?: AgentStreamChunk[]\n contentBlocks?: ContentBlock[]\n usage: {\n durationMs: number\n tokenUsage: TokenUsageData | null\n }\n}\n\nfunction write(stream: Pick<Writable, 'write'>, text: string): void {\n stream.write(text)\n}\n\nfunction buildTitle(question?: string): string {\n const trimmed = question?.trim()\n if (!trimmed) return 'CLI Chat'\n return trimmed.length > 50 ? `${trimmed.slice(0, 50)}...` : trimmed\n}\n\nfunction createAgentStreamError(error: unknown): Error {\n if (error instanceof Error) return error\n if (typeof error === 'string' && error) return new Error(error)\n if (typeof error === 'object' && error !== null) {\n const record = error as { name?: unknown; message?: unknown; stack?: unknown }\n const streamError = new Error(\n typeof record.message === 'string' && record.message ? record.message : 'Agent stream failed'\n )\n if (typeof record.name === 'string' && record.name) streamError.name = record.name\n if (typeof record.stack === 'string' && record.stack) streamError.stack = record.stack\n return streamError\n }\n return new Error('Agent stream failed')\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isChartPayload(value: unknown): value is ChartPayload {\n return isRecord(value) && value.version === 1 && isRecord(value.spec) && isRecord(value.dataset)\n}\n\nfunction extractChartPayloads(toolResult: unknown): ChartPayload[] {\n if (!isRecord(toolResult)) return []\n const details = isRecord(toolResult.details) ? toolResult.details : toolResult\n const charts: ChartPayload[] = []\n if (isChartPayload(details.chart)) charts.push(details.chart)\n if (Array.isArray(details.charts)) {\n for (const chart of details.charts) {\n if (isChartPayload(chart)) charts.push(chart)\n }\n }\n return charts\n}\n\nfunction toPersistedChartPayload(chart: ChartPayload): ChartPayload {\n return {\n ...chart,\n dataset: {\n ...chart.dataset,\n rows: [],\n },\n }\n}\n\nfunction resolveSingleSessionId(dbManager: DatabaseManager): string {\n const sessionIds = dbManager.listSessionIds()\n if (sessionIds.length === 1) return sessionIds[0]!\n if (sessionIds.length === 0) {\n throw new Error('No chat sessions found. Import data first or run `clb sessions` to verify available sessions.')\n }\n throw new Error('Missing --session-id. Run `clb sessions` to choose a session ID.')\n}\n\nfunction assertSessionExists(dbManager: DatabaseManager, sessionId: string): void {\n const db = dbManager.open(sessionId)\n if (!db) {\n throw new Error(`Session ${sessionId} not found`)\n }\n}\n\nexport function resolveAIChatTarget(\n options: Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'question' | 'locale'>,\n deps: Pick<ChatCommandDeps, 'dbManager' | 'aiChatManager'>\n): ResolvedAIChatTarget {\n if (options.aiChatId) {\n const aiChat = deps.aiChatManager.getAIChat(options.aiChatId)\n if (!aiChat) {\n throw new Error(`AI chat ${options.aiChatId} not found`)\n }\n if (options.sessionId && options.sessionId !== aiChat.sessionId) {\n throw new Error(`AI chat ${options.aiChatId} belongs to session ${aiChat.sessionId}, not ${options.sessionId}`)\n }\n assertSessionExists(deps.dbManager, aiChat.sessionId)\n return { sessionId: aiChat.sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: false }\n }\n\n const sessionId = options.sessionId ?? resolveSingleSessionId(deps.dbManager)\n assertSessionExists(deps.dbManager, sessionId)\n const aiChat = deps.aiChatManager.createAIChat(\n sessionId,\n buildTitle(options.question),\n getDefaultGeneralAssistantId(options.locale)\n )\n return { sessionId, aiChatId: aiChat.id, assistantId: aiChat.assistantId, created: true }\n}\n\nexport async function runChatTurn(\n options: Required<Pick<ChatCommandOptions, 'question'>> &\n Pick<ChatCommandOptions, 'sessionId' | 'aiChatId' | 'json' | 'stream' | 'locale' | 'includeEvents'>,\n deps: ChatCommandDeps\n): Promise<ChatTurnResult> {\n const stdout = deps.stdout ?? process.stdout\n const target = resolveAIChatTarget(options, deps)\n const startedAt = Date.now()\n let answer = ''\n let tokenUsage: TokenUsageData | null = null\n const streamState: { error: Error | null } = { error: null }\n const events: AgentStreamChunk[] = []\n const contentBlocks: ContentBlock[] = []\n const toolBlocks = new Map<string, Extract<ContentBlock, { type: 'tool' }>>()\n let hasReplayContentBlocks = false\n\n const runAgentStream = (deps.createRunAgentStream ?? createCliRunAgentStream)(deps.dbManager, deps.aiChatManager)\n\n // 中文注释:CLI 历史回放依赖 contentBlocks 的时序;只要出现计划/思考块,\n // 就同步保留后续正文 text block,避免 UI 使用 blocks 渲染时丢失最终回答。\n const appendTextBlock = (text: string) => {\n if (!text) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'text') {\n lastBlock.text += text\n } else {\n contentBlocks.push({ type: 'text', text })\n }\n }\n\n const appendThinkBlock = (text: string, tag = 'thinking', durationMs?: number) => {\n if (!text && durationMs === undefined) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n let targetBlock: ContentBlock | undefined\n\n if (lastBlock?.type === 'think' && lastBlock.tag === tag) {\n lastBlock.text += text\n targetBlock = lastBlock\n } else if (text.trim().length > 0) {\n targetBlock = { type: 'think', tag, text }\n contentBlocks.push(targetBlock)\n } else if (durationMs !== undefined) {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'think' && block.tag === tag) {\n targetBlock = block\n break\n }\n }\n }\n\n if (durationMs !== undefined && targetBlock?.type === 'think') {\n targetBlock.durationMs = durationMs\n }\n if (targetBlock?.type === 'think') {\n hasReplayContentBlocks = true\n }\n }\n\n const appendChartBlocks = (charts: ChartPayload[]) => {\n if (charts.length === 0) return\n // 中文注释:图表 block 需要持久化给 CLI 生成的 AI 对话回放;\n // 原始 SQL 行数据可能较大,保存时只保留渲染数据和字段元信息。\n contentBlocks.push(...charts.map((chart) => ({ type: 'chart' as const, chart: toPersistedChartPayload(chart) })))\n hasReplayContentBlocks = true\n }\n\n const appendPlanDraftBlock = (delta: string) => {\n if (!delta) return\n const lastBlock = contentBlocks[contentBlocks.length - 1]\n if (lastBlock?.type === 'plan_draft') {\n lastBlock.text += delta\n } else {\n contentBlocks.push({ type: 'plan_draft', version: 1, status: 'streaming', text: delta } as PlanDraftContentBlock)\n }\n hasReplayContentBlocks = true\n }\n\n const removePlanDraftBlocks = () => {\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n if (contentBlocks[index]?.type === 'plan_draft') {\n contentBlocks.splice(index, 1)\n }\n }\n }\n\n const appendFinalPlanBlock = (plan: PlanContentBlock) => {\n const planBlock = JSON.parse(JSON.stringify(plan)) as PlanContentBlock\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block?.type === 'plan_draft') {\n const displayText = block.text.trim()\n if (displayText) planBlock.displayText = displayText\n contentBlocks[index] = planBlock\n hasReplayContentBlocks = true\n return\n }\n }\n contentBlocks.push(planBlock)\n hasReplayContentBlocks = true\n }\n\n await runAgentStream(\n {\n userMessage: options.question,\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n assistantId: target.assistantId,\n chatType: 'group',\n locale: options.locale ?? 'zh-CN',\n enableAutoSkill: true,\n chartAutoMode: 'suggest',\n },\n (chunk: AgentStreamChunk) => {\n if (options.includeEvents) {\n events.push(JSON.parse(JSON.stringify(chunk)) as AgentStreamChunk)\n }\n if (chunk.type === 'error') {\n removePlanDraftBlocks()\n streamState.error = createAgentStreamError(chunk.error)\n return\n }\n if (chunk.type === 'plan_delta' && chunk.planDelta) {\n appendPlanDraftBlock(chunk.planDelta)\n return\n }\n if (chunk.type === 'plan' && chunk.plan) {\n appendFinalPlanBlock(chunk.plan)\n return\n }\n if (chunk.type === 'plan_skipped') {\n removePlanDraftBlocks()\n return\n }\n if (chunk.type === 'think') {\n appendThinkBlock(chunk.content ?? '', chunk.thinkTag, chunk.thinkDurationMs)\n return\n }\n if (chunk.type === 'tool_result' && chunk.toolName === 'render_chart') {\n appendChartBlocks(extractChartPayloads(chunk.toolResult))\n return\n }\n if (chunk.type === 'tool_start' && chunk.toolName && chunk.toolName !== 'render_chart' && chunk.toolCallId) {\n const block: Extract<ContentBlock, { type: 'tool' }> = {\n type: 'tool',\n tool: {\n name: chunk.toolName,\n displayName: chunk.toolName,\n status: 'running',\n toolCallId: chunk.toolCallId,\n params: chunk.toolParams,\n },\n }\n toolBlocks.set(chunk.toolCallId, block)\n contentBlocks.push(block)\n hasReplayContentBlocks = true\n return\n }\n if (chunk.type === 'tool_result' && chunk.toolCallId) {\n const block = toolBlocks.get(chunk.toolCallId)\n if (block) {\n block.tool.status = chunk.toolIsError ? 'error' : 'done'\n block.tool.isError = chunk.toolIsError === true\n block.tool.result = truncateToolResultText(extractToolResultText(chunk.toolResult))\n }\n return\n }\n if (chunk.type === 'content' && chunk.content) {\n answer += chunk.content\n appendTextBlock(chunk.content)\n if (!options.json && options.stream !== false) write(stdout, chunk.content)\n }\n if (chunk.type === 'done' && chunk.usage) {\n tokenUsage = chunk.usage\n for (let index = contentBlocks.length - 1; index >= 0; index--) {\n const block = contentBlocks[index]\n if (block.type === 'plan') {\n block.status = streamState.error ? 'skipped' : 'done'\n break\n }\n }\n }\n },\n new AbortController().signal\n )\n\n const streamError = streamState.error\n if (streamError && streamError.name !== 'OutputLimitError') throw streamError\n if (streamError) {\n contentBlocks.push({\n type: 'error',\n error: { name: streamError.name, message: streamError.message, stack: null },\n })\n hasReplayContentBlocks = true\n }\n\n if (!options.json && options.stream !== false && answer && !answer.endsWith('\\n')) {\n write(stdout, '\\n')\n }\n\n deps.aiChatManager.addMessagePair(\n target.aiChatId,\n { content: options.question },\n {\n content: answer,\n contentBlocks: hasReplayContentBlocks ? contentBlocks : undefined,\n tokenUsage: tokenUsage ?? undefined,\n }\n )\n\n return {\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n question: options.question,\n answer,\n ...(streamError ? { error: { name: streamError.name, message: streamError.message } } : {}),\n ...(options.includeEvents ? { events } : {}),\n ...(hasReplayContentBlocks ? { contentBlocks } : {}),\n usage: {\n durationMs: Date.now() - startedAt,\n tokenUsage,\n },\n }\n}\n\nexport async function runChatCommand(options: ChatCommandOptions, deps: ChatCommandDeps): Promise<void> {\n const stdout = deps.stdout ?? process.stdout\n const stderr = deps.stderr ?? process.stderr\n\n if (options.question?.trim()) {\n const result = await runChatTurn({ ...options, question: options.question.trim() }, deps)\n if (options.json) {\n write(stdout, `${JSON.stringify(result, null, 2)}\\n`)\n } else if (options.stream === false) {\n write(stdout, `${result.answer}\\n`)\n }\n if (result.error) throw createAgentStreamError(result.error)\n return\n }\n\n const rl = createInterface({\n input: deps.stdin ?? process.stdin,\n output: stdout as Writable,\n })\n\n try {\n let aiChatId = options.aiChatId\n while (true) {\n const question = (await rl.question('chatlab> ')).trim()\n if (!question || question === 'exit' || question === 'quit') break\n try {\n const result = await runChatTurn({ ...options, aiChatId, question, json: false, stream: true }, deps)\n aiChatId = result.aiChatId\n if (result.error) write(stderr, `${result.error.message}\\n`)\n } catch (error) {\n write(stderr, `${error instanceof Error ? error.message : String(error)}\\n`)\n }\n }\n } finally {\n rl.close()\n }\n}\n"],"mappings":"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","names":["aiChat"]}
@@ -8,14 +8,14 @@ import {
8
8
  formatPortInUseError,
9
9
  installCliLocalEmbeddingRuntime,
10
10
  isPortAvailable
11
- } from "./chunk-WDLO7OLX.mjs";
11
+ } from "./chunk-O57SQSCO.mjs";
12
12
  import {
13
13
  analyzeAutoImport,
14
14
  autoImport
15
- } from "./chunk-MMTEGUQA.mjs";
15
+ } from "./chunk-5OA4QI3Q.mjs";
16
16
  import {
17
17
  assertCliDataDirCompatible
18
- } from "./chunk-PDQV4RUA.mjs";
18
+ } from "./chunk-GDKQKHJT.mjs";
19
19
  import {
20
20
  getVersion
21
21
  } from "./chunk-5ADKYYNA.mjs";
@@ -29,14 +29,14 @@ import {
29
29
  computeWordFrequency,
30
30
  getSystemLogsDir,
31
31
  hasPendingElectronDataWarning
32
- } from "./chunk-JWJREWVN.mjs";
32
+ } from "./chunk-E6IRRNBQ.mjs";
33
33
  import {
34
34
  IMPORT_IN_PROGRESS_ERROR_KEY,
35
35
  detectFormat,
36
36
  logNativeParserStatus,
37
37
  owner_profile_service_exports,
38
38
  validateChatLabFile
39
- } from "./chunk-GKCIRKOH.mjs";
39
+ } from "./chunk-HJWBFHNR.mjs";
40
40
  import {
41
41
  AIChatManager,
42
42
  ConfigSetError,
@@ -79,7 +79,7 @@ import {
79
79
  searchMessagesLike,
80
80
  setConfigField,
81
81
  verifyCliDataPath
82
- } from "./chunk-OTYNMDDL.mjs";
82
+ } from "./chunk-ZOHSWBD2.mjs";
83
83
 
84
84
  // src/cli.ts
85
85
  import * as fs4 from "fs";
@@ -2314,7 +2314,7 @@ registerImportCommand(program);
2314
2314
  registerValidateCommand(program);
2315
2315
  registerRuntimeCommand(program);
2316
2316
  program.command("formats").description("List all supported chat history formats").action(async () => {
2317
- const { getSupportedFormats } = await import("./import-T4WX2ZJL.mjs");
2317
+ const { getSupportedFormats } = await import("./import-XK6YM26A.mjs");
2318
2318
  const formats = getSupportedFormats();
2319
2319
  console.log(`${formats.length} supported format(s):
2320
2320
  `);
@@ -2323,11 +2323,11 @@ program.command("formats").description("List all supported chat history formats"
2323
2323
  }
2324
2324
  });
2325
2325
  program.command("mcp").description("Start MCP Server (stdio transport, for ClaudeCode / Cursor / AI agents)").action(async () => {
2326
- const { startCliMcpServer } = await import("./mcp-SMF3NWIN.mjs");
2326
+ const { startCliMcpServer } = await import("./mcp-DMGZFSYN.mjs");
2327
2327
  await startCliMcpServer();
2328
2328
  });
2329
2329
  program.command("chat").description("Ask ChatLab AI about an imported chat session").option("--session-id <id>", "Source chat session ID").option("--ai-chat-id <id>", "Existing AI chat ID to continue").option("-q, --question <text>", "Question to ask").option("--json", "Output structured JSON").option("--include-events", "Include all agent stream chunks in JSON output").option("--no-stream", "Disable streaming output").option("--locale <locale>", "AI response locale", "zh-CN").action(async (options) => {
2330
- const { runChatCommand } = await import("./chat-command-YAFRLHMQ.mjs");
2330
+ const { runChatCommand } = await import("./chat-command-RQC44FPF.mjs");
2331
2331
  const { dbManager, pathProvider } = initRuntime();
2332
2332
  const aiChatManager = new AIChatManager(pathProvider.getAiDataDir(), { nativeBinding: resolveNativeBinding() });
2333
2333
  try {
@@ -2367,7 +2367,7 @@ program.command("web").alias("start").description("Start ChatLab (HTTP API + Web
2367
2367
  });
2368
2368
  return;
2369
2369
  }
2370
- const { startHttpServer } = await import("./http-LPFPVTBC.mjs");
2370
+ const { startHttpServer } = await import("./http-QJDZKDNJ.mjs");
2371
2371
  const port = parseInt(options.port, 10);
2372
2372
  let webRoot;
2373
2373
  if (!options.headless) {
@@ -2430,7 +2430,7 @@ Press Ctrl+C to stop.
2430
2430
  }
2431
2431
  const shutdown = async () => {
2432
2432
  console.log("\nShutting down...");
2433
- const { stopHttpServer } = await import("./http-LPFPVTBC.mjs");
2433
+ const { stopHttpServer } = await import("./http-QJDZKDNJ.mjs");
2434
2434
  await stopHttpServer();
2435
2435
  process.exit(0);
2436
2436
  };
@@ -2523,4 +2523,4 @@ if (isDirectRun) {
2523
2523
  export {
2524
2524
  run
2525
2525
  };
2526
- //# sourceMappingURL=chunk-FPVRSXQ4.mjs.map
2526
+ //# sourceMappingURL=chunk-4FAEB4C2.mjs.map
@@ -16,10 +16,10 @@ import {
16
16
  resolveDefaultBatchConcurrency,
17
17
  streamingImport,
18
18
  withDataDirImportLock
19
- } from "./chunk-GKCIRKOH.mjs";
19
+ } from "./chunk-HJWBFHNR.mjs";
20
20
  import {
21
21
  DataDirCompatibilityError
22
- } from "./chunk-OTYNMDDL.mjs";
22
+ } from "./chunk-ZOHSWBD2.mjs";
23
23
 
24
24
  // src/import/stream-import.ts
25
25
  import * as crypto from "crypto";
@@ -375,4 +375,4 @@ export {
375
375
  analyzeIncrementalImport2 as analyzeIncrementalImport,
376
376
  analyzeNewImport2 as analyzeNewImport
377
377
  };
378
- //# sourceMappingURL=chunk-MMTEGUQA.mjs.map
378
+ //# sourceMappingURL=chunk-5OA4QI3Q.mjs.map
@@ -11,15 +11,15 @@ import {
11
11
  getServerAiLogger,
12
12
  getSkillManagerCore,
13
13
  initServerAiLogger
14
- } from "./chunk-ARIBCH47.mjs";
14
+ } from "./chunk-LUENE6L7.mjs";
15
15
  import {
16
16
  AGENT_TOOL_REGISTRY,
17
17
  CoreDataProvider
18
- } from "./chunk-73TJ2S7W.mjs";
18
+ } from "./chunk-IDDTW5JN.mjs";
19
19
  import {
20
20
  prepareUnixSocket,
21
21
  resolveCliLocalEmbeddingRuntimeConfig
22
- } from "./chunk-WDLO7OLX.mjs";
22
+ } from "./chunk-O57SQSCO.mjs";
23
23
  import {
24
24
  analyzeIncrementalImport,
25
25
  analyzeNewImport,
@@ -27,10 +27,10 @@ import {
27
27
  autoImportBatch,
28
28
  incrementalImport,
29
29
  streamImport
30
- } from "./chunk-MMTEGUQA.mjs";
30
+ } from "./chunk-5OA4QI3Q.mjs";
31
31
  import {
32
32
  assertCliDataDirCompatible
33
- } from "./chunk-PDQV4RUA.mjs";
33
+ } from "./chunk-GDKQKHJT.mjs";
34
34
  import {
35
35
  getVersion
36
36
  } from "./chunk-5ADKYYNA.mjs";
@@ -62,7 +62,7 @@ import {
62
62
  isDictDownloaded,
63
63
  segmentText,
64
64
  serializeChatLabToJsonl
65
- } from "./chunk-JWJREWVN.mjs";
65
+ } from "./chunk-E6IRRNBQ.mjs";
66
66
  import {
67
67
  ArchiveImportError,
68
68
  ArchiveImportSourceManager,
@@ -103,7 +103,7 @@ import {
103
103
  session_service_exports,
104
104
  streamParseFileInfo,
105
105
  summary_service_exports
106
- } from "./chunk-GKCIRKOH.mjs";
106
+ } from "./chunk-HJWBFHNR.mjs";
107
107
  import {
108
108
  AIChatManager,
109
109
  AIMemoryService,
@@ -184,7 +184,7 @@ import {
184
184
  validateApiKey,
185
185
  verifyCliDataPath,
186
186
  writeConfigField
187
- } from "./chunk-OTYNMDDL.mjs";
187
+ } from "./chunk-ZOHSWBD2.mjs";
188
188
 
189
189
  // src/http/index.ts
190
190
  import * as fs11 from "fs";
@@ -2400,7 +2400,11 @@ function registerCacheRoutes(server2, ctx) {
2400
2400
  if (!fs3.existsSync(downloadsDir)) {
2401
2401
  fs3.mkdirSync(downloadsDir, { recursive: true });
2402
2402
  }
2403
- const filePath = path5.join(downloadsDir, filename);
2403
+ const safeName = path5.basename(filename);
2404
+ if (safeName !== filename || safeName === "." || safeName === "..") {
2405
+ return { success: false, error: "Invalid filename" };
2406
+ }
2407
+ const filePath = path5.join(downloadsDir, safeName);
2404
2408
  fs3.writeFileSync(filePath, buffer);
2405
2409
  return { success: true, filePath };
2406
2410
  });
@@ -3959,10 +3963,10 @@ function registerWebRoutes2(server2, dbManager2, options) {
3959
3963
  const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
3960
3964
  const ai = options?.aiContext;
3961
3965
  const cliStreamImport = async (dm, filePath) => {
3962
- const { streamImport: streamImport2 } = await import("./stream-import-2BXJTTCE.mjs");
3966
+ const { streamImport: streamImport2 } = await import("./stream-import-7VQVT5ST.mjs");
3963
3967
  const result = await streamImport2(dm, filePath);
3964
3968
  if (!result.success) {
3965
- const { IMPORT_IN_PROGRESS_ERROR_KEY: IMPORT_IN_PROGRESS_ERROR_KEY2, ImportInProgressError: ImportInProgressError2 } = await import("./src-EGLLMTAU.mjs");
3969
+ const { IMPORT_IN_PROGRESS_ERROR_KEY: IMPORT_IN_PROGRESS_ERROR_KEY2, ImportInProgressError: ImportInProgressError2 } = await import("./src-4AHJUFCW.mjs");
3966
3970
  if (result.error === IMPORT_IN_PROGRESS_ERROR_KEY2) throw new ImportInProgressError2();
3967
3971
  throw new Error(result.error || "Import failed");
3968
3972
  }
@@ -5189,4 +5193,4 @@ export {
5189
5193
  startHttpServer,
5190
5194
  stopHttpServer
5191
5195
  };
5192
- //# sourceMappingURL=chunk-UP6JIV3S.mjs.map
5196
+ //# sourceMappingURL=chunk-E2ZFGNZQ.mjs.map