@yugenlab/vaayu 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/chunks/{agentic-tool-loop-O3NUV7KG.js → agentic-tool-loop-NQESOBLC.js} +2 -2
  2. package/chunks/akasha-5C5Q6NMP.js +12 -0
  3. package/chunks/{chunk-7XV5ISV7.js → chunk-26K6DS6N.js} +2 -2
  4. package/chunks/chunk-5E3ZS5SW.js +529 -0
  5. package/chunks/{chunk-D46QTN3G.js → chunk-ARZCIITZ.js} +47 -18
  6. package/chunks/{chunk-ZYY6N3SP.js → chunk-FEDPZOZ5.js} +548 -389
  7. package/chunks/{chunk-3AYSJ7WB.js → chunk-GWYC7R2L.js} +13 -7
  8. package/chunks/chunk-H46F2Y6R.js +134 -0
  9. package/chunks/{chunk-QV4GPIPT.js → chunk-HXHDP2PZ.js} +8 -4
  10. package/chunks/chunk-KVQH4LE7.js +396 -0
  11. package/chunks/{chunk-Z576WVLG.js → chunk-LJCT7UYP.js} +17 -7
  12. package/chunks/{chunk-LJUEMPLG.js → chunk-M2RLX5LU.js} +32 -14
  13. package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
  14. package/chunks/{chunk-F6RNEGFX.js → chunk-PZ4AQ22L.js} +78 -13
  15. package/chunks/{chunk-G2QREGXK.js → chunk-R273KC7J.js} +275 -2
  16. package/chunks/{chunk-A3HOZBC5.js → chunk-RVKTGKFD.js} +2 -2
  17. package/chunks/{chunk-VCUJES75.js → chunk-TSOQ2CT3.js} +763 -620
  18. package/chunks/{chunk-V2ZIKDN4.js → chunk-VEZ2DI2M.js} +16 -5
  19. package/chunks/{chunk-W4PVGBUH.js → chunk-XP3NIH5F.js} +7 -3
  20. package/chunks/{chunk-7AYYXHYZ.js → chunk-Y6IZH6FT.js} +19 -4
  21. package/chunks/{chunk-JZTFJE7M.js → chunk-YRTGGYJU.js} +14 -10
  22. package/chunks/{consolidation-indexer-VIWOP6VO.js → consolidation-indexer-KPXORCJ4.js} +9 -9
  23. package/chunks/database-BX3LVYXS.js +11 -0
  24. package/chunks/{day-consolidation-HMHSXIOM.js → day-consolidation-CR3TJFAL.js} +5 -5
  25. package/chunks/{dist-CY5NX2IK.js → dist-ESCM3CP5.js} +31 -21
  26. package/chunks/graphrag-73XA7LBX.js +14 -0
  27. package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
  28. package/chunks/hybrid-search-OD756RDV.js +20 -0
  29. package/chunks/{memory-store-LEERUQGL.js → memory-store-4GCBR2DZ.js} +4 -4
  30. package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
  31. package/chunks/{postgres-7GZDDX77.js → postgres-YLCUNVPQ.js} +2 -2
  32. package/chunks/recall-64RROTUC.js +21 -0
  33. package/chunks/search-JVCDNTAJ.js +19 -0
  34. package/chunks/{session-store-O3TS7DUY.js → session-store-3EDQZEDS.js} +12 -6
  35. package/chunks/{sqlite-7BC4DJTN.js → sqlite-4N7YH2KK.js} +2 -2
  36. package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
  37. package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
  38. package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
  39. package/chunks/{vasana-engine-BJFHJVGM.js → vasana-engine-W4PYWT5H.js} +5 -5
  40. package/gateway.js +2358 -768
  41. package/package.json +1 -1
  42. package/pair-cli.js +2 -2
  43. package/chunks/chunk-2OBLQJYJ.js +0 -198
  44. package/chunks/chunk-67DXWEKG.js +0 -123
  45. package/chunks/graphrag-T2QWNX57.js +0 -14
  46. package/chunks/hierarchical-temporal-search-U6DG74IR.js +0 -8
  47. package/chunks/hybrid-search-BYTXCOXP.js +0 -20
  48. package/chunks/periodic-consolidation-D6SSKZ7H.js +0 -11
  49. package/chunks/recall-LNRQVATQ.js +0 -21
  50. package/chunks/search-BIODUW2P.js +0 -19
@@ -1,19 +1,21 @@
1
1
  import {
2
- initAgentSchema
3
- } from "./chunk-V2ZIKDN4.js";
2
+ initAgentSchema,
3
+ init_schema
4
+ } from "./chunk-VEZ2DI2M.js";
4
5
  import {
5
- DatabaseManager
6
- } from "./chunk-67DXWEKG.js";
6
+ DatabaseManager,
7
+ init_database
8
+ } from "./chunk-H46F2Y6R.js";
7
9
  import {
8
10
  SessionError,
9
- getChitraguptaHome
10
- } from "./chunk-2OBLQJYJ.js";
11
-
12
- // ../chitragupta/packages/smriti/dist/session-store.js
13
- import fs from "fs";
14
- import { renameSync as nodeRenameSync } from "node:fs";
15
- import path from "path";
16
- import crypto from "crypto";
11
+ getChitraguptaHome,
12
+ init_dist
13
+ } from "./chunk-KVQH4LE7.js";
14
+ import {
15
+ __esm,
16
+ __export,
17
+ __toCommonJS
18
+ } from "./chunk-NAQKA54E.js";
17
19
 
18
20
  // ../chitragupta/packages/smriti/dist/markdown-parser.js
19
21
  function parseFrontmatter(yaml) {
@@ -209,6 +211,12 @@ function parseToolCallSection(name, section) {
209
211
  toolCall.isError = true;
210
212
  return toolCall;
211
213
  }
214
+ var init_markdown_parser = __esm({
215
+ "../chitragupta/packages/smriti/dist/markdown-parser.js"() {
216
+ "use strict";
217
+ init_dist();
218
+ }
219
+ });
212
220
 
213
221
  // ../chitragupta/packages/smriti/dist/markdown-writer.js
214
222
  function writeFrontmatter(meta) {
@@ -302,147 +310,24 @@ function writeSessionMarkdown(session) {
302
310
  function writeTurnMarkdown(turn) {
303
311
  return writeTurn(turn);
304
312
  }
305
-
306
- // ../chitragupta/packages/smriti/dist/session-store.js
307
- function atomicRename(tmpPath, targetPath) {
308
- try {
309
- nodeRenameSync(tmpPath, targetPath);
310
- } catch {
311
- fs.writeFileSync(targetPath, fs.readFileSync(tmpPath, "utf-8"), "utf-8");
312
- try {
313
- fs.unlinkSync(tmpPath);
314
- } catch {
315
- }
316
- }
317
- }
318
- var SESSION_CACHE_MAX = 500;
319
- var SESSION_CACHE_MAX_BYTES = 25 * 1024 * 1024;
320
- var sessionCache = /* @__PURE__ */ new Map();
321
- var sessionCacheSizes = /* @__PURE__ */ new Map();
322
- var sessionCacheBytes = 0;
323
- function estimateSessionBytes(session) {
324
- let bytes = 200;
325
- for (const turn of session.turns) {
326
- bytes += Buffer.byteLength(turn.content, "utf-8") + 50;
327
- }
328
- return bytes;
329
- }
330
- function cacheKey(id, project) {
331
- return `${id}:${project}`;
332
- }
333
- function cacheGet(id, project) {
334
- const key = cacheKey(id, project);
335
- const entry = sessionCache.get(key);
336
- if (!entry)
337
- return void 0;
338
- const size = sessionCacheSizes.get(key) ?? 0;
339
- sessionCache.delete(key);
340
- sessionCacheSizes.delete(key);
341
- sessionCache.set(key, entry);
342
- sessionCacheSizes.set(key, size);
343
- return entry;
344
- }
345
- function cachePut(id, project, session) {
346
- const key = cacheKey(id, project);
347
- const existingSize = sessionCacheSizes.get(key) ?? 0;
348
- sessionCache.delete(key);
349
- sessionCacheSizes.delete(key);
350
- sessionCacheBytes -= existingSize;
351
- const newSize = estimateSessionBytes(session);
352
- while ((sessionCache.size >= SESSION_CACHE_MAX || sessionCacheBytes + newSize > SESSION_CACHE_MAX_BYTES) && sessionCache.size > 0) {
353
- const oldest = sessionCache.keys().next().value;
354
- if (oldest === void 0)
355
- break;
356
- const evictedSize = sessionCacheSizes.get(oldest) ?? 0;
357
- sessionCache.delete(oldest);
358
- sessionCacheSizes.delete(oldest);
359
- sessionCacheBytes -= evictedSize;
313
+ var init_markdown_writer = __esm({
314
+ "../chitragupta/packages/smriti/dist/markdown-writer.js"() {
315
+ "use strict";
360
316
  }
361
- sessionCache.set(key, session);
362
- sessionCacheSizes.set(key, newSize);
363
- sessionCacheBytes += newSize;
364
- }
365
- function cacheInvalidate(id, project) {
366
- const key = cacheKey(id, project);
367
- const size = sessionCacheSizes.get(key) ?? 0;
368
- sessionCache.delete(key);
369
- sessionCacheSizes.delete(key);
370
- sessionCacheBytes -= size;
371
- }
372
- function _resetSessionCache() {
373
- sessionCache.clear();
374
- sessionCacheSizes.clear();
375
- sessionCacheBytes = 0;
376
- }
317
+ });
318
+
319
+ // ../chitragupta/packages/smriti/dist/session-db.js
320
+ import path from "path";
321
+ import crypto from "crypto";
377
322
  function hashProject(project) {
378
323
  return crypto.createHash("sha256").update(project).digest("hex").slice(0, 12);
379
324
  }
380
- function generateSessionId(project) {
381
- const now = /* @__PURE__ */ new Date();
382
- const yyyy = now.getFullYear().toString();
383
- const mm = (now.getMonth() + 1).toString().padStart(2, "0");
384
- const dd = now.getDate().toString().padStart(2, "0");
385
- const dateStr = `${yyyy}-${mm}-${dd}`;
386
- const projHash = hashProject(project).slice(0, 8);
387
- const baseId = `session-${dateStr}-${projHash}`;
388
- const projectDir = getProjectSessionDir(project);
389
- const yearMonthDir = path.join(projectDir, yyyy, mm);
390
- fs.mkdirSync(yearMonthDir, { recursive: true });
391
- const basePath = path.join(yearMonthDir, `${baseId}.md`);
392
- if (!fs.existsSync(basePath)) {
393
- return {
394
- id: baseId,
395
- filePath: path.join("sessions", hashProject(project), yyyy, mm, `${baseId}.md`)
396
- };
397
- }
398
- let counter = 2;
399
- while (fs.existsSync(path.join(yearMonthDir, `${baseId}-${counter}.md`))) {
400
- counter++;
401
- }
402
- const id = `${baseId}-${counter}`;
403
- return {
404
- id,
405
- filePath: path.join("sessions", hashProject(project), yyyy, mm, `${id}.md`)
406
- };
407
- }
408
325
  function getSessionsRoot() {
409
326
  return path.join(getChitraguptaHome(), "sessions");
410
327
  }
411
328
  function getProjectSessionDir(project) {
412
329
  return path.join(getSessionsRoot(), hashProject(project));
413
330
  }
414
- function resolveSessionPath(id, project) {
415
- const projectDir = getProjectSessionDir(project);
416
- const dateMatch = id.match(/^session-(\d{4})-(\d{2})-\d{2}/);
417
- if (dateMatch) {
418
- const newPath = path.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
419
- if (fs.existsSync(newPath))
420
- return newPath;
421
- }
422
- const oldPath = path.join(projectDir, `${id}.md`);
423
- if (fs.existsSync(oldPath))
424
- return oldPath;
425
- if (dateMatch) {
426
- return path.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
427
- }
428
- return oldPath;
429
- }
430
- function patchFrontmatterUpdated(content, updatedIso) {
431
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
432
- if (!fmMatch)
433
- return content;
434
- const frontmatter = fmMatch[1];
435
- if (!/^updated:\s/m.test(frontmatter))
436
- return content;
437
- const patchedFrontmatter = frontmatter.replace(/^updated:\s.*$/m, `updated: ${updatedIso}`);
438
- if (patchedFrontmatter === frontmatter)
439
- return content;
440
- return `---
441
- ${patchedFrontmatter}
442
- ---${content.slice(fmMatch[0].length)}`;
443
- }
444
- var _dbInitialized = false;
445
- var _dbInitError = null;
446
331
  function getAgentDb() {
447
332
  const dbm = DatabaseManager.instance();
448
333
  if (!_dbInitialized) {
@@ -553,8 +438,8 @@ function seedSessionRowForTurn(sessionId, project, filePath) {
553
438
  function insertTurnToDb(sessionId, turn, context) {
554
439
  try {
555
440
  const db = getAgentDb();
441
+ const now = Date.now();
556
442
  const writeTurn2 = db.transaction(() => {
557
- const now = Date.now();
558
443
  const result = db.prepare(`
559
444
  INSERT OR IGNORE INTO turns (session_id, turn_number, role, content, agent, model, tool_calls, created_at)
560
445
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
@@ -581,153 +466,97 @@ function insertTurnToDb(sessionId, turn, context) {
581
466
  `);
582
467
  }
583
468
  }
584
- function createSession(opts) {
585
- const now = (/* @__PURE__ */ new Date()).toISOString();
586
- const { id, filePath } = generateSessionId(opts.project);
587
- const meta = {
588
- id,
589
- title: opts.title ?? "New Session",
590
- created: now,
591
- updated: now,
592
- agent: opts.agent ?? "chitragupta",
593
- model: opts.model ?? "unknown",
594
- provider: opts.provider,
595
- project: opts.project,
596
- parent: opts.parentSessionId ?? null,
597
- branch: opts.branch ?? null,
598
- tags: opts.tags ?? [],
599
- totalCost: 0,
600
- totalTokens: 0,
601
- metadata: opts.metadata
602
- };
603
- if (opts.provider) {
604
- meta.metadata = { ...meta.metadata, provider: opts.provider };
605
- }
606
- const session = { meta, turns: [] };
607
- saveSession(session);
608
- upsertSessionToDb(meta, filePath);
609
- return session;
610
- }
611
- function saveSession(session) {
612
- const filePath = resolveSessionPath(session.meta.id, session.meta.project);
613
- const dir = path.dirname(filePath);
469
+ function getMaxTurnNumber(sessionId) {
614
470
  try {
615
- fs.mkdirSync(dir, { recursive: true });
616
- session.meta.updated = (/* @__PURE__ */ new Date()).toISOString();
617
- const markdown = writeSessionMarkdown(session);
618
- const tmpPath = `${filePath}.tmp.${process.pid}`;
619
- fs.writeFileSync(tmpPath, markdown, "utf-8");
620
- atomicRename(tmpPath, filePath);
621
- cachePut(session.meta.id, session.meta.project, session);
622
- } catch (err) {
623
- throw new SessionError(`Failed to save session ${session.meta.id} at ${filePath}: ${err.message}`);
471
+ const db = getAgentDb();
472
+ const row = db.prepare("SELECT MAX(turn_number) as max_turn FROM turns WHERE session_id = ?").get(sessionId);
473
+ return row?.max_turn ?? 0;
474
+ } catch {
475
+ return 0;
624
476
  }
625
477
  }
626
- function loadSession(id, project) {
627
- const cached = cacheGet(id, project);
628
- if (cached)
629
- return cached;
630
- const filePath = resolveSessionPath(id, project);
631
- if (!fs.existsSync(filePath)) {
632
- throw new SessionError(`Session not found: ${id} (project: ${project})`);
478
+ var _dbInitialized, _dbInitError;
479
+ var init_session_db = __esm({
480
+ "../chitragupta/packages/smriti/dist/session-db.js"() {
481
+ "use strict";
482
+ init_dist();
483
+ init_database();
484
+ init_schema();
485
+ _dbInitialized = false;
486
+ _dbInitError = null;
633
487
  }
634
- try {
635
- const content = fs.readFileSync(filePath, "utf-8");
636
- const session = parseSessionMarkdown(content);
637
- cachePut(id, project, session);
638
- return session;
639
- } catch (err) {
640
- if (err instanceof SessionError)
641
- throw err;
642
- throw new SessionError(`Failed to load session ${id}: ${err.message}`);
488
+ });
489
+
490
+ // ../chitragupta/packages/smriti/dist/session-store-cache.js
491
+ function estimateSessionBytes(session) {
492
+ let bytes = 200;
493
+ for (const turn of session.turns) {
494
+ bytes += Buffer.byteLength(turn.content, "utf-8") + 50;
643
495
  }
496
+ return bytes;
644
497
  }
645
- function listSessions(project) {
646
- try {
647
- const db = getAgentDb();
648
- let rows;
649
- if (project) {
650
- rows = db.prepare("SELECT * FROM sessions WHERE project = ? ORDER BY updated_at DESC").all(project);
651
- } else {
652
- rows = db.prepare("SELECT * FROM sessions ORDER BY updated_at DESC").all();
653
- }
654
- if (rows.length > 0) {
655
- return rows.map(rowToSessionMeta);
656
- }
657
- } catch (err) {
658
- process.stderr.write(`[chitragupta] listSessions SQLite failed, falling back to filesystem: ${err instanceof Error ? err.message : err}
659
- `);
660
- }
661
- return listSessionsFromFilesystem(project);
498
+ function cacheKey(id, project) {
499
+ return `${id}:${project}`;
662
500
  }
663
- function listSessionsByDate(date, project) {
664
- const dateMatch = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
665
- if (!dateMatch) {
666
- throw new SessionError(`Invalid date format: ${date}. Expected YYYY-MM-DD.`);
667
- }
668
- const startOfDay = (/* @__PURE__ */ new Date(`${date}T00:00:00.000Z`)).getTime();
669
- const endOfDay = startOfDay + 864e5;
670
- return listSessionsByDateRange(startOfDay, endOfDay, project);
501
+ function cacheGet(id, project) {
502
+ const key = cacheKey(id, project);
503
+ const entry = sessionCache.get(key);
504
+ if (!entry)
505
+ return void 0;
506
+ const size = sessionCacheSizes.get(key) ?? 0;
507
+ sessionCache.delete(key);
508
+ sessionCacheSizes.delete(key);
509
+ sessionCache.set(key, entry);
510
+ sessionCacheSizes.set(key, size);
511
+ return entry;
671
512
  }
672
- function listSessionsByDateRange(startMs, endMs, project) {
673
- try {
674
- const db = getAgentDb();
675
- let rows;
676
- if (project) {
677
- rows = db.prepare("SELECT * FROM sessions WHERE project = ? AND created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(project, startMs, endMs);
678
- } else {
679
- rows = db.prepare("SELECT * FROM sessions WHERE created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(startMs, endMs);
680
- }
681
- if (rows.length > 0) {
682
- return rows.map(rowToSessionMeta);
683
- }
684
- } catch {
685
- }
686
- const allSessions = listSessionsFromFilesystem(project);
687
- return allSessions.filter((s) => {
688
- const created = new Date(s.created).getTime();
689
- return created >= startMs && created < endMs;
690
- });
691
- }
692
- function listSessionDates(project) {
693
- try {
694
- const db = getAgentDb();
695
- let rows;
696
- if (project) {
697
- rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
698
- FROM sessions WHERE project = ?
699
- ORDER BY session_date DESC`).all(project);
700
- } else {
701
- rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
702
- FROM sessions
703
- ORDER BY session_date DESC`).all();
704
- }
705
- return rows.map((r) => r.session_date).filter(Boolean);
706
- } catch {
707
- const allSessions = listSessionsFromFilesystem(project);
708
- const dates = /* @__PURE__ */ new Set();
709
- for (const s of allSessions) {
710
- dates.add(s.created.slice(0, 10));
711
- }
712
- return [...dates].sort().reverse();
513
+ function cachePut(id, project, session) {
514
+ const key = cacheKey(id, project);
515
+ const existingSize = sessionCacheSizes.get(key) ?? 0;
516
+ sessionCache.delete(key);
517
+ sessionCacheSizes.delete(key);
518
+ sessionCacheBytes -= existingSize;
519
+ const newSize = estimateSessionBytes(session);
520
+ while ((sessionCache.size >= SESSION_CACHE_MAX || sessionCacheBytes + newSize > SESSION_CACHE_MAX_BYTES) && sessionCache.size > 0) {
521
+ const oldest = sessionCache.keys().next().value;
522
+ if (oldest === void 0)
523
+ break;
524
+ const evictedSize = sessionCacheSizes.get(oldest) ?? 0;
525
+ sessionCache.delete(oldest);
526
+ sessionCacheSizes.delete(oldest);
527
+ sessionCacheBytes -= evictedSize;
713
528
  }
529
+ sessionCache.set(key, session);
530
+ sessionCacheSizes.set(key, newSize);
531
+ sessionCacheBytes += newSize;
714
532
  }
715
- function listSessionProjects() {
716
- try {
717
- const db = getAgentDb();
718
- const rows = db.prepare(`SELECT project, COUNT(*) as count, MAX(updated_at) as last_active
719
- FROM sessions
720
- GROUP BY project
721
- ORDER BY last_active DESC`).all();
722
- return rows.map((r) => ({
723
- project: r.project,
724
- sessionCount: r.count,
725
- lastActive: new Date(r.last_active).toISOString()
726
- }));
727
- } catch {
728
- return [];
729
- }
533
+ function cacheInvalidate(id, project) {
534
+ const key = cacheKey(id, project);
535
+ const size = sessionCacheSizes.get(key) ?? 0;
536
+ sessionCache.delete(key);
537
+ sessionCacheSizes.delete(key);
538
+ sessionCacheBytes -= size;
539
+ }
540
+ function _resetSessionCache() {
541
+ sessionCache.clear();
542
+ sessionCacheSizes.clear();
543
+ sessionCacheBytes = 0;
730
544
  }
545
+ var SESSION_CACHE_MAX, SESSION_CACHE_MAX_BYTES, sessionCache, sessionCacheSizes, sessionCacheBytes;
546
+ var init_session_store_cache = __esm({
547
+ "../chitragupta/packages/smriti/dist/session-store-cache.js"() {
548
+ "use strict";
549
+ SESSION_CACHE_MAX = 500;
550
+ SESSION_CACHE_MAX_BYTES = 25 * 1024 * 1024;
551
+ sessionCache = /* @__PURE__ */ new Map();
552
+ sessionCacheSizes = /* @__PURE__ */ new Map();
553
+ sessionCacheBytes = 0;
554
+ }
555
+ });
556
+
557
+ // ../chitragupta/packages/smriti/dist/session-queries.js
558
+ import fs from "fs";
559
+ import path2 from "path";
731
560
  function listSessionsFromFilesystem(project) {
732
561
  const sessionsRoot = getSessionsRoot();
733
562
  if (!fs.existsSync(sessionsRoot))
@@ -742,7 +571,7 @@ function listSessionsFromFilesystem(project) {
742
571
  const projectDirs = fs.readdirSync(sessionsRoot, { withFileTypes: true });
743
572
  for (const entry of projectDirs) {
744
573
  if (entry.isDirectory()) {
745
- results.push(...scanDirRecursive(path.join(sessionsRoot, entry.name)));
574
+ results.push(...scanDirRecursive(path2.join(sessionsRoot, entry.name)));
746
575
  }
747
576
  }
748
577
  }
@@ -754,7 +583,7 @@ function scanDirRecursive(dir) {
754
583
  try {
755
584
  const entries = fs.readdirSync(dir, { withFileTypes: true });
756
585
  for (const entry of entries) {
757
- const fullPath = path.join(dir, entry.name);
586
+ const fullPath = path2.join(dir, entry.name);
758
587
  if (entry.isDirectory()) {
759
588
  metas.push(...scanDirRecursive(fullPath));
760
589
  } else if (entry.name.endsWith(".md")) {
@@ -762,85 +591,109 @@ function scanDirRecursive(dir) {
762
591
  const content = fs.readFileSync(fullPath, "utf-8");
763
592
  const session = parseSessionMarkdown(content);
764
593
  metas.push(session.meta);
765
- } catch {
594
+ } catch (err) {
595
+ process.stderr.write(`[smriti:session-queries] skip unparseable file ${fullPath}: ${err instanceof Error ? err.message : String(err)}
596
+ `);
766
597
  }
767
598
  }
768
599
  }
769
- } catch {
600
+ } catch (err) {
601
+ process.stderr.write(`[smriti:session-queries] directory scan failed for ${dir}: ${err instanceof Error ? err.message : String(err)}
602
+ `);
770
603
  }
771
604
  return metas;
772
605
  }
773
- function deleteSession(id, project) {
774
- const filePath = resolveSessionPath(id, project);
775
- if (!fs.existsSync(filePath)) {
776
- throw new SessionError(`Session not found: ${id} (project: ${project})`);
777
- }
778
- fs.unlinkSync(filePath);
779
- cacheInvalidate(id, project);
780
- let dir = path.dirname(filePath);
781
- const sessionsRoot = getSessionsRoot();
782
- while (dir !== sessionsRoot && dir.length > sessionsRoot.length) {
783
- try {
784
- const remaining = fs.readdirSync(dir);
785
- if (remaining.length === 0) {
786
- fs.rmdirSync(dir);
787
- dir = path.dirname(dir);
788
- } else {
789
- break;
790
- }
791
- } catch {
792
- break;
793
- }
794
- }
606
+ function listSessions(project) {
795
607
  try {
796
608
  const db = getAgentDb();
797
- const turns = db.prepare("SELECT id FROM turns WHERE session_id = ?").all(id);
798
- for (const t of turns) {
799
- db.prepare("DELETE FROM turns_fts WHERE rowid = ?").run(t.id);
609
+ let rows;
610
+ if (project) {
611
+ rows = db.prepare("SELECT * FROM sessions WHERE project = ? ORDER BY updated_at DESC").all(project);
612
+ } else {
613
+ rows = db.prepare("SELECT * FROM sessions ORDER BY updated_at DESC").all();
800
614
  }
801
- db.prepare("DELETE FROM turns WHERE session_id = ?").run(id);
802
- db.prepare("DELETE FROM sessions WHERE id = ?").run(id);
803
- } catch {
615
+ if (rows.length > 0) {
616
+ return rows.map(rowToSessionMeta);
617
+ }
618
+ } catch (err) {
619
+ process.stderr.write(`[chitragupta] listSessions SQLite failed, falling back to filesystem: ${err instanceof Error ? err.message : err}
620
+ `);
804
621
  }
622
+ return listSessionsFromFilesystem(project);
805
623
  }
806
- var sessionWriteQueues = /* @__PURE__ */ new Map();
807
- function addTurn(sessionId, project, turn) {
808
- const key = `${sessionId}:${project}`;
809
- const prev = sessionWriteQueues.get(key) ?? Promise.resolve();
810
- const next = prev.then(() => {
811
- const filePath = resolveSessionPath(sessionId, project);
812
- if (!fs.existsSync(filePath)) {
813
- throw new SessionError(`Session not found: ${sessionId} (project: ${project})`);
624
+ function listSessionsByDate(date, project) {
625
+ const dateMatch = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
626
+ if (!dateMatch) {
627
+ throw new SessionError(`Invalid date format: ${date}. Expected YYYY-MM-DD.`);
628
+ }
629
+ const startOfDay = (/* @__PURE__ */ new Date(`${date}T00:00:00.000Z`)).getTime();
630
+ const endOfDay = startOfDay + 864e5;
631
+ return listSessionsByDateRange(startOfDay, endOfDay, project);
632
+ }
633
+ function listSessionsByDateRange(startMs, endMs, project) {
634
+ try {
635
+ const db = getAgentDb();
636
+ let rows;
637
+ if (project) {
638
+ rows = db.prepare("SELECT * FROM sessions WHERE project = ? AND created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(project, startMs, endMs);
639
+ } else {
640
+ rows = db.prepare("SELECT * FROM sessions WHERE created_at >= ? AND created_at < ? ORDER BY created_at ASC").all(startMs, endMs);
814
641
  }
815
- const fileContent = fs.readFileSync(filePath, "utf-8");
816
- if (!turn.turnNumber) {
817
- try {
818
- const session = parseSessionMarkdown(fileContent);
819
- turn.turnNumber = session.turns.length + 1;
820
- } catch {
821
- turn.turnNumber = getMaxTurnNumber(sessionId) + 1;
822
- }
642
+ if (rows.length > 0) {
643
+ return rows.map(rowToSessionMeta);
823
644
  }
824
- const updatedIso = (/* @__PURE__ */ new Date()).toISOString();
825
- const patchedContent = patchFrontmatterUpdated(fileContent, updatedIso);
826
- if (patchedContent !== fileContent) {
827
- fs.writeFileSync(filePath, patchedContent, "utf-8");
645
+ } catch (err) {
646
+ process.stderr.write(`[smriti:session-queries] listSessionsByDateRange SQLite failed: ${err instanceof Error ? err.message : String(err)}
647
+ `);
648
+ }
649
+ const allSessions = listSessionsFromFilesystem(project);
650
+ return allSessions.filter((s) => {
651
+ const created = new Date(s.created).getTime();
652
+ return created >= startMs && created < endMs;
653
+ });
654
+ }
655
+ function listSessionDates(project) {
656
+ try {
657
+ const db = getAgentDb();
658
+ let rows;
659
+ if (project) {
660
+ rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
661
+ FROM sessions WHERE project = ?
662
+ ORDER BY session_date DESC`).all(project);
663
+ } else {
664
+ rows = db.prepare(`SELECT DISTINCT date(created_at / 1000, 'unixepoch') as session_date
665
+ FROM sessions
666
+ ORDER BY session_date DESC`).all();
828
667
  }
829
- const turnMd = writeTurnMarkdown(turn);
830
- fs.appendFileSync(filePath, `
831
- ${turnMd}
832
- `, "utf-8");
833
- cacheInvalidate(sessionId, project);
834
- insertTurnToDb(sessionId, turn, { project, filePath });
835
- }).catch((err) => {
836
- throw err;
837
- }).finally(() => {
838
- if (sessionWriteQueues.get(key) === next) {
839
- sessionWriteQueues.delete(key);
668
+ return rows.map((r) => r.session_date).filter(Boolean);
669
+ } catch (err) {
670
+ process.stderr.write(`[smriti:session-queries] listSessionDates SQLite failed: ${err instanceof Error ? err.message : String(err)}
671
+ `);
672
+ const allSessions = listSessionsFromFilesystem(project);
673
+ const dates = /* @__PURE__ */ new Set();
674
+ for (const s of allSessions) {
675
+ dates.add(s.created.slice(0, 10));
840
676
  }
841
- });
842
- sessionWriteQueues.set(key, next);
843
- return next;
677
+ return [...dates].sort().reverse();
678
+ }
679
+ }
680
+ function listSessionProjects() {
681
+ try {
682
+ const db = getAgentDb();
683
+ const rows = db.prepare(`SELECT project, COUNT(*) as count, MAX(updated_at) as last_active
684
+ FROM sessions
685
+ GROUP BY project
686
+ ORDER BY last_active DESC`).all();
687
+ return rows.map((r) => ({
688
+ project: r.project,
689
+ sessionCount: r.count,
690
+ lastActive: new Date(r.last_active).toISOString()
691
+ }));
692
+ } catch (err) {
693
+ process.stderr.write(`[smriti:session-queries] listSessionProjects SQLite failed: ${err instanceof Error ? err.message : String(err)}
694
+ `);
695
+ return [];
696
+ }
844
697
  }
845
698
  function listTurnsWithTimestamps(sessionId, project) {
846
699
  try {
@@ -857,17 +710,67 @@ function listTurnsWithTimestamps(sessionId, project) {
857
710
  createdAt: row.created_at
858
711
  }));
859
712
  }
860
- } catch {
713
+ } catch (err) {
714
+ process.stderr.write(`[smriti:session-queries] listTurnsWithTimestamps SQLite failed: ${err instanceof Error ? err.message : String(err)}
715
+ `);
861
716
  }
862
717
  try {
863
- const session = loadSession(sessionId, project);
718
+ const { loadSession: loadSession2 } = (init_session_store(), __toCommonJS(session_store_exports));
719
+ const session = loadSession2(sessionId, project);
864
720
  const baseTime = new Date(session.meta.created).getTime();
865
721
  return session.turns.map((turn, i) => ({
866
722
  ...turn,
867
723
  createdAt: baseTime + i * 1e3
868
724
  // 1-second spacing
869
725
  }));
870
- } catch {
726
+ } catch (err) {
727
+ process.stderr.write(`[smriti:session-queries] listTurnsWithTimestamps markdown fallback failed: ${err instanceof Error ? err.message : String(err)}
728
+ `);
729
+ return [];
730
+ }
731
+ }
732
+ function findSessionByMetadata(key, value, project) {
733
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
734
+ return void 0;
735
+ }
736
+ try {
737
+ const db = getAgentDb();
738
+ const sql = project ? "SELECT * FROM sessions WHERE project = ? AND json_extract(metadata, ?) = ? LIMIT 1" : "SELECT * FROM sessions WHERE json_extract(metadata, ?) = ? LIMIT 1";
739
+ const params = project ? [project, `$.${key}`, value] : [`$.${key}`, value];
740
+ const row = db.prepare(sql).get(...params);
741
+ return row ? rowToSessionMeta(row) : void 0;
742
+ } catch (err) {
743
+ process.stderr.write(`[smriti:session-queries] findSessionByMetadata failed: ${err instanceof Error ? err.message : String(err)}
744
+ `);
745
+ return void 0;
746
+ }
747
+ }
748
+ function getTurnsSince(sessionId, sinceTurnNumber) {
749
+ try {
750
+ const db = getAgentDb();
751
+ const rows = db.prepare("SELECT turn_number, role, content, agent, model, tool_calls FROM turns WHERE session_id = ? AND turn_number > ? ORDER BY turn_number ASC").all(sessionId, sinceTurnNumber);
752
+ return rows.map((row) => ({
753
+ turnNumber: row.turn_number,
754
+ role: row.role,
755
+ content: row.content,
756
+ agent: row.agent ?? void 0,
757
+ model: row.model ?? void 0,
758
+ toolCalls: row.tool_calls ? JSON.parse(row.tool_calls) : void 0
759
+ }));
760
+ } catch (err) {
761
+ process.stderr.write(`[smriti:session-queries] getTurnsSince SQLite failed: ${err instanceof Error ? err.message : String(err)}
762
+ `);
763
+ return [];
764
+ }
765
+ }
766
+ function getSessionsModifiedSince(project, sinceMs) {
767
+ try {
768
+ const db = getAgentDb();
769
+ const rows = db.prepare("SELECT * FROM sessions WHERE project = ? AND updated_at > ? ORDER BY updated_at ASC").all(project, sinceMs);
770
+ return rows.map(rowToSessionMeta);
771
+ } catch (err) {
772
+ process.stderr.write(`[smriti:session-queries] getSessionsModifiedSince SQLite failed: ${err instanceof Error ? err.message : String(err)}
773
+ `);
871
774
  return [];
872
775
  }
873
776
  }
@@ -897,40 +800,32 @@ function updateSessionMeta(sessionId, updates) {
897
800
  sets.push("updated_at = @updated_at");
898
801
  params.updated_at = Date.now();
899
802
  db.prepare(`UPDATE sessions SET ${sets.join(", ")} WHERE id = @id`).run(params);
900
- } catch {
901
- }
902
- }
903
- function getMaxTurnNumber(sessionId) {
904
- try {
905
- const db = getAgentDb();
906
- const row = db.prepare("SELECT MAX(turn_number) as max_turn FROM turns WHERE session_id = ?").get(sessionId);
907
- return row?.max_turn ?? 0;
908
- } catch {
909
- return 0;
803
+ } catch (err) {
804
+ process.stderr.write(`[smriti:session-queries] updateSessionMeta failed for ${sessionId}: ${err instanceof Error ? err.message : String(err)}
805
+ `);
910
806
  }
911
807
  }
912
- function findSessionByMetadata(key, value, project) {
913
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
914
- return void 0;
808
+ var init_session_queries = __esm({
809
+ "../chitragupta/packages/smriti/dist/session-queries.js"() {
810
+ "use strict";
811
+ init_dist();
812
+ init_markdown_parser();
813
+ init_session_db();
814
+ init_session_db();
915
815
  }
916
- try {
917
- const db = getAgentDb();
918
- const sql = project ? "SELECT * FROM sessions WHERE project = ? AND json_extract(metadata, ?) = ? LIMIT 1" : "SELECT * FROM sessions WHERE json_extract(metadata, ?) = ? LIMIT 1";
919
- const params = project ? [project, `$.${key}`, value] : [`$.${key}`, value];
920
- const row = db.prepare(sql).get(...params);
921
- return row ? rowToSessionMeta(row) : void 0;
922
- } catch {
923
- return void 0;
924
- }
925
- }
816
+ });
817
+
818
+ // ../chitragupta/packages/smriti/dist/session-store-migration.js
819
+ import fs2 from "fs";
820
+ import path3 from "path";
926
821
  function migrateExistingSessions(project) {
927
822
  const db = getAgentDb();
928
823
  const sessionsRoot = getSessionsRoot();
929
- if (!fs.existsSync(sessionsRoot))
824
+ if (!fs2.existsSync(sessionsRoot))
930
825
  return { migrated: 0, skipped: 0 };
931
826
  let migrated = 0;
932
827
  let skipped = 0;
933
- const dirs = project ? [getProjectSessionDir(project)] : fs.readdirSync(sessionsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path.join(sessionsRoot, e.name));
828
+ const dirs = project ? [getProjectSessionDir(project)] : fs2.readdirSync(sessionsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path3.join(sessionsRoot, e.name));
934
829
  const insertSession = db.prepare(`
935
830
  INSERT OR IGNORE INTO sessions (id, project, title, created_at, updated_at, turn_count, model, agent, cost, tokens, tags, file_path, parent_id, branch, metadata)
936
831
  VALUES (@id, @project, @title, @created_at, @updated_at, @turn_count, @model, @agent, @cost, @tokens, @tags, @file_path, @parent_id, @branch, @metadata)
@@ -942,7 +837,7 @@ function migrateExistingSessions(project) {
942
837
  const insertFts = db.prepare("INSERT INTO turns_fts (rowid, content) VALUES (?, ?)");
943
838
  const migrateFile = (mdPath, relativePath) => {
944
839
  try {
945
- const content = fs.readFileSync(mdPath, "utf-8");
840
+ const content = fs2.readFileSync(mdPath, "utf-8");
946
841
  const session = parseSessionMarkdown(content);
947
842
  const existing = db.prepare("SELECT id FROM sessions WHERE id = ?").get(session.meta.id);
948
843
  if (existing) {
@@ -965,7 +860,7 @@ function migrateExistingSessions(project) {
965
860
  };
966
861
  const runMigration = db.transaction(() => {
967
862
  for (const dir of dirs) {
968
- if (!fs.existsSync(dir))
863
+ if (!fs2.existsSync(dir))
969
864
  continue;
970
865
  walkMdFiles(dir, sessionsRoot, migrateFile);
971
866
  }
@@ -975,41 +870,305 @@ function migrateExistingSessions(project) {
975
870
  }
976
871
  function walkMdFiles(dir, sessionsRoot, callback) {
977
872
  try {
978
- const entries = fs.readdirSync(dir, { withFileTypes: true });
873
+ const entries = fs2.readdirSync(dir, { withFileTypes: true });
979
874
  for (const entry of entries) {
980
- const fullPath = path.join(dir, entry.name);
875
+ const fullPath = path3.join(dir, entry.name);
981
876
  if (entry.isDirectory()) {
982
877
  walkMdFiles(fullPath, sessionsRoot, callback);
983
878
  } else if (entry.name.endsWith(".md")) {
984
- const relativePath = path.relative(path.dirname(sessionsRoot), fullPath);
879
+ const relativePath = path3.relative(path3.dirname(sessionsRoot), fullPath);
985
880
  callback(fullPath, relativePath);
986
881
  }
987
882
  }
988
883
  } catch {
989
884
  }
990
885
  }
886
+ var init_session_store_migration = __esm({
887
+ "../chitragupta/packages/smriti/dist/session-store-migration.js"() {
888
+ "use strict";
889
+ init_markdown_parser();
890
+ init_session_db();
891
+ }
892
+ });
893
+
894
+ // ../chitragupta/packages/smriti/dist/session-store.js
895
+ var session_store_exports = {};
896
+ __export(session_store_exports, {
897
+ _getDbStatus: () => _getDbStatus,
898
+ _resetDbInit: () => _resetDbInit,
899
+ _resetSessionCache: () => _resetSessionCache,
900
+ addTurn: () => addTurn,
901
+ createSession: () => createSession,
902
+ deleteSession: () => deleteSession,
903
+ findSessionByMetadata: () => findSessionByMetadata,
904
+ getMaxTurnNumber: () => getMaxTurnNumber,
905
+ getSessionsModifiedSince: () => getSessionsModifiedSince,
906
+ getTurnsSince: () => getTurnsSince,
907
+ listSessionDates: () => listSessionDates,
908
+ listSessionProjects: () => listSessionProjects,
909
+ listSessions: () => listSessions,
910
+ listSessionsByDate: () => listSessionsByDate,
911
+ listSessionsByDateRange: () => listSessionsByDateRange,
912
+ listTurnsWithTimestamps: () => listTurnsWithTimestamps,
913
+ loadSession: () => loadSession,
914
+ migrateExistingSessions: () => migrateExistingSessions,
915
+ saveSession: () => saveSession,
916
+ updateSessionMeta: () => updateSessionMeta
917
+ });
918
+ import fs3 from "fs";
919
+ import { renameSync as nodeRenameSync } from "node:fs";
920
+ import path4 from "path";
921
+ function atomicRename(tmpPath, targetPath) {
922
+ try {
923
+ nodeRenameSync(tmpPath, targetPath);
924
+ } catch (err) {
925
+ if (!process.env.VITEST) {
926
+ process.stderr.write(`[smriti:session-store] atomic rename failed, using direct write: ${err instanceof Error ? err.message : String(err)}
927
+ `);
928
+ }
929
+ fs3.writeFileSync(targetPath, fs3.readFileSync(tmpPath, "utf-8"), "utf-8");
930
+ try {
931
+ fs3.unlinkSync(tmpPath);
932
+ } catch {
933
+ }
934
+ }
935
+ }
936
+ function generateSessionId(project) {
937
+ const now = /* @__PURE__ */ new Date();
938
+ const yyyy = now.getFullYear().toString();
939
+ const mm = (now.getMonth() + 1).toString().padStart(2, "0");
940
+ const dd = now.getDate().toString().padStart(2, "0");
941
+ const dateStr = `${yyyy}-${mm}-${dd}`;
942
+ const projHash = hashProject(project).slice(0, 8);
943
+ const baseId = `session-${dateStr}-${projHash}`;
944
+ const projectDir = getProjectSessionDir(project);
945
+ const yearMonthDir = path4.join(projectDir, yyyy, mm);
946
+ fs3.mkdirSync(yearMonthDir, { recursive: true });
947
+ const basePath = path4.join(yearMonthDir, `${baseId}.md`);
948
+ if (!fs3.existsSync(basePath)) {
949
+ return {
950
+ id: baseId,
951
+ filePath: path4.join("sessions", hashProject(project), yyyy, mm, `${baseId}.md`)
952
+ };
953
+ }
954
+ let counter = 2;
955
+ while (fs3.existsSync(path4.join(yearMonthDir, `${baseId}-${counter}.md`))) {
956
+ counter++;
957
+ }
958
+ const id = `${baseId}-${counter}`;
959
+ return {
960
+ id,
961
+ filePath: path4.join("sessions", hashProject(project), yyyy, mm, `${id}.md`)
962
+ };
963
+ }
964
+ function resolveSessionPath(id, project) {
965
+ const projectDir = getProjectSessionDir(project);
966
+ const dateMatch = id.match(/^session-(\d{4})-(\d{2})-\d{2}/);
967
+ if (dateMatch) {
968
+ const newPath = path4.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
969
+ if (fs3.existsSync(newPath))
970
+ return newPath;
971
+ }
972
+ const oldPath = path4.join(projectDir, `${id}.md`);
973
+ if (fs3.existsSync(oldPath))
974
+ return oldPath;
975
+ if (dateMatch) {
976
+ return path4.join(projectDir, dateMatch[1], dateMatch[2], `${id}.md`);
977
+ }
978
+ return oldPath;
979
+ }
980
+ function patchFrontmatterUpdated(content, updatedIso) {
981
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
982
+ if (!fmMatch)
983
+ return content;
984
+ const frontmatter = fmMatch[1];
985
+ if (!/^updated:\s/m.test(frontmatter))
986
+ return content;
987
+ const patchedFrontmatter = frontmatter.replace(/^updated:\s.*$/m, `updated: ${updatedIso}`);
988
+ if (patchedFrontmatter === frontmatter)
989
+ return content;
990
+ return `---
991
+ ${patchedFrontmatter}
992
+ ---${content.slice(fmMatch[0].length)}`;
993
+ }
994
+ function createSession(opts) {
995
+ const now = (/* @__PURE__ */ new Date()).toISOString();
996
+ const { id, filePath } = generateSessionId(opts.project);
997
+ const meta = {
998
+ id,
999
+ title: opts.title ?? "New Session",
1000
+ created: now,
1001
+ updated: now,
1002
+ agent: opts.agent ?? "chitragupta",
1003
+ model: opts.model ?? "unknown",
1004
+ provider: opts.provider,
1005
+ project: opts.project,
1006
+ parent: opts.parentSessionId ?? null,
1007
+ branch: opts.branch ?? null,
1008
+ tags: opts.tags ?? [],
1009
+ totalCost: 0,
1010
+ totalTokens: 0,
1011
+ metadata: opts.metadata
1012
+ };
1013
+ if (opts.provider) {
1014
+ meta.metadata = { ...meta.metadata, provider: opts.provider };
1015
+ }
1016
+ const session = { meta, turns: [] };
1017
+ saveSession(session);
1018
+ upsertSessionToDb(meta, filePath);
1019
+ return session;
1020
+ }
1021
+ function saveSession(session) {
1022
+ const filePath = resolveSessionPath(session.meta.id, session.meta.project);
1023
+ const dir = path4.dirname(filePath);
1024
+ try {
1025
+ fs3.mkdirSync(dir, { recursive: true });
1026
+ session.meta.updated = (/* @__PURE__ */ new Date()).toISOString();
1027
+ const markdown = writeSessionMarkdown(session);
1028
+ const tmpPath = `${filePath}.tmp.${process.pid}`;
1029
+ fs3.writeFileSync(tmpPath, markdown, "utf-8");
1030
+ atomicRename(tmpPath, filePath);
1031
+ cachePut(session.meta.id, session.meta.project, session);
1032
+ } catch (err) {
1033
+ throw new SessionError(`Failed to save session ${session.meta.id} at ${filePath}: ${err.message}`);
1034
+ }
1035
+ }
1036
+ function loadSession(id, project) {
1037
+ const cached = cacheGet(id, project);
1038
+ if (cached)
1039
+ return cached;
1040
+ const filePath = resolveSessionPath(id, project);
1041
+ if (!fs3.existsSync(filePath)) {
1042
+ throw new SessionError(`Session not found: ${id} (project: ${project})`);
1043
+ }
1044
+ try {
1045
+ const content = fs3.readFileSync(filePath, "utf-8");
1046
+ const session = parseSessionMarkdown(content);
1047
+ cachePut(id, project, session);
1048
+ return session;
1049
+ } catch (err) {
1050
+ if (err instanceof SessionError)
1051
+ throw err;
1052
+ throw new SessionError(`Failed to load session ${id}: ${err.message}`);
1053
+ }
1054
+ }
1055
+ function deleteSession(id, project) {
1056
+ const filePath = resolveSessionPath(id, project);
1057
+ if (!fs3.existsSync(filePath)) {
1058
+ throw new SessionError(`Session not found: ${id} (project: ${project})`);
1059
+ }
1060
+ fs3.unlinkSync(filePath);
1061
+ cacheInvalidate(id, project);
1062
+ let dir = path4.dirname(filePath);
1063
+ const sessionsRoot = getSessionsRoot();
1064
+ while (dir !== sessionsRoot && dir.length > sessionsRoot.length) {
1065
+ try {
1066
+ const remaining = fs3.readdirSync(dir);
1067
+ if (remaining.length === 0) {
1068
+ fs3.rmdirSync(dir);
1069
+ dir = path4.dirname(dir);
1070
+ } else {
1071
+ break;
1072
+ }
1073
+ } catch {
1074
+ break;
1075
+ }
1076
+ }
1077
+ try {
1078
+ const db = getAgentDb();
1079
+ const turns = db.prepare("SELECT id FROM turns WHERE session_id = ?").all(id);
1080
+ for (const t of turns) {
1081
+ db.prepare("DELETE FROM turns_fts WHERE rowid = ?").run(t.id);
1082
+ }
1083
+ db.prepare("DELETE FROM turns WHERE session_id = ?").run(id);
1084
+ db.prepare("DELETE FROM sessions WHERE id = ?").run(id);
1085
+ } catch (err) {
1086
+ process.stderr.write(`[smriti:session-store] deleteSession SQLite cleanup failed for ${id}: ${err instanceof Error ? err.message : String(err)}
1087
+ `);
1088
+ }
1089
+ }
1090
+ function addTurn(sessionId, project, turn) {
1091
+ const key = `${sessionId}:${project}`;
1092
+ const prev = sessionWriteQueues.get(key) ?? Promise.resolve();
1093
+ const next = prev.then(() => {
1094
+ const filePath = resolveSessionPath(sessionId, project);
1095
+ if (!fs3.existsSync(filePath)) {
1096
+ throw new SessionError(`Session not found: ${sessionId} (project: ${project})`);
1097
+ }
1098
+ const fileContent = fs3.readFileSync(filePath, "utf-8");
1099
+ if (!turn.turnNumber) {
1100
+ try {
1101
+ const session = parseSessionMarkdown(fileContent);
1102
+ turn.turnNumber = session.turns.length + 1;
1103
+ } catch {
1104
+ turn.turnNumber = getMaxTurnNumber(sessionId) + 1;
1105
+ }
1106
+ }
1107
+ const updatedIso = (/* @__PURE__ */ new Date()).toISOString();
1108
+ const patchedContent = patchFrontmatterUpdated(fileContent, updatedIso);
1109
+ if (patchedContent !== fileContent) {
1110
+ fs3.writeFileSync(filePath, patchedContent, "utf-8");
1111
+ }
1112
+ const turnMd = writeTurnMarkdown(turn);
1113
+ fs3.appendFileSync(filePath, `
1114
+ ${turnMd}
1115
+ `, "utf-8");
1116
+ cacheInvalidate(sessionId, project);
1117
+ insertTurnToDb(sessionId, turn, { project, filePath });
1118
+ }).catch((err) => {
1119
+ throw err;
1120
+ }).finally(() => {
1121
+ if (sessionWriteQueues.get(key) === next) {
1122
+ sessionWriteQueues.delete(key);
1123
+ }
1124
+ });
1125
+ sessionWriteQueues.set(key, next);
1126
+ return next;
1127
+ }
1128
+ var sessionWriteQueues;
1129
+ var init_session_store = __esm({
1130
+ "../chitragupta/packages/smriti/dist/session-store.js"() {
1131
+ init_dist();
1132
+ init_markdown_parser();
1133
+ init_markdown_writer();
1134
+ init_session_db();
1135
+ init_session_store_cache();
1136
+ init_session_store_cache();
1137
+ init_session_db();
1138
+ init_session_queries();
1139
+ init_session_store_migration();
1140
+ sessionWriteQueues = /* @__PURE__ */ new Map();
1141
+ }
1142
+ });
991
1143
 
992
1144
  export {
993
1145
  parseSessionMarkdown,
1146
+ init_markdown_parser,
994
1147
  writeSessionMarkdown,
995
1148
  writeTurnMarkdown,
996
- _resetSessionCache,
1149
+ init_markdown_writer,
1150
+ getAgentDb,
997
1151
  _resetDbInit,
998
1152
  _getDbStatus,
999
- createSession,
1000
- saveSession,
1001
- loadSession,
1153
+ getMaxTurnNumber,
1154
+ init_session_db,
1155
+ _resetSessionCache,
1002
1156
  listSessions,
1003
1157
  listSessionsByDate,
1004
1158
  listSessionsByDateRange,
1005
1159
  listSessionDates,
1006
1160
  listSessionProjects,
1007
- deleteSession,
1008
- addTurn,
1009
1161
  listTurnsWithTimestamps,
1010
- updateSessionMeta,
1011
- getMaxTurnNumber,
1012
1162
  findSessionByMetadata,
1013
- migrateExistingSessions
1163
+ getTurnsSince,
1164
+ getSessionsModifiedSince,
1165
+ updateSessionMeta,
1166
+ migrateExistingSessions,
1167
+ createSession,
1168
+ saveSession,
1169
+ loadSession,
1170
+ deleteSession,
1171
+ addTurn,
1172
+ init_session_store
1014
1173
  };
1015
- //# sourceMappingURL=chunk-ZYY6N3SP.js.map
1174
+ //# sourceMappingURL=chunk-FEDPZOZ5.js.map