@0xmaxma/claude-gateway 1.0.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 (192) hide show
  1. package/README.md +791 -0
  2. package/config.template.json +87 -0
  3. package/dist/agent/context-isolation.d.ts +28 -0
  4. package/dist/agent/context-isolation.d.ts.map +1 -0
  5. package/dist/agent/context-isolation.js +80 -0
  6. package/dist/agent/context-isolation.js.map +1 -0
  7. package/dist/agent/runner.d.ts +211 -0
  8. package/dist/agent/runner.d.ts.map +1 -0
  9. package/dist/agent/runner.js +1802 -0
  10. package/dist/agent/runner.js.map +1 -0
  11. package/dist/agent/workspace-loader.d.ts +31 -0
  12. package/dist/agent/workspace-loader.d.ts.map +1 -0
  13. package/dist/agent/workspace-loader.js +207 -0
  14. package/dist/agent/workspace-loader.js.map +1 -0
  15. package/dist/api/auth.d.ts +25 -0
  16. package/dist/api/auth.d.ts.map +1 -0
  17. package/dist/api/auth.js +77 -0
  18. package/dist/api/auth.js.map +1 -0
  19. package/dist/api/cron-router.d.ts +22 -0
  20. package/dist/api/cron-router.d.ts.map +1 -0
  21. package/dist/api/cron-router.js +197 -0
  22. package/dist/api/cron-router.js.map +1 -0
  23. package/dist/api/gateway-router.d.ts +52 -0
  24. package/dist/api/gateway-router.d.ts.map +1 -0
  25. package/dist/api/gateway-router.js +215 -0
  26. package/dist/api/gateway-router.js.map +1 -0
  27. package/dist/api/router.d.ts +5 -0
  28. package/dist/api/router.d.ts.map +1 -0
  29. package/dist/api/router.js +1098 -0
  30. package/dist/api/router.js.map +1 -0
  31. package/dist/api/skills-router.d.ts +5 -0
  32. package/dist/api/skills-router.d.ts.map +1 -0
  33. package/dist/api/skills-router.js +424 -0
  34. package/dist/api/skills-router.js.map +1 -0
  35. package/dist/api/workspace-router.d.ts +4 -0
  36. package/dist/api/workspace-router.d.ts.map +1 -0
  37. package/dist/api/workspace-router.js +149 -0
  38. package/dist/api/workspace-router.js.map +1 -0
  39. package/dist/config/loader.d.ts +16 -0
  40. package/dist/config/loader.d.ts.map +1 -0
  41. package/dist/config/loader.js +235 -0
  42. package/dist/config/loader.js.map +1 -0
  43. package/dist/config/migrator.d.ts +70 -0
  44. package/dist/config/migrator.d.ts.map +1 -0
  45. package/dist/config/migrator.js +343 -0
  46. package/dist/config/migrator.js.map +1 -0
  47. package/dist/config/watcher.d.ts +30 -0
  48. package/dist/config/watcher.d.ts.map +1 -0
  49. package/dist/config/watcher.js +170 -0
  50. package/dist/config/watcher.js.map +1 -0
  51. package/dist/cron/manager.d.ts +48 -0
  52. package/dist/cron/manager.d.ts.map +1 -0
  53. package/dist/cron/manager.js +580 -0
  54. package/dist/cron/manager.js.map +1 -0
  55. package/dist/cron/scheduler.d.ts +50 -0
  56. package/dist/cron/scheduler.d.ts.map +1 -0
  57. package/dist/cron/scheduler.js +231 -0
  58. package/dist/cron/scheduler.js.map +1 -0
  59. package/dist/discord/receiver.d.ts +17 -0
  60. package/dist/discord/receiver.d.ts.map +1 -0
  61. package/dist/discord/receiver.js +108 -0
  62. package/dist/discord/receiver.js.map +1 -0
  63. package/dist/heartbeat/history.d.ts +24 -0
  64. package/dist/heartbeat/history.d.ts.map +1 -0
  65. package/dist/heartbeat/history.js +50 -0
  66. package/dist/heartbeat/history.js.map +1 -0
  67. package/dist/heartbeat/parser.d.ts +26 -0
  68. package/dist/heartbeat/parser.d.ts.map +1 -0
  69. package/dist/heartbeat/parser.js +283 -0
  70. package/dist/heartbeat/parser.js.map +1 -0
  71. package/dist/history/cleanup.d.ts +21 -0
  72. package/dist/history/cleanup.d.ts.map +1 -0
  73. package/dist/history/cleanup.js +171 -0
  74. package/dist/history/cleanup.js.map +1 -0
  75. package/dist/history/db.d.ts +27 -0
  76. package/dist/history/db.d.ts.map +1 -0
  77. package/dist/history/db.js +323 -0
  78. package/dist/history/db.js.map +1 -0
  79. package/dist/history/media-store.d.ts +27 -0
  80. package/dist/history/media-store.d.ts.map +1 -0
  81. package/dist/history/media-store.js +158 -0
  82. package/dist/history/media-store.js.map +1 -0
  83. package/dist/history/types.d.ts +62 -0
  84. package/dist/history/types.d.ts.map +1 -0
  85. package/dist/history/types.js +3 -0
  86. package/dist/history/types.js.map +1 -0
  87. package/dist/index.d.ts +3 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +483 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/logger.d.ts +3 -0
  92. package/dist/logger.d.ts.map +1 -0
  93. package/dist/logger.js +81 -0
  94. package/dist/logger.js.map +1 -0
  95. package/dist/memory/manager.d.ts +45 -0
  96. package/dist/memory/manager.d.ts.map +1 -0
  97. package/dist/memory/manager.js +178 -0
  98. package/dist/memory/manager.js.map +1 -0
  99. package/dist/session/compactor.d.ts +22 -0
  100. package/dist/session/compactor.d.ts.map +1 -0
  101. package/dist/session/compactor.js +151 -0
  102. package/dist/session/compactor.js.map +1 -0
  103. package/dist/session/process.d.ts +76 -0
  104. package/dist/session/process.d.ts.map +1 -0
  105. package/dist/session/process.js +729 -0
  106. package/dist/session/process.js.map +1 -0
  107. package/dist/session/store.d.ts +102 -0
  108. package/dist/session/store.d.ts.map +1 -0
  109. package/dist/session/store.js +533 -0
  110. package/dist/session/store.js.map +1 -0
  111. package/dist/skills/index.d.ts +9 -0
  112. package/dist/skills/index.d.ts.map +1 -0
  113. package/dist/skills/index.js +15 -0
  114. package/dist/skills/index.js.map +1 -0
  115. package/dist/skills/invoker.d.ts +16 -0
  116. package/dist/skills/invoker.d.ts.map +1 -0
  117. package/dist/skills/invoker.js +36 -0
  118. package/dist/skills/invoker.js.map +1 -0
  119. package/dist/skills/loader.d.ts +23 -0
  120. package/dist/skills/loader.d.ts.map +1 -0
  121. package/dist/skills/loader.js +183 -0
  122. package/dist/skills/loader.js.map +1 -0
  123. package/dist/skills/parser.d.ts +55 -0
  124. package/dist/skills/parser.d.ts.map +1 -0
  125. package/dist/skills/parser.js +178 -0
  126. package/dist/skills/parser.js.map +1 -0
  127. package/dist/skills/sync.d.ts +10 -0
  128. package/dist/skills/sync.d.ts.map +1 -0
  129. package/dist/skills/sync.js +130 -0
  130. package/dist/skills/sync.js.map +1 -0
  131. package/dist/skills/watcher.d.ts +16 -0
  132. package/dist/skills/watcher.d.ts.map +1 -0
  133. package/dist/skills/watcher.js +25 -0
  134. package/dist/skills/watcher.js.map +1 -0
  135. package/dist/telegram/markdown.d.ts +25 -0
  136. package/dist/telegram/markdown.d.ts.map +1 -0
  137. package/dist/telegram/markdown.js +237 -0
  138. package/dist/telegram/markdown.js.map +1 -0
  139. package/dist/telegram/receiver.d.ts +17 -0
  140. package/dist/telegram/receiver.d.ts.map +1 -0
  141. package/dist/telegram/receiver.js +104 -0
  142. package/dist/telegram/receiver.js.map +1 -0
  143. package/dist/types.d.ts +224 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +3 -0
  146. package/dist/types.js.map +1 -0
  147. package/dist/ui/web-ui.d.ts +6 -0
  148. package/dist/ui/web-ui.d.ts.map +1 -0
  149. package/dist/ui/web-ui.js +227 -0
  150. package/dist/ui/web-ui.js.map +1 -0
  151. package/dist/watch/factory.d.ts +26 -0
  152. package/dist/watch/factory.d.ts.map +1 -0
  153. package/dist/watch/factory.js +43 -0
  154. package/dist/watch/factory.js.map +1 -0
  155. package/dist/webhook/manager.d.ts +34 -0
  156. package/dist/webhook/manager.d.ts.map +1 -0
  157. package/dist/webhook/manager.js +120 -0
  158. package/dist/webhook/manager.js.map +1 -0
  159. package/mcp/bun.lock +264 -0
  160. package/mcp/channel-manager.ts +115 -0
  161. package/mcp/package.json +15 -0
  162. package/mcp/router.ts +69 -0
  163. package/mcp/server.ts +129 -0
  164. package/mcp/tools/agent/handlers.ts +578 -0
  165. package/mcp/tools/agent/module.ts +163 -0
  166. package/mcp/tools/browser/module.ts +321 -0
  167. package/mcp/tools/browser/skills/open-browser/SKILL.md +89 -0
  168. package/mcp/tools/cron/client.ts +65 -0
  169. package/mcp/tools/cron/module.ts +158 -0
  170. package/mcp/tools/cron/skills/cron/SKILL.md +46 -0
  171. package/mcp/tools/discord/access.ts +197 -0
  172. package/mcp/tools/discord/client.ts +31 -0
  173. package/mcp/tools/discord/commands.ts +48 -0
  174. package/mcp/tools/discord/inbound.ts +53 -0
  175. package/mcp/tools/discord/module.ts +442 -0
  176. package/mcp/tools/discord/outbound.ts +90 -0
  177. package/mcp/tools/discord/receiver-server.ts +58 -0
  178. package/mcp/tools/discord/skills/access/SKILL.md +86 -0
  179. package/mcp/tools/discord/skills/configure/SKILL.md +53 -0
  180. package/mcp/tools/discord/threading.ts +37 -0
  181. package/mcp/tools/discord/types.ts +106 -0
  182. package/mcp/tools/skills/handlers.ts +196 -0
  183. package/mcp/tools/skills/module.ts +163 -0
  184. package/mcp/tools/telegram/module.ts +454 -0
  185. package/mcp/tools/telegram/pure.ts +224 -0
  186. package/mcp/tools/telegram/receiver-server.ts +1656 -0
  187. package/mcp/tools/telegram/skills/access/SKILL.md +169 -0
  188. package/mcp/tools/telegram/skills/configure/SKILL.md +118 -0
  189. package/mcp/tools/telegram/typing.ts +327 -0
  190. package/mcp/types.ts +128 -0
  191. package/package.json +62 -0
  192. package/resource/claude_gateway.svg +112 -0
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCronRouter = createCronRouter;
4
+ const express_1 = require("express");
5
+ const auth_1 = require("./auth");
6
+ /**
7
+ * Creates Express routes for managing persistent cron jobs.
8
+ *
9
+ * All routes require a valid API key (Authorization: Bearer or X-Api-Key header).
10
+ * Write operations (create/update/delete/run) additionally verify that the key
11
+ * has access to the job's agentId via canAccessAgent().
12
+ *
13
+ * Routes:
14
+ * GET /v1/crons — List jobs accessible by this key
15
+ * GET /v1/crons/status — Overall scheduler status
16
+ * POST /v1/crons — Create a new job
17
+ * GET /v1/crons/:id — Get a single job
18
+ * PUT /v1/crons/:id — Update a job
19
+ * DELETE /v1/crons/:id — Delete a job
20
+ * POST /v1/crons/:id/run — Trigger a job manually
21
+ * GET /v1/crons/:id/runs — Get run history
22
+ */
23
+ function createCronRouter(manager, apiKeys, knownAgentIds) {
24
+ const router = (0, express_1.Router)();
25
+ // Apply auth middleware if apiKeys are provided
26
+ if (apiKeys?.length) {
27
+ router.use((0, auth_1.createApiAuthMiddleware)(apiKeys));
28
+ }
29
+ // Helper: check agent access for jobs retrieved by id
30
+ function checkJobAccess(req, res, agentId) {
31
+ if (!apiKeys?.length)
32
+ return true; // no auth configured — allow all
33
+ const apiKey = req.apiKey;
34
+ if (!(0, auth_1.canAccessAgent)(apiKey, agentId)) {
35
+ res.status(403).json({ error: `API key has no access to agent '${agentId}'` });
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+ // List jobs — filtered to agents this key can access
41
+ router.get('/v1/crons', (_req, res) => {
42
+ const agentId = _req.query.agent;
43
+ let jobs = manager.list(agentId);
44
+ // Filter by key's agent scope
45
+ if (apiKeys?.length) {
46
+ const apiKey = _req.apiKey;
47
+ if (apiKey.agents !== '*') {
48
+ const allowed = apiKey.agents;
49
+ jobs = jobs.filter((j) => allowed.includes(j.agentId));
50
+ }
51
+ }
52
+ res.json({ jobs });
53
+ });
54
+ // Overall status
55
+ router.get('/v1/crons/status', (_req, res) => {
56
+ res.json(manager.status());
57
+ });
58
+ // Create job
59
+ router.post('/v1/crons', async (req, res) => {
60
+ const body = req.body;
61
+ if (!body.agentId || !body.name) {
62
+ res.status(400).json({ error: 'Required fields: agentId, name' });
63
+ return;
64
+ }
65
+ if (!checkJobAccess(req, res, body.agentId))
66
+ return;
67
+ if (knownAgentIds && !knownAgentIds.has(body.agentId)) {
68
+ res.status(404).json({ error: `Agent '${body.agentId}' not found` });
69
+ return;
70
+ }
71
+ const scheduleKind = body.scheduleKind ?? 'cron';
72
+ const type = body.type ?? 'command';
73
+ // Schedule validation
74
+ if (scheduleKind === 'cron' && !body.schedule) {
75
+ res.status(400).json({ error: 'schedule is required for scheduleKind=cron' });
76
+ return;
77
+ }
78
+ if (scheduleKind === 'at' && !body.scheduleAt) {
79
+ res.status(400).json({ error: 'scheduleAt is required for scheduleKind=at' });
80
+ return;
81
+ }
82
+ if (scheduleKind === 'at' && body.scheduleAt && isNaN(Date.parse(body.scheduleAt))) {
83
+ res.status(400).json({ error: `Invalid ISO-8601 timestamp: "${body.scheduleAt}"` });
84
+ return;
85
+ }
86
+ // Payload validation
87
+ if (type === 'command' && !body.command) {
88
+ res.status(400).json({ error: 'command is required for type=command' });
89
+ return;
90
+ }
91
+ if (type === 'agent' && !body.prompt) {
92
+ res.status(400).json({ error: 'prompt is required for type=agent' });
93
+ return;
94
+ }
95
+ if (type === 'agent' && !body.telegram && !body.discord) {
96
+ res.status(400).json({ error: 'telegram or discord is required for type=agent' });
97
+ return;
98
+ }
99
+ try {
100
+ const job = await manager.create(body);
101
+ res.status(201).json({ job });
102
+ }
103
+ catch (err) {
104
+ res.status(400).json({ error: err.message });
105
+ }
106
+ });
107
+ // Get single job
108
+ router.get('/v1/crons/:id', (req, res) => {
109
+ const job = manager.get(req.params.id);
110
+ if (!job) {
111
+ res.status(404).json({ error: 'Job not found' });
112
+ return;
113
+ }
114
+ if (!checkJobAccess(req, res, job.agentId))
115
+ return;
116
+ res.json({ job });
117
+ });
118
+ // Update job
119
+ router.put('/v1/crons/:id', async (req, res) => {
120
+ const job = manager.get(req.params.id);
121
+ if (!job) {
122
+ res.status(404).json({ error: 'Job not found' });
123
+ return;
124
+ }
125
+ if (!checkJobAccess(req, res, job.agentId))
126
+ return;
127
+ try {
128
+ const updated = await manager.update(req.params.id, req.body);
129
+ res.json({ job: updated });
130
+ }
131
+ catch (err) {
132
+ const message = err.message;
133
+ if (message.includes('not found')) {
134
+ res.status(404).json({ error: message });
135
+ }
136
+ else {
137
+ res.status(400).json({ error: message });
138
+ }
139
+ }
140
+ });
141
+ // Delete job
142
+ router.delete('/v1/crons/:id', async (req, res) => {
143
+ const job = manager.get(req.params.id);
144
+ if (!job) {
145
+ res.status(404).json({ error: 'Job not found' });
146
+ return;
147
+ }
148
+ if (!checkJobAccess(req, res, job.agentId))
149
+ return;
150
+ try {
151
+ await manager.remove(req.params.id);
152
+ res.json({ ok: true });
153
+ }
154
+ catch (err) {
155
+ const message = err.message;
156
+ res.status(500).json({ error: message });
157
+ }
158
+ });
159
+ // Manual trigger
160
+ router.post('/v1/crons/:id/run', async (req, res) => {
161
+ const job = manager.get(req.params.id);
162
+ if (!job) {
163
+ res.status(404).json({ error: 'Job not found' });
164
+ return;
165
+ }
166
+ if (!checkJobAccess(req, res, job.agentId))
167
+ return;
168
+ try {
169
+ const log = await manager.run(req.params.id);
170
+ res.json({ run: log });
171
+ }
172
+ catch (err) {
173
+ const message = err.message;
174
+ res.status(500).json({ error: message });
175
+ }
176
+ });
177
+ // Run history
178
+ router.get('/v1/crons/:id/runs', async (req, res) => {
179
+ const job = manager.get(req.params.id);
180
+ if (!job) {
181
+ res.status(404).json({ error: 'Job not found' });
182
+ return;
183
+ }
184
+ if (!checkJobAccess(req, res, job.agentId))
185
+ return;
186
+ const limit = parseInt(req.query.limit) || 20;
187
+ try {
188
+ const runs = await manager.getRuns(req.params.id, limit);
189
+ res.json({ runs });
190
+ }
191
+ catch (err) {
192
+ res.status(500).json({ error: err.message });
193
+ }
194
+ });
195
+ return router;
196
+ }
197
+ //# sourceMappingURL=cron-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-router.js","sourceRoot":"","sources":["../../src/api/cron-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import express from 'express';
2
+ import { AgentRunner } from '../agent/runner';
3
+ import { AgentConfig, AgentStats, ApiKey, GatewayConfig } from '../types';
4
+ import { CronScheduler } from '../cron/scheduler';
5
+ import { CronManager } from '../cron/manager';
6
+ export declare class GatewayRouter {
7
+ private readonly agents;
8
+ private readonly configs;
9
+ private readonly app;
10
+ private server;
11
+ /** Per-agent message counters (output lines from subprocess) */
12
+ private readonly messagesReceived;
13
+ private readonly messagesSent;
14
+ /** Per-agent last activity timestamps */
15
+ private readonly lastActivityAt;
16
+ /** Per-agent recent sessions (last 5): Map<agentId, Array<sessionInfo>> */
17
+ private readonly recentSessions;
18
+ /** Optional per-agent cron schedulers (for /status endpoint) */
19
+ private readonly schedulers;
20
+ /** Gateway start time */
21
+ private readonly startedAt;
22
+ /** Optional gateway config (used to mount API router) */
23
+ private readonly gatewayConfig?;
24
+ /** Optional persistent cron manager */
25
+ private readonly cronManager?;
26
+ /** Path to config.json for agent CRUD operations */
27
+ private readonly configPath?;
28
+ constructor(agents: Map<string, AgentRunner>, configs: Map<string, AgentConfig>, schedulers?: Map<string, CronScheduler>, gatewayConfig?: GatewayConfig, cronManager?: CronManager, configPath?: string);
29
+ private setupRoutes;
30
+ start(port: number): Promise<void>;
31
+ stop(): Promise<void>;
32
+ getApp(): express.Application;
33
+ /**
34
+ * Find agent config by bot token.
35
+ */
36
+ getAgentByToken(token: string): AgentConfig | undefined;
37
+ /**
38
+ * List all agent configs.
39
+ */
40
+ listAgents(): AgentConfig[];
41
+ /**
42
+ * Hot-reload API keys by mutating the existing array in-place.
43
+ * The auth middleware captures apiKeys by reference, so mutations
44
+ * are picked up automatically without remounting the router.
45
+ */
46
+ updateApiKeys(newKeys: ApiKey[]): void;
47
+ /**
48
+ * Return per-agent stats.
49
+ */
50
+ getAgentStats(): AgentStats[];
51
+ }
52
+ //# sourceMappingURL=gateway-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-router.d.ts","sourceRoot":"","sources":["../../src/api/gateway-router.ts"],"names":[],"mappings":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAmB,MAAM,UAAU,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAO9C,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;IAC1C,OAAO,CAAC,MAAM,CAAuB;IAErC,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAE/D,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAE/D,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+F;IAE9H,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IAEpE,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IAExC,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAgB;IAE/C,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAE3C,oDAAoD;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAGnC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAChC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACjC,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EACvC,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,CAAC,EAAE,MAAM;IAiCrB,OAAO,CAAC,WAAW;IAgHb,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,MAAM,IAAI,OAAO,CAAC,WAAW;IAM7B;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IASvD;;OAEG;IACH,UAAU,IAAI,WAAW,EAAE;IAI3B;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAMtC;;OAEG;IACH,aAAa,IAAI,UAAU,EAAE;CAe9B"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GatewayRouter = void 0;
7
+ const express_1 = __importDefault(require("express"));
8
+ const web_ui_1 = require("../ui/web-ui");
9
+ const router_1 = require("./router");
10
+ const cron_router_1 = require("./cron-router");
11
+ const workspace_router_1 = require("./workspace-router");
12
+ const skills_router_1 = require("./skills-router");
13
+ class GatewayRouter {
14
+ constructor(agents, configs, schedulers, gatewayConfig, cronManager, configPath) {
15
+ this.server = null;
16
+ /** Per-agent message counters (output lines from subprocess) */
17
+ this.messagesReceived = new Map();
18
+ this.messagesSent = new Map();
19
+ /** Per-agent last activity timestamps */
20
+ this.lastActivityAt = new Map();
21
+ /** Per-agent recent sessions (last 5): Map<agentId, Array<sessionInfo>> */
22
+ this.recentSessions = new Map();
23
+ /** Optional per-agent cron schedulers (for /status endpoint) */
24
+ this.schedulers = new Map();
25
+ /** Gateway start time */
26
+ this.startedAt = new Date();
27
+ this.agents = agents;
28
+ this.configs = configs;
29
+ this.gatewayConfig = gatewayConfig;
30
+ this.cronManager = cronManager;
31
+ this.configPath = configPath;
32
+ this.app = (0, express_1.default)();
33
+ // Initialise counters for all known agents
34
+ for (const [id, runner] of agents) {
35
+ this.messagesReceived.set(id, 0);
36
+ this.messagesSent.set(id, 0);
37
+ this.recentSessions.set(id, []);
38
+ // Track output lines from subprocess as messagesSent (guard for test mocks)
39
+ if (typeof runner.on === 'function') {
40
+ runner.on('output', () => {
41
+ this.messagesSent.set(id, (this.messagesSent.get(id) ?? 0) + 1);
42
+ this.lastActivityAt.set(id, new Date());
43
+ });
44
+ }
45
+ }
46
+ if (schedulers) {
47
+ for (const [id, scheduler] of schedulers) {
48
+ this.schedulers.set(id, scheduler);
49
+ }
50
+ }
51
+ this.setupRoutes();
52
+ }
53
+ setupRoutes() {
54
+ this.app.use(express_1.default.json());
55
+ // Mount API router after body parser so req.body is populated
56
+ if (this.gatewayConfig?.gateway?.api?.keys?.length) {
57
+ const apiRouter = (0, router_1.createApiRouter)(this.agents, this.configs, this.gatewayConfig.gateway.api.keys, this.configPath, this.gatewayConfig.gateway.models);
58
+ this.app.use('/api', apiRouter);
59
+ }
60
+ // Mount workspace file routes
61
+ if (this.gatewayConfig?.gateway?.api?.keys?.length) {
62
+ const workspaceRouter = (0, workspace_router_1.createWorkspaceRouter)(this.configs, this.gatewayConfig.gateway.api.keys);
63
+ this.app.use('/api', workspaceRouter);
64
+ }
65
+ // Mount skills routes
66
+ if (this.gatewayConfig?.gateway?.api?.keys?.length) {
67
+ const skillsRouter = (0, skills_router_1.createSkillsRouter)(this.configs, this.gatewayConfig.gateway.api.keys, this.agents);
68
+ this.app.use('/api', skillsRouter);
69
+ }
70
+ // Mount cron manager routes with same API key auth as agent router
71
+ if (this.cronManager) {
72
+ const cronRouter = (0, cron_router_1.createCronRouter)(this.cronManager, this.gatewayConfig?.gateway?.api?.keys, new Set(this.configs.keys()));
73
+ this.app.use('/api', cronRouter);
74
+ }
75
+ // Health check
76
+ this.app.get('/health', (_req, res) => {
77
+ res.json({ status: 'ok', agents: [...this.agents.keys()] });
78
+ });
79
+ // Web UI dashboard
80
+ this.app.get('/ui', (_req, res) => {
81
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
82
+ res.send((0, web_ui_1.generateDashboardHtml)());
83
+ });
84
+ // Status endpoint — per-agent stats + heartbeat history
85
+ this.app.get('/status', (_req, res) => {
86
+ const uptimeMs = Date.now() - this.startedAt.getTime();
87
+ const agentsStatus = [...this.agents.entries()].map(([id, runner]) => {
88
+ const scheduler = this.schedulers.get(id);
89
+ const history = scheduler?.getHistory();
90
+ const agentConfig = this.configs.get(id);
91
+ const taskDefs = agentConfig?.heartbeat ?? undefined;
92
+ void taskDefs; // not used directly; task names come from history
93
+ // Collect unique task names from history
94
+ const allResults = history ? history.getHistory(id) : [];
95
+ const taskNames = [...new Set(allResults.map((r) => r.taskName))];
96
+ // Get the most recent result for each known task
97
+ const lastResults = taskNames.map((taskName) => {
98
+ const last = history?.getLastResult(id, taskName);
99
+ if (!last)
100
+ return null;
101
+ return {
102
+ taskName: last.taskName,
103
+ suppressed: last.suppressed,
104
+ rateLimited: last.rateLimited,
105
+ durationMs: last.durationMs,
106
+ ts: last.ts,
107
+ };
108
+ }).filter(Boolean);
109
+ const lastActivity = this.lastActivityAt.get(id);
110
+ const sessions = (this.recentSessions.get(id) ?? []).slice(0, 5).map((s) => ({
111
+ chatId: s.chatId,
112
+ messageCount: s.messageCount,
113
+ lastActivity: s.lastActivity.toISOString(),
114
+ }));
115
+ return {
116
+ id,
117
+ isRunning: runner.isRunning(),
118
+ messagesReceived: this.messagesReceived.get(id) ?? 0,
119
+ messagesSent: this.messagesSent.get(id) ?? 0,
120
+ lastActivityAt: lastActivity ? lastActivity.toISOString() : null,
121
+ heartbeat: {
122
+ tasks: taskNames,
123
+ lastResults,
124
+ },
125
+ sessions,
126
+ };
127
+ });
128
+ res.json({
129
+ agents: agentsStatus,
130
+ uptime: Math.floor(uptimeMs / 1000),
131
+ startedAt: this.startedAt.toISOString(),
132
+ });
133
+ });
134
+ }
135
+ async start(port) {
136
+ return new Promise((resolve, reject) => {
137
+ this.server = this.app.listen(port, () => {
138
+ resolve();
139
+ });
140
+ this.server.on('error', (err) => {
141
+ if (err.code === 'EADDRINUSE') {
142
+ reject(new Error(`Port ${port} is already in use. Stop the existing process or set a different PORT env var.`));
143
+ }
144
+ else {
145
+ reject(err);
146
+ }
147
+ });
148
+ });
149
+ }
150
+ async stop() {
151
+ return new Promise((resolve, reject) => {
152
+ if (!this.server) {
153
+ resolve();
154
+ return;
155
+ }
156
+ this.server.close((err) => {
157
+ if (err)
158
+ reject(err);
159
+ else
160
+ resolve();
161
+ });
162
+ });
163
+ }
164
+ getApp() {
165
+ return this.app;
166
+ }
167
+ // ─── Lookup / stats API ─────────────────────────────────────────────────
168
+ /**
169
+ * Find agent config by bot token.
170
+ */
171
+ getAgentByToken(token) {
172
+ for (const [, config] of this.configs) {
173
+ if (config.telegram?.botToken === token) {
174
+ return config;
175
+ }
176
+ }
177
+ return undefined;
178
+ }
179
+ /**
180
+ * List all agent configs.
181
+ */
182
+ listAgents() {
183
+ return [...this.configs.values()];
184
+ }
185
+ /**
186
+ * Hot-reload API keys by mutating the existing array in-place.
187
+ * The auth middleware captures apiKeys by reference, so mutations
188
+ * are picked up automatically without remounting the router.
189
+ */
190
+ updateApiKeys(newKeys) {
191
+ if (!this.gatewayConfig?.gateway?.api?.keys)
192
+ return;
193
+ const keys = this.gatewayConfig.gateway.api.keys;
194
+ keys.splice(0, keys.length, ...newKeys);
195
+ }
196
+ /**
197
+ * Return per-agent stats.
198
+ */
199
+ getAgentStats() {
200
+ const stats = [];
201
+ for (const [id, runner] of this.agents) {
202
+ const lastActivity = this.lastActivityAt.get(id);
203
+ stats.push({
204
+ id,
205
+ isRunning: runner.isRunning(),
206
+ messagesReceived: this.messagesReceived.get(id) ?? 0,
207
+ messagesSent: this.messagesSent.get(id) ?? 0,
208
+ lastActivityAt: lastActivity ? lastActivity.toISOString() : null,
209
+ });
210
+ }
211
+ return stats;
212
+ }
213
+ }
214
+ exports.GatewayRouter = GatewayRouter;
215
+ //# sourceMappingURL=gateway-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-router.js","sourceRoot":"","sources":["../../src/api/gateway-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Router } from 'express';
2
+ import { AgentRunner } from '../agent/runner';
3
+ import { AgentConfig, ApiKey, ModelConfig } from '../types';
4
+ export declare function createApiRouter(agentRunners: Map<string, AgentRunner>, agentConfigs: Map<string, AgentConfig>, apiKeys: ApiKey[], configPath?: string, models?: ModelConfig[]): Router;
5
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/api/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAMpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA+C5D,wBAAgB,eAAe,CAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACtC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACtC,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,WAAW,EAAE,GACrB,MAAM,CA0gCR"}