@savvy-web/silk-effects 7.2.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -181,6 +181,7 @@ The Silk husky hooks are data. `SavvySections` supplies the section identities a
181
181
 
182
182
  - `SavvyBaseSection` is the shared preamble's identity (key `SAVVY-BASE`); pair it with `savvyBasePreamble()`, which defines `ROOT`, the `in_ci` predicate, `PM` via package-manager detection and `pm_exec`.
183
183
  - `SavvyHooksSection` (key `SAVVY-HOOKS`) pairs with `savvyHooksHygiene()`, a self-guarded repo-hygiene block that runs outside CI.
184
+ - `SavvyToolchainSection` (key `SAVVY-TOOLCHAIN`) pairs with `savvyToolchainCheck()`, a self-guarded block that warns when the running package manager has drifted off the repo's `devEngines.packageManager` pin. Warn only — it never blocks and never installs anything. It is self-contained (its hooks carry no `savvy-base` preamble), honours the manager named in the pin rather than assuming pnpm, strips the `+sha512…` integrity tail, skips inexact pins, and says nothing under CI.
184
185
  - `savvyToolSection(toolName, command)` builds a consumer's one-line tool section whose content is exactly `in_ci || pm_exec <command>` — the command is appended verbatim, so shell tokens like `$ROOT` and `$1` survive into the output. A `savvy-base` section must come first in the same hook file, so pass both to `syncAll` in that order.
185
186
 
186
187
  ```typescript
package/index.d.ts CHANGED
@@ -9913,6 +9913,43 @@ declare function savvyHooksHygiene(): string;
9913
9913
  * @public
9914
9914
  */
9915
9915
  declare function savvyToolSection(toolName: string, command: string): Section;
9916
+ /**
9917
+ * Section identity for the package-manager toolchain drift check.
9918
+ *
9919
+ * `toolName` is `"savvy-toolchain"`; pair with {@link savvyToolchainCheck}.
9920
+ *
9921
+ * @since 7.3.0
9922
+ * @public
9923
+ */
9924
+ declare const SavvyToolchainSection: SectionId;
9925
+ /**
9926
+ * Package-manager drift check shared across Silk Suite hook files.
9927
+ *
9928
+ * @remarks
9929
+ * Compares the running package manager's version against the repo's
9930
+ * `devEngines.packageManager` pin and prints a warning on mismatch. **Warn only** —
9931
+ * it never blocks the hook and never installs anything, so nobody mid-bisect or
9932
+ * mid-rebase on an older pin is stranded.
9933
+ *
9934
+ * Deliberately self-contained: its homes are `.husky/post-checkout` and
9935
+ * `.husky/post-merge`, which carry {@link SavvyHooksSection} but no
9936
+ * {@link SavvyBaseSection}, so it defines its own root/CI/pin lookups rather than
9937
+ * depending on `ROOT`, `in_ci` or `PM`. It honours the `name` recorded in the pin
9938
+ * rather than assuming pnpm.
9939
+ *
9940
+ * Every input is treated as optional: no `git` root, no `jq`, no `devEngines` block,
9941
+ * or a package manager that is not on `PATH` all mean "say nothing". Only an exact
9942
+ * pin is comparable, so ranges (`^1.2.3`, `>=1 || <2`) and wildcards (`1.x`) are
9943
+ * skipped, and the `+sha512…` integrity tail `devEngines` versions routinely carry is
9944
+ * stripped before comparison. Skipped under CI, where the runtime action installs the
9945
+ * pin by construction.
9946
+ *
9947
+ * @returns The drift-check shell, with no surrounding markers or trailing newline.
9948
+ *
9949
+ * @since 7.3.0
9950
+ * @public
9951
+ */
9952
+ declare function savvyToolchainCheck(): string;
9916
9953
  //#endregion
9917
9954
  //#region src/schemas/WorkspaceAnalysisSchemas.d.ts
9918
9955
  declare const SilkPublishConfig_base: Schema.Class<SilkPublishConfig, Schema.Struct<{
@@ -10848,5 +10885,5 @@ declare namespace index_d_exports$5 {
10848
10885
  export { AffectedResult, AffectedResultType, CacheDiagnosis, CacheDiagnosisType, DryRunParseError, GlobalHashSummary, GraphNode, MissExplanation, NotATurboRepoError, PackageCacheStatus, TaskGraphResult, TaskGraphResultType, TurboCache, TurboDigest, TurboDryRun, TurboDryRunType, TurboDryTask, TurboDryTaskType, TurboEnvVars, TurboError, TurboExecError, TurboGlobalCacheInputs, TurboInspector, TurboInspectorShape, TurboNotInstalledError };
10849
10886
  }
10850
10887
  //#endregion
10851
- export { AnalyzedWorkspace, BiomeSchemaSync, type BiomeSchemaSyncShape, BiomeSyncError, type BiomeSyncOptions, type BiomeSyncResult, ChangesetConfig, ChangesetConfigError, type ChangesetConfigFile, ChangesetConfigReader, type ChangesetConfigReaderShape, type ChangesetConfigShape, type ChangesetMode, index_d_exports as Changesets, index_d_exports$1 as Commitlint, type CommitlintPlugin, type CommitlintUserConfig, ConfigDiscovery, type ConfigDiscoveryOptions, type ConfigDiscoveryShape, type ConfigLocation, ConfigNotFoundError, type ConfigSource, index_d_exports$2 as Lint, index_d_exports$3 as PrBody, type PromptConfig, type PromptSettings, PublishTargetBindingError, type PublishablePackage, type RawPackageJson, type RawPublishConfig, type RawPublishTargets, type RawTargetObject, type RawTargetValue, index_d_exports$4 as Repos, type RuleApplicability, type RuleConfigTuple, type RuleSeverity, type RulesConfig, SavvyBaseSection, SavvyHooksSection, type SilkChangesetConfigFile, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, type SilkWorkspaceAnalyzerShape, type TargetBinding, type TargetGroupBinding, type TargetsBinding, index_d_exports$5 as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
10888
+ export { AnalyzedWorkspace, BiomeSchemaSync, type BiomeSchemaSyncShape, BiomeSyncError, type BiomeSyncOptions, type BiomeSyncResult, ChangesetConfig, ChangesetConfigError, type ChangesetConfigFile, ChangesetConfigReader, type ChangesetConfigReaderShape, type ChangesetConfigShape, type ChangesetMode, index_d_exports as Changesets, index_d_exports$1 as Commitlint, type CommitlintPlugin, type CommitlintUserConfig, ConfigDiscovery, type ConfigDiscoveryOptions, type ConfigDiscoveryShape, type ConfigLocation, ConfigNotFoundError, type ConfigSource, index_d_exports$2 as Lint, index_d_exports$3 as PrBody, type PromptConfig, type PromptSettings, PublishTargetBindingError, type PublishablePackage, type RawPackageJson, type RawPublishConfig, type RawPublishTargets, type RawTargetObject, type RawTargetValue, index_d_exports$4 as Repos, type RuleApplicability, type RuleConfigTuple, type RuleSeverity, type RulesConfig, SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, type SilkChangesetConfigFile, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, type SilkWorkspaceAnalyzerShape, type TargetBinding, type TargetGroupBinding, type TargetsBinding, index_d_exports$5 as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection, savvyToolchainCheck };
10852
10889
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SavvyBaseSection, SavvyHooksSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection } from "./schemas/SavvySections.js";
1
+ import { SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection, savvyToolchainCheck } from "./schemas/SavvySections.js";
2
2
  import { ChangesetConfigError } from "./errors/ChangesetConfigError.js";
3
3
  import { ChangesetConfigReader } from "./services/ChangesetConfigReader.js";
4
4
  import { PublishTargetBindingError } from "./errors/PublishTargetBindingError.js";
@@ -18,4 +18,4 @@ import { ConfigDiscovery } from "./services/ConfigDiscovery.js";
18
18
  import { SilkWorkspaceAnalyzer } from "./services/SilkWorkspaceAnalyzer.js";
19
19
  import { turbo_exports } from "./turbo/index.js";
20
20
 
21
- export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigReader, changesets_exports as Changesets, commitlint_exports as Commitlint, ConfigDiscovery, ConfigNotFoundError, lint_exports as Lint, pr_body_exports as PrBody, PublishTargetBindingError, repos_exports as Repos, SavvyBaseSection, SavvyHooksSection, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, turbo_exports as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
21
+ export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigReader, changesets_exports as Changesets, commitlint_exports as Commitlint, ConfigDiscovery, ConfigNotFoundError, lint_exports as Lint, pr_body_exports as PrBody, PublishTargetBindingError, repos_exports as Repos, SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, turbo_exports as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection, savvyToolchainCheck };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/silk-effects",
3
- "version": "7.2.0",
3
+ "version": "7.3.0",
4
4
  "private": false,
5
5
  "description": "Shared Effect library for Silk Suite conventions",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
@@ -130,6 +130,65 @@ fi`;
130
130
  function savvyToolSection(toolName, command) {
131
131
  return shellSection(toolName).section(`in_ci || pm_exec ${command}`);
132
132
  }
133
+ /**
134
+ * Section identity for the package-manager toolchain drift check.
135
+ *
136
+ * `toolName` is `"savvy-toolchain"`; pair with {@link savvyToolchainCheck}.
137
+ *
138
+ * @since 7.3.0
139
+ * @public
140
+ */
141
+ const SavvyToolchainSection = shellSection("savvy-toolchain");
142
+ /**
143
+ * Package-manager drift check shared across Silk Suite hook files.
144
+ *
145
+ * @remarks
146
+ * Compares the running package manager's version against the repo's
147
+ * `devEngines.packageManager` pin and prints a warning on mismatch. **Warn only** —
148
+ * it never blocks the hook and never installs anything, so nobody mid-bisect or
149
+ * mid-rebase on an older pin is stranded.
150
+ *
151
+ * Deliberately self-contained: its homes are `.husky/post-checkout` and
152
+ * `.husky/post-merge`, which carry {@link SavvyHooksSection} but no
153
+ * {@link SavvyBaseSection}, so it defines its own root/CI/pin lookups rather than
154
+ * depending on `ROOT`, `in_ci` or `PM`. It honours the `name` recorded in the pin
155
+ * rather than assuming pnpm.
156
+ *
157
+ * Every input is treated as optional: no `git` root, no `jq`, no `devEngines` block,
158
+ * or a package manager that is not on `PATH` all mean "say nothing". Only an exact
159
+ * pin is comparable, so ranges (`^1.2.3`, `>=1 || <2`) and wildcards (`1.x`) are
160
+ * skipped, and the `+sha512…` integrity tail `devEngines` versions routinely carry is
161
+ * stripped before comparison. Skipped under CI, where the runtime action installs the
162
+ * pin by construction.
163
+ *
164
+ * @returns The drift-check shell, with no surrounding markers or trailing newline.
165
+ *
166
+ * @since 7.3.0
167
+ * @public
168
+ */
169
+ function savvyToolchainCheck() {
170
+ return `if ! { [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ]; }; then
171
+ toolchain_root=$(git rev-parse --show-toplevel 2>/dev/null)
172
+ toolchain_pm=""
173
+ toolchain_pin=""
174
+ if [ -n "$toolchain_root" ] && [ -f "$toolchain_root/package.json" ] && command -v jq >/dev/null 2>&1; then
175
+ toolchain_pm=$(jq -r '.devEngines.packageManager.name // empty' "$toolchain_root/package.json" 2>/dev/null)
176
+ toolchain_pin=$(jq -r '.devEngines.packageManager.version // empty' "$toolchain_root/package.json" 2>/dev/null | cut -d'+' -f1)
177
+ fi
178
+ # Only an exact pin is comparable: drop ranges (^ ~ >= ||) and wildcards (x, *).
179
+ case "$toolchain_pin" in ""|[!0-9]*|*[!0-9A-Za-z.-]*|*x*|*X*) toolchain_pin="" ;; esac
180
+ if [ -n "$toolchain_pm" ] && [ -n "$toolchain_pin" ] && command -v "$toolchain_pm" >/dev/null 2>&1; then
181
+ toolchain_have=$("$toolchain_pm" --version 2>/dev/null | head -n 1 | tr -d '[:space:]')
182
+ # A manager that failed or answered with prose says nothing about drift.
183
+ case "$toolchain_have" in [!0-9]*|*[!0-9A-Za-z.-]*) toolchain_have="" ;; esac
184
+ if [ -n "$toolchain_have" ] && [ "$toolchain_have" != "$toolchain_pin" ]; then
185
+ printf '⚠ %s %s does not match %s, the version pinned in devEngines.packageManager.\\n' "$toolchain_pm" "$toolchain_have" "$toolchain_pin" >&2
186
+ printf ' Lockfiles written by this version may differ from CI. Fix: corepack use %s@%s\\n' "$toolchain_pm" "$toolchain_pin" >&2
187
+ fi
188
+ fi
189
+ unset toolchain_root toolchain_pm toolchain_pin toolchain_have
190
+ fi`;
191
+ }
133
192
 
134
193
  //#endregion
135
- export { SavvyBaseSection, SavvyHooksSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
194
+ export { SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection, savvyToolchainCheck };