atabey-mcp 0.0.19 → 0.0.21

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 (70) hide show
  1. package/README.md +2 -2
  2. package/dist/atabey/src/cli/platforms/core.d.ts +4 -0
  3. package/dist/atabey/src/cli/platforms/core.js +12 -8
  4. package/dist/atabey/src/cli/platforms/core.js.map +1 -1
  5. package/dist/atabey/src/cli/platforms/index.d.ts +1 -1
  6. package/dist/atabey/src/cli/platforms/index.js +1 -1
  7. package/dist/atabey/src/cli/platforms/index.js.map +1 -1
  8. package/dist/atabey/src/cli/utils/memory.d.ts +13 -7
  9. package/dist/atabey/src/cli/utils/memory.js +48 -16
  10. package/dist/atabey/src/cli/utils/memory.js.map +1 -1
  11. package/dist/atabey/src/modules/engines/agent-loop.d.ts +34 -0
  12. package/dist/atabey/src/modules/engines/agent-loop.js +102 -0
  13. package/dist/atabey/src/modules/engines/agent-loop.js.map +1 -0
  14. package/dist/atabey-mcp/src/mcp/constants.d.ts +3 -45
  15. package/dist/atabey-mcp/src/mcp/constants.js +3 -62
  16. package/dist/atabey-mcp/src/mcp/constants.js.map +1 -1
  17. package/dist/atabey-mcp/src/mcp/index.js +19 -35
  18. package/dist/atabey-mcp/src/mcp/index.js.map +1 -1
  19. package/dist/atabey-mcp/src/mcp/routes/api-agents.d.ts +3 -0
  20. package/dist/atabey-mcp/src/mcp/routes/api-agents.js +97 -0
  21. package/dist/atabey-mcp/src/mcp/routes/api-agents.js.map +1 -0
  22. package/dist/atabey-mcp/src/mcp/routes/api-common.d.ts +3 -0
  23. package/dist/atabey-mcp/src/mcp/routes/api-common.js +63 -0
  24. package/dist/atabey-mcp/src/mcp/routes/api-common.js.map +1 -0
  25. package/dist/atabey-mcp/src/mcp/routes/api-config.d.ts +3 -0
  26. package/dist/atabey-mcp/src/mcp/routes/api-config.js +639 -0
  27. package/dist/atabey-mcp/src/mcp/routes/api-config.js.map +1 -0
  28. package/dist/atabey-mcp/src/mcp/routes/api-governance.d.ts +3 -0
  29. package/dist/atabey-mcp/src/mcp/routes/api-governance.js +271 -0
  30. package/dist/atabey-mcp/src/mcp/routes/api-governance.js.map +1 -0
  31. package/dist/atabey-mcp/src/mcp/routes/api-orchestrator.d.ts +3 -0
  32. package/dist/atabey-mcp/src/mcp/routes/api-orchestrator.js +145 -0
  33. package/dist/atabey-mcp/src/mcp/routes/api-orchestrator.js.map +1 -0
  34. package/dist/atabey-mcp/src/mcp/routes/api-workspace.d.ts +3 -0
  35. package/dist/atabey-mcp/src/mcp/routes/api-workspace.js +274 -0
  36. package/dist/atabey-mcp/src/mcp/routes/api-workspace.js.map +1 -0
  37. package/dist/atabey-mcp/src/mcp/routes/index.d.ts +2 -0
  38. package/dist/atabey-mcp/src/mcp/routes/index.js +18 -1436
  39. package/dist/atabey-mcp/src/mcp/routes/index.js.map +1 -1
  40. package/dist/atabey-mcp/src/mcp/routes/types.d.ts +18 -0
  41. package/dist/atabey-mcp/src/mcp/routes/types.js +23 -0
  42. package/dist/atabey-mcp/src/mcp/routes/types.js.map +1 -0
  43. package/dist/atabey-mcp/src/mcp/tools/framework/orchestrate.d.ts +1 -1
  44. package/dist/atabey-mcp/src/mcp/tools/framework/orchestrate.js +11 -4
  45. package/dist/atabey-mcp/src/mcp/tools/framework/orchestrate.js.map +1 -1
  46. package/dist/atabey-mcp/src/mcp/utils/client-config.js +1 -1
  47. package/dist/atabey-mcp/src/mcp/utils/client-config.js.map +1 -1
  48. package/dist/atabey-mcp/src/mcp/utils/compliance-bootstrap.d.ts +8 -0
  49. package/dist/atabey-mcp/src/mcp/utils/compliance-bootstrap.js +46 -0
  50. package/dist/atabey-mcp/src/mcp/utils/compliance-bootstrap.js.map +1 -0
  51. package/dist/atabey-mcp/src/mcp/utils/consent.d.ts +25 -0
  52. package/dist/atabey-mcp/src/mcp/utils/consent.js +60 -0
  53. package/dist/atabey-mcp/src/mcp/utils/consent.js.map +1 -0
  54. package/dist/atabey-mcp/src/mcp/utils/finops.d.ts +7 -11
  55. package/dist/atabey-mcp/src/mcp/utils/finops.js +24 -26
  56. package/dist/atabey-mcp/src/mcp/utils/finops.js.map +1 -1
  57. package/dist/atabey-mcp/src/mcp/utils/framework-config.d.ts +27 -0
  58. package/dist/atabey-mcp/src/mcp/utils/framework-config.js +81 -0
  59. package/dist/atabey-mcp/src/mcp/utils/framework-config.js.map +1 -0
  60. package/dist/atabey-mcp/src/mcp/utils/orchestrator-bootstrap.d.ts +14 -0
  61. package/dist/atabey-mcp/src/mcp/utils/orchestrator-bootstrap.js +98 -0
  62. package/dist/atabey-mcp/src/mcp/utils/orchestrator-bootstrap.js.map +1 -0
  63. package/dist/atabey-mcp/src/mcp/utils/web-config.js +17 -35
  64. package/dist/atabey-mcp/src/mcp/utils/web-config.js.map +1 -1
  65. package/dist/dashboard/assets/{index-DHuA2rua.js → index-BUUxi_j8.js} +75 -75
  66. package/dist/dashboard/index.html +1 -1
  67. package/dist/shared/src/constants.d.ts +30 -1
  68. package/dist/shared/src/constants.js +25 -2
  69. package/dist/shared/src/constants.js.map +1 -1
  70. package/package.json +13 -2
@@ -0,0 +1,639 @@
1
+ import path from "path";
2
+ import { serveJson } from "./types.js";
3
+ import { Storage } from "../../shared/storage.js";
4
+ import { logger } from "../../shared/logger.js";
5
+ export async function handleConfigRoutes(pathname, params, method, req, res, context) {
6
+ // Knowledge Base List
7
+ if (pathname === "/api/knowledge" && req.method === "GET") {
8
+ try {
9
+ const list = Storage.getKnowledgeList();
10
+ serveJson(res, 200, { success: true, data: list });
11
+ }
12
+ catch (e) {
13
+ serveJson(res, 500, { success: false, error: e.message });
14
+ }
15
+ return true;
16
+ }
17
+ // Knowledge View
18
+ if (pathname === "/api/knowledge/view" && req.method === "GET") {
19
+ try {
20
+ const file = params.file;
21
+ if (!file) {
22
+ serveJson(res, 400, { success: false, error: "Missing 'file' parameter" });
23
+ return true;
24
+ }
25
+ const doc = Storage.getKnowledgeFile(file);
26
+ if (!doc) {
27
+ serveJson(res, 404, { success: false, error: "File not found" });
28
+ return true;
29
+ }
30
+ serveJson(res, 200, { success: true, data: doc });
31
+ }
32
+ catch (e) {
33
+ serveJson(res, 500, { success: false, error: e.message });
34
+ }
35
+ return true;
36
+ }
37
+ // Knowledge Update
38
+ if (pathname === "/api/knowledge/update" && req.method === "POST") {
39
+ try {
40
+ let body = "";
41
+ req.on("data", chunk => { body += chunk.toString(); });
42
+ req.on("end", async () => {
43
+ try {
44
+ const parsed = JSON.parse(body);
45
+ const file = parsed.file;
46
+ const content = parsed.content;
47
+ if (!file || content === undefined) {
48
+ serveJson(res, 400, { success: false, error: "Missing 'file' or 'content' in request body" });
49
+ return;
50
+ }
51
+ let safeFile = path.basename(file);
52
+ if (!safeFile.endsWith(".md")) {
53
+ safeFile += ".md";
54
+ }
55
+ Storage.saveKnowledgeFile(safeFile, content);
56
+ serveJson(res, 200, { success: true, message: `Knowledge document '${safeFile}' updated successfully.` });
57
+ }
58
+ catch (err) {
59
+ serveJson(res, 400, { success: false, error: err.message });
60
+ }
61
+ });
62
+ }
63
+ catch (e) {
64
+ serveJson(res, 500, { success: false, error: e.message });
65
+ }
66
+ return true;
67
+ }
68
+ // Knowledge Delete
69
+ if (pathname === "/api/knowledge/delete" && req.method === "POST") {
70
+ try {
71
+ let body = "";
72
+ req.on("data", chunk => { body += chunk.toString(); });
73
+ req.on("end", async () => {
74
+ try {
75
+ const parsed = JSON.parse(body);
76
+ const file = parsed.file;
77
+ if (!file) {
78
+ serveJson(res, 400, { success: false, error: "Missing 'file' in request body" });
79
+ return;
80
+ }
81
+ const safeFile = path.basename(file);
82
+ Storage.deleteKnowledgeFile(safeFile);
83
+ serveJson(res, 200, { success: true, message: `Knowledge document '${safeFile}' deleted.` });
84
+ }
85
+ catch (err) {
86
+ serveJson(res, 400, { success: false, error: err.message });
87
+ }
88
+ });
89
+ }
90
+ catch (e) {
91
+ serveJson(res, 500, { success: false, error: e.message });
92
+ }
93
+ return true;
94
+ }
95
+ // Constitution List
96
+ if (pathname === "/api/constitution" && req.method === "GET") {
97
+ try {
98
+ const db = Storage.getDB();
99
+ const sections = db.prepare("SELECT * FROM constitution ORDER BY priority DESC").all();
100
+ serveJson(res, 200, { success: true, data: sections });
101
+ }
102
+ catch (e) {
103
+ serveJson(res, 500, { success: false, error: e.message });
104
+ }
105
+ return true;
106
+ }
107
+ // Constitution Update
108
+ if (pathname === "/api/constitution/update" && req.method === "POST") {
109
+ try {
110
+ let body = "";
111
+ req.on("data", chunk => { body += chunk.toString(); });
112
+ req.on("end", async () => {
113
+ try {
114
+ const parsed = JSON.parse(body);
115
+ const { section, title, content } = parsed;
116
+ if (!section || !content) {
117
+ serveJson(res, 400, { success: false, error: "Missing 'section' or 'content'" });
118
+ return;
119
+ }
120
+ const db = Storage.getDB();
121
+ db.prepare(`
122
+ INSERT INTO constitution (section, title, content, updated_at)
123
+ VALUES (?, ?, ?, ?)
124
+ ON CONFLICT(section) DO UPDATE SET
125
+ title = excluded.title,
126
+ content = excluded.content,
127
+ updated_at = excluded.updated_at
128
+ `).run(section, title || "", content, new Date().toISOString());
129
+ serveJson(res, 200, { success: true, message: `Section '${section}' updated.` });
130
+ }
131
+ catch (err) {
132
+ serveJson(res, 400, { success: false, error: err.message });
133
+ }
134
+ });
135
+ }
136
+ catch (e) {
137
+ serveJson(res, 500, { success: false, error: e.message });
138
+ }
139
+ return true;
140
+ }
141
+ // CLI Commands
142
+ if (pathname === "/api/cli-commands" && req.method === "GET") {
143
+ try {
144
+ const db = Storage.getDB();
145
+ const commands = db.prepare("SELECT * FROM cli_commands ORDER BY command").all();
146
+ serveJson(res, 200, { success: true, data: commands });
147
+ }
148
+ catch (e) {
149
+ serveJson(res, 500, { success: false, error: e.message });
150
+ }
151
+ return true;
152
+ }
153
+ // Prompts List
154
+ if (pathname === "/api/prompts" && req.method === "GET") {
155
+ try {
156
+ const db = Storage.getDB();
157
+ const prompts = db.prepare("SELECT * FROM prompts ORDER BY category, name").all();
158
+ serveJson(res, 200, { success: true, data: prompts });
159
+ }
160
+ catch (e) {
161
+ serveJson(res, 500, { success: false, error: e.message });
162
+ }
163
+ return true;
164
+ }
165
+ // Prompts Update
166
+ if (pathname === "/api/prompts/update" && req.method === "POST") {
167
+ try {
168
+ let body = "";
169
+ req.on("data", chunk => { body += chunk.toString(); });
170
+ req.on("end", async () => {
171
+ try {
172
+ const parsed = JSON.parse(body);
173
+ const { name, category, content } = parsed;
174
+ if (!name || !content) {
175
+ serveJson(res, 400, { success: false, error: "Missing 'name' or 'content'" });
176
+ return;
177
+ }
178
+ const db = Storage.getDB();
179
+ db.prepare(`
180
+ INSERT INTO prompts (name, category, content, updated_at)
181
+ VALUES (?, ?, ?, ?)
182
+ ON CONFLICT(name) DO UPDATE SET
183
+ category = excluded.category,
184
+ content = excluded.content,
185
+ updated_at = excluded.updated_at
186
+ `).run(name, category || "general", content, new Date().toISOString());
187
+ serveJson(res, 200, { success: true, message: `Prompt '${name}' updated.` });
188
+ }
189
+ catch (err) {
190
+ serveJson(res, 400, { success: false, error: err.message });
191
+ }
192
+ });
193
+ }
194
+ catch (e) {
195
+ serveJson(res, 500, { success: false, error: e.message });
196
+ }
197
+ return true;
198
+ }
199
+ // Rules List
200
+ if (pathname === "/api/rules" && req.method === "GET") {
201
+ try {
202
+ const db = Storage.getDB();
203
+ const rules = db.prepare("SELECT * FROM rules ORDER BY name").all();
204
+ serveJson(res, 200, { success: true, data: rules });
205
+ }
206
+ catch (e) {
207
+ serveJson(res, 500, { success: false, error: e.message });
208
+ }
209
+ return true;
210
+ }
211
+ // Rules Update
212
+ if (pathname === "/api/rules/update" && req.method === "POST") {
213
+ try {
214
+ let body = "";
215
+ req.on("data", chunk => { body += chunk.toString(); });
216
+ req.on("end", async () => {
217
+ try {
218
+ const parsed = JSON.parse(body);
219
+ const { name, content, enabled } = parsed;
220
+ if (!name) {
221
+ serveJson(res, 400, { success: false, error: "Missing 'name'" });
222
+ return;
223
+ }
224
+ const db = Storage.getDB();
225
+ db.prepare(`
226
+ INSERT INTO rules (name, content, enabled, updated_at)
227
+ VALUES (?, ?, ?, ?)
228
+ ON CONFLICT(name) DO UPDATE SET
229
+ content = excluded.content,
230
+ enabled = excluded.enabled,
231
+ updated_at = excluded.updated_at
232
+ `).run(name, content || "", enabled !== undefined ? (enabled ? 1 : 0) : 1, new Date().toISOString());
233
+ serveJson(res, 200, { success: true, message: `Rule '${name}' updated.` });
234
+ }
235
+ catch (err) {
236
+ serveJson(res, 400, { success: false, error: err.message });
237
+ }
238
+ });
239
+ }
240
+ catch (e) {
241
+ serveJson(res, 500, { success: false, error: e.message });
242
+ }
243
+ return true;
244
+ }
245
+ // Registry List
246
+ if (pathname === "/api/registry" && req.method === "GET") {
247
+ try {
248
+ const db = Storage.getDB();
249
+ const items = db.prepare("SELECT * FROM registry ORDER BY type, name").all();
250
+ serveJson(res, 200, { success: true, data: items });
251
+ }
252
+ catch (e) {
253
+ serveJson(res, 500, { success: false, error: e.message });
254
+ }
255
+ return true;
256
+ }
257
+ // Registry Update
258
+ if (pathname === "/api/registry/update" && req.method === "POST") {
259
+ try {
260
+ let body = "";
261
+ req.on("data", chunk => { body += chunk.toString(); });
262
+ req.on("end", async () => {
263
+ try {
264
+ const parsed = JSON.parse(body);
265
+ const { name, type, data } = parsed;
266
+ if (!name) {
267
+ serveJson(res, 400, { success: false, error: "Missing 'name'" });
268
+ return;
269
+ }
270
+ const db = Storage.getDB();
271
+ db.prepare(`
272
+ INSERT INTO registry (name, type, data, updated_at)
273
+ VALUES (?, ?, ?, ?)
274
+ ON CONFLICT(name) DO UPDATE SET
275
+ type = excluded.type,
276
+ data = excluded.data,
277
+ updated_at = excluded.updated_at
278
+ `).run(name, type || "agent", data || "{}", new Date().toISOString());
279
+ serveJson(res, 200, { success: true, message: `Registry '${name}' updated.` });
280
+ }
281
+ catch (err) {
282
+ serveJson(res, 400, { success: false, error: err.message });
283
+ }
284
+ });
285
+ }
286
+ catch (e) {
287
+ serveJson(res, 500, { success: false, error: e.message });
288
+ }
289
+ return true;
290
+ }
291
+ // Settings (Config settings - legacy)
292
+ if (pathname === "/api/settings" && req.method === "GET" && !params.legacy_check) {
293
+ // Wait, index.ts has two distinct "/api/settings" GET/POST blocks.
294
+ // One is in lines 728-751 (projectPath & activeProvider from Storage)
295
+ // One is in lines 1061-1100 (loadWebConfig from web-config.js)
296
+ // Let's check which one matches what.
297
+ // The one in lines 1061 loads safe config with keys. Let's merge them!
298
+ // Actually, let's keep both, but we can differentiate them by headers/body, or just keep them as they were.
299
+ // Let's implement the first one if it doesn't match the second one.
300
+ // Actually, the second one uses `loadWebConfig` which is preferred for dashboard UI configuration.
301
+ // Let's merge them: if it's GET, we return the settings loaded from webConfig and from metadata.
302
+ }
303
+ // Let's check settings routes specifically:
304
+ // GET Settings (Combined load)
305
+ if (pathname === "/api/settings" && req.method === "GET") {
306
+ try {
307
+ const { loadWebConfig } = await import("../utils/web-config.js");
308
+ const config = loadWebConfig();
309
+ const projectPath = config.projectPath || Storage.getMetadata("projectPath") || "";
310
+ const activeProvider = config.activeProvider || Storage.getMetadata("activeProvider") || "gemini";
311
+ const safeConfig = {
312
+ projectPath,
313
+ activeProvider,
314
+ geminiApiKey: config.geminiApiKey ? "********" : "",
315
+ anthropicApiKey: config.anthropicApiKey ? "********" : "",
316
+ openaiApiKey: config.openaiApiKey ? "********" : "",
317
+ };
318
+ serveJson(res, 200, { success: true, data: safeConfig });
319
+ }
320
+ catch (e) {
321
+ serveJson(res, 500, { success: false, error: e.message });
322
+ }
323
+ return true;
324
+ }
325
+ // POST Settings (Save)
326
+ if (pathname === "/api/settings" && req.method === "POST") {
327
+ try {
328
+ let body = "";
329
+ req.on("data", chunk => { body += chunk.toString(); });
330
+ req.on("end", async () => {
331
+ try {
332
+ const parsed = JSON.parse(body);
333
+ // Metadata storage
334
+ if (parsed.projectPath !== undefined)
335
+ Storage.setMetadata("projectPath", parsed.projectPath);
336
+ if (parsed.activeProvider !== undefined)
337
+ Storage.setMetadata("activeProvider", parsed.activeProvider);
338
+ // Config file storage
339
+ const { saveWebConfig } = await import("../utils/web-config.js");
340
+ const configToSave = {};
341
+ if (parsed.projectPath)
342
+ configToSave.projectPath = parsed.projectPath;
343
+ if (parsed.activeProvider)
344
+ configToSave.activeProvider = parsed.activeProvider;
345
+ if (parsed.geminiApiKey && parsed.geminiApiKey !== "********")
346
+ configToSave.geminiApiKey = parsed.geminiApiKey;
347
+ if (parsed.anthropicApiKey && parsed.anthropicApiKey !== "********")
348
+ configToSave.anthropicApiKey = parsed.anthropicApiKey;
349
+ if (parsed.openaiApiKey && parsed.openaiApiKey !== "********")
350
+ configToSave.openaiApiKey = parsed.openaiApiKey;
351
+ const saved = saveWebConfig(configToSave);
352
+ serveJson(res, 200, { success: true, message: "Settings saved successfully", projectPath: saved.projectPath });
353
+ }
354
+ catch (err) {
355
+ serveJson(res, 400, { success: false, error: err.message });
356
+ }
357
+ });
358
+ }
359
+ catch (e) {
360
+ serveJson(res, 500, { success: false, error: e.message });
361
+ }
362
+ return true;
363
+ }
364
+ // Config metadata GET
365
+ if (pathname === "/api/config" && req.method === "GET") {
366
+ try {
367
+ const db = Storage.getDB();
368
+ const configs = db.prepare("SELECT * FROM metadata WHERE key LIKE 'config.%'").all();
369
+ const config = {};
370
+ for (const c of configs) {
371
+ config[c.key.replace("config.", "")] = c.value;
372
+ }
373
+ serveJson(res, 200, { success: true, data: config });
374
+ }
375
+ catch (e) {
376
+ serveJson(res, 500, { success: false, error: e.message });
377
+ }
378
+ return true;
379
+ }
380
+ // Adapter Skills summary
381
+ if (pathname === "/api/adapters/skills") {
382
+ try {
383
+ const { ADAPTER_SKILLS } = await import("atabey/src/modules/skills/adapter-skills.js");
384
+ const summary = Object.entries(ADAPTER_SKILLS).map(([id, config]) => ({
385
+ id, skillCount: Object.keys(config.enabledSkills).length,
386
+ toolsCount: config.toolMapping ? Object.keys(config.toolMapping).length : 0,
387
+ skills: Object.entries(config.enabledSkills).map(([skId, skVal]) => ({
388
+ id: skId,
389
+ name: skVal.name,
390
+ disabled: !!skVal.disabled
391
+ })),
392
+ }));
393
+ serveJson(res, 200, { success: true, data: summary });
394
+ }
395
+ catch (e) {
396
+ serveJson(res, 500, { success: false, error: e.message });
397
+ }
398
+ return true;
399
+ }
400
+ // Adapter Skill Toggle
401
+ if (pathname === "/api/adapters/skills/toggle" && method === "POST") {
402
+ try {
403
+ let body = "";
404
+ req.on("data", chunk => { body += chunk.toString(); });
405
+ req.on("end", async () => {
406
+ try {
407
+ const parsed = JSON.parse(body);
408
+ const { adapterId, skillId } = parsed;
409
+ if (!adapterId || !skillId) {
410
+ serveJson(res, 400, { success: false, error: "Missing adapterId or skillId" });
411
+ return;
412
+ }
413
+ const { ADAPTER_SKILLS } = await import("atabey/src/modules/skills/adapter-skills.js");
414
+ const adapter = ADAPTER_SKILLS[adapterId];
415
+ if (!adapter || !adapter.enabledSkills[skillId]) {
416
+ serveJson(res, 404, { success: false, error: "Adapter or skill not found" });
417
+ return;
418
+ }
419
+ const skill = adapter.enabledSkills[skillId];
420
+ skill.disabled = !skill.disabled;
421
+ serveJson(res, 200, { success: true, disabled: !!skill.disabled });
422
+ }
423
+ catch (err) {
424
+ serveJson(res, 400, { success: false, error: err.message });
425
+ }
426
+ });
427
+ }
428
+ catch (e) {
429
+ serveJson(res, 500, { success: false, error: e.message });
430
+ }
431
+ return true;
432
+ }
433
+ // Auth Login
434
+ if (pathname === "/api/auth/login" && req.method === "POST") {
435
+ try {
436
+ let body = "";
437
+ req.on("data", chunk => { body += chunk.toString(); });
438
+ req.on("end", async () => {
439
+ try {
440
+ const parsed = JSON.parse(body);
441
+ const { username, token } = parsed;
442
+ if (!username || !token) {
443
+ serveJson(res, 400, { success: false, error: "Username and token are required" });
444
+ return;
445
+ }
446
+ const maskedToken = token.length > 8 ? `${token.slice(0, 4)}...${token.slice(-4)}` : "***";
447
+ logger.info(`[LOGIN ATTEMPT] username="${username}", token="${maskedToken}"`);
448
+ const { authenticateToken } = await import("../utils/auth.js");
449
+ const result = authenticateToken(token);
450
+ logger.info(`[LOGIN RESULT] authenticated=${result.authenticated}, user="${result.user}"`);
451
+ if (result.authenticated && (result.user === username || (result.user === "admin" && username === "admin"))) {
452
+ serveJson(res, 200, { success: true, user: { name: username, role: result.user === "admin" ? "admin" : "user" } });
453
+ }
454
+ else {
455
+ serveJson(res, 401, { success: false, error: "Invalid username or token" });
456
+ }
457
+ }
458
+ catch (err) {
459
+ logger.error(`[LOGIN ERROR] ${err.message}`);
460
+ serveJson(res, 400, { success: false, error: err.message });
461
+ }
462
+ });
463
+ }
464
+ catch (e) {
465
+ serveJson(res, 500, { success: false, error: e.message });
466
+ }
467
+ return true;
468
+ }
469
+ // GET Admin Users
470
+ if (pathname === "/api/admin/users" && req.method === "GET") {
471
+ try {
472
+ const users = Storage.getUsers();
473
+ serveJson(res, 200, { success: true, data: users });
474
+ }
475
+ catch (e) {
476
+ serveJson(res, 500, { success: false, error: e.message });
477
+ }
478
+ return true;
479
+ }
480
+ // POST Create/Update Admin User
481
+ if (pathname === "/api/admin/users/create" && req.method === "POST") {
482
+ try {
483
+ let body = "";
484
+ req.on("data", chunk => { body += chunk.toString(); });
485
+ req.on("end", async () => {
486
+ try {
487
+ const parsed = JSON.parse(body);
488
+ const { name, token, role } = parsed;
489
+ if (!name || !token) {
490
+ serveJson(res, 400, { success: false, error: "Username and token are required" });
491
+ return;
492
+ }
493
+ Storage.createUser(name.trim(), token.trim(), role || "user");
494
+ serveJson(res, 200, { success: true, message: `User ${name} created/updated successfully.` });
495
+ }
496
+ catch (err) {
497
+ serveJson(res, 400, { success: false, error: err.message });
498
+ }
499
+ });
500
+ }
501
+ catch (e) {
502
+ serveJson(res, 500, { success: false, error: e.message });
503
+ }
504
+ return true;
505
+ }
506
+ // POST Delete Admin User
507
+ if (pathname === "/api/admin/users/delete" && req.method === "POST") {
508
+ try {
509
+ let body = "";
510
+ req.on("data", chunk => { body += chunk.toString(); });
511
+ req.on("end", async () => {
512
+ try {
513
+ const parsed = JSON.parse(body);
514
+ const { name } = parsed;
515
+ if (!name) {
516
+ serveJson(res, 400, { success: false, error: "Username is required" });
517
+ return;
518
+ }
519
+ Storage.deleteUser(name);
520
+ serveJson(res, 200, { success: true, message: `User ${name} deleted.` });
521
+ }
522
+ catch (err) {
523
+ serveJson(res, 400, { success: false, error: err.message });
524
+ }
525
+ });
526
+ }
527
+ catch (e) {
528
+ serveJson(res, 500, { success: false, error: e.message });
529
+ }
530
+ return true;
531
+ }
532
+ // Orchestrator Status
533
+ if (pathname === "/api/orchestrator/status" && method === "GET") {
534
+ try {
535
+ const { getOrchestratorState } = await import("../utils/web-config.js");
536
+ serveJson(res, 200, { success: true, data: getOrchestratorState() });
537
+ }
538
+ catch (e) {
539
+ serveJson(res, 500, { success: false, error: e.message });
540
+ }
541
+ return true;
542
+ }
543
+ // Orchestrator Start
544
+ if (pathname === "/api/orchestrator/start" && method === "POST") {
545
+ try {
546
+ const { startOrchestratorLoop } = await import("../utils/web-config.js");
547
+ const result = startOrchestratorLoop();
548
+ if (result.success) {
549
+ context.broadcastWS("orchestrator_state", { running: true });
550
+ serveJson(res, 200, { success: true, message: result.message });
551
+ }
552
+ else {
553
+ serveJson(res, 400, { success: false, error: result.message });
554
+ }
555
+ }
556
+ catch (e) {
557
+ serveJson(res, 500, { success: false, error: e.message });
558
+ }
559
+ return true;
560
+ }
561
+ // Orchestrator Stop
562
+ if (pathname === "/api/orchestrator/stop" && method === "POST") {
563
+ try {
564
+ const { stopOrchestratorLoop } = await import("../utils/web-config.js");
565
+ const result = stopOrchestratorLoop();
566
+ if (result.success) {
567
+ context.broadcastWS("orchestrator_state", { running: false });
568
+ serveJson(res, 200, { success: true, message: result.message });
569
+ }
570
+ else {
571
+ serveJson(res, 400, { success: false, error: result.message });
572
+ }
573
+ }
574
+ catch (e) {
575
+ serveJson(res, 500, { success: false, error: e.message });
576
+ }
577
+ return true;
578
+ }
579
+ // GET Token Budget Config
580
+ if (pathname === "/api/token-budget/config" && method === "GET") {
581
+ try {
582
+ const { getTokenBudgetConfig } = await import("../utils/context-optimizer.js");
583
+ const config = getTokenBudgetConfig();
584
+ serveJson(res, 200, { success: true, data: config });
585
+ }
586
+ catch (e) {
587
+ serveJson(res, 500, { success: false, error: e.message });
588
+ }
589
+ return true;
590
+ }
591
+ // UPDATE Token Budget Config
592
+ if (pathname === "/api/token-budget/config/update" && method === "POST") {
593
+ try {
594
+ let body = "";
595
+ req.on("data", chunk => { body += chunk.toString(); });
596
+ req.on("end", async () => {
597
+ try {
598
+ const parsed = JSON.parse(body);
599
+ const { updateTokenBudgetConfig } = await import("../utils/context-optimizer.js");
600
+ updateTokenBudgetConfig(parsed);
601
+ serveJson(res, 200, { success: true, message: "Token budget configuration updated successfully." });
602
+ }
603
+ catch (err) {
604
+ serveJson(res, 400, { success: false, error: err.message });
605
+ }
606
+ });
607
+ }
608
+ catch (e) {
609
+ serveJson(res, 500, { success: false, error: e.message });
610
+ }
611
+ return true;
612
+ }
613
+ // RESET Agent Token Budgets
614
+ if (pathname === "/api/token-budget/reset" && method === "POST") {
615
+ try {
616
+ const { resetTokenBudgets } = await import("../utils/context-optimizer.js");
617
+ resetTokenBudgets();
618
+ serveJson(res, 200, { success: true, message: "All agent token budgets reset successfully." });
619
+ }
620
+ catch (e) {
621
+ serveJson(res, 500, { success: false, error: e.message });
622
+ }
623
+ return true;
624
+ }
625
+ // Telemetry Status
626
+ if (pathname === "/api/telemetry") {
627
+ try {
628
+ const { telemetryStreamer, TelemetryConfig } = await import("../utils/telemetry-streamer.js");
629
+ const status = telemetryStreamer.getStatus();
630
+ serveJson(res, 200, { success: true, data: { ...status, config: { ...TelemetryConfig, AUTH_TOKEN: TelemetryConfig.AUTH_TOKEN ? "***" : "" } } });
631
+ }
632
+ catch (e) {
633
+ serveJson(res, 500, { success: false, error: e.message });
634
+ }
635
+ return true;
636
+ }
637
+ return false;
638
+ }
639
+ //# sourceMappingURL=api-config.js.map