Skip to content

feat(glob): add brace expansion, fix backslash escaping, and lower match cap#282

Merged
sailist merged 2 commits into
mainfrom
haozhe/glob-fix
Jun 1, 2026
Merged

feat(glob): add brace expansion, fix backslash escaping, and lower match cap#282
sailist merged 2 commits into
mainfrom
haozhe/glob-fix

Conversation

@sailist
Copy link
Copy Markdown
Collaborator

@sailist sailist commented Jun 1, 2026

Summary

This PR adds brace expansion support to the Glob tool, fixes backslash escaping in glob patterns, and replaces up-front rejection of broad patterns with a lower match-count cap.


1. Add brace expansion support to Glob tool

Problem: The Glob tool previously rejected brace expansion patterns (e.g., *.{ts,tsx}, {src,test}/**) outright, forcing callers to manually split into separate calls. This added friction and wasted caller context.

What was done:

  • Implemented recursive expandBraces() that supports cartesian products and one level of nesting.
  • Added MAX_BRACE_EXPANSIONS = 64 cap to prevent pathological fan-out.
  • Updated the tool description (glob.md) to document brace expansion support.
  • Updated truncation messages to include the total number of matches seen so far.

2. Fix backslash escaping in glob patterns

Problem: Backslash (\) was not treated as a proper escape character in globPatternToRegex, and trailing backslashes inside character classes like [abc\\] could produce invalid regexes.

What was done:

  • Added backslash-as-escape handling in kaos/src/internal.ts that advances past the escaped character.
  • Escaped backslashes inside character classes before closing ] to keep the regex valid.
  • Added corresponding tests in packages/kaos/test/internal.test.ts.

3. Replace pre-rejection with match-count cap

Problem: Patterns starting with **/ or consisting of pure wildcards were hard-rejected before any walk happened. This was overly restrictive and inconsistent with other implementations.

What was done:

  • Removed startsWithDoubleStarPrefix(), isPureWildcard(), and containsBraceExpansion() pre-rejections.
  • Lowered MAX_MATCHES from 1000 to 100 — the cap itself is now the single safety rail.
  • Updated all tests to reflect the new behavior (walk instead of reject).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • Ran gen-changesets skill.
  • Ran gen-docs skill.

- add brace expansion support for glob patterns with up to 64 sub-pattern cap\n- remove up-front rejection of pure-wildcard and **/ prefix patterns; rely on 100-match cap\n- fix backslash escape handling in globPatternToRegex and inside character classes\n- include matched count in truncation messages\n- show glob pattern, path, and include_dirs in TUI tool-call headers
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 1, 2026

🦋 Changeset detected

Latest commit: f4aa305

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@moonshot-ai/kaos Patch
@moonshot-ai/agent-core Patch
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 1, 2026

pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@f4aa305
npx https://pkg.pr.new/@moonshot-ai/kimi-code@f4aa305

commit: f4aa305

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf9bd45811

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

case '\\': {
if (i + 1 < pattern.length) {
const next = pattern[i + 1];
regex += next.replaceAll(/[{}()+.\\[\]^$|]/g, '\\$&');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape escaped wildcard metacharacters

When a glob pattern uses a backslash to match a literal wildcard, e.g. \*.ts or \?name, this branch appends the raw */? into the regex because the escape set omits those regex metacharacters. That makes new RegExp('^*$') / new RegExp('^?$') throw “Nothing to repeat”, so kaos.glob errors instead of matching files whose names literally contain * or ?; include * and ? in the escaped-character regex here.

Useful? React with 👍 / 👎.

const seen = new Set<string>();
const entries: Array<{ path: string; mtime: number }> = [];
const YIELD_SAFETY_CAP = MAX_MATCHES * 2;
const YIELD_SAFETY_CAP = MAX_MATCHES * 2 * subPatterns.length;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don’t truncate file-only glob results on skipped directories

When include_dirs is false and the pattern yields directories before files (for example Glob with pattern: "**" in a directory-heavy workspace), this raw-yield cap is now only 200 for a single subpattern and counts directories that are filtered out later. In that case the loop can stop with a truncation header and few or no returned files even though matching files exist below; keep the cycle-safety cap independent of the 100 returned-file limit or count it after filtered directories are skipped.

Useful? React with 👍 / 👎.

@sailist sailist merged commit a580cd3 into main Jun 1, 2026
8 checks passed
@sailist sailist deleted the haozhe/glob-fix branch June 1, 2026 13:36
@github-actions github-actions Bot mentioned this pull request Jun 1, 2026
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.

1 participant