@sesamespace/hivemind 0.12.2 → 0.12.3

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,8 +1,8 @@
1
1
  import {
2
2
  runFleetCommand
3
- } from "../chunk-EJM4KCCY.js";
4
- import "../chunk-ZAPHLG7V.js";
5
- import "../chunk-R7RHYYOM.js";
3
+ } from "../chunk-6W56VBXG.js";
4
+ import "../chunk-3SIWFXC7.js";
5
+ import "../chunk-TQYOGZIN.js";
6
6
  import "../chunk-DGUM43GV.js";
7
7
  export {
8
8
  runFleetCommand
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runInitCommand
3
- } from "../chunk-ZI4AN7GT.js";
4
- import "../chunk-ZAPHLG7V.js";
5
- import "../chunk-R7RHYYOM.js";
3
+ } from "../chunk-KOSNIWPS.js";
4
+ import "../chunk-3SIWFXC7.js";
5
+ import "../chunk-TQYOGZIN.js";
6
6
  import "../chunk-DGUM43GV.js";
7
7
  export {
8
8
  runInitCommand
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runStartCommand
3
- } from "../chunk-SNW6Z2W4.js";
4
- import "../chunk-ZAPHLG7V.js";
5
- import "../chunk-R7RHYYOM.js";
3
+ } from "../chunk-7HOPTFRU.js";
4
+ import "../chunk-3SIWFXC7.js";
5
+ import "../chunk-TQYOGZIN.js";
6
6
  import "../chunk-DGUM43GV.js";
7
7
  export {
8
8
  runStartCommand
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  runWatchdogCommand
3
- } from "../chunk-3F7M2BPR.js";
4
- import "../chunk-ZAPHLG7V.js";
5
- import "../chunk-R7RHYYOM.js";
3
+ } from "../chunk-EDSK2CG6.js";
4
+ import "../chunk-3SIWFXC7.js";
5
+ import "../chunk-TQYOGZIN.js";
6
6
  import "../chunk-DGUM43GV.js";
7
7
  export {
8
8
  runWatchdogCommand
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  PrimaryMemorySync,
5
5
  Watchdog,
6
6
  WorkerMemorySync
7
- } from "./chunk-ZAPHLG7V.js";
7
+ } from "./chunk-3SIWFXC7.js";
8
8
  import {
9
9
  Agent,
10
10
  AutoDebugger,
@@ -34,7 +34,7 @@ import {
34
34
  setLogLevel,
35
35
  startPipeline,
36
36
  startWorker
37
- } from "./chunk-R7RHYYOM.js";
37
+ } from "./chunk-TQYOGZIN.js";
38
38
  import "./chunk-DGUM43GV.js";
39
39
  export {
40
40
  Agent,
package/dist/main.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runInitCommand
4
- } from "./chunk-ZI4AN7GT.js";
4
+ } from "./chunk-KOSNIWPS.js";
5
5
  import {
6
6
  runStartCommand
7
- } from "./chunk-SNW6Z2W4.js";
7
+ } from "./chunk-7HOPTFRU.js";
8
8
  import {
9
9
  runFleetCommand
10
- } from "./chunk-EJM4KCCY.js";
10
+ } from "./chunk-6W56VBXG.js";
11
11
  import {
12
12
  runServiceCommand
13
13
  } from "./chunk-6QZDXOMW.js";
@@ -16,9 +16,9 @@ import {
16
16
  } from "./chunk-ICSJNKI6.js";
17
17
  import {
18
18
  runWatchdogCommand
19
- } from "./chunk-3F7M2BPR.js";
20
- import "./chunk-ZAPHLG7V.js";
21
- import "./chunk-R7RHYYOM.js";
19
+ } from "./chunk-EDSK2CG6.js";
20
+ import "./chunk-3SIWFXC7.js";
21
+ import "./chunk-TQYOGZIN.js";
22
22
  import "./chunk-DGUM43GV.js";
23
23
 
24
24
  // packages/cli/src/commands/session.ts
package/dist/start.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  loadConfig,
4
4
  startPipeline,
5
5
  startWorker
6
- } from "./chunk-R7RHYYOM.js";
6
+ } from "./chunk-TQYOGZIN.js";
7
7
  import "./chunk-DGUM43GV.js";
8
8
 
9
9
  // packages/runtime/src/start.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sesamespace/hivemind",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "Cognitive architecture for AI agents with multi-layered memory",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Test Suite for Claude Code Integration
3
+ *
4
+ * Tests the bidirectional context bridge, memory storage,
5
+ * and real-time notification systems.
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, afterEach } from "@jest/globals";
9
+ import { ClaudeContextBridge } from "../packages/runtime/src/tools/context-bridge.js";
10
+ import { ClaudeNotifier } from "../packages/runtime/src/tools/claude-notifier.js";
11
+ import { MemoryClient } from "../packages/runtime/src/memory-client.js";
12
+ import { Logger } from "../packages/runtime/src/logger.js";
13
+ import { writeFileSync, unlinkSync, existsSync } from "fs";
14
+ import { join } from "path";
15
+ import { homedir } from "os";
16
+
17
+ describe("Claude Code Integration", () => {
18
+ let contextBridge: ClaudeContextBridge;
19
+ let memoryClient: MemoryClient;
20
+ let logger: Logger;
21
+ let workspaceDir: string;
22
+ let sessionLogPath: string;
23
+
24
+ beforeEach(async () => {
25
+ // Set up test environment
26
+ workspaceDir = "/tmp/test-workspace";
27
+ sessionLogPath = join(homedir(), ".claude", "session.log");
28
+
29
+ // Create mock implementations
30
+ logger = {
31
+ info: jest.fn(),
32
+ warn: jest.fn(),
33
+ error: jest.fn(),
34
+ debug: jest.fn(),
35
+ } as any;
36
+
37
+ memoryClient = {
38
+ search: jest.fn().mockResolvedValue([]),
39
+ storeEpisode: jest.fn().mockResolvedValue({}),
40
+ } as any;
41
+
42
+ // Create context bridge
43
+ contextBridge = new ClaudeContextBridge({
44
+ workspaceDir,
45
+ memoryClient,
46
+ logger,
47
+ });
48
+
49
+ await contextBridge.initialize();
50
+ });
51
+
52
+ afterEach(() => {
53
+ contextBridge.destroy();
54
+ // Clean up test files
55
+ if (existsSync(sessionLogPath)) {
56
+ unlinkSync(sessionLogPath);
57
+ }
58
+ });
59
+
60
+ describe("Context Preparation", () => {
61
+ it("should prepare context with all fields", async () => {
62
+ const context = {
63
+ goal: "Fix authentication bug",
64
+ requirements: ["Must support OAuth", "Handle token refresh"],
65
+ recentErrors: ["401 Unauthorized on /api/user"],
66
+ relevantPatterns: ["Use middleware for auth"],
67
+ workingFiles: ["src/auth.ts", "src/middleware.ts"],
68
+ knownConstraints: ["JWT tokens expire after 1 hour"],
69
+ };
70
+
71
+ await contextBridge.prepareContext(context);
72
+
73
+ const contextFile = join(workspaceDir, "CLAUDE_CONTEXT.md");
74
+ expect(existsSync(contextFile)).toBe(true);
75
+
76
+ const content = require('fs').readFileSync(contextFile, 'utf-8');
77
+ expect(content).toContain("Fix authentication bug");
78
+ expect(content).toContain("Must support OAuth");
79
+ expect(content).toContain("401 Unauthorized");
80
+ expect(content).toContain("Use middleware for auth");
81
+ expect(content).toContain("src/auth.ts");
82
+ expect(content).toContain("JWT tokens expire after 1 hour");
83
+ });
84
+
85
+ it("should include memory search results", async () => {
86
+ // Mock memory search
87
+ (memoryClient.search as jest.Mock).mockResolvedValue([
88
+ { content: "Previous auth implementation used Passport.js" },
89
+ { content: "Refresh tokens stored in Redis" },
90
+ ]);
91
+
92
+ await contextBridge.prepareContext({ goal: "Implement authentication" });
93
+
94
+ expect(memoryClient.search).toHaveBeenCalledWith("Implement authentication", "global", 5);
95
+
96
+ const contextFile = join(workspaceDir, "CLAUDE_CONTEXT.md");
97
+ const content = require('fs').readFileSync(contextFile, 'utf-8');
98
+ expect(content).toContain("Previous auth implementation used Passport.js");
99
+ expect(content).toContain("Refresh tokens stored in Redis");
100
+ });
101
+ });
102
+
103
+ describe("Session Log Monitoring", () => {
104
+ it("should detect and process DISCOVERY entries", (done) => {
105
+ contextBridge.on('insight', ({ type, content }) => {
106
+ expect(type).toBe('DISCOVERY');
107
+ expect(content).toBe('Found JWT validation in middleware');
108
+ done();
109
+ });
110
+
111
+ // Simulate Claude writing to session log
112
+ setTimeout(() => {
113
+ writeFileSync(sessionLogPath, "DISCOVERY: Found JWT validation in middleware\n", { flag: 'a' });
114
+ }, 100);
115
+ });
116
+
117
+ it("should detect and process NEED entries", (done) => {
118
+ contextBridge.on('context-request', (need) => {
119
+ expect(need).toBe('Database schema for users table');
120
+ done();
121
+ });
122
+
123
+ setTimeout(() => {
124
+ writeFileSync(sessionLogPath, "NEED: Database schema for users table\n", { flag: 'a' });
125
+ }, 100);
126
+ });
127
+
128
+ it("should store PATTERN entries in memory", (done) => {
129
+ contextBridge.on('insight', async ({ type }) => {
130
+ if (type === 'PATTERN') {
131
+ // Give it time to store
132
+ setTimeout(() => {
133
+ expect(memoryClient.storeEpisode).toHaveBeenCalledWith({
134
+ context_name: "claude-code-insights",
135
+ role: "system",
136
+ content: "PATTERN: Always validate JWT in middleware",
137
+ metadata: expect.objectContaining({
138
+ type: "PATTERN",
139
+ source: "claude-code",
140
+ }),
141
+ });
142
+ done();
143
+ }, 100);
144
+ }
145
+ });
146
+
147
+ setTimeout(() => {
148
+ writeFileSync(sessionLogPath, "PATTERN: Always validate JWT in middleware\n", { flag: 'a' });
149
+ }, 100);
150
+ });
151
+
152
+ it("should deduplicate identical patterns", async () => {
153
+ // Write the same pattern twice
154
+ writeFileSync(sessionLogPath, "PATTERN: Use async/await for DB calls\n");
155
+ await new Promise(resolve => setTimeout(resolve, 600));
156
+ writeFileSync(sessionLogPath, "PATTERN: Use async/await for DB calls\n", { flag: 'a' });
157
+ await new Promise(resolve => setTimeout(resolve, 600));
158
+
159
+ // Should only store once
160
+ expect(memoryClient.storeEpisode).toHaveBeenCalledTimes(1);
161
+ });
162
+ });
163
+
164
+ describe("Real-time Context Injection", () => {
165
+ it("should append context when Claude needs it", async () => {
166
+ // Mock memory search for additional context
167
+ (memoryClient.search as jest.Mock).mockResolvedValue([
168
+ { content: "Users table has columns: id, email, password_hash, created_at" },
169
+ ]);
170
+
171
+ // Prepare initial context
172
+ await contextBridge.prepareContext({ goal: "Fix user query" });
173
+
174
+ // Simulate Claude needing more info
175
+ writeFileSync(sessionLogPath, "NEED: Database schema\n", { flag: 'a' });
176
+
177
+ // Wait for processing
178
+ await new Promise(resolve => setTimeout(resolve, 600));
179
+
180
+ // Check that context was appended
181
+ const contextFile = join(workspaceDir, "CLAUDE_CONTEXT.md");
182
+ const content = require('fs').readFileSync(contextFile, 'utf-8');
183
+ expect(content).toContain("Additional Context");
184
+ expect(content).toContain("You asked about: Database schema");
185
+ expect(content).toContain("Users table has columns");
186
+ });
187
+ });
188
+
189
+ describe("Session Summary", () => {
190
+ it("should retrieve categorized insights", async () => {
191
+ // Mock memory with various insight types
192
+ (memoryClient.search as jest.Mock).mockResolvedValue([
193
+ { content: "DISCOVERY: Auth uses JWT with RS256" },
194
+ { content: "PATTERN: Validate tokens in middleware" },
195
+ { content: "ERROR: Missing JWKS endpoint" },
196
+ { content: "COMPLETE: Implemented token refresh" },
197
+ { content: "NEED: Public key for verification" },
198
+ ]);
199
+
200
+ const summary = await contextBridge.getSessionSummary();
201
+
202
+ expect(summary.discoveries).toContain("Auth uses JWT with RS256");
203
+ expect(summary.patterns).toContain("Validate tokens in middleware");
204
+ expect(summary.errors).toContain("Missing JWKS endpoint");
205
+ expect(summary.completions).toContain("Implemented token refresh");
206
+ expect(summary.needs).toContain("Public key for verification");
207
+ });
208
+ });
209
+
210
+ describe("Notification System", () => {
211
+ it("should emit urgent events for NEED requests", (done) => {
212
+ const notifier = new ClaudeNotifier({
213
+ logger,
214
+ contextBridge,
215
+ onNeed: async (need) => {
216
+ expect(need).toBe("API documentation");
217
+ done();
218
+ },
219
+ });
220
+
221
+ // Simulate Claude needing something
222
+ writeFileSync(sessionLogPath, "NEED: API documentation\n", { flag: 'a' });
223
+ });
224
+
225
+ it("should handle critical errors", (done) => {
226
+ const notifier = new ClaudeNotifier({
227
+ logger,
228
+ contextBridge,
229
+ onError: async (error) => {
230
+ expect(error).toBe("Cannot find module 'auth'");
231
+ done();
232
+ },
233
+ });
234
+
235
+ writeFileSync(sessionLogPath, "ERROR: Cannot find module 'auth'\n", { flag: 'a' });
236
+ });
237
+
238
+ it("should create urgent events", (done) => {
239
+ const notifier = new ClaudeNotifier({
240
+ logger,
241
+ contextBridge,
242
+ });
243
+
244
+ notifier.on('urgent-event', (event) => {
245
+ expect(event.type).toBe("immediate");
246
+ expect(event.text).toContain("[Claude Code Urgent]");
247
+ expect(event.text).toContain("Missing database credentials");
248
+ done();
249
+ });
250
+
251
+ notifier.createUrgentEvent("Missing database credentials", "test-channel");
252
+ });
253
+ });
254
+
255
+ describe("End-to-End Integration", () => {
256
+ it("should handle a complete Claude Code session", async () => {
257
+ // Prepare context
258
+ await contextBridge.prepareContext({
259
+ goal: "Implement user authentication",
260
+ requirements: ["Support JWT", "Handle refresh tokens"],
261
+ });
262
+
263
+ // Simulate Claude Code session
264
+ const sessionLog = [
265
+ "DISCOVERY: Found existing Passport.js setup",
266
+ "PATTERN: Use httpOnly cookies for refresh tokens",
267
+ "NEED: Redis connection details",
268
+ "ERROR: Redis connection failed",
269
+ "COMPLETE: Implemented JWT authentication",
270
+ ];
271
+
272
+ for (const line of sessionLog) {
273
+ writeFileSync(sessionLogPath, line + "\n", { flag: 'a' });
274
+ await new Promise(resolve => setTimeout(resolve, 100));
275
+ }
276
+
277
+ // Wait for processing
278
+ await new Promise(resolve => setTimeout(resolve, 1000));
279
+
280
+ // Verify memory storage
281
+ const storeEpisodeCalls = (memoryClient.storeEpisode as jest.Mock).mock.calls;
282
+ expect(storeEpisodeCalls.length).toBeGreaterThanOrEqual(2);
283
+
284
+ // Verify discoveries and patterns were stored
285
+ const storedContent = storeEpisodeCalls.map(call => call[0].content);
286
+ expect(storedContent).toContain("DISCOVERY: Found existing Passport.js setup");
287
+ expect(storedContent).toContain("PATTERN: Use httpOnly cookies for refresh tokens");
288
+
289
+ // Get session summary
290
+ const summary = await contextBridge.getSessionSummary();
291
+ expect(summary.discoveries.length).toBeGreaterThan(0);
292
+ expect(summary.patterns.length).toBeGreaterThan(0);
293
+ expect(summary.errors.length).toBeGreaterThan(0);
294
+ expect(summary.completions.length).toBeGreaterThan(0);
295
+ });
296
+ });
297
+ });
298
+
299
+ describe("Test Suite Requirements", () => {
300
+ it("should cover all critical functionality", () => {
301
+ const testCategories = [
302
+ "Context Preparation",
303
+ "Session Log Monitoring",
304
+ "Real-time Context Injection",
305
+ "Session Summary",
306
+ "Notification System",
307
+ "End-to-End Integration"
308
+ ];
309
+
310
+ const criticalFeatures = [
311
+ "Prepare context with memory search",
312
+ "Monitor session log in real-time",
313
+ "Store discoveries and patterns",
314
+ "Deduplicate patterns",
315
+ "Inject context on NEED",
316
+ "Emit notifications for urgent needs",
317
+ "Generate session summaries",
318
+ "Handle complete sessions"
319
+ ];
320
+
321
+ // This test just documents what we're testing
322
+ expect(testCategories.length).toBeGreaterThanOrEqual(6);
323
+ expect(criticalFeatures.length).toBeGreaterThanOrEqual(8);
324
+ });
325
+ });