mstro-app 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/LICENSE +191 -21
  2. package/PRIVACY.md +286 -62
  3. package/README.md +81 -58
  4. package/bin/commands/status.js +1 -1
  5. package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
  6. package/dist/server/cli/headless/claude-invoker.js +22 -12
  7. package/dist/server/cli/headless/claude-invoker.js.map +1 -1
  8. package/dist/server/cli/headless/headless-logger.d.ts +10 -0
  9. package/dist/server/cli/headless/headless-logger.d.ts.map +1 -0
  10. package/dist/server/cli/headless/headless-logger.js +66 -0
  11. package/dist/server/cli/headless/headless-logger.js.map +1 -0
  12. package/dist/server/cli/headless/mcp-config.d.ts.map +1 -1
  13. package/dist/server/cli/headless/mcp-config.js +6 -5
  14. package/dist/server/cli/headless/mcp-config.js.map +1 -1
  15. package/dist/server/cli/headless/runner.d.ts.map +1 -1
  16. package/dist/server/cli/headless/runner.js +4 -0
  17. package/dist/server/cli/headless/runner.js.map +1 -1
  18. package/dist/server/cli/headless/stall-assessor.d.ts +21 -0
  19. package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
  20. package/dist/server/cli/headless/stall-assessor.js +100 -24
  21. package/dist/server/cli/headless/stall-assessor.js.map +1 -1
  22. package/dist/server/cli/headless/tool-watchdog.d.ts +0 -12
  23. package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
  24. package/dist/server/cli/headless/tool-watchdog.js +22 -9
  25. package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
  26. package/dist/server/cli/headless/types.d.ts +8 -1
  27. package/dist/server/cli/headless/types.d.ts.map +1 -1
  28. package/dist/server/cli/improvisation-session-manager.d.ts +16 -0
  29. package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
  30. package/dist/server/cli/improvisation-session-manager.js +94 -11
  31. package/dist/server/cli/improvisation-session-manager.js.map +1 -1
  32. package/dist/server/mcp/bouncer-cli.d.ts +3 -0
  33. package/dist/server/mcp/bouncer-cli.d.ts.map +1 -0
  34. package/dist/server/mcp/bouncer-cli.js +54 -0
  35. package/dist/server/mcp/bouncer-cli.js.map +1 -0
  36. package/dist/server/services/plan/composer.d.ts +4 -0
  37. package/dist/server/services/plan/composer.d.ts.map +1 -0
  38. package/dist/server/services/plan/composer.js +181 -0
  39. package/dist/server/services/plan/composer.js.map +1 -0
  40. package/dist/server/services/plan/dependency-resolver.d.ts +28 -0
  41. package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -0
  42. package/dist/server/services/plan/dependency-resolver.js +154 -0
  43. package/dist/server/services/plan/dependency-resolver.js.map +1 -0
  44. package/dist/server/services/plan/executor.d.ts +110 -0
  45. package/dist/server/services/plan/executor.d.ts.map +1 -0
  46. package/dist/server/services/plan/executor.js +641 -0
  47. package/dist/server/services/plan/executor.js.map +1 -0
  48. package/dist/server/services/plan/parser.d.ts +11 -0
  49. package/dist/server/services/plan/parser.d.ts.map +1 -0
  50. package/dist/server/services/plan/parser.js +445 -0
  51. package/dist/server/services/plan/parser.js.map +1 -0
  52. package/dist/server/services/plan/state-reconciler.d.ts +2 -0
  53. package/dist/server/services/plan/state-reconciler.d.ts.map +1 -0
  54. package/dist/server/services/plan/state-reconciler.js +145 -0
  55. package/dist/server/services/plan/state-reconciler.js.map +1 -0
  56. package/dist/server/services/plan/types.d.ts +121 -0
  57. package/dist/server/services/plan/types.d.ts.map +1 -0
  58. package/dist/server/services/plan/types.js +4 -0
  59. package/dist/server/services/plan/types.js.map +1 -0
  60. package/dist/server/services/plan/watcher.d.ts +14 -0
  61. package/dist/server/services/plan/watcher.d.ts.map +1 -0
  62. package/dist/server/services/plan/watcher.js +69 -0
  63. package/dist/server/services/plan/watcher.js.map +1 -0
  64. package/dist/server/services/websocket/file-explorer-handlers.js +20 -0
  65. package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
  66. package/dist/server/services/websocket/handler.d.ts.map +1 -1
  67. package/dist/server/services/websocket/handler.js +21 -0
  68. package/dist/server/services/websocket/handler.js.map +1 -1
  69. package/dist/server/services/websocket/plan-handlers.d.ts +6 -0
  70. package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -0
  71. package/dist/server/services/websocket/plan-handlers.js +494 -0
  72. package/dist/server/services/websocket/plan-handlers.js.map +1 -0
  73. package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
  74. package/dist/server/services/websocket/quality-handlers.js +384 -12
  75. package/dist/server/services/websocket/quality-handlers.js.map +1 -1
  76. package/dist/server/services/websocket/quality-persistence.d.ts +45 -0
  77. package/dist/server/services/websocket/quality-persistence.d.ts.map +1 -0
  78. package/dist/server/services/websocket/quality-persistence.js +187 -0
  79. package/dist/server/services/websocket/quality-persistence.js.map +1 -0
  80. package/dist/server/services/websocket/quality-service.d.ts +12 -2
  81. package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
  82. package/dist/server/services/websocket/quality-service.js +162 -18
  83. package/dist/server/services/websocket/quality-service.js.map +1 -1
  84. package/dist/server/services/websocket/types.d.ts +2 -2
  85. package/dist/server/services/websocket/types.d.ts.map +1 -1
  86. package/package.json +3 -3
  87. package/server/cli/headless/claude-invoker.ts +25 -12
  88. package/server/cli/headless/headless-logger.ts +78 -0
  89. package/server/cli/headless/mcp-config.ts +6 -5
  90. package/server/cli/headless/runner.ts +4 -0
  91. package/server/cli/headless/stall-assessor.ts +131 -24
  92. package/server/cli/headless/tool-watchdog.ts +10 -9
  93. package/server/cli/headless/types.ts +10 -1
  94. package/server/cli/improvisation-session-manager.ts +118 -11
  95. package/server/mcp/bouncer-cli.ts +73 -0
  96. package/server/services/plan/composer.ts +199 -0
  97. package/server/services/plan/dependency-resolver.ts +182 -0
  98. package/server/services/plan/executor.ts +700 -0
  99. package/server/services/plan/parser.ts +491 -0
  100. package/server/services/plan/state-reconciler.ts +174 -0
  101. package/server/services/plan/types.ts +166 -0
  102. package/server/services/plan/watcher.ts +73 -0
  103. package/server/services/websocket/file-explorer-handlers.ts +20 -0
  104. package/server/services/websocket/handler.ts +21 -0
  105. package/server/services/websocket/plan-handlers.ts +592 -0
  106. package/server/services/websocket/quality-handlers.ts +450 -12
  107. package/server/services/websocket/quality-persistence.ts +250 -0
  108. package/server/services/websocket/quality-service.ts +183 -18
  109. package/server/services/websocket/types.ts +48 -2
@@ -0,0 +1,641 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * Plan Executor — Wave-based execution with Claude Code Agent Teams.
5
+ *
6
+ * Reads the dependency DAG from .pm/, picks ALL unblocked issues per wave,
7
+ * spawns a coordinator Claude session that uses Agent Teams to execute them
8
+ * in parallel, then reconciles state and repeats for newly-unblocked issues.
9
+ */
10
+ import { EventEmitter } from 'node:events';
11
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
12
+ import { join, resolve } from 'node:path';
13
+ import { runWithFileLogger } from '../../cli/headless/headless-logger.js';
14
+ import { HeadlessRunner } from '../../cli/headless/index.js';
15
+ import { generateMcpConfig } from '../../cli/headless/mcp-config.js';
16
+ import { resolveReadyToWork } from './dependency-resolver.js';
17
+ import { parsePlanDirectory, resolvePmDir } from './parser.js';
18
+ import { reconcileState } from './state-reconciler.js';
19
+ export class PlanExecutor extends EventEmitter {
20
+ status = 'idle';
21
+ workingDir;
22
+ shouldStop = false;
23
+ shouldPause = false;
24
+ epicScope = null;
25
+ metrics = {
26
+ issuesCompleted: 0,
27
+ issuesAttempted: 0,
28
+ totalDuration: 0,
29
+ currentIssueId: null,
30
+ currentWaveIds: [],
31
+ };
32
+ constructor(workingDir) {
33
+ super();
34
+ this.workingDir = workingDir;
35
+ }
36
+ getStatus() {
37
+ return this.status;
38
+ }
39
+ getMetrics() {
40
+ return { ...this.metrics };
41
+ }
42
+ async startEpic(epicPath) {
43
+ this.epicScope = epicPath;
44
+ return this.start();
45
+ }
46
+ async start() {
47
+ if (this.status === 'executing' || this.status === 'starting')
48
+ return;
49
+ this.shouldStop = false;
50
+ this.shouldPause = false;
51
+ this.status = 'starting';
52
+ this.emit('statusChanged', this.status);
53
+ const startTime = Date.now();
54
+ try {
55
+ this.status = 'executing';
56
+ this.emit('statusChanged', this.status);
57
+ while (!this.shouldStop && !this.shouldPause) {
58
+ const readyIssues = this.pickReadyIssues();
59
+ if (readyIssues.length === 0)
60
+ break;
61
+ // Always use wave execution with Agent Teams — even for single issues.
62
+ // Each teammate runs as a separate process with its own context window,
63
+ // bouncer coverage via .mcp.json + PreToolUse hook, and disk persistence.
64
+ await this.executeWave(readyIssues);
65
+ }
66
+ }
67
+ catch (error) {
68
+ this.status = 'error';
69
+ this.emit('error', error instanceof Error ? error.message : String(error));
70
+ return;
71
+ }
72
+ this.metrics.totalDuration = Date.now() - startTime;
73
+ if (this.shouldPause) {
74
+ this.status = 'paused';
75
+ }
76
+ else if (this.shouldStop) {
77
+ this.status = 'idle';
78
+ }
79
+ else {
80
+ this.status = 'complete';
81
+ }
82
+ this.emit('statusChanged', this.status);
83
+ }
84
+ pause() {
85
+ this.shouldPause = true;
86
+ }
87
+ stop() {
88
+ this.shouldStop = true;
89
+ }
90
+ resume() {
91
+ if (this.status !== 'paused')
92
+ return Promise.resolve();
93
+ this.shouldPause = false;
94
+ return this.start();
95
+ }
96
+ // ── Wave execution (Agent Teams) ──────────────────────────────
97
+ async executeWave(issues) {
98
+ const waveStart = Date.now();
99
+ const waveIds = issues.map(i => i.id);
100
+ this.metrics.currentWaveIds = waveIds;
101
+ this.metrics.issuesAttempted += issues.length;
102
+ this.emit('waveStarted', { issueIds: waveIds });
103
+ // Ensure .pm/out/ exists for execution output
104
+ const pmDir = resolvePmDir(this.workingDir);
105
+ if (pmDir) {
106
+ const outDir = join(pmDir, 'out');
107
+ if (!existsSync(outDir))
108
+ mkdirSync(outDir, { recursive: true });
109
+ }
110
+ // Pre-approve tools so teammates don't hit interactive permission prompts
111
+ this.installTeammatePermissions();
112
+ // Install bouncer .mcp.json so Agent Teams teammates discover it
113
+ this.installBouncerForSubagents();
114
+ // Mark all wave issues as in_progress
115
+ for (const issue of issues) {
116
+ this.updateIssueFrontMatter(issue.path, 'in_progress');
117
+ }
118
+ const prompt = this.buildCoordinatorPrompt(issues);
119
+ try {
120
+ const runner = new HeadlessRunner({
121
+ workingDir: this.workingDir,
122
+ directPrompt: prompt,
123
+ stallKillMs: 3_600_000, // 60 min — waves run longer
124
+ stallHardCapMs: 7_200_000, // 2 hr hard cap
125
+ extraEnv: {
126
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1',
127
+ },
128
+ outputCallback: (text) => {
129
+ this.emit('output', { issueId: `wave[${waveIds.join(',')}]`, text });
130
+ },
131
+ });
132
+ const result = await runWithFileLogger('pm-execute-wave', () => runner.run());
133
+ if (!result.completed || result.error) {
134
+ this.emit('waveError', {
135
+ issueIds: waveIds,
136
+ error: result.error || 'Wave did not complete successfully',
137
+ });
138
+ }
139
+ // Check which issues the agents actually completed by reading disk
140
+ this.reconcileWaveResults(issues);
141
+ }
142
+ catch (error) {
143
+ this.emit('waveError', {
144
+ issueIds: waveIds,
145
+ error: error instanceof Error ? error.message : String(error),
146
+ });
147
+ this.revertIncompleteIssues(issues);
148
+ }
149
+ finally {
150
+ // Clean up temporary configs — must run even if wave throws
151
+ this.uninstallBouncerForSubagents();
152
+ this.uninstallTeammatePermissions();
153
+ }
154
+ // Reconcile STATE.md and sprint statuses after wave
155
+ reconcileState(this.workingDir);
156
+ this.emit('stateUpdated');
157
+ // Copy confirmed-done outputs to user-specified output_file paths
158
+ this.publishOutputs(issues);
159
+ // Append progress log entry
160
+ this.appendProgressEntry(issues, waveStart);
161
+ this.metrics.currentWaveIds = [];
162
+ }
163
+ /**
164
+ * After a wave, check each issue's status on disk.
165
+ * `status: done` in issue front matter is the single completion signal.
166
+ * Output doc existence is NOT used as a proxy — code-focused issues
167
+ * (bug fixes, refactors) don't produce docs but are still valid completions.
168
+ */
169
+ reconcileWaveResults(issues) {
170
+ const pmDir = resolvePmDir(this.workingDir);
171
+ if (!pmDir)
172
+ return;
173
+ for (const issue of issues) {
174
+ const fullPath = join(pmDir, issue.path);
175
+ try {
176
+ const content = readFileSync(fullPath, 'utf-8');
177
+ const statusMatch = content.match(/^status:\s*(\S+)/m);
178
+ const currentStatus = statusMatch?.[1] ?? 'unknown';
179
+ if (currentStatus === 'done') {
180
+ this.metrics.issuesCompleted++;
181
+ this.emit('issueCompleted', issue);
182
+ }
183
+ else {
184
+ // Not done — revert to prior status
185
+ this.updateIssueFrontMatter(issue.path, issue.status);
186
+ this.emit('issueError', {
187
+ issueId: issue.id,
188
+ error: 'Issue did not complete during wave execution',
189
+ });
190
+ }
191
+ }
192
+ catch {
193
+ this.emit('issueError', { issueId: issue.id, error: 'Could not read issue file after wave' });
194
+ }
195
+ }
196
+ }
197
+ // ── Issue picking ─────────────────────────────────────────────
198
+ pickReadyIssues() {
199
+ const fullState = parsePlanDirectory(this.workingDir);
200
+ if (!fullState) {
201
+ this.emit('error', 'No .pm/ directory found');
202
+ return [];
203
+ }
204
+ if (fullState.state.paused) {
205
+ this.emit('error', 'Project is paused');
206
+ return [];
207
+ }
208
+ const readyIssues = resolveReadyToWork(fullState.issues, this.epicScope ?? undefined);
209
+ if (readyIssues.length === 0) {
210
+ this.emit('complete', this.epicScope ? 'All epic issues are done or blocked' : 'All work is done or blocked');
211
+ }
212
+ return readyIssues;
213
+ }
214
+ // ── Prompt building ───────────────────────────────────────────
215
+ /**
216
+ * Build the team lead prompt for a wave of issues.
217
+ * Uses Agent Teams for true parallel execution as separate processes —
218
+ * each teammate gets its own context window and sends idle notifications
219
+ * when done. The team is created implicitly by the first Agent(team_name=...) call.
220
+ */
221
+ buildCoordinatorPrompt(issues) {
222
+ const pmDir = resolvePmDir(this.workingDir);
223
+ const outDir = pmDir ? join(pmDir, 'out') : join(this.workingDir, '.pm', 'out');
224
+ // Collect existing output docs that issues may need as input
225
+ const existingDocs = this.listExistingDocs();
226
+ const issueBlocks = issues.map(issue => {
227
+ const criteria = issue.acceptanceCriteria
228
+ .map(c => `- [${c.checked ? 'x' : ' '}] ${c.text}`)
229
+ .join('\n');
230
+ const files = issue.filesToModify.length > 0
231
+ ? `\nFiles to modify:\n${issue.filesToModify.map(f => `- ${f}`).join('\n')}`
232
+ : '';
233
+ // Find predecessor output docs this issue should read
234
+ const predecessorDocs = issue.blockedBy
235
+ .map(bp => {
236
+ const blockerId = bp.replace(/^backlog\//, '').replace(/\.md$/, '');
237
+ return existingDocs.find(d => d.toLowerCase().includes(blockerId.toLowerCase()));
238
+ })
239
+ .filter(Boolean);
240
+ const predecessorSection = predecessorDocs.length > 0
241
+ ? `\nPredecessor outputs to read:\n${predecessorDocs.map(d => `- ${d}`).join('\n')}`
242
+ : '';
243
+ return `### ${issue.id}: ${issue.title}
244
+
245
+ **Type**: ${issue.type} | **Priority**: ${issue.priority} | **Estimate**: ${issue.estimate ?? 'unestimated'}
246
+
247
+ **Description**:
248
+ ${issue.description}
249
+
250
+ **Acceptance Criteria**:
251
+ ${criteria || 'No specific criteria defined.'}
252
+
253
+ **Technical Notes**:
254
+ ${issue.technicalNotes || 'None'}
255
+ ${files}${predecessorSection}
256
+
257
+ **Output file**: ${this.resolveOutputPath(issue)}`;
258
+ }).join('\n\n---\n\n');
259
+ const teamName = `pm-wave-${Date.now()}`;
260
+ const teammateSpawns = issues.map(issue => {
261
+ const predecessorDocs = issue.blockedBy
262
+ .map(bp => {
263
+ const blockerId = bp.replace(/^backlog\//, '').replace(/\.md$/, '');
264
+ return existingDocs.find(d => d.toLowerCase().includes(blockerId.toLowerCase()));
265
+ })
266
+ .filter(Boolean);
267
+ const predInstr = predecessorDocs.length > 0
268
+ ? `Read these predecessor output docs before starting: ${predecessorDocs.join(', ')}. `
269
+ : '';
270
+ const outputFile = this.resolveOutputPath(issue);
271
+ return `Spawn teammate **${issue.id.toLowerCase()}** using the **Agent** tool with \`team_name: "${teamName}"\` and \`name: "${issue.id.toLowerCase()}"\`:
272
+ > ${predInstr}Work on issue ${issue.id}: ${issue.title}.
273
+ > Read the full spec at ${pmDir ? join(pmDir, issue.path) : issue.path}.
274
+ > Execute all acceptance criteria.
275
+ > CRITICAL: Write ALL output/results to ${outputFile} — this is the handoff artifact for downstream issues.
276
+ > After writing output, update the issue front matter: change \`status: in_progress\` to \`status: done\`.
277
+ > Do not modify STATE.md. Do not work on anything outside this issue's scope.`;
278
+ }).join('\n\n');
279
+ return `You are the team lead coordinating ${issues.length} issue${issues.length > 1 ? 's' : ''} using Agent Teams.
280
+
281
+ ## Project Directory
282
+ Working directory: ${this.workingDir}
283
+ Plan directory: ${pmDir || '.pm/'}
284
+
285
+ ## Issues to Execute
286
+
287
+ ${issueBlocks}
288
+
289
+ ## Execution Protocol — Agent Teams
290
+
291
+ ### Step 1: Spawn teammates
292
+
293
+ Spawn all ${issues.length} teammates in parallel by sending a single message with ${issues.length} **Agent** tool calls. Each call must include \`team_name: "${teamName}"\` and a unique \`name\`. The team is created automatically when you spawn the first teammate with \`team_name\` — no separate setup step is needed.
294
+
295
+ ${teammateSpawns}
296
+
297
+ ### Step 2: Wait for ALL teammates to complete
298
+
299
+ CRITICAL: After spawning, you MUST remain active and wait for every single teammate to finish. Each teammate automatically sends you an **idle notification** when they complete their work.
300
+
301
+ Track completion against this checklist — ALL must report idle before you proceed:
302
+ ${issues.map(i => `- [ ] ${i.id.toLowerCase()}`).join('\n')}
303
+
304
+ While waiting:
305
+ - As each teammate goes idle, verify their output file exists on disk using the **Read** tool
306
+ - If a teammate has not gone idle after 15 minutes, use **SendMessage** to check on them
307
+ - Do NOT proceed to Step 3 until you have received idle notifications from ALL ${issues.length} teammates
308
+
309
+ WARNING: The #1 failure mode is exiting before all teammates finish. If you exit early, all teammate processes are killed and their work is permanently lost. When in doubt, keep waiting. Err on the side of waiting too long rather than exiting too early.
310
+
311
+ ### Step 3: Verify outputs
312
+
313
+ Once every teammate has gone idle:
314
+ 1. Verify each output file exists in ${outDir}/ using **Read** or **Glob**
315
+ 2. Verify each issue's front matter status is \`done\`
316
+ 3. If any teammate failed to write output or update status, do it yourself
317
+ 4. Do NOT modify STATE.md — the orchestrator handles that
318
+
319
+ ## Critical Rules
320
+
321
+ - The team is created implicitly when you spawn the first teammate with \`team_name\`, and cleaned up automatically when all teammates exit. Your only job is to spawn teammates, wait, and verify.
322
+ - You MUST wait for idle notifications from ALL ${issues.length} teammates before exiting. Exiting early kills all teammate processes and permanently loses their work.
323
+ - Each teammate MUST write its output to disk — research only in conversation is LOST.
324
+ - Each teammate MUST update the issue front matter status to \`done\`.
325
+ - One issue per teammate — no cross-issue work.`;
326
+ }
327
+ /**
328
+ * Revert issues that stayed in_progress after a failed wave.
329
+ */
330
+ revertIncompleteIssues(issues) {
331
+ const pmDir = resolvePmDir(this.workingDir);
332
+ if (!pmDir)
333
+ return;
334
+ for (const issue of issues) {
335
+ const fullPath = join(pmDir, issue.path);
336
+ try {
337
+ const content = readFileSync(fullPath, 'utf-8');
338
+ if (content.match(/^status:\s*in_progress$/m)) {
339
+ this.updateIssueFrontMatter(issue.path, issue.status);
340
+ }
341
+ }
342
+ catch { /* file may be gone */ }
343
+ }
344
+ }
345
+ // ── Teammate permissions ─────────────────────────────────────
346
+ /** Saved content of any pre-existing .claude/settings.json so we can restore it */
347
+ savedClaudeSettings = null;
348
+ claudeSettingsInstalled = false;
349
+ /**
350
+ * Pre-approve tools in project .claude/settings.json so Agent Teams
351
+ * teammates can work without interactive permission prompts.
352
+ * Teammates are separate processes that inherit the lead's permission
353
+ * settings. Without pre-approved tools, they hit interactive prompts
354
+ * that can't be answered in headless/background mode (known bug #25254).
355
+ */
356
+ installTeammatePermissions() {
357
+ const claudeDir = join(this.workingDir, '.claude');
358
+ const settingsPath = join(claudeDir, 'settings.json');
359
+ if (!existsSync(claudeDir)) {
360
+ mkdirSync(claudeDir, { recursive: true });
361
+ }
362
+ // Tools that teammates may need during execution
363
+ const requiredPermissions = [
364
+ 'Bash',
365
+ 'Read',
366
+ 'Edit',
367
+ 'Write',
368
+ 'Glob',
369
+ 'Grep',
370
+ 'WebFetch',
371
+ 'WebSearch',
372
+ 'Agent',
373
+ ];
374
+ try {
375
+ // Save existing settings
376
+ if (existsSync(settingsPath)) {
377
+ this.savedClaudeSettings = readFileSync(settingsPath, 'utf-8');
378
+ const existing = JSON.parse(this.savedClaudeSettings);
379
+ // Merge permissions into existing settings
380
+ if (!existing.permissions)
381
+ existing.permissions = {};
382
+ if (!existing.permissions.allow)
383
+ existing.permissions.allow = [];
384
+ for (const tool of requiredPermissions) {
385
+ if (!existing.permissions.allow.includes(tool)) {
386
+ existing.permissions.allow.push(tool);
387
+ }
388
+ }
389
+ writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
390
+ }
391
+ else {
392
+ this.savedClaudeSettings = null;
393
+ writeFileSync(settingsPath, JSON.stringify({
394
+ permissions: { allow: requiredPermissions },
395
+ }, null, 2));
396
+ }
397
+ this.claudeSettingsInstalled = true;
398
+ }
399
+ catch {
400
+ // Non-fatal — teammates may hit permission prompts
401
+ }
402
+ }
403
+ /**
404
+ * Restore original .claude/settings.json after wave execution.
405
+ */
406
+ uninstallTeammatePermissions() {
407
+ if (!this.claudeSettingsInstalled)
408
+ return;
409
+ const settingsPath = join(this.workingDir, '.claude', 'settings.json');
410
+ try {
411
+ if (this.savedClaudeSettings !== null) {
412
+ writeFileSync(settingsPath, this.savedClaudeSettings);
413
+ }
414
+ else {
415
+ unlinkSync(settingsPath);
416
+ }
417
+ }
418
+ catch {
419
+ // Best effort
420
+ }
421
+ this.savedClaudeSettings = null;
422
+ this.claudeSettingsInstalled = false;
423
+ }
424
+ // ── Bouncer propagation for sub-agents ─────────────────────
425
+ /** Saved content of any pre-existing .mcp.json so we can restore it */
426
+ savedMcpJson = null;
427
+ mcpJsonInstalled = false;
428
+ /**
429
+ * Write .mcp.json in the working directory so Agent Teams teammates
430
+ * (separate processes) auto-discover the bouncer MCP server.
431
+ * This is essential — teammates don't inherit --mcp-config or
432
+ * --permission-prompt-tool from the team lead. .mcp.json project-level
433
+ * discovery + global PreToolUse hooks are the two bouncer paths for teammates.
434
+ *
435
+ * Also generates ~/.mstro/mcp-config.json for the team lead (--mcp-config).
436
+ */
437
+ installBouncerForSubagents() {
438
+ const mcpJsonPath = join(this.workingDir, '.mcp.json');
439
+ // Generate the standard MCP config (for parent --mcp-config) and reuse for sub-agents
440
+ try {
441
+ const generatedPath = generateMcpConfig(this.workingDir);
442
+ if (!generatedPath)
443
+ return;
444
+ const mcpConfig = readFileSync(generatedPath, 'utf-8');
445
+ // Save any existing .mcp.json
446
+ if (existsSync(mcpJsonPath)) {
447
+ this.savedMcpJson = readFileSync(mcpJsonPath, 'utf-8');
448
+ // Merge: add bouncer to existing config
449
+ const existing = JSON.parse(this.savedMcpJson);
450
+ const generated = JSON.parse(mcpConfig);
451
+ existing.mcpServers = {
452
+ ...existing.mcpServers,
453
+ 'mstro-bouncer': generated.mcpServers['mstro-bouncer'],
454
+ };
455
+ writeFileSync(mcpJsonPath, JSON.stringify(existing, null, 2));
456
+ }
457
+ else {
458
+ writeFileSync(mcpJsonPath, mcpConfig);
459
+ }
460
+ this.mcpJsonInstalled = true;
461
+ }
462
+ catch {
463
+ // Non-fatal: parent has MCP via --mcp-config, teammates fall back to PreToolUse hooks
464
+ }
465
+ }
466
+ /**
467
+ * Restore or remove .mcp.json after execution.
468
+ */
469
+ uninstallBouncerForSubagents() {
470
+ if (!this.mcpJsonInstalled)
471
+ return;
472
+ const mcpJsonPath = join(this.workingDir, '.mcp.json');
473
+ try {
474
+ if (this.savedMcpJson !== null) {
475
+ // Restore the original
476
+ writeFileSync(mcpJsonPath, this.savedMcpJson);
477
+ }
478
+ else {
479
+ // We created it — remove it
480
+ unlinkSync(mcpJsonPath);
481
+ }
482
+ }
483
+ catch {
484
+ // Best effort cleanup
485
+ }
486
+ this.savedMcpJson = null;
487
+ this.mcpJsonInstalled = false;
488
+ }
489
+ // ── Helpers ───────────────────────────────────────────────────
490
+ /**
491
+ * Resolve the canonical output path for an issue in .pm/out/.
492
+ * This is the PM system's internal execution artifact — always under
493
+ * PM control. User-facing delivery to output_file happens via publishOutputs().
494
+ */
495
+ resolveOutputPath(issue) {
496
+ const pmDir = resolvePmDir(this.workingDir);
497
+ const outDir = pmDir ? join(pmDir, 'out') : join(this.workingDir, '.pm', 'out');
498
+ return join(outDir, `${issue.id}-${this.slugify(issue.title)}.md`);
499
+ }
500
+ /**
501
+ * List existing execution output docs in .pm/out/.
502
+ * Single canonical location — no split-brain lookup.
503
+ */
504
+ listExistingDocs() {
505
+ const pmDir = resolvePmDir(this.workingDir);
506
+ if (!pmDir)
507
+ return [];
508
+ const outDir = join(pmDir, 'out');
509
+ if (!existsSync(outDir))
510
+ return [];
511
+ try {
512
+ return readdirSync(outDir)
513
+ .filter(f => f.endsWith('.md'))
514
+ .map(f => join(outDir, f));
515
+ }
516
+ catch {
517
+ return [];
518
+ }
519
+ }
520
+ /**
521
+ * Copy confirmed-done outputs from .pm/out/ to user-specified output_file paths.
522
+ * Only copies for issues that completed successfully and have output_file set.
523
+ * Failures are non-fatal — the canonical artifact in .pm/out/ is always safe.
524
+ */
525
+ publishOutputs(issues) {
526
+ const pmDir = resolvePmDir(this.workingDir);
527
+ if (!pmDir)
528
+ return;
529
+ for (const issue of issues) {
530
+ if (!issue.outputFile)
531
+ continue;
532
+ // Only publish for confirmed-done issues
533
+ try {
534
+ const content = readFileSync(join(pmDir, issue.path), 'utf-8');
535
+ if (!content.match(/^status:\s*done$/m))
536
+ continue;
537
+ }
538
+ catch {
539
+ continue;
540
+ }
541
+ const srcPath = this.resolveOutputPath(issue);
542
+ if (!existsSync(srcPath))
543
+ continue;
544
+ // Guard against path traversal — output_file must resolve within workingDir
545
+ const destPath = resolve(this.workingDir, issue.outputFile);
546
+ if (!destPath.startsWith(this.workingDir + '/') && destPath !== this.workingDir) {
547
+ this.emit('output', {
548
+ issueId: issue.id,
549
+ text: `Warning: output_file "${issue.outputFile}" escapes project directory — skipping`,
550
+ });
551
+ continue;
552
+ }
553
+ try {
554
+ // Ensure destination directory exists
555
+ const destDir = join(destPath, '..');
556
+ if (!existsSync(destDir))
557
+ mkdirSync(destDir, { recursive: true });
558
+ copyFileSync(srcPath, destPath);
559
+ }
560
+ catch {
561
+ // Non-fatal — canonical artifact is safe in .pm/out/
562
+ this.emit('output', {
563
+ issueId: issue.id,
564
+ text: `Warning: could not copy output to ${issue.outputFile}`,
565
+ });
566
+ }
567
+ }
568
+ }
569
+ slugify(text) {
570
+ return text
571
+ .toLowerCase()
572
+ .replace(/[^a-z0-9]+/g, '-')
573
+ .replace(/^-+|-+$/g, '')
574
+ .slice(0, 60);
575
+ }
576
+ updateIssueFrontMatter(issuePath, newStatus) {
577
+ const pmDir = resolvePmDir(this.workingDir);
578
+ if (!pmDir)
579
+ return;
580
+ const fullPath = join(pmDir, issuePath);
581
+ try {
582
+ let content = readFileSync(fullPath, 'utf-8');
583
+ content = content.replace(/^(status:\s*).+$/m, `$1${newStatus}`);
584
+ writeFileSync(fullPath, content, 'utf-8');
585
+ }
586
+ catch {
587
+ // Ignore errors — file may have been moved
588
+ }
589
+ }
590
+ /**
591
+ * Append a progress log entry after a wave completes.
592
+ * Re-reads issue files from disk to determine which actually completed.
593
+ */
594
+ appendProgressEntry(issues, waveStart) {
595
+ const pmDir = resolvePmDir(this.workingDir);
596
+ if (!pmDir)
597
+ return;
598
+ const progressPath = join(pmDir, 'progress.md');
599
+ if (!existsSync(progressPath))
600
+ return;
601
+ const durationMin = Math.round((Date.now() - waveStart) / 60_000);
602
+ const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 16);
603
+ // Re-read issue statuses from disk to get accurate completion count
604
+ const completed = [];
605
+ const failed = [];
606
+ for (const issue of issues) {
607
+ try {
608
+ const content = readFileSync(join(pmDir, issue.path), 'utf-8');
609
+ const statusMatch = content.match(/^status:\s*(\S+)/m);
610
+ if (statusMatch?.[1] === 'done') {
611
+ completed.push(issue.id);
612
+ }
613
+ else {
614
+ failed.push(issue.id);
615
+ }
616
+ }
617
+ catch {
618
+ failed.push(issue.id);
619
+ }
620
+ }
621
+ const lines = [
622
+ '',
623
+ `## ${timestamp} — Wave [${issues.map(i => i.id).join(', ')}]`,
624
+ '',
625
+ `- **Duration**: ${durationMin} min`,
626
+ `- **Completed**: ${completed.length}/${issues.length}${completed.length > 0 ? ` (${completed.join(', ')})` : ''}`,
627
+ ];
628
+ if (failed.length > 0) {
629
+ lines.push(`- **Failed**: ${failed.join(', ')}`);
630
+ }
631
+ lines.push('');
632
+ try {
633
+ const existing = readFileSync(progressPath, 'utf-8');
634
+ writeFileSync(progressPath, existing.trimEnd() + '\n' + lines.join('\n'), 'utf-8');
635
+ }
636
+ catch {
637
+ // Non-fatal
638
+ }
639
+ }
640
+ }
641
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../server/services/plan/executor.ts"],"names":[],"mappings":"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"}