UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

63 lines • 3.01 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { stripSlash } from "../../utils/slash.js"; import { compareCodePoints } from "../../utils/sort.js"; import { CODE_SEARCH_SIZE_LIMIT } from "./constants.js"; // The file entries at or below a repo-relative scope key, in tree order: // every blob for the repository root, the file itself for a file key. A // sibling that merely shares the scope's spelling (srcx/ beside src/) is // outside it. Tree keys are repo-relative without a leading slash, which is // the space `key` is already in. export function scopeBlobs(tree, key) { const norm = stripSlash(key); const prefix = `${norm}/`; const out = []; for (const [p, entry] of Object.entries(tree)) { if (entry.type !== 'blob') continue; if (norm !== '' && p !== norm && !p.startsWith(prefix)) continue; out.push([p, entry]); } return out; } export function countScopeFiles(tree, key) { return scopeBlobs(tree, key).length; } const NARROWING = /[:"]|(?:^|[^A-Za-z0-9_])-|(?:^|[^A-Za-z0-9_])NOT(?:[^A-Za-z0-9_]|$)/; const WORD = /[A-Za-z0-9_]/; // Whether a literal can be sent to code search without rescoping it. The // literal goes into the query verbatim, so any part of it the search grammar // reads as syntax narrows the answer to less than the files that hold it. // Measured against api.github.com: a `name:` word is a qualifier, a quote // opens a phrase, a word-leading `-` negates and `NOT` is an operator; // lowercase `not` and `OR` are plain terms, and parentheses are refused with // a 422, which already falls back. Word characters are ASCII so both hosts // gate the same literals, and a literal holding none of them would send a // query that is only its scope. export function searchSafe(query) { return WORD.test(query) && !NARROWING.test(query); } // The files under a scope that code search never indexes: at or over // CODE_SEARCH_SIZE_LIMIT, or of a size the tree did not report, since // nothing vouches for those either. Sorted repo-relative keys. export function unsearchableKeys(tree, key) { const out = []; for (const [p, entry] of scopeBlobs(tree, key)) { if (entry.size === null || entry.size >= CODE_SEARCH_SIZE_LIMIT) out.push(p); } return out.sort(compareCodePoints); } //# sourceMappingURL=pushdown.js.map