@ff-labs/bun 0.1.0

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/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # fff - Fast File Finder
2
+
3
+ High-performance fuzzy file finder for Bun, powered by Rust. Perfect for LLM agent tools that need to search through codebases.
4
+
5
+ ## Features
6
+
7
+ - **Blazing fast** - Rust-powered fuzzy search with parallel processing
8
+ - **Smart ranking** - Frecency-based scoring (frequency + recency)
9
+ - **Git-aware** - Shows file git status in results
10
+ - **Query history** - Learns from your search patterns
11
+ - **Type-safe** - Full TypeScript support with Result types
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun add fff
17
+ ```
18
+
19
+ The native binary will be downloaded automatically during installation.
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { FileFinder } from "fff";
25
+
26
+ // Initialize with a directory
27
+ const result = FileFinder.init({ basePath: "/path/to/project" });
28
+ if (!result.ok) {
29
+ console.error(result.error);
30
+ process.exit(1);
31
+ }
32
+
33
+ // Wait for initial scan
34
+ FileFinder.waitForScan(5000);
35
+
36
+ // Search for files
37
+ const search = FileFinder.search("main.ts");
38
+ if (search.ok) {
39
+ for (const item of search.value.items) {
40
+ console.log(item.relativePath);
41
+ }
42
+ }
43
+
44
+ // Cleanup when done
45
+ FileFinder.destroy();
46
+ ```
47
+
48
+ ## API Reference
49
+
50
+ ### `FileFinder.init(options)`
51
+
52
+ Initialize the file finder.
53
+
54
+ ```typescript
55
+ interface InitOptions {
56
+ basePath: string; // Directory to index (required)
57
+ frecencyDbPath?: string; // Custom frecency DB path
58
+ historyDbPath?: string; // Custom history DB path
59
+ useUnsafeNoLock?: boolean; // Faster but less safe DB mode
60
+ skipDatabases?: boolean; // Skip frecency/history (simpler mode)
61
+ }
62
+
63
+ const result = FileFinder.init({ basePath: "/my/project" });
64
+ ```
65
+
66
+ ### `FileFinder.search(query, options?)`
67
+
68
+ Search for files.
69
+
70
+ ```typescript
71
+ interface SearchOptions {
72
+ maxThreads?: number; // Parallel threads (0 = auto)
73
+ currentFile?: string; // Deprioritize this file
74
+ comboBoostMultiplier?: number; // Query history boost
75
+ minComboCount?: number; // Min history matches
76
+ pageIndex?: number; // Pagination offset
77
+ pageSize?: number; // Results per page
78
+ }
79
+
80
+ const result = FileFinder.search("main.ts", { pageSize: 10 });
81
+ if (result.ok) {
82
+ console.log(`Found ${result.value.totalMatched} files`);
83
+ }
84
+ ```
85
+
86
+ ### Query Syntax
87
+
88
+ - `foo bar` - Match files containing "foo" and "bar"
89
+ - `src/` - Match files in src directory
90
+ - `file.ts:42` - Match file.ts with line 42
91
+ - `file.ts:42:10` - Match with line and column
92
+
93
+ ### `FileFinder.trackAccess(filePath)`
94
+
95
+ Track file access for frecency scoring.
96
+
97
+ ```typescript
98
+ // Call when user opens a file
99
+ FileFinder.trackAccess("/path/to/file.ts");
100
+ ```
101
+
102
+ ### `FileFinder.trackQuery(query, selectedFile)`
103
+
104
+ Track query completion for smart suggestions.
105
+
106
+ ```typescript
107
+ // Call when user selects a file from search
108
+ FileFinder.trackQuery("main", "/path/to/main.ts");
109
+ ```
110
+
111
+ ### `FileFinder.healthCheck(testPath?)`
112
+
113
+ Get diagnostic information.
114
+
115
+ ```typescript
116
+ const health = FileFinder.healthCheck();
117
+ if (health.ok) {
118
+ console.log(`Version: ${health.value.version}`);
119
+ console.log(`Indexed: ${health.value.filePicker.indexedFiles} files`);
120
+ }
121
+ ```
122
+
123
+ ### Other Methods
124
+
125
+ - `FileFinder.scanFiles()` - Trigger rescan
126
+ - `FileFinder.isScanning()` - Check scan status
127
+ - `FileFinder.getScanProgress()` - Get scan progress
128
+ - `FileFinder.waitForScan(timeoutMs)` - Wait for scan
129
+ - `FileFinder.restartIndex(newPath)` - Change indexed directory
130
+ - `FileFinder.refreshGitStatus()` - Refresh git cache
131
+ - `FileFinder.getHistoricalQuery(offset)` - Get past queries
132
+ - `FileFinder.shortenPath(path, maxSize, strategy)` - Shorten paths
133
+ - `FileFinder.destroy()` - Cleanup resources
134
+
135
+ ## Result Types
136
+
137
+ All methods return a `Result<T>` type for explicit error handling:
138
+
139
+ ```typescript
140
+ type Result<T> =
141
+ | { ok: true; value: T }
142
+ | { ok: false; error: string };
143
+
144
+ const result = FileFinder.search("foo");
145
+ if (result.ok) {
146
+ // result.value is SearchResult
147
+ } else {
148
+ // result.error is string
149
+ }
150
+ ```
151
+
152
+ ## Search Result Types
153
+
154
+ ```typescript
155
+ interface SearchResult {
156
+ items: FileItem[];
157
+ scores: Score[];
158
+ totalMatched: number;
159
+ totalFiles: number;
160
+ location?: Location;
161
+ }
162
+
163
+ interface FileItem {
164
+ path: string;
165
+ relativePath: string;
166
+ fileName: string;
167
+ size: number;
168
+ modified: number;
169
+ gitStatus: string; // 'clean', 'modified', 'untracked', etc.
170
+ }
171
+ ```
172
+
173
+ ## Building from Source
174
+
175
+ If prebuilt binaries aren't available for your platform:
176
+
177
+ ```bash
178
+ # Clone the repository
179
+ git clone https://github.com/dmtrKovalenko/fff.nvim
180
+ cd fff.nvim
181
+
182
+ # Build the C library
183
+ cargo build --release -p fff-c
184
+
185
+ # The binary will be at target/release/libfff_c.{so,dylib,dll}
186
+ ```
187
+
188
+ ## CLI Tools
189
+
190
+ ```bash
191
+ # Download binary manually
192
+ bunx fff download [version]
193
+
194
+ # Show platform info
195
+ bunx fff info
196
+ ```
197
+
198
+ ## License
199
+
200
+ MIT
Binary file
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@ff-labs/bun",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "nativeBinaryHash": "6c641aa",
6
+ "description": "High-performance fuzzy file finder for Bun - perfect for LLM agent tools",
7
+ "type": "module",
8
+ "main": "src/index.ts",
9
+ "types": "src/index.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./src/index.ts",
13
+ "types": "./src/index.ts"
14
+ }
15
+ },
16
+ "bin": {
17
+ "fff": "./scripts/cli.cjs"
18
+ },
19
+ "files": [
20
+ "src",
21
+ "bin",
22
+ "scripts"
23
+ ],
24
+ "scripts": {
25
+ "postinstall": "bun ./scripts/postinstall.ts",
26
+ "download": "bun ./scripts/cli.ts download",
27
+ "test": "bun test src/",
28
+ "typecheck": "tsc --noEmit",
29
+ "demo": "bun ./examples/search.ts"
30
+ },
31
+ "engines": {
32
+ "bun": ">=1.0.0"
33
+ },
34
+ "os": [
35
+ "darwin",
36
+ "linux",
37
+ "win32"
38
+ ],
39
+ "cpu": [
40
+ "x64",
41
+ "arm64"
42
+ ],
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/dmtrKovalenko/fff.nvim.git",
46
+ "directory": "packages/fff"
47
+ },
48
+ "keywords": [
49
+ "file-finder",
50
+ "fuzzy-search",
51
+ "bun",
52
+ "ffi",
53
+ "llm-tools",
54
+ "agent-tools",
55
+ "fast",
56
+ "rust"
57
+ ],
58
+ "author": "Dmitry Kovalenko",
59
+ "license": "MIT",
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/dmtrKovalenko/fff.nvim/issues"
65
+ },
66
+ "homepage": "https://github.com/dmtrKovalenko/fff.nvim#readme",
67
+ "devDependencies": {
68
+ "@types/bun": "^1.3.8",
69
+ "typescript": "^5.0.0"
70
+ },
71
+ "peerDependencies": {
72
+ "bun": ">=1.0.0"
73
+ }
74
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ // Wrapper script for npm - delegates to Bun
3
+ const { execSync } = require("child_process");
4
+ const { join } = require("path");
5
+
6
+ const script = join(__dirname, "cli.ts");
7
+ const args = process.argv.slice(2).join(" ");
8
+
9
+ try {
10
+ execSync(`bun ${script} ${args}`, {
11
+ stdio: "inherit",
12
+ cwd: process.cwd()
13
+ });
14
+ } catch (error) {
15
+ process.exit(error.status || 1);
16
+ }
package/scripts/cli.ts ADDED
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * CLI tool for fff package management
4
+ *
5
+ * Usage:
6
+ * bunx fff download [hash] - Download native binary
7
+ * bunx fff info - Show platform and binary info
8
+ * bunx fff check - Check for updates
9
+ */
10
+
11
+ import {
12
+ downloadBinary,
13
+ getBinaryPath,
14
+ findBinary,
15
+ getInstalledHash,
16
+ checkForUpdate
17
+ } from "../src/download";
18
+ import { getTriple, getLibExtension, getLibFilename } from "../src/platform";
19
+ import { dirname, join } from "node:path";
20
+ import { fileURLToPath } from "node:url";
21
+
22
+ const args = process.argv.slice(2);
23
+ const command = args[0];
24
+
25
+ interface PackageJson {
26
+ version: string;
27
+ nativeBinaryHash?: string;
28
+ }
29
+
30
+ async function getPackageInfo(): Promise<PackageJson> {
31
+ const currentDir = dirname(fileURLToPath(import.meta.url));
32
+ const packageJsonPath = join(currentDir, "..", "package.json");
33
+
34
+ try {
35
+ return await Bun.file(packageJsonPath).json();
36
+ } catch {
37
+ return { version: "unknown" };
38
+ }
39
+ }
40
+
41
+ async function main() {
42
+ switch (command) {
43
+ case "download": {
44
+ const hash = args[1];
45
+ console.log("fff: Downloading native library...");
46
+ try {
47
+ const resolvedHash = await downloadBinary(hash);
48
+ console.log(`fff: Download complete! (${resolvedHash})`);
49
+ } catch (error) {
50
+ console.error("fff: Download failed:", error);
51
+ process.exit(1);
52
+ }
53
+ break;
54
+ }
55
+
56
+ case "check": {
57
+ console.log("fff: Checking for updates...");
58
+ try {
59
+ const { currentHash, latestHash, updateAvailable } = await checkForUpdate();
60
+ console.log(` Installed: ${currentHash || "not installed"}`);
61
+ console.log(` Latest: ${latestHash}`);
62
+ if (updateAvailable) {
63
+ console.log("");
64
+ console.log(" Update available! Run: bunx fff download");
65
+ } else {
66
+ console.log("");
67
+ console.log(" You're up to date!");
68
+ }
69
+ } catch (error) {
70
+ console.error("fff: Failed to check for updates:", error);
71
+ process.exit(1);
72
+ }
73
+ break;
74
+ }
75
+
76
+ case "info": {
77
+ const pkg = await getPackageInfo();
78
+ const installedHash = await getInstalledHash();
79
+
80
+ console.log("fff - Fast File Finder");
81
+ console.log(`Package version: ${pkg.version}`);
82
+ console.log(`Binary hash: ${installedHash || "not installed"}`);
83
+ console.log("");
84
+ console.log("Platform Information:");
85
+ console.log(` Triple: ${getTriple()}`);
86
+ console.log(` Extension: ${getLibExtension()}`);
87
+ console.log(` Library name: ${getLibFilename()}`);
88
+ console.log("");
89
+ console.log("Binary Status:");
90
+ const existing = findBinary();
91
+ if (existing) {
92
+ console.log(` Found: ${existing}`);
93
+ } else {
94
+ console.log(` Not found`);
95
+ console.log(` Expected path: ${getBinaryPath()}`);
96
+ }
97
+ break;
98
+ }
99
+
100
+ case "version":
101
+ case "--version":
102
+ case "-v": {
103
+ const pkg = await getPackageInfo();
104
+ console.log(pkg.version);
105
+ break;
106
+ }
107
+
108
+ case "help":
109
+ case "--help":
110
+ case "-h":
111
+ default: {
112
+ const pkg = await getPackageInfo();
113
+ console.log(`fff - Fast File Finder CLI v${pkg.version}`);
114
+ console.log("");
115
+ console.log("Usage:");
116
+ console.log(" bunx fff download [hash] Download native binary");
117
+ console.log(" bunx fff check Check for updates");
118
+ console.log(" bunx fff info Show platform and binary info");
119
+ console.log(" bunx fff version Show version");
120
+ console.log(" bunx fff help Show this help message");
121
+ console.log("");
122
+ console.log("Examples:");
123
+ console.log(" bunx fff download Download binary for configured hash");
124
+ console.log(" bunx fff download latest Download latest release");
125
+ console.log(" bunx fff download abc1234 Download specific commit hash");
126
+ break;
127
+ }
128
+ }
129
+ }
130
+
131
+ main();
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Postinstall script - automatically downloads the native binary
4
+ */
5
+
6
+ import { downloadBinary, findBinary, getInstalledHash } from "../src/download";
7
+
8
+ async function main() {
9
+ // Check if binary already exists (dev build or previous download)
10
+ const existing = findBinary();
11
+ if (existing) {
12
+ const hash = await getInstalledHash();
13
+ console.log(`fff: Native library found at ${existing}`);
14
+ if (hash) {
15
+ console.log(`fff: Version: ${hash}`);
16
+ }
17
+ return;
18
+ }
19
+
20
+ console.log("fff: Native library not found, downloading...");
21
+
22
+ try {
23
+ const hash = await downloadBinary();
24
+ console.log(`fff: Native library installed successfully! (${hash})`);
25
+ } catch (error) {
26
+ console.error("fff: Failed to download native library:", error);
27
+ console.error("");
28
+ console.error("fff: You can build from source instead:");
29
+ console.error(" cd node_modules/fff && cargo build --release -p fff-c");
30
+ console.error("");
31
+ console.error("fff: Or run `bunx fff download` after fixing network issues.");
32
+ // Don't exit with error - allow install to complete
33
+ // The error will surface when the user tries to use the library
34
+ }
35
+ }
36
+
37
+ main();