@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,149 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createWorkspaceRouter = createWorkspaceRouter;
37
+ const express_1 = require("express");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const crypto_1 = require("crypto");
41
+ const auth_1 = require("./auth");
42
+ const MAX_FILE_SIZE = 1 * 1024 * 1024; // 1MB
43
+ const ALLOWED_FILES = new Set([
44
+ 'SOUL.md',
45
+ 'USER.md',
46
+ 'MEMORY.md',
47
+ 'AGENTS.md',
48
+ 'HEARTBEAT.md',
49
+ 'IDENTITY.md',
50
+ ]);
51
+ const FILENAME_RE = /^[A-Z][A-Z0-9_-]*\.md$/i;
52
+ function validateFilename(filename) {
53
+ if (!FILENAME_RE.test(filename))
54
+ return 'Invalid filename format';
55
+ if (filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
56
+ return 'Path traversal not allowed';
57
+ }
58
+ if (!ALLOWED_FILES.has(filename)) {
59
+ return `Filename not allowed. Allowed files: ${[...ALLOWED_FILES].join(', ')}`;
60
+ }
61
+ return null;
62
+ }
63
+ function createWorkspaceRouter(agentConfigs, apiKeys) {
64
+ const router = (0, express_1.Router)();
65
+ const auth = (0, auth_1.createApiAuthMiddleware)(apiKeys);
66
+ /**
67
+ * GET /api/v1/agents/:agentId/files/:filename
68
+ *
69
+ * Read a workspace file for an agent.
70
+ * Returns 200 with empty content if the file does not exist yet.
71
+ */
72
+ router.get('/v1/agents/:agentId/files/:filename', auth, (req, res) => {
73
+ const { agentId, filename } = req.params;
74
+ const apiKey = req.apiKey;
75
+ if (!(0, auth_1.canAccessAgent)(apiKey, agentId)) {
76
+ res.status(403).json({ error: `API key has no access to agent '${agentId}'` });
77
+ return;
78
+ }
79
+ const config = agentConfigs.get(agentId);
80
+ if (!config) {
81
+ res.status(404).json({ error: `Agent '${agentId}' not found` });
82
+ return;
83
+ }
84
+ const err = validateFilename(filename);
85
+ if (err) {
86
+ res.status(400).json({ error: err });
87
+ return;
88
+ }
89
+ const filePath = path.join(config.workspace, filename);
90
+ let content = '';
91
+ try {
92
+ content = fs.readFileSync(filePath, 'utf-8');
93
+ }
94
+ catch {
95
+ // File doesn't exist yet — return empty content (not an error)
96
+ }
97
+ res.json({ filename, content });
98
+ });
99
+ /**
100
+ * PUT /api/v1/agents/:agentId/files/:filename
101
+ *
102
+ * Write a workspace file for an agent. Requires write access.
103
+ * Gateway's file watcher will auto-reload CLAUDE.md after write.
104
+ */
105
+ router.put('/v1/agents/:agentId/files/:filename', auth, (req, res) => {
106
+ const { agentId, filename } = req.params;
107
+ const apiKey = req.apiKey;
108
+ if (!(0, auth_1.canWriteAgent)(apiKey, agentId)) {
109
+ res.status(403).json({ error: 'Write permission required' });
110
+ return;
111
+ }
112
+ const config = agentConfigs.get(agentId);
113
+ if (!config) {
114
+ res.status(404).json({ error: `Agent '${agentId}' not found` });
115
+ return;
116
+ }
117
+ const err = validateFilename(filename);
118
+ if (err) {
119
+ res.status(400).json({ error: err });
120
+ return;
121
+ }
122
+ const body = req.body;
123
+ if (typeof body.content !== 'string') {
124
+ res.status(400).json({ error: 'content must be a string' });
125
+ return;
126
+ }
127
+ if (body.content.length > MAX_FILE_SIZE) {
128
+ res.status(400).json({ error: 'Content exceeds 1MB limit' });
129
+ return;
130
+ }
131
+ const filePath = path.join(config.workspace, filename);
132
+ const tmpPath = filePath + '.tmp.' + (0, crypto_1.randomUUID)();
133
+ try {
134
+ fs.writeFileSync(tmpPath, body.content, 'utf-8');
135
+ fs.renameSync(tmpPath, filePath);
136
+ }
137
+ catch (writeErr) {
138
+ try {
139
+ fs.unlinkSync(tmpPath);
140
+ }
141
+ catch { /* ignore cleanup error */ }
142
+ res.status(500).json({ error: `Failed to write file: ${writeErr.message}` });
143
+ return;
144
+ }
145
+ res.json({ filename, message: 'File saved. CLAUDE.md will auto-reload.' });
146
+ });
147
+ return router;
148
+ }
149
+ //# sourceMappingURL=workspace-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-router.js","sourceRoot":"","sources":["../../src/api/workspace-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { GatewayConfig } from '../types';
2
+ export declare class ConfigValidationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare class DuplicateAgentIdError extends Error {
6
+ constructor(id: string);
7
+ }
8
+ export declare class MissingEnvVarError extends Error {
9
+ constructor(varName: string);
10
+ }
11
+ /**
12
+ * Load and validate config.json from the given path.
13
+ * Interpolates ${VAR} env vars throughout the config.
14
+ */
15
+ export declare function loadConfig(configPath: string): GatewayConfig;
16
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAe,MAAM,UAAU,CAAC;AAEtD,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAuED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAuH5D"}
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MissingEnvVarError = exports.DuplicateAgentIdError = exports.ConfigValidationError = void 0;
37
+ exports.loadConfig = loadConfig;
38
+ const fs = __importStar(require("fs"));
39
+ class ConfigValidationError extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = 'ConfigValidationError';
43
+ }
44
+ }
45
+ exports.ConfigValidationError = ConfigValidationError;
46
+ class DuplicateAgentIdError extends Error {
47
+ constructor(id) {
48
+ super(`Duplicate agent id: "${id}"`);
49
+ this.name = 'DuplicateAgentIdError';
50
+ }
51
+ }
52
+ exports.DuplicateAgentIdError = DuplicateAgentIdError;
53
+ class MissingEnvVarError extends Error {
54
+ constructor(varName) {
55
+ super(`Missing environment variable: ${varName}`);
56
+ this.name = 'MissingEnvVarError';
57
+ }
58
+ }
59
+ exports.MissingEnvVarError = MissingEnvVarError;
60
+ /**
61
+ * Interpolate ${VAR} placeholders in a string value using process.env.
62
+ * Throws MissingEnvVarError if any referenced variable is not set.
63
+ */
64
+ function interpolateEnvVars(value) {
65
+ return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
66
+ const envValue = process.env[varName];
67
+ if (envValue === undefined) {
68
+ throw new MissingEnvVarError(varName);
69
+ }
70
+ return envValue;
71
+ });
72
+ }
73
+ /**
74
+ * Recursively walk an object and interpolate all string values.
75
+ */
76
+ function interpolateObject(obj) {
77
+ if (typeof obj === 'string') {
78
+ return interpolateEnvVars(obj);
79
+ }
80
+ if (Array.isArray(obj)) {
81
+ return obj.map(interpolateObject);
82
+ }
83
+ if (obj !== null && typeof obj === 'object') {
84
+ const result = {};
85
+ for (const [key, val] of Object.entries(obj)) {
86
+ result[key] = interpolateObject(val);
87
+ }
88
+ return result;
89
+ }
90
+ return obj;
91
+ }
92
+ /**
93
+ * Validate an agent config. Returns an error message if invalid, or null if valid.
94
+ */
95
+ function validateAgent(agent, index) {
96
+ if (!agent.id || typeof agent.id !== 'string') {
97
+ return `Agent at index ${index} is missing required field "id"`;
98
+ }
99
+ const hasTelegram = agent.telegram && typeof agent.telegram === 'object';
100
+ const hasDiscord = agent.discord && typeof agent.discord === 'object';
101
+ // Agents without channels are allowed (API-only agents accessed via HTTP API key)
102
+ if (hasTelegram) {
103
+ const telegram = agent.telegram;
104
+ if (!telegram.botToken || typeof telegram.botToken !== 'string') {
105
+ return `Agent "${agent.id}" is missing "telegram.botToken"`;
106
+ }
107
+ }
108
+ if (hasDiscord) {
109
+ const discord = agent.discord;
110
+ if (!discord.botToken || typeof discord.botToken !== 'string') {
111
+ return `Agent "${agent.id}" is missing "discord.botToken"`;
112
+ }
113
+ }
114
+ if (agent.session !== undefined && typeof agent.session === 'object') {
115
+ const session = agent.session;
116
+ if (session.idleTimeoutMinutes !== undefined && (typeof session.idleTimeoutMinutes !== 'number' || session.idleTimeoutMinutes <= 0)) {
117
+ return `agent '${agent.id}': session.idleTimeoutMinutes must be > 0`;
118
+ }
119
+ if (session.maxConcurrent !== undefined && (typeof session.maxConcurrent !== 'number' || session.maxConcurrent <= 0)) {
120
+ return `agent '${agent.id}': session.maxConcurrent must be > 0`;
121
+ }
122
+ }
123
+ return null;
124
+ }
125
+ /**
126
+ * Load and validate config.json from the given path.
127
+ * Interpolates ${VAR} env vars throughout the config.
128
+ */
129
+ function loadConfig(configPath) {
130
+ let raw;
131
+ try {
132
+ raw = fs.readFileSync(configPath, 'utf-8');
133
+ }
134
+ catch (err) {
135
+ throw new ConfigValidationError(`Cannot read config file at "${configPath}": ${err.message}`);
136
+ }
137
+ let parsed;
138
+ try {
139
+ parsed = JSON.parse(raw);
140
+ }
141
+ catch (err) {
142
+ throw new ConfigValidationError(`Config file is not valid JSON: ${err.message}`);
143
+ }
144
+ if (typeof parsed !== 'object' || parsed === null) {
145
+ throw new ConfigValidationError('Config must be a JSON object');
146
+ }
147
+ const config = parsed;
148
+ if (!Array.isArray(config.agents)) {
149
+ throw new ConfigValidationError('Config is missing required "agents" array');
150
+ }
151
+ if (!config.gateway || typeof config.gateway !== 'object') {
152
+ throw new ConfigValidationError('Config is missing required "gateway" object');
153
+ }
154
+ // Validate each agent before interpolation — skip invalid agents with a warning
155
+ const validAgents = [];
156
+ const skippedAgents = [];
157
+ for (let i = 0; i < config.agents.length; i++) {
158
+ const agent = config.agents[i];
159
+ if (typeof agent !== 'object' || agent === null) {
160
+ console.warn(`[gateway] Skipping agent at index ${i}: must be an object`);
161
+ skippedAgents.push(`index ${i}`);
162
+ continue;
163
+ }
164
+ const error = validateAgent(agent, i);
165
+ if (error) {
166
+ const agentId = agent.id || `index ${i}`;
167
+ console.warn(`[gateway] Skipping agent "${agentId}": ${error}`);
168
+ skippedAgents.push(String(agentId));
169
+ continue;
170
+ }
171
+ validAgents.push(agent);
172
+ }
173
+ // Check for duplicate IDs among valid agents
174
+ const ids = new Set();
175
+ for (const agent of validAgents) {
176
+ const id = agent.id;
177
+ if (ids.has(id)) {
178
+ throw new DuplicateAgentIdError(id);
179
+ }
180
+ ids.add(id);
181
+ }
182
+ // Validate gateway.api.keys if present
183
+ const gateway = config.gateway;
184
+ if (gateway.api !== undefined) {
185
+ const api = gateway.api;
186
+ if (!Array.isArray(api.keys)) {
187
+ throw new ConfigValidationError('gateway.api.keys must be an array');
188
+ }
189
+ const seenKeys = new Set();
190
+ for (const k of api.keys) {
191
+ if (typeof k !== 'object' || k === null) {
192
+ throw new ConfigValidationError('Each entry in gateway.api.keys must be an object');
193
+ }
194
+ const entry = k;
195
+ if (!entry.key || typeof entry.key !== 'string') {
196
+ throw new ConfigValidationError('Each API key must have a non-empty "key" string');
197
+ }
198
+ if (seenKeys.has(entry.key)) {
199
+ throw new ConfigValidationError(`Duplicate API key value detected`);
200
+ }
201
+ seenKeys.add(entry.key);
202
+ if (entry.agents !== '*' && !Array.isArray(entry.agents)) {
203
+ throw new ConfigValidationError(`API key "${entry.key}": "agents" must be an array of agent IDs or the string "*"`);
204
+ }
205
+ }
206
+ }
207
+ // Interpolate gateway config (fatal if env vars missing here)
208
+ const interpolatedGateway = interpolateObject(config.gateway);
209
+ // Interpolate each agent individually — skip agents with missing env vars
210
+ const interpolatedAgents = [];
211
+ for (const agent of validAgents) {
212
+ try {
213
+ interpolatedAgents.push(interpolateObject(agent));
214
+ }
215
+ catch (err) {
216
+ if (err instanceof MissingEnvVarError) {
217
+ console.warn(`[gateway] Skipping agent "${agent.id}": ${err.message}`);
218
+ skippedAgents.push(String(agent.id));
219
+ continue;
220
+ }
221
+ throw err;
222
+ }
223
+ }
224
+ if (interpolatedAgents.length === 0) {
225
+ throw new ConfigValidationError('No valid agents found in config. All agents were skipped due to configuration errors.');
226
+ }
227
+ if (skippedAgents.length > 0) {
228
+ console.warn(`[gateway] ${skippedAgents.length} agent(s) skipped: ${skippedAgents.join(', ')}`);
229
+ }
230
+ return {
231
+ agents: interpolatedAgents,
232
+ gateway: interpolatedGateway,
233
+ };
234
+ }
235
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ export interface MigrationResult {
2
+ migrated: boolean;
3
+ addedFields: string[];
4
+ removedFields: string[];
5
+ }
6
+ export interface DetectMigrationResult {
7
+ needed: boolean;
8
+ fromVersion: string;
9
+ toVersion: string;
10
+ addedFields: string[];
11
+ removedFields: string[];
12
+ config: Record<string, unknown>;
13
+ template: Record<string, unknown>;
14
+ }
15
+ export interface CleanTemplateResult {
16
+ template: Record<string, unknown>;
17
+ ignorePaths: Set<string>;
18
+ removePaths: string[];
19
+ }
20
+ /**
21
+ * Deep-merge template into target, adding missing keys only.
22
+ * Never overwrites existing values. Returns list of added field paths.
23
+ * Keys whose full path is in ignorePaths are skipped entirely.
24
+ */
25
+ declare function deepMerge(target: Record<string, unknown>, template: Record<string, unknown>, prefix: string, added: string[], ignorePaths?: Set<string>): void;
26
+ /**
27
+ * Remove dot-path keys from each agent entry. Returns paths actually removed.
28
+ * Paths are relative to each agent object (e.g. "telegram.allowedUsers").
29
+ */
30
+ declare function pruneAgentPaths(agents: Array<Record<string, unknown>>, removePaths: string[]): string[];
31
+ /**
32
+ * Compare two semver strings. Returns:
33
+ * -1 if a < b, 0 if equal, 1 if a > b
34
+ */
35
+ declare function compareSemver(a: string, b: string): number;
36
+ /**
37
+ * Load a template file, extract the _migration metadata, strip it,
38
+ * and return the clean template along with the ignorePaths set.
39
+ */
40
+ export declare function loadCleanTemplate(templatePath: string): CleanTemplateResult;
41
+ /**
42
+ * Recursively delete keys from obj whose full dotted path matches any entry
43
+ * in ignorePaths. The prefix parameter tracks the current path during recursion.
44
+ */
45
+ export declare function stripIgnoredPaths(obj: Record<string, unknown>, ignorePaths: Set<string>, prefix?: string): void;
46
+ /**
47
+ * Detect whether a config migration is needed (dry-run, no writes).
48
+ * Returns migration metadata including the fields that would be added.
49
+ */
50
+ export declare function detectMigration(configPath: string, templatePath: string, templateVersion: string): DetectMigrationResult;
51
+ /**
52
+ * Apply a config migration: deep-merge missing fields, update version,
53
+ * create backup, and write the updated config.
54
+ */
55
+ export declare function applyMigration(configPath: string, config: Record<string, unknown>, template: Record<string, unknown>, templateVersion: string, ignorePaths?: Set<string>, removePaths?: string[]): MigrationResult;
56
+ /**
57
+ * Migrate config.json by adding missing fields from the template.
58
+ * - Never overwrites existing values
59
+ * - Creates a .bak backup before writing
60
+ * - Skips migration if config file does not exist (first run)
61
+ */
62
+ export declare function migrateConfig(configPath: string, templatePath: string, templateVersion: string): MigrationResult;
63
+ /**
64
+ * Merge models from template into user config by ID.
65
+ * Adds new models, updates alias/label/contextWindow of existing ones.
66
+ * Preserves user models not in template.
67
+ */
68
+ declare function migrateModels(config: Record<string, unknown>, template: Record<string, unknown>, added: string[]): void;
69
+ export { compareSemver, deepMerge, migrateModels, pruneAgentPaths };
70
+ //# sourceMappingURL=migrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../../src/config/migrator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;GAIG;AACH,iBAAS,SAAS,CAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,IAAI,CA6BN;AAmBD;;;GAGG;AACH,iBAAS,eAAe,CACtB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACtC,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,EAAE,CAwBV;AAED;;;GAGG;AACH,iBAAS,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,CAmC3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,MAAM,SAAK,GACV,IAAI,CAcN;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,qBAAqB,CAwFvB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,eAAe,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,eAAe,CA6CjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,eAAe,CA0BjB;AAED;;;;GAIG;AACH,iBAAS,aAAa,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,EAAE,MAAM,EAAE,GACd,IAAI,CAgCN;AAGD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC"}