fix(uncheck): review the whole package: safer hooks, tsc selection like tsc, faster runs, clearer docs - #12
Merged
Merged
Conversation
…anager 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
… 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.
…t paths, argv batches and killed tools Also lets the middleapi tsconfig preset accept the .ts imports Node's type stripping needs.
…ed and preset versions
…taged 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.
…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
…ry 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
…ees 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
…the staged, prepare, hooks and tsc changes
- 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
- 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
- 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
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.
|
Run failed. View the logs →
|
commit: |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
They are different tools and will grow apart, so each keeps its own file as on main.
A stack trace with real names is what users can report back.
path.matchesGlob, the reason for skipping 23.x and early 24.x, is no longer used.
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.
There was a problem hiding this comment.
ℹ️ No critical issues — one minor documentation fix inline.
Reviewed changes
Re-reviewed the README rewrite pushed after the prior head (2491be9 → 40c86a9); the documentation's claims were cross-checked against the current implementation.
- Rewritten
packages/uncheck/README.mdaround what a reader wants to do — install, check a project, check some files, run before every commit, run after every agent turn, monorepos, presets, troubleshooting. - Fixed the licence badge to link to
LICENCE, the file that exists. - Consolidated the duplicated usage, agent and tsconfig blocks into tables, and documented the
uncheck/tsconfig/middleapiand/libexports.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
…er than being skipped
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

A full review of the
uncheckpackage, with every finding reproduced before it was fixed.uncheck stagedno longer loses or mis-stages work in the git situations it used to break on,preparestops writing into hooks it should not touch, agent hooks stop damaging settings and always check the right folder, and tsc runs exactly the projects tsc itself would check. The README is rewritten to be shorter and task-first.Breaking changes
hooks installagent: its hook can neither show the report nor send Cascade back.npx --no,bunx --no-installandyarn run --silent(-Tin Yarn 2+ where needed), so a missing install fails instead of downloading uncheck. Re-runningprepareorhooks installupgrades old lines in place.hooks runwithout--cwdchecks from the top of the git repository; installs below it write--dir=<folder>.uncheck staged, since its fixes touch other manifests and the lockfile.oxlint >=1.60,sherif >=1.10. Node>=22.20is now the whole requirement.Fixes
.gitattributes,core.safecrlf, sparse checkouts, symlinks, type changes and post-checkout hooks are handled.core.hooksPath, non-shell, binary or unreadable hooks, or folder namesshwould misread.extendsare selected like tsc does.tsc -pruns with--noEmit.!or-are checked, colours follow Node's rules, and platform errors print cleanly.--wizardand--log-level, which did nothing, are gone.Performance
stagedspawns fewer git processes and runs independent ones together; file filtering on large projects is several times faster.Docs
Testing
git commitruns through the hook, signal handling, concurrent installs, old git and Yarn PnP.