@jingyi0605/codingns 0.9.0 → 0.9.6

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 (331) hide show
  1. package/bin/codingns.mjs +75 -0
  2. package/dist/public/assets/{AdaptiveButlerPage-B17QiMyT.js → AdaptiveButlerPage-khJQh6a_.js} +2 -2
  3. package/dist/public/assets/{App-CFBwDUNA.js → App-If9gThKM.js} +6 -6
  4. package/dist/public/assets/{BootstrapPage-W5wU3BPh.js → BootstrapPage-DcfYtoLC.js} +1 -1
  5. package/dist/public/assets/{ConversationPage-DQLX1bUh.js → ConversationPage-Bfb7GLTM.js} +1 -1
  6. package/dist/public/assets/{DesktopDetachPreviewPage-DTPeuAW-.js → DesktopDetachPreviewPage-CXUPMcBz.js} +1 -1
  7. package/dist/public/assets/{DesktopModal-6ii53_Y9.js → DesktopModal-bMdI1jEe.js} +1 -1
  8. package/dist/public/assets/DesktopWindowPage-D1xwgS-7.js +2 -0
  9. package/dist/public/assets/FileContextPanel-C4syif3B.js +1 -0
  10. package/dist/public/assets/GitSidebar-DduL9aTV.js +6 -0
  11. package/dist/public/assets/MobileCreateSessionSheet-DWPBsEx8.js +1 -0
  12. package/dist/public/assets/{MobileSheet-opTWyRe1.js → MobileSheet-BXvQPkxt.js} +1 -1
  13. package/dist/public/assets/{MobileTopHeaderFrame-BbNON3Y4.js → MobileTopHeaderFrame-vdYOyaaB.js} +1 -1
  14. package/dist/public/assets/{MobileWorkspaceSwitcherHeader-BZEzPeMj.js → MobileWorkspaceSwitcherHeader-DT330cAx.js} +1 -1
  15. package/dist/public/assets/{PluginAccessOverview-mQDmAljp.js → PluginAccessOverview-C77TeZTK.js} +1 -1
  16. package/dist/public/assets/{PluginContainerPage-CcxUJpM4.js → PluginContainerPage-DdSwOCw-.js} +1 -1
  17. package/dist/public/assets/{PluginDetailPage-D5--ACIt.js → PluginDetailPage-BK1yTzvO.js} +1 -1
  18. package/dist/public/assets/{PluginsListPage-D_oJxYXT.js → PluginsListPage-DAAwSc6W.js} +1 -1
  19. package/dist/public/assets/{RelayConnectEntryPage-DROxpnkv.js → RelayConnectEntryPage-4Yyo2p8b.js} +1 -1
  20. package/dist/public/assets/{ServerSettingsModal-CUUOPqSe.js → ServerSettingsModal-C_DEisHs.js} +1 -1
  21. package/dist/public/assets/{SessionIndexPage-C2Jxh6Gp.js → SessionIndexPage-DyMikN_x.js} +1 -1
  22. package/dist/public/assets/SettingsPage-CDAVsPr3.js +2 -0
  23. package/dist/public/assets/TerminalManagerPanel-4OR47vcf.js +1 -0
  24. package/dist/public/assets/{TerminalPage-CwWyFDj8.js → TerminalPage-Pvx396YX.js} +1 -1
  25. package/dist/public/assets/{TerminalRuntimeFallbackModal-CSVVbO8r.js → TerminalRuntimeFallbackModal-KvG6k4AQ.js} +1 -1
  26. package/dist/public/assets/{ToolFilesPage-QBEY8oCf.js → ToolFilesPage-DrYHk0N-.js} +1 -1
  27. package/dist/public/assets/{ToolGitPage-BKoZ2l9v.js → ToolGitPage-Dz1q-Ns_.js} +1 -1
  28. package/dist/public/assets/{ToolProcessesPage-BOH0ib4G.js → ToolProcessesPage-CRhphOmM.js} +1 -1
  29. package/dist/public/assets/{ToolsHomePage-BcMZ3BCQ.js → ToolsHomePage-BJSDLR6T.js} +1 -1
  30. package/dist/public/assets/{WorkbenchLandingPage-B5zoppEl.js → WorkbenchLandingPage-BlkxdOLC.js} +1 -1
  31. package/dist/public/assets/WorkbenchLayout-D-U7ghT0.js +1022 -0
  32. package/dist/public/assets/{WorkbenchModal-NGmPgqaE.js → WorkbenchModal-xbx1o6MO.js} +1 -1
  33. package/dist/public/assets/WorkbenchShellRoute-DyWSCHz_.js +1 -0
  34. package/dist/public/assets/WorkbenchShellRoute-htbkGbtW.css +1 -0
  35. package/dist/public/assets/WorkspaceDebugDetailPage-B4ol2_a5.js +1 -0
  36. package/dist/public/assets/WorkspaceDetailPage-DMakfmHR.js +1 -0
  37. package/dist/public/assets/WorkspaceHomePage-tmCafatd.js +1 -0
  38. package/dist/public/assets/{client-runtime-manager-DXbI9K1K.js → client-runtime-manager-Bwau7p1v.js} +1 -1
  39. package/dist/public/assets/index-DmUJ8tIw.css +1 -0
  40. package/dist/public/assets/index-_OCkVmfl.js +50 -0
  41. package/dist/public/assets/{login-direct-candidate-resolver-DkKyFtQJ.js → login-direct-candidate-resolver-CKUQ07IA.js} +1 -1
  42. package/dist/public/assets/{plugin-permission-copy-CzN269Bk.js → plugin-permission-copy-DIVk5jNp.js} +1 -1
  43. package/dist/public/assets/{plugins-api-Bv9DHpLF.js → plugins-api-DHJVvPZw.js} +1 -1
  44. package/dist/public/assets/{preferences-service-D2ISL2Zz.js → preferences-service-CyxxeBmS.js} +1 -1
  45. package/dist/public/assets/{relay-entry-Bg0OisQy.js → relay-entry-B5GmiOrR.js} +1 -1
  46. package/dist/public/assets/{terminal-runtime-meta-C8t-CIDF.js → terminal-runtime-meta-DBsyT35T.js} +1 -1
  47. package/dist/public/assets/useRegisteredDebugTemplates-wCGD2SLW.js +1 -0
  48. package/dist/public/assets/workbench-navigation-RyUjchbD.js +1 -0
  49. package/dist/public/index.html +2 -2
  50. package/dist/server/config/env.d.ts +1 -0
  51. package/dist/server/config/env.js +3 -0
  52. package/dist/server/config/env.js.map +1 -1
  53. package/dist/server/modules/affairs-indexer/core/src/parser/parser-skip-repository.js.map +1 -1
  54. package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.d.ts +1 -0
  55. package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.js +31 -0
  56. package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-repository.js.map +1 -1
  57. package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-write-repository.js.map +1 -1
  58. package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.d.ts +1 -0
  59. package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.js +1 -0
  60. package/dist/server/modules/affairs-indexer/core/src/services/dirty/dirty-scope-resolver.js.map +1 -1
  61. package/dist/server/modules/affairs-indexer/core/src/services/export/export-builder.js +4 -1
  62. package/dist/server/modules/affairs-indexer/core/src/services/export/export-builder.js.map +1 -1
  63. package/dist/server/modules/affairs-indexer/core/src/services/search/search-index-builder.js +140 -16
  64. package/dist/server/modules/affairs-indexer/core/src/services/search/search-index-builder.js.map +1 -1
  65. package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js +2 -2
  66. package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js.map +1 -1
  67. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.d.ts +20 -3
  68. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js +3 -3
  69. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js.map +1 -1
  70. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +1 -1
  71. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +8 -7
  72. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
  73. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +14 -13
  74. package/dist/server/modules/assistant-capability/assistant-capability-service.js +27 -24
  75. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
  76. package/dist/server/modules/auth/auth-controller.d.ts +27 -1
  77. package/dist/server/modules/auth/auth-controller.js +20 -0
  78. package/dist/server/modules/auth/auth-controller.js.map +1 -1
  79. package/dist/server/modules/auth/auth-service.d.ts +32 -1
  80. package/dist/server/modules/auth/auth-service.js +217 -2
  81. package/dist/server/modules/auth/auth-service.js.map +1 -1
  82. package/dist/server/modules/bootstrap/bootstrap-service.js +1 -0
  83. package/dist/server/modules/bootstrap/bootstrap-service.js.map +1 -1
  84. package/dist/server/modules/butler/assistant-automation-service.d.ts +1 -1
  85. package/dist/server/modules/butler/assistant-automation-service.js +9 -10
  86. package/dist/server/modules/butler/assistant-automation-service.js.map +1 -1
  87. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.d.ts +32 -0
  88. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js +93 -0
  89. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js.map +1 -0
  90. package/dist/server/modules/butler/assistant-sandbox-service.d.ts +69 -0
  91. package/dist/server/modules/butler/assistant-sandbox-service.js +399 -0
  92. package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
  93. package/dist/server/modules/butler/butler-action-context-service.js +2 -2
  94. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -1
  95. package/dist/server/modules/butler/butler-control-action-service.d.ts +5 -5
  96. package/dist/server/modules/butler/butler-control-action-service.js +19 -19
  97. package/dist/server/modules/butler/butler-control-action-service.js.map +1 -1
  98. package/dist/server/modules/butler/butler-control-session-service.d.ts +1 -1
  99. package/dist/server/modules/butler/butler-control-session-service.js +27 -26
  100. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  101. package/dist/server/modules/butler/butler-control-timer-service.js +4 -5
  102. package/dist/server/modules/butler/butler-control-timer-service.js.map +1 -1
  103. package/dist/server/modules/butler/butler-controller.d.ts +2 -2
  104. package/dist/server/modules/butler/butler-controller.js +19 -17
  105. package/dist/server/modules/butler/butler-controller.js.map +1 -1
  106. package/dist/server/modules/butler/butler-follow-up-service.d.ts +3 -0
  107. package/dist/server/modules/butler/butler-follow-up-service.js +11 -1
  108. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  109. package/dist/server/modules/butler/butler-inbox-service.d.ts +3 -0
  110. package/dist/server/modules/butler/butler-inbox-service.js +14 -2
  111. package/dist/server/modules/butler/butler-inbox-service.js.map +1 -1
  112. package/dist/server/modules/butler/butler-profile-service.d.ts +5 -5
  113. package/dist/server/modules/butler/butler-profile-service.js +17 -16
  114. package/dist/server/modules/butler/butler-profile-service.js.map +1 -1
  115. package/dist/server/modules/butler/butler-project-service.d.ts +7 -6
  116. package/dist/server/modules/butler/butler-project-service.js +35 -21
  117. package/dist/server/modules/butler/butler-project-service.js.map +1 -1
  118. package/dist/server/modules/butler/butler-session-service.d.ts +5 -2
  119. package/dist/server/modules/butler/butler-session-service.js +51 -27
  120. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  121. package/dist/server/modules/butler/butler-session-summary-service.d.ts +2 -2
  122. package/dist/server/modules/butler/butler-session-summary-service.js +23 -9
  123. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  124. package/dist/server/modules/butler/context-aggregator.js +9 -9
  125. package/dist/server/modules/butler/context-aggregator.js.map +1 -1
  126. package/dist/server/modules/butler/patrol-execution-service.d.ts +0 -1
  127. package/dist/server/modules/butler/patrol-execution-service.js +6 -12
  128. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -1
  129. package/dist/server/modules/channels/wechat-claw-client.d.ts +51 -0
  130. package/dist/server/modules/channels/wechat-claw-client.js +245 -0
  131. package/dist/server/modules/channels/wechat-claw-client.js.map +1 -0
  132. package/dist/server/modules/file/file-controller.d.ts +11 -2
  133. package/dist/server/modules/file/file-controller.js +404 -17
  134. package/dist/server/modules/file/file-controller.js.map +1 -1
  135. package/dist/server/modules/file/file-search-service.js +200 -12
  136. package/dist/server/modules/file/file-search-service.js.map +1 -1
  137. package/dist/server/modules/file/runtime/codingns-workspace-bridge.js +18 -5
  138. package/dist/server/modules/file/workspace-file-bridge-service.d.ts +9 -0
  139. package/dist/server/modules/file/workspace-file-bridge-service.js +3 -0
  140. package/dist/server/modules/file/workspace-file-bridge-service.js.map +1 -1
  141. package/dist/server/modules/file/workspace-file-bridge-watch-service.d.ts +9 -0
  142. package/dist/server/modules/file/workspace-file-bridge-watch-service.js +28 -0
  143. package/dist/server/modules/file/workspace-file-bridge-watch-service.js.map +1 -1
  144. package/dist/server/modules/sessions/session-controller.js +3 -3
  145. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  146. package/dist/server/modules/sessions/session-history-service.d.ts +8 -3
  147. package/dist/server/modules/sessions/session-history-service.js +126 -11
  148. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  149. package/dist/server/modules/sessions/session-live-runtime-service.js +25 -15
  150. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  151. package/dist/server/modules/sessions/session-permission-request-service.js +28 -15
  152. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
  153. package/dist/server/modules/tasks/task-types.d.ts +1 -0
  154. package/dist/server/modules/tasks/task-types.js +1 -0
  155. package/dist/server/modules/tasks/task-types.js.map +1 -1
  156. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.d.ts +1 -1
  157. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js +22 -5
  158. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js.map +1 -1
  159. package/dist/server/modules/workbench/workbench-controller.d.ts +5 -0
  160. package/dist/server/modules/workbench/workbench-controller.js +20 -0
  161. package/dist/server/modules/workbench/workbench-controller.js.map +1 -1
  162. package/dist/server/modules/workbench/workbench-service.d.ts +6 -6
  163. package/dist/server/modules/workbench/workbench-service.js +42 -45
  164. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  165. package/dist/server/modules/workspace/affairs-library-controller.d.ts +8 -0
  166. package/dist/server/modules/workspace/affairs-library-controller.js +11 -0
  167. package/dist/server/modules/workspace/affairs-library-controller.js.map +1 -1
  168. package/dist/server/modules/workspace/affairs-library-preview-link-service.d.ts +6 -0
  169. package/dist/server/modules/workspace/affairs-library-preview-link-service.js +12 -2
  170. package/dist/server/modules/workspace/affairs-library-preview-link-service.js.map +1 -1
  171. package/dist/server/modules/workspace/affairs-library-service.d.ts +12 -1
  172. package/dist/server/modules/workspace/affairs-library-service.js +294 -96
  173. package/dist/server/modules/workspace/affairs-library-service.js.map +1 -1
  174. package/dist/server/modules/workspace/affairs-lightweight-session-controller.d.ts +8 -0
  175. package/dist/server/modules/workspace/affairs-lightweight-session-controller.js +55 -8
  176. package/dist/server/modules/workspace/affairs-lightweight-session-controller.js.map +1 -1
  177. package/dist/server/modules/workspace/affairs-lightweight-session-service.d.ts +13 -0
  178. package/dist/server/modules/workspace/affairs-lightweight-session-service.js +167 -21
  179. package/dist/server/modules/workspace/affairs-lightweight-session-service.js.map +1 -1
  180. package/dist/server/modules/workspace/affairs-tag-controller.d.ts +3 -0
  181. package/dist/server/modules/workspace/affairs-tag-controller.js +5 -0
  182. package/dist/server/modules/workspace/affairs-tag-controller.js.map +1 -1
  183. package/dist/server/modules/workspace/affairs-tag-service.d.ts +34 -1
  184. package/dist/server/modules/workspace/affairs-tag-service.js +568 -4
  185. package/dist/server/modules/workspace/affairs-tag-service.js.map +1 -1
  186. package/dist/server/modules/workspace/teable-api-client.d.ts +118 -0
  187. package/dist/server/modules/workspace/teable-api-client.js +142 -0
  188. package/dist/server/modules/workspace/teable-api-client.js.map +1 -0
  189. package/dist/server/modules/workspace/teable-catalog-controller.d.ts +18 -0
  190. package/dist/server/modules/workspace/teable-catalog-controller.js +17 -0
  191. package/dist/server/modules/workspace/teable-catalog-controller.js.map +1 -0
  192. package/dist/server/modules/workspace/teable-catalog-service.d.ts +36 -0
  193. package/dist/server/modules/workspace/teable-catalog-service.js +124 -0
  194. package/dist/server/modules/workspace/teable-catalog-service.js.map +1 -0
  195. package/dist/server/modules/workspace/teable-credential-service.d.ts +8 -0
  196. package/dist/server/modules/workspace/teable-credential-service.js +37 -0
  197. package/dist/server/modules/workspace/teable-credential-service.js.map +1 -0
  198. package/dist/server/modules/workspace/teable-field-mapping-controller.d.ts +25 -0
  199. package/dist/server/modules/workspace/teable-field-mapping-controller.js +31 -0
  200. package/dist/server/modules/workspace/teable-field-mapping-controller.js.map +1 -0
  201. package/dist/server/modules/workspace/teable-field-mapping-service.d.ts +38 -0
  202. package/dist/server/modules/workspace/teable-field-mapping-service.js +215 -0
  203. package/dist/server/modules/workspace/teable-field-mapping-service.js.map +1 -0
  204. package/dist/server/modules/workspace/teable-global-binding-controller.d.ts +22 -0
  205. package/dist/server/modules/workspace/teable-global-binding-controller.js +25 -0
  206. package/dist/server/modules/workspace/teable-global-binding-controller.js.map +1 -0
  207. package/dist/server/modules/workspace/teable-global-binding-service.d.ts +35 -0
  208. package/dist/server/modules/workspace/teable-global-binding-service.js +151 -0
  209. package/dist/server/modules/workspace/teable-global-binding-service.js.map +1 -0
  210. package/dist/server/modules/workspace/teable-mirror-sync-controller.d.ts +29 -0
  211. package/dist/server/modules/workspace/teable-mirror-sync-controller.js +50 -0
  212. package/dist/server/modules/workspace/teable-mirror-sync-controller.js.map +1 -0
  213. package/dist/server/modules/workspace/teable-mirror-sync-service.d.ts +157 -0
  214. package/dist/server/modules/workspace/teable-mirror-sync-service.js +917 -0
  215. package/dist/server/modules/workspace/teable-mirror-sync-service.js.map +1 -0
  216. package/dist/server/modules/workspace/teable-runtime-controller.d.ts +58 -0
  217. package/dist/server/modules/workspace/teable-runtime-controller.js +60 -0
  218. package/dist/server/modules/workspace/teable-runtime-controller.js.map +1 -0
  219. package/dist/server/modules/workspace/teable-runtime-service.d.ts +96 -0
  220. package/dist/server/modules/workspace/teable-runtime-service.js +362 -0
  221. package/dist/server/modules/workspace/teable-runtime-service.js.map +1 -0
  222. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.d.ts +22 -0
  223. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js +20 -0
  224. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js.map +1 -0
  225. package/dist/server/modules/workspace/teable-workbench-sync-config-service.d.ts +22 -0
  226. package/dist/server/modules/workspace/teable-workbench-sync-config-service.js +159 -0
  227. package/dist/server/modules/workspace/teable-workbench-sync-config-service.js.map +1 -0
  228. package/dist/server/modules/workspace/workspace-controller.d.ts +1 -1
  229. package/dist/server/modules/workspace/workspace-controller.js +7 -7
  230. package/dist/server/modules/workspace/workspace-controller.js.map +1 -1
  231. package/dist/server/modules/workspace/workspace-service.d.ts +7 -0
  232. package/dist/server/modules/workspace/workspace-service.js +151 -10
  233. package/dist/server/modules/workspace/workspace-service.js.map +1 -1
  234. package/dist/server/routes/affairs.d.ts +9 -1
  235. package/dist/server/routes/affairs.js +120 -1
  236. package/dist/server/routes/affairs.js.map +1 -1
  237. package/dist/server/routes/auth.js +6 -0
  238. package/dist/server/routes/auth.js.map +1 -1
  239. package/dist/server/routes/workbench.js +15 -0
  240. package/dist/server/routes/workbench.js.map +1 -1
  241. package/dist/server/routes/workspaces.js +51 -41
  242. package/dist/server/routes/workspaces.js.map +1 -1
  243. package/dist/server/server/create-server.d.ts +18 -0
  244. package/dist/server/server/create-server.js +99 -7
  245. package/dist/server/server/create-server.js.map +1 -1
  246. package/dist/server/server/start-host.js +20 -0
  247. package/dist/server/server/start-host.js.map +1 -1
  248. package/dist/server/shared/http/request-diagnostics.d.ts +56 -0
  249. package/dist/server/shared/http/request-diagnostics.js +256 -0
  250. package/dist/server/shared/http/request-diagnostics.js.map +1 -0
  251. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +18 -0
  252. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +191 -0
  253. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
  254. package/dist/server/storage/repositories/auth-token-repository.d.ts +1 -0
  255. package/dist/server/storage/repositories/auth-token-repository.js +8 -0
  256. package/dist/server/storage/repositories/auth-token-repository.js.map +1 -1
  257. package/dist/server/storage/repositories/auth-user-repository.d.ts +50 -0
  258. package/dist/server/storage/repositories/auth-user-repository.js +198 -27
  259. package/dist/server/storage/repositories/auth-user-repository.js.map +1 -1
  260. package/dist/server/storage/repositories/butler-control-session-repository.d.ts +4 -1
  261. package/dist/server/storage/repositories/butler-control-session-repository.js +55 -8
  262. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -1
  263. package/dist/server/storage/repositories/butler-profile-repository.d.ts +2 -1
  264. package/dist/server/storage/repositories/butler-profile-repository.js +35 -6
  265. package/dist/server/storage/repositories/butler-profile-repository.js.map +1 -1
  266. package/dist/server/storage/repositories/butler-project-repository.d.ts +2 -0
  267. package/dist/server/storage/repositories/butler-project-repository.js +38 -4
  268. package/dist/server/storage/repositories/butler-project-repository.js.map +1 -1
  269. package/dist/server/storage/repositories/butler-session-repository.d.ts +2 -1
  270. package/dist/server/storage/repositories/butler-session-repository.js +35 -6
  271. package/dist/server/storage/repositories/butler-session-repository.js.map +1 -1
  272. package/dist/server/storage/repositories/session-binding-repository.d.ts +3 -0
  273. package/dist/server/storage/repositories/session-binding-repository.js +70 -2
  274. package/dist/server/storage/repositories/session-binding-repository.js.map +1 -1
  275. package/dist/server/storage/repositories/session-index-repository.js +7 -5
  276. package/dist/server/storage/repositories/session-index-repository.js.map +1 -1
  277. package/dist/server/storage/repositories/user-affairs-library-setting-repository.js +8 -5
  278. package/dist/server/storage/repositories/user-affairs-library-setting-repository.js.map +1 -1
  279. package/dist/server/storage/repositories/user-teable-credential-repository.d.ts +9 -0
  280. package/dist/server/storage/repositories/user-teable-credential-repository.js +45 -0
  281. package/dist/server/storage/repositories/user-teable-credential-repository.js.map +1 -0
  282. package/dist/server/storage/repositories/user-teable-field-mapping-repository.d.ts +10 -0
  283. package/dist/server/storage/repositories/user-teable-field-mapping-repository.js +69 -0
  284. package/dist/server/storage/repositories/user-teable-field-mapping-repository.js.map +1 -0
  285. package/dist/server/storage/repositories/user-teable-global-setting-repository.d.ts +8 -0
  286. package/dist/server/storage/repositories/user-teable-global-setting-repository.js +52 -0
  287. package/dist/server/storage/repositories/user-teable-global-setting-repository.js.map +1 -0
  288. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.d.ts +9 -0
  289. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js +66 -0
  290. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js.map +1 -0
  291. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.d.ts +9 -0
  292. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js +67 -0
  293. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js.map +1 -0
  294. package/dist/server/storage/repositories/user-teable-sync-log-repository.d.ts +14 -0
  295. package/dist/server/storage/repositories/user-teable-sync-log-repository.js +97 -0
  296. package/dist/server/storage/repositories/user-teable-sync-log-repository.js.map +1 -0
  297. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.d.ts +8 -0
  298. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js +55 -0
  299. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js.map +1 -0
  300. package/dist/server/storage/repositories/workspace-repository.d.ts +3 -1
  301. package/dist/server/storage/repositories/workspace-repository.js +24 -10
  302. package/dist/server/storage/repositories/workspace-repository.js.map +1 -1
  303. package/dist/server/storage/sqlite/client.js +692 -1
  304. package/dist/server/storage/sqlite/client.js.map +1 -1
  305. package/dist/server/storage/sqlite/schema.sql +200 -10
  306. package/dist/server/types/domain.d.ts +114 -1
  307. package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js +34 -7
  308. package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js.map +1 -1
  309. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +3 -7
  310. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  311. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +22 -3
  312. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +29 -2
  313. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +1 -1
  314. package/node_modules/@codingns/session-sync-core/package.json +3 -1
  315. package/package.json +1 -1
  316. package/dist/public/assets/DesktopWindowPage-D0blSuKd.js +0 -2
  317. package/dist/public/assets/FileContextPanel-BrKO8Xt6.js +0 -1
  318. package/dist/public/assets/GitSidebar-BdwiDtOr.js +0 -6
  319. package/dist/public/assets/MobileCreateSessionSheet-Cx_dBiBb.js +0 -1
  320. package/dist/public/assets/SettingsPage-BlAZCHsy.js +0 -2
  321. package/dist/public/assets/TerminalManagerPanel-CjzbiWjl.js +0 -1
  322. package/dist/public/assets/WorkbenchLayout-CikJBS62.js +0 -1019
  323. package/dist/public/assets/WorkbenchShellRoute-BbbSOiZw.js +0 -1
  324. package/dist/public/assets/WorkbenchShellRoute-DT3VMjWD.css +0 -1
  325. package/dist/public/assets/WorkspaceDebugDetailPage-CVivdPx5.js +0 -1
  326. package/dist/public/assets/WorkspaceDetailPage-DgOSjscR.js +0 -1
  327. package/dist/public/assets/WorkspaceHomePage-HPa7M_Vh.js +0 -1
  328. package/dist/public/assets/index-BxJPQpFM.css +0 -1
  329. package/dist/public/assets/index-CeXGOT_T.js +0 -50
  330. package/dist/public/assets/useRegisteredDebugTemplates-Bol3NVfN.js +0 -1
  331. package/dist/public/assets/workbench-navigation-B7IjRQd8.js +0 -1
@@ -12,6 +12,7 @@ import { isIncludedHiddenPath, normalizeIncludedHiddenPaths, SUPPORTED_INDEX_EXT
12
12
  import { writeAffairsLibraryDebugLog } from "./affairs-library-debug-log.js";
13
13
  import { AFFAIRS_LIBRARY_DEBUG_EVENTS, AFFAIRS_LIBRARY_INDEX_DIRTY_REASONS, AFFAIRS_LIBRARY_RECONCILE_REASONS, AFFAIRS_LIBRARY_RECONCILE_SCOPES, AFFAIRS_LIBRARY_RECONCILE_STATUSES } from "./affairs-library-refresh-contract.js";
14
14
  import { getSharedTaskHelperPool } from "../tasks/task-helper-pool.js";
15
+ export const AFFAIRS_GLOBAL_WORKSPACE_ID = "affairs-global";
15
16
  const DEFAULT_CONFIG_RELATIVE_PATH = ".ai-index/doc-semantic-index.config.json";
16
17
  const INDEX_DIR_RELATIVE_PATH = ".ai-index";
17
18
  const EXPORT_DIR_RELATIVE_PATH = ".ai-index/exports";
@@ -38,6 +39,32 @@ const SNAPSHOT_CACHE_SCHEMA_VERSION = 2;
38
39
  const HOT_DIRECTORY_CACHE_TTL_MS = 10 * 60 * 1000;
39
40
  const HOT_DIRECTORY_MAX_PER_WORKSPACE = 3;
40
41
  const LIVE_DIRECTORY_SYNC_SCAN_MAX_DOCUMENTS = 200;
42
+ function parseDashboardStateJson(value) {
43
+ const raw = value?.trim();
44
+ if (!raw) {
45
+ return {};
46
+ }
47
+ try {
48
+ return normalizeDashboardStatePayload(JSON.parse(raw));
49
+ }
50
+ catch {
51
+ return {};
52
+ }
53
+ }
54
+ function normalizeDashboardStatePayload(value) {
55
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
56
+ throw new AppError({
57
+ statusCode: 400,
58
+ errorCode: "INVALID_INPUT",
59
+ detail: "事务工作台配置必须是对象",
60
+ field: "dashboardState"
61
+ });
62
+ }
63
+ return {
64
+ ...value,
65
+ workspaceId: AFFAIRS_GLOBAL_WORKSPACE_ID
66
+ };
67
+ }
41
68
  export class AffairsLibraryService {
42
69
  workspaceService;
43
70
  workspaceNavigationStateRepository;
@@ -60,8 +87,8 @@ export class AffairsLibraryService {
60
87
  this.syncLightweightReconcileTimers();
61
88
  }
62
89
  getGlobalBinding(userId) {
63
- const setting = this.resolveLibrarySetting(userId, null);
64
- return this.buildBindingFromSetting(setting, null);
90
+ const setting = this.resolveLibrarySetting(userId, AFFAIRS_GLOBAL_WORKSPACE_ID);
91
+ return this.buildBindingFromSetting(setting, AFFAIRS_GLOBAL_WORKSPACE_ID);
65
92
  }
66
93
  getBinding(workspaceId, userId) {
67
94
  const setting = this.resolveLibrarySetting(userId, workspaceId);
@@ -71,21 +98,20 @@ export class AffairsLibraryService {
71
98
  const normalizedRootDir = this.normalizeAndValidateBindingRootDir(rootDir);
72
99
  const timestamp = nowIso();
73
100
  const currentSetting = this.resolveLibrarySetting(userId, null);
74
- const workspaceId = this.resolvePreferredWorkspaceId(currentSetting?.lastWorkspaceId ?? null);
101
+ const workspaceId = AFFAIRS_GLOBAL_WORKSPACE_ID;
75
102
  const nextSetting = this.upsertLibrarySetting({
76
103
  userId,
77
104
  rootDir: normalizedRootDir,
78
105
  enabled: true,
79
106
  favoritesJson: currentSetting?.favoritesJson ?? "[]",
80
107
  lastWorkspaceId: workspaceId ?? currentSetting?.lastWorkspaceId ?? null,
108
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
81
109
  createdAt: currentSetting?.createdAt ?? timestamp,
82
110
  updatedAt: timestamp
83
111
  });
84
112
  this.syncLightweightReconcileTimers();
85
- if (workspaceId) {
86
- this.scheduleAutoRefresh(workspaceId, "binding_saved");
87
- }
88
- return this.buildBindingFromSetting(nextSetting, null);
113
+ this.scheduleAutoRefresh(workspaceId, "binding_saved");
114
+ return this.buildBindingFromSetting(nextSetting, AFFAIRS_GLOBAL_WORKSPACE_ID);
89
115
  }
90
116
  setGlobalEnabled(userId, enabled) {
91
117
  const currentSetting = this.resolveLibrarySetting(userId, null);
@@ -100,39 +126,61 @@ export class AffairsLibraryService {
100
126
  if (enabled) {
101
127
  this.assertLibraryRootDir(rootDir);
102
128
  }
103
- const workspaceId = this.resolvePreferredWorkspaceId(currentSetting?.lastWorkspaceId ?? null);
129
+ const workspaceId = AFFAIRS_GLOBAL_WORKSPACE_ID;
104
130
  const nextSetting = this.upsertLibrarySetting({
105
131
  userId,
106
132
  rootDir,
107
133
  enabled,
108
134
  favoritesJson: currentSetting?.favoritesJson ?? "[]",
109
135
  lastWorkspaceId: workspaceId ?? currentSetting?.lastWorkspaceId ?? null,
136
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
110
137
  createdAt: currentSetting?.createdAt ?? nowIso(),
111
138
  updatedAt: nowIso()
112
139
  });
113
140
  this.syncLightweightReconcileTimers();
114
- if (enabled && workspaceId) {
141
+ if (enabled) {
115
142
  this.scheduleAutoRefresh(workspaceId, "library_enabled");
116
143
  }
117
- return this.buildBindingFromSetting(nextSetting, null);
144
+ return this.buildBindingFromSetting(nextSetting, AFFAIRS_GLOBAL_WORKSPACE_ID);
118
145
  }
119
146
  updateGlobalFavorites(userId, favorites) {
120
147
  const currentSetting = this.resolveLibrarySetting(userId, null);
121
148
  const normalizedFavorites = this.normalizeFavorites(favorites);
122
- const workspaceId = this.resolvePreferredWorkspaceId(currentSetting?.lastWorkspaceId ?? null);
149
+ const workspaceId = AFFAIRS_GLOBAL_WORKSPACE_ID;
123
150
  const nextSetting = this.upsertLibrarySetting({
124
151
  userId,
125
152
  rootDir: currentSetting?.rootDir ?? null,
126
153
  enabled: currentSetting?.enabled ?? false,
127
154
  favoritesJson: JSON.stringify(normalizedFavorites),
128
155
  lastWorkspaceId: workspaceId ?? currentSetting?.lastWorkspaceId ?? null,
156
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
129
157
  createdAt: currentSetting?.createdAt ?? nowIso(),
130
158
  updatedAt: nowIso()
131
159
  });
132
160
  return normalizedFavorites;
133
161
  }
162
+ getGlobalDashboardState(userId) {
163
+ const currentSetting = this.resolveLibrarySetting(userId, null);
164
+ return parseDashboardStateJson(currentSetting?.dashboardStateJson);
165
+ }
166
+ updateGlobalDashboardState(userId, dashboardState) {
167
+ const normalizedState = normalizeDashboardStatePayload(dashboardState);
168
+ const currentSetting = this.resolveLibrarySetting(userId, null);
169
+ const timestamp = nowIso();
170
+ this.upsertLibrarySetting({
171
+ userId,
172
+ rootDir: currentSetting?.rootDir ?? null,
173
+ enabled: currentSetting?.enabled ?? false,
174
+ favoritesJson: currentSetting?.favoritesJson ?? "[]",
175
+ lastWorkspaceId: AFFAIRS_GLOBAL_WORKSPACE_ID,
176
+ dashboardStateJson: JSON.stringify(normalizedState),
177
+ createdAt: currentSetting?.createdAt ?? timestamp,
178
+ updatedAt: timestamp
179
+ });
180
+ return normalizedState;
181
+ }
134
182
  saveBinding(workspaceId, userId, rootDir) {
135
- this.workspaceService.getWorkspaceOrThrow(workspaceId);
183
+ this.assertWorkspaceIdCanUseLegacyAffairsRoute(workspaceId);
136
184
  const normalizedRootDir = this.normalizeAndValidateBindingRootDir(rootDir);
137
185
  const timestamp = nowIso();
138
186
  const currentSetting = this.resolveLibrarySetting(userId, workspaceId);
@@ -142,6 +190,7 @@ export class AffairsLibraryService {
142
190
  enabled: true,
143
191
  favoritesJson: currentSetting?.favoritesJson ?? "[]",
144
192
  lastWorkspaceId: workspaceId,
193
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
145
194
  createdAt: currentSetting?.createdAt ?? timestamp,
146
195
  updatedAt: timestamp
147
196
  });
@@ -150,7 +199,7 @@ export class AffairsLibraryService {
150
199
  return this.buildBindingFromSetting(nextSetting, workspaceId);
151
200
  }
152
201
  setEnabled(workspaceId, userId, enabled) {
153
- this.workspaceService.getWorkspaceOrThrow(workspaceId);
202
+ this.assertWorkspaceIdCanUseLegacyAffairsRoute(workspaceId);
154
203
  const currentSetting = this.resolveLibrarySetting(userId, workspaceId);
155
204
  const rootDir = currentSetting?.rootDir?.trim() ?? "";
156
205
  if (!rootDir) {
@@ -169,6 +218,7 @@ export class AffairsLibraryService {
169
218
  enabled,
170
219
  favoritesJson: currentSetting?.favoritesJson ?? "[]",
171
220
  lastWorkspaceId: workspaceId,
221
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
172
222
  createdAt: currentSetting?.createdAt ?? nowIso(),
173
223
  updatedAt: nowIso()
174
224
  });
@@ -308,6 +358,7 @@ export class AffairsLibraryService {
308
358
  if (!binding || !binding.enabled) {
309
359
  return {
310
360
  total: 0,
361
+ visibleEntryTotal: 0,
311
362
  offset: 0,
312
363
  limit: normalizePositiveInt(input.limit, 120, 400),
313
364
  items: [],
@@ -320,12 +371,14 @@ export class AffairsLibraryService {
320
371
  const browseMode = input.browseMode === "tag" ? "tag" : "folder";
321
372
  const offset = Math.max(0, normalizePositiveInt(input.offset, 0, Number.MAX_SAFE_INTEGER));
322
373
  const limit = normalizePositiveInt(input.limit, 120, 400);
374
+ const normalizedKeyword = normalizeDocumentSearchKeyword(input.keyword);
323
375
  const indexStatus = this.readIndexStatus(workspaceId, binding);
324
376
  const selectedFavorite = favorites.find((item) => buildFavoriteNodeId(item.kind, item.path) === (input.selectedFavoriteId?.trim() ?? "")) ?? null;
325
377
  const normalizedSelectedTagPaths = normalizeSelectedTagPaths(input.selectedTagPaths);
326
378
  if (browseMode === "folder") {
327
379
  return this.listLiveFolderDocuments(workspaceId, binding.rootDir, favorites, exportData, selectedFavorite, {
328
380
  selectedFolderPath: input.selectedFolderPath,
381
+ keyword: normalizedKeyword,
329
382
  offset,
330
383
  limit,
331
384
  indexStatus
@@ -334,6 +387,7 @@ export class AffairsLibraryService {
334
387
  if (!exportData) {
335
388
  return {
336
389
  total: 0,
390
+ visibleEntryTotal: 0,
337
391
  offset,
338
392
  limit,
339
393
  items: [],
@@ -342,12 +396,17 @@ export class AffairsLibraryService {
342
396
  };
343
397
  }
344
398
  const filtered = exportData.documents.filter((document) => {
399
+ if (!matchesDocumentKeyword(document, normalizedKeyword)) {
400
+ return false;
401
+ }
345
402
  if (browseMode === "tag") {
346
- const tagPaths = selectedFavorite?.kind === "tag"
347
- ? [selectedFavorite.path]
348
- : normalizedSelectedTagPaths.length > 0
349
- ? normalizedSelectedTagPaths
350
- : (input.selectedTagPath?.trim() ? [input.selectedTagPath.trim()] : []);
403
+ const tagPaths = selectedFavorite?.kind === "tag_filter"
404
+ ? normalizeSelectedTagPaths(selectedFavorite.tagPaths ?? selectedFavorite.path.split("|"))
405
+ : selectedFavorite?.kind === "tag"
406
+ ? [selectedFavorite.path]
407
+ : normalizedSelectedTagPaths.length > 0
408
+ ? normalizedSelectedTagPaths
409
+ : (input.selectedTagPath?.trim() ? [input.selectedTagPath.trim()] : []);
351
410
  return tagPaths.length === 0 || tagPaths.every((tagPath) => matchesTagPath(document, tagPath));
352
411
  }
353
412
  const folderPath = selectedFavorite?.kind === "folder"
@@ -366,6 +425,7 @@ export class AffairsLibraryService {
366
425
  });
367
426
  return {
368
427
  total: filtered.length,
428
+ visibleEntryTotal: filtered.length,
369
429
  offset,
370
430
  limit,
371
431
  items,
@@ -409,7 +469,7 @@ export class AffairsLibraryService {
409
469
  ? fallbackResult.source
410
470
  : directoryResult.source;
411
471
  if (!liveScanDecision.avoidSyncScan) {
412
- this.updateHotDirectoryCache(workspaceId, rootDir, normalizedDirectoryPath, items, directoryResult.source, {
472
+ this.updateHotDirectoryCache(workspaceId, rootDir, normalizedDirectoryPath, items, directoryResult.childDirectoryCount, directoryResult.source, {
413
473
  preserveStatus: directoryStatus.state === "running" || directoryStatus.state === "queued"
414
474
  || directoryStatus.state === "queue_timeout",
415
475
  generatedAt: directoryResult.generatedAt,
@@ -436,6 +496,7 @@ export class AffairsLibraryService {
436
496
  else {
437
497
  const fallbackEntry = this.getOrCreateHotDirectoryEntry(workspaceId, rootDir, normalizedDirectoryPath);
438
498
  fallbackEntry.items = directoryResult.items;
499
+ fallbackEntry.childDirectoryCount = directoryResult.childDirectoryCount;
439
500
  fallbackEntry.source = directoryResult.source;
440
501
  fallbackEntry.generatedAt = directoryResult.generatedAt;
441
502
  fallbackEntry.filesystemObservedAt = directoryResult.filesystemObservedAt;
@@ -455,7 +516,12 @@ export class AffairsLibraryService {
455
516
  && directoryStatus.state !== "queued") {
456
517
  this.scheduleDirectoryHintRefresh(workspaceId, normalizedDirectoryPath, "large_directory_live_scan");
457
518
  }
458
- const resultItems = items.slice(input.offset, input.offset + input.limit);
519
+ const keyword = input.keyword?.trim() ?? "";
520
+ const filteredItems = keyword
521
+ ? items.filter((item) => matchesDocumentKeyword(item, keyword))
522
+ : items;
523
+ const resultItems = filteredItems.slice(input.offset, input.offset + input.limit);
524
+ const visibleEntryTotal = directoryResult.childDirectoryCount + filteredItems.length;
459
525
  writeAffairsLibraryDebugLog({
460
526
  event: "folder_list_served",
461
527
  processRole: "host",
@@ -473,7 +539,9 @@ export class AffairsLibraryService {
473
539
  generatedAt: directoryResult.generatedAt,
474
540
  filesystemObservedAt: directoryResult.filesystemObservedAt,
475
541
  estimatedDocumentCount: liveScanDecision.estimatedDocumentCount,
476
- total: items.length,
542
+ total: filteredItems.length,
543
+ visibleEntryTotal,
544
+ childDirectoryCount: directoryResult.childDirectoryCount,
477
545
  returned: resultItems.length,
478
546
  offset: input.offset,
479
547
  limit: input.limit,
@@ -481,7 +549,8 @@ export class AffairsLibraryService {
481
549
  }
482
550
  });
483
551
  return {
484
- total: items.length,
552
+ total: filteredItems.length,
553
+ visibleEntryTotal,
485
554
  offset: input.offset,
486
555
  limit: input.limit,
487
556
  items: resultItems,
@@ -574,6 +643,7 @@ export class AffairsLibraryService {
574
643
  if (cached && cached.items.length > 0) {
575
644
  return {
576
645
  items: cached.items,
646
+ childDirectoryCount: cached.childDirectoryCount,
577
647
  source: staleReason ? "stale_fallback" : cached.source,
578
648
  generatedAt: cached.generatedAt,
579
649
  filesystemObservedAt: cached.filesystemObservedAt,
@@ -598,6 +668,7 @@ export class AffairsLibraryService {
598
668
  }));
599
669
  return {
600
670
  items,
671
+ childDirectoryCount: countDirectChildFoldersFromSnapshot(normalizedFolderPath, exportData),
601
672
  source: directoryStatus?.source ?? "snapshot",
602
673
  generatedAt: exportData?.generatedAt ?? directoryStatus?.generatedAt ?? null,
603
674
  filesystemObservedAt: directoryStatus?.filesystemObservedAt ?? null,
@@ -633,7 +704,7 @@ export class AffairsLibraryService {
633
704
  });
634
705
  }
635
706
  updateFavorites(workspaceId, userId, favorites) {
636
- this.workspaceService.getWorkspaceOrThrow(workspaceId);
707
+ this.assertWorkspaceIdCanUseLegacyAffairsRoute(workspaceId);
637
708
  const currentSetting = this.resolveLibrarySetting(userId, workspaceId);
638
709
  const normalizedFavorites = this.normalizeFavorites(favorites);
639
710
  const nextSetting = this.upsertLibrarySetting({
@@ -642,6 +713,7 @@ export class AffairsLibraryService {
642
713
  enabled: currentSetting?.enabled ?? false,
643
714
  favoritesJson: JSON.stringify(normalizedFavorites),
644
715
  lastWorkspaceId: workspaceId,
716
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
645
717
  createdAt: currentSetting?.createdAt ?? nowIso(),
646
718
  updatedAt: nowIso()
647
719
  });
@@ -832,13 +904,18 @@ export class AffairsLibraryService {
832
904
  };
833
905
  }
834
906
  if (opType === "delete") {
907
+ const refreshTargetPath = source.stats?.isDirectory()
908
+ ? source.relativePath
909
+ : getParentFolderPath(source.relativePath);
910
+ const deletedPath = source.relativePath;
835
911
  if (source.stats?.isDirectory()) {
836
912
  fs.rmSync(source.absolutePath, { recursive: true, force: false });
837
913
  }
838
914
  else {
839
915
  fs.rmSync(source.absolutePath, { force: false });
840
916
  }
841
- this.afterFileMutation(workspaceId, source.rootDir, `library_delete:${source.relativePath}`, source.relativePath);
917
+ this.removePathFromHotDirectoryCache(workspaceId, source.rootDir, deletedPath);
918
+ this.afterFileMutation(workspaceId, source.rootDir, `library_delete:${source.relativePath}`, source.relativePath, { refreshTargetPath });
842
919
  return {
843
920
  success: true,
844
921
  opType,
@@ -974,9 +1051,9 @@ export class AffairsLibraryService {
974
1051
  });
975
1052
  }
976
1053
  }
977
- afterFileMutation(workspaceId, rootDir, reason, targetPath) {
1054
+ afterFileMutation(workspaceId, rootDir, reason, targetPath, options = {}) {
978
1055
  this.invalidateExportCache(rootDir);
979
- this.scheduleAutoRefresh(workspaceId, reason, normalizeMutationRefreshTarget(targetPath) ?? undefined);
1056
+ this.scheduleAutoRefresh(workspaceId, reason, normalizeMutationRefreshTarget(options.refreshTargetPath ?? targetPath) ?? undefined);
980
1057
  }
981
1058
  requestRefresh(workspaceId, userId, reason) {
982
1059
  const binding = this.requireBinding(workspaceId, userId);
@@ -1086,7 +1163,9 @@ export class AffairsLibraryService {
1086
1163
  if (relativePath === ".ai-index" || relativePath.startsWith(".ai-index/")) {
1087
1164
  return;
1088
1165
  }
1089
- const targetPath = normalizeMutationRefreshTarget(relativePath);
1166
+ const targetPath = normalizeMutationRefreshTarget(input.kind === "delete"
1167
+ ? getParentFolderPath(relativePath)
1168
+ : relativePath);
1090
1169
  if (!targetPath) {
1091
1170
  return;
1092
1171
  }
@@ -1581,6 +1660,7 @@ export class AffairsLibraryService {
1581
1660
  rootDir,
1582
1661
  directoryPath: normalizedDirectoryPath,
1583
1662
  items: [],
1663
+ childDirectoryCount: 0,
1584
1664
  updatedAtMs: 0,
1585
1665
  source: "snapshot",
1586
1666
  dirty: true,
@@ -1598,10 +1678,11 @@ export class AffairsLibraryService {
1598
1678
  this.hotDirectoryCache.set(cacheKey, entry);
1599
1679
  return entry;
1600
1680
  }
1601
- updateHotDirectoryCache(workspaceId, rootDir, directoryPath, items, source, options = {}) {
1681
+ updateHotDirectoryCache(workspaceId, rootDir, directoryPath, items, childDirectoryCount, source, options = {}) {
1602
1682
  const entry = this.getOrCreateHotDirectoryEntry(workspaceId, rootDir, directoryPath);
1603
1683
  entry.rootDir = rootDir;
1604
1684
  entry.items = items;
1685
+ entry.childDirectoryCount = childDirectoryCount;
1605
1686
  entry.updatedAtMs = Date.now();
1606
1687
  entry.source = source;
1607
1688
  entry.lastRefreshRequestedAt = options.requestedAt ?? entry.lastRefreshRequestedAt;
@@ -1635,6 +1716,38 @@ export class AffairsLibraryService {
1635
1716
  entry.staleReason = null;
1636
1717
  this.ensureDirectoryWindow(workspaceId, rootDir, directoryPath);
1637
1718
  }
1719
+ removePathFromHotDirectoryCache(workspaceId, rootDir, targetPath) {
1720
+ const normalizedTargetPath = normalizeMutationRefreshTarget(targetPath);
1721
+ if (!normalizedTargetPath) {
1722
+ return;
1723
+ }
1724
+ const deletedDirectoryPath = normalizeFolderPath(normalizedTargetPath);
1725
+ const parentDirectoryPath = normalizeFolderPath(getParentFolderPath(normalizedTargetPath));
1726
+ for (const entry of this.hotDirectoryCache.values()) {
1727
+ if (entry.workspaceId !== workspaceId || entry.rootDir !== rootDir) {
1728
+ continue;
1729
+ }
1730
+ const normalizedEntryDirectoryPath = normalizeFolderPath(entry.directoryPath);
1731
+ const beforeCount = entry.items.length;
1732
+ entry.items = entry.items.filter((item) => {
1733
+ const itemPath = normalizeMutationRefreshTarget(item.path);
1734
+ if (!itemPath) {
1735
+ return false;
1736
+ }
1737
+ return itemPath !== normalizedTargetPath && !itemPath.startsWith(`${normalizedTargetPath}/`);
1738
+ });
1739
+ if (beforeCount !== entry.items.length
1740
+ || normalizedEntryDirectoryPath === parentDirectoryPath
1741
+ || normalizedEntryDirectoryPath === deletedDirectoryPath
1742
+ || normalizedEntryDirectoryPath.startsWith(`${deletedDirectoryPath}/`)) {
1743
+ entry.dirty = true;
1744
+ entry.status = entry.status === "running" ? "running" : "idle";
1745
+ entry.pendingHintReasons.add(`library_delete:${normalizedTargetPath}`);
1746
+ entry.lastHintAt = nowIso();
1747
+ entry.staleReason = null;
1748
+ }
1749
+ }
1750
+ }
1638
1751
  ensureDirectoryWindow(workspaceId, rootDir, directoryPath) {
1639
1752
  const entry = this.getOrCreateHotDirectoryEntry(workspaceId, rootDir, directoryPath);
1640
1753
  entry.updatedAtMs = Math.max(entry.updatedAtMs, Date.now());
@@ -1721,6 +1834,7 @@ export class AffairsLibraryService {
1721
1834
  refreshedAt: completedAt,
1722
1835
  source: liveResult.source,
1723
1836
  itemCount: liveResult.items.length,
1837
+ childDirectoryCount: liveResult.childDirectoryCount,
1724
1838
  changedPaths,
1725
1839
  items: liveResult.items,
1726
1840
  generatedAt: liveResult.generatedAt,
@@ -1742,7 +1856,7 @@ export class AffairsLibraryService {
1742
1856
  status: "queued"
1743
1857
  });
1744
1858
  void handle.promise.then((result) => {
1745
- this.updateHotDirectoryCache(workspaceId, meta.rootDir, meta.directoryPath, result.items, result.source, {
1859
+ this.updateHotDirectoryCache(workspaceId, meta.rootDir, meta.directoryPath, result.items, result.childDirectoryCount, result.source, {
1746
1860
  requestedAt: this.getOrCreateHotDirectoryEntry(workspaceId, meta.rootDir, meta.directoryPath).lastRefreshRequestedAt,
1747
1861
  completedAt: result.refreshedAt,
1748
1862
  errorSummary: null,
@@ -1804,11 +1918,14 @@ export class AffairsLibraryService {
1804
1918
  }
1805
1919
  return parsed
1806
1920
  .filter((item) => Boolean(item) && typeof item === "object")
1807
- .filter((item) => (item.kind === "folder" || item.kind === "tag") && typeof item.path === "string" && item.path.trim())
1921
+ .filter((item) => isAffairsLibraryFavoriteKind(item.kind) && typeof item.path === "string" && item.path.trim())
1808
1922
  .map((item) => ({
1809
1923
  kind: item.kind,
1810
1924
  path: item.path.trim(),
1811
- label: typeof item.label === "string" && item.label.trim() ? item.label.trim() : item.path.trim()
1925
+ label: typeof item.label === "string" && item.label.trim() ? item.label.trim() : item.path.trim(),
1926
+ ...(item.kind === "tag_filter"
1927
+ ? { tagPaths: normalizeSelectedTagPaths(Array.isArray(item.tagPaths) ? item.tagPaths : item.path.split("|")) }
1928
+ : {})
1812
1929
  }));
1813
1930
  }
1814
1931
  catch {
@@ -2735,7 +2852,9 @@ export class AffairsLibraryService {
2735
2852
  }
2736
2853
  const config = this.readConfig(rootDir);
2737
2854
  return {
2738
- workspaceId: setting?.lastWorkspaceId ?? fallbackWorkspaceId,
2855
+ workspaceId: fallbackWorkspaceId === AFFAIRS_GLOBAL_WORKSPACE_ID
2856
+ ? AFFAIRS_GLOBAL_WORKSPACE_ID
2857
+ : setting?.lastWorkspaceId ?? fallbackWorkspaceId,
2739
2858
  rootDir,
2740
2859
  enabled: setting?.enabled === true,
2741
2860
  mirrorRoot: config.mirrorRoot,
@@ -2786,7 +2905,8 @@ export class AffairsLibraryService {
2786
2905
  rootDir: legacyRootDir,
2787
2906
  enabled: legacy?.affairsLibraryEnabled === true,
2788
2907
  favoritesJson: legacy?.affairsLibraryFavoritesJson ?? "[]",
2789
- lastWorkspaceId: legacy?.workspaceId ?? (workspaceScope || null),
2908
+ lastWorkspaceId: AFFAIRS_GLOBAL_WORKSPACE_ID,
2909
+ dashboardStateJson: currentSetting?.dashboardStateJson ?? "{}",
2790
2910
  createdAt: currentSetting?.createdAt ?? legacy?.updatedAt ?? nowIso(),
2791
2911
  updatedAt: legacy?.updatedAt ?? nowIso()
2792
2912
  });
@@ -2798,7 +2918,8 @@ export class AffairsLibraryService {
2798
2918
  rootDir: record.rootDir?.trim() || null,
2799
2919
  enabled: record.enabled === true,
2800
2920
  favoritesJson: record.favoritesJson ?? null,
2801
- lastWorkspaceId: record.lastWorkspaceId?.trim() || null,
2921
+ lastWorkspaceId: this.normalizeAffairsWorkspaceId(record.lastWorkspaceId),
2922
+ dashboardStateJson: record.dashboardStateJson?.trim() || "{}",
2802
2923
  createdAt: record.createdAt,
2803
2924
  updatedAt: record.updatedAt
2804
2925
  });
@@ -2807,7 +2928,7 @@ export class AffairsLibraryService {
2807
2928
  if (typeof this.userAffairsLibrarySettingRepository.listEnabled === "function") {
2808
2929
  return this.userAffairsLibrarySettingRepository
2809
2930
  .listEnabled()
2810
- .filter((item) => Boolean(item.lastWorkspaceId?.trim() && item.rootDir?.trim()));
2931
+ .filter((item) => Boolean(item.rootDir?.trim()));
2811
2932
  }
2812
2933
  return this.workspaceNavigationStateRepository
2813
2934
  .listEnabledAffairsLibraries()
@@ -2816,19 +2937,26 @@ export class AffairsLibraryService {
2816
2937
  rootDir: item.affairsLibraryRootPath ?? null,
2817
2938
  enabled: item.affairsLibraryEnabled === true,
2818
2939
  favoritesJson: item.affairsLibraryFavoritesJson ?? null,
2819
- lastWorkspaceId: item.workspaceId,
2940
+ lastWorkspaceId: AFFAIRS_GLOBAL_WORKSPACE_ID,
2941
+ dashboardStateJson: "{}",
2820
2942
  createdAt: item.updatedAt,
2821
2943
  updatedAt: item.updatedAt
2822
2944
  }))
2823
- .filter((item) => Boolean(item.lastWorkspaceId?.trim() && item.rootDir?.trim()));
2945
+ .filter((item) => Boolean(item.rootDir?.trim()));
2824
2946
  }
2825
2947
  findEnabledBindingByWorkspaceId(workspaceId) {
2826
- const normalizedWorkspaceId = workspaceId.trim();
2827
- if (!normalizedWorkspaceId) {
2828
- return null;
2829
- }
2948
+ const normalizedWorkspaceId = this.normalizeAffairsWorkspaceId(workspaceId);
2830
2949
  if (typeof this.userAffairsLibrarySettingRepository.findEnabledByWorkspaceId === "function") {
2831
- return this.userAffairsLibrarySettingRepository.findEnabledByWorkspaceId(normalizedWorkspaceId);
2950
+ const direct = this.userAffairsLibrarySettingRepository.findEnabledByWorkspaceId(normalizedWorkspaceId);
2951
+ if (direct) {
2952
+ return direct;
2953
+ }
2954
+ if (normalizedWorkspaceId === AFFAIRS_GLOBAL_WORKSPACE_ID && typeof this.userAffairsLibrarySettingRepository.listEnabled === "function") {
2955
+ return this.userAffairsLibrarySettingRepository
2956
+ .listEnabled()
2957
+ .find((item) => item.rootDir?.trim() && item.enabled === true) ?? null;
2958
+ }
2959
+ return null;
2832
2960
  }
2833
2961
  const legacy = this.workspaceNavigationStateRepository.findAnyEnabledAffairsLibraryByWorkspaceId(normalizedWorkspaceId);
2834
2962
  if (!legacy?.affairsLibraryRootPath?.trim()) {
@@ -2840,10 +2968,21 @@ export class AffairsLibraryService {
2840
2968
  enabled: legacy.affairsLibraryEnabled === true,
2841
2969
  favoritesJson: legacy.affairsLibraryFavoritesJson ?? null,
2842
2970
  lastWorkspaceId: legacy.workspaceId,
2971
+ dashboardStateJson: "{}",
2843
2972
  createdAt: legacy.updatedAt,
2844
2973
  updatedAt: legacy.updatedAt
2845
2974
  };
2846
2975
  }
2976
+ normalizeAffairsWorkspaceId(workspaceId) {
2977
+ return workspaceId?.trim() || AFFAIRS_GLOBAL_WORKSPACE_ID;
2978
+ }
2979
+ assertWorkspaceIdCanUseLegacyAffairsRoute(workspaceId) {
2980
+ const normalizedWorkspaceId = workspaceId.trim();
2981
+ if (!normalizedWorkspaceId || normalizedWorkspaceId === AFFAIRS_GLOBAL_WORKSPACE_ID) {
2982
+ return;
2983
+ }
2984
+ this.workspaceService.getWorkspaceOrThrow(normalizedWorkspaceId);
2985
+ }
2847
2986
  normalizeAndValidateBindingRootDir(rootDir) {
2848
2987
  const normalizedRootDir = rootDir.trim();
2849
2988
  if (!normalizedRootDir) {
@@ -2874,25 +3013,18 @@ export class AffairsLibraryService {
2874
3013
  }
2875
3014
  normalizeFavorites(favorites) {
2876
3015
  return favorites
2877
- .filter((item) => item && (item.kind === "folder" || item.kind === "tag") && item.path.trim())
3016
+ .filter((item) => item && isAffairsLibraryFavoriteKind(item.kind) && item.path.trim())
2878
3017
  .map((item) => ({
2879
3018
  kind: item.kind,
2880
3019
  path: item.path.trim(),
2881
- label: item.label.trim() || item.path.trim()
3020
+ label: item.label.trim() || item.path.trim(),
3021
+ ...(item.kind === "tag_filter"
3022
+ ? { tagPaths: normalizeSelectedTagPaths(item.tagPaths ?? item.path.split("|")) }
3023
+ : {})
2882
3024
  }));
2883
3025
  }
2884
3026
  resolvePreferredWorkspaceId(preferredWorkspaceId) {
2885
- const normalizedPreferredWorkspaceId = preferredWorkspaceId?.trim() ?? "";
2886
- if (normalizedPreferredWorkspaceId) {
2887
- try {
2888
- this.workspaceService.getWorkspaceOrThrow(normalizedPreferredWorkspaceId);
2889
- return normalizedPreferredWorkspaceId;
2890
- }
2891
- catch {
2892
- // 旧的随机 workspaceId 已经失效时,直接降级到当前仍可见的工作区。
2893
- }
2894
- }
2895
- return this.workspaceService.list()[0]?.id ?? null;
3027
+ return this.normalizeAffairsWorkspaceId(preferredWorkspaceId);
2896
3028
  }
2897
3029
  ensureLibraryEnabled(binding) {
2898
3030
  if (binding.enabled) {
@@ -3113,7 +3245,7 @@ function resolveAffairsLibraryRelativePath(rootDir, absolutePath) {
3113
3245
  return relativePath;
3114
3246
  }
3115
3247
  function normalizeMutationRefreshTarget(relativePath) {
3116
- const normalizedPath = relativePath.trim().replace(/^\.\/+/, "").replace(/\/+$/, "");
3248
+ const normalizedPath = relativePath?.trim().replace(/^\.\/+/, "").replace(/\/+$/, "") ?? "";
3117
3249
  return normalizedPath || null;
3118
3250
  }
3119
3251
  function normalizeHintTargetPath(targetPath) {
@@ -3209,16 +3341,38 @@ function shouldForceFullRebuild(reason) {
3209
3341
  || normalizedReason.includes(AFFAIRS_LIBRARY_INDEX_DIRTY_REASONS.missingExportStatus)
3210
3342
  || normalizedReason.includes(AFFAIRS_LIBRARY_INDEX_DIRTY_REASONS.missingExportManifest);
3211
3343
  }
3344
+ function normalizeDocumentSearchKeyword(value) {
3345
+ return value?.trim().toLowerCase() ?? "";
3346
+ }
3347
+ function matchesDocumentKeyword(document, normalizedKeyword) {
3348
+ if (!normalizedKeyword) {
3349
+ return true;
3350
+ }
3351
+ return [
3352
+ document.title,
3353
+ document.path,
3354
+ document.summary,
3355
+ ...document.tags,
3356
+ ...document.derivedTags
3357
+ ].some((value) => value?.toLowerCase().includes(normalizedKeyword));
3358
+ }
3212
3359
  function matchesFavorite(favorite, documentPath, directTags, derivedTags) {
3213
3360
  if (favorite.kind === "folder") {
3214
3361
  const normalizedPath = favorite.path === "." ? "" : favorite.path.replace(/\/+$/g, "");
3215
3362
  return !normalizedPath || documentPath === normalizedPath || documentPath.startsWith(`${normalizedPath}/`);
3216
3363
  }
3364
+ if (favorite.kind === "tag_filter") {
3365
+ const tagPaths = normalizeSelectedTagPaths(favorite.tagPaths ?? favorite.path.split("|"));
3366
+ return tagPaths.length > 0 && tagPaths.every((tagPath) => ([...directTags, ...derivedTags].some((tag) => tag === tagPath || tag.startsWith(`${tagPath}/`))));
3367
+ }
3217
3368
  return [...directTags, ...derivedTags].some((tag) => tag === favorite.path || tag.startsWith(`${favorite.path}/`));
3218
3369
  }
3219
3370
  function buildFavoriteNodeId(kind, pathValue) {
3220
3371
  return `library:favorite:${kind}:${pathValue}`;
3221
3372
  }
3373
+ function isAffairsLibraryFavoriteKind(kind) {
3374
+ return kind === "folder" || kind === "tag" || kind === "tag_filter";
3375
+ }
3222
3376
  function matchesTagPath(document, tagPath) {
3223
3377
  const normalizedTagPath = tagPath.trim();
3224
3378
  if (!normalizedTagPath) {
@@ -3331,6 +3485,44 @@ function readAffairsLibraryConfigSafe(rootDir) {
3331
3485
  folderOpenBehavior: normalizeFolderOpenBehavior(payload.folderOpenBehavior)
3332
3486
  };
3333
3487
  }
3488
+ function countDirectChildFoldersFromSnapshot(normalizedFolderPath, exportData) {
3489
+ if (!exportData) {
3490
+ return 0;
3491
+ }
3492
+ const normalizedCurrentPath = normalizeFolderPath(normalizedFolderPath);
3493
+ return exportData.folders.filter((folder) => normalizeFolderPath(folder.parentPath) === normalizedCurrentPath).length;
3494
+ }
3495
+ function countVisibleDirectChildDirectories(targetDir, normalizedFolderPath, includedHiddenPaths) {
3496
+ if (!fs.existsSync(targetDir)) {
3497
+ return 0;
3498
+ }
3499
+ let stats = null;
3500
+ try {
3501
+ stats = fs.statSync(targetDir);
3502
+ }
3503
+ catch {
3504
+ stats = null;
3505
+ }
3506
+ if (!stats?.isDirectory()) {
3507
+ return 0;
3508
+ }
3509
+ let count = 0;
3510
+ for (const entry of fs.readdirSync(targetDir, { withFileTypes: true })) {
3511
+ if (!entry.isDirectory() || entry.isSymbolicLink()) {
3512
+ continue;
3513
+ }
3514
+ const relativePath = normalizedFolderPath ? `${normalizedFolderPath}/${entry.name}` : entry.name;
3515
+ if (relativePath === '.ai-index' || relativePath.startsWith('.ai-index/')) {
3516
+ continue;
3517
+ }
3518
+ if ((entry.name.startsWith('.') || hasHiddenPathSegment(relativePath))
3519
+ && !isIncludedHiddenPath(relativePath, includedHiddenPaths)) {
3520
+ continue;
3521
+ }
3522
+ count += 1;
3523
+ }
3524
+ return count;
3525
+ }
3334
3526
  function buildAffairsFolderDocumentsFromFilesystem(rootDir, normalizedFolderPath, exportData, config, supportedExtensions = new Set(SUPPORTED_INDEX_EXTENSION_LIST)) {
3335
3527
  const targetDir = normalizedFolderPath
3336
3528
  ? path.resolve(rootDir, normalizedFolderPath)
@@ -3339,6 +3531,16 @@ function buildAffairsFolderDocumentsFromFilesystem(rootDir, normalizedFolderPath
3339
3531
  const documentMap = new Map();
3340
3532
  let hasSnapshotData = false;
3341
3533
  let hasLiveData = false;
3534
+ let targetStats = null;
3535
+ if (fs.existsSync(targetDir)) {
3536
+ try {
3537
+ targetStats = fs.statSync(targetDir);
3538
+ }
3539
+ catch {
3540
+ targetStats = null;
3541
+ }
3542
+ }
3543
+ const canVerifyLiveFiles = targetStats?.isDirectory() === true;
3342
3544
  for (const document of exportData?.documents ?? []) {
3343
3545
  if (!matchesDirectFolder(document.path, normalizedFolderPath)) {
3344
3546
  continue;
@@ -3351,6 +3553,9 @@ function buildAffairsFolderDocumentsFromFilesystem(rootDir, normalizedFolderPath
3351
3553
  continue;
3352
3554
  }
3353
3555
  const stat = readAffairsLibraryStatsSafe(rootDir, document.path);
3556
+ if (canVerifyLiveFiles && !stat?.isFile()) {
3557
+ continue;
3558
+ }
3354
3559
  documentMap.set(document.path, {
3355
3560
  ...document,
3356
3561
  createdAt: document.createdAt ?? toIsoOrNull(stat?.birthtime),
@@ -3360,51 +3565,43 @@ function buildAffairsFolderDocumentsFromFilesystem(rootDir, normalizedFolderPath
3360
3565
  });
3361
3566
  hasSnapshotData = true;
3362
3567
  }
3363
- if (fs.existsSync(targetDir)) {
3364
- let targetStats = null;
3365
- try {
3366
- targetStats = fs.statSync(targetDir);
3367
- }
3368
- catch {
3369
- targetStats = null;
3370
- }
3371
- if (targetStats?.isDirectory()) {
3372
- for (const entry of fs.readdirSync(targetDir, { withFileTypes: true })) {
3373
- const relativePath = normalizedFolderPath ? `${normalizedFolderPath}/${entry.name}` : entry.name;
3374
- if ((entry.name.startsWith(".") || hasHiddenPathSegment(relativePath))
3375
- && !isIncludedHiddenPath(relativePath, config.includedHiddenPaths)) {
3376
- continue;
3377
- }
3378
- if (!entry.isFile()) {
3379
- continue;
3380
- }
3381
- const extension = path.extname(entry.name).toLowerCase();
3382
- if (!supportedExtensions.has(extension)) {
3383
- continue;
3384
- }
3385
- if (configuredExtensions.size > 0 && !configuredExtensions.has(extension)) {
3386
- continue;
3387
- }
3388
- const stat = readAffairsLibraryStatsSafe(rootDir, relativePath);
3389
- const exported = documentMap.get(relativePath);
3390
- documentMap.set(relativePath, {
3391
- documentId: exported?.documentId ?? relativePath,
3392
- path: relativePath,
3393
- title: exported?.title?.trim() || path.basename(entry.name, extension) || entry.name,
3394
- summary: exported?.summary ?? "",
3395
- updatedAt: stat?.mtime.toISOString() ?? exported?.updatedAt ?? "",
3396
- createdAt: toIsoOrNull(stat?.birthtime) ?? exported?.createdAt ?? null,
3397
- sizeBytes: stat?.size ?? exported?.sizeBytes ?? null,
3398
- tags: exported?.tags ?? [],
3399
- derivedTags: exported?.derivedTags ?? [],
3400
- isFavorite: false
3401
- });
3402
- hasLiveData = true;
3568
+ if (targetStats?.isDirectory()) {
3569
+ for (const entry of fs.readdirSync(targetDir, { withFileTypes: true })) {
3570
+ const relativePath = normalizedFolderPath ? `${normalizedFolderPath}/${entry.name}` : entry.name;
3571
+ if ((entry.name.startsWith(".") || hasHiddenPathSegment(relativePath))
3572
+ && !isIncludedHiddenPath(relativePath, config.includedHiddenPaths)) {
3573
+ continue;
3403
3574
  }
3575
+ if (!entry.isFile()) {
3576
+ continue;
3577
+ }
3578
+ const extension = path.extname(entry.name).toLowerCase();
3579
+ if (!supportedExtensions.has(extension)) {
3580
+ continue;
3581
+ }
3582
+ if (configuredExtensions.size > 0 && !configuredExtensions.has(extension)) {
3583
+ continue;
3584
+ }
3585
+ const stat = readAffairsLibraryStatsSafe(rootDir, relativePath);
3586
+ const exported = documentMap.get(relativePath);
3587
+ documentMap.set(relativePath, {
3588
+ documentId: exported?.documentId ?? relativePath,
3589
+ path: relativePath,
3590
+ title: exported?.title?.trim() || path.basename(entry.name, extension) || entry.name,
3591
+ summary: exported?.summary ?? "",
3592
+ updatedAt: stat?.mtime.toISOString() ?? exported?.updatedAt ?? "",
3593
+ createdAt: toIsoOrNull(stat?.birthtime) ?? exported?.createdAt ?? null,
3594
+ sizeBytes: stat?.size ?? exported?.sizeBytes ?? null,
3595
+ tags: exported?.tags ?? [],
3596
+ derivedTags: exported?.derivedTags ?? [],
3597
+ isFavorite: false
3598
+ });
3599
+ hasLiveData = true;
3404
3600
  }
3405
3601
  }
3406
3602
  return {
3407
3603
  items: [...documentMap.values()],
3604
+ childDirectoryCount: countVisibleDirectChildDirectories(targetDir, normalizedFolderPath, config.includedHiddenPaths),
3408
3605
  source: hasLiveData && hasSnapshotData
3409
3606
  ? "mixed"
3410
3607
  : hasLiveData
@@ -3426,6 +3623,7 @@ export async function runAffairsLibraryDirectoryHintInHelper(input) {
3426
3623
  refreshedAt: nowIso(),
3427
3624
  source: result.source,
3428
3625
  itemCount: result.items.length,
3626
+ childDirectoryCount: result.childDirectoryCount,
3429
3627
  changedPaths: result.items.map((item) => item.path).sort((left, right) => left.localeCompare(right, "zh-CN")),
3430
3628
  items: result.items,
3431
3629
  generatedAt: result.generatedAt,