Repository navigation
Commit 8bc75fb
authored
fix(uncheck): review the whole package: safer hooks, tsc selection like tsc, faster runs, clearer docs (#12)
* fix(uncheck): harden the shared runner, file resolution and package-manager commands
- globs match dot files (picomatch) and exclusions on their own apply to everything
- git file names are taken literally in staged and hooks run; names starting with ! or - reach tools intact
- a run given files that no check handles passes in staged and hooks run
- tools killed or failing to spawn fail their check instead of crashing the run
- argv batches fit Windows' command line; Yarn PnP installs resolve tools
- hooks never download: npx --no, bunx --no-install; yarn run --silent keeps agent JSON clean
- sherif only reports in staged, since its fixes reach beyond the commit
- colours follow Node's rules; SIGHUP puts unstaged changes back; platform errors print cleanly
- minified bundle with a compile-cached entry; dead --wizard and --log-level flags hidden
* fix(uncheck): typecheck standalone projects with --noEmit, several at once
tsc -p no longer writes JavaScript or declarations during a check, and the
standalone projects of a monorepo are checked up to four at a time with their
output kept in plan order.
* test(uncheck): cover dot-file globs, exclusion-only paths, literal git paths, argv batches and killed tools
Also lets the middleapi tsconfig preset accept the .ts imports Node's type
stripping needs.
* docs(uncheck): describe dot-file globs, PnP, --noEmit, sherif in staged and preset versions
* fix(uncheck): check only a commit's own files in `staged` and put unstaged changes back intact
- A staged symlink is no longer checked or fixed through to the file it points
to (outside the repository, untracked or unstaged); a symlink turned into a
regular file is now checked.
- During a merge, only files that differ from the side merged in are checked
and fixed, so merge commits no longer carry fixes to the other side's work.
- With --fix only the files the fixes changed are staged, so a merge or squash
bringing in files outside a sparse checkout can be committed, and a
conflicting fix is still undone there.
- A partially staged file stored with CRLF under text=auto or core.autocrlf is
no longer reported as a conflicting fix.
- Run from a package folder, the restored file keeps the line endings and
encoding its .gitattributes set.
- Setting unstaged changes aside and undoing fixes no longer runs, or fails
with, the post-checkout hook.
* fix(uncheck): keep the pre-commit hook prepare writes safe for every repository and every package
- A core.hooksPath from the global or system git config is left alone and reported,
so one install no longer adds this repository's line to the hook every repository runs
- Packages of a workspace that prepare at the same time all keep their line
- In a hook that already has commands, the line runs before them, so their failure
still blocks the commit and an `exec` or `exit` no longer skips it
- A hook in another language (Node, Python, Ruby) is left alone and prepare says
which line it should run, instead of breaking every commit
- A package folder whose name sh would expand inside double quotes gets no line
rather than a broken or ever-growing one
- A hooks folder only counts as the husky 9 or Vite+ dispatcher when it is their `_` folder
- The folder a line enters comes from git itself, so it no longer depends on how
the path to the package was spelled
- Lines older versions wrote with plain npx or yarn are upgraded in place, and
hand-written lines that chain or soften the command stay as they are
* fix(uncheck): agent hooks keep your settings, check the right directory and reach every agent
- `hooks install` refuses a config that is not valid JSON(C) or not an object, naming the file and leaving every file as it was, instead of rewriting it with settings lost
- Reinstalling updates only uncheck's own hook entry, keeping keys added to it; permission rules, notes and chained commands that merely mention `uncheck hooks run` stay as they are, and a Stop hook is still added next to them
- Hook entries carry a 600 s timeout, so Copilot, VS Code and CodeBuddy no longer kill a typecheck at their 30 s or 60 s default; existing installs are upgraded on the next install
- The hook checks the top of the repository whichever directory the agent `cd`'d into; installed below the top it carries `--dir=<path>` and checks that directory
- Copilot is sent back through its Claude-format entry too, not only warned
- When checks still fail after the one retry, Claude Code and CodeBuddy show the user a warning instead of ending the turn silently
- A change no selected check covers passes the hook, and a deleted file whose name looks like a pattern no longer checks its neighbours
- Windsurf is no longer offered: its hook event can neither show the report nor send Cascade back
* fix(uncheck): typecheck every project a change reaches, the way tsc sees it
- staged and given files select referenced configs of any name, so a Vite,
Nx or Angular solution layout (tsconfig.app.json) is no longer skipped
- a changed tsconfig, or a base it extends, selects the projects it applies
to, also when the base is a workspace package linked into node_modules
- a selected project that others reference builds the roots depending on it
with tsc -b, so a library change that breaks its dependents fails the
commit; unrelated roots stay out
- project inputs match tsc: a base shared by two extends branches applies in
both, declarationDir is excluded, `*` skips .min.js, extensions are case
sensitive and an explicit node_modules include counts
- backslashes in extends and references read as separators, and references
keep ${configDir} as written, like tsc
- a reference cycle anywhere fails runs on given files too
* fix(uncheck): keep literal file lists in their given order; document the staged, prepare, hooks and tsc changes
* fix(uncheck): address the final review of the branch
- globs read [!x] as POSIX negation and parentheses literally, as before picomatch
- staged: a CRLF file under text=auto is undone rather than turned to LF, fixes outside a
sparse checkout are staged, core.safecrlf no longer blocks, messages name only what applies
- prepare: the line goes after the hook's PATH and environment setup, git before 2.26 still
refuses a global core.hooksPath, an unreadable or binary hook is never overwritten
- hooks: only the stop event's entry is uncheck's, a timeout the user set is kept, a stale
--dir is reported, Yarn 2+ root installs run the root binary, Copilot is refused below the
top, Cursor turns the user stopped are left alone
- tsc: dependents found without a quadratic walk, backslashes in include/exclude, smaller
cycle search
- Yarn PnP resolves tools from every ancestor workspace
* test(uncheck): cover the final review fixes and correct the docs they touch
* refactor(uncheck): simplify and speed up the branch's code
- globs use minimatch with dot matching, the engine path.matchesGlob already used, instead of
patching picomatch back to its semantics
- shared helpers for the rev-parse location, reading a file that may not exist, platform error
messages and batched git calls; the Yarn 2+ -T rule lives in detectExec
- staged runs its independent git calls together, writes a tree only when it sets changes
aside, and merges files concurrently; hooks run lists changed files concurrently
- existence and node_modules filters no longer cost a fiber or an array per file
- tsc resolves real paths only when a config is among the given files
- tests share the Stop payload, the CLI path and the side-branch setup
* fix(uncheck): address the review of the latest commits
- staged: an edit saved to a partially staged file while the checks run is merged back again;
only a CRLF blob git keeps as it is refuses the merge
- a newline in the repository's path no longer shifts the prefix staged, prepare and install use
- prepare puts its line before a setup line that also runs a command or continues onto the next,
and the old-git scope check reads included config files
- hooks install in a Yarn 2+ package without its own uncheck runs the root's
- a linked node_modules stays out of the project files; globs drop `.` inside braces again
- Yarn PnP falls back to node_modules for folders its resolver does not cover
* test(uncheck): cover the latest review fixes and the gaps it found
Adds tests for an edit saved during the checks, a put-back that fails, a first commit with
fixes, a repository path with a newline, other tools' Stop hooks and --require/--skip in
hook commands, Yarn 2+ package installs, setup lines that run a command or continue, included
git config on old git, tsc -b before parallel tsc -p, Yarn PnP resolution, linked node_modules,
braces with `.`, and the CLI's error output and global flags. The fixture now refuses to write
into a symlinked tool, which would change the shared pnpm store.
* refactor(uncheck): keep the oxlint and oxfmt checks separate
They are different tools and will grow apart, so each keeps its own file as on main.
* build(uncheck): ship the bundle unminified so crash traces stay readable
A stack trace with real names is what users can report back.
* chore(uncheck): require Node 22.20 or later, nothing more
path.matchesGlob, the reason for skipping 23.x and early 24.x, is no longer used.
* docs(uncheck): rewrite the README to be clear, concise and task-first
Organised by what a reader wants to do: check a project, check some files, run it before every
commit, run it after every agent turn, then monorepos, presets and troubleshooting. Every
example was run against the CLI. Also fixes the licence badge, which linked to a missing file.
* docs(uncheck): say that a tsconfig.json without TypeScript fails rather than being skipped1 parent 2c035ee commit 8bc75fb
28 files changed
Lines changed: 2738 additions & 899 deletions
File tree
- packages/uncheck
- src
- checks
- commands
- hooks
- tests
- tsconfig/middleapi
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
58 | 59 | | |
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
63 | 64 | | |
64 | 65 | | |
65 | | - | |
66 | | - | |
| 66 | + | |
| 67 | + | |
67 | 68 | | |
68 | 69 | | |
69 | 70 | | |
| |||
81 | 82 | | |
82 | 83 | | |
83 | 84 | | |
84 | | - | |
| 85 | + | |
85 | 86 | | |
86 | 87 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
| 5 | + | |
| 6 | + | |
9 | 7 | | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
0 commit comments