Ripgrep Skill <identity Enhanced code search with ripgrep binary. NOTE: Prefer for discovery/ranking and smaller output payloads; prefer raw for fastest exact literal matching. </identity <capabilities - Hybrid code search via (BM25 text + semantic vector ranking) - Raw ripgrep for exhaustive pattern sweeps (every match, not ranked top-N) - Advanced regex patterns (PCRE2 with -P flag) - Custom file type definitions via .ripgreprc - Integration with .gitignore and custom ignore patterns </capabilities ⚡ RECOMMENDED: Hybrid Code Search Use the hybrid search system for day-to-day code discovery:…

README.md -r FAST\n75:FAST\n88:FAST\n119:FAST\n124:FAST\n129:FAST\n```\n\nAlternatively, you can combine the `--only-matching` (or `-o` for short) with\nthe `--replace` flag to achieve the same result:\n\n```\n$ rg fast README.md --only-matching --replace FAST\n75:FAST\n88:FAST\n119:FAST\n124:FAST\n129:FAST\n```\n\nor, more succinctly,\n\n```\n$ rg fast README.md -or FAST\n[snip]\n```\n\nFinally, replacements can include capturing groups. For example, let's say\nwe wanted to find all occurrences of `fast` followed by another word and\njoin them together with a dash. The pattern we might use for that is\n`fast\\s+(\\w+)`, which matches `fast`, followed by any amount of whitespace,\nfollowed by any number of \"word\" characters. We put the `\\w+` in a \"capturing\ngroup\" (indicated by parentheses) so that we can reference it later in our\nreplacement string. For example:\n\n```\n$ rg 'fast\\s+(\\w+)' README.md -r 'fast-$1'\n88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while\n124:Summarizing, `ripgrep` is fast-because:\n```\n\nOur replacement string here, `fast-$1`, consists of `fast-` followed by the\ncontents of the capturing group at index `1`. (Capturing groups actually start\nat index 0, but the `0`th capturing group always corresponds to the entire\nmatch. The capturing group at index `1` always corresponds to the first\nexplicit capturing group found in the regex pattern.)\n\nCapturing groups can also be named, which is sometimes more convenient than\nusing the indices. For example, the following command is equivalent to the\nabove command:\n\n```\n$ rg 'fast\\s+(?P\u003cword>\\w+)' README.md -r 'fast-$word'\n88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while\n124:Summarizing, `ripgrep` is fast-because:\n```\n\nIt is important to note that ripgrep **will never modify your files**. The\n`--replace` flag only controls ripgrep's output. (And there is no flag to let\nyou do a replacement in a file.)\n\n### Configuration file\n\nIt is possible that ripgrep's default options aren't suitable in every case.\nFor that reason, and because shell aliases aren't always convenient, ripgrep\nsupports configuration files.\n\nSetting up a configuration file is simple. ripgrep will not look in any\npredetermined directory for a config file automatically. Instead, you need to\nset the `RIPGREP_CONFIG_PATH` environment variable to the file path of your\nconfig file. Once the environment variable is set, open the file and just type\nin the flags you want set automatically. There are only two rules for\ndescribing the format of the config file:\n\n1. Every line is a shell argument, after trimming whitespace.\n2. Lines starting with `#` (optionally preceded by any amount of whitespace)\n are ignored.\n\nIn particular, there is no escaping. Each line is given to ripgrep as a single\ncommand line argument verbatim.\n\nHere's an example of a configuration file, which demonstrates some of the\nformatting peculiarities:\n\n```\n$ cat $HOME/.ripgreprc\n# Don't let ripgrep vomit really long lines to my terminal, and show a preview.\n--max-columns=150\n--max-columns-preview\n\n# Add my 'web' type.\n--type-add\nweb:*.{html,css,js}*\n\n# Search hidden files / directories (e.g. dotfiles) by default\n--hidden\n\n# Using glob patterns to include/exclude files or folders\n--glob=!.git/*\n\n# or\n--glob\n!.git/*\n\n# Set the colors.\n--colors=line:none\n--colors=line:style:bold\n\n# Because who cares about case!?\n--smart-case\n```\n\nWhen we use a flag that has a value, we either put the flag and the value on\nthe same line but delimited by an `=` sign (e.g., `--max-columns=150`), or we\nput the flag and the value on two different lines. This is because ripgrep's\nargument parser knows to treat the single argument `--max-columns=150` as a\nflag with a value, but if we had written `--max-columns 150` in our\nconfiguration file, then ripgrep's argument parser wouldn't know what to do\nwith it.\n\nPutting the flag and value on different lines is exactly equivalent and is a\nmatter of style.\n\nComments are encouraged so that you remember what the config is doing. Empty\nlines are OK too.\n\nSo let's say you're using the above configuration file, but while you're at a\nterminal, you really want to be able to see lines longer than 150 columns. What\ndo you do? Thankfully, all you need to do is pass `--max-columns 0` (or `-M0`\nfor short) on the command line, which will override your configuration file's\nsetting. This works because ripgrep's configuration file is _prepended_ to the\nexplicit arguments you give it on the command line. Since flags given later\noverride flags given earlier, everything works as expected. This works for most\nother flags as well, and each flag's documentation states which other flags\noverride it.\n\nIf you're confused about what configuration file ripgrep is reading arguments\nfrom, then running ripgrep with the `--debug` flag should help clarify things.\nThe debug output should note what config file is being loaded and the arguments\nthat have been read from the configuration.\n\nFinally, if you want to make absolutely sure that ripgrep _isn't_ reading a\nconfiguration file, then you can pass the `--no-config` flag, which will always\nprevent ripgrep from reading extraneous configuration from the environment,\nregardless of what other methods of configuration are added to ripgrep in the\nfuture.\n\n### File encoding\n\n[Text encoding](https://en.wikipedia.org/wiki/Character_encoding) is a complex\ntopic, but we can try to summarize its relevancy to ripgrep:\n\n- Files are generally just a bundle of bytes. There is no reliable way to know\n their encoding.\n- Either the encoding of the pattern must match the encoding of the files being\n searched, or a form of transcoding must be performed that converts either the\n pattern or the file to the same encoding as the other.\n- ripgrep tends to work best on plain text files, and among plain text files,\n the most popular encodings likely consist of ASCII, latin1 or UTF-8. As\n a special exception, UTF-16 is prevalent in Windows environments\n\nIn light of the above, here is how ripgrep behaves when `--encoding auto` is\ngiven, which is the default:\n\n- All input is assumed to be ASCII compatible (which means every byte that\n corresponds to an ASCII codepoint actually is an ASCII codepoint). This\n includes ASCII itself, latin1 and UTF-8.\n- ripgrep works best with UTF-8. For example, ripgrep's regular expression\n engine supports Unicode features. Namely, character classes like `\\w` will\n match all word characters by Unicode's definition and `.` will match any\n Unicode codepoint instead of any byte. These constructions assume UTF-8,\n so they simply won't match when they come across bytes in a file that aren't\n UTF-8.\n- To handle the UTF-16 case, ripgrep will do something called \"BOM sniffing\"\n by default. That is, the first three bytes of a file will be read, and if\n they correspond to a UTF-16 BOM, then ripgrep will transcode the contents of\n the file from UTF-16 to UTF-8, and then execute the search on the transcoded\n version of the file. (This incurs a performance penalty since transcoding\n is needed in addition to regex searching.) If the file contains invalid\n UTF-16, then the Unicode replacement codepoint is substituted in place of\n invalid code units.\n- To handle other cases, ripgrep provides a `-E/--encoding` flag, which permits\n you to specify an encoding from the\n [Encoding Standard](https://encoding.spec.whatwg.org/#concept-encoding-get).\n ripgrep will assume _all_ files searched are the encoding specified (unless\n the file has a BOM) and will perform a transcoding step just like in the\n UTF-16 case described above.\n\nBy default, ripgrep will not require its input be valid UTF-8. That is, ripgrep\ncan and will search arbitrary bytes. The key here is that if you're searching\ncontent that isn't UTF-8, then the usefulness of your pattern will degrade. If\nyou're searching bytes that aren't ASCII compatible, then it's likely the\npattern won't find anything. With all that said, this mode of operation is\nimportant, because it lets you find ASCII or UTF-8 _within_ files that are\notherwise arbitrary bytes.\n\nAs a special case, the `-E/--encoding` flag supports the value `none`, which\nwill completely disable all encoding related logic, including BOM sniffing.\nWhen `-E/--encoding` is set to `none`, ripgrep will search the raw bytes of\nthe underlying file with no transcoding step. For example, here's how you might\nsearch the raw UTF-16 encoding of the string `Шерлок`:\n\n```\n$ rg '(?-u)\\(\\x045\\x04@\\x04;\\x04>\\x04:\\x04' -E none -a some-utf16-file\n```\n\nOf course, that's just an example meant to show how one can drop down into\nraw bytes. Namely, the simpler command works as you might expect automatically:\n\n```\n$ rg 'Шерлок' some-utf16-file\n```\n\nFinally, it is possible to disable ripgrep's Unicode support from within the\nregular expression. For example, let's say you wanted `.` to match any byte\nrather than any Unicode codepoint. (You might want this while searching a\nbinary file, since `.` by default will not match invalid UTF-8.) You could do\nthis by disabling Unicode via a regular expression flag:\n\n```\n$ rg '(?-u:.)'\n```\n\nThis works for any part of the pattern. For example, the following will find\nany Unicode word character followed by any ASCII word character followed by\nanother Unicode word character:\n\n```\n$ rg '\\w(?-u:\\w)\\w'\n```\n\n### Binary data\n\nIn addition to skipping hidden files and files in your `.gitignore` by default,\nripgrep also attempts to skip binary files. ripgrep does this by default\nbecause binary files (like PDFs or images) are typically not things you want to\nsearch when searching for regex matches. Moreover, if content in a binary file\ndid match, then it's possible for undesirable binary data to be printed to your\nterminal and wreak havoc.\n\nUnfortunately, unlike skipping hidden files and respecting your `.gitignore`\nrules, a file cannot as easily be classified as binary. In order to figure out\nwhether a file is binary, the most effective heuristic that balances\ncorrectness with performance is to simply look for `NUL` bytes. At that point,\nthe determination is simple: a file is considered \"binary\" if and only if it\ncontains a `NUL` byte somewhere in its contents.\n\nThe issue is that while most binary files will have a `NUL` byte toward the\nbeginning of its contents, this is not necessarily true. The `NUL` byte might\nbe the very last byte in a large file, but that file is still considered\nbinary. While this leads to a fair amount of complexity inside ripgrep's\nimplementation, it also results in some unintuitive user experiences.\n\nAt a high level, ripgrep operates in three different modes with respect to\nbinary files:\n\n1. The default mode is to attempt to remove binary files from a search\n completely. This is meant to mirror how ripgrep removes hidden files and\n files in your `.gitignore` automatically. That is, as soon as a file is\n detected as binary, searching stops. If a match was already printed (because\n it was detected long before a `NUL` byte), then ripgrep will print a warning\n message indicating that the search stopped prematurely. This default mode\n **only applies to files searched by ripgrep as a result of recursive\n directory traversal**, which is consistent with ripgrep's other automatic\n filtering. For example, `rg foo .file` will search `.file` even though it\n is hidden. Similarly, `rg foo binary-file` will search `binary-file` in\n \"binary\" mode automatically.\n2. Binary mode is similar to the default mode, except it will not always\n stop searching after it sees a `NUL` byte. Namely, in this mode, ripgrep\n will continue searching a file that is known to be binary until the first\n of two conditions is met: 1) the end of the file has been reached or 2) a\n match is or has been seen. This means that in binary mode, if ripgrep\n reports no matches, then there are no matches in the file. When a match does\n occur, ripgrep prints a message similar to one it prints when in its default\n mode indicating that the search has stopped prematurely. This mode can be\n forcefully enabled for all files with the `--binary` flag. The purpose of\n binary mode is to provide a way to discover matches in all files, but to\n avoid having binary data dumped into your terminal.\n3. Text mode completely disables all binary detection and searches all files\n as if they were text. This is useful when searching a file that is\n predominantly text but contains a `NUL` byte, or if you are specifically\n trying to search binary data. This mode can be enabled with the `-a/--text`\n flag. Note that when using this mode on very large binary files, it is\n possible for ripgrep to use a lot of memory.\n\nUnfortunately, there is one additional complexity in ripgrep that can make it\ndifficult to reason about binary files. That is, the way binary detection works\ndepends on the way that ripgrep searches your files. Specifically:\n\n- When ripgrep uses memory maps, then binary detection is only performed on the\n first few kilobytes of the file in addition to every matching line.\n- When ripgrep doesn't use memory maps, then binary detection is performed on\n all bytes searched.\n\nThis means that whether a file is detected as binary or not can change based\non the internal search strategy used by ripgrep. If you prefer to keep\nripgrep's binary file detection consistent, then you can disable memory maps\nvia the `--no-mmap` flag. (The cost will be a small performance regression when\nsearching very large files on some platforms.)\n\n### Preprocessor\n\nIn ripgrep, a preprocessor is any type of command that can be run to transform\nthe input of every file before ripgrep searches it. This makes it possible to\nsearch virtually any kind of content that can be automatically converted to\ntext without having to teach ripgrep how to read said content.\n\nOne common example is searching PDFs. PDFs are first and foremost meant to be\ndisplayed to users. But PDFs often have text streams in them that can be useful\nto search. In our case, we want to search Bruce Watson's excellent\ndissertation,\n[Taxonomies and Toolkits of Regular Language Algorithms](https://burntsushi.net/stuff/1995-watson.pdf).\nAfter downloading it, let's try searching it:\n\n```\n$ rg 'The Commentz-Walter algorithm' 1995-watson.pdf\n$\n```\n\nSurely, a dissertation on regular language algorithms would mention\nCommentz-Walter. Indeed it does, but our search isn't picking it up because\nPDFs are a binary format, and the text shown in the PDF may not be encoded as\nsimple contiguous UTF-8. Namely, even passing the `-a/--text` flag to ripgrep\nwill not make our search work.\n\nOne way to fix this is to convert the PDF to plain text first. This won't work\nwell for all PDFs, but does great in a lot of cases. (Note that the tool we\nuse, `pdftotext`, is part of the [poppler](https://poppler.freedesktop.org)\nPDF rendering library.)\n\n```\n$ pdftotext 1995-watson.pdf > 1995-watson.txt\n$ rg 'The Commentz-Walter algorithm' 1995-watson.txt\n316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :\n7165:4.4 The Commentz-Walter algorithms\n10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm\n17218:The Commentz-Walter algorithm (and its variants) displayed more interesting behaviour,\n17249:Aho-Corasick algorithms are used extensively. The Commentz-Walter algorithms are used\n17297: The Commentz-Walter algorithms (CW). In all versions of the CW algorithms, a common program skeleton is used with di erent shift functions. The CW algorithms are\n```\n\nBut having to explicitly convert every file can be a pain, especially when you\nhave a directory full of PDF files. Instead, we can use ripgrep's preprocessor\nfeature to search the PDF. ripgrep's `--pre` flag works by taking a single\ncommand name and then executing that command for every file that it searches.\nripgrep passes the file path as the first and only argument to the command and\nalso sends the contents of the file to stdin. So let's write a simple shell\nscript that wraps `pdftotext` in a way that conforms to this interface:\n\n```\n$ cat preprocess\n#!/bin/sh\n\nexec pdftotext - -\n```\n\nWith `preprocess` in the same directory as `1995-watson.pdf`, we can now use it\nto search the PDF:\n\n```\n$ rg --pre ./preprocess 'The Commentz-Walter algorithm' 1995-watson.pdf\n316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :\n7165:4.4 The Commentz-Walter algorithms\n10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm\n17218:The Commentz-Walter algorithm (and its variants) displayed more interesting behaviour,\n17249:Aho-Corasick algorithms are used extensively. The Commentz-Walter algorithms are used\n17297: The Commentz-Walter algorithms (CW). In all versions of the CW algorithms, a common program skeleton is used with di erent shift functions. The CW algorithms are\n```\n\nNote that `preprocess` must be resolvable to a command that ripgrep can read.\nThe simplest way to do this is to put your preprocessor command in a directory\nthat is in your `PATH` (or equivalent), or otherwise use an absolute path.\n\nAs a bonus, this turns out to be quite a bit faster than other specialized PDF\ngrepping tools:\n\n```\n$ time rg --pre ./preprocess 'The Commentz-Walter algorithm' 1995-watson.pdf -c\n6\n\nreal 0.697\nuser 0.684\nsys 0.007\nmaxmem 16 MB\nfaults 0\n\n$ time pdfgrep 'The Commentz-Walter algorithm' 1995-watson.pdf -c\n6\n\nreal 1.336\nuser 1.310\nsys 0.023\nmaxmem 16 MB\nfaults 0\n```\n\nIf you wind up needing to search a lot of PDFs, then ripgrep's parallelism can\nmake the speed difference even greater.\n\n#### A more robust preprocessor\n\nOne of the problems with the aforementioned preprocessor is that it will fail\nif you try to search a file that isn't a PDF:\n\n```\n$ echo foo > not-a-pdf\n$ rg --pre ./preprocess 'The Commentz-Walter algorithm' not-a-pdf\nnot-a-pdf: preprocessor command failed: '\"./preprocess\" \"not-a-pdf\"':\n-------------------------------------------------------------------------------\nSyntax Warning: May not be a PDF file (continuing anyway)\nSyntax Error: Couldn't find trailer dictionary\nSyntax Error: Couldn't find trailer dictionary\nSyntax Error: Couldn't read xref table\n```\n\nTo fix this, we can make our preprocessor script a bit more robust by only\nrunning `pdftotext` when we think the input is a non-empty PDF:\n\n```\n$ cat preprocessor\n#!/bin/sh\n\ncase \"$1\" in\n*.pdf)\n # The -s flag ensures that the file is non-empty.\n if [ -s \"$1\" ]; then\n exec pdftotext - -\n else\n exec cat\n fi\n ;;\n*)\n exec cat\n ;;\nesac\n```\n\nWe can even extend our preprocessor to search other kinds of files. Sometimes\nwe don't always know the file type from the file name, so we can use the `file`\nutility to \"sniff\" the type of the file based on its contents:\n\n```\n$ cat processor\n#!/bin/sh\n\ncase \"$1\" in\n*.pdf)\n # The -s flag ensures that the file is non-empty.\n if [ -s \"$1\" ]; then\n exec pdftotext - -\n else\n exec cat\n fi\n ;;\n*)\n case $(file \"$1\") in\n *Zstandard*)\n exec pzstd -cdq\n ;;\n *)\n exec cat\n ;;\n esac\n ;;\nesac\n```\n\n#### Reducing preprocessor overhead\n\nThere is one more problem with the above approach: it requires running a\npreprocessor for every single file that ripgrep searches. If every file needs\na preprocessor, then this is OK. But if most don't, then this can substantially\nslow down searches because of the overhead of launching new processors. You\ncan avoid this by telling ripgrep to only invoke the preprocessor when the file\npath matches a glob. For example, consider the performance difference even when\nsearching a repository as small as ripgrep's:\n\n```\n$ time rg --pre pre-rg 'fn is_empty' -c\ncrates/globset/src/lib.rs:1\ncrates/matcher/src/lib.rs:2\ncrates/ignore/src/overrides.rs:1\ncrates/ignore/src/gitignore.rs:1\ncrates/ignore/src/types.rs:1\n\nreal 0.138\nuser 0.485\nsys 0.209\nmaxmem 7 MB\nfaults 0\n\n$ time rg --pre pre-rg --pre-glob '*.pdf' 'fn is_empty' -c\ncrates/globset/src/lib.rs:1\ncrates/ignore/src/types.rs:1\ncrates/ignore/src/gitignore.rs:1\ncrates/ignore/src/overrides.rs:1\ncrates/matcher/src/lib.rs:2\n\nreal 0.008\nuser 0.010\nsys 0.002\nmaxmem 7 MB\nfaults 0\n```\n\n### Common options\n\nripgrep has a lot of flags. Too many to keep in your head at once. This section\nis intended to give you a sampling of some of the most important and frequently\nused options that will likely impact how you use ripgrep on a regular basis.\n\n- `-h`: Show ripgrep's condensed help output.\n- `--help`: Show ripgrep's longer form help output. (Nearly what you'd find in\n ripgrep's man page, so pipe it into a pager!)\n- `-i/--ignore-case`: When searching for a pattern, ignore case differences.\n That is `rg -i fast` matches `fast`, `fASt`, `FAST`, etc.\n- `-S/--smart-case`: This is similar to `--ignore-case`, but disables itself\n if the pattern contains any uppercase letters. Usually this flag is put into\n alias or a config file.\n- `-F/--fixed-strings`: Disable regular expression matching and treat the pattern\n as a literal string.\n- `-w/--word-regexp`: Require that all matches of the pattern be surrounded\n by word boundaries. That is, given `pattern`, the `--word-regexp` flag will\n cause ripgrep to behave as if `pattern` were actually `\\b(?:pattern)\\b`.\n- `-c/--count`: Report a count of total matched lines.\n- `--files`: Print the files that ripgrep _would_ search, but don't actually\n search them.\n- `-a/--text`: Search binary files as if they were plain text.\n- `-U/--multiline`: Permit matches to span multiple lines.\n- `-z/--search-zip`: Search compressed files (gzip, bzip2, lzma, xz, lz4,\n brotli, zstd). This is disabled by default.\n- `-C/--context`: Show the lines surrounding a match.\n- `--sort path`: Force ripgrep to sort its output by file name. (This disables\n parallelism, so it might be slower.)\n- `-L/--follow`: Follow symbolic links while recursively searching.\n- `-M/--max-columns`: Limit the length of lines printed by ripgrep.\n- `--debug`: Shows ripgrep's debug output. This is useful for understanding\n why a particular file might be ignored from search, or what kinds of\n configuration ripgrep is loading from the environment.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":40668,"content_sha256":"fac798aaaf20433e2e77ecb9e874ee1ab84f55a5281dcc1b1e9ea8c387340f18"},{"filename":"references/README.md","content":"## ripgrep (rg)\n\nripgrep is a line-oriented search tool that recursively searches the current\ndirectory for a regex pattern. By default, ripgrep will respect gitignore rules\nand automatically skip hidden files/directories and binary files. (To disable\nall automatic filtering by default, use `rg -uuu`.) ripgrep has first class\nsupport on Windows, macOS and Linux, with binary downloads available for [every\nrelease](https://github.com/BurntSushi/ripgrep/releases). ripgrep is similar to\nother popular search tools like The Silver Searcher, ack and grep.\n\n[![Build status](https://github.com/BurntSushi/ripgrep/workflows/ci/badge.svg)](https://github.com/BurntSushi/ripgrep/actions)\n[![Crates.io](https://img.shields.io/crates/v/ripgrep.svg)](https://crates.io/crates/ripgrep)\n[![Packaging status](https://repology.org/badge/tiny-repos/ripgrep.svg)](https://repology.org/project/ripgrep/badges)\n\nDual-licensed under MIT or the [UNLICENSE](https://unlicense.org).\n\n### CHANGELOG\n\nPlease see the [CHANGELOG](CHANGELOG.md) for a release history.\n\n### Documentation quick links\n\n- [Installation](#installation)\n- [User Guide](GUIDE.md)\n- [Frequently Asked Questions](FAQ.md)\n- [Regex syntax](https://docs.rs/regex/1/regex/#syntax)\n- [Configuration files](GUIDE.md#configuration-file)\n- [Shell completions](FAQ.md#complete)\n- [Building](#building)\n- [Translations](#translations)\n\n### Screenshot of search results\n\n[![A screenshot of a sample search with ripgrep](https://burntsushi.net/stuff/ripgrep1.png)](https://burntsushi.net/stuff/ripgrep1.png)\n\n### Quick examples comparing tools\n\nThis example searches the entire\n[Linux kernel source tree](https://github.com/BurntSushi/linux)\n(after running `make defconfig && make -j8`) for `[A-Z]+_SUSPEND`, where\nall matches must be words. Timings were collected on a system with an Intel\ni9-12900K 5.2 GHz.\n\nPlease remember that a single benchmark is never enough! See my\n[blog post on ripgrep](https://blog.burntsushi.net/ripgrep/)\nfor a very detailed comparison with more benchmarks and analysis.\n\n| Tool | Command | Line count | Time |\n| ------------------------------------------------------------------------------------ | ------------------------------------------------------------ | ---------- | ------------------ |\n| ripgrep (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 536 | **0.082s** (1.00x) |\n| [hypergrep](https://github.com/p-ranav/hypergrep) | `hgrep -n -w '[A-Z]+_SUSPEND'` | 536 | 0.167s (2.04x) |\n| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `git grep -P -n -w '[A-Z]+_SUSPEND'` | 536 | 0.273s (3.34x) |\n| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 534 | 0.443s (5.43x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND'` | 536 | 0.639s (7.82x) |\n| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 536 | 0.727s (8.91x) |\n| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 536 | 2.670s (32.70x) |\n| [ack](https://github.com/beyondgrep/ack3) | `ack -w '[A-Z]+_SUSPEND'` | 2677 | 2.935s (35.94x) |\n\nHere's another benchmark on the same corpus as above that disregards gitignore\nfiles and searches with a whitelist instead. The corpus is the same as in the\nprevious benchmark, and the flags passed to each command ensure that they are\ndoing equivalent work:\n\n| Tool | Command | Line count | Time |\n| ---------------------------------------------- | ------------------------------------------------------------------- | ---------- | ------------------ |\n| ripgrep | `rg -uuu -tc -n -w '[A-Z]+_SUSPEND'` | 447 | **0.063s** (1.00x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 447 | 0.607s (9.62x) |\n| [GNU grep](https://www.gnu.org/software/grep/) | `grep -E -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 447 | 0.674s (10.69x) |\n\nNow we'll move to searching on single large file. Here is a straight-up\ncomparison between ripgrep, ugrep and GNU grep on a file cached in memory\n(~13GB, [`OpenSubtitles.raw.en.gz`](http://opus.nlpl.eu/download.php?f=OpenSubtitles/v2018/mono/OpenSubtitles.raw.en.gz), decompressed):\n\n| Tool | Command | Line count | Time |\n| -------------------------------------------------------- | ------------------------------------------------- | ---------- | ------------------ |\n| ripgrep (Unicode) | `rg -w 'Sherlock [A-Z]\\w+'` | 7882 | **1.042s** (1.00x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -w 'Sherlock [A-Z]\\w+'` | 7882 | 1.339s (1.28x) |\n| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 egrep -w 'Sherlock [A-Z]\\w+'` | 7882 | 6.577s (6.31x) |\n\nIn the above benchmark, passing the `-n` flag (for showing line numbers)\nincreases the times to `1.664s` for ripgrep and `9.484s` for GNU grep. ugrep\ntimes are unaffected by the presence or absence of `-n`.\n\nBeware of performance cliffs though:\n\n| Tool | Command | Line count | Time |\n| -------------------------------------------------------- | ------------------------------------------------------------ | ---------- | ------------------ |\n| ripgrep (Unicode) | `rg -w '[A-Z]\\w+ Sherlock [A-Z]\\w+'` | 485 | **1.053s** (1.00x) |\n| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 grep -E -w '[A-Z]\\w+ Sherlock [A-Z]\\w+'` | 485 | 6.234s (5.92x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -w '[A-Z]\\w+ Sherlock [A-Z]\\w+'` | 485 | 28.973s (27.51x) |\n\nAnd performance can drop precipitously across the board when searching big\nfiles for patterns without any opportunities for literal optimizations:\n\n| Tool | Command | Line count | Time |\n| -------------------------------------------------------- | ------------------------------------------- | ---------- | ------------------- |\n| ripgrep | `rg '[A-Za-z]{30}'` | 6749 | **15.569s** (1.00x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep -E '[A-Za-z]{30}'` | 6749 | 21.857s (1.40x) |\n| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C grep -E '[A-Za-z]{30}'` | 6749 | 32.409s (2.08x) |\n| [GNU grep (Unicode)](https://www.gnu.org/software/grep/) | `LC_ALL=en_US.UTF-8 grep -E '[A-Za-z]{30}'` | 6795 | 8m30s (32.74x) |\n\nFinally, high match counts also tend to both tank performance and smooth\nout the differences between tools (because performance is dominated by how\nquickly one can handle a match and not the algorithm used to detect the match,\ngenerally speaking):\n\n| Tool | Command | Line count | Time |\n| ---------------------------------------------- | ------------------- | ---------- | ------------------ |\n| ripgrep | `rg the` | 83499915 | **6.948s** (1.00x) |\n| [ugrep](https://github.com/Genivia/ugrep) | `ugrep the` | 83499915 | 11.721s (1.69x) |\n| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C grep the` | 83499915 | 15.217s (2.19x) |\n\n### Why should I use ripgrep?\n\n- It can replace many use cases served by other search tools\n because it contains most of their features and is generally faster. (See\n [the FAQ](FAQ.md#posix4ever) for more details on whether ripgrep can truly\n replace grep.)\n- Like other tools specialized to code search, ripgrep defaults to\n [recursive search](GUIDE.md#recursive-search) and does [automatic\n filtering](GUIDE.md#automatic-filtering). Namely, ripgrep won't search files\n ignored by your `.gitignore`/`.ignore`/`.rgignore` files, it won't search\n hidden files and it won't search binary files. Automatic filtering can be\n disabled with `rg -uuu`.\n- ripgrep can [search specific types of files](GUIDE.md#manual-filtering-file-types).\n For example, `rg -tpy foo` limits your search to Python files and `rg -Tjs\nfoo` excludes JavaScript files from your search. ripgrep can be taught about\n new file types with custom matching rules.\n- ripgrep supports many features found in `grep`, such as showing the context\n of search results, searching multiple patterns, highlighting matches with\n color and full Unicode support. Unlike GNU grep, ripgrep stays fast while\n supporting Unicode (which is always on).\n- ripgrep has optional support for switching its regex engine to use PCRE2.\n Among other things, this makes it possible to use look-around and\n backreferences in your patterns, which are not supported in ripgrep's default\n regex engine. PCRE2 support can be enabled with `-P/--pcre2` (use PCRE2\n always) or `--auto-hybrid-regex` (use PCRE2 only if needed). An alternative\n syntax is provided via the `--engine (default|pcre2|auto)` option.\n- ripgrep has [rudimentary support for replacements](GUIDE.md#replacements),\n which permit rewriting output based on what was matched.\n- ripgrep supports [searching files in text encodings](GUIDE.md#file-encoding)\n other than UTF-8, such as UTF-16, latin-1, GBK, EUC-JP, Shift_JIS and more.\n (Some support for automatically detecting UTF-16 is provided. Other text\n encodings must be specifically specified with the `-E/--encoding` flag.)\n- ripgrep supports searching files compressed in a common format (brotli,\n bzip2, gzip, lz4, lzma, xz, or zstandard) with the `-z/--search-zip` flag.\n- ripgrep supports\n [arbitrary input preprocessing filters](GUIDE.md#preprocessor)\n which could be PDF text extraction, less supported decompression, decrypting,\n automatic encoding detection and so on.\n- ripgrep can be configured via a\n [configuration file](GUIDE.md#configuration-file).\n\nIn other words, use ripgrep if you like speed, filtering by default, fewer\nbugs and Unicode support.\n\n### Why shouldn't I use ripgrep?\n\nDespite initially not wanting to add every feature under the sun to ripgrep,\nover time, ripgrep has grown support for most features found in other file\nsearching tools. This includes searching for results spanning across multiple\nlines, and opt-in support for PCRE2, which provides look-around and\nbackreference support.\n\nAt this point, the primary reasons not to use ripgrep probably consist of one\nor more of the following:\n\n- You need a portable and ubiquitous tool. While ripgrep works on Windows,\n macOS and Linux, it is not ubiquitous and it does not conform to any\n standard such as POSIX. The best tool for this job is good old grep.\n- There still exists some other feature (or bug) not listed in this README that\n you rely on that's in another tool that isn't in ripgrep.\n- There is a performance edge case where ripgrep doesn't do well where another\n tool does do well. (Please file a bug report!)\n- ripgrep isn't possible to install on your machine or isn't available for your\n platform. (Please file a bug report!)\n\n### Is it really faster than everything else?\n\nGenerally, yes. A large number of benchmarks with detailed analysis for each is\n[available on my blog](https://blog.burntsushi.net/ripgrep/).\n\nSummarizing, ripgrep is fast because:\n\n- It is built on top of\n [Rust's regex engine](https://github.com/rust-lang/regex).\n Rust's regex engine uses finite automata, SIMD and aggressive literal\n optimizations to make searching very fast. (PCRE2 support can be opted into\n with the `-P/--pcre2` flag.)\n- Rust's regex library maintains performance with full Unicode support by\n building UTF-8 decoding directly into its deterministic finite automaton\n engine.\n- It supports searching with either memory maps or by searching incrementally\n with an intermediate buffer. The former is better for single files and the\n latter is better for large directories. ripgrep chooses the best searching\n strategy for you automatically.\n- Applies your ignore patterns in `.gitignore` files using a\n [`RegexSet`](https://docs.rs/regex/1/regex/struct.RegexSet.html).\n That means a single file path can be matched against multiple glob patterns\n simultaneously.\n- It uses a lock-free parallel recursive directory iterator, courtesy of\n [`crossbeam`](https://docs.rs/crossbeam) and\n [`ignore`](https://docs.rs/ignore).\n\n### Feature comparison\n\nAndy Lester, author of [ack](https://beyondgrep.com/), has published an\nexcellent table comparing the features of ack, ag, git-grep, GNU grep and\nripgrep: https://beyondgrep.com/feature-comparison/\n\nNote that ripgrep has grown a few significant new features recently that\nare not yet present in Andy's table. This includes, but is not limited to,\nconfiguration files, passthru, support for searching compressed files,\nmultiline search and opt-in fancy regex support via PCRE2.\n\n### Playground\n\nIf you'd like to try ripgrep before installing, there's an unofficial\n[playground](https://codapi.org/ripgrep/) and an [interactive\ntutorial](https://codapi.org/try/ripgrep/).\n\nIf you have any questions about these, please open an issue in the [tutorial\nrepo](https://github.com/nalgeon/tryxinyminutes).\n\n### Installation\n\nThe binary name for ripgrep is `rg`.\n\n**[Archives of precompiled binaries for ripgrep are available for Windows,\nmacOS and Linux.](https://github.com/BurntSushi/ripgrep/releases)** Linux and\nWindows binaries are static executables. Users of platforms not explicitly\nmentioned below are advised to download one of these archives.\n\nIf you're a **macOS Homebrew** or a **Linuxbrew** user, then you can install\nripgrep from homebrew-core:\n\n```\n$ brew install ripgrep\n```\n\nIf you're a **MacPorts** user, then you can install ripgrep from the\n[official ports](https://www.macports.org/ports.php?by=name&substr=ripgrep):\n\n```\n$ sudo port install ripgrep\n```\n\nIf you're a **Windows Chocolatey** user, then you can install ripgrep from the\n[official repo](https://chocolatey.org/packages/ripgrep):\n\n```\n$ choco install ripgrep\n```\n\nIf you're a **Windows Scoop** user, then you can install ripgrep from the\n[official bucket](https://github.com/ScoopInstaller/Main/blob/master/bucket/ripgrep.json):\n\n```\n$ scoop install ripgrep\n```\n\nIf you're a **Windows Winget** user, then you can install ripgrep from the\n[winget-pkgs](https://github.com/microsoft/winget-pkgs/tree/master/manifests/b/BurntSushi/ripgrep)\nrepository:\n\n```\n$ winget install BurntSushi.ripgrep.MSVC\n```\n\nIf you're an **Arch Linux** user, then you can install ripgrep from the official repos:\n\n```\n$ sudo pacman -S ripgrep\n```\n\nIf you're a **Gentoo** user, you can install ripgrep from the\n[official repo](https://packages.gentoo.org/packages/sys-apps/ripgrep):\n\n```\n$ sudo emerge sys-apps/ripgrep\n```\n\nIf you're a **Fedora** user, you can install ripgrep from official\nrepositories.\n\n```\n$ sudo dnf install ripgrep\n```\n\nIf you're an **openSUSE** user, ripgrep is included in **openSUSE Tumbleweed**\nand **openSUSE Leap** since 15.1.\n\n```\n$ sudo zypper install ripgrep\n```\n\nIf you're a **CentOS Stream 10** user, you can install ripgrep from the\n[EPEL](https://docs.fedoraproject.org/en-US/epel/getting-started/) repository:\n\n```\n$ sudo dnf config-manager --set-enabled crb\n$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm\n$ sudo dnf install ripgrep\n```\n\nIf you're a **Red Hat 10** user, you can install ripgrep from the\n[EPEL](https://docs.fedoraproject.org/en-US/epel/getting-started/) repository:\n\n```\n$ sudo subscription-manager repos --enable codeready-builder-for-rhel-10-$(arch)-rpms\n$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm\n$ sudo dnf install ripgrep\n```\n\nIf you're a **Rocky Linux 10** user, you can install ripgrep from the\n[EPEL](https://docs.fedoraproject.org/en-US/epel/getting-started/) repository:\n\n```\n$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm\n$ sudo dnf install ripgrep\n```\n\nIf you're a **Nix** user, you can install ripgrep from\n[nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ri/ripgrep/package.nix):\n\n```\n$ nix-env --install ripgrep\n```\n\nIf you're a **Flox** user, you can install ripgrep as follows:\n\n```\n$ flox install ripgrep\n```\n\nIf you're a **Guix** user, you can install ripgrep from the official\npackage collection:\n\n```\n$ guix install ripgrep\n```\n\nIf you're a **Debian** user (or a user of a Debian derivative like **Ubuntu**),\nthen ripgrep can be installed using a binary `.deb` file provided in each\n[ripgrep release](https://github.com/BurntSushi/ripgrep/releases).\n\n```\n$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep_14.1.1-1_amd64.deb\n$ sudo dpkg -i ripgrep_14.1.1-1_amd64.deb\n```\n\nIf you run Debian stable, ripgrep is [officially maintained by\nDebian](https://tracker.debian.org/pkg/rust-ripgrep), although its version may\nbe older than the `deb` package available in the previous step.\n\n```\n$ sudo apt-get install ripgrep\n```\n\nIf you're an **Ubuntu Cosmic (18.10)** (or newer) user, ripgrep is\n[available](https://launchpad.net/ubuntu/+source/rust-ripgrep) using the same\npackaging as Debian:\n\n```\n$ sudo apt-get install ripgrep\n```\n\n(N.B. Various snaps for ripgrep on Ubuntu are also available, but none of them\nseem to work right and generate a number of very strange bug reports that I\ndon't know how to fix and don't have the time to fix. Therefore, it is no\nlonger a recommended installation option.)\n\nIf you're an **ALT** user, you can install ripgrep from the\n[official repo](https://packages.altlinux.org/en/search?name=ripgrep):\n\n```\n$ sudo apt-get install ripgrep\n```\n\nIf you're a **FreeBSD** user, then you can install ripgrep from the\n[official ports](https://www.freshports.org/textproc/ripgrep/):\n\n```\n$ sudo pkg install ripgrep\n```\n\nIf you're an **OpenBSD** user, then you can install ripgrep from the\n[official ports](https://openports.se/textproc/ripgrep):\n\n```\n$ doas pkg_add ripgrep\n```\n\nIf you're a **NetBSD** user, then you can install ripgrep from\n[pkgsrc](https://pkgsrc.se/textproc/ripgrep):\n\n```\n$ sudo pkgin install ripgrep\n```\n\nIf you're a **Haiku x86_64** user, then you can install ripgrep from the\n[official ports](https://github.com/haikuports/haikuports/tree/master/sys-apps/ripgrep):\n\n```\n$ sudo pkgman install ripgrep\n```\n\nIf you're a **Haiku x86_gcc2** user, then you can install ripgrep from the\nsame port as Haiku x86_64 using the x86 secondary architecture build:\n\n```\n$ sudo pkgman install ripgrep_x86\n```\n\nIf you're a **Void Linux** user, then you can install ripgrep from the\n[official repository](https://voidlinux.org/packages/?arch=x86_64&q=ripgrep):\n\n```\n$ sudo xbps-install -Syv ripgrep\n```\n\nIf you're a **Rust programmer**, ripgrep can be installed with `cargo`.\n\n- Note that the minimum supported version of Rust for ripgrep is **1.85.0**,\n although ripgrep may work with older versions.\n- Note that the binary may be bigger than expected because it contains debug\n symbols. This is intentional. To remove debug symbols and therefore reduce\n the file size, run `strip` on the binary.\n\n```\n$ cargo install ripgrep\n```\n\nAlternatively, one can use [`cargo\nbinstall`](https://github.com/cargo-bins/cargo-binstall) to install a ripgrep\nbinary directly from GitHub:\n\n```\n$ cargo binstall ripgrep\n```\n\n### Building\n\nripgrep is written in Rust, so you'll need to grab a\n[Rust installation](https://www.rust-lang.org/) in order to compile it.\nripgrep compiles with Rust 1.85.0 (stable) or newer. In general, ripgrep tracks\nthe latest stable release of the Rust compiler.\n\nTo build ripgrep:\n\n```\n$ git clone https://github.com/BurntSushi/ripgrep\n$ cd ripgrep\n$ cargo build --release\n$ ./target/release/rg --version\n0.1.3\n```\n\n**NOTE:** In the past, ripgrep supported a `simd-accel` Cargo feature when\nusing a Rust nightly compiler. This only benefited UTF-16 transcoding.\nSince it required unstable features, this build mode was prone to breakage.\nBecause of that, support for it has been removed. If you want SIMD\noptimizations for UTF-16 transcoding, then you'll have to petition the\n[`encoding_rs`](https://github.com/hsivonen/encoding_rs) project to use stable\nAPIs.\n\nFinally, optional PCRE2 support can be built with ripgrep by enabling the\n`pcre2` feature:\n\n```\n$ cargo build --release --features 'pcre2'\n```\n\nEnabling the PCRE2 feature works with a stable Rust compiler and will\nattempt to automatically find and link with your system's PCRE2 library via\n`pkg-config`. If one doesn't exist, then ripgrep will build PCRE2 from source\nusing your system's C compiler and then statically link it into the final\nexecutable. Static linking can be forced even when there is an available PCRE2\nsystem library by either building ripgrep with the MUSL target or by setting\n`PCRE2_SYS_STATIC=1`.\n\nripgrep can be built with the MUSL target on Linux by first installing the MUSL\nlibrary on your system (consult your friendly neighborhood package manager).\nThen you just need to add MUSL support to your Rust toolchain and rebuild\nripgrep, which yields a fully static executable:\n\n```\n$ rustup target add x86_64-unknown-linux-musl\n$ cargo build --release --target x86_64-unknown-linux-musl\n```\n\nApplying the `--features` flag from above works as expected. If you want to\nbuild a static executable with MUSL and with PCRE2, then you will need to have\n`musl-gcc` installed, which might be in a separate package from the actual\nMUSL library, depending on your Linux distribution.\n\n### Running tests\n\nripgrep is relatively well-tested, including both unit tests and integration\ntests. To run the full test suite, use:\n\n```\n$ cargo test --all\n```\n\nfrom the repository root.\n\n### Related tools\n\n- [delta](https://github.com/dandavison/delta) is a syntax highlighting\n pager that supports the `rg --json` output format. So all you need to do to\n make it work is `rg --json pattern | delta`. See [delta's manual section on\n grep](https://dandavison.github.io/delta/grep.html) for more details.\n\n### Vulnerability reporting\n\nFor reporting a security vulnerability, please\n[contact Andrew Gallant](https://blog.burntsushi.net/about/).\nThe contact page has my email address and PGP public key if you wish to send an\nencrypted message.\n\n### Translations\n\nThe following is a list of known translations of ripgrep's documentation. These\nare unofficially maintained and may not be up to date.\n\n- [Chinese](https://github.com/chinanf-boy/ripgrep-zh#%E6%9B%B4%E6%96%B0-)\n- [Spanish](https://github.com/UltiRequiem/traducciones/tree/master/ripgrep)\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":23992,"content_sha256":"9ffc5d5ee7865282a92fd0089bf53070ae4e4a7c59d286f59d88469bc4913139"},{"filename":"references/research-requirements.md","content":"# Research Requirements\n\n- Use Exa first for current best practices.\n- Use WebFetch/arXiv fallback when Exa is insufficient.\n- Capture constraints and map them to hooks/rules/schemas/workflows.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":194,"content_sha256":"5e6198005713629f3bdc1ca4a8a8ddac43d46009663e42c53b72e2f074cee187"},{"filename":"rules/ripgrep.md","content":"# ripgrep Rules\n\n## Purpose\n\nEnhanced code search with custom ripgrep binary supporting ES module extensions and advanced patterns.\n\n## Best Practices\n\n- Follow established patterns\n- Validate inputs at boundaries\n\n## Integration Points\n\nSee SKILL.md for complete documentation.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":279,"content_sha256":"877d53b6419d1c2f9751688434e439b29f3740407b8e673887f8a19c17ee8918"},{"filename":"schemas/input.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"ripgrepInput\",\n \"description\": \"Input schema for Enhanced code search with custom ripgrep binary supporting ES module extensions and advanced patterns.\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"target\": {\n \"type\": \"string\",\n \"description\": \"Target file or path for the skill to operate on\"\n },\n \"options\": {\n \"type\": \"object\",\n \"description\": \"Additional options for skill execution\",\n \"additionalProperties\": true\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":564,"content_sha256":"88fa54a20337046a46ab2f9b15ab3a2b00ee878b9b8ff003287f98667e546983"},{"filename":"schemas/output.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"ripgrepOutput\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"ok\": {\n \"type\": \"boolean\"\n },\n \"summary\": {\n \"type\": \"string\"\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":251,"content_sha256":"524f9756ac41b66d513d73da48d7f8407f422d5ca57656e4f539e782799e7a0e"},{"filename":"scripts/quick-search.mjs","content":"#!/usr/bin/env node\n/**\n * Quick Search Presets for Ripgrep\n * =================================\n *\n * Provides preset-based searches for common patterns.\n *\n * Usage:\n * node quick-search.mjs \u003cpreset> \"pattern\" [extra-options]\n *\n * Presets:\n * js - JavaScript files (.js, .mjs, .cjs)\n * ts - TypeScript files (.ts, .mts, .cts)\n * mjs - ES modules only (.mjs)\n * cjs - CommonJS modules only (.cjs)\n * hooks - .claude/hooks/ directory\n * skills - .claude/skills/ directory\n * tools - .claude/tools/ directory\n * agents - .claude/agents/ directory\n * all - All files (no filter)\n *\n * Examples:\n * node quick-search.mjs js \"function\"\n * node quick-search.mjs hooks \"PreToolUse\"\n * node quick-search.mjs ts \"interface\" -i\n */\n\nimport { spawn } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport path from 'path';\nimport fs from 'fs';\nimport { createRequire } from 'module';\n\nconst require = createRequire(import.meta.url);\nconst { resolveRipgrepBinary } = require('../../../lib/utils/binary-resolver.cjs');\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Find project root (where .claude folder is)\nfunction findProjectRoot() {\n let dir = __dirname;\n while (dir !== path.parse(dir).root) {\n if (fs.existsSync(path.join(dir, '.claude'))) {\n return dir;\n }\n if (path.basename(dir) === '.claude') {\n return path.dirname(dir);\n }\n dir = path.dirname(dir);\n }\n return process.cwd();\n}\n\nconst PROJECT_ROOT = findProjectRoot();\n\n// Get ripgrep binary path from @vscode/ripgrep npm package\nlet vscodeRgPath = null;\ntry {\n const { rgPath: npmRgPath } = require('@vscode/ripgrep');\n vscodeRgPath = npmRgPath;\n} catch (_err) {\n // Continue with resolver fallbacks (Scoop shims / node_modules/.bin / PATH).\n}\n\nconst rgPath = resolveRipgrepBinary({\n projectRoot: PROJECT_ROOT,\n preferredPath: process.env.RG_BIN,\n vscodeRgPath,\n});\n\nif (!rgPath) {\n console.error('❌ Unable to resolve ripgrep binary.');\n console.error(' Install @vscode/ripgrep or ensure rg is available (Scoop/PATH).');\n process.exit(1);\n}\n\n// Optional: Check for .ripgreprc config file (backward compatibility)\nconst RIPGREPRC = path.join(PROJECT_ROOT, 'bin', '.ripgreprc');\nconst configExists = fs.existsSync(RIPGREPRC);\n\n// Parse arguments\nconst args = process.argv.slice(2);\n\nif (args.length \u003c 2) {\n console.error('Usage: node quick-search.mjs \u003cpreset> \"pattern\" [extra-options]');\n console.error('');\n console.error('Presets:');\n console.error(' js - JavaScript files (.js, .mjs, .cjs)');\n console.error(' ts - TypeScript files (.ts, .mts, .cts)');\n console.error(' mjs - ES modules only (.mjs)');\n console.error(' cjs - CommonJS modules only (.cjs)');\n console.error(' hooks - .claude/hooks/ directory');\n console.error(' skills - .claude/skills/ directory');\n console.error(' tools - .claude/tools/ directory');\n console.error(' agents - .claude/agents/ directory');\n console.error(' all - All files (no filter)');\n console.error('');\n console.error('Examples:');\n console.error(' node quick-search.mjs js \"function\"');\n console.error(' node quick-search.mjs hooks \"PreToolUse\"');\n console.error(' node quick-search.mjs ts \"interface\" -i');\n process.exit(1);\n}\n\nconst preset = args[0];\nconst pattern = args[1];\nconst extraArgs = args.slice(2);\n\n// Map presets to ripgrep arguments\nconst presets = {\n js: ['-tjs'],\n ts: ['-tts'],\n mjs: ['-g', '*.mjs'],\n cjs: ['-g', '*.cjs'],\n mts: ['-g', '*.mts'],\n cts: ['-g', '*.cts'],\n hooks: ['-g', '.claude/hooks/**'],\n skills: ['-g', '.claude/skills/**'],\n tools: ['-g', '.claude/tools/**'],\n agents: ['-g', '.claude/agents/**'],\n all: [],\n};\n\nif (!presets[preset]) {\n console.error(`❌ Unknown preset: ${preset}`);\n console.error(' Valid presets: ' + Object.keys(presets).join(', '));\n process.exit(1);\n}\n\n// Build final args: [pattern, ...preset-args, ...extra-args]\n// Note: `.claude/`-prefixed paths are treated as \"hidden\" by ripgrep, so include `--hidden`\n// to make presets like `hooks`, `skills`, etc. work by default.\nconst rgArgs = ['--hidden', ...presets[preset], ...extraArgs, pattern];\n\n// Set environment variable for config if it exists\nconst env = {\n ...process.env,\n};\nif (configExists) {\n env.RIPGREP_CONFIG_PATH = RIPGREPRC;\n}\n\n// Spawn ripgrep\nconst rg = spawn(rgPath, rgArgs, {\n stdio: 'inherit',\n env,\n shell: false, // SECURITY: Prevent shell interpretation\n windowsHide: true,\n});\n\nrg.on('error', error => {\n console.error(`❌ Failed to execute ripgrep: ${error.message}`);\n process.exit(1);\n});\n\nrg.on('close', code => {\n process.exit(code);\n});\n","content_type":"text/javascript","language":"javascript","size":4735,"content_sha256":"966e852cfae57541b5bb768312381ae2073a93758460f4474602f575e0882c4a"},{"filename":"scripts/search.mjs","content":"#!/usr/bin/env node\n/**\n * Ripgrep Search Wrapper\n * ======================\n *\n * Uses @vscode/ripgrep npm package for cross-platform ripgrep binary.\n * Optionally uses .ripgreprc config file if present.\n *\n * Usage:\n * node search.mjs \"pattern\" [options]\n * node search.mjs \"pattern\" -tjs\n * node search.mjs \"pattern\" -i -C 3\n */\n\nimport { spawn } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport path from 'path';\nimport fs from 'fs';\nimport { createRequire } from 'module';\n\nconst require = createRequire(import.meta.url);\nconst { resolveRipgrepBinary } = require('../../../lib/utils/binary-resolver.cjs');\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Find project root (where .claude folder is)\nfunction findProjectRoot() {\n let dir = __dirname;\n while (dir !== path.parse(dir).root) {\n if (fs.existsSync(path.join(dir, '.claude'))) {\n return dir;\n }\n if (path.basename(dir) === '.claude') {\n return path.dirname(dir);\n }\n dir = path.dirname(dir);\n }\n return process.cwd();\n}\n\nconst PROJECT_ROOT = findProjectRoot();\n\n// Get ripgrep binary path from @vscode/ripgrep npm package\nlet vscodeRgPath = null;\ntry {\n const { rgPath: npmRgPath } = require('@vscode/ripgrep');\n vscodeRgPath = npmRgPath;\n} catch (_err) {\n // Continue with resolver fallbacks (Scoop shims / node_modules/.bin / PATH).\n}\n\nconst rgPath = resolveRipgrepBinary({\n projectRoot: PROJECT_ROOT,\n preferredPath: process.env.RG_BIN,\n vscodeRgPath,\n});\n\nif (!rgPath) {\n console.error('❌ Unable to resolve ripgrep binary.');\n console.error(' Install @vscode/ripgrep or ensure rg is available (Scoop/PATH).');\n process.exit(1);\n}\n\n// Optional: Check for .ripgreprc config file (backward compatibility)\nconst RIPGREPRC = path.join(PROJECT_ROOT, 'bin', '.ripgreprc');\nconst configExists = fs.existsSync(RIPGREPRC);\n\n// Get search pattern and args from command line\nconst args = process.argv.slice(2);\n\nif (args.length === 0) {\n console.error('Usage: node search.mjs \"pattern\" [options]');\n console.error('');\n console.error('Examples:');\n console.error(' node search.mjs \"function\" -tjs');\n console.error(' node search.mjs \"TaskUpdate\" -tjs -tts');\n console.error(' node search.mjs \"pattern\" -i -C 3');\n process.exit(1);\n}\n\n// Set environment variable for config if it exists\nconst env = {\n ...process.env,\n};\nif (configExists) {\n env.RIPGREP_CONFIG_PATH = RIPGREPRC;\n}\n\n// Spawn ripgrep with all args passed through\nconst rg = spawn(rgPath, args, {\n stdio: 'inherit',\n env,\n shell: false, // SECURITY: Prevent shell interpretation\n windowsHide: true,\n});\n\nrg.on('error', error => {\n console.error(`❌ Failed to execute ripgrep: ${error.message}`);\n process.exit(1);\n});\n\nrg.on('close', code => {\n process.exit(code);\n});\n","content_type":"text/javascript","language":"javascript","size":2824,"content_sha256":"9ffc0c419c530eaa215124b2b71eb08d8e4187b36a65ca3e00047fe4f23de167"},{"filename":"templates/implementation-template.md","content":"# ripgrep Implementation Template\n\n## Goal\n\n- Define target outcome and acceptance criteria.\n\n## TDD\n\n1. Red\n2. Green\n3. Refactor\n\n## Verification\n\n- lint\n- format\n- targeted tests\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":181,"content_sha256":"2f3fdd8e357b20ce5463dfa2170cd23514233f450210a5d04164a220364be675"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Ripgrep Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cidentity> Enhanced code search with ripgrep binary. NOTE: Prefer ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" for discovery/ranking and smaller output payloads; prefer raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" for fastest exact literal matching. \u003c/identity>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003ccapabilities>","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid code search via ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" (BM25 text + semantic vector ranking)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw ripgrep for exhaustive pattern sweeps (every match, not ranked top-N)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Advanced regex patterns (PCRE2 with -P flag)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom file type definitions via .ripgreprc","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Integration with .gitignore and custom ignore patterns \u003c/capabilities>","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"⚡ RECOMMENDED: Hybrid Code Search","type":"text"}]},{"type":"paragraph","content":[{"text":"Use the hybrid search system for day-to-day code discovery:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Text search works instantly","type":"text","marks":[{"type":"strong"}]},{"text":" with no setup (ripgrep-based BM25)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Semantic search","type":"text","marks":[{"type":"strong"}]},{"text":" requires a one-time index build: ","type":"text"},{"text":"pnpm code:index:reindex","type":"text","marks":[{"type":"code_inline"}]},{"text":" (~12 min with GPU, ~17 min CPU)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GPU-accelerated","type":"text","marks":[{"type":"strong"}]},{"text":" embedding via fastembed (NVIDIA CUDA auto-detected)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory-safe","type":"text","marks":[{"type":"strong"}]},{"text":": embeddings run in isolated subprocess to work around ONNX Runtime memory leak","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid scoring","type":"text","marks":[{"type":"strong"}]},{"text":": Reciprocal Rank Fusion (RRF) combines text matches + semantic similarity","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Build the semantic index (one-time, or after major codebase changes)\npnpm code:index:reindex\n\n# Verify .env has embeddings enabled (should be default)\n# HYBRID_EMBEDDINGS=on\n# LANCEDB_EMBEDDING_MODE=fastembed","type":"text"}]},{"type":"paragraph","content":[{"text":"Without the index build, ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" falls back to text-only matching. Concept queries like \"authentication flow\" will return poor results without embeddings.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Search Commands","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Project structure (directory tree + entry points + dependency graph + Mermaid)\npnpm search:structure\n\n# Token budget analysis (file sizes + token estimates + refactor advice)\npnpm search:tokens .claude/lib # directory analysis\npnpm search:tokens path/to/file.cjs # single file analysis\n\n# Semantic + text hybrid search (concept discovery, ranked results)\n# Repeated/similar queries served from cache (~5ms hit vs ~800ms miss)\npnpm search:code \"authentication logic\"\npnpm search:code \"export class User\"\n\n# One-shot search + compress + dedup pipeline (for large context tasks)\npnpm search:compress \"how does routing work\"\n\n# Get file content with line numbers\npnpm search:file src/auth.ts 1 50\n\n# Cache observability (daemon must be running)\npnpm search:code --cache-stats # view hits, misses, entries\npnpm search:code --cache-clear # flush cached results","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Know Where Things Are","type":"text"}]},{"type":"paragraph","content":[{"text":"Run this FIRST before any edit, refactor, or onboarding task.","type":"text","marks":[{"type":"strong"}]},{"text":" It gives a complete map:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Directory Tree","type":"text","marks":[{"type":"strong"}]},{"text":" — folder hierarchy up to 3 levels deep (excludes node_modules, .git)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Entry Points","type":"text","marks":[{"type":"strong"}]},{"text":" — all ESM ","type":"text"},{"text":"export","type":"text","marks":[{"type":"code_inline"}]},{"text":" and CJS ","type":"text"},{"text":"module.exports","type":"text","marks":[{"type":"code_inline"}]},{"text":" declarations with file:line references","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Top Dependencies","type":"text","marks":[{"type":"strong"}]},{"text":" — most-imported modules (both ","type":"text"},{"text":"import","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"require","type":"text","marks":[{"type":"code_inline"}]},{"text":") with counts, split by:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"📦","type":"text","marks":[{"type":"code_inline"}]},{"text":" External packages (node:test, path, fs, child_process)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"📁","type":"text","marks":[{"type":"code_inline"}]},{"text":" Local modules (which internal files are imported most — these are the architectural hotspots)","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mermaid Diagram","type":"text","marks":[{"type":"strong"}]},{"text":" — visual dependency graph with:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Directory subgraphs showing export counts per folder","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"External dependency subgraph","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Most-imported local modules highlighted as hub nodes","type":"text"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"How agents should use this:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before editing","type":"text","marks":[{"type":"strong"}]},{"text":": run ","type":"text"},{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" to find which directory owns the code you need to change","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"To find hotspots","type":"text","marks":[{"type":"strong"}]},{"text":": the ","type":"text"},{"text":"📁","type":"text","marks":[{"type":"code_inline"}]},{"text":" local dependencies with highest counts are the most-connected modules — changes there have the widest blast radius","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"To find entry points","type":"text","marks":[{"type":"strong"}]},{"text":": the exports list shows which files expose public APIs — start reading there","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"To understand architecture","type":"text","marks":[{"type":"strong"}]},{"text":": the Mermaid diagram shows which directories are most interconnected","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before refactoring","type":"text","marks":[{"type":"strong"}]},{"text":": the dependency counts tell you how many files will be affected by a rename/move","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"pnpm search:tokens [path]","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Know What Fits in Context","type":"text"}]},{"type":"paragraph","content":[{"text":"Run this before deciding HOW to read a file or directory.","type":"text","marks":[{"type":"strong"}]},{"text":" It tells you:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Token estimates","type":"text","marks":[{"type":"strong"}]},{"text":" per file and per directory (~4 chars per token)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Actionable advice","type":"text","marks":[{"type":"strong"}]},{"text":" on whether to Read directly, use offset/limit, or use search:code instead","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Largest files","type":"text","marks":[{"type":"strong"}]},{"text":" that need special handling","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Directory rankings","type":"text","marks":[{"type":"strong"}]},{"text":" by token size — prioritize which subdirs to explore","type":"text"}]}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check a specific file\npnpm search:tokens .claude/lib/memory/lancedb-client-impl.cjs\n# Output: Size: 41.1KB | Tokens: ~10.5K | Advice: △ MEDIUM — use Read with offset/limit\n\n# Check a directory\npnpm search:tokens .claude/lib\n# Output: 333 files, 2.0MB, ~527K tokens (too large to read all — use search:code)\n\n# Check the whole project\npnpm search:tokens .\n# Output: 12478 files, 61MB, ~16M tokens with per-directory breakdown","type":"text"}]},{"type":"paragraph","content":[{"text":"Token Budget Legend:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✓ OK","type":"text","marks":[{"type":"code_inline"}]},{"text":" (\u003c8K tokens) — safe to ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" the entire file","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"△ MEDIUM","type":"text","marks":[{"type":"code_inline"}]},{"text":" (8-32K) — use ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"offset","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"limit","type":"text","marks":[{"type":"code_inline"}]},{"text":" parameters, or ","type":"text"},{"text":"search:file","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"⚠ LARGE","type":"text","marks":[{"type":"code_inline"}]},{"text":" (32-100K) — prefer ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" over full Read; only read targeted sections","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"⚠ OVER","type":"text","marks":[{"type":"code_inline"}]},{"text":" (>100K) — MUST use ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" or invoke ","type":"text"},{"text":"context-compressor","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"When to invoke ","type":"text","marks":[{"type":"strong"}]},{"text":"context-compressor","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":":","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Directory total exceeds 100K tokens and you need to understand the whole subsystem","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"File exceeds 32K tokens and you need a summary rather than specific lines","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You're building a prompt that would exceed context window limits","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Refactor recommendations","type":"text","marks":[{"type":"strong"}]},{"text":" — for source code files >15K tokens, the tool recommends splitting:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pnpm search:tokens .claude/hooks/routing\n# Output includes:\n# ✂ REFACTOR RECOMMENDED: user-prompt-unified.core.cjs (18.2K tokens)\n# Split into ~3 modules of ~8K tokens each:\n# user-prompt-unified.cjs — thin facade (re-exports)\n# user-prompt-unified-impl.cjs — main logic\n# user-prompt-unified-helpers.cjs — extracted helpers","type":"text"}]},{"type":"paragraph","content":[{"text":"This only applies to source code files (","type":"text"},{"text":".js","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".cjs","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".mjs","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".ts","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".py","type":"text","marks":[{"type":"code_inline"}]},{"text":"), not data files or configs. The pattern follows existing splits in the codebase (e.g., ","type":"text"},{"text":"routing-table.cjs","type":"text","marks":[{"type":"code_inline"}]},{"text":" → ","type":"text"},{"text":"routing-table-data.cjs","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"index-manager.cjs","type":"text","marks":[{"type":"code_inline"}]},{"text":" → ","type":"text"},{"text":"index-manager-operations.cjs","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"pnpm search:compress \"query\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Search + Compress in One Shot","type":"text"}]},{"type":"paragraph","content":[{"text":"Use when ","type":"text","marks":[{"type":"strong"}]},{"text":"search:tokens","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" shows a topic spans >32K tokens and you need a compressed summary.","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Combines the full pipeline in a single command:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid search finds relevant files for your query","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reads actual file content (not just file paths)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Adaptively sets compression ratio based on corpus size (0.8 for small, 0.1 for huge)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compresses via the Python engine with evidence-aware mode","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deduplicates extracted insights against existing memory (patterns.json, gotchas.json)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Outputs JSON with compressed context + classified memory records","type":"text"}]}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pnpm search:compress \"how does the routing system work\"\n# Returns JSON:\n# {\n# \"ok\": true,\n# \"search\": { \"query\": \"...\", \"hits\": 20 },\n# \"compression\": { \"mode\": \"evidence_aware\", \"skeletonRatio\": 0.5 },\n# \"memoryRecords\": { \"patterns\": [...], \"gotchas\": [...], \"issues\": [...], \"decisions\": [...] },\n# \"dedupStats\": { \"total\": 24, \"kept\": 18, \"filtered\": 6 }\n# }","type":"text"}]},{"type":"paragraph","content":[{"text":"Key features:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Adaptive compression","type":"text","marks":[{"type":"strong"}]},{"text":": small corpus (\u003c 8K tokens) keeps 80%, huge corpus (>100K) keeps only 10%","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Memory dedup","type":"text","marks":[{"type":"strong"}]},{"text":": won't re-persist patterns/gotchas that already exist in your memory system","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Evidence gating","type":"text","marks":[{"type":"strong"}]},{"text":": use ","type":"text"},{"text":"--fail-on-insufficient-evidence","type":"text","marks":[{"type":"code_inline"}]},{"text":" to abort if the query doesn't find strong matches","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Automatic Optimizations (No Action Needed)","type":"text"}]},{"type":"paragraph","content":[{"text":"These features work in the background with no commands required:","type":"text"}]},{"type":"paragraph","content":[{"text":"Query Cache","type":"text","marks":[{"type":"strong"}]},{"text":" — Repeated or semantically similar ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" queries are served from an in-memory cache (~5ms vs ~800ms). The cache uses cosine similarity (threshold: 0.95) so \"routing system\" and \"how routing works\" share cached results. Entries expire after 5 minutes. The cache lives in the daemon process for persistence across queries.","type":"text"}]},{"type":"paragraph","content":[{"text":"BM25 Auto-Update","type":"text","marks":[{"type":"strong"}]},{"text":" — When you edit a file, the BM25 text index updates incrementally (~10ms per file). This means ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" always reflects your latest changes without needing ","type":"text"},{"text":"code:index:reindex","type":"text","marks":[{"type":"code_inline"}]},{"text":". Only the text index updates; semantic embeddings require a full reindex.","type":"text"}]},{"type":"paragraph","content":[{"text":"Cache observability:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pnpm search:code --cache-stats # entries, hits, misses, hit rate\npnpm search:code --cache-clear # flush all cached results","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Search Mode Contract (Deterministic)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mode","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use when","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Latency","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"First step: understand project layout, find where to edit","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Directory tree + exports + deps + Mermaid","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:tokens [path]","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Before reading: check if file/dir fits in context","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token estimates + refactor advice","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:code \"query\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Concept discovery, find unknown paths. Auto-cached (~5ms repeat)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~0.2-0.8s (first), ~5ms (cached)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Compact ranked top-20","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:compress \"query\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large context: search + compress + dedup in one shot","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~2-5s","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"JSON: compressed context + memory records","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rg -F \"literal\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exact symbol/literal lookup and anchor checks before edits","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fastest (~35ms)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ALL matches (not ranked)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (built-in)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exhaustive pattern sweeps for audits","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ALL matches with context","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Required selection behavior:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FIRST","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" to orient — know the directory layout and dependency hotspots.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CHECK SIZE","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"pnpm search:tokens","type":"text","marks":[{"type":"code_inline"}]},{"text":" before reading — know if the file fits in context.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"THEN","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" for concept discovery — find files related to your task. Repeat queries are cached automatically.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FOR LARGE CONTEXT","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"pnpm search:compress","type":"text","marks":[{"type":"code_inline"}]},{"text":" when you need compressed understanding of a broad topic. Combines search + adaptive compression + memory dedup in one command.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"BEFORE EDITS","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" to validate exact anchors — confirm the symbol/function exists where you think.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FOR AUDITS","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (built-in) for exhaustive sweeps — need ALL matches, not top-N.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"BM25 text index auto-updates when files are edited (no manual action needed).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" stays optional for human-in-the-loop workflows; do not require it for automation.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Locate Before You Edit (MANDATORY workflow for agents)","type":"text"}]},{"type":"paragraph","content":[{"text":"Before writing or editing ANY file, agents must locate it first. Blind edits waste tokens and cause errors.","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 1 — Orient","type":"text","marks":[{"type":"strong"}]},{"text":" (run once per task):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pnpm search:structure","type":"text"}]},{"type":"paragraph","content":[{"text":"Read the output to understand:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Which directories exist and what they contain","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Which modules are most-imported (","type":"text"},{"text":"📁","type":"text","marks":[{"type":"code_inline"}]},{"text":" local deps with high counts)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Where the public APIs are (Entry Points list)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Step 2 — Check token budget","type":"text","marks":[{"type":"strong"}]},{"text":" (before reading files):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Is this file safe to Read in full, or do I need search:code?\npnpm search:tokens .claude/lib/memory/lancedb-client-impl.cjs\n# Output: △ MEDIUM (10.5K tokens) — use Read with offset/limit\n\n# How big is this directory? Can I read all files?\npnpm search:tokens .claude/lib/routing\n# If >32K total → use search:code for discovery, don't try to read everything","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 3 — Discover","type":"text","marks":[{"type":"strong"}]},{"text":" (per subtask):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Find files related to your task concept\npnpm search:code \"hook validation pre-tool\"","type":"text"}]},{"type":"paragraph","content":[{"text":"This returns ranked files most relevant to the concept. Note the file paths.","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 4 — Pinpoint","type":"text","marks":[{"type":"strong"}]},{"text":" (before each edit):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Confirm exact symbol location with line numbers\nrg -F \"validateHookInput\" -g \"*.cjs\" -n\n\n# Read the file to understand context (use offset/limit for MEDIUM+ files)\npnpm search:file .claude/lib/utils/hook-input.cjs 1 50","type":"text"}]},{"type":"paragraph","content":[{"text":"Step 5 — Check blast radius","type":"text","marks":[{"type":"strong"}]},{"text":" (before refactors):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# How many files import the module you're about to change?\nrg -F \"hook-input.cjs\" -g \"*.cjs\" -c\n# If 40+ files import it, consider backward-compatible changes","type":"text"}]},{"type":"paragraph","content":[{"text":"This workflow prevents:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wasting tokens on files too large for context (check tokens first)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Editing the wrong file (there may be similarly-named files in different directories)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing callsites during refactors (rg -c shows exact counts)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Breaking high-import modules without knowing the blast radius","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Triggering context compression unnecessarily (know sizes upfront)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Interactive Narrowing with fzf (Operator UX)","type":"text"}]},{"type":"paragraph","content":[{"text":"When result sets are large, use ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" to interactively narrow ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"rga","type":"text","marks":[{"type":"code_inline"}]},{"text":" output.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# rg + fzf + file preview\nrg --line-number --no-heading --color=always \"auth|token|session\" . \\\n | fzf --ansi --delimiter \":\" \\\n --preview \"bat --color=always --style=numbers --highlight-line {2} {1}\"\n\n# rga (documents/archives) + fzf\nrga --line-number --no-heading --color=always \"invoice|receipt|policy\" . \\\n | fzf --ansi --delimiter \":\" \\\n --preview \"bat --color=always --style=numbers --line-range=:300 {1}\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Advanced interactive ripgrep launcher pattern:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":": | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \\\n fzf --ansi --disabled \\\n --bind 'start:reload:$rg_prefix \"\"' \\\n --bind 'change:reload:$rg_prefix {q} || true'","type":"text"}]},{"type":"paragraph","content":[{"text":"Usage contract:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" for operator selection/narrowing, not as a replacement for search backends.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Keep ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" as default for agent discovery/ranking workflows.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"rga","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" for interactive triage and manual result picking.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Structural + interactive workflow (human triage):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Structural candidates (ast-grep)\nast-grep -p 'function $NAME($$) { $$ }' --lang javascript --files-with-matches .\n\n# Narrow candidates interactively\nast-grep -p 'function $NAME($$) { $$ }' --lang javascript --files-with-matches . \\\n | fzf --ansi --delimiter \":\" \\\n --preview \"bat --color=always --style=numbers --line-range=:220 {}\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"How It Works","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"pnpm code:index:reindex","type":"text","marks":[{"type":"code_inline"}]},{"text":" builds BM25 text index + LanceDB vector embeddings","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Embedding generation runs in an isolated subprocess (GPU-accelerated when available)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Subprocess is restarted every 50 batches to reclaim ONNX native memory leaks","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" checks the query cache first (~5ms hit); on miss, queries BM25 + vector indexes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"RRF merges text and semantic rankings into a single ordered result set","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Results are cached for future similar queries (cosine > 0.95 = cache hit)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Post-edit hooks incrementally update the BM25 text index (~10ms per file)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:compress","type":"text","marks":[{"type":"code_inline"}]},{"text":" combines search + adaptive compression + memory dedup in one pipeline","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Semantic search (default: on after running code:index:reindex)\nHYBRID_EMBEDDINGS=on\n\n# Embedding engine (fastembed recommended for speed + GPU support)\nLANCEDB_EMBEDDING_MODE=fastembed\n\n# Subprocess isolation for ONNX memory safety (default: on)\nEMBED_SUBPROCESS=on\n\n# Query cache (auto-caches repeated/similar queries)\nSEARCH_CACHE_ENABLED=on # Kill switch: set to off to disable\nSEARCH_CACHE_TTL_MS=300000 # Cache TTL: 5 minutes\nSEARCH_CACHE_SIMILARITY=0.95 # Cosine threshold for semantic cache hit\n\n# BM25 incremental update after file edits\nBM25_INCREMENTAL_UPDATE=on # Kill switch: set to off to disable\n\n# Disable semantic search (text-only, fastest, no index needed)\n# HYBRID_EMBEDDINGS=off\n\n# Daemon transport for repeated queries (cache lives here)\nHYBRID_SEARCH_DAEMON=on\nHYBRID_DAEMON_PREWARM=true\nHYBRID_DAEMON_IDLE_MS=600000\n\n# Query cache (caches repeated/similar queries by embedding similarity)\nSEARCH_CACHE_ENABLED=on # set to off to disable\nSEARCH_CACHE_TTL_MS=300000 # cache entry TTL (5 min)\nSEARCH_CACHE_SIMILARITY=0.95 # cosine threshold for cache hit\n\n# BM25 incremental update after file edits\nBM25_INCREMENTAL_UPDATE=on # set to off to disable","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Daemon + Prewarm Runbook","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Start, verify, prewarm\npnpm search:daemon:start\npnpm search:daemon:status\npnpm search:daemon:prewarm\n\n# Search (daemon path)\npnpm search:code \"authentication logic\"\n\n# Stop daemon\npnpm search:daemon:stop","type":"text"}]},{"type":"paragraph","content":[{"text":"Expected latency profile on this repository:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cold daemon first query (no prewarm): ~1.35s avg","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"First query after prewarm: ~0.40s avg","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Warm repeated daemon queries: ~0.18-0.19s","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Direct mode (","type":"text"},{"text":"HYBRID_SEARCH_DAEMON=off","type":"text","marks":[{"type":"code_inline"}]},{"text":"): ~0.73s avg for repeated CLI calls","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Index Build Performance","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Metric","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"With GPU (RTX 4070)","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CPU-only","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Index time (2843 files)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~12 min","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~17 min","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Main process memory","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~200MB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~200MB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Subprocess memory (isolated)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~500MB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~300MB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Heap allocation needed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4GB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4GB","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Index size on disk","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~6MB (BM25) + ~10MB (vectors)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Same","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Measured Performance and Output (This Repo)","type":"text"}]},{"type":"paragraph","content":[{"text":"Using the same 5 queries on this repository:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mode","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Avg Latency","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Avg Output Bytes","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best Use Case","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"HYBRID_EMBEDDINGS=off","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~227ms","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~461 bytes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fast discovery with compact output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"HYBRID_EMBEDDINGS=on","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~734ms","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~512 bytes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Semantic/concept queries","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" literal search","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~35ms","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~2478 bytes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exact symbol/literal lookup","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Interpretation:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" is fastest for exact literal/symbol lookups","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid search returns significantly smaller output payloads (often lower token pressure)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Embeddings improve semantic recall, but add latency","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Decision Rule (Practical)","type":"text"}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" when:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query is conceptual/natural language (","type":"text"},{"text":"\"auth flow for refresh tokens\"","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You need ranked results and concise context for agent prompts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You want lower output volume by default","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Use raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" when:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query is an exact symbol/literal (","type":"text"},{"text":"TaskUpdate(","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"HybridLazyIndexer","type":"text","marks":[{"type":"code_inline"}]},{"text":", exact export names)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You need the fastest possible lookup time","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You need advanced regex/PCRE2 behavior","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Measured by File Size (This Repo)","type":"text"}]},{"type":"paragraph","content":[{"text":"Sample size: 4 small files (0.5-5KB), 4 large files (30-109KB), literal token queries.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bucket","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" off","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" on","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rg_repo","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rg_file","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Small files","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~230ms / ~2707B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~600ms / ~2965B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~34ms / ~17075B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~15ms / ~1156B","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large files","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~228ms / ~2354B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~475ms / ~2847B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~35ms / ~17811B","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~15ms / ~6564B","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Takeaways:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rg_file","type":"text","marks":[{"type":"code_inline"}]},{"text":" is fastest and best for targeted file-level checks.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rg_repo","type":"text","marks":[{"type":"code_inline"}]},{"text":" remains fastest for repo-wide literal scans, but emits much larger output payloads.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" has steadier latency across file sizes and typically lower output volume for prompt usage.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Real-World Scenario Playbook (Tested Patterns)","type":"text"}]},{"type":"paragraph","content":[{"text":"Use these scenario patterns to choose the right search path quickly.","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 1: Incident Triage (Unknown Root Cause)","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: find likely hotspots for a production symptom quickly without flooding context.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 1) Start broad and semantic\npnpm search:code \"task status not updating after completion\"\n\n# 2) Pivot to exact symbol checks once candidates appear\npnpm search:code \"TaskUpdate(\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Start with ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" for intent-level recall.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Narrow with literal/symbol queries once candidate files are identified.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 2: Fast Exact Lookup (You Know the Identifier)","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: locate exact definitions/usages as fast as possible.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Repo-wide exact literal (stable example in this repo)\nrg -F \"TaskUpdate(\" -g \"*.cjs\" -g \"*.js\" -g \"*.ts\" .\n\n# Single-file exact lookup (fastest path)\nrg -F \"spawnSync\" .claude/skills/skill-creator/scripts/create.cjs","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use raw ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" for exact symbol searches, especially for large files or known paths.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 3: Safe Refactor Prep","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: enumerate callsites and assess blast radius before renaming or behavior changes.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 1) Check blast radius — how many files import this module?\npnpm search:structure\n# Look at 📁 local deps: \"📁 router-state (22)\" = 22 files affected by changes\n\n# 2) Gather broad callsites with semantic search\npnpm search:code \"TaskUpdate completed status workflow\"\n\n# 3) Get EXACT callsite inventory (every match, not ranked)\nrg -F \"TaskUpdate(\" -g \"*.cjs\" -g \"*.js\" -g \"*.ts\" -c\n# Shows count per file — plan your edits across all files\n\n# 4) Verify the specific lines before editing\nrg -F \"TaskUpdate(\" -g \"*.cjs\" -n -C 2","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" first to check dependency counts (blast radius).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid search to find semantic variants you might miss.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw ","type":"text"},{"text":"rg -c","type":"text","marks":[{"type":"code_inline"}]},{"text":" for exact callsite count per file.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw ","type":"text"},{"text":"rg -n -C 2","type":"text","marks":[{"type":"code_inline"}]},{"text":" for line numbers + context before making edits.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 4: Security Audit Sweep","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: detect risky patterns and confirm exact high-confidence matches.","type":"text"}]},{"type":"paragraph","content":[{"text":"For exhaustive sweeps (auditing), use ","type":"text","marks":[{"type":"strong"}]},{"text":"rg","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" or ","type":"text","marks":[{"type":"strong"}]},{"text":"Grep","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" (built-in) as primary tool.","type":"text","marks":[{"type":"strong"}]},{"text":" Hybrid search returns ranked top-N results, which is great for discovery but can miss matches. Security audits need ALL instances of a pattern, not a ranked sample.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# EXHAUSTIVE sweep first (every match, not ranked)\nrg -F \"shell: true\" -g \"*.cjs\" -g \"*.js\" -g \"*.mjs\"\nrg -F \"JSON.parse(\" -g \"*.cjs\" -g \"*.js\" --no-heading\nrg \"eval\\(|new Function\\(\" -g \"*.cjs\" -g \"*.js\"\nrg -F \"child_process\" -g \"*.cjs\" -g \"*.js\"\n\n# THEN use hybrid for concept discovery (find patterns you didn't think to grep for)\npnpm search:code \"command injection shell execution security\"\npnpm search:code \"prototype pollution unsafe parsing\"\n\n# Verify specific findings with file-level rg\nrg -F \"exec(\" .claude/lib/tools/standard-tools.cjs","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" for exhaustive sweeps where completeness matters (security, compliance).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid search for concept discovery to find patterns you didn't know to grep for.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never rely solely on hybrid top-N results for security claims.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 5: Architecture Onboarding (New Contributor/Agent)","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: understand structure and know where to make changes.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 1) Get the full project map (directory tree + exports + deps + Mermaid)\npnpm search:structure\n\n# From the output, you'll see:\n# - Directory tree: which folders exist and their nesting\n# - Entry points: which files export APIs (with file:line)\n# - Top dependencies: most-imported local modules (📁) = architectural hotspots\n# e.g. \"📁 memory-manager.cjs (56)\" means 56 files import it — high blast radius\n# - Mermaid diagram: visual module graph\n\n# 2) Drill into subsystems by concept\npnpm search:code \"routing guard task lifecycle\"\npnpm search:code \"memory scheduler session context\"\n\n# 3) Once you find candidate files, read them\npnpm search:file .claude/lib/routing/router-state.cjs 1 50\n\n# 4) Before editing, confirm exact locations with rg\nrg -F \"resetToRouterMode\" -g \"*.cjs\" -n","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" first — know the landscape before touching anything.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Look at ","type":"text"},{"text":"📁","type":"text","marks":[{"type":"code_inline"}]},{"text":" local dependencies with highest counts — those are the modules where changes have the widest impact.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" to find files related to your concept.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"search:file","type":"text","marks":[{"type":"code_inline"}]},{"text":" to read specific files with line numbers.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" to confirm exact symbol locations before editing.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 6: Codebase Audit / Deep Dive","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: systematic audit of a codebase for bugs, security issues, and dead code.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 1) Map the project — identify architectural hotspots FIRST\npnpm search:structure\n# Key things to note from the output:\n# - 📁 local deps with high counts = audit priority (most connected = most risk)\n# - Entry points list = public API surface to review\n# - Directory tree = scope of what needs auditing\n\n# 2) Exhaustive pattern sweeps with rg (need ALL matches, not top-N)\nrg -F \"JSON.parse(\" -g \"*.cjs\" -g \"*.js\" --no-heading\nrg -F \"shell: true\" -g \"*.cjs\" -g \"*.js\"\nrg \"eval\\(|new Function\\(\" -g \"*.cjs\" -g \"*.js\"\nrg \"DEPRECATED|LEGACY|WARN\" -g \"*.cjs\" -g \"*.js\" -g \"*.mjs\"\nrg -F \"catch\" -A1 -g \"*.cjs\" | rg \"^\\s*\\}\" # empty catch blocks\n\n# 3) Concept discovery for patterns you didn't think to grep\npnpm search:code \"prototype pollution unsafe parsing\"\npnpm search:code \"race condition concurrent file write\"\npnpm search:code \"hardcoded secret credential password\"\n\n# 4) Cross-reference: find what calls a specific module\npnpm search:code \"routing-table-intent\"\nrg -F \"standard-tools\" -g \"*.cjs\" -c # exact import count per file\n\n# 5) Check for dead code: find exports that are never imported\n# Compare entry points from search:structure against rg import counts\nrg -F \"orchestrator-tool.cjs\" -g \"*.cjs\" -c # 0 results = dead module","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" first to identify hotspots (high-import modules = audit priority).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" for exhaustive sweeps (security, dead code, pattern matching).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" for concept discovery (find things you didn't know to grep for).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cross-reference ","type":"text"},{"text":"search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" entry points against ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" import counts to find dead code.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never rely solely on hybrid search for audit completeness; it returns ranked top-N, not all matches.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"Scenario 7: Token-Constrained Agent Workflow","type":"text"}]},{"type":"paragraph","content":[{"text":"Goal: minimize prompt/context bloat while maintaining retrieval quality.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Default: semantic search on (compact ranked output, good for agents)\npnpm search:code \"workflow task completion guard\"\n\n# For fastest possible response when you know exact terms\nHYBRID_EMBEDDINGS=off pnpm search:code \"TaskUpdate completed\"\n\n# For intent-heavy queries where exact terms are unknown\npnpm search:code \"why does the task get stuck after agent finishes\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Pattern:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Default to ","type":"text"},{"text":"HYBRID_EMBEDDINGS=on","type":"text","marks":[{"type":"code_inline"}]},{"text":" (compact ranked output is already token-efficient).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"HYBRID_EMBEDDINGS=off","type":"text","marks":[{"type":"code_inline"}]},{"text":" override only when exact keyword match is sufficient and speed is critical.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hybrid search output is typically smaller than raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" output (ranked top-N vs all matches).","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Reusable Query Patterns","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concept query: ","type":"text"},{"text":"\"authentication flow refresh token validation\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mixed query: ","type":"text"},{"text":"\"TaskUpdate completed status\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Exact query: ","type":"text"},{"text":"\"TaskUpdate(\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" (prefer ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" when speed is critical)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Structure query: use ","type":"text"},{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" before large edits","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"File drill-down: ","type":"text"},{"text":"pnpm search:file \u003cpath> \u003cstartLine> \u003cendLine>","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Only use raw ripgrep (below) for:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Advanced PCRE2 regex patterns (lookahead/lookbehind)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom file type filtering not supported by ","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pipeline integration with other CLI tools","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"\u003cinstructions> \u003cexecution_process>","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill provides access to ripgrep (rg) via the ","type":"text"},{"text":"@vscode/ripgrep","type":"text","marks":[{"type":"code_inline"}]},{"text":" npm package, which automatically downloads the correct binary for your platform (Windows, Linux, macOS). Enhanced file type support for modern JavaScript/TypeScript projects.","type":"text"}]},{"type":"paragraph","content":[{"text":"Binary Source","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"@vscode/ripgrep","type":"text","marks":[{"type":"code_inline"}]},{"text":" npm package (cross-platform, auto-installed)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automatically handles Windows, Linux, macOS binaries","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No manual binary management required","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Optional Config","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"bin/.ripgreprc","type":"text","marks":[{"type":"code_inline"}]},{"text":" (if present, automatically used)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use What","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best for","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tradeoff","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Concept discovery, ranked results, agent workflows","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Top-N ranked, not exhaustive; needs index for semantic","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Built-in ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exhaustive pattern sweeps, audits, exact counts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Returns ALL matches; higher token output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Raw ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" via Bash","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PCRE2 regex, pipeline integration, ","type":"text"},{"text":".ripgreprc","type":"text","marks":[{"type":"code_inline"}]},{"text":" types","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Requires Bash tool; larger raw output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Built-in ","type":"text"},{"text":"Glob","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Finding files by name pattern","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No content search","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"For audits and security sweeps","type":"text","marks":[{"type":"strong"}]},{"text":": prefer ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (built-in) — it returns every match, not ranked top-N. You need completeness, not ranking.","type":"text"}]},{"type":"paragraph","content":[{"text":"For discovery and onboarding","type":"text","marks":[{"type":"strong"}]},{"text":": prefer ","type":"text"},{"text":"pnpm search:code","type":"text","marks":[{"type":"code_inline"}]},{"text":" — compact ranked output, semantic understanding, low token pressure.","type":"text"}]},{"type":"paragraph","content":[{"text":"For exact symbol lookups before edits","type":"text","marks":[{"type":"strong"}]},{"text":": prefer raw ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" — fastest possible, deterministic.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start Commands","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Basic Search","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Search for pattern in all files\nnode .claude/skills/ripgrep/scripts/search.mjs \"pattern\"\n\n# Search specific file types\nnode .claude/skills/ripgrep/scripts/search.mjs \"pattern\" -tjs\nnode .claude/skills/ripgrep/scripts/search.mjs \"pattern\" -tts\n\n# Case-insensitive search\nnode .claude/skills/ripgrep/scripts/search.mjs \"pattern\" -i\n\n# Search with context lines\nnode .claude/skills/ripgrep/scripts/search.mjs \"pattern\" -C 3","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Quick Search Presets","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Search JavaScript files (includes .mjs, .cjs)\nnode .claude/skills/ripgrep/scripts/quick-search.mjs js \"pattern\"\n\n# Search TypeScript files (includes .mts, .cts)\nnode .claude/skills/ripgrep/scripts/quick-search.mjs ts \"pattern\"\n\n# Search all .mjs files specifically\nnode .claude/skills/ripgrep/scripts/quick-search.mjs mjs \"pattern\"\n\n# Search .claude directory for hooks\nnode .claude/skills/ripgrep/scripts/quick-search.mjs hooks \"pattern\"\n\n# Search .claude directory for skills\nnode .claude/skills/ripgrep/scripts/quick-search.mjs skills \"pattern\"\n\n# Search .claude directory for tools\nnode .claude/skills/ripgrep/scripts/quick-search.mjs tools \"pattern\"\n\n# Search .claude directory for agents\nnode .claude/skills/ripgrep/scripts/quick-search.mjs agents \"pattern\"\n\n# Search all files (no filter)\nnode .claude/skills/ripgrep/scripts/quick-search.mjs all \"pattern\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"File Type Searches","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# JavaScript files (includes .js, .mjs, .cjs)\nrg \"function\" -tjs\n\n# TypeScript files (includes .ts, .mts, .cts)\nrg \"interface\" -tts\n\n# Config files (.yaml, .yml, .toml, .ini)\nrg \"port\" -tconfig\n\n# Markdown files (includes .md, .mdc)\nrg \"# Heading\" -tmd","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Advanced Regex","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Word boundary search\nrg \"\\bfoo\\b\"\n\n# Case-insensitive\nrg \"pattern\" -i\n\n# Smart case (case-insensitive unless uppercase present)\nrg \"pattern\" -S # Already default in .ripgreprc\n\n# Multiline search\nrg \"pattern.*\\n.*another\" -U\n\n# PCRE2 lookahead/lookbehind\nrg -P \"foo(?=bar)\" # Positive lookahead\nrg -P \"foo(?!bar)\" # Negative lookahead\nrg -P \"(?\u003c=foo)bar\" # Positive lookbehind\nrg -P \"(?\u003c!foo)bar\" # Negative lookbehind","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Filtering","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Exclude directories\nrg \"pattern\" -g \"!node_modules/**\"\nrg \"pattern\" -g \"!.git/**\"\n\n# Include only specific directories\nrg \"pattern\" -g \".claude/**\"\n\n# Exclude specific file types\nrg \"pattern\" -Tjs # Exclude JavaScript\n\n# Search hidden files\nrg \"pattern\" --hidden\n\n# Search binary files\nrg \"pattern\" -a","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Context and Output","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Show 3 lines before and after match\nrg \"pattern\" -C 3\n\n# Show 2 lines before\nrg \"pattern\" -B 2\n\n# Show 2 lines after\nrg \"pattern\" -A 2\n\n# Show only filenames with matches\nrg \"pattern\" -l\n\n# Show count of matches per file\nrg \"pattern\" -c\n\n# Show line numbers (default in .ripgreprc)\nrg \"pattern\" -n","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"PCRE2 Advanced Patterns","type":"text"}]},{"type":"paragraph","content":[{"text":"Enable PCRE2 mode with ","type":"text"},{"text":"-P","type":"text","marks":[{"type":"code_inline"}]},{"text":" for advanced features:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Lookahead and Lookbehind","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Find \"error\" only when followed by \"critical\"\nrg -P \"error(?=.*critical)\"\n\n# Find \"test\" not followed by \".skip\"\nrg -P \"test(?!\\.skip)\"\n\n# Find words starting with capital after \"Dr. \"\nrg -P \"(?\u003c=Dr\\. )[A-Z]\\w+\"\n\n# Find function calls not preceded by \"await \"\nrg -P \"(?\u003c!await )\\b\\w+\\(\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Backreferences","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Find repeated words\nrg -P \"\\b(\\w+)\\s+\\1\\b\"\n\n# Find matching HTML tags\nrg -P \"\u003c(\\w+)>.*?\u003c/\\1>\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Conditionals","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Match IPv4 or IPv6\nrg -P \"(\\d{1,3}\\.){3}\\d{1,3}|([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration with Other Tools","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With fzf (Interactive Search)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Search and interactively select file\nrg --files | fzf\n\n# Search pattern and open in editor\nrg \"pattern\" -l | fzf | xargs code","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With vim","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Set ripgrep as grep program in .vimrc\nset grepprg=rg\\ --vimgrep\\ --smart-case\\ --follow","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pipeline with Other Commands","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Search and count unique matches\nrg \"pattern\" -o | sort | uniq -c\n\n# Search and replace preview\nrg \"old\" -l | xargs sed -i 's/old/new/g'","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Performance Optimization","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Tips for Large Codebases","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use file type filters","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"-tjs","type":"text","marks":[{"type":"code_inline"}]},{"text":" is faster than searching all files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Exclude large directories","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"-g \"!node_modules/**\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use literal strings when possible","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"-F \"literal\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" (disables regex)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable parallel search","type":"text","marks":[{"type":"strong"}]},{"text":": Ripgrep uses all cores by default","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use .gitignore","type":"text","marks":[{"type":"strong"}]},{"text":": Ripgrep respects .gitignore automatically","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Benchmarks","type":"text"}]},{"type":"paragraph","content":[{"text":"Ripgrep is typically:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"10-100x faster","type":"text","marks":[{"type":"strong"}]},{"text":" than grep","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"5-10x faster","type":"text","marks":[{"type":"strong"}]},{"text":" than ag (The Silver Searcher)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"3-5x faster","type":"text","marks":[{"type":"strong"}]},{"text":" than git grep","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Custom Configuration","type":"text"}]},{"type":"paragraph","content":[{"text":"The optional ","type":"text"},{"text":".ripgreprc","type":"text","marks":[{"type":"code_inline"}]},{"text":" file at ","type":"text"},{"text":"bin/.ripgreprc","type":"text","marks":[{"type":"code_inline"}]},{"text":" (if present) contains:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"# Extended file types\n--type-add=js:*.mjs\n--type-add=js:*.cjs\n--type-add=ts:*.mts\n--type-add=ts:*.cts\n--type-add=md:*.mdc\n--type-add=config:*.yaml\n--type-add=config:*.yml\n--type-add=config:*.toml\n--type-add=config:*.ini\n\n# Default options\n--smart-case\n--follow\n--line-number","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Framework-Specific Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Searching .claude Directory","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Find all hooks\nrg \"PreToolUse\\|PostToolUse\" .claude/hooks/\n\n# Find all skills\nrg \"^# \" .claude/skills/ -tmd\n\n# Find agent definitions\nrg \"^name:\" .claude/agents/ -tmd\n\n# Find workflow steps\nrg \"^### Step\" .claude/workflows/ -tmd","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Common Agent Studio Searches","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Find all TaskUpdate calls\nrg \"TaskUpdate\\(\" -tjs -tts\n\n# Find all skill invocations\nrg \"Skill\\(\\{\" -tjs -tts\n\n# Find all memory protocol sections\nrg \"## Memory Protocol\" -tmd\n\n# Find all BLOCKING enforcement comments\nrg \"BLOCKING|CRITICAL\" -C 2","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c/execution_process>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cbest_practices>","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use file type filters","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"-tjs","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-tts","type":"text","marks":[{"type":"code_inline"}]},{"text":") for faster searches","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Respect .gitignore","type":"text","marks":[{"type":"strong"}]},{"text":" patterns (automatic by default)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use smart-case","type":"text","marks":[{"type":"strong"}]},{"text":" for case-insensitive search (default in config)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable PCRE2","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"-P","type":"text","marks":[{"type":"code_inline"}]},{"text":") only when advanced features needed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Exclude large directories","type":"text","marks":[{"type":"strong"}]},{"text":" with ","type":"text"},{"text":"-g \"!node_modules/**\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use literal search","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"-F","type":"text","marks":[{"type":"code_inline"}]},{"text":") when pattern has no regex","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Binary automatically managed","type":"text","marks":[{"type":"strong"}]},{"text":" via ","type":"text"},{"text":"@vscode/ripgrep","type":"text","marks":[{"type":"code_inline"}]},{"text":" npm package","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use quick-search presets","type":"text","marks":[{"type":"strong"}]},{"text":" for common .claude directory searches \u003c/best_practices> \u003c/instructions>","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"\u003cexamples> \u003cusage_example> ","type":"text"},{"text":"Search for all TaskUpdate calls in the project:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node .claude/skills/ripgrep/scripts/search.mjs \"TaskUpdate\" -tjs -tts","type":"text"}]},{"type":"paragraph","content":[{"text":"Find all security-related hooks:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node .claude/skills/ripgrep/scripts/quick-search.mjs hooks \"security|SECURITY\" -i","type":"text"}]},{"type":"paragraph","content":[{"text":"Search for function definitions with PCRE2:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node .claude/skills/ripgrep/scripts/search.mjs -P \"^function\\s+\\w+\\(\" -tjs","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c/usage_example> \u003c/examples>","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Binary Management","type":"text"}]},{"type":"paragraph","content":[{"text":"The search scripts use ","type":"text"},{"text":"@vscode/ripgrep","type":"text","marks":[{"type":"code_inline"}]},{"text":" npm package which automatically:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects your platform (Windows, Linux, macOS)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Downloads the correct binary during ","type":"text"},{"text":"pnpm install","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Handles all architecture variants (x64, ARM64, etc.)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"No manual binary management required - the npm package handles everything automatically.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"grep","type":"text","marks":[{"type":"link","attrs":{"href":"../grep/SKILL.md","title":null}},{"type":"code_inline"}]},{"text":" - Built-in Claude Code grep (simpler, less features)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"glob","type":"text","marks":[{"type":"link","attrs":{"href":"../glob/SKILL.md","title":null}},{"type":"code_inline"}]},{"text":" - File pattern matching","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Iron Laws","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" run ","type":"text"},{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" first to orient before any edit task — editing without understanding directory layout and import hotspots causes missed callsites and blast radius surprises.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER","type":"text","marks":[{"type":"strong"}]},{"text":" use ranked/top-N hybrid search output for security audits — completeness matters for audits; use ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":" or built-in ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" to get every match, not a ranked sample.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" validate exact symbol anchors with ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]},{"text":" before editing code — editing based on semantic matches alone misses similarly-named functions and causes wrong-file edits.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER","type":"text","marks":[{"type":"strong"}]},{"text":" make ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" a blocking dependency in automated or agent workflows — interactive selection is operator UX only; unattended agent flows must stay non-interactive and reproducible.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" scope repo-wide searches with file type filters or path globs — unscoped searches flood context with irrelevant matches and inflate token costs.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Anti-Patterns","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anti-Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Why It Fails","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Correct Approach","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Starting an edit task without running ","type":"text"},{"text":"search:structure","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Missing directory layout knowledge causes edits to the wrong file and missed callsites","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always run ","type":"text"},{"text":"pnpm search:structure","type":"text","marks":[{"type":"code_inline"}]},{"text":" first to understand directory hierarchy and import hotspots","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using hybrid search for security audit completeness","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hybrid search returns ranked top-N, not all matches; security audits need every instance","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" (exhaustive) for security sweeps; use hybrid search only for concept discovery","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Editing code without confirming exact symbol location with ","type":"text"},{"text":"rg -F","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Semantic matches include similarly-named symbols; editing the wrong function is silent","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"rg -F \"exact_symbol\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" to confirm location and callsite count before any code edit","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Making ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" a required step in agent automation pipelines","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" requires interactive input; agents cannot proceed when the pipeline blocks on user selection","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Keep ","type":"text"},{"text":"fzf","type":"text","marks":[{"type":"code_inline"}]},{"text":" optional and operator-only; agent workflows must use deterministic ","type":"text"},{"text":"rg","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"search:code","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Running unscoped repo-wide regex searches","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large monorepos return thousands of matches; token costs spike and context floods","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always constrain scope with ","type":"text"},{"text":"-g \"*.cjs\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-tjs","type":"text","marks":[{"type":"code_inline"}]},{"text":", or a path argument before running repo-wide patterns","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Memory Protocol (MANDATORY)","type":"text"}]},{"type":"paragraph","content":[{"text":"Before starting:","type":"text","marks":[{"type":"strong"}]},{"text":" Read ","type":"text"},{"text":".claude/context/memory/learnings.md","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"After completing:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"New pattern -> ","type":"text"},{"text":".claude/context/memory/learnings.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Issue found -> ","type":"text"},{"text":".claude/context/memory/issues.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Decision made -> ","type":"text"},{"text":".claude/context/memory/decisions.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"ASSUME INTERRUPTION: If it's not in memory, it didn't happen.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"ripgrep","model":"sonnet","tools":["Read","Write","Edit"],"author":"@skillopedia","source":{"stars":29,"repo_name":"agent-studio","origin_url":"https://github.com/oimiragieo/agent-studio/blob/HEAD/.claude/skills/ripgrep/SKILL.md","repo_owner":"oimiragieo","body_sha256":"998486a25c18a92cd724633c6d0ef17eecc7c2e654faf3a87413a02f84ff5310","cluster_key":"7248db014fc4e69cf7da1a60e87b09504682261ac03c099e931e4cd0a61ba7e8","clean_bundle":{"format":"clean-skill-bundle-v1","source":"oimiragieo/agent-studio/.claude/skills/ripgrep/SKILL.md","attachments":[{"id":"c7c18f1a-c194-580d-ba5b-896e1c8750e3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c7c18f1a-c194-580d-ba5b-896e1c8750e3/attachment.md","path":"commands/ripgrep.md","size":107,"sha256":"aa0ca615351893ecec3076fdd1385aed80b1314d4f976123248ded087eb3a803","contentType":"text/markdown; charset=utf-8"},{"id":"570ae1dd-387d-5fa4-adf0-487db680d339","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/570ae1dd-387d-5fa4-adf0-487db680d339/attachment.cjs","path":"hooks/post-execute.cjs","size":292,"sha256":"8c7e6c351e60c8ae2af757188fe5f79ca8b60cee5dc63b7ffeb3475256de2082","contentType":"text/plain; charset=utf-8"},{"id":"f6007a95-445e-5b8d-9b93-331c9d221274","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f6007a95-445e-5b8d-9b93-331c9d221274/attachment.cjs","path":"hooks/pre-execute.cjs","size":409,"sha256":"b08360a1a2c22b562f113fc7874fdf1e19730325ca36f2391c92e68751435427","contentType":"text/plain; charset=utf-8"},{"id":"5e389961-900e-5066-94dd-18b445651024","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5e389961-900e-5066-94dd-18b445651024/attachment","path":"references/.ripgreprc","size":696,"sha256":"c71b310c869e067801df1ff10bbf55bee7086e8699003d13b02ee725a66aabdb","contentType":"text/plain; charset=utf-8"},{"id":"c2332a83-06a2-5555-8e18-a361459e7372","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c2332a83-06a2-5555-8e18-a361459e7372/attachment.md","path":"references/GUIDE.md","size":40668,"sha256":"fac798aaaf20433e2e77ecb9e874ee1ab84f55a5281dcc1b1e9ea8c387340f18","contentType":"text/markdown; charset=utf-8"},{"id":"d229e2ba-c27a-5ded-92fe-4030828c4253","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d229e2ba-c27a-5ded-92fe-4030828c4253/attachment.md","path":"references/README.md","size":23992,"sha256":"9ffc5d5ee7865282a92fd0089bf53070ae4e4a7c59d286f59d88469bc4913139","contentType":"text/markdown; charset=utf-8"},{"id":"eca83afd-694f-5fd4-a0a9-543df3c8aed7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/eca83afd-694f-5fd4-a0a9-543df3c8aed7/attachment.md","path":"references/research-requirements.md","size":194,"sha256":"5e6198005713629f3bdc1ca4a8a8ddac43d46009663e42c53b72e2f074cee187","contentType":"text/markdown; charset=utf-8"},{"id":"6c77cb74-ab94-5d8b-9dee-f3c830d002c9","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6c77cb74-ab94-5d8b-9dee-f3c830d002c9/attachment.md","path":"rules/ripgrep.md","size":279,"sha256":"877d53b6419d1c2f9751688434e439b29f3740407b8e673887f8a19c17ee8918","contentType":"text/markdown; charset=utf-8"},{"id":"c3264861-af1a-589d-a72d-e8f0a014418a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c3264861-af1a-589d-a72d-e8f0a014418a/attachment.json","path":"schemas/input.schema.json","size":564,"sha256":"88fa54a20337046a46ab2f9b15ab3a2b00ee878b9b8ff003287f98667e546983","contentType":"application/json; charset=utf-8"},{"id":"cec0fff0-3b88-54cd-ac6a-bd39f294ec76","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/cec0fff0-3b88-54cd-ac6a-bd39f294ec76/attachment.json","path":"schemas/output.schema.json","size":251,"sha256":"524f9756ac41b66d513d73da48d7f8407f422d5ca57656e4f539e782799e7a0e","contentType":"application/json; charset=utf-8"},{"id":"44542d96-6ae0-561e-9af9-eb7cf381d8a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/44542d96-6ae0-561e-9af9-eb7cf381d8a7/attachment.cjs","path":"scripts/main.cjs","size":121,"sha256":"f87905dc281b62369f3a8dee3530d306f327c9b137d1d711c3f4e96f9a52c3da","contentType":"text/plain; charset=utf-8"},{"id":"4ae0524e-0c2c-57ea-8dcf-e79dbfcd0c74","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4ae0524e-0c2c-57ea-8dcf-e79dbfcd0c74/attachment.mjs","path":"scripts/quick-search.mjs","size":4735,"sha256":"966e852cfae57541b5bb768312381ae2073a93758460f4474602f575e0882c4a","contentType":"text/javascript"},{"id":"5e6bd54e-c14a-5596-887b-a15d98bd0bda","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5e6bd54e-c14a-5596-887b-a15d98bd0bda/attachment.mjs","path":"scripts/search.mjs","size":2824,"sha256":"9ffc0c419c530eaa215124b2b71eb08d8e4187b36a65ca3e00047fe4f23de167","contentType":"text/javascript"},{"id":"b99cc168-3977-5122-a041-fdebaf145991","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b99cc168-3977-5122-a041-fdebaf145991/attachment.md","path":"templates/implementation-template.md","size":181,"sha256":"2f3fdd8e357b20ce5463dfa2170cd23514233f450210a5d04164a220364be675","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"a4dfe88b53622954c6c19cf5966ceca124390dc0a8dc3c4f5e2bb07281a215fb","attachment_count":14,"text_attachments":13,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":1,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":".claude/skills/ripgrep/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"software-engineering","category_label":"Engineering"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"software-engineering","verified":true,"import_tag":"clean-skills-v1","invoked_by":"user","description":"Enhanced code search with custom ripgrep binary supporting ES module extensions and advanced patterns.","trust_score":100,"lastVerifiedAt":"2026-02-22T00:00:00.000Z","provenance_sha":"d09b7888e48174c3","user_invocable":true}},"renderedAt":1782981681083}

Ripgrep Skill <identity Enhanced code search with ripgrep binary. NOTE: Prefer for discovery/ranking and smaller output payloads; prefer raw for fastest exact literal matching. </identity <capabilities - Hybrid code search via (BM25 text + semantic vector ranking) - Raw ripgrep for exhaustive pattern sweeps (every match, not ranked top-N) - Advanced regex patterns (PCRE2 with -P flag) - Custom file type definitions via .ripgreprc - Integration with .gitignore and custom ignore patterns </capabilities ⚡ RECOMMENDED: Hybrid Code Search Use the hybrid search system for day-to-day code discovery:…