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,1218 +0,0 @@
1
- # Test memory-journal-mcp — Pass 4: Code Mode Advanced
2
-
3
- Test multi-step workflows, cross-group orchestration, and the remaining tool groups (relationships, GitHub, admin/backup/export, team) through Code Mode.
4
-
5
- **Scope:** ~55 test scenarios across 6 phases (Phases 22-27) covering multi-step pipelines, cross-group orchestration, relationships, GitHub (16 tools), admin/backup/export, and team tools — all via Code Mode.
6
-
7
- **Prerequisites:**
8
-
9
- - Pass 3 (`test-tools-codemode.md`) must pass first — sandbox, security, core CRUD, and search verified.
10
- - Pass 1 seed data (S1-S17) must exist — S13–S14 are personal journal entries with `project_number: 5`, S15–S17 are team DB entries with `project_number: 5`, all required for `get_cross_project_insights` / `team_get_cross_project_insights` to return non-empty results.
11
- - Confirm MCP server instructions were auto-received before starting.
12
- - Use the MCP server directly for all tests — not the terminal or scripts.
13
- - Use https://github.com/users/neverinfamous/projects/5 for project/Kanban testing.
14
-
15
- **Workflow after testing:**
16
-
17
- 1. Create a plan to fix any issues found or potential improvement opportunities, including changes to `server-instructions.md`/`server-instructions.ts` or this file (`test-server/test-tools-codemode2.md`).
18
- 2. Use `code-map.md` as a source of truth and ensure fixes comply with `C:\Users\chris\Desktop\adamic\skills\mcp-builder`.
19
- 3. After implementation, update `UNRELEASED.md` and commit without pushing. Then, stop so the user can verify with `npm run lint && npm run typecheck`, `npm run test`, and `npm run test:e2e`.
20
- 4. After user completes verification, re-test fixes with direct MCP calls.
21
- 5. Provide a very brief final summary.
22
-
23
- > [!IMPORTANT]
24
- > **Test Session Prerequisites**
25
-
26
- 1. The server instructions are auto-injected by the MCP protocol. Confirm receipt (no need to read `memory://instructions` separately).
27
- 2. Read `memory://briefing` to confirm context loaded (the briefing table confirms receipt).
28
-
29
- ---
30
-
31
- ## Phase 22: Multi-Step Workflows
32
-
33
- ### 22.1 Read-Only Pipelines
34
-
35
- | Test | Code | Expected Result |
36
- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
37
- | Stats + recent summary | `const stats = await mj.analytics.getStatistics({}); const recent = await mj.core.getRecentEntries({limit: 3}); return { total: stats.totalEntries, recentCount: recent.entries.length };` | Both fields populated |
38
- | Search + count | `const results = await mj.search.searchEntries({query: "test", limit: 5}); return { matchCount: results.entries.length, query: "test" };` | `matchCount` ≥ 0, `query: "test"` |
39
- | Recent + tag extraction | `const r = await mj.core.getRecentEntries({limit: 10}); const tags = r.entries.flatMap(e => e.tags \|\| []); const counts = {}; for (const t of tags) { counts[t] = (counts[t] \|\| 0) + 1; } return { uniqueTags: Object.keys(counts).length, topTags: Object.entries(counts).sort(([,a],[,b]) => b - a).slice(0, 5) };` | `uniqueTags` ≥ 0, `topTags` array |
40
-
41
- ### 22.2 Conditional Branching
42
-
43
- | Test | Code | Expected Result |
44
- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
45
- | Conditional on stats | `const s = await mj.analytics.getStatistics({}); if (s.totalEntries > 0) { return { status: "has entries", count: s.totalEntries }; } else { return { status: "empty journal" }; }` | Returns either branch based on data |
46
- | Loop over entries | `const r = await mj.core.getRecentEntries({limit: 5}); const summaries = r.entries.map(e => ({ id: e.id, type: e.entryType, len: e.content?.length ?? 0 })); return summaries;` | Array of summary objects |
47
-
48
- ### 22.3 Create + Read Round-Trip (via Code Mode)
49
-
50
- | Test | Code | Expected Result |
51
- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
52
- | Create + read back | `const created = await mj.core.createEntryMinimal({content: "Code Mode round-trip test"}); const fetched = await mj.core.getEntryById({entry_id: created.entry.id}); return { createdId: created.entry.id, fetchedContent: fetched.entry.content };` | `fetchedContent` matches "Code Mode round-trip test" |
53
- | Create + search | `const created = await mj.core.createEntry({content: "CodeMode search marker XYZ789", tags: ["codemode-test"]}); const found = await mj.search.searchEntries({query: "CodeMode search marker XYZ789", limit: 1}); return { found: found.entries.length > 0, createdId: created.entry.id };` | `found: true` |
54
-
55
- ---
56
-
57
- ## Phase 23: Cross-Group Orchestration
58
-
59
- > [!TIP]
60
- > These tests simulate real agent workflows that span multiple API groups in a single Code Mode execution — the primary use case for token savings.
61
-
62
- ### 23.1 Journal Health Dashboard
63
-
64
- ```javascript
65
- // Test code:
66
- const stats = await mj.analytics.getStatistics({})
67
- const recent = await mj.core.getRecentEntries({ limit: 5 })
68
- const tags = await mj.core.listTags({})
69
- return {
70
- totalEntries: stats.totalEntries,
71
- recentTitles: recent.entries.map((e) => e.title || e.content?.substring(0, 50)),
72
- tagCount: tags.tags?.length ?? 0,
73
- healthStatus: stats.totalEntries > 0 ? 'healthy' : 'empty',
74
- }
75
- ```
76
-
77
- | Check | Expected |
78
- | -------------- | ---------------- |
79
- | `totalEntries` | Number > 0 |
80
- | `recentTitles` | Array of strings |
81
- | `tagCount` | Number ≥ 0 |
82
- | `healthStatus` | `"healthy"` |
83
-
84
- ### 23.2 GitHub-Journal Coverage Report
85
-
86
- ```javascript
87
- // Test code:
88
- const issues = await mj.github.getGithubIssues({ limit: 3 })
89
- const results = []
90
- for (const issue of (issues.issues || []).slice(0, 2)) {
91
- const entries = await mj.search.searchEntries({
92
- query: `#${issue.number}`,
93
- limit: 3,
94
- })
95
- results.push({
96
- issue: `#${issue.number}: ${issue.title}`,
97
- linkedEntries: entries.entries.length,
98
- })
99
- }
100
- return { issueCount: issues.issues?.length ?? 0, coverage: results }
101
- ```
102
-
103
- | Check | Expected |
104
- | ------------ | ----------------------------------------------- |
105
- | `issueCount` | Number ≥ 0 |
106
- | `coverage` | Array with `issue` and `linkedEntries` per item |
107
-
108
- ### 23.3 Tag Analysis Pipeline
109
-
110
- ```javascript
111
- // Test code:
112
- const tagList = await mj.core.listTags({})
113
- const topTags = (tagList.tags || []).sort((a, b) => b.count - a.count).slice(0, 3)
114
- const report = []
115
- for (const tag of topTags) {
116
- const entries = await mj.search.searchEntries({ query: tag.name, limit: 2 })
117
- report.push({ tag: tag.name, count: tag.count, sampleEntries: entries.entries.length })
118
- }
119
- return { analyzedTags: report.length, report }
120
- ```
121
-
122
- | Check | Expected |
123
- | -------------- | --------------------------------------------------- |
124
- | `analyzedTags` | Number ≥ 0 |
125
- | `report` | Array with `tag`, `count`, `sampleEntries` per item |
126
-
127
- ### 23.4 Relationship Graph Summary
128
-
129
- ```javascript
130
- // Test code:
131
- const recent = await mj.core.getRecentEntries({ limit: 5 })
132
- const withRelationships = []
133
- for (const entry of recent.entries.slice(0, 3)) {
134
- const detail = await mj.core.getEntryById({ entry_id: entry.id })
135
- const relCount = detail.entry?.relationships?.length ?? 0
136
- if (relCount > 0) {
137
- withRelationships.push({ id: entry.id, relationships: relCount })
138
- }
139
- }
140
- return { checked: Math.min(recent.entries.length, 3), withRelationships }
141
- ```
142
-
143
- | Check | Expected |
144
- | ------------------- | ---------------------------------------------- |
145
- | `checked` | Number (1-3) |
146
- | `withRelationships` | Array (may be empty if no relationships exist) |
147
-
148
- ### 23.5 Full Pipeline: Create → Index → Search
149
-
150
- > [!CAUTION]
151
- > This test creates a real entry and modifies the vector index.
152
-
153
- ```javascript
154
- // Test code:
155
- const entry = await mj.core.createEntry({
156
- content: 'Code Mode pipeline test: semantic indexing verification ZQJKM',
157
- tags: ['codemode-pipeline-test'],
158
- entry_type: 'technical_note',
159
- })
160
- await mj.admin.addToVectorIndex({ entry_id: entry.entry.id })
161
- const found = await mj.search.semanticSearch({
162
- query: 'semantic indexing verification',
163
- limit: 5,
164
- })
165
- const match = found.entries?.some((e) => e.id === entry.entry.id)
166
- return {
167
- createdId: entry.entry.id,
168
- indexed: true,
169
- foundInSemantic: match,
170
- totalResults: found.entries?.length ?? 0,
171
- }
172
- ```
173
-
174
- | Check | Expected |
175
- | ----------------- | ----------------------------------------------------------------------------------------------------- |
176
- | `createdId` | Number |
177
- | `foundInSemantic` | `true` or `false` — may be `false` due to vector indexing latency within a single Code Mode execution |
178
- | `totalResults` | ≥ 1 |
179
-
180
- ---
181
-
182
- ## Phase 24: Relationships & Visualization via Code Mode
183
-
184
- ### 24.1 Link Entries — All Relationship Types
185
-
186
- ```javascript
187
- // Test code:
188
- const r = await mj.core.getRecentEntries({ limit: 4 })
189
- const ids = r.entries.map((e) => e.id)
190
- if (ids.length < 4) return { error: 'Need at least 4 entries' }
191
-
192
- const ref = await mj.relationships.linkEntries({
193
- from_entry_id: ids[0],
194
- to_entry_id: ids[1],
195
- relationship_type: 'references',
196
- })
197
- const impl = await mj.relationships.linkEntries({
198
- from_entry_id: ids[0],
199
- to_entry_id: ids[2],
200
- relationship_type: 'implements',
201
- description: 'Implements the spec',
202
- })
203
- const blocked = await mj.relationships.linkEntries({
204
- from_entry_id: ids[0],
205
- to_entry_id: ids[3],
206
- relationship_type: 'blocked_by',
207
- })
208
- const resolved = await mj.relationships.linkEntries({
209
- from_entry_id: ids[1],
210
- to_entry_id: ids[2],
211
- relationship_type: 'resolved',
212
- })
213
- const caused = await mj.relationships.linkEntries({
214
- from_entry_id: ids[2],
215
- to_entry_id: ids[3],
216
- relationship_type: 'caused',
217
- })
218
- return {
219
- refSuccess: ref.success,
220
- implSuccess: impl.success,
221
- implHasDesc: !!impl.relationship?.description,
222
- blockedSuccess: blocked.success,
223
- resolvedSuccess: resolved.success,
224
- causedSuccess: caused.success,
225
- entryIds: ids,
226
- }
227
- ```
228
-
229
- | Check | Expected |
230
- | -------------- | -------- |
231
- | All `*Success` | `true` |
232
- | `implHasDesc` | `true` |
233
-
234
- ### 24.2 Link Entries — Duplicate & Error Paths
235
-
236
- ```javascript
237
- // Test code (run after 24.1):
238
- const r = await mj.core.getRecentEntries({ limit: 2 })
239
- const [a, b] = r.entries.map((e) => e.id)
240
-
241
- const dup = await mj.relationships.linkEntries({
242
- from_entry_id: a,
243
- to_entry_id: b,
244
- relationship_type: 'references',
245
- })
246
- const reverse = await mj.relationships.linkEntries({
247
- from_entry_id: b,
248
- to_entry_id: a,
249
- relationship_type: 'references',
250
- })
251
- const badSource = await mj.relationships.linkEntries({
252
- from_entry_id: 999999,
253
- to_entry_id: b,
254
- relationship_type: 'references',
255
- })
256
- const badTarget = await mj.relationships.linkEntries({
257
- from_entry_id: a,
258
- to_entry_id: 999999,
259
- relationship_type: 'references',
260
- })
261
- return {
262
- dupDetected: dup.duplicate === true,
263
- dupHasMessage: !!dup.message,
264
- reverseSuccess: reverse.success,
265
- badSourceFailed: badSource.success === false,
266
- badTargetFailed: badTarget.success === false,
267
- }
268
- ```
269
-
270
- | Check | Expected |
271
- | ----------------- | ---------------------------------- |
272
- | `dupDetected` | `true` |
273
- | `reverseSuccess` | `true` (reverse direction allowed) |
274
- | `badSourceFailed` | `true` |
275
- | `badTargetFailed` | `true` |
276
-
277
- ### 24.3 Visualize Relationships
278
-
279
- ```javascript
280
- // Test code:
281
- const r = await mj.core.getRecentEntries({ limit: 1 })
282
- const id = r.entries[0].id
283
-
284
- const viz = await mj.relationships.visualizeRelationships({ entry_id: id })
285
- const vizTags = await mj.relationships.visualizeRelationships({ tags: ['architecture'] })
286
- const vizDeep = await mj.relationships.visualizeRelationships({ entry_id: id, depth: 3 })
287
- const vizLimit = await mj.relationships.visualizeRelationships({ entry_id: id, limit: 5 })
288
- const vizBad = await mj.relationships.visualizeRelationships({ entry_id: 999999 })
289
- return {
290
- hasMermaid: typeof viz.mermaid === 'string' && viz.mermaid.length > 0,
291
- hasLegend: !!viz.legend,
292
- entryCount: viz.entry_count,
293
- relCount: viz.relationship_count,
294
- tagVizHasMermaid: typeof vizTags.mermaid === 'string',
295
- deepEntryCount: vizDeep.entry_count,
296
- limitEntryCount: vizLimit.entry_count,
297
- badNotFound: !!vizBad.message && vizBad.message.includes('not found'),
298
- }
299
- ```
300
-
301
- | Check | Expected |
302
- | ------------- | -------- |
303
- | `hasMermaid` | `true` |
304
- | `hasLegend` | `true` |
305
- | `entryCount` | ≥ 1 |
306
- | `badNotFound` | `true` |
307
-
308
- ---
309
-
310
- ## Phase 25: GitHub Tools via Code Mode (16 tools)
311
-
312
- > [!CAUTION]
313
- > Phase 25.3–25.4 create and modify **real GitHub issues and milestones**. Clean up after testing.
314
-
315
- ### 25.1 Read-Only GitHub Tools
316
-
317
- ```javascript
318
- // Test code:
319
- const ctx = await mj.github.getGithubContext({})
320
- const issues = await mj.github.getGithubIssues({ limit: 3 })
321
- const closedIssues = await mj.github.getGithubIssues({ state: 'closed', limit: 2 })
322
- const prs = await mj.github.getGithubPrs({ limit: 3 })
323
- const closedPrs = await mj.github.getGithubPrs({ state: 'closed', limit: 2 })
324
- const milestones = await mj.github.getGithubMilestones({})
325
-
326
- // Single-item lookups (use known numbers from context)
327
- const issueNum = issues.issues?.[0]?.number
328
- const prNum = prs.pullRequests?.[0]?.number ?? closedPrs.pullRequests?.[0]?.number
329
- const singleIssue = issueNum ? await mj.github.getGithubIssue({ issue_number: issueNum }) : null
330
- const singlePr = prNum ? await mj.github.getGithubPr({ pr_number: prNum }) : null
331
-
332
- return {
333
- contextHasRepo: !!ctx.repoName,
334
- contextHasBranch: !!ctx.branch,
335
- issueCount: issues.count,
336
- issueMilestoneField: typeof issues.issues?.[0]?.milestone,
337
- closedIssueCount: closedIssues.count,
338
- prCount: prs.count,
339
- closedPrCount: closedPrs.count,
340
- milestoneCount: milestones.count,
341
- singleIssueHasBody: !!singleIssue?.issue?.body !== undefined,
342
- singlePrHasDraft: singlePr?.pullRequest?.draft !== undefined,
343
- }
344
- ```
345
-
346
- | Check | Expected |
347
- | ------------------ | -------- |
348
- | `contextHasRepo` | `true` |
349
- | `contextHasBranch` | `true` |
350
- | `issueCount` | ≥ 0 |
351
- | `milestoneCount` | ≥ 0 |
352
-
353
- ### 25.2 GitHub Error Paths
354
-
355
- | Test | Code | Expected Result |
356
- | --------------------- | -------------------------------------------------------------------------- | ------------------------------------------ |
357
- | Nonexistent issue | `return await mj.github.getGithubIssue({ issue_number: 999999 });` | `{ error: "Issue #999999 not found" }` |
358
- | Nonexistent PR | `return await mj.github.getGithubPr({ pr_number: 999999 });` | `{ error: "PR #999999 not found" }` |
359
- | Nonexistent milestone | `return await mj.github.getGithubMilestone({ milestone_number: 999999 });` | `{ error: "Milestone #999999 not found" }` |
360
- | Nonexistent Kanban | `return await mj.github.getKanbanBoard({ project_number: 99999 });` | Structured error with project not found |
361
-
362
- ### 25.3 Kanban Tools
363
-
364
- ```javascript
365
- // Test code:
366
- const board = await mj.github.getKanbanBoard({ project_number: 5 })
367
- const hasItems = board.columns?.some((c) => c.items?.length > 0)
368
- const itemId = board.columns?.flatMap((c) => c.items ?? []).find((i) => i)?.id
369
-
370
- let moveResult = null
371
- if (itemId) {
372
- moveResult = await mj.github.moveKanbanItem({
373
- project_number: 5,
374
- item_id: itemId,
375
- target_status: 'In progress',
376
- })
377
- }
378
-
379
- const badMove = await mj.github.moveKanbanItem({
380
- project_number: 5,
381
- item_id: itemId || 'fake-id',
382
- target_status: 'Nonexistent Status',
383
- })
384
-
385
- return {
386
- boardHasColumns: Array.isArray(board.columns),
387
- statusOptions: board.statusOptions,
388
- hasItems,
389
- moveSuccess: moveResult?.success,
390
- badMoveError: badMove.success === false,
391
- badMoveHasStatuses: Array.isArray(badMove.availableStatuses),
392
- }
393
- ```
394
-
395
- | Check | Expected |
396
- | -------------------- | ----------------------- |
397
- | `boardHasColumns` | `true` |
398
- | `statusOptions` | Array of valid statuses |
399
- | `moveSuccess` | `true` (if items exist) |
400
- | `badMoveError` | `true` |
401
- | `badMoveHasStatuses` | `true` |
402
-
403
- ### 25.4 Issue Lifecycle & Milestone CRUD
404
-
405
- > [!CAUTION]
406
- > Creates and closes real GitHub issues and milestones. Clean up in Phase 25.6.
407
-
408
- ```javascript
409
- // Test code — Issue Lifecycle:
410
- const created = await mj.github.createGithubIssueWithEntry({
411
- title: 'CM4 Test: Code Mode Issue',
412
- body: 'Created via Code Mode test',
413
- labels: ['test'],
414
- project_number: 5,
415
- tags: ['codemode4-test'],
416
- })
417
- const issueNum = created.issue?.number
418
-
419
- const closed = await mj.github.closeGithubIssueWithEntry({
420
- issue_number: issueNum,
421
- resolution_notes: 'CM4 test complete',
422
- comment: 'Closing via Code Mode',
423
- move_to_done: true,
424
- project_number: 5,
425
- })
426
-
427
- const alreadyClosed = await mj.github.closeGithubIssueWithEntry({
428
- issue_number: issueNum,
429
- })
430
-
431
- return {
432
- createSuccess: created.success,
433
- issueNumber: issueNum,
434
- hasJournal: !!created.journalEntry,
435
- hasProject: !!created.project,
436
- closeSuccess: closed.success,
437
- closeHasKanban: !!closed.kanban,
438
- kanbanMoved: closed.kanban?.moved,
439
- alreadyClosedError: alreadyClosed.success === false,
440
- alreadyClosedMsg: alreadyClosed.error,
441
- }
442
- ```
443
-
444
- | Check | Expected |
445
- | -------------------- | -------- |
446
- | `createSuccess` | `true` |
447
- | `hasJournal` | `true` |
448
- | `closeSuccess` | `true` |
449
- | `kanbanMoved` | `true` |
450
- | `alreadyClosedError` | `true` |
451
-
452
- ```javascript
453
- // Test code — Milestone CRUD:
454
- const ms = await mj.github.createGithubMilestone({
455
- title: 'CM4 Test Milestone',
456
- description: 'Created via Code Mode',
457
- due_on: '2026-12-31',
458
- })
459
- const msNum = ms.milestone?.number
460
-
461
- const updated = await mj.github.updateGithubMilestone({
462
- milestone_number: msNum,
463
- description: 'Updated via Code Mode',
464
- })
465
-
466
- const closed = await mj.github.updateGithubMilestone({
467
- milestone_number: msNum,
468
- state: 'closed',
469
- })
470
-
471
- const detail = await mj.github.getGithubMilestone({
472
- milestone_number: msNum,
473
- })
474
-
475
- const deleted = await mj.github.deleteGithubMilestone({
476
- milestone_number: msNum,
477
- confirm: true,
478
- })
479
-
480
- return {
481
- createSuccess: ms.success,
482
- msNumber: msNum,
483
- updateSuccess: updated.success,
484
- closeSuccess: closed.success,
485
- detailState: detail.milestone?.state,
486
- deleteSuccess: deleted.success,
487
- }
488
- ```
489
-
490
- | Check | Expected |
491
- | --------------- | ---------- |
492
- | `createSuccess` | `true` |
493
- | `updateSuccess` | `true` |
494
- | `detailState` | `"closed"` |
495
- | `deleteSuccess` | `true` |
496
-
497
- ### 25.5 Repo Insights & Copilot Reviews
498
-
499
- ```javascript
500
- // Test code:
501
- const stars = await mj.github.getRepoInsights({})
502
- const traffic = await mj.github.getRepoInsights({ sections: 'traffic' })
503
- const all = await mj.github.getRepoInsights({ sections: 'all' })
504
-
505
- // Copilot reviews (use a known PR number)
506
- const reviewed = await mj.github.getCopilotReviews({ pr_number: 1 })
507
-
508
- return {
509
- hasStars: typeof stars.stars === 'number',
510
- hasForks: typeof stars.forks === 'number',
511
- trafficHasClones: traffic.traffic?.clones !== undefined || traffic.error !== undefined,
512
- allSections: !!all,
513
- reviewState: reviewed.state,
514
- reviewComments: reviewed.commentCount,
515
- }
516
- ```
517
-
518
- | Check | Expected |
519
- | ------------- | ------------------------------------- |
520
- | `hasStars` | `true` |
521
- | `hasForks` | `true` |
522
- | `reviewState` | String (`"none"`, `"approved"`, etc.) |
523
-
524
- ### 25.6 GitHub Cleanup
525
-
526
- > [!IMPORTANT]
527
- > Run after all Phase 25 tests. Check for any unclosed test issues or milestones.
528
-
529
- | Cleanup Step | Code |
530
- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
531
- | Verify no orphans | `const b = await mj.github.getKanbanBoard({ project_number: 5 }); const testItems = b.columns?.flatMap(c => c.items ?? []).filter(i => i.title?.includes("CM4")); return { orphans: testItems?.length ?? 0 };` |
532
-
533
- ---
534
-
535
- ## Phase 26: Admin, Backup & Export via Code Mode
536
-
537
- ### 26.1 Tag Management
538
-
539
- ```javascript
540
- // Test code:
541
- const tags = await mj.core.listTags({})
542
- const hasEntries = tags.tags?.length > 0
543
-
544
- // Create source tag for merge
545
- await mj.core.createEntry({ content: 'CM4 merge test entry', tags: ['cm4-old-tag'] })
546
- const merged = await mj.admin.mergeTags({
547
- source_tag: 'cm4-old-tag',
548
- target_tag: 'cm4-new-tag',
549
- })
550
- const afterMerge = await mj.core.listTags({})
551
- const oldGone = !afterMerge.tags?.some((t) => t.name === 'cm4-old-tag')
552
- const newExists = afterMerge.tags?.some((t) => t.name === 'cm4-new-tag')
553
-
554
- // Error paths
555
- const sameMerge = await mj.admin.mergeTags({
556
- source_tag: 'cm4-new-tag',
557
- target_tag: 'cm4-new-tag',
558
- })
559
- const nonexistentMerge = await mj.admin.mergeTags({
560
- source_tag: 'nonexistent-xyz-cm4',
561
- target_tag: 'test',
562
- })
563
-
564
- return {
565
- tagCount: tags.tags?.length ?? 0,
566
- mergeSuccess: merged.success,
567
- entriesUpdated: merged.entriesUpdated,
568
- oldTagGone: oldGone,
569
- newTagExists: newExists,
570
- sameTagError: sameMerge.success === false,
571
- nonexistentError: nonexistentMerge.success === false,
572
- }
573
- ```
574
-
575
- | Check | Expected |
576
- | ------------------ | -------- |
577
- | `mergeSuccess` | `true` |
578
- | `oldTagGone` | `true` |
579
- | `newTagExists` | `true` |
580
- | `sameTagError` | `true` |
581
- | `nonexistentError` | `true` |
582
-
583
- ### 26.2 Export
584
-
585
- ```javascript
586
- // Test code:
587
- const jsonExport = await mj.export.exportEntries({ format: 'json', limit: 5 })
588
- const mdExport = await mj.export.exportEntries({ format: 'markdown', limit: 5 })
589
- const tagExport = await mj.export.exportEntries({
590
- format: 'json',
591
- tags: ['architecture'],
592
- limit: 10,
593
- })
594
- const dateExport = await mj.export.exportEntries({
595
- format: 'json',
596
- start_date: '2026-01-01',
597
- end_date: '2026-03-01',
598
- })
599
- const typeExport = await mj.export.exportEntries({
600
- format: 'json',
601
- entry_types: ['planning'],
602
- limit: 10,
603
- })
604
- return {
605
- jsonHasEntries: Array.isArray(jsonExport.entries),
606
- jsonCount: jsonExport.entries?.length ?? 0,
607
- mdHasContent: typeof mdExport.content === 'string',
608
- tagFiltered:
609
- tagExport.entries?.every(
610
- (e) => e.tags?.includes('architecture') || e.tags?.some((t) => t === 'architecture')
611
- ) ?? false,
612
- dateFiltered: dateExport.entries?.length >= 0,
613
- typeFiltered: typeExport.entries?.every((e) => e.entryType === 'planning') ?? true,
614
- }
615
- ```
616
-
617
- | Check | Expected |
618
- | ---------------- | --------------------------------------------- |
619
- | `jsonHasEntries` | `true` |
620
- | `mdHasContent` | `true` |
621
- | `tagFiltered` | `true` (only entries with "architecture" tag) |
622
- | `typeFiltered` | `true` (only "planning" type) |
623
-
624
- ### 26.3 Backup & Restore
625
-
626
- ```javascript
627
- // Test code:
628
- const named = await mj.backup.backupJournal({ name: 'cm4-test-backup' })
629
- const auto = await mj.backup.backupJournal({})
630
- const list = await mj.backup.listBackups({})
631
-
632
- // Path traversal
633
- const traversal = await mj.backup.backupJournal({ name: '../../etc/passwd' })
634
-
635
- // Restore
636
- const restored = await mj.backup.restoreBackup({
637
- filename: named.filename,
638
- confirm: true,
639
- })
640
-
641
- // Restore nonexistent
642
- const badRestore = await mj.backup.restoreBackup({
643
- filename: 'nonexistent-cm4.db',
644
- confirm: true,
645
- })
646
-
647
- // Cleanup
648
- const cleanup = await mj.backup.cleanupBackups({ keep_count: 5 })
649
-
650
- return {
651
- namedSuccess: named.success,
652
- namedFilename: named.filename,
653
- namedHasPath: !!named.path,
654
- namedHasSize: typeof named.sizeBytes === 'number',
655
- autoSuccess: auto.success,
656
- listTotal: list.total,
657
- traversalBlocked: traversal.success === false,
658
- restoreSuccess: restored.success,
659
- restoreHasReverted: !!restored.revertedChanges,
660
- badRestoreError: badRestore.success === false,
661
- cleanupSuccess: cleanup.success,
662
- }
663
- ```
664
-
665
- | Check | Expected |
666
- | ------------------ | -------- |
667
- | `namedSuccess` | `true` |
668
- | `namedHasPath` | `true` |
669
- | `namedHasSize` | `true` |
670
- | `autoSuccess` | `true` |
671
- | `traversalBlocked` | `true` |
672
- | `restoreSuccess` | `true` |
673
- | `badRestoreError` | `true` |
674
- | `cleanupSuccess` | `true` |
675
-
676
- ---
677
-
678
- ## Phase 27: Team Tools & Error Paths via Code Mode
679
-
680
- > [!NOTE]
681
- > Requires `TEAM_DB_PATH` to be configured. If not configured, all team tools should return structured `{ success: false, error: "Team database not configured..." }`.
682
- >
683
- > **`team_delete_entry` is soft-delete only** — no `permanent` flag.
684
-
685
- ### 27.1 Team CRUD
686
-
687
- ```javascript
688
- // Test code:
689
- const created = await mj.team.teamCreateEntry({
690
- content: 'CM4 team entry test',
691
- tags: ['codemode4-team-test'],
692
- entry_type: 'standup',
693
- })
694
- const withAuthor = await mj.team.teamCreateEntry({
695
- content: 'CM4 team explicit author',
696
- author: 'CM4Bot',
697
- })
698
- const recent = await mj.team.teamGetRecent({ limit: 5 })
699
- const search = await mj.team.teamSearch({ query: 'CM4 team entry test' })
700
- const tagSearch = await mj.team.teamSearch({ tags: ['codemode4-team-test'] })
701
- const combined = await mj.team.teamSearch({
702
- query: 'team',
703
- tags: ['codemode4-team-test'],
704
- })
705
- const noArgs = await mj.team.teamSearch({})
706
-
707
- // New: get by ID, list tags
708
- const detail = await mj.team.teamGetEntryById({ entry_id: created.entry.id })
709
- const detailNoRels = await mj.team.teamGetEntryById({
710
- entry_id: created.entry.id,
711
- include_relationships: false,
712
- })
713
- const tags = await mj.team.teamListTags({})
714
-
715
- return {
716
- createSuccess: created.success,
717
- createAuthor: created.entry?.author,
718
- explicitAuthor: withAuthor.entry?.author,
719
- recentCount: recent.entries?.length ?? 0,
720
- recentHasAuthor: !!recent.entries?.[0]?.author,
721
- searchCount: search.entries?.length ?? 0,
722
- tagSearchCount: tagSearch.entries?.length ?? 0,
723
- combinedCount: combined.entries?.length ?? 0,
724
- noArgsCount: noArgs.entries?.length ?? 0,
725
- detailHasEntry: !!detail.entry,
726
- detailHasImportance: !!detail.importance,
727
- detailNoRelsEmpty: !detailNoRels.relationships?.length,
728
- tagCount: tags.tags?.length ?? 0,
729
- }
730
- ```
731
-
732
- | Check | Expected |
733
- | ----------------- | --------------------------------- |
734
- | `createSuccess` | `true` |
735
- | `createAuthor` | Non-empty string (auto-populated) |
736
- | `explicitAuthor` | `"CM4Bot"` |
737
- | `recentHasAuthor` | `true` |
738
- | `searchCount` | ≥ 1 |
739
- | `tagSearchCount` | ≥ 1 |
740
- | `detailHasEntry` | `true` |
741
- | `tagCount` | ≥ 1 |
742
-
743
- ### 27.2 Team Error Paths
744
-
745
- | Test | Code | Expected Result |
746
- | ------------------ | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
747
- | Invalid entry_type | `return await mj.team.teamCreateEntry({ content: "test", entry_type: "invalid" });` | `{ success: false, error: "..." }` |
748
- | Nonexistent get | `return await mj.team.teamGetEntryById({ entry_id: 999999 });` | `{ success: false, error: "..." }` |
749
- | Nonexistent update | `return await mj.team.teamUpdateEntry({ entry_id: 999999, content: "x" });` | `{ success: false, error: "..." }` |
750
- | Nonexistent delete | `return await mj.team.teamDeleteEntry({ entry_id: 999999 });` | `{ success: false, error: "..." }` |
751
- | Invalid date range | `return await mj.team.teamSearchByDateRange({ start_date: "Jan 1", end_date: "Jan 31" });` | `{ success: false, error: "..." }` |
752
- | Merge same tag | `return await mj.team.teamMergeTags({ source_tag: "x", target_tag: "x" });` | `{ success: false, error: "..." }` |
753
- | Link nonexistent | `return await mj.team.teamLinkEntries({ from_entry_id: 999999, to_entry_id: 1, relationship_type: "references" });` | `{ success: false, error: "..." }` |
754
-
755
- ### 27.3 Team Date Range Search
756
-
757
- ```javascript
758
- // Test code:
759
- const results = await mj.team.teamSearchByDateRange({
760
- start_date: '2026-01-01',
761
- end_date: '2026-12-31',
762
- })
763
- const typed = await mj.team.teamSearchByDateRange({
764
- start_date: '2026-01-01',
765
- end_date: '2026-12-31',
766
- entry_type: 'standup',
767
- })
768
- const tagged = await mj.team.teamSearchByDateRange({
769
- start_date: '2026-01-01',
770
- end_date: '2026-12-31',
771
- tags: ['codemode4-team-test'],
772
- })
773
- return {
774
- hasEntries: Array.isArray(results.entries),
775
- count: results.count ?? 0,
776
- typedFiltered: typed.entries?.every((e) => e.entryType === 'standup') ?? true,
777
- taggedCount: tagged.entries?.length ?? 0,
778
- }
779
- ```
780
-
781
- | Check | Expected |
782
- | --------------- | -------- |
783
- | `hasEntries` | `true` |
784
- | `typedFiltered` | `true` |
785
-
786
- ### 27.4 Team Admin
787
-
788
- ```javascript
789
- // Test code:
790
- const r = await mj.team.teamGetRecent({ limit: 1 })
791
- const id = r.entries[0].id
792
-
793
- const updated = await mj.team.teamUpdateEntry({
794
- entry_id: id,
795
- content: 'CM4 updated team content',
796
- tags: ['cm4-updated-team'],
797
- })
798
- const verify = await mj.team.teamGetEntryById({ entry_id: id })
799
-
800
- // Merge tags
801
- await mj.team.teamCreateEntry({ content: 'CM4 merge source', tags: ['cm4-team-old'] })
802
- const merged = await mj.team.teamMergeTags({
803
- source_tag: 'cm4-team-old',
804
- target_tag: 'cm4-team-new',
805
- })
806
- const afterTags = await mj.team.teamListTags({})
807
- const oldGone = !afterTags.tags?.some((t) => t.name === 'cm4-team-old')
808
- const newExists = afterTags.tags?.some((t) => t.name === 'cm4-team-new')
809
-
810
- // Soft delete
811
- const toDelete = await mj.team.teamCreateEntry({ content: 'CM4 delete me' })
812
- const deleted = await mj.team.teamDeleteEntry({ entry_id: toDelete.entry.id })
813
-
814
- return {
815
- updateSuccess: updated.success,
816
- contentUpdated: verify.entry?.content === 'CM4 updated team content',
817
- mergeSuccess: merged.success,
818
- oldTagGone: oldGone,
819
- newTagExists: newExists,
820
- deleteSuccess: deleted.success,
821
- }
822
- ```
823
-
824
- | Check | Expected |
825
- | ---------------- | -------- |
826
- | `updateSuccess` | `true` |
827
- | `contentUpdated` | `true` |
828
- | `mergeSuccess` | `true` |
829
- | `oldTagGone` | `true` |
830
- | `newTagExists` | `true` |
831
- | `deleteSuccess` | `true` |
832
-
833
- ### 27.5 Team Analytics
834
-
835
- ```javascript
836
- // Test code:
837
- const stats = await mj.team.teamGetStatistics({})
838
- const monthly = await mj.team.teamGetStatistics({ group_by: 'month' })
839
- return {
840
- hasTotalEntries: typeof stats.totalEntries === 'number',
841
- hasEntriesByType: !!stats.entriesByType,
842
- hasAuthors: Array.isArray(stats.authors),
843
- monthlyHasPeriods: Array.isArray(monthly.entriesByPeriod),
844
- }
845
- ```
846
-
847
- | Check | Expected |
848
- | ------------------- | -------- |
849
- | `hasTotalEntries` | `true` |
850
- | `hasEntriesByType` | `true` |
851
- | `hasAuthors` | `true` |
852
- | `monthlyHasPeriods` | `true` |
853
-
854
- ### 27.6 Team Relationships
855
-
856
- ```javascript
857
- // Test code:
858
- const r = await mj.team.teamGetRecent({ limit: 2 })
859
- const [a, b] = r.entries.map((e) => e.id)
860
-
861
- const linked = await mj.team.teamLinkEntries({
862
- from_entry_id: a,
863
- to_entry_id: b,
864
- relationship_type: 'references',
865
- description: 'CM4 team link test',
866
- })
867
- const dup = await mj.team.teamLinkEntries({
868
- from_entry_id: a,
869
- to_entry_id: b,
870
- relationship_type: 'references',
871
- })
872
- const viz = await mj.team.teamVisualizeRelationships({ entry_id: a })
873
- const vizTag = await mj.team.teamVisualizeRelationships({ tag: 'codemode4-team-test' })
874
-
875
- return {
876
- linkSuccess: linked.success,
877
- hasDescription: !!linked.relationship?.description,
878
- dupDetected: dup.duplicate === true,
879
- hasMermaid: typeof viz.mermaid === 'string' && viz.mermaid.length > 0,
880
- nodeCount: viz.nodeCount,
881
- tagVizHasMermaid: typeof vizTag.mermaid === 'string',
882
- }
883
- ```
884
-
885
- | Check | Expected |
886
- | ---------------- | -------- |
887
- | `linkSuccess` | `true` |
888
- | `hasDescription` | `true` |
889
- | `dupDetected` | `true` |
890
- | `hasMermaid` | `true` |
891
-
892
- ### 27.7 Team Export
893
-
894
- ```javascript
895
- // Test code:
896
- const jsonExport = await mj.team.teamExportEntries({ format: 'json', limit: 5 })
897
- const mdExport = await mj.team.teamExportEntries({ format: 'markdown', limit: 5 })
898
- const tagExport = await mj.team.teamExportEntries({
899
- format: 'json',
900
- tags: ['codemode4-team-test'],
901
- limit: 10,
902
- })
903
- return {
904
- jsonHasData: typeof jsonExport.data === 'string',
905
- jsonCount: jsonExport.count ?? 0,
906
- mdHasData: typeof mdExport.data === 'string',
907
- tagFilteredCount: tagExport.count ?? 0,
908
- }
909
- ```
910
-
911
- | Check | Expected |
912
- | ------------- | -------- |
913
- | `jsonHasData` | `true` |
914
- | `mdHasData` | `true` |
915
- | `jsonCount` | ≥ 1 |
916
-
917
- ### 27.8 Team Backup
918
-
919
- ```javascript
920
- // Test code:
921
- const named = await mj.team.teamBackup({ name: 'cm4-team-backup' })
922
- const auto = await mj.team.teamBackup({})
923
- const list = await mj.team.teamListBackups({})
924
- return {
925
- namedSuccess: named.success,
926
- namedFilename: named.filename,
927
- namedHasPath: !!named.path,
928
- namedHasSize: typeof named.sizeBytes === 'number',
929
- autoSuccess: auto.success,
930
- listTotal: list.total,
931
- listHasBackups: Array.isArray(list.backups),
932
- }
933
- ```
934
-
935
- | Check | Expected |
936
- | ---------------- | -------- |
937
- | `namedSuccess` | `true` |
938
- | `namedHasPath` | `true` |
939
- | `namedHasSize` | `true` |
940
- | `autoSuccess` | `true` |
941
- | `listHasBackups` | `true` |
942
-
943
- ### 27.9 Team Vector & Cross-Project Insights
944
-
945
- ```javascript
946
- // Test code:
947
- const rebuild = await mj.team.teamRebuildVectorIndex({})
948
- const stats = await mj.team.teamGetVectorIndexStats({})
949
-
950
- const search = await mj.team.teamSemanticSearch({ query: 'standup' })
951
- const strict = await mj.team.teamSemanticSearch({
952
- query: 'standup',
953
- similarity_threshold: 0.5,
954
- })
955
-
956
- const recent = await mj.team.teamGetRecent({ limit: 1 })
957
- const addResult = await mj.team.teamAddToVectorIndex({
958
- entry_id: recent.entries[0].id,
959
- })
960
- const addBad = await mj.team.teamAddToVectorIndex({ entry_id: 999999 })
961
-
962
- const insights = await mj.team.teamGetCrossProjectInsights({})
963
- const insightsFiltered = await mj.team.teamGetCrossProjectInsights({
964
- start_date: '2026-01-01',
965
- end_date: '2026-03-01',
966
- min_entries: 1,
967
- })
968
-
969
- return {
970
- rebuildSuccess: rebuild.success,
971
- entriesIndexed: rebuild.entriesIndexed,
972
- vectorAvailable: stats.available,
973
- vectorItemCount: stats.itemCount,
974
- searchCount: search.entries?.length ?? 0,
975
- strictFewer: (strict.entries?.length ?? 0) <= (search.entries?.length ?? 0),
976
- addSuccess: addResult.success,
977
- addBadError: addBad.success === false,
978
- insightsProjectCount: insights.project_count,
979
- insightsHasProjects: Array.isArray(insights.projects),
980
- filteredInsights: insightsFiltered.project_count >= 0,
981
- }
982
- ```
983
-
984
- | Check | Expected |
985
- | ---------------------- | ------------------------------------------------------------------------- |
986
- | `rebuildSuccess` | `true` |
987
- | `entriesIndexed` | Number > 0 |
988
- | `vectorAvailable` | `true` |
989
- | `searchCount` | ≥ 1 |
990
- | `strictFewer` | `true` |
991
- | `addSuccess` | `true` |
992
- | `addBadError` | `true` |
993
- | `insightsHasProjects` | `true` |
994
- | `insightsProjectCount` | ≥ 1 (project 5 visible with seed entries S15–S17; 0 if team seed missing) |
995
- | `filteredInsights` | `project_count ≥ 0` (≥ 1 if S15–S17 fall within date range) |
996
-
997
- ### 27.10 Cross-Tool Error Path Verification (via Code Mode)
998
-
999
- > [!IMPORTANT]
1000
- > Verify that tool errors propagate as structured handler errors through the Code Mode API bridge — not as raw MCP errors or unhandled exceptions.
1001
-
1002
- ```javascript
1003
- // Test code — batch error path testing:
1004
- const errors = {}
1005
-
1006
- // Core errors
1007
- errors.createEmpty = await mj.core.createEntry({ content: '' })
1008
- errors.getNotFound = await mj.core.getEntryById({ entry_id: 999999 })
1009
- errors.updateNotFound = await mj.admin.updateEntry({ entry_id: 999999, content: 'x' })
1010
- errors.deleteNotFound = await mj.admin.deleteEntry({ entry_id: 999999 })
1011
-
1012
- // Relationship errors
1013
- errors.linkBadSource = await mj.relationships.linkEntries({
1014
- from_entry_id: 999999,
1015
- to_entry_id: 1,
1016
- relationship_type: 'references',
1017
- })
1018
- errors.vizNotFound = await mj.relationships.visualizeRelationships({ entry_id: 999999 })
1019
-
1020
- // GitHub errors
1021
- errors.issueNotFound = await mj.github.getGithubIssue({ issue_number: 999999 })
1022
- errors.prNotFound = await mj.github.getGithubPr({ pr_number: 999999 })
1023
- errors.msNotFound = await mj.github.getGithubMilestone({ milestone_number: 999999 })
1024
-
1025
- // Backup errors
1026
- errors.restoreNotFound = await mj.backup.restoreBackup({
1027
- filename: 'nonexistent.db',
1028
- confirm: true,
1029
- })
1030
- errors.backupTraversal = await mj.backup.backupJournal({ name: '../../../etc/passwd' })
1031
-
1032
- // Admin errors
1033
- errors.mergeNonexistent = await mj.admin.mergeTags({
1034
- source_tag: 'nonexistent-xyz-abc',
1035
- target_tag: 'test',
1036
- })
1037
- errors.addVectorBad = await mj.admin.addToVectorIndex({ entry_id: 999999 })
1038
-
1039
- // Team errors
1040
- errors.teamGetNotFound = await mj.team.teamGetEntryById({ entry_id: 999999 })
1041
- errors.teamUpdateNotFound = await mj.team.teamUpdateEntry({ entry_id: 999999, content: 'x' })
1042
- errors.teamDeleteNotFound = await mj.team.teamDeleteEntry({ entry_id: 999999 })
1043
- errors.teamLinkBad = await mj.team.teamLinkEntries({
1044
- from_entry_id: 999999,
1045
- to_entry_id: 1,
1046
- relationship_type: 'references',
1047
- })
1048
-
1049
- // Team vector errors (only true error paths)
1050
- errors.teamAddVectorBad = await mj.team.teamAddToVectorIndex({ entry_id: 999999 })
1051
-
1052
- // Verify all errors are structured (not raw throws)
1053
- const allStructured = Object.entries(errors).every(([key, val]) => {
1054
- return (
1055
- val &&
1056
- typeof val === 'object' &&
1057
- (val.success === false || val.error !== undefined || val.message?.includes('not found'))
1058
- )
1059
- })
1060
-
1061
- return {
1062
- testedCount: Object.keys(errors).length,
1063
- allStructured,
1064
- details: Object.fromEntries(
1065
- Object.entries(errors).map(([k, v]) => [
1066
- k,
1067
- {
1068
- success: v.success,
1069
- hasError: !!v.error || !!v.message,
1070
- errorSnippet: (v.error || v.message || '')?.substring(0, 60),
1071
- },
1072
- ])
1073
- ),
1074
- }
1075
- ```
1076
-
1077
- | Check | Expected |
1078
- | --------------- | --------------------------------------------------- |
1079
- | `testedCount` | 18 |
1080
- | `allStructured` | `true` — no raw exceptions through Code Mode bridge |
1081
-
1082
- ---
1083
-
1084
- ## Cleanup
1085
-
1086
- After testing, remove all entries and backups created during Phases 22-27:
1087
-
1088
- ```javascript
1089
- // Cleanup code:
1090
- const entries = await mj.search.searchEntries({ query: 'CM4', limit: 50 })
1091
- const cm4Entries = entries.entries.filter(
1092
- (e) => e.content?.includes('CM4') || e.tags?.some((t) => t.startsWith('codemode4'))
1093
- )
1094
- const results = []
1095
- for (const e of cm4Entries) {
1096
- const del = await mj.admin.deleteEntry({ entry_id: e.id, permanent: true })
1097
- results.push({ id: e.id, deleted: del.success })
1098
- }
1099
-
1100
- // Also clean up Code Mode (Phase 22-23) entries
1101
- const cmEntries = await mj.search.searchEntries({ query: 'CodeMode', limit: 50 })
1102
- for (const e of cmEntries.entries) {
1103
- if (
1104
- e.content?.includes('Code Mode') &&
1105
- (e.tags?.includes('codemode-test') || e.tags?.includes('codemode-pipeline-test'))
1106
- ) {
1107
- const del = await mj.admin.deleteEntry({ entry_id: e.id, permanent: true })
1108
- results.push({ id: e.id, deleted: del.success })
1109
- }
1110
- }
1111
-
1112
- // Clean up team entries created during Phase 27
1113
- const teamEntries = await mj.team.teamSearch({ query: 'CM4', limit: 50 })
1114
- for (const e of teamEntries.entries ?? []) {
1115
- if (e.content?.includes('CM4')) {
1116
- const del = await mj.team.teamDeleteEntry({ entry_id: e.id })
1117
- results.push({ id: e.id, source: 'team', deleted: del.success })
1118
- }
1119
- }
1120
-
1121
- return { cleaned: results.length, details: results }
1122
- ```
1123
-
1124
- ---
1125
-
1126
- ## Test Execution Order
1127
-
1128
- 1. **Phase 22**: Multi-Step Workflows (read-only pipelines, conditional branching, create+read round-trip)
1129
- 2. **Phase 23**: Cross-Group Orchestration (health dashboard, GitHub-journal coverage, tag analysis, full pipeline)
1130
- 3. **Phase 24**: Relationships & Visualization (all types, duplicates, visualization variants, error paths)
1131
- 4. **Phase 25**: GitHub (16 tools — context, issues, PRs, Kanban, milestones, insights, copilot + cleanup)
1132
- 5. **Phase 26**: Admin, Backup & Export (tags, merge, export filters, backup lifecycle)
1133
- 6. **Phase 27**: Team + Error Paths (20 team tools CRUD, admin, analytics, vector, insights, relationships, export, backup, cross-tool error propagation)
1134
-
1135
- ---
1136
-
1137
- ## Success Criteria
1138
-
1139
- ### Multi-Step Workflows (Phase 22)
1140
-
1141
- - [ ] Chaining 2+ API calls in single execution works
1142
- - [ ] Data transformation (map, flatMap, sort, reduce) works on results
1143
- - [ ] Conditional branching based on query results works
1144
- - [ ] Create + read round-trip produces matching data
1145
- - [ ] Create + search finds the created entry
1146
-
1147
- ### Cross-Group Orchestration (Phase 23)
1148
-
1149
- - [ ] Journal health dashboard aggregates stats + recent + tags correctly
1150
- - [ ] GitHub-journal coverage report iterates issues and searches entries
1151
- - [ ] Tag analysis pipeline processes multiple tags with search per tag
1152
- - [ ] Relationship graph summary checks entries for relationship counts
1153
- - [ ] Full pipeline (create → index → semantic search) completes end-to-end
1154
-
1155
- ### Relationships (Phase 24)
1156
-
1157
- - [ ] All relationship types (`references`, `implements`, `blocked_by`, `resolved`, `caused`) create via Code Mode
1158
- - [ ] `link_entries` with `description` persists the description
1159
- - [ ] Duplicate detection returns `duplicate: true`
1160
- - [ ] Nonexistent IDs return `success: false` with descriptive message
1161
- - [ ] `visualize_relationships` returns Mermaid with legend, supports tags/depth/limit filters
1162
- - [ ] Nonexistent entry ID returns "not found" message
1163
-
1164
- ### GitHub (Phase 25)
1165
-
1166
- - [ ] All 16 GitHub tools callable via `mj.github.*`
1167
- - [ ] `get_github_context` returns repo and branch info
1168
- - [ ] `get_github_issues` and `get_github_prs` support `state` filter (open/closed/all)
1169
- - [ ] Single issue/PR lookups return expected fields
1170
- - [ ] Nonexistent issue/PR/milestone return structured errors
1171
- - [ ] Kanban board returns columns with statusOptions
1172
- - [ ] `move_kanban_item` with invalid status returns error with `availableStatuses`
1173
- - [ ] Issue lifecycle (create → close) works end-to-end via Code Mode
1174
- - [ ] `close_github_issue_with_entry` returns error for already-closed issues
1175
- - [ ] Milestone CRUD lifecycle (create → update → close → delete) works via Code Mode
1176
- - [ ] `get_repo_insights` returns star/fork data
1177
- - [ ] `get_copilot_reviews` returns review state
1178
- - [ ] All test artifacts cleaned up
1179
-
1180
- ### Admin, Backup & Export (Phase 26)
1181
-
1182
- - [ ] `list_tags` returns tag list via Code Mode
1183
- - [ ] `merge_tags` consolidates tags correctly — source removed, target exists
1184
- - [ ] `merge_tags` returns structured errors for same-tag and nonexistent source
1185
- - [ ] `export_entries` JSON and markdown formats work
1186
- - [ ] `export_entries` filters (`tags`, `start_date/end_date`, `entry_types`) produce filtered results
1187
- - [ ] `backup_journal` named and auto-named both succeed
1188
- - [ ] `backup_journal` path traversal blocked with structured error
1189
- - [ ] `list_backups` returns backup metadata
1190
- - [ ] `restore_backup` succeeds with `revertedChanges` field
1191
- - [ ] `restore_backup` nonexistent file returns structured error
1192
- - [ ] `cleanup_backups` deletes old backups
1193
-
1194
- ### Team & Error Paths (Phase 27)
1195
-
1196
- - [ ] `team_create_entry` with auto-detected and explicit `author` works
1197
- - [ ] `team_get_recent` returns entries with `author` field
1198
- - [ ] `team_search` filters by text, tags, and combined
1199
- - [ ] `team_get_entry_by_id` returns entry detail with `importance` and optional `relationships`
1200
- - [ ] `team_list_tags` returns tag list from team database
1201
- - [ ] `team_search_by_date_range` filters by date range, entry_type, and tags
1202
- - [ ] `team_update_entry` updates content, tags, and entry_type
1203
- - [ ] `team_delete_entry` soft-deletes team entries
1204
- - [ ] `team_merge_tags` consolidates tags — source removed, entries re-tagged
1205
- - [ ] `team_get_statistics` returns `totalEntries`, `entriesByType`, `authors`
1206
- - [ ] `team_link_entries` creates relationships with duplicate detection
1207
- - [ ] `team_visualize_relationships` returns Mermaid diagram with node/edge counts
1208
- - [ ] `team_export_entries` exports JSON and markdown with filters
1209
- - [ ] `team_backup` creates named and auto-named backups
1210
- - [ ] `team_list_backups` returns backup metadata
1211
- - [ ] `team_rebuild_vector_index` indexes team entries via Code Mode
1212
- - [ ] `team_get_vector_index_stats` returns vector stats via Code Mode
1213
- - [ ] `team_semantic_search` with threshold filtering works via Code Mode
1214
- - [ ] `team_add_to_vector_index` succeeds for existing, errors for nonexistent via Code Mode
1215
- - [ ] `team_get_cross_project_insights` returns schema-compliant response via Code Mode
1216
- - [ ] Invalid `entry_type` on team create returns structured error
1217
- - [ ] All 18 cross-tool error paths return structured handler errors (not raw throws) through Code Mode
1218
- - [ ] All test entries cleaned up after Phase 27