Skip to content

feat: add src/regex.ts core module + aggregate() regex filter#113

Merged
shouze merged 13 commits intomainfrom
feat/regex-core
Mar 13, 2026
Merged

feat: add src/regex.ts core module + aggregate() regex filter#113
shouze merged 13 commits intomainfrom
feat/regex-core

Conversation

@shouze
Copy link
Contributor

@shouze shouze commented Mar 12, 2026

Summary

Part of #110closes #111.

Implements the pure-function core that enables regex query support in github-code-search. The GitHub REST API does not support /pattern/ syntax, so we work around it by:

  1. Detecting regex syntax in the query
  2. Deriving a safe literal search term to send to the GitHub API
  3. Filtering API results locally with the original regex

No I/O, no side effects — only pure functions eligible for unit testing.

What changed

src/regex.ts (new)

Two public exports:

isRegexQuery(q) — returns true if the query contains a /pattern/ or /pattern/flags token.

buildApiQuery(q) — deterministic algorithm:

Input apiQuery Logic
/from.*['"]axios/ axios Longest [a-zA-Z0-9_-] sequence outside [...], escapes, metacharacters
/TODO|FIXME|HACK/ TODO OR FIXME OR HACK Top-level alternation → GitHub OR operator
/require\(['"]old-lib['"]\)/ old-lib Longest literal
filename:package.json /["']axios["']:/ filename:package.json axios Qualifiers preserved, regex term extracted
/[~^]?[0-9]+\.[0-9]+/ "" + warn No exploitable literal
/[/ (invalid) "" + warn + null filter Invalid regex
plain text plain text No-op passthrough

g flag is stripped (GitHub doesn't return all inline occurrences). i and other flags are kept and applied client-side.

src/aggregate.ts

Added optional regexFilter?: RegExp parameter to aggregate(). When set, a CodeMatch is kept only if at least one TextMatch.fragment matches the regex. Existing callers unaffected (parameter is optional).

src/regex.test.ts (new) — 22 test cases

All acceptance criteria from the issue covered: literal extraction, top-level alternation, qualifier preservation, flag handling, warn cases, invalid regex, plain-text passthrough.

src/aggregate.test.ts

6 new cases covering the regexFilter parameter: keep/exclude by fragment match, multi-fragment, case-insensitive flag, empty textMatches array, backward-compat (undefined filter).

How to test

bun test src/regex.test.ts src/aggregate.test.ts
bun test        # full suite — 639 pass
bun run lint    # 0 errors
bun run knip    # no unused exports

Notes for reviewer

  • longestLiteralSequence only accumulates [a-zA-Z0-9_-] — this is intentional. Punctuation that looks like a literal (e.g. \() produces poor GitHub search terms and is excluded.
  • Character classes [...] are skipped entirely (content like 0-9 is useless as a search term).
  • The >= comparison when updating best means later sequences of equal length win — this ensures old-lib beats require in /require\(['"]old-lib['"]\)/.

Next

#112 wires this into the CLI (searchAction), adds --regex-hint, UX messaging, docs and C4 diagram update.

- isRegexQuery(): detects /pattern/flags token in query string
- buildApiQuery(): derives a safe GitHub API query from a regex query
  - top-level alternation A|B|C → "A OR B OR C" (GitHub OR operator)
  - otherwise: longest word-char literal sequence outside [...], escapes, metacharacters
  - qualifier tokens (filename:, language:, path:) preserved unchanged
  - <3 char result → warn (caller must use --regex-hint)
  - invalid regex → null filter + warn
- aggregate(): new optional regexFilter parameter filters CodeMatch entries
  by testing at least one TextMatch.fragment against the RegExp

Closes #111
Part of #110
Copilot AI review requested due to automatic review settings March 12, 2026 12:53
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.47%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts98.50%100%100%98.39%117, 217
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a pure, testable core for regex-style queries (/pattern/flags) by extracting an API-safe literal term while returning a RegExp for local post-filtering, plus a new optional regexFilter capability in aggregation.

Changes:

  • Added src/regex.ts with isRegexQuery() and buildApiQuery() for regex token detection, API query derivation, and local RegExp compilation.
  • Extended aggregate() with an optional regexFilter?: RegExp to drop CodeMatch entries whose fragments don’t satisfy the regex.
  • Added/expanded unit tests for regex query parsing/derivation and aggregation filtering behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/regex.ts New core module that detects /.../flags, derives a GitHub API query term, and returns a compiled RegExp for local filtering.
src/regex.test.ts New unit tests validating regex detection, API term derivation (literal/OR), qualifier handling, flags, and warn/invalid cases.
src/aggregate.ts Adds optional regexFilter support to filter matches by textMatches.fragment.
src/aggregate.test.ts Adds coverage for aggregate() behavior with/without a regex filter, multi-fragment cases, flags, and empty fragments.

- regex.ts: strip y (sticky) flag alongside g to prevent stateful
  RegExp.test() across independent fragments
- regex.ts: preserve all non-regex tokens (free-text and qualifiers alike)
  in buildApiQuery — previously only qualifier-prefixed tokens were kept,
  silently dropping terms like 'useFeatureFlag NOT deprecated'
- regex.ts: fix splitTopLevelAlternation escape detection — replace
  prev==='\\' check with an 'escaped' boolean so that \\|foo correctly
  identifies | as top-level (the double backslash escapes a backslash,
  not the pipe)
- aggregate.ts: reset regexFilter.lastIndex = 0 before each .test() call
  to avoid false negatives with global/sticky regexes
- regex.test.ts: add .toBe(true) to the missing assertion (line 16)
- regex.test.ts: fix test description for qualifier-preservation case
  (remove non-existent :\s*\" from name)
- regex.test.ts: add tests for y-flag stripping, free-text preservation,
  and escaped-backslash-before-pipe corner case
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.28%100%100%99.22%225
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

- regex.ts: raise branch length threshold from >= 1 to >= 3 in
  extractApiTerm — short branches like /a|bc/ now fall through to the
  longest-literal path which enforces the existing '< 3 chars → warn'
  rule, preventing extremely broad API queries such as 'a OR bc'
- aggregate.ts: align regexFilter type with buildApiQuery return value;
  accept RegExp | null | undefined (via RegExp | null optional param) and
  update guard from !== undefined to != null so callers can pass the
  result of buildApiQuery directly without a null→undefined conversion
- regex.test.ts: add test for short-branch alternation fallback (/a|bc/)
- aggregate.test.ts: add test for null regexFilter treated as no-op
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.28%100%100%99.22%227
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

The flag character class now includes all current JS RegExp flags:
g i m s u y (already present) + d (hasIndices, ES2022) and v
(unicodeSets, ES2023). The comment is updated to list them explicitly.

This ensures /pattern/s (dotAll), /pattern/d, and /pattern/v are
tokenized correctly and the regex token is replaced in the API query
rather than left as a raw /.../flags string unsafe for the GitHub API.

Add test case for /pattern/s to assert the flag is recognized and the
API query is correctly derived.

Closes review comment on PR #113
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.28%100%100%99.22%229
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

…stIndex leak

src/regex.ts — extractRegexToken():
- Exclude \r and \n from the character class ([^/\\] → [^/\\\r\n])
  so the comment ("doesn't contain unescaped newlines") matches reality.
- Add (?=$|\s) end-of-token boundary after the flags so a word like
  /useState/iSomething is not mis-tokenised (the non-flag suffix stops
  the match before it can anchor to whitespace/end-of-string).

src/regex.test.ts:
- isRegexQuery('/useState/iSomething') → false (boundary regression)
- buildApiQuery('/useState/iSomething') → passthrough, regexFilter null

src/aggregate.ts — aggregate():
- Reset regexFilter.lastIndex = 0 after the some() loop so callers
  that reuse the same RegExp instance don't observe a stale lastIndex
  after aggregate() returns.

src/aggregate.test.ts:
- New test: verify lastIndex is 0 after aggregate() when using /g regex
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.28%100%100%99.22%234
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

…ents

src/regex.ts — extractRegexToken():
- Remove 'e' from the allowed flag set: [gimsuydev]* -> [gimsuydv]*
  'e' is not a valid JavaScript RegExp flag; its presence would cause
  /pattern/e to be tokenised as a regex and then fail compilation,
  instead of being passed through unchanged as a plain query token.

src/regex.ts — splitTopLevelAlternation():
- Clarify truncated inline comments:
    depth: 'tracks unescaped ( nesting'
         → 'tracks unescaped \"(\" nesting depth outside character classes'
    inClass: 'tracks [...]'
           → 'tracks whether we are currently inside a character class [...]'

src/regex.test.ts:
- isRegexQuery('/pattern/e') → false (regression test)
- buildApiQuery('/pattern/e') → passthrough, regexFilter null
@shouze shouze requested a review from Copilot March 12, 2026 20:04
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.28%100%100%99.22%235
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

…warn

src/aggregate.ts — aggregate():
- Capture regexFilter.lastIndex before filtering and restore it afterward
  (instead of hard-coding 0). This ensures aggregate() has no observable
  side effects on the caller's RegExp instance: a caller that set lastIndex
  intentionally before calling aggregate() will find it unchanged on return.

src/aggregate.test.ts:
- Updated test: pre-seed a non-zero lastIndex and assert it is restored
  to that exact value after aggregate() returns (not forced to 0).

src/regex.ts — buildApiQuery():
- Capture the thrown Error and include err.message in the warn string.
  Callers now see the engine's own diagnostic (e.g. 'Invalid regular
  expression: /[/: Unterminated character class') instead of a generic
  'Invalid regex pattern …' that loses the root cause.

src/regex.test.ts:
- Extended the invalid-regex test to assert the raw token (/[/) appears
  in the warn string for easy identification.
@shouze shouze requested a review from Copilot March 12, 2026 20:29
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.54%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.30%100%100%99.24%244
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

… test title

src/regex.ts — longestLiteralSequence():
- Remove 'a' and 'e' from isSpecialEscape. In JS without u/v, \a and \e
  are identity escapes that simply match the literal characters 'a' and 'e',
  so they should be accumulated like any other word char, not break the
  sequence. Only true non-literal regex escapes remain (b, B, d, D, s, S,
  w, W, p, P, u, U, x, X, 0-9, n, r, t, f, v).

src/regex.ts — buildApiQuery():
- Expand the comment explaining why both g and y are stripped:
    g: GitHub returns at most a few fragments, not all occurrences.
    y: sticky makes RegExp.test() stateful via lastIndex.
  Both are intentional; all other flags are kept unchanged.

src/regex.test.ts:
- Fix test title: was missing ']' after first character class
  ('/'['\"axios['\"]:/') → correct ('/['\"']axios['\"]:/'), now
  matching the actual query string under test.
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.54%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.30%100%100%99.24%247
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

The previous split(/\s+/) + join approach would break GitHub quoted phrases
(e.g. "feature flag" /from.*axios/) by splitting 'feature flag' into two
separate tokens and losing the quote grouping.

Fix: use q.replace(raw, term).trim() to replace only the regex token in-place,
leaving every other character in the original query unchanged. This preserves
quoted phrases, extra whitespace handling, and all qualifiers byte-for-byte.

Regression test added:
  '"feature flag" /from.*axios/' → '"feature flag" axios'
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.25%100%100%99.21%242
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

String.replace(raw, term) replaces the first *substring* occurrence of raw,
which can target the wrong position when the same text appears earlier in the
query as a non-token prefix (e.g. '/useState/iSomething /useState/i' — the
string '/useState/i' is a substring of the first token but the actual matched
token is the second one).

Fix:
- Add `index: number` to RegexToken, storing the exact start position of the
  token within the original query (computed from m.index + leading-space offset).
- Use slice-based splice in buildApiQuery():
    q.slice(0, index) + term + q.slice(index + raw.length)
  This replaces only the boundary-validated token at its exact location,
  regardless of whether the same raw text appears elsewhere.

Regression test added:
  '/useState/iSomething /useState/i' → '/useState/iSomething useState'
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.26%100%100%99.21%250
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

@shouze shouze requested a review from Copilot March 13, 2026 09:59
@github-actions
Copy link

Coverage after merging feat/regex-core into main will be

96.53%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.55%100%100%93.86%318–322, 383, 400, 63–69
   cache.ts98.08%100%100%97.87%28
   completions.ts99.35%100%100%99.29%252
   group.ts100%100%100%100%
   output.ts99.12%100%94.74%99.52%58
   regex.ts99.26%100%100%99.21%251
   render.ts94.26%100%89.47%94.49%158, 182–187, 189–191, 193–194, 245–246, 267, 440–441, 523–527
   upgrade.ts88.46%100%94.44%87.89%127–128, 148–155, 158–164, 169, 174, 210–213
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@shouze shouze merged commit c02aaf1 into main Mar 13, 2026
10 checks passed
@shouze shouze deleted the feat/regex-core branch March 13, 2026 10:04
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.

feat: add src/regex.ts core module + aggregate() regex filter

2 participants