memex-mvp 0.10.10 → 0.10.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/server.js +26 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memex-mvp",
3
- "version": "0.10.10",
3
+ "version": "0.10.11",
4
4
  "description": "Local-first MCP server for cross-agent AI memory. One SQLite + FTS5 corpus across Claude Code, Cowork, Cursor, Continue, Zed, Obsidian, and Telegram — passively captured, verbatim, searchable from any MCP-compatible client.",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -26,7 +26,7 @@
26
26
  "sync": "node ingest.js",
27
27
  "ingest": "node ingest.js",
28
28
  "bot": "node bot/index.js",
29
- "test": "node test/parser.test.js && node test/bot-inbox.test.js && node test/search-sort.test.js && node test/store-document.test.js && node test/cli.test.js && node test/hook.test.js && node test/telegram-html.test.js && node test/telegram-decisions.test.js && node test/telegram-pending.test.js && node test/telegram-notify.test.js && node test/notify-click-action.test.js",
29
+ "test": "node test/parser.test.js && node test/bot-inbox.test.js && node test/search-sort.test.js && node test/store-document.test.js && node test/cli.test.js && node test/hook.test.js && node test/telegram-html.test.js && node test/telegram-decisions.test.js && node test/telegram-pending.test.js && node test/telegram-notify.test.js && node test/notify-click-action.test.js && node test/inbox-watcher.test.js && node test/e2e-inbox.test.js",
30
30
  "prepublishOnly": "npm test"
31
31
  },
32
32
  "engines": {
package/server.js CHANGED
@@ -810,18 +810,23 @@ function importFile(filePath) {
810
810
  Math.floor(Date.now() / 1000),
811
811
  imported
812
812
  );
813
+ log(`imported ${imported} messages from ${basename(filePath)} (${source})`);
814
+ } else {
815
+ log(`no NEW messages from ${basename(filePath)} (all dupes)`);
816
+ }
813
817
 
814
- // Move processed file to archive
818
+ // Move processed file to archive regardless of imported count. If we only
819
+ // archive when imported>0, a fully-deduplicated snapshot stays in inbox.
820
+ // Daemon then overwrites that file periodically — and on filesystems where
821
+ // rename-over-existing only fires chokidar 'change' (not 'add'), the
822
+ // 'change' listener above re-imports, fine; but it also means a wasted
823
+ // file accumulates in inbox if for any reason the listener didn't catch.
824
+ // Archiving always keeps inbox a clean "what's new" queue.
825
+ if (source !== 'unknown') {
815
826
  const targetDir = join(ARCHIVE, source);
816
827
  mkdirSync(targetDir, { recursive: true });
817
828
  const target = join(targetDir, basename(filePath));
818
- try {
819
- renameSync(filePath, target);
820
- } catch (_) {}
821
-
822
- log(`imported ${imported} messages from ${basename(filePath)} (${source})`);
823
- } else {
824
- log(`no messages imported from ${basename(filePath)}`);
829
+ try { renameSync(filePath, target); } catch (_) {}
825
830
  }
826
831
  return imported;
827
832
  }
@@ -852,6 +857,19 @@ chokidar
852
857
  log('inbox detected (file):', basename(filePath));
853
858
  importFile(filePath);
854
859
  })
860
+ // 'change' is critical: the ingest daemon overwrites the inbox snapshot
861
+ // file every few seconds as the underlying Claude Code / Cowork JSONL
862
+ // grows (the snapshot is a full re-serialisation, not a delta append).
863
+ // Without a 'change' listener, chokidar only fires 'add' once when the
864
+ // file first appears — every subsequent overwrite is silent, the inbox
865
+ // file accumulates new content on disk but server.js never re-imports
866
+ // it. UNIQUE(source, conv, msg_id) + INSERT OR IGNORE keep repeated
867
+ // imports idempotent, so re-processing the whole file on every change
868
+ // is correct (and cheap: SQLite handles ~10k rows in tens of ms).
869
+ .on('change', (filePath) => {
870
+ log('inbox changed (file):', basename(filePath));
871
+ importFile(filePath);
872
+ })
855
873
  .on('addDir', (dirPath) => {
856
874
  // Skip the inbox itself
857
875
  if (dirPath === INBOX) return;