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,265 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
JournalEntry,
|
|
3
|
-
Tag,
|
|
4
|
-
Relationship,
|
|
5
|
-
EntryType,
|
|
6
|
-
RelationshipType,
|
|
7
|
-
ImportanceResult,
|
|
8
|
-
} from '../../types/index.js'
|
|
9
|
-
import type { CreateEntryInput } from '../core/schema.js'
|
|
10
|
-
import type { IDatabaseAdapter, QueryResult } from '../core/interfaces.js'
|
|
11
|
-
|
|
12
|
-
import { NativeConnectionManager } from './native-connection.js'
|
|
13
|
-
import { TagsManager } from './tags.js'
|
|
14
|
-
import { EntriesManager } from './entries/index.js'
|
|
15
|
-
import { RelationshipsManager } from './relationships.js'
|
|
16
|
-
import { BackupManager } from './backup.js'
|
|
17
|
-
import * as fs from 'node:fs'
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* SQLite Database Adapter for Memory Journal using better-sqlite3 native driver
|
|
21
|
-
*/
|
|
22
|
-
export class DatabaseAdapter implements IDatabaseAdapter {
|
|
23
|
-
private connection: NativeConnectionManager
|
|
24
|
-
private tagsMgr: TagsManager
|
|
25
|
-
private entriesMgr: EntriesManager
|
|
26
|
-
private relationshipsMgr: RelationshipsManager
|
|
27
|
-
private backupMgr: BackupManager
|
|
28
|
-
|
|
29
|
-
constructor(dbPath: string) {
|
|
30
|
-
this.connection = new NativeConnectionManager(dbPath)
|
|
31
|
-
this.tagsMgr = new TagsManager(this.connection)
|
|
32
|
-
this.entriesMgr = new EntriesManager(this.connection, this.tagsMgr)
|
|
33
|
-
this.relationshipsMgr = new RelationshipsManager(this.connection, this.entriesMgr)
|
|
34
|
-
this.backupMgr = new BackupManager(this.connection)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async initialize(): Promise<void> {
|
|
38
|
-
return this.connection.initialize()
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
applyTeamSchema(): void {
|
|
42
|
-
this.connection.applyTeamSchema()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
flushSave(): void {
|
|
46
|
-
this.connection.flushSave()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
close(): void {
|
|
50
|
-
this.connection.close()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
createEntry(input: CreateEntryInput): JournalEntry {
|
|
54
|
-
return this.entriesMgr.createEntry(input)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
getEntryById(id: number): JournalEntry | null {
|
|
58
|
-
return this.entriesMgr.getEntryById(id)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
getEntryByIdIncludeDeleted(id: number): JournalEntry | null {
|
|
62
|
-
return this.entriesMgr.getEntryByIdIncludeDeleted(id)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
getEntriesByIds(ids: number[]): Map<number, JournalEntry> {
|
|
66
|
-
return this.entriesMgr.getEntriesByIds(ids)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
calculateImportance(entryId: number): ImportanceResult {
|
|
70
|
-
return this.entriesMgr.calculateImportance(entryId)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getRecentEntries(limit?: number, isPersonal?: boolean): JournalEntry[] {
|
|
74
|
-
return this.entriesMgr.getRecentEntries(limit ?? 10, isPersonal)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
getEntriesPage(offset: number, limit: number): JournalEntry[] {
|
|
78
|
-
return this.entriesMgr.getEntriesPage(offset, limit)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getActiveEntryCount(): number {
|
|
82
|
-
return this.entriesMgr.getActiveEntryCount()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
updateEntry(
|
|
86
|
-
id: number,
|
|
87
|
-
updates: {
|
|
88
|
-
content?: string
|
|
89
|
-
entryType?: EntryType
|
|
90
|
-
tags?: string[]
|
|
91
|
-
isPersonal?: boolean
|
|
92
|
-
}
|
|
93
|
-
): JournalEntry | null {
|
|
94
|
-
return this.entriesMgr.updateEntry(id, updates)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
deleteEntry(id: number, permanent = false): boolean {
|
|
98
|
-
return this.entriesMgr.deleteEntry(id, permanent)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
searchEntries(
|
|
102
|
-
query: string,
|
|
103
|
-
options?: {
|
|
104
|
-
limit?: number
|
|
105
|
-
isPersonal?: boolean
|
|
106
|
-
projectNumber?: number
|
|
107
|
-
issueNumber?: number
|
|
108
|
-
prNumber?: number
|
|
109
|
-
prStatus?: string
|
|
110
|
-
workflowRunId?: number
|
|
111
|
-
}
|
|
112
|
-
): JournalEntry[] {
|
|
113
|
-
return this.entriesMgr.searchEntries(query, options)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
searchByDateRange(
|
|
117
|
-
startDate: string,
|
|
118
|
-
endDate: string,
|
|
119
|
-
options?: {
|
|
120
|
-
entryType?: EntryType
|
|
121
|
-
tags?: string[]
|
|
122
|
-
isPersonal?: boolean
|
|
123
|
-
projectNumber?: number
|
|
124
|
-
issueNumber?: number
|
|
125
|
-
prNumber?: number
|
|
126
|
-
workflowRunId?: number
|
|
127
|
-
limit?: number
|
|
128
|
-
}
|
|
129
|
-
): JournalEntry[] {
|
|
130
|
-
return this.entriesMgr.searchByDateRange(startDate, endDate, options)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
getStatistics(
|
|
134
|
-
groupBy?: 'day' | 'week' | 'month',
|
|
135
|
-
startDate?: string,
|
|
136
|
-
endDate?: string,
|
|
137
|
-
projectBreakdown?: boolean
|
|
138
|
-
): ReturnType<EntriesManager['getStatistics']> {
|
|
139
|
-
return this.entriesMgr.getStatistics(groupBy, startDate, endDate, projectBreakdown)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
getTagsForEntry(entryId: number): string[] {
|
|
143
|
-
return this.tagsMgr.getTagsForEntry(entryId)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
listTags(): Tag[] {
|
|
147
|
-
return this.tagsMgr.listTags()
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
mergeTags(
|
|
151
|
-
sourceTag: string,
|
|
152
|
-
targetTag: string
|
|
153
|
-
): { entriesUpdated: number; sourceDeleted: boolean } {
|
|
154
|
-
return this.tagsMgr.mergeTags(sourceTag, targetTag)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
linkEntries(
|
|
158
|
-
fromEntryId: number,
|
|
159
|
-
toEntryId: number,
|
|
160
|
-
relationshipType: RelationshipType,
|
|
161
|
-
description?: string
|
|
162
|
-
): Relationship {
|
|
163
|
-
return this.relationshipsMgr.linkEntries(
|
|
164
|
-
fromEntryId,
|
|
165
|
-
toEntryId,
|
|
166
|
-
relationshipType,
|
|
167
|
-
description
|
|
168
|
-
)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
getRelationships(entryId: number): Relationship[] {
|
|
172
|
-
return this.relationshipsMgr.getRelationships(entryId)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getBackupsDir(): string {
|
|
176
|
-
return this.connection.getBackupsDir()
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async exportToFile(
|
|
180
|
-
backupName?: string
|
|
181
|
-
): Promise<{ filename: string; path: string; sizeBytes: number }> {
|
|
182
|
-
return this.backupMgr.exportToFile(backupName)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
listBackups(): { filename: string; path: string; sizeBytes: number; createdAt: string }[] {
|
|
186
|
-
return this.backupMgr.listBackups()
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
deleteOldBackups(keepCount: number): { deleted: string[]; kept: number } {
|
|
190
|
-
return this.backupMgr.deleteOldBackups(keepCount)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async restoreFromFile(filename: string): Promise<{
|
|
194
|
-
restoredFrom: string
|
|
195
|
-
previousEntryCount: number
|
|
196
|
-
newEntryCount: number
|
|
197
|
-
}> {
|
|
198
|
-
return this.backupMgr.restoreFromFile(filename)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
getHealthStatus(): ReturnType<IDatabaseAdapter['getHealthStatus']> {
|
|
202
|
-
// Safe query execution through the connection interface
|
|
203
|
-
const dbPath = this.connection.getDbPath()
|
|
204
|
-
|
|
205
|
-
let sizeBytes = 0
|
|
206
|
-
try {
|
|
207
|
-
const stats = fs.statSync(dbPath)
|
|
208
|
-
sizeBytes = stats.size
|
|
209
|
-
} catch {
|
|
210
|
-
// File may not exist on disk yet
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Combined health counts in a single query (batch instead of 4 serial queries)
|
|
214
|
-
const countsResult = this.connection.exec(`
|
|
215
|
-
SELECT
|
|
216
|
-
(SELECT COUNT(*) FROM memory_journal WHERE deleted_at IS NULL) AS entry_count,
|
|
217
|
-
(SELECT COUNT(*) FROM memory_journal WHERE deleted_at IS NOT NULL) AS deleted_count,
|
|
218
|
-
(SELECT COUNT(*) FROM relationships) AS rel_count,
|
|
219
|
-
(SELECT COUNT(*) FROM tags) AS tag_count
|
|
220
|
-
`)
|
|
221
|
-
|
|
222
|
-
const row = countsResult[0]?.values[0]
|
|
223
|
-
const entryCount = (row?.[0] as number) ?? 0
|
|
224
|
-
const deletedEntryCount = (row?.[1] as number) ?? 0
|
|
225
|
-
const relationshipCount = (row?.[2] as number) ?? 0
|
|
226
|
-
const tagCount = (row?.[3] as number) ?? 0
|
|
227
|
-
|
|
228
|
-
const backups = this.listBackups()
|
|
229
|
-
const lastBackup = backups[0] ?? null
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
database: {
|
|
233
|
-
path: dbPath,
|
|
234
|
-
sizeBytes,
|
|
235
|
-
entryCount,
|
|
236
|
-
deletedEntryCount,
|
|
237
|
-
relationshipCount,
|
|
238
|
-
tagCount,
|
|
239
|
-
},
|
|
240
|
-
backups: {
|
|
241
|
-
directory: this.getBackupsDir(),
|
|
242
|
-
count: backups.length,
|
|
243
|
-
lastBackup: lastBackup
|
|
244
|
-
? {
|
|
245
|
-
filename: lastBackup.filename,
|
|
246
|
-
createdAt: lastBackup.createdAt,
|
|
247
|
-
sizeBytes: lastBackup.sizeBytes,
|
|
248
|
-
}
|
|
249
|
-
: null,
|
|
250
|
-
},
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
pragma(command: string): void {
|
|
255
|
-
this.connection.pragma(command)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
getRawDb(): unknown {
|
|
259
|
-
return this.connection.getRawDb()
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
executeRawQuery(sql: string, params?: unknown[]): QueryResult[] {
|
|
263
|
-
return this.connection.exec(sql, params)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import DatabaseAdapter from 'better-sqlite3'
|
|
2
|
-
import type { Database } from 'better-sqlite3'
|
|
3
|
-
import * as fs from 'node:fs'
|
|
4
|
-
import * as path from 'node:path'
|
|
5
|
-
import { logger } from '../../utils/logger.js'
|
|
6
|
-
import { ConnectionError } from '../../types/errors.js'
|
|
7
|
-
import { SCHEMA_SQL, TEAM_SCHEMA_SQL } from '../core/schema.js'
|
|
8
|
-
import type { IDatabaseConnection, QueryResult } from '../core/interfaces.js'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Pre-compiled regex to detect SQL mutation statements.
|
|
12
|
-
* Hoisted to module scope to avoid recompilation on every exec() call.
|
|
13
|
-
*/
|
|
14
|
-
const IS_MUTATION_RE =
|
|
15
|
-
/^\s*(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|PRAGMA (?!table_info|foreign_key_list|index_info|index_list|journal_mode|synchronous|temp_store))./i
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Shared migration columns required by both personal and team schemas.
|
|
19
|
-
* Adding a new column here ensures it is applied in both migrateSchema() and applyTeamSchema().
|
|
20
|
-
*/
|
|
21
|
-
const SHARED_MIGRATION_COLUMNS: { name: string; sql: string }[] = [
|
|
22
|
-
{
|
|
23
|
-
name: 'significance_type',
|
|
24
|
-
sql: 'ALTER TABLE memory_journal ADD COLUMN significance_type TEXT',
|
|
25
|
-
},
|
|
26
|
-
{ name: 'auto_context', sql: 'ALTER TABLE memory_journal ADD COLUMN auto_context TEXT' },
|
|
27
|
-
{ name: 'deleted_at', sql: 'ALTER TABLE memory_journal ADD COLUMN deleted_at TEXT' },
|
|
28
|
-
{ name: 'project_number', sql: 'ALTER TABLE memory_journal ADD COLUMN project_number INTEGER' },
|
|
29
|
-
{ name: 'project_owner', sql: 'ALTER TABLE memory_journal ADD COLUMN project_owner TEXT' },
|
|
30
|
-
{ name: 'issue_number', sql: 'ALTER TABLE memory_journal ADD COLUMN issue_number INTEGER' },
|
|
31
|
-
{ name: 'issue_url', sql: 'ALTER TABLE memory_journal ADD COLUMN issue_url TEXT' },
|
|
32
|
-
{ name: 'pr_number', sql: 'ALTER TABLE memory_journal ADD COLUMN pr_number INTEGER' },
|
|
33
|
-
{ name: 'pr_url', sql: 'ALTER TABLE memory_journal ADD COLUMN pr_url TEXT' },
|
|
34
|
-
{ name: 'pr_status', sql: 'ALTER TABLE memory_journal ADD COLUMN pr_status TEXT' },
|
|
35
|
-
{
|
|
36
|
-
name: 'workflow_run_id',
|
|
37
|
-
sql: 'ALTER TABLE memory_journal ADD COLUMN workflow_run_id INTEGER',
|
|
38
|
-
},
|
|
39
|
-
{ name: 'workflow_name', sql: 'ALTER TABLE memory_journal ADD COLUMN workflow_name TEXT' },
|
|
40
|
-
{ name: 'workflow_status', sql: 'ALTER TABLE memory_journal ADD COLUMN workflow_status TEXT' },
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
export class NativeConnectionManager implements IDatabaseConnection {
|
|
44
|
-
private db: Database | null = null
|
|
45
|
-
private readonly dbPath: string
|
|
46
|
-
private initialized = false
|
|
47
|
-
|
|
48
|
-
constructor(dbPath: string) {
|
|
49
|
-
this.dbPath = dbPath
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async initialize(): Promise<void> {
|
|
53
|
-
if (this.initialized) return
|
|
54
|
-
|
|
55
|
-
const dir = path.dirname(this.dbPath)
|
|
56
|
-
if (dir && !fs.existsSync(dir)) {
|
|
57
|
-
await fs.promises.mkdir(dir, { recursive: true })
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
this.db = new DatabaseAdapter(this.dbPath)
|
|
62
|
-
const db = this.db
|
|
63
|
-
|
|
64
|
-
// Native-only PRAGMAs for performance and safety
|
|
65
|
-
db.pragma('journal_mode = WAL')
|
|
66
|
-
db.pragma('synchronous = NORMAL')
|
|
67
|
-
db.pragma('foreign_keys = ON')
|
|
68
|
-
db.pragma('temp_store = MEMORY')
|
|
69
|
-
|
|
70
|
-
// Load sqlite-vec extension for vector search
|
|
71
|
-
// Use local `db` ref to avoid race with concurrent close() during await
|
|
72
|
-
const sqliteVec = await import('sqlite-vec')
|
|
73
|
-
|
|
74
|
-
// Guard: if close() was called during the await, abort initialization
|
|
75
|
-
if (this.db === null) {
|
|
76
|
-
logger.info('Database closed during initialization, aborting', {
|
|
77
|
-
module: 'NativeConnectionManager',
|
|
78
|
-
})
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
sqliteVec.load(db)
|
|
83
|
-
logger.info('sqlite-vec extension loaded', { module: 'NativeConnectionManager' })
|
|
84
|
-
|
|
85
|
-
// Create base schema
|
|
86
|
-
db.exec(SCHEMA_SQL)
|
|
87
|
-
|
|
88
|
-
// Create vector embeddings table (sqlite-vec vec0 virtual table)
|
|
89
|
-
db.exec(`
|
|
90
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS vec_embeddings USING vec0(
|
|
91
|
-
entry_id INTEGER PRIMARY KEY,
|
|
92
|
-
embedding float[384]
|
|
93
|
-
)
|
|
94
|
-
`)
|
|
95
|
-
|
|
96
|
-
// Run schema migrations
|
|
97
|
-
this.migrateSchema()
|
|
98
|
-
|
|
99
|
-
this.initialized = true
|
|
100
|
-
logger.info('Native database opened', {
|
|
101
|
-
module: 'NativeConnectionManager',
|
|
102
|
-
dbPath: this.dbPath,
|
|
103
|
-
})
|
|
104
|
-
} catch (error) {
|
|
105
|
-
logger.error('Failed to initialize native database', {
|
|
106
|
-
module: 'NativeConnectionManager',
|
|
107
|
-
error: String(error),
|
|
108
|
-
})
|
|
109
|
-
throw new ConnectionError(`Native DB Initialization failed: ${String(error)}`)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private migrateSchema(): void {
|
|
114
|
-
const db = this.ensureDb()
|
|
115
|
-
|
|
116
|
-
// table_info in better-sqlite3 returns an array of objects like { "cid": 0, "name": "id", ...}
|
|
117
|
-
const tableInfo = db.prepare('PRAGMA table_info(memory_journal)').all() as {
|
|
118
|
-
name: string
|
|
119
|
-
}[]
|
|
120
|
-
const columns = new Set(tableInfo.map((row) => row.name))
|
|
121
|
-
|
|
122
|
-
const added: string[] = []
|
|
123
|
-
for (const col of SHARED_MIGRATION_COLUMNS) {
|
|
124
|
-
if (!columns.has(col.name)) {
|
|
125
|
-
db.exec(col.sql)
|
|
126
|
-
added.push(col.name)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
db.prepare('UPDATE tags SET usage_count = 0 WHERE usage_count IS NULL').run()
|
|
131
|
-
|
|
132
|
-
// Populate FTS5 index for existing databases that were created before FTS5 was added.
|
|
133
|
-
// Uses FTS5's built-in 'rebuild' command for content-sync tables.
|
|
134
|
-
const ftsCount = (
|
|
135
|
-
db.prepare('SELECT COUNT(*) as c FROM fts_content').get() as { c: number }
|
|
136
|
-
).c
|
|
137
|
-
const entryCount = (
|
|
138
|
-
db.prepare('SELECT COUNT(*) as c FROM memory_journal').get() as { c: number }
|
|
139
|
-
).c
|
|
140
|
-
if (ftsCount === 0 && entryCount > 0) {
|
|
141
|
-
db.exec("INSERT INTO fts_content(fts_content) VALUES ('rebuild')")
|
|
142
|
-
added.push('fts5:populated')
|
|
143
|
-
} else if (ftsCount > entryCount) {
|
|
144
|
-
// Ghost entries: FTS has more rows than the journal (hard deletes before the
|
|
145
|
-
// fts_content_ad trigger existed). Rebuild to remove stale FTS tokens.
|
|
146
|
-
db.exec("INSERT INTO fts_content(fts_content) VALUES ('rebuild')")
|
|
147
|
-
added.push('fts5:rebuilt-ghost-cleanup')
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (added.length > 0) {
|
|
151
|
-
logger.info('Schema migrated', {
|
|
152
|
-
module: 'NativeConnectionManager',
|
|
153
|
-
dbPath: this.dbPath,
|
|
154
|
-
changes: added.map((c) => (c.startsWith('fts5:') ? c : `column:${c}`)),
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
applyTeamSchema(): void {
|
|
160
|
-
const db = this.ensureDb()
|
|
161
|
-
const tableInfo = db.prepare('PRAGMA table_info(memory_journal)').all() as {
|
|
162
|
-
name: string
|
|
163
|
-
}[]
|
|
164
|
-
const columns = new Set(tableInfo.map((row) => row.name))
|
|
165
|
-
|
|
166
|
-
// Shared columns + team-only author column
|
|
167
|
-
const teamColumns: { name: string; sql: string }[] = [
|
|
168
|
-
...SHARED_MIGRATION_COLUMNS,
|
|
169
|
-
{ name: 'author', sql: TEAM_SCHEMA_SQL.trim() },
|
|
170
|
-
]
|
|
171
|
-
|
|
172
|
-
const added: string[] = []
|
|
173
|
-
for (const col of teamColumns) {
|
|
174
|
-
if (!columns.has(col.name)) {
|
|
175
|
-
db.exec(col.sql)
|
|
176
|
-
added.push(col.name)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (added.length > 0) {
|
|
181
|
-
logger.info('Team schema migrated', {
|
|
182
|
-
module: 'NativeConnectionManager',
|
|
183
|
-
dbPath: this.dbPath,
|
|
184
|
-
columnsAdded: added,
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Maps better-sqlite3 results to the legacy `{ columns: string[], values: unknown[][] }[]` shape
|
|
191
|
-
* Because better-sqlite3 returns arrays of objects instantly, we map them out.
|
|
192
|
-
*/
|
|
193
|
-
exec(sql: string, params?: unknown[]): QueryResult[] {
|
|
194
|
-
const db = this.ensureDb()
|
|
195
|
-
|
|
196
|
-
// Use pre-compiled regex to detect true mutations that should return an empty set
|
|
197
|
-
const isMutation = IS_MUTATION_RE.test(sql)
|
|
198
|
-
|
|
199
|
-
// For multiple statements separated by semicolon where they just want it to run
|
|
200
|
-
if (isMutation && sql.includes(';')) {
|
|
201
|
-
db.exec(sql)
|
|
202
|
-
return []
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const stmt = db.prepare(sql)
|
|
206
|
-
|
|
207
|
-
if (isMutation || !stmt.reader) {
|
|
208
|
-
// It's a mutation, don't try to read rows back
|
|
209
|
-
if (params && params.length > 0) {
|
|
210
|
-
stmt.run(...params)
|
|
211
|
-
} else {
|
|
212
|
-
stmt.run()
|
|
213
|
-
}
|
|
214
|
-
return []
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// It's a SELECT/PRAGMA with a reader
|
|
218
|
-
const rows =
|
|
219
|
-
params && params.length > 0
|
|
220
|
-
? (stmt.all(...params) as Record<string, unknown>[])
|
|
221
|
-
: (stmt.all() as Record<string, unknown>[])
|
|
222
|
-
|
|
223
|
-
if (rows.length === 0) {
|
|
224
|
-
return []
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const columns = Object.keys(rows[0] as object)
|
|
228
|
-
const values: unknown[][] = rows.map((row) => columns.map((col) => row[col]))
|
|
229
|
-
|
|
230
|
-
return [{ columns, values }]
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Wrapper for INSERT/UPDATE/DELETE
|
|
235
|
-
*/
|
|
236
|
-
run(sql: string, params?: unknown[]): void {
|
|
237
|
-
const db = this.ensureDb()
|
|
238
|
-
if (params && params.length > 0) {
|
|
239
|
-
db.prepare(sql).run(...params)
|
|
240
|
-
} else {
|
|
241
|
-
db.prepare(sql).run()
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
scheduleSave(): void {
|
|
246
|
-
// No-op for Native SQLite, disk writes are automatic
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
flushSave(): void {
|
|
250
|
-
// No-op for Native SQLite
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
close(): void {
|
|
254
|
-
if (this.db) {
|
|
255
|
-
// Ensure WAL checkpoint
|
|
256
|
-
try {
|
|
257
|
-
this.db.pragma('wal_checkpoint(TRUNCATE)')
|
|
258
|
-
} catch {
|
|
259
|
-
// ignore
|
|
260
|
-
}
|
|
261
|
-
this.db.close()
|
|
262
|
-
this.db = null
|
|
263
|
-
}
|
|
264
|
-
logger.info('Native database closed', { module: 'NativeConnectionManager' })
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
private ensureDb(): Database {
|
|
268
|
-
if (!this.db) {
|
|
269
|
-
throw new ConnectionError('Database not initialized. Call initialize() first.')
|
|
270
|
-
}
|
|
271
|
-
return this.db
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
pragma(command: string): void {
|
|
275
|
-
const db = this.ensureDb()
|
|
276
|
-
db.pragma(command)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
getRawDb(): unknown {
|
|
280
|
-
return this.ensureDb()
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
getDbPath(): string {
|
|
284
|
-
return this.dbPath
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
getBackupsDir(): string {
|
|
288
|
-
return path.join(path.dirname(this.dbPath), 'backups')
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
closeDbBeforeRestore(): void {
|
|
292
|
-
this.close()
|
|
293
|
-
this.initialized = false
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
setDbAndInitialized(db: unknown): void {
|
|
297
|
-
this.db = db as Database
|
|
298
|
-
this.db.pragma('foreign_keys = ON')
|
|
299
|
-
this.initialized = true
|
|
300
|
-
}
|
|
301
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type { Database } from 'better-sqlite3'
|
|
2
|
-
import type { Relationship, RelationshipType } from '../../types/index.js'
|
|
3
|
-
import type { NativeConnectionManager } from './native-connection.js'
|
|
4
|
-
import type { EntriesManager } from './entries/index.js'
|
|
5
|
-
|
|
6
|
-
export class RelationshipsManager {
|
|
7
|
-
private ctx: NativeConnectionManager
|
|
8
|
-
private entries: EntriesManager
|
|
9
|
-
|
|
10
|
-
constructor(ctx: NativeConnectionManager, entries: EntriesManager) {
|
|
11
|
-
this.ctx = ctx
|
|
12
|
-
this.entries = entries
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
private get db(): Database {
|
|
16
|
-
return this.ctx.getRawDb() as Database
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
linkEntries(
|
|
20
|
-
fromEntryId: number,
|
|
21
|
-
toEntryId: number,
|
|
22
|
-
relationshipType: RelationshipType,
|
|
23
|
-
description?: string
|
|
24
|
-
): Relationship {
|
|
25
|
-
const db = this.db
|
|
26
|
-
|
|
27
|
-
this.entries.getEntryById(fromEntryId)
|
|
28
|
-
this.entries.getEntryById(toEntryId)
|
|
29
|
-
|
|
30
|
-
const result = db
|
|
31
|
-
.prepare(
|
|
32
|
-
`INSERT INTO relationships (from_entry_id, to_entry_id, relationship_type, description)
|
|
33
|
-
VALUES (?, ?, ?, ?)`
|
|
34
|
-
)
|
|
35
|
-
.run(fromEntryId, toEntryId, relationshipType, description ?? null)
|
|
36
|
-
|
|
37
|
-
const id = result.lastInsertRowid as number
|
|
38
|
-
|
|
39
|
-
this.ctx.scheduleSave()
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
id,
|
|
43
|
-
fromEntryId,
|
|
44
|
-
toEntryId,
|
|
45
|
-
relationshipType,
|
|
46
|
-
description: description ?? null,
|
|
47
|
-
createdAt: new Date().toISOString(),
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getRelationships(entryId: number): Relationship[] {
|
|
52
|
-
const rows = this.db
|
|
53
|
-
.prepare(
|
|
54
|
-
`SELECT id, from_entry_id as fromEntryId, to_entry_id as toEntryId,
|
|
55
|
-
relationship_type as relationshipType, description, created_at as createdAt
|
|
56
|
-
FROM relationships
|
|
57
|
-
WHERE from_entry_id = ? OR to_entry_id = ?`
|
|
58
|
-
)
|
|
59
|
-
.all(entryId, entryId) as {
|
|
60
|
-
id: number
|
|
61
|
-
fromEntryId: number
|
|
62
|
-
toEntryId: number
|
|
63
|
-
relationshipType: RelationshipType
|
|
64
|
-
description: string | null
|
|
65
|
-
createdAt: string
|
|
66
|
-
}[]
|
|
67
|
-
|
|
68
|
-
return rows
|
|
69
|
-
}
|
|
70
|
-
}
|