mstro-app 0.4.2 → 0.4.4
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.
- package/bin/mstro.js +119 -40
- package/dist/server/cli/headless/claude-invoker-process.d.ts +11 -0
- package/dist/server/cli/headless/claude-invoker-process.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-process.js +140 -0
- package/dist/server/cli/headless/claude-invoker-process.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts +40 -0
- package/dist/server/cli/headless/claude-invoker-stall.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stall.js +98 -0
- package/dist/server/cli/headless/claude-invoker-stall.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts +44 -0
- package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-stream.js +276 -0
- package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts +21 -0
- package/dist/server/cli/headless/claude-invoker-tools.d.ts.map +1 -0
- package/dist/server/cli/headless/claude-invoker-tools.js +137 -0
- package/dist/server/cli/headless/claude-invoker-tools.js.map +1 -0
- package/dist/server/cli/headless/claude-invoker.d.ts +6 -4
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +10 -804
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/haiku-assessments.d.ts +62 -0
- package/dist/server/cli/headless/haiku-assessments.d.ts.map +1 -0
- package/dist/server/cli/headless/haiku-assessments.js +281 -0
- package/dist/server/cli/headless/haiku-assessments.js.map +1 -0
- package/dist/server/cli/headless/headless-logger.d.ts +3 -2
- package/dist/server/cli/headless/headless-logger.d.ts.map +1 -1
- package/dist/server/cli/headless/headless-logger.js +28 -5
- package/dist/server/cli/headless/headless-logger.js.map +1 -1
- package/dist/server/cli/headless/native-timeout-detector.d.ts +44 -0
- package/dist/server/cli/headless/native-timeout-detector.d.ts.map +1 -0
- package/dist/server/cli/headless/native-timeout-detector.js +99 -0
- package/dist/server/cli/headless/native-timeout-detector.js.map +1 -0
- package/dist/server/cli/headless/stall-assessor.d.ts +2 -110
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +65 -457
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/types.d.ts +4 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-attachments.d.ts +21 -0
- package/dist/server/cli/improvisation-attachments.d.ts.map +1 -0
- package/dist/server/cli/improvisation-attachments.js +116 -0
- package/dist/server/cli/improvisation-attachments.js.map +1 -0
- package/dist/server/cli/improvisation-retry.d.ts +52 -0
- package/dist/server/cli/improvisation-retry.d.ts.map +1 -0
- package/dist/server/cli/improvisation-retry.js +434 -0
- package/dist/server/cli/improvisation-retry.js.map +1 -0
- package/dist/server/cli/improvisation-session-manager.d.ts +10 -266
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +117 -1079
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/cli/improvisation-types.d.ts +86 -0
- package/dist/server/cli/improvisation-types.d.ts.map +1 -0
- package/dist/server/cli/improvisation-types.js +10 -0
- package/dist/server/cli/improvisation-types.js.map +1 -0
- package/dist/server/cli/prompt-builders.d.ts +68 -0
- package/dist/server/cli/prompt-builders.d.ts.map +1 -0
- package/dist/server/cli/prompt-builders.js +312 -0
- package/dist/server/cli/prompt-builders.js.map +1 -0
- package/dist/server/index.js +33 -212
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-haiku.d.ts +10 -0
- package/dist/server/mcp/bouncer-haiku.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-haiku.js +152 -0
- package/dist/server/mcp/bouncer-haiku.js.map +1 -0
- package/dist/server/mcp/bouncer-integration.d.ts +3 -4
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +50 -196
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/security-analysis.d.ts +38 -0
- package/dist/server/mcp/security-analysis.d.ts.map +1 -0
- package/dist/server/mcp/security-analysis.js +183 -0
- package/dist/server/mcp/security-analysis.js.map +1 -0
- package/dist/server/mcp/security-audit.d.ts +1 -1
- package/dist/server/mcp/security-audit.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.d.ts +1 -25
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +55 -260
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/server-setup.d.ts +22 -0
- package/dist/server/server-setup.d.ts.map +1 -0
- package/dist/server/server-setup.js +101 -0
- package/dist/server/server-setup.js.map +1 -0
- package/dist/server/services/file-explorer-ops.d.ts +24 -0
- package/dist/server/services/file-explorer-ops.d.ts.map +1 -0
- package/dist/server/services/file-explorer-ops.js +211 -0
- package/dist/server/services/file-explorer-ops.js.map +1 -0
- package/dist/server/services/files.d.ts +2 -85
- package/dist/server/services/files.d.ts.map +1 -1
- package/dist/server/services/files.js +7 -427
- package/dist/server/services/files.js.map +1 -1
- package/dist/server/services/plan/composer.d.ts +1 -1
- package/dist/server/services/plan/composer.d.ts.map +1 -1
- package/dist/server/services/plan/composer.js +118 -32
- package/dist/server/services/plan/composer.js.map +1 -1
- package/dist/server/services/plan/config-installer.d.ts +25 -0
- package/dist/server/services/plan/config-installer.d.ts.map +1 -0
- package/dist/server/services/plan/config-installer.js +182 -0
- package/dist/server/services/plan/config-installer.js.map +1 -0
- package/dist/server/services/plan/dependency-resolver.d.ts +1 -1
- package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -1
- package/dist/server/services/plan/dependency-resolver.js +4 -1
- package/dist/server/services/plan/dependency-resolver.js.map +1 -1
- package/dist/server/services/plan/executor.d.ts +38 -74
- package/dist/server/services/plan/executor.d.ts.map +1 -1
- package/dist/server/services/plan/executor.js +274 -460
- package/dist/server/services/plan/executor.js.map +1 -1
- package/dist/server/services/plan/front-matter.d.ts +18 -0
- package/dist/server/services/plan/front-matter.d.ts.map +1 -0
- package/dist/server/services/plan/front-matter.js +44 -0
- package/dist/server/services/plan/front-matter.js.map +1 -0
- package/dist/server/services/plan/output-manager.d.ts +22 -0
- package/dist/server/services/plan/output-manager.d.ts.map +1 -0
- package/dist/server/services/plan/output-manager.js +97 -0
- package/dist/server/services/plan/output-manager.js.map +1 -0
- package/dist/server/services/plan/parser-core.d.ts +20 -0
- package/dist/server/services/plan/parser-core.d.ts.map +1 -0
- package/dist/server/services/plan/parser-core.js +350 -0
- package/dist/server/services/plan/parser-core.js.map +1 -0
- package/dist/server/services/plan/parser-migration.d.ts +5 -0
- package/dist/server/services/plan/parser-migration.d.ts.map +1 -0
- package/dist/server/services/plan/parser-migration.js +124 -0
- package/dist/server/services/plan/parser-migration.js.map +1 -0
- package/dist/server/services/plan/parser.d.ts +11 -3
- package/dist/server/services/plan/parser.d.ts.map +1 -1
- package/dist/server/services/plan/parser.js +184 -369
- package/dist/server/services/plan/parser.js.map +1 -1
- package/dist/server/services/plan/prompt-builder.d.ts +17 -0
- package/dist/server/services/plan/prompt-builder.d.ts.map +1 -0
- package/dist/server/services/plan/prompt-builder.js +137 -0
- package/dist/server/services/plan/prompt-builder.js.map +1 -0
- package/dist/server/services/plan/review-gate.d.ts +28 -0
- package/dist/server/services/plan/review-gate.d.ts.map +1 -0
- package/dist/server/services/plan/review-gate.js +191 -0
- package/dist/server/services/plan/review-gate.js.map +1 -0
- package/dist/server/services/plan/state-reconciler.d.ts +1 -1
- package/dist/server/services/plan/state-reconciler.d.ts.map +1 -1
- package/dist/server/services/plan/state-reconciler.js +59 -7
- package/dist/server/services/plan/state-reconciler.js.map +1 -1
- package/dist/server/services/plan/types.d.ts +68 -0
- package/dist/server/services/plan/types.d.ts.map +1 -1
- package/dist/server/services/platform-credentials.d.ts +24 -0
- package/dist/server/services/platform-credentials.d.ts.map +1 -0
- package/dist/server/services/platform-credentials.js +68 -0
- package/dist/server/services/platform-credentials.js.map +1 -0
- package/dist/server/services/platform.d.ts +1 -31
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +11 -109
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts +7 -97
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +53 -266
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/terminal/pty-utils.d.ts +57 -0
- package/dist/server/services/terminal/pty-utils.d.ts.map +1 -0
- package/dist/server/services/terminal/pty-utils.js +141 -0
- package/dist/server/services/terminal/pty-utils.js.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts +4 -0
- package/dist/server/services/websocket/file-definition-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-definition-handlers.js +153 -0
- package/dist/server/services/websocket/file-definition-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-explorer-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/file-explorer-handlers.js +52 -391
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-search-handlers.d.ts +5 -0
- package/dist/server/services/websocket/file-search-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/file-search-handlers.js +238 -0
- package/dist/server/services/websocket/file-search-handlers.js.map +1 -0
- package/dist/server/services/websocket/file-utils.js +3 -3
- package/dist/server/services/websocket/file-utils.js.map +1 -1
- package/dist/server/services/websocket/git-branch-handlers.d.ts +7 -0
- package/dist/server/services/websocket/git-branch-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-branch-handlers.js +110 -0
- package/dist/server/services/websocket/git-branch-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-diff-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-diff-handlers.js +123 -0
- package/dist/server/services/websocket/git-diff-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-handlers.d.ts +2 -31
- package/dist/server/services/websocket/git-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-handlers.js +35 -541
- package/dist/server/services/websocket/git-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-log-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-log-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-log-handlers.js +128 -0
- package/dist/server/services/websocket/git-log-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-pr-handlers.js +13 -53
- package/dist/server/services/websocket/git-pr-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-tag-handlers.d.ts +6 -0
- package/dist/server/services/websocket/git-tag-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/git-tag-handlers.js +76 -0
- package/dist/server/services/websocket/git-tag-handlers.js.map +1 -0
- package/dist/server/services/websocket/git-utils.d.ts +43 -0
- package/dist/server/services/websocket/git-utils.d.ts.map +1 -0
- package/dist/server/services/websocket/git-utils.js +201 -0
- package/dist/server/services/websocket/git-utils.js.map +1 -0
- package/dist/server/services/websocket/handler.d.ts +2 -0
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +37 -112
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/plan-board-handlers.d.ts +11 -0
- package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-board-handlers.js +218 -0
- package/dist/server/services/websocket/plan-board-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts +9 -0
- package/dist/server/services/websocket/plan-execution-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-execution-handlers.js +142 -0
- package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-handlers.d.ts +7 -2
- package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-handlers.js +21 -462
- package/dist/server/services/websocket/plan-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-helpers.d.ts +19 -0
- package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-helpers.js +199 -0
- package/dist/server/services/websocket/plan-helpers.js.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts +12 -0
- package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-issue-handlers.js +162 -0
- package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts +7 -0
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js +206 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -0
- package/dist/server/services/websocket/quality-complexity.d.ts +14 -0
- package/dist/server/services/websocket/quality-complexity.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-complexity.js +262 -0
- package/dist/server/services/websocket/quality-complexity.js.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts +16 -0
- package/dist/server/services/websocket/quality-fix-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-fix-agent.js +140 -0
- package/dist/server/services/websocket/quality-fix-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-handlers.js +34 -346
- package/dist/server/services/websocket/quality-handlers.js.map +1 -1
- package/dist/server/services/websocket/quality-linting.d.ts +9 -0
- package/dist/server/services/websocket/quality-linting.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-linting.js +178 -0
- package/dist/server/services/websocket/quality-linting.js.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts +19 -0
- package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-review-agent.js +206 -0
- package/dist/server/services/websocket/quality-review-agent.js.map +1 -0
- package/dist/server/services/websocket/quality-service.d.ts +3 -51
- package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-service.js +9 -651
- package/dist/server/services/websocket/quality-service.js.map +1 -1
- package/dist/server/services/websocket/quality-tools.d.ts +23 -0
- package/dist/server/services/websocket/quality-tools.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-tools.js +208 -0
- package/dist/server/services/websocket/quality-tools.js.map +1 -0
- package/dist/server/services/websocket/quality-types.d.ts +59 -0
- package/dist/server/services/websocket/quality-types.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-types.js +101 -0
- package/dist/server/services/websocket/quality-types.js.map +1 -0
- package/dist/server/services/websocket/session-handlers.d.ts +3 -4
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/session-handlers.js +3 -378
- package/dist/server/services/websocket/session-handlers.js.map +1 -1
- package/dist/server/services/websocket/session-history.d.ts +4 -0
- package/dist/server/services/websocket/session-history.d.ts.map +1 -0
- package/dist/server/services/websocket/session-history.js +208 -0
- package/dist/server/services/websocket/session-history.js.map +1 -0
- package/dist/server/services/websocket/session-initialization.d.ts +5 -0
- package/dist/server/services/websocket/session-initialization.d.ts.map +1 -0
- package/dist/server/services/websocket/session-initialization.js +163 -0
- package/dist/server/services/websocket/session-initialization.js.map +1 -0
- package/dist/server/services/websocket/types.d.ts +12 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/package.json +1 -2
- package/server/cli/headless/claude-invoker-process.ts +204 -0
- package/server/cli/headless/claude-invoker-stall.ts +164 -0
- package/server/cli/headless/claude-invoker-stream.ts +353 -0
- package/server/cli/headless/claude-invoker-tools.ts +187 -0
- package/server/cli/headless/claude-invoker.ts +15 -1092
- package/server/cli/headless/haiku-assessments.ts +365 -0
- package/server/cli/headless/headless-logger.ts +26 -5
- package/server/cli/headless/native-timeout-detector.ts +117 -0
- package/server/cli/headless/stall-assessor.ts +65 -618
- package/server/cli/headless/types.ts +4 -1
- package/server/cli/improvisation-attachments.ts +148 -0
- package/server/cli/improvisation-retry.ts +602 -0
- package/server/cli/improvisation-session-manager.ts +140 -1349
- package/server/cli/improvisation-types.ts +98 -0
- package/server/cli/prompt-builders.ts +370 -0
- package/server/index.ts +35 -246
- package/server/mcp/bouncer-haiku.ts +182 -0
- package/server/mcp/bouncer-integration.ts +87 -248
- package/server/mcp/security-analysis.ts +217 -0
- package/server/mcp/security-audit.ts +1 -1
- package/server/mcp/security-patterns.ts +60 -283
- package/server/server-setup.ts +114 -0
- package/server/services/file-explorer-ops.ts +293 -0
- package/server/services/files.ts +20 -532
- package/server/services/plan/composer.ts +140 -35
- package/server/services/plan/config-installer.ts +187 -0
- package/server/services/plan/dependency-resolver.ts +4 -1
- package/server/services/plan/executor.ts +281 -488
- package/server/services/plan/front-matter.ts +48 -0
- package/server/services/plan/output-manager.ts +113 -0
- package/server/services/plan/parser-core.ts +406 -0
- package/server/services/plan/parser-migration.ts +128 -0
- package/server/services/plan/parser.ts +188 -394
- package/server/services/plan/prompt-builder.ts +161 -0
- package/server/services/plan/review-gate.ts +212 -0
- package/server/services/plan/state-reconciler.ts +68 -7
- package/server/services/plan/types.ts +101 -1
- package/server/services/platform-credentials.ts +83 -0
- package/server/services/platform.ts +16 -131
- package/server/services/terminal/pty-manager.ts +66 -313
- package/server/services/terminal/pty-utils.ts +176 -0
- package/server/services/websocket/file-definition-handlers.ts +165 -0
- package/server/services/websocket/file-explorer-handlers.ts +37 -452
- package/server/services/websocket/file-search-handlers.ts +291 -0
- package/server/services/websocket/file-utils.ts +3 -3
- package/server/services/websocket/git-branch-handlers.ts +130 -0
- package/server/services/websocket/git-diff-handlers.ts +140 -0
- package/server/services/websocket/git-handlers.ts +40 -625
- package/server/services/websocket/git-log-handlers.ts +149 -0
- package/server/services/websocket/git-pr-handlers.ts +17 -62
- package/server/services/websocket/git-tag-handlers.ts +91 -0
- package/server/services/websocket/git-utils.ts +230 -0
- package/server/services/websocket/handler.ts +39 -112
- package/server/services/websocket/plan-board-handlers.ts +277 -0
- package/server/services/websocket/plan-execution-handlers.ts +184 -0
- package/server/services/websocket/plan-handlers.ts +23 -544
- package/server/services/websocket/plan-helpers.ts +215 -0
- package/server/services/websocket/plan-issue-handlers.ts +204 -0
- package/server/services/websocket/plan-sprint-handlers.ts +252 -0
- package/server/services/websocket/quality-complexity.ts +294 -0
- package/server/services/websocket/quality-fix-agent.ts +181 -0
- package/server/services/websocket/quality-handlers.ts +36 -404
- package/server/services/websocket/quality-linting.ts +187 -0
- package/server/services/websocket/quality-review-agent.ts +246 -0
- package/server/services/websocket/quality-service.ts +11 -762
- package/server/services/websocket/quality-tools.ts +209 -0
- package/server/services/websocket/quality-types.ts +169 -0
- package/server/services/websocket/session-handlers.ts +5 -437
- package/server/services/websocket/session-history.ts +222 -0
- package/server/services/websocket/session-initialization.ts +209 -0
- package/server/services/websocket/types.ts +46 -2
|
@@ -15,7 +15,8 @@ import { runWithFileLogger } from '../../cli/headless/headless-logger.js';
|
|
|
15
15
|
import { HeadlessRunner, type ToolUseEvent } from '../../cli/headless/index.js';
|
|
16
16
|
import type { HandlerContext } from '../websocket/handler-context.js';
|
|
17
17
|
import type { WSContext } from '../websocket/types.js';
|
|
18
|
-
import { getNextId, parsePlanDirectory, resolvePmDir } from './parser.js';
|
|
18
|
+
import { defaultPmDir, getNextId, parseBoardDirectory, parsePlanDirectory, resolvePmDir } from './parser.js';
|
|
19
|
+
import type { Issue } from './types.js';
|
|
19
20
|
|
|
20
21
|
const PROMPT_TOOL_MESSAGES: Record<string, string> = {
|
|
21
22
|
Glob: 'Discovering project files...',
|
|
@@ -64,57 +65,159 @@ function readFileOrEmpty(path: string): string {
|
|
|
64
65
|
return '';
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
interface ComposerContext {
|
|
69
|
+
boardContext: string;
|
|
70
|
+
stateContent: string;
|
|
71
|
+
issues: Issue[];
|
|
72
|
+
idInfo: string;
|
|
73
|
+
epicContext: string;
|
|
74
|
+
issuesSummary: string;
|
|
75
|
+
boardDir: string;
|
|
76
|
+
backlogPath: string;
|
|
77
|
+
effectiveBoardId: string | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function buildComposerContext(pmDir: string, workingDir: string, boardId?: string): ComposerContext {
|
|
81
|
+
const fullState = parsePlanDirectory(workingDir);
|
|
82
|
+
const effectiveBoardId = boardId ?? fullState?.workspace?.activeBoardId ?? null;
|
|
83
|
+
|
|
84
|
+
let boardContext = '';
|
|
85
|
+
let stateContent = '';
|
|
86
|
+
let issues: Issue[] = [];
|
|
87
|
+
|
|
88
|
+
if (effectiveBoardId) {
|
|
89
|
+
const boardState = parseBoardDirectory(pmDir, effectiveBoardId);
|
|
90
|
+
if (boardState) {
|
|
91
|
+
stateContent = readFileOrEmpty(join(pmDir, 'boards', effectiveBoardId, 'STATE.md'));
|
|
92
|
+
issues = boardState.issues;
|
|
93
|
+
boardContext = `\nActive board: ${effectiveBoardId} — "${boardState.board.title}"
|
|
94
|
+
Board status: ${boardState.board.status}
|
|
95
|
+
Board goal: ${boardState.board.goal || '(none set)'}
|
|
96
|
+
Board directory: ${pmDir}/boards/${effectiveBoardId}/
|
|
97
|
+
Backlog directory: ${pmDir}/boards/${effectiveBoardId}/backlog/\n`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!stateContent) stateContent = readFileOrEmpty(join(pmDir, 'STATE.md'));
|
|
102
|
+
if (issues.length === 0 && fullState) issues = fullState.issues;
|
|
103
|
+
|
|
104
|
+
const idInfo = (issues.length > 0 || fullState)
|
|
105
|
+
? `Next available IDs: ${getNextId(issues, 'IS')}, ${getNextId(issues, 'BG')}, ${getNextId(issues, 'EP')}`
|
|
106
|
+
: '';
|
|
107
|
+
|
|
108
|
+
const existingEpics = issues.filter(i => i.type === 'epic');
|
|
109
|
+
const epicContext = existingEpics.length > 0
|
|
110
|
+
? `\nExisting epics:\n${existingEpics.map(e => `- ${e.id}: ${e.title} (${e.path}, children: ${e.children.length})`).join('\n')}\n`
|
|
111
|
+
: '';
|
|
112
|
+
|
|
113
|
+
const nonEpicIssues = issues.filter(i => i.type !== 'epic');
|
|
114
|
+
const issuesSummary = nonEpicIssues.length > 0
|
|
115
|
+
? `\nExisting issues on this board:\n${nonEpicIssues.map(i => `- ${i.id}: ${i.title} [${i.status}] (P${i.priority})`).join('\n')}\n`
|
|
116
|
+
: '';
|
|
117
|
+
|
|
118
|
+
const boardDir = effectiveBoardId ? `boards/${effectiveBoardId}` : '';
|
|
119
|
+
const backlogPath = effectiveBoardId
|
|
120
|
+
? `${pmDir}/boards/${effectiveBoardId}/backlog/`
|
|
121
|
+
: `${pmDir}/backlog/`;
|
|
122
|
+
|
|
123
|
+
return { boardContext, stateContent, issues, idInfo, epicContext, issuesSummary, boardDir, backlogPath, effectiveBoardId };
|
|
124
|
+
}
|
|
125
|
+
|
|
67
126
|
export async function handlePlanPrompt(
|
|
68
127
|
ctx: HandlerContext,
|
|
69
128
|
ws: WSContext,
|
|
70
129
|
userPrompt: string,
|
|
71
130
|
workingDir: string,
|
|
131
|
+
boardId?: string,
|
|
72
132
|
): Promise<void> {
|
|
73
|
-
const pmDir = resolvePmDir(workingDir) ??
|
|
74
|
-
const stateContent = readFileOrEmpty(join(pmDir, 'STATE.md'));
|
|
133
|
+
const pmDir = resolvePmDir(workingDir) ?? defaultPmDir(workingDir);
|
|
75
134
|
const projectContent = readFileOrEmpty(join(pmDir, 'project.md'));
|
|
135
|
+
const cc = buildComposerContext(pmDir, workingDir, boardId);
|
|
76
136
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (fullState) {
|
|
81
|
-
const nextIS = getNextId(fullState.issues, 'IS');
|
|
82
|
-
const nextBG = getNextId(fullState.issues, 'BG');
|
|
83
|
-
const nextEP = getNextId(fullState.issues, 'EP');
|
|
84
|
-
idInfo = `Next available IDs: ${nextIS}, ${nextBG}, ${nextEP}`;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Read existing epic files to provide context
|
|
88
|
-
let epicContext = '';
|
|
89
|
-
if (fullState) {
|
|
90
|
-
const existingEpics = fullState.issues.filter((i: { type: string }) => i.type === 'epic');
|
|
91
|
-
if (existingEpics.length > 0) {
|
|
92
|
-
epicContext = `\nExisting epics:\n${existingEpics.map((e: { id: string; title: string; path: string; children: string[] }) => `- ${e.id}: ${e.title} (${e.path}, children: ${e.children.length})`).join('\n')}\n`;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const enrichedPrompt = `You are managing a project in the .pm/ directory format (Project Plan Spec).
|
|
97
|
-
The project's current state is:
|
|
98
|
-
|
|
137
|
+
const enrichedPrompt = `You are managing a project using a board-centric PM system (Project Plan Spec v2).
|
|
138
|
+
All issues belong to a board. Each board has its own backlog/, STATE.md, and out/ directory.
|
|
139
|
+
${cc.boardContext}
|
|
99
140
|
<state>
|
|
100
|
-
${stateContent || 'No STATE.md exists yet'}
|
|
141
|
+
${cc.stateContent || 'No STATE.md exists yet'}
|
|
101
142
|
</state>
|
|
102
143
|
|
|
103
144
|
<project>
|
|
104
145
|
${projectContent || 'No project.md yet'}
|
|
105
146
|
</project>
|
|
106
147
|
|
|
107
|
-
${idInfo}
|
|
108
|
-
${epicContext}
|
|
148
|
+
${cc.idInfo}
|
|
149
|
+
${cc.epicContext}
|
|
150
|
+
${cc.issuesSummary}
|
|
151
|
+
|
|
152
|
+
## Directory structure
|
|
109
153
|
|
|
110
|
-
|
|
111
|
-
|
|
154
|
+
\`\`\`
|
|
155
|
+
${pmDir}/
|
|
156
|
+
├── project.md
|
|
157
|
+
├── workspace.json
|
|
158
|
+
└── boards/
|
|
159
|
+
└── ${cc.effectiveBoardId || 'BOARD-NNN'}/
|
|
160
|
+
├── board.md # Board metadata
|
|
161
|
+
├── STATE.md # Board execution state
|
|
162
|
+
├── backlog/ # Issues, epics, bugs
|
|
163
|
+
│ ├── EP-*.md
|
|
164
|
+
│ ├── IS-*.md
|
|
165
|
+
│ └── BG-*.md
|
|
166
|
+
├── out/ # Output artifacts
|
|
167
|
+
├── reviews/ # Review gate results
|
|
168
|
+
└── progress.md # Execution log
|
|
169
|
+
\`\`\`
|
|
170
|
+
|
|
171
|
+
## Rules
|
|
172
|
+
|
|
173
|
+
- ALL new issue files MUST be created in \`${cc.backlogPath}\`
|
|
174
|
+
- Use YAML front matter + markdown body for all files
|
|
112
175
|
- When modifying issues, preserve all existing YAML fields you don't change
|
|
113
|
-
- After any state change, update STATE.md
|
|
176
|
+
- After any state change, update the board's STATE.md at \`${pmDir}/${cc.boardDir}/STATE.md\`
|
|
114
177
|
- Use the next available ID for new entities
|
|
178
|
+
- Set all new issue statuses to \`todo\` so they appear in the "Ready to Work" section
|
|
115
179
|
- Respond briefly describing what you did
|
|
116
180
|
|
|
117
|
-
Issue
|
|
181
|
+
## Issue format
|
|
182
|
+
|
|
183
|
+
Each issue file must have this structure:
|
|
184
|
+
\`\`\`markdown
|
|
185
|
+
---
|
|
186
|
+
id: IS-NNN
|
|
187
|
+
title: "Short descriptive title"
|
|
188
|
+
type: issue
|
|
189
|
+
status: todo
|
|
190
|
+
priority: P0|P1|P2|P3
|
|
191
|
+
estimate: 1-5
|
|
192
|
+
labels: []
|
|
193
|
+
epic: backlog/EP-NNN.md # if part of an epic
|
|
194
|
+
created: "YYYY-MM-DD"
|
|
195
|
+
blocked_by: [] # Use backlog-relative paths: backlog/IS-NNN.md
|
|
196
|
+
blocks: [] # Use backlog-relative paths: backlog/IS-NNN.md
|
|
197
|
+
review_gate: auto
|
|
198
|
+
output_file: null
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
# IS-NNN: Title
|
|
202
|
+
|
|
203
|
+
## Description
|
|
204
|
+
What needs to be done and why.
|
|
205
|
+
|
|
206
|
+
## Acceptance Criteria
|
|
207
|
+
- [ ] Criterion 1
|
|
208
|
+
- [ ] Criterion 2
|
|
209
|
+
|
|
210
|
+
## Technical Notes
|
|
211
|
+
Implementation guidance.
|
|
212
|
+
|
|
213
|
+
## Files to Modify
|
|
214
|
+
- path/to/file.ts
|
|
215
|
+
|
|
216
|
+
## Activity
|
|
217
|
+
\`\`\`
|
|
218
|
+
|
|
219
|
+
## Issue scoping rules (critical for execution quality)
|
|
220
|
+
|
|
118
221
|
- Each issue is executed by a single AI agent with its own context window
|
|
119
222
|
- Issues estimated at 1-3 story points execute well (focused, single concern)
|
|
120
223
|
- Issues at 5 story points are viable if scoped to one subsystem
|
|
@@ -124,8 +227,9 @@ Issue scoping rules (critical for execution quality):
|
|
|
124
227
|
- If an issue requires work across multiple subsystems, split it into one issue per subsystem with blocked_by edges between them
|
|
125
228
|
- Research/investigation issues should be separate from implementation issues
|
|
126
229
|
|
|
127
|
-
Epic creation rules
|
|
128
|
-
|
|
230
|
+
## Epic creation rules
|
|
231
|
+
|
|
232
|
+
- Create an EP-*.md file in ${cc.backlogPath} with type: epic and a children: [] field in front matter
|
|
129
233
|
- Create individual IS-*.md (or BG-*.md) files for each child issue
|
|
130
234
|
- Each child issue must have epic: backlog/EP-XXX.md in its front matter
|
|
131
235
|
- The epic's children field must list all child paths: [backlog/IS-001.md, backlog/IS-002.md, ...]
|
|
@@ -169,7 +273,8 @@ User request: ${userPrompt}`;
|
|
|
169
273
|
data: { message: 'Claude is planning your project...' },
|
|
170
274
|
});
|
|
171
275
|
|
|
172
|
-
const
|
|
276
|
+
const boardLogDir = cc.effectiveBoardId ? join(pmDir, 'boards', cc.effectiveBoardId, 'logs') : undefined;
|
|
277
|
+
const result = await runWithFileLogger('pm-compose', () => runner.run(), boardLogDir);
|
|
173
278
|
|
|
174
279
|
ctx.broadcastToAll({
|
|
175
280
|
type: 'planPromptProgress',
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Config Installer — Manages temporary config file modifications for Agent Teams.
|
|
6
|
+
*
|
|
7
|
+
* Installs teammate permissions in .claude/settings.json and bouncer MCP config
|
|
8
|
+
* in .mcp.json before wave execution, then restores originals afterward.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { generateMcpConfig } from '../../cli/headless/mcp-config.js';
|
|
14
|
+
|
|
15
|
+
/** Tools that teammates may need during execution */
|
|
16
|
+
const REQUIRED_PERMISSIONS = [
|
|
17
|
+
'Bash',
|
|
18
|
+
'Read',
|
|
19
|
+
'Edit',
|
|
20
|
+
'Write',
|
|
21
|
+
'Glob',
|
|
22
|
+
'Grep',
|
|
23
|
+
'WebFetch',
|
|
24
|
+
'WebSearch',
|
|
25
|
+
'Agent',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/** Restore a file from a .pm-backup, handling the __NONE__ sentinel for files that didn't exist. */
|
|
29
|
+
function restoreFromBackup(backupPath: string, targetPath: string): void {
|
|
30
|
+
try {
|
|
31
|
+
if (!existsSync(backupPath)) return;
|
|
32
|
+
const backup = readFileSync(backupPath, 'utf-8');
|
|
33
|
+
if (backup === '__NONE__') {
|
|
34
|
+
if (existsSync(targetPath)) unlinkSync(targetPath);
|
|
35
|
+
} else {
|
|
36
|
+
writeFileSync(targetPath, backup);
|
|
37
|
+
}
|
|
38
|
+
unlinkSync(backupPath);
|
|
39
|
+
} catch { /* best effort */ }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class ConfigInstaller {
|
|
43
|
+
private savedClaudeSettings: string | null = null;
|
|
44
|
+
private claudeSettingsInstalled = false;
|
|
45
|
+
private savedMcpJson: string | null = null;
|
|
46
|
+
private mcpJsonInstalled = false;
|
|
47
|
+
|
|
48
|
+
constructor(private workingDir: string) {
|
|
49
|
+
// Recover from prior crash: if backup files exist, restore them
|
|
50
|
+
this.recoverFromCrash();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Restore .claude/settings.json and .mcp.json from backups left by a previous crash. */
|
|
54
|
+
private recoverFromCrash(): void {
|
|
55
|
+
restoreFromBackup(
|
|
56
|
+
join(this.workingDir, '.claude', 'settings.json.pm-backup'),
|
|
57
|
+
join(this.workingDir, '.claude', 'settings.json'),
|
|
58
|
+
);
|
|
59
|
+
restoreFromBackup(
|
|
60
|
+
join(this.workingDir, '.mcp.json.pm-backup'),
|
|
61
|
+
join(this.workingDir, '.mcp.json'),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Pre-approve tools in .claude/settings.json so Agent Teams
|
|
67
|
+
* teammates can work without interactive permission prompts.
|
|
68
|
+
*/
|
|
69
|
+
installTeammatePermissions(): void {
|
|
70
|
+
const claudeDir = join(this.workingDir, '.claude');
|
|
71
|
+
const settingsPath = join(claudeDir, 'settings.json');
|
|
72
|
+
|
|
73
|
+
if (!existsSync(claudeDir)) {
|
|
74
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const backupPath = join(claudeDir, 'settings.json.pm-backup');
|
|
78
|
+
try {
|
|
79
|
+
if (existsSync(settingsPath)) {
|
|
80
|
+
this.savedClaudeSettings = readFileSync(settingsPath, 'utf-8');
|
|
81
|
+
writeFileSync(backupPath, this.savedClaudeSettings);
|
|
82
|
+
const existing = JSON.parse(this.savedClaudeSettings);
|
|
83
|
+
|
|
84
|
+
if (!existing.permissions) existing.permissions = {};
|
|
85
|
+
if (!existing.permissions.allow) existing.permissions.allow = [];
|
|
86
|
+
|
|
87
|
+
for (const tool of REQUIRED_PERMISSIONS) {
|
|
88
|
+
if (!existing.permissions.allow.includes(tool)) {
|
|
89
|
+
existing.permissions.allow.push(tool);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
|
|
94
|
+
} else {
|
|
95
|
+
this.savedClaudeSettings = null;
|
|
96
|
+
writeFileSync(backupPath, '__NONE__');
|
|
97
|
+
writeFileSync(settingsPath, JSON.stringify({
|
|
98
|
+
permissions: { allow: REQUIRED_PERMISSIONS },
|
|
99
|
+
}, null, 2));
|
|
100
|
+
}
|
|
101
|
+
this.claudeSettingsInstalled = true;
|
|
102
|
+
} catch {
|
|
103
|
+
// Non-fatal — teammates may hit permission prompts
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Restore original .claude/settings.json after wave execution. */
|
|
108
|
+
uninstallTeammatePermissions(): void {
|
|
109
|
+
if (!this.claudeSettingsInstalled) return;
|
|
110
|
+
const settingsPath = join(this.workingDir, '.claude', 'settings.json');
|
|
111
|
+
const backupPath = join(this.workingDir, '.claude', 'settings.json.pm-backup');
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
if (this.savedClaudeSettings !== null) {
|
|
115
|
+
writeFileSync(settingsPath, this.savedClaudeSettings);
|
|
116
|
+
} else {
|
|
117
|
+
unlinkSync(settingsPath);
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
// Best effort
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Remove backup — successful restore means crash recovery is no longer needed
|
|
124
|
+
try { if (existsSync(backupPath)) unlinkSync(backupPath); } catch { /* ok */ }
|
|
125
|
+
|
|
126
|
+
this.savedClaudeSettings = null;
|
|
127
|
+
this.claudeSettingsInstalled = false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Write .mcp.json so Agent Teams teammates auto-discover the bouncer MCP server.
|
|
132
|
+
* Also generates ~/.mstro/mcp-config.json for the team lead (--mcp-config).
|
|
133
|
+
*/
|
|
134
|
+
installBouncerForSubagents(): void {
|
|
135
|
+
const mcpJsonPath = join(this.workingDir, '.mcp.json');
|
|
136
|
+
|
|
137
|
+
const backupPath = join(this.workingDir, '.mcp.json.pm-backup');
|
|
138
|
+
try {
|
|
139
|
+
const generatedPath = generateMcpConfig(this.workingDir);
|
|
140
|
+
if (!generatedPath) return;
|
|
141
|
+
|
|
142
|
+
const mcpConfig = readFileSync(generatedPath, 'utf-8');
|
|
143
|
+
|
|
144
|
+
if (existsSync(mcpJsonPath)) {
|
|
145
|
+
this.savedMcpJson = readFileSync(mcpJsonPath, 'utf-8');
|
|
146
|
+
writeFileSync(backupPath, this.savedMcpJson);
|
|
147
|
+
|
|
148
|
+
const existing = JSON.parse(this.savedMcpJson);
|
|
149
|
+
const generated = JSON.parse(mcpConfig);
|
|
150
|
+
existing.mcpServers = {
|
|
151
|
+
...existing.mcpServers,
|
|
152
|
+
'mstro-bouncer': generated.mcpServers['mstro-bouncer'],
|
|
153
|
+
};
|
|
154
|
+
writeFileSync(mcpJsonPath, JSON.stringify(existing, null, 2));
|
|
155
|
+
} else {
|
|
156
|
+
writeFileSync(backupPath, '__NONE__');
|
|
157
|
+
writeFileSync(mcpJsonPath, mcpConfig);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.mcpJsonInstalled = true;
|
|
161
|
+
} catch {
|
|
162
|
+
// Non-fatal: parent has MCP via --mcp-config, teammates fall back to PreToolUse hooks
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Restore or remove .mcp.json after execution. */
|
|
167
|
+
uninstallBouncerForSubagents(): void {
|
|
168
|
+
if (!this.mcpJsonInstalled) return;
|
|
169
|
+
const mcpJsonPath = join(this.workingDir, '.mcp.json');
|
|
170
|
+
const backupPath = join(this.workingDir, '.mcp.json.pm-backup');
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
if (this.savedMcpJson !== null) {
|
|
174
|
+
writeFileSync(mcpJsonPath, this.savedMcpJson);
|
|
175
|
+
} else {
|
|
176
|
+
unlinkSync(mcpJsonPath);
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
// Best effort cleanup
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
try { if (existsSync(backupPath)) unlinkSync(backupPath); } catch { /* ok */ }
|
|
183
|
+
|
|
184
|
+
this.savedMcpJson = null;
|
|
185
|
+
this.mcpJsonInstalled = false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -84,7 +84,7 @@ function dfs(
|
|
|
84
84
|
*
|
|
85
85
|
* If epicScope is provided, only returns issues belonging to that epic.
|
|
86
86
|
*/
|
|
87
|
-
export function resolveReadyToWork(issues: Issue[], epicScope?: string): Issue[] {
|
|
87
|
+
export function resolveReadyToWork(issues: Issue[], epicScope?: string, sprintScope?: string): Issue[] {
|
|
88
88
|
const issueByPath = new Map<string, Issue>();
|
|
89
89
|
for (const issue of issues) {
|
|
90
90
|
issueByPath.set(issue.path, issue);
|
|
@@ -116,6 +116,9 @@ export function resolveReadyToWork(issues: Issue[], epicScope?: string): Issue[]
|
|
|
116
116
|
// If scoped to an epic, only include that epic's children
|
|
117
117
|
if (epicChildPaths && !epicChildPaths.has(issue.path)) return false;
|
|
118
118
|
|
|
119
|
+
// If scoped to a sprint, only include issues assigned to that sprint
|
|
120
|
+
if (sprintScope && issue.sprint !== sprintScope) return false;
|
|
121
|
+
|
|
119
122
|
// Check all blockers are resolved
|
|
120
123
|
if (issue.blockedBy.length > 0) {
|
|
121
124
|
const allResolved = issue.blockedBy.every(bp => {
|