agent-bober 0.18.0 → 0.19.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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/README.md +245 -6
- package/agents/bober-art-director.md +100 -0
- package/agents/bober-design-critic.md +114 -0
- package/agents/bober-frontend-builder.md +101 -0
- package/agents/bober-security-auditor.md +193 -0
- package/agents/bober-security-verifier.md +104 -0
- package/agents/bober-seo-strategist.md +144 -0
- package/agents/bober-seo-verifier.md +103 -0
- package/dist/calendar/calendar-egress.d.ts +26 -0
- package/dist/calendar/calendar-egress.d.ts.map +1 -0
- package/dist/calendar/calendar-egress.js +35 -0
- package/dist/calendar/calendar-egress.js.map +1 -0
- package/dist/calendar/calendar-token.d.ts +34 -0
- package/dist/calendar/calendar-token.d.ts.map +1 -0
- package/dist/calendar/calendar-token.js +56 -0
- package/dist/calendar/calendar-token.js.map +1 -0
- package/dist/calendar/connector.d.ts +22 -0
- package/dist/calendar/connector.d.ts.map +1 -0
- package/dist/calendar/connector.js +3 -0
- package/dist/calendar/connector.js.map +1 -0
- package/dist/calendar/finding-source.d.ts +20 -0
- package/dist/calendar/finding-source.d.ts.map +1 -0
- package/dist/calendar/finding-source.js +35 -0
- package/dist/calendar/finding-source.js.map +1 -0
- package/dist/calendar/google-connector.d.ts +65 -0
- package/dist/calendar/google-connector.d.ts.map +1 -0
- package/dist/calendar/google-connector.js +129 -0
- package/dist/calendar/google-connector.js.map +1 -0
- package/dist/calendar/ics-connector.d.ts +12 -0
- package/dist/calendar/ics-connector.d.ts.map +1 -0
- package/dist/calendar/ics-connector.js +48 -0
- package/dist/calendar/ics-connector.js.map +1 -0
- package/dist/calendar/proposal-gate.d.ts +84 -0
- package/dist/calendar/proposal-gate.d.ts.map +1 -0
- package/dist/calendar/proposal-gate.js +126 -0
- package/dist/calendar/proposal-gate.js.map +1 -0
- package/dist/calendar/slotter.d.ts +34 -0
- package/dist/calendar/slotter.d.ts.map +1 -0
- package/dist/calendar/slotter.js +196 -0
- package/dist/calendar/slotter.js.map +1 -0
- package/dist/calendar/types.d.ts +162 -0
- package/dist/calendar/types.d.ts.map +1 -0
- package/dist/calendar/types.js +28 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/chat/chat-session.d.ts +27 -0
- package/dist/chat/chat-session.d.ts.map +1 -1
- package/dist/chat/chat-session.js +101 -1
- package/dist/chat/chat-session.js.map +1 -1
- package/dist/chat/slash-commands.d.ts +6 -2
- package/dist/chat/slash-commands.d.ts.map +1 -1
- package/dist/chat/slash-commands.js +22 -2
- package/dist/chat/slash-commands.js.map +1 -1
- package/dist/chat/turn-classifier.d.ts +3 -0
- package/dist/chat/turn-classifier.d.ts.map +1 -1
- package/dist/chat/turn-classifier.js +7 -0
- package/dist/chat/turn-classifier.js.map +1 -1
- package/dist/cli/commands/calendar.d.ts +75 -0
- package/dist/cli/commands/calendar.d.ts.map +1 -0
- package/dist/cli/commands/calendar.js +203 -0
- package/dist/cli/commands/calendar.js.map +1 -0
- package/dist/cli/commands/do.d.ts +52 -0
- package/dist/cli/commands/do.d.ts.map +1 -0
- package/dist/cli/commands/do.js +216 -0
- package/dist/cli/commands/do.js.map +1 -0
- package/dist/cli/commands/hub.d.ts +29 -0
- package/dist/cli/commands/hub.d.ts.map +1 -0
- package/dist/cli/commands/hub.js +233 -0
- package/dist/cli/commands/hub.js.map +1 -0
- package/dist/cli/commands/medical.d.ts +25 -0
- package/dist/cli/commands/medical.d.ts.map +1 -1
- package/dist/cli/commands/medical.js +233 -0
- package/dist/cli/commands/medical.js.map +1 -1
- package/dist/cli/commands/research.d.ts +41 -0
- package/dist/cli/commands/research.d.ts.map +1 -0
- package/dist/cli/commands/research.js +313 -0
- package/dist/cli/commands/research.js.map +1 -0
- package/dist/cli/commands/security-audit.d.ts +89 -0
- package/dist/cli/commands/security-audit.d.ts.map +1 -0
- package/dist/cli/commands/security-audit.js +238 -0
- package/dist/cli/commands/security-audit.js.map +1 -0
- package/dist/cli/commands/task.d.ts +64 -0
- package/dist/cli/commands/task.d.ts.map +1 -0
- package/dist/cli/commands/task.js +422 -0
- package/dist/cli/commands/task.js.map +1 -0
- package/dist/cli/commands/telegram.d.ts +10 -0
- package/dist/cli/commands/telegram.d.ts.map +1 -0
- package/dist/cli/commands/telegram.js +44 -0
- package/dist/cli/commands/telegram.js.map +1 -0
- package/dist/cli/commands/vault.d.ts +40 -0
- package/dist/cli/commands/vault.d.ts.map +1 -0
- package/dist/cli/commands/vault.js +122 -0
- package/dist/cli/commands/vault.js.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/role-providers.d.ts +15 -0
- package/dist/config/role-providers.d.ts.map +1 -1
- package/dist/config/role-providers.js +8 -1
- package/dist/config/role-providers.js.map +1 -1
- package/dist/config/schema.d.ts +3522 -171
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +405 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/do-bridge/coding-promoter.d.ts +19 -0
- package/dist/do-bridge/coding-promoter.d.ts.map +1 -0
- package/dist/do-bridge/coding-promoter.js +43 -0
- package/dist/do-bridge/coding-promoter.js.map +1 -0
- package/dist/do-bridge/finding-port.d.ts +88 -0
- package/dist/do-bridge/finding-port.d.ts.map +1 -0
- package/dist/do-bridge/finding-port.js +95 -0
- package/dist/do-bridge/finding-port.js.map +1 -0
- package/dist/do-bridge/launcher.d.ts +55 -0
- package/dist/do-bridge/launcher.d.ts.map +1 -0
- package/dist/do-bridge/launcher.js +37 -0
- package/dist/do-bridge/launcher.js.map +1 -0
- package/dist/do-bridge/promote.d.ts +50 -0
- package/dist/do-bridge/promote.d.ts.map +1 -0
- package/dist/do-bridge/promote.js +116 -0
- package/dist/do-bridge/promote.js.map +1 -0
- package/dist/do-bridge/reconcile.d.ts +50 -0
- package/dist/do-bridge/reconcile.d.ts.map +1 -0
- package/dist/do-bridge/reconcile.js +70 -0
- package/dist/do-bridge/reconcile.js.map +1 -0
- package/dist/do-bridge/registry.d.ts +23 -0
- package/dist/do-bridge/registry.d.ts.map +1 -0
- package/dist/do-bridge/registry.js +42 -0
- package/dist/do-bridge/registry.js.map +1 -0
- package/dist/do-bridge/types.d.ts +50 -0
- package/dist/do-bridge/types.d.ts.map +1 -0
- package/dist/do-bridge/types.js +17 -0
- package/dist/do-bridge/types.js.map +1 -0
- package/dist/fleet/child-config.d.ts.map +1 -1
- package/dist/fleet/child-config.js +7 -0
- package/dist/fleet/child-config.js.map +1 -1
- package/dist/fleet/coordinator.d.ts +27 -1
- package/dist/fleet/coordinator.d.ts.map +1 -1
- package/dist/fleet/coordinator.js +70 -0
- package/dist/fleet/coordinator.js.map +1 -1
- package/dist/fleet/critic-deep.d.ts +9 -1
- package/dist/fleet/critic-deep.d.ts.map +1 -1
- package/dist/fleet/critic-deep.js +5 -2
- package/dist/fleet/critic-deep.js.map +1 -1
- package/dist/fleet/decomposer-deep.d.ts +4 -11
- package/dist/fleet/decomposer-deep.d.ts.map +1 -1
- package/dist/fleet/decomposer-deep.js +5 -5
- package/dist/fleet/decomposer-deep.js.map +1 -1
- package/dist/fleet/index.d.ts +9 -0
- package/dist/fleet/index.d.ts.map +1 -1
- package/dist/fleet/index.js +87 -8
- package/dist/fleet/index.js.map +1 -1
- package/dist/fleet/manifest.d.ts +26 -0
- package/dist/fleet/manifest.d.ts.map +1 -1
- package/dist/fleet/manifest.js +8 -0
- package/dist/fleet/manifest.js.map +1 -1
- package/dist/fleet/reporter.d.ts +4 -1
- package/dist/fleet/reporter.d.ts.map +1 -1
- package/dist/fleet/reporter.js +2 -1
- package/dist/fleet/reporter.js.map +1 -1
- package/dist/fleet/scaffolder.d.ts +5 -1
- package/dist/fleet/scaffolder.d.ts.map +1 -1
- package/dist/fleet/scaffolder.js +11 -2
- package/dist/fleet/scaffolder.js.map +1 -1
- package/dist/graph/client.d.ts.map +1 -1
- package/dist/graph/client.js +115 -23
- package/dist/graph/client.js.map +1 -1
- package/dist/graph/mcp-client.d.ts +1 -0
- package/dist/graph/mcp-client.d.ts.map +1 -1
- package/dist/graph/mcp-client.js +58 -7
- package/dist/graph/mcp-client.js.map +1 -1
- package/dist/hub/collector.d.ts +12 -0
- package/dist/hub/collector.d.ts.map +1 -0
- package/dist/hub/collector.js +36 -0
- package/dist/hub/collector.js.map +1 -0
- package/dist/hub/finding-source.d.ts +22 -0
- package/dist/hub/finding-source.d.ts.map +1 -0
- package/dist/hub/finding-source.js +41 -0
- package/dist/hub/finding-source.js.map +1 -0
- package/dist/hub/finding-store.d.ts +68 -0
- package/dist/hub/finding-store.d.ts.map +1 -0
- package/dist/hub/finding-store.js +122 -0
- package/dist/hub/finding-store.js.map +1 -0
- package/dist/hub/finding.d.ts +54 -0
- package/dist/hub/finding.d.ts.map +1 -0
- package/dist/hub/finding.js +24 -0
- package/dist/hub/finding.js.map +1 -0
- package/dist/hub/gmail-to-task.d.ts +69 -0
- package/dist/hub/gmail-to-task.d.ts.map +1 -0
- package/dist/hub/gmail-to-task.js +102 -0
- package/dist/hub/gmail-to-task.js.map +1 -0
- package/dist/hub/hub-config.d.ts +18 -0
- package/dist/hub/hub-config.d.ts.map +1 -0
- package/dist/hub/hub-config.js +40 -0
- package/dist/hub/hub-config.js.map +1 -0
- package/dist/hub/judge.d.ts +30 -0
- package/dist/hub/judge.d.ts.map +1 -0
- package/dist/hub/judge.js +177 -0
- package/dist/hub/judge.js.map +1 -0
- package/dist/hub/lenses.d.ts +60 -0
- package/dist/hub/lenses.d.ts.map +1 -0
- package/dist/hub/lenses.js +123 -0
- package/dist/hub/lenses.js.map +1 -0
- package/dist/hub/priority-md.d.ts +21 -0
- package/dist/hub/priority-md.d.ts.map +1 -0
- package/dist/hub/priority-md.js +64 -0
- package/dist/hub/priority-md.js.map +1 -0
- package/dist/hub/repo-resolver.d.ts +11 -0
- package/dist/hub/repo-resolver.d.ts.map +1 -0
- package/dist/hub/repo-resolver.js +39 -0
- package/dist/hub/repo-resolver.js.map +1 -0
- package/dist/hub/scope.d.ts +39 -0
- package/dist/hub/scope.d.ts.map +1 -0
- package/dist/hub/scope.js +62 -0
- package/dist/hub/scope.js.map +1 -0
- package/dist/hub/task-inbox.d.ts +16 -0
- package/dist/hub/task-inbox.d.ts.map +1 -0
- package/dist/hub/task-inbox.js +39 -0
- package/dist/hub/task-inbox.js.map +1 -0
- package/dist/incident/resolution-verify.d.ts +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/medical/adapters/apple-health.js +1 -1
- package/dist/medical/adapters/apple-health.js.map +1 -1
- package/dist/medical/analysis/cadence.d.ts +32 -0
- package/dist/medical/analysis/cadence.d.ts.map +1 -0
- package/dist/medical/analysis/cadence.js +72 -0
- package/dist/medical/analysis/cadence.js.map +1 -0
- package/dist/medical/analysis/cross-marker.d.ts +33 -0
- package/dist/medical/analysis/cross-marker.d.ts.map +1 -0
- package/dist/medical/analysis/cross-marker.js +79 -0
- package/dist/medical/analysis/cross-marker.js.map +1 -0
- package/dist/medical/analysis/finding-writer.d.ts +26 -0
- package/dist/medical/analysis/finding-writer.d.ts.map +1 -0
- package/dist/medical/analysis/finding-writer.js +60 -0
- package/dist/medical/analysis/finding-writer.js.map +1 -0
- package/dist/medical/analysis/finding.d.ts +63 -0
- package/dist/medical/analysis/finding.d.ts.map +1 -0
- package/dist/medical/analysis/finding.js +70 -0
- package/dist/medical/analysis/finding.js.map +1 -0
- package/dist/medical/analysis/review-pass.d.ts +76 -0
- package/dist/medical/analysis/review-pass.d.ts.map +1 -0
- package/dist/medical/analysis/review-pass.js +119 -0
- package/dist/medical/analysis/review-pass.js.map +1 -0
- package/dist/medical/analysis/trends.d.ts +36 -0
- package/dist/medical/analysis/trends.d.ts.map +1 -0
- package/dist/medical/analysis/trends.js +157 -0
- package/dist/medical/analysis/trends.js.map +1 -0
- package/dist/medical/health-store.d.ts +5 -0
- package/dist/medical/health-store.d.ts.map +1 -1
- package/dist/medical/health-store.js +10 -0
- package/dist/medical/health-store.js.map +1 -1
- package/dist/medical/lab-note.d.ts +72 -0
- package/dist/medical/lab-note.d.ts.map +1 -0
- package/dist/medical/lab-note.js +161 -0
- package/dist/medical/lab-note.js.map +1 -0
- package/dist/medical/lab-pdf-parser.d.ts +19 -0
- package/dist/medical/lab-pdf-parser.d.ts.map +1 -0
- package/dist/medical/lab-pdf-parser.js +57 -0
- package/dist/medical/lab-pdf-parser.js.map +1 -0
- package/dist/medical/lab-reindex.d.ts +24 -0
- package/dist/medical/lab-reindex.d.ts.map +1 -0
- package/dist/medical/lab-reindex.js +45 -0
- package/dist/medical/lab-reindex.js.map +1 -0
- package/dist/medical/lab-types.d.ts +75 -0
- package/dist/medical/lab-types.d.ts.map +1 -0
- package/dist/medical/lab-types.js +17 -0
- package/dist/medical/lab-types.js.map +1 -0
- package/dist/medical/profile.d.ts +96 -0
- package/dist/medical/profile.d.ts.map +1 -0
- package/dist/medical/profile.js +273 -0
- package/dist/medical/profile.js.map +1 -0
- package/dist/medical/recommend/context.d.ts +48 -0
- package/dist/medical/recommend/context.d.ts.map +1 -0
- package/dist/medical/recommend/context.js +109 -0
- package/dist/medical/recommend/context.js.map +1 -0
- package/dist/medical/recommend/judge-panel.d.ts +49 -0
- package/dist/medical/recommend/judge-panel.d.ts.map +1 -0
- package/dist/medical/recommend/judge-panel.js +164 -0
- package/dist/medical/recommend/judge-panel.js.map +1 -0
- package/dist/medical/recommend/lenses.d.ts +72 -0
- package/dist/medical/recommend/lenses.d.ts.map +1 -0
- package/dist/medical/recommend/lenses.js +220 -0
- package/dist/medical/recommend/lenses.js.map +1 -0
- package/dist/medical/recommend/recommend.d.ts +86 -0
- package/dist/medical/recommend/recommend.d.ts.map +1 -0
- package/dist/medical/recommend/recommend.js +211 -0
- package/dist/medical/recommend/recommend.js.map +1 -0
- package/dist/medical/recommend/types.d.ts +98 -0
- package/dist/medical/recommend/types.d.ts.map +1 -0
- package/dist/medical/recommend/types.js +20 -0
- package/dist/medical/recommend/types.js.map +1 -0
- package/dist/medical/recommend/urgency.d.ts +26 -0
- package/dist/medical/recommend/urgency.d.ts.map +1 -0
- package/dist/medical/recommend/urgency.js +124 -0
- package/dist/medical/recommend/urgency.js.map +1 -0
- package/dist/medical/research/online-research.d.ts +65 -0
- package/dist/medical/research/online-research.d.ts.map +1 -0
- package/dist/medical/research/online-research.js +101 -0
- package/dist/medical/research/online-research.js.map +1 -0
- package/dist/medical/research/research-note.d.ts +32 -0
- package/dist/medical/research/research-note.d.ts.map +1 -0
- package/dist/medical/research/research-note.js +55 -0
- package/dist/medical/research/research-note.js.map +1 -0
- package/dist/medical/supplements.d.ts +82 -0
- package/dist/medical/supplements.d.ts.map +1 -0
- package/dist/medical/supplements.js +173 -0
- package/dist/medical/supplements.js.map +1 -0
- package/dist/orchestrator/agentic-loop.d.ts +160 -1
- package/dist/orchestrator/agentic-loop.d.ts.map +1 -1
- package/dist/orchestrator/agentic-loop.js +350 -41
- package/dist/orchestrator/agentic-loop.js.map +1 -1
- package/dist/orchestrator/compaction.d.ts +47 -0
- package/dist/orchestrator/compaction.d.ts.map +1 -0
- package/dist/orchestrator/compaction.js +75 -0
- package/dist/orchestrator/compaction.js.map +1 -0
- package/dist/orchestrator/generator-agent.d.ts +19 -0
- package/dist/orchestrator/generator-agent.d.ts.map +1 -1
- package/dist/orchestrator/generator-agent.js +27 -1
- package/dist/orchestrator/generator-agent.js.map +1 -1
- package/dist/orchestrator/loop-events.d.ts +98 -0
- package/dist/orchestrator/loop-events.d.ts.map +1 -0
- package/dist/orchestrator/loop-events.js +2 -0
- package/dist/orchestrator/loop-events.js.map +1 -0
- package/dist/orchestrator/model-resolver.d.ts.map +1 -1
- package/dist/orchestrator/model-resolver.js +10 -6
- package/dist/orchestrator/model-resolver.js.map +1 -1
- package/dist/orchestrator/pipeline.d.ts +10 -1
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +102 -4
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/security-audit-types.d.ts +53 -0
- package/dist/orchestrator/security-audit-types.d.ts.map +1 -0
- package/dist/orchestrator/security-audit-types.js +10 -0
- package/dist/orchestrator/security-audit-types.js.map +1 -0
- package/dist/orchestrator/security-auditor-agent.d.ts +68 -0
- package/dist/orchestrator/security-auditor-agent.d.ts.map +1 -0
- package/dist/orchestrator/security-auditor-agent.js +482 -0
- package/dist/orchestrator/security-auditor-agent.js.map +1 -0
- package/dist/orchestrator/security-gate.d.ts +73 -0
- package/dist/orchestrator/security-gate.d.ts.map +1 -0
- package/dist/orchestrator/security-gate.js +174 -0
- package/dist/orchestrator/security-gate.js.map +1 -0
- package/dist/orchestrator/security-hub.d.ts +45 -0
- package/dist/orchestrator/security-hub.d.ts.map +1 -0
- package/dist/orchestrator/security-hub.js +147 -0
- package/dist/orchestrator/security-hub.js.map +1 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.d.ts +43 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.js +13 -0
- package/dist/orchestrator/security-knowledge/benchmark/harness.js.map +1 -0
- package/dist/orchestrator/security-knowledge/diff-provider.d.ts +79 -0
- package/dist/orchestrator/security-knowledge/diff-provider.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/diff-provider.js +320 -0
- package/dist/orchestrator/security-knowledge/diff-provider.js.map +1 -0
- package/dist/orchestrator/security-knowledge/index.d.ts +22 -0
- package/dist/orchestrator/security-knowledge/index.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/index.js +66 -0
- package/dist/orchestrator/security-knowledge/index.js.map +1 -0
- package/dist/orchestrator/security-knowledge/parser.d.ts +9 -0
- package/dist/orchestrator/security-knowledge/parser.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/parser.js +137 -0
- package/dist/orchestrator/security-knowledge/parser.js.map +1 -0
- package/dist/orchestrator/security-knowledge/registry.d.ts +25 -0
- package/dist/orchestrator/security-knowledge/registry.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/registry.js +114 -0
- package/dist/orchestrator/security-knowledge/registry.js.map +1 -0
- package/dist/orchestrator/security-knowledge/resolver.d.ts +48 -0
- package/dist/orchestrator/security-knowledge/resolver.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/resolver.js +63 -0
- package/dist/orchestrator/security-knowledge/resolver.js.map +1 -0
- package/dist/orchestrator/security-knowledge/selector.d.ts +18 -0
- package/dist/orchestrator/security-knowledge/selector.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/selector.js +46 -0
- package/dist/orchestrator/security-knowledge/selector.js.map +1 -0
- package/dist/orchestrator/security-knowledge/signature.d.ts +37 -0
- package/dist/orchestrator/security-knowledge/signature.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/signature.js +2 -0
- package/dist/orchestrator/security-knowledge/signature.js.map +1 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.d.ts +29 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.d.ts.map +1 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.js +211 -0
- package/dist/orchestrator/security-knowledge/supply-chain-inspector.js.map +1 -0
- package/dist/orchestrator/security-scanners.d.ts +126 -0
- package/dist/orchestrator/security-scanners.d.ts.map +1 -0
- package/dist/orchestrator/security-scanners.js +501 -0
- package/dist/orchestrator/security-scanners.js.map +1 -0
- package/dist/orchestrator/security-verifier-agent.d.ts +62 -0
- package/dist/orchestrator/security-verifier-agent.d.ts.map +1 -0
- package/dist/orchestrator/security-verifier-agent.js +230 -0
- package/dist/orchestrator/security-verifier-agent.js.map +1 -0
- package/dist/orchestrator/session-store.d.ts +95 -0
- package/dist/orchestrator/session-store.d.ts.map +1 -0
- package/dist/orchestrator/session-store.js +186 -0
- package/dist/orchestrator/session-store.js.map +1 -0
- package/dist/orchestrator/stack-knowledge.d.ts +17 -0
- package/dist/orchestrator/stack-knowledge.d.ts.map +1 -0
- package/dist/orchestrator/stack-knowledge.js +35 -0
- package/dist/orchestrator/stack-knowledge.js.map +1 -0
- package/dist/orchestrator/subagents.d.ts +62 -0
- package/dist/orchestrator/subagents.d.ts.map +1 -0
- package/dist/orchestrator/subagents.js +143 -0
- package/dist/orchestrator/subagents.js.map +1 -0
- package/dist/orchestrator/tools/executor.d.ts +68 -0
- package/dist/orchestrator/tools/executor.d.ts.map +1 -0
- package/dist/orchestrator/tools/executor.js +104 -0
- package/dist/orchestrator/tools/executor.js.map +1 -0
- package/dist/orchestrator/tools/mcp-bridge.d.ts +76 -0
- package/dist/orchestrator/tools/mcp-bridge.d.ts.map +1 -0
- package/dist/orchestrator/tools/mcp-bridge.js +154 -0
- package/dist/orchestrator/tools/mcp-bridge.js.map +1 -0
- package/dist/orchestrator/tools/schemas.d.ts.map +1 -1
- package/dist/orchestrator/tools/schemas.js +3 -0
- package/dist/orchestrator/tools/schemas.js.map +1 -1
- package/dist/orchestrator/workflow/budget.d.ts +24 -2
- package/dist/orchestrator/workflow/budget.d.ts.map +1 -1
- package/dist/orchestrator/workflow/budget.js +39 -1
- package/dist/orchestrator/workflow/budget.js.map +1 -1
- package/dist/orchestrator/workflow/engine.d.ts +1 -1
- package/dist/orchestrator/workflow/engine.d.ts.map +1 -1
- package/dist/orchestrator/workflow/selector.d.ts.map +1 -1
- package/dist/orchestrator/workflow/selector.js +10 -0
- package/dist/orchestrator/workflow/selector.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +116 -26
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/claude-code.d.ts.map +1 -1
- package/dist/providers/claude-code.js +17 -0
- package/dist/providers/claude-code.js.map +1 -1
- package/dist/providers/cost-meter.d.ts +52 -0
- package/dist/providers/cost-meter.d.ts.map +1 -0
- package/dist/providers/cost-meter.js +81 -0
- package/dist/providers/cost-meter.js.map +1 -0
- package/dist/providers/factory.d.ts +6 -1
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +24 -5
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +29 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/grounded-search.d.ts +128 -0
- package/dist/providers/grounded-search.d.ts.map +1 -0
- package/dist/providers/grounded-search.js +160 -0
- package/dist/providers/grounded-search.js.map +1 -0
- package/dist/providers/openai-compat.d.ts +15 -1
- package/dist/providers/openai-compat.d.ts.map +1 -1
- package/dist/providers/openai-compat.js +24 -0
- package/dist/providers/openai-compat.js.map +1 -1
- package/dist/providers/openai.d.ts +7 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +95 -4
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/types.d.ts +88 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/research/cadence.d.ts +33 -0
- package/dist/research/cadence.d.ts.map +1 -0
- package/dist/research/cadence.js +55 -0
- package/dist/research/cadence.js.map +1 -0
- package/dist/research/digest.d.ts +80 -0
- package/dist/research/digest.d.ts.map +1 -0
- package/dist/research/digest.js +119 -0
- package/dist/research/digest.js.map +1 -0
- package/dist/research/egress.d.ts +28 -0
- package/dist/research/egress.d.ts.map +1 -0
- package/dist/research/egress.js +41 -0
- package/dist/research/egress.js.map +1 -0
- package/dist/research/job-store.d.ts +30 -0
- package/dist/research/job-store.d.ts.map +1 -0
- package/dist/research/job-store.js +100 -0
- package/dist/research/job-store.js.map +1 -0
- package/dist/research/model-diversity.d.ts +27 -0
- package/dist/research/model-diversity.d.ts.map +1 -0
- package/dist/research/model-diversity.js +52 -0
- package/dist/research/model-diversity.js.map +1 -0
- package/dist/research/note-writer.d.ts +36 -0
- package/dist/research/note-writer.d.ts.map +1 -0
- package/dist/research/note-writer.js +53 -0
- package/dist/research/note-writer.js.map +1 -0
- package/dist/research/online-retrieval.d.ts +27 -0
- package/dist/research/online-retrieval.d.ts.map +1 -0
- package/dist/research/online-retrieval.js +22 -0
- package/dist/research/online-retrieval.js.map +1 -0
- package/dist/research/runner.d.ts +80 -0
- package/dist/research/runner.d.ts.map +1 -0
- package/dist/research/runner.js +115 -0
- package/dist/research/runner.js.map +1 -0
- package/dist/research/scheduler.d.ts +61 -0
- package/dist/research/scheduler.d.ts.map +1 -0
- package/dist/research/scheduler.js +58 -0
- package/dist/research/scheduler.js.map +1 -0
- package/dist/research/types.d.ts +81 -0
- package/dist/research/types.d.ts.map +1 -0
- package/dist/research/types.js +57 -0
- package/dist/research/types.js.map +1 -0
- package/dist/seo/adapters/http.d.ts +43 -0
- package/dist/seo/adapters/http.d.ts.map +1 -0
- package/dist/seo/adapters/http.js +35 -0
- package/dist/seo/adapters/http.js.map +1 -0
- package/dist/seo/ai-visibility-provider.d.ts +171 -0
- package/dist/seo/ai-visibility-provider.d.ts.map +1 -0
- package/dist/seo/ai-visibility-provider.js +165 -0
- package/dist/seo/ai-visibility-provider.js.map +1 -0
- package/dist/seo/ai-visibility-scorer.d.ts +43 -0
- package/dist/seo/ai-visibility-scorer.d.ts.map +1 -0
- package/dist/seo/ai-visibility-scorer.js +102 -0
- package/dist/seo/ai-visibility-scorer.js.map +1 -0
- package/dist/seo/analyzer.d.ts +58 -0
- package/dist/seo/analyzer.d.ts.map +1 -0
- package/dist/seo/analyzer.js +265 -0
- package/dist/seo/analyzer.js.map +1 -0
- package/dist/seo/benchmark/harness.d.ts +56 -0
- package/dist/seo/benchmark/harness.d.ts.map +1 -0
- package/dist/seo/benchmark/harness.js +172 -0
- package/dist/seo/benchmark/harness.js.map +1 -0
- package/dist/seo/builder/approved-finding.d.ts +115 -0
- package/dist/seo/builder/approved-finding.d.ts.map +1 -0
- package/dist/seo/builder/approved-finding.js +145 -0
- package/dist/seo/builder/approved-finding.js.map +1 -0
- package/dist/seo/builder/build-runner.d.ts +41 -0
- package/dist/seo/builder/build-runner.d.ts.map +1 -0
- package/dist/seo/builder/build-runner.js +156 -0
- package/dist/seo/builder/build-runner.js.map +1 -0
- package/dist/seo/builder/draft-generators.d.ts +32 -0
- package/dist/seo/builder/draft-generators.d.ts.map +1 -0
- package/dist/seo/builder/draft-generators.js +31 -0
- package/dist/seo/builder/draft-generators.js.map +1 -0
- package/dist/seo/builder/draft-store.d.ts +30 -0
- package/dist/seo/builder/draft-store.d.ts.map +1 -0
- package/dist/seo/builder/draft-store.js +76 -0
- package/dist/seo/builder/draft-store.js.map +1 -0
- package/dist/seo/builder/draft-types.d.ts +36 -0
- package/dist/seo/builder/draft-types.d.ts.map +1 -0
- package/dist/seo/builder/draft-types.js +14 -0
- package/dist/seo/builder/draft-types.js.map +1 -0
- package/dist/seo/builder/hub-approved-source.d.ts +11 -0
- package/dist/seo/builder/hub-approved-source.d.ts.map +1 -0
- package/dist/seo/builder/hub-approved-source.js +48 -0
- package/dist/seo/builder/hub-approved-source.js.map +1 -0
- package/dist/seo/builder/seo-builder.d.ts +72 -0
- package/dist/seo/builder/seo-builder.d.ts.map +1 -0
- package/dist/seo/builder/seo-builder.js +72 -0
- package/dist/seo/builder/seo-builder.js.map +1 -0
- package/dist/seo/citation-gate.d.ts +36 -0
- package/dist/seo/citation-gate.d.ts.map +1 -0
- package/dist/seo/citation-gate.js +59 -0
- package/dist/seo/citation-gate.js.map +1 -0
- package/dist/seo/command.d.ts +11 -0
- package/dist/seo/command.d.ts.map +1 -0
- package/dist/seo/command.js +90 -0
- package/dist/seo/command.js.map +1 -0
- package/dist/seo/content-sanitizer.d.ts +56 -0
- package/dist/seo/content-sanitizer.d.ts.map +1 -0
- package/dist/seo/content-sanitizer.js +55 -0
- package/dist/seo/content-sanitizer.js.map +1 -0
- package/dist/seo/crawl-engine.d.ts +35 -0
- package/dist/seo/crawl-engine.d.ts.map +1 -0
- package/dist/seo/crawl-engine.js +2 -0
- package/dist/seo/crawl-engine.js.map +1 -0
- package/dist/seo/data-source.d.ts +156 -0
- package/dist/seo/data-source.d.ts.map +1 -0
- package/dist/seo/data-source.js +2 -0
- package/dist/seo/data-source.js.map +1 -0
- package/dist/seo/egress.d.ts +39 -0
- package/dist/seo/egress.d.ts.map +1 -0
- package/dist/seo/egress.js +64 -0
- package/dist/seo/egress.js.map +1 -0
- package/dist/seo/hub-emitter.d.ts +28 -0
- package/dist/seo/hub-emitter.d.ts.map +1 -0
- package/dist/seo/hub-emitter.js +95 -0
- package/dist/seo/hub-emitter.js.map +1 -0
- package/dist/seo/index.d.ts +42 -0
- package/dist/seo/index.d.ts.map +1 -0
- package/dist/seo/index.js +19 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/never-encode-filter.d.ts +45 -0
- package/dist/seo/never-encode-filter.d.ts.map +1 -0
- package/dist/seo/never-encode-filter.js +51 -0
- package/dist/seo/never-encode-filter.js.map +1 -0
- package/dist/seo/parser.d.ts +46 -0
- package/dist/seo/parser.d.ts.map +1 -0
- package/dist/seo/parser.js +113 -0
- package/dist/seo/parser.js.map +1 -0
- package/dist/seo/playbook-index.d.ts +19 -0
- package/dist/seo/playbook-index.d.ts.map +1 -0
- package/dist/seo/playbook-index.js +74 -0
- package/dist/seo/playbook-index.js.map +1 -0
- package/dist/seo/quota-governor.d.ts +100 -0
- package/dist/seo/quota-governor.d.ts.map +1 -0
- package/dist/seo/quota-governor.js +199 -0
- package/dist/seo/quota-governor.js.map +1 -0
- package/dist/seo/quota-ledger.d.ts +50 -0
- package/dist/seo/quota-ledger.d.ts.map +1 -0
- package/dist/seo/quota-ledger.js +95 -0
- package/dist/seo/quota-ledger.js.map +1 -0
- package/dist/seo/report-store.d.ts +30 -0
- package/dist/seo/report-store.d.ts.map +1 -0
- package/dist/seo/report-store.js +94 -0
- package/dist/seo/report-store.js.map +1 -0
- package/dist/seo/retriever.d.ts +34 -0
- package/dist/seo/retriever.d.ts.map +1 -0
- package/dist/seo/retriever.js +95 -0
- package/dist/seo/retriever.js.map +1 -0
- package/dist/seo/runner.d.ts +108 -0
- package/dist/seo/runner.d.ts.map +1 -0
- package/dist/seo/runner.js +512 -0
- package/dist/seo/runner.js.map +1 -0
- package/dist/seo/scrape-throttle.d.ts +84 -0
- package/dist/seo/scrape-throttle.d.ts.map +1 -0
- package/dist/seo/scrape-throttle.js +149 -0
- package/dist/seo/scrape-throttle.js.map +1 -0
- package/dist/seo/serp-provider.d.ts +52 -0
- package/dist/seo/serp-provider.d.ts.map +1 -0
- package/dist/seo/serp-provider.js +17 -0
- package/dist/seo/serp-provider.js.map +1 -0
- package/dist/seo/sources/ai-visibility-adapter.d.ts +87 -0
- package/dist/seo/sources/ai-visibility-adapter.d.ts.map +1 -0
- package/dist/seo/sources/ai-visibility-adapter.js +85 -0
- package/dist/seo/sources/ai-visibility-adapter.js.map +1 -0
- package/dist/seo/sources/api-spine-provider.d.ts +66 -0
- package/dist/seo/sources/api-spine-provider.d.ts.map +1 -0
- package/dist/seo/sources/api-spine-provider.js +68 -0
- package/dist/seo/sources/api-spine-provider.js.map +1 -0
- package/dist/seo/sources/citation-verifier.d.ts +95 -0
- package/dist/seo/sources/citation-verifier.d.ts.map +1 -0
- package/dist/seo/sources/citation-verifier.js +106 -0
- package/dist/seo/sources/citation-verifier.js.map +1 -0
- package/dist/seo/sources/crawl-source.d.ts +62 -0
- package/dist/seo/sources/crawl-source.d.ts.map +1 -0
- package/dist/seo/sources/crawl-source.js +87 -0
- package/dist/seo/sources/crawl-source.js.map +1 -0
- package/dist/seo/sources/damcrawler-crawl-engine.d.ts +151 -0
- package/dist/seo/sources/damcrawler-crawl-engine.d.ts.map +1 -0
- package/dist/seo/sources/damcrawler-crawl-engine.js +154 -0
- package/dist/seo/sources/damcrawler-crawl-engine.js.map +1 -0
- package/dist/seo/sources/damcrawler-serp-provider.d.ts +75 -0
- package/dist/seo/sources/damcrawler-serp-provider.d.ts.map +1 -0
- package/dist/seo/sources/damcrawler-serp-provider.js +60 -0
- package/dist/seo/sources/damcrawler-serp-provider.js.map +1 -0
- package/dist/seo/sources/dataforseo-adapter.d.ts +46 -0
- package/dist/seo/sources/dataforseo-adapter.d.ts.map +1 -0
- package/dist/seo/sources/dataforseo-adapter.js +335 -0
- package/dist/seo/sources/dataforseo-adapter.js.map +1 -0
- package/dist/seo/sources/dataforseo-serp-provider.d.ts +30 -0
- package/dist/seo/sources/dataforseo-serp-provider.d.ts.map +1 -0
- package/dist/seo/sources/dataforseo-serp-provider.js +20 -0
- package/dist/seo/sources/dataforseo-serp-provider.js.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.d.ts +62 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.d.ts.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.js +72 -0
- package/dist/seo/sources/engine-scrape-parser-chatgpt.js.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.d.ts +10 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.d.ts.map +1 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.js +72 -0
- package/dist/seo/sources/engine-scrape-parser-perplexity.js.map +1 -0
- package/dist/seo/sources/gsc-adapter.d.ts +64 -0
- package/dist/seo/sources/gsc-adapter.d.ts.map +1 -0
- package/dist/seo/sources/gsc-adapter.js +221 -0
- package/dist/seo/sources/gsc-adapter.js.map +1 -0
- package/dist/seo/sources/local-export.d.ts +53 -0
- package/dist/seo/sources/local-export.d.ts.map +1 -0
- package/dist/seo/sources/local-export.js +307 -0
- package/dist/seo/sources/local-export.js.map +1 -0
- package/dist/seo/sources/mention-citation-extractor.d.ts +136 -0
- package/dist/seo/sources/mention-citation-extractor.d.ts.map +1 -0
- package/dist/seo/sources/mention-citation-extractor.js +272 -0
- package/dist/seo/sources/mention-citation-extractor.js.map +1 -0
- package/dist/seo/sources/scrape-arm-provider.d.ts +109 -0
- package/dist/seo/sources/scrape-arm-provider.d.ts.map +1 -0
- package/dist/seo/sources/scrape-arm-provider.js +129 -0
- package/dist/seo/sources/scrape-arm-provider.js.map +1 -0
- package/dist/seo/tracked-prompt-store.d.ts +33 -0
- package/dist/seo/tracked-prompt-store.d.ts.map +1 -0
- package/dist/seo/tracked-prompt-store.js +68 -0
- package/dist/seo/tracked-prompt-store.js.map +1 -0
- package/dist/seo/types.d.ts +128 -0
- package/dist/seo/types.d.ts.map +1 -0
- package/dist/seo/types.js +14 -0
- package/dist/seo/types.js.map +1 -0
- package/dist/seo/verifier.d.ts +34 -0
- package/dist/seo/verifier.d.ts.map +1 -0
- package/dist/seo/verifier.js +204 -0
- package/dist/seo/verifier.js.map +1 -0
- package/dist/seo/workflow-capabilities.d.ts +26 -0
- package/dist/seo/workflow-capabilities.d.ts.map +1 -0
- package/dist/seo/workflow-capabilities.js +12 -0
- package/dist/seo/workflow-capabilities.js.map +1 -0
- package/dist/state/facts.d.ts +5 -1
- package/dist/state/facts.d.ts.map +1 -1
- package/dist/state/facts.js +29 -19
- package/dist/state/facts.js.map +1 -1
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +1 -1
- package/dist/state/index.js.map +1 -1
- package/dist/state/outline-state.d.ts +0 -12
- package/dist/state/outline-state.d.ts.map +1 -1
- package/dist/state/outline-state.js +1 -18
- package/dist/state/outline-state.js.map +1 -1
- package/dist/state/security-audit-state.d.ts +20 -0
- package/dist/state/security-audit-state.d.ts.map +1 -0
- package/dist/state/security-audit-state.js +59 -0
- package/dist/state/security-audit-state.js.map +1 -0
- package/dist/teams/registry.d.ts.map +1 -1
- package/dist/teams/registry.js +17 -0
- package/dist/teams/registry.js.map +1 -1
- package/dist/telegram/bot.d.ts +137 -0
- package/dist/telegram/bot.d.ts.map +1 -0
- package/dist/telegram/bot.js +323 -0
- package/dist/telegram/bot.js.map +1 -0
- package/dist/telegram/digest.d.ts +19 -0
- package/dist/telegram/digest.d.ts.map +1 -0
- package/dist/telegram/digest.js +23 -0
- package/dist/telegram/digest.js.map +1 -0
- package/dist/telegram/fleet-view.d.ts +38 -0
- package/dist/telegram/fleet-view.d.ts.map +1 -0
- package/dist/telegram/fleet-view.js +98 -0
- package/dist/telegram/fleet-view.js.map +1 -0
- package/dist/telegram/handlers/approvals.d.ts +61 -0
- package/dist/telegram/handlers/approvals.d.ts.map +1 -0
- package/dist/telegram/handlers/approvals.js +122 -0
- package/dist/telegram/handlers/approvals.js.map +1 -0
- package/dist/telegram/handlers/capture.d.ts +43 -0
- package/dist/telegram/handlers/capture.d.ts.map +1 -0
- package/dist/telegram/handlers/capture.js +51 -0
- package/dist/telegram/handlers/capture.js.map +1 -0
- package/dist/telegram/handlers/prioritize.d.ts +50 -0
- package/dist/telegram/handlers/prioritize.d.ts.map +1 -0
- package/dist/telegram/handlers/prioritize.js +99 -0
- package/dist/telegram/handlers/prioritize.js.map +1 -0
- package/dist/telegram/handlers/upload.d.ts +105 -0
- package/dist/telegram/handlers/upload.d.ts.map +1 -0
- package/dist/telegram/handlers/upload.js +149 -0
- package/dist/telegram/handlers/upload.js.map +1 -0
- package/dist/telegram/keyboard.d.ts +48 -0
- package/dist/telegram/keyboard.d.ts.map +1 -0
- package/dist/telegram/keyboard.js +81 -0
- package/dist/telegram/keyboard.js.map +1 -0
- package/dist/telegram/outbound.d.ts +77 -0
- package/dist/telegram/outbound.d.ts.map +1 -0
- package/dist/telegram/outbound.js +45 -0
- package/dist/telegram/outbound.js.map +1 -0
- package/dist/telegram/router.d.ts +46 -0
- package/dist/telegram/router.d.ts.map +1 -0
- package/dist/telegram/router.js +63 -0
- package/dist/telegram/router.js.map +1 -0
- package/dist/telegram/streaming.d.ts +36 -0
- package/dist/telegram/streaming.d.ts.map +1 -0
- package/dist/telegram/streaming.js +55 -0
- package/dist/telegram/streaming.js.map +1 -0
- package/dist/telegram/whitelist.d.ts +20 -0
- package/dist/telegram/whitelist.d.ts.map +1 -0
- package/dist/telegram/whitelist.js +34 -0
- package/dist/telegram/whitelist.js.map +1 -0
- package/dist/utils/git.d.ts +0 -6
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +0 -19
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/vault/conventions.d.ts +23 -0
- package/dist/vault/conventions.d.ts.map +1 -0
- package/dist/vault/conventions.js +22 -0
- package/dist/vault/conventions.js.map +1 -0
- package/dist/vault/frontmatter.d.ts +47 -0
- package/dist/vault/frontmatter.d.ts.map +1 -0
- package/dist/vault/frontmatter.js +149 -0
- package/dist/vault/frontmatter.js.map +1 -0
- package/dist/vault/index-map.d.ts +35 -0
- package/dist/vault/index-map.d.ts.map +1 -0
- package/dist/vault/index-map.js +67 -0
- package/dist/vault/index-map.js.map +1 -0
- package/dist/vault/mcp-adapter.d.ts +96 -0
- package/dist/vault/mcp-adapter.d.ts.map +1 -0
- package/dist/vault/mcp-adapter.js +176 -0
- package/dist/vault/mcp-adapter.js.map +1 -0
- package/dist/vault/note-io.d.ts +29 -0
- package/dist/vault/note-io.d.ts.map +1 -0
- package/dist/vault/note-io.js +44 -0
- package/dist/vault/note-io.js.map +1 -0
- package/dist/vault/profile.d.ts +35 -0
- package/dist/vault/profile.d.ts.map +1 -0
- package/dist/vault/profile.js +50 -0
- package/dist/vault/profile.js.map +1 -0
- package/dist/vault/reindex.d.ts +55 -0
- package/dist/vault/reindex.d.ts.map +1 -0
- package/dist/vault/reindex.js +69 -0
- package/dist/vault/reindex.js.map +1 -0
- package/dist/vault/types.d.ts +25 -0
- package/dist/vault/types.d.ts.map +1 -0
- package/dist/vault/types.js +9 -0
- package/dist/vault/types.js.map +1 -0
- package/package.json +20 -4
- package/scripts/sync-targets.json +2 -1
- package/skills/bober.design/SKILL.md +190 -0
- package/skills/bober.design/references/1-anti-slop.md +102 -0
- package/skills/bober.design/references/2-design-brief.md +84 -0
- package/skills/bober.design/references/3-critique-rubric.md +62 -0
- package/skills/bober.design/references/4-copy-guide.md +43 -0
- package/skills/bober.plan/SKILL.md +15 -1
- package/skills/bober.run/SKILL.md +7 -4
- package/skills/bober.security-anchor/SKILL.md +172 -0
- package/skills/bober.security-audit/SKILL.md +288 -0
- package/skills/bober.security-dex-backend/SKILL.md +306 -0
- package/skills/bober.security-generic/SKILL.md +295 -0
- package/skills/bober.security-igaming/SKILL.md +290 -0
- package/skills/bober.security-node/SKILL.md +267 -0
- package/skills/bober.security-payments/SKILL.md +249 -0
- package/skills/bober.security-react/SKILL.md +194 -0
- package/skills/bober.security-solidity/SKILL.md +306 -0
- package/skills/bober.seo/SKILL.md +132 -0
- package/skills/bober.seo-ai-visibility/SKILL.md +110 -0
- package/skills/bober.seo-content-decay/SKILL.md +99 -0
- package/skills/bober.seo-generic/SKILL.md +173 -0
- package/skills/bober.seo-internal-linking/SKILL.md +87 -0
- package/skills/bober.seo-parasite-watch/SKILL.md +121 -0
- package/skills/bober.seo-rank-track/SKILL.md +98 -0
- package/skills/bober.seo-schema-audit/SKILL.md +97 -0
- package/skills/bober.seo-technical-audit/SKILL.md +113 -0
- package/skills/bober.seo-topical-map/SKILL.md +100 -0
- package/skills/bober.seo-verticals/SKILL.md +133 -0
- package/skills/bober.using-bober/SKILL.md +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ContentSanitizer } from "../content-sanitizer.js";
|
|
2
|
+
const defaultLoader = async () => {
|
|
3
|
+
// Indirection through a variable: under `moduleResolution: NodeNext` a
|
|
4
|
+
// LITERAL `import("damcrawler")` is statically resolved by tsc and fails
|
|
5
|
+
// with TS2307 when the dep is absent. Routing the specifier through a
|
|
6
|
+
// `string` variable makes tsc treat the result as `any`, so `tsc --noEmit`
|
|
7
|
+
// stays clean whether or not damcrawler is installed (mirrors
|
|
8
|
+
// `damcrawler-serp-provider.ts:54-63`, `citation-verifier.ts:74-83`).
|
|
9
|
+
const mod = "damcrawler";
|
|
10
|
+
return (await import(mod).catch(() => undefined));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Builds the target URL for one prompt, per configured `ScrapeEngine`
|
|
14
|
+
* (Sprint 11 — generalized from the Sprint-10 ChatGPT-only builder). Each
|
|
15
|
+
* engine's scrape target is provider-constructed from the prompt text alone
|
|
16
|
+
* (no per-target routing) — mirrors the `DamcrawlerSerpProvider` "no SSRF
|
|
17
|
+
* guard needed" rationale (this class never fetches a caller-supplied URL).
|
|
18
|
+
* The `switch` is exhaustive over `ScrapeEngine` (a compile error surfaces
|
|
19
|
+
* any future engine value left unhandled).
|
|
20
|
+
*/
|
|
21
|
+
function scrapeUrlFor(engine, prompt) {
|
|
22
|
+
switch (engine) {
|
|
23
|
+
case "chatgpt-ui":
|
|
24
|
+
return `https://chatgpt.com/?q=${encodeURIComponent(prompt)}`;
|
|
25
|
+
case "perplexity-ui":
|
|
26
|
+
return `https://www.perplexity.ai/search?q=${encodeURIComponent(prompt)}`;
|
|
27
|
+
default: {
|
|
28
|
+
const _exhaustive = engine;
|
|
29
|
+
return _exhaustive;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `AiVisibilityProvider` backed by a gated damcrawler UI scrape.
|
|
35
|
+
* Guard-first, lazy-load, throttle-metered, sanitize-before-parse,
|
|
36
|
+
* never-throw; books zero USD to the governor (proxy cost is tracked
|
|
37
|
+
* independently by the injected `ScrapeThrottle`).
|
|
38
|
+
*/
|
|
39
|
+
export class ScrapeArmEngineProvider {
|
|
40
|
+
egress;
|
|
41
|
+
parser;
|
|
42
|
+
extractor;
|
|
43
|
+
verifier;
|
|
44
|
+
throttle;
|
|
45
|
+
samplesPerPrompt;
|
|
46
|
+
authSession;
|
|
47
|
+
proxyUsdPerScrape;
|
|
48
|
+
proxy;
|
|
49
|
+
load;
|
|
50
|
+
name;
|
|
51
|
+
estCostUsdPerPrompt = 0;
|
|
52
|
+
constructor(egress, engine, parser, extractor, verifier, throttle, samplesPerPrompt,
|
|
53
|
+
// Operator-supplied auth session (storageState path / profile name /
|
|
54
|
+
// cookie blob) from `config.seo.aiVisibility.scrape.authSession` — opaque
|
|
55
|
+
// to this class, passed straight through to `dam.scrape` options. NOT
|
|
56
|
+
// hardcoded (nonGoal: no auth harvesting).
|
|
57
|
+
authSession, proxyUsdPerScrape, proxy = undefined, load = defaultLoader) {
|
|
58
|
+
this.egress = egress;
|
|
59
|
+
this.parser = parser;
|
|
60
|
+
this.extractor = extractor;
|
|
61
|
+
this.verifier = verifier;
|
|
62
|
+
this.throttle = throttle;
|
|
63
|
+
this.samplesPerPrompt = samplesPerPrompt;
|
|
64
|
+
this.authSession = authSession;
|
|
65
|
+
this.proxyUsdPerScrape = proxyUsdPerScrape;
|
|
66
|
+
this.proxy = proxy;
|
|
67
|
+
this.load = load;
|
|
68
|
+
this.name = engine;
|
|
69
|
+
}
|
|
70
|
+
async probe(target, prompts, _locale) {
|
|
71
|
+
// -- STATEMENT 1: self-assert the axis FIRST, before any import (ADR-4, load-bearing barrier, sc-10-1) --
|
|
72
|
+
try {
|
|
73
|
+
this.egress.assertAllowed("ai-visibility-scrape");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return []; // axis off => abstain, zero sockets, NO loader call, NO throttle call
|
|
77
|
+
}
|
|
78
|
+
const dam = await this.load();
|
|
79
|
+
if (!dam)
|
|
80
|
+
return []; // damcrawler-not-installed (optional peer dep) => abstain, never throw
|
|
81
|
+
const sanitizer = new ContentSanitizer(dam.sanitize); // ADR-11: sanitize at the network->in-process boundary
|
|
82
|
+
const rows = [];
|
|
83
|
+
for (const prompt of prompts) {
|
|
84
|
+
for (let i = 0; i < this.samplesPerPrompt; i++) {
|
|
85
|
+
const decision = await this.throttle.acquire(this.name); // BEFORE scrape
|
|
86
|
+
if (!decision.proceed)
|
|
87
|
+
continue; // throttle denial => skip this sample (sc-10-3), no ledger side effect
|
|
88
|
+
try {
|
|
89
|
+
const [result] = await dam.scrape([scrapeUrlFor(this.name, prompt)], {
|
|
90
|
+
formats: ["markdown"],
|
|
91
|
+
proxy: this.proxy,
|
|
92
|
+
authSession: this.authSession,
|
|
93
|
+
});
|
|
94
|
+
if (!result || result.error)
|
|
95
|
+
continue; // scrape error/missing row => drop sample, never throw (sc-10-3)
|
|
96
|
+
// sc-10-2: sanitize the raw scraped markdown BEFORE the parser runs
|
|
97
|
+
// (Sprint-9 F1 lesson — reversing this order re-opens the
|
|
98
|
+
// prompt-injection regression).
|
|
99
|
+
const cleanMarkdown = sanitizer.clean(result.markdown, result.url).content;
|
|
100
|
+
const raw = { url: result.url, markdown: cleanMarkdown };
|
|
101
|
+
const parsed = this.parser.parse(raw); // PURE: RawScrape -> {answerText, citations}
|
|
102
|
+
const obs = await this.extractor.extract({
|
|
103
|
+
target,
|
|
104
|
+
answerText: parsed.answerText,
|
|
105
|
+
citations: parsed.citations,
|
|
106
|
+
});
|
|
107
|
+
const verified = await this.verifier.verify(target, obs.sourceUrls);
|
|
108
|
+
const sourceUrls = verified.filter((v) => v.live).map((v) => v.url);
|
|
109
|
+
const row = {
|
|
110
|
+
prompt,
|
|
111
|
+
provider: this.name,
|
|
112
|
+
mentioned: obs.mentioned,
|
|
113
|
+
citationPresent: obs.citationPresent,
|
|
114
|
+
sourceUrls,
|
|
115
|
+
};
|
|
116
|
+
if (obs.rank !== undefined)
|
|
117
|
+
row.rank = obs.rank; // never `rank: undefined`
|
|
118
|
+
rows.push(row);
|
|
119
|
+
await this.throttle.recordProxyCost(this.name, this.proxyUsdPerScrape); // AFTER a successful, row-producing scrape
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
continue; // any error mid-sample => drop that sample, NEVER throw (sc-10-3)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return rows; // sc-10-3: never throws; [] is a valid abstain (zero booked, zero over-book risk at $0/prompt)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=scrape-arm-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrape-arm-provider.js","sourceRoot":"","sources":["../../../src/seo/sources/scrape-arm-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const TrackedPromptSetSchema: z.ZodObject<{
|
|
3
|
+
target: z.ZodString;
|
|
4
|
+
prompts: z.ZodArray<z.ZodString, "many">;
|
|
5
|
+
engines: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
6
|
+
samplesPerPrompt: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
prompts: string[];
|
|
10
|
+
samplesPerPrompt: number;
|
|
11
|
+
engines: string[];
|
|
12
|
+
target: string;
|
|
13
|
+
locale?: string | undefined;
|
|
14
|
+
}, {
|
|
15
|
+
prompts: string[];
|
|
16
|
+
target: string;
|
|
17
|
+
samplesPerPrompt?: number | undefined;
|
|
18
|
+
engines?: string[] | undefined;
|
|
19
|
+
locale?: string | undefined;
|
|
20
|
+
}>;
|
|
21
|
+
export type TrackedPromptSet = z.infer<typeof TrackedPromptSetSchema>;
|
|
22
|
+
export declare class TrackedPromptStore {
|
|
23
|
+
private readonly projectRoot;
|
|
24
|
+
constructor(projectRoot: string);
|
|
25
|
+
/**
|
|
26
|
+
* Load the committed tracked-prompt set for `target`. Missing, unreadable,
|
|
27
|
+
* or malformed (fails Zod validation) all fall back to
|
|
28
|
+
* `{ target, prompts: [target], engines: [], samplesPerPrompt: 5 }`.
|
|
29
|
+
* Never throws.
|
|
30
|
+
*/
|
|
31
|
+
load(target: string): Promise<TrackedPromptSet>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=tracked-prompt-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked-prompt-store.d.ts","sourceRoot":"","sources":["../../src/seo/tracked-prompt-store.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAmBtE,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEhD;;;;;OAKG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAWtD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TrackedPromptStore — reads the committed tracked-prompt set for a target
|
|
3
|
+
* from `.bober/seo/ai-visibility/<target>.json`
|
|
4
|
+
* (spec-20260718-in-house-ai-visibility, Sprint 6).
|
|
5
|
+
*
|
|
6
|
+
* `load()` NEVER throws: a missing file, an unreadable file, or a file that
|
|
7
|
+
* fails `TrackedPromptSetSchema.safeParse` all collapse to the SAME fallback
|
|
8
|
+
* — `{ target, prompts: [target], engines: [], samplesPerPrompt: 5 }` — which
|
|
9
|
+
* is byte-identical (for the `target`/`prompts` fields `gatherDataBundle`
|
|
10
|
+
* actually forwards into `AiVisibilityQuery`) to the pre-Sprint-6 literal at
|
|
11
|
+
* `runner.ts:421` (sc-6-2). Mirrors the read-JSON -> Zod `safeParse` ->
|
|
12
|
+
* fallback idiom of `readJob` (`src/research/job-store.ts:100-113`).
|
|
13
|
+
*
|
|
14
|
+
* `engines`/`samplesPerPrompt` are parsed for completeness (sc-6-1) but are
|
|
15
|
+
* ADVISORY ONLY — the real per-target N/engines are resolved by config at
|
|
16
|
+
* provider construction (`schema.ts:729-747`), and the caller in
|
|
17
|
+
* `runner.ts`'s `gatherDataBundle` deliberately does NOT flow them into the
|
|
18
|
+
* LOCKED `AiVisibilityQuery` shape (`data-source.ts:61`; contract nonGoal).
|
|
19
|
+
*/
|
|
20
|
+
import { readFile } from "node:fs/promises";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
// ── Schema ───────────────────────────────────────────────────────────
|
|
24
|
+
export const TrackedPromptSetSchema = z.object({
|
|
25
|
+
target: z.string(),
|
|
26
|
+
prompts: z.array(z.string()),
|
|
27
|
+
// Advisory — never flowed into AiVisibilityQuery (contract nonGoal). A
|
|
28
|
+
// plain string array (not the config's engine enum) so a stray/unknown
|
|
29
|
+
// engine name never fails the whole file's safeParse.
|
|
30
|
+
engines: z.array(z.string()).default([]),
|
|
31
|
+
samplesPerPrompt: z.number().int().positive().default(5),
|
|
32
|
+
locale: z.string().optional(),
|
|
33
|
+
});
|
|
34
|
+
// ── Paths ────────────────────────────────────────────────────────────
|
|
35
|
+
const TRACKED_PROMPTS_DIR = ".bober/seo/ai-visibility";
|
|
36
|
+
/** fs-safe filename — mirrors `report-store.ts:34-36`'s traversal-safe sanitization. */
|
|
37
|
+
function trackedPromptPath(projectRoot, target) {
|
|
38
|
+
const safeTarget = target.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
39
|
+
return join(projectRoot, TRACKED_PROMPTS_DIR, `${safeTarget}.json`);
|
|
40
|
+
}
|
|
41
|
+
/** The byte-identical-to-pre-Sprint-6 fallback (sc-6-2). */
|
|
42
|
+
function fallback(target) {
|
|
43
|
+
return { target, prompts: [target], engines: [], samplesPerPrompt: 5 };
|
|
44
|
+
}
|
|
45
|
+
// ── Store ────────────────────────────────────────────────────────────
|
|
46
|
+
export class TrackedPromptStore {
|
|
47
|
+
projectRoot;
|
|
48
|
+
constructor(projectRoot) {
|
|
49
|
+
this.projectRoot = projectRoot;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Load the committed tracked-prompt set for `target`. Missing, unreadable,
|
|
53
|
+
* or malformed (fails Zod validation) all fall back to
|
|
54
|
+
* `{ target, prompts: [target], engines: [], samplesPerPrompt: 5 }`.
|
|
55
|
+
* Never throws.
|
|
56
|
+
*/
|
|
57
|
+
async load(target) {
|
|
58
|
+
try {
|
|
59
|
+
const raw = JSON.parse(await readFile(trackedPromptPath(this.projectRoot, target), "utf-8"));
|
|
60
|
+
const result = TrackedPromptSetSchema.safeParse(raw);
|
|
61
|
+
return result.success ? result.data : fallback(target);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return fallback(target);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tracked-prompt-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked-prompt-store.js","sourceRoot":"","sources":["../../src/seo/tracked-prompt-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wEAAwE;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5B,uEAAuE;IACvE,uEAAuE;IACvE,sDAAsD;IACtD,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACxC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAIH,wEAAwE;AAExE,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAEvD,wFAAwF;AACxF,SAAS,iBAAiB,CAAC,WAAmB,EAAE,MAAc;IAC5D,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,WAAW,EAAE,mBAAmB,EAAE,GAAG,UAAU,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,4DAA4D;AAC5D,SAAS,QAAQ,CAAC,MAAc;IAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,wEAAwE;AAExE,MAAM,OAAO,kBAAkB;IACA;IAA7B,YAA6B,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;IAAG,CAAC;IAEpD;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAC7B,MAAM,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CACrE,CAAC;YACF,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core SEO type foundation (spec-20260715-ultimate-seo-suite, Sprint 1).
|
|
3
|
+
*
|
|
4
|
+
* Pure `type` declarations only — no runtime code, no imports. These shapes
|
|
5
|
+
* are quoted verbatim from the architecture Component Breakdown / Data Model
|
|
6
|
+
* (.bober/architecture/arch-20260715-ultimate-seo-agents-skills-architecture.md).
|
|
7
|
+
*
|
|
8
|
+
* Deliberately NOT included this sprint (later-sprint nonGoals): the
|
|
9
|
+
* `SeoDataSource` seam, capability/query types, adapters, and any import of
|
|
10
|
+
* `src/hub/finding.js` — `SeoFinding.severity` stays a plain 1..5 numeric
|
|
11
|
+
* union until the hub emitter sprint maps it onto `Finding`.
|
|
12
|
+
*/
|
|
13
|
+
/** The 8 SEO workflows the CLI dispatches on (architecture lines 65-73). */
|
|
14
|
+
export type SeoWorkflow = "technical-audit" | "rank-track" | "content-decay" | "topical-map" | "ai-visibility" | "parasite-watch" | "internal-linking" | "schema-audit";
|
|
15
|
+
/**
|
|
16
|
+
* Provenance stamped on every `DataOutcome` `"data"` arm (architecture
|
|
17
|
+
* lines 165-169). `costUsd` is set only by costed live sources (DataForSEO).
|
|
18
|
+
* `path`/`mtimeMs` are set only by file-backed sources (LocalExportSource,
|
|
19
|
+
* Sprint 6) for freshness auditing — optional so `gsc`/`dataforseo`
|
|
20
|
+
* provenance stays byte-compatible (same optional idiom as `costUsd`).
|
|
21
|
+
*
|
|
22
|
+
* Widened (spec-20260717-seo-improver-builder, Sprint 1) with `"ai-visibility"`
|
|
23
|
+
* and `"damcrawler"` — additive only; no consumer exhaustively switches on
|
|
24
|
+
* `source` (`analyzer.ts` switches on `DataOutcome.kind`, not `source`).
|
|
25
|
+
*/
|
|
26
|
+
export type DataProvenance = {
|
|
27
|
+
source: "local-export" | "gsc" | "dataforseo" | "ai-visibility" | "damcrawler";
|
|
28
|
+
retrievedAt: string;
|
|
29
|
+
costUsd?: number;
|
|
30
|
+
path?: string;
|
|
31
|
+
mtimeMs?: number;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Three-arm outcome for every `SeoDataSource` capability call (architecture
|
|
35
|
+
* lines 160-163; mirrors `RetrievalOutcome`, medline-source.ts:25-28).
|
|
36
|
+
*/
|
|
37
|
+
export type DataOutcome<T> = {
|
|
38
|
+
kind: "disabled";
|
|
39
|
+
} | {
|
|
40
|
+
kind: "abstain";
|
|
41
|
+
reason: string;
|
|
42
|
+
} | {
|
|
43
|
+
kind: "data";
|
|
44
|
+
rows: T;
|
|
45
|
+
provenance: DataProvenance;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Parsed from each `skills/bober.seo-*` directory's `SKILL.md`, strong/
|
|
49
|
+
* read-only, memoised per process (architecture lines 349-360).
|
|
50
|
+
*
|
|
51
|
+
* `liveWeightStatus` (spec-20260717-seo-improver-builder, Sprint 3) is a
|
|
52
|
+
* soft field encoding the documented-vs-live-weight caveat: whether the
|
|
53
|
+
* signature's invariant is corroborated by a LIVE ranking signal
|
|
54
|
+
* (`live-corroborated`), is documented-only guidance not (yet) confirmed
|
|
55
|
+
* live (`documented-only`), or unknown/unstated (`unknown`, the default).
|
|
56
|
+
* It lives ONLY on the signature — `SeoFinding` is unchanged (ADR-2).
|
|
57
|
+
*/
|
|
58
|
+
export type SeoSignature = {
|
|
59
|
+
playbookId: string;
|
|
60
|
+
workflows: SeoWorkflow[];
|
|
61
|
+
title: string;
|
|
62
|
+
tactic: string;
|
|
63
|
+
invariant: string;
|
|
64
|
+
primarySourceUrl: string;
|
|
65
|
+
policyClass: "auto-safe" | "human-approve";
|
|
66
|
+
evidenceGrade: "verified" | "primary-unverified" | "single-source";
|
|
67
|
+
liveWeightStatus: "live-corroborated" | "documented-only" | "unknown";
|
|
68
|
+
keywords: string[];
|
|
69
|
+
skillRef: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* One SEO recommendation (architecture lines 258-267). `severity` maps to
|
|
73
|
+
* hub `Finding` urgency/severity 1..5 (finding.ts:15-16) in a LATER sprint —
|
|
74
|
+
* `Finding` is not imported here.
|
|
75
|
+
*/
|
|
76
|
+
export type SeoFinding = {
|
|
77
|
+
recommendation: string;
|
|
78
|
+
workflow: SeoWorkflow;
|
|
79
|
+
playbookRef: string;
|
|
80
|
+
citationUrl: string;
|
|
81
|
+
evidence: Array<{
|
|
82
|
+
metric: string;
|
|
83
|
+
value: string;
|
|
84
|
+
source: string;
|
|
85
|
+
url: string;
|
|
86
|
+
}>;
|
|
87
|
+
severity: 1 | 2 | 3 | 4 | 5;
|
|
88
|
+
humanApprovalRequired: boolean;
|
|
89
|
+
confidence: "firm" | "tentative";
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Persisted at `.bober/seo/reports/<safeId>-seo-report.json` (architecture
|
|
93
|
+
* lines 363-372).
|
|
94
|
+
*
|
|
95
|
+
* `droppedNeverEncode` (spec-20260717-seo-improver-builder, Sprint 1 field /
|
|
96
|
+
* Sprint 2 wiring) mirrors `droppedUncited` exactly — a required plain
|
|
97
|
+
* `number` counter. Populated by `NeverEncodeFilter` (`never-encode-filter.ts`,
|
|
98
|
+
* Sprint 2), which runs in `SeoWorkflowRunner.run` between the
|
|
99
|
+
* `analysis.parsed` check and `SeoCitationGate.apply`.
|
|
100
|
+
*/
|
|
101
|
+
export type SeoReport = {
|
|
102
|
+
reportId: string;
|
|
103
|
+
workflow: SeoWorkflow;
|
|
104
|
+
target: string;
|
|
105
|
+
generatedAt: string;
|
|
106
|
+
findings: SeoFinding[];
|
|
107
|
+
droppedUncited: number;
|
|
108
|
+
droppedNeverEncode: number;
|
|
109
|
+
dataProvenance: DataProvenance[];
|
|
110
|
+
verdict: "pass" | "blocked";
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Persisted at `.bober/seo/quota-ledger.json` (architecture calls this
|
|
114
|
+
* shape `QuotaLedger`, lines 375-385; named `SeoQuotaLedger` per
|
|
115
|
+
* generatorNotes to match the `Seo*` naming convention of this module).
|
|
116
|
+
*/
|
|
117
|
+
export type SeoQuotaLedger = {
|
|
118
|
+
[dateKey: string]: {
|
|
119
|
+
spentUsd: number;
|
|
120
|
+
scopes: {
|
|
121
|
+
[scopeKey: string]: {
|
|
122
|
+
rowsToday: number;
|
|
123
|
+
urlInspectionsToday: number;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/seo/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GACnB,iBAAiB,GACjB,YAAY,GACZ,eAAe,GACf,aAAa,GACb,eAAe,GACf,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,CAAC;AAInB;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,GAAG,KAAK,GAAG,YAAY,GAAG,eAAe,GAAG,YAAY,CAAC;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,UAAU,EAAE,cAAc,CAAA;CAAE,CAAC;AAI1D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,WAAW,GAAG,eAAe,CAAC;IAC3C,aAAa,EAAE,UAAU,GAAG,oBAAoB,GAAG,eAAe,CAAC;IACnE,gBAAgB,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;CAClC,CAAC;AAIF;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAIF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,OAAO,EAAE,MAAM,GAAG;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE;YACN,CAAC,QAAQ,EAAE,MAAM,GAAG;gBAAE,SAAS,EAAE,MAAM,CAAC;gBAAC,mBAAmB,EAAE,MAAM,CAAA;aAAE,CAAC;SACxE,CAAC;KACH,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core SEO type foundation (spec-20260715-ultimate-seo-suite, Sprint 1).
|
|
3
|
+
*
|
|
4
|
+
* Pure `type` declarations only — no runtime code, no imports. These shapes
|
|
5
|
+
* are quoted verbatim from the architecture Component Breakdown / Data Model
|
|
6
|
+
* (.bober/architecture/arch-20260715-ultimate-seo-agents-skills-architecture.md).
|
|
7
|
+
*
|
|
8
|
+
* Deliberately NOT included this sprint (later-sprint nonGoals): the
|
|
9
|
+
* `SeoDataSource` seam, capability/query types, adapters, and any import of
|
|
10
|
+
* `src/hub/finding.js` — `SeoFinding.severity` stays a plain 1..5 numeric
|
|
11
|
+
* union until the hub emitter sprint maps it onto `Finding`.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/seo/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { LLMClient } from "../providers/types.js";
|
|
2
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
3
|
+
import type { SeoFinding } from "./types.js";
|
|
4
|
+
export interface SeoVerifyParams {
|
|
5
|
+
/** The citation gate's `cited` findings — the ONLY findings the verifier ever sees. */
|
|
6
|
+
findings: SeoFinding[];
|
|
7
|
+
config: BoberConfig;
|
|
8
|
+
projectRoot: string;
|
|
9
|
+
/** Injected wall-clock snapshot (ISO-8601) — the verifier never reads the clock itself. */
|
|
10
|
+
now: string;
|
|
11
|
+
/** TEST injection — default = a real client via `createClient(...)`. Tests pass a ScriptedClient. */
|
|
12
|
+
llm?: LLMClient;
|
|
13
|
+
}
|
|
14
|
+
export interface SeoVerifyResult {
|
|
15
|
+
/** False on disabled/parse-failure/provider-error (fail-closed) — `findings` is then the UNCHANGED input. */
|
|
16
|
+
ran: boolean;
|
|
17
|
+
findings: SeoFinding[];
|
|
18
|
+
}
|
|
19
|
+
/** Injectable seam so `runner.test.ts` can stub the stage (mirrors `SeoRunInput.analyzer`). */
|
|
20
|
+
export interface SeoVerifier {
|
|
21
|
+
verify(params: SeoVerifyParams): Promise<SeoVerifyResult>;
|
|
22
|
+
}
|
|
23
|
+
export declare class SeoRecommendationVerifier implements SeoVerifier {
|
|
24
|
+
/**
|
|
25
|
+
* Never throws. Resolves `{ ran:false, findings }` (input UNCHANGED) when
|
|
26
|
+
* disabled, when the agent md can't be loaded, on any provider/transport
|
|
27
|
+
* error, or when the response can't be parsed into a valid verdicts
|
|
28
|
+
* container. Resolves `{ ran:true, findings:<folded> }` on a successful,
|
|
29
|
+
* parseable response — always a subset of the input with severities only
|
|
30
|
+
* moving down.
|
|
31
|
+
*/
|
|
32
|
+
verify(params: SeoVerifyParams): Promise<SeoVerifyResult>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/seo/verifier.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,GAAG,EAAE,MAAM,CAAC;IACZ,qGAAqG;IACrG,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,6GAA6G;IAC7G,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,+FAA+F;AAC/F,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC3D;AA8ID,qBAAa,yBAA0B,YAAW,WAAW;IAC3D;;;;;;;OAOG;IACG,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;CA2ChE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeoRecommendationVerifier — opt-in, downgrade-only, fail-closed adversarial
|
|
3
|
+
* verifier (spec-20260715-ultimate-seo-suite, Sprint 12).
|
|
4
|
+
*
|
|
5
|
+
* Mirrors two precedents:
|
|
6
|
+
* - The security verifier's fold semantics and fail-closed result shape
|
|
7
|
+
* (`src/orchestrator/security-verifier-agent.ts`, and the fold at
|
|
8
|
+
* `src/orchestrator/security-auditor-agent.ts:338-354`): `ran===false`
|
|
9
|
+
* (disabled/parse-failure/provider-error/refusal) returns the input
|
|
10
|
+
* findings UNCHANGED; on success, `disproved` drops a finding,
|
|
11
|
+
* `downgraded` lowers its severity by one (floored at 1), and
|
|
12
|
+
* `confirmed`/unaddressed keeps it unchanged. The new set is always a
|
|
13
|
+
* strict SUBSET with severities only ever moving DOWN — never
|
|
14
|
+
* promoted, added, or raised.
|
|
15
|
+
* - The SEO analyzer's single-shot injected-`LLMClient` + 3-tier defensive
|
|
16
|
+
* parse (`src/seo/analyzer.ts:187-226,280-301`). Unlike the security
|
|
17
|
+
* verifier, this is a single `llm.chat` call — NOT an agentic loop (no
|
|
18
|
+
* `runAgenticLoop`/`resolveRoleTools`, nothing to Read/Grep/Glob: SEO
|
|
19
|
+
* findings cite external URLs, and there is no local evidence to
|
|
20
|
+
* re-check).
|
|
21
|
+
*
|
|
22
|
+
* NEVER throws: any disabled-flag short-circuit, agent-md-load failure,
|
|
23
|
+
* provider/transport error, or parse failure resolves
|
|
24
|
+
* `{ ran:false, findings }` — the caller (`SeoWorkflowRunner`) keeps the
|
|
25
|
+
* citation gate's findings UNCHANGED (fail-closed, sc-12-3). This is the
|
|
26
|
+
* key divergence from `SeoAnalyzer.analyze`, which propagates transport
|
|
27
|
+
* errors — the verifier is an opt-in stage whose failure must never flip
|
|
28
|
+
* the run's exit code (sc-12-4).
|
|
29
|
+
*
|
|
30
|
+
* Gated on `config.seo?.verifier?.enabled` (schema.ts:688, default false,
|
|
31
|
+
* pre-existing from Sprint 1) at TWO layers, defense-in-depth: the runner
|
|
32
|
+
* (`src/seo/runner.ts`) never constructs or calls a verifier at all when
|
|
33
|
+
* disabled (so a disabled run makes zero provider calls, sc-12-2), and
|
|
34
|
+
* `verify()` itself also short-circuits on the flag so a caller that
|
|
35
|
+
* constructs a `SeoRecommendationVerifier` directly can't accidentally
|
|
36
|
+
* trigger a provider call either.
|
|
37
|
+
*/
|
|
38
|
+
import { z } from "zod";
|
|
39
|
+
import { createClient } from "../providers/factory.js";
|
|
40
|
+
import { loadAgentDefinition } from "../orchestrator/agent-loader.js";
|
|
41
|
+
import { logger } from "../utils/logger.js";
|
|
42
|
+
// -- Model-facing verdict schema (defensive, never trusts the LLM blindly) --
|
|
43
|
+
const SeoVerdictSchema = z.object({
|
|
44
|
+
index: z.number().int().min(0),
|
|
45
|
+
verdict: z.enum(["confirmed", "downgraded", "disproved"]),
|
|
46
|
+
confidence: z.enum(["high", "medium", "low"]),
|
|
47
|
+
reason: z.string(),
|
|
48
|
+
});
|
|
49
|
+
const SeoVerdictsContainerSchema = z.object({
|
|
50
|
+
verdicts: z.array(SeoVerdictSchema),
|
|
51
|
+
});
|
|
52
|
+
// -- Defaults -------------------------------------------------------------
|
|
53
|
+
/** No `config.seo.verifier.model` field exists (schema.ts:688 has ONLY `enabled`) — this is the sole default. */
|
|
54
|
+
const DEFAULT_SEO_VERIFIER_MODEL = "sonnet";
|
|
55
|
+
function buildDefaultClient() {
|
|
56
|
+
// createClient is the ONLY place SDKs are imported (mirrors runner.ts's buildDefaultAnalyzer).
|
|
57
|
+
return createClient(undefined, null, undefined, DEFAULT_SEO_VERIFIER_MODEL, "SeoVerifier");
|
|
58
|
+
}
|
|
59
|
+
// -- Prompt assembly --------------------------------------------------------
|
|
60
|
+
/**
|
|
61
|
+
* Builds the verifier's user message from ONLY the findings + the injected
|
|
62
|
+
* `now`. Deliberately excludes any sprint/contract framing — the agent md
|
|
63
|
+
* (loaded as the `system` prompt) is the fresh, contract-free adversary; this
|
|
64
|
+
* message carries just the evidence to judge.
|
|
65
|
+
*/
|
|
66
|
+
function buildVerifierUserMessage(findings, now) {
|
|
67
|
+
const findingsJson = JSON.stringify(findings.map((finding, index) => ({ index, ...finding })), null, 2);
|
|
68
|
+
return [
|
|
69
|
+
`Current reference date/time (for freshness judgments only): ${now}.`,
|
|
70
|
+
``,
|
|
71
|
+
`# Findings To Verify`,
|
|
72
|
+
``,
|
|
73
|
+
findingsJson,
|
|
74
|
+
``,
|
|
75
|
+
`# Your Task`,
|
|
76
|
+
``,
|
|
77
|
+
`For each finding above, attempt to DISPROVE it: is the citationUrl a genuine primary source that ` +
|
|
78
|
+
`actually backs the recommendation? Does the evidence actually support the claimed severity? Is ` +
|
|
79
|
+
`anything invented, overstated, or unsupported?`,
|
|
80
|
+
``,
|
|
81
|
+
`Render one verdict per finding: "confirmed" (it holds — stays at its original severity), "downgraded" ` +
|
|
82
|
+
`(real but overstated — severity moves down by one), or "disproved" (the evidence does not support ` +
|
|
83
|
+
`it — dropped entirely).`,
|
|
84
|
+
``,
|
|
85
|
+
`Output ONLY a single JSON object (no prose, no markdown fences), one entry per finding, in this exact shape:`,
|
|
86
|
+
`{"verdicts":[{"index":0,"verdict":"confirmed","confidence":"high","reason":"<one-line reason>"}]}`,
|
|
87
|
+
].join("\n");
|
|
88
|
+
}
|
|
89
|
+
/** Mirrors `analyzer.ts:parseFindingsContainer` verbatim, swapping the container schema. */
|
|
90
|
+
function parseVerdictsContainer(rawText) {
|
|
91
|
+
let parsed;
|
|
92
|
+
try {
|
|
93
|
+
parsed = JSON.parse(rawText.trim());
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Tier 2: extract from a fenced ```json ... ``` block.
|
|
97
|
+
const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(rawText);
|
|
98
|
+
if (fenceMatch) {
|
|
99
|
+
try {
|
|
100
|
+
parsed = JSON.parse(fenceMatch[1].trim());
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// fall through to tier 3
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Tier 3: take the first { ... last } span.
|
|
107
|
+
if (parsed === undefined) {
|
|
108
|
+
const braceStart = rawText.indexOf("{");
|
|
109
|
+
const braceEnd = rawText.lastIndexOf("}");
|
|
110
|
+
if (braceStart !== -1 && braceEnd > braceStart) {
|
|
111
|
+
try {
|
|
112
|
+
parsed = JSON.parse(rawText.slice(braceStart, braceEnd + 1));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return { ok: false, error: `No valid JSON object found in response. Raw: ${rawText.slice(0, 200)}` };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
return { ok: false, error: `No JSON object found in response. Raw: ${rawText.slice(0, 200)}` };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const result = SeoVerdictsContainerSchema.safeParse(parsed);
|
|
124
|
+
if (!result.success) {
|
|
125
|
+
const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
126
|
+
return { ok: false, error: issues };
|
|
127
|
+
}
|
|
128
|
+
return { ok: true, verdicts: result.data.verdicts };
|
|
129
|
+
}
|
|
130
|
+
// -- Downgrade-only fold (structural — no code path raises/adds) ----------
|
|
131
|
+
/**
|
|
132
|
+
* Folds verdicts onto `findings` by 0-based `index`. `disproved` drops the
|
|
133
|
+
* finding; `downgraded` lowers `severity` by exactly one, floored at 1
|
|
134
|
+
* (input `severity` is always `1..5`, so `severity-1` is always `0..4`,
|
|
135
|
+
* floored to `1..4` — the cast is safe); `confirmed` OR an unaddressed
|
|
136
|
+
* finding (no matching verdict entry, or an out-of-range `index` the model
|
|
137
|
+
* invented) is kept byte-unchanged. There is no branch here that raises a
|
|
138
|
+
* severity or pushes a finding not already present in `findings` — the
|
|
139
|
+
* downgrade-only guarantee is structural, not trusted from the model.
|
|
140
|
+
*/
|
|
141
|
+
function applyVerdicts(findings, verdicts) {
|
|
142
|
+
const byIndex = new Map(verdicts.map((v) => [v.index, v]));
|
|
143
|
+
const out = [];
|
|
144
|
+
findings.forEach((finding, i) => {
|
|
145
|
+
const v = byIndex.get(i);
|
|
146
|
+
if (v?.verdict === "disproved")
|
|
147
|
+
return;
|
|
148
|
+
if (v?.verdict === "downgraded") {
|
|
149
|
+
const lowered = Math.max(1, finding.severity - 1);
|
|
150
|
+
out.push({ ...finding, severity: lowered });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
out.push(finding); // "confirmed" OR unaddressed — fail-closed default: keep unchanged.
|
|
154
|
+
});
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
// -- SeoRecommendationVerifier ---------------------------------------------
|
|
158
|
+
export class SeoRecommendationVerifier {
|
|
159
|
+
/**
|
|
160
|
+
* Never throws. Resolves `{ ran:false, findings }` (input UNCHANGED) when
|
|
161
|
+
* disabled, when the agent md can't be loaded, on any provider/transport
|
|
162
|
+
* error, or when the response can't be parsed into a valid verdicts
|
|
163
|
+
* container. Resolves `{ ran:true, findings:<folded> }` on a successful,
|
|
164
|
+
* parseable response — always a subset of the input with severities only
|
|
165
|
+
* moving down.
|
|
166
|
+
*/
|
|
167
|
+
async verify(params) {
|
|
168
|
+
const { findings, config, projectRoot, now } = params;
|
|
169
|
+
// Nothing to verify — clean no-op, no LLM call needed either way
|
|
170
|
+
// (mirrors runSecurityVerifier's empty-findings short-circuit).
|
|
171
|
+
if (findings.length === 0) {
|
|
172
|
+
return { ran: true, findings };
|
|
173
|
+
}
|
|
174
|
+
// Defense-in-depth (sc-12-2): even a caller that constructs
|
|
175
|
+
// SeoRecommendationVerifier directly and bypasses the runner's own gate
|
|
176
|
+
// (Pattern E) can never trigger a provider call when the flag is off.
|
|
177
|
+
if (config.seo?.verifier?.enabled !== true) {
|
|
178
|
+
return { ran: false, findings };
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const definition = await loadAgentDefinition("bober-seo-verifier", projectRoot);
|
|
182
|
+
const llm = params.llm ?? buildDefaultClient();
|
|
183
|
+
const response = await llm.chat({
|
|
184
|
+
model: DEFAULT_SEO_VERIFIER_MODEL,
|
|
185
|
+
system: definition.systemPrompt,
|
|
186
|
+
messages: [{ role: "user", content: buildVerifierUserMessage(findings, now) }],
|
|
187
|
+
jsonObjectMode: true,
|
|
188
|
+
});
|
|
189
|
+
const parsedResult = parseVerdictsContainer(response.text);
|
|
190
|
+
if (!parsedResult.ok) {
|
|
191
|
+
logger.debug(`[seo-verifier] parse failed: ${parsedResult.error} — fail-closed`);
|
|
192
|
+
return { ran: false, findings };
|
|
193
|
+
}
|
|
194
|
+
return { ran: true, findings: applyVerdicts(findings, parsedResult.verdicts) };
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
// Agent-md-load failure, provider/network error, or any other throw —
|
|
198
|
+
// fail-closed, never propagate a crash out of an opt-in stage.
|
|
199
|
+
logger.debug(`[seo-verifier] failed: ${err instanceof Error ? err.message : String(err)} — fail-closed`);
|
|
200
|
+
return { ran: false, findings };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=verifier.js.map
|