memory-journal-mcp 4.4.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/.github/workflows/codeql.yml +1 -6
  2. package/.github/workflows/docker-publish.yml +15 -49
  3. package/.github/workflows/lint-and-test.yml +1 -1
  4. package/.github/workflows/secrets-scanning.yml +4 -3
  5. package/.github/workflows/security-update.yml +3 -3
  6. package/CHANGELOG.md +213 -0
  7. package/CONTRIBUTING.md +132 -97
  8. package/DOCKER_README.md +184 -235
  9. package/Dockerfile +27 -24
  10. package/README.md +218 -190
  11. package/SECURITY.md +27 -35
  12. package/dist/cli.js +16 -1
  13. package/dist/cli.js.map +1 -1
  14. package/dist/constants/ServerInstructions.d.ts +5 -1
  15. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  16. package/dist/constants/ServerInstructions.js +133 -73
  17. package/dist/constants/ServerInstructions.js.map +1 -1
  18. package/dist/constants/icons.d.ts +2 -2
  19. package/dist/constants/icons.d.ts.map +1 -1
  20. package/dist/constants/icons.js +7 -6
  21. package/dist/constants/icons.js.map +1 -1
  22. package/dist/database/SqliteAdapter.d.ts +37 -24
  23. package/dist/database/SqliteAdapter.d.ts.map +1 -1
  24. package/dist/database/SqliteAdapter.js +319 -157
  25. package/dist/database/SqliteAdapter.js.map +1 -1
  26. package/dist/database/schema.d.ts +45 -0
  27. package/dist/database/schema.d.ts.map +1 -0
  28. package/dist/database/schema.js +92 -0
  29. package/dist/database/schema.js.map +1 -0
  30. package/dist/filtering/ToolFilter.d.ts +1 -1
  31. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  32. package/dist/filtering/ToolFilter.js +13 -2
  33. package/dist/filtering/ToolFilter.js.map +1 -1
  34. package/dist/github/GitHubIntegration.d.ts.map +1 -1
  35. package/dist/github/GitHubIntegration.js +1 -3
  36. package/dist/github/GitHubIntegration.js.map +1 -1
  37. package/dist/handlers/prompts/github.d.ts +12 -0
  38. package/dist/handlers/prompts/github.d.ts.map +1 -0
  39. package/dist/handlers/prompts/github.js +178 -0
  40. package/dist/handlers/prompts/github.js.map +1 -0
  41. package/dist/handlers/prompts/index.d.ts +23 -2
  42. package/dist/handlers/prompts/index.d.ts.map +1 -1
  43. package/dist/handlers/prompts/index.js +7 -432
  44. package/dist/handlers/prompts/index.js.map +1 -1
  45. package/dist/handlers/prompts/workflow.d.ts +12 -0
  46. package/dist/handlers/prompts/workflow.d.ts.map +1 -0
  47. package/dist/handlers/prompts/workflow.js +277 -0
  48. package/dist/handlers/prompts/workflow.js.map +1 -0
  49. package/dist/handlers/resources/core.d.ts +11 -0
  50. package/dist/handlers/resources/core.d.ts.map +1 -0
  51. package/dist/handlers/resources/core.js +433 -0
  52. package/dist/handlers/resources/core.js.map +1 -0
  53. package/dist/handlers/resources/github.d.ts +11 -0
  54. package/dist/handlers/resources/github.d.ts.map +1 -0
  55. package/dist/handlers/resources/github.js +314 -0
  56. package/dist/handlers/resources/github.js.map +1 -0
  57. package/dist/handlers/resources/graph.d.ts +11 -0
  58. package/dist/handlers/resources/graph.d.ts.map +1 -0
  59. package/dist/handlers/resources/graph.js +204 -0
  60. package/dist/handlers/resources/graph.js.map +1 -0
  61. package/dist/handlers/resources/index.d.ts +5 -20
  62. package/dist/handlers/resources/index.d.ts.map +1 -1
  63. package/dist/handlers/resources/index.js +16 -1278
  64. package/dist/handlers/resources/index.js.map +1 -1
  65. package/dist/handlers/resources/shared.d.ts +60 -0
  66. package/dist/handlers/resources/shared.d.ts.map +1 -0
  67. package/dist/handlers/resources/shared.js +49 -0
  68. package/dist/handlers/resources/shared.js.map +1 -0
  69. package/dist/handlers/resources/team.d.ts +13 -0
  70. package/dist/handlers/resources/team.d.ts.map +1 -0
  71. package/dist/handlers/resources/team.js +119 -0
  72. package/dist/handlers/resources/team.js.map +1 -0
  73. package/dist/handlers/resources/templates.d.ts +13 -0
  74. package/dist/handlers/resources/templates.d.ts.map +1 -0
  75. package/dist/handlers/resources/templates.js +310 -0
  76. package/dist/handlers/resources/templates.js.map +1 -0
  77. package/dist/handlers/tools/admin.d.ts +8 -0
  78. package/dist/handlers/tools/admin.d.ts.map +1 -0
  79. package/dist/handlers/tools/admin.js +270 -0
  80. package/dist/handlers/tools/admin.js.map +1 -0
  81. package/dist/handlers/tools/analytics.d.ts +8 -0
  82. package/dist/handlers/tools/analytics.d.ts.map +1 -0
  83. package/dist/handlers/tools/analytics.js +256 -0
  84. package/dist/handlers/tools/analytics.js.map +1 -0
  85. package/dist/handlers/tools/backup.d.ts +8 -0
  86. package/dist/handlers/tools/backup.d.ts.map +1 -0
  87. package/dist/handlers/tools/backup.js +224 -0
  88. package/dist/handlers/tools/backup.js.map +1 -0
  89. package/dist/handlers/tools/core.d.ts +9 -0
  90. package/dist/handlers/tools/core.d.ts.map +1 -0
  91. package/dist/handlers/tools/core.js +326 -0
  92. package/dist/handlers/tools/core.js.map +1 -0
  93. package/dist/handlers/tools/export.d.ts +8 -0
  94. package/dist/handlers/tools/export.d.ts.map +1 -0
  95. package/dist/handlers/tools/export.js +89 -0
  96. package/dist/handlers/tools/export.js.map +1 -0
  97. package/dist/handlers/tools/github/helpers.d.ts +34 -0
  98. package/dist/handlers/tools/github/helpers.d.ts.map +1 -0
  99. package/dist/handlers/tools/github/helpers.js +52 -0
  100. package/dist/handlers/tools/github/helpers.js.map +1 -0
  101. package/dist/handlers/tools/github/insights-tools.d.ts +8 -0
  102. package/dist/handlers/tools/github/insights-tools.d.ts.map +1 -0
  103. package/dist/handlers/tools/github/insights-tools.js +104 -0
  104. package/dist/handlers/tools/github/insights-tools.js.map +1 -0
  105. package/dist/handlers/tools/github/issue-tools.d.ts +8 -0
  106. package/dist/handlers/tools/github/issue-tools.d.ts.map +1 -0
  107. package/dist/handlers/tools/github/issue-tools.js +359 -0
  108. package/dist/handlers/tools/github/issue-tools.js.map +1 -0
  109. package/dist/handlers/tools/github/kanban-tools.d.ts +8 -0
  110. package/dist/handlers/tools/github/kanban-tools.d.ts.map +1 -0
  111. package/dist/handlers/tools/github/kanban-tools.js +108 -0
  112. package/dist/handlers/tools/github/kanban-tools.js.map +1 -0
  113. package/dist/handlers/tools/github/milestone-tools.d.ts +9 -0
  114. package/dist/handlers/tools/github/milestone-tools.d.ts.map +1 -0
  115. package/dist/handlers/tools/github/milestone-tools.js +302 -0
  116. package/dist/handlers/tools/github/milestone-tools.js.map +1 -0
  117. package/dist/handlers/tools/github/mutation-tools.d.ts +12 -0
  118. package/dist/handlers/tools/github/mutation-tools.d.ts.map +1 -0
  119. package/dist/handlers/tools/github/mutation-tools.js +15 -0
  120. package/dist/handlers/tools/github/mutation-tools.js.map +1 -0
  121. package/dist/handlers/tools/github/read-tools.d.ts +8 -0
  122. package/dist/handlers/tools/github/read-tools.d.ts.map +1 -0
  123. package/dist/handlers/tools/github/read-tools.js +260 -0
  124. package/dist/handlers/tools/github/read-tools.js.map +1 -0
  125. package/dist/handlers/tools/github/schemas.d.ts +467 -0
  126. package/dist/handlers/tools/github/schemas.d.ts.map +1 -0
  127. package/dist/handlers/tools/github/schemas.js +335 -0
  128. package/dist/handlers/tools/github/schemas.js.map +1 -0
  129. package/dist/handlers/tools/github.d.ts +14 -0
  130. package/dist/handlers/tools/github.d.ts.map +1 -0
  131. package/dist/handlers/tools/github.js +28 -0
  132. package/dist/handlers/tools/github.js.map +1 -0
  133. package/dist/handlers/tools/index.d.ts +15 -20
  134. package/dist/handlers/tools/index.d.ts.map +1 -1
  135. package/dist/handlers/tools/index.js +117 -2909
  136. package/dist/handlers/tools/index.js.map +1 -1
  137. package/dist/handlers/tools/relationships.d.ts +8 -0
  138. package/dist/handlers/tools/relationships.d.ts.map +1 -0
  139. package/dist/handlers/tools/relationships.js +308 -0
  140. package/dist/handlers/tools/relationships.js.map +1 -0
  141. package/dist/handlers/tools/schemas.d.ts +108 -0
  142. package/dist/handlers/tools/schemas.d.ts.map +1 -0
  143. package/dist/handlers/tools/schemas.js +122 -0
  144. package/dist/handlers/tools/schemas.js.map +1 -0
  145. package/dist/handlers/tools/search.d.ts +8 -0
  146. package/dist/handlers/tools/search.d.ts.map +1 -0
  147. package/dist/handlers/tools/search.js +282 -0
  148. package/dist/handlers/tools/search.js.map +1 -0
  149. package/dist/handlers/tools/team.d.ts +11 -0
  150. package/dist/handlers/tools/team.d.ts.map +1 -0
  151. package/dist/handlers/tools/team.js +239 -0
  152. package/dist/handlers/tools/team.js.map +1 -0
  153. package/dist/server/McpServer.d.ts +4 -0
  154. package/dist/server/McpServer.d.ts.map +1 -1
  155. package/dist/server/McpServer.js +48 -297
  156. package/dist/server/McpServer.js.map +1 -1
  157. package/dist/server/Scheduler.d.ts +91 -0
  158. package/dist/server/Scheduler.d.ts.map +1 -0
  159. package/dist/server/Scheduler.js +201 -0
  160. package/dist/server/Scheduler.js.map +1 -0
  161. package/dist/transports/http.d.ts +66 -0
  162. package/dist/transports/http.d.ts.map +1 -0
  163. package/dist/transports/http.js +519 -0
  164. package/dist/transports/http.js.map +1 -0
  165. package/dist/types/entities.d.ts +101 -0
  166. package/dist/types/entities.d.ts.map +1 -0
  167. package/dist/types/entities.js +5 -0
  168. package/dist/types/entities.js.map +1 -0
  169. package/dist/types/filtering.d.ts +34 -0
  170. package/dist/types/filtering.d.ts.map +1 -0
  171. package/dist/types/filtering.js +5 -0
  172. package/dist/types/filtering.js.map +1 -0
  173. package/dist/types/github.d.ts +166 -0
  174. package/dist/types/github.d.ts.map +1 -0
  175. package/dist/types/github.js +5 -0
  176. package/dist/types/github.js.map +1 -0
  177. package/dist/types/index.d.ts +35 -292
  178. package/dist/types/index.d.ts.map +1 -1
  179. package/dist/types/index.js +2 -2
  180. package/dist/types/index.js.map +1 -1
  181. package/dist/utils/error-helpers.d.ts +37 -0
  182. package/dist/utils/error-helpers.d.ts.map +1 -0
  183. package/dist/utils/error-helpers.js +47 -0
  184. package/dist/utils/error-helpers.js.map +1 -0
  185. package/dist/utils/logger.d.ts.map +1 -1
  186. package/dist/utils/logger.js +6 -3
  187. package/dist/utils/logger.js.map +1 -1
  188. package/dist/utils/security-utils.d.ts +0 -21
  189. package/dist/utils/security-utils.d.ts.map +1 -1
  190. package/dist/utils/security-utils.js +0 -47
  191. package/dist/utils/security-utils.js.map +1 -1
  192. package/dist/vector/VectorSearchManager.d.ts.map +1 -1
  193. package/dist/vector/VectorSearchManager.js +9 -32
  194. package/dist/vector/VectorSearchManager.js.map +1 -1
  195. package/docker-compose.yml +11 -2
  196. package/hooks/README.md +107 -0
  197. package/hooks/cursor/hooks.json +10 -0
  198. package/hooks/cursor/memory-journal.mdc +22 -0
  199. package/hooks/cursor/session-end.sh +19 -0
  200. package/hooks/kilo-code/session-end-mode.json +11 -0
  201. package/hooks/kiro/session-end.md +13 -0
  202. package/mcp-config-example.json +1 -0
  203. package/package.json +11 -9
  204. package/playwright.config.ts +29 -0
  205. package/releases/v4.5.0.md +116 -0
  206. package/releases/v5.0.0.md +105 -0
  207. package/scripts/generate-server-instructions.ts +176 -0
  208. package/scripts/server-instructions-function-body.ts +77 -0
  209. package/server.json +3 -3
  210. package/src/cli.ts +45 -1
  211. package/src/constants/ServerInstructions.ts +133 -73
  212. package/src/constants/icons.ts +8 -7
  213. package/src/constants/server-instructions.md +268 -0
  214. package/src/database/SqliteAdapter.ts +358 -192
  215. package/src/database/schema.ts +125 -0
  216. package/src/filtering/ToolFilter.ts +13 -2
  217. package/src/github/GitHubIntegration.ts +1 -3
  218. package/src/handlers/prompts/github.ts +209 -0
  219. package/src/handlers/prompts/index.ts +10 -499
  220. package/src/handlers/prompts/workflow.ts +314 -0
  221. package/src/handlers/resources/core.ts +528 -0
  222. package/src/handlers/resources/github.ts +358 -0
  223. package/src/handlers/resources/graph.ts +254 -0
  224. package/src/handlers/resources/index.ts +23 -1570
  225. package/src/handlers/resources/shared.ts +103 -0
  226. package/src/handlers/resources/team.ts +133 -0
  227. package/src/handlers/resources/templates.ts +374 -0
  228. package/src/handlers/tools/admin.ts +285 -0
  229. package/src/handlers/tools/analytics.ts +301 -0
  230. package/src/handlers/tools/backup.ts +242 -0
  231. package/src/handlers/tools/core.ts +350 -0
  232. package/src/handlers/tools/export.ts +115 -0
  233. package/src/handlers/tools/github/helpers.ts +86 -0
  234. package/src/handlers/tools/github/insights-tools.ts +119 -0
  235. package/src/handlers/tools/github/issue-tools.ts +439 -0
  236. package/src/handlers/tools/github/kanban-tools.ts +134 -0
  237. package/src/handlers/tools/github/milestone-tools.ts +392 -0
  238. package/src/handlers/tools/github/mutation-tools.ts +17 -0
  239. package/src/handlers/tools/github/read-tools.ts +328 -0
  240. package/src/handlers/tools/github/schemas.ts +369 -0
  241. package/src/handlers/tools/github.ts +36 -0
  242. package/src/handlers/tools/index.ts +144 -3325
  243. package/src/handlers/tools/relationships.ts +358 -0
  244. package/src/handlers/tools/schemas.ts +132 -0
  245. package/src/handlers/tools/search.ts +343 -0
  246. package/src/handlers/tools/team.ts +273 -0
  247. package/src/server/McpServer.ts +63 -358
  248. package/src/server/Scheduler.ts +278 -0
  249. package/src/transports/http.ts +635 -0
  250. package/src/types/entities.ts +145 -0
  251. package/src/types/filtering.ts +54 -0
  252. package/src/types/github.ts +180 -0
  253. package/src/types/index.ts +67 -375
  254. package/src/utils/error-helpers.ts +52 -0
  255. package/src/utils/logger.ts +6 -3
  256. package/src/utils/security-utils.ts +0 -52
  257. package/src/vector/VectorSearchManager.ts +9 -33
  258. package/tests/constants/icons.test.ts +1 -2
  259. package/tests/constants/server-instructions.test.ts +30 -4
  260. package/tests/database/sqlite-adapter.test.ts +91 -7
  261. package/tests/e2e/auth.spec.ts +154 -0
  262. package/tests/e2e/health.spec.ts +63 -0
  263. package/tests/e2e/protocols.spec.ts +134 -0
  264. package/tests/e2e/resources.spec.ts +103 -0
  265. package/tests/e2e/scheduler.spec.ts +79 -0
  266. package/tests/e2e/security.spec.ts +91 -0
  267. package/tests/e2e/sessions.spec.ts +95 -0
  268. package/tests/e2e/stateless.spec.ts +121 -0
  269. package/tests/e2e/tools.spec.ts +111 -0
  270. package/tests/filtering/tool-filter.test.ts +46 -0
  271. package/tests/handlers/error-path-coverage.test.ts +324 -0
  272. package/tests/handlers/github-resource-handlers.test.ts +453 -0
  273. package/tests/handlers/github-tool-handlers.test.ts +899 -0
  274. package/tests/handlers/prompt-handler-coverage.test.ts +106 -0
  275. package/tests/handlers/prompt-handlers.test.ts +40 -0
  276. package/tests/handlers/resource-handler-coverage.test.ts +181 -0
  277. package/tests/handlers/resource-handlers.test.ts +33 -9
  278. package/tests/handlers/search-tool-handlers.test.ts +272 -0
  279. package/tests/handlers/targeted-gap-closure.test.ts +387 -0
  280. package/tests/handlers/team-resource-handlers.test.ts +156 -0
  281. package/tests/handlers/team-tool-handlers.test.ts +301 -0
  282. package/tests/handlers/tool-handler-coverage.test.ts +469 -0
  283. package/tests/handlers/tool-handlers.test.ts +2 -2
  284. package/tests/security/sql-injection.test.ts +3 -54
  285. package/tests/server/mcp-server.test.ts +503 -8
  286. package/tests/server/scheduler.test.ts +400 -0
  287. package/tests/transports/http-transport.test.ts +620 -0
  288. package/tests/vector/vector-search-manager.test.ts +60 -0
  289. package/vitest.config.ts +4 -1
  290. package/.memory-journal-team.db +0 -0
  291. package/.vscode/settings.json +0 -84
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Team Tool Handler Tests
3
+ *
4
+ * Tests the team tool group: team_create_entry, team_get_recent, team_search,
5
+ * and the share_with_team shorthand on create_entry.
6
+ */
7
+
8
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest'
9
+ import { callTool } from '../../src/handlers/tools/index.js'
10
+ import { SqliteAdapter } from '../../src/database/SqliteAdapter.js'
11
+
12
+ describe('Team Tool Handlers', () => {
13
+ let personalDb: SqliteAdapter
14
+ let teamDb: SqliteAdapter
15
+ const personalDbPath = './test-team-tools-personal.db'
16
+ const teamDbPath = './test-team-tools-team.db'
17
+
18
+ beforeAll(async () => {
19
+ personalDb = new SqliteAdapter(personalDbPath)
20
+ await personalDb.initialize()
21
+
22
+ teamDb = new SqliteAdapter(teamDbPath)
23
+ await teamDb.initialize()
24
+ teamDb.applyTeamSchema()
25
+ })
26
+
27
+ afterAll(() => {
28
+ personalDb.close()
29
+ teamDb.close()
30
+ try {
31
+ const fs = require('node:fs')
32
+ if (fs.existsSync(personalDbPath)) fs.unlinkSync(personalDbPath)
33
+ if (fs.existsSync(teamDbPath)) fs.unlinkSync(teamDbPath)
34
+ } catch {
35
+ // Ignore cleanup errors
36
+ }
37
+ })
38
+
39
+ // ========================================================================
40
+ // team_create_entry
41
+ // ========================================================================
42
+
43
+ describe('team_create_entry', () => {
44
+ it('should create team entry with auto-detected author', async () => {
45
+ const result = (await callTool(
46
+ 'team_create_entry',
47
+ { content: 'Team entry alpha' },
48
+ personalDb,
49
+ undefined,
50
+ undefined,
51
+ undefined,
52
+ undefined,
53
+ teamDb
54
+ )) as { success: boolean; entry: { content: string }; author: string }
55
+
56
+ expect(result.success).toBe(true)
57
+ expect(result.entry.content).toBe('Team entry alpha')
58
+ expect(result.author).toBeDefined()
59
+ expect(typeof result.author).toBe('string')
60
+ })
61
+
62
+ it('should use explicit author when provided', async () => {
63
+ const result = (await callTool(
64
+ 'team_create_entry',
65
+ { content: 'Entry by Alice', author: 'Alice' },
66
+ personalDb,
67
+ undefined,
68
+ undefined,
69
+ undefined,
70
+ undefined,
71
+ teamDb
72
+ )) as { success: boolean; author: string }
73
+
74
+ expect(result.success).toBe(true)
75
+ expect(result.author).toBe('Alice')
76
+ })
77
+
78
+ it('should support tags and entry_type', async () => {
79
+ const result = (await callTool(
80
+ 'team_create_entry',
81
+ {
82
+ content: 'Tagged team entry',
83
+ entry_type: 'project_decision',
84
+ tags: ['team-tag-1', 'team-tag-2'],
85
+ },
86
+ personalDb,
87
+ undefined,
88
+ undefined,
89
+ undefined,
90
+ undefined,
91
+ teamDb
92
+ )) as { success: boolean; entry: { entryType: string; tags: string[] } }
93
+
94
+ expect(result.success).toBe(true)
95
+ expect(result.entry.entryType).toBe('project_decision')
96
+ expect(result.entry.tags).toContain('team-tag-1')
97
+ })
98
+
99
+ it('should return error when team DB not configured', async () => {
100
+ const result = (await callTool(
101
+ 'team_create_entry',
102
+ { content: 'Should fail' },
103
+ personalDb
104
+ // No teamDb passed
105
+ )) as { success: boolean; error: string }
106
+
107
+ expect(result.success).toBe(false)
108
+ expect(result.error).toContain('Team database not configured')
109
+ })
110
+ })
111
+
112
+ // ========================================================================
113
+ // team_get_recent
114
+ // ========================================================================
115
+
116
+ describe('team_get_recent', () => {
117
+ it('should return recent team entries with author', async () => {
118
+ const result = (await callTool(
119
+ 'team_get_recent',
120
+ { limit: 5 },
121
+ personalDb,
122
+ undefined,
123
+ undefined,
124
+ undefined,
125
+ undefined,
126
+ teamDb
127
+ )) as { entries: { content: string; author: string | null }[]; count: number }
128
+
129
+ expect(result.count).toBeGreaterThan(0)
130
+ // Entries should have author field
131
+ for (const entry of result.entries) {
132
+ expect('author' in entry).toBe(true)
133
+ }
134
+ })
135
+
136
+ it('should respect limit', async () => {
137
+ const result = (await callTool(
138
+ 'team_get_recent',
139
+ { limit: 1 },
140
+ personalDb,
141
+ undefined,
142
+ undefined,
143
+ undefined,
144
+ undefined,
145
+ teamDb
146
+ )) as { entries: unknown[]; count: number }
147
+
148
+ expect(result.count).toBeLessThanOrEqual(1)
149
+ })
150
+
151
+ it('should return error when team DB not configured', async () => {
152
+ const result = (await callTool('team_get_recent', {}, personalDb)) as {
153
+ success: boolean
154
+ error: string
155
+ }
156
+
157
+ expect(result.success).toBe(false)
158
+ expect(result.error).toContain('Team database not configured')
159
+ })
160
+ })
161
+
162
+ // ========================================================================
163
+ // team_search
164
+ // ========================================================================
165
+
166
+ describe('team_search', () => {
167
+ it('should search team entries by query', async () => {
168
+ await callTool(
169
+ 'team_create_entry',
170
+ { content: 'Searchable team xyz987' },
171
+ personalDb,
172
+ undefined,
173
+ undefined,
174
+ undefined,
175
+ undefined,
176
+ teamDb
177
+ )
178
+
179
+ const result = (await callTool(
180
+ 'team_search',
181
+ { query: 'xyz987' },
182
+ personalDb,
183
+ undefined,
184
+ undefined,
185
+ undefined,
186
+ undefined,
187
+ teamDb
188
+ )) as { entries: unknown[]; count: number }
189
+
190
+ expect(result.count).toBeGreaterThan(0)
191
+ })
192
+
193
+ it('should search by tags', async () => {
194
+ await callTool(
195
+ 'team_create_entry',
196
+ { content: 'Tag-searchable entry', tags: ['unique-search-tag'] },
197
+ personalDb,
198
+ undefined,
199
+ undefined,
200
+ undefined,
201
+ undefined,
202
+ teamDb
203
+ )
204
+
205
+ const result = (await callTool(
206
+ 'team_search',
207
+ { tags: ['unique-search-tag'] },
208
+ personalDb,
209
+ undefined,
210
+ undefined,
211
+ undefined,
212
+ undefined,
213
+ teamDb
214
+ )) as { entries: unknown[]; count: number }
215
+
216
+ expect(result.count).toBeGreaterThan(0)
217
+ })
218
+
219
+ it('should return error when team DB not configured', async () => {
220
+ const result = (await callTool('team_search', { query: 'test' }, personalDb)) as {
221
+ success: boolean
222
+ error: string
223
+ }
224
+
225
+ expect(result.success).toBe(false)
226
+ expect(result.error).toContain('Team database not configured')
227
+ })
228
+ })
229
+
230
+ // ========================================================================
231
+ // share_with_team (on create_entry)
232
+ // ========================================================================
233
+
234
+ describe('create_entry - share_with_team', () => {
235
+ it('should share entry to team DB when share_with_team is true', async () => {
236
+ const result = (await callTool(
237
+ 'create_entry',
238
+ { content: 'Shared to team abc123', share_with_team: true },
239
+ personalDb,
240
+ undefined,
241
+ undefined,
242
+ undefined,
243
+ undefined,
244
+ teamDb
245
+ )) as {
246
+ success: boolean
247
+ entry: { content: string }
248
+ sharedWithTeam?: boolean
249
+ author?: string
250
+ }
251
+
252
+ expect(result.success).toBe(true)
253
+ expect(result.sharedWithTeam).toBe(true)
254
+ expect(result.author).toBeDefined()
255
+
256
+ // Verify the entry exists in team DB
257
+ const teamResults = (await callTool(
258
+ 'team_search',
259
+ { query: 'abc123' },
260
+ personalDb,
261
+ undefined,
262
+ undefined,
263
+ undefined,
264
+ undefined,
265
+ teamDb
266
+ )) as { entries: unknown[]; count: number }
267
+
268
+ expect(teamResults.count).toBeGreaterThan(0)
269
+ })
270
+
271
+ it('should not include sharedWithTeam when share_with_team is false', async () => {
272
+ const result = (await callTool(
273
+ 'create_entry',
274
+ { content: 'Not shared to team', share_with_team: false },
275
+ personalDb,
276
+ undefined,
277
+ undefined,
278
+ undefined,
279
+ undefined,
280
+ teamDb
281
+ )) as { success: boolean; sharedWithTeam?: boolean }
282
+
283
+ expect(result.success).toBe(true)
284
+ expect(result.sharedWithTeam).toBeUndefined()
285
+ })
286
+
287
+ it('should still save personal entry even without team DB', async () => {
288
+ const result = (await callTool(
289
+ 'create_entry',
290
+ { content: 'Personal only entry', share_with_team: true },
291
+ personalDb
292
+ // No teamDb — share_with_team is silently ignored
293
+ )) as { success: boolean; entry: { content: string }; sharedWithTeam?: boolean }
294
+
295
+ expect(result.success).toBe(true)
296
+ expect(result.entry.content).toBe('Personal only entry')
297
+ // share_with_team is just silently skipped (no team DB)
298
+ expect(result.sharedWithTeam).toBeUndefined()
299
+ })
300
+ })
301
+ })