agent-bober 0.12.0 → 0.15.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/CHANGELOG.md +213 -0
- package/README.md +112 -3
- package/agents/bober-architect.md +38 -0
- package/agents/bober-code-reviewer.md +236 -0
- package/agents/bober-curator.md +37 -0
- package/agents/bober-deployer.md +267 -0
- package/agents/bober-diagnoser.md +289 -0
- package/agents/bober-evaluator.md +89 -1
- package/agents/bober-generator.md +68 -3
- package/agents/bober-planner.md +39 -0
- package/agents/bober-postmortemer.md +185 -0
- package/agents/bober-researcher.md +38 -0
- package/dist/cli/commands/approve.d.ts +17 -0
- package/dist/cli/commands/approve.d.ts.map +1 -0
- package/dist/cli/commands/approve.js +64 -0
- package/dist/cli/commands/approve.js.map +1 -0
- package/dist/cli/commands/audit-show.d.ts +14 -0
- package/dist/cli/commands/audit-show.d.ts.map +1 -0
- package/dist/cli/commands/audit-show.js +85 -0
- package/dist/cli/commands/audit-show.js.map +1 -0
- package/dist/cli/commands/config.d.ts +10 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +73 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/graph.d.ts +8 -0
- package/dist/cli/commands/graph.d.ts.map +1 -0
- package/dist/cli/commands/graph.js +219 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +19 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +191 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/incident.d.ts +19 -0
- package/dist/cli/commands/incident.d.ts.map +1 -0
- package/dist/cli/commands/incident.js +324 -0
- package/dist/cli/commands/incident.js.map +1 -0
- package/dist/cli/commands/init.js +36 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/list-approvals.d.ts +16 -0
- package/dist/cli/commands/list-approvals.d.ts.map +1 -0
- package/dist/cli/commands/list-approvals.js +57 -0
- package/dist/cli/commands/list-approvals.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +3 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +190 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/playbook.d.ts +17 -0
- package/dist/cli/commands/playbook.d.ts.map +1 -0
- package/dist/cli/commands/playbook.js +123 -0
- package/dist/cli/commands/playbook.js.map +1 -0
- package/dist/cli/commands/postmortem.d.ts +12 -0
- package/dist/cli/commands/postmortem.d.ts.map +1 -0
- package/dist/cli/commands/postmortem.js +67 -0
- package/dist/cli/commands/postmortem.js.map +1 -0
- package/dist/cli/commands/reject.d.ts +17 -0
- package/dist/cli/commands/reject.d.ts.map +1 -0
- package/dist/cli/commands/reject.js +52 -0
- package/dist/cli/commands/reject.js.map +1 -0
- package/dist/cli/commands/rollback.d.ts +21 -0
- package/dist/cli/commands/rollback.d.ts.map +1 -0
- package/dist/cli/commands/rollback.js +90 -0
- package/dist/cli/commands/rollback.js.map +1 -0
- package/dist/cli/commands/run.d.ts +9 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +29 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/telemetry.d.ts +16 -0
- package/dist/cli/commands/telemetry.d.ts.map +1 -0
- package/dist/cli/commands/telemetry.js +152 -0
- package/dist/cli/commands/telemetry.js.map +1 -0
- package/dist/cli/commands/worktree.d.ts +12 -0
- package/dist/cli/commands/worktree.d.ts.map +1 -0
- package/dist/cli/commands/worktree.js +57 -0
- package/dist/cli/commands/worktree.js.map +1 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +27 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +18 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +976 -56
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +147 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/graph/artifact-store.d.ts +14 -0
- package/dist/graph/artifact-store.d.ts.map +1 -0
- package/dist/graph/artifact-store.js +100 -0
- package/dist/graph/artifact-store.js.map +1 -0
- package/dist/graph/cli.d.ts +49 -0
- package/dist/graph/cli.d.ts.map +1 -0
- package/dist/graph/cli.js +140 -0
- package/dist/graph/cli.js.map +1 -0
- package/dist/graph/client.d.ts +64 -0
- package/dist/graph/client.d.ts.map +1 -0
- package/dist/graph/client.js +216 -0
- package/dist/graph/client.js.map +1 -0
- package/dist/graph/fallback.d.ts +13 -0
- package/dist/graph/fallback.d.ts.map +1 -0
- package/dist/graph/fallback.js +57 -0
- package/dist/graph/fallback.js.map +1 -0
- package/dist/graph/hook-handler.d.ts +50 -0
- package/dist/graph/hook-handler.d.ts.map +1 -0
- package/dist/graph/hook-handler.js +217 -0
- package/dist/graph/hook-handler.js.map +1 -0
- package/dist/graph/incidents.d.ts +59 -0
- package/dist/graph/incidents.d.ts.map +1 -0
- package/dist/graph/incidents.js +22 -0
- package/dist/graph/incidents.js.map +1 -0
- package/dist/graph/mcp-client.d.ts +51 -0
- package/dist/graph/mcp-client.d.ts.map +1 -0
- package/dist/graph/mcp-client.js +285 -0
- package/dist/graph/mcp-client.js.map +1 -0
- package/dist/graph/onboarding-composer.d.ts +30 -0
- package/dist/graph/onboarding-composer.d.ts.map +1 -0
- package/dist/graph/onboarding-composer.js +275 -0
- package/dist/graph/onboarding-composer.js.map +1 -0
- package/dist/graph/pipeline-lifecycle.d.ts +86 -0
- package/dist/graph/pipeline-lifecycle.d.ts.map +1 -0
- package/dist/graph/pipeline-lifecycle.js +329 -0
- package/dist/graph/pipeline-lifecycle.js.map +1 -0
- package/dist/graph/preflight-budgets.d.ts +52 -0
- package/dist/graph/preflight-budgets.d.ts.map +1 -0
- package/dist/graph/preflight-budgets.js +78 -0
- package/dist/graph/preflight-budgets.js.map +1 -0
- package/dist/graph/preflight-injector.d.ts +116 -0
- package/dist/graph/preflight-injector.d.ts.map +1 -0
- package/dist/graph/preflight-injector.js +538 -0
- package/dist/graph/preflight-injector.js.map +1 -0
- package/dist/graph/prereq.d.ts +12 -0
- package/dist/graph/prereq.d.ts.map +1 -0
- package/dist/graph/prereq.js +61 -0
- package/dist/graph/prereq.js.map +1 -0
- package/dist/graph/prompts.d.ts +42 -0
- package/dist/graph/prompts.d.ts.map +1 -0
- package/dist/graph/prompts.js +80 -0
- package/dist/graph/prompts.js.map +1 -0
- package/dist/graph/sandbox.d.ts +19 -0
- package/dist/graph/sandbox.d.ts.map +1 -0
- package/dist/graph/sandbox.js +25 -0
- package/dist/graph/sandbox.js.map +1 -0
- package/dist/graph/token-usage.d.ts +21 -0
- package/dist/graph/token-usage.d.ts.map +1 -0
- package/dist/graph/token-usage.js +22 -0
- package/dist/graph/token-usage.js.map +1 -0
- package/dist/graph/types.d.ts +129 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +12 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/incident/orchestrator.d.ts +168 -0
- package/dist/incident/orchestrator.d.ts.map +1 -0
- package/dist/incident/orchestrator.js +279 -0
- package/dist/incident/orchestrator.js.map +1 -0
- package/dist/incident/playbook-search.d.ts +67 -0
- package/dist/incident/playbook-search.d.ts.map +1 -0
- package/dist/incident/playbook-search.js +288 -0
- package/dist/incident/playbook-search.js.map +1 -0
- package/dist/incident/postmortem.d.ts +44 -0
- package/dist/incident/postmortem.d.ts.map +1 -0
- package/dist/incident/postmortem.js +486 -0
- package/dist/incident/postmortem.js.map +1 -0
- package/dist/incident/resolution-verify.d.ts +186 -0
- package/dist/incident/resolution-verify.d.ts.map +1 -0
- package/dist/incident/resolution-verify.js +210 -0
- package/dist/incident/resolution-verify.js.map +1 -0
- package/dist/incident/rollback.d.ts +137 -0
- package/dist/incident/rollback.d.ts.map +1 -0
- package/dist/incident/rollback.js +328 -0
- package/dist/incident/rollback.js.map +1 -0
- package/dist/incident/timeline.d.ts +147 -0
- package/dist/incident/timeline.d.ts.map +1 -0
- package/dist/incident/timeline.js +452 -0
- package/dist/incident/timeline.js.map +1 -0
- package/dist/incident/types.d.ts +335 -0
- package/dist/incident/types.d.ts.map +1 -0
- package/dist/incident/types.js +158 -0
- package/dist/incident/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/event-stream.d.ts +46 -0
- package/dist/mcp/event-stream.d.ts.map +1 -0
- package/dist/mcp/event-stream.js +421 -0
- package/dist/mcp/event-stream.js.map +1 -0
- package/dist/mcp/external-client.d.ts +38 -0
- package/dist/mcp/external-client.d.ts.map +1 -0
- package/dist/mcp/external-client.js +121 -0
- package/dist/mcp/external-client.js.map +1 -0
- package/dist/mcp/run-manager.d.ts +74 -9
- package/dist/mcp/run-manager.d.ts.map +1 -1
- package/dist/mcp/run-manager.js +127 -31
- package/dist/mcp/run-manager.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +56 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/abort-run.d.ts +2 -0
- package/dist/mcp/tools/abort-run.d.ts.map +1 -0
- package/dist/mcp/tools/abort-run.js +62 -0
- package/dist/mcp/tools/abort-run.js.map +1 -0
- package/dist/mcp/tools/anchor.js +1 -1
- package/dist/mcp/tools/anchor.js.map +1 -1
- package/dist/mcp/tools/approve-checkpoint.d.ts +2 -0
- package/dist/mcp/tools/approve-checkpoint.d.ts.map +1 -0
- package/dist/mcp/tools/approve-checkpoint.js +70 -0
- package/dist/mcp/tools/approve-checkpoint.js.map +1 -0
- package/dist/mcp/tools/brownfield.js +1 -1
- package/dist/mcp/tools/brownfield.js.map +1 -1
- package/dist/mcp/tools/get-project-state.d.ts +2 -0
- package/dist/mcp/tools/get-project-state.d.ts.map +1 -0
- package/dist/mcp/tools/get-project-state.js +107 -0
- package/dist/mcp/tools/get-project-state.js.map +1 -0
- package/dist/mcp/tools/get-run-status.d.ts +2 -0
- package/dist/mcp/tools/get-run-status.d.ts.map +1 -0
- package/dist/mcp/tools/get-run-status.js +40 -0
- package/dist/mcp/tools/get-run-status.js.map +1 -0
- package/dist/mcp/tools/graph-schemas.d.ts +100 -0
- package/dist/mcp/tools/graph-schemas.d.ts.map +1 -0
- package/dist/mcp/tools/graph-schemas.js +39 -0
- package/dist/mcp/tools/graph-schemas.js.map +1 -0
- package/dist/mcp/tools/graph.d.ts +19 -0
- package/dist/mcp/tools/graph.d.ts.map +1 -0
- package/dist/mcp/tools/graph.js +263 -0
- package/dist/mcp/tools/graph.js.map +1 -0
- package/dist/mcp/tools/incident.d.ts +2 -0
- package/dist/mcp/tools/incident.d.ts.map +1 -0
- package/dist/mcp/tools/incident.js +246 -0
- package/dist/mcp/tools/incident.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +38 -18
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +74 -18
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/list-active-runs.d.ts +2 -0
- package/dist/mcp/tools/list-active-runs.d.ts.map +1 -0
- package/dist/mcp/tools/list-active-runs.js +35 -0
- package/dist/mcp/tools/list-active-runs.js.map +1 -0
- package/dist/mcp/tools/list-pending-approvals.d.ts +2 -0
- package/dist/mcp/tools/list-pending-approvals.d.ts.map +1 -0
- package/dist/mcp/tools/list-pending-approvals.js +40 -0
- package/dist/mcp/tools/list-pending-approvals.js.map +1 -0
- package/dist/mcp/tools/list-projects.d.ts +2 -0
- package/dist/mcp/tools/list-projects.d.ts.map +1 -0
- package/dist/mcp/tools/list-projects.js +101 -0
- package/dist/mcp/tools/list-projects.js.map +1 -0
- package/dist/mcp/tools/list-specs.d.ts +2 -0
- package/dist/mcp/tools/list-specs.d.ts.map +1 -0
- package/dist/mcp/tools/list-specs.js +48 -0
- package/dist/mcp/tools/list-specs.js.map +1 -0
- package/dist/mcp/tools/playbook.d.ts +2 -0
- package/dist/mcp/tools/playbook.d.ts.map +1 -0
- package/dist/mcp/tools/playbook.js +104 -0
- package/dist/mcp/tools/playbook.js.map +1 -0
- package/dist/mcp/tools/postmortem.d.ts +2 -0
- package/dist/mcp/tools/postmortem.d.ts.map +1 -0
- package/dist/mcp/tools/postmortem.js +75 -0
- package/dist/mcp/tools/postmortem.js.map +1 -0
- package/dist/mcp/tools/react.js +1 -1
- package/dist/mcp/tools/react.js.map +1 -1
- package/dist/mcp/tools/reject-checkpoint.d.ts +2 -0
- package/dist/mcp/tools/reject-checkpoint.d.ts.map +1 -0
- package/dist/mcp/tools/reject-checkpoint.js +79 -0
- package/dist/mcp/tools/reject-checkpoint.js.map +1 -0
- package/dist/mcp/tools/rollback.d.ts +2 -0
- package/dist/mcp/tools/rollback.d.ts.map +1 -0
- package/dist/mcp/tools/rollback.js +78 -0
- package/dist/mcp/tools/rollback.js.map +1 -0
- package/dist/mcp/tools/run-in-worktree.d.ts +2 -0
- package/dist/mcp/tools/run-in-worktree.d.ts.map +1 -0
- package/dist/mcp/tools/run-in-worktree.js +90 -0
- package/dist/mcp/tools/run-in-worktree.js.map +1 -0
- package/dist/mcp/tools/run.js +1 -1
- package/dist/mcp/tools/run.js.map +1 -1
- package/dist/mcp/tools/solidity.js +1 -1
- package/dist/mcp/tools/solidity.js.map +1 -1
- package/dist/mcp/tools/status.d.ts.map +1 -1
- package/dist/mcp/tools/status.js +11 -0
- package/dist/mcp/tools/status.js.map +1 -1
- package/dist/mcp/tools/subscribe-events.d.ts +2 -0
- package/dist/mcp/tools/subscribe-events.d.ts.map +1 -0
- package/dist/mcp/tools/subscribe-events.js +48 -0
- package/dist/mcp/tools/subscribe-events.js.map +1 -0
- package/dist/mcp/tools/unsubscribe-events.d.ts +2 -0
- package/dist/mcp/tools/unsubscribe-events.d.ts.map +1 -0
- package/dist/mcp/tools/unsubscribe-events.js +45 -0
- package/dist/mcp/tools/unsubscribe-events.js.map +1 -0
- package/dist/orchestrator/agent-loader.d.ts +16 -0
- package/dist/orchestrator/agent-loader.d.ts.map +1 -1
- package/dist/orchestrator/agent-loader.js +16 -0
- package/dist/orchestrator/agent-loader.js.map +1 -1
- package/dist/orchestrator/architect-agent.d.ts.map +1 -1
- package/dist/orchestrator/architect-agent.js +37 -8
- package/dist/orchestrator/architect-agent.js.map +1 -1
- package/dist/orchestrator/checkpoints/audit.d.ts +128 -0
- package/dist/orchestrator/checkpoints/audit.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/audit.js +272 -0
- package/dist/orchestrator/checkpoints/audit.js.map +1 -0
- package/dist/orchestrator/checkpoints/feedback-router.d.ts +213 -0
- package/dist/orchestrator/checkpoints/feedback-router.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/feedback-router.js +438 -0
- package/dist/orchestrator/checkpoints/feedback-router.js.map +1 -0
- package/dist/orchestrator/checkpoints/index.d.ts +11 -0
- package/dist/orchestrator/checkpoints/index.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/index.js +12 -0
- package/dist/orchestrator/checkpoints/index.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.d.ts +35 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.js +153 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.d.ts +34 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.js +139 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.d.ts +141 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.js +445 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.js.map +1 -0
- package/dist/orchestrator/checkpoints/noop.d.ts +12 -0
- package/dist/orchestrator/checkpoints/noop.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/noop.js +13 -0
- package/dist/orchestrator/checkpoints/noop.js.map +1 -0
- package/dist/orchestrator/checkpoints/registry.d.ts +48 -0
- package/dist/orchestrator/checkpoints/registry.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/registry.js +89 -0
- package/dist/orchestrator/checkpoints/registry.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/_util.d.ts +50 -0
- package/dist/orchestrator/checkpoints/renderers/_util.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/_util.js +137 -0
- package/dist/orchestrator/checkpoints/renderers/_util.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.js +66 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.js +40 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.js +54 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.d.ts +49 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.js +154 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.js +59 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/plan.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/plan.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/plan.js +34 -0
- package/dist/orchestrator/checkpoints/renderers/plan.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/registry.d.ts +43 -0
- package/dist/orchestrator/checkpoints/renderers/registry.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/registry.js +83 -0
- package/dist/orchestrator/checkpoints/renderers/registry.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/research.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/research.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/research.js +39 -0
- package/dist/orchestrator/checkpoints/renderers/research.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.d.ts +20 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.js +57 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.js +38 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.js.map +1 -0
- package/dist/orchestrator/checkpoints/sites.d.ts +22 -0
- package/dist/orchestrator/checkpoints/sites.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/sites.js +57 -0
- package/dist/orchestrator/checkpoints/sites.js.map +1 -0
- package/dist/orchestrator/checkpoints/types.d.ts +51 -0
- package/dist/orchestrator/checkpoints/types.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/types.js +9 -0
- package/dist/orchestrator/checkpoints/types.js.map +1 -0
- package/dist/orchestrator/code-reviewer-agent.d.ts +50 -0
- package/dist/orchestrator/code-reviewer-agent.d.ts.map +1 -0
- package/dist/orchestrator/code-reviewer-agent.js +283 -0
- package/dist/orchestrator/code-reviewer-agent.js.map +1 -0
- package/dist/orchestrator/curator-agent.d.ts.map +1 -1
- package/dist/orchestrator/curator-agent.js +59 -8
- package/dist/orchestrator/curator-agent.js.map +1 -1
- package/dist/orchestrator/deploy/classify.d.ts +31 -0
- package/dist/orchestrator/deploy/classify.d.ts.map +1 -0
- package/dist/orchestrator/deploy/classify.js +109 -0
- package/dist/orchestrator/deploy/classify.js.map +1 -0
- package/dist/orchestrator/deploy/execute.d.ts +45 -0
- package/dist/orchestrator/deploy/execute.d.ts.map +1 -0
- package/dist/orchestrator/deploy/execute.js +146 -0
- package/dist/orchestrator/deploy/execute.js.map +1 -0
- package/dist/orchestrator/deploy/executor.d.ts +22 -0
- package/dist/orchestrator/deploy/executor.d.ts.map +1 -0
- package/dist/orchestrator/deploy/executor.js +31 -0
- package/dist/orchestrator/deploy/executor.js.map +1 -0
- package/dist/orchestrator/deploy/index.d.ts +21 -0
- package/dist/orchestrator/deploy/index.d.ts.map +1 -0
- package/dist/orchestrator/deploy/index.js +21 -0
- package/dist/orchestrator/deploy/index.js.map +1 -0
- package/dist/orchestrator/deploy/resolve.d.ts +51 -0
- package/dist/orchestrator/deploy/resolve.d.ts.map +1 -0
- package/dist/orchestrator/deploy/resolve.js +53 -0
- package/dist/orchestrator/deploy/resolve.js.map +1 -0
- package/dist/orchestrator/deploy/spawn.d.ts +60 -0
- package/dist/orchestrator/deploy/spawn.d.ts.map +1 -0
- package/dist/orchestrator/deploy/spawn.js +62 -0
- package/dist/orchestrator/deploy/spawn.js.map +1 -0
- package/dist/orchestrator/deploy/types.d.ts +98 -0
- package/dist/orchestrator/deploy/types.d.ts.map +1 -0
- package/dist/orchestrator/deploy/types.js +39 -0
- package/dist/orchestrator/deploy/types.js.map +1 -0
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -1
- package/dist/orchestrator/evaluator-agent.js +21 -8
- package/dist/orchestrator/evaluator-agent.js.map +1 -1
- package/dist/orchestrator/generator-agent.d.ts.map +1 -1
- package/dist/orchestrator/generator-agent.js +21 -8
- package/dist/orchestrator/generator-agent.js.map +1 -1
- package/dist/orchestrator/model-resolver.d.ts.map +1 -1
- package/dist/orchestrator/model-resolver.js +3 -1
- package/dist/orchestrator/model-resolver.js.map +1 -1
- package/dist/orchestrator/observability/index.d.ts +12 -0
- package/dist/orchestrator/observability/index.d.ts.map +1 -0
- package/dist/orchestrator/observability/index.js +12 -0
- package/dist/orchestrator/observability/index.js.map +1 -0
- package/dist/orchestrator/observability/merge.d.ts +73 -0
- package/dist/orchestrator/observability/merge.d.ts.map +1 -0
- package/dist/orchestrator/observability/merge.js +110 -0
- package/dist/orchestrator/observability/merge.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts +21 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +156 -2
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/planner-agent.d.ts.map +1 -1
- package/dist/orchestrator/planner-agent.js +5 -4
- package/dist/orchestrator/planner-agent.js.map +1 -1
- package/dist/orchestrator/research-agent.d.ts.map +1 -1
- package/dist/orchestrator/research-agent.js +46 -9
- package/dist/orchestrator/research-agent.js.map +1 -1
- package/dist/orchestrator/tools/handlers.d.ts +2 -0
- package/dist/orchestrator/tools/handlers.d.ts.map +1 -1
- package/dist/orchestrator/tools/handlers.js +1 -1
- package/dist/orchestrator/tools/handlers.js.map +1 -1
- package/dist/orchestrator/tools/index.d.ts +84 -1
- package/dist/orchestrator/tools/index.d.ts.map +1 -1
- package/dist/orchestrator/tools/index.js +164 -1
- package/dist/orchestrator/tools/index.js.map +1 -1
- package/dist/orchestrator/worktree.d.ts +18 -0
- package/dist/orchestrator/worktree.d.ts.map +1 -0
- package/dist/orchestrator/worktree.js +129 -0
- package/dist/orchestrator/worktree.js.map +1 -0
- package/dist/providers/anthropic.d.ts +8 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +86 -5
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +35 -2
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +5 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +4 -0
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/types.d.ts +25 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/state/approval-state.d.ts +74 -0
- package/dist/state/approval-state.d.ts.map +1 -0
- package/dist/state/approval-state.js +127 -0
- package/dist/state/approval-state.js.map +1 -0
- package/dist/state/index.d.ts +3 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +4 -1
- package/dist/state/index.js.map +1 -1
- package/dist/state/review-state.d.ts +15 -0
- package/dist/state/review-state.d.ts.map +1 -0
- package/dist/state/review-state.js +51 -0
- package/dist/state/review-state.js.map +1 -0
- package/dist/state/run-state.d.ts +39 -0
- package/dist/state/run-state.d.ts.map +1 -0
- package/dist/state/run-state.js +101 -0
- package/dist/state/run-state.js.map +1 -0
- package/dist/telemetry/emit.d.ts +41 -0
- package/dist/telemetry/emit.d.ts.map +1 -0
- package/dist/telemetry/emit.js +65 -0
- package/dist/telemetry/emit.js.map +1 -0
- package/dist/utils/git.d.ts +27 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +50 -0
- package/dist/utils/git.js.map +1 -1
- package/hooks/hooks.json +17 -1
- package/hooks/session-start +42 -0
- package/package.json +5 -2
- package/scripts/check-prereqs.sh +12 -0
- package/scripts/e2e-graph-smoke.sh +167 -0
- package/scripts/graph-hook.mjs +151 -0
- package/scripts/run-kpi-gate.mjs +245 -0
- package/scripts/sync-skills.mjs +4 -1
- package/skills/bober.code-review/SKILL.md +186 -0
- package/skills/bober.debug/SKILL.md +300 -0
- package/skills/bober.deploy/SKILL.md +262 -0
- package/skills/bober.diagnose/SKILL.md +254 -0
- package/skills/bober.graph/SKILL.md +85 -0
- package/skills/bober.impact/SKILL.md +101 -0
- package/skills/bober.incident/SKILL.md +245 -0
- package/skills/bober.onboard/SKILL.md +84 -0
- package/skills/bober.plan/SKILL.md +10 -0
- package/skills/bober.postmortem/SKILL.md +231 -0
- package/skills/bober.runbook/SKILL.md +335 -0
- package/skills/bober.using-bober/SKILL.md +133 -0
- package/skills/bober.verify/SKILL.md +143 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolution verification gate (Sprint 22).
|
|
3
|
+
*
|
|
4
|
+
* verifyResolution queries the configured observability MCP provider for the
|
|
5
|
+
* named metric over the named window, applies the comparison per-sample (lt is
|
|
6
|
+
* strict <, lte is <=, gt is strict >, gte is >=), and returns verified=true
|
|
7
|
+
* ONLY when EVERY sample meets the threshold. One outlier = not verified.
|
|
8
|
+
*
|
|
9
|
+
* Evidence persistence: every call (verified=true OR false) writes raw samples
|
|
10
|
+
* to `.bober/incidents/<id>/resolution-evidence/<ISO-timestamp>.json` for
|
|
11
|
+
* audit and postmortem reconstruction. Presence of the evidence file does
|
|
12
|
+
* NOT imply resolution — only the VerifyResult.verified boolean does.
|
|
13
|
+
*
|
|
14
|
+
* No provider configured: returns verified=false, reason='NO_PROVIDER', hint.
|
|
15
|
+
* Override path: handled by setIncidentStatus in src/incident/timeline.ts,
|
|
16
|
+
* not here. This module ONLY measures.
|
|
17
|
+
*
|
|
18
|
+
* Sprint 22 — src/incident/resolution-verify.ts
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
import type { ObservabilityProvider } from "../config/schema.js";
|
|
22
|
+
import type { IncidentId } from "./types.js";
|
|
23
|
+
export declare const ComparisonSchema: z.ZodEnum<["lt", "gt", "lte", "gte"]>;
|
|
24
|
+
export type Comparison = z.infer<typeof ComparisonSchema>;
|
|
25
|
+
export declare const BaselineComparisonSchema: z.ZodEnum<["absolute", "percent-of-baseline"]>;
|
|
26
|
+
export type BaselineComparison = z.infer<typeof BaselineComparisonSchema>;
|
|
27
|
+
export declare const ResolutionCriteriaSchema: z.ZodObject<{
|
|
28
|
+
metricName: z.ZodString;
|
|
29
|
+
threshold: z.ZodNumber;
|
|
30
|
+
comparison: z.ZodEnum<["lt", "gt", "lte", "gte"]>;
|
|
31
|
+
windowMinutes: z.ZodNumber;
|
|
32
|
+
provider: z.ZodString;
|
|
33
|
+
baselineComparison: z.ZodOptional<z.ZodEnum<["absolute", "percent-of-baseline"]>>;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
provider: string;
|
|
36
|
+
metricName: string;
|
|
37
|
+
threshold: number;
|
|
38
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
39
|
+
windowMinutes: number;
|
|
40
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
41
|
+
}, {
|
|
42
|
+
provider: string;
|
|
43
|
+
metricName: string;
|
|
44
|
+
threshold: number;
|
|
45
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
46
|
+
windowMinutes: number;
|
|
47
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
export type ResolutionCriteria = z.infer<typeof ResolutionCriteriaSchema>;
|
|
50
|
+
export declare const MetricSampleSchema: z.ZodObject<{
|
|
51
|
+
timestamp: z.ZodString;
|
|
52
|
+
value: z.ZodNumber;
|
|
53
|
+
}, "strip", z.ZodTypeAny, {
|
|
54
|
+
value: number;
|
|
55
|
+
timestamp: string;
|
|
56
|
+
}, {
|
|
57
|
+
value: number;
|
|
58
|
+
timestamp: string;
|
|
59
|
+
}>;
|
|
60
|
+
export type MetricSample = z.infer<typeof MetricSampleSchema>;
|
|
61
|
+
export declare const VerifyResultSchema: z.ZodObject<{
|
|
62
|
+
verified: z.ZodBoolean;
|
|
63
|
+
/** Worst-case sample value (the one that failed, else last sample). */
|
|
64
|
+
observedValue: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
/** ISO timestamp of the witness sample. */
|
|
66
|
+
sampledAt: z.ZodOptional<z.ZodString>;
|
|
67
|
+
/** Path to the evidence file: .bober/incidents/<id>/resolution-evidence/<ts>.json */
|
|
68
|
+
evidencePath: z.ZodOptional<z.ZodString>;
|
|
69
|
+
reason: z.ZodOptional<z.ZodEnum<["OK", "OUTLIER", "NO_PROVIDER", "NOT_IMPLEMENTED", "MCP_ERROR"]>>;
|
|
70
|
+
hint: z.ZodOptional<z.ZodString>;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
verified: boolean;
|
|
73
|
+
reason?: "OK" | "OUTLIER" | "NO_PROVIDER" | "NOT_IMPLEMENTED" | "MCP_ERROR" | undefined;
|
|
74
|
+
hint?: string | undefined;
|
|
75
|
+
observedValue?: number | undefined;
|
|
76
|
+
sampledAt?: string | undefined;
|
|
77
|
+
evidencePath?: string | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
verified: boolean;
|
|
80
|
+
reason?: "OK" | "OUTLIER" | "NO_PROVIDER" | "NOT_IMPLEMENTED" | "MCP_ERROR" | undefined;
|
|
81
|
+
hint?: string | undefined;
|
|
82
|
+
observedValue?: number | undefined;
|
|
83
|
+
sampledAt?: string | undefined;
|
|
84
|
+
evidencePath?: string | undefined;
|
|
85
|
+
}>;
|
|
86
|
+
export type VerifyResult = z.infer<typeof VerifyResultSchema>;
|
|
87
|
+
export declare const ResolutionEvidenceSchema: z.ZodObject<{
|
|
88
|
+
incidentId: z.ZodString;
|
|
89
|
+
verifiedAt: z.ZodString;
|
|
90
|
+
criteria: z.ZodObject<{
|
|
91
|
+
metricName: z.ZodString;
|
|
92
|
+
threshold: z.ZodNumber;
|
|
93
|
+
comparison: z.ZodEnum<["lt", "gt", "lte", "gte"]>;
|
|
94
|
+
windowMinutes: z.ZodNumber;
|
|
95
|
+
provider: z.ZodString;
|
|
96
|
+
baselineComparison: z.ZodOptional<z.ZodEnum<["absolute", "percent-of-baseline"]>>;
|
|
97
|
+
}, "strip", z.ZodTypeAny, {
|
|
98
|
+
provider: string;
|
|
99
|
+
metricName: string;
|
|
100
|
+
threshold: number;
|
|
101
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
102
|
+
windowMinutes: number;
|
|
103
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
104
|
+
}, {
|
|
105
|
+
provider: string;
|
|
106
|
+
metricName: string;
|
|
107
|
+
threshold: number;
|
|
108
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
109
|
+
windowMinutes: number;
|
|
110
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
111
|
+
}>;
|
|
112
|
+
samples: z.ZodArray<z.ZodObject<{
|
|
113
|
+
timestamp: z.ZodString;
|
|
114
|
+
value: z.ZodNumber;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
value: number;
|
|
117
|
+
timestamp: string;
|
|
118
|
+
}, {
|
|
119
|
+
value: number;
|
|
120
|
+
timestamp: string;
|
|
121
|
+
}>, "many">;
|
|
122
|
+
allSamplesPassed: z.ZodBoolean;
|
|
123
|
+
}, "strip", z.ZodTypeAny, {
|
|
124
|
+
incidentId: string;
|
|
125
|
+
verifiedAt: string;
|
|
126
|
+
criteria: {
|
|
127
|
+
provider: string;
|
|
128
|
+
metricName: string;
|
|
129
|
+
threshold: number;
|
|
130
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
131
|
+
windowMinutes: number;
|
|
132
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
133
|
+
};
|
|
134
|
+
samples: {
|
|
135
|
+
value: number;
|
|
136
|
+
timestamp: string;
|
|
137
|
+
}[];
|
|
138
|
+
allSamplesPassed: boolean;
|
|
139
|
+
}, {
|
|
140
|
+
incidentId: string;
|
|
141
|
+
verifiedAt: string;
|
|
142
|
+
criteria: {
|
|
143
|
+
provider: string;
|
|
144
|
+
metricName: string;
|
|
145
|
+
threshold: number;
|
|
146
|
+
comparison: "lt" | "gt" | "lte" | "gte";
|
|
147
|
+
windowMinutes: number;
|
|
148
|
+
baselineComparison?: "absolute" | "percent-of-baseline" | undefined;
|
|
149
|
+
};
|
|
150
|
+
samples: {
|
|
151
|
+
value: number;
|
|
152
|
+
timestamp: string;
|
|
153
|
+
}[];
|
|
154
|
+
allSamplesPassed: boolean;
|
|
155
|
+
}>;
|
|
156
|
+
export type ResolutionEvidence = z.infer<typeof ResolutionEvidenceSchema>;
|
|
157
|
+
export interface MetricQueryArgs {
|
|
158
|
+
name: string;
|
|
159
|
+
timeRange: {
|
|
160
|
+
start: string;
|
|
161
|
+
end: string;
|
|
162
|
+
};
|
|
163
|
+
step?: string;
|
|
164
|
+
}
|
|
165
|
+
export interface MetricQueryClient {
|
|
166
|
+
/** Call obs__<provider>__query_metric and return parsed dataPoints. */
|
|
167
|
+
queryMetric(provider: string, args: MetricQueryArgs): Promise<MetricSample[]>;
|
|
168
|
+
}
|
|
169
|
+
export interface VerifyResolutionDeps {
|
|
170
|
+
projectRoot: string;
|
|
171
|
+
providers: readonly ObservabilityProvider[];
|
|
172
|
+
/** Injected for tests; default = real spawn via mergeObsTools. */
|
|
173
|
+
client?: MetricQueryClient;
|
|
174
|
+
/** Injected clock for tests. Default = () => new Date(). */
|
|
175
|
+
now?: () => Date;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Apply the comparison per the criteria. Boundary semantics:
|
|
179
|
+
* - 'lt' : value < threshold (strict; value === threshold FAILS)
|
|
180
|
+
* - 'lte' : value <= threshold (inclusive; value === threshold PASSES)
|
|
181
|
+
* - 'gt' : value > threshold (strict)
|
|
182
|
+
* - 'gte' : value >= threshold (inclusive)
|
|
183
|
+
*/
|
|
184
|
+
export declare function sampleMeetsThreshold(value: number, threshold: number, comparison: Comparison): boolean;
|
|
185
|
+
export declare function verifyResolution(incidentId: IncidentId, criteria: ResolutionCriteria, deps: VerifyResolutionDeps): Promise<VerifyResult>;
|
|
186
|
+
//# sourceMappingURL=resolution-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution-verify.d.ts","sourceRoot":"","sources":["../../src/incident/resolution-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,eAAO,MAAM,gBAAgB,uCAAqC,CAAC;AACnE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,wBAAwB,gDAA8C,CAAC;AACpF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;EAOnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,kBAAkB;;IAE7B,uEAAuE;;IAEvE,2CAA2C;;IAE3C,qFAAqF;;;;;;;;;;;;;;;;;;EAIrF,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAI1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC5C,kEAAkE;IAClE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAID;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAOtG;AAID,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,YAAY,CAAC,CA6EvB"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolution verification gate (Sprint 22).
|
|
3
|
+
*
|
|
4
|
+
* verifyResolution queries the configured observability MCP provider for the
|
|
5
|
+
* named metric over the named window, applies the comparison per-sample (lt is
|
|
6
|
+
* strict <, lte is <=, gt is strict >, gte is >=), and returns verified=true
|
|
7
|
+
* ONLY when EVERY sample meets the threshold. One outlier = not verified.
|
|
8
|
+
*
|
|
9
|
+
* Evidence persistence: every call (verified=true OR false) writes raw samples
|
|
10
|
+
* to `.bober/incidents/<id>/resolution-evidence/<ISO-timestamp>.json` for
|
|
11
|
+
* audit and postmortem reconstruction. Presence of the evidence file does
|
|
12
|
+
* NOT imply resolution — only the VerifyResult.verified boolean does.
|
|
13
|
+
*
|
|
14
|
+
* No provider configured: returns verified=false, reason='NO_PROVIDER', hint.
|
|
15
|
+
* Override path: handled by setIncidentStatus in src/incident/timeline.ts,
|
|
16
|
+
* not here. This module ONLY measures.
|
|
17
|
+
*
|
|
18
|
+
* Sprint 22 — src/incident/resolution-verify.ts
|
|
19
|
+
*/
|
|
20
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
import { mergeObsTools, namespaceToolName, stopAll } from "../orchestrator/observability/merge.js";
|
|
24
|
+
// ── Schemas ────────────────────────────────────────────────────────────────────
|
|
25
|
+
export const ComparisonSchema = z.enum(["lt", "gt", "lte", "gte"]);
|
|
26
|
+
export const BaselineComparisonSchema = z.enum(["absolute", "percent-of-baseline"]);
|
|
27
|
+
export const ResolutionCriteriaSchema = z.object({
|
|
28
|
+
metricName: z.string().min(1),
|
|
29
|
+
threshold: z.number(),
|
|
30
|
+
comparison: ComparisonSchema,
|
|
31
|
+
windowMinutes: z.number().int().positive(),
|
|
32
|
+
provider: z.string().min(1),
|
|
33
|
+
baselineComparison: BaselineComparisonSchema.optional(),
|
|
34
|
+
});
|
|
35
|
+
export const MetricSampleSchema = z.object({
|
|
36
|
+
timestamp: z.string(),
|
|
37
|
+
value: z.number(),
|
|
38
|
+
});
|
|
39
|
+
export const VerifyResultSchema = z.object({
|
|
40
|
+
verified: z.boolean(),
|
|
41
|
+
/** Worst-case sample value (the one that failed, else last sample). */
|
|
42
|
+
observedValue: z.number().optional(),
|
|
43
|
+
/** ISO timestamp of the witness sample. */
|
|
44
|
+
sampledAt: z.string().optional(),
|
|
45
|
+
/** Path to the evidence file: .bober/incidents/<id>/resolution-evidence/<ts>.json */
|
|
46
|
+
evidencePath: z.string().optional(),
|
|
47
|
+
reason: z.enum(["OK", "OUTLIER", "NO_PROVIDER", "NOT_IMPLEMENTED", "MCP_ERROR"]).optional(),
|
|
48
|
+
hint: z.string().optional(),
|
|
49
|
+
});
|
|
50
|
+
export const ResolutionEvidenceSchema = z.object({
|
|
51
|
+
incidentId: z.string(),
|
|
52
|
+
verifiedAt: z.string(),
|
|
53
|
+
criteria: ResolutionCriteriaSchema,
|
|
54
|
+
samples: z.array(MetricSampleSchema),
|
|
55
|
+
allSamplesPassed: z.boolean(),
|
|
56
|
+
});
|
|
57
|
+
// ── Per-sample comparator ──────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Apply the comparison per the criteria. Boundary semantics:
|
|
60
|
+
* - 'lt' : value < threshold (strict; value === threshold FAILS)
|
|
61
|
+
* - 'lte' : value <= threshold (inclusive; value === threshold PASSES)
|
|
62
|
+
* - 'gt' : value > threshold (strict)
|
|
63
|
+
* - 'gte' : value >= threshold (inclusive)
|
|
64
|
+
*/
|
|
65
|
+
export function sampleMeetsThreshold(value, threshold, comparison) {
|
|
66
|
+
switch (comparison) {
|
|
67
|
+
case "lt": return value < threshold;
|
|
68
|
+
case "lte": return value <= threshold;
|
|
69
|
+
case "gt": return value > threshold;
|
|
70
|
+
case "gte": return value >= threshold;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ── Main entry point ───────────────────────────────────────────────────────────
|
|
74
|
+
export async function verifyResolution(incidentId, criteria, deps) {
|
|
75
|
+
ResolutionCriteriaSchema.parse(criteria);
|
|
76
|
+
// 1. baselineComparison = 'percent-of-baseline' is documented but deferred.
|
|
77
|
+
// Sprint 22 does not implement baseline retrieval — there is no baseline
|
|
78
|
+
// data infrastructure in the repo. Return NOT_IMPLEMENTED as per contract.
|
|
79
|
+
if (criteria.baselineComparison === "percent-of-baseline") {
|
|
80
|
+
return {
|
|
81
|
+
verified: false,
|
|
82
|
+
reason: "NOT_IMPLEMENTED",
|
|
83
|
+
hint: "baselineComparison='percent-of-baseline' is not implemented in Sprint 22. Use 'absolute' or omit. Tracked as a follow-up.",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// 2. Provider lookup. No provider → NO_PROVIDER with actionable hint.
|
|
87
|
+
const providerDecl = deps.providers.find((p) => p.name === criteria.provider && p.enabled !== false);
|
|
88
|
+
if (!providerDecl) {
|
|
89
|
+
return {
|
|
90
|
+
verified: false,
|
|
91
|
+
reason: "NO_PROVIDER",
|
|
92
|
+
hint: `No observability provider '${criteria.provider}' configured for metric '${criteria.metricName}'. ` +
|
|
93
|
+
`Add it to bober.config.json under observability.providers, or use overrideToken='SKIP_METRIC_VERIFY: <reason>' when calling setIncidentStatus(..., 'resolved', { overrideToken }).`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// 3. Window → ISO time range.
|
|
97
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
98
|
+
const end = now.toISOString();
|
|
99
|
+
const start = new Date(now.getTime() - criteria.windowMinutes * 60_000).toISOString();
|
|
100
|
+
// 4. Query the metric via injected client (default = spawn via mergeObsTools).
|
|
101
|
+
let samples;
|
|
102
|
+
try {
|
|
103
|
+
const client = deps.client ?? (await defaultMcpClient([providerDecl]));
|
|
104
|
+
samples = await client.queryMetric(criteria.provider, {
|
|
105
|
+
name: criteria.metricName,
|
|
106
|
+
timeRange: { start, end },
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
111
|
+
return {
|
|
112
|
+
verified: false,
|
|
113
|
+
reason: "MCP_ERROR",
|
|
114
|
+
hint: `Failed to query metric: ${msg.replace(/\b[A-Z_][A-Z0-9_]*=\S+/g, "[redacted]")}`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// 5. Per-sample comparison; allSamplesPassed is the gate.
|
|
118
|
+
// Guard: empty samples array → every() returns true on empty, so guard with length > 0.
|
|
119
|
+
const allSamplesPassed = samples.length > 0 &&
|
|
120
|
+
samples.every((s) => sampleMeetsThreshold(s.value, criteria.threshold, criteria.comparison));
|
|
121
|
+
// 6. Worst-case sample for observedValue (the one that FAILED, else last).
|
|
122
|
+
const lastSample = samples[samples.length - 1];
|
|
123
|
+
const failingSample = samples.find((s) => !sampleMeetsThreshold(s.value, criteria.threshold, criteria.comparison));
|
|
124
|
+
const witness = failingSample ?? lastSample;
|
|
125
|
+
// 7. Write evidence file ALWAYS (audit/postmortem).
|
|
126
|
+
const evidencePath = await writeEvidenceFile(deps.projectRoot, incidentId, {
|
|
127
|
+
incidentId,
|
|
128
|
+
verifiedAt: end,
|
|
129
|
+
criteria,
|
|
130
|
+
samples,
|
|
131
|
+
allSamplesPassed,
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
verified: allSamplesPassed,
|
|
135
|
+
observedValue: witness?.value,
|
|
136
|
+
sampledAt: witness?.timestamp,
|
|
137
|
+
evidencePath,
|
|
138
|
+
reason: allSamplesPassed ? "OK" : samples.length === 0 ? "MCP_ERROR" : "OUTLIER",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
142
|
+
async function writeEvidenceFile(projectRoot, incidentId, evidence) {
|
|
143
|
+
const dir = join(projectRoot, ".bober", "incidents", incidentId, "resolution-evidence");
|
|
144
|
+
await mkdir(dir, { recursive: true });
|
|
145
|
+
const fname = `${evidence.verifiedAt.replace(/[:.]/g, "-")}.json`;
|
|
146
|
+
const fpath = join(dir, fname);
|
|
147
|
+
await writeFile(fpath, JSON.stringify(evidence, null, 2) + "\n", {
|
|
148
|
+
encoding: "utf-8",
|
|
149
|
+
mode: 0o600,
|
|
150
|
+
});
|
|
151
|
+
return fpath;
|
|
152
|
+
}
|
|
153
|
+
async function defaultMcpClient(providers) {
|
|
154
|
+
const { servers } = await mergeObsTools(providers);
|
|
155
|
+
// Map providerName → server for direct callTool invocations.
|
|
156
|
+
const serverByName = new Map(servers.map((s) => [s.name, s]));
|
|
157
|
+
return {
|
|
158
|
+
async queryMetric(provider, args) {
|
|
159
|
+
const server = serverByName.get(provider);
|
|
160
|
+
if (!server) {
|
|
161
|
+
// best-effort stop before throwing
|
|
162
|
+
await stopAll(servers).catch(() => { });
|
|
163
|
+
throw new Error(`provider '${provider}' not running after mergeObsTools`);
|
|
164
|
+
}
|
|
165
|
+
// The upstream name is 'query_metric'; namespaceToolName is for the diagnoser's tool list,
|
|
166
|
+
// NOT for direct callTool invocation on the server (per Pattern D in briefing).
|
|
167
|
+
const upstreamName = namespaceToolName(provider, "query_metric").replace(`obs__${provider}__`, "");
|
|
168
|
+
try {
|
|
169
|
+
const raw = await server.callTool(upstreamName, args);
|
|
170
|
+
return extractSamples(raw);
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await stopAll(servers).catch(() => { });
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Parse the metrics MCP response shape (from docs/observability-mcps/metrics.md):
|
|
180
|
+
* { metric, labels, dataPoints: [{ timestamp, value }] }
|
|
181
|
+
* Tolerates the SDK callTool() envelope (which may wrap content in `content`).
|
|
182
|
+
*/
|
|
183
|
+
function extractSamples(raw) {
|
|
184
|
+
// The MCP SDK callTool returns { content: [{type:'text',text:...}], isError }.
|
|
185
|
+
// Real implementations may return structured JSON in `content[0].text` OR
|
|
186
|
+
// a typed result. Accept both shapes defensively.
|
|
187
|
+
const candidate = raw;
|
|
188
|
+
if (Array.isArray(candidate.dataPoints)) {
|
|
189
|
+
return candidate.dataPoints
|
|
190
|
+
.map((p) => MetricSampleSchema.safeParse(p))
|
|
191
|
+
.filter((r) => r.success)
|
|
192
|
+
.map((r) => r.data);
|
|
193
|
+
}
|
|
194
|
+
if (Array.isArray(candidate.content) && candidate.content[0]?.text) {
|
|
195
|
+
try {
|
|
196
|
+
const parsed = JSON.parse(candidate.content[0].text);
|
|
197
|
+
if (Array.isArray(parsed?.dataPoints)) {
|
|
198
|
+
return parsed.dataPoints
|
|
199
|
+
.map((p) => MetricSampleSchema.safeParse(p))
|
|
200
|
+
.filter((r) => r.success)
|
|
201
|
+
.map((r) => r.data);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// fallthrough — return empty array
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=resolution-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution-verify.js","sourceRoot":"","sources":["../../src/incident/resolution-verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollback awareness helpers (Sprint 21).
|
|
3
|
+
*
|
|
4
|
+
* Reads changelog.jsonl for an incident, identifies ChangeEntries that are
|
|
5
|
+
* effective-status 'executed' (not yet rolled back), and provides:
|
|
6
|
+
*
|
|
7
|
+
* planRollback — returns a RollbackPlan with steps in reverse execution order.
|
|
8
|
+
* executeRollback — runs each step via the Sprint 20 risky-action gate (per-step).
|
|
9
|
+
* presentPlan — renders the plan to a human-readable string for CLI output.
|
|
10
|
+
*
|
|
11
|
+
* Escalation design note (Sprint 21):
|
|
12
|
+
* True checkpoint-based escalation is deferred to Sprint 24 (full /bober-incident
|
|
13
|
+
* flow). Escalation here consists of:
|
|
14
|
+
* 1. A 'rollback_halted' timeline event with remaining step ids.
|
|
15
|
+
* 2. A stderr warning via writeWarn.
|
|
16
|
+
* 3. result.escalated=true + result.remaining=[...] returned to the caller.
|
|
17
|
+
* Sprint 24 can wrap this return value in a real checkpoint if needed.
|
|
18
|
+
*
|
|
19
|
+
* JSONL semantics: changelog.jsonl is append-only; "latest line per id wins".
|
|
20
|
+
* When a change is executed, Sprint 20 writes two lines (pending, executed).
|
|
21
|
+
* After rollback, Sprint 21 appends a third line (rolled-back). Effective status
|
|
22
|
+
* is determined by the LAST line in file-order with a given id.
|
|
23
|
+
*
|
|
24
|
+
* Reverse execution order: sort by the FIRST entry's executedAt (when the action
|
|
25
|
+
* originally ran), then reverse. File order guarantees write monotonicity.
|
|
26
|
+
*
|
|
27
|
+
* Sprint 21 — src/incident/rollback.ts
|
|
28
|
+
*/
|
|
29
|
+
import type { ExecutorSeam } from "../orchestrator/deploy/types.js";
|
|
30
|
+
import type { RiskyActionConfig } from "../orchestrator/deploy/resolve.js";
|
|
31
|
+
import type { IncidentId } from "./types.js";
|
|
32
|
+
export interface RollbackStep {
|
|
33
|
+
originalChangeId: string;
|
|
34
|
+
originalDescription: string;
|
|
35
|
+
inverseDescription: string;
|
|
36
|
+
inverseCommand?: string;
|
|
37
|
+
/** ISO-8601 from the original ChangeEntry's first (pending/executed) record. */
|
|
38
|
+
originalExecutedAt: string;
|
|
39
|
+
}
|
|
40
|
+
export interface RollbackPlan {
|
|
41
|
+
incidentId: string;
|
|
42
|
+
totalChanges: number;
|
|
43
|
+
rollbackableChanges: number;
|
|
44
|
+
/** Count of changes excluded because no inverse is available. */
|
|
45
|
+
unrollbackableChanges: number;
|
|
46
|
+
steps: RollbackStep[];
|
|
47
|
+
warnings: string[];
|
|
48
|
+
}
|
|
49
|
+
export interface PlanRollbackOpts {
|
|
50
|
+
/** Include only changes executed AFTER this changeId (strict-after semantics). */
|
|
51
|
+
since?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface ExecuteRollbackOpts {
|
|
54
|
+
/** Pipeline config — forwarded to executeAction for gate resolution. */
|
|
55
|
+
config?: RiskyActionConfig;
|
|
56
|
+
/** Injected executor (for tests). Default = real execa-based executor. */
|
|
57
|
+
executor?: ExecutorSeam;
|
|
58
|
+
/** Stderr writer override (for capturing warnings in tests). Default = process.stderr.write. */
|
|
59
|
+
writeWarn?: (msg: string) => void;
|
|
60
|
+
/** Injectable clock (for tests). Default = () => new Date(). */
|
|
61
|
+
now?: () => Date;
|
|
62
|
+
}
|
|
63
|
+
export interface RollbackExecutionEntry {
|
|
64
|
+
/** ISO-8601 timestamp of when the rollback step was attempted. */
|
|
65
|
+
timestamp: string;
|
|
66
|
+
originalChangeId: string;
|
|
67
|
+
inverseDescription: string;
|
|
68
|
+
status: "rolled-back" | "rolled-back-failed";
|
|
69
|
+
durationMs: number;
|
|
70
|
+
errorMessage?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface RollbackResult {
|
|
73
|
+
attempted: number;
|
|
74
|
+
succeeded: number;
|
|
75
|
+
/** 0 or 1 — the sequence halts on the first failure. */
|
|
76
|
+
failed: number;
|
|
77
|
+
/** Non-empty when failed === 1; contains steps that were not attempted. */
|
|
78
|
+
remaining: RollbackStep[];
|
|
79
|
+
/** true when the rollback halted due to a failure — caller should escalate. */
|
|
80
|
+
escalated: boolean;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build a RollbackPlan from a changelog.
|
|
84
|
+
*
|
|
85
|
+
* Effective-status semantics (latest-line-wins):
|
|
86
|
+
* For each unique `id`, group all entries; the LAST entry in file order
|
|
87
|
+
* determines the effective status. Only `executed` entries are rollbackable.
|
|
88
|
+
*
|
|
89
|
+
* Reverse execution order:
|
|
90
|
+
* Steps are sorted ascending by the FIRST entry's executedAt (the original
|
|
91
|
+
* execution time), then reversed. This means the most recent action is
|
|
92
|
+
* rolled back first.
|
|
93
|
+
*
|
|
94
|
+
* --since semantics (changeId-based, strict-after):
|
|
95
|
+
* Only changes whose FIRST entry's executedAt is strictly greater than the
|
|
96
|
+
* --since changeId's first entry's executedAt are included.
|
|
97
|
+
*
|
|
98
|
+
* @param projectRoot Absolute path to the project root.
|
|
99
|
+
* @param incidentId Incident to plan a rollback for.
|
|
100
|
+
* @param opts Optional PlanRollbackOpts.
|
|
101
|
+
* @throws Error if opts.since references a non-existent changeId.
|
|
102
|
+
*/
|
|
103
|
+
export declare function planRollback(projectRoot: string, incidentId: IncidentId, opts?: PlanRollbackOpts): Promise<RollbackPlan>;
|
|
104
|
+
/**
|
|
105
|
+
* Render a RollbackPlan to a human-readable string for CLI output.
|
|
106
|
+
*
|
|
107
|
+
* Always includes:
|
|
108
|
+
* - Header with incident ID
|
|
109
|
+
* - Change counts (total, rollbackable, unrollbackable)
|
|
110
|
+
* - Numbered steps in reverse execution order
|
|
111
|
+
* - Warnings section (if any)
|
|
112
|
+
*/
|
|
113
|
+
export declare function presentPlan(plan: RollbackPlan): string;
|
|
114
|
+
/**
|
|
115
|
+
* Execute a RollbackPlan step by step.
|
|
116
|
+
*
|
|
117
|
+
* Each step is a risky action that MUST pass through the Sprint 20 gate
|
|
118
|
+
* individually. This means N rollback steps → N gate invocations.
|
|
119
|
+
*
|
|
120
|
+
* On success of each step:
|
|
121
|
+
* - Appends a ChangeEntry with id=originalChangeId, status='rolled-back'.
|
|
122
|
+
* - Appends a RollbackExecutionEntry with status='rolled-back'.
|
|
123
|
+
*
|
|
124
|
+
* On failure of any step:
|
|
125
|
+
* - Appends a ChangeEntry with id=originalChangeId, status='rolled-back-failed'.
|
|
126
|
+
* - Appends a RollbackExecutionEntry with status='rolled-back-failed'.
|
|
127
|
+
* - Halts the sequence (remaining steps are NOT attempted).
|
|
128
|
+
* - Emits a 'rollback_halted' timeline event.
|
|
129
|
+
* - Returns result.escalated=true with result.remaining=[unrolled steps].
|
|
130
|
+
*
|
|
131
|
+
* @param projectRoot Absolute path to the project root.
|
|
132
|
+
* @param incidentId Incident to execute the rollback for.
|
|
133
|
+
* @param plan The plan produced by planRollback.
|
|
134
|
+
* @param opts Optional injections (config, executor, writeWarn, now).
|
|
135
|
+
*/
|
|
136
|
+
export declare function executeRollback(projectRoot: string, incidentId: IncidentId, plan: RollbackPlan, opts?: ExecuteRollbackOpts): Promise<RollbackResult>;
|
|
137
|
+
//# sourceMappingURL=rollback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/incident/rollback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAQH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,MAAM,WAAW,YAAY;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,gGAAgG;IAChG,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,aAAa,GAAG,oBAAoB,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,SAAS,EAAE,OAAO,CAAC;CACpB;AA0ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EACtB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAyEvB;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA8BtD;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,YAAY,EAClB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,cAAc,CAAC,CA2HzB"}
|