@visulima/vis 1.0.0-alpha.37 → 1.0.0-alpha.38

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 (177) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE.md +1 -503
  3. package/dist/bin.js +1 -1
  4. package/dist/binx.js +1 -1
  5. package/dist/config/index.d.ts +7 -0
  6. package/dist/packem_chunks/DEFAULT_CLEAN_KEEP.js +1 -0
  7. package/dist/packem_chunks/bin.js +302 -515
  8. package/dist/packem_chunks/bloom-sync.js +1 -1
  9. package/dist/packem_chunks/catalog-detector.js +1 -0
  10. package/dist/packem_chunks/detect.js +3 -0
  11. package/dist/packem_chunks/detect2.js +8 -0
  12. package/dist/packem_chunks/discord.js +4 -0
  13. package/dist/packem_chunks/dynamic-import.js +1 -0
  14. package/dist/packem_chunks/extra-files.js +3 -0
  15. package/dist/packem_chunks/fix.js +1 -1
  16. package/dist/packem_chunks/git.js +3 -0
  17. package/dist/packem_chunks/handler10.js +1 -1
  18. package/dist/packem_chunks/handler12.js +1 -1
  19. package/dist/packem_chunks/handler13.js +1 -1
  20. package/dist/packem_chunks/handler14.js +1 -1
  21. package/dist/packem_chunks/handler15.js +1 -1
  22. package/dist/packem_chunks/handler16.js +1 -1
  23. package/dist/packem_chunks/handler17.js +1 -1
  24. package/dist/packem_chunks/handler18.js +1 -1
  25. package/dist/packem_chunks/handler19.js +1 -1
  26. package/dist/packem_chunks/handler21.js +1 -1
  27. package/dist/packem_chunks/handler27.js +1 -1
  28. package/dist/packem_chunks/handler28.js +1 -1
  29. package/dist/packem_chunks/handler29.js +1 -1
  30. package/dist/packem_chunks/handler3.js +4 -4
  31. package/dist/packem_chunks/handler30.js +2 -7
  32. package/dist/packem_chunks/handler31.js +2 -33
  33. package/dist/packem_chunks/handler32.js +2 -3
  34. package/dist/packem_chunks/handler33.js +3 -8
  35. package/dist/packem_chunks/handler34.js +6 -4
  36. package/dist/packem_chunks/handler35.js +1 -1
  37. package/dist/packem_chunks/handler36.js +42 -5
  38. package/dist/packem_chunks/handler37.js +8 -11
  39. package/dist/packem_chunks/handler38.js +9 -3
  40. package/dist/packem_chunks/handler39.js +74 -21
  41. package/dist/packem_chunks/handler4.js +1 -1
  42. package/dist/packem_chunks/handler40.js +5 -61
  43. package/dist/packem_chunks/handler41.js +4 -3
  44. package/dist/packem_chunks/handler42.js +3 -6
  45. package/dist/packem_chunks/handler43.js +2 -24
  46. package/dist/packem_chunks/handler44.js +1 -25
  47. package/dist/packem_chunks/handler45.js +1 -153
  48. package/dist/packem_chunks/handler46.js +1 -10
  49. package/dist/packem_chunks/handler47.js +3 -24
  50. package/dist/packem_chunks/handler48.js +1 -322
  51. package/dist/packem_chunks/handler49.js +7 -708
  52. package/dist/packem_chunks/handler5.js +6 -6
  53. package/dist/packem_chunks/handler50.js +33 -48
  54. package/dist/packem_chunks/handler51.js +3 -27
  55. package/dist/packem_chunks/handler52.js +8 -3
  56. package/dist/packem_chunks/handler53.js +4 -200
  57. package/dist/packem_chunks/handler54.js +1 -38
  58. package/dist/packem_chunks/handler55.js +12 -0
  59. package/dist/packem_chunks/handler56.js +7 -0
  60. package/dist/packem_chunks/handler57.js +5 -0
  61. package/dist/packem_chunks/handler58.js +11 -0
  62. package/dist/packem_chunks/handler59.js +3 -0
  63. package/dist/packem_chunks/handler60.js +22 -0
  64. package/dist/packem_chunks/handler61.js +61 -0
  65. package/dist/packem_chunks/handler62.js +3 -0
  66. package/dist/packem_chunks/handler63.js +6 -0
  67. package/dist/packem_chunks/handler64.js +708 -0
  68. package/dist/packem_chunks/handler65.js +24 -0
  69. package/dist/packem_chunks/handler66.js +25 -0
  70. package/dist/packem_chunks/handler67.js +153 -0
  71. package/dist/packem_chunks/handler68.js +10 -0
  72. package/dist/packem_chunks/handler69.js +24 -0
  73. package/dist/packem_chunks/handler7.js +1 -1
  74. package/dist/packem_chunks/handler70.js +322 -0
  75. package/dist/packem_chunks/handler71.js +48 -0
  76. package/dist/packem_chunks/handler72.js +27 -0
  77. package/dist/packem_chunks/handler73.js +3 -0
  78. package/dist/packem_chunks/handler74.js +190 -0
  79. package/dist/packem_chunks/handler75.js +38 -0
  80. package/dist/packem_chunks/handler8.js +1 -1
  81. package/dist/packem_chunks/handler9.js +1 -1
  82. package/dist/packem_chunks/heal-accept.js +1 -1
  83. package/dist/packem_chunks/heal.js +1 -1
  84. package/dist/packem_chunks/help-command.js +1 -1
  85. package/dist/packem_chunks/index.js +1 -7
  86. package/dist/packem_chunks/index2.js +7 -0
  87. package/dist/packem_chunks/interface.js +2 -0
  88. package/dist/packem_chunks/keys-refresh.js +1 -1
  89. package/dist/packem_chunks/list.js +1 -1
  90. package/dist/packem_chunks/loader.js +1 -1
  91. package/dist/packem_chunks/orchestrator.js +39 -0
  92. package/dist/packem_chunks/pre-mode.js +2 -0
  93. package/dist/packem_chunks/print-config.js +2 -0
  94. package/dist/packem_chunks/prompts.js +7 -0
  95. package/dist/packem_chunks/publish-guards.js +1 -0
  96. package/dist/packem_chunks/registry.js +48 -0
  97. package/dist/packem_chunks/resolveFormatter.js +9 -0
  98. package/dist/packem_chunks/security.js +1 -0
  99. package/dist/packem_chunks/shell-runner.js +1 -0
  100. package/dist/packem_chunks/slack.js +2 -0
  101. package/dist/packem_chunks/snapshot.js +2 -0
  102. package/dist/packem_chunks/stage-publisher.js +1 -0
  103. package/dist/packem_chunks/staged-registry.js +2 -0
  104. package/dist/packem_chunks/state.js +3 -0
  105. package/dist/packem_chunks/success-walk.js +8 -0
  106. package/dist/packem_chunks/sync.js +1 -1
  107. package/dist/packem_chunks/sync2.js +1 -1
  108. package/dist/packem_chunks/tripwire.js +1 -1
  109. package/dist/packem_chunks/verify-lockfile.js +2 -2
  110. package/dist/packem_chunks/version-resolver.js +2 -0
  111. package/dist/packem_chunks/webhook.js +1 -0
  112. package/dist/packem_chunks/workflow-templates.js +167 -0
  113. package/dist/packem_chunks/workspace.js +2 -0
  114. package/dist/packem_shared/AfterAllProjectsVersioned-CAKI2nWf.js +1 -0
  115. package/dist/packem_shared/ReleaseClient-YHzBIxYS.js +1 -0
  116. package/dist/packem_shared/VisReleaseError-DMGRBTNO.js +1 -0
  117. package/dist/packem_shared/{ai-analysis-DT3bU-_M.js → ai-analysis-K-DKU3ZA.js} +1 -1
  118. package/dist/packem_shared/{ai-fix-BkNqd5nP.js → ai-fix-BPrYoCk8.js} +1 -1
  119. package/dist/packem_shared/api.d-BPftyU9r.d.ts +27 -0
  120. package/dist/packem_shared/createAdapter-bU4DIP3F.js +1 -0
  121. package/dist/packem_shared/createVersionActions-BK43SNDH.js +1 -0
  122. package/dist/packem_shared/{cyclonedx-86-DbHtf.js → cyclonedx-kYozDyxp.js} +3 -3
  123. package/dist/packem_shared/defineFormatter-D5dCp6Kv.js +1 -0
  124. package/dist/packem_shared/dependency-scan-anTuZB1t.js +1 -0
  125. package/dist/packem_shared/{docker-tNrDU3oK.js → docker-BMLrNtWm.js} +1 -1
  126. package/dist/packem_shared/{failure-log-Dwqt6_Ga.js → failure-log-CEWP3bP0.js} +1 -1
  127. package/dist/packem_shared/index-BJbpNthk.js +1 -0
  128. package/dist/packem_shared/index-CgcF6_wo.js +1 -0
  129. package/dist/packem_shared/{index-dQ37x8_P.js → index-D1_fbGbj.js} +1 -1
  130. package/dist/packem_shared/interface.d-B7VK2rcH.d.ts +148 -0
  131. package/dist/packem_shared/interface.d-Cezzifoh.d.ts +106 -0
  132. package/dist/packem_shared/{missing-package-json-41VUWFBY.js → missing-package-json-BfWUxTGv.js} +1 -1
  133. package/dist/packem_shared/{native-config-sync-BKAZ0NIs.js → native-config-sync-BEkJW7g3.js} +8 -8
  134. package/dist/packem_shared/pm-runner-OGResYrA.js +1 -0
  135. package/dist/packem_shared/provenance-_CJjMKwu.js +1 -0
  136. package/dist/packem_shared/public-api-WqUCiyIe.js +131 -0
  137. package/dist/packem_shared/{registry-keys-Bf2zzlcZ.js → registry-keys-BfFto6vI.js} +1 -1
  138. package/dist/packem_shared/{resolve-explicit-jH0RKyMJ.js → resolve-explicit-CMDl55Nz.js} +2 -2
  139. package/dist/packem_shared/s1ngularity-Dhr3bPk0.js +1 -0
  140. package/dist/packem_shared/{scan-progress-JBbd9QeT.js → scan-progress-DG7_JmTV.js} +1 -1
  141. package/dist/packem_shared/{signatures-D1H6h6GH.js → signatures-C730vkyK.js} +2 -2
  142. package/dist/packem_shared/slug-DoueYuLo.js +1 -0
  143. package/dist/packem_shared/spinner-CV3WVJLv.js +1 -0
  144. package/dist/packem_shared/sticky-comment-D6_7-w8T.js +1 -0
  145. package/dist/packem_shared/{tabs-BqUepRaD.js → tabs-BuTy5gPV.js} +1 -1
  146. package/dist/packem_shared/{typosquats-C8qg1neE.js → typosquats-DN78xx1x.js} +1 -1
  147. package/dist/packem_shared/use-measured-height-_eVGWtWt.js +1 -0
  148. package/dist/packem_shared/verify-6WCmFmy8.js +1 -0
  149. package/dist/packem_shared/{vis-update-app-CTwRkNgj.js → vis-update-app-k3fDxech.js} +1 -1
  150. package/dist/release/core/changelog/index.d.ts +5 -0
  151. package/dist/release/core/changelog/index.js +1 -0
  152. package/dist/release/core/package-managers/index.d.ts +6 -0
  153. package/dist/release/core/package-managers/index.js +1 -0
  154. package/dist/release/core/version-actions/index.d.ts +14 -0
  155. package/dist/release/core/version-actions/index.js +1 -0
  156. package/dist/release/index.d.ts +196 -0
  157. package/dist/release/index.js +1 -0
  158. package/dist/release/plugin-sdk.d.ts +127 -0
  159. package/dist/release/plugin-sdk.js +1 -0
  160. package/dist/release/presets.d.ts +225 -0
  161. package/dist/release/presets.js +1 -0
  162. package/dist/release/types.d.ts +1377 -0
  163. package/dist/release/types.js +1 -0
  164. package/index.d.ts +201 -201
  165. package/index.js +578 -752
  166. package/package.json +52 -10
  167. package/schemas/vis-config.schema.json +1394 -6
  168. package/schemas/vis-release-config.schema.json +1390 -0
  169. package/dist/packem_shared/dependency-scan-BDTH898x.js +0 -1
  170. package/dist/packem_shared/index-CB4p298r.js +0 -1
  171. package/dist/packem_shared/index-DMefdF51.js +0 -1
  172. package/dist/packem_shared/pm-runner-pVihAfxV.js +0 -1
  173. package/dist/packem_shared/provenance-DMuEftgc.js +0 -1
  174. package/dist/packem_shared/s1ngularity-BkfgC6NO.js +0 -1
  175. package/dist/packem_shared/spinner-BXSl864p.js +0 -1
  176. package/dist/packem_shared/use-measured-height-BBJ9intr.js +0 -1
  177. package/dist/packem_shared/verify-Du7xZ2BJ.js +0 -1
@@ -833,6 +833,10 @@
833
833
  "additionalProperties": false,
834
834
  "description": "Pre-flight checks fired before `vis run` starts the orchestrator. Each check is opt-out (`false`) — defaults are sensible for the common monorepo case."
835
835
  },
836
+ "release": {
837
+ "$ref": "#/$defs/VisReleaseConfig",
838
+ "description": "Configuration for the `vis release` subsystem. Controls change-file authoring, version computation, channel routing, publish behavior, and CI integration. See `packages/tooling/vis/rfc/design-release-manager.md`."
839
+ },
836
840
  "run": {
837
841
  "type": "object",
838
842
  "properties": {
@@ -2100,14 +2104,14 @@
2100
2104
  "description": "When `true`, the cache directory is partitioned by a hash of the resolved `globalEnv` values. Changing a globalEnv var moves cache writes into a new namespace; rolling it back reuses the old namespace and its hits. Without this option, any globalEnv change silently busts every cached entry.\n\nKeep disabled when globalEnv is stable across runs — the extra path depth offers no value, and misconfigured namespaces can hide stale hits.",
2101
2105
  "default": false
2102
2106
  },
2103
- "onFingerprint": {
2104
- "not": {},
2105
- "description": "Plugin extension point invoked during task fingerprinting. Fires once per task after the built-in inputs (filesets, runtime, env) have been gathered and before the hash is sealed. Contributions made through the supplied {@link FingerprintContributor } are mixed deterministically into the final hash.\n\nThrowing aborts fingerprinting for that task — the task fails before any cache lookup runs, so a buggy plugin can't silently corrupt cache state.\n\nWired by `vis` to bridge into the `task:fingerprint` hook; standalone task-runner consumers can pass a callback directly."
2106
- },
2107
2107
  "onDiagnostic": {
2108
2108
  "not": {},
2109
2109
  "description": "Non-fatal diagnostic sink, forwarded to the task hasher. Fires when a cacheable task's file-set inputs resolve to zero files (the signature of a dropped `namedInputs`, a wrong `{projectRoot}`, or a glob matching nothing — a task that will reuse one cache entry forever). `vis` wires this to its logger."
2110
2110
  },
2111
+ "onFingerprint": {
2112
+ "not": {},
2113
+ "description": "Plugin extension point invoked during task fingerprinting. Fires once per task after the built-in inputs (filesets, runtime, env) have been gathered and before the hash is sealed. Contributions made through the supplied {@link FingerprintContributor } are mixed deterministically into the final hash.\n\nThrowing aborts fingerprinting for that task — the task fails before any cache lookup runs, so a buggy plugin can't silently corrupt cache state.\n\nWired by `vis` to bridge into the `task:fingerprint` hook; standalone task-runner consumers can pass a callback directly."
2114
+ },
2111
2115
  "parallel": {
2112
2116
  "type": [
2113
2117
  "number",
@@ -2257,8 +2261,8 @@
2257
2261
  },
2258
2262
  "verifyOnDownload": {
2259
2263
  "type": "boolean",
2260
- "description": "Reject downloads whose signature doesn't match or is missing. Set to `true` once every upload on your server is signed.",
2261
- "default": false
2264
+ "description": "Reject downloads whose signature doesn't match or is missing.\n\nDefaults to `true` whenever a {@link RemoteCacheSigning.secret } is configured: signing implies the intent to authenticate artifacts, so the secure default is to verify. Set to `false` only during a migration window where some uploads on your server are not yet signed — be aware this re-opens the cache-poisoning attack surface (a server or MITM can strip the signature header and have unsigned artifacts extracted as build outputs).",
2265
+ "default": true
2262
2266
  }
2263
2267
  },
2264
2268
  "required": [
@@ -3921,6 +3925,1390 @@
3921
3925
  "additionalProperties": false,
3922
3926
  "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."
3923
3927
  },
3928
+ "VisReleaseConfig": {
3929
+ "type": "object",
3930
+ "properties": {
3931
+ "access": {
3932
+ "type": "string",
3933
+ "enum": [
3934
+ "public",
3935
+ "restricted"
3936
+ ],
3937
+ "description": "Default npm `--access` flag. Default: `\"public\"`."
3938
+ },
3939
+ "acknowledgeUnstable": {
3940
+ "type": "boolean",
3941
+ "description": "Suppress the unstable warning printed on first invocation (RFC §21.2)."
3942
+ },
3943
+ "aggregateRelease": {
3944
+ "anyOf": [
3945
+ {
3946
+ "type": "boolean"
3947
+ },
3948
+ {
3949
+ "type": "object",
3950
+ "properties": {
3951
+ "enabled": {
3952
+ "type": "boolean"
3953
+ },
3954
+ "title": {
3955
+ "type": "string"
3956
+ }
3957
+ },
3958
+ "required": [
3959
+ "enabled"
3960
+ ],
3961
+ "additionalProperties": false
3962
+ }
3963
+ ],
3964
+ "description": "Single GH release per wave vs per-package."
3965
+ },
3966
+ "aggregateReleaseTagPattern": {
3967
+ "type": "string",
3968
+ "description": "Pattern for the workspace-level aggregate release tag (when `aggregateRelease.enabled`). Tokens: `{date}`, `{version}` (latest bumped pkg's version). Default: `\"release-{date}\"`."
3969
+ },
3970
+ "allowCustomCommands": {
3971
+ "anyOf": [
3972
+ {
3973
+ "type": "boolean"
3974
+ },
3975
+ {
3976
+ "type": "array",
3977
+ "items": {
3978
+ "type": "string"
3979
+ }
3980
+ }
3981
+ ],
3982
+ "description": "Trust gate for per-package custom commands."
3983
+ },
3984
+ "baseBranch": {
3985
+ "type": "string",
3986
+ "description": "Branch used for `--from` baseline in `status`/`generate`. Default: `\"main\"`."
3987
+ },
3988
+ "bumpDevDependencies": {
3989
+ "anyOf": [
3990
+ {
3991
+ "type": "boolean"
3992
+ },
3993
+ {
3994
+ "type": "array",
3995
+ "items": {
3996
+ "type": "string"
3997
+ }
3998
+ }
3999
+ ],
4000
+ "description": "Opt-in cascade for `devDependencies` bumps (changesets #944 parity).\n\nBy default, when a workspace package is bumped, only its `dependencies` / `peerDependencies` / `optionalDependencies` consumers are considered for propagation — devDependency consumers are silently ignored because consumers of the dependent don't observe the devDep at runtime.\n\nSome teams disagree (especially for type-only packages or build plugins) and want a devDep bump to still trigger a patch on its consumer so the lockfile stays in sync across machines. Set this to:\n\n - `true` — every devDep cascade fires (patch-level on the dependent), regardless of the source package. - `string[]` — narrow allow-list of source package names. Only bumps to packages whose name appears in the list will cascade through devDependencies. Useful when only specific \"infrastructure\" packages should propagate via devDeps.\n\nDefault: `false` (devDep cascades remain off — historical behaviour)."
4001
+ },
4002
+ "bumpMinorPreMajor": {
4003
+ "type": "boolean",
4004
+ "description": "For pre-1.0 versions, demote `major` bumps to `minor`. Common for 0.x libraries that don't want their first breaking change to leap to 2.0. Maps to release-please's `bump-minor-pre-major`. Default `false`."
4005
+ },
4006
+ "bumpPatchForMinorPreMajor": {
4007
+ "type": "boolean",
4008
+ "description": "Companion to `bumpMinorPreMajor` — also demote `minor` bumps to `patch` for pre-1.0 versions. Maps to release-please's `bump-patch-for-minor-pre-major`. No-op without `bumpMinorPreMajor`. Default `false`."
4009
+ },
4010
+ "changedFilePatterns": {
4011
+ "type": "array",
4012
+ "items": {
4013
+ "type": "string"
4014
+ },
4015
+ "description": "Globs that count toward \"package changed\" detection."
4016
+ },
4017
+ "changelog": {
4018
+ "anyOf": [
4019
+ {
4020
+ "type": "boolean",
4021
+ "const": false
4022
+ },
4023
+ {
4024
+ "type": "string"
4025
+ },
4026
+ {
4027
+ "type": "array",
4028
+ "minItems": 2,
4029
+ "maxItems": 2,
4030
+ "prefixItems": [
4031
+ {
4032
+ "type": "string"
4033
+ },
4034
+ {
4035
+ "type": "object",
4036
+ "additionalProperties": {}
4037
+ }
4038
+ ]
4039
+ }
4040
+ ],
4041
+ "description": "Changelog formatter selection. Pass `false` to disable changelog output, one of the built-in names (`\"default\"`, `\"github\"`, `\"keep-a-changelog\"`), a path to a custom module, or a `[path, options]` tuple."
4042
+ },
4043
+ "changesDir": {
4044
+ "type": "string",
4045
+ "description": "Directory holding change files. Default: `\".vis/release\"`."
4046
+ },
4047
+ "channels": {
4048
+ "type": "object",
4049
+ "additionalProperties": {
4050
+ "$ref": "#/$defs/ChannelConfig"
4051
+ },
4052
+ "description": "Per-channel routing config (semantic-release-style)."
4053
+ },
4054
+ "currentVersionResolver": {
4055
+ "type": "string",
4056
+ "enum": [
4057
+ "disk",
4058
+ "git-tag",
4059
+ "registry"
4060
+ ],
4061
+ "description": "Source of truth for \"what is the current version of this package?\", controlling how `oldVersion` is resolved when building the release plan.\n\n `\"disk\"` (default) — read `package.json#version` (or the equivalent manifest field for non-npm versionActions). Preserves vis's historical behaviour and is the right choice when the manifest on disk is the canonical source. `\"registry\"` — query the package registry via the package's `versionActions.readPublishedVersion()`. Useful when the manifest drifts between repo and registry (e.g. teams that publish out-of-band) and you want the registry to win. `\"git-tag\"` — find the highest `releaseTagPattern`-matching tag in the current commit's ancestry and parse the version out of it. Matches nx's `git-tag` resolver and release-please's tag-based lookup.\n\n`\"registry\"` and `\"git-tag\"` fall back to the manifest version when their primary source cannot produce a valid semver (e.g. registry 404 on a freshly-added package, no matching tag yet, etc.) and surface a plan warning so the operator sees what happened.\n\nOverridable per-package via `packages.<name>.currentVersionResolver`.\n\nThe `--first-release` CLI flag is the bootstrap shortcut for this setting — it forces `\"disk\"` regardless of config and additionally skips remote-tag collision checks, so the very first run on a greenfield monorepo can't trip over missing tags or registry 404s."
4062
+ },
4063
+ "defaultManaged": {
4064
+ "type": "boolean",
4065
+ "description": "Default `release.managed` for unconfigured packages. Default: `false`."
4066
+ },
4067
+ "dependencyBumpRules": {
4068
+ "$ref": "#/$defs/DependencyBumpRules",
4069
+ "description": "Default dep-bump rules (overridable per-package)."
4070
+ },
4071
+ "detectCatalogChanges": {
4072
+ "type": "boolean",
4073
+ "description": "Opt-in cascade for `pnpm-workspace.yaml` catalog version bumps (changesets #1707 parity).\n\npnpm's `catalog:` / `catalogs:` blocks let multiple packages share a single version range. When the operator bumps a catalog entry (e.g. `react: ^18.2.0` → `react: ^18.3.0`) every consumer package pulls the new version on its next `pnpm install`. Without detection, vis sees no change to the consumer's `package.json` and skips it — so the published tarball ends up shipping a stale `\"react\": \"catalog:\"` reference that resolves differently across machines.\n\nWhen `true`, vis diffs `pnpm-workspace.yaml` between `HEAD~1` (the previous release commit) and `HEAD` (working tree). Every catalog dep that moved triggers a `patch` bump on each consumer package, attributed as `BumpReason.CATALOG_CHANGED` in the release plan. Set on the consumer's dep cascade rules to widen the bump level via the same `dependencyBumpRules` knob used for direct dependency bumps.\n\nDefault: `false` (backwards-compat — the prior behaviour was to silently ignore catalog changes during plan assembly)."
4074
+ },
4075
+ "fixed": {
4076
+ "type": "array",
4077
+ "items": {
4078
+ "$ref": "#/$defs/ReleaseGroupConfig"
4079
+ },
4080
+ "description": "Fixed groups: members share the same version, all bump on any change.\n\nTwo accepted shapes (backwards-compatible — the original `string[][]` keeps working):\n\n - `string[]` — bare list of package names / globs. Implicitly `{ changelog: { mode: \"per-package\" } }`. - `{ packages, changelog }` — object form, lets you opt into a SHARED changelog file for the group (changesets #1059 parity). When `changelog.mode === \"shared\"`, every member's entry is rendered into one group file (default `<first-member-dir>/GROUP-CHANGELOG.md`)."
4081
+ },
4082
+ "floatingMajorTag": {
4083
+ "type": "boolean",
4084
+ "description": "Floating major-version tag. When `true`, every non-prerelease, non-private release also force-updates a `<safe-name>-v<major>` tag to point at the release commit. `safe-name` is the package name with the leading `@` stripped and `/` replaced by `-`:\n\n - `@acme/action` → `acme-action-v1` - `@vendor/cli` → `vendor-cli-v1` - unscoped `cli` → `cli-v1`\n\nUseful for reusable GitHub Actions consumers who pin to `acme/action@acme-action-v1` and expect automatic patch / minor delivery without a tag-rev migration. The scope is included so two packages with the same unscoped name from different scopes (`@acme/cli` + `@vendor/cli`) don't both retarget the same floating tag.\n\nSkipped on: - Prereleases (per-channel `prerelease` configured). The float would otherwise yank the major pointer across an unstable pre-release boundary. - Packages whose `releaseTagPattern` already includes `{major}` (the pattern is already serving the same role). - Private packages (`package.json#private === true`) and packages that set `skipNpmPublish: true` — there's no published artifact for a consumer to pin against, so a floating tag would just clutter the tag history.\n\nDefault: `false`. Semantic-release parity: #1515."
4085
+ },
4086
+ "formatChangedFiles": {
4087
+ "type": "boolean",
4088
+ "description": "Run the project's Prettier over the files the version step writes (package.json bumps + CHANGELOG.md entries) before committing them (RFC §14 step 7). Scoped to the changed files only — never the whole tree. Resolves the project's own Prettier from the workspace root; soft-fails if Prettier isn't installed.\n\nDefault: `false` (opt-in — a project that doesn't use Prettier, or whose Prettier config conflicts with how vis writes JSON, leaves this off)."
4089
+ },
4090
+ "githubHost": {
4091
+ "type": "string",
4092
+ "description": "Self-hosted GitHub Enterprise host (e.g. `\"github.acme.com\"` — no scheme). Translates to the `GH_HOST` env var that the `gh` CLI consumes natively, so all adapter calls land on the right instance. Operators can also export `GH_HOST` directly; this config knob is the typed, vis.config.ts-discoverable equivalent. Ignored when `provider` resolves to anything other than `github`."
4093
+ },
4094
+ "gitlabHost": {
4095
+ "type": "string",
4096
+ "description": "Self-hosted GitLab host (e.g. `\"gitlab.example.com\"`). Translates to the `GITLAB_HOST` env var that `glab` consumes natively, so all adapter calls land on the right instance. Ignored when `provider` resolves to anything other than `gitlab`."
4097
+ },
4098
+ "gitSignCommits": {
4099
+ "type": "boolean",
4100
+ "description": "Sign release-flow commits with `git commit -S`. Set to `true` in workspaces that enforce `commit.gpgsign = true`. The active git identity must have a configured signing key (gpg, ssh, x509). Default `false`."
4101
+ },
4102
+ "gitUser": {
4103
+ "$ref": "#/$defs/GitUserConfig",
4104
+ "description": "Git committer identity used by CI workflows."
4105
+ },
4106
+ "groupPreVersionCommands": {
4107
+ "type": "object",
4108
+ "additionalProperties": {
4109
+ "type": "string"
4110
+ },
4111
+ "description": "Group-scoped preVersion command. Runs once before any package in the group is versioned. `groupName` matches a `fixed`/`linked` array's index (group-0, group-1, …) or a named entry (future)."
4112
+ },
4113
+ "httpProxy": {
4114
+ "type": "string",
4115
+ "description": "HTTPS proxy URL (e.g. `\"http://proxy.acme.com:8080\"`) for enterprise networks that route outbound HTTPS through a proxy.\n\nWired through to two surfaces:\n\n 1. `gh` / `glab` CLI subprocesses get `HTTPS_PROXY` and `HTTP_PROXY` set on their env so they tunnel through the proxy exactly as if the operator had exported the vars manually.\n\n 2. Every internal `fetch()` call (registry probes in version-actions/{cargo,python,maven,container}.ts and the shared `safeFetchVersionMetadata` helper) attaches an undici `ProxyAgent` via the `dispatcher` option, so Node's built-in fetch routes through the proxy as well.\n\nNode 22's bundled undici handles the proxy plumbing — no `https-proxy-agent` dep needed."
4116
+ },
4117
+ "ignore": {
4118
+ "type": "array",
4119
+ "items": {
4120
+ "type": "string"
4121
+ },
4122
+ "description": "Globs of packages to exclude from release entirely."
4123
+ },
4124
+ "include": {
4125
+ "type": "array",
4126
+ "items": {
4127
+ "type": "string"
4128
+ },
4129
+ "description": "Globs that override `ignore` and `private` exclusion."
4130
+ },
4131
+ "linked": {
4132
+ "type": "array",
4133
+ "items": {
4134
+ "$ref": "#/$defs/ReleaseGroupConfig"
4135
+ },
4136
+ "description": "Linked groups: members share bump levels but only changed members publish. Accepts the same dual-shape format as `fixed` — see the `ReleaseGroupConfig` doc comment for details."
4137
+ },
4138
+ "notifications": {
4139
+ "$ref": "#/$defs/NotificationsConfig",
4140
+ "description": "Notifications — post-release fan-out to chat / webhook destinations. See {@link NotificationsConfig } . Each channel runs in parallel; per-channel failures log a warning but do NOT fail the publish."
4141
+ },
4142
+ "oneCommitPerPackage": {
4143
+ "type": "boolean",
4144
+ "description": "Emit one release commit per package (a `release(channel): pkg@version [skip ci]` message) instead of a single aggregate commit for the whole wave (RFC §19.5). Mirrors the per-package commit history that multi-semantic-release produced — useful for projects migrating off it that want to preserve `git log` shape. Only honoured when `aggregateRelease` is falsy. Shared artifacts (lockfile + consumed change-file deletions) ride along in the final package's commit.\n\nDefault: `false` (one aggregate commit per wave)."
4145
+ },
4146
+ "packages": {
4147
+ "type": "object",
4148
+ "additionalProperties": {
4149
+ "$ref": "#/$defs/PerPackageReleaseConfig"
4150
+ },
4151
+ "description": "Per-package overrides (matches `package.json[\"vis-release\"]`)."
4152
+ },
4153
+ "postPublishCommand": {
4154
+ "type": "string",
4155
+ "description": "Shell command run after all publishes complete."
4156
+ },
4157
+ "postVersionCommand": {
4158
+ "type": "string",
4159
+ "description": "Shell command run after versioning, before publish."
4160
+ },
4161
+ "prePublishCommand": {
4162
+ "type": "string",
4163
+ "description": "Shell command run after versioning, before publish."
4164
+ },
4165
+ "preVersionCommand": {
4166
+ "type": "string",
4167
+ "description": "Shell command run before any versioning."
4168
+ },
4169
+ "privatePackages": {
4170
+ "type": "object",
4171
+ "properties": {
4172
+ "tag": {
4173
+ "type": "boolean"
4174
+ },
4175
+ "version": {
4176
+ "type": "boolean"
4177
+ }
4178
+ },
4179
+ "required": [
4180
+ "tag",
4181
+ "version"
4182
+ ],
4183
+ "additionalProperties": false,
4184
+ "description": "Whether to version + tag private packages."
4185
+ },
4186
+ "provider": {
4187
+ "type": "string",
4188
+ "enum": [
4189
+ "github",
4190
+ "gitlab",
4191
+ "auto"
4192
+ ],
4193
+ "description": "Forge provider for remote operations (PR comments, releases, version PRs)."
4194
+ },
4195
+ "publish": {
4196
+ "$ref": "#/$defs/PublishConfig",
4197
+ "description": "Publish-related config."
4198
+ },
4199
+ "releaseNoteTemplate": {
4200
+ "type": "object",
4201
+ "properties": {
4202
+ "footer": {
4203
+ "type": "string"
4204
+ },
4205
+ "header": {
4206
+ "type": "string"
4207
+ }
4208
+ },
4209
+ "additionalProperties": false,
4210
+ "description": "Wrap each per-package GitHub / GitLab release body with operator- supplied header / footer text. Common use: link a migration guide above the auto-generated body, or paste a sponsorship blurb below.\n\nBoth fields are template strings supporting tokens: - `{name}` — package name - `{version}` — new version - `{previousVersion}` — previous version - `{date}` — `YYYY-MM-DD` - `{repo}` — `owner/repo` slug - `{contributors}` — bullet list of authors collected from the entire wave's change-file `author:` frontmatter (release-please #292). Wave-scoped — every per-package release in the wave sees the same set, so cascade and dependency-only bumps still credit the upstream author. Block-only — keep this token on its own line, typically under a heading; inline use like `Thanks {contributors}!` will produce broken markdown. Authors are de-duplicated case-insensitively, markdown-escaped, and filtered through the github formatter's `internalAuthors` list (when configured). Empty string when no change file in the wave declared an author.\n\nWhen set, the rendered body is composed as `header\\n\\n<body>\\n\\nfooter`. Empty / unset fields are skipped (no leading / trailing blank line).\n\n> **Aggregate-release mode (`release.aggregateRelease: true`)**: the > header and footer are NOT applied. The aggregate release body is > already operator-templated via `release.aggregateRelease.title` > and the per-package list is auto-rendered. If you want a custom > prefix/suffix on the aggregate body, override > `release.aggregateRelease.title` directly.\n\nRelease-please parity: #1274."
4211
+ },
4212
+ "releaseTagPattern": {
4213
+ "type": "string",
4214
+ "description": "Git tag template — overridable per-package via `package.json[\"vis-release\"][\"releaseTagPattern\"]`. Tokens: `{name}`, `{unscopedName}`, `{version}`, `{major}`, `{minor}`, `{patch}`, `{date}`, `{channel}`. Default: `\"{name}@{version}\"`."
4215
+ },
4216
+ "signing": {
4217
+ "type": "object",
4218
+ "properties": {
4219
+ "key": {
4220
+ "type": "string"
4221
+ },
4222
+ "mode": {
4223
+ "type": "string",
4224
+ "enum": [
4225
+ "gpg",
4226
+ "sigstore",
4227
+ "ssh"
4228
+ ]
4229
+ }
4230
+ },
4231
+ "required": [
4232
+ "mode"
4233
+ ],
4234
+ "additionalProperties": false,
4235
+ "description": "Sign release tags. Wraps `git tag -s` / `-u <key>` and adds a `gitsign`-based code path for sigstore-style keyless signing.\n\nModes: - `\"gpg\"` — `git tag -s` (or `-u <key>` when `key` is set). Relies on `user.signingkey` in git config. - `\"ssh\"` — Same `-s` flag, but the operator must have `gpg.format=ssh` + `user.signingkey=<path-to-key>` configured. Doctor surfaces missing config with a warning at preflight. - `\"sigstore\"` — Experimental (\"preview\"). Uses `gitsign` when on PATH, otherwise falls back to GPG with a warning.\n\nPer-package signing is not supported (release tags are a workspace- wide artefact). Default: undefined (no signing).\n\nRelease-please parity: #1738, #1314."
4236
+ },
4237
+ "snapshot": {
4238
+ "$ref": "#/$defs/SnapshotConfig",
4239
+ "description": "Snapshot config."
4240
+ },
4241
+ "successWalk": {
4242
+ "$ref": "#/$defs/SuccessWalkConfig",
4243
+ "description": "Post-release notification walk. Configures the \"🎉 This is included in version X.Y.Z\" comment + `released` label pass that runs after a successful publish wave.\n\n**Default OFF.** Leave undefined and the walk never runs — vis will not touch third-party PRs referenced in changelog bodies. Set to `{}` to opt in with defaults, or pass an object to override the comment template / labels / prerelease behaviour."
4244
+ },
4245
+ "updateInternalDependencies": {
4246
+ "$ref": "#/$defs/UpdateInternalDependenciesMode",
4247
+ "description": "Dep-propagation mode. Default: `\"out-of-range\"`."
4248
+ },
4249
+ "versionPr": {
4250
+ "$ref": "#/$defs/VersionPrConfig",
4251
+ "description": "Version-PR config."
4252
+ },
4253
+ "workspaceChangelog": {
4254
+ "anyOf": [
4255
+ {
4256
+ "type": "boolean",
4257
+ "const": false
4258
+ },
4259
+ {
4260
+ "type": "object",
4261
+ "properties": {
4262
+ "file": {
4263
+ "type": "string"
4264
+ },
4265
+ "waveHeading": {
4266
+ "type": "string"
4267
+ }
4268
+ },
4269
+ "additionalProperties": false
4270
+ }
4271
+ ],
4272
+ "description": "Workspace-level changelog config (RFC §6.1 / nx parity). When set, renders one CHANGELOG.md at the workspace root in addition to per-package files."
4273
+ }
4274
+ },
4275
+ "additionalProperties": false
4276
+ },
4277
+ "ChannelConfig": {
4278
+ "type": "object",
4279
+ "properties": {
4280
+ "mode": {
4281
+ "$ref": "#/$defs/ChannelMode",
4282
+ "description": "CI behavior: `auto-publish` (push triggers publish) or `version-pr` (review gate)."
4283
+ },
4284
+ "prerelease": {
4285
+ "type": "string",
4286
+ "description": "Pre-release identifier (e.g. `\"alpha\"`, `\"beta\"`, `\"rc\"`). Omit for stable channels."
4287
+ },
4288
+ "range": {
4289
+ "type": "string",
4290
+ "description": "For maintenance branches: `\"match\"` keeps releases inside the branch's semver range."
4291
+ },
4292
+ "tag": {
4293
+ "type": "string",
4294
+ "description": "npm dist-tag for publishes on this channel. Use `\"branch-name\"` to mirror the branch name."
4295
+ }
4296
+ },
4297
+ "required": [
4298
+ "tag"
4299
+ ],
4300
+ "additionalProperties": false
4301
+ },
4302
+ "ChannelMode": {
4303
+ "type": "string",
4304
+ "enum": [
4305
+ "auto-publish",
4306
+ "version-pr"
4307
+ ]
4308
+ },
4309
+ "DependencyBumpRules": {
4310
+ "type": "object",
4311
+ "properties": {
4312
+ "dependencies": {
4313
+ "anyOf": [
4314
+ {
4315
+ "$ref": "#/$defs/DependencyBumpRule"
4316
+ },
4317
+ {
4318
+ "type": "boolean",
4319
+ "const": false
4320
+ }
4321
+ ]
4322
+ },
4323
+ "devDependencies": {
4324
+ "anyOf": [
4325
+ {
4326
+ "$ref": "#/$defs/DependencyBumpRule"
4327
+ },
4328
+ {
4329
+ "type": "boolean",
4330
+ "const": false
4331
+ }
4332
+ ]
4333
+ },
4334
+ "peerDependencies": {
4335
+ "anyOf": [
4336
+ {
4337
+ "$ref": "#/$defs/DependencyBumpRule"
4338
+ },
4339
+ {
4340
+ "type": "boolean",
4341
+ "const": false
4342
+ }
4343
+ ]
4344
+ },
4345
+ "optionalDependencies": {
4346
+ "anyOf": [
4347
+ {
4348
+ "$ref": "#/$defs/DependencyBumpRule"
4349
+ },
4350
+ {
4351
+ "type": "boolean",
4352
+ "const": false
4353
+ }
4354
+ ]
4355
+ }
4356
+ },
4357
+ "additionalProperties": false
4358
+ },
4359
+ "DependencyBumpRule": {
4360
+ "type": "object",
4361
+ "properties": {
4362
+ "bumpAs": {
4363
+ "$ref": "#/$defs/BumpAs",
4364
+ "description": "Bump level to apply to the dependent. `\"match\"` = same as source."
4365
+ },
4366
+ "trigger": {
4367
+ "$ref": "#/$defs/BumpLevel",
4368
+ "description": "Minimum source bump that activates this rule."
4369
+ }
4370
+ },
4371
+ "required": [
4372
+ "bumpAs",
4373
+ "trigger"
4374
+ ],
4375
+ "additionalProperties": false
4376
+ },
4377
+ "BumpAs": {
4378
+ "anyOf": [
4379
+ {
4380
+ "$ref": "#/$defs/BumpLevel"
4381
+ },
4382
+ {
4383
+ "type": "string",
4384
+ "const": "match"
4385
+ }
4386
+ ]
4387
+ },
4388
+ "BumpLevel": {
4389
+ "type": "string",
4390
+ "enum": [
4391
+ "major",
4392
+ "minor",
4393
+ "patch",
4394
+ "none"
4395
+ ],
4396
+ "description": "Public types for the vis release subsystem.\n\nImported via `@visulima/vis/release/types` sub-export. See the RFC at `packages/tooling/vis/rfc/design-release-manager.md` for the full design.\n\nStability: every type here is part of vis's public API surface — breaking changes require a vis major version bump (RFC §21.1)."
4397
+ },
4398
+ "ReleaseGroupConfig": {
4399
+ "anyOf": [
4400
+ {
4401
+ "type": "array",
4402
+ "items": {
4403
+ "type": "string"
4404
+ }
4405
+ },
4406
+ {
4407
+ "type": "object",
4408
+ "properties": {
4409
+ "changelog": {
4410
+ "$ref": "#/$defs/ReleaseGroupChangelogConfig"
4411
+ },
4412
+ "name": {
4413
+ "type": "string",
4414
+ "description": "Optional name for the group. Used as the heading in the shared changelog when set; defaults to a \"group-N\"-style identifier derived from the array index."
4415
+ },
4416
+ "packages": {
4417
+ "type": "array",
4418
+ "items": {
4419
+ "type": "string"
4420
+ },
4421
+ "description": "Package names or globs that belong to this group."
4422
+ }
4423
+ },
4424
+ "required": [
4425
+ "packages"
4426
+ ],
4427
+ "additionalProperties": false
4428
+ }
4429
+ ],
4430
+ "description": "Dual-shape config for `release.fixed` / `release.linked` entries.\n\nBare `string[]` is interpreted as `{ packages, changelog: { mode: \"per-package\" } }` — keeps existing configs working without migration."
4431
+ },
4432
+ "ReleaseGroupChangelogConfig": {
4433
+ "type": "object",
4434
+ "properties": {
4435
+ "mode": {
4436
+ "type": "string",
4437
+ "enum": [
4438
+ "per-package",
4439
+ "shared"
4440
+ ]
4441
+ },
4442
+ "path": {
4443
+ "type": "string",
4444
+ "description": "Override file path. Default: `<first-member-dir>/GROUP-CHANGELOG.md`."
4445
+ }
4446
+ },
4447
+ "required": [
4448
+ "mode"
4449
+ ],
4450
+ "additionalProperties": false,
4451
+ "description": "Per-group changelog routing.\n\n - `\"per-package\"` (default) — every member writes to its own `<pkg-dir>/CHANGELOG.md` exactly as if it weren't grouped. - `\"shared\"` — every member's entry is rendered into ONE shared file. `path` overrides the default location (`<first-member-dir>/GROUP-CHANGELOG.md`). Useful for `core/utils` pairs and other tightly-coupled package sets where one consolidated changelog reads better than N tiny ones."
4452
+ },
4453
+ "GitUserConfig": {
4454
+ "type": "object",
4455
+ "properties": {
4456
+ "email": {
4457
+ "type": "string"
4458
+ },
4459
+ "name": {
4460
+ "type": "string"
4461
+ }
4462
+ },
4463
+ "required": [
4464
+ "email",
4465
+ "name"
4466
+ ],
4467
+ "additionalProperties": false
4468
+ },
4469
+ "NotificationsConfig": {
4470
+ "type": "object",
4471
+ "properties": {
4472
+ "discord": {
4473
+ "anyOf": [
4474
+ {
4475
+ "$ref": "#/$defs/DiscordConfig"
4476
+ },
4477
+ {
4478
+ "type": "array",
4479
+ "items": {
4480
+ "$ref": "#/$defs/DiscordConfig"
4481
+ }
4482
+ }
4483
+ ],
4484
+ "description": "Built-in Discord channel(s). Single config or array. Each posts a formatted embed with title + bullet-list of packages."
4485
+ },
4486
+ "plugins": {
4487
+ "type": "array",
4488
+ "items": {
4489
+ "anyOf": [
4490
+ {
4491
+ "type": "string"
4492
+ },
4493
+ {
4494
+ "type": "array",
4495
+ "minItems": 2,
4496
+ "maxItems": 2,
4497
+ "prefixItems": [
4498
+ {
4499
+ "type": "string"
4500
+ },
4501
+ {
4502
+ "type": "object",
4503
+ "additionalProperties": {}
4504
+ }
4505
+ ]
4506
+ }
4507
+ ]
4508
+ },
4509
+ "description": "Custom channels loaded from a path. The module must export a default `NotificationChannel` (object with `.send`) OR a factory `(options) => NotificationChannel` for the tuple `[path, options]` form."
4510
+ },
4511
+ "skipPrerelease": {
4512
+ "type": "boolean",
4513
+ "description": "Skip notifications on prerelease waves (when every published version has a `-…` suffix). Default `true` — most teams want Slack noise only on stable releases."
4514
+ },
4515
+ "slack": {
4516
+ "anyOf": [
4517
+ {
4518
+ "$ref": "#/$defs/SlackConfig"
4519
+ },
4520
+ {
4521
+ "type": "array",
4522
+ "items": {
4523
+ "$ref": "#/$defs/SlackConfig"
4524
+ }
4525
+ }
4526
+ ],
4527
+ "description": "Built-in Slack channel(s). Each posts a Block Kit message with a header + package list + context block."
4528
+ },
4529
+ "webhook": {
4530
+ "anyOf": [
4531
+ {
4532
+ "$ref": "#/$defs/WebhookConfig"
4533
+ },
4534
+ {
4535
+ "type": "array",
4536
+ "items": {
4537
+ "$ref": "#/$defs/WebhookConfig"
4538
+ }
4539
+ }
4540
+ ],
4541
+ "description": "Generic webhook(s) for Teams / Mattermost / internal dashboards."
4542
+ }
4543
+ },
4544
+ "additionalProperties": false
4545
+ },
4546
+ "DiscordConfig": {
4547
+ "type": "object",
4548
+ "properties": {
4549
+ "id": {
4550
+ "type": "string",
4551
+ "description": "Optional disambiguator for log lines + doctor checks."
4552
+ },
4553
+ "includeSkipped": {
4554
+ "type": "boolean",
4555
+ "description": "Skip the `Skipped (N):` block. Default false (skipped are surfaced)."
4556
+ },
4557
+ "title": {
4558
+ "type": "string",
4559
+ "description": "Title template — see `expandNotificationTemplate` for tokens (`{count}`, `{packages}`, `{firstName}`, `{firstVersion}`, `{channel}`, `{repo}`, `{date}`). When omitted, a sensible \"🚀 Released N packages\" default is used."
4560
+ },
4561
+ "avatarUrl": {
4562
+ "type": "string",
4563
+ "description": "Override the embed avatar."
4564
+ },
4565
+ "color": {
4566
+ "type": "number",
4567
+ "description": "Embed colour as an integer RGB (e.g. `0x3B82F6` = blue-500)."
4568
+ },
4569
+ "username": {
4570
+ "type": "string",
4571
+ "description": "Bot display name override."
4572
+ },
4573
+ "webhook": {
4574
+ "type": "string",
4575
+ "description": "Discord webhook URL. Server+channel scoped."
4576
+ }
4577
+ },
4578
+ "required": [
4579
+ "webhook"
4580
+ ],
4581
+ "additionalProperties": false
4582
+ },
4583
+ "SlackConfig": {
4584
+ "type": "object",
4585
+ "properties": {
4586
+ "id": {
4587
+ "type": "string",
4588
+ "description": "Optional disambiguator for log lines + doctor checks."
4589
+ },
4590
+ "includeSkipped": {
4591
+ "type": "boolean",
4592
+ "description": "Skip the `Skipped (N):` block. Default false (skipped are surfaced)."
4593
+ },
4594
+ "title": {
4595
+ "type": "string",
4596
+ "description": "Title template — see `expandNotificationTemplate` for tokens (`{count}`, `{packages}`, `{firstName}`, `{firstVersion}`, `{channel}`, `{repo}`, `{date}`). When omitted, a sensible \"🚀 Released N packages\" default is used."
4597
+ },
4598
+ "channelOverride": {
4599
+ "type": "string",
4600
+ "description": "Override the channel the webhook posts to. Only honoured when the webhook was created with multi-channel posting allowed (rare)."
4601
+ },
4602
+ "iconEmoji": {
4603
+ "type": "string",
4604
+ "description": "Bot icon emoji (e.g. `\":rocket:\"`)."
4605
+ },
4606
+ "username": {
4607
+ "type": "string",
4608
+ "description": "Bot display name override."
4609
+ },
4610
+ "webhook": {
4611
+ "type": "string",
4612
+ "description": "Slack incoming-webhook URL. Workspace+channel scoped. Use env substitution if you don't want it inline: `webhook: \"${SLACK_WEBHOOK_URL}\"`."
4613
+ }
4614
+ },
4615
+ "required": [
4616
+ "webhook"
4617
+ ],
4618
+ "additionalProperties": false
4619
+ },
4620
+ "WebhookConfig": {
4621
+ "type": "object",
4622
+ "properties": {
4623
+ "id": {
4624
+ "type": "string",
4625
+ "description": "Optional disambiguator for log lines + doctor checks."
4626
+ },
4627
+ "includeSkipped": {
4628
+ "type": "boolean",
4629
+ "description": "Skip the `Skipped (N):` block. Default false (skipped are surfaced)."
4630
+ },
4631
+ "title": {
4632
+ "type": "string",
4633
+ "description": "Title template — see `expandNotificationTemplate` for tokens (`{count}`, `{packages}`, `{firstName}`, `{firstVersion}`, `{channel}`, `{repo}`, `{date}`). When omitted, a sensible \"🚀 Released N packages\" default is used."
4634
+ },
4635
+ "body": {
4636
+ "description": "Body template. When omitted, the full `NotificationContext` is sent verbatim as JSON. When provided, every string leaf is run through `expandNotificationTemplate`."
4637
+ },
4638
+ "headers": {
4639
+ "type": "object",
4640
+ "additionalProperties": {
4641
+ "type": "string"
4642
+ },
4643
+ "description": "Additional headers (values run through template interpolation)."
4644
+ },
4645
+ "method": {
4646
+ "type": "string",
4647
+ "enum": [
4648
+ "POST",
4649
+ "PUT"
4650
+ ],
4651
+ "description": "HTTP method. Default `POST`."
4652
+ },
4653
+ "url": {
4654
+ "type": "string",
4655
+ "description": "Target URL."
4656
+ }
4657
+ },
4658
+ "required": [
4659
+ "url"
4660
+ ],
4661
+ "additionalProperties": false
4662
+ },
4663
+ "PerPackageReleaseConfig": {
4664
+ "type": "object",
4665
+ "properties": {
4666
+ "additionalPaths": {
4667
+ "type": "array",
4668
+ "items": {
4669
+ "type": "string"
4670
+ },
4671
+ "description": "Extra directories (or globs) that logically belong to this package. Used by `vis release check --strict` to attribute changes outside the package's own directory to this package — e.g. a shared `docs/api/` directory whose updates should still trip the \"covered by a change file?\" gate for the package they document.\n\nGlobs are workspace-root-relative (NOT package-directory-relative). Examples:\n\n ```ts release: { packages: { \"@scope/cli\": { additionalPaths: [\"docs/cli/**\", \"examples/cli/**\"], }, }, } ```\n\nDefault: `undefined` (only the package's own directory is attributed to it). Release-please parity: #1921."
4672
+ },
4673
+ "buildCommand": {
4674
+ "type": "string",
4675
+ "description": "Custom shell command run before publish (requires `allowCustomCommands`)."
4676
+ },
4677
+ "buildContext": {
4678
+ "type": "string",
4679
+ "description": "Build context passed to `docker buildx build` (the final positional argument). Honoured by the `container` versionActions; defaults to the package directory."
4680
+ },
4681
+ "cargoTomlPath": {
4682
+ "type": "string",
4683
+ "description": "Relative path from the package directory to `Cargo.toml` for the `cargo` versionActions. Set automatically by the `cargo()` preset from its `crateDir` option. Defaults to `\"Cargo.toml\"`."
4684
+ },
4685
+ "cascadeTo": {
4686
+ "type": "object",
4687
+ "additionalProperties": {
4688
+ "$ref": "#/$defs/DependencyBumpRule"
4689
+ },
4690
+ "description": "Source-side cascade: glob → rule."
4691
+ },
4692
+ "changedFilePatterns": {
4693
+ "type": "array",
4694
+ "items": {
4695
+ "type": "string"
4696
+ },
4697
+ "description": "Per-pkg override of `release.changedFilePatterns`. Replaces (does not merge)."
4698
+ },
4699
+ "checkPublished": {
4700
+ "type": "string",
4701
+ "description": "Custom shell command that prints currently-published version to stdout."
4702
+ },
4703
+ "containerBuildArgs": {
4704
+ "type": "object",
4705
+ "additionalProperties": {
4706
+ "type": "string"
4707
+ },
4708
+ "description": "Extra `--build-arg KEY=VALUE` pairs forwarded to `docker buildx build`. Useful for stamping the version into the image at build time. Consumed by the `container` versionActions."
4709
+ },
4710
+ "containerImage": {
4711
+ "type": "string",
4712
+ "description": "Fully-qualified container image reference, e.g. `\"ghcr.io/scope/foo\"`. Required by the `container` versionActions (no built-in default since the registry hostname is operator- specific). Set automatically by the `container()` preset."
4713
+ },
4714
+ "containerPlatforms": {
4715
+ "type": "array",
4716
+ "items": {
4717
+ "type": "string"
4718
+ },
4719
+ "description": "Target platforms passed to `docker buildx build --platform`. Defaults to `[\"linux/amd64\", \"linux/arm64\"]`. Single-arch builds can pass a one-entry array."
4720
+ },
4721
+ "containerSigning": {
4722
+ "type": "string",
4723
+ "const": "cosign",
4724
+ "description": "Post-push signing scheme for the `container` versionActions. `\"cosign\"` runs `cosign sign --yes <image>:<version>` against the just-pushed immutable tag. Future schemes (sigstore-bundle, notation, etc.) can extend this union."
4725
+ },
4726
+ "containerSkipLatest": {
4727
+ "type": "boolean",
4728
+ "description": "Skip the conventional `:latest` floating tag on push. Useful for pre-release / channel-specific images that shouldn't move the shared `latest` pointer."
4729
+ },
4730
+ "currentVersionResolver": {
4731
+ "type": "string",
4732
+ "enum": [
4733
+ "disk",
4734
+ "git-tag",
4735
+ "registry"
4736
+ ],
4737
+ "description": "Per-package override of the workspace-level `currentVersionResolver`. Same set of modes: `\"disk\"`, `\"registry\"`, `\"git-tag\"`. Useful when one package in the monorepo lags behind the registry / git-tag baseline (e.g. a newly-added package that hasn't been published yet)."
4738
+ },
4739
+ "dependencyBumpRules": {
4740
+ "$ref": "#/$defs/DependencyBumpRules",
4741
+ "description": "Per-pkg override of inbound dep-bump rules."
4742
+ },
4743
+ "extraFiles": {
4744
+ "type": "array",
4745
+ "items": {
4746
+ "$ref": "#/$defs/ExtraFileRule"
4747
+ },
4748
+ "description": "Per-package `extra-files` rules with paths relative to the package directory. Merged with workspace-level `release.publish.extraFiles` (per-package wins on path collision)."
4749
+ },
4750
+ "jsrConfigPath": {
4751
+ "type": "string",
4752
+ "description": "Relative path from the package directory to the JSR manifest (`jsr.json` or `deno.json`) for the `jsr` versionActions. Set automatically by the `jsr()` preset from its `manifestPath` option. Defaults to `\"jsr.json\"`."
4753
+ },
4754
+ "jsrPublishArgs": {
4755
+ "type": "array",
4756
+ "items": {
4757
+ "type": "string"
4758
+ },
4759
+ "description": "Extra arguments forwarded verbatim to `jsr publish` for the `jsr` versionActions (the `jsr()` preset wires this from its `publishArgs` / `allowSlowTypes` options). The most common entry is `\"--allow-slow-types\"`, which JSR requires for packages whose public API has types it can't statically infer. `--allow-dirty` is always passed by vis (the version is bumped on disk before publish) and need not be listed here."
4760
+ },
4761
+ "managed": {
4762
+ "type": "boolean",
4763
+ "description": "Hard opt-in/out — overrides every other rule."
4764
+ },
4765
+ "mavenMetadataUrl": {
4766
+ "type": "string",
4767
+ "description": "Override the Maven Central metadata URL used by the `maven` versionActions for already-published detection. Set this when publishing to a custom repository (Artifactory, Nexus, GitHub Packages); the URL should point at `<base>/<groupId>/<artifactId>/maven-metadata.xml`. Pass `\"\"` (empty string) to disable the metadata check entirely."
4768
+ },
4769
+ "pomPath": {
4770
+ "type": "string",
4771
+ "description": "Override the path to `pom.xml` for the `maven` versionActions, relative to the package directory. Defaults to `\"pom.xml\"`."
4772
+ },
4773
+ "publishCommand": {
4774
+ "anyOf": [
4775
+ {
4776
+ "type": "string"
4777
+ },
4778
+ {
4779
+ "type": "array",
4780
+ "items": {
4781
+ "type": "string"
4782
+ }
4783
+ }
4784
+ ],
4785
+ "description": "Custom shell command run instead of `npm publish` (requires `allowCustomCommands`)."
4786
+ },
4787
+ "pythonProjectDir": {
4788
+ "type": "string",
4789
+ "description": "Relative path from the package directory to the directory containing `pyproject.toml` for the `python` versionActions. Set automatically by the `pyproject()` preset from its `projectDir` option. Defaults to the package directory."
4790
+ },
4791
+ "registry": {
4792
+ "type": "string",
4793
+ "description": "Custom registry URL (overrides `publish.registry`)."
4794
+ },
4795
+ "releaseTagPattern": {
4796
+ "type": "string",
4797
+ "description": "Override the workspace-wide releaseTagPattern. Tokens: `{name}`, `{unscopedName}`, `{version}`, `{major}`, `{minor}`, `{patch}`, `{date}`, `{channel}`."
4798
+ },
4799
+ "skipNpmPublish": {
4800
+ "type": "boolean",
4801
+ "description": "Skip the npm publish step but still create a git tag."
4802
+ },
4803
+ "uvLockPath": {
4804
+ "type": "string",
4805
+ "description": "Relative path from the package directory (or workspace root, for uv-workspace setups) to `uv.lock`. Set when the operator wants vis to acknowledge a uv-managed lockfile during doctor checks.\n\nvis does NOT mutate `uv.lock` itself — uv regenerates it on `uv sync` / `uv build`. The path is recorded only so doctor can warn when the file is missing despite the operator configuring uv-aware tooling. Operators wanting `uv.lock` in the release commit should run `uv lock` between `vis release version` and the commit step (typically wired via `postVersionCommand`).\n\nrelease-please parity: #2561."
4806
+ },
4807
+ "uvWorkspace": {
4808
+ "type": "object",
4809
+ "properties": {
4810
+ "root": {
4811
+ "type": "string"
4812
+ }
4813
+ },
4814
+ "required": [
4815
+ "root"
4816
+ ],
4817
+ "additionalProperties": false,
4818
+ "description": "uv workspace configuration. When set, the `python` versionActions and the `pyproject()` preset treat this package as a member of a uv workspace rooted at `uvWorkspace.root` (relative to the package directory — typically `\"..\"` or the path up to the repo root).\n\nDoctor checks: - the root's pyproject.toml exists at `<root>/pyproject.toml` - `[tool.uv.workspace] members` lists the package's project directory (relative path from the workspace root)\n\nSet automatically by the `pyproject({ uvWorkspace })` preset.\n\nrelease-please parity: #2560."
4819
+ },
4820
+ "versionActions": {
4821
+ "type": "string",
4822
+ "description": "Built-in id (`\"npm\"`, `\"native-addon\"`, `\"private\"`, `\"shell\"`, `\"cargo\"`, `\"python\"`, `\"maven\"`, `\"container\"`, `\"jsr\"`) or a path to a custom implementation module."
4823
+ }
4824
+ },
4825
+ "additionalProperties": false
4826
+ },
4827
+ "ExtraFileRule": {
4828
+ "anyOf": [
4829
+ {
4830
+ "$ref": "#/$defs/ExtraFileAnnotationRule"
4831
+ },
4832
+ {
4833
+ "$ref": "#/$defs/ExtraFileRegexRule"
4834
+ }
4835
+ ],
4836
+ "description": "Union of every extra-files rule shape. The regex form is the historical default; the annotation form was added for release-please ergonomics.\n\nWhen `type` is omitted, the rule is treated as a regex rule (preserves backwards-compat for every existing vis.config.ts in the wild)."
4837
+ },
4838
+ "ExtraFileAnnotationRule": {
4839
+ "type": "object",
4840
+ "properties": {
4841
+ "anchor": {
4842
+ "type": "string",
4843
+ "description": "Limit the semver-replacement to occurrences anchored by this literal prefix on the marked line. Useful when the file has multiple version-shaped substrings (e.g. a lockfile or a Dockerfile referencing both APP_VERSION and a base-image tag).\n\nExample — `ENV APP_VERSION=\"0.1.0\"` with `anchor: \"APP_VERSION\"` only touches the version after that prefix. When omitted, the FIRST semver substring on the marked line is replaced.\n\n**Strongly recommended** for any file that contains more than one version-shaped substring (lockfiles, Dockerfiles with both APP and base-image tags, multi-version compose files). The default \"first semver wins\" behaviour is convenient for single-version files but a footgun on lockfiles — annotating a `package-lock .json` without an anchor would happily rewrite the first nested dep's `version`."
4844
+ },
4845
+ "marker": {
4846
+ "type": "string",
4847
+ "description": "Override the marker string. Default `\"x-release-please-version\"` (release-please compatibility). Match is plain substring (no regex), case-sensitive."
4848
+ },
4849
+ "path": {
4850
+ "type": "string",
4851
+ "description": "File path. Workspace-root-relative when declared on `release.publish.extraFiles`; package-directory-relative when on `release.packages.<name>.extraFiles`."
4852
+ },
4853
+ "type": {
4854
+ "type": "string",
4855
+ "const": "annotation",
4856
+ "description": "Switch to annotation-comment mode. The substitution engine looks for lines tagged with the configured marker — by default `x-release-please-version` (release-please compatibility). The marked line (or the line immediately following an own-line marker) has its semver-shaped substring replaced with the new version."
4857
+ }
4858
+ },
4859
+ "required": [
4860
+ "path",
4861
+ "type"
4862
+ ],
4863
+ "additionalProperties": false,
4864
+ "description": "Annotation-comment file-substitution rule — release-please parity.\n\nInstead of authoring a regex, the operator drops an `x-release-please- version` (or custom-named) marker comment in the target file and vis locates the semver-shaped substring on the marked line (or the line immediately following an own-line marker) and replaces it with the new version. Far more ergonomic than the regex form for the common case of \"bump this version string here\".\n\nTwo recognised placements:\n\n 1. **Inline** — marker on the same line as the version: ```ts export const VERSION = \"0.1.0\"; // x-release-please-version ```\n\n 2. **Preceding-line** — marker on the line just above the version: ```dockerfile # x-release-please-version ENV APP_VERSION=\"0.1.0\" ```\n\nLike the regex path, missing files / no marker found surface as `plan.warnings` rather than throwing."
4865
+ },
4866
+ "ExtraFileRegexRule": {
4867
+ "type": "object",
4868
+ "properties": {
4869
+ "flags": {
4870
+ "type": "string",
4871
+ "description": "Regex flags (default `\"g\"`). Combine as needed: `\"gm\"`, `\"gmi\"`, etc."
4872
+ },
4873
+ "path": {
4874
+ "type": "string",
4875
+ "description": "File path. Workspace-root-relative when declared on `release.publish.extraFiles`; package-directory-relative when on `release.packages.<name>.extraFiles`."
4876
+ },
4877
+ "replace": {
4878
+ "type": "string",
4879
+ "description": "Substitution template. `{version}` is replaced with the new version literal. Standard regex backreferences (`$1`, `$2`, `$&`) work too. When omitted, the entire match is replaced with the new version."
4880
+ },
4881
+ "search": {
4882
+ "type": "string",
4883
+ "description": "JavaScript regex source (without delimiters)."
4884
+ },
4885
+ "type": {
4886
+ "type": "string",
4887
+ "const": "regex",
4888
+ "description": "Explicit type discriminator. Defaults to `\"regex\"` when omitted — legacy rules without a `type` field continue to work as regex rules."
4889
+ }
4890
+ },
4891
+ "required": [
4892
+ "path",
4893
+ "search"
4894
+ ],
4895
+ "additionalProperties": false,
4896
+ "description": "Regex-based file-substitution rule used by `publish.extraFiles` (workspace) or `packages.<name>.extraFiles` (per-package) to keep version strings in non-package.json files in sync with the release."
4897
+ },
4898
+ "PublishConfig": {
4899
+ "type": "object",
4900
+ "properties": {
4901
+ "addReleases": {
4902
+ "type": [
4903
+ "boolean",
4904
+ "string"
4905
+ ],
4906
+ "enum": [
4907
+ false,
4908
+ "bottom",
4909
+ "top"
4910
+ ],
4911
+ "description": "Semantic-release/github parity — when set, prepend (\"top\") or append (\"bottom\") a \"Related releases\" block to the per-package GitHub release body that links to the immediately previous N releases of the same package. Aids navigation in the Releases UI (\"what did 1.4.2 fix?\" is a single click from 1.5.0's release page).\n\nHonoured only on the GitHub adapter; GitLab logs a warning and skips the block. Aggregate-release mode is skipped — there's no per-package prior release to point at.\n\nDefault `false` (no link block)."
4912
+ },
4913
+ "catalogResolution": {
4914
+ "$ref": "#/$defs/CatalogResolutionMode",
4915
+ "description": "How to resolve `catalog:` protocols."
4916
+ },
4917
+ "cleanPackageJson": {
4918
+ "anyOf": [
4919
+ {
4920
+ "type": "boolean"
4921
+ },
4922
+ {
4923
+ "$ref": "#/$defs/CleanPackageJsonConfig"
4924
+ }
4925
+ ],
4926
+ "description": "Strip/keep config for the published `package.json`. `false` ships unmodified."
4927
+ },
4928
+ "discussionCategory": {
4929
+ "type": "string",
4930
+ "description": "GitHub-only: link each created release to a Discussion in the named category (e.g. `\"Announcements\"`, `\"Releases\"`). The category must already exist on the repository; GitHub creates the discussion automatically. Ignored on GitLab."
4931
+ },
4932
+ "draftRelease": {
4933
+ "type": "boolean",
4934
+ "description": "Create the forge release (GitHub Release / GitLab Release) as a draft. A draft release is invisible to consumers until a human publishes it through the UI — useful when release notes need a human review before going public. Default `false`.\n\nMaps to GitHub's `draft: true` API field and GitLab's released_at being absent (GitLab models drafts implicitly via no released_at)."
4935
+ },
4936
+ "extraFiles": {
4937
+ "type": "array",
4938
+ "items": {
4939
+ "$ref": "#/$defs/ExtraFileRule"
4940
+ },
4941
+ "description": "Bump version strings in arbitrary files alongside package.json. Each rule's `path` is workspace-root-relative; per-package rules (under `packages.<name>.extraFiles`) resolve relative to the package directory.\n\nThe `search` is a JavaScript regex source. Default `flags: \"g\"` for global replacement. The `replace` template supports the `{version}` token and standard regex backreferences (`$1`, `$2`, `$&`, etc.). When `replace` is absent, the entire match is substituted with the new version.\n\nExamples — README badge, TS constant, Cargo.toml field: `{ path: \"README.md\", search: \"v\\\\d+\\\\.\\\\d+\\\\.\\\\d+\" }` `{ path: \"src/version.ts\", search: 'VERSION = \"[^\"]+\"', replace: 'VERSION = \"{version}\"' }` `{ path: \"Cargo.toml\", search: '^version = \"[^\"]+\"', replace: 'version = \"{version}\"', flags: \"m\" }`\n\nFailed matches are non-fatal — the publish carries on, but a warning surfaces so misconfigured rules don't silently rot."
4942
+ },
4943
+ "guards": {
4944
+ "$ref": "#/$defs/PublishGuardsConfig",
4945
+ "description": "Pre-publish security gates. Each gate is opt-in."
4946
+ },
4947
+ "noRelease": {
4948
+ "type": "boolean",
4949
+ "description": "Skip creating the GitHub / GitLab Release entirely while still pushing the git tag and publishing the package to the registry. Useful for teams that maintain release notes elsewhere (a docs site, in-product changelog, etc.) and don't want the duplicate forge artifact.\n\nDefault `false`. Release-please parity: #1295."
4950
+ },
4951
+ "packManager": {
4952
+ "$ref": "#/$defs/PackManager",
4953
+ "description": "Which manager to invoke for `<pm> pack`."
4954
+ },
4955
+ "preferStaticToken": {
4956
+ "type": "boolean",
4957
+ "description": "Auth-precedence escape hatch for the multi-language actions (cargo, python). Default `false`.\n\nDefault behaviour (false): when both an OIDC env signal (`ACTIONS_ID_TOKEN_REQUEST_URL`) AND a static token (`CARGO_REGISTRY_TOKEN` / `TWINE_PASSWORD`) are present, OIDC wins — an operator who enabled OIDC trusted publishing wants OIDC by default and a leftover token in the env shouldn't silently switch auth modes (M-3).\n\nSet `true` to flip the precedence: when both signals are present, the static token wins. Useful for operators migrating off OIDC, shadow-publishing during a cutover, or working around a temporary trusted-publishing outage at the registry."
4958
+ },
4959
+ "protocolResolution": {
4960
+ "$ref": "#/$defs/ProtocolResolutionMode",
4961
+ "description": "How to resolve `workspace:` protocols."
4962
+ },
4963
+ "publishArgs": {
4964
+ "type": "array",
4965
+ "items": {
4966
+ "type": "string"
4967
+ },
4968
+ "description": "Extra args appended to publish (`--provenance`, etc.). Skipped for managers that don't support them."
4969
+ },
4970
+ "publishStrategy": {
4971
+ "$ref": "#/$defs/PublishStrategy",
4972
+ "description": "Publish strategy — see RFC §11.3."
4973
+ },
4974
+ "registry": {
4975
+ "type": "string",
4976
+ "description": "Override default registry."
4977
+ },
4978
+ "releaseAssets": {
4979
+ "$ref": "#/$defs/ReleaseAssetsConfig",
4980
+ "description": "Post-publish asset attestation work."
4981
+ },
4982
+ "stage": {
4983
+ "anyOf": [
4984
+ {
4985
+ "type": "boolean"
4986
+ },
4987
+ {
4988
+ "type": "object",
4989
+ "properties": {
4990
+ "pollIntervalMs": {
4991
+ "type": "number",
4992
+ "description": "Sleep between consecutive `npm stage view` checks while waiting. Default: 15_000 (15 seconds)."
4993
+ },
4994
+ "timeoutMs": {
4995
+ "type": "number",
4996
+ "description": "Hard deadline before the wait gives up and skips the publish. Default: 1_800_000 (30 minutes)."
4997
+ }
4998
+ },
4999
+ "additionalProperties": false
5000
+ }
5001
+ ],
5002
+ "description": "Use npm's staged-publishing flow (`npm stage publish`) instead of `npm publish`. The published version is invisible to consumers until a maintainer approves it via 2FA (`vis release stage approve` or the npmjs.com web UI). Requires npm CLI ≥ 11.15.0 and `registry.npmjs.org` as the registry; doctor warns when those preconditions aren't met.\n\nPublish blocks on the human-review gate so downstream pipeline steps (tags, GH release, post-hooks) only run against actually-live packages. Rejection and timeout are NOT CI failures — they flow through the skipped[] result so `vis release publish` exits 0; the unapproved package just doesn't get its downstream side-effects.\n\nPass `true` for defaults (30-min timeout, 15s poll). Pass an object to override per-workspace. Snapshots always publish directly (preview content shouldn't gate on review)."
5003
+ }
5004
+ },
5005
+ "additionalProperties": false
5006
+ },
5007
+ "CatalogResolutionMode": {
5008
+ "type": "string",
5009
+ "enum": [
5010
+ "auto",
5011
+ "in-place",
5012
+ "delegate"
5013
+ ]
5014
+ },
5015
+ "CleanPackageJsonConfig": {
5016
+ "type": "object",
5017
+ "properties": {
5018
+ "keep": {
5019
+ "type": "array",
5020
+ "items": {
5021
+ "type": "string"
5022
+ },
5023
+ "description": "Fields to keep — overrides default strip behaviour."
5024
+ },
5025
+ "strip": {
5026
+ "type": "array",
5027
+ "items": {
5028
+ "type": "string"
5029
+ },
5030
+ "description": "Fields to strip from the published package.json (extends defaults)."
5031
+ }
5032
+ },
5033
+ "additionalProperties": false
5034
+ },
5035
+ "PublishGuardsConfig": {
5036
+ "type": "object",
5037
+ "properties": {
5038
+ "audit": {
5039
+ "type": "string",
5040
+ "enum": [
5041
+ "critical",
5042
+ "high",
5043
+ "low",
5044
+ "moderate",
5045
+ "off"
5046
+ ],
5047
+ "description": "Run `npm audit --omit=dev` against the resolved package and fail at the configured severity. Skips devDependency CVEs (which don't ship to consumers). `\"off\"` disables."
5048
+ },
5049
+ "exportsExist": {
5050
+ "type": "boolean",
5051
+ "description": "Verify every leaf path declared in `package.json#exports` / `main` / `module` / `types` / `bin` exists post-build. Wildcard exports (`./feat/*.js`) check that the directory is non-empty after build.\n\nCatches \"deleted file but forgot to update exports\" before publish."
5052
+ },
5053
+ "lifecycleScripts": {
5054
+ "anyOf": [
5055
+ {
5056
+ "type": "string",
5057
+ "const": "off"
5058
+ },
5059
+ {
5060
+ "type": "string",
5061
+ "const": "strict"
5062
+ },
5063
+ {
5064
+ "type": "string",
5065
+ "const": "warn"
5066
+ },
5067
+ {
5068
+ "type": "object",
5069
+ "properties": {
5070
+ "allow": {
5071
+ "type": "object",
5072
+ "additionalProperties": {
5073
+ "type": "string"
5074
+ }
5075
+ },
5076
+ "mode": {
5077
+ "type": "string",
5078
+ "enum": [
5079
+ "off",
5080
+ "strict",
5081
+ "warn"
5082
+ ]
5083
+ }
5084
+ },
5085
+ "required": [
5086
+ "mode"
5087
+ ],
5088
+ "additionalProperties": false
5089
+ }
5090
+ ],
5091
+ "description": "Gate on lifecycle scripts (`preinstall` / `install` / `postinstall`) declared on the package being published. These run on the consumer's machine at install time, so unauthorized additions are a supply-chain vector.\n\nModes: `\"off\"` (skip), `\"warn\"` (log + continue), `\"strict\"` (fail). Object form provides an exact-match `allow` table — only commands matching the listed value pass through."
5092
+ },
5093
+ "packSecretScan": {
5094
+ "anyOf": [
5095
+ {
5096
+ "type": "boolean"
5097
+ },
5098
+ {
5099
+ "type": "object",
5100
+ "properties": {
5101
+ "ignore": {
5102
+ "type": "array",
5103
+ "items": {
5104
+ "type": "string"
5105
+ }
5106
+ }
5107
+ },
5108
+ "additionalProperties": false
5109
+ }
5110
+ ],
5111
+ "description": "Scan the resolved tarball contents (post `npm pack`) for secrets. Catches `.npmignore`/`files` misconfigurations that would ship `.env`, AWS keys, etc. Different scope than log redaction — this gates what actually leaves the machine.\n\n`true` runs the default `@visulima/secret-scanner` ruleset. Object form lets callers narrow the rule set or skip files."
5112
+ }
5113
+ },
5114
+ "additionalProperties": false,
5115
+ "description": "Pre-publish security gates — run after the manifest is rewritten and the tarball is packed but BEFORE `npm publish` is invoked. Each gate is opt-in; defaults aim for \"useful for new repos, easy to disable for established ones\"."
5116
+ },
5117
+ "PackManager": {
5118
+ "type": "string",
5119
+ "enum": [
5120
+ "auto",
5121
+ "npm",
5122
+ "pnpm",
5123
+ "yarn",
5124
+ "bun"
5125
+ ]
5126
+ },
5127
+ "ProtocolResolutionMode": {
5128
+ "type": "string",
5129
+ "enum": [
5130
+ "pack",
5131
+ "in-place",
5132
+ "none"
5133
+ ]
5134
+ },
5135
+ "PublishStrategy": {
5136
+ "type": "string",
5137
+ "enum": [
5138
+ "npm-publish-tarball",
5139
+ "native"
5140
+ ]
5141
+ },
5142
+ "ReleaseAssetsConfig": {
5143
+ "type": "object",
5144
+ "properties": {
5145
+ "stampHashes": {
5146
+ "type": "boolean",
5147
+ "description": "Compute SHA256 + SHA512 of the published tarball and append them to the release body. Lets consumers verify the registry tarball matches the audited build, defending against post-publish substitution."
5148
+ },
5149
+ "uploadTarball": {
5150
+ "type": "boolean",
5151
+ "description": "Upload the published tarball as a release asset alongside the GH release. Belt-and-suspenders alongside `stampHashes` — registry tampering is detectable by hash comparison."
5152
+ }
5153
+ },
5154
+ "additionalProperties": false
5155
+ },
5156
+ "SnapshotConfig": {
5157
+ "type": "object",
5158
+ "properties": {
5159
+ "backend": {
5160
+ "$ref": "#/$defs/SnapshotBackend"
5161
+ },
5162
+ "cleanupOnPrClose": {
5163
+ "type": "boolean",
5164
+ "description": "Whether to delete published snapshots on PR-close (no-op for `pkg-pr-new`)."
5165
+ },
5166
+ "registry": {
5167
+ "type": "string",
5168
+ "description": "When backend is `pkg-pr-new`, the registry URL is supplied automatically."
5169
+ },
5170
+ "tags": {
5171
+ "type": "array",
5172
+ "items": {
5173
+ "$ref": "#/$defs/SnapshotTagKind"
5174
+ },
5175
+ "description": "Multi-tag publish — pick which tag types to emit per snapshot."
5176
+ },
5177
+ "versionTemplate": {
5178
+ "type": "string",
5179
+ "description": "Version template — interpolation tokens: `{tag}`, `{shortSha}`, `{sha}`, `{branch}`, `{pr}`, `{timestamp}`."
5180
+ }
5181
+ },
5182
+ "additionalProperties": false
5183
+ },
5184
+ "SnapshotBackend": {
5185
+ "anyOf": [
5186
+ {
5187
+ "type": "string",
5188
+ "const": "pkg-pr-new"
5189
+ },
5190
+ {
5191
+ "type": "string",
5192
+ "const": "registry"
5193
+ },
5194
+ {
5195
+ "type": "object",
5196
+ "properties": {
5197
+ "auth": {
5198
+ "type": "string"
5199
+ },
5200
+ "url": {
5201
+ "type": "string"
5202
+ }
5203
+ },
5204
+ "required": [
5205
+ "url"
5206
+ ],
5207
+ "additionalProperties": false
5208
+ }
5209
+ ]
5210
+ },
5211
+ "SnapshotTagKind": {
5212
+ "type": "string",
5213
+ "enum": [
5214
+ "sha",
5215
+ "short-sha",
5216
+ "branch",
5217
+ "pr"
5218
+ ]
5219
+ },
5220
+ "SuccessWalkConfig": {
5221
+ "type": "object",
5222
+ "properties": {
5223
+ "commentBody": {
5224
+ "type": "string",
5225
+ "description": "Comment body template posted on every referenced PR / issue. Tokens: - `{version}` — the published version (e.g. `1.2.0`) - `{name}` — the published package name - `{tag}` — the git tag created for this release - `{url}` — the forge release URL when available\n\nDefault mirrors semantic-release's `successComment`."
5226
+ },
5227
+ "enabled": {
5228
+ "type": "boolean",
5229
+ "description": "Enable the walk. Default `true` when `successWalk` is present in the config. Setting `enabled: false` is functionally equivalent to omitting `successWalk` entirely (no walk runs) — the difference is one of intent: an explicit `enabled: false` documents that the operator has considered the walk and disabled it.\n\nLeaving `successWalk` undefined at the top level is the recommended \"off\" stance — see the interface docstring."
5230
+ },
5231
+ "labels": {
5232
+ "type": "array",
5233
+ "items": {
5234
+ "type": "string"
5235
+ },
5236
+ "description": "Labels added to every walked PR / issue. Default `[\"released\"]`."
5237
+ },
5238
+ "skipPrerelease": {
5239
+ "type": "boolean",
5240
+ "description": "Skip the walk entirely on prerelease channels — the typical \"don't notify users their PR shipped in a beta\" guardrail. Default `true`."
5241
+ }
5242
+ },
5243
+ "additionalProperties": false,
5244
+ "description": "Post-release notification walk — semantic-release parity.\n\n**Default OFF.** Set `release.successWalk: {}` to opt in with defaults. Leaving `successWalk` undefined in the workspace config is the explicit \"don't touch third-party PRs\" stance — sticky comments and the `released` label are an irreversible side effect on every PR mentioned in a changelog body, so we never apply them implicitly.\n\nWhen opted in, after a successful publish wave vis walks every PR / issue referenced in the rendered changelog entries and: 1. Posts (or upserts) a sticky comment announcing the release version. 2. Adds the configured labels (default `[\"released\"]`).\n\nFailure to walk a single ref is non-fatal — the publish itself already succeeded; we don't want a forge API blip rolling that back."
5245
+ },
5246
+ "UpdateInternalDependenciesMode": {
5247
+ "type": "string",
5248
+ "enum": [
5249
+ "patch",
5250
+ "minor",
5251
+ "out-of-range"
5252
+ ]
5253
+ },
5254
+ "VersionPrConfig": {
5255
+ "type": "object",
5256
+ "properties": {
5257
+ "assignees": {
5258
+ "type": "array",
5259
+ "items": {
5260
+ "type": "string"
5261
+ },
5262
+ "description": "Auto-assign these users (logins) as the PR assignees on creation. Existing assignees are preserved; this only adds. Defaults to unassigned."
5263
+ },
5264
+ "autoMerge": {
5265
+ "type": "boolean",
5266
+ "description": "Enable GitHub's auto-merge once status checks pass. Maps to `gh pr merge --auto`. Requires the repo to have auto-merge enabled in settings. Default `false`."
5267
+ },
5268
+ "autoMergeMethod": {
5269
+ "type": "string",
5270
+ "enum": [
5271
+ "merge",
5272
+ "rebase",
5273
+ "squash"
5274
+ ],
5275
+ "description": "Merge strategy for auto-merge — defaults to `\"squash\"`. Honoured only when `autoMerge: true`."
5276
+ },
5277
+ "autoRebase": {
5278
+ "type": "boolean",
5279
+ "description": "Periodically rebase the version-PR branch on top of `base` so the PR doesn't drift behind. Default `false`. Enable when the version-PR sits open for long periods and conflicts with other PRs are likely. The actual rebase runs via `vis release ci rebase-pr` (which the CI workflow can schedule on a cron)."
5280
+ },
5281
+ "branch": {
5282
+ "type": "string"
5283
+ },
5284
+ "commentMarker": {
5285
+ "type": "string",
5286
+ "description": "Sentinel comment marker for sticky-update detection."
5287
+ },
5288
+ "labels": {
5289
+ "type": "array",
5290
+ "items": {
5291
+ "type": "string"
5292
+ },
5293
+ "description": "Labels applied to the version-PR. Defaults to `[\"autorelease: pending\"]`. Set to `[]` to disable. The label is added on every PR refresh — external automation can rely on it being present until the lifecycle moves on (`autorelease: tagged` post-publish, etc.)."
5294
+ },
5295
+ "preamble": {
5296
+ "type": "string",
5297
+ "description": "Markdown prepended to the PR body."
5298
+ },
5299
+ "reviewers": {
5300
+ "type": "array",
5301
+ "items": {
5302
+ "type": "string"
5303
+ },
5304
+ "description": "Auto-request reviews from these users / teams on PR creation. Format: GitHub usernames or `org/team`. Existing reviewers are preserved."
5305
+ },
5306
+ "title": {
5307
+ "type": "string"
5308
+ }
5309
+ },
5310
+ "additionalProperties": false
5311
+ },
3924
5312
  "ScopedTasksBlock": {
3925
5313
  "type": "object",
3926
5314
  "properties": {