@redplanethq/corebrain 2.8.13 → 2.8.15

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/dist/commands/coding/list.js +1 -1
  2. package/dist/commands/coding/list.js.map +1 -1
  3. package/dist/commands/coding/setup.d.ts +2 -1
  4. package/dist/commands/coding/setup.d.ts.map +1 -1
  5. package/dist/commands/coding/setup.js +1 -24
  6. package/dist/commands/coding/setup.js.map +1 -1
  7. package/dist/commands/folder/add.d.ts +13 -0
  8. package/dist/commands/folder/add.d.ts.map +1 -0
  9. package/dist/commands/folder/add.js +71 -0
  10. package/dist/commands/folder/add.js.map +1 -0
  11. package/dist/commands/folder/index.d.ts +3 -0
  12. package/dist/commands/folder/index.d.ts.map +1 -0
  13. package/dist/commands/folder/index.js +5 -0
  14. package/dist/commands/folder/index.js.map +1 -0
  15. package/dist/commands/folder/list.d.ts +8 -0
  16. package/dist/commands/folder/list.d.ts.map +1 -0
  17. package/dist/commands/folder/list.js +39 -0
  18. package/dist/commands/folder/list.js.map +1 -0
  19. package/dist/commands/folder/remove.d.ts +10 -0
  20. package/dist/commands/folder/remove.d.ts.map +1 -0
  21. package/dist/commands/folder/remove.js +29 -0
  22. package/dist/commands/folder/remove.js.map +1 -0
  23. package/dist/commands/folder/scope.d.ts +13 -0
  24. package/dist/commands/folder/scope.d.ts.map +1 -0
  25. package/dist/commands/folder/scope.js +61 -0
  26. package/dist/commands/folder/scope.js.map +1 -0
  27. package/dist/commands/gateway/config.d.ts +1 -1
  28. package/dist/commands/gateway/config.d.ts.map +1 -1
  29. package/dist/commands/gateway/config.js +122 -116
  30. package/dist/commands/gateway/config.js.map +1 -1
  31. package/dist/commands/gateway/register.d.ts +37 -0
  32. package/dist/commands/gateway/register.d.ts.map +1 -0
  33. package/dist/commands/gateway/register.js +132 -0
  34. package/dist/commands/gateway/register.js.map +1 -0
  35. package/dist/commands/gateway/start.d.ts +2 -1
  36. package/dist/commands/gateway/start.d.ts.map +1 -1
  37. package/dist/commands/gateway/start.js +73 -6
  38. package/dist/commands/gateway/start.js.map +1 -1
  39. package/dist/commands/gateway/status.d.ts.map +1 -1
  40. package/dist/commands/gateway/status.js +10 -1
  41. package/dist/commands/gateway/status.js.map +1 -1
  42. package/dist/commands/gateway/stop.d.ts.map +1 -1
  43. package/dist/commands/gateway/stop.js +11 -0
  44. package/dist/commands/gateway/stop.js.map +1 -1
  45. package/dist/config/folders.d.ts +20 -0
  46. package/dist/config/folders.d.ts.map +1 -0
  47. package/dist/config/folders.js +114 -0
  48. package/dist/config/folders.js.map +1 -0
  49. package/dist/server/api/auth.d.ts +17 -0
  50. package/dist/server/api/auth.d.ts.map +1 -0
  51. package/dist/server/api/auth.js +45 -0
  52. package/dist/server/api/auth.js.map +1 -0
  53. package/dist/server/api/browser/cdp.d.ts +18 -0
  54. package/dist/server/api/browser/cdp.d.ts.map +1 -0
  55. package/dist/server/api/browser/cdp.js +137 -0
  56. package/dist/server/api/browser/cdp.js.map +1 -0
  57. package/dist/server/api/browser/index.d.ts +3 -0
  58. package/dist/server/api/browser/index.d.ts.map +1 -0
  59. package/dist/server/api/browser/index.js +10 -0
  60. package/dist/server/api/browser/index.js.map +1 -0
  61. package/dist/server/api/browser/launch.d.ts +17 -0
  62. package/dist/server/api/browser/launch.d.ts.map +1 -0
  63. package/dist/server/api/browser/launch.js +41 -0
  64. package/dist/server/api/browser/launch.js.map +1 -0
  65. package/dist/server/api/coding/coding_spawn.d.ts +22 -0
  66. package/dist/server/api/coding/coding_spawn.d.ts.map +1 -0
  67. package/dist/server/api/coding/coding_spawn.js +121 -0
  68. package/dist/server/api/coding/coding_spawn.js.map +1 -0
  69. package/dist/server/api/coding/coding_xterm_session.d.ts +3 -0
  70. package/dist/server/api/coding/coding_xterm_session.d.ts.map +1 -0
  71. package/dist/server/api/coding/coding_xterm_session.js +163 -0
  72. package/dist/server/api/coding/coding_xterm_session.js.map +1 -0
  73. package/dist/server/api/coding/index.d.ts +10 -0
  74. package/dist/server/api/coding/index.d.ts.map +1 -0
  75. package/dist/server/api/coding/index.js +17 -0
  76. package/dist/server/api/coding/index.js.map +1 -0
  77. package/dist/server/api/exec/index.d.ts +3 -0
  78. package/dist/server/api/exec/index.d.ts.map +1 -0
  79. package/dist/server/api/exec/index.js +6 -0
  80. package/dist/server/api/exec/index.js.map +1 -0
  81. package/dist/server/api/files/index.d.ts +3 -0
  82. package/dist/server/api/files/index.d.ts.map +1 -0
  83. package/dist/server/api/files/index.js +6 -0
  84. package/dist/server/api/files/index.js.map +1 -0
  85. package/dist/server/api/folders/index.d.ts +14 -0
  86. package/dist/server/api/folders/index.d.ts.map +1 -0
  87. package/dist/server/api/folders/index.js +161 -0
  88. package/dist/server/api/folders/index.js.map +1 -0
  89. package/dist/server/api/manifest-builder.d.ts +13 -0
  90. package/dist/server/api/manifest-builder.d.ts.map +1 -0
  91. package/dist/server/api/manifest-builder.js +158 -0
  92. package/dist/server/api/manifest-builder.js.map +1 -0
  93. package/dist/server/api/ops.d.ts +3 -0
  94. package/dist/server/api/ops.d.ts.map +1 -0
  95. package/dist/server/api/ops.js +32 -0
  96. package/dist/server/api/ops.js.map +1 -0
  97. package/dist/server/api/server.d.ts +9 -0
  98. package/dist/server/api/server.d.ts.map +1 -0
  99. package/dist/server/api/server.js +66 -0
  100. package/dist/server/api/server.js.map +1 -0
  101. package/dist/server/api/shell/index.d.ts +17 -0
  102. package/dist/server/api/shell/index.d.ts.map +1 -0
  103. package/dist/server/api/shell/index.js +61 -0
  104. package/dist/server/api/shell/index.js.map +1 -0
  105. package/dist/server/api/tool-group.d.ts +21 -0
  106. package/dist/server/api/tool-group.d.ts.map +1 -0
  107. package/dist/server/api/tool-group.js +23 -0
  108. package/dist/server/api/tool-group.js.map +1 -0
  109. package/dist/server/api/tunnels/ngrok.d.ts +10 -0
  110. package/dist/server/api/tunnels/ngrok.d.ts.map +1 -0
  111. package/dist/server/api/tunnels/ngrok.js +33 -0
  112. package/dist/server/api/tunnels/ngrok.js.map +1 -0
  113. package/dist/server/api/tunnels/tailscale.d.ts +12 -0
  114. package/dist/server/api/tunnels/tailscale.d.ts.map +1 -0
  115. package/dist/server/api/tunnels/tailscale.js +49 -0
  116. package/dist/server/api/tunnels/tailscale.js.map +1 -0
  117. package/dist/server/api/utils/index.d.ts +3 -0
  118. package/dist/server/api/utils/index.d.ts.map +1 -0
  119. package/dist/server/api/utils/index.js +6 -0
  120. package/dist/server/api/utils/index.js.map +1 -0
  121. package/dist/server/gateway-entry.d.ts +2 -2
  122. package/dist/server/gateway-entry.js +43 -106
  123. package/dist/server/gateway-entry.js.map +1 -1
  124. package/dist/server/gateway-log.d.ts +10 -0
  125. package/dist/server/gateway-log.d.ts.map +1 -0
  126. package/dist/server/gateway-log.js +33 -0
  127. package/dist/server/gateway-log.js.map +1 -0
  128. package/dist/server/pty/manager.d.ts +75 -0
  129. package/dist/server/pty/manager.d.ts.map +1 -0
  130. package/dist/server/pty/manager.js +280 -0
  131. package/dist/server/pty/manager.js.map +1 -0
  132. package/dist/server/tools/coding-tools.d.ts.map +1 -1
  133. package/dist/server/tools/coding-tools.js +56 -17
  134. package/dist/server/tools/coding-tools.js.map +1 -1
  135. package/dist/server/tools/exec-tools.d.ts.map +1 -1
  136. package/dist/server/tools/exec-tools.js +30 -3
  137. package/dist/server/tools/exec-tools.js.map +1 -1
  138. package/dist/server/tools/files-tools.d.ts +8 -0
  139. package/dist/server/tools/files-tools.d.ts.map +1 -0
  140. package/dist/server/tools/files-tools.js +523 -0
  141. package/dist/server/tools/files-tools.js.map +1 -0
  142. package/dist/server/tools/scope-error.d.ts +8 -0
  143. package/dist/server/tools/scope-error.d.ts.map +1 -0
  144. package/dist/server/tools/scope-error.js +11 -0
  145. package/dist/server/tools/scope-error.js.map +1 -0
  146. package/dist/types/config.d.ts +15 -3
  147. package/dist/types/config.d.ts.map +1 -1
  148. package/dist/utils/agent-templates.d.ts +18 -0
  149. package/dist/utils/agent-templates.d.ts.map +1 -0
  150. package/dist/utils/agent-templates.js +59 -0
  151. package/dist/utils/agent-templates.js.map +1 -0
  152. package/dist/utils/browser-manager.d.ts +20 -0
  153. package/dist/utils/browser-manager.d.ts.map +1 -1
  154. package/dist/utils/browser-manager.js +76 -0
  155. package/dist/utils/browser-manager.js.map +1 -1
  156. package/dist/utils/coding-agents/codex.d.ts +5 -8
  157. package/dist/utils/coding-agents/codex.d.ts.map +1 -1
  158. package/dist/utils/coding-agents/codex.js +6 -26
  159. package/dist/utils/coding-agents/codex.js.map +1 -1
  160. package/dist/utils/coding-runner.d.ts +13 -9
  161. package/dist/utils/coding-runner.d.ts.map +1 -1
  162. package/dist/utils/coding-runner.js +45 -78
  163. package/dist/utils/coding-runner.js.map +1 -1
  164. package/dist/utils/env-bootstrap.d.ts +29 -0
  165. package/dist/utils/env-bootstrap.d.ts.map +1 -0
  166. package/dist/utils/env-bootstrap.js +204 -0
  167. package/dist/utils/env-bootstrap.js.map +1 -0
  168. package/package.json +9 -2
  169. package/dist/commands/coding/close.d.ts +0 -11
  170. package/dist/commands/coding/close.d.ts.map +0 -1
  171. package/dist/commands/coding/close.js +0 -76
  172. package/dist/commands/coding/close.js.map +0 -1
  173. package/dist/commands/coding/resume.d.ts +0 -12
  174. package/dist/commands/coding/resume.d.ts.map +0 -1
  175. package/dist/commands/coding/resume.js +0 -86
  176. package/dist/commands/coding/resume.js.map +0 -1
  177. package/dist/commands/coding/start.d.ts +0 -17
  178. package/dist/commands/coding/start.d.ts.map +0 -1
  179. package/dist/commands/coding/start.js +0 -135
  180. package/dist/commands/coding/start.js.map +0 -1
  181. package/dist/server/gateway-client.d.ts +0 -84
  182. package/dist/server/gateway-client.d.ts.map +0 -1
  183. package/dist/server/gateway-client.js +0 -340
  184. package/dist/server/gateway-client.js.map +0 -1
  185. package/dist/server/tools/imessage-tools.d.ts +0 -34
  186. package/dist/server/tools/imessage-tools.d.ts.map +0 -1
  187. package/dist/server/tools/imessage-tools.js +0 -262
  188. package/dist/server/tools/imessage-tools.js.map +0 -1
  189. package/dist/utils/app-bundle.d.ts +0 -25
  190. package/dist/utils/app-bundle.d.ts.map +0 -1
  191. package/dist/utils/app-bundle.js +0 -117
  192. package/dist/utils/app-bundle.js.map +0 -1
@@ -0,0 +1,3 @@
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ export declare const filesRoutes: FastifyPluginAsync;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/files/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAIhD,eAAO,MAAM,WAAW,EAAE,kBAEzB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { filesTools, executeFilesTool } from '../../../server/tools/files-tools.js';
2
+ import { makeToolGroupRoutes } from '../tool-group.js';
3
+ export const filesRoutes = async (app) => {
4
+ await app.register(makeToolGroupRoutes(filesTools, executeFilesTool));
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/files/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAE,gBAAgB,EAAC,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAC,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5D,MAAM,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ /**
3
+ * Folder management routes (mounted at `/api/folders`).
4
+ *
5
+ * GET /api/folders → manifest mirror, used by webapp settings
6
+ * POST /api/folders/local → register an existing on-disk path
7
+ * POST /api/folders/git → git clone <url> into the workspace, register
8
+ * DELETE /api/folders/:idOrName → unregister (does not delete files)
9
+ *
10
+ * Auth is handled upstream (`makeAuthHook`); these handlers assume the caller
11
+ * already passed the gateway's security key.
12
+ */
13
+ export declare const folderRoutes: FastifyPluginAsync;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/folders/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAUhD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,kBAyK1B,CAAC"}
@@ -0,0 +1,161 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { existsSync, mkdirSync, statSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { addFolder, listFolders, removeFolder } from '../../../config/folders.js';
6
+ import { gatewayLog } from '../../../server/gateway-log.js';
7
+ const execFileP = promisify(execFile);
8
+ /**
9
+ * Folder management routes (mounted at `/api/folders`).
10
+ *
11
+ * GET /api/folders → manifest mirror, used by webapp settings
12
+ * POST /api/folders/local → register an existing on-disk path
13
+ * POST /api/folders/git → git clone <url> into the workspace, register
14
+ * DELETE /api/folders/:idOrName → unregister (does not delete files)
15
+ *
16
+ * Auth is handled upstream (`makeAuthHook`); these handlers assume the caller
17
+ * already passed the gateway's security key.
18
+ */
19
+ export const folderRoutes = async (app) => {
20
+ // ---- list ----
21
+ app.get('/', async () => ({
22
+ ok: true,
23
+ folders: listFolders(),
24
+ }));
25
+ // ---- register existing local path ----
26
+ app.post('/local', async (req, reply) => {
27
+ const body = (req.body ?? {});
28
+ if (!body.path) {
29
+ reply.code(400);
30
+ return { ok: false, error: '`path` is required' };
31
+ }
32
+ const scopes = body.scopes && body.scopes.length > 0
33
+ ? body.scopes
34
+ : ['files', 'coding', 'exec'];
35
+ try {
36
+ const folder = addFolder({
37
+ name: body.name,
38
+ path: body.path,
39
+ scopes: scopes,
40
+ });
41
+ gatewayLog(`folder added (local): ${folder.name} → ${folder.path}`);
42
+ return { ok: true, folder };
43
+ }
44
+ catch (err) {
45
+ reply.code(400);
46
+ return {
47
+ ok: false,
48
+ error: err instanceof Error ? err.message : 'failed to add folder',
49
+ };
50
+ }
51
+ });
52
+ // ---- clone github / git url, register the clone ----
53
+ app.post('/git', async (req, reply) => {
54
+ const body = (req.body ?? {});
55
+ if (!body.url) {
56
+ reply.code(400);
57
+ return { ok: false, error: '`url` is required' };
58
+ }
59
+ const workspaceRoot = process.env.COREBRAIN_DEFAULT_WORKSPACE || '/app';
60
+ if (!existsSync(workspaceRoot)) {
61
+ try {
62
+ mkdirSync(workspaceRoot, { recursive: true });
63
+ }
64
+ catch {
65
+ reply.code(500);
66
+ return {
67
+ ok: false,
68
+ error: `workspace dir ${workspaceRoot} missing and could not be created`,
69
+ };
70
+ }
71
+ }
72
+ try {
73
+ if (!statSync(workspaceRoot).isDirectory()) {
74
+ reply.code(500);
75
+ return {
76
+ ok: false,
77
+ error: `workspace path ${workspaceRoot} is not a directory`,
78
+ };
79
+ }
80
+ }
81
+ catch {
82
+ reply.code(500);
83
+ return { ok: false, error: `workspace path ${workspaceRoot} not accessible` };
84
+ }
85
+ // Default folder name: derive from the repo URL (".../foo/bar.git" → "bar").
86
+ const defaultName = body.name ??
87
+ body.url
88
+ .replace(/\/$/, '')
89
+ .replace(/\.git$/i, '')
90
+ .split('/')
91
+ .pop() ??
92
+ 'repo';
93
+ // Sanitize so we don't end up with something silly like "../etc" inside
94
+ // /app. Letters, digits, dot, dash, underscore only — anything else
95
+ // becomes "-".
96
+ const safeName = defaultName.replace(/[^a-zA-Z0-9._-]/g, '-');
97
+ const target = join(workspaceRoot, safeName);
98
+ if (existsSync(target)) {
99
+ reply.code(409);
100
+ return { ok: false, error: `target dir already exists: ${target}` };
101
+ }
102
+ const args = ['clone', '--depth', '1'];
103
+ if (body.branch) {
104
+ args.push('--branch', body.branch, '--single-branch');
105
+ }
106
+ args.push(body.url, target);
107
+ gatewayLog(`folder add (git): cloning ${body.url} → ${target}`);
108
+ try {
109
+ await execFileP('git', args, {
110
+ timeout: 5 * 60_000, // 5 minutes
111
+ env: process.env,
112
+ });
113
+ }
114
+ catch (err) {
115
+ reply.code(502);
116
+ const stderr = err?.stderr;
117
+ const message = stderr
118
+ ? Buffer.isBuffer(stderr)
119
+ ? stderr.toString('utf8')
120
+ : stderr
121
+ : err instanceof Error
122
+ ? err.message
123
+ : 'git clone failed';
124
+ gatewayLog(`folder add (git) FAILED: ${message.trim()}`);
125
+ return { ok: false, error: message.trim() };
126
+ }
127
+ try {
128
+ const folder = addFolder({
129
+ name: safeName,
130
+ path: target,
131
+ scopes: ['files', 'coding', 'exec'],
132
+ });
133
+ gatewayLog(`folder added (git): ${folder.name} → ${folder.path}`);
134
+ return { ok: true, folder };
135
+ }
136
+ catch (err) {
137
+ reply.code(500);
138
+ return {
139
+ ok: false,
140
+ error: err instanceof Error ? err.message : 'failed to register clone',
141
+ };
142
+ }
143
+ });
144
+ // ---- unregister (does not delete files on disk) ----
145
+ app.delete('/:idOrName', async (req, reply) => {
146
+ const { idOrName } = req.params;
147
+ try {
148
+ removeFolder(idOrName);
149
+ gatewayLog(`folder removed: ${idOrName}`);
150
+ return { ok: true };
151
+ }
152
+ catch (err) {
153
+ reply.code(404);
154
+ return {
155
+ ok: false,
156
+ error: err instanceof Error ? err.message : 'not found',
157
+ };
158
+ }
159
+ });
160
+ };
161
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/folders/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type Manifest } from '@redplanethq/gateway-protocol';
2
+ import type { GatewaySlots } from '../../types/config.js';
3
+ /**
4
+ * A slot is considered enabled unless the user explicitly disabled it via
5
+ * `corebrain gateway config` (slots[name].enabled === false). Missing config
6
+ * means enabled, for backwards compatibility.
7
+ */
8
+ export declare function isSlotEnabled(slots: GatewaySlots | undefined, slot: keyof GatewaySlots): boolean;
9
+ export declare function buildManifest(): {
10
+ manifest: Manifest;
11
+ etag: string;
12
+ };
13
+ //# sourceMappingURL=manifest-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-builder.d.ts","sourceRoot":"","sources":["../../../src/server/api/manifest-builder.ts"],"names":[],"mappings":"AAIA,OAAO,EAEN,KAAK,QAAQ,EAGb,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAgB,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAkGhE;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,YAAY,GAAG,SAAS,EAC/B,IAAI,EAAE,MAAM,YAAY,GACtB,OAAO,CAKT;AAED,wBAAgB,aAAa,IAAI;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAyDlE"}
@@ -0,0 +1,158 @@
1
+ import { hostname, platform } from 'node:os';
2
+ import { createHash } from 'node:crypto';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { existsSync } from 'node:fs';
5
+ import { PROTOCOL_VERSION, } from '@redplanethq/gateway-protocol';
6
+ import { getPreferences } from '../../config/preferences.js';
7
+ import { listFolders } from '../../config/folders.js';
8
+ import { browserTools } from '../../server/tools/browser-tools.js';
9
+ import { codingTools } from '../../server/tools/coding-tools.js';
10
+ import { execTools } from '../../server/tools/exec-tools.js';
11
+ import { filesTools } from '../../server/tools/files-tools.js';
12
+ import { utilsTools } from '../../server/tools/utils-tools.js';
13
+ let cliVersion = '0.0.0';
14
+ try {
15
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
16
+ cliVersion = require('../../../package.json').version ?? cliVersion;
17
+ }
18
+ catch {
19
+ /* compiled build may not have the package.json alongside */
20
+ }
21
+ /**
22
+ * Project an internal tool export (may have extra metadata) onto the public
23
+ * GatewayTool shape the manifest advertises.
24
+ */
25
+ function projectTool(t) {
26
+ return {
27
+ name: t.name,
28
+ description: t.description,
29
+ inputSchema: t.inputSchema,
30
+ };
31
+ }
32
+ // Coding agents the gateway knows how to drive. Each entry maps the public
33
+ // agent name (used in the manifest + tool params) to the binary we'll run on
34
+ // PATH. Add new entries here when a new agent is supported.
35
+ const KNOWN_AGENTS = [
36
+ { name: 'claude-code', command: 'claude' },
37
+ { name: 'codex-cli', command: 'codex' },
38
+ ];
39
+ /**
40
+ * Resolve a bare command via the env's PATH (the same one node-pty will use
41
+ * when spawning). Returns the absolute path on success, null otherwise.
42
+ *
43
+ * We don't capture login PATH here because the manifest endpoint is hit very
44
+ * frequently; reading PATH from the process env is sufficient — the gateway
45
+ * is started by `corebrain gateway start` which already inherits the user's
46
+ * shell PATH (foreground mode) or had it captured at PtyManager load.
47
+ */
48
+ function resolveBinary(cmd) {
49
+ if (cmd.includes('/'))
50
+ return existsSync(cmd) ? cmd : null;
51
+ try {
52
+ const out = execFileSync('/bin/sh', ['-c', `command -v ${cmd}`], {
53
+ encoding: 'utf8',
54
+ timeout: 2_000,
55
+ });
56
+ const path = out.trim();
57
+ return path || null;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ function detectAvailableAgents(configuredAgents, coding) {
64
+ const result = [];
65
+ for (const agent of KNOWN_AGENTS) {
66
+ // Prefer the user-configured command (often an absolute path written
67
+ // during `corebrain coding setup`). Falls back to a PATH lookup of the
68
+ // bare binary, which is unreliable for daemons launched by launchd /
69
+ // systemd because they don't inherit the login shell's PATH.
70
+ const configuredCommand = coding[agent.name]?.command;
71
+ const path = (configuredCommand ? resolveBinary(configuredCommand) : null) ??
72
+ resolveBinary(agent.command);
73
+ if (!path)
74
+ continue;
75
+ result.push({
76
+ name: agent.name,
77
+ command: agent.command,
78
+ path,
79
+ configured: configuredAgents.has(agent.name),
80
+ });
81
+ }
82
+ return result;
83
+ }
84
+ function detectDeployMode() {
85
+ // Explicit env wins (Dockerfile sets COREBRAIN_DEPLOY_MODE=docker).
86
+ const envMode = process.env.COREBRAIN_DEPLOY_MODE;
87
+ if (envMode === 'docker' || envMode === 'native')
88
+ return envMode;
89
+ // Fallback heuristic — `/.dockerenv` is created by Docker on container init.
90
+ if (existsSync('/.dockerenv'))
91
+ return 'docker';
92
+ return 'native';
93
+ }
94
+ /**
95
+ * A slot is considered enabled unless the user explicitly disabled it via
96
+ * `corebrain gateway config` (slots[name].enabled === false). Missing config
97
+ * means enabled, for backwards compatibility.
98
+ */
99
+ export function isSlotEnabled(slots, slot) {
100
+ if (!slots)
101
+ return true;
102
+ const entry = slots[slot];
103
+ if (!entry)
104
+ return true;
105
+ return entry.enabled !== false;
106
+ }
107
+ export function buildManifest() {
108
+ const prefs = getPreferences();
109
+ const gw = prefs.gateway ?? {};
110
+ const slots = gw.slots;
111
+ // Respect the user's slot toggles — a disabled slot hides its tools (and
112
+ // agents, when coding is off) from the manifest. Callers that shouldn't
113
+ // see a tool shouldn't be able to hit its route either; server.ts applies
114
+ // the same filter when registering routes.
115
+ const tools = [
116
+ ...(isSlotEnabled(slots, 'browser') ? browserTools : []),
117
+ ...(isSlotEnabled(slots, 'coding') ? codingTools : []),
118
+ ...(isSlotEnabled(slots, 'exec') ? execTools : []),
119
+ ...(isSlotEnabled(slots, 'files') ? filesTools : []),
120
+ ...utilsTools,
121
+ ].map(projectTool);
122
+ // Configured coding agents — keys of prefs.coding (e.g. "claude-code", "codex-cli").
123
+ // Empty when the coding slot is disabled so UIs don't offer agents the user
124
+ // doesn't want exposed.
125
+ const coding = (prefs.coding ?? {});
126
+ const agents = isSlotEnabled(slots, 'coding') ? Object.keys(coding) : [];
127
+ const configuredAgents = new Set(agents);
128
+ const availableAgents = isSlotEnabled(slots, 'coding')
129
+ ? detectAvailableAgents(configuredAgents, coding)
130
+ : [];
131
+ const manifest = {
132
+ protocolVersion: PROTOCOL_VERSION,
133
+ gateway: {
134
+ id: gw.id ?? 'pending',
135
+ name: gw.name ?? `${hostname()}-gateway`,
136
+ version: cliVersion,
137
+ platform: platform(),
138
+ hostname: hostname(),
139
+ deployMode: detectDeployMode(),
140
+ },
141
+ capabilities: {
142
+ browser: {
143
+ enabled: isSlotEnabled(slots, 'browser'),
144
+ engines: ['chromium'],
145
+ },
146
+ },
147
+ folders: listFolders(),
148
+ tools,
149
+ agents,
150
+ availableAgents,
151
+ };
152
+ const etag = createHash('sha256')
153
+ .update(JSON.stringify(manifest))
154
+ .digest('hex')
155
+ .slice(0, 16);
156
+ return { manifest, etag };
157
+ }
158
+ //# sourceMappingURL=manifest-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-builder.js","sourceRoot":"","sources":["../../../src/server/api/manifest-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ export declare const opsRoutes: FastifyPluginAsync;
3
+ //# sourceMappingURL=ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../../src/server/api/ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAQhD,eAAO,MAAM,SAAS,EAAE,kBA6BvB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { hostname, platform } from 'node:os';
2
+ import { buildManifest } from './manifest-builder.js';
3
+ import { getPreferences } from '../../config/preferences.js';
4
+ const startedAt = Date.now();
5
+ export const opsRoutes = async (app) => {
6
+ app.get('/manifest', async (_req, reply) => {
7
+ const { manifest, etag } = buildManifest();
8
+ reply.header('etag', etag);
9
+ return manifest;
10
+ });
11
+ app.get('/healthz', async () => {
12
+ const { etag } = buildManifest();
13
+ return {
14
+ status: 'ok',
15
+ manifestEtag: etag,
16
+ uptimeSec: Math.floor((Date.now() - startedAt) / 1000),
17
+ };
18
+ });
19
+ app.get('/healthz/public', async () => {
20
+ return { status: 'ok' };
21
+ });
22
+ app.get('/verify', async () => {
23
+ const gw = getPreferences().gateway ?? {};
24
+ return {
25
+ ok: true,
26
+ gatewayId: gw.id ?? null,
27
+ hostname: hostname(),
28
+ platform: platform(),
29
+ };
30
+ });
31
+ };
32
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../../../src/server/api/ops.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAEpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,SAAS,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC1D,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QAC1C,MAAM,EAAC,QAAQ,EAAE,IAAI,EAAC,GAAG,aAAa,EAAE,CAAC;QACzC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3B,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,EAAC,IAAI,EAAC,GAAG,aAAa,EAAE,CAAC;QAC/B,OAAO;YACN,MAAM,EAAE,IAAa;YACrB,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;SACtD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;QACrC,OAAO,EAAC,MAAM,EAAE,IAAa,EAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,EAAE,GAA2B,cAAc,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;QAClE,OAAO;YACN,EAAE,EAAE,IAAI;YACR,SAAS,EAAE,EAAE,CAAC,EAAE,IAAI,IAAI;YACxB,QAAQ,EAAE,QAAQ,EAAE;YACpB,QAAQ,EAAE,QAAQ,EAAE;SACpB,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type FastifyInstance } from 'fastify';
2
+ export interface ApiServerOptions {
3
+ port: number;
4
+ host?: string;
5
+ log?: (message: string) => void;
6
+ }
7
+ export declare function buildServer(opts: ApiServerOptions): Promise<FastifyInstance>;
8
+ export declare function startServer(opts: ApiServerOptions): Promise<FastifyInstance>;
9
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/server/api/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAC,KAAK,eAAe,EAAC,MAAM,SAAS,CAAC;AActD,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoDlF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAKlF"}
@@ -0,0 +1,66 @@
1
+ import Fastify from 'fastify';
2
+ import fastifyWebsocket from '@fastify/websocket';
3
+ import { makeAuthHook } from './auth.js';
4
+ import { opsRoutes } from './ops.js';
5
+ import { codingRoutes } from './coding/index.js';
6
+ import { browserRoutes } from './browser/index.js';
7
+ import { execRoutes } from './exec/index.js';
8
+ import { filesRoutes } from './files/index.js';
9
+ import { utilsRoutes } from './utils/index.js';
10
+ import { folderRoutes } from './folders/index.js';
11
+ import { shellRoutes } from './shell/index.js';
12
+ import { isSlotEnabled } from './manifest-builder.js';
13
+ import { getPreferences } from '../../config/preferences.js';
14
+ export async function buildServer(opts) {
15
+ const log = opts.log ?? (() => { });
16
+ const app = Fastify({
17
+ logger: false,
18
+ bodyLimit: 50 * 1024 * 1024, // 50 MB — browser_screenshot base64 can be large
19
+ trustProxy: true,
20
+ });
21
+ await app.register(fastifyWebsocket);
22
+ // Auth for every route except /healthz/public.
23
+ app.addHook('onRequest', makeAuthHook(['/healthz/public']));
24
+ // Ops routes are always on (manifest / healthz / verify).
25
+ await app.register(opsRoutes);
26
+ // Group routes gated by slot config — a disabled slot hides both the
27
+ // manifest entries and the HTTP routes so clients can't dodge the toggle.
28
+ const slots = getPreferences().gateway?.slots;
29
+ if (isSlotEnabled(slots, 'coding')) {
30
+ await app.register(codingRoutes, { prefix: '/api/coding' });
31
+ }
32
+ if (isSlotEnabled(slots, 'browser')) {
33
+ await app.register(browserRoutes, { prefix: '/api/browser' });
34
+ }
35
+ if (isSlotEnabled(slots, 'exec')) {
36
+ await app.register(execRoutes, { prefix: '/api/exec' });
37
+ }
38
+ if (isSlotEnabled(slots, 'files')) {
39
+ await app.register(filesRoutes, { prefix: '/api/files' });
40
+ }
41
+ // utils has no slot — it's always enabled (e.g. `sleep`).
42
+ await app.register(utilsRoutes, { prefix: '/api/utils' });
43
+ // Folder management — used by the webapp's per-gateway settings page to
44
+ // add/remove local paths or clone GitHub URLs into the workspace.
45
+ await app.register(folderRoutes, { prefix: '/api/folders' });
46
+ // General-purpose shell PTY for the webapp's Terminal tab.
47
+ await app.register(shellRoutes, { prefix: '/api/shell' });
48
+ app.setErrorHandler((err, _req, reply) => {
49
+ log(`api error: ${err.message}`);
50
+ if (reply.sent)
51
+ return;
52
+ const status = err.statusCode ?? 500;
53
+ reply.code(status).send({
54
+ ok: false,
55
+ error: { code: err.code ?? 'INTERNAL', message: err.message },
56
+ });
57
+ });
58
+ return app;
59
+ }
60
+ export async function startServer(opts) {
61
+ const app = await buildServer(opts);
62
+ await app.listen({ port: opts.port, host: opts.host ?? '0.0.0.0' });
63
+ opts.log?.(`gateway HTTP listening on :${opts.port}`);
64
+ return app;
65
+ }
66
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/api/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ /**
3
+ * General-purpose shell PTY for the webapp's per-gateway Terminal tab.
4
+ *
5
+ * POST /api/shell/spawn
6
+ * body: { cwd?: string }
7
+ * → 200 { ok: true, sessionId, pid }
8
+ *
9
+ * Spawns the user's `$SHELL` (falling back to `/bin/bash` → `/bin/sh`) inside
10
+ * a PTY managed by `ptyManager`. The browser attaches via the existing xterm
11
+ * WS endpoint — no CodingSession involved.
12
+ *
13
+ * Auth is handled by the global gateway auth hook (security key), so anyone
14
+ * able to hit this can already exec arbitrary tools — no extra guardrails.
15
+ */
16
+ export declare const shellRoutes: FastifyPluginAsync;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/api/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAOhD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,EAAE,kBA8CzB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { homedir } from 'node:os';
3
+ import { existsSync } from 'node:fs';
4
+ import { ptyManager } from '../../../server/pty/manager.js';
5
+ import { gatewayLog } from '../../../server/gateway-log.js';
6
+ /**
7
+ * General-purpose shell PTY for the webapp's per-gateway Terminal tab.
8
+ *
9
+ * POST /api/shell/spawn
10
+ * body: { cwd?: string }
11
+ * → 200 { ok: true, sessionId, pid }
12
+ *
13
+ * Spawns the user's `$SHELL` (falling back to `/bin/bash` → `/bin/sh`) inside
14
+ * a PTY managed by `ptyManager`. The browser attaches via the existing xterm
15
+ * WS endpoint — no CodingSession involved.
16
+ *
17
+ * Auth is handled by the global gateway auth hook (security key), so anyone
18
+ * able to hit this can already exec arbitrary tools — no extra guardrails.
19
+ */
20
+ export const shellRoutes = async (app) => {
21
+ app.post('/spawn', async (req, reply) => {
22
+ const body = (req.body ?? {});
23
+ // Resolve a usable shell. SHELL → /bin/zsh → /bin/bash → /bin/sh.
24
+ const candidates = [
25
+ process.env.SHELL,
26
+ '/bin/zsh',
27
+ '/bin/bash',
28
+ '/bin/sh',
29
+ ].filter((s) => Boolean(s && existsSync(s)));
30
+ const shell = candidates[0];
31
+ if (!shell) {
32
+ reply.code(500);
33
+ return { ok: false, error: 'no usable shell on PATH' };
34
+ }
35
+ const cwd = body.cwd && existsSync(body.cwd)
36
+ ? body.cwd
37
+ : process.env.COREBRAIN_DEFAULT_WORKSPACE &&
38
+ existsSync(process.env.COREBRAIN_DEFAULT_WORKSPACE)
39
+ ? process.env.COREBRAIN_DEFAULT_WORKSPACE
40
+ : homedir();
41
+ const sessionId = randomUUID();
42
+ gatewayLog(`shell spawn: shell=${shell} cwd=${cwd} sessionId=${sessionId}`);
43
+ try {
44
+ const { pid } = ptyManager.spawn({
45
+ sessionId,
46
+ command: shell,
47
+ args: ['-il'], // login + interactive so PATH/aliases are loaded
48
+ cwd,
49
+ agent: 'shell',
50
+ });
51
+ return { ok: true, sessionId, pid };
52
+ }
53
+ catch (err) {
54
+ const msg = err instanceof Error ? err.message : 'spawn failed';
55
+ gatewayLog(`shell spawn FAILED: ${msg}`);
56
+ reply.code(500);
57
+ return { ok: false, error: msg };
58
+ }
59
+ });
60
+ };
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/api/shell/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAEhD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,WAAW,GAAuB,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5D,GAAG,CAAC,IAAI,CAAyB,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAC/D,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAmB,CAAC;QAEhD,kEAAkE;QAClE,MAAM,UAAU,GAAG;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK;YACjB,UAAU;YACV,WAAW;YACX,SAAS;SACT,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAC,CAAC;QACtD,CAAC;QAED,MAAM,GAAG,GACR,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;YAC/B,CAAC,CAAC,IAAI,CAAC,GAAG;YACV,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B;gBACtC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;gBACrD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B;gBACzC,CAAC,CAAC,OAAO,EAAE,CAAC;QAEf,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,UAAU,CACT,sBAAsB,KAAK,QAAQ,GAAG,cAAc,SAAS,EAAE,CAC/D,CAAC;QAEF,IAAI,CAAC;YACJ,MAAM,EAAC,GAAG,EAAC,GAAG,UAAU,CAAC,KAAK,CAAC;gBAC9B,SAAS;gBACT,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,iDAAiD;gBAChE,GAAG;gBACH,KAAK,EAAE,OAAO;aACd,CAAC,CAAC;YACH,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;YAChE,UAAU,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC;QAChC,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { FastifyPluginAsync } from 'fastify';
2
+ interface ToolMeta {
3
+ name: string;
4
+ description: string;
5
+ }
6
+ interface ToolResult {
7
+ success: boolean;
8
+ result?: unknown;
9
+ error?: string;
10
+ }
11
+ type Executor = (toolName: string, params: Record<string, unknown>) => Promise<ToolResult> | ToolResult;
12
+ /**
13
+ * Build a Fastify plugin that exposes one POST route per tool in `tools`,
14
+ * each at path `/{tool.name}` — e.g. /api/coding/coding_ask.
15
+ *
16
+ * The plugin is meant to be registered with a prefix:
17
+ * app.register(makeToolGroupRoutes(codingTools, executeCodingTool), { prefix: '/api/coding' });
18
+ */
19
+ export declare function makeToolGroupRoutes(tools: ToolMeta[], execute: Executor): FastifyPluginAsync;
20
+ export {};
21
+ //# sourceMappingURL=tool-group.d.ts.map