Skip to content

feat: add pre/post lifecycle hooks for package.json scripts#231

Merged
branchseer merged 3 commits intomainfrom
feat/pre-post-script-hooks
Mar 12, 2026
Merged

feat: add pre/post lifecycle hooks for package.json scripts#231
branchseer merged 3 commits intomainfrom
feat/pre-post-script-hooks

Conversation

@branchseer
Copy link
Member

@branchseer branchseer commented Mar 12, 2026

Summary

Adds npm-style pre/post lifecycle hooks for package.json scripts.

If you have a script named test, you can now define pretest and posttest scripts that automatically run before and after it — no extra configuration needed:

{
  "scripts": {
    "pretest": "docker compose up -d",
    "test": "vitest run",
    "posttest": "docker compose down"
  }
}

Running vt run test will execute all three in order.

Behavior

  • Hooks apply only to package.json scripts, not tasks defined in vite-task.json
  • Extra CLI args (e.g. vt run test --coverage) are passed to the main script only, not the hooks
  • Hooks are one level deep: when test runs pretest as a hook, pretest does not also run prepretest — matching npm's behavior
  • Opt out workspace-wide with enablePrePostScripts: false in the root vite-task.json

Test plan

  • script-hooks: pre/post hooks run in correct order; extra args not forwarded to hooks; running pretest directly does expand prepretest, but prepretest is not included when pretest runs as a hook of test
  • script-hooks-disabled: enablePrePostScripts: false suppresses hooks
  • script-hooks-task-no-hook: task configs are not expanded with hooks

🤖 Generated with Claude Code

When a package.json script `X` is run, automatically expand `preX`
and `postX` scripts (if they exist in the same package) as inline
execution items — matching npm's lifecycle hook behavior.

- Hooks are expanded at plan time, not as graph dependency edges
- Only applies to `PackageJsonScript` tasks; `TaskConfig` tasks are excluded
- Extra CLI args are not forwarded to hook scripts
- Configurable via `enablePrePostScripts` in the workspace root
  `vite-task.json` (defaults to `true`)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@branchseer branchseer marked this pull request as draft March 12, 2026 09:40
branchseer and others added 2 commits March 12, 2026 17:41
When `vt run test` triggers `pretest` as a hook, `pretest` itself does
not look for `prepretest`. This matches npm's behavior where lifecycle
hooks are always one level deep.

Implemented via an `expand_hooks: bool` flag on `PlanContext` that is
set to `false` when planning any hook script. Added `prepretest` to the
script-hooks test fixture to prove that `vt run test` correctly produces
[pretest, test, posttest] without `prepretest`, while `vt run pretest`
directly does expand `prepretest`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a hook script's command is `vt run someScript`, `someScript`'s own
pre/post hooks should still be expanded. Previously, the `expand_hooks`
flag (which suppresses recursive hook expansion) incorrectly propagated
into nested `plan_query_request` calls, preventing `prescriptInHook`
from being found when `scriptInHook` was called via `vt run` from a hook.

The flag is now a `with_hooks: bool` parameter of `plan_task_as_execution_node`
rather than a field on `PlanContext`. `plan_query_request` always passes
`true`, correctly scoping the one-level-deep restriction to the single hook
call rather than its entire subtree.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@branchseer branchseer marked this pull request as ready for review March 12, 2026 09:53
@branchseer branchseer merged commit 47cee2c into main Mar 12, 2026
7 checks passed
@branchseer branchseer deleted the feat/pre-post-script-hooks branch March 12, 2026 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants