@blackms/aistack 1.0.13 → 1.2.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.
- package/README.md +16 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/web.d.ts +6 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +79 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.ts +23 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +54 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/sqlite-store.d.ts +26 -1
- package/dist/memory/sqlite-store.d.ts.map +1 -1
- package/dist/memory/sqlite-store.js +356 -0
- package/dist/memory/sqlite-store.js.map +1 -1
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/validation.d.ts +2 -2
- package/dist/web/index.d.ts +8 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +8 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/middleware/auth.d.ts +21 -0
- package/dist/web/middleware/auth.d.ts.map +1 -0
- package/dist/web/middleware/auth.js +31 -0
- package/dist/web/middleware/auth.js.map +1 -0
- package/dist/web/middleware/cors.d.ts +7 -0
- package/dist/web/middleware/cors.d.ts.map +1 -0
- package/dist/web/middleware/cors.js +28 -0
- package/dist/web/middleware/cors.js.map +1 -0
- package/dist/web/middleware/error.d.ts +16 -0
- package/dist/web/middleware/error.d.ts.map +1 -0
- package/dist/web/middleware/error.js +51 -0
- package/dist/web/middleware/error.js.map +1 -0
- package/dist/web/middleware/index.d.ts +7 -0
- package/dist/web/middleware/index.d.ts.map +1 -0
- package/dist/web/middleware/index.js +7 -0
- package/dist/web/middleware/index.js.map +1 -0
- package/dist/web/router.d.ts +40 -0
- package/dist/web/router.d.ts.map +1 -0
- package/dist/web/router.js +162 -0
- package/dist/web/router.js.map +1 -0
- package/dist/web/routes/agents.d.ts +7 -0
- package/dist/web/routes/agents.d.ts.map +1 -0
- package/dist/web/routes/agents.js +182 -0
- package/dist/web/routes/agents.js.map +1 -0
- package/dist/web/routes/filesystem.d.ts +7 -0
- package/dist/web/routes/filesystem.d.ts.map +1 -0
- package/dist/web/routes/filesystem.js +212 -0
- package/dist/web/routes/filesystem.js.map +1 -0
- package/dist/web/routes/index.d.ts +13 -0
- package/dist/web/routes/index.d.ts.map +1 -0
- package/dist/web/routes/index.js +13 -0
- package/dist/web/routes/index.js.map +1 -0
- package/dist/web/routes/memory.d.ts +7 -0
- package/dist/web/routes/memory.d.ts.map +1 -0
- package/dist/web/routes/memory.js +146 -0
- package/dist/web/routes/memory.js.map +1 -0
- package/dist/web/routes/projects.d.ts +7 -0
- package/dist/web/routes/projects.d.ts.map +1 -0
- package/dist/web/routes/projects.js +296 -0
- package/dist/web/routes/projects.js.map +1 -0
- package/dist/web/routes/sessions.d.ts +7 -0
- package/dist/web/routes/sessions.d.ts.map +1 -0
- package/dist/web/routes/sessions.js +75 -0
- package/dist/web/routes/sessions.js.map +1 -0
- package/dist/web/routes/specifications.d.ts +7 -0
- package/dist/web/routes/specifications.d.ts.map +1 -0
- package/dist/web/routes/specifications.js +267 -0
- package/dist/web/routes/specifications.js.map +1 -0
- package/dist/web/routes/system.d.ts +7 -0
- package/dist/web/routes/system.d.ts.map +1 -0
- package/dist/web/routes/system.js +147 -0
- package/dist/web/routes/system.js.map +1 -0
- package/dist/web/routes/tasks.d.ts +7 -0
- package/dist/web/routes/tasks.d.ts.map +1 -0
- package/dist/web/routes/tasks.js +188 -0
- package/dist/web/routes/tasks.js.map +1 -0
- package/dist/web/routes/workflows.d.ts +7 -0
- package/dist/web/routes/workflows.d.ts.map +1 -0
- package/dist/web/routes/workflows.js +132 -0
- package/dist/web/routes/workflows.js.map +1 -0
- package/dist/web/server.d.ts +49 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +236 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/types.d.ts +191 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +5 -0
- package/dist/web/types.js.map +1 -0
- package/dist/web/websocket/event-bridge.d.ts +115 -0
- package/dist/web/websocket/event-bridge.d.ts.map +1 -0
- package/dist/web/websocket/event-bridge.js +138 -0
- package/dist/web/websocket/event-bridge.js.map +1 -0
- package/dist/web/websocket/handler.d.ts +23 -0
- package/dist/web/websocket/handler.d.ts.map +1 -0
- package/dist/web/websocket/handler.js +282 -0
- package/dist/web/websocket/handler.js.map +1 -0
- package/dist/web/websocket/index.d.ts +6 -0
- package/dist/web/websocket/index.d.ts.map +1 -0
- package/dist/web/websocket/index.js +6 -0
- package/dist/web/websocket/index.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event bridge - connects internal EventEmitters to WebSocket clients
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
export declare const agentEvents: EventEmitter<[never]>;
|
|
6
|
+
export interface AgentSpawnedEvent {
|
|
7
|
+
id: string;
|
|
8
|
+
type: string;
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AgentStoppedEvent {
|
|
12
|
+
id: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AgentStatusEvent {
|
|
15
|
+
id: string;
|
|
16
|
+
status: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TaskCreatedEvent {
|
|
19
|
+
task: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface TaskAssignedEvent {
|
|
22
|
+
taskId: string;
|
|
23
|
+
agentId: string;
|
|
24
|
+
}
|
|
25
|
+
export interface TaskCompletedEvent {
|
|
26
|
+
taskId: string;
|
|
27
|
+
result?: unknown;
|
|
28
|
+
}
|
|
29
|
+
export interface WorkflowStartEvent {
|
|
30
|
+
workflowId: string;
|
|
31
|
+
config: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface WorkflowPhaseEvent {
|
|
34
|
+
workflowId: string;
|
|
35
|
+
phase: string;
|
|
36
|
+
status: string;
|
|
37
|
+
}
|
|
38
|
+
export interface WorkflowCompleteEvent {
|
|
39
|
+
workflowId: string;
|
|
40
|
+
report: unknown;
|
|
41
|
+
}
|
|
42
|
+
export interface WorkflowErrorEvent {
|
|
43
|
+
workflowId: string;
|
|
44
|
+
error: string;
|
|
45
|
+
}
|
|
46
|
+
export interface MessageReceivedEvent {
|
|
47
|
+
from: string;
|
|
48
|
+
to: string;
|
|
49
|
+
content: string;
|
|
50
|
+
}
|
|
51
|
+
export interface ProjectCreatedEvent {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
path: string;
|
|
55
|
+
}
|
|
56
|
+
export interface ProjectUpdatedEvent {
|
|
57
|
+
id: string;
|
|
58
|
+
changes: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
export interface ProjectTaskCreatedEvent {
|
|
61
|
+
projectId: string;
|
|
62
|
+
taskId: string;
|
|
63
|
+
title: string;
|
|
64
|
+
}
|
|
65
|
+
export interface ProjectTaskPhaseEvent {
|
|
66
|
+
projectId: string;
|
|
67
|
+
taskId: string;
|
|
68
|
+
fromPhase: string;
|
|
69
|
+
toPhase: string;
|
|
70
|
+
}
|
|
71
|
+
export interface SpecCreatedEvent {
|
|
72
|
+
id: string;
|
|
73
|
+
taskId: string;
|
|
74
|
+
type: string;
|
|
75
|
+
title: string;
|
|
76
|
+
}
|
|
77
|
+
export interface SpecStatusEvent {
|
|
78
|
+
id: string;
|
|
79
|
+
status: string;
|
|
80
|
+
reviewedBy?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface AgentProgressEvent {
|
|
83
|
+
agentId: string;
|
|
84
|
+
taskId: string;
|
|
85
|
+
progress: number;
|
|
86
|
+
message?: string;
|
|
87
|
+
}
|
|
88
|
+
export type EventName = 'agent:spawned' | 'agent:stopped' | 'agent:status' | 'agent:progress' | 'task:created' | 'task:assigned' | 'task:completed' | 'workflow:start' | 'workflow:phase' | 'workflow:complete' | 'workflow:error' | 'workflow:finding' | 'message:received' | 'project:created' | 'project:updated' | 'project:task:created' | 'project:task:phase' | 'spec:created' | 'spec:status';
|
|
89
|
+
export declare class EventBridge {
|
|
90
|
+
private listeners;
|
|
91
|
+
constructor();
|
|
92
|
+
/**
|
|
93
|
+
* Subscribe to all events
|
|
94
|
+
*/
|
|
95
|
+
subscribe(callback: (event: string, data: unknown) => void): () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Subscribe to specific event
|
|
98
|
+
*/
|
|
99
|
+
subscribeToEvent(event: string, callback: (data: unknown) => void): () => void;
|
|
100
|
+
/**
|
|
101
|
+
* Broadcast event to all subscribers
|
|
102
|
+
*/
|
|
103
|
+
broadcast(event: string, data: unknown): void;
|
|
104
|
+
/**
|
|
105
|
+
* Get subscriber count for an event
|
|
106
|
+
*/
|
|
107
|
+
getSubscriberCount(event?: string): number;
|
|
108
|
+
/**
|
|
109
|
+
* Clear all listeners
|
|
110
|
+
*/
|
|
111
|
+
clear(): void;
|
|
112
|
+
}
|
|
113
|
+
export declare function getEventBridge(): EventBridge;
|
|
114
|
+
export declare function resetEventBridge(): void;
|
|
115
|
+
//# sourceMappingURL=event-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bridge.d.ts","sourceRoot":"","sources":["../../../src/web/websocket/event-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event bridge - connects internal EventEmitters to WebSocket clients
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
const log = logger.child('web:events');
|
|
7
|
+
// Agent events emitter - used by routes to emit events
|
|
8
|
+
export const agentEvents = new EventEmitter();
|
|
9
|
+
// Event bridge class for managing WebSocket subscriptions
|
|
10
|
+
export class EventBridge {
|
|
11
|
+
listeners = new Map();
|
|
12
|
+
constructor() {
|
|
13
|
+
// Wire up all agent events to broadcast
|
|
14
|
+
const events = [
|
|
15
|
+
'agent:spawned',
|
|
16
|
+
'agent:stopped',
|
|
17
|
+
'agent:status',
|
|
18
|
+
'agent:progress',
|
|
19
|
+
'task:created',
|
|
20
|
+
'task:assigned',
|
|
21
|
+
'task:completed',
|
|
22
|
+
'workflow:start',
|
|
23
|
+
'workflow:phase',
|
|
24
|
+
'workflow:complete',
|
|
25
|
+
'workflow:error',
|
|
26
|
+
'workflow:finding',
|
|
27
|
+
'message:received',
|
|
28
|
+
'project:created',
|
|
29
|
+
'project:updated',
|
|
30
|
+
'project:task:created',
|
|
31
|
+
'project:task:phase',
|
|
32
|
+
'spec:created',
|
|
33
|
+
'spec:status',
|
|
34
|
+
];
|
|
35
|
+
for (const event of events) {
|
|
36
|
+
agentEvents.on(event, (data) => {
|
|
37
|
+
this.broadcast(event, data);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to all events
|
|
43
|
+
*/
|
|
44
|
+
subscribe(callback) {
|
|
45
|
+
const wrappedCallback = (data) => callback('*', data);
|
|
46
|
+
// Subscribe to all events
|
|
47
|
+
if (!this.listeners.has('*')) {
|
|
48
|
+
this.listeners.set('*', new Set());
|
|
49
|
+
}
|
|
50
|
+
this.listeners.get('*').add(wrappedCallback);
|
|
51
|
+
// Return unsubscribe function
|
|
52
|
+
return () => {
|
|
53
|
+
this.listeners.get('*')?.delete(wrappedCallback);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Subscribe to specific event
|
|
58
|
+
*/
|
|
59
|
+
subscribeToEvent(event, callback) {
|
|
60
|
+
if (!this.listeners.has(event)) {
|
|
61
|
+
this.listeners.set(event, new Set());
|
|
62
|
+
}
|
|
63
|
+
this.listeners.get(event).add(callback);
|
|
64
|
+
return () => {
|
|
65
|
+
this.listeners.get(event)?.delete(callback);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Broadcast event to all subscribers
|
|
70
|
+
*/
|
|
71
|
+
broadcast(event, data) {
|
|
72
|
+
log.debug('Broadcasting event', { event });
|
|
73
|
+
// Notify event-specific listeners
|
|
74
|
+
const eventListeners = this.listeners.get(event);
|
|
75
|
+
if (eventListeners) {
|
|
76
|
+
for (const listener of eventListeners) {
|
|
77
|
+
try {
|
|
78
|
+
listener(data);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
log.error('Error in event listener', {
|
|
82
|
+
event,
|
|
83
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Notify wildcard listeners
|
|
89
|
+
const wildcardListeners = this.listeners.get('*');
|
|
90
|
+
if (wildcardListeners) {
|
|
91
|
+
for (const listener of wildcardListeners) {
|
|
92
|
+
try {
|
|
93
|
+
listener({ event, data });
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
log.error('Error in wildcard listener', {
|
|
97
|
+
event,
|
|
98
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get subscriber count for an event
|
|
106
|
+
*/
|
|
107
|
+
getSubscriberCount(event) {
|
|
108
|
+
if (event) {
|
|
109
|
+
return this.listeners.get(event)?.size ?? 0;
|
|
110
|
+
}
|
|
111
|
+
let total = 0;
|
|
112
|
+
for (const listeners of this.listeners.values()) {
|
|
113
|
+
total += listeners.size;
|
|
114
|
+
}
|
|
115
|
+
return total;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Clear all listeners
|
|
119
|
+
*/
|
|
120
|
+
clear() {
|
|
121
|
+
this.listeners.clear();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Singleton instance
|
|
125
|
+
let eventBridge = null;
|
|
126
|
+
export function getEventBridge() {
|
|
127
|
+
if (!eventBridge) {
|
|
128
|
+
eventBridge = new EventBridge();
|
|
129
|
+
}
|
|
130
|
+
return eventBridge;
|
|
131
|
+
}
|
|
132
|
+
export function resetEventBridge() {
|
|
133
|
+
if (eventBridge) {
|
|
134
|
+
eventBridge.clear();
|
|
135
|
+
eventBridge = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=event-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bridge.js","sourceRoot":"","sources":["../../../src/web/websocket/event-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket handler
|
|
3
|
+
*/
|
|
4
|
+
import type { IncomingMessage } from 'node:http';
|
|
5
|
+
import type { Duplex } from 'node:stream';
|
|
6
|
+
import type { WSMessage } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle WebSocket upgrade request
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleWebSocketUpgrade(req: IncomingMessage, socket: Duplex, _head: Buffer): void;
|
|
11
|
+
/**
|
|
12
|
+
* Get connected client count
|
|
13
|
+
*/
|
|
14
|
+
export declare function getClientCount(): number;
|
|
15
|
+
/**
|
|
16
|
+
* Broadcast message to all clients
|
|
17
|
+
*/
|
|
18
|
+
export declare function broadcastMessage(message: WSMessage): void;
|
|
19
|
+
/**
|
|
20
|
+
* Close all connections
|
|
21
|
+
*/
|
|
22
|
+
export declare function closeAllConnections(): void;
|
|
23
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/web/websocket/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,aAAa,CAAC;AAW3D;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CAkHN;AAoKD;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAIzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket handler
|
|
3
|
+
*/
|
|
4
|
+
import { randomUUID, createHash } from 'node:crypto';
|
|
5
|
+
import { logger } from '../../utils/logger.js';
|
|
6
|
+
import { getEventBridge } from './event-bridge.js';
|
|
7
|
+
const log = logger.child('web:websocket');
|
|
8
|
+
// WebSocket client connections
|
|
9
|
+
const clients = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Handle WebSocket upgrade request
|
|
12
|
+
*/
|
|
13
|
+
export function handleWebSocketUpgrade(req, socket, _head) {
|
|
14
|
+
// Verify WebSocket upgrade request
|
|
15
|
+
const upgradeHeader = req.headers.upgrade?.toLowerCase();
|
|
16
|
+
if (upgradeHeader !== 'websocket') {
|
|
17
|
+
socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
|
|
18
|
+
socket.destroy();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Get WebSocket key
|
|
22
|
+
const wsKey = req.headers['sec-websocket-key'];
|
|
23
|
+
if (!wsKey) {
|
|
24
|
+
socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
|
|
25
|
+
socket.destroy();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Calculate accept key
|
|
29
|
+
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
|
30
|
+
const acceptKey = createHash('sha1')
|
|
31
|
+
.update(wsKey + GUID)
|
|
32
|
+
.digest('base64');
|
|
33
|
+
// Send upgrade response
|
|
34
|
+
const response = [
|
|
35
|
+
'HTTP/1.1 101 Switching Protocols',
|
|
36
|
+
'Upgrade: websocket',
|
|
37
|
+
'Connection: Upgrade',
|
|
38
|
+
`Sec-WebSocket-Accept: ${acceptKey}`,
|
|
39
|
+
'',
|
|
40
|
+
'',
|
|
41
|
+
].join('\r\n');
|
|
42
|
+
socket.write(response);
|
|
43
|
+
// Create client info
|
|
44
|
+
const clientId = randomUUID();
|
|
45
|
+
const clientInfo = {
|
|
46
|
+
id: clientId,
|
|
47
|
+
connectedAt: new Date(),
|
|
48
|
+
subscriptions: new Set(['*']), // Subscribe to all by default
|
|
49
|
+
};
|
|
50
|
+
// Subscribe to events
|
|
51
|
+
const eventBridge = getEventBridge();
|
|
52
|
+
const unsubscribe = eventBridge.subscribe((event, data) => {
|
|
53
|
+
sendMessage(socket, {
|
|
54
|
+
type: event,
|
|
55
|
+
payload: data,
|
|
56
|
+
timestamp: new Date().toISOString(),
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
// Store client
|
|
60
|
+
clients.set(clientId, { socket, info: clientInfo, unsubscribe });
|
|
61
|
+
log.info('WebSocket client connected', { clientId });
|
|
62
|
+
// Handle incoming data
|
|
63
|
+
let buffer = Buffer.alloc(0);
|
|
64
|
+
socket.on('data', (chunk) => {
|
|
65
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
66
|
+
// Try to parse frames
|
|
67
|
+
while (buffer.length >= 2) {
|
|
68
|
+
const frame = parseWebSocketFrame(buffer);
|
|
69
|
+
if (!frame)
|
|
70
|
+
break;
|
|
71
|
+
buffer = buffer.subarray(frame.totalLength);
|
|
72
|
+
// Handle frame
|
|
73
|
+
if (frame.opcode === 0x8) {
|
|
74
|
+
// Close frame
|
|
75
|
+
log.info('WebSocket client disconnected (close frame)', { clientId });
|
|
76
|
+
cleanupClient(clientId);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (frame.opcode === 0x9) {
|
|
80
|
+
// Ping - send pong
|
|
81
|
+
const pongFrame = createWebSocketFrame(0xa, frame.payload);
|
|
82
|
+
socket.write(pongFrame);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (frame.opcode === 0xa) {
|
|
86
|
+
// Pong - ignore
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (frame.opcode === 0x1 || frame.opcode === 0x2) {
|
|
90
|
+
// Text or binary frame
|
|
91
|
+
handleClientMessage(clientId, frame.payload.toString('utf-8'));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
socket.on('close', () => {
|
|
96
|
+
log.info('WebSocket client disconnected (socket close)', { clientId });
|
|
97
|
+
cleanupClient(clientId);
|
|
98
|
+
});
|
|
99
|
+
socket.on('error', (error) => {
|
|
100
|
+
log.error('WebSocket error', { clientId, error: error.message });
|
|
101
|
+
cleanupClient(clientId);
|
|
102
|
+
});
|
|
103
|
+
// Send welcome message
|
|
104
|
+
sendMessage(socket, {
|
|
105
|
+
type: 'connected',
|
|
106
|
+
payload: { clientId },
|
|
107
|
+
timestamp: new Date().toISOString(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse WebSocket frame
|
|
112
|
+
*/
|
|
113
|
+
function parseWebSocketFrame(buffer) {
|
|
114
|
+
if (buffer.length < 2)
|
|
115
|
+
return null;
|
|
116
|
+
const firstByte = buffer[0];
|
|
117
|
+
const secondByte = buffer[1];
|
|
118
|
+
const opcode = firstByte & 0x0f;
|
|
119
|
+
const masked = (secondByte & 0x80) !== 0;
|
|
120
|
+
let payloadLength = secondByte & 0x7f;
|
|
121
|
+
let offset = 2;
|
|
122
|
+
// Extended payload length
|
|
123
|
+
if (payloadLength === 126) {
|
|
124
|
+
if (buffer.length < 4)
|
|
125
|
+
return null;
|
|
126
|
+
payloadLength = buffer.readUInt16BE(2);
|
|
127
|
+
offset = 4;
|
|
128
|
+
}
|
|
129
|
+
else if (payloadLength === 127) {
|
|
130
|
+
if (buffer.length < 10)
|
|
131
|
+
return null;
|
|
132
|
+
// For simplicity, we'll only handle 32-bit lengths
|
|
133
|
+
payloadLength = buffer.readUInt32BE(6);
|
|
134
|
+
offset = 10;
|
|
135
|
+
}
|
|
136
|
+
// Masking key
|
|
137
|
+
let maskingKey = null;
|
|
138
|
+
if (masked) {
|
|
139
|
+
if (buffer.length < offset + 4)
|
|
140
|
+
return null;
|
|
141
|
+
maskingKey = buffer.subarray(offset, offset + 4);
|
|
142
|
+
offset += 4;
|
|
143
|
+
}
|
|
144
|
+
// Payload
|
|
145
|
+
if (buffer.length < offset + payloadLength)
|
|
146
|
+
return null;
|
|
147
|
+
let payload = buffer.subarray(offset, offset + payloadLength);
|
|
148
|
+
// Unmask if needed
|
|
149
|
+
if (maskingKey) {
|
|
150
|
+
const unmasked = Buffer.alloc(payloadLength);
|
|
151
|
+
for (let i = 0; i < payloadLength; i++) {
|
|
152
|
+
unmasked[i] = payload[i] ^ maskingKey[i % 4];
|
|
153
|
+
}
|
|
154
|
+
payload = unmasked;
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
opcode,
|
|
158
|
+
payload,
|
|
159
|
+
totalLength: offset + payloadLength,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create WebSocket frame
|
|
164
|
+
*/
|
|
165
|
+
function createWebSocketFrame(opcode, payload) {
|
|
166
|
+
const payloadLength = payload.length;
|
|
167
|
+
let header;
|
|
168
|
+
if (payloadLength < 126) {
|
|
169
|
+
header = Buffer.alloc(2);
|
|
170
|
+
header[0] = 0x80 | opcode; // FIN + opcode
|
|
171
|
+
header[1] = payloadLength;
|
|
172
|
+
}
|
|
173
|
+
else if (payloadLength < 65536) {
|
|
174
|
+
header = Buffer.alloc(4);
|
|
175
|
+
header[0] = 0x80 | opcode;
|
|
176
|
+
header[1] = 126;
|
|
177
|
+
header.writeUInt16BE(payloadLength, 2);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
header = Buffer.alloc(10);
|
|
181
|
+
header[0] = 0x80 | opcode;
|
|
182
|
+
header[1] = 127;
|
|
183
|
+
header.writeUInt32BE(0, 2);
|
|
184
|
+
header.writeUInt32BE(payloadLength, 6);
|
|
185
|
+
}
|
|
186
|
+
return Buffer.concat([header, payload]);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Send message to WebSocket client
|
|
190
|
+
*/
|
|
191
|
+
function sendMessage(socket, message) {
|
|
192
|
+
try {
|
|
193
|
+
const payload = Buffer.from(JSON.stringify(message), 'utf-8');
|
|
194
|
+
const frame = createWebSocketFrame(0x1, payload); // 0x1 = text frame
|
|
195
|
+
socket.write(frame);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
log.error('Failed to send WebSocket message', {
|
|
199
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Handle message from client
|
|
205
|
+
*/
|
|
206
|
+
function handleClientMessage(clientId, message) {
|
|
207
|
+
const client = clients.get(clientId);
|
|
208
|
+
if (!client)
|
|
209
|
+
return;
|
|
210
|
+
try {
|
|
211
|
+
const parsed = JSON.parse(message);
|
|
212
|
+
// Handle subscription changes
|
|
213
|
+
if (parsed.type === 'subscribe') {
|
|
214
|
+
const events = parsed.events;
|
|
215
|
+
if (Array.isArray(events)) {
|
|
216
|
+
for (const event of events) {
|
|
217
|
+
client.info.subscriptions.add(event);
|
|
218
|
+
}
|
|
219
|
+
log.debug('Client subscribed to events', { clientId, events });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (parsed.type === 'unsubscribe') {
|
|
223
|
+
const events = parsed.events;
|
|
224
|
+
if (Array.isArray(events)) {
|
|
225
|
+
for (const event of events) {
|
|
226
|
+
client.info.subscriptions.delete(event);
|
|
227
|
+
}
|
|
228
|
+
log.debug('Client unsubscribed from events', { clientId, events });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Handle ping
|
|
232
|
+
if (parsed.type === 'ping') {
|
|
233
|
+
sendMessage(client.socket, {
|
|
234
|
+
type: 'pong',
|
|
235
|
+
payload: {},
|
|
236
|
+
timestamp: new Date().toISOString(),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
log.warn('Failed to parse client message', { clientId, message });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Cleanup disconnected client
|
|
246
|
+
*/
|
|
247
|
+
function cleanupClient(clientId) {
|
|
248
|
+
const client = clients.get(clientId);
|
|
249
|
+
if (client) {
|
|
250
|
+
client.unsubscribe();
|
|
251
|
+
try {
|
|
252
|
+
client.socket.destroy();
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// Ignore errors during cleanup
|
|
256
|
+
}
|
|
257
|
+
clients.delete(clientId);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get connected client count
|
|
262
|
+
*/
|
|
263
|
+
export function getClientCount() {
|
|
264
|
+
return clients.size;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Broadcast message to all clients
|
|
268
|
+
*/
|
|
269
|
+
export function broadcastMessage(message) {
|
|
270
|
+
for (const client of clients.values()) {
|
|
271
|
+
sendMessage(client.socket, message);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Close all connections
|
|
276
|
+
*/
|
|
277
|
+
export function closeAllConnections() {
|
|
278
|
+
for (const clientId of clients.keys()) {
|
|
279
|
+
cleanupClient(clientId);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/web/websocket/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket exports
|
|
3
|
+
*/
|
|
4
|
+
export { handleWebSocketUpgrade, getClientCount, broadcastMessage, closeAllConnections, } from './handler.js';
|
|
5
|
+
export { agentEvents, getEventBridge, resetEventBridge, EventBridge, type EventName, } from './event-bridge.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/web/websocket/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,KAAK,SAAS,GACf,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket exports
|
|
3
|
+
*/
|
|
4
|
+
export { handleWebSocketUpgrade, getClientCount, broadcastMessage, closeAllConnections, } from './handler.js';
|
|
5
|
+
export { agentEvents, getEventBridge, resetEventBridge, EventBridge, } from './event-bridge.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/websocket/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,WAAW,GAEZ,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blackms/aistack",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Clean agent orchestration for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,7 +43,11 @@
|
|
|
43
43
|
"lint:fix": "eslint src --fix",
|
|
44
44
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
|
-
"prepublishOnly": "npm run build"
|
|
46
|
+
"prepublishOnly": "npm run build",
|
|
47
|
+
"web": "node dist/cli/index.js web start",
|
|
48
|
+
"web:dev": "npm run build && npm run web",
|
|
49
|
+
"dev:web": "cd web && npm run dev",
|
|
50
|
+
"build:web": "cd web && npm run build"
|
|
47
51
|
},
|
|
48
52
|
"dependencies": {
|
|
49
53
|
"@anthropic-ai/sdk": "^0.71.0",
|