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,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incident state machine + phase routing (Sprint 24).
|
|
3
|
+
*
|
|
4
|
+
* Wraps Sprint 19 setIncidentStatus with a GUARDED transition table:
|
|
5
|
+
* invalid transitions reject with a typed error before any disk write.
|
|
6
|
+
*
|
|
7
|
+
* The state machine is deterministic: given (currentPhase, agentOutput),
|
|
8
|
+
* the next phase is fully determined. No human-in-loop required for
|
|
9
|
+
* happy-path autopilot (subject to Tier 2 risky-action gates that fire
|
|
10
|
+
* inside executeAction). This is the integration capstone — no new
|
|
11
|
+
* primitives, only orchestration.
|
|
12
|
+
*
|
|
13
|
+
* Re-open path (resolved → investigating) is the ONLY transition that
|
|
14
|
+
* requires an explicit `reason` arg. Every other transition is implicit
|
|
15
|
+
* from the agent's output.
|
|
16
|
+
*
|
|
17
|
+
* Phase transition diagram:
|
|
18
|
+
*
|
|
19
|
+
* ┌──────────────────────────────────────────────────────┐
|
|
20
|
+
* │ │
|
|
21
|
+
* ▼ │
|
|
22
|
+
* ┌───────────────┐ │
|
|
23
|
+
* │ investigating │ │
|
|
24
|
+
* └───────┬───────┘ │
|
|
25
|
+
* │ │
|
|
26
|
+
* diagnoser produces │
|
|
27
|
+
* nextActions with │
|
|
28
|
+
* ≥1 risky │
|
|
29
|
+
* │ │
|
|
30
|
+
* ▼ │
|
|
31
|
+
* ┌───────────────┐ │
|
|
32
|
+
* │ remediating │ │
|
|
33
|
+
* └───────┬───────┘ │
|
|
34
|
+
* │ │
|
|
35
|
+
* all proposed actions executed │
|
|
36
|
+
* + postcondition passed │
|
|
37
|
+
* │ │
|
|
38
|
+
* ▼ │
|
|
39
|
+
* ┌───────────────┐ ──── verifyResolution fails ─────────────────┤
|
|
40
|
+
* │ monitoring │ │
|
|
41
|
+
* └───────┬───────┘ │
|
|
42
|
+
* │ │
|
|
43
|
+
* verifyResolution.verified=true │
|
|
44
|
+
* for criteria.windowMinutes │
|
|
45
|
+
* │ │
|
|
46
|
+
* ▼ │
|
|
47
|
+
* ┌───────────────┐ ──── user re-opens (reason REQUIRED) ────────┘
|
|
48
|
+
* │ resolved │
|
|
49
|
+
* └───────────────┘ (auto-postmortem triggered by setIncidentStatus)
|
|
50
|
+
*
|
|
51
|
+
* At any phase: user issues `bober incident abort <id> --reason <text> [--confirm-rollback]`
|
|
52
|
+
* ──────────────────────────────────────► aborted (terminal)
|
|
53
|
+
*
|
|
54
|
+
* Sprint 24 — src/incident/orchestrator.ts
|
|
55
|
+
*/
|
|
56
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
57
|
+
import { join } from "node:path";
|
|
58
|
+
import { appendTimeline, setIncidentStatus, } from "./timeline.js";
|
|
59
|
+
import { emit } from "../telemetry/emit.js";
|
|
60
|
+
import { IncidentMetadataSchema, STATUS_TRANSITIONS, } from "./types.js";
|
|
61
|
+
import { planRollback, executeRollback, presentPlan, } from "./rollback.js";
|
|
62
|
+
import { verifyResolution, } from "./resolution-verify.js";
|
|
63
|
+
// ── Public types ──────────────────────────────────────────────────────────────
|
|
64
|
+
export class InvalidTransitionError extends Error {
|
|
65
|
+
from;
|
|
66
|
+
to;
|
|
67
|
+
reasonRequired;
|
|
68
|
+
constructor(from, to, reasonRequired = false) {
|
|
69
|
+
const msg = reasonRequired
|
|
70
|
+
? `Invalid transition ${from} → ${to}: this transition requires an explicit 'reason' (re-open path).`
|
|
71
|
+
: `Invalid transition ${from} → ${to}. Allowed from '${from}': [${STATUS_TRANSITIONS[from].join(", ")}]`;
|
|
72
|
+
super(msg);
|
|
73
|
+
this.from = from;
|
|
74
|
+
this.to = to;
|
|
75
|
+
this.reasonRequired = reasonRequired;
|
|
76
|
+
this.name = "InvalidTransitionError";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// ── readIncidentMetadata: a thin wrapper for the CLI status command ────────────
|
|
80
|
+
export async function readIncidentMetadata(projectRoot, incidentId) {
|
|
81
|
+
const metaPath = join(projectRoot, ".bober", "incidents", incidentId, "incident.json");
|
|
82
|
+
const raw = await readFile(metaPath, "utf-8");
|
|
83
|
+
return IncidentMetadataSchema.parse(JSON.parse(raw));
|
|
84
|
+
}
|
|
85
|
+
// ── transitionPhase: the guarded gate ─────────────────────────────────────────
|
|
86
|
+
export async function transitionPhase(projectRoot, incidentId, toPhase, opts = {}) {
|
|
87
|
+
// 1. Read current phase.
|
|
88
|
+
const meta = await readIncidentMetadata(projectRoot, incidentId);
|
|
89
|
+
const from = meta.status;
|
|
90
|
+
// 2. Guard: allowed in the transition table.
|
|
91
|
+
const allowed = STATUS_TRANSITIONS[from];
|
|
92
|
+
if (!allowed.includes(toPhase)) {
|
|
93
|
+
throw new InvalidTransitionError(from, toPhase, false);
|
|
94
|
+
}
|
|
95
|
+
// 3. Re-open path: resolved → investigating requires an explicit reason.
|
|
96
|
+
const isReopen = from === "resolved" && toPhase === "investigating";
|
|
97
|
+
if (isReopen && (!opts.reason || opts.reason.trim() === "")) {
|
|
98
|
+
throw new InvalidTransitionError(from, toPhase, true);
|
|
99
|
+
}
|
|
100
|
+
// 4. Persist via the Sprint 19 atomic writer.
|
|
101
|
+
await setIncidentStatus(projectRoot, incidentId, toPhase, undefined, opts.setStatus);
|
|
102
|
+
// 5. Audit timeline event.
|
|
103
|
+
await appendTimeline(projectRoot, incidentId, {
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
eventKind: "phase_transition",
|
|
106
|
+
source: "system",
|
|
107
|
+
summary: isReopen
|
|
108
|
+
? `Re-opened: ${from} → ${toPhase}. Reason: ${opts.reason}`
|
|
109
|
+
: `Phase transition: ${from} → ${toPhase}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// ── applyDiagnosisOutcome: routes to 'remediating' or stays at 'investigating' ─
|
|
113
|
+
/**
|
|
114
|
+
* Inspect a diagnosis output and transition the incident phase accordingly.
|
|
115
|
+
*
|
|
116
|
+
* If any nextAction has blastRadius='risky' → transition to 'remediating'.
|
|
117
|
+
* If nextActions is empty (diagnoser found no remediation needed) → leave at
|
|
118
|
+
* 'investigating'; the operator should call transitionPhase or `bober incident end`.
|
|
119
|
+
* If nextActions has entries but all are safe → leave at 'investigating' (no
|
|
120
|
+
* state-mutating actions are needed; diagnose further or end the incident).
|
|
121
|
+
*
|
|
122
|
+
* Returns { newPhase } — the phase AFTER the call. Callers can use this to
|
|
123
|
+
* branch their own logic.
|
|
124
|
+
*/
|
|
125
|
+
export async function applyDiagnosisOutcome(projectRoot, incidentId, diagnosis, _opts = {}) {
|
|
126
|
+
const hasRiskyActions = diagnosis.nextActions.some((a) => a.blastRadius === "risky");
|
|
127
|
+
if (hasRiskyActions) {
|
|
128
|
+
// Transition to remediating — some next actions require the deploy gate.
|
|
129
|
+
await transitionPhase(projectRoot, incidentId, "remediating", {});
|
|
130
|
+
return { newPhase: "remediating" };
|
|
131
|
+
}
|
|
132
|
+
// No risky actions: stay at investigating. The orchestrator does not auto-resolve
|
|
133
|
+
// here because "no risky actions" ≠ "incident is resolved" — the diagnoser may
|
|
134
|
+
// have produced safe investigative actions, or no actions at all. Only the
|
|
135
|
+
// operator (via `bober incident end`) can mark the incident resolved.
|
|
136
|
+
const meta = await readIncidentMetadata(projectRoot, incidentId);
|
|
137
|
+
return { newPhase: meta.status };
|
|
138
|
+
}
|
|
139
|
+
// ── applyDeploymentOutcome: routes to 'monitoring' then resolved ──────────────
|
|
140
|
+
/**
|
|
141
|
+
* After deployment actions complete, transition the incident phase.
|
|
142
|
+
*
|
|
143
|
+
* If all actions executed successfully AND verifyResolution is available:
|
|
144
|
+
* - call verifyResolution
|
|
145
|
+
* - if verified=true → transition to 'monitoring'
|
|
146
|
+
* - Returns { newPhase: 'monitoring', verified: true }
|
|
147
|
+
*
|
|
148
|
+
* Transitioning from monitoring → resolved is the caller's responsibility
|
|
149
|
+
* (the CLI / orchestration layer drives the second transition after the
|
|
150
|
+
* criteria window elapses). This function ONLY moves to monitoring.
|
|
151
|
+
*
|
|
152
|
+
* If verifyDeps is not provided or skipVerification=true:
|
|
153
|
+
* - Transition to monitoring unconditionally (operator is asserting success).
|
|
154
|
+
*
|
|
155
|
+
* If any action failed:
|
|
156
|
+
* - Stay in remediating (return { newPhase: 'remediating', verified: false }).
|
|
157
|
+
*/
|
|
158
|
+
export async function applyDeploymentOutcome(projectRoot, incidentId, deployResult, opts = {}) {
|
|
159
|
+
const allExecuted = deployResult.executed.every((e) => e.status === "executed");
|
|
160
|
+
if (!allExecuted) {
|
|
161
|
+
// Some actions failed — stay in remediating.
|
|
162
|
+
const meta = await readIncidentMetadata(projectRoot, incidentId);
|
|
163
|
+
return { newPhase: meta.status, verified: false };
|
|
164
|
+
}
|
|
165
|
+
// All actions succeeded. Attempt verification if criteria are provided.
|
|
166
|
+
if (opts.resolutionCriteria && opts.verifyDeps && !opts.skipVerification) {
|
|
167
|
+
const verifyResult = await verifyResolution(incidentId, opts.resolutionCriteria, {
|
|
168
|
+
...opts.verifyDeps,
|
|
169
|
+
projectRoot,
|
|
170
|
+
});
|
|
171
|
+
if (verifyResult.verified) {
|
|
172
|
+
// Move to monitoring — criteria passed.
|
|
173
|
+
await transitionPhase(projectRoot, incidentId, "monitoring", {});
|
|
174
|
+
return { newPhase: "monitoring", verified: true };
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// Verification failed — stay in remediating.
|
|
178
|
+
const meta = await readIncidentMetadata(projectRoot, incidentId);
|
|
179
|
+
return { newPhase: meta.status, verified: false };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// No verification configured or skipped — move to monitoring optimistically.
|
|
183
|
+
await transitionPhase(projectRoot, incidentId, "monitoring", {});
|
|
184
|
+
return { newPhase: "monitoring" };
|
|
185
|
+
}
|
|
186
|
+
// ── abort: terminal escape hatch (s24-c7) ─────────────────────────────────────
|
|
187
|
+
/**
|
|
188
|
+
* Abort an incident at any phase.
|
|
189
|
+
*
|
|
190
|
+
* Writes .bober/incidents/<id>/aborted.txt with reason.
|
|
191
|
+
* Writes .bober/incidents/<id>/abort-report.md with reason + rollback plan.
|
|
192
|
+
* Transitions the incident to status='aborted' (terminal).
|
|
193
|
+
*
|
|
194
|
+
* IF confirmRollback=true: plans + executes rollback for executed-not-rolled-back
|
|
195
|
+
* changes (each step goes through the deploy gate individually).
|
|
196
|
+
* IF confirmRollback=false (default): does NOT execute any rollbacks.
|
|
197
|
+
*
|
|
198
|
+
* Silent rollback on abort is a footgun — confirmRollback=true is the explicit
|
|
199
|
+
* opt-in. Without it, the operator is on the hook for manual cleanup.
|
|
200
|
+
*
|
|
201
|
+
* @throws Error if the incident is already aborted (abort is terminal).
|
|
202
|
+
*/
|
|
203
|
+
export async function abort(projectRoot, incidentId, opts) {
|
|
204
|
+
const now = opts.now ?? (() => new Date());
|
|
205
|
+
const reason = opts.reason;
|
|
206
|
+
// Read current state.
|
|
207
|
+
const meta = await readIncidentMetadata(projectRoot, incidentId);
|
|
208
|
+
if (meta.status === "aborted") {
|
|
209
|
+
throw new Error(`Incident ${incidentId} is already aborted. abort is a terminal state — no further transitions are possible.`);
|
|
210
|
+
}
|
|
211
|
+
const incidentDir = join(projectRoot, ".bober", "incidents", incidentId);
|
|
212
|
+
await mkdir(incidentDir, { recursive: true });
|
|
213
|
+
// Write aborted.txt marker.
|
|
214
|
+
const abortedTxtPath = join(incidentDir, "aborted.txt");
|
|
215
|
+
await writeFile(abortedTxtPath, `Incident ${incidentId} aborted at ${now().toISOString()}\nReason: ${reason}\n`, { encoding: "utf-8", mode: 0o600 });
|
|
216
|
+
// Emit timeline event.
|
|
217
|
+
await appendTimeline(projectRoot, incidentId, {
|
|
218
|
+
timestamp: now().toISOString(),
|
|
219
|
+
eventKind: "incident_aborted",
|
|
220
|
+
source: "human",
|
|
221
|
+
summary: `Incident aborted. Reason: ${reason}`,
|
|
222
|
+
});
|
|
223
|
+
// Optionally run rollback.
|
|
224
|
+
let rollbackResult;
|
|
225
|
+
let planText = "(no rollback requested)";
|
|
226
|
+
if (opts.confirmRollback) {
|
|
227
|
+
const plan = await planRollback(projectRoot, incidentId);
|
|
228
|
+
planText = presentPlan(plan);
|
|
229
|
+
if (plan.steps.length > 0) {
|
|
230
|
+
rollbackResult = await executeRollback(projectRoot, incidentId, plan, {
|
|
231
|
+
config: opts.config,
|
|
232
|
+
...(opts.rollbackOpts ?? {}),
|
|
233
|
+
now,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
rollbackResult = {
|
|
238
|
+
attempted: 0,
|
|
239
|
+
succeeded: 0,
|
|
240
|
+
failed: 0,
|
|
241
|
+
remaining: [],
|
|
242
|
+
escalated: false,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Write abort-report.md.
|
|
247
|
+
const abortReportPath = join(incidentDir, "abort-report.md");
|
|
248
|
+
const rollbackSection = rollbackResult
|
|
249
|
+
? `## Rollback\n\n${planText}\n\nResult: ${rollbackResult.succeeded}/${rollbackResult.attempted} steps succeeded.${rollbackResult.escalated ? " ESCALATED — manual recovery required." : ""}\n`
|
|
250
|
+
: `## Rollback\n\nNot executed (--confirm-rollback was not provided). Manual cleanup may be required.\n\n${planText}\n`;
|
|
251
|
+
const report = `# Abort Report: ${incidentId}
|
|
252
|
+
|
|
253
|
+
## Incident Details
|
|
254
|
+
|
|
255
|
+
- **Incident ID:** ${incidentId}
|
|
256
|
+
- **Symptom:** ${meta.symptom}
|
|
257
|
+
- **Phase at abort:** ${meta.status}
|
|
258
|
+
- **Aborted at:** ${now().toISOString()}
|
|
259
|
+
- **Reason:** ${reason}
|
|
260
|
+
|
|
261
|
+
${rollbackSection}
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
*This is a brief abort report, not a full postmortem. For a complete root cause analysis, re-open the incident or run \`bober postmortem generate ${incidentId}\`.*
|
|
265
|
+
`;
|
|
266
|
+
await writeFile(abortReportPath, report, { encoding: "utf-8", mode: 0o600 });
|
|
267
|
+
// Transition to aborted (terminal). aborted does not require verifyResult/overrideToken.
|
|
268
|
+
// setIncidentStatus does NOT gate on 'aborted' — only 'resolved' is gated.
|
|
269
|
+
await setIncidentStatus(projectRoot, incidentId, "aborted");
|
|
270
|
+
// Sprint 28 — telemetry: emit incident-aborted (fire-and-forget)
|
|
271
|
+
if (opts.boberConfig) {
|
|
272
|
+
void emit(projectRoot, opts.boberConfig, "incident-aborted", { incidentId });
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
rollback: rollbackResult,
|
|
276
|
+
abortReportPath,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/incident/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playbook search — symptom-to-playbook matching (Sprint 25).
|
|
3
|
+
*
|
|
4
|
+
* Loads playbooks from .bober/playbooks/*.md (skipping README.md).
|
|
5
|
+
* Each playbook frontmatter (name, classification, applicableSymptoms,
|
|
6
|
+
* prerequisites) is parsed via a minimal YAML block parser — no external dep.
|
|
7
|
+
*
|
|
8
|
+
* searchPlaybooks(symptom) tokenises the symptom string, scores each
|
|
9
|
+
* playbook's applicableSymptoms by token overlap, and returns matches
|
|
10
|
+
* sorted by confidence descending.
|
|
11
|
+
*
|
|
12
|
+
* Confidence thresholds (exported constants):
|
|
13
|
+
* HIGH_CONFIDENCE_THRESHOLD = 0.6 → diagnoser auto-follows playbook
|
|
14
|
+
* LOW_CONFIDENCE_THRESHOLD = 0.3 → diagnoser surfaces as suggestion
|
|
15
|
+
*
|
|
16
|
+
* Sprint 25 — src/incident/playbook-search.ts
|
|
17
|
+
*/
|
|
18
|
+
/** A match at or above this threshold triggers automatic playbook execution. */
|
|
19
|
+
export declare const HIGH_CONFIDENCE_THRESHOLD = 0.6;
|
|
20
|
+
/** A match at or above this (and below HIGH) surfaces as a suggestion. */
|
|
21
|
+
export declare const LOW_CONFIDENCE_THRESHOLD = 0.3;
|
|
22
|
+
export interface Playbook {
|
|
23
|
+
name: string;
|
|
24
|
+
classification: "standard" | "emergency";
|
|
25
|
+
applicableSymptoms: string[];
|
|
26
|
+
prerequisites: string[];
|
|
27
|
+
filePath: string;
|
|
28
|
+
/** Raw step sections (## Step N: ...) extracted from the markdown body */
|
|
29
|
+
stepSections: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface PlaybookMatch {
|
|
32
|
+
playbook: Playbook;
|
|
33
|
+
/** Confidence in [0, 1]. Clamped to the range. */
|
|
34
|
+
confidence: number;
|
|
35
|
+
/** The tokens from the query that overlapped with a matched symptom phrase */
|
|
36
|
+
matchedTokens: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Tokenise a string into lowercase, non-empty, non-stopword tokens.
|
|
40
|
+
* Splits on whitespace and common punctuation.
|
|
41
|
+
*/
|
|
42
|
+
export declare function tokenize(text: string): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Load all playbooks from .bober/playbooks/*.md in the given projectRoot.
|
|
45
|
+
* - Skips README.md
|
|
46
|
+
* - Skips files with missing or malformed frontmatter (logs a warning)
|
|
47
|
+
* - Returns [] gracefully when the directory does not exist
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadPlaybooks(projectRoot: string): Promise<Playbook[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Search the playbook library for playbooks matching the given symptom string.
|
|
52
|
+
*
|
|
53
|
+
* Algorithm:
|
|
54
|
+
* 1. Tokenise the symptom string.
|
|
55
|
+
* 2. For each playbook, score each of its applicableSymptoms phrases.
|
|
56
|
+
* 3. Take the maximum score across phrases as the playbook's confidence.
|
|
57
|
+
* 4. Return all playbooks with confidence > 0, sorted descending by confidence.
|
|
58
|
+
*
|
|
59
|
+
* @param symptom The free-text symptom string from the incident.
|
|
60
|
+
* @param projectRoot Absolute path to the project root. Defaults to process.cwd().
|
|
61
|
+
*/
|
|
62
|
+
export declare function searchPlaybooks(symptom: string, projectRoot?: string): Promise<PlaybookMatch[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Search a pre-loaded list of playbooks. Useful for testing without touching disk.
|
|
65
|
+
*/
|
|
66
|
+
export declare function searchPlaybooksList(symptom: string, playbooks: Playbook[]): PlaybookMatch[];
|
|
67
|
+
//# sourceMappingURL=playbook-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playbook-search.d.ts","sourceRoot":"","sources":["../../src/incident/playbook-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,0EAA0E;AAC1E,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAI5C,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,UAAU,GAAG,WAAW,CAAC;IACzC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/C;AA8ID;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAuD5E;AAwBD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,EAAE,CAAC,CAI1B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,QAAQ,EAAE,GACpB,aAAa,EAAE,CAkCjB"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playbook search — symptom-to-playbook matching (Sprint 25).
|
|
3
|
+
*
|
|
4
|
+
* Loads playbooks from .bober/playbooks/*.md (skipping README.md).
|
|
5
|
+
* Each playbook frontmatter (name, classification, applicableSymptoms,
|
|
6
|
+
* prerequisites) is parsed via a minimal YAML block parser — no external dep.
|
|
7
|
+
*
|
|
8
|
+
* searchPlaybooks(symptom) tokenises the symptom string, scores each
|
|
9
|
+
* playbook's applicableSymptoms by token overlap, and returns matches
|
|
10
|
+
* sorted by confidence descending.
|
|
11
|
+
*
|
|
12
|
+
* Confidence thresholds (exported constants):
|
|
13
|
+
* HIGH_CONFIDENCE_THRESHOLD = 0.6 → diagnoser auto-follows playbook
|
|
14
|
+
* LOW_CONFIDENCE_THRESHOLD = 0.3 → diagnoser surfaces as suggestion
|
|
15
|
+
*
|
|
16
|
+
* Sprint 25 — src/incident/playbook-search.ts
|
|
17
|
+
*/
|
|
18
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
// ── Confidence thresholds ─────────────────────────────────────────────────────
|
|
21
|
+
/** A match at or above this threshold triggers automatic playbook execution. */
|
|
22
|
+
export const HIGH_CONFIDENCE_THRESHOLD = 0.6;
|
|
23
|
+
/** A match at or above this (and below HIGH) surfaces as a suggestion. */
|
|
24
|
+
export const LOW_CONFIDENCE_THRESHOLD = 0.3;
|
|
25
|
+
// ── Stop-word list ────────────────────────────────────────────────────────────
|
|
26
|
+
const STOPWORDS = new Set([
|
|
27
|
+
"the", "is", "a", "an", "in", "on", "at", "of", "to", "for", "and", "or",
|
|
28
|
+
"be", "are", "was", "were", "has", "have", "had", "been", "not", "by",
|
|
29
|
+
"it", "its", "this", "that", "but", "with", "from", "as", "up",
|
|
30
|
+
]);
|
|
31
|
+
// ── Tokenizer ─────────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Tokenise a string into lowercase, non-empty, non-stopword tokens.
|
|
34
|
+
* Splits on whitespace and common punctuation.
|
|
35
|
+
*/
|
|
36
|
+
export function tokenize(text) {
|
|
37
|
+
return text
|
|
38
|
+
.toLowerCase()
|
|
39
|
+
.split(/[\s\-_/.,;:!?()[\]{}'"]+/)
|
|
40
|
+
.filter((t) => t.length > 0 && !STOPWORDS.has(t));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse the YAML frontmatter block between the first two `---` lines.
|
|
44
|
+
* Handles only the simple types used in playbook files:
|
|
45
|
+
* - scalar: key: value
|
|
46
|
+
* - list: key:\n - item\n - item
|
|
47
|
+
*
|
|
48
|
+
* Returns null if no frontmatter block is found.
|
|
49
|
+
*/
|
|
50
|
+
function parseFrontmatter(content) {
|
|
51
|
+
// Must start with ---
|
|
52
|
+
const lines = content.split("\n");
|
|
53
|
+
if (lines[0]?.trim() !== "---")
|
|
54
|
+
return null;
|
|
55
|
+
// Find closing ---
|
|
56
|
+
let closingIdx = -1;
|
|
57
|
+
for (let i = 1; i < lines.length; i++) {
|
|
58
|
+
if (lines[i]?.trim() === "---") {
|
|
59
|
+
closingIdx = i;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (closingIdx === -1)
|
|
64
|
+
return null;
|
|
65
|
+
const yamlLines = lines.slice(1, closingIdx);
|
|
66
|
+
const result = {};
|
|
67
|
+
let currentKey = null;
|
|
68
|
+
let currentList = null;
|
|
69
|
+
for (const raw of yamlLines) {
|
|
70
|
+
const line = raw;
|
|
71
|
+
// List item under a key
|
|
72
|
+
if (line.startsWith(" - ") || line.startsWith(" - ")) {
|
|
73
|
+
const item = line.replace(/^\s+-\s*/, "").trim();
|
|
74
|
+
if (currentList !== null && currentKey !== null) {
|
|
75
|
+
currentList.push(item);
|
|
76
|
+
}
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// Flush previous list if any
|
|
80
|
+
if (currentList !== null && currentKey !== null) {
|
|
81
|
+
switch (currentKey) {
|
|
82
|
+
case "applicableSymptoms":
|
|
83
|
+
result.applicableSymptoms = currentList;
|
|
84
|
+
break;
|
|
85
|
+
case "prerequisites":
|
|
86
|
+
result.prerequisites = currentList;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
currentList = null;
|
|
90
|
+
currentKey = null;
|
|
91
|
+
}
|
|
92
|
+
// Key: value or Key: (start of list)
|
|
93
|
+
const colonIdx = line.indexOf(":");
|
|
94
|
+
if (colonIdx === -1)
|
|
95
|
+
continue;
|
|
96
|
+
const key = line.slice(0, colonIdx).trim();
|
|
97
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
98
|
+
if (value === "") {
|
|
99
|
+
// Start of a list block
|
|
100
|
+
currentKey = key;
|
|
101
|
+
currentList = [];
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Scalar
|
|
105
|
+
switch (key) {
|
|
106
|
+
case "name":
|
|
107
|
+
result.name = value;
|
|
108
|
+
break;
|
|
109
|
+
case "classification":
|
|
110
|
+
result.classification = value;
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
currentKey = null;
|
|
116
|
+
currentList = null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Flush trailing list
|
|
120
|
+
if (currentList !== null && currentKey !== null) {
|
|
121
|
+
switch (currentKey) {
|
|
122
|
+
case "applicableSymptoms":
|
|
123
|
+
result.applicableSymptoms = currentList;
|
|
124
|
+
break;
|
|
125
|
+
case "prerequisites":
|
|
126
|
+
result.prerequisites = currentList;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Extract step sections from the markdown body (after the frontmatter).
|
|
134
|
+
* A step section starts with `## Step N:` and ends before the next `## Step` or EOF.
|
|
135
|
+
*/
|
|
136
|
+
function extractSteps(content) {
|
|
137
|
+
const lines = content.split("\n");
|
|
138
|
+
// Skip frontmatter
|
|
139
|
+
let bodyStart = 0;
|
|
140
|
+
if (lines[0]?.trim() === "---") {
|
|
141
|
+
for (let i = 1; i < lines.length; i++) {
|
|
142
|
+
if (lines[i]?.trim() === "---") {
|
|
143
|
+
bodyStart = i + 1;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const steps = [];
|
|
149
|
+
let currentStep = null;
|
|
150
|
+
for (let i = bodyStart; i < lines.length; i++) {
|
|
151
|
+
const line = lines[i] ?? "";
|
|
152
|
+
if (/^##\s+Step\s+\d+:/.test(line)) {
|
|
153
|
+
if (currentStep !== null) {
|
|
154
|
+
steps.push(currentStep.join("\n").trim());
|
|
155
|
+
}
|
|
156
|
+
currentStep = [line];
|
|
157
|
+
}
|
|
158
|
+
else if (currentStep !== null) {
|
|
159
|
+
currentStep.push(line);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (currentStep !== null) {
|
|
163
|
+
steps.push(currentStep.join("\n").trim());
|
|
164
|
+
}
|
|
165
|
+
return steps;
|
|
166
|
+
}
|
|
167
|
+
// ── loadPlaybooks ─────────────────────────────────────────────────────────────
|
|
168
|
+
/**
|
|
169
|
+
* Load all playbooks from .bober/playbooks/*.md in the given projectRoot.
|
|
170
|
+
* - Skips README.md
|
|
171
|
+
* - Skips files with missing or malformed frontmatter (logs a warning)
|
|
172
|
+
* - Returns [] gracefully when the directory does not exist
|
|
173
|
+
*/
|
|
174
|
+
export async function loadPlaybooks(projectRoot) {
|
|
175
|
+
const playbooksDir = join(projectRoot, ".bober", "playbooks");
|
|
176
|
+
let entries;
|
|
177
|
+
try {
|
|
178
|
+
entries = await readdir(playbooksDir);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
if (err.code === "ENOENT")
|
|
182
|
+
return [];
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
const mdFiles = entries.filter((e) => e.endsWith(".md") && e.toLowerCase() !== "readme.md");
|
|
186
|
+
const playbooks = [];
|
|
187
|
+
for (const filename of mdFiles) {
|
|
188
|
+
const filePath = join(playbooksDir, filename);
|
|
189
|
+
let content;
|
|
190
|
+
try {
|
|
191
|
+
content = await readFile(filePath, "utf-8");
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
process.stderr.write(`[playbook-search] warning: could not read ${filePath}\n`);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const fm = parseFrontmatter(content);
|
|
198
|
+
if (fm === null) {
|
|
199
|
+
process.stderr.write(`[playbook-search] warning: no frontmatter in ${filename}, skipping\n`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (!fm.name || !fm.classification || !fm.applicableSymptoms?.length) {
|
|
203
|
+
process.stderr.write(`[playbook-search] warning: malformed frontmatter in ${filename} (missing name/classification/applicableSymptoms), skipping\n`);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const classification = fm.classification;
|
|
207
|
+
if (classification !== "standard" && classification !== "emergency") {
|
|
208
|
+
process.stderr.write(`[playbook-search] warning: unknown classification '${fm.classification}' in ${filename}, skipping\n`);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
playbooks.push({
|
|
212
|
+
name: fm.name,
|
|
213
|
+
classification,
|
|
214
|
+
applicableSymptoms: fm.applicableSymptoms,
|
|
215
|
+
prerequisites: fm.prerequisites ?? [],
|
|
216
|
+
filePath,
|
|
217
|
+
stepSections: extractSteps(content),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return playbooks;
|
|
221
|
+
}
|
|
222
|
+
// ── Scoring helper ────────────────────────────────────────────────────────────
|
|
223
|
+
/**
|
|
224
|
+
* Score a symptom query against a single symptom phrase.
|
|
225
|
+
*
|
|
226
|
+
* score = (number of overlapping tokens) / (number of tokens in the phrase)
|
|
227
|
+
*
|
|
228
|
+
* Clamped to [0, 1].
|
|
229
|
+
*/
|
|
230
|
+
function scoreAgainstPhrase(queryTokens, phrase) {
|
|
231
|
+
const phraseTokens = tokenize(phrase);
|
|
232
|
+
if (phraseTokens.length === 0)
|
|
233
|
+
return { score: 0, matchedTokens: [] };
|
|
234
|
+
const matched = phraseTokens.filter((t) => queryTokens.has(t));
|
|
235
|
+
const score = Math.min(1, matched.length / phraseTokens.length);
|
|
236
|
+
return { score, matchedTokens: matched };
|
|
237
|
+
}
|
|
238
|
+
// ── searchPlaybooks ───────────────────────────────────────────────────────────
|
|
239
|
+
/**
|
|
240
|
+
* Search the playbook library for playbooks matching the given symptom string.
|
|
241
|
+
*
|
|
242
|
+
* Algorithm:
|
|
243
|
+
* 1. Tokenise the symptom string.
|
|
244
|
+
* 2. For each playbook, score each of its applicableSymptoms phrases.
|
|
245
|
+
* 3. Take the maximum score across phrases as the playbook's confidence.
|
|
246
|
+
* 4. Return all playbooks with confidence > 0, sorted descending by confidence.
|
|
247
|
+
*
|
|
248
|
+
* @param symptom The free-text symptom string from the incident.
|
|
249
|
+
* @param projectRoot Absolute path to the project root. Defaults to process.cwd().
|
|
250
|
+
*/
|
|
251
|
+
export async function searchPlaybooks(symptom, projectRoot) {
|
|
252
|
+
const root = projectRoot ?? process.cwd();
|
|
253
|
+
const playbooks = await loadPlaybooks(root);
|
|
254
|
+
return searchPlaybooksList(symptom, playbooks);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Search a pre-loaded list of playbooks. Useful for testing without touching disk.
|
|
258
|
+
*/
|
|
259
|
+
export function searchPlaybooksList(symptom, playbooks) {
|
|
260
|
+
const queryTokens = new Set(tokenize(symptom));
|
|
261
|
+
if (queryTokens.size === 0)
|
|
262
|
+
return [];
|
|
263
|
+
const matches = [];
|
|
264
|
+
for (const playbook of playbooks) {
|
|
265
|
+
let bestScore = 0;
|
|
266
|
+
let bestMatchedTokens = [];
|
|
267
|
+
for (const phrase of playbook.applicableSymptoms) {
|
|
268
|
+
const { score, matchedTokens } = scoreAgainstPhrase(queryTokens, phrase);
|
|
269
|
+
if (score > bestScore) {
|
|
270
|
+
bestScore = score;
|
|
271
|
+
bestMatchedTokens = matchedTokens;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (bestScore > 0) {
|
|
275
|
+
matches.push({
|
|
276
|
+
playbook,
|
|
277
|
+
confidence: bestScore,
|
|
278
|
+
matchedTokens: bestMatchedTokens,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Sort descending by confidence; ties broken by name for determinism.
|
|
283
|
+
matches.sort((a, b) => b.confidence !== a.confidence
|
|
284
|
+
? b.confidence - a.confidence
|
|
285
|
+
: a.playbook.name.localeCompare(b.playbook.name));
|
|
286
|
+
return matches;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=playbook-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playbook-search.js","sourceRoot":"","sources":["../../src/incident/playbook-search.ts"],"names":[],"mappings":"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"}
|