@fleettools/server 0.1.1 → 0.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.
@@ -1,111 +0,0 @@
1
- /**
2
- * Agent Validation Schemas
3
- *
4
- * Zod validation schemas for agent coordination
5
- */
6
- import { z } from 'zod';
7
- // Agent Type Schema
8
- export const AgentTypeSchema = z.enum([
9
- 'frontend',
10
- 'backend',
11
- 'testing',
12
- 'documentation',
13
- 'security',
14
- 'performance'
15
- ]);
16
- // Agent Configuration Schema
17
- export const AgentConfigSchema = z.object({
18
- timeout: z.number().int().positive().optional(),
19
- retries: z.number().int().min(0).max(10).optional(),
20
- resources: z.object({
21
- memory: z.string().optional(),
22
- cpu: z.string().optional(),
23
- }).optional(),
24
- environment: z.record(z.string()).optional(),
25
- });
26
- // Agent Spawn Request Schema
27
- export const AgentSpawnRequestSchema = z.object({
28
- type: AgentTypeSchema,
29
- task: z.string().optional(),
30
- metadata: z.record(z.unknown()).optional(),
31
- config: AgentConfigSchema.optional(),
32
- });
33
- // Agent Update Request Schema
34
- export const AgentUpdateRequestSchema = z.object({
35
- status: z.enum(['idle', 'busy', 'error']).optional(),
36
- metadata: z.record(z.unknown()).optional(),
37
- heartbeat: z.boolean().optional(),
38
- });
39
- // Validation functions
40
- export class AgentValidator {
41
- /**
42
- * Validate agent spawn request
43
- */
44
- static validateSpawnRequest(data) {
45
- const result = AgentSpawnRequestSchema.safeParse(data);
46
- if (!result.success) {
47
- throw new Error(`Invalid spawn request: ${result.error.message}`);
48
- }
49
- return result.data;
50
- }
51
- /**
52
- * Validate agent configuration
53
- */
54
- static validateConfig(data) {
55
- const result = AgentConfigSchema.safeParse(data);
56
- if (!result.success) {
57
- throw new Error(`Invalid agent config: ${result.error.message}`);
58
- }
59
- return result.data;
60
- }
61
- /**
62
- * Validate agent type
63
- */
64
- static validateAgentType(type) {
65
- const result = AgentTypeSchema.safeParse(type);
66
- if (!result.success) {
67
- throw new Error(`Invalid agent type: ${result.error.message}`);
68
- }
69
- return result.data;
70
- }
71
- /**
72
- * Validate agent ID format
73
- */
74
- static validateAgentId(id) {
75
- // Agent IDs should follow pattern: agt_<uuid>
76
- const agentIdPattern = /^agt_[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
77
- return agentIdPattern.test(id);
78
- }
79
- /**
80
- * Check if agent type is suitable for task type
81
- */
82
- static isAgentSuitableForTask(agentType, taskType) {
83
- const suitabilityMap = {
84
- 'frontend': ['ui', 'frontend', 'component', 'interface'],
85
- 'backend': ['api', 'backend', 'server', 'database'],
86
- 'testing': ['test', 'testing', 'qa', 'validation'],
87
- 'documentation': ['docs', 'documentation', 'readme', 'guide'],
88
- 'security': ['security', 'audit', 'vulnerability', 'scan'],
89
- 'performance': ['performance', 'optimization', 'benchmark', 'metrics']
90
- };
91
- const agentCapabilities = suitabilityMap[agentType] || [];
92
- return agentCapabilities.includes(taskType.toLowerCase());
93
- }
94
- /**
95
- * Get recommended agents for task type
96
- */
97
- static getRecommendedAgents(taskType) {
98
- const taskToAgents = {
99
- 'ui': ['frontend'],
100
- 'frontend': ['frontend'],
101
- 'api': ['backend'],
102
- 'backend': ['backend'],
103
- 'test': ['testing'],
104
- 'security': ['security'],
105
- 'docs': ['documentation'],
106
- 'performance': ['performance'],
107
- 'general': ['backend', 'frontend'] // General tasks can go to multiple types
108
- };
109
- return taskToAgents[taskType.toLowerCase()] || ['backend']; // Default to backend
110
- }
111
- }
package/dist/index.js DELETED
@@ -1,255 +0,0 @@
1
- import { closeDatabase, initializeDatabase } from '../../../squawk/src/db/index.js';
2
- import path from 'node:path';
3
- import { registerWorkOrdersRoutes } from './flightline/work-orders.js';
4
- import { registerCtkRoutes } from './flightline/ctk.js';
5
- import { registerTechOrdersRoutes } from './flightline/tech-orders.js';
6
- import { registerMailboxRoutes } from './squawk/mailbox.js';
7
- import { registerCursorRoutes } from './squawk/cursor.js';
8
- import { registerLockRoutes } from './squawk/lock.js';
9
- import { registerCoordinatorRoutes } from './squawk/coordinator.js';
10
- import { registerMissionRoutes } from './coordination/missions.js';
11
- import { registerAgentRoutes } from './coordination/agents.js';
12
- import { registerTaskDecompositionRoutes } from './coordination/tasks.js';
13
- import { registerAgentSpawnerRoutes } from './coordination/agent-spawner-routes.js';
14
- import { registerTaskQueueRoutes } from './coordination/task-queue-routes.js';
15
- import { registerCheckpointRoutes } from './coordination/checkpoint-routes.js';
16
- // Configure CORS based on environment
17
- const getAllowedOrigins = () => {
18
- const envOrigins = process.env.ALLOWED_ORIGINS;
19
- if (envOrigins) {
20
- return envOrigins.split(',').map(origin => origin.trim());
21
- }
22
- // Default origins for development
23
- const nodeEnv = process.env.NODE_ENV || 'development';
24
- return nodeEnv === 'production'
25
- ? [] // No default origins in production
26
- : ['http://localhost:3000', 'http://localhost:5173', 'http://127.0.0.1:3000'];
27
- };
28
- const getHeaders = (origin) => {
29
- const allowedOrigins = getAllowedOrigins();
30
- const isAllowed = !origin || allowedOrigins.length === 0 || allowedOrigins.includes(origin);
31
- return {
32
- 'Access-Control-Allow-Origin': isAllowed ? (origin || '*') : 'false',
33
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
34
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',
35
- 'Access-Control-Allow-Credentials': 'true',
36
- 'Access-Control-Max-Age': '86400', // 24 hours
37
- };
38
- };
39
- const routes = [];
40
- function parsePathPattern(pathPattern) {
41
- const paramNames = [];
42
- const regexPattern = pathPattern.replace(/:([^/]+)/g, (_, paramName) => {
43
- paramNames.push(paramName);
44
- return '([^/]+)';
45
- });
46
- return {
47
- regex: new RegExp(`^${regexPattern}$`),
48
- paramNames,
49
- };
50
- }
51
- function createRouter() {
52
- const addRoute = (method, path, handler, paramNames, regex) => {
53
- routes.push({ method, pathPattern: path, regex, paramNames, handler });
54
- };
55
- return {
56
- get: (path, handler) => {
57
- const { regex, paramNames } = parsePathPattern(path);
58
- if (path.includes(':')) {
59
- addRoute('GET', path, handler, paramNames, regex);
60
- }
61
- else {
62
- addRoute('GET', path, handler, [], regex);
63
- }
64
- },
65
- post: (path, handler) => {
66
- const { regex, paramNames } = parsePathPattern(path);
67
- if (path.includes(':')) {
68
- addRoute('POST', path, handler, paramNames, regex);
69
- }
70
- else {
71
- addRoute('POST', path, handler, [], regex);
72
- }
73
- },
74
- patch: (path, handler) => {
75
- const { regex, paramNames } = parsePathPattern(path);
76
- if (path.includes(':')) {
77
- addRoute('PATCH', path, handler, paramNames, regex);
78
- }
79
- else {
80
- addRoute('PATCH', path, handler, [], regex);
81
- }
82
- },
83
- delete: (path, handler) => {
84
- const { regex, paramNames } = parsePathPattern(path);
85
- if (path.includes(':')) {
86
- addRoute('DELETE', path, handler, paramNames, regex);
87
- }
88
- else {
89
- addRoute('DELETE', path, handler, [], regex);
90
- }
91
- },
92
- };
93
- }
94
- async function registerRoutes() {
95
- const headers = getHeaders();
96
- registerWorkOrdersRoutes(createRouter(), headers);
97
- registerCtkRoutes(createRouter(), headers);
98
- registerTechOrdersRoutes(createRouter(), headers);
99
- registerMailboxRoutes(createRouter(), headers);
100
- registerCursorRoutes(createRouter(), headers);
101
- registerLockRoutes(createRouter(), headers);
102
- registerCoordinatorRoutes(createRouter(), headers);
103
- // Initialize coordination components
104
- const { ProgressTracker } = await import('./coordination/progress-tracker.js');
105
- const progressTracker = new ProgressTracker({
106
- dbPath: path.join(process.cwd(), '.flightline', 'progress.db')
107
- });
108
- registerMissionRoutes(createRouter(), progressTracker);
109
- registerAgentRoutes(createRouter(), headers);
110
- registerTaskDecompositionRoutes(createRouter(), headers);
111
- registerAgentSpawnerRoutes(createRouter(), headers);
112
- registerTaskQueueRoutes(createRouter(), headers);
113
- registerCheckpointRoutes(createRouter(), headers);
114
- }
115
- async function startServer() {
116
- try {
117
- await initializeDatabase();
118
- console.log('Squawk database initialized');
119
- }
120
- catch (error) {
121
- console.error('Failed to initialize database:', error);
122
- process.exit(1);
123
- }
124
- await registerRoutes();
125
- const server = Bun.serve({
126
- port: parseInt(process.env.PORT || '3001', 10),
127
- async fetch(request) {
128
- const url = new URL(request.url);
129
- const path = url.pathname;
130
- const method = request.method;
131
- const origin = request.headers.get('origin');
132
- const headers = getHeaders(origin || undefined);
133
- if (method === 'OPTIONS') {
134
- return new Response(null, { headers });
135
- }
136
- if (path === '/health') {
137
- return new Response(JSON.stringify({
138
- status: 'healthy',
139
- service: 'fleettools-consolidated',
140
- timestamp: new Date().toISOString(),
141
- version: '1.0.0',
142
- }), {
143
- headers: { ...headers, 'Content-Type': 'application/json' },
144
- });
145
- }
146
- for (const route of routes) {
147
- if (route.method !== method)
148
- continue;
149
- const match = path.match(route.regex);
150
- if (match) {
151
- try {
152
- const params = {};
153
- route.paramNames.forEach((name, i) => {
154
- params[name] = match[i + 1];
155
- });
156
- return await route.handler(request, params);
157
- }
158
- catch (error) {
159
- console.error('Route handler error:', error);
160
- return new Response(JSON.stringify({
161
- error: 'Internal server error',
162
- message: error instanceof Error ? error.message : 'Unknown error',
163
- }), {
164
- status: 500,
165
- headers: { ...headers, 'Content-Type': 'application/json' },
166
- });
167
- }
168
- }
169
- }
170
- // 404
171
- return new Response(JSON.stringify({
172
- error: 'Not found',
173
- path,
174
- method,
175
- }), {
176
- status: 404,
177
- headers: { ...headers, 'Content-Type': 'application/json' },
178
- });
179
- },
180
- });
181
- setInterval(async () => {
182
- try {
183
- const { lockOps } = await import('../../../squawk/src/db/index.js');
184
- const released = await lockOps.releaseExpired();
185
- if (released > 0) {
186
- console.log(`Released ${released} expired locks`);
187
- }
188
- }
189
- catch (error) {
190
- console.error('Error releasing expired locks:', error);
191
- }
192
- }, 30000); // Check every 30 seconds
193
- console.log(`FleetTools Consolidated API server listening on port ${server.port}`);
194
- console.log(`Health check: http://localhost:${server.port}/health`);
195
- console.log('\nFlightline Endpoints:');
196
- console.log(' GET /api/v1/work-orders - List work orders');
197
- console.log(' POST /api/v1/work-orders - Create work order');
198
- console.log(' GET /api/v1/work-orders/:id - Get work order');
199
- console.log(' PATCH /api/v1/work-orders/:id - Update work order');
200
- console.log(' DELETE /api/v1/work-orders/:id - Delete work order');
201
- console.log(' GET /api/v1/ctk/reservations - List CTK reservations');
202
- console.log(' POST /api/v1/ctk/reserve - Reserve file');
203
- console.log(' POST /api/v1/ctk/release - Release reservation');
204
- console.log(' GET /api/v1/tech-orders - List tech orders');
205
- console.log(' POST /api/v1/tech-orders - Create tech order');
206
- console.log('\nSquawk Endpoints:');
207
- console.log(' POST /api/v1/mailbox/append - Append events to mailbox');
208
- console.log(' GET /api/v1/mailbox/:streamId - Get mailbox contents');
209
- console.log(' POST /api/v1/cursor/advance - Advance cursor position');
210
- console.log(' GET /api/v1/cursor/:cursorId - Get cursor position');
211
- console.log(' POST /api/v1/lock/acquire - Acquire file lock');
212
- console.log(' POST /api/v1/lock/release - Release file lock');
213
- console.log(' GET /api/v1/locks - List all active locks');
214
- console.log(' GET /api/v1/coordinator/status - Get coordinator status');
215
- console.log('\nCoordination Endpoints:');
216
- console.log(' POST /api/v1/agents/spawn - Spawn new agent');
217
- console.log(' GET /api/v1/agents - List all agents');
218
- console.log(' GET /api/v1/agents/:id - Get agent details');
219
- console.log(' DELETE /api/v1/agents/:id - Terminate agent');
220
- console.log(' POST /api/v1/agents/:id/progress - Report agent progress');
221
- console.log(' POST /api/v1/agents/:id/heartbeat - Agent heartbeat');
222
- console.log(' GET /api/v1/agents/:id/health - Get agent health');
223
- console.log(' GET /api/v1/agents/system/health - Get system health');
224
- console.log(' POST /api/v1/tasks/decompose - Decompose mission into tasks');
225
- console.log(' POST /api/v1/tasks - Create new task');
226
- console.log(' GET /api/v1/tasks - List tasks');
227
- console.log(' GET /api/v1/tasks/:id - Get task details');
228
- console.log(' PATCH /api/v1/tasks/:id/start - Start task');
229
- console.log(' PATCH /api/v1/tasks/:id/complete - Complete task');
230
- console.log(' PATCH /api/v1/tasks/:id/fail - Fail task');
231
- console.log(' GET /api/v1/tasks/next/:agentType - Get next tasks');
232
- console.log(' GET /api/v1/tasks/stats - Get task statistics');
233
- console.log(' POST /api/v1/tasks/retry-failed - Retry failed tasks');
234
- console.log(' POST /api/v1/checkpoints - Create checkpoint');
235
- console.log(' GET /api/v1/checkpoints - List checkpoints');
236
- console.log(' GET /api/v1/checkpoints/:id - Get checkpoint');
237
- console.log(' GET /api/v1/checkpoints/latest/:missionId - Get latest checkpoint');
238
- console.log(' DELETE /api/v1/checkpoints/:id - Delete checkpoint');
239
- process.on('SIGINT', () => {
240
- console.log('\nShutting down...');
241
- closeDatabase();
242
- server.stop();
243
- process.exit(0);
244
- });
245
- process.on('SIGTERM', () => {
246
- console.log('\nShutting down...');
247
- closeDatabase();
248
- server.stop();
249
- process.exit(0);
250
- });
251
- return server;
252
- }
253
- const server = await startServer();
254
- export { server };
255
- //# sourceMappingURL=index.js.map