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.
- package/.github/workflows/codeql.yml +1 -6
- package/.github/workflows/docker-publish.yml +15 -49
- package/.github/workflows/lint-and-test.yml +1 -1
- package/.github/workflows/secrets-scanning.yml +4 -3
- package/.github/workflows/security-update.yml +3 -3
- package/CHANGELOG.md +213 -0
- package/CONTRIBUTING.md +132 -97
- package/DOCKER_README.md +184 -235
- package/Dockerfile +27 -24
- package/README.md +218 -190
- package/SECURITY.md +27 -35
- package/dist/cli.js +16 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts +5 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +133 -73
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/constants/icons.d.ts +2 -2
- package/dist/constants/icons.d.ts.map +1 -1
- package/dist/constants/icons.js +7 -6
- package/dist/constants/icons.js.map +1 -1
- package/dist/database/SqliteAdapter.d.ts +37 -24
- package/dist/database/SqliteAdapter.d.ts.map +1 -1
- package/dist/database/SqliteAdapter.js +319 -157
- package/dist/database/SqliteAdapter.js.map +1 -1
- package/dist/database/schema.d.ts +45 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +92 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/filtering/ToolFilter.d.ts +1 -1
- package/dist/filtering/ToolFilter.d.ts.map +1 -1
- package/dist/filtering/ToolFilter.js +13 -2
- package/dist/filtering/ToolFilter.js.map +1 -1
- package/dist/github/GitHubIntegration.d.ts.map +1 -1
- package/dist/github/GitHubIntegration.js +1 -3
- package/dist/github/GitHubIntegration.js.map +1 -1
- package/dist/handlers/prompts/github.d.ts +12 -0
- package/dist/handlers/prompts/github.d.ts.map +1 -0
- package/dist/handlers/prompts/github.js +178 -0
- package/dist/handlers/prompts/github.js.map +1 -0
- package/dist/handlers/prompts/index.d.ts +23 -2
- package/dist/handlers/prompts/index.d.ts.map +1 -1
- package/dist/handlers/prompts/index.js +7 -432
- package/dist/handlers/prompts/index.js.map +1 -1
- package/dist/handlers/prompts/workflow.d.ts +12 -0
- package/dist/handlers/prompts/workflow.d.ts.map +1 -0
- package/dist/handlers/prompts/workflow.js +277 -0
- package/dist/handlers/prompts/workflow.js.map +1 -0
- package/dist/handlers/resources/core.d.ts +11 -0
- package/dist/handlers/resources/core.d.ts.map +1 -0
- package/dist/handlers/resources/core.js +433 -0
- package/dist/handlers/resources/core.js.map +1 -0
- package/dist/handlers/resources/github.d.ts +11 -0
- package/dist/handlers/resources/github.d.ts.map +1 -0
- package/dist/handlers/resources/github.js +314 -0
- package/dist/handlers/resources/github.js.map +1 -0
- package/dist/handlers/resources/graph.d.ts +11 -0
- package/dist/handlers/resources/graph.d.ts.map +1 -0
- package/dist/handlers/resources/graph.js +204 -0
- package/dist/handlers/resources/graph.js.map +1 -0
- package/dist/handlers/resources/index.d.ts +5 -20
- package/dist/handlers/resources/index.d.ts.map +1 -1
- package/dist/handlers/resources/index.js +16 -1278
- package/dist/handlers/resources/index.js.map +1 -1
- package/dist/handlers/resources/shared.d.ts +60 -0
- package/dist/handlers/resources/shared.d.ts.map +1 -0
- package/dist/handlers/resources/shared.js +49 -0
- package/dist/handlers/resources/shared.js.map +1 -0
- package/dist/handlers/resources/team.d.ts +13 -0
- package/dist/handlers/resources/team.d.ts.map +1 -0
- package/dist/handlers/resources/team.js +119 -0
- package/dist/handlers/resources/team.js.map +1 -0
- package/dist/handlers/resources/templates.d.ts +13 -0
- package/dist/handlers/resources/templates.d.ts.map +1 -0
- package/dist/handlers/resources/templates.js +310 -0
- package/dist/handlers/resources/templates.js.map +1 -0
- package/dist/handlers/tools/admin.d.ts +8 -0
- package/dist/handlers/tools/admin.d.ts.map +1 -0
- package/dist/handlers/tools/admin.js +270 -0
- package/dist/handlers/tools/admin.js.map +1 -0
- package/dist/handlers/tools/analytics.d.ts +8 -0
- package/dist/handlers/tools/analytics.d.ts.map +1 -0
- package/dist/handlers/tools/analytics.js +256 -0
- package/dist/handlers/tools/analytics.js.map +1 -0
- package/dist/handlers/tools/backup.d.ts +8 -0
- package/dist/handlers/tools/backup.d.ts.map +1 -0
- package/dist/handlers/tools/backup.js +224 -0
- package/dist/handlers/tools/backup.js.map +1 -0
- package/dist/handlers/tools/core.d.ts +9 -0
- package/dist/handlers/tools/core.d.ts.map +1 -0
- package/dist/handlers/tools/core.js +326 -0
- package/dist/handlers/tools/core.js.map +1 -0
- package/dist/handlers/tools/export.d.ts +8 -0
- package/dist/handlers/tools/export.d.ts.map +1 -0
- package/dist/handlers/tools/export.js +89 -0
- package/dist/handlers/tools/export.js.map +1 -0
- package/dist/handlers/tools/github/helpers.d.ts +34 -0
- package/dist/handlers/tools/github/helpers.d.ts.map +1 -0
- package/dist/handlers/tools/github/helpers.js +52 -0
- package/dist/handlers/tools/github/helpers.js.map +1 -0
- package/dist/handlers/tools/github/insights-tools.d.ts +8 -0
- package/dist/handlers/tools/github/insights-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/insights-tools.js +104 -0
- package/dist/handlers/tools/github/insights-tools.js.map +1 -0
- package/dist/handlers/tools/github/issue-tools.d.ts +8 -0
- package/dist/handlers/tools/github/issue-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/issue-tools.js +359 -0
- package/dist/handlers/tools/github/issue-tools.js.map +1 -0
- package/dist/handlers/tools/github/kanban-tools.d.ts +8 -0
- package/dist/handlers/tools/github/kanban-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/kanban-tools.js +108 -0
- package/dist/handlers/tools/github/kanban-tools.js.map +1 -0
- package/dist/handlers/tools/github/milestone-tools.d.ts +9 -0
- package/dist/handlers/tools/github/milestone-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/milestone-tools.js +302 -0
- package/dist/handlers/tools/github/milestone-tools.js.map +1 -0
- package/dist/handlers/tools/github/mutation-tools.d.ts +12 -0
- package/dist/handlers/tools/github/mutation-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/mutation-tools.js +15 -0
- package/dist/handlers/tools/github/mutation-tools.js.map +1 -0
- package/dist/handlers/tools/github/read-tools.d.ts +8 -0
- package/dist/handlers/tools/github/read-tools.d.ts.map +1 -0
- package/dist/handlers/tools/github/read-tools.js +260 -0
- package/dist/handlers/tools/github/read-tools.js.map +1 -0
- package/dist/handlers/tools/github/schemas.d.ts +467 -0
- package/dist/handlers/tools/github/schemas.d.ts.map +1 -0
- package/dist/handlers/tools/github/schemas.js +335 -0
- package/dist/handlers/tools/github/schemas.js.map +1 -0
- package/dist/handlers/tools/github.d.ts +14 -0
- package/dist/handlers/tools/github.d.ts.map +1 -0
- package/dist/handlers/tools/github.js +28 -0
- package/dist/handlers/tools/github.js.map +1 -0
- package/dist/handlers/tools/index.d.ts +15 -20
- package/dist/handlers/tools/index.d.ts.map +1 -1
- package/dist/handlers/tools/index.js +117 -2909
- package/dist/handlers/tools/index.js.map +1 -1
- package/dist/handlers/tools/relationships.d.ts +8 -0
- package/dist/handlers/tools/relationships.d.ts.map +1 -0
- package/dist/handlers/tools/relationships.js +308 -0
- package/dist/handlers/tools/relationships.js.map +1 -0
- package/dist/handlers/tools/schemas.d.ts +108 -0
- package/dist/handlers/tools/schemas.d.ts.map +1 -0
- package/dist/handlers/tools/schemas.js +122 -0
- package/dist/handlers/tools/schemas.js.map +1 -0
- package/dist/handlers/tools/search.d.ts +8 -0
- package/dist/handlers/tools/search.d.ts.map +1 -0
- package/dist/handlers/tools/search.js +282 -0
- package/dist/handlers/tools/search.js.map +1 -0
- package/dist/handlers/tools/team.d.ts +11 -0
- package/dist/handlers/tools/team.d.ts.map +1 -0
- package/dist/handlers/tools/team.js +239 -0
- package/dist/handlers/tools/team.js.map +1 -0
- package/dist/server/McpServer.d.ts +4 -0
- package/dist/server/McpServer.d.ts.map +1 -1
- package/dist/server/McpServer.js +48 -297
- package/dist/server/McpServer.js.map +1 -1
- package/dist/server/Scheduler.d.ts +91 -0
- package/dist/server/Scheduler.d.ts.map +1 -0
- package/dist/server/Scheduler.js +201 -0
- package/dist/server/Scheduler.js.map +1 -0
- package/dist/transports/http.d.ts +66 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +519 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/types/entities.d.ts +101 -0
- package/dist/types/entities.d.ts.map +1 -0
- package/dist/types/entities.js +5 -0
- package/dist/types/entities.js.map +1 -0
- package/dist/types/filtering.d.ts +34 -0
- package/dist/types/filtering.d.ts.map +1 -0
- package/dist/types/filtering.js +5 -0
- package/dist/types/filtering.js.map +1 -0
- package/dist/types/github.d.ts +166 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/github.js +5 -0
- package/dist/types/github.js.map +1 -0
- package/dist/types/index.d.ts +35 -292
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/error-helpers.d.ts +37 -0
- package/dist/utils/error-helpers.d.ts.map +1 -0
- package/dist/utils/error-helpers.js +47 -0
- package/dist/utils/error-helpers.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +6 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/security-utils.d.ts +0 -21
- package/dist/utils/security-utils.d.ts.map +1 -1
- package/dist/utils/security-utils.js +0 -47
- package/dist/utils/security-utils.js.map +1 -1
- package/dist/vector/VectorSearchManager.d.ts.map +1 -1
- package/dist/vector/VectorSearchManager.js +9 -32
- package/dist/vector/VectorSearchManager.js.map +1 -1
- package/docker-compose.yml +11 -2
- package/hooks/README.md +107 -0
- package/hooks/cursor/hooks.json +10 -0
- package/hooks/cursor/memory-journal.mdc +22 -0
- package/hooks/cursor/session-end.sh +19 -0
- package/hooks/kilo-code/session-end-mode.json +11 -0
- package/hooks/kiro/session-end.md +13 -0
- package/mcp-config-example.json +1 -0
- package/package.json +11 -9
- package/playwright.config.ts +29 -0
- package/releases/v4.5.0.md +116 -0
- package/releases/v5.0.0.md +105 -0
- package/scripts/generate-server-instructions.ts +176 -0
- package/scripts/server-instructions-function-body.ts +77 -0
- package/server.json +3 -3
- package/src/cli.ts +45 -1
- package/src/constants/ServerInstructions.ts +133 -73
- package/src/constants/icons.ts +8 -7
- package/src/constants/server-instructions.md +268 -0
- package/src/database/SqliteAdapter.ts +358 -192
- package/src/database/schema.ts +125 -0
- package/src/filtering/ToolFilter.ts +13 -2
- package/src/github/GitHubIntegration.ts +1 -3
- package/src/handlers/prompts/github.ts +209 -0
- package/src/handlers/prompts/index.ts +10 -499
- package/src/handlers/prompts/workflow.ts +314 -0
- package/src/handlers/resources/core.ts +528 -0
- package/src/handlers/resources/github.ts +358 -0
- package/src/handlers/resources/graph.ts +254 -0
- package/src/handlers/resources/index.ts +23 -1570
- package/src/handlers/resources/shared.ts +103 -0
- package/src/handlers/resources/team.ts +133 -0
- package/src/handlers/resources/templates.ts +374 -0
- package/src/handlers/tools/admin.ts +285 -0
- package/src/handlers/tools/analytics.ts +301 -0
- package/src/handlers/tools/backup.ts +242 -0
- package/src/handlers/tools/core.ts +350 -0
- package/src/handlers/tools/export.ts +115 -0
- package/src/handlers/tools/github/helpers.ts +86 -0
- package/src/handlers/tools/github/insights-tools.ts +119 -0
- package/src/handlers/tools/github/issue-tools.ts +439 -0
- package/src/handlers/tools/github/kanban-tools.ts +134 -0
- package/src/handlers/tools/github/milestone-tools.ts +392 -0
- package/src/handlers/tools/github/mutation-tools.ts +17 -0
- package/src/handlers/tools/github/read-tools.ts +328 -0
- package/src/handlers/tools/github/schemas.ts +369 -0
- package/src/handlers/tools/github.ts +36 -0
- package/src/handlers/tools/index.ts +144 -3325
- package/src/handlers/tools/relationships.ts +358 -0
- package/src/handlers/tools/schemas.ts +132 -0
- package/src/handlers/tools/search.ts +343 -0
- package/src/handlers/tools/team.ts +273 -0
- package/src/server/McpServer.ts +63 -358
- package/src/server/Scheduler.ts +278 -0
- package/src/transports/http.ts +635 -0
- package/src/types/entities.ts +145 -0
- package/src/types/filtering.ts +54 -0
- package/src/types/github.ts +180 -0
- package/src/types/index.ts +67 -375
- package/src/utils/error-helpers.ts +52 -0
- package/src/utils/logger.ts +6 -3
- package/src/utils/security-utils.ts +0 -52
- package/src/vector/VectorSearchManager.ts +9 -33
- package/tests/constants/icons.test.ts +1 -2
- package/tests/constants/server-instructions.test.ts +30 -4
- package/tests/database/sqlite-adapter.test.ts +91 -7
- package/tests/e2e/auth.spec.ts +154 -0
- package/tests/e2e/health.spec.ts +63 -0
- package/tests/e2e/protocols.spec.ts +134 -0
- package/tests/e2e/resources.spec.ts +103 -0
- package/tests/e2e/scheduler.spec.ts +79 -0
- package/tests/e2e/security.spec.ts +91 -0
- package/tests/e2e/sessions.spec.ts +95 -0
- package/tests/e2e/stateless.spec.ts +121 -0
- package/tests/e2e/tools.spec.ts +111 -0
- package/tests/filtering/tool-filter.test.ts +46 -0
- package/tests/handlers/error-path-coverage.test.ts +324 -0
- package/tests/handlers/github-resource-handlers.test.ts +453 -0
- package/tests/handlers/github-tool-handlers.test.ts +899 -0
- package/tests/handlers/prompt-handler-coverage.test.ts +106 -0
- package/tests/handlers/prompt-handlers.test.ts +40 -0
- package/tests/handlers/resource-handler-coverage.test.ts +181 -0
- package/tests/handlers/resource-handlers.test.ts +33 -9
- package/tests/handlers/search-tool-handlers.test.ts +272 -0
- package/tests/handlers/targeted-gap-closure.test.ts +387 -0
- package/tests/handlers/team-resource-handlers.test.ts +156 -0
- package/tests/handlers/team-tool-handlers.test.ts +301 -0
- package/tests/handlers/tool-handler-coverage.test.ts +469 -0
- package/tests/handlers/tool-handlers.test.ts +2 -2
- package/tests/security/sql-injection.test.ts +3 -54
- package/tests/server/mcp-server.test.ts +503 -8
- package/tests/server/scheduler.test.ts +400 -0
- package/tests/transports/http-transport.test.ts +620 -0
- package/tests/vector/vector-search-manager.test.ts +60 -0
- package/vitest.config.ts +4 -1
- package/.memory-journal-team.db +0 -0
- package/.vscode/settings.json +0 -84
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Milestone Tools - 5 tools
|
|
3
|
+
*
|
|
4
|
+
* Tools: get_github_milestones, get_github_milestone,
|
|
5
|
+
* create_github_milestone, update_github_milestone, delete_github_milestone
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { z } from 'zod'
|
|
9
|
+
import type { ToolDefinition, ToolContext } from '../../../types/index.js'
|
|
10
|
+
import type { GitHubIntegration } from '../../../github/GitHubIntegration.js'
|
|
11
|
+
import { formatHandlerError } from '../../../utils/error-helpers.js'
|
|
12
|
+
import {
|
|
13
|
+
GitHubMilestonesListOutputSchema,
|
|
14
|
+
GitHubMilestoneResultOutputSchema,
|
|
15
|
+
CreateMilestoneOutputSchema,
|
|
16
|
+
UpdateMilestoneOutputSchema,
|
|
17
|
+
DeleteMilestoneOutputSchema,
|
|
18
|
+
} from './schemas.js'
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Helper: owner/repo resolution
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
async function resolveOwnerRepo(
|
|
25
|
+
context: ToolContext,
|
|
26
|
+
input: { owner?: string; repo?: string },
|
|
27
|
+
entityLabel: string
|
|
28
|
+
): Promise<
|
|
29
|
+
| {
|
|
30
|
+
owner: string
|
|
31
|
+
repo: string
|
|
32
|
+
detectedOwner: string | null
|
|
33
|
+
detectedRepo: string | null
|
|
34
|
+
github: GitHubIntegration
|
|
35
|
+
}
|
|
36
|
+
| { error: true; response: Record<string, unknown> }
|
|
37
|
+
> {
|
|
38
|
+
if (!context.github) {
|
|
39
|
+
return { error: true, response: { error: 'GitHub integration not available' } }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const repoInfo = await context.github.getRepoInfo()
|
|
43
|
+
const detectedOwner = repoInfo.owner
|
|
44
|
+
const detectedRepo = repoInfo.repo
|
|
45
|
+
const owner = input.owner ?? detectedOwner ?? undefined
|
|
46
|
+
const repo = input.repo ?? detectedRepo ?? undefined
|
|
47
|
+
|
|
48
|
+
if (!owner || !repo) {
|
|
49
|
+
return {
|
|
50
|
+
error: true,
|
|
51
|
+
response: {
|
|
52
|
+
error: 'STOP: Could not auto-detect repository. DO NOT GUESS. You MUST ask the user to provide the GitHub owner and repository name.',
|
|
53
|
+
requiresUserInput: true,
|
|
54
|
+
detectedOwner,
|
|
55
|
+
detectedRepo,
|
|
56
|
+
instruction: `Ask the user: "${entityLabel}"`,
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { owner, repo, detectedOwner, detectedRepo, github: context.github }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Tool Definitions
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
export function getGitHubMilestoneTools(context: ToolContext): ToolDefinition[] {
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
name: 'get_github_milestones',
|
|
72
|
+
title: 'List GitHub Milestones',
|
|
73
|
+
description:
|
|
74
|
+
'List GitHub milestones for the repository with completion percentages and due dates.',
|
|
75
|
+
group: 'github',
|
|
76
|
+
inputSchema: z.object({
|
|
77
|
+
state: z
|
|
78
|
+
.string()
|
|
79
|
+
.optional()
|
|
80
|
+
.default('open')
|
|
81
|
+
.describe('Filter by state (default: open)'),
|
|
82
|
+
limit: z
|
|
83
|
+
.number()
|
|
84
|
+
.optional()
|
|
85
|
+
.default(20)
|
|
86
|
+
.describe('Max milestones to return (default: 20)'),
|
|
87
|
+
owner: z.string().optional().describe('LEAVE EMPTY to auto-detect from git'),
|
|
88
|
+
repo: z.string().optional().describe('LEAVE EMPTY to auto-detect from git'),
|
|
89
|
+
}),
|
|
90
|
+
outputSchema: GitHubMilestonesListOutputSchema,
|
|
91
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
92
|
+
handler: async (params: unknown) => {
|
|
93
|
+
try {
|
|
94
|
+
const input = z
|
|
95
|
+
.object({
|
|
96
|
+
state: z.enum(['open', 'closed', 'all']).optional().default('open'),
|
|
97
|
+
limit: z.number().optional().default(20),
|
|
98
|
+
owner: z.string().optional(),
|
|
99
|
+
repo: z.string().optional(),
|
|
100
|
+
})
|
|
101
|
+
.parse(params)
|
|
102
|
+
|
|
103
|
+
const resolved = await resolveOwnerRepo(
|
|
104
|
+
context,
|
|
105
|
+
input,
|
|
106
|
+
'What GitHub repository should I list milestones for? Please provide the owner and repo name (e.g., owner/repo).'
|
|
107
|
+
)
|
|
108
|
+
if ('error' in resolved) return resolved.response
|
|
109
|
+
|
|
110
|
+
const milestones = await resolved.github.getMilestones(
|
|
111
|
+
resolved.owner,
|
|
112
|
+
resolved.repo,
|
|
113
|
+
input.state,
|
|
114
|
+
input.limit
|
|
115
|
+
)
|
|
116
|
+
const milestonesWithPercentage = milestones.map((ms) => {
|
|
117
|
+
const total = ms.openIssues + ms.closedIssues
|
|
118
|
+
const completionPercentage =
|
|
119
|
+
total > 0 ? Math.round((ms.closedIssues / total) * 100) : 0
|
|
120
|
+
return { ...ms, completionPercentage }
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
milestones: milestonesWithPercentage,
|
|
125
|
+
count: milestonesWithPercentage.length,
|
|
126
|
+
owner: resolved.owner,
|
|
127
|
+
repo: resolved.repo,
|
|
128
|
+
detectedOwner: resolved.detectedOwner,
|
|
129
|
+
detectedRepo: resolved.detectedRepo,
|
|
130
|
+
}
|
|
131
|
+
} catch (err) {
|
|
132
|
+
return formatHandlerError(err)
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'get_github_milestone',
|
|
138
|
+
title: 'Get GitHub Milestone Details',
|
|
139
|
+
description:
|
|
140
|
+
'Get detailed information about a specific GitHub milestone including progress and linked issue counts.',
|
|
141
|
+
group: 'github',
|
|
142
|
+
inputSchema: z.object({
|
|
143
|
+
milestone_number: z.number().describe('Milestone number'),
|
|
144
|
+
owner: z.string().optional().describe('LEAVE EMPTY to auto-detect from git'),
|
|
145
|
+
repo: z.string().optional().describe('LEAVE EMPTY to auto-detect from git'),
|
|
146
|
+
}),
|
|
147
|
+
outputSchema: GitHubMilestoneResultOutputSchema,
|
|
148
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
149
|
+
handler: async (params: unknown) => {
|
|
150
|
+
try {
|
|
151
|
+
const input = z
|
|
152
|
+
.object({
|
|
153
|
+
milestone_number: z.number(),
|
|
154
|
+
owner: z.string().optional(),
|
|
155
|
+
repo: z.string().optional(),
|
|
156
|
+
})
|
|
157
|
+
.parse(params)
|
|
158
|
+
|
|
159
|
+
const resolved = await resolveOwnerRepo(
|
|
160
|
+
context,
|
|
161
|
+
input,
|
|
162
|
+
'What GitHub repository is this milestone from? Please provide the owner and repo name (e.g., owner/repo).'
|
|
163
|
+
)
|
|
164
|
+
if ('error' in resolved) return resolved.response
|
|
165
|
+
|
|
166
|
+
const milestone = await resolved.github.getMilestone(
|
|
167
|
+
resolved.owner,
|
|
168
|
+
resolved.repo,
|
|
169
|
+
input.milestone_number
|
|
170
|
+
)
|
|
171
|
+
if (!milestone) {
|
|
172
|
+
return {
|
|
173
|
+
error: `Milestone #${String(input.milestone_number)} not found`,
|
|
174
|
+
owner: resolved.owner,
|
|
175
|
+
repo: resolved.repo,
|
|
176
|
+
detectedOwner: resolved.detectedOwner,
|
|
177
|
+
detectedRepo: resolved.detectedRepo,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const total = milestone.openIssues + milestone.closedIssues
|
|
182
|
+
const completionPercentage =
|
|
183
|
+
total > 0 ? Math.round((milestone.closedIssues / total) * 100) : 0
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
milestone: { ...milestone, completionPercentage },
|
|
187
|
+
owner: resolved.owner,
|
|
188
|
+
repo: resolved.repo,
|
|
189
|
+
detectedOwner: resolved.detectedOwner,
|
|
190
|
+
detectedRepo: resolved.detectedRepo,
|
|
191
|
+
}
|
|
192
|
+
} catch (err) {
|
|
193
|
+
return formatHandlerError(err)
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'create_github_milestone',
|
|
199
|
+
title: 'Create GitHub Milestone',
|
|
200
|
+
description:
|
|
201
|
+
'Create a new GitHub milestone for tracking progress toward a project goal.',
|
|
202
|
+
group: 'github',
|
|
203
|
+
inputSchema: z.object({
|
|
204
|
+
title: z.string().min(1).describe('Milestone title'),
|
|
205
|
+
description: z.string().optional().describe('Milestone description'),
|
|
206
|
+
due_on: z.string().optional().describe('Due date in YYYY-MM-DD format (optional)'),
|
|
207
|
+
owner: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
208
|
+
repo: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
209
|
+
}),
|
|
210
|
+
outputSchema: CreateMilestoneOutputSchema,
|
|
211
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: true },
|
|
212
|
+
handler: async (params: unknown) => {
|
|
213
|
+
try {
|
|
214
|
+
const input = z
|
|
215
|
+
.object({
|
|
216
|
+
title: z.string().min(1),
|
|
217
|
+
description: z.string().optional(),
|
|
218
|
+
due_on: z.string().optional(),
|
|
219
|
+
owner: z.string().optional(),
|
|
220
|
+
repo: z.string().optional(),
|
|
221
|
+
})
|
|
222
|
+
.parse(params)
|
|
223
|
+
|
|
224
|
+
const resolved = await resolveOwnerRepo(
|
|
225
|
+
context,
|
|
226
|
+
input,
|
|
227
|
+
'What GitHub repository should I create the milestone in?'
|
|
228
|
+
)
|
|
229
|
+
if ('error' in resolved) return resolved.response
|
|
230
|
+
|
|
231
|
+
const dueOn = input.due_on ? `${input.due_on}T08:00:00Z` : undefined
|
|
232
|
+
const milestone = await resolved.github.createMilestone(
|
|
233
|
+
resolved.owner,
|
|
234
|
+
resolved.repo,
|
|
235
|
+
input.title,
|
|
236
|
+
input.description,
|
|
237
|
+
dueOn
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
if (!milestone) {
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
error: 'Failed to create milestone. Check GITHUB_TOKEN permissions.',
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
success: true,
|
|
249
|
+
milestone: { ...milestone, completionPercentage: 0 },
|
|
250
|
+
message: `Created milestone #${String(milestone.number)}: ${milestone.title}`,
|
|
251
|
+
}
|
|
252
|
+
} catch (err) {
|
|
253
|
+
return formatHandlerError(err)
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: 'update_github_milestone',
|
|
259
|
+
title: 'Update GitHub Milestone',
|
|
260
|
+
description:
|
|
261
|
+
'Update a GitHub milestone (title, description, due date, or state). Use state "closed" to close a completed milestone.',
|
|
262
|
+
group: 'github',
|
|
263
|
+
inputSchema: z.object({
|
|
264
|
+
milestone_number: z.number().describe('Milestone number to update'),
|
|
265
|
+
title: z.string().optional().describe('New title'),
|
|
266
|
+
description: z.string().optional().describe('New description'),
|
|
267
|
+
due_on: z.string().optional().describe('New due date in YYYY-MM-DD format'),
|
|
268
|
+
state: z.string().optional().describe('Set to "closed" to close the milestone'),
|
|
269
|
+
owner: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
270
|
+
repo: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
271
|
+
}),
|
|
272
|
+
outputSchema: UpdateMilestoneOutputSchema,
|
|
273
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: true },
|
|
274
|
+
handler: async (params: unknown) => {
|
|
275
|
+
try {
|
|
276
|
+
const input = z
|
|
277
|
+
.object({
|
|
278
|
+
milestone_number: z.number(),
|
|
279
|
+
title: z.string().optional(),
|
|
280
|
+
description: z.string().optional(),
|
|
281
|
+
due_on: z.string().optional(),
|
|
282
|
+
state: z.enum(['open', 'closed']).optional(),
|
|
283
|
+
owner: z.string().optional(),
|
|
284
|
+
repo: z.string().optional(),
|
|
285
|
+
})
|
|
286
|
+
.parse(params)
|
|
287
|
+
|
|
288
|
+
const resolved = await resolveOwnerRepo(
|
|
289
|
+
context,
|
|
290
|
+
input,
|
|
291
|
+
'What GitHub repository is this milestone in?'
|
|
292
|
+
)
|
|
293
|
+
if ('error' in resolved) return resolved.response
|
|
294
|
+
|
|
295
|
+
const dueOn = input.due_on ? `${input.due_on}T08:00:00Z` : undefined
|
|
296
|
+
const milestone = await resolved.github.updateMilestone(
|
|
297
|
+
resolved.owner,
|
|
298
|
+
resolved.repo,
|
|
299
|
+
input.milestone_number,
|
|
300
|
+
{
|
|
301
|
+
title: input.title,
|
|
302
|
+
description: input.description,
|
|
303
|
+
dueOn,
|
|
304
|
+
state: input.state,
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
if (!milestone) {
|
|
309
|
+
return {
|
|
310
|
+
success: false,
|
|
311
|
+
error: `Failed to update milestone #${String(input.milestone_number)}. Check that it exists and GITHUB_TOKEN has permissions.`,
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const total = milestone.openIssues + milestone.closedIssues
|
|
316
|
+
const completionPercentage =
|
|
317
|
+
total > 0 ? Math.round((milestone.closedIssues / total) * 100) : 0
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
success: true,
|
|
321
|
+
milestone: { ...milestone, completionPercentage },
|
|
322
|
+
message: `Updated milestone #${String(milestone.number)}: ${milestone.title}`,
|
|
323
|
+
}
|
|
324
|
+
} catch (err) {
|
|
325
|
+
return formatHandlerError(err)
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: 'delete_github_milestone',
|
|
331
|
+
title: 'Delete GitHub Milestone',
|
|
332
|
+
description:
|
|
333
|
+
'Permanently delete a GitHub milestone. Issues assigned to the milestone will be un-assigned but not deleted.',
|
|
334
|
+
group: 'github',
|
|
335
|
+
inputSchema: z.object({
|
|
336
|
+
milestone_number: z.number().describe('Milestone number to delete'),
|
|
337
|
+
confirm: z.literal(true).describe('Must be set to true to confirm deletion'),
|
|
338
|
+
owner: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
339
|
+
repo: z.string().optional().describe('LEAVE EMPTY to auto-detect'),
|
|
340
|
+
}),
|
|
341
|
+
outputSchema: DeleteMilestoneOutputSchema,
|
|
342
|
+
annotations: {
|
|
343
|
+
readOnlyHint: false,
|
|
344
|
+
idempotentHint: false,
|
|
345
|
+
destructiveHint: true,
|
|
346
|
+
openWorldHint: true,
|
|
347
|
+
},
|
|
348
|
+
handler: async (params: unknown) => {
|
|
349
|
+
try {
|
|
350
|
+
const input = z
|
|
351
|
+
.object({
|
|
352
|
+
milestone_number: z.number(),
|
|
353
|
+
confirm: z.literal(true),
|
|
354
|
+
owner: z.string().optional(),
|
|
355
|
+
repo: z.string().optional(),
|
|
356
|
+
})
|
|
357
|
+
.parse(params)
|
|
358
|
+
|
|
359
|
+
const resolved = await resolveOwnerRepo(
|
|
360
|
+
context,
|
|
361
|
+
input,
|
|
362
|
+
'What GitHub repository is this milestone in?'
|
|
363
|
+
)
|
|
364
|
+
if ('error' in resolved) return resolved.response
|
|
365
|
+
|
|
366
|
+
const result = await resolved.github.deleteMilestone(
|
|
367
|
+
resolved.owner,
|
|
368
|
+
resolved.repo,
|
|
369
|
+
input.milestone_number
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
if (!result.success) {
|
|
373
|
+
return {
|
|
374
|
+
success: false,
|
|
375
|
+
milestoneNumber: input.milestone_number,
|
|
376
|
+
message: `Failed to delete milestone #${String(input.milestone_number)}`,
|
|
377
|
+
error: result.error ?? undefined,
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return {
|
|
382
|
+
success: true,
|
|
383
|
+
milestoneNumber: input.milestone_number,
|
|
384
|
+
message: `Deleted milestone #${String(input.milestone_number)}`,
|
|
385
|
+
}
|
|
386
|
+
} catch (err) {
|
|
387
|
+
return formatHandlerError(err)
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
]
|
|
392
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Mutation Tools - Barrel file
|
|
3
|
+
*
|
|
4
|
+
* Composes kanban tools and issue tools into a single export
|
|
5
|
+
* for backward compatibility with existing imports.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ToolDefinition, ToolContext } from '../../../types/index.js'
|
|
9
|
+
import { getKanbanTools } from './kanban-tools.js'
|
|
10
|
+
import { getGitHubIssueTools } from './issue-tools.js'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get all GitHub mutation tools (kanban + issue management)
|
|
14
|
+
*/
|
|
15
|
+
export function getGitHubMutationTools(context: ToolContext): ToolDefinition[] {
|
|
16
|
+
return [...getKanbanTools(context), ...getGitHubIssueTools(context)]
|
|
17
|
+
}
|