feat(cli): support yaml-only workspace roots in list/run/install/query/why#486
feat(cli): support yaml-only workspace roots in list/run/install/query/why#486
Conversation
Greptile SummaryThis PR adds yaml-only workspace root support to The root-resolution priorities are consistent across commands: Confidence Score: 5/5Safe to merge — logic is correct, previous review concerns are addressed, and the only finding is a stale comment. All three concerns raised in prior review threads (silent fallback, misleading error message, install priority reversal) are correctly addressed in this revision. The No files require special attention. Important Files Changed
Reviews (7): Last reviewed commit: "docs(cli): clarify patch.rs handles yaml..." | Re-trigger Greptile |
Benchmark changesVersions:
Public ratios: warm installs vs Bun 7x -> 10x; warm installs vs pnpm 11x -> 12x.
190f201 vs 5f05906 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex. |
70edb61 to
d2f5b26
Compare
Two PR #486 review fixes: - The previous commit flipped install root resolution to prefer the workspace root over the project root, which broke the legacy `cd packages/app && aube install` shape (the patch.bats workspace test hit "is-odd is not installed" because install ran at the workspace root rather than the member). Restore the legacy precedence: project first, fall back to the workspace root for yaml-only coordinator roots that have no sibling `package.json`. Members install into their own dir as before; only the bare yaml-only root takes the workspace path. - `project_or_workspace_root` now mentions both `package.json` and the workspace yaml in its not-found error so users on a pure-coordinator monorepo see the actionable signal. Mirrored in install::run's local error path. Addresses Greptile P2 + Cursor low-severity on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Addressed CI bats failure + Greptile P2 + Cursor low-severity: CI patch.bats failure: the previous commit flipped install root resolution to prefer the workspace root, which broke Greptile P2 (misleading error in Cursor low-severity (silent fallback in Cursor low-severity (manifest-or-default duplication across 5 sites): noted but left in-place this round; refactoring 5 call sites into a Validation: cargo build/clippy/fmt clean, Written with Claude. |
|
Addressed Greptile P1 / Cursor low: `aube run -r` was silently falling back to `initial_cwd.clone()` when both `find_project_root` and `find_workspace_root` returned `None`. Replaced with a hard error matching `project_or_workspace_root`'s wording. Verified locally: `cargo build` / `cargo clippy --all-targets -- -D warnings` / `cargo fmt --check` clean, full `patch.bats` passes (the test that was failing in CI before jdx's earlier fix). Cursor's "duplicated manifest-or-default fallback pattern" (low severity) left as-is for now — five call sites is borderline for extraction and the inline form is easy to follow. Written with Claude. |
The "check if package.json exists, load it or fall back to default" pattern was copy-pasted across five call sites (install/mod.rs, list.rs, query.rs, why.rs main + run_filtered). Extract a single `load_manifest_or_default(root)` helper next to the existing `load_manifest` so future changes to the fallback land in one place. No behavior change. Addresses Cursor low-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Addressed Cursor's last open low-severity finding: extracted
Written with Claude. |
|
Three CI bats failures resolved (all from my last commit's install-precedence flip):
Verified locally: Also rebased PR #483 against current main (it had merge conflicts on PNPM_TEST_IMPORT.md from #471's triage doc landing). Written with Claude. |
Install and patch both want workspace-first precedence (so members share the workspace's lockfile + `.aube/` store), which is the opposite of `project_or_workspace_root`. Both call sites had the inline match block duplicated. Extract `workspace_or_project_root` next to the existing helper, share the no-root error builder, and collapse both call sites. No behavior change. Addresses Cursor low-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Extracted |
`run_install_command` was using `project_or_workspace_root` (project- first) to load `.npmrc` and workspace yaml, while `install::run` itself uses `workspace_or_project_root` (workspace-first). When both roots exist, the two diverged: settings loaded from the member's config, install acted against the workspace root. Use the same helper at both sites. Addresses Cursor medium-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Aligned |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a88fba0. Configure here.
…y/why Adds `project_or_workspace_root()` to `crates/aube/src/dirs.rs` and routes the five workspace-scoped commands through it so a pure- coordinator monorepo (Turborepo defaults: `pnpm-workspace.yaml` at the root, sub-packages under `packages/*`, no root `package.json`) works end-to-end. `install` synthesizes an empty `PackageJson` for the root when no manifest is on disk; the other four commands skip the root manifest read in the same way. Single-project commands (`add`, `remove`, root-only `run <script>`, `ci`, `version`, …) keep using `project_root()` and still hard-error on yaml-only roots because they need a manifest to act on. Triage decision in PR #471 (test/PNPM_TEST_IMPORT.md, monorepo/index.ts:56). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight bats cases in `test/yaml_only_root.bats` exercise install/list -r/run -r/query/why against a `pnpm-workspace.yaml` root with no sibling `package.json`, and pin three single-project commands (`add`/`remove`/root-only `run`) to their existing hard-error path. Promotes the monorepo/index.ts:56 entry in `test/PNPM_TEST_IMPORT.md` to "landed" and trims the related divergence note. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two PR #486 review fixes: - The previous commit flipped install root resolution to prefer the workspace root over the project root, which broke the legacy `cd packages/app && aube install` shape (the patch.bats workspace test hit "is-odd is not installed" because install ran at the workspace root rather than the member). Restore the legacy precedence: project first, fall back to the workspace root for yaml-only coordinator roots that have no sibling `package.json`. Members install into their own dir as before; only the bare yaml-only root takes the workspace path. - `project_or_workspace_root` now mentions both `package.json` and the workspace yaml in its not-found error so users on a pure-coordinator monorepo see the actionable signal. Mirrored in install::run's local error path. Addresses Greptile P2 + Cursor low-severity on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile P1 / Cursor low: when `aube run -r` is invoked from a directory with no `package.json` ancestor and no workspace root, the filter branch was silently falling back to `initial_cwd.clone()`, silently proceeding against an arbitrary directory. Replace the `unwrap_or_else` with a hard error matching `project_or_workspace_root`'s wording. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "check if package.json exists, load it or fall back to default" pattern was copy-pasted across five call sites (install/mod.rs, list.rs, query.rs, why.rs main + run_filtered). Extract a single `load_manifest_or_default(root)` helper next to the existing `load_manifest` so future changes to the fallback land in one place. No behavior change. Addresses Cursor low-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Revert the install root-precedence flip from the previous commit —
the explicit `workspace_member_install_walks_up.bats` test enforces
pnpm-parity (install at the workspace root, not at the member). My
"project-first" flip broke that test plus the
`pnpm_monorepo_index.bats:512` topological-order port (running
`aube --filter=...<pkg>` from a member ran auto-install at the
member, which then tried to fetch workspace-internal package names
from the registry).
`aube patch` continued to use `project_root()` and looked for the
`.aube/` store at the member level — empty in a workspace install,
so `aube patch is-odd@3.0.1` from `packages/app/` reported "not
installed". Mirror the install resolution (workspace-first, project
fallback) so patch finds the shared store.
Update `project_root_walk_up.bats` for the new error wording from
the previous commit ("no package.json or workspace yaml found").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Install and patch both want workspace-first precedence (so members share the workspace's lockfile + `.aube/` store), which is the opposite of `project_or_workspace_root`. Both call sites had the inline match block duplicated. Extract `workspace_or_project_root` next to the existing helper, share the no-root error builder, and collapse both call sites. No behavior change. Addresses Cursor low-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`run_install_command` was using `project_or_workspace_root` (project- first) to load `.npmrc` and workspace yaml, while `install::run` itself uses `workspace_or_project_root` (workspace-first). When both roots exist, the two diverged: settings loaded from the member's config, install acted against the workspace root. Use the same helper at both sites. Addresses Cursor medium-severity review on PR #486. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Note that `upsert_patched_dependency` already routes through `config_write_target`, which lands the entry in the workspace yaml when the resolved root has no `package.json`. Addresses Cursor medium-severity feedback on PR #486 — flagged a hypothetical silent-loss bug that doesn't actually occur. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a88fba0 to
190f201
Compare
|
Rebased onto current main (post-#475/#481/#483/#485). Conflict was on Three of the four review items were stale (already addressed by recent commits on this branch):
The Cursor medium ("Patch from yaml-only workspace root breaks patch-commit") turned out to be a false alarm: Validation: cargo build/clippy/fmt clean, Written with Claude. |

Summary
project_or_workspace_root()(crates/aube/src/dirs.rs) — falls back to the workspace root when no ancestor haspackage.jsonbut apnpm-workspace.yaml/aube-workspace.yamlis present.aube install,aube list,aube run -r,aube query,aube whythrough it.installsynthesizes an emptyPackageJsonwhen the workspace root has no manifest; the other four commands read the lockfile directly and skip the manifest read on yaml-only roots.add,remove, root-onlyrun <script>,ci,version, …) still callproject_root()and continue to hard-error without a manifest.Use case: pure-coordinator monorepos (Turborepo defaults and several large OSS repos) with
pnpm-workspace.yamlat the root and no rootpackage.json. Today the five commands above hard-error atproject_root(). With this change, they operate against the workspace as a whole.Triage decision in test/PNPM_TEST_IMPORT.md (monorepo/index.ts:56) → recorded as "landed" alongside this PR.
Test plan
cargo build --workspacecargo clippy --all-targets -- -D warningscargo fmt --checkcargo test --workspacemise run test:bats test/yaml_only_root.bats— 8/8 pass (install/list/run -r/query/why against yaml-only root + 3 single-project hard-error guards)mise run test:bats test/install.bats test/list.bats test/run.bats— no regressionsThis PR was generated by Claude.
Note
Medium Risk
Changes root-resolution and manifest-loading behavior for
installand multiple workspace commands, which can affect where lockfiles/stores are read/written and how monorepos are interpreted. Risk is mitigated by being scoped to workspace root detection and adding targeted bats coverage.Overview
Adds support for yaml-only “coordinator” workspaces (e.g.,
pnpm-workspace.yamlat repo root with no rootpackage.json) across workspace-scoped commands.Root resolution is updated via new
dirs::{project_or_workspace_root, workspace_or_project_root}soinstall/patchprefer the workspace root (sharedaube-lock.yaml/.aube/), while read-style commands (list,query,why) can fall back to a workspace root when no project manifest is present. Commands that previously unconditionally read<root>/package.jsonnow useload_manifest_or_defaultto synthesize an empty manifest when absent.Updates CLI error messaging for “no root found” cases and adds
test/yaml_only_root.batsto cover install/list/run -r/query/why behavior on yaml-only roots while asserting single-project commands still fail without a manifest.Reviewed by Cursor Bugbot for commit 190f201. Bugbot is set up for automated code reviews on this repo. Configure here.