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,334 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Journal MCP Server - Template Resource Definitions
|
|
3
|
-
*
|
|
4
|
-
* Resources with URI templates (parameterized):
|
|
5
|
-
* projects/{number}/timeline, issues/{issue_number}/entries, prs/{pr_number}/entries,
|
|
6
|
-
* prs/{pr_number}/timeline, kanban/{project_number}, kanban/{project_number}/diagram
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { ICON_ISSUE, ICON_PR } from '../../constants/icons.js'
|
|
10
|
-
import { RAW_ENTRY_COLUMNS as ENTRY_COLUMNS } from '../../database/core/entry-columns.js'
|
|
11
|
-
import { ASSISTANT_FOCUSED, MEDIUM_PRIORITY } from '../../utils/resource-annotations.js'
|
|
12
|
-
import type { InternalResourceDef, ResourceContext } from './shared.js'
|
|
13
|
-
import { execQuery, transformEntryRow } from './shared.js'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get template resource definitions
|
|
17
|
-
*/
|
|
18
|
-
export function getTemplateResourceDefinitions(): InternalResourceDef[] {
|
|
19
|
-
return [
|
|
20
|
-
{
|
|
21
|
-
uri: 'memory://projects/{number}/timeline',
|
|
22
|
-
name: 'Project Timeline',
|
|
23
|
-
title: 'Project Activity Timeline',
|
|
24
|
-
description: 'Project activity timeline',
|
|
25
|
-
mimeType: 'application/json',
|
|
26
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
27
|
-
handler: (uri: string, context: ResourceContext) => {
|
|
28
|
-
const match = /memory:\/\/projects\/(\d+)\/timeline/.exec(uri)
|
|
29
|
-
const projectNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
30
|
-
|
|
31
|
-
if (projectNumber === null) {
|
|
32
|
-
return { error: 'Invalid project number' }
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const rows = execQuery(
|
|
36
|
-
context.db,
|
|
37
|
-
`
|
|
38
|
-
SELECT ${ENTRY_COLUMNS} FROM memory_journal
|
|
39
|
-
WHERE project_number = ?
|
|
40
|
-
AND deleted_at IS NULL
|
|
41
|
-
ORDER BY timestamp DESC
|
|
42
|
-
LIMIT 50
|
|
43
|
-
`,
|
|
44
|
-
[projectNumber]
|
|
45
|
-
)
|
|
46
|
-
const entries = rows.map(transformEntryRow)
|
|
47
|
-
return { projectNumber, entries, count: entries.length }
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
uri: 'memory://issues/{issue_number}/entries',
|
|
52
|
-
name: 'Issue Entries',
|
|
53
|
-
title: 'Entries Linked to Issue',
|
|
54
|
-
description: 'All entries linked to a specific issue',
|
|
55
|
-
mimeType: 'application/json',
|
|
56
|
-
icons: [ICON_ISSUE],
|
|
57
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
58
|
-
handler: (uri: string, context: ResourceContext) => {
|
|
59
|
-
const match = /memory:\/\/issues\/(\d+)\/entries/.exec(uri)
|
|
60
|
-
const issueNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
61
|
-
|
|
62
|
-
if (issueNumber === null) {
|
|
63
|
-
return { error: 'Invalid issue number' }
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const rows = execQuery(
|
|
67
|
-
context.db,
|
|
68
|
-
`
|
|
69
|
-
SELECT ${ENTRY_COLUMNS} FROM memory_journal
|
|
70
|
-
WHERE issue_number = ?
|
|
71
|
-
AND deleted_at IS NULL
|
|
72
|
-
ORDER BY timestamp DESC
|
|
73
|
-
`,
|
|
74
|
-
[issueNumber]
|
|
75
|
-
)
|
|
76
|
-
const entries = rows.map(transformEntryRow)
|
|
77
|
-
return { issueNumber, entries, count: entries.length }
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
uri: 'memory://prs/{pr_number}/entries',
|
|
82
|
-
name: 'PR Entries',
|
|
83
|
-
title: 'Entries Linked to PR',
|
|
84
|
-
description: 'All entries linked to a specific pull request',
|
|
85
|
-
mimeType: 'application/json',
|
|
86
|
-
icons: [ICON_PR],
|
|
87
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
88
|
-
handler: (uri: string, context: ResourceContext) => {
|
|
89
|
-
const match = /memory:\/\/prs\/(\d+)\/entries/.exec(uri)
|
|
90
|
-
const prNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
91
|
-
|
|
92
|
-
if (prNumber === null) {
|
|
93
|
-
return { error: 'Invalid PR number' }
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const rows = execQuery(
|
|
97
|
-
context.db,
|
|
98
|
-
`
|
|
99
|
-
SELECT ${ENTRY_COLUMNS} FROM memory_journal
|
|
100
|
-
WHERE pr_number = ?
|
|
101
|
-
AND deleted_at IS NULL
|
|
102
|
-
ORDER BY timestamp DESC
|
|
103
|
-
`,
|
|
104
|
-
[prNumber]
|
|
105
|
-
)
|
|
106
|
-
const entries = rows.map(transformEntryRow)
|
|
107
|
-
return {
|
|
108
|
-
prNumber,
|
|
109
|
-
entries,
|
|
110
|
-
count: entries.length,
|
|
111
|
-
...(entries.length === 0
|
|
112
|
-
? {
|
|
113
|
-
hint: 'No journal entries linked to this PR. Use create_entry with pr_number to link entries.',
|
|
114
|
-
}
|
|
115
|
-
: {}),
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
uri: 'memory://prs/{pr_number}/timeline',
|
|
121
|
-
name: 'PR Timeline',
|
|
122
|
-
title: 'Combined PR and Journal Timeline',
|
|
123
|
-
description: 'Combined PR + journal timeline with live PR metadata',
|
|
124
|
-
mimeType: 'application/json',
|
|
125
|
-
icons: [ICON_PR],
|
|
126
|
-
annotations: ASSISTANT_FOCUSED,
|
|
127
|
-
handler: async (uri: string, context: ResourceContext) => {
|
|
128
|
-
const match = /memory:\/\/prs\/(\d+)\/timeline/.exec(uri)
|
|
129
|
-
const prNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
130
|
-
|
|
131
|
-
if (prNumber === null) {
|
|
132
|
-
return { error: 'Invalid PR number' }
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Fetch live PR metadata from GitHub if available
|
|
136
|
-
let prMetadata: {
|
|
137
|
-
title: string
|
|
138
|
-
state: string
|
|
139
|
-
draft: boolean
|
|
140
|
-
mergedAt: string | null
|
|
141
|
-
closedAt: string | null
|
|
142
|
-
author: string
|
|
143
|
-
headBranch: string
|
|
144
|
-
baseBranch: string
|
|
145
|
-
} | null = null
|
|
146
|
-
|
|
147
|
-
if (context.github) {
|
|
148
|
-
try {
|
|
149
|
-
const repoInfo = await context.github.getRepoInfo()
|
|
150
|
-
if (repoInfo.owner && repoInfo.repo) {
|
|
151
|
-
const pr = await context.github.getPullRequest(
|
|
152
|
-
repoInfo.owner,
|
|
153
|
-
repoInfo.repo,
|
|
154
|
-
prNumber
|
|
155
|
-
)
|
|
156
|
-
if (pr) {
|
|
157
|
-
prMetadata = {
|
|
158
|
-
title: pr.title,
|
|
159
|
-
state: pr.state,
|
|
160
|
-
draft: pr.draft,
|
|
161
|
-
mergedAt: pr.mergedAt,
|
|
162
|
-
closedAt: pr.closedAt,
|
|
163
|
-
author: pr.author,
|
|
164
|
-
headBranch: pr.headBranch,
|
|
165
|
-
baseBranch: pr.baseBranch,
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
} catch {
|
|
170
|
-
// GitHub not available, proceed without metadata
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const rows = execQuery(
|
|
175
|
-
context.db,
|
|
176
|
-
`
|
|
177
|
-
SELECT ${ENTRY_COLUMNS} FROM memory_journal
|
|
178
|
-
WHERE pr_number = ?
|
|
179
|
-
AND deleted_at IS NULL
|
|
180
|
-
ORDER BY timestamp DESC
|
|
181
|
-
`,
|
|
182
|
-
[prNumber]
|
|
183
|
-
)
|
|
184
|
-
const entries = rows.map(transformEntryRow)
|
|
185
|
-
|
|
186
|
-
let timelineNote: string
|
|
187
|
-
if (prMetadata) {
|
|
188
|
-
const stateDesc = prMetadata.state.toLowerCase()
|
|
189
|
-
const mergedNote = prMetadata.mergedAt ? ' (merged)' : ''
|
|
190
|
-
const draftNote = prMetadata.draft ? ' [DRAFT]' : ''
|
|
191
|
-
timelineNote = `PR #${String(prNumber)} is ${stateDesc}${mergedNote}${draftNote}`
|
|
192
|
-
} else {
|
|
193
|
-
timelineNote =
|
|
194
|
-
'GitHub integration unavailable for live PR status. Entry timestamps show journal activity.'
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
prNumber,
|
|
199
|
-
prMetadata,
|
|
200
|
-
entries,
|
|
201
|
-
count: entries.length,
|
|
202
|
-
timelineNote,
|
|
203
|
-
...(entries.length === 0
|
|
204
|
-
? {
|
|
205
|
-
hint: 'No journal entries linked to this PR. Use create_entry with pr_number to link entries.',
|
|
206
|
-
}
|
|
207
|
-
: {}),
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
// Kanban board resources (GitHub Projects v2)
|
|
212
|
-
{
|
|
213
|
-
uri: 'memory://kanban/{project_number}',
|
|
214
|
-
name: 'Kanban Board',
|
|
215
|
-
title: 'GitHub Project Kanban Board',
|
|
216
|
-
description: 'View a GitHub Project v2 as a Kanban board with items grouped by Status',
|
|
217
|
-
mimeType: 'application/json',
|
|
218
|
-
annotations: { ...MEDIUM_PRIORITY, audience: ['assistant'] },
|
|
219
|
-
handler: async (uri: string, context: ResourceContext) => {
|
|
220
|
-
const match = /memory:\/\/kanban\/(\d+)/.exec(uri)
|
|
221
|
-
const projectNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
222
|
-
|
|
223
|
-
if (projectNumber === null) {
|
|
224
|
-
return { error: 'Invalid project number' }
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (!context.github) {
|
|
228
|
-
return {
|
|
229
|
-
error: 'GitHub integration not available',
|
|
230
|
-
hint: 'Set GITHUB_TOKEN and GITHUB_REPO_PATH environment variables.',
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const repoInfo = await context.github.getRepoInfo()
|
|
235
|
-
const owner = repoInfo.owner
|
|
236
|
-
const repo = repoInfo.repo ?? undefined
|
|
237
|
-
|
|
238
|
-
if (!owner) {
|
|
239
|
-
return {
|
|
240
|
-
error: 'Could not detect repository owner',
|
|
241
|
-
hint: 'Set GITHUB_REPO_PATH to your git repository.',
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const board = await context.github.getProjectKanban(owner, projectNumber, repo)
|
|
246
|
-
if (!board) {
|
|
247
|
-
return {
|
|
248
|
-
error: `Project #${String(projectNumber)} not found or Status field not configured`,
|
|
249
|
-
projectNumber,
|
|
250
|
-
owner,
|
|
251
|
-
hint: 'Projects can be at user, repository, or organization level.',
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return board
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
uri: 'memory://kanban/{project_number}/diagram',
|
|
260
|
-
name: 'Kanban Diagram',
|
|
261
|
-
title: 'Kanban Board Mermaid Diagram',
|
|
262
|
-
description: 'Mermaid diagram visualization of a GitHub Project Kanban board',
|
|
263
|
-
mimeType: 'text/plain',
|
|
264
|
-
annotations: MEDIUM_PRIORITY,
|
|
265
|
-
handler: async (uri: string, context: ResourceContext) => {
|
|
266
|
-
const match = /memory:\/\/kanban\/(\d+)\/diagram/.exec(uri)
|
|
267
|
-
const projectNumber = match?.[1] ? parseInt(match[1], 10) : null
|
|
268
|
-
|
|
269
|
-
if (projectNumber === null) {
|
|
270
|
-
return { error: 'Invalid project number' }
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (!context.github) {
|
|
274
|
-
return 'graph LR\n NoGitHub["GitHub integration not available \u2014 set GITHUB_TOKEN and GITHUB_REPO_PATH"]'
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const repoInfo = await context.github.getRepoInfo()
|
|
278
|
-
const owner = repoInfo.owner
|
|
279
|
-
const repo = repoInfo.repo ?? undefined
|
|
280
|
-
|
|
281
|
-
if (!owner) {
|
|
282
|
-
return 'graph LR\n NoOwner["Repository owner not detected \u2014 set GITHUB_REPO_PATH"]'
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const board = await context.github.getProjectKanban(owner, projectNumber, repo)
|
|
286
|
-
if (!board) {
|
|
287
|
-
return `graph LR\n NotFound["Project #${String(projectNumber)} not found \u2014 ensure project exists with a Status field"]`
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Build Mermaid diagram with subgraphs for each column
|
|
291
|
-
const lines: string[] = ['graph LR']
|
|
292
|
-
|
|
293
|
-
lines.push(' classDef issue fill:#28a745,color:#fff')
|
|
294
|
-
lines.push(' classDef pr fill:#6f42c1,color:#fff')
|
|
295
|
-
lines.push(' classDef draft fill:#6c757d,color:#fff')
|
|
296
|
-
|
|
297
|
-
for (const column of board.columns) {
|
|
298
|
-
const safeStatus = column.status.replace(/["\s]/g, '_')
|
|
299
|
-
lines.push(
|
|
300
|
-
` subgraph ${safeStatus}["${column.status} (${String(column.items.length)})"]`
|
|
301
|
-
)
|
|
302
|
-
|
|
303
|
-
for (const item of column.items) {
|
|
304
|
-
const safeId = item.id.replace(/[^a-zA-Z0-9]/g, '').slice(-8)
|
|
305
|
-
const label = item.title.slice(0, 25).replace(/["[\]]/g, "'")
|
|
306
|
-
const typeIcon =
|
|
307
|
-
item.type === 'ISSUE'
|
|
308
|
-
? '🔵'
|
|
309
|
-
: item.type === 'PULL_REQUEST'
|
|
310
|
-
? '🟣'
|
|
311
|
-
: '⚪'
|
|
312
|
-
const numberStr =
|
|
313
|
-
item.number !== undefined && item.number !== 0
|
|
314
|
-
? `#${String(item.number)}`
|
|
315
|
-
: ''
|
|
316
|
-
lines.push(` I${safeId}["${typeIcon} ${numberStr} ${label}..."]`)
|
|
317
|
-
|
|
318
|
-
const typeClass =
|
|
319
|
-
item.type === 'ISSUE'
|
|
320
|
-
? 'issue'
|
|
321
|
-
: item.type === 'PULL_REQUEST'
|
|
322
|
-
? 'pr'
|
|
323
|
-
: 'draft'
|
|
324
|
-
lines.push(` class I${safeId} ${typeClass}`)
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
lines.push(' end')
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return lines.join('\n')
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
]
|
|
334
|
-
}
|
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin Tool Group - 5 tools
|
|
3
|
-
*
|
|
4
|
-
* Tools: update_entry, delete_entry, merge_tags, rebuild_vector_index, add_to_vector_index
|
|
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 { autoIndexEntry } from '../../utils/vector-index-helpers.js'
|
|
11
|
-
import { ENTRY_TYPES, EntryOutputSchema, relaxedNumber } from './schemas.js'
|
|
12
|
-
import { ErrorFieldsMixin } from './error-fields-mixin.js'
|
|
13
|
-
|
|
14
|
-
// ============================================================================
|
|
15
|
-
// Input Schemas
|
|
16
|
-
// ============================================================================
|
|
17
|
-
|
|
18
|
-
/** Strict schema — used inside handler for structured Zod errors */
|
|
19
|
-
const UpdateEntrySchema = z.object({
|
|
20
|
-
entry_id: z.number(),
|
|
21
|
-
content: z.string().optional(),
|
|
22
|
-
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
23
|
-
is_personal: z.boolean().optional(),
|
|
24
|
-
tags: z.array(z.string()).optional(),
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
/** Relaxed schema — passed to SDK inputSchema so Zod enum errors reach the handler */
|
|
28
|
-
const UpdateEntrySchemaMcp = z.object({
|
|
29
|
-
entry_id: relaxedNumber(),
|
|
30
|
-
content: z.string().optional(),
|
|
31
|
-
entry_type: z.string().optional(),
|
|
32
|
-
is_personal: z.boolean().optional(),
|
|
33
|
-
tags: z.array(z.string()).optional(),
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const DeleteEntrySchema = z.object({
|
|
37
|
-
entry_id: z.number(),
|
|
38
|
-
permanent: z.boolean().optional().default(false),
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
/** Relaxed schema — passed to SDK inputSchema so type coercion errors reach the handler */
|
|
42
|
-
const DeleteEntrySchemaMcp = z.object({
|
|
43
|
-
entry_id: relaxedNumber(),
|
|
44
|
-
permanent: z.boolean().optional().default(false),
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// ============================================================================
|
|
48
|
-
// Output Schemas
|
|
49
|
-
// ============================================================================
|
|
50
|
-
|
|
51
|
-
const UpdateEntryOutputSchema = z
|
|
52
|
-
.object({
|
|
53
|
-
success: z.boolean().optional(),
|
|
54
|
-
entry: EntryOutputSchema.optional(),
|
|
55
|
-
error: z.string().optional(),
|
|
56
|
-
})
|
|
57
|
-
.extend(ErrorFieldsMixin.shape)
|
|
58
|
-
|
|
59
|
-
const DeleteEntryOutputSchema = z
|
|
60
|
-
.object({
|
|
61
|
-
success: z.boolean().optional(),
|
|
62
|
-
entryId: z.number().optional(),
|
|
63
|
-
permanent: z.boolean().optional(),
|
|
64
|
-
error: z.string().optional(),
|
|
65
|
-
})
|
|
66
|
-
.extend(ErrorFieldsMixin.shape)
|
|
67
|
-
|
|
68
|
-
const MergeTagsOutputSchema = z
|
|
69
|
-
.object({
|
|
70
|
-
success: z.boolean().optional(),
|
|
71
|
-
sourceTag: z.string().optional(),
|
|
72
|
-
targetTag: z.string().optional(),
|
|
73
|
-
entriesUpdated: z.number().optional(),
|
|
74
|
-
sourceDeleted: z.boolean().optional(),
|
|
75
|
-
message: z.string().optional(),
|
|
76
|
-
error: z.string().optional(),
|
|
77
|
-
})
|
|
78
|
-
.extend(ErrorFieldsMixin.shape)
|
|
79
|
-
|
|
80
|
-
const RebuildVectorIndexOutputSchema = z
|
|
81
|
-
.object({
|
|
82
|
-
success: z.boolean().optional(),
|
|
83
|
-
entriesIndexed: z.number().optional(),
|
|
84
|
-
failedEntries: z.number().optional(),
|
|
85
|
-
error: z.string().optional(),
|
|
86
|
-
})
|
|
87
|
-
.extend(ErrorFieldsMixin.shape)
|
|
88
|
-
|
|
89
|
-
const AddToVectorIndexOutputSchema = z
|
|
90
|
-
.object({
|
|
91
|
-
success: z.boolean().optional(),
|
|
92
|
-
entryId: z.number().optional(),
|
|
93
|
-
error: z.string().optional(),
|
|
94
|
-
})
|
|
95
|
-
.extend(ErrorFieldsMixin.shape)
|
|
96
|
-
|
|
97
|
-
// ============================================================================
|
|
98
|
-
// Tool Definitions
|
|
99
|
-
// ============================================================================
|
|
100
|
-
|
|
101
|
-
export function getAdminTools(context: ToolContext): ToolDefinition[] {
|
|
102
|
-
const { db, vectorManager, progress } = context
|
|
103
|
-
return [
|
|
104
|
-
{
|
|
105
|
-
name: 'update_entry',
|
|
106
|
-
title: 'Update Entry',
|
|
107
|
-
description: 'Update an existing journal entry',
|
|
108
|
-
group: 'admin',
|
|
109
|
-
inputSchema: UpdateEntrySchemaMcp,
|
|
110
|
-
outputSchema: UpdateEntryOutputSchema,
|
|
111
|
-
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
|
|
112
|
-
handler: (params: unknown) => {
|
|
113
|
-
try {
|
|
114
|
-
const input = UpdateEntrySchema.parse(params)
|
|
115
|
-
const entry = db.updateEntry(input.entry_id, {
|
|
116
|
-
content: input.content,
|
|
117
|
-
entryType: input.entry_type,
|
|
118
|
-
isPersonal: input.is_personal,
|
|
119
|
-
tags: input.tags,
|
|
120
|
-
})
|
|
121
|
-
if (!entry) {
|
|
122
|
-
return {
|
|
123
|
-
success: false,
|
|
124
|
-
error: `Entry ${String(input.entry_id)} not found`,
|
|
125
|
-
code: 'RESOURCE_NOT_FOUND',
|
|
126
|
-
category: 'resource',
|
|
127
|
-
suggestion: 'Verify the entry ID and try again',
|
|
128
|
-
recoverable: true,
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Re-index if content changed
|
|
133
|
-
if (input.content) {
|
|
134
|
-
autoIndexEntry(vectorManager, entry.id, entry.content)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return { success: true, entry }
|
|
138
|
-
} catch (err) {
|
|
139
|
-
return formatHandlerError(err)
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: 'delete_entry',
|
|
145
|
-
title: 'Delete Entry',
|
|
146
|
-
description: 'Delete a journal entry (soft delete with timestamp)',
|
|
147
|
-
group: 'admin',
|
|
148
|
-
inputSchema: DeleteEntrySchemaMcp,
|
|
149
|
-
outputSchema: DeleteEntryOutputSchema,
|
|
150
|
-
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
|
|
151
|
-
handler: (params: unknown) => {
|
|
152
|
-
try {
|
|
153
|
-
const { entry_id, permanent } = DeleteEntrySchema.parse(params)
|
|
154
|
-
const success = db.deleteEntry(entry_id, permanent)
|
|
155
|
-
|
|
156
|
-
if (!success) {
|
|
157
|
-
return {
|
|
158
|
-
success: false,
|
|
159
|
-
entryId: entry_id,
|
|
160
|
-
permanent,
|
|
161
|
-
error: `Entry ${String(entry_id)} not found`,
|
|
162
|
-
code: 'RESOURCE_NOT_FOUND',
|
|
163
|
-
category: 'resource',
|
|
164
|
-
suggestion: 'Verify the entry ID and try again',
|
|
165
|
-
recoverable: true,
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Remove from vector index (non-critical if fails)
|
|
170
|
-
if (vectorManager) {
|
|
171
|
-
try {
|
|
172
|
-
vectorManager.removeEntry(entry_id)
|
|
173
|
-
} catch {
|
|
174
|
-
// Non-critical failure, entry already deleted from DB
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return { success, entryId: entry_id, permanent }
|
|
179
|
-
} catch (err) {
|
|
180
|
-
return formatHandlerError(err)
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: 'merge_tags',
|
|
186
|
-
title: 'Merge Tags',
|
|
187
|
-
description:
|
|
188
|
-
'Merge one tag into another to consolidate similar tags (e.g., merge "phase-2" into "phase2"). The source tag is deleted after merge.',
|
|
189
|
-
group: 'admin',
|
|
190
|
-
inputSchema: z.object({
|
|
191
|
-
source_tag: z.string().min(1).describe('Tag to merge from (will be deleted)'),
|
|
192
|
-
target_tag: z
|
|
193
|
-
.string()
|
|
194
|
-
.min(1)
|
|
195
|
-
.describe('Tag to merge into (will be created if not exists)'),
|
|
196
|
-
}),
|
|
197
|
-
outputSchema: MergeTagsOutputSchema,
|
|
198
|
-
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
|
|
199
|
-
handler: (params: unknown) => {
|
|
200
|
-
try {
|
|
201
|
-
const { source_tag, target_tag } = z
|
|
202
|
-
.object({
|
|
203
|
-
source_tag: z.string().min(1),
|
|
204
|
-
target_tag: z.string().min(1),
|
|
205
|
-
})
|
|
206
|
-
.parse(params)
|
|
207
|
-
|
|
208
|
-
if (source_tag === target_tag) {
|
|
209
|
-
return {
|
|
210
|
-
success: false,
|
|
211
|
-
sourceTag: source_tag,
|
|
212
|
-
targetTag: target_tag,
|
|
213
|
-
entriesUpdated: 0,
|
|
214
|
-
sourceDeleted: false,
|
|
215
|
-
message: 'Source and target tags cannot be the same',
|
|
216
|
-
error: 'Source and target tags must be different',
|
|
217
|
-
code: 'VALIDATION_ERROR',
|
|
218
|
-
category: 'validation',
|
|
219
|
-
suggestion: 'Provide two different tag names',
|
|
220
|
-
recoverable: true,
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const result = db.mergeTags(source_tag, target_tag)
|
|
225
|
-
return {
|
|
226
|
-
success: true,
|
|
227
|
-
sourceTag: source_tag,
|
|
228
|
-
targetTag: target_tag,
|
|
229
|
-
entriesUpdated: result.entriesUpdated,
|
|
230
|
-
sourceDeleted: result.sourceDeleted,
|
|
231
|
-
message: `Merged "${source_tag}" into "${target_tag}". Updated ${String(result.entriesUpdated)} entries.`,
|
|
232
|
-
}
|
|
233
|
-
} catch (error) {
|
|
234
|
-
// Zod or domain error
|
|
235
|
-
if (error instanceof z.ZodError) {
|
|
236
|
-
return formatHandlerError(error)
|
|
237
|
-
}
|
|
238
|
-
// Domain error from db.mergeTags — try to preserve schema shape
|
|
239
|
-
try {
|
|
240
|
-
const parsed = z
|
|
241
|
-
.object({ source_tag: z.string(), target_tag: z.string() })
|
|
242
|
-
.parse(params)
|
|
243
|
-
return {
|
|
244
|
-
success: false,
|
|
245
|
-
sourceTag: parsed.source_tag,
|
|
246
|
-
targetTag: parsed.target_tag,
|
|
247
|
-
entriesUpdated: 0,
|
|
248
|
-
sourceDeleted: false,
|
|
249
|
-
message: 'Tag merge failed',
|
|
250
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
251
|
-
code: 'RESOURCE_NOT_FOUND',
|
|
252
|
-
category: 'resource',
|
|
253
|
-
suggestion: 'Verify the source tag exists using list_tags',
|
|
254
|
-
recoverable: true,
|
|
255
|
-
}
|
|
256
|
-
} catch {
|
|
257
|
-
return formatHandlerError(error)
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
name: 'rebuild_vector_index',
|
|
264
|
-
title: 'Rebuild Vector Index',
|
|
265
|
-
description: 'Rebuild the semantic search vector index from all existing entries',
|
|
266
|
-
group: 'admin',
|
|
267
|
-
inputSchema: z.object({}).strict(),
|
|
268
|
-
outputSchema: RebuildVectorIndexOutputSchema,
|
|
269
|
-
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
|
|
270
|
-
handler: async (_params: unknown) => {
|
|
271
|
-
try {
|
|
272
|
-
if (!vectorManager) {
|
|
273
|
-
return {
|
|
274
|
-
success: false,
|
|
275
|
-
entriesIndexed: 0,
|
|
276
|
-
error: 'Vector search not available',
|
|
277
|
-
code: 'CONFIGURATION_ERROR',
|
|
278
|
-
category: 'configuration',
|
|
279
|
-
suggestion:
|
|
280
|
-
'Enable semantic search with --auto-rebuild-index or set up the vector manager',
|
|
281
|
-
recoverable: false,
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
const { indexed, failed, firstError } = await vectorManager.rebuildIndex(
|
|
285
|
-
db,
|
|
286
|
-
progress
|
|
287
|
-
)
|
|
288
|
-
const success = indexed > 0 || failed === 0
|
|
289
|
-
return {
|
|
290
|
-
success,
|
|
291
|
-
entriesIndexed: indexed,
|
|
292
|
-
...(failed > 0 ? { failedEntries: failed } : {}),
|
|
293
|
-
...(!success
|
|
294
|
-
? { error: firstError ?? 'All entries failed to generate embeddings' }
|
|
295
|
-
: {}),
|
|
296
|
-
}
|
|
297
|
-
} catch (err) {
|
|
298
|
-
return formatHandlerError(err)
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
name: 'add_to_vector_index',
|
|
304
|
-
title: 'Add Entry to Vector Index',
|
|
305
|
-
description: 'Add a specific entry to the semantic search vector index',
|
|
306
|
-
group: 'admin',
|
|
307
|
-
inputSchema: z.object({ entry_id: relaxedNumber() }),
|
|
308
|
-
outputSchema: AddToVectorIndexOutputSchema,
|
|
309
|
-
annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
|
|
310
|
-
handler: async (params: unknown) => {
|
|
311
|
-
try {
|
|
312
|
-
const { entry_id } = z.object({ entry_id: z.number() }).parse(params)
|
|
313
|
-
if (!vectorManager) {
|
|
314
|
-
return {
|
|
315
|
-
success: false,
|
|
316
|
-
entryId: entry_id,
|
|
317
|
-
error: 'Vector search not available',
|
|
318
|
-
code: 'CONFIGURATION_ERROR',
|
|
319
|
-
category: 'configuration',
|
|
320
|
-
suggestion:
|
|
321
|
-
'Enable semantic search with --auto-rebuild-index or set up the vector manager',
|
|
322
|
-
recoverable: false,
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
const entry = db.getEntryById(entry_id)
|
|
326
|
-
if (!entry) {
|
|
327
|
-
return {
|
|
328
|
-
success: false,
|
|
329
|
-
entryId: entry_id,
|
|
330
|
-
error: `Entry ${String(entry_id)} not found`,
|
|
331
|
-
code: 'RESOURCE_NOT_FOUND',
|
|
332
|
-
category: 'resource',
|
|
333
|
-
suggestion: 'Verify the entry ID and try again',
|
|
334
|
-
recoverable: true,
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
const result = await vectorManager.addEntry(entry_id, entry.content)
|
|
338
|
-
return {
|
|
339
|
-
success: result.success,
|
|
340
|
-
entryId: entry_id,
|
|
341
|
-
...(result.success
|
|
342
|
-
? {}
|
|
343
|
-
: { error: result.error ?? 'Failed to generate or store embedding' }),
|
|
344
|
-
}
|
|
345
|
-
} catch (err) {
|
|
346
|
-
return formatHandlerError(err)
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
]
|
|
351
|
-
}
|