Skip to content

Allow workspace packages to omit version field - #171

Open
exo-nikita wants to merge 1 commit into
mainfrom
claude/local-package-version-optional-fegqhs
Open

Allow workspace packages to omit version field#171
exo-nikita wants to merge 1 commit into
mainfrom
claude/local-package-version-optional-fegqhs

Conversation

@exo-nikita

Copy link
Copy Markdown
Collaborator

Summary

This change enables stasis to handle workspace packages that omit the version field, which is common for private/unpublished packages. The version field is now optional for packages outside node_modules, while remaining required for packages within node_modules.

Key Changes

  • bundle-util.js: Updated findPackageMetadata() to accept workspace packages with only a name field (no version required), while still requiring both name and version for node_modules packages.

  • state.js: Modified package resolution logic to allow workspace packages to claim buckets with just a name, without requiring a version. The assertion message was updated to reflect this change.

  • bundle.js: Relaxed the assertion when parsing bundle metadata to allow workspace buckets without a version field, while still requiring name and files.

  • Test fixtures: Added test fixtures for edge cases:

    • partial/ - workspace package with name but no version
    • unnamed/ - workspace package with no name (should fail)
    • node_modules/noversion/ - node_modules package without version (should fail)
  • New comprehensive test suite (state-versionless-workspace.test.js): Added 7 tests covering:

    • Lockfile round-tripping of version-less buckets
    • Bundle serialization and deserialization
    • Frozen state reload with version-less packages
    • Bundle absorption without a lockfile
    • Version drift detection (still fails closed)
    • Package metadata discovery behavior
    • stasis add command handling
  • Updated existing tests (state-nested-pkg.test.js): Modified tests to reflect the new behavior and added tests for the stricter node_modules requirements.

Implementation Details

The key distinction is that workspace packages (outside node_modules) can now use just the name field to claim a bucket, matching how State#locateModule identifies packages. This allows private/unpublished workspace packages to work seamlessly through the entire artifact round-trip (lockfile → bundle → reload). However, packages within node_modules still require both name and version to maintain strict identity verification and prevent accidental bucket collisions.

https://claude.ai/code/session_013KtXt8ccBU9WLHNKe1CEkp

A package defined in the local workspace outside node_modules (private/
unpublished) may legitimately lack a version in its package.json, but
State#locateModule required name+version on the walk up from the closest
manifest, so such a package tripped the pure-type-marker assert. Its
name alone now claims the bucket, with version left undefined;
node_modules buckets still require both.

Kept consistent across the toolchain:
- findPackageMetadata (stasis add / stasis bundle) stops at the same
  named manifest outside node_modules, so static and runtime bucketing
  agree instead of splitting the same file across different buckets.
- Bundle.parse accepts a version-less workspace sources bucket (the
  serializer already omitted the undefined field).
- The no-lockfile bundle absorb seeds a version-less workspace bucket's
  identity; v0 partial metadata (nameless buckets, version-less
  node_modules buckets) stays skipped.

Lockfile serialize/parse, diff, sbom, audit, why and prune already
tolerate a missing version.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013KtXt8ccBU9WLHNKe1CEkp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants