[object Object]

← back to Fleet Rag

fix fleet-rag indexer: point memory collector at live machine home, flush vectors.jsonl before cache read, and skip corrupt lines on load

71a926c0ea7caefbdec3b089f7b262a6c9eea453 · 2026-07-06 08:49:59 -0700 · Steve

Files touched

Diff

commit 71a926c0ea7caefbdec3b089f7b262a6c9eea453
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jul 6 08:49:59 2026 -0700

    fix fleet-rag indexer: point memory collector at live machine home, flush vectors.jsonl before cache read, and skip corrupt lines on load
---
 lib/index.js | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/lib/index.js b/lib/index.js
index c5e5de9..2cabb97 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -9,7 +9,7 @@ const { redact } = require('./redact');
 const VECTORS_PATH = path.join(__dirname, '../data/vectors.jsonl');
 const CHUNK_SIZE   = 512;
 const OVERLAP      = 50;
-const HOME         = process.env.HOME || '/Users/stevestudio2';
+const HOME         = process.env.HOME || '/Users/macstudio3';
 
 // ── helpers ──────────────────────────────────────────────────────────────────
 
@@ -105,7 +105,12 @@ function collectPm2() {
 
 function collectMemory() {
   const docs = [];
-  const memDir = path.join(HOME, '.claude/projects/-Users-stevestudio2/memory');
+  // Claude keys its per-project memory dir on the working dir with slashes → dashes.
+  // Derive it from the live HOME so this tracks the current machine instead of a
+  // hardcoded pre-migration home (was -Users-stevestudio2, which post mac2→mac3
+  // migration points at a STALE memory copy — the live memory is under the derived path).
+  const dashedHome = HOME.replace(/\//g, '-');
+  const memDir = path.join(HOME, '.claude/projects', `${dashedHome}/memory`);
   if (!fs.existsSync(memDir)) return docs;
   const files = fs.readdirSync(memDir).filter(f => f.endsWith('.md'));
   for (const f of files) {
@@ -159,6 +164,14 @@ async function buildIndex(onProgress) {
   log(`[indexer] total chunks to embed: ${all.length}`);
 
   const out = fs.createWriteStream(VECTORS_PATH);
+  // Resolve only once the file is fully flushed to disk. server.js calls
+  // refreshCache() (a synchronous read) immediately after buildIndex() returns,
+  // so returning before 'finish' can load a truncated index. Attach the error
+  // listener at creation so a mid-write error can't become an uncaught 'error'.
+  const streamDone = new Promise((resolve, reject) => {
+    out.on('finish', resolve);
+    out.on('error', reject);
+  });
   let ok = 0, fail = 0;
 
   for (let i = 0; i < all.length; i++) {
@@ -177,6 +190,7 @@ async function buildIndex(onProgress) {
   }
 
   out.end();
+  await streamDone;
   log(`[indexer] done. ok=${ok} fail=${fail} path=${VECTORS_PATH}`);
   return { ok, fail, path: VECTORS_PATH };
 }
@@ -184,7 +198,15 @@ async function buildIndex(onProgress) {
 function loadVectors() {
   if (!fs.existsSync(VECTORS_PATH)) return [];
   const lines = fs.readFileSync(VECTORS_PATH, 'utf8').split('\n').filter(Boolean);
-  return lines.map(l => JSON.parse(l));
+  // Skip (don't throw on) an unparseable line so one truncated/corrupt record can't
+  // crash server startup — refreshCache() runs at module load and would take the
+  // whole process down otherwise.
+  const records = [];
+  for (const l of lines) {
+    try { records.push(JSON.parse(l)); }
+    catch (e) { console.warn('[fleet-rag] skipping unparseable vectors.jsonl line:', e.message); }
+  }
+  return records;
 }
 
 module.exports = { buildIndex, loadVectors, VECTORS_PATH };

← b21a822 untrack vectors.jsonl build artifact (held spilled secrets)  ·  back to Fleet Rag  ·  dedup duplicate data/vectors.jsonl entry in .gitignore ec94b6c →