feat(add): linkWorkspacePackages + saveWorkspaceProtocol#539
Conversation
Two new workspace settings on `aube add`, matching pnpm's CLI: - `linkWorkspacePackages` (bool, default false): when true, `aube add <name>` prefers a local workspace sibling over the registry. The packument fetch is skipped, the manifest specifier is built from `saveWorkspaceProtocol`, and the resolver picks up the local copy on the next install (existing aube behavior on bare semver ranges). - `saveWorkspaceProtocol` (`"true" | "false" | "rolling"`, default `"rolling"`): controls the spec form written to package.json. `rolling` writes `workspace:^` (no version), `true` writes `workspace:^<version>`, `false` writes `^<version>`. The `--save-workspace-protocol` / `--no-save-workspace-protocol` CLI flags override per-invocation. `update_manifest_for_add` now reads its settings from the workspace yaml root rather than the immediate project dir so a sub-project's add picks up the workspace-wide policy. Closes the workspace-protocol gap for the monorepo/index.ts batch-2 ports. Bats coverage at `test/pnpm_monorepo_index.bats`: - monorepo/index.ts:112 (default save-workspace-protocol) - monorepo/index.ts:156 (`saveWorkspaceProtocol: rolling`) - regression guard for `saveWorkspaceProtocol: true` (no pnpm equivalent; the three protocol variants share one code path) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR closes the workspace-protocol gap for
Confidence Score: 5/5The workspace-linking logic is well-guarded against tricky edge cases and the manifest-write branching is correct across all three saveWorkspaceProtocol variants. Both defects identified in the previous review round are demonstrably fixed in this diff. The eligibility guards, version-satisfies check, spec-form selection, and per-invocation override all behave correctly under the scenarios tested and the edge cases examined during review. The bats suite provides concrete regression coverage for every code path including the aliased-spec and version-mismatch cases. No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "fix(add): validate range against sibling..." | Re-trigger Greptile |
- Skip aliased specs in the linkWorkspacePackages eligibility block. `workspace:` resolves by manifest key, so writing `"my-alias": "workspace:^"` would point the resolver at a sibling named `my-alias` (which doesn't exist) and 404 on the registry fallback. Aliased specs now fall through to the registry path. Regression-guarded by a new bats test. - Split the `aube add` settings context so `tag` / `savePrefix` / `catalogMode` keep reading from the project's own dir (`load_npmrc_entries` doesn't walk up, so a sub-project's `.npmrc` would have been silently dropped after the previous workspace-root switch). Only `linkWorkspacePackages` and `saveWorkspaceProtocol` now read from the workspace yaml root. - DRY up the `workspace_protocol_override` tri-state: extract a single `workspace_protocol_override_from_flags(save, no_save)` helper and call it from both `run()` and `AddManifestOptions::from_args`. - Add `linkWorkspacePackages` and `saveWorkspaceProtocol` as typed fields on `WorkspaceConfig` so `meta::workspace_yaml_keys_deserialize_onto_workspace_config` passes (Linux + Windows CI). `saveWorkspaceProtocol` is `Option<yaml_serde::Value>` because pnpm's setting accepts the bool `true`/`false` and the string `"rolling"`; the resolver normalizes via `SaveWorkspaceProtocol::from_str_normalized`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8dbfeed. Configure here.
Two follow-up review fixes on the linkWorkspacePackages path: - Validate the user's explicit version range against the workspace sibling's actual version before triggering a workspace link. `aube add project-2@^1.0.0` against a sibling at 2.0.0 used to silently write `workspace:^` and link the incompatible local copy; it now falls through to the registry path. Bare adds (no `@<range>`) keep the implicit dist-tag behavior since `has_explicit_range` is false in that case. Two new bats tests cover the satisfies-true and satisfies-false branches. - Drop the `"deep"` mention from `linkWorkspacePackages` docs. The field is `Option<bool>` so `linkWorkspacePackages: "deep"` in `pnpm-workspace.yaml` would have failed deserialization. The feature is intentionally not implemented — aube's resolver already prefers workspace siblings on bare semver ranges, so pnpm's transitive-link semantics are aube's default — and the docs now say so explicitly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Summary
Closes the workspace-protocol gap surfaced by pnpm's monorepo/index.ts batch 2 ports. Two new settings on
aube add:linkWorkspacePackages(bool, defaultfalse): whentrue,aube add <name>prefers a local workspace sibling over the registry. The packument fetch is skipped, the manifest specifier is built fromsaveWorkspaceProtocol, and the resolver picks up the local copy on the next install (existing aube behavior on bare semver ranges, so no resolver change required).saveWorkspaceProtocol("true" | "false" | "rolling", default"rolling"): controls the spec form written topackage.json.rollingwritesworkspace:^(no version),truewritesworkspace:^<version>,falsewrites^<version>. The--save-workspace-protocol/--no-save-workspace-protocolCLI flags override per-invocation.update_manifest_for_addnow reads settings from the workspace yaml root rather than the immediate project dir so a sub-project's add picks up the workspace-wide policy.Tests
Bats ports in
test/pnpm_monorepo_index.bats:saveWorkspaceProtocol,--save-dev,--save-optional --no-save-workspace-protocol)saveWorkspaceProtocol: rolling)saveWorkspaceProtocol: true(no pnpm equivalent; the three protocol variants share one code path so coverage of the third form is the only way to catch a silent regression there)Test plan
cargo clippy --all-targets -- -D warningscargo fmt --checkcargo test -p aube(430 tests)bats test/pnpm_monorepo_index.bats(9 tests, all green)🤖 Generated with Claude Code
Note
Medium Risk
Changes
aube adddependency resolution and manifest-writing behavior in workspaces, which can alterpackage.jsonspecifiers and skip registry fetches based on new settings/flags. Risk is moderated by explicit opt-in defaults, guardrails for aliases/range mismatches, and added bats coverage.Overview
aube addcan now prefer local workspace siblings over the registry via newlinkWorkspacePackages(defaultfalse), skipping packument fetches when a matching sibling exists and writing the manifest entry according tosaveWorkspaceProtocol(rollingworkspace:^, pinnedworkspace:^<version>, or registry-style^<version>).Adds
--save-workspace-protocoland--no-save-workspace-protocolflags to override the per-workspace policy for a single invocation, reads these workspace-owned settings from the workspace-yaml root (so subprojects honor workspace policy), updates workspace yaml schema/docs/CLI help generation, and introduces new bats tests covering rolling/pinned/opt-out behavior plus regression guards for aliases and explicit range mismatches.Reviewed by Cursor Bugbot for commit 195e61d. Bugbot is set up for automated code reviews on this repo. Configure here.