@diff-review-system/drs 3.3.1 → 4.0.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/.pi/agents/describe/pr-describer.md +14 -0
- package/.pi/agents/review/unified-reviewer.md +31 -1
- package/.pi/agents/task/agents-md-updater.md +26 -0
- package/.pi/agents/task/changelog-updater.md +29 -0
- package/.pi/agents/task/review-issue-fixer.md +42 -0
- package/.pi/agents/visual/pr-explainer.md +205 -0
- package/.pi/workflows/github-pr-describe.yaml +26 -0
- package/.pi/workflows/github-pr-fix-review-issues-stacked.yaml +148 -0
- package/.pi/workflows/github-pr-post-comment.yaml +19 -0
- package/.pi/workflows/github-pr-review-post.yaml +43 -0
- package/.pi/workflows/github-pr-review.yaml +364 -0
- package/.pi/workflows/github-pr-show-changes.yaml +25 -0
- package/.pi/workflows/github-pr-update-agents-md-stacked.yaml +103 -0
- package/.pi/workflows/github-pr-visual-explain.yaml +35 -0
- package/.pi/workflows/gitlab-mr-describe.yaml +24 -0
- package/.pi/workflows/gitlab-mr-fix-review-issues-stacked.yaml +144 -0
- package/.pi/workflows/gitlab-mr-post-comment.yaml +17 -0
- package/.pi/workflows/gitlab-mr-review.yaml +364 -0
- package/.pi/workflows/gitlab-mr-show-changes.yaml +23 -0
- package/.pi/workflows/gitlab-mr-update-agents-md-stacked.yaml +100 -0
- package/.pi/workflows/gitlab-mr-visual-explain.yaml +33 -0
- package/.pi/workflows/local-changelog-update.yaml +23 -0
- package/.pi/workflows/local-fix-review-issues.yaml +111 -0
- package/.pi/workflows/local-review.yaml +24 -0
- package/.pi/workflows/local-update-agents-md.yaml +24 -0
- package/.pi/workflows/local-visual-explain.yaml +31 -0
- package/.pi/workflows/release-changelog-finalize.yaml +47 -0
- package/.pi/workflows/tag-changelog-update.yaml +26 -0
- package/README.md +281 -104
- package/dist/ci/runner.d.ts.map +1 -1
- package/dist/ci/runner.js +9 -8
- package/dist/ci/runner.js.map +1 -1
- package/dist/cli/index.js +95 -325
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +25 -23
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/run-agent.d.ts +26 -0
- package/dist/cli/run-agent.d.ts.map +1 -0
- package/dist/cli/run-agent.js +143 -0
- package/dist/cli/run-agent.js.map +1 -0
- package/dist/cli/workflow.d.ts +105 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +3309 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/github/client.d.ts +12 -0
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +27 -0
- package/dist/github/client.js.map +1 -1
- package/dist/github/platform-adapter.d.ts +6 -1
- package/dist/github/platform-adapter.d.ts.map +1 -1
- package/dist/github/platform-adapter.js +84 -8
- package/dist/github/platform-adapter.js.map +1 -1
- package/dist/gitlab/client.d.ts +11 -0
- package/dist/gitlab/client.d.ts.map +1 -1
- package/dist/gitlab/client.js +11 -0
- package/dist/gitlab/client.js.map +1 -1
- package/dist/gitlab/platform-adapter.d.ts +3 -1
- package/dist/gitlab/platform-adapter.d.ts.map +1 -1
- package/dist/gitlab/platform-adapter.js +32 -1
- package/dist/gitlab/platform-adapter.js.map +1 -1
- package/dist/lib/agent-id.d.ts +9 -0
- package/dist/lib/agent-id.d.ts.map +1 -0
- package/dist/lib/agent-id.js +32 -0
- package/dist/lib/agent-id.js.map +1 -0
- package/dist/lib/comment-formatter.d.ts +15 -1
- package/dist/lib/comment-formatter.d.ts.map +1 -1
- package/dist/lib/comment-formatter.js +53 -4
- package/dist/lib/comment-formatter.js.map +1 -1
- package/dist/lib/comment-manager.d.ts +4 -0
- package/dist/lib/comment-manager.d.ts.map +1 -1
- package/dist/lib/comment-manager.js +7 -1
- package/dist/lib/comment-manager.js.map +1 -1
- package/dist/lib/comment-poster.d.ts +2 -2
- package/dist/lib/comment-poster.d.ts.map +1 -1
- package/dist/lib/comment-poster.js +31 -4
- package/dist/lib/comment-poster.js.map +1 -1
- package/dist/lib/config.d.ts +160 -44
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +475 -101
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/context-compression.d.ts +10 -0
- package/dist/lib/context-compression.d.ts.map +1 -1
- package/dist/lib/context-compression.js +101 -13
- package/dist/lib/context-compression.js.map +1 -1
- package/dist/lib/context-loader.d.ts +5 -4
- package/dist/lib/context-loader.d.ts.map +1 -1
- package/dist/lib/context-loader.js +79 -7
- package/dist/lib/context-loader.js.map +1 -1
- package/dist/lib/describe-core.d.ts.map +1 -1
- package/dist/lib/describe-core.js +3 -2
- package/dist/lib/describe-core.js.map +1 -1
- package/dist/lib/description-executor.js +1 -1
- package/dist/lib/description-executor.js.map +1 -1
- package/dist/lib/diff-lines.d.ts +18 -0
- package/dist/lib/diff-lines.d.ts.map +1 -0
- package/dist/lib/diff-lines.js +40 -0
- package/dist/lib/diff-lines.js.map +1 -0
- package/dist/lib/exit.js +4 -4
- package/dist/lib/exit.js.map +1 -1
- package/dist/lib/html-artifact.d.ts +14 -0
- package/dist/lib/html-artifact.d.ts.map +1 -0
- package/dist/lib/html-artifact.js +59 -0
- package/dist/lib/html-artifact.js.map +1 -0
- package/dist/lib/issue-parser.js +3 -3
- package/dist/lib/issue-parser.js.map +1 -1
- package/dist/lib/json-output-schema.d.ts +70 -0
- package/dist/lib/json-output-schema.d.ts.map +1 -1
- package/dist/lib/json-output-schema.js +40 -0
- package/dist/lib/json-output-schema.js.map +1 -1
- package/dist/lib/logger.d.ts +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/platform-client.d.ts +26 -0
- package/dist/lib/platform-client.d.ts.map +1 -1
- package/dist/lib/review-artifact.d.ts +69 -0
- package/dist/lib/review-artifact.d.ts.map +1 -0
- package/dist/lib/review-artifact.js +171 -0
- package/dist/lib/review-artifact.js.map +1 -0
- package/dist/lib/review-core.d.ts +6 -4
- package/dist/lib/review-core.d.ts.map +1 -1
- package/dist/lib/review-core.js +88 -173
- package/dist/lib/review-core.js.map +1 -1
- package/dist/lib/review-orchestrator.d.ts +23 -0
- package/dist/lib/review-orchestrator.d.ts.map +1 -1
- package/dist/lib/review-orchestrator.js +31 -21
- package/dist/lib/review-orchestrator.js.map +1 -1
- package/dist/lib/review-usage.d.ts +4 -0
- package/dist/lib/review-usage.d.ts.map +1 -1
- package/dist/lib/review-usage.js +25 -0
- package/dist/lib/review-usage.js.map +1 -1
- package/dist/lib/trace-collector.d.ts +105 -0
- package/dist/lib/trace-collector.d.ts.map +1 -0
- package/dist/lib/trace-collector.js +255 -0
- package/dist/lib/trace-collector.js.map +1 -0
- package/dist/lib/trace-html.d.ts +3 -0
- package/dist/lib/trace-html.d.ts.map +1 -0
- package/dist/lib/trace-html.js +349 -0
- package/dist/lib/trace-html.js.map +1 -0
- package/dist/lib/workflow-artifacts.d.ts +54 -0
- package/dist/lib/workflow-artifacts.d.ts.map +1 -0
- package/dist/lib/workflow-artifacts.js +150 -0
- package/dist/lib/workflow-artifacts.js.map +1 -0
- package/dist/pi/sdk.d.ts.map +1 -1
- package/dist/pi/sdk.js +605 -16
- package/dist/pi/sdk.js.map +1 -1
- package/dist/runtime/agent-loader.d.ts +10 -6
- package/dist/runtime/agent-loader.d.ts.map +1 -1
- package/dist/runtime/agent-loader.js +55 -29
- package/dist/runtime/agent-loader.js.map +1 -1
- package/dist/runtime/built-in-paths.d.ts +1 -0
- package/dist/runtime/built-in-paths.d.ts.map +1 -1
- package/dist/runtime/built-in-paths.js +7 -0
- package/dist/runtime/built-in-paths.js.map +1 -1
- package/dist/runtime/client.d.ts +14 -0
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +87 -56
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/path-config.d.ts +2 -2
- package/dist/runtime/path-config.d.ts.map +1 -1
- package/dist/runtime/path-config.js +8 -8
- package/dist/runtime/path-config.js.map +1 -1
- package/package.json +22 -16
- package/.pi/agents/review/documentation.md +0 -56
- package/.pi/agents/review/performance.md +0 -53
- package/.pi/agents/review/quality.md +0 -59
- package/.pi/agents/review/security.md +0 -53
- package/.pi/agents/review/style.md +0 -132
- package/dist/cli/describe-mr.d.ts +0 -11
- package/dist/cli/describe-mr.d.ts.map +0 -1
- package/dist/cli/describe-mr.js +0 -134
- package/dist/cli/describe-mr.js.map +0 -1
- package/dist/cli/describe-pr.d.ts +0 -12
- package/dist/cli/describe-pr.d.ts.map +0 -1
- package/dist/cli/describe-pr.js +0 -135
- package/dist/cli/describe-pr.js.map +0 -1
- package/dist/cli/post-comments.d.ts +0 -20
- package/dist/cli/post-comments.d.ts.map +0 -1
- package/dist/cli/post-comments.js +0 -225
- package/dist/cli/post-comments.js.map +0 -1
- package/dist/cli/review-local.d.ts +0 -13
- package/dist/cli/review-local.d.ts.map +0 -1
- package/dist/cli/review-local.integration.test.d.ts +0 -2
- package/dist/cli/review-local.integration.test.d.ts.map +0 -1
- package/dist/cli/review-local.integration.test.js +0 -343
- package/dist/cli/review-local.integration.test.js.map +0 -1
- package/dist/cli/review-local.js +0 -90
- package/dist/cli/review-local.js.map +0 -1
- package/dist/cli/review-local.live.e2e.test.d.ts +0 -2
- package/dist/cli/review-local.live.e2e.test.d.ts.map +0 -1
- package/dist/cli/review-local.live.e2e.test.js +0 -153
- package/dist/cli/review-local.live.e2e.test.js.map +0 -1
- package/dist/cli/review-local.test.d.ts +0 -2
- package/dist/cli/review-local.test.d.ts.map +0 -1
- package/dist/cli/review-local.test.js +0 -164
- package/dist/cli/review-local.test.js.map +0 -1
- package/dist/cli/review-mr.d.ts +0 -22
- package/dist/cli/review-mr.d.ts.map +0 -1
- package/dist/cli/review-mr.js +0 -181
- package/dist/cli/review-mr.js.map +0 -1
- package/dist/cli/review-mr.test.d.ts +0 -2
- package/dist/cli/review-mr.test.d.ts.map +0 -1
- package/dist/cli/review-mr.test.js +0 -142
- package/dist/cli/review-mr.test.js.map +0 -1
- package/dist/cli/review-pr.d.ts +0 -22
- package/dist/cli/review-pr.d.ts.map +0 -1
- package/dist/cli/review-pr.js +0 -181
- package/dist/cli/review-pr.js.map +0 -1
- package/dist/cli/review-pr.test.d.ts +0 -2
- package/dist/cli/review-pr.test.d.ts.map +0 -1
- package/dist/cli/review-pr.test.js +0 -137
- package/dist/cli/review-pr.test.js.map +0 -1
- package/dist/cli/review-url.d.ts +0 -35
- package/dist/cli/review-url.d.ts.map +0 -1
- package/dist/cli/review-url.js +0 -110
- package/dist/cli/review-url.js.map +0 -1
- package/dist/cli/review-url.test.d.ts +0 -2
- package/dist/cli/review-url.test.d.ts.map +0 -1
- package/dist/cli/review-url.test.js +0 -132
- package/dist/cli/review-url.test.js.map +0 -1
- package/dist/cli/show-changes.d.ts +0 -15
- package/dist/cli/show-changes.d.ts.map +0 -1
- package/dist/cli/show-changes.js +0 -184
- package/dist/cli/show-changes.js.map +0 -1
- package/dist/github/client.test.d.ts +0 -2
- package/dist/github/client.test.d.ts.map +0 -1
- package/dist/github/client.test.js +0 -206
- package/dist/github/client.test.js.map +0 -1
- package/dist/github/platform-adapter.test.d.ts +0 -2
- package/dist/github/platform-adapter.test.d.ts.map +0 -1
- package/dist/github/platform-adapter.test.js +0 -40
- package/dist/github/platform-adapter.test.js.map +0 -1
- package/dist/gitlab/diff-parser.test.d.ts +0 -2
- package/dist/gitlab/diff-parser.test.d.ts.map +0 -1
- package/dist/gitlab/diff-parser.test.js +0 -315
- package/dist/gitlab/diff-parser.test.js.map +0 -1
- package/dist/gitlab/platform-adapter.test.d.ts +0 -2
- package/dist/gitlab/platform-adapter.test.d.ts.map +0 -1
- package/dist/gitlab/platform-adapter.test.js +0 -21
- package/dist/gitlab/platform-adapter.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -7
- package/dist/index.test.js.map +0 -1
- package/dist/lib/code-quality-report.test.d.ts +0 -2
- package/dist/lib/code-quality-report.test.d.ts.map +0 -1
- package/dist/lib/code-quality-report.test.js +0 -327
- package/dist/lib/code-quality-report.test.js.map +0 -1
- package/dist/lib/comment-formatter.test.d.ts +0 -2
- package/dist/lib/comment-formatter.test.d.ts.map +0 -1
- package/dist/lib/comment-formatter.test.js +0 -694
- package/dist/lib/comment-formatter.test.js.map +0 -1
- package/dist/lib/comment-manager.test.d.ts +0 -2
- package/dist/lib/comment-manager.test.d.ts.map +0 -1
- package/dist/lib/comment-manager.test.js +0 -680
- package/dist/lib/comment-manager.test.js.map +0 -1
- package/dist/lib/comment-poster.test.d.ts +0 -5
- package/dist/lib/comment-poster.test.d.ts.map +0 -1
- package/dist/lib/comment-poster.test.js +0 -245
- package/dist/lib/comment-poster.test.js.map +0 -1
- package/dist/lib/config-model-overrides.test.d.ts +0 -12
- package/dist/lib/config-model-overrides.test.d.ts.map +0 -1
- package/dist/lib/config-model-overrides.test.js +0 -254
- package/dist/lib/config-model-overrides.test.js.map +0 -1
- package/dist/lib/config.test.d.ts +0 -2
- package/dist/lib/config.test.d.ts.map +0 -1
- package/dist/lib/config.test.js +0 -73
- package/dist/lib/config.test.js.map +0 -1
- package/dist/lib/context-compression.test.d.ts +0 -2
- package/dist/lib/context-compression.test.d.ts.map +0 -1
- package/dist/lib/context-compression.test.js +0 -337
- package/dist/lib/context-compression.test.js.map +0 -1
- package/dist/lib/context-loader.test.d.ts +0 -2
- package/dist/lib/context-loader.test.d.ts.map +0 -1
- package/dist/lib/context-loader.test.js +0 -207
- package/dist/lib/context-loader.test.js.map +0 -1
- package/dist/lib/cursor-fix-link.test.d.ts +0 -2
- package/dist/lib/cursor-fix-link.test.d.ts.map +0 -1
- package/dist/lib/cursor-fix-link.test.js +0 -70
- package/dist/lib/cursor-fix-link.test.js.map +0 -1
- package/dist/lib/describe-core.test.d.ts +0 -2
- package/dist/lib/describe-core.test.d.ts.map +0 -1
- package/dist/lib/describe-core.test.js +0 -208
- package/dist/lib/describe-core.test.js.map +0 -1
- package/dist/lib/describe-output-path.test.d.ts +0 -2
- package/dist/lib/describe-output-path.test.d.ts.map +0 -1
- package/dist/lib/describe-output-path.test.js +0 -51
- package/dist/lib/describe-output-path.test.js.map +0 -1
- package/dist/lib/describe-parser.test.d.ts +0 -2
- package/dist/lib/describe-parser.test.d.ts.map +0 -1
- package/dist/lib/describe-parser.test.js +0 -282
- package/dist/lib/describe-parser.test.js.map +0 -1
- package/dist/lib/description-executor.test.d.ts +0 -2
- package/dist/lib/description-executor.test.d.ts.map +0 -1
- package/dist/lib/description-executor.test.js +0 -128
- package/dist/lib/description-executor.test.js.map +0 -1
- package/dist/lib/description-formatter.test.d.ts +0 -2
- package/dist/lib/description-formatter.test.d.ts.map +0 -1
- package/dist/lib/description-formatter.test.js +0 -57
- package/dist/lib/description-formatter.test.js.map +0 -1
- package/dist/lib/diff-parser.test.d.ts +0 -2
- package/dist/lib/diff-parser.test.d.ts.map +0 -1
- package/dist/lib/diff-parser.test.js +0 -335
- package/dist/lib/diff-parser.test.js.map +0 -1
- package/dist/lib/error-comment-poster.test.d.ts +0 -2
- package/dist/lib/error-comment-poster.test.d.ts.map +0 -1
- package/dist/lib/error-comment-poster.test.js +0 -128
- package/dist/lib/error-comment-poster.test.js.map +0 -1
- package/dist/lib/exit.test.d.ts +0 -2
- package/dist/lib/exit.test.d.ts.map +0 -1
- package/dist/lib/exit.test.js +0 -120
- package/dist/lib/exit.test.js.map +0 -1
- package/dist/lib/issue-parser.test.d.ts +0 -2
- package/dist/lib/issue-parser.test.d.ts.map +0 -1
- package/dist/lib/issue-parser.test.js +0 -281
- package/dist/lib/issue-parser.test.js.map +0 -1
- package/dist/lib/json-output-schema.test.d.ts +0 -2
- package/dist/lib/json-output-schema.test.d.ts.map +0 -1
- package/dist/lib/json-output-schema.test.js +0 -92
- package/dist/lib/json-output-schema.test.js.map +0 -1
- package/dist/lib/json-output.test.d.ts +0 -2
- package/dist/lib/json-output.test.d.ts.map +0 -1
- package/dist/lib/json-output.test.js +0 -141
- package/dist/lib/json-output.test.js.map +0 -1
- package/dist/lib/logger.test.d.ts +0 -2
- package/dist/lib/logger.test.d.ts.map +0 -1
- package/dist/lib/logger.test.js +0 -324
- package/dist/lib/logger.test.js.map +0 -1
- package/dist/lib/position-validator.test.d.ts +0 -2
- package/dist/lib/position-validator.test.d.ts.map +0 -1
- package/dist/lib/position-validator.test.js +0 -128
- package/dist/lib/position-validator.test.js.map +0 -1
- package/dist/lib/prompt-budget.test.d.ts +0 -2
- package/dist/lib/prompt-budget.test.d.ts.map +0 -1
- package/dist/lib/prompt-budget.test.js +0 -55
- package/dist/lib/prompt-budget.test.js.map +0 -1
- package/dist/lib/repository-validator.test.d.ts +0 -5
- package/dist/lib/repository-validator.test.d.ts.map +0 -1
- package/dist/lib/repository-validator.test.js +0 -341
- package/dist/lib/repository-validator.test.js.map +0 -1
- package/dist/lib/review-core.test.d.ts +0 -2
- package/dist/lib/review-core.test.d.ts.map +0 -1
- package/dist/lib/review-core.test.js +0 -600
- package/dist/lib/review-core.test.js.map +0 -1
- package/dist/lib/review-orchestrator.test.d.ts +0 -2
- package/dist/lib/review-orchestrator.test.d.ts.map +0 -1
- package/dist/lib/review-orchestrator.test.js +0 -531
- package/dist/lib/review-orchestrator.test.js.map +0 -1
- package/dist/lib/review-output-path.test.d.ts +0 -2
- package/dist/lib/review-output-path.test.d.ts.map +0 -1
- package/dist/lib/review-output-path.test.js +0 -83
- package/dist/lib/review-output-path.test.js.map +0 -1
- package/dist/lib/review-parser.test.d.ts +0 -2
- package/dist/lib/review-parser.test.d.ts.map +0 -1
- package/dist/lib/review-parser.test.js +0 -130
- package/dist/lib/review-parser.test.js.map +0 -1
- package/dist/lib/review-usage.test.d.ts +0 -2
- package/dist/lib/review-usage.test.d.ts.map +0 -1
- package/dist/lib/review-usage.test.js +0 -83
- package/dist/lib/review-usage.test.js.map +0 -1
- package/dist/lib/unified-review-executor.d.ts +0 -60
- package/dist/lib/unified-review-executor.d.ts.map +0 -1
- package/dist/lib/unified-review-executor.js +0 -207
- package/dist/lib/unified-review-executor.js.map +0 -1
- package/dist/lib/unified-review-executor.test.d.ts +0 -5
- package/dist/lib/unified-review-executor.test.d.ts.map +0 -1
- package/dist/lib/unified-review-executor.test.js +0 -472
- package/dist/lib/unified-review-executor.test.js.map +0 -1
- package/dist/lib/write-json-output.test.d.ts +0 -2
- package/dist/lib/write-json-output.test.d.ts.map +0 -1
- package/dist/lib/write-json-output.test.js +0 -259
- package/dist/lib/write-json-output.test.js.map +0 -1
- package/dist/pi/sdk.test.d.ts +0 -2
- package/dist/pi/sdk.test.d.ts.map +0 -1
- package/dist/pi/sdk.test.js +0 -449
- package/dist/pi/sdk.test.js.map +0 -1
- package/dist/runtime/agent-loader.test.d.ts +0 -2
- package/dist/runtime/agent-loader.test.d.ts.map +0 -1
- package/dist/runtime/agent-loader.test.js +0 -280
- package/dist/runtime/agent-loader.test.js.map +0 -1
- package/dist/runtime/client.test.d.ts +0 -2
- package/dist/runtime/client.test.d.ts.map +0 -1
- package/dist/runtime/client.test.js +0 -523
- package/dist/runtime/client.test.js.map +0 -1
- package/dist/runtime/path-config.test.d.ts +0 -2
- package/dist/runtime/path-config.test.d.ts.map +0 -1
- package/dist/runtime/path-config.test.js +0 -112
- package/dist/runtime/path-config.test.js.map +0 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createIssueFingerprint } from './comment-manager.js';
|
|
2
|
+
function createReviewId(date) {
|
|
3
|
+
const timestamp = date.toISOString().replace(/[-:.TZ]/g, '');
|
|
4
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
5
|
+
return `rev_${timestamp}_${random}`;
|
|
6
|
+
}
|
|
7
|
+
function getSourceString(source) {
|
|
8
|
+
return source?.name;
|
|
9
|
+
}
|
|
10
|
+
function getSourceProject(source) {
|
|
11
|
+
const projectId = source?.context.projectId;
|
|
12
|
+
return typeof projectId === 'string' ? projectId : undefined;
|
|
13
|
+
}
|
|
14
|
+
function getSourcePullRequest(source) {
|
|
15
|
+
const pullRequest = source?.context.pullRequest;
|
|
16
|
+
if (!pullRequest || typeof pullRequest !== 'object') {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
const record = pullRequest;
|
|
20
|
+
return {
|
|
21
|
+
headSha: typeof record.headSha === 'string' ? record.headSha : undefined,
|
|
22
|
+
sourceBranch: typeof record.sourceBranch === 'string' ? record.sourceBranch : undefined,
|
|
23
|
+
targetBranch: typeof record.targetBranch === 'string' ? record.targetBranch : undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function findingId(index) {
|
|
27
|
+
return `F${String(index + 1).padStart(3, '0')}`;
|
|
28
|
+
}
|
|
29
|
+
function nextFindingId(findings) {
|
|
30
|
+
const max = findings.reduce((currentMax, finding) => {
|
|
31
|
+
const match = /^F(\d+)$/.exec(finding.id);
|
|
32
|
+
return match ? Math.max(currentMax, Number.parseInt(match[1] ?? '0', 10)) : currentMax;
|
|
33
|
+
}, 0);
|
|
34
|
+
return findingId(max);
|
|
35
|
+
}
|
|
36
|
+
function selectorMatches(finding, selector) {
|
|
37
|
+
const hasIds = selector.ids !== undefined && selector.ids.length > 0;
|
|
38
|
+
const hasFingerprints = selector.fingerprints !== undefined && selector.fingerprints.length > 0;
|
|
39
|
+
const hasSeverity = selector.severity !== undefined && selector.severity !== '';
|
|
40
|
+
if (!hasIds && !hasFingerprints && !hasSeverity) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return ((hasIds && (selector.ids?.includes(finding.id) ?? false)) ||
|
|
44
|
+
(hasFingerprints && (selector.fingerprints?.includes(finding.fingerprint) ?? false)) ||
|
|
45
|
+
(hasSeverity && finding.issue.severity === selector.severity));
|
|
46
|
+
}
|
|
47
|
+
export function createReviewArtifactPayload(review, source, date = new Date()) {
|
|
48
|
+
const now = date.toISOString();
|
|
49
|
+
const pullRequest = getSourcePullRequest(source);
|
|
50
|
+
const findings = review.issues.map((issue, index) => ({
|
|
51
|
+
id: findingId(index),
|
|
52
|
+
fingerprint: createIssueFingerprint(issue),
|
|
53
|
+
issue,
|
|
54
|
+
state: 'open',
|
|
55
|
+
disposition: 'confirmed',
|
|
56
|
+
source: 'agent',
|
|
57
|
+
createdAt: now,
|
|
58
|
+
updatedAt: now,
|
|
59
|
+
}));
|
|
60
|
+
return {
|
|
61
|
+
schemaVersion: 1,
|
|
62
|
+
reviewId: createReviewId(date),
|
|
63
|
+
reviewedAt: now,
|
|
64
|
+
reviewedSha: pullRequest.headSha,
|
|
65
|
+
baseBranch: pullRequest.targetBranch,
|
|
66
|
+
headBranch: pullRequest.sourceBranch,
|
|
67
|
+
summary: review.summary,
|
|
68
|
+
findings,
|
|
69
|
+
usage: review.usage,
|
|
70
|
+
metadata: {
|
|
71
|
+
source: getSourceString(source),
|
|
72
|
+
project: getSourceProject(source),
|
|
73
|
+
branch: pullRequest.sourceBranch || pullRequest.targetBranch
|
|
74
|
+
? {
|
|
75
|
+
source: pullRequest.sourceBranch,
|
|
76
|
+
target: pullRequest.targetBranch,
|
|
77
|
+
}
|
|
78
|
+
: undefined,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function isReviewArtifactPayload(value) {
|
|
83
|
+
if (!value || typeof value !== 'object') {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const candidate = value;
|
|
87
|
+
return (candidate.schemaVersion === 1 &&
|
|
88
|
+
typeof candidate.reviewId === 'string' &&
|
|
89
|
+
typeof candidate.reviewedAt === 'string' &&
|
|
90
|
+
typeof candidate.summary === 'object' &&
|
|
91
|
+
Array.isArray(candidate.findings));
|
|
92
|
+
}
|
|
93
|
+
export function getReviewArtifactStatus(artifact) {
|
|
94
|
+
const byState = { open: 0, attempted: 0, resolved: 0 };
|
|
95
|
+
const byDisposition = {
|
|
96
|
+
confirmed: 0,
|
|
97
|
+
uncertain: 0,
|
|
98
|
+
pre_existing: 0,
|
|
99
|
+
partial: 0,
|
|
100
|
+
still_open: 0,
|
|
101
|
+
regression: 0,
|
|
102
|
+
resolved: 0,
|
|
103
|
+
};
|
|
104
|
+
for (const finding of artifact.findings) {
|
|
105
|
+
byState[finding.state] += 1;
|
|
106
|
+
byDisposition[finding.disposition] += 1;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
reviewId: artifact.reviewId,
|
|
110
|
+
reviewedAt: artifact.reviewedAt,
|
|
111
|
+
reviewedSha: artifact.reviewedSha,
|
|
112
|
+
totalFindings: artifact.findings.length,
|
|
113
|
+
byState,
|
|
114
|
+
byDisposition,
|
|
115
|
+
bySeverity: artifact.summary.bySeverity,
|
|
116
|
+
openFindings: byState.open,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function addReviewArtifactFinding(artifact, issue, source = 'manual', date = new Date()) {
|
|
120
|
+
const now = date.toISOString();
|
|
121
|
+
const finding = {
|
|
122
|
+
id: nextFindingId(artifact.findings),
|
|
123
|
+
fingerprint: createIssueFingerprint(issue),
|
|
124
|
+
issue,
|
|
125
|
+
state: 'open',
|
|
126
|
+
disposition: 'confirmed',
|
|
127
|
+
source,
|
|
128
|
+
createdAt: now,
|
|
129
|
+
updatedAt: now,
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
...artifact,
|
|
133
|
+
findings: [...artifact.findings, finding],
|
|
134
|
+
summary: {
|
|
135
|
+
...artifact.summary,
|
|
136
|
+
issuesFound: artifact.summary.issuesFound + 1,
|
|
137
|
+
bySeverity: {
|
|
138
|
+
...artifact.summary.bySeverity,
|
|
139
|
+
[issue.severity]: (artifact.summary.bySeverity[issue.severity] ?? 0) + 1,
|
|
140
|
+
},
|
|
141
|
+
byCategory: {
|
|
142
|
+
...artifact.summary.byCategory,
|
|
143
|
+
[issue.category]: (artifact.summary.byCategory[issue.category] ?? 0) + 1,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export function updateReviewArtifactFindings(artifact, options, date = new Date()) {
|
|
149
|
+
const now = date.toISOString();
|
|
150
|
+
const updatedIds = [];
|
|
151
|
+
const findings = artifact.findings.map((finding) => {
|
|
152
|
+
if (!selectorMatches(finding, options)) {
|
|
153
|
+
return finding;
|
|
154
|
+
}
|
|
155
|
+
updatedIds.push(finding.id);
|
|
156
|
+
return {
|
|
157
|
+
...finding,
|
|
158
|
+
state: options.state ?? finding.state,
|
|
159
|
+
disposition: options.disposition ?? finding.disposition,
|
|
160
|
+
updatedAt: now,
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
artifact: {
|
|
165
|
+
...artifact,
|
|
166
|
+
findings,
|
|
167
|
+
},
|
|
168
|
+
updatedIds,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=review-artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-artifact.js","sourceRoot":"","sources":["../../src/lib/review-artifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core review execution logic shared between local and platform reviews
|
|
3
3
|
*
|
|
4
|
-
* This module contains the common agent execution logic
|
|
5
|
-
* between review-orchestrator.ts (local) and unified-review-executor.ts (platform).
|
|
4
|
+
* This module contains the common agent execution logic used by the review orchestrator.
|
|
6
5
|
*/
|
|
7
6
|
import type { DRSConfig } from './config.js';
|
|
8
7
|
import { calculateSummary, type ReviewIssue } from './comment-formatter.js';
|
|
9
8
|
import type { ChangeSummary } from './change-summary.js';
|
|
10
9
|
import type { RuntimeClient } from '../runtime/client.js';
|
|
10
|
+
import type { ReviewVerificationContext, ReviewVerificationResult } from './review-orchestrator.js';
|
|
11
11
|
import { type AgentUsageSummary, type ReviewUsageSummary } from './review-usage.js';
|
|
12
12
|
/**
|
|
13
13
|
* File with optional diff content
|
|
@@ -34,11 +34,14 @@ export interface AgentReviewResult {
|
|
|
34
34
|
agentResults: AgentResult[];
|
|
35
35
|
/** Token usage and cost details for the review run */
|
|
36
36
|
usage?: ReviewUsageSummary;
|
|
37
|
+
/** Explicit verification verdicts for existing review findings. */
|
|
38
|
+
verification?: ReviewVerificationResult;
|
|
37
39
|
}
|
|
38
40
|
export interface AgentResult {
|
|
39
41
|
agentType: string;
|
|
40
42
|
success: boolean;
|
|
41
43
|
issues: ReviewIssue[];
|
|
44
|
+
verification?: ReviewVerificationResult;
|
|
42
45
|
usage?: AgentUsageSummary;
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
@@ -48,8 +51,7 @@ export interface AgentResult {
|
|
|
48
51
|
* @param files - List of files with optional diff content
|
|
49
52
|
* @param diffCommand - Fallback git diff command hint (used when diff not provided)
|
|
50
53
|
*/
|
|
51
|
-
export declare function buildBaseInstructions(label: string, files: FileWithDiff[], diffCommand?: string, compressionSummary?: string): string;
|
|
52
|
-
export declare function runUnifiedReviewAgent(runtime: RuntimeClient, config: DRSConfig, baseInstructions: string, reviewLabel: string, filteredFiles: string[], additionalContext?: Record<string, unknown>, workingDir?: string, debug?: boolean): Promise<AgentReviewResult>;
|
|
54
|
+
export declare function buildBaseInstructions(label: string, files: FileWithDiff[], diffCommand?: string, compressionSummary?: string, verificationContext?: ReviewVerificationContext): string;
|
|
53
55
|
export declare function runReviewAgents(runtime: RuntimeClient, config: DRSConfig, baseInstructions: string, reviewLabel: string, filteredFiles: string[], additionalContext?: Record<string, unknown>, workingDir?: string, debug?: boolean): Promise<AgentReviewResult>;
|
|
54
56
|
export declare function runReviewPipeline(runtime: RuntimeClient, config: DRSConfig, baseInstructions: string, reviewLabel: string, filteredFiles: string[], additionalContext?: Record<string, unknown>, workingDir?: string, debug?: boolean): Promise<AgentReviewResult>;
|
|
55
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-core.d.ts","sourceRoot":"","sources":["../../src/lib/review-core.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"review-core.d.ts","sourceRoot":"","sources":["../../src/lib/review-core.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/review-core.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core review execution logic shared between local and platform reviews
|
|
3
3
|
*
|
|
4
|
-
* This module contains the common agent execution logic
|
|
5
|
-
* between review-orchestrator.ts (local) and unified-review-executor.ts (platform).
|
|
4
|
+
* This module contains the common agent execution logic used by the review orchestrator.
|
|
6
5
|
*/
|
|
7
6
|
import chalk from 'chalk';
|
|
8
|
-
import {
|
|
7
|
+
import { getModelOverrides, getReviewAgentIds, getUnifiedModelOverride, resolveAgentSkills, } from './config.js';
|
|
9
8
|
import { buildReviewPrompt } from './context-loader.js';
|
|
10
9
|
import { parseReviewIssues } from './issue-parser.js';
|
|
11
10
|
import { parseReviewOutput } from './review-parser.js';
|
|
12
11
|
import { calculateSummary } from './comment-formatter.js';
|
|
13
|
-
import {
|
|
12
|
+
import { loadAgents } from '../runtime/agent-loader.js';
|
|
14
13
|
import { getLogger } from './logger.js';
|
|
15
|
-
import { aggregateAgentUsage, applyUsageMessage, createAgentUsageSummary, } from './review-usage.js';
|
|
14
|
+
import { aggregateAgentUsage, applySkillCall, applyToolCall, applyUsageMessage, createAgentUsageSummary, } from './review-usage.js';
|
|
16
15
|
import { estimatePromptBudget, formatPromptBudgetEstimate } from './prompt-budget.js';
|
|
17
16
|
/**
|
|
18
17
|
* Build base review instructions for agents
|
|
@@ -21,7 +20,7 @@ import { estimatePromptBudget, formatPromptBudgetEstimate } from './prompt-budge
|
|
|
21
20
|
* @param files - List of files with optional diff content
|
|
22
21
|
* @param diffCommand - Fallback git diff command hint (used when diff not provided)
|
|
23
22
|
*/
|
|
24
|
-
export function buildBaseInstructions(label, files, diffCommand, compressionSummary) {
|
|
23
|
+
export function buildBaseInstructions(label, files, diffCommand, compressionSummary, verificationContext) {
|
|
25
24
|
// Check if we have actual diff content
|
|
26
25
|
const filesWithDiffs = files.filter((f) => f.patch);
|
|
27
26
|
const hasDiffs = filesWithDiffs.length > 0;
|
|
@@ -81,18 +80,19 @@ ${compressionSummary ? `${compressionSummary}\n\n` : ''}Output requirements:
|
|
|
81
80
|
"references": ["https://link1", "https://link2"],
|
|
82
81
|
"agent": "security" | "quality" | "style" | "performance" | "documentation" | "unified"
|
|
83
82
|
}
|
|
84
|
-
]
|
|
83
|
+
]${verificationContext ? buildVerificationSchemaSnippet() : ''}
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
**Analysis approach:**
|
|
88
87
|
1. First, use Grep or Read to quickly understand the project's existing patterns relevant to the changed files (e.g., existing validation, error handling, auth patterns, naming conventions).
|
|
89
88
|
2. Then analyze the diff content above against those established patterns.
|
|
89
|
+
3. If the prompt says a diff was omitted or summarized, call git_diff for that file before making file-specific claims.
|
|
90
90
|
|
|
91
91
|
**Review rules:**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
4. **IMPORTANT: Only report issues on lines that were actually changed or added (lines starting with + in the diff).** Do not report issues on unchanged code.
|
|
93
|
+
5. Only flag deviations or new risks introduced by the changes.
|
|
94
|
+
6. Populate summary counts based on the issues you report (use 0 when none).
|
|
95
|
+
7. Focus on the changes - only report issues for newly added or modified lines (lines with + prefix in the diff).`;
|
|
96
96
|
}
|
|
97
97
|
// No diff content available - instruct agent to read files directly
|
|
98
98
|
return `Review the following changed files from ${label}:
|
|
@@ -139,40 +139,52 @@ Output requirements:
|
|
|
139
139
|
"references": ["https://link1", "https://link2"],
|
|
140
140
|
"agent": "security" | "quality" | "style" | "performance" | "documentation" | "unified"
|
|
141
141
|
}
|
|
142
|
-
]
|
|
142
|
+
]${verificationContext ? buildVerificationSchemaSnippet() : ''}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
**Instructions:**
|
|
146
|
-
1. The diffs for these files were omitted due to size constraints. Use the
|
|
147
|
-
2. Focus your review on newly added or modified code patterns.
|
|
146
|
+
1. The diffs for these files were omitted due to size constraints. Use git_diff to inspect the file diffs, then use Read/Grep for surrounding context as needed.
|
|
147
|
+
2. Focus your review on newly added or modified code patterns from the git_diff output.
|
|
148
148
|
3. **IMPORTANT: Only report issues on lines that were actually changed or added.** Do not report issues on existing code that was not modified.
|
|
149
149
|
4. Analyze the changed code for issues in your specialty area
|
|
150
150
|
5. Populate summary counts based on the issues you report (use 0 when none).
|
|
151
151
|
6. Focus on the changes - only report issues for newly added or modified lines.`;
|
|
152
152
|
}
|
|
153
|
+
function buildVerificationSchemaSnippet() {
|
|
154
|
+
return `,
|
|
155
|
+
"verification": {
|
|
156
|
+
"findings": [
|
|
157
|
+
{
|
|
158
|
+
"id": "F001",
|
|
159
|
+
"disposition": "resolved",
|
|
160
|
+
"rationale": "short explanation",
|
|
161
|
+
"issue": null
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}`;
|
|
165
|
+
}
|
|
153
166
|
/**
|
|
154
167
|
* Get information about configured review agents
|
|
155
168
|
*/
|
|
156
169
|
function getConfiguredAgentInfo(config, workingDir, cachedAgents) {
|
|
157
|
-
const configuredNames =
|
|
158
|
-
const allAgents = cachedAgents ??
|
|
170
|
+
const configuredNames = getReviewAgentIds(config);
|
|
171
|
+
const allAgents = cachedAgents ?? loadAgents(workingDir, config);
|
|
159
172
|
return configuredNames
|
|
160
|
-
.map((
|
|
161
|
-
const
|
|
162
|
-
const agent = allAgents.find((a) => a.name === fullName);
|
|
173
|
+
.map((agentId) => {
|
|
174
|
+
const agent = allAgents.find((a) => a.id === agentId);
|
|
163
175
|
return {
|
|
164
|
-
name,
|
|
165
|
-
description: agent?.description ?? `${
|
|
176
|
+
name: agentId,
|
|
177
|
+
description: agent?.description ?? `${agentId} review agent`,
|
|
166
178
|
};
|
|
167
179
|
})
|
|
168
180
|
.filter((a) => a !== null);
|
|
169
181
|
}
|
|
170
182
|
function validateConfiguredReviewAgents(config, workingDir, cachedAgents) {
|
|
171
|
-
const
|
|
172
|
-
const availableAgents = new Set((cachedAgents ??
|
|
173
|
-
.filter((agent) => agent.
|
|
174
|
-
.map((agent) => agent.
|
|
175
|
-
const missingAgents =
|
|
183
|
+
const configuredAgentIds = getReviewAgentIds(config);
|
|
184
|
+
const availableAgents = new Set((cachedAgents ?? loadAgents(workingDir, config))
|
|
185
|
+
.filter((agent) => agent.namespace === 'review')
|
|
186
|
+
.map((agent) => agent.id));
|
|
187
|
+
const missingAgents = configuredAgentIds.filter((agentId) => !availableAgents.has(agentId));
|
|
176
188
|
if (missingAgents.length === 0) {
|
|
177
189
|
return;
|
|
178
190
|
}
|
|
@@ -192,11 +204,7 @@ function summarizeRunUsage(agentResults) {
|
|
|
192
204
|
return aggregateAgentUsage(agentUsage);
|
|
193
205
|
}
|
|
194
206
|
function getConfiguredSkillsForAgent(config, agentType) {
|
|
195
|
-
|
|
196
|
-
const normalizedAgents = normalizeAgentConfig(config.review.agents);
|
|
197
|
-
const agentConfig = normalizedAgents.find((agent) => agent.name === agentType || agent.name === `review/${agentType}`);
|
|
198
|
-
const agentSkills = (agentConfig?.skills ?? []).map(String).filter((skill) => skill.length > 0);
|
|
199
|
-
return [...new Set([...defaultSkills, ...agentSkills])];
|
|
207
|
+
return resolveAgentSkills(config, agentType);
|
|
200
208
|
}
|
|
201
209
|
function resolveReviewModelOverrides(config) {
|
|
202
210
|
return {
|
|
@@ -260,144 +268,8 @@ function extractSkillNameFromToolOutput(content) {
|
|
|
260
268
|
}
|
|
261
269
|
return undefined;
|
|
262
270
|
}
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
const agentName = `review/${agentType}`;
|
|
266
|
-
console.log(chalk.bold('🎯 Selected Agents: unified-reviewer\n'));
|
|
267
|
-
console.log(chalk.gray('Running unified review...\n'));
|
|
268
|
-
let agentUsage = createAgentUsageSummary(agentType);
|
|
269
|
-
const configuredSkills = getConfiguredSkillsForAgent(config, agentType);
|
|
270
|
-
const reviewModelOverrides = resolveReviewModelOverrides(config);
|
|
271
|
-
const modelId = reviewModelOverrides[agentName];
|
|
272
|
-
let sawSkillToolCall = false;
|
|
273
|
-
const describeSummary = typeof additionalContext.describeSummary === 'string'
|
|
274
|
-
? additionalContext.describeSummary
|
|
275
|
-
: undefined;
|
|
276
|
-
try {
|
|
277
|
-
const reviewPrompt = buildReviewPrompt(agentType, baseInstructions, reviewLabel, filteredFiles, workingDir, config, describeSummary);
|
|
278
|
-
logPromptInputBudget({
|
|
279
|
-
runtime,
|
|
280
|
-
config,
|
|
281
|
-
agentType,
|
|
282
|
-
prompt: reviewPrompt,
|
|
283
|
-
modelId,
|
|
284
|
-
});
|
|
285
|
-
const logger = getLogger();
|
|
286
|
-
if (debug) {
|
|
287
|
-
console.log(chalk.gray('┌── DEBUG: Message sent to review agent'));
|
|
288
|
-
console.log(chalk.gray(`│ Agent: ${agentName}`));
|
|
289
|
-
console.log(chalk.gray('│ Prompt:'));
|
|
290
|
-
console.log(chalk.gray('─'.repeat(60)));
|
|
291
|
-
console.log(reviewPrompt);
|
|
292
|
-
console.log(chalk.gray('─'.repeat(60)));
|
|
293
|
-
console.log(chalk.gray(`└── End message for ${agentName}\n`));
|
|
294
|
-
}
|
|
295
|
-
else {
|
|
296
|
-
logger.agentInput(agentType, reviewPrompt);
|
|
297
|
-
}
|
|
298
|
-
const session = await runtime.createSession({
|
|
299
|
-
agent: agentName,
|
|
300
|
-
message: reviewPrompt,
|
|
301
|
-
});
|
|
302
|
-
const agentIssues = [];
|
|
303
|
-
let fullResponse = '';
|
|
304
|
-
for await (const message of runtime.streamMessages(session.id)) {
|
|
305
|
-
if (message.role === 'tool') {
|
|
306
|
-
// Detect skill loading: legacy 'skill' tool or Pi-native read of SKILL.md
|
|
307
|
-
const skillFromLegacy = message.toolName === 'skill'
|
|
308
|
-
? extractSkillNameFromToolOutput(message.content)
|
|
309
|
-
: undefined;
|
|
310
|
-
const skillFromRead = extractSkillNameFromReadToolOutput(message.toolName, message.content);
|
|
311
|
-
const skillName = skillFromLegacy ?? skillFromRead;
|
|
312
|
-
if (skillName) {
|
|
313
|
-
logger.skillLoaded(skillName, agentType);
|
|
314
|
-
sawSkillToolCall = true;
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
logger.toolOutput(message.toolName ?? 'unknown', agentType, message.content);
|
|
318
|
-
}
|
|
319
|
-
continue;
|
|
320
|
-
}
|
|
321
|
-
if (message.role === 'assistant') {
|
|
322
|
-
agentUsage = applyUsageMessage(agentUsage, message);
|
|
323
|
-
if (!message.content.trim()) {
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
fullResponse += message.content;
|
|
327
|
-
if (debug) {
|
|
328
|
-
console.log(chalk.gray(`┌── DEBUG: Full response from ${agentName}`));
|
|
329
|
-
console.log(message.content);
|
|
330
|
-
console.log(chalk.gray(`└── End response for ${agentName}\n`));
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
logger.agentMessage(agentType, message.content);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (configuredSkills.length > 0 && !sawSkillToolCall) {
|
|
338
|
-
logger.noSkillCalls(agentType);
|
|
339
|
-
}
|
|
340
|
-
await runtime.closeSession(session.id);
|
|
341
|
-
try {
|
|
342
|
-
const reviewOutput = await parseReviewOutput(workingDir, debug, fullResponse);
|
|
343
|
-
const parsedIssues = parseReviewIssues(JSON.stringify(reviewOutput), 'unified');
|
|
344
|
-
if (parsedIssues.length > 0) {
|
|
345
|
-
agentIssues.push(...parsedIssues);
|
|
346
|
-
console.log(chalk.green(`✓ [unified] Found ${parsedIssues.length} issue(s)`));
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
catch (parseError) {
|
|
350
|
-
console.error(chalk.red('Failed to parse unified review output'));
|
|
351
|
-
if (debug) {
|
|
352
|
-
console.log(chalk.dim('Unified agent output:'), fullResponse);
|
|
353
|
-
}
|
|
354
|
-
const reason = parseError instanceof Error ? `: ${parseError.message}` : '';
|
|
355
|
-
throw new Error(`Unified review agent did not return valid JSON output${reason}`);
|
|
356
|
-
}
|
|
357
|
-
const summary = calculateSummary(filteredFiles.length, agentIssues);
|
|
358
|
-
const agentResults = [
|
|
359
|
-
{
|
|
360
|
-
agentType,
|
|
361
|
-
success: true,
|
|
362
|
-
issues: agentIssues,
|
|
363
|
-
usage: {
|
|
364
|
-
...agentUsage,
|
|
365
|
-
success: true,
|
|
366
|
-
},
|
|
367
|
-
},
|
|
368
|
-
];
|
|
369
|
-
return {
|
|
370
|
-
issues: agentIssues,
|
|
371
|
-
summary,
|
|
372
|
-
filesReviewed: filteredFiles.length,
|
|
373
|
-
agentResults,
|
|
374
|
-
usage: summarizeRunUsage(agentResults),
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
catch (error) {
|
|
378
|
-
console.error(chalk.red(`✗ unified-reviewer agent failed: ${error}`));
|
|
379
|
-
const agentResults = [
|
|
380
|
-
{
|
|
381
|
-
agentType,
|
|
382
|
-
success: false,
|
|
383
|
-
issues: [],
|
|
384
|
-
usage: {
|
|
385
|
-
...agentUsage,
|
|
386
|
-
success: false,
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
];
|
|
390
|
-
return {
|
|
391
|
-
issues: [],
|
|
392
|
-
summary: calculateSummary(filteredFiles.length, []),
|
|
393
|
-
filesReviewed: filteredFiles.length,
|
|
394
|
-
agentResults,
|
|
395
|
-
usage: summarizeRunUsage(agentResults),
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel, filteredFiles, workingDir, debug, agentType, reviewModelOverrides, describeSummary) {
|
|
400
|
-
const agentName = `review/${agentType}`;
|
|
271
|
+
async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel, filteredFiles, workingDir, debug, agentType, reviewModelOverrides, describeSummary, verificationContext) {
|
|
272
|
+
const agentName = agentType;
|
|
401
273
|
console.log(chalk.gray(`Running ${agentType} review...\n`));
|
|
402
274
|
let agentUsage = createAgentUsageSummary(agentType);
|
|
403
275
|
const configuredSkills = getConfiguredSkillsForAgent(config, agentType);
|
|
@@ -405,7 +277,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
405
277
|
let sawSkillToolCall = false;
|
|
406
278
|
try {
|
|
407
279
|
// Build prompt with global and agent-specific context
|
|
408
|
-
const reviewPrompt = buildReviewPrompt(agentType, baseInstructions, reviewLabel, filteredFiles, workingDir, config, describeSummary);
|
|
280
|
+
const reviewPrompt = buildReviewPrompt(agentType, baseInstructions, reviewLabel, filteredFiles, workingDir, config, describeSummary, verificationContext);
|
|
409
281
|
logPromptInputBudget({
|
|
410
282
|
runtime,
|
|
411
283
|
config,
|
|
@@ -435,6 +307,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
435
307
|
// Collect results from this agent
|
|
436
308
|
for await (const message of runtime.streamMessages(session.id)) {
|
|
437
309
|
if (message.role === 'tool') {
|
|
310
|
+
agentUsage = applyToolCall(agentUsage, message.toolName);
|
|
438
311
|
// Detect skill loading: legacy 'skill' tool or Pi-native read of SKILL.md
|
|
439
312
|
const skillFromLegacy = message.toolName === 'skill'
|
|
440
313
|
? extractSkillNameFromToolOutput(message.content)
|
|
@@ -442,6 +315,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
442
315
|
const skillFromRead = extractSkillNameFromReadToolOutput(message.toolName, message.content);
|
|
443
316
|
const skillName = skillFromLegacy ?? skillFromRead;
|
|
444
317
|
if (skillName) {
|
|
318
|
+
agentUsage = applySkillCall(agentUsage, skillName);
|
|
445
319
|
logger.skillLoaded(skillName, agentType);
|
|
446
320
|
sawSkillToolCall = true;
|
|
447
321
|
}
|
|
@@ -472,6 +346,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
472
346
|
await runtime.closeSession(session.id);
|
|
473
347
|
const reviewOutput = await parseReviewOutput(workingDir, debug, fullResponse);
|
|
474
348
|
const parsedIssues = parseReviewIssues(JSON.stringify(reviewOutput), agentType);
|
|
349
|
+
const verification = parseReviewVerification(reviewOutput);
|
|
475
350
|
if (parsedIssues.length > 0) {
|
|
476
351
|
agentIssues.push(...parsedIssues);
|
|
477
352
|
console.log(chalk.green(`✓ [${agentType}] Found ${parsedIssues.length} issue(s)`));
|
|
@@ -480,6 +355,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
480
355
|
agentType,
|
|
481
356
|
success: true,
|
|
482
357
|
issues: agentIssues,
|
|
358
|
+
verification,
|
|
483
359
|
usage: {
|
|
484
360
|
...agentUsage,
|
|
485
361
|
success: true,
|
|
@@ -501,7 +377,7 @@ async function executeSingleAgent(runtime, config, baseInstructions, reviewLabel
|
|
|
501
377
|
}
|
|
502
378
|
export async function runReviewAgents(runtime, config, baseInstructions, reviewLabel, filteredFiles, additionalContext = {}, workingDir = process.cwd(), debug = false) {
|
|
503
379
|
console.log(chalk.gray('Starting code analysis...\n'));
|
|
504
|
-
const allAgents =
|
|
380
|
+
const allAgents = loadAgents(workingDir, config);
|
|
505
381
|
validateConfiguredReviewAgents(config, workingDir, allAgents);
|
|
506
382
|
const configuredAgentInfo = getConfiguredAgentInfo(config, workingDir, allAgents);
|
|
507
383
|
if (configuredAgentInfo.length > 0) {
|
|
@@ -511,13 +387,16 @@ export async function runReviewAgents(runtime, config, baseInstructions, reviewL
|
|
|
511
387
|
});
|
|
512
388
|
console.log('');
|
|
513
389
|
}
|
|
514
|
-
const agentNames =
|
|
390
|
+
const agentNames = getReviewAgentIds(config);
|
|
515
391
|
console.log(chalk.bold(`🎯 Selected Agents: ${agentNames.join(', ') || 'None'}\n`));
|
|
516
392
|
const reviewModelOverrides = resolveReviewModelOverrides(config);
|
|
517
393
|
const describeSummary = typeof additionalContext.describeSummary === 'string'
|
|
518
394
|
? additionalContext.describeSummary
|
|
519
395
|
: undefined;
|
|
520
|
-
const
|
|
396
|
+
const verificationContext = isReviewVerificationContext(additionalContext.verificationContext)
|
|
397
|
+
? additionalContext.verificationContext
|
|
398
|
+
: undefined;
|
|
399
|
+
const agentResults = await Promise.all(agentNames.map((agentType) => executeSingleAgent(runtime, config, baseInstructions, reviewLabel, filteredFiles, workingDir, debug, agentType, reviewModelOverrides, describeSummary, verificationContext)));
|
|
521
400
|
// Check agent results
|
|
522
401
|
const successfulAgents = agentResults.filter((r) => r.success);
|
|
523
402
|
const failedAgents = agentResults.filter((r) => !r.success);
|
|
@@ -537,17 +416,53 @@ export async function runReviewAgents(runtime, config, baseInstructions, reviewL
|
|
|
537
416
|
const issues = [];
|
|
538
417
|
agentResults.forEach((result) => issues.push(...result.issues));
|
|
539
418
|
const summary = calculateSummary(filteredFiles.length, issues);
|
|
419
|
+
const verificationFindings = agentResults.flatMap((result) => result.verification?.findings ?? []);
|
|
540
420
|
return {
|
|
541
421
|
issues,
|
|
542
422
|
summary,
|
|
543
423
|
filesReviewed: filteredFiles.length,
|
|
544
424
|
agentResults,
|
|
425
|
+
verification: verificationFindings.length > 0 ? { findings: verificationFindings } : undefined,
|
|
545
426
|
usage: summarizeRunUsage(agentResults),
|
|
546
427
|
};
|
|
547
428
|
}
|
|
548
429
|
export async function runReviewPipeline(runtime, config, baseInstructions, reviewLabel, filteredFiles, additionalContext = {}, workingDir = process.cwd(), debug = false) {
|
|
549
430
|
return runReviewAgents(runtime, config, baseInstructions, reviewLabel, filteredFiles, additionalContext, workingDir, debug);
|
|
550
431
|
}
|
|
432
|
+
function isReviewVerificationContext(value) {
|
|
433
|
+
if (!value || typeof value !== 'object') {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
const candidate = value;
|
|
437
|
+
return !!candidate.artifact && Array.isArray(candidate.artifact.findings);
|
|
438
|
+
}
|
|
439
|
+
function parseReviewVerification(value) {
|
|
440
|
+
if (!value || typeof value !== 'object') {
|
|
441
|
+
return undefined;
|
|
442
|
+
}
|
|
443
|
+
const verification = value.verification;
|
|
444
|
+
if (!verification || typeof verification !== 'object') {
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
447
|
+
const findings = verification.findings;
|
|
448
|
+
if (!Array.isArray(findings)) {
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
451
|
+
const parsed = findings.filter(isReviewVerificationFinding);
|
|
452
|
+
return parsed.length > 0 ? { findings: parsed } : undefined;
|
|
453
|
+
}
|
|
454
|
+
function isReviewVerificationFinding(value) {
|
|
455
|
+
if (!value || typeof value !== 'object') {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
const candidate = value;
|
|
459
|
+
return (typeof candidate.id === 'string' &&
|
|
460
|
+
isReviewVerificationDisposition(candidate.disposition) &&
|
|
461
|
+
(candidate.rationale === undefined || typeof candidate.rationale === 'string'));
|
|
462
|
+
}
|
|
463
|
+
function isReviewVerificationDisposition(value) {
|
|
464
|
+
return value === 'resolved' || value === 'still_open' || value === 'partial';
|
|
465
|
+
}
|
|
551
466
|
/**
|
|
552
467
|
* Display review summary to terminal
|
|
553
468
|
*/
|