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.
- package/README.md +44 -28
- package/dist/{chunk-X4SWFATC.js → chunk-BI4ZNSKA.js} +38 -24
- package/dist/{chunk-HCEWINSB.js → chunk-N6EBIDN7.js} +99 -102
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/tools-WPRY5MJ6.js +2 -0
- package/package.json +10 -1
- package/skills/github-commander/SKILL.md +151 -0
- package/skills/github-commander/config/project-config.example.md +125 -0
- package/skills/github-commander/workflows/code-quality-audit.md +80 -0
- package/skills/github-commander/workflows/full-audit.md +134 -0
- package/skills/github-commander/workflows/issue-triage.md +239 -0
- package/skills/github-commander/workflows/milestone-sprint.md +81 -0
- package/skills/github-commander/workflows/perf-audit.md +142 -0
- package/skills/github-commander/workflows/pr-review.md +123 -0
- package/skills/github-commander/workflows/security-audit.md +170 -0
- package/skills/github-commander/workflows/update-deps.md +109 -0
- package/.dockerignore +0 -139
- package/.gitattributes +0 -20
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -95
- package/.github/ISSUE_TEMPLATE/config.yml +0 -11
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -110
- package/.github/ISSUE_TEMPLATE/question.md +0 -78
- package/.github/aw/actions-lock.json +0 -14
- package/.github/copilot-instructions.md +0 -122
- package/.github/dependabot.yml +0 -93
- package/.github/pull_request_template.md +0 -135
- package/.github/workflows/README.md +0 -133
- package/.github/workflows/agentics-maintenance.yml +0 -141
- package/.github/workflows/auto-release.yml +0 -68
- package/.github/workflows/ci-health-monitor.lock.yml +0 -1121
- package/.github/workflows/ci-health-monitor.md +0 -87
- package/.github/workflows/codeql.yml +0 -41
- package/.github/workflows/dependabot-auto-merge.yml +0 -42
- package/.github/workflows/dependency-maintenance.lock.yml +0 -1182
- package/.github/workflows/dependency-maintenance.md +0 -147
- package/.github/workflows/docker-publish.yml +0 -254
- package/.github/workflows/docs-drift-detector.lock.yml +0 -1142
- package/.github/workflows/docs-drift-detector.md +0 -115
- package/.github/workflows/lint-and-test.yml +0 -60
- package/.github/workflows/publish-npm.yml +0 -85
- package/.github/workflows/secrets-scanning.yml +0 -32
- package/.github/workflows/security-update.yml +0 -127
- package/.gitleaks.toml +0 -9
- package/.prettierignore +0 -21
- package/.prettierrc +0 -33
- package/.scout-ignore +0 -12
- package/.trivyignore +0 -21
- package/CHANGELOG.md +0 -1814
- package/CODE_OF_CONDUCT.md +0 -133
- package/CONTRIBUTING.md +0 -263
- package/DOCKER_README.md +0 -331
- package/Dockerfile +0 -128
- package/SECURITY.md +0 -227
- package/UNRELEASED.md +0 -1
- package/dist/tools-T4U5A3X4.js +0 -2
- package/docker-compose.yml +0 -71
- package/docs/README.md +0 -18
- package/docs/agentic-journal-synergy.md +0 -175
- package/docs/copilot-setup.md +0 -72
- package/eslint.config.js +0 -110
- package/mcp-config-example.json +0 -21
- package/playwright.config.ts +0 -35
- package/releases/v2.1.0.md +0 -220
- package/releases/v2.2.0.md +0 -168
- package/releases/v3.0.0.md +0 -237
- package/releases/v3.1.0.md +0 -104
- package/releases/v3.1.1.md +0 -42
- package/releases/v3.1.2.md +0 -40
- package/releases/v3.1.3.md +0 -64
- package/releases/v3.1.4.md +0 -32
- package/releases/v3.1.5.md +0 -44
- package/releases/v4.0.0.md +0 -71
- package/releases/v4.1.0.md +0 -88
- package/releases/v4.2.0.md +0 -90
- package/releases/v4.3.0.md +0 -92
- package/releases/v4.3.1.md +0 -69
- package/releases/v4.4.0.md +0 -120
- package/releases/v4.4.1.md +0 -33
- package/releases/v4.4.2.md +0 -31
- package/releases/v4.5.0.md +0 -116
- package/releases/v5.0.0.md +0 -105
- package/releases/v5.0.1.md +0 -25
- package/releases/v5.1.0.md +0 -83
- package/releases/v5.1.1.md +0 -10
- package/releases/v6.0.0.md +0 -48
- package/releases/v6.0.1.md +0 -36
- package/releases/v6.1.0.md +0 -68
- package/releases/v6.1.1.md +0 -30
- package/releases/v6.1.2.md +0 -23
- package/scripts/generate-server-instructions.ts +0 -306
- package/scripts/server-instructions-function-body.ts +0 -107
- package/scripts/server-instructions-gotchas.ts +0 -45
- package/server.json +0 -42
- package/social-preview.png +0 -0
- package/src/auth/auth-context.ts +0 -78
- package/src/auth/authorization-server-discovery.ts +0 -263
- package/src/auth/errors.ts +0 -215
- package/src/auth/index.ts +0 -58
- package/src/auth/middleware.ts +0 -392
- package/src/auth/oauth-resource-server.ts +0 -170
- package/src/auth/scope-map.ts +0 -46
- package/src/auth/scopes.ts +0 -256
- package/src/auth/token-validator.ts +0 -293
- package/src/auth/transport-agnostic.ts +0 -164
- package/src/auth/types.ts +0 -372
- package/src/cli.ts +0 -279
- package/src/codemode/api-constants.ts +0 -263
- package/src/codemode/api.ts +0 -302
- package/src/codemode/auto-return.ts +0 -65
- package/src/codemode/index.ts +0 -47
- package/src/codemode/sandbox-factory.ts +0 -144
- package/src/codemode/sandbox.ts +0 -220
- package/src/codemode/security.ts +0 -155
- package/src/codemode/types.ts +0 -228
- package/src/codemode/worker-sandbox.ts +0 -277
- package/src/codemode/worker-script.ts +0 -239
- package/src/constants/icons.ts +0 -183
- package/src/constants/server-instructions.md +0 -166
- package/src/constants/server-instructions.ts +0 -514
- package/src/database/adapter-factory.ts +0 -16
- package/src/database/core/entry-columns.ts +0 -10
- package/src/database/core/interfaces.ts +0 -188
- package/src/database/core/schema.ts +0 -152
- package/src/database/sqlite-adapter/backup.ts +0 -167
- package/src/database/sqlite-adapter/entries/crud.ts +0 -233
- package/src/database/sqlite-adapter/entries/importance.ts +0 -76
- package/src/database/sqlite-adapter/entries/index.ts +0 -142
- package/src/database/sqlite-adapter/entries/search.ts +0 -294
- package/src/database/sqlite-adapter/entries/shared.ts +0 -102
- package/src/database/sqlite-adapter/entries/statistics.ts +0 -162
- package/src/database/sqlite-adapter/index.ts +0 -265
- package/src/database/sqlite-adapter/native-connection.ts +0 -301
- package/src/database/sqlite-adapter/relationships.ts +0 -70
- package/src/database/sqlite-adapter/tags.ts +0 -182
- package/src/filtering/tool-filter.ts +0 -312
- package/src/github/github-integration/client.ts +0 -114
- package/src/github/github-integration/index.ts +0 -297
- package/src/github/github-integration/insights.ts +0 -155
- package/src/github/github-integration/issues.ts +0 -213
- package/src/github/github-integration/milestones.ts +0 -262
- package/src/github/github-integration/projects.ts +0 -414
- package/src/github/github-integration/pull-requests.ts +0 -235
- package/src/github/github-integration/repository.ts +0 -110
- package/src/github/github-integration/types.ts +0 -43
- package/src/handlers/prompts/github.ts +0 -210
- package/src/handlers/prompts/index.ts +0 -97
- package/src/handlers/prompts/workflow.ts +0 -361
- package/src/handlers/resources/core/briefing/context-section.ts +0 -182
- package/src/handlers/resources/core/briefing/github-section.ts +0 -354
- package/src/handlers/resources/core/briefing/index.ts +0 -106
- package/src/handlers/resources/core/briefing/user-message.ts +0 -114
- package/src/handlers/resources/core/health.ts +0 -75
- package/src/handlers/resources/core/index.ts +0 -31
- package/src/handlers/resources/core/instructions.ts +0 -45
- package/src/handlers/resources/core/utilities.ts +0 -310
- package/src/handlers/resources/github.ts +0 -340
- package/src/handlers/resources/graph.ts +0 -218
- package/src/handlers/resources/help.ts +0 -410
- package/src/handlers/resources/index.ts +0 -143
- package/src/handlers/resources/shared.ts +0 -219
- package/src/handlers/resources/team.ts +0 -134
- package/src/handlers/resources/templates.ts +0 -334
- package/src/handlers/tools/admin.ts +0 -351
- package/src/handlers/tools/analytics.ts +0 -346
- package/src/handlers/tools/backup.ts +0 -272
- package/src/handlers/tools/codemode.ts +0 -188
- package/src/handlers/tools/core.ts +0 -359
- package/src/handlers/tools/error-fields-mixin.ts +0 -10
- package/src/handlers/tools/export.ts +0 -150
- package/src/handlers/tools/github/copilot-tools.ts +0 -72
- package/src/handlers/tools/github/helpers.ts +0 -125
- package/src/handlers/tools/github/insights-tools.ts +0 -112
- package/src/handlers/tools/github/issue-tools.ts +0 -442
- package/src/handlers/tools/github/kanban-tools.ts +0 -153
- package/src/handlers/tools/github/milestone-tools.ts +0 -371
- package/src/handlers/tools/github/mutation-tools.ts +0 -17
- package/src/handlers/tools/github/read-tools.ts +0 -302
- package/src/handlers/tools/github/schemas.ts +0 -435
- package/src/handlers/tools/github.ts +0 -39
- package/src/handlers/tools/index.ts +0 -255
- package/src/handlers/tools/relationships.ts +0 -390
- package/src/handlers/tools/schemas.ts +0 -165
- package/src/handlers/tools/search.ts +0 -448
- package/src/handlers/tools/team/admin-tools.ts +0 -164
- package/src/handlers/tools/team/analytics-tools.ts +0 -233
- package/src/handlers/tools/team/backup-tools.ts +0 -83
- package/src/handlers/tools/team/core-tools.ts +0 -197
- package/src/handlers/tools/team/export-tools.ts +0 -130
- package/src/handlers/tools/team/helpers.ts +0 -66
- package/src/handlers/tools/team/index.ts +0 -45
- package/src/handlers/tools/team/relationship-tools.ts +0 -219
- package/src/handlers/tools/team/schemas.ts +0 -558
- package/src/handlers/tools/team/search-tools.ts +0 -145
- package/src/handlers/tools/team/vector-tools.ts +0 -261
- package/src/index.ts +0 -57
- package/src/server/mcp-server.ts +0 -446
- package/src/server/registration.ts +0 -141
- package/src/server/scheduler.ts +0 -283
- package/src/transports/http/handlers.ts +0 -78
- package/src/transports/http/index.ts +0 -8
- package/src/transports/http/security.ts +0 -147
- package/src/transports/http/server/index.ts +0 -397
- package/src/transports/http/server/legacy-sse.ts +0 -87
- package/src/transports/http/server/stateful.ts +0 -222
- package/src/transports/http/server/stateless.ts +0 -42
- package/src/transports/http/types.ts +0 -132
- package/src/types/entities.ts +0 -145
- package/src/types/error-types.ts +0 -92
- package/src/types/errors.ts +0 -200
- package/src/types/filtering.ts +0 -55
- package/src/types/github.ts +0 -216
- package/src/types/index.ts +0 -348
- package/src/utils/error-helpers.ts +0 -78
- package/src/utils/errors/error-response-fields.ts +0 -29
- package/src/utils/errors/suggestions.ts +0 -94
- package/src/utils/github-helpers.ts +0 -33
- package/src/utils/logger.ts +0 -107
- package/src/utils/mcp-logger.ts +0 -155
- package/src/utils/progress-utils.ts +0 -100
- package/src/utils/query-helpers.ts +0 -78
- package/src/utils/resource-annotations.ts +0 -75
- package/src/utils/security-utils.ts +0 -198
- package/src/utils/vector-index-helpers.ts +0 -24
- package/src/vector/vector-search-manager.ts +0 -409
- package/src/version.ts +0 -15
- package/test-server/README.md +0 -193
- package/test-server/code-map.md +0 -399
- package/test-server/test-agent-experience.md +0 -213
- package/test-server/test-filter-instructions.mjs +0 -295
- package/test-server/test-instruction-levels.mjs +0 -102
- package/test-server/test-preflight.md +0 -55
- package/test-server/test-prompts.mjs +0 -185
- package/test-server/test-scheduler.mjs +0 -174
- package/test-server/test-tool-annotations.mjs +0 -115
- package/test-server/test-tools-codemode.md +0 -632
- package/test-server/test-tools-codemode2.md +0 -1218
- package/test-server/test-tools-team.md +0 -215
- package/test-server/test-tools.md +0 -429
- package/test-server/test-tools2.md +0 -361
- package/test-server/test-tools3.md +0 -396
- package/test-server/tool-reference.md +0 -231
- package/tests/README.md +0 -54
- package/tests/auth/auth-context.test.ts +0 -162
- package/tests/auth/authorization-server-discovery.test.ts +0 -265
- package/tests/auth/errors.test.ts +0 -170
- package/tests/auth/middleware.test.ts +0 -585
- package/tests/auth/oauth-resource-server.test.ts +0 -173
- package/tests/auth/scope-map.test.ts +0 -66
- package/tests/auth/scopes.test.ts +0 -347
- package/tests/auth/token-validator.test.ts +0 -271
- package/tests/codemode/api.test.ts +0 -396
- package/tests/codemode/auto-return.test.ts +0 -167
- package/tests/codemode/codemode-tool-handlers.test.ts +0 -197
- package/tests/codemode/sandbox-factory.test.ts +0 -152
- package/tests/codemode/sandbox.test.ts +0 -190
- package/tests/codemode/security.test.ts +0 -242
- package/tests/codemode/worker-sandbox.test.ts +0 -106
- package/tests/constants/icons.test.ts +0 -101
- package/tests/constants/server-instructions.test.ts +0 -514
- package/tests/database/crud-workflow-branches.test.ts +0 -418
- package/tests/database/database-branches.test.ts +0 -132
- package/tests/database/entries-auth-branches.test.ts +0 -390
- package/tests/database/native-connection.test.ts +0 -249
- package/tests/database/shared-helpers.test.ts +0 -103
- package/tests/database/sqlite-adapter.bench.ts +0 -63
- package/tests/database/sqlite-adapter.test.ts +0 -690
- package/tests/database/tags.test.ts +0 -134
- package/tests/e2e/README.md +0 -39
- package/tests/e2e/auth.spec.ts +0 -106
- package/tests/e2e/codemode-abuse.spec.ts +0 -75
- package/tests/e2e/health.spec.ts +0 -63
- package/tests/e2e/helpers.ts +0 -139
- package/tests/e2e/oauth-discovery.spec.ts +0 -102
- package/tests/e2e/oauth-scopes.spec.ts +0 -222
- package/tests/e2e/payloads-admin.spec.ts +0 -76
- package/tests/e2e/payloads-analytics.spec.ts +0 -37
- package/tests/e2e/payloads-backup-restore.spec.ts +0 -102
- package/tests/e2e/payloads-backup.spec.ts +0 -44
- package/tests/e2e/payloads-codemode-api.spec.ts +0 -131
- package/tests/e2e/payloads-codemode-readonly.spec.ts +0 -116
- package/tests/e2e/payloads-codemode.spec.ts +0 -116
- package/tests/e2e/payloads-core.spec.ts +0 -82
- package/tests/e2e/payloads-error-contracts.spec.ts +0 -159
- package/tests/e2e/payloads-export.spec.ts +0 -46
- package/tests/e2e/payloads-github-degradation.spec.ts +0 -73
- package/tests/e2e/payloads-github.spec.ts +0 -176
- package/tests/e2e/payloads-relationships.spec.ts +0 -56
- package/tests/e2e/payloads-search.spec.ts +0 -64
- package/tests/e2e/payloads-team-happy.spec.ts +0 -231
- package/tests/e2e/payloads-team.spec.ts +0 -174
- package/tests/e2e/prompts-expanded.spec.ts +0 -137
- package/tests/e2e/prompts.spec.ts +0 -62
- package/tests/e2e/protocols.spec.ts +0 -134
- package/tests/e2e/rate-limiting.spec.ts +0 -291
- package/tests/e2e/resources-briefing-env.spec.ts +0 -106
- package/tests/e2e/resources-complete.spec.ts +0 -180
- package/tests/e2e/resources-expanded.spec.ts +0 -83
- package/tests/e2e/resources-instructions-levels.spec.ts +0 -145
- package/tests/e2e/resources-templates.spec.ts +0 -123
- package/tests/e2e/resources.spec.ts +0 -103
- package/tests/e2e/scheduler.spec.ts +0 -79
- package/tests/e2e/security.spec.ts +0 -112
- package/tests/e2e/session-advanced.spec.ts +0 -152
- package/tests/e2e/sessions.spec.ts +0 -95
- package/tests/e2e/stateless.spec.ts +0 -79
- package/tests/e2e/streaming.spec.ts +0 -176
- package/tests/e2e/tool-filtering-presets.spec.ts +0 -192
- package/tests/e2e/tool-filtering.spec.ts +0 -77
- package/tests/e2e/tools.spec.ts +0 -111
- package/tests/filtering/tool-filter.test.ts +0 -314
- package/tests/github/client-issues-errors.test.ts +0 -433
- package/tests/github/github-integration-branches.test.ts +0 -490
- package/tests/github/github-integration.test.ts +0 -1015
- package/tests/github/github-managers-branches.test.ts +0 -907
- package/tests/github/pull-requests.test.ts +0 -334
- package/tests/handlers/analytics-branches.test.ts +0 -222
- package/tests/handlers/backup-branches.test.ts +0 -270
- package/tests/handlers/briefing-context-section.test.ts +0 -388
- package/tests/handlers/briefing-github-section.test.ts +0 -392
- package/tests/handlers/briefing-user-message.test.ts +0 -405
- package/tests/handlers/codemode-tools.test.ts +0 -85
- package/tests/handlers/copilot-tools.test.ts +0 -126
- package/tests/handlers/error-path-coverage.test.ts +0 -324
- package/tests/handlers/export-tools.test.ts +0 -203
- package/tests/handlers/github-resource-handlers.test.ts +0 -929
- package/tests/handlers/github-tool-handlers.test.ts +0 -1452
- package/tests/handlers/handler-error-branches.test.ts +0 -346
- package/tests/handlers/help-resource.test.ts +0 -92
- package/tests/handlers/prompt-handler-coverage.test.ts +0 -108
- package/tests/handlers/prompt-handlers.test.ts +0 -131
- package/tests/handlers/resource-handler-coverage.test.ts +0 -281
- package/tests/handlers/resource-handlers.test.ts +0 -357
- package/tests/handlers/resource-prompt-branches.test.ts +0 -495
- package/tests/handlers/search-tool-handlers.test.ts +0 -379
- package/tests/handlers/targeted-gap-closure.test.ts +0 -387
- package/tests/handlers/team-admin.test.ts +0 -291
- package/tests/handlers/team-analytics.test.ts +0 -220
- package/tests/handlers/team-core.test.ts +0 -148
- package/tests/handlers/team-data.test.ts +0 -198
- package/tests/handlers/team-relationships.test.ts +0 -271
- package/tests/handlers/team-resource-handlers.test.ts +0 -161
- package/tests/handlers/team-search.test.ts +0 -134
- package/tests/handlers/team-tool-handlers.test.ts +0 -301
- package/tests/handlers/team-vector.test.ts +0 -213
- package/tests/handlers/template-github-branches.test.ts +0 -676
- package/tests/handlers/tool-annotations.test.ts +0 -90
- package/tests/handlers/tool-handler-coverage.test.ts +0 -514
- package/tests/handlers/tool-handlers.test.ts +0 -510
- package/tests/handlers/tool-output-schemas.test.ts +0 -116
- package/tests/handlers/vector-tool-handlers.test.ts +0 -238
- package/tests/security/sql-injection.test.ts +0 -284
- package/tests/server/mcp-server.bench.ts +0 -55
- package/tests/server/mcp-server.test.ts +0 -1326
- package/tests/server/scheduler.test.ts +0 -400
- package/tests/transports/http-legacy-sse.test.ts +0 -275
- package/tests/transports/http-security.test.ts +0 -322
- package/tests/transports/http-stateful.test.ts +0 -487
- package/tests/transports/http-transport-server.test.ts +0 -301
- package/tests/transports/http-transport.test.ts +0 -771
- package/tests/utils/github-helpers.test.ts +0 -58
- package/tests/utils/logger.test.ts +0 -180
- package/tests/utils/mcp-logger.test.ts +0 -211
- package/tests/utils/progress-utils.test.ts +0 -156
- package/tests/utils/query-helpers.test.ts +0 -80
- package/tests/utils/security-utils.test.ts +0 -82
- package/tests/vector/vector-search-branches.test.ts +0 -111
- package/tests/vector/vector-search-manager.test.ts +0 -375
- package/tests/vector/vector-search.bench.ts +0 -48
- package/tsconfig.json +0 -42
- package/tsup.config.ts +0 -19
- package/vitest.config.ts +0 -25
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { getAllToolNames, getEnabledGroups } from '../../../filtering/tool-filter.js'
|
|
2
|
-
import {
|
|
3
|
-
generateInstructions,
|
|
4
|
-
type InstructionLevel,
|
|
5
|
-
} from '../../../constants/server-instructions.js'
|
|
6
|
-
import { getPrompts } from '../../prompts/index.js'
|
|
7
|
-
import { ICON_BRIEFING } from '../../../constants/icons.js'
|
|
8
|
-
import { withPriority, ASSISTANT_FOCUSED } from '../../../utils/resource-annotations.js'
|
|
9
|
-
import type { InternalResourceDef, ResourceContext, ResourceResult } from '../shared.js'
|
|
10
|
-
|
|
11
|
-
export const instructionsResource: InternalResourceDef = {
|
|
12
|
-
uri: 'memory://instructions',
|
|
13
|
-
name: 'Server Instructions',
|
|
14
|
-
title: 'Full Server Behavioral Guidance',
|
|
15
|
-
description: 'Full server instructions for AI agents.',
|
|
16
|
-
mimeType: 'text/markdown',
|
|
17
|
-
icons: [ICON_BRIEFING],
|
|
18
|
-
annotations: withPriority(0.95, ASSISTANT_FOCUSED),
|
|
19
|
-
handler: (_uri: string, context: ResourceContext): ResourceResult => {
|
|
20
|
-
const level: InstructionLevel = 'full'
|
|
21
|
-
|
|
22
|
-
const allToolNames = new Set(getAllToolNames())
|
|
23
|
-
const enabledTools = context.filterConfig?.enabledTools ?? allToolNames
|
|
24
|
-
const enabledGroups = context.filterConfig
|
|
25
|
-
? getEnabledGroups(context.filterConfig.enabledTools)
|
|
26
|
-
: undefined
|
|
27
|
-
|
|
28
|
-
const prompts = getPrompts().map((p) => {
|
|
29
|
-
const prompt = p as { name: string; description?: string }
|
|
30
|
-
return { name: prompt.name, description: prompt.description }
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const instructions = generateInstructions(
|
|
34
|
-
enabledTools,
|
|
35
|
-
prompts,
|
|
36
|
-
undefined,
|
|
37
|
-
level,
|
|
38
|
-
enabledGroups
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
data: instructions,
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
}
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import type { Tag } from '../../../types/index.js'
|
|
2
|
-
import {
|
|
3
|
-
ICON_CLOCK,
|
|
4
|
-
ICON_STAR,
|
|
5
|
-
ICON_TAG,
|
|
6
|
-
ICON_ANALYTICS,
|
|
7
|
-
ICON_BRIEFING,
|
|
8
|
-
} from '../../../constants/icons.js'
|
|
9
|
-
import { RAW_ENTRY_COLUMNS as ENTRY_COLUMNS } from '../../../database/core/entry-columns.js'
|
|
10
|
-
import {
|
|
11
|
-
withPriority,
|
|
12
|
-
ASSISTANT_FOCUSED,
|
|
13
|
-
LOW_PRIORITY,
|
|
14
|
-
MEDIUM_PRIORITY,
|
|
15
|
-
} from '../../../utils/resource-annotations.js'
|
|
16
|
-
import type { InternalResourceDef, ResourceContext, ResourceResult } from '../shared.js'
|
|
17
|
-
import { execQuery, transformEntryRow } from '../shared.js'
|
|
18
|
-
import * as fs from 'node:fs'
|
|
19
|
-
import * as path from 'node:path'
|
|
20
|
-
|
|
21
|
-
export const recentResource: InternalResourceDef = {
|
|
22
|
-
uri: 'memory://recent',
|
|
23
|
-
name: 'Recent Entries',
|
|
24
|
-
title: 'Recent Journal Entries',
|
|
25
|
-
description: '10 most recent journal entries',
|
|
26
|
-
mimeType: 'application/json',
|
|
27
|
-
icons: [ICON_CLOCK],
|
|
28
|
-
annotations: withPriority(0.8, ASSISTANT_FOCUSED),
|
|
29
|
-
handler: (_uri: string, context: ResourceContext): ResourceResult => {
|
|
30
|
-
const entries = context.db.getRecentEntries(10)
|
|
31
|
-
const lastModified = entries[0]?.timestamp ?? new Date().toISOString()
|
|
32
|
-
return {
|
|
33
|
-
data: { entries, count: entries.length },
|
|
34
|
-
annotations: { lastModified },
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const significantResource: InternalResourceDef = {
|
|
40
|
-
uri: 'memory://significant',
|
|
41
|
-
name: 'Significant Entries',
|
|
42
|
-
title: 'Significant Milestones',
|
|
43
|
-
description: 'Significant milestones and breakthroughs',
|
|
44
|
-
mimeType: 'application/json',
|
|
45
|
-
icons: [ICON_STAR],
|
|
46
|
-
annotations: withPriority(0.7, ASSISTANT_FOCUSED),
|
|
47
|
-
handler: (_uri: string, context: ResourceContext) => {
|
|
48
|
-
// Batched importance: single query computes rel_count + causal_count for all
|
|
49
|
-
// significant entries using LEFT JOIN aggregations, eliminating N+1 per-entry calls.
|
|
50
|
-
// Weights mirror importance.ts constants (significance 0.3, relationships 0.35,
|
|
51
|
-
// causal 0.2, recency 0.15). If those change, update the formula here too.
|
|
52
|
-
const rows = execQuery(
|
|
53
|
-
context.db,
|
|
54
|
-
`
|
|
55
|
-
SELECT ${ENTRY_COLUMNS},
|
|
56
|
-
COALESCE(r.rel_count, 0) AS rel_count,
|
|
57
|
-
COALESCE(r.causal_count, 0) AS causal_count
|
|
58
|
-
FROM memory_journal
|
|
59
|
-
LEFT JOIN (
|
|
60
|
-
SELECT entry_id,
|
|
61
|
-
COUNT(*) AS rel_count,
|
|
62
|
-
SUM(CASE WHEN rel_type IN ('blocked_by','resolved','caused') THEN 1 ELSE 0 END) AS causal_count
|
|
63
|
-
FROM (
|
|
64
|
-
SELECT from_entry_id AS entry_id, relationship_type AS rel_type FROM relationships
|
|
65
|
-
UNION ALL
|
|
66
|
-
SELECT to_entry_id AS entry_id, relationship_type AS rel_type FROM relationships
|
|
67
|
-
) grouped
|
|
68
|
-
GROUP BY entry_id
|
|
69
|
-
) r ON r.entry_id = memory_journal.id
|
|
70
|
-
WHERE significance_type IS NOT NULL
|
|
71
|
-
AND deleted_at IS NULL
|
|
72
|
-
`
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
const now = Date.now()
|
|
76
|
-
const MS_PER_DAY = 86_400_000
|
|
77
|
-
const RECENCY_WINDOW_DAYS = 90
|
|
78
|
-
const MAX_REL_SCORE_AT = 5
|
|
79
|
-
const MAX_CAUSAL_SCORE_AT = 3
|
|
80
|
-
|
|
81
|
-
const entriesWithImportance = rows.map((row) => {
|
|
82
|
-
const entry = transformEntryRow(row)
|
|
83
|
-
const relCount = (row['rel_count'] as number) ?? 0
|
|
84
|
-
const causalCount = (row['causal_count'] as number) ?? 0
|
|
85
|
-
const daysSince = Math.floor(
|
|
86
|
-
(now - new Date(entry['timestamp'] as string).getTime()) / MS_PER_DAY
|
|
87
|
-
)
|
|
88
|
-
const recency = Math.max(0, 1 - daysSince / RECENCY_WINDOW_DAYS)
|
|
89
|
-
|
|
90
|
-
const importance =
|
|
91
|
-
Math.round(
|
|
92
|
-
(1.0 * 0.3 + // significance (always 1.0 — filtered by IS NOT NULL)
|
|
93
|
-
Math.min(relCount / MAX_REL_SCORE_AT, 1.0) * 0.35 + // relationships
|
|
94
|
-
Math.min(causalCount / MAX_CAUSAL_SCORE_AT, 1.0) * 0.2 + // causal
|
|
95
|
-
recency * 0.15) * // recency
|
|
96
|
-
100
|
|
97
|
-
) / 100
|
|
98
|
-
|
|
99
|
-
return { ...entry, importance } as { timestamp: string; importance: number }
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
entriesWithImportance.sort((a, b) => {
|
|
103
|
-
if (b.importance !== a.importance) {
|
|
104
|
-
return b.importance - a.importance
|
|
105
|
-
}
|
|
106
|
-
const aTime = new Date(a.timestamp).getTime()
|
|
107
|
-
const bTime = new Date(b.timestamp).getTime()
|
|
108
|
-
return bTime - aTime
|
|
109
|
-
})
|
|
110
|
-
const top20 = entriesWithImportance.slice(0, 20)
|
|
111
|
-
return { entries: top20, count: top20.length }
|
|
112
|
-
},
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export const tagsResource: InternalResourceDef = {
|
|
116
|
-
uri: 'memory://tags',
|
|
117
|
-
name: 'All Tags',
|
|
118
|
-
title: 'Tag List',
|
|
119
|
-
description: 'All available tags with usage counts',
|
|
120
|
-
mimeType: 'application/json',
|
|
121
|
-
icons: [ICON_TAG],
|
|
122
|
-
annotations: { ...LOW_PRIORITY, audience: ['assistant'] },
|
|
123
|
-
handler: (_uri: string, context: ResourceContext) => {
|
|
124
|
-
const tags: Tag[] = context.db.listTags()
|
|
125
|
-
const mappedTags = tags.map((t) => ({
|
|
126
|
-
id: t.id,
|
|
127
|
-
name: t.name,
|
|
128
|
-
count: t.usageCount,
|
|
129
|
-
}))
|
|
130
|
-
return { tags: mappedTags, count: mappedTags.length }
|
|
131
|
-
},
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export const statisticsResource: InternalResourceDef = {
|
|
135
|
-
uri: 'memory://statistics',
|
|
136
|
-
name: 'Statistics',
|
|
137
|
-
title: 'Journal Statistics',
|
|
138
|
-
description: 'Overall journal statistics',
|
|
139
|
-
mimeType: 'application/json',
|
|
140
|
-
icons: [ICON_ANALYTICS],
|
|
141
|
-
annotations: { ...LOW_PRIORITY, audience: ['assistant'] },
|
|
142
|
-
handler: (_uri: string, context: ResourceContext) => {
|
|
143
|
-
return context.db.getStatistics('week')
|
|
144
|
-
},
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export const rulesResource: InternalResourceDef = {
|
|
148
|
-
uri: 'memory://rules',
|
|
149
|
-
name: 'Rules File',
|
|
150
|
-
title: 'Agent Rules & Coding Standards',
|
|
151
|
-
description: 'Contents of the configured RULES_FILE_PATH (agent rules / GEMINI.md)',
|
|
152
|
-
mimeType: 'text/markdown',
|
|
153
|
-
icons: [ICON_BRIEFING],
|
|
154
|
-
annotations: withPriority(0.7, ASSISTANT_FOCUSED),
|
|
155
|
-
handler: (_uri: string, _context: ResourceContext): ResourceResult => {
|
|
156
|
-
const rulesPath = process.env['RULES_FILE_PATH']
|
|
157
|
-
if (!rulesPath) {
|
|
158
|
-
return {
|
|
159
|
-
data: {
|
|
160
|
-
configured: false,
|
|
161
|
-
message:
|
|
162
|
-
'RULES_FILE_PATH is not configured. Set this env var to serve rules content.',
|
|
163
|
-
},
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
try {
|
|
167
|
-
const content = fs.readFileSync(rulesPath, 'utf8')
|
|
168
|
-
return {
|
|
169
|
-
data: content,
|
|
170
|
-
annotations: {
|
|
171
|
-
lastModified: new Date(fs.statSync(rulesPath).mtimeMs).toISOString(),
|
|
172
|
-
},
|
|
173
|
-
}
|
|
174
|
-
} catch (err) {
|
|
175
|
-
const message = err instanceof Error ? err.message : String(err)
|
|
176
|
-
return {
|
|
177
|
-
data: {
|
|
178
|
-
configured: true,
|
|
179
|
-
error: `Could not read rules file: ${message}`,
|
|
180
|
-
path: rulesPath,
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export const workflowsResource: InternalResourceDef = {
|
|
188
|
-
uri: 'memory://workflows',
|
|
189
|
-
name: 'Workflows',
|
|
190
|
-
title: 'Agent Workflow Summaries',
|
|
191
|
-
description: 'Summary of available agent workflows from the configured workflow directory',
|
|
192
|
-
mimeType: 'application/json',
|
|
193
|
-
icons: [ICON_BRIEFING],
|
|
194
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
195
|
-
handler: (_uri: string, context: ResourceContext): ResourceResult => {
|
|
196
|
-
// Prefer briefingConfig.workflowSummary (set via CLI --workflow-summary or
|
|
197
|
-
// MEMORY_JOURNAL_WORKFLOW_SUMMARY env var in cli.ts). Fall back to env var
|
|
198
|
-
// for callers that don't pass a briefingConfig (e.g., tests, direct readResource).
|
|
199
|
-
const workflowSummary: string | undefined =
|
|
200
|
-
context.briefingConfig?.workflowSummary ??
|
|
201
|
-
process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY']
|
|
202
|
-
if (workflowSummary === undefined || workflowSummary === '') {
|
|
203
|
-
return {
|
|
204
|
-
data: {
|
|
205
|
-
configured: false,
|
|
206
|
-
message:
|
|
207
|
-
'No workflow summary is available. Set MEMORY_JOURNAL_WORKFLOW_SUMMARY env var or use --workflow-summary.',
|
|
208
|
-
},
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return {
|
|
212
|
-
data: {
|
|
213
|
-
configured: true,
|
|
214
|
-
summary: workflowSummary,
|
|
215
|
-
},
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let cachedSkills: { name: string; path: string; excerpt: string }[] | null = null
|
|
221
|
-
let lastScanTime = 0
|
|
222
|
-
const SKILLS_CACHE_TTL_MS = 5 * 60 * 1000 // 5 minutes
|
|
223
|
-
|
|
224
|
-
export const skillsResource: InternalResourceDef = {
|
|
225
|
-
uri: 'memory://skills',
|
|
226
|
-
name: 'Skills',
|
|
227
|
-
title: 'Agent Skills Index',
|
|
228
|
-
description: 'Index of available agent skills from the configured SKILLS_DIR_PATH',
|
|
229
|
-
mimeType: 'application/json',
|
|
230
|
-
icons: [ICON_BRIEFING],
|
|
231
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
232
|
-
handler: (_uri: string, _context: ResourceContext): ResourceResult => {
|
|
233
|
-
const skillsDir = process.env['SKILLS_DIR_PATH']
|
|
234
|
-
if (!skillsDir) {
|
|
235
|
-
return {
|
|
236
|
-
data: {
|
|
237
|
-
configured: false,
|
|
238
|
-
message: 'SKILLS_DIR_PATH is not configured. Set this env var to index skills.',
|
|
239
|
-
},
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
try {
|
|
243
|
-
if (!fs.existsSync(skillsDir)) {
|
|
244
|
-
return {
|
|
245
|
-
data: {
|
|
246
|
-
configured: true,
|
|
247
|
-
error: `Skills directory not found: ${skillsDir}`,
|
|
248
|
-
skills: [],
|
|
249
|
-
count: 0,
|
|
250
|
-
},
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (cachedSkills && Date.now() - lastScanTime < SKILLS_CACHE_TTL_MS) {
|
|
255
|
-
return {
|
|
256
|
-
data: {
|
|
257
|
-
configured: true,
|
|
258
|
-
skillsDir,
|
|
259
|
-
skills: cachedSkills,
|
|
260
|
-
count: cachedSkills.length,
|
|
261
|
-
},
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Find all SKILL.md files one level deep (each skill is a directory)
|
|
266
|
-
const entries = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
267
|
-
const skills: { name: string; path: string; excerpt: string }[] = []
|
|
268
|
-
|
|
269
|
-
for (const entry of entries) {
|
|
270
|
-
if (!entry.isDirectory()) continue
|
|
271
|
-
const skillMdPath = path.join(skillsDir, entry.name, 'SKILL.md')
|
|
272
|
-
if (!fs.existsSync(skillMdPath)) continue
|
|
273
|
-
|
|
274
|
-
const content = fs.readFileSync(skillMdPath, 'utf8')
|
|
275
|
-
// Extract first non-empty non-header line as excerpt (up to 160 chars)
|
|
276
|
-
const lines = content.split('\n')
|
|
277
|
-
const excerptLine = lines.find(
|
|
278
|
-
(l) => l.trim().length > 0 && !l.startsWith('#') && !l.startsWith('---')
|
|
279
|
-
)
|
|
280
|
-
const excerpt = excerptLine ? excerptLine.trim().slice(0, 160) : ''
|
|
281
|
-
|
|
282
|
-
skills.push({ name: entry.name, path: skillMdPath, excerpt })
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
skills.sort((a, b) => a.name.localeCompare(b.name))
|
|
286
|
-
|
|
287
|
-
cachedSkills = skills
|
|
288
|
-
lastScanTime = Date.now()
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
data: {
|
|
292
|
-
configured: true,
|
|
293
|
-
skillsDir,
|
|
294
|
-
skills,
|
|
295
|
-
count: skills.length,
|
|
296
|
-
},
|
|
297
|
-
}
|
|
298
|
-
} catch (err) {
|
|
299
|
-
const message = err instanceof Error ? err.message : String(err)
|
|
300
|
-
return {
|
|
301
|
-
data: {
|
|
302
|
-
configured: true,
|
|
303
|
-
error: `Could not scan skills directory: ${message}`,
|
|
304
|
-
skills: [],
|
|
305
|
-
count: 0,
|
|
306
|
-
},
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
}
|
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Journal MCP Server - GitHub Resource Definitions
|
|
3
|
-
*
|
|
4
|
-
* Resources: github/status, github/insights, github/milestones, milestones/{number}
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { ICON_GITHUB, ICON_ANALYTICS, ICON_MILESTONE } from '../../constants/icons.js'
|
|
8
|
-
import {
|
|
9
|
-
withPriority,
|
|
10
|
-
ASSISTANT_FOCUSED,
|
|
11
|
-
LOW_PRIORITY,
|
|
12
|
-
MEDIUM_PRIORITY,
|
|
13
|
-
} from '../../utils/resource-annotations.js'
|
|
14
|
-
import type { InternalResourceDef, ResourceContext, ResourceResult } from './shared.js'
|
|
15
|
-
import { resolveGitHubRepo, isResourceError, milestoneCompletionPct } from './shared.js'
|
|
16
|
-
import { logger } from '../../utils/logger.js'
|
|
17
|
-
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// Resource API Limits
|
|
20
|
-
// ============================================================================
|
|
21
|
-
|
|
22
|
-
/** Max open issues to fetch for resource views (token efficiency) */
|
|
23
|
-
const RESOURCE_ISSUE_LIMIT = 5
|
|
24
|
-
/** Max open PRs to fetch for resource views (token efficiency) */
|
|
25
|
-
const RESOURCE_PR_LIMIT = 5
|
|
26
|
-
/** Max workflow runs to fetch for CI status */
|
|
27
|
-
const RESOURCE_WORKFLOW_LIMIT = 5
|
|
28
|
-
/** Max open milestones to fetch for status summary */
|
|
29
|
-
const RESOURCE_STATUS_MILESTONE_LIMIT = 5
|
|
30
|
-
/** Max open milestones to fetch for the milestones resource */
|
|
31
|
-
const RESOURCE_MILESTONE_LIMIT = 20
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get GitHub resource definitions
|
|
35
|
-
*/
|
|
36
|
-
export function getGitHubResourceDefinitions(): InternalResourceDef[] {
|
|
37
|
-
return [
|
|
38
|
-
{
|
|
39
|
-
uri: 'memory://github/status',
|
|
40
|
-
name: 'GitHub Status',
|
|
41
|
-
title: 'GitHub Repository Status',
|
|
42
|
-
description:
|
|
43
|
-
'Compact GitHub status: repository, branch, CI, issues, PRs, Kanban summary',
|
|
44
|
-
mimeType: 'application/json',
|
|
45
|
-
icons: [ICON_GITHUB],
|
|
46
|
-
annotations: withPriority(0.7, ASSISTANT_FOCUSED),
|
|
47
|
-
handler: async (_uri: string, context: ResourceContext): Promise<ResourceResult> => {
|
|
48
|
-
const resolved = await resolveGitHubRepo(context.github)
|
|
49
|
-
if (isResourceError(resolved)) return resolved
|
|
50
|
-
const { owner, repo, branch, lastModified, github } = resolved
|
|
51
|
-
|
|
52
|
-
// Resolve default project number — skip kanban fetch when not configured
|
|
53
|
-
const defaultProjectNumber = context.briefingConfig?.defaultProjectNumber
|
|
54
|
-
|
|
55
|
-
// Parallelize independent API calls for performance
|
|
56
|
-
const [
|
|
57
|
-
commitResult,
|
|
58
|
-
issuesResult,
|
|
59
|
-
prsResult,
|
|
60
|
-
workflowsResult,
|
|
61
|
-
kanbanResult,
|
|
62
|
-
milestoneResult,
|
|
63
|
-
] = await Promise.allSettled([
|
|
64
|
-
github.getRepoContext(),
|
|
65
|
-
github.getIssues(owner, repo, 'open', RESOURCE_ISSUE_LIMIT),
|
|
66
|
-
github.getPullRequests(owner, repo, 'open', RESOURCE_PR_LIMIT),
|
|
67
|
-
github.getWorkflowRuns(owner, repo, RESOURCE_WORKFLOW_LIMIT),
|
|
68
|
-
defaultProjectNumber !== undefined
|
|
69
|
-
? github.getProjectKanban(owner, defaultProjectNumber, repo)
|
|
70
|
-
: Promise.resolve(null),
|
|
71
|
-
github.getMilestones(owner, repo, 'open', RESOURCE_STATUS_MILESTONE_LIMIT),
|
|
72
|
-
])
|
|
73
|
-
|
|
74
|
-
// Extract results with safe defaults
|
|
75
|
-
const commit =
|
|
76
|
-
commitResult.status === 'fulfilled' ? commitResult.value.commit : null
|
|
77
|
-
if (commitResult.status === 'rejected') {
|
|
78
|
-
logger.debug('Failed to fetch commit context', {
|
|
79
|
-
module: 'RESOURCE',
|
|
80
|
-
operation: 'github-status',
|
|
81
|
-
error: commitResult.reason,
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const issues = issuesResult.status === 'fulfilled' ? issuesResult.value : []
|
|
86
|
-
const openIssues = issues.map((i) => ({
|
|
87
|
-
number: i.number,
|
|
88
|
-
title: i.title.slice(0, 50),
|
|
89
|
-
}))
|
|
90
|
-
|
|
91
|
-
const prs = prsResult.status === 'fulfilled' ? prsResult.value : []
|
|
92
|
-
const openPrs = prs.map((pr) => ({
|
|
93
|
-
number: pr.number,
|
|
94
|
-
title: pr.title.slice(0, 50),
|
|
95
|
-
state: pr.state,
|
|
96
|
-
}))
|
|
97
|
-
|
|
98
|
-
// CI status from workflow runs
|
|
99
|
-
const workflowRuns =
|
|
100
|
-
workflowsResult.status === 'fulfilled' ? workflowsResult.value : []
|
|
101
|
-
let ciStatus: 'passing' | 'failing' | 'pending' | 'cancelled' | 'unknown' =
|
|
102
|
-
'unknown'
|
|
103
|
-
let latestRun: { name: string; conclusion: string | null; headSha: string } | null =
|
|
104
|
-
null
|
|
105
|
-
|
|
106
|
-
if (workflowRuns.length > 0) {
|
|
107
|
-
const latestCompleted = workflowRuns.find((r) => r.status === 'completed')
|
|
108
|
-
const latest = workflowRuns[0]
|
|
109
|
-
|
|
110
|
-
latestRun = {
|
|
111
|
-
name: latest?.name ?? 'Unknown',
|
|
112
|
-
conclusion: latest?.conclusion ?? null,
|
|
113
|
-
headSha: latest?.headSha?.slice(0, 7) ?? '',
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (latestCompleted) {
|
|
117
|
-
switch (latestCompleted.conclusion) {
|
|
118
|
-
case 'success':
|
|
119
|
-
ciStatus = 'passing'
|
|
120
|
-
break
|
|
121
|
-
case 'failure':
|
|
122
|
-
ciStatus = 'failing'
|
|
123
|
-
break
|
|
124
|
-
case 'cancelled':
|
|
125
|
-
ciStatus = 'cancelled'
|
|
126
|
-
break
|
|
127
|
-
default:
|
|
128
|
-
ciStatus = 'unknown'
|
|
129
|
-
}
|
|
130
|
-
} else if (workflowRuns.some((r) => r.status !== 'completed')) {
|
|
131
|
-
ciStatus = 'pending'
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Kanban summary
|
|
136
|
-
let kanbanSummary: Record<string, number> | null = null
|
|
137
|
-
if (kanbanResult.status === 'fulfilled' && kanbanResult.value) {
|
|
138
|
-
kanbanSummary = {}
|
|
139
|
-
for (const col of kanbanResult.value.columns) {
|
|
140
|
-
kanbanSummary[col.status] = col.items.length
|
|
141
|
-
}
|
|
142
|
-
} else if (kanbanResult.status === 'rejected') {
|
|
143
|
-
logger.debug('Failed to fetch Kanban board', {
|
|
144
|
-
module: 'RESOURCE',
|
|
145
|
-
operation: 'github-status',
|
|
146
|
-
error: kanbanResult.reason,
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Milestone summary
|
|
151
|
-
let milestoneSummary:
|
|
152
|
-
| {
|
|
153
|
-
number: number
|
|
154
|
-
title: string
|
|
155
|
-
state: string
|
|
156
|
-
openIssues: number
|
|
157
|
-
closedIssues: number
|
|
158
|
-
completionPercentage: number
|
|
159
|
-
dueOn: string | null
|
|
160
|
-
}[]
|
|
161
|
-
| null = null
|
|
162
|
-
if (milestoneResult.status === 'fulfilled' && milestoneResult.value.length > 0) {
|
|
163
|
-
milestoneSummary = milestoneResult.value.map((ms) => {
|
|
164
|
-
const pct = milestoneCompletionPct(ms.openIssues, ms.closedIssues)
|
|
165
|
-
return {
|
|
166
|
-
number: ms.number,
|
|
167
|
-
title: ms.title,
|
|
168
|
-
state: ms.state,
|
|
169
|
-
openIssues: ms.openIssues,
|
|
170
|
-
closedIssues: ms.closedIssues,
|
|
171
|
-
completionPercentage: pct,
|
|
172
|
-
dueOn: ms.dueOn,
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
} else if (milestoneResult.status === 'rejected') {
|
|
176
|
-
logger.debug('Failed to fetch milestones', {
|
|
177
|
-
module: 'RESOURCE',
|
|
178
|
-
operation: 'github-status',
|
|
179
|
-
error: milestoneResult.reason,
|
|
180
|
-
})
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
data: {
|
|
185
|
-
repository: `${owner}/${repo}`,
|
|
186
|
-
branch,
|
|
187
|
-
commit: commit?.slice(0, 7) ?? null,
|
|
188
|
-
ci: {
|
|
189
|
-
status: ciStatus,
|
|
190
|
-
latestRun,
|
|
191
|
-
},
|
|
192
|
-
issues: {
|
|
193
|
-
openCount: issues.length,
|
|
194
|
-
items: openIssues,
|
|
195
|
-
},
|
|
196
|
-
pullRequests: {
|
|
197
|
-
openCount: prs.length,
|
|
198
|
-
items: openPrs,
|
|
199
|
-
},
|
|
200
|
-
kanbanSummary,
|
|
201
|
-
milestones: milestoneSummary,
|
|
202
|
-
},
|
|
203
|
-
annotations: { lastModified },
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
// Repository insights resource
|
|
208
|
-
{
|
|
209
|
-
uri: 'memory://github/insights',
|
|
210
|
-
name: 'Repository Insights',
|
|
211
|
-
title: 'Repository Stars & Traffic Summary',
|
|
212
|
-
description: 'Compact repo insights: stars, forks, 14-day traffic totals (~150 tokens)',
|
|
213
|
-
mimeType: 'application/json',
|
|
214
|
-
icons: [ICON_ANALYTICS],
|
|
215
|
-
annotations: { ...LOW_PRIORITY, audience: ['assistant'] },
|
|
216
|
-
handler: async (_uri: string, context: ResourceContext): Promise<ResourceResult> => {
|
|
217
|
-
const resolved = await resolveGitHubRepo(context.github)
|
|
218
|
-
if (isResourceError(resolved)) return resolved
|
|
219
|
-
const { owner, repo, lastModified, github } = resolved
|
|
220
|
-
|
|
221
|
-
const stats = await github.getRepoStats(owner, repo)
|
|
222
|
-
|
|
223
|
-
let traffic: { clones14d: number; views14d: number } | null = null
|
|
224
|
-
try {
|
|
225
|
-
const trafficData = await github.getTrafficData(owner, repo)
|
|
226
|
-
if (trafficData) {
|
|
227
|
-
traffic = {
|
|
228
|
-
clones14d: trafficData.clones.total,
|
|
229
|
-
views14d: trafficData.views.total,
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
} catch {
|
|
233
|
-
// Traffic data requires push access
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
data: {
|
|
238
|
-
repository: `${owner}/${repo}`,
|
|
239
|
-
stars: stats?.stars ?? null,
|
|
240
|
-
forks: stats?.forks ?? null,
|
|
241
|
-
watchers: stats?.watchers ?? null,
|
|
242
|
-
...(traffic ?? {}),
|
|
243
|
-
hint: !traffic
|
|
244
|
-
? 'Traffic data requires push access to the repository.'
|
|
245
|
-
: undefined,
|
|
246
|
-
},
|
|
247
|
-
annotations: { lastModified },
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
// Milestone resources
|
|
252
|
-
{
|
|
253
|
-
uri: 'memory://github/milestones',
|
|
254
|
-
name: 'GitHub Milestones',
|
|
255
|
-
title: 'GitHub Repository Milestones',
|
|
256
|
-
description:
|
|
257
|
-
'Open GitHub milestones with completion percentages, due dates, and issue counts',
|
|
258
|
-
mimeType: 'application/json',
|
|
259
|
-
icons: [ICON_MILESTONE],
|
|
260
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
261
|
-
handler: async (_uri: string, context: ResourceContext): Promise<ResourceResult> => {
|
|
262
|
-
const resolved = await resolveGitHubRepo(context.github)
|
|
263
|
-
if (isResourceError(resolved)) return resolved
|
|
264
|
-
const { owner, repo, lastModified, github } = resolved
|
|
265
|
-
|
|
266
|
-
const milestones = await github.getMilestones(
|
|
267
|
-
owner,
|
|
268
|
-
repo,
|
|
269
|
-
'open',
|
|
270
|
-
RESOURCE_MILESTONE_LIMIT
|
|
271
|
-
)
|
|
272
|
-
const milestonesWithProgress = milestones.map((ms) => {
|
|
273
|
-
const completionPercentage = milestoneCompletionPct(
|
|
274
|
-
ms.openIssues,
|
|
275
|
-
ms.closedIssues
|
|
276
|
-
)
|
|
277
|
-
return { ...ms, completionPercentage }
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
return {
|
|
281
|
-
data: {
|
|
282
|
-
repository: `${owner}/${repo}`,
|
|
283
|
-
milestones: milestonesWithProgress,
|
|
284
|
-
count: milestonesWithProgress.length,
|
|
285
|
-
hint: 'Use get_github_milestones tool for state filtering. Use memory://milestones/{number} for detail.',
|
|
286
|
-
},
|
|
287
|
-
annotations: { lastModified },
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
uri: 'memory://milestones/{number}',
|
|
293
|
-
name: 'Milestone Detail',
|
|
294
|
-
title: 'GitHub Milestone Detail',
|
|
295
|
-
description:
|
|
296
|
-
'Detailed view of a single GitHub milestone with completion progress and issue counts. Use get_github_issues with the milestone filter for individual issue details.',
|
|
297
|
-
mimeType: 'application/json',
|
|
298
|
-
icons: [ICON_MILESTONE],
|
|
299
|
-
annotations: ASSISTANT_FOCUSED,
|
|
300
|
-
handler: async (uri: string, context: ResourceContext): Promise<ResourceResult> => {
|
|
301
|
-
const lastModified = new Date().toISOString()
|
|
302
|
-
const match = /memory:\/\/milestones\/(\d+)/.exec(uri)
|
|
303
|
-
const milestoneNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
304
|
-
|
|
305
|
-
if (milestoneNumber === null) {
|
|
306
|
-
return {
|
|
307
|
-
data: { error: 'Invalid milestone number' },
|
|
308
|
-
annotations: { lastModified },
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const resolved = await resolveGitHubRepo(context.github)
|
|
313
|
-
if (isResourceError(resolved)) return resolved
|
|
314
|
-
const { owner, repo, github } = resolved
|
|
315
|
-
|
|
316
|
-
const milestone = await github.getMilestone(owner, repo, milestoneNumber)
|
|
317
|
-
if (!milestone) {
|
|
318
|
-
return {
|
|
319
|
-
data: { error: `Milestone #${String(milestoneNumber)} not found` },
|
|
320
|
-
annotations: { lastModified },
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const completionPercentage = milestoneCompletionPct(
|
|
325
|
-
milestone.openIssues,
|
|
326
|
-
milestone.closedIssues
|
|
327
|
-
)
|
|
328
|
-
|
|
329
|
-
return {
|
|
330
|
-
data: {
|
|
331
|
-
repository: `${owner}/${repo}`,
|
|
332
|
-
milestone: { ...milestone, completionPercentage },
|
|
333
|
-
hint: 'Use get_github_issues tool to list issues associated with this milestone.',
|
|
334
|
-
},
|
|
335
|
-
annotations: { lastModified },
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
]
|
|
340
|
-
}
|