opencode-swarm-plugin 0.62.1 → 0.62.2

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "swarm",
3
3
  "description": "Multi-agent task decomposition and coordination for Claude Code",
4
- "version": "0.59.5",
4
+ "version": "0.62.0",
5
5
  "author": {
6
6
  "name": "Joel Hooks"
7
7
  },
@@ -29321,8 +29321,48 @@ async function runMigrations(db2) {
29321
29321
  }
29322
29322
  }
29323
29323
  const finalVersion = await getCurrentVersion3(db2);
29324
+ await healMemorySchema(db2);
29324
29325
  return { applied, current: finalVersion };
29325
29326
  }
29327
+ async function healMemorySchema(db2) {
29328
+ try {
29329
+ const tableCheck = await db2.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='memories'`);
29330
+ if (tableCheck.rows.length === 0)
29331
+ return;
29332
+ const columnsResult = await db2.query(`SELECT name FROM pragma_table_info('memories')`);
29333
+ const existingColumns = new Set(columnsResult.rows.map((r) => r.name));
29334
+ const expectedColumns = [
29335
+ { name: "tags", type: "TEXT", defaultVal: "'[]'" },
29336
+ { name: "updated_at", type: "TEXT", defaultVal: "(datetime('now'))" },
29337
+ { name: "decay_factor", type: "REAL", defaultVal: "1.0" },
29338
+ { name: "access_count", type: "TEXT", defaultVal: "'0'" },
29339
+ { name: "last_accessed", type: "TEXT", defaultVal: "(datetime('now'))" },
29340
+ { name: "category", type: "TEXT", defaultVal: "NULL" },
29341
+ { name: "status", type: "TEXT", defaultVal: "'active'" },
29342
+ { name: "valid_from", type: "TEXT", defaultVal: "NULL" },
29343
+ { name: "valid_until", type: "TEXT", defaultVal: "NULL" },
29344
+ { name: "superseded_by", type: "TEXT", defaultVal: "NULL" },
29345
+ { name: "auto_tags", type: "TEXT", defaultVal: "NULL" },
29346
+ { name: "keywords", type: "TEXT", defaultVal: "NULL" }
29347
+ ];
29348
+ let healed = 0;
29349
+ for (const col of expectedColumns) {
29350
+ if (!existingColumns.has(col.name)) {
29351
+ try {
29352
+ const defaultClause = col.defaultVal === "NULL" ? "" : ` DEFAULT ${col.defaultVal}`;
29353
+ await db2.exec(`ALTER TABLE memories ADD COLUMN ${col.name} ${col.type}${defaultClause}`);
29354
+ healed++;
29355
+ console.log(`[migrations] healed: added missing column memories.${col.name}`);
29356
+ } catch {}
29357
+ }
29358
+ }
29359
+ if (healed > 0) {
29360
+ console.log(`[migrations] self-heal: added ${healed} missing column(s) to memories table`);
29361
+ }
29362
+ } catch (error46) {
29363
+ console.warn("[migrations] self-heal failed (non-fatal):", error46.message);
29364
+ }
29365
+ }
29326
29366
  async function rollbackTo(db2, targetVersion) {
29327
29367
  const currentVersion = await getCurrentVersion3(db2);
29328
29368
  const rolledBack = [];
@@ -65982,7 +66022,7 @@ ${prefix}}`;
65982
66022
  fromDriver(value10) {
65983
66023
  return Array.from(new Float32Array(value10.buffer));
65984
66024
  }
65985
- }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrations, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol222, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist3, NEVER22, $brand2, $ZodAsyncError2, globalConfig2, init_core32, exports_util2, captureStackTrace2, allowsEval2, getParsedType22 = (data) => {
66025
+ }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrationLibSQL, memorySchemaOverhaulLibSQL, sessionMetadataExtensionLibSQL, memorySelfHealColumnsLibSQL, memoryMigrations, memoryMigrationsLibSQL, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol222, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist3, NEVER22, $brand2, $ZodAsyncError2, globalConfig2, init_core32, exports_util2, captureStackTrace2, allowsEval2, getParsedType22 = (data) => {
65986
66026
  const t = typeof data;
65987
66027
  switch (t) {
65988
66028
  case "undefined":
@@ -133719,9 +133759,212 @@ ${stack.split(`
133719
133759
  DROP INDEX IF EXISTS memories_content_idx;
133720
133760
  DROP INDEX IF EXISTS idx_memories_collection;
133721
133761
  DROP TABLE IF EXISTS memories;
133762
+ `
133763
+ };
133764
+ memoryMigrationLibSQL = {
133765
+ version: 9,
133766
+ description: "Add semantic memory tables (memories with vector support, FTS5)",
133767
+ up: `
133768
+ -- ========================================================================
133769
+ -- Memories Table
133770
+ -- ========================================================================
133771
+ CREATE TABLE IF NOT EXISTS memories (
133772
+ id TEXT PRIMARY KEY NOT NULL,
133773
+ content TEXT NOT NULL,
133774
+ metadata TEXT DEFAULT '{}',
133775
+ collection TEXT DEFAULT 'default',
133776
+ created_at TEXT DEFAULT (datetime('now')),
133777
+ confidence REAL DEFAULT 0.7,
133778
+ embedding F32_BLOB(1024)
133779
+ );
133780
+
133781
+ -- Collection filtering index
133782
+ CREATE INDEX IF NOT EXISTS idx_memories_collection ON memories(collection);
133783
+
133784
+ -- Vector embedding index for fast similarity search
133785
+ CREATE INDEX IF NOT EXISTS idx_memories_embedding ON memories(libsql_vector_idx(embedding));
133786
+
133787
+ -- ========================================================================
133788
+ -- FTS5 virtual table for full-text search
133789
+ -- ========================================================================
133790
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
133791
+ USING fts5(id UNINDEXED, content, content=memories, content_rowid=rowid);
133792
+
133793
+ -- Triggers to keep FTS5 in sync
133794
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert
133795
+ AFTER INSERT ON memories
133796
+ BEGIN
133797
+ INSERT INTO memories_fts(rowid, id, content)
133798
+ VALUES (new.rowid, new.id, new.content);
133799
+ END;
133800
+
133801
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update
133802
+ AFTER UPDATE ON memories
133803
+ BEGIN
133804
+ UPDATE memories_fts
133805
+ SET content = new.content
133806
+ WHERE rowid = new.rowid;
133807
+ END;
133808
+
133809
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete
133810
+ AFTER DELETE ON memories
133811
+ BEGIN
133812
+ DELETE FROM memories_fts WHERE rowid = old.rowid;
133813
+ END;
133814
+ `,
133815
+ down: `
133816
+ -- Drop in reverse order
133817
+ DROP TRIGGER IF EXISTS memories_fts_delete;
133818
+ DROP TRIGGER IF EXISTS memories_fts_update;
133819
+ DROP TRIGGER IF EXISTS memories_fts_insert;
133820
+ DROP TABLE IF EXISTS memories_fts;
133821
+ DROP INDEX IF EXISTS idx_memories_embedding;
133822
+ DROP INDEX IF EXISTS idx_memories_collection;
133823
+ DROP TABLE IF EXISTS memories;
133824
+ `
133825
+ };
133826
+ memorySchemaOverhaulLibSQL = {
133827
+ version: 10,
133828
+ description: "Memory schema overhaul: links, entities, relationships, temporal fields",
133829
+ up: `
133830
+ -- ========================================================================
133831
+ -- Add temporal and metadata columns to memories table
133832
+ -- ========================================================================
133833
+ ALTER TABLE memories ADD COLUMN valid_from TEXT;
133834
+ ALTER TABLE memories ADD COLUMN valid_until TEXT;
133835
+ ALTER TABLE memories ADD COLUMN superseded_by TEXT REFERENCES memories(id);
133836
+ ALTER TABLE memories ADD COLUMN auto_tags TEXT;
133837
+ ALTER TABLE memories ADD COLUMN keywords TEXT;
133838
+
133839
+ -- ========================================================================
133840
+ -- Memory Links Table (Zettelkasten-style bidirectional connections)
133841
+ -- ========================================================================
133842
+ CREATE TABLE IF NOT EXISTS memory_links (
133843
+ id TEXT PRIMARY KEY,
133844
+ source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133845
+ target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133846
+ link_type TEXT NOT NULL,
133847
+ strength REAL DEFAULT 1.0,
133848
+ created_at TEXT DEFAULT (datetime('now')),
133849
+ UNIQUE(source_id, target_id, link_type)
133850
+ );
133851
+
133852
+ CREATE INDEX IF NOT EXISTS idx_memory_links_source ON memory_links(source_id);
133853
+ CREATE INDEX IF NOT EXISTS idx_memory_links_target ON memory_links(target_id);
133854
+
133855
+ -- ========================================================================
133856
+ -- Entities Table (Named entities extracted from memories)
133857
+ -- ========================================================================
133858
+ CREATE TABLE IF NOT EXISTS entities (
133859
+ id TEXT PRIMARY KEY,
133860
+ name TEXT NOT NULL,
133861
+ entity_type TEXT NOT NULL,
133862
+ canonical_name TEXT,
133863
+ created_at TEXT DEFAULT (datetime('now')),
133864
+ updated_at TEXT DEFAULT (datetime('now')),
133865
+ UNIQUE(name, entity_type)
133866
+ );
133867
+
133868
+ CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
133869
+ CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
133870
+
133871
+ -- ========================================================================
133872
+ -- Relationships Table (Entity-entity triples)
133873
+ -- ========================================================================
133874
+ CREATE TABLE IF NOT EXISTS relationships (
133875
+ id TEXT PRIMARY KEY,
133876
+ subject_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133877
+ predicate TEXT NOT NULL,
133878
+ object_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133879
+ memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
133880
+ confidence REAL DEFAULT 1.0,
133881
+ created_at TEXT DEFAULT (datetime('now')),
133882
+ UNIQUE(subject_id, predicate, object_id)
133883
+ );
133884
+
133885
+ CREATE INDEX IF NOT EXISTS idx_relationships_subject ON relationships(subject_id);
133886
+ CREATE INDEX IF NOT EXISTS idx_relationships_object ON relationships(object_id);
133887
+ CREATE INDEX IF NOT EXISTS idx_relationships_predicate ON relationships(predicate);
133888
+
133889
+ -- ========================================================================
133890
+ -- Memory-Entities Junction Table
133891
+ -- ========================================================================
133892
+ CREATE TABLE IF NOT EXISTS memory_entities (
133893
+ memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133894
+ entity_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133895
+ role TEXT,
133896
+ PRIMARY KEY(memory_id, entity_id)
133897
+ );
133898
+ `,
133899
+ down: `
133900
+ -- Drop tables in dependency order
133901
+ DROP TABLE IF EXISTS memory_entities;
133902
+ DROP TABLE IF EXISTS relationships;
133903
+ DROP INDEX IF EXISTS idx_memory_links_source;
133904
+ DROP INDEX IF EXISTS idx_memory_links_target;
133905
+ DROP TABLE IF EXISTS memory_links;
133906
+ DROP INDEX IF EXISTS idx_entities_type;
133907
+ DROP INDEX IF EXISTS idx_entities_name;
133908
+ DROP TABLE IF EXISTS entities;
133909
+
133910
+ -- Remove columns from memories table (SQLite doesn't support DROP COLUMN until 3.35.0)
133911
+ -- In production, these columns can be left as NULL if downgrade is needed
133912
+ -- Or recreate table without these columns
133913
+ `
133914
+ };
133915
+ sessionMetadataExtensionLibSQL = {
133916
+ version: 11,
133917
+ description: "Add session metadata columns (agent_type, session_id, message_role, message_idx, source_path)",
133918
+ up: `
133919
+ -- ========================================================================
133920
+ -- Add session metadata columns to memories table
133921
+ -- ========================================================================
133922
+ ALTER TABLE memories ADD COLUMN agent_type TEXT;
133923
+ ALTER TABLE memories ADD COLUMN session_id TEXT;
133924
+ ALTER TABLE memories ADD COLUMN message_role TEXT CHECK(message_role IN ('user', 'assistant', 'system'));
133925
+ ALTER TABLE memories ADD COLUMN message_idx INTEGER;
133926
+ ALTER TABLE memories ADD COLUMN source_path TEXT;
133927
+
133928
+ -- Index for session-based queries
133929
+ CREATE INDEX IF NOT EXISTS idx_memories_session ON memories(session_id, message_idx);
133930
+
133931
+ -- Index for agent filtering
133932
+ CREATE INDEX IF NOT EXISTS idx_memories_agent_type ON memories(agent_type);
133933
+
133934
+ -- Index for role filtering
133935
+ CREATE INDEX IF NOT EXISTS idx_memories_role ON memories(message_role);
133936
+ `,
133937
+ down: `
133938
+ -- Drop indexes first
133939
+ DROP INDEX IF EXISTS idx_memories_role;
133940
+ DROP INDEX IF EXISTS idx_memories_agent_type;
133941
+ DROP INDEX IF EXISTS idx_memories_session;
133942
+
133943
+ -- SQLite doesn't support DROP COLUMN until 3.35.0
133944
+ -- In production, these columns can be left as NULL if downgrade is needed
133945
+ -- Or recreate table without these columns
133946
+ `
133947
+ };
133948
+ memorySelfHealColumnsLibSQL = {
133949
+ version: 12,
133950
+ description: "Schema convergence: self-heal missing columns (tags, updated_at, decay_factor, access_count, last_accessed, category, status)",
133951
+ up: `
133952
+ -- No-op: actual column additions handled by healMemorySchema() post-migration.
133953
+ -- This migration just bumps the version number.
133954
+ SELECT 1;
133955
+ `,
133956
+ down: `
133957
+ -- Cannot remove columns in older SQLite versions
133958
+ SELECT 1;
133722
133959
  `
133723
133960
  };
133724
133961
  memoryMigrations = [memoryMigration];
133962
+ memoryMigrationsLibSQL = [
133963
+ memoryMigrationLibSQL,
133964
+ memorySchemaOverhaulLibSQL,
133965
+ sessionMetadataExtensionLibSQL,
133966
+ memorySelfHealColumnsLibSQL
133967
+ ];
133725
133968
  });
133726
133969
  exports_migrations2 = {};
133727
133970
  __export2(exports_migrations2, {
@@ -134061,7 +134304,7 @@ ${stack.split(`
134061
134304
  `
134062
134305
  },
134063
134306
  ...hiveMigrations,
134064
- ...memoryMigrations
134307
+ ...memoryMigrationsLibSQL
134065
134308
  ];
134066
134309
  });
134067
134310
  init_decision_trace_store = __esm2(() => {
package/dist/bin/swarm.js CHANGED
@@ -16662,8 +16662,48 @@ async function runMigrations(db2) {
16662
16662
  }
16663
16663
  }
16664
16664
  const finalVersion = await getCurrentVersion3(db2);
16665
+ await healMemorySchema(db2);
16665
16666
  return { applied, current: finalVersion };
16666
16667
  }
16668
+ async function healMemorySchema(db2) {
16669
+ try {
16670
+ const tableCheck = await db2.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='memories'`);
16671
+ if (tableCheck.rows.length === 0)
16672
+ return;
16673
+ const columnsResult = await db2.query(`SELECT name FROM pragma_table_info('memories')`);
16674
+ const existingColumns = new Set(columnsResult.rows.map((r) => r.name));
16675
+ const expectedColumns = [
16676
+ { name: "tags", type: "TEXT", defaultVal: "'[]'" },
16677
+ { name: "updated_at", type: "TEXT", defaultVal: "(datetime('now'))" },
16678
+ { name: "decay_factor", type: "REAL", defaultVal: "1.0" },
16679
+ { name: "access_count", type: "TEXT", defaultVal: "'0'" },
16680
+ { name: "last_accessed", type: "TEXT", defaultVal: "(datetime('now'))" },
16681
+ { name: "category", type: "TEXT", defaultVal: "NULL" },
16682
+ { name: "status", type: "TEXT", defaultVal: "'active'" },
16683
+ { name: "valid_from", type: "TEXT", defaultVal: "NULL" },
16684
+ { name: "valid_until", type: "TEXT", defaultVal: "NULL" },
16685
+ { name: "superseded_by", type: "TEXT", defaultVal: "NULL" },
16686
+ { name: "auto_tags", type: "TEXT", defaultVal: "NULL" },
16687
+ { name: "keywords", type: "TEXT", defaultVal: "NULL" }
16688
+ ];
16689
+ let healed = 0;
16690
+ for (const col of expectedColumns) {
16691
+ if (!existingColumns.has(col.name)) {
16692
+ try {
16693
+ const defaultClause = col.defaultVal === "NULL" ? "" : ` DEFAULT ${col.defaultVal}`;
16694
+ await db2.exec(`ALTER TABLE memories ADD COLUMN ${col.name} ${col.type}${defaultClause}`);
16695
+ healed++;
16696
+ console.log(`[migrations] healed: added missing column memories.${col.name}`);
16697
+ } catch {}
16698
+ }
16699
+ }
16700
+ if (healed > 0) {
16701
+ console.log(`[migrations] self-heal: added ${healed} missing column(s) to memories table`);
16702
+ }
16703
+ } catch (error4) {
16704
+ console.warn("[migrations] self-heal failed (non-fatal):", error4.message);
16705
+ }
16706
+ }
16667
16707
  async function rollbackTo(db2, targetVersion) {
16668
16708
  const currentVersion = await getCurrentVersion3(db2);
16669
16709
  const rolledBack = [];
@@ -53323,7 +53363,7 @@ ${prefix}}`;
53323
53363
  fromDriver(value10) {
53324
53364
  return Array.from(new Float32Array(value10.buffer));
53325
53365
  }
53326
- }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrations, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol22, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist2, NEVER2, $brand, $ZodAsyncError, globalConfig, init_core3, exports_util2, captureStackTrace, allowsEval, getParsedType2 = (data) => {
53366
+ }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrationLibSQL, memorySchemaOverhaulLibSQL, sessionMetadataExtensionLibSQL, memorySelfHealColumnsLibSQL, memoryMigrations, memoryMigrationsLibSQL, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol22, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist2, NEVER2, $brand, $ZodAsyncError, globalConfig, init_core3, exports_util2, captureStackTrace, allowsEval, getParsedType2 = (data) => {
53327
53367
  const t = typeof data;
53328
53368
  switch (t) {
53329
53369
  case "undefined":
@@ -121060,9 +121100,212 @@ ${stack.split(`
121060
121100
  DROP INDEX IF EXISTS memories_content_idx;
121061
121101
  DROP INDEX IF EXISTS idx_memories_collection;
121062
121102
  DROP TABLE IF EXISTS memories;
121103
+ `
121104
+ };
121105
+ memoryMigrationLibSQL = {
121106
+ version: 9,
121107
+ description: "Add semantic memory tables (memories with vector support, FTS5)",
121108
+ up: `
121109
+ -- ========================================================================
121110
+ -- Memories Table
121111
+ -- ========================================================================
121112
+ CREATE TABLE IF NOT EXISTS memories (
121113
+ id TEXT PRIMARY KEY NOT NULL,
121114
+ content TEXT NOT NULL,
121115
+ metadata TEXT DEFAULT '{}',
121116
+ collection TEXT DEFAULT 'default',
121117
+ created_at TEXT DEFAULT (datetime('now')),
121118
+ confidence REAL DEFAULT 0.7,
121119
+ embedding F32_BLOB(1024)
121120
+ );
121121
+
121122
+ -- Collection filtering index
121123
+ CREATE INDEX IF NOT EXISTS idx_memories_collection ON memories(collection);
121124
+
121125
+ -- Vector embedding index for fast similarity search
121126
+ CREATE INDEX IF NOT EXISTS idx_memories_embedding ON memories(libsql_vector_idx(embedding));
121127
+
121128
+ -- ========================================================================
121129
+ -- FTS5 virtual table for full-text search
121130
+ -- ========================================================================
121131
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
121132
+ USING fts5(id UNINDEXED, content, content=memories, content_rowid=rowid);
121133
+
121134
+ -- Triggers to keep FTS5 in sync
121135
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert
121136
+ AFTER INSERT ON memories
121137
+ BEGIN
121138
+ INSERT INTO memories_fts(rowid, id, content)
121139
+ VALUES (new.rowid, new.id, new.content);
121140
+ END;
121141
+
121142
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update
121143
+ AFTER UPDATE ON memories
121144
+ BEGIN
121145
+ UPDATE memories_fts
121146
+ SET content = new.content
121147
+ WHERE rowid = new.rowid;
121148
+ END;
121149
+
121150
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete
121151
+ AFTER DELETE ON memories
121152
+ BEGIN
121153
+ DELETE FROM memories_fts WHERE rowid = old.rowid;
121154
+ END;
121155
+ `,
121156
+ down: `
121157
+ -- Drop in reverse order
121158
+ DROP TRIGGER IF EXISTS memories_fts_delete;
121159
+ DROP TRIGGER IF EXISTS memories_fts_update;
121160
+ DROP TRIGGER IF EXISTS memories_fts_insert;
121161
+ DROP TABLE IF EXISTS memories_fts;
121162
+ DROP INDEX IF EXISTS idx_memories_embedding;
121163
+ DROP INDEX IF EXISTS idx_memories_collection;
121164
+ DROP TABLE IF EXISTS memories;
121165
+ `
121166
+ };
121167
+ memorySchemaOverhaulLibSQL = {
121168
+ version: 10,
121169
+ description: "Memory schema overhaul: links, entities, relationships, temporal fields",
121170
+ up: `
121171
+ -- ========================================================================
121172
+ -- Add temporal and metadata columns to memories table
121173
+ -- ========================================================================
121174
+ ALTER TABLE memories ADD COLUMN valid_from TEXT;
121175
+ ALTER TABLE memories ADD COLUMN valid_until TEXT;
121176
+ ALTER TABLE memories ADD COLUMN superseded_by TEXT REFERENCES memories(id);
121177
+ ALTER TABLE memories ADD COLUMN auto_tags TEXT;
121178
+ ALTER TABLE memories ADD COLUMN keywords TEXT;
121179
+
121180
+ -- ========================================================================
121181
+ -- Memory Links Table (Zettelkasten-style bidirectional connections)
121182
+ -- ========================================================================
121183
+ CREATE TABLE IF NOT EXISTS memory_links (
121184
+ id TEXT PRIMARY KEY,
121185
+ source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
121186
+ target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
121187
+ link_type TEXT NOT NULL,
121188
+ strength REAL DEFAULT 1.0,
121189
+ created_at TEXT DEFAULT (datetime('now')),
121190
+ UNIQUE(source_id, target_id, link_type)
121191
+ );
121192
+
121193
+ CREATE INDEX IF NOT EXISTS idx_memory_links_source ON memory_links(source_id);
121194
+ CREATE INDEX IF NOT EXISTS idx_memory_links_target ON memory_links(target_id);
121195
+
121196
+ -- ========================================================================
121197
+ -- Entities Table (Named entities extracted from memories)
121198
+ -- ========================================================================
121199
+ CREATE TABLE IF NOT EXISTS entities (
121200
+ id TEXT PRIMARY KEY,
121201
+ name TEXT NOT NULL,
121202
+ entity_type TEXT NOT NULL,
121203
+ canonical_name TEXT,
121204
+ created_at TEXT DEFAULT (datetime('now')),
121205
+ updated_at TEXT DEFAULT (datetime('now')),
121206
+ UNIQUE(name, entity_type)
121207
+ );
121208
+
121209
+ CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
121210
+ CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
121211
+
121212
+ -- ========================================================================
121213
+ -- Relationships Table (Entity-entity triples)
121214
+ -- ========================================================================
121215
+ CREATE TABLE IF NOT EXISTS relationships (
121216
+ id TEXT PRIMARY KEY,
121217
+ subject_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
121218
+ predicate TEXT NOT NULL,
121219
+ object_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
121220
+ memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
121221
+ confidence REAL DEFAULT 1.0,
121222
+ created_at TEXT DEFAULT (datetime('now')),
121223
+ UNIQUE(subject_id, predicate, object_id)
121224
+ );
121225
+
121226
+ CREATE INDEX IF NOT EXISTS idx_relationships_subject ON relationships(subject_id);
121227
+ CREATE INDEX IF NOT EXISTS idx_relationships_object ON relationships(object_id);
121228
+ CREATE INDEX IF NOT EXISTS idx_relationships_predicate ON relationships(predicate);
121229
+
121230
+ -- ========================================================================
121231
+ -- Memory-Entities Junction Table
121232
+ -- ========================================================================
121233
+ CREATE TABLE IF NOT EXISTS memory_entities (
121234
+ memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
121235
+ entity_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
121236
+ role TEXT,
121237
+ PRIMARY KEY(memory_id, entity_id)
121238
+ );
121239
+ `,
121240
+ down: `
121241
+ -- Drop tables in dependency order
121242
+ DROP TABLE IF EXISTS memory_entities;
121243
+ DROP TABLE IF EXISTS relationships;
121244
+ DROP INDEX IF EXISTS idx_memory_links_source;
121245
+ DROP INDEX IF EXISTS idx_memory_links_target;
121246
+ DROP TABLE IF EXISTS memory_links;
121247
+ DROP INDEX IF EXISTS idx_entities_type;
121248
+ DROP INDEX IF EXISTS idx_entities_name;
121249
+ DROP TABLE IF EXISTS entities;
121250
+
121251
+ -- Remove columns from memories table (SQLite doesn't support DROP COLUMN until 3.35.0)
121252
+ -- In production, these columns can be left as NULL if downgrade is needed
121253
+ -- Or recreate table without these columns
121254
+ `
121255
+ };
121256
+ sessionMetadataExtensionLibSQL = {
121257
+ version: 11,
121258
+ description: "Add session metadata columns (agent_type, session_id, message_role, message_idx, source_path)",
121259
+ up: `
121260
+ -- ========================================================================
121261
+ -- Add session metadata columns to memories table
121262
+ -- ========================================================================
121263
+ ALTER TABLE memories ADD COLUMN agent_type TEXT;
121264
+ ALTER TABLE memories ADD COLUMN session_id TEXT;
121265
+ ALTER TABLE memories ADD COLUMN message_role TEXT CHECK(message_role IN ('user', 'assistant', 'system'));
121266
+ ALTER TABLE memories ADD COLUMN message_idx INTEGER;
121267
+ ALTER TABLE memories ADD COLUMN source_path TEXT;
121268
+
121269
+ -- Index for session-based queries
121270
+ CREATE INDEX IF NOT EXISTS idx_memories_session ON memories(session_id, message_idx);
121271
+
121272
+ -- Index for agent filtering
121273
+ CREATE INDEX IF NOT EXISTS idx_memories_agent_type ON memories(agent_type);
121274
+
121275
+ -- Index for role filtering
121276
+ CREATE INDEX IF NOT EXISTS idx_memories_role ON memories(message_role);
121277
+ `,
121278
+ down: `
121279
+ -- Drop indexes first
121280
+ DROP INDEX IF EXISTS idx_memories_role;
121281
+ DROP INDEX IF EXISTS idx_memories_agent_type;
121282
+ DROP INDEX IF EXISTS idx_memories_session;
121283
+
121284
+ -- SQLite doesn't support DROP COLUMN until 3.35.0
121285
+ -- In production, these columns can be left as NULL if downgrade is needed
121286
+ -- Or recreate table without these columns
121287
+ `
121288
+ };
121289
+ memorySelfHealColumnsLibSQL = {
121290
+ version: 12,
121291
+ description: "Schema convergence: self-heal missing columns (tags, updated_at, decay_factor, access_count, last_accessed, category, status)",
121292
+ up: `
121293
+ -- No-op: actual column additions handled by healMemorySchema() post-migration.
121294
+ -- This migration just bumps the version number.
121295
+ SELECT 1;
121296
+ `,
121297
+ down: `
121298
+ -- Cannot remove columns in older SQLite versions
121299
+ SELECT 1;
121063
121300
  `
121064
121301
  };
121065
121302
  memoryMigrations = [memoryMigration];
121303
+ memoryMigrationsLibSQL = [
121304
+ memoryMigrationLibSQL,
121305
+ memorySchemaOverhaulLibSQL,
121306
+ sessionMetadataExtensionLibSQL,
121307
+ memorySelfHealColumnsLibSQL
121308
+ ];
121066
121309
  });
121067
121310
  exports_migrations2 = {};
121068
121311
  __export2(exports_migrations2, {
@@ -121402,7 +121645,7 @@ ${stack.split(`
121402
121645
  `
121403
121646
  },
121404
121647
  ...hiveMigrations,
121405
- ...memoryMigrations
121648
+ ...memoryMigrationsLibSQL
121406
121649
  ];
121407
121650
  });
121408
121651
  init_decision_trace_store = __esm2(() => {
@@ -151655,8 +151898,48 @@ async function runMigrations2(db2) {
151655
151898
  }
151656
151899
  }
151657
151900
  const finalVersion = await getCurrentVersion32(db2);
151901
+ await healMemorySchema2(db2);
151658
151902
  return { applied, current: finalVersion };
151659
151903
  }
151904
+ async function healMemorySchema2(db2) {
151905
+ try {
151906
+ const tableCheck = await db2.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='memories'`);
151907
+ if (tableCheck.rows.length === 0)
151908
+ return;
151909
+ const columnsResult = await db2.query(`SELECT name FROM pragma_table_info('memories')`);
151910
+ const existingColumns = new Set(columnsResult.rows.map((r) => r.name));
151911
+ const expectedColumns = [
151912
+ { name: "tags", type: "TEXT", defaultVal: "'[]'" },
151913
+ { name: "updated_at", type: "TEXT", defaultVal: "(datetime('now'))" },
151914
+ { name: "decay_factor", type: "REAL", defaultVal: "1.0" },
151915
+ { name: "access_count", type: "TEXT", defaultVal: "'0'" },
151916
+ { name: "last_accessed", type: "TEXT", defaultVal: "(datetime('now'))" },
151917
+ { name: "category", type: "TEXT", defaultVal: "NULL" },
151918
+ { name: "status", type: "TEXT", defaultVal: "'active'" },
151919
+ { name: "valid_from", type: "TEXT", defaultVal: "NULL" },
151920
+ { name: "valid_until", type: "TEXT", defaultVal: "NULL" },
151921
+ { name: "superseded_by", type: "TEXT", defaultVal: "NULL" },
151922
+ { name: "auto_tags", type: "TEXT", defaultVal: "NULL" },
151923
+ { name: "keywords", type: "TEXT", defaultVal: "NULL" }
151924
+ ];
151925
+ let healed = 0;
151926
+ for (const col of expectedColumns) {
151927
+ if (!existingColumns.has(col.name)) {
151928
+ try {
151929
+ const defaultClause = col.defaultVal === "NULL" ? "" : ` DEFAULT ${col.defaultVal}`;
151930
+ await db2.exec(`ALTER TABLE memories ADD COLUMN ${col.name} ${col.type}${defaultClause}`);
151931
+ healed++;
151932
+ console.log(`[migrations] healed: added missing column memories.${col.name}`);
151933
+ } catch {}
151934
+ }
151935
+ }
151936
+ if (healed > 0) {
151937
+ console.log(`[migrations] self-heal: added ${healed} missing column(s) to memories table`);
151938
+ }
151939
+ } catch (error410) {
151940
+ console.warn("[migrations] self-heal failed (non-fatal):", error410.message);
151941
+ }
151942
+ }
151660
151943
  async function rollbackTo2(db2, targetVersion) {
151661
151944
  const currentVersion = await getCurrentVersion32(db2);
151662
151945
  const rolledBack = [];
@@ -188316,7 +188599,7 @@ ${prefix}}`;
188316
188599
  fromDriver(value102) {
188317
188600
  return Array.from(new Float32Array(value102.buffer));
188318
188601
  }
188319
- }), memories2, memoryLinks2, entities2, entityTaxonomy2, relationships2, memoryEntities2, init_memory3, init_expressions22, exports_drizzle_orm2, init_drizzle_orm2, exports_streams3, eventsTable2, agentsTable2, messagesTable2, messageRecipientsTable2, reservationsTable2, locksTable2, cursorsTable2, evalRecordsTable2, swarmContextsTable2, decisionTracesTable2, entityLinksTable2, init_streams3, exports_hive2, beads2, cells2, cellEvents2, beadLabels2, cellLabels2, beadComments2, cellComments2, beadDependencies2, cellDependencies2, blockedBeadsCache2, dirtyBeads2, schemaVersion2, init_hive2, exports_schema2, init_schema2, init_drizzle2, require_entity2, require_logger2, require_query_promise2, require_column2, require_column_builder2, require_table_utils2, require_foreign_keys2, require_tracing_utils2, require_unique_constraint2, require_array2, require_common22, require_enum2, require_subquery3, require_version3, require_tracing2, require_view_common3, require_table3, require_sql3, require_alias3, require_selection_proxy2, require_utils9, require_delete2, require_casing2, require_errors2, require_int_common2, require_bigint2, require_bigserial2, require_boolean2, require_char2, require_cidr2, require_custom2, require_date_common2, require_date2, require_double_precision2, require_inet2, require_integer2, require_interval2, require_json3, require_jsonb2, require_line2, require_macaddr2, require_macaddr82, require_numeric2, require_point2, require_utils22, require_geometry2, require_real2, require_serial2, require_smallint2, require_smallserial2, require_text2, require_time2, require_timestamp3, require_uuid2, require_varchar2, require_bit2, require_halfvec2, require_sparsevec2, require_vector3, require_columns2, require_all2, require_table22, require_primary_keys2, require_conditions2, require_select3, require_expressions2, require_relations2, require_aggregate2, require_vector22, require_functions2, require_sql22, require_view_base2, require_dialect2, require_query_builder3, require_select22, require_query_builder22, require_insert2, require_refresh_materialized_view2, require_select_types2, require_update2, require_query_builders2, require_count2, require_query2, require_raw2, require_db2, require_alias22, require_checks2, require_indexes2, require_policies2, require_roles2, require_sequence2, require_view_common22, require_view2, require_schema3, require_session3, require_subquery22, require_utils32, require_utils42, require_pg_core2, require_session22, require_driver2, require_pglite2, exports_libsql_convenience2, instances2, init_libsql_convenience2, exports_lock2, DurableLock2, DurableLockLive2, init_lock2, exports_reservation_utils2, init_reservation_utils2, init_projections_drizzle3, exports_store_drizzle2, init_store_drizzle2, exports_swarm_mail2, MAX_INBOX_LIMIT3 = 5, DEFAULT_TTL_SECONDS3 = 3600, ADJECTIVES3, NOUNS3, init_swarm_mail2, MAX_INBOX_LIMIT22 = 5, DEFAULT_TTL_SECONDS22 = 3600, ADJECTIVES22, NOUNS22, init_agent_mail2, exports_migrations3, beadsMigration2, cellsViewMigration2, cellsViewMigrationLibSQL2, beadsMigrationLibSQL2, beadsResultColumnsMigration2, beadsResultColumnsMigrationLibSQL2, beadsMigrations2, hiveMigrations2, sessionsMigrationLibSQL2, hiveMigrationsLibSQL2, init_migrations4, memoryMigration2, memoryMigrations2, init_migrations22, exports_migrations22, migrations2, init_migrations32, urlAlphabet2 = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER2 = 128, pool2, poolOffset2, init_nanoid2 = () => {}, init_decision_trace_store2, ClientBuffer2, init_client_buffer2, exports_streams22, SLOW_QUERY_THRESHOLD_MS2 = 100, init_streams22, exports_store2, adapterCache4, TIMESTAMP_SAFE_UNTIL2, init_store3, init_adapter3, exports_dependencies_drizzle2, MAX_DEPENDENCY_DEPTH3 = 100, init_dependencies_drizzle2, exports_projections_drizzle2, init_projections_drizzle22, exports_dependencies2, MAX_DEPENDENCY_DEPTH22 = 100, init_store22, FIELD_SETS2, init_pagination2, marker21 = "vercel.ai.error", symbol65, _a24, _b16, AISDKError2, name25 = "AI_APICallError", marker24, symbol222, _a25, _b23, APICallError2, name222 = "AI_EmptyResponseBodyError", marker34, symbol322, _a34, _b33, EmptyResponseBodyError2, name34 = "AI_InvalidArgumentError", marker44, symbol422, _a44, _b43, InvalidArgumentError3, name44 = "AI_InvalidPromptError", marker54, symbol522, _a54, _b53, InvalidPromptError2, name54 = "AI_InvalidResponseDataError", marker64, symbol622, _a64, _b63, InvalidResponseDataError2, name64 = "AI_JSONParseError", marker74, symbol74, _a74, _b73, JSONParseError2, name73 = "AI_LoadAPIKeyError", marker83, symbol83, _a83, _b82, LoadAPIKeyError2, name83 = "AI_LoadSettingError", marker93, symbol93, _a93, _b92, LoadSettingError2, name93 = "AI_NoContentGeneratedError", marker103, symbol103, _a103, _b102, NoContentGeneratedError2, name103 = "AI_NoSuchModelError", marker113, symbol113, _a113, _b112, NoSuchModelError2, name113 = "AI_TooManyEmbeddingValuesForCallError", marker123, symbol123, _a123, _b122, TooManyEmbeddingValuesForCallError2, name123 = "AI_TypeValidationError", marker133, symbol133, _a133, _b132, TypeValidationError2, name133 = "AI_UnsupportedFunctionalityError", marker143, symbol143, _a143, _b142, UnsupportedFunctionalityError2, init_dist11, NEVER22, $brand6, $ZodAsyncError6, globalConfig6, init_core33, exports_util22, captureStackTrace6, allowsEval6, getParsedType22 = (data) => {
188602
+ }), memories2, memoryLinks2, entities2, entityTaxonomy2, relationships2, memoryEntities2, init_memory3, init_expressions22, exports_drizzle_orm2, init_drizzle_orm2, exports_streams3, eventsTable2, agentsTable2, messagesTable2, messageRecipientsTable2, reservationsTable2, locksTable2, cursorsTable2, evalRecordsTable2, swarmContextsTable2, decisionTracesTable2, entityLinksTable2, init_streams3, exports_hive2, beads2, cells2, cellEvents2, beadLabels2, cellLabels2, beadComments2, cellComments2, beadDependencies2, cellDependencies2, blockedBeadsCache2, dirtyBeads2, schemaVersion2, init_hive2, exports_schema2, init_schema2, init_drizzle2, require_entity2, require_logger2, require_query_promise2, require_column2, require_column_builder2, require_table_utils2, require_foreign_keys2, require_tracing_utils2, require_unique_constraint2, require_array2, require_common22, require_enum2, require_subquery3, require_version3, require_tracing2, require_view_common3, require_table3, require_sql3, require_alias3, require_selection_proxy2, require_utils9, require_delete2, require_casing2, require_errors2, require_int_common2, require_bigint2, require_bigserial2, require_boolean2, require_char2, require_cidr2, require_custom2, require_date_common2, require_date2, require_double_precision2, require_inet2, require_integer2, require_interval2, require_json3, require_jsonb2, require_line2, require_macaddr2, require_macaddr82, require_numeric2, require_point2, require_utils22, require_geometry2, require_real2, require_serial2, require_smallint2, require_smallserial2, require_text2, require_time2, require_timestamp3, require_uuid2, require_varchar2, require_bit2, require_halfvec2, require_sparsevec2, require_vector3, require_columns2, require_all2, require_table22, require_primary_keys2, require_conditions2, require_select3, require_expressions2, require_relations2, require_aggregate2, require_vector22, require_functions2, require_sql22, require_view_base2, require_dialect2, require_query_builder3, require_select22, require_query_builder22, require_insert2, require_refresh_materialized_view2, require_select_types2, require_update2, require_query_builders2, require_count2, require_query2, require_raw2, require_db2, require_alias22, require_checks2, require_indexes2, require_policies2, require_roles2, require_sequence2, require_view_common22, require_view2, require_schema3, require_session3, require_subquery22, require_utils32, require_utils42, require_pg_core2, require_session22, require_driver2, require_pglite2, exports_libsql_convenience2, instances2, init_libsql_convenience2, exports_lock2, DurableLock2, DurableLockLive2, init_lock2, exports_reservation_utils2, init_reservation_utils2, init_projections_drizzle3, exports_store_drizzle2, init_store_drizzle2, exports_swarm_mail2, MAX_INBOX_LIMIT3 = 5, DEFAULT_TTL_SECONDS3 = 3600, ADJECTIVES3, NOUNS3, init_swarm_mail2, MAX_INBOX_LIMIT22 = 5, DEFAULT_TTL_SECONDS22 = 3600, ADJECTIVES22, NOUNS22, init_agent_mail2, exports_migrations3, beadsMigration2, cellsViewMigration2, cellsViewMigrationLibSQL2, beadsMigrationLibSQL2, beadsResultColumnsMigration2, beadsResultColumnsMigrationLibSQL2, beadsMigrations2, hiveMigrations2, sessionsMigrationLibSQL2, hiveMigrationsLibSQL2, init_migrations4, memoryMigration2, memoryMigrationLibSQL2, memorySchemaOverhaulLibSQL2, sessionMetadataExtensionLibSQL2, memorySelfHealColumnsLibSQL2, memoryMigrations2, memoryMigrationsLibSQL2, init_migrations22, exports_migrations22, migrations2, init_migrations32, urlAlphabet2 = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER2 = 128, pool2, poolOffset2, init_nanoid2 = () => {}, init_decision_trace_store2, ClientBuffer2, init_client_buffer2, exports_streams22, SLOW_QUERY_THRESHOLD_MS2 = 100, init_streams22, exports_store2, adapterCache4, TIMESTAMP_SAFE_UNTIL2, init_store3, init_adapter3, exports_dependencies_drizzle2, MAX_DEPENDENCY_DEPTH3 = 100, init_dependencies_drizzle2, exports_projections_drizzle2, init_projections_drizzle22, exports_dependencies2, MAX_DEPENDENCY_DEPTH22 = 100, init_store22, FIELD_SETS2, init_pagination2, marker21 = "vercel.ai.error", symbol65, _a24, _b16, AISDKError2, name25 = "AI_APICallError", marker24, symbol222, _a25, _b23, APICallError2, name222 = "AI_EmptyResponseBodyError", marker34, symbol322, _a34, _b33, EmptyResponseBodyError2, name34 = "AI_InvalidArgumentError", marker44, symbol422, _a44, _b43, InvalidArgumentError3, name44 = "AI_InvalidPromptError", marker54, symbol522, _a54, _b53, InvalidPromptError2, name54 = "AI_InvalidResponseDataError", marker64, symbol622, _a64, _b63, InvalidResponseDataError2, name64 = "AI_JSONParseError", marker74, symbol74, _a74, _b73, JSONParseError2, name73 = "AI_LoadAPIKeyError", marker83, symbol83, _a83, _b82, LoadAPIKeyError2, name83 = "AI_LoadSettingError", marker93, symbol93, _a93, _b92, LoadSettingError2, name93 = "AI_NoContentGeneratedError", marker103, symbol103, _a103, _b102, NoContentGeneratedError2, name103 = "AI_NoSuchModelError", marker113, symbol113, _a113, _b112, NoSuchModelError2, name113 = "AI_TooManyEmbeddingValuesForCallError", marker123, symbol123, _a123, _b122, TooManyEmbeddingValuesForCallError2, name123 = "AI_TypeValidationError", marker133, symbol133, _a133, _b132, TypeValidationError2, name133 = "AI_UnsupportedFunctionalityError", marker143, symbol143, _a143, _b142, UnsupportedFunctionalityError2, init_dist11, NEVER22, $brand6, $ZodAsyncError6, globalConfig6, init_core33, exports_util22, captureStackTrace6, allowsEval6, getParsedType22 = (data) => {
188320
188603
  const t = typeof data;
188321
188604
  switch (t) {
188322
188605
  case "undefined":
@@ -256053,9 +256336,212 @@ ${stack.split(`
256053
256336
  DROP INDEX IF EXISTS memories_content_idx;
256054
256337
  DROP INDEX IF EXISTS idx_memories_collection;
256055
256338
  DROP TABLE IF EXISTS memories;
256339
+ `
256340
+ };
256341
+ memoryMigrationLibSQL2 = {
256342
+ version: 9,
256343
+ description: "Add semantic memory tables (memories with vector support, FTS5)",
256344
+ up: `
256345
+ -- ========================================================================
256346
+ -- Memories Table
256347
+ -- ========================================================================
256348
+ CREATE TABLE IF NOT EXISTS memories (
256349
+ id TEXT PRIMARY KEY NOT NULL,
256350
+ content TEXT NOT NULL,
256351
+ metadata TEXT DEFAULT '{}',
256352
+ collection TEXT DEFAULT 'default',
256353
+ created_at TEXT DEFAULT (datetime('now')),
256354
+ confidence REAL DEFAULT 0.7,
256355
+ embedding F32_BLOB(1024)
256356
+ );
256357
+
256358
+ -- Collection filtering index
256359
+ CREATE INDEX IF NOT EXISTS idx_memories_collection ON memories(collection);
256360
+
256361
+ -- Vector embedding index for fast similarity search
256362
+ CREATE INDEX IF NOT EXISTS idx_memories_embedding ON memories(libsql_vector_idx(embedding));
256363
+
256364
+ -- ========================================================================
256365
+ -- FTS5 virtual table for full-text search
256366
+ -- ========================================================================
256367
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
256368
+ USING fts5(id UNINDEXED, content, content=memories, content_rowid=rowid);
256369
+
256370
+ -- Triggers to keep FTS5 in sync
256371
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert
256372
+ AFTER INSERT ON memories
256373
+ BEGIN
256374
+ INSERT INTO memories_fts(rowid, id, content)
256375
+ VALUES (new.rowid, new.id, new.content);
256376
+ END;
256377
+
256378
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update
256379
+ AFTER UPDATE ON memories
256380
+ BEGIN
256381
+ UPDATE memories_fts
256382
+ SET content = new.content
256383
+ WHERE rowid = new.rowid;
256384
+ END;
256385
+
256386
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete
256387
+ AFTER DELETE ON memories
256388
+ BEGIN
256389
+ DELETE FROM memories_fts WHERE rowid = old.rowid;
256390
+ END;
256391
+ `,
256392
+ down: `
256393
+ -- Drop in reverse order
256394
+ DROP TRIGGER IF EXISTS memories_fts_delete;
256395
+ DROP TRIGGER IF EXISTS memories_fts_update;
256396
+ DROP TRIGGER IF EXISTS memories_fts_insert;
256397
+ DROP TABLE IF EXISTS memories_fts;
256398
+ DROP INDEX IF EXISTS idx_memories_embedding;
256399
+ DROP INDEX IF EXISTS idx_memories_collection;
256400
+ DROP TABLE IF EXISTS memories;
256401
+ `
256402
+ };
256403
+ memorySchemaOverhaulLibSQL2 = {
256404
+ version: 10,
256405
+ description: "Memory schema overhaul: links, entities, relationships, temporal fields",
256406
+ up: `
256407
+ -- ========================================================================
256408
+ -- Add temporal and metadata columns to memories table
256409
+ -- ========================================================================
256410
+ ALTER TABLE memories ADD COLUMN valid_from TEXT;
256411
+ ALTER TABLE memories ADD COLUMN valid_until TEXT;
256412
+ ALTER TABLE memories ADD COLUMN superseded_by TEXT REFERENCES memories(id);
256413
+ ALTER TABLE memories ADD COLUMN auto_tags TEXT;
256414
+ ALTER TABLE memories ADD COLUMN keywords TEXT;
256415
+
256416
+ -- ========================================================================
256417
+ -- Memory Links Table (Zettelkasten-style bidirectional connections)
256418
+ -- ========================================================================
256419
+ CREATE TABLE IF NOT EXISTS memory_links (
256420
+ id TEXT PRIMARY KEY,
256421
+ source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
256422
+ target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
256423
+ link_type TEXT NOT NULL,
256424
+ strength REAL DEFAULT 1.0,
256425
+ created_at TEXT DEFAULT (datetime('now')),
256426
+ UNIQUE(source_id, target_id, link_type)
256427
+ );
256428
+
256429
+ CREATE INDEX IF NOT EXISTS idx_memory_links_source ON memory_links(source_id);
256430
+ CREATE INDEX IF NOT EXISTS idx_memory_links_target ON memory_links(target_id);
256431
+
256432
+ -- ========================================================================
256433
+ -- Entities Table (Named entities extracted from memories)
256434
+ -- ========================================================================
256435
+ CREATE TABLE IF NOT EXISTS entities (
256436
+ id TEXT PRIMARY KEY,
256437
+ name TEXT NOT NULL,
256438
+ entity_type TEXT NOT NULL,
256439
+ canonical_name TEXT,
256440
+ created_at TEXT DEFAULT (datetime('now')),
256441
+ updated_at TEXT DEFAULT (datetime('now')),
256442
+ UNIQUE(name, entity_type)
256443
+ );
256444
+
256445
+ CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
256446
+ CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
256447
+
256448
+ -- ========================================================================
256449
+ -- Relationships Table (Entity-entity triples)
256450
+ -- ========================================================================
256451
+ CREATE TABLE IF NOT EXISTS relationships (
256452
+ id TEXT PRIMARY KEY,
256453
+ subject_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
256454
+ predicate TEXT NOT NULL,
256455
+ object_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
256456
+ memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
256457
+ confidence REAL DEFAULT 1.0,
256458
+ created_at TEXT DEFAULT (datetime('now')),
256459
+ UNIQUE(subject_id, predicate, object_id)
256460
+ );
256461
+
256462
+ CREATE INDEX IF NOT EXISTS idx_relationships_subject ON relationships(subject_id);
256463
+ CREATE INDEX IF NOT EXISTS idx_relationships_object ON relationships(object_id);
256464
+ CREATE INDEX IF NOT EXISTS idx_relationships_predicate ON relationships(predicate);
256465
+
256466
+ -- ========================================================================
256467
+ -- Memory-Entities Junction Table
256468
+ -- ========================================================================
256469
+ CREATE TABLE IF NOT EXISTS memory_entities (
256470
+ memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
256471
+ entity_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
256472
+ role TEXT,
256473
+ PRIMARY KEY(memory_id, entity_id)
256474
+ );
256475
+ `,
256476
+ down: `
256477
+ -- Drop tables in dependency order
256478
+ DROP TABLE IF EXISTS memory_entities;
256479
+ DROP TABLE IF EXISTS relationships;
256480
+ DROP INDEX IF EXISTS idx_memory_links_source;
256481
+ DROP INDEX IF EXISTS idx_memory_links_target;
256482
+ DROP TABLE IF EXISTS memory_links;
256483
+ DROP INDEX IF EXISTS idx_entities_type;
256484
+ DROP INDEX IF EXISTS idx_entities_name;
256485
+ DROP TABLE IF EXISTS entities;
256486
+
256487
+ -- Remove columns from memories table (SQLite doesn't support DROP COLUMN until 3.35.0)
256488
+ -- In production, these columns can be left as NULL if downgrade is needed
256489
+ -- Or recreate table without these columns
256490
+ `
256491
+ };
256492
+ sessionMetadataExtensionLibSQL2 = {
256493
+ version: 11,
256494
+ description: "Add session metadata columns (agent_type, session_id, message_role, message_idx, source_path)",
256495
+ up: `
256496
+ -- ========================================================================
256497
+ -- Add session metadata columns to memories table
256498
+ -- ========================================================================
256499
+ ALTER TABLE memories ADD COLUMN agent_type TEXT;
256500
+ ALTER TABLE memories ADD COLUMN session_id TEXT;
256501
+ ALTER TABLE memories ADD COLUMN message_role TEXT CHECK(message_role IN ('user', 'assistant', 'system'));
256502
+ ALTER TABLE memories ADD COLUMN message_idx INTEGER;
256503
+ ALTER TABLE memories ADD COLUMN source_path TEXT;
256504
+
256505
+ -- Index for session-based queries
256506
+ CREATE INDEX IF NOT EXISTS idx_memories_session ON memories(session_id, message_idx);
256507
+
256508
+ -- Index for agent filtering
256509
+ CREATE INDEX IF NOT EXISTS idx_memories_agent_type ON memories(agent_type);
256510
+
256511
+ -- Index for role filtering
256512
+ CREATE INDEX IF NOT EXISTS idx_memories_role ON memories(message_role);
256513
+ `,
256514
+ down: `
256515
+ -- Drop indexes first
256516
+ DROP INDEX IF EXISTS idx_memories_role;
256517
+ DROP INDEX IF EXISTS idx_memories_agent_type;
256518
+ DROP INDEX IF EXISTS idx_memories_session;
256519
+
256520
+ -- SQLite doesn't support DROP COLUMN until 3.35.0
256521
+ -- In production, these columns can be left as NULL if downgrade is needed
256522
+ -- Or recreate table without these columns
256523
+ `
256524
+ };
256525
+ memorySelfHealColumnsLibSQL2 = {
256526
+ version: 12,
256527
+ description: "Schema convergence: self-heal missing columns (tags, updated_at, decay_factor, access_count, last_accessed, category, status)",
256528
+ up: `
256529
+ -- No-op: actual column additions handled by healMemorySchema() post-migration.
256530
+ -- This migration just bumps the version number.
256531
+ SELECT 1;
256532
+ `,
256533
+ down: `
256534
+ -- Cannot remove columns in older SQLite versions
256535
+ SELECT 1;
256056
256536
  `
256057
256537
  };
256058
256538
  memoryMigrations2 = [memoryMigration2];
256539
+ memoryMigrationsLibSQL2 = [
256540
+ memoryMigrationLibSQL2,
256541
+ memorySchemaOverhaulLibSQL2,
256542
+ sessionMetadataExtensionLibSQL2,
256543
+ memorySelfHealColumnsLibSQL2
256544
+ ];
256059
256545
  });
256060
256546
  exports_migrations22 = {};
256061
256547
  __export7(exports_migrations22, {
@@ -256395,7 +256881,7 @@ ${stack.split(`
256395
256881
  `
256396
256882
  },
256397
256883
  ...hiveMigrations2,
256398
- ...memoryMigrations2
256884
+ ...memoryMigrationsLibSQL2
256399
256885
  ];
256400
256886
  });
256401
256887
  init_decision_trace_store2 = __esm5(() => {
@@ -29321,8 +29321,48 @@ async function runMigrations(db2) {
29321
29321
  }
29322
29322
  }
29323
29323
  const finalVersion = await getCurrentVersion3(db2);
29324
+ await healMemorySchema(db2);
29324
29325
  return { applied, current: finalVersion };
29325
29326
  }
29327
+ async function healMemorySchema(db2) {
29328
+ try {
29329
+ const tableCheck = await db2.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='memories'`);
29330
+ if (tableCheck.rows.length === 0)
29331
+ return;
29332
+ const columnsResult = await db2.query(`SELECT name FROM pragma_table_info('memories')`);
29333
+ const existingColumns = new Set(columnsResult.rows.map((r) => r.name));
29334
+ const expectedColumns = [
29335
+ { name: "tags", type: "TEXT", defaultVal: "'[]'" },
29336
+ { name: "updated_at", type: "TEXT", defaultVal: "(datetime('now'))" },
29337
+ { name: "decay_factor", type: "REAL", defaultVal: "1.0" },
29338
+ { name: "access_count", type: "TEXT", defaultVal: "'0'" },
29339
+ { name: "last_accessed", type: "TEXT", defaultVal: "(datetime('now'))" },
29340
+ { name: "category", type: "TEXT", defaultVal: "NULL" },
29341
+ { name: "status", type: "TEXT", defaultVal: "'active'" },
29342
+ { name: "valid_from", type: "TEXT", defaultVal: "NULL" },
29343
+ { name: "valid_until", type: "TEXT", defaultVal: "NULL" },
29344
+ { name: "superseded_by", type: "TEXT", defaultVal: "NULL" },
29345
+ { name: "auto_tags", type: "TEXT", defaultVal: "NULL" },
29346
+ { name: "keywords", type: "TEXT", defaultVal: "NULL" }
29347
+ ];
29348
+ let healed = 0;
29349
+ for (const col of expectedColumns) {
29350
+ if (!existingColumns.has(col.name)) {
29351
+ try {
29352
+ const defaultClause = col.defaultVal === "NULL" ? "" : ` DEFAULT ${col.defaultVal}`;
29353
+ await db2.exec(`ALTER TABLE memories ADD COLUMN ${col.name} ${col.type}${defaultClause}`);
29354
+ healed++;
29355
+ console.log(`[migrations] healed: added missing column memories.${col.name}`);
29356
+ } catch {}
29357
+ }
29358
+ }
29359
+ if (healed > 0) {
29360
+ console.log(`[migrations] self-heal: added ${healed} missing column(s) to memories table`);
29361
+ }
29362
+ } catch (error46) {
29363
+ console.warn("[migrations] self-heal failed (non-fatal):", error46.message);
29364
+ }
29365
+ }
29326
29366
  async function rollbackTo(db2, targetVersion) {
29327
29367
  const currentVersion = await getCurrentVersion3(db2);
29328
29368
  const rolledBack = [];
@@ -65982,7 +66022,7 @@ ${prefix}}`;
65982
66022
  fromDriver(value10) {
65983
66023
  return Array.from(new Float32Array(value10.buffer));
65984
66024
  }
65985
- }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrations, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol222, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist3, NEVER22, $brand2, $ZodAsyncError2, globalConfig2, init_core32, exports_util2, captureStackTrace2, allowsEval2, getParsedType22 = (data) => {
66025
+ }), memories, memoryLinks, entities, entityTaxonomy, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsResultColumnsMigration, beadsResultColumnsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrationLibSQL, memorySchemaOverhaulLibSQL, sessionMetadataExtensionLibSQL, memorySelfHealColumnsLibSQL, memoryMigrations, memoryMigrationsLibSQL, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, init_store2, FIELD_SETS, init_pagination, marker = "vercel.ai.error", symbol6, _a, _b, AISDKError, name2 = "AI_APICallError", marker2, symbol222, _a2, _b2, APICallError, name22 = "AI_EmptyResponseBodyError", marker3, symbol32, _a3, _b3, EmptyResponseBodyError, name3 = "AI_InvalidArgumentError", marker4, symbol42, _a4, _b4, InvalidArgumentError, name4 = "AI_InvalidPromptError", marker5, symbol52, _a5, _b5, InvalidPromptError, name5 = "AI_InvalidResponseDataError", marker6, symbol62, _a6, _b6, InvalidResponseDataError, name6 = "AI_JSONParseError", marker7, symbol7, _a7, _b7, JSONParseError, name7 = "AI_LoadAPIKeyError", marker8, symbol8, _a8, _b8, LoadAPIKeyError, name8 = "AI_LoadSettingError", marker9, symbol9, _a9, _b9, LoadSettingError, name9 = "AI_NoContentGeneratedError", marker10, symbol10, _a10, _b10, NoContentGeneratedError, name10 = "AI_NoSuchModelError", marker11, symbol11, _a11, _b11, NoSuchModelError, name11 = "AI_TooManyEmbeddingValuesForCallError", marker12, symbol12, _a12, _b12, TooManyEmbeddingValuesForCallError, name12 = "AI_TypeValidationError", marker13, symbol13, _a13, _b13, TypeValidationError, name13 = "AI_UnsupportedFunctionalityError", marker14, symbol14, _a14, _b14, UnsupportedFunctionalityError, init_dist3, NEVER22, $brand2, $ZodAsyncError2, globalConfig2, init_core32, exports_util2, captureStackTrace2, allowsEval2, getParsedType22 = (data) => {
65986
66026
  const t = typeof data;
65987
66027
  switch (t) {
65988
66028
  case "undefined":
@@ -133719,9 +133759,212 @@ ${stack.split(`
133719
133759
  DROP INDEX IF EXISTS memories_content_idx;
133720
133760
  DROP INDEX IF EXISTS idx_memories_collection;
133721
133761
  DROP TABLE IF EXISTS memories;
133762
+ `
133763
+ };
133764
+ memoryMigrationLibSQL = {
133765
+ version: 9,
133766
+ description: "Add semantic memory tables (memories with vector support, FTS5)",
133767
+ up: `
133768
+ -- ========================================================================
133769
+ -- Memories Table
133770
+ -- ========================================================================
133771
+ CREATE TABLE IF NOT EXISTS memories (
133772
+ id TEXT PRIMARY KEY NOT NULL,
133773
+ content TEXT NOT NULL,
133774
+ metadata TEXT DEFAULT '{}',
133775
+ collection TEXT DEFAULT 'default',
133776
+ created_at TEXT DEFAULT (datetime('now')),
133777
+ confidence REAL DEFAULT 0.7,
133778
+ embedding F32_BLOB(1024)
133779
+ );
133780
+
133781
+ -- Collection filtering index
133782
+ CREATE INDEX IF NOT EXISTS idx_memories_collection ON memories(collection);
133783
+
133784
+ -- Vector embedding index for fast similarity search
133785
+ CREATE INDEX IF NOT EXISTS idx_memories_embedding ON memories(libsql_vector_idx(embedding));
133786
+
133787
+ -- ========================================================================
133788
+ -- FTS5 virtual table for full-text search
133789
+ -- ========================================================================
133790
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
133791
+ USING fts5(id UNINDEXED, content, content=memories, content_rowid=rowid);
133792
+
133793
+ -- Triggers to keep FTS5 in sync
133794
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert
133795
+ AFTER INSERT ON memories
133796
+ BEGIN
133797
+ INSERT INTO memories_fts(rowid, id, content)
133798
+ VALUES (new.rowid, new.id, new.content);
133799
+ END;
133800
+
133801
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update
133802
+ AFTER UPDATE ON memories
133803
+ BEGIN
133804
+ UPDATE memories_fts
133805
+ SET content = new.content
133806
+ WHERE rowid = new.rowid;
133807
+ END;
133808
+
133809
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete
133810
+ AFTER DELETE ON memories
133811
+ BEGIN
133812
+ DELETE FROM memories_fts WHERE rowid = old.rowid;
133813
+ END;
133814
+ `,
133815
+ down: `
133816
+ -- Drop in reverse order
133817
+ DROP TRIGGER IF EXISTS memories_fts_delete;
133818
+ DROP TRIGGER IF EXISTS memories_fts_update;
133819
+ DROP TRIGGER IF EXISTS memories_fts_insert;
133820
+ DROP TABLE IF EXISTS memories_fts;
133821
+ DROP INDEX IF EXISTS idx_memories_embedding;
133822
+ DROP INDEX IF EXISTS idx_memories_collection;
133823
+ DROP TABLE IF EXISTS memories;
133824
+ `
133825
+ };
133826
+ memorySchemaOverhaulLibSQL = {
133827
+ version: 10,
133828
+ description: "Memory schema overhaul: links, entities, relationships, temporal fields",
133829
+ up: `
133830
+ -- ========================================================================
133831
+ -- Add temporal and metadata columns to memories table
133832
+ -- ========================================================================
133833
+ ALTER TABLE memories ADD COLUMN valid_from TEXT;
133834
+ ALTER TABLE memories ADD COLUMN valid_until TEXT;
133835
+ ALTER TABLE memories ADD COLUMN superseded_by TEXT REFERENCES memories(id);
133836
+ ALTER TABLE memories ADD COLUMN auto_tags TEXT;
133837
+ ALTER TABLE memories ADD COLUMN keywords TEXT;
133838
+
133839
+ -- ========================================================================
133840
+ -- Memory Links Table (Zettelkasten-style bidirectional connections)
133841
+ -- ========================================================================
133842
+ CREATE TABLE IF NOT EXISTS memory_links (
133843
+ id TEXT PRIMARY KEY,
133844
+ source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133845
+ target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133846
+ link_type TEXT NOT NULL,
133847
+ strength REAL DEFAULT 1.0,
133848
+ created_at TEXT DEFAULT (datetime('now')),
133849
+ UNIQUE(source_id, target_id, link_type)
133850
+ );
133851
+
133852
+ CREATE INDEX IF NOT EXISTS idx_memory_links_source ON memory_links(source_id);
133853
+ CREATE INDEX IF NOT EXISTS idx_memory_links_target ON memory_links(target_id);
133854
+
133855
+ -- ========================================================================
133856
+ -- Entities Table (Named entities extracted from memories)
133857
+ -- ========================================================================
133858
+ CREATE TABLE IF NOT EXISTS entities (
133859
+ id TEXT PRIMARY KEY,
133860
+ name TEXT NOT NULL,
133861
+ entity_type TEXT NOT NULL,
133862
+ canonical_name TEXT,
133863
+ created_at TEXT DEFAULT (datetime('now')),
133864
+ updated_at TEXT DEFAULT (datetime('now')),
133865
+ UNIQUE(name, entity_type)
133866
+ );
133867
+
133868
+ CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(entity_type);
133869
+ CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
133870
+
133871
+ -- ========================================================================
133872
+ -- Relationships Table (Entity-entity triples)
133873
+ -- ========================================================================
133874
+ CREATE TABLE IF NOT EXISTS relationships (
133875
+ id TEXT PRIMARY KEY,
133876
+ subject_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133877
+ predicate TEXT NOT NULL,
133878
+ object_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133879
+ memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
133880
+ confidence REAL DEFAULT 1.0,
133881
+ created_at TEXT DEFAULT (datetime('now')),
133882
+ UNIQUE(subject_id, predicate, object_id)
133883
+ );
133884
+
133885
+ CREATE INDEX IF NOT EXISTS idx_relationships_subject ON relationships(subject_id);
133886
+ CREATE INDEX IF NOT EXISTS idx_relationships_object ON relationships(object_id);
133887
+ CREATE INDEX IF NOT EXISTS idx_relationships_predicate ON relationships(predicate);
133888
+
133889
+ -- ========================================================================
133890
+ -- Memory-Entities Junction Table
133891
+ -- ========================================================================
133892
+ CREATE TABLE IF NOT EXISTS memory_entities (
133893
+ memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
133894
+ entity_id TEXT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
133895
+ role TEXT,
133896
+ PRIMARY KEY(memory_id, entity_id)
133897
+ );
133898
+ `,
133899
+ down: `
133900
+ -- Drop tables in dependency order
133901
+ DROP TABLE IF EXISTS memory_entities;
133902
+ DROP TABLE IF EXISTS relationships;
133903
+ DROP INDEX IF EXISTS idx_memory_links_source;
133904
+ DROP INDEX IF EXISTS idx_memory_links_target;
133905
+ DROP TABLE IF EXISTS memory_links;
133906
+ DROP INDEX IF EXISTS idx_entities_type;
133907
+ DROP INDEX IF EXISTS idx_entities_name;
133908
+ DROP TABLE IF EXISTS entities;
133909
+
133910
+ -- Remove columns from memories table (SQLite doesn't support DROP COLUMN until 3.35.0)
133911
+ -- In production, these columns can be left as NULL if downgrade is needed
133912
+ -- Or recreate table without these columns
133913
+ `
133914
+ };
133915
+ sessionMetadataExtensionLibSQL = {
133916
+ version: 11,
133917
+ description: "Add session metadata columns (agent_type, session_id, message_role, message_idx, source_path)",
133918
+ up: `
133919
+ -- ========================================================================
133920
+ -- Add session metadata columns to memories table
133921
+ -- ========================================================================
133922
+ ALTER TABLE memories ADD COLUMN agent_type TEXT;
133923
+ ALTER TABLE memories ADD COLUMN session_id TEXT;
133924
+ ALTER TABLE memories ADD COLUMN message_role TEXT CHECK(message_role IN ('user', 'assistant', 'system'));
133925
+ ALTER TABLE memories ADD COLUMN message_idx INTEGER;
133926
+ ALTER TABLE memories ADD COLUMN source_path TEXT;
133927
+
133928
+ -- Index for session-based queries
133929
+ CREATE INDEX IF NOT EXISTS idx_memories_session ON memories(session_id, message_idx);
133930
+
133931
+ -- Index for agent filtering
133932
+ CREATE INDEX IF NOT EXISTS idx_memories_agent_type ON memories(agent_type);
133933
+
133934
+ -- Index for role filtering
133935
+ CREATE INDEX IF NOT EXISTS idx_memories_role ON memories(message_role);
133936
+ `,
133937
+ down: `
133938
+ -- Drop indexes first
133939
+ DROP INDEX IF EXISTS idx_memories_role;
133940
+ DROP INDEX IF EXISTS idx_memories_agent_type;
133941
+ DROP INDEX IF EXISTS idx_memories_session;
133942
+
133943
+ -- SQLite doesn't support DROP COLUMN until 3.35.0
133944
+ -- In production, these columns can be left as NULL if downgrade is needed
133945
+ -- Or recreate table without these columns
133946
+ `
133947
+ };
133948
+ memorySelfHealColumnsLibSQL = {
133949
+ version: 12,
133950
+ description: "Schema convergence: self-heal missing columns (tags, updated_at, decay_factor, access_count, last_accessed, category, status)",
133951
+ up: `
133952
+ -- No-op: actual column additions handled by healMemorySchema() post-migration.
133953
+ -- This migration just bumps the version number.
133954
+ SELECT 1;
133955
+ `,
133956
+ down: `
133957
+ -- Cannot remove columns in older SQLite versions
133958
+ SELECT 1;
133722
133959
  `
133723
133960
  };
133724
133961
  memoryMigrations = [memoryMigration];
133962
+ memoryMigrationsLibSQL = [
133963
+ memoryMigrationLibSQL,
133964
+ memorySchemaOverhaulLibSQL,
133965
+ sessionMetadataExtensionLibSQL,
133966
+ memorySelfHealColumnsLibSQL
133967
+ ];
133725
133968
  });
133726
133969
  exports_migrations2 = {};
133727
133970
  __export2(exports_migrations2, {
@@ -134061,7 +134304,7 @@ ${stack.split(`
134061
134304
  `
134062
134305
  },
134063
134306
  ...hiveMigrations,
134064
- ...memoryMigrations
134307
+ ...memoryMigrationsLibSQL
134065
134308
  ];
134066
134309
  });
134067
134310
  init_decision_trace_store = __esm2(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm-plugin",
3
- "version": "0.62.1",
3
+ "version": "0.62.2",
4
4
  "description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",