@visulima/vis 6.1.0 → 6.1.2
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/CHANGELOG.md +49 -0
- package/dist/bin.js +1 -1
- package/dist/binx.js +1 -1
- package/dist/config/index.d.ts +1226 -1216
- package/dist/packem_chunks/bloom-sync.js +1 -1
- package/dist/packem_chunks/cargo-lock.js +5 -0
- package/dist/packem_chunks/cargo-plan.js +3 -3
- package/dist/packem_chunks/catalog-detector.js +1 -1
- package/dist/packem_chunks/catalog.js +1 -94
- package/dist/packem_chunks/catalog2.js +11 -0
- package/dist/packem_chunks/cli-exec.js +1 -1
- package/dist/packem_chunks/cli-main.js +156 -174
- package/dist/packem_chunks/context.js +8 -0
- package/dist/packem_chunks/fix.js +1 -1
- package/dist/packem_chunks/handler10.js +1 -1
- package/dist/packem_chunks/handler12.js +1 -1
- package/dist/packem_chunks/handler13.js +1 -1
- package/dist/packem_chunks/handler14.js +1 -1
- package/dist/packem_chunks/handler15.js +1 -1
- package/dist/packem_chunks/handler19.js +5 -5
- package/dist/packem_chunks/handler2.js +1 -1
- package/dist/packem_chunks/handler20.js +1 -1
- package/dist/packem_chunks/handler21.js +1 -1
- package/dist/packem_chunks/handler23.js +1 -1
- package/dist/packem_chunks/handler24.js +1 -1
- package/dist/packem_chunks/handler25.js +1 -1
- package/dist/packem_chunks/handler28.js +1 -1
- package/dist/packem_chunks/handler3.js +1 -1
- package/dist/packem_chunks/handler31.js +1 -1
- package/dist/packem_chunks/handler32.js +1 -1
- package/dist/packem_chunks/handler33.js +1 -1
- package/dist/packem_chunks/handler34.js +3 -3
- package/dist/packem_chunks/handler35.js +1 -1
- package/dist/packem_chunks/handler36.js +1 -1
- package/dist/packem_chunks/handler38.js +2 -2
- package/dist/packem_chunks/handler39.js +5 -5
- package/dist/packem_chunks/handler4.js +4 -4
- package/dist/packem_chunks/handler40.js +1 -1
- package/dist/packem_chunks/handler41.js +1 -1
- package/dist/packem_chunks/handler42.js +1 -1
- package/dist/packem_chunks/handler43.js +1 -1
- package/dist/packem_chunks/handler44.js +1 -1
- package/dist/packem_chunks/handler45.js +1 -1
- package/dist/packem_chunks/handler46.js +1 -1
- package/dist/packem_chunks/handler47.js +1 -1
- package/dist/packem_chunks/handler48.js +1 -1
- package/dist/packem_chunks/handler49.js +1 -1
- package/dist/packem_chunks/handler5.js +4 -4
- package/dist/packem_chunks/handler50.js +5 -5
- package/dist/packem_chunks/handler52.js +1 -1
- package/dist/packem_chunks/handler54.js +2 -2
- package/dist/packem_chunks/handler55.js +1 -1
- package/dist/packem_chunks/handler56.js +3 -3
- package/dist/packem_chunks/handler57.js +4 -4
- package/dist/packem_chunks/handler58.js +4 -4
- package/dist/packem_chunks/handler59.js +2 -2
- package/dist/packem_chunks/handler6.js +7 -7
- package/dist/packem_chunks/handler60.js +1 -1
- package/dist/packem_chunks/handler61.js +2 -2
- package/dist/packem_chunks/handler62.js +1 -1
- package/dist/packem_chunks/handler63.js +3 -3
- package/dist/packem_chunks/handler64.js +3 -3
- package/dist/packem_chunks/handler65.js +2 -2
- package/dist/packem_chunks/handler66.js +2 -2
- package/dist/packem_chunks/handler67.js +5 -5
- package/dist/packem_chunks/handler68.js +12 -25
- package/dist/packem_chunks/handler69.js +25 -22
- package/dist/packem_chunks/handler70.js +22 -10
- package/dist/packem_chunks/handler71.js +10 -133
- package/dist/packem_chunks/handler72.js +133 -23
- package/dist/packem_chunks/handler73.js +23 -323
- package/dist/packem_chunks/handler74.js +274 -659
- package/dist/packem_chunks/handler75.js +708 -48
- package/dist/packem_chunks/handler76.js +48 -27
- package/dist/packem_chunks/handler77.js +27 -3
- package/dist/packem_chunks/handler78.js +3 -191
- package/dist/packem_chunks/handler79.js +191 -0
- package/dist/packem_chunks/handler8.js +1 -1
- package/dist/packem_chunks/heal.js +2 -2
- package/dist/packem_chunks/help-command.js +1 -1
- package/dist/packem_chunks/index2.js +3 -58
- package/dist/packem_chunks/index3.js +40 -3
- package/dist/packem_chunks/index6.js +135 -7
- package/dist/packem_chunks/index7.js +7 -135
- package/dist/packem_chunks/keys-refresh.js +1 -1
- package/dist/packem_chunks/list.js +2 -2
- package/dist/packem_chunks/prune.js +1 -1
- package/dist/packem_chunks/python-plan.js +3 -3
- package/dist/packem_chunks/python-projects.js +1 -1
- package/dist/packem_chunks/python.js +1 -0
- package/dist/packem_chunks/run.js +1 -1
- package/dist/packem_chunks/snapshot.js +2 -2
- package/dist/packem_chunks/state.js +2 -2
- package/dist/packem_chunks/status.js +1 -1
- package/dist/packem_chunks/sync.js +1 -1
- package/dist/packem_chunks/verify-lockfile.js +1 -1
- package/dist/packem_chunks/version-resolver.js +1 -1
- package/dist/packem_chunks/workspace.js +2 -2
- package/dist/packem_shared/ReleaseClient-CWD9BC5w.js +1 -0
- package/dist/packem_shared/advisories-DO-P0V1_.js +1 -0
- package/dist/packem_shared/{affected-selection-DGb6Xu5K.js → affected-selection-CeeZo7Uy.js} +1 -1
- package/dist/packem_shared/{ai-analysis-pldoS_N4.js → ai-analysis-BCJ1kuDM.js} +3 -3
- package/dist/packem_shared/ai-cache-iSIyY3So.js +1 -0
- package/dist/packem_shared/{ai-fix-D9MxigBQ.js → ai-fix-DIMErSws.js} +6 -6
- package/dist/packem_shared/apply-DoeQAAGm.js +6 -0
- package/dist/packem_shared/apply-release-plan-BalHtK-g.js +15 -0
- package/dist/packem_shared/{bin-AZQv95jh.js → bin-BcLTer1k.js} +1 -1
- package/dist/packem_shared/clean-package-json-rutwkKl-.js +1 -0
- package/dist/packem_shared/createAdapter-DMK4bBET.js +1 -0
- package/dist/packem_shared/createVersionActions-DXo4z8VN.js +1 -0
- package/dist/packem_shared/dependency-scan-D_v3KM59.js +1 -0
- package/dist/packem_shared/{ecosystem-gate-DiqQj0LJ.js → ecosystem-gate-CwsTc7YW.js} +1 -1
- package/dist/packem_shared/env-BSXG3QKH.js +4 -0
- package/dist/packem_shared/failure-log-DIsKBKaI.js +2 -0
- package/dist/packem_shared/formatBytes-_HvjOy8a-iHCer6uX.js +1 -0
- package/dist/packem_shared/glob-Cyk1H9ZL-CL9optrn.js +1 -0
- package/dist/packem_shared/{index-JRb5wabN.js → index-9Ot7jTd4.js} +1 -1
- package/dist/packem_shared/index-BS6A9QR_.js +1 -0
- package/dist/packem_shared/lifecycle-CQjeMPY0.js +2 -0
- package/dist/packem_shared/missing-package-json-1BIoWQq0.js +1 -0
- package/dist/packem_shared/multi-eco-lockfiles-fgkpeHJv.js +1 -0
- package/dist/packem_shared/npmrc-CHsOyMvA.js +2 -0
- package/dist/packem_shared/osv-Do9PMOea.js +1 -0
- package/dist/packem_shared/{package-version-KLwH0Ivy.js → package-version-Bq6Cne_7.js} +1 -1
- package/dist/packem_shared/packument-CbTmbHU4.js +1 -0
- package/dist/packem_shared/{project-name-filter-B1ZCsbOW.js → project-name-filter-ZQaLgytG.js} +1 -1
- package/dist/packem_shared/{provenance-L1M2FPy_.js → provenance-SX1MxPUZ.js} +1 -1
- package/dist/packem_shared/publish-Dc0XGH3K.js +34 -0
- package/dist/packem_shared/registry-Dg9XI6RT.js +81 -0
- package/dist/packem_shared/registry-keys-z038Ecb4.js +1 -0
- package/dist/packem_shared/removeSync-g1D5kONg-LbjATA8v.js +1 -0
- package/dist/packem_shared/renderToString-DR0zDUjh-DXppT6AM.js +3 -0
- package/dist/packem_shared/{resolve-explicit-CQa37JSq.js → resolve-explicit-D9kdTNvl.js} +1 -1
- package/dist/packem_shared/{run-D-uVGHQ4.js → run-DLvd3RIZ.js} +1 -1
- package/dist/packem_shared/run-summary-utils-CMeURYtS.js +1 -0
- package/dist/packem_shared/s1ngularity-BuU9Cxpy.js +1 -0
- package/dist/packem_shared/{scaffold-files-DVyfB0yz.js → scaffold-files-DJlz36Mu.js} +1 -1
- package/dist/packem_shared/scan-progress-DymX71_5.js +2 -0
- package/dist/packem_shared/{signatures-DIqFUOfs.js → signatures-CeL0bOEo.js} +1 -1
- package/dist/packem_shared/spinner-CPoBymcv.js +1 -0
- package/dist/packem_shared/table-oA7p7-yP.js +1 -0
- package/dist/packem_shared/tabs-BiSifphV.js +1 -0
- package/dist/packem_shared/{task-env-DzR4RkOj.js → task-env-C2lmxvzA.js} +1 -1
- package/dist/packem_shared/typosquats-BFKus_aM.js +1 -0
- package/dist/packem_shared/use-measured-height-BHm-HiSF.js +1 -0
- package/dist/packem_shared/vis-update-app-6QOYxnNx.js +1 -0
- package/dist/packem_shared/{vis-user-error-CRmrBaD1.js → vis-user-error-3YS7sPYy.js} +1 -1
- package/dist/packem_shared/{watch-loop-D1_e-qIl.js → watch-loop-CGi66Fs0.js} +1 -1
- package/dist/packem_shared/xxh3-BLHlvhgT.js +1 -0
- package/dist/release/core/package-managers/index.js +1 -1
- package/dist/release/core/version-actions/index.js +1 -1
- package/dist/release/index.js +1 -1
- package/index.js +26 -26
- package/package.json +9 -9
- package/dist/packem_chunks/orchestrator.js +0 -46
- package/dist/packem_shared/ReleaseClient-DAvbxCdo.js +0 -1
- package/dist/packem_shared/createAdapter-F7GidOzU.js +0 -1
- package/dist/packem_shared/createVersionActions-ByaJ1Nbv.js +0 -1
- package/dist/packem_shared/dependency-scan-CawAKoU_.js +0 -1
- package/dist/packem_shared/failure-log-BP-gCUb5.js +0 -2
- package/dist/packem_shared/formatBytes-_HvjOy8a-B_qQr4Hw.js +0 -4
- package/dist/packem_shared/glob-Cyk1H9ZL-Dxlf9Swz.js +0 -1
- package/dist/packem_shared/index-CDHP1kby.js +0 -1
- package/dist/packem_shared/lifecycle-DvmDIRbb.js +0 -2
- package/dist/packem_shared/missing-package-json-Cu5YVAot.js +0 -1
- package/dist/packem_shared/multi-eco-lockfiles-B2X3yhyo.js +0 -1
- package/dist/packem_shared/packument-zb18Jnlw.js +0 -1
- package/dist/packem_shared/registry-keys-DxdqMzyp.js +0 -1
- package/dist/packem_shared/s1ngularity-CO5GkkqX.js +0 -1
- package/dist/packem_shared/scan-progress-RwCRxJdX.js +0 -2
- package/dist/packem_shared/spinner-BJjbNl1F.js +0 -1
- package/dist/packem_shared/tabs--uxJGL8N.js +0 -1
- package/dist/packem_shared/typosquats-D4DEHhFy.js +0 -1
- package/dist/packem_shared/use-measured-height-DUZyyias.js +0 -1
- package/dist/packem_shared/vis-update-app-9b2kSk9f.js +0 -1
package/dist/config/index.d.ts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
1
|
import { TargetConfiguration, ChildEnvOptions, TaskResult, Task, FingerprintContributor, ConstraintsConfig, NamedInputs, TaskRunnerOptions } from '@visulima/task-runner';
|
|
2
2
|
export type { FingerprintContributor } from '@visulima/task-runner';
|
|
3
3
|
import { VisReleaseConfig } from "../release/types.js";
|
|
4
|
-
/**
|
|
5
|
-
* One family of upstream-coupled packages.
|
|
6
|
-
*
|
|
7
|
-
* `members` is an exact-match list. `prefixes` accept any dep whose
|
|
8
|
-
* name starts with the prefix — useful for monorepos that ship many
|
|
9
|
-
* subpackages under one scope (e.g. `@babel/`, `@storybook/`,
|
|
10
|
-
* `@nx/`). A family can use either or both; a dep matching either
|
|
11
|
-
* list belongs to the family.
|
|
12
|
-
*/
|
|
13
|
-
interface SimilarDepFamily {
|
|
14
|
-
/** Stable id; used in report output and config overrides. */
|
|
15
|
-
id: string;
|
|
16
|
-
/** Pretty label for the report. Defaults to `id` when omitted. */
|
|
17
|
-
label?: string;
|
|
18
|
-
/** Dep names that belong to this family verbatim. */
|
|
19
|
-
members?: string[];
|
|
20
|
-
/** Dep-name prefixes (literal, no glob). Match if `depName.startsWith(prefix)`. */
|
|
21
|
-
prefixes?: string[];
|
|
22
|
-
}
|
|
23
4
|
/** Adapter IDs that can format (adapter `kind` is `"fmt"` or `"both"`). */
|
|
24
5
|
type FmtAdapterId = "biome" | "dprint" | "oxfmt" | "prettier" | "ruff-fmt";
|
|
25
6
|
/** Adapter IDs that can lint (adapter `kind` is `"lint"` or `"both"`). */
|
|
@@ -693,33 +674,6 @@ interface VisPlugin {
|
|
|
693
674
|
*/
|
|
694
675
|
setup?: (hooks: Hookable<VisHooks>) => Promise<void> | void;
|
|
695
676
|
}
|
|
696
|
-
/**
|
|
697
|
-
* Per-adapter override applied by `vis lint` / `vis fmt`. Keyed by
|
|
698
|
-
* adapter id under `lint.adapters` / `fmt.adapters`. Every field is
|
|
699
|
-
* optional — set only what you need to change.
|
|
700
|
-
*/
|
|
701
|
-
interface LintFmtAdapterOverride {
|
|
702
|
-
/**
|
|
703
|
-
* Set to `false` to skip this adapter even when its config file or
|
|
704
|
-
* package.json entry is detected. Defaults to `true` (run when
|
|
705
|
-
* detected).
|
|
706
|
-
*/
|
|
707
|
-
enabled?: boolean;
|
|
708
|
-
/**
|
|
709
|
-
* Extra arguments appended verbatim to every invocation of this
|
|
710
|
-
* adapter. Useful for tool-specific flags vis doesn't expose
|
|
711
|
-
* directly (e.g. `eslint --rulesdir`).
|
|
712
|
-
*/
|
|
713
|
-
extraArgs?: string[];
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* The 8 Socket.dev-style supply-chain policies. Used in `security.policies`
|
|
717
|
-
* and `security.acceptedRisks[*].policies`. Kept as a const tuple so callers
|
|
718
|
-
* can import the runtime array (`POLICY_NAMES`) for iteration without
|
|
719
|
-
* drifting from the union type.
|
|
720
|
-
*/
|
|
721
|
-
declare const POLICY_NAMES: readonly ["firstSeen", "installScripts", "license", "malware", "publisherChange", "score", "unexpectedDeps", "vulnerability"];
|
|
722
|
-
type PolicyName = (typeof POLICY_NAMES)[number];
|
|
723
677
|
/**
|
|
724
678
|
* Recognised input sources for the codeowners aggregator.
|
|
725
679
|
*
|
|
@@ -762,6 +716,56 @@ interface CodeownersConfig {
|
|
|
762
716
|
/** Enabled input sources. Defaults to `["project-json"]`. */
|
|
763
717
|
sources?: CodeownersSource[];
|
|
764
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* Declared code-owner assignment for a path glob within a project.
|
|
721
|
+
* Mirrors moon's `owners` shape so migrations can round-trip cleanly.
|
|
722
|
+
*/
|
|
723
|
+
interface OwnersEntry {
|
|
724
|
+
/** Optional notification channel (e.g. Slack, Teams). */
|
|
725
|
+
channel?: string;
|
|
726
|
+
/** Owner handles (e.g. `@visulima/core-team`). */
|
|
727
|
+
owners: string[];
|
|
728
|
+
/** File/glob pattern relative to the project root. */
|
|
729
|
+
path: string;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Per-adapter override applied by `vis lint` / `vis fmt`. Keyed by
|
|
733
|
+
* adapter id under `lint.adapters` / `fmt.adapters`. Every field is
|
|
734
|
+
* optional — set only what you need to change.
|
|
735
|
+
*/
|
|
736
|
+
interface LintFmtAdapterOverride {
|
|
737
|
+
/**
|
|
738
|
+
* Set to `false` to skip this adapter even when its config file or
|
|
739
|
+
* package.json entry is detected. Defaults to `true` (run when
|
|
740
|
+
* detected).
|
|
741
|
+
*/
|
|
742
|
+
enabled?: boolean;
|
|
743
|
+
/**
|
|
744
|
+
* Extra arguments appended verbatim to every invocation of this
|
|
745
|
+
* adapter. Useful for tool-specific flags vis doesn't expose
|
|
746
|
+
* directly (e.g. `eslint --rulesdir`).
|
|
747
|
+
*/
|
|
748
|
+
extraArgs?: string[];
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* One family of upstream-coupled packages.
|
|
752
|
+
*
|
|
753
|
+
* `members` is an exact-match list. `prefixes` accept any dep whose
|
|
754
|
+
* name starts with the prefix — useful for monorepos that ship many
|
|
755
|
+
* subpackages under one scope (e.g. `@babel/`, `@storybook/`,
|
|
756
|
+
* `@nx/`). A family can use either or both; a dep matching either
|
|
757
|
+
* list belongs to the family.
|
|
758
|
+
*/
|
|
759
|
+
interface SimilarDepFamily {
|
|
760
|
+
/** Stable id; used in report output and config overrides. */
|
|
761
|
+
id: string;
|
|
762
|
+
/** Pretty label for the report. Defaults to `id` when omitted. */
|
|
763
|
+
label?: string;
|
|
764
|
+
/** Dep names that belong to this family verbatim. */
|
|
765
|
+
members?: string[];
|
|
766
|
+
/** Dep-name prefixes (literal, no glob). Match if `depName.startsWith(prefix)`. */
|
|
767
|
+
prefixes?: string[];
|
|
768
|
+
}
|
|
765
769
|
/**
|
|
766
770
|
* One user-declared customTypes entry. See `policy.customTypes.extraTypes`
|
|
767
771
|
* for the full contract — this is just the row shape.
|
|
@@ -788,18 +792,6 @@ interface ExtraCustomType {
|
|
|
788
792
|
*/
|
|
789
793
|
strategy: "name@version" | "name~version" | "string" | "versionsByName";
|
|
790
794
|
}
|
|
791
|
-
/**
|
|
792
|
-
* Declared code-owner assignment for a path glob within a project.
|
|
793
|
-
* Mirrors moon's `owners` shape so migrations can round-trip cleanly.
|
|
794
|
-
*/
|
|
795
|
-
interface OwnersEntry {
|
|
796
|
-
/** Optional notification channel (e.g. Slack, Teams). */
|
|
797
|
-
channel?: string;
|
|
798
|
-
/** Owner handles (e.g. `@visulima/core-team`). */
|
|
799
|
-
owners: string[];
|
|
800
|
-
/** File/glob pattern relative to the project root. */
|
|
801
|
-
path: string;
|
|
802
|
-
}
|
|
803
795
|
/**
|
|
804
796
|
* Per-project TypeScript overlay loaded from `vis.task.ts`. Adds a
|
|
805
797
|
* dynamic, type-safe layer for target overrides on top of `project.json`,
|
|
@@ -877,22 +869,6 @@ interface ProjectJson {
|
|
|
877
869
|
/** Vis-style target definitions (merged on top of package.json scripts). */
|
|
878
870
|
targets?: Record<string, VisTargetConfiguration>;
|
|
879
871
|
}
|
|
880
|
-
/**
|
|
881
|
-
* A predicate used by {@link VisConfig.scopedTasks}.
|
|
882
|
-
* All listed constraints must match for the block to apply.
|
|
883
|
-
*/
|
|
884
|
-
interface ScopedTasksMatch {
|
|
885
|
-
/** Match on primary language. */
|
|
886
|
-
language?: string | string[];
|
|
887
|
-
/** Match on project layer. */
|
|
888
|
-
layer?: ProjectJson["layer"] | ProjectJson["layer"][];
|
|
889
|
-
/** Match on project type. */
|
|
890
|
-
projectType?: "application" | "library" | "service" | "tool";
|
|
891
|
-
/** Match on project stack. */
|
|
892
|
-
stack?: ProjectJson["stack"] | ProjectJson["stack"][];
|
|
893
|
-
/** Match projects tagged with any of these tags. */
|
|
894
|
-
tags?: string[];
|
|
895
|
-
}
|
|
896
872
|
/**
|
|
897
873
|
* A single scoped-tasks block — a set of task defaults gated by an
|
|
898
874
|
* optional match predicate.
|
|
@@ -903,104 +879,1167 @@ interface ScopedTasksBlock {
|
|
|
903
879
|
/** Task default configurations, keyed by target name. */
|
|
904
880
|
tasks: Record<string, Partial<VisTargetConfiguration>>;
|
|
905
881
|
}
|
|
906
|
-
|
|
882
|
+
/**
|
|
883
|
+
* The 8 Socket.dev-style supply-chain policies. Used in `security.policies`
|
|
884
|
+
* and `security.acceptedRisks[*].policies`. Kept as a const tuple so callers
|
|
885
|
+
* can import the runtime array (`POLICY_NAMES`) for iteration without
|
|
886
|
+
* drifting from the union type.
|
|
887
|
+
*/
|
|
888
|
+
declare const POLICY_NAMES: readonly ["firstSeen", "installScripts", "license", "malware", "publisherChange", "score", "unexpectedDeps", "vulnerability"];
|
|
889
|
+
type PolicyName = (typeof POLICY_NAMES)[number];
|
|
890
|
+
interface VisPolicyConfig {
|
|
907
891
|
/**
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
* By default a changed file that belongs to no project (a root
|
|
913
|
-
* `tsconfig.json`, `package.json`, …) is a global change and marks every
|
|
914
|
-
* project affected. A changed file matching one of these patterns is
|
|
915
|
-
* skipped instead. The patterns are only checked for files that belong
|
|
916
|
-
* to NO project: a file inside a project root is never filtered, so a
|
|
917
|
-
* broad pattern like `*.md` cannot hide a real package change.
|
|
918
|
-
*
|
|
919
|
-
* Patterns use `path.matchesGlob` syntax, where `*` does not cross `/`:
|
|
920
|
-
* `*.md` matches `README.md` but not `docs/guide.md`.
|
|
892
|
+
* Map of dep names or globs → reason (or `{ reason, replacement, packages?, paths? }`).
|
|
893
|
+
* Internal/workspace deps are never flagged here; the
|
|
894
|
+
* workspace-protocol lint owns those.
|
|
921
895
|
*
|
|
922
|
-
*
|
|
923
|
-
*
|
|
924
|
-
*
|
|
925
|
-
*
|
|
896
|
+
* Optional `packages` (globs over the declaring package's `name`) and
|
|
897
|
+
* `paths` (globs over the workspace-relative `packageDir`) narrow where
|
|
898
|
+
* the rule applies. With both set, either match is enough. Omit both
|
|
899
|
+
* to ban anywhere — the default.
|
|
900
|
+
* @example
|
|
901
|
+
* ```
|
|
902
|
+
* bannedDeps: {
|
|
903
|
+
* request: "deprecated; use undici",
|
|
904
|
+
* moment: { reason: "huge bundle, frozen upstream", replacement: "date-fns" },
|
|
905
|
+
* "@radix-ui/*": "we standardized on shadcn",
|
|
906
|
+
* react: { reason: "no react in shared libs", paths: ["packages/shared/*"] },
|
|
907
|
+
* "next": { reason: "apps only", packages: ["@app/*"] },
|
|
908
|
+
* }
|
|
909
|
+
* ```
|
|
926
910
|
*/
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
priority?: Record<string, number>;
|
|
934
|
-
/** Use a specific provider instead of auto-detecting (e.g., `"claude"`, `"gemini"`). */
|
|
935
|
-
provider?: string;
|
|
936
|
-
};
|
|
911
|
+
bannedDeps?: Record<string, string | {
|
|
912
|
+
packages?: string[];
|
|
913
|
+
paths?: string[];
|
|
914
|
+
reason: string;
|
|
915
|
+
replacement?: string;
|
|
916
|
+
}>;
|
|
937
917
|
/**
|
|
938
|
-
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
* generated artefacts (schemas, `.d.ts` snapshots) that legitimately
|
|
942
|
-
* differ across branches no longer oscillate the cache contents.
|
|
918
|
+
* Tweak the custom-types lint that flags drift in `engines.{node,pnpm,...}`,
|
|
919
|
+
* `packageManager`, `volta.{node,pnpm,yarn}`, and the proposed
|
|
920
|
+
* `devEngines.{runtime,packageManager}` array form.
|
|
943
921
|
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
*
|
|
922
|
+
* Each (customType × name) cluster is tracked independently —
|
|
923
|
+
* `engines.node` and `volta.node` don't cross-couple here. Use a
|
|
924
|
+
* versionGroup once that lands if you need to enforce they agree.
|
|
947
925
|
*/
|
|
948
|
-
|
|
926
|
+
customTypes?: {
|
|
927
|
+
/**
|
|
928
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
929
|
+
* for the contract — same semantics, applied to drift rewrites
|
|
930
|
+
* across engines / packageManager / volta / devEngines.
|
|
931
|
+
*
|
|
932
|
+
* Note: `--fix` strips any `+sha512.<hash>` suffix from
|
|
933
|
+
* `packageManager` on bump — content-integrity hashes are tied
|
|
934
|
+
* to a specific package, not a version, so users must regenerate
|
|
935
|
+
* via their PM (`pnpm install` re-pins; `corepack use pnpm@X` etc.).
|
|
936
|
+
* @default true
|
|
937
|
+
*/
|
|
938
|
+
autofix?: "prompt" | boolean;
|
|
939
|
+
/**
|
|
940
|
+
* User-defined custom-type pin locations. Each entry tells the
|
|
941
|
+
* customTypes lint to read additional version pins from a
|
|
942
|
+
* non-standard JSON path inside every workspace package.json,
|
|
943
|
+
* cluster them by `(name × depName)` like the built-in types,
|
|
944
|
+
* and rewrite them with `--fix`.
|
|
945
|
+
*
|
|
946
|
+
* The original built-ins (`engines`, `volta`, `packageManager`,
|
|
947
|
+
* `devEngines.runtime`, `devEngines.packageManager`) keep
|
|
948
|
+
* running unconditionally — these layer on top.
|
|
949
|
+
*
|
|
950
|
+
* Strategies:
|
|
951
|
+
* - `versionsByName`: the JSON at `path` is `{ [depName]: version }`
|
|
952
|
+
* (like `engines` or `pnpm.overrides`).
|
|
953
|
+
* - `name@version`: the JSON at `path` is a string of the form
|
|
954
|
+
* `name@version` (like `packageManager`). The leading `name@`
|
|
955
|
+
* is preserved; only the version segment is rewritten.
|
|
956
|
+
* - `string`: the JSON at `path` is a bare version string. The
|
|
957
|
+
* `depName` field is required and identifies the dep cluster.
|
|
958
|
+
*
|
|
959
|
+
* `name` must not collide with a built-in type name. `path` is
|
|
960
|
+
* a dot-separated walk into the package.json (e.g. `pnpm.overrides`).
|
|
961
|
+
* @example
|
|
962
|
+
* ```ts
|
|
963
|
+
* extraTypes: [
|
|
964
|
+
* { name: "pnpmOverridesLegacy", path: "pnpm.overrides", strategy: "versionsByName" },
|
|
965
|
+
* { name: "myToolPin", path: "myTool.runtime", strategy: "name@version" },
|
|
966
|
+
* { name: "minNode", path: "config.minNode", strategy: "string", depName: "node" },
|
|
967
|
+
* ]
|
|
968
|
+
* ```
|
|
969
|
+
*/
|
|
970
|
+
extraTypes?: ExtraCustomType[];
|
|
971
|
+
/**
|
|
972
|
+
* Dep names exempt from the drift check (exact match against the
|
|
973
|
+
* field name within the block — e.g. `node`, `pnpm`).
|
|
974
|
+
*/
|
|
975
|
+
ignore?: string[];
|
|
976
|
+
/**
|
|
977
|
+
* Resolution strategy used when `--fix` runs.
|
|
978
|
+
* - `highest` (default): align every drifting instance to the
|
|
979
|
+
* highest declared version.
|
|
980
|
+
* - `lowest`: align to the lowest.
|
|
981
|
+
* @default "highest"
|
|
982
|
+
*/
|
|
983
|
+
resolve?: "highest" | "lowest";
|
|
984
|
+
};
|
|
949
985
|
/**
|
|
950
|
-
*
|
|
951
|
-
*
|
|
986
|
+
* Tweak the dead-workspace-patterns lint that flags entries in
|
|
987
|
+
* `pnpm-workspace.yaml#packages` / `package.json#workspaces` which
|
|
988
|
+
* resolve to zero on-disk directories.
|
|
952
989
|
*/
|
|
953
|
-
|
|
990
|
+
deadWorkspacePatterns?: {
|
|
991
|
+
/**
|
|
992
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
993
|
+
* for the contract — applied here to dropping unmatched patterns
|
|
994
|
+
* from the workspace config file.
|
|
995
|
+
* @default true
|
|
996
|
+
*/
|
|
997
|
+
autofix?: "prompt" | boolean;
|
|
998
|
+
};
|
|
954
999
|
/**
|
|
955
|
-
*
|
|
956
|
-
*
|
|
1000
|
+
* Tweak the empty-deps lint that flags empty `dependencies` /
|
|
1001
|
+
* `devDependencies` / `peerDependencies` / `optionalDependencies`
|
|
1002
|
+
* blocks across the workspace.
|
|
957
1003
|
*/
|
|
958
|
-
|
|
959
|
-
|
|
1004
|
+
emptyDeps?: {
|
|
1005
|
+
/**
|
|
1006
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1007
|
+
* for the contract — applied here to removing the empty key.
|
|
1008
|
+
* @default true
|
|
1009
|
+
*/
|
|
1010
|
+
autofix?: "prompt" | boolean;
|
|
1011
|
+
/**
|
|
1012
|
+
* Block names exempt from the rule (e.g. `["peerDependencies"]`
|
|
1013
|
+
* to keep the key around as a marker even when empty).
|
|
1014
|
+
*/
|
|
1015
|
+
ignoreBlocks?: ("dependencies" | "devDependencies" | "optionalDependencies" | "peerDependencies")[];
|
|
960
1016
|
};
|
|
961
1017
|
/**
|
|
962
|
-
*
|
|
963
|
-
*
|
|
1018
|
+
* Tweak the redefine-root lint that flags non-root packages duplicating
|
|
1019
|
+
* deps already pinned at the workspace root.
|
|
964
1020
|
*/
|
|
965
|
-
|
|
1021
|
+
redefineRoot?: {
|
|
1022
|
+
/** Dep names that are exempt from the redefine-root rule (exact match). */
|
|
1023
|
+
ignore?: string[];
|
|
1024
|
+
};
|
|
966
1025
|
/**
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
* post-creation behavior.
|
|
1026
|
+
* Tweak the root-deps lint that flags runtime `dependencies` declared
|
|
1027
|
+
* on the private workspace root (they should live in `devDependencies`).
|
|
970
1028
|
*/
|
|
971
|
-
|
|
1029
|
+
rootDeps?: {
|
|
972
1030
|
/**
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
*
|
|
1031
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1032
|
+
* for the contract — applied here to moving entries from
|
|
1033
|
+
* `dependencies` to `devDependencies` on the root package.json.
|
|
1034
|
+
* @default true
|
|
976
1035
|
*/
|
|
977
|
-
|
|
1036
|
+
autofix?: "prompt" | boolean;
|
|
1037
|
+
};
|
|
1038
|
+
/**
|
|
1039
|
+
* Tweak the root-package-manager lint that flags a missing or
|
|
1040
|
+
* malformed `packageManager` field on the workspace root.
|
|
1041
|
+
*/
|
|
1042
|
+
rootPackageManager?: {
|
|
978
1043
|
/**
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
1044
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1045
|
+
* for the contract. `--fix` only writes when `suggested` is set —
|
|
1046
|
+
* a missing `packageManager` field has no canonical default.
|
|
1047
|
+
* @default true
|
|
982
1048
|
*/
|
|
983
|
-
|
|
1049
|
+
autofix?: "prompt" | boolean;
|
|
984
1050
|
/**
|
|
985
|
-
*
|
|
986
|
-
*
|
|
1051
|
+
* Canonical specifier (`name@version`) to write when `--fix` runs
|
|
1052
|
+
* and the field is absent. Required to enable autofix —
|
|
1053
|
+
* vis won't guess the workspace's preferred manager.
|
|
1054
|
+
* @example "pnpm@10.32.1"
|
|
987
1055
|
*/
|
|
988
|
-
|
|
1056
|
+
suggested?: string;
|
|
1057
|
+
};
|
|
1058
|
+
/**
|
|
1059
|
+
* Tweak the root-private lint that flags a workspace root package.json
|
|
1060
|
+
* missing `"private": true`. Only fires when the root looks like a
|
|
1061
|
+
* workspace (npm/yarn/bun `workspaces` field or `pnpm-workspace.yaml`).
|
|
1062
|
+
*/
|
|
1063
|
+
rootPrivate?: {
|
|
989
1064
|
/**
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1065
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1066
|
+
* for the contract — applied here to inserting `"private": true`.
|
|
1067
|
+
* @default true
|
|
992
1068
|
*/
|
|
993
|
-
|
|
1069
|
+
autofix?: "prompt" | boolean;
|
|
1070
|
+
};
|
|
1071
|
+
/**
|
|
1072
|
+
* Tweak the similar-deps lint that flags drift across related dep
|
|
1073
|
+
* families (e.g. `react` and `react-dom`, all of `@babel/*`).
|
|
1074
|
+
*
|
|
1075
|
+
* The lint is report-only — aligning a family requires picking a
|
|
1076
|
+
* single canonical specifier across heterogeneous range syntaxes
|
|
1077
|
+
* (`^`, `~`, exact), which is too lossy without user input.
|
|
1078
|
+
*/
|
|
1079
|
+
similarDeps?: {
|
|
994
1080
|
/**
|
|
995
|
-
*
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
*
|
|
1081
|
+
* Additional families merged with the built-ins. Same `id` wins
|
|
1082
|
+
* → user override fully replaces the built-in entry.
|
|
1083
|
+
* @example
|
|
1084
|
+
* ```
|
|
1085
|
+
* extraFamilies: [
|
|
1086
|
+
* { id: "vue", label: "Vue", members: ["vue", "vue-router", "pinia"] },
|
|
1087
|
+
* ]
|
|
1088
|
+
* ```
|
|
999
1089
|
*/
|
|
1000
|
-
|
|
1090
|
+
extraFamilies?: SimilarDepFamily[];
|
|
1091
|
+
/** Family ids to skip entirely (matches `SimilarDepFamily.id`). */
|
|
1092
|
+
ignoreFamilies?: string[];
|
|
1093
|
+
};
|
|
1094
|
+
/**
|
|
1095
|
+
* Tweak the types-in-deps lint that flags `@types/*` declared in
|
|
1096
|
+
* `dependencies` on a private package (they belong in
|
|
1097
|
+
* `devDependencies` since the package never ships).
|
|
1098
|
+
*/
|
|
1099
|
+
typesInDeps?: {
|
|
1001
1100
|
/**
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1101
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1102
|
+
* for the contract — applied here to moving the entry to
|
|
1103
|
+
* `devDependencies`. Existing dev pins are preserved on conflict.
|
|
1104
|
+
* @default true
|
|
1105
|
+
*/
|
|
1106
|
+
autofix?: "prompt" | boolean;
|
|
1107
|
+
/** Dep names exempt from the rule (exact match, e.g. `@types/node`). */
|
|
1108
|
+
ignore?: string[];
|
|
1109
|
+
};
|
|
1110
|
+
/**
|
|
1111
|
+
* Tweak the workspace-protocol lint that flags internal deps not
|
|
1112
|
+
* using the `workspace:` protocol.
|
|
1113
|
+
*/
|
|
1114
|
+
workspaceProtocol?: {
|
|
1115
|
+
/**
|
|
1116
|
+
* Three-state autofix opt-out. Some workspaces want detection
|
|
1117
|
+
* without rewrite (e.g. dual-licensed packages where `workspace:*`
|
|
1118
|
+
* is unsafe).
|
|
1119
|
+
* - `true` (default): `--fix` rewrites the specifier.
|
|
1120
|
+
* - `false`: never rewrite — report the violation only.
|
|
1121
|
+
* - `"prompt"`: ask before each rewrite. Falls back to report-only
|
|
1122
|
+
* when stdin isn't a TTY (CI). Reserved; not yet implemented.
|
|
1123
|
+
*
|
|
1124
|
+
* Note: when `false` (or `"prompt"`), `--fix` still **fails CI** on
|
|
1125
|
+
* detected violations — the rule is "report only", not "ignore".
|
|
1126
|
+
* Drop the rule from the lint selection if you want a clean exit.
|
|
1127
|
+
* @default true
|
|
1128
|
+
* @example
|
|
1129
|
+
* ```
|
|
1130
|
+
* policy: {
|
|
1131
|
+
* workspaceProtocol: { autofix: false },
|
|
1132
|
+
* }
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
autofix?: "prompt" | boolean;
|
|
1136
|
+
};
|
|
1137
|
+
/**
|
|
1138
|
+
* Tweak the workspace-versions lint that flags external deps declared
|
|
1139
|
+
* at inconsistent versions across the workspace.
|
|
1140
|
+
*/
|
|
1141
|
+
workspaceVersions?: {
|
|
1142
|
+
/**
|
|
1143
|
+
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1144
|
+
* for the contract — same semantics, applied to drift rewrites.
|
|
1145
|
+
*
|
|
1146
|
+
* Also gates the `--propose-min` catalog suggestion writer:
|
|
1147
|
+
* when `false` / `"prompt"`, `--fix --propose-min` reports the
|
|
1148
|
+
* proposed catalog entries but does not write
|
|
1149
|
+
* `pnpm-workspace.yaml`. Same "report only, still fails CI"
|
|
1150
|
+
* note applies as on `workspaceProtocol.autofix`.
|
|
1151
|
+
* @default true
|
|
1152
|
+
*/
|
|
1153
|
+
autofix?: "prompt" | boolean;
|
|
1154
|
+
/** Dep names exempt from the version-drift check (exact match). */
|
|
1155
|
+
ignore?: string[];
|
|
1156
|
+
/**
|
|
1157
|
+
* Resolution strategy used when `--fix` runs.
|
|
1158
|
+
* - `highest` (default): rewrite every drifting instance to the
|
|
1159
|
+
* highest sibling specifier.
|
|
1160
|
+
* - `lowest`: rewrite to the lowest.
|
|
1161
|
+
* - `catalog`: rewrite any dep already pinned in a workspace catalog
|
|
1162
|
+
* to `catalog:` / `catalog:<name>`. Catalog must exist; this lint
|
|
1163
|
+
* does not create the catalog (see `vis lint --resolve catalog --propose`).
|
|
1164
|
+
* @default "highest"
|
|
1165
|
+
*/
|
|
1166
|
+
resolve?: "catalog" | "highest" | "lowest";
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
interface VisSecurityConfig {
|
|
1170
|
+
/**
|
|
1171
|
+
* Packages whose policy findings have been reviewed and explicitly
|
|
1172
|
+
* accepted. Matched against every policy unless `policies` narrows the
|
|
1173
|
+
* scope. Replaces the legacy `security.socket.acceptedRisks` map.
|
|
1174
|
+
*
|
|
1175
|
+
* Key format: package name (`"lodash"`), name@version
|
|
1176
|
+
* (`"lodash@4.17.21"`), or glob (`"@myorg/*"`). Unversioned keys match
|
|
1177
|
+
* all versions of that package.
|
|
1178
|
+
* @example
|
|
1179
|
+
* ```
|
|
1180
|
+
* acceptedRisks: {
|
|
1181
|
+
* "some-risky-pkg": {
|
|
1182
|
+
* reason: "Internal fork, low score expected",
|
|
1183
|
+
* acceptedAt: "2026-03-15T10:00:00Z",
|
|
1184
|
+
* acceptedScore: 0.25,
|
|
1185
|
+
* policies: ["score"],
|
|
1186
|
+
* expiresAt: "2026-12-31",
|
|
1187
|
+
* },
|
|
1188
|
+
* }
|
|
1189
|
+
* ```
|
|
1190
|
+
*/
|
|
1191
|
+
acceptedRisks?: Record<string, {
|
|
1192
|
+
/** ISO 8601 timestamp when the risk was accepted. */
|
|
1193
|
+
acceptedAt: string;
|
|
1194
|
+
/**
|
|
1195
|
+
* The overall Socket.dev score at the time of acceptance,
|
|
1196
|
+
* in the range `[0, 1]` (mirrors `policies.score.minimum`).
|
|
1197
|
+
* Only relevant for the `score` policy; ignored elsewhere.
|
|
1198
|
+
*/
|
|
1199
|
+
acceptedScore?: number;
|
|
1200
|
+
/**
|
|
1201
|
+
* ISO 8601 date (or datetime). After this point the acceptance
|
|
1202
|
+
* stops applying and vis emits a warning. Leave undefined for
|
|
1203
|
+
* non-expiring entries. Values that fail to parse as a Date
|
|
1204
|
+
* are rejected by the loader rather than silently treated as
|
|
1205
|
+
* "always expired".
|
|
1206
|
+
*/
|
|
1207
|
+
expiresAt?: string;
|
|
1208
|
+
/**
|
|
1209
|
+
* Which policies this acceptance covers. When undefined the
|
|
1210
|
+
* acceptance applies to every policy finding on this package.
|
|
1211
|
+
*/
|
|
1212
|
+
policies?: PolicyName[];
|
|
1213
|
+
/** User-provided reason for accepting the risk. */
|
|
1214
|
+
reason: string;
|
|
1215
|
+
}>;
|
|
1216
|
+
/**
|
|
1217
|
+
* Map of bin names (or `pkg#bin` qualifiers) blessed for shadowing.
|
|
1218
|
+
* When two installed packages expose the same bin name, vis flags
|
|
1219
|
+
* the collision in `vis security list` and the post-install drift
|
|
1220
|
+
* report — set the bin (or `pkg#bin`) to `true` here to suppress
|
|
1221
|
+
* the warning once you've reviewed the conflict.
|
|
1222
|
+
*
|
|
1223
|
+
* Port of LavaMoat allow-scripts' experimental `allowBins`.
|
|
1224
|
+
* Bare names match any conflicting bin with that name; the
|
|
1225
|
+
* `pkg#bin` form scopes the approval to a single package's bin.
|
|
1226
|
+
* @example
|
|
1227
|
+
* ```
|
|
1228
|
+
* allowBins: {
|
|
1229
|
+
* tsc: true, // bless any 'tsc' bin
|
|
1230
|
+
* "typescript#tsc": true, // bless only typescript's 'tsc'
|
|
1231
|
+
* }
|
|
1232
|
+
* ```
|
|
1233
|
+
*/
|
|
1234
|
+
allowBins?: Record<string, boolean>;
|
|
1235
|
+
/**
|
|
1236
|
+
* Offline OSV advisory + `vis audit` configuration.
|
|
1237
|
+
*
|
|
1238
|
+
* Controls `vis audit --offline` and `vis advisories sync` behavior:
|
|
1239
|
+
* - `audit.advisories.source` is the OSV mirror to download from. It
|
|
1240
|
+
* must be `https://` and resolve to a host in `allowedHosts` (or one
|
|
1241
|
+
* of the built-in defaults).
|
|
1242
|
+
* - `audit.offlineByDefault` flips the default of `--offline`.
|
|
1243
|
+
*
|
|
1244
|
+
* Vulnerability severity gating and reachability filtering live under
|
|
1245
|
+
* `policies.vulnerability` (see below).
|
|
1246
|
+
*/
|
|
1247
|
+
audit?: {
|
|
1248
|
+
/**
|
|
1249
|
+
* Offline advisory cache settings.
|
|
1250
|
+
*/
|
|
1251
|
+
advisories?: {
|
|
1252
|
+
/**
|
|
1253
|
+
* Extra hosts permitted as `audit.advisories.source`. The
|
|
1254
|
+
* built-in allowlist is enforced even if this field is
|
|
1255
|
+
* omitted; entries here add to it.
|
|
1256
|
+
* @example ["mirror.corp.example.com"]
|
|
1257
|
+
*/
|
|
1258
|
+
allowedHosts?: string[];
|
|
1259
|
+
/**
|
|
1260
|
+
* Bloom-filter prefilter for OSV `MAL-*` (malicious-package)
|
|
1261
|
+
* advisories. Probes a ~380 KB filter fetched from
|
|
1262
|
+
* `endevco/osv-bloom` and escalates hits to the existing
|
|
1263
|
+
* advisory query path for `(name, version)` confirmation.
|
|
1264
|
+
*
|
|
1265
|
+
* Cost: ~380 KB on the wire, refreshed every 10 minutes
|
|
1266
|
+
* upstream. False-positive rate is ~0.1%, so a typical
|
|
1267
|
+
* 1000-package lockfile triggers zero or one extra
|
|
1268
|
+
* round trip per audit.
|
|
1269
|
+
*
|
|
1270
|
+
* Independent of `audit.advisories.source` / `verify` —
|
|
1271
|
+
* those control the full OSV ingest. The bloom is
|
|
1272
|
+
* MAL-* only and aimed at cold-start preflight and
|
|
1273
|
+
* ephemeral CI runners that haven't synced the full DB.
|
|
1274
|
+
*/
|
|
1275
|
+
bloom?: {
|
|
1276
|
+
/**
|
|
1277
|
+
* Extra hosts permitted as `bloom.source`. The
|
|
1278
|
+
* built-in allowlist (`endevco.github.io`) is enforced
|
|
1279
|
+
* even if this field is omitted; entries here add to it.
|
|
1280
|
+
*/
|
|
1281
|
+
allowedHosts?: string[];
|
|
1282
|
+
/**
|
|
1283
|
+
* Prefilter mode:
|
|
1284
|
+
* - `off`: never run the bloom check.
|
|
1285
|
+
* - `on`: run when a local filter is cached; on
|
|
1286
|
+
* fetch failure, fall back to the cached filter or
|
|
1287
|
+
* skip the prefilter (audit continues against the
|
|
1288
|
+
* non-bloom path).
|
|
1289
|
+
* - `required`: hard-fail the audit when the bloom
|
|
1290
|
+
* refresh fails or the local cache is missing.
|
|
1291
|
+
* Use in hardened CI together with
|
|
1292
|
+
* `audit.advisories.source`.
|
|
1293
|
+
* @default "off"
|
|
1294
|
+
*/
|
|
1295
|
+
mode?: "off" | "on" | "required";
|
|
1296
|
+
/**
|
|
1297
|
+
* Bloom mirror base URL (no trailing slash). Defaults
|
|
1298
|
+
* to the public `endevco/osv-bloom` GH Pages site.
|
|
1299
|
+
* Override only if you mirror the bloom artifacts
|
|
1300
|
+
* internally; the hostname must appear in
|
|
1301
|
+
* `allowedHosts`.
|
|
1302
|
+
* @default "https://endevco.github.io/osv-bloom"
|
|
1303
|
+
*/
|
|
1304
|
+
source?: string;
|
|
1305
|
+
};
|
|
1306
|
+
/**
|
|
1307
|
+
* Number of hours after `lastSyncIso` before `vis audit`
|
|
1308
|
+
* prints a "your advisory cache may be stale" notice.
|
|
1309
|
+
* `vis audit` never auto-syncs — the user runs
|
|
1310
|
+
* `vis advisories sync` themselves.
|
|
1311
|
+
* @default 24
|
|
1312
|
+
*/
|
|
1313
|
+
refreshIntervalHours?: number;
|
|
1314
|
+
/**
|
|
1315
|
+
* OSV mirror base URL (no trailing slash). Defaults to the
|
|
1316
|
+
* public Google Cloud Storage bucket. Override to point at a
|
|
1317
|
+
* corporate mirror; the hostname must appear in `allowedHosts`
|
|
1318
|
+
* (or one of the built-in defaults) and the scheme must be
|
|
1319
|
+
* `https://`.
|
|
1320
|
+
* @default "https://osv-vulnerabilities.storage.googleapis.com"
|
|
1321
|
+
*/
|
|
1322
|
+
source?: string;
|
|
1323
|
+
/**
|
|
1324
|
+
* Sigstore signature verification for the OSV dump.
|
|
1325
|
+
* Requires the native binding to be built with the
|
|
1326
|
+
* `verify-signatures` Cargo feature (default in the release
|
|
1327
|
+
* build). Off by default — the upstream OSV bucket does not
|
|
1328
|
+
* ship signatures today.
|
|
1329
|
+
*/
|
|
1330
|
+
verify?: {
|
|
1331
|
+
/**
|
|
1332
|
+
* Enable signature verification. The sync flow downloads
|
|
1333
|
+
* `<eco>/all.zip.sig` next to the zip and aborts if it
|
|
1334
|
+
* cannot verify against `expectedIssuer` / `expectedSubject`.
|
|
1335
|
+
* @default false
|
|
1336
|
+
*/
|
|
1337
|
+
enabled?: boolean;
|
|
1338
|
+
/** OIDC issuer that signed the bundle. */
|
|
1339
|
+
expectedIssuer?: string;
|
|
1340
|
+
/** OIDC subject (workload identity) that signed the bundle. */
|
|
1341
|
+
expectedSubject?: string;
|
|
1342
|
+
};
|
|
1343
|
+
};
|
|
1344
|
+
/**
|
|
1345
|
+
* Gates for the auto-fix flow (`vis audit --fix` /
|
|
1346
|
+
* `--fix-transitive`). The CLI prompts outside CI; inside CI
|
|
1347
|
+
* the flags refuse to run unless `--yes` is set and, for
|
|
1348
|
+
* transitives, `apply.transitive.enabled = true`.
|
|
1349
|
+
*/
|
|
1350
|
+
apply?: {
|
|
1351
|
+
/**
|
|
1352
|
+
* Gates for `vis audit --fix-transitive`. Two-lock: the
|
|
1353
|
+
* CLI requires `--yes` AND this flag set to `true` before
|
|
1354
|
+
* it will rewrite override entries in CI.
|
|
1355
|
+
*/
|
|
1356
|
+
transitive?: {
|
|
1357
|
+
/**
|
|
1358
|
+
* When true, allows `--fix-transitive` to run in CI
|
|
1359
|
+
* environments. Defaults to false because rewriting
|
|
1360
|
+
* overrides is a higher blast radius than bumping a
|
|
1361
|
+
* direct dep.
|
|
1362
|
+
* @default false
|
|
1363
|
+
*/
|
|
1364
|
+
enabled?: boolean;
|
|
1365
|
+
};
|
|
1366
|
+
};
|
|
1367
|
+
/**
|
|
1368
|
+
* Vulnerability scanner backend.
|
|
1369
|
+
*
|
|
1370
|
+
* - `auto` (default): delegate to `aube audit` when aube is the
|
|
1371
|
+
* active installer (its scanner reads the same lockfile and
|
|
1372
|
+
* produces equivalent severity ratings); otherwise run vis's
|
|
1373
|
+
* own OSV/Socket scanner.
|
|
1374
|
+
* - `aube`: always delegate to `aube audit`. Errors if `aube` is
|
|
1375
|
+
* not on PATH.
|
|
1376
|
+
* - `vis`: always use vis's built-in scanner — never delegate.
|
|
1377
|
+
*
|
|
1378
|
+
* Delegation avoids redundant work (aube already has a
|
|
1379
|
+
* full-fidelity audit pass that respects its own exclusions
|
|
1380
|
+
* via `aube-workspace.yaml::auditConfig`) and lets users get
|
|
1381
|
+
* a single, consistent result regardless of which entry point
|
|
1382
|
+
* they invoke.
|
|
1383
|
+
* @default "auto"
|
|
1384
|
+
*/
|
|
1385
|
+
backend?: "aube" | "auto" | "vis";
|
|
1386
|
+
/**
|
|
1387
|
+
* When true, `vis audit` skips network calls and queries the
|
|
1388
|
+
* offline cache. Equivalent to the CLI `--offline` flag.
|
|
1389
|
+
* @default false
|
|
1390
|
+
*/
|
|
1391
|
+
offlineByDefault?: boolean;
|
|
1392
|
+
};
|
|
1393
|
+
/**
|
|
1394
|
+
* When true, prevents transitive dependencies from using exotic sources
|
|
1395
|
+
* (git repositories, direct tarball URLs). Only direct dependencies may
|
|
1396
|
+
* use such sources. Equivalent to pnpm's `blockExoticSubdeps`.
|
|
1397
|
+
* @default false
|
|
1398
|
+
*/
|
|
1399
|
+
blockExoticSubdeps?: boolean;
|
|
1400
|
+
/**
|
|
1401
|
+
* deps.dev (Google Open Source Insights) data-source configuration.
|
|
1402
|
+
* Public, unauthenticated; pulls Scorecard data + advisories from
|
|
1403
|
+
* `api.deps.dev`. Complements or replaces Socket.dev. Heavily cached.
|
|
1404
|
+
* @see https://docs.deps.dev/api/v3/
|
|
1405
|
+
*/
|
|
1406
|
+
depsDev?: {
|
|
1407
|
+
/**
|
|
1408
|
+
* Cache TTL for advisory entries (immutable once published). 7 days.
|
|
1409
|
+
* @default 604800000
|
|
1410
|
+
*/
|
|
1411
|
+
advisoryCacheTtlMs?: number;
|
|
1412
|
+
/**
|
|
1413
|
+
* Enable deps.dev scanning on install/update/check/audit commands.
|
|
1414
|
+
* @default false
|
|
1415
|
+
*/
|
|
1416
|
+
enabled?: boolean;
|
|
1417
|
+
/**
|
|
1418
|
+
* Cache TTL for OpenSSF Scorecard project data (refreshes weekly). 24 hours.
|
|
1419
|
+
* @default 86400000
|
|
1420
|
+
*/
|
|
1421
|
+
projectCacheTtlMs?: number;
|
|
1422
|
+
/**
|
|
1423
|
+
* Request timeout in milliseconds.
|
|
1424
|
+
* @default 15000
|
|
1425
|
+
*/
|
|
1426
|
+
timeoutMs?: number;
|
|
1427
|
+
/**
|
|
1428
|
+
* Cache TTL for npm version metadata (immutable). 7 days.
|
|
1429
|
+
* @default 604800000
|
|
1430
|
+
*/
|
|
1431
|
+
versionCacheTtlMs?: number;
|
|
1432
|
+
};
|
|
1433
|
+
/**
|
|
1434
|
+
* Package names exempted from the `blockExoticSubdeps` check.
|
|
1435
|
+
* Bare names and a trailing `*` glob (`@scope/*`) are supported.
|
|
1436
|
+
* Use for an internal package legitimately published as a git or
|
|
1437
|
+
* tarball dependency.
|
|
1438
|
+
* @example ["@myorg/legacy", "internal-*"]
|
|
1439
|
+
*/
|
|
1440
|
+
exoticSubdepsAllow?: string[];
|
|
1441
|
+
/**
|
|
1442
|
+
* Pre-install marshall pipeline — packument-derived supply-chain
|
|
1443
|
+
* gates (author, provenance, s1ngularity, new-bin, metadata,
|
|
1444
|
+
* downloads, expired-domains, signatures, archived-repo) that run before
|
|
1445
|
+
* `vis add` / `vis install <pkg>` / `vis update <pkg>` hand off to
|
|
1446
|
+
* the underlying package manager. Every entry is optional; omit a
|
|
1447
|
+
* key and the marshall runs with defaults. Set `enabled: false`
|
|
1448
|
+
* on a specific marshall to skip it without touching env vars.
|
|
1449
|
+
*/
|
|
1450
|
+
marshalls?: {
|
|
1451
|
+
/** Archived-repo marshall (GitHub repository status). */
|
|
1452
|
+
archivedRepo?: {
|
|
1453
|
+
/** Package names to skip. */
|
|
1454
|
+
allowlist?: string[];
|
|
1455
|
+
/** Default: marshall is on. Set false to disable. */
|
|
1456
|
+
enabled?: boolean;
|
|
1457
|
+
/** GitHub PAT for the API call (5k/hr vs 60/hr). */
|
|
1458
|
+
githubToken?: string;
|
|
1459
|
+
};
|
|
1460
|
+
/** Author / publisher heuristics. */
|
|
1461
|
+
author?: {
|
|
1462
|
+
allowlist?: string[];
|
|
1463
|
+
/** Days since the publisher's last release before flagging as error. */
|
|
1464
|
+
dormantErrorDays?: number;
|
|
1465
|
+
/** Days since the publisher's last release before flagging as warning. */
|
|
1466
|
+
dormantWarnDays?: number;
|
|
1467
|
+
enabled?: boolean;
|
|
1468
|
+
/** Window for the "new publisher on an established package" check. */
|
|
1469
|
+
newPublisherWindowDays?: number;
|
|
1470
|
+
/** Days since the resolved version was published — error threshold. */
|
|
1471
|
+
recentVersionErrorDays?: number;
|
|
1472
|
+
/** Days since the resolved version was published — warning threshold. */
|
|
1473
|
+
recentVersionWarnDays?: number;
|
|
1474
|
+
};
|
|
1475
|
+
/** npm `deprecated`-flag check on the resolved version. */
|
|
1476
|
+
deprecation?: {
|
|
1477
|
+
allowlist?: string[];
|
|
1478
|
+
enabled?: boolean;
|
|
1479
|
+
};
|
|
1480
|
+
/** Monthly download-count floor. */
|
|
1481
|
+
downloads?: {
|
|
1482
|
+
allowlist?: string[];
|
|
1483
|
+
enabled?: boolean;
|
|
1484
|
+
/** Below this monthly count → error (default: 20). */
|
|
1485
|
+
errorThreshold?: number;
|
|
1486
|
+
/** Below this monthly count → warning (default: 1000). */
|
|
1487
|
+
warnThreshold?: number;
|
|
1488
|
+
};
|
|
1489
|
+
/** Maintainer-email-domain NS lookup. */
|
|
1490
|
+
expiredDomains?: {
|
|
1491
|
+
/** Domains exempted from the check (legacy / internal). */
|
|
1492
|
+
allowDomains?: string[];
|
|
1493
|
+
allowlist?: string[];
|
|
1494
|
+
/** DNS resolvers to query (default: system). */
|
|
1495
|
+
dnsServers?: string[];
|
|
1496
|
+
enabled?: boolean;
|
|
1497
|
+
/** Per-domain DNS timeout (default: 5000). */
|
|
1498
|
+
timeoutMs?: number;
|
|
1499
|
+
};
|
|
1500
|
+
/** README / license / repository presence checks. */
|
|
1501
|
+
metadata?: {
|
|
1502
|
+
allowlist?: string[];
|
|
1503
|
+
/** Subset of checks to run. Default: all three. */
|
|
1504
|
+
checks?: ("license" | "readme" | "repo")[];
|
|
1505
|
+
enabled?: boolean;
|
|
1506
|
+
};
|
|
1507
|
+
/** New CLI-bin script introduced in this version. */
|
|
1508
|
+
newBin?: {
|
|
1509
|
+
allowlist?: string[];
|
|
1510
|
+
enabled?: boolean;
|
|
1511
|
+
};
|
|
1512
|
+
/** Whole-package age heuristics (newly created / unmaintained). */
|
|
1513
|
+
packageAge?: {
|
|
1514
|
+
allowlist?: string[];
|
|
1515
|
+
enabled?: boolean;
|
|
1516
|
+
/** Package created fewer than this many days ago → error. Default 22. */
|
|
1517
|
+
newPackageDays?: number;
|
|
1518
|
+
/** No publish within this many days → warning. Default 365. */
|
|
1519
|
+
unmaintainedDays?: number;
|
|
1520
|
+
};
|
|
1521
|
+
/** Provenance regression check. */
|
|
1522
|
+
provenance?: {
|
|
1523
|
+
allowlist?: string[];
|
|
1524
|
+
enabled?: boolean;
|
|
1525
|
+
};
|
|
1526
|
+
/**
|
|
1527
|
+
* Composite "compromised-publish shape" detector — flags a single
|
|
1528
|
+
* version that simultaneously introduced/changed an install hook
|
|
1529
|
+
* AND dropped the provenance attestation a prior stable version
|
|
1530
|
+
* carried (the August 2025 s1ngularity / Nx fingerprint).
|
|
1531
|
+
*/
|
|
1532
|
+
s1ngularity?: {
|
|
1533
|
+
allowlist?: string[];
|
|
1534
|
+
enabled?: boolean;
|
|
1535
|
+
};
|
|
1536
|
+
/**
|
|
1537
|
+
* ECDSA P-256 verification against npm's signing keys. Disabled
|
|
1538
|
+
* by default because npm coverage still has gaps that produce
|
|
1539
|
+
* noisy warnings on legitimate packages.
|
|
1540
|
+
*/
|
|
1541
|
+
signatures?: {
|
|
1542
|
+
allowlist?: string[];
|
|
1543
|
+
/** Default: marshall is *off*. Set true to enable. */
|
|
1544
|
+
enabled?: boolean;
|
|
1545
|
+
/** Override the keys endpoint (default: npm registry). */
|
|
1546
|
+
keysUrl?: string;
|
|
1547
|
+
/** How to treat an expired-but-known key. Default: "warning". */
|
|
1548
|
+
treatExpiredAs?: "error" | "warning";
|
|
1549
|
+
};
|
|
1550
|
+
};
|
|
1551
|
+
/**
|
|
1552
|
+
* When true, `security.policies.installScripts.allow` keys are matched
|
|
1553
|
+
* as `name@version`. A version bump on an approved package drops it from
|
|
1554
|
+
* the allowlist until the new version is explicitly re-approved (port
|
|
1555
|
+
* of LavaMoat allow-scripts' version-aware policy matcher).
|
|
1556
|
+
*
|
|
1557
|
+
* After a version bump, run `vis approve-builds` or `vis security list`
|
|
1558
|
+
* — both surface a "Version drift" block with the suggested new key
|
|
1559
|
+
* (`old-key → new-key`) so you can update `vis.config.ts` by hand.
|
|
1560
|
+
* @default false
|
|
1561
|
+
*/
|
|
1562
|
+
pinVersions?: boolean;
|
|
1563
|
+
/**
|
|
1564
|
+
* Supply-chain policy gates. Each sub-block enables one policy and
|
|
1565
|
+
* configures its behavior. When a sub-block is omitted the policy is
|
|
1566
|
+
* inactive. `acceptedRisks` (above) silences specific packages without
|
|
1567
|
+
* disabling a policy globally.
|
|
1568
|
+
*
|
|
1569
|
+
* The 8 policies are inspired by Socket.dev's classification:
|
|
1570
|
+
* - `malware` — Socket-flagged malicious packages
|
|
1571
|
+
* - `firstSeen` — packages published less than N minutes ago
|
|
1572
|
+
* - `unexpectedDeps` — packages outside an allow-list / baseline
|
|
1573
|
+
* - `publisherChange` — maintainer set changed between installs
|
|
1574
|
+
* - `installScripts` — preinstall/install/postinstall scripts
|
|
1575
|
+
* - `score` — Socket overall score below threshold
|
|
1576
|
+
* - `vulnerability` — OSV vulnerability findings
|
|
1577
|
+
* - `license` — SPDX allow / deny lists
|
|
1578
|
+
*/
|
|
1579
|
+
policies?: {
|
|
1580
|
+
/**
|
|
1581
|
+
* Minimum number of minutes that must pass after a version is
|
|
1582
|
+
* published before vis will allow installation. Migrated from
|
|
1583
|
+
* the legacy `security.minimumReleaseAge` field. Equivalent to
|
|
1584
|
+
* pnpm's `minimumReleaseAge`.
|
|
1585
|
+
* @default 0
|
|
1586
|
+
* @example { minutes: 1440, exclude: ["@myorg/*"] } // 24 hours
|
|
1587
|
+
*/
|
|
1588
|
+
firstSeen?: {
|
|
1589
|
+
/**
|
|
1590
|
+
* Package names/patterns excluded from the firstSeen check.
|
|
1591
|
+
* Equivalent to pnpm's `minimumReleaseAgeExclude`.
|
|
1592
|
+
* @example ["webpack", "react", "@myorg/*"]
|
|
1593
|
+
*/
|
|
1594
|
+
exclude?: string[];
|
|
1595
|
+
/** Minutes after publish before install is allowed. */
|
|
1596
|
+
minutes?: number;
|
|
1597
|
+
};
|
|
1598
|
+
/**
|
|
1599
|
+
* Build-script (pre/install/postinstall/prepare) controls.
|
|
1600
|
+
* Migrated from the legacy `security.allowBuilds` /
|
|
1601
|
+
* `security.strictDepBuilds` fields.
|
|
1602
|
+
* @example { allow: { esbuild: true }, strict: true }
|
|
1603
|
+
*/
|
|
1604
|
+
installScripts?: {
|
|
1605
|
+
/**
|
|
1606
|
+
* Map of package names/patterns to allow (true) or deny
|
|
1607
|
+
* (false) build scripts. Packages not listed are denied
|
|
1608
|
+
* by default. Equivalent to pnpm's `allowBuilds`.
|
|
1609
|
+
*/
|
|
1610
|
+
allow?: Record<string, boolean>;
|
|
1611
|
+
/**
|
|
1612
|
+
* When true, installation will fail (exit non-zero) if any
|
|
1613
|
+
* dependencies have unreviewed build scripts. Equivalent to
|
|
1614
|
+
* pnpm's `strictDepBuilds`.
|
|
1615
|
+
* @default false
|
|
1616
|
+
*/
|
|
1617
|
+
strict?: boolean;
|
|
1618
|
+
};
|
|
1619
|
+
/**
|
|
1620
|
+
* SPDX license allow / deny lists. Deny wins on any sub-license
|
|
1621
|
+
* match in SPDX expressions (`(MIT OR GPL-3.0)` against
|
|
1622
|
+
* `deny: ["GPL-3.0"]` is blocked). Packages with no declared
|
|
1623
|
+
* license are flagged when `allow` is set.
|
|
1624
|
+
* @example
|
|
1625
|
+
* ```
|
|
1626
|
+
* license: {
|
|
1627
|
+
* allow: ["MIT", "Apache-2.0", "BSD-3-Clause"],
|
|
1628
|
+
* deny: ["GPL-3.0", "AGPL-3.0"],
|
|
1629
|
+
* }
|
|
1630
|
+
* ```
|
|
1631
|
+
*/
|
|
1632
|
+
license?: {
|
|
1633
|
+
/**
|
|
1634
|
+
* SPDX identifiers that are explicitly permitted. When set,
|
|
1635
|
+
* any package whose declared license is not on this list is
|
|
1636
|
+
* blocked.
|
|
1637
|
+
*/
|
|
1638
|
+
allow?: string[];
|
|
1639
|
+
/**
|
|
1640
|
+
* SPDX identifiers that are explicitly forbidden. Always
|
|
1641
|
+
* wins over `allow` when both reference the same identifier.
|
|
1642
|
+
*/
|
|
1643
|
+
deny?: string[];
|
|
1644
|
+
};
|
|
1645
|
+
/**
|
|
1646
|
+
* Behavior when the Socket.dev feed flags a package as malicious
|
|
1647
|
+
* (`alerts[].type === "Malware"`).
|
|
1648
|
+
*
|
|
1649
|
+
* The default is cross-field: `{ mode: "block" }` whenever
|
|
1650
|
+
* `security.socket.enabled !== false` (the engine cannot evaluate
|
|
1651
|
+
* malware without Socket data), and `"off"` otherwise. Consumers
|
|
1652
|
+
* resolve this default at evaluation time.
|
|
1653
|
+
*/
|
|
1654
|
+
malware?: {
|
|
1655
|
+
/**
|
|
1656
|
+
* - `"block"` — emit a block decision.
|
|
1657
|
+
* - `"warn"` — surface as a warning; do not gate exit code.
|
|
1658
|
+
* - `"off"` — disable the policy entirely.
|
|
1659
|
+
*/
|
|
1660
|
+
mode?: "block" | "off" | "warn";
|
|
1661
|
+
};
|
|
1662
|
+
/**
|
|
1663
|
+
* Trust-level checking for package publishing. Migrated from the
|
|
1664
|
+
* legacy `security.trustPolicy*` fields. Equivalent to pnpm's
|
|
1665
|
+
* `trustPolicy`.
|
|
1666
|
+
* @example { mode: "no-downgrade", ignoreAfter: 43200 } // 30 days
|
|
1667
|
+
*/
|
|
1668
|
+
publisherChange?: {
|
|
1669
|
+
/**
|
|
1670
|
+
* Package selectors excluded from the check.
|
|
1671
|
+
* Equivalent to pnpm's `trustPolicyExclude`.
|
|
1672
|
+
* @example ["chokidar@4.0.3"]
|
|
1673
|
+
*/
|
|
1674
|
+
exclude?: string[];
|
|
1675
|
+
/**
|
|
1676
|
+
* Ignore packages published more than N minutes ago. Useful
|
|
1677
|
+
* for older packages that pre-date provenance support.
|
|
1678
|
+
* Equivalent to pnpm's `trustPolicyIgnoreAfter`.
|
|
1679
|
+
*/
|
|
1680
|
+
ignoreAfter?: number;
|
|
1681
|
+
/**
|
|
1682
|
+
* - `"off"` — no trust checking (default).
|
|
1683
|
+
* - `"no-downgrade"` — block when a package's trust level
|
|
1684
|
+
* has decreased compared to previous releases (e.g., was
|
|
1685
|
+
* published by trusted publisher, now only has provenance).
|
|
1686
|
+
*/
|
|
1687
|
+
mode?: "no-downgrade" | "off";
|
|
1688
|
+
};
|
|
1689
|
+
/**
|
|
1690
|
+
* Socket.dev overall-score threshold. Packages scoring below
|
|
1691
|
+
* `minimum` trigger a block decision (or interactive prompt
|
|
1692
|
+
* during `vis add`). Migrated from the legacy
|
|
1693
|
+
* `security.socket.minimumScore` field.
|
|
1694
|
+
* @example { minimum: 0.4 }
|
|
1695
|
+
*/
|
|
1696
|
+
score?: {
|
|
1697
|
+
/**
|
|
1698
|
+
* Minimum overall Socket.dev score (0–1). Set to 0 to
|
|
1699
|
+
* disable the gate while keeping Socket data fetched.
|
|
1700
|
+
*
|
|
1701
|
+
* Consulted by `vis add`, `audit`, `doctor`, `check`, and
|
|
1702
|
+
* `update`; resolved once in `buildSocketOptions`, then
|
|
1703
|
+
* threaded through every consumer. Falls back to
|
|
1704
|
+
* `DEFAULT_LOW_SCORE_THRESHOLD` (`0.4`) when unset.
|
|
1705
|
+
*/
|
|
1706
|
+
minimum?: number;
|
|
1707
|
+
};
|
|
1708
|
+
/**
|
|
1709
|
+
* Net-new transitive dependency detection. Either provide a
|
|
1710
|
+
* static allow-list, a baseline lockfile path (recommended), or
|
|
1711
|
+
* both — the intersection is enforced.
|
|
1712
|
+
* @example { baselineLockfile: "./security/lockfile.baseline.yaml" }
|
|
1713
|
+
*/
|
|
1714
|
+
unexpectedDeps?: {
|
|
1715
|
+
/**
|
|
1716
|
+
* Allow-list of dependency names that may appear in the
|
|
1717
|
+
* resolved package set. Glob patterns are supported.
|
|
1718
|
+
* @example ["lodash", "axios", "@myorg/*"]
|
|
1719
|
+
*/
|
|
1720
|
+
allow?: string[];
|
|
1721
|
+
/**
|
|
1722
|
+
* Path (absolute or relative to the workspace root) to a
|
|
1723
|
+
* baseline lockfile snapshot. The policy diffs the current
|
|
1724
|
+
* lockfile against this baseline and flags any package that
|
|
1725
|
+
* didn't exist before.
|
|
1726
|
+
* @example "./security/lockfile.baseline.yaml"
|
|
1727
|
+
*/
|
|
1728
|
+
baselineLockfile?: string;
|
|
1729
|
+
};
|
|
1730
|
+
/**
|
|
1731
|
+
* OSV vulnerability gating. Migrated from the legacy
|
|
1732
|
+
* `security.audit.failOn` + `security.audit.usage` fields.
|
|
1733
|
+
*/
|
|
1734
|
+
vulnerability?: {
|
|
1735
|
+
/**
|
|
1736
|
+
* Severity threshold that makes `vis audit` exit non-zero.
|
|
1737
|
+
* Equivalent to the CLI `--fail-on` flag.
|
|
1738
|
+
* @example "high"
|
|
1739
|
+
*/
|
|
1740
|
+
failOn?: "critical" | "high" | "low" | "medium";
|
|
1741
|
+
/**
|
|
1742
|
+
* Reachability filter — only report vulnerabilities in
|
|
1743
|
+
* packages the workspace statically imports.
|
|
1744
|
+
*/
|
|
1745
|
+
usage?: {
|
|
1746
|
+
/**
|
|
1747
|
+
* Packages to always treat as reachable even if no
|
|
1748
|
+
* static import is found.
|
|
1749
|
+
* @example ["esbuild", "webpack-cli"]
|
|
1750
|
+
*/
|
|
1751
|
+
alwaysAssumeUsed?: string[];
|
|
1752
|
+
/**
|
|
1753
|
+
* Enable the reachability filter by default. Equivalent
|
|
1754
|
+
* to `--usage` on the CLI; `--no-usage` disables.
|
|
1755
|
+
* @default false
|
|
1756
|
+
*/
|
|
1757
|
+
enabled?: boolean;
|
|
1758
|
+
};
|
|
1759
|
+
};
|
|
1760
|
+
};
|
|
1761
|
+
/**
|
|
1762
|
+
* Which provider wins merge conflicts when multiple are enabled (e.g.
|
|
1763
|
+
* both Socket.dev and deps.dev return data for the same package). The
|
|
1764
|
+
* primary provider's `score` is kept; alerts from secondaries are
|
|
1765
|
+
* appended and deduped by `key`. Defaults to whichever provider is
|
|
1766
|
+
* enabled first in this order: socket → deps-dev → snyk.
|
|
1767
|
+
*/
|
|
1768
|
+
primaryProvider?: "deps-dev" | "snyk" | "socket";
|
|
1769
|
+
/**
|
|
1770
|
+
* Snyk data-source configuration. Snyk only contributes vulnerability
|
|
1771
|
+
* data (no maintenance / quality / supply-chain / license signal);
|
|
1772
|
+
* those axes stay neutral. Requires both an org id and an API token —
|
|
1773
|
+
* if either is missing the provider is skipped.
|
|
1774
|
+
* @see https://docs.snyk.io/snyk-api/using-specific-snyk-apis/issues-list-issues-for-a-package
|
|
1775
|
+
*/
|
|
1776
|
+
snyk?: {
|
|
1777
|
+
/**
|
|
1778
|
+
* Snyk API token. Set via VIS_SNYK_TOKEN environment variable or
|
|
1779
|
+
* here.
|
|
1780
|
+
*/
|
|
1781
|
+
apiToken?: string;
|
|
1782
|
+
/**
|
|
1783
|
+
* Snyk REST API version date sent as the `version` query param.
|
|
1784
|
+
* @default "2024-10-15"
|
|
1785
|
+
*/
|
|
1786
|
+
apiVersion?: string;
|
|
1787
|
+
/**
|
|
1788
|
+
* Cache TTL in milliseconds for Snyk issue lookups. 6 hours.
|
|
1789
|
+
* @default 21600000
|
|
1790
|
+
*/
|
|
1791
|
+
cacheTtlMs?: number;
|
|
1792
|
+
/**
|
|
1793
|
+
* Enable Snyk security scanning on install/update/check/audit
|
|
1794
|
+
* commands.
|
|
1795
|
+
* @default false
|
|
1796
|
+
*/
|
|
1797
|
+
enabled?: boolean;
|
|
1798
|
+
/**
|
|
1799
|
+
* Snyk organization id (the REST endpoint is org-scoped). Set via
|
|
1800
|
+
* VIS_SNYK_ORG environment variable or here.
|
|
1801
|
+
*/
|
|
1802
|
+
orgId?: string;
|
|
1803
|
+
/**
|
|
1804
|
+
* Request timeout in milliseconds for the Snyk API. 15 seconds.
|
|
1805
|
+
* @default 15000
|
|
1806
|
+
*/
|
|
1807
|
+
timeoutMs?: number;
|
|
1808
|
+
};
|
|
1809
|
+
/**
|
|
1810
|
+
* Socket.dev data-source configuration. Connection knobs only — score
|
|
1811
|
+
* thresholds and accepted-risk overrides moved to `policies.score` and
|
|
1812
|
+
* `security.acceptedRisks` respectively.
|
|
1813
|
+
* @see https://socket.dev
|
|
1814
|
+
*/
|
|
1815
|
+
socket?: {
|
|
1816
|
+
/**
|
|
1817
|
+
* Custom Socket.dev API token. Falls back to the public API token.
|
|
1818
|
+
* Set via VIS_SOCKET_TOKEN environment variable or here.
|
|
1819
|
+
*/
|
|
1820
|
+
apiToken?: string;
|
|
1821
|
+
/**
|
|
1822
|
+
* Cache TTL in milliseconds for Socket.dev reports. 1 hour.
|
|
1823
|
+
* @default 3600000
|
|
1824
|
+
*/
|
|
1825
|
+
cacheTtlMs?: number;
|
|
1826
|
+
/**
|
|
1827
|
+
* Enable Socket.dev security scanning on install/update/check commands.
|
|
1828
|
+
* @default false
|
|
1829
|
+
*/
|
|
1830
|
+
enabled?: boolean;
|
|
1831
|
+
/**
|
|
1832
|
+
* Request timeout in milliseconds for the Socket.dev API. 15 seconds.
|
|
1833
|
+
* @default 15000
|
|
1834
|
+
*/
|
|
1835
|
+
timeoutMs?: number;
|
|
1836
|
+
};
|
|
1837
|
+
/**
|
|
1838
|
+
* Package names to skip during typosquat detection.
|
|
1839
|
+
* Use this for internal packages or known-safe names that happen to
|
|
1840
|
+
* look similar to popular packages.
|
|
1841
|
+
* @example ["my-internal-axois", "@myorg/recat"]
|
|
1842
|
+
*/
|
|
1843
|
+
typosquatAllowlist?: string[];
|
|
1844
|
+
}
|
|
1845
|
+
interface VisUpdateConfig {
|
|
1846
|
+
/**
|
|
1847
|
+
* Dependency fields to scan for outdated packages.
|
|
1848
|
+
* Beyond the standard fields, supports:
|
|
1849
|
+
* - `"overrides"` (npm)
|
|
1850
|
+
* - `"resolutions"` (yarn)
|
|
1851
|
+
* - `"pnpm.overrides"`
|
|
1852
|
+
* @default ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"]
|
|
1853
|
+
*/
|
|
1854
|
+
depFields?: string[];
|
|
1855
|
+
exclude?: string[];
|
|
1856
|
+
format?: "json" | "minimal" | "table";
|
|
1857
|
+
/**
|
|
1858
|
+
* Package names or glob patterns to permanently ignore during updates.
|
|
1859
|
+
* Ignored packages are skipped and listed in the output so you know
|
|
1860
|
+
* they were not checked.
|
|
1861
|
+
* @example ["eslint", "@types/*"]
|
|
1862
|
+
*/
|
|
1863
|
+
ignore?: string[];
|
|
1864
|
+
include?: string[];
|
|
1865
|
+
/**
|
|
1866
|
+
* Include packages with pinned/exact versions (no `^` or `~` prefix).
|
|
1867
|
+
* By default, pinned versions are skipped during update checks.
|
|
1868
|
+
* @default false
|
|
1869
|
+
*/
|
|
1870
|
+
includeLocked?: boolean;
|
|
1871
|
+
install?: boolean;
|
|
1872
|
+
/**
|
|
1873
|
+
* Maximum number of concurrent registry requests during outdated checks.
|
|
1874
|
+
* Higher values speed up large workspaces but risk hitting registry rate
|
|
1875
|
+
* limits or self-hosted Verdaccio caps.
|
|
1876
|
+
* @default 8
|
|
1877
|
+
*/
|
|
1878
|
+
maxConcurrentRequests?: number;
|
|
1879
|
+
/**
|
|
1880
|
+
* Minimum number of minutes since a version was published before
|
|
1881
|
+
* vis will consider it for updates. This mirrors pnpm's
|
|
1882
|
+
* `minimumReleaseAge` — a single setting that applies to both
|
|
1883
|
+
* install and update.
|
|
1884
|
+
*
|
|
1885
|
+
* Not set by default. If your package manager config
|
|
1886
|
+
* (`pnpm-workspace.yaml`) has `minimumReleaseAge`, vis will
|
|
1887
|
+
* read it from there as a fallback.
|
|
1888
|
+
* @example 1440 // 24 hours
|
|
1889
|
+
*/
|
|
1890
|
+
minimumReleaseAge?: number;
|
|
1891
|
+
/**
|
|
1892
|
+
* Package names/patterns excluded from the minimumReleaseAge check.
|
|
1893
|
+
* @example ["webpack", "@myorg/*"]
|
|
1894
|
+
*/
|
|
1895
|
+
minimumReleaseAgeExclude?: string[];
|
|
1896
|
+
/**
|
|
1897
|
+
* Per-package or per-pattern update target overrides.
|
|
1898
|
+
* Keys are exact package names, glob patterns, or regex patterns
|
|
1899
|
+
* wrapped in `/` (e.g., `/^@vue/`).
|
|
1900
|
+
* Values are `"latest"`, `"minor"`, or `"patch"`.
|
|
1901
|
+
* @example { "typescript": "minor", "/^@vue/": "patch" }
|
|
1902
|
+
*/
|
|
1903
|
+
packageMode?: Record<string, "latest" | "minor" | "patch">;
|
|
1904
|
+
prerelease?: boolean;
|
|
1905
|
+
/**
|
|
1906
|
+
* Which release channels to consider when picking the target version.
|
|
1907
|
+
* - `"stable"` (default) — only ship stable releases (no prereleases).
|
|
1908
|
+
* - `"same"` — match the prerelease channel of the *current* range:
|
|
1909
|
+
* if you're on `react@19.0.0-rc.1`, only `rc.*` candidates qualify;
|
|
1910
|
+
* if you're on a stable, only stable candidates. Prevents
|
|
1911
|
+
* accidentally promoting a prerelease pin to a stable major bump.
|
|
1912
|
+
* - `"any"` — equivalent to `--prerelease`. Any channel is fair game.
|
|
1913
|
+
*
|
|
1914
|
+
* `--release-channel` on the CLI overrides this. If `prerelease: true`
|
|
1915
|
+
* is set without `releaseChannel`, vis treats it as `"any"`.
|
|
1916
|
+
* @default "stable"
|
|
1917
|
+
*/
|
|
1918
|
+
releaseChannel?: "any" | "same" | "stable";
|
|
1919
|
+
security?: boolean;
|
|
1920
|
+
target?: "latest" | "minor" | "patch";
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Same shape as `T`. Wrapping a section type in it makes the schema
|
|
1924
|
+
* generator emit the section as a nested object, as it does for an inline
|
|
1925
|
+
* type literal, instead of a `$ref` to a named definition. This keeps the
|
|
1926
|
+
* published JSON schema unchanged when a section moves to its own module.
|
|
1927
|
+
*/
|
|
1928
|
+
type Inline<T> = { [K in keyof T]: T[K]; };
|
|
1929
|
+
/**
|
|
1930
|
+
* A predicate used by {@link VisConfig.scopedTasks}.
|
|
1931
|
+
* All listed constraints must match for the block to apply.
|
|
1932
|
+
*/
|
|
1933
|
+
interface ScopedTasksMatch {
|
|
1934
|
+
/** Match on primary language. */
|
|
1935
|
+
language?: string | string[];
|
|
1936
|
+
/** Match on project layer. */
|
|
1937
|
+
layer?: ProjectJson["layer"] | ProjectJson["layer"][];
|
|
1938
|
+
/** Match on project type. */
|
|
1939
|
+
projectType?: "application" | "library" | "service" | "tool";
|
|
1940
|
+
/** Match on project stack. */
|
|
1941
|
+
stack?: ProjectJson["stack"] | ProjectJson["stack"][];
|
|
1942
|
+
/** Match projects tagged with any of these tags. */
|
|
1943
|
+
tags?: string[];
|
|
1944
|
+
}
|
|
1945
|
+
interface VisConfig {
|
|
1946
|
+
/**
|
|
1947
|
+
* Workspace-relative glob patterns for changed files outside every
|
|
1948
|
+
* project that `vis affected`, `vis run --affected`, `vis ci` and
|
|
1949
|
+
* `vis ci ignore` should not count as a change.
|
|
1950
|
+
*
|
|
1951
|
+
* By default a changed file that belongs to no project (a root
|
|
1952
|
+
* `tsconfig.json`, `package.json`, …) is a global change and marks every
|
|
1953
|
+
* project affected. A changed file matching one of these patterns is
|
|
1954
|
+
* skipped instead. The patterns are only checked for files that belong
|
|
1955
|
+
* to NO project: a file inside a project root is never filtered, so a
|
|
1956
|
+
* broad pattern like `*.md` cannot hide a real package change.
|
|
1957
|
+
*
|
|
1958
|
+
* Patterns use `path.matchesGlob` syntax, where `*` does not cross `/`:
|
|
1959
|
+
* `*.md` matches `README.md` but not `docs/guide.md`.
|
|
1960
|
+
*
|
|
1961
|
+
* Do NOT list paths whose changes really do affect projects, such as
|
|
1962
|
+
* bundler-inlined shared source or the root `tsconfig.json`: an edit
|
|
1963
|
+
* there would then run nothing.
|
|
1964
|
+
* @example ["api-snapshots/**", "plans/**", "*.md"]
|
|
1965
|
+
*/
|
|
1966
|
+
affectedIgnore?: string[];
|
|
1967
|
+
/** AI analysis configuration */
|
|
1968
|
+
ai?: {
|
|
1969
|
+
/** Cache TTL in milliseconds. Overrides default (1h / 30min for security). */
|
|
1970
|
+
cacheTtl?: number;
|
|
1971
|
+
/** Override default provider priority. Higher number = preferred. */
|
|
1972
|
+
priority?: Record<string, number>;
|
|
1973
|
+
/** Use a specific provider instead of auto-detecting (e.g., `"claude"`, `"gemini"`). */
|
|
1974
|
+
provider?: string;
|
|
1975
|
+
};
|
|
1976
|
+
/**
|
|
1977
|
+
* Scope the task-runner cache directory by the current git branch.
|
|
1978
|
+
* When `true`, caches are stored under `<cacheDir>/branches/<slug>`
|
|
1979
|
+
* so `main` and feature branches stop thrashing each other —
|
|
1980
|
+
* generated artefacts (schemas, `.d.ts` snapshots) that legitimately
|
|
1981
|
+
* differ across branches no longer oscillate the cache contents.
|
|
1982
|
+
*
|
|
1983
|
+
* Falls back to the unscoped path on detached HEAD, non-git
|
|
1984
|
+
* workspaces, or when git isn't available.
|
|
1985
|
+
* @default false
|
|
1986
|
+
*/
|
|
1987
|
+
branchScopedCache?: boolean;
|
|
1988
|
+
/**
|
|
1989
|
+
* Code ownership configuration. Controls how `vis sync codeowners`
|
|
1990
|
+
* renders the generated CODEOWNERS file.
|
|
1991
|
+
*/
|
|
1992
|
+
codeowners?: CodeownersConfig;
|
|
1993
|
+
/**
|
|
1994
|
+
* Composer packages as task projects. Off by default: a `composer.json` in a
|
|
1995
|
+
* subdirectory gets validate and, when its scripts define them, test and lint targets.
|
|
1996
|
+
*/
|
|
1997
|
+
composer?: {
|
|
1998
|
+
discover?: boolean;
|
|
1999
|
+
};
|
|
2000
|
+
/**
|
|
2001
|
+
* Project dependency constraints.
|
|
2002
|
+
* Enforced after building the project graph, before running tasks.
|
|
2003
|
+
*/
|
|
2004
|
+
constraints?: ConstraintsConfig;
|
|
2005
|
+
/**
|
|
2006
|
+
* Configuration for the `vis create` scaffolding command.
|
|
2007
|
+
* Controls template downloads (via giget), default options, and
|
|
2008
|
+
* post-creation behavior.
|
|
2009
|
+
*/
|
|
2010
|
+
create?: {
|
|
2011
|
+
/**
|
|
2012
|
+
* Authorization token for downloading private repository templates.
|
|
2013
|
+
* Passed as Bearer token to the git host API.
|
|
2014
|
+
* Can also be set via GIGET_AUTH, GITHUB_TOKEN, or GH_TOKEN environment variables.
|
|
2015
|
+
*/
|
|
2016
|
+
auth?: string;
|
|
2017
|
+
/**
|
|
2018
|
+
* Default editor to configure after scaffolding.
|
|
2019
|
+
* When set, `vis create` automatically generates editor config files.
|
|
2020
|
+
* @example "vscode"
|
|
2021
|
+
*/
|
|
2022
|
+
defaultEditor?: "vscode";
|
|
2023
|
+
/**
|
|
2024
|
+
* Default package manager for new standalone projects.
|
|
2025
|
+
* When set, skips the PM selection prompt in interactive mode.
|
|
2026
|
+
*/
|
|
2027
|
+
defaultPm?: "bun" | "npm" | "pnpm" | "yarn";
|
|
2028
|
+
/**
|
|
2029
|
+
* Default giget provider for `owner/repo` shorthand inputs.
|
|
2030
|
+
* @default "github"
|
|
2031
|
+
*/
|
|
2032
|
+
defaultProvider?: "bitbucket" | "github" | "gitlab" | "sourcehut";
|
|
2033
|
+
/**
|
|
2034
|
+
* Template used by a bare `vis create`. Accepts any template input, including an
|
|
2035
|
+
* organization scope (`@acme` opens the `@acme/create` manifest picker, `@acme:app`
|
|
2036
|
+
* selects one entry directly). In a terminal the usual prompts still run, minus the template step.
|
|
2037
|
+
* @example "@acme"
|
|
2038
|
+
*/
|
|
2039
|
+
defaultTemplate?: string;
|
|
2040
|
+
/**
|
|
2041
|
+
* Initialize a git repository after scaffolding standalone projects.
|
|
2042
|
+
* @default false
|
|
1004
2043
|
*/
|
|
1005
2044
|
gitInit?: boolean;
|
|
1006
2045
|
/**
|
|
@@ -1376,326 +2415,48 @@ interface VisConfig {
|
|
|
1376
2415
|
*
|
|
1377
2416
|
* Shown at most once every 14 days; skipped in CI, non-TTY shells,
|
|
1378
2417
|
* during `--help`/`--version`/`ai`/`mcp` invocations, and when
|
|
1379
|
-
* `VIS_NO_MCP_PROMOTE=1` is set. Set `enabled: false` to silence
|
|
1380
|
-
* permanently for this workspace.
|
|
1381
|
-
* @example
|
|
1382
|
-
* ```
|
|
1383
|
-
* mcpPromote: { enabled: false }
|
|
1384
|
-
* ```
|
|
1385
|
-
*/
|
|
1386
|
-
mcpPromote?: {
|
|
1387
|
-
/**
|
|
1388
|
-
* Show the vis-mcp promotion notice on successful command completion.
|
|
1389
|
-
* @default true
|
|
1390
|
-
*/
|
|
1391
|
-
enabled?: boolean;
|
|
1392
|
-
};
|
|
1393
|
-
/**
|
|
1394
|
-
* Named input patterns inherited by every project target. Equivalent
|
|
1395
|
-
* to task-runner's `namedInputs` but configurable from the vis config.
|
|
1396
|
-
*/
|
|
1397
|
-
namedInputs?: NamedInputs;
|
|
1398
|
-
/**
|
|
1399
|
-
* NuGet projects as task projects. Off by default: each directory with one `*.csproj` or
|
|
1400
|
-
* `*.fsproj` (outside `bin`, `obj` and `node_modules`) gets build, test and format:check
|
|
1401
|
-
* targets when this is set. POSIX only: the inferred commands are not verified on Windows.
|
|
1402
|
-
*/
|
|
1403
|
-
nuget?: {
|
|
1404
|
-
discover?: boolean;
|
|
1405
|
-
};
|
|
1406
|
-
/** Package override mappings applied during migration (e.g., `{ "lodash": "lodash-es" }`) */
|
|
1407
|
-
overrides?: Record<string, string>;
|
|
1408
|
-
/**
|
|
1409
|
-
* Plugins — each plugin registers typed hooks that fire at run /
|
|
1410
|
-
* task / cache boundaries. See {@link VisPlugin} for the contract.
|
|
1411
|
-
* Prefer plugins over per-target shell hooks when behaviour needs
|
|
1412
|
-
* access to task metadata, results, or cache state.
|
|
1413
|
-
*/
|
|
1414
|
-
plugins?: VisPlugin[];
|
|
1415
|
-
/**
|
|
1416
|
-
* Workspace dep-policy lints exposed via `vis lint`. Each block opts in
|
|
1417
|
-
* to a single rule; the command flags (`--workspace-protocol`,
|
|
1418
|
-
* `--no-redefine-root`, `--banned-deps`) toggle them per-run.
|
|
1419
|
-
*/
|
|
1420
|
-
policy?: {
|
|
1421
|
-
/**
|
|
1422
|
-
* Map of dep names or globs → reason (or `{ reason, replacement, packages?, paths? }`).
|
|
1423
|
-
* Internal/workspace deps are never flagged here; the
|
|
1424
|
-
* workspace-protocol lint owns those.
|
|
1425
|
-
*
|
|
1426
|
-
* Optional `packages` (globs over the declaring package's `name`) and
|
|
1427
|
-
* `paths` (globs over the workspace-relative `packageDir`) narrow where
|
|
1428
|
-
* the rule applies. With both set, either match is enough. Omit both
|
|
1429
|
-
* to ban anywhere — the default.
|
|
1430
|
-
* @example
|
|
1431
|
-
* ```
|
|
1432
|
-
* bannedDeps: {
|
|
1433
|
-
* request: "deprecated; use undici",
|
|
1434
|
-
* moment: { reason: "huge bundle, frozen upstream", replacement: "date-fns" },
|
|
1435
|
-
* "@radix-ui/*": "we standardized on shadcn",
|
|
1436
|
-
* react: { reason: "no react in shared libs", paths: ["packages/shared/*"] },
|
|
1437
|
-
* "next": { reason: "apps only", packages: ["@app/*"] },
|
|
1438
|
-
* }
|
|
1439
|
-
* ```
|
|
1440
|
-
*/
|
|
1441
|
-
bannedDeps?: Record<string, string | {
|
|
1442
|
-
packages?: string[];
|
|
1443
|
-
paths?: string[];
|
|
1444
|
-
reason: string;
|
|
1445
|
-
replacement?: string;
|
|
1446
|
-
}>;
|
|
1447
|
-
/**
|
|
1448
|
-
* Tweak the custom-types lint that flags drift in `engines.{node,pnpm,...}`,
|
|
1449
|
-
* `packageManager`, `volta.{node,pnpm,yarn}`, and the proposed
|
|
1450
|
-
* `devEngines.{runtime,packageManager}` array form.
|
|
1451
|
-
*
|
|
1452
|
-
* Each (customType × name) cluster is tracked independently —
|
|
1453
|
-
* `engines.node` and `volta.node` don't cross-couple here. Use a
|
|
1454
|
-
* versionGroup once that lands if you need to enforce they agree.
|
|
1455
|
-
*/
|
|
1456
|
-
customTypes?: {
|
|
1457
|
-
/**
|
|
1458
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1459
|
-
* for the contract — same semantics, applied to drift rewrites
|
|
1460
|
-
* across engines / packageManager / volta / devEngines.
|
|
1461
|
-
*
|
|
1462
|
-
* Note: `--fix` strips any `+sha512.<hash>` suffix from
|
|
1463
|
-
* `packageManager` on bump — content-integrity hashes are tied
|
|
1464
|
-
* to a specific package, not a version, so users must regenerate
|
|
1465
|
-
* via their PM (`pnpm install` re-pins; `corepack use pnpm@X` etc.).
|
|
1466
|
-
* @default true
|
|
1467
|
-
*/
|
|
1468
|
-
autofix?: "prompt" | boolean;
|
|
1469
|
-
/**
|
|
1470
|
-
* User-defined custom-type pin locations. Each entry tells the
|
|
1471
|
-
* customTypes lint to read additional version pins from a
|
|
1472
|
-
* non-standard JSON path inside every workspace package.json,
|
|
1473
|
-
* cluster them by `(name × depName)` like the built-in types,
|
|
1474
|
-
* and rewrite them with `--fix`.
|
|
1475
|
-
*
|
|
1476
|
-
* The original built-ins (`engines`, `volta`, `packageManager`,
|
|
1477
|
-
* `devEngines.runtime`, `devEngines.packageManager`) keep
|
|
1478
|
-
* running unconditionally — these layer on top.
|
|
1479
|
-
*
|
|
1480
|
-
* Strategies:
|
|
1481
|
-
* - `versionsByName`: the JSON at `path` is `{ [depName]: version }`
|
|
1482
|
-
* (like `engines` or `pnpm.overrides`).
|
|
1483
|
-
* - `name@version`: the JSON at `path` is a string of the form
|
|
1484
|
-
* `name@version` (like `packageManager`). The leading `name@`
|
|
1485
|
-
* is preserved; only the version segment is rewritten.
|
|
1486
|
-
* - `string`: the JSON at `path` is a bare version string. The
|
|
1487
|
-
* `depName` field is required and identifies the dep cluster.
|
|
1488
|
-
*
|
|
1489
|
-
* `name` must not collide with a built-in type name. `path` is
|
|
1490
|
-
* a dot-separated walk into the package.json (e.g. `pnpm.overrides`).
|
|
1491
|
-
* @example
|
|
1492
|
-
* ```ts
|
|
1493
|
-
* extraTypes: [
|
|
1494
|
-
* { name: "pnpmOverridesLegacy", path: "pnpm.overrides", strategy: "versionsByName" },
|
|
1495
|
-
* { name: "myToolPin", path: "myTool.runtime", strategy: "name@version" },
|
|
1496
|
-
* { name: "minNode", path: "config.minNode", strategy: "string", depName: "node" },
|
|
1497
|
-
* ]
|
|
1498
|
-
* ```
|
|
1499
|
-
*/
|
|
1500
|
-
extraTypes?: ExtraCustomType[];
|
|
1501
|
-
/**
|
|
1502
|
-
* Dep names exempt from the drift check (exact match against the
|
|
1503
|
-
* field name within the block — e.g. `node`, `pnpm`).
|
|
1504
|
-
*/
|
|
1505
|
-
ignore?: string[];
|
|
1506
|
-
/**
|
|
1507
|
-
* Resolution strategy used when `--fix` runs.
|
|
1508
|
-
* - `highest` (default): align every drifting instance to the
|
|
1509
|
-
* highest declared version.
|
|
1510
|
-
* - `lowest`: align to the lowest.
|
|
1511
|
-
* @default "highest"
|
|
1512
|
-
*/
|
|
1513
|
-
resolve?: "highest" | "lowest";
|
|
1514
|
-
};
|
|
1515
|
-
/**
|
|
1516
|
-
* Tweak the dead-workspace-patterns lint that flags entries in
|
|
1517
|
-
* `pnpm-workspace.yaml#packages` / `package.json#workspaces` which
|
|
1518
|
-
* resolve to zero on-disk directories.
|
|
1519
|
-
*/
|
|
1520
|
-
deadWorkspacePatterns?: {
|
|
1521
|
-
/**
|
|
1522
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1523
|
-
* for the contract — applied here to dropping unmatched patterns
|
|
1524
|
-
* from the workspace config file.
|
|
1525
|
-
* @default true
|
|
1526
|
-
*/
|
|
1527
|
-
autofix?: "prompt" | boolean;
|
|
1528
|
-
};
|
|
1529
|
-
/**
|
|
1530
|
-
* Tweak the empty-deps lint that flags empty `dependencies` /
|
|
1531
|
-
* `devDependencies` / `peerDependencies` / `optionalDependencies`
|
|
1532
|
-
* blocks across the workspace.
|
|
1533
|
-
*/
|
|
1534
|
-
emptyDeps?: {
|
|
1535
|
-
/**
|
|
1536
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1537
|
-
* for the contract — applied here to removing the empty key.
|
|
1538
|
-
* @default true
|
|
1539
|
-
*/
|
|
1540
|
-
autofix?: "prompt" | boolean;
|
|
1541
|
-
/**
|
|
1542
|
-
* Block names exempt from the rule (e.g. `["peerDependencies"]`
|
|
1543
|
-
* to keep the key around as a marker even when empty).
|
|
1544
|
-
*/
|
|
1545
|
-
ignoreBlocks?: ("dependencies" | "devDependencies" | "optionalDependencies" | "peerDependencies")[];
|
|
1546
|
-
};
|
|
1547
|
-
/**
|
|
1548
|
-
* Tweak the redefine-root lint that flags non-root packages duplicating
|
|
1549
|
-
* deps already pinned at the workspace root.
|
|
1550
|
-
*/
|
|
1551
|
-
redefineRoot?: {
|
|
1552
|
-
/** Dep names that are exempt from the redefine-root rule (exact match). */
|
|
1553
|
-
ignore?: string[];
|
|
1554
|
-
};
|
|
1555
|
-
/**
|
|
1556
|
-
* Tweak the root-deps lint that flags runtime `dependencies` declared
|
|
1557
|
-
* on the private workspace root (they should live in `devDependencies`).
|
|
1558
|
-
*/
|
|
1559
|
-
rootDeps?: {
|
|
1560
|
-
/**
|
|
1561
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1562
|
-
* for the contract — applied here to moving entries from
|
|
1563
|
-
* `dependencies` to `devDependencies` on the root package.json.
|
|
1564
|
-
* @default true
|
|
1565
|
-
*/
|
|
1566
|
-
autofix?: "prompt" | boolean;
|
|
1567
|
-
};
|
|
1568
|
-
/**
|
|
1569
|
-
* Tweak the root-package-manager lint that flags a missing or
|
|
1570
|
-
* malformed `packageManager` field on the workspace root.
|
|
1571
|
-
*/
|
|
1572
|
-
rootPackageManager?: {
|
|
1573
|
-
/**
|
|
1574
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1575
|
-
* for the contract. `--fix` only writes when `suggested` is set —
|
|
1576
|
-
* a missing `packageManager` field has no canonical default.
|
|
1577
|
-
* @default true
|
|
1578
|
-
*/
|
|
1579
|
-
autofix?: "prompt" | boolean;
|
|
1580
|
-
/**
|
|
1581
|
-
* Canonical specifier (`name@version`) to write when `--fix` runs
|
|
1582
|
-
* and the field is absent. Required to enable autofix —
|
|
1583
|
-
* vis won't guess the workspace's preferred manager.
|
|
1584
|
-
* @example "pnpm@10.32.1"
|
|
1585
|
-
*/
|
|
1586
|
-
suggested?: string;
|
|
1587
|
-
};
|
|
1588
|
-
/**
|
|
1589
|
-
* Tweak the root-private lint that flags a workspace root package.json
|
|
1590
|
-
* missing `"private": true`. Only fires when the root looks like a
|
|
1591
|
-
* workspace (npm/yarn/bun `workspaces` field or `pnpm-workspace.yaml`).
|
|
1592
|
-
*/
|
|
1593
|
-
rootPrivate?: {
|
|
1594
|
-
/**
|
|
1595
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1596
|
-
* for the contract — applied here to inserting `"private": true`.
|
|
1597
|
-
* @default true
|
|
1598
|
-
*/
|
|
1599
|
-
autofix?: "prompt" | boolean;
|
|
1600
|
-
};
|
|
1601
|
-
/**
|
|
1602
|
-
* Tweak the similar-deps lint that flags drift across related dep
|
|
1603
|
-
* families (e.g. `react` and `react-dom`, all of `@babel/*`).
|
|
1604
|
-
*
|
|
1605
|
-
* The lint is report-only — aligning a family requires picking a
|
|
1606
|
-
* single canonical specifier across heterogeneous range syntaxes
|
|
1607
|
-
* (`^`, `~`, exact), which is too lossy without user input.
|
|
1608
|
-
*/
|
|
1609
|
-
similarDeps?: {
|
|
1610
|
-
/**
|
|
1611
|
-
* Additional families merged with the built-ins. Same `id` wins
|
|
1612
|
-
* → user override fully replaces the built-in entry.
|
|
1613
|
-
* @example
|
|
1614
|
-
* ```
|
|
1615
|
-
* extraFamilies: [
|
|
1616
|
-
* { id: "vue", label: "Vue", members: ["vue", "vue-router", "pinia"] },
|
|
1617
|
-
* ]
|
|
1618
|
-
* ```
|
|
1619
|
-
*/
|
|
1620
|
-
extraFamilies?: SimilarDepFamily[];
|
|
1621
|
-
/** Family ids to skip entirely (matches `SimilarDepFamily.id`). */
|
|
1622
|
-
ignoreFamilies?: string[];
|
|
1623
|
-
};
|
|
1624
|
-
/**
|
|
1625
|
-
* Tweak the types-in-deps lint that flags `@types/*` declared in
|
|
1626
|
-
* `dependencies` on a private package (they belong in
|
|
1627
|
-
* `devDependencies` since the package never ships).
|
|
1628
|
-
*/
|
|
1629
|
-
typesInDeps?: {
|
|
1630
|
-
/**
|
|
1631
|
-
* Three-state autofix opt-out. See `workspaceProtocol.autofix`
|
|
1632
|
-
* for the contract — applied here to moving the entry to
|
|
1633
|
-
* `devDependencies`. Existing dev pins are preserved on conflict.
|
|
1634
|
-
* @default true
|
|
1635
|
-
*/
|
|
1636
|
-
autofix?: "prompt" | boolean;
|
|
1637
|
-
/** Dep names exempt from the rule (exact match, e.g. `@types/node`). */
|
|
1638
|
-
ignore?: string[];
|
|
1639
|
-
};
|
|
1640
|
-
/**
|
|
1641
|
-
* Tweak the workspace-protocol lint that flags internal deps not
|
|
1642
|
-
* using the `workspace:` protocol.
|
|
1643
|
-
*/
|
|
1644
|
-
workspaceProtocol?: {
|
|
1645
|
-
/**
|
|
1646
|
-
* Three-state autofix opt-out. Some workspaces want detection
|
|
1647
|
-
* without rewrite (e.g. dual-licensed packages where `workspace:*`
|
|
1648
|
-
* is unsafe).
|
|
1649
|
-
* - `true` (default): `--fix` rewrites the specifier.
|
|
1650
|
-
* - `false`: never rewrite — report the violation only.
|
|
1651
|
-
* - `"prompt"`: ask before each rewrite. Falls back to report-only
|
|
1652
|
-
* when stdin isn't a TTY (CI). Reserved; not yet implemented.
|
|
1653
|
-
*
|
|
1654
|
-
* Note: when `false` (or `"prompt"`), `--fix` still **fails CI** on
|
|
1655
|
-
* detected violations — the rule is "report only", not "ignore".
|
|
1656
|
-
* Drop the rule from the lint selection if you want a clean exit.
|
|
1657
|
-
* @default true
|
|
1658
|
-
* @example
|
|
1659
|
-
* ```
|
|
1660
|
-
* policy: {
|
|
1661
|
-
* workspaceProtocol: { autofix: false },
|
|
1662
|
-
* }
|
|
1663
|
-
* ```
|
|
1664
|
-
*/
|
|
1665
|
-
autofix?: "prompt" | boolean;
|
|
1666
|
-
};
|
|
2418
|
+
* `VIS_NO_MCP_PROMOTE=1` is set. Set `enabled: false` to silence
|
|
2419
|
+
* permanently for this workspace.
|
|
2420
|
+
* @example
|
|
2421
|
+
* ```
|
|
2422
|
+
* mcpPromote: { enabled: false }
|
|
2423
|
+
* ```
|
|
2424
|
+
*/
|
|
2425
|
+
mcpPromote?: {
|
|
1667
2426
|
/**
|
|
1668
|
-
*
|
|
1669
|
-
*
|
|
2427
|
+
* Show the vis-mcp promotion notice on successful command completion.
|
|
2428
|
+
* @default true
|
|
1670
2429
|
*/
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
ignore?: string[];
|
|
1686
|
-
/**
|
|
1687
|
-
* Resolution strategy used when `--fix` runs.
|
|
1688
|
-
* - `highest` (default): rewrite every drifting instance to the
|
|
1689
|
-
* highest sibling specifier.
|
|
1690
|
-
* - `lowest`: rewrite to the lowest.
|
|
1691
|
-
* - `catalog`: rewrite any dep already pinned in a workspace catalog
|
|
1692
|
-
* to `catalog:` / `catalog:<name>`. Catalog must exist; this lint
|
|
1693
|
-
* does not create the catalog (see `vis lint --resolve catalog --propose`).
|
|
1694
|
-
* @default "highest"
|
|
1695
|
-
*/
|
|
1696
|
-
resolve?: "catalog" | "highest" | "lowest";
|
|
1697
|
-
};
|
|
2430
|
+
enabled?: boolean;
|
|
2431
|
+
};
|
|
2432
|
+
/**
|
|
2433
|
+
* Named input patterns inherited by every project target. Equivalent
|
|
2434
|
+
* to task-runner's `namedInputs` but configurable from the vis config.
|
|
2435
|
+
*/
|
|
2436
|
+
namedInputs?: NamedInputs;
|
|
2437
|
+
/**
|
|
2438
|
+
* NuGet projects as task projects. Off by default: each directory with one `*.csproj` or
|
|
2439
|
+
* `*.fsproj` (outside `bin`, `obj` and `node_modules`) gets build, test and format:check
|
|
2440
|
+
* targets when this is set. POSIX only: the inferred commands are not verified on Windows.
|
|
2441
|
+
*/
|
|
2442
|
+
nuget?: {
|
|
2443
|
+
discover?: boolean;
|
|
1698
2444
|
};
|
|
2445
|
+
/** Package override mappings applied during migration (e.g., `{ "lodash": "lodash-es" }`) */
|
|
2446
|
+
overrides?: Record<string, string>;
|
|
2447
|
+
/**
|
|
2448
|
+
* Plugins — each plugin registers typed hooks that fire at run /
|
|
2449
|
+
* task / cache boundaries. See {@link VisPlugin} for the contract.
|
|
2450
|
+
* Prefer plugins over per-target shell hooks when behaviour needs
|
|
2451
|
+
* access to task metadata, results, or cache state.
|
|
2452
|
+
*/
|
|
2453
|
+
plugins?: VisPlugin[];
|
|
2454
|
+
/**
|
|
2455
|
+
* Workspace dep-policy lints exposed via `vis lint`. Each block opts in
|
|
2456
|
+
* to a single rule; the command flags (`--workspace-protocol`,
|
|
2457
|
+
* `--no-redefine-root`, `--banned-deps`) toggle them per-run.
|
|
2458
|
+
*/
|
|
2459
|
+
policy?: Inline<VisPolicyConfig>;
|
|
1699
2460
|
/**
|
|
1700
2461
|
* Pre-flight checks fired before `vis run` starts the orchestrator.
|
|
1701
2462
|
* Each check is opt-out (`false`) — defaults are sensible for the
|
|
@@ -1880,682 +2641,7 @@ interface VisConfig {
|
|
|
1880
2641
|
* For npm/yarn/bun users: vis enforces these at the vis layer since
|
|
1881
2642
|
* those package managers lack native support.
|
|
1882
2643
|
*/
|
|
1883
|
-
security?:
|
|
1884
|
-
/**
|
|
1885
|
-
* Packages whose policy findings have been reviewed and explicitly
|
|
1886
|
-
* accepted. Matched against every policy unless `policies` narrows the
|
|
1887
|
-
* scope. Replaces the legacy `security.socket.acceptedRisks` map.
|
|
1888
|
-
*
|
|
1889
|
-
* Key format: package name (`"lodash"`), name@version
|
|
1890
|
-
* (`"lodash@4.17.21"`), or glob (`"@myorg/*"`). Unversioned keys match
|
|
1891
|
-
* all versions of that package.
|
|
1892
|
-
* @example
|
|
1893
|
-
* ```
|
|
1894
|
-
* acceptedRisks: {
|
|
1895
|
-
* "some-risky-pkg": {
|
|
1896
|
-
* reason: "Internal fork, low score expected",
|
|
1897
|
-
* acceptedAt: "2026-03-15T10:00:00Z",
|
|
1898
|
-
* acceptedScore: 0.25,
|
|
1899
|
-
* policies: ["score"],
|
|
1900
|
-
* expiresAt: "2026-12-31",
|
|
1901
|
-
* },
|
|
1902
|
-
* }
|
|
1903
|
-
* ```
|
|
1904
|
-
*/
|
|
1905
|
-
acceptedRisks?: Record<string, {
|
|
1906
|
-
/** ISO 8601 timestamp when the risk was accepted. */
|
|
1907
|
-
acceptedAt: string;
|
|
1908
|
-
/**
|
|
1909
|
-
* The overall Socket.dev score at the time of acceptance,
|
|
1910
|
-
* in the range `[0, 1]` (mirrors `policies.score.minimum`).
|
|
1911
|
-
* Only relevant for the `score` policy; ignored elsewhere.
|
|
1912
|
-
*/
|
|
1913
|
-
acceptedScore?: number;
|
|
1914
|
-
/**
|
|
1915
|
-
* ISO 8601 date (or datetime). After this point the acceptance
|
|
1916
|
-
* stops applying and vis emits a warning. Leave undefined for
|
|
1917
|
-
* non-expiring entries. Values that fail to parse as a Date
|
|
1918
|
-
* are rejected by the loader rather than silently treated as
|
|
1919
|
-
* "always expired".
|
|
1920
|
-
*/
|
|
1921
|
-
expiresAt?: string;
|
|
1922
|
-
/**
|
|
1923
|
-
* Which policies this acceptance covers. When undefined the
|
|
1924
|
-
* acceptance applies to every policy finding on this package.
|
|
1925
|
-
*/
|
|
1926
|
-
policies?: PolicyName[];
|
|
1927
|
-
/** User-provided reason for accepting the risk. */
|
|
1928
|
-
reason: string;
|
|
1929
|
-
}>;
|
|
1930
|
-
/**
|
|
1931
|
-
* Map of bin names (or `pkg#bin` qualifiers) blessed for shadowing.
|
|
1932
|
-
* When two installed packages expose the same bin name, vis flags
|
|
1933
|
-
* the collision in `vis security list` and the post-install drift
|
|
1934
|
-
* report — set the bin (or `pkg#bin`) to `true` here to suppress
|
|
1935
|
-
* the warning once you've reviewed the conflict.
|
|
1936
|
-
*
|
|
1937
|
-
* Port of LavaMoat allow-scripts' experimental `allowBins`.
|
|
1938
|
-
* Bare names match any conflicting bin with that name; the
|
|
1939
|
-
* `pkg#bin` form scopes the approval to a single package's bin.
|
|
1940
|
-
* @example
|
|
1941
|
-
* ```
|
|
1942
|
-
* allowBins: {
|
|
1943
|
-
* tsc: true, // bless any 'tsc' bin
|
|
1944
|
-
* "typescript#tsc": true, // bless only typescript's 'tsc'
|
|
1945
|
-
* }
|
|
1946
|
-
* ```
|
|
1947
|
-
*/
|
|
1948
|
-
allowBins?: Record<string, boolean>;
|
|
1949
|
-
/**
|
|
1950
|
-
* Offline OSV advisory + `vis audit` configuration.
|
|
1951
|
-
*
|
|
1952
|
-
* Controls `vis audit --offline` and `vis advisories sync` behavior:
|
|
1953
|
-
* - `audit.advisories.source` is the OSV mirror to download from. It
|
|
1954
|
-
* must be `https://` and resolve to a host in `allowedHosts` (or one
|
|
1955
|
-
* of the built-in defaults).
|
|
1956
|
-
* - `audit.offlineByDefault` flips the default of `--offline`.
|
|
1957
|
-
*
|
|
1958
|
-
* Vulnerability severity gating and reachability filtering live under
|
|
1959
|
-
* `policies.vulnerability` (see below).
|
|
1960
|
-
*/
|
|
1961
|
-
audit?: {
|
|
1962
|
-
/**
|
|
1963
|
-
* Offline advisory cache settings.
|
|
1964
|
-
*/
|
|
1965
|
-
advisories?: {
|
|
1966
|
-
/**
|
|
1967
|
-
* Extra hosts permitted as `audit.advisories.source`. The
|
|
1968
|
-
* built-in allowlist is enforced even if this field is
|
|
1969
|
-
* omitted; entries here add to it.
|
|
1970
|
-
* @example ["mirror.corp.example.com"]
|
|
1971
|
-
*/
|
|
1972
|
-
allowedHosts?: string[];
|
|
1973
|
-
/**
|
|
1974
|
-
* Bloom-filter prefilter for OSV `MAL-*` (malicious-package)
|
|
1975
|
-
* advisories. Probes a ~380 KB filter fetched from
|
|
1976
|
-
* `endevco/osv-bloom` and escalates hits to the existing
|
|
1977
|
-
* advisory query path for `(name, version)` confirmation.
|
|
1978
|
-
*
|
|
1979
|
-
* Cost: ~380 KB on the wire, refreshed every 10 minutes
|
|
1980
|
-
* upstream. False-positive rate is ~0.1%, so a typical
|
|
1981
|
-
* 1000-package lockfile triggers zero or one extra
|
|
1982
|
-
* round trip per audit.
|
|
1983
|
-
*
|
|
1984
|
-
* Independent of `audit.advisories.source` / `verify` —
|
|
1985
|
-
* those control the full OSV ingest. The bloom is
|
|
1986
|
-
* MAL-* only and aimed at cold-start preflight and
|
|
1987
|
-
* ephemeral CI runners that haven't synced the full DB.
|
|
1988
|
-
*/
|
|
1989
|
-
bloom?: {
|
|
1990
|
-
/**
|
|
1991
|
-
* Extra hosts permitted as `bloom.source`. The
|
|
1992
|
-
* built-in allowlist (`endevco.github.io`) is enforced
|
|
1993
|
-
* even if this field is omitted; entries here add to it.
|
|
1994
|
-
*/
|
|
1995
|
-
allowedHosts?: string[];
|
|
1996
|
-
/**
|
|
1997
|
-
* Prefilter mode:
|
|
1998
|
-
* - `off`: never run the bloom check.
|
|
1999
|
-
* - `on`: run when a local filter is cached; on
|
|
2000
|
-
* fetch failure, fall back to the cached filter or
|
|
2001
|
-
* skip the prefilter (audit continues against the
|
|
2002
|
-
* non-bloom path).
|
|
2003
|
-
* - `required`: hard-fail the audit when the bloom
|
|
2004
|
-
* refresh fails or the local cache is missing.
|
|
2005
|
-
* Use in hardened CI together with
|
|
2006
|
-
* `audit.advisories.source`.
|
|
2007
|
-
* @default "off"
|
|
2008
|
-
*/
|
|
2009
|
-
mode?: "off" | "on" | "required";
|
|
2010
|
-
/**
|
|
2011
|
-
* Bloom mirror base URL (no trailing slash). Defaults
|
|
2012
|
-
* to the public `endevco/osv-bloom` GH Pages site.
|
|
2013
|
-
* Override only if you mirror the bloom artifacts
|
|
2014
|
-
* internally; the hostname must appear in
|
|
2015
|
-
* `allowedHosts`.
|
|
2016
|
-
* @default "https://endevco.github.io/osv-bloom"
|
|
2017
|
-
*/
|
|
2018
|
-
source?: string;
|
|
2019
|
-
};
|
|
2020
|
-
/**
|
|
2021
|
-
* Number of hours after `lastSyncIso` before `vis audit`
|
|
2022
|
-
* prints a "your advisory cache may be stale" notice.
|
|
2023
|
-
* `vis audit` never auto-syncs — the user runs
|
|
2024
|
-
* `vis advisories sync` themselves.
|
|
2025
|
-
* @default 24
|
|
2026
|
-
*/
|
|
2027
|
-
refreshIntervalHours?: number;
|
|
2028
|
-
/**
|
|
2029
|
-
* OSV mirror base URL (no trailing slash). Defaults to the
|
|
2030
|
-
* public Google Cloud Storage bucket. Override to point at a
|
|
2031
|
-
* corporate mirror; the hostname must appear in `allowedHosts`
|
|
2032
|
-
* (or one of the built-in defaults) and the scheme must be
|
|
2033
|
-
* `https://`.
|
|
2034
|
-
* @default "https://osv-vulnerabilities.storage.googleapis.com"
|
|
2035
|
-
*/
|
|
2036
|
-
source?: string;
|
|
2037
|
-
/**
|
|
2038
|
-
* Sigstore signature verification for the OSV dump.
|
|
2039
|
-
* Requires the native binding to be built with the
|
|
2040
|
-
* `verify-signatures` Cargo feature (default in the release
|
|
2041
|
-
* build). Off by default — the upstream OSV bucket does not
|
|
2042
|
-
* ship signatures today.
|
|
2043
|
-
*/
|
|
2044
|
-
verify?: {
|
|
2045
|
-
/**
|
|
2046
|
-
* Enable signature verification. The sync flow downloads
|
|
2047
|
-
* `<eco>/all.zip.sig` next to the zip and aborts if it
|
|
2048
|
-
* cannot verify against `expectedIssuer` / `expectedSubject`.
|
|
2049
|
-
* @default false
|
|
2050
|
-
*/
|
|
2051
|
-
enabled?: boolean;
|
|
2052
|
-
/** OIDC issuer that signed the bundle. */
|
|
2053
|
-
expectedIssuer?: string;
|
|
2054
|
-
/** OIDC subject (workload identity) that signed the bundle. */
|
|
2055
|
-
expectedSubject?: string;
|
|
2056
|
-
};
|
|
2057
|
-
};
|
|
2058
|
-
/**
|
|
2059
|
-
* Gates for the auto-fix flow (`vis audit --fix` /
|
|
2060
|
-
* `--fix-transitive`). The CLI prompts outside CI; inside CI
|
|
2061
|
-
* the flags refuse to run unless `--yes` is set and, for
|
|
2062
|
-
* transitives, `apply.transitive.enabled = true`.
|
|
2063
|
-
*/
|
|
2064
|
-
apply?: {
|
|
2065
|
-
/**
|
|
2066
|
-
* Gates for `vis audit --fix-transitive`. Two-lock: the
|
|
2067
|
-
* CLI requires `--yes` AND this flag set to `true` before
|
|
2068
|
-
* it will rewrite override entries in CI.
|
|
2069
|
-
*/
|
|
2070
|
-
transitive?: {
|
|
2071
|
-
/**
|
|
2072
|
-
* When true, allows `--fix-transitive` to run in CI
|
|
2073
|
-
* environments. Defaults to false because rewriting
|
|
2074
|
-
* overrides is a higher blast radius than bumping a
|
|
2075
|
-
* direct dep.
|
|
2076
|
-
* @default false
|
|
2077
|
-
*/
|
|
2078
|
-
enabled?: boolean;
|
|
2079
|
-
};
|
|
2080
|
-
};
|
|
2081
|
-
/**
|
|
2082
|
-
* Vulnerability scanner backend.
|
|
2083
|
-
*
|
|
2084
|
-
* - `auto` (default): delegate to `aube audit` when aube is the
|
|
2085
|
-
* active installer (its scanner reads the same lockfile and
|
|
2086
|
-
* produces equivalent severity ratings); otherwise run vis's
|
|
2087
|
-
* own OSV/Socket scanner.
|
|
2088
|
-
* - `aube`: always delegate to `aube audit`. Errors if `aube` is
|
|
2089
|
-
* not on PATH.
|
|
2090
|
-
* - `vis`: always use vis's built-in scanner — never delegate.
|
|
2091
|
-
*
|
|
2092
|
-
* Delegation avoids redundant work (aube already has a
|
|
2093
|
-
* full-fidelity audit pass that respects its own exclusions
|
|
2094
|
-
* via `aube-workspace.yaml::auditConfig`) and lets users get
|
|
2095
|
-
* a single, consistent result regardless of which entry point
|
|
2096
|
-
* they invoke.
|
|
2097
|
-
* @default "auto"
|
|
2098
|
-
*/
|
|
2099
|
-
backend?: "aube" | "auto" | "vis";
|
|
2100
|
-
/**
|
|
2101
|
-
* When true, `vis audit` skips network calls and queries the
|
|
2102
|
-
* offline cache. Equivalent to the CLI `--offline` flag.
|
|
2103
|
-
* @default false
|
|
2104
|
-
*/
|
|
2105
|
-
offlineByDefault?: boolean;
|
|
2106
|
-
};
|
|
2107
|
-
/**
|
|
2108
|
-
* When true, prevents transitive dependencies from using exotic sources
|
|
2109
|
-
* (git repositories, direct tarball URLs). Only direct dependencies may
|
|
2110
|
-
* use such sources. Equivalent to pnpm's `blockExoticSubdeps`.
|
|
2111
|
-
* @default false
|
|
2112
|
-
*/
|
|
2113
|
-
blockExoticSubdeps?: boolean;
|
|
2114
|
-
/**
|
|
2115
|
-
* deps.dev (Google Open Source Insights) data-source configuration.
|
|
2116
|
-
* Public, unauthenticated; pulls Scorecard data + advisories from
|
|
2117
|
-
* `api.deps.dev`. Complements or replaces Socket.dev. Heavily cached.
|
|
2118
|
-
* @see https://docs.deps.dev/api/v3/
|
|
2119
|
-
*/
|
|
2120
|
-
depsDev?: {
|
|
2121
|
-
/**
|
|
2122
|
-
* Cache TTL for advisory entries (immutable once published). 7 days.
|
|
2123
|
-
* @default 604800000
|
|
2124
|
-
*/
|
|
2125
|
-
advisoryCacheTtlMs?: number;
|
|
2126
|
-
/**
|
|
2127
|
-
* Enable deps.dev scanning on install/update/check/audit commands.
|
|
2128
|
-
* @default false
|
|
2129
|
-
*/
|
|
2130
|
-
enabled?: boolean;
|
|
2131
|
-
/**
|
|
2132
|
-
* Cache TTL for OpenSSF Scorecard project data (refreshes weekly). 24 hours.
|
|
2133
|
-
* @default 86400000
|
|
2134
|
-
*/
|
|
2135
|
-
projectCacheTtlMs?: number;
|
|
2136
|
-
/**
|
|
2137
|
-
* Request timeout in milliseconds.
|
|
2138
|
-
* @default 15000
|
|
2139
|
-
*/
|
|
2140
|
-
timeoutMs?: number;
|
|
2141
|
-
/**
|
|
2142
|
-
* Cache TTL for npm version metadata (immutable). 7 days.
|
|
2143
|
-
* @default 604800000
|
|
2144
|
-
*/
|
|
2145
|
-
versionCacheTtlMs?: number;
|
|
2146
|
-
};
|
|
2147
|
-
/**
|
|
2148
|
-
* Package names exempted from the `blockExoticSubdeps` check.
|
|
2149
|
-
* Bare names and a trailing `*` glob (`@scope/*`) are supported.
|
|
2150
|
-
* Use for an internal package legitimately published as a git or
|
|
2151
|
-
* tarball dependency.
|
|
2152
|
-
* @example ["@myorg/legacy", "internal-*"]
|
|
2153
|
-
*/
|
|
2154
|
-
exoticSubdepsAllow?: string[];
|
|
2155
|
-
/**
|
|
2156
|
-
* Pre-install marshall pipeline — packument-derived supply-chain
|
|
2157
|
-
* gates (author, provenance, s1ngularity, new-bin, metadata,
|
|
2158
|
-
* downloads, expired-domains, signatures, archived-repo) that run before
|
|
2159
|
-
* `vis add` / `vis install <pkg>` / `vis update <pkg>` hand off to
|
|
2160
|
-
* the underlying package manager. Every entry is optional; omit a
|
|
2161
|
-
* key and the marshall runs with defaults. Set `enabled: false`
|
|
2162
|
-
* on a specific marshall to skip it without touching env vars.
|
|
2163
|
-
*/
|
|
2164
|
-
marshalls?: {
|
|
2165
|
-
/** Archived-repo marshall (GitHub repository status). */
|
|
2166
|
-
archivedRepo?: {
|
|
2167
|
-
/** Package names to skip. */
|
|
2168
|
-
allowlist?: string[];
|
|
2169
|
-
/** Default: marshall is on. Set false to disable. */
|
|
2170
|
-
enabled?: boolean;
|
|
2171
|
-
/** GitHub PAT for the API call (5k/hr vs 60/hr). */
|
|
2172
|
-
githubToken?: string;
|
|
2173
|
-
};
|
|
2174
|
-
/** Author / publisher heuristics. */
|
|
2175
|
-
author?: {
|
|
2176
|
-
allowlist?: string[];
|
|
2177
|
-
/** Days since the publisher's last release before flagging as error. */
|
|
2178
|
-
dormantErrorDays?: number;
|
|
2179
|
-
/** Days since the publisher's last release before flagging as warning. */
|
|
2180
|
-
dormantWarnDays?: number;
|
|
2181
|
-
enabled?: boolean;
|
|
2182
|
-
/** Window for the "new publisher on an established package" check. */
|
|
2183
|
-
newPublisherWindowDays?: number;
|
|
2184
|
-
/** Days since the resolved version was published — error threshold. */
|
|
2185
|
-
recentVersionErrorDays?: number;
|
|
2186
|
-
/** Days since the resolved version was published — warning threshold. */
|
|
2187
|
-
recentVersionWarnDays?: number;
|
|
2188
|
-
};
|
|
2189
|
-
/** npm `deprecated`-flag check on the resolved version. */
|
|
2190
|
-
deprecation?: {
|
|
2191
|
-
allowlist?: string[];
|
|
2192
|
-
enabled?: boolean;
|
|
2193
|
-
};
|
|
2194
|
-
/** Monthly download-count floor. */
|
|
2195
|
-
downloads?: {
|
|
2196
|
-
allowlist?: string[];
|
|
2197
|
-
enabled?: boolean;
|
|
2198
|
-
/** Below this monthly count → error (default: 20). */
|
|
2199
|
-
errorThreshold?: number;
|
|
2200
|
-
/** Below this monthly count → warning (default: 1000). */
|
|
2201
|
-
warnThreshold?: number;
|
|
2202
|
-
};
|
|
2203
|
-
/** Maintainer-email-domain NS lookup. */
|
|
2204
|
-
expiredDomains?: {
|
|
2205
|
-
/** Domains exempted from the check (legacy / internal). */
|
|
2206
|
-
allowDomains?: string[];
|
|
2207
|
-
allowlist?: string[];
|
|
2208
|
-
/** DNS resolvers to query (default: system). */
|
|
2209
|
-
dnsServers?: string[];
|
|
2210
|
-
enabled?: boolean;
|
|
2211
|
-
/** Per-domain DNS timeout (default: 5000). */
|
|
2212
|
-
timeoutMs?: number;
|
|
2213
|
-
};
|
|
2214
|
-
/** README / license / repository presence checks. */
|
|
2215
|
-
metadata?: {
|
|
2216
|
-
allowlist?: string[];
|
|
2217
|
-
/** Subset of checks to run. Default: all three. */
|
|
2218
|
-
checks?: ("license" | "readme" | "repo")[];
|
|
2219
|
-
enabled?: boolean;
|
|
2220
|
-
};
|
|
2221
|
-
/** New CLI-bin script introduced in this version. */
|
|
2222
|
-
newBin?: {
|
|
2223
|
-
allowlist?: string[];
|
|
2224
|
-
enabled?: boolean;
|
|
2225
|
-
};
|
|
2226
|
-
/** Whole-package age heuristics (newly created / unmaintained). */
|
|
2227
|
-
packageAge?: {
|
|
2228
|
-
allowlist?: string[];
|
|
2229
|
-
enabled?: boolean;
|
|
2230
|
-
/** Package created fewer than this many days ago → error. Default 22. */
|
|
2231
|
-
newPackageDays?: number;
|
|
2232
|
-
/** No publish within this many days → warning. Default 365. */
|
|
2233
|
-
unmaintainedDays?: number;
|
|
2234
|
-
};
|
|
2235
|
-
/** Provenance regression check. */
|
|
2236
|
-
provenance?: {
|
|
2237
|
-
allowlist?: string[];
|
|
2238
|
-
enabled?: boolean;
|
|
2239
|
-
};
|
|
2240
|
-
/**
|
|
2241
|
-
* Composite "compromised-publish shape" detector — flags a single
|
|
2242
|
-
* version that simultaneously introduced/changed an install hook
|
|
2243
|
-
* AND dropped the provenance attestation a prior stable version
|
|
2244
|
-
* carried (the August 2025 s1ngularity / Nx fingerprint).
|
|
2245
|
-
*/
|
|
2246
|
-
s1ngularity?: {
|
|
2247
|
-
allowlist?: string[];
|
|
2248
|
-
enabled?: boolean;
|
|
2249
|
-
};
|
|
2250
|
-
/**
|
|
2251
|
-
* ECDSA P-256 verification against npm's signing keys. Disabled
|
|
2252
|
-
* by default because npm coverage still has gaps that produce
|
|
2253
|
-
* noisy warnings on legitimate packages.
|
|
2254
|
-
*/
|
|
2255
|
-
signatures?: {
|
|
2256
|
-
allowlist?: string[];
|
|
2257
|
-
/** Default: marshall is *off*. Set true to enable. */
|
|
2258
|
-
enabled?: boolean;
|
|
2259
|
-
/** Override the keys endpoint (default: npm registry). */
|
|
2260
|
-
keysUrl?: string;
|
|
2261
|
-
/** How to treat an expired-but-known key. Default: "warning". */
|
|
2262
|
-
treatExpiredAs?: "error" | "warning";
|
|
2263
|
-
};
|
|
2264
|
-
};
|
|
2265
|
-
/**
|
|
2266
|
-
* When true, `security.policies.installScripts.allow` keys are matched
|
|
2267
|
-
* as `name@version`. A version bump on an approved package drops it from
|
|
2268
|
-
* the allowlist until the new version is explicitly re-approved (port
|
|
2269
|
-
* of LavaMoat allow-scripts' version-aware policy matcher).
|
|
2270
|
-
*
|
|
2271
|
-
* After a version bump, run `vis approve-builds` or `vis security list`
|
|
2272
|
-
* — both surface a "Version drift" block with the suggested new key
|
|
2273
|
-
* (`old-key → new-key`) so you can update `vis.config.ts` by hand.
|
|
2274
|
-
* @default false
|
|
2275
|
-
*/
|
|
2276
|
-
pinVersions?: boolean;
|
|
2277
|
-
/**
|
|
2278
|
-
* Supply-chain policy gates. Each sub-block enables one policy and
|
|
2279
|
-
* configures its behavior. When a sub-block is omitted the policy is
|
|
2280
|
-
* inactive. `acceptedRisks` (above) silences specific packages without
|
|
2281
|
-
* disabling a policy globally.
|
|
2282
|
-
*
|
|
2283
|
-
* The 8 policies are inspired by Socket.dev's classification:
|
|
2284
|
-
* - `malware` — Socket-flagged malicious packages
|
|
2285
|
-
* - `firstSeen` — packages published less than N minutes ago
|
|
2286
|
-
* - `unexpectedDeps` — packages outside an allow-list / baseline
|
|
2287
|
-
* - `publisherChange` — maintainer set changed between installs
|
|
2288
|
-
* - `installScripts` — preinstall/install/postinstall scripts
|
|
2289
|
-
* - `score` — Socket overall score below threshold
|
|
2290
|
-
* - `vulnerability` — OSV vulnerability findings
|
|
2291
|
-
* - `license` — SPDX allow / deny lists
|
|
2292
|
-
*/
|
|
2293
|
-
policies?: {
|
|
2294
|
-
/**
|
|
2295
|
-
* Minimum number of minutes that must pass after a version is
|
|
2296
|
-
* published before vis will allow installation. Migrated from
|
|
2297
|
-
* the legacy `security.minimumReleaseAge` field. Equivalent to
|
|
2298
|
-
* pnpm's `minimumReleaseAge`.
|
|
2299
|
-
* @default 0
|
|
2300
|
-
* @example { minutes: 1440, exclude: ["@myorg/*"] } // 24 hours
|
|
2301
|
-
*/
|
|
2302
|
-
firstSeen?: {
|
|
2303
|
-
/**
|
|
2304
|
-
* Package names/patterns excluded from the firstSeen check.
|
|
2305
|
-
* Equivalent to pnpm's `minimumReleaseAgeExclude`.
|
|
2306
|
-
* @example ["webpack", "react", "@myorg/*"]
|
|
2307
|
-
*/
|
|
2308
|
-
exclude?: string[];
|
|
2309
|
-
/** Minutes after publish before install is allowed. */
|
|
2310
|
-
minutes?: number;
|
|
2311
|
-
};
|
|
2312
|
-
/**
|
|
2313
|
-
* Build-script (pre/install/postinstall/prepare) controls.
|
|
2314
|
-
* Migrated from the legacy `security.allowBuilds` /
|
|
2315
|
-
* `security.strictDepBuilds` fields.
|
|
2316
|
-
* @example { allow: { esbuild: true }, strict: true }
|
|
2317
|
-
*/
|
|
2318
|
-
installScripts?: {
|
|
2319
|
-
/**
|
|
2320
|
-
* Map of package names/patterns to allow (true) or deny
|
|
2321
|
-
* (false) build scripts. Packages not listed are denied
|
|
2322
|
-
* by default. Equivalent to pnpm's `allowBuilds`.
|
|
2323
|
-
*/
|
|
2324
|
-
allow?: Record<string, boolean>;
|
|
2325
|
-
/**
|
|
2326
|
-
* When true, installation will fail (exit non-zero) if any
|
|
2327
|
-
* dependencies have unreviewed build scripts. Equivalent to
|
|
2328
|
-
* pnpm's `strictDepBuilds`.
|
|
2329
|
-
* @default false
|
|
2330
|
-
*/
|
|
2331
|
-
strict?: boolean;
|
|
2332
|
-
};
|
|
2333
|
-
/**
|
|
2334
|
-
* SPDX license allow / deny lists. Deny wins on any sub-license
|
|
2335
|
-
* match in SPDX expressions (`(MIT OR GPL-3.0)` against
|
|
2336
|
-
* `deny: ["GPL-3.0"]` is blocked). Packages with no declared
|
|
2337
|
-
* license are flagged when `allow` is set.
|
|
2338
|
-
* @example
|
|
2339
|
-
* ```
|
|
2340
|
-
* license: {
|
|
2341
|
-
* allow: ["MIT", "Apache-2.0", "BSD-3-Clause"],
|
|
2342
|
-
* deny: ["GPL-3.0", "AGPL-3.0"],
|
|
2343
|
-
* }
|
|
2344
|
-
* ```
|
|
2345
|
-
*/
|
|
2346
|
-
license?: {
|
|
2347
|
-
/**
|
|
2348
|
-
* SPDX identifiers that are explicitly permitted. When set,
|
|
2349
|
-
* any package whose declared license is not on this list is
|
|
2350
|
-
* blocked.
|
|
2351
|
-
*/
|
|
2352
|
-
allow?: string[];
|
|
2353
|
-
/**
|
|
2354
|
-
* SPDX identifiers that are explicitly forbidden. Always
|
|
2355
|
-
* wins over `allow` when both reference the same identifier.
|
|
2356
|
-
*/
|
|
2357
|
-
deny?: string[];
|
|
2358
|
-
};
|
|
2359
|
-
/**
|
|
2360
|
-
* Behavior when the Socket.dev feed flags a package as malicious
|
|
2361
|
-
* (`alerts[].type === "Malware"`).
|
|
2362
|
-
*
|
|
2363
|
-
* The default is cross-field: `{ mode: "block" }` whenever
|
|
2364
|
-
* `security.socket.enabled !== false` (the engine cannot evaluate
|
|
2365
|
-
* malware without Socket data), and `"off"` otherwise. Consumers
|
|
2366
|
-
* resolve this default at evaluation time.
|
|
2367
|
-
*/
|
|
2368
|
-
malware?: {
|
|
2369
|
-
/**
|
|
2370
|
-
* - `"block"` — emit a block decision.
|
|
2371
|
-
* - `"warn"` — surface as a warning; do not gate exit code.
|
|
2372
|
-
* - `"off"` — disable the policy entirely.
|
|
2373
|
-
*/
|
|
2374
|
-
mode?: "block" | "off" | "warn";
|
|
2375
|
-
};
|
|
2376
|
-
/**
|
|
2377
|
-
* Trust-level checking for package publishing. Migrated from the
|
|
2378
|
-
* legacy `security.trustPolicy*` fields. Equivalent to pnpm's
|
|
2379
|
-
* `trustPolicy`.
|
|
2380
|
-
* @example { mode: "no-downgrade", ignoreAfter: 43200 } // 30 days
|
|
2381
|
-
*/
|
|
2382
|
-
publisherChange?: {
|
|
2383
|
-
/**
|
|
2384
|
-
* Package selectors excluded from the check.
|
|
2385
|
-
* Equivalent to pnpm's `trustPolicyExclude`.
|
|
2386
|
-
* @example ["chokidar@4.0.3"]
|
|
2387
|
-
*/
|
|
2388
|
-
exclude?: string[];
|
|
2389
|
-
/**
|
|
2390
|
-
* Ignore packages published more than N minutes ago. Useful
|
|
2391
|
-
* for older packages that pre-date provenance support.
|
|
2392
|
-
* Equivalent to pnpm's `trustPolicyIgnoreAfter`.
|
|
2393
|
-
*/
|
|
2394
|
-
ignoreAfter?: number;
|
|
2395
|
-
/**
|
|
2396
|
-
* - `"off"` — no trust checking (default).
|
|
2397
|
-
* - `"no-downgrade"` — block when a package's trust level
|
|
2398
|
-
* has decreased compared to previous releases (e.g., was
|
|
2399
|
-
* published by trusted publisher, now only has provenance).
|
|
2400
|
-
*/
|
|
2401
|
-
mode?: "no-downgrade" | "off";
|
|
2402
|
-
};
|
|
2403
|
-
/**
|
|
2404
|
-
* Socket.dev overall-score threshold. Packages scoring below
|
|
2405
|
-
* `minimum` trigger a block decision (or interactive prompt
|
|
2406
|
-
* during `vis add`). Migrated from the legacy
|
|
2407
|
-
* `security.socket.minimumScore` field.
|
|
2408
|
-
* @example { minimum: 0.4 }
|
|
2409
|
-
*/
|
|
2410
|
-
score?: {
|
|
2411
|
-
/**
|
|
2412
|
-
* Minimum overall Socket.dev score (0–1). Set to 0 to
|
|
2413
|
-
* disable the gate while keeping Socket data fetched.
|
|
2414
|
-
*
|
|
2415
|
-
* Consulted by `vis add`, `audit`, `doctor`, `check`, and
|
|
2416
|
-
* `update`; resolved once in `buildSocketOptions`, then
|
|
2417
|
-
* threaded through every consumer. Falls back to
|
|
2418
|
-
* `DEFAULT_LOW_SCORE_THRESHOLD` (`0.4`) when unset.
|
|
2419
|
-
*/
|
|
2420
|
-
minimum?: number;
|
|
2421
|
-
};
|
|
2422
|
-
/**
|
|
2423
|
-
* Net-new transitive dependency detection. Either provide a
|
|
2424
|
-
* static allow-list, a baseline lockfile path (recommended), or
|
|
2425
|
-
* both — the intersection is enforced.
|
|
2426
|
-
* @example { baselineLockfile: "./security/lockfile.baseline.yaml" }
|
|
2427
|
-
*/
|
|
2428
|
-
unexpectedDeps?: {
|
|
2429
|
-
/**
|
|
2430
|
-
* Allow-list of dependency names that may appear in the
|
|
2431
|
-
* resolved package set. Glob patterns are supported.
|
|
2432
|
-
* @example ["lodash", "axios", "@myorg/*"]
|
|
2433
|
-
*/
|
|
2434
|
-
allow?: string[];
|
|
2435
|
-
/**
|
|
2436
|
-
* Path (absolute or relative to the workspace root) to a
|
|
2437
|
-
* baseline lockfile snapshot. The policy diffs the current
|
|
2438
|
-
* lockfile against this baseline and flags any package that
|
|
2439
|
-
* didn't exist before.
|
|
2440
|
-
* @example "./security/lockfile.baseline.yaml"
|
|
2441
|
-
*/
|
|
2442
|
-
baselineLockfile?: string;
|
|
2443
|
-
};
|
|
2444
|
-
/**
|
|
2445
|
-
* OSV vulnerability gating. Migrated from the legacy
|
|
2446
|
-
* `security.audit.failOn` + `security.audit.usage` fields.
|
|
2447
|
-
*/
|
|
2448
|
-
vulnerability?: {
|
|
2449
|
-
/**
|
|
2450
|
-
* Severity threshold that makes `vis audit` exit non-zero.
|
|
2451
|
-
* Equivalent to the CLI `--fail-on` flag.
|
|
2452
|
-
* @example "high"
|
|
2453
|
-
*/
|
|
2454
|
-
failOn?: "critical" | "high" | "low" | "medium";
|
|
2455
|
-
/**
|
|
2456
|
-
* Reachability filter — only report vulnerabilities in
|
|
2457
|
-
* packages the workspace statically imports.
|
|
2458
|
-
*/
|
|
2459
|
-
usage?: {
|
|
2460
|
-
/**
|
|
2461
|
-
* Packages to always treat as reachable even if no
|
|
2462
|
-
* static import is found.
|
|
2463
|
-
* @example ["esbuild", "webpack-cli"]
|
|
2464
|
-
*/
|
|
2465
|
-
alwaysAssumeUsed?: string[];
|
|
2466
|
-
/**
|
|
2467
|
-
* Enable the reachability filter by default. Equivalent
|
|
2468
|
-
* to `--usage` on the CLI; `--no-usage` disables.
|
|
2469
|
-
* @default false
|
|
2470
|
-
*/
|
|
2471
|
-
enabled?: boolean;
|
|
2472
|
-
};
|
|
2473
|
-
};
|
|
2474
|
-
};
|
|
2475
|
-
/**
|
|
2476
|
-
* Which provider wins merge conflicts when multiple are enabled (e.g.
|
|
2477
|
-
* both Socket.dev and deps.dev return data for the same package). The
|
|
2478
|
-
* primary provider's `score` is kept; alerts from secondaries are
|
|
2479
|
-
* appended and deduped by `key`. Defaults to whichever provider is
|
|
2480
|
-
* enabled first in this order: socket → deps-dev → snyk.
|
|
2481
|
-
*/
|
|
2482
|
-
primaryProvider?: "deps-dev" | "snyk" | "socket";
|
|
2483
|
-
/**
|
|
2484
|
-
* Snyk data-source configuration. Snyk only contributes vulnerability
|
|
2485
|
-
* data (no maintenance / quality / supply-chain / license signal);
|
|
2486
|
-
* those axes stay neutral. Requires both an org id and an API token —
|
|
2487
|
-
* if either is missing the provider is skipped.
|
|
2488
|
-
* @see https://docs.snyk.io/snyk-api/using-specific-snyk-apis/issues-list-issues-for-a-package
|
|
2489
|
-
*/
|
|
2490
|
-
snyk?: {
|
|
2491
|
-
/**
|
|
2492
|
-
* Snyk API token. Set via VIS_SNYK_TOKEN environment variable or
|
|
2493
|
-
* here.
|
|
2494
|
-
*/
|
|
2495
|
-
apiToken?: string;
|
|
2496
|
-
/**
|
|
2497
|
-
* Snyk REST API version date sent as the `version` query param.
|
|
2498
|
-
* @default "2024-10-15"
|
|
2499
|
-
*/
|
|
2500
|
-
apiVersion?: string;
|
|
2501
|
-
/**
|
|
2502
|
-
* Cache TTL in milliseconds for Snyk issue lookups. 6 hours.
|
|
2503
|
-
* @default 21600000
|
|
2504
|
-
*/
|
|
2505
|
-
cacheTtlMs?: number;
|
|
2506
|
-
/**
|
|
2507
|
-
* Enable Snyk security scanning on install/update/check/audit
|
|
2508
|
-
* commands.
|
|
2509
|
-
* @default false
|
|
2510
|
-
*/
|
|
2511
|
-
enabled?: boolean;
|
|
2512
|
-
/**
|
|
2513
|
-
* Snyk organization id (the REST endpoint is org-scoped). Set via
|
|
2514
|
-
* VIS_SNYK_ORG environment variable or here.
|
|
2515
|
-
*/
|
|
2516
|
-
orgId?: string;
|
|
2517
|
-
/**
|
|
2518
|
-
* Request timeout in milliseconds for the Snyk API. 15 seconds.
|
|
2519
|
-
* @default 15000
|
|
2520
|
-
*/
|
|
2521
|
-
timeoutMs?: number;
|
|
2522
|
-
};
|
|
2523
|
-
/**
|
|
2524
|
-
* Socket.dev data-source configuration. Connection knobs only — score
|
|
2525
|
-
* thresholds and accepted-risk overrides moved to `policies.score` and
|
|
2526
|
-
* `security.acceptedRisks` respectively.
|
|
2527
|
-
* @see https://socket.dev
|
|
2528
|
-
*/
|
|
2529
|
-
socket?: {
|
|
2530
|
-
/**
|
|
2531
|
-
* Custom Socket.dev API token. Falls back to the public API token.
|
|
2532
|
-
* Set via VIS_SOCKET_TOKEN environment variable or here.
|
|
2533
|
-
*/
|
|
2534
|
-
apiToken?: string;
|
|
2535
|
-
/**
|
|
2536
|
-
* Cache TTL in milliseconds for Socket.dev reports. 1 hour.
|
|
2537
|
-
* @default 3600000
|
|
2538
|
-
*/
|
|
2539
|
-
cacheTtlMs?: number;
|
|
2540
|
-
/**
|
|
2541
|
-
* Enable Socket.dev security scanning on install/update/check commands.
|
|
2542
|
-
* @default false
|
|
2543
|
-
*/
|
|
2544
|
-
enabled?: boolean;
|
|
2545
|
-
/**
|
|
2546
|
-
* Request timeout in milliseconds for the Socket.dev API. 15 seconds.
|
|
2547
|
-
* @default 15000
|
|
2548
|
-
*/
|
|
2549
|
-
timeoutMs?: number;
|
|
2550
|
-
};
|
|
2551
|
-
/**
|
|
2552
|
-
* Package names to skip during typosquat detection.
|
|
2553
|
-
* Use this for internal packages or known-safe names that happen to
|
|
2554
|
-
* look similar to popular packages.
|
|
2555
|
-
* @example ["my-internal-axois", "@myorg/recat"]
|
|
2556
|
-
*/
|
|
2557
|
-
typosquatAllowlist?: string[];
|
|
2558
|
-
};
|
|
2644
|
+
security?: Inline<VisSecurityConfig>;
|
|
2559
2645
|
/**
|
|
2560
2646
|
* Share the cache between sibling git worktrees. When the workspace is a
|
|
2561
2647
|
* linked worktree (created with `git worktree add`), the cache root is
|
|
@@ -2688,83 +2774,7 @@ interface VisConfig {
|
|
|
2688
2774
|
autoExit?: boolean | number;
|
|
2689
2775
|
};
|
|
2690
2776
|
/** Update command defaults */
|
|
2691
|
-
update?:
|
|
2692
|
-
/**
|
|
2693
|
-
* Dependency fields to scan for outdated packages.
|
|
2694
|
-
* Beyond the standard fields, supports:
|
|
2695
|
-
* - `"overrides"` (npm)
|
|
2696
|
-
* - `"resolutions"` (yarn)
|
|
2697
|
-
* - `"pnpm.overrides"`
|
|
2698
|
-
* @default ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"]
|
|
2699
|
-
*/
|
|
2700
|
-
depFields?: string[];
|
|
2701
|
-
exclude?: string[];
|
|
2702
|
-
format?: "json" | "minimal" | "table";
|
|
2703
|
-
/**
|
|
2704
|
-
* Package names or glob patterns to permanently ignore during updates.
|
|
2705
|
-
* Ignored packages are skipped and listed in the output so you know
|
|
2706
|
-
* they were not checked.
|
|
2707
|
-
* @example ["eslint", "@types/*"]
|
|
2708
|
-
*/
|
|
2709
|
-
ignore?: string[];
|
|
2710
|
-
include?: string[];
|
|
2711
|
-
/**
|
|
2712
|
-
* Include packages with pinned/exact versions (no `^` or `~` prefix).
|
|
2713
|
-
* By default, pinned versions are skipped during update checks.
|
|
2714
|
-
* @default false
|
|
2715
|
-
*/
|
|
2716
|
-
includeLocked?: boolean;
|
|
2717
|
-
install?: boolean;
|
|
2718
|
-
/**
|
|
2719
|
-
* Maximum number of concurrent registry requests during outdated checks.
|
|
2720
|
-
* Higher values speed up large workspaces but risk hitting registry rate
|
|
2721
|
-
* limits or self-hosted Verdaccio caps.
|
|
2722
|
-
* @default 8
|
|
2723
|
-
*/
|
|
2724
|
-
maxConcurrentRequests?: number;
|
|
2725
|
-
/**
|
|
2726
|
-
* Minimum number of minutes since a version was published before
|
|
2727
|
-
* vis will consider it for updates. This mirrors pnpm's
|
|
2728
|
-
* `minimumReleaseAge` — a single setting that applies to both
|
|
2729
|
-
* install and update.
|
|
2730
|
-
*
|
|
2731
|
-
* Not set by default. If your package manager config
|
|
2732
|
-
* (`pnpm-workspace.yaml`) has `minimumReleaseAge`, vis will
|
|
2733
|
-
* read it from there as a fallback.
|
|
2734
|
-
* @example 1440 // 24 hours
|
|
2735
|
-
*/
|
|
2736
|
-
minimumReleaseAge?: number;
|
|
2737
|
-
/**
|
|
2738
|
-
* Package names/patterns excluded from the minimumReleaseAge check.
|
|
2739
|
-
* @example ["webpack", "@myorg/*"]
|
|
2740
|
-
*/
|
|
2741
|
-
minimumReleaseAgeExclude?: string[];
|
|
2742
|
-
/**
|
|
2743
|
-
* Per-package or per-pattern update target overrides.
|
|
2744
|
-
* Keys are exact package names, glob patterns, or regex patterns
|
|
2745
|
-
* wrapped in `/` (e.g., `/^@vue/`).
|
|
2746
|
-
* Values are `"latest"`, `"minor"`, or `"patch"`.
|
|
2747
|
-
* @example { "typescript": "minor", "/^@vue/": "patch" }
|
|
2748
|
-
*/
|
|
2749
|
-
packageMode?: Record<string, "latest" | "minor" | "patch">;
|
|
2750
|
-
prerelease?: boolean;
|
|
2751
|
-
/**
|
|
2752
|
-
* Which release channels to consider when picking the target version.
|
|
2753
|
-
* - `"stable"` (default) — only ship stable releases (no prereleases).
|
|
2754
|
-
* - `"same"` — match the prerelease channel of the *current* range:
|
|
2755
|
-
* if you're on `react@19.0.0-rc.1`, only `rc.*` candidates qualify;
|
|
2756
|
-
* if you're on a stable, only stable candidates. Prevents
|
|
2757
|
-
* accidentally promoting a prerelease pin to a stable major bump.
|
|
2758
|
-
* - `"any"` — equivalent to `--prerelease`. Any channel is fair game.
|
|
2759
|
-
*
|
|
2760
|
-
* `--release-channel` on the CLI overrides this. If `prerelease: true`
|
|
2761
|
-
* is set without `releaseChannel`, vis treats it as `"any"`.
|
|
2762
|
-
* @default "stable"
|
|
2763
|
-
*/
|
|
2764
|
-
releaseChannel?: "any" | "same" | "stable";
|
|
2765
|
-
security?: boolean;
|
|
2766
|
-
target?: "latest" | "minor" | "patch";
|
|
2767
|
-
};
|
|
2777
|
+
update?: Inline<VisUpdateConfig>;
|
|
2768
2778
|
/**
|
|
2769
2779
|
* Minimum vis CLI version required by this workspace. When the
|
|
2770
2780
|
* running vis binary is older than this constraint, vis exits with
|