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,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* readApprovedSeoFindings — the hub->ApprovedFinding adapter
|
|
3
|
+
* (spec-20260717-seo-improver-builder, Sprint 11; ADR-4). The REVERSE of
|
|
4
|
+
* `../hub-emitter.ts`'s SeoFinding->hub mapping: decodes exactly what the
|
|
5
|
+
* emitter encoded (domain `"seo"` filter, `cite:` evidence extraction,
|
|
6
|
+
* `playbook:`/`workflow:` tag extraction — all inside `ApprovedFinding.from`).
|
|
7
|
+
*
|
|
8
|
+
* Reads RAW rows via the same primitive `../../hub/finding-store.ts:47`'s
|
|
9
|
+
* `readFindings` uses (`getActiveFacts(HUB_SCOPE, undefined, "finding")`) —
|
|
10
|
+
* deliberately NOT `readFindings()` itself, because that helper calls
|
|
11
|
+
* `FindingSchema.parse`, which THROWS on a status outside the canonical
|
|
12
|
+
* 5-value enum (`finding-store.ts:48`); an `"approved"` row would crash it.
|
|
13
|
+
* Instead each row is `safeParse`d against the widened
|
|
14
|
+
* `ApprovedHubFindingSchema` and skipped on failure — mirrors
|
|
15
|
+
* `FactStoreFindingSource.read` (`../../hub/finding-source.ts`,
|
|
16
|
+
* "never throws; skip malformed").
|
|
17
|
+
*/
|
|
18
|
+
import { HUB_SCOPE } from "../../hub/finding-source.js";
|
|
19
|
+
import { ApprovedFinding, ApprovedHubFindingSchema } from "./approved-finding.js";
|
|
20
|
+
/**
|
|
21
|
+
* Reads approved, cited, SEO-domain hub Findings from `store` and maps each
|
|
22
|
+
* to an `ApprovedFinding` via `ApprovedFinding.from`. Never throws: malformed
|
|
23
|
+
* JSON, schema-invalid rows, non-`"seo"`-domain rows, non-`"approved"`
|
|
24
|
+
* status, and uncited/malformed-citation rows are all silently skipped
|
|
25
|
+
* (sc-11-4).
|
|
26
|
+
*/
|
|
27
|
+
export function readApprovedSeoFindings(store) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const row of store.getActiveFacts(HUB_SCOPE, undefined, "finding")) {
|
|
30
|
+
let json;
|
|
31
|
+
try {
|
|
32
|
+
json = JSON.parse(row.value);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
continue; // malformed JSON — skip, never throw
|
|
36
|
+
}
|
|
37
|
+
const parsed = ApprovedHubFindingSchema.safeParse(json);
|
|
38
|
+
if (!parsed.success)
|
|
39
|
+
continue; // schema-invalid — skip
|
|
40
|
+
if (parsed.data.domain !== "seo")
|
|
41
|
+
continue; // SEO-domain only (../hub-emitter.ts:69)
|
|
42
|
+
const approved = ApprovedFinding.from(parsed.data); // null if !approved / cite-bad
|
|
43
|
+
if (approved !== null)
|
|
44
|
+
out.push(approved);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=hub-approved-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-approved-source.js","sourceRoot":"","sources":["../../../src/seo/builder/hub-approved-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAgB;IACtD,MAAM,GAAG,GAAsB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;QACxE,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAY,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,qCAAqC;QACjD,CAAC;QAED,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,SAAS,CAAC,wBAAwB;QAEvD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK;YAAE,SAAS,CAAC,yCAAyC;QAErF,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,+BAA+B;QACnF,IAAI,QAAQ,KAAK,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeoBuilder — the gated generative builder (spec-20260717-seo-improver-
|
|
3
|
+
* builder, Sprint 12; ADR-4, the highest-risk piece of this spec). Crosses
|
|
4
|
+
* the advisory→generative boundary that Sprints 2/11 fenced off:
|
|
5
|
+
* `build(input)` accepts `ApprovedFinding[]` ONLY (`./approved-finding.js`) —
|
|
6
|
+
* a raw `SeoFinding[]` does not type-check (see `seo-builder.test.ts`'s
|
|
7
|
+
* `@ts-expect-error` compile-proof, sc-12-1) — and is constructed with a
|
|
8
|
+
* MANDATORY `NeverEncodeFilter` (`../never-encode-filter.js`, Sprint 2) that
|
|
9
|
+
* is re-run over EVERY generated draft's artifact text before it is
|
|
10
|
+
* returned (drop-only, sc-12-3/sc-12-4). Every returned `SeoDraft` carries
|
|
11
|
+
* `humanApprovalRequired: true` (the type's literal, ADR-4) and a
|
|
12
|
+
* `sourceCitationUrl` copied verbatim from the approving finding — nothing
|
|
13
|
+
* is ever auto-applied to a live property.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors `SeoAnalyzer`'s shape (`../analyzer.ts:304-336`): constructor-
|
|
16
|
+
* injected deps, `now` threaded in (never `new Date()`), and never-throws-
|
|
17
|
+
* on-recoverable-failure — here, a per-finding generation error increments
|
|
18
|
+
* `skipped` and moves on rather than bricking the whole batch (same
|
|
19
|
+
* drop-only spirit as `NeverEncodeFilter`, `../never-encode-filter.ts:16`).
|
|
20
|
+
*/
|
|
21
|
+
import type { BoberConfig } from "../../config/schema.js";
|
|
22
|
+
import type { NeverEncodeFilter } from "../never-encode-filter.js";
|
|
23
|
+
import type { ApprovedFinding } from "./approved-finding.js";
|
|
24
|
+
import { type DraftGenerator } from "./draft-generators.js";
|
|
25
|
+
import type { SeoDraft, SeoDraftKind } from "./draft-types.js";
|
|
26
|
+
export type SeoBuildInput = {
|
|
27
|
+
/** ONLY `ApprovedFinding[]` — a raw `SeoFinding[]` must NOT type-check (sc-12-1). */
|
|
28
|
+
approvedFindings: ApprovedFinding[];
|
|
29
|
+
/** The URL/page/entity every produced draft targets. */
|
|
30
|
+
target: string;
|
|
31
|
+
/**
|
|
32
|
+
* Accepted for interface parity with `SeoAnalyzeInput` (`../analyzer.ts:76`)
|
|
33
|
+
* and the Sprint-13 runner/CLI contract. Not consumed by this sprint's
|
|
34
|
+
* `build` body — no builder behaviour this sprint reads `config`.
|
|
35
|
+
*/
|
|
36
|
+
config: BoberConfig;
|
|
37
|
+
/** Injected wall-clock snapshot (ISO-8601) — `build` never reads the clock itself. */
|
|
38
|
+
now: string;
|
|
39
|
+
};
|
|
40
|
+
export type SeoBuildResult = {
|
|
41
|
+
drafts: SeoDraft[];
|
|
42
|
+
/** Count of approved findings that produced NO draft — either a generation error or a never-encode re-filter drop. */
|
|
43
|
+
skipped: number;
|
|
44
|
+
};
|
|
45
|
+
export declare class SeoBuilder {
|
|
46
|
+
/** MANDATORY (sc-12-1, ADR-4) — re-run over every generated draft's artifact text before it is returned. */
|
|
47
|
+
private readonly neverEncode;
|
|
48
|
+
private readonly generators;
|
|
49
|
+
constructor(
|
|
50
|
+
/** MANDATORY (sc-12-1, ADR-4) — re-run over every generated draft's artifact text before it is returned. */
|
|
51
|
+
neverEncode: NeverEncodeFilter, generators?: Record<SeoDraftKind, DraftGenerator>);
|
|
52
|
+
/**
|
|
53
|
+
* Generates one `SeoDraft` per approved finding via the deterministic
|
|
54
|
+
* templates in `./draft-generators.js`, re-runs the mandatory
|
|
55
|
+
* `NeverEncodeFilter` over each artifact, and returns only the drafts
|
|
56
|
+
* that pass. NEVER throws: a generation error for one finding increments
|
|
57
|
+
* `skipped` and the loop continues (sc-12-5).
|
|
58
|
+
*/
|
|
59
|
+
build(input: SeoBuildInput): SeoBuildResult;
|
|
60
|
+
/**
|
|
61
|
+
* Re-runs the INJECTED `NeverEncodeFilter` over `artifactText` (§4 of the
|
|
62
|
+
* sprint briefing). `NeverEncodeFilter.apply` scans `SeoFinding.recommendation`
|
|
63
|
+
* + evidence fields (`../never-encode-filter.ts:50-57`); a `SeoDraft` has
|
|
64
|
+
* no `recommendation` field, so a throwaway probe `SeoFinding` is built
|
|
65
|
+
* whose `recommendation` IS the draft artifact text — the only field that
|
|
66
|
+
* matters for the scan. Using the injected filter instance (rather than
|
|
67
|
+
* `NEVER_ENCODE_PATTERNS` directly) keeps the "mandatory filter" guarantee
|
|
68
|
+
* load-bearing and testable (a test could inject a spy filter).
|
|
69
|
+
*/
|
|
70
|
+
private isBanned;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=seo-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo-builder.d.ts","sourceRoot":"","sources":["../../../src/seo/builder/seo-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAoD,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9G,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAI/D,MAAM,MAAM,aAAa,GAAG;IAC1B,qFAAqF;IACrF,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB,sFAAsF;IACtF,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,sHAAsH;IACtH,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,qBAAa,UAAU;IAEnB,4GAA4G;IAC5G,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;;IAF3B,4GAA4G;IAC3F,WAAW,EAAE,iBAAiB,EAC9B,UAAU,GAAE,MAAM,CAAC,YAAY,EAAE,cAAc,CAA4B;IAG9F;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc;IAiC3C;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ;CAajB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { DEFAULT_DRAFT_GENERATORS, kindForApprovedFinding } from "./draft-generators.js";
|
|
2
|
+
// -- SeoBuilder ---------------------------------------------------------------
|
|
3
|
+
export class SeoBuilder {
|
|
4
|
+
neverEncode;
|
|
5
|
+
generators;
|
|
6
|
+
constructor(
|
|
7
|
+
/** MANDATORY (sc-12-1, ADR-4) — re-run over every generated draft's artifact text before it is returned. */
|
|
8
|
+
neverEncode, generators = DEFAULT_DRAFT_GENERATORS) {
|
|
9
|
+
this.neverEncode = neverEncode;
|
|
10
|
+
this.generators = generators;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generates one `SeoDraft` per approved finding via the deterministic
|
|
14
|
+
* templates in `./draft-generators.js`, re-runs the mandatory
|
|
15
|
+
* `NeverEncodeFilter` over each artifact, and returns only the drafts
|
|
16
|
+
* that pass. NEVER throws: a generation error for one finding increments
|
|
17
|
+
* `skipped` and the loop continues (sc-12-5).
|
|
18
|
+
*/
|
|
19
|
+
build(input) {
|
|
20
|
+
const drafts = [];
|
|
21
|
+
let skipped = 0;
|
|
22
|
+
for (const finding of input.approvedFindings) {
|
|
23
|
+
try {
|
|
24
|
+
const kind = kindForApprovedFinding(finding);
|
|
25
|
+
const artifact = this.generators[kind](finding, input.target);
|
|
26
|
+
if (this.isBanned(artifact)) {
|
|
27
|
+
// Re-filter DROP (sc-12-3/sc-12-4) — never emitted, counted as skipped.
|
|
28
|
+
skipped += 1;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
drafts.push({
|
|
32
|
+
kind,
|
|
33
|
+
humanApprovalRequired: true, // LITERAL true (draft-types.ts) — never a plain boolean.
|
|
34
|
+
sourceCitationUrl: finding.sourceCitationUrl, // COPIED verbatim — never invented.
|
|
35
|
+
sourceFindingId: finding.sourceFindingId,
|
|
36
|
+
target: input.target,
|
|
37
|
+
artifact,
|
|
38
|
+
playbookRef: finding.playbookRef,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// A generation error skips this finding only — never bricks the batch (sc-12-5).
|
|
43
|
+
skipped += 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { drafts, skipped };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Re-runs the INJECTED `NeverEncodeFilter` over `artifactText` (§4 of the
|
|
50
|
+
* sprint briefing). `NeverEncodeFilter.apply` scans `SeoFinding.recommendation`
|
|
51
|
+
* + evidence fields (`../never-encode-filter.ts:50-57`); a `SeoDraft` has
|
|
52
|
+
* no `recommendation` field, so a throwaway probe `SeoFinding` is built
|
|
53
|
+
* whose `recommendation` IS the draft artifact text — the only field that
|
|
54
|
+
* matters for the scan. Using the injected filter instance (rather than
|
|
55
|
+
* `NEVER_ENCODE_PATTERNS` directly) keeps the "mandatory filter" guarantee
|
|
56
|
+
* load-bearing and testable (a test could inject a spy filter).
|
|
57
|
+
*/
|
|
58
|
+
isBanned(artifactText) {
|
|
59
|
+
const probe = {
|
|
60
|
+
recommendation: artifactText,
|
|
61
|
+
workflow: "technical-audit",
|
|
62
|
+
playbookRef: "",
|
|
63
|
+
citationUrl: "",
|
|
64
|
+
evidence: [],
|
|
65
|
+
severity: 3,
|
|
66
|
+
humanApprovalRequired: false,
|
|
67
|
+
confidence: "firm",
|
|
68
|
+
};
|
|
69
|
+
return this.neverEncode.apply([probe]).dropped.length > 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=seo-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo-builder.js","sourceRoot":"","sources":["../../../src/seo/builder/seo-builder.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAuB,MAAM,uBAAuB,CAAC;AA0B9G,gFAAgF;AAEhF,MAAM,OAAO,UAAU;IAGF;IACA;IAHnB;IACE,4GAA4G;IAC3F,WAA8B,EAC9B,aAAmD,wBAAwB;QAD3E,gBAAW,GAAX,WAAW,CAAmB;QAC9B,eAAU,GAAV,UAAU,CAAiE;IAC3F,CAAC;IAEJ;;;;;;OAMG;IACH,KAAK,CAAC,KAAoB;QACxB,MAAM,MAAM,GAAe,EAAE,CAAC;QAC9B,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;gBAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAE9D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,wEAAwE;oBACxE,OAAO,IAAI,CAAC,CAAC;oBACb,SAAS;gBACX,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI;oBACJ,qBAAqB,EAAE,IAAI,EAAE,yDAAyD;oBACtF,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,oCAAoC;oBAClF,eAAe,EAAE,OAAO,CAAC,eAAe;oBACxC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ;oBACR,WAAW,EAAE,OAAO,CAAC,WAAW;iBACjC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;gBACjF,OAAO,IAAI,CAAC,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;;;OASG;IACK,QAAQ,CAAC,YAAoB;QACnC,MAAM,KAAK,GAAe;YACxB,cAAc,EAAE,YAAY;YAC5B,QAAQ,EAAE,iBAAiB;YAC3B,WAAW,EAAE,EAAE;YACf,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,CAAC;YACX,qBAAqB,EAAE,KAAK;YAC5B,UAAU,EAAE,MAAM;SACnB,CAAC;QACF,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5D,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeoCitationGate — the deterministic, offline, pre-hub citation gate
|
|
3
|
+
* (spec-20260715-ultimate-seo-suite, Sprint 10; ADR-3,
|
|
4
|
+
* arch-20260715-ultimate-seo-agents-skills-architecture.md:279-295).
|
|
5
|
+
*
|
|
6
|
+
* Pure and total: no LLM, no egress, no filesystem, no clock. Imports
|
|
7
|
+
* nothing beyond `./types.js`. Partitions findings by whether their
|
|
8
|
+
* `citationUrl` is a well-formed primary-source URL — uncited findings are
|
|
9
|
+
* dropped and NEVER reach the hub (Sprint 11) or a human.
|
|
10
|
+
*
|
|
11
|
+
* Naming note (see the sprint briefing §0): the contract (sc-10-3) spells
|
|
12
|
+
* the method `filter`; the architecture and generatorNotes call it `apply`.
|
|
13
|
+
* Both are provided — `filter` is an alias of the same implementation.
|
|
14
|
+
*/
|
|
15
|
+
import type { SeoFinding } from "./types.js";
|
|
16
|
+
/** Mirrors `SeoConfigSchema.blockThreshold` (config/schema.ts:697). */
|
|
17
|
+
export type SeoBlockThreshold = "never" | "any-uncited" | "critical-uncited";
|
|
18
|
+
export type CitationGateResult = {
|
|
19
|
+
/** Findings with a well-formed primary-source citationUrl — the ONLY findings emitted downstream. */
|
|
20
|
+
cited: SeoFinding[];
|
|
21
|
+
/** Findings with an empty/malformed citationUrl — never reach the hub. */
|
|
22
|
+
dropped: SeoFinding[];
|
|
23
|
+
/** Fail-closed exit-2 signal, derived from `dropped` per `threshold`. */
|
|
24
|
+
blocked: boolean;
|
|
25
|
+
};
|
|
26
|
+
export declare class SeoCitationGate {
|
|
27
|
+
/**
|
|
28
|
+
* Partitions `findings` into `cited`/`dropped` by citationUrl
|
|
29
|
+
* well-formedness, then derives `blocked` from `threshold`. Pure and
|
|
30
|
+
* total: identical input always yields identical output.
|
|
31
|
+
*/
|
|
32
|
+
apply(findings: SeoFinding[], threshold: SeoBlockThreshold): CitationGateResult;
|
|
33
|
+
/** Alias of `apply` — satisfies the contract's literal `.filter(...)` wording (sc-10-3). */
|
|
34
|
+
filter: (findings: SeoFinding[], threshold: SeoBlockThreshold) => CitationGateResult;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=citation-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation-gate.d.ts","sourceRoot":"","sources":["../../src/seo/citation-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,uEAAuE;AACvE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAE7E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,qGAAqG;IACrG,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,0EAA0E;IAC1E,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAuCF,qBAAa,eAAe;IAC1B;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,iBAAiB,GAAG,kBAAkB;IAe/E,4FAA4F;IAC5F,MAAM,GAAI,UAAU,UAAU,EAAE,EAAE,WAAW,iBAAiB,KAAG,kBAAkB,CACjD;CACnC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A citationUrl is well-formed when it is a non-empty, non-whitespace
|
|
3
|
+
* string that parses as an absolute http(s) URL. No URL-validation utility
|
|
4
|
+
* exists elsewhere in `src` — this is a local, single-purpose check.
|
|
5
|
+
*/
|
|
6
|
+
function isWellFormedCitationUrl(url) {
|
|
7
|
+
if (typeof url !== "string" || url.trim().length === 0)
|
|
8
|
+
return false;
|
|
9
|
+
try {
|
|
10
|
+
const parsed = new URL(url);
|
|
11
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* bober: the "critical" cutoff for `critical-uncited` is not pinned by the
|
|
19
|
+
* contract; severity 4-5 (of the 1..5 scale) is the recommended reading
|
|
20
|
+
* per the sprint briefing — bump this constant if that reading changes.
|
|
21
|
+
*/
|
|
22
|
+
const CRITICAL_SEVERITY_FLOOR = 4;
|
|
23
|
+
function isBlocked(dropped, threshold) {
|
|
24
|
+
switch (threshold) {
|
|
25
|
+
case "never":
|
|
26
|
+
return false;
|
|
27
|
+
case "any-uncited":
|
|
28
|
+
return dropped.length > 0;
|
|
29
|
+
case "critical-uncited":
|
|
30
|
+
return dropped.some((finding) => finding.severity >= CRITICAL_SEVERITY_FLOOR);
|
|
31
|
+
default: {
|
|
32
|
+
const _exhaustive = threshold; // compile error if a SeoBlockThreshold value is unhandled
|
|
33
|
+
return _exhaustive;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class SeoCitationGate {
|
|
38
|
+
/**
|
|
39
|
+
* Partitions `findings` into `cited`/`dropped` by citationUrl
|
|
40
|
+
* well-formedness, then derives `blocked` from `threshold`. Pure and
|
|
41
|
+
* total: identical input always yields identical output.
|
|
42
|
+
*/
|
|
43
|
+
apply(findings, threshold) {
|
|
44
|
+
const cited = [];
|
|
45
|
+
const dropped = [];
|
|
46
|
+
for (const finding of findings) {
|
|
47
|
+
if (isWellFormedCitationUrl(finding.citationUrl)) {
|
|
48
|
+
cited.push(finding);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
dropped.push(finding);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { cited, dropped, blocked: isBlocked(dropped, threshold) };
|
|
55
|
+
}
|
|
56
|
+
/** Alias of `apply` — satisfies the contract's literal `.filter(...)` wording (sc-10-3). */
|
|
57
|
+
filter = (findings, threshold) => this.apply(findings, threshold);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=citation-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation-gate.js","sourceRoot":"","sources":["../../src/seo/citation-gate.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,SAAS,uBAAuB,CAAC,GAAW;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAElC,SAAS,SAAS,CAAC,OAAqB,EAAE,SAA4B;IACpE,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5B,KAAK,kBAAkB;YACrB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,IAAI,uBAAuB,CAAC,CAAC;QAChF,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,SAAS,CAAC,CAAC,0DAA0D;YAChG,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,OAAO,eAAe;IAC1B;;;;OAIG;IACH,KAAK,CAAC,QAAsB,EAAE,SAA4B;QACxD,MAAM,KAAK,GAAiB,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,uBAAuB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBACjD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IACpE,CAAC;IAED,4FAA4F;IAC5F,MAAM,GAAG,CAAC,QAAsB,EAAE,SAA4B,EAAsB,EAAE,CACpF,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;CACnC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { SeoRunInput, SeoRunOutcome } from "./runner.js";
|
|
3
|
+
import type { SeoBuildRunInput, SeoBuildRunOutcome } from "./builder/build-runner.js";
|
|
4
|
+
export interface SeoCommandOverrides {
|
|
5
|
+
/** Injected in tests to bypass the real runner (no real LLM/network/fs). */
|
|
6
|
+
runWorkflow?: (input: SeoRunInput) => Promise<SeoRunOutcome>;
|
|
7
|
+
/** Injected in tests to bypass the real build runner (no real fs/hub). */
|
|
8
|
+
runBuild?: (input: SeoBuildRunInput) => Promise<SeoBuildRunOutcome>;
|
|
9
|
+
}
|
|
10
|
+
export declare function registerSeoCommand(program: Command, overrides?: SeoCommandOverrides): void;
|
|
11
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/seo/command.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAkBtF,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7D,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACrE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAqE1F"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bober seo <workflow> [target]` — run an SEO workflow end-to-end.
|
|
3
|
+
* (spec-20260715-ultimate-seo-suite, Sprint 11.)
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `registerSecurityAuditCommand`
|
|
6
|
+
* (`src/cli/commands/security-audit.ts:289-322`): `now` is stamped ONCE at
|
|
7
|
+
* the `.action()` boundary and threaded downstream — never re-read inside
|
|
8
|
+
* `SeoWorkflowRunner`. The handler NEVER throws; it always sets
|
|
9
|
+
* `process.exitCode` (`0` pass / `2` blocked-or-fail-closed — `1` is
|
|
10
|
+
* Commander-reserved).
|
|
11
|
+
*
|
|
12
|
+
* Lives at `src/seo/command.ts` (not `src/cli/commands/seo.ts`) per the
|
|
13
|
+
* contract's `estimatedFiles` — mirrors `registerFleetCommand`
|
|
14
|
+
* (`src/fleet/index.ts`, imported into the CLI at `cli/index.ts:39`).
|
|
15
|
+
*
|
|
16
|
+
* `bober seo build <reportId>` (spec-20260717-seo-improver-builder,
|
|
17
|
+
* Sprint 13) is an ADDITIVE child subcommand hung off the returned `seo`
|
|
18
|
+
* command — it does NOT alter the `seo <workflow> [target]` `.action()`
|
|
19
|
+
* chain above (sc-13-3). Same stamp-once + never-throw discipline via
|
|
20
|
+
* `SeoBuildRunner`.
|
|
21
|
+
*/
|
|
22
|
+
import chalk from "chalk";
|
|
23
|
+
import { findProjectRoot } from "../utils/fs.js";
|
|
24
|
+
import { loadConfig } from "../config/loader.js";
|
|
25
|
+
import { SeoWorkflowRunner } from "./runner.js";
|
|
26
|
+
import { SeoBuildRunner } from "./builder/build-runner.js";
|
|
27
|
+
/** The 8 SEO workflows the CLI dispatches on (mirrors `types.ts:17-25`). */
|
|
28
|
+
const SEO_WORKFLOWS = [
|
|
29
|
+
"technical-audit",
|
|
30
|
+
"rank-track",
|
|
31
|
+
"content-decay",
|
|
32
|
+
"topical-map",
|
|
33
|
+
"ai-visibility",
|
|
34
|
+
"parasite-watch",
|
|
35
|
+
"internal-linking",
|
|
36
|
+
"schema-audit",
|
|
37
|
+
];
|
|
38
|
+
function isSeoWorkflow(value) {
|
|
39
|
+
return SEO_WORKFLOWS.includes(value);
|
|
40
|
+
}
|
|
41
|
+
export function registerSeoCommand(program, overrides) {
|
|
42
|
+
const seo = program
|
|
43
|
+
.command("seo <workflow> [target]")
|
|
44
|
+
.description("Run an SEO workflow end-to-end (offline by default; opt-in live data via config.seo.egress).")
|
|
45
|
+
.action(async (workflow, target) => {
|
|
46
|
+
try {
|
|
47
|
+
if (!isSeoWorkflow(workflow)) {
|
|
48
|
+
process.stderr.write(chalk.red(`seo: unknown workflow "${workflow}". Expected one of: ${SEO_WORKFLOWS.join(", ")}\n`));
|
|
49
|
+
process.exitCode = 2;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const projectRoot = (await findProjectRoot()) ?? process.cwd();
|
|
53
|
+
// Stamp wall-clock time ONLY here — never inside the runner.
|
|
54
|
+
const now = new Date().toISOString();
|
|
55
|
+
const config = await loadConfig(projectRoot);
|
|
56
|
+
const run = overrides?.runWorkflow ?? ((i) => new SeoWorkflowRunner().run(i));
|
|
57
|
+
const { report, exitCode } = await run({ projectRoot, config, workflow, target, now });
|
|
58
|
+
if (report) {
|
|
59
|
+
process.stdout.write(`SEO report ${report.reportId}: verdict=${report.verdict}, ` +
|
|
60
|
+
`findings=${report.findings.length}, droppedUncited=${report.droppedUncited}\n`);
|
|
61
|
+
}
|
|
62
|
+
process.exitCode = exitCode;
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
process.stderr.write(chalk.red(`seo failed: ${err instanceof Error ? err.message : String(err)}\n`));
|
|
66
|
+
process.exitCode = 2; // fail-closed; 1 is Commander-reserved
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Additive child subcommand (spec-20260717-seo-improver-builder, Sprint 13)
|
|
70
|
+
// — does NOT alter the analyze `.action()` chain above (sc-13-3).
|
|
71
|
+
seo
|
|
72
|
+
.command("build <reportId>")
|
|
73
|
+
.description("Draft human-approval-required SEO artifacts from a report's approved hub findings.")
|
|
74
|
+
.action(async (reportId) => {
|
|
75
|
+
try {
|
|
76
|
+
const projectRoot = (await findProjectRoot()) ?? process.cwd();
|
|
77
|
+
// Stamp wall-clock time ONLY here — never inside the build runner.
|
|
78
|
+
const now = new Date().toISOString();
|
|
79
|
+
const config = await loadConfig(projectRoot);
|
|
80
|
+
const run = overrides?.runBuild ?? ((i) => new SeoBuildRunner().run(i));
|
|
81
|
+
const { exitCode } = await run({ projectRoot, config, reportId, now });
|
|
82
|
+
process.exitCode = exitCode;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
process.stderr.write(chalk.red(`seo build failed: ${err instanceof Error ? err.message : String(err)}\n`));
|
|
86
|
+
process.exitCode = 2; // fail-closed; 1 is Commander-reserved
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/seo/command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,4EAA4E;AAC5E,MAAM,aAAa,GAA2B;IAC5C,iBAAiB;IACjB,YAAY;IACZ,eAAe;IACf,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,kBAAkB;IAClB,cAAc;CACf,CAAC;AAEF,SAAS,aAAa,CAAC,KAAa;IAClC,OAAQ,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AASD,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,SAA+B;IAClF,MAAM,GAAG,GAAG,OAAO;SAChB,OAAO,CAAC,yBAAyB,CAAC;SAClC,WAAW,CACV,8FAA8F,CAC/F;SACA,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,MAAe,EAAE,EAAE;QAClD,IAAI,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,GAAG,CACP,0BAA0B,QAAQ,uBAAuB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACtF,CACF,CAAC;gBACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,CAAC,MAAM,eAAe,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAC/D,6DAA6D;YAC7D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAE7C,MAAM,GAAG,GACP,SAAS,EAAE,WAAW,IAAI,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,IAAI,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAEjF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAEvF,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,MAAM,CAAC,QAAQ,aAAa,MAAM,CAAC,OAAO,IAAI;oBAC1D,YAAY,MAAM,CAAC,QAAQ,CAAC,MAAM,oBAAoB,MAAM,CAAC,cAAc,IAAI,CAClF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,GAAG,CAAC,eAAe,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAC/E,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,uCAAuC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,4EAA4E;IAC5E,kEAAkE;IAClE,GAAG;SACA,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CACV,oFAAoF,CACrF;SACA,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,EAAE;QACjC,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,CAAC,MAAM,eAAe,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAC/D,mEAAmE;YACnE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAE7C,MAAM,GAAG,GACP,SAAS,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAEhF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,CAAC,GAAG,CAAC,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CACrF,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,uCAAuC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContentSanitizer — fail-closed wrapper around damcrawler's `sanitize`
|
|
3
|
+
* (spec-20260717-seo-improver-builder, Sprint 6; ADR-11).
|
|
4
|
+
*
|
|
5
|
+
* ADR-11's decision is to sanitize untrusted crawled/scraped free-text
|
|
6
|
+
* INSIDE the damcrawler adapter, at the network→in-process boundary,
|
|
7
|
+
* BEFORE it ever reaches `SeoAnalyzer` (which `JSON.stringify`s rows
|
|
8
|
+
* verbatim into its LLM system prompt — the prompt-injection surface this
|
|
9
|
+
* sprint closes). This class does no importing/loading of damcrawler
|
|
10
|
+
* itself — the caller (`DamcrawlerCrawlEngine`, already holding the loaded
|
|
11
|
+
* module behind the `site-crawl` axis) injects the narrow `SanitizeFn`.
|
|
12
|
+
*
|
|
13
|
+
* IMPORTANT SDK correction (see sprint briefing §0/§9.1): damcrawler's
|
|
14
|
+
* `sanitizeWithReport(raw, sourceUrl?)` returns a bare `string` — it does
|
|
15
|
+
* NOT yield `hadThreats`. The only damcrawler export exposing `hadThreats`
|
|
16
|
+
* is `sanitize(raw, options?): { content; threats; hadThreats }`
|
|
17
|
+
* (`damcrawler/src/lib/sanitize.ts:68-79,89`). This wrapper's `SanitizeFn`
|
|
18
|
+
* type matches THAT signature — callers must inject `dam.sanitize`, not
|
|
19
|
+
* `dam.sanitizeWithReport`.
|
|
20
|
+
*/
|
|
21
|
+
import { type Logger } from "../utils/logger.js";
|
|
22
|
+
/**
|
|
23
|
+
* The narrow sanitize surface this module depends on — a SUBSET of
|
|
24
|
+
* damcrawler's `SanitizeResult` (`sanitize.ts:68-79`, `threats` omitted,
|
|
25
|
+
* this module never needs the detailed threat breakdown). Injected so
|
|
26
|
+
* tests never require the real `damcrawler` dependency.
|
|
27
|
+
*/
|
|
28
|
+
export type SanitizeFn = (raw: string, options?: {
|
|
29
|
+
sourceUrl?: string;
|
|
30
|
+
}) => {
|
|
31
|
+
content: string;
|
|
32
|
+
hadThreats: boolean;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Fail-closed content sanitizer. `clean()` never throws: a successful
|
|
36
|
+
* sanitize call logs+strips on `hadThreats`; a sanitize-function error
|
|
37
|
+
* drops the text entirely (`content: ""`, `hadThreats: true`) rather than
|
|
38
|
+
* letting raw, unsanitized attacker-controlled text pass through.
|
|
39
|
+
*/
|
|
40
|
+
export declare class ContentSanitizer {
|
|
41
|
+
private readonly sanitizeFn;
|
|
42
|
+
private readonly log;
|
|
43
|
+
constructor(sanitizeFn: SanitizeFn, log?: Pick<Logger, "warn">);
|
|
44
|
+
/**
|
|
45
|
+
* Sanitizes `text` sourced from `url`. `hadThreats` is logged (warn, for
|
|
46
|
+
* audit) and the STRIPPED `content` is returned either way — callers
|
|
47
|
+
* must never fall back to the raw input. A thrown sanitize error is
|
|
48
|
+
* treated as fail-closed: the page's free-text is dropped rather than
|
|
49
|
+
* passed through unsanitized.
|
|
50
|
+
*/
|
|
51
|
+
clean(text: string, url: string): {
|
|
52
|
+
content: string;
|
|
53
|
+
hadThreats: boolean;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=content-sanitizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-sanitizer.d.ts","sourceRoot":"","sources":["../../src/seo/content-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC;AAErH;;;;;GAKG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,UAAU,EAAE,UAAU,EACtB,GAAG,GAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAU;IAGrD;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE;CAW3E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContentSanitizer — fail-closed wrapper around damcrawler's `sanitize`
|
|
3
|
+
* (spec-20260717-seo-improver-builder, Sprint 6; ADR-11).
|
|
4
|
+
*
|
|
5
|
+
* ADR-11's decision is to sanitize untrusted crawled/scraped free-text
|
|
6
|
+
* INSIDE the damcrawler adapter, at the network→in-process boundary,
|
|
7
|
+
* BEFORE it ever reaches `SeoAnalyzer` (which `JSON.stringify`s rows
|
|
8
|
+
* verbatim into its LLM system prompt — the prompt-injection surface this
|
|
9
|
+
* sprint closes). This class does no importing/loading of damcrawler
|
|
10
|
+
* itself — the caller (`DamcrawlerCrawlEngine`, already holding the loaded
|
|
11
|
+
* module behind the `site-crawl` axis) injects the narrow `SanitizeFn`.
|
|
12
|
+
*
|
|
13
|
+
* IMPORTANT SDK correction (see sprint briefing §0/§9.1): damcrawler's
|
|
14
|
+
* `sanitizeWithReport(raw, sourceUrl?)` returns a bare `string` — it does
|
|
15
|
+
* NOT yield `hadThreats`. The only damcrawler export exposing `hadThreats`
|
|
16
|
+
* is `sanitize(raw, options?): { content; threats; hadThreats }`
|
|
17
|
+
* (`damcrawler/src/lib/sanitize.ts:68-79,89`). This wrapper's `SanitizeFn`
|
|
18
|
+
* type matches THAT signature — callers must inject `dam.sanitize`, not
|
|
19
|
+
* `dam.sanitizeWithReport`.
|
|
20
|
+
*/
|
|
21
|
+
import { logger } from "../utils/logger.js";
|
|
22
|
+
/**
|
|
23
|
+
* Fail-closed content sanitizer. `clean()` never throws: a successful
|
|
24
|
+
* sanitize call logs+strips on `hadThreats`; a sanitize-function error
|
|
25
|
+
* drops the text entirely (`content: ""`, `hadThreats: true`) rather than
|
|
26
|
+
* letting raw, unsanitized attacker-controlled text pass through.
|
|
27
|
+
*/
|
|
28
|
+
export class ContentSanitizer {
|
|
29
|
+
sanitizeFn;
|
|
30
|
+
log;
|
|
31
|
+
constructor(sanitizeFn, log = logger) {
|
|
32
|
+
this.sanitizeFn = sanitizeFn;
|
|
33
|
+
this.log = log;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Sanitizes `text` sourced from `url`. `hadThreats` is logged (warn, for
|
|
37
|
+
* audit) and the STRIPPED `content` is returned either way — callers
|
|
38
|
+
* must never fall back to the raw input. A thrown sanitize error is
|
|
39
|
+
* treated as fail-closed: the page's free-text is dropped rather than
|
|
40
|
+
* passed through unsanitized.
|
|
41
|
+
*/
|
|
42
|
+
clean(text, url) {
|
|
43
|
+
try {
|
|
44
|
+
const r = this.sanitizeFn(text, { sourceUrl: url });
|
|
45
|
+
if (r.hadThreats) {
|
|
46
|
+
this.log.warn(`[seo][content-sanitizer] injection vectors neutralized in ${url}`);
|
|
47
|
+
}
|
|
48
|
+
return { content: r.content, hadThreats: r.hadThreats };
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { content: "", hadThreats: true }; // fail-closed DROP: never pass raw text through
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=content-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-sanitizer.js","sourceRoot":"","sources":["../../src/seo/content-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,MAAM,EAAe,MAAM,oBAAoB,CAAC;AAUzD;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IAER;IACA;IAFnB,YACmB,UAAsB,EACtB,MAA4B,MAAM;QADlC,eAAU,GAAV,UAAU,CAAY;QACtB,QAAG,GAAH,GAAG,CAA+B;IAClD,CAAC;IAEJ;;;;;;OAMG;IACH,KAAK,CAAC,IAAY,EAAE,GAAW;QAC7B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBACjB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,GAAG,EAAE,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,gDAAgD;QAC5F,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CrawlEngine port (spec-20260717-seo-improver-builder, Sprint 6; ADR-9).
|
|
3
|
+
*
|
|
4
|
+
* Pure `interface` + query `type` only — no runtime code, mirroring
|
|
5
|
+
* `data-source.ts`'s structure. `DamcrawlerCrawlEngine` (Sprint 6) is the
|
|
6
|
+
* first implementer; `CrawlSource`/`SeoDataSource` wiring is deferred to
|
|
7
|
+
* Sprint 7 (nonGoal here).
|
|
8
|
+
*
|
|
9
|
+
* `UrlInspectionQuery`/`UrlInspectionRow`, `LinkGraphQuery`/`LinkGraphRow`,
|
|
10
|
+
* and `CrawlPageRow` already exist on `data-source.ts` (Sprint 1) — imported
|
|
11
|
+
* here, never redefined.
|
|
12
|
+
*/
|
|
13
|
+
import type { DataOutcome } from "./types.js";
|
|
14
|
+
import type { UrlInspectionQuery, UrlInspectionRow, LinkGraphQuery, LinkGraphRow, CrawlPageRow } from "./data-source.js";
|
|
15
|
+
/**
|
|
16
|
+
* Site-crawl query (rootUrl + optional bounds). No `Query` pair exists yet
|
|
17
|
+
* in `data-source.ts` for crawl pages — `CrawlPageRow` has none (see its
|
|
18
|
+
* docstring, `data-source.ts:136-143`) since the crawl query lives here.
|
|
19
|
+
*/
|
|
20
|
+
export type CrawlQuery = {
|
|
21
|
+
rootUrl: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
maxDepth?: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* ADR-9 port. Every method: guard `site-crawl` FIRST (before any import),
|
|
27
|
+
* lazy-load damcrawler, and degrade to `{ kind: "abstain", reason }` —
|
|
28
|
+
* never throw to the caller.
|
|
29
|
+
*/
|
|
30
|
+
export interface CrawlEngine {
|
|
31
|
+
crawl(q: CrawlQuery): Promise<DataOutcome<CrawlPageRow[]>>;
|
|
32
|
+
urlVisibility(q: UrlInspectionQuery): Promise<DataOutcome<UrlInspectionRow[]>>;
|
|
33
|
+
linkGraph(q: LinkGraphQuery): Promise<DataOutcome<LinkGraphRow[]>>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=crawl-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl-engine.d.ts","sourceRoot":"","sources":["../../src/seo/crawl-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEzH;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC3D,aAAa,CAAC,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC/E,SAAS,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;CACpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl-engine.js","sourceRoot":"","sources":["../../src/seo/crawl-engine.ts"],"names":[],"mappings":""}
|