mstro-app 0.4.52 → 0.5.1
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/LICENSE +129 -190
- package/PRIVACY.md +3 -3
- package/README.md +15 -6
- package/bin/commands/config.js +0 -1
- package/bin/mstro.js +1 -2
- package/bin/postinstall.js +0 -1
- package/dist/server/cli/headless/claude-invoker-process.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker-process.js +0 -1
- package/dist/server/cli/headless/claude-invoker-process.js.map +1 -1
- package/dist/server/cli/headless/claude-invoker-stall.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker-stall.js +7 -3
- package/dist/server/cli/headless/claude-invoker-stall.js.map +1 -1
- package/dist/server/cli/headless/claude-invoker-stream.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker-stream.js +0 -1
- package/dist/server/cli/headless/claude-invoker-stream.js.map +1 -1
- package/dist/server/cli/headless/claude-invoker-tools.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker-tools.js +0 -1
- package/dist/server/cli/headless/claude-invoker-tools.js.map +1 -1
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +1 -2
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/haiku-assessments.d.ts.map +1 -1
- package/dist/server/cli/headless/haiku-assessments.js +0 -1
- package/dist/server/cli/headless/haiku-assessments.js.map +1 -1
- package/dist/server/cli/headless/headless-logger.d.ts.map +1 -1
- package/dist/server/cli/headless/headless-logger.js +0 -1
- package/dist/server/cli/headless/headless-logger.js.map +1 -1
- package/dist/server/cli/headless/index.d.ts.map +1 -1
- package/dist/server/cli/headless/index.js +0 -1
- package/dist/server/cli/headless/index.js.map +1 -1
- package/dist/server/cli/headless/native-timeout-detector.d.ts.map +1 -1
- package/dist/server/cli/headless/native-timeout-detector.js +0 -1
- package/dist/server/cli/headless/native-timeout-detector.js.map +1 -1
- package/dist/server/cli/headless/output-utils.d.ts.map +1 -1
- package/dist/server/cli/headless/output-utils.js +0 -1
- package/dist/server/cli/headless/output-utils.js.map +1 -1
- package/dist/server/cli/headless/prompt-utils.d.ts.map +1 -1
- package/dist/server/cli/headless/prompt-utils.js +0 -1
- package/dist/server/cli/headless/prompt-utils.js.map +1 -1
- package/dist/server/cli/headless/resilient-runner.d.ts.map +1 -1
- package/dist/server/cli/headless/resilient-runner.js +0 -1
- package/dist/server/cli/headless/resilient-runner.js.map +1 -1
- package/dist/server/cli/headless/retry-strategies.d.ts.map +1 -1
- package/dist/server/cli/headless/retry-strategies.js +0 -1
- package/dist/server/cli/headless/retry-strategies.js.map +1 -1
- package/dist/server/cli/headless/runner.d.ts.map +1 -1
- package/dist/server/cli/headless/runner.js +63 -68
- package/dist/server/cli/headless/runner.js.map +1 -1
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +9 -5
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.js +0 -1
- package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/headless/types.js +0 -1
- package/dist/server/cli/headless/types.js.map +1 -1
- package/dist/server/cli/improvisation-attachments.d.ts.map +1 -1
- package/dist/server/cli/improvisation-attachments.js +0 -1
- package/dist/server/cli/improvisation-attachments.js.map +1 -1
- package/dist/server/cli/improvisation-history-store.d.ts +16 -0
- package/dist/server/cli/improvisation-history-store.d.ts.map +1 -0
- package/dist/server/cli/improvisation-history-store.js +51 -0
- package/dist/server/cli/improvisation-history-store.js.map +1 -0
- package/dist/server/cli/improvisation-movements.d.ts +31 -0
- package/dist/server/cli/improvisation-movements.d.ts.map +1 -0
- package/dist/server/cli/improvisation-movements.js +92 -0
- package/dist/server/cli/improvisation-movements.js.map +1 -0
- package/dist/server/cli/improvisation-output-queue.d.ts +13 -0
- package/dist/server/cli/improvisation-output-queue.d.ts.map +1 -0
- package/dist/server/cli/improvisation-output-queue.js +39 -0
- package/dist/server/cli/improvisation-output-queue.js.map +1 -0
- package/dist/server/cli/improvisation-retry.d.ts +21 -51
- package/dist/server/cli/improvisation-retry.d.ts.map +1 -1
- package/dist/server/cli/improvisation-retry.js +18 -434
- package/dist/server/cli/improvisation-retry.js.map +1 -1
- package/dist/server/cli/improvisation-session-manager.d.ts +10 -8
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +53 -149
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/cli/improvisation-types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-types.js +0 -1
- package/dist/server/cli/improvisation-types.js.map +1 -1
- package/dist/server/cli/retry/retry-best-result.d.ts +4 -0
- package/dist/server/cli/retry/retry-best-result.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-best-result.js +60 -0
- package/dist/server/cli/retry/retry-best-result.js.map +1 -0
- package/dist/server/cli/retry/retry-context-loss.d.ts +6 -0
- package/dist/server/cli/retry/retry-context-loss.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-context-loss.js +67 -0
- package/dist/server/cli/retry/retry-context-loss.js.map +1 -0
- package/dist/server/cli/retry/retry-premature-completion.d.ts +5 -0
- package/dist/server/cli/retry/retry-premature-completion.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-premature-completion.js +80 -0
- package/dist/server/cli/retry/retry-premature-completion.js.map +1 -0
- package/dist/server/cli/retry/retry-recovery-strategies.d.ts +13 -0
- package/dist/server/cli/retry/retry-recovery-strategies.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-recovery-strategies.js +165 -0
- package/dist/server/cli/retry/retry-recovery-strategies.js.map +1 -0
- package/dist/server/cli/retry/retry-resume-strategy.d.ts +12 -0
- package/dist/server/cli/retry/retry-resume-strategy.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-resume-strategy.js +21 -0
- package/dist/server/cli/retry/retry-resume-strategy.js.map +1 -0
- package/dist/server/cli/retry/retry-runner-factory.d.ts +11 -0
- package/dist/server/cli/retry/retry-runner-factory.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-runner-factory.js +59 -0
- package/dist/server/cli/retry/retry-runner-factory.js.map +1 -0
- package/dist/server/cli/retry/retry-tool-results.d.ts +9 -0
- package/dist/server/cli/retry/retry-tool-results.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-tool-results.js +23 -0
- package/dist/server/cli/retry/retry-tool-results.js.map +1 -0
- package/dist/server/cli/retry/retry-types.d.ts +30 -0
- package/dist/server/cli/retry/retry-types.d.ts.map +1 -0
- package/dist/server/cli/retry/retry-types.js +3 -0
- package/dist/server/cli/retry/retry-types.js.map +1 -0
- package/dist/server/index.js +21 -110
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-cli.js +0 -1
- package/dist/server/mcp/bouncer-cli.js.map +1 -1
- package/dist/server/mcp/bouncer-haiku.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-haiku.js +0 -1
- package/dist/server/mcp/bouncer-haiku.js.map +1 -1
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +0 -1
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/security-analysis.d.ts.map +1 -1
- package/dist/server/mcp/security-analysis.js +0 -1
- package/dist/server/mcp/security-analysis.js.map +1 -1
- package/dist/server/mcp/security-audit.d.ts.map +1 -1
- package/dist/server/mcp/security-audit.js +0 -1
- package/dist/server/mcp/security-audit.js.map +1 -1
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +0 -1
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/mcp/server.js +0 -1
- package/dist/server/mcp/server.js.map +1 -1
- package/dist/server/routes/files.d.ts.map +1 -1
- package/dist/server/routes/files.js +0 -1
- package/dist/server/routes/files.js.map +1 -1
- package/dist/server/routes/improvise.d.ts.map +1 -1
- package/dist/server/routes/improvise.js +0 -1
- package/dist/server/routes/improvise.js.map +1 -1
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +0 -1
- package/dist/server/routes/index.js.map +1 -1
- package/dist/server/routes/instances.d.ts.map +1 -1
- package/dist/server/routes/instances.js +0 -1
- package/dist/server/routes/instances.js.map +1 -1
- package/dist/server/routes/notifications.d.ts.map +1 -1
- package/dist/server/routes/notifications.js +0 -1
- package/dist/server/routes/notifications.js.map +1 -1
- package/dist/server/server-setup.d.ts +16 -1
- package/dist/server/server-setup.d.ts.map +1 -1
- package/dist/server/server-setup.js +107 -1
- package/dist/server/server-setup.js.map +1 -1
- package/dist/server/services/analytics.d.ts.map +1 -1
- package/dist/server/services/analytics.js +0 -1
- package/dist/server/services/analytics.js.map +1 -1
- package/dist/server/services/auth.d.ts.map +1 -1
- package/dist/server/services/auth.js +0 -1
- package/dist/server/services/auth.js.map +1 -1
- package/dist/server/services/client-id.d.ts.map +1 -1
- package/dist/server/services/client-id.js +0 -1
- package/dist/server/services/client-id.js.map +1 -1
- package/dist/server/services/file-explorer-ops.d.ts.map +1 -1
- package/dist/server/services/file-explorer-ops.js +0 -1
- package/dist/server/services/file-explorer-ops.js.map +1 -1
- package/dist/server/services/files.d.ts.map +1 -1
- package/dist/server/services/files.js +0 -1
- package/dist/server/services/files.js.map +1 -1
- package/dist/server/services/instances.d.ts.map +1 -1
- package/dist/server/services/instances.js +0 -1
- package/dist/server/services/instances.js.map +1 -1
- package/dist/server/services/pathUtils.d.ts.map +1 -1
- package/dist/server/services/pathUtils.js +0 -1
- package/dist/server/services/pathUtils.js.map +1 -1
- package/dist/server/services/plan/agent-loader.d.ts.map +1 -1
- package/dist/server/services/plan/agent-loader.js +0 -1
- package/dist/server/services/plan/agent-loader.js.map +1 -1
- package/dist/server/services/plan/board-config.d.ts +21 -0
- package/dist/server/services/plan/board-config.d.ts.map +1 -0
- package/dist/server/services/plan/board-config.js +111 -0
- package/dist/server/services/plan/board-config.js.map +1 -0
- 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 +7 -6
- package/dist/server/services/plan/composer.js.map +1 -1
- package/dist/server/services/plan/config-installer.d.ts.map +1 -1
- package/dist/server/services/plan/config-installer.js +0 -1
- package/dist/server/services/plan/config-installer.js.map +1 -1
- package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -1
- package/dist/server/services/plan/dependency-resolver.js +0 -1
- package/dist/server/services/plan/dependency-resolver.js.map +1 -1
- package/dist/server/services/plan/executor.d.ts +48 -48
- package/dist/server/services/plan/executor.d.ts.map +1 -1
- package/dist/server/services/plan/executor.js +202 -458
- package/dist/server/services/plan/executor.js.map +1 -1
- package/dist/server/services/plan/front-matter.d.ts.map +1 -1
- package/dist/server/services/plan/front-matter.js +0 -1
- package/dist/server/services/plan/front-matter.js.map +1 -1
- package/dist/server/services/plan/issue-classification.d.ts.map +1 -1
- package/dist/server/services/plan/issue-classification.js +0 -1
- package/dist/server/services/plan/issue-classification.js.map +1 -1
- package/dist/server/services/plan/issue-loader.d.ts +16 -0
- package/dist/server/services/plan/issue-loader.d.ts.map +1 -0
- package/dist/server/services/plan/issue-loader.js +45 -0
- package/dist/server/services/plan/issue-loader.js.map +1 -0
- package/dist/server/services/plan/issue-prompt-builder.d.ts.map +1 -1
- package/dist/server/services/plan/issue-prompt-builder.js +0 -1
- package/dist/server/services/plan/issue-prompt-builder.js.map +1 -1
- package/dist/server/services/plan/issue-retry.d.ts +3 -1
- package/dist/server/services/plan/issue-retry.d.ts.map +1 -1
- package/dist/server/services/plan/issue-retry.js +2 -1
- package/dist/server/services/plan/issue-retry.js.map +1 -1
- package/dist/server/services/plan/issue-writer.d.ts +34 -0
- package/dist/server/services/plan/issue-writer.d.ts.map +1 -0
- package/dist/server/services/plan/issue-writer.js +109 -0
- package/dist/server/services/plan/issue-writer.js.map +1 -0
- package/dist/server/services/plan/output-manager.js +2 -2
- package/dist/server/services/plan/output-manager.js.map +1 -1
- package/dist/server/services/plan/parser-core.d.ts.map +1 -1
- package/dist/server/services/plan/parser-core.js +0 -1
- package/dist/server/services/plan/parser-core.js.map +1 -1
- package/dist/server/services/plan/parser-migration.d.ts.map +1 -1
- package/dist/server/services/plan/parser-migration.js +0 -1
- package/dist/server/services/plan/parser-migration.js.map +1 -1
- package/dist/server/services/plan/parser.d.ts.map +1 -1
- package/dist/server/services/plan/parser.js +0 -1
- package/dist/server/services/plan/parser.js.map +1 -1
- package/dist/server/services/plan/progress-log.d.ts +11 -0
- package/dist/server/services/plan/progress-log.d.ts.map +1 -0
- package/dist/server/services/plan/progress-log.js +80 -0
- package/dist/server/services/plan/progress-log.js.map +1 -0
- package/dist/server/services/plan/prompt-builder.d.ts.map +1 -1
- package/dist/server/services/plan/prompt-builder.js +48 -32
- package/dist/server/services/plan/prompt-builder.js.map +1 -1
- package/dist/server/services/plan/readiness-planner.d.ts +15 -0
- package/dist/server/services/plan/readiness-planner.d.ts.map +1 -0
- package/dist/server/services/plan/readiness-planner.js +40 -0
- package/dist/server/services/plan/readiness-planner.js.map +1 -0
- package/dist/server/services/plan/review-gate.d.ts +31 -0
- package/dist/server/services/plan/review-gate.d.ts.map +1 -1
- package/dist/server/services/plan/review-gate.js +52 -3
- package/dist/server/services/plan/review-gate.js.map +1 -1
- package/dist/server/services/plan/state-reconciler.d.ts.map +1 -1
- package/dist/server/services/plan/state-reconciler.js +0 -1
- package/dist/server/services/plan/state-reconciler.js.map +1 -1
- package/dist/server/services/plan/types.d.ts.map +1 -1
- package/dist/server/services/plan/types.js +0 -1
- package/dist/server/services/plan/types.js.map +1 -1
- package/dist/server/services/plan/watcher.d.ts.map +1 -1
- package/dist/server/services/plan/watcher.js +0 -1
- package/dist/server/services/plan/watcher.js.map +1 -1
- package/dist/server/services/platform-credentials.d.ts.map +1 -1
- package/dist/server/services/platform-credentials.js +0 -1
- package/dist/server/services/platform-credentials.js.map +1 -1
- package/dist/server/services/platform-token-lifecycle.d.ts +70 -0
- package/dist/server/services/platform-token-lifecycle.d.ts.map +1 -0
- package/dist/server/services/platform-token-lifecycle.js +156 -0
- package/dist/server/services/platform-token-lifecycle.js.map +1 -0
- package/dist/server/services/platform.d.ts +25 -4
- package/dist/server/services/platform.d.ts.map +1 -1
- package/dist/server/services/platform.js +150 -92
- package/dist/server/services/platform.js.map +1 -1
- package/dist/server/services/sentry.d.ts.map +1 -1
- package/dist/server/services/sentry.js +0 -1
- package/dist/server/services/sentry.js.map +1 -1
- package/dist/server/services/settings.d.ts.map +1 -1
- package/dist/server/services/settings.js +0 -1
- package/dist/server/services/settings.js.map +1 -1
- package/dist/server/services/terminal/pty-manager.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-manager.js +0 -1
- package/dist/server/services/terminal/pty-manager.js.map +1 -1
- package/dist/server/services/terminal/pty-utils.d.ts.map +1 -1
- package/dist/server/services/terminal/pty-utils.js +0 -1
- package/dist/server/services/terminal/pty-utils.js.map +1 -1
- package/dist/server/services/websocket/autocomplete.d.ts.map +1 -1
- package/dist/server/services/websocket/autocomplete.js +0 -1
- package/dist/server/services/websocket/autocomplete.js.map +1 -1
- package/dist/server/services/websocket/file-definition-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/file-definition-handlers.js +0 -1
- package/dist/server/services/websocket/file-definition-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-download-handler.d.ts +17 -0
- package/dist/server/services/websocket/file-download-handler.d.ts.map +1 -0
- package/dist/server/services/websocket/file-download-handler.js +164 -0
- package/dist/server/services/websocket/file-download-handler.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 +0 -1
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-search-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/file-search-handlers.js +0 -1
- package/dist/server/services/websocket/file-search-handlers.js.map +1 -1
- package/dist/server/services/websocket/file-upload-handler.d.ts +2 -3
- package/dist/server/services/websocket/file-upload-handler.d.ts.map +1 -1
- package/dist/server/services/websocket/file-upload-handler.js +4 -7
- package/dist/server/services/websocket/file-upload-handler.js.map +1 -1
- package/dist/server/services/websocket/file-utils.d.ts.map +1 -1
- package/dist/server/services/websocket/file-utils.js +0 -1
- package/dist/server/services/websocket/file-utils.js.map +1 -1
- package/dist/server/services/websocket/git-branch-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-branch-handlers.js +0 -1
- package/dist/server/services/websocket/git-branch-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-diff-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-diff-handlers.js +0 -1
- package/dist/server/services/websocket/git-diff-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-handlers.js +58 -6
- package/dist/server/services/websocket/git-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-head-watcher.d.ts.map +1 -1
- package/dist/server/services/websocket/git-head-watcher.js +0 -1
- package/dist/server/services/websocket/git-head-watcher.js.map +1 -1
- package/dist/server/services/websocket/git-log-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-log-handlers.js +0 -1
- package/dist/server/services/websocket/git-log-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-pr-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-pr-handlers.js +0 -1
- package/dist/server/services/websocket/git-pr-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-tag-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-tag-handlers.js +0 -1
- package/dist/server/services/websocket/git-tag-handlers.js.map +1 -1
- package/dist/server/services/websocket/git-utils.d.ts +18 -3
- package/dist/server/services/websocket/git-utils.d.ts.map +1 -1
- package/dist/server/services/websocket/git-utils.js +58 -8
- package/dist/server/services/websocket/git-utils.js.map +1 -1
- package/dist/server/services/websocket/git-worktree-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/git-worktree-handlers.js +258 -16
- package/dist/server/services/websocket/git-worktree-handlers.js.map +1 -1
- package/dist/server/services/websocket/handler-context.d.ts +15 -0
- package/dist/server/services/websocket/handler-context.d.ts.map +1 -1
- package/dist/server/services/websocket/handler-context.js +0 -1
- package/dist/server/services/websocket/handler-context.js.map +1 -1
- package/dist/server/services/websocket/handler.d.ts +7 -0
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +76 -15
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/index.d.ts.map +1 -1
- package/dist/server/services/websocket/index.js +0 -1
- package/dist/server/services/websocket/index.js.map +1 -1
- package/dist/server/services/websocket/msg-id-tracker.d.ts +21 -0
- package/dist/server/services/websocket/msg-id-tracker.d.ts.map +1 -0
- package/dist/server/services/websocket/msg-id-tracker.js +76 -0
- package/dist/server/services/websocket/msg-id-tracker.js.map +1 -0
- package/dist/server/services/websocket/plan-board-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-board-handlers.js +0 -1
- package/dist/server/services/websocket/plan-board-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-execution-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-execution-handlers.js +6 -2
- package/dist/server/services/websocket/plan-execution-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-handlers.js +0 -1
- package/dist/server/services/websocket/plan-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-helpers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-helpers.js +0 -1
- package/dist/server/services/websocket/plan-helpers.js.map +1 -1
- package/dist/server/services/websocket/plan-issue-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-issue-handlers.js +0 -1
- package/dist/server/services/websocket/plan-issue-handlers.js.map +1 -1
- package/dist/server/services/websocket/plan-sprint-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/plan-sprint-handlers.js +0 -1
- package/dist/server/services/websocket/plan-sprint-handlers.js.map +1 -1
- package/dist/server/services/websocket/quality-complexity.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-complexity.js +0 -1
- package/dist/server/services/websocket/quality-complexity.js.map +1 -1
- package/dist/server/services/websocket/quality-grading.d.ts +46 -0
- package/dist/server/services/websocket/quality-grading.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-grading.js +482 -0
- package/dist/server/services/websocket/quality-grading.js.map +1 -0
- package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-handlers.js +15 -4
- package/dist/server/services/websocket/quality-handlers.js.map +1 -1
- package/dist/server/services/websocket/quality-linting.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-linting.js +0 -1
- package/dist/server/services/websocket/quality-linting.js.map +1 -1
- package/dist/server/services/websocket/quality-persistence.d.ts +14 -0
- package/dist/server/services/websocket/quality-persistence.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-persistence.js +28 -12
- package/dist/server/services/websocket/quality-persistence.js.map +1 -1
- package/dist/server/services/websocket/quality-review-agent.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-review-agent.js +2 -3
- package/dist/server/services/websocket/quality-review-agent.js.map +1 -1
- package/dist/server/services/websocket/quality-service.d.ts +3 -1
- package/dist/server/services/websocket/quality-service.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-service.js +53 -58
- package/dist/server/services/websocket/quality-service.js.map +1 -1
- package/dist/server/services/websocket/quality-tools.d.ts +1 -1
- package/dist/server/services/websocket/quality-tools.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-tools.js +6 -3
- package/dist/server/services/websocket/quality-tools.js.map +1 -1
- package/dist/server/services/websocket/quality-types.d.ts +18 -2
- package/dist/server/services/websocket/quality-types.d.ts.map +1 -1
- package/dist/server/services/websocket/quality-types.js +0 -1
- package/dist/server/services/websocket/quality-types.js.map +1 -1
- package/dist/server/services/websocket/session-handlers.d.ts +48 -2
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/session-handlers.js +204 -66
- package/dist/server/services/websocket/session-handlers.js.map +1 -1
- package/dist/server/services/websocket/session-history.d.ts.map +1 -1
- package/dist/server/services/websocket/session-history.js +0 -1
- package/dist/server/services/websocket/session-history.js.map +1 -1
- package/dist/server/services/websocket/session-initialization.d.ts +2 -2
- package/dist/server/services/websocket/session-initialization.d.ts.map +1 -1
- package/dist/server/services/websocket/session-initialization.js +75 -18
- package/dist/server/services/websocket/session-initialization.js.map +1 -1
- package/dist/server/services/websocket/session-registry.d.ts +29 -1
- package/dist/server/services/websocket/session-registry.d.ts.map +1 -1
- package/dist/server/services/websocket/session-registry.js +53 -5
- package/dist/server/services/websocket/session-registry.js.map +1 -1
- package/dist/server/services/websocket/settings-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/settings-handlers.js +0 -1
- package/dist/server/services/websocket/settings-handlers.js.map +1 -1
- package/dist/server/services/websocket/skill-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/skill-handlers.js +0 -1
- package/dist/server/services/websocket/skill-handlers.js.map +1 -1
- package/dist/server/services/websocket/skill-watcher.d.ts.map +1 -1
- package/dist/server/services/websocket/skill-watcher.js +0 -1
- package/dist/server/services/websocket/skill-watcher.js.map +1 -1
- package/dist/server/services/websocket/tab-broadcast.d.ts +24 -0
- package/dist/server/services/websocket/tab-broadcast.d.ts.map +1 -0
- package/dist/server/services/websocket/tab-broadcast.js +12 -0
- package/dist/server/services/websocket/tab-broadcast.js.map +1 -0
- package/dist/server/services/websocket/tab-event-buffer.d.ts +103 -0
- package/dist/server/services/websocket/tab-event-buffer.d.ts.map +1 -0
- package/dist/server/services/websocket/tab-event-buffer.js +106 -0
- package/dist/server/services/websocket/tab-event-buffer.js.map +1 -0
- package/dist/server/services/websocket/tab-event-replay.d.ts +20 -0
- package/dist/server/services/websocket/tab-event-replay.d.ts.map +1 -0
- package/dist/server/services/websocket/tab-event-replay.js +20 -0
- package/dist/server/services/websocket/tab-event-replay.js.map +1 -0
- package/dist/server/services/websocket/tab-handlers.d.ts +0 -1
- package/dist/server/services/websocket/tab-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/tab-handlers.js +2 -10
- package/dist/server/services/websocket/tab-handlers.js.map +1 -1
- package/dist/server/services/websocket/terminal-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/terminal-handlers.js +39 -4
- package/dist/server/services/websocket/terminal-handlers.js.map +1 -1
- package/dist/server/services/websocket/types.d.ts +17 -8
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/dist/server/services/websocket/types.js +8 -7
- package/dist/server/services/websocket/types.js.map +1 -1
- package/dist/server/utils/agent-manager.d.ts.map +1 -1
- package/dist/server/utils/agent-manager.js +0 -1
- package/dist/server/utils/agent-manager.js.map +1 -1
- package/dist/server/utils/paths.d.ts.map +1 -1
- package/dist/server/utils/paths.js +0 -1
- package/dist/server/utils/paths.js.map +1 -1
- package/dist/server/utils/port-manager.d.ts.map +1 -1
- package/dist/server/utils/port-manager.js +0 -1
- package/dist/server/utils/port-manager.js.map +1 -1
- package/dist/server/utils/port.d.ts.map +1 -1
- package/dist/server/utils/port.js +0 -1
- package/dist/server/utils/port.js.map +1 -1
- package/package.json +2 -2
- package/server/README.md +1 -1
- package/server/cli/headless/claude-invoker-process.ts +0 -1
- package/server/cli/headless/claude-invoker-stall.ts +7 -3
- package/server/cli/headless/claude-invoker-stream.ts +0 -1
- package/server/cli/headless/claude-invoker-tools.ts +0 -1
- package/server/cli/headless/claude-invoker.ts +1 -2
- package/server/cli/headless/haiku-assessments.ts +0 -1
- package/server/cli/headless/headless-logger.ts +0 -1
- package/server/cli/headless/index.ts +0 -1
- package/server/cli/headless/native-timeout-detector.ts +0 -1
- package/server/cli/headless/output-utils.ts +0 -1
- package/server/cli/headless/prompt-utils.ts +0 -1
- package/server/cli/headless/resilient-runner.ts +0 -1
- package/server/cli/headless/retry-strategies.ts +0 -1
- package/server/cli/headless/runner.ts +67 -73
- package/server/cli/headless/stall-assessor.ts +9 -5
- package/server/cli/headless/tool-watchdog.ts +0 -1
- package/server/cli/headless/types.ts +1 -2
- package/server/cli/improvisation-attachments.ts +0 -1
- package/server/cli/improvisation-history-store.ts +61 -0
- package/server/cli/improvisation-movements.ts +119 -0
- package/server/cli/improvisation-output-queue.ts +41 -0
- package/server/cli/improvisation-retry.ts +25 -601
- package/server/cli/improvisation-session-manager.ts +74 -161
- package/server/cli/improvisation-types.ts +0 -1
- package/server/cli/retry/retry-best-result.ts +69 -0
- package/server/cli/retry/retry-context-loss.ts +86 -0
- package/server/cli/retry/retry-premature-completion.ts +112 -0
- package/server/cli/retry/retry-recovery-strategies.ts +246 -0
- package/server/cli/retry/retry-resume-strategy.ts +32 -0
- package/server/cli/retry/retry-runner-factory.ts +69 -0
- package/server/cli/retry/retry-tool-results.ts +30 -0
- package/server/cli/retry/retry-types.ts +31 -0
- package/server/index.ts +37 -124
- package/server/mcp/bouncer-cli.ts +0 -1
- package/server/mcp/bouncer-haiku.ts +0 -1
- package/server/mcp/bouncer-integration.ts +0 -1
- package/server/mcp/security-analysis.ts +0 -1
- package/server/mcp/security-audit.ts +0 -1
- package/server/mcp/security-patterns.ts +0 -1
- package/server/mcp/server.ts +0 -1
- package/server/routes/files.ts +0 -1
- package/server/routes/improvise.ts +0 -1
- package/server/routes/index.ts +0 -1
- package/server/routes/instances.ts +0 -1
- package/server/routes/notifications.ts +0 -1
- package/server/server-setup.ts +126 -2
- package/server/services/analytics.ts +0 -1
- package/server/services/auth.ts +0 -1
- package/server/services/client-id.ts +0 -1
- package/server/services/file-explorer-ops.ts +0 -1
- package/server/services/files.ts +0 -1
- package/server/services/instances.ts +0 -1
- package/server/services/pathUtils.ts +0 -1
- package/server/services/plan/agent-loader.ts +0 -1
- package/server/services/plan/agents/assess-stall.md +11 -4
- package/server/services/plan/agents/code-review.md +13 -11
- package/server/services/plan/board-config.ts +121 -0
- package/server/services/plan/composer.ts +7 -6
- package/server/services/plan/config-installer.ts +0 -1
- package/server/services/plan/dependency-resolver.ts +0 -1
- package/server/services/plan/executor.ts +259 -470
- package/server/services/plan/front-matter.ts +0 -1
- package/server/services/plan/issue-classification.ts +0 -1
- package/server/services/plan/issue-loader.ts +63 -0
- package/server/services/plan/issue-prompt-builder.ts +0 -1
- package/server/services/plan/issue-retry.ts +5 -2
- package/server/services/plan/issue-writer.ts +136 -0
- package/server/services/plan/output-manager.ts +2 -2
- package/server/services/plan/parser-core.ts +0 -1
- package/server/services/plan/parser-migration.ts +0 -1
- package/server/services/plan/parser.ts +0 -1
- package/server/services/plan/progress-log.ts +91 -0
- package/server/services/plan/prompt-builder.ts +73 -36
- package/server/services/plan/readiness-planner.ts +49 -0
- package/server/services/plan/review-gate.ts +102 -3
- package/server/services/plan/state-reconciler.ts +0 -1
- package/server/services/plan/types.ts +0 -1
- package/server/services/plan/watcher.ts +0 -1
- package/server/services/platform-credentials.ts +0 -1
- package/server/services/platform-token-lifecycle.ts +171 -0
- package/server/services/platform.ts +168 -105
- package/server/services/sentry.ts +0 -1
- package/server/services/settings.ts +0 -1
- package/server/services/terminal/pty-manager.ts +0 -1
- package/server/services/terminal/pty-utils.ts +0 -1
- package/server/services/websocket/autocomplete.ts +0 -1
- package/server/services/websocket/file-definition-handlers.ts +0 -1
- package/server/services/websocket/file-download-handler.ts +190 -0
- package/server/services/websocket/file-explorer-handlers.ts +0 -1
- package/server/services/websocket/file-search-handlers.ts +0 -1
- package/server/services/websocket/file-upload-handler.ts +6 -5
- package/server/services/websocket/file-utils.ts +0 -1
- package/server/services/websocket/git-branch-handlers.ts +0 -1
- package/server/services/websocket/git-diff-handlers.ts +0 -1
- package/server/services/websocket/git-handlers.ts +66 -10
- package/server/services/websocket/git-head-watcher.ts +0 -1
- package/server/services/websocket/git-log-handlers.ts +0 -1
- package/server/services/websocket/git-pr-handlers.ts +0 -1
- package/server/services/websocket/git-tag-handlers.ts +0 -1
- package/server/services/websocket/git-utils.ts +69 -9
- package/server/services/websocket/git-worktree-handlers.ts +289 -19
- package/server/services/websocket/handler-context.ts +15 -1
- package/server/services/websocket/handler.ts +79 -16
- package/server/services/websocket/index.ts +0 -1
- package/server/services/websocket/msg-id-tracker.ts +83 -0
- package/server/services/websocket/plan-board-handlers.ts +0 -1
- package/server/services/websocket/plan-execution-handlers.ts +6 -2
- package/server/services/websocket/plan-handlers.ts +0 -1
- package/server/services/websocket/plan-helpers.ts +0 -1
- package/server/services/websocket/plan-issue-handlers.ts +0 -1
- package/server/services/websocket/plan-sprint-handlers.ts +0 -1
- package/server/services/websocket/quality-complexity.ts +0 -1
- package/server/services/websocket/quality-grading.ts +611 -0
- package/server/services/websocket/quality-handlers.ts +16 -4
- package/server/services/websocket/quality-linting.ts +0 -1
- package/server/services/websocket/quality-persistence.ts +30 -8
- package/server/services/websocket/quality-review-agent.ts +2 -3
- package/server/services/websocket/quality-service.ts +54 -55
- package/server/services/websocket/quality-tools.ts +11 -3
- package/server/services/websocket/quality-types.ts +21 -3
- package/server/services/websocket/session-handlers.ts +213 -69
- package/server/services/websocket/session-history.ts +0 -1
- package/server/services/websocket/session-initialization.ts +83 -20
- package/server/services/websocket/session-registry.ts +61 -5
- package/server/services/websocket/settings-handlers.ts +0 -1
- package/server/services/websocket/skill-handlers.ts +0 -1
- package/server/services/websocket/skill-watcher.ts +0 -1
- package/server/services/websocket/tab-broadcast.ts +37 -0
- package/server/services/websocket/tab-event-buffer.ts +158 -0
- package/server/services/websocket/tab-event-replay.ts +41 -0
- package/server/services/websocket/tab-handlers.ts +2 -10
- package/server/services/websocket/terminal-handlers.ts +39 -3
- package/server/services/websocket/types.ts +19 -7
- package/server/utils/agent-manager.ts +0 -1
- package/server/utils/paths.ts +0 -1
- package/server/utils/port-manager.ts +0 -1
- package/server/utils/port.ts +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Issue loader: wraps parser.ts to load either board-scoped or
|
|
5
|
+
* project-level issues, emitting error/activation signals via callbacks
|
|
6
|
+
* so it stays decoupled from the EventEmitter in PlanExecutor.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { activateBoard } from './board-config.js';
|
|
10
|
+
import type { WarnFn } from './issue-writer.js';
|
|
11
|
+
import { parseBoardDirectory, parsePlanDirectory } from './parser.js';
|
|
12
|
+
import type { Issue } from './types.js';
|
|
13
|
+
|
|
14
|
+
export interface IssueLoaderHandlers {
|
|
15
|
+
/** Invoked when the board/project is in an unloadable state (not found, paused, etc.). */
|
|
16
|
+
onError: (message: string) => void;
|
|
17
|
+
/** Invoked to forward warnings from `activateBoard` side-effects. */
|
|
18
|
+
warn: WarnFn;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Load issues from a specific board, auto-activating draft boards.
|
|
23
|
+
* Returns null on error (and invokes `handlers.onError`).
|
|
24
|
+
*/
|
|
25
|
+
export async function loadBoardIssues(
|
|
26
|
+
pmDir: string,
|
|
27
|
+
boardId: string,
|
|
28
|
+
handlers: IssueLoaderHandlers,
|
|
29
|
+
): Promise<Issue[] | null> {
|
|
30
|
+
const boardState = parseBoardDirectory(pmDir, boardId);
|
|
31
|
+
if (!boardState) {
|
|
32
|
+
handlers.onError(`Board not found: ${boardId}`);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (boardState.state.paused) {
|
|
36
|
+
handlers.onError('Board is paused');
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
if (boardState.board.status === 'draft') {
|
|
40
|
+
await activateBoard(pmDir, boardId, handlers.warn);
|
|
41
|
+
} else if (boardState.board.status !== 'active') {
|
|
42
|
+
handlers.onError(`Board ${boardId} is not active (status: ${boardState.board.status})`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return boardState.issues;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Load project-level issues (legacy or no boards). Returns null on error. */
|
|
49
|
+
export function loadProjectIssues(
|
|
50
|
+
workingDir: string,
|
|
51
|
+
handlers: Pick<IssueLoaderHandlers, 'onError'>,
|
|
52
|
+
): Issue[] | null {
|
|
53
|
+
const fullState = parsePlanDirectory(workingDir);
|
|
54
|
+
if (!fullState) {
|
|
55
|
+
handlers.onError('No PM directory found');
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
if (fullState.state.paused) {
|
|
59
|
+
handlers.onError('Project is paused');
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return fullState.issues;
|
|
63
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
-
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
2
|
|
|
4
3
|
import { ResilientRunner } from '../../cli/headless/resilient-runner.js';
|
|
5
|
-
import type { SessionResult } from '../../cli/headless/types.js';
|
|
4
|
+
import type { SessionResult, ToolUseEvent } from '../../cli/headless/types.js';
|
|
6
5
|
|
|
7
6
|
export interface IssueRunnerConfig {
|
|
8
7
|
workingDir: string;
|
|
@@ -12,6 +11,8 @@ export interface IssueRunnerConfig {
|
|
|
12
11
|
stallHardCapMs: number;
|
|
13
12
|
stallMaxExtensions: number;
|
|
14
13
|
outputCallback?: (text: string) => void;
|
|
14
|
+
thinkingCallback?: (text: string) => void;
|
|
15
|
+
toolUseCallback?: (event: ToolUseEvent) => void;
|
|
15
16
|
extraEnv?: Record<string, string>;
|
|
16
17
|
abortSignal?: AbortSignal;
|
|
17
18
|
}
|
|
@@ -27,6 +28,8 @@ export async function runIssueWithRetry(config: IssueRunnerConfig): Promise<Sess
|
|
|
27
28
|
stallHardCapMs: config.stallHardCapMs,
|
|
28
29
|
stallMaxExtensions: config.stallMaxExtensions,
|
|
29
30
|
outputCallback: config.outputCallback,
|
|
31
|
+
thinkingCallback: config.thinkingCallback,
|
|
32
|
+
toolUseCallback: config.toolUseCallback,
|
|
30
33
|
verbose: true,
|
|
31
34
|
extraEnv: config.extraEnv,
|
|
32
35
|
abortSignal: config.abortSignal,
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Issue file mutations: front-matter status updates, activity note appends,
|
|
5
|
+
* stale-issue recovery, and wave-revert logic used by the plan executor.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
9
|
+
import { isAbsolute, relative, resolve } from 'node:path';
|
|
10
|
+
import { checkAllAcceptanceCriteria, setFrontMatterFieldAsync } from './front-matter.js';
|
|
11
|
+
import type { Issue } from './types.js';
|
|
12
|
+
|
|
13
|
+
/** Emits a warning message — caller typically maps this to executor 'output' events. */
|
|
14
|
+
export type WarnFn = (message: string, issueId?: string) => void;
|
|
15
|
+
|
|
16
|
+
/** Matches the `status: <value>` front-matter line (YAML-style, first occurrence). */
|
|
17
|
+
const STATUS_LINE_PATTERN = /^status:\s*(\S+)/m;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Extract the `status:` front-matter value from an issue-file body. Returns
|
|
21
|
+
* `null` if the field is missing or malformed. Lives here alongside the other
|
|
22
|
+
* front-matter mutators so all modules parse the status identically.
|
|
23
|
+
*/
|
|
24
|
+
export function extractIssueStatus(content: string): string | null {
|
|
25
|
+
return content.match(STATUS_LINE_PATTERN)?.[1] ?? null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Resolve an issue's relative path against a base directory, ensuring it
|
|
30
|
+
* stays inside the base (guards against `..` and absolute-path escapes).
|
|
31
|
+
*/
|
|
32
|
+
export function validateIssuePath(issuePath: string, baseDir: string): string {
|
|
33
|
+
const resolvedBase = resolve(baseDir);
|
|
34
|
+
const resolvedFull = resolve(resolvedBase, issuePath);
|
|
35
|
+
const rel = relative(resolvedBase, resolvedFull);
|
|
36
|
+
if (rel === '' || rel.startsWith('..') || isAbsolute(rel)) {
|
|
37
|
+
throw new Error(`Invalid issue path: path traversal detected in "${issuePath}"`);
|
|
38
|
+
}
|
|
39
|
+
return resolvedFull;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Update an issue's `status:` front-matter field, and — when transitioning
|
|
44
|
+
* to `done` — check off any remaining acceptance-criteria checkboxes.
|
|
45
|
+
*/
|
|
46
|
+
export async function updateIssueFrontMatter(
|
|
47
|
+
pmDir: string,
|
|
48
|
+
issuePath: string,
|
|
49
|
+
newStatus: string,
|
|
50
|
+
warn: WarnFn,
|
|
51
|
+
): Promise<void> {
|
|
52
|
+
try {
|
|
53
|
+
const fullPath = validateIssuePath(issuePath, pmDir);
|
|
54
|
+
await setFrontMatterFieldAsync(fullPath, 'status', newStatus);
|
|
55
|
+
|
|
56
|
+
if (newStatus === 'done') {
|
|
57
|
+
const content = await readFile(fullPath, 'utf-8');
|
|
58
|
+
const updated = checkAllAcceptanceCriteria(content);
|
|
59
|
+
if (updated !== content) await writeFile(fullPath, updated, 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
warn(`Warning: failed to update issue front matter for ${issuePath}: ${errMsg(err)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* After a wave fails, revert any issue still stuck in `in_progress` back to
|
|
68
|
+
* its pre-wave status. Silently skips issues already out of `in_progress`.
|
|
69
|
+
*/
|
|
70
|
+
export async function revertIncompleteIssues(
|
|
71
|
+
pmDir: string,
|
|
72
|
+
issues: Issue[],
|
|
73
|
+
warn: WarnFn,
|
|
74
|
+
): Promise<void> {
|
|
75
|
+
for (const issue of issues) {
|
|
76
|
+
const fullPath = validateIssuePath(issue.path, pmDir);
|
|
77
|
+
try {
|
|
78
|
+
const content = await readFile(fullPath, 'utf-8');
|
|
79
|
+
if (extractIssueStatus(content) === 'in_progress') {
|
|
80
|
+
await updateIssueFrontMatter(pmDir, issue.path, issue.status, warn);
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
warn(`Warning: failed to revert issue status: ${errMsg(err)}`, issue.id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Append a cancellation note to the issue's `## Activity` section. */
|
|
89
|
+
export async function appendCancellationNote(
|
|
90
|
+
pmDir: string,
|
|
91
|
+
issue: Issue,
|
|
92
|
+
reason: string,
|
|
93
|
+
warn: WarnFn,
|
|
94
|
+
): Promise<void> {
|
|
95
|
+
const fullPath = validateIssuePath(issue.path, pmDir);
|
|
96
|
+
try {
|
|
97
|
+
let content = await readFile(fullPath, 'utf-8');
|
|
98
|
+
const entry = `- Cancelled (${new Date().toISOString().split('T')[0]}): ${reason}`;
|
|
99
|
+
if (content.includes('## Activity')) {
|
|
100
|
+
content = content.replace(/## Activity/, `## Activity\n${entry}`);
|
|
101
|
+
} else {
|
|
102
|
+
content += `\n\n## Activity\n${entry}`;
|
|
103
|
+
}
|
|
104
|
+
await writeFile(fullPath, content, 'utf-8');
|
|
105
|
+
} catch (err) {
|
|
106
|
+
warn(`Warning: failed to append cancellation note: ${errMsg(err)}`, issue.id);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Recover from a previous interrupted execution by reverting stale
|
|
112
|
+
* `in_progress` and `in_review` issues back to `todo`. Returns the list of
|
|
113
|
+
* recovered issue descriptors (e.g. "FEAT-012 (in_progress → todo)") so the
|
|
114
|
+
* caller can emit a single summary event.
|
|
115
|
+
*/
|
|
116
|
+
export async function recoverStaleIssues(
|
|
117
|
+
pmDir: string,
|
|
118
|
+
issues: Issue[],
|
|
119
|
+
warn: WarnFn,
|
|
120
|
+
): Promise<string[]> {
|
|
121
|
+
const staleStatuses = new Set(['in_progress', 'in_review']);
|
|
122
|
+
const recovered: string[] = [];
|
|
123
|
+
|
|
124
|
+
for (const issue of issues) {
|
|
125
|
+
if (issue.type === 'epic') continue;
|
|
126
|
+
if (staleStatuses.has(issue.status)) {
|
|
127
|
+
await updateIssueFrontMatter(pmDir, issue.path, 'todo', warn);
|
|
128
|
+
recovered.push(`${issue.id} (${issue.status} → todo)`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return recovered;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function errMsg(err: unknown): string {
|
|
135
|
+
return err instanceof Error ? err.message : String(err);
|
|
136
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
-
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Output Manager — Resolves output paths, lists existing docs, and publishes outputs.
|
|
@@ -9,6 +8,7 @@
|
|
|
9
8
|
|
|
10
9
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync } from 'node:fs';
|
|
11
10
|
import { join, resolve } from 'node:path';
|
|
11
|
+
import { extractIssueStatus } from './issue-writer.js';
|
|
12
12
|
import { defaultPmDir, resolvePmDir } from './parser.js';
|
|
13
13
|
import type { Issue } from './types.js';
|
|
14
14
|
|
|
@@ -90,7 +90,7 @@ function publishSingleOutput(
|
|
|
90
90
|
// Only publish for confirmed-done issues
|
|
91
91
|
try {
|
|
92
92
|
const content = readFileSync(join(pmDir, issue.path), 'utf-8');
|
|
93
|
-
if (
|
|
93
|
+
if (extractIssueStatus(content) !== 'done') return;
|
|
94
94
|
} catch { return; }
|
|
95
95
|
|
|
96
96
|
const srcPath = resolveOutputPath(issue, workingDir, sprintSandboxDir);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Progress log writer: ensures output directories exist and appends
|
|
5
|
+
* per-wave markdown entries to the board or PM-dir progress.md.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { validateIssuePath, type WarnFn } from './issue-writer.js';
|
|
12
|
+
import type { Issue } from './types.js';
|
|
13
|
+
|
|
14
|
+
/** Create the board's or PM dir's `out/` directory if it doesn't exist. */
|
|
15
|
+
export async function ensureOutputDirs(pmDir: string | null, boardDir: string | null): Promise<void> {
|
|
16
|
+
if (boardDir) {
|
|
17
|
+
const boardOutDir = join(boardDir, 'out');
|
|
18
|
+
if (!existsSync(boardOutDir)) await mkdir(boardOutDir, { recursive: true });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (pmDir) {
|
|
22
|
+
const outDir = join(pmDir, 'out');
|
|
23
|
+
if (!existsSync(outDir)) await mkdir(outDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Append a wave summary section to progress.md (creating the file with a
|
|
29
|
+
* `# Board Progress` header if missing). Reads each issue's on-disk status
|
|
30
|
+
* to partition completed vs failed.
|
|
31
|
+
*/
|
|
32
|
+
export async function appendProgressEntry(
|
|
33
|
+
pmDir: string | null,
|
|
34
|
+
boardDir: string | null,
|
|
35
|
+
issues: Issue[],
|
|
36
|
+
waveStart: number,
|
|
37
|
+
warn: WarnFn,
|
|
38
|
+
): Promise<void> {
|
|
39
|
+
if (!pmDir) return;
|
|
40
|
+
|
|
41
|
+
const progressPath = boardDir ? join(boardDir, 'progress.md') : join(pmDir, 'progress.md');
|
|
42
|
+
const durationMin = Math.round((Date.now() - waveStart) / 60_000);
|
|
43
|
+
const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 16);
|
|
44
|
+
|
|
45
|
+
const { completed, failed } = await partitionByOnDiskStatus(pmDir, issues);
|
|
46
|
+
|
|
47
|
+
const lines = [
|
|
48
|
+
'',
|
|
49
|
+
`## ${timestamp} — Wave [${issues.map(i => i.id).join(', ')}]`,
|
|
50
|
+
'',
|
|
51
|
+
`- **Duration**: ${durationMin} min`,
|
|
52
|
+
`- **Completed**: ${completed.length}/${issues.length}${completed.length > 0 ? ` (${completed.join(', ')})` : ''}`,
|
|
53
|
+
];
|
|
54
|
+
if (failed.length > 0) {
|
|
55
|
+
lines.push(`- **Failed**: ${failed.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
lines.push('');
|
|
58
|
+
|
|
59
|
+
await writeProgressLines(progressPath, lines, warn);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function partitionByOnDiskStatus(
|
|
63
|
+
pmDir: string,
|
|
64
|
+
issues: Issue[],
|
|
65
|
+
): Promise<{ completed: string[]; failed: string[] }> {
|
|
66
|
+
const completed: string[] = [];
|
|
67
|
+
const failed: string[] = [];
|
|
68
|
+
for (const issue of issues) {
|
|
69
|
+
try {
|
|
70
|
+
const content = await readFile(validateIssuePath(issue.path, pmDir), 'utf-8');
|
|
71
|
+
const statusMatch = content.match(/^status:\s*(\S+)/m);
|
|
72
|
+
if (statusMatch?.[1] === 'done') completed.push(issue.id);
|
|
73
|
+
else failed.push(issue.id);
|
|
74
|
+
} catch {
|
|
75
|
+
failed.push(issue.id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { completed, failed };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function writeProgressLines(filePath: string, lines: string[], warn: WarnFn): Promise<void> {
|
|
82
|
+
try {
|
|
83
|
+
if (existsSync(filePath)) {
|
|
84
|
+
await appendFile(filePath, `\n${lines.join('\n')}`, 'utf-8');
|
|
85
|
+
} else {
|
|
86
|
+
await writeFile(filePath, `# Board Progress\n${lines.join('\n')}`, 'utf-8');
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
warn(`Warning: failed to write progress log: ${err instanceof Error ? err.message : String(err)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
-
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Prompt Builder — Constructs the Agent Teams coordinator prompt.
|
|
@@ -28,23 +27,40 @@ export interface CoordinatorPromptOptions {
|
|
|
28
27
|
*/
|
|
29
28
|
export function buildCoordinatorPrompt(options: CoordinatorPromptOptions): string {
|
|
30
29
|
const { issues, workingDir, pmDir, boardDir, existingDocs, resolveOutputPath } = options;
|
|
31
|
-
const outDir =
|
|
30
|
+
const outDir = resolveOutDir(workingDir, pmDir, boardDir);
|
|
31
|
+
const teamName = `pm-wave-${Date.now()}`;
|
|
32
|
+
|
|
33
|
+
const issueBlocks = issues.map(issue => buildIssueBlock(issue, existingDocs, resolveOutputPath)).join('\n\n---\n\n');
|
|
34
|
+
const teammateSpawns = issues.map(issue => buildTeammateSpawn(issue, teamName, pmDir, existingDocs, resolveOutputPath)).join('\n\n');
|
|
35
|
+
|
|
36
|
+
return assembleCoordinatorPrompt({ issues, workingDir, pmDir, outDir, teamName, issueBlocks, teammateSpawns });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveOutDir(workingDir: string, pmDir: string | null, boardDir: string | null): string {
|
|
40
|
+
if (boardDir) return join(boardDir, 'out');
|
|
41
|
+
if (pmDir) return join(pmDir, 'out');
|
|
42
|
+
return join(workingDir, '.mstro', 'pm', 'out');
|
|
43
|
+
}
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
function buildIssueBlock(
|
|
46
|
+
issue: Issue,
|
|
47
|
+
existingDocs: string[],
|
|
48
|
+
resolveOutputPath: (issue: Issue) => string,
|
|
49
|
+
): string {
|
|
50
|
+
const criteria = issue.acceptanceCriteria
|
|
51
|
+
.map(c => `- [${c.checked ? 'x' : ' '}] ${c.text}`)
|
|
52
|
+
.join('\n');
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
const files = issue.filesToModify.length > 0
|
|
55
|
+
? `\nFiles to modify:\n${issue.filesToModify.map(f => `- ${f}`).join('\n')}`
|
|
56
|
+
: '';
|
|
41
57
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
const predecessorDocs = resolvePredecessorDocs(issue, existingDocs);
|
|
59
|
+
const predecessorSection = predecessorDocs.length > 0
|
|
60
|
+
? `\nPredecessor outputs to read:\n${predecessorDocs.map(d => `- ${d}`).join('\n')}`
|
|
61
|
+
: '';
|
|
46
62
|
|
|
47
|
-
|
|
63
|
+
return `### ${issue.id}: ${issue.title}
|
|
48
64
|
|
|
49
65
|
**Type**: ${issue.type} | **Priority**: ${issue.priority} | **Estimate**: ${issue.estimate ?? 'unestimated'}
|
|
50
66
|
|
|
@@ -59,32 +75,53 @@ ${issue.technicalNotes || 'None'}
|
|
|
59
75
|
${files}${predecessorSection}
|
|
60
76
|
|
|
61
77
|
**Output file**: ${resolveOutputPath(issue)}`;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const teamName = `pm-wave-${Date.now()}`;
|
|
65
|
-
|
|
66
|
-
const teammateSpawns = issues.map(issue => {
|
|
67
|
-
const predecessorDocs = resolvePredecessorDocs(issue, existingDocs);
|
|
68
|
-
const predInstr = predecessorDocs.length > 0
|
|
69
|
-
? `Read these predecessor output docs before starting: ${predecessorDocs.join(', ')}. `
|
|
70
|
-
: '';
|
|
71
|
-
|
|
72
|
-
const outputFile = resolveOutputPath(issue);
|
|
73
|
-
|
|
74
|
-
const fileOwnership = issue.filesToModify.length > 0
|
|
75
|
-
? `\n> FILE OWNERSHIP: You own these files exclusively: ${issue.filesToModify.join(', ')}. Other teammates own all other files.`
|
|
76
|
-
: '';
|
|
78
|
+
}
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
function buildTeammateSpawn(
|
|
81
|
+
issue: Issue,
|
|
82
|
+
teamName: string,
|
|
83
|
+
pmDir: string | null,
|
|
84
|
+
existingDocs: string[],
|
|
85
|
+
resolveOutputPath: (issue: Issue) => string,
|
|
86
|
+
): string {
|
|
87
|
+
const predecessorDocs = resolvePredecessorDocs(issue, existingDocs);
|
|
88
|
+
const predInstr = predecessorDocs.length > 0
|
|
89
|
+
? `Read these predecessor output docs before starting: ${predecessorDocs.join(', ')}. `
|
|
90
|
+
: '';
|
|
91
|
+
|
|
92
|
+
const outputFile = resolveOutputPath(issue);
|
|
93
|
+
|
|
94
|
+
const fileOwnership = issue.filesToModify.length > 0
|
|
95
|
+
? `\n> FILE OWNERSHIP: You own these files exclusively: ${issue.filesToModify.join(', ')}. Other teammates own all other files.`
|
|
96
|
+
: '';
|
|
97
|
+
|
|
98
|
+
return `Spawn teammate **${issue.id.toLowerCase()}** using the **Agent** tool with \`team_name: "${teamName}"\` and \`name: "${issue.id.toLowerCase()}"\`:
|
|
79
99
|
> ${predInstr}Work on issue ${issue.id}: ${issue.title}.
|
|
80
100
|
> Read the full spec at ${pmDir ? join(pmDir, issue.path) : issue.path}.
|
|
81
101
|
> Execute all acceptance criteria.
|
|
82
102
|
> Write all output and results to ${outputFile} — this is the handoff artifact for downstream issues.
|
|
83
103
|
> After writing output, update the issue front matter: change \`status: in_progress\` to \`status: done\`.
|
|
84
104
|
> The orchestrator manages STATE.md. Stay within this issue's scope.${fileOwnership}`;
|
|
85
|
-
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface AssembleArgs {
|
|
108
|
+
issues: Issue[];
|
|
109
|
+
workingDir: string;
|
|
110
|
+
pmDir: string | null;
|
|
111
|
+
outDir: string;
|
|
112
|
+
teamName: string;
|
|
113
|
+
issueBlocks: string;
|
|
114
|
+
teammateSpawns: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function assembleCoordinatorPrompt(args: AssembleArgs): string {
|
|
118
|
+
const { issues, workingDir, pmDir, outDir, teamName, issueBlocks, teammateSpawns } = args;
|
|
119
|
+
const issueCount = issues.length;
|
|
120
|
+
const plural = issueCount > 1 ? 's' : '';
|
|
121
|
+
const checklist = issues.map(i => `- [ ] ${i.id.toLowerCase()}`).join('\n');
|
|
122
|
+
const teammateNames = issues.map(i => `- \`${i.id.toLowerCase()}\``).join('\n');
|
|
86
123
|
|
|
87
|
-
return `You are the team lead coordinating ${
|
|
124
|
+
return `You are the team lead coordinating ${issueCount} issue${plural} using Agent Teams.
|
|
88
125
|
|
|
89
126
|
## Project Directory
|
|
90
127
|
Working directory: ${workingDir}
|
|
@@ -102,7 +139,7 @@ All team coordination uses exactly two tools:
|
|
|
102
139
|
|
|
103
140
|
### Step 1: Spawn all teammates in one message
|
|
104
141
|
|
|
105
|
-
Send a single message containing ${
|
|
142
|
+
Send a single message containing ${issueCount} **Agent** tool calls. Include \`team_name: "${teamName}"\` and a unique \`name\` in each call. The team starts automatically when the first teammate is spawned — the \`team_name\` parameter handles all setup.
|
|
106
143
|
|
|
107
144
|
${teammateSpawns}
|
|
108
145
|
|
|
@@ -113,10 +150,10 @@ After spawning, idle notifications arrive automatically as messages — you will
|
|
|
113
150
|
Your first action after spawning all teammates: output a brief status message listing all teammates and confirming you are waiting for their idle notifications. Then wait.
|
|
114
151
|
|
|
115
152
|
Track completion against this checklist — proceed to Step 3 only after all are checked:
|
|
116
|
-
${
|
|
153
|
+
${checklist}
|
|
117
154
|
|
|
118
155
|
Exact teammate names for SendMessage (messages to any other name are silently dropped):
|
|
119
|
-
${
|
|
156
|
+
${teammateNames}
|
|
120
157
|
|
|
121
158
|
When you receive an idle notification from a teammate:
|
|
122
159
|
- Check off that teammate in the checklist above
|
|
@@ -143,7 +180,7 @@ After all outputs are verified:
|
|
|
143
180
|
## Coordination Rules
|
|
144
181
|
|
|
145
182
|
- The team starts implicitly when you spawn the first teammate with \`team_name\`. Cleanup happens automatically when all teammates exit or the lead exits.
|
|
146
|
-
- Wait for idle notifications from all ${
|
|
183
|
+
- Wait for idle notifications from all ${issueCount} teammates before exiting — this ensures all work is saved to disk.
|
|
147
184
|
- Each teammate writes its output to disk (the handoff artifact for downstream issues). Research kept only in conversation is lost when the teammate exits.
|
|
148
185
|
- Each teammate updates its issue front matter status to \`done\` when finished.
|
|
149
186
|
- One issue per teammate — each teammate stays within its assigned scope.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pure helpers for wave readiness: human-readable completion reasons
|
|
5
|
+
* and detection of "dead" issues stuck in non-terminal states.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Issue } from './types.js';
|
|
9
|
+
|
|
10
|
+
const TERMINAL_STATUSES = new Set(['done', 'cancelled']);
|
|
11
|
+
|
|
12
|
+
/** Build the user-facing completion message shown when no issues remain. */
|
|
13
|
+
export function buildCompletionReason(issues: Issue[], epicScope: string | null): string {
|
|
14
|
+
const nonEpic = issues.filter(i => i.type !== 'epic');
|
|
15
|
+
const done = nonEpic.filter(i => TERMINAL_STATUSES.has(i.status)).length;
|
|
16
|
+
const blocked = nonEpic.filter(i => i.status === 'todo').length;
|
|
17
|
+
if (done === nonEpic.length) return epicScope ? 'All epic issues are done' : 'All issues are done';
|
|
18
|
+
if (blocked > 0) return `${done}/${nonEpic.length} issues done, ${blocked} blocked by incomplete dependencies`;
|
|
19
|
+
return epicScope ? 'All epic issues are done or blocked' : 'All work is done or blocked';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Detect issues stuck in non-terminal states with no path to completion.
|
|
24
|
+
* Returns a human-readable reason, or null when the board is healthy.
|
|
25
|
+
*/
|
|
26
|
+
export function detectDeadState(issues: Issue[]): string | null {
|
|
27
|
+
const nonEpic = issues.filter(i => i.type !== 'epic');
|
|
28
|
+
const stuck = nonEpic.filter(i => !TERMINAL_STATUSES.has(i.status) && i.status !== 'todo');
|
|
29
|
+
if (stuck.length === 0) return null;
|
|
30
|
+
|
|
31
|
+
const stuckIds = stuck.map(i => `${i.id} (${i.status})`).join(', ');
|
|
32
|
+
|
|
33
|
+
const issueByPath = new Map(issues.map(i => [i.path, i]));
|
|
34
|
+
const blockedByStuck = nonEpic.filter(i => {
|
|
35
|
+
if (i.status !== 'todo') return false;
|
|
36
|
+
return i.blockedBy.some(bp => {
|
|
37
|
+
const blocker = issueByPath.get(bp);
|
|
38
|
+
return blocker && !TERMINAL_STATUSES.has(blocker.status);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
const blockedIds = blockedByStuck.map(i => i.id).join(', ');
|
|
42
|
+
|
|
43
|
+
return `Board stuck: ${stuckIds} cannot progress${blockedIds ? `. Blocking: ${blockedIds}` : ''}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** True iff any non-epic issue is stuck in a non-terminal, non-todo state. */
|
|
47
|
+
export function hasBlockedIssues(issues: Issue[]): boolean {
|
|
48
|
+
return issues.some(i => i.type !== 'epic' && !TERMINAL_STATUSES.has(i.status) && i.status !== 'todo');
|
|
49
|
+
}
|