@geekbeer/minion 3.23.0 → 3.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/core/db.js +70 -7
  2. package/package.json +1 -1
package/core/db.js CHANGED
@@ -451,9 +451,12 @@ function migrateSchema(db) {
451
451
 
452
452
  console.log('[DB] Migration 3 complete: memories.project_id added')
453
453
  } catch (err) {
454
- // Column may already exist (duplicate column error)
455
- console.warn(`[DB] Migration 3 skipped: ${err.message}`)
456
- try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (3)") } catch {}
454
+ if (hasColumn(db, 'memories', 'project_id')) {
455
+ console.warn(`[DB] Migration 3 skipped (column already exists): ${err.message}`)
456
+ try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (3)") } catch {}
457
+ } else {
458
+ console.error(`[DB] Migration 3 FAILED — memories.project_id not added: ${err.message}`)
459
+ }
457
460
  }
458
461
  }
459
462
 
@@ -472,8 +475,12 @@ function migrateSchema(db) {
472
475
 
473
476
  console.log('[DB] Migration 4 complete: chat_sessions.workspace_id added')
474
477
  } catch (err) {
475
- console.warn(`[DB] Migration 4 skipped: ${err.message}`)
476
- try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (4)") } catch {}
478
+ if (hasColumn(db, 'chat_sessions', 'workspace_id')) {
479
+ console.warn(`[DB] Migration 4 skipped (column already exists): ${err.message}`)
480
+ try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (4)") } catch {}
481
+ } else {
482
+ console.error(`[DB] Migration 4 FAILED — chat_sessions.workspace_id not added: ${err.message}`)
483
+ }
477
484
  }
478
485
  }
479
486
 
@@ -492,10 +499,66 @@ function migrateSchema(db) {
492
499
 
493
500
  console.log('[DB] Migration 5 complete: todos.session_id / injection_count added')
494
501
  } catch (err) {
495
- console.warn(`[DB] Migration 5 skipped: ${err.message}`)
496
- try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (5)") } catch {}
502
+ if (hasColumn(db, 'todos', 'session_id') && hasColumn(db, 'todos', 'injection_count')) {
503
+ console.warn(`[DB] Migration 5 skipped (columns already exist): ${err.message}`)
504
+ try { db.exec("INSERT OR IGNORE INTO schema_version (version) VALUES (5)") } catch {}
505
+ } else {
506
+ console.error(`[DB] Migration 5 FAILED — todos columns not added: ${err.message}`)
507
+ }
508
+ }
509
+ }
510
+
511
+ // Repair step: fix DBs where migrations were incorrectly marked as done
512
+ // but columns were never actually added (caused by the old catch-all error handling)
513
+ repairMissingColumns(db)
514
+ }
515
+
516
+ /**
517
+ * Check if a table has a specific column.
518
+ * @param {import('better-sqlite3').Database} db
519
+ * @param {string} table
520
+ * @param {string} column
521
+ * @returns {boolean}
522
+ */
523
+ function hasColumn(db, table, column) {
524
+ const cols = db.prepare(`PRAGMA table_info(${table})`).all()
525
+ return cols.some(c => c.name === column)
526
+ }
527
+
528
+ /**
529
+ * Repair missing columns that should have been added by migrations.
530
+ * Handles DBs where migrations were marked as done but ALTER TABLE actually failed.
531
+ */
532
+ function repairMissingColumns(db) {
533
+ const repairs = [
534
+ { table: 'memories', column: 'project_id', sql: 'ALTER TABLE memories ADD COLUMN project_id TEXT DEFAULT NULL' },
535
+ { table: 'chat_sessions', column: 'workspace_id', sql: 'ALTER TABLE chat_sessions ADD COLUMN workspace_id TEXT DEFAULT NULL' },
536
+ { table: 'todos', column: 'session_id', sql: 'ALTER TABLE todos ADD COLUMN session_id TEXT' },
537
+ { table: 'todos', column: 'injection_count', sql: 'ALTER TABLE todos ADD COLUMN injection_count INTEGER NOT NULL DEFAULT 0' },
538
+ ]
539
+
540
+ for (const { table, column, sql } of repairs) {
541
+ if (!hasColumn(db, table, column)) {
542
+ try {
543
+ console.warn(`[DB] Repair: adding missing column ${table}.${column}`)
544
+ db.exec(sql)
545
+ console.log(`[DB] Repair: ${table}.${column} added successfully`)
546
+ } catch (err) {
547
+ console.error(`[DB] Repair FAILED for ${table}.${column}: ${err.message}`)
548
+ }
497
549
  }
498
550
  }
551
+
552
+ // Ensure indexes exist after repair
553
+ try {
554
+ db.exec(`
555
+ CREATE INDEX IF NOT EXISTS idx_memories_project_id ON memories(project_id);
556
+ CREATE INDEX IF NOT EXISTS idx_chat_sessions_workspace ON chat_sessions(workspace_id, updated_at DESC);
557
+ CREATE INDEX IF NOT EXISTS idx_todos_session ON todos(session_id);
558
+ `)
559
+ } catch (err) {
560
+ console.warn(`[DB] Repair index creation skipped: ${err.message}`)
561
+ }
499
562
  }
500
563
 
501
564
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekbeer/minion",
3
- "version": "3.23.0",
3
+ "version": "3.23.1",
4
4
  "description": "AI Agent runtime for Minion - manages status and skill deployment on VPS",
5
5
  "main": "linux/server.js",
6
6
  "bin": {