Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a8d5b53
fix(cli): preserve project-owned git hooks
TheAlexLichter Jul 29, 2026
555bd1a
fix(cli): guard hook migration conflicts
TheAlexLichter Jul 31, 2026
f581528
fix(cli): defer project hook migration
TheAlexLichter Aug 1, 2026
cc72f4d
fix(cli): harden project hook migration
TheAlexLichter Aug 3, 2026
093cb75
fix(cli): preflight all migrated hook entries
TheAlexLichter Aug 3, 2026
ac172fe
fix(cli): preserve nested hook migrations
TheAlexLichter Aug 3, 2026
2686c5a
Merge remote-tracking branch 'origin/main' into fix/config-hook-dispa…
TheAlexLichter Aug 3, 2026
ba768de
fix(cli): migrate legacy Husky hook helpers
TheAlexLichter Aug 3, 2026
f46533d
fix(cli): contain git hook migrations
TheAlexLichter Aug 3, 2026
218e266
fix(cli): preserve safe hook migration state
TheAlexLichter Aug 3, 2026
3d83272
fix(cli): harden hook dispatcher refresh
TheAlexLichter Aug 3, 2026
b77b3aa
fix(cli): make hook migration transactional
TheAlexLichter Aug 3, 2026
467f09b
fix(cli): preserve uncommon hook migrations
TheAlexLichter Aug 3, 2026
910a8d6
fix(cli): reject unsafe hook filesystem state
TheAlexLichter Aug 3, 2026
9640ee1
fix(cli): reject linked project hooks
TheAlexLichter Aug 3, 2026
5814dc6
fix(cli): contain direct hook installation
TheAlexLichter Aug 3, 2026
d432e32
fix(cli): rewrite prepare within migration transaction
TheAlexLichter Aug 3, 2026
9e75f37
fix(cli): parse escaped Husky hook paths
TheAlexLichter Aug 3, 2026
0bf690c
fix(cli): preserve lint-staged package scripts
TheAlexLichter Aug 3, 2026
de0e9f6
fix(cli): preserve direct Husky hook setup
TheAlexLichter Aug 3, 2026
0743eb8
fix(cli): respect native hook path separators
TheAlexLichter Aug 3, 2026
b47e44a
fix(cli): honor worktree hook configuration
TheAlexLichter Aug 3, 2026
05f03be
fix(cli): reject ambiguous Husky directories
TheAlexLichter Aug 3, 2026
e605088
fix(cli): detect lifecycle hook commands precisely
TheAlexLichter Aug 3, 2026
5b029d3
fix(cli): normalize explicit Husky default directory
TheAlexLichter Aug 3, 2026
8fc3371
fix(cli): normalize equivalent Husky paths
TheAlexLichter Aug 3, 2026
f5a2dd6
fix(cli): preserve remaining Husky consumers
TheAlexLichter Aug 3, 2026
5bb106a
fix(cli): roll back partial hook migrations
TheAlexLichter Aug 3, 2026
d8e87b1
fix(cli): avoid hook command marker collisions
TheAlexLichter Aug 3, 2026
cdaefad
fix(cli): preserve only active Husky commands
TheAlexLichter Aug 3, 2026
917b980
test(cli): use native hook path separators
TheAlexLichter Aug 3, 2026
61117f1
fix(cli): harden hook migration rollback
TheAlexLichter Aug 3, 2026
afaa842
fix(cli): normalize equivalent hook paths
TheAlexLichter Aug 3, 2026
cf297ec
fix(cli): handle Husky init migration
TheAlexLichter Aug 3, 2026
3135883
fix(cli): respect shell command boundaries
TheAlexLichter Aug 3, 2026
744aae4
refactor(cli): narrow Husky hook migration
TheAlexLichter Aug 3, 2026
85cad80
docs: clarify Husky migration scope
TheAlexLichter Aug 3, 2026
241f629
refactor(cli): skip Husky init prepare scripts
TheAlexLichter Aug 3, 2026
6cfa1f9
refactor(cli): defer Husky hook migration
TheAlexLichter Aug 4, 2026
c074011
docs: clarify hook migration ownership
TheAlexLichter Aug 4, 2026
b465f18
Merge remote-tracking branch 'origin/main' into fix/config-hook-dispa…
TheAlexLichter Aug 4, 2026
ff155ca
test(cli): preserve Husky migration snapshots
TheAlexLichter Aug 4, 2026
e40bf17
fix(cli): detect runnable hook policies
TheAlexLichter Aug 4, 2026
2eb7fdb
Merge remote-tracking branch 'origin/main' into fix/config-hook-dispa…
TheAlexLichter Aug 4, 2026
05eb22f
fix(cli): preflight hook policy during create
TheAlexLichter Aug 4, 2026
8bf6502
Merge remote-tracking branch 'origin/main' into fix/config-hook-dispa…
TheAlexLichter Aug 4, 2026
cf9043c
fix(cli): preflight hooks across create workspaces
TheAlexLichter Aug 4, 2026
6da8378
Merge branch 'main' into fix/config-hook-dispatcher-only
fengmk2 Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vp run lint
vp exec tsc --noEmit
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[[case]]
name = "command_config_auto_hooks"
vp = "global"
env = { npm_lifecycle_event = "prepare" }
steps = [
{ argv = ["git", "init"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "config"], comment = "should install hooks automatically without prompting (staged config exists)", continue-on-failure = true },
{ argv = ["vp", "config"], comment = "prepare should install the dispatcher without changing project hook policy", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "should have vp staged", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "project-owned hook should remain unchanged", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite.config.ts"], comment = "should remain unchanged", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## `vp config`

should install hooks automatically without prompting (staged config exists)
prepare should install the dispatcher without changing project hook policy

```
```
Expand All @@ -20,10 +20,11 @@ should be .vite-hooks/_

## `vpt print-file .vite-hooks/pre-commit`

should have vp staged
project-owned hook should remain unchanged

```
vp staged
vp run lint
vp exec tsc --noEmit
```

## `vpt print-file vite.config.ts`
Expand All @@ -33,9 +34,5 @@ should remain unchanged
```
import { defineConfig } from 'vite-plus';

export default defineConfig({
staged: {
'*': 'vp check --fix',
},
});
export default defineConfig({});
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { defineConfig } from 'vite-plus';

export default defineConfig({
staged: {
'*': 'vp check --fix',
},
});
export default defineConfig({});
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ VITE+ - The Unified Toolchain for the Web

Usage: vp config [OPTIONS]

Configure Vite+ for the current project (hooks + agent integration).
Configure Vite+ for the current project (hook dispatcher + agent integration).

Options:
--hooks-dir <path> Custom hooks directory (default: .vite-hooks)
--no-hooks Skip hook installation
--no-hooks Skip hook dispatcher installation
--no-agent Skip updating coding agent instructions
-h, --help Show this help message

Environment:
VP_GIT_HOOKS=0 Skip hook installation
VP_GIT_HOOKS=0 Skip hook dispatcher installation

Documentation: https://viteplus.dev/guide/commit-hooks
```
Expand All @@ -28,16 +28,16 @@ VITE+ - The Unified Toolchain for the Web

Usage: vp config [OPTIONS]

Configure Vite+ for the current project (hooks + agent integration).
Configure Vite+ for the current project (hook dispatcher + agent integration).

Options:
--hooks-dir <path> Custom hooks directory (default: .vite-hooks)
--no-hooks Skip hook installation
--no-hooks Skip hook dispatcher installation
--no-agent Skip updating coding agent instructions
-h, --help Show this help message

Environment:
VP_GIT_HOOKS=0 Skip hook installation
VP_GIT_HOOKS=0 Skip hook dispatcher installation

Documentation: https://viteplus.dev/guide/commit-hooks
```
Expand All @@ -49,16 +49,16 @@ VITE+ - The Unified Toolchain for the Web

Usage: vp config [OPTIONS]

Configure Vite+ for the current project (hooks + agent integration).
Configure Vite+ for the current project (hook dispatcher + agent integration).

Options:
--hooks-dir <path> Custom hooks directory (default: .vite-hooks)
--no-hooks Skip hook installation
--no-hooks Skip hook dispatcher installation
--no-agent Skip updating coding agent instructions
-h, --help Show this help message

Environment:
VP_GIT_HOOKS=0 Skip hook installation
VP_GIT_HOOKS=0 Skip hook dispatcher installation

Documentation: https://viteplus.dev/guide/commit-hooks
```
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "command_config_no_agent"
vp = "global"
steps = [
{ argv = ["git", "init"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "config", "--no-agent"], comment = "should install hooks but skip agent instruction updates", continue-on-failure = true },
{ argv = ["vp", "config", "--no-agent"], tty = false, comment = "should install the hook dispatcher but skip agent instruction updates", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vpt", "grep-file", "AGENTS.md", "OUTDATED CONTENT"], comment = "agent must stay unchanged (outdated marker still present)" },
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## `vp config --no-agent`

should install hooks but skip agent instruction updates
should install the hook dispatcher but skip agent instruction updates

```
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ vp = "global"
env = { npm_lifecycle_event = "postinstall" }
steps = [
{ argv = ["git", "init"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "config"], comment = "should install hooks automatically without prompting", continue-on-failure = true },
{ argv = ["vp", "config"], comment = "should install the dispatcher automatically without prompting", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "should have vp staged", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite.config.ts"], comment = "should have staged config", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".vite-hooks/_/pre-commit", "--assert", "file"], comment = "generated dispatcher shim should exist", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".vite-hooks/pre-commit", "--assert", "missing"], comment = "project hook should not be created", continue-on-failure = true },
{ argv = ["vpt", "stat-file", "vite.config.ts", "--assert", "missing"], comment = "vite config should not be created", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## `vp config`

should install hooks automatically without prompting
should install the dispatcher automatically without prompting

```
```
Expand All @@ -18,25 +18,26 @@ should be .vite-hooks/_
.vite-hooks/_
```

## `vpt print-file .vite-hooks/pre-commit`
## `vpt stat-file .vite-hooks/_/pre-commit --assert file`

should have vp staged
generated dispatcher shim should exist

```
vp staged
.vite-hooks/_/pre-commit: file
```

## `vpt print-file vite.config.ts`
## `vpt stat-file .vite-hooks/pre-commit --assert missing`

should have staged config
project hook should not be created

```
import { defineConfig } from 'vite-plus';
.vite-hooks/pre-commit: missing
```

## `vpt stat-file vite.config.ts --assert missing`

export default defineConfig({
staged: {
"*": "vp check --fix"
},
vite config should not be created

});
```
vite.config.ts: missing
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ vp = "global"
env = { npm_lifecycle_event = "prepare" }
steps = [
{ argv = ["git", "init"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "config"], comment = "should install hooks automatically without prompting", continue-on-failure = true },
{ argv = ["vp", "config"], comment = "should install the dispatcher automatically without prompting", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "should have vp staged", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite.config.ts"], comment = "should have staged config", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".vite-hooks/_/pre-commit", "--assert", "file"], comment = "generated dispatcher shim should exist", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".vite-hooks/pre-commit", "--assert", "missing"], comment = "project hook should not be created", continue-on-failure = true },
{ argv = ["vpt", "stat-file", "vite.config.ts", "--assert", "missing"], comment = "vite config should not be created", continue-on-failure = true },
{ argv = ["vp", "config"], comment = "run again to ensure idempotent", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "should remain unchanged", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite.config.ts"], comment = "should remain unchanged", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".vite-hooks/pre-commit", "--assert", "missing"], comment = "project hook should still be absent", continue-on-failure = true },
{ argv = ["vpt", "stat-file", "vite.config.ts", "--assert", "missing"], comment = "vite config should still be absent", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## `vp config`

should install hooks automatically without prompting
should install the dispatcher automatically without prompting

```
```
Expand All @@ -18,27 +18,28 @@ should be .vite-hooks/_
.vite-hooks/_
```

## `vpt print-file .vite-hooks/pre-commit`
## `vpt stat-file .vite-hooks/_/pre-commit --assert file`

should have vp staged
generated dispatcher shim should exist

```
vp staged
.vite-hooks/_/pre-commit: file
```

## `vpt print-file vite.config.ts`
## `vpt stat-file .vite-hooks/pre-commit --assert missing`

should have staged config
project hook should not be created

```
import { defineConfig } from 'vite-plus';
.vite-hooks/pre-commit: missing
```

## `vpt stat-file vite.config.ts --assert missing`

export default defineConfig({
staged: {
"*": "vp check --fix"
},
vite config should not be created

});
```
vite.config.ts: missing
```

## `vp config`
Expand All @@ -48,25 +49,18 @@ run again to ensure idempotent
```
```

## `vpt print-file .vite-hooks/pre-commit`
## `vpt stat-file .vite-hooks/pre-commit --assert missing`

should remain unchanged
project hook should still be absent

```
vp staged
.vite-hooks/pre-commit: missing
```

## `vpt print-file vite.config.ts`
## `vpt stat-file vite.config.ts --assert missing`

should remain unchanged
vite config should still be absent

```
import { defineConfig } from 'vite-plus';

export default defineConfig({
staged: {
"*": "vp check --fix"
},

});
vite.config.ts: missing
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ vp = "global"
steps = [
{ argv = ["git", "init"], snapshot = false, continue-on-failure = true },
{ argv = ["git", "config", "core.hooksPath", ".husky/_"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "config", "--no-agent"], tty = false, comment = "should replace .husky/_ with .vite-hooks/_", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vp", "config", "--no-agent"], tty = false, comment = "should preserve the existing Husky hooks path", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should remain .husky/_", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

## `vp config --no-agent`

should replace .husky/_ with .vite-hooks/_
should preserve the existing Husky hooks path

```
core.hooksPath is already set to ".husky/_", skipping
```

## `git config --local core.hooksPath`

should be .vite-hooks/_
should remain .husky/_

```
.vite-hooks/_
.husky/_
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[case]]
name = "create_default_hooks"
vp = "global"
skip-platforms = ["windows", { os = "linux", libc = "musl" }]
steps = [
{ argv = ["vp", "create", "vite:application", "--no-interactive"], comment = "create should scaffold the default hook policy", snapshot = false, continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite-plus-application/.vite-hooks/pre-commit"], comment = "project-owned pre-commit hook should run vp staged", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite-plus-application/vite.config.ts"], comment = "vite config should contain the matching staged policy", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# create_default_hooks

## `vp create vite:application --no-interactive`

create should scaffold the default hook policy


## `vpt print-file vite-plus-application/.vite-hooks/pre-commit`

project-owned pre-commit hook should run vp staged

```
vp staged
```

## `vpt print-file vite-plus-application/vite.config.ts`

vite config should contain the matching staged policy

```
import { defineConfig } from "vite-plus";

export default defineConfig({
staged: {
"*": "vp check --fix",
},
fmt: {},
lint: {
jsPlugins: [{ name: "vite-plus", specifier: "vite-plus/oxlint-plugin" }],
rules: { "vite-plus/prefer-vite-plus-imports": "error" },
options: { typeAware: true, typeCheck: true },
},
});
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hook documentation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ steps = [
{ argv = ["git", "config", "core.hooksPath", ".husky/_"], snapshot = false, continue-on-failure = true },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "a version-update defers legacy husky hooks to --full", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "still husky's .husky/_ (not overridden)", continue-on-failure = true },
{ argv = ["vp", "migrate", "--hooks", "--no-interactive"], comment = "--hooks overrides husky's core.hooksPath and migrates hooks", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "husky/lint-staged should be removed, prepare should be vp config", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".vite-hooks/pre-commit"], comment = "pre-commit hook should be rewritten", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "should be .vite-hooks/_", continue-on-failure = true },
{ argv = ["vp", "migrate", "--hooks", "--no-interactive"], comment = "--hooks still preserves a detected Husky setup", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "Husky and lint-staged metadata should remain", continue-on-failure = true },
{ argv = ["vpt", "print-file", ".husky/pre-commit"], comment = "the Husky hook should remain unchanged", continue-on-failure = true },
{ argv = ["git", "config", "--local", "core.hooksPath"], comment = "Husky's hooksPath should remain", continue-on-failure = true },
]
Loading
Loading