@sesamespace/hivemind 0.11.4 → 0.12.0

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startPipeline
3
- } from "./chunk-OB6OXLPC.js";
3
+ } from "./chunk-ZQ26EOYD.js";
4
4
 
5
5
  // packages/cli/src/commands/start.ts
6
6
  import { resolve } from "path";
@@ -66,4 +66,4 @@ Options:
66
66
  export {
67
67
  runStartCommand
68
68
  };
69
- //# sourceMappingURL=chunk-ZA4NWNS6.js.map
69
+ //# sourceMappingURL=chunk-3EB4T7D4.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Watchdog
3
- } from "./chunk-K6KL2VD6.js";
3
+ } from "./chunk-YJW6OOEJ.js";
4
4
  import {
5
5
  defaultSentinelConfig,
6
6
  loadConfig
7
- } from "./chunk-OB6OXLPC.js";
7
+ } from "./chunk-ZQ26EOYD.js";
8
8
 
9
9
  // packages/cli/src/commands/watchdog.ts
10
10
  import { resolve } from "path";
@@ -76,4 +76,4 @@ Options:
76
76
  export {
77
77
  runWatchdogCommand
78
78
  };
79
- //# sourceMappingURL=chunk-LYL5GG2F.js.map
79
+ //# sourceMappingURL=chunk-6JB4OAB6.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FleetManager
3
- } from "./chunk-K6KL2VD6.js";
3
+ } from "./chunk-YJW6OOEJ.js";
4
4
 
5
5
  // packages/cli/src/commands/fleet.ts
6
6
  function formatUptime(seconds) {
@@ -183,4 +183,4 @@ Commands:
183
183
  export {
184
184
  runFleetCommand
185
185
  };
186
- //# sourceMappingURL=chunk-4C6B2AMB.js.map
186
+ //# sourceMappingURL=chunk-G5LF3BSN.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SesameClient,
3
3
  getClaudeCodeOAuthToken
4
- } from "./chunk-OB6OXLPC.js";
4
+ } from "./chunk-ZQ26EOYD.js";
5
5
 
6
6
  // packages/cli/src/commands/init.ts
7
7
  import { resolve, dirname } from "path";
@@ -436,4 +436,4 @@ Options:
436
436
  export {
437
437
  runInitCommand
438
438
  };
439
- //# sourceMappingURL=chunk-4YXOQGQC.js.map
439
+ //# sourceMappingURL=chunk-JP3ZHMPE.js.map
@@ -7,7 +7,7 @@ import {
7
7
  SesameClient2 as SesameClient,
8
8
  WORKER_ROUTES,
9
9
  createLogger
10
- } from "./chunk-OB6OXLPC.js";
10
+ } from "./chunk-ZQ26EOYD.js";
11
11
 
12
12
  // packages/runtime/src/watchdog.ts
13
13
  import { execSync } from "child_process";
@@ -1095,4 +1095,4 @@ export {
1095
1095
  WorkerMemorySync,
1096
1096
  PrimaryMemorySync
1097
1097
  };
1098
- //# sourceMappingURL=chunk-K6KL2VD6.js.map
1098
+ //# sourceMappingURL=chunk-YJW6OOEJ.js.map
@@ -4225,12 +4225,12 @@ var LogWatcher = class extends BackgroundProcess {
4225
4225
  }
4226
4226
  savePositions() {
4227
4227
  try {
4228
- const { mkdirSync: mkdirSync15, writeFileSync: writeFileSync9 } = __require("fs");
4229
- const { dirname: dirname9 } = __require("path");
4230
- const dir = dirname9(this.positionsFile);
4231
- if (!existsSync7(dir)) mkdirSync15(dir, { recursive: true });
4228
+ const { mkdirSync: mkdirSync16, writeFileSync: writeFileSync10 } = __require("fs");
4229
+ const { dirname: dirname10 } = __require("path");
4230
+ const dir = dirname10(this.positionsFile);
4231
+ if (!existsSync7(dir)) mkdirSync16(dir, { recursive: true });
4232
4232
  const data = Object.fromEntries(this.tailPositions);
4233
- writeFileSync9(this.positionsFile, JSON.stringify(data));
4233
+ writeFileSync10(this.positionsFile, JSON.stringify(data));
4234
4234
  } catch (err) {
4235
4235
  log2.warn("failed to save tail positions", {
4236
4236
  error: err.message
@@ -5335,15 +5335,12 @@ function registerMemoryTools(registry, daemonUrl) {
5335
5335
  const context = params.context || "global";
5336
5336
  const topK = params.top_k || 10;
5337
5337
  try {
5338
- const resp = await fetch(`${daemonUrl}/api/search`, {
5339
- method: "POST",
5340
- headers: { "Content-Type": "application/json" },
5341
- body: JSON.stringify({ query, context_name: context, top_k: topK })
5342
- });
5338
+ const searchParams = new URLSearchParams({ q: query, context, limit: String(topK) });
5339
+ const resp = await fetch(`${daemonUrl}/search?${searchParams}`);
5343
5340
  if (!resp.ok) return `Memory search failed: ${resp.status}`;
5344
5341
  const data = await resp.json();
5345
- if (!data.results?.length) return `No memories found for "${query}" in context "${context}".`;
5346
- return data.results.map((r, i) => `${i + 1}. [score: ${r.score.toFixed(3)}] [${r.context_name}] [${r.role}] ${r.content.slice(0, 200)}`).join("\n");
5342
+ if (!data.episodes?.length) return `No memories found for "${query}" in context "${context}".`;
5343
+ return data.episodes.map((r, i) => `${i + 1}. [score: ${r.score.toFixed(3)}] [${r.context_name}] [${r.role}] ${r.content.slice(0, 200)}`).join("\n");
5347
5344
  } catch (err) {
5348
5345
  return `Memory daemon unreachable: ${err.message}`;
5349
5346
  }
@@ -5361,12 +5358,12 @@ function registerMemoryTools(registry, daemonUrl) {
5361
5358
  try {
5362
5359
  const healthResp = await fetch(`${daemonUrl}/health`);
5363
5360
  const health = healthResp.ok ? await healthResp.json() : { status: "unreachable" };
5364
- const ctxResp = await fetch(`${daemonUrl}/api/contexts`);
5361
+ const ctxResp = await fetch(`${daemonUrl}/contexts`);
5365
5362
  const contexts = ctxResp.ok ? (await ctxResp.json()).contexts : [];
5366
5363
  const l3Counts = {};
5367
5364
  for (const ctx of contexts) {
5368
5365
  try {
5369
- const l3Resp = await fetch(`${daemonUrl}/api/l3/${encodeURIComponent(ctx.name)}`);
5366
+ const l3Resp = await fetch(`${daemonUrl}/promotion/l3?context=${encodeURIComponent(ctx.name)}`);
5370
5367
  if (l3Resp.ok) {
5371
5368
  const l3Data = await l3Resp.json();
5372
5369
  l3Counts[ctx.name] = l3Data.entries?.length ?? 0;
@@ -5411,7 +5408,7 @@ Contexts:
5411
5408
  async (params) => {
5412
5409
  const context = params.context || "global";
5413
5410
  try {
5414
- const resp = await fetch(`${daemonUrl}/api/l3/${encodeURIComponent(context)}`);
5411
+ const resp = await fetch(`${daemonUrl}/promotion/l3?context=${encodeURIComponent(context)}`);
5415
5412
  if (!resp.ok) return `L3 query failed: ${resp.status}`;
5416
5413
  const data = await resp.json();
5417
5414
  if (!data.entries?.length) return `No L3 knowledge in context "${context}".`;
@@ -5442,15 +5439,19 @@ Contexts:
5442
5439
  const query = params.query;
5443
5440
  const topK = params.top_k || 10;
5444
5441
  try {
5445
- const resp = await fetch(`${daemonUrl}/api/search/cross-context`, {
5446
- method: "POST",
5447
- headers: { "Content-Type": "application/json" },
5448
- body: JSON.stringify({ query, top_k: topK })
5449
- });
5442
+ const crossParams = new URLSearchParams({ q: query, limit: String(topK) });
5443
+ const resp = await fetch(`${daemonUrl}/search/cross-context?${crossParams}`);
5450
5444
  if (!resp.ok) return `Cross-context search failed: ${resp.status}`;
5451
5445
  const data = await resp.json();
5452
- if (!data.results?.length) return `No memories found across any context for "${query}".`;
5453
- return data.results.map((r, i) => `${i + 1}. [${r.score.toFixed(3)}] [${r.context_name}] ${r.content.slice(0, 200)}`).join("\n");
5446
+ const flat = [];
5447
+ for (const group of data.results || []) {
5448
+ for (const ep of group.episodes) {
5449
+ flat.push({ ...ep, context_name: group.context });
5450
+ }
5451
+ }
5452
+ if (!flat.length) return `No memories found across any context for "${query}".`;
5453
+ flat.sort((a, b) => b.score - a.score);
5454
+ return flat.map((r, i) => `${i + 1}. [${r.score.toFixed(3)}] [${r.context_name}] ${r.content.slice(0, 200)}`).join("\n");
5454
5455
  } catch (err) {
5455
5456
  return `Memory daemon unreachable: ${err.message}`;
5456
5457
  }
@@ -7808,7 +7809,7 @@ function truncate2(text) {
7808
7809
  import { execSync as execSync9 } from "child_process";
7809
7810
  import { resolve as resolve17 } from "path";
7810
7811
  var MAX_OUTPUT6 = 5e4;
7811
- function registerCodingAgentTools(registry, workspaceDir) {
7812
+ function registerCodingAgentTools(registry, workspaceDir, contextBridge) {
7812
7813
  registry.register(
7813
7814
  "coding_agent",
7814
7815
  "Spawn Claude Code CLI to perform a coding task. Use for writing code, debugging, refactoring, or any task that benefits from an AI coding assistant with full filesystem access. Requires the 'claude' CLI to be installed.",
@@ -7826,6 +7827,31 @@ function registerCodingAgentTools(registry, workspaceDir) {
7826
7827
  timeout: {
7827
7828
  type: "number",
7828
7829
  description: "Timeout in seconds. Default: 300"
7830
+ },
7831
+ requirements: {
7832
+ type: "array",
7833
+ items: { type: "string" },
7834
+ description: "Key requirements or constraints for the task"
7835
+ },
7836
+ recentErrors: {
7837
+ type: "array",
7838
+ items: { type: "string" },
7839
+ description: "Recent errors encountered that may be relevant"
7840
+ },
7841
+ relevantPatterns: {
7842
+ type: "array",
7843
+ items: { type: "string" },
7844
+ description: "Known patterns or approaches that might help"
7845
+ },
7846
+ workingFiles: {
7847
+ type: "array",
7848
+ items: { type: "string" },
7849
+ description: "Files currently being worked on"
7850
+ },
7851
+ knownConstraints: {
7852
+ type: "array",
7853
+ items: { type: "string" },
7854
+ description: "Known constraints or limitations to consider"
7829
7855
  }
7830
7856
  },
7831
7857
  required: ["task"]
@@ -7834,8 +7860,24 @@ function registerCodingAgentTools(registry, workspaceDir) {
7834
7860
  const task = params.task;
7835
7861
  const timeoutSeconds = params.timeout || 300;
7836
7862
  const cwd = params.workdir ? resolve17(workspaceDir, params.workdir) : workspaceDir;
7837
- const homedir = process.env.HOME || "/root";
7838
- const extendedPath = `${homedir}/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:${process.env.PATH}`;
7863
+ if (contextBridge) {
7864
+ const context = {
7865
+ goal: task,
7866
+ // Extract additional context from params if provided
7867
+ requirements: params.requirements || [],
7868
+ recentErrors: params.recentErrors || [],
7869
+ relevantPatterns: params.relevantPatterns || [],
7870
+ workingFiles: params.workingFiles || [],
7871
+ knownConstraints: params.knownConstraints || []
7872
+ };
7873
+ try {
7874
+ await contextBridge.prepareContext(context);
7875
+ } catch (err) {
7876
+ console.warn("Failed to prepare context for Claude Code:", err);
7877
+ }
7878
+ }
7879
+ const homedir2 = process.env.HOME || "/root";
7880
+ const extendedPath = `${homedir2}/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:${process.env.PATH}`;
7839
7881
  try {
7840
7882
  execSync9("which claude", { stdio: "ignore", env: { ...process.env, PATH: extendedPath } });
7841
7883
  } catch {
@@ -8070,7 +8112,7 @@ ${findingText}`
8070
8112
  async function storeInMemory(contextName, topic, findings, synthesis, daemonUrl) {
8071
8113
  const storedIds = [];
8072
8114
  try {
8073
- await fetch(`${daemonUrl}/api/contexts`, {
8115
+ await fetch(`${daemonUrl}/contexts`, {
8074
8116
  method: "POST",
8075
8117
  headers: { "Content-Type": "application/json" },
8076
8118
  body: JSON.stringify({
@@ -8084,7 +8126,7 @@ async function storeInMemory(contextName, topic, findings, synthesis, daemonUrl)
8084
8126
  const content = `[Source: ${finding.source}]
8085
8127
  ${finding.keyPoints.join("\n")}`;
8086
8128
  try {
8087
- const resp = await fetch(`${daemonUrl}/api/episodes`, {
8129
+ const resp = await fetch(`${daemonUrl}/episodes`, {
8088
8130
  method: "POST",
8089
8131
  headers: { "Content-Type": "application/json" },
8090
8132
  body: JSON.stringify({
@@ -8101,7 +8143,7 @@ ${finding.keyPoints.join("\n")}`;
8101
8143
  }
8102
8144
  }
8103
8145
  try {
8104
- const resp = await fetch(`${daemonUrl}/api/episodes`, {
8146
+ const resp = await fetch(`${daemonUrl}/episodes`, {
8105
8147
  method: "POST",
8106
8148
  headers: { "Content-Type": "application/json" },
8107
8149
  body: JSON.stringify({
@@ -8118,7 +8160,7 @@ ${synthesis}`
8118
8160
  } catch {
8119
8161
  }
8120
8162
  try {
8121
- await fetch(`${daemonUrl}/api/promotion/run?context=${encodeURIComponent(contextName)}`, {
8163
+ await fetch(`${daemonUrl}/promotion/run?context=${encodeURIComponent(contextName)}`, {
8122
8164
  method: "POST"
8123
8165
  });
8124
8166
  } catch {
@@ -8265,28 +8307,30 @@ ${synthesis}${storageNote}`;
8265
8307
  const daemonUrl = config.memoryDaemonUrl;
8266
8308
  try {
8267
8309
  if (context) {
8268
- const resp2 = await fetch(`${daemonUrl}/api/search`, {
8269
- method: "POST",
8270
- headers: { "Content-Type": "application/json" },
8271
- body: JSON.stringify({ query: topic, context_name: context, top_k: 10 })
8272
- });
8310
+ const searchParams = new URLSearchParams({ q: topic, context, limit: "10" });
8311
+ const resp2 = await fetch(`${daemonUrl}/search?${searchParams}`);
8273
8312
  if (!resp2.ok) return `Memory search failed: ${resp2.status}`;
8274
8313
  const data2 = await resp2.json();
8275
- if (!data2.results?.length) return `No learned knowledge found for "${topic}" in context "${context}".`;
8276
- return data2.results.map((r, i) => `${i + 1}. [score: ${r.score.toFixed(3)}] [${r.role}]
8314
+ if (!data2.episodes?.length) return `No learned knowledge found for "${topic}" in context "${context}".`;
8315
+ return data2.episodes.map((r, i) => `${i + 1}. [score: ${r.score.toFixed(3)}] [${r.role}]
8277
8316
  ${r.content.slice(0, 500)}`).join("\n\n");
8278
8317
  }
8279
- const resp = await fetch(`${daemonUrl}/api/search/cross-context`, {
8280
- method: "POST",
8281
- headers: { "Content-Type": "application/json" },
8282
- body: JSON.stringify({ query: topic, top_k: 15 })
8283
- });
8318
+ const crossParams = new URLSearchParams({ q: topic, limit: "15" });
8319
+ const resp = await fetch(`${daemonUrl}/search/cross-context?${crossParams}`);
8284
8320
  if (!resp.ok) return `Memory cross-search failed: ${resp.status}`;
8285
8321
  const data = await resp.json();
8286
- const learnResults = data.results?.filter((r) => r.context_name.startsWith("learn-")) || [];
8322
+ const learnResults = [];
8323
+ for (const group of data.results || []) {
8324
+ if (group.context.startsWith("learn-")) {
8325
+ for (const ep of group.episodes) {
8326
+ learnResults.push({ ...ep, context_name: group.context });
8327
+ }
8328
+ }
8329
+ }
8287
8330
  if (learnResults.length === 0) {
8288
8331
  return `No previously learned knowledge found for "${topic}". Use the learn tool first.`;
8289
8332
  }
8333
+ learnResults.sort((a, b) => b.score - a.score);
8290
8334
  return learnResults.map((r, i) => `${i + 1}. [score: ${r.score.toFixed(3)}] [${r.context_name}] [${r.role}]
8291
8335
  ${r.content.slice(0, 500)}`).join("\n\n");
8292
8336
  } catch (err) {
@@ -8325,7 +8369,7 @@ function registerAllTools(hivemindHome, config) {
8325
8369
  registerWatchTools(registry, workspaceDir, dataDir);
8326
8370
  registerMacOSTools(registry, workspaceDir);
8327
8371
  registerDataTools(registry, workspaceDir);
8328
- registerCodingAgentTools(registry, workspaceDir);
8372
+ registerCodingAgentTools(registry, workspaceDir, config?.contextBridge);
8329
8373
  registerLearnTools(registry, {
8330
8374
  llmConfig: config?.llmConfig,
8331
8375
  memoryDaemonUrl: config?.memoryDaemonUrl || "http://localhost:3434",
@@ -8534,13 +8578,224 @@ Path: ${skillDir}`;
8534
8578
  }
8535
8579
 
8536
8580
  // packages/runtime/src/pipeline.ts
8537
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, unlinkSync as unlinkSync3 } from "fs";
8538
- import { resolve as resolve20, dirname as dirname8 } from "path";
8581
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3 } from "fs";
8582
+ import { resolve as resolve20, dirname as dirname9 } from "path";
8539
8583
  import { fileURLToPath as fileURLToPath3 } from "url";
8584
+
8585
+ // packages/runtime/src/tools/context-bridge.ts
8586
+ import { writeFileSync as writeFileSync8, readFileSync as readFileSync15, existsSync as existsSync20, mkdirSync as mkdirSync15, watchFile, unwatchFile } from "fs";
8587
+ import { join as join8, dirname as dirname8 } from "path";
8588
+ import { homedir } from "os";
8589
+ import { EventEmitter as EventEmitter2 } from "events";
8590
+ var ClaudeContextBridge = class extends EventEmitter2 {
8591
+ workspaceDir;
8592
+ memoryClient;
8593
+ logger;
8594
+ sessionLogPath;
8595
+ contextFilePath;
8596
+ claudeSettingsPath;
8597
+ logWatcher;
8598
+ constructor(config) {
8599
+ super();
8600
+ this.workspaceDir = config.workspaceDir;
8601
+ this.memoryClient = config.memoryClient;
8602
+ this.logger = config.logger;
8603
+ this.sessionLogPath = join8(homedir(), ".claude", "session.log");
8604
+ this.contextFilePath = join8(this.workspaceDir, "CLAUDE_CONTEXT.md");
8605
+ this.claudeSettingsPath = join8(homedir(), ".claude", "settings.json");
8606
+ }
8607
+ /**
8608
+ * Initialize the context bridge
8609
+ */
8610
+ async initialize() {
8611
+ const claudeDir = dirname8(this.claudeSettingsPath);
8612
+ if (!existsSync20(claudeDir)) {
8613
+ mkdirSync15(claudeDir, { recursive: true });
8614
+ }
8615
+ await this.setupClaudeSettings();
8616
+ this.startLogMonitoring();
8617
+ this.logger.info("Claude context bridge initialized");
8618
+ }
8619
+ /**
8620
+ * Configure Claude Code to report insights
8621
+ */
8622
+ async setupClaudeSettings() {
8623
+ const customInstructions = `# Hivemind Context Bridge
8624
+
8625
+ When working on tasks, please report significant findings by writing to the session log:
8626
+
8627
+ - When you discover architecture/patterns: echo "DISCOVERY: [details]" >> ~/.claude/session.log
8628
+ - When you need more context: echo "NEED: [what you need]" >> ~/.claude/session.log
8629
+ - When you complete major steps: echo "COMPLETE: [what you did]" >> ~/.claude/session.log
8630
+ - When you find reusable solutions: echo "PATTERN: [approach]" >> ~/.claude/session.log
8631
+ - When you encounter errors: echo "ERROR: [error details]" >> ~/.claude/session.log
8632
+
8633
+ Always check ~/hivemind/workspace/CLAUDE_CONTEXT.md for task context and requirements.`;
8634
+ const settings = {
8635
+ customInstructions,
8636
+ alwaysIncludeFiles: [
8637
+ this.contextFilePath,
8638
+ join8(this.workspaceDir, "ARCHITECTURE.md"),
8639
+ join8(this.workspaceDir, "TOOLS.md")
8640
+ ],
8641
+ // Enable verbose logging for better insights
8642
+ verboseLogging: true
8643
+ };
8644
+ writeFileSync8(this.claudeSettingsPath, JSON.stringify(settings, null, 2));
8645
+ this.logger.info("Claude settings configured for context bridge");
8646
+ }
8647
+ /**
8648
+ * Prepare context for a Claude Code session
8649
+ */
8650
+ async prepareContext(context) {
8651
+ let content = `# Claude Code Context
8652
+ Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
8653
+
8654
+ ## Current Goal
8655
+ ${context.goal}
8656
+ `;
8657
+ if (context.requirements?.length) {
8658
+ content += `
8659
+ ## Requirements
8660
+ ${context.requirements.map((r) => `- ${r}`).join("\n")}
8661
+ `;
8662
+ }
8663
+ if (context.recentErrors?.length) {
8664
+ content += `
8665
+ ## Recent Errors
8666
+ \`\`\`
8667
+ ${context.recentErrors.join("\n")}
8668
+ \`\`\`
8669
+ `;
8670
+ }
8671
+ if (context.relevantPatterns?.length) {
8672
+ content += `
8673
+ ## Known Patterns
8674
+ ${context.relevantPatterns.map((p) => `- ${p}`).join("\n")}
8675
+ `;
8676
+ }
8677
+ if (context.workingFiles?.length) {
8678
+ content += `
8679
+ ## Working Files
8680
+ ${context.workingFiles.map((f) => `- ${f}`).join("\n")}
8681
+ `;
8682
+ }
8683
+ if (context.knownConstraints?.length) {
8684
+ content += `
8685
+ ## Known Constraints
8686
+ ${context.knownConstraints.map((c) => `- ${c}`).join("\n")}
8687
+ `;
8688
+ }
8689
+ try {
8690
+ const memories = await this.getRelevantMemories(context.goal);
8691
+ if (memories.length > 0) {
8692
+ content += `
8693
+ ## Relevant Knowledge
8694
+ ${memories.join("\n\n")}
8695
+ `;
8696
+ }
8697
+ } catch (err) {
8698
+ this.logger.warn("Failed to fetch memories for context", err);
8699
+ }
8700
+ writeFileSync8(this.contextFilePath, content);
8701
+ this.logger.info("Context prepared for Claude Code", { goal: context.goal });
8702
+ }
8703
+ /**
8704
+ * Fetch relevant memories for the task
8705
+ */
8706
+ async getRelevantMemories(goal) {
8707
+ try {
8708
+ const results = await this.memoryClient.search(goal, "global", 5);
8709
+ return results.map((r) => `- ${r.content}`);
8710
+ } catch (err) {
8711
+ return [];
8712
+ }
8713
+ }
8714
+ /**
8715
+ * Start monitoring Claude's session log for insights
8716
+ */
8717
+ startLogMonitoring() {
8718
+ if (!existsSync20(this.sessionLogPath)) {
8719
+ writeFileSync8(this.sessionLogPath, "");
8720
+ }
8721
+ let lastSize = 0;
8722
+ watchFile(this.sessionLogPath, { interval: 1e3 }, (curr, prev) => {
8723
+ if (curr.size > lastSize) {
8724
+ const content = readFileSync15(this.sessionLogPath, "utf-8");
8725
+ const newContent = content.slice(lastSize);
8726
+ lastSize = curr.size;
8727
+ const lines = newContent.split("\n").filter((line) => line.trim());
8728
+ for (const line of lines) {
8729
+ this.processLogLine(line);
8730
+ }
8731
+ }
8732
+ });
8733
+ this.logger.info("Started monitoring Claude session log");
8734
+ }
8735
+ /**
8736
+ * Process a line from Claude's session log
8737
+ */
8738
+ processLogLine(line) {
8739
+ const patterns = {
8740
+ DISCOVERY: /^DISCOVERY:\s*(.+)$/,
8741
+ NEED: /^NEED:\s*(.+)$/,
8742
+ COMPLETE: /^COMPLETE:\s*(.+)$/,
8743
+ PATTERN: /^PATTERN:\s*(.+)$/,
8744
+ ERROR: /^ERROR:\s*(.+)$/
8745
+ };
8746
+ for (const [type, pattern] of Object.entries(patterns)) {
8747
+ const match = line.match(pattern);
8748
+ if (match) {
8749
+ const content = match[1];
8750
+ this.handleInsight(type, content);
8751
+ break;
8752
+ }
8753
+ }
8754
+ }
8755
+ /**
8756
+ * Handle an insight from Claude Code
8757
+ */
8758
+ async handleInsight(type, content) {
8759
+ this.logger.info(`Claude insight: ${type}`, { content });
8760
+ this.emit("insight", { type, content });
8761
+ if (["DISCOVERY", "PATTERN"].includes(type)) {
8762
+ try {
8763
+ await this.memoryClient.store({
8764
+ content: `Claude Code ${type}: ${content}`,
8765
+ metadata: {
8766
+ source: "claude-code",
8767
+ type: type.toLowerCase(),
8768
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8769
+ }
8770
+ });
8771
+ } catch (err) {
8772
+ this.logger.warn("Failed to store Claude insight in memory", err);
8773
+ }
8774
+ }
8775
+ if (type === "NEED") {
8776
+ this.emit("context-request", content);
8777
+ }
8778
+ }
8779
+ /**
8780
+ * Clean up resources
8781
+ */
8782
+ destroy() {
8783
+ if (this.sessionLogPath && existsSync20(this.sessionLogPath)) {
8784
+ unwatchFile(this.sessionLogPath);
8785
+ }
8786
+ }
8787
+ };
8788
+ async function createContextBridge(config) {
8789
+ const bridge = new ClaudeContextBridge(config);
8790
+ await bridge.initialize();
8791
+ return bridge;
8792
+ }
8793
+
8794
+ // packages/runtime/src/pipeline.ts
8540
8795
  var PACKAGE_VERSION = "unknown";
8541
8796
  try {
8542
- const __dirname2 = dirname8(fileURLToPath3(import.meta.url));
8543
- const pkg = JSON.parse(readFileSync15(resolve20(__dirname2, "../package.json"), "utf-8"));
8797
+ const __dirname2 = dirname9(fileURLToPath3(import.meta.url));
8798
+ const pkg = JSON.parse(readFileSync16(resolve20(__dirname2, "../package.json"), "utf-8"));
8544
8799
  PACKAGE_VERSION = pkg.version ?? "unknown";
8545
8800
  } catch {
8546
8801
  }
@@ -8582,7 +8837,7 @@ function startHealthServer(port) {
8582
8837
  return server;
8583
8838
  }
8584
8839
  function writePidFile(path) {
8585
- writeFileSync8(path, String(process.pid));
8840
+ writeFileSync9(path, String(process.pid));
8586
8841
  console.log(`[hivemind] PID file written: ${path}`);
8587
8842
  }
8588
8843
  function cleanupPidFile(path) {
@@ -8623,20 +8878,34 @@ async function startPipeline(configPath) {
8623
8878
  console.log("[hivemind] Global context already exists in memory daemon");
8624
8879
  }
8625
8880
  }
8626
- const requestLogger = new RequestLogger(resolve20(dirname8(configPath), "data", "dashboard.db"));
8881
+ const requestLogger = new RequestLogger(resolve20(dirname9(configPath), "data", "dashboard.db"));
8627
8882
  const agent = new Agent(config);
8628
8883
  startDashboardServer(requestLogger, config.memory, () => agent.getConversationHistories());
8629
8884
  agent.setRequestLogger(requestLogger);
8630
8885
  const hivemindHome = process.env.HIVEMIND_HOME || resolve20(process.env.HOME || "/root", "hivemind");
8886
+ const workspaceDir = resolve20(hivemindHome, config.agent.workspace || "workspace");
8887
+ let contextBridge;
8888
+ if (memoryConnected) {
8889
+ try {
8890
+ contextBridge = await createContextBridge({
8891
+ workspaceDir,
8892
+ memoryClient: memory,
8893
+ logger: createLogger("claude-bridge")
8894
+ });
8895
+ console.log("[hivemind] Claude context bridge initialized");
8896
+ } catch (err) {
8897
+ console.warn("[hivemind] Failed to create Claude context bridge:", err);
8898
+ }
8899
+ }
8631
8900
  const toolRegistry = registerAllTools(hivemindHome, {
8632
8901
  enabled: true,
8633
8902
  workspace: config.agent.workspace || "workspace",
8634
8903
  braveApiKey: process.env.BRAVE_API_KEY,
8635
8904
  memoryDaemonUrl: config.memory.daemon_url,
8636
8905
  configPath,
8637
- llmConfig: config.llm
8906
+ llmConfig: config.llm,
8907
+ contextBridge
8638
8908
  });
8639
- const workspaceDir = resolve20(hivemindHome, config.agent.workspace || "workspace");
8640
8909
  const skillsEngine = new SkillsEngine(workspaceDir, toolRegistry);
8641
8910
  await skillsEngine.loadAll();
8642
8911
  registerSkillsTools(toolRegistry, skillsEngine, workspaceDir);
@@ -8886,7 +9155,7 @@ async function runSpawnTask(config, configPath) {
8886
9155
  const result = response.content;
8887
9156
  console.log(`[spawn] Task completed (context: ${response.context})`);
8888
9157
  if (spawnDir) {
8889
- writeFileSync8(resolve20(spawnDir, "result.txt"), result);
9158
+ writeFileSync9(resolve20(spawnDir, "result.txt"), result);
8890
9159
  }
8891
9160
  if (channelId && config.sesame.api_key) {
8892
9161
  try {
@@ -8903,7 +9172,7 @@ async function runSpawnTask(config, configPath) {
8903
9172
  const errorMsg = `[SPAWN ERROR] ${err.message}`;
8904
9173
  console.error(`[spawn] ${errorMsg}`);
8905
9174
  if (spawnDir) {
8906
- writeFileSync8(resolve20(spawnDir, "result.txt"), errorMsg);
9175
+ writeFileSync9(resolve20(spawnDir, "result.txt"), errorMsg);
8907
9176
  }
8908
9177
  process.exitCode = 1;
8909
9178
  }
@@ -9415,4 +9684,4 @@ smol-toml/dist/index.js:
9415
9684
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9416
9685
  *)
9417
9686
  */
9418
- //# sourceMappingURL=chunk-OB6OXLPC.js.map
9687
+ //# sourceMappingURL=chunk-ZQ26EOYD.js.map