@swarmroom/server 0.1.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.
Files changed (61) hide show
  1. package/dist/__tests__/setup.d.ts +6 -0
  2. package/dist/__tests__/setup.js +88 -0
  3. package/dist/app.d.ts +3 -0
  4. package/dist/app.js +41 -0
  5. package/dist/db/index.d.ts +6 -0
  6. package/dist/db/index.js +62 -0
  7. package/dist/db/schema.d.ts +655 -0
  8. package/dist/db/schema.js +61 -0
  9. package/dist/db/seed.d.ts +1 -0
  10. package/dist/db/seed.js +15 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +30 -0
  13. package/dist/lib/names.d.ts +1 -0
  14. package/dist/lib/names.js +32 -0
  15. package/dist/mcp/server.d.ts +2 -0
  16. package/dist/mcp/server.js +154 -0
  17. package/dist/mcp/transport.d.ts +2 -0
  18. package/dist/mcp/transport.js +27 -0
  19. package/dist/middleware/cors.d.ts +1 -0
  20. package/dist/middleware/cors.js +8 -0
  21. package/dist/middleware/error-handler.d.ts +2 -0
  22. package/dist/middleware/error-handler.js +10 -0
  23. package/dist/routes/__tests__/agents.test.d.ts +1 -0
  24. package/dist/routes/__tests__/agents.test.js +80 -0
  25. package/dist/routes/agents.d.ts +3 -0
  26. package/dist/routes/agents.js +100 -0
  27. package/dist/routes/health.d.ts +3 -0
  28. package/dist/routes/health.js +14 -0
  29. package/dist/routes/messages.d.ts +3 -0
  30. package/dist/routes/messages.js +65 -0
  31. package/dist/routes/projects.d.ts +3 -0
  32. package/dist/routes/projects.js +94 -0
  33. package/dist/routes/teams.d.ts +3 -0
  34. package/dist/routes/teams.js +94 -0
  35. package/dist/routes/well-known.d.ts +3 -0
  36. package/dist/routes/well-known.js +78 -0
  37. package/dist/routes/ws.d.ts +5 -0
  38. package/dist/routes/ws.js +19 -0
  39. package/dist/services/__tests__/agent-service.test.d.ts +1 -0
  40. package/dist/services/__tests__/agent-service.test.js +67 -0
  41. package/dist/services/__tests__/heartbeat-service.test.d.ts +1 -0
  42. package/dist/services/__tests__/heartbeat-service.test.js +76 -0
  43. package/dist/services/__tests__/message-service.test.d.ts +1 -0
  44. package/dist/services/__tests__/message-service.test.js +85 -0
  45. package/dist/services/agent-service.d.ts +74 -0
  46. package/dist/services/agent-service.js +131 -0
  47. package/dist/services/heartbeat-service.d.ts +2 -0
  48. package/dist/services/heartbeat-service.js +35 -0
  49. package/dist/services/mdns-browser.d.ts +2 -0
  50. package/dist/services/mdns-browser.js +53 -0
  51. package/dist/services/mdns-service.d.ts +2 -0
  52. package/dist/services/mdns-service.js +66 -0
  53. package/dist/services/message-service.d.ts +82 -0
  54. package/dist/services/message-service.js +172 -0
  55. package/dist/services/project-service.d.ts +130 -0
  56. package/dist/services/project-service.js +104 -0
  57. package/dist/services/team-service.d.ts +130 -0
  58. package/dist/services/team-service.js +104 -0
  59. package/dist/services/ws-manager.d.ts +19 -0
  60. package/dist/services/ws-manager.js +165 -0
  61. package/package.json +47 -0
@@ -0,0 +1,6 @@
1
+ import Database from 'better-sqlite3';
2
+ import * as schema from '../db/schema.js';
3
+ export declare function createTestDb(): import("drizzle-orm/better-sqlite3").BetterSQLite3Database<typeof schema> & {
4
+ $client: Database.Database;
5
+ };
6
+ export declare let testDb: ReturnType<typeof createTestDb>;
@@ -0,0 +1,88 @@
1
+ import Database from 'better-sqlite3';
2
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
3
+ import * as schema from '../db/schema.js';
4
+ import { vi, beforeEach } from 'vitest';
5
+ const SQL_INIT = `
6
+ CREATE TABLE IF NOT EXISTS agents (
7
+ id TEXT PRIMARY KEY,
8
+ name TEXT UNIQUE NOT NULL,
9
+ display_name TEXT,
10
+ url TEXT NOT NULL,
11
+ status TEXT DEFAULT 'online',
12
+ agent_card TEXT,
13
+ last_heartbeat INTEGER,
14
+ created_at INTEGER DEFAULT (unixepoch() * 1000),
15
+ updated_at INTEGER
16
+ );
17
+
18
+ CREATE TABLE IF NOT EXISTS messages (
19
+ id TEXT PRIMARY KEY,
20
+ from_agent_id TEXT NOT NULL,
21
+ to_agent_id TEXT NOT NULL,
22
+ sender_type TEXT DEFAULT 'agent',
23
+ content TEXT NOT NULL,
24
+ type TEXT DEFAULT 'notification',
25
+ reply_to TEXT,
26
+ metadata TEXT,
27
+ read INTEGER DEFAULT 0,
28
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
29
+ );
30
+
31
+ CREATE TABLE IF NOT EXISTS teams (
32
+ id TEXT PRIMARY KEY,
33
+ name TEXT UNIQUE NOT NULL,
34
+ description TEXT,
35
+ color TEXT DEFAULT '#6366f1',
36
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
37
+ );
38
+
39
+ CREATE TABLE IF NOT EXISTS project_groups (
40
+ id TEXT PRIMARY KEY,
41
+ name TEXT UNIQUE NOT NULL,
42
+ description TEXT,
43
+ repository TEXT,
44
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
45
+ );
46
+
47
+ CREATE TABLE IF NOT EXISTS agent_teams (
48
+ agent_id TEXT NOT NULL REFERENCES agents(id),
49
+ team_id TEXT NOT NULL REFERENCES teams(id),
50
+ PRIMARY KEY (agent_id, team_id)
51
+ );
52
+
53
+ CREATE TABLE IF NOT EXISTS agent_projects (
54
+ agent_id TEXT NOT NULL REFERENCES agents(id),
55
+ project_id TEXT NOT NULL REFERENCES project_groups(id),
56
+ PRIMARY KEY (agent_id, project_id)
57
+ );
58
+ `;
59
+ export function createTestDb() {
60
+ const sqlite = new Database(':memory:');
61
+ sqlite.pragma('journal_mode = WAL');
62
+ sqlite.pragma('foreign_keys = ON');
63
+ sqlite.exec(SQL_INIT);
64
+ return drizzle(sqlite, { schema });
65
+ }
66
+ export let testDb;
67
+ vi.mock(import('../db/index.js'), async (importOriginal) => {
68
+ const actual = await importOriginal();
69
+ return {
70
+ ...actual,
71
+ get db() {
72
+ return testDb;
73
+ },
74
+ };
75
+ });
76
+ vi.mock('../services/ws-manager.js', () => ({
77
+ pushMessageToRecipient: vi.fn(),
78
+ broadcastAgentOnline: vi.fn(),
79
+ broadcastAgentOffline: vi.fn(),
80
+ broadcast: vi.fn(),
81
+ sendToClient: vi.fn(),
82
+ sendToDashboards: vi.fn(),
83
+ sendToDaemons: vi.fn(),
84
+ hasActiveConnections: vi.fn(() => false),
85
+ }));
86
+ beforeEach(() => {
87
+ testDb = createTestDb();
88
+ });
package/dist/app.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export { app };
package/dist/app.js ADDED
@@ -0,0 +1,41 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { Hono } from 'hono';
5
+ import { serveStatic } from '@hono/node-server/serve-static';
6
+ import { corsMiddleware } from './middleware/cors.js';
7
+ import { errorHandler } from './middleware/error-handler.js';
8
+ import { health } from './routes/health.js';
9
+ import { agentsRoute } from './routes/agents.js';
10
+ import { messagesRoute } from './routes/messages.js';
11
+ import { teamsRoute } from './routes/teams.js';
12
+ import { projectsRoute } from './routes/projects.js';
13
+ import { wellKnown } from './routes/well-known.js';
14
+ import { mcpRoute } from './mcp/transport.js';
15
+ const __dirname = resolve(fileURLToPath(import.meta.url), '..');
16
+ const webDistPath = resolve(__dirname, '../../web/dist');
17
+ const webDistExists = existsSync(webDistPath);
18
+ const app = new Hono();
19
+ app.use('*', corsMiddleware);
20
+ app.onError(errorHandler);
21
+ app.route('/', health);
22
+ app.route('/', wellKnown);
23
+ app.route('/api/agents', agentsRoute);
24
+ app.route('/api/messages', messagesRoute);
25
+ app.route('/api/teams', teamsRoute);
26
+ app.route('/api/projects', projectsRoute);
27
+ app.route('/mcp', mcpRoute);
28
+ if (webDistExists) {
29
+ app.use('*', serveStatic({ root: webDistPath }));
30
+ app.get('*', serveStatic({ root: webDistPath, path: '/index.html' }));
31
+ }
32
+ else {
33
+ app.get('/', (c) => {
34
+ return c.json({
35
+ name: 'SwarmRoom Hub',
36
+ version: '0.1.0',
37
+ description: 'Multi-agent coordination hub for local AI agents',
38
+ });
39
+ });
40
+ }
41
+ export { app };
@@ -0,0 +1,6 @@
1
+ import Database from "better-sqlite3";
2
+ import * as schema from "./schema.js";
3
+ export declare const db: import("drizzle-orm/better-sqlite3").BetterSQLite3Database<typeof schema> & {
4
+ $client: Database.Database;
5
+ };
6
+ export { agents, messages, teams, projectGroups, agentTeams, agentProjects, } from "./schema.js";
@@ -0,0 +1,62 @@
1
+ import Database from "better-sqlite3";
2
+ import { drizzle } from "drizzle-orm/better-sqlite3";
3
+ import * as schema from "./schema.js";
4
+ const sqlite = new Database("swarmroom.db");
5
+ sqlite.pragma("journal_mode = WAL");
6
+ sqlite.pragma("foreign_keys = ON");
7
+ sqlite.exec(`
8
+ CREATE TABLE IF NOT EXISTS agents (
9
+ id TEXT PRIMARY KEY,
10
+ name TEXT UNIQUE NOT NULL,
11
+ display_name TEXT,
12
+ url TEXT NOT NULL,
13
+ status TEXT DEFAULT 'online',
14
+ agent_card TEXT,
15
+ last_heartbeat INTEGER,
16
+ created_at INTEGER DEFAULT (unixepoch() * 1000),
17
+ updated_at INTEGER
18
+ );
19
+
20
+ CREATE TABLE IF NOT EXISTS messages (
21
+ id TEXT PRIMARY KEY,
22
+ from_agent_id TEXT NOT NULL,
23
+ to_agent_id TEXT NOT NULL,
24
+ sender_type TEXT DEFAULT 'agent',
25
+ content TEXT NOT NULL,
26
+ type TEXT DEFAULT 'notification',
27
+ reply_to TEXT,
28
+ metadata TEXT,
29
+ read INTEGER DEFAULT 0,
30
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
31
+ );
32
+
33
+ CREATE TABLE IF NOT EXISTS teams (
34
+ id TEXT PRIMARY KEY,
35
+ name TEXT UNIQUE NOT NULL,
36
+ description TEXT,
37
+ color TEXT DEFAULT '#6366f1',
38
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
39
+ );
40
+
41
+ CREATE TABLE IF NOT EXISTS project_groups (
42
+ id TEXT PRIMARY KEY,
43
+ name TEXT UNIQUE NOT NULL,
44
+ description TEXT,
45
+ repository TEXT,
46
+ created_at INTEGER DEFAULT (unixepoch() * 1000)
47
+ );
48
+
49
+ CREATE TABLE IF NOT EXISTS agent_teams (
50
+ agent_id TEXT NOT NULL REFERENCES agents(id),
51
+ team_id TEXT NOT NULL REFERENCES teams(id),
52
+ PRIMARY KEY (agent_id, team_id)
53
+ );
54
+
55
+ CREATE TABLE IF NOT EXISTS agent_projects (
56
+ agent_id TEXT NOT NULL REFERENCES agents(id),
57
+ project_id TEXT NOT NULL REFERENCES project_groups(id),
58
+ PRIMARY KEY (agent_id, project_id)
59
+ );
60
+ `);
61
+ export const db = drizzle(sqlite, { schema });
62
+ export { agents, messages, teams, projectGroups, agentTeams, agentProjects, } from "./schema.js";