the-campfire 0.3.0 → 0.3.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "the-campfire",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Campfire \u2014 collaborative web platform for AI coding agents. Run Claude Code, Codex, Goose, Aider, and more from one browser UI with real-time collaboration, permission voting, and automation.",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  import type { BrowserIncomingMessage, BrowserOutgoingMessage, BackendType } from "./session-types.js";
27
- import { storeFragment, queryFragments, queryForEnrichment } from "./semantic-memory.js";
27
+ import { storeFragment, queryFragments, queryForEnrichment, warmMemory } from "./semantic-memory.js";
28
28
  import type { GitContext, MemoryType, EnrichmentResult } from "./semantic-memory.js";
29
29
  import { consolidate } from "./memory-consolidation.js";
30
30
  import { deliberationEngine } from "./deliberation-engine.js";
@@ -355,6 +355,15 @@ export class CollectiveIntelligenceLayer {
355
355
  });
356
356
  }
357
357
 
358
+ /**
359
+ * Fire-and-forget: open the memory store's tables when a session becomes
360
+ * ready so the session's first user message enriches within budget. Called
361
+ * from WsBridge on session init; never awaited, never throws.
362
+ */
363
+ warmForSession(repoRoot: string, backendType: BackendType): void {
364
+ void warmMemory({ repoRoot, backendType }).catch(() => { /* best-effort */ });
365
+ }
366
+
358
367
  // ─── Session lifecycle ────────────────────────────────────────────────────
359
368
 
360
369
  /**
@@ -1254,6 +1254,28 @@ export interface NamespaceOverviewEntry {
1254
1254
  * Per-namespace fragment stats for the memory panel: count, average decayed
1255
1255
  * weight, and pinned count, over [session:<id>, repo:<hash>, agent:<backend>, global].
1256
1256
  */
1257
+ /**
1258
+ * Open the LanceDB connection and the tables a subsequent enrichment query
1259
+ * will touch, so the first real `queryForEnrichment` for a session lands
1260
+ * within the 250 ms budget instead of paying the cold connect+open cost
1261
+ * (~230 ms on a fresh process) and getting skipped. Best-effort and
1262
+ * reinforcement-free — it must never throw into session startup, and it must
1263
+ * not touch access counts (it is not a real recall).
1264
+ */
1265
+ export async function warmMemory(opts: { repoRoot: string; backendType: string }): Promise<void> {
1266
+ try {
1267
+ const ns = opts.repoRoot ? repoNamespace(opts.repoRoot) : "global";
1268
+ // getNamespaceOverview opens the fragments table + connection;
1269
+ // getKnowledgeByNamespace opens the consolidated table. Neither reinforces.
1270
+ await Promise.all([
1271
+ getNamespaceOverview({ sessionId: "warm", repoRoot: opts.repoRoot, backendType: opts.backendType }),
1272
+ getKnowledgeByNamespace(ns),
1273
+ ]);
1274
+ } catch {
1275
+ // Warming is an optimization; a cold first query still works, just slower.
1276
+ }
1277
+ }
1278
+
1257
1279
  export async function getNamespaceOverview(opts: {
1258
1280
  sessionId: string;
1259
1281
  repoRoot: string;
@@ -1038,6 +1038,7 @@ export class WsBridge {
1038
1038
  this.persistSession(session);
1039
1039
  this.injectDetectedEnvironmentMcp(session);
1040
1040
  this.agentMcpBridge?.onSessionReady(session.id, backendType, session.state.cwd);
1041
+ this.collectiveIntelligence?.warmForSession(session.state.repo_root || session.state.cwd || "", backendType);
1041
1042
  } else if (msg.type === "session_update") {
1042
1043
  session.state = { ...session.state, ...msg.session, backend_type: backendType };
1043
1044
  this.refreshGitInfo(session, { notifyPoller: true });
@@ -1382,6 +1383,7 @@ export class WsBridge {
1382
1383
  this.persistSession(session);
1383
1384
  this.injectDetectedEnvironmentMcp(session);
1384
1385
  this.agentMcpBridge?.onSessionReady(session.id, session.backendType, session.state.cwd);
1386
+ this.collectiveIntelligence?.warmForSession(session.state.repo_root || session.state.cwd || "", session.backendType);
1385
1387
  } else if (msg.subtype === "status") {
1386
1388
  session.state.is_compacting = msg.status === "compacting";
1387
1389