mstro-app 0.4.21 → 0.4.24

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 (167) hide show
  1. package/README.md +66 -0
  2. package/dist/server/cli/headless/claude-invoker-process.js +1 -1
  3. package/dist/server/cli/headless/claude-invoker-process.js.map +1 -1
  4. package/dist/server/cli/headless/mcp-config.d.ts +1 -1
  5. package/dist/server/cli/headless/mcp-config.d.ts.map +1 -1
  6. package/dist/server/cli/headless/mcp-config.js +4 -1
  7. package/dist/server/cli/headless/mcp-config.js.map +1 -1
  8. package/dist/server/cli/headless/runner.d.ts.map +1 -1
  9. package/dist/server/cli/headless/runner.js +1 -0
  10. package/dist/server/cli/headless/runner.js.map +1 -1
  11. package/dist/server/cli/headless/types.d.ts +4 -1
  12. package/dist/server/cli/headless/types.d.ts.map +1 -1
  13. package/dist/server/index.js +9 -1
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
  16. package/dist/server/mcp/bouncer-integration.js +9 -1
  17. package/dist/server/mcp/bouncer-integration.js.map +1 -1
  18. package/dist/server/mcp/security-analysis.d.ts +6 -0
  19. package/dist/server/mcp/security-analysis.d.ts.map +1 -1
  20. package/dist/server/mcp/security-analysis.js +16 -1
  21. package/dist/server/mcp/security-analysis.js.map +1 -1
  22. package/dist/server/mcp/security-patterns.d.ts +8 -0
  23. package/dist/server/mcp/security-patterns.d.ts.map +1 -1
  24. package/dist/server/mcp/security-patterns.js +47 -2
  25. package/dist/server/mcp/security-patterns.js.map +1 -1
  26. package/dist/server/services/deploy/ai-broker.d.ts +63 -0
  27. package/dist/server/services/deploy/ai-broker.d.ts.map +1 -0
  28. package/dist/server/services/deploy/ai-broker.js +360 -0
  29. package/dist/server/services/deploy/ai-broker.js.map +1 -0
  30. package/dist/server/services/deploy/board-execution-handler.d.ts +114 -0
  31. package/dist/server/services/deploy/board-execution-handler.d.ts.map +1 -0
  32. package/dist/server/services/deploy/board-execution-handler.js +621 -0
  33. package/dist/server/services/deploy/board-execution-handler.js.map +1 -0
  34. package/dist/server/services/deploy/credentials.d.ts +35 -0
  35. package/dist/server/services/deploy/credentials.d.ts.map +1 -0
  36. package/dist/server/services/deploy/credentials.js +177 -0
  37. package/dist/server/services/deploy/credentials.js.map +1 -0
  38. package/dist/server/services/deploy/deploy-ai-service.d.ts +107 -0
  39. package/dist/server/services/deploy/deploy-ai-service.d.ts.map +1 -0
  40. package/dist/server/services/deploy/deploy-ai-service.js +294 -0
  41. package/dist/server/services/deploy/deploy-ai-service.js.map +1 -0
  42. package/dist/server/services/deploy/headless-session-handler.d.ts +94 -0
  43. package/dist/server/services/deploy/headless-session-handler.d.ts.map +1 -0
  44. package/dist/server/services/deploy/headless-session-handler.js +274 -0
  45. package/dist/server/services/deploy/headless-session-handler.js.map +1 -0
  46. package/dist/server/services/file-explorer-ops.d.ts.map +1 -1
  47. package/dist/server/services/file-explorer-ops.js +2 -6
  48. package/dist/server/services/file-explorer-ops.js.map +1 -1
  49. package/dist/server/services/plan/agent-loader.d.ts +10 -0
  50. package/dist/server/services/plan/agent-loader.d.ts.map +1 -0
  51. package/dist/server/services/plan/agent-loader.js +65 -0
  52. package/dist/server/services/plan/agent-loader.js.map +1 -0
  53. package/dist/server/services/plan/composer.js +1 -1
  54. package/dist/server/services/plan/dependency-resolver.d.ts +1 -1
  55. package/dist/server/services/plan/dependency-resolver.js +2 -2
  56. package/dist/server/services/plan/dependency-resolver.js.map +1 -1
  57. package/dist/server/services/plan/executor.d.ts +6 -2
  58. package/dist/server/services/plan/executor.d.ts.map +1 -1
  59. package/dist/server/services/plan/executor.js +21 -6
  60. package/dist/server/services/plan/executor.js.map +1 -1
  61. package/dist/server/services/plan/front-matter.d.ts +5 -0
  62. package/dist/server/services/plan/front-matter.d.ts.map +1 -1
  63. package/dist/server/services/plan/front-matter.js +19 -0
  64. package/dist/server/services/plan/front-matter.js.map +1 -1
  65. package/dist/server/services/plan/issue-prompt-builder.d.ts +1 -1
  66. package/dist/server/services/plan/issue-prompt-builder.d.ts.map +1 -1
  67. package/dist/server/services/plan/issue-prompt-builder.js +1 -1
  68. package/dist/server/services/plan/issue-retry.d.ts +2 -0
  69. package/dist/server/services/plan/issue-retry.d.ts.map +1 -1
  70. package/dist/server/services/plan/issue-retry.js +1 -0
  71. package/dist/server/services/plan/issue-retry.js.map +1 -1
  72. package/dist/server/services/plan/output-manager.d.ts +2 -2
  73. package/dist/server/services/plan/output-manager.js +2 -2
  74. package/dist/server/services/plan/parser-core.d.ts +1 -1
  75. package/dist/server/services/plan/parser-core.js +1 -1
  76. package/dist/server/services/plan/parser-core.js.map +1 -1
  77. package/dist/server/services/plan/parser-migration.d.ts +2 -2
  78. package/dist/server/services/plan/parser-migration.d.ts.map +1 -1
  79. package/dist/server/services/plan/parser-migration.js +5 -5
  80. package/dist/server/services/plan/parser-migration.js.map +1 -1
  81. package/dist/server/services/plan/parser.d.ts.map +1 -1
  82. package/dist/server/services/plan/parser.js +4 -7
  83. package/dist/server/services/plan/parser.js.map +1 -1
  84. package/dist/server/services/plan/prompt-builder.d.ts +1 -1
  85. package/dist/server/services/plan/prompt-builder.d.ts.map +1 -1
  86. package/dist/server/services/plan/review-gate.d.ts +4 -0
  87. package/dist/server/services/plan/review-gate.d.ts.map +1 -1
  88. package/dist/server/services/plan/review-gate.js +89 -34
  89. package/dist/server/services/plan/review-gate.js.map +1 -1
  90. package/dist/server/services/plan/state-reconciler.d.ts.map +1 -1
  91. package/dist/server/services/plan/state-reconciler.js +21 -11
  92. package/dist/server/services/plan/state-reconciler.js.map +1 -1
  93. package/dist/server/services/plan/types.d.ts +2 -2
  94. package/dist/server/services/plan/types.d.ts.map +1 -1
  95. package/dist/server/services/plan/watcher.js +1 -1
  96. package/dist/server/services/sentry.d.ts.map +1 -1
  97. package/dist/server/services/sentry.js +8 -4
  98. package/dist/server/services/sentry.js.map +1 -1
  99. package/dist/server/services/websocket/deploy-handlers.d.ts +14 -0
  100. package/dist/server/services/websocket/deploy-handlers.d.ts.map +1 -0
  101. package/dist/server/services/websocket/deploy-handlers.js +409 -0
  102. package/dist/server/services/websocket/deploy-handlers.js.map +1 -0
  103. package/dist/server/services/websocket/handler.d.ts.map +1 -1
  104. package/dist/server/services/websocket/handler.js +4 -0
  105. package/dist/server/services/websocket/handler.js.map +1 -1
  106. package/dist/server/services/websocket/handlers/deploy-handlers.d.ts +11 -0
  107. package/dist/server/services/websocket/handlers/deploy-handlers.d.ts.map +1 -0
  108. package/dist/server/services/websocket/handlers/deploy-handlers.js +181 -0
  109. package/dist/server/services/websocket/handlers/deploy-handlers.js.map +1 -0
  110. package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -1
  111. package/dist/server/services/websocket/plan-board-handlers.js +54 -1
  112. package/dist/server/services/websocket/plan-board-handlers.js.map +1 -1
  113. package/dist/server/services/websocket/plan-helpers.d.ts +1 -1
  114. package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -1
  115. package/dist/server/services/websocket/plan-helpers.js +3 -4
  116. package/dist/server/services/websocket/plan-helpers.js.map +1 -1
  117. package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -1
  118. package/dist/server/services/websocket/plan-issue-handlers.js +5 -1
  119. package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -1
  120. package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -1
  121. package/dist/server/services/websocket/plan-sprint-handlers.js +3 -11
  122. package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -1
  123. package/dist/server/services/websocket/types.d.ts +264 -2
  124. package/dist/server/services/websocket/types.d.ts.map +1 -1
  125. package/package.json +1 -1
  126. package/server/cli/headless/claude-invoker-process.ts +1 -1
  127. package/server/cli/headless/mcp-config.ts +4 -1
  128. package/server/cli/headless/runner.ts +1 -0
  129. package/server/cli/headless/types.ts +4 -1
  130. package/server/index.ts +9 -1
  131. package/server/mcp/bouncer-integration.ts +9 -1
  132. package/server/mcp/security-analysis.ts +19 -0
  133. package/server/mcp/security-patterns.ts +53 -2
  134. package/server/services/deploy/ai-broker.ts +512 -0
  135. package/server/services/deploy/board-execution-handler.ts +847 -0
  136. package/server/services/deploy/credentials.ts +200 -0
  137. package/server/services/deploy/deploy-ai-service.ts +401 -0
  138. package/server/services/deploy/headless-session-handler.ts +415 -0
  139. package/server/services/file-explorer-ops.ts +2 -6
  140. package/server/services/plan/agent-loader.ts +73 -0
  141. package/server/services/plan/agents/review-code.md +28 -0
  142. package/server/services/plan/agents/review-custom.md +27 -0
  143. package/server/services/plan/agents/review-quality.md +42 -0
  144. package/server/services/plan/composer.ts +1 -1
  145. package/server/services/plan/dependency-resolver.ts +2 -2
  146. package/server/services/plan/executor.ts +21 -6
  147. package/server/services/plan/front-matter.ts +23 -0
  148. package/server/services/plan/issue-prompt-builder.ts +2 -2
  149. package/server/services/plan/issue-retry.ts +3 -0
  150. package/server/services/plan/output-manager.ts +2 -2
  151. package/server/services/plan/parser-core.ts +2 -2
  152. package/server/services/plan/parser-migration.ts +5 -5
  153. package/server/services/plan/parser.ts +4 -5
  154. package/server/services/plan/prompt-builder.ts +1 -1
  155. package/server/services/plan/review-gate.ts +104 -33
  156. package/server/services/plan/state-reconciler.ts +21 -11
  157. package/server/services/plan/types.ts +3 -3
  158. package/server/services/plan/watcher.ts +1 -1
  159. package/server/services/sentry.ts +8 -4
  160. package/server/services/websocket/deploy-handlers.ts +544 -0
  161. package/server/services/websocket/handler.ts +5 -1
  162. package/server/services/websocket/handlers/deploy-handlers.ts +231 -0
  163. package/server/services/websocket/plan-board-handlers.ts +53 -1
  164. package/server/services/websocket/plan-helpers.ts +3 -4
  165. package/server/services/websocket/plan-issue-handlers.ts +6 -1
  166. package/server/services/websocket/plan-sprint-handlers.ts +3 -9
  167. package/server/services/websocket/types.ts +333 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-execution-handler.d.ts","sourceRoot":"","sources":["../../../../server/services/deploy/board-execution-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,621 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * Board Execution Handler
5
+ *
6
+ * Handles PM Board execution requests from a developer's backend on behalf
7
+ * of end users. Each execution is isolated — no shared context between
8
+ * end users.
9
+ *
10
+ * Flow:
11
+ * 1. Validate boardTemplateId against deployment's allowedBoardTemplateIds
12
+ * 2. Load the referenced board template from .mstro/pm/boards/
13
+ * 3. Create an isolated working directory (git worktree)
14
+ * 4. Use headless Claude Code to customize the board from end-user prompt
15
+ * 5. Trigger PM Board "implement all" execution via PlanExecutor
16
+ * 6. Collect results and return them
17
+ *
18
+ * Board executions are long-running — returns a job ID immediately with
19
+ * polling for status and results.
20
+ *
21
+ * Security: End-user prompts are untrusted input. They are always passed
22
+ * as user messages, never injected into system instructions.
23
+ */
24
+ import { execSync } from 'node:child_process';
25
+ import { randomUUID } from 'node:crypto';
26
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync } from 'node:fs';
27
+ import { tmpdir } from 'node:os';
28
+ import { join } from 'node:path';
29
+ import { HeadlessRunner } from '../../cli/headless/runner.js';
30
+ import { PlanExecutor } from '../plan/executor.js';
31
+ import { parseBoardDirectory, resolvePmDir } from '../plan/parser.js';
32
+ import { readOwnerApiCredential } from './deploy-ai-service.js';
33
+ // ========== Prompt Sanitization ==========
34
+ /**
35
+ * Maximum allowed length for an end-user prompt.
36
+ * Prevents memory abuse and ensures reasonable prompt sizes.
37
+ */
38
+ const MAX_END_USER_PROMPT_LENGTH = 100_000;
39
+ /**
40
+ * Sanitize an end-user prompt before passing it to the AI.
41
+ *
42
+ * SECURITY: End-user prompts are untrusted. This function:
43
+ * 1. Strips system instruction XML delimiters to prevent prompt escape
44
+ * 2. Removes null bytes and zero-width characters used for evasion
45
+ * 3. Truncates to MAX_END_USER_PROMPT_LENGTH
46
+ *
47
+ * Note: This does NOT strip tool-use instructions or path traversal text —
48
+ * those are handled by the Security Bouncer (tool execution level) and
49
+ * the isolated working directory (filesystem level).
50
+ */
51
+ export function sanitizeEndUserPrompt(prompt) {
52
+ let sanitized = prompt;
53
+ // Strip system instruction XML tags that could break prompt structure
54
+ sanitized = sanitized.replace(/<\/?system-instruction>/gi, '');
55
+ // Remove null bytes
56
+ sanitized = sanitized.replace(/\x00/g, '');
57
+ // Remove zero-width characters used for evasion
58
+ // U+200B Zero Width Space, U+200C Zero Width Non-Joiner,
59
+ // U+200D Zero Width Joiner, U+FEFF Byte Order Mark
60
+ sanitized = sanitized.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
61
+ // Truncate to max length
62
+ if (sanitized.length > MAX_END_USER_PROMPT_LENGTH) {
63
+ sanitized = sanitized.slice(0, MAX_END_USER_PROMPT_LENGTH);
64
+ }
65
+ return sanitized;
66
+ }
67
+ const rateBuckets = new Map();
68
+ function getBucket(deploymentId) {
69
+ let bucket = rateBuckets.get(deploymentId);
70
+ if (!bucket) {
71
+ bucket = { timestamps: [], activeExecutions: 0 };
72
+ rateBuckets.set(deploymentId, bucket);
73
+ }
74
+ return bucket;
75
+ }
76
+ function pruneTimestamps(bucket) {
77
+ const oneMinuteAgo = Date.now() - 60_000;
78
+ while (bucket.timestamps.length > 0 && bucket.timestamps[0] < oneMinuteAgo) {
79
+ bucket.timestamps.shift();
80
+ }
81
+ }
82
+ function checkRateLimit(config) {
83
+ const bucket = getBucket(config.deploymentId);
84
+ // Check concurrent executions
85
+ if (bucket.activeExecutions >= config.maxConcurrentBoardExecutions) {
86
+ return {
87
+ code: 'CONCURRENT_LIMIT_EXCEEDED',
88
+ message: `Deployment has reached the maximum of ${config.maxConcurrentBoardExecutions} concurrent board executions. Wait for an existing execution to complete.`,
89
+ };
90
+ }
91
+ // Check executions per minute
92
+ if (config.maxBoardExecutionsPerMinute !== null) {
93
+ pruneTimestamps(bucket);
94
+ if (bucket.timestamps.length >= config.maxBoardExecutionsPerMinute) {
95
+ return {
96
+ code: 'RATE_LIMIT_EXCEEDED',
97
+ message: `Deployment has exceeded the rate limit of ${config.maxBoardExecutionsPerMinute} board executions per minute. Try again shortly.`,
98
+ };
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+ function recordExecutionStart(deploymentId) {
104
+ const bucket = getBucket(deploymentId);
105
+ bucket.timestamps.push(Date.now());
106
+ bucket.activeExecutions++;
107
+ }
108
+ function recordExecutionEnd(deploymentId) {
109
+ const bucket = getBucket(deploymentId);
110
+ bucket.activeExecutions = Math.max(0, bucket.activeExecutions - 1);
111
+ }
112
+ // ========== Job Store ==========
113
+ /** Retention window for completed/failed jobs before cleanup (5 minutes) */
114
+ const JOB_RETENTION_MS = 300_000;
115
+ const jobs = new Map();
116
+ function createJob(request) {
117
+ const jobId = `board-exec-${request.deploymentId}-${randomUUID()}`;
118
+ const now = Date.now();
119
+ const job = {
120
+ jobId,
121
+ deploymentId: request.deploymentId,
122
+ endUserId: request.endUserId,
123
+ boardTemplateId: request.boardTemplateId,
124
+ endUserPrompt: request.endUserPrompt,
125
+ status: 'customizing',
126
+ progress: {
127
+ phase: 'isolating',
128
+ issuesTotal: 0,
129
+ issuesCompleted: 0,
130
+ currentWaveIds: [],
131
+ },
132
+ result: null,
133
+ error: null,
134
+ createdAt: now,
135
+ updatedAt: now,
136
+ isolatedDir: null,
137
+ };
138
+ jobs.set(jobId, job);
139
+ return job;
140
+ }
141
+ function updateJob(jobId, updates) {
142
+ const job = jobs.get(jobId);
143
+ if (!job)
144
+ return;
145
+ Object.assign(job, updates, { updatedAt: Date.now() });
146
+ }
147
+ function scheduleJobCleanup(jobId) {
148
+ setTimeout(() => {
149
+ const job = jobs.get(jobId);
150
+ if (job && job.status !== 'customizing' && job.status !== 'executing') {
151
+ if (job.isolatedDir) {
152
+ cleanupIsolatedDir(job.isolatedDir);
153
+ }
154
+ jobs.delete(jobId);
155
+ }
156
+ }, JOB_RETENTION_MS);
157
+ }
158
+ // ========== Isolation ==========
159
+ function isGitRepo(dir) {
160
+ try {
161
+ execSync('git rev-parse --is-inside-work-tree', { cwd: dir, stdio: 'pipe' });
162
+ return true;
163
+ }
164
+ catch {
165
+ return false;
166
+ }
167
+ }
168
+ /**
169
+ * Create an isolated working directory for a board execution.
170
+ *
171
+ * Uses git worktree for git repos (efficient — shares object store).
172
+ * Falls back to a filtered directory copy for non-git repos.
173
+ *
174
+ * .mstro/pm/ is gitignored, so it is always copied manually.
175
+ */
176
+ function createIsolatedDir(workingDir) {
177
+ const prefix = join(tmpdir(), 'mstro-board-exec-');
178
+ if (isGitRepo(workingDir)) {
179
+ const isolatedDir = mkdtempSync(prefix);
180
+ // git worktree needs a non-existent path
181
+ rmSync(isolatedDir, { recursive: true, force: true });
182
+ execSync(`git worktree add --detach "${isolatedDir}"`, {
183
+ cwd: workingDir,
184
+ stdio: 'pipe',
185
+ });
186
+ // .mstro/ is gitignored — copy the PM directory manually
187
+ const pmDir = join(workingDir, '.mstro', 'pm');
188
+ const isolatedPmDir = join(isolatedDir, '.mstro', 'pm');
189
+ if (existsSync(pmDir) && !existsSync(isolatedPmDir)) {
190
+ mkdirSync(join(isolatedDir, '.mstro'), { recursive: true });
191
+ cpSync(pmDir, isolatedPmDir, { recursive: true });
192
+ }
193
+ return isolatedDir;
194
+ }
195
+ // Fallback: filtered directory copy for non-git repos
196
+ const isolatedDir = mkdtempSync(prefix);
197
+ cpSync(workingDir, isolatedDir, {
198
+ recursive: true,
199
+ filter: (src) => !src.includes('node_modules') && !src.includes('.git'),
200
+ });
201
+ return isolatedDir;
202
+ }
203
+ function cleanupIsolatedDir(isolatedDir) {
204
+ try {
205
+ // Try git worktree remove first
206
+ execSync(`git worktree remove --force "${isolatedDir}"`, { stdio: 'pipe' });
207
+ }
208
+ catch {
209
+ // Fallback: direct removal
210
+ try {
211
+ rmSync(isolatedDir, { recursive: true, force: true });
212
+ }
213
+ catch { /* best-effort cleanup */ }
214
+ }
215
+ }
216
+ // ========== Board Template Loading ==========
217
+ function validateBoardTemplate(workingDir, boardTemplateId) {
218
+ const pmDir = resolvePmDir(workingDir);
219
+ if (!pmDir)
220
+ return null;
221
+ const boardState = parseBoardDirectory(pmDir, boardTemplateId);
222
+ if (!boardState)
223
+ return null;
224
+ return {
225
+ issueCount: boardState.issues.filter(i => i.type !== 'epic').length,
226
+ };
227
+ }
228
+ // ========== Board Customization ==========
229
+ /**
230
+ * Build the customization prompt. The system instruction explains the task;
231
+ * the end-user prompt is in a separate, clearly delimited section.
232
+ *
233
+ * SECURITY: The end-user prompt is never interpolated into the system
234
+ * instruction. It appears in the user-message section only.
235
+ */
236
+ function buildCustomizationPrompt(boardTemplateId, endUserPrompt, isolatedDir) {
237
+ const pmDir = resolvePmDir(isolatedDir);
238
+ const boardDir = pmDir ? join(pmDir, 'boards', boardTemplateId) : '';
239
+ const backlogDir = boardDir ? join(boardDir, 'backlog') : '';
240
+ const systemInstruction = `You are customizing a PM Board template for an end user's specific needs.
241
+
242
+ ## Board Template
243
+ Board ID: ${boardTemplateId}
244
+ Board directory: ${boardDir}
245
+ Backlog directory: ${backlogDir}
246
+
247
+ ## Task
248
+
249
+ Read all issue files in the board's backlog directory. Then adapt every issue to fulfill the end user's request below. For each issue:
250
+
251
+ 1. Update the description to be specific to the end user's needs
252
+ 2. Update acceptance criteria to match their requirements
253
+ 3. Update technical notes with relevant implementation details
254
+ 4. Update "Files to Modify" if applicable
255
+ 5. Preserve all YAML front matter fields (id, type, status, priority, blocked_by, etc.)
256
+ 6. Do NOT change issue IDs, dependency edges, or the overall board structure
257
+
258
+ If issues need to be added or removed to properly serve the end user's request, you may do so — but preserve the dependency graph's integrity.
259
+
260
+ ## Rules
261
+
262
+ - All changes must be within ${backlogDir}
263
+ - Preserve YAML front matter structure exactly
264
+ - Keep issue scoping appropriate (1-5 story points each)
265
+ - Ensure blocked_by references remain valid
266
+ - Do NOT modify board.md, STATE.md, or any files outside the backlog
267
+ - Respond briefly describing what you changed`;
268
+ return [
269
+ '<system-instruction>',
270
+ systemInstruction,
271
+ '</system-instruction>',
272
+ '',
273
+ endUserPrompt,
274
+ ].join('\n');
275
+ }
276
+ /**
277
+ * Customize a board template via headless Claude Code session.
278
+ * Claude reads the board's issues and adapts them for the end user's prompt.
279
+ */
280
+ async function customizeBoard(boardTemplateId, endUserPrompt, isolatedDir, apiKey) {
281
+ const prompt = buildCustomizationPrompt(boardTemplateId, endUserPrompt, isolatedDir);
282
+ const runner = new HeadlessRunner({
283
+ workingDir: isolatedDir,
284
+ directPrompt: prompt,
285
+ stallWarningMs: 300_000, // 5 min
286
+ stallKillMs: 900_000, // 15 min
287
+ stallHardCapMs: 1_800_000, // 30 min hard cap
288
+ extraEnv: { ANTHROPIC_API_KEY: apiKey },
289
+ verbose: false,
290
+ deployMode: true, // Activate deploy-specific bouncer patterns
291
+ });
292
+ const result = await runner.run();
293
+ return { completed: result.completed, error: result.error };
294
+ }
295
+ // ========== Board Execution ==========
296
+ /**
297
+ * Run the full board execution ("implement all") via PlanExecutor.
298
+ * Listens to executor events to track progress on the parent job.
299
+ */
300
+ async function executeBoard(boardTemplateId, isolatedDir, job, apiKey) {
301
+ const startTime = Date.now();
302
+ const executor = new PlanExecutor(isolatedDir, {
303
+ extraEnv: { ANTHROPIC_API_KEY: apiKey },
304
+ });
305
+ // Track progress via executor events
306
+ executor.on('waveStarted', (data) => {
307
+ const current = jobs.get(job.jobId);
308
+ if (current) {
309
+ updateJob(job.jobId, {
310
+ progress: { ...current.progress, currentWaveIds: data.issueIds },
311
+ });
312
+ }
313
+ });
314
+ executor.on('issueCompleted', () => {
315
+ const current = jobs.get(job.jobId);
316
+ if (current) {
317
+ updateJob(job.jobId, {
318
+ progress: {
319
+ ...current.progress,
320
+ issuesCompleted: current.progress.issuesCompleted + 1,
321
+ currentWaveIds: [],
322
+ },
323
+ });
324
+ }
325
+ });
326
+ await executor.startBoard(boardTemplateId);
327
+ // Collect output artifacts
328
+ const outputs = collectOutputs(isolatedDir, boardTemplateId);
329
+ const metrics = executor.getMetrics();
330
+ return {
331
+ completed: executor.getStatus() === 'complete',
332
+ issuesTotal: metrics.issuesAttempted,
333
+ issuesCompleted: metrics.issuesCompleted,
334
+ issuesFailed: metrics.issuesAttempted - metrics.issuesCompleted,
335
+ outputs,
336
+ durationMs: Date.now() - startTime,
337
+ };
338
+ }
339
+ // ========== Result Collection ==========
340
+ function collectOutputs(isolatedDir, boardTemplateId) {
341
+ const pmDir = resolvePmDir(isolatedDir);
342
+ if (!pmDir)
343
+ return {};
344
+ const outDir = join(pmDir, 'boards', boardTemplateId, 'out');
345
+ if (!existsSync(outDir))
346
+ return {};
347
+ const outputs = {};
348
+ try {
349
+ for (const file of readdirSync(outDir)) {
350
+ if (file.endsWith('.md')) {
351
+ outputs[file] = readFileSync(join(outDir, file), 'utf-8');
352
+ }
353
+ }
354
+ }
355
+ catch { /* non-fatal */ }
356
+ return outputs;
357
+ }
358
+ // ========== Background Execution ==========
359
+ /**
360
+ * Orchestrates the full board execution lifecycle. Updates job state
361
+ * as it progresses through isolation, customization, execution, and
362
+ * result collection phases.
363
+ */
364
+ async function runBoardExecution(job, config, apiKey) {
365
+ try {
366
+ // Phase 1: Create isolated working directory
367
+ updateJob(job.jobId, {
368
+ progress: { ...job.progress, phase: 'isolating' },
369
+ });
370
+ let isolatedDir;
371
+ try {
372
+ isolatedDir = createIsolatedDir(config.workingDir);
373
+ }
374
+ catch (error) {
375
+ const message = error instanceof Error ? error.message : String(error);
376
+ updateJob(job.jobId, {
377
+ status: 'failed',
378
+ error: `Failed to create isolated directory: ${message}`,
379
+ });
380
+ return;
381
+ }
382
+ updateJob(job.jobId, { isolatedDir });
383
+ // Phase 2: Customize board via headless Claude Code
384
+ updateJob(job.jobId, {
385
+ status: 'customizing',
386
+ progress: { ...job.progress, phase: 'customizing' },
387
+ });
388
+ const customization = await customizeBoard(job.boardTemplateId, sanitizeEndUserPrompt(job.endUserPrompt), isolatedDir, apiKey);
389
+ if (!customization.completed) {
390
+ updateJob(job.jobId, {
391
+ status: 'failed',
392
+ error: `Board customization failed: ${customization.error || 'Unknown error'}`,
393
+ });
394
+ return;
395
+ }
396
+ // Phase 3: Execute board ("implement all")
397
+ updateJob(job.jobId, {
398
+ status: 'executing',
399
+ progress: { ...job.progress, phase: 'executing' },
400
+ });
401
+ const result = await executeBoard(job.boardTemplateId, isolatedDir, job, apiKey);
402
+ // Phase 4: Store results
403
+ updateJob(job.jobId, {
404
+ status: result.completed ? 'completed' : 'failed',
405
+ progress: {
406
+ phase: 'done',
407
+ issuesTotal: result.issuesTotal,
408
+ issuesCompleted: result.issuesCompleted,
409
+ currentWaveIds: [],
410
+ },
411
+ result,
412
+ error: result.completed ? null : 'Board execution did not complete all issues',
413
+ });
414
+ }
415
+ catch (error) {
416
+ const message = error instanceof Error ? error.message : String(error);
417
+ updateJob(job.jobId, {
418
+ status: 'failed',
419
+ error: message,
420
+ });
421
+ }
422
+ finally {
423
+ recordExecutionEnd(job.deploymentId);
424
+ scheduleJobCleanup(job.jobId);
425
+ }
426
+ }
427
+ // ========== Public API ==========
428
+ /**
429
+ * Start a board execution for an end user. Returns a job ID immediately.
430
+ * The execution runs asynchronously — poll with getBoardExecutionStatus().
431
+ *
432
+ * Validates the deployment config, checks rate limits, verifies the board
433
+ * template exists and is allowed, then launches the background execution.
434
+ *
435
+ * @returns Structured result with either the job ID or an error.
436
+ */
437
+ export function startBoardExecution(request, config) {
438
+ // ── Validate request ───────────────────────────────────────
439
+ if (!request.endUserPrompt || request.endUserPrompt.trim().length === 0) {
440
+ return {
441
+ ok: false,
442
+ error: { code: 'INVALID_REQUEST', message: 'endUserPrompt is required and must not be empty.' },
443
+ };
444
+ }
445
+ if (request.endUserPrompt.length > MAX_END_USER_PROMPT_LENGTH) {
446
+ return {
447
+ ok: false,
448
+ error: {
449
+ code: 'INVALID_REQUEST',
450
+ message: `endUserPrompt exceeds the maximum allowed length of ${MAX_END_USER_PROMPT_LENGTH.toLocaleString()} characters.`,
451
+ },
452
+ };
453
+ }
454
+ if (!request.endUserId || request.endUserId.trim().length === 0) {
455
+ return {
456
+ ok: false,
457
+ error: { code: 'INVALID_REQUEST', message: 'endUserId is required.' },
458
+ };
459
+ }
460
+ if (!request.boardTemplateId || request.boardTemplateId.trim().length === 0) {
461
+ return {
462
+ ok: false,
463
+ error: { code: 'INVALID_REQUEST', message: 'boardTemplateId is required.' },
464
+ };
465
+ }
466
+ // ── Validate boardTemplateId format (path traversal defense) ─
467
+ if (/[/\\]|\.\.|\x00/.test(request.boardTemplateId)) {
468
+ return {
469
+ ok: false,
470
+ error: {
471
+ code: 'INVALID_BOARD_TEMPLATE',
472
+ message: 'boardTemplateId contains invalid characters (/, \\, .., or null bytes).',
473
+ },
474
+ };
475
+ }
476
+ // ── Validate AI is enabled ─────────────────────────────────
477
+ if (!config.aiEnabled) {
478
+ return {
479
+ ok: false,
480
+ error: { code: 'AI_DISABLED', message: 'AI features are not enabled for this deployment.' },
481
+ };
482
+ }
483
+ // ── Validate board-execution capability ────────────────────
484
+ if (!config.allowedAiCapabilities.includes('board-execution')) {
485
+ return {
486
+ ok: false,
487
+ error: {
488
+ code: 'CAPABILITY_DENIED',
489
+ message: "This deployment does not have the 'board-execution' AI capability enabled.",
490
+ },
491
+ };
492
+ }
493
+ // ── Validate board template is allowed ─────────────────────
494
+ if (!config.allowedBoardTemplateIds.includes(request.boardTemplateId)) {
495
+ return {
496
+ ok: false,
497
+ error: {
498
+ code: 'INVALID_BOARD_TEMPLATE',
499
+ message: `Board template '${request.boardTemplateId}' is not allowed for this deployment.`,
500
+ },
501
+ };
502
+ }
503
+ // ── Validate board template exists ─────────────────────────
504
+ const template = validateBoardTemplate(config.workingDir, request.boardTemplateId);
505
+ if (!template) {
506
+ return {
507
+ ok: false,
508
+ error: {
509
+ code: 'BOARD_TEMPLATE_NOT_FOUND',
510
+ message: `Board template '${request.boardTemplateId}' not found in project.`,
511
+ },
512
+ };
513
+ }
514
+ // ── Rate limit checks ─────────────────────────────────────
515
+ const rateLimitError = checkRateLimit(config);
516
+ if (rateLimitError) {
517
+ return { ok: false, error: rateLimitError };
518
+ }
519
+ // ── Verify API key ─────────────────────────────────────────
520
+ const credential = readOwnerApiCredential();
521
+ if (!credential || credential.type !== 'api-key') {
522
+ return {
523
+ ok: false,
524
+ error: {
525
+ code: 'EXECUTION_FAILED',
526
+ message: 'Deploy requires an Anthropic API key. Add your key in Deploy \u2192 AI Config or set ANTHROPIC_API_KEY in your environment.',
527
+ },
528
+ };
529
+ }
530
+ // ── Create job and launch background execution ─────────────
531
+ const job = createJob(request);
532
+ job.progress.issuesTotal = template.issueCount;
533
+ recordExecutionStart(config.deploymentId);
534
+ // Fire-and-forget — execution runs in background, errors captured in job
535
+ runBoardExecution(job, config, credential.key).catch(() => { });
536
+ return { ok: true, jobId: job.jobId };
537
+ }
538
+ /**
539
+ * Get the current status of a board execution job.
540
+ *
541
+ * Optionally pass endUserId to enforce isolation — returns null if the
542
+ * job belongs to a different end user.
543
+ *
544
+ * @returns Job status or null if not found / access denied.
545
+ */
546
+ export function getBoardExecutionStatus(jobId, endUserId) {
547
+ const job = jobs.get(jobId);
548
+ if (!job)
549
+ return null;
550
+ // Enforce end-user isolation when endUserId is provided
551
+ if (endUserId !== undefined && job.endUserId !== endUserId) {
552
+ return null;
553
+ }
554
+ return {
555
+ jobId: job.jobId,
556
+ status: job.status,
557
+ progress: { ...job.progress },
558
+ result: job.result,
559
+ error: job.error,
560
+ };
561
+ }
562
+ /**
563
+ * Get the current rate limit state for a deployment's board executions.
564
+ * Useful for status/monitoring endpoints.
565
+ */
566
+ export function getDeploymentBoardExecutionState(deploymentId) {
567
+ const bucket = getBucket(deploymentId);
568
+ pruneTimestamps(bucket);
569
+ return {
570
+ executionsInLastMinute: bucket.timestamps.length,
571
+ activeExecutions: bucket.activeExecutions,
572
+ };
573
+ }
574
+ /**
575
+ * Reset rate limit state for a deployment's board executions.
576
+ * Call when a deployment is deleted.
577
+ */
578
+ export function resetDeploymentBoardExecutionRateLimit(deploymentId) {
579
+ rateBuckets.delete(deploymentId);
580
+ }
581
+ /**
582
+ * Sweep stale isolated directories left behind by crashed executions.
583
+ *
584
+ * Board execution creates temp dirs prefixed with 'mstro-board-exec-'.
585
+ * If the process crashes before cleanup, these dirs leak. This function
586
+ * removes any that are older than the retention window + buffer.
587
+ *
588
+ * Safe to call on startup or periodically.
589
+ */
590
+ export function sweepStaleIsolatedDirs() {
591
+ const prefix = 'mstro-board-exec-';
592
+ const maxAgeMs = JOB_RETENTION_MS * 2; // 10 minutes — generous buffer
593
+ let swept = 0;
594
+ try {
595
+ const tmpDir = tmpdir();
596
+ const entries = readdirSync(tmpDir);
597
+ const now = Date.now();
598
+ for (const entry of entries) {
599
+ if (!entry.startsWith(prefix))
600
+ continue;
601
+ const fullPath = join(tmpDir, entry);
602
+ try {
603
+ // Extract timestamp from dir name: mstro-board-exec-<random>
604
+ // Use filesystem stat for age instead of parsing name
605
+ const { mtimeMs } = statSync(fullPath);
606
+ if (now - mtimeMs > maxAgeMs) {
607
+ cleanupIsolatedDir(fullPath);
608
+ swept++;
609
+ }
610
+ }
611
+ catch {
612
+ // Can't stat or clean — skip
613
+ }
614
+ }
615
+ }
616
+ catch {
617
+ // Can't read tmpdir — skip
618
+ }
619
+ return swept;
620
+ }
621
+ //# sourceMappingURL=board-execution-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-execution-handler.js","sourceRoot":"","sources":["../../../../server/services/deploy/board-execution-handler.ts"],"names":[],"mappings":"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"}