@stackmemoryai/stackmemory 0.5.31 → 0.5.34
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/agents/core/agent-task-manager.js.map +1 -1
- package/dist/cli/claude-sm.js +199 -16
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/commands/clear.js +1 -1
- package/dist/cli/commands/clear.js.map +1 -1
- package/dist/cli/commands/context.js +1 -12
- package/dist/cli/commands/context.js.map +2 -2
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/discovery.js +1 -1
- package/dist/cli/commands/discovery.js.map +1 -1
- package/dist/cli/commands/handoff.js +1 -1
- package/dist/cli/commands/handoff.js.map +1 -1
- package/dist/cli/commands/linear.js +1 -14
- package/dist/cli/commands/linear.js.map +2 -2
- package/dist/cli/commands/login.js +32 -10
- package/dist/cli/commands/login.js.map +2 -2
- package/dist/cli/commands/migrate.js +80 -22
- package/dist/cli/commands/migrate.js.map +2 -2
- package/dist/cli/commands/model.js +533 -0
- package/dist/cli/commands/model.js.map +7 -0
- package/dist/cli/commands/monitor.js +1 -1
- package/dist/cli/commands/monitor.js.map +1 -1
- package/dist/cli/commands/quality.js +1 -1
- package/dist/cli/commands/quality.js.map +1 -1
- package/dist/cli/commands/ralph.js +93 -28
- package/dist/cli/commands/ralph.js.map +2 -2
- package/dist/cli/commands/service.js +10 -3
- package/dist/cli/commands/service.js.map +2 -2
- package/dist/cli/commands/skills.js +61 -11
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/sms-notify.js +342 -22
- package/dist/cli/commands/sms-notify.js.map +3 -3
- package/dist/cli/commands/workflow.js +1 -1
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/commands/worktree.js +1 -1
- package/dist/cli/commands/worktree.js.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +2 -2
- package/dist/core/context/auto-context.js.map +1 -1
- package/dist/core/context/compaction-handler.js.map +2 -2
- package/dist/core/context/context-bridge.js.map +2 -2
- package/dist/core/context/dual-stack-manager.js +24 -8
- package/dist/core/context/dual-stack-manager.js.map +2 -2
- package/dist/core/context/enhanced-rehydration.js.map +1 -1
- package/dist/core/context/frame-database.js +41 -5
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-digest.js +6 -1
- package/dist/core/context/frame-digest.js.map +2 -2
- package/dist/core/context/frame-handoff-manager.js.map +1 -1
- package/dist/core/context/frame-lifecycle-hooks.js +119 -0
- package/dist/core/context/frame-lifecycle-hooks.js.map +7 -0
- package/dist/core/context/frame-manager.js +56 -9
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/context/frame-stack.js +29 -0
- package/dist/core/context/frame-stack.js.map +2 -2
- package/dist/core/context/incremental-gc.js.map +2 -2
- package/dist/core/context/index.js +4 -22
- package/dist/core/context/index.js.map +2 -2
- package/dist/core/context/permission-manager.js +0 -11
- package/dist/core/context/permission-manager.js.map +2 -2
- package/dist/core/context/recursive-context-manager.js +15 -9
- package/dist/core/context/recursive-context-manager.js.map +2 -2
- package/dist/core/context/refactored-frame-manager.js +140 -34
- package/dist/core/context/refactored-frame-manager.js.map +3 -3
- package/dist/core/context/shared-context-layer.js +0 -11
- package/dist/core/context/shared-context-layer.js.map +2 -2
- package/dist/core/context/stack-merge-resolver.js.map +1 -1
- package/dist/core/context/validation.js +6 -1
- package/dist/core/context/validation.js.map +2 -2
- package/dist/core/database/database-adapter.js.map +1 -1
- package/dist/core/database/paradedb-adapter.js.map +1 -1
- package/dist/core/database/query-router.js.map +1 -1
- package/dist/core/database/sqlite-adapter.js.map +1 -1
- package/dist/core/digest/frame-digest-integration.js.map +1 -1
- package/dist/core/digest/hybrid-digest-generator.js.map +1 -1
- package/dist/core/digest/types.js.map +1 -1
- package/dist/core/errors/index.js +249 -0
- package/dist/core/errors/index.js.map +2 -2
- package/dist/core/frame/workflow-templates.js.map +2 -2
- package/dist/core/merge/conflict-detector.js.map +1 -1
- package/dist/core/merge/resolution-engine.js.map +1 -1
- package/dist/core/merge/stack-diff.js.map +1 -1
- package/dist/core/models/fallback-monitor.js +229 -0
- package/dist/core/models/fallback-monitor.js.map +7 -0
- package/dist/core/models/model-router.js +340 -0
- package/dist/core/models/model-router.js.map +7 -0
- package/dist/core/monitoring/error-handler.js +37 -270
- package/dist/core/monitoring/error-handler.js.map +3 -3
- package/dist/core/monitoring/session-monitor.js.map +1 -1
- package/dist/core/performance/lazy-context-loader.js.map +1 -1
- package/dist/core/performance/optimized-frame-context.js.map +1 -1
- package/dist/core/retrieval/context-retriever.js.map +1 -1
- package/dist/core/retrieval/graph-retrieval.js.map +1 -1
- package/dist/core/retrieval/hierarchical-retrieval.js.map +1 -1
- package/dist/core/retrieval/llm-context-retrieval.js.map +1 -1
- package/dist/core/retrieval/retrieval-benchmarks.js.map +1 -1
- package/dist/core/retrieval/summary-generator.js.map +1 -1
- package/dist/core/retrieval/types.js.map +1 -1
- package/dist/core/storage/chromadb-adapter.js.map +1 -1
- package/dist/core/storage/infinite-storage.js.map +1 -1
- package/dist/core/storage/two-tier-storage.js.map +1 -1
- package/dist/features/tasks/task-aware-context.js.map +1 -1
- package/dist/features/web/server/index.js +1 -1
- package/dist/features/web/server/index.js.map +1 -1
- package/dist/hooks/claude-code-whatsapp-hook.js +197 -0
- package/dist/hooks/claude-code-whatsapp-hook.js.map +7 -0
- package/dist/hooks/linear-task-picker.js +1 -1
- package/dist/hooks/linear-task-picker.js.map +2 -2
- package/dist/hooks/schemas.js +105 -1
- package/dist/hooks/schemas.js.map +2 -2
- package/dist/hooks/session-summary.js +5 -1
- package/dist/hooks/session-summary.js.map +2 -2
- package/dist/hooks/sms-action-runner.js +16 -1
- package/dist/hooks/sms-action-runner.js.map +2 -2
- package/dist/hooks/sms-notify.js +4 -2
- package/dist/hooks/sms-notify.js.map +2 -2
- package/dist/hooks/sms-webhook.js +23 -2
- package/dist/hooks/sms-webhook.js.map +2 -2
- package/dist/hooks/whatsapp-commands.js +516 -0
- package/dist/hooks/whatsapp-commands.js.map +7 -0
- package/dist/hooks/whatsapp-scheduler.js +317 -0
- package/dist/hooks/whatsapp-scheduler.js.map +7 -0
- package/dist/hooks/whatsapp-sync.js +409 -0
- package/dist/hooks/whatsapp-sync.js.map +7 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/mcp/handlers/context-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/discovery-handlers.js.map +1 -1
- package/dist/integrations/mcp/server.js +1 -1
- package/dist/integrations/mcp/server.js.map +1 -1
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +1 -1
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +1 -1
- package/dist/integrations/ralph/context/stackmemory-context-loader.js +1 -1
- package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +1 -1
- package/dist/integrations/ralph/learning/pattern-learner.js +1 -1
- package/dist/integrations/ralph/learning/pattern-learner.js.map +1 -1
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +1 -1
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +1 -1
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +1 -1
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +1 -1
- package/dist/integrations/ralph/visualization/ralph-debugger.js +1 -1
- package/dist/integrations/ralph/visualization/ralph-debugger.js.map +1 -1
- package/dist/mcp/stackmemory-mcp-server.js +1 -1
- package/dist/mcp/stackmemory-mcp-server.js.map +1 -1
- package/dist/skills/claude-skills.js.map +1 -1
- package/dist/skills/recursive-agent-orchestrator.js.map +1 -1
- package/dist/skills/unified-rlm-orchestrator.js.map +1 -1
- package/package.json +2 -3
|
@@ -6,6 +6,11 @@ const __dirname = __pathDirname(__filename);
|
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { Pool } from "pg";
|
|
8
8
|
import Database from "better-sqlite3";
|
|
9
|
+
import {
|
|
10
|
+
DatabaseError,
|
|
11
|
+
ValidationError,
|
|
12
|
+
ErrorCode
|
|
13
|
+
} from "../../core/errors/index.js";
|
|
9
14
|
const MIGRATIONS = [
|
|
10
15
|
{
|
|
11
16
|
version: 1,
|
|
@@ -57,34 +62,54 @@ function isPg() {
|
|
|
57
62
|
async function connect() {
|
|
58
63
|
if (isPg()) {
|
|
59
64
|
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
60
|
-
await pool.query(
|
|
65
|
+
await pool.query(
|
|
66
|
+
`CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT NOW(), description TEXT)`
|
|
67
|
+
);
|
|
61
68
|
return { kind: "pg", pg: pool };
|
|
62
69
|
} else {
|
|
63
70
|
const path = process.env.DATABASE_URL || ".stackmemory/railway.db";
|
|
64
71
|
const db = new Database(path);
|
|
65
|
-
db.exec(
|
|
72
|
+
db.exec(
|
|
73
|
+
`CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at DATETIME DEFAULT CURRENT_TIMESTAMP, description TEXT)`
|
|
74
|
+
);
|
|
66
75
|
return { kind: "sqlite", sqlite: db };
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
async function getCurrentVersion(m) {
|
|
70
79
|
if (m.kind === "pg") {
|
|
71
|
-
const r = await m.pg.query(
|
|
80
|
+
const r = await m.pg.query(
|
|
81
|
+
"SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version"
|
|
82
|
+
);
|
|
72
83
|
return Number(r.rows[0]?.v || 0);
|
|
73
84
|
}
|
|
74
|
-
const row = m.sqlite.prepare(
|
|
85
|
+
const row = m.sqlite.prepare(
|
|
86
|
+
"SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version"
|
|
87
|
+
).get();
|
|
75
88
|
return Number(row?.v || 0);
|
|
76
89
|
}
|
|
77
90
|
async function listApplied(m) {
|
|
78
91
|
if (m.kind === "pg") {
|
|
79
|
-
const r = await m.pg.query(
|
|
80
|
-
|
|
92
|
+
const r = await m.pg.query(
|
|
93
|
+
"SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC"
|
|
94
|
+
);
|
|
95
|
+
return r.rows.map((row) => ({
|
|
96
|
+
version: Number(row.version),
|
|
97
|
+
description: row.description
|
|
98
|
+
}));
|
|
81
99
|
}
|
|
82
|
-
const rows = m.sqlite.prepare(
|
|
83
|
-
|
|
100
|
+
const rows = m.sqlite.prepare(
|
|
101
|
+
"SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC"
|
|
102
|
+
).all();
|
|
103
|
+
return rows.map((row) => ({
|
|
104
|
+
version: Number(row.version),
|
|
105
|
+
description: row.description
|
|
106
|
+
}));
|
|
84
107
|
}
|
|
85
108
|
async function applyTo(m, target) {
|
|
86
109
|
const current = await getCurrentVersion(m);
|
|
87
|
-
const pending = MIGRATIONS.filter(
|
|
110
|
+
const pending = MIGRATIONS.filter(
|
|
111
|
+
(mig) => mig.version > current && mig.version <= target
|
|
112
|
+
);
|
|
88
113
|
for (const mig of pending) {
|
|
89
114
|
if (m.kind === "pg") {
|
|
90
115
|
for (const s of mig.statements) {
|
|
@@ -93,7 +118,10 @@ async function applyTo(m, target) {
|
|
|
93
118
|
} catch {
|
|
94
119
|
}
|
|
95
120
|
}
|
|
96
|
-
await m.pg.query(
|
|
121
|
+
await m.pg.query(
|
|
122
|
+
"INSERT INTO railway_schema_version (version, description) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING",
|
|
123
|
+
[mig.version, mig.description]
|
|
124
|
+
);
|
|
97
125
|
} else {
|
|
98
126
|
m.sqlite.exec("BEGIN");
|
|
99
127
|
try {
|
|
@@ -103,11 +131,17 @@ async function applyTo(m, target) {
|
|
|
103
131
|
} catch {
|
|
104
132
|
}
|
|
105
133
|
}
|
|
106
|
-
m.sqlite.prepare(
|
|
134
|
+
m.sqlite.prepare(
|
|
135
|
+
"INSERT OR IGNORE INTO railway_schema_version (version, description) VALUES (?, ?)"
|
|
136
|
+
).run(mig.version, mig.description);
|
|
107
137
|
m.sqlite.exec("COMMIT");
|
|
108
138
|
} catch {
|
|
109
139
|
m.sqlite.exec("ROLLBACK");
|
|
110
|
-
throw new
|
|
140
|
+
throw new DatabaseError(
|
|
141
|
+
`Migration ${mig.version} failed`,
|
|
142
|
+
ErrorCode.DB_MIGRATION_FAILED,
|
|
143
|
+
{ version: mig.version, description: mig.description }
|
|
144
|
+
);
|
|
111
145
|
}
|
|
112
146
|
}
|
|
113
147
|
console.log(`Applied migration v${mig.version}: ${mig.description}`);
|
|
@@ -120,17 +154,24 @@ async function rollbackTo(m, target) {
|
|
|
120
154
|
return;
|
|
121
155
|
}
|
|
122
156
|
if (m.kind === "pg") {
|
|
123
|
-
await m.pg.query("DELETE FROM railway_schema_version WHERE version > $1", [
|
|
157
|
+
await m.pg.query("DELETE FROM railway_schema_version WHERE version > $1", [
|
|
158
|
+
target
|
|
159
|
+
]);
|
|
124
160
|
} else {
|
|
125
|
-
m.sqlite.prepare(
|
|
161
|
+
m.sqlite.prepare(
|
|
162
|
+
"DELETE FROM railway_schema_version WHERE version > ?"
|
|
163
|
+
).run(target);
|
|
126
164
|
}
|
|
127
|
-
console.log(
|
|
165
|
+
console.log(
|
|
166
|
+
`Rolled back schema version pointer from ${current} to ${target}`
|
|
167
|
+
);
|
|
128
168
|
}
|
|
129
169
|
async function main() {
|
|
130
170
|
const program = new Command();
|
|
131
171
|
program.name("railway-migrate").description("Manage Railway server schema migrations").option("-d, --database <url>", "DATABASE_URL override");
|
|
132
172
|
program.command("list").description("List applied migrations").action(async () => {
|
|
133
|
-
if (program.opts().database)
|
|
173
|
+
if (program.opts().database)
|
|
174
|
+
process.env.DATABASE_URL = program.opts().database;
|
|
134
175
|
const m = await connect();
|
|
135
176
|
const applied = await listApplied(m);
|
|
136
177
|
const current = await getCurrentVersion(m);
|
|
@@ -140,7 +181,8 @@ async function main() {
|
|
|
140
181
|
process.exit(0);
|
|
141
182
|
});
|
|
142
183
|
program.command("status").description("Show current version and pending migrations").action(async () => {
|
|
143
|
-
if (program.opts().database)
|
|
184
|
+
if (program.opts().database)
|
|
185
|
+
process.env.DATABASE_URL = program.opts().database;
|
|
144
186
|
const m = await connect();
|
|
145
187
|
const current = await getCurrentVersion(m);
|
|
146
188
|
const latest = Math.max(...MIGRATIONS.map((m2) => m2.version));
|
|
@@ -154,21 +196,37 @@ async function main() {
|
|
|
154
196
|
}
|
|
155
197
|
process.exit(0);
|
|
156
198
|
});
|
|
157
|
-
program.command("apply").description("Apply migrations up to a target").option(
|
|
158
|
-
|
|
199
|
+
program.command("apply").description("Apply migrations up to a target").option(
|
|
200
|
+
"--to <version|latest>",
|
|
201
|
+
'Target version (number or "latest")',
|
|
202
|
+
"latest"
|
|
203
|
+
).action(async (cmd) => {
|
|
204
|
+
if (program.opts().database)
|
|
205
|
+
process.env.DATABASE_URL = program.opts().database;
|
|
159
206
|
const m = await connect();
|
|
160
207
|
const latest = Math.max(...MIGRATIONS.map((m2) => m2.version));
|
|
161
208
|
const target = cmd.to === "latest" ? latest : parseInt(cmd.to, 10);
|
|
162
|
-
if (!Number.isFinite(target))
|
|
209
|
+
if (!Number.isFinite(target))
|
|
210
|
+
throw new ValidationError(
|
|
211
|
+
"Invalid target version",
|
|
212
|
+
ErrorCode.INVALID_INPUT,
|
|
213
|
+
{ target: cmd.to }
|
|
214
|
+
);
|
|
163
215
|
await applyTo(m, target);
|
|
164
216
|
console.log("Done.");
|
|
165
217
|
process.exit(0);
|
|
166
218
|
});
|
|
167
219
|
program.command("rollback").description("Rollback schema version pointer (non-destructive)").option("--to <version>", "Target version number", "0").action(async (cmd) => {
|
|
168
|
-
if (program.opts().database)
|
|
220
|
+
if (program.opts().database)
|
|
221
|
+
process.env.DATABASE_URL = program.opts().database;
|
|
169
222
|
const m = await connect();
|
|
170
223
|
const target = parseInt(cmd.to, 10);
|
|
171
|
-
if (!Number.isFinite(target))
|
|
224
|
+
if (!Number.isFinite(target))
|
|
225
|
+
throw new ValidationError(
|
|
226
|
+
"Invalid target version",
|
|
227
|
+
ErrorCode.INVALID_INPUT,
|
|
228
|
+
{ target: cmd.to }
|
|
229
|
+
);
|
|
172
230
|
await rollbackTo(m, target);
|
|
173
231
|
console.log("Done.");
|
|
174
232
|
process.exit(0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/commands/migrate.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Railway schema migration CLI\n * Usage examples:\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts list\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts status\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts apply --to latest\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts rollback --to 2\n */\n\nimport { Command } from 'commander';\nimport { Pool } from 'pg';\nimport Database from 'better-sqlite3';\n\ntype DbKind = 'pg' | 'sqlite';\n\ninterface Migrator {\n kind: DbKind;\n pg?: Pool;\n sqlite?: Database.Database;\n}\n\nconst MIGRATIONS: Array<{ version: number; description: string; statements: string[] }> = [\n {\n version: 1,\n description: 'base schema',\n statements: [\n // contexts\n `CREATE TABLE IF NOT EXISTS contexts (id ${isPg() ? 'BIGSERIAL' : 'INTEGER PRIMARY KEY AUTOINCREMENT'} PRIMARY KEY, project_id TEXT NOT NULL, content TEXT NOT NULL, type TEXT DEFAULT 'general', ${isPg() ? \"metadata JSONB DEFAULT '{}'::jsonb\" : \"metadata TEXT DEFAULT '{}'\"}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // api_keys\n `CREATE TABLE IF NOT EXISTS api_keys (id ${isPg() ? 'BIGSERIAL' : 'INTEGER PRIMARY KEY AUTOINCREMENT'} PRIMARY KEY, key_hash TEXT UNIQUE NOT NULL, user_id TEXT NOT NULL, name TEXT, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, ${isPg() ? 'last_used TIMESTAMPTZ' : 'last_used DATETIME'}, revoked ${isPg() ? 'BOOLEAN' : 'BOOLEAN'} DEFAULT ${isPg() ? 'false' : '0'})`,\n // users with role\n `CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, email TEXT, name TEXT, tier TEXT DEFAULT 'free', role TEXT DEFAULT 'user', created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // projects\n `CREATE TABLE IF NOT EXISTS projects (id TEXT PRIMARY KEY, name TEXT, is_public ${isPg() ? 'BOOLEAN' : 'BOOLEAN'} DEFAULT ${isPg() ? 'false' : '0'}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // project members\n `CREATE TABLE IF NOT EXISTS project_members (project_id TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL ${isPg() ? '' : \"CHECK (role IN ('admin','owner','editor','viewer'))\"}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, PRIMARY KEY (project_id, user_id))`,\n // indexes\n `CREATE INDEX IF NOT EXISTS idx_contexts_project ON contexts(project_id)`,\n `CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash)`,\n `CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)`,\n `CREATE INDEX IF NOT EXISTS idx_project_members_user ON project_members(user_id)`\n ],\n },\n {\n version: 2,\n description: 'admin sessions',\n statements: [\n `CREATE TABLE IF NOT EXISTS admin_sessions (id TEXT PRIMARY KEY, user_id TEXT NOT NULL, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, expires_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} NOT NULL, user_agent TEXT, ip TEXT)`,\n `CREATE INDEX IF NOT EXISTS idx_admin_sessions_user ON admin_sessions(user_id)`\n ],\n },\n {\n version: 3,\n description: 'role enums & checks',\n statements: [\n // PG enum upgrades; for SQLite CHECK already present\n `CREATE TYPE user_role AS ENUM ('admin','user')`,\n `CREATE TYPE member_role AS ENUM ('admin','owner','editor','viewer')`,\n `ALTER TABLE users ALTER COLUMN role TYPE user_role USING role::user_role`,\n `ALTER TABLE project_members ALTER COLUMN role TYPE member_role USING role::member_role`,\n `ALTER TABLE project_members ADD CONSTRAINT project_members_role_check CHECK (role IN ('admin','owner','editor','viewer'))`,\n `ALTER TABLE users ADD CONSTRAINT users_role_check CHECK (role IN ('admin','user'))`\n ],\n },\n];\n\nfunction isPg(): boolean {\n const url = process.env.DATABASE_URL || '';\n return url.startsWith('postgres://') || url.startsWith('postgresql://');\n}\n\nasync function connect(): Promise<Migrator> {\n if (isPg()) {\n const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n // ensure version table\n await pool.query(`CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT NOW(), description TEXT)`);\n return { kind: 'pg', pg: pool };\n } else {\n const path = process.env.DATABASE_URL || '.stackmemory/railway.db';\n const db = new Database(path);\n db.exec(`CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at DATETIME DEFAULT CURRENT_TIMESTAMP, description TEXT)`);\n return { kind: 'sqlite', sqlite: db };\n }\n}\n\nasync function getCurrentVersion(m: Migrator): Promise<number> {\n if (m.kind === 'pg') {\n const r = await m.pg!.query('SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version');\n return Number(r.rows[0]?.v || 0);\n }\n const row = m.sqlite!.prepare('SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version').get() as any;\n return Number(row?.v || 0);\n}\n\nasync function listApplied(m: Migrator): Promise<Array<{ version: number; description: string }>> {\n if (m.kind === 'pg') {\n const r = await m.pg!.query('SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC');\n return r.rows.map((row) => ({ version: Number(row.version), description: row.description }));\n }\n const rows = m.sqlite!.prepare('SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC').all() as any[];\n return rows.map((row) => ({ version: Number(row.version), description: row.description }));\n}\n\nasync function applyTo(m: Migrator, target: number): Promise<void> {\n const current = await getCurrentVersion(m);\n const pending = MIGRATIONS.filter((mig) => mig.version > current && mig.version <= target);\n for (const mig of pending) {\n if (m.kind === 'pg') {\n for (const s of mig.statements) {\n try { await m.pg!.query(s); } catch {}\n }\n await m.pg!.query('INSERT INTO railway_schema_version (version, description) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING', [mig.version, mig.description]);\n } else {\n m.sqlite!.exec('BEGIN');\n try {\n for (const s of mig.statements) {\n try { m.sqlite!.exec(s); } catch {}\n }\n m.sqlite!.prepare('INSERT OR IGNORE INTO railway_schema_version (version, description) VALUES (?, ?)').run(mig.version, mig.description);\n m.sqlite!.exec('COMMIT');\n } catch {\n m.sqlite!.exec('ROLLBACK');\n throw new Error(`Migration ${mig.version} failed`);\n }\n }\n console.log(`Applied migration v${mig.version}: ${mig.description}`);\n }\n}\n\nasync function rollbackTo(m: Migrator, target: number): Promise<void> {\n const current = await getCurrentVersion(m);\n if (target >= current) {\n console.log('Nothing to rollback');\n return;\n }\n // Soft rollback: move version pointer back; does not drop objects\n if (m.kind === 'pg') {\n await m.pg!.query('DELETE FROM railway_schema_version WHERE version > $1', [target]);\n } else {\n m.sqlite!.prepare('DELETE FROM railway_schema_version WHERE version > ?').run(target);\n }\n console.log(`Rolled back schema version pointer from ${current} to ${target}`);\n}\n\nasync function main() {\n const program = new Command();\n program\n .name('railway-migrate')\n .description('Manage Railway server schema migrations')\n .option('-d, --database <url>', 'DATABASE_URL override');\n\n program\n .command('list')\n .description('List applied migrations')\n .action(async () => {\n if (program.opts().database) process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const applied = await listApplied(m);\n const current = await getCurrentVersion(m);\n console.log('Current version:', current);\n if (applied.length === 0) console.log('(no migrations applied)');\n applied.forEach((a) => console.log(`v${a.version} - ${a.description}`));\n process.exit(0);\n });\n\n program\n .command('status')\n .description('Show current version and pending migrations')\n .action(async () => {\n if (program.opts().database) process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const current = await getCurrentVersion(m);\n const latest = Math.max(...MIGRATIONS.map((m) => m.version));\n const pending = MIGRATIONS.filter((mig) => mig.version > current);\n console.log('Current version:', current);\n console.log('Latest available:', latest);\n if (pending.length === 0) console.log('No pending migrations.');\n else {\n console.log('Pending:');\n pending.forEach((p) => console.log(`- v${p.version} ${p.description}`));\n }\n process.exit(0);\n });\n\n program\n .command('apply')\n .description('Apply migrations up to a target')\n .option('--to <version|latest>', 'Target version (number or \"latest\")', 'latest')\n .action(async (cmd) => {\n if (program.opts().database) process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const latest = Math.max(...MIGRATIONS.map((m) => m.version));\n const target = cmd.to === 'latest' ? latest : parseInt(cmd.to, 10);\n if (!Number.isFinite(target)) throw new Error('Invalid target');\n await applyTo(m, target);\n console.log('Done.');\n process.exit(0);\n });\n\n program\n .command('rollback')\n .description('Rollback schema version pointer (non-destructive)')\n .option('--to <version>', 'Target version number', '0')\n .action(async (cmd) => {\n if (program.opts().database) process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const target = parseInt(cmd.to, 10);\n if (!Number.isFinite(target)) throw new Error('Invalid target');\n await rollbackTo(m, target);\n console.log('Done.');\n process.exit(0);\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n\n"],
|
|
5
|
-
"mappings": ";;;;;AAUA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAAO,cAAc;
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Railway schema migration CLI\n * Usage examples:\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts list\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts status\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts apply --to latest\n * - DATABASE_URL=... tsx src/cli/commands/migrate.ts rollback --to 2\n */\n\nimport { Command } from 'commander';\nimport { Pool } from 'pg';\nimport Database from 'better-sqlite3';\nimport {\n DatabaseError,\n ValidationError,\n ErrorCode,\n} from '../../core/errors/index.js';\n\ntype DbKind = 'pg' | 'sqlite';\n\ninterface Migrator {\n kind: DbKind;\n pg?: Pool;\n sqlite?: Database.Database;\n}\n\nconst MIGRATIONS: Array<{\n version: number;\n description: string;\n statements: string[];\n}> = [\n {\n version: 1,\n description: 'base schema',\n statements: [\n // contexts\n `CREATE TABLE IF NOT EXISTS contexts (id ${isPg() ? 'BIGSERIAL' : 'INTEGER PRIMARY KEY AUTOINCREMENT'} PRIMARY KEY, project_id TEXT NOT NULL, content TEXT NOT NULL, type TEXT DEFAULT 'general', ${isPg() ? \"metadata JSONB DEFAULT '{}'::jsonb\" : \"metadata TEXT DEFAULT '{}'\"}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // api_keys\n `CREATE TABLE IF NOT EXISTS api_keys (id ${isPg() ? 'BIGSERIAL' : 'INTEGER PRIMARY KEY AUTOINCREMENT'} PRIMARY KEY, key_hash TEXT UNIQUE NOT NULL, user_id TEXT NOT NULL, name TEXT, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, ${isPg() ? 'last_used TIMESTAMPTZ' : 'last_used DATETIME'}, revoked ${isPg() ? 'BOOLEAN' : 'BOOLEAN'} DEFAULT ${isPg() ? 'false' : '0'})`,\n // users with role\n `CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, email TEXT, name TEXT, tier TEXT DEFAULT 'free', role TEXT DEFAULT 'user', created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // projects\n `CREATE TABLE IF NOT EXISTS projects (id TEXT PRIMARY KEY, name TEXT, is_public ${isPg() ? 'BOOLEAN' : 'BOOLEAN'} DEFAULT ${isPg() ? 'false' : '0'}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, updated_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'})`,\n // project members\n `CREATE TABLE IF NOT EXISTS project_members (project_id TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL ${isPg() ? '' : \"CHECK (role IN ('admin','owner','editor','viewer'))\"}, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, PRIMARY KEY (project_id, user_id))`,\n // indexes\n `CREATE INDEX IF NOT EXISTS idx_contexts_project ON contexts(project_id)`,\n `CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash)`,\n `CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)`,\n `CREATE INDEX IF NOT EXISTS idx_project_members_user ON project_members(user_id)`,\n ],\n },\n {\n version: 2,\n description: 'admin sessions',\n statements: [\n `CREATE TABLE IF NOT EXISTS admin_sessions (id TEXT PRIMARY KEY, user_id TEXT NOT NULL, created_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} DEFAULT ${isPg() ? 'NOW()' : 'CURRENT_TIMESTAMP'}, expires_at ${isPg() ? 'TIMESTAMPTZ' : 'DATETIME'} NOT NULL, user_agent TEXT, ip TEXT)`,\n `CREATE INDEX IF NOT EXISTS idx_admin_sessions_user ON admin_sessions(user_id)`,\n ],\n },\n {\n version: 3,\n description: 'role enums & checks',\n statements: [\n // PG enum upgrades; for SQLite CHECK already present\n `CREATE TYPE user_role AS ENUM ('admin','user')`,\n `CREATE TYPE member_role AS ENUM ('admin','owner','editor','viewer')`,\n `ALTER TABLE users ALTER COLUMN role TYPE user_role USING role::user_role`,\n `ALTER TABLE project_members ALTER COLUMN role TYPE member_role USING role::member_role`,\n `ALTER TABLE project_members ADD CONSTRAINT project_members_role_check CHECK (role IN ('admin','owner','editor','viewer'))`,\n `ALTER TABLE users ADD CONSTRAINT users_role_check CHECK (role IN ('admin','user'))`,\n ],\n },\n];\n\nfunction isPg(): boolean {\n const url = process.env.DATABASE_URL || '';\n return url.startsWith('postgres://') || url.startsWith('postgresql://');\n}\n\nasync function connect(): Promise<Migrator> {\n if (isPg()) {\n const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n // ensure version table\n await pool.query(\n `CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT NOW(), description TEXT)`\n );\n return { kind: 'pg', pg: pool };\n } else {\n const path = process.env.DATABASE_URL || '.stackmemory/railway.db';\n const db = new Database(path);\n db.exec(\n `CREATE TABLE IF NOT EXISTS railway_schema_version (version INTEGER PRIMARY KEY, applied_at DATETIME DEFAULT CURRENT_TIMESTAMP, description TEXT)`\n );\n return { kind: 'sqlite', sqlite: db };\n }\n}\n\nasync function getCurrentVersion(m: Migrator): Promise<number> {\n if (m.kind === 'pg') {\n const r = await m.pg!.query(\n 'SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version'\n );\n return Number(r.rows[0]?.v || 0);\n }\n const row = m\n .sqlite!.prepare(\n 'SELECT COALESCE(MAX(version), 0) AS v FROM railway_schema_version'\n )\n .get() as any;\n return Number(row?.v || 0);\n}\n\nasync function listApplied(\n m: Migrator\n): Promise<Array<{ version: number; description: string }>> {\n if (m.kind === 'pg') {\n const r = await m.pg!.query(\n 'SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC'\n );\n return r.rows.map((row) => ({\n version: Number(row.version),\n description: row.description,\n }));\n }\n const rows = m\n .sqlite!.prepare(\n 'SELECT version, description, applied_at FROM railway_schema_version ORDER BY version ASC'\n )\n .all() as any[];\n return rows.map((row) => ({\n version: Number(row.version),\n description: row.description,\n }));\n}\n\nasync function applyTo(m: Migrator, target: number): Promise<void> {\n const current = await getCurrentVersion(m);\n const pending = MIGRATIONS.filter(\n (mig) => mig.version > current && mig.version <= target\n );\n for (const mig of pending) {\n if (m.kind === 'pg') {\n for (const s of mig.statements) {\n try {\n await m.pg!.query(s);\n } catch {}\n }\n await m.pg!.query(\n 'INSERT INTO railway_schema_version (version, description) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING',\n [mig.version, mig.description]\n );\n } else {\n m.sqlite!.exec('BEGIN');\n try {\n for (const s of mig.statements) {\n try {\n m.sqlite!.exec(s);\n } catch {}\n }\n m.sqlite!.prepare(\n 'INSERT OR IGNORE INTO railway_schema_version (version, description) VALUES (?, ?)'\n ).run(mig.version, mig.description);\n m.sqlite!.exec('COMMIT');\n } catch {\n m.sqlite!.exec('ROLLBACK');\n throw new DatabaseError(\n `Migration ${mig.version} failed`,\n ErrorCode.DB_MIGRATION_FAILED,\n { version: mig.version, description: mig.description }\n );\n }\n }\n console.log(`Applied migration v${mig.version}: ${mig.description}`);\n }\n}\n\nasync function rollbackTo(m: Migrator, target: number): Promise<void> {\n const current = await getCurrentVersion(m);\n if (target >= current) {\n console.log('Nothing to rollback');\n return;\n }\n // Soft rollback: move version pointer back; does not drop objects\n if (m.kind === 'pg') {\n await m.pg!.query('DELETE FROM railway_schema_version WHERE version > $1', [\n target,\n ]);\n } else {\n m.sqlite!.prepare(\n 'DELETE FROM railway_schema_version WHERE version > ?'\n ).run(target);\n }\n console.log(\n `Rolled back schema version pointer from ${current} to ${target}`\n );\n}\n\nasync function main() {\n const program = new Command();\n program\n .name('railway-migrate')\n .description('Manage Railway server schema migrations')\n .option('-d, --database <url>', 'DATABASE_URL override');\n\n program\n .command('list')\n .description('List applied migrations')\n .action(async () => {\n if (program.opts().database)\n process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const applied = await listApplied(m);\n const current = await getCurrentVersion(m);\n console.log('Current version:', current);\n if (applied.length === 0) console.log('(no migrations applied)');\n applied.forEach((a) => console.log(`v${a.version} - ${a.description}`));\n process.exit(0);\n });\n\n program\n .command('status')\n .description('Show current version and pending migrations')\n .action(async () => {\n if (program.opts().database)\n process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const current = await getCurrentVersion(m);\n const latest = Math.max(...MIGRATIONS.map((m) => m.version));\n const pending = MIGRATIONS.filter((mig) => mig.version > current);\n console.log('Current version:', current);\n console.log('Latest available:', latest);\n if (pending.length === 0) console.log('No pending migrations.');\n else {\n console.log('Pending:');\n pending.forEach((p) => console.log(`- v${p.version} ${p.description}`));\n }\n process.exit(0);\n });\n\n program\n .command('apply')\n .description('Apply migrations up to a target')\n .option(\n '--to <version|latest>',\n 'Target version (number or \"latest\")',\n 'latest'\n )\n .action(async (cmd) => {\n if (program.opts().database)\n process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const latest = Math.max(...MIGRATIONS.map((m) => m.version));\n const target = cmd.to === 'latest' ? latest : parseInt(cmd.to, 10);\n if (!Number.isFinite(target))\n throw new ValidationError(\n 'Invalid target version',\n ErrorCode.INVALID_INPUT,\n { target: cmd.to }\n );\n await applyTo(m, target);\n console.log('Done.');\n process.exit(0);\n });\n\n program\n .command('rollback')\n .description('Rollback schema version pointer (non-destructive)')\n .option('--to <version>', 'Target version number', '0')\n .action(async (cmd) => {\n if (program.opts().database)\n process.env.DATABASE_URL = program.opts().database;\n const m = await connect();\n const target = parseInt(cmd.to, 10);\n if (!Number.isFinite(target))\n throw new ValidationError(\n 'Invalid target version',\n ErrorCode.INVALID_INPUT,\n { target: cmd.to }\n );\n await rollbackTo(m, target);\n console.log('Done.');\n process.exit(0);\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["m"]
|
|
7
7
|
}
|