@quickchatai/pi-quickreview 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +75 -2
- package/assets/agents/pass-abstraction.md +64 -0
- package/assets/agents/pass-ask-human.md +134 -0
- package/assets/agents/pass-backcompat.md +67 -0
- package/assets/agents/pass-baseline.md +61 -0
- package/assets/agents/pass-behaviour-delta.md +64 -0
- package/assets/agents/pass-bounds.md +36 -0
- package/assets/agents/pass-claims.md +31 -0
- package/assets/agents/pass-concurrency.md +168 -0
- package/assets/agents/pass-consistency.md +57 -0
- package/assets/agents/pass-contracts.md +30 -0
- package/assets/agents/pass-data-safety.md +54 -0
- package/assets/agents/pass-deferred.md +35 -0
- package/assets/agents/pass-delivery.md +37 -0
- package/assets/agents/pass-duplication.md +60 -0
- package/assets/agents/pass-intent.md +63 -0
- package/assets/agents/pass-lint-conformance.md +46 -0
- package/assets/agents/pass-maintainability.md +67 -0
- package/assets/agents/pass-placement.md +68 -0
- package/assets/agents/pass-prod-risk.md +24 -0
- package/assets/agents/pass-rollout.md +32 -0
- package/assets/agents/pass-roundtrip.md +46 -0
- package/assets/agents/pass-security.md +31 -0
- package/assets/agents/pass-simplicity.md +68 -0
- package/assets/agents/pass-statelessness.md +27 -0
- package/assets/agents/pass-style.md +37 -0
- package/assets/agents/pass-sweep.md +57 -0
- package/assets/agents/pass-tests.md +58 -0
- package/assets/agents/pass-ui.md +23 -0
- package/assets/agents/pass-validate.md +50 -0
- package/assets/agents/pass-widened.md +46 -0
- package/assets/agents/scan/pass-scan.md +86 -0
- package/assets/config.example.toml +1067 -0
- package/assets/deploy/reviewer/AGENTS.override.md +12 -0
- package/assets/profiles/default/README.md +21 -0
- package/assets/profiles/default/addenda/.gitkeep +0 -0
- package/assets/profiles/default/profile.toml +17 -0
- package/assets/profiles/example-django/README.md +21 -0
- package/assets/profiles/example-django/addenda/10-migration-discipline.md +13 -0
- package/assets/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
- package/assets/profiles/example-django/addenda/30-test-doctrine.md +12 -0
- package/assets/profiles/example-django/addenda/40-orm-usage.md +19 -0
- package/assets/profiles/example-django/addenda/50-declared-shape.md +10 -0
- package/assets/profiles/example-django/addenda/60-config-placement.md +14 -0
- package/assets/profiles/example-django/heuristics.toml +24 -0
- package/assets/profiles/example-django/profile.toml +9 -0
- package/assets/profiles/fast/README.md +24 -0
- package/assets/profiles/fast/profile.toml +59 -0
- package/assets/profiles/minimal/README.md +17 -0
- package/assets/profiles/minimal/addenda/.gitkeep +0 -0
- package/assets/profiles/minimal/profile.toml +8 -0
- package/assets/profiles/snappy/README.md +24 -0
- package/assets/profiles/snappy/addenda/10-race-as-question.md +6 -0
- package/assets/profiles/snappy/profile.toml +46 -0
- package/assets/prompts/companion-day-open.md +46 -0
- package/assets/prompts/companion-first-run.md +104 -0
- package/assets/prompts/companion.md +821 -0
- package/assets/prompts/conversation-system.md +117 -0
- package/assets/prompts/eod-sweep.md +120 -0
- package/assets/prompts/onboarding.md +74 -0
- package/assets/prompts/pass-common.md +52 -0
- package/assets/prompts/pass-quality-common.md +22 -0
- package/assets/prompts/round-first.md +874 -0
- package/assets/prompts/round-follow-up.md +991 -0
- package/assets/prompts/round-re-review.md +889 -0
- package/assets/prompts/round-recheck.md +196 -0
- package/assets/prompts/round-staleness.md +856 -0
- package/assets/schemas/review-result.v1.json +391 -0
- package/assets/schemas/scan-result.v1.json +421 -0
- package/assets/schemas/version.v1.json +57 -0
- package/assets/seed-manifest.json +19 -0
- package/assets/seeds/agents/pass-baseline.md +61 -0
- package/assets/seeds/agents/pass-contracts.md +30 -0
- package/assets/seeds/agents/pass-data-safety.md +54 -0
- package/assets/seeds/agents/pass-delivery.md +37 -0
- package/assets/seeds/agents/pass-prod-risk.md +24 -0
- package/assets/seeds/agents/pass-security.md +31 -0
- package/assets/seeds/agents/pass-statelessness.md +27 -0
- package/assets/seeds/agents/pass-ui.md +23 -0
- package/assets/seeds/agents/pass-validate.md +50 -0
- package/assets/seeds/prompts/conversation-system.md +117 -0
- package/assets/seeds/prompts/eod-sweep.md +120 -0
- package/assets/seeds/prompts/pass-common.md +52 -0
- package/dist/extensions/bash-guard.d.ts +467 -0
- package/dist/extensions/bash-guard.d.ts.map +1 -0
- package/dist/extensions/bash-guard.js +3058 -0
- package/dist/extensions/bash-guard.js.map +1 -0
- package/dist/extensions/finding-clusters.d.ts +33 -0
- package/dist/extensions/finding-clusters.d.ts.map +1 -0
- package/dist/extensions/finding-clusters.js +218 -0
- package/dist/extensions/finding-clusters.js.map +1 -0
- package/dist/extensions/ledger-pin.d.ts +76 -0
- package/dist/extensions/ledger-pin.d.ts.map +1 -0
- package/dist/extensions/ledger-pin.js +331 -0
- package/dist/extensions/ledger-pin.js.map +1 -0
- package/dist/extensions/lens.d.ts +43 -0
- package/dist/extensions/lens.d.ts.map +1 -0
- package/dist/extensions/lens.js +150 -0
- package/dist/extensions/lens.js.map +1 -0
- package/dist/extensions/pi-tool.d.ts +22 -0
- package/dist/extensions/pi-tool.d.ts.map +1 -0
- package/dist/extensions/pi-tool.js +20 -0
- package/dist/extensions/pi-tool.js.map +1 -0
- package/dist/extensions/quickreview.d.ts +21 -0
- package/dist/extensions/quickreview.d.ts.map +1 -0
- package/dist/extensions/quickreview.js +132 -0
- package/dist/extensions/quickreview.js.map +1 -0
- package/dist/src/anchors.d.ts +54 -0
- package/dist/src/anchors.d.ts.map +1 -0
- package/dist/src/anchors.js +127 -0
- package/dist/src/anchors.js.map +1 -0
- package/dist/src/assetroot.d.ts +16 -0
- package/dist/src/assetroot.d.ts.map +1 -0
- package/dist/src/assetroot.js +77 -0
- package/dist/src/assetroot.js.map +1 -0
- package/dist/src/authwatch.d.ts +61 -0
- package/dist/src/authwatch.d.ts.map +1 -0
- package/dist/src/authwatch.js +210 -0
- package/dist/src/authwatch.js.map +1 -0
- package/dist/src/budget.d.ts +15 -0
- package/dist/src/budget.d.ts.map +1 -0
- package/dist/src/budget.js +32 -0
- package/dist/src/budget.js.map +1 -0
- package/dist/src/casebudget.d.ts +3 -0
- package/dist/src/casebudget.d.ts.map +1 -0
- package/dist/src/casebudget.js +3 -0
- package/dist/src/casebudget.js.map +1 -0
- package/dist/src/cigate.d.ts +116 -0
- package/dist/src/cigate.d.ts.map +1 -0
- package/dist/src/cigate.js +176 -0
- package/dist/src/cigate.js.map +1 -0
- package/dist/src/codespan.d.ts +46 -0
- package/dist/src/codespan.d.ts.map +1 -0
- package/dist/src/codespan.js +75 -0
- package/dist/src/codespan.js.map +1 -0
- package/dist/src/contextpack.d.ts +56 -0
- package/dist/src/contextpack.d.ts.map +1 -0
- package/dist/src/contextpack.js +195 -0
- package/dist/src/contextpack.js.map +1 -0
- package/dist/src/contract.d.ts +8 -0
- package/dist/src/contract.d.ts.map +1 -0
- package/dist/src/contract.js +21 -0
- package/dist/src/contract.js.map +1 -0
- package/dist/src/coverage.d.ts +32 -0
- package/dist/src/coverage.d.ts.map +1 -0
- package/dist/src/coverage.js +85 -0
- package/dist/src/coverage.js.map +1 -0
- package/dist/src/datafence.d.ts +19 -0
- package/dist/src/datafence.d.ts.map +1 -0
- package/dist/src/datafence.js +60 -0
- package/dist/src/datafence.js.map +1 -0
- package/dist/src/dedup.d.ts +65 -0
- package/dist/src/dedup.d.ts.map +1 -0
- package/dist/src/dedup.js +459 -0
- package/dist/src/dedup.js.map +1 -0
- package/dist/src/depsources.d.ts +304 -0
- package/dist/src/depsources.d.ts.map +1 -0
- package/dist/src/depsources.js +3367 -0
- package/dist/src/depsources.js.map +1 -0
- package/dist/src/diffinput.d.ts +10 -0
- package/dist/src/diffinput.d.ts.map +1 -0
- package/dist/src/diffinput.js +172 -0
- package/dist/src/diffinput.js.map +1 -0
- package/dist/src/doubtwords.d.ts +10 -0
- package/dist/src/doubtwords.d.ts.map +1 -0
- package/dist/src/doubtwords.js +13 -0
- package/dist/src/doubtwords.js.map +1 -0
- package/dist/src/ecosystem.d.ts +148 -0
- package/dist/src/ecosystem.d.ts.map +1 -0
- package/dist/src/ecosystem.js +338 -0
- package/dist/src/ecosystem.js.map +1 -0
- package/dist/src/engine/agentdir.d.ts +5 -0
- package/dist/src/engine/agentdir.d.ts.map +1 -0
- package/dist/src/engine/agentdir.js +21 -0
- package/dist/src/engine/agentdir.js.map +1 -0
- package/dist/src/engine/auth.d.ts +214 -0
- package/dist/src/engine/auth.d.ts.map +1 -0
- package/dist/src/engine/auth.js +374 -0
- package/dist/src/engine/auth.js.map +1 -0
- package/dist/src/engine/budget.d.ts +60 -0
- package/dist/src/engine/budget.d.ts.map +1 -0
- package/dist/src/engine/budget.js +113 -0
- package/dist/src/engine/budget.js.map +1 -0
- package/dist/src/engine/capfd.d.ts +6 -0
- package/dist/src/engine/capfd.d.ts.map +1 -0
- package/dist/src/engine/capfd.js +21 -0
- package/dist/src/engine/capfd.js.map +1 -0
- package/dist/src/engine/caseout.d.ts +66 -0
- package/dist/src/engine/caseout.d.ts.map +1 -0
- package/dist/src/engine/caseout.js +107 -0
- package/dist/src/engine/caseout.js.map +1 -0
- package/dist/src/engine/context.d.ts +57 -0
- package/dist/src/engine/context.d.ts.map +1 -0
- package/dist/src/engine/context.js +212 -0
- package/dist/src/engine/context.js.map +1 -0
- package/dist/src/engine/envmap.d.ts +13 -0
- package/dist/src/engine/envmap.d.ts.map +1 -0
- package/dist/src/engine/envmap.js +372 -0
- package/dist/src/engine/envmap.js.map +1 -0
- package/dist/src/engine/extfiles.d.ts +7 -0
- package/dist/src/engine/extfiles.d.ts.map +1 -0
- package/dist/src/engine/extfiles.js +23 -0
- package/dist/src/engine/extfiles.js.map +1 -0
- package/dist/src/engine/keyroute.d.ts +21 -0
- package/dist/src/engine/keyroute.d.ts.map +1 -0
- package/dist/src/engine/keyroute.js +58 -0
- package/dist/src/engine/keyroute.js.map +1 -0
- package/dist/src/engine/lens/cache-group.d.ts +20 -0
- package/dist/src/engine/lens/cache-group.d.ts.map +1 -0
- package/dist/src/engine/lens/cache-group.js +31 -0
- package/dist/src/engine/lens/cache-group.js.map +1 -0
- package/dist/src/engine/lens/cache-run.d.ts +65 -0
- package/dist/src/engine/lens/cache-run.d.ts.map +1 -0
- package/dist/src/engine/lens/cache-run.js +159 -0
- package/dist/src/engine/lens/cache-run.js.map +1 -0
- package/dist/src/engine/lens/deadline.d.ts +54 -0
- package/dist/src/engine/lens/deadline.d.ts.map +1 -0
- package/dist/src/engine/lens/deadline.js +111 -0
- package/dist/src/engine/lens/deadline.js.map +1 -0
- package/dist/src/engine/lens/engine-tools.d.ts +13 -0
- package/dist/src/engine/lens/engine-tools.d.ts.map +1 -0
- package/dist/src/engine/lens/engine-tools.js +37 -0
- package/dist/src/engine/lens/engine-tools.js.map +1 -0
- package/dist/src/engine/lens/env.d.ts +23 -0
- package/dist/src/engine/lens/env.d.ts.map +1 -0
- package/dist/src/engine/lens/env.js +42 -0
- package/dist/src/engine/lens/env.js.map +1 -0
- package/dist/src/engine/lens/launch-plan.d.ts +63 -0
- package/dist/src/engine/lens/launch-plan.d.ts.map +1 -0
- package/dist/src/engine/lens/launch-plan.js +203 -0
- package/dist/src/engine/lens/launch-plan.js.map +1 -0
- package/dist/src/engine/lens/leaf-cache.d.ts +22 -0
- package/dist/src/engine/lens/leaf-cache.d.ts.map +1 -0
- package/dist/src/engine/lens/leaf-cache.js +115 -0
- package/dist/src/engine/lens/leaf-cache.js.map +1 -0
- package/dist/src/engine/lens/permits.d.ts +14 -0
- package/dist/src/engine/lens/permits.d.ts.map +1 -0
- package/dist/src/engine/lens/permits.js +18 -0
- package/dist/src/engine/lens/permits.js.map +1 -0
- package/dist/src/engine/lens/registry.d.ts +55 -0
- package/dist/src/engine/lens/registry.d.ts.map +1 -0
- package/dist/src/engine/lens/registry.js +140 -0
- package/dist/src/engine/lens/registry.js.map +1 -0
- package/dist/src/engine/lens/round-lens.d.ts +16 -0
- package/dist/src/engine/lens/round-lens.d.ts.map +1 -0
- package/dist/src/engine/lens/round-lens.js +46 -0
- package/dist/src/engine/lens/round-lens.js.map +1 -0
- package/dist/src/engine/lens/runlens.d.ts +103 -0
- package/dist/src/engine/lens/runlens.d.ts.map +1 -0
- package/dist/src/engine/lens/runlens.js +538 -0
- package/dist/src/engine/lens/runlens.js.map +1 -0
- package/dist/src/engine/lens/section.d.ts +19 -0
- package/dist/src/engine/lens/section.d.ts.map +1 -0
- package/dist/src/engine/lens/section.js +40 -0
- package/dist/src/engine/lens/section.js.map +1 -0
- package/dist/src/engine/lens/semaphore.d.ts +13 -0
- package/dist/src/engine/lens/semaphore.d.ts.map +1 -0
- package/dist/src/engine/lens/semaphore.js +44 -0
- package/dist/src/engine/lens/semaphore.js.map +1 -0
- package/dist/src/engine/lens/tool.d.ts +34 -0
- package/dist/src/engine/lens/tool.d.ts.map +1 -0
- package/dist/src/engine/lens/tool.js +345 -0
- package/dist/src/engine/lens/tool.js.map +1 -0
- package/dist/src/engine/lens/wave.d.ts +63 -0
- package/dist/src/engine/lens/wave.d.ts.map +1 -0
- package/dist/src/engine/lens/wave.js +95 -0
- package/dist/src/engine/lens/wave.js.map +1 -0
- package/dist/src/engine/livesessions.d.ts +21 -0
- package/dist/src/engine/livesessions.d.ts.map +1 -0
- package/dist/src/engine/livesessions.js +57 -0
- package/dist/src/engine/livesessions.js.map +1 -0
- package/dist/src/engine/livewire.d.ts +18 -0
- package/dist/src/engine/livewire.d.ts.map +1 -0
- package/dist/src/engine/livewire.js +31 -0
- package/dist/src/engine/livewire.js.map +1 -0
- package/dist/src/engine/openable.d.ts +37 -0
- package/dist/src/engine/openable.d.ts.map +1 -0
- package/dist/src/engine/openable.js +120 -0
- package/dist/src/engine/openable.js.map +1 -0
- package/dist/src/engine/pisdk.d.ts +226 -0
- package/dist/src/engine/pisdk.d.ts.map +1 -0
- package/dist/src/engine/pisdk.js +552 -0
- package/dist/src/engine/pisdk.js.map +1 -0
- package/dist/src/engine/port.d.ts +144 -0
- package/dist/src/engine/port.d.ts.map +1 -0
- package/dist/src/engine/port.js +16 -0
- package/dist/src/engine/port.js.map +1 -0
- package/dist/src/engine/prompts.d.ts +159 -0
- package/dist/src/engine/prompts.d.ts.map +1 -0
- package/dist/src/engine/prompts.js +339 -0
- package/dist/src/engine/prompts.js.map +1 -0
- package/dist/src/engine/render.d.ts +10 -0
- package/dist/src/engine/render.d.ts.map +1 -0
- package/dist/src/engine/render.js +23 -0
- package/dist/src/engine/render.js.map +1 -0
- package/dist/src/engine/reviewruntime.d.ts +13 -0
- package/dist/src/engine/reviewruntime.d.ts.map +1 -0
- package/dist/src/engine/reviewruntime.js +35 -0
- package/dist/src/engine/reviewruntime.js.map +1 -0
- package/dist/src/engine/reviewsdk.d.ts +75 -0
- package/dist/src/engine/reviewsdk.d.ts.map +1 -0
- package/dist/src/engine/reviewsdk.js +180 -0
- package/dist/src/engine/reviewsdk.js.map +1 -0
- package/dist/src/engine/round.d.ts +166 -0
- package/dist/src/engine/round.d.ts.map +1 -0
- package/dist/src/engine/round.js +543 -0
- package/dist/src/engine/round.js.map +1 -0
- package/dist/src/engine/roundagents.d.ts +17 -0
- package/dist/src/engine/roundagents.d.ts.map +1 -0
- package/dist/src/engine/roundagents.js +49 -0
- package/dist/src/engine/roundagents.js.map +1 -0
- package/dist/src/engine/roundevents.d.ts +110 -0
- package/dist/src/engine/roundevents.d.ts.map +1 -0
- package/dist/src/engine/roundevents.js +276 -0
- package/dist/src/engine/roundevents.js.map +1 -0
- package/dist/src/engine/roundsdk.d.ts +33 -0
- package/dist/src/engine/roundsdk.d.ts.map +1 -0
- package/dist/src/engine/roundsdk.js +76 -0
- package/dist/src/engine/roundsdk.js.map +1 -0
- package/dist/src/engine/sdkruntime.d.ts +23 -0
- package/dist/src/engine/sdkruntime.d.ts.map +1 -0
- package/dist/src/engine/sdkruntime.js +340 -0
- package/dist/src/engine/sdkruntime.js.map +1 -0
- package/dist/src/engine/select.d.ts +16 -0
- package/dist/src/engine/select.d.ts.map +1 -0
- package/dist/src/engine/select.js +32 -0
- package/dist/src/engine/select.js.map +1 -0
- package/dist/src/engine/sessionwrap.d.ts +4 -0
- package/dist/src/engine/sessionwrap.d.ts.map +1 -0
- package/dist/src/engine/sessionwrap.js +31 -0
- package/dist/src/engine/sessionwrap.js.map +1 -0
- package/dist/src/engine/toolfence.d.ts +90 -0
- package/dist/src/engine/toolfence.d.ts.map +1 -0
- package/dist/src/engine/toolfence.js +378 -0
- package/dist/src/engine/toolfence.js.map +1 -0
- package/dist/src/engine/tooluid.d.ts +128 -0
- package/dist/src/engine/tooluid.d.ts.map +1 -0
- package/dist/src/engine/tooluid.js +401 -0
- package/dist/src/engine/tooluid.js.map +1 -0
- package/dist/src/envstrip.d.ts +10 -0
- package/dist/src/envstrip.d.ts.map +1 -0
- package/dist/src/envstrip.js +15 -0
- package/dist/src/envstrip.js.map +1 -0
- package/dist/src/escalationprompt.d.ts +22 -0
- package/dist/src/escalationprompt.d.ts.map +1 -0
- package/dist/src/escalationprompt.js +54 -0
- package/dist/src/escalationprompt.js.map +1 -0
- package/dist/src/execfn.d.ts +29 -0
- package/dist/src/execfn.d.ts.map +1 -0
- package/dist/src/execfn.js +55 -0
- package/dist/src/execfn.js.map +1 -0
- package/dist/src/finding-chain.d.ts +40 -0
- package/dist/src/finding-chain.d.ts.map +1 -0
- package/dist/src/finding-chain.js +76 -0
- package/dist/src/finding-chain.js.map +1 -0
- package/dist/src/finding-row.d.ts +24 -0
- package/dist/src/finding-row.d.ts.map +1 -0
- package/dist/src/finding-row.js +26 -0
- package/dist/src/finding-row.js.map +1 -0
- package/dist/src/findingkey.d.ts +99 -0
- package/dist/src/findingkey.d.ts.map +1 -0
- package/dist/src/findingkey.js +210 -0
- package/dist/src/findingkey.js.map +1 -0
- package/dist/src/findingsrecord.d.ts +175 -0
- package/dist/src/findingsrecord.d.ts.map +1 -0
- package/dist/src/findingsrecord.js +410 -0
- package/dist/src/findingsrecord.js.map +1 -0
- package/dist/src/followup-mode.d.ts +4 -0
- package/dist/src/followup-mode.d.ts.map +1 -0
- package/dist/src/followup-mode.js +6 -0
- package/dist/src/followup-mode.js.map +1 -0
- package/dist/src/gate.d.ts +199 -0
- package/dist/src/gate.d.ts.map +1 -0
- package/dist/src/gate.js +315 -0
- package/dist/src/gate.js.map +1 -0
- package/dist/src/ghcred.d.ts +58 -0
- package/dist/src/ghcred.d.ts.map +1 -0
- package/dist/src/ghcred.js +139 -0
- package/dist/src/ghcred.js.map +1 -0
- package/dist/src/githubAuth.d.ts +32 -0
- package/dist/src/githubAuth.d.ts.map +1 -0
- package/dist/src/githubAuth.js +116 -0
- package/dist/src/githubAuth.js.map +1 -0
- package/dist/src/githubcore.d.ts +20 -0
- package/dist/src/githubcore.d.ts.map +1 -0
- package/dist/src/githubcore.js +20 -0
- package/dist/src/githubcore.js.map +1 -0
- package/dist/src/glob.d.ts +11 -0
- package/dist/src/glob.d.ts.map +1 -0
- package/dist/src/glob.js +69 -0
- package/dist/src/glob.js.map +1 -0
- package/dist/src/guards.d.ts +93 -0
- package/dist/src/guards.d.ts.map +1 -0
- package/dist/src/guards.js +306 -0
- package/dist/src/guards.js.map +1 -0
- package/dist/src/heartbeat.d.ts +29 -0
- package/dist/src/heartbeat.d.ts.map +1 -0
- package/dist/src/heartbeat.js +87 -0
- package/dist/src/heartbeat.js.map +1 -0
- package/dist/src/heuristics.d.ts +247 -0
- package/dist/src/heuristics.d.ts.map +1 -0
- package/dist/src/heuristics.js +927 -0
- package/dist/src/heuristics.js.map +1 -0
- package/dist/src/homes.d.ts +181 -0
- package/dist/src/homes.d.ts.map +1 -0
- package/dist/src/homes.js +242 -0
- package/dist/src/homes.js.map +1 -0
- package/dist/src/hunkheader.d.ts +11 -0
- package/dist/src/hunkheader.d.ts.map +1 -0
- package/dist/src/hunkheader.js +18 -0
- package/dist/src/hunkheader.js.map +1 -0
- package/dist/src/include.d.ts +435 -0
- package/dist/src/include.d.ts.map +1 -0
- package/dist/src/include.js +1692 -0
- package/dist/src/include.js.map +1 -0
- package/dist/src/launchvocab.d.ts +36 -0
- package/dist/src/launchvocab.d.ts.map +1 -0
- package/dist/src/launchvocab.js +59 -0
- package/dist/src/launchvocab.js.map +1 -0
- package/dist/src/ledgercarry.d.ts +24 -0
- package/dist/src/ledgercarry.d.ts.map +1 -0
- package/dist/src/ledgercarry.js +109 -0
- package/dist/src/ledgercarry.js.map +1 -0
- package/dist/src/lensids.d.ts +7 -0
- package/dist/src/lensids.d.ts.map +1 -0
- package/dist/src/lensids.js +53 -0
- package/dist/src/lensids.js.map +1 -0
- package/dist/src/lensplanning.d.ts +8 -0
- package/dist/src/lensplanning.d.ts.map +1 -0
- package/dist/src/lensplanning.js +126 -0
- package/dist/src/lensplanning.js.map +1 -0
- package/dist/src/lensresult.d.ts +94 -0
- package/dist/src/lensresult.d.ts.map +1 -0
- package/dist/src/lensresult.js +162 -0
- package/dist/src/lensresult.js.map +1 -0
- package/dist/src/lenstuning.d.ts +97 -0
- package/dist/src/lenstuning.d.ts.map +1 -0
- package/dist/src/lenstuning.js +326 -0
- package/dist/src/lenstuning.js.map +1 -0
- package/dist/src/lintconfig.d.ts +31 -0
- package/dist/src/lintconfig.d.ts.map +1 -0
- package/dist/src/lintconfig.js +543 -0
- package/dist/src/lintconfig.js.map +1 -0
- package/dist/src/live/events.d.ts +188 -0
- package/dist/src/live/events.d.ts.map +1 -0
- package/dist/src/live/events.js +136 -0
- package/dist/src/live/events.js.map +1 -0
- package/dist/src/live/writer.d.ts +54 -0
- package/dist/src/live/writer.d.ts.map +1 -0
- package/dist/src/live/writer.js +516 -0
- package/dist/src/live/writer.js.map +1 -0
- package/dist/src/localreview.d.ts +128 -0
- package/dist/src/localreview.d.ts.map +1 -0
- package/dist/src/localreview.js +426 -0
- package/dist/src/localreview.js.map +1 -0
- package/dist/src/loosenedtests.d.ts +13 -0
- package/dist/src/loosenedtests.d.ts.map +1 -0
- package/dist/src/loosenedtests.js +188 -0
- package/dist/src/loosenedtests.js.map +1 -0
- package/dist/src/memoryport.d.ts +264 -0
- package/dist/src/memoryport.d.ts.map +1 -0
- package/dist/src/memoryport.js +445 -0
- package/dist/src/memoryport.js.map +1 -0
- package/dist/src/migrations.d.ts +106 -0
- package/dist/src/migrations.d.ts.map +1 -0
- package/dist/src/migrations.js +373 -0
- package/dist/src/migrations.js.map +1 -0
- package/dist/src/oneshot.d.ts +12 -0
- package/dist/src/oneshot.d.ts.map +1 -0
- package/dist/src/oneshot.js +8 -0
- package/dist/src/oneshot.js.map +1 -0
- package/dist/src/packing.d.ts +11 -0
- package/dist/src/packing.d.ts.map +1 -0
- package/dist/src/packing.js +31 -0
- package/dist/src/packing.js.map +1 -0
- package/dist/src/passes.d.ts +16 -0
- package/dist/src/passes.d.ts.map +1 -0
- package/dist/src/passes.js +104 -0
- package/dist/src/passes.js.map +1 -0
- package/dist/src/passtasks.d.ts +68 -0
- package/dist/src/passtasks.d.ts.map +1 -0
- package/dist/src/passtasks.js +360 -0
- package/dist/src/passtasks.js.map +1 -0
- package/dist/src/pathinside.d.ts +5 -0
- package/dist/src/pathinside.d.ts.map +1 -0
- package/dist/src/pathinside.js +9 -0
- package/dist/src/pathinside.js.map +1 -0
- package/dist/src/pibuiltins.d.ts +36 -0
- package/dist/src/pibuiltins.d.ts.map +1 -0
- package/dist/src/pibuiltins.js +83 -0
- package/dist/src/pibuiltins.js.map +1 -0
- package/dist/src/plankey.d.ts +4 -0
- package/dist/src/plankey.d.ts.map +1 -0
- package/dist/src/plankey.js +10 -0
- package/dist/src/plankey.js.map +1 -0
- package/dist/src/planner.d.ts +375 -0
- package/dist/src/planner.d.ts.map +1 -0
- package/dist/src/planner.js +722 -0
- package/dist/src/planner.js.map +1 -0
- package/dist/src/plugin/args.d.ts +19 -0
- package/dist/src/plugin/args.d.ts.map +1 -0
- package/dist/src/plugin/args.js +107 -0
- package/dist/src/plugin/args.js.map +1 -0
- package/dist/src/plugin/index.d.ts +3 -0
- package/dist/src/plugin/index.d.ts.map +1 -0
- package/dist/src/plugin/index.js +14 -0
- package/dist/src/plugin/index.js.map +1 -0
- package/dist/src/plugin/login.d.ts +39 -0
- package/dist/src/plugin/login.d.ts.map +1 -0
- package/dist/src/plugin/login.js +73 -0
- package/dist/src/plugin/login.js.map +1 -0
- package/dist/src/plugin/review.d.ts +27 -0
- package/dist/src/plugin/review.d.ts.map +1 -0
- package/dist/src/plugin/review.js +298 -0
- package/dist/src/plugin/review.js.map +1 -0
- package/dist/src/plugin/runner.d.ts +6 -0
- package/dist/src/plugin/runner.d.ts.map +1 -0
- package/dist/src/plugin/runner.js +65 -0
- package/dist/src/plugin/runner.js.map +1 -0
- package/dist/src/plugin/scan.d.ts +79 -0
- package/dist/src/plugin/scan.d.ts.map +1 -0
- package/dist/src/plugin/scan.js +348 -0
- package/dist/src/plugin/scan.js.map +1 -0
- package/dist/src/plugin/session.d.ts +56 -0
- package/dist/src/plugin/session.d.ts.map +1 -0
- package/dist/src/plugin/session.js +2 -0
- package/dist/src/plugin/session.js.map +1 -0
- package/dist/src/plugin/setup.d.ts +19 -0
- package/dist/src/plugin/setup.d.ts.map +1 -0
- package/dist/src/plugin/setup.js +142 -0
- package/dist/src/plugin/setup.js.map +1 -0
- package/dist/src/plugin/versiongate.d.ts +26 -0
- package/dist/src/plugin/versiongate.d.ts.map +1 -0
- package/dist/src/plugin/versiongate.js +83 -0
- package/dist/src/plugin/versiongate.js.map +1 -0
- package/dist/src/postingkey.d.ts +8 -0
- package/dist/src/postingkey.d.ts.map +1 -0
- package/dist/src/postingkey.js +25 -0
- package/dist/src/postingkey.js.map +1 -0
- package/dist/src/postingpolicy.d.ts +108 -0
- package/dist/src/postingpolicy.d.ts.map +1 -0
- package/dist/src/postingpolicy.js +341 -0
- package/dist/src/postingpolicy.js.map +1 -0
- package/dist/src/pr-identity.d.ts +3 -0
- package/dist/src/pr-identity.d.ts.map +1 -0
- package/dist/src/pr-identity.js +9 -0
- package/dist/src/pr-identity.js.map +1 -0
- package/dist/src/prdelta.d.ts +181 -0
- package/dist/src/prdelta.d.ts.map +1 -0
- package/dist/src/prdelta.js +501 -0
- package/dist/src/prdelta.js.map +1 -0
- package/dist/src/pricing.d.ts +94 -0
- package/dist/src/pricing.d.ts.map +1 -0
- package/dist/src/pricing.js +209 -0
- package/dist/src/pricing.js.map +1 -0
- package/dist/src/priorfindings.d.ts +167 -0
- package/dist/src/priorfindings.d.ts.map +1 -0
- package/dist/src/priorfindings.js +445 -0
- package/dist/src/priorfindings.js.map +1 -0
- package/dist/src/priortasks.d.ts +31 -0
- package/dist/src/priortasks.d.ts.map +1 -0
- package/dist/src/priortasks.js +119 -0
- package/dist/src/priortasks.js.map +1 -0
- package/dist/src/profilelookup.d.ts +59 -0
- package/dist/src/profilelookup.d.ts.map +1 -0
- package/dist/src/profilelookup.js +98 -0
- package/dist/src/profilelookup.js.map +1 -0
- package/dist/src/profileoverrides.d.ts +91 -0
- package/dist/src/profileoverrides.d.ts.map +1 -0
- package/dist/src/profileoverrides.js +313 -0
- package/dist/src/profileoverrides.js.map +1 -0
- package/dist/src/profiles.d.ts +144 -0
- package/dist/src/profiles.d.ts.map +1 -0
- package/dist/src/profiles.js +604 -0
- package/dist/src/profiles.js.map +1 -0
- package/dist/src/promptdoc.d.ts +3 -0
- package/dist/src/promptdoc.d.ts.map +1 -0
- package/dist/src/promptdoc.js +18 -0
- package/dist/src/promptdoc.js.map +1 -0
- package/dist/src/prtarget.d.ts +70 -0
- package/dist/src/prtarget.d.ts.map +1 -0
- package/dist/src/prtarget.js +181 -0
- package/dist/src/prtarget.js.map +1 -0
- package/dist/src/recheckorder.d.ts +32 -0
- package/dist/src/recheckorder.d.ts.map +1 -0
- package/dist/src/recheckorder.js +5 -0
- package/dist/src/recheckorder.js.map +1 -0
- package/dist/src/reviewapi.d.ts +207 -0
- package/dist/src/reviewapi.d.ts.map +1 -0
- package/dist/src/reviewapi.js +939 -0
- package/dist/src/reviewapi.js.map +1 -0
- package/dist/src/reviewbotfindings.d.ts +33 -0
- package/dist/src/reviewbotfindings.d.ts.map +1 -0
- package/dist/src/reviewbotfindings.js +80 -0
- package/dist/src/reviewbotfindings.js.map +1 -0
- package/dist/src/reviewconfig.d.ts +741 -0
- package/dist/src/reviewconfig.d.ts.map +1 -0
- package/dist/src/reviewconfig.js +797 -0
- package/dist/src/reviewconfig.js.map +1 -0
- package/dist/src/reviewdelta.d.ts +51 -0
- package/dist/src/reviewdelta.d.ts.map +1 -0
- package/dist/src/reviewdelta.js +119 -0
- package/dist/src/reviewdelta.js.map +1 -0
- package/dist/src/reviewdest.d.ts +86 -0
- package/dist/src/reviewdest.d.ts.map +1 -0
- package/dist/src/reviewdest.js +142 -0
- package/dist/src/reviewdest.js.map +1 -0
- package/dist/src/reviewerstub.d.ts +12 -0
- package/dist/src/reviewerstub.d.ts.map +1 -0
- package/dist/src/reviewerstub.js +28 -0
- package/dist/src/reviewerstub.js.map +1 -0
- package/dist/src/reviewhost.d.ts +58 -0
- package/dist/src/reviewhost.d.ts.map +1 -0
- package/dist/src/reviewhost.js +135 -0
- package/dist/src/reviewhost.js.map +1 -0
- package/dist/src/reviewpost.d.ts +79 -0
- package/dist/src/reviewpost.d.ts.map +1 -0
- package/dist/src/reviewpost.js +233 -0
- package/dist/src/reviewpost.js.map +1 -0
- package/dist/src/reviewrender.d.ts +154 -0
- package/dist/src/reviewrender.d.ts.map +1 -0
- package/dist/src/reviewrender.js +480 -0
- package/dist/src/reviewrender.js.map +1 -0
- package/dist/src/reviewstate.d.ts +62 -0
- package/dist/src/reviewstate.d.ts.map +1 -0
- package/dist/src/reviewstate.js +167 -0
- package/dist/src/reviewstate.js.map +1 -0
- package/dist/src/reviewstore.d.ts +17 -0
- package/dist/src/reviewstore.d.ts.map +1 -0
- package/dist/src/reviewstore.js +105 -0
- package/dist/src/reviewstore.js.map +1 -0
- package/dist/src/round-progress.d.ts +120 -0
- package/dist/src/round-progress.d.ts.map +1 -0
- package/dist/src/round-progress.js +172 -0
- package/dist/src/round-progress.js.map +1 -0
- package/dist/src/round-stage-deadlines.d.ts +12 -0
- package/dist/src/round-stage-deadlines.d.ts.map +1 -0
- package/dist/src/round-stage-deadlines.js +10 -0
- package/dist/src/round-stage-deadlines.js.map +1 -0
- package/dist/src/session-command.d.ts +19 -0
- package/dist/src/session-command.d.ts.map +1 -0
- package/dist/src/session-command.js +20 -0
- package/dist/src/session-command.js.map +1 -0
- package/dist/src/settledread.d.ts +61 -0
- package/dist/src/settledread.d.ts.map +1 -0
- package/dist/src/settledread.js +135 -0
- package/dist/src/settledread.js.map +1 -0
- package/dist/src/severity.d.ts +167 -0
- package/dist/src/severity.d.ts.map +1 -0
- package/dist/src/severity.js +364 -0
- package/dist/src/severity.js.map +1 -0
- package/dist/src/severityrank.d.ts +8 -0
- package/dist/src/severityrank.d.ts.map +1 -0
- package/dist/src/severityrank.js +16 -0
- package/dist/src/severityrank.js.map +1 -0
- package/dist/src/standing-review.d.ts +45 -0
- package/dist/src/standing-review.d.ts.map +1 -0
- package/dist/src/standing-review.js +43 -0
- package/dist/src/standing-review.js.map +1 -0
- package/dist/src/storerows.d.ts +225 -0
- package/dist/src/storerows.d.ts.map +1 -0
- package/dist/src/storerows.js +7 -0
- package/dist/src/storerows.js.map +1 -0
- package/dist/src/styleguide.d.ts +25 -0
- package/dist/src/styleguide.d.ts.map +1 -0
- package/dist/src/styleguide.js +272 -0
- package/dist/src/styleguide.js.map +1 -0
- package/dist/src/sweepstatus.d.ts +42 -0
- package/dist/src/sweepstatus.d.ts.map +1 -0
- package/dist/src/sweepstatus.js +97 -0
- package/dist/src/sweepstatus.js.map +1 -0
- package/dist/src/templates.d.ts +243 -0
- package/dist/src/templates.d.ts.map +1 -0
- package/dist/src/templates.js +847 -0
- package/dist/src/templates.js.map +1 -0
- package/dist/src/types.d.ts +639 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +90 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/unifieddiff.d.ts +22 -0
- package/dist/src/unifieddiff.d.ts.map +1 -0
- package/dist/src/unifieddiff.js +176 -0
- package/dist/src/unifieddiff.js.map +1 -0
- package/dist/src/yieldloop.d.ts +2 -0
- package/dist/src/yieldloop.d.ts.map +1 -0
- package/dist/src/yieldloop.js +14 -0
- package/dist/src/yieldloop.js.map +1 -0
- package/package.json +60 -4
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Passive pi auth-failure detection: no smoke calls — watch the session
|
|
2
|
+
// JSONLs pi already writes and raise when sessions start failing with
|
|
3
|
+
// token-expired API errors. The live signature:
|
|
4
|
+
// "errorMessage":"Provided authentication token is expired."
|
|
5
|
+
// The scanner tail-reads recently-modified *.jsonl under the pi sessions dir
|
|
6
|
+
// (one nesting level: pi groups sessions by cwd) — cheap enough for a 60s
|
|
7
|
+
// tick, and entirely observational: it never talks to any API.
|
|
8
|
+
// Only a record's own `errorMessage` FIELD is tested — never the raw line:
|
|
9
|
+
// reviewer sessions store tool results verbatim (diffs, file reads, CI logs),
|
|
10
|
+
// and a PR touching OAuth code puts "invalid_grant" in them as plain text.
|
|
11
|
+
import { closeSync, openSync, readSync, readdirSync, statSync } from "node:fs";
|
|
12
|
+
import { join, sep } from "node:path";
|
|
13
|
+
export const PI_AUTH_ERROR_RE = /authentication token is expired|invalid_grant|401 unauthorized/i;
|
|
14
|
+
/** True when a JSONL line is a record carrying an auth-failure `errorMessage`
|
|
15
|
+
* field — at any depth, since a subagent's failed message arrives nested in
|
|
16
|
+
* its tool result. Text inside string values (tool output, quoted JSON) never
|
|
17
|
+
* matches: it is data, not a key. Non-JSON lines never match. */
|
|
18
|
+
export function lineHasAuthError(line) {
|
|
19
|
+
if (!line.includes("errorMessage"))
|
|
20
|
+
return false;
|
|
21
|
+
let record;
|
|
22
|
+
try {
|
|
23
|
+
record = JSON.parse(line);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const visit = (x, depth) => {
|
|
29
|
+
if (depth > 12 || typeof x !== "object" || x === null)
|
|
30
|
+
return false;
|
|
31
|
+
if (Array.isArray(x))
|
|
32
|
+
return x.some((y) => visit(y, depth + 1));
|
|
33
|
+
const r = x;
|
|
34
|
+
const msg = r["errorMessage"];
|
|
35
|
+
if (typeof msg === "string" && PI_AUTH_ERROR_RE.test(msg))
|
|
36
|
+
return true;
|
|
37
|
+
return Object.values(r).some((v) => visit(v, depth + 1));
|
|
38
|
+
};
|
|
39
|
+
return visit(record, 0);
|
|
40
|
+
}
|
|
41
|
+
/** Only the tail is read: session JSONLs grow large, and a live auth failure
|
|
42
|
+
* is by definition near the end of the file. */
|
|
43
|
+
export const AUTH_TAIL_BYTES = 128 * 1024;
|
|
44
|
+
/** The complete lines of `path` not yet scanned: from `from` (clamped into the
|
|
45
|
+
* last `bytes`) up to the last newline. Returns the text and the offset the
|
|
46
|
+
* NEXT read starts at — just past that newline, so a line still being written
|
|
47
|
+
* is read whole, exactly once, next time rather than split or counted twice. */
|
|
48
|
+
function readFrom(path, from, bytes) {
|
|
49
|
+
const fd = openSync(path, "r");
|
|
50
|
+
try {
|
|
51
|
+
const size = statSync(path).size;
|
|
52
|
+
// A file that shrank was rewritten: its old offset means nothing.
|
|
53
|
+
const start = Math.max(from > size ? 0 : from, size - bytes, 0);
|
|
54
|
+
const buf = Buffer.alloc(size - start);
|
|
55
|
+
readSync(fd, buf, 0, buf.length, start);
|
|
56
|
+
// Only COMPLETE lines are tested: a trailing partial line is left for the
|
|
57
|
+
// next scan, so testing it now too would count the same error twice.
|
|
58
|
+
const lastNl = buf.lastIndexOf(0x0a);
|
|
59
|
+
if (lastNl < 0)
|
|
60
|
+
return { text: "", next: start };
|
|
61
|
+
return { text: buf.subarray(0, lastNl + 1).toString("utf8"), next: start + lastNl + 1 };
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
closeSync(fd);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Scan *.jsonl files modified at/after `sinceMs` (dir + one sublevel) for
|
|
68
|
+
* auth-error signatures. Unreadable files are skipped — observation must
|
|
69
|
+
* never throw into the daemon tick — and counted (`scanPiAuth`'s `unread`),
|
|
70
|
+
* so a caller keeps them inside its next window.
|
|
71
|
+
*
|
|
72
|
+
* `seen` (path → byte offset, updated in place) makes the scan read only what
|
|
73
|
+
* was appended since the last scan, so an old error still inside the tail
|
|
74
|
+
* never matches again after a re-login and the flag can clear. A file not in
|
|
75
|
+
* `seen` is read tail-only.
|
|
76
|
+
*
|
|
77
|
+
* `seen` is also pruned: an entry under `sessionsDir` whose file
|
|
78
|
+
* the listing no longer shows — archived, or its whole session dir gone — is
|
|
79
|
+
* dropped, so the map tracks the live tree instead of every file that ever
|
|
80
|
+
* existed. Only a listing that answered prunes: an entry under a directory
|
|
81
|
+
* that could not be read stays (its file is unknown, never gone). */
|
|
82
|
+
export function scanPiAuthErrors(sessionsDir, sinceMs, seen) {
|
|
83
|
+
return scanPiAuth(sessionsDir, sinceMs, seen).hits;
|
|
84
|
+
}
|
|
85
|
+
/** `scanPiAuthErrors`, with how many observations failed (a directory that
|
|
86
|
+
* could not be listed, an entry that could not be stat'd, a file that could
|
|
87
|
+
* not be read): those were not seen, so they are not "quiet". */
|
|
88
|
+
function scanPiAuth(sessionsDir, sinceMs, seen) {
|
|
89
|
+
const hits = [];
|
|
90
|
+
let unread = 0;
|
|
91
|
+
/** Every path the listing showed, and the dirs it could not list. */
|
|
92
|
+
const present = new Set();
|
|
93
|
+
const unlisted = [];
|
|
94
|
+
const visit = (dir, depth) => {
|
|
95
|
+
let names = [];
|
|
96
|
+
try {
|
|
97
|
+
names = readdirSync(dir);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (err.code !== "ENOENT") {
|
|
101
|
+
unlisted.push(dir);
|
|
102
|
+
unread++;
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
for (const name of names) {
|
|
107
|
+
const path = join(dir, name);
|
|
108
|
+
present.add(path);
|
|
109
|
+
let st;
|
|
110
|
+
try {
|
|
111
|
+
st = statSync(path);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
// Gone since the listing: nothing to see. Anything else is unknown —
|
|
115
|
+
// its offsets (a directory's, or the file's own) are kept.
|
|
116
|
+
if (err.code !== "ENOENT") {
|
|
117
|
+
unlisted.push(path);
|
|
118
|
+
unread++;
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (st.isDirectory()) {
|
|
123
|
+
if (depth < 1)
|
|
124
|
+
visit(path, depth + 1);
|
|
125
|
+
else
|
|
126
|
+
unlisted.push(path); // deeper than the scan reads: unknown
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!name.endsWith(".jsonl") || st.mtimeMs < sinceMs)
|
|
130
|
+
continue;
|
|
131
|
+
try {
|
|
132
|
+
const { text, next } = readFrom(path, seen?.get(path) ?? 0, AUTH_TAIL_BYTES);
|
|
133
|
+
seen?.set(path, next);
|
|
134
|
+
if (text.split("\n").some(lineHasAuthError))
|
|
135
|
+
hits.push({ file: path, mtimeMs: st.mtimeMs });
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
unread++;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
visit(sessionsDir, 0);
|
|
143
|
+
if (seen) {
|
|
144
|
+
const under = `${sessionsDir}${sep}`;
|
|
145
|
+
for (const path of [...seen.keys()]) {
|
|
146
|
+
if (!path.startsWith(under) || present.has(path))
|
|
147
|
+
continue;
|
|
148
|
+
if (unlisted.some((d) => path === d || path.startsWith(`${d}${sep}`)))
|
|
149
|
+
continue;
|
|
150
|
+
seen.delete(path);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { hits, unread };
|
|
154
|
+
}
|
|
155
|
+
/** How long a detection keeps the status flag up with no fresh errors. */
|
|
156
|
+
export const AUTH_FLAG_FRESH_MS = 30 * 60 * 1000;
|
|
157
|
+
/**
|
|
158
|
+
* Stateful watcher for the daemon tick. Each scan covers files modified since
|
|
159
|
+
* the previous scan (first scan looks 10 minutes back). `status()` reports
|
|
160
|
+
* the flag while the last detection is fresh (< AUTH_FLAG_FRESH_MS) — the
|
|
161
|
+
* flag clears itself once the errors stop.
|
|
162
|
+
*/
|
|
163
|
+
export class PiAuthWatch {
|
|
164
|
+
now;
|
|
165
|
+
sinceMs;
|
|
166
|
+
lastErrorAt = null;
|
|
167
|
+
totalHits = 0;
|
|
168
|
+
/** Per-file offset already scanned — a match is a NEW error line, never an
|
|
169
|
+
* old one the tail still holds. */
|
|
170
|
+
seen = new Map();
|
|
171
|
+
sessionsDirs;
|
|
172
|
+
constructor(
|
|
173
|
+
/** One root, or several: each is scanned the same way (dir + one sublevel). */
|
|
174
|
+
sessionsDirs, now = () => new Date()) {
|
|
175
|
+
this.now = now;
|
|
176
|
+
this.sessionsDirs = typeof sessionsDirs === "string" ? [sessionsDirs] : [...sessionsDirs];
|
|
177
|
+
this.sinceMs = this.now().getTime() - 10 * 60 * 1000;
|
|
178
|
+
}
|
|
179
|
+
/** How many files the scan is tracking an offset for — the live tree's
|
|
180
|
+
* session files it has read, never every file that ever existed. */
|
|
181
|
+
trackedFiles() {
|
|
182
|
+
return this.seen.size;
|
|
183
|
+
}
|
|
184
|
+
/** Returns the NEW hits found this scan (empty array when quiet). */
|
|
185
|
+
scan() {
|
|
186
|
+
const started = this.now().getTime();
|
|
187
|
+
const scans = this.sessionsDirs.map((dir) => scanPiAuth(dir, this.sinceMs, this.seen));
|
|
188
|
+
const hits = scans.flatMap((x) => x.hits);
|
|
189
|
+
// Next scan starts at this scan's start, minus a minute of overlap so a
|
|
190
|
+
// write racing the scan is never missed; the per-file offsets keep the
|
|
191
|
+
// overlap from re-reading (and re-counting) bytes already scanned. A scan
|
|
192
|
+
// that could not read something keeps its window: what it missed stays
|
|
193
|
+
// eligible until a scan reads it (the offsets still stop a re-count).
|
|
194
|
+
if (scans.every((x) => x.unread === 0))
|
|
195
|
+
this.sinceMs = started - 60 * 1000;
|
|
196
|
+
if (hits.length > 0) {
|
|
197
|
+
this.lastErrorAt = started;
|
|
198
|
+
this.totalHits += hits.length;
|
|
199
|
+
}
|
|
200
|
+
return hits;
|
|
201
|
+
}
|
|
202
|
+
status() {
|
|
203
|
+
if (this.lastErrorAt === null)
|
|
204
|
+
return undefined;
|
|
205
|
+
if (this.now().getTime() - this.lastErrorAt > AUTH_FLAG_FRESH_MS)
|
|
206
|
+
return undefined;
|
|
207
|
+
return { last_at: new Date(this.lastErrorAt).toISOString(), hits: this.totalHits };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=authwatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authwatch.js","sourceRoot":"","sources":["../../src/authwatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Bounded<T> = {
|
|
2
|
+
kind: "done";
|
|
3
|
+
value: T;
|
|
4
|
+
} | {
|
|
5
|
+
kind: "budget";
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* `work`'s answer, or `{ kind: "budget" }` once `ms` has passed — whichever
|
|
9
|
+
* comes first; the timer is cleared either way and never holds the process
|
|
10
|
+
* open. The work is NOT cancelled (a read already in the kernel cannot be): it
|
|
11
|
+
* runs on, and its late answer or rejection is dropped. A rejection BEFORE the
|
|
12
|
+
* budget is the caller's to catch.
|
|
13
|
+
*/
|
|
14
|
+
export declare function withinBudget<T>(work: Promise<T>, ms: number): Promise<Bounded<T>>;
|
|
15
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/budget.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAgBvF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// A bounded wait. A round end waits for its transcripts and its
|
|
2
|
+
// integrity re-hash, and a dispatch for its integrity baseline, at most so
|
|
3
|
+
// long — then goes on without the answer. A filesystem read that never
|
|
4
|
+
// returns must cost a bounded wait and an honest "unknown", never a verdict
|
|
5
|
+
// that is not applied or a dispatch pump that never moves again.
|
|
6
|
+
/**
|
|
7
|
+
* `work`'s answer, or `{ kind: "budget" }` once `ms` has passed — whichever
|
|
8
|
+
* comes first; the timer is cleared either way and never holds the process
|
|
9
|
+
* open. The work is NOT cancelled (a read already in the kernel cannot be): it
|
|
10
|
+
* runs on, and its late answer or rejection is dropped. A rejection BEFORE the
|
|
11
|
+
* budget is the caller's to catch.
|
|
12
|
+
*/
|
|
13
|
+
export async function withinBudget(work, ms) {
|
|
14
|
+
let timer;
|
|
15
|
+
const budget = new Promise((resolve) => {
|
|
16
|
+
timer = setTimeout(() => resolve({ kind: "budget" }), Math.max(0, ms));
|
|
17
|
+
timer.unref?.();
|
|
18
|
+
});
|
|
19
|
+
// Keeps a loser's late rejection handled.
|
|
20
|
+
work.catch(() => undefined);
|
|
21
|
+
try {
|
|
22
|
+
return await Promise.race([
|
|
23
|
+
work.then((value) => ({ kind: "done", value })),
|
|
24
|
+
budget,
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
if (timer !== undefined)
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/budget.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,2EAA2E;AAC3E,uEAAuE;AACvE,4EAA4E;AAC5E,iEAAiE;AAIjE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,IAAgB,EAAE,EAAU;IAChE,IAAI,KAAgD,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;QACjD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACvE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,0CAA0C;IAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3D,MAAM;SACP,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casebudget.d.ts","sourceRoot":"","sources":["../../src/casebudget.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,OAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casebudget.js","sourceRoot":"","sources":["../../src/casebudget.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One check at a head, as GitHub's check-runs / statuses APIs report it.
|
|
3
|
+
*
|
|
4
|
+
* `source` says which of the two APIs it came from, and the adapter
|
|
5
|
+
* (`github.ts listChecks`) is its ONLY writer. It is the carrier the
|
|
6
|
+
* latest-run rule keys on: a check-run can supersede an older
|
|
7
|
+
* check-run of its name; a commit status never supersedes anything and is
|
|
8
|
+
* never superseded. Without the kind on the row, a status and a check-run of
|
|
9
|
+
* one name are told apart only by whether `started_at` happens to be set —
|
|
10
|
+
* and a check-run GitHub reports with a null start then reads as a status.
|
|
11
|
+
*/
|
|
12
|
+
export interface CheckSummary {
|
|
13
|
+
name: string;
|
|
14
|
+
/** `check_run` from the check-runs API; `status` from the combined status
|
|
15
|
+
* endpoint (which already dedupes statuses per context). */
|
|
16
|
+
source: "check_run" | "status";
|
|
17
|
+
/** `queued` | `in_progress` | `completed` (statuses map onto these). */
|
|
18
|
+
status: string;
|
|
19
|
+
/** `success` | `failure` | `cancelled` | `timed_out` | `skipped` | … */
|
|
20
|
+
conclusion: string | null;
|
|
21
|
+
/** When the run started — the recency key for latest-run-per-name
|
|
22
|
+
* among check-runs. Set on check-runs (nullable in GitHub's schema)
|
|
23
|
+
* and never on commit statuses: the adapter does not carry a time for
|
|
24
|
+
* them, and `latestRunPerName` does not collapse them at all. */
|
|
25
|
+
started_at?: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The four things CI can be at a head:
|
|
29
|
+
*
|
|
30
|
+
* - `green` every check completed and at least one really succeeded
|
|
31
|
+
* - `red` something completed badly — failure, cancelled, timed out,
|
|
32
|
+
* action_required, stale. No special-casing: an infra
|
|
33
|
+
* cancellation blocks exactly like a failing test.
|
|
34
|
+
* - `pending` a check is still queued or running — not green *yet*
|
|
35
|
+
* - `none` no check reported at this head at all
|
|
36
|
+
*/
|
|
37
|
+
export type CiState = "green" | "red" | "pending" | "none";
|
|
38
|
+
/**
|
|
39
|
+
* Only the most recent run of each check name counts. GitHub auto-cancels
|
|
40
|
+
* superseded workflow runs, leaving permanent `completed/cancelled` husks
|
|
41
|
+
* beside the run that actually finished; counting every run would classify
|
|
42
|
+
* such a head red forever and no withheld approval could ever release.
|
|
43
|
+
*
|
|
44
|
+
* The rule, exactly, keyed on `source`:
|
|
45
|
+
*
|
|
46
|
+
* - Only CHECK-RUNS collapse. Among check-runs of one name that carry a
|
|
47
|
+
* `started_at`, the latest start wins; an equal start resolves to the
|
|
48
|
+
* later list position. A check-run WITHOUT a timestamp (null in GitHub's
|
|
49
|
+
* schema) never competes with a timestamped one in either direction — it
|
|
50
|
+
* stands beside that name's latest timestamped run and counts on its own;
|
|
51
|
+
* among untimestamped check-runs of one name the later list position wins.
|
|
52
|
+
* A missing timestamp is unknown, never "older than everything".
|
|
53
|
+
* - A COMMIT STATUS is never collapsed with anything — not with a check-run
|
|
54
|
+
* of its name, not with another status. The combined status endpoint
|
|
55
|
+
* already dedupes per context, and a status under the same context as a
|
|
56
|
+
* check-run is a second check, not a superseded run.
|
|
57
|
+
*
|
|
58
|
+
* Why the kind and not the timestamp decides: collapsing a status with a
|
|
59
|
+
* same-named check-run lets one hide the other. A failing status could lose
|
|
60
|
+
* to a passing check-run, or an untimestamped check-run (queued, or failed
|
|
61
|
+
* with a null start) could lose to a passing status listed after it — either
|
|
62
|
+
* way red or pending reads green. `scripts/pr-checks.sh` reads check-runs and commit statuses and applies
|
|
63
|
+
* both clauses. Keep the two in step (`tests/fences-cigate.test.ts`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function latestRunPerName(checks: readonly CheckSummary[]): CheckSummary[];
|
|
66
|
+
/**
|
|
67
|
+
* Classify the checks at one head. Pure — both the gate guard and the shell
|
|
68
|
+
* mirror answer from this table, so "green" means the same thing on every
|
|
69
|
+
* posting route.
|
|
70
|
+
*
|
|
71
|
+
* A suite whose every check is skipped or neutral is not green: it reports
|
|
72
|
+
* `red`, because there is no evidence this PR's code passed anything.
|
|
73
|
+
*/
|
|
74
|
+
export declare function classifyCi(allChecks: readonly CheckSummary[]): CiState;
|
|
75
|
+
/**
|
|
76
|
+
* One check's outcome — the per-check half of `classifyCi`, and the one
|
|
77
|
+
* reading of a check anything else (the escalation's failing-check rule)
|
|
78
|
+
* may use. `failed` is every finished conclusion that is neither a success
|
|
79
|
+
* nor inert: failure, cancelled, timed_out, action_required, stale, …
|
|
80
|
+
*/
|
|
81
|
+
export declare function checkOutcome(c: CheckSummary): "pending" | "success" | "inert" | "failed";
|
|
82
|
+
/**
|
|
83
|
+
* Does this CI state make APPROVE unavailable?
|
|
84
|
+
*
|
|
85
|
+
* `none` blocks only when `noChecksIsRed` says so: in a repo that normally
|
|
86
|
+
* runs CI, a head with zero check-runs — a conflicted PR, or CI that has not
|
|
87
|
+
* started — carries no execution evidence, so approval waits for checks to
|
|
88
|
+
* appear and pass. The flag is off by default so a repo with no CI at all is
|
|
89
|
+
* never permanently wedged.
|
|
90
|
+
*/
|
|
91
|
+
export declare function ciBlocksApproval(state: CiState, opts?: {
|
|
92
|
+
noChecksIsRed?: boolean;
|
|
93
|
+
}): boolean;
|
|
94
|
+
/** Plain-words reason, for the note and the logs. */
|
|
95
|
+
export declare function ciStateReason(state: CiState): string;
|
|
96
|
+
/**
|
|
97
|
+
* The paragraph a withheld review carries. It says the two things the author
|
|
98
|
+
* needs — that the review is finished and found nothing blocking, and that the
|
|
99
|
+
* approval is waiting on CI and on nothing else — so the work is never
|
|
100
|
+
* invisible while CI is broken.
|
|
101
|
+
*/
|
|
102
|
+
export declare function withheldApprovalNote(state: CiState, headSha: string): string;
|
|
103
|
+
/** The review payload as it appears inside a `create_review` intent. */
|
|
104
|
+
export interface CiReviewBody {
|
|
105
|
+
commit_id?: string;
|
|
106
|
+
event?: string;
|
|
107
|
+
body?: string;
|
|
108
|
+
comments?: unknown[];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* APPROVE → COMMENT, findings untouched, with the withheld note appended.
|
|
112
|
+
* Never REQUEST_CHANGES: there is nothing for the author to change on the
|
|
113
|
+
* review's account, and the fault may be the base branch or infra.
|
|
114
|
+
*/
|
|
115
|
+
export declare function withholdApproval(body: CiReviewBody, state: CiState, headSha: string): CiReviewBody;
|
|
116
|
+
//# sourceMappingURL=cigate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cigate.d.ts","sourceRoot":"","sources":["../../src/cigate.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb;gEAC4D;IAC5D,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;qEAGiE;IACjE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;AAS3D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE,CAwBhF;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAatE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAOxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAGhG;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO5E;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,YAAY,CAMd"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Red CI hard-gates APPROVE.
|
|
2
|
+
//
|
|
3
|
+
// The rule: no green CI at this head ⇒ APPROVE is unavailable, regardless of
|
|
4
|
+
// findings. Infra problems block as well — deliberately simpler and stricter
|
|
5
|
+
// than judging whether a failure is attributable to the PR, because a rule
|
|
6
|
+
// that is argued case by case in prose makes the verdict depend on which
|
|
7
|
+
// reviewer ran. The code is still reviewed and the findings still posted;
|
|
8
|
+
// only the verdict is gated.
|
|
9
|
+
//
|
|
10
|
+
// Where the rule lives:
|
|
11
|
+
//
|
|
12
|
+
// round-*.md Decide step ─► the session withholds the approval itself and
|
|
13
|
+
// posts the full review as a COMMENT
|
|
14
|
+
// guards.ts (guard 4) ─► the gate rewrites an APPROVE review to COMMENT
|
|
15
|
+
// this module ─► the classifier both halves share
|
|
16
|
+
// ciretry.ts ─► the retry (the bot's half)
|
|
17
|
+
//
|
|
18
|
+
// The retry is what makes the gate safe: a PR whose approval is withheld needs
|
|
19
|
+
// something to notice when CI goes green, or an infra flake becomes a
|
|
20
|
+
// permanently stuck PR. `approval_withheld` (state.ts) is the mark, the
|
|
21
|
+
// `ci_completed` webhook is the trigger, and `retryWithheldApproval`
|
|
22
|
+
// (src/ciretry.ts) re-queues the PR so its session can decide again — at
|
|
23
|
+
// which point the approval is simply available.
|
|
24
|
+
//
|
|
25
|
+
// Nothing here triggers, re-runs or cancels CI: every call in this module is a
|
|
26
|
+
// GET, exactly as the no-exec policy requires (`gh pr checks` / `gh api` only).
|
|
27
|
+
/** Conclusions that are neither a success nor a failure: a path-filtered job
|
|
28
|
+
* skipped, an advisory check. They neither make CI green nor make it red. */
|
|
29
|
+
const INERT_CONCLUSIONS = new Set(["skipped", "neutral"]);
|
|
30
|
+
/** Not-yet-finished statuses. Anything else is treated as completed. */
|
|
31
|
+
const UNFINISHED = new Set(["queued", "in_progress", "waiting", "pending", "requested"]);
|
|
32
|
+
/**
|
|
33
|
+
* Only the most recent run of each check name counts. GitHub auto-cancels
|
|
34
|
+
* superseded workflow runs, leaving permanent `completed/cancelled` husks
|
|
35
|
+
* beside the run that actually finished; counting every run would classify
|
|
36
|
+
* such a head red forever and no withheld approval could ever release.
|
|
37
|
+
*
|
|
38
|
+
* The rule, exactly, keyed on `source`:
|
|
39
|
+
*
|
|
40
|
+
* - Only CHECK-RUNS collapse. Among check-runs of one name that carry a
|
|
41
|
+
* `started_at`, the latest start wins; an equal start resolves to the
|
|
42
|
+
* later list position. A check-run WITHOUT a timestamp (null in GitHub's
|
|
43
|
+
* schema) never competes with a timestamped one in either direction — it
|
|
44
|
+
* stands beside that name's latest timestamped run and counts on its own;
|
|
45
|
+
* among untimestamped check-runs of one name the later list position wins.
|
|
46
|
+
* A missing timestamp is unknown, never "older than everything".
|
|
47
|
+
* - A COMMIT STATUS is never collapsed with anything — not with a check-run
|
|
48
|
+
* of its name, not with another status. The combined status endpoint
|
|
49
|
+
* already dedupes per context, and a status under the same context as a
|
|
50
|
+
* check-run is a second check, not a superseded run.
|
|
51
|
+
*
|
|
52
|
+
* Why the kind and not the timestamp decides: collapsing a status with a
|
|
53
|
+
* same-named check-run lets one hide the other. A failing status could lose
|
|
54
|
+
* to a passing check-run, or an untimestamped check-run (queued, or failed
|
|
55
|
+
* with a null start) could lose to a passing status listed after it — either
|
|
56
|
+
* way red or pending reads green. `scripts/pr-checks.sh` reads check-runs and commit statuses and applies
|
|
57
|
+
* both clauses. Keep the two in step (`tests/fences-cigate.test.ts`).
|
|
58
|
+
*/
|
|
59
|
+
export function latestRunPerName(checks) {
|
|
60
|
+
const kept = [];
|
|
61
|
+
const timedRuns = new Map();
|
|
62
|
+
const untimedRuns = new Map();
|
|
63
|
+
checks.forEach((check, idx) => {
|
|
64
|
+
if (check.source !== "check_run") {
|
|
65
|
+
kept.push({ check, idx }); // a status is never collapsed, in either direction
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const at = check.started_at || null; // "" carries no time either
|
|
69
|
+
if (at === null) {
|
|
70
|
+
untimedRuns.set(check.name, { check, idx });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const prev = timedRuns.get(check.name);
|
|
74
|
+
if (!prev || at >= prev.at)
|
|
75
|
+
timedRuns.set(check.name, { check, idx, at });
|
|
76
|
+
});
|
|
77
|
+
return [...kept, ...timedRuns.values(), ...untimedRuns.values()]
|
|
78
|
+
.sort((x, y) => x.idx - y.idx)
|
|
79
|
+
.map((e) => e.check);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Classify the checks at one head. Pure — both the gate guard and the shell
|
|
83
|
+
* mirror answer from this table, so "green" means the same thing on every
|
|
84
|
+
* posting route.
|
|
85
|
+
*
|
|
86
|
+
* A suite whose every check is skipped or neutral is not green: it reports
|
|
87
|
+
* `red`, because there is no evidence this PR's code passed anything.
|
|
88
|
+
*/
|
|
89
|
+
export function classifyCi(allChecks) {
|
|
90
|
+
const checks = latestRunPerName(allChecks);
|
|
91
|
+
if (checks.length === 0)
|
|
92
|
+
return "none";
|
|
93
|
+
let pending = false;
|
|
94
|
+
let succeeded = false;
|
|
95
|
+
for (const c of checks) {
|
|
96
|
+
const outcome = checkOutcome(c);
|
|
97
|
+
if (outcome === "failed")
|
|
98
|
+
return "red";
|
|
99
|
+
if (outcome === "pending")
|
|
100
|
+
pending = true;
|
|
101
|
+
if (outcome === "success")
|
|
102
|
+
succeeded = true;
|
|
103
|
+
}
|
|
104
|
+
if (pending)
|
|
105
|
+
return "pending";
|
|
106
|
+
return succeeded ? "green" : "red";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* One check's outcome — the per-check half of `classifyCi`, and the one
|
|
110
|
+
* reading of a check anything else (the escalation's failing-check rule)
|
|
111
|
+
* may use. `failed` is every finished conclusion that is neither a success
|
|
112
|
+
* nor inert: failure, cancelled, timed_out, action_required, stale, …
|
|
113
|
+
*/
|
|
114
|
+
export function checkOutcome(c) {
|
|
115
|
+
const status = (c.status ?? "").toLowerCase();
|
|
116
|
+
const conclusion = (c.conclusion ?? "").toLowerCase();
|
|
117
|
+
if (UNFINISHED.has(status) || (status !== "completed" && conclusion === ""))
|
|
118
|
+
return "pending";
|
|
119
|
+
if (conclusion === "success")
|
|
120
|
+
return "success";
|
|
121
|
+
if (INERT_CONCLUSIONS.has(conclusion))
|
|
122
|
+
return "inert";
|
|
123
|
+
return "failed";
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Does this CI state make APPROVE unavailable?
|
|
127
|
+
*
|
|
128
|
+
* `none` blocks only when `noChecksIsRed` says so: in a repo that normally
|
|
129
|
+
* runs CI, a head with zero check-runs — a conflicted PR, or CI that has not
|
|
130
|
+
* started — carries no execution evidence, so approval waits for checks to
|
|
131
|
+
* appear and pass. The flag is off by default so a repo with no CI at all is
|
|
132
|
+
* never permanently wedged.
|
|
133
|
+
*/
|
|
134
|
+
export function ciBlocksApproval(state, opts = {}) {
|
|
135
|
+
if (state === "none")
|
|
136
|
+
return opts.noChecksIsRed === true;
|
|
137
|
+
return state === "red" || state === "pending";
|
|
138
|
+
}
|
|
139
|
+
/** Plain-words reason, for the note and the logs. */
|
|
140
|
+
export function ciStateReason(state) {
|
|
141
|
+
switch (state) {
|
|
142
|
+
case "red":
|
|
143
|
+
return "CI is not green at this head";
|
|
144
|
+
case "pending":
|
|
145
|
+
return "CI has not finished at this head";
|
|
146
|
+
case "green":
|
|
147
|
+
return "CI is green at this head";
|
|
148
|
+
case "none":
|
|
149
|
+
return "no CI reported at this head";
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The paragraph a withheld review carries. It says the two things the author
|
|
154
|
+
* needs — that the review is finished and found nothing blocking, and that the
|
|
155
|
+
* approval is waiting on CI and on nothing else — so the work is never
|
|
156
|
+
* invisible while CI is broken.
|
|
157
|
+
*/
|
|
158
|
+
export function withheldApprovalNote(state, headSha) {
|
|
159
|
+
return (`_**No blockers were found in this review.** Approval is withheld because ` +
|
|
160
|
+
`${ciStateReason(state)} (\`${headSha.slice(0, 7)}\`) — nothing above asks you to change anything, ` +
|
|
161
|
+
"and the failures may well be infrastructure or the base branch rather than this PR. " +
|
|
162
|
+
"The approval is waiting on green CI alone, and is re-attempted automatically once CI is green at this head._");
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* APPROVE → COMMENT, findings untouched, with the withheld note appended.
|
|
166
|
+
* Never REQUEST_CHANGES: there is nothing for the author to change on the
|
|
167
|
+
* review's account, and the fault may be the base branch or infra.
|
|
168
|
+
*/
|
|
169
|
+
export function withholdApproval(body, state, headSha) {
|
|
170
|
+
return {
|
|
171
|
+
...body,
|
|
172
|
+
event: "COMMENT",
|
|
173
|
+
body: `${body.body ?? ""}\n\n${withheldApprovalNote(state, headSha)}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=cigate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cigate.js","sourceRoot":"","sources":["../../src/cigate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author-controlled text rendered as Markdown DATA. A leaf module (no imports)
|
|
3
|
+
* so any renderer can use it without pulling in the prompt templates — the
|
|
4
|
+
* round prompts (`templates.ts`) and the escalation note (`escalation.ts`)
|
|
5
|
+
* both render repository paths, and both must keep them literal.
|
|
6
|
+
*/
|
|
7
|
+
/** The longest run of backticks in `text` (0 when none) — what a fence or a
|
|
8
|
+
* code span must out-length so nothing inside can close it (CommonMark). */
|
|
9
|
+
export declare function longestBacktickRun(text: string): number;
|
|
10
|
+
/** The backtick fence for a block of `text`: one longer than any backtick run
|
|
11
|
+
* inside it, and at least three, so nothing inside can close it. */
|
|
12
|
+
export declare function backtickFence(text: string): string;
|
|
13
|
+
/** Control characters (newlines included) as visible `\\uXXXX` escapes, so
|
|
14
|
+
* author-controlled text can never start a new line of prompt. */
|
|
15
|
+
export declare function flatControls(text: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* A repository path as an inline code span that stays DATA. Git paths may hold
|
|
18
|
+
* backticks, pipes and newlines, and they are author-controlled: rendered raw
|
|
19
|
+
* they could close the span, split a plan-table row, or open a new line of
|
|
20
|
+
* daemon-authored prompt text. Control characters are shown as `\uXXXX`,
|
|
21
|
+
* and the fence is one backtick longer than any run inside the name
|
|
22
|
+
* (CommonMark), padded with a space when CommonMark would otherwise strip one
|
|
23
|
+
* of the name's own, so the name reads back exactly otherwise. Pipes are escaped
|
|
24
|
+
* only for a TABLE cell (`table`): GFM un-escapes `\|` there, even inside a
|
|
25
|
+
* code span, but everywhere else the backslash would read back as part of
|
|
26
|
+
* the path.
|
|
27
|
+
*/
|
|
28
|
+
export declare function codePath(path: string, opts?: {
|
|
29
|
+
table?: boolean;
|
|
30
|
+
}): string;
|
|
31
|
+
/**
|
|
32
|
+
* Author-derived text quoted inside a daemon-authored `("…")` in prompt text.
|
|
33
|
+
* It must not be able to close that quotation or start a new line of
|
|
34
|
+
* instructions: control characters collapse to a space and a double quote
|
|
35
|
+
* becomes a single one. No length cap — the caller owns the length (the round
|
|
36
|
+
* memory query is clamped at its own 600-character budget, and quoting it
|
|
37
|
+
* must not silently cut what the daemon actually asked).
|
|
38
|
+
*/
|
|
39
|
+
export declare function promptQuoted(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* A PR title quoted inside daemon-authored prompt text (`("{{title}}")` in the
|
|
42
|
+
* conversation system prompt and the round templates): `promptQuoted`, capped
|
|
43
|
+
* at 256 characters as GitHub caps titles.
|
|
44
|
+
*/
|
|
45
|
+
export declare function promptTitle(title: string): string;
|
|
46
|
+
//# sourceMappingURL=codespan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codespan.d.ts","sourceRoot":"","sources":["../../src/codespan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;4EAC4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;oEACoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAQD;kEACkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAU7E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|