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,306 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bober.security-dex-backend
|
|
3
|
+
description: "Crypto exchange/DEX off-chain backend security signature library. Not a workflow skill -- a data file of discrete vulnerable/safe code signature blocks read by SecuritySignatureParser. Covers withdrawal TOCTOU races, missing withdrawal idempotency, missing 2FA/withdrawal-whitelist cooldown, deposit crediting without confirmations, token decimals mismatch, float token amounts, hot-wallet key custody, KMS signer authz gates, SIWE replay, missing price-feed circuit breakers, unsigned webhooks, and unvalidated withdrawal amounts."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bober.security-dex-backend — Crypto Exchange/DEX Off-Chain Backend Security Signature Library
|
|
7
|
+
|
|
8
|
+
This skill is a **signature-library** file, not a workflow skill. It is read (as raw
|
|
9
|
+
markdown text) by `SecuritySignatureParser.parse()`
|
|
10
|
+
(`src/orchestrator/security-knowledge/parser.ts`) and turned into typed
|
|
11
|
+
`SecuritySignature[]` records used by the security-audit agent team. Do not confuse this
|
|
12
|
+
with `bober.security-audit`, which is the audit *workflow* skill. This skill covers the
|
|
13
|
+
off-chain custody/backend surface of an exchange or DEX — where most exchange money is
|
|
14
|
+
actually stolen — as distinct from `bober.security-solidity`'s on-chain contract surface.
|
|
15
|
+
|
|
16
|
+
## Signature Block Format
|
|
17
|
+
|
|
18
|
+
Each signature is a level-3 heading (three `#` characters, a space, then the
|
|
19
|
+
`signatureId`) followed by labelled fields and two fenced code examples. This file and
|
|
20
|
+
`SecuritySignatureParser` are one executable spec — keep them in sync.
|
|
21
|
+
|
|
22
|
+
Required fields per block:
|
|
23
|
+
- The heading text itself is the `signatureId` (must be non-empty).
|
|
24
|
+
- `- **Title:** <human-readable title>`
|
|
25
|
+
- `- **CWE:** CWE-xx` (optional — omit the line entirely for `cwe: null`)
|
|
26
|
+
- `- **Severity:** critical|high|medium|low|info`
|
|
27
|
+
- `- **VulnClass:** <a VulnClass union member, verbatim — see security-audit-types.ts>`
|
|
28
|
+
- `- **Invariant:** <the safety invariant this signature protects>`
|
|
29
|
+
- `- **Keywords:** comma, separated, keywords`
|
|
30
|
+
|
|
31
|
+
Then two labelled fenced code examples:
|
|
32
|
+
- `**Unsafe:**` followed by a fenced `ts` block with the vulnerable example.
|
|
33
|
+
- `**Safe:**` followed by a fenced `ts` block with the fixed example.
|
|
34
|
+
|
|
35
|
+
A block missing `Title`, a valid `VulnClass`, a valid `Severity`, or a non-empty
|
|
36
|
+
unsafe/safe example is dropped by the parser — never a fatal error.
|
|
37
|
+
|
|
38
|
+
## Signatures
|
|
39
|
+
|
|
40
|
+
### dex.withdrawal-toctou-race
|
|
41
|
+
- **Title:** Withdrawal TOCTOU race (SELECT-compare-UPDATE, no row lock)
|
|
42
|
+
- **CWE:** CWE-362
|
|
43
|
+
- **Severity:** critical
|
|
44
|
+
- **VulnClass:** race-condition
|
|
45
|
+
- **Invariant:** A withdrawal debit is a single atomic conditional write against the balance — never a separate SELECT-then-UPDATE that lets two concurrent requests both pass the check.
|
|
46
|
+
- **Keywords:** withdrawal, FOR UPDATE, row lock, TOCTOU, balance
|
|
47
|
+
|
|
48
|
+
**Unsafe:**
|
|
49
|
+
```ts
|
|
50
|
+
const { balance } = await db.query("SELECT balance FROM wallets WHERE id = $1", [id]);
|
|
51
|
+
if (balance >= amount) await db.query("UPDATE wallets SET balance = balance - $1 WHERE id = $2", [amount, id]);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Safe:**
|
|
55
|
+
```ts
|
|
56
|
+
const result = await db.query(
|
|
57
|
+
"UPDATE wallets SET balance = balance - $1 WHERE id = $2 AND balance >= $1 RETURNING balance",
|
|
58
|
+
[amount, id],
|
|
59
|
+
);
|
|
60
|
+
if (result.rowCount === 0) throw new Error("insufficient balance");
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### dex.missing-withdrawal-idempotency
|
|
64
|
+
- **Title:** Missing withdrawal idempotency key (double-withdraw on client retry)
|
|
65
|
+
- **CWE:** CWE-362
|
|
66
|
+
- **Severity:** critical
|
|
67
|
+
- **VulnClass:** race-condition
|
|
68
|
+
- **Invariant:** A withdrawal request carries a unique client idempotency key enforced with a database uniqueness constraint, so a retried request cannot execute the withdrawal twice.
|
|
69
|
+
- **Keywords:** idempotency, withdrawal, unique, retry, double-withdraw
|
|
70
|
+
|
|
71
|
+
**Unsafe:**
|
|
72
|
+
```ts
|
|
73
|
+
app.post("/withdraw", async (req, res) => { await executeWithdrawal(req.body.amount, req.body.address); });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Safe:**
|
|
77
|
+
```ts
|
|
78
|
+
app.post("/withdraw", async (req, res) => {
|
|
79
|
+
const inserted = await db.query(
|
|
80
|
+
"INSERT INTO withdrawal_requests (idempotency_key) VALUES ($1) ON CONFLICT DO NOTHING RETURNING idempotency_key",
|
|
81
|
+
[req.headers["idempotency-key"]],
|
|
82
|
+
);
|
|
83
|
+
if (inserted.rowCount === 0) return res.status(409).json({ error: "duplicate request" });
|
|
84
|
+
await executeWithdrawal(req.body.amount, req.body.address);
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### dex.missing-2fa-cooldown
|
|
89
|
+
- **Title:** Missing 2FA / withdrawal-whitelist cooldown (Crypto.com-style bypass)
|
|
90
|
+
- **Severity:** critical
|
|
91
|
+
- **VulnClass:** authn-authz
|
|
92
|
+
- **Invariant:** A withdrawal to a new destination address requires a fresh second-factor confirmation and is held for a cooldown window before it becomes eligible to execute, unless the address is already on an established allowlist.
|
|
93
|
+
- **Keywords:** 2FA, withdrawal whitelist, cooldown, allowlist, address-book
|
|
94
|
+
|
|
95
|
+
**Unsafe:**
|
|
96
|
+
```ts
|
|
97
|
+
await executeWithdrawal(userId, amount, newAddress); // instant withdrawal to any address, no 2FA re-check
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Safe:**
|
|
101
|
+
```ts
|
|
102
|
+
await assert2faVerified(userId, req.body.totpCode);
|
|
103
|
+
if (!(await isWhitelistedAddress(userId, newAddress))) {
|
|
104
|
+
await queueForCooldown(userId, newAddress, amount, WITHDRAWAL_COOLDOWN_MS); // held before executing
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
await executeWithdrawal(userId, amount, newAddress);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### dex.deposit-no-confirmations
|
|
111
|
+
- **Title:** Deposit credited off event-log/webhook without outer-tx-success + balanceOf delta + confirmations
|
|
112
|
+
- **CWE:** CWE-345
|
|
113
|
+
- **Severity:** critical
|
|
114
|
+
- **VulnClass:** money-integrity
|
|
115
|
+
- **Invariant:** A deposit is only credited after the containing transaction's receipt reports success, the credited amount matches a measured balanceOf delta, and the block has accumulated the required confirmation depth.
|
|
116
|
+
- **Keywords:** deposit, confirmations, balanceOf, reorg, receipt.status
|
|
117
|
+
|
|
118
|
+
**Unsafe:**
|
|
119
|
+
```ts
|
|
120
|
+
provider.on(transferFilter, (from, to, amount) => { creditDeposit(to, amount); }); // credited on log alone, no confirmation wait
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Safe:**
|
|
124
|
+
```ts
|
|
125
|
+
provider.on(transferFilter, async (from, to, amount, event) => {
|
|
126
|
+
const receipt = await event.getTransactionReceipt();
|
|
127
|
+
if (receipt.status !== 1) return;
|
|
128
|
+
const confirmations = await event.getBlockNumber().then((bn) => provider.getBlockNumber().then((cur) => cur - bn));
|
|
129
|
+
if (confirmations < REQUIRED_CONFIRMATIONS) return;
|
|
130
|
+
const delta = await measureBalanceOfDelta(to, event.blockNumber);
|
|
131
|
+
creditDeposit(to, delta);
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### dex.token-decimals-mismatch
|
|
136
|
+
- **Title:** Token decimals mismatch (WBTC=8, USDC=6 vs assumed 18)
|
|
137
|
+
- **CWE:** CWE-682
|
|
138
|
+
- **Severity:** critical
|
|
139
|
+
- **VulnClass:** money-integrity
|
|
140
|
+
- **Invariant:** Every raw on-chain token amount is converted using that specific token's actual `decimals()` value, never a hardcoded assumption of 18.
|
|
141
|
+
- **Keywords:** decimals, WBTC, USDC, parseUnits, 10^18
|
|
142
|
+
|
|
143
|
+
**Unsafe:**
|
|
144
|
+
```ts
|
|
145
|
+
const humanAmount = Number(rawAmount) / 1e18; // wrong for USDC (6) and WBTC (8)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Safe:**
|
|
149
|
+
```ts
|
|
150
|
+
const decimals = await tokenContract.decimals();
|
|
151
|
+
const humanAmount = ethers.formatUnits(rawAmount, decimals);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### dex.float-token-amounts
|
|
155
|
+
- **Title:** Float/Number token amounts instead of BigInt
|
|
156
|
+
- **CWE:** CWE-681
|
|
157
|
+
- **Severity:** high
|
|
158
|
+
- **VulnClass:** money-integrity
|
|
159
|
+
- **Invariant:** On-chain token amounts are carried as BigInt (or an equivalent arbitrary-precision integer) end-to-end — never converted through a JS `Number`, which loses precision above 2^53.
|
|
160
|
+
- **Keywords:** BigInt, Number, float, wei, precision
|
|
161
|
+
|
|
162
|
+
**Unsafe:**
|
|
163
|
+
```ts
|
|
164
|
+
const amount = Number(rawWeiAmount); // loses precision for large wei values
|
|
165
|
+
await creditLedger(userId, amount);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Safe:**
|
|
169
|
+
```ts
|
|
170
|
+
const amount = BigInt(rawWeiAmount);
|
|
171
|
+
await creditLedger(userId, amount);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### dex.hot-wallet-key-in-env
|
|
175
|
+
- **Title:** Hot-wallet private key in env/config/repo
|
|
176
|
+
- **CWE:** CWE-798
|
|
177
|
+
- **Severity:** critical
|
|
178
|
+
- **VulnClass:** secret-handling
|
|
179
|
+
- **Invariant:** A private key or seed phrase that can move customer funds is never a literal string in source, config, or a plaintext environment variable — it is held in a non-extractable form (KMS/HSM) that only signs on request.
|
|
180
|
+
- **Keywords:** private key, PRIVATE_KEY, hot wallet, env, mnemonic, seed phrase
|
|
181
|
+
|
|
182
|
+
**Unsafe:**
|
|
183
|
+
```ts
|
|
184
|
+
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY); // key material in plaintext env
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Safe:**
|
|
188
|
+
```ts
|
|
189
|
+
const signer = new KmsSigner(process.env.KMS_KEY_ID); // key never leaves the KMS/HSM boundary
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### dex.kms-signer-no-authz-gate
|
|
193
|
+
- **Title:** KMS/HSM signer with no policy/authz gate in front
|
|
194
|
+
- **CWE:** CWE-862
|
|
195
|
+
- **Severity:** critical
|
|
196
|
+
- **VulnClass:** authn-authz
|
|
197
|
+
- **Invariant:** A call to the custody signer is only reachable after an explicit authorization policy (amount limits, destination allowlist, rate limit) approves the specific request — the signer is never directly callable by request handlers.
|
|
198
|
+
- **Keywords:** KMS, HSM, signer, policy gate, authorization, sign
|
|
199
|
+
|
|
200
|
+
**Unsafe:**
|
|
201
|
+
```ts
|
|
202
|
+
app.post("/withdraw", async (req, res) => {
|
|
203
|
+
const sig = await kmsSigner.sign(req.body.tx); // any authenticated caller can get anything signed
|
|
204
|
+
res.json({ sig });
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Safe:**
|
|
209
|
+
```ts
|
|
210
|
+
app.post("/withdraw", async (req, res) => {
|
|
211
|
+
await assertWithinPolicy(req.body.tx, { maxAmount: DAILY_LIMIT, allowlist: destinationAllowlist });
|
|
212
|
+
const sig = await kmsSigner.sign(req.body.tx);
|
|
213
|
+
res.json({ sig });
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### dex.siwe-replay
|
|
218
|
+
- **Title:** SIWE/EIP-4361 recover-but-skip-domain/nonce/chainId (replay)
|
|
219
|
+
- **CWE:** CWE-294
|
|
220
|
+
- **Severity:** critical
|
|
221
|
+
- **VulnClass:** crypto-weakness
|
|
222
|
+
- **Invariant:** A Sign-In-With-Ethereum message is only accepted after validating its domain, chain id, and a server-issued single-use nonce, and after checking the message has not expired — signature recovery alone is not authentication.
|
|
223
|
+
- **Keywords:** SIWE, EIP-4361, nonce, domain, chainId, verifyMessage, replay
|
|
224
|
+
|
|
225
|
+
**Unsafe:**
|
|
226
|
+
```ts
|
|
227
|
+
const recovered = ethers.verifyMessage(message, signature);
|
|
228
|
+
if (recovered === expectedAddress) req.session.userId = recovered; // domain/nonce/chainId never checked
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Safe:**
|
|
232
|
+
```ts
|
|
233
|
+
const siweMessage = new SiweMessage(message);
|
|
234
|
+
const { data } = await siweMessage.verify({ signature, domain, nonce: req.session.nonce });
|
|
235
|
+
if (data.chainId !== EXPECTED_CHAIN_ID || Date.parse(data.expirationTime) < Date.now()) throw new Error("invalid SIWE");
|
|
236
|
+
req.session.userId = data.address;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### dex.missing-price-circuit-breaker
|
|
240
|
+
- **Title:** Missing circuit breaker / sanity bound on price feed
|
|
241
|
+
- **Severity:** critical
|
|
242
|
+
- **VulnClass:** money-integrity
|
|
243
|
+
- **Invariant:** A price read from an external feed is rejected (and trading paused) when it deviates beyond a bounded threshold from the last accepted price or exceeds a staleness window, rather than being applied unconditionally.
|
|
244
|
+
- **Keywords:** circuit breaker, price feed, oracle, RPC, sanity, staleness
|
|
245
|
+
|
|
246
|
+
**Unsafe:**
|
|
247
|
+
```ts
|
|
248
|
+
const price = await priceFeed.getPrice(); // applied unconditionally, no deviation or staleness bound
|
|
249
|
+
applyPrice(price);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Safe:**
|
|
253
|
+
```ts
|
|
254
|
+
const price = await priceFeed.getPrice();
|
|
255
|
+
const deviation = Math.abs(price - lastAcceptedPrice) / lastAcceptedPrice;
|
|
256
|
+
if (deviation > MAX_DEVIATION || priceFeed.staleness() > MAX_STALENESS_MS) {
|
|
257
|
+
pauseTrading();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
applyPrice(price);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### dex.webhook-no-signature
|
|
264
|
+
- **Title:** Provider/chain webhook accepted without signature verification
|
|
265
|
+
- **CWE:** CWE-345
|
|
266
|
+
- **Severity:** critical
|
|
267
|
+
- **VulnClass:** authn-authz
|
|
268
|
+
- **Invariant:** A chain-indexer or provider webhook payload is only processed after its signature header is verified against the provider's known signing secret.
|
|
269
|
+
- **Keywords:** webhook, signature, HMAC, provider callback, verify
|
|
270
|
+
|
|
271
|
+
**Unsafe:**
|
|
272
|
+
```ts
|
|
273
|
+
app.post("/chain-webhook", (req, res) => { processDepositEvent(req.body); }); // unsigned body trusted directly
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Safe:**
|
|
277
|
+
```ts
|
|
278
|
+
app.post("/chain-webhook", (req, res) => {
|
|
279
|
+
const expected = crypto.createHmac("sha256", providerSecret).update(req.rawBody).digest("hex");
|
|
280
|
+
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-provider-signature"]))) {
|
|
281
|
+
return res.status(401).end();
|
|
282
|
+
}
|
|
283
|
+
processDepositEvent(req.body);
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### dex.unvalidated-withdrawal-amount
|
|
288
|
+
- **Title:** Negative/zero/oversized withdrawal amount not validated
|
|
289
|
+
- **CWE:** CWE-20
|
|
290
|
+
- **Severity:** critical
|
|
291
|
+
- **VulnClass:** money-integrity
|
|
292
|
+
- **Invariant:** A withdrawal amount is validated as a positive integer no greater than the account's available balance before any debit or signing occurs.
|
|
293
|
+
- **Keywords:** amount, negative, validation, balance check, withdrawal
|
|
294
|
+
|
|
295
|
+
**Unsafe:**
|
|
296
|
+
```ts
|
|
297
|
+
await executeWithdrawal(userId, req.body.amount, req.body.address); // amount never bounds-checked
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Safe:**
|
|
301
|
+
```ts
|
|
302
|
+
if (!Number.isInteger(req.body.amount) || req.body.amount <= 0 || req.body.amount > await getBalance(userId)) {
|
|
303
|
+
throw new Error("invalid withdrawal amount");
|
|
304
|
+
}
|
|
305
|
+
await executeWithdrawal(userId, req.body.amount, req.body.address);
|
|
306
|
+
```
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bober.security-generic
|
|
3
|
+
description: "Generic OWASP/CWE security signature library shared across every stack-specific security skill. Not a workflow skill -- a data file of discrete vulnerable/safe code signature blocks read by SecuritySignatureParser. Covers injection, SSRF, XSS, secret handling, missing authorization (BOLA), insecure deserialization, weak randomness, prototype pollution/SSTI, log injection, mass assignment, and weak crypto."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bober.security-generic — Generic Security Signature Library
|
|
7
|
+
|
|
8
|
+
This skill is a **signature-library** file, not a workflow skill. It is read (as raw
|
|
9
|
+
markdown text) by `SecuritySignatureParser.parse()`
|
|
10
|
+
(`src/orchestrator/security-knowledge/parser.ts`) and turned into typed
|
|
11
|
+
`SecuritySignature[]` records used by the security-audit agent team. Do not confuse this
|
|
12
|
+
with `bober.security-audit`, which is the audit *workflow* skill.
|
|
13
|
+
|
|
14
|
+
## Signature Block Format
|
|
15
|
+
|
|
16
|
+
Each signature is a level-3 heading (three `#` characters, a space, then the
|
|
17
|
+
`signatureId`) followed by labelled fields and two fenced code examples. This file and
|
|
18
|
+
`SecuritySignatureParser` are one executable spec — keep them in sync.
|
|
19
|
+
|
|
20
|
+
Required fields per block:
|
|
21
|
+
- The heading text itself is the `signatureId` (must be non-empty).
|
|
22
|
+
- `- **Title:** <human-readable title>`
|
|
23
|
+
- `- **CWE:** CWE-xx` (optional — omit the line entirely for `cwe: null`)
|
|
24
|
+
- `- **Severity:** critical|high|medium|low|info`
|
|
25
|
+
- `- **VulnClass:** <a VulnClass union member, verbatim — see security-audit-types.ts>`
|
|
26
|
+
- `- **Invariant:** <the safety invariant this signature protects>`
|
|
27
|
+
- `- **Keywords:** comma, separated, keywords`
|
|
28
|
+
|
|
29
|
+
Then two labelled fenced code examples:
|
|
30
|
+
- `**Unsafe:**` followed by a fenced `ts` block with the vulnerable example.
|
|
31
|
+
- `**Safe:**` followed by a fenced `ts` block with the fixed example.
|
|
32
|
+
|
|
33
|
+
A block missing `Title`, a valid `VulnClass`, a valid `Severity`, or a non-empty
|
|
34
|
+
unsafe/safe example is dropped by the parser — never a fatal error.
|
|
35
|
+
|
|
36
|
+
## Signatures
|
|
37
|
+
|
|
38
|
+
### sql-injection
|
|
39
|
+
- **Title:** SQL injection via string concatenation
|
|
40
|
+
- **CWE:** CWE-89
|
|
41
|
+
- **Severity:** critical
|
|
42
|
+
- **VulnClass:** injection
|
|
43
|
+
- **Invariant:** User-controlled values never reach a SQL statement as raw string content — always via a parameterized placeholder.
|
|
44
|
+
- **Keywords:** sql, query, concat, raw, template-literal
|
|
45
|
+
|
|
46
|
+
**Unsafe:**
|
|
47
|
+
```ts
|
|
48
|
+
const rows = await db.query(`SELECT * FROM users WHERE id = ${req.query.id}`);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Safe:**
|
|
52
|
+
```ts
|
|
53
|
+
const rows = await db.query("SELECT * FROM users WHERE id = $1", [req.query.id]);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### command-injection
|
|
57
|
+
- **Title:** OS command injection via shell interpolation
|
|
58
|
+
- **CWE:** CWE-78
|
|
59
|
+
- **Severity:** critical
|
|
60
|
+
- **VulnClass:** injection
|
|
61
|
+
- **Invariant:** User-controlled values never reach a shell string; child processes are spawned with an argv array and no shell.
|
|
62
|
+
- **Keywords:** exec, shell, spawn, child_process
|
|
63
|
+
|
|
64
|
+
**Unsafe:**
|
|
65
|
+
```ts
|
|
66
|
+
exec(`ping ${host}`, callback);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Safe:**
|
|
70
|
+
```ts
|
|
71
|
+
execFile("ping", [host], callback);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### path-traversal
|
|
75
|
+
- **Title:** Path traversal in file read
|
|
76
|
+
- **CWE:** CWE-22
|
|
77
|
+
- **Severity:** high
|
|
78
|
+
- **VulnClass:** path-traversal
|
|
79
|
+
- **Invariant:** A resolved file path must stay within its declared base directory before any fs call touches it.
|
|
80
|
+
- **Keywords:** fs, readFile, path.join, traversal, dotdot
|
|
81
|
+
|
|
82
|
+
**Unsafe:**
|
|
83
|
+
```ts
|
|
84
|
+
const data = await fs.readFile(path.join(baseDir, req.query.file));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Safe:**
|
|
88
|
+
```ts
|
|
89
|
+
const resolved = path.resolve(baseDir, req.query.file);
|
|
90
|
+
if (!resolved.startsWith(path.resolve(baseDir) + path.sep)) throw new Error("invalid path");
|
|
91
|
+
const data = await fs.readFile(resolved);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### ssrf-outbound-fetch
|
|
95
|
+
- **Title:** SSRF via unvalidated outbound URL
|
|
96
|
+
- **CWE:** CWE-918
|
|
97
|
+
- **Severity:** high
|
|
98
|
+
- **VulnClass:** ssrf
|
|
99
|
+
- **Invariant:** Outbound requests to a user-supplied URL are checked against an allowlist and blocked for RFC1918/loopback/link-local targets at the connection layer, not just by string inspection.
|
|
100
|
+
- **Keywords:** fetch, axios, ssrf, outbound, url
|
|
101
|
+
|
|
102
|
+
**Unsafe:**
|
|
103
|
+
```ts
|
|
104
|
+
const res = await fetch(req.body.url);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Safe:**
|
|
108
|
+
```ts
|
|
109
|
+
assertAllowedHost(new URL(req.body.url)); // blocks RFC1918, 169.254.169.254, loopback
|
|
110
|
+
const res = await fetch(req.body.url, { dispatcher: pinnedDnsDispatcher });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### reflected-xss
|
|
114
|
+
- **Title:** XSS via unescaped HTML sink
|
|
115
|
+
- **CWE:** CWE-79
|
|
116
|
+
- **Severity:** high
|
|
117
|
+
- **VulnClass:** xss
|
|
118
|
+
- **Invariant:** User-controlled content never reaches an HTML sink (innerHTML, dangerouslySetInnerHTML, v-html) without escaping or sanitization.
|
|
119
|
+
- **Keywords:** innerHTML, dangerouslySetInnerHTML, xss, sanitize
|
|
120
|
+
|
|
121
|
+
**Unsafe:**
|
|
122
|
+
```ts
|
|
123
|
+
el.innerHTML = userComment;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Safe:**
|
|
127
|
+
```ts
|
|
128
|
+
el.textContent = userComment;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### hardcoded-secret
|
|
132
|
+
- **Title:** Hard-coded credential or API key
|
|
133
|
+
- **CWE:** CWE-798
|
|
134
|
+
- **Severity:** critical
|
|
135
|
+
- **VulnClass:** secret-handling
|
|
136
|
+
- **Invariant:** Credentials and API keys are never literal source-code strings — they are loaded from environment variables or a secrets manager at runtime.
|
|
137
|
+
- **Keywords:** api-key, secret, credential, hardcoded
|
|
138
|
+
|
|
139
|
+
**Unsafe:**
|
|
140
|
+
```ts
|
|
141
|
+
const apiKey = "sk-live-abc123def456";
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Safe:**
|
|
145
|
+
```ts
|
|
146
|
+
const apiKey = mustGetEnv("API_KEY"); // fails fast if unset, never checked into source
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### missing-authz-bola
|
|
150
|
+
- **Title:** Missing ownership check on ID-to-DB lookup (BOLA)
|
|
151
|
+
- **CWE:** CWE-862
|
|
152
|
+
- **Severity:** high
|
|
153
|
+
- **VulnClass:** idor-bola
|
|
154
|
+
- **Invariant:** Every object fetched or mutated by a client-supplied id is filtered by the requesting session's ownership, not just its existence.
|
|
155
|
+
- **Keywords:** bola, idor, ownerid, authorization
|
|
156
|
+
|
|
157
|
+
**Unsafe:**
|
|
158
|
+
```ts
|
|
159
|
+
const order = await Order.findById(req.params.id);
|
|
160
|
+
return res.json(order);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Safe:**
|
|
164
|
+
```ts
|
|
165
|
+
const order = await Order.findOne({ _id: req.params.id, ownerId: req.session.userId });
|
|
166
|
+
if (!order) return res.status(404).end();
|
|
167
|
+
return res.json(order);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### insecure-deserialization
|
|
171
|
+
- **Title:** Unsafe deserialization of tainted data
|
|
172
|
+
- **CWE:** CWE-502
|
|
173
|
+
- **Severity:** critical
|
|
174
|
+
- **VulnClass:** deserialization
|
|
175
|
+
- **Invariant:** Tainted input is only ever parsed with a schema-validated JSON.parse — never passed to a deserializer, vm context, or dynamic code evaluator.
|
|
176
|
+
- **Keywords:** deserialize, unserialize, vm, new-function, eval
|
|
177
|
+
|
|
178
|
+
**Unsafe:**
|
|
179
|
+
```ts
|
|
180
|
+
const obj = vm.runInNewContext(req.body.payload);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Safe:**
|
|
184
|
+
```ts
|
|
185
|
+
const obj = payloadSchema.parse(JSON.parse(req.body.payload));
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### weak-randomness
|
|
189
|
+
- **Title:** Predictable RNG for a security-sensitive value
|
|
190
|
+
- **CWE:** CWE-338
|
|
191
|
+
- **Severity:** high
|
|
192
|
+
- **VulnClass:** insecure-randomness
|
|
193
|
+
- **Invariant:** Tokens, session ids, and other security-sensitive values are generated from a CSPRNG, never Math.random().
|
|
194
|
+
- **Keywords:** math.random, token, session-id, csprng
|
|
195
|
+
|
|
196
|
+
**Unsafe:**
|
|
197
|
+
```ts
|
|
198
|
+
const token = Math.random().toString(36).slice(2);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Safe:**
|
|
202
|
+
```ts
|
|
203
|
+
const token = crypto.randomBytes(32).toString("hex");
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### prototype-pollution
|
|
207
|
+
- **Title:** Prototype pollution via recursive merge
|
|
208
|
+
- **CWE:** CWE-1321
|
|
209
|
+
- **Severity:** high
|
|
210
|
+
- **VulnClass:** input-validation
|
|
211
|
+
- **Invariant:** A recursive merge/clone of user-controlled objects rejects __proto__/constructor/prototype keys before assigning any property.
|
|
212
|
+
- **Keywords:** prototype-pollution, merge, deep-merge, __proto__
|
|
213
|
+
|
|
214
|
+
**Unsafe:**
|
|
215
|
+
```ts
|
|
216
|
+
deepMerge(config, req.body);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Safe:**
|
|
220
|
+
```ts
|
|
221
|
+
deepMerge(config, req.body, { blockedKeys: ["__proto__", "constructor", "prototype"] });
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### ssti
|
|
225
|
+
- **Title:** Server-side template injection
|
|
226
|
+
- **CWE:** CWE-94
|
|
227
|
+
- **Severity:** critical
|
|
228
|
+
- **VulnClass:** injection
|
|
229
|
+
- **Invariant:** User-controlled input is passed to a template as data, never compiled as template source.
|
|
230
|
+
- **Keywords:** ssti, template, eval, render
|
|
231
|
+
|
|
232
|
+
**Unsafe:**
|
|
233
|
+
```ts
|
|
234
|
+
const html = ejs.render(userSuppliedTemplate, data);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Safe:**
|
|
238
|
+
```ts
|
|
239
|
+
const html = precompiledTemplate(data); // template source is fixed, never user-supplied
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### log-injection-crlf
|
|
243
|
+
- **Title:** CRLF / log injection
|
|
244
|
+
- **CWE:** CWE-117
|
|
245
|
+
- **Severity:** medium
|
|
246
|
+
- **VulnClass:** audit-logging
|
|
247
|
+
- **Invariant:** User-controlled values written to a log line have CR/LF stripped or encoded before concatenation, so a single log entry cannot be forged into multiple.
|
|
248
|
+
- **Keywords:** crlf, log-injection, logger, newline
|
|
249
|
+
|
|
250
|
+
**Unsafe:**
|
|
251
|
+
```ts
|
|
252
|
+
logger.info("login attempt user=" + req.body.username);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Safe:**
|
|
256
|
+
```ts
|
|
257
|
+
logger.info("login attempt", { user: req.body.username.replace(/[\r\n]/g, "") });
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### mass-assignment
|
|
261
|
+
- **Title:** Mass assignment / bulk property assignment (BOPLA)
|
|
262
|
+
- **CWE:** CWE-915
|
|
263
|
+
- **Severity:** high
|
|
264
|
+
- **VulnClass:** input-validation
|
|
265
|
+
- **Invariant:** A model update accepts only an explicit allowlist of client-writable fields, never the raw request body.
|
|
266
|
+
- **Keywords:** mass-assignment, bopla, allowlist, update
|
|
267
|
+
|
|
268
|
+
**Unsafe:**
|
|
269
|
+
```ts
|
|
270
|
+
await User.update(req.body, { where: { id: req.session.userId } });
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Safe:**
|
|
274
|
+
```ts
|
|
275
|
+
const { name, email } = req.body;
|
|
276
|
+
await User.update({ name, email }, { where: { id: req.session.userId } });
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### weak-crypto-hash
|
|
280
|
+
- **Title:** Weak hash for password or integrity check
|
|
281
|
+
- **CWE:** CWE-327
|
|
282
|
+
- **Severity:** medium
|
|
283
|
+
- **VulnClass:** crypto-weakness
|
|
284
|
+
- **Invariant:** Passwords are hashed with a slow, salted algorithm (argon2/bcrypt); integrity checks use a modern digest (SHA-256+), never md5/sha1.
|
|
285
|
+
- **Keywords:** md5, sha1, password-hash, crypto-weakness
|
|
286
|
+
|
|
287
|
+
**Unsafe:**
|
|
288
|
+
```ts
|
|
289
|
+
const hash = crypto.createHash("md5").update(password).digest("hex");
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Safe:**
|
|
293
|
+
```ts
|
|
294
|
+
const hash = await argon2.hash(password);
|
|
295
|
+
```
|