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,115 @@
1
+ /**
2
+ * Export Tool Group - 1 tool
3
+ *
4
+ * Tools: export_entries
5
+ */
6
+
7
+ import { z } from 'zod'
8
+ import type { ToolDefinition, ToolContext } from '../../types/index.js'
9
+ import { formatHandlerError } from '../../utils/error-helpers.js'
10
+ import { sendProgress } from '../../utils/progress-utils.js'
11
+ import {
12
+ ENTRY_TYPES,
13
+ DATE_FORMAT_REGEX,
14
+ DATE_FORMAT_MESSAGE,
15
+ EntryOutputSchema,
16
+ } from './schemas.js'
17
+
18
+ // ============================================================================
19
+ // Input Schemas
20
+ // ============================================================================
21
+
22
+ /** Strict schema — used inside handler for structured Zod errors */
23
+ const ExportEntriesSchema = z.object({
24
+ format: z.enum(['json', 'markdown']).optional().default('json'),
25
+ start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
26
+ end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
27
+ entry_types: z.array(z.enum(ENTRY_TYPES)).optional(),
28
+ tags: z.array(z.string()).optional(),
29
+ limit: z
30
+ .number()
31
+ .max(500)
32
+ .optional()
33
+ .default(100)
34
+ .describe('Maximum entries to export (default: 100)'),
35
+ })
36
+
37
+ /** Relaxed schema — passed to SDK inputSchema so Zod errors reach the handler */
38
+ const ExportEntriesSchemaMcp = z.object({
39
+ format: z.string().optional().default('json'),
40
+ start_date: z.string().optional(),
41
+ end_date: z.string().optional(),
42
+ entry_types: z.array(z.string()).optional(),
43
+ tags: z.array(z.string()).optional(),
44
+ limit: z
45
+ .number()
46
+ .max(500)
47
+ .optional()
48
+ .default(100)
49
+ .describe('Maximum entries to export (default: 100)'),
50
+ })
51
+
52
+ // ============================================================================
53
+ // Output Schemas
54
+ // ============================================================================
55
+
56
+ const ExportEntriesOutputSchema = z.object({
57
+ format: z.enum(['json', 'markdown']).optional(),
58
+ entries: z.array(EntryOutputSchema).optional(),
59
+ content: z.string().optional(),
60
+ success: z.boolean().optional(),
61
+ error: z.string().optional(),
62
+ })
63
+
64
+ // ============================================================================
65
+ // Tool Definitions
66
+ // ============================================================================
67
+
68
+ export function getExportTools(context: ToolContext): ToolDefinition[] {
69
+ const { db, progress } = context
70
+ return [
71
+ {
72
+ name: 'export_entries',
73
+ title: 'Export Entries',
74
+ description: 'Export journal entries to JSON or Markdown format',
75
+ group: 'export',
76
+ inputSchema: ExportEntriesSchemaMcp,
77
+ outputSchema: ExportEntriesOutputSchema,
78
+ annotations: { readOnlyHint: true, idempotentHint: true },
79
+ handler: async (params: unknown) => {
80
+ try {
81
+ const input = ExportEntriesSchema.parse(params)
82
+ const limit = input.limit ?? 100
83
+
84
+ await sendProgress(progress, 0, 2, 'Fetching entries...')
85
+
86
+ const entries = db.getRecentEntries(limit)
87
+
88
+ await sendProgress(
89
+ progress,
90
+ 1,
91
+ 2,
92
+ `Processing ${String(entries.length)} entries...`
93
+ )
94
+
95
+ if (input.format === 'markdown') {
96
+ const md = entries
97
+ .map(
98
+ (e) =>
99
+ `## ${e.timestamp}\n\n**Type:** ${e.entryType}\n\n${e.content}\n\n---`
100
+ )
101
+ .join('\n\n')
102
+
103
+ await sendProgress(progress, 2, 2, 'Export complete')
104
+ return { format: 'markdown', content: md }
105
+ }
106
+
107
+ await sendProgress(progress, 2, 2, 'Export complete')
108
+ return { format: 'json', entries }
109
+ } catch (err) {
110
+ return formatHandlerError(err)
111
+ }
112
+ },
113
+ },
114
+ ]
115
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * GitHub Tool Helpers - Shared owner/repo resolution
3
+ */
4
+
5
+ import type { ToolContext } from '../../../types/index.js'
6
+ import type { GitHubIntegration } from '../../../github/GitHubIntegration.js'
7
+
8
+ /**
9
+ * Resolve owner (owner-only, no repo required)
10
+ */
11
+ export async function resolveOwner(
12
+ context: ToolContext,
13
+ inputOwner?: string
14
+ ): Promise<
15
+ | {
16
+ owner: string
17
+ detectedOwner: string | null
18
+ repo: string | undefined
19
+ github: GitHubIntegration
20
+ }
21
+ | { error: true; response: Record<string, unknown> }
22
+ > {
23
+ if (!context.github) {
24
+ return { error: true, response: { error: 'GitHub integration not available' } }
25
+ }
26
+
27
+ const repoInfo = await context.github.getRepoInfo()
28
+ const detectedOwner = repoInfo.owner
29
+ const owner = inputOwner ?? detectedOwner ?? undefined
30
+ const repo = repoInfo.repo ?? undefined
31
+
32
+ if (!owner) {
33
+ return {
34
+ error: true,
35
+ response: {
36
+ error: 'STOP: Could not auto-detect repository owner. DO NOT GUESS. You MUST ask the user to provide the GitHub owner.',
37
+ requiresUserInput: true,
38
+ detectedOwner,
39
+ instruction:
40
+ 'Ask the user: "What GitHub username or organization owns this project?"',
41
+ },
42
+ }
43
+ }
44
+
45
+ return { owner, detectedOwner, repo, github: context.github }
46
+ }
47
+
48
+ /**
49
+ * Resolve owner + repo (both required)
50
+ */
51
+ export async function resolveOwnerRepo(
52
+ context: ToolContext,
53
+ input: { owner?: string; repo?: string }
54
+ ): Promise<
55
+ | {
56
+ owner: string
57
+ repo: string
58
+ detectedOwner: string | null
59
+ detectedRepo: string | null
60
+ github: GitHubIntegration
61
+ }
62
+ | { error: true; response: Record<string, unknown> }
63
+ > {
64
+ if (!context.github) {
65
+ return { error: true, response: { error: 'GitHub integration not available' } }
66
+ }
67
+
68
+ const repoInfo = await context.github.getRepoInfo()
69
+ const detectedOwner = repoInfo.owner
70
+ const detectedRepo = repoInfo.repo
71
+ const owner = input.owner ?? detectedOwner ?? undefined
72
+ const repo = input.repo ?? detectedRepo ?? undefined
73
+
74
+ if (!owner || !repo) {
75
+ return {
76
+ error: true,
77
+ response: {
78
+ error: 'STOP: Could not auto-detect repository. DO NOT GUESS.',
79
+ requiresUserInput: true,
80
+ detected: { owner, repo },
81
+ },
82
+ }
83
+ }
84
+
85
+ return { owner, repo, detectedOwner, detectedRepo, github: context.github }
86
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * GitHub Insights Tools - 1 tool
3
+ *
4
+ * Tools: get_repo_insights
5
+ */
6
+
7
+ import { z } from 'zod'
8
+ import type { ToolDefinition, ToolContext } from '../../../types/index.js'
9
+ import { formatHandlerError } from '../../../utils/error-helpers.js'
10
+ import { RepoInsightsOutputSchema } from './schemas.js'
11
+
12
+ // ============================================================================
13
+ // Tool Definitions
14
+ // ============================================================================
15
+
16
+ export function getGitHubInsightsTools(context: ToolContext): ToolDefinition[] {
17
+ return [
18
+ {
19
+ name: 'get_repo_insights',
20
+ title: 'Repository Insights',
21
+ description:
22
+ 'Get repository insights: stars, forks, traffic (clones/views), referrers, and popular paths. Use "sections" to control token usage: stars (~50 tokens), traffic (~100), referrers (~100), paths (~100), or all (~350).',
23
+ group: 'github',
24
+ inputSchema: z.object({
25
+ sections: z
26
+ .enum(['stars', 'traffic', 'referrers', 'paths', 'all'])
27
+ .optional()
28
+ .default('stars')
29
+ .describe(
30
+ 'Data section to return (default: stars). Use "all" for full payload.'
31
+ ),
32
+ owner: z
33
+ .string()
34
+ .optional()
35
+ .describe('Repository owner - LEAVE EMPTY to auto-detect'),
36
+ repo: z
37
+ .string()
38
+ .optional()
39
+ .describe('Repository name - LEAVE EMPTY to auto-detect'),
40
+ }),
41
+ outputSchema: RepoInsightsOutputSchema,
42
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
43
+ handler: async (params: unknown) => {
44
+ try {
45
+ const input = z
46
+ .object({
47
+ sections: z
48
+ .enum(['stars', 'traffic', 'referrers', 'paths', 'all'])
49
+ .optional()
50
+ .default('stars'),
51
+ owner: z.string().optional(),
52
+ repo: z.string().optional(),
53
+ })
54
+ .parse(params)
55
+
56
+ if (!context.github) {
57
+ return { error: 'GitHub integration not available' }
58
+ }
59
+
60
+ const repoInfo = await context.github.getRepoInfo()
61
+ const owner = input.owner ?? repoInfo.owner ?? undefined
62
+ const repo = input.repo ?? repoInfo.repo ?? undefined
63
+
64
+ if (!owner || !repo) {
65
+ return {
66
+ error: 'STOP: Could not auto-detect repository. DO NOT GUESS. You MUST ask the user to provide the GitHub owner and repository name.',
67
+ requiresUserInput: true,
68
+ instruction:
69
+ 'Ask the user: "What GitHub repository should I get insights for? Please provide the owner and repo name (e.g., owner/repo)."',
70
+ }
71
+ }
72
+
73
+ const section = input.sections
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- building response dynamically
75
+ const result: Record<string, any> = {
76
+ owner,
77
+ repo,
78
+ section,
79
+ }
80
+
81
+ if (section === 'stars' || section === 'all') {
82
+ const stats = await context.github.getRepoStats(owner, repo)
83
+ if (stats) {
84
+ result['stars'] = stats.stars
85
+ result['forks'] = stats.forks
86
+ result['watchers'] = stats.watchers
87
+ result['openIssues'] = stats.openIssues
88
+ if (section === 'all') {
89
+ result['size'] = stats.size
90
+ result['defaultBranch'] = stats.defaultBranch
91
+ }
92
+ }
93
+ }
94
+
95
+ if (section === 'traffic' || section === 'all') {
96
+ const traffic = await context.github.getTrafficData(owner, repo)
97
+ if (traffic) {
98
+ result['traffic'] = traffic
99
+ }
100
+ }
101
+
102
+ if (section === 'referrers' || section === 'all') {
103
+ const referrers = await context.github.getTopReferrers(owner, repo, 5)
104
+ result['referrers'] = referrers
105
+ }
106
+
107
+ if (section === 'paths' || section === 'all') {
108
+ const paths = await context.github.getPopularPaths(owner, repo, 5)
109
+ result['paths'] = paths
110
+ }
111
+
112
+ return result
113
+ } catch (err) {
114
+ return formatHandlerError(err)
115
+ }
116
+ },
117
+ },
118
+ ]
119
+ }