voidzero-dev / voidzero-dev/vite-plus

Allow `vp staged` to resolve workspace-root config from subdirectories

Aperta
#2,177 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
pending triage
Lingua principale
Rust
Stelle
5.8k
Fork
262
Merge medio
1g 34m
PR unite (30g)
135

Descrizione

### Description

In a monorepo, `vp staged` fails when invoked from a workspace package if the `staged` config exists only in the workspace-root `vite.config.ts`.

This is common with coding agents: after inspecting or editing one package, they often keep that package as the working directory when running validation commands.

```text
repo/
├── package.json # workspaces: ["packages/*"]
├── vite.config.ts # contains staged config
└── packages/
└── app/
└── src/index.ts
```

```ts
// repo/vite.config.ts
export default {
staged: {
'*.{js,ts,tsx}': 'vp check --fix',
},
}
```

```sh
git add packages/app/src/index.ts
cd packages/app
vp staged
```

Actual result:

```text
error: No "staged" config found in vite.config.ts. Please add a staged config
```

A normal pre-commit hook usually hides this behavior because Git starts client-side hooks from the worktree root, regardless of where `git commit` was entered.

### Current behavior

The following was verified with an isolated Git monorepo:

| Invocation | Config | File/task scope |
| --- | --- | --- |
| Run from repository root | Root `vite.config.ts` | Repository |
| Run from a package with no local `staged` config | None; exits with an error | Nothing runs |
| Run from a package with a local `staged` config | Package config | Package CWD |
| Run from a package with `--cwd ` | Root config | Repository |
| Run through a Git pre-commit hook | Root config, because Git uses the worktree root | Repository |

Internally, Vite+ resolves one `staged` object from the invocation CWD and passes it through lint-staged's programmatic `config` option. lint-staged still resolves the Git repository and staged files, but its own multi-config discovery is bypassed.

### Ecosystem patterns

Existing tools use different models:

| Model | Tools | Behavior |
| --- | --- | --- |
| Hook manager | Git, Husky, simple-git-hooks | Git starts hooks at the worktree root. The manager executes a literal hook command; package-specific CWD or filtering is left to that command. |
| Central root config | pre-commit, Lefthook | The tool resolves the Git root and loads a repository-level config. Package behavior is expressed through filters or per-command root settings. |
| Distributed config | lint-staged | The tool can discover multiple configs, assign each staged file to its closest config, and run tasks from the selected config directory. Configs are isolated rather than merged. |
| Current Vite+ behavior | `vp staged` | Git state is repository-aware through lint-staged, while Vite config lookup remains limited to the invocation CWD. |

Relevant details:

- Git changes to the worktree root before client-side hooks: https://git-scm.com/docs/githooks
- Husky requires an explicit `cd` when a hook should run inside a nested project: https://typicode.github.io/husky/how-to.html#project-not-in-git-root-directory
- lint-staged documents closest-config selection, isolated configs, config-directory task CWD, and package scoping with `--cwd`: https://github.com/lint-staged/lint-staged#how-to-use-lint-staged-in-a-multi-package-monorepo
- Lefthook loads from the Git root and uses a command-level `root` option to change CWD and filter files; globs remain relative to the Git root: https://lefthook.dev/configuration/root/
- pre-commit resolves the Git top level and changes into it before running most commands: https://github.com/pre-commit/pre-commit/blob/main/pre_commit/main.py#L175-L199

### Design choices

There are two separate decisions. This issue does not propose a preferred combination.

#### 1. Where should config come from?

- **Current CWD only:** preserve existing behavior; improve documentation/error output and require callers to use root CWD or `--cwd`.
- **Workspace/Git root:** always use one central root policy.
- **Nearest ancestor config:** walk upward to the workspace root. This could stop at the first Vite config, or continue until finding one that defines `staged`.
- **Multiple configs:** discover package/root staged configs and assign files to them independently.
- **Explicit selection:** add an option such as `--config` or `--root`; this can supplement any implicit rule.

Important edge case: a package may have a `vite.config.ts` for build settings but keep `staged` only at the workspace root. “Nearest Vite config” and “nearest config defining staged” produce different results.

#### 2. What should the execution scope be?

- **Repository root:** task CWD, glob base, and staged-file scope all use the root.
- **Invocation directory:** an inherited/root config can be used while files and tasks remain scoped to the package from which the command was launched.
- **Config directory:** tasks and file matching follow whichever config was selected.

These choices have different consequences. Root scope may process staged files in sibling packages; invocation scope may run root-defined commands from a package CWD; config-directory scope becomes more complex if multiple configs are supported.

Possible combinations include:

- root config + root scope;
- nearest ancestor config + invocation scope;
- current behavior + an explicit config/root option;
- multiple configs + per-config task scope.

### Relevant implementation

- Current staged config resolution and inline lint-staged config: https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/staged/bin.ts#L139-L164
- Existing workspace-bounded config traversal: https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/resolve-vite-config.ts#L98-L115
- Existing use of traversal in `vp pack`: https://github.com/voidzero-dev/vite-plus/blob/main/packages/cli/src/pack-bin.ts#L148-L150

### Validations

- [x] Read the [Contributing Guidelines](https://github.com/voidzero-dev/vite-plus/blob/main/CONTRIBUTING.md).
- [x] Confirm this request is for Vite+ itself and not for Vite, Vitest, tsdown, Rolldown, or Oxc.
- [x] Checked that there is not already an open issue requesting the same behavior.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start with packages/cli/src/staged/bin.ts, then read the workspace-bounded traversal in packages/cli/src/resolve-vite-config.ts and its use in packages/cli/src/pack-bin.ts. Reproduce the root-config-from-package scenario described above, then establish and validate a single config-resolution and execution-scope policy, including the package-local Vite config edge case.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
cli, tooling
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Tranquilla
Chiarezza
Da chiarire
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.