mstro-app 0.4.38 → 0.4.43

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 (198) hide show
  1. package/bin/commands/login.js +17 -7
  2. package/bin/commands/logout.js +14 -6
  3. package/bin/commands/status.js +9 -3
  4. package/bin/commands/whoami.js +10 -4
  5. package/bin/mstro.js +11 -1
  6. package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -1
  7. package/dist/server/cli/headless/claude-invoker-stream.js +1 -0
  8. package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -1
  9. package/dist/server/cli/headless/index.d.ts +1 -0
  10. package/dist/server/cli/headless/index.d.ts.map +1 -1
  11. package/dist/server/cli/headless/index.js +2 -0
  12. package/dist/server/cli/headless/index.js.map +1 -1
  13. package/dist/server/cli/headless/resilient-runner.d.ts +47 -0
  14. package/dist/server/cli/headless/resilient-runner.d.ts.map +1 -0
  15. package/dist/server/cli/headless/resilient-runner.js +234 -0
  16. package/dist/server/cli/headless/resilient-runner.js.map +1 -0
  17. package/dist/server/cli/headless/retry-strategies.d.ts +44 -0
  18. package/dist/server/cli/headless/retry-strategies.d.ts.map +1 -0
  19. package/dist/server/cli/headless/retry-strategies.js +262 -0
  20. package/dist/server/cli/headless/retry-strategies.js.map +1 -0
  21. package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
  22. package/dist/server/cli/headless/stall-assessor.js +5 -0
  23. package/dist/server/cli/headless/stall-assessor.js.map +1 -1
  24. package/dist/server/cli/headless/tool-watchdog.d.ts +2 -0
  25. package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
  26. package/dist/server/cli/headless/tool-watchdog.js +31 -4
  27. package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
  28. package/dist/server/cli/improvisation-retry.d.ts.map +1 -1
  29. package/dist/server/cli/improvisation-retry.js +1 -30
  30. package/dist/server/cli/improvisation-retry.js.map +1 -1
  31. package/dist/server/cli/improvisation-session-manager.d.ts +1 -0
  32. package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
  33. package/dist/server/cli/improvisation-session-manager.js +16 -3
  34. package/dist/server/cli/improvisation-session-manager.js.map +1 -1
  35. package/dist/server/cli/prompt-builders.d.ts.map +1 -1
  36. package/dist/server/cli/prompt-builders.js +31 -13
  37. package/dist/server/cli/prompt-builders.js.map +1 -1
  38. package/dist/server/index.js +1 -9
  39. package/dist/server/index.js.map +1 -1
  40. package/dist/server/mcp/bouncer-cli.js +5 -4
  41. package/dist/server/mcp/bouncer-cli.js.map +1 -1
  42. package/dist/server/mcp/bouncer-haiku.js +1 -1
  43. package/dist/server/mcp/bouncer-haiku.js.map +1 -1
  44. package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
  45. package/dist/server/mcp/bouncer-integration.js +14 -8
  46. package/dist/server/mcp/bouncer-integration.js.map +1 -1
  47. package/dist/server/mcp/security-patterns.js +1 -1
  48. package/dist/server/mcp/security-patterns.js.map +1 -1
  49. package/dist/server/services/plan/composer.d.ts.map +1 -1
  50. package/dist/server/services/plan/composer.js +19 -9
  51. package/dist/server/services/plan/composer.js.map +1 -1
  52. package/dist/server/services/plan/executor.d.ts +6 -1
  53. package/dist/server/services/plan/executor.d.ts.map +1 -1
  54. package/dist/server/services/plan/executor.js +158 -76
  55. package/dist/server/services/plan/executor.js.map +1 -1
  56. package/dist/server/services/plan/front-matter.d.ts +1 -0
  57. package/dist/server/services/plan/front-matter.d.ts.map +1 -1
  58. package/dist/server/services/plan/front-matter.js +6 -0
  59. package/dist/server/services/plan/front-matter.js.map +1 -1
  60. package/dist/server/services/plan/issue-classification.d.ts +11 -0
  61. package/dist/server/services/plan/issue-classification.d.ts.map +1 -0
  62. package/dist/server/services/plan/issue-classification.js +20 -0
  63. package/dist/server/services/plan/issue-classification.js.map +1 -0
  64. package/dist/server/services/plan/issue-prompt-builder.d.ts.map +1 -1
  65. package/dist/server/services/plan/issue-prompt-builder.js +10 -5
  66. package/dist/server/services/plan/issue-prompt-builder.js.map +1 -1
  67. package/dist/server/services/plan/issue-retry.d.ts +0 -5
  68. package/dist/server/services/plan/issue-retry.d.ts.map +1 -1
  69. package/dist/server/services/plan/issue-retry.js +12 -241
  70. package/dist/server/services/plan/issue-retry.js.map +1 -1
  71. package/dist/server/services/plan/parser-core.d.ts.map +1 -1
  72. package/dist/server/services/plan/parser-core.js +1 -0
  73. package/dist/server/services/plan/parser-core.js.map +1 -1
  74. package/dist/server/services/plan/review-gate.d.ts.map +1 -1
  75. package/dist/server/services/plan/review-gate.js +9 -6
  76. package/dist/server/services/plan/review-gate.js.map +1 -1
  77. package/dist/server/services/plan/types.d.ts +1 -0
  78. package/dist/server/services/plan/types.d.ts.map +1 -1
  79. package/dist/server/services/platform-credentials.d.ts.map +1 -1
  80. package/dist/server/services/platform-credentials.js +11 -4
  81. package/dist/server/services/platform-credentials.js.map +1 -1
  82. package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
  83. package/dist/server/services/terminal/pty-manager.js +7 -1
  84. package/dist/server/services/terminal/pty-manager.js.map +1 -1
  85. package/dist/server/services/websocket/handler-context.d.ts +2 -0
  86. package/dist/server/services/websocket/handler-context.d.ts.map +1 -1
  87. package/dist/server/services/websocket/handler.d.ts +2 -0
  88. package/dist/server/services/websocket/handler.d.ts.map +1 -1
  89. package/dist/server/services/websocket/handler.js +18 -7
  90. package/dist/server/services/websocket/handler.js.map +1 -1
  91. package/dist/server/services/websocket/plan-execution-handlers.js +6 -6
  92. package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -1
  93. package/dist/server/services/websocket/quality-fix-agent.d.ts.map +1 -1
  94. package/dist/server/services/websocket/quality-fix-agent.js +90 -42
  95. package/dist/server/services/websocket/quality-fix-agent.js.map +1 -1
  96. package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
  97. package/dist/server/services/websocket/quality-handlers.js +48 -7
  98. package/dist/server/services/websocket/quality-handlers.js.map +1 -1
  99. package/dist/server/services/websocket/quality-persistence.d.ts +22 -0
  100. package/dist/server/services/websocket/quality-persistence.d.ts.map +1 -1
  101. package/dist/server/services/websocket/quality-persistence.js +48 -1
  102. package/dist/server/services/websocket/quality-persistence.js.map +1 -1
  103. package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -1
  104. package/dist/server/services/websocket/quality-review-agent.js +74 -32
  105. package/dist/server/services/websocket/quality-review-agent.js.map +1 -1
  106. package/dist/server/services/websocket/quality-tools.d.ts.map +1 -1
  107. package/dist/server/services/websocket/quality-tools.js +18 -18
  108. package/dist/server/services/websocket/quality-tools.js.map +1 -1
  109. package/dist/server/services/websocket/skill-handlers.d.ts +3 -1
  110. package/dist/server/services/websocket/skill-handlers.d.ts.map +1 -1
  111. package/dist/server/services/websocket/skill-handlers.js +52 -41
  112. package/dist/server/services/websocket/skill-handlers.js.map +1 -1
  113. package/dist/server/services/websocket/skill-watcher.d.ts +17 -0
  114. package/dist/server/services/websocket/skill-watcher.d.ts.map +1 -0
  115. package/dist/server/services/websocket/skill-watcher.js +85 -0
  116. package/dist/server/services/websocket/skill-watcher.js.map +1 -0
  117. package/dist/server/services/websocket/types.d.ts +2 -268
  118. package/dist/server/services/websocket/types.d.ts.map +1 -1
  119. package/dist/server/services/websocket/types.js +0 -4
  120. package/dist/server/services/websocket/types.js.map +1 -1
  121. package/package.json +1 -1
  122. package/server/cli/headless/claude-invoker-stream.ts +1 -0
  123. package/server/cli/headless/index.ts +2 -0
  124. package/server/cli/headless/resilient-runner.ts +354 -0
  125. package/server/cli/headless/retry-strategies.ts +330 -0
  126. package/server/cli/headless/stall-assessor.ts +5 -0
  127. package/server/cli/headless/tool-watchdog.ts +40 -4
  128. package/server/cli/improvisation-retry.ts +1 -32
  129. package/server/cli/improvisation-session-manager.ts +17 -3
  130. package/server/cli/prompt-builders.ts +33 -12
  131. package/server/index.ts +1 -9
  132. package/server/mcp/bouncer-cli.ts +5 -4
  133. package/server/mcp/bouncer-haiku.ts +1 -1
  134. package/server/mcp/bouncer-integration.ts +15 -8
  135. package/server/mcp/security-patterns.ts +1 -1
  136. package/server/services/plan/agents/code-review.md +109 -0
  137. package/server/services/plan/agents/commit-message.md +26 -0
  138. package/server/services/plan/agents/execute-issue.md +10 -1
  139. package/server/services/plan/agents/fix-quality.md +24 -0
  140. package/server/services/plan/agents/pr-description.md +28 -0
  141. package/server/services/plan/composer.ts +20 -9
  142. package/server/services/plan/executor.ts +160 -76
  143. package/server/services/plan/front-matter.ts +7 -0
  144. package/server/services/plan/issue-classification.ts +21 -0
  145. package/server/services/plan/issue-prompt-builder.ts +11 -5
  146. package/server/services/plan/issue-retry.ts +15 -330
  147. package/server/services/plan/parser-core.ts +1 -0
  148. package/server/services/plan/review-gate.ts +9 -6
  149. package/server/services/plan/types.ts +3 -0
  150. package/server/services/platform-credentials.ts +10 -4
  151. package/server/services/terminal/pty-manager.ts +7 -1
  152. package/server/services/websocket/handler-context.ts +2 -0
  153. package/server/services/websocket/handler.ts +18 -8
  154. package/server/services/websocket/plan-execution-handlers.ts +7 -7
  155. package/server/services/websocket/quality-fix-agent.ts +86 -44
  156. package/server/services/websocket/quality-handlers.ts +48 -7
  157. package/server/services/websocket/quality-persistence.ts +75 -1
  158. package/server/services/websocket/quality-review-agent.ts +70 -31
  159. package/server/services/websocket/quality-tools.ts +16 -14
  160. package/server/services/websocket/skill-handlers.ts +50 -40
  161. package/server/services/websocket/skill-watcher.ts +79 -0
  162. package/server/services/websocket/types.ts +0 -311
  163. package/dist/server/services/deploy/ai-broker.d.ts +0 -63
  164. package/dist/server/services/deploy/ai-broker.d.ts.map +0 -1
  165. package/dist/server/services/deploy/ai-broker.js +0 -360
  166. package/dist/server/services/deploy/ai-broker.js.map +0 -1
  167. package/dist/server/services/deploy/board-execution-handler.d.ts +0 -114
  168. package/dist/server/services/deploy/board-execution-handler.d.ts.map +0 -1
  169. package/dist/server/services/deploy/board-execution-handler.js +0 -621
  170. package/dist/server/services/deploy/board-execution-handler.js.map +0 -1
  171. package/dist/server/services/deploy/credentials.d.ts +0 -35
  172. package/dist/server/services/deploy/credentials.d.ts.map +0 -1
  173. package/dist/server/services/deploy/credentials.js +0 -177
  174. package/dist/server/services/deploy/credentials.js.map +0 -1
  175. package/dist/server/services/deploy/deploy-ai-service.d.ts +0 -107
  176. package/dist/server/services/deploy/deploy-ai-service.d.ts.map +0 -1
  177. package/dist/server/services/deploy/deploy-ai-service.js +0 -294
  178. package/dist/server/services/deploy/deploy-ai-service.js.map +0 -1
  179. package/dist/server/services/deploy/headless-session-handler.d.ts +0 -94
  180. package/dist/server/services/deploy/headless-session-handler.d.ts.map +0 -1
  181. package/dist/server/services/deploy/headless-session-handler.js +0 -266
  182. package/dist/server/services/deploy/headless-session-handler.js.map +0 -1
  183. package/dist/server/services/websocket/deploy-handlers.d.ts +0 -14
  184. package/dist/server/services/websocket/deploy-handlers.d.ts.map +0 -1
  185. package/dist/server/services/websocket/deploy-handlers.js +0 -409
  186. package/dist/server/services/websocket/deploy-handlers.js.map +0 -1
  187. package/dist/server/services/websocket/handlers/deploy-handlers.d.ts +0 -11
  188. package/dist/server/services/websocket/handlers/deploy-handlers.d.ts.map +0 -1
  189. package/dist/server/services/websocket/handlers/deploy-handlers.js +0 -176
  190. package/dist/server/services/websocket/handlers/deploy-handlers.js.map +0 -1
  191. package/server/cli/headless/RESEARCH.md +0 -627
  192. package/server/services/deploy/ai-broker.ts +0 -512
  193. package/server/services/deploy/board-execution-handler.ts +0 -847
  194. package/server/services/deploy/credentials.ts +0 -200
  195. package/server/services/deploy/deploy-ai-service.ts +0 -401
  196. package/server/services/deploy/headless-session-handler.ts +0 -414
  197. package/server/services/websocket/deploy-handlers.ts +0 -544
  198. package/server/services/websocket/handlers/deploy-handlers.ts +0 -228
@@ -1,360 +0,0 @@
1
- // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
- // Licensed under the MIT License. See LICENSE file for details.
3
- /**
4
- * AI Broker — HTTP endpoint for developer backends to invoke AI execution.
5
- *
6
- * POST /api/deploy/ai/invoke
7
- * Accepts { capability, deploymentId, endUserId, prompt, ... }
8
- * Authorization: Bearer <deploy-token>
9
- *
10
- * GET /api/deploy/ai/jobs/:jobId
11
- * Poll board execution status.
12
- *
13
- * Deploy tokens are per-deployment. The CLI stores the SHA-256 hash; the
14
- * developer's backend sends the raw token. We hash the incoming token and
15
- * compare against the stored hash.
16
- *
17
- * Headless sessions return SSE (text/event-stream).
18
- * Board executions return { jobId, statusUrl } immediately.
19
- */
20
- import { createHash } from 'node:crypto';
21
- import { Hono } from 'hono';
22
- import { streamSSE } from 'hono/streaming';
23
- import { getBoardExecutionStatus, startBoardExecution, } from './board-execution-handler.js';
24
- import { handleHeadlessSession, } from './headless-session-handler.js';
25
- // ========== Token Store ==========
26
- /**
27
- * In-memory store for deploy tokens. Populated when deployments are created
28
- * via the WebSocket handlers. Each entry maps a deployment ID to its
29
- * hashed token and configuration.
30
- */
31
- const tokenStore = new Map();
32
- export function registerDeployToken(record) {
33
- tokenStore.set(record.deploymentId, record);
34
- }
35
- export function unregisterDeployToken(deploymentId) {
36
- tokenStore.delete(deploymentId);
37
- }
38
- export function getDeployTokenRecord(deploymentId) {
39
- return tokenStore.get(deploymentId);
40
- }
41
- /**
42
- * Update rate limit and AI config on an existing deploy token record.
43
- * Called when the server syncs updated deployment config to the CLI.
44
- */
45
- export function updateDeployTokenConfig(deploymentId, updates) {
46
- const record = tokenStore.get(deploymentId);
47
- if (!record)
48
- return false;
49
- if (updates.maxRequestsPerMinute !== undefined) {
50
- record.rateLimit.maxRequestsPerMinute = updates.maxRequestsPerMinute;
51
- }
52
- if (updates.maxConcurrentSessions !== undefined) {
53
- record.rateLimit.maxConcurrentSessions = updates.maxConcurrentSessions;
54
- }
55
- if (updates.maxTokensPerRequest !== undefined) {
56
- record.aiConfig.maxTokensPerRequest = updates.maxTokensPerRequest;
57
- }
58
- if (updates.aiEnabled !== undefined) {
59
- record.aiConfig.aiEnabled = updates.aiEnabled;
60
- }
61
- return true;
62
- }
63
- let usageReportListener = null;
64
- let healthUpdateListener = null;
65
- /**
66
- * Register a listener for deploy usage reports.
67
- * Called from the server setup to wire usage reports to the platform connection.
68
- */
69
- export function setDeployUsageReportListener(listener) {
70
- usageReportListener = listener;
71
- }
72
- /**
73
- * Register a listener for deploy AI health updates.
74
- * Called from the server setup to wire health updates to the platform connection.
75
- */
76
- export function setDeployHealthUpdateListener(listener) {
77
- healthUpdateListener = listener;
78
- }
79
- // ========== Token Validation ==========
80
- function hashToken(token) {
81
- return createHash('sha256').update(token).digest('hex');
82
- }
83
- function extractBearerToken(authHeader) {
84
- if (!authHeader)
85
- return null;
86
- const match = authHeader.match(/^Bearer\s+(.+)$/i);
87
- return match ? match[1] : null;
88
- }
89
- /**
90
- * Validate a deploy token against the stored hash.
91
- * Returns the token record if valid, null otherwise.
92
- */
93
- function validateDeployToken(rawToken, deploymentId) {
94
- const record = tokenStore.get(deploymentId);
95
- if (!record)
96
- return null;
97
- const incomingHash = hashToken(rawToken);
98
- if (incomingHash !== record.tokenHash)
99
- return null;
100
- return record;
101
- }
102
- const brokerRateBuckets = new Map();
103
- function getBucket(key) {
104
- let bucket = brokerRateBuckets.get(key);
105
- if (!bucket) {
106
- bucket = { timestamps: [], activeSessions: 0 };
107
- brokerRateBuckets.set(key, bucket);
108
- }
109
- return bucket;
110
- }
111
- function pruneTimestamps(bucket) {
112
- const oneMinuteAgo = Date.now() - 60_000;
113
- while (bucket.timestamps.length > 0 && bucket.timestamps[0] < oneMinuteAgo) {
114
- bucket.timestamps.shift();
115
- }
116
- }
117
- function checkBrokerRateLimit(record) {
118
- const bucket = getBucket(record.deploymentId);
119
- if (bucket.activeSessions >= record.rateLimit.maxConcurrentSessions) {
120
- return { limited: true, retryAfterMs: 5_000 };
121
- }
122
- if (record.rateLimit.maxRequestsPerMinute !== null) {
123
- pruneTimestamps(bucket);
124
- if (bucket.timestamps.length >= record.rateLimit.maxRequestsPerMinute) {
125
- // Calculate retry-after based on oldest timestamp expiry
126
- const oldestTs = bucket.timestamps[0];
127
- const retryAfterMs = oldestTs + 60_000 - Date.now();
128
- return { limited: true, retryAfterMs: Math.max(1_000, retryAfterMs) };
129
- }
130
- }
131
- return { limited: false };
132
- }
133
- function recordBrokerRequestStart(deploymentId) {
134
- const bucket = getBucket(deploymentId);
135
- bucket.timestamps.push(Date.now());
136
- bucket.activeSessions++;
137
- }
138
- function recordBrokerRequestEnd(deploymentId) {
139
- const bucket = getBucket(deploymentId);
140
- bucket.activeSessions = Math.max(0, bucket.activeSessions - 1);
141
- }
142
- function validateBody(body) {
143
- if (!body.capability || !body.deploymentId || !body.endUserId || !body.prompt) {
144
- return 'Missing required fields: capability, deploymentId, endUserId, prompt';
145
- }
146
- if (body.capability !== 'headless' && body.capability !== 'pm-board') {
147
- return "Invalid capability. Must be 'headless' or 'pm-board'";
148
- }
149
- if (body.capability === 'pm-board' && !body.boardTemplateId) {
150
- return "boardTemplateId is required when capability is 'pm-board'";
151
- }
152
- return null;
153
- }
154
- function validateTokenAndConfig(rawToken, body) {
155
- const record = validateDeployToken(rawToken, body.deploymentId);
156
- if (!record) {
157
- return { ok: false, error: 'Invalid deploy token', status: 401 };
158
- }
159
- if (!record.enabled) {
160
- return { ok: false, error: 'Deployment is disabled', status: 403 };
161
- }
162
- if (!record.aiConfig.aiEnabled) {
163
- return { ok: false, error: 'AI features are not enabled for this deployment', status: 403 };
164
- }
165
- if (!record.capabilities.includes(body.capability)) {
166
- return { ok: false, error: `Capability '${body.capability}' is not enabled for this deployment`, status: 403 };
167
- }
168
- const rateCheck = checkBrokerRateLimit(record);
169
- if (rateCheck.limited) {
170
- const retryAfterSec = Math.ceil((rateCheck.retryAfterMs ?? 5_000) / 1_000);
171
- return {
172
- ok: false,
173
- error: 'Rate limit exceeded. Try again later.',
174
- status: 429,
175
- headers: { 'Retry-After': String(retryAfterSec) },
176
- };
177
- }
178
- return { ok: true, body, record };
179
- }
180
- // ========== Route Factory ==========
181
- export function createAiBrokerRoutes() {
182
- const routes = new Hono();
183
- // ── POST /invoke — trigger AI execution ────────────────────
184
- routes.post('/invoke', async (c) => {
185
- const rawToken = extractBearerToken(c.req.header('Authorization'));
186
- if (!rawToken) {
187
- return c.json({ error: 'Missing or malformed Authorization header. Expected: Bearer <deploy-token>' }, 401);
188
- }
189
- let body;
190
- try {
191
- body = await c.req.json();
192
- }
193
- catch {
194
- return c.json({ error: 'Invalid JSON body' }, 400);
195
- }
196
- const bodyError = validateBody(body);
197
- if (bodyError) {
198
- return c.json({ error: bodyError }, 400);
199
- }
200
- const validation = validateTokenAndConfig(rawToken, body);
201
- if (!validation.ok) {
202
- return c.json({ error: validation.error }, { status: validation.status, headers: validation.headers });
203
- }
204
- if (body.capability === 'headless') {
205
- return handleHeadlessInvoke(c, body, validation.record);
206
- }
207
- return handleBoardInvoke(c, body, validation.record);
208
- });
209
- // ── GET /jobs/:jobId — poll board execution status ─────────
210
- routes.get('/jobs/:jobId', (c) => {
211
- const { jobId } = c.req.param();
212
- const endUserId = c.req.query('endUserId');
213
- const status = getBoardExecutionStatus(jobId, endUserId ?? undefined);
214
- if (!status) {
215
- return c.json({ error: 'Job not found' }, 404);
216
- }
217
- return c.json(status);
218
- });
219
- return routes;
220
- }
221
- // ========== Headless Dispatch ==========
222
- async function handleHeadlessInvoke(c, body, record) {
223
- const config = {
224
- deploymentId: record.deploymentId,
225
- aiEnabled: record.aiConfig.aiEnabled,
226
- allowedAiCapabilities: record.capabilities,
227
- maxTokensPerRequest: record.aiConfig.maxTokensPerRequest,
228
- maxRequestsPerMinute: record.rateLimit.maxRequestsPerMinute,
229
- maxConcurrentSessions: record.rateLimit.maxConcurrentSessions,
230
- defaultSystemPrompt: record.aiConfig.defaultSystemPrompt,
231
- defaultModel: record.aiConfig.defaultModel,
232
- workingDir: record.aiConfig.workingDir,
233
- };
234
- recordBrokerRequestStart(record.deploymentId);
235
- // Stream headless session output as SSE
236
- return streamSSE(c, async (stream) => {
237
- let resultSent = false;
238
- const callbacks = {
239
- onOutput: (text) => {
240
- stream.writeSSE({ event: 'output', data: text }).catch(() => { });
241
- },
242
- onThinking: (text) => {
243
- stream.writeSSE({ event: 'thinking', data: text }).catch(() => { });
244
- },
245
- onToolUse: (event) => {
246
- stream.writeSSE({ event: 'tool_use', data: JSON.stringify(event) }).catch(() => { });
247
- },
248
- onUsageReport: (report) => {
249
- usageReportListener?.(report);
250
- },
251
- onHealthUpdate: (update) => {
252
- healthUpdateListener?.(update);
253
- },
254
- };
255
- try {
256
- const result = await handleHeadlessSession({
257
- prompt: body.prompt,
258
- systemPrompt: body.systemPrompt,
259
- allowedTools: body.allowedTools,
260
- model: body.model,
261
- endUserId: body.endUserId,
262
- }, config, callbacks);
263
- if (result.ok) {
264
- await stream.writeSSE({
265
- event: 'done',
266
- data: JSON.stringify({
267
- sessionId: result.result.sessionId,
268
- completed: result.result.completed,
269
- totalTokens: result.result.totalTokens,
270
- durationMs: result.result.durationMs,
271
- }),
272
- });
273
- }
274
- else {
275
- // Map error codes to appropriate SSE error events
276
- const statusCode = mapErrorCodeToStatus(result.error.code);
277
- const errorData = {
278
- code: result.error.code,
279
- message: result.error.message,
280
- statusCode,
281
- };
282
- if (statusCode === 402 && record.paymentUrl) {
283
- errorData.paymentUrl = record.paymentUrl;
284
- }
285
- await stream.writeSSE({
286
- event: 'error',
287
- data: JSON.stringify(errorData),
288
- });
289
- }
290
- resultSent = true;
291
- }
292
- catch (error) {
293
- if (!resultSent) {
294
- const message = error instanceof Error ? error.message : String(error);
295
- await stream.writeSSE({
296
- event: 'error',
297
- data: JSON.stringify({ code: 'EXECUTION_FAILED', message }),
298
- }).catch(() => { });
299
- }
300
- }
301
- finally {
302
- recordBrokerRequestEnd(record.deploymentId);
303
- }
304
- });
305
- }
306
- // ========== Board Dispatch ==========
307
- function handleBoardInvoke(c, body, record) {
308
- const config = {
309
- deploymentId: record.deploymentId,
310
- aiEnabled: record.aiConfig.aiEnabled,
311
- allowedAiCapabilities: record.capabilities.map((cap) => cap === 'pm-board' ? 'board-execution' : cap),
312
- allowedBoardTemplateIds: record.aiConfig.allowedBoardTemplateIds,
313
- maxConcurrentBoardExecutions: record.aiConfig.maxConcurrentBoardExecutions,
314
- maxBoardExecutionsPerMinute: record.aiConfig.maxBoardExecutionsPerMinute,
315
- defaultModel: record.aiConfig.defaultModel,
316
- workingDir: record.aiConfig.workingDir,
317
- };
318
- const result = startBoardExecution({
319
- boardTemplateId: body.boardTemplateId,
320
- endUserPrompt: body.prompt,
321
- endUserId: body.endUserId,
322
- deploymentId: body.deploymentId,
323
- }, config);
324
- if (!result.ok) {
325
- const statusCode = mapErrorCodeToStatus(result.error.code);
326
- const body = { error: result.error.message, code: result.error.code };
327
- if (statusCode === 402 && record.paymentUrl) {
328
- body.paymentUrl = record.paymentUrl;
329
- }
330
- return c.json(body, statusCode);
331
- }
332
- // Construct polling URL relative to the request
333
- const host = c.req.header('Host') || 'localhost';
334
- const protocol = c.req.header('X-Forwarded-Proto') || 'http';
335
- const statusUrl = `${protocol}://${host}/api/deploy/ai/jobs/${result.jobId}`;
336
- return c.json({
337
- jobId: result.jobId,
338
- statusUrl,
339
- }, 202);
340
- }
341
- // ========== Error Mapping ==========
342
- function mapErrorCodeToStatus(code) {
343
- switch (code) {
344
- case 'CAPABILITY_DENIED':
345
- case 'AI_DISABLED':
346
- return 403;
347
- case 'RATE_LIMIT_EXCEEDED':
348
- case 'CONCURRENT_LIMIT_EXCEEDED':
349
- return 429;
350
- case 'INVALID_REQUEST':
351
- case 'INVALID_BOARD_TEMPLATE':
352
- case 'BOARD_TEMPLATE_NOT_FOUND':
353
- return 400;
354
- case 'PAYMENT_REQUIRED':
355
- return 402;
356
- default:
357
- return 500;
358
- }
359
- }
360
- //# sourceMappingURL=ai-broker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai-broker.js","sourceRoot":"","sources":["../../../../server/services/deploy/ai-broker.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gEAAgE;AAEhE;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAgB,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAEL,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAIL,qBAAqB,GAEtB,MAAM,+BAA+B,CAAC;AAuCvC,oCAAoC;AAEpC;;;;GAIG;AACH,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;AAExD,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,YAAoB;IACxD,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,YAAoB;IACvD,OAAO,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAoB,EACpB,OAKC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,IAAI,OAAO,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,CAAC,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IACzE,CAAC;IACD,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,CAAC,QAAQ,CAAC,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACpE,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,IAAI,mBAAmB,GAA+B,IAAI,CAAC;AAC3D,IAAI,oBAAoB,GAAgC,IAAI,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,QAA6B;IACxE,mBAAmB,GAAG,QAAQ,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAA8B;IAC1E,oBAAoB,GAAG,QAAQ,CAAC;AAClC,CAAC;AAED,yCAAyC;AAEzC,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,kBAAkB,CAAC,UAA8B;IACxD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,QAAgB,EAChB,YAAoB;IAEpB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,YAAY,KAAK,MAAM,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAEnD,OAAO,MAAM,CAAC;AAChB,CAAC;AASD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE9D,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAC/C,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,MAAwB;IAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IACzC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC;QAC3E,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAyB;IAEzB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;QACpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,CAAC,oBAAoB,KAAK,IAAI,EAAE,CAAC;QACnD,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC;YACtE,yDAAyD;YACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC;QACxE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,wBAAwB,CAAC,YAAoB;IACpD,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,cAAc,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;AACjE,CAAC;AAQD,SAAS,YAAY,CAAC,IAAwB;IAC5C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9E,OAAO,sEAAsE,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACrE,OAAO,sDAAsD,CAAC;IAChE,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5D,OAAO,2DAA2D,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,sBAAsB,CAC7B,QAAgB,EAChB,IAAwB;IAExB,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iDAAiD,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,IAAI,CAAC,UAAU,sCAAsC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACjH,CAAC;IAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;QAC3E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,uCAAuC;YAC9C,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,EAAE;SAClD,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,sCAAsC;AAEtC,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;IAE1B,8DAA8D;IAE9D,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4EAA4E,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9G,CAAC;QAED,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAsB,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,EAC3B,EAAE,MAAM,EAAE,UAAU,CAAC,MAAa,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAClE,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAE9D,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;QAC/B,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,SAAS,IAAI,SAAS,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0CAA0C;AAE1C,KAAK,UAAU,oBAAoB,CACjC,CAAU,EACV,IAAwB,EACxB,MAAyB;IAEzB,MAAM,MAAM,GAAuB;QACjC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;QACpC,qBAAqB,EAAE,MAAM,CAAC,YAAY;QAC1C,mBAAmB,EAAE,MAAM,CAAC,QAAQ,CAAC,mBAAmB;QACxD,oBAAoB,EAAE,MAAM,CAAC,SAAS,CAAC,oBAAoB;QAC3D,qBAAqB,EAAE,MAAM,CAAC,SAAS,CAAC,qBAAqB;QAC7D,mBAAmB,EAAE,MAAM,CAAC,QAAQ,CAAC,mBAAmB;QACxD,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY;QAC1C,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU;KACvC,CAAC;IAEF,wBAAwB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAE9C,wCAAwC;IACxC,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,SAAS,GAAmC;YAChD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjB,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnE,CAAC;YACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnB,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;gBACnB,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACtF,CAAC;YACD,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE;gBACxB,mBAAmB,EAAE,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YACD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE;gBACzB,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC;YACjC,CAAC;SACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CACxC;gBACE,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,EACD,MAAM,EACN,SAAS,CACV,CAAC;YAEF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACd,MAAM,MAAM,CAAC,QAAQ,CAAC;oBACpB,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS;wBAClC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS;wBAClC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW;wBACtC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;qBACrC,CAAC;iBACH,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,kDAAkD;gBAClD,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3D,MAAM,SAAS,GAA4B;oBACzC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;oBACvB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;oBAC7B,UAAU;iBACX,CAAC;gBACF,IAAI,UAAU,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBAC5C,SAAS,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;gBAC3C,CAAC;gBACD,MAAM,MAAM,CAAC,QAAQ,CAAC;oBACpB,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;iBAChC,CAAC,CAAC;YACL,CAAC;YACD,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,MAAM,MAAM,CAAC,QAAQ,CAAC;oBACpB,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC;iBAC5D,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,sBAAsB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uCAAuC;AAEvC,SAAS,iBAAiB,CACxB,CAAU,EACV,IAAwB,EACxB,MAAyB;IAEzB,MAAM,MAAM,GAAyB;QACnC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;QACpC,qBAAqB,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACrD,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAC7C;QACD,uBAAuB,EAAE,MAAM,CAAC,QAAQ,CAAC,uBAAuB;QAChE,4BAA4B,EAAE,MAAM,CAAC,QAAQ,CAAC,4BAA4B;QAC1E,2BAA2B,EAAE,MAAM,CAAC,QAAQ,CAAC,2BAA2B;QACxE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY;QAC1C,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU;KACvC,CAAC;IAEF,MAAM,MAAM,GAAG,mBAAmB,CAChC;QACE,eAAe,EAAE,IAAI,CAAC,eAAgB;QACtC,aAAa,EAAE,IAAI,CAAC,MAAM;QAC1B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,EACD,MAAM,CACP,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,IAAI,GAA4B,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC/F,IAAI,UAAU,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACtC,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,UAAiB,CAAC,CAAC;IACzC,CAAC;IAED,gDAAgD;IAChD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC;IAC7D,MAAM,SAAS,GAAG,GAAG,QAAQ,MAAM,IAAI,uBAAuB,MAAM,CAAC,KAAK,EAAE,CAAC;IAE7E,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS;KACV,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,sCAAsC;AAEtC,SAAS,oBAAoB,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,mBAAmB,CAAC;QACzB,KAAK,aAAa;YAChB,OAAO,GAAG,CAAC;QACb,KAAK,qBAAqB,CAAC;QAC3B,KAAK,2BAA2B;YAC9B,OAAO,GAAG,CAAC;QACb,KAAK,iBAAiB,CAAC;QACvB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,0BAA0B;YAC7B,OAAO,GAAG,CAAC;QACb,KAAK,kBAAkB;YACrB,OAAO,GAAG,CAAC;QACb;YACE,OAAO,GAAG,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,114 +0,0 @@
1
- /**
2
- * Sanitize an end-user prompt before passing it to the AI.
3
- *
4
- * SECURITY: End-user prompts are untrusted. This function:
5
- * 1. Strips system instruction XML delimiters to prevent prompt escape
6
- * 2. Removes null bytes and zero-width characters used for evasion
7
- * 3. Truncates to MAX_END_USER_PROMPT_LENGTH
8
- *
9
- * Note: This does NOT strip tool-use instructions or path traversal text —
10
- * those are handled by the Security Bouncer (tool execution level) and
11
- * the isolated working directory (filesystem level).
12
- */
13
- export declare function sanitizeEndUserPrompt(prompt: string): string;
14
- export interface BoardExecutionRequest {
15
- /** Board template to execute (must be in deployment's allowedBoardTemplateIds) */
16
- boardTemplateId: string;
17
- /** The end user's prompt (untrusted input) */
18
- endUserPrompt: string;
19
- /** Unique identifier for the end user (for isolation + rate tracking) */
20
- endUserId: string;
21
- /** Deployment that owns this execution */
22
- deploymentId: string;
23
- }
24
- export interface BoardExecutionConfig {
25
- deploymentId: string;
26
- aiEnabled: boolean;
27
- allowedAiCapabilities: string[];
28
- /** Board template IDs this deployment is allowed to execute */
29
- allowedBoardTemplateIds: string[];
30
- /** Max concurrent board executions per deployment */
31
- maxConcurrentBoardExecutions: number;
32
- /** Max board executions per minute (null = unlimited) */
33
- maxBoardExecutionsPerMinute: number | null;
34
- defaultModel: string;
35
- workingDir: string;
36
- }
37
- export type BoardExecutionErrorCode = 'CAPABILITY_DENIED' | 'AI_DISABLED' | 'INVALID_BOARD_TEMPLATE' | 'BOARD_TEMPLATE_NOT_FOUND' | 'RATE_LIMIT_EXCEEDED' | 'CONCURRENT_LIMIT_EXCEEDED' | 'INVALID_REQUEST' | 'EXECUTION_FAILED';
38
- export interface BoardExecutionError {
39
- code: BoardExecutionErrorCode;
40
- message: string;
41
- }
42
- export type BoardExecutionJobStatus = 'customizing' | 'executing' | 'completed' | 'failed' | 'cancelled';
43
- export interface BoardExecutionProgress {
44
- phase: 'isolating' | 'customizing' | 'executing' | 'collecting' | 'done';
45
- issuesTotal: number;
46
- issuesCompleted: number;
47
- currentWaveIds: string[];
48
- }
49
- export interface BoardExecutionJobResult {
50
- completed: boolean;
51
- issuesTotal: number;
52
- issuesCompleted: number;
53
- issuesFailed: number;
54
- /** Output artifact contents keyed by filename */
55
- outputs: Record<string, string>;
56
- durationMs: number;
57
- }
58
- export interface BoardExecutionStatusResult {
59
- jobId: string;
60
- status: BoardExecutionJobStatus;
61
- progress: BoardExecutionProgress;
62
- result: BoardExecutionJobResult | null;
63
- error: string | null;
64
- }
65
- export type StartBoardExecutionResult = {
66
- ok: true;
67
- jobId: string;
68
- } | {
69
- ok: false;
70
- error: BoardExecutionError;
71
- };
72
- /**
73
- * Start a board execution for an end user. Returns a job ID immediately.
74
- * The execution runs asynchronously — poll with getBoardExecutionStatus().
75
- *
76
- * Validates the deployment config, checks rate limits, verifies the board
77
- * template exists and is allowed, then launches the background execution.
78
- *
79
- * @returns Structured result with either the job ID or an error.
80
- */
81
- export declare function startBoardExecution(request: BoardExecutionRequest, config: BoardExecutionConfig): StartBoardExecutionResult;
82
- /**
83
- * Get the current status of a board execution job.
84
- *
85
- * Optionally pass endUserId to enforce isolation — returns null if the
86
- * job belongs to a different end user.
87
- *
88
- * @returns Job status or null if not found / access denied.
89
- */
90
- export declare function getBoardExecutionStatus(jobId: string, endUserId?: string): BoardExecutionStatusResult | null;
91
- /**
92
- * Get the current rate limit state for a deployment's board executions.
93
- * Useful for status/monitoring endpoints.
94
- */
95
- export declare function getDeploymentBoardExecutionState(deploymentId: string): {
96
- executionsInLastMinute: number;
97
- activeExecutions: number;
98
- };
99
- /**
100
- * Reset rate limit state for a deployment's board executions.
101
- * Call when a deployment is deleted.
102
- */
103
- export declare function resetDeploymentBoardExecutionRateLimit(deploymentId: string): void;
104
- /**
105
- * Sweep stale isolated directories left behind by crashed executions.
106
- *
107
- * Board execution creates temp dirs prefixed with 'mstro-board-exec-'.
108
- * If the process crashes before cleanup, these dirs leak. This function
109
- * removes any that are older than the retention window + buffer.
110
- *
111
- * Safe to call on startup or periodically.
112
- */
113
- export declare function sweepStaleIsolatedDirs(): number;
114
- //# sourceMappingURL=board-execution-handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"board-execution-handler.d.ts","sourceRoot":"","sources":["../../../../server/services/deploy/board-execution-handler.ts"],"names":[],"mappings":"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"}