@kya-os/cli 1.8.1 → 1.8.3
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/dist/commands/agent.d.ts +35 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +321 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/build.js +2 -2
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.js +3 -3
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/checkpoint-init.d.ts +1 -1
- package/dist/commands/checkpoint-init.d.ts.map +1 -1
- package/dist/commands/checkpoint-init.js +8 -41
- package/dist/commands/checkpoint-init.js.map +1 -1
- package/dist/commands/claim.js +2 -2
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/dco.d.ts +59 -0
- package/dist/commands/dco.d.ts.map +1 -1
- package/dist/commands/dco.js +280 -5
- package/dist/commands/dco.js.map +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +18 -24
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/env.js +6 -6
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/identity.js +3 -3
- package/dist/commands/identity.js.map +1 -1
- package/dist/commands/init-stages.d.ts +141 -0
- package/dist/commands/init-stages.d.ts.map +1 -0
- package/dist/commands/init-stages.js +684 -0
- package/dist/commands/init-stages.js.map +1 -0
- package/dist/commands/init.d.ts +46 -16
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +229 -279
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/orchestrator.d.ts +18 -0
- package/dist/commands/orchestrator.d.ts.map +1 -0
- package/dist/commands/orchestrator.js +251 -0
- package/dist/commands/orchestrator.js.map +1 -0
- package/dist/commands/register.d.ts +1 -1
- package/dist/commands/register.d.ts.map +1 -1
- package/dist/commands/register.js +35 -7
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/review.d.ts +48 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +220 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/rotate.js +4 -4
- package/dist/commands/rotate.js.map +1 -1
- package/dist/commands/score.d.ts +15 -0
- package/dist/commands/score.d.ts.map +1 -0
- package/dist/commands/score.js +471 -0
- package/dist/commands/score.js.map +1 -0
- package/dist/commands/start.js +3 -3
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/verify.js +6 -6
- package/dist/commands/verify.js.map +1 -1
- package/dist/dco.d.ts +4 -0
- package/dist/dco.d.ts.map +1 -0
- package/dist/dco.js +23 -0
- package/dist/dco.js.map +1 -0
- package/dist/index.js +52 -9
- package/dist/orchestrator/daemon.d.ts +137 -0
- package/dist/orchestrator/daemon.d.ts.map +1 -0
- package/dist/orchestrator/daemon.js +242 -0
- package/dist/orchestrator/daemon.js.map +1 -0
- package/dist/orchestrator/db/dispatches.d.ts +108 -0
- package/dist/orchestrator/db/dispatches.d.ts.map +1 -0
- package/dist/orchestrator/db/dispatches.js +122 -0
- package/dist/orchestrator/db/dispatches.js.map +1 -0
- package/dist/orchestrator/db/index.d.ts +50 -0
- package/dist/orchestrator/db/index.d.ts.map +1 -0
- package/dist/orchestrator/db/index.js +116 -0
- package/dist/orchestrator/db/index.js.map +1 -0
- package/dist/orchestrator/db/journal.d.ts +93 -0
- package/dist/orchestrator/db/journal.d.ts.map +1 -0
- package/dist/orchestrator/db/journal.js +91 -0
- package/dist/orchestrator/db/journal.js.map +1 -0
- package/dist/orchestrator/db/liveness.d.ts +97 -0
- package/dist/orchestrator/db/liveness.d.ts.map +1 -0
- package/dist/orchestrator/db/liveness.js +105 -0
- package/dist/orchestrator/db/liveness.js.map +1 -0
- package/dist/orchestrator/db/mission.d.ts +78 -0
- package/dist/orchestrator/db/mission.d.ts.map +1 -0
- package/dist/orchestrator/db/mission.js +99 -0
- package/dist/orchestrator/db/mission.js.map +1 -0
- package/dist/orchestrator/db/schema.d.ts +14 -0
- package/dist/orchestrator/db/schema.d.ts.map +1 -0
- package/dist/orchestrator/db/schema.js +169 -0
- package/dist/orchestrator/db/schema.js.map +1 -0
- package/dist/orchestrator/db/tickets.d.ts +147 -0
- package/dist/orchestrator/db/tickets.d.ts.map +1 -0
- package/dist/orchestrator/db/tickets.js +238 -0
- package/dist/orchestrator/db/tickets.js.map +1 -0
- package/dist/orchestrator/db/verdicts.d.ts +187 -0
- package/dist/orchestrator/db/verdicts.d.ts.map +1 -0
- package/dist/orchestrator/db/verdicts.js +197 -0
- package/dist/orchestrator/db/verdicts.js.map +1 -0
- package/dist/orchestrator/events.d.ts +69 -0
- package/dist/orchestrator/events.d.ts.map +1 -0
- package/dist/orchestrator/events.js +20 -0
- package/dist/orchestrator/events.js.map +1 -0
- package/dist/orchestrator/github-credential-anchor-sender.d.ts +159 -0
- package/dist/orchestrator/github-credential-anchor-sender.d.ts.map +1 -0
- package/dist/orchestrator/github-credential-anchor-sender.js +313 -0
- package/dist/orchestrator/github-credential-anchor-sender.js.map +1 -0
- package/dist/orchestrator/hub-dispatch.d.ts +120 -0
- package/dist/orchestrator/hub-dispatch.d.ts.map +1 -0
- package/dist/orchestrator/hub-dispatch.js +257 -0
- package/dist/orchestrator/hub-dispatch.js.map +1 -0
- package/dist/orchestrator/hub-observer.d.ts +201 -0
- package/dist/orchestrator/hub-observer.d.ts.map +1 -0
- package/dist/orchestrator/hub-observer.js +474 -0
- package/dist/orchestrator/hub-observer.js.map +1 -0
- package/dist/orchestrator/journal-writer.d.ts +80 -0
- package/dist/orchestrator/journal-writer.d.ts.map +1 -0
- package/dist/orchestrator/journal-writer.js +113 -0
- package/dist/orchestrator/journal-writer.js.map +1 -0
- package/dist/orchestrator/mcp/server.d.ts +136 -0
- package/dist/orchestrator/mcp/server.d.ts.map +1 -0
- package/dist/orchestrator/mcp/server.js +582 -0
- package/dist/orchestrator/mcp/server.js.map +1 -0
- package/dist/orchestrator/mcp/stdio.d.ts +22 -0
- package/dist/orchestrator/mcp/stdio.d.ts.map +1 -0
- package/dist/orchestrator/mcp/stdio.js +51 -0
- package/dist/orchestrator/mcp/stdio.js.map +1 -0
- package/dist/orchestrator/review.d.ts +131 -0
- package/dist/orchestrator/review.d.ts.map +1 -0
- package/dist/orchestrator/review.js +322 -0
- package/dist/orchestrator/review.js.map +1 -0
- package/dist/tui/app.d.ts +33 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +71 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/components.d.ts +110 -0
- package/dist/tui/components.d.ts.map +1 -0
- package/dist/tui/components.js +118 -0
- package/dist/tui/components.js.map +1 -0
- package/dist/tui/index.d.ts +30 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +95 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/keymap.d.ts +33 -0
- package/dist/tui/keymap.d.ts.map +1 -0
- package/dist/tui/keymap.js +49 -0
- package/dist/tui/keymap.js.map +1 -0
- package/dist/tui/nav.d.ts +29 -0
- package/dist/tui/nav.d.ts.map +1 -0
- package/dist/tui/nav.js +39 -0
- package/dist/tui/nav.js.map +1 -0
- package/dist/tui/sanitize.d.ts +25 -0
- package/dist/tui/sanitize.d.ts.map +1 -0
- package/dist/tui/sanitize.js +36 -0
- package/dist/tui/sanitize.js.map +1 -0
- package/dist/tui/theme.d.ts +32 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +63 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/views/agents.d.ts +67 -0
- package/dist/tui/views/agents.d.ts.map +1 -0
- package/dist/tui/views/agents.js +231 -0
- package/dist/tui/views/agents.js.map +1 -0
- package/dist/tui/views/index.d.ts +93 -0
- package/dist/tui/views/index.d.ts.map +1 -0
- package/dist/tui/views/index.js +150 -0
- package/dist/tui/views/index.js.map +1 -0
- package/dist/tui/views/registry.d.ts +22 -0
- package/dist/tui/views/registry.d.ts.map +1 -0
- package/dist/tui/views/registry.js +110 -0
- package/dist/tui/views/registry.js.map +1 -0
- package/dist/utils/agent/backoff.d.ts +31 -0
- package/dist/utils/agent/backoff.d.ts.map +1 -0
- package/dist/utils/agent/backoff.js +51 -0
- package/dist/utils/agent/backoff.js.map +1 -0
- package/dist/utils/agent/markers.d.ts +87 -0
- package/dist/utils/agent/markers.d.ts.map +1 -0
- package/dist/utils/agent/markers.js +147 -0
- package/dist/utils/agent/markers.js.map +1 -0
- package/dist/utils/agent/review.d.ts +67 -0
- package/dist/utils/agent/review.d.ts.map +1 -0
- package/dist/utils/agent/review.js +305 -0
- package/dist/utils/agent/review.js.map +1 -0
- package/dist/utils/agent/spawn-agent.d.ts +117 -0
- package/dist/utils/agent/spawn-agent.d.ts.map +1 -0
- package/dist/utils/agent/spawn-agent.js +177 -0
- package/dist/utils/agent/spawn-agent.js.map +1 -0
- package/dist/utils/agent/task.d.ts +101 -0
- package/dist/utils/agent/task.d.ts.map +1 -0
- package/dist/utils/agent/task.js +357 -0
- package/dist/utils/agent/task.js.map +1 -0
- package/dist/utils/agent/verify.d.ts +47 -0
- package/dist/utils/agent/verify.d.ts.map +1 -0
- package/dist/utils/agent/verify.js +144 -0
- package/dist/utils/agent/verify.js.map +1 -0
- package/dist/utils/agent-detector.d.ts +48 -0
- package/dist/utils/agent-detector.d.ts.map +1 -0
- package/dist/utils/agent-detector.js +74 -0
- package/dist/utils/agent-detector.js.map +1 -0
- package/dist/utils/agent-profile-stage.d.ts +70 -0
- package/dist/utils/agent-profile-stage.d.ts.map +1 -0
- package/dist/utils/agent-profile-stage.js +153 -0
- package/dist/utils/agent-profile-stage.js.map +1 -0
- package/dist/utils/agent-profiles.d.ts +27 -0
- package/dist/utils/agent-profiles.d.ts.map +1 -0
- package/dist/utils/agent-profiles.js +61 -0
- package/dist/utils/agent-profiles.js.map +1 -0
- package/dist/utils/checkpoint-api.d.ts +1 -1
- package/dist/utils/checkpoint-api.js +1 -1
- package/dist/utils/checkpoint-env.d.ts +1 -1
- package/dist/utils/checkpoint-env.js +2 -2
- package/dist/utils/checkpoint-env.js.map +1 -1
- package/dist/utils/checkpoint-scaffold.d.ts +1 -1
- package/dist/utils/checkpoint-scaffold.js +1 -1
- package/dist/utils/cli-kit/browser.d.ts +24 -0
- package/dist/utils/cli-kit/browser.d.ts.map +1 -0
- package/dist/utils/cli-kit/browser.js +58 -0
- package/dist/utils/cli-kit/browser.js.map +1 -0
- package/dist/utils/cli-kit/claim-polling.d.ts +18 -0
- package/dist/utils/cli-kit/claim-polling.d.ts.map +1 -0
- package/dist/utils/{claim-polling.js → cli-kit/claim-polling.js} +19 -26
- package/dist/utils/cli-kit/claim-polling.js.map +1 -0
- package/dist/utils/cli-kit/diagnostics.d.ts +9 -0
- package/dist/utils/cli-kit/diagnostics.d.ts.map +1 -0
- package/dist/utils/cli-kit/diagnostics.js +11 -0
- package/dist/utils/cli-kit/diagnostics.js.map +1 -0
- package/dist/utils/cli-kit/fs-safe.d.ts +14 -0
- package/dist/utils/cli-kit/fs-safe.d.ts.map +1 -0
- package/dist/utils/cli-kit/fs-safe.js +20 -0
- package/dist/utils/cli-kit/fs-safe.js.map +1 -0
- package/dist/utils/cli-kit/index.d.ts +15 -0
- package/dist/utils/cli-kit/index.d.ts.map +1 -0
- package/dist/utils/cli-kit/index.js +10 -0
- package/dist/utils/cli-kit/index.js.map +1 -0
- package/dist/utils/cli-kit/json-file.d.ts +21 -0
- package/dist/utils/cli-kit/json-file.d.ts.map +1 -0
- package/dist/utils/cli-kit/json-file.js +51 -0
- package/dist/utils/cli-kit/json-file.js.map +1 -0
- package/dist/utils/cli-kit/marker-block.d.ts +26 -0
- package/dist/utils/cli-kit/marker-block.d.ts.map +1 -0
- package/dist/utils/cli-kit/marker-block.js +61 -0
- package/dist/utils/cli-kit/marker-block.js.map +1 -0
- package/dist/utils/cli-kit/paths.d.ts +15 -0
- package/dist/utils/cli-kit/paths.d.ts.map +1 -0
- package/dist/utils/cli-kit/paths.js +21 -0
- package/dist/utils/cli-kit/paths.js.map +1 -0
- package/dist/utils/cli-kit/secure-storage.d.ts +14 -0
- package/dist/utils/cli-kit/secure-storage.d.ts.map +1 -0
- package/dist/utils/cli-kit/secure-storage.js +20 -0
- package/dist/utils/cli-kit/secure-storage.js.map +1 -0
- package/dist/utils/cli-kit/step-report.d.ts +16 -0
- package/dist/utils/cli-kit/step-report.d.ts.map +1 -0
- package/dist/utils/cli-kit/step-report.js +36 -0
- package/dist/utils/cli-kit/step-report.js.map +1 -0
- package/dist/utils/dco/agent-metadata.d.ts +1 -1
- package/dist/utils/dco/agent-metadata.js +1 -1
- package/dist/utils/dco/agent-metadata.js.map +1 -1
- package/dist/utils/dco/claude-config.d.ts +18 -14
- package/dist/utils/dco/claude-config.d.ts.map +1 -1
- package/dist/utils/dco/claude-config.js +31 -97
- package/dist/utils/dco/claude-config.js.map +1 -1
- package/dist/utils/dco/dispatch.d.ts +134 -0
- package/dist/utils/dco/dispatch.d.ts.map +1 -0
- package/dist/utils/dco/dispatch.js +399 -0
- package/dist/utils/dco/dispatch.js.map +1 -0
- package/dist/utils/dco/fix.d.ts +122 -0
- package/dist/utils/dco/fix.d.ts.map +1 -0
- package/dist/utils/dco/fix.js +560 -0
- package/dist/utils/dco/fix.js.map +1 -0
- package/dist/utils/dco/git-config.d.ts.map +1 -1
- package/dist/utils/dco/git-config.js +5 -3
- package/dist/utils/dco/git-config.js.map +1 -1
- package/dist/utils/dco/github.d.ts +101 -0
- package/dist/utils/dco/github.d.ts.map +1 -1
- package/dist/utils/dco/github.js +133 -0
- package/dist/utils/dco/github.js.map +1 -1
- package/dist/utils/dco/paths.d.ts +1 -8
- package/dist/utils/dco/paths.d.ts.map +1 -1
- package/dist/utils/dco/paths.js +3 -12
- package/dist/utils/dco/paths.js.map +1 -1
- package/dist/utils/dco/render.d.ts +1 -1
- package/dist/utils/dco/render.d.ts.map +1 -1
- package/dist/utils/dco/render.js +4 -21
- package/dist/utils/dco/render.js.map +1 -1
- package/dist/utils/dco/resolve-agent.d.ts +54 -0
- package/dist/utils/dco/resolve-agent.d.ts.map +1 -0
- package/dist/utils/dco/resolve-agent.js +164 -0
- package/dist/utils/dco/resolve-agent.js.map +1 -0
- package/dist/utils/dco/setup.d.ts +10 -7
- package/dist/utils/dco/setup.d.ts.map +1 -1
- package/dist/utils/dco/setup.js +264 -200
- package/dist/utils/dco/setup.js.map +1 -1
- package/dist/utils/dco/signing-key-writer.d.ts +40 -0
- package/dist/utils/dco/signing-key-writer.d.ts.map +1 -0
- package/dist/utils/dco/signing-key-writer.js +76 -0
- package/dist/utils/dco/signing-key-writer.js.map +1 -0
- package/dist/utils/dco/ssh-key.d.ts +50 -0
- package/dist/utils/dco/ssh-key.d.ts.map +1 -1
- package/dist/utils/dco/ssh-key.js +129 -8
- package/dist/utils/dco/ssh-key.js.map +1 -1
- package/dist/utils/dco/status.d.ts +1 -1
- package/dist/utils/dco/status.d.ts.map +1 -1
- package/dist/utils/dco/status.js +3 -3
- package/dist/utils/dco/status.js.map +1 -1
- package/dist/utils/dco/verify.d.ts +170 -0
- package/dist/utils/dco/verify.d.ts.map +1 -0
- package/dist/utils/dco/verify.js +550 -0
- package/dist/utils/dco/verify.js.map +1 -0
- package/dist/utils/dependency-installer.d.ts +37 -0
- package/dist/utils/dependency-installer.d.ts.map +1 -0
- package/dist/utils/dependency-installer.js +32 -0
- package/dist/utils/dependency-installer.js.map +1 -0
- package/dist/utils/github-credential-stage.d.ts +87 -0
- package/dist/utils/github-credential-stage.d.ts.map +1 -0
- package/dist/utils/github-credential-stage.js +168 -0
- package/dist/utils/github-credential-stage.js.map +1 -0
- package/dist/utils/github-credential.d.ts +160 -0
- package/dist/utils/github-credential.d.ts.map +1 -0
- package/dist/utils/github-credential.js +308 -0
- package/dist/utils/github-credential.js.map +1 -0
- package/dist/utils/gitignore.d.ts +17 -0
- package/dist/utils/gitignore.d.ts.map +1 -0
- package/dist/utils/gitignore.js +40 -0
- package/dist/utils/gitignore.js.map +1 -0
- package/dist/utils/hub-config.d.ts +21 -0
- package/dist/utils/hub-config.d.ts.map +1 -0
- package/dist/utils/hub-config.js +28 -0
- package/dist/utils/hub-config.js.map +1 -0
- package/dist/utils/identity-heal.d.ts +16 -0
- package/dist/utils/identity-heal.d.ts.map +1 -0
- package/dist/utils/identity-heal.js +37 -0
- package/dist/utils/identity-heal.js.map +1 -0
- package/dist/utils/init/pipeline.d.ts +74 -0
- package/dist/utils/init/pipeline.d.ts.map +1 -0
- package/dist/utils/init/pipeline.js +96 -0
- package/dist/utils/init/pipeline.js.map +1 -0
- package/dist/utils/poll.d.ts +15 -1
- package/dist/utils/poll.d.ts.map +1 -1
- package/dist/utils/poll.js +6 -3
- package/dist/utils/poll.js.map +1 -1
- package/dist/utils/register-agent-identity.d.ts +67 -0
- package/dist/utils/register-agent-identity.d.ts.map +1 -0
- package/dist/utils/register-agent-identity.js +34 -0
- package/dist/utils/register-agent-identity.js.map +1 -0
- package/dist/utils/review/did-web-key.d.ts +34 -0
- package/dist/utils/review/did-web-key.d.ts.map +1 -0
- package/dist/utils/review/did-web-key.js +104 -0
- package/dist/utils/review/did-web-key.js.map +1 -0
- package/dist/utils/review/load-registry.d.ts +33 -0
- package/dist/utils/review/load-registry.d.ts.map +1 -0
- package/dist/utils/review/load-registry.js +62 -0
- package/dist/utils/review/load-registry.js.map +1 -0
- package/dist/utils/review/verdict-verify.d.ts +43 -0
- package/dist/utils/review/verdict-verify.d.ts.map +1 -0
- package/dist/utils/review/verdict-verify.js +53 -0
- package/dist/utils/review/verdict-verify.js.map +1 -0
- package/dist/utils/review-registry-writer.d.ts +52 -0
- package/dist/utils/review-registry-writer.d.ts.map +1 -0
- package/dist/utils/review-registry-writer.js +79 -0
- package/dist/utils/review-registry-writer.js.map +1 -0
- package/dist/utils/should-install-dependency.d.ts +17 -0
- package/dist/utils/should-install-dependency.d.ts.map +1 -0
- package/dist/utils/should-install-dependency.js +25 -0
- package/dist/utils/should-install-dependency.js.map +1 -0
- package/dist/utils/tool-readiness.d.ts +57 -0
- package/dist/utils/tool-readiness.d.ts.map +1 -0
- package/dist/utils/tool-readiness.js +114 -0
- package/dist/utils/tool-readiness.js.map +1 -0
- package/dist/utils/which.d.ts +2 -0
- package/dist/utils/which.d.ts.map +1 -0
- package/dist/utils/which.js +22 -0
- package/dist/utils/which.js.map +1 -0
- package/dist/version.d.ts +15 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +1 -0
- package/package.json +19 -6
- package/dist/utils/claim-polling.d.ts +0 -21
- package/dist/utils/claim-polling.d.ts.map +0 -1
- package/dist/utils/claim-polling.js.map +0 -1
- package/dist/utils/dco/fs-safe.d.ts +0 -14
- package/dist/utils/dco/fs-safe.d.ts.map +0 -1
- package/dist/utils/dco/fs-safe.js +0 -20
- package/dist/utils/dco/fs-safe.js.map +0 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { FixAttestationSchema, ReviewVerdictBodySchema, } from "@kya-os/contracts/review";
|
|
2
|
+
import { verifyReviewVerdictProof } from "@kya-os/contracts/review/verify";
|
|
3
|
+
import { sanitizeForMarkdownBlock } from "../dco/fix.js";
|
|
4
|
+
const VERDICT_MARKER_PATTERN = /<!-- kya-os-verdict:v1 repo=(\S+) pr=(\d+) head=([0-9a-f]{40}) reviewer=(\S+) -->/;
|
|
5
|
+
function sanitizedMarkerFields(marker) {
|
|
6
|
+
return {
|
|
7
|
+
repo: sanitizeForMarkdownBlock(marker.repo),
|
|
8
|
+
prNumber: marker.prNumber,
|
|
9
|
+
headSha: marker.headSha,
|
|
10
|
+
reviewerDid: sanitizeForMarkdownBlock(marker.reviewerDid),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function buildVerdictMarker(marker) {
|
|
14
|
+
const safe = sanitizedMarkerFields(marker);
|
|
15
|
+
return `<!-- kya-os-verdict:v1 repo=${safe.repo} pr=${safe.prNumber} head=${safe.headSha} reviewer=${safe.reviewerDid} -->`;
|
|
16
|
+
}
|
|
17
|
+
/** Parse the first `kya-os-verdict:v1` marker out of a review/comment body, if present. */
|
|
18
|
+
export function findVerdictMarker(body) {
|
|
19
|
+
const match = VERDICT_MARKER_PATTERN.exec(body);
|
|
20
|
+
if (!match)
|
|
21
|
+
return null;
|
|
22
|
+
return { repo: match[1], prNumber: Number(match[2]), headSha: match[3], reviewerDid: match[4] };
|
|
23
|
+
}
|
|
24
|
+
function markerMatches(marker, target) {
|
|
25
|
+
return (marker !== null &&
|
|
26
|
+
marker.repo === target.repo &&
|
|
27
|
+
marker.prNumber === target.prNumber &&
|
|
28
|
+
marker.headSha === target.headSha &&
|
|
29
|
+
marker.reviewerDid === target.reviewerDid);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether any of `bodies` already carries a marker for the exact same
|
|
33
|
+
* `(repo, pr, head, reviewer)` — the idempotency check `kya-os agent
|
|
34
|
+
* review` runs before posting a new verdict for a head it may have already
|
|
35
|
+
* reviewed (e.g. the hub/PR replaying events to a reconnecting consumer, or
|
|
36
|
+
* a `--watch` loop's own poll tick landing right after its own post).
|
|
37
|
+
*/
|
|
38
|
+
export function hasVerdictMarker(bodies, target) {
|
|
39
|
+
const safeTarget = sanitizedMarkerFields(target);
|
|
40
|
+
return bodies.some((body) => markerMatches(findVerdictMarker(body), safeTarget));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Find the `ReviewVerdictBody` actually posted AND cryptographically
|
|
44
|
+
* verified for `target`'s `(repo, pr, head, reviewer)`, if any. Used on an
|
|
45
|
+
* idempotent skip to recover the TRUE prior verdict instead of trusting a
|
|
46
|
+
* freshly recomputed one: the review-analysis pass is LLM-driven and can be
|
|
47
|
+
* non-deterministic, so re-running it against an already-reviewed head can
|
|
48
|
+
* produce a different verdict than what is actually signed and posted on
|
|
49
|
+
* the PR. A caller that returned the recompute instead (e.g. treating a
|
|
50
|
+
* recomputed "approve" as equivalent to a truly-posted one) could report
|
|
51
|
+
* success without a real approve ever having landed.
|
|
52
|
+
*
|
|
53
|
+
* `publicKeyRaw` MUST be this reviewer's own Ed25519 public key -- the only
|
|
54
|
+
* key a genuine prior post from this same `reviewerDid` could have signed
|
|
55
|
+
* with. This is not optional: the marker is free text and a fenced block's
|
|
56
|
+
* shape is Zod-checked only, so without a signature check anyone who can
|
|
57
|
+
* post a `COMMENT` review could plant a matching marker plus a schema-valid
|
|
58
|
+
* but unsigned "approve" block and have it trusted as a real prior post. The
|
|
59
|
+
* search keeps scanning past a marker match whose block is missing, corrupt,
|
|
60
|
+
* or fails verification, rather than stopping at the first one found --
|
|
61
|
+
* a forged comment must never be able to shadow a real, later, genuinely
|
|
62
|
+
* signed post. Returns `null` (never a partial/unverified value) when no
|
|
63
|
+
* candidate verifies, so a caller can tell "nothing genuine was posted" from
|
|
64
|
+
* "something was posted"; treating null the same as "not yet posted" (i.e.
|
|
65
|
+
* proceeding to post a real verdict) is the correct, fail-safe response to
|
|
66
|
+
* either a missing OR a forged prior post.
|
|
67
|
+
*/
|
|
68
|
+
export function findPostedVerdict(bodies, target, publicKeyRaw) {
|
|
69
|
+
const safeTarget = sanitizedMarkerFields(target);
|
|
70
|
+
for (const body of bodies) {
|
|
71
|
+
if (!markerMatches(findVerdictMarker(body), safeTarget))
|
|
72
|
+
continue;
|
|
73
|
+
for (const verdict of extractSignedVerdicts(body)) {
|
|
74
|
+
const subjectMatches = verdict.subject.repo === target.repo &&
|
|
75
|
+
verdict.subject.prNumber === target.prNumber &&
|
|
76
|
+
verdict.subject.headSha === target.headSha;
|
|
77
|
+
if (subjectMatches && verifyReviewVerdictProof(verdict, publicKeyRaw)) {
|
|
78
|
+
return verdict;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build the review body posted for a signed verdict: the idempotency
|
|
86
|
+
* marker, a human-readable findings section, then the fenced
|
|
87
|
+
* `kya-os-signed-verdict` JSON block `kya-os agent verify` reads back.
|
|
88
|
+
* `findingsSummary` is caller-built (severity/path:line/summary lines) so
|
|
89
|
+
* this function stays about structure, not findings formatting.
|
|
90
|
+
*/
|
|
91
|
+
export function buildVerdictReviewBody(verdict, reviewerDid, findingsSummary) {
|
|
92
|
+
const marker = buildVerdictMarker({
|
|
93
|
+
repo: verdict.subject.repo,
|
|
94
|
+
prNumber: verdict.subject.prNumber,
|
|
95
|
+
headSha: verdict.subject.headSha,
|
|
96
|
+
reviewerDid,
|
|
97
|
+
});
|
|
98
|
+
const block = ["```kya-os-signed-verdict", JSON.stringify(verdict, null, 2), "```"].join("\n");
|
|
99
|
+
return [marker, "", findingsSummary, "", block, ""].join("\n");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Extract every ` ```<tag> ... ``` ` fenced block from `body`, JSON-parsing
|
|
103
|
+
* each one. A block whose contents don't parse is still returned (with
|
|
104
|
+
* `parsed` absent) rather than silently dropped: `kya-os agent verify`
|
|
105
|
+
* needs to report "found but INVALID: schema" for a corrupted block, not
|
|
106
|
+
* make it disappear as if it were never posted.
|
|
107
|
+
*/
|
|
108
|
+
export function extractFencedBlocks(body, tag) {
|
|
109
|
+
const escapedTag = tag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
110
|
+
const pattern = new RegExp("```" + escapedTag + "\\n([\\s\\S]*?)\\n```", "g");
|
|
111
|
+
const blocks = [];
|
|
112
|
+
for (const match of body.matchAll(pattern)) {
|
|
113
|
+
const raw = match[1];
|
|
114
|
+
try {
|
|
115
|
+
blocks.push({ raw, parsed: JSON.parse(raw) });
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
blocks.push({ raw });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return blocks;
|
|
122
|
+
}
|
|
123
|
+
/** Every `kya-os-signed-verdict` block in `body` that parses AND validates against the schema. */
|
|
124
|
+
export function extractSignedVerdicts(body) {
|
|
125
|
+
const verdicts = [];
|
|
126
|
+
for (const block of extractFencedBlocks(body, "kya-os-signed-verdict")) {
|
|
127
|
+
if (block.parsed === undefined)
|
|
128
|
+
continue;
|
|
129
|
+
const result = ReviewVerdictBodySchema.safeParse(block.parsed);
|
|
130
|
+
if (result.success)
|
|
131
|
+
verdicts.push(result.data);
|
|
132
|
+
}
|
|
133
|
+
return verdicts;
|
|
134
|
+
}
|
|
135
|
+
/** Every `kya-os-fix-attestation` block in `body` that parses AND validates against the schema. */
|
|
136
|
+
export function extractFixAttestations(body) {
|
|
137
|
+
const attestations = [];
|
|
138
|
+
for (const block of extractFencedBlocks(body, "kya-os-fix-attestation")) {
|
|
139
|
+
if (block.parsed === undefined)
|
|
140
|
+
continue;
|
|
141
|
+
const result = FixAttestationSchema.safeParse(block.parsed);
|
|
142
|
+
if (result.success)
|
|
143
|
+
attestations.push(result.data);
|
|
144
|
+
}
|
|
145
|
+
return attestations;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=markers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markers.js","sourceRoot":"","sources":["../../../src/utils/agent/markers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type ReviewVerdict } from "@kya-os/contracts/review";
|
|
2
|
+
import { type ResolveSigningIdentityResult } from "../dco/dispatch.js";
|
|
3
|
+
import { type PullRequestReview, type PullRequestSummary, type PostPullRequestReviewResult, type PullRequestReviewEvent } from "../dco/github.js";
|
|
4
|
+
import { type RunHeadlessAgentOptions } from "./spawn-agent.js";
|
|
5
|
+
export interface AgentReviewGithubClient {
|
|
6
|
+
getPullRequestSummary: (target: string, repo?: string) => Promise<PullRequestSummary>;
|
|
7
|
+
getPullRequestDiff: (target: string, repo?: string) => Promise<string>;
|
|
8
|
+
getPullRequestReviews: (target: string, repo?: string) => Promise<PullRequestReview[]>;
|
|
9
|
+
postPullRequestReview: (target: string, options: {
|
|
10
|
+
event: PullRequestReviewEvent;
|
|
11
|
+
body: string;
|
|
12
|
+
}, repo?: string) => Promise<PostPullRequestReviewResult>;
|
|
13
|
+
}
|
|
14
|
+
export interface RunAgentReviewOptions {
|
|
15
|
+
agentSlug: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
/** owner/name. Derived from the PR URL when omitted. */
|
|
18
|
+
repo?: string;
|
|
19
|
+
/** Diffs at or above this size are refused before ever reaching the agent. */
|
|
20
|
+
maxDiffBytes?: number;
|
|
21
|
+
/** Not writeCapable: this is a read-only analysis pass, never file/commit access. */
|
|
22
|
+
agentOptions?: Omit<RunHeadlessAgentOptions, "cwd" | "writeCapable">;
|
|
23
|
+
github?: AgentReviewGithubClient;
|
|
24
|
+
resolveIdentity?: (cwd: string, agentSlug: string | undefined) => Promise<ResolveSigningIdentityResult>;
|
|
25
|
+
}
|
|
26
|
+
export interface AgentReviewOnceResult {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
headSha: string;
|
|
29
|
+
verdict?: ReviewVerdict;
|
|
30
|
+
findingsCount?: number;
|
|
31
|
+
posted: boolean;
|
|
32
|
+
/** True when this exact (repo, pr, head, reviewer) was already reviewed — nothing was posted again. */
|
|
33
|
+
skippedAlreadyPosted?: boolean;
|
|
34
|
+
/** True when GitHub's self-review 422 forced a COMMENT review instead of APPROVE/REQUEST_CHANGES. */
|
|
35
|
+
fellBackToComment?: boolean;
|
|
36
|
+
failure?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* One review pass against the PR's CURRENT head at call time. Never
|
|
40
|
+
* approves a diff that exceeded the size cap or failed to fetch fully —
|
|
41
|
+
* that head is failed with an actionable REQUEST_CHANGES instead, the same
|
|
42
|
+
* rule review-loop P8's review-executor documents.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runAgentReviewOnce(prTarget: string, options: RunAgentReviewOptions): Promise<AgentReviewOnceResult>;
|
|
45
|
+
export type AgentReviewWatchStopReason = "approved" | "max-heads-reached" | "pr-closed" | "review-failed";
|
|
46
|
+
export interface AgentReviewWatchResult {
|
|
47
|
+
ok: boolean;
|
|
48
|
+
stopReason: AgentReviewWatchStopReason;
|
|
49
|
+
rounds: AgentReviewOnceResult[];
|
|
50
|
+
}
|
|
51
|
+
export interface RunAgentReviewWatchOptions extends RunAgentReviewOptions {
|
|
52
|
+
maxHeads?: number;
|
|
53
|
+
pollSeconds?: number;
|
|
54
|
+
sleepImpl?: (ms: number) => Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Poll the PR's head SHA, running a fresh review whenever it changes, until
|
|
58
|
+
* an approve verdict is posted (`ok:true, stopReason:"approved"`),
|
|
59
|
+
* `maxHeads` heads have been reviewed (`ok:false,
|
|
60
|
+
* stopReason:"max-heads-reached"`), the PR closes
|
|
61
|
+
* (`stopReason:"pr-closed"`), or a review round itself fails
|
|
62
|
+
* (`stopReason:"review-failed"` — a signing/identity/analysis failure, not
|
|
63
|
+
* merely a request-changes verdict, which is a normal outcome that keeps
|
|
64
|
+
* the loop running).
|
|
65
|
+
*/
|
|
66
|
+
export declare function runAgentReviewWatch(prTarget: string, options: RunAgentReviewWatchOptions): Promise<AgentReviewWatchResult>;
|
|
67
|
+
//# sourceMappingURL=review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/utils/agent/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { ReviewFindingSchema, ReviewVerdictBodySchema, } from "@kya-os/contracts/review";
|
|
3
|
+
import { computeFindingsDigest, getVerdictCanonicalSigningString } from "@kya-os/contracts/review";
|
|
4
|
+
import { resolveSigningIdentity } from "../dco/dispatch.js";
|
|
5
|
+
import { parseOwnerRepoFromPrUrl, sanitizeForMarkdownBlock } from "../dco/fix.js";
|
|
6
|
+
import { getPullRequestDiff, getPullRequestReviews, getPullRequestSummary, postPullRequestReview, } from "../dco/github.js";
|
|
7
|
+
import { deriveEd25519PublicKey, parseEd25519SshPrivateKeyPem, signWithEd25519Seed } from "../dco/ssh-key.js";
|
|
8
|
+
import { withGithubBackoff } from "./backoff.js";
|
|
9
|
+
import { buildVerdictReviewBody, findPostedVerdict } from "./markers.js";
|
|
10
|
+
import { runHeadlessAgent } from "./spawn-agent.js";
|
|
11
|
+
/**
|
|
12
|
+
* `kya-os agent review` — the reviewer half of review-loop P13's two-party
|
|
13
|
+
* loop. One-shot ({@link runAgentReviewOnce}) fetches the PR diff read-only,
|
|
14
|
+
* runs a headless-agent analysis pass (see spawn-agent.ts; `claude` by
|
|
15
|
+
* default, provider-agnostic), derives a verdict, signs it, and
|
|
16
|
+
* posts it as a real GitHub review with the `kya-os-verdict:v1` marker +
|
|
17
|
+
* fenced `kya-os-signed-verdict` block for idempotency and later
|
|
18
|
+
* verification. `--watch` ({@link runAgentReviewWatch}) repeats this across
|
|
19
|
+
* new heads until an approve lands, `--max-heads` is exhausted, or the PR
|
|
20
|
+
* closes.
|
|
21
|
+
*/
|
|
22
|
+
const DEFAULT_MAX_DIFF_BYTES = 200000;
|
|
23
|
+
function errorMessage(error) {
|
|
24
|
+
return error instanceof Error ? error.message : String(error);
|
|
25
|
+
}
|
|
26
|
+
const defaultGithubClient = {
|
|
27
|
+
getPullRequestSummary,
|
|
28
|
+
getPullRequestDiff,
|
|
29
|
+
getPullRequestReviews,
|
|
30
|
+
postPullRequestReview,
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Build the review-analysis prompt: instructs the agent to return STRICT
|
|
34
|
+
* JSON — an array matching `ReviewFindingSchema` — and nothing else. A
|
|
35
|
+
* response that doesn't parse and validate is treated as a failed run, never
|
|
36
|
+
* as "no findings" (see `runAgentReviewOnce`'s parse step): a garbled
|
|
37
|
+
* response silently becoming an empty findings array would silently become
|
|
38
|
+
* an approve.
|
|
39
|
+
*/
|
|
40
|
+
function buildReviewAnalysisPrompt(diff, context) {
|
|
41
|
+
return [
|
|
42
|
+
`You are reviewing pull request #${context.prNumber} on ${context.repo} at commit ${context.headSha}.`,
|
|
43
|
+
"Analyze the unified diff below for bugs, correctness issues, and other findings worth flagging.",
|
|
44
|
+
"",
|
|
45
|
+
"Respond with ONLY a strict JSON array (no markdown fences, no prose before or after) where each",
|
|
46
|
+
'element has the shape: {"path"?: string, "line"?: number, "severity": "blocking"|"major"|"minor"|"nit",',
|
|
47
|
+
'"summary": string, "detail"?: string}. Return an empty array [] if you find nothing worth flagging.',
|
|
48
|
+
"Do not wrap the array in an object. Do not include any text outside the JSON array.",
|
|
49
|
+
"",
|
|
50
|
+
"--- BEGIN DIFF ---",
|
|
51
|
+
diff,
|
|
52
|
+
"--- END DIFF ---",
|
|
53
|
+
].join("\n");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `path` and `summary` are free-form text from the LLM analysis pass — as
|
|
57
|
+
* hostile-diff-influenceable as any other reviewer-visible LLM output — and
|
|
58
|
+
* this summary is interpolated ahead of the `kya-os-signed-verdict` fence in
|
|
59
|
+
* `buildVerdictReviewBody`. Sanitized with the same `sanitizeForMarkdownBlock`
|
|
60
|
+
* `dco/fix.ts` uses for the marker's own free-text fields, for the same
|
|
61
|
+
* reason: an unsanitized backtick could close the fence early, and an
|
|
62
|
+
* unsanitized `<!--`/`-->` could forge or prematurely close an HTML-comment
|
|
63
|
+
* marker, letting `extractFencedBlocks`/`kya-os agent verify` pick up
|
|
64
|
+
* spurious blocks even when the real signed verdict is fine.
|
|
65
|
+
*/
|
|
66
|
+
function buildFindingsSummary(findings) {
|
|
67
|
+
if (findings.length === 0) {
|
|
68
|
+
return "No findings.";
|
|
69
|
+
}
|
|
70
|
+
return findings
|
|
71
|
+
.map((finding) => {
|
|
72
|
+
const safePath = finding.path ? sanitizeForMarkdownBlock(finding.path) : undefined;
|
|
73
|
+
const location = safePath ? `${safePath}${finding.line ? `:${finding.line}` : ""}` : "(general)";
|
|
74
|
+
const safeSummary = sanitizeForMarkdownBlock(finding.summary);
|
|
75
|
+
return `- **${finding.severity}** ${location}: ${safeSummary}`;
|
|
76
|
+
})
|
|
77
|
+
.join("\n");
|
|
78
|
+
}
|
|
79
|
+
/** Whether `finding` alone would force a request-changes verdict. */
|
|
80
|
+
function isBlockingFinding(finding) {
|
|
81
|
+
return finding.severity === "blocking" || finding.severity === "major";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Strip a markdown code fence wrapping the ENTIRE response, a formatting
|
|
85
|
+
* habit Claude falls back to even when the prompt explicitly asks for none
|
|
86
|
+
* — confirmed live: a real analysis response came back as
|
|
87
|
+
* "```json\n[...]\n```" and would otherwise fail to parse, turning a
|
|
88
|
+
* perfectly good findings array into a hard failure. Only strips a fence
|
|
89
|
+
* that wraps the whole trimmed text; anything else is left untouched and
|
|
90
|
+
* still fails to parse as JSON exactly as before, which is the correct
|
|
91
|
+
* outcome for a genuinely malformed response.
|
|
92
|
+
*/
|
|
93
|
+
function stripJsonCodeFence(text) {
|
|
94
|
+
const trimmed = text.trim();
|
|
95
|
+
const match = /^```(?:json)?\r?\n([\s\S]*?)\r?\n```$/.exec(trimmed);
|
|
96
|
+
return match ? match[1] : trimmed;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One review pass against the PR's CURRENT head at call time. Never
|
|
100
|
+
* approves a diff that exceeded the size cap or failed to fetch fully —
|
|
101
|
+
* that head is failed with an actionable REQUEST_CHANGES instead, the same
|
|
102
|
+
* rule review-loop P8's review-executor documents.
|
|
103
|
+
*/
|
|
104
|
+
export async function runAgentReviewOnce(prTarget, options) {
|
|
105
|
+
const github = options.github ?? defaultGithubClient;
|
|
106
|
+
const resolveIdentity = options.resolveIdentity ?? resolveSigningIdentity;
|
|
107
|
+
const cwd = options.cwd ?? process.cwd();
|
|
108
|
+
const maxDiffBytes = options.maxDiffBytes ?? DEFAULT_MAX_DIFF_BYTES;
|
|
109
|
+
const repo = options.repo ?? parseOwnerRepoFromPrUrl(prTarget) ?? undefined;
|
|
110
|
+
const identityResult = await resolveIdentity(cwd, options.agentSlug);
|
|
111
|
+
if (!identityResult.ok) {
|
|
112
|
+
return { ok: false, headSha: "", posted: false, failure: identityResult.failure };
|
|
113
|
+
}
|
|
114
|
+
const { did, keyPath } = identityResult.identity;
|
|
115
|
+
const summary = await withGithubBackoff(() => github.getPullRequestSummary(prTarget, repo));
|
|
116
|
+
if (summary.state !== "OPEN") {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
headSha: summary.headRefOid,
|
|
120
|
+
posted: false,
|
|
121
|
+
failure: `pr-not-open: PR #${summary.number} is ${summary.state.toLowerCase()}, not open`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const subjectRepo = repo ?? parseOwnerRepoFromPrUrl(summary.url) ?? "";
|
|
125
|
+
let diff;
|
|
126
|
+
try {
|
|
127
|
+
diff = await withGithubBackoff(() => github.getPullRequestDiff(prTarget, repo));
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
headSha: summary.headRefOid,
|
|
133
|
+
posted: false,
|
|
134
|
+
failure: `diff-fetch-failed: ${errorMessage(error)}`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const diffTooLarge = Buffer.byteLength(diff, "utf8") >= maxDiffBytes;
|
|
138
|
+
let findings;
|
|
139
|
+
let verdict;
|
|
140
|
+
if (diffTooLarge) {
|
|
141
|
+
findings = [
|
|
142
|
+
{
|
|
143
|
+
severity: "blocking",
|
|
144
|
+
summary: `Diff is at or above the ${maxDiffBytes}-byte review cap; refusing to approve an unreviewed change.`,
|
|
145
|
+
detail: "Split this PR into smaller, independently reviewable commits.",
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
verdict = "request-changes";
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const prompt = buildReviewAnalysisPrompt(diff, {
|
|
152
|
+
repo: subjectRepo,
|
|
153
|
+
prNumber: summary.number,
|
|
154
|
+
headSha: summary.headRefOid,
|
|
155
|
+
});
|
|
156
|
+
const agentResult = await runHeadlessAgent(prompt, { cwd, ...options.agentOptions });
|
|
157
|
+
let parsedJson;
|
|
158
|
+
try {
|
|
159
|
+
parsedJson = JSON.parse(stripJsonCodeFence(agentResult.text));
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// A parse failure fails the run outright — it must never be
|
|
163
|
+
// silently treated as "no findings", which would become an approve.
|
|
164
|
+
throw new Error(`review analysis did not return valid JSON: ${agentResult.text.slice(0, 500)}`);
|
|
165
|
+
}
|
|
166
|
+
const parseResult = ReviewFindingSchema.array().max(500).safeParse(parsedJson);
|
|
167
|
+
if (!parseResult.success) {
|
|
168
|
+
throw new Error(`review analysis JSON did not match the findings schema: ${parseResult.error.message}`);
|
|
169
|
+
}
|
|
170
|
+
findings = parseResult.data;
|
|
171
|
+
verdict = findings.some(isBlockingFinding) ? "request-changes" : "approve";
|
|
172
|
+
}
|
|
173
|
+
const subject = { repo: subjectRepo, prNumber: summary.number, headSha: summary.headRefOid };
|
|
174
|
+
const findingsDigest = computeFindingsDigest(findings);
|
|
175
|
+
const signingString = getVerdictCanonicalSigningString(subject, verdict, findingsDigest);
|
|
176
|
+
const pem = readFileSync(keyPath, "utf-8");
|
|
177
|
+
const { seed } = parseEd25519SshPrivateKeyPem(pem);
|
|
178
|
+
const publicKeyRaw = deriveEd25519PublicKey(seed);
|
|
179
|
+
const signature = signWithEd25519Seed(seed, Buffer.from(signingString, "utf8")).toString("base64url");
|
|
180
|
+
const taskId = `review-${subject.prNumber}-${subject.headSha.slice(0, 12)}`;
|
|
181
|
+
const verdictBody = ReviewVerdictBodySchema.parse({
|
|
182
|
+
taskId,
|
|
183
|
+
subject,
|
|
184
|
+
verdict,
|
|
185
|
+
findings,
|
|
186
|
+
findingsDigest,
|
|
187
|
+
proof: { alg: "Ed25519", signature },
|
|
188
|
+
});
|
|
189
|
+
const existingReviews = await withGithubBackoff(() => github.getPullRequestReviews(prTarget, repo));
|
|
190
|
+
const existingBodies = existingReviews.map((review) => review.body ?? "");
|
|
191
|
+
const verdictMarkerTarget = { repo: subject.repo, prNumber: subject.prNumber, headSha: subject.headSha, reviewerDid: did };
|
|
192
|
+
// Idempotency is gated on a VERIFIED prior post, never on a marker match
|
|
193
|
+
// alone: a marker is free text and a fenced block's shape is Zod-checked
|
|
194
|
+
// only, so anyone who can post a COMMENT review could otherwise plant a
|
|
195
|
+
// matching marker plus a schema-valid but unsigned "approve" and have it
|
|
196
|
+
// trusted as a genuine prior post (findPostedVerdict verifies against
|
|
197
|
+
// THIS reviewer's own key, the only one a real prior post from this
|
|
198
|
+
// identity could have signed with). When nothing verifies -- nothing was
|
|
199
|
+
// really posted, or what looks posted is forged/corrupt -- fall through
|
|
200
|
+
// and post the real verdict below, exactly as if this were a fresh head;
|
|
201
|
+
// silently treating an unverifiable marker as "already handled" would
|
|
202
|
+
// otherwise let --watch stall on this head forever.
|
|
203
|
+
const posted = findPostedVerdict(existingBodies, verdictMarkerTarget, publicKeyRaw);
|
|
204
|
+
if (posted) {
|
|
205
|
+
// Return the verdict ACTUALLY posted for this head, recovered from the
|
|
206
|
+
// matching review's own signed block — never the value this call just
|
|
207
|
+
// recomputed. The analysis pass is LLM-driven and can come back
|
|
208
|
+
// differently on a re-run; trusting the recompute here could make
|
|
209
|
+
// --watch report an approve that never actually landed on the PR.
|
|
210
|
+
return {
|
|
211
|
+
ok: true,
|
|
212
|
+
headSha: subject.headSha,
|
|
213
|
+
verdict: posted.verdict,
|
|
214
|
+
findingsCount: posted.findings.length,
|
|
215
|
+
posted: false,
|
|
216
|
+
skippedAlreadyPosted: true,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const body = buildVerdictReviewBody(verdictBody, did, buildFindingsSummary(findings));
|
|
220
|
+
const event = verdict === "approve" ? "APPROVE" : "REQUEST_CHANGES";
|
|
221
|
+
const postResult = await withGithubBackoff(() => github.postPullRequestReview(prTarget, { event, body }, repo));
|
|
222
|
+
if (postResult.ok) {
|
|
223
|
+
return { ok: true, headSha: subject.headSha, verdict, findingsCount: findings.length, posted: true };
|
|
224
|
+
}
|
|
225
|
+
if (postResult.selfReviewRejected) {
|
|
226
|
+
// GitHub refuses APPROVE/REQUEST_CHANGES from the token that owns the
|
|
227
|
+
// PR; COMMENT is always allowed. The signed block inside `body` is
|
|
228
|
+
// unchanged — the signature is the claim that verifies either way.
|
|
229
|
+
const fallbackResult = await withGithubBackoff(() => github.postPullRequestReview(prTarget, { event: "COMMENT", body }, repo));
|
|
230
|
+
if (!fallbackResult.ok) {
|
|
231
|
+
// Don't report `posted: true` for a fallback that itself failed --
|
|
232
|
+
// --watch would otherwise treat an approve that never reached the PR
|
|
233
|
+
// as a completed, successful round.
|
|
234
|
+
return {
|
|
235
|
+
ok: false,
|
|
236
|
+
headSha: subject.headSha,
|
|
237
|
+
verdict,
|
|
238
|
+
findingsCount: findings.length,
|
|
239
|
+
posted: false,
|
|
240
|
+
failure: "post-review-failed: COMMENT fallback for the self-review rejection also failed",
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
ok: true,
|
|
245
|
+
headSha: subject.headSha,
|
|
246
|
+
verdict,
|
|
247
|
+
findingsCount: findings.length,
|
|
248
|
+
posted: true,
|
|
249
|
+
fellBackToComment: true,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
ok: false,
|
|
254
|
+
headSha: subject.headSha,
|
|
255
|
+
verdict,
|
|
256
|
+
findingsCount: findings.length,
|
|
257
|
+
posted: false,
|
|
258
|
+
failure: "post-review-failed",
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const DEFAULT_MAX_HEADS = 5;
|
|
262
|
+
const DEFAULT_POLL_SECONDS = 30;
|
|
263
|
+
/**
|
|
264
|
+
* Poll the PR's head SHA, running a fresh review whenever it changes, until
|
|
265
|
+
* an approve verdict is posted (`ok:true, stopReason:"approved"`),
|
|
266
|
+
* `maxHeads` heads have been reviewed (`ok:false,
|
|
267
|
+
* stopReason:"max-heads-reached"`), the PR closes
|
|
268
|
+
* (`stopReason:"pr-closed"`), or a review round itself fails
|
|
269
|
+
* (`stopReason:"review-failed"` — a signing/identity/analysis failure, not
|
|
270
|
+
* merely a request-changes verdict, which is a normal outcome that keeps
|
|
271
|
+
* the loop running).
|
|
272
|
+
*/
|
|
273
|
+
export async function runAgentReviewWatch(prTarget, options) {
|
|
274
|
+
const github = options.github ?? defaultGithubClient;
|
|
275
|
+
const maxHeads = options.maxHeads ?? DEFAULT_MAX_HEADS;
|
|
276
|
+
const pollMs = (options.pollSeconds ?? DEFAULT_POLL_SECONDS) * 1000;
|
|
277
|
+
const sleep = options.sleepImpl ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
278
|
+
const rounds = [];
|
|
279
|
+
let lastReviewedHead;
|
|
280
|
+
for (;;) {
|
|
281
|
+
const summary = await withGithubBackoff(() => github.getPullRequestSummary(prTarget, options.repo));
|
|
282
|
+
if (summary.state !== "OPEN") {
|
|
283
|
+
return { ok: false, stopReason: "pr-closed", rounds };
|
|
284
|
+
}
|
|
285
|
+
if (summary.headRefOid !== lastReviewedHead) {
|
|
286
|
+
if (rounds.length >= maxHeads) {
|
|
287
|
+
return { ok: false, stopReason: "max-heads-reached", rounds };
|
|
288
|
+
}
|
|
289
|
+
const result = await runAgentReviewOnce(prTarget, { ...options, github });
|
|
290
|
+
rounds.push(result);
|
|
291
|
+
lastReviewedHead = result.headSha || summary.headRefOid;
|
|
292
|
+
if (!result.ok) {
|
|
293
|
+
return { ok: false, stopReason: "review-failed", rounds };
|
|
294
|
+
}
|
|
295
|
+
if (result.verdict === "approve" && (result.posted || result.skippedAlreadyPosted)) {
|
|
296
|
+
return { ok: true, stopReason: "approved", rounds };
|
|
297
|
+
}
|
|
298
|
+
if (rounds.length >= maxHeads) {
|
|
299
|
+
return { ok: false, stopReason: "max-heads-reached", rounds };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
await sleep(pollMs);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/utils/agent/review.ts"],"names":[],"mappings":"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"}
|