@herdctl/web 0.0.1 → 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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/dist/client/assets/index-Cyochp2F.css +1 -0
  3. package/dist/client/assets/index-mp9jz5eD.js +373 -0
  4. package/dist/client/favicon.ico +0 -0
  5. package/dist/client/favicon.svg +1 -0
  6. package/dist/client/herdctl-logo.svg +29 -0
  7. package/dist/client/index.html +21 -0
  8. package/dist/server/__tests__/routes.test.d.ts +8 -0
  9. package/dist/server/__tests__/routes.test.d.ts.map +1 -0
  10. package/dist/server/__tests__/routes.test.js +535 -0
  11. package/dist/server/__tests__/routes.test.js.map +1 -0
  12. package/dist/server/__tests__/ws-handler.test.d.ts +7 -0
  13. package/dist/server/__tests__/ws-handler.test.d.ts.map +1 -0
  14. package/dist/server/__tests__/ws-handler.test.js +380 -0
  15. package/dist/server/__tests__/ws-handler.test.js.map +1 -0
  16. package/dist/server/chat/index.d.ts +5 -0
  17. package/dist/server/chat/index.d.ts.map +1 -0
  18. package/dist/server/chat/index.js +5 -0
  19. package/dist/server/chat/index.js.map +1 -0
  20. package/dist/server/chat/web-chat-manager.d.ts +158 -0
  21. package/dist/server/chat/web-chat-manager.d.ts.map +1 -0
  22. package/dist/server/chat/web-chat-manager.js +437 -0
  23. package/dist/server/chat/web-chat-manager.js.map +1 -0
  24. package/dist/server/index.d.ts +144 -0
  25. package/dist/server/index.d.ts.map +1 -0
  26. package/dist/server/index.js +341 -0
  27. package/dist/server/index.js.map +1 -0
  28. package/dist/server/routes/agents.d.ts +15 -0
  29. package/dist/server/routes/agents.d.ts.map +1 -0
  30. package/dist/server/routes/agents.js +66 -0
  31. package/dist/server/routes/agents.js.map +1 -0
  32. package/dist/server/routes/chat.d.ts +18 -0
  33. package/dist/server/routes/chat.d.ts.map +1 -0
  34. package/dist/server/routes/chat.js +191 -0
  35. package/dist/server/routes/chat.js.map +1 -0
  36. package/dist/server/routes/fleet.d.ts +15 -0
  37. package/dist/server/routes/fleet.d.ts.map +1 -0
  38. package/dist/server/routes/fleet.js +36 -0
  39. package/dist/server/routes/fleet.js.map +1 -0
  40. package/dist/server/routes/jobs.d.ts +17 -0
  41. package/dist/server/routes/jobs.d.ts.map +1 -0
  42. package/dist/server/routes/jobs.js +188 -0
  43. package/dist/server/routes/jobs.js.map +1 -0
  44. package/dist/server/routes/schedules.d.ts +16 -0
  45. package/dist/server/routes/schedules.d.ts.map +1 -0
  46. package/dist/server/routes/schedules.js +126 -0
  47. package/dist/server/routes/schedules.js.map +1 -0
  48. package/dist/server/ws/fleet-bridge.d.ts +80 -0
  49. package/dist/server/ws/fleet-bridge.d.ts.map +1 -0
  50. package/dist/server/ws/fleet-bridge.js +184 -0
  51. package/dist/server/ws/fleet-bridge.js.map +1 -0
  52. package/dist/server/ws/handler.d.ts +93 -0
  53. package/dist/server/ws/handler.d.ts.map +1 -0
  54. package/dist/server/ws/handler.js +270 -0
  55. package/dist/server/ws/handler.js.map +1 -0
  56. package/dist/server/ws/index.d.ts +8 -0
  57. package/dist/server/ws/index.d.ts.map +1 -0
  58. package/dist/server/ws/index.js +8 -0
  59. package/dist/server/ws/index.js.map +1 -0
  60. package/dist/server/ws/types.d.ts +215 -0
  61. package/dist/server/ws/types.d.ts.map +1 -0
  62. package/dist/server/ws/types.js +67 -0
  63. package/dist/server/ws/types.js.map +1 -0
  64. package/package.json +77 -1
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Web server factory and WebManager for @herdctl/web
3
+ *
4
+ * Creates a Fastify server that serves the React SPA and provides
5
+ * REST API endpoints and WebSocket connections for fleet management.
6
+ */
7
+ import Fastify from "fastify";
8
+ import fastifyCors from "@fastify/cors";
9
+ import fastifyStatic from "@fastify/static";
10
+ import fastifyWebsocket from "@fastify/websocket";
11
+ import { existsSync, readFileSync } from "node:fs";
12
+ import { join, dirname } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ import { createLogger, listJobs, } from "@herdctl/core";
15
+ import { registerFleetRoutes } from "./routes/fleet.js";
16
+ import { registerAgentRoutes } from "./routes/agents.js";
17
+ import { registerJobRoutes } from "./routes/jobs.js";
18
+ import { registerScheduleRoutes } from "./routes/schedules.js";
19
+ import { registerChatRoutes } from "./routes/chat.js";
20
+ import { WebSocketHandler, FleetBridge } from "./ws/index.js";
21
+ import { WebChatManager } from "./chat/index.js";
22
+ const logger = createLogger("web");
23
+ // Get the directory of this file to find the client build
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ /**
27
+ * Creates a Fastify web server instance with WebSocket support
28
+ *
29
+ * The server is returned but NOT started - the caller controls the lifecycle.
30
+ * The returned FleetBridge should be started after the server starts listening,
31
+ * and stopped before the server closes.
32
+ *
33
+ * @param fleetManager - FleetManager instance for API calls and event subscription
34
+ * @param config - Server configuration
35
+ * @returns WebServerResult containing server, wsHandler, fleetBridge, and chatManager
36
+ */
37
+ export async function createWebServer(fleetManager, config) {
38
+ const server = Fastify({
39
+ logger: false, // We use our own logger
40
+ });
41
+ // Register CORS for development (allow localhost origins)
42
+ await server.register(fastifyCors, {
43
+ origin: [
44
+ "http://localhost:3232",
45
+ "http://localhost:5173", // Vite dev server
46
+ "http://127.0.0.1:3232",
47
+ "http://127.0.0.1:5173",
48
+ `http://${config.host}:${config.port}`,
49
+ ],
50
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
51
+ });
52
+ // Register WebSocket plugin
53
+ await server.register(fastifyWebsocket);
54
+ // Create WebSocket handler, fleet bridge, and chat manager
55
+ const wsHandler = new WebSocketHandler(fleetManager);
56
+ const fleetBridge = new FleetBridge(fleetManager, wsHandler);
57
+ const chatManager = new WebChatManager();
58
+ // Initialize chat manager if state directory is provided
59
+ if (config.stateDir) {
60
+ await chatManager.initialize(fleetManager, config.stateDir, {
61
+ enabled: true,
62
+ port: config.port,
63
+ host: config.host,
64
+ session_expiry_hours: config.sessionExpiryHours ?? 24,
65
+ open_browser: false,
66
+ });
67
+ // Wire up chat manager to WebSocket handler
68
+ wsHandler.setChatManager(chatManager);
69
+ }
70
+ // Register WebSocket route at /ws
71
+ server.get("/ws", { websocket: true }, (socket, _request) => {
72
+ // Handle new WebSocket connection
73
+ wsHandler.handleConnection(socket).catch((error) => {
74
+ logger.warn(`Error handling WebSocket connection: ${error.message}`);
75
+ });
76
+ });
77
+ // Register static file serving for the built React SPA
78
+ // The client build outputs to dist/client/ relative to package root
79
+ // When compiled, this file is at dist/server/index.js
80
+ // So we need to go up two levels to get to dist/client
81
+ const clientDistPath = join(__dirname, "..", "client");
82
+ try {
83
+ await server.register(fastifyStatic, {
84
+ root: clientDistPath,
85
+ prefix: "/",
86
+ // Don't serve index.html for API routes
87
+ wildcard: false,
88
+ });
89
+ }
90
+ catch {
91
+ // Client dist may not exist in development - that's OK
92
+ logger.debug("Client dist not found, static serving disabled");
93
+ }
94
+ // Register REST API routes
95
+ registerFleetRoutes(server, fleetManager);
96
+ registerAgentRoutes(server, fleetManager);
97
+ registerJobRoutes(server, fleetManager, listJobs);
98
+ registerScheduleRoutes(server, fleetManager);
99
+ registerChatRoutes(server, fleetManager, chatManager);
100
+ // Health check endpoint
101
+ server.get("/api/health", async (_request, reply) => {
102
+ return reply.send({ status: "ok", timestamp: new Date().toISOString() });
103
+ });
104
+ // SPA fallback - serve index.html for non-API, non-WS routes
105
+ // This must be registered after static file serving and API routes
106
+ const indexPath = join(clientDistPath, "index.html");
107
+ server.setNotFoundHandler(async (request, reply) => {
108
+ const url = request.url;
109
+ // Don't serve SPA for API routes, WebSocket, or static assets
110
+ if (url.startsWith("/api/") ||
111
+ url === "/ws" ||
112
+ url.startsWith("/assets/")) {
113
+ return reply.status(404).send({ error: "Not found" });
114
+ }
115
+ // Serve index.html for SPA routing
116
+ if (existsSync(indexPath)) {
117
+ const html = readFileSync(indexPath, "utf-8");
118
+ return reply.type("text/html").send(html);
119
+ }
120
+ // Client build not available
121
+ return reply.status(503).send({
122
+ error: "Client not built",
123
+ message: "Run 'pnpm build:client' to build the web dashboard",
124
+ });
125
+ });
126
+ // Log registered routes in debug mode
127
+ logger.debug("Web server routes registered (REST + WebSocket + SPA fallback)");
128
+ return { server, wsHandler, fleetBridge, chatManager };
129
+ }
130
+ /**
131
+ * WebManager manages the web dashboard server lifecycle
132
+ *
133
+ * Implements IChatManager interface for integration with FleetManager.
134
+ * Unlike Discord/Slack managers which have per-agent connectors,
135
+ * WebManager provides a single dashboard that serves all agents.
136
+ */
137
+ export class WebManager {
138
+ ctx;
139
+ server = null;
140
+ wsHandler = null;
141
+ fleetBridge = null;
142
+ initialized = false;
143
+ connectorState = {
144
+ status: "disconnected",
145
+ connectedAt: null,
146
+ disconnectedAt: null,
147
+ reconnectAttempts: 0,
148
+ lastError: null,
149
+ botUser: null,
150
+ messageStats: {
151
+ received: 0,
152
+ sent: 0,
153
+ ignored: 0,
154
+ },
155
+ };
156
+ constructor(ctx) {
157
+ this.ctx = ctx;
158
+ }
159
+ /**
160
+ * Initialize the web manager
161
+ *
162
+ * Creates the Fastify server with WebSocket support and REST API routes.
163
+ * Does not start listening - that happens in start().
164
+ */
165
+ async initialize() {
166
+ if (this.initialized) {
167
+ return;
168
+ }
169
+ const log = this.ctx.getLogger();
170
+ const config = this.ctx.getConfig();
171
+ // Web config is at fleet level (config.fleet.web), not on ResolvedConfig directly
172
+ if (!config?.fleet?.web?.enabled) {
173
+ log.debug("Web UI not enabled in configuration");
174
+ this.initialized = true;
175
+ return;
176
+ }
177
+ const webConfig = config.fleet.web;
178
+ try {
179
+ // Get the FleetManager instance (the context IS the FleetManager)
180
+ const fleetManager = this.ctx.getEmitter();
181
+ // Create the web server with all components
182
+ const stateDir = this.ctx.getStateDir();
183
+ const result = await createWebServer(fleetManager, {
184
+ host: webConfig.host,
185
+ port: webConfig.port,
186
+ stateDir,
187
+ sessionExpiryHours: webConfig.session_expiry_hours,
188
+ });
189
+ this.server = result.server;
190
+ this.wsHandler = result.wsHandler;
191
+ this.fleetBridge = result.fleetBridge;
192
+ this.initialized = true;
193
+ log.debug("Web manager initialized");
194
+ }
195
+ catch (error) {
196
+ const errorMessage = error instanceof Error ? error.message : String(error);
197
+ this.connectorState.lastError = errorMessage;
198
+ log.error(`Failed to initialize web manager: ${errorMessage}`);
199
+ throw error;
200
+ }
201
+ }
202
+ /**
203
+ * Start the web server
204
+ *
205
+ * Starts listening on the configured host:port and begins
206
+ * broadcasting FleetManager events to WebSocket clients.
207
+ */
208
+ async start() {
209
+ const log = this.ctx.getLogger();
210
+ const config = this.ctx.getConfig();
211
+ // Web config is at fleet level (config.fleet.web)
212
+ if (!config?.fleet?.web?.enabled) {
213
+ log.debug("Web UI not enabled, skipping start");
214
+ return;
215
+ }
216
+ if (!this.initialized) {
217
+ throw new Error("WebManager must be initialized before starting");
218
+ }
219
+ if (!this.server || !this.fleetBridge) {
220
+ log.debug("Web server not created (initialization may have failed)");
221
+ return;
222
+ }
223
+ const webConfig = config.fleet.web;
224
+ try {
225
+ // Start the Fastify server
226
+ await this.server.listen({
227
+ host: webConfig.host,
228
+ port: webConfig.port,
229
+ });
230
+ // Start the fleet bridge to broadcast events
231
+ this.fleetBridge.start();
232
+ // Update connector state
233
+ this.connectorState.status = "connected";
234
+ this.connectorState.connectedAt = new Date().toISOString();
235
+ this.connectorState.lastError = null;
236
+ const url = `http://${webConfig.host}:${webConfig.port}`;
237
+ log.info(`Web dashboard available at ${url}`);
238
+ }
239
+ catch (error) {
240
+ const errorMessage = error instanceof Error ? error.message : String(error);
241
+ this.connectorState.status = "error";
242
+ this.connectorState.lastError = errorMessage;
243
+ log.error(`Failed to start web server: ${errorMessage}`);
244
+ throw error;
245
+ }
246
+ }
247
+ /**
248
+ * Stop the web server
249
+ *
250
+ * Gracefully shuts down the Fastify server and stops event broadcasting.
251
+ */
252
+ async stop() {
253
+ const log = this.ctx.getLogger();
254
+ if (this.fleetBridge) {
255
+ this.fleetBridge.stop();
256
+ }
257
+ if (this.wsHandler) {
258
+ this.wsHandler.closeAll();
259
+ }
260
+ if (this.server) {
261
+ try {
262
+ await this.server.close();
263
+ log.debug("Web server stopped");
264
+ }
265
+ catch (error) {
266
+ const errorMessage = error instanceof Error ? error.message : String(error);
267
+ log.warn(`Error stopping web server: ${errorMessage}`);
268
+ }
269
+ }
270
+ this.connectorState.status = "disconnected";
271
+ this.connectorState.disconnectedAt = new Date().toISOString();
272
+ }
273
+ /**
274
+ * Check if the manager is initialized
275
+ */
276
+ isInitialized() {
277
+ return this.initialized;
278
+ }
279
+ /**
280
+ * Get the connector names managed by this manager
281
+ *
282
+ * Unlike Discord/Slack which have per-agent connectors,
283
+ * the web dashboard returns ["web"] to indicate it manages
284
+ * the single web interface.
285
+ */
286
+ getConnectorNames() {
287
+ return ["web"];
288
+ }
289
+ /**
290
+ * Get the count of connected WebSocket clients
291
+ */
292
+ getConnectedCount() {
293
+ return this.wsHandler?.getConnectedCount() ?? 0;
294
+ }
295
+ /**
296
+ * Check if a specific agent is accessible via the web dashboard
297
+ *
298
+ * All agents are accessible via the web dashboard, so this always returns true.
299
+ */
300
+ hasAgent(_agentName) {
301
+ return true;
302
+ }
303
+ /**
304
+ * Get the connector state for a specific agent
305
+ *
306
+ * Since the web dashboard doesn't have per-agent connectors,
307
+ * this returns the overall web server state for any agent.
308
+ */
309
+ getState(_agentName) {
310
+ return {
311
+ ...this.connectorState,
312
+ // Update message stats with current connected count
313
+ messageStats: {
314
+ ...this.connectorState.messageStats,
315
+ // We can use received to track total connections over time if needed
316
+ },
317
+ };
318
+ }
319
+ /**
320
+ * Get the internal web manager state
321
+ *
322
+ * This provides additional state information beyond the IChatManager interface.
323
+ */
324
+ getWebState() {
325
+ const config = this.ctx.getConfig();
326
+ const webConfig = config?.fleet?.web;
327
+ return {
328
+ initialized: this.initialized,
329
+ running: this.connectorState.status === "connected",
330
+ host: webConfig?.host ?? null,
331
+ port: webConfig?.port ?? null,
332
+ connectedClients: this.getConnectedCount(),
333
+ startedAt: this.connectorState.connectedAt,
334
+ };
335
+ }
336
+ }
337
+ // Re-export WebSocket types for consumers
338
+ export { WebSocketHandler, FleetBridge, isClientMessage, isChatSendMessage, isAgentStartedPayload, isAgentStoppedPayload, } from "./ws/index.js";
339
+ // Re-export chat types for consumers
340
+ export { WebChatManager, } from "./chat/index.js";
341
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Agent REST API routes
3
+ *
4
+ * Provides endpoints for retrieving agent information.
5
+ */
6
+ import type { FastifyInstance } from "fastify";
7
+ import type { FleetManager } from "@herdctl/core";
8
+ /**
9
+ * Register agent-related routes
10
+ *
11
+ * @param server - Fastify instance
12
+ * @param fleetManager - FleetManager instance
13
+ */
14
+ export declare function registerAgentRoutes(server: FastifyInstance, fleetManager: FleetManager): void;
15
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/server/routes/agents.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,YAAY,GACzB,IAAI,CAwDN"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Agent REST API routes
3
+ *
4
+ * Provides endpoints for retrieving agent information.
5
+ */
6
+ /**
7
+ * Register agent-related routes
8
+ *
9
+ * @param server - Fastify instance
10
+ * @param fleetManager - FleetManager instance
11
+ */
12
+ export function registerAgentRoutes(server, fleetManager) {
13
+ /**
14
+ * GET /api/agents
15
+ *
16
+ * Returns a list of all agents with their current status.
17
+ * Each agent includes:
18
+ * - Name and description
19
+ * - Current status (idle, running, error)
20
+ * - Current/last job IDs
21
+ * - Schedule information
22
+ * - Chat connector statuses
23
+ */
24
+ server.get("/api/agents", async (_request, reply) => {
25
+ try {
26
+ const agents = await fleetManager.getAgentInfo();
27
+ return reply.send(agents);
28
+ }
29
+ catch (error) {
30
+ const message = error instanceof Error ? error.message : String(error);
31
+ return reply.status(500).send({
32
+ error: `Failed to get agents: ${message}`,
33
+ statusCode: 500,
34
+ });
35
+ }
36
+ });
37
+ /**
38
+ * GET /api/agents/:name
39
+ *
40
+ * Returns detailed information for a single agent.
41
+ *
42
+ * @param name - Agent name (URL parameter)
43
+ */
44
+ server.get("/api/agents/:name", async (request, reply) => {
45
+ try {
46
+ const { name } = request.params;
47
+ const agent = await fleetManager.getAgentInfoByName(name);
48
+ return reply.send(agent);
49
+ }
50
+ catch (error) {
51
+ const message = error instanceof Error ? error.message : String(error);
52
+ // Check if it's a "not found" error
53
+ if (message.toLowerCase().includes("not found")) {
54
+ return reply.status(404).send({
55
+ error: message,
56
+ statusCode: 404,
57
+ });
58
+ }
59
+ return reply.status(500).send({
60
+ error: `Failed to get agent: ${message}`,
61
+ statusCode: 500,
62
+ });
63
+ }
64
+ });
65
+ }
66
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/server/routes/agents.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAuB,EACvB,YAA0B;IAE1B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,KAAK,EAAE,yBAAyB,OAAO,EAAE;gBACzC,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,CAEP,mBAAmB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEvE,oCAAoC;YACpC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAChD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC5B,KAAK,EAAE,OAAO;oBACd,UAAU,EAAE,GAAG;iBAChB,CAAC,CAAC;YACL,CAAC;YAED,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,KAAK,EAAE,wBAAwB,OAAO,EAAE;gBACxC,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Chat REST API routes
3
+ *
4
+ * Provides endpoints for managing chat sessions and messages.
5
+ * Actual message streaming happens via WebSocket.
6
+ */
7
+ import type { FastifyInstance } from "fastify";
8
+ import type { FleetManager } from "@herdctl/core";
9
+ import type { WebChatManager } from "../chat/index.js";
10
+ /**
11
+ * Register chat-related routes
12
+ *
13
+ * @param server - Fastify instance
14
+ * @param fleetManager - FleetManager instance
15
+ * @param chatManager - WebChatManager instance
16
+ */
17
+ export declare function registerChatRoutes(server: FastifyInstance, fleetManager: FleetManager, chatManager: WebChatManager): void;
18
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/server/routes/chat.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,cAAc,GAC1B,IAAI,CA+MN"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Chat REST API routes
3
+ *
4
+ * Provides endpoints for managing chat sessions and messages.
5
+ * Actual message streaming happens via WebSocket.
6
+ */
7
+ /**
8
+ * Register chat-related routes
9
+ *
10
+ * @param server - Fastify instance
11
+ * @param fleetManager - FleetManager instance
12
+ * @param chatManager - WebChatManager instance
13
+ */
14
+ export function registerChatRoutes(server, fleetManager, chatManager) {
15
+ /**
16
+ * POST /api/chat/:agentName/sessions
17
+ *
18
+ * Create a new chat session for an agent.
19
+ *
20
+ * @returns { sessionId, createdAt }
21
+ */
22
+ server.post("/api/chat/:agentName/sessions", async (request, reply) => {
23
+ try {
24
+ const { agentName } = request.params;
25
+ // Verify agent exists
26
+ try {
27
+ await fleetManager.getAgentInfoByName(agentName);
28
+ }
29
+ catch {
30
+ return reply.status(404).send({
31
+ error: `Agent not found: ${agentName}`,
32
+ statusCode: 404,
33
+ });
34
+ }
35
+ const session = await chatManager.createSession(agentName);
36
+ return reply.status(201).send({
37
+ sessionId: session.sessionId,
38
+ createdAt: session.createdAt,
39
+ });
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ return reply.status(500).send({
44
+ error: `Failed to create session: ${message}`,
45
+ statusCode: 500,
46
+ });
47
+ }
48
+ });
49
+ /**
50
+ * GET /api/chat/:agentName/sessions
51
+ *
52
+ * List all chat sessions for an agent.
53
+ *
54
+ * @returns { sessions: [{ sessionId, createdAt, lastMessageAt, messageCount, preview }] }
55
+ */
56
+ server.get("/api/chat/:agentName/sessions", async (request, reply) => {
57
+ try {
58
+ const { agentName } = request.params;
59
+ // Verify agent exists
60
+ try {
61
+ await fleetManager.getAgentInfoByName(agentName);
62
+ }
63
+ catch {
64
+ return reply.status(404).send({
65
+ error: `Agent not found: ${agentName}`,
66
+ statusCode: 404,
67
+ });
68
+ }
69
+ const sessions = await chatManager.listSessions(agentName);
70
+ return reply.send({ sessions });
71
+ }
72
+ catch (error) {
73
+ const message = error instanceof Error ? error.message : String(error);
74
+ return reply.status(500).send({
75
+ error: `Failed to list sessions: ${message}`,
76
+ statusCode: 500,
77
+ });
78
+ }
79
+ });
80
+ /**
81
+ * GET /api/chat/:agentName/sessions/:sessionId
82
+ *
83
+ * Get session details with message history.
84
+ *
85
+ * @returns { sessionId, messages, createdAt, lastMessageAt }
86
+ */
87
+ server.get("/api/chat/:agentName/sessions/:sessionId", async (request, reply) => {
88
+ try {
89
+ const { agentName, sessionId } = request.params;
90
+ const session = await chatManager.getSession(agentName, sessionId);
91
+ if (!session) {
92
+ return reply.status(404).send({
93
+ error: `Session not found: ${sessionId}`,
94
+ statusCode: 404,
95
+ });
96
+ }
97
+ return reply.send(session);
98
+ }
99
+ catch (error) {
100
+ const message = error instanceof Error ? error.message : String(error);
101
+ return reply.status(500).send({
102
+ error: `Failed to get session: ${message}`,
103
+ statusCode: 500,
104
+ });
105
+ }
106
+ });
107
+ /**
108
+ * DELETE /api/chat/:agentName/sessions/:sessionId
109
+ *
110
+ * Delete a chat session.
111
+ *
112
+ * @returns { deleted: true }
113
+ */
114
+ server.delete("/api/chat/:agentName/sessions/:sessionId", async (request, reply) => {
115
+ try {
116
+ const { agentName, sessionId } = request.params;
117
+ const deleted = await chatManager.deleteSession(agentName, sessionId);
118
+ if (!deleted) {
119
+ return reply.status(404).send({
120
+ error: `Session not found: ${sessionId}`,
121
+ statusCode: 404,
122
+ });
123
+ }
124
+ return reply.send({ deleted: true });
125
+ }
126
+ catch (error) {
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ return reply.status(500).send({
129
+ error: `Failed to delete session: ${message}`,
130
+ statusCode: 500,
131
+ });
132
+ }
133
+ });
134
+ /**
135
+ * POST /api/chat/:agentName/sessions/:sessionId/messages
136
+ *
137
+ * Send a message in a chat session. The actual response streams via WebSocket.
138
+ *
139
+ * Request body: { message: string }
140
+ * @returns { jobId }
141
+ */
142
+ server.post("/api/chat/:agentName/sessions/:sessionId/messages", async (request, reply) => {
143
+ try {
144
+ const { agentName, sessionId } = request.params;
145
+ const { message } = request.body;
146
+ if (!message || typeof message !== "string") {
147
+ return reply.status(400).send({
148
+ error: "Message is required",
149
+ statusCode: 400,
150
+ });
151
+ }
152
+ // Verify session exists
153
+ const session = await chatManager.getSession(agentName, sessionId);
154
+ if (!session) {
155
+ return reply.status(404).send({
156
+ error: `Session not found: ${sessionId}`,
157
+ statusCode: 404,
158
+ });
159
+ }
160
+ // Note: This endpoint just validates and returns immediately.
161
+ // The actual message sending should be done via WebSocket (chat:send)
162
+ // to enable streaming responses.
163
+ //
164
+ // However, we provide this REST endpoint for clients that want a simpler
165
+ // request/response pattern without streaming.
166
+ // In that case, we collect all chunks and return when complete.
167
+ let response = "";
168
+ const result = await chatManager.sendMessage(agentName, sessionId, message, (chunk) => {
169
+ response += chunk;
170
+ });
171
+ if (!result.success) {
172
+ return reply.status(500).send({
173
+ error: result.error ?? "Failed to send message",
174
+ statusCode: 500,
175
+ });
176
+ }
177
+ return reply.send({
178
+ jobId: result.jobId,
179
+ response,
180
+ });
181
+ }
182
+ catch (error) {
183
+ const message = error instanceof Error ? error.message : String(error);
184
+ return reply.status(500).send({
185
+ error: `Failed to send message: ${message}`,
186
+ statusCode: 500,
187
+ });
188
+ }
189
+ });
190
+ }
191
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/server/routes/chat.ts"],"names":[],"mappings":"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"}