kiro-memory 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,7 +70,7 @@ var BunQueryCompat = class {
70
70
  // src/shared/paths.ts
71
71
  import { join as join2, dirname, basename } from "path";
72
72
  import { homedir as homedir2 } from "os";
73
- import { mkdirSync as mkdirSync2 } from "fs";
73
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
74
74
  import { fileURLToPath } from "url";
75
75
 
76
76
  // src/utils/logger.ts
@@ -300,7 +300,9 @@ function getDirname() {
300
300
  return dirname(fileURLToPath(import.meta.url));
301
301
  }
302
302
  var _dirname = getDirname();
303
- var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || join2(homedir2(), ".contextkit");
303
+ var _legacyDir = join2(homedir2(), ".contextkit");
304
+ var _defaultDir = existsSync2(_legacyDir) ? _legacyDir : join2(homedir2(), ".kiro-memory");
305
+ var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || _defaultDir;
304
306
  var KIRO_CONFIG_DIR = process.env.KIRO_CONFIG_DIR || join2(homedir2(), ".kiro");
305
307
  var PLUGIN_ROOT = join2(KIRO_CONFIG_DIR, "plugins", "kiro-memory");
306
308
  var ARCHIVES_DIR = join2(DATA_DIR, "archives");
@@ -309,7 +311,8 @@ var TRASH_DIR = join2(DATA_DIR, "trash");
309
311
  var BACKUPS_DIR = join2(DATA_DIR, "backups");
310
312
  var MODES_DIR = join2(DATA_DIR, "modes");
311
313
  var USER_SETTINGS_PATH = join2(DATA_DIR, "settings.json");
312
- var DB_PATH = join2(DATA_DIR, "contextkit.db");
314
+ var _legacyDb = join2(DATA_DIR, "contextkit.db");
315
+ var DB_PATH = existsSync2(_legacyDb) ? _legacyDb : join2(DATA_DIR, "kiro-memory.db");
313
316
  var VECTOR_DB_DIR = join2(DATA_DIR, "vector-db");
314
317
  var OBSERVER_SESSIONS_DIR = join2(DATA_DIR, "observer-sessions");
315
318
  var KIRO_SETTINGS_PATH = join2(KIRO_CONFIG_DIR, "settings.json");
@@ -324,7 +327,11 @@ var SQLITE_CACHE_SIZE_PAGES = 1e4;
324
327
  var dbInstance = null;
325
328
  var KiroMemoryDatabase = class {
326
329
  db;
327
- constructor(dbPath = DB_PATH) {
330
+ /**
331
+ * @param dbPath - Percorso al file SQLite (default: DB_PATH)
332
+ * @param skipMigrations - Se true, salta il migration runner (per hook ad alta frequenza)
333
+ */
334
+ constructor(dbPath = DB_PATH, skipMigrations = false) {
328
335
  if (dbPath !== ":memory:") {
329
336
  ensureDir(DATA_DIR);
330
337
  }
@@ -335,8 +342,18 @@ var KiroMemoryDatabase = class {
335
342
  this.db.run("PRAGMA temp_store = memory");
336
343
  this.db.run(`PRAGMA mmap_size = ${SQLITE_MMAP_SIZE_BYTES}`);
337
344
  this.db.run(`PRAGMA cache_size = ${SQLITE_CACHE_SIZE_PAGES}`);
338
- const migrationRunner = new MigrationRunner(this.db);
339
- migrationRunner.runAllMigrations();
345
+ if (!skipMigrations) {
346
+ const migrationRunner = new MigrationRunner(this.db);
347
+ migrationRunner.runAllMigrations();
348
+ }
349
+ }
350
+ /**
351
+ * Esegue una funzione all'interno di una transazione atomica.
352
+ * Se fn() lancia un errore, la transazione viene annullata automaticamente.
353
+ */
354
+ withTransaction(fn) {
355
+ const transaction = this.db.transaction(fn);
356
+ return transaction(this.db);
340
357
  }
341
358
  /**
342
359
  * Close the database connection
@@ -634,6 +651,7 @@ async function initializeDatabase() {
634
651
  return await manager.initialize();
635
652
  }
636
653
  export {
654
+ KiroMemoryDatabase as ContextKitDatabase,
637
655
  Database,
638
656
  DatabaseManager,
639
657
  KiroMemoryDatabase,
@@ -1,15 +1,21 @@
1
1
  import { createRequire } from 'module';const require = createRequire(import.meta.url);
2
2
 
3
3
  // src/services/sqlite/Search.ts
4
+ function sanitizeFTS5Query(query) {
5
+ const terms = query.replace(/[""]/g, "").split(/\s+/).filter((t) => t.length > 0).map((t) => `"${t}"`);
6
+ return terms.join(" ");
7
+ }
4
8
  function searchObservationsFTS(db, query, filters = {}) {
5
9
  const limit = filters.limit || 50;
6
10
  try {
11
+ const safeQuery = sanitizeFTS5Query(query);
12
+ if (!safeQuery) return searchObservationsLIKE(db, query, filters);
7
13
  let sql = `
8
14
  SELECT o.* FROM observations o
9
15
  JOIN observations_fts fts ON o.id = fts.rowid
10
16
  WHERE observations_fts MATCH ?
11
17
  `;
12
- const params = [query];
18
+ const params = [safeQuery];
13
19
  if (filters.project) {
14
20
  sql += " AND o.project = ?";
15
21
  params.push(filters.project);
@@ -70,7 +70,7 @@ var BunQueryCompat = class {
70
70
  // src/shared/paths.ts
71
71
  import { join as join2, dirname, basename } from "path";
72
72
  import { homedir as homedir2 } from "os";
73
- import { mkdirSync as mkdirSync2 } from "fs";
73
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
74
74
  import { fileURLToPath } from "url";
75
75
 
76
76
  // src/utils/logger.ts
@@ -300,7 +300,9 @@ function getDirname() {
300
300
  return dirname(fileURLToPath(import.meta.url));
301
301
  }
302
302
  var _dirname = getDirname();
303
- var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || join2(homedir2(), ".contextkit");
303
+ var _legacyDir = join2(homedir2(), ".contextkit");
304
+ var _defaultDir = existsSync2(_legacyDir) ? _legacyDir : join2(homedir2(), ".kiro-memory");
305
+ var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || _defaultDir;
304
306
  var KIRO_CONFIG_DIR = process.env.KIRO_CONFIG_DIR || join2(homedir2(), ".kiro");
305
307
  var PLUGIN_ROOT = join2(KIRO_CONFIG_DIR, "plugins", "kiro-memory");
306
308
  var ARCHIVES_DIR = join2(DATA_DIR, "archives");
@@ -309,7 +311,8 @@ var TRASH_DIR = join2(DATA_DIR, "trash");
309
311
  var BACKUPS_DIR = join2(DATA_DIR, "backups");
310
312
  var MODES_DIR = join2(DATA_DIR, "modes");
311
313
  var USER_SETTINGS_PATH = join2(DATA_DIR, "settings.json");
312
- var DB_PATH = join2(DATA_DIR, "contextkit.db");
314
+ var _legacyDb = join2(DATA_DIR, "contextkit.db");
315
+ var DB_PATH = existsSync2(_legacyDb) ? _legacyDb : join2(DATA_DIR, "kiro-memory.db");
313
316
  var VECTOR_DB_DIR = join2(DATA_DIR, "vector-db");
314
317
  var OBSERVER_SESSIONS_DIR = join2(DATA_DIR, "observer-sessions");
315
318
  var KIRO_SETTINGS_PATH = join2(KIRO_CONFIG_DIR, "settings.json");
@@ -324,7 +327,11 @@ var SQLITE_CACHE_SIZE_PAGES = 1e4;
324
327
  var dbInstance = null;
325
328
  var KiroMemoryDatabase = class {
326
329
  db;
327
- constructor(dbPath = DB_PATH) {
330
+ /**
331
+ * @param dbPath - Percorso al file SQLite (default: DB_PATH)
332
+ * @param skipMigrations - Se true, salta il migration runner (per hook ad alta frequenza)
333
+ */
334
+ constructor(dbPath = DB_PATH, skipMigrations = false) {
328
335
  if (dbPath !== ":memory:") {
329
336
  ensureDir(DATA_DIR);
330
337
  }
@@ -335,8 +342,18 @@ var KiroMemoryDatabase = class {
335
342
  this.db.run("PRAGMA temp_store = memory");
336
343
  this.db.run(`PRAGMA mmap_size = ${SQLITE_MMAP_SIZE_BYTES}`);
337
344
  this.db.run(`PRAGMA cache_size = ${SQLITE_CACHE_SIZE_PAGES}`);
338
- const migrationRunner = new MigrationRunner(this.db);
339
- migrationRunner.runAllMigrations();
345
+ if (!skipMigrations) {
346
+ const migrationRunner = new MigrationRunner(this.db);
347
+ migrationRunner.runAllMigrations();
348
+ }
349
+ }
350
+ /**
351
+ * Esegue una funzione all'interno di una transazione atomica.
352
+ * Se fn() lancia un errore, la transazione viene annullata automaticamente.
353
+ */
354
+ withTransaction(fn) {
355
+ const transaction = this.db.transaction(fn);
356
+ return transaction(this.db);
340
357
  }
341
358
  /**
342
359
  * Close the database connection
@@ -797,15 +814,21 @@ function deletePrompt(db, id) {
797
814
  }
798
815
 
799
816
  // src/services/sqlite/Search.ts
817
+ function sanitizeFTS5Query(query) {
818
+ const terms = query.replace(/[""]/g, "").split(/\s+/).filter((t) => t.length > 0).map((t) => `"${t}"`);
819
+ return terms.join(" ");
820
+ }
800
821
  function searchObservationsFTS(db, query, filters = {}) {
801
822
  const limit = filters.limit || 50;
802
823
  try {
824
+ const safeQuery = sanitizeFTS5Query(query);
825
+ if (!safeQuery) return searchObservationsLIKE(db, query, filters);
803
826
  let sql = `
804
827
  SELECT o.* FROM observations o
805
828
  JOIN observations_fts fts ON o.id = fts.rowid
806
829
  WHERE observations_fts MATCH ?
807
830
  `;
808
- const params = [query];
831
+ const params = [safeQuery];
809
832
  if (filters.project) {
810
833
  sql += " AND o.project = ?";
811
834
  params.push(filters.project);
@@ -3,7 +3,7 @@ import { createRequire } from 'module';const require = createRequire(import.meta
3
3
  // src/shared/paths.ts
4
4
  import { join as join2, dirname, basename } from "path";
5
5
  import { homedir as homedir2 } from "os";
6
- import { mkdirSync as mkdirSync2 } from "fs";
6
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
7
7
  import { execSync } from "child_process";
8
8
  import { fileURLToPath } from "url";
9
9
 
@@ -234,7 +234,9 @@ function getDirname() {
234
234
  return dirname(fileURLToPath(import.meta.url));
235
235
  }
236
236
  var _dirname = getDirname();
237
- var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || join2(homedir2(), ".contextkit");
237
+ var _legacyDir = join2(homedir2(), ".contextkit");
238
+ var _defaultDir = existsSync2(_legacyDir) ? _legacyDir : join2(homedir2(), ".kiro-memory");
239
+ var DATA_DIR = process.env.KIRO_MEMORY_DATA_DIR || process.env.CONTEXTKIT_DATA_DIR || _defaultDir;
238
240
  var KIRO_CONFIG_DIR = process.env.KIRO_CONFIG_DIR || join2(homedir2(), ".kiro");
239
241
  var PLUGIN_ROOT = join2(KIRO_CONFIG_DIR, "plugins", "kiro-memory");
240
242
  var ARCHIVES_DIR = join2(DATA_DIR, "archives");
@@ -243,7 +245,8 @@ var TRASH_DIR = join2(DATA_DIR, "trash");
243
245
  var BACKUPS_DIR = join2(DATA_DIR, "backups");
244
246
  var MODES_DIR = join2(DATA_DIR, "modes");
245
247
  var USER_SETTINGS_PATH = join2(DATA_DIR, "settings.json");
246
- var DB_PATH = join2(DATA_DIR, "contextkit.db");
248
+ var _legacyDb = join2(DATA_DIR, "contextkit.db");
249
+ var DB_PATH = existsSync2(_legacyDb) ? _legacyDb : join2(DATA_DIR, "kiro-memory.db");
247
250
  var VECTOR_DB_DIR = join2(DATA_DIR, "vector-db");
248
251
  var OBSERVER_SESSIONS_DIR = join2(DATA_DIR, "observer-sessions");
249
252
  var KIRO_SETTINGS_PATH = join2(KIRO_CONFIG_DIR, "settings.json");
@@ -23975,11 +23975,22 @@ function useSSE() {
23975
23975
  console.error("Failed to fetch projects:", err);
23976
23976
  }
23977
23977
  };
23978
+ const fetchAll = () => {
23979
+ fetchObservations();
23980
+ fetchSummaries();
23981
+ fetchPrompts();
23982
+ fetchProjects();
23983
+ };
23984
+ let wasConnected = false;
23978
23985
  const connect = () => {
23979
23986
  if (!mountedRef.current) return;
23980
23987
  eventSource = new EventSource("/events");
23981
23988
  eventSource.onopen = () => {
23982
23989
  if (!mountedRef.current) return;
23990
+ if (wasConnected) {
23991
+ fetchAll();
23992
+ }
23993
+ wasConnected = true;
23983
23994
  retryCount = 0;
23984
23995
  setState((prev) => ({ ...prev, isConnected: true }));
23985
23996
  };
@@ -24003,10 +24014,7 @@ function useSSE() {
24003
24014
  fetchPrompts();
24004
24015
  });
24005
24016
  };
24006
- fetchObservations();
24007
- fetchSummaries();
24008
- fetchPrompts();
24009
- fetchProjects();
24017
+ fetchAll();
24010
24018
  connect();
24011
24019
  return () => {
24012
24020
  mountedRef.current = false;