@ajdev0/token-shrink 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/parser/registry.ts","../src/index.ts","../src/parser/pruner.ts","../src/parser/wasm.ts","../src/watcher/sync.ts","../src/server/assembler.ts","../src/cli.ts","../src/mcp.ts"],"sourcesContent":["/**\n * Language registry mapping file extensions to tree-sitter grammars and\n * pruning strategies. Each spec defines:\n * - the web-tree-sitter language name\n * - the `.wasm` file and the authoritative download URL\n * - one or more S-expression queries (the \"prune query\") that match the\n * implementation blocks to remove, plus the replacement token.\n *\n * The empty-query default of '' matches nothing, so the pruner leaves the\n * file untouched when a language has no registered prune rules yet.\n */\n\nimport path from 'node:path';\n\n/** Source of truth mirror in the PRD language matrix. */\nexport type Replacement = {\n /** Token used to replace a pruned block. */\n token: string;\n /**\n * Optional regex, run against the raw block text. If it matches, the block\n * is kept instead of pruned. Used to preserve directive/header lines\n * ('use client/server') even when they live inside an otherwise-pruned body.\n */\n keepIf?: RegExp;\n};\n\nexport interface LanguageSpec {\n /** Friendly name, used in logs and the report header. */\n name: string;\n /** web-tree-sitter `Language.load` file name. */\n wasm: string;\n /** Where to download the `.wasm` binary if not cached locally. */\n url: string;\n /** Extensions that map to this language: `.ts`, `.tsx`, etc. */\n extensions: string[];\n /**\n * One or more (query, replacement) pairs. Blocks matched by each query are\n * pruned bottom-up. Queries are combined; a block is pruned if it matches\n * any. This keeps small, frequently repeated constructs cheap to configure.\n */\n rules: { query: string; replacement: Replacement }[];\n}\n\n// ---------------------------------------------------------------------------\n// Pruning workhorse: prune every `statement_block` / `block` node.\n// ---------------------------------------------------------------------------\n\nconst BLOCK = { query: '(statement_block) @block', replacement: { token: '/* ... */' } };\nconst SWIFT_BLOCK = { query: '(statements) @block', replacement: { token: '/* ... */' } };\nconst GO_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst RUST_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst PY_BLOCK = { query: '(block) @block', replacement: { token: 'pass' } };\nconst C_BLOCK = { query: '(compound_statement) @block', replacement: { token: '/* ... */' } };\nconst JAVA_BLOCK = {\n query: '(block) @block',\n replacement: { token: '/* ... */' },\n};\nconst PHP_BLOCK = {\n query: '(compound_statement) @block',\n replacement: { token: '/* ... */' },\n};\nconst KOTLIN_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst DART_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\n\n// Keeps `'use client'`/`'use server'` and top-level directive strings.\nconst DIRECTIVE_KEEP: Replacement = {\n token: '/* ... */',\n keepIf: /^\\s*'use (client|server)'/,\n};\n\nexport const registry: Record<string, LanguageSpec> = {\n typescript: {\n name: 'TypeScript',\n wasm: 'tree-sitter-typescript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-typescript/releases/latest/download/tree-sitter-typescript.wasm',\n extensions: ['.ts', '.cts', '.mts'],\n rules: [BLOCK],\n },\n javascript: {\n name: 'JavaScript',\n wasm: 'tree-sitter-javascript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-javascript/releases/latest/download/tree-sitter-javascript.wasm',\n extensions: ['.js', '.cjs', '.mjs'],\n rules: [BLOCK],\n },\n tsx: {\n name: 'React / Next.js (TSX)',\n wasm: 'tree-sitter-tsx.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-typescript/releases/latest/download/tree-sitter-tsx.wasm',\n extensions: ['.tsx'],\n rules: [{ query: '(statement_block) @block', replacement: DIRECTIVE_KEEP }],\n },\n jsx: {\n name: 'React (JSX)',\n wasm: 'tree-sitter-javascript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-javascript/releases/latest/download/tree-sitter-javascript.wasm',\n extensions: ['.jsx'],\n rules: [{ query: '(statement_block) @block', replacement: DIRECTIVE_KEEP }],\n },\n python: {\n name: 'Python',\n wasm: 'tree-sitter-python.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-python/releases/latest/download/tree-sitter-python.wasm',\n extensions: ['.py', '.pyi'],\n rules: [PY_BLOCK],\n },\n dart: {\n name: 'Dart / Flutter',\n wasm: 'tree-sitter-dart.wasm',\n url: 'https://github.com/UserNobody14/tree-sitter-dart.wasm/releases/latest/download/tree-sitter-dart.wasm',\n extensions: ['.dart'],\n rules: [DART_BLOCK],\n },\n swift: {\n name: 'Swift / SwiftUI',\n wasm: 'tree-sitter-swift.wasm',\n url: 'https://github.com/alex-pinkus/tree-sitter-swift/releases/latest/download/tree-sitter-swift.wasm',\n extensions: ['.swift'],\n rules: [SWIFT_BLOCK],\n },\n go: {\n name: 'Go',\n wasm: 'tree-sitter-go.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-go/releases/latest/download/tree-sitter-go.wasm',\n extensions: ['.go'],\n rules: [GO_BLOCK],\n },\n rust: {\n name: 'Rust',\n wasm: 'tree-sitter-rust.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-rust/releases/latest/download/tree-sitter-rust.wasm',\n extensions: ['.rs'],\n rules: [RUST_BLOCK],\n },\n java: {\n name: 'Java',\n wasm: 'tree-sitter-java.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-java/releases/latest/download/tree-sitter-java.wasm',\n extensions: ['.java'],\n rules: [JAVA_BLOCK],\n },\n kotlin: {\n name: 'Kotlin',\n wasm: 'tree-sitter-kotlin.wasm',\n url: 'https://github.com/fwcd/tree-sitter-kotlin/releases/latest/download/tree-sitter-kotlin.wasm',\n extensions: ['.kt', '.kts'],\n rules: [KOTLIN_BLOCK],\n },\n c: {\n name: 'C',\n wasm: 'tree-sitter-c.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-c/releases/latest/download/tree-sitter-c.wasm',\n extensions: ['.c', '.h'],\n rules: [C_BLOCK],\n },\n cpp: {\n name: 'C++',\n wasm: 'tree-sitter-cpp.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-cpp/releases/latest/download/tree-sitter-cpp.wasm',\n extensions: ['.cc', '.cpp', '.cxx', '.hpp', '.hh', '.hxx'],\n rules: [C_BLOCK],\n },\n php: {\n name: 'PHP',\n wasm: 'tree-sitter-php.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-php/releases/latest/download/tree-sitter-php.wasm',\n extensions: ['.php'],\n rules: [PHP_BLOCK],\n },\n} satisfies Record<string, LanguageSpec>;\n\n/** Map of extension -> language spec id, built once. */\nconst extensionIndex = new Map<string, string>();\nfor (const [id, spec] of Object.entries(registry)) {\n for (const ext of spec.extensions) {\n extensionIndex.set(ext, id);\n }\n}\n\nexport type LanguageId = keyof typeof registry;\n\n/** Return the language spec for a file path, or null if unsupported. */\nexport function languageForFile(filePath: string): LanguageSpec | null {\n const langId = extensionIndex.get(path.extname(filePath).toLowerCase());\n if (!langId) return null;\n return registry[langId];\n}\n\n/** All languages that have at least one prune rule. */\nexport const supportedLanguageIds = Object.keys(registry) as LanguageId[];\n\n/** Convenience: list every known extension. */\nexport const allExtensions = [...extensionIndex.keys()];\n","/**\n * token-shrink — public library entry.\n *\n * Re-exports the pruning engine, language registry, incremental watcher/cache,\n * and context assembler for embedding. To run the servers, see `./cli.js`\n * (HTTP) and `./mcp.js` (MCP stdio), which are the packaged CLIs.\n */\n\nexport { prune, spliceRanges } from './parser/pruner.js';\nexport { languageForFile, registry, supportedLanguageIds, allExtensions } from './parser/registry.js';\nexport type { LanguageSpec, Replacement } from './parser/registry.js';\nexport { getGrammar, warmGrammars } from './parser/wasm.js';\n\nexport {\n createWatcher,\n hashOf,\n extractImports,\n resolveImport,\n DEFAULT_IGNORED,\n} from './watcher/sync.js';\nexport type { CacheEntry, GraphCache, SyncOptions } from './watcher/sync.js';\n\nexport { assemble, extractSpecifiers, approximateTokens } from './server/assembler.js';\nexport type { AssembleOptions, AssembleResult } from './server/assembler.js';\n\nexport { startServer } from './cli.js';\nexport type { CliOptions } from './cli.js';\nexport {\n startMcpServer,\n createAutoRule,\n createCursorRule,\n AUTO_RULE_PATH,\n AUTO_RULE_SENTINEL,\n CURSOR_RULE_PATH,\n CLAUDE_RULE_PATH,\n CLAUDE_RULE_SENTINEL,\n CLINE_RULE_PATH,\n CLINE_RULE_SENTINEL,\n RULE_TARGET_PATH,\n} from './mcp.js';\nexport type { McpServerOptions, RuleWriteResult, RuleTarget } from './mcp.js';\n\nexport const version = '2.0.0';\n","/**\n * Polyglot AST pruning engine. Parses a source file with its language grammar\n * and replaces matched implementation blocks with a compact skeleton token,\n * preserving type signatures, interfaces, and module exports.\n *\n * Range splicing is done bottom-up (descending start offset) so that earlier\n * replacements never shift the byte offsets of later ones.\n */\n\nimport Parser from 'web-tree-sitter';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { languageForFile, type LanguageSpec } from './registry.js';\nimport { getGrammar } from './wasm.js';\n\n/** A byte-range that will be replaced by `token`. */\ninterface PruneRange {\n start: number;\n end: number;\n token: string;\n}\n\n/**\n * Cache of decoded web-tree-sitter Language objects, keyed by grammar file\n * name. Grammar bytes only change when the on-disk binary changes, so we can\n * decode once per process and reuse it across all parses for that language.\n */\nconst languageCache = new Map<string, Parser.Language>();\n\nlet initPromise: Promise<void> | null = null;\n/** `Parser.init()` only needs to run once; make concurrent calls share it. */\nexport function ensureParserInit(): Promise<void> {\n if (!initPromise) {\n initPromise = Parser.init({\n locateFile: (file: string) => {\n // Point the wasm runtime at the bundled tree-sitter.wasm so it works\n // from tsup's dist build as well as from node_modules. `__filename` is\n // shimmed by tsup for ESM and native in CJS, avoiding the empty\n // `import.meta.url` that crashes the CJS CLI bundle.\n const require = createRequire(__filename);\n try {\n const pkgRoot = path.dirname(require.resolve('web-tree-sitter/package.json'));\n return path.join(pkgRoot, file);\n } catch {\n return file;\n }\n },\n });\n }\n return initPromise;\n}\n\n/** Load (and cache) a decoded Language object for a language spec. */\nexport function loadLanguage(spec: LanguageSpec, force = false): Promise<Parser.Language> {\n if (!force) {\n const cached = languageCache.get(spec.wasm);\n if (cached) return Promise.resolve(cached);\n }\n // Force re-download/re-decode and refresh the cache.\n if (force) languageCache.delete(spec.wasm);\n return (async () => {\n await ensureParserInit();\n const grammar = await getGrammar(spec, force);\n const language = await Parser.Language.load(grammar);\n languageCache.set(spec.wasm, language);\n return language;\n })();\n}\n\n/**\n * Prune the implementation bodies out of `source` (a file at `filePath`).\n * If the language has no registered rules, returns the source unchanged.\n */\nexport async function prune(\n filePath: string,\n source: string,\n opts: { forceDownload?: boolean } = {},\n): Promise<{ code: string; language: string | null; removed: number }> {\n const spec = languageForFile(filePath);\n if (!spec || spec.rules.length === 0) {\n return { code: source, language: null, removed: 0 };\n }\n\n const language = await loadLanguage(spec, opts.forceDownload);\n\n const parser = new Parser();\n parser.setLanguage(language);\n const tree = parser.parse(source);\n\n const ranges: PruneRange[] = [];\n for (const rule of spec.rules) {\n const query = language.query(rule.query);\n const captures = query.captures(tree.rootNode);\n for (const cap of captures) {\n // Skip captures whose source text is empty (there's nothing to shrink).\n if (cap.node.startIndex === cap.node.endIndex) continue;\n // Allow rules to keep certain blocks (e.g. 'use client/server').\n if (rule.replacement.keepIf?.test(cap.node.text)) continue;\n ranges.push({\n start: cap.node.startIndex,\n end: cap.node.endIndex,\n token: rule.replacement.token,\n });\n }\n query.delete();\n }\n tree.delete();\n parser.delete();\n\n const { code, removed } = spliceRanges(source, ranges);\n return { code, language: spec.name, removed };\n}\n\n/**\n * Replace all ranges with their tokens. Ranges are pre-sorted descending by\n * start offset so each splice happens at the tail of the string first,\n * keeping earlier offsets stable.\n */\nexport function spliceRanges(source: string, ranges: PruneRange[]): {\n code: string;\n removed: number;\n} {\n let removed = 0;\n const sorted = [...ranges].sort((a, b) => b.start - a.start);\n let out = source;\n for (const r of sorted) {\n if (r.start < 0 || r.end > out.length || r.end < r.start) continue;\n removed += r.end - r.start;\n out = out.slice(0, r.start) + r.token + out.slice(r.end);\n }\n return { code: out, removed };\n}\n\n","/**\n * WASM grammar acquisition. Lazily downloads a language's `.wasm` grammar\n * from its upstream GitHub release on first use and caches it on disk in a\n * `wasm/` directory at the project root (mirrored to `dist/wasm` by tsup).\n *\n * `Language.load` on Node expects either a Uint8Array of the real parser\n * bytes or a filesystem path; we hand it the raw bytes via `getGrammar`,\n * which returns a `Uint8Array` for the pruner to load directly.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { LanguageSpec } from './registry.js';\n\n// `__dirname` is shimmed automatically by tsup so it works in both ESM and\n// CJS output: in ESM it derives from import.meta.url, in CJS it is native.\n// This avoids calling fileURLToPath(import.meta.url), which is empty in the\n// CJS bundle and would crash the packaged CLI (`dist/cli.cjs`, `dist/mcp.cjs`).\n/**\n * Resolve the `wasm/` cache directory, preferring the packaged copy.\n * Candidates are searched in order: project `wasm/`, `dist/wasm/`.\n */\nfunction resolveWasmDir(): string {\n const candidates = [\n path.resolve(__dirname, '../../wasm'),\n path.resolve(__dirname, '../wasm'),\n path.resolve(process.cwd(), 'wasm'),\n ];\n for (const dir of candidates) {\n try {\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n /* try next */\n }\n }\n const dir = path.resolve(process.cwd(), 'wasm');\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nlet wasmDir: string | null = null;\nfunction cacheDir(): string {\n if (!wasmDir) wasmDir = resolveWasmDir();\n return wasmDir;\n}\n\nexport function cachePath(spec: LanguageSpec): string {\n return path.join(cacheDir(), spec.wasm);\n}\n\n/** True if the head bytes are the wasm magic `\\0asm`. */\nfunction looksLikeWasm(bytes: Uint8Array): boolean {\n return (\n bytes.length >= 4 &&\n bytes[0] === 0 &&\n bytes[1] === 97 &&\n bytes[2] === 115 &&\n bytes[3] === 109\n );\n}\n\n/** In-flight downloads keyed by wasm filename, so concurrent callers share one. */\nconst inflight = new Map<string, Promise<Uint8Array>>();\n\nfunction download(spec: LanguageSpec): Promise<Uint8Array> {\n const pending = inflight.get(spec.wasm);\n if (pending) return pending;\n const job = (async () => {\n const res = await fetch(spec.url, { redirect: 'follow' });\n if (!res.ok) {\n throw new Error(\n `Failed to download grammar \"${spec.wasm}\" from ${spec.url} (HTTP ${res.status})`,\n );\n }\n const bytes = new Uint8Array(await res.arrayBuffer());\n if (!looksLikeWasm(bytes)) {\n throw new Error(\n `Downloaded grammar \"${spec.wasm}\" is not valid WebAssembly (got HTML/redirect).`,\n );\n }\n // Write atomically (tmp file + rename) so a concurrent reader never\n // observes a partially-written grammar.\n const target = cachePath(spec);\n const tmp = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, bytes);\n fs.renameSync(tmp, target);\n inflight.delete(spec.wasm);\n return bytes;\n })().catch((err) => {\n inflight.delete(spec.wasm);\n throw err;\n });\n inflight.set(spec.wasm, job);\n return job;\n}\n\n/**\n * Return the raw grammar bytes for a language, downloading them if needed.\n * `force` bypasses the local disk cache (used by tests / `--warm`).\n */\nexport async function getGrammar(\n spec: LanguageSpec,\n force = false,\n): Promise<Uint8Array> {\n if (!force && fs.existsSync(cachePath(spec))) {\n const cached = fs.readFileSync(cachePath(spec));\n if (looksLikeWasm(cached)) return cached;\n }\n return download(spec);\n}\n\n/**\n * Pre-download every supported grammar (used on cold boot / `prune --warm`).\n * Returns the number of grammars that are ready on disk afterward.\n */\nexport async function warmGrammars(specs: LanguageSpec[] = []): Promise<number> {\n const registryModule = await import('./registry.js');\n const list =\n specs.length > 0 ? specs : (Object.values(registryModule.registry) as LanguageSpec[]);\n const unique = new Map<string, LanguageSpec>();\n for (const spec of list) unique.set(spec.wasm, spec);\n const results = await Promise.allSettled(\n [...unique.values()].map((spec) => getGrammar(spec)),\n );\n return results.filter((r) => r.status === 'fulfilled').length;\n}\n\n","/**\n * Incremental synchronization layer (Phase 3).\n *\n * - Watches the repository with chokidar (ignoring vendor/build dirs).\n * - On add/change, hashes the file and, if the hash changed, re-prunes it and\n * updates the in-memory graph cache.\n * - Extracts import/require specifiers from each file and normalizes relative\n * and aliased paths to absolute file paths on disk.\n *\n * The graph cache is shared with the Context Assembler, which reads ring-1\n * skeletons out of it.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\n\nimport chokidar, { type FSWatcher, type Matcher } from 'chokidar';\n\nimport { ensureParserInit, prune } from '../parser/pruner.js';\n\nexport type { Matcher };\n\n/** Default paths that will never be indexed or watched. */\nexport const DEFAULT_IGNORED = [\n /(^|[/\\\\])\\.[^/\\\\]+/, // dotfiles / dot-dirs (.git, .cursor, .env, ...)\n /node_modules/,\n /[/\\\\](build|dist|out|coverage|\\.next|\\.turbo|\\.cache)[/\\\\]/,\n];\n\nexport interface CacheEntry {\n /** sha1 of the last-indexed file content. */\n hash: string;\n /** Pruned skeleton for this file. */\n skeleton: string;\n /** The language name used to prune it (or null if unsupported). */\n language: string | null;\n /** Absolute paths of the files this file imports. */\n imports: string[];\n}\n\nexport type GraphCache = Map<string, CacheEntry>;\n\nexport class ContextCache {\n readonly entries: GraphCache = new Map();\n private initPromise: Promise<void> | null = null;\n\n ensureInit(): Promise<void> {\n if (!this.initPromise) {\n this.initPromise = ensureParserInit();\n }\n return this.initPromise;\n }\n\n /** Returns the cached skeleton for a file, if present. */\n getSkeleton(filePath: string): CacheEntry | null {\n return this.entries.get(path.resolve(filePath)) ?? null;\n }\n\n get imports() {\n return this.entries;\n }\n}\n\n/** Compute a sha1 of a string. */\nexport function hashOf(text: string): string {\n return createHash('sha1').update(text).digest('hex');\n}\n\n/**\n * Extract import/require specifiers from source text using a robust,\n * language-agnostic regex (AST-based import queries are grammar-fragile and\n * occasionally malformed; regex covers the common import forms across JS/TS,\n * Python, Go, Rust, Dart, Swift, Java, Kotlin, PHP, C/C++).\n * Returns the matched specifier strings (may be relative or absolute).\n */\nexport function extractImports(_filePath: string, source: string): string[] {\n const out: string[] = [];\n\n // import ... from 'x' | import 'x' | require('x')\n const re =\n /(?:from\\s+['\"`]([^'\"`]+)['\"`]|import\\s+['\"`]([^'\"`]+)['\"`]|require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\))/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n const spec = m[1] ?? m[2] ?? m[3];\n if (spec) out.push(spec);\n }\n\n // Python / Go / Rust / Dart / Swift / Java / Kotlin / C/C++ single-quote not\n // covered by the JS-style regex is out of scope for the first pass.\n\n return [...new Set(out)].filter(Boolean);\n}\n\n/** Normalize a specifier to an absolute file path when it resolves locally. */\nexport function resolveImport(\n importer: string,\n specifier: string,\n root: string,\n): string | null {\n // Skip bare, non-relative imports (npm packages) and obviously external.\n if (!/^[.~@]/.test(specifier)) {\n // Alias `@/...` and `~` map to the project root.\n if (specifier.startsWith('@/')) {\n return resolveCandidate(path.join(root, specifier.slice(2)));\n }\n if (specifier.startsWith('@')) {\n return null; // scoped package, not local\n }\n if (specifier.startsWith('~')) {\n return resolveCandidate(path.join(root, specifier.slice(1)));\n }\n return null;\n }\n\n const base = path.dirname(path.resolve(importer));\n return resolveCandidate(path.resolve(base, specifier));\n}\n\n/** Try a specifier with common extension/index additions. */\nfunction resolveCandidate(p: string): string | null {\n const candidates = [\n p,\n `${p}.ts`,\n `${p}.tsx`,\n `${p}.js`,\n `${p}.jsx`,\n `${p}.mjs`,\n `${p}.cjs`,\n `${p}.py`,\n `${p}.go`,\n `${p}.rs`,\n `${p}.dart`,\n `${p}.swift`,\n `${p}.java`,\n `${p}.kt`,\n `${p}.c`,\n `${p}.cpp`,\n `${p}.h`,\n `${p}.hpp`,\n `${p}.php`,\n path.join(p, 'index.ts'),\n path.join(p, 'index.js'),\n path.join(p, 'index.tsx'),\n path.join(p, 'index.jsx'),\n path.join(p, 'index.py'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c) && fs.statSync(c).isFile()) return path.resolve(c);\n }\n return null;\n}\n\nexport interface SyncOptions {\n root: string;\n ignored?: Matcher[];\n onIndexed?: (filePath: string, entry: CacheEntry) => void;\n}\n\n/**\n * Watch a project root and keep the graph cache fresh. Returns the cache and\n * a close() handle. `prune` is awaited per change to keep hot-reload latency\n * predictable.\n */\nexport function createWatcher(opts: SyncOptions) {\n const cache = new ContextCache();\n const { root, ignored = DEFAULT_IGNORED, onIndexed } = opts;\n\n // Debounce a burst of events into a single re-prune per file.\n const pending = new Map<string, NodeJS.Timeout>();\n const DEBOUNCE_MS = 100;\n\n async function handle(filePath: string) {\n const abs = path.resolve(filePath);\n let source: string;\n try {\n const st = fs.statSync(abs);\n if (!st.isFile()) return; // sockets/symlinks etc.\n source = fs.readFileSync(abs, 'utf8');\n } catch {\n return; // file vanished between event and read\n }\n const hash = hashOf(source);\n const cached = cache.entries.get(abs);\n if (cached && cached.hash === hash) return; // unchanged\n\n await cache.ensureInit();\n const { code, language } = await prune(abs, source);\n const imports = await extractImports(abs, source);\n const entry: CacheEntry = {\n hash,\n skeleton: code,\n language,\n imports: imports\n .map((spec) => resolveImport(abs, spec, root))\n .filter((p): p is string => p !== null),\n };\n cache.entries.set(abs, entry);\n onIndexed?.(abs, entry);\n }\n\n const watcher: FSWatcher = chokidar.watch(root, {\n // Combine path matchers with a stat check so non-regular files (e.g. unix\n // sockets) are never opened with fs.watch (which raises UVException).\n ignored(_p, stats) {\n if (stats && !stats.isFile() && !stats.isDirectory()) return true;\n return isIgnored(path.resolve(String(_p)), ignored);\n },\n alwaysStat: true,\n ignoreInitial: true,\n persistent: true,\n awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 10 },\n });\n\n function debounce(filePath: string) {\n const abs = path.resolve(filePath);\n const existing = pending.get(abs);\n if (existing) clearTimeout(existing);\n // Fire immediately on the first event, then coalesce noise.\n if (!existing) void handle(abs);\n pending.set(\n abs,\n setTimeout(() => pending.delete(abs), DEBOUNCE_MS),\n );\n }\n\n watcher.on('add', debounce);\n watcher.on('change', debounce);\n watcher.on('unlink', (filePath: string) => {\n const abs = path.resolve(filePath);\n cache.entries.delete(abs);\n });\n\n return {\n cache,\n watcher,\n /** Index an existing file right now (bypasses the watcher). */\n index: handle,\n /**\n * Index the whole tree once (cold start). Returns the number of files\n * successfully indexed.\n */\n async indexAll(): Promise<number> {\n const files: string[] = [];\n await walk(root, (f) => files.push(f), ignored);\n let ok = 0;\n for (const f of files) {\n try {\n await handle(f);\n ok++;\n } catch {\n /* skip unparseable files */\n }\n }\n return ok;\n },\n close: () => watcher.close(),\n };\n}\n\n/** Recursively list supported source files, honoring ignore patterns. */\nasync function walk(\n root: string,\n push: (f: string) => void,\n ignored: Matcher[],\n): Promise<void> {\n const entries = await fs.promises.readdir(root, { withFileTypes: true });\n for (const e of entries) {\n const abs = path.join(root, e.name);\n if (isIgnored(abs, ignored)) continue;\n if (e.isDirectory()) {\n await walk(abs, push, ignored);\n } else if (e.isFile()) {\n push(abs);\n }\n // Skip sockets, symlinks to non-files, devices, etc. to avoid chokidar/fs\n // throwing UVException while trying to watch them.\n }\n}\n\nfunction isIgnored(abs: string, ignored: Matcher[]): boolean {\n for (const m of ignored) {\n if (typeof m === 'string' && abs.includes(m)) return true;\n if (m instanceof RegExp && m.test(abs)) return true;\n }\n return false;\n}\n","/**\n * Context Assembler (Phase 4). Produces a Markdown context payload from the\n * graph cache:\n *\n * Ring 0 — the active file's raw, full text.\n * Ring 1 — pruned skeletons of the files it directly imports.\n *\n * The payload keeps full type signatures (imports, interfaces, exports) while\n * dropping implementation bodies, delivering the 80–90% reduction target.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { GraphCache } from '../watcher/sync.js';\n\nexport interface AssembleOptions {\n /** Number of PRD-style stats to append (disabled by default). */\n includeStats?: boolean;\n /** Maximum number of ring-1 files to include. */\n maxSkeletons?: number;\n /** Whether the active file itself should also be pruned (Ring 0 raw by default). */\n pruneActiveFile?: boolean;\n}\n\nexport interface AssembleResult {\n /** Human-readable Markdown payload for an agent. */\n markdown: string;\n activeFilePath: string;\n /** Ring-0 full text of the active file. */\n activeSource: string;\n /** Ring-1 entries actually included. */\n included: { filePath: string; language: string | null }[];\n /** Paths referenced by imports that could not be resolved to a file. */\n unresolved: string[];\n}\n\n/**\n * Build the compressed context for an open file.\n * `activeFilePath` may be absolute or project-relative.\n */\nexport function assemble(\n activeFilePath: string,\n cache: GraphCache,\n opts: AssembleOptions = {},\n): AssembleResult {\n const { includeStats = false, maxSkeletons = 50, pruneActiveFile = false } = opts;\n\n const abs = path.resolve(activeFilePath);\n const activeSource = fs.existsSync(abs) ? fs.readFileSync(abs, 'utf8') : '';\n const activeEntry = cache.get(abs);\n\n const included: AssembleResult['included'] = [];\n const unresolved: string[] = [];\n\n // Ring 1: walk the active file's direct imports.\n const seen = new Set<string>();\n if (activeEntry) {\n for (const imp of activeEntry.imports) {\n const entry = cache.get(imp);\n if (!entry) {\n unresolved.push(imp);\n continue;\n }\n if (seen.has(imp)) continue;\n seen.add(imp);\n included.push({ filePath: imp, language: entry.language });\n if (included.length >= maxSkeletons) break;\n }\n }\n\n // If the active file is unsupported (no cache entry), try to resolve its\n // imports on the fly from disk so the payload is still useful.\n if (!activeEntry && activeSource) {\n // Fallback: derive imports from a lightweight regex and resolve from disk.\n const specifiers = extractSpecifiers(activeSource);\n for (const spec of specifiers) {\n const resolved = resolveLocal(abs, spec);\n if (!resolved) {\n unresolved.push(spec);\n continue;\n }\n if (seen.has(resolved)) continue;\n seen.add(resolved);\n const cached = cache.get(resolved);\n included.push({ filePath: resolved, language: cached?.language ?? null });\n if (included.length >= maxSkeletons) break;\n }\n }\n\n const lines: string[] = [];\n lines.push('# Compressed Code Context', '');\n lines.push(`Active file: \\`${rel(abs)}\\``, '');\n\n // Ring 0.\n lines.push('## Ring 0 — Active file (full text)', '');\n const ring0 = pruneActiveFile && activeEntry ? activeEntry.skeleton : activeSource;\n lines.push(`\\`\\`\\`${ext(activeFilePath)}`);\n lines.push(ring0.trim() || '(empty or unreadable file)');\n lines.push('```', '');\n\n // Ring 1.\n lines.push(\n `## Ring 1 — Pruned dependencies (${included.length})`,\n '',\n 'Implementation bodies removed; type signatures, interfaces and exports retained.',\n '',\n );\n if (included.length === 0) {\n lines.push('_No local dependency skeletons available._', '');\n }\n for (const inc of included) {\n const entry = cache.get(inc.filePath);\n const label = rel(inc.filePath);\n lines.push(`### \\`${label}\\``, '');\n if (entry) {\n lines.push(`\\`\\`\\`${ext(inc.filePath)}`);\n lines.push(entry.skeleton.trim());\n lines.push('```', '');\n } else {\n lines.push('_Unindexed file._', '');\n }\n }\n\n if (unresolved.length > 0) {\n lines.push('## Unresolved imports', '');\n for (const u of unresolved) lines.push(`- \\`${u}\\``);\n lines.push('');\n }\n\n if (includeStats) {\n const depTokens = included.reduce(\n (acc, inc) => {\n const e = cache.get(inc.filePath);\n return e ? acc + approximateTokens(e.skeleton) : acc;\n },\n 0,\n );\n lines.push('---', '');\n lines.push(\n `_Token estimate — active: ${approximateTokens(activeSource)} · pruned deps: ${depTokens}._`,\n '',\n );\n }\n\n return {\n markdown: lines.join('\\n'),\n activeFilePath: abs,\n activeSource,\n included,\n unresolved,\n };\n}\n\n/** Fallback import specifier extraction when no AST index exists yet. */\nexport function extractSpecifiers(source: string): string[] {\n const found: string[] = [];\n // import ... from 'x'; / import 'x'; / require('x')\n const re = /(?:from\\s+['\"`]|import\\s+['\"`]|require\\s*\\(\\s*['\"`])([^'\"`]+)['\"`]/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n if (m[1]) found.push(m[1]);\n }\n return [...new Set(found)];\n}\n\n/** Resolve a fallback specifier to an existing file, mirroring sync.resolveImport. */\nfunction resolveLocal(importer: string, specifier: string): string | null {\n if (!/^[.~@]/.test(specifier)) return null;\n if (specifier.startsWith('@/')) specifier = specifier.slice(2);\n else if (specifier.startsWith('~')) specifier = specifier.slice(1);\n const base = path.dirname(path.resolve(importer));\n const p = path.resolve(base, specifier);\n const candidates = [\n p,\n `${p}.ts`,\n `${p}.tsx`,\n `${p}.js`,\n `${p}.jsx`,\n `${p}.py`,\n `${p}.go`,\n `${p}.rs`,\n `${p}.dart`,\n `${p}.swift`,\n `${p}.java`,\n `${p}.kt`,\n `${p}.c`,\n `${p}.cpp`,\n path.join(p, 'index.ts'),\n path.join(p, 'index.js'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c) && fs.statSync(c).isFile()) return path.resolve(c);\n }\n return null;\n}\n\n/** Relative path for display (fall back to basename). */\nfunction rel(p: string): string {\n try {\n const cwd = process.cwd();\n if (p.startsWith(cwd)) return '.' + p.slice(cwd.length);\n } catch {\n /* noop */\n }\n return p;\n}\n\n/** Return a code-block language label for a file path. */\nfunction ext(p: string): string {\n return path.extname(p).replace(/^\\./, '') || 'text';\n}\n\n/** Rough, dependency-free token approximation (words + punctuation runs). */\nexport function approximateTokens(text: string): number {\n if (!text) return 0;\n const tokens = text.match(/[A-Za-z0-9_$]+|[^A-Za-z0-9_\\s$]/g);\n return tokens ? tokens.length : 0;\n}\n\nexport function assembleFromCache(\n activeFilePath: string,\n cache: GraphCache,\n): AssembleResult {\n return assemble(activeFilePath, cache);\n}\n","/**\n * HTTP/CLI server. Exposes the context assembler as a small Fastify service:\n *\n * GET /health -> liveness\n * POST /v1/context -> { activeFilePath, maxSkeletons?, includeStats? } => markdown\n *\n * Run as `token-shrink` or `node dist/cli.js`. The server watches `--root`\n * (defaults to cwd) and keeps the import graph + skeletons warm.\n */\n\nimport Fastify from 'fastify';\nimport picocolors from 'picocolors';\nimport path from 'node:path';\n\nimport { assemble } from './server/assembler.js';\nimport { createWatcher, type Matcher } from './watcher/sync.js';\nimport { warmGrammars } from './parser/wasm.js';\n\nexport interface CliOptions {\n port?: number;\n host?: string;\n root?: string;\n ignored?: Matcher[];\n silent?: boolean;\n}\n\nfunction parseArgv(argv = process.argv): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < argv.length; i++) {\n const cur = argv[i];\n if (cur?.startsWith('--')) {\n const key = cur.slice(2);\n const next = argv[i + 1];\n if (next && !next.startsWith('--')) {\n out[key] = next;\n i++;\n } else {\n out[key] = 'true';\n }\n }\n }\n return out;\n}\n\n/** Start the Fastify server; returns the running instance + watcher handle. */\nexport async function startServer(opts: CliOptions = {}) {\n const args = parseArgv();\n const port = opts.port ?? Number(args.port ?? process.env.PORT ?? 3000);\n const host = opts.host ?? args.host ?? '0.0.0.0';\n const root = path.resolve(opts.root ?? args.root ?? process.cwd());\n const silent = opts.silent ?? args.silent === 'true';\n\n const log = (msg: string) => {\n if (!silent) console.log(picocolors.dim(msg));\n };\n\n // Warm grammars in the background so the first prune isn't slow.\n void warmGrammars().catch(() => {});\n\n const watcher = createWatcher({ root, ignored: opts.ignored });\n log(`Indexing ${root} in the background…`);\n void watcher.indexAll().then((n) => log(`Indexed ${n} files.`));\n\n const app = Fastify({ logger: !silent });\n\n app.get('/health', async () => ({\n status: 'ok',\n service: 'token-shrink',\n version: '2.0.0',\n root,\n indexed: watcher.cache.entries.size,\n }));\n\n app.post('/v1/context', async (req, reply) => {\n const body = (req.body ?? {}) as {\n activeFilePath?: string;\n maxSkeletons?: number;\n includeStats?: boolean;\n };\n if (!body.activeFilePath) {\n return reply.status(400).send({ error: '`activeFilePath` is required' });\n }\n const result = assemble(body.activeFilePath, watcher.cache.entries, {\n maxSkeletons: body.maxSkeletons,\n includeStats: body.includeStats,\n });\n return {\n markdown: result.markdown,\n activeFilePath: result.activeFilePath,\n dependencies: result.included.map((i) => i.filePath),\n unresolved: result.unresolved,\n };\n });\n\n app.setNotFoundHandler(async (req, reply) => {\n void req;\n return reply.status(404).send({ error: 'Not found' });\n });\n\n await app.listen({ port, host });\n log(`Listening on http://${host}:${port}`);\n\n return { app, watcher };\n}\n\n// Start when invoked directly (`node dist/cli.cjs` / `token-shrink`).\nconst argv1 = process.argv[1] ? path.basename(process.argv[1]) : '';\nif (\n argv1 === 'cli.js' || argv1 === 'cli.mjs' ||\n argv1 === 'cli.cjs' || argv1 === 'cli.ts'\n) {\n startServer().catch((err) => {\n console.error(picocolors.red(`[token-shrink] ${err.message}`));\n process.exitCode = 1;\n });\n}\n","/**\n * MCP stdio server. Exposes a single tool:\n *\n * get_compressed_code_context({ activeFilePath, maxSkeletons?, includeStats? })\n *\n * It maintains its own graph cache by watching the repository root derived\n * from the active file, so Cursor/Claude/Cline agents can request pruned context.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { assemble } from './server/assembler.js';\nimport { createWatcher, type Matcher } from './watcher/sync.js';\n\n/** Supported auto-rule integration targets. */\nexport type RuleTarget = 'cursor' | 'claude' | 'cline';\n\n/** Agent integration file descriptors written when the auto-rule is on. */\ninterface RuleTargetSpec {\n relPath: string;\n sentinel: string;\n body: string;\n}\n\nexport const RULE_TARGET_PATH = {\n cursor: '.cursor/rules/token-shrink.mdc',\n claude: '.claude/rules/token-shrink.md',\n cline: '.clinerules/token-shrink.md',\n} as const;\n\nexport const AUTO_RULE_SENTINEL = '# auto-generated by token-shrink';\nexport const CURSOR_RULE_PATH = RULE_TARGET_PATH.cursor;\n/** Back-compat alias for the previous single-target constant. */\nexport const AUTO_RULE_PATH = CURSOR_RULE_PATH;\nexport const CLAUDE_RULE_PATH = RULE_TARGET_PATH.claude;\nexport const CLAUDE_RULE_SENTINEL = '# auto-generated by token-shrink (claude)';\nexport const CLINE_RULE_PATH = RULE_TARGET_PATH.cline;\nexport const CLINE_RULE_SENTINEL = '# auto-generated by token-shrink (cline)';\n\nconst ruleTargets: Record<RuleTarget, RuleTargetSpec> = {\n cursor: {\n relPath: CURSOR_RULE_PATH,\n sentinel: AUTO_RULE_SENTINEL,\n body: `---\ndescription: Compress dependency context with token-shrink on every task\nglobs: **/*.{ts,tsx,js,jsx,py,go,rs,dart,swift,java,kt,c,cpp,h,hpp,php}\nalwaysApply: true\n---\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${AUTO_RULE_SENTINEL}\n`,\n },\n claude: {\n relPath: CLAUDE_RULE_PATH,\n sentinel: CLAUDE_RULE_SENTINEL,\n body: `---\ndescription: Compress dependency context with token-shrink on every task\npaths: [\"**/*.{ts,tsx,js,jsx,py,go,rs,dart,swift,java,kt,c,cpp,h,hpp,php}\"]\n---\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${CLAUDE_RULE_SENTINEL}\n`,\n },\n cline: {\n relPath: CLINE_RULE_PATH,\n sentinel: CLINE_RULE_SENTINEL,\n // No frontmatter -> always-on rule (Cline treats unconditional .clinerules/*.md\n // files as universal rules, applied to every task regardless of active file).\n body: `# token-shrink\n\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${CLINE_RULE_SENTINEL}\n`,\n },\n};\n\nexport interface McpServerOptions {\n /** Project root. Defaults to cwd. */\n root?: string;\n /** Extra ignore globs for the watcher. */\n ignored?: Matcher[];\n /** Silence log output (stdio must stay clean for the MCP protocol). */\n silent?: boolean;\n /** Whether to auto-write agent integration rules at all. Default true. */\n createRule?: boolean;\n /** Which agent rule target(s) to write. Default all. */\n ruleTarget?: RuleTarget | RuleTarget[];\n}\n\nexport interface RuleWriteResult {\n created: boolean;\n skipped: 'none' | 'exists' | 'user';\n /** Path of the rule file that was considered. */\n filePath: string;\n}\n\n/**\n * Write a rules file for a given agent target. Idempotent:\n * - absent -> create it (tagged with our sentinel);\n * - has our sentinel -> skip (already ours);\n * - present without sentinel -> leave the user's file untouched.\n */\nexport function createAutoRule(root: string, target: RuleTarget): RuleWriteResult {\n const spec = ruleTargets[target];\n const rulePath = path.join(root, spec.relPath);\n try {\n if (fs.existsSync(rulePath)) {\n const existing = fs.readFileSync(rulePath, 'utf8');\n if (existing.includes(spec.sentinel)) {\n return { created: false, skipped: 'exists', filePath: rulePath };\n }\n return { created: false, skipped: 'user', filePath: rulePath };\n }\n fs.mkdirSync(path.dirname(rulePath), { recursive: true });\n fs.writeFileSync(rulePath, spec.body, 'utf8');\n return { created: true, skipped: 'none', filePath: rulePath };\n } catch (err) {\n // Never let a rule-write failure take down the MCP server; surface via result.\n process.stderr.write(\n `[token-shrink] Failed to write rule for \"${target}\": ${(err as Error).message}\\n`,\n );\n return { created: false, skipped: 'none', filePath: rulePath };\n }\n}\n\n/** Back-compat alias for code that imported the old Cursor-only helper. */\nexport function createCursorRule(root: string): RuleWriteResult {\n return createAutoRule(root, 'cursor');\n}\n\n/** Expand `ruleTarget` (single / array / all) into the ordered list to write. */\nfunction resolveTargets(ruleTarget: McpServerOptions['ruleTarget']): RuleTarget[] {\n if (!ruleTarget) return ['cursor', 'claude', 'cline'];\n const list = Array.isArray(ruleTarget) ? ruleTarget : [ruleTarget];\n if (list.includes('all' as unknown as RuleTarget)) return ['cursor', 'claude', 'cline'];\n return list;\n}\n\n/**\n * Start the MCP server. Because the MCP protocol runs over stdio, all human\n * logging should go to stderr; stdout is reserved for JSON-RPC.\n */\nexport async function startMcpServer(opts: McpServerOptions = {}): Promise<McpServer> {\n const root = path.resolve(opts.root ?? process.env.ROOT ?? process.cwd());\n const log = (msg: string) => {\n if (!opts.silent) process.stderr.write(`[token-shrink] ${msg}\\n`);\n };\n\n const watcher = createWatcher({ root, ignored: opts.ignored });\n if (!opts.silent) {\n log(`Indexing ${root} in the background…`);\n }\n\n // Auto-create agent integration rules so the tool is used by default.\n if (opts.createRule !== false) {\n for (const target of resolveTargets(opts.ruleTarget)) {\n const res = createAutoRule(root, target);\n if (res.created) {\n log(`Wrote ${target} rule to ${res.filePath}`);\n } else if (res.skipped === 'user') {\n log(`${target} rule exists (user-authored); leaving it untouched.`);\n }\n }\n }\n // Fire-and-forget cold start; zero CPU afterward thanks to the watcher.\n void watcher.indexAll().then((n) => log(`Indexed ${n} files.`));\n\n const server = new McpServer(\n { name: 'token-shrink', version: '2.0.0' },\n { capabilities: { tools: {} } },\n );\n\n server.registerTool(\n 'get_compressed_code_context',\n {\n title: 'Get Compressed Code Context',\n description:\n 'Returns a compressed, framework-aware AST context payload for a file: ' +\n 'the active file’s full source (Ring 0) plus pruned skeletons of its direct ' +\n 'imports (Ring 1). Implementation bodies are removed but type signatures, ' +\n 'interfaces, and module exports are preserved for ~80-90% token reduction.',\n inputSchema: {\n activeFilePath: z.string().describe('Path to the file the agent is working on'),\n maxSkeletons: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Cap on number of dependency skeletons to include'),\n includeStats: z\n .boolean()\n .optional()\n .describe('Append approximate token-count stats'),\n },\n },\n async ({ activeFilePath, maxSkeletons, includeStats }) => {\n const result = assemble(activeFilePath, watcher.cache.entries, {\n maxSkeletons,\n includeStats,\n });\n return {\n content: [\n {\n type: 'text' as const,\n text: result.markdown,\n },\n {\n type: 'text' as const,\n text: `[stats] active=${result.activeFilePath} dependencies=${result.included.length} unresolved=${result.unresolved.length}`,\n },\n ],\n };\n },\n );\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log('MCP server connected.');\n return server;\n}\n\n// Start the server only when run as the MCP binary (`dist/mcp.cjs`), not when\n// imported as a library. Guard against both the source and bundled filenames.\nconst argv1 = process.argv[1] ? path.basename(process.argv[1]) : '';\nif (\n argv1 === 'mcp.js' || argv1 === 'mcp.mjs' ||\n argv1 === 'mcp.cjs' || argv1 === 'mcp.ts'\n) {\n const rootArg = (() => {\n const i = process.argv.indexOf('--root');\n if (i !== -1 && process.argv[i + 1]) return process.argv[i + 1];\n const eq = process.argv.find((a) => a.startsWith('--root='));\n if (eq) return eq.slice('--root='.length);\n return undefined;\n })();\n const createRule = !(\n process.env.TOKEN_SHRINK_CREATE_RULE === '0' ||\n process.env.TOKEN_SHRINK_CREATE_RULE === 'false' ||\n process.env.CONTEXT_SHRINK_CREATE_RULE === '0' ||\n process.env.CONTEXT_SHRINK_CREATE_RULE === 'false' ||\n process.argv.includes('--no-create-rule') ||\n (() => {\n const f = process.argv.find((a) => a.startsWith('--create-rule='));\n return f ? f.slice('--create-rule='.length) === 'false' : false;\n })()\n );\n // --rule-target=cursor|claude|cline|all (repeatable / comma-separated), default all.\n const rawTargets = process.argv\n .filter((a) => a.startsWith('--rule-target='))\n .flatMap((a) => a.slice('--rule-target='.length).split(','));\n const ruleTarget: RuleTarget | RuleTarget[] | undefined =\n rawTargets.length > 0 && !rawTargets.includes('all')\n ? ([...new Set(rawTargets)].filter(\n (v): v is RuleTarget => v === 'cursor' || v === 'claude' || v === 'cline',\n ) as RuleTarget[])\n : undefined;\n void startMcpServer({ root: rootArg, createRule, ruleTarget }).catch((err) => {\n process.stderr.write(`[token-shrink] MCP server error: ${err.message}\\n`);\n process.exitCode = 1;\n });\n}\n"],"mappings":"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","names":["path","ext","import_node_path","import_node_path","path","dir","fs","Parser","require","path","import_node_fs","import_node_path","path","fs","chokidar","import_node_fs","import_node_path","path","fs","import_node_path","path","picocolors","Fastify","import_node_fs","import_node_path","path","fs","argv1"]}
1
+ {"version":3,"sources":["../src/parser/registry.ts","../src/index.ts","../src/parser/analyze.ts","../src/parser/wasm.ts","../src/parser/symbols.ts","../src/detect.ts","../src/search/index.ts","../src/config.ts","../src/watcher/sync.ts","../src/server/assembler.ts","../src/cli.ts","../src/mcp.ts","../src/git.ts"],"sourcesContent":["/**\n * Language registry mapping file extensions to tree-sitter grammars and\n * pruning strategies. Each spec defines:\n * - the web-tree-sitter language name\n * - the `.wasm` file and the authoritative download URL\n * - one or more S-expression queries (the \"prune query\") that match the\n * implementation blocks to remove, plus the replacement token.\n *\n * The empty-query default of '' matches nothing, so the pruner leaves the\n * file untouched when a language has no registered prune rules yet.\n */\n\nimport path from 'node:path';\n\n/** Source of truth mirror in the PRD language matrix. */\nexport type Replacement = {\n /** Token used to replace a pruned block. */\n token: string;\n /**\n * Optional regex, run against the raw block text. If it matches, the block\n * is kept instead of pruned. Used to preserve directive/header lines\n * ('use client/server') even when they live inside an otherwise-pruned body.\n */\n keepIf?: RegExp;\n};\n\nexport interface LanguageSpec {\n /** Friendly name, used in logs and the report header. */\n name: string;\n /** web-tree-sitter `Language.load` file name. */\n wasm: string;\n /** Where to download the `.wasm` binary if not cached locally. */\n url: string;\n /** Extensions that map to this language: `.ts`, `.tsx`, etc. */\n extensions: string[];\n /**\n * One or more (query, replacement) pairs. Blocks matched by each query are\n * pruned bottom-up. Queries are combined; a block is pruned if it matches\n * any. This keeps small, frequently repeated constructs cheap to configure.\n */\n rules: { query: string; replacement: Replacement }[];\n}\n\n// ---------------------------------------------------------------------------\n// Pruning workhorse: prune every `statement_block` / `block` node.\n// ---------------------------------------------------------------------------\n\nconst BLOCK = { query: '(statement_block) @block', replacement: { token: '/* ... */' } };\nconst SWIFT_BLOCK = { query: '(statements) @block', replacement: { token: '/* ... */' } };\nconst GO_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst RUST_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst PY_BLOCK = { query: '(block) @block', replacement: { token: 'pass' } };\nconst C_BLOCK = { query: '(compound_statement) @block', replacement: { token: '/* ... */' } };\nconst JAVA_BLOCK = {\n query: '(block) @block',\n replacement: { token: '/* ... */' },\n};\nconst PHP_BLOCK = {\n query: '(compound_statement) @block',\n replacement: { token: '/* ... */' },\n};\nconst KOTLIN_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\nconst DART_BLOCK = { query: '(block) @block', replacement: { token: '/* ... */' } };\n\n// Keeps `'use client'`/`'use server'` and top-level directive strings.\nconst DIRECTIVE_KEEP: Replacement = {\n token: '/* ... */',\n keepIf: /^\\s*'use (client|server)'/,\n};\n\nexport const registry: Record<string, LanguageSpec> = {\n typescript: {\n name: 'TypeScript',\n wasm: 'tree-sitter-typescript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-typescript/releases/latest/download/tree-sitter-typescript.wasm',\n extensions: ['.ts', '.cts', '.mts'],\n rules: [BLOCK],\n },\n javascript: {\n name: 'JavaScript',\n wasm: 'tree-sitter-javascript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-javascript/releases/latest/download/tree-sitter-javascript.wasm',\n extensions: ['.js', '.cjs', '.mjs'],\n rules: [BLOCK],\n },\n tsx: {\n name: 'React / Next.js (TSX)',\n wasm: 'tree-sitter-tsx.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-typescript/releases/latest/download/tree-sitter-tsx.wasm',\n extensions: ['.tsx'],\n rules: [{ query: '(statement_block) @block', replacement: DIRECTIVE_KEEP }],\n },\n jsx: {\n name: 'React (JSX)',\n wasm: 'tree-sitter-javascript.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-javascript/releases/latest/download/tree-sitter-javascript.wasm',\n extensions: ['.jsx'],\n rules: [{ query: '(statement_block) @block', replacement: DIRECTIVE_KEEP }],\n },\n python: {\n name: 'Python',\n wasm: 'tree-sitter-python.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-python/releases/latest/download/tree-sitter-python.wasm',\n extensions: ['.py', '.pyi'],\n rules: [PY_BLOCK],\n },\n dart: {\n name: 'Dart / Flutter',\n wasm: 'tree-sitter-dart.wasm',\n url: 'https://github.com/UserNobody14/tree-sitter-dart.wasm/releases/latest/download/tree-sitter-dart.wasm',\n extensions: ['.dart'],\n rules: [DART_BLOCK],\n },\n swift: {\n name: 'Swift / SwiftUI',\n wasm: 'tree-sitter-swift.wasm',\n url: 'https://github.com/alex-pinkus/tree-sitter-swift/releases/latest/download/tree-sitter-swift.wasm',\n extensions: ['.swift'],\n rules: [SWIFT_BLOCK],\n },\n go: {\n name: 'Go',\n wasm: 'tree-sitter-go.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-go/releases/latest/download/tree-sitter-go.wasm',\n extensions: ['.go'],\n rules: [GO_BLOCK],\n },\n rust: {\n name: 'Rust',\n wasm: 'tree-sitter-rust.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-rust/releases/latest/download/tree-sitter-rust.wasm',\n extensions: ['.rs'],\n rules: [RUST_BLOCK],\n },\n java: {\n name: 'Java',\n wasm: 'tree-sitter-java.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-java/releases/latest/download/tree-sitter-java.wasm',\n extensions: ['.java'],\n rules: [JAVA_BLOCK],\n },\n kotlin: {\n name: 'Kotlin',\n wasm: 'tree-sitter-kotlin.wasm',\n url: 'https://github.com/fwcd/tree-sitter-kotlin/releases/latest/download/tree-sitter-kotlin.wasm',\n extensions: ['.kt', '.kts'],\n rules: [KOTLIN_BLOCK],\n },\n c: {\n name: 'C',\n wasm: 'tree-sitter-c.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-c/releases/latest/download/tree-sitter-c.wasm',\n extensions: ['.c', '.h'],\n rules: [C_BLOCK],\n },\n cpp: {\n name: 'C++',\n wasm: 'tree-sitter-cpp.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-cpp/releases/latest/download/tree-sitter-cpp.wasm',\n extensions: ['.cc', '.cpp', '.cxx', '.hpp', '.hh', '.hxx'],\n rules: [C_BLOCK],\n },\n php: {\n name: 'PHP',\n wasm: 'tree-sitter-php.wasm',\n url: 'https://github.com/tree-sitter/tree-sitter-php/releases/latest/download/tree-sitter-php.wasm',\n extensions: ['.php'],\n rules: [PHP_BLOCK],\n },\n} satisfies Record<string, LanguageSpec>;\n\n/** Map of extension -> language spec id, built once. */\nconst extensionIndex = new Map<string, string>();\nfor (const [id, spec] of Object.entries(registry)) {\n for (const ext of spec.extensions) {\n extensionIndex.set(ext, id);\n }\n}\n\nexport type LanguageId = keyof typeof registry;\n\n/** Return the language spec for a file path, or null if unsupported. */\nexport function languageForFile(filePath: string): LanguageSpec | null {\n const langId = extensionIndex.get(path.extname(filePath).toLowerCase());\n if (!langId) return null;\n return registry[langId];\n}\n\n/** All languages that have at least one prune rule. */\nexport const supportedLanguageIds = Object.keys(registry) as LanguageId[];\n\n/** Convenience: list every known extension. */\nexport const allExtensions = [...extensionIndex.keys()];\n","/**\n * token-shrink — public library entry.\n *\n * Re-exports the pruning engine, language registry, incremental watcher/cache,\n * and context assembler for embedding. To run the servers, see `./cli.js`\n * (HTTP) and `./mcp.js` (MCP stdio), which are the packaged CLIs.\n */\n\nexport { prune, spliceRanges, analyze, ensureParserInit, loadLanguage } from './parser/analyze.js';\nexport type { AnalyzeOptions, AnalyzeResult, PruneRange } from './parser/analyze.js';\nexport { collectSymbols, matchSymbols } from './parser/symbols.js';\nexport type { SymbolInfo, SymbolKind } from './parser/symbols.js';\nexport { languageForFile, registry, supportedLanguageIds, allExtensions } from './parser/registry.js';\nexport type { LanguageSpec, Replacement } from './parser/registry.js';\nexport { getGrammar, warmGrammars } from './parser/wasm.js';\n\nexport { detectProjectRoot, PROJECT_MANIFEST_FILES, VCS_MARKER_DIRS } from './detect.js';\n\nexport { SymbolSearch } from './search/index.js';\nexport type { SymbolDoc, SymbolHit } from './search/index.js';\n\nexport {\n loadConfig,\n matchesAny,\n matchesGlob,\n globToRegExp,\n EMPTY_CONFIG,\n CONFIG_FILE_NAME,\n configPathFor,\n} from './config.js';\nexport type { TokenShrinkConfig } from './config.js';\n\nexport {\n createWatcher,\n hashOf,\n extractImports,\n resolveImport,\n DEFAULT_IGNORED,\n} from './watcher/sync.js';\nexport type { CacheEntry, GraphCache, SyncOptions } from './watcher/sync.js';\n\nexport { assemble, assembleMany, extractSpecifiers, approximateTokens } from './server/assembler.js';\nexport type { AssembleOptions, AssembleResult, TokenStats } from './server/assembler.js';\n\nexport { startServer } from './cli.js';\nexport type { CliOptions } from './cli.js';\nexport {\n startMcpServer,\n createAutoRule,\n createCursorRule,\n AUTO_RULE_PATH,\n AUTO_RULE_SENTINEL,\n CURSOR_RULE_PATH,\n CLAUDE_RULE_PATH,\n CLAUDE_RULE_SENTINEL,\n CLINE_RULE_PATH,\n CLINE_RULE_SENTINEL,\n RULE_TARGET_PATH,\n} from './mcp.js';\nexport type { McpServerOptions, RuleWriteResult, RuleTarget } from './mcp.js';\n\nexport const version = '2.0.0';\n","/**\n * Single-parse analysis pass. Produces the pruned skeleton (Ring-1 text) and\n * the per-file symbol index from ONE tree-sitter parse, so the watcher never\n * parses a file twice for pruning and symbol extraction.\n *\n * The previous `prune()` implementation lived in `parser/pruner.ts`; the\n * parser plumbing (init/language cache) moved here and is re-exported from\n * `pruner.ts` for backwards compatibility.\n */\n\nimport Parser from 'web-tree-sitter';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { languageForFile, type LanguageSpec } from './registry.js';\nimport { getGrammar } from './wasm.js';\nimport { collectSymbols, type SymbolInfo } from './symbols.js';\n\n/** A byte-range that will be replaced by `token`. */\nexport interface PruneRange {\n start: number;\n end: number;\n token: string;\n}\n\n/**\n * Cache of decoded web-tree-sitter Language objects, keyed by grammar file\n * name. Grammar bytes only change when the on-disk binary changes, so we can\n * decode once per process and reuse it across all parses for that language.\n */\nconst languageCache = new Map<string, Parser.Language>();\n\nlet initPromise: Promise<void> | null = null;\n/** `Parser.init()` only needs to run once; make concurrent calls share it. */\nexport function ensureParserInit(): Promise<void> {\n if (!initPromise) {\n initPromise = Parser.init({\n locateFile: (file: string) => {\n // Point the wasm runtime at the bundled tree-sitter.wasm so it works\n // from tsup's dist build as well as from node_modules. `__filename` is\n // shimmed by tsup for ESM and native in CJS, avoiding the empty\n // `import.meta.url` that crashes the CJS CLI bundle.\n const require = createRequire(__filename);\n try {\n const pkgRoot = path.dirname(require.resolve('web-tree-sitter/package.json'));\n return path.join(pkgRoot, file);\n } catch {\n return file;\n }\n },\n });\n }\n return initPromise;\n}\n\n/** Load (and cache) a decoded Language object for a language spec. */\nexport function loadLanguage(\n spec: LanguageSpec,\n force = false,\n): Promise<Parser.Language> {\n if (!force) {\n const cached = languageCache.get(spec.wasm);\n if (cached) return Promise.resolve(cached);\n }\n // Force re-download/re-decode and refresh the cache.\n if (force) languageCache.delete(spec.wasm);\n return (async () => {\n await ensureParserInit();\n const grammar = await getGrammar(spec, force);\n const language = await Parser.Language.load(grammar);\n languageCache.set(spec.wasm, language);\n return language;\n })();\n}\n\n/**\n * Replace all ranges with their tokens. Ranges are pre-sorted descending by\n * start offset so each splice happens at the tail of the string first,\n * keeping earlier offsets stable.\n */\nexport function spliceRanges(source: string, ranges: PruneRange[]): {\n code: string;\n removed: number;\n} {\n let removed = 0;\n const sorted = [...ranges].sort((a, b) => b.start - a.start);\n let out = source;\n for (const r of sorted) {\n if (r.start < 0 || r.end > out.length || r.end < r.start) continue;\n removed += r.end - r.start;\n out = out.slice(0, r.start) + r.token + out.slice(r.end);\n }\n return { code: out, removed };\n}\n\nexport interface AnalyzeOptions {\n forceDownload?: boolean;\n /**\n * Keep the full source instead of producing a pruned skeleton (used by\n * `keepUnpruned` config rules). Symbols are still collected.\n */\n skipPrune?: boolean;\n /**\n * Byte ranges to exempt from pruning (used by `preserveAnnotations` config\n * rules). Blocks fully inside an exempted region are kept unpruned.\n */\n keepBlocksInside?: { start: number; end: number }[];\n /**\n * Annotation markers (e.g. `@keepContext`, `@api`). Any definition whose\n * preceding source window contains `@<marker>` is kept fully unpruned.\n */\n preserveAnnotations?: string[];\n}\n\nexport interface AnalyzeResult {\n /** Pruned skeleton, or the full source when skipped/unsupported. */\n code: string;\n /** Friendly language name, or null when unsupported/unavailable. */\n language: string | null;\n /** Number of bytes removed by pruning. */\n removed: number;\n /** Named definitions found in this file. */\n symbols: SymbolInfo[];\n}\n\n/**\n * Prune a file's implementation bodies and index its symbols from a single\n * parse. When the grammar cannot be loaded (e.g. first offline run) the file\n * is kept usable and unpruned rather than being dropped from the index.\n */\nexport async function analyze(\n filePath: string,\n source: string,\n opts: AnalyzeOptions = {},\n): Promise<AnalyzeResult> {\n const spec = languageForFile(filePath);\n if (!spec || spec.rules.length === 0) {\n return { code: source, language: null, removed: 0, symbols: [] };\n }\n\n let language: Parser.Language;\n try {\n language = await loadLanguage(spec, opts.forceDownload);\n } catch {\n return { code: source, language: null, removed: 0, symbols: [] };\n }\n\n const parser = new Parser();\n parser.setLanguage(language);\n const tree = parser.parse(source);\n try {\n const symbols = collectSymbols(tree.rootNode, source);\n if (opts.skipPrune) {\n return { code: source, language: spec.name, removed: 0, symbols };\n }\n\n // Config keep-rules: an annotated definition (or an explicit keep range)\n // protects every prunable block inside it.\n const keepRanges: { start: number; end: number }[] = [\n ...(opts.keepBlocksInside ?? []),\n ...(opts.preserveAnnotations?.length\n ? annotatedKeepRanges(symbols, source, opts.preserveAnnotations)\n : []),\n ];\n const isProtected = (start: number, end: number) =>\n keepRanges.some((k) => k.start <= start && end <= k.end);\n\n const ranges: PruneRange[] = [];\n for (const rule of spec.rules) {\n const query = language.query(rule.query);\n const captures = query.captures(tree.rootNode);\n for (const cap of captures) {\n // Skip captures whose source text is empty (there's nothing to shrink).\n if (cap.node.startIndex === cap.node.endIndex) continue;\n // Allow rules to keep certain blocks (e.g. 'use client/server').\n if (rule.replacement.keepIf?.test(cap.node.text)) continue;\n // Config keep-rules (preserveAnnotations / keepBlocksInside).\n if (isProtected(cap.node.startIndex, cap.node.endIndex)) continue;\n ranges.push({\n start: cap.node.startIndex,\n end: cap.node.endIndex,\n token: rule.replacement.token,\n });\n }\n query.delete();\n }\n\n const { code, removed } = spliceRanges(source, ranges);\n return { code, language: spec.name, removed, symbols };\n } finally {\n tree.delete();\n parser.delete();\n }\n}\n\n/** Back-compat entry point (same contract as the historical `prune`). */\nexport async function prune(\n filePath: string,\n source: string,\n opts: { forceDownload?: boolean } = {},\n): Promise<{ code: string; language: string | null; removed: number }> {\n const res = await analyze(filePath, source, opts);\n return { code: res.code, language: res.language, removed: res.removed };\n}\n\n/** How far back from a definition to look for an annotation line. */\nconst ANNOTATION_WINDOW = 240;\n\n/**\n * Ranges of definitions whose preceding source window mentions any configured\n * annotation (e.g. a `@api` decorator or `// @keepContext` comment). Grammar\n * agnostic: it uses symbol byte ranges plus a plain-text backwards scan, so an\n * annotated function/class keeps ALL of its nested bodies unpruned.\n */\nfunction annotatedKeepRanges(\n symbols: SymbolInfo[],\n source: string,\n annotations: string[],\n): { start: number; end: number }[] {\n if (annotations.length === 0) return [];\n const markers = annotations.filter(Boolean).map(escapeRegExp);\n if (markers.length === 0) return [];\n const re = new RegExp(`@(${markers.join('|')})\\\\b`, 'i');\n return symbols\n .filter((s) => {\n // Look at the slice of source right before the definition. Cut everything\n // back to the last `}`/`;` so an annotation that belongs to a PREVIOUS\n // definition (still inside the 240-char window) can never leak onto the\n // next one.\n const windowStart = Math.max(0, s.start - ANNOTATION_WINDOW);\n const tail = source.slice(windowStart, s.start);\n const cut = Math.max(tail.lastIndexOf('}\\n'), tail.lastIndexOf(';\\n'));\n const relevant = cut === -1 ? tail : tail.slice(cut + 1);\n return re.test(relevant);\n })\n .map((s) => ({ start: s.start, end: s.end }));\n}\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n","/**\n * WASM grammar acquisition. Lazily downloads a language's `.wasm` grammar\n * from its upstream GitHub release on first use and caches it on disk in a\n * `wasm/` directory at the project root (mirrored to `dist/wasm` by tsup).\n *\n * `Language.load` on Node expects either a Uint8Array of the real parser\n * bytes or a filesystem path; we hand it the raw bytes via `getGrammar`,\n * which returns a `Uint8Array` for the pruner to load directly.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { LanguageSpec } from './registry.js';\n\n// `__dirname` is shimmed automatically by tsup so it works in both ESM and\n// CJS output: in ESM it derives from import.meta.url, in CJS it is native.\n// This avoids calling fileURLToPath(import.meta.url), which is empty in the\n// CJS bundle and would crash the packaged CLI (`dist/cli.cjs`, `dist/mcp.cjs`).\n/**\n * Resolve the `wasm/` cache directory, preferring the packaged copy.\n * Candidates are searched in order: project `wasm/`, `dist/wasm/`.\n */\nfunction resolveWasmDir(): string {\n const candidates = [\n path.resolve(__dirname, '../../wasm'),\n path.resolve(__dirname, '../wasm'),\n path.resolve(process.cwd(), 'wasm'),\n ];\n for (const dir of candidates) {\n try {\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n /* try next */\n }\n }\n const dir = path.resolve(process.cwd(), 'wasm');\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nlet wasmDir: string | null = null;\nfunction cacheDir(): string {\n if (!wasmDir) wasmDir = resolveWasmDir();\n return wasmDir;\n}\n\nexport function cachePath(spec: LanguageSpec): string {\n return path.join(cacheDir(), spec.wasm);\n}\n\n/** True if the head bytes are the wasm magic `\\0asm`. */\nfunction looksLikeWasm(bytes: Uint8Array): boolean {\n return (\n bytes.length >= 4 &&\n bytes[0] === 0 &&\n bytes[1] === 97 &&\n bytes[2] === 115 &&\n bytes[3] === 109\n );\n}\n\n/** In-flight downloads keyed by wasm filename, so concurrent callers share one. */\nconst inflight = new Map<string, Promise<Uint8Array>>();\n\nfunction download(spec: LanguageSpec): Promise<Uint8Array> {\n const pending = inflight.get(spec.wasm);\n if (pending) return pending;\n const job = (async () => {\n const res = await fetch(spec.url, { redirect: 'follow' });\n if (!res.ok) {\n throw new Error(\n `Failed to download grammar \"${spec.wasm}\" from ${spec.url} (HTTP ${res.status})`,\n );\n }\n const bytes = new Uint8Array(await res.arrayBuffer());\n if (!looksLikeWasm(bytes)) {\n throw new Error(\n `Downloaded grammar \"${spec.wasm}\" is not valid WebAssembly (got HTML/redirect).`,\n );\n }\n // Write atomically (tmp file + rename) so a concurrent reader never\n // observes a partially-written grammar.\n const target = cachePath(spec);\n const tmp = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, bytes);\n fs.renameSync(tmp, target);\n inflight.delete(spec.wasm);\n return bytes;\n })().catch((err) => {\n inflight.delete(spec.wasm);\n throw err;\n });\n inflight.set(spec.wasm, job);\n return job;\n}\n\n/**\n * Return the raw grammar bytes for a language, downloading them if needed.\n * `force` bypasses the local disk cache (used by tests / `--warm`).\n */\nexport async function getGrammar(\n spec: LanguageSpec,\n force = false,\n): Promise<Uint8Array> {\n if (!force && fs.existsSync(cachePath(spec))) {\n const cached = fs.readFileSync(cachePath(spec));\n if (looksLikeWasm(cached)) return cached;\n }\n return download(spec);\n}\n\n/**\n * Pre-download every supported grammar (used on cold boot / `prune --warm`).\n * Returns the number of grammars that are ready on disk afterward.\n */\nexport async function warmGrammars(specs: LanguageSpec[] = []): Promise<number> {\n const registryModule = await import('./registry.js');\n const list =\n specs.length > 0 ? specs : (Object.values(registryModule.registry) as LanguageSpec[]);\n const unique = new Map<string, LanguageSpec>();\n for (const spec of list) unique.set(spec.wasm, spec);\n const results = await Promise.allSettled(\n [...unique.values()].map((spec) => getGrammar(spec)),\n );\n return results.filter((r) => r.status === 'fulfilled').length;\n}\n\n","/**\n * Symbol extraction from a parsed tree. One tree-sitter parse yields every\n * named definition (function/class/interface/…) with its byte range, so the\n * MCP server can:\n * - `expand_symbol`: return a specific definition's full, un-pruned body;\n * - `search_symbol_signatures`: index names + signature lines for fast lookup.\n *\n * Node types are matched by name across grammars, and definitions are only\n * kept when the grammar exposes a `name` field (verified for TS/JS/TSX/JSX,\n * Python, Go, Rust, Kotlin, Dart, Swift, Java, PHP). Grammars without a\n * `name` field (e.g. C/C++ `function_definition`) simply contribute nothing.\n */\n\nimport type { SyntaxNode } from 'web-tree-sitter';\n\nexport type SymbolKind =\n | 'function'\n | 'method'\n | 'arrow'\n | 'class'\n | 'interface'\n | 'enum'\n | 'type'\n | 'other';\n\nexport interface SymbolInfo {\n name: string;\n kind: SymbolKind;\n /** 1-based line of the definition start. */\n line: number;\n /** Byte range in the original source (the full definition, body included). */\n start: number;\n end: number;\n /** First line of the definition (trimmed, capped) for search previews. */\n signature?: string;\n}\n\n/** Map of tree-sitter node types to a symbol kind (unique keys only). */\nconst KIND_BY_TYPE: Record<string, SymbolKind> = {\n // TypeScript / JavaScript / TSX / JSX\n function_declaration: 'function',\n generator_function_declaration: 'function',\n function_expression: 'function',\n function_signature_item: 'function',\n method_definition: 'method',\n method_signature: 'method',\n class_declaration: 'class',\n abstract_class_declaration: 'class',\n interface_declaration: 'interface',\n enum_declaration: 'enum',\n type_alias_declaration: 'type',\n // Python\n function_definition: 'function',\n class_definition: 'class',\n // Go\n method_declaration: 'method',\n type_spec: 'type',\n // Rust\n function_item: 'function',\n struct_item: 'class',\n enum_item: 'enum',\n trait_item: 'interface',\n type_item: 'type',\n // Java / Kotlin / PHP / Dart / Swift (best-effort generic names)\n constructor_declaration: 'method',\n module_declaration: 'class',\n protocol_declaration: 'interface',\n};\n\n/** Signature preview cap. */\nconst SIGNATURE_MAX = 200;\n\n/**\n * Walk `root` and collect every named definition with its byte range.\n * `source` is only needed to build signature/line previews.\n */\nexport function collectSymbols(root: SyntaxNode, source: string): SymbolInfo[] {\n const out: SymbolInfo[] = [];\n const walk = (node: SyntaxNode) => {\n const kind = KIND_BY_TYPE[node.type];\n if (kind) {\n const nameNode = node.childForFieldName('name');\n if (nameNode && nameNode.text.trim()) {\n out.push(symbolFrom(nameNode.text.trim(), kind, node.startIndex, node.endIndex, source));\n }\n } else if (node.type === 'variable_declarator') {\n // `const fn = (…) => …` / `const f = function () { … }`\n const value = node.childForFieldName('value');\n const valueType = value?.type;\n if (valueType === 'arrow_function' || valueType === 'function_expression') {\n const nameNode = node.childForFieldName('name');\n if (nameNode && nameNode.text.trim()) {\n out.push(\n symbolFrom(nameNode.text.trim(), 'arrow', node.startIndex, node.endIndex, source),\n );\n }\n }\n }\n // Keep descending so nested methods/inner functions are indexed too.\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i);\n if (child) walk(child);\n }\n };\n walk(root);\n return out;\n}\n\n/**\n * Resolve `query` to matching symbols. Exact name match wins; falls back to\n * case-insensitive exact, then substring. `kind` narrows the candidates.\n */\nexport function matchSymbols(\n symbols: SymbolInfo[],\n query: string,\n kind?: SymbolKind,\n): SymbolInfo[] {\n const q = query.trim();\n if (!q) return [];\n const pool = kind ? symbols.filter((s) => s.kind === kind) : symbols;\n const byName = pool.filter((s) => s.name === q);\n if (byName.length > 0) return byName;\n const byNameCi = pool.filter((s) => s.name.toLowerCase() === q.toLowerCase());\n if (byNameCi.length > 0) return byNameCi;\n const lower = q.toLowerCase();\n const bySubstring = pool.filter((s) => s.name.toLowerCase().includes(lower));\n return bySubstring.length > 0\n ? bySubstring\n : pool.filter((s) => (s.signature ?? '').toLowerCase().includes(lower));\n}\n\nfunction symbolFrom(\n name: string,\n kind: SymbolKind,\n start: number,\n end: number,\n source: string,\n): SymbolInfo {\n return {\n name,\n kind,\n line: source.slice(0, start).split('\\n').length,\n start,\n end,\n signature: signaturePreview(source, start, end),\n };\n}\n\nfunction signaturePreview(source: string, start: number, end: number): string {\n const nl = source.indexOf('\\n', start);\n const endOfLine = nl === -1 ? end : nl;\n const first = source.slice(start, Math.min(endOfLine, end)).trim();\n return first.length > SIGNATURE_MAX ? `${first.slice(0, SIGNATURE_MAX)}…` : first;\n}\n","/**\n * Project-root auto-detection for zero-config (no `--root`) mode.\n *\n * The MCP server cannot always know its project at startup: clients spawn\n * stdio servers from directories they choose, and shared/global configs have no\n * project at all. When no explicit root is supplied, these helpers locate the\n * repository by walking up from a known path (the process cwd, or the active\n * file of a tool call) until a VCS directory or a project manifest is found.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/** VCS dirs mark the true repository boundary — the strongest signal. */\nexport const VCS_MARKER_DIRS = ['.git', '.hg', '.svn'] as const;\n\n/** Manifest files that mark a project boundary when no VCS dir exists. */\nexport const PROJECT_MANIFEST_FILES = [\n // JavaScript / TypeScript\n 'package.json',\n 'tsconfig.json',\n // Python\n 'pyproject.toml',\n 'setup.py',\n 'setup.cfg',\n 'requirements.txt',\n // Go / Rust / Dart / Swift\n 'go.mod',\n 'Cargo.toml',\n 'pubspec.yaml',\n 'Package.swift',\n // Java / Kotlin\n 'pom.xml',\n 'build.gradle',\n 'build.gradle.kts',\n 'settings.gradle',\n 'settings.gradle.kts',\n // PHP / Ruby / Elixir\n 'composer.json',\n 'Gemfile',\n 'mix.exs',\n] as const;\n\nconst MANIFEST_FILE_SET: ReadonlySet<string> = new Set(PROJECT_MANIFEST_FILES);\n\n/** Ceiling on upward directory walks (fs roots are deep but bounded). */\nconst MAX_WALK_DEPTH = 64;\n\n/**\n * Find the project root that `fromPath` belongs to, or `null` when none can be\n * determined. `fromPath` may be a file or directory (existing or not).\n *\n * Walk-up rules:\n * - the first ancestor containing a VCS dir (`.git`/`.hg`/`.svn`) wins — it is\n * the true repository boundary, even inside a monorepo sub-package;\n * - otherwise the deepest ancestor containing a project manifest\n * (`package.json`, `pyproject.toml`, `go.mod`, …) is returned;\n * - otherwise `null`, meaning the tree holds no recognizable project markers.\n */\nexport function detectProjectRoot(fromPath: string): string | null {\n const resolved = path.resolve(fromPath);\n let dir = isDirectory(resolved) ? resolved : path.dirname(resolved);\n let nearestManifest: string | null = null;\n\n for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {\n const names = readDirNames(dir);\n if (names) {\n if (VCS_MARKER_DIRS.some((vcs) => names.has(vcs))) return dir;\n if (nearestManifest === null && hasManifest(names)) nearestManifest = dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached the filesystem root\n dir = parent;\n }\n return nearestManifest;\n}\n\n/** Is `p` an existing directory (ENOENT-safe)? */\nfunction isDirectory(p: string): boolean {\n try {\n return fs.statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Read a directory's entry names, or `null` when unreadable. */\nfunction readDirNames(dir: string): ReadonlySet<string> | null {\n try {\n return new Set(fs.readdirSync(dir));\n } catch {\n return null; // permission errors / vanished dirs mid-walk\n }\n}\n\nfunction hasManifest(names: ReadonlySet<string>): boolean {\n for (const name of names) {\n if (MANIFEST_FILE_SET.has(name)) return true;\n }\n return false;\n}\n","/**\n * In-memory symbol signature index for `search_symbol_signatures`.\n *\n * Zero-dependency alternative to SQLite FTS5: we index only symbol metadata\n * (names + signature lines) produced during the tree-sitter analyze pass, so\n * lookups stay well under a millisecond at repository scale without adding a\n * native module to the dependency tree.\n *\n * The index is kept fresh by the watcher: files are added/removed as chokidar\n * events and the analyze pass run.\n */\n\nimport type { SymbolInfo, SymbolKind } from '../parser/symbols.js';\nimport type { CacheEntry } from '../watcher/sync.js';\n\nexport interface SymbolDoc extends SymbolInfo {\n /** Absolute path of the containing file. */\n filePath: string;\n}\n\nexport interface SymbolHit extends SymbolDoc {\n /** Higher is better. */\n score: number;\n /** Human label like `file.ts:12 — fn(a: number): number`. */\n label: string;\n}\n\ntype ScoredHit = SymbolDoc & { score: number };\n\n/** Split an identifier into searchable words (camelCase + snake_case aware). */\nfunction words(text: string): string[] {\n const out = new Set<string>();\n for (const part of text.split(/[^A-Za-z0-9_$]+/)) {\n if (!part) continue;\n // camelCase / PascalCase boundaries.\n for (const seg of part.split(/(?<=[a-z0-9])(?=[A-Z])/)) {\n const w = seg.toLowerCase();\n if (w) out.add(w);\n }\n // snake_case parts.\n for (const seg of part.split('_')) {\n const w = seg.toLowerCase();\n if (w) out.add(w);\n }\n }\n return [...out];\n}\n\nexport class SymbolSearch {\n private docs: SymbolDoc[] = [];\n private byFile = new Map<string, SymbolDoc[]>();\n private inverted = new Map<string, number[]>();\n\n get size(): number {\n return this.docs.length;\n }\n\n /** Replace the docs for one file (or remove when `symbols` is empty). */\n setFile(filePath: string, symbols: SymbolInfo[]): void {\n this.removeFile(filePath);\n if (symbols.length === 0) return;\n const docs: SymbolDoc[] = symbols.map((s) => ({ ...s, filePath }));\n const ids = docs.map((d) => {\n const id = this.docs.length;\n this.docs.push(d);\n for (const w of words(`${d.name}`)) {\n const list = this.inverted.get(w) ?? [];\n list.push(id);\n this.inverted.set(w, list);\n }\n return id;\n });\n this.byFile.set(filePath, docs);\n void ids; // ids are implicit in `this.docs`\n }\n\n removeFile(filePath: string): void {\n const docs = this.byFile.get(filePath);\n if (!docs) return;\n const removed = new Set(docs);\n // Rebuild the arrays from scratch: file-level churn is rare enough that\n // this stays far cheaper than a persistent per-doc tombstones scheme.\n this.docs = this.docs.filter((d) => !removed.has(d));\n this.byFile.delete(filePath);\n this.rebuildInverted();\n }\n\n /** Bulk-load a whole cache (used at attach time and cold lazy builds). */\n loadCache(entries: ReadonlyMap<string, CacheEntry>): void {\n this.docs = [];\n this.byFile.clear();\n for (const [abs, entry] of entries) {\n if (!entry.symbols || entry.symbols.length === 0) continue;\n const docs: SymbolDoc[] = entry.symbols.map((s) => ({ ...s, filePath: abs }));\n this.byFile.set(abs, docs);\n this.docs.push(...docs);\n }\n this.rebuildInverted();\n }\n\n /** Ranked symbol hits for `query`. */\n search(\n query: string,\n opts: { maxResults?: number; kind?: SymbolKind } = {},\n ): SymbolHit[] {\n const maxResults = opts.maxResults ?? 10;\n const q = query.trim().toLowerCase();\n if (!q) return [];\n\n const queryWords = words(q);\n let candidates: SymbolDoc[];\n if (queryWords.length > 0) {\n const ids = new Set<number>();\n for (const w of queryWords) {\n const post = this.inverted.get(w);\n if (post) for (const id of post) ids.add(id);\n }\n candidates = [...ids].map((id) => this.docs[id]);\n } else {\n candidates = this.docs;\n }\n if (opts.kind) candidates = candidates.filter((d) => d.kind === opts.kind);\n\n const scored = candidates\n .map((d) => this.score(d, q, queryWords))\n .filter((s): s is ScoredHit => s !== null)\n .sort((a, b) => b.score - a.score || a.line - b.line)\n .slice(0, maxResults);\n\n return scored.map((s) => ({ ...s, label: this.label(s) }));\n }\n\n private score(\n d: SymbolDoc,\n q: string,\n queryWords: string[],\n ): ScoredHit | null {\n const name = d.name.toLowerCase();\n let score = 0;\n if (name === q) score += 100;\n if (name.startsWith(q)) score += 60;\n if (name.includes(q)) score += 30;\n if ((d.signature ?? '').toLowerCase().includes(q)) score += 8;\n for (const w of queryWords) {\n if (name.includes(w)) score += 4;\n if ((d.signature ?? '').toLowerCase().includes(w)) score += 1;\n }\n if (score <= 0) return null;\n return { ...d, score };\n }\n\n private label(d: SymbolDoc): string {\n const sig = d.signature && d.signature.length > 0 ? ` — ${d.signature}` : '';\n return `${d.filePath}:${d.line}${sig}`;\n }\n\n private rebuildInverted(): void {\n this.inverted.clear();\n this.docs.forEach((d, id) => {\n for (const w of words(d.name)) {\n const list = this.inverted.get(w) ?? [];\n list.push(id);\n this.inverted.set(w, list);\n }\n });\n }\n}\n\n","/**\n * `.tokenshrinkrc.json` support — developer-level customization.\n *\n * Supported keys (all optional arrays of strings):\n * - ignorePatterns: glob patterns of paths that are never indexed/watched;\n * - keepUnpruned: glob patterns of files to index but never prune;\n * - preserveAnnotations: markers (e.g. `@keepContext`, `@api`) that exempt a\n * definition (and everything nested in it) from pruning.\n *\n * The config file lives at the repository root (the auto-detected root when no\n * `--root` is given). Invalid JSON never crashes the server — it logs a warning\n * and falls back to empty defaults.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport const CONFIG_FILE_NAME = '.tokenshrinkrc.json';\n\nexport interface TokenShrinkConfig {\n /** Glob patterns of paths that should never be indexed or watched. */\n ignorePatterns: string[];\n /** Glob patterns of files to index but never prune (full Ring-1 text). */\n keepUnpruned: string[];\n /** Annotation markers (e.g. `@keepContext`) that exempt a definition from pruning. */\n preserveAnnotations: string[];\n /**\n * When false, the generated agent rule carries only lightweight guidance and\n * the model decides when to call the auxiliary tools on its own. Default\n * (true / unset): rules choreograph the tools automatically each task.\n */\n autoWorkflow?: boolean;\n}\n\nexport const EMPTY_CONFIG: TokenShrinkConfig = {\n ignorePatterns: [],\n keepUnpruned: [],\n preserveAnnotations: [],\n};\n\nexport function configPathFor(root: string): string {\n return path.join(root, CONFIG_FILE_NAME);\n}\n\n/** Parse + validate the config at `root`, tolerating any JSON shape. */\nexport function loadConfig(\n root: string,\n warn?: (msg: string) => void,\n): TokenShrinkConfig {\n const file = configPathFor(root);\n let raw: unknown;\n try {\n if (!fs.existsSync(file)) return { ...EMPTY_CONFIG };\n raw = JSON.parse(fs.readFileSync(file, 'utf8'));\n } catch (err) {\n warn?.(`Invalid ${CONFIG_FILE_NAME} at ${file}: ${(err as Error).message}`);\n return { ...EMPTY_CONFIG };\n }\n return normalizeConfig(raw, warn, file);\n}\n\nfunction normalizeConfig(\n raw: unknown,\n warn?: (msg: string) => void,\n file?: string,\n): TokenShrinkConfig {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n warn?.(`Invalid ${CONFIG_FILE_NAME}${file ? ` at ${file}` : ''}: expected a JSON object.`);\n return { ...EMPTY_CONFIG };\n }\n const obj = raw as Record<string, unknown>;\n const asStrings = (v: unknown): string[] =>\n Array.isArray(v) ? v.filter((x): x is string => typeof x === 'string') : [];\n return {\n ignorePatterns: asStrings(obj.ignorePatterns),\n keepUnpruned: asStrings(obj.keepUnpruned),\n preserveAnnotations: asStrings(obj.preserveAnnotations),\n ...(typeof obj.autoWorkflow === 'boolean' ? { autoWorkflow: obj.autoWorkflow } : {}),\n };\n}\n\n/** True when the (slash-normalized) `file` matches any `pattern`. */\nexport function matchesAny(file: string, patterns: string[]): boolean {\n const rel = normalizeSlashes(file);\n for (const raw of patterns) {\n if (!raw) continue;\n const pattern = normalizeSlashes(raw).replace(/^\\.\\//, '');\n if (matchesGlob(rel, pattern)) return true;\n }\n return false;\n}\n\n/**\n * Glob matcher with `**`, `*`, `?` and `[...]` support. Patterns that contain\n * no glob metacharacters also match as a path suffix (a bare filename like\n * `global.d.ts` matches any directory containing it).\n */\nexport function matchesGlob(file: string, pattern: string): boolean {\n if (file === pattern) return true;\n if (!/[?*[]/.test(pattern)) {\n // Plain path: exact, or trailing suffix (bare file name / deep dir).\n return file.endsWith(`/${pattern}`);\n }\n const re = globToRegExp(pattern);\n return re.test(file);\n}\n\n/** Compile `**`/`*`/`?`/`[...]` glob into a `/`-normalized regex. */\nexport function globToRegExp(glob: string): RegExp {\n let re = '^';\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i];\n if (c === '*') {\n if (glob[i + 1] === '*') {\n i++;\n // `**/` may match zero or more segments; consume the slash too.\n if (glob[i + 1] === '/') {\n i++;\n re += '(?:.*/)?';\n } else {\n re += '.*';\n }\n } else {\n re += '[^/]*';\n }\n } else if (c === '?') {\n re += '[^/]';\n } else if (c === '[') {\n const close = glob.indexOf(']', i);\n if (close === -1) {\n re += '\\\\[';\n } else {\n const inner = glob.slice(i + 1, close).replace(/\\\\/g, '\\\\\\\\');\n re += `[${inner}]`;\n i = close;\n }\n } else {\n re += c.replace(/[.+^${}()|\\\\]/g, '\\\\$&');\n }\n }\n re += '$';\n return new RegExp(re);\n}\n\nfunction normalizeSlashes(p: string): string {\n return p.split(path.sep).join('/').replace(/^\\.\\//, '');\n}\n","/**\n * Incremental synchronization layer (Phase 3).\n *\n * - Watches the repository with chokidar (ignoring vendor/build dirs).\n * - On add/change, hashes the file and, if the hash changed, re-prunes it and\n * updates the in-memory graph cache.\n * - Extracts import/require specifiers from each file and normalizes relative\n * and aliased paths to absolute file paths on disk.\n *\n * The graph cache is shared with the Context Assembler, which reads ring-1\n * skeletons out of it.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\n\nimport chokidar, { type FSWatcher, type Matcher } from 'chokidar';\n\nimport { ensureParserInit } from '../parser/pruner.js';\nimport { analyze } from '../parser/analyze.js';\nimport type { SymbolInfo } from '../parser/symbols.js';\nimport { matchesAny, type TokenShrinkConfig } from '../config.js';\n\nexport type { Matcher };\n\n/** Default paths that will never be indexed or watched. */\nexport const DEFAULT_IGNORED = [\n /(^|[/\\\\])\\.[^/\\\\]+/, // dotfiles / dot-dirs (.git, .cursor, .env, ...)\n /node_modules/,\n /[/\\\\](build|dist|out|coverage|\\.next|\\.turbo|\\.cache)[/\\\\]/,\n];\n\nexport interface CacheEntry {\n /** sha1 of the last-indexed file content. */\n hash: string;\n /** Pruned skeleton for this file. */\n skeleton: string;\n /** The language name used to prune it (or null if unsupported). */\n language: string | null;\n /** Absolute paths of the files this file imports. */\n imports: string[];\n /** Named definitions found while indexing (for expand_symbol / search). */\n symbols?: SymbolInfo[];\n}\n\nexport type GraphCache = Map<string, CacheEntry>;\n\nexport class ContextCache {\n readonly entries: GraphCache = new Map();\n private initPromise: Promise<void> | null = null;\n\n ensureInit(): Promise<void> {\n if (!this.initPromise) {\n this.initPromise = ensureParserInit();\n }\n return this.initPromise;\n }\n\n /** Returns the cached skeleton for a file, if present. */\n getSkeleton(filePath: string): CacheEntry | null {\n return this.entries.get(path.resolve(filePath)) ?? null;\n }\n\n get imports() {\n return this.entries;\n }\n}\n\n/** Compute a sha1 of a string. */\nexport function hashOf(text: string): string {\n return createHash('sha1').update(text).digest('hex');\n}\n\n/**\n * Extract import/require specifiers from source text using a robust,\n * language-agnostic regex (AST-based import queries are grammar-fragile and\n * occasionally malformed; regex covers the common import forms across JS/TS,\n * Python, Go, Rust, Dart, Swift, Java, Kotlin, PHP, C/C++).\n * Returns the matched specifier strings (may be relative or absolute).\n */\nexport function extractImports(_filePath: string, source: string): string[] {\n const out: string[] = [];\n\n // import ... from 'x' | import 'x' | require('x')\n const re =\n /(?:from\\s+['\"`]([^'\"`]+)['\"`]|import\\s+['\"`]([^'\"`]+)['\"`]|require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\))/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n const spec = m[1] ?? m[2] ?? m[3];\n if (spec) out.push(spec);\n }\n\n // Python / Go / Rust / Dart / Swift / Java / Kotlin / C/C++ single-quote not\n // covered by the JS-style regex is out of scope for the first pass.\n\n return [...new Set(out)].filter(Boolean);\n}\n\n/** Normalize a specifier to an absolute file path when it resolves locally. */\nexport function resolveImport(\n importer: string,\n specifier: string,\n root: string,\n): string | null {\n // Skip bare, non-relative imports (npm packages) and obviously external.\n if (!/^[.~@]/.test(specifier)) {\n // Alias `@/...` and `~` map to the project root.\n if (specifier.startsWith('@/')) {\n return resolveCandidate(path.join(root, specifier.slice(2)));\n }\n if (specifier.startsWith('@')) {\n return null; // scoped package, not local\n }\n if (specifier.startsWith('~')) {\n return resolveCandidate(path.join(root, specifier.slice(1)));\n }\n return null;\n }\n\n const base = path.dirname(path.resolve(importer));\n return resolveCandidate(path.resolve(base, specifier));\n}\n\n/** Try a specifier with common extension/index additions. */\nfunction resolveCandidate(p: string): string | null {\n const candidates = [\n p,\n `${p}.ts`,\n `${p}.tsx`,\n `${p}.js`,\n `${p}.jsx`,\n `${p}.mjs`,\n `${p}.cjs`,\n `${p}.py`,\n `${p}.go`,\n `${p}.rs`,\n `${p}.dart`,\n `${p}.swift`,\n `${p}.java`,\n `${p}.kt`,\n `${p}.c`,\n `${p}.cpp`,\n `${p}.h`,\n `${p}.hpp`,\n `${p}.php`,\n path.join(p, 'index.ts'),\n path.join(p, 'index.js'),\n path.join(p, 'index.tsx'),\n path.join(p, 'index.jsx'),\n path.join(p, 'index.py'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c) && fs.statSync(c).isFile()) return path.resolve(c);\n }\n return null;\n}\n\nexport interface SyncOptions {\n root: string;\n ignored?: Matcher[];\n /** Optional `.tokenshrinkrc.json` settings. */\n config?: TokenShrinkConfig;\n onIndexed?: (filePath: string, entry: CacheEntry) => void;\n /** Called when a watched file disappears from disk (cache entry dropped). */\n onRemoved?: (filePath: string) => void;\n}\n\n/**\n * Watch a project root and keep the graph cache fresh. Returns the cache and\n * a close() handle. `prune` is awaited per change to keep hot-reload latency\n * predictable.\n */\nexport function createWatcher(opts: SyncOptions) {\n const cache = new ContextCache();\n const { root, ignored = DEFAULT_IGNORED, config, onIndexed, onRemoved } = opts;\n\n // Config `ignorePatterns` become extra matchers evaluated against the path\n // relative to the repo root (so globs like `**/dist/**` behave predictably).\n const rel = (abs: string) => path.relative(root, abs);\n const effectiveIgnored: Matcher[] = [\n ...ignored,\n ...(config?.ignorePatterns?.length\n ? [(_abs: string) => matchesAny(rel(String(_abs)), config.ignorePatterns)]\n : []),\n ];\n\n // Debounce a burst of events into a single re-prune per file.\n const pending = new Map<string, NodeJS.Timeout>();\n const DEBOUNCE_MS = 100;\n\n async function handle(filePath: string) {\n const abs = path.resolve(filePath);\n let source: string;\n try {\n const st = fs.statSync(abs);\n if (!st.isFile()) return; // sockets/symlinks etc.\n source = fs.readFileSync(abs, 'utf8');\n } catch {\n return; // file vanished between event and read\n }\n const hash = hashOf(source);\n const cached = cache.entries.get(abs);\n if (cached && cached.hash === hash) return; // unchanged\n\n await cache.ensureInit();\n const keepFull = config?.keepUnpruned?.length\n ? matchesAny(path.relative(root, abs), config.keepUnpruned)\n : false;\n const { code, language, symbols } = await analyze(abs, source, {\n skipPrune: keepFull,\n preserveAnnotations: config?.preserveAnnotations,\n });\n const imports = extractImports(abs, source);\n const entry: CacheEntry = {\n hash,\n skeleton: code,\n language,\n imports: imports\n .map((spec) => resolveImport(abs, spec, root))\n .filter((p): p is string => p !== null),\n ...(symbols.length > 0 ? { symbols } : {}),\n };\n cache.entries.set(abs, entry);\n onIndexed?.(abs, entry);\n }\n\n const watcher: FSWatcher = chokidar.watch(root, {\n // Combine path matchers with a stat check so non-regular files (e.g. unix\n // sockets) are never opened with fs.watch (which raises UVException).\n ignored(_p, stats) {\n if (stats && !stats.isFile() && !stats.isDirectory()) return true;\n return isIgnored(path.resolve(String(_p)), effectiveIgnored);\n },\n alwaysStat: true,\n ignoreInitial: true,\n persistent: true,\n awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 10 },\n });\n\n function debounce(filePath: string) {\n const abs = path.resolve(filePath);\n const existing = pending.get(abs);\n if (existing) clearTimeout(existing);\n // Fire immediately on the first event, then coalesce noise.\n if (!existing) void handle(abs);\n pending.set(\n abs,\n setTimeout(() => pending.delete(abs), DEBOUNCE_MS),\n );\n }\n\n watcher.on('add', debounce);\n watcher.on('change', debounce);\n watcher.on('unlink', (filePath: string) => {\n const abs = path.resolve(filePath);\n cache.entries.delete(abs);\n onRemoved?.(abs);\n });\n\n return {\n cache,\n watcher,\n /** Index an existing file right now (bypasses the watcher). */\n index: handle,\n /**\n * Index the whole tree once (cold start). Returns the number of files\n * successfully indexed.\n */\n async indexAll(): Promise<number> {\n const files: string[] = [];\n await walk(root, (f) => files.push(f), effectiveIgnored);\n let ok = 0;\n for (const f of files) {\n try {\n await handle(f);\n ok++;\n } catch {\n /* skip unparseable files */\n }\n }\n return ok;\n },\n close: () => watcher.close(),\n };\n}\n\n/** Recursively list supported source files, honoring ignore patterns. */\nasync function walk(\n root: string,\n push: (f: string) => void,\n ignored: Matcher[],\n): Promise<void> {\n const entries = await fs.promises.readdir(root, { withFileTypes: true });\n for (const e of entries) {\n const abs = path.join(root, e.name);\n if (isIgnored(abs, ignored)) continue;\n if (e.isDirectory()) {\n await walk(abs, push, ignored);\n } else if (e.isFile()) {\n push(abs);\n }\n // Skip sockets, symlinks to non-files, devices, etc. to avoid chokidar/fs\n // throwing UVException while trying to watch them.\n }\n}\n\nfunction isIgnored(abs: string, ignored: Matcher[]): boolean {\n for (const m of ignored) {\n if (typeof m === 'function') {\n if (m(abs)) return true;\n continue;\n }\n if (typeof m === 'string' && abs.includes(m)) return true;\n if (m instanceof RegExp && m.test(abs)) return true;\n }\n return false;\n}\n","/**\n * Context Assembler (Phase 4). Produces a Markdown context payload from the\n * graph cache:\n *\n * Ring 0 — the active file's raw, full text.\n * Ring 1 — pruned skeletons of the files it directly imports.\n *\n * The payload keeps full type signatures (imports, interfaces, exports) while\n * dropping implementation bodies, delivering the 80–90% reduction target.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { GraphCache } from '../watcher/sync.js';\n\nexport interface AssembleOptions {\n /** Number of PRD-style stats to append (disabled by default). */\n includeStats?: boolean;\n /** Maximum number of ring-1 files to include. */\n maxSkeletons?: number;\n /**\n * Hard token budget for the whole payload (Ring 0 + Ring 1). When set, Ring 1\n * candidates are ranked by relevance and greedily packed until the budget is\n * exhausted; Ring 0 is always kept in full.\n */\n maxTokens?: number;\n /** Whether the active file itself should also be pruned (Ring 0 raw by default). */\n pruneActiveFile?: boolean;\n}\n\n/** Token accounting for an assembled payload. */\nexport interface TokenStats {\n activeTokens: number;\n dependencyTokens: number;\n totalTokens: number;\n /** When `maxTokens` was supplied, the budget that was enforced. */\n budget?: number;\n /** Number of Ring 1 candidates dropped by the token budget. */\n trimmed: number;\n}\n\nexport interface AssembleResult {\n /** Human-readable Markdown payload for an agent. */\n markdown: string;\n /** First active file (back-compat; prefer `activeFilePaths`). */\n activeFilePath: string;\n /** Every resolved Ring-0 path, in request order. */\n activeFilePaths: string[];\n /** Ring-0 full text of the active file(s). */\n activeSource: string;\n /** Ring-1 entries actually included. */\n included: { filePath: string; language: string | null }[];\n /** Paths referenced by imports that could not be resolved to a file. */\n unresolved: string[];\n /** Approximate token accounting for this payload. */\n tokenStats: TokenStats;\n}\n\n/** Markdown headers/fences overhead subtracted from a `maxTokens` budget. */\nconst MARKDOWN_OVERHEAD_TOKENS = 40;\n\n/**\n * Build the compressed context for one or more open files.\n * `activeFiles` may be absolute or project-relative. Every listed file is\n * emitted in full as Ring 0; the combined set of their local imports is\n * emitted as pruned Ring-1 skeletons, minus any file already in Ring 0.\n *\n * When `opts.maxTokens` is set, Ring 1 candidates are ranked by a cheap\n * relevance proxy (fan-in → path depth → declaration order) and greedily\n * packed until the budget is exhausted; Ring 0 is always kept in full.\n */\nexport function assembleMany(\n activeFiles: string[],\n cache: GraphCache,\n opts: AssembleOptions = {},\n): AssembleResult {\n const {\n includeStats = false,\n maxSkeletons = 50,\n maxTokens,\n pruneActiveFile = false,\n } = opts;\n\n const absList = activeFiles.map((p) => path.resolve(p));\n const sources = absList.map((abs) => {\n try {\n return fs.readFileSync(abs, 'utf8');\n } catch {\n return '';\n }\n });\n const activeSet = new Set(absList);\n\n // Ring-0 text that will actually be emitted (pruned only on request).\n const ring0Texts = absList.map((abs, i) => {\n const entry = cache.get(abs);\n return pruneActiveFile && entry ? entry.skeleton : sources[i];\n });\n\n const included: AssembleResult['included'] = [];\n const unresolved: string[] = [];\n const seen = new Set<string>();\n const addUnresolved = (p: string) => {\n if (!unresolved.includes(p)) unresolved.push(p);\n };\n const addIncluded = (p: string, allowUncached: boolean) => {\n if (seen.has(p)) return;\n const entry = cache.get(p);\n if (!entry && !allowUncached) {\n addUnresolved(p);\n return;\n }\n seen.add(p);\n included.push({ filePath: p, language: entry?.language ?? null });\n };\n\n for (let i = 0; i < absList.length; i++) {\n const abs = absList[i];\n const entry = cache.get(abs);\n if (entry) {\n // Indexed active file: walk its resolved imports.\n for (const imp of entry.imports) {\n if (activeSet.has(imp)) continue; // already full Ring 0\n addIncluded(imp, false);\n }\n } else if (sources[i]) {\n // Unindexed active file: resolve imports from disk with the fallback\n // so the payload is still useful.\n for (const spec of extractSpecifiers(sources[i])) {\n const resolved = resolveLocal(abs, spec);\n if (!resolved) {\n addUnresolved(spec);\n continue;\n }\n if (activeSet.has(resolved)) continue;\n addIncluded(resolved, true);\n }\n }\n }\n\n // Keep declaration order by default (stable output); rank by relevance only\n // when a token budget forces us to drop lower-value dependencies.\n const ordered =\n maxTokens === undefined ? included : rankByRelevance(included, cache);\n\n // Greedy packing: respect maxSkeletons always; additionally stay within the\n // token budget when one is given.\n const budget =\n maxTokens === undefined\n ? undefined\n : Math.max(0, maxTokens - MARKDOWN_OVERHEAD_TOKENS);\n const selected: AssembleResult['included'] = [];\n let trimmed = 0;\n let dependencyTokens = 0;\n for (const cand of ordered) {\n if (selected.length >= maxSkeletons) break;\n const entry = cache.get(cand.filePath);\n // Unindexed candidates get a small nominal cost until they are indexed.\n const cost = entry ? approximateTokens(entry.skeleton) : 8;\n if (budget !== undefined && dependencyTokens + cost > budget) {\n trimmed++;\n continue;\n }\n selected.push(cand);\n dependencyTokens += cost;\n }\n const activeTokens = ring0Texts.reduce(\n (acc, t) => acc + approximateTokens(t),\n 0,\n );\n\n const lines: string[] = [];\n lines.push('# Compressed Code Context', '');\n\n if (absList.length === 1) {\n lines.push(`Active file: \\`${rel(absList[0])}\\``, '');\n } else {\n lines.push('Active files:', '');\n for (const p of absList) lines.push(`- \\`${rel(p)}\\``);\n lines.push('');\n }\n\n // Ring 0.\n lines.push(\n absList.length === 1\n ? '## Ring 0 — Active file (full text)'\n : '## Ring 0 — Active files (full text)',\n '',\n );\n for (let i = 0; i < absList.length; i++) {\n if (absList.length > 1) lines.push(`### \\`${rel(absList[i])}\\``, '');\n const body = ring0Texts[i].trim() || '(empty or unreadable file)';\n lines.push(`\\`\\`\\`${ext(absList[i])}`, body, '```', '');\n }\n\n // Ring 1.\n lines.push(\n `## Ring 1 — Pruned dependencies (${selected.length})`,\n '',\n 'Implementation bodies removed; type signatures, interfaces and exports retained.',\n '',\n );\n if (selected.length === 0) {\n lines.push('_No local dependency skeletons available._', '');\n }\n for (const inc of selected) {\n const entry = cache.get(inc.filePath);\n const label = rel(inc.filePath);\n lines.push(`### \\`${label}\\``, '');\n if (entry) {\n lines.push(`\\`\\`\\`${ext(inc.filePath)}`, entry.skeleton.trim(), '```', '');\n } else {\n lines.push('_Unindexed file._', '');\n }\n }\n if (maxTokens !== undefined && trimmed > 0) {\n lines.push(\n `_Note: token budget of ${maxTokens} excluded ${trimmed} lower-priority dependenc${trimmed === 1 ? 'y' : 'ies'}._`,\n '',\n );\n }\n\n if (unresolved.length > 0) {\n lines.push('## Unresolved imports', '');\n for (const u of unresolved) lines.push(`- \\`${u}\\``);\n lines.push('');\n }\n\n if (includeStats) {\n const budgetNote =\n maxTokens !== undefined ? ` · budget ${maxTokens} (${trimmed} deps trimmed)` : '';\n lines.push(\n '---',\n '',\n `_Token estimate — active: ${activeTokens} · pruned deps: ${dependencyTokens}${budgetNote}._`,\n '',\n );\n }\n\n return {\n markdown: lines.join('\\n'),\n activeFilePath: absList[0] ?? '',\n activeFilePaths: absList,\n activeSource: sources.join('\\n'),\n included: selected,\n unresolved,\n tokenStats: {\n activeTokens,\n dependencyTokens,\n totalTokens: activeTokens + dependencyTokens,\n ...(maxTokens !== undefined ? { budget: maxTokens } : {}),\n trimmed,\n },\n };\n}\n\n/**\n * Build the compressed context for a single open file.\n * `activeFilePath` may be absolute or project-relative.\n */\nexport function assemble(\n activeFilePath: string,\n cache: GraphCache,\n opts: AssembleOptions = {},\n): AssembleResult {\n return assembleMany([activeFilePath], cache, opts);\n}\n\n/** Rank Ring-1 candidates by a cheap relevance proxy: fan-in desc, then depth asc. */\nfunction rankByRelevance(\n candidates: AssembleResult['included'],\n cache: GraphCache,\n): AssembleResult['included'] {\n const fanIn = new Map<string, number>();\n for (const entry of cache.values()) {\n for (const imp of entry.imports) fanIn.set(imp, (fanIn.get(imp) ?? 0) + 1);\n }\n return candidates\n .map((cand, idx) => ({ cand, idx }))\n .sort((a, b) => {\n const fa = fanIn.get(a.cand.filePath) ?? 0;\n const fb = fanIn.get(b.cand.filePath) ?? 0;\n if (fa !== fb) return fb - fa;\n const da = pathDepth(a.cand.filePath);\n const db = pathDepth(b.cand.filePath);\n if (da !== db) return da - db;\n return a.idx - b.idx;\n })\n .map((x) => x.cand);\n}\n\n/** Number of path segments (a rough \"nearby module\" proxy). */\nfunction pathDepth(p: string): number {\n return p.split(/[/\\\\]+/).filter(Boolean).length;\n}\n\n/** Fallback import specifier extraction when no AST index exists yet. */\nexport function extractSpecifiers(source: string): string[] {\n const found: string[] = [];\n // import ... from 'x'; / import 'x'; / require('x')\n const re = /(?:from\\s+['\"`]|import\\s+['\"`]|require\\s*\\(\\s*['\"`])([^'\"`]+)['\"`]/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(source)) !== null) {\n if (m[1]) found.push(m[1]);\n }\n return [...new Set(found)];\n}\n\n/** Resolve a fallback specifier to an existing file, mirroring sync.resolveImport. */\nfunction resolveLocal(importer: string, specifier: string): string | null {\n if (!/^[.~@]/.test(specifier)) return null;\n if (specifier.startsWith('@/')) specifier = specifier.slice(2);\n else if (specifier.startsWith('~')) specifier = specifier.slice(1);\n const base = path.dirname(path.resolve(importer));\n const p = path.resolve(base, specifier);\n const candidates = [\n p,\n `${p}.ts`,\n `${p}.tsx`,\n `${p}.js`,\n `${p}.jsx`,\n `${p}.py`,\n `${p}.go`,\n `${p}.rs`,\n `${p}.dart`,\n `${p}.swift`,\n `${p}.java`,\n `${p}.kt`,\n `${p}.c`,\n `${p}.cpp`,\n path.join(p, 'index.ts'),\n path.join(p, 'index.js'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c) && fs.statSync(c).isFile()) return path.resolve(c);\n }\n return null;\n}\n\n/** Relative path for display (fall back to basename). */\nfunction rel(p: string): string {\n try {\n const cwd = process.cwd();\n if (p.startsWith(cwd)) return '.' + p.slice(cwd.length);\n } catch {\n /* noop */\n }\n return p;\n}\n\n/** Return a code-block language label for a file path. */\nfunction ext(p: string): string {\n return path.extname(p).replace(/^\\./, '') || 'text';\n}\n\n/** Rough, dependency-free token approximation (words + punctuation runs). */\nexport function approximateTokens(text: string): number {\n if (!text) return 0;\n const tokens = text.match(/[A-Za-z0-9_$]+|[^A-Za-z0-9_\\s$]/g);\n return tokens ? tokens.length : 0;\n}\n\nexport function assembleFromCache(\n activeFilePath: string,\n cache: GraphCache,\n): AssembleResult {\n return assemble(activeFilePath, cache);\n}\n","/**\n * HTTP/CLI server. Exposes the context assembler as a small Fastify service:\n *\n * GET /health -> liveness\n * POST /v1/context -> { activeFilePath, maxSkeletons?, includeStats? } => markdown\n *\n * Run as `token-shrink` or `node dist/cli.js`. The server watches `--root`\n * (defaults to cwd) and keeps the import graph + skeletons warm.\n */\n\nimport Fastify from 'fastify';\nimport picocolors from 'picocolors';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { assembleMany } from './server/assembler.js';\nimport { createWatcher, type Matcher } from './watcher/sync.js';\nimport { warmGrammars } from './parser/wasm.js';\n\nexport interface CliOptions {\n port?: number;\n host?: string;\n root?: string;\n ignored?: Matcher[];\n silent?: boolean;\n}\n\nfunction parseArgv(argv = process.argv): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < argv.length; i++) {\n const cur = argv[i];\n if (cur?.startsWith('--')) {\n const key = cur.slice(2);\n const next = argv[i + 1];\n if (next && !next.startsWith('--')) {\n out[key] = next;\n i++;\n } else {\n out[key] = 'true';\n }\n }\n }\n return out;\n}\n\n/** Start the Fastify server; returns the running instance + watcher handle. */\nexport async function startServer(opts: CliOptions = {}) {\n const args = parseArgv();\n const port = opts.port ?? Number(args.port ?? process.env.PORT ?? 3000);\n const host = opts.host ?? args.host ?? '0.0.0.0';\n const root = path.resolve(opts.root ?? args.root ?? process.cwd());\n const silent = opts.silent ?? args.silent === 'true';\n // Optional server-wide token budget: --max-tokens 4000.\n const maxTokensDefault = args['max-tokens']\n ? Number(args['max-tokens'])\n : undefined;\n\n const log = (msg: string) => {\n if (!silent) console.log(picocolors.dim(msg));\n };\n\n // Warm grammars in the background so the first prune isn't slow.\n void warmGrammars().catch(() => {});\n\n const watcher = createWatcher({ root, ignored: opts.ignored });\n log(`Indexing ${root} in the background…`);\n void watcher.indexAll().then((n) => log(`Indexed ${n} files.`));\n\n const app = Fastify({ logger: !silent });\n\n app.get('/health', async () => ({\n status: 'ok',\n service: 'token-shrink',\n version: '2.0.0',\n root,\n indexed: watcher.cache.entries.size,\n }));\n\n app.post('/v1/context', async (req, reply) => {\n const body = (req.body ?? {}) as {\n activeFilePath?: string;\n activeFiles?: string[];\n maxSkeletons?: number;\n maxTokens?: number;\n includeStats?: boolean;\n };\n const hasMany = Array.isArray(body.activeFiles) && body.activeFiles.length > 0;\n if (hasMany && body.activeFilePath) {\n return reply\n .status(400)\n .send({ error: 'Pass either `activeFilePath` or `activeFiles`, not both.' });\n }\n const paths = hasMany\n ? (body.activeFiles as string[])\n : body.activeFilePath\n ? [body.activeFilePath]\n : [];\n if (paths.length === 0) {\n return reply.status(400).send({ error: '`activeFilePath` or `activeFiles` is required' });\n }\n const maxTokens =\n body.maxTokens !== undefined ? body.maxTokens : maxTokensDefault;\n const result = assembleMany(paths, watcher.cache.entries, {\n maxSkeletons: body.maxSkeletons,\n maxTokens: Number.isFinite(maxTokens as number) ? (maxTokens as number) : undefined,\n includeStats: body.includeStats,\n });\n return {\n markdown: result.markdown,\n activeFilePath: result.activeFilePath,\n activeFilePaths: result.activeFilePaths,\n dependencies: result.included.map((i) => i.filePath),\n unresolved: result.unresolved,\n tokenStats: result.tokenStats,\n };\n });\n\n app.setNotFoundHandler(async (req, reply) => {\n void req;\n return reply.status(404).send({ error: 'Not found' });\n });\n\n await app.listen({ port, host });\n log(`Listening on http://${host}:${port}`);\n\n return { app, watcher };\n}\n\n// Start when invoked directly (`node dist/cli.cjs` / the `token-shrink` bin),\n// not when imported as a library. `realpathSync` resolves the npm bin symlink,\n// so `token-shrink` -> `dist/cli.cjs` is detected as `cli.cjs`.\nconst argv1 = process.argv[1] ? path.basename(process.argv[1]) : '';\nlet argv1Real = '';\ntry {\n argv1Real = process.argv[1]\n ? path.basename(fs.realpathSync(process.argv[1]))\n : '';\n} catch {\n /* path may not exist yet (tsx/dev runners) — fall back to argv basename */\n}\nif (\n argv1 === 'cli.js' || argv1 === 'cli.mjs' ||\n argv1 === 'cli.cjs' || argv1 === 'cli.ts' ||\n argv1Real === 'cli.js' || argv1Real === 'cli.mjs' ||\n argv1Real === 'cli.cjs' || argv1Real === 'cli.ts'\n) {\n startServer().catch((err) => {\n console.error(picocolors.red(`[token-shrink] ${err.message}`));\n process.exitCode = 1;\n });\n}\n","/**\n * MCP stdio server. Exposes a single tool:\n *\n * get_compressed_code_context({ activeFilePath, maxSkeletons?, includeStats? })\n *\n * It maintains its own graph cache by watching the repository root derived\n * from the active file, so Cursor/Claude/Cline agents can request pruned context.\n *\n * Root resolution: `--root` (or `ROOT`) pins the project; without one the\n * server auto-detects it from project markers (`.git`, manifests) — first\n * around the process cwd, and lazily from `activeFilePath` once a tool call\n * arrives.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { assembleMany } from './server/assembler.js';\nimport { createWatcher, type Matcher } from './watcher/sync.js';\nimport { detectProjectRoot } from './detect.js';\nimport { languageForFile } from './parser/registry.js';\nimport { analyze } from './parser/analyze.js';\nimport { matchSymbols, type SymbolKind } from './parser/symbols.js';\nimport { SymbolSearch } from './search/index.js';\nimport { gitChangedFiles, type GitChangedOptions, type GitDiffScope } from './git.js';\nimport {\n loadConfig,\n configPathFor,\n EMPTY_CONFIG,\n type TokenShrinkConfig,\n} from './config.js';\n\n/** Watcher handle shape returned by `createWatcher`. */\ntype WatcherHandle = ReturnType<typeof createWatcher>;\n\n/** Supported auto-rule integration targets. */\nexport type RuleTarget = 'cursor' | 'claude' | 'cline';\n\n/** Agent integration file descriptors written when the auto-rule is on. */\ninterface RuleTargetSpec {\n relPath: string;\n sentinel: string;\n body: string;\n}\n\nexport const RULE_TARGET_PATH = {\n cursor: '.cursor/rules/token-shrink.mdc',\n claude: '.claude/rules/token-shrink.md',\n cline: '.clinerules/token-shrink.md',\n} as const;\n\n/** Bump when the generated rule bodies gain new tool guidance. */\nexport const RULE_VERSION = 3;\n/** Marker line inside generated rules; its presence means \"current version\". */\nexport const RULE_VERSION_MARKER = `# token-shrink rule v${RULE_VERSION}`;\n\n/**\n * Auto-workflow guidance (default). Instructs the agent to run the right tool\n * at the right time on every task instead of waiting to be asked. Plain text —\n * intentionally no code backticks so the templates stay easy to read.\n */\nconst WORKFLOW_GUIDANCE = [\n 'When a pruned skeleton is not enough to write or change code correctly, expand the exact',\n 'definition with expand_symbol.',\n '',\n 'Call search_symbol_signatures automatically for any identifier you reference that the',\n 'context does not already define, so you always work from exact signatures.',\n '',\n 'Before multi-file edits, reviews, or work on code with uncommitted or staged changes, call',\n 'git_diff_context and use its impact payload (changed files and their callers) as context.',\n '',\n 'Pass activeFiles to get_compressed_code_context when a task spans several files, and',\n 'maxTokens whenever the payload must fit a token budget.',\n].join('\\n');\n\n/** Light guidance used when `.tokenshrinkrc` sets \"autoWorkflow\": false. */\nconst LIGHT_GUIDANCE = [\n 'Use expand_symbol when a pruned body is not enough, git_diff_context for changed or',\n 'multi-file work, and search_symbol_signatures to locate definitions repo-wide.',\n].join('\\n');\n\nexport const AUTO_RULE_SENTINEL = '# auto-generated by token-shrink';\nexport const CURSOR_RULE_PATH = RULE_TARGET_PATH.cursor;\n/** Back-compat alias for the previous single-target constant. */\nexport const AUTO_RULE_PATH = CURSOR_RULE_PATH;\nexport const CLAUDE_RULE_PATH = RULE_TARGET_PATH.claude;\nexport const CLAUDE_RULE_SENTINEL = '# auto-generated by token-shrink (claude)';\nexport const CLINE_RULE_PATH = RULE_TARGET_PATH.cline;\nexport const CLINE_RULE_SENTINEL = '# auto-generated by token-shrink (cline)';\n\nconst ruleTargets: Record<RuleTarget, RuleTargetSpec> = {\n cursor: {\n relPath: CURSOR_RULE_PATH,\n sentinel: AUTO_RULE_SENTINEL,\n body: `---\ndescription: Compress dependency context with token-shrink on every task\nglobs: **/*.{ts,tsx,js,jsx,py,go,rs,dart,swift,java,kt,c,cpp,h,hpp,php}\nalwaysApply: true\n---\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${WORKFLOW_GUIDANCE}\n\n${RULE_VERSION_MARKER}\n${AUTO_RULE_SENTINEL}\n`,\n },\n claude: {\n relPath: CLAUDE_RULE_PATH,\n sentinel: CLAUDE_RULE_SENTINEL,\n body: `---\ndescription: Compress dependency context with token-shrink on every task\npaths: [\"**/*.{ts,tsx,js,jsx,py,go,rs,dart,swift,java,kt,c,cpp,h,hpp,php}\"]\n---\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${WORKFLOW_GUIDANCE}\n\n${RULE_VERSION_MARKER}\n${CLAUDE_RULE_SENTINEL}\n`,\n },\n cline: {\n relPath: CLINE_RULE_PATH,\n sentinel: CLINE_RULE_SENTINEL,\n // No frontmatter -> always-on rule (Cline treats unconditional .clinerules/*.md\n // files as universal rules, applied to every task regardless of active file).\n body: `# token-shrink\n\nBefore working on a file in this repo, call the \\`get_compressed_code_context\\` MCP tool with\nthat file's path, and use the returned Ring 0 + Ring 1 payload as the context for that file\nand its direct imports.\n\n${WORKFLOW_GUIDANCE}\n\n${RULE_VERSION_MARKER}\n${CLINE_RULE_SENTINEL}\n`,\n },\n};\n\nexport interface McpServerOptions {\n /**\n * Project root to watch. When omitted (and the `ROOT` env var is unset) the\n * server runs in auto-detect mode: it locates the project from markers\n * around the process cwd if possible, otherwise lazily from the first tool\n * call's `activeFilePath`.\n */\n root?: string;\n /** Extra ignore globs for the watcher. */\n ignored?: Matcher[];\n /** Silence log output (stdio must stay clean for the MCP protocol). */\n silent?: boolean;\n /** Whether to auto-write agent integration rules at all. Default true. */\n createRule?: boolean;\n /** Which agent rule target(s) to write. Default all. */\n ruleTarget?: RuleTarget | RuleTarget[];\n}\n\nexport interface RuleWriteResult {\n created: boolean;\n skipped: 'none' | 'exists' | 'user';\n /** Path of the rule file that was considered. */\n filePath: string;\n}\n\n/**\n * Write a rules file for a given agent target. Idempotent and version-aware:\n * - absent -> create it (tagged with our sentinel + version marker);\n * - has our sentinel AND current version marker -> skip (already ours);\n * - has our sentinel but predates the version marker -> rewrite (upgrade);\n * - present without our sentinel -> leave the user's file untouched.\n */\nexport function createAutoRule(root: string, target: RuleTarget): RuleWriteResult {\n const spec = ruleTargets[target];\n const rulePath = path.join(root, spec.relPath);\n // `.tokenshrinkrc.json` \"autoWorkflow\": false switches to lightweight rules.\n const autoWorkflow = loadConfig(root).autoWorkflow !== false;\n const body = autoWorkflow\n ? spec.body\n : spec.body.replace(WORKFLOW_GUIDANCE, LIGHT_GUIDANCE);\n try {\n if (fs.existsSync(rulePath)) {\n const existing = fs.readFileSync(rulePath, 'utf8');\n if (existing.includes(spec.sentinel)) {\n if (existing.includes(RULE_VERSION_MARKER)) {\n return { created: false, skipped: 'exists', filePath: rulePath };\n }\n // Legacy rule we wrote before the version marker existed: upgrade it.\n fs.writeFileSync(rulePath, body, 'utf8');\n return { created: true, skipped: 'none', filePath: rulePath };\n }\n return { created: false, skipped: 'user', filePath: rulePath };\n }\n fs.mkdirSync(path.dirname(rulePath), { recursive: true });\n fs.writeFileSync(rulePath, body, 'utf8');\n return { created: true, skipped: 'none', filePath: rulePath };\n } catch (err) {\n // Never let a rule-write failure take down the MCP server; surface via result.\n process.stderr.write(\n `[token-shrink] Failed to write rule for \"${target}\": ${(err as Error).message}\\n`,\n );\n return { created: false, skipped: 'none', filePath: rulePath };\n }\n}\n\n/** Back-compat alias for code that imported the old Cursor-only helper. */\nexport function createCursorRule(root: string): RuleWriteResult {\n return createAutoRule(root, 'cursor');\n}\n\n/** Expand `ruleTarget` (single / array / all) into the ordered list to write. */\nfunction resolveTargets(ruleTarget: McpServerOptions['ruleTarget']): RuleTarget[] {\n if (!ruleTarget) return ['cursor', 'claude', 'cline'];\n const list = Array.isArray(ruleTarget) ? ruleTarget : [ruleTarget];\n if (list.includes('all' as unknown as RuleTarget)) return ['cursor', 'claude', 'cline'];\n return list;\n}\n\n/** Is `child` inside (or equal to) directory `parent`? */\nfunction isWithin(parent: string, child: string): boolean {\n const rel = path.relative(path.resolve(parent), path.resolve(child));\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n}\n\n/**\n * Normalize the single-file / multi-file active-file inputs into a path list.\n * Exactly one of the two forms may be supplied.\n */\nfunction resolveActiveFiles(\n single: string | undefined,\n many: string[] | undefined,\n): string[] {\n if (many && many.length > 0) {\n if (single) {\n throw new Error('Pass either `activeFilePath` or `activeFiles`, not both.');\n }\n return many;\n }\n if (single) return [single];\n throw new Error('`activeFilePath` or `activeFiles` is required');\n}\n\n/**\n * Start the MCP server. Because the MCP protocol runs over stdio, all human\n * logging should go to stderr; stdout is reserved for JSON-RPC.\n */\nexport async function startMcpServer(opts: McpServerOptions = {}): Promise<McpServer> {\n const log = (msg: string) => {\n if (!opts.silent) process.stderr.write(`[token-shrink] ${msg}\\n`);\n };\n const textReply = (text: string) => ({\n content: [{ type: 'text' as const, text }],\n });\n\n // ---------------------------------------------------------------------------\n // Root + watcher lifecycle. An explicit root (--root / ROOT env) warms up\n // immediately. Otherwise the server auto-detects: project markers around the\n // cwd win at startup; if none exist, the root is chosen lazily from the first\n // tool call, and later calls re-point the watcher when the active file moves\n // to a different project.\n // ---------------------------------------------------------------------------\n const explicitRoot = opts.root?.trim() || process.env.ROOT?.trim() || '';\n const autoMode = explicitRoot === '';\n\n let root = '';\n let watcher: WatcherHandle | null = null;\n let searchIndex: SymbolSearch | null = null;\n let lifecycle: Promise<void> = Promise.resolve();\n\n // `.tokenshrinkrc.json` state: re-read at every root attach and hot-reloaded\n // when the file changes under a running server.\n let config: TokenShrinkConfig = { ...EMPTY_CONFIG };\n let configFsw: fs.FSWatcher | null = null;\n let configReloadTimer: NodeJS.Timeout | null = null;\n\n const stopConfigWatch = () => {\n if (configReloadTimer) {\n clearTimeout(configReloadTimer);\n configReloadTimer = null;\n }\n if (configFsw) {\n configFsw.close();\n configFsw = null;\n }\n };\n\n const reloadForRoot = async (r: string) => {\n const next = loadConfig(r, (m) => log(m));\n const changed = JSON.stringify(next) !== JSON.stringify(config);\n config = next;\n if (!changed || !watcher || root !== r) return;\n log('.tokenshrinkrc.json changed — re-indexing with the new rules.');\n stopConfigWatch();\n const old = watcher;\n watcher = null;\n root = '';\n await old.close().catch(() => {});\n await attachWatcher(r, false);\n };\n\n const startConfigWatch = (r: string) => {\n stopConfigWatch();\n const cfgPath = configPathFor(r);\n if (!fs.existsSync(cfgPath)) return;\n try {\n configFsw = fs.watch(cfgPath, () => {\n if (configReloadTimer) clearTimeout(configReloadTimer);\n configReloadTimer = setTimeout(() => {\n void enqueue(() => reloadForRoot(r));\n }, 200);\n });\n } catch {\n /* fs.watch unavailable — config hot-reload disabled for this root */\n }\n };\n\n // Auto-create agent integration rules so the tool is used by default.\n const writeRules = (r: string) => {\n if (opts.createRule === false) return;\n for (const target of resolveTargets(opts.ruleTarget)) {\n const res = createAutoRule(r, target);\n if (res.created) {\n log(`Wrote ${target} rule to ${res.filePath}`);\n } else if (res.skipped === 'user') {\n log(`${target} rule exists (user-authored); leaving it untouched.`);\n }\n }\n };\n\n /**\n * Attach a watcher to `r`. When `waitForIndex` is true the returned promise\n * only resolves once the cold tree index finishes (used on the lazy first\n * call so Ring 1 is already warm).\n */\n const attachWatcher = (r: string, waitForIndex: boolean): Promise<void> => {\n stopConfigWatch();\n config = loadConfig(r, (m) => log(m));\n const search = new SymbolSearch();\n const w = createWatcher({\n root: r,\n ignored: opts.ignored,\n config,\n onIndexed: (abs, entry) => {\n if (entry.symbols && entry.symbols.length > 0) search.setFile(abs, entry.symbols);\n else search.removeFile(abs);\n },\n onRemoved: (abs) => search.removeFile(abs),\n });\n searchIndex = search;\n root = r;\n watcher = w;\n writeRules(r);\n log(`Indexing ${r} in the background…`);\n const indexed = w\n .indexAll()\n .then((n) => log(`Indexed ${n} files.`))\n .catch((err: unknown) => log(`Indexing ${r} failed: ${(err as Error)?.message ?? err}`));\n startConfigWatch(r);\n return waitForIndex ? indexed : Promise.resolve();\n };\n\n /** Serialize lifecycle transitions so concurrent tool calls cannot race. */\n const enqueue = (fn: () => Promise<void>): Promise<void> => {\n const run = lifecycle.then(fn);\n lifecycle = run.then(\n () => {},\n () => {},\n );\n return run;\n };\n\n if (explicitRoot) {\n void enqueue(() => attachWatcher(path.resolve(explicitRoot), false));\n } else {\n const fromCwd = detectProjectRoot(process.cwd());\n if (fromCwd) {\n log(`Auto-detected project root ${fromCwd} (from cwd). Pass --root to pin it.`);\n void enqueue(() => attachWatcher(fromCwd, false));\n } else {\n log(\n 'No --root and no project markers around the current directory — ' +\n 'will auto-detect the project from the first tool call.',\n );\n }\n }\n\n /**\n * Ensure a watcher covers `activeFilePath`. No-op once ready; in auto mode a\n * file outside the current root triggers detection of a new root.\n */\n const ensureReadyFor = (activeFilePath: string): Promise<void> =>\n enqueue(async () => {\n const abs = path.resolve(activeFilePath);\n if (watcher && root) {\n if (!autoMode || isWithin(root, abs)) return; // already covered\n const next = detectProjectRoot(abs);\n if (!next || next === root) return; // nothing better to index\n log(`Active file is in a different project (${next}); re-indexing (was ${root}).`);\n await watcher.close().catch(() => {});\n watcher = null;\n root = '';\n }\n if (root) return; // defensive: watcher attached meanwhile\n const detected = detectProjectRoot(abs);\n const target = detected ?? process.cwd();\n if (detected) {\n log(`Auto-detected project root ${target} from ${abs}.`);\n } else {\n log(`No project markers around ${abs}; falling back to ${target}.`);\n }\n await attachWatcher(target, true);\n });\n\n const server = new McpServer(\n { name: 'token-shrink', version: '2.0.0' },\n { capabilities: { tools: {} } },\n );\n\n server.registerTool(\n 'get_compressed_code_context',\n {\n title: 'Get Compressed Code Context',\n description:\n 'Returns a compressed, framework-aware AST context payload for one or more files: ' +\n 'each active file’s full source (Ring 0) plus pruned skeletons of their direct ' +\n 'imports (Ring 1). Implementation bodies are removed but type signatures, ' +\n 'interfaces, and module exports are preserved for ~80-90% token reduction. ' +\n 'Use `activeFiles` to pin multiple files as Ring 0 and `maxTokens` to cap the ' +\n 'payload with a relevance-ranked Ring 1.',\n inputSchema: {\n activeFilePath: z\n .string()\n .optional()\n .describe('Path to the file the agent is working on (or use `activeFiles`)'),\n activeFiles: z\n .array(z.string())\n .optional()\n .describe('Multiple files to keep as Ring 0 (full text); mutually exclusive with `activeFilePath`'),\n maxSkeletons: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Cap on number of dependency skeletons to include'),\n maxTokens: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Hard token budget for the whole payload; Ring 1 is relevance-ranked and packed to fit'),\n includeStats: z\n .boolean()\n .optional()\n .describe('Append approximate token-count stats'),\n },\n },\n async ({ activeFilePath, activeFiles, maxSkeletons, maxTokens, includeStats }) => {\n const paths = resolveActiveFiles(activeFilePath, activeFiles);\n // In auto-detect mode each Ring-0 file may live in a different project;\n // ensure the watcher covers every one before assembling.\n for (const p of paths) await ensureReadyFor(p);\n if (!watcher) {\n throw new Error('token-shrink watcher failed to start');\n }\n const result = assembleMany(paths, watcher.cache.entries, {\n maxSkeletons,\n maxTokens,\n includeStats,\n });\n const ts = result.tokenStats;\n const budgetNote =\n ts.budget !== undefined ? ` budget=${ts.budget} trimmed=${ts.trimmed}` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: result.markdown,\n },\n {\n type: 'text' as const,\n text:\n `[stats] files=${result.activeFilePaths.length} ` +\n `dependencies=${result.included.length} unresolved=${result.unresolved.length} ` +\n `tokens=${ts.totalTokens}${budgetNote}`,\n },\n ],\n };\n },\n );\n\n server.registerTool(\n 'expand_symbol',\n {\n title: 'Expand Symbol',\n description:\n 'Returns the full, un-pruned source of a named definition (function, method, ' +\n 'class, interface, enum, arrow/const function, …) from one file. Use it when ' +\n 'a Ring-1 skeleton is not enough — e.g. you need the exact algorithm inside ' +\n 'a pruned body before writing or changing code.',\n inputSchema: {\n filePath: z.string().describe('Path to the file containing the symbol'),\n symbolName: z\n .string()\n .describe('Name of the definition to expand (exact name preferred; falls back to case-insensitive/substring)'),\n maxMatches: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .describe('Maximum matching definitions to return (default 5)'),\n },\n },\n async ({ filePath, symbolName, maxMatches }) => {\n await ensureReadyFor(filePath);\n const abs = path.resolve(filePath);\n let source: string;\n try {\n source = fs.readFileSync(abs, 'utf8');\n } catch {\n return textReply(`File not found or unreadable: ${filePath}`);\n }\n const spec = languageForFile(abs);\n if (!spec) {\n return textReply(`No token-shrink grammar for file type: ${filePath}`);\n }\n const { symbols } = await analyze(abs, source, { skipPrune: true });\n if (symbols.length === 0) {\n return textReply(\n `No parseable definitions found in ${filePath} — the grammar may be unavailable ` +\n '(first run offline) or the language exposes no name-carrying definitions yet.',\n );\n }\n const matches = matchSymbols(symbols, symbolName).slice(0, maxMatches ?? 5);\n if (matches.length === 0) {\n const names = [...new Set(symbols.map((s) => s.name))].slice(0, 12).join(', ');\n return textReply(\n `No symbol named \"${symbolName}\" in ${filePath}.` +\n (names ? ` Other definitions there: ${names}.` : ''),\n );\n }\n const fence = path.extname(abs).replace(/^\\./, '') || 'text';\n const parts = matches.map((m) => {\n const body = source.slice(m.start, m.end).trim();\n return (\n `### ${m.name} (${m.kind}) — ${abs}:${m.line}` +\n '\\n\\n```' +\n fence +\n '\\n' +\n body +\n '\\n```\\n'\n );\n });\n const disambig =\n matches.length > 1\n ? `\\n_Multiple definitions matched (${matches.length}); each is shown above._`\n : '';\n return textReply(parts.join('\\n') + disambig);\n },\n );\n\n server.registerTool(\n 'git_diff_context',\n {\n title: 'Git Diff Context',\n description:\n 'Builds an impact-analysis payload from git changes: every changed file is ' +\n 'kept as Ring 0 (full code), their imports AND the files that import them ' +\n '(file-level callers) are attached as pruned Ring-1 skeletons. Use for PR ' +\n 'reviews, regression fixes and multi-file tasks where no single \"active file\" exists.',\n inputSchema: {\n scope: z\n .enum(['worktree', 'staged', 'branch'])\n .optional()\n .describe(\"Diff scope: 'worktree' (default, staged+unstaged), 'staged', or 'branch' (base...head)\"),\n base: z.string().optional().describe('Base ref for scope=branch (default HEAD~1)'),\n head: z.string().optional().describe('Head ref for scope=branch (default HEAD)'),\n includeUntracked: z\n .boolean()\n .optional()\n .describe('Include untracked files (worktree scope only)'),\n maxFiles: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Maximum changed files to include (default 30)'),\n maxImporters: z\n .number()\n .int()\n .min(0)\n .max(100)\n .optional()\n .describe('Maximum importer skeletons to append (default 20)'),\n maxSkeletons: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Cap on dependency skeletons per payload'),\n maxTokens: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Hard token budget for the whole payload'),\n includeStats: z.boolean().optional().describe('Append approximate token-count stats'),\n },\n },\n async ({\n scope,\n base,\n head,\n includeUntracked,\n maxFiles,\n maxImporters,\n maxSkeletons,\n maxTokens,\n includeStats,\n }) => {\n // The git root is the server root; in auto mode detect from cwd until a\n // tool call establishes the project.\n await ensureReadyFor(process.cwd());\n if (!watcher || !root) {\n throw new Error('token-shrink watcher failed to start');\n }\n const repoRoot = root;\n const changedResult = await gitChangedFiles(repoRoot, {\n scope: (scope as GitDiffScope) ?? 'worktree',\n base,\n head,\n includeUntracked,\n } satisfies GitChangedOptions);\n if (changedResult.error) {\n return textReply(`git error: ${changedResult.error}`);\n }\n if (changedResult.files.length === 0) {\n return textReply('No changed files (clean worktree, or empty diff for the requested scope).');\n }\n const fileCap = maxFiles ?? 30;\n const changed = changedResult.files.slice(0, fileCap);\n const filesTruncated = changedResult.files.length > changed.length;\n\n // Warm not-yet-indexed changed files so Ring-1 edges are accurate.\n for (const abs of changed) {\n if (!watcher.cache.entries.has(abs)) {\n try {\n await watcher.index(abs);\n } catch {\n /* unparseable file — skip */\n }\n }\n }\n\n const assembled = assembleMany(changed, watcher.cache.entries, {\n maxSkeletons,\n maxTokens,\n includeStats,\n });\n\n // Reverse edges: files that import the changed files (file-level callers).\n const changedSet = new Set(changed);\n const importerOf = new Map<string, string[]>();\n for (const [fileAbs, entry] of watcher.cache.entries) {\n for (const imp of entry.imports) {\n if (!changedSet.has(imp)) continue;\n const list = importerOf.get(imp) ?? [];\n list.push(fileAbs);\n importerOf.set(imp, list);\n }\n }\n const importerList = [...new Set([...importerOf.values()].flat())].filter(\n (f) => !changedSet.has(f),\n );\n const importerCap = maxImporters ?? 20;\n const importers = importerList.slice(0, importerCap);\n const importersTruncated = importerList.length > importers.length;\n\n const relLabel = (abs: string) => {\n const rel = path.relative(repoRoot, abs);\n return rel && !rel.startsWith('..') ? rel : abs;\n };\n const fence = (abs: string) => path.extname(abs).replace(/^\\./, '') || 'text';\n\n const parts: string[] = [];\n parts.push(\n `# Git Impact Context (${changed.length} changed file${changed.length === 1 ? '' : 's'})`,\n '',\n );\n parts.push(`- changed files: ${changed.map(relLabel).join(', ')}`);\n if (importers.length > 0) {\n parts.push(`- importing files (callers): ${importers.map(relLabel).join(', ')}`);\n }\n parts.push('', '---', '');\n parts.push('## Changed files — full code', '');\n for (const abs of changed) {\n parts.push(`### \\`${relLabel(abs)}\\``, '');\n let source = '';\n try {\n source = fs.readFileSync(abs, 'utf8');\n } catch {\n /* file vanished between listing and read */\n }\n parts.push(`\\`\\`\\`${fence(abs)}`, source.trim() || '(unreadable file)', '```', '');\n }\n parts.push(`## Ring 1 — Pruned dependencies (${assembled.included.length})`, '');\n parts.push('', 'Implementation bodies removed; type signatures, interfaces and exports retained.', '');\n if (assembled.included.length === 0) {\n parts.push('_No local dependency skeletons available._', '');\n }\n for (const inc of assembled.included) {\n const entry = watcher.cache.entries.get(inc.filePath);\n const label = relLabel(inc.filePath);\n parts.push(`### \\`${label}\\``, '');\n if (entry) {\n parts.push(`\\`\\`\\`${fence(inc.filePath)}`, entry.skeleton.trim(), '```', '');\n } else {\n parts.push('_Unindexed file._', '');\n }\n parts.push('');\n }\n if (assembled.tokenStats.budget !== undefined && assembled.tokenStats.trimmed > 0) {\n parts.push(\n `_Note: token budget of ${assembled.tokenStats.budget} excluded ` +\n `${assembled.tokenStats.trimmed} lower-priority dependencies._`,\n '',\n );\n }\n\n if (importers.length > 0) {\n parts.push(`## Ring 2 — Files importing the diff (${importers.length})`, '');\n parts.push('', 'Pruned skeletons of modules that call into the changed files.', '');\n for (const abs of importers) {\n const entry = watcher.cache.entries.get(abs);\n parts.push(`### \\`${relLabel(abs)}\\``, '');\n if (entry) {\n parts.push(`\\`\\`\\`${fence(abs)}`, entry.skeleton.trim(), '```', '');\n } else {\n parts.push('_Unindexed file._', '');\n }\n parts.push('');\n }\n if (importersTruncated) {\n parts.push(\n `_…and ${importerList.length - importers.length} more importing files (raise maxImporters)._`,\n '',\n );\n }\n }\n if (filesTruncated) {\n parts.push(\n `_Note: capped to ${fileCap} changed files (${changedResult.files.length} total); ` +\n 'raise maxFiles to include more._',\n '',\n );\n }\n if (assembled.unresolved.length > 0) {\n parts.push('## Unresolved imports', '');\n for (const u of assembled.unresolved) parts.push(`- \\`${u}\\``);\n parts.push('');\n }\n\n const ts = assembled.tokenStats;\n const budgetNote =\n ts.budget !== undefined ? ` budget=${ts.budget} trimmed=${ts.trimmed}` : '';\n const stats =\n `[git-stats] files=${changed.length} ring1=${assembled.included.length} ` +\n `importers=${importers.length} unresolved=${assembled.unresolved.length} tokens=${ts.totalTokens}${budgetNote}`;\n return {\n content: [\n { type: 'text' as const, text: parts.join('\\n') },\n { type: 'text' as const, text: stats },\n ],\n };\n },\n );\n\n server.registerTool(\n 'search_symbol_signatures',\n {\n title: 'Search Symbol Signatures',\n description:\n 'Fast, repo-wide lookup of named definitions (functions, methods, classes, ' +\n 'interfaces, enums, …). Returns compact `file:line — signature` lines instead ' +\n 'of raw search hits. Use it to discover where a symbol lives and what its ' +\n 'exact signature is before reading or editing code.',\n inputSchema: {\n query: z\n .string()\n .describe('Search text (matched against symbol names; falls back to signatures)'),\n maxResults: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Maximum results to return (default 10)'),\n kind: z\n .enum(['function', 'method', 'arrow', 'class', 'interface', 'enum', 'type', 'other'])\n .optional()\n .describe('Only return definitions of this kind'),\n },\n },\n async ({ query, maxResults, kind }) => {\n await ensureReadyFor(process.cwd());\n if (!searchIndex) {\n throw new Error('token-shrink symbol index failed to start');\n }\n // Cold lazy build: if the background index has not finished yet, load\n // whatever the cache already holds so the first search still answers.\n if (searchIndex.size === 0 && watcher && watcher.cache.entries.size > 0) {\n searchIndex.loadCache(watcher.cache.entries);\n }\n const hits = searchIndex.search(query, {\n maxResults: maxResults ?? 10,\n kind: kind as SymbolKind | undefined,\n });\n if (hits.length === 0) {\n return textReply(`No symbols match \"${query}\". Try a different name or kind.`);\n }\n const lines = hits.map((h) => `- \\`${h.label}\\``);\n return textReply(\n `${lines.join('\\n')}\\n\\n_Found ${hits.length} symbol${hits.length === 1 ? '' : 's'} ` +\n `matching \"${query}\"._`,\n );\n },\n );\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log('MCP server connected.');\n return server;\n}\n\n// Start the server only when run as the MCP binary, not when imported as a\n// library. Guard against both the source filenames and the tsup bundles:\n// `dist/mcp.cjs` (used by the npm `token-shrink-mcp` bin). `realpathSync`\n// resolves the npm bin symlink, so `token-shrink-mcp` -> `dist/mcp.cjs` is\n// detected as `mcp.cjs`.\nconst argv1 = process.argv[1] ? path.basename(process.argv[1]) : '';\nlet argv1Real = '';\ntry {\n argv1Real = process.argv[1]\n ? path.basename(fs.realpathSync(process.argv[1]))\n : '';\n} catch {\n /* path may not exist yet (tsx/dev runners) — fall back to argv basename */\n}\nconst invokedAsMcp =\n argv1 === 'mcp.js' || argv1 === 'mcp.mjs' ||\n argv1 === 'mcp.cjs' || argv1 === 'mcp.ts' ||\n argv1Real === 'mcp.js' || argv1Real === 'mcp.mjs' ||\n argv1Real === 'mcp.cjs' || argv1Real === 'mcp.ts';\nif (invokedAsMcp) {\n const rootArg = (() => {\n const i = process.argv.indexOf('--root');\n if (i !== -1 && process.argv[i + 1]) return process.argv[i + 1];\n const eq = process.argv.find((a) => a.startsWith('--root='));\n if (eq) return eq.slice('--root='.length);\n return undefined;\n })();\n const createRule = !(\n process.env.TOKEN_SHRINK_CREATE_RULE === '0' ||\n process.env.TOKEN_SHRINK_CREATE_RULE === 'false' ||\n process.env.CONTEXT_SHRINK_CREATE_RULE === '0' ||\n process.env.CONTEXT_SHRINK_CREATE_RULE === 'false' ||\n process.argv.includes('--no-create-rule') ||\n (() => {\n const f = process.argv.find((a) => a.startsWith('--create-rule='));\n return f ? f.slice('--create-rule='.length) === 'false' : false;\n })()\n );\n // --rule-target=cursor|claude|cline|all (repeatable / comma-separated), default all.\n const rawTargets = process.argv\n .filter((a) => a.startsWith('--rule-target='))\n .flatMap((a) => a.slice('--rule-target='.length).split(','));\n const ruleTarget: RuleTarget | RuleTarget[] | undefined =\n rawTargets.length > 0 && !rawTargets.includes('all')\n ? ([...new Set(rawTargets)].filter(\n (v): v is RuleTarget => v === 'cursor' || v === 'claude' || v === 'cline',\n ) as RuleTarget[])\n : undefined;\n void startMcpServer({ root: rootArg, createRule, ruleTarget }).catch((err) => {\n process.stderr.write(`[token-shrink] MCP server error: ${err.message}\\n`);\n process.exitCode = 1;\n });\n}\n","/**\n * Thin `git` plumbing helpers for the `git_diff_context` MCP tool. Uses the\n * system `git` binary via spawn (no native deps) and always runs with\n * `--no-pager` + `LC_ALL=C` so output is deterministic and parseable.\n */\n\nimport { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\nexport type GitDiffScope = 'worktree' | 'staged' | 'branch';\n\nexport interface GitChangedOptions {\n scope: GitDiffScope;\n /** Base ref for `scope: 'branch'` (e.g. `main`). Defaults to `HEAD~1`. */\n base?: string;\n /** Head ref for `scope: 'branch'`. Defaults to `HEAD`. */\n head?: string;\n /** Include untracked files (worktree scope only). */\n includeUntracked?: boolean;\n}\n\nexport interface GitChangedResult {\n /** Absolute paths of changed files that exist on disk. */\n files: string[];\n /** Non-empty when git could not be satisfied (not a repo, bad ref, …). */\n error?: string;\n}\n\nfunction runGit(root: string, args: string[]): Promise<{ ok: boolean; out: string; err: string }> {\n return new Promise((resolve) => {\n const child = spawn('git', ['--no-pager', ...args], {\n cwd: root,\n env: { ...process.env, LC_ALL: 'C' },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let out = '';\n let err = '';\n child.stdout.on('data', (d) => {\n out += d;\n });\n child.stderr.on('data', (d) => {\n err += d;\n });\n child.on('error', (e) => resolve({ ok: false, out: '', err: e.message }));\n child.on('close', (code) => resolve({ ok: code === 0, out, err }));\n });\n}\n\n/** Split git name-only output into relative paths. */\nfunction parseNames(out: string): string[] {\n return out\n .split('\\n')\n .map((l) => l.trim())\n .filter(Boolean);\n}\n\nfunction isFatal(err: string): string | undefined {\n if (!err) return undefined;\n const e = err.trim();\n if (/not a git repository|fatal:/i.test(e)) return e;\n return undefined;\n}\n\n/**\n * List files changed in the repository at `root`. Paths are returned absolute\n * and filtered to files that still exist on disk.\n */\nexport async function gitChangedFiles(\n root: string,\n opts: GitChangedOptions,\n): Promise<GitChangedResult> {\n const scope = opts.scope ?? 'worktree';\n const filter = '--diff-filter=ACMRT';\n\n let relative: string[] = [];\n if (scope === 'staged') {\n const r = await runGit(root, ['diff', '--cached', '--name-only', filter]);\n const fatal = isFatal(r.err);\n if (!r.ok) return { files: [], ...(fatal ? { error: fatal } : {}) };\n relative = parseNames(r.out);\n } else if (scope === 'branch') {\n const base = opts.base ?? 'HEAD~1';\n const head = opts.head ?? 'HEAD';\n const r = await runGit(root, ['diff', '--name-only', `${base}...${head}`, filter]);\n const fatal = isFatal(r.err);\n if (!r.ok) return { files: [], ...(fatal ? { error: fatal } : {}) };\n relative = parseNames(r.out);\n } else {\n // worktree = staged + unstaged (merged, deduped).\n const [unstaged, staged] = await Promise.all([\n runGit(root, ['diff', '--name-only', filter]),\n runGit(root, ['diff', '--cached', '--name-only', filter]),\n ]);\n const fatal = isFatal(unstaged.err) ?? isFatal(staged.err);\n if (!unstaged.ok && !staged.ok) {\n return { files: [], ...(fatal ? { error: fatal } : {}) };\n }\n const merged = new Set([...parseNames(unstaged.out), ...parseNames(staged.out)]);\n if (opts.includeUntracked) {\n const ut = await runGit(root, ['ls-files', '--others', '--exclude-standard']);\n for (const f of parseNames(ut.out)) merged.add(f);\n }\n relative = [...merged];\n }\n\n const files = relative\n .map((rel) => path.resolve(root, rel))\n .filter((abs) => {\n try {\n return fs.statSync(abs).isFile();\n } catch {\n return false; // deleted in the meantime / rename source\n }\n });\n\n return { files };\n}\n"],"mappings":"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","names":["path","ext","import_node_path","import_node_path","path","dir","fs","walk","Parser","require","path","import_node_fs","import_node_path","path","fs","import_node_fs","import_node_path","path","fs","rel","import_node_fs","import_node_path","path","fs","rel","chokidar","import_node_fs","import_node_path","path","fs","import_node_fs","import_node_path","path","picocolors","Fastify","fs","import_node_fs","import_node_path","import_node_path","import_node_fs","rel","path","fs","path","fs","rel","argv1","argv1Real"]}