@shepai/cli 1.111.0 → 1.112.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/dist/packages/core/src/infrastructure/persistence/sqlite/legacy-migrations.d.ts +27 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/legacy-migrations.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/legacy-migrations.js +540 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts +13 -7
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +94 -545
- package/dist/packages/core/src/infrastructure/persistence/sqlite/sqlite-migration-storage.d.ts +59 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/sqlite-migration-storage.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/sqlite-migration-storage.js +98 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__07a39ff2._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_2649c1af._.js → _5214cc6d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_2649c1af._.js.map → _5214cc6d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_4474f9f3._.js → _688c410c._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_4474f9f3._.js.map → _688c410c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_ba9c581b._.js → _8ef2db1a._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_ba9c581b._.js.map → _8ef2db1a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +31 -31
- package/web/.next/static/chunks/{b27c0bbd1de96d37.js → 2ceb08e50a58ff13.js} +1 -1
- package/web/.next/static/chunks/{cbfa943160cc5f90.js → 3a154a226e936a39.js} +1 -1
- package/web/.next/static/chunks/{279db4719a31b985.js → 691c8fb9987506c7.js} +1 -1
- package/web/.next/static/chunks/{185203c3444a4da7.js → 6a91f6e4059b8e65.js} +2 -2
- package/web/.next/static/chunks/{5f52d11e6182396e.js → 6e5ddc3f058e4c15.js} +1 -1
- package/web/.next/static/chunks/{487babfd13611736.js → 974a4718eae26449.js} +1 -1
- package/web/.next/static/chunks/{4e2530a36f28dec7.js → 979328ec65bd195c.js} +2 -2
- package/web/.next/static/chunks/{dd15e70af64f5dd0.js → a067d472cd7bab74.js} +1 -1
- package/web/.next/static/chunks/c2c5d4e54fb6693a.js +1 -0
- package/web/.next/static/chunks/cf78337357d8447e.js +1 -0
- package/web/.next/static/chunks/464557a2dc1fe286.js +0 -1
- package/web/.next/static/chunks/6d2a5b3e881c75a8.js +0 -1
- /package/web/.next/static/{4LIlcvj7VQahrcSQtqQlm → m4kJ9xcvKM_tYBQYtX8sa}/_buildManifest.js +0 -0
- /package/web/.next/static/{4LIlcvj7VQahrcSQtqQlm → m4kJ9xcvKM_tYBQYtX8sa}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{4LIlcvj7VQahrcSQtqQlm → m4kJ9xcvKM_tYBQYtX8sa}/_ssgManifest.js +0 -0
|
@@ -1,566 +1,115 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQLite Migrations Module
|
|
3
3
|
*
|
|
4
|
-
* Manages database schema migrations using
|
|
5
|
-
*
|
|
6
|
-
* (
|
|
4
|
+
* Manages database schema migrations using umzug v3.
|
|
5
|
+
* Legacy migrations (V1–V34) are registered programmatically from legacy-migrations.ts.
|
|
6
|
+
* New migrations (35+) are individual .ts files in the migrations/ directory,
|
|
7
|
+
* discovered at runtime via directory scan.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
+
* Preserves the same export API (runSQLiteMigrations, LATEST_SCHEMA_VERSION) so
|
|
10
|
+
* all 16+ importing files require zero changes.
|
|
9
11
|
*/
|
|
12
|
+
import { readdirSync } from 'node:fs';
|
|
13
|
+
import { dirname, join } from 'node:path';
|
|
14
|
+
import { pathToFileURL } from 'node:url';
|
|
15
|
+
import { Umzug } from 'umzug';
|
|
16
|
+
import { SQLiteMigrationStorage } from './sqlite-migration-storage.js';
|
|
17
|
+
import { LEGACY_MIGRATIONS, LEGACY_MIGRATION_NAMES } from './legacy-migrations.js';
|
|
10
18
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
19
|
+
* The latest schema version (highest legacy migration version number).
|
|
20
|
+
* Exported for test assertions so they don't hardcode version numbers.
|
|
13
21
|
*/
|
|
14
|
-
const
|
|
15
|
-
{
|
|
16
|
-
version: 1,
|
|
17
|
-
sql: `
|
|
18
|
-
-- Migration 001: Create Settings Table
|
|
19
|
-
CREATE TABLE IF NOT EXISTS settings (
|
|
20
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
21
|
-
created_at TEXT NOT NULL,
|
|
22
|
-
updated_at TEXT NOT NULL,
|
|
23
|
-
model_analyze TEXT NOT NULL,
|
|
24
|
-
model_requirements TEXT NOT NULL,
|
|
25
|
-
model_plan TEXT NOT NULL,
|
|
26
|
-
model_implement TEXT NOT NULL,
|
|
27
|
-
user_name TEXT,
|
|
28
|
-
user_email TEXT,
|
|
29
|
-
user_github_username TEXT,
|
|
30
|
-
env_default_editor TEXT NOT NULL,
|
|
31
|
-
env_shell_preference TEXT NOT NULL,
|
|
32
|
-
sys_auto_update INTEGER NOT NULL,
|
|
33
|
-
sys_log_level TEXT NOT NULL
|
|
34
|
-
);
|
|
35
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_settings_id ON settings(id);
|
|
36
|
-
`,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
version: 2,
|
|
40
|
-
sql: `
|
|
41
|
-
-- Migration 002: Add Agent Configuration
|
|
42
|
-
ALTER TABLE settings ADD COLUMN agent_type TEXT NOT NULL DEFAULT 'claude-code';
|
|
43
|
-
ALTER TABLE settings ADD COLUMN agent_auth_method TEXT NOT NULL DEFAULT 'session';
|
|
44
|
-
ALTER TABLE settings ADD COLUMN agent_token TEXT;
|
|
45
|
-
`,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
version: 3,
|
|
49
|
-
sql: `
|
|
50
|
-
-- Migration 003: Create Agent Runs Table
|
|
51
|
-
CREATE TABLE agent_runs (
|
|
52
|
-
id TEXT PRIMARY KEY,
|
|
53
|
-
agent_type TEXT NOT NULL,
|
|
54
|
-
agent_name TEXT NOT NULL,
|
|
55
|
-
status TEXT NOT NULL,
|
|
56
|
-
prompt TEXT NOT NULL,
|
|
57
|
-
result TEXT,
|
|
58
|
-
session_id TEXT,
|
|
59
|
-
thread_id TEXT NOT NULL,
|
|
60
|
-
pid INTEGER,
|
|
61
|
-
last_heartbeat INTEGER,
|
|
62
|
-
started_at INTEGER,
|
|
63
|
-
completed_at INTEGER,
|
|
64
|
-
error TEXT,
|
|
65
|
-
created_at INTEGER NOT NULL,
|
|
66
|
-
updated_at INTEGER NOT NULL
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
CREATE INDEX idx_agent_runs_status ON agent_runs(status);
|
|
70
|
-
CREATE INDEX idx_agent_runs_pid ON agent_runs(pid) WHERE pid IS NOT NULL;
|
|
71
|
-
CREATE INDEX idx_agent_runs_thread_id ON agent_runs(thread_id);
|
|
72
|
-
`,
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
version: 4,
|
|
76
|
-
sql: `
|
|
77
|
-
-- Migration 004: Create Features Table
|
|
78
|
-
CREATE TABLE features (
|
|
79
|
-
id TEXT PRIMARY KEY,
|
|
80
|
-
name TEXT NOT NULL,
|
|
81
|
-
slug TEXT NOT NULL,
|
|
82
|
-
description TEXT NOT NULL,
|
|
83
|
-
repository_path TEXT NOT NULL,
|
|
84
|
-
branch TEXT NOT NULL,
|
|
85
|
-
lifecycle TEXT NOT NULL DEFAULT 'Requirements',
|
|
86
|
-
messages TEXT NOT NULL DEFAULT '[]',
|
|
87
|
-
plan TEXT,
|
|
88
|
-
related_artifacts TEXT NOT NULL DEFAULT '[]',
|
|
89
|
-
agent_run_id TEXT,
|
|
90
|
-
created_at INTEGER NOT NULL,
|
|
91
|
-
updated_at INTEGER NOT NULL
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
CREATE INDEX idx_features_slug ON features(slug, repository_path);
|
|
95
|
-
CREATE INDEX idx_features_repo ON features(repository_path);
|
|
96
|
-
CREATE INDEX idx_features_lifecycle ON features(lifecycle);
|
|
97
|
-
`,
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
version: 5,
|
|
101
|
-
sql: `
|
|
102
|
-
-- Migration 005: Add feature references to agent_runs
|
|
103
|
-
ALTER TABLE agent_runs ADD COLUMN feature_id TEXT;
|
|
104
|
-
ALTER TABLE agent_runs ADD COLUMN repository_path TEXT;
|
|
105
|
-
CREATE INDEX idx_agent_runs_feature ON agent_runs(feature_id) WHERE feature_id IS NOT NULL;
|
|
106
|
-
`,
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
version: 6,
|
|
110
|
-
sql: `
|
|
111
|
-
-- Migration 006: Add approval workflow columns to agent_runs
|
|
112
|
-
ALTER TABLE agent_runs ADD COLUMN approval_mode TEXT;
|
|
113
|
-
ALTER TABLE agent_runs ADD COLUMN approval_status TEXT;
|
|
114
|
-
`,
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
version: 7,
|
|
118
|
-
sql: `
|
|
119
|
-
-- Migration 007: Add spec_path to features
|
|
120
|
-
ALTER TABLE features ADD COLUMN spec_path TEXT;
|
|
121
|
-
`,
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
version: 8,
|
|
125
|
-
sql: `
|
|
126
|
-
-- Migration 008: Add approval_gates JSON column and phase_timings table
|
|
127
|
-
ALTER TABLE agent_runs ADD COLUMN approval_gates TEXT;
|
|
128
|
-
|
|
129
|
-
-- Transform existing approval_mode strings to JSON
|
|
130
|
-
UPDATE agent_runs SET approval_gates = '{"allowPrd":true,"allowPlan":false}'
|
|
131
|
-
WHERE approval_mode = 'allow-prd';
|
|
132
|
-
UPDATE agent_runs SET approval_gates = '{"allowPrd":false,"allowPlan":true}'
|
|
133
|
-
WHERE approval_mode = 'allow-plan';
|
|
134
|
-
UPDATE agent_runs SET approval_gates = '{"allowPrd":true,"allowPlan":true}'
|
|
135
|
-
WHERE approval_mode = 'allow-all';
|
|
136
|
-
UPDATE agent_runs SET approval_gates = '{"allowPrd":false,"allowPlan":false}'
|
|
137
|
-
WHERE approval_mode = 'interactive';
|
|
138
|
-
|
|
139
|
-
-- Create phase_timings table
|
|
140
|
-
CREATE TABLE phase_timings (
|
|
141
|
-
id TEXT PRIMARY KEY,
|
|
142
|
-
agent_run_id TEXT NOT NULL,
|
|
143
|
-
phase TEXT NOT NULL,
|
|
144
|
-
started_at INTEGER NOT NULL,
|
|
145
|
-
completed_at INTEGER,
|
|
146
|
-
duration_ms INTEGER,
|
|
147
|
-
created_at INTEGER NOT NULL,
|
|
148
|
-
updated_at INTEGER NOT NULL
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
CREATE INDEX idx_phase_timings_run ON phase_timings(agent_run_id);
|
|
152
|
-
`,
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
version: 9,
|
|
156
|
-
sql: `
|
|
157
|
-
-- Migration 009: Add Notification Preferences to Settings
|
|
158
|
-
ALTER TABLE settings ADD COLUMN notif_in_app_enabled INTEGER NOT NULL DEFAULT 1;
|
|
159
|
-
ALTER TABLE settings ADD COLUMN notif_browser_enabled INTEGER NOT NULL DEFAULT 1;
|
|
160
|
-
ALTER TABLE settings ADD COLUMN notif_desktop_enabled INTEGER NOT NULL DEFAULT 1;
|
|
161
|
-
ALTER TABLE settings ADD COLUMN notif_evt_agent_started INTEGER NOT NULL DEFAULT 1;
|
|
162
|
-
ALTER TABLE settings ADD COLUMN notif_evt_phase_completed INTEGER NOT NULL DEFAULT 1;
|
|
163
|
-
ALTER TABLE settings ADD COLUMN notif_evt_waiting_approval INTEGER NOT NULL DEFAULT 1;
|
|
164
|
-
ALTER TABLE settings ADD COLUMN notif_evt_agent_completed INTEGER NOT NULL DEFAULT 1;
|
|
165
|
-
ALTER TABLE settings ADD COLUMN notif_evt_agent_failed INTEGER NOT NULL DEFAULT 1;
|
|
166
|
-
`,
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
version: 10,
|
|
170
|
-
sql: `
|
|
171
|
-
-- Migration 010: Add workflow flags, PR tracking to features; workflow config to settings; lifecycle migration
|
|
172
|
-
|
|
173
|
-
-- Workflow configuration flags on features
|
|
174
|
-
ALTER TABLE features ADD COLUMN open_pr INTEGER NOT NULL DEFAULT 0;
|
|
175
|
-
ALTER TABLE features ADD COLUMN auto_merge INTEGER NOT NULL DEFAULT 0;
|
|
176
|
-
ALTER TABLE features ADD COLUMN allow_prd INTEGER NOT NULL DEFAULT 0;
|
|
177
|
-
ALTER TABLE features ADD COLUMN allow_plan INTEGER NOT NULL DEFAULT 0;
|
|
178
|
-
ALTER TABLE features ADD COLUMN allow_merge INTEGER NOT NULL DEFAULT 0;
|
|
179
|
-
|
|
180
|
-
-- PR tracking state on features
|
|
181
|
-
ALTER TABLE features ADD COLUMN pr_url TEXT;
|
|
182
|
-
ALTER TABLE features ADD COLUMN pr_number INTEGER;
|
|
183
|
-
ALTER TABLE features ADD COLUMN pr_status TEXT;
|
|
184
|
-
ALTER TABLE features ADD COLUMN commit_hash TEXT;
|
|
185
|
-
ALTER TABLE features ADD COLUMN ci_status TEXT;
|
|
186
|
-
|
|
187
|
-
-- Workflow defaults on settings
|
|
188
|
-
ALTER TABLE settings ADD COLUMN workflow_open_pr_on_impl_complete INTEGER NOT NULL DEFAULT 0;
|
|
189
|
-
ALTER TABLE settings ADD COLUMN workflow_auto_merge_on_impl_complete INTEGER NOT NULL DEFAULT 0;
|
|
190
|
-
|
|
191
|
-
-- Migrate existing features with DeployAndQA lifecycle to Maintain
|
|
192
|
-
UPDATE features SET lifecycle = 'Maintain' WHERE lifecycle = 'Deploy & QA';
|
|
193
|
-
`,
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
version: 11,
|
|
197
|
-
sql: `
|
|
198
|
-
-- Migration 011: Add worktree_path to features
|
|
199
|
-
ALTER TABLE features ADD COLUMN worktree_path TEXT;
|
|
200
|
-
`,
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
version: 12,
|
|
204
|
-
sql: `
|
|
205
|
-
-- Migration 012: Add push column to features
|
|
206
|
-
ALTER TABLE features ADD COLUMN push INTEGER NOT NULL DEFAULT 0;
|
|
207
|
-
`,
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
version: 13,
|
|
211
|
-
sql: `
|
|
212
|
-
-- Migration 013: Add user_query to features for preserving verbatim user input
|
|
213
|
-
ALTER TABLE features ADD COLUMN user_query TEXT NOT NULL DEFAULT '';
|
|
214
|
-
`,
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
version: 14,
|
|
218
|
-
sql: `
|
|
219
|
-
-- Migration 014: Add approval wait timing columns to phase_timings
|
|
220
|
-
ALTER TABLE phase_timings ADD COLUMN waiting_approval_at INTEGER;
|
|
221
|
-
ALTER TABLE phase_timings ADD COLUMN approval_wait_ms INTEGER;
|
|
222
|
-
`,
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
version: 15,
|
|
226
|
-
sql: `
|
|
227
|
-
-- Migration 015: Create Repositories Table and backfill from features
|
|
228
|
-
|
|
229
|
-
-- 1. Create repositories table
|
|
230
|
-
CREATE TABLE repositories (
|
|
231
|
-
id TEXT PRIMARY KEY,
|
|
232
|
-
name TEXT NOT NULL,
|
|
233
|
-
path TEXT NOT NULL UNIQUE,
|
|
234
|
-
created_at INTEGER NOT NULL,
|
|
235
|
-
updated_at INTEGER NOT NULL
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
CREATE INDEX idx_repositories_path ON repositories(path);
|
|
239
|
-
|
|
240
|
-
-- 2. Extract unique repository_path values from features into repositories
|
|
241
|
-
INSERT INTO repositories (id, name, path, created_at, updated_at)
|
|
242
|
-
SELECT
|
|
243
|
-
lower(hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-4' || substr(hex(randomblob(2)),2) || '-' || substr('89ab', abs(random()) % 4 + 1, 1) || substr(hex(randomblob(2)),2) || '-' || hex(randomblob(6))) AS id,
|
|
244
|
-
CASE
|
|
245
|
-
WHEN instr(repository_path, '/') > 0
|
|
246
|
-
THEN replace(repository_path, rtrim(repository_path, replace(repository_path, '/', '')), '')
|
|
247
|
-
ELSE repository_path
|
|
248
|
-
END AS name,
|
|
249
|
-
repository_path AS path,
|
|
250
|
-
MIN(created_at) AS created_at,
|
|
251
|
-
MAX(updated_at) AS updated_at
|
|
252
|
-
FROM features
|
|
253
|
-
WHERE repository_path IS NOT NULL AND repository_path != ''
|
|
254
|
-
GROUP BY repository_path;
|
|
255
|
-
|
|
256
|
-
-- 3. Add repository_id column to features
|
|
257
|
-
ALTER TABLE features ADD COLUMN repository_id TEXT;
|
|
258
|
-
|
|
259
|
-
-- 4. Backfill repository_id on all existing features
|
|
260
|
-
UPDATE features SET repository_id = (
|
|
261
|
-
SELECT r.id FROM repositories r WHERE r.path = features.repository_path
|
|
262
|
-
);
|
|
263
|
-
`,
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
version: 16,
|
|
267
|
-
sql: `
|
|
268
|
-
-- Migration 016: Add soft delete support to repositories
|
|
269
|
-
ALTER TABLE repositories ADD COLUMN deleted_at INTEGER;
|
|
270
|
-
`,
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
version: 17,
|
|
274
|
-
sql: `
|
|
275
|
-
-- Migration 017: Fix repository names backfilled incorrectly in migration 015
|
|
276
|
-
-- The original substr formula extracted from the wrong position.
|
|
277
|
-
-- Correct approach: strip the last path segment using rtrim trick.
|
|
278
|
-
UPDATE repositories
|
|
279
|
-
SET name = replace(path, rtrim(path, replace(path, '/', '')), '')
|
|
280
|
-
WHERE instr(path, '/') > 0;
|
|
281
|
-
`,
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
version: 18,
|
|
285
|
-
sql: `
|
|
286
|
-
-- Migration 018: Add onboarding and approval gate default columns
|
|
287
|
-
ALTER TABLE settings ADD COLUMN onboarding_complete INTEGER NOT NULL DEFAULT 0;
|
|
288
|
-
ALTER TABLE settings ADD COLUMN approval_gate_allow_prd INTEGER NOT NULL DEFAULT 0;
|
|
289
|
-
ALTER TABLE settings ADD COLUMN approval_gate_allow_plan INTEGER NOT NULL DEFAULT 0;
|
|
290
|
-
ALTER TABLE settings ADD COLUMN approval_gate_allow_merge INTEGER NOT NULL DEFAULT 0;
|
|
291
|
-
ALTER TABLE settings ADD COLUMN approval_gate_push_on_impl_complete INTEGER NOT NULL DEFAULT 0;
|
|
292
|
-
|
|
293
|
-
-- Existing users should NOT be forced through onboarding
|
|
294
|
-
UPDATE settings SET onboarding_complete = 1 WHERE id IS NOT NULL;
|
|
295
|
-
`,
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
version: 19,
|
|
299
|
-
sql: `
|
|
300
|
-
-- Migration 019: Add CI fix tracking columns to features
|
|
301
|
-
ALTER TABLE features ADD COLUMN ci_fix_attempts INTEGER;
|
|
302
|
-
ALTER TABLE features ADD COLUMN ci_fix_history TEXT;
|
|
303
|
-
`,
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
version: 20,
|
|
307
|
-
// Migration 020: Add parent_id to features for hierarchical feature dependencies
|
|
308
|
-
// Uses custom handler because the column may already exist from a pre-rebase migration 19.
|
|
309
|
-
sql: '',
|
|
310
|
-
handler: (db) => {
|
|
311
|
-
const columns = db.pragma('table_info(features)');
|
|
312
|
-
// Backfill ci_fix columns for users whose old migration 19 added parent_id
|
|
313
|
-
// instead of ci_fix_attempts/ci_fix_history (pre-rebase ordering).
|
|
314
|
-
if (!columns.some((c) => c.name === 'ci_fix_attempts')) {
|
|
315
|
-
db.exec('ALTER TABLE features ADD COLUMN ci_fix_attempts INTEGER');
|
|
316
|
-
}
|
|
317
|
-
if (!columns.some((c) => c.name === 'ci_fix_history')) {
|
|
318
|
-
db.exec('ALTER TABLE features ADD COLUMN ci_fix_history TEXT');
|
|
319
|
-
}
|
|
320
|
-
if (!columns.some((c) => c.name === 'parent_id')) {
|
|
321
|
-
db.exec('ALTER TABLE features ADD COLUMN parent_id TEXT');
|
|
322
|
-
}
|
|
323
|
-
// CREATE INDEX IF NOT EXISTS is supported by SQLite
|
|
324
|
-
db.exec('CREATE INDEX IF NOT EXISTS idx_features_parent_id ON features(parent_id)');
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
version: 21,
|
|
329
|
-
// Migration 021: Backfill columns that may be missing due to migration 19 rebase reordering.
|
|
330
|
-
// If the old migration 19 (parent_id) ran before the rebase, ci_fix_attempts/ci_fix_history
|
|
331
|
-
// were never added. Migration 20's handler now covers fresh installs; this covers
|
|
332
|
-
// databases that already ran migration 20 with the old handler.
|
|
333
|
-
sql: '',
|
|
334
|
-
handler: (db) => {
|
|
335
|
-
const columns = db.pragma('table_info(features)');
|
|
336
|
-
if (!columns.some((c) => c.name === 'ci_fix_attempts')) {
|
|
337
|
-
db.exec('ALTER TABLE features ADD COLUMN ci_fix_attempts INTEGER');
|
|
338
|
-
}
|
|
339
|
-
if (!columns.some((c) => c.name === 'ci_fix_history')) {
|
|
340
|
-
db.exec('ALTER TABLE features ADD COLUMN ci_fix_history TEXT');
|
|
341
|
-
}
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
version: 22,
|
|
346
|
-
// Migration 022: Add PR notification event type filters to settings.
|
|
347
|
-
// Uses handler because these columns may already exist from the pre-rebase migration 19.
|
|
348
|
-
sql: '',
|
|
349
|
-
handler: (db) => {
|
|
350
|
-
const columns = db.pragma('table_info(settings)');
|
|
351
|
-
const add = (col) => {
|
|
352
|
-
if (!columns.some((c) => c.name === col)) {
|
|
353
|
-
db.exec(`ALTER TABLE settings ADD COLUMN ${col} INTEGER NOT NULL DEFAULT 1`);
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
add('notif_evt_pr_merged');
|
|
357
|
-
add('notif_evt_pr_closed');
|
|
358
|
-
add('notif_evt_pr_checks_passed');
|
|
359
|
-
add('notif_evt_pr_checks_failed');
|
|
360
|
-
},
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
version: 23,
|
|
364
|
-
sql: `
|
|
365
|
-
-- Migration 023: Back-fill repositories rows for orphaned features
|
|
366
|
-
-- Inserts a repository row for every distinct repository_path in the features table
|
|
367
|
-
-- that has no matching row in repositories. INSERT OR IGNORE ensures idempotency.
|
|
368
|
-
INSERT OR IGNORE INTO repositories (id, name, path, created_at, updated_at)
|
|
369
|
-
SELECT
|
|
370
|
-
lower(hex(randomblob(16))) AS id,
|
|
371
|
-
CASE
|
|
372
|
-
WHEN instr(repository_path, '/') > 0
|
|
373
|
-
THEN replace(repository_path, rtrim(repository_path, replace(repository_path, '/', '')), '')
|
|
374
|
-
ELSE repository_path
|
|
375
|
-
END AS name,
|
|
376
|
-
repository_path AS path,
|
|
377
|
-
strftime('%s', 'now') * 1000 AS created_at,
|
|
378
|
-
strftime('%s', 'now') * 1000 AS updated_at
|
|
379
|
-
FROM (
|
|
380
|
-
SELECT DISTINCT repository_path
|
|
381
|
-
FROM features
|
|
382
|
-
WHERE repository_path IS NOT NULL AND repository_path != ''
|
|
383
|
-
)
|
|
384
|
-
WHERE repository_path NOT IN (SELECT path FROM repositories WHERE path IS NOT NULL);
|
|
385
|
-
`,
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
version: 24,
|
|
389
|
-
// Migration 024: Add feature flag columns and CI workflow columns to settings.
|
|
390
|
-
sql: '',
|
|
391
|
-
handler: (db) => {
|
|
392
|
-
const columns = db.pragma('table_info(settings)');
|
|
393
|
-
const addNotNull = (col, dflt) => {
|
|
394
|
-
if (!columns.some((c) => c.name === col)) {
|
|
395
|
-
db.exec(`ALTER TABLE settings ADD COLUMN ${col} INTEGER NOT NULL DEFAULT ${dflt}`);
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
const addNullable = (col) => {
|
|
399
|
-
if (!columns.some((c) => c.name === col)) {
|
|
400
|
-
db.exec(`ALTER TABLE settings ADD COLUMN ${col} INTEGER`);
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
addNotNull('feature_flag_skills', '0');
|
|
404
|
-
addNotNull('feature_flag_env_deploy', '1');
|
|
405
|
-
addNotNull('feature_flag_debug', '0');
|
|
406
|
-
addNullable('ci_max_fix_attempts');
|
|
407
|
-
addNullable('ci_watch_timeout_ms');
|
|
408
|
-
addNullable('ci_log_max_chars');
|
|
409
|
-
},
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
version: 25,
|
|
413
|
-
// Migration 025: Add model_default column to settings.
|
|
414
|
-
sql: '',
|
|
415
|
-
handler: (db) => {
|
|
416
|
-
const settingsCols = db.pragma('table_info(settings)');
|
|
417
|
-
if (!settingsCols.some((c) => c.name === 'model_default')) {
|
|
418
|
-
db.exec("ALTER TABLE settings ADD COLUMN model_default TEXT NOT NULL DEFAULT 'claude-sonnet-4-6'");
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
},
|
|
422
|
-
{
|
|
423
|
-
version: 26,
|
|
424
|
-
// Migration 026: Add model_id column to agent_runs for per-run model tracking.
|
|
425
|
-
sql: '',
|
|
426
|
-
handler: (db) => {
|
|
427
|
-
const columns = db.pragma('table_info(agent_runs)');
|
|
428
|
-
if (!columns.some((c) => c.name === 'model_id')) {
|
|
429
|
-
db.exec('ALTER TABLE agent_runs ADD COLUMN model_id TEXT');
|
|
430
|
-
}
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
version: 27,
|
|
435
|
-
// Migration 027: Add fast column to features for fast mode tracking.
|
|
436
|
-
sql: '',
|
|
437
|
-
handler: (db) => {
|
|
438
|
-
const columns = db.pragma('table_info(features)');
|
|
439
|
-
if (!columns.some((c) => c.name === 'fast')) {
|
|
440
|
-
db.exec('ALTER TABLE features ADD COLUMN fast INTEGER NOT NULL DEFAULT 0');
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
},
|
|
444
|
-
{
|
|
445
|
-
version: 28,
|
|
446
|
-
// Migration 028: Add attachments JSON column to features.
|
|
447
|
-
// Also backfills fast column if missing (rebase reordered migrations 27/28,
|
|
448
|
-
// so DBs that ran the old migration 27 may have attachments but not fast).
|
|
449
|
-
sql: '',
|
|
450
|
-
handler: (db) => {
|
|
451
|
-
const columns = db.pragma('table_info(features)');
|
|
452
|
-
if (!columns.some((c) => c.name === 'fast')) {
|
|
453
|
-
db.exec('ALTER TABLE features ADD COLUMN fast INTEGER NOT NULL DEFAULT 0');
|
|
454
|
-
}
|
|
455
|
-
if (!columns.some((c) => c.name === 'attachments')) {
|
|
456
|
-
db.exec("ALTER TABLE features ADD COLUMN attachments TEXT NOT NULL DEFAULT '[]'");
|
|
457
|
-
}
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
version: 29,
|
|
462
|
-
// Migration 029: Add soft delete support to features table.
|
|
463
|
-
sql: '',
|
|
464
|
-
handler: (db) => {
|
|
465
|
-
const columns = db.pragma('table_info(features)');
|
|
466
|
-
if (!columns.some((c) => c.name === 'deleted_at')) {
|
|
467
|
-
db.exec('ALTER TABLE features ADD COLUMN deleted_at INTEGER');
|
|
468
|
-
db.exec('CREATE INDEX IF NOT EXISTS idx_features_deleted_at ON features(deleted_at)');
|
|
469
|
-
}
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
version: 30,
|
|
474
|
-
// Migration 030: Add evidence workflow settings to settings table.
|
|
475
|
-
sql: '',
|
|
476
|
-
handler: (db) => {
|
|
477
|
-
const columns = db.pragma('table_info(settings)');
|
|
478
|
-
if (!columns.some((c) => c.name === 'workflow_enable_evidence')) {
|
|
479
|
-
db.exec('ALTER TABLE settings ADD COLUMN workflow_enable_evidence INTEGER NOT NULL DEFAULT 0');
|
|
480
|
-
}
|
|
481
|
-
if (!columns.some((c) => c.name === 'workflow_commit_evidence')) {
|
|
482
|
-
db.exec('ALTER TABLE settings ADD COLUMN workflow_commit_evidence INTEGER NOT NULL DEFAULT 0');
|
|
483
|
-
}
|
|
484
|
-
},
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
version: 31,
|
|
488
|
-
// Migration 031: Add pr_mergeable column to features table for merge conflict tracking.
|
|
489
|
-
sql: '',
|
|
490
|
-
handler: (db) => {
|
|
491
|
-
const columns = db.pragma('table_info(features)');
|
|
492
|
-
if (!columns.some((c) => c.name === 'pr_mergeable')) {
|
|
493
|
-
db.exec('ALTER TABLE features ADD COLUMN pr_mergeable INTEGER');
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
},
|
|
497
|
-
{
|
|
498
|
-
version: 32,
|
|
499
|
-
// Migration 032: Change envDeploy feature flag default to enabled (1).
|
|
500
|
-
sql: `UPDATE settings SET feature_flag_env_deploy = 1 WHERE feature_flag_env_deploy = 0;`,
|
|
501
|
-
},
|
|
502
|
-
{
|
|
503
|
-
version: 33,
|
|
504
|
-
sql: `
|
|
505
|
-
-- Migration 033: Create pr_sync_lock table for cross-process poll coordination
|
|
506
|
-
CREATE TABLE IF NOT EXISTS pr_sync_lock (
|
|
507
|
-
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
508
|
-
locked_by TEXT NOT NULL,
|
|
509
|
-
locked_at INTEGER NOT NULL,
|
|
510
|
-
expires_at INTEGER NOT NULL
|
|
511
|
-
);
|
|
512
|
-
`,
|
|
513
|
-
},
|
|
514
|
-
{
|
|
515
|
-
version: 34,
|
|
516
|
-
// Migration 034: Add merge review ready and pr_blocked notification event filter columns.
|
|
517
|
-
// Uses handler because notif_evt_pr_blocked may already exist from earlier manual fixes.
|
|
518
|
-
sql: '',
|
|
519
|
-
handler: (db) => {
|
|
520
|
-
const columns = db.pragma('table_info(settings)');
|
|
521
|
-
const add = (col) => {
|
|
522
|
-
if (!columns.some((c) => c.name === col)) {
|
|
523
|
-
db.exec(`ALTER TABLE settings ADD COLUMN ${col} INTEGER NOT NULL DEFAULT 1`);
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
add('notif_evt_pr_blocked');
|
|
527
|
-
add('notif_evt_merge_review_ready');
|
|
528
|
-
},
|
|
529
|
-
},
|
|
530
|
-
];
|
|
22
|
+
export const LATEST_SCHEMA_VERSION = 34;
|
|
531
23
|
/**
|
|
532
|
-
*
|
|
533
|
-
*
|
|
24
|
+
* Resolves the migrations directory path.
|
|
25
|
+
* Works both in source (src/) and compiled (dist/) contexts.
|
|
26
|
+
*/
|
|
27
|
+
function getMigrationsDir() {
|
|
28
|
+
// import.meta.url is available in ESM; fallback to __dirname for CJS
|
|
29
|
+
// The migrations/ directory is a sibling of this file
|
|
30
|
+
return join(dirname(new URL(import.meta.url).pathname), 'migrations');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Discovers new migration files (035+) in the migrations/ directory.
|
|
34
|
+
* Files must be .js (compiled from .ts) and follow the naming convention:
|
|
35
|
+
* 035-description.js, 036-description.js, etc.
|
|
36
|
+
*
|
|
37
|
+
* Each file must export:
|
|
38
|
+
* - up(params: MigrationParams<Database.Database>): Promise<void>
|
|
39
|
+
* - down(params: MigrationParams<Database.Database>): Promise<void> (required for 35+)
|
|
40
|
+
*/
|
|
41
|
+
async function discoverNewMigrations(migrationsDir) {
|
|
42
|
+
let files;
|
|
43
|
+
try {
|
|
44
|
+
files = readdirSync(migrationsDir)
|
|
45
|
+
.filter((f) => f.endsWith('.js') && !f.endsWith('.d.js'))
|
|
46
|
+
.sort();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Directory doesn't exist or is unreadable — no new migrations
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const migrations = [];
|
|
53
|
+
for (const file of files) {
|
|
54
|
+
const filePath = join(migrationsDir, file);
|
|
55
|
+
const name = file.replace(/\.js$/, '');
|
|
56
|
+
const mod = (await import(pathToFileURL(filePath).href));
|
|
57
|
+
migrations.push({
|
|
58
|
+
name,
|
|
59
|
+
path: filePath,
|
|
60
|
+
up: async (params) => mod.up(params),
|
|
61
|
+
...(mod.down
|
|
62
|
+
? { down: async (params) => mod.down(params) }
|
|
63
|
+
: {}),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return migrations;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates a configured Umzug instance for the given database.
|
|
70
|
+
*
|
|
71
|
+
* Combines legacy inline migrations with runtime-discovered new
|
|
72
|
+
* migration files (035+) from the migrations/ directory.
|
|
534
73
|
*/
|
|
535
|
-
|
|
74
|
+
function createUmzug(db) {
|
|
75
|
+
const storage = new SQLiteMigrationStorage(db, LEGACY_MIGRATION_NAMES);
|
|
76
|
+
const migrationsDir = getMigrationsDir();
|
|
77
|
+
return new Umzug({
|
|
78
|
+
storage,
|
|
79
|
+
context: db,
|
|
80
|
+
migrations: async () => {
|
|
81
|
+
const newMigrations = await discoverNewMigrations(migrationsDir);
|
|
82
|
+
// Legacy migrations first (001–034), then new migrations (035+) sorted by name
|
|
83
|
+
return [...LEGACY_MIGRATIONS, ...newMigrations];
|
|
84
|
+
},
|
|
85
|
+
/* eslint-disable no-console */
|
|
86
|
+
logger: process.env.DEBUG_SQL
|
|
87
|
+
? {
|
|
88
|
+
info: (msg) => console.log('[umzug:info]', msg),
|
|
89
|
+
warn: (msg) => console.warn('[umzug:warn]', msg),
|
|
90
|
+
error: (msg) => console.error('[umzug:error]', msg),
|
|
91
|
+
debug: (msg) => console.debug('[umzug:debug]', msg),
|
|
92
|
+
}
|
|
93
|
+
: undefined,
|
|
94
|
+
/* eslint-enable no-console */
|
|
95
|
+
});
|
|
96
|
+
}
|
|
536
97
|
/**
|
|
537
98
|
* Runs all pending database migrations.
|
|
538
99
|
* Safe to call multiple times (idempotent).
|
|
539
100
|
*
|
|
540
|
-
*
|
|
101
|
+
* Internally creates an Umzug instance configured with:
|
|
102
|
+
* - SQLiteMigrationStorage (custom better-sqlite3 storage adapter)
|
|
103
|
+
* - 34 legacy inline migrations from legacy-migrations.ts
|
|
104
|
+
* - Runtime discovery for new migration files (35+)
|
|
105
|
+
* - Debug-level logger (when DEBUG_SQL is set)
|
|
541
106
|
*
|
|
542
107
|
* @param db - Database instance to run migrations on
|
|
543
108
|
*/
|
|
544
109
|
export async function runSQLiteMigrations(db) {
|
|
545
110
|
try {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const currentVersion = result.user_version;
|
|
549
|
-
// Run each pending migration
|
|
550
|
-
for (const migration of MIGRATIONS) {
|
|
551
|
-
if (migration.version > currentVersion) {
|
|
552
|
-
// Execute migration in a transaction
|
|
553
|
-
db.transaction(() => {
|
|
554
|
-
if (migration.sql) {
|
|
555
|
-
db.exec(migration.sql);
|
|
556
|
-
}
|
|
557
|
-
if (migration.handler) {
|
|
558
|
-
migration.handler(db);
|
|
559
|
-
}
|
|
560
|
-
db.prepare(`PRAGMA user_version = ${migration.version}`).run();
|
|
561
|
-
})();
|
|
562
|
-
}
|
|
563
|
-
}
|
|
111
|
+
const umzug = createUmzug(db);
|
|
112
|
+
await umzug.up();
|
|
564
113
|
}
|
|
565
114
|
catch (error) {
|
|
566
115
|
throw new Error(`Failed to run database migrations: ${error instanceof Error ? error.message : String(error)}`);
|