memory-journal-mcp 6.1.2 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/README.md +44 -28
  2. package/dist/{chunk-X4SWFATC.js → chunk-BI4ZNSKA.js} +38 -24
  3. package/dist/{chunk-HCEWINSB.js → chunk-N6EBIDN7.js} +99 -102
  4. package/dist/cli.js +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/tools-WPRY5MJ6.js +2 -0
  7. package/package.json +10 -1
  8. package/skills/github-commander/SKILL.md +151 -0
  9. package/skills/github-commander/config/project-config.example.md +125 -0
  10. package/skills/github-commander/workflows/code-quality-audit.md +80 -0
  11. package/skills/github-commander/workflows/full-audit.md +134 -0
  12. package/skills/github-commander/workflows/issue-triage.md +239 -0
  13. package/skills/github-commander/workflows/milestone-sprint.md +81 -0
  14. package/skills/github-commander/workflows/perf-audit.md +142 -0
  15. package/skills/github-commander/workflows/pr-review.md +123 -0
  16. package/skills/github-commander/workflows/security-audit.md +170 -0
  17. package/skills/github-commander/workflows/update-deps.md +109 -0
  18. package/.dockerignore +0 -139
  19. package/.gitattributes +0 -20
  20. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -95
  21. package/.github/ISSUE_TEMPLATE/config.yml +0 -11
  22. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -110
  23. package/.github/ISSUE_TEMPLATE/question.md +0 -78
  24. package/.github/aw/actions-lock.json +0 -14
  25. package/.github/copilot-instructions.md +0 -122
  26. package/.github/dependabot.yml +0 -93
  27. package/.github/pull_request_template.md +0 -135
  28. package/.github/workflows/README.md +0 -133
  29. package/.github/workflows/agentics-maintenance.yml +0 -141
  30. package/.github/workflows/auto-release.yml +0 -68
  31. package/.github/workflows/ci-health-monitor.lock.yml +0 -1121
  32. package/.github/workflows/ci-health-monitor.md +0 -87
  33. package/.github/workflows/codeql.yml +0 -41
  34. package/.github/workflows/dependabot-auto-merge.yml +0 -42
  35. package/.github/workflows/dependency-maintenance.lock.yml +0 -1182
  36. package/.github/workflows/dependency-maintenance.md +0 -147
  37. package/.github/workflows/docker-publish.yml +0 -254
  38. package/.github/workflows/docs-drift-detector.lock.yml +0 -1142
  39. package/.github/workflows/docs-drift-detector.md +0 -115
  40. package/.github/workflows/lint-and-test.yml +0 -60
  41. package/.github/workflows/publish-npm.yml +0 -85
  42. package/.github/workflows/secrets-scanning.yml +0 -32
  43. package/.github/workflows/security-update.yml +0 -127
  44. package/.gitleaks.toml +0 -9
  45. package/.prettierignore +0 -21
  46. package/.prettierrc +0 -33
  47. package/.scout-ignore +0 -12
  48. package/.trivyignore +0 -21
  49. package/CHANGELOG.md +0 -1814
  50. package/CODE_OF_CONDUCT.md +0 -133
  51. package/CONTRIBUTING.md +0 -263
  52. package/DOCKER_README.md +0 -331
  53. package/Dockerfile +0 -128
  54. package/SECURITY.md +0 -227
  55. package/UNRELEASED.md +0 -1
  56. package/dist/tools-T4U5A3X4.js +0 -2
  57. package/docker-compose.yml +0 -71
  58. package/docs/README.md +0 -18
  59. package/docs/agentic-journal-synergy.md +0 -175
  60. package/docs/copilot-setup.md +0 -72
  61. package/eslint.config.js +0 -110
  62. package/mcp-config-example.json +0 -21
  63. package/playwright.config.ts +0 -35
  64. package/releases/v2.1.0.md +0 -220
  65. package/releases/v2.2.0.md +0 -168
  66. package/releases/v3.0.0.md +0 -237
  67. package/releases/v3.1.0.md +0 -104
  68. package/releases/v3.1.1.md +0 -42
  69. package/releases/v3.1.2.md +0 -40
  70. package/releases/v3.1.3.md +0 -64
  71. package/releases/v3.1.4.md +0 -32
  72. package/releases/v3.1.5.md +0 -44
  73. package/releases/v4.0.0.md +0 -71
  74. package/releases/v4.1.0.md +0 -88
  75. package/releases/v4.2.0.md +0 -90
  76. package/releases/v4.3.0.md +0 -92
  77. package/releases/v4.3.1.md +0 -69
  78. package/releases/v4.4.0.md +0 -120
  79. package/releases/v4.4.1.md +0 -33
  80. package/releases/v4.4.2.md +0 -31
  81. package/releases/v4.5.0.md +0 -116
  82. package/releases/v5.0.0.md +0 -105
  83. package/releases/v5.0.1.md +0 -25
  84. package/releases/v5.1.0.md +0 -83
  85. package/releases/v5.1.1.md +0 -10
  86. package/releases/v6.0.0.md +0 -48
  87. package/releases/v6.0.1.md +0 -36
  88. package/releases/v6.1.0.md +0 -68
  89. package/releases/v6.1.1.md +0 -30
  90. package/releases/v6.1.2.md +0 -23
  91. package/scripts/generate-server-instructions.ts +0 -306
  92. package/scripts/server-instructions-function-body.ts +0 -107
  93. package/scripts/server-instructions-gotchas.ts +0 -45
  94. package/server.json +0 -42
  95. package/social-preview.png +0 -0
  96. package/src/auth/auth-context.ts +0 -78
  97. package/src/auth/authorization-server-discovery.ts +0 -263
  98. package/src/auth/errors.ts +0 -215
  99. package/src/auth/index.ts +0 -58
  100. package/src/auth/middleware.ts +0 -392
  101. package/src/auth/oauth-resource-server.ts +0 -170
  102. package/src/auth/scope-map.ts +0 -46
  103. package/src/auth/scopes.ts +0 -256
  104. package/src/auth/token-validator.ts +0 -293
  105. package/src/auth/transport-agnostic.ts +0 -164
  106. package/src/auth/types.ts +0 -372
  107. package/src/cli.ts +0 -279
  108. package/src/codemode/api-constants.ts +0 -263
  109. package/src/codemode/api.ts +0 -302
  110. package/src/codemode/auto-return.ts +0 -65
  111. package/src/codemode/index.ts +0 -47
  112. package/src/codemode/sandbox-factory.ts +0 -144
  113. package/src/codemode/sandbox.ts +0 -220
  114. package/src/codemode/security.ts +0 -155
  115. package/src/codemode/types.ts +0 -228
  116. package/src/codemode/worker-sandbox.ts +0 -277
  117. package/src/codemode/worker-script.ts +0 -239
  118. package/src/constants/icons.ts +0 -183
  119. package/src/constants/server-instructions.md +0 -166
  120. package/src/constants/server-instructions.ts +0 -514
  121. package/src/database/adapter-factory.ts +0 -16
  122. package/src/database/core/entry-columns.ts +0 -10
  123. package/src/database/core/interfaces.ts +0 -188
  124. package/src/database/core/schema.ts +0 -152
  125. package/src/database/sqlite-adapter/backup.ts +0 -167
  126. package/src/database/sqlite-adapter/entries/crud.ts +0 -233
  127. package/src/database/sqlite-adapter/entries/importance.ts +0 -76
  128. package/src/database/sqlite-adapter/entries/index.ts +0 -142
  129. package/src/database/sqlite-adapter/entries/search.ts +0 -294
  130. package/src/database/sqlite-adapter/entries/shared.ts +0 -102
  131. package/src/database/sqlite-adapter/entries/statistics.ts +0 -162
  132. package/src/database/sqlite-adapter/index.ts +0 -265
  133. package/src/database/sqlite-adapter/native-connection.ts +0 -301
  134. package/src/database/sqlite-adapter/relationships.ts +0 -70
  135. package/src/database/sqlite-adapter/tags.ts +0 -182
  136. package/src/filtering/tool-filter.ts +0 -312
  137. package/src/github/github-integration/client.ts +0 -114
  138. package/src/github/github-integration/index.ts +0 -297
  139. package/src/github/github-integration/insights.ts +0 -155
  140. package/src/github/github-integration/issues.ts +0 -213
  141. package/src/github/github-integration/milestones.ts +0 -262
  142. package/src/github/github-integration/projects.ts +0 -414
  143. package/src/github/github-integration/pull-requests.ts +0 -235
  144. package/src/github/github-integration/repository.ts +0 -110
  145. package/src/github/github-integration/types.ts +0 -43
  146. package/src/handlers/prompts/github.ts +0 -210
  147. package/src/handlers/prompts/index.ts +0 -97
  148. package/src/handlers/prompts/workflow.ts +0 -361
  149. package/src/handlers/resources/core/briefing/context-section.ts +0 -182
  150. package/src/handlers/resources/core/briefing/github-section.ts +0 -354
  151. package/src/handlers/resources/core/briefing/index.ts +0 -106
  152. package/src/handlers/resources/core/briefing/user-message.ts +0 -114
  153. package/src/handlers/resources/core/health.ts +0 -75
  154. package/src/handlers/resources/core/index.ts +0 -31
  155. package/src/handlers/resources/core/instructions.ts +0 -45
  156. package/src/handlers/resources/core/utilities.ts +0 -310
  157. package/src/handlers/resources/github.ts +0 -340
  158. package/src/handlers/resources/graph.ts +0 -218
  159. package/src/handlers/resources/help.ts +0 -410
  160. package/src/handlers/resources/index.ts +0 -143
  161. package/src/handlers/resources/shared.ts +0 -219
  162. package/src/handlers/resources/team.ts +0 -134
  163. package/src/handlers/resources/templates.ts +0 -334
  164. package/src/handlers/tools/admin.ts +0 -351
  165. package/src/handlers/tools/analytics.ts +0 -346
  166. package/src/handlers/tools/backup.ts +0 -272
  167. package/src/handlers/tools/codemode.ts +0 -188
  168. package/src/handlers/tools/core.ts +0 -359
  169. package/src/handlers/tools/error-fields-mixin.ts +0 -10
  170. package/src/handlers/tools/export.ts +0 -150
  171. package/src/handlers/tools/github/copilot-tools.ts +0 -72
  172. package/src/handlers/tools/github/helpers.ts +0 -125
  173. package/src/handlers/tools/github/insights-tools.ts +0 -112
  174. package/src/handlers/tools/github/issue-tools.ts +0 -442
  175. package/src/handlers/tools/github/kanban-tools.ts +0 -153
  176. package/src/handlers/tools/github/milestone-tools.ts +0 -371
  177. package/src/handlers/tools/github/mutation-tools.ts +0 -17
  178. package/src/handlers/tools/github/read-tools.ts +0 -302
  179. package/src/handlers/tools/github/schemas.ts +0 -435
  180. package/src/handlers/tools/github.ts +0 -39
  181. package/src/handlers/tools/index.ts +0 -255
  182. package/src/handlers/tools/relationships.ts +0 -390
  183. package/src/handlers/tools/schemas.ts +0 -165
  184. package/src/handlers/tools/search.ts +0 -448
  185. package/src/handlers/tools/team/admin-tools.ts +0 -164
  186. package/src/handlers/tools/team/analytics-tools.ts +0 -233
  187. package/src/handlers/tools/team/backup-tools.ts +0 -83
  188. package/src/handlers/tools/team/core-tools.ts +0 -197
  189. package/src/handlers/tools/team/export-tools.ts +0 -130
  190. package/src/handlers/tools/team/helpers.ts +0 -66
  191. package/src/handlers/tools/team/index.ts +0 -45
  192. package/src/handlers/tools/team/relationship-tools.ts +0 -219
  193. package/src/handlers/tools/team/schemas.ts +0 -558
  194. package/src/handlers/tools/team/search-tools.ts +0 -145
  195. package/src/handlers/tools/team/vector-tools.ts +0 -261
  196. package/src/index.ts +0 -57
  197. package/src/server/mcp-server.ts +0 -446
  198. package/src/server/registration.ts +0 -141
  199. package/src/server/scheduler.ts +0 -283
  200. package/src/transports/http/handlers.ts +0 -78
  201. package/src/transports/http/index.ts +0 -8
  202. package/src/transports/http/security.ts +0 -147
  203. package/src/transports/http/server/index.ts +0 -397
  204. package/src/transports/http/server/legacy-sse.ts +0 -87
  205. package/src/transports/http/server/stateful.ts +0 -222
  206. package/src/transports/http/server/stateless.ts +0 -42
  207. package/src/transports/http/types.ts +0 -132
  208. package/src/types/entities.ts +0 -145
  209. package/src/types/error-types.ts +0 -92
  210. package/src/types/errors.ts +0 -200
  211. package/src/types/filtering.ts +0 -55
  212. package/src/types/github.ts +0 -216
  213. package/src/types/index.ts +0 -348
  214. package/src/utils/error-helpers.ts +0 -78
  215. package/src/utils/errors/error-response-fields.ts +0 -29
  216. package/src/utils/errors/suggestions.ts +0 -94
  217. package/src/utils/github-helpers.ts +0 -33
  218. package/src/utils/logger.ts +0 -107
  219. package/src/utils/mcp-logger.ts +0 -155
  220. package/src/utils/progress-utils.ts +0 -100
  221. package/src/utils/query-helpers.ts +0 -78
  222. package/src/utils/resource-annotations.ts +0 -75
  223. package/src/utils/security-utils.ts +0 -198
  224. package/src/utils/vector-index-helpers.ts +0 -24
  225. package/src/vector/vector-search-manager.ts +0 -409
  226. package/src/version.ts +0 -15
  227. package/test-server/README.md +0 -193
  228. package/test-server/code-map.md +0 -399
  229. package/test-server/test-agent-experience.md +0 -213
  230. package/test-server/test-filter-instructions.mjs +0 -295
  231. package/test-server/test-instruction-levels.mjs +0 -102
  232. package/test-server/test-preflight.md +0 -55
  233. package/test-server/test-prompts.mjs +0 -185
  234. package/test-server/test-scheduler.mjs +0 -174
  235. package/test-server/test-tool-annotations.mjs +0 -115
  236. package/test-server/test-tools-codemode.md +0 -632
  237. package/test-server/test-tools-codemode2.md +0 -1218
  238. package/test-server/test-tools-team.md +0 -215
  239. package/test-server/test-tools.md +0 -429
  240. package/test-server/test-tools2.md +0 -361
  241. package/test-server/test-tools3.md +0 -396
  242. package/test-server/tool-reference.md +0 -231
  243. package/tests/README.md +0 -54
  244. package/tests/auth/auth-context.test.ts +0 -162
  245. package/tests/auth/authorization-server-discovery.test.ts +0 -265
  246. package/tests/auth/errors.test.ts +0 -170
  247. package/tests/auth/middleware.test.ts +0 -585
  248. package/tests/auth/oauth-resource-server.test.ts +0 -173
  249. package/tests/auth/scope-map.test.ts +0 -66
  250. package/tests/auth/scopes.test.ts +0 -347
  251. package/tests/auth/token-validator.test.ts +0 -271
  252. package/tests/codemode/api.test.ts +0 -396
  253. package/tests/codemode/auto-return.test.ts +0 -167
  254. package/tests/codemode/codemode-tool-handlers.test.ts +0 -197
  255. package/tests/codemode/sandbox-factory.test.ts +0 -152
  256. package/tests/codemode/sandbox.test.ts +0 -190
  257. package/tests/codemode/security.test.ts +0 -242
  258. package/tests/codemode/worker-sandbox.test.ts +0 -106
  259. package/tests/constants/icons.test.ts +0 -101
  260. package/tests/constants/server-instructions.test.ts +0 -514
  261. package/tests/database/crud-workflow-branches.test.ts +0 -418
  262. package/tests/database/database-branches.test.ts +0 -132
  263. package/tests/database/entries-auth-branches.test.ts +0 -390
  264. package/tests/database/native-connection.test.ts +0 -249
  265. package/tests/database/shared-helpers.test.ts +0 -103
  266. package/tests/database/sqlite-adapter.bench.ts +0 -63
  267. package/tests/database/sqlite-adapter.test.ts +0 -690
  268. package/tests/database/tags.test.ts +0 -134
  269. package/tests/e2e/README.md +0 -39
  270. package/tests/e2e/auth.spec.ts +0 -106
  271. package/tests/e2e/codemode-abuse.spec.ts +0 -75
  272. package/tests/e2e/health.spec.ts +0 -63
  273. package/tests/e2e/helpers.ts +0 -139
  274. package/tests/e2e/oauth-discovery.spec.ts +0 -102
  275. package/tests/e2e/oauth-scopes.spec.ts +0 -222
  276. package/tests/e2e/payloads-admin.spec.ts +0 -76
  277. package/tests/e2e/payloads-analytics.spec.ts +0 -37
  278. package/tests/e2e/payloads-backup-restore.spec.ts +0 -102
  279. package/tests/e2e/payloads-backup.spec.ts +0 -44
  280. package/tests/e2e/payloads-codemode-api.spec.ts +0 -131
  281. package/tests/e2e/payloads-codemode-readonly.spec.ts +0 -116
  282. package/tests/e2e/payloads-codemode.spec.ts +0 -116
  283. package/tests/e2e/payloads-core.spec.ts +0 -82
  284. package/tests/e2e/payloads-error-contracts.spec.ts +0 -159
  285. package/tests/e2e/payloads-export.spec.ts +0 -46
  286. package/tests/e2e/payloads-github-degradation.spec.ts +0 -73
  287. package/tests/e2e/payloads-github.spec.ts +0 -176
  288. package/tests/e2e/payloads-relationships.spec.ts +0 -56
  289. package/tests/e2e/payloads-search.spec.ts +0 -64
  290. package/tests/e2e/payloads-team-happy.spec.ts +0 -231
  291. package/tests/e2e/payloads-team.spec.ts +0 -174
  292. package/tests/e2e/prompts-expanded.spec.ts +0 -137
  293. package/tests/e2e/prompts.spec.ts +0 -62
  294. package/tests/e2e/protocols.spec.ts +0 -134
  295. package/tests/e2e/rate-limiting.spec.ts +0 -291
  296. package/tests/e2e/resources-briefing-env.spec.ts +0 -106
  297. package/tests/e2e/resources-complete.spec.ts +0 -180
  298. package/tests/e2e/resources-expanded.spec.ts +0 -83
  299. package/tests/e2e/resources-instructions-levels.spec.ts +0 -145
  300. package/tests/e2e/resources-templates.spec.ts +0 -123
  301. package/tests/e2e/resources.spec.ts +0 -103
  302. package/tests/e2e/scheduler.spec.ts +0 -79
  303. package/tests/e2e/security.spec.ts +0 -112
  304. package/tests/e2e/session-advanced.spec.ts +0 -152
  305. package/tests/e2e/sessions.spec.ts +0 -95
  306. package/tests/e2e/stateless.spec.ts +0 -79
  307. package/tests/e2e/streaming.spec.ts +0 -176
  308. package/tests/e2e/tool-filtering-presets.spec.ts +0 -192
  309. package/tests/e2e/tool-filtering.spec.ts +0 -77
  310. package/tests/e2e/tools.spec.ts +0 -111
  311. package/tests/filtering/tool-filter.test.ts +0 -314
  312. package/tests/github/client-issues-errors.test.ts +0 -433
  313. package/tests/github/github-integration-branches.test.ts +0 -490
  314. package/tests/github/github-integration.test.ts +0 -1015
  315. package/tests/github/github-managers-branches.test.ts +0 -907
  316. package/tests/github/pull-requests.test.ts +0 -334
  317. package/tests/handlers/analytics-branches.test.ts +0 -222
  318. package/tests/handlers/backup-branches.test.ts +0 -270
  319. package/tests/handlers/briefing-context-section.test.ts +0 -388
  320. package/tests/handlers/briefing-github-section.test.ts +0 -392
  321. package/tests/handlers/briefing-user-message.test.ts +0 -405
  322. package/tests/handlers/codemode-tools.test.ts +0 -85
  323. package/tests/handlers/copilot-tools.test.ts +0 -126
  324. package/tests/handlers/error-path-coverage.test.ts +0 -324
  325. package/tests/handlers/export-tools.test.ts +0 -203
  326. package/tests/handlers/github-resource-handlers.test.ts +0 -929
  327. package/tests/handlers/github-tool-handlers.test.ts +0 -1452
  328. package/tests/handlers/handler-error-branches.test.ts +0 -346
  329. package/tests/handlers/help-resource.test.ts +0 -92
  330. package/tests/handlers/prompt-handler-coverage.test.ts +0 -108
  331. package/tests/handlers/prompt-handlers.test.ts +0 -131
  332. package/tests/handlers/resource-handler-coverage.test.ts +0 -281
  333. package/tests/handlers/resource-handlers.test.ts +0 -357
  334. package/tests/handlers/resource-prompt-branches.test.ts +0 -495
  335. package/tests/handlers/search-tool-handlers.test.ts +0 -379
  336. package/tests/handlers/targeted-gap-closure.test.ts +0 -387
  337. package/tests/handlers/team-admin.test.ts +0 -291
  338. package/tests/handlers/team-analytics.test.ts +0 -220
  339. package/tests/handlers/team-core.test.ts +0 -148
  340. package/tests/handlers/team-data.test.ts +0 -198
  341. package/tests/handlers/team-relationships.test.ts +0 -271
  342. package/tests/handlers/team-resource-handlers.test.ts +0 -161
  343. package/tests/handlers/team-search.test.ts +0 -134
  344. package/tests/handlers/team-tool-handlers.test.ts +0 -301
  345. package/tests/handlers/team-vector.test.ts +0 -213
  346. package/tests/handlers/template-github-branches.test.ts +0 -676
  347. package/tests/handlers/tool-annotations.test.ts +0 -90
  348. package/tests/handlers/tool-handler-coverage.test.ts +0 -514
  349. package/tests/handlers/tool-handlers.test.ts +0 -510
  350. package/tests/handlers/tool-output-schemas.test.ts +0 -116
  351. package/tests/handlers/vector-tool-handlers.test.ts +0 -238
  352. package/tests/security/sql-injection.test.ts +0 -284
  353. package/tests/server/mcp-server.bench.ts +0 -55
  354. package/tests/server/mcp-server.test.ts +0 -1326
  355. package/tests/server/scheduler.test.ts +0 -400
  356. package/tests/transports/http-legacy-sse.test.ts +0 -275
  357. package/tests/transports/http-security.test.ts +0 -322
  358. package/tests/transports/http-stateful.test.ts +0 -487
  359. package/tests/transports/http-transport-server.test.ts +0 -301
  360. package/tests/transports/http-transport.test.ts +0 -771
  361. package/tests/utils/github-helpers.test.ts +0 -58
  362. package/tests/utils/logger.test.ts +0 -180
  363. package/tests/utils/mcp-logger.test.ts +0 -211
  364. package/tests/utils/progress-utils.test.ts +0 -156
  365. package/tests/utils/query-helpers.test.ts +0 -80
  366. package/tests/utils/security-utils.test.ts +0 -82
  367. package/tests/vector/vector-search-branches.test.ts +0 -111
  368. package/tests/vector/vector-search-manager.test.ts +0 -375
  369. package/tests/vector/vector-search.bench.ts +0 -48
  370. package/tsconfig.json +0 -42
  371. package/tsup.config.ts +0 -19
  372. package/vitest.config.ts +0 -25
@@ -1,390 +0,0 @@
1
- /**
2
- * memory-journal-mcp — Token Validator, Search, Statistics, Importance Branch Coverage
3
- *
4
- * Targets uncovered branches in:
5
- * - token-validator.ts (71.05%): JWKS cache hit, invalid issuer URL, error dispatch
6
- * - search.ts entries (79.24%): searchByDateRange filter combos (isPersonal, project, issue, pr, workflowRunId)
7
- * - statistics.ts (81.08%): date-filtered path, projectBreakdown, growthPercent null
8
- * - importance.ts (75%): null rel_count/causal_count
9
- */
10
-
11
- import { describe, it, expect, vi, beforeEach } from 'vitest'
12
- import Database from 'better-sqlite3'
13
-
14
- vi.mock('../../src/utils/logger.js', () => ({
15
- logger: { info: vi.fn(), warning: vi.fn(), error: vi.fn(), debug: vi.fn() },
16
- }))
17
-
18
- import { TokenValidator, createTokenValidator } from '../../src/auth/token-validator.js'
19
- import { AUTH_ERROR_CODES } from '../../src/auth/errors.js'
20
- import { searchByDateRange } from '../../src/database/sqlite-adapter/entries/search.js'
21
- import { getStatistics } from '../../src/database/sqlite-adapter/entries/statistics.js'
22
- import { calculateImportance } from '../../src/database/sqlite-adapter/entries/importance.js'
23
-
24
- // ============================================================================
25
- // Helpers — in-memory SQLite DB
26
- // ============================================================================
27
-
28
- function createTestDb() {
29
- const db = new Database(':memory:')
30
- db.exec(`
31
- CREATE TABLE memory_journal (
32
- id INTEGER PRIMARY KEY,
33
- content TEXT NOT NULL,
34
- entry_type TEXT DEFAULT 'personal_reflection',
35
- timestamp TEXT NOT NULL,
36
- is_personal INTEGER DEFAULT 1,
37
- deleted_at TEXT DEFAULT NULL,
38
- project_number INTEGER DEFAULT NULL,
39
- issue_number INTEGER DEFAULT NULL,
40
- pr_number INTEGER DEFAULT NULL,
41
- issue_url TEXT DEFAULT NULL,
42
- pr_url TEXT DEFAULT NULL,
43
- pr_status TEXT DEFAULT NULL,
44
- project_owner TEXT DEFAULT NULL,
45
- workflow_run_id INTEGER DEFAULT NULL,
46
- workflow_name TEXT DEFAULT NULL,
47
- workflow_status TEXT DEFAULT NULL,
48
- significance_type TEXT DEFAULT NULL,
49
- auto_context TEXT DEFAULT NULL,
50
- share_with_team INTEGER DEFAULT 0
51
- );
52
- CREATE TABLE tags (id INTEGER PRIMARY KEY, name TEXT UNIQUE, usage_count INTEGER DEFAULT 0);
53
- CREATE TABLE entry_tags (entry_id INTEGER, tag_id INTEGER);
54
- CREATE TABLE relationships (
55
- id INTEGER PRIMARY KEY,
56
- from_entry_id INTEGER,
57
- to_entry_id INTEGER,
58
- relationship_type TEXT,
59
- description TEXT DEFAULT NULL
60
- );
61
- CREATE VIRTUAL TABLE fts_content USING fts5(content, content_rowid='rowid');
62
- `)
63
- return db
64
- }
65
-
66
- function createTagsMgr() {
67
- return {
68
- batchGetTagsForEntries: vi.fn().mockReturnValue(new Map()),
69
- }
70
- }
71
-
72
- // ============================================================================
73
- // TokenValidator Branch Coverage
74
- // ============================================================================
75
-
76
- describe('TokenValidator — branch coverage', () => {
77
- it('should handle invalid issuer URL gracefully in constructor', () => {
78
- const validator = new TokenValidator({
79
- jwksUri: 'https://example.com/.well-known/jwks.json',
80
- issuer: 'not-a-url',
81
- audience: 'test',
82
- })
83
- expect(validator).toBeDefined()
84
- })
85
-
86
- it('should use cached JWKS on second call', () => {
87
- const validator = new TokenValidator({
88
- jwksUri: 'https://example.com/.well-known/jwks.json',
89
- issuer: 'https://example.com',
90
- audience: 'test',
91
- })
92
- // First call creates JWKS
93
- validator.refreshJwks()
94
- // Second call triggers cache hit branch because jwksExpiry is in the future
95
- // We verify no error is thrown
96
- expect(validator).toBeDefined()
97
- })
98
-
99
- it('should clear cache', () => {
100
- const validator = new TokenValidator({
101
- jwksUri: 'https://example.com/.well-known/jwks.json',
102
- issuer: 'https://example.com',
103
- audience: 'test',
104
- })
105
- validator.clearCache()
106
- expect(validator).toBeDefined()
107
- })
108
-
109
- it('should handle invalid JWKS URI gracefully', () => {
110
- const validator = new TokenValidator({
111
- jwksUri: 'not-a-url',
112
- issuer: 'https://example.com',
113
- audience: 'test',
114
- })
115
- // getJwks internally — URL constructor may throw for invalid jwksUri
116
- expect(() => validator.refreshJwks()).toThrow()
117
- })
118
-
119
- describe('handleValidationError dispatch', () => {
120
- let validator: TokenValidator
121
-
122
- beforeEach(() => {
123
- validator = new TokenValidator({
124
- jwksUri: 'https://example.com/.well-known/jwks.json',
125
- issuer: 'https://example.com',
126
- audience: 'test',
127
- })
128
- })
129
-
130
- it('should handle JWTExpired', async () => {
131
- // Access private handleValidationError via validate path
132
- const result = await validator.validate('invalid.token.here')
133
- expect(result.valid).toBe(false)
134
- })
135
-
136
- it('should return expired error via toOAuthError', () => {
137
- const result = TokenValidator.toOAuthError({
138
- valid: false,
139
- error: 'expired',
140
- errorCode: AUTH_ERROR_CODES.TOKEN_EXPIRED,
141
- })
142
- expect(result.code).toBe(AUTH_ERROR_CODES.TOKEN_EXPIRED)
143
- })
144
-
145
- it('should return signature error via toOAuthError', () => {
146
- const result = TokenValidator.toOAuthError({
147
- valid: false,
148
- error: 'bad sig',
149
- errorCode: AUTH_ERROR_CODES.SIGNATURE_INVALID,
150
- })
151
- expect(result.code).toBe(AUTH_ERROR_CODES.SIGNATURE_INVALID)
152
- })
153
-
154
- it('should return generic invalid token via toOAuthError', () => {
155
- const result = TokenValidator.toOAuthError({
156
- valid: false,
157
- error: 'some error',
158
- errorCode: AUTH_ERROR_CODES.TOKEN_INVALID,
159
- })
160
- expect(result.code).toBe(AUTH_ERROR_CODES.TOKEN_INVALID)
161
- })
162
- })
163
-
164
- it('createTokenValidator factory function', () => {
165
- const validator = createTokenValidator({
166
- jwksUri: 'https://example.com/.well-known/jwks.json',
167
- issuer: 'https://example.com',
168
- audience: 'test',
169
- })
170
- expect(validator).toBeInstanceOf(TokenValidator)
171
- })
172
- })
173
-
174
- // ============================================================================
175
- // searchByDateRange Branch Coverage — filter combinations
176
- // ============================================================================
177
-
178
- describe('searchByDateRange — filter combinations', () => {
179
- let db: InstanceType<typeof Database>
180
- let context: { db: ReturnType<typeof Database>; tagsMgr: ReturnType<typeof createTagsMgr> }
181
-
182
- beforeEach(() => {
183
- db = createTestDb()
184
- db.exec(`
185
- INSERT INTO memory_journal (id, content, timestamp, is_personal, project_number, issue_number, pr_number, workflow_run_id, entry_type)
186
- VALUES
187
- (1, 'entry one', '2025-01-15T10:00:00Z', 1, 42, 10, 20, 100, 'personal_reflection'),
188
- (2, 'entry two', '2025-01-20T10:00:00Z', 0, 42, 11, null, null, 'decision'),
189
- (3, 'entry three', '2025-02-01T10:00:00Z', 1, null, null, null, null, 'personal_reflection');
190
- INSERT INTO tags (id, name, usage_count) VALUES (1, 'test-tag', 1);
191
- INSERT INTO entry_tags (entry_id, tag_id) VALUES (1, 1);
192
- INSERT INTO fts_content (rowid, content) VALUES (1, 'entry one'), (2, 'entry two'), (3, 'entry three');
193
- `)
194
- context = { db, tagsMgr: createTagsMgr() }
195
- })
196
-
197
- it('should filter by date range only', () => {
198
- const result = searchByDateRange(context, '2025-01-01', '2025-01-31')
199
- expect(result.length).toBe(2)
200
- })
201
-
202
- it('should filter by isPersonal', () => {
203
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', { isPersonal: true })
204
- expect(result.every((e) => e.isPersonal === true)).toBe(true)
205
- })
206
-
207
- it('should filter by projectNumber', () => {
208
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', { projectNumber: 42 })
209
- expect(result.length).toBe(2)
210
- })
211
-
212
- it('should filter by issueNumber', () => {
213
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', { issueNumber: 10 })
214
- expect(result.length).toBe(1)
215
- })
216
-
217
- it('should filter by prNumber', () => {
218
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', { prNumber: 20 })
219
- expect(result.length).toBe(1)
220
- })
221
-
222
- it('should filter by workflowRunId', () => {
223
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', {
224
- workflowRunId: 100,
225
- })
226
- expect(result.length).toBe(1)
227
- })
228
-
229
- it('should filter by entryType', () => {
230
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', {
231
- entryType: 'decision',
232
- })
233
- expect(result.length).toBe(1)
234
- })
235
-
236
- it('should filter by tags', () => {
237
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', {
238
- tags: ['test-tag'],
239
- })
240
- expect(result.length).toBe(1)
241
- })
242
-
243
- it('should handle startDate without T (appends time)', () => {
244
- const result = searchByDateRange(context, '2025-01-01', '2025-01-31')
245
- expect(result.length).toBeGreaterThanOrEqual(0)
246
- })
247
-
248
- it('should handle endDate without T (appends time)', () => {
249
- const result = searchByDateRange(context, '2025-01-01', '2025-01-31')
250
- expect(result.length).toBeGreaterThanOrEqual(0)
251
- })
252
-
253
- it('should combine multiple filters', () => {
254
- const result = searchByDateRange(context, '2025-01-01', '2025-12-31', {
255
- isPersonal: true,
256
- projectNumber: 42,
257
- issueNumber: 10,
258
- prNumber: 20,
259
- workflowRunId: 100,
260
- })
261
- expect(result.length).toBe(1)
262
- })
263
- })
264
-
265
- // ============================================================================
266
- // getStatistics Branch Coverage
267
- // ============================================================================
268
-
269
- describe('getStatistics — branch coverage', () => {
270
- let db: InstanceType<typeof Database>
271
- let context: { db: ReturnType<typeof Database>; tagsMgr: ReturnType<typeof createTagsMgr> }
272
-
273
- beforeEach(() => {
274
- db = createTestDb()
275
- db.exec(`
276
- INSERT INTO memory_journal (id, content, timestamp, project_number, significance_type) VALUES
277
- (1, 'entry 1', '2025-01-15T10:00:00Z', 42, 'decision'),
278
- (2, 'entry 2', '2025-01-20T10:00:00Z', 42, null),
279
- (3, 'entry 3', '2025-02-01T10:00:00Z', null, null);
280
- INSERT INTO relationships (from_entry_id, to_entry_id, relationship_type) VALUES
281
- (1, 2, 'resolved'),
282
- (1, 3, 'references');
283
- `)
284
- context = { db, tagsMgr: createTagsMgr() }
285
- })
286
-
287
- it('should compute stats without date filters (else branch)', () => {
288
- const result = getStatistics(context)
289
- expect(result.totalEntries).toBe(3)
290
- })
291
-
292
- it('should compute stats with startDate filter', () => {
293
- const result = getStatistics(context, 'week', '2025-01-18')
294
- expect(result.totalEntries as number).toBe(2)
295
- })
296
-
297
- it('should compute stats with both date filters', () => {
298
- const result = getStatistics(context, 'week', '2025-01-01', '2025-01-31')
299
- expect(result.totalEntries as number).toBe(2)
300
- })
301
-
302
- it('should include projectBreakdown when requested', () => {
303
- const result = getStatistics(context, 'week', undefined, undefined, true)
304
- expect(result.projectBreakdown).toBeDefined()
305
- const breakdown = result.projectBreakdown as {
306
- project_number: number
307
- entry_count: number
308
- }[]
309
- expect(breakdown.length).toBe(1)
310
- expect(breakdown[0]!.project_number).toBe(42)
311
- })
312
-
313
- it('should compute growthPercent as null when previousCount is 0', () => {
314
- // With only one entry, the second period will be empty
315
- db.exec('DELETE FROM memory_journal WHERE id > 1')
316
- const result = getStatistics(context)
317
- const trend = result.activityTrend as { growthPercent: number | null }
318
- expect(trend.growthPercent).toBeNull()
319
- })
320
-
321
- it('should use year groupBy (maps to month format)', () => {
322
- const result = getStatistics(context, 'year')
323
- expect(result.totalEntries).toBe(3)
324
- })
325
-
326
- it('should include causalMetrics', () => {
327
- const result = getStatistics(context)
328
- const causal = result.causalMetrics as Record<string, number>
329
- expect(causal.resolved).toBe(1)
330
- })
331
-
332
- it('should include dateRange when date filters provided', () => {
333
- const result = getStatistics(context, 'week', '2025-01-01', '2025-12-31')
334
- expect(result.dateRange).toBeDefined()
335
- })
336
-
337
- it('should not include dateRange when no date filters', () => {
338
- const result = getStatistics(context)
339
- expect(result.dateRange).toBeUndefined()
340
- })
341
- })
342
-
343
- // ============================================================================
344
- // calculateImportance Branch Coverage
345
- // ============================================================================
346
-
347
- describe('calculateImportance — branch coverage', () => {
348
- let db: InstanceType<typeof Database>
349
- let context: { db: ReturnType<typeof Database>; tagsMgr: ReturnType<typeof createTagsMgr> }
350
-
351
- beforeEach(() => {
352
- db = createTestDb()
353
- context = { db, tagsMgr: createTagsMgr() }
354
- })
355
-
356
- it('should return 0 score for non-existent entry', () => {
357
- const result = calculateImportance(context, 999)
358
- expect(result.score).toBe(0)
359
- })
360
-
361
- it('should compute importance for entry with significance and relationships', () => {
362
- db.exec(`
363
- INSERT INTO memory_journal (id, content, timestamp, significance_type) VALUES (1, 'test', '${new Date().toISOString()}', 'decision');
364
- INSERT INTO relationships (from_entry_id, to_entry_id, relationship_type) VALUES (1, 2, 'references'), (1, 3, 'caused');
365
- `)
366
- const result = calculateImportance(context, 1)
367
- expect(result.score).toBeGreaterThan(0)
368
- expect(result.breakdown.significance).toBeGreaterThan(0)
369
- expect(result.breakdown.relationships).toBeGreaterThan(0)
370
- expect(result.breakdown.causal).toBeGreaterThan(0)
371
- expect(result.breakdown.recency).toBeGreaterThan(0)
372
- })
373
-
374
- it('should compute importance with no significance type', () => {
375
- db.exec(
376
- `INSERT INTO memory_journal (id, content, timestamp) VALUES (1, 'test', '${new Date().toISOString()}')`
377
- )
378
- const result = calculateImportance(context, 1)
379
- expect(result.breakdown.significance).toBe(0)
380
- })
381
-
382
- it('should decay recency for old entries', () => {
383
- const oldDate = new Date(Date.now() - 100 * 24 * 60 * 60 * 1000).toISOString()
384
- db.exec(
385
- `INSERT INTO memory_journal (id, content, timestamp) VALUES (1, 'old entry', '${oldDate}')`
386
- )
387
- const result = calculateImportance(context, 1)
388
- expect(result.breakdown.recency).toBe(0)
389
- })
390
- })
@@ -1,249 +0,0 @@
1
- /**
2
- * NativeConnectionManager Unit Tests
3
- *
4
- * Tests for init failure, migration, FTS rebuild,
5
- * and close-during-initialization branches.
6
- */
7
-
8
- import { describe, it, expect, afterAll } from 'vitest'
9
- import type Database from 'better-sqlite3'
10
- import fs from 'node:fs'
11
- import { NativeConnectionManager } from '../../src/database/sqlite-adapter/native-connection.js'
12
-
13
- const TEST_DB_PATH = './test-native-conn.db'
14
- const TEST_DB_PATH_2 = './test-native-conn-2.db'
15
- const TEST_DB_NESTED = './test-native-nested/subdir/test.db'
16
-
17
- function cleanupFiles(...paths: string[]) {
18
- for (const p of paths) {
19
- try {
20
- if (fs.existsSync(p)) fs.unlinkSync(p)
21
- } catch {
22
- // ignore
23
- }
24
- }
25
- }
26
-
27
- function cleanupDirs(...paths: string[]) {
28
- for (const p of paths) {
29
- try {
30
- if (fs.existsSync(p)) fs.rmSync(p, { recursive: true })
31
- } catch {
32
- // ignore
33
- }
34
- }
35
- }
36
-
37
- afterAll(() => {
38
- cleanupFiles(TEST_DB_PATH, TEST_DB_PATH_2)
39
- cleanupDirs('./test-native-nested')
40
- })
41
-
42
- describe('NativeConnectionManager', () => {
43
- // =========================================================================
44
- // Basic initialization
45
- // =========================================================================
46
-
47
- describe('initialize', () => {
48
- it('should initialize successfully and return a valid DB', async () => {
49
- const mgr = new NativeConnectionManager(TEST_DB_PATH)
50
- await mgr.initialize()
51
-
52
- const db = mgr.getRawDb() as Database
53
- expect(db).toBeDefined()
54
-
55
- // DB should be usable
56
- const result = db.prepare('SELECT 1 as n').get() as { n: number }
57
- expect(result.n).toBe(1)
58
-
59
- mgr.close()
60
- })
61
-
62
- it('should be idempotent (double init)', async () => {
63
- const mgr = new NativeConnectionManager(TEST_DB_PATH_2)
64
- await mgr.initialize()
65
- await mgr.initialize() // should not throw
66
-
67
- const db = mgr.getRawDb() as Database
68
- expect(db).toBeDefined()
69
- mgr.close()
70
- })
71
-
72
- it('should create parent directories if they do not exist', async () => {
73
- cleanupDirs('./test-native-nested')
74
- const mgr = new NativeConnectionManager(TEST_DB_NESTED)
75
- await mgr.initialize()
76
-
77
- expect(fs.existsSync(TEST_DB_NESTED)).toBe(true)
78
- mgr.close()
79
- })
80
-
81
- it('should handle and wrap initialization errors', async () => {
82
- const mkdirSpy = vi
83
- .spyOn(fs.promises, 'mkdir')
84
- .mockRejectedValueOnce(new Error('Permission denied'))
85
-
86
- cleanupDirs('./test-native-nested-error')
87
- const mgr = new NativeConnectionManager('./test-native-nested-error/db.sqlite')
88
-
89
- await expect(mgr.initialize()).rejects.toThrow('Permission denied')
90
-
91
- mkdirSpy.mockRestore()
92
- })
93
- })
94
-
95
- // =========================================================================
96
- // ensureDb guard
97
- // =========================================================================
98
-
99
- describe('ensureDb', () => {
100
- it('should throw ConnectionError when DB is not initialized', () => {
101
- const mgr = new NativeConnectionManager(':memory:')
102
- expect(() => mgr.getRawDb()).toThrow()
103
- })
104
- })
105
-
106
- // =========================================================================
107
- // Close behavior
108
- // =========================================================================
109
-
110
- describe('close', () => {
111
- it('should safely close and nullify DB', async () => {
112
- const mgr = new NativeConnectionManager(':memory:')
113
- await mgr.initialize()
114
- mgr.close()
115
-
116
- // getRawDb should throw after close
117
- expect(() => mgr.getRawDb()).toThrow()
118
- })
119
-
120
- it('should be safe to call close() multiple times', async () => {
121
- const mgr = new NativeConnectionManager(':memory:')
122
- await mgr.initialize()
123
- mgr.close()
124
- mgr.close() // should not throw
125
- })
126
- })
127
-
128
- // =========================================================================
129
- // Migration — column addition
130
- // =========================================================================
131
-
132
- describe('schema migration', () => {
133
- it('should add missing columns on re-init of existing DB', async () => {
134
- // First init creates full schema
135
- const mgr = new NativeConnectionManager(TEST_DB_PATH)
136
- await mgr.initialize()
137
-
138
- const db = mgr.getRawDb() as Database
139
- // Verify some migration columns exist
140
- const info = db.prepare('PRAGMA table_info(memory_journal)').all() as { name: string }[]
141
- const cols = info.map((r) => r.name)
142
-
143
- expect(cols).toContain('issue_url')
144
- expect(cols).toContain('pr_url')
145
- expect(cols).toContain('workflow_run_id')
146
-
147
- mgr.close()
148
- })
149
-
150
- it('should populate FTS5 on existing DBs missing FTS rows', async () => {
151
- const mgr = new NativeConnectionManager(TEST_DB_PATH_2)
152
- await mgr.initialize()
153
- const db = mgr.getRawDb() as Database
154
- db.exec("INSERT INTO memory_journal(content, entry_type) VALUES ('foo', 'test')")
155
- // Wipe fts_content manually
156
- db.exec('DELETE FROM fts_content')
157
- mgr.close()
158
-
159
- // Re-init should populate FTS
160
- const mgr2 = new NativeConnectionManager(TEST_DB_PATH_2)
161
- await mgr2.initialize()
162
- mgr2.close()
163
- })
164
-
165
- it('should rebuild FTS5 index if ghost entries detected', async () => {
166
- // First DB is initialized
167
- const mgr = new NativeConnectionManager(TEST_DB_PATH)
168
- await mgr.initialize()
169
- const db = mgr.getRawDb() as Database
170
-
171
- // FTS count is > 0, entryCount = 0 since we deleted memory_journal entries or made fts larger
172
- db.exec("INSERT INTO memory_journal(content, entry_type) VALUES ('foo', 'test')")
173
- db.exec("INSERT INTO memory_journal(content, entry_type) VALUES ('bar', 'test')")
174
- db.exec("INSERT INTO memory_journal(content, entry_type) VALUES ('baz', 'test')")
175
- // Drop delete trigger so deletion doesn't hit FTS
176
- db.exec('DROP TRIGGER IF EXISTS memory_journal_ad')
177
- db.exec('DELETE FROM memory_journal')
178
- mgr.close()
179
-
180
- // Re-init should trigger ghost cleanup because fts_count (3) > entry_count (0)
181
- const mgr2 = new NativeConnectionManager(TEST_DB_PATH)
182
- await mgr2.initialize()
183
- mgr2.close()
184
- })
185
- })
186
-
187
- // =========================================================================
188
- // Team schema
189
- // =========================================================================
190
-
191
- describe('applyTeamSchema', () => {
192
- it('should add author column', async () => {
193
- const mgr = new NativeConnectionManager(':memory:')
194
- await mgr.initialize()
195
- mgr.applyTeamSchema()
196
-
197
- const db = mgr.getRawDb() as Database
198
- const info = db.prepare('PRAGMA table_info(memory_journal)').all() as { name: string }[]
199
- const cols = info.map((r) => r.name)
200
- expect(cols).toContain('author')
201
-
202
- mgr.close()
203
- })
204
-
205
- it('should be idempotent (double apply)', async () => {
206
- const mgr = new NativeConnectionManager(':memory:')
207
- await mgr.initialize()
208
- mgr.applyTeamSchema()
209
- mgr.applyTeamSchema() // should not throw
210
-
211
- mgr.close()
212
- })
213
- })
214
-
215
- // =========================================================================
216
- // executeRawQuery
217
- // =========================================================================
218
-
219
- describe('exec', () => {
220
- it('should execute a raw query and return results', async () => {
221
- const mgr = new NativeConnectionManager(':memory:')
222
- await mgr.initialize()
223
-
224
- const db = mgr.getRawDb() as Database
225
- db.exec(
226
- "INSERT INTO memory_journal (entry_type, content, timestamp, is_personal) VALUES ('test_entry', 'test content', datetime('now'), 1)"
227
- )
228
-
229
- const result = mgr.exec('SELECT COUNT(*) as c FROM memory_journal', [])
230
- expect(result).toBeDefined()
231
- expect(result.length).toBeGreaterThan(0)
232
-
233
- mgr.close()
234
- })
235
- })
236
-
237
- // =========================================================================
238
- // pragma
239
- // =========================================================================
240
-
241
- describe('pragma', () => {
242
- it('should execute pragma commands', async () => {
243
- const mgr = new NativeConnectionManager(':memory:')
244
- await mgr.initialize()
245
- expect(() => mgr.pragma('cache_size = 2000')).not.toThrow()
246
- mgr.close()
247
- })
248
- })
249
- })