Repository navigation
Commit f54766b
* Start fix for #1846
Assisted-by: Claude Code:claude-opus-5-5
* Skip comments when reading pnpm lock importers
The check for "does this pnpm lock list workspace members" counted a
`#`-commented importer line as a member, and a column-0 comment ended
the importers section early. It now skips comments, accepts tab-led
lines, and gains a whole-text entry point so the second, hand-split
copy in pnpm_workspace can go (#1846).
Assisted-by: Claude Code:claude-opus-5-5
* Read pnpm brace and class workspace globs
A pnpm-workspace.yaml listing members as `packages/{a,b}` or
`packages/[ab]*` was refused by every non-hosted membership check,
or (when deciding which workspace file governs a project) treated as
listing every directory, even though pnpm installs exactly those
members and the shared glob matcher already reads that syntax. Hosted
mode kept its own second reader to work around the refusal.
Now one reader answers for all callers: brace sets and plain classes
of letters, digits, `_` and `-` match as pnpm 10.28 reads them, and
the member walk expands braces and widens classes before narrowing.
Syntax pnpm reads its own way stays refused: `[!a]` (pnpm reads it
as `[a]`), `[^a]` and `[.]` (they match a leading dot), POSIX classes
and extglob groups. The hosted fallback reader and the duplicate
lock-importer detector are gone (#1846).
Assisted-by: Claude Code:claude-opus-5-5
* Use an extglob as the unmodeled pnpm glob
The hosted/in-memory parity test used `packages/{a,b}` as its example
of a pnpm glob socket-patch cannot read. Brace sets are now read
(#1846), so the case uses an extglob group, which is still refused.
Assisted-by: Claude Code:claude-opus-5-5
* Refuse pnpm globs pnpm reads as regex or escape
Review on #1846: beside a class or brace set, pnpm reads `+` as a
quantifier (`packages/[ab]+` lists `packages/ab`) and `\` as an
escape (`packages/\[a]` lists only a directory named `[a]`), while
the shared matcher reads `+` literally and `\` as a separator. Those
globs are refused again, in each brace alternative too, instead of
answering "not a member". Globs without classes or braces read as
before.
The member walk now applies one directory bound across every brace
alternative, so a brace glob can no longer collect many times more
candidates than the limit. Each candidate also skips the repeated
syntax check.
Assisted-by: Claude Code:claude-opus-5-5
* Refuse pnpm class ranges that start at a dash
A class range from `-` (as in `packages/[--9]h`) spans `.` and `/`,
so pnpm can match a hidden directory that the shared matcher never
does. Such classes are refused now. A literal `-` (`[-a]`) and ranges
between letters, digits and `_` stay readable.
Assisted-by: Claude Code:claude-opus-5-5
* Refuse pnpm brace shapes that pnpm reads differently
pnpm 10.28.0 reads braces as picomatch does, not as brace-expansion
does. So modeled() accepted three shapes whose members differ from
what pnpm lists:
- a stepped or multi-character sequence: `p{1..10}` lists p0 and p1
under pnpm, not p10;
- a `*` or `?` inside braces: `{a,*}` lists dot directories under pnpm;
- an empty alternative: `packages/{a,}` listed `packages` itself.
Refuse these shapes, as the rest of modeled() already does for syntax
pnpm reads its own way, instead of guessing a member set that would
reach member_dirs and the hosted governing root.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Cap the brace alternatives pnpm member_dirs walks
member_dirs walks the tree once for each brace alternative, and the
directory bound only counts matches, so an alternative that matches
nothing walks the whole tree without ever reaching it. A scanned repo's
pnpm-workspace.yaml could list up to 4095 alternatives (for example
**/{a..z}{a..z}{a..e}) and stall the scan for minutes on a modest tree.
Allow at most 64 alternatives over all globs and answer Err beyond
that, which callers already treat as no answer.
Refs #1846
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011f9aeRR24V93EPLyuXR8tp
* Count only brace walks against pnpm walk cap
The cap on how many tree walks a pnpm-workspace.yaml can ask for also
counted globs without braces. A workspace listing more than 64 plain
`packages:` entries, which large monorepos do, failed member-lock
discovery, though main walks those without a cap. Only the extra walks
brace sets add now count; a plain glob is one walk, as before.
Assisted-by: Claude Code:claude-opus-5-5
* Refuse pnpm brace ranges across punctuation
A brace sequence with single-character ends that are not the same
kind stepped through punctuation: `packages/{-..0}` expanded through
`.` and `/`, listing `packages` itself as a member, and `{0..Z}`
through `?`, which the walk then read as a wildcard. A sequence now
needs both ends to be digits, both lowercase or both uppercase.
Found in the final review of #1863.
Assisted-by: Claude Code:claude-opus-5-5
* Refuse pnpm brace sets pnpm reads as sequences or class members
pnpm 10.28 expands a `..` inside a comma brace set as a sequence
(`packages/{a,b..c}` lists `,` `0` `A` `[` ...), and reads braces inside a
class as class members (`packages/[a{b,c}]` lists `,` `{` `}`). modeled()
accepted both and listed a different member set, where the rule is to
refuse syntax we don't read the way pnpm does. Refuse any alternative
holding `..` beside a comma, and check classes on the raw glob too.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011f9aeRocMg7S8GHB43bJsX
* Test pnpm brace groups without a comma stay literal
pnpm 10.28 keeps a brace group with no top-level comma or `..`
literal, also around a nested set: `packages/{app-{web,api}}` lists
only a directory named `{app-web}`, never `app-web`. The shared
matcher reads it the same way; this pins that.
Assisted-by: Claude Code:claude-opus-5-5
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 81ae437 commit f54766b
4 files changed
Lines changed: 432 additions & 55 deletions
File tree
- crates
- socket-patch-cli/tests
- socket-patch-core/src
- hosted
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1616 | 1616 | | |
1617 | 1617 | | |
1618 | 1618 | | |
1619 | | - | |
| 1619 | + | |
| 1620 | + | |
1620 | 1621 | | |
1621 | 1622 | | |
1622 | 1623 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
693 | 693 | | |
694 | 694 | | |
695 | 695 | | |
696 | | - | |
697 | | - | |
698 | | - | |
699 | | - | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
700 | 702 | | |
701 | 703 | | |
702 | 704 | | |
| |||
730 | 732 | | |
731 | 733 | | |
732 | 734 | | |
733 | | - | |
734 | | - | |
| 735 | + | |
735 | 736 | | |
736 | 737 | | |
737 | 738 | | |
| |||
740 | 741 | | |
741 | 742 | | |
742 | 743 | | |
743 | | - | |
744 | | - | |
745 | | - | |
746 | | - | |
747 | | - | |
748 | | - | |
749 | | - | |
750 | | - | |
751 | | - | |
752 | | - | |
753 | | - | |
754 | | - | |
755 | | - | |
756 | | - | |
757 | | - | |
758 | | - | |
759 | | - | |
760 | | - | |
761 | | - | |
762 | | - | |
763 | | - | |
764 | | - | |
765 | | - | |
766 | | - | |
767 | | - | |
768 | 744 | | |
769 | 745 | | |
770 | 746 | | |
| |||
1388 | 1364 | | |
1389 | 1365 | | |
1390 | 1366 | | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
1391 | 1408 | | |
1392 | 1409 | | |
1393 | 1410 | | |
| |||
0 commit comments