Pavel 'PK' Kaminsky 00dd5475f0 feat(cli): agent hooks fix only the file the agent edited (#814)
* feat(cli): agent hooks fix only the file the agent edited

The generated agent hook ran the project's fix script over the whole project
after every edit. It now passes --hook, and fix --hook reads the agent's hook
payload from stdin: Claude Code and CodeBuddy tool_input.file_path, Cursor
file_path, Windsurf tool_info.file_path. A file outside the project or one
that no longer exists is skipped. A payload with no readable path keeps the
whole-project run. Re-running init does not add a second hook next to one
generated before --hook.

* Make fix --hook robust to unsupported files, open stdin, symlinked roots and explicit targets

- Skip a file the linters do not handle instead of failing the hook: Oxlint
  only receives files it lints, oxfmt gets --no-error-on-unmatched-pattern,
  Prettier gets --ignore-unknown.
- Bound the stdin read: resolve as soon as a complete JSON payload arrives,
  or at a one second deadline, so a host that leaves stdin open cannot hang
  the hook.
- Compare real paths so a project opened through a symlink still contains
  its own files, and hand the linters a path relative to the project root.
- Honour targets already on the command line: narrow them to the edited
  file, skip a file outside them, and keep them as they are when they are
  globs.
- Upgrade a hook command generated before --hook existed when init is
  re-run, instead of leaving it in place.

* Make the hook target tests independent of the working directory and platform

* Resolve explicit hook targets and rewrite every outdated generated hook command

- A symlinked directory given on the command line now resolves like the
  edited file, so the file under it is still covered.
- Re-running init rewrites any command an earlier init generated, for any
  package manager or linter, rather than only the pre-`--hook` command for
  the current one. A changed linter or package manager no longer leaves the
  old hook in place or gains a second one.

* Parse hook payloads strictly and only upgrade the generated hook's own command

- A truncated payload no longer yields a file path through lenient JSONC
  parsing; anything that is not valid JSON keeps the whole-project run.
- The init re-run only rewrites the command at the position the integration
  itself generates, so a user's own hook that runs the fix script elsewhere
  is left untouched.

---------

Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
2026-09-16 20:48:50 -07:00
2026-03-13 19:25:49 -07:00
2026-04-25 01:19:14 -07:00
2026-08-13 21:07:55 -07:00
2026-08-13 21:07:55 -07:00
2022-03-18 16:20:30 +11:00
2025-12-28 02:17:21 -08:00
2023-12-26 11:51:13 -05:00
2026-04-25 01:19:14 -07:00
S
Description
Ultracite is a zero-config linting and formatting preset for JavaScript/TypeScript projects. Use when: (1) Setting up or initializing Ultracite in a project…
32 MiB
Languages
TypeScript 70.2%
JavaScript 16.9%
MDX 7.4%
Astro 4.9%
CSS 0.6%