neondeck 1.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/DEVELOPMENT.md +310 -0
- package/LICENSE +21 -0
- package/README.md +128 -0
- package/SOUL.md +8 -0
- package/bin/neondeck.mjs +27 -0
- package/config/dashboard.json +208 -0
- package/config/dashboard.schema.json +207 -0
- package/dist/SOUL.md +8 -0
- package/dist/assets/app-BuuvLo98.js +3620 -0
- package/dist/assets/app-BuuvLo98.js.map +1 -0
- package/dist/assets/autopilot-CKgEx8yQ.js +68025 -0
- package/dist/assets/autopilot-CKgEx8yQ.js.map +1 -0
- package/dist/assets/briefing-DYVbJaqk.js +2 -0
- package/dist/assets/briefing-DoO-fJr1.js +22 -0
- package/dist/assets/briefing-DoO-fJr1.js.map +1 -0
- package/dist/assets/command-run-B2TWLpLL.js +20 -0
- package/dist/assets/command-run-B2TWLpLL.js.map +1 -0
- package/dist/assets/command-run-CzQra_Y7.js +2 -0
- package/dist/assets/display-assistant-CbCRBSYM.js +389 -0
- package/dist/assets/display-assistant-CbCRBSYM.js.map +1 -0
- package/dist/assets/fix-pr-ci-BlUl-2ht.js +46 -0
- package/dist/assets/fix-pr-ci-BlUl-2ht.js.map +1 -0
- package/dist/assets/fix-pr-ci-Dl1wpKXp.js +2 -0
- package/dist/assets/migrations/20260710061339_neondeck_pre_1_0_baseline/migration.sql +748 -0
- package/dist/assets/migrations/20260710061339_neondeck_pre_1_0_baseline/snapshot.json +7240 -0
- package/dist/assets/prepare-pr-worktree-CLzccRYh.js +2 -0
- package/dist/assets/prepare-pr-worktree-DxyTygiU.js +17 -0
- package/dist/assets/prepare-pr-worktree-DxyTygiU.js.map +1 -0
- package/dist/assets/push-pr-autofix-BFNSEASU.js +2 -0
- package/dist/assets/push-pr-autofix-DlVjw1IN.js +17 -0
- package/dist/assets/push-pr-autofix-DlVjw1IN.js.map +1 -0
- package/dist/assets/review-pr-for-human-B2j8wz2L.js +2 -0
- package/dist/assets/review-pr-for-human-DcGE-7wb.js +708 -0
- package/dist/assets/review-pr-for-human-DcGE-7wb.js.map +1 -0
- package/dist/assets/safety-CawD9GxD.js +2499 -0
- package/dist/assets/safety-CawD9GxD.js.map +1 -0
- package/dist/assets/scheduled-agent-instruction-CQgogBv3.js +22 -0
- package/dist/assets/scheduled-agent-instruction-CQgogBv3.js.map +1 -0
- package/dist/assets/scheduled-agent-instruction-Dr2ebZRD.js +2 -0
- package/dist/assets/scheduler-tick-Cy26qBld.js +105 -0
- package/dist/assets/scheduler-tick-Cy26qBld.js.map +1 -0
- package/dist/assets/skills/github-gh/SKILL.md +56 -0
- package/dist/assets/skills/neon-ci-fix/SKILL.md +15 -0
- package/dist/assets/skills/neon-docs-fix/SKILL.md +15 -0
- package/dist/assets/skills/neon-issue-triage/SKILL.md +13 -0
- package/dist/assets/skills/neon-pr-review/SKILL.md +19 -0
- package/dist/assets/skills/neondeck/SKILL.md +123 -0
- package/dist/assets/skills/neondeck-handoff/SKILL.md +31 -0
- package/dist/assets/triage-pr-event-BlE3GKNR.js +17 -0
- package/dist/assets/triage-pr-event-BlE3GKNR.js.map +1 -0
- package/dist/assets/triage-pr-event-hxUP587F.js +2 -0
- package/dist/assets/verify-then-push-pr-autofix-CIl5ZwZm.js +2 -0
- package/dist/assets/verify-then-push-pr-autofix-Djy0UFUv.js +75 -0
- package/dist/assets/verify-then-push-pr-autofix-Djy0UFUv.js.map +1 -0
- package/dist/config/dashboard.json +208 -0
- package/dist/config/dashboard.schema.json +207 -0
- package/dist/server.mjs +582 -0
- package/dist/server.mjs.map +1 -0
- package/dist/skills/github-gh/SKILL.md +56 -0
- package/dist/skills/neon-ci-fix/SKILL.md +15 -0
- package/dist/skills/neon-docs-fix/SKILL.md +15 -0
- package/dist/skills/neon-issue-triage/SKILL.md +13 -0
- package/dist/skills/neon-pr-review/SKILL.md +19 -0
- package/dist/skills/neondeck/SKILL.md +123 -0
- package/dist/skills/neondeck-handoff/SKILL.md +31 -0
- package/drizzle.config.ts +7 -0
- package/package.json +155 -0
- package/shared/patch-anchors.ts +78 -0
- package/src/agents/busywork-workflow.ts +24 -0
- package/src/agents/display-assistant.ts +134 -0
- package/src/agents/pr-review-assistant.ts +25 -0
- package/src/agents/scheduler-workflow.ts +20 -0
- package/src/agents/support/tools.ts +346 -0
- package/src/app.ts +1 -0
- package/src/cli/index.ts +560 -0
- package/src/cli/learning.ts +44 -0
- package/src/cli/mcp.ts +496 -0
- package/src/cli/modules.ts +107 -0
- package/src/cli/onboarding.ts +667 -0
- package/src/cli/options.ts +103 -0
- package/src/cli/output.ts +399 -0
- package/src/cli/preapprovals.ts +204 -0
- package/src/cli/prompts.ts +108 -0
- package/src/cli/types.ts +59 -0
- package/src/db.ts +41 -0
- package/src/desktop/open.ts +698 -0
- package/src/desktop/service.ts +863 -0
- package/src/domains/mcp/actions.ts +420 -0
- package/src/domains/mcp/config.ts +501 -0
- package/src/domains/mcp/format.ts +35 -0
- package/src/domains/mcp/gate.ts +188 -0
- package/src/domains/mcp/index.ts +9 -0
- package/src/domains/mcp/instructions.ts +18 -0
- package/src/domains/mcp/oauth.ts +1063 -0
- package/src/domains/mcp/policy.ts +15 -0
- package/src/domains/mcp/registry.ts +461 -0
- package/src/domains/mcp/schemas.ts +171 -0
- package/src/domains/mcp/stdio.ts +451 -0
- package/src/domains/mcp/store.ts +905 -0
- package/src/domains/mcp/tools.ts +119 -0
- package/src/lib/action-result.ts +51 -0
- package/src/lib/exec.ts +118 -0
- package/src/lib/git.ts +20 -0
- package/src/lib/report-html.ts +193 -0
- package/src/lib/sqlite.ts +51 -0
- package/src/lib/valibot.ts +33 -0
- package/src/modules/app-state/index.ts +5 -0
- package/src/modules/app-state/native-notifications.ts +76 -0
- package/src/modules/app-state/notification-events.ts +45 -0
- package/src/modules/app-state/notifications.ts +276 -0
- package/src/modules/app-state/types.ts +42 -0
- package/src/modules/app-state/workflow-summaries.ts +201 -0
- package/src/modules/autonomous-audit/index.ts +225 -0
- package/src/modules/autopilot/actions.ts +165 -0
- package/src/modules/autopilot/admissions.ts +865 -0
- package/src/modules/autopilot/approvals.ts +59 -0
- package/src/modules/autopilot/ci-fix-run.ts +1332 -0
- package/src/modules/autopilot/ci-fix.ts +692 -0
- package/src/modules/autopilot/comments.ts +426 -0
- package/src/modules/autopilot/fixtures.ts +344 -0
- package/src/modules/autopilot/github-facts.ts +303 -0
- package/src/modules/autopilot/index.ts +64 -0
- package/src/modules/autopilot/notifications.ts +271 -0
- package/src/modules/autopilot/push-support.ts +288 -0
- package/src/modules/autopilot/push.ts +661 -0
- package/src/modules/autopilot/recovery.ts +656 -0
- package/src/modules/autopilot/review-feedback.ts +651 -0
- package/src/modules/autopilot/review-support.ts +524 -0
- package/src/modules/autopilot/revision-run.ts +445 -0
- package/src/modules/autopilot/schemas.ts +485 -0
- package/src/modules/autopilot/state-mappers.ts +512 -0
- package/src/modules/autopilot/state-schemas.ts +451 -0
- package/src/modules/autopilot/state-store.ts +183 -0
- package/src/modules/autopilot/state.ts +255 -0
- package/src/modules/autopilot/triage-support.ts +234 -0
- package/src/modules/autopilot/triage.ts +156 -0
- package/src/modules/autopilot/utils.ts +145 -0
- package/src/modules/autopilot/worktree.ts +622 -0
- package/src/modules/autopilot-policy/config.ts +110 -0
- package/src/modules/autopilot-policy/index.ts +4 -0
- package/src/modules/autopilot-policy/risk.ts +359 -0
- package/src/modules/autopilot-policy/schemas.ts +284 -0
- package/src/modules/autopilot-policy/service.ts +304 -0
- package/src/modules/commands/actions.ts +112 -0
- package/src/modules/commands/handlers/index.ts +3 -0
- package/src/modules/commands/handlers/misc.ts +441 -0
- package/src/modules/commands/handlers/queue.ts +694 -0
- package/src/modules/commands/handlers/repo.ts +339 -0
- package/src/modules/commands/index.ts +5 -0
- package/src/modules/commands/registry.ts +157 -0
- package/src/modules/commands/runner.ts +152 -0
- package/src/modules/commands/schemas.ts +107 -0
- package/src/modules/commands/summaries.ts +92 -0
- package/src/modules/commands/utils.ts +113 -0
- package/src/modules/config/actions.ts +253 -0
- package/src/modules/config/events.ts +80 -0
- package/src/modules/config/files.ts +9 -0
- package/src/modules/config/history.ts +74 -0
- package/src/modules/config/index.ts +9 -0
- package/src/modules/config/mutations/dashboard.ts +319 -0
- package/src/modules/config/mutations/execution.ts +89 -0
- package/src/modules/config/mutations/models.ts +467 -0
- package/src/modules/config/mutations/providers.ts +163 -0
- package/src/modules/config/mutations/repos.ts +620 -0
- package/src/modules/config/read.ts +135 -0
- package/src/modules/config/result.ts +66 -0
- package/src/modules/config/schemas.ts +181 -0
- package/src/modules/docs-drift/index.ts +1 -0
- package/src/modules/docs-drift/service.ts +863 -0
- package/src/modules/execution/actions.ts +35 -0
- package/src/modules/execution/approvals.ts +322 -0
- package/src/modules/execution/exedev/checkouts.ts +356 -0
- package/src/modules/execution/exedev/context.ts +286 -0
- package/src/modules/execution/index.ts +7 -0
- package/src/modules/execution/policy.ts +102 -0
- package/src/modules/execution/run.ts +589 -0
- package/src/modules/execution/schemas.ts +116 -0
- package/src/modules/execution/scope.ts +137 -0
- package/src/modules/execution/store.ts +320 -0
- package/src/modules/execution/utils.ts +105 -0
- package/src/modules/execution-policy/index.ts +424 -0
- package/src/modules/flue/execution-context.ts +41 -0
- package/src/modules/github/actions.ts +334 -0
- package/src/modules/github/checks.ts +484 -0
- package/src/modules/github/client.ts +110 -0
- package/src/modules/github/comments.ts +204 -0
- package/src/modules/github/errors.ts +50 -0
- package/src/modules/github/index.ts +92 -0
- package/src/modules/github/issues.ts +116 -0
- package/src/modules/github/pr-file-cache.ts +264 -0
- package/src/modules/github/pull-requests.ts +384 -0
- package/src/modules/github/queue.ts +342 -0
- package/src/modules/github/reviews.ts +1421 -0
- package/src/modules/github/schemas.ts +794 -0
- package/src/modules/github/state-truncation.ts +31 -0
- package/src/modules/handoff/index.ts +2 -0
- package/src/modules/handoff/schemas.ts +61 -0
- package/src/modules/handoff/service.ts +587 -0
- package/src/modules/hygiene/index.ts +1 -0
- package/src/modules/hygiene/service.ts +513 -0
- package/src/modules/kilo/actions.ts +229 -0
- package/src/modules/kilo/ci-fix-run-reconcile.ts +299 -0
- package/src/modules/kilo/docs-drift-boundary.ts +178 -0
- package/src/modules/kilo/index.ts +8 -0
- package/src/modules/kilo/notifications.ts +295 -0
- package/src/modules/kilo/process.ts +637 -0
- package/src/modules/kilo/results/actions.ts +66 -0
- package/src/modules/kilo/results/gates.ts +227 -0
- package/src/modules/kilo/results/index.ts +23 -0
- package/src/modules/kilo/results/schemas.ts +112 -0
- package/src/modules/kilo/results/service.ts +512 -0
- package/src/modules/kilo/results/state.ts +508 -0
- package/src/modules/kilo/results/verify.ts +328 -0
- package/src/modules/kilo/revision-reconcile.ts +187 -0
- package/src/modules/kilo/runtime-facts.ts +128 -0
- package/src/modules/kilo/schemas.ts +265 -0
- package/src/modules/kilo/service.ts +714 -0
- package/src/modules/kilo/sessions-adapters.ts +343 -0
- package/src/modules/kilo/sessions.ts +446 -0
- package/src/modules/kilo/store.ts +689 -0
- package/src/modules/kilo/utils.ts +166 -0
- package/src/modules/learning/automation-health.ts +441 -0
- package/src/modules/learning/automation-memory.ts +179 -0
- package/src/modules/learning/index.ts +6 -0
- package/src/modules/learning/observability.ts +616 -0
- package/src/modules/learning/operator.ts +404 -0
- package/src/modules/learning/reviews/agents.ts +33 -0
- package/src/modules/learning/reviews/complete.ts +321 -0
- package/src/modules/learning/reviews/context.ts +145 -0
- package/src/modules/learning/reviews/events.ts +306 -0
- package/src/modules/learning/reviews/index.ts +6 -0
- package/src/modules/learning/reviews/pr-cadence.ts +157 -0
- package/src/modules/learning/reviews/pr-context.ts +749 -0
- package/src/modules/learning/reviews/prepare.ts +387 -0
- package/src/modules/learning/reviews/schemas.ts +184 -0
- package/src/modules/learning/reviews/store.ts +405 -0
- package/src/modules/learning/skill-patches/actions.ts +86 -0
- package/src/modules/learning/skill-patches/index.ts +3 -0
- package/src/modules/learning/skill-patches/schemas.ts +60 -0
- package/src/modules/learning/skill-patches/service.ts +571 -0
- package/src/modules/learning/skill-patches/support.ts +417 -0
- package/src/modules/memory/actions.ts +183 -0
- package/src/modules/memory/candidates.ts +525 -0
- package/src/modules/memory/events.ts +2 -0
- package/src/modules/memory/index.ts +6 -0
- package/src/modules/memory/prompt.ts +214 -0
- package/src/modules/memory/schemas.ts +170 -0
- package/src/modules/memory/service.ts +578 -0
- package/src/modules/memory/store.ts +489 -0
- package/src/modules/pr-events/actions.ts +191 -0
- package/src/modules/pr-events/index.ts +45 -0
- package/src/modules/pr-events/schemas.ts +186 -0
- package/src/modules/pr-events/service.ts +1414 -0
- package/src/modules/pr-events/target.ts +222 -0
- package/src/modules/pr-events/utils.ts +85 -0
- package/src/modules/pr-events/watermarks.ts +308 -0
- package/src/modules/pr-local-diffs/index.ts +334 -0
- package/src/modules/pr-review-assist/actions.ts +199 -0
- package/src/modules/pr-review-assist/index.ts +3 -0
- package/src/modules/pr-review-assist/schemas.ts +74 -0
- package/src/modules/pr-review-assist/service.ts +656 -0
- package/src/modules/prepared-diffs/actions.ts +132 -0
- package/src/modules/prepared-diffs/index.ts +53 -0
- package/src/modules/prepared-diffs/schemas.ts +255 -0
- package/src/modules/prepared-diffs/service.ts +777 -0
- package/src/modules/prepared-diffs/store.ts +606 -0
- package/src/modules/reports/index.ts +1 -0
- package/src/modules/reports/service.ts +322 -0
- package/src/modules/repos/index.ts +3 -0
- package/src/modules/repos/model-discovery.ts +233 -0
- package/src/modules/repos/providers.ts +194 -0
- package/src/modules/repos/registry.ts +232 -0
- package/src/modules/runtime/agent-config.ts +167 -0
- package/src/modules/runtime/doctor.ts +528 -0
- package/src/modules/runtime/env.ts +123 -0
- package/src/modules/runtime/index.ts +12 -0
- package/src/modules/runtime/local-api-auth.ts +43 -0
- package/src/modules/runtime/metrics.ts +211 -0
- package/src/modules/runtime/skills-actions.ts +141 -0
- package/src/modules/runtime/skills.ts +689 -0
- package/src/modules/runtime/soul.ts +68 -0
- package/src/modules/runtime/status-database.ts +252 -0
- package/src/modules/runtime/status-schema.ts +149 -0
- package/src/modules/runtime/status.ts +482 -0
- package/src/modules/runtime/subagents.ts +37 -0
- package/src/modules/runtime/utility-model.ts +47 -0
- package/src/modules/safety/index.ts +3 -0
- package/src/modules/safety/policy-entries.ts +2432 -0
- package/src/modules/safety/schemas.ts +63 -0
- package/src/modules/safety/service.ts +58 -0
- package/src/modules/safety/tools.ts +15 -0
- package/src/modules/scheduled-tasks/actions.ts +113 -0
- package/src/modules/scheduled-tasks/dispatch.ts +105 -0
- package/src/modules/scheduled-tasks/index.ts +6 -0
- package/src/modules/scheduled-tasks/schemas.ts +91 -0
- package/src/modules/scheduled-tasks/service.ts +296 -0
- package/src/modules/scheduled-tasks/store.ts +814 -0
- package/src/modules/scheduled-tasks/triggers.ts +87 -0
- package/src/modules/scheduler/actions.ts +37 -0
- package/src/modules/scheduler/dispatch.ts +126 -0
- package/src/modules/scheduler/index.ts +4 -0
- package/src/modules/scheduler/lease.ts +247 -0
- package/src/modules/scheduler/pr-watch-event-deltas.ts +367 -0
- package/src/modules/scheduler/pr-watch-events.ts +834 -0
- package/src/modules/scheduler/schemas.ts +79 -0
- package/src/modules/scheduler/service.ts +228 -0
- package/src/modules/scheduler/utils.ts +106 -0
- package/src/modules/scheduler/workflow-invocation.ts +40 -0
- package/src/modules/sessions/actions.ts +213 -0
- package/src/modules/sessions/active-session.ts +46 -0
- package/src/modules/sessions/agent-context.ts +146 -0
- package/src/modules/sessions/approval-nudges.ts +156 -0
- package/src/modules/sessions/events.ts +58 -0
- package/src/modules/sessions/index.ts +10 -0
- package/src/modules/sessions/queries.ts +252 -0
- package/src/modules/sessions/references.ts +113 -0
- package/src/modules/sessions/schemas.ts +263 -0
- package/src/modules/sessions/service.ts +845 -0
- package/src/modules/sessions/store.ts +559 -0
- package/src/modules/sessions/summaries.ts +129 -0
- package/src/modules/sessions/utils.ts +18 -0
- package/src/modules/watches/actions.ts +115 -0
- package/src/modules/watches/index.ts +6 -0
- package/src/modules/watches/polling.ts +245 -0
- package/src/modules/watches/references.ts +293 -0
- package/src/modules/watches/schemas.ts +156 -0
- package/src/modules/watches/service.ts +558 -0
- package/src/modules/watches/store.ts +398 -0
- package/src/modules/watches/utils.ts +51 -0
- package/src/modules/worktree-verification/index.ts +256 -0
- package/src/modules/worktrees/access.ts +129 -0
- package/src/modules/worktrees/actions.ts +108 -0
- package/src/modules/worktrees/cleanup.ts +98 -0
- package/src/modules/worktrees/errors.ts +38 -0
- package/src/modules/worktrees/git.ts +48 -0
- package/src/modules/worktrees/index.ts +5 -0
- package/src/modules/worktrees/locks.ts +192 -0
- package/src/modules/worktrees/paths.ts +209 -0
- package/src/modules/worktrees/queries.ts +31 -0
- package/src/modules/worktrees/schemas.ts +234 -0
- package/src/modules/worktrees/service.ts +657 -0
- package/src/modules/worktrees/store.ts +414 -0
- package/src/repo-edit/actions.ts +129 -0
- package/src/repo-edit/audit.ts +180 -0
- package/src/repo-edit/fuzzy-replace.ts +256 -0
- package/src/repo-edit/git.ts +784 -0
- package/src/repo-edit/index.ts +4 -0
- package/src/repo-edit/locks.ts +27 -0
- package/src/repo-edit/patch-parser.ts +212 -0
- package/src/repo-edit/patch-service.ts +572 -0
- package/src/repo-edit/path-safety.ts +294 -0
- package/src/repo-edit/schemas.ts +220 -0
- package/src/repo-edit/service.ts +488 -0
- package/src/repo-edit/support.ts +459 -0
- package/src/runtime-home/app-db/index.ts +73 -0
- package/src/runtime-home/app-db/migrate.ts +491 -0
- package/src/runtime-home/app-db/migrations/20260710061339_neondeck_pre_1_0_baseline/migration.sql +748 -0
- package/src/runtime-home/app-db/migrations/20260710061339_neondeck_pre_1_0_baseline/snapshot.json +7240 -0
- package/src/runtime-home/app-db/reconcile.ts +155 -0
- package/src/runtime-home/app-db/schema.ts +1118 -0
- package/src/runtime-home/bootstrap.ts +171 -0
- package/src/runtime-home/defaults.ts +42 -0
- package/src/runtime-home/files.ts +193 -0
- package/src/runtime-home/index.ts +68 -0
- package/src/runtime-home/paths.ts +75 -0
- package/src/runtime-home/schemas.ts +485 -0
- package/src/sandboxes/exedev.ts +676 -0
- package/src/server/app.ts +5 -0
- package/src/server/autopilot-push-dispatch.ts +326 -0
- package/src/server/create-app.ts +160 -0
- package/src/server/events/config-stream.ts +67 -0
- package/src/server/events/notification-stream.ts +49 -0
- package/src/server/events/session-stream.ts +49 -0
- package/src/server/http.ts +56 -0
- package/src/server/learning-hooks.ts +430 -0
- package/src/server/middleware.ts +81 -0
- package/src/server/routes/autopilot.ts +318 -0
- package/src/server/routes/commands.ts +12 -0
- package/src/server/routes/config.ts +124 -0
- package/src/server/routes/execution.ts +71 -0
- package/src/server/routes/github.ts +372 -0
- package/src/server/routes/handoff.ts +69 -0
- package/src/server/routes/kilo.ts +179 -0
- package/src/server/routes/learning.ts +384 -0
- package/src/server/routes/mcp.ts +301 -0
- package/src/server/routes/memory.ts +99 -0
- package/src/server/routes/metrics.ts +12 -0
- package/src/server/routes/notifications.ts +48 -0
- package/src/server/routes/repo-edit.ts +115 -0
- package/src/server/routes/reports.ts +127 -0
- package/src/server/routes/repos.ts +50 -0
- package/src/server/routes/runtime.ts +48 -0
- package/src/server/routes/safety.ts +13 -0
- package/src/server/routes/scheduled-tasks.ts +58 -0
- package/src/server/routes/scheduler.ts +13 -0
- package/src/server/routes/sessions.ts +216 -0
- package/src/server/routes/skills.ts +103 -0
- package/src/server/routes/watches.ts +81 -0
- package/src/server/routes/workflows.ts +21 -0
- package/src/server/routes/worktrees.ts +64 -0
- package/src/server/scheduler-workflow.ts +541 -0
- package/src/server/serve.ts +100 -0
- package/src/setup.ts +162 -0
- package/src/skills/github-gh/SKILL.md +56 -0
- package/src/skills/neon-ci-fix/SKILL.md +15 -0
- package/src/skills/neon-docs-fix/SKILL.md +15 -0
- package/src/skills/neon-issue-triage/SKILL.md +13 -0
- package/src/skills/neon-pr-review/SKILL.md +19 -0
- package/src/skills/neondeck/SKILL.md +123 -0
- package/src/skills/neondeck-handoff/SKILL.md +31 -0
- package/src/workflows/briefing.ts +14 -0
- package/src/workflows/command-run.ts +15 -0
- package/src/workflows/comment-pr-autofix-result.ts +10 -0
- package/src/workflows/curate_learning_store.ts +37 -0
- package/src/workflows/dev-doctor.ts +10 -0
- package/src/workflows/fix-pr-ci-failure.ts +10 -0
- package/src/workflows/fix-pr-ci.ts +15 -0
- package/src/workflows/fix-pr-review-feedback.ts +10 -0
- package/src/workflows/handoff_to_kilo.ts +10 -0
- package/src/workflows/prepare-pr-worktree.ts +10 -0
- package/src/workflows/promote_kilo_result.ts +10 -0
- package/src/workflows/push-pr-autofix.ts +10 -0
- package/src/workflows/reconcile_kilo_task.ts +10 -0
- package/src/workflows/review-pr-for-human.ts +15 -0
- package/src/workflows/review_conversation_for_learning.ts +37 -0
- package/src/workflows/review_kilo_result.ts +10 -0
- package/src/workflows/review_pr_batch_for_learning.ts +37 -0
- package/src/workflows/scheduled-agent-instruction.ts +16 -0
- package/src/workflows/scheduler-tick.ts +10 -0
- package/src/workflows/summarize_kilo_session.ts +25 -0
- package/src/workflows/triage-pr-event.ts +10 -0
- package/src/workflows/verify-pr-worktree.ts +10 -0
- package/src/workflows/verify-then-push-pr-autofix.ts +82 -0
- package/src/workflows/verify_kilo_result.ts +10 -0
- package/src/workflows/watch-pr.ts +10 -0
- package/web/dist/assets/GitHubPrReview-QK9oqeDs.js +2 -0
- package/web/dist/assets/MultiFileView-CMm6tA9f.js +2970 -0
- package/web/dist/assets/abap-CLvhMVsD.js +1 -0
- package/web/dist/assets/actionscript-3--17pq3dv.js +1 -0
- package/web/dist/assets/ada-C5qYipkI.js +1 -0
- package/web/dist/assets/andromeeda-vGVdxbeo.js +1 -0
- package/web/dist/assets/angular-html-BVBpGdXr.js +1 -0
- package/web/dist/assets/angular-ts-BfdufMKP.js +1 -0
- package/web/dist/assets/apache-U0d_L8uA.js +1 -0
- package/web/dist/assets/apex-VAyPSnFM.js +1 -0
- package/web/dist/assets/apl-DWBSSoBH.js +1 -0
- package/web/dist/assets/applescript-CCn79oCD.js +1 -0
- package/web/dist/assets/ara-4CJ0cIlV.js +1 -0
- package/web/dist/assets/asciidoc-DE70LPWp.js +1 -0
- package/web/dist/assets/asm-Cmm7eHzH.js +1 -0
- package/web/dist/assets/astro-3LtMP0Sq.js +1 -0
- package/web/dist/assets/aurora-x-CDeNXAV0.js +1 -0
- package/web/dist/assets/awk-BWXHIvNe.js +1 -0
- package/web/dist/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/web/dist/assets/ayu-light-C3h-C4tm.js +1 -0
- package/web/dist/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/web/dist/assets/ballerina-B7ZEbQpA.js +1 -0
- package/web/dist/assets/bat-Bo4NYOV-.js +1 -0
- package/web/dist/assets/beancount-D-usSTwE.js +1 -0
- package/web/dist/assets/berry-DKpUyyne.js +1 -0
- package/web/dist/assets/bibtex-Ci_nEsc7.js +1 -0
- package/web/dist/assets/bicep-CUHmPFLl.js +1 -0
- package/web/dist/assets/bird2-C6vDhewU.js +1 -0
- package/web/dist/assets/blade-llJRbbtR.js +1 -0
- package/web/dist/assets/bsl-BkkzgIyY.js +1 -0
- package/web/dist/assets/c-Wt1voDr2.js +1 -0
- package/web/dist/assets/c3-BFHwR3_K.js +1 -0
- package/web/dist/assets/cadence-CQ2zXKGN.js +1 -0
- package/web/dist/assets/cairo-DLTphjLi.js +1 -0
- package/web/dist/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
- package/web/dist/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
- package/web/dist/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
- package/web/dist/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
- package/web/dist/assets/clarity-SemFz856.js +1 -0
- package/web/dist/assets/clojure-DqKBuwfJ.js +1 -0
- package/web/dist/assets/cmake-Bj61d0ZC.js +1 -0
- package/web/dist/assets/cobol-x_HIyl2P.js +1 -0
- package/web/dist/assets/codeowners-C8r90Shi.js +1 -0
- package/web/dist/assets/codeql-oeQT6MSM.js +1 -0
- package/web/dist/assets/coffee-CThvmt4R.js +1 -0
- package/web/dist/assets/common-lisp-Cv5bFMCO.js +1 -0
- package/web/dist/assets/coq-BrsZFFmf.js +1 -0
- package/web/dist/assets/cpp-NtAeskI3.js +1 -0
- package/web/dist/assets/crystal-DNu_sX0G.js +1 -0
- package/web/dist/assets/csharp-oqKa8noW.js +1 -0
- package/web/dist/assets/css-DJp_X0uY.js +1 -0
- package/web/dist/assets/csv-Dx-8-gkx.js +1 -0
- package/web/dist/assets/cue-CE9AQfxI.js +1 -0
- package/web/dist/assets/cypher-ClKdZ_lG.js +1 -0
- package/web/dist/assets/d-qD-0Kul2.js +1 -0
- package/web/dist/assets/dark-plus-Cs2F2srj.js +1 -0
- package/web/dist/assets/dart-CnvKMtbv.js +1 -0
- package/web/dist/assets/dax-BkyTk9wS.js +1 -0
- package/web/dist/assets/desktop-Dlh5hvp9.js +1 -0
- package/web/dist/assets/diff-woXpYk--.js +1 -0
- package/web/dist/assets/docker-IyjqRm3v.js +1 -0
- package/web/dist/assets/dotenv-_5a1GRtc.js +1 -0
- package/web/dist/assets/dracula-BHWKrbxM.js +1 -0
- package/web/dist/assets/dracula-soft-5eyTD99u.js +1 -0
- package/web/dist/assets/dream-maker-DW3nJb8Q.js +1 -0
- package/web/dist/assets/edge-ozw5tpLl.js +1 -0
- package/web/dist/assets/elixir-VhA6FeZt.js +1 -0
- package/web/dist/assets/elm-dREJmIFz.js +1 -0
- package/web/dist/assets/emacs-lisp-B4R74twV.js +1 -0
- package/web/dist/assets/erb-CIg6G69l.js +1 -0
- package/web/dist/assets/erlang-Cphh6RMH.js +1 -0
- package/web/dist/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/web/dist/assets/everforest-light-Df2xbC6M.js +1 -0
- package/web/dist/assets/fennel-DQxkIbk2.js +1 -0
- package/web/dist/assets/fish-BJitypiv.js +1 -0
- package/web/dist/assets/fluent-C03EYrpw.js +1 -0
- package/web/dist/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
- package/web/dist/assets/fortran-free-form-CYNrtFtB.js +1 -0
- package/web/dist/assets/fsharp-D13ZGOAj.js +1 -0
- package/web/dist/assets/gdresource-C0sCabJj.js +1 -0
- package/web/dist/assets/gdscript-Cp2uCuqX.js +1 -0
- package/web/dist/assets/gdshader-CBce3t8t.js +1 -0
- package/web/dist/assets/genie-CV2tkWYe.js +1 -0
- package/web/dist/assets/gherkin-DExj1W_8.js +1 -0
- package/web/dist/assets/git-commit-BSykSTBG.js +1 -0
- package/web/dist/assets/git-rebase-B44mJPta.js +1 -0
- package/web/dist/assets/github-dark-C-LZuMrd.js +1 -0
- package/web/dist/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/web/dist/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/web/dist/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/web/dist/assets/github-light-EUqPIrTm.js +1 -0
- package/web/dist/assets/github-light-default-BXViO-2h.js +1 -0
- package/web/dist/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/web/dist/assets/gleam-CSRkHgEL.js +1 -0
- package/web/dist/assets/glimmer-js-vH_gHG0-.js +1 -0
- package/web/dist/assets/glimmer-ts--abOzSAQ.js +1 -0
- package/web/dist/assets/glsl-Dv5r7kPw.js +1 -0
- package/web/dist/assets/gn-ilITqXS6.js +1 -0
- package/web/dist/assets/gnuplot-7GGW24-e.js +1 -0
- package/web/dist/assets/go-rLFTqkRN.js +1 -0
- package/web/dist/assets/graphql-CB4jsw2E.js +1 -0
- package/web/dist/assets/groovy-CacY0gHj.js +1 -0
- package/web/dist/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/web/dist/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/web/dist/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/web/dist/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/web/dist/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/web/dist/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/web/dist/assets/hack-DvEYX148.js +1 -0
- package/web/dist/assets/haml-zE6W3STP.js +1 -0
- package/web/dist/assets/handlebars-CzBR2SDs.js +1 -0
- package/web/dist/assets/haskell-D8IpX4py.js +1 -0
- package/web/dist/assets/haxe-OTjmBuCE.js +1 -0
- package/web/dist/assets/hcl-Dh228itO.js +1 -0
- package/web/dist/assets/hjson-CxZEssPk.js +1 -0
- package/web/dist/assets/hlsl-Cvrh5tZx.js +1 -0
- package/web/dist/assets/horizon-CE9ld1lL.js +1 -0
- package/web/dist/assets/horizon-bright-DSNQnXHK.js +1 -0
- package/web/dist/assets/houston-CsvMBhTu.js +1 -0
- package/web/dist/assets/html-C8UlPnhE.js +1 -0
- package/web/dist/assets/html-derivative-CY6NRz-J.js +1 -0
- package/web/dist/assets/http-Cyd7bS_S.js +1 -0
- package/web/dist/assets/hurl-CWPsiEpf.js +1 -0
- package/web/dist/assets/hxml-B0Qn7Nwc.js +1 -0
- package/web/dist/assets/hy-CZbG8q4J.js +1 -0
- package/web/dist/assets/imba-DsUTQ-LC.js +1 -0
- package/web/dist/assets/index-DqZpo0Jd.js +44 -0
- package/web/dist/assets/index-_jKCE4ks.css +2 -0
- package/web/dist/assets/ini-B5eOa1yu.js +1 -0
- package/web/dist/assets/java-CGc3VwQr.js +1 -0
- package/web/dist/assets/javascript-CUt1pgmJ.js +1 -0
- package/web/dist/assets/jinja-CD-Z-FLd.js +1 -0
- package/web/dist/assets/jison-imPNup1l.js +1 -0
- package/web/dist/assets/json-Bg9ijW3F.js +1 -0
- package/web/dist/assets/json5-BR5RXkoi.js +1 -0
- package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
- package/web/dist/assets/jsonl-CmCQp5Yx.js +1 -0
- package/web/dist/assets/jsonnet-CJTPZ8u_.js +1 -0
- package/web/dist/assets/jssm-DXw9l8Rf.js +1 -0
- package/web/dist/assets/jsx-CY6oMTks.js +1 -0
- package/web/dist/assets/julia-Dc3O-irA.js +1 -0
- package/web/dist/assets/just-BhOq_Kbv.js +1 -0
- package/web/dist/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
- package/web/dist/assets/kanagawa-lotus-BN08jTvb.js +1 -0
- package/web/dist/assets/kanagawa-wave-CTweb8Dz.js +1 -0
- package/web/dist/assets/kdl-CsD5j6eV.js +1 -0
- package/web/dist/assets/kotlin-DhhofPvG.js +1 -0
- package/web/dist/assets/kusto-C7mF5XQf.js +1 -0
- package/web/dist/assets/laserwave-C_8bwKvT.js +1 -0
- package/web/dist/assets/latex-Cu4Y1d5w.js +1 -0
- package/web/dist/assets/lean-CewbzKMR.js +1 -0
- package/web/dist/assets/less-DVTAwKKz.js +1 -0
- package/web/dist/assets/light-plus-DVQuIRkW.js +1 -0
- package/web/dist/assets/liquid-CvXMrjlQ.js +1 -0
- package/web/dist/assets/llvm-Cm23YOpf.js +1 -0
- package/web/dist/assets/log-BNLmms1o.js +1 -0
- package/web/dist/assets/logo-Cluzi2Zq.js +1 -0
- package/web/dist/assets/lua-BjLEUjKY.js +1 -0
- package/web/dist/assets/luau-FMPmPwt6.js +1 -0
- package/web/dist/assets/make-Dixweg8N.js +1 -0
- package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
- package/web/dist/assets/marko-DvhNOisQ.js +1 -0
- package/web/dist/assets/material-theme-Bm3Qr25_.js +1 -0
- package/web/dist/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/web/dist/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/web/dist/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/web/dist/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/web/dist/assets/matlab-D7qyCx1q.js +1 -0
- package/web/dist/assets/mdc-Bm9TpL1X.js +1 -0
- package/web/dist/assets/mdx-DQZ5AkYe.js +1 -0
- package/web/dist/assets/mermaid-Bk4SNUv9.js +1 -0
- package/web/dist/assets/min-dark-BSWPekZh.js +1 -0
- package/web/dist/assets/min-light-DDpmG2fV.js +1 -0
- package/web/dist/assets/mipsasm-BMqwQI7S.js +1 -0
- package/web/dist/assets/mojo-BgCJLMeH.js +1 -0
- package/web/dist/assets/monokai-CdkpiU2Y.js +1 -0
- package/web/dist/assets/moonbit-CaWjb8XO.js +1 -0
- package/web/dist/assets/move-B1IS1UjX.js +1 -0
- package/web/dist/assets/narrat-_X_XdTYD.js +1 -0
- package/web/dist/assets/nextflow-BJtWHP5T.js +1 -0
- package/web/dist/assets/nextflow-groovy-DJMQeKeT.js +1 -0
- package/web/dist/assets/nginx-Bhc82uuv.js +1 -0
- package/web/dist/assets/night-owl-DhmEMT88.js +1 -0
- package/web/dist/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/web/dist/assets/nim-DXTVBFnF.js +1 -0
- package/web/dist/assets/nix-IvuFDN5E.js +1 -0
- package/web/dist/assets/nord-Cb4Vim4T.js +1 -0
- package/web/dist/assets/nushell-DcLAeLz5.js +1 -0
- package/web/dist/assets/objective-c-D1A_Heim.js +1 -0
- package/web/dist/assets/objective-cpp-BsSzOQcm.js +1 -0
- package/web/dist/assets/ocaml-O90oeIOV.js +1 -0
- package/web/dist/assets/odin-B1RWQWA5.js +1 -0
- package/web/dist/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/web/dist/assets/one-light-D7Lr4KcI.js +1 -0
- package/web/dist/assets/openscad-BUDT5pXO.js +1 -0
- package/web/dist/assets/pascal-4ZHwLPI5.js +1 -0
- package/web/dist/assets/perl-C7veXV9z.js +1 -0
- package/web/dist/assets/php-BRiuMnnr.js +1 -0
- package/web/dist/assets/pierre-dark-CpLgRqie.js +1 -0
- package/web/dist/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
- package/web/dist/assets/pierre-dark-soft-kZQmAZld.js +1 -0
- package/web/dist/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
- package/web/dist/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
- package/web/dist/assets/pierre-light-CoaEpmwp.js +1 -0
- package/web/dist/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
- package/web/dist/assets/pierre-light-soft-lWLdNTOI.js +1 -0
- package/web/dist/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
- package/web/dist/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
- package/web/dist/assets/pkl-ot-7Btpt.js +1 -0
- package/web/dist/assets/plastic-DQwYfKfQ.js +1 -0
- package/web/dist/assets/plsql-DGHpHOYJ.js +1 -0
- package/web/dist/assets/po-BiJDBrnU.js +1 -0
- package/web/dist/assets/poimandres-DRFjx7u4.js +1 -0
- package/web/dist/assets/polar-C7UOKdEL.js +1 -0
- package/web/dist/assets/postcss-BXeXVLqQ.js +1 -0
- package/web/dist/assets/powerquery-DNMTfnFr.js +1 -0
- package/web/dist/assets/powershell-DshXNtvi.js +1 -0
- package/web/dist/assets/prisma-BsRQq5mF.js +1 -0
- package/web/dist/assets/prolog-iXnhIJG7.js +1 -0
- package/web/dist/assets/proto-DB4EqR-F.js +1 -0
- package/web/dist/assets/pug-C5hz5LQ7.js +1 -0
- package/web/dist/assets/puppet-CDv2pdJW.js +1 -0
- package/web/dist/assets/purescript-9MfHhQsQ.js +1 -0
- package/web/dist/assets/python-gzcpVVnB.js +1 -0
- package/web/dist/assets/qml-BdUV3aTS.js +1 -0
- package/web/dist/assets/qmldir-DCQb3MpD.js +1 -0
- package/web/dist/assets/qss-Fe1Jh2GI.js +1 -0
- package/web/dist/assets/r-8R7vtdQc.js +1 -0
- package/web/dist/assets/racket-DcIDlBhZ.js +1 -0
- package/web/dist/assets/raku-B3gFvitq.js +1 -0
- package/web/dist/assets/razor-DRL52XO2.js +1 -0
- package/web/dist/assets/red-CJ3rzSJv.js +1 -0
- package/web/dist/assets/reg-CRGYupPL.js +1 -0
- package/web/dist/assets/regexp-Omp9DhTb.js +1 -0
- package/web/dist/assets/rel-BtDbiS_P.js +1 -0
- package/web/dist/assets/riscv-Ckw8ddFX.js +1 -0
- package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/web/dist/assets/ron-VUp2lXgN.js +1 -0
- package/web/dist/assets/rose-pine-BthvhNj6.js +1 -0
- package/web/dist/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
- package/web/dist/assets/rose-pine-moon-hon4tzzS.js +1 -0
- package/web/dist/assets/rosmsg-CAekHB0j.js +1 -0
- package/web/dist/assets/rst-BHX71KW9.js +1 -0
- package/web/dist/assets/ruby-B--HzjGU.js +1 -0
- package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
- package/web/dist/assets/sas-DrLaYOK_.js +1 -0
- package/web/dist/assets/sass-DXrisJhu.js +1 -0
- package/web/dist/assets/scala-DKOlJaKm.js +1 -0
- package/web/dist/assets/scheme-DQCgrYNe.js +1 -0
- package/web/dist/assets/scss-DdSxiZKl.js +1 -0
- package/web/dist/assets/sdbl-bTVj8UrX.js +1 -0
- package/web/dist/assets/shaderlab-TOUzSsQk.js +1 -0
- package/web/dist/assets/shellscript-DwcUjJBL.js +1 -0
- package/web/dist/assets/shellsession-CPZkydE6.js +1 -0
- package/web/dist/assets/slack-dark-DnToyrRv.js +1 -0
- package/web/dist/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/web/dist/assets/smalltalk-B16xEiuN.js +1 -0
- package/web/dist/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/web/dist/assets/solarized-dark-DV17i1UV.js +1 -0
- package/web/dist/assets/solarized-light-DSh2HLQt.js +1 -0
- package/web/dist/assets/solidity-CKzVLygQ.js +1 -0
- package/web/dist/assets/soy-Br5FhD7c.js +1 -0
- package/web/dist/assets/sparql-D_iOobhT.js +1 -0
- package/web/dist/assets/splunk-BC2Px7Mm.js +1 -0
- package/web/dist/assets/sql-DNssxck8.js +1 -0
- package/web/dist/assets/ssh-config-BgfXC-Er.js +1 -0
- package/web/dist/assets/stata-DXn1tqOr.js +1 -0
- package/web/dist/assets/stylus-B6D30XZt.js +1 -0
- package/web/dist/assets/surfaces-B8Ko8AJ3.js +1 -0
- package/web/dist/assets/surrealql-IeLNQw0f.js +1 -0
- package/web/dist/assets/svelte-DOdLCIlh.js +1 -0
- package/web/dist/assets/swift-DonLKvLd.js +1 -0
- package/web/dist/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/web/dist/assets/system-verilog-DJ5XKQeo.js +1 -0
- package/web/dist/assets/systemd-BxMlprV5.js +1 -0
- package/web/dist/assets/talonscript-CohzipZa.js +1 -0
- package/web/dist/assets/tasl-DMoTqEGO.js +1 -0
- package/web/dist/assets/tcl-CZd0xW_V.js +1 -0
- package/web/dist/assets/templ-CIwIngms.js +1 -0
- package/web/dist/assets/terraform-DswuEJGm.js +1 -0
- package/web/dist/assets/tex-D8QMumu5.js +1 -0
- package/web/dist/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/web/dist/assets/toml-CcmNWLt0.js +1 -0
- package/web/dist/assets/ts-tags-BMVY4q-l.js +1 -0
- package/web/dist/assets/tsv-sltzmVWM.js +1 -0
- package/web/dist/assets/tsx-5Eka4NBX.js +1 -0
- package/web/dist/assets/turtle-ByJddavk.js +1 -0
- package/web/dist/assets/twig-C8o_5mgw.js +1 -0
- package/web/dist/assets/typescript-DOu2WMV5.js +1 -0
- package/web/dist/assets/typespec-BRdr0IET.js +1 -0
- package/web/dist/assets/typst-DI99ib-x.js +1 -0
- package/web/dist/assets/v-DETTlOr0.js +1 -0
- package/web/dist/assets/vala-zf12oZj6.js +1 -0
- package/web/dist/assets/vb-Djn5o6TS.js +1 -0
- package/web/dist/assets/verilog-CiiDBU1e.js +1 -0
- package/web/dist/assets/vesper-DdrHHSXu.js +1 -0
- package/web/dist/assets/vhdl-BroJfC0k.js +1 -0
- package/web/dist/assets/viml-DvXPmvsu.js +1 -0
- package/web/dist/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/web/dist/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/web/dist/assets/vitesse-light-VbXTXTou.js +1 -0
- package/web/dist/assets/vue-BU18DNDL.js +1 -0
- package/web/dist/assets/vue-html-BeluIYX0.js +1 -0
- package/web/dist/assets/vue-vine-DGUAbOCX.js +1 -0
- package/web/dist/assets/vyper-CgoNMtux.js +1 -0
- package/web/dist/assets/wasm-BnjxR4X6.js +1 -0
- package/web/dist/assets/wasm-ByWQv1Qj.js +1 -0
- package/web/dist/assets/wenyan-C8pVoKbM.js +1 -0
- package/web/dist/assets/wgsl-BsKzXJz4.js +1 -0
- package/web/dist/assets/wikitext-ClFFjSW2.js +1 -0
- package/web/dist/assets/wit-DdvCle-K.js +1 -0
- package/web/dist/assets/wolfram-DLL8P-h_.js +1 -0
- package/web/dist/assets/worker-CBKQOXEl.js +160 -0
- package/web/dist/assets/xml-DIqSwXR3.js +1 -0
- package/web/dist/assets/xsl-Ct_-YIAy.js +1 -0
- package/web/dist/assets/yaml-DTtCYNlS.js +1 -0
- package/web/dist/assets/zenscript-BnlCZFoB.js +1 -0
- package/web/dist/assets/zig-CMLA9XwU.js +1 -0
- package/web/dist/icons/neondeck-icon-192.png +0 -0
- package/web/dist/icons/neondeck-icon-512.png +0 -0
- package/web/dist/icons/neondeck-icon.svg +41 -0
- package/web/dist/icons/neondeck-maskable-512.png +0 -0
- package/web/dist/index.html +24 -0
- package/web/dist/manifest.webmanifest +28 -0
|
@@ -0,0 +1,1414 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { defineAction, defineTool, type JsonValue } from '@flue/runtime';
|
|
3
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
4
|
+
import * as v from 'valibot';
|
|
5
|
+
import {
|
|
6
|
+
addPrReviewDraftComment,
|
|
7
|
+
deletePrReviewDraftComment,
|
|
8
|
+
discardPrReviewDraft,
|
|
9
|
+
fetchPullRequestEventState,
|
|
10
|
+
fetchPullRequestFiles,
|
|
11
|
+
fetchPullRequestFilesWithCache,
|
|
12
|
+
fetchPullRequestReviewThreadsWithMetadata,
|
|
13
|
+
fetchPullRequestReviewThread,
|
|
14
|
+
GitHubPrReviewSubmitError,
|
|
15
|
+
postPullRequestComment,
|
|
16
|
+
pullRequestEventStateTruncation,
|
|
17
|
+
readLivePrReviewDraft,
|
|
18
|
+
readCachedPullRequestFiles,
|
|
19
|
+
readPrReviewDraft,
|
|
20
|
+
readPrReviewDraftForComment,
|
|
21
|
+
replyToPullRequestReviewThread,
|
|
22
|
+
resolvePullRequestReviewThread,
|
|
23
|
+
submitPullRequestReview,
|
|
24
|
+
unresolvePullRequestReviewThread,
|
|
25
|
+
updatePrReviewDraftComment,
|
|
26
|
+
upsertPrReviewDraft,
|
|
27
|
+
type GitHubPrReviewDraft,
|
|
28
|
+
type GitHubPrReviewDraftComment,
|
|
29
|
+
type GitHubPullRequestEventState,
|
|
30
|
+
type GitHubPullRequestReviewThread,
|
|
31
|
+
} from '../github';
|
|
32
|
+
import {
|
|
33
|
+
readLocalPullRequestFileDiff,
|
|
34
|
+
readLocalPullRequestFiles,
|
|
35
|
+
} from '../pr-local-diffs';
|
|
36
|
+
import { readRepoRegistrySnapshot, repoFullName } from '../repos';
|
|
37
|
+
import {
|
|
38
|
+
type RuntimePaths,
|
|
39
|
+
ensureRuntimeHome,
|
|
40
|
+
runtimePaths,
|
|
41
|
+
} from '../../runtime-home';
|
|
42
|
+
import {
|
|
43
|
+
listPrWatchRecords,
|
|
44
|
+
parseWatchPrReference,
|
|
45
|
+
type PrWatch,
|
|
46
|
+
} from '../watches';
|
|
47
|
+
import {
|
|
48
|
+
prCommentInputSchema,
|
|
49
|
+
prEventTargetInputSchema,
|
|
50
|
+
prFileDiffInputSchema,
|
|
51
|
+
prFilesInputSchema,
|
|
52
|
+
prReviewDraftCommentInputSchema,
|
|
53
|
+
prReviewDraftCommentUpdateInputSchema,
|
|
54
|
+
prReviewDraftInputSchema,
|
|
55
|
+
prReviewSubmitInputSchema,
|
|
56
|
+
prReviewThreadReplyInputSchema,
|
|
57
|
+
prWatchEventWatermarkListInputSchema,
|
|
58
|
+
type PrEventActionResult,
|
|
59
|
+
type PrEventStateDependencies,
|
|
60
|
+
type PullRequestTarget,
|
|
61
|
+
} from './schemas';
|
|
62
|
+
import {
|
|
63
|
+
fetchEventState,
|
|
64
|
+
isConfiguredRepoTarget,
|
|
65
|
+
resolvePullRequestTarget,
|
|
66
|
+
} from './target';
|
|
67
|
+
import {
|
|
68
|
+
buildPatchAnchorIndex,
|
|
69
|
+
commentAnchorExists,
|
|
70
|
+
} from '../../../shared/patch-anchors';
|
|
71
|
+
import {
|
|
72
|
+
readWatermarks,
|
|
73
|
+
upsertWatermarks,
|
|
74
|
+
watermarksFromEventState,
|
|
75
|
+
} from './watermarks';
|
|
76
|
+
import {
|
|
77
|
+
errorMessage,
|
|
78
|
+
eventTargetJson,
|
|
79
|
+
failResult,
|
|
80
|
+
okResult,
|
|
81
|
+
stableJson,
|
|
82
|
+
} from './utils';
|
|
83
|
+
|
|
84
|
+
export async function getGitHubPrEventState(
|
|
85
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
86
|
+
paths: RuntimePaths = runtimePaths(),
|
|
87
|
+
dependencies: PrEventStateDependencies = {},
|
|
88
|
+
): Promise<PrEventActionResult> {
|
|
89
|
+
const resolved = await fetchEventState(
|
|
90
|
+
'github_pr_event_state_get',
|
|
91
|
+
input,
|
|
92
|
+
paths,
|
|
93
|
+
dependencies,
|
|
94
|
+
);
|
|
95
|
+
if (!resolved.ok) return resolved.result;
|
|
96
|
+
|
|
97
|
+
return okResult(
|
|
98
|
+
'github_pr_event_state_get',
|
|
99
|
+
false,
|
|
100
|
+
`Fetched PR event state for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
101
|
+
{
|
|
102
|
+
target: eventTargetJson(resolved.target),
|
|
103
|
+
state: resolved.state as unknown as JsonValue,
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export async function getGitHubPrReviewThreads(
|
|
109
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
110
|
+
paths: RuntimePaths = runtimePaths(),
|
|
111
|
+
dependencies: PrEventStateDependencies = {},
|
|
112
|
+
): Promise<PrEventActionResult> {
|
|
113
|
+
const action = 'github_pr_review_threads_get';
|
|
114
|
+
await ensureRuntimeHome(paths);
|
|
115
|
+
const parsed = v.safeParse(prEventTargetInputSchema, input);
|
|
116
|
+
if (!parsed.success) {
|
|
117
|
+
return failResult(action, 'Invalid PR review threads input.', {
|
|
118
|
+
errors: [v.summarize(parsed.issues)],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
123
|
+
if (!token) {
|
|
124
|
+
return failResult(action, 'GITHUB_TOKEN is not configured.', {
|
|
125
|
+
requires: ['GITHUB_TOKEN'],
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const resolved = await resolvePullRequestTarget(parsed.output, paths, action);
|
|
130
|
+
if (!resolved.ok) return resolved.result;
|
|
131
|
+
|
|
132
|
+
let threads: GitHubPullRequestReviewThread[];
|
|
133
|
+
let truncated = false;
|
|
134
|
+
try {
|
|
135
|
+
const fetcher =
|
|
136
|
+
dependencies.fetchPullRequestReviewThreads ??
|
|
137
|
+
fetchPullRequestReviewThreadsWithMetadata;
|
|
138
|
+
const result = await fetcher({
|
|
139
|
+
token,
|
|
140
|
+
owner: resolved.target.owner,
|
|
141
|
+
repo: resolved.target.repo,
|
|
142
|
+
number: resolved.target.number,
|
|
143
|
+
});
|
|
144
|
+
threads = result.reviewThreads;
|
|
145
|
+
truncated =
|
|
146
|
+
result.truncated || threads.some((thread) => thread.commentsTruncated);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
return failResult(action, 'Could not fetch GitHub PR review threads.', {
|
|
149
|
+
errors: [errorMessage(error)],
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const unresolvedThreads = threads.filter((thread) => !thread.isResolved);
|
|
154
|
+
const unresolvedReviewComments = unresolvedThreads.flatMap((thread) =>
|
|
155
|
+
thread.comments.map((comment) => ({
|
|
156
|
+
...comment,
|
|
157
|
+
threadId: thread.id,
|
|
158
|
+
threadPath: thread.path,
|
|
159
|
+
threadLine: thread.line,
|
|
160
|
+
threadIsOutdated: thread.isOutdated,
|
|
161
|
+
})),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
return okResult(
|
|
165
|
+
action,
|
|
166
|
+
false,
|
|
167
|
+
`Fetched ${threads.length} review thread(s) for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
168
|
+
{
|
|
169
|
+
target: eventTargetJson(resolved.target),
|
|
170
|
+
reviewThreads: threads as unknown as JsonValue,
|
|
171
|
+
reviewThreadsTruncated: truncated,
|
|
172
|
+
unresolvedReviewThreads: unresolvedThreads as unknown as JsonValue,
|
|
173
|
+
unresolvedReviewComments:
|
|
174
|
+
unresolvedReviewComments as unknown as JsonValue,
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function getGitHubPrFiles(
|
|
180
|
+
input: v.InferInput<typeof prFilesInputSchema>,
|
|
181
|
+
paths: RuntimePaths = runtimePaths(),
|
|
182
|
+
dependencies: PrEventStateDependencies = {},
|
|
183
|
+
): Promise<PrEventActionResult> {
|
|
184
|
+
await ensureRuntimeHome(paths);
|
|
185
|
+
const parsed = v.safeParse(prFilesInputSchema, input);
|
|
186
|
+
if (!parsed.success) {
|
|
187
|
+
return failResult('github_pr_files_get', 'Invalid PR files input.', {
|
|
188
|
+
errors: [v.summarize(parsed.issues)],
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const resolved = await resolvePullRequestTarget(
|
|
193
|
+
{
|
|
194
|
+
watchId: parsed.output.watchId,
|
|
195
|
+
ref: parsed.output.ref,
|
|
196
|
+
repo: parsed.output.repo,
|
|
197
|
+
prNumber: parsed.output.prNumber,
|
|
198
|
+
},
|
|
199
|
+
paths,
|
|
200
|
+
'github_pr_files_get',
|
|
201
|
+
);
|
|
202
|
+
if (!resolved.ok) return resolved.result;
|
|
203
|
+
|
|
204
|
+
const patches = parsed.output.patches ?? 'all';
|
|
205
|
+
const source = parsed.output.source ?? 'auto';
|
|
206
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
207
|
+
const localErrorMessages: string[] = [];
|
|
208
|
+
if (source !== 'github') {
|
|
209
|
+
try {
|
|
210
|
+
const diff = await readLocalPullRequestFiles(
|
|
211
|
+
{
|
|
212
|
+
owner: resolved.target.owner,
|
|
213
|
+
repo: resolved.target.repo,
|
|
214
|
+
number: resolved.target.number,
|
|
215
|
+
headSha: parsed.output.headSha ?? null,
|
|
216
|
+
baseSha: parsed.output.baseSha ?? null,
|
|
217
|
+
baseRef: parsed.output.baseRef ?? null,
|
|
218
|
+
includePatches: patches === 'all',
|
|
219
|
+
},
|
|
220
|
+
paths,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
return okResult(
|
|
224
|
+
'github_pr_files_get',
|
|
225
|
+
false,
|
|
226
|
+
`Fetched ${diff.files.length} local PR file diff(s) for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
227
|
+
{
|
|
228
|
+
target: eventTargetJson(resolved.target),
|
|
229
|
+
files: diff.files as unknown as JsonValue,
|
|
230
|
+
diffSummary: diff.diffSummary as unknown as JsonValue,
|
|
231
|
+
fetchedAt: diff.fetchedAt,
|
|
232
|
+
source: 'local',
|
|
233
|
+
},
|
|
234
|
+
);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
localErrorMessages.push(errorMessage(error));
|
|
237
|
+
if (source === 'local') {
|
|
238
|
+
return failResult(
|
|
239
|
+
'github_pr_files_get',
|
|
240
|
+
'Could not fetch local PR files.',
|
|
241
|
+
{ errors: localErrorMessages },
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!token) {
|
|
248
|
+
return failResult(
|
|
249
|
+
'github_pr_files_get',
|
|
250
|
+
'GITHUB_TOKEN is not configured.',
|
|
251
|
+
{
|
|
252
|
+
requires: ['GITHUB_TOKEN'],
|
|
253
|
+
errors: localErrorMessages.length ? localErrorMessages : undefined,
|
|
254
|
+
},
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const fetcher = dependencies.fetchPullRequestFiles ?? fetchPullRequestFiles;
|
|
260
|
+
const diff = await fetchPullRequestFilesWithCache({
|
|
261
|
+
token,
|
|
262
|
+
owner: resolved.target.owner,
|
|
263
|
+
repo: resolved.target.repo,
|
|
264
|
+
number: resolved.target.number,
|
|
265
|
+
headSha: parsed.output.headSha ?? null,
|
|
266
|
+
patches,
|
|
267
|
+
databasePath: paths.neondeckDatabase,
|
|
268
|
+
fetcher,
|
|
269
|
+
fetchHeadSha: dependencies.fetchPullRequestHeadSha,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return okResult(
|
|
273
|
+
'github_pr_files_get',
|
|
274
|
+
false,
|
|
275
|
+
`Fetched ${diff.files.length} PR file diff(s) for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
276
|
+
{
|
|
277
|
+
target: eventTargetJson(resolved.target),
|
|
278
|
+
files: diff.files as unknown as JsonValue,
|
|
279
|
+
diffSummary: diff.diffSummary as unknown as JsonValue,
|
|
280
|
+
fetchedAt: diff.fetchedAt,
|
|
281
|
+
source: 'github',
|
|
282
|
+
},
|
|
283
|
+
);
|
|
284
|
+
} catch (error) {
|
|
285
|
+
return failResult(
|
|
286
|
+
'github_pr_files_get',
|
|
287
|
+
'Could not fetch GitHub PR files.',
|
|
288
|
+
{
|
|
289
|
+
errors: [errorMessage(error)],
|
|
290
|
+
},
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export async function getGitHubPrFileDiff(
|
|
296
|
+
input: v.InferInput<typeof prFileDiffInputSchema>,
|
|
297
|
+
paths: RuntimePaths = runtimePaths(),
|
|
298
|
+
dependencies: PrEventStateDependencies = {},
|
|
299
|
+
): Promise<PrEventActionResult> {
|
|
300
|
+
await ensureRuntimeHome(paths);
|
|
301
|
+
const parsed = v.safeParse(prFileDiffInputSchema, input);
|
|
302
|
+
if (!parsed.success) {
|
|
303
|
+
return failResult(
|
|
304
|
+
'github_pr_file_diff_get',
|
|
305
|
+
'Invalid PR file diff input.',
|
|
306
|
+
{
|
|
307
|
+
errors: [v.summarize(parsed.issues)],
|
|
308
|
+
},
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const resolved = await resolvePullRequestTarget(
|
|
313
|
+
{
|
|
314
|
+
watchId: parsed.output.watchId,
|
|
315
|
+
ref: parsed.output.ref,
|
|
316
|
+
repo: parsed.output.repo,
|
|
317
|
+
prNumber: parsed.output.prNumber,
|
|
318
|
+
},
|
|
319
|
+
paths,
|
|
320
|
+
'github_pr_file_diff_get',
|
|
321
|
+
);
|
|
322
|
+
if (!resolved.ok) return resolved.result;
|
|
323
|
+
|
|
324
|
+
const source = parsed.output.source ?? 'auto';
|
|
325
|
+
const localErrorMessages: string[] = [];
|
|
326
|
+
if (source !== 'github') {
|
|
327
|
+
try {
|
|
328
|
+
const diff = await readLocalPullRequestFileDiff(
|
|
329
|
+
{
|
|
330
|
+
owner: resolved.target.owner,
|
|
331
|
+
repo: resolved.target.repo,
|
|
332
|
+
number: resolved.target.number,
|
|
333
|
+
headSha: parsed.output.headSha ?? null,
|
|
334
|
+
baseSha: parsed.output.baseSha ?? null,
|
|
335
|
+
baseRef: parsed.output.baseRef ?? null,
|
|
336
|
+
path: parsed.output.path,
|
|
337
|
+
maxPatchBytes: parsed.output.maxPatchBytes,
|
|
338
|
+
},
|
|
339
|
+
paths,
|
|
340
|
+
);
|
|
341
|
+
return okResult(
|
|
342
|
+
'github_pr_file_diff_get',
|
|
343
|
+
false,
|
|
344
|
+
diff.file
|
|
345
|
+
? `Read local PR diff for ${parsed.output.path}.`
|
|
346
|
+
: `No local PR diff found for ${parsed.output.path}.`,
|
|
347
|
+
{
|
|
348
|
+
target: eventTargetJson(resolved.target),
|
|
349
|
+
file: diff.file as unknown as JsonValue,
|
|
350
|
+
diff: diff.diff,
|
|
351
|
+
diffSummary: diff.diffSummary as unknown as JsonValue,
|
|
352
|
+
fetchedAt: diff.fetchedAt,
|
|
353
|
+
source: 'local',
|
|
354
|
+
},
|
|
355
|
+
);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
localErrorMessages.push(errorMessage(error));
|
|
358
|
+
if (source === 'local') {
|
|
359
|
+
return failResult(
|
|
360
|
+
'github_pr_file_diff_get',
|
|
361
|
+
'Could not fetch local PR file diff.',
|
|
362
|
+
{ errors: localErrorMessages },
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
369
|
+
if (!token) {
|
|
370
|
+
return failResult(
|
|
371
|
+
'github_pr_file_diff_get',
|
|
372
|
+
'GITHUB_TOKEN is not configured.',
|
|
373
|
+
{
|
|
374
|
+
requires: ['GITHUB_TOKEN'],
|
|
375
|
+
errors: localErrorMessages.length ? localErrorMessages : undefined,
|
|
376
|
+
},
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
const diff = await fetchPullRequestFilesWithCache({
|
|
382
|
+
token,
|
|
383
|
+
owner: resolved.target.owner,
|
|
384
|
+
repo: resolved.target.repo,
|
|
385
|
+
number: resolved.target.number,
|
|
386
|
+
headSha: parsed.output.headSha ?? null,
|
|
387
|
+
patches: 'all',
|
|
388
|
+
databasePath: paths.neondeckDatabase,
|
|
389
|
+
fetcher: dependencies.fetchPullRequestFiles ?? fetchPullRequestFiles,
|
|
390
|
+
fetchHeadSha: dependencies.fetchPullRequestHeadSha,
|
|
391
|
+
});
|
|
392
|
+
const file =
|
|
393
|
+
diff.files.find((item) => item.path === parsed.output.path) ?? null;
|
|
394
|
+
return okResult(
|
|
395
|
+
'github_pr_file_diff_get',
|
|
396
|
+
false,
|
|
397
|
+
file
|
|
398
|
+
? `Read GitHub PR diff for ${parsed.output.path}.`
|
|
399
|
+
: `No GitHub PR diff found for ${parsed.output.path}.`,
|
|
400
|
+
{
|
|
401
|
+
target: eventTargetJson(resolved.target),
|
|
402
|
+
file: file as unknown as JsonValue,
|
|
403
|
+
diff: file?.patch ?? '',
|
|
404
|
+
diffSummary: diff.diffSummary as unknown as JsonValue,
|
|
405
|
+
fetchedAt: diff.fetchedAt,
|
|
406
|
+
source: 'github',
|
|
407
|
+
},
|
|
408
|
+
);
|
|
409
|
+
} catch (error) {
|
|
410
|
+
return failResult(
|
|
411
|
+
'github_pr_file_diff_get',
|
|
412
|
+
'Could not fetch GitHub PR file diff.',
|
|
413
|
+
{
|
|
414
|
+
errors: [errorMessage(error)],
|
|
415
|
+
},
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export async function getGitHubPrReviewDraft(
|
|
421
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
422
|
+
paths: RuntimePaths = runtimePaths(),
|
|
423
|
+
): Promise<PrEventActionResult> {
|
|
424
|
+
await ensureRuntimeHome(paths);
|
|
425
|
+
const parsed = v.safeParse(prEventTargetInputSchema, input);
|
|
426
|
+
if (!parsed.success) {
|
|
427
|
+
return failResult('github_pr_review_draft_get', 'Invalid PR draft input.', {
|
|
428
|
+
errors: [v.summarize(parsed.issues)],
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const resolved = await resolvePullRequestTarget(
|
|
433
|
+
parsed.output,
|
|
434
|
+
paths,
|
|
435
|
+
'github_pr_review_draft_get',
|
|
436
|
+
);
|
|
437
|
+
if (!resolved.ok) return resolved.result;
|
|
438
|
+
|
|
439
|
+
const draft = readLivePrReviewDraft({
|
|
440
|
+
databasePath: paths.neondeckDatabase,
|
|
441
|
+
repo: resolved.target.repoFullName,
|
|
442
|
+
prNumber: resolved.target.number,
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
return okResult(
|
|
446
|
+
'github_pr_review_draft_get',
|
|
447
|
+
false,
|
|
448
|
+
draft
|
|
449
|
+
? `Fetched review draft for ${resolved.target.repoFullName}#${resolved.target.number}.`
|
|
450
|
+
: `No review draft for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
451
|
+
{
|
|
452
|
+
target: eventTargetJson(resolved.target),
|
|
453
|
+
draft: draft as unknown as JsonValue,
|
|
454
|
+
},
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export async function putGitHubPrReviewDraft(
|
|
459
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
460
|
+
draftInput: v.InferInput<typeof prReviewDraftInputSchema>,
|
|
461
|
+
paths: RuntimePaths = runtimePaths(),
|
|
462
|
+
): Promise<PrEventActionResult> {
|
|
463
|
+
await ensureRuntimeHome(paths);
|
|
464
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
465
|
+
const parsedDraft = v.safeParse(prReviewDraftInputSchema, draftInput);
|
|
466
|
+
if (!parsedTarget.success || !parsedDraft.success) {
|
|
467
|
+
return failResult('github_pr_review_draft_put', 'Invalid PR draft input.', {
|
|
468
|
+
errors: [
|
|
469
|
+
...(!parsedTarget.success ? [v.summarize(parsedTarget.issues)] : []),
|
|
470
|
+
...(!parsedDraft.success ? [v.summarize(parsedDraft.issues)] : []),
|
|
471
|
+
],
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const resolved = await resolvePullRequestTarget(
|
|
476
|
+
parsedTarget.output,
|
|
477
|
+
paths,
|
|
478
|
+
'github_pr_review_draft_put',
|
|
479
|
+
);
|
|
480
|
+
if (!resolved.ok) return resolved.result;
|
|
481
|
+
|
|
482
|
+
const draftUpdate: Parameters<typeof upsertPrReviewDraft>[0] = {
|
|
483
|
+
databasePath: paths.neondeckDatabase,
|
|
484
|
+
repo: resolved.target.repoFullName,
|
|
485
|
+
prNumber: resolved.target.number,
|
|
486
|
+
headSha: parsedDraft.output.headSha,
|
|
487
|
+
};
|
|
488
|
+
if ('verdict' in parsedDraft.output) {
|
|
489
|
+
draftUpdate.verdict = parsedDraft.output.verdict ?? null;
|
|
490
|
+
}
|
|
491
|
+
if ('body' in parsedDraft.output) {
|
|
492
|
+
draftUpdate.body = parsedDraft.output.body ?? null;
|
|
493
|
+
}
|
|
494
|
+
if (parsedDraft.output.reanchorHeadSha) {
|
|
495
|
+
draftUpdate.reanchorHeadSha = true;
|
|
496
|
+
}
|
|
497
|
+
let draft: ReturnType<typeof upsertPrReviewDraft>;
|
|
498
|
+
try {
|
|
499
|
+
draft = upsertPrReviewDraft(draftUpdate);
|
|
500
|
+
} catch (error) {
|
|
501
|
+
return failResult(
|
|
502
|
+
'github_pr_review_draft_put',
|
|
503
|
+
'Could not save review draft.',
|
|
504
|
+
{ errors: [errorMessage(error)] },
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return okResult(
|
|
509
|
+
'github_pr_review_draft_put',
|
|
510
|
+
true,
|
|
511
|
+
`Saved review draft for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
512
|
+
{
|
|
513
|
+
target: eventTargetJson(resolved.target),
|
|
514
|
+
draft: draft as unknown as JsonValue,
|
|
515
|
+
},
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export async function postGitHubPrReviewDraftComment(
|
|
520
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
521
|
+
input: v.InferInput<typeof prReviewDraftCommentInputSchema>,
|
|
522
|
+
paths: RuntimePaths = runtimePaths(),
|
|
523
|
+
dependencies: PrEventStateDependencies = {},
|
|
524
|
+
): Promise<PrEventActionResult> {
|
|
525
|
+
await ensureRuntimeHome(paths);
|
|
526
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
527
|
+
const parsed = v.safeParse(prReviewDraftCommentInputSchema, input);
|
|
528
|
+
if (!parsedTarget.success || !parsed.success) {
|
|
529
|
+
return failResult(
|
|
530
|
+
'github_pr_review_draft_comment_post',
|
|
531
|
+
'Invalid PR draft comment input.',
|
|
532
|
+
{
|
|
533
|
+
errors: [
|
|
534
|
+
...(!parsedTarget.success ? [v.summarize(parsedTarget.issues)] : []),
|
|
535
|
+
...(!parsed.success ? [v.summarize(parsed.issues)] : []),
|
|
536
|
+
],
|
|
537
|
+
},
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const resolved = await resolvePullRequestTarget(
|
|
542
|
+
parsedTarget.output,
|
|
543
|
+
paths,
|
|
544
|
+
'github_pr_review_draft_comment_post',
|
|
545
|
+
);
|
|
546
|
+
if (!resolved.ok) return resolved.result;
|
|
547
|
+
|
|
548
|
+
const draft = readPrReviewDraft({
|
|
549
|
+
databasePath: paths.neondeckDatabase,
|
|
550
|
+
draftId: parsed.output.draftId,
|
|
551
|
+
});
|
|
552
|
+
if (!draft || !draftMatchesTarget(draft, resolved.target)) {
|
|
553
|
+
return failResult(
|
|
554
|
+
'github_pr_review_draft_comment_post',
|
|
555
|
+
'Review draft does not belong to this pull request.',
|
|
556
|
+
{ requires: ['draftId'] },
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const invalidAnchor = await validateDraftCommentAnchor(
|
|
561
|
+
'github_pr_review_draft_comment_post',
|
|
562
|
+
resolved.target,
|
|
563
|
+
draft,
|
|
564
|
+
{
|
|
565
|
+
path: parsed.output.path,
|
|
566
|
+
side: parsed.output.side,
|
|
567
|
+
line: parsed.output.line,
|
|
568
|
+
startLine: parsed.output.startLine ?? null,
|
|
569
|
+
startSide: parsed.output.startSide ?? null,
|
|
570
|
+
},
|
|
571
|
+
paths,
|
|
572
|
+
dependencies,
|
|
573
|
+
);
|
|
574
|
+
if (invalidAnchor) return invalidAnchor;
|
|
575
|
+
|
|
576
|
+
try {
|
|
577
|
+
const draft = addPrReviewDraftComment({
|
|
578
|
+
databasePath: paths.neondeckDatabase,
|
|
579
|
+
draftId: parsed.output.draftId,
|
|
580
|
+
path: parsed.output.path,
|
|
581
|
+
side: parsed.output.side,
|
|
582
|
+
line: parsed.output.line,
|
|
583
|
+
startLine: parsed.output.startLine ?? null,
|
|
584
|
+
startSide: parsed.output.startSide ?? null,
|
|
585
|
+
body: parsed.output.body,
|
|
586
|
+
});
|
|
587
|
+
return okResult(
|
|
588
|
+
'github_pr_review_draft_comment_post',
|
|
589
|
+
true,
|
|
590
|
+
'Saved PR review draft comment.',
|
|
591
|
+
{ draft: draft as unknown as JsonValue },
|
|
592
|
+
);
|
|
593
|
+
} catch (error) {
|
|
594
|
+
return failResult(
|
|
595
|
+
'github_pr_review_draft_comment_post',
|
|
596
|
+
'Could not save PR review draft comment.',
|
|
597
|
+
{ errors: [errorMessage(error)] },
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export async function patchGitHubPrReviewDraftComment(
|
|
603
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
604
|
+
commentId: string,
|
|
605
|
+
input: v.InferInput<typeof prReviewDraftCommentUpdateInputSchema>,
|
|
606
|
+
paths: RuntimePaths = runtimePaths(),
|
|
607
|
+
dependencies: PrEventStateDependencies = {},
|
|
608
|
+
): Promise<PrEventActionResult> {
|
|
609
|
+
await ensureRuntimeHome(paths);
|
|
610
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
611
|
+
const parsed = v.safeParse(prReviewDraftCommentUpdateInputSchema, input);
|
|
612
|
+
if (!commentId || !parsedTarget.success || !parsed.success) {
|
|
613
|
+
return failResult(
|
|
614
|
+
'github_pr_review_draft_comment_patch',
|
|
615
|
+
'Invalid PR draft comment update input.',
|
|
616
|
+
{
|
|
617
|
+
errors: [
|
|
618
|
+
...(!parsedTarget.success ? [v.summarize(parsedTarget.issues)] : []),
|
|
619
|
+
...(!parsed.success ? [v.summarize(parsed.issues)] : []),
|
|
620
|
+
],
|
|
621
|
+
requires: !commentId ? ['commentId'] : undefined,
|
|
622
|
+
},
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const resolved = await resolvePullRequestTarget(
|
|
627
|
+
parsedTarget.output,
|
|
628
|
+
paths,
|
|
629
|
+
'github_pr_review_draft_comment_patch',
|
|
630
|
+
);
|
|
631
|
+
if (!resolved.ok) return resolved.result;
|
|
632
|
+
|
|
633
|
+
const draft = readPrReviewDraftForComment({
|
|
634
|
+
databasePath: paths.neondeckDatabase,
|
|
635
|
+
commentId,
|
|
636
|
+
});
|
|
637
|
+
if (!draft || !draftMatchesTarget(draft, resolved.target)) {
|
|
638
|
+
return failResult(
|
|
639
|
+
'github_pr_review_draft_comment_patch',
|
|
640
|
+
'Review draft comment does not belong to this pull request.',
|
|
641
|
+
{ requires: ['commentId'] },
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const existing = draft.comments.find((comment) => comment.id === commentId);
|
|
646
|
+
if (!existing) {
|
|
647
|
+
return failResult(
|
|
648
|
+
'github_pr_review_draft_comment_patch',
|
|
649
|
+
'Review draft comment was not found.',
|
|
650
|
+
{ requires: ['commentId'] },
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
const nextAnchor = {
|
|
654
|
+
path: parsed.output.path ?? existing.path,
|
|
655
|
+
side: parsed.output.side ?? existing.side,
|
|
656
|
+
line: parsed.output.line ?? existing.line,
|
|
657
|
+
startLine:
|
|
658
|
+
'startLine' in parsed.output
|
|
659
|
+
? (parsed.output.startLine ?? null)
|
|
660
|
+
: existing.startLine,
|
|
661
|
+
startSide:
|
|
662
|
+
'startSide' in parsed.output
|
|
663
|
+
? (parsed.output.startSide ?? null)
|
|
664
|
+
: existing.startSide,
|
|
665
|
+
};
|
|
666
|
+
const invalidAnchor = await validateDraftCommentAnchor(
|
|
667
|
+
'github_pr_review_draft_comment_patch',
|
|
668
|
+
resolved.target,
|
|
669
|
+
draft,
|
|
670
|
+
nextAnchor,
|
|
671
|
+
paths,
|
|
672
|
+
dependencies,
|
|
673
|
+
);
|
|
674
|
+
if (invalidAnchor) return invalidAnchor;
|
|
675
|
+
|
|
676
|
+
try {
|
|
677
|
+
const draft = updatePrReviewDraftComment({
|
|
678
|
+
databasePath: paths.neondeckDatabase,
|
|
679
|
+
commentId,
|
|
680
|
+
body: parsed.output.body,
|
|
681
|
+
...('path' in parsed.output ? { path: parsed.output.path } : {}),
|
|
682
|
+
...('side' in parsed.output ? { side: parsed.output.side } : {}),
|
|
683
|
+
...('line' in parsed.output ? { line: parsed.output.line } : {}),
|
|
684
|
+
...('startLine' in parsed.output
|
|
685
|
+
? { startLine: parsed.output.startLine ?? null }
|
|
686
|
+
: {}),
|
|
687
|
+
...('startSide' in parsed.output
|
|
688
|
+
? { startSide: parsed.output.startSide ?? null }
|
|
689
|
+
: {}),
|
|
690
|
+
});
|
|
691
|
+
return okResult(
|
|
692
|
+
'github_pr_review_draft_comment_patch',
|
|
693
|
+
true,
|
|
694
|
+
'Updated PR review draft comment.',
|
|
695
|
+
{ draft: draft as unknown as JsonValue },
|
|
696
|
+
);
|
|
697
|
+
} catch (error) {
|
|
698
|
+
return failResult(
|
|
699
|
+
'github_pr_review_draft_comment_patch',
|
|
700
|
+
'Could not update PR review draft comment.',
|
|
701
|
+
{ errors: [errorMessage(error)] },
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export async function deleteGitHubPrReviewDraftComment(
|
|
707
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
708
|
+
commentId: string,
|
|
709
|
+
paths: RuntimePaths = runtimePaths(),
|
|
710
|
+
): Promise<PrEventActionResult> {
|
|
711
|
+
await ensureRuntimeHome(paths);
|
|
712
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
713
|
+
if (!commentId || !parsedTarget.success) {
|
|
714
|
+
return failResult(
|
|
715
|
+
'github_pr_review_draft_comment_delete',
|
|
716
|
+
'Invalid PR draft comment delete input.',
|
|
717
|
+
{
|
|
718
|
+
errors: parsedTarget.success
|
|
719
|
+
? undefined
|
|
720
|
+
: [v.summarize(parsedTarget.issues)],
|
|
721
|
+
requires: !commentId ? ['commentId'] : undefined,
|
|
722
|
+
},
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
const resolved = await resolvePullRequestTarget(
|
|
727
|
+
parsedTarget.output,
|
|
728
|
+
paths,
|
|
729
|
+
'github_pr_review_draft_comment_delete',
|
|
730
|
+
);
|
|
731
|
+
if (!resolved.ok) return resolved.result;
|
|
732
|
+
|
|
733
|
+
const draft = readPrReviewDraftForComment({
|
|
734
|
+
databasePath: paths.neondeckDatabase,
|
|
735
|
+
commentId,
|
|
736
|
+
});
|
|
737
|
+
if (!draftMatchesTarget(draft, resolved.target)) {
|
|
738
|
+
return failResult(
|
|
739
|
+
'github_pr_review_draft_comment_delete',
|
|
740
|
+
'Review draft comment does not belong to this pull request.',
|
|
741
|
+
{ requires: ['commentId'] },
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
try {
|
|
746
|
+
const draft = deletePrReviewDraftComment({
|
|
747
|
+
databasePath: paths.neondeckDatabase,
|
|
748
|
+
commentId,
|
|
749
|
+
});
|
|
750
|
+
return okResult(
|
|
751
|
+
'github_pr_review_draft_comment_delete',
|
|
752
|
+
true,
|
|
753
|
+
'Deleted PR review draft comment.',
|
|
754
|
+
{ draft: draft as unknown as JsonValue },
|
|
755
|
+
);
|
|
756
|
+
} catch (error) {
|
|
757
|
+
return failResult(
|
|
758
|
+
'github_pr_review_draft_comment_delete',
|
|
759
|
+
'Could not delete PR review draft comment.',
|
|
760
|
+
{ errors: [errorMessage(error)] },
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
export async function deleteGitHubPrReviewDraft(
|
|
766
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
767
|
+
paths: RuntimePaths = runtimePaths(),
|
|
768
|
+
): Promise<PrEventActionResult> {
|
|
769
|
+
await ensureRuntimeHome(paths);
|
|
770
|
+
const parsed = v.safeParse(prEventTargetInputSchema, input);
|
|
771
|
+
if (!parsed.success) {
|
|
772
|
+
return failResult(
|
|
773
|
+
'github_pr_review_draft_delete',
|
|
774
|
+
'Invalid PR draft delete input.',
|
|
775
|
+
{ errors: [v.summarize(parsed.issues)] },
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const resolved = await resolvePullRequestTarget(
|
|
780
|
+
parsed.output,
|
|
781
|
+
paths,
|
|
782
|
+
'github_pr_review_draft_delete',
|
|
783
|
+
);
|
|
784
|
+
if (!resolved.ok) return resolved.result;
|
|
785
|
+
|
|
786
|
+
const draft = discardPrReviewDraft({
|
|
787
|
+
databasePath: paths.neondeckDatabase,
|
|
788
|
+
repo: resolved.target.repoFullName,
|
|
789
|
+
prNumber: resolved.target.number,
|
|
790
|
+
});
|
|
791
|
+
return okResult(
|
|
792
|
+
'github_pr_review_draft_delete',
|
|
793
|
+
draft !== null,
|
|
794
|
+
draft
|
|
795
|
+
? `Discarded review draft for ${resolved.target.repoFullName}#${resolved.target.number}.`
|
|
796
|
+
: `No review draft for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
797
|
+
{
|
|
798
|
+
target: eventTargetJson(resolved.target),
|
|
799
|
+
draft: draft as unknown as JsonValue,
|
|
800
|
+
},
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export async function postGitHubPrReview(
|
|
805
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
806
|
+
reviewInput: v.InferInput<typeof prReviewSubmitInputSchema>,
|
|
807
|
+
paths: RuntimePaths = runtimePaths(),
|
|
808
|
+
dependencies: PrEventStateDependencies = {},
|
|
809
|
+
): Promise<PrEventActionResult> {
|
|
810
|
+
await ensureRuntimeHome(paths);
|
|
811
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
812
|
+
const parsedReview = v.safeParse(prReviewSubmitInputSchema, reviewInput);
|
|
813
|
+
if (!parsedTarget.success || !parsedReview.success) {
|
|
814
|
+
return failResult('github_pr_review_post', 'Invalid PR review input.', {
|
|
815
|
+
errors: [
|
|
816
|
+
...(!parsedTarget.success ? [v.summarize(parsedTarget.issues)] : []),
|
|
817
|
+
...(!parsedReview.success ? [v.summarize(parsedReview.issues)] : []),
|
|
818
|
+
],
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
823
|
+
if (!token) {
|
|
824
|
+
return failResult(
|
|
825
|
+
'github_pr_review_post',
|
|
826
|
+
'GITHUB_TOKEN is not configured.',
|
|
827
|
+
{
|
|
828
|
+
requires: ['GITHUB_TOKEN'],
|
|
829
|
+
},
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
const resolved = await resolvePullRequestTarget(
|
|
834
|
+
parsedTarget.output,
|
|
835
|
+
paths,
|
|
836
|
+
'github_pr_review_post',
|
|
837
|
+
);
|
|
838
|
+
if (!resolved.ok) return resolved.result;
|
|
839
|
+
if (!(await isConfiguredRepoTarget(resolved.target, paths))) {
|
|
840
|
+
return failResult(
|
|
841
|
+
'github_pr_review_post',
|
|
842
|
+
`Repository "${resolved.target.repoFullName}" is not configured for PR reviews.`,
|
|
843
|
+
{ requires: ['repo'] },
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
try {
|
|
848
|
+
const submitter =
|
|
849
|
+
dependencies.submitPullRequestReview ?? submitPullRequestReview;
|
|
850
|
+
const result = await submitter({
|
|
851
|
+
token,
|
|
852
|
+
owner: resolved.target.owner,
|
|
853
|
+
repo: resolved.target.repo,
|
|
854
|
+
number: resolved.target.number,
|
|
855
|
+
databasePath: paths.neondeckDatabase,
|
|
856
|
+
paths,
|
|
857
|
+
draftId: parsedReview.output.draftId,
|
|
858
|
+
headSha: parsedReview.output.headSha,
|
|
859
|
+
commentIds: parsedReview.output.commentIds,
|
|
860
|
+
fetchHeadSha: dependencies.fetchPullRequestHeadSha,
|
|
861
|
+
});
|
|
862
|
+
return okResult(
|
|
863
|
+
'github_pr_review_post',
|
|
864
|
+
true,
|
|
865
|
+
`Submitted PR review for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
866
|
+
{
|
|
867
|
+
target: eventTargetJson(resolved.target),
|
|
868
|
+
draft: result.draft as unknown as JsonValue,
|
|
869
|
+
review: result.review as unknown as JsonValue,
|
|
870
|
+
},
|
|
871
|
+
);
|
|
872
|
+
} catch (error) {
|
|
873
|
+
if (error instanceof GitHubPrReviewSubmitError) {
|
|
874
|
+
return {
|
|
875
|
+
ok: false,
|
|
876
|
+
action: 'github_pr_review_post',
|
|
877
|
+
changed: false,
|
|
878
|
+
message: error.failure.message,
|
|
879
|
+
data: {
|
|
880
|
+
code: error.failure.code,
|
|
881
|
+
failingCommentIds: error.failure.failingCommentIds ?? [],
|
|
882
|
+
},
|
|
883
|
+
...(error.failure.requires ? { requires: error.failure.requires } : {}),
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
return failResult('github_pr_review_post', 'Could not submit PR review.', {
|
|
887
|
+
errors: [errorMessage(error)],
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
function draftMatchesTarget(
|
|
893
|
+
draft: {
|
|
894
|
+
repo: string;
|
|
895
|
+
prNumber: number;
|
|
896
|
+
} | null,
|
|
897
|
+
target: PullRequestTarget,
|
|
898
|
+
) {
|
|
899
|
+
return (
|
|
900
|
+
draft?.repo === target.repoFullName && draft.prNumber === target.number
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
async function validateDraftCommentAnchor(
|
|
905
|
+
action: string,
|
|
906
|
+
target: PullRequestTarget,
|
|
907
|
+
draft: GitHubPrReviewDraft,
|
|
908
|
+
anchor: {
|
|
909
|
+
path: string;
|
|
910
|
+
side: GitHubPrReviewDraftComment['side'];
|
|
911
|
+
line: number;
|
|
912
|
+
startLine: number | null;
|
|
913
|
+
startSide: GitHubPrReviewDraftComment['startSide'];
|
|
914
|
+
},
|
|
915
|
+
paths: RuntimePaths,
|
|
916
|
+
dependencies: PrEventStateDependencies,
|
|
917
|
+
): Promise<PrEventActionResult | null> {
|
|
918
|
+
try {
|
|
919
|
+
const cached = readCachedPullRequestFiles({
|
|
920
|
+
databasePath: paths.neondeckDatabase,
|
|
921
|
+
repo: target.repoFullName,
|
|
922
|
+
number: target.number,
|
|
923
|
+
headSha: draft.headSha,
|
|
924
|
+
});
|
|
925
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
926
|
+
if (!cached && !token) {
|
|
927
|
+
return failResult(
|
|
928
|
+
action,
|
|
929
|
+
'GITHUB_TOKEN is required to validate anchors.',
|
|
930
|
+
{
|
|
931
|
+
requires: ['GITHUB_TOKEN'],
|
|
932
|
+
},
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
const diff =
|
|
937
|
+
cached ??
|
|
938
|
+
(await fetchPullRequestFilesWithCache({
|
|
939
|
+
token: token!,
|
|
940
|
+
owner: target.owner,
|
|
941
|
+
repo: target.repo,
|
|
942
|
+
number: target.number,
|
|
943
|
+
headSha: draft.headSha,
|
|
944
|
+
databasePath: paths.neondeckDatabase,
|
|
945
|
+
fetcher: dependencies.fetchPullRequestFiles ?? fetchPullRequestFiles,
|
|
946
|
+
fetchHeadSha: dependencies.fetchPullRequestHeadSha,
|
|
947
|
+
}));
|
|
948
|
+
const file = diff.files.find((item) => item.path === anchor.path);
|
|
949
|
+
if (
|
|
950
|
+
!file ||
|
|
951
|
+
!commentAnchorExists(buildPatchAnchorIndex(file.patch), {
|
|
952
|
+
side: anchor.side,
|
|
953
|
+
line: anchor.line,
|
|
954
|
+
startLine: anchor.startLine,
|
|
955
|
+
startSide: anchor.startSide,
|
|
956
|
+
})
|
|
957
|
+
) {
|
|
958
|
+
return failResult(
|
|
959
|
+
action,
|
|
960
|
+
'Review draft comment anchor is not present in the PR patch.',
|
|
961
|
+
{ requires: ['validAnchor'] },
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
return null;
|
|
965
|
+
} catch (error) {
|
|
966
|
+
return failResult(action, 'Could not validate PR review draft anchor.', {
|
|
967
|
+
errors: [errorMessage(error)],
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
export async function postGitHubPrThreadReply(
|
|
973
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
974
|
+
threadId: string,
|
|
975
|
+
input: v.InferInput<typeof prReviewThreadReplyInputSchema>,
|
|
976
|
+
paths: RuntimePaths = runtimePaths(),
|
|
977
|
+
dependencies: PrEventStateDependencies = {},
|
|
978
|
+
): Promise<PrEventActionResult> {
|
|
979
|
+
await ensureRuntimeHome(paths);
|
|
980
|
+
const action = 'github_pr_thread_reply_post';
|
|
981
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
982
|
+
const parsed = v.safeParse(prReviewThreadReplyInputSchema, input);
|
|
983
|
+
if (!threadId || !parsedTarget.success || !parsed.success) {
|
|
984
|
+
return failResult(action, 'Invalid review thread reply input.', {
|
|
985
|
+
errors: [
|
|
986
|
+
...(!parsedTarget.success ? [v.summarize(parsedTarget.issues)] : []),
|
|
987
|
+
...(!parsed.success ? [v.summarize(parsed.issues)] : []),
|
|
988
|
+
],
|
|
989
|
+
requires: !threadId ? ['threadId'] : undefined,
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
994
|
+
if (!token) {
|
|
995
|
+
return failResult(action, 'GITHUB_TOKEN is not configured.', {
|
|
996
|
+
requires: ['GITHUB_TOKEN'],
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
const resolved = await resolvePullRequestTarget(
|
|
1001
|
+
parsedTarget.output,
|
|
1002
|
+
paths,
|
|
1003
|
+
action,
|
|
1004
|
+
);
|
|
1005
|
+
if (!resolved.ok) return resolved.result;
|
|
1006
|
+
if (!(await isConfiguredRepoTarget(resolved.target, paths))) {
|
|
1007
|
+
return failResult(
|
|
1008
|
+
action,
|
|
1009
|
+
`Repository "${resolved.target.repoFullName}" is not configured for review thread replies.`,
|
|
1010
|
+
{ requires: ['repo'] },
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
const verified = await verifyReviewThreadTarget({
|
|
1015
|
+
action,
|
|
1016
|
+
token,
|
|
1017
|
+
threadId,
|
|
1018
|
+
target: resolved.target,
|
|
1019
|
+
dependencies,
|
|
1020
|
+
});
|
|
1021
|
+
if (!verified.ok) return verified.result;
|
|
1022
|
+
|
|
1023
|
+
try {
|
|
1024
|
+
const replier =
|
|
1025
|
+
dependencies.replyToPullRequestReviewThread ??
|
|
1026
|
+
replyToPullRequestReviewThread;
|
|
1027
|
+
const thread = await replier({
|
|
1028
|
+
token,
|
|
1029
|
+
threadId,
|
|
1030
|
+
body: parsed.output.text,
|
|
1031
|
+
});
|
|
1032
|
+
return okResult(action, true, 'Posted review thread reply.', {
|
|
1033
|
+
thread: thread as unknown as JsonValue,
|
|
1034
|
+
});
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
return failResult(action, 'Could not post review thread reply.', {
|
|
1037
|
+
errors: [errorMessage(error)],
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
export async function postGitHubPrThreadResolution(
|
|
1043
|
+
targetInput: v.InferInput<typeof prEventTargetInputSchema>,
|
|
1044
|
+
threadId: string,
|
|
1045
|
+
resolved: boolean,
|
|
1046
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1047
|
+
dependencies: PrEventStateDependencies = {},
|
|
1048
|
+
): Promise<PrEventActionResult> {
|
|
1049
|
+
await ensureRuntimeHome(paths);
|
|
1050
|
+
const action = resolved
|
|
1051
|
+
? 'github_pr_thread_resolve_post'
|
|
1052
|
+
: 'github_pr_thread_unresolve_post';
|
|
1053
|
+
const parsedTarget = v.safeParse(prEventTargetInputSchema, targetInput);
|
|
1054
|
+
if (!threadId || !parsedTarget.success) {
|
|
1055
|
+
return failResult(
|
|
1056
|
+
action,
|
|
1057
|
+
!threadId
|
|
1058
|
+
? 'Review thread id is required.'
|
|
1059
|
+
: 'Invalid review thread target input.',
|
|
1060
|
+
{
|
|
1061
|
+
errors: parsedTarget.success
|
|
1062
|
+
? undefined
|
|
1063
|
+
: [v.summarize(parsedTarget.issues)],
|
|
1064
|
+
requires: !threadId ? ['threadId'] : undefined,
|
|
1065
|
+
},
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
1070
|
+
if (!token) {
|
|
1071
|
+
return failResult(action, 'GITHUB_TOKEN is not configured.', {
|
|
1072
|
+
requires: ['GITHUB_TOKEN'],
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
const target = await resolvePullRequestTarget(
|
|
1077
|
+
parsedTarget.output,
|
|
1078
|
+
paths,
|
|
1079
|
+
action,
|
|
1080
|
+
);
|
|
1081
|
+
if (!target.ok) return target.result;
|
|
1082
|
+
if (!(await isConfiguredRepoTarget(target.target, paths))) {
|
|
1083
|
+
return failResult(
|
|
1084
|
+
action,
|
|
1085
|
+
`Repository "${target.target.repoFullName}" is not configured for review thread resolution.`,
|
|
1086
|
+
{ requires: ['repo'] },
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
const verified = await verifyReviewThreadTarget({
|
|
1091
|
+
action,
|
|
1092
|
+
token,
|
|
1093
|
+
threadId,
|
|
1094
|
+
target: target.target,
|
|
1095
|
+
dependencies,
|
|
1096
|
+
});
|
|
1097
|
+
if (!verified.ok) return verified.result;
|
|
1098
|
+
|
|
1099
|
+
try {
|
|
1100
|
+
const mutator = resolved
|
|
1101
|
+
? (dependencies.resolvePullRequestReviewThread ??
|
|
1102
|
+
resolvePullRequestReviewThread)
|
|
1103
|
+
: (dependencies.unresolvePullRequestReviewThread ??
|
|
1104
|
+
unresolvePullRequestReviewThread);
|
|
1105
|
+
const thread = await mutator({ token, threadId });
|
|
1106
|
+
return okResult(
|
|
1107
|
+
action,
|
|
1108
|
+
true,
|
|
1109
|
+
resolved ? 'Resolved review thread.' : 'Unresolved review thread.',
|
|
1110
|
+
{ thread: thread as unknown as JsonValue },
|
|
1111
|
+
);
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
return failResult(
|
|
1114
|
+
action,
|
|
1115
|
+
resolved
|
|
1116
|
+
? 'Could not resolve review thread.'
|
|
1117
|
+
: 'Could not unresolve review thread.',
|
|
1118
|
+
{ errors: [errorMessage(error)] },
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
async function verifyReviewThreadTarget(options: {
|
|
1124
|
+
action: string;
|
|
1125
|
+
token: string;
|
|
1126
|
+
threadId: string;
|
|
1127
|
+
target: PullRequestTarget;
|
|
1128
|
+
dependencies: PrEventStateDependencies;
|
|
1129
|
+
}): Promise<
|
|
1130
|
+
| { ok: true; thread: GitHubPullRequestReviewThread }
|
|
1131
|
+
| { ok: false; result: PrEventActionResult }
|
|
1132
|
+
> {
|
|
1133
|
+
try {
|
|
1134
|
+
const fetcher =
|
|
1135
|
+
options.dependencies.fetchPullRequestReviewThread ??
|
|
1136
|
+
fetchPullRequestReviewThread;
|
|
1137
|
+
const thread = await fetcher({
|
|
1138
|
+
token: options.token,
|
|
1139
|
+
threadId: options.threadId,
|
|
1140
|
+
});
|
|
1141
|
+
if (!reviewThreadBelongsToTarget(thread, options.target)) {
|
|
1142
|
+
return {
|
|
1143
|
+
ok: false,
|
|
1144
|
+
result: failResult(
|
|
1145
|
+
options.action,
|
|
1146
|
+
'Review thread does not belong to this pull request.',
|
|
1147
|
+
{ requires: ['threadId'] },
|
|
1148
|
+
),
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
return { ok: true, thread };
|
|
1152
|
+
} catch (error) {
|
|
1153
|
+
return {
|
|
1154
|
+
ok: false,
|
|
1155
|
+
result: failResult(
|
|
1156
|
+
options.action,
|
|
1157
|
+
'Could not verify review thread target.',
|
|
1158
|
+
{ errors: [errorMessage(error)] },
|
|
1159
|
+
),
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
function reviewThreadBelongsToTarget(
|
|
1165
|
+
thread: GitHubPullRequestReviewThread,
|
|
1166
|
+
target: PullRequestTarget,
|
|
1167
|
+
) {
|
|
1168
|
+
return (
|
|
1169
|
+
thread.pullRequestRepo?.toLowerCase() ===
|
|
1170
|
+
target.repoFullName.toLowerCase() &&
|
|
1171
|
+
thread.pullRequestNumber === target.number
|
|
1172
|
+
);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
export async function getGitHubPrRequestedChanges(
|
|
1176
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
1177
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1178
|
+
dependencies: PrEventStateDependencies = {},
|
|
1179
|
+
): Promise<PrEventActionResult> {
|
|
1180
|
+
const resolved = await fetchEventState(
|
|
1181
|
+
'github_pr_requested_changes_get',
|
|
1182
|
+
input,
|
|
1183
|
+
paths,
|
|
1184
|
+
dependencies,
|
|
1185
|
+
);
|
|
1186
|
+
if (!resolved.ok) return resolved.result;
|
|
1187
|
+
|
|
1188
|
+
return okResult(
|
|
1189
|
+
'github_pr_requested_changes_get',
|
|
1190
|
+
false,
|
|
1191
|
+
`Fetched ${resolved.state.requestedChangesReviews.length} requested-changes review(s) for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
1192
|
+
{
|
|
1193
|
+
target: eventTargetJson(resolved.target),
|
|
1194
|
+
requestedChangesReviews: resolved.state
|
|
1195
|
+
.requestedChangesReviews as unknown as JsonValue,
|
|
1196
|
+
requestedChangesState: resolved.state
|
|
1197
|
+
.requestedChangesState as unknown as JsonValue,
|
|
1198
|
+
},
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
export async function getGitHubPrBranchPermissions(
|
|
1203
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
1204
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1205
|
+
dependencies: PrEventStateDependencies = {},
|
|
1206
|
+
): Promise<PrEventActionResult> {
|
|
1207
|
+
const resolved = await fetchEventState(
|
|
1208
|
+
'github_pr_branch_permissions_get',
|
|
1209
|
+
input,
|
|
1210
|
+
paths,
|
|
1211
|
+
dependencies,
|
|
1212
|
+
);
|
|
1213
|
+
if (!resolved.ok) return resolved.result;
|
|
1214
|
+
|
|
1215
|
+
return okResult(
|
|
1216
|
+
'github_pr_branch_permissions_get',
|
|
1217
|
+
false,
|
|
1218
|
+
`Fetched branch permission facts for ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
1219
|
+
{
|
|
1220
|
+
target: eventTargetJson(resolved.target),
|
|
1221
|
+
branchPermissions: resolved.state
|
|
1222
|
+
.branchPermissions as unknown as JsonValue,
|
|
1223
|
+
},
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
export async function postGitHubPrComment(
|
|
1228
|
+
input: v.InferInput<typeof prCommentInputSchema>,
|
|
1229
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1230
|
+
dependencies: PrEventStateDependencies = {},
|
|
1231
|
+
): Promise<PrEventActionResult> {
|
|
1232
|
+
await ensureRuntimeHome(paths);
|
|
1233
|
+
const parsed = v.safeParse(prCommentInputSchema, input);
|
|
1234
|
+
if (!parsed.success) {
|
|
1235
|
+
return failResult('pr_comment', 'Invalid PR comment input.', {
|
|
1236
|
+
errors: [v.summarize(parsed.issues)],
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
const token = dependencies.token ?? process.env.GITHUB_TOKEN;
|
|
1241
|
+
if (!token) {
|
|
1242
|
+
return failResult('pr_comment', 'GITHUB_TOKEN is not configured.', {
|
|
1243
|
+
requires: ['GITHUB_TOKEN'],
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
const resolved = await resolvePullRequestTarget(
|
|
1248
|
+
parsed.output,
|
|
1249
|
+
paths,
|
|
1250
|
+
'pr_comment',
|
|
1251
|
+
);
|
|
1252
|
+
if (!resolved.ok) return resolved.result;
|
|
1253
|
+
if (!(await isConfiguredRepoTarget(resolved.target, paths))) {
|
|
1254
|
+
return failResult(
|
|
1255
|
+
'pr_comment',
|
|
1256
|
+
`Repository "${resolved.target.repoFullName}" is not configured for PR comments.`,
|
|
1257
|
+
{ requires: ['repo'] },
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
try {
|
|
1262
|
+
const fetcher =
|
|
1263
|
+
dependencies.fetchPullRequestEventState ?? fetchPullRequestEventState;
|
|
1264
|
+
const eventState = await fetcher({
|
|
1265
|
+
token,
|
|
1266
|
+
owner: resolved.target.owner,
|
|
1267
|
+
repo: resolved.target.repo,
|
|
1268
|
+
number: resolved.target.number,
|
|
1269
|
+
});
|
|
1270
|
+
const truncation = pullRequestEventStateTruncation(eventState);
|
|
1271
|
+
if (truncation.any) {
|
|
1272
|
+
return failResult(
|
|
1273
|
+
'pr_comment',
|
|
1274
|
+
'PR event facts are incomplete; refusing to post a PR comment from truncated GitHub data.',
|
|
1275
|
+
{
|
|
1276
|
+
requires: ['completePrEventFacts'],
|
|
1277
|
+
errors: [
|
|
1278
|
+
`Truncated PR event fact categories: ${truncation.categories.join(', ')}.`,
|
|
1279
|
+
],
|
|
1280
|
+
},
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
const poster =
|
|
1285
|
+
dependencies.postPullRequestComment ?? postPullRequestComment;
|
|
1286
|
+
const comment = await poster({
|
|
1287
|
+
token,
|
|
1288
|
+
owner: resolved.target.owner,
|
|
1289
|
+
repo: resolved.target.repo,
|
|
1290
|
+
number: resolved.target.number,
|
|
1291
|
+
body: parsed.output.body,
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
return okResult(
|
|
1295
|
+
'pr_comment',
|
|
1296
|
+
true,
|
|
1297
|
+
`Posted PR comment on ${resolved.target.repoFullName}#${resolved.target.number}.`,
|
|
1298
|
+
{
|
|
1299
|
+
target: eventTargetJson(resolved.target),
|
|
1300
|
+
comment: comment as unknown as JsonValue,
|
|
1301
|
+
metadata: {
|
|
1302
|
+
addressedReviewThreadIds:
|
|
1303
|
+
parsed.output.addressedReviewThreadIds ?? [],
|
|
1304
|
+
addressedReviewCommentIds:
|
|
1305
|
+
parsed.output.addressedReviewCommentIds ?? [],
|
|
1306
|
+
checkRunIds: parsed.output.checkRunIds ?? [],
|
|
1307
|
+
commitSha: parsed.output.commitSha ?? null,
|
|
1308
|
+
},
|
|
1309
|
+
},
|
|
1310
|
+
);
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
return failResult('pr_comment', 'Could not post GitHub PR comment.', {
|
|
1313
|
+
errors: [errorMessage(error)],
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
export async function refreshPrWatchEventState(
|
|
1319
|
+
input: v.InferInput<typeof prEventTargetInputSchema>,
|
|
1320
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1321
|
+
dependencies: PrEventStateDependencies = {},
|
|
1322
|
+
): Promise<PrEventActionResult> {
|
|
1323
|
+
const resolved = await fetchEventState(
|
|
1324
|
+
'pr_watch_event_state_refresh',
|
|
1325
|
+
input,
|
|
1326
|
+
paths,
|
|
1327
|
+
dependencies,
|
|
1328
|
+
);
|
|
1329
|
+
if (!resolved.ok) return resolved.result;
|
|
1330
|
+
if (!resolved.target.watch) {
|
|
1331
|
+
return failResult(
|
|
1332
|
+
'pr_watch_event_state_refresh',
|
|
1333
|
+
'Refreshing event watermarks requires a configured PR watch.',
|
|
1334
|
+
{ requires: ['watchId'] },
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
const previous = readWatermarks(paths, resolved.target.watch.id);
|
|
1339
|
+
const next = watermarksFromEventState(
|
|
1340
|
+
resolved.target.watch.id,
|
|
1341
|
+
resolved.state,
|
|
1342
|
+
);
|
|
1343
|
+
const changedCategories = next
|
|
1344
|
+
.filter((item) => {
|
|
1345
|
+
const existing = previous.find(
|
|
1346
|
+
(record) => record.category === item.category,
|
|
1347
|
+
);
|
|
1348
|
+
return (
|
|
1349
|
+
stableJson(comparableWatermark(item.category, existing?.watermark)) !==
|
|
1350
|
+
stableJson(comparableWatermark(item.category, item.value))
|
|
1351
|
+
);
|
|
1352
|
+
})
|
|
1353
|
+
.map((item) => item.category);
|
|
1354
|
+
|
|
1355
|
+
upsertWatermarks(paths, resolved.target.watch.id, next);
|
|
1356
|
+
|
|
1357
|
+
return okResult(
|
|
1358
|
+
'pr_watch_event_state_refresh',
|
|
1359
|
+
changedCategories.length > 0,
|
|
1360
|
+
changedCategories.length > 0
|
|
1361
|
+
? `Updated ${changedCategories.length} PR event watermark(s) for ${resolved.target.watch.id}.`
|
|
1362
|
+
: `No PR event watermark changes for ${resolved.target.watch.id}.`,
|
|
1363
|
+
{
|
|
1364
|
+
watchId: resolved.target.watch.id,
|
|
1365
|
+
target: eventTargetJson(resolved.target),
|
|
1366
|
+
changedCategories,
|
|
1367
|
+
watermarks: readWatermarks(
|
|
1368
|
+
paths,
|
|
1369
|
+
resolved.target.watch.id,
|
|
1370
|
+
) as unknown as JsonValue,
|
|
1371
|
+
},
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
function comparableWatermark(category: string, value: unknown) {
|
|
1376
|
+
if (category !== 'mergeability') return value ?? null;
|
|
1377
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1378
|
+
return value ?? null;
|
|
1379
|
+
}
|
|
1380
|
+
const record = value as Record<string, unknown>;
|
|
1381
|
+
return {
|
|
1382
|
+
state: record.state,
|
|
1383
|
+
draft: typeof record.draft === 'boolean' ? record.draft : false,
|
|
1384
|
+
merged: record.merged,
|
|
1385
|
+
mergeable: record.mergeable,
|
|
1386
|
+
mergeableState: record.mergeableState,
|
|
1387
|
+
mergeCommitSha: record.mergeCommitSha,
|
|
1388
|
+
headSha: record.headSha,
|
|
1389
|
+
baseSha: record.baseSha,
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
export async function listPrWatchEventWatermarks(
|
|
1394
|
+
input: v.InferInput<typeof prWatchEventWatermarkListInputSchema> = {},
|
|
1395
|
+
paths: RuntimePaths = runtimePaths(),
|
|
1396
|
+
): Promise<PrEventActionResult> {
|
|
1397
|
+
await ensureRuntimeHome(paths);
|
|
1398
|
+
const parsed = v.safeParse(prWatchEventWatermarkListInputSchema, input);
|
|
1399
|
+
if (!parsed.success) {
|
|
1400
|
+
return failResult(
|
|
1401
|
+
'pr_watch_event_watermarks_list',
|
|
1402
|
+
'Invalid PR watch event watermark input.',
|
|
1403
|
+
{ errors: [v.summarize(parsed.issues)] },
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
const watermarks = readWatermarks(paths, parsed.output.watchId);
|
|
1408
|
+
return okResult(
|
|
1409
|
+
'pr_watch_event_watermarks_list',
|
|
1410
|
+
false,
|
|
1411
|
+
`Listed ${watermarks.length} PR watch event watermark(s).`,
|
|
1412
|
+
{ watermarks: watermarks as unknown as JsonValue },
|
|
1413
|
+
);
|
|
1414
|
+
}
|