expxagents 0.6.0 → 0.7.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/dist/__tests__/cli.test.d.ts +1 -0
- package/dist/__tests__/cli.test.js +23 -0
- package/dist/cli/src/commands/init.js +12 -2
- package/dist/cli/src/commands/virtual-office.js +50 -5
- package/dist/cli/src/utils/config.d.ts +5 -0
- package/dist/cli/src/utils/config.js +1 -1
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +34 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +58 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +16 -0
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +58 -0
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.js +173 -0
- package/dist/commands/server.d.ts +1 -0
- package/dist/commands/server.js +22 -0
- package/dist/commands/stop.d.ts +1 -0
- package/dist/commands/stop.js +23 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +12 -0
- package/dist/dashboard/assets/BufferResource-Cf2Uo4_f.js +185 -0
- package/dist/dashboard/assets/CanvasRenderer-DFdMBORe.js +1 -0
- package/dist/dashboard/assets/RenderTargetSystem-CMh8XRf_.js +172 -0
- package/dist/dashboard/assets/WebGLRenderer-B5huw0RY.js +156 -0
- package/dist/dashboard/assets/WebGPURenderer-BdIKurkV.js +41 -0
- package/dist/dashboard/assets/browserAll-BjVJrv1L.js +14 -0
- package/dist/dashboard/assets/index-DwTFo09S.js +344 -0
- package/dist/dashboard/assets/webworkerAll-DMtK63GZ.js +83 -0
- package/dist/dashboard/index.html +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +47 -0
- package/dist/server/api/health-routes.d.ts +3 -0
- package/dist/server/api/health-routes.d.ts.map +1 -0
- package/dist/server/api/health-routes.js +6 -0
- package/dist/server/api/health-routes.js.map +1 -0
- package/dist/server/api/squads-routes.d.ts +7 -0
- package/dist/server/api/squads-routes.d.ts.map +1 -0
- package/dist/server/api/squads-routes.js +91 -0
- package/dist/server/api/squads-routes.js.map +1 -0
- package/dist/server/api/users-routes.d.ts +8 -0
- package/dist/server/api/users-routes.d.ts.map +1 -0
- package/dist/server/api/users-routes.js +45 -0
- package/dist/server/api/users-routes.js.map +1 -0
- package/dist/server/app.d.ts +7 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +109 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/auth/auth-middleware.d.ts +13 -0
- package/dist/server/auth/auth-middleware.d.ts.map +1 -0
- package/dist/server/auth/auth-middleware.js +25 -0
- package/dist/server/auth/auth-middleware.js.map +1 -0
- package/dist/server/auth/auth-routes.d.ts +9 -0
- package/dist/server/auth/auth-routes.d.ts.map +1 -0
- package/dist/server/auth/auth-routes.js +149 -0
- package/dist/server/auth/auth-routes.js.map +1 -0
- package/dist/server/auth/jwt.d.ts +14 -0
- package/dist/server/auth/jwt.d.ts.map +1 -0
- package/dist/server/auth/jwt.js +16 -0
- package/dist/server/auth/jwt.js.map +1 -0
- package/dist/server/auth/password.d.ts +3 -0
- package/dist/server/auth/password.d.ts.map +1 -0
- package/dist/server/auth/password.js +9 -0
- package/dist/server/auth/password.js.map +1 -0
- package/dist/server/bridge/__tests__/chat-handler.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/chat-handler.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/chat-handler.test.js +132 -0
- package/dist/server/bridge/__tests__/chat-handler.test.js.map +1 -0
- package/dist/server/bridge/__tests__/chat-integration.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/chat-integration.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/chat-integration.test.js +141 -0
- package/dist/server/bridge/__tests__/chat-integration.test.js.map +1 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.js +223 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.js.map +1 -0
- package/dist/server/bridge/__tests__/conversation.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/conversation.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/conversation.test.js +168 -0
- package/dist/server/bridge/__tests__/conversation.test.js.map +1 -0
- package/dist/server/bridge/__tests__/stream-parser.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/stream-parser.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/stream-parser.test.js +66 -0
- package/dist/server/bridge/__tests__/stream-parser.test.js.map +1 -0
- package/dist/server/bridge/chat-handler.d.ts +19 -0
- package/dist/server/bridge/chat-handler.d.ts.map +1 -0
- package/dist/server/bridge/chat-handler.js +104 -0
- package/dist/server/bridge/chat-handler.js.map +1 -0
- package/dist/server/bridge/claude-bridge.d.ts +27 -0
- package/dist/server/bridge/claude-bridge.d.ts.map +1 -0
- package/dist/server/bridge/claude-bridge.js +91 -0
- package/dist/server/bridge/claude-bridge.js.map +1 -0
- package/dist/server/bridge/conversation.d.ts +44 -0
- package/dist/server/bridge/conversation.d.ts.map +1 -0
- package/dist/server/bridge/conversation.js +73 -0
- package/dist/server/bridge/conversation.js.map +1 -0
- package/dist/server/bridge/stream-parser.d.ts +14 -0
- package/dist/server/bridge/stream-parser.d.ts.map +1 -0
- package/dist/server/bridge/stream-parser.js +26 -0
- package/dist/server/bridge/stream-parser.js.map +1 -0
- package/dist/server/config.d.ts +10 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +22 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/db/__tests__/chat-tables.test.d.ts +2 -0
- package/dist/server/db/__tests__/chat-tables.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/chat-tables.test.js +82 -0
- package/dist/server/db/__tests__/chat-tables.test.js.map +1 -0
- package/dist/server/db/connection.d.ts +4 -0
- package/dist/server/db/connection.d.ts.map +1 -0
- package/dist/server/db/connection.js +21 -0
- package/dist/server/db/connection.js.map +1 -0
- package/dist/server/db/migrations.d.ts +4 -0
- package/dist/server/db/migrations.d.ts.map +1 -0
- package/dist/server/db/migrations.js +17 -0
- package/dist/server/db/migrations.js.map +1 -0
- package/dist/server/db/schema.d.ts +2 -0
- package/dist/server/db/schema.d.ts.map +1 -0
- package/dist/server/db/schema.js +44 -0
- package/dist/server/db/schema.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +18 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/__tests__/conversations.test.d.ts +2 -0
- package/dist/server/routes/__tests__/conversations.test.d.ts.map +1 -0
- package/dist/server/routes/__tests__/conversations.test.js +94 -0
- package/dist/server/routes/__tests__/conversations.test.js.map +1 -0
- package/dist/server/routes/conversations.d.ts +8 -0
- package/dist/server/routes/conversations.d.ts.map +1 -0
- package/dist/server/routes/conversations.js +25 -0
- package/dist/server/routes/conversations.js.map +1 -0
- package/dist/server/watcher/file-watcher.d.ts +12 -0
- package/dist/server/watcher/file-watcher.d.ts.map +1 -0
- package/dist/server/watcher/file-watcher.js +68 -0
- package/dist/server/watcher/file-watcher.js.map +1 -0
- package/dist/server/watcher/state-parser.d.ts +77 -0
- package/dist/server/watcher/state-parser.d.ts.map +1 -0
- package/dist/server/watcher/state-parser.js +74 -0
- package/dist/server/watcher/state-parser.js.map +1 -0
- package/dist/server/ws/ws-auth.d.ts +4 -0
- package/dist/server/ws/ws-auth.d.ts.map +1 -0
- package/dist/server/ws/ws-auth.js +42 -0
- package/dist/server/ws/ws-auth.js.map +1 -0
- package/dist/server/ws/ws-handler.d.ts +11 -0
- package/dist/server/ws/ws-handler.d.ts.map +1 -0
- package/dist/server/ws/ws-handler.js +107 -0
- package/dist/server/ws/ws-handler.js.map +1 -0
- package/dist/server/ws/ws-rooms.d.ts +12 -0
- package/dist/server/ws/ws-rooms.d.ts.map +1 -0
- package/dist/server/ws/ws-rooms.js +52 -0
- package/dist/server/ws/ws-rooms.js.map +1 -0
- package/dist/utils/config.d.ts +15 -0
- package/dist/utils/config.js +23 -0
- package/package.json +16 -5
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface BridgeError {
|
|
2
|
+
code: number | null;
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
export interface BridgeSendOptions {
|
|
6
|
+
prompt: string;
|
|
7
|
+
cwd: string;
|
|
8
|
+
squadName?: string;
|
|
9
|
+
agentId?: string;
|
|
10
|
+
agentName?: string;
|
|
11
|
+
onChunk: (text: string) => void;
|
|
12
|
+
onOutputChunk?: (agentId: string, agentName: string, delta: string) => void;
|
|
13
|
+
onDone: (fullText: string) => void;
|
|
14
|
+
onError: (error: BridgeError) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface BridgeConfig {
|
|
17
|
+
timeoutMs: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class ClaudeBridge {
|
|
20
|
+
private activeProcesses;
|
|
21
|
+
private timeoutMs;
|
|
22
|
+
constructor(config?: Partial<BridgeConfig>);
|
|
23
|
+
send(opts: BridgeSendOptions): void;
|
|
24
|
+
isActive(squadName: string): boolean;
|
|
25
|
+
kill(squadName: string): void;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=claude-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/claude-bridge.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAI1C,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAiFnC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAM9B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
export class ClaudeBridge {
|
|
3
|
+
activeProcesses = new Map();
|
|
4
|
+
timeoutMs;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.timeoutMs = config?.timeoutMs ?? 300_000;
|
|
7
|
+
}
|
|
8
|
+
send(opts) {
|
|
9
|
+
const key = opts.squadName ?? opts.cwd;
|
|
10
|
+
if (this.activeProcesses.has(key)) {
|
|
11
|
+
opts.onError({
|
|
12
|
+
code: null,
|
|
13
|
+
message: 'Pipeline is running — chat unavailable until pipeline completes',
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let proc;
|
|
18
|
+
try {
|
|
19
|
+
proc = spawn('claude', ['-p', '--output-format', 'text', opts.prompt], {
|
|
20
|
+
cwd: opts.cwd,
|
|
21
|
+
env: { ...process.env },
|
|
22
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
opts.onError({ code: null, message: 'Claude Code CLI not available' });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.activeProcesses.set(key, proc);
|
|
30
|
+
let stderrBuffer = '';
|
|
31
|
+
let fullText = '';
|
|
32
|
+
let settled = false;
|
|
33
|
+
let killTimer;
|
|
34
|
+
const cleanup = () => {
|
|
35
|
+
this.activeProcesses.delete(key);
|
|
36
|
+
clearTimeout(timeoutTimer);
|
|
37
|
+
clearTimeout(killTimer);
|
|
38
|
+
};
|
|
39
|
+
const timeoutTimer = setTimeout(() => {
|
|
40
|
+
if (settled)
|
|
41
|
+
return;
|
|
42
|
+
proc.kill('SIGTERM');
|
|
43
|
+
killTimer = setTimeout(() => {
|
|
44
|
+
proc.kill('SIGKILL');
|
|
45
|
+
}, 5000);
|
|
46
|
+
}, this.timeoutMs);
|
|
47
|
+
proc.stdout?.on('data', (data) => {
|
|
48
|
+
const text = data.toString('utf-8');
|
|
49
|
+
if (text.length > 0) {
|
|
50
|
+
fullText += text;
|
|
51
|
+
opts.onChunk(text);
|
|
52
|
+
if (opts.onOutputChunk && opts.agentId && opts.agentName) {
|
|
53
|
+
opts.onOutputChunk(opts.agentId, opts.agentName, text);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
proc.stderr?.on('data', (data) => {
|
|
58
|
+
stderrBuffer += data.toString('utf-8');
|
|
59
|
+
});
|
|
60
|
+
proc.on('error', (_err) => {
|
|
61
|
+
if (settled)
|
|
62
|
+
return;
|
|
63
|
+
settled = true;
|
|
64
|
+
cleanup();
|
|
65
|
+
opts.onError({ code: null, message: 'Claude Code CLI not available' });
|
|
66
|
+
});
|
|
67
|
+
proc.on('close', (code) => {
|
|
68
|
+
if (settled)
|
|
69
|
+
return;
|
|
70
|
+
settled = true;
|
|
71
|
+
cleanup();
|
|
72
|
+
if (code !== 0 && code !== null) {
|
|
73
|
+
const lastLine = stderrBuffer.trim().split('\n').pop() ?? 'Unknown error';
|
|
74
|
+
opts.onError({ code, message: `Exit code ${code}: ${lastLine}` });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
opts.onDone(fullText);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
isActive(squadName) {
|
|
82
|
+
return this.activeProcesses.has(squadName);
|
|
83
|
+
}
|
|
84
|
+
kill(squadName) {
|
|
85
|
+
const proc = this.activeProcesses.get(squadName);
|
|
86
|
+
if (proc) {
|
|
87
|
+
proc.kill('SIGTERM');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=claude-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-bridge.js","sourceRoot":"","sources":["../../src/bridge/claude-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface Conversation {
|
|
3
|
+
id: string;
|
|
4
|
+
squad_name: string;
|
|
5
|
+
created_at: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ChatMessage {
|
|
8
|
+
id: string;
|
|
9
|
+
conversation_id: string;
|
|
10
|
+
role: 'user' | 'assistant' | 'agent_dm';
|
|
11
|
+
content: string;
|
|
12
|
+
agent_id: string | null;
|
|
13
|
+
agent_name: string | null;
|
|
14
|
+
created_at: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PaginatedResult<T> {
|
|
17
|
+
data: T[];
|
|
18
|
+
nextCursor: string | null;
|
|
19
|
+
}
|
|
20
|
+
export declare function generateId(): string;
|
|
21
|
+
export declare function createConversation(db: Database.Database, squadName: string): Conversation;
|
|
22
|
+
export declare function getActiveConversation(db: Database.Database, squadName: string): Conversation | null;
|
|
23
|
+
export declare function getOrCreateConversation(db: Database.Database, squadName: string): {
|
|
24
|
+
conversation: Conversation;
|
|
25
|
+
created: boolean;
|
|
26
|
+
};
|
|
27
|
+
export interface InsertMessageParams {
|
|
28
|
+
conversationId: string;
|
|
29
|
+
role: 'user' | 'assistant' | 'agent_dm';
|
|
30
|
+
content: string;
|
|
31
|
+
agentId?: string;
|
|
32
|
+
agentName?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function insertMessage(db: Database.Database, params: InsertMessageParams): ChatMessage;
|
|
35
|
+
export declare function getMessages(db: Database.Database, conversationId: string, opts: {
|
|
36
|
+
limit: number;
|
|
37
|
+
cursor?: string;
|
|
38
|
+
}): PaginatedResult<ChatMessage>;
|
|
39
|
+
export declare function getConversations(db: Database.Database, squadName: string, opts: {
|
|
40
|
+
limit: number;
|
|
41
|
+
cursor?: string;
|
|
42
|
+
}): PaginatedResult<Conversation>;
|
|
43
|
+
export declare function getRecentMessages(db: Database.Database, conversationId: string, count: number): ChatMessage[];
|
|
44
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/bridge/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,UAAU,IAAI,MAAM,CAInC;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAOzF;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAKnG;AAED,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,GAChB;IAAE,YAAY,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAOlD;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,mBAAmB,GAAG,WAAW,CAmB7F;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,eAAe,CAAC,WAAW,CAAC,CAmB9B;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,eAAe,CAAC,YAAY,CAAC,CAmB/B;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,GACZ,WAAW,EAAE,CAKf"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { randomBytes } from 'crypto';
|
|
2
|
+
export function generateId() {
|
|
3
|
+
const now = new Date().toISOString();
|
|
4
|
+
const rand = randomBytes(6).toString('hex');
|
|
5
|
+
return `${now}-${rand}`;
|
|
6
|
+
}
|
|
7
|
+
export function createConversation(db, squadName) {
|
|
8
|
+
const id = generateId();
|
|
9
|
+
const createdAt = new Date().toISOString();
|
|
10
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run(id, squadName, createdAt);
|
|
11
|
+
return { id, squad_name: squadName, created_at: createdAt };
|
|
12
|
+
}
|
|
13
|
+
export function getActiveConversation(db, squadName) {
|
|
14
|
+
const row = db.prepare('SELECT * FROM conversations WHERE squad_name = ? ORDER BY id DESC LIMIT 1').get(squadName);
|
|
15
|
+
return row ?? null;
|
|
16
|
+
}
|
|
17
|
+
export function getOrCreateConversation(db, squadName) {
|
|
18
|
+
const existing = getActiveConversation(db, squadName);
|
|
19
|
+
if (existing) {
|
|
20
|
+
return { conversation: existing, created: false };
|
|
21
|
+
}
|
|
22
|
+
const conversation = createConversation(db, squadName);
|
|
23
|
+
return { conversation, created: true };
|
|
24
|
+
}
|
|
25
|
+
export function insertMessage(db, params) {
|
|
26
|
+
const id = generateId();
|
|
27
|
+
const createdAt = new Date().toISOString();
|
|
28
|
+
const agentId = params.agentId ?? null;
|
|
29
|
+
const agentName = params.agentName ?? null;
|
|
30
|
+
db.prepare('INSERT INTO chat_messages (id, conversation_id, role, content, agent_id, agent_name, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run(id, params.conversationId, params.role, params.content, agentId, agentName, createdAt);
|
|
31
|
+
return {
|
|
32
|
+
id,
|
|
33
|
+
conversation_id: params.conversationId,
|
|
34
|
+
role: params.role,
|
|
35
|
+
content: params.content,
|
|
36
|
+
agent_id: agentId,
|
|
37
|
+
agent_name: agentName,
|
|
38
|
+
created_at: createdAt,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function getMessages(db, conversationId, opts) {
|
|
42
|
+
const limit = opts.limit;
|
|
43
|
+
let rows;
|
|
44
|
+
if (opts.cursor) {
|
|
45
|
+
rows = db.prepare('SELECT * FROM chat_messages WHERE conversation_id = ? AND id > ? ORDER BY id ASC LIMIT ?').all(conversationId, opts.cursor, limit + 1);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
rows = db.prepare('SELECT * FROM chat_messages WHERE conversation_id = ? ORDER BY id ASC LIMIT ?').all(conversationId, limit + 1);
|
|
49
|
+
}
|
|
50
|
+
const hasMore = rows.length > limit;
|
|
51
|
+
const data = hasMore ? rows.slice(0, limit) : rows;
|
|
52
|
+
const nextCursor = hasMore ? data[data.length - 1].id : null;
|
|
53
|
+
return { data, nextCursor };
|
|
54
|
+
}
|
|
55
|
+
export function getConversations(db, squadName, opts) {
|
|
56
|
+
const limit = opts.limit;
|
|
57
|
+
let rows;
|
|
58
|
+
if (opts.cursor) {
|
|
59
|
+
rows = db.prepare('SELECT * FROM conversations WHERE squad_name = ? AND id < ? ORDER BY id DESC LIMIT ?').all(squadName, opts.cursor, limit + 1);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
rows = db.prepare('SELECT * FROM conversations WHERE squad_name = ? ORDER BY id DESC LIMIT ?').all(squadName, limit + 1);
|
|
63
|
+
}
|
|
64
|
+
const hasMore = rows.length > limit;
|
|
65
|
+
const data = hasMore ? rows.slice(0, limit) : rows;
|
|
66
|
+
const nextCursor = hasMore ? data[data.length - 1].id : null;
|
|
67
|
+
return { data, nextCursor };
|
|
68
|
+
}
|
|
69
|
+
export function getRecentMessages(db, conversationId, count) {
|
|
70
|
+
const rows = db.prepare('SELECT * FROM chat_messages WHERE conversation_id = ? ORDER BY id DESC LIMIT ?').all(conversationId, count);
|
|
71
|
+
return rows.reverse();
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/bridge/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface StreamParserOptions {
|
|
2
|
+
onChunk: (text: string) => void;
|
|
3
|
+
onDone: (fullText: string) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare class StreamParser {
|
|
6
|
+
private buffer;
|
|
7
|
+
private ended;
|
|
8
|
+
private onChunk;
|
|
9
|
+
private onDone;
|
|
10
|
+
constructor(opts: StreamParserOptions);
|
|
11
|
+
write(data: string | Buffer): void;
|
|
12
|
+
end(): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=stream-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-parser.d.ts","sourceRoot":"","sources":["../../src/bridge/stream-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,MAAM,CAA6B;gBAE/B,IAAI,EAAE,mBAAmB;IAKrC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUlC,GAAG,IAAI,IAAI;CAKZ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class StreamParser {
|
|
2
|
+
buffer = '';
|
|
3
|
+
ended = false;
|
|
4
|
+
onChunk;
|
|
5
|
+
onDone;
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
this.onChunk = opts.onChunk;
|
|
8
|
+
this.onDone = opts.onDone;
|
|
9
|
+
}
|
|
10
|
+
write(data) {
|
|
11
|
+
if (this.ended)
|
|
12
|
+
return;
|
|
13
|
+
const text = typeof data === 'string' ? data : data.toString('utf-8');
|
|
14
|
+
if (text.length === 0)
|
|
15
|
+
return;
|
|
16
|
+
this.buffer += text;
|
|
17
|
+
this.onChunk(text);
|
|
18
|
+
}
|
|
19
|
+
end() {
|
|
20
|
+
if (this.ended)
|
|
21
|
+
return;
|
|
22
|
+
this.ended = true;
|
|
23
|
+
this.onDone(this.buffer);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=stream-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-parser.js","sourceRoot":"","sources":["../../src/bridge/stream-parser.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,YAAY;IACf,MAAM,GAAW,EAAE,CAAC;IACpB,KAAK,GAAY,KAAK,CAAC;IACvB,OAAO,CAAyB;IAChC,MAAM,CAA6B;IAE3C,YAAY,IAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAqB;QACzB,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QAEvB,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE9B,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,GAAG;QACD,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAqBnC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
export function loadConfig() {
|
|
6
|
+
// Load .env — prefer DOTENV_PATH (set by CLI), fallback to project root
|
|
7
|
+
const projectRoot = path.resolve(__dirname, '..', '..');
|
|
8
|
+
const dotenvFile = process.env.DOTENV_PATH ?? path.join(projectRoot, '.env');
|
|
9
|
+
dotenv.config({ path: dotenvFile });
|
|
10
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
11
|
+
if (!jwtSecret || jwtSecret.length < 32) {
|
|
12
|
+
throw new Error('JWT_SECRET environment variable is required and must be at least 32 characters. ' +
|
|
13
|
+
'Run "npx expxagents init" to generate one.');
|
|
14
|
+
}
|
|
15
|
+
const port = parseInt(process.env.PORT || '3001', 10);
|
|
16
|
+
const corsOrigin = process.env.CORS_ORIGIN || `http://localhost:${port}`;
|
|
17
|
+
const nodeEnv = process.env.NODE_ENV || 'development';
|
|
18
|
+
const dataDir = process.env.DATA_DIR ?? path.join(__dirname, '..', 'data');
|
|
19
|
+
const squadsDir = process.env.SQUADS_DIR ?? path.resolve(projectRoot, 'squads');
|
|
20
|
+
return { port, corsOrigin, nodeEnv, jwtSecret, dataDir, squadsDir };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAW/D,MAAM,UAAU,UAAU;IACxB,wEAAwE;IACxE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC7E,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACzC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,kFAAkF;YAClF,4CAA4C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,oBAAoB,IAAI,EAAE,CAAC;IACzE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAEhF,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-tables.test.d.ts","sourceRoot":"","sources":["../../../src/db/__tests__/chat-tables.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import Database from 'better-sqlite3';
|
|
3
|
+
function createTestDb() {
|
|
4
|
+
const db = new Database(':memory:');
|
|
5
|
+
db.pragma('journal_mode = WAL');
|
|
6
|
+
db.exec(`
|
|
7
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
squad_name TEXT NOT NULL,
|
|
10
|
+
created_at TEXT NOT NULL
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE TABLE IF NOT EXISTS chat_messages (
|
|
14
|
+
id TEXT PRIMARY KEY,
|
|
15
|
+
conversation_id TEXT NOT NULL REFERENCES conversations(id),
|
|
16
|
+
role TEXT NOT NULL,
|
|
17
|
+
content TEXT NOT NULL,
|
|
18
|
+
agent_id TEXT,
|
|
19
|
+
agent_name TEXT,
|
|
20
|
+
created_at TEXT NOT NULL
|
|
21
|
+
);
|
|
22
|
+
`);
|
|
23
|
+
return db;
|
|
24
|
+
}
|
|
25
|
+
describe('chat tables', () => {
|
|
26
|
+
let db;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
db = createTestDb();
|
|
29
|
+
});
|
|
30
|
+
it('should insert and retrieve a conversation', () => {
|
|
31
|
+
const id = '2026-03-13T10:00:00Z-abc123';
|
|
32
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run(id, 'content-team', '2026-03-13T10:00:00Z');
|
|
33
|
+
const row = db.prepare('SELECT * FROM conversations WHERE id = ?').get(id);
|
|
34
|
+
expect(row.id).toBe(id);
|
|
35
|
+
expect(row.squad_name).toBe('content-team');
|
|
36
|
+
});
|
|
37
|
+
it('should insert and retrieve chat messages', () => {
|
|
38
|
+
const convId = '2026-03-13T10:00:00Z-conv1';
|
|
39
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run(convId, 'content-team', '2026-03-13T10:00:00Z');
|
|
40
|
+
const msgId = '2026-03-13T10:00:01Z-msg1';
|
|
41
|
+
db.prepare('INSERT INTO chat_messages (id, conversation_id, role, content, agent_id, agent_name, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run(msgId, convId, 'user', 'Hello', null, null, '2026-03-13T10:00:01Z');
|
|
42
|
+
const msg = db.prepare('SELECT * FROM chat_messages WHERE id = ?').get(msgId);
|
|
43
|
+
expect(msg.role).toBe('user');
|
|
44
|
+
expect(msg.content).toBe('Hello');
|
|
45
|
+
expect(msg.conversation_id).toBe(convId);
|
|
46
|
+
});
|
|
47
|
+
it('should insert agent_dm messages with agent metadata', () => {
|
|
48
|
+
const convId = '2026-03-13T10:00:00Z-conv2';
|
|
49
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run(convId, 'content-team', '2026-03-13T10:00:00Z');
|
|
50
|
+
const msgId = '2026-03-13T10:00:02Z-dm1';
|
|
51
|
+
db.prepare('INSERT INTO chat_messages (id, conversation_id, role, content, agent_id, agent_name, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run(msgId, convId, 'agent_dm', 'Found 5 topics', 'researcher', 'Researcher', '2026-03-13T10:00:02Z');
|
|
52
|
+
const msg = db.prepare('SELECT * FROM chat_messages WHERE id = ?').get(msgId);
|
|
53
|
+
expect(msg.role).toBe('agent_dm');
|
|
54
|
+
expect(msg.agent_id).toBe('researcher');
|
|
55
|
+
expect(msg.agent_name).toBe('Researcher');
|
|
56
|
+
});
|
|
57
|
+
it('should list conversations newest-first by id', () => {
|
|
58
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run('2026-03-13T10:00:00Z-aaa', 'content-team', '2026-03-13T10:00:00Z');
|
|
59
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run('2026-03-13T11:00:00Z-bbb', 'content-team', '2026-03-13T11:00:00Z');
|
|
60
|
+
const rows = db.prepare('SELECT * FROM conversations WHERE squad_name = ? ORDER BY id DESC').all('content-team');
|
|
61
|
+
expect(rows[0].id).toBe('2026-03-13T11:00:00Z-bbb');
|
|
62
|
+
expect(rows[1].id).toBe('2026-03-13T10:00:00Z-aaa');
|
|
63
|
+
});
|
|
64
|
+
it('should list messages oldest-first by id with cursor pagination', () => {
|
|
65
|
+
const convId = '2026-03-13T10:00:00Z-conv3';
|
|
66
|
+
db.prepare('INSERT INTO conversations (id, squad_name, created_at) VALUES (?, ?, ?)').run(convId, 'content-team', '2026-03-13T10:00:00Z');
|
|
67
|
+
for (let i = 1; i <= 5; i++) {
|
|
68
|
+
const ts = `2026-03-13T10:00:0${i}Z`;
|
|
69
|
+
db.prepare('INSERT INTO chat_messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)').run(`${ts}-m${i}`, convId, 'user', `msg ${i}`, ts);
|
|
70
|
+
}
|
|
71
|
+
// First page (limit 2)
|
|
72
|
+
const page1 = db.prepare('SELECT * FROM chat_messages WHERE conversation_id = ? ORDER BY id ASC LIMIT ?').all(convId, 2);
|
|
73
|
+
expect(page1).toHaveLength(2);
|
|
74
|
+
expect(page1[0].content).toBe('msg 1');
|
|
75
|
+
// Second page using cursor
|
|
76
|
+
const cursor = page1[1].id;
|
|
77
|
+
const page2 = db.prepare('SELECT * FROM chat_messages WHERE conversation_id = ? AND id > ? ORDER BY id ASC LIMIT ?').all(convId, cursor, 2);
|
|
78
|
+
expect(page2).toHaveLength(2);
|
|
79
|
+
expect(page2[0].content).toBe('msg 3');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=chat-tables.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-tables.test.js","sourceRoot":"","sources":["../../../src/db/__tests__/chat-tables.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAOtC,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAUxD;AAED,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { runMigrations } from './migrations.js';
|
|
5
|
+
let db = null;
|
|
6
|
+
export function getDb(dataDir) {
|
|
7
|
+
if (db)
|
|
8
|
+
return db;
|
|
9
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
10
|
+
const dbPath = path.join(dataDir, 'opensquad.db');
|
|
11
|
+
db = new Database(dbPath);
|
|
12
|
+
runMigrations(db);
|
|
13
|
+
return db;
|
|
14
|
+
}
|
|
15
|
+
export function closeDb() {
|
|
16
|
+
if (db) {
|
|
17
|
+
db.close();
|
|
18
|
+
db = null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,IAAI,EAAE,GAA6B,IAAI,CAAC;AAExC,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAElD,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAIzD;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import bcrypt from 'bcrypt';
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import { SCHEMA_SQL } from './schema.js';
|
|
4
|
+
export function runMigrations(db) {
|
|
5
|
+
db.pragma('journal_mode = WAL');
|
|
6
|
+
db.pragma('foreign_keys = ON');
|
|
7
|
+
db.exec(SCHEMA_SQL);
|
|
8
|
+
}
|
|
9
|
+
export async function seedDefaultAdmin(db) {
|
|
10
|
+
const existing = db.prepare('SELECT id FROM users WHERE username = ?').get('admin');
|
|
11
|
+
if (existing)
|
|
12
|
+
return;
|
|
13
|
+
const id = crypto.randomUUID();
|
|
14
|
+
const hash = await bcrypt.hash('admin', 12);
|
|
15
|
+
db.prepare('INSERT INTO users (id, username, email, password_hash, role, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(id, 'admin', null, hash, 'admin', new Date().toISOString());
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAqB;IAC1D,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpF,IAAI,QAAQ;QAAE,OAAO;IAErB,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC5C,EAAE,CAAC,OAAO,CACR,oGAAoG,CACrG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n username TEXT UNIQUE NOT NULL,\n email TEXT,\n password_hash TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'operator',\n created_at TEXT NOT NULL,\n last_login TEXT\n);\n\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n token_hash TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS audit_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id TEXT NOT NULL REFERENCES users(id),\n action TEXT NOT NULL,\n details TEXT,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n squad_name TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS chat_messages (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL REFERENCES conversations(id),\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n agent_id TEXT,\n agent_name TEXT,\n created_at TEXT NOT NULL\n);\n";
|
|
2
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,yhCA0CtB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const SCHEMA_SQL = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
3
|
+
id TEXT PRIMARY KEY,
|
|
4
|
+
username TEXT UNIQUE NOT NULL,
|
|
5
|
+
email TEXT,
|
|
6
|
+
password_hash TEXT NOT NULL,
|
|
7
|
+
role TEXT NOT NULL DEFAULT 'operator',
|
|
8
|
+
created_at TEXT NOT NULL,
|
|
9
|
+
last_login TEXT
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
15
|
+
token_hash TEXT NOT NULL,
|
|
16
|
+
expires_at TEXT NOT NULL,
|
|
17
|
+
created_at TEXT NOT NULL
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
21
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
user_id TEXT NOT NULL REFERENCES users(id),
|
|
23
|
+
action TEXT NOT NULL,
|
|
24
|
+
details TEXT,
|
|
25
|
+
created_at TEXT NOT NULL
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
29
|
+
id TEXT PRIMARY KEY,
|
|
30
|
+
squad_name TEXT NOT NULL,
|
|
31
|
+
created_at TEXT NOT NULL
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS chat_messages (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
conversation_id TEXT NOT NULL REFERENCES conversations(id),
|
|
37
|
+
role TEXT NOT NULL,
|
|
38
|
+
content TEXT NOT NULL,
|
|
39
|
+
agent_id TEXT,
|
|
40
|
+
agent_name TEXT,
|
|
41
|
+
created_at TEXT NOT NULL
|
|
42
|
+
);
|
|
43
|
+
`;
|
|
44
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { loadConfig } from './config.js';
|
|
2
|
+
import { closeDb } from './db/connection.js';
|
|
3
|
+
import { buildApp } from './app.js';
|
|
4
|
+
const config = loadConfig();
|
|
5
|
+
const app = await buildApp();
|
|
6
|
+
// Graceful shutdown
|
|
7
|
+
const shutdown = async (signal) => {
|
|
8
|
+
app.log.info(`Received ${signal}, shutting down...`);
|
|
9
|
+
await app.close();
|
|
10
|
+
closeDb();
|
|
11
|
+
process.exit(0);
|
|
12
|
+
};
|
|
13
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
14
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
15
|
+
// Start
|
|
16
|
+
await app.listen({ port: config.port, host: '0.0.0.0' });
|
|
17
|
+
app.log.info(`Server listening on port ${config.port}`);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAC5B,MAAM,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;AAE7B,oBAAoB;AACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;IACxC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,MAAM,oBAAoB,CAAC,CAAC;IACrD,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAClB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE/C,QAAQ;AACR,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AACzD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.test.d.ts","sourceRoot":"","sources":["../../../src/routes/__tests__/conversations.test.ts"],"names":[],"mappings":""}
|