feat(cli): support workspace-yaml-only-root monorepos in list/run/install/query/why#485
feat(cli): support workspace-yaml-only-root monorepos in list/run/install/query/why#485
Conversation
…tall/query/why Turborepo-style monorepos keep `pnpm-workspace.yaml` / `aube-workspace.yaml` at the repo root with no sibling `package.json`. The five workspace-scoped commands previously hard-errored at `project_root()` because they walked up looking for a `package.json` and found none. Add `crate::dirs::project_or_workspace_root()` that falls back to a yaml-only ancestor and route the five commands through it; install treats the missing root manifest as `PackageJson::default()` so root deps and root lifecycle hooks no-op while workspace projects still install. Single-project commands (`add`, `remove`, `version`, `publish`, `patch`, etc.) intentionally stay on `project_root()`. Triage decision tracked in PR #471 (`test/PNPM_TEST_IMPORT.md`). Ports the empty-monorepo case from `pnpm/test/monorepo/index.ts:56` — `aube list -r` from a yaml root with zero on-disk projects now prints "No projects found in <dir>" and exits 0 instead of erroring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryIntroduces Confidence Score: 4/5Safe to merge; only P2 findings — no data loss or crash risk. All findings are P2. The
Important Files Changed
|
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 0bd749a. Configure here.
| // means `--filter`/`-r` is meaningless). | ||
| if workspace_pkgs.is_empty() { | ||
| if aube_manifest::workspace::workspace_yaml_existing(&read_from).is_some() | ||
| || read_from.join("package.json").is_file() |
There was a problem hiding this comment.
Overly permissive check treats non-workspace projects as empty workspaces
Medium Severity
The condition read_from.join("package.json").is_file() is too broad. When find_workspace_root(&cwd) returns None (no workspace markers found), read_from falls back to cwd.clone(), which may be a plain project root with a package.json that has no workspaces field. In that scenario, the check passes, causing aube list --filter=... in a non-workspace project to print "No projects found" and exit 0 instead of returning the correct error about --filter requiring a workspace root. The condition needs to verify the package.json actually declares a workspace (has a workspaces field), not merely that it exists.
Reviewed by Cursor Bugbot for commit 0bd749a. Configure here.
Benchmark changesPublic ratios: warm installs vs Bun 7x -> 6x; warm installs vs pnpm 11x -> 10x.
0bd749a vs 71ec8ef | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex. |
|
Superseded by #486 — same feature (workspace yaml-only-root), newer iteration with full review coverage. Closing in favor of that PR. Written with Claude. |


Summary
crate::dirs::project_or_workspace_root()helper resolves cwd for the five workspace-scoped commands by preferring apackage.jsonwalk-up and falling back to a yaml-only ancestor (aube-workspace.yaml/pnpm-workspace.yaml). Errors only when neither exists.aube list,aube run -r,aube install,aube query,aube whythrough it.installtreats a missing root manifest asPackageJson::default()so root deps and root lifecycle hooks no-op while workspace projects still install.aube list -rfrom a yaml root with zero on-disk projects now prints "No projects found in " and exits 0.add,remove,version,publish,patch,patch-commit, etc.) intentionally stay onproject_root()— they require a real manifest to act on.monorepo/index.ts:56no-projects-found case intest/PNPM_TEST_IMPORT.md.Triage decision tracked in PR #471.
Test plan
cargo build --workspacecargo test— 360+ unit tests passcargo clippy --all-targets -- -D warnings— cleancargo fmt --check— cleanmise run test:bats test/workspace_yaml_only_root.bats— 7/7 pass (install, list -r, run -r, query, why from a yaml-only root; pnpmmonorepo/index.ts:56empty-monorepo port; single-project add still surfaces a helpful error)mise run test:bats test/workspace.bats test/workspace_member_install_walks_up.bats test/list.bats test/why.bats test/query.bats test/run.bats test/filter.bats test/pnpm_monorepo_index.bats test/patch.bats— no regressions on the affected workspace surface🤖 Generated with Claude Code
Note
Medium Risk
Changes cwd resolution and root-manifest handling for multiple workspace-scoped commands, which can alter behavior in monorepos and affect which project/lockfile is targeted. Risk is mitigated by defaulting missing root manifests to empty and adding Bats coverage for yaml-only workspaces.
Overview
Adds workspace-yaml-only root support (e.g.
pnpm-workspace.yaml/aube-workspace.yamlwithout a rootpackage.json) for the workspace-scoped commandsinstall,list -r,run -r,query, andwhyby introducingcrate::dirs::project_or_workspace_root()and routing these entrypoints through it.Updates these commands to tolerate missing root manifests by synthesizing
PackageJson::default()whenpackage.jsonis absent (so root deps/scripts no-op) and improves error/warning behavior (e.g.list -rprints “No projects found” and exits 0 when the workspace YAML exists but matches no on-disk projects).Adds
test/workspace_yaml_only_root.batsand updatesPNPM_TEST_IMPORT.mdto record/verify the new yaml-only workspace behavior.Reviewed by Cursor Bugbot for commit 0bd749a. Bugbot is set up for automated code reviews on this repo. Configure here.