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,281 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resource Handler Coverage Tests — Targeted Gap Closure
|
|
3
|
-
*
|
|
4
|
-
* Tests for remaining uncovered lines in:
|
|
5
|
-
* - handlers/resources/index.ts: getBaseUri non-memory URL, template match + ResourceResult
|
|
6
|
-
* - handlers/resources/templates.ts: invalid params for template resources
|
|
7
|
-
* - handlers/resources/core.ts: CI status branches, scheduler section
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
|
|
11
|
-
import { readResource } from '../../src/handlers/resources/index.js'
|
|
12
|
-
import { DatabaseAdapter } from '../../src/database/sqlite-adapter/index.js'
|
|
13
|
-
|
|
14
|
-
describe('Resource Handler Coverage', () => {
|
|
15
|
-
let db: DatabaseAdapter
|
|
16
|
-
const testDbPath = './test-resource-coverage.db'
|
|
17
|
-
|
|
18
|
-
beforeAll(async () => {
|
|
19
|
-
db = new DatabaseAdapter(testDbPath)
|
|
20
|
-
await db.initialize()
|
|
21
|
-
|
|
22
|
-
// Create entries with project/issue/PR links for template tests
|
|
23
|
-
db.createEntry({
|
|
24
|
-
content: 'Resource coverage test entry',
|
|
25
|
-
tags: ['resource-test'],
|
|
26
|
-
projectNumber: 42,
|
|
27
|
-
issueNumber: 7,
|
|
28
|
-
prNumber: 3,
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
afterAll(() => {
|
|
33
|
-
db.close()
|
|
34
|
-
try {
|
|
35
|
-
const fs = require('node:fs')
|
|
36
|
-
if (fs.existsSync(testDbPath)) fs.unlinkSync(testDbPath)
|
|
37
|
-
} catch {
|
|
38
|
-
// cleanup
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// ========================================================================
|
|
43
|
-
// handlers/resources/index.ts — getBaseUri, template matching
|
|
44
|
-
// ========================================================================
|
|
45
|
-
|
|
46
|
-
describe('readResource - base URI parsing', () => {
|
|
47
|
-
it('should handle memory:// URIs with query parameters', async () => {
|
|
48
|
-
const result = await readResource('memory://recent?limit=5&format=brief', db)
|
|
49
|
-
expect(result.data).toBeDefined()
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should throw for unknown resource URI', async () => {
|
|
53
|
-
await expect(readResource('memory://nonexistent-resource-xyz', db)).rejects.toThrow(
|
|
54
|
-
'Resource not found: memory://nonexistent-resource-xyz'
|
|
55
|
-
)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('should throw for non-memory URI schemes', async () => {
|
|
59
|
-
await expect(readResource('https://example.com/unknown', db)).rejects.toThrow(
|
|
60
|
-
'Resource not found: https://example.com/unknown'
|
|
61
|
-
)
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
// ========================================================================
|
|
66
|
-
// handlers/resources/templates.ts — invalid template params (lines 33, 67, 100)
|
|
67
|
-
// ========================================================================
|
|
68
|
-
|
|
69
|
-
describe('template resources — invalid params', () => {
|
|
70
|
-
it('should return error for invalid project timeline number', async () => {
|
|
71
|
-
const result = await readResource('memory://projects/abc/timeline', db)
|
|
72
|
-
expect(result.data).toHaveProperty('error')
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('should return entries for valid project timeline', async () => {
|
|
76
|
-
const result = await readResource('memory://projects/42/timeline', db)
|
|
77
|
-
const data = result.data as { projectNumber: number; entries: unknown[] }
|
|
78
|
-
expect(data.projectNumber).toBe(42)
|
|
79
|
-
expect(data.entries).toBeDefined()
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('should return error for invalid issue entries number', async () => {
|
|
83
|
-
const result = await readResource('memory://issues/abc/entries', db)
|
|
84
|
-
expect(result.data).toHaveProperty('error')
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('should return entries for valid issue entries', async () => {
|
|
88
|
-
const result = await readResource('memory://issues/7/entries', db)
|
|
89
|
-
const data = result.data as { issueNumber: number; entries: unknown[] }
|
|
90
|
-
expect(data.issueNumber).toBe(7)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('should return error for invalid PR entries number', async () => {
|
|
94
|
-
const result = await readResource('memory://prs/abc/entries', db)
|
|
95
|
-
expect(result.data).toHaveProperty('error')
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('should return entries for valid PR entries', async () => {
|
|
99
|
-
const result = await readResource('memory://prs/3/entries', db)
|
|
100
|
-
const data = result.data as { prNumber: number; entries: unknown[] }
|
|
101
|
-
expect(data.prNumber).toBe(3)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('should return error for invalid PR timeline number', async () => {
|
|
105
|
-
const result = await readResource('memory://prs/abc/timeline', db)
|
|
106
|
-
expect(result.data).toHaveProperty('error')
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('should return timeline without GitHub for valid PR', async () => {
|
|
110
|
-
const result = await readResource('memory://prs/3/timeline', db)
|
|
111
|
-
const data = result.data as {
|
|
112
|
-
prNumber: number
|
|
113
|
-
prMetadata: null
|
|
114
|
-
timelineNote: string
|
|
115
|
-
}
|
|
116
|
-
expect(data.prNumber).toBe(3)
|
|
117
|
-
expect(data.prMetadata).toBeNull()
|
|
118
|
-
expect(data.timelineNote).toContain('unavailable')
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('should return error for invalid kanban project number', async () => {
|
|
122
|
-
const result = await readResource('memory://kanban/abc', db)
|
|
123
|
-
expect(result.data).toHaveProperty('error')
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it('should return error for kanban without github', async () => {
|
|
127
|
-
const result = await readResource('memory://kanban/1', db)
|
|
128
|
-
const data = result.data as { error: string }
|
|
129
|
-
expect(data.error).toContain('not available')
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it('should return error for invalid kanban diagram number', async () => {
|
|
133
|
-
const result = await readResource('memory://kanban/abc/diagram', db)
|
|
134
|
-
expect(result.data).toHaveProperty('error')
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('should return mermaid fallback for diagram without github', async () => {
|
|
138
|
-
const result = await readResource('memory://kanban/1/diagram', db)
|
|
139
|
-
expect(typeof result.data).toBe('string')
|
|
140
|
-
expect(result.data as string).toContain('not available')
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
// Note: health endpoint is served by HttpTransport, not as a memory:// resource.
|
|
145
|
-
|
|
146
|
-
// ========================================================================
|
|
147
|
-
// handlers/resources/core.ts — instructions resource
|
|
148
|
-
// ========================================================================
|
|
149
|
-
|
|
150
|
-
describe('core resources — instructions', () => {
|
|
151
|
-
it('should return instructions text', async () => {
|
|
152
|
-
const result = await readResource('memory://instructions', db)
|
|
153
|
-
expect(result.data).toBeDefined()
|
|
154
|
-
expect(typeof result.data).toBe('string')
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
// ========================================================================
|
|
159
|
-
// handlers/resources/core.ts — briefing resource
|
|
160
|
-
// ========================================================================
|
|
161
|
-
|
|
162
|
-
describe('core resources — briefing', () => {
|
|
163
|
-
it('should return briefing data', async () => {
|
|
164
|
-
const result = await readResource('memory://briefing', db)
|
|
165
|
-
expect(result.data).toBeDefined()
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
// ========================================================================
|
|
170
|
-
// handlers/resources/core.ts — recent with entry_type filter
|
|
171
|
-
// ========================================================================
|
|
172
|
-
|
|
173
|
-
describe('core resources — recent with filters', () => {
|
|
174
|
-
it('should return recent entries with query params', async () => {
|
|
175
|
-
const result = await readResource('memory://recent?limit=3', db)
|
|
176
|
-
const data = result.data as { entries: unknown[] }
|
|
177
|
-
expect(data.entries).toBeDefined()
|
|
178
|
-
})
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
// ========================================================================
|
|
182
|
-
// New optional resources — rules, workflows, skills
|
|
183
|
-
// ========================================================================
|
|
184
|
-
|
|
185
|
-
describe('core resources — memory://rules', () => {
|
|
186
|
-
it('should return configured:false when RULES_FILE_PATH is not set', async () => {
|
|
187
|
-
const originalEnv = process.env['RULES_FILE_PATH']
|
|
188
|
-
delete process.env['RULES_FILE_PATH']
|
|
189
|
-
|
|
190
|
-
const result = await readResource('memory://rules', db)
|
|
191
|
-
const data = result.data as { configured: boolean; message: string }
|
|
192
|
-
expect(data.configured).toBe(false)
|
|
193
|
-
expect(data.message).toContain('RULES_FILE_PATH')
|
|
194
|
-
|
|
195
|
-
// Restore
|
|
196
|
-
if (originalEnv !== undefined) process.env['RULES_FILE_PATH'] = originalEnv
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
it('should return error when RULES_FILE_PATH points to nonexistent file', async () => {
|
|
200
|
-
process.env['RULES_FILE_PATH'] = '/nonexistent/path/RULES.md'
|
|
201
|
-
|
|
202
|
-
const result = await readResource('memory://rules', db)
|
|
203
|
-
const data = result.data as { configured: boolean; error: string }
|
|
204
|
-
expect(data.configured).toBe(true)
|
|
205
|
-
expect(data.error).toBeDefined()
|
|
206
|
-
|
|
207
|
-
delete process.env['RULES_FILE_PATH']
|
|
208
|
-
})
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
describe('core resources — memory://workflows', () => {
|
|
212
|
-
it('should return configured:false when MEMORY_JOURNAL_WORKFLOW_SUMMARY is not set', async () => {
|
|
213
|
-
const originalEnv = process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY']
|
|
214
|
-
delete process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY']
|
|
215
|
-
|
|
216
|
-
const result = await readResource('memory://workflows', db)
|
|
217
|
-
const data = result.data as { configured: boolean; message: string }
|
|
218
|
-
expect(data.configured).toBe(false)
|
|
219
|
-
expect(data.message).toContain('MEMORY_JOURNAL_WORKFLOW_SUMMARY')
|
|
220
|
-
|
|
221
|
-
if (originalEnv !== undefined)
|
|
222
|
-
process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY'] = originalEnv
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
it('should return workflow summary when MEMORY_JOURNAL_WORKFLOW_SUMMARY is set', async () => {
|
|
226
|
-
process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY'] = 'deploy, release, audit'
|
|
227
|
-
|
|
228
|
-
const result = await readResource('memory://workflows', db)
|
|
229
|
-
const data = result.data as { configured: boolean; summary: string }
|
|
230
|
-
expect(data.configured).toBe(true)
|
|
231
|
-
expect(data.summary).toBe('deploy, release, audit')
|
|
232
|
-
|
|
233
|
-
delete process.env['MEMORY_JOURNAL_WORKFLOW_SUMMARY']
|
|
234
|
-
})
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
describe('core resources — memory://skills', () => {
|
|
238
|
-
it('should return configured:false when SKILLS_DIR_PATH is not set', async () => {
|
|
239
|
-
const originalEnv = process.env['SKILLS_DIR_PATH']
|
|
240
|
-
delete process.env['SKILLS_DIR_PATH']
|
|
241
|
-
|
|
242
|
-
const result = await readResource('memory://skills', db)
|
|
243
|
-
const data = result.data as { configured: boolean; message: string }
|
|
244
|
-
expect(data.configured).toBe(false)
|
|
245
|
-
expect(data.message).toContain('SKILLS_DIR_PATH')
|
|
246
|
-
|
|
247
|
-
// Restore
|
|
248
|
-
if (originalEnv !== undefined) process.env['SKILLS_DIR_PATH'] = originalEnv
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
it('should return error when SKILLS_DIR_PATH points to nonexistent directory', async () => {
|
|
252
|
-
process.env['SKILLS_DIR_PATH'] = '/nonexistent/skills/dir'
|
|
253
|
-
|
|
254
|
-
const result = await readResource('memory://skills', db)
|
|
255
|
-
const data = result.data as { configured: boolean; skills: unknown[]; count: number }
|
|
256
|
-
expect(data.configured).toBe(true)
|
|
257
|
-
expect(data.skills).toEqual([])
|
|
258
|
-
expect(data.count).toBe(0)
|
|
259
|
-
|
|
260
|
-
delete process.env['SKILLS_DIR_PATH']
|
|
261
|
-
})
|
|
262
|
-
|
|
263
|
-
it('should scan existing directory and return skill list', async () => {
|
|
264
|
-
// Point at the test server directory which has markdown files (no SKILL.md, so count=0)
|
|
265
|
-
process.env['SKILLS_DIR_PATH'] = './tests'
|
|
266
|
-
|
|
267
|
-
const result = await readResource('memory://skills', db)
|
|
268
|
-
const data = result.data as {
|
|
269
|
-
configured: boolean
|
|
270
|
-
skillsDir: string
|
|
271
|
-
skills: { name: string; path: string; excerpt: string }[]
|
|
272
|
-
count: number
|
|
273
|
-
}
|
|
274
|
-
expect(data.configured).toBe(true)
|
|
275
|
-
expect(data.skills).toBeDefined()
|
|
276
|
-
expect(typeof data.count).toBe('number')
|
|
277
|
-
|
|
278
|
-
delete process.env['SKILLS_DIR_PATH']
|
|
279
|
-
})
|
|
280
|
-
})
|
|
281
|
-
})
|
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resource Handler Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests getResources listing and readResource for non-GitHub resources.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
|
|
8
|
-
import { getResources, readResource } from '../../src/handlers/resources/index.js'
|
|
9
|
-
import { DatabaseAdapter } from '../../src/database/sqlite-adapter/index.js'
|
|
10
|
-
|
|
11
|
-
describe('Resource Handlers', () => {
|
|
12
|
-
let db: DatabaseAdapter
|
|
13
|
-
const testDbPath = './test-resources.db'
|
|
14
|
-
|
|
15
|
-
beforeAll(async () => {
|
|
16
|
-
db = new DatabaseAdapter(testDbPath)
|
|
17
|
-
await db.initialize()
|
|
18
|
-
|
|
19
|
-
// Seed test data
|
|
20
|
-
const e1 = db.createEntry({
|
|
21
|
-
content: 'Resource test entry alpha',
|
|
22
|
-
tags: ['res-tag'],
|
|
23
|
-
significanceType: 'milestone',
|
|
24
|
-
})
|
|
25
|
-
const e2 = db.createEntry({
|
|
26
|
-
content: 'Resource test entry beta',
|
|
27
|
-
isPersonal: false,
|
|
28
|
-
projectNumber: 42,
|
|
29
|
-
issueNumber: 7,
|
|
30
|
-
})
|
|
31
|
-
db.createEntry({
|
|
32
|
-
content: 'Resource test entry gamma',
|
|
33
|
-
prNumber: 15,
|
|
34
|
-
})
|
|
35
|
-
db.linkEntries(e1.id, e2.id, 'references', 'Related work')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
afterAll(() => {
|
|
39
|
-
db.close()
|
|
40
|
-
try {
|
|
41
|
-
const fs = require('node:fs')
|
|
42
|
-
if (fs.existsSync(testDbPath)) fs.unlinkSync(testDbPath)
|
|
43
|
-
} catch {
|
|
44
|
-
// Ignore cleanup errors
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
// ========================================================================
|
|
49
|
-
// getResources
|
|
50
|
-
// ========================================================================
|
|
51
|
-
|
|
52
|
-
describe('getResources', () => {
|
|
53
|
-
it('should return non-empty array of resource definitions', () => {
|
|
54
|
-
const resources = getResources()
|
|
55
|
-
expect(Array.isArray(resources)).toBe(true)
|
|
56
|
-
expect(resources.length).toBeGreaterThan(10)
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it('should have uri, name, and description on each resource', () => {
|
|
60
|
-
const resources = getResources()
|
|
61
|
-
for (const r of resources) {
|
|
62
|
-
const res = r as { uri: string; name: string; description: string }
|
|
63
|
-
expect(typeof res.uri).toBe('string')
|
|
64
|
-
expect(res.uri).toMatch(/^memory:\/\//)
|
|
65
|
-
expect(typeof res.name).toBe('string')
|
|
66
|
-
expect(typeof res.description).toBe('string')
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('should include known resource URIs', () => {
|
|
71
|
-
const resources = getResources()
|
|
72
|
-
const uris = resources.map((r) => (r as { uri: string }).uri)
|
|
73
|
-
|
|
74
|
-
expect(uris).toContain('memory://briefing')
|
|
75
|
-
expect(uris).toContain('memory://health')
|
|
76
|
-
expect(uris).toContain('memory://recent')
|
|
77
|
-
expect(uris).toContain('memory://significant')
|
|
78
|
-
expect(uris).toContain('memory://tags')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('should include template resources', () => {
|
|
82
|
-
const resources = getResources()
|
|
83
|
-
const uris = resources.map((r) => (r as { uri: string }).uri)
|
|
84
|
-
|
|
85
|
-
expect(uris).toContain('memory://projects/{number}/timeline')
|
|
86
|
-
expect(uris).toContain('memory://issues/{issue_number}/entries')
|
|
87
|
-
expect(uris).toContain('memory://prs/{pr_number}/entries')
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
// ========================================================================
|
|
92
|
-
// readResource - static resources
|
|
93
|
-
// ========================================================================
|
|
94
|
-
|
|
95
|
-
describe('readResource - static resources', () => {
|
|
96
|
-
it('should read memory://briefing', async () => {
|
|
97
|
-
const result = await readResource('memory://briefing', db)
|
|
98
|
-
|
|
99
|
-
expect(result.data).toBeDefined()
|
|
100
|
-
const data = result.data as {
|
|
101
|
-
version: string
|
|
102
|
-
journal: { totalEntries: number }
|
|
103
|
-
userMessage: string
|
|
104
|
-
}
|
|
105
|
-
expect(data.version).toBeDefined()
|
|
106
|
-
expect(data.journal.totalEntries).toBeGreaterThan(0)
|
|
107
|
-
expect(data.userMessage).toContain('Session Context')
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('should read memory://instructions', async () => {
|
|
111
|
-
const result = await readResource('memory://instructions', db)
|
|
112
|
-
|
|
113
|
-
expect(result.data).toBeDefined()
|
|
114
|
-
expect(typeof result.data).toBe('string')
|
|
115
|
-
expect(result.data as string).toContain('Session Start')
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('should show all tools in memory://instructions when no filter is set', async () => {
|
|
119
|
-
// Bug fix: when filterConfig is null (all tools enabled), memory://instructions
|
|
120
|
-
// must show Active Tools (39), not Active Tools (3) from the old hardcoded fallback
|
|
121
|
-
const result = await readResource('memory://instructions', db, undefined, null)
|
|
122
|
-
|
|
123
|
-
const text = result.data as string
|
|
124
|
-
expect(text).toContain('Active Tools (61)')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('should read memory://recent', async () => {
|
|
128
|
-
const result = await readResource('memory://recent', db)
|
|
129
|
-
|
|
130
|
-
const data = result.data as { entries: unknown[]; count: number }
|
|
131
|
-
expect(data.entries).toBeDefined()
|
|
132
|
-
expect(data.count).toBeGreaterThan(0)
|
|
133
|
-
expect(result.annotations?.lastModified).toBeDefined()
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('should read memory://significant', async () => {
|
|
137
|
-
const result = await readResource('memory://significant', db)
|
|
138
|
-
|
|
139
|
-
const data = result.data as { entries: unknown[]; count: number }
|
|
140
|
-
expect(data.entries).toBeDefined()
|
|
141
|
-
// We created an entry with significanceType='milestone'
|
|
142
|
-
expect(data.count).toBeGreaterThan(0)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('should sort memory://significant by importance descending, not by timestamp', async () => {
|
|
146
|
-
// Create 3 significant entries: e2 gets a relationship (higher importance), e3 gets 2 (highest)
|
|
147
|
-
const eBase = db.createEntry({ content: 'Sort test: base entry (no relationships)' })
|
|
148
|
-
const e1 = db.createEntry({
|
|
149
|
-
content: 'Sort test: sig entry 1 - no relationships',
|
|
150
|
-
significanceType: 'milestone',
|
|
151
|
-
})
|
|
152
|
-
const e2 = db.createEntry({
|
|
153
|
-
content: 'Sort test: sig entry 2 - one relationship',
|
|
154
|
-
significanceType: 'blocker_resolved',
|
|
155
|
-
})
|
|
156
|
-
const e3 = db.createEntry({
|
|
157
|
-
content: 'Sort test: sig entry 3 - two relationships',
|
|
158
|
-
significanceType: 'milestone',
|
|
159
|
-
})
|
|
160
|
-
// Give e2 one relationship, e3 two relationships → e3 should score highest
|
|
161
|
-
db.linkEntries(e2.id, eBase.id, 'references', 'One link')
|
|
162
|
-
db.linkEntries(e3.id, eBase.id, 'references', 'Link A')
|
|
163
|
-
db.linkEntries(e3.id, e1.id, 'references', 'Link B')
|
|
164
|
-
|
|
165
|
-
const result = await readResource('memory://significant', db)
|
|
166
|
-
const data = result.data as {
|
|
167
|
-
entries: { id: number; importance: number }[]
|
|
168
|
-
count: number
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// 1: importance field present on all entries
|
|
172
|
-
for (const entry of data.entries) {
|
|
173
|
-
expect(typeof entry.importance).toBe('number')
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// 2: entries sorted descending by importance (no entry should be less important than its successor)
|
|
177
|
-
for (let i = 1; i < data.entries.length; i++) {
|
|
178
|
-
const prev = data.entries[i - 1]!
|
|
179
|
-
const curr = data.entries[i]!
|
|
180
|
-
expect(prev.importance).toBeGreaterThanOrEqual(curr.importance)
|
|
181
|
-
}
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('should read memory://tags', async () => {
|
|
185
|
-
const result = await readResource('memory://tags', db)
|
|
186
|
-
|
|
187
|
-
const data = result.data as { tags: unknown[]; count: number }
|
|
188
|
-
expect(data.tags).toBeDefined()
|
|
189
|
-
expect(data.count).toBeGreaterThan(0)
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
it('should read memory://health', async () => {
|
|
193
|
-
const result = await readResource('memory://health', db)
|
|
194
|
-
|
|
195
|
-
const data = result.data as {
|
|
196
|
-
database: { entryCount: number }
|
|
197
|
-
toolFilter: { totalCount: number }
|
|
198
|
-
timestamp: string
|
|
199
|
-
}
|
|
200
|
-
expect(data.database.entryCount).toBeGreaterThan(0)
|
|
201
|
-
expect(data.toolFilter.totalCount).toBeGreaterThan(0)
|
|
202
|
-
expect(data.timestamp).toBeDefined()
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
it('should read memory://graph/recent', async () => {
|
|
206
|
-
const result = await readResource('memory://graph/recent', db)
|
|
207
|
-
|
|
208
|
-
expect(typeof result.data).toBe('string')
|
|
209
|
-
expect(result.data as string).toContain('graph TD')
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
it('should read memory://statistics', async () => {
|
|
213
|
-
const result = await readResource('memory://statistics', db)
|
|
214
|
-
|
|
215
|
-
const data = result.data as { totalEntries: number; entriesByType: object }
|
|
216
|
-
expect(data.totalEntries).toBeGreaterThan(0)
|
|
217
|
-
expect(data.entriesByType).toBeDefined()
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
// ========================================================================
|
|
222
|
-
// readResource - template resources
|
|
223
|
-
// ========================================================================
|
|
224
|
-
|
|
225
|
-
describe('readResource - template resources', () => {
|
|
226
|
-
it('should read memory://projects/{number}/timeline', async () => {
|
|
227
|
-
const result = await readResource('memory://projects/42/timeline', db)
|
|
228
|
-
|
|
229
|
-
const data = result.data as { projectNumber: number; entries: unknown[]; count: number }
|
|
230
|
-
expect(data.projectNumber).toBe(42)
|
|
231
|
-
expect(data.count).toBeGreaterThan(0)
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
it('should read memory://issues/{issue_number}/entries', async () => {
|
|
235
|
-
const result = await readResource('memory://issues/7/entries', db)
|
|
236
|
-
|
|
237
|
-
const data = result.data as { issueNumber: number; entries: unknown[]; count: number }
|
|
238
|
-
expect(data.issueNumber).toBe(7)
|
|
239
|
-
expect(data.count).toBeGreaterThan(0)
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
it('should read memory://prs/{pr_number}/entries', async () => {
|
|
243
|
-
const result = await readResource('memory://prs/15/entries', db)
|
|
244
|
-
|
|
245
|
-
const data = result.data as { prNumber: number; entries: unknown[]; count: number }
|
|
246
|
-
expect(data.prNumber).toBe(15)
|
|
247
|
-
expect(data.count).toBeGreaterThan(0)
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
it('should return empty for non-matching project', async () => {
|
|
251
|
-
const result = await readResource('memory://projects/99999/timeline', db)
|
|
252
|
-
|
|
253
|
-
const data = result.data as { count: number }
|
|
254
|
-
expect(data.count).toBe(0)
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
it('should handle empty PR entries with hint', async () => {
|
|
258
|
-
const result = await readResource('memory://prs/99999/entries', db)
|
|
259
|
-
|
|
260
|
-
const data = result.data as { count: number; hint?: string }
|
|
261
|
-
expect(data.count).toBe(0)
|
|
262
|
-
expect(data.hint).toContain('No journal entries')
|
|
263
|
-
})
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
// ========================================================================
|
|
267
|
-
// readResource - error cases
|
|
268
|
-
// ========================================================================
|
|
269
|
-
|
|
270
|
-
describe('readResource - error cases', () => {
|
|
271
|
-
it('should throw for unknown resource', async () => {
|
|
272
|
-
await expect(readResource('memory://nonexistent', db)).rejects.toThrow(
|
|
273
|
-
'Resource not found: memory://nonexistent'
|
|
274
|
-
)
|
|
275
|
-
})
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
// ========================================================================
|
|
279
|
-
// readResource - branch coverage for query params & variants
|
|
280
|
-
// ========================================================================
|
|
281
|
-
|
|
282
|
-
describe('readResource - additional branch coverage', () => {
|
|
283
|
-
it('should read memory://graph/actions', async () => {
|
|
284
|
-
const result = await readResource('memory://graph/actions', db)
|
|
285
|
-
|
|
286
|
-
expect(typeof result.data).toBe('string')
|
|
287
|
-
expect(result.data as string).toContain('graph')
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
it('should read memory://actions/recent', async () => {
|
|
291
|
-
const result = await readResource('memory://actions/recent', db)
|
|
292
|
-
|
|
293
|
-
const data = result.data as { entries: unknown[]; count: number }
|
|
294
|
-
expect(data.entries).toBeDefined()
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
it('should return briefing with expected structure', async () => {
|
|
298
|
-
const result = await readResource('memory://briefing', db)
|
|
299
|
-
const data = result.data as {
|
|
300
|
-
version: string
|
|
301
|
-
journal: { totalEntries: number }
|
|
302
|
-
behaviors: { create: string }
|
|
303
|
-
userMessage: string
|
|
304
|
-
templateResources: string[]
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
expect(data.behaviors.create).toContain('implementations')
|
|
308
|
-
expect(data.templateResources).toContain('memory://projects/{number}/timeline')
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
it('should return annotations on recent entries', async () => {
|
|
312
|
-
const result = await readResource('memory://recent', db)
|
|
313
|
-
|
|
314
|
-
expect(result.annotations).toBeDefined()
|
|
315
|
-
expect(result.annotations?.lastModified).toBeDefined()
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
it('should handle PR timeline template', async () => {
|
|
319
|
-
// PR 15 was seeded with an entry
|
|
320
|
-
const result = await readResource('memory://prs/15/timeline', db)
|
|
321
|
-
|
|
322
|
-
const data = result.data as { prNumber: number }
|
|
323
|
-
expect(data.prNumber).toBe(15)
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
it('should handle resource URI with query parameters', async () => {
|
|
327
|
-
// Query params should be stripped for matching but the full URI is passed to the handler
|
|
328
|
-
const result = await readResource('memory://recent?limit=5', db)
|
|
329
|
-
const data = result.data as { entries: unknown[]; count: number }
|
|
330
|
-
expect(data.entries).toBeDefined()
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
it('should handle resource URI with hash fragment', async () => {
|
|
334
|
-
const result = await readResource('memory://recent#section', db)
|
|
335
|
-
const data = result.data as { entries: unknown[]; count: number }
|
|
336
|
-
expect(data.entries).toBeDefined()
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
it('should handle template URI with query parameters', async () => {
|
|
340
|
-
const result = await readResource('memory://projects/42/timeline?sort=asc', db)
|
|
341
|
-
const data = result.data as { projectNumber: number }
|
|
342
|
-
expect(data.projectNumber).toBe(42)
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
it('should return no-github diagram for kanban without integration', async () => {
|
|
346
|
-
const result = await readResource(
|
|
347
|
-
'memory://kanban/1/diagram',
|
|
348
|
-
db,
|
|
349
|
-
undefined,
|
|
350
|
-
undefined,
|
|
351
|
-
null // no github
|
|
352
|
-
)
|
|
353
|
-
expect(typeof result.data).toBe('string')
|
|
354
|
-
expect(result.data as string).toContain('GitHub integration not available')
|
|
355
|
-
})
|
|
356
|
-
})
|
|
357
|
-
})
|