@slicedearth/whoisleuth-cli 2.3.0 → 2.5.1
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/NOTICE +8 -2
- package/README.md +19 -15
- package/bin/whoisleuth.mjs +8 -1
- package/cli/archive-content-digest.mjs +14 -0
- package/cli/archive-inspect.mjs +20 -53
- package/cli/argument-values.mjs +55 -0
- package/cli/arguments.mjs +24 -408
- package/cli/artifact-validation/case-response.mjs +65 -44
- package/cli/artifact-validation/investigation-capsule.mjs +52 -31
- package/cli/artifact-validation/lookup-evidence.mjs +15 -9
- package/cli/artifact-validation/signed-review.mjs +136 -68
- package/cli/artifact-validation/structure-primitives.mjs +1 -105
- package/cli/artifact-verify.mjs +92 -24
- package/cli/assurance-arguments.mjs +56 -0
- package/cli/assurance-command-definitions.mjs +179 -0
- package/cli/assurance-command-runner.mjs +40 -5
- package/cli/bagit-folder.mjs +57 -0
- package/cli/bagit-review.mjs +23 -0
- package/cli/bounded-json.mjs +1 -1
- package/cli/bulk-checkpoint.mjs +1 -1
- package/cli/bulk-command-runner.mjs +4 -2
- package/cli/bulk-output.mjs +29 -3
- package/cli/bulk.mjs +2 -3
- package/cli/case-command.mjs +212 -0
- package/cli/case-pack.mjs +50 -32
- package/cli/ci-report.mjs +6 -3
- package/cli/collection-arguments.mjs +123 -0
- package/cli/collection-command-definitions.mjs +330 -0
- package/cli/collection-preflight.mjs +8 -1
- package/cli/command-argument-grammar.mjs +8 -206
- package/cli/command-definition.mjs +329 -0
- package/cli/command-reference.mjs +94 -1357
- package/cli/command-seeds.mjs +18 -0
- package/cli/compare.mjs +1 -1
- package/cli/completion.mjs +298 -79
- package/cli/config-profile.mjs +8 -6
- package/cli/ct-event-intake.mjs +16 -16
- package/cli/discover.mjs +5 -4
- package/cli/discovery-observation-snapshot.mjs +46 -18
- package/cli/discovery-scan-command-runner.mjs +5 -3
- package/cli/discovery-scan.mjs +7 -4
- package/cli/discovery-snapshot.mjs +2 -2
- package/cli/discovery-workflow.mjs +5 -5
- package/cli/domain-control-monitor.mjs +50 -20
- package/cli/domain-control-observations.mjs +151 -103
- package/cli/errors.mjs +37 -6
- package/cli/evidence-arguments.mjs +46 -0
- package/cli/evidence-command-definitions.mjs +69 -0
- package/cli/evidence-command-runner.mjs +18 -8
- package/cli/evidence-signing.mjs +5 -4
- package/cli/external-observation-mapping.mjs +9 -10
- package/cli/formatters/terminal-command-formats.mjs +6 -0
- package/cli/formatters/terminal-lookup.mjs +24 -46
- package/cli/formatters/terminal-shared.mjs +5 -3
- package/cli/formatters/terminal-technology.mjs +114 -0
- package/cli/history-arguments.mjs +39 -0
- package/cli/history-command-definitions.mjs +88 -0
- package/cli/indicator-set-command.mjs +33 -0
- package/cli/inline-command-families.mjs +6 -46
- package/cli/inline-command-runner.mjs +4 -31
- package/cli/input.mjs +2 -2
- package/cli/intake-command.mjs +107 -0
- package/cli/interactive-launcher.mjs +2 -160
- package/cli/interchange-report.mjs +8 -10
- package/cli/investigation-artifacts.mjs +176 -0
- package/cli/investigation-checkpoint.mjs +10 -0
- package/cli/investigation-folder.mjs +114 -0
- package/cli/investigation-manifest.mjs +1 -112
- package/cli/investigation-package-review.mjs +103 -0
- package/cli/investigation-plan.mjs +38 -147
- package/cli/investigation-recipes.mjs +177 -0
- package/cli/investigation-run.mjs +256 -35
- package/cli/local-document-checkpoint.mjs +170 -0
- package/cli/local-mmdb-review.mjs +197 -17
- package/cli/lookalike-calibration.mjs +1 -1
- package/cli/lookup-brief.mjs +2 -2
- package/cli/lookup-browser.mjs +5 -12
- package/cli/lookup-command-runner.mjs +33 -39
- package/cli/lookup-diff.mjs +47 -12
- package/cli/lookup-plan.mjs +16 -14
- package/cli/lookup-reconcile.mjs +15 -12
- package/cli/lookup-timeline.mjs +7 -6
- package/cli/mail-header-review.mjs +24 -247
- package/cli/mail-review.mjs +75 -21
- package/cli/manual.mjs +1 -0
- package/cli/network-arguments.mjs +51 -0
- package/cli/network-command-definitions.mjs +130 -0
- package/cli/network-command-runner.mjs +45 -31
- package/cli/offline-evidence-review.mjs +39 -6
- package/cli/output-file.mjs +31 -5
- package/cli/posture.mjs +1 -1
- package/cli/registry-doctor.mjs +3 -1
- package/cli/registry-fixture-scaffold.mjs +1 -1
- package/cli/registry-support.mjs +1 -1
- package/cli/retained-artifact-diff.mjs +10 -9
- package/cli/review-arguments.mjs +131 -0
- package/cli/review-command-definitions.mjs +273 -0
- package/cli/review-command-runner.mjs +104 -149
- package/cli/risk-calibration.mjs +8 -8
- package/cli/runner.mjs +74 -37
- package/cli/saved-lookup.mjs +2 -2
- package/cli/selected-input-worker.mjs +63 -0
- package/cli/sharing-review.mjs +8 -80
- package/cli/signer-trust.mjs +104 -0
- package/cli/source-reliability.mjs +75 -84
- package/cli/support-arguments.mjs +49 -0
- package/cli/support-command-definitions.mjs +209 -0
- package/cli/support-command-runner.mjs +2 -2
- package/cli/terminal-input.mjs +168 -0
- package/cli/workflow-arguments.mjs +86 -0
- package/cli/workflow-command-definitions.mjs +78 -0
- package/cli/workflow-command-runner.mjs +75 -13
- package/docs/cli-reference.md +103 -30
- package/docs/cli.md +510 -25
- package/docs/contextual-reviews.md +155 -0
- package/lib/abort.mjs +4 -1
- package/lib/analyst-taxonomy.mjs +2 -40
- package/lib/application-version.mjs +1 -1
- package/lib/availability.mjs +27 -754
- package/lib/bounded-contract-normalizers.mjs +4 -0
- package/lib/bounded-file.mjs +3 -1
- package/lib/bounded-html-document.mjs +125 -0
- package/lib/bounded-json.mjs +2 -290
- package/lib/browser-library-profile.mjs +99 -130
- package/lib/browser-library-worker.mjs +112 -0
- package/lib/candidate-provenance-bounds.mjs +2 -0
- package/lib/classify.mjs +1 -1
- package/lib/client-behavior-profile.mjs +3 -3
- package/lib/ct-query.mjs +2 -27
- package/lib/ct-response-bounds.mjs +2 -9
- package/lib/ct-search.mjs +89 -46
- package/lib/dmarc-discovery.mjs +62 -0
- package/lib/dns-convergence-review.mjs +21 -8
- package/lib/dns-delegation-health.mjs +36 -22
- package/lib/dns-inheritance-review.mjs +207 -0
- package/lib/dns-intelligence.mjs +44 -29
- package/lib/dns-mx.mjs +1 -1
- package/lib/dns-query-coverage.mjs +40 -0
- package/lib/dnssec-evidence-validation.mjs +11 -3
- package/lib/domain-assurance.mjs +1 -1
- package/lib/domain-change-packet.mjs +18 -14
- package/lib/domain-change-review.mjs +40 -16
- package/lib/domain-control-flight-recorder.mjs +301 -124
- package/lib/domain-control-manifest.mjs +126 -58
- package/lib/domain-posture-analysis.mjs +41 -11
- package/lib/domain-posture-parsers.mjs +88 -6
- package/lib/domain-posture.mjs +120 -32
- package/lib/domain-registration.mjs +392 -0
- package/lib/evidence-export-privacy.mjs +568 -0
- package/lib/evidence-export.mjs +12 -593
- package/lib/evidence-report.mjs +7 -2
- package/lib/external-intelligence-risk.mjs +2 -124
- package/lib/favicon.mjs +117 -41
- package/lib/generated/cisa-kev-catalog.mjs +50 -4
- package/lib/generated/registrar-standing-catalogue.mjs +18 -10
- package/lib/generated/retire-browser-catalog.mjs +2742 -1034
- package/lib/generated/{unicode-confusables-17.mjs → unicode-confusables.mjs} +33 -33
- package/lib/html-signals.mjs +87 -85
- package/lib/http-evidence-bounds.mjs +2 -7
- package/lib/http-intelligence.mjs +52 -27
- package/lib/idn-confusable-policy.mjs +6 -4
- package/lib/idn-confusables.mjs +1 -1
- package/lib/interchange-fidelity-registry.mjs +10 -0
- package/lib/lookup-cache.mjs +34 -11
- package/lib/lookup-child-profile-contract.mjs +24 -15
- package/lib/lookup-contract-primitives.mjs +1 -1
- package/lib/lookup-diagnostics.mjs +2 -1
- package/lib/lookup-network-evidence-bounds.mjs +1 -10
- package/lib/lookup-progress.mjs +79 -13
- package/lib/lookup-response-contract.mjs +1077 -0
- package/lib/lookup-response.mjs +11 -24
- package/lib/lookup-source-progress.mjs +24 -35
- package/lib/lookup.mjs +49 -28
- package/lib/observed-network-context.mjs +43 -27
- package/lib/opportunity-scoring.mjs +2 -107
- package/lib/outbound-identity.mjs +1 -1
- package/lib/outbound-request-bounds.mjs +4 -1
- package/lib/page-fingerprints.mjs +87 -134
- package/lib/page-role-profile.mjs +12 -8
- package/lib/perceptual-hash-comparison.mjs +2 -34
- package/lib/perceptual-hash.mjs +79 -24
- package/lib/portable-generator.mjs +2 -29
- package/lib/project-metadata.mjs +2 -8
- package/lib/rdap-bootstrap.mjs +72 -22
- package/lib/rdap-client.mjs +26 -14
- package/lib/rdap-normalization.mjs +33 -18
- package/lib/rdap-search-workbench.mjs +1 -1
- package/lib/rdap-transport.mjs +47 -20
- package/lib/rdap-types.mjs +2 -1
- package/lib/rdap.mjs +18 -3
- package/lib/registrable-domain.mjs +2 -36
- package/lib/registrar-standing-contract.mjs +2 -1
- package/lib/registrar-standing.mjs +9 -13
- package/lib/registry-capabilities.mjs +7 -3
- package/lib/registry-capability-catalogue.mjs +29 -20
- package/lib/registry-dates.mjs +2 -190
- package/lib/registry-insights.mjs +56 -18
- package/lib/response-policy.mjs +86 -48
- package/lib/risk-calibration-summary.mjs +2 -338
- package/lib/risk-scoring.mjs +2 -345
- package/lib/rpki-evidence.mjs +8 -5
- package/lib/safe-fetch.mjs +54 -47
- package/lib/scoring-evidence-quality.mjs +2 -107
- package/lib/security-txt.mjs +10 -7
- package/lib/semantic-version.mjs +2 -54
- package/lib/service-binding-dns.mjs +35 -0
- package/lib/smtp-transport-review.mjs +75 -34
- package/lib/sslbl-certificates.generated.mjs +141 -138
- package/lib/static-html-analysis.mjs +117 -146
- package/lib/structured-data-identity.mjs +2 -1
- package/lib/technology-markup.mjs +100 -0
- package/lib/threat-intelligence-manifests.mjs +11 -139
- package/lib/threat-intelligence-runtime.mjs +24 -52
- package/lib/threat-intelligence-targets.mjs +6 -34
- package/lib/threat-intelligence-types.mjs +2 -36
- package/lib/typosquat-generator.mjs +29 -16
- package/lib/urlhaus-intelligence.mjs +8 -3
- package/lib/urlscan-intelligence.mjs +1 -1
- package/lib/website-enrichment.mjs +388 -0
- package/lib/website-security-posture.mjs +30 -6
- package/lib/website-technology.mjs +111 -71
- package/lib/whois-authority.mjs +55 -5
- package/lib/whois-chain.mjs +9 -2
- package/lib/whois-common-formats.mjs +5 -5
- package/lib/whois-contracts.mjs +2 -1
- package/lib/whois-dialects.mjs +2 -2
- package/lib/whois-normalization.mjs +3 -1
- package/lib/whois-parser-support.mjs +8 -1
- package/lib/whois-parser.mjs +5 -3
- package/lib/whois-transport.mjs +23 -7
- package/package.json +14 -14
- package/packages/analysis/analyst-taxonomy.mjs +40 -0
- package/packages/analysis/bounded-json.mjs +330 -0
- package/packages/analysis/candidate-provenance-bounds.mjs +4 -0
- package/packages/analysis/cli-argument-grammar.mjs +216 -0
- package/packages/analysis/ct-query.mjs +27 -0
- package/packages/analysis/ct-response-bounds.mjs +9 -0
- package/packages/analysis/external-intelligence-risk.mjs +124 -0
- package/packages/analysis/http-evidence-bounds.mjs +8 -0
- package/packages/analysis/lookup-network-evidence-bounds.mjs +10 -0
- package/packages/analysis/opportunity-scoring.mjs +107 -0
- package/packages/analysis/perceptual-hash-comparison.mjs +34 -0
- package/packages/analysis/portable-generator.mjs +29 -0
- package/packages/analysis/project-metadata.mjs +8 -0
- package/packages/analysis/registrable-domain.mjs +56 -0
- package/packages/analysis/risk-calibration-summary.mjs +352 -0
- package/packages/analysis/risk-scoring.mjs +345 -0
- package/packages/analysis/scoring-evidence-quality.mjs +107 -0
- package/packages/analysis/semantic-version.mjs +54 -0
- package/packages/analysis/threat-intelligence-types.mjs +75 -0
- package/packages/cases/case-attachment-model.mjs +83 -0
- package/packages/cases/case-evidence-links.mjs +135 -0
- package/packages/cases/case-evidence-model.mjs +229 -69
- package/packages/cases/case-evidence-quality.mjs +5 -0
- package/packages/cases/case-export-input.mjs +55 -0
- package/packages/cases/case-incident-context.mjs +52 -0
- package/packages/cases/case-markdown.mjs +11 -0
- package/packages/cases/case-migration-model.mjs +98 -48
- package/packages/cases/case-model.mjs +1 -0
- package/packages/cases/case-recheck-model.mjs +149 -0
- package/packages/cases/case-record-contracts.mjs +1 -1
- package/packages/cases/case-record-core.mjs +4 -3
- package/packages/cases/case-record-operations.mjs +123 -133
- package/packages/cases/case-record-projection.mjs +30 -20
- package/packages/cases/case-record-version-input.mjs +19 -0
- package/packages/cases/case-report.mjs +114 -67
- package/packages/cases/case-requested-evidence.mjs +146 -0
- package/packages/cases/case-response-actions.mjs +756 -0
- package/packages/cases/case-response-model.mjs +49 -1129
- package/packages/cases/case-response-outcomes.mjs +338 -0
- package/packages/cases/case-response-packet-render.mjs +157 -0
- package/packages/cases/case-response-packet-types.mjs +1 -0
- package/packages/cases/case-response-packet-vocabulary.mjs +48 -0
- package/packages/cases/case-response-packet.mjs +58 -593
- package/packages/cases/case-response-records.mjs +93 -0
- package/packages/cases/case-response-review-inputs.mjs +382 -0
- package/packages/cases/case-response-values.mjs +85 -0
- package/packages/cases/case-review-package.mjs +45 -0
- package/packages/cases/case-selection.mjs +46 -0
- package/packages/cases/case-storage-model.mjs +26 -1
- package/packages/cases/case-workflow-metadata.mjs +225 -0
- package/packages/cases/case-workflow-migration.mjs +43 -0
- package/packages/cases/http-summary.mjs +6 -1
- package/packages/cases/response-route-freshness.mjs +16 -0
- package/packages/comparison/capture-context.mjs +61 -0
- package/packages/comparison/comparison-ledger-bulk.mjs +4 -1
- package/packages/comparison/favicon-similarity.mjs +1 -1
- package/packages/comparison/page-similarity.mjs +3 -2
- package/packages/comparison/relationship-evidence.mjs +103 -14
- package/packages/comparison/relationship-provenance.mjs +99 -0
- package/packages/contracts/analyst-interchange.mjs +234 -0
- package/packages/contracts/analyst-review-state-contract.mjs +11 -0
- package/packages/contracts/analyst-review-state.mjs +5 -4
- package/packages/contracts/case-portability.mjs +370 -114
- package/packages/contracts/case-views-contract.mjs +12 -0
- package/packages/contracts/case-views.mjs +26 -0
- package/packages/contracts/cli-command-semantics.mjs +3 -0
- package/packages/contracts/cli-grammar.mjs +6 -0
- package/packages/contracts/cli-lookup-brief.mjs +2 -0
- package/packages/contracts/cli-lookup.mjs +0 -1
- package/packages/contracts/context-review.mjs +24 -0
- package/packages/contracts/document-intake.mjs +11 -0
- package/packages/contracts/domain-control-flight-recorder.mjs +98 -44
- package/packages/contracts/domain-control-manifest.mjs +128 -74
- package/packages/contracts/domain-control-monitor.mjs +59 -45
- package/packages/contracts/domain-control-review.mjs +200 -121
- package/packages/contracts/domain-name.mjs +21 -0
- package/packages/contracts/external-observation-interchange.mjs +2 -1
- package/packages/contracts/extracted-domain-lifecycle.mjs +11 -32
- package/packages/contracts/har-review.mjs +2 -0
- package/packages/contracts/http-url.mjs +2 -0
- package/packages/contracts/identity-events.mjs +4 -0
- package/packages/contracts/investigation-package-limits.mjs +24 -0
- package/packages/contracts/investigation-portability.mjs +56 -27
- package/packages/contracts/investigation-run.mjs +18 -0
- package/packages/contracts/ip-address.mjs +44 -0
- package/packages/contracts/lookup-evidence.mjs +35 -0
- package/packages/contracts/mail-authentication.mjs +5 -0
- package/packages/contracts/message-intake.mjs +31 -0
- package/packages/contracts/offline-comparison.mjs +4 -2
- package/packages/contracts/page-fingerprints.mjs +15 -0
- package/packages/contracts/passive-mail.mjs +10 -0
- package/packages/contracts/risk-calibration.mjs +0 -1
- package/packages/contracts/schema-compatibility.mjs +1 -1
- package/packages/contracts/schema-lifecycle.mjs +83 -153
- package/packages/contracts/selected-file-limits.mjs +6 -0
- package/packages/contracts/vulnerability-identifiers.mjs +5 -0
- package/packages/contracts/web-capture.mjs +10 -0
- package/packages/contracts/workspace-portability.mjs +219 -238
- package/packages/evidence/artifact-integrity.mjs +8 -2
- package/packages/evidence/artifact-structure.mjs +105 -0
- package/packages/evidence/collection-quality.mjs +67 -0
- package/packages/evidence/decision-fact.mjs +4 -1
- package/packages/evidence/dns-query-outcome.mjs +72 -0
- package/packages/evidence/domain-control-runtime.mjs +155 -27
- package/packages/evidence/domain-posture-context.mjs +79 -0
- package/packages/evidence/email-recipient.mjs +18 -0
- package/packages/evidence/image-regions.mjs +56 -0
- package/packages/evidence/latest-observations.mjs +28 -0
- package/packages/evidence/lookup-target.mjs +108 -0
- package/packages/evidence/observation.mjs +18 -1
- package/packages/evidence/passphrase-encryption.mjs +44 -0
- package/packages/evidence/png-pixels.mjs +117 -0
- package/packages/evidence/public-address-policy.mjs +83 -0
- package/packages/evidence/record-identity.mjs +72 -0
- package/packages/evidence/registry-dates.mjs +190 -0
- package/packages/evidence/retained-file.mjs +69 -0
- package/packages/evidence/review-age.mjs +14 -0
- package/packages/interchange/bagit.mjs +342 -0
- package/packages/interchange/bounded-zip-extraction.mjs +278 -0
- package/packages/interchange/crc32.mjs +17 -0
- package/packages/interchange/defensive-indicator-export.mjs +264 -0
- package/packages/interchange/external-findings-import.mjs +93 -61
- package/packages/interchange/managed-indicator-export.mjs +35 -0
- package/packages/interchange/managed-indicator-set.mjs +210 -0
- package/packages/interchange/misp-indicator-export.mjs +93 -0
- package/packages/interchange/sharing-policy.mjs +56 -0
- package/packages/interchange/stix-indicator-export.mjs +129 -0
- package/packages/interchange/web-capture-import.mjs +389 -0
- package/packages/investigation/acquisition-decision-packet.mjs +1 -1
- package/packages/investigation/bulk-mail-exposure.mjs +9 -14
- package/packages/investigation/capture-coverage.mjs +57 -0
- package/packages/investigation/connector-provenance-review.mjs +100 -0
- package/packages/investigation/context-review.mjs +35 -0
- package/packages/investigation/document-intake.mjs +81 -0
- package/packages/investigation/docx-intake.mjs +133 -0
- package/packages/investigation/domain-history-review.mjs +100 -0
- package/packages/investigation/domain-transition-review.mjs +47 -0
- package/packages/investigation/evidence-coverage-ledger.mjs +9 -1
- package/packages/investigation/har-intake.mjs +68 -0
- package/packages/investigation/identity-event-intake.mjs +131 -0
- package/packages/investigation/identity-incident-review.mjs +39 -0
- package/packages/investigation/incident-sequence-review.mjs +58 -0
- package/packages/investigation/intake-report.mjs +19 -0
- package/packages/investigation/investigation-bagit.mjs +14 -0
- package/packages/investigation/investigation-capsule.mjs +33 -5
- package/packages/investigation/investigation-manifest.mjs +200 -0
- package/packages/investigation/investigation-package-crypto.mjs +98 -0
- package/packages/investigation/investigation-package.mjs +200 -0
- package/packages/investigation/link-intake.mjs +179 -0
- package/packages/investigation/lookup-asset-graph-inputs.mjs +38 -0
- package/packages/investigation/lookup-asset-graph.mjs +161 -141
- package/packages/investigation/lookup-claim-readiness.mjs +18 -0
- package/packages/investigation/lookup-investigation-brief.mjs +3 -3
- package/packages/investigation/lookup-task-guidance.mjs +58 -0
- package/packages/investigation/mail-authentication-review.mjs +222 -0
- package/packages/investigation/mail-header-identity.mjs +209 -0
- package/packages/investigation/message-intake.mjs +195 -0
- package/packages/investigation/page-behaviour.mjs +113 -0
- package/packages/investigation/pdf-intake.mjs +155 -0
- package/packages/investigation/platform-continuity-review.mjs +60 -0
- package/packages/investigation/qr-intake.mjs +56 -0
- package/packages/investigation/requested-action-hints.mjs +11 -0
- package/packages/investigation/selected-input-review.mjs +17 -0
- package/packages/investigation/storefront-review.mjs +70 -0
- package/packages/monitoring/analyst-review-state.mjs +38 -90
- package/packages/workspace/brand-profile-model.mjs +160 -22
- package/packages/workspace/bulk-columns.mjs +17 -0
- package/packages/workspace/bulk-review-model.mjs +39 -31
- package/packages/workspace/bulk-session-model.mjs +112 -27
- package/packages/workspace/bulk-sort.mjs +1 -0
- package/packages/workspace/campaign-model.mjs +1 -1
- package/packages/workspace/case-views.mjs +102 -0
- package/packages/workspace/detection-rule-model.mjs +1 -1
- package/packages/workspace/hostile-input.mjs +29 -8
- package/packages/workspace/investigation-guide.mjs +2 -2
- package/packages/workspace/investigation-template-model.mjs +45 -6
- package/packages/workspace/page-baseline.mjs +20 -17
- package/packages/workspace/relationship-observation-model.mjs +54 -35
- package/packages/workspace/shortlist-model.mjs +14 -5
- package/packages/workspace/watchlist-history.mjs +30 -14
- package/packages/workspace/watchlist-store.mjs +24 -6
- package/packages/workspace/website-snapshot-model.mjs +98 -33
- package/packages/workspace/workspace-archive-crypto.mjs +41 -61
- package/packages/workspace/workspace-archive.mjs +90 -25
- package/third-party-notices.txt +577 -17
- package/lib/hostname.mjs +0 -38
- package/packages/investigation/bulk-review-export.mjs +0 -63
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {} from "./command-argument-grammar.mjs";
|
|
2
|
+
import {} from "./fail-policy.mjs";
|
|
3
|
+
import { commandDefaultNumber, commandDefaultText } from "./command-reference.mjs";
|
|
4
|
+
import { COLLECTION_COMMAND_DEFINITIONS } from "./collection-command-definitions.mjs";
|
|
5
|
+
import { terminalOptions, normalizedLabel, failPolicies, parseOutput, } from "./argument-values.mjs";
|
|
6
|
+
function parseLookupArguments(parsed) {
|
|
7
|
+
const output = parseOutput(parsed, COLLECTION_COMMAND_DEFINITIONS.lookup);
|
|
8
|
+
const selectedFailPolicies = failPolicies(parsed, 'lookup');
|
|
9
|
+
return {
|
|
10
|
+
action: 'lookup',
|
|
11
|
+
query: parsed.positionalValue('target'),
|
|
12
|
+
output,
|
|
13
|
+
deep: parsed.hasOption('--deep'),
|
|
14
|
+
detail: parsed.hasOption('--summary')
|
|
15
|
+
? 'summary'
|
|
16
|
+
: parsed.hasOption('--verbose')
|
|
17
|
+
? 'verbose'
|
|
18
|
+
: 'standard',
|
|
19
|
+
strictExit: parsed.hasOption('--strict-exit'),
|
|
20
|
+
events: parsed.hasOption('--events'),
|
|
21
|
+
plan: parsed.hasOption('--plan'),
|
|
22
|
+
includeAttribution: !parsed.hasOption('--no-attribution'),
|
|
23
|
+
observerLabel: normalizedLabel(parsed, '--observer', 80),
|
|
24
|
+
vantageLabel: normalizedLabel(parsed, '--vantage', 80),
|
|
25
|
+
...terminalOptions(parsed),
|
|
26
|
+
...(parsed.hasOption('--browse') ? { browse: true } : {}),
|
|
27
|
+
...(parsed.hasOption('--exact-url') ? { exactUrl: true } : {}),
|
|
28
|
+
...(parsed.optionValue('--save-lookup')
|
|
29
|
+
? { saveLookup: parsed.optionValue('--save-lookup') }
|
|
30
|
+
: {}),
|
|
31
|
+
...(selectedFailPolicies ? { failOn: selectedFailPolicies } : {}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function parseBulkArguments(parsed) {
|
|
35
|
+
const deep = parsed.hasOption('--deep');
|
|
36
|
+
const selectedFailPolicies = failPolicies(parsed, 'bulk');
|
|
37
|
+
const output = parseOutput(parsed, COLLECTION_COMMAND_DEFINITIONS.bulk);
|
|
38
|
+
const filter = parsed.hasOption('--registered-only')
|
|
39
|
+
? 'registered'
|
|
40
|
+
: parsed.hasOption('--inconclusive-only')
|
|
41
|
+
? 'inconclusive'
|
|
42
|
+
: parsed.hasOption('--errors-only')
|
|
43
|
+
? 'errors'
|
|
44
|
+
: 'all';
|
|
45
|
+
return {
|
|
46
|
+
action: 'bulk',
|
|
47
|
+
source: parsed.positionalValue('source'),
|
|
48
|
+
output,
|
|
49
|
+
deep,
|
|
50
|
+
concurrency: parsed.integerOption('--concurrency') ?? commandDefaultNumber('bulk', '--concurrency', deep),
|
|
51
|
+
checkpoint: parsed.optionValue('--checkpoint'),
|
|
52
|
+
resume: parsed.hasOption('--resume'),
|
|
53
|
+
events: parsed.hasOption('--events'),
|
|
54
|
+
plan: parsed.hasOption('--plan'),
|
|
55
|
+
filter,
|
|
56
|
+
...terminalOptions(parsed),
|
|
57
|
+
...(selectedFailPolicies ? { failOn: selectedFailPolicies } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function parseDiscoverArguments(parsed) {
|
|
61
|
+
return {
|
|
62
|
+
action: 'discover',
|
|
63
|
+
seed: parsed.positionalValue('subject'),
|
|
64
|
+
output: parseOutput(parsed, COLLECTION_COMMAND_DEFINITIONS.discover),
|
|
65
|
+
...discoveryValues(parsed),
|
|
66
|
+
snapshotSource: parsed.optionValue('--snapshot'),
|
|
67
|
+
...terminalOptions(parsed),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function discoveryValues(parsed) {
|
|
71
|
+
const familyText = parsed.optionValue('--families');
|
|
72
|
+
return {
|
|
73
|
+
preset: (familyText
|
|
74
|
+
? 'custom'
|
|
75
|
+
: (parsed.optionValue('--preset') ?? commandDefaultText('discover', '--preset'))),
|
|
76
|
+
keyboardLayout: (parsed.optionValue('--keyboard') ??
|
|
77
|
+
commandDefaultText('discover', '--keyboard')),
|
|
78
|
+
tldText: parsed.optionValue('--tlds'),
|
|
79
|
+
dictionarySource: parsed.optionValue('--dictionary'),
|
|
80
|
+
familyText,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function parseDiscoverScanArguments(parsed) {
|
|
84
|
+
const deep = parsed.hasOption('--deep');
|
|
85
|
+
const selectedFailPolicies = failPolicies(parsed, 'discover-scan');
|
|
86
|
+
const filter = parsed.hasOption('--registered-only')
|
|
87
|
+
? 'registered'
|
|
88
|
+
: parsed.hasOption('--inconclusive-only')
|
|
89
|
+
? 'inconclusive'
|
|
90
|
+
: parsed.hasOption('--acquisition-only')
|
|
91
|
+
? 'acquisition'
|
|
92
|
+
: parsed.hasOption('--suppressed-only')
|
|
93
|
+
? 'suppressed'
|
|
94
|
+
: 'all';
|
|
95
|
+
return {
|
|
96
|
+
action: 'discover-scan',
|
|
97
|
+
seed: parsed.positionalValue('subject'),
|
|
98
|
+
output: parseOutput(parsed, COLLECTION_COMMAND_DEFINITIONS['discover-scan']),
|
|
99
|
+
...discoveryValues(parsed),
|
|
100
|
+
deep,
|
|
101
|
+
scanLimit: parsed.integerOption('--scan-limit') ??
|
|
102
|
+
commandDefaultNumber('discover-scan', '--scan-limit', deep),
|
|
103
|
+
chunkSize: parsed.integerOption('--chunk-size') ?? commandDefaultNumber('discover-scan', '--chunk-size'),
|
|
104
|
+
concurrency: parsed.integerOption('--concurrency') ??
|
|
105
|
+
commandDefaultNumber('discover-scan', '--concurrency', deep),
|
|
106
|
+
checkpoint: parsed.optionValue('--checkpoint'),
|
|
107
|
+
resume: parsed.hasOption('--resume'),
|
|
108
|
+
resolverText: parsed.optionValue('--resolver'),
|
|
109
|
+
observationSnapshot: parsed.optionValue('--observation-snapshot'),
|
|
110
|
+
allowlistSource: parsed.optionValue('--allowlist'),
|
|
111
|
+
filter,
|
|
112
|
+
events: parsed.hasOption('--events'),
|
|
113
|
+
plan: parsed.hasOption('--plan'),
|
|
114
|
+
...terminalOptions(parsed),
|
|
115
|
+
...(selectedFailPolicies ? { failOn: selectedFailPolicies } : {}),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export const COLLECTION_ARGUMENT_PARSERS = Object.freeze({
|
|
119
|
+
lookup: parseLookupArguments,
|
|
120
|
+
bulk: parseBulkArguments,
|
|
121
|
+
discover: parseDiscoverArguments,
|
|
122
|
+
'discover-scan': parseDiscoverScanArguments,
|
|
123
|
+
});
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { positional, OPTIONAL_FILE_POSITIONAL, OPTIONAL_TEXT_POSITIONAL, constraint, commandSeed, } from "./command-definition.mjs";
|
|
2
|
+
import { bulkQueryLimit, bulkConcurrencyLimit } from "../lib/bulk-limits.mjs";
|
|
3
|
+
const COLLECTION_CEILINGS = `${bulkQueryLimit('fast')} fast or ${bulkQueryLimit('deep')} deep`;
|
|
4
|
+
const CONCURRENCY_CEILINGS = `${bulkConcurrencyLimit('fast')} fast or ${bulkConcurrencyLimit('deep')} deep`;
|
|
5
|
+
export const COLLECTION_COMMAND_DEFINITIONS = Object.freeze({
|
|
6
|
+
lookup: commandSeed({
|
|
7
|
+
reference: {
|
|
8
|
+
description: 'Collect registration evidence for one domain, IP, or ASN.',
|
|
9
|
+
example: 'whoisleuth lookup example.test --deep --browse',
|
|
10
|
+
boundary: 'Fast is the default. An ICANN-recognised public domain, reserved documentation domain, IP, or ASN may occupy command position as shorthand; it delegates to this same parser and URL-like input requires the explicit lookup command. Deep mode adds bounded WHOIS, DNS, HTTP, TLS, technology, posture, and network context where applicable. --deep --exact-url explicitly sends the input URL path and query to the website, without its fragment; ordinary URL input sends only the hostname. --plan remains offline and omits the selected URL. Retained paths and page-derived text require review before sharing. A full Deep homepage observation can derive fixed publication and delivery/cache summaries from the same response without retaining raw metadata values or making another request. --browse opens before collection, shows aggregate Fast progress or independently settled planned Deep sources, and then navigates allowlisted retained fields in the completed document. Press ? for help and / to search rendered panel text only. Closing during collection cancels without a partial document. --save-lookup writes the exact completed private JSON only after a normal browser close; it can contain normalised evidence omitted from panels and refuses an existing path.',
|
|
11
|
+
},
|
|
12
|
+
collection: {
|
|
13
|
+
scope: 'Accepts one target. Fast is the default; deep collection must be selected explicitly.',
|
|
14
|
+
},
|
|
15
|
+
summary: 'Collect one domain, IP, or ASN',
|
|
16
|
+
options: [
|
|
17
|
+
'--json',
|
|
18
|
+
'--junit',
|
|
19
|
+
'--markdown',
|
|
20
|
+
'--html',
|
|
21
|
+
'--no-attribution',
|
|
22
|
+
'--fast',
|
|
23
|
+
'--deep',
|
|
24
|
+
'--exact-url',
|
|
25
|
+
'--observer',
|
|
26
|
+
'--vantage',
|
|
27
|
+
'--plan',
|
|
28
|
+
'--summary',
|
|
29
|
+
'--verbose',
|
|
30
|
+
'--browse',
|
|
31
|
+
'--save-lookup',
|
|
32
|
+
'--strict-exit',
|
|
33
|
+
'--fail-on',
|
|
34
|
+
'--events',
|
|
35
|
+
'--quiet',
|
|
36
|
+
'--no-color',
|
|
37
|
+
],
|
|
38
|
+
positionals: Object.freeze([
|
|
39
|
+
positional('target', 'text', 0, 1, [], 'argv_or_stdin', ['--browse']),
|
|
40
|
+
]),
|
|
41
|
+
constraints: Object.freeze([
|
|
42
|
+
constraint({
|
|
43
|
+
kind: 'mutually_exclusive',
|
|
44
|
+
options: ['--json', '--junit', '--markdown', '--html'],
|
|
45
|
+
}),
|
|
46
|
+
constraint({ kind: 'mutually_exclusive', options: ['--fast', '--deep'] }),
|
|
47
|
+
constraint({ kind: 'mutually_exclusive', options: ['--summary', '--verbose'] }),
|
|
48
|
+
constraint({ kind: 'requires_all', option: '--save-lookup', requiredOptions: ['--browse'] }),
|
|
49
|
+
constraint({ kind: 'requires_all', option: '--exact-url', requiredOptions: ['--deep'] }),
|
|
50
|
+
constraint({
|
|
51
|
+
kind: 'excludes_all',
|
|
52
|
+
option: '--summary',
|
|
53
|
+
excludedOptions: ['--json', '--junit', '--markdown', '--html'],
|
|
54
|
+
}),
|
|
55
|
+
constraint({
|
|
56
|
+
kind: 'excludes_all',
|
|
57
|
+
option: '--verbose',
|
|
58
|
+
excludedOptions: ['--json', '--junit', '--markdown', '--html'],
|
|
59
|
+
}),
|
|
60
|
+
constraint({
|
|
61
|
+
kind: 'excludes_all',
|
|
62
|
+
option: '--browse',
|
|
63
|
+
excludedOptions: [
|
|
64
|
+
'--json',
|
|
65
|
+
'--junit',
|
|
66
|
+
'--markdown',
|
|
67
|
+
'--html',
|
|
68
|
+
'--summary',
|
|
69
|
+
'--verbose',
|
|
70
|
+
'--events',
|
|
71
|
+
'--plan',
|
|
72
|
+
'--quiet',
|
|
73
|
+
],
|
|
74
|
+
}),
|
|
75
|
+
constraint({
|
|
76
|
+
kind: 'requires_any',
|
|
77
|
+
option: '--no-attribution',
|
|
78
|
+
requiredOptions: ['--markdown', '--html'],
|
|
79
|
+
}),
|
|
80
|
+
constraint({
|
|
81
|
+
kind: 'excludes_all',
|
|
82
|
+
option: '--plan',
|
|
83
|
+
excludedOptions: [
|
|
84
|
+
'--junit',
|
|
85
|
+
'--markdown',
|
|
86
|
+
'--html',
|
|
87
|
+
'--summary',
|
|
88
|
+
'--verbose',
|
|
89
|
+
'--strict-exit',
|
|
90
|
+
'--events',
|
|
91
|
+
'--quiet',
|
|
92
|
+
'--fail-on',
|
|
93
|
+
],
|
|
94
|
+
}),
|
|
95
|
+
]),
|
|
96
|
+
handlerOwner: 'lookup',
|
|
97
|
+
networkEffect: 'conditional_network',
|
|
98
|
+
common: true,
|
|
99
|
+
schemaIdentifiers: Object.freeze(['whoisleuth.cli.lookup', 'whoisleuth.cli.lookup-plan']),
|
|
100
|
+
primaryArtefacts: Object.freeze(['Source-qualified Lookup', 'Lookup request plan']),
|
|
101
|
+
planSupport: true,
|
|
102
|
+
additionalOutputFormats: Object.freeze([]),
|
|
103
|
+
bootstrapProfile: 'allowed',
|
|
104
|
+
}),
|
|
105
|
+
bulk: commandSeed({
|
|
106
|
+
reference: {
|
|
107
|
+
description: 'Triage newline-delimited domains, IPs, or ASNs with bounded concurrency.',
|
|
108
|
+
example: 'cat domains.txt | whoisleuth bulk --jsonl',
|
|
109
|
+
boundary: 'Fast and deep jobs use separate concurrency ceilings. Filters affect output only; collection failures and inconclusive authority states remain explicit in JSON, JSONL, and CSV. --csv-with-metadata adds source versions, separate observation and report times, collection origin and diagnostic states; --csv retains the compact columns.',
|
|
110
|
+
},
|
|
111
|
+
collection: {
|
|
112
|
+
scope: `Accepts at most ${COLLECTION_CEILINGS} targets, with concurrency capped at ${CONCURRENCY_CEILINGS}.`,
|
|
113
|
+
},
|
|
114
|
+
summary: 'Run bounded multi-target collection',
|
|
115
|
+
options: [
|
|
116
|
+
'--json',
|
|
117
|
+
'--jsonl',
|
|
118
|
+
'--junit',
|
|
119
|
+
'--csv',
|
|
120
|
+
'--csv-with-metadata',
|
|
121
|
+
'--domains',
|
|
122
|
+
'--queries',
|
|
123
|
+
'--registered-only',
|
|
124
|
+
'--inconclusive-only',
|
|
125
|
+
'--errors-only',
|
|
126
|
+
'--fast',
|
|
127
|
+
'--deep',
|
|
128
|
+
'--concurrency',
|
|
129
|
+
'--checkpoint',
|
|
130
|
+
'--resume',
|
|
131
|
+
'--events',
|
|
132
|
+
'--plan',
|
|
133
|
+
'--fail-on',
|
|
134
|
+
'--quiet',
|
|
135
|
+
'--no-color',
|
|
136
|
+
],
|
|
137
|
+
positionals: OPTIONAL_FILE_POSITIONAL,
|
|
138
|
+
constraints: Object.freeze([
|
|
139
|
+
constraint({
|
|
140
|
+
kind: 'mutually_exclusive',
|
|
141
|
+
options: [
|
|
142
|
+
'--json',
|
|
143
|
+
'--jsonl',
|
|
144
|
+
'--junit',
|
|
145
|
+
'--csv',
|
|
146
|
+
'--csv-with-metadata',
|
|
147
|
+
'--domains',
|
|
148
|
+
'--queries',
|
|
149
|
+
],
|
|
150
|
+
}),
|
|
151
|
+
constraint({
|
|
152
|
+
kind: 'mutually_exclusive',
|
|
153
|
+
options: ['--registered-only', '--inconclusive-only', '--errors-only'],
|
|
154
|
+
}),
|
|
155
|
+
constraint({ kind: 'mutually_exclusive', options: ['--fast', '--deep'] }),
|
|
156
|
+
constraint({ kind: 'requires_all', option: '--resume', requiredOptions: ['--checkpoint'] }),
|
|
157
|
+
constraint({
|
|
158
|
+
kind: 'excludes_all',
|
|
159
|
+
option: '--plan',
|
|
160
|
+
excludedOptions: [
|
|
161
|
+
'--jsonl',
|
|
162
|
+
'--junit',
|
|
163
|
+
'--csv',
|
|
164
|
+
'--csv-with-metadata',
|
|
165
|
+
'--domains',
|
|
166
|
+
'--queries',
|
|
167
|
+
'--events',
|
|
168
|
+
'--checkpoint',
|
|
169
|
+
'--resume',
|
|
170
|
+
'--quiet',
|
|
171
|
+
'--fail-on',
|
|
172
|
+
],
|
|
173
|
+
}),
|
|
174
|
+
]),
|
|
175
|
+
handlerOwner: 'bulk',
|
|
176
|
+
networkEffect: 'conditional_network',
|
|
177
|
+
common: true,
|
|
178
|
+
schemaIdentifiers: Object.freeze([
|
|
179
|
+
'whoisleuth.cli.bulk',
|
|
180
|
+
'whoisleuth.cli.bulk.item',
|
|
181
|
+
'whoisleuth.cli.bulk-checkpoint',
|
|
182
|
+
]),
|
|
183
|
+
primaryArtefacts: Object.freeze(['Bulk result', 'Bulk checkpoint']),
|
|
184
|
+
planSupport: true,
|
|
185
|
+
additionalOutputFormats: Object.freeze([]),
|
|
186
|
+
bootstrapProfile: 'allowed',
|
|
187
|
+
}),
|
|
188
|
+
discover: commandSeed({
|
|
189
|
+
reference: {
|
|
190
|
+
description: 'Generate bounded lookalike-domain candidates from a brand or registrable domain, including multi-part public suffixes.',
|
|
191
|
+
example: 'whoisleuth discover example.test --preset common --jsonl',
|
|
192
|
+
boundary: 'Generation and optional local snapshot comparison are offline. Candidates are leads only and are not resolved, registered, or classified as malicious.',
|
|
193
|
+
},
|
|
194
|
+
collection: {
|
|
195
|
+
scope: 'Generates a bounded candidate set from local rules, dictionaries, and optional saved snapshots.',
|
|
196
|
+
},
|
|
197
|
+
summary: 'Generate lookalike candidates offline',
|
|
198
|
+
options: [
|
|
199
|
+
'--tlds',
|
|
200
|
+
'--preset',
|
|
201
|
+
'--families',
|
|
202
|
+
'--keyboard',
|
|
203
|
+
'--dictionary',
|
|
204
|
+
'--snapshot',
|
|
205
|
+
'--json',
|
|
206
|
+
'--jsonl',
|
|
207
|
+
'--domains',
|
|
208
|
+
'--quiet',
|
|
209
|
+
'--no-color',
|
|
210
|
+
],
|
|
211
|
+
positionals: OPTIONAL_TEXT_POSITIONAL,
|
|
212
|
+
constraints: Object.freeze([
|
|
213
|
+
constraint({ kind: 'mutually_exclusive', options: ['--json', '--jsonl', '--domains'] }),
|
|
214
|
+
constraint({ kind: 'mutually_exclusive', options: ['--preset', '--families'] }),
|
|
215
|
+
constraint({
|
|
216
|
+
kind: 'value_excludes',
|
|
217
|
+
option: '--preset',
|
|
218
|
+
value: 'common',
|
|
219
|
+
excludedOptions: ['--dictionary'],
|
|
220
|
+
}),
|
|
221
|
+
]),
|
|
222
|
+
handlerOwner: 'discovery',
|
|
223
|
+
networkEffect: 'offline',
|
|
224
|
+
common: true,
|
|
225
|
+
schemaIdentifiers: Object.freeze([
|
|
226
|
+
'whoisleuth.cli.discover',
|
|
227
|
+
'whoisleuth.cli.discover.item',
|
|
228
|
+
'whoisleuth.cli.discovery-snapshot',
|
|
229
|
+
]),
|
|
230
|
+
primaryArtefacts: Object.freeze(['Candidate set', 'Discovery snapshot']),
|
|
231
|
+
planSupport: false,
|
|
232
|
+
additionalOutputFormats: Object.freeze([]),
|
|
233
|
+
bootstrapProfile: 'allowed',
|
|
234
|
+
}),
|
|
235
|
+
'discover-scan': commandSeed({
|
|
236
|
+
reference: {
|
|
237
|
+
description: 'Generate a bounded candidate set, collect a selected subset, and produce a supervised review queue.',
|
|
238
|
+
example: 'whoisleuth discover-scan example.test --scan-limit 50 --checkpoint scan.json --json',
|
|
239
|
+
boundary: `This command performs network collection. Fast compact lookup is the default; deep mode is capped at ${bulkQueryLimit('deep')} candidates. Allowlisting changes review priority only and shared infrastructure remains a lead, not attribution. --csv-with-metadata adds source versions, separate observation and report times, collection origin and diagnostic states; --csv retains the compact columns.`,
|
|
240
|
+
},
|
|
241
|
+
collection: {
|
|
242
|
+
scope: `Scans at most ${COLLECTION_CEILINGS} candidates, with concurrency capped at ${CONCURRENCY_CEILINGS}.`,
|
|
243
|
+
},
|
|
244
|
+
summary: 'Collect a supervised candidate review queue',
|
|
245
|
+
options: [
|
|
246
|
+
'--tlds',
|
|
247
|
+
'--preset',
|
|
248
|
+
'--families',
|
|
249
|
+
'--keyboard',
|
|
250
|
+
'--dictionary',
|
|
251
|
+
'--fast',
|
|
252
|
+
'--deep',
|
|
253
|
+
'--scan-limit',
|
|
254
|
+
'--chunk-size',
|
|
255
|
+
'--concurrency',
|
|
256
|
+
'--resolver',
|
|
257
|
+
'--allowlist',
|
|
258
|
+
'--checkpoint',
|
|
259
|
+
'--resume',
|
|
260
|
+
'--observation-snapshot',
|
|
261
|
+
'--registered-only',
|
|
262
|
+
'--inconclusive-only',
|
|
263
|
+
'--acquisition-only',
|
|
264
|
+
'--suppressed-only',
|
|
265
|
+
'--events',
|
|
266
|
+
'--plan',
|
|
267
|
+
'--fail-on',
|
|
268
|
+
'--json',
|
|
269
|
+
'--jsonl',
|
|
270
|
+
'--csv',
|
|
271
|
+
'--csv-with-metadata',
|
|
272
|
+
'--domains',
|
|
273
|
+
'--quiet',
|
|
274
|
+
'--no-color',
|
|
275
|
+
],
|
|
276
|
+
positionals: OPTIONAL_TEXT_POSITIONAL,
|
|
277
|
+
constraints: Object.freeze([
|
|
278
|
+
constraint({
|
|
279
|
+
kind: 'mutually_exclusive',
|
|
280
|
+
options: ['--json', '--jsonl', '--csv', '--csv-with-metadata', '--domains'],
|
|
281
|
+
}),
|
|
282
|
+
constraint({ kind: 'mutually_exclusive', options: ['--preset', '--families'] }),
|
|
283
|
+
constraint({ kind: 'mutually_exclusive', options: ['--fast', '--deep'] }),
|
|
284
|
+
constraint({
|
|
285
|
+
kind: 'mutually_exclusive',
|
|
286
|
+
options: [
|
|
287
|
+
'--registered-only',
|
|
288
|
+
'--inconclusive-only',
|
|
289
|
+
'--acquisition-only',
|
|
290
|
+
'--suppressed-only',
|
|
291
|
+
],
|
|
292
|
+
}),
|
|
293
|
+
constraint({ kind: 'requires_all', option: '--resume', requiredOptions: ['--checkpoint'] }),
|
|
294
|
+
constraint({
|
|
295
|
+
kind: 'value_excludes',
|
|
296
|
+
option: '--preset',
|
|
297
|
+
value: 'common',
|
|
298
|
+
excludedOptions: ['--dictionary'],
|
|
299
|
+
}),
|
|
300
|
+
constraint({
|
|
301
|
+
kind: 'excludes_all',
|
|
302
|
+
option: '--plan',
|
|
303
|
+
excludedOptions: [
|
|
304
|
+
'--jsonl',
|
|
305
|
+
'--csv',
|
|
306
|
+
'--csv-with-metadata',
|
|
307
|
+
'--domains',
|
|
308
|
+
'--events',
|
|
309
|
+
'--checkpoint',
|
|
310
|
+
'--resume',
|
|
311
|
+
'--observation-snapshot',
|
|
312
|
+
'--quiet',
|
|
313
|
+
'--fail-on',
|
|
314
|
+
],
|
|
315
|
+
}),
|
|
316
|
+
]),
|
|
317
|
+
handlerOwner: 'discovery_scan',
|
|
318
|
+
networkEffect: 'conditional_network',
|
|
319
|
+
common: true,
|
|
320
|
+
schemaIdentifiers: Object.freeze([
|
|
321
|
+
'whoisleuth.cli.discovery-scan',
|
|
322
|
+
'whoisleuth.cli.discovery-scan.item',
|
|
323
|
+
'whoisleuth.cli.discovery-observation-snapshot',
|
|
324
|
+
]),
|
|
325
|
+
primaryArtefacts: Object.freeze(['Reviewed candidate queue', 'Observation snapshot']),
|
|
326
|
+
planSupport: true,
|
|
327
|
+
additionalOutputFormats: Object.freeze([]),
|
|
328
|
+
bootstrapProfile: 'allowed',
|
|
329
|
+
}),
|
|
330
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bulkQueryLimit } from "../lib/bulk-limits.mjs";
|
|
1
2
|
export const CLI_COLLECTION_PREFLIGHT_SCHEMA = 'whoisleuth.cli.collection-preflight';
|
|
2
3
|
export const CLI_COLLECTION_PREFLIGHT_VERSION = 1;
|
|
3
4
|
export function buildCollectionPreflight(options) {
|
|
@@ -12,7 +13,7 @@ export function buildCollectionPreflight(options) {
|
|
|
12
13
|
networkRequestsMade: false,
|
|
13
14
|
scope: Object.freeze({
|
|
14
15
|
selectedTargets: options.targetCount,
|
|
15
|
-
commandTargetLimit: options.
|
|
16
|
+
commandTargetLimit: bulkQueryLimit(options.deep ? 'deep' : 'fast'),
|
|
16
17
|
concurrency: options.concurrency,
|
|
17
18
|
sourceFamilies: Object.freeze(sourceFamilies),
|
|
18
19
|
exactRequestCountKnown: false,
|
|
@@ -53,6 +54,12 @@ export function formatCollectionPreflight(document) {
|
|
|
53
54
|
...document.scope.sourceFamilies.map((source) => ` ${source}`),
|
|
54
55
|
'',
|
|
55
56
|
...document.disclosure.map((item) => `Disclosure: ${item}`),
|
|
57
|
+
'',
|
|
58
|
+
`Output format: ${document.persistence.output}`,
|
|
59
|
+
`Checkpoint: ${document.persistence.checkpoint ? 'enabled' : 'not written'}. ${document.persistence.note}`,
|
|
60
|
+
...(document.review.allowlistAffectsPriorityOnly ? ['Allowlist: affects review priority only; it does not exclude targets from collection.'] : []),
|
|
61
|
+
'Enforcement: none. This plan does not report, block or remove a target.',
|
|
62
|
+
'',
|
|
56
63
|
...document.limitations.map((item) => `Limitation: ${item}`),
|
|
57
64
|
'',
|
|
58
65
|
].join('\n');
|