prjct-cli 1.22.0 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +230 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct-core.mjs +1748 -0
- package/dist/bin/prjct.mjs +17 -36672
- package/dist/cli/linear.mjs +14 -0
- package/dist/daemon/entry.mjs +1429 -0
- package/dist/templates.json +1 -0
- package/package.json +4 -5
- package/bin/prjct.ts +0 -342
- package/core/__tests__/agentic/analysis-injection.test.ts +0 -377
- package/core/__tests__/agentic/cache-eviction.test.ts +0 -294
- package/core/__tests__/agentic/command-context.test.ts +0 -281
- package/core/__tests__/agentic/command-executor.test.ts +0 -659
- package/core/__tests__/agentic/domain-classifier.test.ts +0 -330
- package/core/__tests__/agentic/injection-validator.test.ts +0 -255
- package/core/__tests__/agentic/memory-system.test.ts +0 -281
- package/core/__tests__/agentic/plan-mode.test.ts +0 -386
- package/core/__tests__/agentic/prompt-assembly.test.ts +0 -298
- package/core/__tests__/agentic/prompt-builder.test.ts +0 -243
- package/core/__tests__/agentic/response-validator.test.ts +0 -263
- package/core/__tests__/agentic/semantic-matching.test.ts +0 -131
- package/core/__tests__/agentic/smart-context.test.ts +0 -372
- package/core/__tests__/agentic/tech-normalizer.test.ts +0 -136
- package/core/__tests__/agentic/token-budget.test.ts +0 -294
- package/core/__tests__/ai-tools/formatters.test.ts +0 -476
- package/core/__tests__/domain/bm25.test.ts +0 -225
- package/core/__tests__/domain/change-propagator.test.ts +0 -100
- package/core/__tests__/domain/fibonacci.test.ts +0 -113
- package/core/__tests__/domain/file-hasher.test.ts +0 -146
- package/core/__tests__/domain/file-ranker.test.ts +0 -169
- package/core/__tests__/domain/git-cochange.test.ts +0 -121
- package/core/__tests__/domain/import-graph.test.ts +0 -156
- package/core/__tests__/domain/velocity.test.ts +0 -623
- package/core/__tests__/infrastructure/performance-tracker.test.ts +0 -328
- package/core/__tests__/schemas/model.test.ts +0 -272
- package/core/__tests__/services/dependency-validator.test.ts +0 -175
- package/core/__tests__/services/hierarchical-agent-resolver.test.ts +0 -359
- package/core/__tests__/services/nested-context-resolver.test.ts +0 -443
- package/core/__tests__/services/project-index.test.ts +0 -355
- package/core/__tests__/services/staleness-checker.test.ts +0 -204
- package/core/__tests__/storage/analysis-storage.test.ts +0 -641
- package/core/__tests__/storage/archive-storage.test.ts +0 -455
- package/core/__tests__/storage/safe-reader.test.ts +0 -262
- package/core/__tests__/storage/sqlite-migration.test.ts +0 -1016
- package/core/__tests__/storage/state-storage-feedback.test.ts +0 -463
- package/core/__tests__/storage/state-storage-history.test.ts +0 -469
- package/core/__tests__/storage/storage-manager.test.ts +0 -383
- package/core/__tests__/storage/subtask-handoff.test.ts +0 -237
- package/core/__tests__/types/fs.test.ts +0 -125
- package/core/__tests__/utils/date-helper.test.ts +0 -449
- package/core/__tests__/utils/output.test.ts +0 -278
- package/core/__tests__/utils/preserve-sections.test.ts +0 -216
- package/core/__tests__/utils/project-commands.test.ts +0 -71
- package/core/__tests__/utils/retry.test.ts +0 -381
- package/core/__tests__/workflow/state-machine.test.ts +0 -216
- package/core/agentic/agent-router.ts +0 -150
- package/core/agentic/anti-hallucination.ts +0 -141
- package/core/agentic/chain-of-thought.ts +0 -234
- package/core/agentic/command-classifier.ts +0 -141
- package/core/agentic/command-context.ts +0 -168
- package/core/agentic/command-executor.ts +0 -471
- package/core/agentic/context-builder.ts +0 -285
- package/core/agentic/domain-classifier.ts +0 -525
- package/core/agentic/environment-block.ts +0 -102
- package/core/agentic/ground-truth.ts +0 -706
- package/core/agentic/index.ts +0 -193
- package/core/agentic/injection-validator.ts +0 -208
- package/core/agentic/loop-detector.ts +0 -451
- package/core/agentic/memory-system.ts +0 -1547
- package/core/agentic/orchestrator-executor.ts +0 -579
- package/core/agentic/plan-mode.ts +0 -525
- package/core/agentic/prompt-builder.ts +0 -1069
- package/core/agentic/response-validator.ts +0 -98
- package/core/agentic/services.ts +0 -167
- package/core/agentic/skill-loader.ts +0 -106
- package/core/agentic/smart-context.ts +0 -393
- package/core/agentic/tech-normalizer.ts +0 -167
- package/core/agentic/template-executor.ts +0 -272
- package/core/agentic/template-loader.ts +0 -109
- package/core/agentic/token-budget.ts +0 -226
- package/core/agentic/tool-registry.ts +0 -146
- package/core/agents/index.ts +0 -28
- package/core/agents/performance.ts +0 -429
- package/core/ai-tools/formatters.ts +0 -341
- package/core/ai-tools/generator.ts +0 -144
- package/core/ai-tools/index.ts +0 -15
- package/core/ai-tools/registry.ts +0 -201
- package/core/bus/bus.ts +0 -314
- package/core/bus/index.ts +0 -8
- package/core/cli/linear.ts +0 -500
- package/core/cli/lint-meta-commentary.ts +0 -177
- package/core/cli/start.ts +0 -386
- package/core/commands/analysis.ts +0 -1274
- package/core/commands/analytics.ts +0 -342
- package/core/commands/base.ts +0 -118
- package/core/commands/cleanup.ts +0 -157
- package/core/commands/command-data.ts +0 -463
- package/core/commands/commands.ts +0 -306
- package/core/commands/context.ts +0 -238
- package/core/commands/design.ts +0 -77
- package/core/commands/index.ts +0 -19
- package/core/commands/maintenance.ts +0 -77
- package/core/commands/performance.ts +0 -114
- package/core/commands/planning.ts +0 -662
- package/core/commands/register.ts +0 -127
- package/core/commands/registry.ts +0 -444
- package/core/commands/setup.ts +0 -280
- package/core/commands/shipping.ts +0 -267
- package/core/commands/snapshots.ts +0 -297
- package/core/commands/uninstall.ts +0 -542
- package/core/commands/velocity.ts +0 -149
- package/core/commands/workflow.ts +0 -505
- package/core/config/command-context.config.json +0 -66
- package/core/constants/index.ts +0 -379
- package/core/context/generator.ts +0 -368
- package/core/context-tools/files-tool.ts +0 -577
- package/core/context-tools/imports-tool.ts +0 -400
- package/core/context-tools/index.ts +0 -434
- package/core/context-tools/recent-tool.ts +0 -301
- package/core/context-tools/signatures-tool.ts +0 -495
- package/core/context-tools/summary-tool.ts +0 -301
- package/core/context-tools/token-counter.ts +0 -273
- package/core/context-tools/types.ts +0 -253
- package/core/domain/agent-generator.ts +0 -186
- package/core/domain/agent-loader.ts +0 -419
- package/core/domain/analyzer.ts +0 -387
- package/core/domain/architecture-generator.ts +0 -108
- package/core/domain/bm25.ts +0 -525
- package/core/domain/change-propagator.ts +0 -162
- package/core/domain/context-estimator.ts +0 -175
- package/core/domain/fibonacci.ts +0 -128
- package/core/domain/file-hasher.ts +0 -296
- package/core/domain/file-ranker.ts +0 -151
- package/core/domain/git-cochange.ts +0 -250
- package/core/domain/import-graph.ts +0 -315
- package/core/domain/snapshot-manager.ts +0 -415
- package/core/domain/task-stack.ts +0 -578
- package/core/domain/velocity.ts +0 -470
- package/core/errors.ts +0 -335
- package/core/events/events.ts +0 -85
- package/core/events/index.ts +0 -8
- package/core/index.ts +0 -481
- package/core/infrastructure/agent-detector.ts +0 -135
- package/core/infrastructure/ai-provider.ts +0 -578
- package/core/infrastructure/author-detector.ts +0 -133
- package/core/infrastructure/capability-installer.ts +0 -76
- package/core/infrastructure/claude-agent.ts +0 -297
- package/core/infrastructure/command-installer.ts +0 -752
- package/core/infrastructure/config-manager.ts +0 -364
- package/core/infrastructure/editors-config.ts +0 -172
- package/core/infrastructure/path-manager.ts +0 -571
- package/core/infrastructure/performance-tracker.ts +0 -326
- package/core/infrastructure/permission-manager.ts +0 -289
- package/core/infrastructure/setup.ts +0 -1061
- package/core/infrastructure/update-checker.ts +0 -246
- package/core/integrations/issue-tracker/enricher.ts +0 -271
- package/core/integrations/issue-tracker/index.ts +0 -8
- package/core/integrations/issue-tracker/manager.ts +0 -286
- package/core/integrations/issue-tracker/types.ts +0 -310
- package/core/integrations/jira/cache.ts +0 -57
- package/core/integrations/jira/client.ts +0 -688
- package/core/integrations/jira/index.ts +0 -23
- package/core/integrations/jira/service.ts +0 -244
- package/core/integrations/linear/cache.ts +0 -68
- package/core/integrations/linear/client.ts +0 -436
- package/core/integrations/linear/index.ts +0 -20
- package/core/integrations/linear/service.ts +0 -260
- package/core/integrations/linear/sync.ts +0 -314
- package/core/outcomes/analyzer.ts +0 -286
- package/core/outcomes/index.ts +0 -34
- package/core/outcomes/recorder.ts +0 -195
- package/core/plugin/builtin/webhook.ts +0 -148
- package/core/plugin/hooks.ts +0 -315
- package/core/plugin/index.ts +0 -50
- package/core/plugin/loader.ts +0 -354
- package/core/plugin/registry.ts +0 -326
- package/core/schemas/agents.ts +0 -27
- package/core/schemas/analysis.ts +0 -530
- package/core/schemas/classification.ts +0 -91
- package/core/schemas/command-context.ts +0 -29
- package/core/schemas/enriched-task.ts +0 -291
- package/core/schemas/ideas.ts +0 -114
- package/core/schemas/index.ts +0 -53
- package/core/schemas/issues.ts +0 -159
- package/core/schemas/llm-output.ts +0 -170
- package/core/schemas/metrics.ts +0 -143
- package/core/schemas/model.ts +0 -153
- package/core/schemas/outcomes.ts +0 -487
- package/core/schemas/performance.ts +0 -128
- package/core/schemas/permissions.ts +0 -180
- package/core/schemas/prd.ts +0 -450
- package/core/schemas/project.ts +0 -57
- package/core/schemas/roadmap.ts +0 -322
- package/core/schemas/schemas.ts +0 -38
- package/core/schemas/shipped.ts +0 -109
- package/core/schemas/state.ts +0 -284
- package/core/schemas/velocity.ts +0 -103
- package/core/server/index.ts +0 -21
- package/core/server/routes-extended.ts +0 -566
- package/core/server/routes.ts +0 -176
- package/core/server/server.ts +0 -149
- package/core/server/sse.ts +0 -192
- package/core/services/agent-generator.ts +0 -385
- package/core/services/agent-service.ts +0 -168
- package/core/services/breakdown-service.ts +0 -124
- package/core/services/context-generator.ts +0 -445
- package/core/services/context-selector.ts +0 -429
- package/core/services/dependency-validator.ts +0 -318
- package/core/services/diff-generator.ts +0 -313
- package/core/services/doctor-service.ts +0 -423
- package/core/services/file-categorizer.ts +0 -448
- package/core/services/file-scorer.ts +0 -270
- package/core/services/git-analyzer.ts +0 -293
- package/core/services/hierarchical-agent-resolver.ts +0 -236
- package/core/services/hooks-service.ts +0 -685
- package/core/services/index.ts +0 -46
- package/core/services/local-state-generator.ts +0 -158
- package/core/services/memory-service.ts +0 -181
- package/core/services/nested-context-resolver.ts +0 -842
- package/core/services/project-index.ts +0 -911
- package/core/services/project-service.ts +0 -155
- package/core/services/session-tracker.ts +0 -287
- package/core/services/skill-installer.ts +0 -447
- package/core/services/skill-lock.ts +0 -132
- package/core/services/skill-service.ts +0 -306
- package/core/services/stack-detector.ts +0 -229
- package/core/services/staleness-checker.ts +0 -327
- package/core/services/sync-service.ts +0 -1515
- package/core/services/sync-verifier.ts +0 -253
- package/core/services/watch-service.ts +0 -312
- package/core/session/compaction.ts +0 -248
- package/core/session/index.ts +0 -35
- package/core/session/log-migration.ts +0 -88
- package/core/session/metrics.ts +0 -323
- package/core/session/session-log-manager.ts +0 -307
- package/core/session/task-session-manager.ts +0 -404
- package/core/session/utils.ts +0 -51
- package/core/storage/analysis-storage.ts +0 -373
- package/core/storage/archive-storage.ts +0 -205
- package/core/storage/database.ts +0 -575
- package/core/storage/ideas-storage.ts +0 -298
- package/core/storage/index-storage.ts +0 -523
- package/core/storage/index.ts +0 -79
- package/core/storage/metrics-storage.ts +0 -321
- package/core/storage/migrate-json.ts +0 -720
- package/core/storage/queue-storage.ts +0 -336
- package/core/storage/safe-reader.ts +0 -105
- package/core/storage/shipped-storage.ts +0 -253
- package/core/storage/state-storage.ts +0 -1035
- package/core/storage/storage-manager.ts +0 -205
- package/core/storage/storage.ts +0 -177
- package/core/storage/velocity-storage.ts +0 -149
- package/core/sync/auth-config.ts +0 -138
- package/core/sync/index.ts +0 -31
- package/core/sync/oauth-handler.ts +0 -143
- package/core/sync/sync-client.ts +0 -251
- package/core/sync/sync-manager.ts +0 -327
- package/core/tsconfig.json +0 -22
- package/core/types/agentic.ts +0 -760
- package/core/types/agents.ts +0 -150
- package/core/types/bus.ts +0 -193
- package/core/types/citations.ts +0 -22
- package/core/types/commands.ts +0 -399
- package/core/types/config.ts +0 -92
- package/core/types/core.ts +0 -96
- package/core/types/diff.ts +0 -41
- package/core/types/domain.ts +0 -71
- package/core/types/errors.ts +0 -111
- package/core/types/events.ts +0 -42
- package/core/types/fs.ts +0 -72
- package/core/types/index.ts +0 -510
- package/core/types/infrastructure.ts +0 -210
- package/core/types/integrations.ts +0 -31
- package/core/types/jira.ts +0 -51
- package/core/types/logger.ts +0 -17
- package/core/types/memory.ts +0 -313
- package/core/types/outcomes.ts +0 -190
- package/core/types/output.ts +0 -47
- package/core/types/plugin.ts +0 -25
- package/core/types/project-sync.ts +0 -129
- package/core/types/provider.ts +0 -163
- package/core/types/server.ts +0 -71
- package/core/types/services.ts +0 -84
- package/core/types/session.ts +0 -135
- package/core/types/stack.ts +0 -19
- package/core/types/storage.ts +0 -318
- package/core/types/sync-verifier.ts +0 -33
- package/core/types/sync.ts +0 -121
- package/core/types/task.ts +0 -72
- package/core/types/template.ts +0 -24
- package/core/types/utils.ts +0 -92
- package/core/types/workflow.ts +0 -23
- package/core/utils/agent-stream.ts +0 -140
- package/core/utils/animations.ts +0 -251
- package/core/utils/branding.ts +0 -88
- package/core/utils/cache.ts +0 -187
- package/core/utils/citations.ts +0 -39
- package/core/utils/collection-filters.ts +0 -209
- package/core/utils/date-helper.ts +0 -176
- package/core/utils/error-messages.ts +0 -38
- package/core/utils/file-helper.ts +0 -277
- package/core/utils/fs-helpers.ts +0 -14
- package/core/utils/help.ts +0 -314
- package/core/utils/jsonl-helper.ts +0 -290
- package/core/utils/keychain.ts +0 -127
- package/core/utils/logger.ts +0 -77
- package/core/utils/markdown-builder.ts +0 -280
- package/core/utils/next-steps.ts +0 -95
- package/core/utils/output.ts +0 -403
- package/core/utils/preserve-sections.ts +0 -218
- package/core/utils/project-commands.ts +0 -126
- package/core/utils/project-credentials.ts +0 -143
- package/core/utils/provider-cache.ts +0 -49
- package/core/utils/retry.ts +0 -318
- package/core/utils/runtime.ts +0 -108
- package/core/utils/session-helper.ts +0 -278
- package/core/utils/subtask-table.ts +0 -227
- package/core/utils/version.ts +0 -128
- package/core/wizard/index.ts +0 -13
- package/core/wizard/onboarding.ts +0 -633
- package/core/workflow/index.ts +0 -7
- package/core/workflow/state-machine.ts +0 -198
- package/core/workflow/workflow-preferences.ts +0 -294
- package/dist/core/infrastructure/command-installer.js +0 -1141
- package/dist/core/infrastructure/editors-config.js +0 -177
- package/dist/core/infrastructure/setup.js +0 -2244
- package/dist/core/utils/version.js +0 -141
- package/templates/agentic/agent-routing.md +0 -45
- package/templates/agentic/agents/uxui.md +0 -63
- package/templates/agentic/checklist-routing.md +0 -98
- package/templates/agentic/orchestrator.md +0 -68
- package/templates/agentic/task-fragmentation.md +0 -89
- package/templates/agents/AGENTS.md +0 -68
- package/templates/analysis/analyze.md +0 -84
- package/templates/analysis/patterns.md +0 -60
- package/templates/antigravity/SKILL.md +0 -39
- package/templates/architect/discovery.md +0 -67
- package/templates/architect/phases.md +0 -59
- package/templates/checklists/architecture.md +0 -28
- package/templates/checklists/code-quality.md +0 -28
- package/templates/checklists/data.md +0 -33
- package/templates/checklists/documentation.md +0 -33
- package/templates/checklists/infrastructure.md +0 -33
- package/templates/checklists/performance.md +0 -33
- package/templates/checklists/security.md +0 -33
- package/templates/checklists/testing.md +0 -33
- package/templates/checklists/ux-ui.md +0 -37
- package/templates/commands/analyze.md +0 -56
- package/templates/commands/auth.md +0 -234
- package/templates/commands/bug.md +0 -163
- package/templates/commands/cleanup.md +0 -19
- package/templates/commands/dash.md +0 -99
- package/templates/commands/design.md +0 -15
- package/templates/commands/done.md +0 -291
- package/templates/commands/enrich.md +0 -174
- package/templates/commands/git.md +0 -295
- package/templates/commands/history.md +0 -389
- package/templates/commands/idea.md +0 -88
- package/templates/commands/impact.md +0 -864
- package/templates/commands/init.md +0 -54
- package/templates/commands/jira.md +0 -278
- package/templates/commands/linear.md +0 -288
- package/templates/commands/merge.md +0 -206
- package/templates/commands/next.md +0 -80
- package/templates/commands/p.md +0 -67
- package/templates/commands/p.toml +0 -37
- package/templates/commands/pause.md +0 -136
- package/templates/commands/plan.md +0 -696
- package/templates/commands/prd.md +0 -356
- package/templates/commands/resume.md +0 -171
- package/templates/commands/review.md +0 -276
- package/templates/commands/serve.md +0 -118
- package/templates/commands/setup.md +0 -91
- package/templates/commands/ship.md +0 -475
- package/templates/commands/skill.md +0 -259
- package/templates/commands/spec.md +0 -218
- package/templates/commands/status.md +0 -207
- package/templates/commands/sync.md +0 -104
- package/templates/commands/task.md +0 -312
- package/templates/commands/test.md +0 -93
- package/templates/commands/update.md +0 -63
- package/templates/commands/verify.md +0 -204
- package/templates/commands/workflow.md +0 -150
- package/templates/config/skill-mappings.json +0 -82
- package/templates/context/dashboard.md +0 -256
- package/templates/context/roadmap.md +0 -221
- package/templates/cursor/commands/bug.md +0 -8
- package/templates/cursor/commands/done.md +0 -4
- package/templates/cursor/commands/pause.md +0 -6
- package/templates/cursor/commands/resume.md +0 -4
- package/templates/cursor/commands/ship.md +0 -8
- package/templates/cursor/commands/sync.md +0 -4
- package/templates/cursor/commands/task.md +0 -8
- package/templates/cursor/p.md +0 -29
- package/templates/cursor/router.mdc +0 -28
- package/templates/design/api.md +0 -95
- package/templates/design/architecture.md +0 -77
- package/templates/design/component.md +0 -89
- package/templates/design/database.md +0 -78
- package/templates/design/flow.md +0 -94
- package/templates/global/ANTIGRAVITY.md +0 -254
- package/templates/global/CLAUDE.md +0 -497
- package/templates/global/CURSOR.mdc +0 -266
- package/templates/global/GEMINI.md +0 -293
- package/templates/global/STORAGE-SPEC.md +0 -391
- package/templates/global/WINDSURF.md +0 -266
- package/templates/global/modules/CLAUDE-commands.md +0 -70
- package/templates/global/modules/CLAUDE-core.md +0 -105
- package/templates/global/modules/CLAUDE-git.md +0 -50
- package/templates/global/modules/CLAUDE-intelligence.md +0 -92
- package/templates/global/modules/CLAUDE-storage.md +0 -50
- package/templates/global/modules/module-config.json +0 -36
- package/templates/mcp-config.json +0 -19
- package/templates/permissions/default.jsonc +0 -60
- package/templates/permissions/permissive.jsonc +0 -49
- package/templates/permissions/strict.jsonc +0 -58
- package/templates/planning-methodology.md +0 -195
- package/templates/skills/code-review.md +0 -47
- package/templates/skills/debug.md +0 -61
- package/templates/skills/refactor.md +0 -47
- package/templates/subagents/agent-base.md +0 -20
- package/templates/subagents/domain/backend.md +0 -109
- package/templates/subagents/domain/database.md +0 -121
- package/templates/subagents/domain/devops.md +0 -152
- package/templates/subagents/domain/frontend.md +0 -103
- package/templates/subagents/domain/testing.md +0 -169
- package/templates/subagents/pm-expert.md +0 -366
- package/templates/subagents/workflow/chief-architect.md +0 -657
- package/templates/subagents/workflow/prjct-planner.md +0 -159
- package/templates/subagents/workflow/prjct-shipper.md +0 -188
- package/templates/subagents/workflow/prjct-workflow.md +0 -98
- package/templates/tools/bash.txt +0 -22
- package/templates/tools/edit.txt +0 -18
- package/templates/tools/glob.txt +0 -19
- package/templates/tools/grep.txt +0 -21
- package/templates/tools/read.txt +0 -14
- package/templates/tools/task.txt +0 -20
- package/templates/tools/webfetch.txt +0 -16
- package/templates/tools/websearch.txt +0 -18
- package/templates/tools/write.txt +0 -17
- package/templates/windsurf/router.md +0 -28
- package/templates/windsurf/workflows/bug.md +0 -8
- package/templates/windsurf/workflows/done.md +0 -4
- package/templates/windsurf/workflows/pause.md +0 -4
- package/templates/windsurf/workflows/resume.md +0 -4
- package/templates/windsurf/workflows/ship.md +0 -8
- package/templates/windsurf/workflows/sync.md +0 -4
- package/templates/windsurf/workflows/task.md +0 -8
package/core/storage/database.ts
DELETED
|
@@ -1,575 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SQLite Database Manager (PRJ-303)
|
|
3
|
-
*
|
|
4
|
-
* Single SQLite database per project replaces 7+ JSON files.
|
|
5
|
-
* Uses Bun's built-in SQLite (`bun:sqlite`) — zero external deps.
|
|
6
|
-
*
|
|
7
|
-
* Benefits over JSON files:
|
|
8
|
-
* - Atomic writes (WAL mode, no race conditions)
|
|
9
|
-
* - Indexed queries (<1ms lookups vs 10-50ms JSON parse)
|
|
10
|
-
* - Concurrent reads + single writer (WAL)
|
|
11
|
-
* - No file locking needed
|
|
12
|
-
*
|
|
13
|
-
* Storage architecture:
|
|
14
|
-
* - `kv_store` table: Document-style storage (drop-in replacement for JSON files)
|
|
15
|
-
* - Normalized tables: For indexed queries on frequently accessed entities
|
|
16
|
-
* - `events` table: Append-only event log (replaces events.jsonl)
|
|
17
|
-
*
|
|
18
|
-
* @version 1.0.0
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import { Database, type SQLQueryBindings } from 'bun:sqlite'
|
|
22
|
-
import fs from 'node:fs'
|
|
23
|
-
import path from 'node:path'
|
|
24
|
-
import pathManager from '../infrastructure/path-manager'
|
|
25
|
-
|
|
26
|
-
// =============================================================================
|
|
27
|
-
// Types
|
|
28
|
-
// =============================================================================
|
|
29
|
-
|
|
30
|
-
export interface Migration {
|
|
31
|
-
version: number
|
|
32
|
-
name: string
|
|
33
|
-
up: (db: Database) => void
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface MigrationRecord {
|
|
37
|
-
version: number
|
|
38
|
-
name: string
|
|
39
|
-
applied_at: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// =============================================================================
|
|
43
|
-
// Schema Migrations
|
|
44
|
-
// =============================================================================
|
|
45
|
-
|
|
46
|
-
const migrations: Migration[] = [
|
|
47
|
-
{
|
|
48
|
-
version: 1,
|
|
49
|
-
name: 'initial-schema',
|
|
50
|
-
up: (db: Database) => {
|
|
51
|
-
db.run(`
|
|
52
|
-
-- =======================================================================
|
|
53
|
-
-- Document storage (backward-compatible with JSON file pattern)
|
|
54
|
-
-- =======================================================================
|
|
55
|
-
-- Each row replaces one JSON file (state.json, queue.json, etc.)
|
|
56
|
-
-- StorageManager reads/writes entire documents via key lookup.
|
|
57
|
-
CREATE TABLE kv_store (
|
|
58
|
-
key TEXT PRIMARY KEY,
|
|
59
|
-
data TEXT NOT NULL,
|
|
60
|
-
updated_at TEXT NOT NULL
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
-- =======================================================================
|
|
64
|
-
-- Normalized: Tasks
|
|
65
|
-
-- =======================================================================
|
|
66
|
-
CREATE TABLE tasks (
|
|
67
|
-
id TEXT PRIMARY KEY,
|
|
68
|
-
description TEXT NOT NULL,
|
|
69
|
-
type TEXT,
|
|
70
|
-
status TEXT NOT NULL,
|
|
71
|
-
parent_description TEXT,
|
|
72
|
-
branch TEXT,
|
|
73
|
-
linear_id TEXT,
|
|
74
|
-
linear_uuid TEXT,
|
|
75
|
-
session_id TEXT,
|
|
76
|
-
feature_id TEXT,
|
|
77
|
-
started_at TEXT NOT NULL,
|
|
78
|
-
completed_at TEXT,
|
|
79
|
-
shipped_at TEXT,
|
|
80
|
-
paused_at TEXT,
|
|
81
|
-
pause_reason TEXT,
|
|
82
|
-
pr_url TEXT,
|
|
83
|
-
expected_value TEXT,
|
|
84
|
-
data TEXT
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
CREATE INDEX idx_tasks_status ON tasks(status);
|
|
88
|
-
CREATE INDEX idx_tasks_type ON tasks(type);
|
|
89
|
-
CREATE INDEX idx_tasks_branch ON tasks(branch);
|
|
90
|
-
CREATE INDEX idx_tasks_linear_id ON tasks(linear_id);
|
|
91
|
-
|
|
92
|
-
-- =======================================================================
|
|
93
|
-
-- Normalized: Subtasks
|
|
94
|
-
-- =======================================================================
|
|
95
|
-
CREATE TABLE subtasks (
|
|
96
|
-
id TEXT PRIMARY KEY,
|
|
97
|
-
task_id TEXT NOT NULL,
|
|
98
|
-
description TEXT NOT NULL,
|
|
99
|
-
status TEXT NOT NULL,
|
|
100
|
-
domain TEXT,
|
|
101
|
-
agent TEXT,
|
|
102
|
-
sort_order INTEGER NOT NULL,
|
|
103
|
-
depends_on TEXT,
|
|
104
|
-
started_at TEXT,
|
|
105
|
-
completed_at TEXT,
|
|
106
|
-
output TEXT,
|
|
107
|
-
summary TEXT,
|
|
108
|
-
FOREIGN KEY (task_id) REFERENCES tasks(id)
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
CREATE INDEX idx_subtasks_task_id ON subtasks(task_id);
|
|
112
|
-
CREATE INDEX idx_subtasks_status ON subtasks(status);
|
|
113
|
-
|
|
114
|
-
-- =======================================================================
|
|
115
|
-
-- Normalized: Queue Tasks
|
|
116
|
-
-- =======================================================================
|
|
117
|
-
CREATE TABLE queue_tasks (
|
|
118
|
-
id TEXT PRIMARY KEY,
|
|
119
|
-
description TEXT NOT NULL,
|
|
120
|
-
type TEXT,
|
|
121
|
-
priority TEXT,
|
|
122
|
-
section TEXT,
|
|
123
|
-
created_at TEXT NOT NULL,
|
|
124
|
-
completed INTEGER DEFAULT 0,
|
|
125
|
-
completed_at TEXT,
|
|
126
|
-
feature_id TEXT,
|
|
127
|
-
feature_name TEXT
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
CREATE INDEX idx_queue_tasks_section ON queue_tasks(section);
|
|
131
|
-
CREATE INDEX idx_queue_tasks_priority ON queue_tasks(priority);
|
|
132
|
-
CREATE INDEX idx_queue_tasks_completed ON queue_tasks(completed);
|
|
133
|
-
|
|
134
|
-
-- =======================================================================
|
|
135
|
-
-- Normalized: Ideas
|
|
136
|
-
-- =======================================================================
|
|
137
|
-
CREATE TABLE ideas (
|
|
138
|
-
id TEXT PRIMARY KEY,
|
|
139
|
-
text TEXT NOT NULL,
|
|
140
|
-
status TEXT NOT NULL DEFAULT 'pending',
|
|
141
|
-
priority TEXT NOT NULL DEFAULT 'medium',
|
|
142
|
-
tags TEXT,
|
|
143
|
-
added_at TEXT NOT NULL,
|
|
144
|
-
converted_to TEXT,
|
|
145
|
-
details TEXT,
|
|
146
|
-
data TEXT
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
CREATE INDEX idx_ideas_status ON ideas(status);
|
|
150
|
-
CREATE INDEX idx_ideas_priority ON ideas(priority);
|
|
151
|
-
|
|
152
|
-
-- =======================================================================
|
|
153
|
-
-- Normalized: Shipped Features
|
|
154
|
-
-- =======================================================================
|
|
155
|
-
CREATE TABLE shipped_features (
|
|
156
|
-
id TEXT PRIMARY KEY,
|
|
157
|
-
name TEXT NOT NULL,
|
|
158
|
-
shipped_at TEXT NOT NULL,
|
|
159
|
-
version TEXT NOT NULL,
|
|
160
|
-
description TEXT,
|
|
161
|
-
type TEXT,
|
|
162
|
-
duration TEXT,
|
|
163
|
-
data TEXT
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
CREATE INDEX idx_shipped_version ON shipped_features(version);
|
|
167
|
-
CREATE INDEX idx_shipped_at ON shipped_features(shipped_at);
|
|
168
|
-
|
|
169
|
-
-- =======================================================================
|
|
170
|
-
-- Events (replaces events.jsonl)
|
|
171
|
-
-- =======================================================================
|
|
172
|
-
CREATE TABLE events (
|
|
173
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
174
|
-
type TEXT NOT NULL,
|
|
175
|
-
task_id TEXT,
|
|
176
|
-
data TEXT,
|
|
177
|
-
timestamp TEXT NOT NULL
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
CREATE INDEX idx_events_type ON events(type);
|
|
181
|
-
CREATE INDEX idx_events_task_id ON events(task_id);
|
|
182
|
-
CREATE INDEX idx_events_timestamp ON events(timestamp);
|
|
183
|
-
|
|
184
|
-
-- =======================================================================
|
|
185
|
-
-- Analysis (draft + sealed)
|
|
186
|
-
-- =======================================================================
|
|
187
|
-
CREATE TABLE analysis (
|
|
188
|
-
id TEXT PRIMARY KEY,
|
|
189
|
-
status TEXT NOT NULL,
|
|
190
|
-
commit_hash TEXT,
|
|
191
|
-
signature TEXT,
|
|
192
|
-
sealed_at TEXT,
|
|
193
|
-
analyzed_at TEXT,
|
|
194
|
-
data TEXT NOT NULL
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
-- =======================================================================
|
|
198
|
-
-- Index: File scores and checksums
|
|
199
|
-
-- =======================================================================
|
|
200
|
-
CREATE TABLE index_files (
|
|
201
|
-
path TEXT PRIMARY KEY,
|
|
202
|
-
score REAL,
|
|
203
|
-
size INTEGER,
|
|
204
|
-
mtime TEXT,
|
|
205
|
-
language TEXT,
|
|
206
|
-
categories TEXT,
|
|
207
|
-
domain TEXT
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
CREATE INDEX idx_index_files_domain ON index_files(domain);
|
|
211
|
-
CREATE INDEX idx_index_files_score ON index_files(score);
|
|
212
|
-
|
|
213
|
-
CREATE TABLE index_checksums (
|
|
214
|
-
path TEXT PRIMARY KEY,
|
|
215
|
-
checksum TEXT NOT NULL,
|
|
216
|
-
size INTEGER,
|
|
217
|
-
mtime TEXT
|
|
218
|
-
);
|
|
219
|
-
|
|
220
|
-
-- =======================================================================
|
|
221
|
-
-- Index: Metadata (project-index, domains, categories-cache)
|
|
222
|
-
-- =======================================================================
|
|
223
|
-
CREATE TABLE index_meta (
|
|
224
|
-
key TEXT PRIMARY KEY,
|
|
225
|
-
data TEXT NOT NULL,
|
|
226
|
-
updated_at TEXT NOT NULL
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
-- =======================================================================
|
|
230
|
-
-- Memory (key-value with domain tagging)
|
|
231
|
-
-- =======================================================================
|
|
232
|
-
CREATE TABLE memory (
|
|
233
|
-
key TEXT PRIMARY KEY,
|
|
234
|
-
domain TEXT,
|
|
235
|
-
value TEXT,
|
|
236
|
-
confidence REAL DEFAULT 1.0,
|
|
237
|
-
updated_at TEXT NOT NULL
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
CREATE INDEX idx_memory_domain ON memory(domain);
|
|
241
|
-
|
|
242
|
-
-- =======================================================================
|
|
243
|
-
-- Metrics: Daily stats for trend analysis
|
|
244
|
-
-- =======================================================================
|
|
245
|
-
CREATE TABLE metrics_daily (
|
|
246
|
-
date TEXT PRIMARY KEY,
|
|
247
|
-
tokens_saved INTEGER NOT NULL DEFAULT 0,
|
|
248
|
-
syncs INTEGER NOT NULL DEFAULT 0,
|
|
249
|
-
avg_compression_rate REAL NOT NULL DEFAULT 0,
|
|
250
|
-
total_duration INTEGER NOT NULL DEFAULT 0
|
|
251
|
-
);
|
|
252
|
-
|
|
253
|
-
-- =======================================================================
|
|
254
|
-
-- Velocity: Sprint data
|
|
255
|
-
-- =======================================================================
|
|
256
|
-
CREATE TABLE velocity_sprints (
|
|
257
|
-
sprint_number INTEGER PRIMARY KEY,
|
|
258
|
-
points_completed REAL NOT NULL DEFAULT 0,
|
|
259
|
-
tasks_completed INTEGER NOT NULL DEFAULT 0,
|
|
260
|
-
estimation_accuracy REAL NOT NULL DEFAULT 0,
|
|
261
|
-
avg_variance REAL NOT NULL DEFAULT 0,
|
|
262
|
-
started_at TEXT,
|
|
263
|
-
ended_at TEXT
|
|
264
|
-
);
|
|
265
|
-
`)
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
version: 2,
|
|
270
|
-
name: 'archives-table',
|
|
271
|
-
up: (db: Database) => {
|
|
272
|
-
db.run(`
|
|
273
|
-
-- =======================================================================
|
|
274
|
-
-- Archives: Stale data moved out of active storage (PRJ-267)
|
|
275
|
-
-- =======================================================================
|
|
276
|
-
CREATE TABLE archives (
|
|
277
|
-
id TEXT PRIMARY KEY,
|
|
278
|
-
entity_type TEXT NOT NULL,
|
|
279
|
-
entity_id TEXT NOT NULL,
|
|
280
|
-
entity_data TEXT NOT NULL,
|
|
281
|
-
summary TEXT,
|
|
282
|
-
archived_at TEXT NOT NULL,
|
|
283
|
-
reason TEXT NOT NULL
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
CREATE INDEX idx_archives_entity_type ON archives(entity_type);
|
|
287
|
-
CREATE INDEX idx_archives_archived_at ON archives(archived_at);
|
|
288
|
-
CREATE INDEX idx_archives_entity_id ON archives(entity_id);
|
|
289
|
-
`)
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
|
-
]
|
|
293
|
-
|
|
294
|
-
// =============================================================================
|
|
295
|
-
// Database Manager
|
|
296
|
-
// =============================================================================
|
|
297
|
-
|
|
298
|
-
class PrjctDatabase {
|
|
299
|
-
private connections = new Map<string, Database>()
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Get the database file path for a project.
|
|
303
|
-
*/
|
|
304
|
-
getDbPath(projectId: string): string {
|
|
305
|
-
return path.join(pathManager.getGlobalProjectPath(projectId), 'prjct.db')
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Get or create a database connection for a project.
|
|
310
|
-
* Lazily opens the database, runs migrations, and enables WAL mode.
|
|
311
|
-
*/
|
|
312
|
-
getDb(projectId: string): Database {
|
|
313
|
-
const existing = this.connections.get(projectId)
|
|
314
|
-
if (existing) return existing
|
|
315
|
-
|
|
316
|
-
const dbPath = this.getDbPath(projectId)
|
|
317
|
-
// Ensure parent directory exists before creating DB
|
|
318
|
-
const dbDir = path.dirname(dbPath)
|
|
319
|
-
if (!fs.existsSync(dbDir)) {
|
|
320
|
-
fs.mkdirSync(dbDir, { recursive: true })
|
|
321
|
-
}
|
|
322
|
-
const db = new Database(dbPath, { create: true })
|
|
323
|
-
|
|
324
|
-
// Enable WAL mode for concurrent reads + single writer
|
|
325
|
-
db.run('PRAGMA journal_mode = WAL')
|
|
326
|
-
|
|
327
|
-
// Performance tuning
|
|
328
|
-
db.run('PRAGMA synchronous = NORMAL')
|
|
329
|
-
db.run('PRAGMA cache_size = -2000') // 2MB cache
|
|
330
|
-
db.run('PRAGMA temp_store = MEMORY')
|
|
331
|
-
db.run('PRAGMA mmap_size = 268435456') // 256MB mmap
|
|
332
|
-
|
|
333
|
-
// Run pending migrations
|
|
334
|
-
this.runMigrations(db)
|
|
335
|
-
|
|
336
|
-
this.connections.set(projectId, db)
|
|
337
|
-
return db
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Close a specific project's database connection, or all connections.
|
|
342
|
-
*/
|
|
343
|
-
close(projectId?: string): void {
|
|
344
|
-
if (projectId) {
|
|
345
|
-
const db = this.connections.get(projectId)
|
|
346
|
-
if (db) {
|
|
347
|
-
db.close()
|
|
348
|
-
this.connections.delete(projectId)
|
|
349
|
-
}
|
|
350
|
-
} else {
|
|
351
|
-
this.connections.forEach((db) => {
|
|
352
|
-
db.close()
|
|
353
|
-
})
|
|
354
|
-
this.connections.clear()
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Check if a database exists for a project (without creating one).
|
|
360
|
-
*/
|
|
361
|
-
exists(projectId: string): boolean {
|
|
362
|
-
return fs.existsSync(this.getDbPath(projectId))
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// ===========================================================================
|
|
366
|
-
// Document Storage (kv_store)
|
|
367
|
-
// ===========================================================================
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Read a document from kv_store by key.
|
|
371
|
-
* Returns parsed JSON or null if not found.
|
|
372
|
-
*/
|
|
373
|
-
getDoc<T>(projectId: string, key: string): T | null {
|
|
374
|
-
const db = this.getDb(projectId)
|
|
375
|
-
const row = db.prepare('SELECT data FROM kv_store WHERE key = ?').get(key) as {
|
|
376
|
-
data: string
|
|
377
|
-
} | null
|
|
378
|
-
if (!row) return null
|
|
379
|
-
return JSON.parse(row.data) as T
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Write a document to kv_store.
|
|
384
|
-
* Replaces existing document with same key.
|
|
385
|
-
*/
|
|
386
|
-
setDoc<T>(projectId: string, key: string, data: T): void {
|
|
387
|
-
const db = this.getDb(projectId)
|
|
388
|
-
const json = JSON.stringify(data)
|
|
389
|
-
const now = new Date().toISOString()
|
|
390
|
-
db.prepare('INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)').run(
|
|
391
|
-
key,
|
|
392
|
-
json,
|
|
393
|
-
now
|
|
394
|
-
)
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Delete a document from kv_store.
|
|
399
|
-
*/
|
|
400
|
-
deleteDoc(projectId: string, key: string): void {
|
|
401
|
-
const db = this.getDb(projectId)
|
|
402
|
-
db.prepare('DELETE FROM kv_store WHERE key = ?').run(key)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Check if a document exists in kv_store.
|
|
407
|
-
*/
|
|
408
|
-
hasDoc(projectId: string, key: string): boolean {
|
|
409
|
-
const db = this.getDb(projectId)
|
|
410
|
-
const row = db.prepare('SELECT 1 FROM kv_store WHERE key = ?').get(key)
|
|
411
|
-
return row !== null
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// ===========================================================================
|
|
415
|
-
// Event Log
|
|
416
|
-
// ===========================================================================
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Append an event to the event log.
|
|
420
|
-
*/
|
|
421
|
-
appendEvent(
|
|
422
|
-
projectId: string,
|
|
423
|
-
type: string,
|
|
424
|
-
data: Record<string, unknown>,
|
|
425
|
-
taskId?: string
|
|
426
|
-
): void {
|
|
427
|
-
const db = this.getDb(projectId)
|
|
428
|
-
const now = new Date().toISOString()
|
|
429
|
-
db.prepare('INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)').run(
|
|
430
|
-
type,
|
|
431
|
-
taskId ?? null,
|
|
432
|
-
JSON.stringify(data),
|
|
433
|
-
now
|
|
434
|
-
)
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Query events by type, with optional limit.
|
|
439
|
-
*/
|
|
440
|
-
getEvents(
|
|
441
|
-
projectId: string,
|
|
442
|
-
type?: string,
|
|
443
|
-
limit = 100
|
|
444
|
-
): Array<{ id: number; type: string; task_id: string | null; data: string; timestamp: string }> {
|
|
445
|
-
const db = this.getDb(projectId)
|
|
446
|
-
if (type) {
|
|
447
|
-
return db
|
|
448
|
-
.prepare('SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?')
|
|
449
|
-
.all(type, limit) as Array<{
|
|
450
|
-
id: number
|
|
451
|
-
type: string
|
|
452
|
-
task_id: string | null
|
|
453
|
-
data: string
|
|
454
|
-
timestamp: string
|
|
455
|
-
}>
|
|
456
|
-
}
|
|
457
|
-
return db.prepare('SELECT * FROM events ORDER BY id DESC LIMIT ?').all(limit) as Array<{
|
|
458
|
-
id: number
|
|
459
|
-
type: string
|
|
460
|
-
task_id: string | null
|
|
461
|
-
data: string
|
|
462
|
-
timestamp: string
|
|
463
|
-
}>
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// ===========================================================================
|
|
467
|
-
// Raw Query Access
|
|
468
|
-
// ===========================================================================
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Execute a raw SQL query that returns rows.
|
|
472
|
-
*/
|
|
473
|
-
query<T = Record<string, unknown>>(
|
|
474
|
-
projectId: string,
|
|
475
|
-
sql: string,
|
|
476
|
-
...params: SQLQueryBindings[]
|
|
477
|
-
): T[] {
|
|
478
|
-
const db = this.getDb(projectId)
|
|
479
|
-
return db.prepare(sql).all(...params) as T[]
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Execute a raw SQL statement (INSERT/UPDATE/DELETE).
|
|
484
|
-
*/
|
|
485
|
-
run(projectId: string, sql: string, ...params: SQLQueryBindings[]): void {
|
|
486
|
-
const db = this.getDb(projectId)
|
|
487
|
-
db.prepare(sql).run(...params)
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Execute a raw SQL query that returns a single row.
|
|
492
|
-
*/
|
|
493
|
-
get<T = Record<string, unknown>>(
|
|
494
|
-
projectId: string,
|
|
495
|
-
sql: string,
|
|
496
|
-
...params: SQLQueryBindings[]
|
|
497
|
-
): T | null {
|
|
498
|
-
const db = this.getDb(projectId)
|
|
499
|
-
return (db.prepare(sql).get(...params) as T) ?? null
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Run multiple statements in a transaction.
|
|
504
|
-
*/
|
|
505
|
-
transaction<T>(projectId: string, fn: (db: Database) => T): T {
|
|
506
|
-
const db = this.getDb(projectId)
|
|
507
|
-
return db.transaction(fn)(db)
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// ===========================================================================
|
|
511
|
-
// Migration System
|
|
512
|
-
// ===========================================================================
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* Run all pending migrations.
|
|
516
|
-
*/
|
|
517
|
-
private runMigrations(db: Database): void {
|
|
518
|
-
// Create migrations table if it doesn't exist
|
|
519
|
-
db.run(`
|
|
520
|
-
CREATE TABLE IF NOT EXISTS _migrations (
|
|
521
|
-
version INTEGER PRIMARY KEY,
|
|
522
|
-
name TEXT NOT NULL,
|
|
523
|
-
applied_at TEXT NOT NULL
|
|
524
|
-
)
|
|
525
|
-
`)
|
|
526
|
-
|
|
527
|
-
// Get applied versions
|
|
528
|
-
const applied = new Set(
|
|
529
|
-
(db.prepare('SELECT version FROM _migrations').all() as Array<{ version: number }>).map(
|
|
530
|
-
(r) => r.version
|
|
531
|
-
)
|
|
532
|
-
)
|
|
533
|
-
|
|
534
|
-
// Run pending migrations in order
|
|
535
|
-
for (const migration of migrations) {
|
|
536
|
-
if (applied.has(migration.version)) continue
|
|
537
|
-
|
|
538
|
-
db.transaction(() => {
|
|
539
|
-
migration.up(db)
|
|
540
|
-
db.prepare('INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)').run(
|
|
541
|
-
migration.version,
|
|
542
|
-
migration.name,
|
|
543
|
-
new Date().toISOString()
|
|
544
|
-
)
|
|
545
|
-
})()
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* Get applied migrations for a project.
|
|
551
|
-
*/
|
|
552
|
-
getMigrations(projectId: string): MigrationRecord[] {
|
|
553
|
-
const db = this.getDb(projectId)
|
|
554
|
-
return db.prepare('SELECT * FROM _migrations ORDER BY version').all() as MigrationRecord[]
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Get the current schema version.
|
|
559
|
-
*/
|
|
560
|
-
getSchemaVersion(projectId: string): number {
|
|
561
|
-
const db = this.getDb(projectId)
|
|
562
|
-
const row = db.prepare('SELECT MAX(version) as version FROM _migrations').get() as {
|
|
563
|
-
version: number | null
|
|
564
|
-
} | null
|
|
565
|
-
return row?.version ?? 0
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// =============================================================================
|
|
570
|
-
// Singleton Export
|
|
571
|
-
// =============================================================================
|
|
572
|
-
|
|
573
|
-
export const prjctDb = new PrjctDatabase()
|
|
574
|
-
export default prjctDb
|
|
575
|
-
export { PrjctDatabase }
|