chatlab-cli 0.36.0 → 0.36.1

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 (193) hide show
  1. package/README.md +7 -7
  2. package/dist/{chat-command-SXW67RF7.mjs → chat-command-XPJ43KSW.mjs} +10 -10
  3. package/dist/chat-command-XPJ43KSW.mjs.map +1 -0
  4. package/dist/{chunk-BSGLH6G3.mjs → chunk-2JPFBIAG.mjs} +144 -79
  5. package/dist/chunk-2JPFBIAG.mjs.map +1 -0
  6. package/dist/{chunk-VDWI4A4U.mjs → chunk-5MJO4AJB.mjs} +2 -2
  7. package/dist/{chunk-GVW3BDGZ.mjs → chunk-67HNPYZJ.mjs} +3 -3
  8. package/dist/{chunk-UNIKQFI5.mjs → chunk-6QP47LID.mjs} +2 -2
  9. package/dist/{chunk-4YPNYQSP.mjs → chunk-FJOGBUXU.mjs} +390 -96
  10. package/dist/chunk-FJOGBUXU.mjs.map +1 -0
  11. package/dist/{chunk-XDF6PMVZ.mjs → chunk-JOVL7OTW.mjs} +2 -2
  12. package/dist/{chunk-CNEWMCGX.mjs → chunk-L7TIIVAY.mjs} +57 -57
  13. package/dist/chunk-L7TIIVAY.mjs.map +1 -0
  14. package/dist/{chunk-U2NXHIJK.mjs → chunk-NFTCEJBJ.mjs} +3 -3
  15. package/dist/{chunk-AAGDVTP2.mjs → chunk-NQHZPSW2.mjs} +2 -2
  16. package/dist/{chunk-OWOEWZIC.mjs → chunk-Q3NEL2KK.mjs} +82 -28
  17. package/dist/chunk-Q3NEL2KK.mjs.map +1 -0
  18. package/dist/{chunk-LZGOIRLV.mjs → chunk-R73XMAB2.mjs} +9 -5
  19. package/dist/chunk-R73XMAB2.mjs.map +1 -0
  20. package/dist/{chunk-JHON5FN7.mjs → chunk-X2QBH24F.mjs} +8 -3
  21. package/dist/chunk-X2QBH24F.mjs.map +1 -0
  22. package/dist/cli.mjs +9 -9
  23. package/dist/contacts-worker.mjs +2 -2
  24. package/dist/global-insight-worker.mjs +1 -1
  25. package/dist/{http-LVOGJFDL.mjs → http-5RVY5J5U.mjs} +12 -12
  26. package/dist/{import-7OU57ZHM.mjs → import-ILTWVHKU.mjs} +7 -7
  27. package/dist/index.mjs +12 -12
  28. package/dist/{mcp-CUKHTTII.mjs → mcp-Y2YXOFB4.mjs} +8 -8
  29. package/dist/people-relationships-worker.mjs +2 -2
  30. package/dist/semantic-index-worker.mjs +1 -1
  31. package/dist/{service-KZTHBDQ5.mjs → service-ZAHXRSFD.mjs} +6 -6
  32. package/dist/service-ZAHXRSFD.mjs.map +1 -0
  33. package/dist/{src-LORFXAUE.mjs → src-OV5ZNE3Z.mjs} +10 -6
  34. package/dist/{stream-import-7YUWIAD6.mjs → stream-import-XOUM3Z5W.mjs} +7 -7
  35. package/dist/{undici-MU5I3L6Q.mjs → undici-UGXDRJLV.mjs} +193 -193
  36. package/dist/undici-UGXDRJLV.mjs.map +1 -0
  37. package/dist/{update-checker-3N7HQEP2.mjs → update-checker-UL2FBLXH.mjs} +3 -5
  38. package/dist/{update-checker-3N7HQEP2.mjs.map → update-checker-UL2FBLXH.mjs.map} +1 -1
  39. package/dist/{worker-runtime-GQ5SY7E3.mjs → worker-runtime-JNGURHDM.mjs} +5 -5
  40. package/dist-cli-web/assets/AISettingsTab-vvjijrc5.js +1 -0
  41. package/dist-cli-web/assets/AboutTab-CxI8zJNz.js +1 -0
  42. package/dist-cli-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-w0hHEodr.js +110 -0
  43. package/dist-cli-web/assets/{Alert-DJzXKcec.js → Alert-_MYcI_E2.js} +1 -1
  44. package/dist-cli-web/assets/ApiSettingsTab-CK7U6dVA.js +2 -0
  45. package/dist-cli-web/assets/BatchManageTab-1WnEqqpB.js +1 -0
  46. package/dist-cli-web/assets/{BufferResource-DY3P-dGs.js → BufferResource-i64DlwQT.js} +1 -1
  47. package/dist-cli-web/assets/{CanvasRenderer-As2MJTWZ.js → CanvasRenderer-B76mEt9A.js} +1 -1
  48. package/dist-cli-web/assets/ChatRecordDrawer-Bp6OSCrz.js +1 -0
  49. package/dist-cli-web/assets/{ChatRecordWorkspace-CVDPBmcl.js → ChatRecordWorkspace-CyfPIlIy.js} +1 -1
  50. package/dist-cli-web/assets/{Checkbox-4F1WAuVF.js → Checkbox-Ci7IeRw1.js} +1 -1
  51. package/dist-cli-web/assets/DataDirCleanupNotice-Dh63pOLt.js +1 -0
  52. package/dist-cli-web/assets/DatePicker.vue_vue_type_script_setup_true_lang-DqNBNa1D.js +1 -0
  53. package/dist-cli-web/assets/{DebugToolsPanel-BLU6SY8a.js → DebugToolsPanel-CbNsD9co.js} +1 -1
  54. package/dist-cli-web/assets/EChart.vue_vue_type_script_setup_true_lang-YeqmodwE.js +1 -0
  55. package/dist-cli-web/assets/EChartBar.vue_vue_type_script_setup_true_lang-C3pZmq0v.js +1 -0
  56. package/dist-cli-web/assets/{EChartLine.vue_vue_type_script_setup_true_lang-BYhukELX.js → EChartLine.vue_vue_type_script_setup_true_lang-Co6olfwv.js} +1 -1
  57. package/dist-cli-web/assets/{EChartWordcloud-C16xh7Tx.js → EChartWordcloud-rDusZwSq.js} +1 -1
  58. package/dist-cli-web/assets/{Filter-BEtPORqF.js → Filter-yxkeHO78.js} +1 -1
  59. package/dist-cli-web/assets/GlobalTaskBar-BlZ-fFiq.js +1 -0
  60. package/dist-cli-web/assets/GroupRelationshipGalaxyView-BXQBX0zJ.js +1 -0
  61. package/dist-cli-web/assets/{Label-Dgl3ghzT.js → Label-CFAZFBQX.js} +1 -1
  62. package/dist-cli-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-CwgpqtMZ.js +1 -0
  63. package/dist-cli-web/assets/MessageExportModal-DU71grc7.js +1 -0
  64. package/dist-cli-web/assets/{PageHeader-CL9AFfvl.js → PageHeader-BDPf4NuI.js} +1 -1
  65. package/dist-cli-web/assets/{PageTabs.vue_vue_type_script_setup_true_lang-C22kOxIK.js → PageTabs.vue_vue_type_script_setup_true_lang-_j82asQU.js} +1 -1
  66. package/dist-cli-web/assets/{RelationshipGalaxyCanvas-BnkcrIpk.js → RelationshipGalaxyCanvas-BODk18aA.js} +14 -14
  67. package/dist-cli-web/assets/RelationshipGalaxyThreeCanvas-BJyuRiC-.js +4168 -0
  68. package/dist-cli-web/assets/RelationshipGalaxyThreeCanvas-CCasBcBQ.css +1 -0
  69. package/dist-cli-web/assets/{RenderTargetSystem-CPwnC2X3.js → RenderTargetSystem-CVMvAUSv.js} +1 -1
  70. package/dist-cli-web/assets/RovingFocusItem-DC_06OmN.js +1 -0
  71. package/dist-cli-web/assets/{ScreenCaptureModal-ByKxzNQe.js → ScreenCaptureModal-DrBFDOtC.js} +1 -1
  72. package/dist-cli-web/assets/SectionTabs.vue_vue_type_script_setup_true_lang-C-Zj2biH.js +1 -0
  73. package/dist-cli-web/assets/{Select-jVtfc_xc.js → Select-DLK2LYhO.js} +1 -1
  74. package/dist-cli-web/assets/SettingsModal-BFkxzo0Y.css +1 -0
  75. package/dist-cli-web/assets/SettingsModal-DqaR4Dx5.js +2 -0
  76. package/dist-cli-web/assets/{StorageTab-QdcDqA6Q.js → StorageTab-B0ebN0f8.js} +1 -1
  77. package/dist-cli-web/assets/{Switch-DYHM64k9.js → Switch-CokhQWxm.js} +1 -1
  78. package/dist-cli-web/assets/{Tabs-B6Nzq2NQ.js → Tabs-D1UiZNaZ.js} +1 -1
  79. package/dist-cli-web/assets/Tabs-N3Q-Mpqi.js +1 -0
  80. package/dist-cli-web/assets/{ThemeCard.vue_vue_type_script_setup_true_lang-Bsq7gpC0.js → ThemeCard.vue_vue_type_script_setup_true_lang-OT-I0mbU.js} +1 -1
  81. package/dist-cli-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-Ccunouyf.js +1 -0
  82. package/dist-cli-web/assets/{VisuallyHiddenInput-IQpmK9yR.js → VisuallyHiddenInput-OAJEt_Y5.js} +1 -1
  83. package/dist-cli-web/assets/{WebGLRenderer-8JHbnkTc.js → WebGLRenderer-DuUeftYD.js} +1 -1
  84. package/dist-cli-web/assets/{WebGPURenderer-CLWfB4CC.js → WebGPURenderer-DoWQxiWZ.js} +1 -1
  85. package/dist-cli-web/assets/aiChat-CdADfRnU.js +8 -0
  86. package/dist-cli-web/assets/{browserAll-Cin6ghNg.js → browserAll-Cb-mtR2y.js} +1 -1
  87. package/dist-cli-web/assets/{cli-web-D7IBc3AX.js → cli-web-BHQCZLLg.js} +1 -1
  88. package/dist-cli-web/assets/{fetch-B7kuohCt.js → fetch-AvsnJLWJ.js} +1 -1
  89. package/dist-cli-web/assets/{fetch-BR71C0K9.js → fetch-B-6tyYWu.js} +1 -1
  90. package/dist-cli-web/assets/{fetch-OnnCjzee.js → fetch-B4PYy5JS.js} +1 -1
  91. package/dist-cli-web/assets/{fetch-_CN1EVMt.js → fetch-BbcFaCRB.js} +1 -1
  92. package/dist-cli-web/assets/{fetch-C8tTTsCm.js → fetch-BkA_so1e.js} +1 -1
  93. package/dist-cli-web/assets/{fetch-2QEQPA9q.js → fetch-BzXuAaT3.js} +1 -1
  94. package/dist-cli-web/assets/fetch-CW2fKvGp.js +1 -0
  95. package/dist-cli-web/assets/{fetch-CuUeyk0N.js → fetch-DEub4tOo.js} +1 -1
  96. package/dist-cli-web/assets/{fetch-1NiXh-_B.js → fetch-DLTlYnDB.js} +1 -1
  97. package/dist-cli-web/assets/{fetch-B2agy1hy.js → fetch-Qs38Hx1V.js} +1 -1
  98. package/dist-cli-web/assets/{fetch-Bk-7vxHV.js → fetch-sYDJ-Zs8.js} +1 -1
  99. package/dist-cli-web/assets/{fetch-DPRDSI39.js → fetch-ul8-uQIb.js} +1 -1
  100. package/dist-cli-web/assets/host-B6SQ6OGo.js +1 -0
  101. package/dist-cli-web/assets/host-DYIkQqvY.js +1 -0
  102. package/dist-cli-web/assets/{index-BCEk6ZpL.js → index--IEkRjKe.js} +10 -10
  103. package/dist-cli-web/assets/index-9iaY_EWG.js +1 -0
  104. package/dist-cli-web/assets/index-BnaLj2dx.css +1 -0
  105. package/dist-cli-web/assets/index-C7omDgiJ.js +2 -0
  106. package/dist-cli-web/assets/index-CHsM84U1.js +2 -0
  107. package/dist-cli-web/assets/index-CL8u01Pf.js +137 -0
  108. package/dist-cli-web/assets/{index-BIHFuCJK.js → index-CShh95fU.js} +1 -1
  109. package/dist-cli-web/assets/index-C_OS8Y8W.js +1 -0
  110. package/dist-cli-web/assets/{index-Colc58j-.js → index-D64XYYts.js} +1 -1
  111. package/dist-cli-web/assets/index-DrCc8p_I.css +1 -0
  112. package/dist-cli-web/assets/index-Dz_ddyZS.css +1 -0
  113. package/dist-cli-web/assets/index-UpTe1KzQ.js +1 -0
  114. package/dist-cli-web/assets/index-a8Hw6eD8.js +1 -0
  115. package/dist-cli-web/assets/index-jwjzZNKm.js +1 -0
  116. package/dist-cli-web/assets/index-pkxlF8Ee.js +1 -0
  117. package/dist-cli-web/assets/index-sWxuTsa7.js +36 -0
  118. package/dist-cli-web/assets/{people-page-header-DNPjaSt4.js → people-page-header-0jvXFFnh.js} +1 -1
  119. package/dist-cli-web/assets/{prompt-BgywZQ_g.js → prompt-BPYj29Vq.js} +1 -1
  120. package/dist-cli-web/assets/{semantic-index-config-builder-bji_UxYE.js → semantic-index-config-builder-vO37z355.js} +1 -1
  121. package/dist-cli-web/assets/service-CVoA9yNf.js +1 -0
  122. package/dist-cli-web/assets/{service-DpU9fa-l.js → service-D29Vftq9.js} +1 -1
  123. package/dist-cli-web/assets/service-DMysyLCa.js +1 -0
  124. package/dist-cli-web/assets/{useFormControl-De24E2zT.js → useFormControl-DVawP2DO.js} +1 -1
  125. package/dist-cli-web/assets/useTable-Bv3R_Hux.js +1 -0
  126. package/dist-cli-web/assets/useToast-BA0EwImD.js +1 -0
  127. package/dist-cli-web/assets/{vendor-echarts-DfAMQxdr.js → vendor-echarts-hTLhTs52.js} +5 -5
  128. package/dist-cli-web/assets/{vendor-echarts-wordcloud-BsaEJTPY.js → vendor-echarts-wordcloud-B8CF_NgP.js} +1 -1
  129. package/dist-cli-web/assets/{vendor-zrender-PFmZe1EY.js → vendor-zrender-D8psf1AA.js} +2 -2
  130. package/dist-cli-web/assets/{webworkerAll-BRnv6GvJ.js → webworkerAll-ZPE_yGnC.js} +1 -1
  131. package/dist-cli-web/index.html +2 -2
  132. package/package.json +4 -4
  133. package/dist/chat-command-SXW67RF7.mjs.map +0 -1
  134. package/dist/chunk-4YPNYQSP.mjs.map +0 -1
  135. package/dist/chunk-BSGLH6G3.mjs.map +0 -1
  136. package/dist/chunk-CNEWMCGX.mjs.map +0 -1
  137. package/dist/chunk-JHON5FN7.mjs.map +0 -1
  138. package/dist/chunk-LZGOIRLV.mjs.map +0 -1
  139. package/dist/chunk-OWOEWZIC.mjs.map +0 -1
  140. package/dist/service-KZTHBDQ5.mjs.map +0 -1
  141. package/dist/undici-MU5I3L6Q.mjs.map +0 -1
  142. package/dist-cli-web/assets/AISettingsTab-BmhNcUEh.js +0 -1
  143. package/dist-cli-web/assets/AboutTab-CFklrZt8.js +0 -1
  144. package/dist-cli-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-B-dIPvcs.js +0 -110
  145. package/dist-cli-web/assets/ApiSettingsTab-DvDm421U.js +0 -2
  146. package/dist-cli-web/assets/BatchManageTab-DhIDH3Q1.js +0 -1
  147. package/dist-cli-web/assets/ChatRecordDrawer-DHdas7Jp.js +0 -1
  148. package/dist-cli-web/assets/DataDirCleanupNotice-jebQ9il3.js +0 -1
  149. package/dist-cli-web/assets/DatePicker.vue_vue_type_script_setup_true_lang-Cal624eP.js +0 -1
  150. package/dist-cli-web/assets/EChart.vue_vue_type_script_setup_true_lang-CsgJ-Xn3.js +0 -1
  151. package/dist-cli-web/assets/GlobalTaskBar-BvNmFO7q.js +0 -1
  152. package/dist-cli-web/assets/GroupRelationshipGalaxyView-DEUIrvgz.js +0 -1
  153. package/dist-cli-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-CwDIA0UP.js +0 -1
  154. package/dist-cli-web/assets/MessageExportModal-DYjhBuzO.js +0 -1
  155. package/dist-cli-web/assets/RelationshipGalaxyThreeCanvas-CqdqveEJ.js +0 -4108
  156. package/dist-cli-web/assets/RelationshipGalaxyThreeCanvas-TYGOUDiv.css +0 -1
  157. package/dist-cli-web/assets/RovingFocusItem-j33Nsbbn.js +0 -1
  158. package/dist-cli-web/assets/SectionTabs.vue_vue_type_script_setup_true_lang-C6EHKB_i.js +0 -1
  159. package/dist-cli-web/assets/SettingsModal-CjVax3I6.css +0 -1
  160. package/dist-cli-web/assets/SettingsModal-Dg27piEO.js +0 -2
  161. package/dist-cli-web/assets/Tabs-CRZdCcU4.js +0 -1
  162. package/dist-cli-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-BLpQds4F.js +0 -1
  163. package/dist-cli-web/assets/aiChat-4JvxWGXZ.js +0 -8
  164. package/dist-cli-web/assets/base-D6fxqD_X.js +0 -1
  165. package/dist-cli-web/assets/dateFormat-Bu4-Ux3L.js +0 -1
  166. package/dist-cli-web/assets/index-BUz_Vl9U.js +0 -2
  167. package/dist-cli-web/assets/index-BWZIoPV3.css +0 -1
  168. package/dist-cli-web/assets/index-BYQV3OA5.js +0 -1
  169. package/dist-cli-web/assets/index-CVVv_6qu.js +0 -2
  170. package/dist-cli-web/assets/index-CacwXQL4.js +0 -1
  171. package/dist-cli-web/assets/index-DImo7TQN.js +0 -1
  172. package/dist-cli-web/assets/index-DV9zQVPV.js +0 -137
  173. package/dist-cli-web/assets/index-DXKS-q-w.css +0 -1
  174. package/dist-cli-web/assets/index-DZc5A4_J.js +0 -1
  175. package/dist-cli-web/assets/index-DkWTvE7d.js +0 -36
  176. package/dist-cli-web/assets/index-DmEn0PAI.js +0 -1
  177. package/dist-cli-web/assets/index-b9eEQeVt.js +0 -1
  178. package/dist-cli-web/assets/index-waDxab2e.css +0 -1
  179. package/dist-cli-web/assets/insight-time-range-MJxLEu6o.js +0 -1
  180. package/dist-cli-web/assets/useTable-C7BH94MF.js +0 -1
  181. package/dist-cli-web/assets/useToast-CxhJkhXK.js +0 -1
  182. /package/dist/{chunk-VDWI4A4U.mjs.map → chunk-5MJO4AJB.mjs.map} +0 -0
  183. /package/dist/{chunk-GVW3BDGZ.mjs.map → chunk-67HNPYZJ.mjs.map} +0 -0
  184. /package/dist/{chunk-UNIKQFI5.mjs.map → chunk-6QP47LID.mjs.map} +0 -0
  185. /package/dist/{chunk-XDF6PMVZ.mjs.map → chunk-JOVL7OTW.mjs.map} +0 -0
  186. /package/dist/{chunk-U2NXHIJK.mjs.map → chunk-NFTCEJBJ.mjs.map} +0 -0
  187. /package/dist/{chunk-AAGDVTP2.mjs.map → chunk-NQHZPSW2.mjs.map} +0 -0
  188. /package/dist/{http-LVOGJFDL.mjs.map → http-5RVY5J5U.mjs.map} +0 -0
  189. /package/dist/{import-7OU57ZHM.mjs.map → import-ILTWVHKU.mjs.map} +0 -0
  190. /package/dist/{mcp-CUKHTTII.mjs.map → mcp-Y2YXOFB4.mjs.map} +0 -0
  191. /package/dist/{src-LORFXAUE.mjs.map → src-OV5ZNE3Z.mjs.map} +0 -0
  192. /package/dist/{stream-import-7YUWIAD6.mjs.map → stream-import-XOUM3Z5W.mjs.map} +0 -0
  193. /package/dist/{worker-runtime-GQ5SY7E3.mjs.map → worker-runtime-JNGURHDM.mjs.map} +0 -0
package/README.md CHANGED
@@ -43,9 +43,9 @@ npm i chatlab-cli -g
43
43
  Start ChatLab:
44
44
 
45
45
  ```bash
46
- chatlab start # Start API + Web UI, auto-open in browser
47
- chatlab start --no-open # Start API + Web UI, skip auto-open
48
- chatlab start --headless # API only, no Web UI (for scripts / AI Agents)
46
+ clb web # Start API + Web UI, auto-open in browser
47
+ clb web --no-open # Start API + Web UI, skip auto-open
48
+ clb web --headless # API only, no Web UI (for scripts / AI Agents)
49
49
  ```
50
50
 
51
51
  Common options: `--port <port>` (default 3110), `--host <address>`, `--token <token>`.
@@ -53,9 +53,9 @@ Common options: `--port <port>` (default 3110), `--host <address>`, `--token <to
53
53
  To run as a persistent background service (auto-start on login + auto-restart on crash):
54
54
 
55
55
  ```bash
56
- chatlab start --daemon # Install as system service (macOS / Linux)
57
- chatlab status # Check service status
58
- chatlab stop # Stop and uninstall service
56
+ clb web --daemon # Install as system service (macOS / Linux)
57
+ clb status # Check service status
58
+ clb stop # Stop and uninstall service
59
59
  ```
60
60
 
61
61
  For a full walkthrough, see the [Quick Start guide](https://docs.chatlab.fun/usage/quick-start).
@@ -97,7 +97,7 @@ For complete contributor instructions, see the [Development Guide](https://docs.
97
97
  ### Requirements
98
98
 
99
99
  - Node.js >= 24 < 25
100
- - pnpm >= 9 < 10
100
+ - pnpm >= 11 < 12
101
101
 
102
102
  ### Setup
103
103
 
@@ -6,16 +6,16 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  createCliRunAgentStream
9
- } from "./chunk-LZGOIRLV.mjs";
10
- import "./chunk-JHON5FN7.mjs";
11
- import "./chunk-U2NXHIJK.mjs";
12
- import "./chunk-4YPNYQSP.mjs";
13
- import "./chunk-XDF6PMVZ.mjs";
14
- import "./chunk-AAGDVTP2.mjs";
9
+ } from "./chunk-R73XMAB2.mjs";
10
+ import "./chunk-X2QBH24F.mjs";
11
+ import "./chunk-NFTCEJBJ.mjs";
12
+ import "./chunk-FJOGBUXU.mjs";
13
+ import "./chunk-JOVL7OTW.mjs";
14
+ import "./chunk-NQHZPSW2.mjs";
15
15
  import "./chunk-YKMQLAVP.mjs";
16
16
  import {
17
17
  getDefaultGeneralAssistantId
18
- } from "./chunk-OWOEWZIC.mjs";
18
+ } from "./chunk-Q3NEL2KK.mjs";
19
19
  import "./chunk-VSOWNKPA.mjs";
20
20
 
21
21
  // src/ai/chat-command.ts
@@ -73,9 +73,9 @@ function resolveSingleSessionId(dbManager) {
73
73
  const sessionIds = dbManager.listSessionIds();
74
74
  if (sessionIds.length === 1) return sessionIds[0];
75
75
  if (sessionIds.length === 0) {
76
- throw new Error("No chat sessions found. Import data first or run `chatlab sessions` to verify available sessions.");
76
+ throw new Error("No chat sessions found. Import data first or run `clb sessions` to verify available sessions.");
77
77
  }
78
- throw new Error("Missing --session-id. Run `chatlab sessions` to choose a session ID.");
78
+ throw new Error("Missing --session-id. Run `clb sessions` to choose a session ID.");
79
79
  }
80
80
  function assertSessionExists(dbManager, sessionId) {
81
81
  const db = dbManager.open(sessionId);
@@ -312,4 +312,4 @@ export {
312
312
  runChatCommand,
313
313
  runChatTurn
314
314
  };
315
- //# sourceMappingURL=chat-command-SXW67RF7.mjs.map
315
+ //# sourceMappingURL=chat-command-XPJ43KSW.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 { 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 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 let streamError: Error | null = null\n const events: AgentStreamChunk[] = []\n const contentBlocks: ContentBlock[] = []\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 streamError = 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 === '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 = 'done'\n break\n }\n }\n }\n },\n new AbortController().signal\n )\n\n if (streamError) throw streamError\n\n if (!options.json && options.stream !== false && answer && !answer.endsWith('\\n')) {\n write(stdout, '\\n')\n }\n\n deps.aiChatManager.addMessage(target.aiChatId, 'user', options.question)\n deps.aiChatManager.addMessage(\n target.aiChatId,\n 'assistant',\n answer,\n undefined,\n undefined,\n hasReplayContentBlocks ? contentBlocks : undefined,\n tokenUsage ?? undefined\n )\n\n return {\n sessionId: target.sessionId,\n aiChatId: target.aiChatId,\n question: options.question,\n answer,\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 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 } 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"]}
@@ -11,14 +11,14 @@ import {
11
11
  getServerAiLogger,
12
12
  getSkillManagerCore,
13
13
  initServerAiLogger
14
- } from "./chunk-LZGOIRLV.mjs";
14
+ } from "./chunk-R73XMAB2.mjs";
15
15
  import {
16
16
  AGENT_TOOL_REGISTRY,
17
17
  CoreDataProvider
18
- } from "./chunk-JHON5FN7.mjs";
18
+ } from "./chunk-X2QBH24F.mjs";
19
19
  import {
20
20
  resolveCliLocalEmbeddingRuntimeConfig
21
- } from "./chunk-UNIKQFI5.mjs";
21
+ } from "./chunk-6QP47LID.mjs";
22
22
  import {
23
23
  analyzeIncrementalImport,
24
24
  analyzeNewImport,
@@ -26,10 +26,10 @@ import {
26
26
  autoImportBatch,
27
27
  incrementalImport,
28
28
  streamImport
29
- } from "./chunk-GVW3BDGZ.mjs";
29
+ } from "./chunk-67HNPYZJ.mjs";
30
30
  import {
31
31
  assertCliDataDirCompatible
32
- } from "./chunk-VDWI4A4U.mjs";
32
+ } from "./chunk-5MJO4AJB.mjs";
33
33
  import {
34
34
  getVersion
35
35
  } from "./chunk-5ADKYYNA.mjs";
@@ -62,7 +62,7 @@ import {
62
62
  isDictDownloaded,
63
63
  segmentText,
64
64
  serializeChatLabToJsonl
65
- } from "./chunk-U2NXHIJK.mjs";
65
+ } from "./chunk-NFTCEJBJ.mjs";
66
66
  import {
67
67
  ArchiveImportError,
68
68
  ArchiveImportSourceManager,
@@ -70,6 +70,7 @@ import {
70
70
  ImportIdempotencyCache,
71
71
  ImportInProgressError,
72
72
  MergeSessionCache,
73
+ NavigationLayoutValidationError,
73
74
  PARSER_FORMAT_IDS,
74
75
  SEMANTIC_INDEX_CONFIG_FILE,
75
76
  SemanticIndexConfigStore,
@@ -77,6 +78,7 @@ import {
77
78
  createChatLabTempDir,
78
79
  createContactsService,
79
80
  createGlobalInsightService,
81
+ createNavigationLayoutService,
80
82
  createPeopleRelationshipsService,
81
83
  createTimeInvestmentService,
82
84
  detectAllFormats,
@@ -100,10 +102,11 @@ import {
100
102
  session_service_exports,
101
103
  streamParseFileInfo,
102
104
  summary_service_exports
103
- } from "./chunk-4YPNYQSP.mjs";
105
+ } from "./chunk-FJOGBUXU.mjs";
104
106
  import {
105
107
  AIChatManager,
106
108
  ALL_MIGRATIONS,
109
+ ANNUAL_SUMMARY_PLUGIN_ID,
107
110
  BUILTIN_MODELS,
108
111
  BUILTIN_PROVIDERS,
109
112
  BUILTIN_TOOL_CATALOG,
@@ -114,6 +117,7 @@ import {
114
117
  GROUP_RELATIONSHIP_GALAXY_ALGORITHM_VERSION,
115
118
  MigrationRunner,
116
119
  POS_TAG_DEFINITIONS,
120
+ TIME_INVESTMENT_PLUGIN_ID,
117
121
  appLogger,
118
122
  assertValidTopicDayKey,
119
123
  buildPiModel,
@@ -174,7 +178,7 @@ import {
174
178
  validateApiKey,
175
179
  verifyCliDataPath,
176
180
  writeConfigField
177
- } from "./chunk-OWOEWZIC.mjs";
181
+ } from "./chunk-Q3NEL2KK.mjs";
178
182
 
179
183
  // src/http/index.ts
180
184
  import * as fs11 from "fs";
@@ -800,6 +804,11 @@ function registerRestRoutes(server2, ctx) {
800
804
  registerImportRoutes(server2, ctx);
801
805
  }
802
806
 
807
+ // ../../packages/http-routes/src/plugins/node.ts
808
+ function registerNodePlugins(server2, context, plugins) {
809
+ for (const plugin of plugins) plugin.registerHttpRoutes(server2, context);
810
+ }
811
+
803
812
  // ../../packages/http-routes/src/routes/web/ai-agent-stream.ts
804
813
  var activeAgentAborts = /* @__PURE__ */ new Map();
805
814
  function registerAiAgentStreamRoutes(server2, ctx) {
@@ -2329,69 +2338,6 @@ function registerExportRoutes(server2, ctx) {
2329
2338
  });
2330
2339
  }
2331
2340
 
2332
- // ../../packages/http-routes/src/routes/web/global-insight.ts
2333
- function registerGlobalInsightRoutes(server2, ctx) {
2334
- let preferences = ctx.preferencesManager;
2335
- const getExcludedSessionIds = () => {
2336
- preferences ??= new PreferencesManager(ctx.pathProvider.getSystemDir());
2337
- return preferences.load().ownerExcludedSessionIds;
2338
- };
2339
- const service = ctx.globalInsightService ?? createGlobalInsightService({
2340
- adapter: ctx.sessionAdapter,
2341
- pathProvider: ctx.pathProvider,
2342
- runtimeIdentity: ctx.runtimeIdentity,
2343
- nativeBinding: ctx.nativeBinding,
2344
- getExcludedSessionIds
2345
- });
2346
- const timeInvestmentService = ctx.timeInvestmentService ?? createTimeInvestmentService({
2347
- adapter: ctx.sessionAdapter,
2348
- pathProvider: ctx.pathProvider,
2349
- runtimeIdentity: ctx.runtimeIdentity,
2350
- nativeBinding: ctx.nativeBinding,
2351
- getExcludedSessionIds
2352
- });
2353
- server2.addHook("onClose", async () => {
2354
- await Promise.all([service.close(), timeInvestmentService.close()]);
2355
- });
2356
- server2.get("/_web/global-insight/annual-summary", async (request) => {
2357
- return service.getAnnualSummary({
2358
- ...parseRange(request.query),
2359
- acceptStale: isTruthy2(request.query.acceptStale)
2360
- });
2361
- });
2362
- server2.post(
2363
- "/_web/global-insight/annual-summary/recompute",
2364
- async (request) => service.startRecompute(parseRange(request.query))
2365
- );
2366
- server2.get(
2367
- "/_web/global-insight/time-investment",
2368
- async (request) => timeInvestmentService.getTimeInvestment({
2369
- ...parseRange(request.query),
2370
- acceptStale: isTruthy2(request.query.acceptStale)
2371
- })
2372
- );
2373
- server2.post(
2374
- "/_web/global-insight/time-investment/recompute",
2375
- async (request) => timeInvestmentService.startRecompute(parseRange(request.query))
2376
- );
2377
- }
2378
- function parseRange(query) {
2379
- const mode = query.mode === "recent" ? "recent" : "year";
2380
- return {
2381
- mode,
2382
- year: parseInteger(query.year),
2383
- days: query.days === "365" ? 365 : void 0
2384
- };
2385
- }
2386
- function parseInteger(value) {
2387
- if (!value) return void 0;
2388
- const parsed = Number(value);
2389
- return Number.isInteger(parsed) ? parsed : void 0;
2390
- }
2391
- function isTruthy2(value) {
2392
- return value === "1" || value === "true" || value === "yes";
2393
- }
2394
-
2395
2341
  // ../../packages/http-routes/src/routes/web/logs.ts
2396
2342
  function registerLogRoutes(server2) {
2397
2343
  server2.post("/_web/logs/report", async (req, reply) => {
@@ -2484,6 +2430,27 @@ function isHttpClientError(error) {
2484
2430
  return error instanceof Error && "statusCode" in error && typeof error.statusCode === "number" && error.statusCode >= 400 && error.statusCode < 500;
2485
2431
  }
2486
2432
 
2433
+ // ../../packages/http-routes/src/routes/web/navigation-layout.ts
2434
+ function registerNavigationLayoutRoutes(server2, context) {
2435
+ const service = context.navigationLayoutService ?? createNavigationLayoutService(context.pathProvider.getSystemDir());
2436
+ server2.get("/_web/navigation-layout", async () => service.load());
2437
+ server2.put("/_web/navigation-layout", async (request, reply) => {
2438
+ try {
2439
+ const layout = service.save(request.body);
2440
+ return { status: "saved", layout };
2441
+ } catch (error) {
2442
+ if (error instanceof NavigationLayoutValidationError) {
2443
+ return reply.code(400).send({ error: "INVALID_NAVIGATION_LAYOUT" });
2444
+ }
2445
+ throw error;
2446
+ }
2447
+ });
2448
+ server2.delete("/_web/navigation-layout", async () => {
2449
+ service.reset();
2450
+ return { status: "missing", layout: null };
2451
+ });
2452
+ }
2453
+
2487
2454
  // ../../packages/http-routes/src/routes/web/merge.ts
2488
2455
  import * as fs4 from "fs";
2489
2456
  import * as path6 from "path";
@@ -2749,7 +2716,7 @@ function registerPeopleRelationshipsRoutes(server2, ctx) {
2749
2716
  });
2750
2717
  server2.get("/_web/people/relationships", async (request) => {
2751
2718
  return service.getGraph({
2752
- acceptStale: isTruthy3(request.query.acceptStale),
2719
+ acceptStale: isTruthy2(request.query.acceptStale),
2753
2720
  timeRangePreset: parseContactsTimeRangePreset2(request.query.timeRange),
2754
2721
  graphScope: parsePeopleRelationshipsGraphScope(request.query.scope),
2755
2722
  query: request.query.q
@@ -2766,14 +2733,14 @@ function registerPeopleRelationshipsRoutes(server2, ctx) {
2766
2733
  "/_web/people/relationships/:key/neighborhood",
2767
2734
  async (request) => {
2768
2735
  return service.getNeighborhood(request.params.key, {
2769
- acceptStale: isTruthy3(request.query.acceptStale),
2736
+ acceptStale: isTruthy2(request.query.acceptStale),
2770
2737
  timeRangePreset: parseContactsTimeRangePreset2(request.query.timeRange),
2771
2738
  graphScope: parsePeopleRelationshipsGraphScope(request.query.scope)
2772
2739
  });
2773
2740
  }
2774
2741
  );
2775
2742
  }
2776
- function isTruthy3(value) {
2743
+ function isTruthy2(value) {
2777
2744
  return value === "1" || value === "true" || value === "yes";
2778
2745
  }
2779
2746
  function parseContactsTimeRangePreset2(value) {
@@ -3006,7 +2973,8 @@ function registerWebRoutes(server2, ctx, options) {
3006
2973
  registerMemberRoutes(server2, resolvedCtx);
3007
2974
  registerContactsRoutes(server2, resolvedCtx);
3008
2975
  registerPeopleRelationshipsRoutes(server2, resolvedCtx);
3009
- registerGlobalInsightRoutes(server2, resolvedCtx);
2976
+ registerNavigationLayoutRoutes(server2, resolvedCtx);
2977
+ registerNodePlugins(server2, resolvedCtx, options?.nodePlugins ?? []);
3010
2978
  registerPreferencesRoutes(server2, resolvedCtx);
3011
2979
  registerAnalyticsRoutes(server2, resolvedCtx);
3012
2980
  registerSqlRoutes(server2, resolvedCtx);
@@ -3026,6 +2994,100 @@ function registerSharedRoutes(server2, ctx, options) {
3026
2994
  registerWebRoutes(server2, ctx, options);
3027
2995
  }
3028
2996
 
2997
+ // ../../packages/http-routes/src/plugins/builtin/annual-summary/index.ts
2998
+ var annualSummaryNodePlugin = {
2999
+ id: ANNUAL_SUMMARY_PLUGIN_ID,
3000
+ registerHttpRoutes(server2, context) {
3001
+ let preferences = context.preferencesManager;
3002
+ const getExcludedSessionIds = () => {
3003
+ preferences ??= new PreferencesManager(context.pathProvider.getSystemDir());
3004
+ return preferences.load().ownerExcludedSessionIds;
3005
+ };
3006
+ const service = context.globalInsightService ?? createGlobalInsightService({
3007
+ adapter: context.sessionAdapter,
3008
+ pathProvider: context.pathProvider,
3009
+ runtimeIdentity: context.runtimeIdentity,
3010
+ nativeBinding: context.nativeBinding,
3011
+ getExcludedSessionIds
3012
+ });
3013
+ server2.addHook("onClose", () => service.close());
3014
+ server2.get(
3015
+ "/_web/global-insight/annual-summary",
3016
+ async (request) => service.getAnnualSummary({
3017
+ ...parseRange(request.query),
3018
+ acceptStale: isTruthy3(request.query.acceptStale)
3019
+ })
3020
+ );
3021
+ server2.post(
3022
+ "/_web/global-insight/annual-summary/recompute",
3023
+ async (request) => service.startRecompute(parseRange(request.query))
3024
+ );
3025
+ }
3026
+ };
3027
+ function parseRange(query) {
3028
+ const mode = query.mode === "recent" ? "recent" : "year";
3029
+ return {
3030
+ mode,
3031
+ year: parseInteger(query.year),
3032
+ days: query.days === "365" ? 365 : void 0
3033
+ };
3034
+ }
3035
+ function parseInteger(value) {
3036
+ if (!value) return void 0;
3037
+ const parsed = Number(value);
3038
+ return Number.isInteger(parsed) ? parsed : void 0;
3039
+ }
3040
+ function isTruthy3(value) {
3041
+ return value === "1" || value === "true" || value === "yes";
3042
+ }
3043
+
3044
+ // ../../packages/http-routes/src/plugins/builtin/time-investment/index.ts
3045
+ var timeInvestmentNodePlugin = {
3046
+ id: TIME_INVESTMENT_PLUGIN_ID,
3047
+ registerHttpRoutes(server2, context) {
3048
+ let preferences = context.preferencesManager;
3049
+ const getExcludedSessionIds = () => {
3050
+ preferences ??= new PreferencesManager(context.pathProvider.getSystemDir());
3051
+ return preferences.load().ownerExcludedSessionIds;
3052
+ };
3053
+ const service = context.timeInvestmentService ?? createTimeInvestmentService({
3054
+ adapter: context.sessionAdapter,
3055
+ pathProvider: context.pathProvider,
3056
+ runtimeIdentity: context.runtimeIdentity,
3057
+ nativeBinding: context.nativeBinding,
3058
+ getExcludedSessionIds
3059
+ });
3060
+ server2.addHook("onClose", () => service.close());
3061
+ server2.get(
3062
+ "/_web/global-insight/time-investment",
3063
+ async (request) => service.getTimeInvestment({
3064
+ ...parseRange2(request.query),
3065
+ acceptStale: isTruthy4(request.query.acceptStale)
3066
+ })
3067
+ );
3068
+ server2.post(
3069
+ "/_web/global-insight/time-investment/recompute",
3070
+ async (request) => service.startRecompute(parseRange2(request.query))
3071
+ );
3072
+ }
3073
+ };
3074
+ function parseRange2(query) {
3075
+ const mode = query.mode === "recent" ? "recent" : "year";
3076
+ return {
3077
+ mode,
3078
+ year: parseInteger2(query.year),
3079
+ days: query.days === "365" ? 365 : void 0
3080
+ };
3081
+ }
3082
+ function parseInteger2(value) {
3083
+ if (!value) return void 0;
3084
+ const parsed = Number(value);
3085
+ return Number.isInteger(parsed) ? parsed : void 0;
3086
+ }
3087
+ function isTruthy4(value) {
3088
+ return value === "1" || value === "true" || value === "yes";
3089
+ }
3090
+
3029
3091
  // ../../packages/http-routes/src/routes/web/automation.ts
3030
3092
  function requireAutomation(ctx) {
3031
3093
  return ctx.automation ?? null;
@@ -3699,10 +3761,10 @@ function registerWebRoutes2(server2, dbManager2, options) {
3699
3761
  const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
3700
3762
  const ai = options?.aiContext;
3701
3763
  const cliStreamImport = async (dm, filePath) => {
3702
- const { streamImport: streamImport2 } = await import("./stream-import-7YUWIAD6.mjs");
3764
+ const { streamImport: streamImport2 } = await import("./stream-import-XOUM3Z5W.mjs");
3703
3765
  const result = await streamImport2(dm, filePath);
3704
3766
  if (!result.success) {
3705
- const { IMPORT_IN_PROGRESS_ERROR_KEY: IMPORT_IN_PROGRESS_ERROR_KEY2, ImportInProgressError: ImportInProgressError2 } = await import("./src-LORFXAUE.mjs");
3767
+ const { IMPORT_IN_PROGRESS_ERROR_KEY: IMPORT_IN_PROGRESS_ERROR_KEY2, ImportInProgressError: ImportInProgressError2 } = await import("./src-OV5ZNE3Z.mjs");
3706
3768
  if (result.error === IMPORT_IN_PROGRESS_ERROR_KEY2) throw new ImportInProgressError2();
3707
3769
  throw new Error(result.error || "Import failed");
3708
3770
  }
@@ -3768,7 +3830,10 @@ function registerWebRoutes2(server2, dbManager2, options) {
3768
3830
  runAgentStream: ai.runAgentStream
3769
3831
  }
3770
3832
  },
3771
- ai ? { requireAi: true } : void 0
3833
+ {
3834
+ nodePlugins: [annualSummaryNodePlugin, timeInvestmentNodePlugin],
3835
+ ...ai && { requireAi: true }
3836
+ }
3772
3837
  );
3773
3838
  registerImportRoutes2(server2, dbManager2);
3774
3839
  server2.get("/_web/system/check-update", async () => {
@@ -4878,4 +4943,4 @@ export {
4878
4943
  startHttpServer,
4879
4944
  stopHttpServer
4880
4945
  };
4881
- //# sourceMappingURL=chunk-BSGLH6G3.mjs.map
4946
+ //# sourceMappingURL=chunk-2JPFBIAG.mjs.map