@ff-labs/fff-bun 0.10.6 → 0.10.7-nightly.0f4b0dc

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.
package/dist/fff-api.d.ts CHANGED
@@ -413,6 +413,11 @@ export interface GrepOptions {
413
413
  * partial results. 0 = unlimited. (default: 0)
414
414
  */
415
415
  timeBudgetMs?: number;
416
+ /**
417
+ * Apply `timeBudgetMs` even before anything matched. Off by default, so a
418
+ * zero-match query scans every candidate file. (default: false)
419
+ */
420
+ enforceTimeBudget?: boolean;
416
421
  /** Number of context lines to include before each match (default: 0) */
417
422
  beforeContext?: number;
418
423
  /** Number of context lines to include after each match (default: 0) */
@@ -516,6 +521,11 @@ export interface MultiGrepOptions {
516
521
  * partial results. 0 = unlimited. (default: 0)
517
522
  */
518
523
  timeBudgetMs?: number;
524
+ /**
525
+ * Apply `timeBudgetMs` even before anything matched. Off by default, so a
526
+ * zero-match query scans every candidate file. (default: false)
527
+ */
528
+ enforceTimeBudget?: boolean;
519
529
  /** Number of context lines to include before each match (default: 0) */
520
530
  beforeContext?: number;
521
531
  /** Number of context lines to include after each match (default: 0) */
@@ -1 +1 @@
1
- {"version":3,"file":"fff-api.d.ts","sourceRoot":"","sources":["../src/fff-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fff-api.d.ts","sourceRoot":"","sources":["../src/fff-api.ts"],"names":[],"mappings":"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"}
package/dist/ffi.d.ts CHANGED
@@ -52,11 +52,11 @@ export declare function ffiSearchMixed(handle: NativeHandle, query: string, curr
52
52
  /**
53
53
  * Live grep - search file contents.
54
54
  */
55
- export declare function ffiLiveGrep(handle: NativeHandle, query: string, mode: string, maxFileSize: number, maxMatchesPerFile: number, smartCase: boolean, fileOffset: number, pageLimit: number, timeBudgetMs: number, beforeContext: number, afterContext: number, classifyDefinitions: boolean): Result<GrepResult>;
55
+ export declare function ffiLiveGrep(handle: NativeHandle, query: string, mode: string, maxFileSize: number, maxMatchesPerFile: number, smartCase: boolean, fileOffset: number, pageLimit: number, timeBudgetMs: number, enforceTimeBudget: boolean, beforeContext: number, afterContext: number, classifyDefinitions: boolean): Result<GrepResult>;
56
56
  /**
57
57
  * Multi-pattern grep - Aho-Corasick multi-needle search.
58
58
  */
59
- export declare function ffiMultiGrep(handle: NativeHandle, patternsJoined: string, constraints: string, maxFileSize: number, maxMatchesPerFile: number, smartCase: boolean, fileOffset: number, pageLimit: number, timeBudgetMs: number, beforeContext: number, afterContext: number, classifyDefinitions: boolean): Result<GrepResult>;
59
+ export declare function ffiMultiGrep(handle: NativeHandle, patternsJoined: string, constraints: string, maxFileSize: number, maxMatchesPerFile: number, smartCase: boolean, fileOffset: number, pageLimit: number, timeBudgetMs: number, enforceTimeBudget: boolean, beforeContext: number, afterContext: number, classifyDefinitions: boolean): Result<GrepResult>;
60
60
  /**
61
61
  * Trigger file scan.
62
62
  */
package/dist/ffi.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ffi.d.ts","sourceRoot":"","sources":["../src/ffi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ffi.d.ts","sourceRoot":"","sources":["../src/ffi.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"finder.d.ts","sourceRoot":"","sources":["../src/finder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"finder.d.ts","sourceRoot":"","sources":["../src/finder.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -150,9 +150,9 @@ function findBinary() {
150
150
  const devPath = getDevBinaryPath();
151
151
  if (devPath)
152
152
  return devPath;
153
- const npmPath2 = resolveFromNpmPackage();
154
- if (npmPath2)
155
- return npmPath2;
153
+ const npmPath = resolveFromNpmPackage();
154
+ if (npmPath)
155
+ return npmPath;
156
156
  return null;
157
157
  }
158
158
  const npmPath = resolveFromNpmPackage();
@@ -295,7 +295,7 @@ var ffiDefinition = {
295
295
  ],
296
296
  returns: FFIType.ptr
297
297
  },
298
- fff_live_grep: {
298
+ fff_live_grep_ex: {
299
299
  args: [
300
300
  FFIType.ptr,
301
301
  FFIType.cstring,
@@ -306,13 +306,14 @@ var ffiDefinition = {
306
306
  FFIType.u32,
307
307
  FFIType.u32,
308
308
  FFIType.u64,
309
+ FFIType.bool,
309
310
  FFIType.u32,
310
311
  FFIType.u32,
311
312
  FFIType.bool
312
313
  ],
313
314
  returns: FFIType.ptr
314
315
  },
315
- fff_multi_grep: {
316
+ fff_multi_grep_ex: {
316
317
  args: [
317
318
  FFIType.ptr,
318
319
  FFIType.cstring,
@@ -323,6 +324,7 @@ var ffiDefinition = {
323
324
  FFIType.u32,
324
325
  FFIType.u32,
325
326
  FFIType.u64,
327
+ FFIType.bool,
326
328
  FFIType.u32,
327
329
  FFIType.u32,
328
330
  FFIType.bool
@@ -1061,14 +1063,14 @@ function ffiSearchMixed(handle, query, currentFile, maxThreads, pageIndex, pageS
1061
1063
  const resultPtr = library.symbols.fff_search_mixed(handle, ptr(encodeString(query)), ptr(encodeString(currentFile)), maxThreads, pageIndex, pageSize, comboBoostMultiplier, minComboCount);
1062
1064
  return parseMixedSearchResult(resultPtr);
1063
1065
  }
1064
- function ffiLiveGrep(handle, query, mode, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
1066
+ function ffiLiveGrep(handle, query, mode, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, enforceTimeBudget, beforeContext, afterContext, classifyDefinitions) {
1065
1067
  const library = loadLibrary();
1066
- const resultPtr = library.symbols.fff_live_grep(handle, ptr(encodeString(query)), grepModeToU8(mode), BigInt(maxFileSize), maxMatchesPerFile, smartCase, fileOffset, pageLimit, BigInt(timeBudgetMs), beforeContext, afterContext, classifyDefinitions);
1068
+ const resultPtr = library.symbols.fff_live_grep_ex(handle, ptr(encodeString(query)), grepModeToU8(mode), BigInt(maxFileSize), maxMatchesPerFile, smartCase, fileOffset, pageLimit, BigInt(timeBudgetMs), enforceTimeBudget, beforeContext, afterContext, classifyDefinitions);
1067
1069
  return parseGrepResult(resultPtr);
1068
1070
  }
1069
- function ffiMultiGrep(handle, patternsJoined, constraints, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, beforeContext, afterContext, classifyDefinitions) {
1071
+ function ffiMultiGrep(handle, patternsJoined, constraints, maxFileSize, maxMatchesPerFile, smartCase, fileOffset, pageLimit, timeBudgetMs, enforceTimeBudget, beforeContext, afterContext, classifyDefinitions) {
1070
1072
  const library = loadLibrary();
1071
- const resultPtr = library.symbols.fff_multi_grep(handle, ptr(encodeString(patternsJoined)), ptr(encodeString(constraints)), BigInt(maxFileSize), maxMatchesPerFile, smartCase, fileOffset, pageLimit, BigInt(timeBudgetMs), beforeContext, afterContext, classifyDefinitions);
1073
+ const resultPtr = library.symbols.fff_multi_grep_ex(handle, ptr(encodeString(patternsJoined)), ptr(encodeString(constraints)), BigInt(maxFileSize), maxMatchesPerFile, smartCase, fileOffset, pageLimit, BigInt(timeBudgetMs), enforceTimeBudget, beforeContext, afterContext, classifyDefinitions);
1072
1074
  return parseGrepResult(resultPtr);
1073
1075
  }
1074
1076
  function ffiScanFiles(handle) {
@@ -1268,7 +1270,7 @@ class FileFinder {
1268
1270
  const guard = this.ensureAlive();
1269
1271
  if (!guard.ok)
1270
1272
  return guard;
1271
- return ffiLiveGrep(guard.value, query, options?.mode ?? "plain", options?.maxFileSize ?? 0, options?.maxMatchesPerFile ?? 0, options?.smartCase ?? true, options?.cursor?._offset ?? 0, options?.pageSize ?? 0, options?.timeBudgetMs ?? 0, options?.beforeContext ?? 0, options?.afterContext ?? 0, options?.classifyDefinitions ?? false);
1273
+ return ffiLiveGrep(guard.value, query, options?.mode ?? "plain", options?.maxFileSize ?? 0, options?.maxMatchesPerFile ?? 0, options?.smartCase ?? true, options?.cursor?._offset ?? 0, options?.pageSize ?? 0, options?.timeBudgetMs ?? 0, options?.enforceTimeBudget ?? false, options?.beforeContext ?? 0, options?.afterContext ?? 0, options?.classifyDefinitions ?? false);
1272
1274
  }
1273
1275
  multiGrep(options) {
1274
1276
  const guard = this.ensureAlive();
@@ -1278,7 +1280,7 @@ class FileFinder {
1278
1280
  return err("patterns array must have at least 1 element");
1279
1281
  }
1280
1282
  return ffiMultiGrep(guard.value, options.patterns.join(`
1281
- `), options.constraints ?? "", options.maxFileSize ?? 0, options.maxMatchesPerFile ?? 0, options.smartCase ?? true, options.cursor?._offset ?? 0, options.pageSize ?? 0, options.timeBudgetMs ?? 0, options.beforeContext ?? 0, options.afterContext ?? 0, options.classifyDefinitions ?? false);
1283
+ `), options.constraints ?? "", options.maxFileSize ?? 0, options.maxMatchesPerFile ?? 0, options.smartCase ?? true, options.cursor?._offset ?? 0, options.pageSize ?? 0, options.timeBudgetMs ?? 0, options.enforceTimeBudget ?? false, options.beforeContext ?? 0, options.afterContext ?? 0, options.classifyDefinitions ?? false);
1282
1284
  }
1283
1285
  scanFiles() {
1284
1286
  const guard = this.ensureAlive();
@@ -1437,4 +1439,4 @@ export {
1437
1439
  getTriple
1438
1440
  };
1439
1441
 
1440
- //# debugId=043EF0566D90D1E064756E2164756E21
1442
+ //# debugId=D4151B7C94AD421364756E2164756E21
package/dist/index.js.map CHANGED
@@ -4,12 +4,12 @@
4
4
  "sourcesContent": [
5
5
  "/**\n * Binary resolution utilities for fff\n *\n * Resolves the native library from:\n * 1. Platform-specific npm package (e.g. @ff-labs/fff-bin-darwin-arm64)\n * 2. Local dev build (target/release or target/debug)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getLibFilename, getNpmPackageName } from \"./platform\";\n\n/**\n * Get the current file's directory\n */\nfunction getCurrentDir(): string {\n const url = import.meta.url;\n\n // When running in a compiled Bun binary, import.meta.url points to the virtual\n // $bunfs filesystem. Use process.execPath to get the real filesystem location.\n if (url.includes(\"$bunfs\")) {\n return dirname(process.execPath);\n }\n\n if (url.startsWith(\"file://\")) {\n return dirname(fileURLToPath(url));\n }\n return dirname(url);\n}\n\n/**\n * Get the package root directory\n */\nfunction getPackageDir(): string {\n const currentDir = getCurrentDir();\n return dirname(currentDir);\n}\n\n/**\n * Check if the binary exists in any known location\n */\nexport function binaryExists(): boolean {\n return findBinary() !== null;\n}\n\n/**\n * Try to resolve the binary from the platform-specific npm package.\n *\n * When users install @ff-labs/fff-bun, npm/bun automatically installs the matching\n * optionalDependency (e.g. @ff-labs/fff-bin-darwin-arm64). We resolve the binary\n * path by requiring that package's package.json and looking for the binary\n * in the same directory.\n */\nfunction resolveFromNpmPackage(): string | null {\n const packageName = getNpmPackageName();\n\n try {\n // Use createRequire to resolve the platform package's location\n const require = createRequire(join(getPackageDir(), \"package.json\"));\n const packageJsonPath = require.resolve(`${packageName}/package.json`);\n const packageDir = dirname(packageJsonPath);\n const binaryPath = join(packageDir, getLibFilename());\n\n if (existsSync(binaryPath)) {\n return binaryPath;\n }\n } catch {\n // Package not installed - this is expected on unsupported platforms\n // or when installed without optional dependencies\n }\n\n return null;\n}\n\n/**\n * Get the development binary path (for local development)\n */\nfunction getDevBinaryPath(): string | null {\n const packageDir = getPackageDir();\n const workspaceRoot = join(packageDir, \"..\", \"..\");\n\n const possiblePaths = [\n join(workspaceRoot, \"target\", \"release\", getLibFilename()),\n join(workspaceRoot, \"target\", \"debug\", getLibFilename()),\n ];\n\n for (const path of possiblePaths) {\n if (existsSync(path)) {\n return path;\n }\n }\n\n return null;\n}\n\nfunction isDevWorkspace(): boolean {\n const packageDir = getPackageDir();\n const workspaceRoot = join(packageDir, \"..\", \"..\");\n return existsSync(join(workspaceRoot, \"Cargo.toml\"));\n}\n\n/**\n * Find the native library binary.\n *\n * Resolution order:\n * - Dev workspace: local dev build first, then npm package\n * - Production: npm package first, then dev build\n *\n * @returns Absolute path to the library, or null if not found\n */\nexport function findBinary(): string | null {\n if (isDevWorkspace()) {\n // 1. Local bin/ directory (populated by `make prepare-bun`)\n const binPath = join(getPackageDir(), \"bin\", getLibFilename());\n if (existsSync(binPath)) return binPath;\n\n // 2. Local dev build (target/release or target/debug)\n const devPath = getDevBinaryPath();\n if (devPath) return devPath;\n\n // 3. Fallback to npm package\n const npmPath = resolveFromNpmPackage();\n if (npmPath) return npmPath;\n\n return null;\n }\n\n // Production: npm package first\n const npmPath = resolveFromNpmPackage();\n if (npmPath) return npmPath;\n\n // Fallback: local dev build (e.g. user built from source)\n return getDevBinaryPath();\n}\n",
6
6
  "/**\n * Platform detection utilities for downloading the correct binary\n */\n\nimport { execSync } from \"node:child_process\";\n\n/**\n * Get the platform triple (e.g., \"x86_64-unknown-linux-gnu\")\n */\nexport function getTriple(): string {\n const platform = process.platform;\n const arch = process.arch;\n\n let osName: string;\n if (platform === \"darwin\") {\n osName = \"apple-darwin\";\n } else if (platform === \"android\") {\n osName = \"linux-android\";\n } else if (platform === \"linux\") {\n osName = detectLinuxLibc();\n } else if (platform === \"win32\") {\n osName = \"pc-windows-msvc\";\n } else {\n throw new Error(`Unsupported platform: ${platform}`);\n }\n\n const archName = normalizeArch(arch);\n return `${archName}-${osName}`;\n}\n\n/**\n * Detect whether we're on musl or glibc Linux\n */\nfunction detectLinuxLibc(): string {\n let output = \"\";\n try {\n output = execSync(\"ldd --version 2>&1\", {\n encoding: \"utf-8\",\n timeout: 5000,\n });\n } catch (e: unknown) {\n // Alpine/musl: `ldd --version` exits with code 1 but still prints\n // \"musl libc ...\" — execSync surfaces that on the error object.\n const err = e as { stdout?: string | Buffer; stderr?: string | Buffer };\n output = String(err?.stdout ?? \"\") + String(err?.stderr ?? \"\");\n }\n if (output.toLowerCase().includes(\"musl\")) {\n return \"unknown-linux-musl\";\n }\n return \"unknown-linux-gnu\";\n}\n\n/**\n * Normalize architecture name to Rust target format\n */\nfunction normalizeArch(arch: string): string {\n switch (arch) {\n case \"x64\":\n case \"amd64\":\n return \"x86_64\";\n case \"arm64\":\n return \"aarch64\";\n case \"arm\":\n return \"arm\";\n default:\n throw new Error(`Unsupported architecture: ${arch}`);\n }\n}\n\n/**\n * Get the library file extension for the current platform\n */\nexport function getLibExtension(): \"dylib\" | \"so\" | \"dll\" {\n switch (process.platform) {\n case \"darwin\":\n return \"dylib\";\n case \"win32\":\n return \"dll\";\n default:\n return \"so\";\n }\n}\n\n/**\n * Get the library filename prefix (empty on Windows)\n */\nexport function getLibPrefix(): string {\n return process.platform === \"win32\" ? \"\" : \"lib\";\n}\n\n/**\n * Get the full library filename for the current platform\n */\nexport function getLibFilename(): string {\n const prefix = getLibPrefix();\n const ext = getLibExtension();\n return `${prefix}fff_c.${ext}`;\n}\n\n/**\n * Map from Rust target triple to npm platform package name\n */\nconst TRIPLE_TO_NPM_PACKAGE: Record<string, string> = {\n \"aarch64-apple-darwin\": \"@ff-labs/fff-bin-darwin-arm64\",\n \"x86_64-apple-darwin\": \"@ff-labs/fff-bin-darwin-x64\",\n \"x86_64-unknown-linux-gnu\": \"@ff-labs/fff-bin-linux-x64-gnu\",\n \"aarch64-unknown-linux-gnu\": \"@ff-labs/fff-bin-linux-arm64-gnu\",\n \"x86_64-unknown-linux-musl\": \"@ff-labs/fff-bin-linux-x64-musl\",\n \"aarch64-unknown-linux-musl\": \"@ff-labs/fff-bin-linux-arm64-musl\",\n \"x86_64-pc-windows-msvc\": \"@ff-labs/fff-bin-win32-x64\",\n \"aarch64-pc-windows-msvc\": \"@ff-labs/fff-bin-win32-arm64\",\n \"aarch64-linux-android\": \"@ff-labs/fff-bin-android-arm64\",\n};\n\n/**\n * Get the npm package name for the current platform's native binary.\n *\n * @returns Package name like \"@ff-labs/fff-bin-darwin-arm64\"\n * @throws If the current platform is not supported\n */\nexport function getNpmPackageName(): string {\n const triple = getTriple();\n const packageName = TRIPLE_TO_NPM_PACKAGE[triple];\n if (!packageName) {\n throw new Error(`No npm package available for platform: ${triple}`);\n }\n return packageName;\n}\n",
7
- "/**\n * FileFinder - High-level API for the fff file finder\n *\n * This class provides a type-safe, ergonomic API for file finding operations.\n * Each instance owns an independent native file picker that can be created\n * and destroyed independently. Multiple instances can coexist.\n *\n * All methods return Result types for explicit error handling.\n */\n\nimport { FFIType, JSCallback, type Pointer } from \"bun:ffi\";\n\nimport {\n ensureLoaded,\n ffiCreate,\n ffiDestroy,\n ffiGetBasePath,\n ffiGetHistoricalQuery,\n ffiGetScanProgress,\n ffiGlob,\n ffiHealthCheck,\n ffiIsScanning,\n ffiLiveGrep,\n ffiMultiGrep,\n ffiRefreshGitStatus,\n ffiRestartIndex,\n ffiScanFiles,\n ffiSearch,\n ffiSearchDirectories,\n ffiSearchMixed,\n ffiSetWatchCallback,\n ffiTrackQuery,\n ffiUnwatch,\n ffiWaitForScan,\n ffiWatch,\n isAvailable,\n type NativeHandle,\n readWatchEventBatch,\n} from \"./ffi\";\n\nimport type {\n DirSearchOptions,\n DirSearchResult,\n InitOptions as FFFInitOptions,\n FileFinderApi,\n GlobOptions,\n GrepOptions,\n GrepResult,\n HealthCheck,\n MixedSearchResult,\n MultiGrepOptions,\n Result,\n ScanProgress,\n SearchOptions,\n SearchResult,\n WatchBatchCallback,\n WatchOptions,\n WatchUnsubscribe,\n} from \"./fff-api\";\n\nimport { err } from \"./fff-api\";\n\n/**\n * FileFinder - Fast file finder with fuzzy search\n *\n * Each instance is backed by an independent native file picker. Create as many\n * as you need and destroy them when done.\n *\n * @example\n * ```typescript\n * import { FileFinder } from \"fff\";\n *\n * // Create an instance\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n * if (!finder.ok) {\n * console.error(finder.error);\n * process.exit(1);\n * }\n *\n * // Wait for initial scan\n * await finder.value.waitForScan(5000);\n *\n * // Search for files\n * const search = finder.value.search(\"main.ts\");\n * if (search.ok) {\n * for (const item of search.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n *\n * // Cleanup\n * finder.value.destroy();\n * ```\n */\nexport class FileFinder implements FileFinderApi {\n private handle: NativeHandle | null;\n /** Active watch subscriptions: native watch id -> JS batch handler. */\n private watchHandlers = new Map<number, WatchBatchCallback>();\n /**\n * ONE threadsafe JSCallback per instance, registered lazily with\n * `fff_set_watch_callback` on the first subscription and closed in\n * `destroy()` after `fff_destroy` returns (the quiescence barrier).\n */\n private watchJsCallback: JSCallback | null = null;\n\n private constructor(handle: NativeHandle) {\n this.handle = handle;\n }\n\n /**\n * Create a new file finder instance.\n *\n * @param options - Initialization options\n * @returns Result containing the new FileFinder instance or an error\n *\n * @example\n * ```typescript\n * // Basic initialization\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n *\n * // With custom database paths\n * const finder = FileFinder.create({\n * basePath: \"/path/to/project\",\n * frecencyDbPath: \"/custom/frecency.mdb\",\n * historyDbPath: \"/custom/history.mdb\",\n * });\n * ```\n */\n static create(options: FFFInitOptions): Result<FileFinder> {\n const result = ffiCreate(\n options.basePath,\n options.frecencyDbPath ?? \"\",\n options.historyDbPath ?? \"\",\n options.useUnsafeNoLock ?? false,\n !(options.disableMmapCache ?? false),\n !(options.disableContentIndexing ?? options.disableMmapCache ?? false),\n !(options.disableWatch ?? false),\n options.aiMode ?? false,\n options.logFilePath ?? \"\",\n options.logLevel ?? \"\",\n BigInt(options.cacheBudgetMaxFiles ?? 0),\n BigInt(options.cacheBudgetMaxBytes ?? 0),\n BigInt(options.cacheBudgetMaxFileSize ?? 0),\n options.enableFsRootScanning ?? false,\n options.enableHomeDirScanning ?? false,\n );\n\n if (!result.ok) {\n return result;\n }\n\n return { ok: true, value: new FileFinder(result.value) };\n }\n\n /**\n * Destroy and clean up all resources.\n *\n * Frees the native instance (unsubscribing all watches), then closes the\n * instance watch trampoline. After calling this, the instance must not be\n * used again.\n */\n destroy(): void {\n if (this.handle !== null) {\n this.watchHandlers.clear();\n ffiDestroy(this.handle);\n this.handle = null;\n // Handlers were cleared first, so a delivery racing the destroy is a\n // benign id-map miss before the trampoline is closed.\n this.watchJsCallback?.close();\n this.watchJsCallback = null;\n }\n }\n\n /**\n * Check if this instance has been destroyed.\n */\n get isDestroyed(): boolean {\n return this.handle === null;\n }\n\n /**\n * Guard that returns an error if the instance has been destroyed.\n */\n private ensureAlive(): Result<NativeHandle> {\n if (this.handle === null) {\n return err(\"FileFinder instance has been destroyed.\");\n }\n return { ok: true, value: this.handle };\n }\n\n /**\n * Search for files matching the query.\n *\n * The query supports fuzzy matching and special syntax:\n * - `foo bar` - Match files containing \"foo\" and \"bar\"\n * - `src/` - Match files in src directory\n * - `file.ts:42` - Match file.ts with line 42\n * - `file.ts:42:10` - Match file.ts with line 42, column 10\n *\n * @param query - Search query string\n * @param options - Search options\n * @returns Search results with matched files and scores\n *\n * @example\n * ```typescript\n * const result = finder.search(\"main.ts\", { pageSize: 10 });\n * if (result.ok) {\n * console.log(`Found ${result.value.totalMatched} files`);\n * for (const item of result.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n * ```\n */\n fileSearch(query: string, options?: SearchOptions): Result<SearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearch(\n guard.value,\n query,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n options?.comboBoostMultiplier ?? 0,\n options?.minComboCount ?? 0,\n );\n }\n\n /**\n * Glob-only search.\n *\n * The pattern is applied as a single pass SIMD optimized prefiltering\n * without any fuzzy matching involved. Faster and 100% compatible to npm `glob`.\n *\n * @param pattern - Glob pattern (required, non-empty)\n * @param options - Glob search options (pagination, max threads, current file)\n * @returns Search results with files matching the glob\n */\n glob(pattern: string, options?: GlobOptions): Result<SearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiGlob(\n guard.value,\n pattern,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n );\n }\n\n /**\n * Search for directories matching the query.\n *\n * @param query - Search query string\n * @param options - Directory search options\n * @returns Search results with matched directories and scores\n *\n * @example\n * ```typescript\n * const result = finder.directorySearch(\"components\", { pageSize: 10 });\n * if (result.ok) {\n * console.log(`Found ${result.value.totalMatched} directories`);\n * for (const item of result.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n * ```\n */\n directorySearch(query: string, options?: DirSearchOptions): Result<DirSearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearchDirectories(\n guard.value,\n query,\n options?.currentFile ?? null,\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n );\n }\n\n /**\n * Search for files and directories together (mixed search).\n *\n * Results are interleaved by total score in descending order.\n *\n * @param query - Search query string\n * @param options - Search options\n * @returns Mixed search results with files and directories interleaved by score\n *\n * @example\n * ```typescript\n * const result = finder.mixedSearch(\"main\", { pageSize: 20 });\n * if (result.ok) {\n * for (const entry of result.value.items) {\n * if (entry.type === \"file\") {\n * console.log(`File: ${entry.item.relativePath}`);\n * } else {\n * console.log(`Dir: ${entry.item.relativePath}`);\n * }\n * }\n * }\n * ```\n */\n mixedSearch(query: string, options?: SearchOptions): Result<MixedSearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearchMixed(\n guard.value,\n query,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n options?.comboBoostMultiplier ?? 0,\n options?.minComboCount ?? 0,\n );\n }\n\n /**\n * Search file contents (live grep).\n *\n * Searches through the contents of indexed files using the specified mode:\n * - `\"plain\"` (default): SIMD-accelerated literal text matching\n * - `\"regex\"`: Regular expression matching\n * - `\"fuzzy\"`: Smith-Waterman fuzzy matching per line\n *\n * Supports pagination for large result sets. The result includes a `nextCursor`\n * that can be passed back to fetch the next page.\n *\n * The query also supports constraint syntax:\n * - `*.ts pattern` - Only search in TypeScript files\n * - `src/ pattern` - Only search in the src directory\n *\n * @param query - Search query string\n * @param options - Grep options (mode, pagination, limits)\n * @returns Grep results with matched lines and file metadata\n *\n * @example\n * ```typescript\n * // First page\n * const result = finder.grep(\"TODO\", { mode: \"plain\" });\n * if (result.ok) {\n * for (const match of result.value.items) {\n * console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);\n * }\n * // Fetch next page\n * if (result.value.nextCursor) {\n * const page2 = finder.grep(\"TODO\", {\n * cursor: result.value.nextCursor,\n * });\n * }\n * }\n * ```\n */\n grep(query: string, options?: GrepOptions): Result<GrepResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiLiveGrep(\n guard.value,\n query,\n options?.mode ?? \"plain\",\n options?.maxFileSize ?? 0,\n options?.maxMatchesPerFile ?? 0,\n options?.smartCase ?? true,\n options?.cursor?._offset ?? 0,\n options?.pageSize ?? 0,\n options?.timeBudgetMs ?? 0,\n options?.beforeContext ?? 0,\n options?.afterContext ?? 0,\n options?.classifyDefinitions ?? false,\n );\n }\n\n /**\n * Multi-pattern OR search using Aho-Corasick.\n *\n * Searches for lines matching ANY of the provided patterns using\n * SIMD-accelerated multi-needle matching. Faster than regex alternation\n * for literal text searches.\n *\n * Supports pagination. The result includes a `nextCursor` that can be\n * passed back to fetch the next page.\n *\n * @param options - Multi-grep options including patterns and optional constraints\n * @returns Grep results with matched lines and file metadata\n *\n * @example\n * ```typescript\n * const result = finder.multiGrep({\n * patterns: [\"VideoFrame\", \"video_frame\", \"PreloadedImage\"],\n * });\n * if (result.ok) {\n * for (const match of result.value.items) {\n * console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);\n * }\n * }\n * ```\n */\n multiGrep(options: MultiGrepOptions): Result<GrepResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n if (!options.patterns || options.patterns.length === 0) {\n return err(\"patterns array must have at least 1 element\");\n }\n\n return ffiMultiGrep(\n guard.value,\n options.patterns.join(\"\\n\"),\n options.constraints ?? \"\",\n options.maxFileSize ?? 0,\n options.maxMatchesPerFile ?? 0,\n options.smartCase ?? true,\n options.cursor?._offset ?? 0,\n options.pageSize ?? 0,\n options.timeBudgetMs ?? 0,\n options.beforeContext ?? 0,\n options.afterContext ?? 0,\n options.classifyDefinitions ?? false,\n );\n }\n\n /**\n * Trigger a rescan of the indexed directory.\n *\n * This is useful after major file system changes that the\n * background watcher might have missed.\n */\n scanFiles(): Result<void> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiScanFiles(guard.value);\n }\n\n /**\n * Check if a scan is currently in progress.\n */\n isScanning(): boolean {\n if (this.handle === null) return false;\n return ffiIsScanning(this.handle);\n }\n\n /**\n * Get the base path of the file picker (the root directory being indexed).\n */\n getBasePath(): Result<string | null> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetBasePath(guard.value);\n }\n\n /**\n * Get the current scan progress.\n */\n getScanProgress(): Result<ScanProgress> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetScanProgress(guard.value) as Result<ScanProgress>;\n }\n\n /**\n * Wait for the initial file scan to complete.\n *\n * Non-blocking: polls `isScanning` and yields to the event loop between\n * checks, so other async work keeps running while waiting.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if scan completed, false if timed out\n *\n * @example\n * ```typescript\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n * if (finder.ok) {\n * const completed = await finder.value.waitForScan(10000);\n * if (!completed.ok || !completed.value) {\n * console.warn(\"Scan did not complete in time\");\n * }\n * }\n * ```\n */\n async waitForScan(timeoutMs: number = 5000): Promise<Result<boolean>> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const deadline = Date.now() + timeoutMs;\n while (this.isScanning()) {\n if (Date.now() >= deadline) {\n return { ok: true, value: false };\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n return { ok: true, value: true };\n }\n\n /**\n * Wait for the initial file scan to complete, blocking the calling thread.\n *\n * Backed by the native `fff_wait_for_scan` call. Prefer {@link waitForScan}\n * unless you specifically need synchronous blocking behaviour.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if scan completed, false if timed out\n */\n waitForScanBlocking(timeoutMs: number = 5000): Result<boolean> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiWaitForScan(guard.value, timeoutMs);\n }\n\n /**\n * Wait until the index is fully ready: the scan has finished and the warmup\n * (content indexing / bigram) phase has completed.\n *\n * Non-blocking — polls `getScanProgress` and yields to the event loop.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if the index became ready, false if timed out\n */\n async waitForIndexReady(timeoutMs: number = 5000): Promise<Result<boolean>> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const deadline = Date.now() + timeoutMs;\n while (true) {\n const progress = this.getScanProgress();\n if (!progress.ok) return progress;\n if (!progress.value.isScanning && progress.value.isWarmupComplete) {\n return { ok: true, value: true };\n }\n if (Date.now() >= deadline) {\n return { ok: true, value: false };\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n }\n\n /**\n * Change the indexed directory to a new path.\n *\n * This stops the current file watcher and starts indexing the new directory.\n *\n * @param newPath - New directory path to index\n */\n reindex(newPath: string): Result<void> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiRestartIndex(guard.value, newPath);\n }\n\n /**\n * Refresh the git status cache.\n *\n * @returns Number of files with updated git status\n */\n refreshGitStatus(): Result<number> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiRefreshGitStatus(guard.value);\n }\n\n /**\n * Track query completion for smart suggestions.\n *\n * Call this when a user selects a file from search results.\n * This helps improve future search rankings for similar queries.\n *\n * @param query - The search query that was used\n * @param selectedFilePath - The file path that was selected\n */\n trackQuery(query: string, selectedFilePath: string): Result<boolean> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiTrackQuery(guard.value, query, selectedFilePath);\n }\n\n /**\n * Get a historical query by offset.\n *\n * @param offset - Offset from most recent (0 = most recent)\n * @returns The historical query string, or null if not found\n */\n getHistoricalQuery(offset: number): Result<string | null> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetHistoricalQuery(guard.value, offset);\n }\n\n /**\n * Lazily create + register the instance-wide watch trampoline. Routes\n * every delivered batch to the handler registered for its watch id;\n * unknown ids (unsubscribe races) are benign — the batch is just freed.\n */\n private ensureWatchTrampoline(handle: NativeHandle): Result<void> {\n if (this.watchJsCallback !== null) return { ok: true, value: undefined };\n\n // Threadsafe: the native callback thread enqueues the invocation onto the\n // JS event loop; the batch stays valid because JS owns it until it frees\n // it inside readWatchEventBatch.\n const jsCallback = new JSCallback(\n (watchId: bigint | number, batchPtr: Pointer, _userData: Pointer) => {\n const events = readWatchEventBatch(batchPtr);\n const handler = this.watchHandlers.get(Number(watchId));\n if (handler !== undefined && events.length > 0) {\n handler(events);\n }\n },\n {\n // an attempt to fix the bug that is kept unfixed in the zig version of bun :()\n // https://github.com/oven-sh/bun/issues/33840:\n //\n // watch_id is declared `ptr`, not `u64`: ABI-identical (one 64-bit\n // register), but u64 args make bun allocate a JSBigInt on the CALLING\n // (non-JS) thread, corrupting the JS heap\n args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],\n returns: FFIType.void,\n threadsafe: true,\n },\n );\n\n const registered = ffiSetWatchCallback(handle, jsCallback);\n if (!registered.ok) {\n jsCallback.close();\n return registered;\n }\n this.watchJsCallback = jsCallback;\n return { ok: true, value: undefined };\n }\n\n /**\n * Subscribe to filesystem changes matching `pattern` (glob, exact file,\n * or directory subtree). Omit the pattern to watch the entire indexed\n * tree. Normalized batches of up to 128 events are delivered on the JS event\n * loop, with each path appearing at most once. See `FileFinderApi.watch`.\n *\n * @example\n * ```typescript\n * const sub = finder.watch(\"**\\/*.ts\", (events) => {\n * for (const e of events) console.log(e.kind, e.path);\n * });\n * if (sub.ok) sub.value(); // unsubscribe\n *\n * // no pattern: everything under the indexed base path\n * const all = finder.watch((events) => console.log(events.length));\n * ```\n */\n watch(callback: WatchBatchCallback, options?: WatchOptions): Result<WatchUnsubscribe>;\n watch(\n pattern: string,\n callback: WatchBatchCallback,\n options?: WatchOptions,\n ): Result<WatchUnsubscribe>;\n watch(\n patternOrCallback: string | WatchBatchCallback,\n callbackOrOptions?: WatchBatchCallback | WatchOptions,\n maybeOptions?: WatchOptions,\n ): Result<WatchUnsubscribe> {\n // Overload shift: watch(cb, opts?) -> empty pattern = whole tree.\n const noPattern = typeof patternOrCallback === \"function\";\n const pattern = noPattern ? \"\" : patternOrCallback;\n const callback = noPattern\n ? patternOrCallback\n : (callbackOrOptions as WatchBatchCallback);\n const options = noPattern\n ? (callbackOrOptions as WatchOptions | undefined)\n : maybeOptions;\n\n if (typeof callback !== \"function\") {\n return err(\"watch callback must be a function\");\n }\n\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const trampoline = this.ensureWatchTrampoline(guard.value);\n if (!trampoline.ok) return trampoline;\n\n const result = ffiWatch(guard.value, pattern, options?.ignore ?? []);\n if (!result.ok) return result;\n\n // No startup race: the threadsafe trampoline only runs on the JS event\n // loop, so this synchronous set always precedes the first routing lookup.\n const watchId = result.value;\n this.watchHandlers.set(watchId, callback);\n\n return { ok: true, value: () => this.unwatchById(watchId) };\n }\n\n /**\n * Remove a subscription from the routing map, then from the native side.\n * Map removal is synchronous on the JS thread, so once this returns the\n * handler can never run again (late native batches miss the lookup).\n * Idempotent.\n */\n private unwatchById(watchId: number): void {\n if (!this.watchHandlers.delete(watchId)) return;\n if (this.handle !== null) {\n ffiUnwatch(this.handle, watchId);\n }\n }\n\n /**\n * Get health check information.\n *\n * Useful for debugging and verifying the file finder is working correctly.\n *\n * @param testPath - Optional path to test git repository detection\n */\n healthCheck(testPath?: string): Result<HealthCheck> {\n return ffiHealthCheck(this.handle, testPath || \"\") as Result<HealthCheck>;\n }\n\n /**\n * Check if the native library is available.\n */\n static isAvailable(): boolean {\n return isAvailable();\n }\n\n /** Ensure the native library is loaded. */\n static ensureLoaded(): void {\n ensureLoaded();\n }\n\n /**\n * Get a health check without requiring an instance.\n *\n * Returns limited info (version + git only, no picker/frecency/query data).\n *\n * @param testPath - Optional path to test git repository detection\n */\n static healthCheckStatic(testPath?: string): Result<HealthCheck> {\n return ffiHealthCheck(null, testPath || \"\") as Result<HealthCheck>;\n }\n}\n",
8
- "/**\n * Bun FFI bindings for the fff-c native library\n *\n * This module uses Bun's native FFI to call into the Rust C library.\n * All functions follow the Result pattern for error handling.\n *\n * The API is instance-based: `ffiCreate` returns an opaque handle that must\n * be passed to all subsequent calls and freed with `ffiDestroy`.\n */\n\nimport {\n CString,\n dlopen,\n FFIType,\n type JSCallback,\n type Pointer,\n ptr,\n read,\n} from \"bun:ffi\";\nimport { findBinary } from \"./download\";\nimport { embeddedLibPath } from \"./embedded\";\nimport type {\n DirItem,\n DirSearchResult,\n FileItem,\n GrepMatch,\n GrepResult,\n Location,\n MixedItem,\n MixedSearchResult,\n Result,\n ScanProgress,\n Score,\n SearchResult,\n WatchEvent,\n WatchEventKind,\n} from \"./fff-api\";\nimport { createGrepCursor, err } from \"./fff-api\";\n\n/** Grep mode constants matching the C API (u8). */\nconst GREP_MODE_PLAIN = 0;\nconst GREP_MODE_REGEX = 1;\nconst GREP_MODE_FUZZY = 2;\n\n/** Map string mode to u8 */\nfunction grepModeToU8(mode?: string): number {\n switch (mode) {\n case \"regex\":\n return GREP_MODE_REGEX;\n case \"fuzzy\":\n return GREP_MODE_FUZZY;\n default:\n return GREP_MODE_PLAIN;\n }\n}\n\nconst ffiDefinition = {\n fff_create_instance2: {\n args: [\n FFIType.cstring, // base_path\n FFIType.cstring, // frecency_db_path\n FFIType.cstring, // history_db_path\n FFIType.bool, // use_unsafe_no_lock\n FFIType.bool, // enable_mmap_cache\n FFIType.bool, // enable_content_indexing\n FFIType.bool, // watch\n FFIType.bool, // ai_mode\n FFIType.cstring, // log_file_path\n FFIType.cstring, // log_level\n FFIType.u64, // cache_budget_max_files\n FFIType.u64, // cache_budget_max_bytes\n FFIType.u64, // cache_budget_max_file_size\n ],\n returns: FFIType.ptr,\n },\n fff_create_instance_with: {\n args: [FFIType.ptr], // *const FffCreateOptions\n returns: FFIType.ptr,\n },\n fff_destroy: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n\n // Search\n fff_search: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n FFIType.i32, // combo_boost_multiplier\n FFIType.u32, // min_combo_count\n ],\n returns: FFIType.ptr,\n },\n\n // Glob-only search (bypasses query parser)\n fff_glob: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // pattern\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n ],\n returns: FFIType.ptr,\n },\n\n // Directory search\n fff_search_directories: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n ],\n returns: FFIType.ptr,\n },\n\n // Mixed search (files + directories)\n fff_search_mixed: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n FFIType.i32, // combo_boost_multiplier\n FFIType.u32, // min_combo_count\n ],\n returns: FFIType.ptr,\n },\n\n // Live grep (content search)\n fff_live_grep: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.u8, // mode\n FFIType.u64, // max_file_size\n FFIType.u32, // max_matches_per_file\n FFIType.bool, // smart_case\n FFIType.u32, // file_offset\n FFIType.u32, // page_limit\n FFIType.u64, // time_budget_ms\n FFIType.u32, // before_context\n FFIType.u32, // after_context\n FFIType.bool, // classify_definitions\n ],\n returns: FFIType.ptr,\n },\n\n // Multi-pattern grep (Aho-Corasick)\n fff_multi_grep: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // patterns_joined (\\n-separated)\n FFIType.cstring, // constraints\n FFIType.u64, // max_file_size\n FFIType.u32, // max_matches_per_file\n FFIType.bool, // smart_case\n FFIType.u32, // file_offset\n FFIType.u32, // page_limit\n FFIType.u64, // time_budget_ms\n FFIType.u32, // before_context\n FFIType.u32, // after_context\n FFIType.bool, // classify_definitions\n ],\n returns: FFIType.ptr,\n },\n\n // File index\n fff_scan_files: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_is_scanning: {\n args: [FFIType.ptr],\n returns: FFIType.bool,\n },\n fff_get_base_path: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_get_scan_progress: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_wait_for_scan: {\n args: [FFIType.ptr, FFIType.u64],\n returns: FFIType.ptr,\n },\n fff_restart_index: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n\n // Watch subscriptions\n fff_set_watch_callback: {\n args: [\n FFIType.ptr, // handle\n FFIType.function, // FffWatchCallback (instance-wide)\n FFIType.ptr, // user_data\n ],\n returns: FFIType.ptr,\n },\n fff_watch: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // pattern\n FFIType.ptr, // *const FffWatchOptions (or NULL)\n ],\n returns: FFIType.ptr,\n },\n fff_unwatch: {\n args: [FFIType.ptr, FFIType.u64], // handle, watch_id\n returns: FFIType.ptr,\n },\n fff_free_watch_events: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_watch_events_count: {\n args: [FFIType.ptr],\n returns: FFIType.u32,\n },\n fff_watch_events_get_path: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_watch_events_get_kind: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.u8,\n },\n\n // Git\n fff_refresh_git_status: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n\n // Query tracking\n fff_track_query: {\n args: [FFIType.ptr, FFIType.cstring, FFIType.cstring],\n returns: FFIType.ptr,\n },\n fff_get_historical_query: {\n args: [FFIType.ptr, FFIType.u64],\n returns: FFIType.ptr,\n },\n\n // Utilities\n fff_health_check: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n\n // Search result accessors / free\n fff_free_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Dir search result accessors / free\n fff_free_dir_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_dir_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_dir_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Mixed search result accessors / free\n fff_free_mixed_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_mixed_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_mixed_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Grep result accessors / free\n fff_free_grep_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_grep_result_get_match: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Memory management\n fff_free_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_free_string: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_free_scan_progress: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n} as const;\n\ntype FFFLibrary = ReturnType<typeof dlopen<typeof ffiDefinition>>;\n\nlet lib: FFFLibrary | null = null;\n\n/**\n * Load the native library\n */\nfunction loadLibrary(): FFFLibrary {\n if (lib) return lib;\n\n const isEmbedded = embeddedLibPath?.includes(\"$bunfs\") ?? false;\n const binaryPath = isEmbedded ? embeddedLibPath : (findBinary() ?? embeddedLibPath);\n if (!binaryPath) {\n throw new Error(libNotFoundMessage());\n }\n\n lib = dlopen(binaryPath, ffiDefinition);\n return lib;\n}\n\nfunction libNotFoundMessage(): string {\n if (import.meta.url.includes(\"$bunfs\")) {\n if (process.platform === \"linux\") {\n return [\n \"You are running bun --compile with fff native library which CAN NOT resolve a binary\",\n \"On Linux the libc must be supplied at compile time so the native lib is bundled.\",\n \"Rebuild with:\",\n \" bun build --compile --define FFF_LIBC='\\\"gnu\\\"' ... # glibc\",\n \" bun build --compile --define FFF_LIBC='\\\"musl\\\"' ... # musl / Alpine\",\n ].join(\"\\n\");\n }\n\n return \"fff native library was not embedded into this executable. Rebuild with `bun build --compile` and ensure the @ff-labs/fff-bin-* package for this platform is installed.\";\n }\n\n return \"fff native library not found. Build from source with `cargo build --release -p fff-c` or install the platform package.\";\n}\n\n/**\n * Encode a string for FFI (null-terminated)\n */\nfunction encodeString(s: string): Uint8Array {\n return new TextEncoder().encode(`${s}\\0`);\n}\n\n/**\n * Read a C string from a pointer\n * Note: read.ptr() returns number but CString expects Pointer - we cast through unknown\n */\nfunction readCString(pointer: Pointer | number | null): string | null {\n if (pointer === null || pointer === 0) return null;\n // CString constructor accepts Pointer, but read.ptr returns number\n // Cast through unknown for runtime compatibility\n return new CString(pointer as unknown as Pointer).toString();\n}\n\n/**\n * Convert snake_case keys to camelCase recursively\n */\nfunction snakeToCamel(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(snakeToCamel);\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n result[camelKey] = snakeToCamel(value);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// FffResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { success: bool(1+7pad), error: *char(8), handle: *void(8), int_value: i64(8) }\n// ---------------------------------------------------------------------------\nconst RES_SUCCESS = 0; // bool (1 + 7 padding)\nconst RES_ERROR = 8; // *mut c_char (8)\nconst RES_HANDLE = 16; // *mut c_void (8)\nconst RES_INT_VALUE = 24; // i64 (8)\n\n// MUST match `crates/fff-c/src/ffi_types.rs::FffCreateOptions`\nconst FFF_CREATE_OPTIONS_VERSION = 1;\nconst FFF_CREATE_OPTIONS_SIZE = 88;\nconst FCO_VERSION = 0;\nconst FCO_BASE_PATH = 8;\nconst FCO_FRECENCY_DB_PATH = 16;\nconst FCO_HISTORY_DB_PATH = 24;\nconst FCO_ENABLE_MMAP_CACHE = 32;\nconst FCO_ENABLE_CONTENT_INDEXING = 33;\nconst FCO_WATCH = 34;\nconst FCO_AI_MODE = 35;\nconst FCO_LOG_FILE_PATH = 40;\nconst FCO_LOG_LEVEL = 48;\nconst FCO_CACHE_BUDGET_MAX_FILES = 56;\nconst FCO_CACHE_BUDGET_MAX_BYTES = 64;\nconst FCO_CACHE_BUDGET_MAX_FILE_SIZE = 72;\nconst FCO_ENABLE_FS_ROOT_SCANNING = 80;\nconst FCO_ENABLE_HOME_DIR_SCANNING = 81;\n\nfunction readResultEnvelope(\n resultPtr: Pointer | null,\n): { success: true; handlePtr: number; intValue: number } | Result<never> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const success = read.u8(resultPtr, RES_SUCCESS) !== 0;\n const library = loadLibrary();\n\n if (!success) {\n const errorPtr = read.ptr(resultPtr, RES_ERROR);\n const errorMsg = readCString(errorPtr) || \"Unknown error\";\n library.symbols.fff_free_result(resultPtr);\n return err(errorMsg);\n }\n\n const handlePtr = read.ptr(resultPtr, RES_HANDLE);\n const intValue = Number(read.i64(resultPtr, RES_INT_VALUE));\n library.symbols.fff_free_result(resultPtr);\n return { success: true, handlePtr, intValue };\n}\n\n/** Parse a FffResult that carries a bool in int_value (0 = false, nonzero = true). */\nfunction parseBoolResult(resultPtr: Pointer | null): Result<boolean> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: envelope.intValue !== 0 };\n}\n\n/** Parse a FffResult that carries an integer in int_value. */\nfunction parseIntResult(resultPtr: Pointer | null): Result<number> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: envelope.intValue };\n}\n\n/** Parse a FffResult that carries a string in handle (freed with fff_free_string). */\nfunction parseStringResult(resultPtr: Pointer | null): Result<string | null> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) return { ok: true, value: null };\n\n const library = loadLibrary();\n const str = readCString(envelope.handlePtr);\n library.symbols.fff_free_string(asPtr(envelope.handlePtr));\n return { ok: true, value: str };\n}\n\n/** Parse a FffResult that carries a JSON string in handle. */\nfunction parseJsonResult<T>(resultPtr: Pointer | null): Result<T> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) return { ok: true, value: undefined as T };\n\n const library = loadLibrary();\n const jsonStr = readCString(envelope.handlePtr);\n library.symbols.fff_free_string(asPtr(envelope.handlePtr));\n\n if (jsonStr === null || jsonStr === \"\") return { ok: true, value: undefined as T };\n\n try {\n return { ok: true, value: snakeToCamel(JSON.parse(jsonStr)) as T };\n } catch {\n return { ok: true, value: jsonStr as T };\n }\n}\n\n/** Parse a FffResult with no payload (void, success/error only). */\nfunction parseVoidResult(resultPtr: Pointer | null): Result<void> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: undefined };\n}\n\n/**\n * Opaque native handle type. Callers must not inspect or modify this value.\n */\nexport type NativeHandle = Pointer;\n\n/**\n * Create a new file finder instance.\n *\n * Hand-encodes a [`FffCreateOptions`] struct (88 bytes, locked offsets — see\n * `crates/fff-c/src/ffi_types.rs::options_layout_tests`) into a Buffer and\n * passes its pointer to `fff_create_instance_with`. Inner cstring addresses\n * come from Bun's native `ptr(buffer)` primitive — no round-trip helpers,\n * no struct support gaps.\n *\n * Adding new options later means: (1) appending the field to\n * `FffCreateOptions` in Rust, (2) bumping `FFF_CREATE_OPTIONS_VERSION`,\n * (3) extending `FFF_CREATE_OPTIONS_SIZE` + offsets here. The C entry point\n * never changes.\n */\nexport function ffiCreate(\n basePath: string,\n frecencyDbPath: string,\n historyDbPath: string,\n _useUnsafeNoLock: boolean,\n enableMmapCache: boolean,\n enableContentIndexing: boolean,\n watch: boolean,\n aiMode: boolean,\n logFilePath: string,\n logLevel: string,\n cacheBudgetMaxFiles: bigint,\n cacheBudgetMaxBytes: bigint,\n cacheBudgetMaxFileSize: bigint,\n enableFsRootScanning: boolean,\n enableHomeDirScanning: boolean,\n): Result<NativeHandle> {\n const library = loadLibrary();\n\n // Keep cstring buffers alive across the FFI call. Bun's `ptr()` returns\n // the underlying memory address of each Buffer — no round-trips.\n const basePathCStr = encodeCStringBuf(basePath);\n const frecencyCStr = encodeCStringBuf(frecencyDbPath);\n const historyCStr = encodeCStringBuf(historyDbPath);\n const logFileCStr = encodeCStringBuf(logFilePath);\n const logLevelCStr = encodeCStringBuf(logLevel);\n\n const opts = Buffer.alloc(FFF_CREATE_OPTIONS_SIZE);\n opts.writeUInt32LE(FFF_CREATE_OPTIONS_VERSION, FCO_VERSION);\n writePtrLE(opts, FCO_BASE_PATH, basePathCStr);\n writePtrLE(opts, FCO_FRECENCY_DB_PATH, frecencyCStr);\n writePtrLE(opts, FCO_HISTORY_DB_PATH, historyCStr);\n opts.writeUInt8(enableMmapCache ? 1 : 0, FCO_ENABLE_MMAP_CACHE);\n opts.writeUInt8(enableContentIndexing ? 1 : 0, FCO_ENABLE_CONTENT_INDEXING);\n opts.writeUInt8(watch ? 1 : 0, FCO_WATCH);\n opts.writeUInt8(aiMode ? 1 : 0, FCO_AI_MODE);\n writePtrLE(opts, FCO_LOG_FILE_PATH, logFileCStr);\n writePtrLE(opts, FCO_LOG_LEVEL, logLevelCStr);\n opts.writeBigUInt64LE(cacheBudgetMaxFiles, FCO_CACHE_BUDGET_MAX_FILES);\n opts.writeBigUInt64LE(cacheBudgetMaxBytes, FCO_CACHE_BUDGET_MAX_BYTES);\n opts.writeBigUInt64LE(cacheBudgetMaxFileSize, FCO_CACHE_BUDGET_MAX_FILE_SIZE);\n opts.writeUInt8(enableFsRootScanning ? 1 : 0, FCO_ENABLE_FS_ROOT_SCANNING);\n opts.writeUInt8(enableHomeDirScanning ? 1 : 0, FCO_ENABLE_HOME_DIR_SCANNING);\n\n const resultPtr = library.symbols.fff_create_instance_with(ptr(opts));\n\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const success = read.u8(resultPtr, RES_SUCCESS) !== 0;\n\n if (success) {\n const handlePtr = read.ptr(resultPtr, RES_HANDLE);\n const handle = handlePtr as unknown as Pointer;\n library.symbols.fff_free_result(resultPtr);\n\n if (!handle || handle === (0 as unknown as Pointer)) {\n return err(\"fff_create_instance_with returned null handle\");\n }\n\n return { ok: true, value: handle };\n } else {\n const errorPtr = read.ptr(resultPtr, RES_ERROR);\n const errorMsg = readCString(errorPtr) || \"Unknown error\";\n library.symbols.fff_free_result(resultPtr);\n return err(errorMsg);\n }\n}\n\n/** NUL-terminated UTF-8 buffer for `s`, or `null` for empty input. */\nfunction encodeCStringBuf(s: string | null | undefined): Buffer | null {\n if (!s) return null;\n return Buffer.from(s + \"\\0\", \"utf-8\");\n}\n\n/** Write Bun's native pointer-to-buffer address into the options buffer. */\nfunction writePtrLE(buf: Buffer, offset: number, target: Buffer | null): void {\n if (target == null) {\n buf.writeBigUInt64LE(0n, offset);\n return;\n }\n buf.writeBigUInt64LE(BigInt(ptr(target) as unknown as number), offset);\n}\n\n/**\n * Destroy and clean up an instance.\n */\nexport function ffiDestroy(handle: NativeHandle): void {\n const library = loadLibrary();\n library.symbols.fff_destroy(handle);\n}\n\n// ---------------------------------------------------------------------------\n// Struct byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// FffSearchResult { items: *mut, scores: *mut, count: u32, total_matched: u32, total_files: u32, location: FffLocation }\nconst SR_ITEMS = 0; // *mut FffFileItem (8)\nconst SR_SCORES = 8; // *mut FffScore (8)\nconst SR_COUNT = 16; // u32 (4)\nconst SR_MATCHED = 20; // u32 (4)\nconst SR_TOTAL = 24; // u32 (4)\n// FffLocation is inlined at offset 28\nconst SR_LOC_TAG = 28; // u8 (1 + 3 padding)\nconst SR_LOC_LINE = 32; // i32 (4)\nconst SR_LOC_COL = 36; // i32 (4)\nconst SR_LOC_END_LINE = 40; // i32 (4)\nconst SR_LOC_END_COL = 44; // i32 (4)\n\n// FffFileItem (72 bytes)\nconst FI_RELPATH = 0; // *mut c_char (8)\nconst FI_FNAME = 8; // *mut c_char (8)\nconst FI_GIT = 16; // *mut c_char (8)\nconst FI_SIZE = 24; // u64 (8)\nconst FI_MODIFIED = 32; // u64 (8)\nconst FI_ACCESS = 40; // i64 (8)\nconst FI_MODFR = 48; // i64 (8)\nconst FI_TOTAL_FR = 56; // i64 (8)\nconst FI_SIZE_OF = 72;\n\n// FffScore (48 bytes)\nconst SC_TOTAL = 0; // i32 (4)\nconst SC_BASE = 4; // i32 (4)\nconst SC_FNAME = 8; // i32 (4)\nconst SC_SPECIAL = 12; // i32 (4)\nconst SC_FREC = 16; // i32 (4)\nconst SC_DIST = 20; // i32 (4)\nconst SC_CURFILE = 24; // i32 (4)\nconst SC_COMBO = 28; // i32 (4)\nconst SC_EXACT = 32; // bool (1 + 7 pad)\nconst SC_MTYPE = 40; // *mut c_char (8)\nconst SC_SIZE_OF = 48;\n\n/** Cast a number (raw address from pointer math) to Pointer for read.*. */\nfunction asPtr(n: number): Pointer {\n return n as unknown as Pointer;\n}\n\n/**\n * Read an FffFileItem struct at the given raw address.\n */\nfunction readFileItemStruct(p: number): FileItem {\n const pp = asPtr(p);\n return {\n relativePath: readCString(read.ptr(pp, FI_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, FI_FNAME)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, FI_GIT)) ?? \"\",\n size: Number(read.u64(pp, FI_SIZE)),\n modified: Number(read.u64(pp, FI_MODIFIED)),\n accessFrecencyScore: Number(read.i64(pp, FI_ACCESS)),\n modificationFrecencyScore: Number(read.i64(pp, FI_MODFR)),\n totalFrecencyScore: Number(read.i64(pp, FI_TOTAL_FR)),\n };\n}\n\n/**\n * Read an FffScore struct at the given raw address.\n */\nfunction readScoreStruct(p: number): Score {\n const pp = asPtr(p);\n return {\n total: read.i32(pp, SC_TOTAL),\n baseScore: read.i32(pp, SC_BASE),\n filenameBonus: read.i32(pp, SC_FNAME),\n specialFilenameBonus: read.i32(pp, SC_SPECIAL),\n frecencyBoost: read.i32(pp, SC_FREC),\n distancePenalty: read.i32(pp, SC_DIST),\n currentFilePenalty: read.i32(pp, SC_CURFILE),\n comboMatchBoost: read.i32(pp, SC_COMBO),\n exactMatch: read.u8(pp, SC_EXACT) !== 0,\n matchType: readCString(read.ptr(pp, SC_MTYPE)) ?? \"\",\n };\n}\n\n/**\n * Parse an FffSearchResult from a raw pointer, then free native memory.\n */\nfunction parseSearchResult(resultPtr: Pointer | null): Result<SearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, SR_COUNT);\n const totalMatched = read.u32(hp, SR_MATCHED);\n const totalFiles = read.u32(hp, SR_TOTAL);\n const itemsBase = read.ptr(hp, SR_ITEMS);\n const scoresBase = read.ptr(hp, SR_SCORES);\n\n // Read location\n const locTag = read.u8(hp, SR_LOC_TAG);\n let location: Location | undefined;\n if (locTag === 1) {\n location = { type: \"line\", line: read.i32(hp, SR_LOC_LINE) };\n } else if (locTag === 2) {\n location = {\n type: \"position\",\n line: read.i32(hp, SR_LOC_LINE),\n col: read.i32(hp, SR_LOC_COL),\n };\n } else if (locTag === 3) {\n location = {\n type: \"range\",\n start: { line: read.i32(hp, SR_LOC_LINE), col: read.i32(hp, SR_LOC_COL) },\n end: {\n line: read.i32(hp, SR_LOC_END_LINE),\n col: read.i32(hp, SR_LOC_END_COL),\n },\n };\n }\n\n // Read items and scores arrays using pointer arithmetic\n const items: FileItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n items.push(readFileItemStruct(itemsBase + i * FI_SIZE_OF));\n scores.push(readScoreStruct(scoresBase + i * SC_SIZE_OF));\n }\n\n // Free native search result\n loadLibrary().symbols.fff_free_search_result(hp);\n\n const result: SearchResult = { items, scores, totalMatched, totalFiles };\n if (location) {\n result.location = location;\n }\n return { ok: true, value: result };\n}\n\n// ---------------------------------------------------------------------------\n// FffDirSearchResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { items: *mut, scores: *mut, count: u32, total_matched: u32, total_dirs: u32 }\n// ---------------------------------------------------------------------------\nconst DSR_COUNT = 16; // u32 (4)\nconst DSR_MATCHED = 20; // u32 (4)\nconst DSR_TOTAL_DIRS = 24; // u32 (4)\n\n// FffDirItem (24 bytes: 8 + 8 + 4 + 4pad)\nconst DI_RELPATH = 0; // *mut c_char (8)\nconst DI_DIRNAME = 8; // *mut c_char (8)\nconst DI_MAX_FRECENCY = 16; // i32 (4)\n\n/**\n * Read an FffDirItem struct at the given raw address.\n */\nfunction readDirItemStruct(p: number): DirItem {\n const pp = asPtr(p);\n return {\n relativePath: readCString(read.ptr(pp, DI_RELPATH)) ?? \"\",\n dirName: readCString(read.ptr(pp, DI_DIRNAME)) ?? \"\",\n maxAccessFrecency: read.i32(pp, DI_MAX_FRECENCY),\n };\n}\n\n/**\n * Parse an FffDirSearchResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseDirSearchResult(resultPtr: Pointer | null): Result<DirSearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search_directories returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, DSR_COUNT);\n const totalMatched = read.u32(hp, DSR_MATCHED);\n const totalDirs = read.u32(hp, DSR_TOTAL_DIRS);\n\n const library = loadLibrary();\n\n const items: DirItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n const itemPtr = library.symbols.fff_dir_search_result_get_item(hp, i);\n if (itemPtr !== null && (itemPtr as unknown as number) !== 0) {\n items.push(readDirItemStruct(itemPtr as unknown as number));\n }\n const scorePtr = library.symbols.fff_dir_search_result_get_score(hp, i);\n if (scorePtr !== null && (scorePtr as unknown as number) !== 0) {\n scores.push(readScoreStruct(scorePtr as unknown as number));\n }\n }\n\n // Free native dir search result\n library.symbols.fff_free_dir_search_result(hp);\n\n return { ok: true, value: { items, scores, totalMatched, totalDirs } };\n}\n\n// ---------------------------------------------------------------------------\n// FffMixedSearchResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { items: *mut, scores: *mut, count: u32, total_matched: u32, total_files: u32, total_dirs: u32, location: FffLocation }\n// ---------------------------------------------------------------------------\nconst MSR_COUNT = 16; // u32 (4)\nconst MSR_MATCHED = 20; // u32 (4)\nconst MSR_TOTAL_FILES = 24; // u32 (4)\nconst MSR_TOTAL_DIRS = 28; // u32 (4)\n// FffLocation is inlined at offset 32\nconst MSR_LOC_TAG = 32; // u8 (1 + 3 padding)\nconst MSR_LOC_LINE = 36; // i32 (4)\nconst MSR_LOC_COL = 40; // i32 (4)\nconst MSR_LOC_END_LINE = 44; // i32 (4)\nconst MSR_LOC_END_COL = 48; // i32 (4)\n\n// FffMixedItem (80 bytes)\nconst MI_TYPE = 0; // u8 (1 + 7 pad)\nconst MI_RELPATH = 8; // *mut c_char (8)\nconst MI_DISPLAY = 16; // *mut c_char (8)\nconst MI_GIT = 24; // *mut c_char (8)\nconst MI_SIZE = 32; // u64 (8)\nconst MI_MODIFIED = 40; // u64 (8)\nconst MI_ACCESS = 48; // i64 (8)\nconst MI_MODFR = 56; // i64 (8)\nconst MI_TOTAL_FR = 64; // i64 (8)\n\n/**\n * Read an FffMixedItem struct at the given raw address and return a MixedItem.\n */\nfunction readMixedItemStruct(p: number): MixedItem {\n const pp = asPtr(p);\n const itemType = read.u8(pp, MI_TYPE);\n\n if (itemType === 1) {\n // Directory\n return {\n type: \"directory\",\n item: {\n relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? \"\",\n dirName: readCString(read.ptr(pp, MI_DISPLAY)) ?? \"\",\n maxAccessFrecency: Number(read.i64(pp, MI_ACCESS)),\n },\n };\n }\n\n // File (itemType === 0)\n return {\n type: \"file\",\n item: {\n relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, MI_DISPLAY)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, MI_GIT)) ?? \"\",\n size: Number(read.u64(pp, MI_SIZE)),\n modified: Number(read.u64(pp, MI_MODIFIED)),\n accessFrecencyScore: Number(read.i64(pp, MI_ACCESS)),\n modificationFrecencyScore: Number(read.i64(pp, MI_MODFR)),\n totalFrecencyScore: Number(read.i64(pp, MI_TOTAL_FR)),\n },\n };\n}\n\n/**\n * Parse an FffMixedSearchResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseMixedSearchResult(resultPtr: Pointer | null): Result<MixedSearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search_mixed returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, MSR_COUNT);\n const totalMatched = read.u32(hp, MSR_MATCHED);\n const totalFiles = read.u32(hp, MSR_TOTAL_FILES);\n const totalDirs = read.u32(hp, MSR_TOTAL_DIRS);\n\n // Read location\n const locTag = read.u8(hp, MSR_LOC_TAG);\n let location: Location | undefined;\n if (locTag === 1) {\n location = { type: \"line\", line: read.i32(hp, MSR_LOC_LINE) };\n } else if (locTag === 2) {\n location = {\n type: \"position\",\n line: read.i32(hp, MSR_LOC_LINE),\n col: read.i32(hp, MSR_LOC_COL),\n };\n } else if (locTag === 3) {\n location = {\n type: \"range\",\n start: {\n line: read.i32(hp, MSR_LOC_LINE),\n col: read.i32(hp, MSR_LOC_COL),\n },\n end: {\n line: read.i32(hp, MSR_LOC_END_LINE),\n col: read.i32(hp, MSR_LOC_END_COL),\n },\n };\n }\n\n const library = loadLibrary();\n\n const items: MixedItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n const itemPtr = library.symbols.fff_mixed_search_result_get_item(hp, i);\n if (itemPtr !== null && (itemPtr as unknown as number) !== 0) {\n items.push(readMixedItemStruct(itemPtr as unknown as number));\n }\n const scorePtr = library.symbols.fff_mixed_search_result_get_score(hp, i);\n if (scorePtr !== null && (scorePtr as unknown as number) !== 0) {\n scores.push(readScoreStruct(scorePtr as unknown as number));\n }\n }\n\n // Free native mixed search result\n library.symbols.fff_free_mixed_search_result(hp);\n\n const result: MixedSearchResult = {\n items,\n scores,\n totalMatched,\n totalFiles,\n totalDirs,\n };\n if (location) {\n result.location = location;\n }\n return { ok: true, value: result };\n}\n\n// ---------------------------------------------------------------------------\n// FffGrepMatch byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// Pointers (8 bytes each)\nconst GM_RELPATH = 0;\nconst GM_FNAME = 8;\nconst GM_GIT = 16;\nconst GM_LINE_CONTENT = 24;\nconst GM_MATCH_RANGES = 32;\nconst GM_CTX_BEFORE = 40;\nconst GM_CTX_AFTER = 48;\n\n// 8-byte numeric fields\nconst GM_SIZE = 56;\nconst GM_MODIFIED = 64;\nconst GM_TOTAL_FR = 72;\nconst GM_ACCESS_FR = 80;\nconst GM_MOD_FR = 88;\nconst GM_LINE_NUM = 96;\nconst GM_BYTE_OFF = 104;\n\n// 4-byte fields\nconst GM_COL = 112;\nconst GM_MR_COUNT = 116;\nconst GM_CTX_B_COUNT = 120;\nconst GM_CTX_A_COUNT = 124;\n\n// 2-byte\nconst GM_FUZZY_SCORE = 128;\n// 1-byte\nconst GM_HAS_FUZZY = 130;\nconst GM_IS_BINARY = 131;\nconst GM_IS_DEFINITION = 132;\n\n// struct size: pad to 8-byte alignment → 136\nconst GM_SIZE_OF = 136;\n\n// FffGrepResult\nconst GR_ITEMS = 0; // *mut FffGrepMatch (8)\nconst GR_COUNT = 8; // u32 (4)\nconst GR_MATCHED = 12; // u32 (4)\nconst GR_FILES_SEARCHED = 16; // u32 (4)\nconst GR_TOTAL_FILES = 20; // u32 (4)\nconst GR_FILTERED = 24; // u32 (4)\nconst GR_NEXT_OFFSET = 28; // u32 (4)\nconst GR_REGEX_ERR = 32; // *mut c_char (8)\n\n// FffMatchRange (8 bytes)\nconst MR_START = 0;\nconst MR_END = 4;\nconst MR_SIZE = 8;\n\n/**\n * Read a C string array (char**) at the given pointer, with `count` elements.\n */\nfunction readCStringArray(base: number, count: number): string[] {\n if (count === 0 || base === 0) return [];\n const result: string[] = [];\n const bp = asPtr(base);\n for (let i = 0; i < count; i++) {\n const strPtr = read.ptr(bp, i * 8); // each pointer is 8 bytes\n result.push(readCString(strPtr) ?? \"\");\n }\n return result;\n}\n\n/**\n * Read an FffGrepMatch struct at the given raw address.\n */\nfunction readGrepMatchStruct(p: number): GrepMatch {\n const pp = asPtr(p);\n const matchRangesPtr = read.ptr(pp, GM_MATCH_RANGES);\n const matchRangesCount = read.u32(pp, GM_MR_COUNT);\n const matchRanges: [number, number][] = [];\n for (let i = 0; i < matchRangesCount; i++) {\n const base = matchRangesPtr + i * MR_SIZE;\n const bp = asPtr(base);\n matchRanges.push([read.u32(bp, MR_START), read.u32(bp, MR_END)]);\n }\n\n const hasFuzzy = read.u8(pp, GM_HAS_FUZZY) !== 0;\n const ctxBeforeCount = read.u32(pp, GM_CTX_B_COUNT);\n const ctxAfterCount = read.u32(pp, GM_CTX_A_COUNT);\n\n const match: GrepMatch = {\n relativePath: readCString(read.ptr(pp, GM_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, GM_FNAME)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, GM_GIT)) ?? \"\",\n lineContent: readCString(read.ptr(pp, GM_LINE_CONTENT)) ?? \"\",\n size: Number(read.u64(pp, GM_SIZE)),\n modified: Number(read.u64(pp, GM_MODIFIED)),\n totalFrecencyScore: Number(read.i64(pp, GM_TOTAL_FR)),\n accessFrecencyScore: Number(read.i64(pp, GM_ACCESS_FR)),\n modificationFrecencyScore: Number(read.i64(pp, GM_MOD_FR)),\n isBinary: read.u8(pp, GM_IS_BINARY) !== 0,\n lineNumber: Number(read.u64(pp, GM_LINE_NUM)),\n col: read.u32(pp, GM_COL),\n byteOffset: Number(read.u64(pp, GM_BYTE_OFF)),\n matchRanges,\n };\n\n if (hasFuzzy) {\n match.fuzzyScore = read.u16(pp, GM_FUZZY_SCORE);\n }\n if (ctxBeforeCount > 0) {\n match.contextBefore = readCStringArray(read.ptr(pp, GM_CTX_BEFORE), ctxBeforeCount);\n }\n if (ctxAfterCount > 0) {\n match.contextAfter = readCStringArray(read.ptr(pp, GM_CTX_AFTER), ctxAfterCount);\n }\n if (read.u8(pp, GM_IS_DEFINITION) !== 0) {\n match.isDefinition = true;\n }\n\n return match;\n}\n\n/**\n * Parse an FffGrepResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseGrepResult(resultPtr: Pointer | null): Result<GrepResult> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"grep returned null result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, GR_COUNT);\n const totalMatched = read.u32(hp, GR_MATCHED);\n const totalFilesSearched = read.u32(hp, GR_FILES_SEARCHED);\n const totalFiles = read.u32(hp, GR_TOTAL_FILES);\n const filteredFileCount = read.u32(hp, GR_FILTERED);\n const nextFileOffset = read.u32(hp, GR_NEXT_OFFSET);\n const regexErrPtr = read.ptr(hp, GR_REGEX_ERR);\n const regexFallbackError = readCString(regexErrPtr) ?? undefined;\n const itemsBase = read.ptr(hp, GR_ITEMS);\n\n const items: GrepMatch[] = [];\n for (let i = 0; i < count; i++) {\n items.push(readGrepMatchStruct(itemsBase + i * GM_SIZE_OF));\n }\n\n loadLibrary().symbols.fff_free_grep_result(hp);\n\n const grepResult: GrepResult = {\n items,\n totalMatched,\n totalFilesSearched,\n totalFiles,\n filteredFileCount,\n nextCursor: nextFileOffset > 0 ? createGrepCursor(nextFileOffset) : null,\n };\n if (regexFallbackError) {\n grepResult.regexFallbackError = regexFallbackError;\n }\n return { ok: true, value: grepResult };\n}\n\n/**\n * Perform fuzzy search.\n */\nexport function ffiSearch(\n handle: NativeHandle,\n query: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n comboBoostMultiplier: number,\n minComboCount: number,\n): Result<SearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n comboBoostMultiplier,\n minComboCount,\n );\n return parseSearchResult(resultPtr);\n}\n\n/**\n * Glob-only search. Bypasses the regular query parser, applies the pattern\n * as a single `Constraint::Glob`, ranks by frecency, paginates.\n */\nexport function ffiGlob(\n handle: NativeHandle,\n pattern: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n): Result<SearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_glob(\n handle,\n ptr(encodeString(pattern)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n );\n return parseSearchResult(resultPtr);\n}\n\n/**\n * Perform fuzzy directory search.\n */\nexport function ffiSearchDirectories(\n handle: NativeHandle,\n query: string,\n currentFile: string | null,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n): Result<DirSearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search_directories(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile ?? \"\")),\n maxThreads,\n pageIndex,\n pageSize,\n );\n return parseDirSearchResult(resultPtr);\n}\n\n/**\n * Perform mixed (files + directories) fuzzy search.\n */\nexport function ffiSearchMixed(\n handle: NativeHandle,\n query: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n comboBoostMultiplier: number,\n minComboCount: number,\n): Result<MixedSearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search_mixed(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n comboBoostMultiplier,\n minComboCount,\n );\n return parseMixedSearchResult(resultPtr);\n}\n\n/**\n * Live grep - search file contents.\n */\nexport function ffiLiveGrep(\n handle: NativeHandle,\n query: string,\n mode: string,\n maxFileSize: number,\n maxMatchesPerFile: number,\n smartCase: boolean,\n fileOffset: number,\n pageLimit: number,\n timeBudgetMs: number,\n beforeContext: number,\n afterContext: number,\n classifyDefinitions: boolean,\n): Result<GrepResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_live_grep(\n handle,\n ptr(encodeString(query)),\n grepModeToU8(mode),\n BigInt(maxFileSize),\n maxMatchesPerFile,\n smartCase,\n fileOffset,\n pageLimit,\n BigInt(timeBudgetMs),\n beforeContext,\n afterContext,\n classifyDefinitions,\n );\n return parseGrepResult(resultPtr);\n}\n\n/**\n * Multi-pattern grep - Aho-Corasick multi-needle search.\n */\nexport function ffiMultiGrep(\n handle: NativeHandle,\n patternsJoined: string,\n constraints: string,\n maxFileSize: number,\n maxMatchesPerFile: number,\n smartCase: boolean,\n fileOffset: number,\n pageLimit: number,\n timeBudgetMs: number,\n beforeContext: number,\n afterContext: number,\n classifyDefinitions: boolean,\n): Result<GrepResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_multi_grep(\n handle,\n ptr(encodeString(patternsJoined)),\n ptr(encodeString(constraints)),\n BigInt(maxFileSize),\n maxMatchesPerFile,\n smartCase,\n fileOffset,\n pageLimit,\n BigInt(timeBudgetMs),\n beforeContext,\n afterContext,\n classifyDefinitions,\n );\n return parseGrepResult(resultPtr);\n}\n\n/**\n * Trigger file scan.\n */\nexport function ffiScanFiles(handle: NativeHandle): Result<void> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_scan_files(handle);\n return parseVoidResult(resultPtr);\n}\n\n/**\n * Check if scanning.\n */\nexport function ffiIsScanning(handle: NativeHandle): boolean {\n const library = loadLibrary();\n return library.symbols.fff_is_scanning(handle) as boolean;\n}\n\n/**\n * Get the base path of the file picker.\n */\nexport function ffiGetBasePath(handle: NativeHandle): Result<string | null> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_base_path(handle);\n return parseStringResult(resultPtr);\n}\n\n// FffScanProgress { scanned_files_count: u64(8), is_scanning: bool(1), is_watcher_ready: bool(1), is_warmup_complete: bool(1) + pad }\nconst SP_COUNT = 0; // u64 (8)\nconst SP_SCANNING = 8; // bool (1)\nconst SP_WATCHER_READY = 9; // bool (1)\nconst SP_WARMUP_COMPLETE = 10; // bool (1)\n\n/**\n * Get scan progress.\n */\nexport function ffiGetScanProgress(handle: NativeHandle): Result<ScanProgress> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_scan_progress(handle);\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"scan progress returned null\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const result: ScanProgress = {\n scannedFilesCount: Number(read.u64(hp, SP_COUNT)),\n isScanning: read.u8(hp, SP_SCANNING) !== 0,\n isWatcherReady: read.u8(hp, SP_WATCHER_READY) !== 0,\n isWarmupComplete: read.u8(hp, SP_WARMUP_COMPLETE) !== 0,\n };\n library.symbols.fff_free_scan_progress(hp);\n return { ok: true, value: result };\n}\n\n/**\n * Wait for scan to complete.\n */\nexport function ffiWaitForScan(handle: NativeHandle, timeoutMs: number): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_wait_for_scan(handle, BigInt(timeoutMs));\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Restart index in new path.\n */\nexport function ffiRestartIndex(handle: NativeHandle, newPath: string): Result<void> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_restart_index(handle, ptr(encodeString(newPath)));\n return parseVoidResult(resultPtr);\n}\n\n// ---------------------------------------------------------------------------\n// Watch struct byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// MUST match `crates/fff-c`::FffWatchOptions\nconst FFF_WATCH_OPTIONS_VERSION = 1;\nconst FFF_WATCH_OPTIONS_SIZE = 24;\nconst FWO_VERSION = 0; // u32 (4 + 4 pad)\nconst FWO_IGNORE = 8; // *const *const c_char (8)\nconst FWO_IGNORE_COUNT = 16; // u32 (4 + 4 pad)\n\n/** kind u8 -> WatchEventKind. Unknown values degrade to \"rescan\". */\nconst WATCH_EVENT_KINDS: readonly WatchEventKind[] = [\n \"created\",\n \"modified\",\n \"removed\",\n \"rescan\",\n];\n\n/**\n * Parse an FffWatchEventBatch delivered to a watch callback, then free it.\n * Ownership of the batch transfers to JS at callback time, so this MUST be\n * called exactly once per delivered batch pointer.\n */\nexport function readWatchEventBatch(batchPtr: Pointer | number | null): WatchEvent[] {\n if (batchPtr === null || (batchPtr as unknown as number) === 0) {\n return [];\n }\n\n const bp = batchPtr as unknown as Pointer;\n const symbols = loadLibrary().symbols;\n const count = symbols.fff_watch_events_count(bp);\n\n const events: WatchEvent[] = [];\n for (let i = 0; i < count; i++) {\n const path = symbols.fff_watch_events_get_path(bp, i) as Pointer | null;\n const kind = symbols.fff_watch_events_get_kind(bp, i) as number;\n events.push({\n path: readCString(path) ?? \"\",\n kind: WATCH_EVENT_KINDS[kind] ?? \"rescan\",\n });\n }\n\n symbols.fff_free_watch_events(bp);\n return events;\n}\n\n/**\n * Register the instance-wide watch callback. Must be called before the\n * first `ffiWatch`. The caller owns `callback` (a threadsafe `JSCallback`\n * built in finder.ts) and must keep it alive until after `ffiDestroy`\n * returns for this handle — that call is the delivery quiescence barrier.\n */\nexport function ffiSetWatchCallback(\n handle: NativeHandle,\n callback: JSCallback,\n): Result<void> {\n const library = loadLibrary();\n if (callback.ptr === null) {\n return err(\"watch callback has been closed\");\n }\n const resultPtr = library.symbols.fff_set_watch_callback(handle, callback.ptr, null);\n return parseVoidResult(resultPtr);\n}\n\n/**\n * Subscribe to filesystem changes; batches are delivered through the\n * instance callback registered with `ffiSetWatchCallback`, tagged with the\n * watch id this function returns.\n *\n * @returns The native watch id carried in `FffResult.int_value`.\n */\nexport function ffiWatch(\n handle: NativeHandle,\n pattern: string,\n ignore: string[] = [],\n): Result<number> {\n const library = loadLibrary();\n\n // Keep every buffer referenced until the FFI call returns: the options\n // struct, the pointer array, and each encoded ignore string.\n const opts = Buffer.alloc(FFF_WATCH_OPTIONS_SIZE);\n opts.writeUInt32LE(FFF_WATCH_OPTIONS_VERSION, FWO_VERSION);\n\n const ignoreBuffers = ignore.map((entry) => encodeString(entry));\n const ignorePtrs = Buffer.alloc(Math.max(ignoreBuffers.length, 1) * 8);\n for (let i = 0; i < ignoreBuffers.length; i++) {\n ignorePtrs.writeBigUInt64LE(BigInt(ptr(ignoreBuffers[i] as Uint8Array)), i * 8);\n }\n opts.writeBigUInt64LE(\n ignoreBuffers.length > 0 ? BigInt(ptr(ignorePtrs)) : 0n,\n FWO_IGNORE,\n );\n opts.writeUInt32LE(ignoreBuffers.length, FWO_IGNORE_COUNT);\n\n const resultPtr = library.symbols.fff_watch(\n handle,\n ptr(encodeString(pattern)),\n ptr(opts),\n );\n return parseIntResult(resultPtr);\n}\n\n/**\n * Remove a watch subscription. Returns true if the id was found.\n */\nexport function ffiUnwatch(handle: NativeHandle, watchId: number): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_unwatch(handle, BigInt(watchId));\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Refresh git status.\n */\nexport function ffiRefreshGitStatus(handle: NativeHandle): Result<number> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_refresh_git_status(handle);\n return parseIntResult(resultPtr);\n}\n\n/**\n * Track query completion.\n */\nexport function ffiTrackQuery(\n handle: NativeHandle,\n query: string,\n filePath: string,\n): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_track_query(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(filePath)),\n );\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Get historical query.\n */\nexport function ffiGetHistoricalQuery(\n handle: NativeHandle,\n offset: number,\n): Result<string | null> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_historical_query(handle, BigInt(offset));\n return parseStringResult(resultPtr);\n}\n\n/**\n * Health check.\n *\n * `handle` can be null for a limited check (version + git only).\n */\nexport function ffiHealthCheck(\n handle: NativeHandle | null,\n testPath: string,\n): Result<unknown> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_health_check(\n handle ?? (0 as unknown as Pointer),\n ptr(encodeString(testPath)),\n );\n return parseJsonResult<unknown>(resultPtr);\n}\n\n/**\n * Ensure the library is loaded.\n *\n * Loads the native library from the platform-specific npm package\n * or a local dev build. Throws if the binary is not found.\n */\nexport function ensureLoaded(): void {\n loadLibrary();\n}\n\n/**\n * Check if the library is available.\n */\nexport function isAvailable(): boolean {\n try {\n loadLibrary();\n return true;\n } catch {\n return false;\n }\n}\n",
7
+ "/**\n * FileFinder - High-level API for the fff file finder\n *\n * This class provides a type-safe, ergonomic API for file finding operations.\n * Each instance owns an independent native file picker that can be created\n * and destroyed independently. Multiple instances can coexist.\n *\n * All methods return Result types for explicit error handling.\n */\n\nimport { FFIType, JSCallback, type Pointer } from \"bun:ffi\";\n\nimport {\n ensureLoaded,\n ffiCreate,\n ffiDestroy,\n ffiGetBasePath,\n ffiGetHistoricalQuery,\n ffiGetScanProgress,\n ffiGlob,\n ffiHealthCheck,\n ffiIsScanning,\n ffiLiveGrep,\n ffiMultiGrep,\n ffiRefreshGitStatus,\n ffiRestartIndex,\n ffiScanFiles,\n ffiSearch,\n ffiSearchDirectories,\n ffiSearchMixed,\n ffiSetWatchCallback,\n ffiTrackQuery,\n ffiUnwatch,\n ffiWaitForScan,\n ffiWatch,\n isAvailable,\n type NativeHandle,\n readWatchEventBatch,\n} from \"./ffi\";\n\nimport type {\n DirSearchOptions,\n DirSearchResult,\n InitOptions as FFFInitOptions,\n FileFinderApi,\n GlobOptions,\n GrepOptions,\n GrepResult,\n HealthCheck,\n MixedSearchResult,\n MultiGrepOptions,\n Result,\n ScanProgress,\n SearchOptions,\n SearchResult,\n WatchBatchCallback,\n WatchOptions,\n WatchUnsubscribe,\n} from \"./fff-api\";\n\nimport { err } from \"./fff-api\";\n\n/**\n * FileFinder - Fast file finder with fuzzy search\n *\n * Each instance is backed by an independent native file picker. Create as many\n * as you need and destroy them when done.\n *\n * @example\n * ```typescript\n * import { FileFinder } from \"fff\";\n *\n * // Create an instance\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n * if (!finder.ok) {\n * console.error(finder.error);\n * process.exit(1);\n * }\n *\n * // Wait for initial scan\n * await finder.value.waitForScan(5000);\n *\n * // Search for files\n * const search = finder.value.search(\"main.ts\");\n * if (search.ok) {\n * for (const item of search.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n *\n * // Cleanup\n * finder.value.destroy();\n * ```\n */\nexport class FileFinder implements FileFinderApi {\n private handle: NativeHandle | null;\n /** Active watch subscriptions: native watch id -> JS batch handler. */\n private watchHandlers = new Map<number, WatchBatchCallback>();\n /**\n * ONE threadsafe JSCallback per instance, registered lazily with\n * `fff_set_watch_callback` on the first subscription and closed in\n * `destroy()` after `fff_destroy` returns (the quiescence barrier).\n */\n private watchJsCallback: JSCallback | null = null;\n\n private constructor(handle: NativeHandle) {\n this.handle = handle;\n }\n\n /**\n * Create a new file finder instance.\n *\n * @param options - Initialization options\n * @returns Result containing the new FileFinder instance or an error\n *\n * @example\n * ```typescript\n * // Basic initialization\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n *\n * // With custom database paths\n * const finder = FileFinder.create({\n * basePath: \"/path/to/project\",\n * frecencyDbPath: \"/custom/frecency.mdb\",\n * historyDbPath: \"/custom/history.mdb\",\n * });\n * ```\n */\n static create(options: FFFInitOptions): Result<FileFinder> {\n const result = ffiCreate(\n options.basePath,\n options.frecencyDbPath ?? \"\",\n options.historyDbPath ?? \"\",\n options.useUnsafeNoLock ?? false,\n !(options.disableMmapCache ?? false),\n !(options.disableContentIndexing ?? options.disableMmapCache ?? false),\n !(options.disableWatch ?? false),\n options.aiMode ?? false,\n options.logFilePath ?? \"\",\n options.logLevel ?? \"\",\n BigInt(options.cacheBudgetMaxFiles ?? 0),\n BigInt(options.cacheBudgetMaxBytes ?? 0),\n BigInt(options.cacheBudgetMaxFileSize ?? 0),\n options.enableFsRootScanning ?? false,\n options.enableHomeDirScanning ?? false,\n );\n\n if (!result.ok) {\n return result;\n }\n\n return { ok: true, value: new FileFinder(result.value) };\n }\n\n /**\n * Destroy and clean up all resources.\n *\n * Frees the native instance (unsubscribing all watches), then closes the\n * instance watch trampoline. After calling this, the instance must not be\n * used again.\n */\n destroy(): void {\n if (this.handle !== null) {\n this.watchHandlers.clear();\n ffiDestroy(this.handle);\n this.handle = null;\n // Handlers were cleared first, so a delivery racing the destroy is a\n // benign id-map miss before the trampoline is closed.\n this.watchJsCallback?.close();\n this.watchJsCallback = null;\n }\n }\n\n /**\n * Check if this instance has been destroyed.\n */\n get isDestroyed(): boolean {\n return this.handle === null;\n }\n\n /**\n * Guard that returns an error if the instance has been destroyed.\n */\n private ensureAlive(): Result<NativeHandle> {\n if (this.handle === null) {\n return err(\"FileFinder instance has been destroyed.\");\n }\n return { ok: true, value: this.handle };\n }\n\n /**\n * Search for files matching the query.\n *\n * The query supports fuzzy matching and special syntax:\n * - `foo bar` - Match files containing \"foo\" and \"bar\"\n * - `src/` - Match files in src directory\n * - `file.ts:42` - Match file.ts with line 42\n * - `file.ts:42:10` - Match file.ts with line 42, column 10\n *\n * @param query - Search query string\n * @param options - Search options\n * @returns Search results with matched files and scores\n *\n * @example\n * ```typescript\n * const result = finder.search(\"main.ts\", { pageSize: 10 });\n * if (result.ok) {\n * console.log(`Found ${result.value.totalMatched} files`);\n * for (const item of result.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n * ```\n */\n fileSearch(query: string, options?: SearchOptions): Result<SearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearch(\n guard.value,\n query,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n options?.comboBoostMultiplier ?? 0,\n options?.minComboCount ?? 0,\n );\n }\n\n /**\n * Glob-only search.\n *\n * The pattern is applied as a single pass SIMD optimized prefiltering\n * without any fuzzy matching involved. Faster and 100% compatible to npm `glob`.\n *\n * @param pattern - Glob pattern (required, non-empty)\n * @param options - Glob search options (pagination, max threads, current file)\n * @returns Search results with files matching the glob\n */\n glob(pattern: string, options?: GlobOptions): Result<SearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiGlob(\n guard.value,\n pattern,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n );\n }\n\n /**\n * Search for directories matching the query.\n *\n * @param query - Search query string\n * @param options - Directory search options\n * @returns Search results with matched directories and scores\n *\n * @example\n * ```typescript\n * const result = finder.directorySearch(\"components\", { pageSize: 10 });\n * if (result.ok) {\n * console.log(`Found ${result.value.totalMatched} directories`);\n * for (const item of result.value.items) {\n * console.log(item.relativePath);\n * }\n * }\n * ```\n */\n directorySearch(query: string, options?: DirSearchOptions): Result<DirSearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearchDirectories(\n guard.value,\n query,\n options?.currentFile ?? null,\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n );\n }\n\n /**\n * Search for files and directories together (mixed search).\n *\n * Results are interleaved by total score in descending order.\n *\n * @param query - Search query string\n * @param options - Search options\n * @returns Mixed search results with files and directories interleaved by score\n *\n * @example\n * ```typescript\n * const result = finder.mixedSearch(\"main\", { pageSize: 20 });\n * if (result.ok) {\n * for (const entry of result.value.items) {\n * if (entry.type === \"file\") {\n * console.log(`File: ${entry.item.relativePath}`);\n * } else {\n * console.log(`Dir: ${entry.item.relativePath}`);\n * }\n * }\n * }\n * ```\n */\n mixedSearch(query: string, options?: SearchOptions): Result<MixedSearchResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiSearchMixed(\n guard.value,\n query,\n options?.currentFile ?? \"\",\n options?.maxThreads ?? 0,\n options?.pageIndex ?? 0,\n options?.pageSize ?? 0,\n options?.comboBoostMultiplier ?? 0,\n options?.minComboCount ?? 0,\n );\n }\n\n /**\n * Search file contents (live grep).\n *\n * Searches through the contents of indexed files using the specified mode:\n * - `\"plain\"` (default): SIMD-accelerated literal text matching\n * - `\"regex\"`: Regular expression matching\n * - `\"fuzzy\"`: Smith-Waterman fuzzy matching per line\n *\n * Supports pagination for large result sets. The result includes a `nextCursor`\n * that can be passed back to fetch the next page.\n *\n * The query also supports constraint syntax:\n * - `*.ts pattern` - Only search in TypeScript files\n * - `src/ pattern` - Only search in the src directory\n *\n * @param query - Search query string\n * @param options - Grep options (mode, pagination, limits)\n * @returns Grep results with matched lines and file metadata\n *\n * @example\n * ```typescript\n * // First page\n * const result = finder.grep(\"TODO\", { mode: \"plain\" });\n * if (result.ok) {\n * for (const match of result.value.items) {\n * console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);\n * }\n * // Fetch next page\n * if (result.value.nextCursor) {\n * const page2 = finder.grep(\"TODO\", {\n * cursor: result.value.nextCursor,\n * });\n * }\n * }\n * ```\n */\n grep(query: string, options?: GrepOptions): Result<GrepResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n return ffiLiveGrep(\n guard.value,\n query,\n options?.mode ?? \"plain\",\n options?.maxFileSize ?? 0,\n options?.maxMatchesPerFile ?? 0,\n options?.smartCase ?? true,\n options?.cursor?._offset ?? 0,\n options?.pageSize ?? 0,\n options?.timeBudgetMs ?? 0,\n options?.enforceTimeBudget ?? false,\n options?.beforeContext ?? 0,\n options?.afterContext ?? 0,\n options?.classifyDefinitions ?? false,\n );\n }\n\n /**\n * Multi-pattern OR search using Aho-Corasick.\n *\n * Searches for lines matching ANY of the provided patterns using\n * SIMD-accelerated multi-needle matching. Faster than regex alternation\n * for literal text searches.\n *\n * Supports pagination. The result includes a `nextCursor` that can be\n * passed back to fetch the next page.\n *\n * @param options - Multi-grep options including patterns and optional constraints\n * @returns Grep results with matched lines and file metadata\n *\n * @example\n * ```typescript\n * const result = finder.multiGrep({\n * patterns: [\"VideoFrame\", \"video_frame\", \"PreloadedImage\"],\n * });\n * if (result.ok) {\n * for (const match of result.value.items) {\n * console.log(`${match.relativePath}:${match.lineNumber}: ${match.lineContent}`);\n * }\n * }\n * ```\n */\n multiGrep(options: MultiGrepOptions): Result<GrepResult> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n if (!options.patterns || options.patterns.length === 0) {\n return err(\"patterns array must have at least 1 element\");\n }\n\n return ffiMultiGrep(\n guard.value,\n options.patterns.join(\"\\n\"),\n options.constraints ?? \"\",\n options.maxFileSize ?? 0,\n options.maxMatchesPerFile ?? 0,\n options.smartCase ?? true,\n options.cursor?._offset ?? 0,\n options.pageSize ?? 0,\n options.timeBudgetMs ?? 0,\n options.enforceTimeBudget ?? false,\n options.beforeContext ?? 0,\n options.afterContext ?? 0,\n options.classifyDefinitions ?? false,\n );\n }\n\n /**\n * Trigger a rescan of the indexed directory.\n *\n * This is useful after major file system changes that the\n * background watcher might have missed.\n */\n scanFiles(): Result<void> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiScanFiles(guard.value);\n }\n\n /**\n * Check if a scan is currently in progress.\n */\n isScanning(): boolean {\n if (this.handle === null) return false;\n return ffiIsScanning(this.handle);\n }\n\n /**\n * Get the base path of the file picker (the root directory being indexed).\n */\n getBasePath(): Result<string | null> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetBasePath(guard.value);\n }\n\n /**\n * Get the current scan progress.\n */\n getScanProgress(): Result<ScanProgress> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetScanProgress(guard.value) as Result<ScanProgress>;\n }\n\n /**\n * Wait for the initial file scan to complete.\n *\n * Non-blocking: polls `isScanning` and yields to the event loop between\n * checks, so other async work keeps running while waiting.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if scan completed, false if timed out\n *\n * @example\n * ```typescript\n * const finder = FileFinder.create({ basePath: \"/path/to/project\" });\n * if (finder.ok) {\n * const completed = await finder.value.waitForScan(10000);\n * if (!completed.ok || !completed.value) {\n * console.warn(\"Scan did not complete in time\");\n * }\n * }\n * ```\n */\n async waitForScan(timeoutMs: number = 5000): Promise<Result<boolean>> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const deadline = Date.now() + timeoutMs;\n while (this.isScanning()) {\n if (Date.now() >= deadline) {\n return { ok: true, value: false };\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n return { ok: true, value: true };\n }\n\n /**\n * Wait for the initial file scan to complete, blocking the calling thread.\n *\n * Backed by the native `fff_wait_for_scan` call. Prefer {@link waitForScan}\n * unless you specifically need synchronous blocking behaviour.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if scan completed, false if timed out\n */\n waitForScanBlocking(timeoutMs: number = 5000): Result<boolean> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiWaitForScan(guard.value, timeoutMs);\n }\n\n /**\n * Wait until the index is fully ready: the scan has finished and the warmup\n * (content indexing / bigram) phase has completed.\n *\n * Non-blocking — polls `getScanProgress` and yields to the event loop.\n *\n * @param timeoutMs - Maximum time to wait in milliseconds (default: 5000)\n * @returns true if the index became ready, false if timed out\n */\n async waitForIndexReady(timeoutMs: number = 5000): Promise<Result<boolean>> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const deadline = Date.now() + timeoutMs;\n while (true) {\n const progress = this.getScanProgress();\n if (!progress.ok) return progress;\n if (!progress.value.isScanning && progress.value.isWarmupComplete) {\n return { ok: true, value: true };\n }\n if (Date.now() >= deadline) {\n return { ok: true, value: false };\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n }\n\n /**\n * Change the indexed directory to a new path.\n *\n * This stops the current file watcher and starts indexing the new directory.\n *\n * @param newPath - New directory path to index\n */\n reindex(newPath: string): Result<void> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiRestartIndex(guard.value, newPath);\n }\n\n /**\n * Refresh the git status cache.\n *\n * @returns Number of files with updated git status\n */\n refreshGitStatus(): Result<number> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiRefreshGitStatus(guard.value);\n }\n\n /**\n * Track query completion for smart suggestions.\n *\n * Call this when a user selects a file from search results.\n * This helps improve future search rankings for similar queries.\n *\n * @param query - The search query that was used\n * @param selectedFilePath - The file path that was selected\n */\n trackQuery(query: string, selectedFilePath: string): Result<boolean> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiTrackQuery(guard.value, query, selectedFilePath);\n }\n\n /**\n * Get a historical query by offset.\n *\n * @param offset - Offset from most recent (0 = most recent)\n * @returns The historical query string, or null if not found\n */\n getHistoricalQuery(offset: number): Result<string | null> {\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n return ffiGetHistoricalQuery(guard.value, offset);\n }\n\n /**\n * Lazily create + register the instance-wide watch trampoline. Routes\n * every delivered batch to the handler registered for its watch id;\n * unknown ids (unsubscribe races) are benign — the batch is just freed.\n */\n private ensureWatchTrampoline(handle: NativeHandle): Result<void> {\n if (this.watchJsCallback !== null) return { ok: true, value: undefined };\n\n // Threadsafe: the native callback thread enqueues the invocation onto the\n // JS event loop; the batch stays valid because JS owns it until it frees\n // it inside readWatchEventBatch.\n const jsCallback = new JSCallback(\n (watchId: bigint | number, batchPtr: Pointer, _userData: Pointer) => {\n const events = readWatchEventBatch(batchPtr);\n const handler = this.watchHandlers.get(Number(watchId));\n if (handler !== undefined && events.length > 0) {\n handler(events);\n }\n },\n {\n // an attempt to fix the bug that is kept unfixed in the zig version of bun :()\n // https://github.com/oven-sh/bun/issues/33840:\n //\n // watch_id is declared `ptr`, not `u64`: ABI-identical (one 64-bit\n // register), but u64 args make bun allocate a JSBigInt on the CALLING\n // (non-JS) thread, corrupting the JS heap\n args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],\n returns: FFIType.void,\n threadsafe: true,\n },\n );\n\n const registered = ffiSetWatchCallback(handle, jsCallback);\n if (!registered.ok) {\n jsCallback.close();\n return registered;\n }\n this.watchJsCallback = jsCallback;\n return { ok: true, value: undefined };\n }\n\n /**\n * Subscribe to filesystem changes matching `pattern` (glob, exact file,\n * or directory subtree). Omit the pattern to watch the entire indexed\n * tree. Normalized batches of up to 128 events are delivered on the JS event\n * loop, with each path appearing at most once. See `FileFinderApi.watch`.\n *\n * @example\n * ```typescript\n * const sub = finder.watch(\"**\\/*.ts\", (events) => {\n * for (const e of events) console.log(e.kind, e.path);\n * });\n * if (sub.ok) sub.value(); // unsubscribe\n *\n * // no pattern: everything under the indexed base path\n * const all = finder.watch((events) => console.log(events.length));\n * ```\n */\n watch(callback: WatchBatchCallback, options?: WatchOptions): Result<WatchUnsubscribe>;\n watch(\n pattern: string,\n callback: WatchBatchCallback,\n options?: WatchOptions,\n ): Result<WatchUnsubscribe>;\n watch(\n patternOrCallback: string | WatchBatchCallback,\n callbackOrOptions?: WatchBatchCallback | WatchOptions,\n maybeOptions?: WatchOptions,\n ): Result<WatchUnsubscribe> {\n // Overload shift: watch(cb, opts?) -> empty pattern = whole tree.\n const noPattern = typeof patternOrCallback === \"function\";\n const pattern = noPattern ? \"\" : patternOrCallback;\n const callback = noPattern\n ? patternOrCallback\n : (callbackOrOptions as WatchBatchCallback);\n const options = noPattern\n ? (callbackOrOptions as WatchOptions | undefined)\n : maybeOptions;\n\n if (typeof callback !== \"function\") {\n return err(\"watch callback must be a function\");\n }\n\n const guard = this.ensureAlive();\n if (!guard.ok) return guard;\n\n const trampoline = this.ensureWatchTrampoline(guard.value);\n if (!trampoline.ok) return trampoline;\n\n const result = ffiWatch(guard.value, pattern, options?.ignore ?? []);\n if (!result.ok) return result;\n\n // No startup race: the threadsafe trampoline only runs on the JS event\n // loop, so this synchronous set always precedes the first routing lookup.\n const watchId = result.value;\n this.watchHandlers.set(watchId, callback);\n\n return { ok: true, value: () => this.unwatchById(watchId) };\n }\n\n /**\n * Remove a subscription from the routing map, then from the native side.\n * Map removal is synchronous on the JS thread, so once this returns the\n * handler can never run again (late native batches miss the lookup).\n * Idempotent.\n */\n private unwatchById(watchId: number): void {\n if (!this.watchHandlers.delete(watchId)) return;\n if (this.handle !== null) {\n ffiUnwatch(this.handle, watchId);\n }\n }\n\n /**\n * Get health check information.\n *\n * Useful for debugging and verifying the file finder is working correctly.\n *\n * @param testPath - Optional path to test git repository detection\n */\n healthCheck(testPath?: string): Result<HealthCheck> {\n return ffiHealthCheck(this.handle, testPath || \"\") as Result<HealthCheck>;\n }\n\n /**\n * Check if the native library is available.\n */\n static isAvailable(): boolean {\n return isAvailable();\n }\n\n /** Ensure the native library is loaded. */\n static ensureLoaded(): void {\n ensureLoaded();\n }\n\n /**\n * Get a health check without requiring an instance.\n *\n * Returns limited info (version + git only, no picker/frecency/query data).\n *\n * @param testPath - Optional path to test git repository detection\n */\n static healthCheckStatic(testPath?: string): Result<HealthCheck> {\n return ffiHealthCheck(null, testPath || \"\") as Result<HealthCheck>;\n }\n}\n",
8
+ "/**\n * Bun FFI bindings for the fff-c native library\n *\n * This module uses Bun's native FFI to call into the Rust C library.\n * All functions follow the Result pattern for error handling.\n *\n * The API is instance-based: `ffiCreate` returns an opaque handle that must\n * be passed to all subsequent calls and freed with `ffiDestroy`.\n */\n\nimport {\n CString,\n dlopen,\n FFIType,\n type JSCallback,\n type Pointer,\n ptr,\n read,\n} from \"bun:ffi\";\nimport { findBinary } from \"./download\";\nimport { embeddedLibPath } from \"./embedded\";\nimport type {\n DirItem,\n DirSearchResult,\n FileItem,\n GrepMatch,\n GrepResult,\n Location,\n MixedItem,\n MixedSearchResult,\n Result,\n ScanProgress,\n Score,\n SearchResult,\n WatchEvent,\n WatchEventKind,\n} from \"./fff-api\";\nimport { createGrepCursor, err } from \"./fff-api\";\n\n/** Grep mode constants matching the C API (u8). */\nconst GREP_MODE_PLAIN = 0;\nconst GREP_MODE_REGEX = 1;\nconst GREP_MODE_FUZZY = 2;\n\n/** Map string mode to u8 */\nfunction grepModeToU8(mode?: string): number {\n switch (mode) {\n case \"regex\":\n return GREP_MODE_REGEX;\n case \"fuzzy\":\n return GREP_MODE_FUZZY;\n default:\n return GREP_MODE_PLAIN;\n }\n}\n\nconst ffiDefinition = {\n fff_create_instance2: {\n args: [\n FFIType.cstring, // base_path\n FFIType.cstring, // frecency_db_path\n FFIType.cstring, // history_db_path\n FFIType.bool, // use_unsafe_no_lock\n FFIType.bool, // enable_mmap_cache\n FFIType.bool, // enable_content_indexing\n FFIType.bool, // watch\n FFIType.bool, // ai_mode\n FFIType.cstring, // log_file_path\n FFIType.cstring, // log_level\n FFIType.u64, // cache_budget_max_files\n FFIType.u64, // cache_budget_max_bytes\n FFIType.u64, // cache_budget_max_file_size\n ],\n returns: FFIType.ptr,\n },\n fff_create_instance_with: {\n args: [FFIType.ptr], // *const FffCreateOptions\n returns: FFIType.ptr,\n },\n fff_destroy: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n\n // Search\n fff_search: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n FFIType.i32, // combo_boost_multiplier\n FFIType.u32, // min_combo_count\n ],\n returns: FFIType.ptr,\n },\n\n // Glob-only search (bypasses query parser)\n fff_glob: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // pattern\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n ],\n returns: FFIType.ptr,\n },\n\n // Directory search\n fff_search_directories: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n ],\n returns: FFIType.ptr,\n },\n\n // Mixed search (files + directories)\n fff_search_mixed: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.cstring, // current_file\n FFIType.u32, // max_threads\n FFIType.u32, // page_index\n FFIType.u32, // page_size\n FFIType.i32, // combo_boost_multiplier\n FFIType.u32, // min_combo_count\n ],\n returns: FFIType.ptr,\n },\n\n // Live grep (content search)\n fff_live_grep_ex: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // query\n FFIType.u8, // mode\n FFIType.u64, // max_file_size\n FFIType.u32, // max_matches_per_file\n FFIType.bool, // smart_case\n FFIType.u32, // file_offset\n FFIType.u32, // page_limit\n FFIType.u64, // time_budget_ms\n FFIType.bool, // enforce_time_budget\n FFIType.u32, // before_context\n FFIType.u32, // after_context\n FFIType.bool, // classify_definitions\n ],\n returns: FFIType.ptr,\n },\n\n // Multi-pattern grep (Aho-Corasick)\n fff_multi_grep_ex: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // patterns_joined (\\n-separated)\n FFIType.cstring, // constraints\n FFIType.u64, // max_file_size\n FFIType.u32, // max_matches_per_file\n FFIType.bool, // smart_case\n FFIType.u32, // file_offset\n FFIType.u32, // page_limit\n FFIType.u64, // time_budget_ms\n FFIType.bool, // enforce_time_budget\n FFIType.u32, // before_context\n FFIType.u32, // after_context\n FFIType.bool, // classify_definitions\n ],\n returns: FFIType.ptr,\n },\n\n // File index\n fff_scan_files: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_is_scanning: {\n args: [FFIType.ptr],\n returns: FFIType.bool,\n },\n fff_get_base_path: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_get_scan_progress: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n fff_wait_for_scan: {\n args: [FFIType.ptr, FFIType.u64],\n returns: FFIType.ptr,\n },\n fff_restart_index: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n\n // Watch subscriptions\n fff_set_watch_callback: {\n args: [\n FFIType.ptr, // handle\n FFIType.function, // FffWatchCallback (instance-wide)\n FFIType.ptr, // user_data\n ],\n returns: FFIType.ptr,\n },\n fff_watch: {\n args: [\n FFIType.ptr, // handle\n FFIType.cstring, // pattern\n FFIType.ptr, // *const FffWatchOptions (or NULL)\n ],\n returns: FFIType.ptr,\n },\n fff_unwatch: {\n args: [FFIType.ptr, FFIType.u64], // handle, watch_id\n returns: FFIType.ptr,\n },\n fff_free_watch_events: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_watch_events_count: {\n args: [FFIType.ptr],\n returns: FFIType.u32,\n },\n fff_watch_events_get_path: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_watch_events_get_kind: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.u8,\n },\n\n // Git\n fff_refresh_git_status: {\n args: [FFIType.ptr],\n returns: FFIType.ptr,\n },\n\n // Query tracking\n fff_track_query: {\n args: [FFIType.ptr, FFIType.cstring, FFIType.cstring],\n returns: FFIType.ptr,\n },\n fff_get_historical_query: {\n args: [FFIType.ptr, FFIType.u64],\n returns: FFIType.ptr,\n },\n\n // Utilities\n fff_health_check: {\n args: [FFIType.ptr, FFIType.cstring],\n returns: FFIType.ptr,\n },\n\n // Search result accessors / free\n fff_free_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Dir search result accessors / free\n fff_free_dir_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_dir_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_dir_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Mixed search result accessors / free\n fff_free_mixed_search_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_mixed_search_result_get_item: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n fff_mixed_search_result_get_score: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Grep result accessors / free\n fff_free_grep_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_grep_result_get_match: {\n args: [FFIType.ptr, FFIType.u32],\n returns: FFIType.ptr,\n },\n\n // Memory management\n fff_free_result: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_free_string: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n fff_free_scan_progress: {\n args: [FFIType.ptr],\n returns: FFIType.void,\n },\n} as const;\n\ntype FFFLibrary = ReturnType<typeof dlopen<typeof ffiDefinition>>;\n\nlet lib: FFFLibrary | null = null;\n\n/**\n * Load the native library\n */\nfunction loadLibrary(): FFFLibrary {\n if (lib) return lib;\n\n const isEmbedded = embeddedLibPath?.includes(\"$bunfs\") ?? false;\n const binaryPath = isEmbedded ? embeddedLibPath : (findBinary() ?? embeddedLibPath);\n if (!binaryPath) {\n throw new Error(libNotFoundMessage());\n }\n\n lib = dlopen(binaryPath, ffiDefinition);\n return lib;\n}\n\nfunction libNotFoundMessage(): string {\n if (import.meta.url.includes(\"$bunfs\")) {\n if (process.platform === \"linux\") {\n return [\n \"You are running bun --compile with fff native library which CAN NOT resolve a binary\",\n \"On Linux the libc must be supplied at compile time so the native lib is bundled.\",\n \"Rebuild with:\",\n \" bun build --compile --define FFF_LIBC='\\\"gnu\\\"' ... # glibc\",\n \" bun build --compile --define FFF_LIBC='\\\"musl\\\"' ... # musl / Alpine\",\n ].join(\"\\n\");\n }\n\n return \"fff native library was not embedded into this executable. Rebuild with `bun build --compile` and ensure the @ff-labs/fff-bin-* package for this platform is installed.\";\n }\n\n return \"fff native library not found. Build from source with `cargo build --release -p fff-c` or install the platform package.\";\n}\n\n/**\n * Encode a string for FFI (null-terminated)\n */\nfunction encodeString(s: string): Uint8Array {\n return new TextEncoder().encode(`${s}\\0`);\n}\n\n/**\n * Read a C string from a pointer\n * Note: read.ptr() returns number but CString expects Pointer - we cast through unknown\n */\nfunction readCString(pointer: Pointer | number | null): string | null {\n if (pointer === null || pointer === 0) return null;\n // CString constructor accepts Pointer, but read.ptr returns number\n // Cast through unknown for runtime compatibility\n return new CString(pointer as unknown as Pointer).toString();\n}\n\n/**\n * Convert snake_case keys to camelCase recursively\n */\nfunction snakeToCamel(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(snakeToCamel);\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n result[camelKey] = snakeToCamel(value);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// FffResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { success: bool(1+7pad), error: *char(8), handle: *void(8), int_value: i64(8) }\n// ---------------------------------------------------------------------------\nconst RES_SUCCESS = 0; // bool (1 + 7 padding)\nconst RES_ERROR = 8; // *mut c_char (8)\nconst RES_HANDLE = 16; // *mut c_void (8)\nconst RES_INT_VALUE = 24; // i64 (8)\n\n// MUST match `crates/fff-c/src/ffi_types.rs::FffCreateOptions`\nconst FFF_CREATE_OPTIONS_VERSION = 1;\nconst FFF_CREATE_OPTIONS_SIZE = 88;\nconst FCO_VERSION = 0;\nconst FCO_BASE_PATH = 8;\nconst FCO_FRECENCY_DB_PATH = 16;\nconst FCO_HISTORY_DB_PATH = 24;\nconst FCO_ENABLE_MMAP_CACHE = 32;\nconst FCO_ENABLE_CONTENT_INDEXING = 33;\nconst FCO_WATCH = 34;\nconst FCO_AI_MODE = 35;\nconst FCO_LOG_FILE_PATH = 40;\nconst FCO_LOG_LEVEL = 48;\nconst FCO_CACHE_BUDGET_MAX_FILES = 56;\nconst FCO_CACHE_BUDGET_MAX_BYTES = 64;\nconst FCO_CACHE_BUDGET_MAX_FILE_SIZE = 72;\nconst FCO_ENABLE_FS_ROOT_SCANNING = 80;\nconst FCO_ENABLE_HOME_DIR_SCANNING = 81;\n\nfunction readResultEnvelope(\n resultPtr: Pointer | null,\n): { success: true; handlePtr: number; intValue: number } | Result<never> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const success = read.u8(resultPtr, RES_SUCCESS) !== 0;\n const library = loadLibrary();\n\n if (!success) {\n const errorPtr = read.ptr(resultPtr, RES_ERROR);\n const errorMsg = readCString(errorPtr) || \"Unknown error\";\n library.symbols.fff_free_result(resultPtr);\n return err(errorMsg);\n }\n\n const handlePtr = read.ptr(resultPtr, RES_HANDLE);\n const intValue = Number(read.i64(resultPtr, RES_INT_VALUE));\n library.symbols.fff_free_result(resultPtr);\n return { success: true, handlePtr, intValue };\n}\n\n/** Parse a FffResult that carries a bool in int_value (0 = false, nonzero = true). */\nfunction parseBoolResult(resultPtr: Pointer | null): Result<boolean> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: envelope.intValue !== 0 };\n}\n\n/** Parse a FffResult that carries an integer in int_value. */\nfunction parseIntResult(resultPtr: Pointer | null): Result<number> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: envelope.intValue };\n}\n\n/** Parse a FffResult that carries a string in handle (freed with fff_free_string). */\nfunction parseStringResult(resultPtr: Pointer | null): Result<string | null> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) return { ok: true, value: null };\n\n const library = loadLibrary();\n const str = readCString(envelope.handlePtr);\n library.symbols.fff_free_string(asPtr(envelope.handlePtr));\n return { ok: true, value: str };\n}\n\n/** Parse a FffResult that carries a JSON string in handle. */\nfunction parseJsonResult<T>(resultPtr: Pointer | null): Result<T> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) return { ok: true, value: undefined as T };\n\n const library = loadLibrary();\n const jsonStr = readCString(envelope.handlePtr);\n library.symbols.fff_free_string(asPtr(envelope.handlePtr));\n\n if (jsonStr === null || jsonStr === \"\") return { ok: true, value: undefined as T };\n\n try {\n return { ok: true, value: snakeToCamel(JSON.parse(jsonStr)) as T };\n } catch {\n return { ok: true, value: jsonStr as T };\n }\n}\n\n/** Parse a FffResult with no payload (void, success/error only). */\nfunction parseVoidResult(resultPtr: Pointer | null): Result<void> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n return { ok: true, value: undefined };\n}\n\n/**\n * Opaque native handle type. Callers must not inspect or modify this value.\n */\nexport type NativeHandle = Pointer;\n\n/**\n * Create a new file finder instance.\n *\n * Hand-encodes a [`FffCreateOptions`] struct (88 bytes, locked offsets — see\n * `crates/fff-c/src/ffi_types.rs::options_layout_tests`) into a Buffer and\n * passes its pointer to `fff_create_instance_with`. Inner cstring addresses\n * come from Bun's native `ptr(buffer)` primitive — no round-trip helpers,\n * no struct support gaps.\n *\n * Adding new options later means: (1) appending the field to\n * `FffCreateOptions` in Rust, (2) bumping `FFF_CREATE_OPTIONS_VERSION`,\n * (3) extending `FFF_CREATE_OPTIONS_SIZE` + offsets here. The C entry point\n * never changes.\n */\nexport function ffiCreate(\n basePath: string,\n frecencyDbPath: string,\n historyDbPath: string,\n _useUnsafeNoLock: boolean,\n enableMmapCache: boolean,\n enableContentIndexing: boolean,\n watch: boolean,\n aiMode: boolean,\n logFilePath: string,\n logLevel: string,\n cacheBudgetMaxFiles: bigint,\n cacheBudgetMaxBytes: bigint,\n cacheBudgetMaxFileSize: bigint,\n enableFsRootScanning: boolean,\n enableHomeDirScanning: boolean,\n): Result<NativeHandle> {\n const library = loadLibrary();\n\n // Keep cstring buffers alive across the FFI call. Bun's `ptr()` returns\n // the underlying memory address of each Buffer — no round-trips.\n const basePathCStr = encodeCStringBuf(basePath);\n const frecencyCStr = encodeCStringBuf(frecencyDbPath);\n const historyCStr = encodeCStringBuf(historyDbPath);\n const logFileCStr = encodeCStringBuf(logFilePath);\n const logLevelCStr = encodeCStringBuf(logLevel);\n\n const opts = Buffer.alloc(FFF_CREATE_OPTIONS_SIZE);\n opts.writeUInt32LE(FFF_CREATE_OPTIONS_VERSION, FCO_VERSION);\n writePtrLE(opts, FCO_BASE_PATH, basePathCStr);\n writePtrLE(opts, FCO_FRECENCY_DB_PATH, frecencyCStr);\n writePtrLE(opts, FCO_HISTORY_DB_PATH, historyCStr);\n opts.writeUInt8(enableMmapCache ? 1 : 0, FCO_ENABLE_MMAP_CACHE);\n opts.writeUInt8(enableContentIndexing ? 1 : 0, FCO_ENABLE_CONTENT_INDEXING);\n opts.writeUInt8(watch ? 1 : 0, FCO_WATCH);\n opts.writeUInt8(aiMode ? 1 : 0, FCO_AI_MODE);\n writePtrLE(opts, FCO_LOG_FILE_PATH, logFileCStr);\n writePtrLE(opts, FCO_LOG_LEVEL, logLevelCStr);\n opts.writeBigUInt64LE(cacheBudgetMaxFiles, FCO_CACHE_BUDGET_MAX_FILES);\n opts.writeBigUInt64LE(cacheBudgetMaxBytes, FCO_CACHE_BUDGET_MAX_BYTES);\n opts.writeBigUInt64LE(cacheBudgetMaxFileSize, FCO_CACHE_BUDGET_MAX_FILE_SIZE);\n opts.writeUInt8(enableFsRootScanning ? 1 : 0, FCO_ENABLE_FS_ROOT_SCANNING);\n opts.writeUInt8(enableHomeDirScanning ? 1 : 0, FCO_ENABLE_HOME_DIR_SCANNING);\n\n const resultPtr = library.symbols.fff_create_instance_with(ptr(opts));\n\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const success = read.u8(resultPtr, RES_SUCCESS) !== 0;\n\n if (success) {\n const handlePtr = read.ptr(resultPtr, RES_HANDLE);\n const handle = handlePtr as unknown as Pointer;\n library.symbols.fff_free_result(resultPtr);\n\n if (!handle || handle === (0 as unknown as Pointer)) {\n return err(\"fff_create_instance_with returned null handle\");\n }\n\n return { ok: true, value: handle };\n } else {\n const errorPtr = read.ptr(resultPtr, RES_ERROR);\n const errorMsg = readCString(errorPtr) || \"Unknown error\";\n library.symbols.fff_free_result(resultPtr);\n return err(errorMsg);\n }\n}\n\n/** NUL-terminated UTF-8 buffer for `s`, or `null` for empty input. */\nfunction encodeCStringBuf(s: string | null | undefined): Buffer | null {\n if (!s) return null;\n return Buffer.from(s + \"\\0\", \"utf-8\");\n}\n\n/** Write Bun's native pointer-to-buffer address into the options buffer. */\nfunction writePtrLE(buf: Buffer, offset: number, target: Buffer | null): void {\n if (target == null) {\n buf.writeBigUInt64LE(0n, offset);\n return;\n }\n buf.writeBigUInt64LE(BigInt(ptr(target) as unknown as number), offset);\n}\n\n/**\n * Destroy and clean up an instance.\n */\nexport function ffiDestroy(handle: NativeHandle): void {\n const library = loadLibrary();\n library.symbols.fff_destroy(handle);\n}\n\n// ---------------------------------------------------------------------------\n// Struct byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// FffSearchResult { items: *mut, scores: *mut, count: u32, total_matched: u32, total_files: u32, location: FffLocation }\nconst SR_ITEMS = 0; // *mut FffFileItem (8)\nconst SR_SCORES = 8; // *mut FffScore (8)\nconst SR_COUNT = 16; // u32 (4)\nconst SR_MATCHED = 20; // u32 (4)\nconst SR_TOTAL = 24; // u32 (4)\n// FffLocation is inlined at offset 28\nconst SR_LOC_TAG = 28; // u8 (1 + 3 padding)\nconst SR_LOC_LINE = 32; // i32 (4)\nconst SR_LOC_COL = 36; // i32 (4)\nconst SR_LOC_END_LINE = 40; // i32 (4)\nconst SR_LOC_END_COL = 44; // i32 (4)\n\n// FffFileItem (72 bytes)\nconst FI_RELPATH = 0; // *mut c_char (8)\nconst FI_FNAME = 8; // *mut c_char (8)\nconst FI_GIT = 16; // *mut c_char (8)\nconst FI_SIZE = 24; // u64 (8)\nconst FI_MODIFIED = 32; // u64 (8)\nconst FI_ACCESS = 40; // i64 (8)\nconst FI_MODFR = 48; // i64 (8)\nconst FI_TOTAL_FR = 56; // i64 (8)\nconst FI_SIZE_OF = 72;\n\n// FffScore (48 bytes)\nconst SC_TOTAL = 0; // i32 (4)\nconst SC_BASE = 4; // i32 (4)\nconst SC_FNAME = 8; // i32 (4)\nconst SC_SPECIAL = 12; // i32 (4)\nconst SC_FREC = 16; // i32 (4)\nconst SC_DIST = 20; // i32 (4)\nconst SC_CURFILE = 24; // i32 (4)\nconst SC_COMBO = 28; // i32 (4)\nconst SC_EXACT = 32; // bool (1 + 7 pad)\nconst SC_MTYPE = 40; // *mut c_char (8)\nconst SC_SIZE_OF = 48;\n\n/** Cast a number (raw address from pointer math) to Pointer for read.*. */\nfunction asPtr(n: number): Pointer {\n return n as unknown as Pointer;\n}\n\n/**\n * Read an FffFileItem struct at the given raw address.\n */\nfunction readFileItemStruct(p: number): FileItem {\n const pp = asPtr(p);\n return {\n relativePath: readCString(read.ptr(pp, FI_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, FI_FNAME)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, FI_GIT)) ?? \"\",\n size: Number(read.u64(pp, FI_SIZE)),\n modified: Number(read.u64(pp, FI_MODIFIED)),\n accessFrecencyScore: Number(read.i64(pp, FI_ACCESS)),\n modificationFrecencyScore: Number(read.i64(pp, FI_MODFR)),\n totalFrecencyScore: Number(read.i64(pp, FI_TOTAL_FR)),\n };\n}\n\n/**\n * Read an FffScore struct at the given raw address.\n */\nfunction readScoreStruct(p: number): Score {\n const pp = asPtr(p);\n return {\n total: read.i32(pp, SC_TOTAL),\n baseScore: read.i32(pp, SC_BASE),\n filenameBonus: read.i32(pp, SC_FNAME),\n specialFilenameBonus: read.i32(pp, SC_SPECIAL),\n frecencyBoost: read.i32(pp, SC_FREC),\n distancePenalty: read.i32(pp, SC_DIST),\n currentFilePenalty: read.i32(pp, SC_CURFILE),\n comboMatchBoost: read.i32(pp, SC_COMBO),\n exactMatch: read.u8(pp, SC_EXACT) !== 0,\n matchType: readCString(read.ptr(pp, SC_MTYPE)) ?? \"\",\n };\n}\n\n/**\n * Parse an FffSearchResult from a raw pointer, then free native memory.\n */\nfunction parseSearchResult(resultPtr: Pointer | null): Result<SearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, SR_COUNT);\n const totalMatched = read.u32(hp, SR_MATCHED);\n const totalFiles = read.u32(hp, SR_TOTAL);\n const itemsBase = read.ptr(hp, SR_ITEMS);\n const scoresBase = read.ptr(hp, SR_SCORES);\n\n // Read location\n const locTag = read.u8(hp, SR_LOC_TAG);\n let location: Location | undefined;\n if (locTag === 1) {\n location = { type: \"line\", line: read.i32(hp, SR_LOC_LINE) };\n } else if (locTag === 2) {\n location = {\n type: \"position\",\n line: read.i32(hp, SR_LOC_LINE),\n col: read.i32(hp, SR_LOC_COL),\n };\n } else if (locTag === 3) {\n location = {\n type: \"range\",\n start: { line: read.i32(hp, SR_LOC_LINE), col: read.i32(hp, SR_LOC_COL) },\n end: {\n line: read.i32(hp, SR_LOC_END_LINE),\n col: read.i32(hp, SR_LOC_END_COL),\n },\n };\n }\n\n // Read items and scores arrays using pointer arithmetic\n const items: FileItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n items.push(readFileItemStruct(itemsBase + i * FI_SIZE_OF));\n scores.push(readScoreStruct(scoresBase + i * SC_SIZE_OF));\n }\n\n // Free native search result\n loadLibrary().symbols.fff_free_search_result(hp);\n\n const result: SearchResult = { items, scores, totalMatched, totalFiles };\n if (location) {\n result.location = location;\n }\n return { ok: true, value: result };\n}\n\n// ---------------------------------------------------------------------------\n// FffDirSearchResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { items: *mut, scores: *mut, count: u32, total_matched: u32, total_dirs: u32 }\n// ---------------------------------------------------------------------------\nconst DSR_COUNT = 16; // u32 (4)\nconst DSR_MATCHED = 20; // u32 (4)\nconst DSR_TOTAL_DIRS = 24; // u32 (4)\n\n// FffDirItem (24 bytes: 8 + 8 + 4 + 4pad)\nconst DI_RELPATH = 0; // *mut c_char (8)\nconst DI_DIRNAME = 8; // *mut c_char (8)\nconst DI_MAX_FRECENCY = 16; // i32 (4)\n\n/**\n * Read an FffDirItem struct at the given raw address.\n */\nfunction readDirItemStruct(p: number): DirItem {\n const pp = asPtr(p);\n return {\n relativePath: readCString(read.ptr(pp, DI_RELPATH)) ?? \"\",\n dirName: readCString(read.ptr(pp, DI_DIRNAME)) ?? \"\",\n maxAccessFrecency: read.i32(pp, DI_MAX_FRECENCY),\n };\n}\n\n/**\n * Parse an FffDirSearchResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseDirSearchResult(resultPtr: Pointer | null): Result<DirSearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search_directories returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, DSR_COUNT);\n const totalMatched = read.u32(hp, DSR_MATCHED);\n const totalDirs = read.u32(hp, DSR_TOTAL_DIRS);\n\n const library = loadLibrary();\n\n const items: DirItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n const itemPtr = library.symbols.fff_dir_search_result_get_item(hp, i);\n if (itemPtr !== null && (itemPtr as unknown as number) !== 0) {\n items.push(readDirItemStruct(itemPtr as unknown as number));\n }\n const scorePtr = library.symbols.fff_dir_search_result_get_score(hp, i);\n if (scorePtr !== null && (scorePtr as unknown as number) !== 0) {\n scores.push(readScoreStruct(scorePtr as unknown as number));\n }\n }\n\n // Free native dir search result\n library.symbols.fff_free_dir_search_result(hp);\n\n return { ok: true, value: { items, scores, totalMatched, totalDirs } };\n}\n\n// ---------------------------------------------------------------------------\n// FffMixedSearchResult byte offsets (must match #[repr(C)] layout on 64-bit)\n// { items: *mut, scores: *mut, count: u32, total_matched: u32, total_files: u32, total_dirs: u32, location: FffLocation }\n// ---------------------------------------------------------------------------\nconst MSR_COUNT = 16; // u32 (4)\nconst MSR_MATCHED = 20; // u32 (4)\nconst MSR_TOTAL_FILES = 24; // u32 (4)\nconst MSR_TOTAL_DIRS = 28; // u32 (4)\n// FffLocation is inlined at offset 32\nconst MSR_LOC_TAG = 32; // u8 (1 + 3 padding)\nconst MSR_LOC_LINE = 36; // i32 (4)\nconst MSR_LOC_COL = 40; // i32 (4)\nconst MSR_LOC_END_LINE = 44; // i32 (4)\nconst MSR_LOC_END_COL = 48; // i32 (4)\n\n// FffMixedItem (80 bytes)\nconst MI_TYPE = 0; // u8 (1 + 7 pad)\nconst MI_RELPATH = 8; // *mut c_char (8)\nconst MI_DISPLAY = 16; // *mut c_char (8)\nconst MI_GIT = 24; // *mut c_char (8)\nconst MI_SIZE = 32; // u64 (8)\nconst MI_MODIFIED = 40; // u64 (8)\nconst MI_ACCESS = 48; // i64 (8)\nconst MI_MODFR = 56; // i64 (8)\nconst MI_TOTAL_FR = 64; // i64 (8)\n\n/**\n * Read an FffMixedItem struct at the given raw address and return a MixedItem.\n */\nfunction readMixedItemStruct(p: number): MixedItem {\n const pp = asPtr(p);\n const itemType = read.u8(pp, MI_TYPE);\n\n if (itemType === 1) {\n // Directory\n return {\n type: \"directory\",\n item: {\n relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? \"\",\n dirName: readCString(read.ptr(pp, MI_DISPLAY)) ?? \"\",\n maxAccessFrecency: Number(read.i64(pp, MI_ACCESS)),\n },\n };\n }\n\n // File (itemType === 0)\n return {\n type: \"file\",\n item: {\n relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, MI_DISPLAY)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, MI_GIT)) ?? \"\",\n size: Number(read.u64(pp, MI_SIZE)),\n modified: Number(read.u64(pp, MI_MODIFIED)),\n accessFrecencyScore: Number(read.i64(pp, MI_ACCESS)),\n modificationFrecencyScore: Number(read.i64(pp, MI_MODFR)),\n totalFrecencyScore: Number(read.i64(pp, MI_TOTAL_FR)),\n },\n };\n}\n\n/**\n * Parse an FffMixedSearchResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseMixedSearchResult(resultPtr: Pointer | null): Result<MixedSearchResult> {\n if (resultPtr === null) {\n return err(\"FFI returned null pointer\");\n }\n\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"fff_search_mixed returned null search result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, MSR_COUNT);\n const totalMatched = read.u32(hp, MSR_MATCHED);\n const totalFiles = read.u32(hp, MSR_TOTAL_FILES);\n const totalDirs = read.u32(hp, MSR_TOTAL_DIRS);\n\n // Read location\n const locTag = read.u8(hp, MSR_LOC_TAG);\n let location: Location | undefined;\n if (locTag === 1) {\n location = { type: \"line\", line: read.i32(hp, MSR_LOC_LINE) };\n } else if (locTag === 2) {\n location = {\n type: \"position\",\n line: read.i32(hp, MSR_LOC_LINE),\n col: read.i32(hp, MSR_LOC_COL),\n };\n } else if (locTag === 3) {\n location = {\n type: \"range\",\n start: {\n line: read.i32(hp, MSR_LOC_LINE),\n col: read.i32(hp, MSR_LOC_COL),\n },\n end: {\n line: read.i32(hp, MSR_LOC_END_LINE),\n col: read.i32(hp, MSR_LOC_END_COL),\n },\n };\n }\n\n const library = loadLibrary();\n\n const items: MixedItem[] = [];\n const scores: Score[] = [];\n\n for (let i = 0; i < count; i++) {\n const itemPtr = library.symbols.fff_mixed_search_result_get_item(hp, i);\n if (itemPtr !== null && (itemPtr as unknown as number) !== 0) {\n items.push(readMixedItemStruct(itemPtr as unknown as number));\n }\n const scorePtr = library.symbols.fff_mixed_search_result_get_score(hp, i);\n if (scorePtr !== null && (scorePtr as unknown as number) !== 0) {\n scores.push(readScoreStruct(scorePtr as unknown as number));\n }\n }\n\n // Free native mixed search result\n library.symbols.fff_free_mixed_search_result(hp);\n\n const result: MixedSearchResult = {\n items,\n scores,\n totalMatched,\n totalFiles,\n totalDirs,\n };\n if (location) {\n result.location = location;\n }\n return { ok: true, value: result };\n}\n\n// ---------------------------------------------------------------------------\n// FffGrepMatch byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// Pointers (8 bytes each)\nconst GM_RELPATH = 0;\nconst GM_FNAME = 8;\nconst GM_GIT = 16;\nconst GM_LINE_CONTENT = 24;\nconst GM_MATCH_RANGES = 32;\nconst GM_CTX_BEFORE = 40;\nconst GM_CTX_AFTER = 48;\n\n// 8-byte numeric fields\nconst GM_SIZE = 56;\nconst GM_MODIFIED = 64;\nconst GM_TOTAL_FR = 72;\nconst GM_ACCESS_FR = 80;\nconst GM_MOD_FR = 88;\nconst GM_LINE_NUM = 96;\nconst GM_BYTE_OFF = 104;\n\n// 4-byte fields\nconst GM_COL = 112;\nconst GM_MR_COUNT = 116;\nconst GM_CTX_B_COUNT = 120;\nconst GM_CTX_A_COUNT = 124;\n\n// 2-byte\nconst GM_FUZZY_SCORE = 128;\n// 1-byte\nconst GM_HAS_FUZZY = 130;\nconst GM_IS_BINARY = 131;\nconst GM_IS_DEFINITION = 132;\n\n// struct size: pad to 8-byte alignment → 136\nconst GM_SIZE_OF = 136;\n\n// FffGrepResult\nconst GR_ITEMS = 0; // *mut FffGrepMatch (8)\nconst GR_COUNT = 8; // u32 (4)\nconst GR_MATCHED = 12; // u32 (4)\nconst GR_FILES_SEARCHED = 16; // u32 (4)\nconst GR_TOTAL_FILES = 20; // u32 (4)\nconst GR_FILTERED = 24; // u32 (4)\nconst GR_NEXT_OFFSET = 28; // u32 (4)\nconst GR_REGEX_ERR = 32; // *mut c_char (8)\n\n// FffMatchRange (8 bytes)\nconst MR_START = 0;\nconst MR_END = 4;\nconst MR_SIZE = 8;\n\n/**\n * Read a C string array (char**) at the given pointer, with `count` elements.\n */\nfunction readCStringArray(base: number, count: number): string[] {\n if (count === 0 || base === 0) return [];\n const result: string[] = [];\n const bp = asPtr(base);\n for (let i = 0; i < count; i++) {\n const strPtr = read.ptr(bp, i * 8); // each pointer is 8 bytes\n result.push(readCString(strPtr) ?? \"\");\n }\n return result;\n}\n\n/**\n * Read an FffGrepMatch struct at the given raw address.\n */\nfunction readGrepMatchStruct(p: number): GrepMatch {\n const pp = asPtr(p);\n const matchRangesPtr = read.ptr(pp, GM_MATCH_RANGES);\n const matchRangesCount = read.u32(pp, GM_MR_COUNT);\n const matchRanges: [number, number][] = [];\n for (let i = 0; i < matchRangesCount; i++) {\n const base = matchRangesPtr + i * MR_SIZE;\n const bp = asPtr(base);\n matchRanges.push([read.u32(bp, MR_START), read.u32(bp, MR_END)]);\n }\n\n const hasFuzzy = read.u8(pp, GM_HAS_FUZZY) !== 0;\n const ctxBeforeCount = read.u32(pp, GM_CTX_B_COUNT);\n const ctxAfterCount = read.u32(pp, GM_CTX_A_COUNT);\n\n const match: GrepMatch = {\n relativePath: readCString(read.ptr(pp, GM_RELPATH)) ?? \"\",\n fileName: readCString(read.ptr(pp, GM_FNAME)) ?? \"\",\n gitStatus: readCString(read.ptr(pp, GM_GIT)) ?? \"\",\n lineContent: readCString(read.ptr(pp, GM_LINE_CONTENT)) ?? \"\",\n size: Number(read.u64(pp, GM_SIZE)),\n modified: Number(read.u64(pp, GM_MODIFIED)),\n totalFrecencyScore: Number(read.i64(pp, GM_TOTAL_FR)),\n accessFrecencyScore: Number(read.i64(pp, GM_ACCESS_FR)),\n modificationFrecencyScore: Number(read.i64(pp, GM_MOD_FR)),\n isBinary: read.u8(pp, GM_IS_BINARY) !== 0,\n lineNumber: Number(read.u64(pp, GM_LINE_NUM)),\n col: read.u32(pp, GM_COL),\n byteOffset: Number(read.u64(pp, GM_BYTE_OFF)),\n matchRanges,\n };\n\n if (hasFuzzy) {\n match.fuzzyScore = read.u16(pp, GM_FUZZY_SCORE);\n }\n if (ctxBeforeCount > 0) {\n match.contextBefore = readCStringArray(read.ptr(pp, GM_CTX_BEFORE), ctxBeforeCount);\n }\n if (ctxAfterCount > 0) {\n match.contextAfter = readCStringArray(read.ptr(pp, GM_CTX_AFTER), ctxAfterCount);\n }\n if (read.u8(pp, GM_IS_DEFINITION) !== 0) {\n match.isDefinition = true;\n }\n\n return match;\n}\n\n/**\n * Parse an FffGrepResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseGrepResult(resultPtr: Pointer | null): Result<GrepResult> {\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"grep returned null result\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const count = read.u32(hp, GR_COUNT);\n const totalMatched = read.u32(hp, GR_MATCHED);\n const totalFilesSearched = read.u32(hp, GR_FILES_SEARCHED);\n const totalFiles = read.u32(hp, GR_TOTAL_FILES);\n const filteredFileCount = read.u32(hp, GR_FILTERED);\n const nextFileOffset = read.u32(hp, GR_NEXT_OFFSET);\n const regexErrPtr = read.ptr(hp, GR_REGEX_ERR);\n const regexFallbackError = readCString(regexErrPtr) ?? undefined;\n const itemsBase = read.ptr(hp, GR_ITEMS);\n\n const items: GrepMatch[] = [];\n for (let i = 0; i < count; i++) {\n items.push(readGrepMatchStruct(itemsBase + i * GM_SIZE_OF));\n }\n\n loadLibrary().symbols.fff_free_grep_result(hp);\n\n const grepResult: GrepResult = {\n items,\n totalMatched,\n totalFilesSearched,\n totalFiles,\n filteredFileCount,\n nextCursor: nextFileOffset > 0 ? createGrepCursor(nextFileOffset) : null,\n };\n if (regexFallbackError) {\n grepResult.regexFallbackError = regexFallbackError;\n }\n return { ok: true, value: grepResult };\n}\n\n/**\n * Perform fuzzy search.\n */\nexport function ffiSearch(\n handle: NativeHandle,\n query: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n comboBoostMultiplier: number,\n minComboCount: number,\n): Result<SearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n comboBoostMultiplier,\n minComboCount,\n );\n return parseSearchResult(resultPtr);\n}\n\n/**\n * Glob-only search. Bypasses the regular query parser, applies the pattern\n * as a single `Constraint::Glob`, ranks by frecency, paginates.\n */\nexport function ffiGlob(\n handle: NativeHandle,\n pattern: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n): Result<SearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_glob(\n handle,\n ptr(encodeString(pattern)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n );\n return parseSearchResult(resultPtr);\n}\n\n/**\n * Perform fuzzy directory search.\n */\nexport function ffiSearchDirectories(\n handle: NativeHandle,\n query: string,\n currentFile: string | null,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n): Result<DirSearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search_directories(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile ?? \"\")),\n maxThreads,\n pageIndex,\n pageSize,\n );\n return parseDirSearchResult(resultPtr);\n}\n\n/**\n * Perform mixed (files + directories) fuzzy search.\n */\nexport function ffiSearchMixed(\n handle: NativeHandle,\n query: string,\n currentFile: string,\n maxThreads: number,\n pageIndex: number,\n pageSize: number,\n comboBoostMultiplier: number,\n minComboCount: number,\n): Result<MixedSearchResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_search_mixed(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(currentFile)),\n maxThreads,\n pageIndex,\n pageSize,\n comboBoostMultiplier,\n minComboCount,\n );\n return parseMixedSearchResult(resultPtr);\n}\n\n/**\n * Live grep - search file contents.\n */\nexport function ffiLiveGrep(\n handle: NativeHandle,\n query: string,\n mode: string,\n maxFileSize: number,\n maxMatchesPerFile: number,\n smartCase: boolean,\n fileOffset: number,\n pageLimit: number,\n timeBudgetMs: number,\n enforceTimeBudget: boolean,\n beforeContext: number,\n afterContext: number,\n classifyDefinitions: boolean,\n): Result<GrepResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_live_grep_ex(\n handle,\n ptr(encodeString(query)),\n grepModeToU8(mode),\n BigInt(maxFileSize),\n maxMatchesPerFile,\n smartCase,\n fileOffset,\n pageLimit,\n BigInt(timeBudgetMs),\n enforceTimeBudget,\n beforeContext,\n afterContext,\n classifyDefinitions,\n );\n return parseGrepResult(resultPtr);\n}\n\n/**\n * Multi-pattern grep - Aho-Corasick multi-needle search.\n */\nexport function ffiMultiGrep(\n handle: NativeHandle,\n patternsJoined: string,\n constraints: string,\n maxFileSize: number,\n maxMatchesPerFile: number,\n smartCase: boolean,\n fileOffset: number,\n pageLimit: number,\n timeBudgetMs: number,\n enforceTimeBudget: boolean,\n beforeContext: number,\n afterContext: number,\n classifyDefinitions: boolean,\n): Result<GrepResult> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_multi_grep_ex(\n handle,\n ptr(encodeString(patternsJoined)),\n ptr(encodeString(constraints)),\n BigInt(maxFileSize),\n maxMatchesPerFile,\n smartCase,\n fileOffset,\n pageLimit,\n BigInt(timeBudgetMs),\n enforceTimeBudget,\n beforeContext,\n afterContext,\n classifyDefinitions,\n );\n return parseGrepResult(resultPtr);\n}\n\n/**\n * Trigger file scan.\n */\nexport function ffiScanFiles(handle: NativeHandle): Result<void> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_scan_files(handle);\n return parseVoidResult(resultPtr);\n}\n\n/**\n * Check if scanning.\n */\nexport function ffiIsScanning(handle: NativeHandle): boolean {\n const library = loadLibrary();\n return library.symbols.fff_is_scanning(handle) as boolean;\n}\n\n/**\n * Get the base path of the file picker.\n */\nexport function ffiGetBasePath(handle: NativeHandle): Result<string | null> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_base_path(handle);\n return parseStringResult(resultPtr);\n}\n\n// FffScanProgress { scanned_files_count: u64(8), is_scanning: bool(1), is_watcher_ready: bool(1), is_warmup_complete: bool(1) + pad }\nconst SP_COUNT = 0; // u64 (8)\nconst SP_SCANNING = 8; // bool (1)\nconst SP_WATCHER_READY = 9; // bool (1)\nconst SP_WARMUP_COMPLETE = 10; // bool (1)\n\n/**\n * Get scan progress.\n */\nexport function ffiGetScanProgress(handle: NativeHandle): Result<ScanProgress> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_scan_progress(handle);\n const envelope = readResultEnvelope(resultPtr);\n if (!(\"success\" in envelope)) return envelope;\n\n if (envelope.handlePtr === 0) {\n return err(\"scan progress returned null\");\n }\n\n const hp = asPtr(envelope.handlePtr);\n const result: ScanProgress = {\n scannedFilesCount: Number(read.u64(hp, SP_COUNT)),\n isScanning: read.u8(hp, SP_SCANNING) !== 0,\n isWatcherReady: read.u8(hp, SP_WATCHER_READY) !== 0,\n isWarmupComplete: read.u8(hp, SP_WARMUP_COMPLETE) !== 0,\n };\n library.symbols.fff_free_scan_progress(hp);\n return { ok: true, value: result };\n}\n\n/**\n * Wait for scan to complete.\n */\nexport function ffiWaitForScan(handle: NativeHandle, timeoutMs: number): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_wait_for_scan(handle, BigInt(timeoutMs));\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Restart index in new path.\n */\nexport function ffiRestartIndex(handle: NativeHandle, newPath: string): Result<void> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_restart_index(handle, ptr(encodeString(newPath)));\n return parseVoidResult(resultPtr);\n}\n\n// ---------------------------------------------------------------------------\n// Watch struct byte offsets (must match #[repr(C)] layout on 64-bit)\n// ---------------------------------------------------------------------------\n\n// MUST match `crates/fff-c`::FffWatchOptions\nconst FFF_WATCH_OPTIONS_VERSION = 1;\nconst FFF_WATCH_OPTIONS_SIZE = 24;\nconst FWO_VERSION = 0; // u32 (4 + 4 pad)\nconst FWO_IGNORE = 8; // *const *const c_char (8)\nconst FWO_IGNORE_COUNT = 16; // u32 (4 + 4 pad)\n\n/** kind u8 -> WatchEventKind. Unknown values degrade to \"rescan\". */\nconst WATCH_EVENT_KINDS: readonly WatchEventKind[] = [\n \"created\",\n \"modified\",\n \"removed\",\n \"rescan\",\n];\n\n/**\n * Parse an FffWatchEventBatch delivered to a watch callback, then free it.\n * Ownership of the batch transfers to JS at callback time, so this MUST be\n * called exactly once per delivered batch pointer.\n */\nexport function readWatchEventBatch(batchPtr: Pointer | number | null): WatchEvent[] {\n if (batchPtr === null || (batchPtr as unknown as number) === 0) {\n return [];\n }\n\n const bp = batchPtr as unknown as Pointer;\n const symbols = loadLibrary().symbols;\n const count = symbols.fff_watch_events_count(bp);\n\n const events: WatchEvent[] = [];\n for (let i = 0; i < count; i++) {\n const path = symbols.fff_watch_events_get_path(bp, i) as Pointer | null;\n const kind = symbols.fff_watch_events_get_kind(bp, i) as number;\n events.push({\n path: readCString(path) ?? \"\",\n kind: WATCH_EVENT_KINDS[kind] ?? \"rescan\",\n });\n }\n\n symbols.fff_free_watch_events(bp);\n return events;\n}\n\n/**\n * Register the instance-wide watch callback. Must be called before the\n * first `ffiWatch`. The caller owns `callback` (a threadsafe `JSCallback`\n * built in finder.ts) and must keep it alive until after `ffiDestroy`\n * returns for this handle — that call is the delivery quiescence barrier.\n */\nexport function ffiSetWatchCallback(\n handle: NativeHandle,\n callback: JSCallback,\n): Result<void> {\n const library = loadLibrary();\n if (callback.ptr === null) {\n return err(\"watch callback has been closed\");\n }\n const resultPtr = library.symbols.fff_set_watch_callback(handle, callback.ptr, null);\n return parseVoidResult(resultPtr);\n}\n\n/**\n * Subscribe to filesystem changes; batches are delivered through the\n * instance callback registered with `ffiSetWatchCallback`, tagged with the\n * watch id this function returns.\n *\n * @returns The native watch id carried in `FffResult.int_value`.\n */\nexport function ffiWatch(\n handle: NativeHandle,\n pattern: string,\n ignore: string[] = [],\n): Result<number> {\n const library = loadLibrary();\n\n // Keep every buffer referenced until the FFI call returns: the options\n // struct, the pointer array, and each encoded ignore string.\n const opts = Buffer.alloc(FFF_WATCH_OPTIONS_SIZE);\n opts.writeUInt32LE(FFF_WATCH_OPTIONS_VERSION, FWO_VERSION);\n\n const ignoreBuffers = ignore.map((entry) => encodeString(entry));\n const ignorePtrs = Buffer.alloc(Math.max(ignoreBuffers.length, 1) * 8);\n for (let i = 0; i < ignoreBuffers.length; i++) {\n ignorePtrs.writeBigUInt64LE(BigInt(ptr(ignoreBuffers[i] as Uint8Array)), i * 8);\n }\n opts.writeBigUInt64LE(\n ignoreBuffers.length > 0 ? BigInt(ptr(ignorePtrs)) : 0n,\n FWO_IGNORE,\n );\n opts.writeUInt32LE(ignoreBuffers.length, FWO_IGNORE_COUNT);\n\n const resultPtr = library.symbols.fff_watch(\n handle,\n ptr(encodeString(pattern)),\n ptr(opts),\n );\n return parseIntResult(resultPtr);\n}\n\n/**\n * Remove a watch subscription. Returns true if the id was found.\n */\nexport function ffiUnwatch(handle: NativeHandle, watchId: number): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_unwatch(handle, BigInt(watchId));\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Refresh git status.\n */\nexport function ffiRefreshGitStatus(handle: NativeHandle): Result<number> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_refresh_git_status(handle);\n return parseIntResult(resultPtr);\n}\n\n/**\n * Track query completion.\n */\nexport function ffiTrackQuery(\n handle: NativeHandle,\n query: string,\n filePath: string,\n): Result<boolean> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_track_query(\n handle,\n ptr(encodeString(query)),\n ptr(encodeString(filePath)),\n );\n return parseBoolResult(resultPtr);\n}\n\n/**\n * Get historical query.\n */\nexport function ffiGetHistoricalQuery(\n handle: NativeHandle,\n offset: number,\n): Result<string | null> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_get_historical_query(handle, BigInt(offset));\n return parseStringResult(resultPtr);\n}\n\n/**\n * Health check.\n *\n * `handle` can be null for a limited check (version + git only).\n */\nexport function ffiHealthCheck(\n handle: NativeHandle | null,\n testPath: string,\n): Result<unknown> {\n const library = loadLibrary();\n const resultPtr = library.symbols.fff_health_check(\n handle ?? (0 as unknown as Pointer),\n ptr(encodeString(testPath)),\n );\n return parseJsonResult<unknown>(resultPtr);\n}\n\n/**\n * Ensure the library is loaded.\n *\n * Loads the native library from the platform-specific npm package\n * or a local dev build. Throws if the binary is not found.\n */\nexport function ensureLoaded(): void {\n loadLibrary();\n}\n\n/**\n * Check if the library is available.\n */\nexport function isAvailable(): boolean {\n try {\n loadLibrary();\n return true;\n } catch {\n return false;\n }\n}\n",
9
9
  "/**\n * Tools for standalone-executable native library embedding.\n *\n * `bun build --compile` only bundles files referenced by statically analyzable\n * imports. Runtime resolution (./download.ts) is invisible to the bundler, so\n * we additionally reference the platform's native lib through a `type: \"file\"`\n * import. Bun then embeds it and returns a `$bunfs` path inside the compiled\n * binary (and the real on-disk path under `bun run`).\n *\n * Linux libc cannot be detected at build time, so it is supplied via the\n * FFF_LIBC build constant (`bun build --define FFF_LIBC='\"musl\"'`), defaulting\n * to glibc. macOS/Windows need no define.\n */\n\nasync function importFile(promise: Promise<{ default: string }>): Promise<string | null> {\n try {\n return (await promise).default;\n } catch {\n return null;\n }\n}\n\nasync function resolveEmbeddedLibPath(): Promise<string | null> {\n if (process.platform === \"darwin\") {\n return importFile(\n import(`@ff-labs/fff-bin-darwin-${process.arch}/libfff_c.dylib`, {\n with: { type: \"file\" },\n }),\n );\n }\n\n if (process.platform === \"win32\") {\n return importFile(\n import(`@ff-labs/fff-bin-win32-${process.arch}/fff_c.dll`, {\n with: { type: \"file\" },\n }),\n );\n }\n\n if (process.platform === \"linux\") {\n return importFile(\n import(\n `@ff-labs/fff-bin-linux-${process.arch}-${typeof FFF_LIBC === \"string\" ? FFF_LIBC : \"gnu\"}/libfff_c.so`,\n { with: { type: \"file\" } }\n ),\n );\n }\n\n return null;\n}\n\n// Resolved once at module init so loadLibrary() can stay synchronous.\nexport const embeddedLibPath: string | null = await resolveEmbeddedLibPath();\n",
10
- "// ----------------------------------------------------------------------------\n// GENERATED FILE - DO NOT EDIT.\n// Copied from: packages/shared/fff-api.ts\n// Run make sync-js-api from the repo root to regenerate.\n// ----------------------------------------------------------------------------\n\n/**\n * The shared public API surface for the fff file finder, implemented identically\n * by `@ff-labs/fff-node` and `@ff-labs/fff-bun`.\n *\n * This file is the single source of truth for every type, helper, and the\n * `FileFinderApi` interface that crosses the package boundary. It is copied\n * verbatim into each package's `src/fff-api.ts` by `make sync-api`.\n *\n * Anything that is not part of the public API (FFI struct layouts, binary\n * loading, platform detection, etc.) stays as per-package internal\n * implementation and must NOT live here.\n *\n * Keep this file self-contained: it must not import from any package-local\n * module, since each package compiles its own copy.\n */\n\n/**\n * Result type for all operations - follows the Result pattern\n */\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n/**\n * Helper to create a successful result\n */\nexport function ok<T>(value: T): Result<T> {\n return { ok: true, value };\n}\n\n/**\n * Helper to create an error result\n */\nexport function err<T>(error: string): Result<T> {\n return { ok: false, error };\n}\n\n/**\n * Initialization options for the file finder\n */\nexport interface InitOptions {\n /** Base directory to index (required) */\n basePath: string;\n /** Path to frecency database (optional, omit to skip frecency initialization) */\n frecencyDbPath?: string;\n /** Path to query history database (optional, omit to skip query tracker initialization) */\n historyDbPath?: string;\n /** @deprecated no-op */\n useUnsafeNoLock?: boolean;\n /**\n * Disable mmap cache warmup after the initial scan. When mmap cache is\n * enabled (the default), the first grep search is as fast as subsequent\n * ones at the cost of a longer scan time and higher initial memory usage.\n */\n disableMmapCache?: boolean;\n /**\n * Disable the content index built after the initial scan.\n * Content indexing enables faster content-aware filtering during grep.\n */\n disableContentIndexing?: boolean;\n /**\n * Disable the background file-system watcher. When the watcher is\n * disabled, files are scanned once but not monitored for changes.\n * (default: false)\n */\n disableWatch?: boolean;\n /** enables optimizations for AI agent assistants. Provide as true if running via mcp/agent */\n aiMode?: boolean;\n /**\n * Path to the tracing log file. When set, the shared FFF tracing subscriber\n * is installed on first init and file output is written here. Omit to leave\n * logging uninitialized.\n */\n logFilePath?: string;\n /**\n * Log level for the tracing subscriber: \"trace\", \"debug\", \"info\", \"warn\",\n * or \"error\". Defaults to \"info\". Ignored when `logFilePath` is not set.\n */\n logLevel?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n /**\n * Override for the content cache file-count cap. When omitted, the picker\n * auto-sizes the budget from the final scanned file count.\n */\n cacheBudgetMaxFiles?: number;\n /** Override for the content cache byte cap. See `cacheBudgetMaxFiles`. */\n cacheBudgetMaxBytes?: number;\n /** Override for the per-file byte cap in the content cache. */\n cacheBudgetMaxFileSize?: number;\n /**\n * Allow indexing the filesystem root (`/`).\n * Off by default, having fff instance at the large folder will generally require\n * file watcher and indexing which will consume a lot of resources if performed uncontrolled\n **/\n enableFsRootScanning?: boolean;\n /** Allow indexing the user's home directory. Same trade-off as `enableFsRootScanning`. */\n enableHomeDirScanning?: boolean;\n /** Follow symlinks for directories */\n followSymlinks?: boolean;\n}\n\n/**\n * Search options for fuzzy file search\n */\nexport interface SearchOptions {\n /** Maximum threads for parallel search (0 = auto) */\n maxThreads?: number;\n /** Current file path (for deprioritization in results) */\n currentFile?: string;\n /** Combo boost score multiplier (default: 100) */\n comboBoostMultiplier?: number;\n /** Minimum combo count for boost (default: 3) */\n minComboCount?: number;\n /** Page index for pagination (default: 0) */\n pageIndex?: number;\n /** Page size for pagination (default: 100) */\n pageSize?: number;\n}\n\n/**\n * Options for `glob`, the constraint-only search.\n *\n * The pattern is applied as a single pass SIMD optimized prefiltering\n * without any fuzzy matching involved. Faster and 100% compatible to npm `glob`.\n */\nexport interface GlobOptions {\n /** Maximum threads for parallel filtering (0 = auto). */\n maxThreads?: number;\n /** Current file path (for deprioritization in results). */\n currentFile?: string;\n /** Page index for pagination (default: 0). */\n pageIndex?: number;\n /** Page size for pagination (default: 100). */\n pageSize?: number;\n}\n\n/**\n * A file item in search results\n */\nexport interface FileItem {\n /** Path relative to the indexed directory */\n relativePath: string;\n /** File name only */\n fileName: string;\n /** File size in bytes */\n size: number;\n /** Last modified timestamp (Unix seconds) */\n modified: number;\n /** Frecency score based on access patterns */\n accessFrecencyScore: number;\n /** Frecency score based on modification time */\n modificationFrecencyScore: number;\n /** Combined frecency score */\n totalFrecencyScore: number;\n /** Git status: 'clean', 'modified', 'untracked', 'staged_new', etc. */\n gitStatus: string;\n}\n\n/**\n * Score breakdown for a search result\n */\nexport interface Score {\n /** Total combined score */\n total: number;\n /** Base fuzzy match score */\n baseScore: number;\n /** Bonus for filename match */\n filenameBonus: number;\n /** Bonus for special filenames (index.ts, main.rs, etc.) */\n specialFilenameBonus: number;\n /** Boost from frecency */\n frecencyBoost: number;\n /** Penalty for distance in path */\n distancePenalty: number;\n /** Penalty if this is the current file */\n currentFilePenalty: number;\n /** Boost from query history combo matching */\n comboMatchBoost: number;\n /** Whether this was an exact match */\n exactMatch: boolean;\n /** Type of match: 'fuzzy', 'exact', 'prefix', etc. */\n matchType: string;\n}\n\n/**\n * Location in file (from query like \"file.ts:42\")\n */\nexport type Location =\n | { type: \"line\"; line: number }\n | { type: \"position\"; line: number; col: number }\n | {\n type: \"range\";\n start: { line: number; col: number };\n end: { line: number; col: number };\n };\n\n/**\n * Search result from fuzzy file search\n */\nexport interface SearchResult {\n /** Matched file items */\n items: FileItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of files that matched */\n totalMatched: number;\n /** Total number of indexed files */\n totalFiles: number;\n /** Location parsed from query (e.g., \"file.ts:42:10\") */\n location?: Location;\n}\n\n/**\n * A directory item in search results\n */\nexport interface DirItem {\n /** Path relative to the indexed directory (e.g., \"src/components/\") */\n relativePath: string;\n /** Last path segment (e.g., \"components/\" for \"src/components/\") */\n dirName: string;\n /** Maximum access frecency score among direct child files */\n maxAccessFrecency: number;\n}\n\n/**\n * Search options for directory search (subset of SearchOptions)\n */\nexport interface DirSearchOptions {\n /** Maximum threads for parallel search (0 = auto) */\n maxThreads?: number;\n /** Current file path (for distance scoring) */\n currentFile?: string;\n /** Page index for pagination (default: 0) */\n pageIndex?: number;\n /** Page size for pagination (default: 100) */\n pageSize?: number;\n}\n\n/**\n * Search result from fuzzy directory search\n */\nexport interface DirSearchResult {\n /** Matched directory items */\n items: DirItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of directories that matched */\n totalMatched: number;\n /** Total number of indexed directories */\n totalDirs: number;\n}\n\n/**\n * A single item in a mixed (files + directories) search result\n */\nexport type MixedItem =\n | { type: \"file\"; item: FileItem }\n | { type: \"directory\"; item: DirItem };\n\n/**\n * Search result from mixed (files + directories) fuzzy search.\n * Items are interleaved by total score in descending order.\n */\nexport interface MixedSearchResult {\n /** Matched items (files and directories interleaved by score) */\n items: MixedItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of items (files + dirs) that matched */\n totalMatched: number;\n /** Total number of indexed files */\n totalFiles: number;\n /** Total number of indexed directories */\n totalDirs: number;\n /** Location parsed from query */\n location?: Location;\n}\n\n/**\n * Scan progress information\n */\nexport interface ScanProgress {\n /** Number of files scanned so far */\n scannedFilesCount: number;\n /** Whether a scan is currently in progress */\n isScanning: boolean;\n /** Whether the background file watcher is ready */\n isWatcherReady: boolean;\n /** Whether the warmup/bigram phase has completed */\n isWarmupComplete: boolean;\n}\n\n/**\n * Normalized watch event kind.\n * A file removed and recreated in one processed batch is marked as modified.\n *\n * rescan = internal OS buffers were overloaded, some events might be missing.\n * The `path` is going to be a folder needs to be rescanned\n */\nexport type WatchEventKind = \"created\" | \"modified\" | \"removed\" | \"rescan\";\n\n/** A single filesystem change notification. */\nexport interface WatchEvent {\n /** Absolute path of the affected file (base path to rescan if `kind ==rescan`) */\n path: string;\n kind: WatchEventKind;\n}\n\n/** Options for watch subscriptions. */\nexport interface WatchOptions {\n /** Additional glob wildcard patterns to ignore */\n ignore?: string[];\n}\n\n/**\n * Receives normalized batches of up to 128 events. Each path appears once.\n */\nexport type WatchBatchCallback = (events: WatchEvent[]) => void;\n\n/** Call me to unsubscribe. */\nexport type WatchUnsubscribe = () => void;\n\n/** Database health information */\nexport interface DbHealth {\n /** Path to the database */\n path: string;\n /** Size of the database on disk in bytes */\n diskSize: number;\n}\n\n/**\n * Health check result\n */\nexport interface HealthCheck {\n /** Library version */\n version: string;\n /** Git integration status */\n git: {\n /** Whether git2 library is available */\n available: boolean;\n /** Whether a git repository was found */\n repositoryFound: boolean;\n /** Git working directory path */\n workdir?: string;\n /** libgit2 version string */\n libgit2Version: string;\n /** Error message if git detection failed */\n error?: string;\n };\n /** File picker status */\n filePicker: {\n /** Whether the file picker is initialized */\n initialized: boolean;\n /** Base path being indexed */\n basePath?: string;\n /** Whether a scan is in progress */\n isScanning?: boolean;\n /** Number of indexed files */\n indexedFiles?: number;\n /** Error message if there's an issue */\n error?: string;\n };\n /** Frecency database status */\n frecency: {\n /** Whether frecency tracking is initialized */\n initialized: boolean;\n /** Database health information */\n dbHealthcheck?: DbHealth;\n /** Error message if there's an issue */\n error?: string;\n };\n /** Query tracker status */\n queryTracker: {\n /** Whether query tracking is initialized */\n initialized: boolean;\n /** Database health information */\n dbHealthcheck?: DbHealth;\n /** Error message if there's an issue */\n error?: string;\n };\n}\n\n/**\n * Grep search mode\n */\nexport type GrepMode = \"plain\" | \"regex\" | \"fuzzy\";\n\n/**\n * Opaque pagination cursor for grep results.\n * Pass this to `GrepOptions.cursor` to fetch the next page.\n * Do not construct or modify this — use the `nextCursor` from a previous `GrepResult`.\n */\nexport interface GrepCursor {\n /** @internal */\n readonly __brand: \"GrepCursor\";\n /** @internal */\n readonly _offset: number;\n}\n\n/**\n * @internal Create a GrepCursor from a raw file offset.\n */\nexport function createGrepCursor(offset: number): GrepCursor {\n return { __brand: \"GrepCursor\" as const, _offset: offset };\n}\n\n/**\n * Options for live grep (content search)\n *\n * Files are searched sequentially in frecency order (most recently/frequently\n * accessed first). The engine returns a `nextCursor` for fetching the next page.\n */\nexport interface GrepOptions {\n /** Maximum file size to search in bytes. Files larger than this are skipped. (default: 10MB) */\n maxFileSize?: number;\n /** Maximum matching lines to collect from a single file (default: 200) */\n maxMatchesPerFile?: number;\n /** Smart case: case-insensitive when the query is all lowercase, case-sensitive otherwise (default: true) */\n smartCase?: boolean;\n /**\n * Pagination cursor from a previous `GrepResult.nextCursor`.\n * Omit (or pass `null`) for the first page.\n */\n cursor?: GrepCursor | null;\n /** Search mode (default: \"plain\") */\n mode?: GrepMode;\n /**\n * Maximum wall-clock time in milliseconds to spend searching before returning\n * partial results. 0 = unlimited. (default: 0)\n */\n timeBudgetMs?: number;\n /** Number of context lines to include before each match (default: 0) */\n beforeContext?: number;\n /** Number of context lines to include after each match (default: 0) */\n afterContext?: number;\n /** Maximum matches to return in this page across all files (default: 50) */\n pageSize?: number;\n /**\n * When true, classify each match line as a code definition (struct/fn/class/...)\n * and expose it via `GrepMatch.isDefinition`. Let callers re-rank defs first\n * without a TS-side regex port. (default: false)\n */\n classifyDefinitions?: boolean;\n}\n\n/**\n * A single grep match with file and line information\n */\nexport interface GrepMatch {\n /** Path relative to the indexed directory */\n relativePath: string;\n /** File name only */\n fileName: string;\n /** Git status */\n gitStatus: string;\n /** File size in bytes */\n size: number;\n /** Last modified timestamp (Unix seconds) */\n modified: number;\n /** Whether the file is binary */\n isBinary: boolean;\n /** Combined frecency score */\n totalFrecencyScore: number;\n /** Access-based frecency score */\n accessFrecencyScore: number;\n /** Modification-based frecency score */\n modificationFrecencyScore: number;\n /** 1-based line number of the match */\n lineNumber: number;\n /** 0-based byte column of first match start */\n col: number;\n /** Absolute byte offset of the matched line from file start */\n byteOffset: number;\n /** The matched line text (may be truncated) */\n lineContent: string;\n /** Byte offset pairs [start, end] within lineContent for highlighting */\n matchRanges: [number, number][];\n /** Fuzzy match score (only in fuzzy mode) */\n fuzzyScore?: number;\n /** Lines before the match (context). Empty array when context is 0. */\n contextBefore?: string[];\n /** Lines after the match (context). Empty array when context is 0. */\n contextAfter?: string[];\n /** Whether this line is a code definition (only populated when `classifyDefinitions: true`). */\n isDefinition?: boolean;\n}\n\n/**\n * Result from a grep search\n */\nexport interface GrepResult {\n /** Matched items with file and line information. At most `max_matches_per_file`. */\n items: GrepMatch[];\n /** Total number of matches collected (always equal to items.length). */\n totalMatched: number;\n /** Number of files actually opened and searched in this call */\n totalFilesSearched: number;\n /** Total number of indexed files (before any filtering) */\n totalFiles: number;\n /** Number of files eligible for search after filtering out binary files, oversized files, and constraint mismatches */\n filteredFileCount: number;\n /**\n * Cursor for the next page, or `null` if all eligible files have been searched.\n * Pass this as `GrepOptions.cursor` to continue from where this call left off.\n */\n nextCursor: GrepCursor | null;\n /** When regex mode fails to compile the pattern, the engine falls back to literal matching and this field contains the compilation error */\n regexFallbackError?: string;\n}\n\n/**\n * Options for multi-pattern grep (Aho-Corasick multi-needle search)\n *\n * Searches for lines matching ANY of the provided patterns using\n * SIMD-accelerated Aho-Corasick multi-pattern matching.\n */\nexport interface MultiGrepOptions {\n /** Patterns to search for (OR logic — matches lines containing any pattern) */\n patterns: string[];\n /** File constraints like \"*.rs\" or \"/src/\" */\n constraints?: string;\n /** Maximum file size to search in bytes (default: 10MB) */\n maxFileSize?: number;\n /** Maximum matching lines to collect from a single file (default: 0 = unlimited) */\n maxMatchesPerFile?: number;\n /** Smart case: case-insensitive when all patterns are lowercase (default: true) */\n smartCase?: boolean;\n /**\n * Pagination cursor from a previous `GrepResult.nextCursor`.\n * Omit (or pass `null`) for the first page.\n */\n cursor?: GrepCursor | null;\n /**\n * Maximum wall-clock time in milliseconds to spend searching before returning\n * partial results. 0 = unlimited. (default: 0)\n */\n timeBudgetMs?: number;\n /** Number of context lines to include before each match (default: 0) */\n beforeContext?: number;\n /** Number of context lines to include after each match (default: 0) */\n afterContext?: number;\n /** Maximum matches to return in this page across all files (default: 50) */\n pageSize?: number;\n /**\n * When true, classify each match line as a code definition (struct/fn/class/...)\n * and expose it via `GrepMatch.isDefinition`. (default: false)\n */\n classifyDefinitions?: boolean;\n}\n\n/**\n * The shared instance surface implemented by `FileFinder` in both\n * `@ff-labs/fff-node` and `@ff-labs/fff-bun`.\n *\n * Both packages must implement this identically. Only instance members belong\n * here. Static helpers (`create`, `isAvailable`, `ensureLoaded`,\n * `healthCheckStatic`) are package-specific and intentionally excluded.\n */\nexport interface FileFinderApi {\n /** Whether the instance has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Destroy and free all native resources. */\n destroy(): void;\n\n /** Fuzzy file search. */\n fileSearch(query: string, options?: SearchOptions): Result<SearchResult>;\n\n /** Glob-only filtering (no fuzzy matching). */\n glob(pattern: string, options?: GlobOptions): Result<SearchResult>;\n\n /** Fuzzy directory search. */\n directorySearch(query: string, options?: DirSearchOptions): Result<DirSearchResult>;\n\n /** Fuzzy search over files and directories interleaved by score. */\n mixedSearch(query: string, options?: SearchOptions): Result<MixedSearchResult>;\n\n /** Content search (live grep). */\n grep(query: string, options?: GrepOptions): Result<GrepResult>;\n\n /** Multi-pattern OR content search (Aho-Corasick). */\n multiGrep(options: MultiGrepOptions): Result<GrepResult>;\n\n /** Trigger an async rescan of the indexed directory. */\n scanFiles(): Result<void>;\n\n /** Whether a scan is currently in progress. */\n isScanning(): boolean;\n\n /** The root directory being indexed. */\n getBasePath(): Result<string | null>;\n\n /** Current scan progress snapshot. */\n getScanProgress(): Result<ScanProgress>;\n\n /**\n * Wait for the initial file scan to complete.\n *\n * Non-blocking: polls `isScanning` and yields to the event loop between\n * checks, so other async work keeps running while waiting.\n */\n waitForScan(timeoutMs?: number): Promise<Result<boolean>>;\n\n /**\n * Wait for the initial file scan to complete, blocking the calling thread.\n *\n * Backed by the native `fff_wait_for_scan` call. Prefer `waitForScan` unless\n * you specifically need synchronous blocking behaviour.\n */\n waitForScanBlocking(timeoutMs?: number): Result<boolean>;\n\n /**\n * Wait until the index is fully ready: the scan has finished and the warmup\n * (content indexing / bigram) phase has completed.\n *\n * Non-blocking: polls `getScanProgress` and yields to the event loop.\n */\n waitForIndexReady(timeoutMs?: number): Promise<Result<boolean>>;\n\n /** Restart indexing in a new directory. */\n reindex(newPath: string): Result<void>;\n\n /** Refresh the git status cache. Returns the number of updated files. */\n refreshGitStatus(): Result<number>;\n\n /** Record that `selectedFilePath` was chosen for `query`. */\n trackQuery(query: string, selectedFilePath: string): Result<boolean>;\n\n /** Get a historical query by offset (0 = most recent). */\n getHistoricalQuery(offset: number): Result<string | null>;\n\n /**\n * Subscribe to filesystem changes matching `pattern`.\n *\n * Patterns may be base-relative globs (./ works), exact paths inside the indexed\n * tree, or existing directories. An empty pattern watches the whole tree.\n *\n * Events are debounced and submitted in batches per 100-ms window at most 128 events.\n * Gitignored and other ignored files are never triggering watcher.\n */\n watch(callback: WatchBatchCallback, options?: WatchOptions): Result<WatchUnsubscribe>;\n watch(\n pattern: string,\n callback: WatchBatchCallback,\n options?: WatchOptions,\n ): Result<WatchUnsubscribe>;\n\n /** Health/diagnostics information for this instance. */\n healthCheck(testPath?: string): Result<HealthCheck>;\n}\n"
10
+ "// ----------------------------------------------------------------------------\n// GENERATED FILE - DO NOT EDIT.\n// Copied from: packages/shared/fff-api.ts\n// Run make sync-js-api from the repo root to regenerate.\n// ----------------------------------------------------------------------------\n\n/**\n * The shared public API surface for the fff file finder, implemented identically\n * by `@ff-labs/fff-node` and `@ff-labs/fff-bun`.\n *\n * This file is the single source of truth for every type, helper, and the\n * `FileFinderApi` interface that crosses the package boundary. It is copied\n * verbatim into each package's `src/fff-api.ts` by `make sync-api`.\n *\n * Anything that is not part of the public API (FFI struct layouts, binary\n * loading, platform detection, etc.) stays as per-package internal\n * implementation and must NOT live here.\n *\n * Keep this file self-contained: it must not import from any package-local\n * module, since each package compiles its own copy.\n */\n\n/**\n * Result type for all operations - follows the Result pattern\n */\nexport type Result<T> = { ok: true; value: T } | { ok: false; error: string };\n\n/**\n * Helper to create a successful result\n */\nexport function ok<T>(value: T): Result<T> {\n return { ok: true, value };\n}\n\n/**\n * Helper to create an error result\n */\nexport function err<T>(error: string): Result<T> {\n return { ok: false, error };\n}\n\n/**\n * Initialization options for the file finder\n */\nexport interface InitOptions {\n /** Base directory to index (required) */\n basePath: string;\n /** Path to frecency database (optional, omit to skip frecency initialization) */\n frecencyDbPath?: string;\n /** Path to query history database (optional, omit to skip query tracker initialization) */\n historyDbPath?: string;\n /** @deprecated no-op */\n useUnsafeNoLock?: boolean;\n /**\n * Disable mmap cache warmup after the initial scan. When mmap cache is\n * enabled (the default), the first grep search is as fast as subsequent\n * ones at the cost of a longer scan time and higher initial memory usage.\n */\n disableMmapCache?: boolean;\n /**\n * Disable the content index built after the initial scan.\n * Content indexing enables faster content-aware filtering during grep.\n */\n disableContentIndexing?: boolean;\n /**\n * Disable the background file-system watcher. When the watcher is\n * disabled, files are scanned once but not monitored for changes.\n * (default: false)\n */\n disableWatch?: boolean;\n /** enables optimizations for AI agent assistants. Provide as true if running via mcp/agent */\n aiMode?: boolean;\n /**\n * Path to the tracing log file. When set, the shared FFF tracing subscriber\n * is installed on first init and file output is written here. Omit to leave\n * logging uninitialized.\n */\n logFilePath?: string;\n /**\n * Log level for the tracing subscriber: \"trace\", \"debug\", \"info\", \"warn\",\n * or \"error\". Defaults to \"info\". Ignored when `logFilePath` is not set.\n */\n logLevel?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n /**\n * Override for the content cache file-count cap. When omitted, the picker\n * auto-sizes the budget from the final scanned file count.\n */\n cacheBudgetMaxFiles?: number;\n /** Override for the content cache byte cap. See `cacheBudgetMaxFiles`. */\n cacheBudgetMaxBytes?: number;\n /** Override for the per-file byte cap in the content cache. */\n cacheBudgetMaxFileSize?: number;\n /**\n * Allow indexing the filesystem root (`/`).\n * Off by default, having fff instance at the large folder will generally require\n * file watcher and indexing which will consume a lot of resources if performed uncontrolled\n **/\n enableFsRootScanning?: boolean;\n /** Allow indexing the user's home directory. Same trade-off as `enableFsRootScanning`. */\n enableHomeDirScanning?: boolean;\n /** Follow symlinks for directories */\n followSymlinks?: boolean;\n}\n\n/**\n * Search options for fuzzy file search\n */\nexport interface SearchOptions {\n /** Maximum threads for parallel search (0 = auto) */\n maxThreads?: number;\n /** Current file path (for deprioritization in results) */\n currentFile?: string;\n /** Combo boost score multiplier (default: 100) */\n comboBoostMultiplier?: number;\n /** Minimum combo count for boost (default: 3) */\n minComboCount?: number;\n /** Page index for pagination (default: 0) */\n pageIndex?: number;\n /** Page size for pagination (default: 100) */\n pageSize?: number;\n}\n\n/**\n * Options for `glob`, the constraint-only search.\n *\n * The pattern is applied as a single pass SIMD optimized prefiltering\n * without any fuzzy matching involved. Faster and 100% compatible to npm `glob`.\n */\nexport interface GlobOptions {\n /** Maximum threads for parallel filtering (0 = auto). */\n maxThreads?: number;\n /** Current file path (for deprioritization in results). */\n currentFile?: string;\n /** Page index for pagination (default: 0). */\n pageIndex?: number;\n /** Page size for pagination (default: 100). */\n pageSize?: number;\n}\n\n/**\n * A file item in search results\n */\nexport interface FileItem {\n /** Path relative to the indexed directory */\n relativePath: string;\n /** File name only */\n fileName: string;\n /** File size in bytes */\n size: number;\n /** Last modified timestamp (Unix seconds) */\n modified: number;\n /** Frecency score based on access patterns */\n accessFrecencyScore: number;\n /** Frecency score based on modification time */\n modificationFrecencyScore: number;\n /** Combined frecency score */\n totalFrecencyScore: number;\n /** Git status: 'clean', 'modified', 'untracked', 'staged_new', etc. */\n gitStatus: string;\n}\n\n/**\n * Score breakdown for a search result\n */\nexport interface Score {\n /** Total combined score */\n total: number;\n /** Base fuzzy match score */\n baseScore: number;\n /** Bonus for filename match */\n filenameBonus: number;\n /** Bonus for special filenames (index.ts, main.rs, etc.) */\n specialFilenameBonus: number;\n /** Boost from frecency */\n frecencyBoost: number;\n /** Penalty for distance in path */\n distancePenalty: number;\n /** Penalty if this is the current file */\n currentFilePenalty: number;\n /** Boost from query history combo matching */\n comboMatchBoost: number;\n /** Whether this was an exact match */\n exactMatch: boolean;\n /** Type of match: 'fuzzy', 'exact', 'prefix', etc. */\n matchType: string;\n}\n\n/**\n * Location in file (from query like \"file.ts:42\")\n */\nexport type Location =\n | { type: \"line\"; line: number }\n | { type: \"position\"; line: number; col: number }\n | {\n type: \"range\";\n start: { line: number; col: number };\n end: { line: number; col: number };\n };\n\n/**\n * Search result from fuzzy file search\n */\nexport interface SearchResult {\n /** Matched file items */\n items: FileItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of files that matched */\n totalMatched: number;\n /** Total number of indexed files */\n totalFiles: number;\n /** Location parsed from query (e.g., \"file.ts:42:10\") */\n location?: Location;\n}\n\n/**\n * A directory item in search results\n */\nexport interface DirItem {\n /** Path relative to the indexed directory (e.g., \"src/components/\") */\n relativePath: string;\n /** Last path segment (e.g., \"components/\" for \"src/components/\") */\n dirName: string;\n /** Maximum access frecency score among direct child files */\n maxAccessFrecency: number;\n}\n\n/**\n * Search options for directory search (subset of SearchOptions)\n */\nexport interface DirSearchOptions {\n /** Maximum threads for parallel search (0 = auto) */\n maxThreads?: number;\n /** Current file path (for distance scoring) */\n currentFile?: string;\n /** Page index for pagination (default: 0) */\n pageIndex?: number;\n /** Page size for pagination (default: 100) */\n pageSize?: number;\n}\n\n/**\n * Search result from fuzzy directory search\n */\nexport interface DirSearchResult {\n /** Matched directory items */\n items: DirItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of directories that matched */\n totalMatched: number;\n /** Total number of indexed directories */\n totalDirs: number;\n}\n\n/**\n * A single item in a mixed (files + directories) search result\n */\nexport type MixedItem =\n | { type: \"file\"; item: FileItem }\n | { type: \"directory\"; item: DirItem };\n\n/**\n * Search result from mixed (files + directories) fuzzy search.\n * Items are interleaved by total score in descending order.\n */\nexport interface MixedSearchResult {\n /** Matched items (files and directories interleaved by score) */\n items: MixedItem[];\n /** Corresponding scores for each item */\n scores: Score[];\n /** Total number of items (files + dirs) that matched */\n totalMatched: number;\n /** Total number of indexed files */\n totalFiles: number;\n /** Total number of indexed directories */\n totalDirs: number;\n /** Location parsed from query */\n location?: Location;\n}\n\n/**\n * Scan progress information\n */\nexport interface ScanProgress {\n /** Number of files scanned so far */\n scannedFilesCount: number;\n /** Whether a scan is currently in progress */\n isScanning: boolean;\n /** Whether the background file watcher is ready */\n isWatcherReady: boolean;\n /** Whether the warmup/bigram phase has completed */\n isWarmupComplete: boolean;\n}\n\n/**\n * Normalized watch event kind.\n * A file removed and recreated in one processed batch is marked as modified.\n *\n * rescan = internal OS buffers were overloaded, some events might be missing.\n * The `path` is going to be a folder needs to be rescanned\n */\nexport type WatchEventKind = \"created\" | \"modified\" | \"removed\" | \"rescan\";\n\n/** A single filesystem change notification. */\nexport interface WatchEvent {\n /** Absolute path of the affected file (base path to rescan if `kind ==rescan`) */\n path: string;\n kind: WatchEventKind;\n}\n\n/** Options for watch subscriptions. */\nexport interface WatchOptions {\n /** Additional glob wildcard patterns to ignore */\n ignore?: string[];\n}\n\n/**\n * Receives normalized batches of up to 128 events. Each path appears once.\n */\nexport type WatchBatchCallback = (events: WatchEvent[]) => void;\n\n/** Call me to unsubscribe. */\nexport type WatchUnsubscribe = () => void;\n\n/** Database health information */\nexport interface DbHealth {\n /** Path to the database */\n path: string;\n /** Size of the database on disk in bytes */\n diskSize: number;\n}\n\n/**\n * Health check result\n */\nexport interface HealthCheck {\n /** Library version */\n version: string;\n /** Git integration status */\n git: {\n /** Whether git2 library is available */\n available: boolean;\n /** Whether a git repository was found */\n repositoryFound: boolean;\n /** Git working directory path */\n workdir?: string;\n /** libgit2 version string */\n libgit2Version: string;\n /** Error message if git detection failed */\n error?: string;\n };\n /** File picker status */\n filePicker: {\n /** Whether the file picker is initialized */\n initialized: boolean;\n /** Base path being indexed */\n basePath?: string;\n /** Whether a scan is in progress */\n isScanning?: boolean;\n /** Number of indexed files */\n indexedFiles?: number;\n /** Error message if there's an issue */\n error?: string;\n };\n /** Frecency database status */\n frecency: {\n /** Whether frecency tracking is initialized */\n initialized: boolean;\n /** Database health information */\n dbHealthcheck?: DbHealth;\n /** Error message if there's an issue */\n error?: string;\n };\n /** Query tracker status */\n queryTracker: {\n /** Whether query tracking is initialized */\n initialized: boolean;\n /** Database health information */\n dbHealthcheck?: DbHealth;\n /** Error message if there's an issue */\n error?: string;\n };\n}\n\n/**\n * Grep search mode\n */\nexport type GrepMode = \"plain\" | \"regex\" | \"fuzzy\";\n\n/**\n * Opaque pagination cursor for grep results.\n * Pass this to `GrepOptions.cursor` to fetch the next page.\n * Do not construct or modify this — use the `nextCursor` from a previous `GrepResult`.\n */\nexport interface GrepCursor {\n /** @internal */\n readonly __brand: \"GrepCursor\";\n /** @internal */\n readonly _offset: number;\n}\n\n/**\n * @internal Create a GrepCursor from a raw file offset.\n */\nexport function createGrepCursor(offset: number): GrepCursor {\n return { __brand: \"GrepCursor\" as const, _offset: offset };\n}\n\n/**\n * Options for live grep (content search)\n *\n * Files are searched sequentially in frecency order (most recently/frequently\n * accessed first). The engine returns a `nextCursor` for fetching the next page.\n */\nexport interface GrepOptions {\n /** Maximum file size to search in bytes. Files larger than this are skipped. (default: 10MB) */\n maxFileSize?: number;\n /** Maximum matching lines to collect from a single file (default: 200) */\n maxMatchesPerFile?: number;\n /** Smart case: case-insensitive when the query is all lowercase, case-sensitive otherwise (default: true) */\n smartCase?: boolean;\n /**\n * Pagination cursor from a previous `GrepResult.nextCursor`.\n * Omit (or pass `null`) for the first page.\n */\n cursor?: GrepCursor | null;\n /** Search mode (default: \"plain\") */\n mode?: GrepMode;\n /**\n * Maximum wall-clock time in milliseconds to spend searching before returning\n * partial results. 0 = unlimited. (default: 0)\n */\n timeBudgetMs?: number;\n /**\n * Apply `timeBudgetMs` even before anything matched. Off by default, so a\n * zero-match query scans every candidate file. (default: false)\n */\n enforceTimeBudget?: boolean;\n /** Number of context lines to include before each match (default: 0) */\n beforeContext?: number;\n /** Number of context lines to include after each match (default: 0) */\n afterContext?: number;\n /** Maximum matches to return in this page across all files (default: 50) */\n pageSize?: number;\n /**\n * When true, classify each match line as a code definition (struct/fn/class/...)\n * and expose it via `GrepMatch.isDefinition`. Let callers re-rank defs first\n * without a TS-side regex port. (default: false)\n */\n classifyDefinitions?: boolean;\n}\n\n/**\n * A single grep match with file and line information\n */\nexport interface GrepMatch {\n /** Path relative to the indexed directory */\n relativePath: string;\n /** File name only */\n fileName: string;\n /** Git status */\n gitStatus: string;\n /** File size in bytes */\n size: number;\n /** Last modified timestamp (Unix seconds) */\n modified: number;\n /** Whether the file is binary */\n isBinary: boolean;\n /** Combined frecency score */\n totalFrecencyScore: number;\n /** Access-based frecency score */\n accessFrecencyScore: number;\n /** Modification-based frecency score */\n modificationFrecencyScore: number;\n /** 1-based line number of the match */\n lineNumber: number;\n /** 0-based byte column of first match start */\n col: number;\n /** Absolute byte offset of the matched line from file start */\n byteOffset: number;\n /** The matched line text (may be truncated) */\n lineContent: string;\n /** Byte offset pairs [start, end] within lineContent for highlighting */\n matchRanges: [number, number][];\n /** Fuzzy match score (only in fuzzy mode) */\n fuzzyScore?: number;\n /** Lines before the match (context). Empty array when context is 0. */\n contextBefore?: string[];\n /** Lines after the match (context). Empty array when context is 0. */\n contextAfter?: string[];\n /** Whether this line is a code definition (only populated when `classifyDefinitions: true`). */\n isDefinition?: boolean;\n}\n\n/**\n * Result from a grep search\n */\nexport interface GrepResult {\n /** Matched items with file and line information. At most `max_matches_per_file`. */\n items: GrepMatch[];\n /** Total number of matches collected (always equal to items.length). */\n totalMatched: number;\n /** Number of files actually opened and searched in this call */\n totalFilesSearched: number;\n /** Total number of indexed files (before any filtering) */\n totalFiles: number;\n /** Number of files eligible for search after filtering out binary files, oversized files, and constraint mismatches */\n filteredFileCount: number;\n /**\n * Cursor for the next page, or `null` if all eligible files have been searched.\n * Pass this as `GrepOptions.cursor` to continue from where this call left off.\n */\n nextCursor: GrepCursor | null;\n /** When regex mode fails to compile the pattern, the engine falls back to literal matching and this field contains the compilation error */\n regexFallbackError?: string;\n}\n\n/**\n * Options for multi-pattern grep (Aho-Corasick multi-needle search)\n *\n * Searches for lines matching ANY of the provided patterns using\n * SIMD-accelerated Aho-Corasick multi-pattern matching.\n */\nexport interface MultiGrepOptions {\n /** Patterns to search for (OR logic — matches lines containing any pattern) */\n patterns: string[];\n /** File constraints like \"*.rs\" or \"/src/\" */\n constraints?: string;\n /** Maximum file size to search in bytes (default: 10MB) */\n maxFileSize?: number;\n /** Maximum matching lines to collect from a single file (default: 0 = unlimited) */\n maxMatchesPerFile?: number;\n /** Smart case: case-insensitive when all patterns are lowercase (default: true) */\n smartCase?: boolean;\n /**\n * Pagination cursor from a previous `GrepResult.nextCursor`.\n * Omit (or pass `null`) for the first page.\n */\n cursor?: GrepCursor | null;\n /**\n * Maximum wall-clock time in milliseconds to spend searching before returning\n * partial results. 0 = unlimited. (default: 0)\n */\n timeBudgetMs?: number;\n /**\n * Apply `timeBudgetMs` even before anything matched. Off by default, so a\n * zero-match query scans every candidate file. (default: false)\n */\n enforceTimeBudget?: boolean;\n /** Number of context lines to include before each match (default: 0) */\n beforeContext?: number;\n /** Number of context lines to include after each match (default: 0) */\n afterContext?: number;\n /** Maximum matches to return in this page across all files (default: 50) */\n pageSize?: number;\n /**\n * When true, classify each match line as a code definition (struct/fn/class/...)\n * and expose it via `GrepMatch.isDefinition`. (default: false)\n */\n classifyDefinitions?: boolean;\n}\n\n/**\n * The shared instance surface implemented by `FileFinder` in both\n * `@ff-labs/fff-node` and `@ff-labs/fff-bun`.\n *\n * Both packages must implement this identically. Only instance members belong\n * here. Static helpers (`create`, `isAvailable`, `ensureLoaded`,\n * `healthCheckStatic`) are package-specific and intentionally excluded.\n */\nexport interface FileFinderApi {\n /** Whether the instance has been destroyed. */\n readonly isDestroyed: boolean;\n\n /** Destroy and free all native resources. */\n destroy(): void;\n\n /** Fuzzy file search. */\n fileSearch(query: string, options?: SearchOptions): Result<SearchResult>;\n\n /** Glob-only filtering (no fuzzy matching). */\n glob(pattern: string, options?: GlobOptions): Result<SearchResult>;\n\n /** Fuzzy directory search. */\n directorySearch(query: string, options?: DirSearchOptions): Result<DirSearchResult>;\n\n /** Fuzzy search over files and directories interleaved by score. */\n mixedSearch(query: string, options?: SearchOptions): Result<MixedSearchResult>;\n\n /** Content search (live grep). */\n grep(query: string, options?: GrepOptions): Result<GrepResult>;\n\n /** Multi-pattern OR content search (Aho-Corasick). */\n multiGrep(options: MultiGrepOptions): Result<GrepResult>;\n\n /** Trigger an async rescan of the indexed directory. */\n scanFiles(): Result<void>;\n\n /** Whether a scan is currently in progress. */\n isScanning(): boolean;\n\n /** The root directory being indexed. */\n getBasePath(): Result<string | null>;\n\n /** Current scan progress snapshot. */\n getScanProgress(): Result<ScanProgress>;\n\n /**\n * Wait for the initial file scan to complete.\n *\n * Non-blocking: polls `isScanning` and yields to the event loop between\n * checks, so other async work keeps running while waiting.\n */\n waitForScan(timeoutMs?: number): Promise<Result<boolean>>;\n\n /**\n * Wait for the initial file scan to complete, blocking the calling thread.\n *\n * Backed by the native `fff_wait_for_scan` call. Prefer `waitForScan` unless\n * you specifically need synchronous blocking behaviour.\n */\n waitForScanBlocking(timeoutMs?: number): Result<boolean>;\n\n /**\n * Wait until the index is fully ready: the scan has finished and the warmup\n * (content indexing / bigram) phase has completed.\n *\n * Non-blocking: polls `getScanProgress` and yields to the event loop.\n */\n waitForIndexReady(timeoutMs?: number): Promise<Result<boolean>>;\n\n /** Restart indexing in a new directory. */\n reindex(newPath: string): Result<void>;\n\n /** Refresh the git status cache. Returns the number of updated files. */\n refreshGitStatus(): Result<number>;\n\n /** Record that `selectedFilePath` was chosen for `query`. */\n trackQuery(query: string, selectedFilePath: string): Result<boolean>;\n\n /** Get a historical query by offset (0 = most recent). */\n getHistoricalQuery(offset: number): Result<string | null>;\n\n /**\n * Subscribe to filesystem changes matching `pattern`.\n *\n * Patterns may be base-relative globs (./ works), exact paths inside the indexed\n * tree, or existing directories. An empty pattern watches the whole tree.\n *\n * Events are debounced and submitted in batches per 100-ms window at most 128 events.\n * Gitignored and other ignored files are never triggering watcher.\n */\n watch(callback: WatchBatchCallback, options?: WatchOptions): Result<WatchUnsubscribe>;\n watch(\n pattern: string,\n callback: WatchBatchCallback,\n options?: WatchOptions,\n ): Result<WatchUnsubscribe>;\n\n /** Health/diagnostics information for this instance. */\n healthCheck(testPath?: string): Result<HealthCheck>;\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "043EF0566D90D1E064756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "D4151B7C94AD421364756E2164756E21",
14
14
  "names": []
15
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ff-labs/fff-bun",
3
- "version": "0.10.6",
3
+ "version": "0.10.7-nightly.0f4b0dc",
4
4
  "private": false,
5
5
  "description": "High-performance fuzzy file finder for Bun - perfect for LLM agent tools",
6
6
  "type": "module",
@@ -68,14 +68,14 @@
68
68
  "typescript": "^5.0.0"
69
69
  },
70
70
  "optionalDependencies": {
71
- "@ff-labs/fff-bin-android-arm64": "0.10.6",
72
- "@ff-labs/fff-bin-darwin-arm64": "0.10.6",
73
- "@ff-labs/fff-bin-darwin-x64": "0.10.6",
74
- "@ff-labs/fff-bin-linux-arm64-gnu": "0.10.6",
75
- "@ff-labs/fff-bin-linux-arm64-musl": "0.10.6",
76
- "@ff-labs/fff-bin-linux-x64-gnu": "0.10.6",
77
- "@ff-labs/fff-bin-linux-x64-musl": "0.10.6",
78
- "@ff-labs/fff-bin-win32-arm64": "0.10.6",
79
- "@ff-labs/fff-bin-win32-x64": "0.10.6"
71
+ "@ff-labs/fff-bin-android-arm64": "0.10.7-nightly.0f4b0dc",
72
+ "@ff-labs/fff-bin-darwin-arm64": "0.10.7-nightly.0f4b0dc",
73
+ "@ff-labs/fff-bin-darwin-x64": "0.10.7-nightly.0f4b0dc",
74
+ "@ff-labs/fff-bin-linux-arm64-gnu": "0.10.7-nightly.0f4b0dc",
75
+ "@ff-labs/fff-bin-linux-arm64-musl": "0.10.7-nightly.0f4b0dc",
76
+ "@ff-labs/fff-bin-linux-x64-gnu": "0.10.7-nightly.0f4b0dc",
77
+ "@ff-labs/fff-bin-linux-x64-musl": "0.10.7-nightly.0f4b0dc",
78
+ "@ff-labs/fff-bin-win32-arm64": "0.10.7-nightly.0f4b0dc",
79
+ "@ff-labs/fff-bin-win32-x64": "0.10.7-nightly.0f4b0dc"
80
80
  }
81
81
  }
package/src/fff-api.ts CHANGED
@@ -432,6 +432,11 @@ export interface GrepOptions {
432
432
  * partial results. 0 = unlimited. (default: 0)
433
433
  */
434
434
  timeBudgetMs?: number;
435
+ /**
436
+ * Apply `timeBudgetMs` even before anything matched. Off by default, so a
437
+ * zero-match query scans every candidate file. (default: false)
438
+ */
439
+ enforceTimeBudget?: boolean;
435
440
  /** Number of context lines to include before each match (default: 0) */
436
441
  beforeContext?: number;
437
442
  /** Number of context lines to include after each match (default: 0) */
@@ -538,6 +543,11 @@ export interface MultiGrepOptions {
538
543
  * partial results. 0 = unlimited. (default: 0)
539
544
  */
540
545
  timeBudgetMs?: number;
546
+ /**
547
+ * Apply `timeBudgetMs` even before anything matched. Off by default, so a
548
+ * zero-match query scans every candidate file. (default: false)
549
+ */
550
+ enforceTimeBudget?: boolean;
541
551
  /** Number of context lines to include before each match (default: 0) */
542
552
  beforeContext?: number;
543
553
  /** Number of context lines to include after each match (default: 0) */
package/src/ffi.ts CHANGED
@@ -139,7 +139,7 @@ const ffiDefinition = {
139
139
  },
140
140
 
141
141
  // Live grep (content search)
142
- fff_live_grep: {
142
+ fff_live_grep_ex: {
143
143
  args: [
144
144
  FFIType.ptr, // handle
145
145
  FFIType.cstring, // query
@@ -150,6 +150,7 @@ const ffiDefinition = {
150
150
  FFIType.u32, // file_offset
151
151
  FFIType.u32, // page_limit
152
152
  FFIType.u64, // time_budget_ms
153
+ FFIType.bool, // enforce_time_budget
153
154
  FFIType.u32, // before_context
154
155
  FFIType.u32, // after_context
155
156
  FFIType.bool, // classify_definitions
@@ -158,7 +159,7 @@ const ffiDefinition = {
158
159
  },
159
160
 
160
161
  // Multi-pattern grep (Aho-Corasick)
161
- fff_multi_grep: {
162
+ fff_multi_grep_ex: {
162
163
  args: [
163
164
  FFIType.ptr, // handle
164
165
  FFIType.cstring, // patterns_joined (\n-separated)
@@ -169,6 +170,7 @@ const ffiDefinition = {
169
170
  FFIType.u32, // file_offset
170
171
  FFIType.u32, // page_limit
171
172
  FFIType.u64, // time_budget_ms
173
+ FFIType.bool, // enforce_time_budget
172
174
  FFIType.u32, // before_context
173
175
  FFIType.u32, // after_context
174
176
  FFIType.bool, // classify_definitions
@@ -1244,12 +1246,13 @@ export function ffiLiveGrep(
1244
1246
  fileOffset: number,
1245
1247
  pageLimit: number,
1246
1248
  timeBudgetMs: number,
1249
+ enforceTimeBudget: boolean,
1247
1250
  beforeContext: number,
1248
1251
  afterContext: number,
1249
1252
  classifyDefinitions: boolean,
1250
1253
  ): Result<GrepResult> {
1251
1254
  const library = loadLibrary();
1252
- const resultPtr = library.symbols.fff_live_grep(
1255
+ const resultPtr = library.symbols.fff_live_grep_ex(
1253
1256
  handle,
1254
1257
  ptr(encodeString(query)),
1255
1258
  grepModeToU8(mode),
@@ -1259,6 +1262,7 @@ export function ffiLiveGrep(
1259
1262
  fileOffset,
1260
1263
  pageLimit,
1261
1264
  BigInt(timeBudgetMs),
1265
+ enforceTimeBudget,
1262
1266
  beforeContext,
1263
1267
  afterContext,
1264
1268
  classifyDefinitions,
@@ -1279,12 +1283,13 @@ export function ffiMultiGrep(
1279
1283
  fileOffset: number,
1280
1284
  pageLimit: number,
1281
1285
  timeBudgetMs: number,
1286
+ enforceTimeBudget: boolean,
1282
1287
  beforeContext: number,
1283
1288
  afterContext: number,
1284
1289
  classifyDefinitions: boolean,
1285
1290
  ): Result<GrepResult> {
1286
1291
  const library = loadLibrary();
1287
- const resultPtr = library.symbols.fff_multi_grep(
1292
+ const resultPtr = library.symbols.fff_multi_grep_ex(
1288
1293
  handle,
1289
1294
  ptr(encodeString(patternsJoined)),
1290
1295
  ptr(encodeString(constraints)),
@@ -1294,6 +1299,7 @@ export function ffiMultiGrep(
1294
1299
  fileOffset,
1295
1300
  pageLimit,
1296
1301
  BigInt(timeBudgetMs),
1302
+ enforceTimeBudget,
1297
1303
  beforeContext,
1298
1304
  afterContext,
1299
1305
  classifyDefinitions,
package/src/finder.ts CHANGED
@@ -373,6 +373,7 @@ export class FileFinder implements FileFinderApi {
373
373
  options?.cursor?._offset ?? 0,
374
374
  options?.pageSize ?? 0,
375
375
  options?.timeBudgetMs ?? 0,
376
+ options?.enforceTimeBudget ?? false,
376
377
  options?.beforeContext ?? 0,
377
378
  options?.afterContext ?? 0,
378
379
  options?.classifyDefinitions ?? false,
@@ -422,6 +423,7 @@ export class FileFinder implements FileFinderApi {
422
423
  options.cursor?._offset ?? 0,
423
424
  options.pageSize ?? 0,
424
425
  options.timeBudgetMs ?? 0,
426
+ options.enforceTimeBudget ?? false,
425
427
  options.beforeContext ?? 0,
426
428
  options.afterContext ?? 0,
427
429
  options.classifyDefinitions ?? false,