Skip to content

Release v0.3.0 (part 1): tinyglobby (#56), empty path: entries (#55), dependency advisories - #57

Merged
jlevy merged 9 commits into
mainfrom
claude/loving-rubin-8wqg92
Oct 4, 2026
Merged

jlevy merged 9 commits into
mainfrom
claude/loving-rubin-8wqg92

Conversation

@jlevy

@jlevy jlevy commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

This is the first half of the v0.3.0 release. The second half, #58, adds requires:. The release was renumbered from v0.2.2 to v0.3.0 at the maintainer's request, since it bundles a runtime dependency swap, broad dependency upgrades, and a new feature. v0.2.2 was never tagged.

This PR clears every open audit finding (one runtime, six dev-only), fixes #55, and applies the dependency bumps that are past the cool-off. No cool-off exception is taken: every resolved version predates the 14-day cutoff (2026-09-20T21:55Z).

tinyglobby needed a discovery layer to keep fast-glob semantics

Using tinyglobby 0.2.17 directly, as #56 proposes, silently drops tests in several ways. findTestFiles handles each one:

  1. A pattern rooted above cwd drops files inside cwd. For example, ../../**/*.tryscript.md from packages/tryscript returned 1 file instead of 33. tinyglobby matches candidates relative to its own cwd. Fix: each positive pattern is globbed separately, from the deepest directory containing cwd and that pattern's static base.
  2. An unreadable directory is skipped silently. fdir suppresses readdir errors; fast-glob threw EACCES. Fix: errors are recorded through tinyglobby's fs adapter, and discovery fails naming the directory (exit 2). Only ENOENT is ignored.
  3. Negations. These are matched to fast-glob's isAffectDepthOfReadingPattern rule:
    • A negation whose last segment is **, a literal name, or a brace list of literal names goes into tinyglobby's ignore list, so the excluded directory is never read.
    • Other negations (!dir/*, or one rooted above a pattern's frame) subtract the files they match.
    • A negation that cannot overlap any positive pattern is not crawled.
  4. Windows UNC roots are preserved when joining bases (posix.join collapsed //server/share).

Parity: against fast-glob 3.3.3, every pattern and negation case under cwd matches. That covers this repo's trees plus the reviewer's adversarial sets: negparity, negadv2, negprune, intermediate, symlinks, ./, a/../b, and a cwd inside dist. Intended differences, all documented in the CHANGELOG and reference:

  • Patterns that climb above cwd (../**) now apply the node_modules/dist ignores and negations, which fast-glob skipped for them.
  • An absolute pattern into a project located under a dist directory now finds its files; fast-glob found nothing.
  • Exclusions do not match inside dot directories unless they name them. This is the same dot rule inclusions use.

Senior review

A delegated senior-engineer review ran three rounds over this PR and #58.

  • Fixed here: discovery read errors, ignore frame, intermediate-directory listing, UNC roots, negation pruning, !dir, brace-list negations, and crawls of non-overlapping negations.
  • Remaining: none open. Two Low items became follow-up beads: broadening Windows CI, and a single definition for requires validation.

Supply-chain review

  • New runtime dependencies: tinyglobby 0.2.17 (trusted publishing and provenance), fdir 6.5.0, picomatch 4.0.7. None runs lifecycle scripts, and each keeps its previous publisher. The picomatch 4.0.5 → 4.0.7 diff touches only the parser.
  • Held back:
    • eslint ≥ 10.10, which pulls in file-entry-cache 11 → flat-cache → cacheable → keyv (the keyv worm family).
    • tsx 4.23.15, which repackages its dist two hours after 4.23.14.
  • Avoided: pnpm update --depth Infinity would also have dragged in rollup 4.63.4 and postcss.

Validation plan

Closes #55
Closes #56

🤖 Generated with Claude Code

https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD

claude added 4 commits October 4, 2026 22:13
An unset variable in a `path:` entry expanded to '' and then resolved
from the test file's directory, so a bare `$TOOL_DIR` silently put the
test directory on PATH. Drop such entries instead. Also stop appending
an empty element when no PATH is inherited, since POSIX reads an empty
element as the working directory.

Closes #55

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
fast-glob reaches braces through micromatch, and braces <=3.0.3 has an
unpatched high-severity advisory (GHSA-vfj7-8cjw-p6xm / CVE-2026-93687)
that fails `npm audit` in every project depending on tryscript.
tinyglobby matches through picomatch, which has no braces dependency.

Discovery moves to src/lib/discovery.ts. tinyglobby 0.2.17 matches
candidate paths relative to its cwd, so a pattern rooted above cwd
(`../**/x`, or an absolute pattern run from a subdirectory) silently
drops every file inside cwd. findTestFiles therefore globs from the
deepest directory containing cwd and every pattern's static base, with
patterns rewritten relative to it. expandDirectories is off to keep
fast-glob's directory semantics.

Patterns under cwd select the same files as fast-glob 3.3.3 (checked on
this repository and on a fixture tree). Deliberate edge-case changes:
`../` patterns now skip node_modules/dist and honor negations, and an
absolute pattern no longer matches nothing when a directory above cwd
is named dist or node_modules.

The micromatch>picomatch override is removed; micromatch has left the
tree. tinyglobby 0.2.17 was published 2026-05-30 via trusted publishing
with provenance and has no lifecycle scripts.

Closes #56

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
Advisories (dev-only; none reaches the published package):
- vitest, @vitest/coverage-v8 4.1.10 -> 4.1.11 (GHSA-82fw-gwwq-j7x9)
- brace-expansion -> 5.0.12 via one range override, replacing the two
  version-keyed minimatch edges (GHSA-qhr7-859c-m2p7,
  GHSA-6j4f-fj2g-mc7p, GHSA-q2hr-2g5m-vwhr)
- @humanfs/node -> 0.16.8 via a floor override (GHSA-p498-v437-472g).
  `pnpm update --depth Infinity` also pulled rollup 4.63.4 and postcss,
  so an override keeps the lockfile delta to the advisory.

Tooling, same publishers, no new dependencies: typescript-eslint 8.70.0,
prettier 3.9.8, publint 0.3.24, lefthook 2.1.14.

The picomatch 4 override becomes a floor (<4.0.5) instead of pinning
every 4.x, so re-resolution can reach the 4.0.7 consumers already get.
The minimumReleaseAgeExclude entries for brace-expansion@5.0.9 and
nanoid@3.3.18 are removed; both are past the cool-off.

Every version is older than the 14-day cool-off (cutoff
2026-09-20T21:55Z), so no exception is taken. Held back: eslint >=10.10
(adds file-entry-cache 11 -> flat-cache -> cacheable -> keyv) and tsx
4.23.15 (repackaged dist, no advisory against 4.23.1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
@deepsource-io

deepsource-io Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 1ffbe8f...5527761 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
Secrets Oct 4, 2026 11:17p.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 97.46% 5333 / 5472
🔵 Statements 97.46% 5333 / 5472
🔵 Functions 63.78% 162 / 254
🔵 Branches 55.1% 826 / 1499
File CoverageNo changed files found.
Generated in workflow #189 for commit 5527761 by the Vitest Coverage Report Action

fdir, which tinyglobby crawls with, suppresses readdir errors, so a
directory the user cannot read silently dropped its tests and the run
could exit 0. fast-glob 3.3.3 threw EACCES there. Record readdir errors
through tinyglobby's fs adapter and fail with the directory and code,
ignoring only ENOENT (removed mid-crawl), as fast-glob did.

Verified as an unprivileged user against the packed tarball: a `**`
pattern over an EACCES directory exits 2 naming it; a pattern that
does not traverse it still runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
@jlevy
jlevy added this pull request to stack #59 October 4, 2026 22:47
@jlevy
jlevy marked this pull request as ready for review October 4, 2026 22:48
claude added 4 commits October 4, 2026 23:01
Review follow-up. Globbing every pattern from one common ancestor had
two side effects: the node_modules/dist ignores applied relative to
that ancestor, so a cwd inside dist lost its own matches as soon as
another pattern climbed above it (silently); and tinyglobby listed
directories between the patterns' bases, which fast-glob never read,
so an unlistable parent (mode 0711) newly failed the run.

Each positive pattern is now globbed separately from the deepest
directory containing cwd and its own base; negations remove the files
they match as patterns of their own. Bases are joined below the root
without posix.join, which collapsed UNC roots (//server/share).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
The release bundles a runtime dependency swap and broad dependency
upgrades, and the stacked requires: feature, so it is a minor release.
v0.2.2 was never tagged or published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
Second review follow-up. Subtracting every negation's matches after
the fact (032d590) stopped `!dir/**` from pruning the crawl, so an
excluded tree was walked twice and an unreadable path inside it failed
the run, and `!dir` no longer excluded the directory.

Negations whose last segment is `**` or a literal name now go to
tinyglobby's ignore list for each pattern whose frame contains them,
so excluded directories are never read, matching fast-glob's
isAffectDepthOfReadingPattern rule. Other negations (`!dir/*`, or one
rooted above a pattern's frame) still subtract the files they match,
and their read errors are ignored since they can only remove matches.

Against fast-glob 3.3.3, every negation case under cwd now matches
except exclusions into dot directories, which follow the same dot rule
as inclusions and are documented.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
Third review follow-up. fast-glob expanded braces before deciding
which negations prune, so `!{fixtures,tmp}` excluded both directories;
here the brace segment counted as dynamic and only subtracted files.
A negation whose last segment is a brace list of literal names is now
split into one negation per name before classification.

A negation whose base neither contains nor sits inside any positive
pattern's base cannot remove anything, so it is no longer crawled
(`!../vendor/**` read the whole tree for nothing).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5x8Ticwm5ZY4j2DLhCbXD
@jlevy jlevy changed the title Release v0.2.2: tinyglobby (#56), empty path: entries (#55), dependency advisories Release v0.3.0 (part 1): tinyglobby (#56), empty path: entries (#55), dependency advisories Oct 4, 2026
@jlevy
jlevy merged commit a326a9f into main Oct 4, 2026
4 checks passed
@jlevy
jlevy deleted the claude/loving-rubin-8wqg92 branch October 4, 2026 23:21
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.

Replace fast-glob with tinyglobby to drop braces (GHSA-vfj7-8cjw-p6xm) An unset variable in path: puts the working directory on PATH

2 participants