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,290 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bober.security-igaming
|
|
3
|
+
description: "iGaming/betting backend security signature library. Not a workflow skill -- a data file of discrete vulnerable/safe code signature blocks read by SecuritySignatureParser. Covers TOCTOU balance double-spend, non-atomic settlement/idempotency, client-supplied odds trust, negative/zero stake, float money, missing webhook HMAC, seamless-wallet rollback abuse, non-CSPRNG outcomes, client-side outcome determination, client-side-only limits, bonus/wagering abuse, and settlement replay."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bober.security-igaming — iGaming/Betting 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.
|
|
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
|
+
### igaming.toctou-balance-double-spend
|
|
39
|
+
- **Title:** TOCTOU balance double-spend (read-check-write, no lock)
|
|
40
|
+
- **CWE:** CWE-362
|
|
41
|
+
- **Severity:** critical
|
|
42
|
+
- **VulnClass:** race-condition
|
|
43
|
+
- **Invariant:** A balance debit is a single atomic conditional write — the check and the write execute as one statement, never a separate read followed by a later write.
|
|
44
|
+
- **Keywords:** balance, FOR UPDATE, TOCTOU, double-spend, atomic
|
|
45
|
+
|
|
46
|
+
**Unsafe:**
|
|
47
|
+
```ts
|
|
48
|
+
const account = await db.query("SELECT balance FROM accounts WHERE id = $1", [id]);
|
|
49
|
+
if (account.balance >= amount) {
|
|
50
|
+
await db.query("UPDATE accounts SET balance = balance - $1 WHERE id = $2", [amount, id]);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Safe:**
|
|
55
|
+
```ts
|
|
56
|
+
const result = await db.query(
|
|
57
|
+
"UPDATE accounts 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
|
+
### igaming.non-atomic-idempotency
|
|
64
|
+
- **Title:** Missing/non-atomic idempotency key on deposit/settlement
|
|
65
|
+
- **CWE:** CWE-362
|
|
66
|
+
- **Severity:** critical
|
|
67
|
+
- **VulnClass:** race-condition
|
|
68
|
+
- **Invariant:** A deposit or settlement request is applied at most once per idempotency key, enforced by a unique constraint at the database layer, not by an application-level check-then-insert.
|
|
69
|
+
- **Keywords:** idempotency, idempotency-key, settlement, unique, upsert
|
|
70
|
+
|
|
71
|
+
**Unsafe:**
|
|
72
|
+
```ts
|
|
73
|
+
const existing = await db.query("SELECT id FROM settlements WHERE key = $1", [idempotencyKey]);
|
|
74
|
+
if (!existing) await db.query("INSERT INTO settlements (key, amount) VALUES ($1, $2)", [idempotencyKey, amount]);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Safe:**
|
|
78
|
+
```ts
|
|
79
|
+
await db.query(
|
|
80
|
+
"INSERT INTO settlements (key, amount) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING", // key has a UNIQUE constraint
|
|
81
|
+
[idempotencyKey, amount],
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### igaming.client-supplied-odds
|
|
86
|
+
- **Title:** Trusting client-supplied odds/price at bet acceptance
|
|
87
|
+
- **CWE:** CWE-602
|
|
88
|
+
- **Severity:** critical
|
|
89
|
+
- **VulnClass:** money-integrity
|
|
90
|
+
- **Invariant:** The payout for an accepted bet is computed from the server's current price for the selection id at acceptance time, never from an odds value the client submitted in the request body.
|
|
91
|
+
- **Keywords:** odds, price, selectionId, payout, re-resolve
|
|
92
|
+
|
|
93
|
+
**Unsafe:**
|
|
94
|
+
```ts
|
|
95
|
+
const payout = req.body.stake * req.body.odds; // client controls the multiplier directly
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Safe:**
|
|
99
|
+
```ts
|
|
100
|
+
const currentOdds = await priceService.getOdds(req.body.selectionId); // server-resolved at acceptance
|
|
101
|
+
const payout = req.body.stake * currentOdds;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### igaming.negative-zero-stake
|
|
105
|
+
- **Title:** Negative/zero stake inverts debit to credit
|
|
106
|
+
- **CWE:** CWE-20
|
|
107
|
+
- **Severity:** critical
|
|
108
|
+
- **VulnClass:** money-integrity
|
|
109
|
+
- **Invariant:** A stake amount is validated as a positive integer above the platform's minimum before any debit occurs — a negative or zero value is rejected, never processed.
|
|
110
|
+
- **Keywords:** stake, negative, amount, validation, <= 0
|
|
111
|
+
|
|
112
|
+
**Unsafe:**
|
|
113
|
+
```ts
|
|
114
|
+
await debit(userId, req.body.stake); // stake = -1000 credits the account instead of debiting it
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Safe:**
|
|
118
|
+
```ts
|
|
119
|
+
if (!Number.isInteger(req.body.stake) || req.body.stake <= 0) throw new Error("invalid stake");
|
|
120
|
+
await debit(userId, req.body.stake);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### igaming.float-money
|
|
124
|
+
- **Title:** Float money instead of integer minor units / Decimal
|
|
125
|
+
- **CWE:** CWE-681
|
|
126
|
+
- **Severity:** high
|
|
127
|
+
- **VulnClass:** money-integrity
|
|
128
|
+
- **Invariant:** Monetary amounts are represented as integer minor units (cents) or an arbitrary-precision Decimal type end-to-end — never IEEE-754 floats, which drift under repeated arithmetic.
|
|
129
|
+
- **Keywords:** float, Number, minor units, Decimal, rounding, cents
|
|
130
|
+
|
|
131
|
+
**Unsafe:**
|
|
132
|
+
```ts
|
|
133
|
+
balance += 0.1; // repeated float addition drifts from the true balance over many operations
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Safe:**
|
|
137
|
+
```ts
|
|
138
|
+
balanceCents += 10; // integer minor units, no drift
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### igaming.missing-webhook-hmac
|
|
142
|
+
- **Title:** Missing/incorrect provider webhook HMAC + timestamp verification
|
|
143
|
+
- **CWE:** CWE-345
|
|
144
|
+
- **Severity:** critical
|
|
145
|
+
- **VulnClass:** authn-authz
|
|
146
|
+
- **Invariant:** A webhook payload is only processed after its HMAC signature over the raw request body is verified with a constant-time comparison and its timestamp is checked against replay drift.
|
|
147
|
+
- **Keywords:** webhook, HMAC, timingSafeEqual, raw-body, timestamp
|
|
148
|
+
|
|
149
|
+
**Unsafe:**
|
|
150
|
+
```ts
|
|
151
|
+
app.post("/webhook", (req, res) => { applySettlement(req.body); }); // body trusted, unsigned
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Safe:**
|
|
155
|
+
```ts
|
|
156
|
+
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
|
|
157
|
+
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-signature"])) ||
|
|
158
|
+
Date.now() - Number(req.headers["x-timestamp"]) > MAX_SKEW_MS) {
|
|
159
|
+
return res.status(401).end();
|
|
160
|
+
}
|
|
161
|
+
applySettlement(req.body);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### igaming.seamless-wallet-orphan-rollback
|
|
165
|
+
- **Title:** Orphan / replayed seamless-wallet rollback credit
|
|
166
|
+
- **Severity:** critical
|
|
167
|
+
- **VulnClass:** money-integrity
|
|
168
|
+
- **Invariant:** A rollback credit is only applied when it matches an existing debit transaction by a composite provider/round/transaction key, and each rollback key is processed at most once.
|
|
169
|
+
- **Keywords:** seamless wallet, rollback, orphan, roundId, txId, dedup
|
|
170
|
+
|
|
171
|
+
**Unsafe:**
|
|
172
|
+
```ts
|
|
173
|
+
await credit(userId, req.body.amount); // rollback credited with no matching prior debit, replayable
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Safe:**
|
|
177
|
+
```ts
|
|
178
|
+
const debit = await findDebit(providerId, req.body.roundId, req.body.txId);
|
|
179
|
+
if (!debit) throw new Error("no matching debit for rollback");
|
|
180
|
+
await db.query(
|
|
181
|
+
"INSERT INTO rollbacks (provider_id, round_id, tx_id, tx_type) VALUES ($1, $2, $3, 'rollback') ON CONFLICT DO NOTHING RETURNING id",
|
|
182
|
+
[providerId, req.body.roundId, req.body.txId],
|
|
183
|
+
);
|
|
184
|
+
await credit(userId, debit.amount);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### igaming.non-csprng-outcome
|
|
188
|
+
- **Title:** Math.random() for game outcome (fails GLI-19 certification)
|
|
189
|
+
- **CWE:** CWE-338
|
|
190
|
+
- **Severity:** critical
|
|
191
|
+
- **VulnClass:** insecure-randomness
|
|
192
|
+
- **Invariant:** A game outcome that determines a payout is generated from a certified CSPRNG seeded with at least 256 bits of entropy, never `Math.random()`.
|
|
193
|
+
- **Keywords:** Math.random, RNG, CSPRNG, outcome, seed, GLI-19
|
|
194
|
+
|
|
195
|
+
**Unsafe:**
|
|
196
|
+
```ts
|
|
197
|
+
const outcome = Math.floor(Math.random() * reelSymbols.length); // predictable, not certifiable
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Safe:**
|
|
201
|
+
```ts
|
|
202
|
+
const outcome = certifiedRng.nextInt(reelSymbols.length); // certified CSPRNG, seeded >= 256 bits
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### igaming.client-side-outcome
|
|
206
|
+
- **Title:** Client-determined outcome trusted by server
|
|
207
|
+
- **CWE:** CWE-602
|
|
208
|
+
- **Severity:** critical
|
|
209
|
+
- **VulnClass:** authn-authz
|
|
210
|
+
- **Invariant:** The server independently computes the authoritative round outcome; a client-submitted result value is never accepted as-is for settlement.
|
|
211
|
+
- **Keywords:** client-side, outcome, server-authoritative, trust boundary
|
|
212
|
+
|
|
213
|
+
**Unsafe:**
|
|
214
|
+
```ts
|
|
215
|
+
await settleRound(req.body.result); // client tells the server what it won
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Safe:**
|
|
219
|
+
```ts
|
|
220
|
+
const result = await computeAuthoritativeOutcome(roundId); // server-computed, ignores client claims
|
|
221
|
+
await settleRound(result);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### igaming.limits-client-only
|
|
225
|
+
- **Title:** Deposit-limit / self-exclusion enforced client-side only
|
|
226
|
+
- **CWE:** CWE-602
|
|
227
|
+
- **Severity:** high
|
|
228
|
+
- **VulnClass:** authn-authz
|
|
229
|
+
- **Invariant:** Deposit limits and self-exclusion status are enforced by a server-side check on every deposit/bet request, not merely by disabling controls in the UI.
|
|
230
|
+
- **Keywords:** deposit limit, self-exclusion, KYC, client-side, GAMSTOP
|
|
231
|
+
|
|
232
|
+
**Unsafe:**
|
|
233
|
+
```ts
|
|
234
|
+
// UI disables the deposit button once the limit is reached; the API accepts any amount
|
|
235
|
+
app.post("/deposit", (req, res) => { processDeposit(req.body.amount); });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Safe:**
|
|
239
|
+
```ts
|
|
240
|
+
app.post("/deposit", async (req, res) => {
|
|
241
|
+
await assertWithinDepositLimit(req.session.userId, req.body.amount); // server-enforced, throws if exceeded
|
|
242
|
+
await assertNotSelfExcluded(req.session.userId);
|
|
243
|
+
processDeposit(req.body.amount);
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### igaming.bonus-wagering-abuse
|
|
248
|
+
- **Title:** Bonus / wagering-requirement bypass (multi-account, self-referral)
|
|
249
|
+
- **CWE:** CWE-841
|
|
250
|
+
- **Severity:** high
|
|
251
|
+
- **VulnClass:** money-integrity
|
|
252
|
+
- **Invariant:** Bonus funds are withdrawable only after the wagering requirement is met on qualifying real-money play, and bonus eligibility is checked against multi-account/self-referral signals, not per-account state alone.
|
|
253
|
+
- **Keywords:** bonus, wagering requirement, multi-account, self-referral
|
|
254
|
+
|
|
255
|
+
**Unsafe:**
|
|
256
|
+
```ts
|
|
257
|
+
await withdraw(userId, bonusBalance); // no check that wagering requirement was met
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Safe:**
|
|
261
|
+
```ts
|
|
262
|
+
const progress = await getWageringProgress(userId);
|
|
263
|
+
if (progress.wagered < progress.required) throw new Error("wagering requirement not met");
|
|
264
|
+
if (await isSelfReferralOrMultiAccount(userId)) throw new Error("bonus ineligible");
|
|
265
|
+
await withdraw(userId, bonusBalance);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### igaming.settlement-replay
|
|
269
|
+
- **Title:** Replayed settlement/payout webhook without provider-event dedup
|
|
270
|
+
- **Severity:** critical
|
|
271
|
+
- **VulnClass:** money-integrity
|
|
272
|
+
- **Invariant:** Each provider settlement event is applied at most once, keyed by the provider's unique event id enforced with a database uniqueness constraint.
|
|
273
|
+
- **Keywords:** settlement, replay, dedup, provider-event, unique
|
|
274
|
+
|
|
275
|
+
**Unsafe:**
|
|
276
|
+
```ts
|
|
277
|
+
app.post("/settlement", async (req, res) => { await applyPayout(req.body); }); // same event processed twice on retry
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Safe:**
|
|
281
|
+
```ts
|
|
282
|
+
app.post("/settlement", async (req, res) => {
|
|
283
|
+
const inserted = await db.query(
|
|
284
|
+
"INSERT INTO settlement_events (event_id) VALUES ($1) ON CONFLICT DO NOTHING RETURNING event_id",
|
|
285
|
+
[req.body.eventId],
|
|
286
|
+
);
|
|
287
|
+
if (inserted.rowCount === 0) return res.status(200).end(); // already processed
|
|
288
|
+
await applyPayout(req.body);
|
|
289
|
+
});
|
|
290
|
+
```
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bober.security-node
|
|
3
|
+
description: "Node/Express backend security signature library. Not a workflow skill -- a data file of discrete vulnerable/safe code signature blocks read by SecuritySignatureParser. Covers SQL/NoSQL injection, ORM raw escape hatches, command injection, path traversal, SSRF, BOLA, mass assignment (BOPLA), BFLA, insecure deserialization, vm-as-sandbox misuse, hardcoded/logged secrets, and JWT/session weaknesses."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bober.security-node — Node/Express 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.
|
|
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
|
+
### node.sql-injection
|
|
39
|
+
- **Title:** SQL injection via string concatenation / template literal
|
|
40
|
+
- **CWE:** CWE-89
|
|
41
|
+
- **Severity:** critical
|
|
42
|
+
- **VulnClass:** injection
|
|
43
|
+
- **Invariant:** A SQL query built from request-derived data always uses parameterized placeholders — the query text is never built by concatenating or interpolating untrusted input.
|
|
44
|
+
- **Keywords:** sql, query, concat, template-literal, parameterized
|
|
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
|
+
### node.orm-raw-escape-hatch
|
|
57
|
+
- **Title:** ORM raw escape hatch (.raw/.literal/$queryRawUnsafe/$where) with interpolated input
|
|
58
|
+
- **CWE:** CWE-89
|
|
59
|
+
- **Severity:** critical
|
|
60
|
+
- **VulnClass:** injection
|
|
61
|
+
- **Invariant:** When an ORM's raw-SQL escape hatch is used, the query text is a static tagged template or the ORM's own bound-parameter form — request-derived values are never string-concatenated into it.
|
|
62
|
+
- **Keywords:** ORM, raw, $queryRawUnsafe, literal, $where, prisma, knex
|
|
63
|
+
|
|
64
|
+
**Unsafe:**
|
|
65
|
+
```ts
|
|
66
|
+
await prisma.$queryRawUnsafe(`SELECT * FROM users WHERE name = '${req.query.name}'`);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Safe:**
|
|
70
|
+
```ts
|
|
71
|
+
await prisma.$queryRaw`SELECT * FROM users WHERE name = ${req.query.name}`;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### node.command-injection
|
|
75
|
+
- **Title:** OS command injection via exec / shell:true
|
|
76
|
+
- **CWE:** CWE-78
|
|
77
|
+
- **Severity:** critical
|
|
78
|
+
- **VulnClass:** injection
|
|
79
|
+
- **Invariant:** A subprocess is spawned with an explicit binary and an argument array, never through a shell, so request-derived data cannot be interpreted as shell syntax.
|
|
80
|
+
- **Keywords:** exec, child_process, shell, execFile, command
|
|
81
|
+
|
|
82
|
+
**Unsafe:**
|
|
83
|
+
```ts
|
|
84
|
+
exec(`convert ${req.body.file} out.png`);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Safe:**
|
|
88
|
+
```ts
|
|
89
|
+
execFile("convert", [req.body.file, "out.png"]);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### node.path-traversal
|
|
93
|
+
- **Title:** Path traversal via path.join/resolve with no boundary assertion
|
|
94
|
+
- **CWE:** CWE-22
|
|
95
|
+
- **Severity:** high
|
|
96
|
+
- **VulnClass:** path-traversal
|
|
97
|
+
- **Invariant:** A file path built from a request-supplied name is resolved and asserted to remain inside the intended base directory before any filesystem access.
|
|
98
|
+
- **Keywords:** path.join, path.resolve, traversal, ../, boundary
|
|
99
|
+
|
|
100
|
+
**Unsafe:**
|
|
101
|
+
```ts
|
|
102
|
+
const filePath = path.join(baseDir, req.params.name);
|
|
103
|
+
await fs.readFile(filePath);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Safe:**
|
|
107
|
+
```ts
|
|
108
|
+
const filePath = path.resolve(baseDir, req.params.name);
|
|
109
|
+
if (!filePath.startsWith(path.resolve(baseDir) + path.sep)) throw new Error("invalid path");
|
|
110
|
+
await fs.readFile(filePath);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### node.ssrf-outbound-fetch
|
|
114
|
+
- **Title:** SSRF via unvalidated outbound fetch/axios (cloud metadata / RFC1918)
|
|
115
|
+
- **CWE:** CWE-918
|
|
116
|
+
- **Severity:** critical
|
|
117
|
+
- **VulnClass:** ssrf
|
|
118
|
+
- **Invariant:** An outbound HTTP request to a user-supplied URL is only made after the resolved host is checked against an allowlist and internal/link-local address ranges are blocked at connect time.
|
|
119
|
+
- **Keywords:** ssrf, fetch, axios, 169.254.169.254, RFC1918, metadata
|
|
120
|
+
|
|
121
|
+
**Unsafe:**
|
|
122
|
+
```ts
|
|
123
|
+
const res = await fetch(req.body.url);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Safe:**
|
|
127
|
+
```ts
|
|
128
|
+
assertAllowedOutboundHost(req.body.url); // rejects RFC1918 / 169.254.169.254 / non-allowlisted hosts
|
|
129
|
+
const res = await fetch(req.body.url);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### node.bola-missing-ownership
|
|
133
|
+
- **Title:** BOLA: object id looked up with no owner predicate
|
|
134
|
+
- **CWE:** CWE-639
|
|
135
|
+
- **Severity:** critical
|
|
136
|
+
- **VulnClass:** idor-bola
|
|
137
|
+
- **Invariant:** A lookup by object id is always scoped to the requesting session's owner id in the query itself — the object is never fetched by id alone and checked afterward.
|
|
138
|
+
- **Keywords:** BOLA, IDOR, ownerId, object id, authorization
|
|
139
|
+
|
|
140
|
+
**Unsafe:**
|
|
141
|
+
```ts
|
|
142
|
+
const doc = await db.query("SELECT * FROM documents WHERE id = $1", [req.params.id]);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Safe:**
|
|
146
|
+
```ts
|
|
147
|
+
const doc = await db.query(
|
|
148
|
+
"SELECT * FROM documents WHERE id = $1 AND owner_id = $2",
|
|
149
|
+
[req.params.id, req.session.userId],
|
|
150
|
+
);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### node.mass-assignment-bopla
|
|
154
|
+
- **Title:** BOPLA / mass assignment via Model.update(req.body)
|
|
155
|
+
- **CWE:** CWE-915
|
|
156
|
+
- **Severity:** critical
|
|
157
|
+
- **VulnClass:** idor-bola
|
|
158
|
+
- **Invariant:** An update from request data only writes an explicit allowlist of updatable fields — the raw request body is never passed directly to a model update call.
|
|
159
|
+
- **Keywords:** mass assignment, BOPLA, req.body, allowlist, isAdmin
|
|
160
|
+
|
|
161
|
+
**Unsafe:**
|
|
162
|
+
```ts
|
|
163
|
+
await User.update(req.body, { where: { id: req.session.userId } });
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Safe:**
|
|
167
|
+
```ts
|
|
168
|
+
const { name, email } = req.body; // explicit allowlist, excludes isAdmin/role/etc.
|
|
169
|
+
await User.update({ name, email }, { where: { id: req.session.userId } });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### node.bfla-admin-no-role-gate
|
|
173
|
+
- **Title:** BFLA: admin/privileged route with no role gate
|
|
174
|
+
- **CWE:** CWE-862
|
|
175
|
+
- **Severity:** critical
|
|
176
|
+
- **VulnClass:** authn-authz
|
|
177
|
+
- **Invariant:** A route performing a privileged function is always guarded by a role check that runs before the handler executes — the function-level authorization is never assumed from the route existing under an "/admin" prefix.
|
|
178
|
+
- **Keywords:** BFLA, admin route, role, requireRole, authorization
|
|
179
|
+
|
|
180
|
+
**Unsafe:**
|
|
181
|
+
```ts
|
|
182
|
+
app.post("/admin/users/:id/delete", async (req, res) => { await deleteUser(req.params.id); });
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Safe:**
|
|
186
|
+
```ts
|
|
187
|
+
app.post("/admin/users/:id/delete", requireRole("admin"), async (req, res) => {
|
|
188
|
+
await deleteUser(req.params.id);
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### node.insecure-deserialization
|
|
193
|
+
- **Title:** Insecure deserialization of untrusted input
|
|
194
|
+
- **CWE:** CWE-502
|
|
195
|
+
- **Severity:** critical
|
|
196
|
+
- **VulnClass:** deserialization
|
|
197
|
+
- **Invariant:** Untrusted input is only decoded with a format-safe parser (plain JSON, or a YAML loader restricted to a safe schema) — a deserializer capable of reconstructing arbitrary objects or executing code is never applied to request data.
|
|
198
|
+
- **Keywords:** deserialization, unserialize, yaml.load, node-serialize, gadget
|
|
199
|
+
|
|
200
|
+
**Unsafe:**
|
|
201
|
+
```ts
|
|
202
|
+
const obj = serialize.unserialize(req.body.payload); // node-serialize: gadget chain -> RCE
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Safe:**
|
|
206
|
+
```ts
|
|
207
|
+
const obj = JSON.parse(req.body.payload); // or yaml.load(input, { schema: JSON_SCHEMA })
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### node.vm-not-a-sandbox
|
|
211
|
+
- **Title:** vm/new Function/eval on tainted input (vm is not a sandbox)
|
|
212
|
+
- **CWE:** CWE-94
|
|
213
|
+
- **Severity:** critical
|
|
214
|
+
- **VulnClass:** injection
|
|
215
|
+
- **Invariant:** Request-derived strings are never passed to eval, new Function, or Node's built-in vm module as executable code — vm does not provide a security boundary against untrusted code.
|
|
216
|
+
- **Keywords:** vm, vm2, new Function, eval, runInNewContext, sandbox
|
|
217
|
+
|
|
218
|
+
**Unsafe:**
|
|
219
|
+
```ts
|
|
220
|
+
const result = new vm.Script(req.body.code).runInNewContext({});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Safe:**
|
|
224
|
+
```ts
|
|
225
|
+
// never eval untrusted input; use a real out-of-process sandbox (worker with no
|
|
226
|
+
// filesystem/network access) plus an explicit allowlist of permitted operations
|
|
227
|
+
const result = await runInIsolatedWorker(req.body.code, { allowlist: SAFE_OPS });
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### node.secrets-hardcoded-logged
|
|
231
|
+
- **Title:** Hard-coded or logged secrets
|
|
232
|
+
- **CWE:** CWE-798
|
|
233
|
+
- **Severity:** high
|
|
234
|
+
- **VulnClass:** secret-handling
|
|
235
|
+
- **Invariant:** Credentials and API keys are read from environment variables or a secret manager at runtime and are never embedded as string literals or written to application logs.
|
|
236
|
+
- **Keywords:** secret, API key, hardcoded, logger, redact, .env
|
|
237
|
+
|
|
238
|
+
**Unsafe:**
|
|
239
|
+
```ts
|
|
240
|
+
const stripeKey = "sk_live_51H8x...";
|
|
241
|
+
logger.info("charging user", { apiKey: stripeKey, amount });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Safe:**
|
|
245
|
+
```ts
|
|
246
|
+
const stripeKey = process.env.STRIPE_SECRET_KEY;
|
|
247
|
+
logger.info("charging user", { amount }); // secret never included in log fields
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### node.jwt-alg-none
|
|
251
|
+
- **Title:** JWT alg:none / weak secret / session fixation
|
|
252
|
+
- **CWE:** CWE-347
|
|
253
|
+
- **Severity:** critical
|
|
254
|
+
- **VulnClass:** authn-authz
|
|
255
|
+
- **Invariant:** A JWT is verified with a pinned strong algorithm and a high-entropy secret or key, and a session identifier is rotated on every successful login — a token is never accepted with an attacker-chosen algorithm or a weak shared secret.
|
|
256
|
+
- **Keywords:** JWT, alg none, algorithms, session fixation, verify
|
|
257
|
+
|
|
258
|
+
**Unsafe:**
|
|
259
|
+
```ts
|
|
260
|
+
const payload = jwt.verify(token, secret, { algorithms: ["none", "HS256"] });
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Safe:**
|
|
264
|
+
```ts
|
|
265
|
+
const payload = jwt.verify(token, strongSecret, { algorithms: ["HS256"] });
|
|
266
|
+
req.session.regenerate(() => { req.session.userId = payload.sub; }); // rotate on login
|
|
267
|
+
```
|