@visulima/vis 1.0.0-alpha.19 → 1.0.0-alpha.20

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.
Files changed (107) hide show
  1. package/CHANGELOG.md +164 -0
  2. package/LICENSE.md +187 -779
  3. package/README.md +1 -1
  4. package/dist/config/index.d.ts +535 -121
  5. package/dist/config/index.js +1 -1
  6. package/dist/packem_chunks/bin.js +380 -286
  7. package/dist/packem_chunks/config.js +15 -14
  8. package/dist/packem_chunks/doctor-probe.js +2 -2
  9. package/dist/packem_chunks/fix.js +9 -9
  10. package/dist/packem_chunks/handler.js +1 -1
  11. package/dist/packem_chunks/handler10.js +1 -2
  12. package/dist/packem_chunks/handler11.js +5 -1
  13. package/dist/packem_chunks/handler12.js +1 -5
  14. package/dist/packem_chunks/handler13.js +27 -1
  15. package/dist/packem_chunks/handler14.js +5 -20
  16. package/dist/packem_chunks/handler15.js +1 -1
  17. package/dist/packem_chunks/handler16.js +1 -1
  18. package/dist/packem_chunks/handler17.js +1 -1
  19. package/dist/packem_chunks/handler18.js +1 -1
  20. package/dist/packem_chunks/handler19.js +1 -5
  21. package/dist/packem_chunks/handler20.js +5 -2
  22. package/dist/packem_chunks/handler21.js +2 -18
  23. package/dist/packem_chunks/handler22.js +2 -1
  24. package/dist/packem_chunks/handler23.js +18 -1
  25. package/dist/packem_chunks/handler24.js +1 -5
  26. package/dist/packem_chunks/handler25.js +1 -1
  27. package/dist/packem_chunks/handler26.js +5 -3
  28. package/dist/packem_chunks/handler27.js +1 -1
  29. package/dist/packem_chunks/handler28.js +3 -1
  30. package/dist/packem_chunks/handler29.js +1 -7
  31. package/dist/packem_chunks/handler3.js +3 -3
  32. package/dist/packem_chunks/handler30.js +6 -22
  33. package/dist/packem_chunks/handler31.js +33 -3
  34. package/dist/packem_chunks/handler32.js +3 -1
  35. package/dist/packem_chunks/handler33.js +1 -2
  36. package/dist/packem_chunks/handler34.js +25 -24
  37. package/dist/packem_chunks/handler35.js +3 -3
  38. package/dist/packem_chunks/handler36.js +6 -21
  39. package/dist/packem_chunks/handler37.js +22 -428
  40. package/dist/packem_chunks/handler38.js +428 -6
  41. package/dist/packem_chunks/handler39.js +6 -5
  42. package/dist/packem_chunks/handler4.js +8 -2
  43. package/dist/packem_chunks/handler40.js +24 -10
  44. package/dist/packem_chunks/handler41.js +10 -24
  45. package/dist/packem_chunks/handler42.js +1 -1
  46. package/dist/packem_chunks/handler43.js +6 -6
  47. package/dist/packem_chunks/handler44.js +13 -13
  48. package/dist/packem_chunks/handler45.js +213 -3
  49. package/dist/packem_chunks/handler46.js +3 -27
  50. package/dist/packem_chunks/handler47.js +21 -161
  51. package/dist/packem_chunks/handler48.js +166 -33
  52. package/dist/packem_chunks/handler49.js +34 -0
  53. package/dist/packem_chunks/handler5.js +1 -8
  54. package/dist/packem_chunks/handler6.js +1 -1
  55. package/dist/packem_chunks/handler7.js +1 -1
  56. package/dist/packem_chunks/handler8.js +1 -1
  57. package/dist/packem_chunks/handler9.js +2 -1
  58. package/dist/packem_chunks/heal-accept.js +2 -2
  59. package/dist/packem_chunks/heal.js +1 -1
  60. package/dist/packem_chunks/help-command.js +16 -16
  61. package/dist/packem_chunks/index.js +6 -6
  62. package/dist/packem_chunks/keys-refresh.js +4 -0
  63. package/dist/packem_chunks/list.js +3 -0
  64. package/dist/packem_chunks/loader.js +1 -1
  65. package/dist/packem_chunks/prune.js +3 -0
  66. package/dist/packem_chunks/run.js +1 -0
  67. package/dist/packem_chunks/status.js +2 -0
  68. package/dist/packem_chunks/sync.js +2 -0
  69. package/dist/packem_chunks/sync2.js +2 -0
  70. package/dist/packem_chunks/tripwire.js +2 -0
  71. package/dist/packem_shared/advisories-DsynpacV.js +1 -0
  72. package/dist/packem_shared/{ai-analysis-C_GpXikx.js → ai-analysis-uYuTIIXi.js} +1 -1
  73. package/dist/packem_shared/{ai-cache-DrCLD4gc.js → ai-cache-DuwHYx2O.js} +1 -1
  74. package/dist/packem_shared/{ai-fix-CWOz12Om.js → ai-fix-DzrA-dVz.js} +4 -4
  75. package/dist/packem_shared/applyDefaults-BOVDw1jD.js +1 -0
  76. package/dist/packem_shared/build-scripts-DsWMSWDs.js +1 -0
  77. package/dist/packem_shared/{cache-directory-C_U1qsIw.js → cache-directory-DQak1Vjc.js} +1 -1
  78. package/dist/packem_shared/cyclonedx-CiHXuG8M.js +4 -0
  79. package/dist/packem_shared/dependency-scan-DC3nAFHS.js +1 -0
  80. package/dist/packem_shared/{docker-B4s1fjiN.js → docker-B-CIN_nj.js} +19 -19
  81. package/dist/packem_shared/{failure-log-CSC6KfcO.js → failure-log-C3LEMmkq.js} +1 -1
  82. package/dist/packem_shared/{flakiness-DUtrm-wS.js → flakiness-Dq6K4ymq.js} +1 -1
  83. package/dist/packem_shared/glob-MHJQjR39-CQ2GC0b_.js +1 -0
  84. package/dist/packem_shared/{lifecycle-CgK8pcfa.js → lifecycle-Dv3nAtoD.js} +2 -2
  85. package/dist/packem_shared/{lockfile-i-qvq_k8.js → lockfile-C5DYMHVq.js} +1 -1
  86. package/dist/packem_shared/manifests-B0fMp872.js +1 -0
  87. package/dist/packem_shared/min-release-age-BFozFonQ.js +34 -0
  88. package/dist/packem_shared/native-config-sync-Dvi1g2nQ.js +21 -0
  89. package/dist/packem_shared/registry-keys-CewRFW0e.js +1 -0
  90. package/dist/packem_shared/resolve-explicit-CC4Kifk5.js +5 -0
  91. package/dist/packem_shared/{run-summary-utils-CJv75pla.js → run-summary-utils-BaBGP3bo.js} +1 -1
  92. package/dist/packem_shared/{runtime-check-CBU6W8qG.js → runtime-check-BusAwPb2.js} +1 -1
  93. package/dist/packem_shared/scan-progress-CMynp3eA.js +2 -0
  94. package/dist/packem_shared/signatures-5ZdjJ2Pu.js +2 -0
  95. package/dist/packem_shared/{toolchain-B7dckBQ1.js → toolchain-Cc3cwyLP.js} +3 -3
  96. package/dist/packem_shared/typosquats-BCeR-sLf.js +1 -0
  97. package/dist/packem_shared/verify-07kUNTuP.js +1 -0
  98. package/dist/packem_shared/{vis-update-app-D0uL3eO5.js → vis-update-app-CFrlJ3mW.js} +1 -1
  99. package/index.d.ts +358 -0
  100. package/index.js +56 -53
  101. package/package.json +14 -13
  102. package/schemas/vis-config.schema.json +595 -100
  103. package/dist/packem_shared/applyDefaults-DLY94gWA.js +0 -1
  104. package/dist/packem_shared/dependency-scan-YdgNVvoz.js +0 -2
  105. package/dist/packem_shared/readTomlSync-1fKo0R52-DtxWULlF.js +0 -109
  106. package/dist/packem_shared/typosquats-B3A38-qx.js +0 -1
  107. package/dist/packem_shared/verify-WDStBFvK.js +0 -1
@@ -882,70 +882,379 @@
882
882
  "security": {
883
883
  "type": "object",
884
884
  "properties": {
885
- "allowBuilds": {
885
+ "acceptedRisks": {
886
+ "type": "object",
887
+ "additionalProperties": {
888
+ "type": "object",
889
+ "properties": {
890
+ "acceptedAt": {
891
+ "type": "string",
892
+ "description": "ISO 8601 timestamp when the risk was accepted."
893
+ },
894
+ "acceptedScore": {
895
+ "type": "number",
896
+ "description": "The overall Socket.dev score at the time of acceptance, in the range `[0, 1]` (mirrors `policies.score.minimum`). Only relevant for the `score` policy; ignored elsewhere."
897
+ },
898
+ "expiresAt": {
899
+ "type": "string",
900
+ "description": "ISO 8601 date (or datetime). After this point the acceptance stops applying and vis emits a warning. Leave undefined for non-expiring entries. Values that fail to parse as a Date are rejected by the loader rather than silently treated as \"always expired\"."
901
+ },
902
+ "policies": {
903
+ "type": "array",
904
+ "items": {
905
+ "$ref": "#/$defs/PolicyName"
906
+ },
907
+ "description": "Which policies this acceptance covers. When undefined the acceptance applies to every policy finding on this package."
908
+ },
909
+ "reason": {
910
+ "type": "string",
911
+ "description": "User-provided reason for accepting the risk."
912
+ }
913
+ },
914
+ "required": [
915
+ "acceptedAt",
916
+ "reason"
917
+ ],
918
+ "additionalProperties": false
919
+ },
920
+ "description": "Packages whose policy findings have been reviewed and explicitly accepted. Matched against every policy unless `policies` narrows the scope. Replaces the legacy `security.socket.acceptedRisks` map.\n\nKey format: package name (`\"lodash\"`), name@version (`\"lodash@4.17.21\"`), or glob (`\"@myorg/*\"`). Unversioned keys match all versions of that package."
921
+ },
922
+ "audit": {
923
+ "type": "object",
924
+ "properties": {
925
+ "advisories": {
926
+ "type": "object",
927
+ "properties": {
928
+ "allowedHosts": {
929
+ "type": "array",
930
+ "items": {
931
+ "type": "string"
932
+ },
933
+ "description": "Extra hosts permitted as `audit.advisories.source`. The built-in allowlist is enforced even if this field is omitted; entries here add to it.",
934
+ "examples": [
935
+ [
936
+ "mirror.corp.example.com"
937
+ ]
938
+ ]
939
+ },
940
+ "refreshIntervalHours": {
941
+ "type": "number",
942
+ "description": "Number of hours after `lastSyncIso` before `vis audit` prints a \"your advisory cache may be stale\" notice. `vis audit` never auto-syncs — the user runs `vis advisories sync` themselves.",
943
+ "default": 24
944
+ },
945
+ "source": {
946
+ "type": "string",
947
+ "description": "OSV mirror base URL (no trailing slash). Defaults to the public Google Cloud Storage bucket. Override to point at a corporate mirror; the hostname must appear in `allowedHosts` (or one of the built-in defaults) and the scheme must be `https://`.",
948
+ "default": "https://osv-vulnerabilities.storage.googleapis.com"
949
+ },
950
+ "verify": {
951
+ "type": "object",
952
+ "properties": {
953
+ "enabled": {
954
+ "type": "boolean",
955
+ "description": "Enable signature verification. The sync flow downloads `<eco>/all.zip.sig` next to the zip and aborts if it cannot verify against `expectedIssuer` / `expectedSubject`.",
956
+ "default": false
957
+ },
958
+ "expectedIssuer": {
959
+ "type": "string",
960
+ "description": "OIDC issuer that signed the bundle."
961
+ },
962
+ "expectedSubject": {
963
+ "type": "string",
964
+ "description": "OIDC subject (workload identity) that signed the bundle."
965
+ }
966
+ },
967
+ "additionalProperties": false,
968
+ "description": "Sigstore signature verification for the OSV dump. Requires the native binding to be built with the `verify-signatures` Cargo feature (default in the release build). Off by default — the upstream OSV bucket does not ship signatures today."
969
+ }
970
+ },
971
+ "additionalProperties": false,
972
+ "description": "Offline advisory cache settings."
973
+ },
974
+ "apply": {
975
+ "type": "object",
976
+ "properties": {
977
+ "transitive": {
978
+ "type": "object",
979
+ "properties": {
980
+ "enabled": {
981
+ "type": "boolean",
982
+ "description": "When true, allows `--fix-transitive` to run in CI environments. Defaults to false because rewriting overrides is a higher blast radius than bumping a direct dep.",
983
+ "default": false
984
+ }
985
+ },
986
+ "additionalProperties": false,
987
+ "description": "Gates for `vis audit --fix-transitive`. Two-lock: the CLI requires `--yes` AND this flag set to `true` before it will rewrite override entries in CI."
988
+ }
989
+ },
990
+ "additionalProperties": false,
991
+ "description": "Gates for the auto-fix flow (`vis audit --fix` / `--fix-transitive`). The CLI prompts outside CI; inside CI the flags refuse to run unless `--yes` is set and, for transitives, `apply.transitive.enabled = true`."
992
+ },
993
+ "offlineByDefault": {
994
+ "type": "boolean",
995
+ "description": "When true, `vis audit` skips network calls and queries the offline cache. Equivalent to the CLI `--offline` flag.",
996
+ "default": false
997
+ }
998
+ },
999
+ "additionalProperties": false,
1000
+ "description": "Offline OSV advisory + `vis audit` configuration.\n\nControls `vis audit --offline` and `vis advisories sync` behavior:\n- `audit.advisories.source` is the OSV mirror to download from. It must be `https://` and resolve to a host in `allowedHosts` (or one of the built-in defaults).\n- `audit.offlineByDefault` flips the default of `--offline`.\n\nVulnerability severity gating and reachability filtering live under `policies.vulnerability` (see below)."
1001
+ },
1002
+ "allowBins": {
886
1003
  "type": "object",
887
1004
  "additionalProperties": {
888
1005
  "type": "boolean"
889
1006
  },
890
- "description": "Map of package names/patterns to allow (true) or deny (false) build scripts. Packages not listed are denied by default. Equivalent to pnpm's `allowBuilds` setting."
1007
+ "description": "Map of bin names (or `pkg#bin` qualifiers) blessed for shadowing. When two installed packages expose the same bin name, vis flags the collision in `vis security list` and the post-install drift report — set the bin (or `pkg#bin`) to `true` here to suppress the warning once you've reviewed the conflict.\n\nPort of LavaMoat allow-scripts' experimental `allowBins`. Bare names match any conflicting bin with that name; the `pkg#bin` form scopes the approval to a single package's bin."
891
1008
  },
892
1009
  "blockExoticSubdeps": {
893
1010
  "type": "boolean",
894
1011
  "description": "When true, prevents transitive dependencies from using exotic sources (git repositories, direct tarball URLs). Only direct dependencies may use such sources. Equivalent to pnpm's `blockExoticSubdeps`.",
895
1012
  "default": false
896
1013
  },
897
- "minimumReleaseAge": {
898
- "type": "number",
899
- "description": "Minimum number of minutes that must pass after a version is published before vis will allow installation. Reduces risk of installing compromised packages that are typically discovered within hours. Equivalent to pnpm's `minimumReleaseAge`.",
900
- "examples": [
901
- 1440
902
- ],
903
- "default": 0
904
- },
905
- "minimumReleaseAgeExclude": {
906
- "type": "array",
907
- "items": {
908
- "type": "string"
909
- },
910
- "description": "Package names/patterns excluded from minimumReleaseAge check. Equivalent to pnpm's `minimumReleaseAgeExclude`.",
911
- "examples": [
912
- [
913
- "webpack",
914
- "react",
915
- "@myorg/*"
916
- ]
917
- ]
1014
+ "pinVersions": {
1015
+ "type": "boolean",
1016
+ "description": "When true, `security.policies.installScripts.allow` keys are matched as `name@version`. A version bump on an approved package drops it from the allowlist until the new version is explicitly re-approved (port of LavaMoat allow-scripts' version-aware policy matcher).\n\nAfter a version bump, run `vis approve-builds` or `vis security list` both surface a \"Version drift\" block with the suggested new key (`old-key → new-key`) so you can update `vis.config.ts` by hand.",
1017
+ "default": false
918
1018
  },
919
- "socket": {
1019
+ "policies": {
920
1020
  "type": "object",
921
1021
  "properties": {
922
- "acceptedRisks": {
1022
+ "firstSeen": {
923
1023
  "type": "object",
924
- "additionalProperties": {
925
- "type": "object",
926
- "properties": {
927
- "acceptedAt": {
928
- "type": "string",
929
- "description": "ISO 8601 timestamp when the risk was accepted."
1024
+ "properties": {
1025
+ "exclude": {
1026
+ "type": "array",
1027
+ "items": {
1028
+ "type": "string"
930
1029
  },
931
- "acceptedScore": {
932
- "type": "number",
933
- "description": "The overall Socket.dev score at the time of acceptance."
1030
+ "description": "Package names/patterns excluded from the firstSeen check. Equivalent to pnpm's `minimumReleaseAgeExclude`.",
1031
+ "examples": [
1032
+ [
1033
+ "webpack",
1034
+ "react",
1035
+ "@myorg/*"
1036
+ ]
1037
+ ]
1038
+ },
1039
+ "minutes": {
1040
+ "type": "number",
1041
+ "description": "Minutes after publish before install is allowed."
1042
+ }
1043
+ },
1044
+ "additionalProperties": false,
1045
+ "description": "Minimum number of minutes that must pass after a version is published before vis will allow installation. Migrated from the legacy `security.minimumReleaseAge` field. Equivalent to pnpm's `minimumReleaseAge`.",
1046
+ "examples": [
1047
+ {
1048
+ "minutes": 1440,
1049
+ "exclude": [
1050
+ "@myorg/*"
1051
+ ]
1052
+ }
1053
+ ],
1054
+ "default": 0
1055
+ },
1056
+ "installScripts": {
1057
+ "type": "object",
1058
+ "properties": {
1059
+ "allow": {
1060
+ "type": "object",
1061
+ "additionalProperties": {
1062
+ "type": "boolean"
934
1063
  },
935
- "reason": {
936
- "type": "string",
937
- "description": "User-provided reason for accepting the risk."
938
- }
1064
+ "description": "Map of package names/patterns to allow (true) or deny (false) build scripts. Packages not listed are denied by default. Equivalent to pnpm's `allowBuilds`."
939
1065
  },
940
- "required": [
941
- "acceptedAt",
942
- "acceptedScore",
943
- "reason"
944
- ],
945
- "additionalProperties": false
1066
+ "strict": {
1067
+ "type": "boolean",
1068
+ "description": "When true, installation will fail (exit non-zero) if any dependencies have unreviewed build scripts. Equivalent to pnpm's `strictDepBuilds`.",
1069
+ "default": false
1070
+ }
1071
+ },
1072
+ "additionalProperties": false,
1073
+ "description": "Build-script (pre/install/postinstall/prepare) controls. Migrated from the legacy `security.allowBuilds` / `security.strictDepBuilds` fields.",
1074
+ "examples": [
1075
+ {
1076
+ "allow": {
1077
+ "esbuild": true
1078
+ },
1079
+ "strict": true
1080
+ }
1081
+ ]
1082
+ },
1083
+ "license": {
1084
+ "type": "object",
1085
+ "properties": {
1086
+ "allow": {
1087
+ "type": "array",
1088
+ "items": {
1089
+ "type": "string"
1090
+ },
1091
+ "description": "SPDX identifiers that are explicitly permitted. When set, any package whose declared license is not on this list is blocked."
1092
+ },
1093
+ "deny": {
1094
+ "type": "array",
1095
+ "items": {
1096
+ "type": "string"
1097
+ },
1098
+ "description": "SPDX identifiers that are explicitly forbidden. Always wins over `allow` when both reference the same identifier."
1099
+ }
1100
+ },
1101
+ "additionalProperties": false,
1102
+ "description": "SPDX license allow / deny lists. Deny wins on any sub-license match in SPDX expressions (`(MIT OR GPL-3.0)` against `deny: [\"GPL-3.0\"]` is blocked). Packages with no declared license are flagged when `allow` is set."
1103
+ },
1104
+ "malware": {
1105
+ "type": "object",
1106
+ "properties": {
1107
+ "mode": {
1108
+ "type": "string",
1109
+ "enum": [
1110
+ "block",
1111
+ "off",
1112
+ "warn"
1113
+ ],
1114
+ "description": "- `\"block\"` — emit a block decision.\n- `\"warn\"` — surface as a warning; do not gate exit code.\n- `\"off\"` — disable the policy entirely."
1115
+ }
1116
+ },
1117
+ "additionalProperties": false,
1118
+ "description": "Behavior when the Socket.dev feed flags a package as malicious (`alerts[].type === \"Malware\"`).\n\nThe default is cross-field: `{ mode: \"block\" }` whenever `security.socket.enabled !== false` (the engine cannot evaluate malware without Socket data), and `\"off\"` otherwise. Consumers resolve this default at evaluation time."
1119
+ },
1120
+ "publisherChange": {
1121
+ "type": "object",
1122
+ "properties": {
1123
+ "exclude": {
1124
+ "type": "array",
1125
+ "items": {
1126
+ "type": "string"
1127
+ },
1128
+ "description": "Package selectors excluded from the check. Equivalent to pnpm's `trustPolicyExclude`.",
1129
+ "examples": [
1130
+ [
1131
+ "chokidar@4.0.3"
1132
+ ]
1133
+ ]
1134
+ },
1135
+ "ignoreAfter": {
1136
+ "type": "number",
1137
+ "description": "Ignore packages published more than N minutes ago. Useful for older packages that pre-date provenance support. Equivalent to pnpm's `trustPolicyIgnoreAfter`."
1138
+ },
1139
+ "mode": {
1140
+ "type": "string",
1141
+ "enum": [
1142
+ "no-downgrade",
1143
+ "off"
1144
+ ],
1145
+ "description": "- `\"off\"` — no trust checking (default).\n- `\"no-downgrade\"` — block when a package's trust level has decreased compared to previous releases (e.g., was published by trusted publisher, now only has provenance)."
1146
+ }
1147
+ },
1148
+ "additionalProperties": false,
1149
+ "description": "Trust-level checking for package publishing. Migrated from the legacy `security.trustPolicy*` fields. Equivalent to pnpm's `trustPolicy`.",
1150
+ "examples": [
1151
+ {
1152
+ "mode": "no-downgrade",
1153
+ "ignoreAfter": 43200
1154
+ }
1155
+ ]
1156
+ },
1157
+ "score": {
1158
+ "type": "object",
1159
+ "properties": {
1160
+ "minimum": {
1161
+ "type": "number",
1162
+ "description": "Minimum overall Socket.dev score (0–1). Set to 0 to disable the gate while keeping Socket data fetched.\n\nConsulted by `vis add`, `audit`, `doctor`, `check`, and `update`; resolved once in `buildSocketOptions`, then threaded through every consumer. Falls back to `DEFAULT_LOW_SCORE_THRESHOLD` (`0.4`) when unset."
1163
+ }
946
1164
  },
947
- "description": "Packages whose low Socket.dev scores or alerts have been reviewed and explicitly accepted. These packages skip the confirmation prompt during `vis add` and show as \"acknowledged\" in `vis audit`.\n\nKey format: package name (`\"lodash\"`), name@version (`\"lodash@4.17.21\"`), or glob (`\"@myorg/*\"`). Unversioned keys match all versions of that package."
1165
+ "additionalProperties": false,
1166
+ "description": "Socket.dev overall-score threshold. Packages scoring below `minimum` trigger a block decision (or interactive prompt during `vis add`). Migrated from the legacy `security.socket.minimumScore` field.",
1167
+ "examples": [
1168
+ {
1169
+ "minimum": 0.4
1170
+ }
1171
+ ]
948
1172
  },
1173
+ "unexpectedDeps": {
1174
+ "type": "object",
1175
+ "properties": {
1176
+ "allow": {
1177
+ "type": "array",
1178
+ "items": {
1179
+ "type": "string"
1180
+ },
1181
+ "description": "Allow-list of dependency names that may appear in the resolved package set. Glob patterns are supported.",
1182
+ "examples": [
1183
+ [
1184
+ "lodash",
1185
+ "axios",
1186
+ "@myorg/*"
1187
+ ]
1188
+ ]
1189
+ },
1190
+ "baselineLockfile": {
1191
+ "type": "string",
1192
+ "description": "Path (absolute or relative to the workspace root) to a baseline lockfile snapshot. The policy diffs the current lockfile against this baseline and flags any package that didn't exist before.",
1193
+ "examples": [
1194
+ "./security/lockfile.baseline.yaml"
1195
+ ]
1196
+ }
1197
+ },
1198
+ "additionalProperties": false,
1199
+ "description": "Net-new transitive dependency detection. Either provide a static allow-list, a baseline lockfile path (recommended), or both — the intersection is enforced.",
1200
+ "examples": [
1201
+ {
1202
+ "baselineLockfile": "./security/lockfile.baseline.yaml"
1203
+ }
1204
+ ]
1205
+ },
1206
+ "vulnerability": {
1207
+ "type": "object",
1208
+ "properties": {
1209
+ "failOn": {
1210
+ "type": "string",
1211
+ "enum": [
1212
+ "critical",
1213
+ "high",
1214
+ "low",
1215
+ "medium"
1216
+ ],
1217
+ "description": "Severity threshold that makes `vis audit` exit non-zero. Equivalent to the CLI `--fail-on` flag.",
1218
+ "examples": [
1219
+ "high"
1220
+ ]
1221
+ },
1222
+ "usage": {
1223
+ "type": "object",
1224
+ "properties": {
1225
+ "alwaysAssumeUsed": {
1226
+ "type": "array",
1227
+ "items": {
1228
+ "type": "string"
1229
+ },
1230
+ "description": "Packages to always treat as reachable even if no static import is found.",
1231
+ "examples": [
1232
+ [
1233
+ "esbuild",
1234
+ "webpack-cli"
1235
+ ]
1236
+ ]
1237
+ },
1238
+ "enabled": {
1239
+ "type": "boolean",
1240
+ "description": "Enable the reachability filter by default. Equivalent to `--usage` on the CLI; `--no-usage` disables.",
1241
+ "default": false
1242
+ }
1243
+ },
1244
+ "additionalProperties": false,
1245
+ "description": "Reachability filter — only report vulnerabilities in packages the workspace statically imports."
1246
+ }
1247
+ },
1248
+ "additionalProperties": false,
1249
+ "description": "OSV vulnerability gating. Migrated from the legacy `security.audit.failOn` + `security.audit.usage` fields."
1250
+ }
1251
+ },
1252
+ "additionalProperties": false,
1253
+ "description": "Supply-chain policy gates. Each sub-block enables one policy and configures its behavior. When a sub-block is omitted the policy is inactive. `acceptedRisks` (above) silences specific packages without disabling a policy globally.\n\nThe 8 policies are inspired by Socket.dev's classification:\n- `malware` — Socket-flagged malicious packages\n- `firstSeen` — packages published less than N minutes ago\n- `unexpectedDeps` — packages outside an allow-list / baseline\n- `publisherChange` — maintainer set changed between installs\n- `installScripts` — preinstall/install/postinstall scripts\n- `score` — Socket overall score below threshold\n- `vulnerability` — OSV vulnerability findings\n- `license` — SPDX allow / deny lists"
1254
+ },
1255
+ "socket": {
1256
+ "type": "object",
1257
+ "properties": {
949
1258
  "apiToken": {
950
1259
  "type": "string",
951
1260
  "description": "Custom Socket.dev API token. Falls back to the public API token. Set via VIS_SOCKET_TOKEN environment variable or here."
@@ -960,11 +1269,6 @@
960
1269
  "description": "Enable Socket.dev security scanning on install/update/check commands.",
961
1270
  "default": false
962
1271
  },
963
- "minimumScore": {
964
- "type": "number",
965
- "description": "Minimum overall Socket.dev score (0–1) for a package to be accepted without a confirmation prompt during `vis add`. Packages scoring below this threshold trigger an interactive prompt asking the user to confirm. Set to 0 to disable.",
966
- "default": 0.4
967
- },
968
1272
  "timeoutMs": {
969
1273
  "type": "number",
970
1274
  "description": "Request timeout in milliseconds for the Socket.dev API.",
@@ -972,41 +1276,219 @@
972
1276
  }
973
1277
  },
974
1278
  "additionalProperties": false,
975
- "description": "Socket.dev security intelligence configuration. When enabled, vis fetches package security scores, alerts, and report data from the Socket.dev API during install, update, and check commands."
976
- },
977
- "strictDepBuilds": {
978
- "type": "boolean",
979
- "description": "When true, installation will fail (exit non-zero) if any dependencies have unreviewed build scripts. Equivalent to pnpm's `strictDepBuilds`.",
980
- "default": false
981
- },
982
- "trustPolicy": {
983
- "type": "string",
984
- "enum": [
985
- "no-downgrade",
986
- "off"
987
- ],
988
- "description": "Trust level checking for package publishing.\n- \"off\": No trust checking (default)\n- \"no-downgrade\": Fail if a package's trust level has decreased compared to previous releases (e.g., was published by trusted publisher, now only has provenance). Equivalent to pnpm's `trustPolicy`.",
989
- "default": "off"
1279
+ "description": "Socket.dev data-source configuration. Connection knobs only score thresholds and accepted-risk overrides moved to `policies.score` and `security.acceptedRisks` respectively."
990
1280
  },
991
- "trustPolicyExclude": {
992
- "type": "array",
993
- "items": {
994
- "type": "string"
1281
+ "marshalls": {
1282
+ "type": "object",
1283
+ "properties": {
1284
+ "archivedRepo": {
1285
+ "type": "object",
1286
+ "properties": {
1287
+ "allowlist": {
1288
+ "type": "array",
1289
+ "items": {
1290
+ "type": "string"
1291
+ },
1292
+ "description": "Package names to skip."
1293
+ },
1294
+ "enabled": {
1295
+ "type": "boolean",
1296
+ "description": "Default: marshall is on. Set false to disable."
1297
+ },
1298
+ "githubToken": {
1299
+ "type": "string",
1300
+ "description": "GitHub PAT for the API call (5k/hr vs 60/hr)."
1301
+ }
1302
+ },
1303
+ "additionalProperties": false,
1304
+ "description": "Archived-repo marshall (GitHub repository status)."
1305
+ },
1306
+ "author": {
1307
+ "type": "object",
1308
+ "properties": {
1309
+ "allowlist": {
1310
+ "type": "array",
1311
+ "items": {
1312
+ "type": "string"
1313
+ }
1314
+ },
1315
+ "dormantErrorDays": {
1316
+ "type": "number",
1317
+ "description": "Days since the publisher's last release before flagging as error."
1318
+ },
1319
+ "dormantWarnDays": {
1320
+ "type": "number",
1321
+ "description": "Days since the publisher's last release before flagging as warning."
1322
+ },
1323
+ "enabled": {
1324
+ "type": "boolean"
1325
+ },
1326
+ "newPublisherWindowDays": {
1327
+ "type": "number",
1328
+ "description": "Window for the \"new publisher on an established package\" check."
1329
+ },
1330
+ "recentVersionErrorDays": {
1331
+ "type": "number",
1332
+ "description": "Days since the resolved version was published — error threshold."
1333
+ },
1334
+ "recentVersionWarnDays": {
1335
+ "type": "number",
1336
+ "description": "Days since the resolved version was published — warning threshold."
1337
+ }
1338
+ },
1339
+ "additionalProperties": false,
1340
+ "description": "Author / publisher heuristics."
1341
+ },
1342
+ "downloads": {
1343
+ "type": "object",
1344
+ "properties": {
1345
+ "allowlist": {
1346
+ "type": "array",
1347
+ "items": {
1348
+ "type": "string"
1349
+ }
1350
+ },
1351
+ "enabled": {
1352
+ "type": "boolean"
1353
+ },
1354
+ "errorThreshold": {
1355
+ "type": "number",
1356
+ "description": "Below this monthly count → error (default: 20)."
1357
+ },
1358
+ "warnThreshold": {
1359
+ "type": "number",
1360
+ "description": "Below this monthly count → warning (default: 1000)."
1361
+ }
1362
+ },
1363
+ "additionalProperties": false,
1364
+ "description": "Monthly download-count floor."
1365
+ },
1366
+ "expiredDomains": {
1367
+ "type": "object",
1368
+ "properties": {
1369
+ "allowDomains": {
1370
+ "type": "array",
1371
+ "items": {
1372
+ "type": "string"
1373
+ },
1374
+ "description": "Domains exempted from the check (legacy / internal)."
1375
+ },
1376
+ "allowlist": {
1377
+ "type": "array",
1378
+ "items": {
1379
+ "type": "string"
1380
+ }
1381
+ },
1382
+ "dnsServers": {
1383
+ "type": "array",
1384
+ "items": {
1385
+ "type": "string"
1386
+ },
1387
+ "description": "DNS resolvers to query (default: system)."
1388
+ },
1389
+ "enabled": {
1390
+ "type": "boolean"
1391
+ },
1392
+ "timeoutMs": {
1393
+ "type": "number",
1394
+ "description": "Per-domain DNS timeout (default: 5000)."
1395
+ }
1396
+ },
1397
+ "additionalProperties": false,
1398
+ "description": "Maintainer-email-domain NS lookup."
1399
+ },
1400
+ "metadata": {
1401
+ "type": "object",
1402
+ "properties": {
1403
+ "allowlist": {
1404
+ "type": "array",
1405
+ "items": {
1406
+ "type": "string"
1407
+ }
1408
+ },
1409
+ "checks": {
1410
+ "type": "array",
1411
+ "items": {
1412
+ "type": "string",
1413
+ "enum": [
1414
+ "license",
1415
+ "readme",
1416
+ "repo"
1417
+ ]
1418
+ },
1419
+ "description": "Subset of checks to run. Default: all three."
1420
+ },
1421
+ "enabled": {
1422
+ "type": "boolean"
1423
+ }
1424
+ },
1425
+ "additionalProperties": false,
1426
+ "description": "README / license / repository presence checks."
1427
+ },
1428
+ "newBin": {
1429
+ "type": "object",
1430
+ "properties": {
1431
+ "allowlist": {
1432
+ "type": "array",
1433
+ "items": {
1434
+ "type": "string"
1435
+ }
1436
+ },
1437
+ "enabled": {
1438
+ "type": "boolean"
1439
+ }
1440
+ },
1441
+ "additionalProperties": false,
1442
+ "description": "New CLI-bin script introduced in this version."
1443
+ },
1444
+ "provenance": {
1445
+ "type": "object",
1446
+ "properties": {
1447
+ "allowlist": {
1448
+ "type": "array",
1449
+ "items": {
1450
+ "type": "string"
1451
+ }
1452
+ },
1453
+ "enabled": {
1454
+ "type": "boolean"
1455
+ }
1456
+ },
1457
+ "additionalProperties": false,
1458
+ "description": "Provenance regression check."
1459
+ },
1460
+ "signatures": {
1461
+ "type": "object",
1462
+ "properties": {
1463
+ "allowlist": {
1464
+ "type": "array",
1465
+ "items": {
1466
+ "type": "string"
1467
+ }
1468
+ },
1469
+ "enabled": {
1470
+ "type": "boolean",
1471
+ "description": "Default: marshall is *off*. Set true to enable."
1472
+ },
1473
+ "keysUrl": {
1474
+ "type": "string",
1475
+ "description": "Override the keys endpoint (default: npm registry)."
1476
+ },
1477
+ "treatExpiredAs": {
1478
+ "type": "string",
1479
+ "enum": [
1480
+ "error",
1481
+ "warning"
1482
+ ],
1483
+ "description": "How to treat an expired-but-known key. Default: \"warning\"."
1484
+ }
1485
+ },
1486
+ "additionalProperties": false,
1487
+ "description": "ECDSA P-256 verification against npm's signing keys. Disabled by default because npm coverage still has gaps that produce noisy warnings on legitimate packages."
1488
+ }
995
1489
  },
996
- "description": "Package selectors excluded from trust policy checks. Equivalent to pnpm's `trustPolicyExclude`.",
997
- "examples": [
998
- [
999
- "chokidar@4.0.3",
1000
- "@babel/core@7.28.5"
1001
- ]
1002
- ]
1003
- },
1004
- "trustPolicyIgnoreAfter": {
1005
- "type": "number",
1006
- "description": "Ignore the trust policy check for packages published more than the specified number of minutes ago. Useful for older packages that pre-date provenance support. Equivalent to pnpm's `trustPolicyIgnoreAfter` (10.27+).",
1007
- "examples": [
1008
- 43200
1009
- ]
1490
+ "additionalProperties": false,
1491
+ "description": "Pre-install marshall pipeline — packument-derived supply-chain gates (author, provenance, new-bin, metadata, downloads, expired-domains, signatures, archived-repo) that run before `vis add` / `vis install <pkg>` / `vis update <pkg>` hand off to the underlying package manager. Every entry is optional; omit a key and the marshall runs with defaults. Set `enabled: false` on a specific marshall to skip it without touching env vars."
1010
1492
  },
1011
1493
  "typosquatAllowlist": {
1012
1494
  "type": "array",
@@ -1078,7 +1560,7 @@
1078
1560
  "description": "When `true`, every task command is scanned for `${VAR}` / `$VAR` references before spawn. If a referenced var is unset in the task's effective env (envFile + service env + per-task `env` + `process.env`), the task fails with an actionable error naming the missing variable, instead of letting the shell silently substitute an empty string.\n\nOverride per run with `--strict-env` / `--no-strict-env`. Override per target with `options.strictEnv`.",
1079
1561
  "default": false
1080
1562
  },
1081
- "targetDefaults": {
1563
+ "tasks": {
1082
1564
  "type": "object",
1083
1565
  "additionalProperties": {
1084
1566
  "type": "object",
@@ -1589,14 +2071,14 @@
1589
2071
  },
1590
2072
  "additionalProperties": false
1591
2073
  },
1592
- "description": "Target default configurations"
2074
+ "description": "Workspace-wide task defaults keyed by target name. Applied universally to every project that exposes a matching target. Use `scopedTasks` when defaults should only apply to a subset of projects."
1593
2075
  },
1594
- "taskDefaults": {
2076
+ "scopedTasks": {
1595
2077
  "type": "array",
1596
2078
  "items": {
1597
- "$ref": "#/$defs/TaskDefaultsBlock"
2079
+ "$ref": "#/$defs/ScopedTasksBlock"
1598
2080
  },
1599
- "description": "Cascading task-default blocks. Each block may scope its targets to a subset of projects via `scope`. Blocks are evaluated in order; later blocks override earlier ones when the same field is set.\n\nScope matching is additive — if `scope` is omitted, the block applies to every project."
2081
+ "description": "Cascading scoped-task blocks. Each block may narrow its tasks to a subset of projects via `match`. Blocks are evaluated in order; later blocks override earlier ones when the same field is set.\n\nMatch predicates are additive — if `match` is omitted, the block applies to every project."
1600
2082
  },
1601
2083
  "taskGroups": {
1602
2084
  "type": "object",
@@ -1652,7 +2134,7 @@
1652
2134
  },
1653
2135
  "description": "Named bundles of target dependencies, referenceable from any task's `dependsOn`. `dependsOn: [{ group: \"lint\" }]` expands to every entry in the named group; nested groups are resolved recursively and a cycle raises during discovery."
1654
2136
  },
1655
- "taskRunnerOptions": {
2137
+ "taskRunner": {
1656
2138
  "type": "object",
1657
2139
  "properties": {
1658
2140
  "autoEnvVars": {
@@ -2456,7 +2938,7 @@
2456
2938
  }
2457
2939
  },
2458
2940
  "additionalProperties": false,
2459
- "description": "Task runner options forwarded verbatim to `defaultTaskRunner`.\n\nIncludes `remoteCache` (HTTP or REAPI gRPC backend), `cacheDirectory`, `parallel`, `globalEnv`, `globalInputs`, `targetDefaults`, etc. See `TaskRunnerOptions` for the full surface."
2941
+ "description": "Task runner options forwarded verbatim to `defaultTaskRunner`.\n\nIncludes `remoteCache` (HTTP or REAPI gRPC backend), `cacheDirectory`, `parallel`, `globalEnv`, `globalInputs`, etc. See `TaskRunnerOptions` for the full surface."
2460
2942
  },
2461
2943
  "toolchain": {
2462
2944
  "type": "object",
@@ -2890,6 +3372,19 @@
2890
3372
  "additionalProperties": false,
2891
3373
  "description": "One family of upstream-coupled packages.\n\n`members` is an exact-match list. `prefixes` accept any dep whose name starts with the prefix — useful for monorepos that ship many subpackages under one scope (e.g. `@babel/`, `@storybook/`, `@nx/`). A family can use either or both; a dep matching either list belongs to the family."
2892
3374
  },
3375
+ "PolicyName": {
3376
+ "type": "string",
3377
+ "enum": [
3378
+ "firstSeen",
3379
+ "installScripts",
3380
+ "license",
3381
+ "malware",
3382
+ "publisherChange",
3383
+ "score",
3384
+ "unexpectedDeps",
3385
+ "vulnerability"
3386
+ ]
3387
+ },
2893
3388
  "StagedConfig": {
2894
3389
  "type": "object",
2895
3390
  "additionalProperties": {
@@ -3143,14 +3638,14 @@
3143
3638
  ],
3144
3639
  "description": "Semantic classification for a target.\n- `build`: Generates one or more artifacts; cached by default.\n- `test`: Validation task (lint, typecheck, unit test). Default type.\n- `run`: One-off or long-running process. Not cached by default."
3145
3640
  },
3146
- "TaskDefaultsBlock": {
3641
+ "ScopedTasksBlock": {
3147
3642
  "type": "object",
3148
3643
  "properties": {
3149
- "scope": {
3150
- "$ref": "#/$defs/TaskDefaultsScope",
3151
- "description": "Optional scope predicate; if omitted, the block applies universally."
3644
+ "match": {
3645
+ "$ref": "#/$defs/ScopedTasksMatch",
3646
+ "description": "Optional match predicate; if omitted, the block applies universally."
3152
3647
  },
3153
- "targets": {
3648
+ "tasks": {
3154
3649
  "type": "object",
3155
3650
  "additionalProperties": {
3156
3651
  "type": "object",
@@ -3661,16 +4156,16 @@
3661
4156
  },
3662
4157
  "additionalProperties": false
3663
4158
  },
3664
- "description": "Target default configurations."
4159
+ "description": "Task default configurations, keyed by target name."
3665
4160
  }
3666
4161
  },
3667
4162
  "required": [
3668
- "targets"
4163
+ "tasks"
3669
4164
  ],
3670
4165
  "additionalProperties": false,
3671
- "description": "A single task-defaults block — a set of target defaults gated by an optional scope predicate."
4166
+ "description": "A single scoped-tasks block — a set of task defaults gated by an optional match predicate."
3672
4167
  },
3673
- "TaskDefaultsScope": {
4168
+ "ScopedTasksMatch": {
3674
4169
  "type": "object",
3675
4170
  "properties": {
3676
4171
  "language": {
@@ -3805,7 +4300,7 @@
3805
4300
  }
3806
4301
  },
3807
4302
  "additionalProperties": false,
3808
- "description": "A scope predicate used by {@link VisConfig.taskDefaults } . All listed constraints must match for the block to apply."
4303
+ "description": "A predicate used by {@link VisConfig.scopedTasks } . All listed constraints must match for the block to apply."
3809
4304
  }
3810
4305
  }
3811
4306
  }