@vheins/local-memory-mcp 0.5.32 → 0.6.0

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 (506) hide show
  1. package/README.md +9 -6
  2. package/dist/chunk-XIJO63UU.js +3618 -0
  3. package/dist/dashboard/public/assets/{index-C8FB4maW.css → index-Bd7v94SO.css} +1 -1
  4. package/dist/dashboard/public/assets/index-Df97JpLg.js +84 -0
  5. package/dist/dashboard/public/index.html +2 -2
  6. package/dist/dashboard/server.js +790 -451
  7. package/dist/mcp/server.js +2121 -305
  8. package/dist/{mcp/prompts/definitions → prompts}/create-task.md +4 -3
  9. package/dist/{mcp/prompts/definitions → prompts}/memory-agent-core.md +2 -0
  10. package/dist/{mcp/prompts/definitions → prompts}/memory-index-policy.md +2 -0
  11. package/dist/{mcp/prompts/definitions → prompts}/review-and-audit.md +3 -1
  12. package/dist/{mcp/prompts/definitions → prompts}/review-and-post-issue.md +3 -1
  13. package/dist/prompts/task-management-guidelines.md +28 -0
  14. package/dist/{mcp/prompts/definitions → prompts}/task-memory-executor.md +6 -5
  15. package/package.json +22 -6
  16. package/dist/capabilities.d.ts +0 -22
  17. package/dist/capabilities.d.ts.map +0 -1
  18. package/dist/capabilities.js +0 -38
  19. package/dist/capabilities.js.map +0 -1
  20. package/dist/completion.d.ts +0 -25
  21. package/dist/completion.d.ts.map +0 -1
  22. package/dist/completion.js +0 -127
  23. package/dist/completion.js.map +0 -1
  24. package/dist/dashboard/dashboard.test.d.ts +0 -2
  25. package/dist/dashboard/dashboard.test.d.ts.map +0 -1
  26. package/dist/dashboard/dashboard.test.js +0 -370
  27. package/dist/dashboard/dashboard.test.js.map +0 -1
  28. package/dist/dashboard/public/assets/index-DIhCu9qA.js +0 -78
  29. package/dist/dashboard/server.d.ts +0 -3
  30. package/dist/dashboard/server.d.ts.map +0 -1
  31. package/dist/dashboard/server.js.map +0 -1
  32. package/dist/e2e.test.d.ts +0 -2
  33. package/dist/e2e.test.d.ts.map +0 -1
  34. package/dist/e2e.test.js +0 -250
  35. package/dist/e2e.test.js.map +0 -1
  36. package/dist/mcp/capabilities.d.ts +0 -22
  37. package/dist/mcp/capabilities.d.ts.map +0 -1
  38. package/dist/mcp/capabilities.js +0 -38
  39. package/dist/mcp/capabilities.js.map +0 -1
  40. package/dist/mcp/client.d.ts +0 -34
  41. package/dist/mcp/client.d.ts.map +0 -1
  42. package/dist/mcp/client.js +0 -188
  43. package/dist/mcp/client.js.map +0 -1
  44. package/dist/mcp/client.test.d.ts +0 -2
  45. package/dist/mcp/client.test.d.ts.map +0 -1
  46. package/dist/mcp/client.test.js +0 -130
  47. package/dist/mcp/client.test.js.map +0 -1
  48. package/dist/mcp/completion.d.ts +0 -25
  49. package/dist/mcp/completion.d.ts.map +0 -1
  50. package/dist/mcp/completion.js +0 -127
  51. package/dist/mcp/completion.js.map +0 -1
  52. package/dist/mcp/elicitation.d.ts +0 -24
  53. package/dist/mcp/elicitation.d.ts.map +0 -1
  54. package/dist/mcp/elicitation.js +0 -13
  55. package/dist/mcp/elicitation.js.map +0 -1
  56. package/dist/mcp/prompts/definitions/task-management-guidelines.md +0 -30
  57. package/dist/mcp/prompts/loader.d.ts +0 -10
  58. package/dist/mcp/prompts/loader.d.ts.map +0 -1
  59. package/dist/mcp/prompts/loader.js +0 -31
  60. package/dist/mcp/prompts/loader.js.map +0 -1
  61. package/dist/mcp/prompts/registry.d.ts +0 -35
  62. package/dist/mcp/prompts/registry.d.ts.map +0 -1
  63. package/dist/mcp/prompts/registry.js +0 -95
  64. package/dist/mcp/prompts/registry.js.map +0 -1
  65. package/dist/mcp/resources/index.d.ts +0 -68
  66. package/dist/mcp/resources/index.d.ts.map +0 -1
  67. package/dist/mcp/resources/index.js +0 -359
  68. package/dist/mcp/resources/index.js.map +0 -1
  69. package/dist/mcp/router.d.ts +0 -14
  70. package/dist/mcp/router.d.ts.map +0 -1
  71. package/dist/mcp/router.js +0 -255
  72. package/dist/mcp/router.js.map +0 -1
  73. package/dist/mcp/sampling.d.ts +0 -69
  74. package/dist/mcp/sampling.d.ts.map +0 -1
  75. package/dist/mcp/sampling.js +0 -13
  76. package/dist/mcp/sampling.js.map +0 -1
  77. package/dist/mcp/server.d.ts +0 -3
  78. package/dist/mcp/server.d.ts.map +0 -1
  79. package/dist/mcp/server.js.map +0 -1
  80. package/dist/mcp/session.d.ts +0 -28
  81. package/dist/mcp/session.d.ts.map +0 -1
  82. package/dist/mcp/session.js +0 -106
  83. package/dist/mcp/session.js.map +0 -1
  84. package/dist/mcp/storage/sqlite.d.ts +0 -87
  85. package/dist/mcp/storage/sqlite.d.ts.map +0 -1
  86. package/dist/mcp/storage/sqlite.js +0 -1327
  87. package/dist/mcp/storage/sqlite.js.map +0 -1
  88. package/dist/mcp/storage/vectors.d.ts +0 -19
  89. package/dist/mcp/storage/vectors.d.ts.map +0 -1
  90. package/dist/mcp/storage/vectors.js +0 -74
  91. package/dist/mcp/storage/vectors.js.map +0 -1
  92. package/dist/mcp/storage/vectors.stub.d.ts +0 -12
  93. package/dist/mcp/storage/vectors.stub.d.ts.map +0 -1
  94. package/dist/mcp/storage/vectors.stub.js +0 -88
  95. package/dist/mcp/storage/vectors.stub.js.map +0 -1
  96. package/dist/mcp/tests/client.test.d.ts +0 -2
  97. package/dist/mcp/tests/client.test.d.ts.map +0 -1
  98. package/dist/mcp/tests/client.test.js +0 -130
  99. package/dist/mcp/tests/client.test.js.map +0 -1
  100. package/dist/mcp/tests/dashboard.test.d.ts +0 -2
  101. package/dist/mcp/tests/dashboard.test.d.ts.map +0 -1
  102. package/dist/mcp/tests/dashboard.test.js +0 -370
  103. package/dist/mcp/tests/dashboard.test.js.map +0 -1
  104. package/dist/mcp/tests/detail-tools.test.d.ts +0 -2
  105. package/dist/mcp/tests/detail-tools.test.d.ts.map +0 -1
  106. package/dist/mcp/tests/detail-tools.test.js +0 -109
  107. package/dist/mcp/tests/detail-tools.test.js.map +0 -1
  108. package/dist/mcp/tests/e2e.test.d.ts +0 -2
  109. package/dist/mcp/tests/e2e.test.d.ts.map +0 -1
  110. package/dist/mcp/tests/e2e.test.js +0 -255
  111. package/dist/mcp/tests/e2e.test.js.map +0 -1
  112. package/dist/mcp/tests/index.test.d.ts +0 -2
  113. package/dist/mcp/tests/index.test.d.ts.map +0 -1
  114. package/dist/mcp/tests/index.test.js +0 -185
  115. package/dist/mcp/tests/index.test.js.map +0 -1
  116. package/dist/mcp/tests/logger.test.d.ts +0 -2
  117. package/dist/mcp/tests/logger.test.d.ts.map +0 -1
  118. package/dist/mcp/tests/logger.test.js +0 -104
  119. package/dist/mcp/tests/logger.test.js.map +0 -1
  120. package/dist/mcp/tests/memory.bulk.test.d.ts +0 -2
  121. package/dist/mcp/tests/memory.bulk.test.d.ts.map +0 -1
  122. package/dist/mcp/tests/memory.bulk.test.js +0 -53
  123. package/dist/mcp/tests/memory.bulk.test.js.map +0 -1
  124. package/dist/mcp/tests/memory.search.test.d.ts +0 -2
  125. package/dist/mcp/tests/memory.search.test.d.ts.map +0 -1
  126. package/dist/mcp/tests/memory.search.test.js +0 -181
  127. package/dist/mcp/tests/memory.search.test.js.map +0 -1
  128. package/dist/mcp/tests/normalize.test.d.ts +0 -2
  129. package/dist/mcp/tests/normalize.test.d.ts.map +0 -1
  130. package/dist/mcp/tests/normalize.test.js +0 -181
  131. package/dist/mcp/tests/normalize.test.js.map +0 -1
  132. package/dist/mcp/tests/query-expander.test.d.ts +0 -2
  133. package/dist/mcp/tests/query-expander.test.d.ts.map +0 -1
  134. package/dist/mcp/tests/query-expander.test.js +0 -33
  135. package/dist/mcp/tests/query-expander.test.js.map +0 -1
  136. package/dist/mcp/tests/router.test.d.ts +0 -2
  137. package/dist/mcp/tests/router.test.d.ts.map +0 -1
  138. package/dist/mcp/tests/router.test.js +0 -481
  139. package/dist/mcp/tests/router.test.js.map +0 -1
  140. package/dist/mcp/tests/spec_compliance.test.d.ts +0 -2
  141. package/dist/mcp/tests/spec_compliance.test.d.ts.map +0 -1
  142. package/dist/mcp/tests/spec_compliance.test.js +0 -61
  143. package/dist/mcp/tests/spec_compliance.test.js.map +0 -1
  144. package/dist/mcp/tests/sqlite.test.d.ts +0 -2
  145. package/dist/mcp/tests/sqlite.test.d.ts.map +0 -1
  146. package/dist/mcp/tests/sqlite.test.js +0 -367
  147. package/dist/mcp/tests/sqlite.test.js.map +0 -1
  148. package/dist/mcp/tests/tasks-search.test.d.ts +0 -2
  149. package/dist/mcp/tests/tasks-search.test.d.ts.map +0 -1
  150. package/dist/mcp/tests/tasks-search.test.js +0 -156
  151. package/dist/mcp/tests/tasks-search.test.js.map +0 -1
  152. package/dist/mcp/tests/tasks-transition.test.d.ts +0 -2
  153. package/dist/mcp/tests/tasks-transition.test.d.ts.map +0 -1
  154. package/dist/mcp/tests/tasks-transition.test.js +0 -174
  155. package/dist/mcp/tests/tasks-transition.test.js.map +0 -1
  156. package/dist/mcp/tests/tasks.bulk.test.d.ts +0 -2
  157. package/dist/mcp/tests/tasks.bulk.test.d.ts.map +0 -1
  158. package/dist/mcp/tests/tasks.bulk.test.js +0 -410
  159. package/dist/mcp/tests/tasks.bulk.test.js.map +0 -1
  160. package/dist/mcp/tests/tasks.e2e.test.d.ts +0 -2
  161. package/dist/mcp/tests/tasks.e2e.test.d.ts.map +0 -1
  162. package/dist/mcp/tests/tasks.e2e.test.js +0 -289
  163. package/dist/mcp/tests/tasks.e2e.test.js.map +0 -1
  164. package/dist/mcp/tests/tasks.pending-limit-refined.test.d.ts +0 -2
  165. package/dist/mcp/tests/tasks.pending-limit-refined.test.d.ts.map +0 -1
  166. package/dist/mcp/tests/tasks.pending-limit-refined.test.js +0 -72
  167. package/dist/mcp/tests/tasks.pending-limit-refined.test.js.map +0 -1
  168. package/dist/mcp/tests/v2-features.test.d.ts +0 -2
  169. package/dist/mcp/tests/v2-features.test.d.ts.map +0 -1
  170. package/dist/mcp/tests/v2-features.test.js +0 -209
  171. package/dist/mcp/tests/v2-features.test.js.map +0 -1
  172. package/dist/mcp/tools/memory.acknowledge.d.ts +0 -4
  173. package/dist/mcp/tools/memory.acknowledge.d.ts.map +0 -1
  174. package/dist/mcp/tools/memory.acknowledge.js +0 -32
  175. package/dist/mcp/tools/memory.acknowledge.js.map +0 -1
  176. package/dist/mcp/tools/memory.bulk-delete.d.ts +0 -4
  177. package/dist/mcp/tools/memory.bulk-delete.d.ts.map +0 -1
  178. package/dist/mcp/tools/memory.bulk-delete.js +0 -40
  179. package/dist/mcp/tools/memory.bulk-delete.js.map +0 -1
  180. package/dist/mcp/tools/memory.delete.d.ts +0 -9
  181. package/dist/mcp/tools/memory.delete.d.ts.map +0 -1
  182. package/dist/mcp/tools/memory.delete.js +0 -40
  183. package/dist/mcp/tools/memory.delete.js.map +0 -1
  184. package/dist/mcp/tools/memory.get.d.ts +0 -3
  185. package/dist/mcp/tools/memory.get.d.ts.map +0 -1
  186. package/dist/mcp/tools/memory.get.js +0 -24
  187. package/dist/mcp/tools/memory.get.js.map +0 -1
  188. package/dist/mcp/tools/memory.recap.d.ts +0 -4
  189. package/dist/mcp/tools/memory.recap.d.ts.map +0 -1
  190. package/dist/mcp/tools/memory.recap.js +0 -52
  191. package/dist/mcp/tools/memory.recap.js.map +0 -1
  192. package/dist/mcp/tools/memory.search.d.ts +0 -5
  193. package/dist/mcp/tools/memory.search.d.ts.map +0 -1
  194. package/dist/mcp/tools/memory.search.js +0 -144
  195. package/dist/mcp/tools/memory.search.js.map +0 -1
  196. package/dist/mcp/tools/memory.store.d.ts +0 -5
  197. package/dist/mcp/tools/memory.store.d.ts.map +0 -1
  198. package/dist/mcp/tools/memory.store.js +0 -120
  199. package/dist/mcp/tools/memory.store.js.map +0 -1
  200. package/dist/mcp/tools/memory.summarize.d.ts +0 -4
  201. package/dist/mcp/tools/memory.summarize.d.ts.map +0 -1
  202. package/dist/mcp/tools/memory.summarize.js +0 -32
  203. package/dist/mcp/tools/memory.summarize.js.map +0 -1
  204. package/dist/mcp/tools/memory.synthesize.d.ts +0 -14
  205. package/dist/mcp/tools/memory.synthesize.d.ts.map +0 -1
  206. package/dist/mcp/tools/memory.synthesize.js +0 -230
  207. package/dist/mcp/tools/memory.synthesize.js.map +0 -1
  208. package/dist/mcp/tools/memory.update.d.ts +0 -5
  209. package/dist/mcp/tools/memory.update.d.ts.map +0 -1
  210. package/dist/mcp/tools/memory.update.js +0 -74
  211. package/dist/mcp/tools/memory.update.js.map +0 -1
  212. package/dist/mcp/tools/schemas.d.ts +0 -3177
  213. package/dist/mcp/tools/schemas.d.ts.map +0 -1
  214. package/dist/mcp/tools/schemas.js +0 -1081
  215. package/dist/mcp/tools/schemas.js.map +0 -1
  216. package/dist/mcp/tools/task.bulk-manage.d.ts +0 -4
  217. package/dist/mcp/tools/task.bulk-manage.d.ts.map +0 -1
  218. package/dist/mcp/tools/task.bulk-manage.js +0 -190
  219. package/dist/mcp/tools/task.bulk-manage.js.map +0 -1
  220. package/dist/mcp/tools/task.get.d.ts +0 -3
  221. package/dist/mcp/tools/task.get.d.ts.map +0 -1
  222. package/dist/mcp/tools/task.get.js +0 -32
  223. package/dist/mcp/tools/task.get.js.map +0 -1
  224. package/dist/mcp/tools/task.manage.d.ts +0 -18
  225. package/dist/mcp/tools/task.manage.d.ts.map +0 -1
  226. package/dist/mcp/tools/task.manage.js +0 -477
  227. package/dist/mcp/tools/task.manage.js.map +0 -1
  228. package/dist/mcp/types.d.ts +0 -87
  229. package/dist/mcp/types.d.ts.map +0 -1
  230. package/dist/mcp/types.js +0 -3
  231. package/dist/mcp/types.js.map +0 -1
  232. package/dist/mcp/utils/completion.d.ts +0 -2
  233. package/dist/mcp/utils/completion.d.ts.map +0 -1
  234. package/dist/mcp/utils/completion.js +0 -28
  235. package/dist/mcp/utils/completion.js.map +0 -1
  236. package/dist/mcp/utils/git-scope.d.ts +0 -8
  237. package/dist/mcp/utils/git-scope.d.ts.map +0 -1
  238. package/dist/mcp/utils/git-scope.js +0 -38
  239. package/dist/mcp/utils/git-scope.js.map +0 -1
  240. package/dist/mcp/utils/logger.d.ts +0 -25
  241. package/dist/mcp/utils/logger.d.ts.map +0 -1
  242. package/dist/mcp/utils/logger.js +0 -152
  243. package/dist/mcp/utils/logger.js.map +0 -1
  244. package/dist/mcp/utils/mcp-response.d.ts +0 -82
  245. package/dist/mcp/utils/mcp-response.d.ts.map +0 -1
  246. package/dist/mcp/utils/mcp-response.js +0 -182
  247. package/dist/mcp/utils/mcp-response.js.map +0 -1
  248. package/dist/mcp/utils/normalize.d.ts +0 -9
  249. package/dist/mcp/utils/normalize.d.ts.map +0 -1
  250. package/dist/mcp/utils/normalize.js +0 -62
  251. package/dist/mcp/utils/normalize.js.map +0 -1
  252. package/dist/mcp/utils/pagination.d.ts +0 -6
  253. package/dist/mcp/utils/pagination.d.ts.map +0 -1
  254. package/dist/mcp/utils/pagination.js +0 -32
  255. package/dist/mcp/utils/pagination.js.map +0 -1
  256. package/dist/mcp/utils/query-expander.d.ts +0 -2
  257. package/dist/mcp/utils/query-expander.d.ts.map +0 -1
  258. package/dist/mcp/utils/query-expander.js +0 -29
  259. package/dist/mcp/utils/query-expander.js.map +0 -1
  260. package/dist/memory.bulk.test.d.ts +0 -2
  261. package/dist/memory.bulk.test.d.ts.map +0 -1
  262. package/dist/memory.bulk.test.js +0 -52
  263. package/dist/memory.bulk.test.js.map +0 -1
  264. package/dist/memory.db +0 -0
  265. package/dist/prompts/registry.d.ts +0 -314
  266. package/dist/prompts/registry.d.ts.map +0 -1
  267. package/dist/prompts/registry.js +0 -936
  268. package/dist/prompts/registry.js.map +0 -1
  269. package/dist/resources/index.d.ts +0 -68
  270. package/dist/resources/index.d.ts.map +0 -1
  271. package/dist/resources/index.js +0 -323
  272. package/dist/resources/index.js.map +0 -1
  273. package/dist/resources/index.test.d.ts +0 -2
  274. package/dist/resources/index.test.d.ts.map +0 -1
  275. package/dist/resources/index.test.js +0 -105
  276. package/dist/resources/index.test.js.map +0 -1
  277. package/dist/router.d.ts +0 -14
  278. package/dist/router.d.ts.map +0 -1
  279. package/dist/router.js +0 -242
  280. package/dist/router.js.map +0 -1
  281. package/dist/router.test.d.ts +0 -2
  282. package/dist/router.test.d.ts.map +0 -1
  283. package/dist/router.test.js +0 -122
  284. package/dist/router.test.js.map +0 -1
  285. package/dist/server.d.ts +0 -3
  286. package/dist/server.d.ts.map +0 -1
  287. package/dist/server.js +0 -338
  288. package/dist/server.js.map +0 -1
  289. package/dist/storage/sqlite.d.ts +0 -79
  290. package/dist/storage/sqlite.d.ts.map +0 -1
  291. package/dist/storage/sqlite.js +0 -1148
  292. package/dist/storage/sqlite.js.map +0 -1
  293. package/dist/storage/sqlite.test.d.ts +0 -2
  294. package/dist/storage/sqlite.test.d.ts.map +0 -1
  295. package/dist/storage/sqlite.test.js +0 -367
  296. package/dist/storage/sqlite.test.js.map +0 -1
  297. package/dist/storage/vectors.d.ts +0 -19
  298. package/dist/storage/vectors.d.ts.map +0 -1
  299. package/dist/storage/vectors.js +0 -74
  300. package/dist/storage/vectors.js.map +0 -1
  301. package/dist/storage/vectors.stub.d.ts +0 -12
  302. package/dist/storage/vectors.stub.d.ts.map +0 -1
  303. package/dist/storage/vectors.stub.js +0 -88
  304. package/dist/storage/vectors.stub.js.map +0 -1
  305. package/dist/tasks.archive.test.d.ts +0 -2
  306. package/dist/tasks.archive.test.d.ts.map +0 -1
  307. package/dist/tasks.archive.test.js +0 -75
  308. package/dist/tasks.archive.test.js.map +0 -1
  309. package/dist/tasks.bulk.test.d.ts +0 -2
  310. package/dist/tasks.bulk.test.d.ts.map +0 -1
  311. package/dist/tasks.bulk.test.js +0 -250
  312. package/dist/tasks.bulk.test.js.map +0 -1
  313. package/dist/tasks.e2e.test.d.ts +0 -2
  314. package/dist/tasks.e2e.test.d.ts.map +0 -1
  315. package/dist/tasks.e2e.test.js +0 -289
  316. package/dist/tasks.e2e.test.js.map +0 -1
  317. package/dist/tests/client.test.d.ts +0 -2
  318. package/dist/tests/client.test.d.ts.map +0 -1
  319. package/dist/tests/client.test.js +0 -130
  320. package/dist/tests/client.test.js.map +0 -1
  321. package/dist/tests/dashboard.test.d.ts +0 -2
  322. package/dist/tests/dashboard.test.d.ts.map +0 -1
  323. package/dist/tests/dashboard.test.js +0 -370
  324. package/dist/tests/dashboard.test.js.map +0 -1
  325. package/dist/tests/e2e.test.d.ts +0 -2
  326. package/dist/tests/e2e.test.d.ts.map +0 -1
  327. package/dist/tests/e2e.test.js +0 -250
  328. package/dist/tests/e2e.test.js.map +0 -1
  329. package/dist/tests/index.test.d.ts +0 -2
  330. package/dist/tests/index.test.d.ts.map +0 -1
  331. package/dist/tests/index.test.js +0 -185
  332. package/dist/tests/index.test.js.map +0 -1
  333. package/dist/tests/logger.test.d.ts +0 -2
  334. package/dist/tests/logger.test.d.ts.map +0 -1
  335. package/dist/tests/logger.test.js +0 -104
  336. package/dist/tests/logger.test.js.map +0 -1
  337. package/dist/tests/memory.bulk.test.d.ts +0 -2
  338. package/dist/tests/memory.bulk.test.d.ts.map +0 -1
  339. package/dist/tests/memory.bulk.test.js +0 -52
  340. package/dist/tests/memory.bulk.test.js.map +0 -1
  341. package/dist/tests/memory.search.test.d.ts +0 -2
  342. package/dist/tests/memory.search.test.d.ts.map +0 -1
  343. package/dist/tests/memory.search.test.js +0 -181
  344. package/dist/tests/memory.search.test.js.map +0 -1
  345. package/dist/tests/normalize.test.d.ts +0 -2
  346. package/dist/tests/normalize.test.d.ts.map +0 -1
  347. package/dist/tests/normalize.test.js +0 -181
  348. package/dist/tests/normalize.test.js.map +0 -1
  349. package/dist/tests/query-expander.test.d.ts +0 -2
  350. package/dist/tests/query-expander.test.d.ts.map +0 -1
  351. package/dist/tests/query-expander.test.js +0 -33
  352. package/dist/tests/query-expander.test.js.map +0 -1
  353. package/dist/tests/router.test.d.ts +0 -2
  354. package/dist/tests/router.test.d.ts.map +0 -1
  355. package/dist/tests/router.test.js +0 -470
  356. package/dist/tests/router.test.js.map +0 -1
  357. package/dist/tests/sqlite.test.d.ts +0 -2
  358. package/dist/tests/sqlite.test.d.ts.map +0 -1
  359. package/dist/tests/sqlite.test.js +0 -367
  360. package/dist/tests/sqlite.test.js.map +0 -1
  361. package/dist/tests/tasks-search.test.d.ts +0 -2
  362. package/dist/tests/tasks-search.test.d.ts.map +0 -1
  363. package/dist/tests/tasks-search.test.js +0 -154
  364. package/dist/tests/tasks-search.test.js.map +0 -1
  365. package/dist/tests/tasks-transition.test.d.ts +0 -2
  366. package/dist/tests/tasks-transition.test.d.ts.map +0 -1
  367. package/dist/tests/tasks-transition.test.js +0 -174
  368. package/dist/tests/tasks-transition.test.js.map +0 -1
  369. package/dist/tests/tasks.bulk.test.d.ts +0 -2
  370. package/dist/tests/tasks.bulk.test.d.ts.map +0 -1
  371. package/dist/tests/tasks.bulk.test.js +0 -254
  372. package/dist/tests/tasks.bulk.test.js.map +0 -1
  373. package/dist/tests/tasks.e2e.test.d.ts +0 -2
  374. package/dist/tests/tasks.e2e.test.d.ts.map +0 -1
  375. package/dist/tests/tasks.e2e.test.js +0 -289
  376. package/dist/tests/tasks.e2e.test.js.map +0 -1
  377. package/dist/tests/tasks.pending-limit-refined.test.d.ts +0 -2
  378. package/dist/tests/tasks.pending-limit-refined.test.d.ts.map +0 -1
  379. package/dist/tests/tasks.pending-limit-refined.test.js +0 -72
  380. package/dist/tests/tasks.pending-limit-refined.test.js.map +0 -1
  381. package/dist/tests/v2-features.test.d.ts +0 -2
  382. package/dist/tests/v2-features.test.d.ts.map +0 -1
  383. package/dist/tests/v2-features.test.js +0 -209
  384. package/dist/tests/v2-features.test.js.map +0 -1
  385. package/dist/tools/memory.acknowledge.d.ts +0 -4
  386. package/dist/tools/memory.acknowledge.d.ts.map +0 -1
  387. package/dist/tools/memory.acknowledge.js +0 -30
  388. package/dist/tools/memory.acknowledge.js.map +0 -1
  389. package/dist/tools/memory.bulk-delete.d.ts +0 -4
  390. package/dist/tools/memory.bulk-delete.d.ts.map +0 -1
  391. package/dist/tools/memory.bulk-delete.js +0 -39
  392. package/dist/tools/memory.bulk-delete.js.map +0 -1
  393. package/dist/tools/memory.delete.d.ts +0 -9
  394. package/dist/tools/memory.delete.d.ts.map +0 -1
  395. package/dist/tools/memory.delete.js +0 -39
  396. package/dist/tools/memory.delete.js.map +0 -1
  397. package/dist/tools/memory.recap.d.ts +0 -4
  398. package/dist/tools/memory.recap.d.ts.map +0 -1
  399. package/dist/tools/memory.recap.js +0 -90
  400. package/dist/tools/memory.recap.js.map +0 -1
  401. package/dist/tools/memory.search.d.ts +0 -5
  402. package/dist/tools/memory.search.d.ts.map +0 -1
  403. package/dist/tools/memory.search.js +0 -134
  404. package/dist/tools/memory.search.js.map +0 -1
  405. package/dist/tools/memory.search.test.d.ts +0 -2
  406. package/dist/tools/memory.search.test.d.ts.map +0 -1
  407. package/dist/tools/memory.search.test.js +0 -181
  408. package/dist/tools/memory.search.test.js.map +0 -1
  409. package/dist/tools/memory.store.d.ts +0 -5
  410. package/dist/tools/memory.store.d.ts.map +0 -1
  411. package/dist/tools/memory.store.js +0 -117
  412. package/dist/tools/memory.store.js.map +0 -1
  413. package/dist/tools/memory.summarize.d.ts +0 -4
  414. package/dist/tools/memory.summarize.d.ts.map +0 -1
  415. package/dist/tools/memory.summarize.js +0 -31
  416. package/dist/tools/memory.summarize.js.map +0 -1
  417. package/dist/tools/memory.synthesize.d.ts +0 -14
  418. package/dist/tools/memory.synthesize.d.ts.map +0 -1
  419. package/dist/tools/memory.synthesize.js +0 -228
  420. package/dist/tools/memory.synthesize.js.map +0 -1
  421. package/dist/tools/memory.update.d.ts +0 -5
  422. package/dist/tools/memory.update.d.ts.map +0 -1
  423. package/dist/tools/memory.update.js +0 -73
  424. package/dist/tools/memory.update.js.map +0 -1
  425. package/dist/tools/schemas.d.ts +0 -2762
  426. package/dist/tools/schemas.d.ts.map +0 -1
  427. package/dist/tools/schemas.js +0 -952
  428. package/dist/tools/schemas.js.map +0 -1
  429. package/dist/tools/task.bulk-manage.d.ts +0 -4
  430. package/dist/tools/task.bulk-manage.d.ts.map +0 -1
  431. package/dist/tools/task.bulk-manage.js +0 -146
  432. package/dist/tools/task.bulk-manage.js.map +0 -1
  433. package/dist/tools/task.manage.d.ts +0 -16
  434. package/dist/tools/task.manage.d.ts.map +0 -1
  435. package/dist/tools/task.manage.js +0 -395
  436. package/dist/tools/task.manage.js.map +0 -1
  437. package/dist/tools/tasks-transition.test.d.ts +0 -2
  438. package/dist/tools/tasks-transition.test.d.ts.map +0 -1
  439. package/dist/tools/tasks-transition.test.js +0 -174
  440. package/dist/tools/tasks-transition.test.js.map +0 -1
  441. package/dist/tools/tasks.pending-limit-refined.test.d.ts +0 -2
  442. package/dist/tools/tasks.pending-limit-refined.test.d.ts.map +0 -1
  443. package/dist/tools/tasks.pending-limit-refined.test.js +0 -72
  444. package/dist/tools/tasks.pending-limit-refined.test.js.map +0 -1
  445. package/dist/types.d.ts +0 -87
  446. package/dist/types.d.ts.map +0 -1
  447. package/dist/types.js +0 -3
  448. package/dist/types.js.map +0 -1
  449. package/dist/utils/completion.d.ts +0 -2
  450. package/dist/utils/completion.d.ts.map +0 -1
  451. package/dist/utils/completion.js +0 -28
  452. package/dist/utils/completion.js.map +0 -1
  453. package/dist/utils/git-scope.d.ts +0 -8
  454. package/dist/utils/git-scope.d.ts.map +0 -1
  455. package/dist/utils/git-scope.js +0 -38
  456. package/dist/utils/git-scope.js.map +0 -1
  457. package/dist/utils/logger.d.ts +0 -25
  458. package/dist/utils/logger.d.ts.map +0 -1
  459. package/dist/utils/logger.js +0 -152
  460. package/dist/utils/logger.js.map +0 -1
  461. package/dist/utils/logger.test.d.ts +0 -2
  462. package/dist/utils/logger.test.d.ts.map +0 -1
  463. package/dist/utils/logger.test.js +0 -76
  464. package/dist/utils/logger.test.js.map +0 -1
  465. package/dist/utils/mcp-response.d.ts +0 -96
  466. package/dist/utils/mcp-response.d.ts.map +0 -1
  467. package/dist/utils/mcp-response.js +0 -131
  468. package/dist/utils/mcp-response.js.map +0 -1
  469. package/dist/utils/normalize.d.ts +0 -9
  470. package/dist/utils/normalize.d.ts.map +0 -1
  471. package/dist/utils/normalize.js +0 -62
  472. package/dist/utils/normalize.js.map +0 -1
  473. package/dist/utils/normalize.test.d.ts +0 -2
  474. package/dist/utils/normalize.test.d.ts.map +0 -1
  475. package/dist/utils/normalize.test.js +0 -159
  476. package/dist/utils/normalize.test.js.map +0 -1
  477. package/dist/utils/pagination.d.ts +0 -6
  478. package/dist/utils/pagination.d.ts.map +0 -1
  479. package/dist/utils/pagination.js +0 -32
  480. package/dist/utils/pagination.js.map +0 -1
  481. package/dist/utils/query-expander.d.ts +0 -2
  482. package/dist/utils/query-expander.d.ts.map +0 -1
  483. package/dist/utils/query-expander.js +0 -29
  484. package/dist/utils/query-expander.js.map +0 -1
  485. package/dist/utils/query-expander.test.d.ts +0 -2
  486. package/dist/utils/query-expander.test.d.ts.map +0 -1
  487. package/dist/utils/query-expander.test.js +0 -33
  488. package/dist/utils/query-expander.test.js.map +0 -1
  489. package/dist/v2-features.test.d.ts +0 -2
  490. package/dist/v2-features.test.d.ts.map +0 -1
  491. package/dist/v2-features.test.js +0 -209
  492. package/dist/v2-features.test.js.map +0 -1
  493. /package/dist/{mcp/prompts/definitions → prompts}/architecture-design.md +0 -0
  494. /package/dist/{mcp/prompts/definitions → prompts}/documentation-sync.md +0 -0
  495. /package/dist/{mcp/prompts/definitions → prompts}/fix-suggestion.md +0 -0
  496. /package/dist/{mcp/prompts/definitions → prompts}/import-github-issues.md +0 -0
  497. /package/dist/{mcp/prompts/definitions → prompts}/learning-retrospective.md +0 -0
  498. /package/dist/{mcp/prompts/definitions → prompts}/memory-guided-review.md +0 -0
  499. /package/dist/{mcp/prompts/definitions → prompts}/project-briefing.md +0 -0
  500. /package/dist/{mcp/prompts/definitions → prompts}/root-cause-analysis.md +0 -0
  501. /package/dist/{mcp/prompts/definitions → prompts}/security-triage.md +0 -0
  502. /package/dist/{mcp/prompts/definitions → prompts}/senior-code-review.md +0 -0
  503. /package/dist/{mcp/prompts/definitions → prompts}/session-planner.md +0 -0
  504. /package/dist/{mcp/prompts/definitions → prompts}/tech-affinity-scout.md +0 -0
  505. /package/dist/{mcp/prompts/definitions → prompts}/technical-planning.md +0 -0
  506. /package/dist/{mcp/prompts/definitions → prompts}/tool-usage-guidelines.md +0 -0
@@ -1,486 +1,825 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ MCP_PROTOCOL_VERSION,
4
+ PROMPTS,
5
+ SQLiteStore,
6
+ TOOL_DEFINITIONS,
7
+ listResources,
8
+ logger
9
+ } from "../chunk-XIJO63UU.js";
10
+
11
+ // src/dashboard/server.ts
2
12
  import express from "express";
13
+ import path3 from "path";
14
+ import fs2 from "fs";
15
+ import { fileURLToPath as fileURLToPath3 } from "url";
16
+
17
+ // src/mcp/client.ts
18
+ import { spawn } from "child_process";
19
+ import { createInterface } from "readline";
3
20
  import path from "path";
4
- import fs from "fs";
5
21
  import { fileURLToPath } from "url";
6
- import { randomUUID } from "crypto";
7
- import { MCPClient } from "../mcp/client.js";
8
- import { SQLiteStore } from "../mcp/storage/sqlite.js";
9
- import { logger } from "../mcp/utils/logger.js";
10
- import { TOOL_DEFINITIONS } from "../mcp/tools/schemas.js";
11
- import { PROMPTS } from "../mcp/prompts/registry.js";
12
- import { listResources } from "../mcp/resources/index.js";
13
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
- let pkg = { version: "0.0.0" };
15
- try {
16
- const pkgPath = path.join(__dirname, "../../package.json");
17
- if (fs.existsSync(pkgPath)) {
18
- pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
19
- }
20
- }
21
- catch (e) {
22
- // Silent fallback
23
- }
24
- const app = express();
25
- const PORT = process.env.PORT || 3456;
26
- const startTime = Date.now();
27
- const db = new SQLiteStore();
28
- const mcpClient = new MCPClient();
29
- // --- Middleware ---
30
- app.use(express.json());
31
- app.use((req, res, next) => {
32
- const start = Date.now();
33
- res.on("finish", () => {
34
- const duration = Date.now() - start;
35
- if (duration > 1000) {
36
- logger.warn("Slow request", { method: req.method, path: req.path, duration });
22
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
23
+ var RETRY_DELAYS = [1e3, 2e3, 4e3];
24
+ var MAX_RETRIES = 3;
25
+ var MAX_RESTARTS = 3;
26
+ var REQUEST_TIMEOUT_MS = 1e4;
27
+ var MCPClient = class {
28
+ process = null;
29
+ requestId = 0;
30
+ pendingRequests = /* @__PURE__ */ new Map();
31
+ isInitialized = false;
32
+ serverPathOverride;
33
+ restartCount = 0;
34
+ constructor(serverPath) {
35
+ this.serverPathOverride = serverPath;
36
+ }
37
+ async start() {
38
+ if (this.process) return;
39
+ const serverPath = this.serverPathOverride || path.join(__dirname, "./server.js");
40
+ this.process = spawn("node", [serverPath], {
41
+ stdio: ["pipe", "pipe", "inherit"]
42
+ });
43
+ if (!this.process.stdout || !this.process.stdin) {
44
+ throw new Error("Failed to spawn MCP server");
45
+ }
46
+ this.process.on("close", (code) => {
47
+ if (this.process === null) {
48
+ return;
49
+ }
50
+ logger.error("MCP server process closed unexpectedly", { code, restartCount: this.restartCount });
51
+ this.process = null;
52
+ this.isInitialized = false;
53
+ if (this.restartCount < MAX_RESTARTS) {
54
+ this.restartCount++;
55
+ logger.info("Attempting to restart MCP server", { attempt: this.restartCount });
56
+ this.start().catch((err) => {
57
+ logger.error("Failed to restart MCP server", { error: String(err) });
58
+ });
59
+ } else {
60
+ logger.error("Max restart attempts reached, giving up", { maxRestarts: MAX_RESTARTS });
61
+ }
62
+ });
63
+ const rl = createInterface({
64
+ input: this.process.stdout,
65
+ crlfDelay: Infinity
66
+ });
67
+ rl.on("line", (line) => {
68
+ try {
69
+ const response = JSON.parse(line);
70
+ if (!response.id) return;
71
+ const pending = this.pendingRequests.get(response.id);
72
+ if (pending) {
73
+ this.pendingRequests.delete(response.id);
74
+ if (response.error) {
75
+ pending.reject(new Error(response.error.message));
76
+ } else {
77
+ pending.resolve(response.result);
78
+ }
37
79
  }
80
+ } catch (err) {
81
+ logger.error("Failed to parse MCP response", { error: String(err) });
82
+ }
38
83
  });
39
- next();
40
- });
41
- // --- API Routes ---
42
- // Health check
43
- app.get("/api/health", (req, res) => {
44
- const stats = db.getStats();
45
- res.json({
46
- connected: mcpClient.isConnected(),
47
- uptime: Math.floor((Date.now() - startTime) / 1000),
48
- version: pkg.version,
49
- memoryCount: stats.total,
50
- pendingRequests: mcpClient.getPendingCount(),
51
- dbPath: db.getDbPath()
84
+ await this.callWithRetry("initialize", {
85
+ protocolVersion: MCP_PROTOCOL_VERSION,
86
+ capabilities: {},
87
+ clientInfo: { name: "mcp-client", version: "1.0.0" }
52
88
  });
53
- });
54
- // List all repositories
55
- app.get("/api/repos", async (req, res) => {
89
+ if (this.process?.stdin) {
90
+ this.process.stdin.write(
91
+ JSON.stringify({
92
+ jsonrpc: "2.0",
93
+ method: "notifications/initialized"
94
+ }) + "\n"
95
+ );
96
+ }
97
+ this.isInitialized = true;
98
+ }
99
+ /**
100
+ * Send a single request without retry. Returns a Promise that rejects on timeout.
101
+ */
102
+ callOnce(method, params = {}) {
103
+ if (!this.process || !this.process.stdin) {
104
+ return Promise.reject(new Error("MCP server not started"));
105
+ }
106
+ const id = ++this.requestId;
107
+ const request = { jsonrpc: "2.0", id, method, params };
108
+ return new Promise((resolve, reject) => {
109
+ this.pendingRequests.set(id, { resolve, reject });
110
+ const timer = setTimeout(() => {
111
+ if (this.pendingRequests.has(id)) {
112
+ this.pendingRequests.delete(id);
113
+ reject(new Error("Request timeout"));
114
+ }
115
+ }, REQUEST_TIMEOUT_MS);
116
+ if (timer.unref) timer.unref();
117
+ this.process.stdin.write(JSON.stringify(request) + "\n");
118
+ });
119
+ }
120
+ /**
121
+ * Call with retry on timeout — up to MAX_RETRIES retries with exponential backoff.
122
+ * Req 18.1: retry up to 3x with delays 1s, 2s, 4s.
123
+ */
124
+ async callWithRetry(method, params = {}) {
125
+ let lastError;
126
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
127
+ try {
128
+ return await this.callOnce(method, params);
129
+ } catch (err) {
130
+ lastError = err;
131
+ const isTimeout = err instanceof Error && err.message === "Request timeout";
132
+ if (!isTimeout || attempt === MAX_RETRIES) {
133
+ logger.error("MCP request failed", {
134
+ method,
135
+ attempt,
136
+ error: String(err)
137
+ });
138
+ throw err;
139
+ }
140
+ const delay = RETRY_DELAYS[attempt];
141
+ logger.warn("MCP request timed out, retrying", {
142
+ method,
143
+ attempt: attempt + 1,
144
+ delayMs: delay
145
+ });
146
+ await sleep(delay);
147
+ }
148
+ }
149
+ throw lastError;
150
+ }
151
+ async call(method, params = {}) {
152
+ return this.callWithRetry(method, params);
153
+ }
154
+ async callTool(toolName, args) {
155
+ return this.call("tools/call", { name: toolName, arguments: args });
156
+ }
157
+ async readResource(uri) {
158
+ return this.call("resources/read", { uri });
159
+ }
160
+ /**
161
+ * Stop the client: reject all pending requests, then kill the process.
162
+ * Req 18.3: reject all pending requests with "Client stopped".
163
+ */
164
+ stop() {
165
+ for (const [id, pending] of this.pendingRequests) {
166
+ pending.reject(new Error("Client stopped"));
167
+ this.pendingRequests.delete(id);
168
+ }
169
+ if (this.process) {
170
+ const proc = this.process;
171
+ this.process = null;
172
+ this.isInitialized = false;
173
+ proc.kill();
174
+ }
175
+ }
176
+ isConnected() {
177
+ return this.isInitialized && this.process !== null;
178
+ }
179
+ /**
180
+ * Returns the number of requests currently awaiting a response.
181
+ * Req 18.5
182
+ */
183
+ getPendingCount() {
184
+ return this.pendingRequests.size;
185
+ }
186
+ };
187
+ function sleep(ms) {
188
+ return new Promise((resolve) => setTimeout(resolve, ms));
189
+ }
190
+
191
+ // src/dashboard/lib/context.ts
192
+ var db = new SQLiteStore();
193
+ var mcpClient = new MCPClient();
194
+ var startTime = Date.now();
195
+
196
+ // src/dashboard/routes/index.ts
197
+ import { Router as Router4 } from "express";
198
+
199
+ // src/dashboard/routes/system.routes.ts
200
+ import { Router } from "express";
201
+
202
+ // src/dashboard/controllers/SystemController.ts
203
+ import fs from "fs";
204
+ import path2 from "path";
205
+ import { fileURLToPath as fileURLToPath2 } from "url";
206
+
207
+ // src/dashboard/lib/jsonApi.ts
208
+ function jsonApiRes(data, type, extra = {}) {
209
+ const isArray = Array.isArray(data);
210
+ const dataLayer = isArray ? data.map((item) => {
211
+ const { id, ...attributes } = item;
212
+ return { type, id: String(id || "system"), attributes };
213
+ }) : (() => {
214
+ const { id, ...attributes } = data;
215
+ return { type, id: String(id || attributes.id || "system"), attributes };
216
+ })();
217
+ return {
218
+ jsonapi: { version: "1.1" },
219
+ data: dataLayer,
220
+ ...extra
221
+ };
222
+ }
223
+ function jsonApiError(message, status = 500) {
224
+ return {
225
+ jsonapi: { version: "1.1" },
226
+ errors: [{ status: String(status), detail: message }]
227
+ };
228
+ }
229
+ function getAttributes(req) {
230
+ return req.body.data?.attributes || req.body;
231
+ }
232
+
233
+ // src/dashboard/lib/helpers.ts
234
+ function condenseRecentActions(actions, limit) {
235
+ const condensed = [];
236
+ for (const action of actions) {
237
+ const prev = condensed[condensed.length - 1];
238
+ const same = prev && prev.action === action.action && prev.query === action.query && prev.memory_id === action.memory_id;
239
+ const within = prev && Math.abs(new Date(prev.created_at).getTime() - new Date(action.created_at).getTime()) <= 6e5;
240
+ if (same && within) {
241
+ prev.burstCount++;
242
+ prev.created_at = action.created_at;
243
+ } else {
244
+ condensed.push({ ...action, burstCount: 1 });
245
+ }
246
+ }
247
+ return condensed.slice(0, limit);
248
+ }
249
+
250
+ // src/dashboard/controllers/SystemController.ts
251
+ var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
252
+ var pkg = { version: "0.0.0" };
253
+ try {
254
+ const pkgPath = path2.join(__dirname2, "../../../package.json");
255
+ if (fs.existsSync(pkgPath)) {
256
+ pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
257
+ }
258
+ } catch {
259
+ }
260
+ var SystemController = class {
261
+ static getHealth(req, res) {
262
+ const stats = db.system.getGlobalStats();
263
+ const health = {
264
+ connected: mcpClient.isConnected(),
265
+ uptime: Math.floor((Date.now() - startTime) / 1e3),
266
+ version: pkg.version,
267
+ memoryCount: stats.totalMemories,
268
+ pendingRequests: mcpClient.getPendingCount(),
269
+ dbPath: db.getDbPath()
270
+ };
271
+ res.json(jsonApiRes(health, "health"));
272
+ }
273
+ static getRepos(req, res) {
56
274
  try {
57
- const repos = db.listRepoNavigation();
58
- res.json({ repos });
59
- }
60
- catch (err) {
61
- res.status(500).json({ error: err.message });
62
- }
63
- });
64
- // Get global or repo stats
65
- app.get("/api/stats", async (req, res) => {
275
+ const repos = db.system.listRepoNavigation();
276
+ res.json(
277
+ jsonApiRes(
278
+ repos.map((r) => ({ id: r.repo, name: r.repo, ...r })),
279
+ "repository"
280
+ )
281
+ );
282
+ } catch (err) {
283
+ const message = err instanceof Error ? err.message : "Internal server error";
284
+ res.status(500).json(jsonApiError(message));
285
+ }
286
+ }
287
+ static getStats(req, res) {
66
288
  try {
67
- const repo = req.query.repo;
68
- const stats = db.getDashboardStats(repo);
69
- res.json(stats);
70
- }
71
- catch (err) {
72
- res.status(500).json({ error: err.message });
73
- }
74
- });
75
- // Get recent actions
76
- app.get("/api/recent-actions", async (req, res) => {
289
+ const repo = req.query.repo;
290
+ if (!repo) return res.status(400).json(jsonApiError("repo is required", 400));
291
+ const stats = db.system.getDashboardStats(repo);
292
+ res.json(jsonApiRes(stats, "system-stats"));
293
+ } catch (err) {
294
+ const message = err instanceof Error ? err.message : "Internal server error";
295
+ res.status(500).json(jsonApiError(message));
296
+ }
297
+ }
298
+ static getRecentActions(req, res) {
77
299
  try {
78
- const repo = req.query.repo;
79
- const pageSize = Math.min(50, Math.max(1, parseInt(req.query.pageSize) || 10));
80
- const page = Math.max(1, parseInt(req.query.page) || 1);
81
- const rawActions = db.getRecentActions(repo, 100);
82
- const allCondensed = condenseRecentActions(rawActions, 100);
83
- const offset = (page - 1) * pageSize;
84
- res.json({
85
- actions: allCondensed.slice(offset, offset + pageSize),
86
- pagination: { page, pageSize, totalItems: allCondensed.length }
87
- });
88
- }
89
- catch (err) {
90
- res.status(500).json({ error: err.message });
91
- }
92
- });
93
- // Memory endpoints
94
- app.get("/api/memories", async (req, res) => {
300
+ const repo = req.query.repo;
301
+ const pageSize = Math.min(50, Math.max(1, parseInt(req.query.pageSize) || 10));
302
+ const page = Math.max(1, parseInt(req.query.page) || 1);
303
+ const rawActions = db.actions.getRecentActions(repo, 100);
304
+ const actions = rawActions.map((a) => ({
305
+ ...a,
306
+ query: a.query || void 0,
307
+ response: a.response || void 0,
308
+ memory_id: a.memory_id || void 0,
309
+ task_id: a.task_id || void 0,
310
+ memory_title: a.memory_title || void 0,
311
+ memory_type: a.memory_type || void 0
312
+ }));
313
+ const allCondensed = condenseRecentActions(actions, 100);
314
+ const offset = (page - 1) * pageSize;
315
+ const items = allCondensed.slice(offset, offset + pageSize);
316
+ res.json(
317
+ jsonApiRes(items, "recent-action", {
318
+ meta: { page, pageSize, totalItems: allCondensed.length }
319
+ })
320
+ );
321
+ } catch (err) {
322
+ const message = err instanceof Error ? err.message : "Internal server error";
323
+ res.status(500).json(jsonApiError(message));
324
+ }
325
+ }
326
+ static getCapabilities(req, res) {
327
+ const caps = {
328
+ tools: TOOL_DEFINITIONS || [],
329
+ resources: listResources().resources || [],
330
+ prompts: Object.values(PROMPTS) || []
331
+ };
332
+ res.json(jsonApiRes(caps, "capability"));
333
+ }
334
+ static getExport(req, res) {
95
335
  try {
96
- const { repo, type, search, minImportance, maxImportance, sortBy, sortOrder } = req.query;
97
- const page = Math.max(1, parseInt(req.query.page || "1", 10));
98
- const pageSize = Math.min(100, Math.max(1, parseInt(req.query.pageSize || "25", 10)));
99
- if (!repo)
100
- return res.status(400).json({ error: "repo is required" });
101
- const result = db.listMemoriesForDashboard({
102
- repo: repo,
103
- type: type,
104
- search: search,
105
- minImportance: minImportance ? parseInt(minImportance) : undefined,
106
- maxImportance: maxImportance ? parseInt(maxImportance) : undefined,
107
- sortBy: sortBy,
108
- sortOrder: sortOrder === "asc" ? "asc" : "desc",
109
- limit: pageSize,
110
- offset: (page - 1) * pageSize,
111
- });
112
- res.json({
113
- memories: result.items,
114
- pagination: {
115
- page,
116
- pageSize,
117
- totalItems: result.total,
118
- totalPages: Math.ceil(result.total / pageSize)
119
- }
120
- });
121
- }
122
- catch (err) {
123
- res.status(500).json({ error: err.message });
124
- }
125
- });
126
- app.get("/api/memories/:id", async (req, res) => {
336
+ const { repo } = req.query;
337
+ if (!repo) return res.status(400).json(jsonApiError("repo is required", 400));
338
+ const memories = db.memories.getAllMemoriesWithStats(repo);
339
+ const tasks = db.tasks.getTasksByRepo(repo);
340
+ const allComments = db.tasks.getAllTaskCommentsByRepo(repo);
341
+ const commentsByTaskId = allComments.reduce(
342
+ (acc, comment) => {
343
+ if (!acc[comment.task_id]) acc[comment.task_id] = [];
344
+ acc[comment.task_id].push(comment);
345
+ return acc;
346
+ },
347
+ {}
348
+ );
349
+ const tasksWithComments = tasks.map((t) => ({
350
+ ...t,
351
+ comments: commentsByTaskId[t.id] || []
352
+ }));
353
+ const exportData = {
354
+ repo,
355
+ exported_at: (/* @__PURE__ */ new Date()).toISOString(),
356
+ memories,
357
+ tasks: tasksWithComments
358
+ };
359
+ res.json(jsonApiRes(exportData, "export"));
360
+ } catch (err) {
361
+ const message = err instanceof Error ? err.message : "Internal server error";
362
+ res.status(500).json(jsonApiError(message));
363
+ }
364
+ }
365
+ static async callTool(req, res) {
127
366
  try {
128
- const memory = db.getByIdWithStats(req.params.id);
129
- if (!memory)
130
- throw new Error("Memory not found");
131
- db.logAction("read", memory.scope.repo, { memoryId: memory.id, resultCount: 1 });
132
- res.json(memory);
133
- }
134
- catch (err) {
135
- res.status(404).json({ error: err.message });
136
- }
137
- });
138
- app.post("/api/memories", async (req, res) => {
367
+ if (!mcpClient.isConnected()) await mcpClient.start();
368
+ const { name } = req.params;
369
+ const args = getAttributes(req);
370
+ const result = await mcpClient.callTool(name, args);
371
+ res.json(jsonApiRes(result, "tool-result"));
372
+ } catch (err) {
373
+ const message = err instanceof Error ? err.message : "Internal server error";
374
+ res.status(500).json(jsonApiError(message));
375
+ }
376
+ }
377
+ };
378
+
379
+ // src/dashboard/routes/system.routes.ts
380
+ var router = Router();
381
+ router.get("/health", SystemController.getHealth);
382
+ router.get("/repos", SystemController.getRepos);
383
+ router.get("/stats", SystemController.getStats);
384
+ router.get("/recent-actions", SystemController.getRecentActions);
385
+ router.get("/capabilities", SystemController.getCapabilities);
386
+ router.get("/export", SystemController.getExport);
387
+ router.post("/tools/:name/call", SystemController.callTool);
388
+ var system_routes_default = router;
389
+
390
+ // src/dashboard/routes/memory.routes.ts
391
+ import { Router as Router2 } from "express";
392
+
393
+ // src/dashboard/controllers/MemoriesController.ts
394
+ import { randomUUID } from "crypto";
395
+ var MemoriesController = class {
396
+ static list(req, res) {
139
397
  try {
140
- const { repo, type, content } = req.body;
141
- if (!repo || !type || !content)
142
- return res.status(400).json({ error: "Required fields missing" });
143
- const id = randomUUID();
144
- db.insert({ ...req.body, id, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), scope: { repo } });
145
- db.logAction("write", repo, { memoryId: id });
146
- res.json({ success: true, id });
147
- }
148
- catch (err) {
149
- res.status(500).json({ error: err.message });
150
- }
151
- });
152
- app.put("/api/memories/:id", async (req, res) => {
398
+ const query = req.query;
399
+ const { repo, type, search, minImportance, maxImportance, sortBy, sortOrder } = query;
400
+ const page = Math.max(1, parseInt(query.page || "1", 10));
401
+ const pageSize = Math.min(100, Math.max(1, parseInt(query.limit || "25", 10)));
402
+ if (!repo) return res.status(400).json(jsonApiError("repo is required", 400));
403
+ const result = db.memories.listMemoriesForDashboard({
404
+ repo,
405
+ type,
406
+ search,
407
+ minImportance: minImportance ? parseInt(minImportance) : void 0,
408
+ maxImportance: maxImportance ? parseInt(maxImportance) : void 0,
409
+ sortBy,
410
+ sortOrder: sortOrder?.toUpperCase() === "ASC" ? "ASC" : "DESC",
411
+ limit: pageSize,
412
+ offset: (page - 1) * pageSize
413
+ });
414
+ res.json(
415
+ jsonApiRes(result.items, "memory", {
416
+ meta: {
417
+ page,
418
+ pageSize,
419
+ totalItems: result.total,
420
+ totalPages: Math.ceil(result.total / pageSize)
421
+ }
422
+ })
423
+ );
424
+ } catch (err) {
425
+ const message = err instanceof Error ? err.message : "Internal server error";
426
+ res.status(500).json(jsonApiError(message));
427
+ }
428
+ }
429
+ static get(req, res) {
153
430
  try {
154
- const { id } = req.params;
155
- const existing = db.getByIdWithStats ? db.getByIdWithStats(id) : db.getById(id);
156
- if (!existing)
157
- return res.status(404).json({ error: "Memory not found" });
158
- const { title, content, type, importance, tags, agent, model, repo } = req.body;
159
- const updates = { title, content, type, importance, tags, agent, model, repo, updated_at: new Date().toISOString() };
160
- db.update(id, updates);
161
- db.logAction("update", existing.repo || req.body.repo || "", { memoryId: id });
162
- res.json({ success: true });
163
- }
164
- catch (err) {
165
- res.status(500).json({ error: err.message });
166
- }
167
- });
168
- app.delete("/api/memories/:id", async (req, res) => {
431
+ const memory = db.memories.getByIdWithStats(req.params.id);
432
+ if (!memory) throw new Error("Memory not found");
433
+ db.actions.logAction("read", memory.scope.repo, { memoryId: memory.id, resultCount: 1 });
434
+ res.json(jsonApiRes(memory, "memory"));
435
+ } catch (err) {
436
+ const message = err instanceof Error ? err.message : "Memory not found";
437
+ res.status(404).json(jsonApiError(message, 404));
438
+ }
439
+ }
440
+ static create(req, res) {
169
441
  try {
170
- const { id } = req.params;
171
- const existing = db.getByIdWithStats ? db.getByIdWithStats(id) : db.getById(id);
172
- if (!existing)
173
- return res.status(404).json({ error: "Memory not found" });
174
- db.delete(id);
175
- db.logAction("delete", existing.repo || "", { memoryId: id });
176
- res.json({ success: true });
177
- }
178
- catch (err) {
179
- res.status(500).json({ error: err.message });
180
- }
181
- });
182
- app.post("/api/memories/bulk-import", async (req, res) => {
442
+ const attributes = getAttributes(req);
443
+ const { repo, type, content } = attributes;
444
+ if (!repo || !type || !content) return res.status(400).json(jsonApiError("Required fields missing", 400));
445
+ const id = randomUUID();
446
+ db.memories.insert({
447
+ ...attributes,
448
+ id,
449
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
450
+ updated_at: (/* @__PURE__ */ new Date()).toISOString(),
451
+ scope: { repo }
452
+ });
453
+ db.actions.logAction("write", repo, { memoryId: id });
454
+ res.json(jsonApiRes({ id }, "memory"));
455
+ } catch (err) {
456
+ const message = err instanceof Error ? err.message : "Internal server error";
457
+ res.status(500).json(jsonApiError(message));
458
+ }
459
+ }
460
+ static update(req, res) {
183
461
  try {
184
- const { items, repo } = req.body;
185
- if (!Array.isArray(items) || !repo)
186
- return res.status(400).json({ error: "Invalid payload: requires 'items' array and 'repo'" });
187
- const entries = items.map(item => ({
188
- ...item,
189
- id: item.id || randomUUID(),
190
- scope: { ...item.scope, repo },
191
- created_at: item.created_at || new Date().toISOString(),
192
- updated_at: item.updated_at || new Date().toISOString()
193
- }));
194
- const count = db.bulkInsertMemories(entries);
195
- db.logAction("write", repo, { query: `Bulk imported ${count} memories` });
196
- res.json({ success: true, count });
197
- }
198
- catch (err) {
199
- res.status(500).json({ error: err.message });
200
- }
201
- });
202
- app.post("/api/memories/bulk-action", async (req, res) => {
462
+ const { id } = req.params;
463
+ const existing = db.memories.getByIdWithStats ? db.memories.getByIdWithStats(id) : db.memories.getById(id);
464
+ if (!existing) return res.status(404).json(jsonApiError("Memory not found", 404));
465
+ const attributes = getAttributes(req);
466
+ const { title, content, type, importance, tags, agent, model, repo } = attributes;
467
+ const updates = {
468
+ title,
469
+ content,
470
+ type,
471
+ importance,
472
+ tags,
473
+ agent,
474
+ model,
475
+ repo,
476
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
477
+ };
478
+ db.memories.update(id, updates);
479
+ db.actions.logAction("update", existing.scope?.repo || attributes.repo || "", { memoryId: id });
480
+ res.json(jsonApiRes({ message: "Updated" }, "status"));
481
+ } catch (err) {
482
+ const message = err instanceof Error ? err.message : "Internal server error";
483
+ res.status(500).json(jsonApiError(message));
484
+ }
485
+ }
486
+ static delete(req, res) {
203
487
  try {
204
- const { action, ids, updates } = req.body;
205
- if (!Array.isArray(ids) || !action)
206
- return res.status(400).json({ error: "Invalid payload: requires 'ids' array and 'action'" });
207
- let count = 0;
208
- if (action === "delete") {
209
- count = db.bulkDeleteMemories(ids);
210
- }
211
- else if (action === "update" || action === "archive") {
212
- count = db.bulkUpdateMemories(ids, updates || { status: action === 'archive' ? 'archived' : 'active' });
213
- }
214
- else {
215
- return res.status(400).json({ error: "Invalid action" });
216
- }
217
- if (ids.length > 0) {
218
- const mem = db.getById(ids[0]);
219
- db.logAction(action, mem?.scope?.repo || "unknown", { query: `Bulk ${action} applied to ${count} memories` });
220
- }
221
- res.json({ success: true, count });
222
- }
223
- catch (err) {
224
- res.status(500).json({ error: err.message });
225
- }
226
- });
227
- // Task endpoints
228
- app.get("/api/tasks", async (req, res) => {
488
+ const { id } = req.params;
489
+ const existing = db.memories.getByIdWithStats ? db.memories.getByIdWithStats(id) : db.memories.getById(id);
490
+ if (!existing) return res.status(404).json(jsonApiError("Memory not found", 404));
491
+ db.memories.delete(id);
492
+ db.actions.logAction("delete", existing.scope?.repo || "", { memoryId: id });
493
+ res.json(jsonApiRes({ message: "Deleted" }, "status"));
494
+ } catch (err) {
495
+ const message = err instanceof Error ? err.message : "Internal server error";
496
+ res.status(500).json(jsonApiError(message));
497
+ }
498
+ }
499
+ static bulkCreate(req, res) {
229
500
  try {
230
- const { repo, status, search } = req.query;
231
- const page = Math.max(1, parseInt(req.query.page || "1", 10));
232
- const pageSize = Math.min(100, Math.max(1, parseInt(req.query.pageSize || "20", 10)));
233
- if (!repo)
234
- return res.status(400).json({ error: "repo is required" });
235
- let tasks;
236
- if (status && status.includes(',')) {
237
- tasks = db.getTasksByMultipleStatuses(repo, status.split(','), pageSize, (page - 1) * pageSize, search);
238
- }
239
- else {
240
- tasks = db.getTasksByRepo(repo, status, pageSize, (page - 1) * pageSize, search);
241
- }
242
- res.json({ tasks, page, pageSize });
243
- }
244
- catch (err) {
245
- res.status(500).json({ error: err.message });
246
- }
247
- });
248
- app.get("/api/tasks/:id", async (req, res) => {
501
+ const { items, repo } = getAttributes(req);
502
+ if (!Array.isArray(items) || !repo)
503
+ return res.status(400).json(jsonApiError("Invalid payload: requires 'items' array and 'repo'", 400));
504
+ const entries = items.map((item) => ({
505
+ ...item,
506
+ id: item.id || randomUUID(),
507
+ scope: { ...item.scope, repo },
508
+ created_at: item.created_at || (/* @__PURE__ */ new Date()).toISOString(),
509
+ updated_at: item.updated_at || (/* @__PURE__ */ new Date()).toISOString()
510
+ }));
511
+ const count = db.memories.bulkInsertMemories(entries);
512
+ db.actions.logAction("write", repo, { query: `Bulk imported ${count} memories` });
513
+ res.json(jsonApiRes({ count }, "status"));
514
+ } catch (err) {
515
+ const message = err instanceof Error ? err.message : "Internal server error";
516
+ res.status(500).json(jsonApiError(message));
517
+ }
518
+ }
519
+ static bulkAction(req, res) {
249
520
  try {
250
- const task = db.getTaskById(req.params.id);
251
- if (!task)
252
- throw new Error("Task not found");
253
- db.logAction("read", task.repo, { taskId: task.id });
254
- res.json(task);
255
- }
256
- catch (err) {
257
- res.status(404).json({ error: err.message });
258
- }
259
- });
260
- app.put("/api/tasks/:id", async (req, res) => {
521
+ const { action, ids, updates } = getAttributes(req);
522
+ if (!Array.isArray(ids) || !action)
523
+ return res.status(400).json(jsonApiError("Invalid payload: requires 'ids' array and 'action'", 400));
524
+ let count = 0;
525
+ if (action === "delete") {
526
+ count = db.memories.bulkDeleteMemories(ids);
527
+ } else if (action === "update" || action === "archive") {
528
+ count = db.memories.bulkUpdateMemories(
529
+ ids,
530
+ updates || { status: action === "archive" ? "archived" : "active" }
531
+ );
532
+ } else {
533
+ return res.status(400).json(jsonApiError("Invalid action", 400));
534
+ }
535
+ if (ids.length > 0) {
536
+ const mem = db.memories.getById(ids[0]);
537
+ db.actions.logAction(action, mem?.scope?.repo || "unknown", {
538
+ query: `Bulk ${action} applied to ${count} memories`
539
+ });
540
+ }
541
+ res.json(jsonApiRes({ count }, "status"));
542
+ } catch (err) {
543
+ const message = err instanceof Error ? err.message : "Internal server error";
544
+ res.status(500).json(jsonApiError(message));
545
+ }
546
+ }
547
+ };
548
+
549
+ // src/dashboard/routes/memory.routes.ts
550
+ var router2 = Router2();
551
+ router2.get("/", MemoriesController.list);
552
+ router2.post("/", MemoriesController.create);
553
+ router2.post("/import", MemoriesController.bulkCreate);
554
+ router2.post("/action", MemoriesController.bulkAction);
555
+ router2.get("/:id", MemoriesController.get);
556
+ router2.put("/:id", MemoriesController.update);
557
+ router2.delete("/:id", MemoriesController.delete);
558
+ var memory_routes_default = router2;
559
+
560
+ // src/dashboard/routes/task.routes.ts
561
+ import { Router as Router3 } from "express";
562
+
563
+ // src/dashboard/controllers/TasksController.ts
564
+ import { randomUUID as randomUUID2 } from "crypto";
565
+ var TasksController = class {
566
+ static list(req, res) {
261
567
  try {
262
- const { id } = req.params;
263
- const updates = req.body;
264
- const existingTask = db.getTaskById(id);
265
- if (!existingTask)
266
- return res.status(404).json({ error: "Task not found" });
267
- db.updateTask(id, updates);
268
- if (updates.status && updates.status !== existingTask.status) {
269
- db.logAction("update", existingTask.repo, { taskId: id, query: `Status changed to ${updates.status}` });
270
- db.insertTaskComment({
271
- id: randomUUID(),
272
- task_id: id,
273
- repo: existingTask.repo,
274
- comment: updates.comment || `Status updated via dashboard`,
275
- agent: "dashboard",
276
- role: "user",
277
- model: "web-ui",
278
- previous_status: existingTask.status,
279
- next_status: updates.status,
280
- created_at: new Date().toISOString()
281
- });
282
- }
283
- else if (updates.comment) {
284
- db.insertTaskComment({
285
- id: randomUUID(),
286
- task_id: id,
287
- repo: existingTask.repo,
288
- comment: updates.comment,
289
- agent: "dashboard",
290
- role: "user",
291
- model: "web-ui",
292
- created_at: new Date().toISOString()
293
- });
294
- }
295
- res.json({ success: true });
296
- }
297
- catch (err) {
298
- res.status(500).json({ error: err.message });
299
- }
300
- });
301
- app.delete("/api/tasks/:id", async (req, res) => {
568
+ const query = req.query;
569
+ const { repo, status, search } = query;
570
+ const page = Math.max(1, parseInt(req.query.page || "1", 10));
571
+ const pageSize = Math.min(100, Math.max(1, parseInt(req.query.pageSize || "20", 10)));
572
+ if (!repo) return res.status(400).json(jsonApiError("repo is required", 400));
573
+ let tasks;
574
+ if (status && status.includes(",")) {
575
+ tasks = db.tasks.getTasksByMultipleStatuses(
576
+ repo,
577
+ status.split(","),
578
+ pageSize,
579
+ (page - 1) * pageSize,
580
+ search
581
+ );
582
+ } else {
583
+ tasks = db.tasks.getTasksByRepo(
584
+ repo,
585
+ status,
586
+ pageSize,
587
+ (page - 1) * pageSize,
588
+ search
589
+ );
590
+ }
591
+ res.json(jsonApiRes(tasks, "task", { meta: { page, pageSize } }));
592
+ } catch (err) {
593
+ const message = err instanceof Error ? err.message : "Internal server error";
594
+ res.status(500).json(jsonApiError(message));
595
+ }
596
+ }
597
+ static get(req, res) {
302
598
  try {
303
- const { id } = req.params;
304
- const task = db.getTaskById(id);
305
- if (!task)
306
- return res.status(404).json({ error: "Task not found" });
307
- db.deleteTask(id);
308
- db.logAction("delete", task.repo, { taskId: id });
309
- res.json({ success: true });
310
- }
311
- catch (err) {
312
- res.status(500).json({ error: err.message });
313
- }
314
- });
315
- app.post("/api/tasks/bulk-import", async (req, res) => {
599
+ const task = db.tasks.getTaskById(req.params.id);
600
+ if (!task) throw new Error("Task not found");
601
+ db.actions.logAction("read", task.repo, { taskId: task.id });
602
+ res.json(jsonApiRes(task, "task"));
603
+ } catch (err) {
604
+ const message = err instanceof Error ? err.message : "Task not found";
605
+ res.status(404).json(jsonApiError(message, 404));
606
+ }
607
+ }
608
+ static create(req, res) {
316
609
  try {
317
- const { items, repo } = req.body;
318
- if (!Array.isArray(items) || !repo)
319
- return res.status(400).json({ error: "Invalid payload: requires 'items' array and 'repo'" });
320
- const tasks = items.map(t => ({
321
- ...t,
322
- id: t.id || randomUUID(),
323
- repo,
324
- task_code: t.task_code || randomUUID().substring(0, 8),
325
- created_at: t.created_at || new Date().toISOString(),
326
- updated_at: t.updated_at || new Date().toISOString()
327
- }));
328
- const count = db.bulkInsertTasks(tasks);
329
- db.logAction("write", repo, { query: `Bulk imported ${count} tasks` });
330
- res.json({ success: true, count });
331
- }
332
- catch (err) {
333
- res.status(500).json({ error: err.message });
334
- }
335
- });
336
- app.put("/api/task-comments/:id", async (req, res) => {
610
+ const attributes = getAttributes(req);
611
+ const { repo, task_code, title } = attributes;
612
+ if (!repo || !task_code || !title) return res.status(400).json(jsonApiError("Required fields missing", 400));
613
+ if (db.tasks.isTaskCodeDuplicate(repo, task_code))
614
+ return res.status(400).json(jsonApiError("Duplicate task_code", 400));
615
+ const id = randomUUID2();
616
+ db.tasks.insertTask({
617
+ ...attributes,
618
+ id,
619
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
620
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
621
+ });
622
+ db.actions.logAction("write", repo, { taskId: id });
623
+ res.json(jsonApiRes({ id }, "task"));
624
+ } catch (err) {
625
+ const message = err instanceof Error ? err.message : "Internal server error";
626
+ res.status(500).json(jsonApiError(message));
627
+ }
628
+ }
629
+ static update(req, res) {
337
630
  try {
338
- const { id } = req.params;
339
- const { comment } = req.body;
340
- const existingComment = db.getTaskCommentById(id);
341
- if (!existingComment)
342
- return res.status(404).json({ error: "Comment not found" });
343
- db.updateTaskComment(id, { comment });
344
- res.json({ success: true });
345
- }
346
- catch (err) {
347
- res.status(500).json({ error: err.message });
348
- }
349
- });
350
- app.delete("/api/task-comments/:id", async (req, res) => {
631
+ const { id } = req.params;
632
+ const attributes = getAttributes(req);
633
+ const existingTask = db.tasks.getTaskById(id);
634
+ if (!existingTask) return res.status(404).json(jsonApiError("Task not found", 404));
635
+ db.tasks.updateTask(id, attributes);
636
+ if (attributes.status && attributes.status !== existingTask.status) {
637
+ db.actions.logAction("update", existingTask.repo, {
638
+ taskId: id,
639
+ query: `Status changed to ${attributes.status}`
640
+ });
641
+ db.tasks.insertTaskComment({
642
+ id: randomUUID2(),
643
+ task_id: id,
644
+ repo: existingTask.repo,
645
+ comment: attributes.comment || `Status updated via dashboard`,
646
+ agent: "dashboard",
647
+ role: "user",
648
+ model: "web-ui",
649
+ previous_status: existingTask.status,
650
+ next_status: attributes.status,
651
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
652
+ });
653
+ } else if (attributes.comment) {
654
+ db.tasks.insertTaskComment({
655
+ id: randomUUID2(),
656
+ task_id: id,
657
+ repo: existingTask.repo,
658
+ comment: attributes.comment,
659
+ agent: "dashboard",
660
+ role: "user",
661
+ model: "web-ui",
662
+ previous_status: null,
663
+ next_status: null,
664
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
665
+ });
666
+ }
667
+ res.json(jsonApiRes({ message: "Updated" }, "status"));
668
+ } catch (err) {
669
+ const message = err instanceof Error ? err.message : "Internal server error";
670
+ res.status(500).json(jsonApiError(message));
671
+ }
672
+ }
673
+ static delete(req, res) {
351
674
  try {
352
- const { id } = req.params;
353
- db.deleteTaskComment(id);
354
- res.json({ success: true });
355
- }
356
- catch (err) {
357
- res.status(500).json({ error: err.message });
358
- }
359
- });
360
- app.post("/api/tasks", async (req, res) => {
675
+ const { id } = req.params;
676
+ const task = db.tasks.getTaskById(id);
677
+ if (!task) return res.status(404).json(jsonApiError("Task not found", 404));
678
+ db.tasks.deleteTask(id);
679
+ db.actions.logAction("delete", task.repo, { taskId: id });
680
+ res.json(jsonApiRes({ message: "Deleted" }, "status"));
681
+ } catch (err) {
682
+ const message = err instanceof Error ? err.message : "Internal server error";
683
+ res.status(500).json(jsonApiError(message));
684
+ }
685
+ }
686
+ static bulkCreate(req, res) {
361
687
  try {
362
- const { repo, task_code, title } = req.body;
363
- if (!repo || !task_code || !title)
364
- return res.status(400).json({ error: "Required fields missing" });
365
- if (db.isTaskCodeDuplicate(repo, task_code))
366
- return res.status(400).json({ error: "Duplicate task_code" });
367
- const id = randomUUID();
368
- db.insertTask({ ...req.body, id, created_at: new Date().toISOString(), updated_at: new Date().toISOString() });
369
- db.logAction("write", repo, { taskId: id });
370
- res.json({ success: true, id });
371
- }
372
- catch (err) {
373
- res.status(500).json({ error: err.message });
374
- }
375
- });
376
- app.get("/api/tasks/stats/time", async (req, res) => {
688
+ const { items, repo } = getAttributes(req);
689
+ if (!Array.isArray(items) || !repo)
690
+ return res.status(400).json(jsonApiError("Invalid payload: requires 'items' array and 'repo'", 400));
691
+ const tasks = items.map((item) => ({
692
+ ...item,
693
+ id: item.id || randomUUID2(),
694
+ repo,
695
+ task_code: item.task_code || randomUUID2().substring(0, 8),
696
+ created_at: item.created_at || (/* @__PURE__ */ new Date()).toISOString(),
697
+ updated_at: item.updated_at || (/* @__PURE__ */ new Date()).toISOString()
698
+ }));
699
+ const count = db.tasks.bulkInsertTasks(tasks);
700
+ db.actions.logAction("write", repo, { query: `Bulk imported ${count} tasks` });
701
+ res.json(jsonApiRes({ count }, "status"));
702
+ } catch (err) {
703
+ const message = err instanceof Error ? err.message : "Internal server error";
704
+ res.status(500).json(jsonApiError(message));
705
+ }
706
+ }
707
+ static getTimeStats(req, res) {
377
708
  try {
378
- const { repo } = req.query;
379
- if (!repo)
380
- return res.status(400).json({ error: "repo is required" });
381
- const stats = {
382
- daily: {
383
- ...db.getTaskTimeStats(repo, 'daily'),
384
- history: db.getTaskComparisonSeries(repo, 'daily')
385
- },
386
- weekly: {
387
- ...db.getTaskTimeStats(repo, 'weekly'),
388
- history: db.getTaskComparisonSeries(repo, 'weekly')
389
- },
390
- monthly: {
391
- ...db.getTaskTimeStats(repo, 'monthly'),
392
- history: db.getTaskComparisonSeries(repo, 'monthly')
393
- },
394
- overall: {
395
- ...db.getTaskTimeStats(repo, 'overall'),
396
- history: db.getTaskComparisonSeries(repo, 'overall')
397
- }
398
- };
399
- res.json(stats);
400
- }
401
- catch (err) {
402
- res.status(500).json({ error: err.message });
403
- }
404
- });
405
- app.get("/api/capabilities", (req, res) => {
406
- res.json({ tools: TOOL_DEFINITIONS || [], resources: listResources().resources || [], prompts: Object.values(PROMPTS) || [] });
407
- });
408
- app.get("/api/export", async (req, res) => {
709
+ const { repo } = req.query;
710
+ if (!repo) return res.status(400).json(jsonApiError("repo is required", 400));
711
+ const stats = {
712
+ daily: {
713
+ ...db.tasks.getTaskTimeStats(repo, "daily"),
714
+ history: db.tasks.getTaskComparisonSeries(repo, "daily")
715
+ },
716
+ weekly: {
717
+ ...db.tasks.getTaskTimeStats(repo, "weekly"),
718
+ history: db.tasks.getTaskComparisonSeries(repo, "weekly")
719
+ },
720
+ monthly: {
721
+ ...db.tasks.getTaskTimeStats(repo, "monthly"),
722
+ history: db.tasks.getTaskComparisonSeries(repo, "monthly")
723
+ },
724
+ overall: {
725
+ ...db.tasks.getTaskTimeStats(repo, "overall"),
726
+ history: db.tasks.getTaskComparisonSeries(repo, "overall")
727
+ }
728
+ };
729
+ res.json(jsonApiRes(stats, "performance-stats"));
730
+ } catch (err) {
731
+ const message = err instanceof Error ? err.message : "Internal server error";
732
+ res.status(500).json(jsonApiError(message));
733
+ }
734
+ }
735
+ static updateComment(req, res) {
409
736
  try {
410
- const { repo } = req.query;
411
- if (!repo)
412
- return res.status(400).json({ error: "repo is required" });
413
- const memories = db.getAllMemoriesWithStats(repo);
414
- const tasks = db.getTasksByRepo(repo);
415
- const allComments = db.getAllTaskCommentsByRepo(repo);
416
- const commentsByTaskId = allComments.reduce((acc, comment) => {
417
- if (!acc[comment.task_id]) {
418
- acc[comment.task_id] = [];
419
- }
420
- acc[comment.task_id].push(comment);
421
- return acc;
422
- }, {});
423
- const tasksWithComments = tasks.map(t => ({
424
- ...t,
425
- comments: commentsByTaskId[t.id] || []
426
- }));
427
- res.json({
428
- repo,
429
- exported_at: new Date().toISOString(),
430
- memories,
431
- tasks: tasksWithComments
432
- });
433
- }
434
- catch (err) {
435
- res.status(500).json({ error: err.message });
436
- }
437
- });
438
- app.post("/api/tools/:name/call", async (req, res) => {
737
+ const { id } = req.params;
738
+ const { comment } = getAttributes(req);
739
+ const existingComment = db.tasks.getTaskCommentById(id);
740
+ if (!existingComment) return res.status(404).json(jsonApiError("Comment not found", 404));
741
+ db.tasks.updateTaskComment(id, { comment });
742
+ res.json(jsonApiRes({ message: "Updated" }, "status"));
743
+ } catch (err) {
744
+ const message = err instanceof Error ? err.message : "Internal server error";
745
+ res.status(500).json(jsonApiError(message));
746
+ }
747
+ }
748
+ static deleteComment(req, res) {
439
749
  try {
440
- if (!mcpClient.isConnected()) {
441
- await mcpClient.start();
442
- }
443
- const { name } = req.params;
444
- const args = req.body;
445
- const result = await mcpClient.callTool(name, args);
446
- res.json(result);
447
- }
448
- catch (err) {
449
- res.status(500).json({ error: err.message });
450
- }
750
+ const { id } = req.params;
751
+ db.tasks.deleteTaskComment(id);
752
+ res.json(jsonApiRes({ message: "Deleted" }, "status"));
753
+ } catch (err) {
754
+ const message = err instanceof Error ? err.message : "Internal server error";
755
+ res.status(500).json(jsonApiError(message));
756
+ }
757
+ }
758
+ };
759
+
760
+ // src/dashboard/routes/task.routes.ts
761
+ var router3 = Router3();
762
+ router3.get("/", TasksController.list);
763
+ router3.post("/", TasksController.create);
764
+ router3.post("/import", TasksController.bulkCreate);
765
+ router3.get("/stats/time", TasksController.getTimeStats);
766
+ router3.get("/:id", TasksController.get);
767
+ router3.put("/:id", TasksController.update);
768
+ router3.delete("/:id", TasksController.delete);
769
+ router3.put("/comments/:id", TasksController.updateComment);
770
+ router3.delete("/comments/:id", TasksController.deleteComment);
771
+ var task_routes_default = router3;
772
+
773
+ // src/dashboard/routes/index.ts
774
+ var router4 = Router4();
775
+ router4.use("/", system_routes_default);
776
+ router4.use("/memories", memory_routes_default);
777
+ router4.use("/tasks", task_routes_default);
778
+ var routes_default = router4;
779
+
780
+ // src/dashboard/server.ts
781
+ var __dirname3 = path3.dirname(fileURLToPath3(import.meta.url));
782
+ var pkg2 = { version: "0.0.0" };
783
+ try {
784
+ const pkgPath = path3.join(__dirname3, "../../package.json");
785
+ if (fs2.existsSync(pkgPath)) {
786
+ pkg2 = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
787
+ }
788
+ } catch {
789
+ }
790
+ var app = express();
791
+ var PORT = process.env.PORT || 3456;
792
+ app.use(express.json());
793
+ app.use((req, res, next) => {
794
+ const start = Date.now();
795
+ res.on("finish", () => {
796
+ const duration = Date.now() - start;
797
+ if (duration > 1e3) {
798
+ logger.warn("Slow request", { method: req.method, path: req.path, duration });
799
+ }
800
+ });
801
+ next();
451
802
  });
452
- // --- Static Serving & Final Routes ---
453
- const staticRoot = fs.existsSync(path.join(__dirname, "public")) ? path.join(__dirname, "public") : path.join(process.cwd(), "src", "dashboard", "public");
803
+ app.use("/api", routes_default);
804
+ var staticRoot = fs2.existsSync(path3.join(__dirname3, "public")) ? path3.join(__dirname3, "public") : path3.join(process.cwd(), "src", "dashboard", "public");
454
805
  app.use(express.static(staticRoot));
455
- app.get("/", (req, res) => {
456
- res.sendFile(path.join(staticRoot, "index.html"));
806
+ app.use((req, res, next) => {
807
+ if (req.path.startsWith("/api")) return next();
808
+ res.sendFile(path3.join(staticRoot, "index.html"));
457
809
  });
458
- // --- Utilities ---
459
- function condenseRecentActions(actions, limit) {
460
- const condensed = [];
461
- for (const action of actions) {
462
- const prev = condensed[condensed.length - 1];
463
- const same = prev && prev.action === action.action && prev.query === action.query && prev.memory_id === action.memory_id;
464
- const within = prev && Math.abs(new Date(prev.created_at).getTime() - new Date(action.created_at).getTime()) <= 600000;
465
- if (same && within) {
466
- prev.burstCount++;
467
- prev.created_at = action.created_at;
468
- }
469
- else {
470
- condensed.push({ ...action, burstCount: 1 });
471
- }
472
- }
473
- return condensed.slice(0, limit);
474
- }
475
- // --- Start Server ---
476
- // The dashboard reads directly from SQLite for its own views, so it should stay
477
- // usable even when the MCP child process is unavailable.
478
810
  if (process.env.DASHBOARD_ENABLE_MCP === "true") {
479
- mcpClient.start().catch(e => logger.error("MCP Client failed", { error: e.message }));
811
+ mcpClient.start().catch((e) => logger.error("MCP Client failed", { error: e.message }));
480
812
  }
481
813
  app.listen(PORT, () => {
482
- console.log(`${new Date().toISOString()} DASHBOARD_STARTING v${pkg.version} on port ${PORT}`);
814
+ console.log(`${(/* @__PURE__ */ new Date()).toISOString()} DASHBOARD_STARTING v${pkg2.version} on port ${PORT}`);
815
+ });
816
+ process.on("SIGINT", () => {
817
+ mcpClient.stop();
818
+ db.close();
819
+ process.exit(0);
820
+ });
821
+ process.on("SIGTERM", () => {
822
+ mcpClient.stop();
823
+ db.close();
824
+ process.exit(0);
483
825
  });
484
- process.on("SIGINT", () => { mcpClient.stop(); db.close(); process.exit(0); });
485
- process.on("SIGTERM", () => { mcpClient.stop(); db.close(); process.exit(0); });
486
- //# sourceMappingURL=server.js.map