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
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Quality Review Agent — AI-powered code review using Claude Code headless runner.
|
|
6
|
+
*
|
|
7
|
+
* Builds the review prompt, runs the agent, parses findings, and persists results.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { runWithFileLogger } from '../../cli/headless/headless-logger.js';
|
|
11
|
+
import { HeadlessRunner } from '../../cli/headless/index.js';
|
|
12
|
+
import type { ToolUseEvent } from '../../cli/headless/types.js';
|
|
13
|
+
import type { HandlerContext } from './handler-context.js';
|
|
14
|
+
import type { QualityPersistence } from './quality-persistence.js';
|
|
15
|
+
import { recomputeWithAiReview } from './quality-service.js';
|
|
16
|
+
import type { WSContext } from './types.js';
|
|
17
|
+
|
|
18
|
+
// ── Types ─────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
export interface CodeReviewFinding {
|
|
21
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
22
|
+
category: 'security' | 'bugs' | 'performance' | 'maintainability';
|
|
23
|
+
file: string;
|
|
24
|
+
line: number | null;
|
|
25
|
+
title: string;
|
|
26
|
+
description: string;
|
|
27
|
+
suggestion?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Prompt ────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
export function buildCodeReviewPrompt(dirPath: string): string {
|
|
33
|
+
return `You are an expert code review agent. Your task is to perform a comprehensive, language-agnostic code review of the project in the current working directory.
|
|
34
|
+
|
|
35
|
+
IMPORTANT: Your current working directory is "${dirPath}". Only review files within this directory. Do NOT traverse parent directories or review files outside this path.
|
|
36
|
+
|
|
37
|
+
## Review Process
|
|
38
|
+
|
|
39
|
+
1. **Discover**: Use Glob to find source files (e.g. "**/*.{ts,tsx,js,py,rs,go,java,rb,php}"). Understand the project structure. Only search within the current directory.
|
|
40
|
+
2. **Read**: Read the most important files — entry points, core modules, handlers, services. Prioritize files with recent git changes (\`git diff --name-only HEAD~5\` via Bash if available).
|
|
41
|
+
3. **Analyze**: Look for real, actionable issues across these categories:
|
|
42
|
+
- **security**: Injection vulnerabilities (SQL, XSS, command), hardcoded secrets/credentials, auth bypasses, insecure crypto, path traversal, SSRF, unsafe deserialization
|
|
43
|
+
- **bugs**: Null/undefined errors, race conditions, logic errors, unhandled edge cases, off-by-one errors, resource leaks, incorrect error handling
|
|
44
|
+
- **performance**: N+1 queries, unnecessary re-renders, missing memoization, blocking I/O in hot paths, unbounded data structures, missing pagination
|
|
45
|
+
- **maintainability**: God functions (>100 lines), deep nesting (>4 levels), duplicated logic, missing error handling at system boundaries, tight coupling
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
- Only report findings you are >80% confident about. No speculative or low-confidence issues.
|
|
50
|
+
- Focus on bugs and security over style. Skip formatting, naming preferences, and minor nits.
|
|
51
|
+
- Each finding MUST reference a specific file and line number. Do not report vague or file-level issues.
|
|
52
|
+
- Limit to the 20 most important findings, ranked by severity.
|
|
53
|
+
- Do NOT modify any files. This is a read-only review.
|
|
54
|
+
|
|
55
|
+
## Output
|
|
56
|
+
|
|
57
|
+
After your analysis, output EXACTLY one JSON code block with your findings. No other text after the JSON block.
|
|
58
|
+
|
|
59
|
+
\`\`\`json
|
|
60
|
+
{
|
|
61
|
+
"findings": [
|
|
62
|
+
{
|
|
63
|
+
"severity": "critical|high|medium|low",
|
|
64
|
+
"category": "security|bugs|performance|maintainability",
|
|
65
|
+
"file": "relative/path/to/file.ts",
|
|
66
|
+
"line": 42,
|
|
67
|
+
"title": "Short title describing the issue",
|
|
68
|
+
"description": "What the problem is and why it matters.",
|
|
69
|
+
"suggestion": "How to fix it."
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"summary": "Brief 1-2 sentence summary of overall code quality."
|
|
73
|
+
}
|
|
74
|
+
\`\`\``;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ── Response parsing ──────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
const VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low']);
|
|
80
|
+
const VALID_CATEGORIES = new Set(['security', 'bugs', 'performance', 'maintainability']);
|
|
81
|
+
|
|
82
|
+
function normalizeFinding(f: Record<string, unknown>): CodeReviewFinding | null {
|
|
83
|
+
if (typeof f.file !== 'string' || typeof f.title !== 'string') return null;
|
|
84
|
+
return {
|
|
85
|
+
severity: VALID_SEVERITIES.has(f.severity as string) ? f.severity as CodeReviewFinding['severity'] : 'medium',
|
|
86
|
+
category: VALID_CATEGORIES.has(f.category as string) ? f.category as CodeReviewFinding['category'] : 'maintainability',
|
|
87
|
+
file: f.file as string,
|
|
88
|
+
line: typeof f.line === 'number' ? f.line : null,
|
|
89
|
+
title: f.title as string,
|
|
90
|
+
description: typeof f.description === 'string' ? f.description : '',
|
|
91
|
+
suggestion: typeof f.suggestion === 'string' ? f.suggestion : undefined,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function extractJson(response: string): string {
|
|
96
|
+
const fencedJson = response.match(/```json\s*([\s\S]*?)```/);
|
|
97
|
+
if (fencedJson) return fencedJson[1].trim();
|
|
98
|
+
|
|
99
|
+
const fencedPlain = response.match(/```\s*([\s\S]*?)```/);
|
|
100
|
+
if (fencedPlain) return fencedPlain[1].trim();
|
|
101
|
+
|
|
102
|
+
const braceMatch = response.match(/\{[\s\S]*\}/);
|
|
103
|
+
if (braceMatch) return braceMatch[0].trim();
|
|
104
|
+
|
|
105
|
+
return response.trim();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function parseCodeReviewResponse(response: string): { findings: CodeReviewFinding[]; summary: string } {
|
|
109
|
+
const jsonStr = extractJson(response);
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(jsonStr);
|
|
113
|
+
const rawFindings: Record<string, unknown>[] = Array.isArray(parsed.findings) ? parsed.findings : [];
|
|
114
|
+
const findings = rawFindings.map(normalizeFinding).filter((f): f is CodeReviewFinding => f !== null);
|
|
115
|
+
const summary = typeof parsed.summary === 'string' ? parsed.summary : `Found ${findings.length} issue(s).`;
|
|
116
|
+
return { findings, summary };
|
|
117
|
+
} catch {
|
|
118
|
+
return { findings: [], summary: 'Failed to parse code review results.' };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ── Progress tracking ─────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
const TOOL_START_MESSAGES: Record<string, string> = {
|
|
125
|
+
Glob: 'Discovering project files...',
|
|
126
|
+
Read: 'Reading source files...',
|
|
127
|
+
Grep: 'Searching codebase...',
|
|
128
|
+
Bash: 'Running analysis command...',
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
function getToolCompleteMessage(event: ToolUseEvent): string | null {
|
|
132
|
+
const input = event.completeInput;
|
|
133
|
+
if (!input) return null;
|
|
134
|
+
if (event.toolName === 'Read' && input.file_path) {
|
|
135
|
+
return `Reviewed ${String(input.file_path).split('/').slice(-2).join('/')}`;
|
|
136
|
+
}
|
|
137
|
+
if (event.toolName === 'Grep' && input.pattern) {
|
|
138
|
+
return `Searched for "${String(input.pattern).slice(0, 40)}"`;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function createCodeReviewProgressTracker() {
|
|
144
|
+
const seenToolStarts = new Set<string>();
|
|
145
|
+
|
|
146
|
+
return (event: ToolUseEvent): string | null => {
|
|
147
|
+
if (event.type === 'tool_start' && event.toolName) {
|
|
148
|
+
if (seenToolStarts.has(event.toolName)) return null;
|
|
149
|
+
seenToolStarts.add(event.toolName);
|
|
150
|
+
return TOOL_START_MESSAGES[event.toolName] ?? null;
|
|
151
|
+
}
|
|
152
|
+
if (event.type === 'tool_complete') return getToolCompleteMessage(event);
|
|
153
|
+
return null;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ── Handler ───────────────────────────────────────────────────
|
|
158
|
+
|
|
159
|
+
export async function handleCodeReview(
|
|
160
|
+
ctx: HandlerContext,
|
|
161
|
+
ws: WSContext,
|
|
162
|
+
reportPath: string,
|
|
163
|
+
dirPath: string,
|
|
164
|
+
workingDir: string,
|
|
165
|
+
activeReviews: Set<string>,
|
|
166
|
+
getPersistence: (dir: string) => QualityPersistence,
|
|
167
|
+
): Promise<void> {
|
|
168
|
+
if (activeReviews.has(dirPath)) {
|
|
169
|
+
ctx.send(ws, {
|
|
170
|
+
type: 'qualityError',
|
|
171
|
+
data: { path: reportPath, error: 'A code review is already running for this directory.' },
|
|
172
|
+
});
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
activeReviews.add(dirPath);
|
|
177
|
+
try {
|
|
178
|
+
ctx.send(ws, {
|
|
179
|
+
type: 'qualityCodeReviewProgress',
|
|
180
|
+
data: { path: reportPath, message: 'Starting AI code review...' },
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const runner = new HeadlessRunner({
|
|
184
|
+
workingDir: dirPath,
|
|
185
|
+
directPrompt: buildCodeReviewPrompt(dirPath),
|
|
186
|
+
stallWarningMs: 120_000,
|
|
187
|
+
stallKillMs: 600_000,
|
|
188
|
+
stallHardCapMs: 900_000,
|
|
189
|
+
toolUseCallback: (() => {
|
|
190
|
+
const getProgressMessage = createCodeReviewProgressTracker();
|
|
191
|
+
return (event: ToolUseEvent) => {
|
|
192
|
+
const message = getProgressMessage(event);
|
|
193
|
+
if (message) {
|
|
194
|
+
ctx.send(ws, {
|
|
195
|
+
type: 'qualityCodeReviewProgress',
|
|
196
|
+
data: { path: reportPath, message },
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
})(),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
ctx.send(ws, {
|
|
204
|
+
type: 'qualityCodeReviewProgress',
|
|
205
|
+
data: { path: reportPath, message: 'Claude is analyzing your codebase...' },
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const result = await runWithFileLogger('code-review', () => runner.run());
|
|
209
|
+
|
|
210
|
+
ctx.send(ws, {
|
|
211
|
+
type: 'qualityCodeReviewProgress',
|
|
212
|
+
data: { path: reportPath, message: 'Generating review report...' },
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const responseText = result.assistantResponse || '';
|
|
216
|
+
const { findings, summary } = parseCodeReviewResponse(responseText);
|
|
217
|
+
|
|
218
|
+
// Recompute overall score with AI review findings included
|
|
219
|
+
let updatedResults: import('./quality-service.js').QualityResults | null = null;
|
|
220
|
+
try {
|
|
221
|
+
const persistence = getPersistence(workingDir);
|
|
222
|
+
const existingReport = persistence.loadReport(reportPath);
|
|
223
|
+
if (existingReport) {
|
|
224
|
+
updatedResults = recomputeWithAiReview(existingReport, findings);
|
|
225
|
+
updatedResults = { ...updatedResults, codeReview: findings as unknown as typeof updatedResults.codeReview };
|
|
226
|
+
persistence.saveReport(reportPath, updatedResults);
|
|
227
|
+
persistence.appendHistory(updatedResults, reportPath);
|
|
228
|
+
}
|
|
229
|
+
persistence.saveCodeReview(reportPath, findings as unknown as Record<string, unknown>[], summary);
|
|
230
|
+
} catch {
|
|
231
|
+
// Persistence failure should not break the review flow
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
ctx.send(ws, {
|
|
235
|
+
type: 'qualityCodeReview',
|
|
236
|
+
data: { path: reportPath, findings, summary, results: updatedResults },
|
|
237
|
+
});
|
|
238
|
+
} catch (error) {
|
|
239
|
+
ctx.send(ws, {
|
|
240
|
+
type: 'qualityError',
|
|
241
|
+
data: { path: reportPath, error: error instanceof Error ? error.message : String(error) },
|
|
242
|
+
});
|
|
243
|
+
} finally {
|
|
244
|
+
activeReviews.delete(dirPath);
|
|
245
|
+
}
|
|
246
|
+
}
|