feat: mirror pnpm release-age gate in npm and workspaces, type compiler options encode#139
Conversation
…er options encode - ReleaseAgeGate and PartialReleaseAgeGate in @effected/npm: strictest-wins combine, pnpm-parity flat star exclude matching, pure publish-age version filtering with a caller clock. - ConfigDependencyHooks.inject now returns HookInjection so one hook replay yields catalogs and release-age keys; WorkspaceCatalogs gains releaseAgeGate assembling the effective gate strictest-wins. - TsEnumCodec.encodeCompilerOptions returns the new structural ProgrammaticCompilerOptions type so consumers drop their casts. - Changesets: @effected/npm 0.3.0, @effected/workspaces 0.6.0, @effected/tsconfig-json 0.3.0. Closes #120 Signed-off-by: C. Spencer Beggs <spencer@beggs.codes>
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR adds pnpm release-age gate modeling, hook replay integration, and WorkspaceCatalogs exposure. It also gives ChangesRelease-age gate integration
Typed compiler-options encoding
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant WorkspaceCatalogs
participant WorkspaceManifest
participant ConfigDependencyHooks
participant ReleaseAgeGate
WorkspaceCatalogs->>WorkspaceManifest: decode inline release-age keys
WorkspaceCatalogs->>ConfigDependencyHooks: replay hooks
ConfigDependencyHooks-->>WorkspaceCatalogs: return catalogs and releaseAge
WorkspaceCatalogs->>ReleaseAgeGate: combine inline and hook contributions
ReleaseAgeGate-->>WorkspaceCatalogs: return effective gate
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/npm/CLAUDE.md`:
- Line 29: Update the ReleaseAgeGate documentation to refer to its public
ageMinutes field instead of minReleaseAge, including the description of the
Schema.Class shape. Keep the existing combine, matchesExclude, isExcluded, and
filterVersions behavior descriptions unchanged.
In `@packages/npm/src/ReleaseAgeGate.ts`:
- Around line 64-72: Replace the RegExp-based wildcard handling in
matchesPattern with a linear-time matcher that processes the pattern and name
without backtracking, while preserving exact matches, * wildcard semantics, and
full-string matching.
In `@packages/workspaces/src/WorkspaceCatalogs.ts`:
- Around line 248-253: Update the Schema.decodeUnknownEffect pipeline’s
SchemaError handler to recover with a failed Effect containing
CatalogAssemblyError, using Effect.fail around the existing error construction.
Preserve the current source, path, and cause values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: f1aa4393-0dce-43c9-bc1f-e724c80b6fa1
⛔ Files ignored due to path filters (7)
.changeset/programmatic-compiler-options.mdis excluded by!.changeset/**.changeset/release-age-gate-assembly.mdis excluded by!.changeset/**.changeset/release-age-gate-vocabulary.mdis excluded by!.changeset/**.claude/design/effected/packages/npm.mdis excluded by!.claude/**.claude/design/effected/packages/tsconfig-json.mdis excluded by!.claude/**.claude/design/effected/packages/workspaces.mdis excluded by!.claude/**.claude/design/refs.jsonis excluded by!.claude/**
📒 Files selected for processing (20)
packages/npm/CLAUDE.mdpackages/npm/README.mdpackages/npm/__test__/ReleaseAgeGate.test.tspackages/npm/src/ReleaseAgeGate.tspackages/npm/src/index.tspackages/tsconfig-json/CLAUDE.mdpackages/tsconfig-json/README.mdpackages/tsconfig-json/__test__/TsEnumCodec.assignability.test.tspackages/tsconfig-json/src/TsEnumCodec.tspackages/tsconfig-json/src/index.tspackages/workspaces/CLAUDE.mdpackages/workspaces/README.mdpackages/workspaces/__test__/WorkspaceCatalogs.test.tspackages/workspaces/__test__/fixtures/hook-pnpmfile-age-1440.mjspackages/workspaces/__test__/fixtures/hook-pnpmfile-age-4320.mjspackages/workspaces/__test__/fixtures/hook-pnpmfile-age-garbage.mjspackages/workspaces/__test__/integration/ConfigDependencyHooks.int.test.tspackages/workspaces/src/ConfigDependencyHooks.tspackages/workspaces/src/WorkspaceCatalogs.tspackages/workspaces/src/index.ts
This comment has been minimized.
This comment has been minimized.
- Replace the exclude matcher's star-to-regex compilation with a linear two-pointer wildcard scan so a config-supplied pattern cannot trigger catastrophic regex backtracking; matching semantics unchanged. - Correct the npm package context file to name the real ageMinutes field. Signed-off-by: C. Spencer Beggs <spencer@beggs.codes>
Mirrors pnpm's release-age gate (
minimumReleaseAge/minimumReleaseAgeExclude) in the kit and types the tsconfig-json programmatic encode boundary.@effected/npm—ReleaseAgeGate(minor → 0.3.0)Schema-first release-age vocabulary, ported from the rolldown-pnpm-config reference by redesign:
ReleaseAgeGate(Schema.Class) withcombine(variadic, total, strictest-wins, exclude union) andmatchesExclude(flat-string*with@pnpm/matcherparity — deliberately not@effected/glob's dialect, divergence documented), plus instanceisExcluded/filterVersions(pure, caller-supplied clock; missing/unparseable publish timestamps dropped).PartialReleaseAgeGateis the permissive contribution schema;combineis the single clamping authority. 99/99 tests, zero-warning prod build.@effected/workspaces— release-age surfacing (minor → 0.6.0, breaking)ConfigDependencyHooks.injectnow returnsHookInjection { catalogs, releaseAge }— one hook replay yields both catalogs and the release-age keys the hooks already produced (previously discarded); keys thread last-hook-wins exactly as pnpm replays them.WorkspaceCatalogs.releaseAgeGate()assembles the effective gate from inlinepnpm-workspace.yamlvalues + hook contributions, strictest-wins, folded into the existing single memoized assembly pass; malformed inline values fail typed (CatalogAssemblyError,manifestsource). 273/273 tests, zero-warning prod build.@effected/tsconfig-json—ProgrammaticCompilerOptions(minor → 0.3.0)TsEnumCodec.encodeCompilerOptionsreturns the new exported structuralProgrammaticCompilerOptionsinstead ofRecord<string, unknown>— assignable tots.CompilerOptionswith no cast, transcribed from typescript 6.0.3'sCompilerOptionsValuewith the package's zero-typescript-imports rule intact, proven by a compile-time assignability test. Runtime unchanged. 158/158 tests.Closes #120
Context
Driven by the savvy-web-systems dogfood loop relaying
silk-update-action'sERR_PNPM_NO_MATURE_MATCHING_VERSIONfix; downstream adopted via local overrides and confirmed all surfaces (535/535 tests on their side) before this PR. Registry version collision (npm 0.2.3 / workspaces 0.5.2 already published) is resolved by the changesets above.Signed-off-by: C. Spencer Beggs spencer@beggs.codes
Adds pnpm-compatible release-age gating across
@effected/npmand@effected/workspaces, including exclusion matching, version filtering, schema validation, hook replay, and workspace gate composition.Exports structural
ProgrammaticCompilerOptionstypes from@effected/tsconfig-json, allowing encoded compiler options to be assigned to TypeScript compiler options without casts while preserving runtime behavior.