context-mode 1.0.99 → 1.0.101

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 (65) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  4. package/.openclaw-plugin/package.json +1 -1
  5. package/README.md +22 -8
  6. package/build/adapters/claude-code/hooks.d.ts +4 -2
  7. package/build/adapters/claude-code/hooks.js +11 -4
  8. package/build/adapters/codex/index.d.ts +1 -1
  9. package/build/adapters/codex/index.js +6 -5
  10. package/build/adapters/gemini-cli/hooks.js +2 -1
  11. package/build/adapters/jetbrains-copilot/hooks.js +2 -1
  12. package/build/adapters/kiro/hooks.js +2 -1
  13. package/build/adapters/qwen-code/index.d.ts +1 -1
  14. package/build/adapters/qwen-code/index.js +13 -10
  15. package/build/adapters/types.d.ts +13 -0
  16. package/build/adapters/types.js +23 -1
  17. package/build/adapters/vscode-copilot/hooks.js +2 -1
  18. package/build/openclaw-plugin.js +3 -2
  19. package/build/pi-extension.js +1 -1
  20. package/build/search/auto-memory.d.ts +29 -0
  21. package/build/search/auto-memory.js +121 -0
  22. package/build/search/unified.d.ts +41 -0
  23. package/build/search/unified.js +89 -0
  24. package/build/server.js +73 -24
  25. package/build/session/analytics.js +1 -1
  26. package/build/session/db.d.ts +17 -0
  27. package/build/session/db.js +28 -0
  28. package/build/session/extract.d.ts +4 -0
  29. package/build/session/extract.js +232 -1
  30. package/build/session/snapshot.js +31 -0
  31. package/build/store.js +67 -4
  32. package/build/types.d.ts +1 -0
  33. package/cli.bundle.mjs +254 -119
  34. package/configs/claude-code/CLAUDE.md +21 -1
  35. package/configs/codex/AGENTS.md +22 -1
  36. package/configs/cursor/context-mode.mdc +18 -1
  37. package/configs/gemini-cli/GEMINI.md +22 -1
  38. package/configs/jetbrains-copilot/copilot-instructions.md +22 -1
  39. package/configs/kilo/AGENTS.md +19 -2
  40. package/configs/kiro/KIRO.md +18 -1
  41. package/configs/openclaw/AGENTS.md +22 -2
  42. package/configs/opencode/AGENTS.md +18 -1
  43. package/configs/pi/AGENTS.md +18 -1
  44. package/configs/qwen-code/QWEN.md +38 -18
  45. package/configs/vscode-copilot/copilot-instructions.md +22 -1
  46. package/hooks/auto-injection.mjs +76 -0
  47. package/hooks/codex/userpromptsubmit.mjs +1 -1
  48. package/hooks/core/mcp-ready.mjs +7 -1
  49. package/hooks/ensure-deps.mjs +35 -7
  50. package/hooks/posttooluse.mjs +50 -1
  51. package/hooks/precompact.mjs +9 -0
  52. package/hooks/pretooluse.mjs +27 -0
  53. package/hooks/routing-block.mjs +7 -1
  54. package/hooks/session-db.bundle.mjs +19 -13
  55. package/hooks/session-extract.bundle.mjs +2 -2
  56. package/hooks/session-snapshot.bundle.mjs +18 -17
  57. package/hooks/sessionstart.mjs +17 -0
  58. package/hooks/userpromptsubmit.mjs +1 -1
  59. package/insight/server.mjs +379 -1
  60. package/insight/src/lib/api.ts +88 -16
  61. package/insight/src/routes/index.tsx +566 -5
  62. package/openclaw.plugin.json +1 -1
  63. package/package.json +1 -1
  64. package/server.bundle.mjs +222 -87
  65. package/start.mjs +3 -1
@@ -312,6 +312,30 @@ function buildSkillsSection(skillEvents, searchTool) {
312
312
  ];
313
313
  return lines.join("\n");
314
314
  }
315
+ function buildRolesSection(roleEvents, searchTool) {
316
+ if (roleEvents.length === 0)
317
+ return "";
318
+ const seen = new Set();
319
+ const summaryLines = [];
320
+ const queryTerms = [];
321
+ for (const ev of roleEvents) {
322
+ if (seen.has(ev.data))
323
+ continue;
324
+ seen.add(ev.data);
325
+ summaryLines.push(` ${escapeXML(ev.data)}`);
326
+ queryTerms.push(ev.data);
327
+ }
328
+ if (summaryLines.length === 0)
329
+ return "";
330
+ const queries = buildQueries(queryTerms);
331
+ const lines = [
332
+ ` <roles count="${summaryLines.length}">`,
333
+ ...summaryLines,
334
+ toolCall(searchTool, queries),
335
+ ` </roles>`,
336
+ ];
337
+ return lines.join("\n");
338
+ }
315
339
  function buildIntentSection(intentEvents) {
316
340
  if (intentEvents.length === 0)
317
341
  return "";
@@ -344,6 +368,7 @@ export function buildResumeSnapshot(events, opts) {
344
368
  const subagentEvents = [];
345
369
  const intentEvents = [];
346
370
  const skillEvents = [];
371
+ const roleEvents = [];
347
372
  for (const ev of events) {
348
373
  switch (ev.category) {
349
374
  case "file":
@@ -379,6 +404,9 @@ export function buildResumeSnapshot(events, opts) {
379
404
  case "skill":
380
405
  skillEvents.push(ev);
381
406
  break;
407
+ case "role":
408
+ roleEvents.push(ev);
409
+ break;
382
410
  }
383
411
  }
384
412
  // ── Build all sections ──
@@ -417,6 +445,9 @@ export function buildResumeSnapshot(events, opts) {
417
445
  const skills = buildSkillsSection(skillEvents, searchTool);
418
446
  if (skills)
419
447
  sections.push(skills);
448
+ const roles = buildRolesSection(roleEvents, searchTool);
449
+ if (roles)
450
+ sections.push(roles);
420
451
  const intent = buildIntentSection(intentEvents);
421
452
  if (intent)
422
453
  sections.push(intent);
package/build/store.js CHANGED
@@ -402,6 +402,10 @@ export class ContentStore {
402
402
  content,
403
403
  source_id UNINDEXED,
404
404
  content_type UNINDEXED,
405
+ source_category UNINDEXED,
406
+ session_id UNINDEXED,
407
+ event_id UNINDEXED,
408
+ timestamp UNINDEXED,
405
409
  tokenize='porter unicode61'
406
410
  );
407
411
 
@@ -410,6 +414,10 @@ export class ContentStore {
410
414
  content,
411
415
  source_id UNINDEXED,
412
416
  content_type UNINDEXED,
417
+ source_category UNINDEXED,
418
+ session_id UNINDEXED,
419
+ event_id UNINDEXED,
420
+ timestamp UNINDEXED,
413
421
  tokenize='trigram'
414
422
  );
415
423
 
@@ -419,6 +427,47 @@ export class ContentStore {
419
427
 
420
428
  CREATE INDEX IF NOT EXISTS idx_sources_label ON sources(label);
421
429
  `);
430
+ // FTS5 schema migration: old schema (4 cols) → new schema (8 cols).
431
+ // FTS5 virtual tables do not support ALTER TABLE ADD COLUMN, so we must
432
+ // DROP + re-CREATE. Detection: check for sentinel column `source_category`
433
+ // via pragma_table_xinfo. Three states:
434
+ // 1. No table → CREATE above handled it (fresh DB)
435
+ // 2. Old schema (4 cols) → DROP + CREATE new
436
+ // 3. New schema (8 cols) → do nothing
437
+ try {
438
+ const cols = this.#db.prepare("SELECT name FROM pragma_table_xinfo('chunks')").all();
439
+ const colNames = new Set(cols.map(c => c.name));
440
+ if (cols.length > 0 && !colNames.has("source_category")) {
441
+ // Old schema detected — drop both FTS5 tables and re-create with new columns
442
+ this.#db.exec("DROP TABLE IF EXISTS chunks");
443
+ this.#db.exec("DROP TABLE IF EXISTS chunks_trigram");
444
+ this.#db.exec(`
445
+ CREATE VIRTUAL TABLE chunks USING fts5(
446
+ title,
447
+ content,
448
+ source_id UNINDEXED,
449
+ content_type UNINDEXED,
450
+ source_category UNINDEXED,
451
+ session_id UNINDEXED,
452
+ event_id UNINDEXED,
453
+ timestamp UNINDEXED,
454
+ tokenize='porter unicode61'
455
+ );
456
+ CREATE VIRTUAL TABLE chunks_trigram USING fts5(
457
+ title,
458
+ content,
459
+ source_id UNINDEXED,
460
+ content_type UNINDEXED,
461
+ source_category UNINDEXED,
462
+ session_id UNINDEXED,
463
+ event_id UNINDEXED,
464
+ timestamp UNINDEXED,
465
+ tokenize='trigram'
466
+ );
467
+ `);
468
+ }
469
+ }
470
+ catch { /* pragma_table_xinfo may fail if table doesn't exist yet — safe to ignore */ }
422
471
  // Stale detection columns — safe for existing DBs (ALTER is O(1) in SQLite)
423
472
  try {
424
473
  this.#db.exec("ALTER TABLE sources ADD COLUMN file_path TEXT");
@@ -433,8 +482,8 @@ export class ContentStore {
433
482
  // Write path
434
483
  this.#stmtInsertSourceEmpty = this.#db.prepare("INSERT INTO sources (label, chunk_count, code_chunk_count, file_path, content_hash) VALUES (?, 0, 0, ?, ?)");
435
484
  this.#stmtInsertSource = this.#db.prepare("INSERT INTO sources (label, chunk_count, code_chunk_count, file_path, content_hash) VALUES (?, ?, ?, ?, ?)");
436
- this.#stmtInsertChunk = this.#db.prepare("INSERT INTO chunks (title, content, source_id, content_type) VALUES (?, ?, ?, ?)");
437
- this.#stmtInsertChunkTrigram = this.#db.prepare("INSERT INTO chunks_trigram (title, content, source_id, content_type) VALUES (?, ?, ?, ?)");
485
+ this.#stmtInsertChunk = this.#db.prepare("INSERT INTO chunks (title, content, source_id, content_type, source_category, session_id, event_id, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
486
+ this.#stmtInsertChunkTrigram = this.#db.prepare("INSERT INTO chunks_trigram (title, content, source_id, content_type, source_category, session_id, event_id, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
438
487
  this.#stmtInsertVocab = this.#db.prepare("INSERT OR IGNORE INTO vocabulary (word) VALUES (?)");
439
488
  // Dedup path: delete previous source with same label before re-indexing
440
489
  // Prevents stale outputs from accumulating in iterative workflows (build-fix-build)
@@ -447,6 +496,7 @@ export class ContentStore {
447
496
  chunks.title,
448
497
  chunks.content,
449
498
  chunks.content_type,
499
+ chunks.timestamp,
450
500
  sources.label,
451
501
  bm25(chunks, 5.0, 1.0) AS rank,
452
502
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -461,6 +511,7 @@ export class ContentStore {
461
511
  chunks.title,
462
512
  chunks.content,
463
513
  chunks.content_type,
514
+ chunks.timestamp,
464
515
  sources.label,
465
516
  bm25(chunks, 5.0, 1.0) AS rank,
466
517
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -475,6 +526,7 @@ export class ContentStore {
475
526
  chunks.title,
476
527
  chunks.content,
477
528
  chunks.content_type,
529
+ chunks.timestamp,
478
530
  sources.label,
479
531
  bm25(chunks, 5.0, 1.0) AS rank,
480
532
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -489,6 +541,7 @@ export class ContentStore {
489
541
  chunks_trigram.title,
490
542
  chunks_trigram.content,
491
543
  chunks_trigram.content_type,
544
+ chunks_trigram.timestamp,
492
545
  sources.label,
493
546
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
494
547
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -503,6 +556,7 @@ export class ContentStore {
503
556
  chunks_trigram.title,
504
557
  chunks_trigram.content,
505
558
  chunks_trigram.content_type,
559
+ chunks_trigram.timestamp,
506
560
  sources.label,
507
561
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
508
562
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -517,6 +571,7 @@ export class ContentStore {
517
571
  chunks_trigram.title,
518
572
  chunks_trigram.content,
519
573
  chunks_trigram.content_type,
574
+ chunks_trigram.timestamp,
520
575
  sources.label,
521
576
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
522
577
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -532,6 +587,7 @@ export class ContentStore {
532
587
  chunks.title,
533
588
  chunks.content,
534
589
  chunks.content_type,
590
+ chunks.timestamp,
535
591
  sources.label,
536
592
  bm25(chunks, 5.0, 1.0) AS rank,
537
593
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -546,6 +602,7 @@ export class ContentStore {
546
602
  chunks.title,
547
603
  chunks.content,
548
604
  chunks.content_type,
605
+ chunks.timestamp,
549
606
  sources.label,
550
607
  bm25(chunks, 5.0, 1.0) AS rank,
551
608
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -560,6 +617,7 @@ export class ContentStore {
560
617
  chunks.title,
561
618
  chunks.content,
562
619
  chunks.content_type,
620
+ chunks.timestamp,
563
621
  sources.label,
564
622
  bm25(chunks, 5.0, 1.0) AS rank,
565
623
  highlight(chunks, 1, char(2), char(3)) AS highlighted
@@ -574,6 +632,7 @@ export class ContentStore {
574
632
  chunks_trigram.title,
575
633
  chunks_trigram.content,
576
634
  chunks_trigram.content_type,
635
+ chunks_trigram.timestamp,
577
636
  sources.label,
578
637
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
579
638
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -588,6 +647,7 @@ export class ContentStore {
588
647
  chunks_trigram.title,
589
648
  chunks_trigram.content,
590
649
  chunks_trigram.content_type,
650
+ chunks_trigram.timestamp,
591
651
  sources.label,
592
652
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
593
653
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -602,6 +662,7 @@ export class ContentStore {
602
662
  chunks_trigram.title,
603
663
  chunks_trigram.content,
604
664
  chunks_trigram.content_type,
665
+ chunks_trigram.timestamp,
605
666
  sources.label,
606
667
  bm25(chunks_trigram, 5.0, 1.0) AS rank,
607
668
  highlight(chunks_trigram, 1, char(2), char(3)) AS highlighted
@@ -714,10 +775,11 @@ export class ContentStore {
714
775
  }
715
776
  const info = this.#stmtInsertSource.run(label, chunks.length, codeChunks, filePath ?? null, contentHash ?? null);
716
777
  const sourceId = Number(info.lastInsertRowid);
778
+ const now = new Date().toISOString();
717
779
  for (const chunk of chunks) {
718
780
  const ct = chunk.hasCode ? "code" : "prose";
719
- this.#stmtInsertChunk.run(chunk.title, chunk.content, sourceId, ct);
720
- this.#stmtInsertChunkTrigram.run(chunk.title, chunk.content, sourceId, ct);
781
+ this.#stmtInsertChunk.run(chunk.title, chunk.content, sourceId, ct, null, null, null, now);
782
+ this.#stmtInsertChunkTrigram.run(chunk.title, chunk.content, sourceId, ct, null, null, null, now);
721
783
  }
722
784
  return sourceId;
723
785
  });
@@ -748,6 +810,7 @@ export class ContentStore {
748
810
  rank: r.rank,
749
811
  contentType: r.content_type,
750
812
  highlighted: r.highlighted,
813
+ timestamp: r.timestamp ?? undefined,
751
814
  }));
752
815
  }
753
816
  #sourceFilterParam(source, sourceMatchMode) {
package/build/types.d.ts CHANGED
@@ -74,6 +74,7 @@ export interface SearchResult {
74
74
  contentType: "code" | "prose";
75
75
  matchLayer?: "porter" | "trigram" | "fuzzy" | "rrf" | "rrf-fuzzy";
76
76
  highlighted?: string;
77
+ timestamp?: string;
77
78
  }
78
79
  /**
79
80
  * Aggregate statistics for a ContentStore instance.