infiniloom-node 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,293 @@
1
+ # @infiniloom/node
2
+
3
+ Node.js bindings for Infiniloom - Repository context engine for LLMs.
4
+
5
+ ## Features
6
+
7
+ - **Pack repositories** into optimized LLM context with configurable compression
8
+ - **Scan repositories** for statistics and metadata
9
+ - **Count tokens** for different LLM models
10
+ - **Security scanning** to detect secrets and sensitive data
11
+ - **Fast native performance** powered by Rust and NAPI-RS
12
+ - **Cross-platform** support (macOS, Linux, Windows)
13
+
14
+ ## Installation
15
+
16
+ Phase 2 (not implemented intentionally): `npm install @infiniloom/node` (npm release).
17
+ For now, build from source in this repository.
18
+
19
+ ## Quick Start
20
+
21
+ ### Simple Packing
22
+
23
+ ```javascript
24
+ const { pack } = require('@infiniloom/node');
25
+
26
+ // Pack a repository with default settings
27
+ const context = pack('./my-repo');
28
+ console.log(context);
29
+ ```
30
+
31
+ ### With Options
32
+
33
+ ```javascript
34
+ const { pack } = require('@infiniloom/node');
35
+
36
+ const context = pack('./my-repo', {
37
+ format: 'xml', // Output format: 'xml', 'markdown', 'json', or 'yaml'
38
+ model: 'claude', // Target model: 'claude', 'gpt-5.2', 'o3', 'gpt-4o', 'gemini', 'llama', etc.
39
+ compression: 'balanced', // Compression: 'none', 'minimal', 'balanced', 'aggressive', 'extreme'
40
+ mapBudget: 2000, // Token budget for repository map
41
+ maxSymbols: 50, // Maximum symbols to include in map
42
+ skipSecurity: false, // Skip security scanning
43
+ redactSecrets: true, // Redact detected secrets in output (default true)
44
+ skipSymbols: false // Skip symbol extraction for faster scans
45
+ });
46
+ ```
47
+
48
+ ### Repository Scanning
49
+
50
+ ```javascript
51
+ const { scan } = require('@infiniloom/node');
52
+
53
+ const stats = scan('./my-repo', 'claude');
54
+ console.log(`Repository: ${stats.name}`);
55
+ console.log(`Total files: ${stats.totalFiles}`);
56
+ console.log(`Total lines: ${stats.totalLines}`);
57
+ console.log(`Total tokens: ${stats.totalTokens}`);
58
+ console.log(`Primary language: ${stats.primaryLanguage}`);
59
+ console.log(`Languages:`, stats.languages);
60
+ ```
61
+
62
+ ### Token Counting
63
+
64
+ ```javascript
65
+ const { countTokens } = require('@infiniloom/node');
66
+
67
+ const count = countTokens('Hello, world!', 'claude');
68
+ console.log(`Tokens: ${count}`);
69
+ ```
70
+
71
+ ### Semantic Compression
72
+
73
+ ```javascript
74
+ const { semanticCompress } = require('@infiniloom/node');
75
+
76
+ // Compress text while preserving important content
77
+ const longText = '... your long text content ...';
78
+ const compressed = semanticCompress(longText, 0.7, 0.5);
79
+ // Parameters:
80
+ // - text: The text to compress
81
+ // - similarityThreshold (optional): 0.0-1.0, default 0.7
82
+ // - budgetRatio (optional): 0.0-1.0, default 0.5
83
+ console.log(compressed);
84
+ ```
85
+
86
+ ### Advanced Usage with Infiniloom Class
87
+
88
+ ```javascript
89
+ const { Infiniloom } = require('@infiniloom/node');
90
+
91
+ // Create an Infiniloom instance
92
+ const loom = new Infiniloom('./my-repo', 'claude');
93
+
94
+ // Get statistics
95
+ const stats = loom.getStats();
96
+ console.log(stats);
97
+
98
+ // Generate repository map
99
+ const map = loom.generateMap(2000, 50);
100
+ console.log(map);
101
+
102
+ // Pack with options
103
+ const context = loom.pack({
104
+ format: 'xml',
105
+ compression: 'balanced'
106
+ });
107
+ console.log(context);
108
+
109
+ // Security scan
110
+ const findings = loom.securityScan();
111
+ if (findings.length > 0) {
112
+ console.warn('Security issues found:');
113
+ findings.forEach(finding => console.warn(finding));
114
+ }
115
+ ```
116
+
117
+ ## API Reference
118
+
119
+ ### Functions
120
+
121
+ #### `pack(path: string, options?: PackOptions): string`
122
+
123
+ Pack a repository into optimized LLM context.
124
+
125
+ **Parameters:**
126
+ - `path` - Path to repository root
127
+ - `options` - Optional packing options
128
+
129
+ **Returns:** Formatted repository context as a string
130
+
131
+ #### `scan(path: string, model?: string): ScanStats`
132
+
133
+ Scan a repository and return statistics.
134
+
135
+ **Parameters:**
136
+ - `path` - Path to repository root
137
+ - `model` - Optional target model (default: "claude")
138
+
139
+ **Returns:** Repository statistics
140
+
141
+ #### `countTokens(text: string, model?: string): number`
142
+
143
+ Count tokens in text for a specific model.
144
+
145
+ **Parameters:**
146
+ - `text` - Text to tokenize
147
+ - `model` - Optional model name (default: "claude")
148
+
149
+ **Returns:** Token count
150
+
151
+ #### `semanticCompress(text: string, similarityThreshold?: number, budgetRatio?: number): string`
152
+
153
+ Compress text using semantic compression while preserving important content.
154
+
155
+ **Parameters:**
156
+ - `text` - Text to compress
157
+ - `similarityThreshold` - Threshold for grouping similar chunks (0.0-1.0, default: 0.7)
158
+ - `budgetRatio` - Target size as ratio of original (0.0-1.0, default: 0.5)
159
+
160
+ **Returns:** Compressed text
161
+
162
+ ### Types
163
+
164
+ #### `PackOptions`
165
+
166
+ ```typescript
167
+ interface PackOptions {
168
+ format?: string; // "xml", "markdown", "json", "yaml", "toon", or "plain"
169
+ model?: string; // "claude", "gpt-4o", "gpt-4", "gemini", "llama", etc.
170
+ compression?: string; // "none", "minimal", "balanced", "aggressive", "extreme", "focused", "semantic"
171
+ mapBudget?: number; // Token budget for repository map
172
+ maxSymbols?: number; // Maximum number of symbols in map
173
+ skipSecurity?: boolean; // Skip security scanning
174
+ redactSecrets?: boolean;// Redact detected secrets
175
+ skipSymbols?: boolean; // Skip symbol extraction
176
+ }
177
+ ```
178
+
179
+ #### `ScanStats`
180
+
181
+ ```typescript
182
+ interface ScanStats {
183
+ name: string;
184
+ totalFiles: number;
185
+ totalLines: number;
186
+ totalTokens: number;
187
+ primaryLanguage?: string;
188
+ languages: LanguageStat[];
189
+ securityFindings: number;
190
+ }
191
+ ```
192
+
193
+ #### `LanguageStat`
194
+
195
+ ```typescript
196
+ interface LanguageStat {
197
+ language: string;
198
+ files: number;
199
+ lines: number;
200
+ percentage: number;
201
+ }
202
+ ```
203
+
204
+ ### Infiniloom Class
205
+
206
+ #### `new Infiniloom(path: string, model?: string)`
207
+
208
+ Create a new Infiniloom instance.
209
+
210
+ #### `getStats(): ScanStats`
211
+
212
+ Get repository statistics.
213
+
214
+ #### `generateMap(budget?: number, maxSymbols?: number): string`
215
+
216
+ Generate a repository map.
217
+
218
+ #### `pack(options?: PackOptions): string`
219
+
220
+ Pack repository with specific options.
221
+
222
+ #### `securityScan(): string[]`
223
+
224
+ Check for security issues and return findings.
225
+
226
+ ## Supported Models
227
+
228
+ - **Claude** - Anthropic's Claude models
229
+ - **GPT-4o** - OpenAI's GPT-4o
230
+ - **GPT-4** - OpenAI's GPT-4
231
+ - **Gemini** - Google's Gemini
232
+ - **Llama** - Meta's Llama
233
+
234
+ ## Compression Levels
235
+
236
+ - **none** - No compression (0% reduction)
237
+ - **minimal** - Remove empty lines, trim whitespace (~15% reduction)
238
+ - **balanced** - Remove comments, normalize whitespace (~35% reduction)
239
+ - **aggressive** - Remove docstrings, keep signatures only (~60% reduction)
240
+ - **extreme** - Key symbols only (~80% reduction)
241
+ - **focused** - Key symbols with small context (~75% reduction)
242
+ - **semantic** - Heuristic semantic compression (~60-70% reduction)
243
+
244
+ ## Output Formats
245
+
246
+ - **xml** - XML format optimized for Claude
247
+ - **markdown** - Markdown format for GPT models
248
+ - **json** - JSON format for programmatic access
249
+ - **yaml** - YAML format optimized for Gemini
250
+ - **toon** - Token-efficient format (~40% smaller than JSON)
251
+ - **plain** - Simple plain text format
252
+
253
+ ## Security Scanning
254
+
255
+ Infiniloom automatically scans for sensitive data including:
256
+
257
+ - API keys
258
+ - Access tokens
259
+ - Private keys
260
+ - Passwords
261
+ - Database connection strings
262
+ - AWS credentials
263
+ - GitHub tokens
264
+
265
+ Critical security issues will prevent packing unless `skipSecurity: true` is set.
266
+
267
+ ## Building from Source
268
+
269
+ ```bash
270
+ # Install dependencies
271
+ npm install
272
+
273
+ # Build native addon
274
+ npm run build
275
+
276
+ # Build for release
277
+ npm run build --release
278
+ ```
279
+
280
+ ## Requirements
281
+
282
+ - Node.js >= 16
283
+ - Rust >= 1.91 (for building from source)
284
+
285
+ ## License
286
+
287
+ MIT
288
+
289
+ ## Links
290
+
291
+ - [GitHub Repository](https://github.com/Topos-Labs/infiniloom)
292
+ - [Documentation](https://infiniloom.dev/docs)
293
+ - [npm Package](https://www.npmjs.com/package/@infiniloom/node)
package/index.d.ts ADDED
@@ -0,0 +1,396 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /** Options for packing a repository */
7
+ export interface PackOptions {
8
+ /** Output format: "xml", "markdown", "json", or "yaml" */
9
+ format?: string
10
+ /** Target model: "claude", "gpt-4o", "gpt-4", "gemini", or "llama" */
11
+ model?: string
12
+ /** Compression level: "none", "minimal", "balanced", "aggressive", "extreme", "focused", "semantic" */
13
+ compression?: string
14
+ /** Token budget for repository map */
15
+ mapBudget?: number
16
+ /** Maximum number of symbols in map */
17
+ maxSymbols?: number
18
+ /** Skip security scanning (fail on critical findings) */
19
+ skipSecurity?: boolean
20
+ /** Redact detected secrets in output (default: true) */
21
+ redactSecrets?: boolean
22
+ /** Skip symbol extraction for faster scanning */
23
+ skipSymbols?: boolean
24
+ }
25
+ /** Statistics from scanning a repository */
26
+ export interface ScanStats {
27
+ /** Repository name */
28
+ name: string
29
+ /** Total number of files */
30
+ totalFiles: number
31
+ /** Total lines of code */
32
+ totalLines: number
33
+ /** Total tokens for target model */
34
+ totalTokens: number
35
+ /** Primary language */
36
+ primaryLanguage?: string
37
+ /** Language breakdown */
38
+ languages: Array<LanguageStat>
39
+ /** Number of security findings */
40
+ securityFindings: number
41
+ }
42
+ /** Statistics for a single language */
43
+ export interface LanguageStat {
44
+ /** Language name */
45
+ language: string
46
+ /** Number of files */
47
+ files: number
48
+ /** Total lines */
49
+ lines: number
50
+ /** Percentage of codebase */
51
+ percentage: number
52
+ }
53
+ /**
54
+ * Pack a repository into optimized LLM context
55
+ *
56
+ * # Arguments
57
+ * * `path` - Path to repository root
58
+ * * `options` - Optional packing options
59
+ *
60
+ * # Returns
61
+ * Formatted repository context as a string
62
+ *
63
+ * # Example
64
+ * ```javascript
65
+ * const { pack } = require('@infiniloom/node');
66
+ *
67
+ * const context = pack('./my-repo', {
68
+ * format: 'xml',
69
+ * model: 'claude',
70
+ * compression: 'balanced',
71
+ * mapBudget: 2000
72
+ * });
73
+ * ```
74
+ */
75
+ export declare function pack(path: string, options?: PackOptions | undefined | null): string
76
+ /**
77
+ * Scan a repository and return statistics
78
+ *
79
+ * # Arguments
80
+ * * `path` - Path to repository root
81
+ * * `model` - Optional target model (default: "claude")
82
+ *
83
+ * # Returns
84
+ * Repository statistics
85
+ *
86
+ * # Example
87
+ * ```javascript
88
+ * const { scan } = require('@infiniloom/node');
89
+ *
90
+ * const stats = scan('./my-repo', 'claude');
91
+ * console.log(`Total files: ${stats.totalFiles}`);
92
+ * console.log(`Total tokens: ${stats.totalTokens}`);
93
+ * ```
94
+ */
95
+ export declare function scan(path: string, model?: string | undefined | null): ScanStats
96
+ /**
97
+ * Count tokens in text for a specific model
98
+ *
99
+ * # Arguments
100
+ * * `text` - Text to tokenize
101
+ * * `model` - Optional model name (default: "claude")
102
+ *
103
+ * # Returns
104
+ * Token count (exact for OpenAI models via tiktoken, calibrated estimates for others)
105
+ *
106
+ * # Example
107
+ * ```javascript
108
+ * const { countTokens } = require('@infiniloom/node');
109
+ *
110
+ * const count = countTokens('Hello, world!', 'claude');
111
+ * console.log(`Tokens: ${count}`);
112
+ * ```
113
+ */
114
+ export declare function countTokens(text: string, model?: string | undefined | null): number
115
+ /**
116
+ * Compress text using semantic compression
117
+ *
118
+ * Uses heuristic-based compression to reduce content while preserving meaning.
119
+ * When built with the "embeddings" feature, uses neural networks for clustering.
120
+ *
121
+ * # Arguments
122
+ * * `text` - Text to compress
123
+ * * `similarity_threshold` - Threshold for grouping similar chunks (0.0-1.0, default: 0.7)
124
+ * * `budget_ratio` - Target size as ratio of original (0.0-1.0, default: 0.5)
125
+ *
126
+ * # Returns
127
+ * Compressed text
128
+ *
129
+ * # Example
130
+ * ```javascript
131
+ * const { semanticCompress } = require('@infiniloom/node');
132
+ *
133
+ * const compressed = semanticCompress(longText, 0.7, 0.3);
134
+ * ```
135
+ */
136
+ export declare function semanticCompress(text: string, similarityThreshold?: number | undefined | null, budgetRatio?: number | undefined | null): string
137
+ /**
138
+ * Check if a path is a git repository
139
+ *
140
+ * # Arguments
141
+ * * `path` - Path to check
142
+ *
143
+ * # Returns
144
+ * True if path is a git repository, false otherwise
145
+ *
146
+ * # Example
147
+ * ```javascript
148
+ * const { isGitRepo } = require('@infiniloom/node');
149
+ *
150
+ * if (isGitRepo('./my-project')) {
151
+ * console.log('This is a git repository');
152
+ * }
153
+ * ```
154
+ */
155
+ export declare function isGitRepo(path: string): boolean
156
+ /** File status information */
157
+ export interface GitFileStatus {
158
+ /** File path */
159
+ path: string
160
+ /** Old path (for renames) */
161
+ oldPath?: string
162
+ /** Status: "Added", "Modified", "Deleted", "Renamed", "Copied", "Unknown" */
163
+ status: string
164
+ }
165
+ /** Changed file with diff stats */
166
+ export interface GitChangedFile {
167
+ /** File path */
168
+ path: string
169
+ /** Old path (for renames) */
170
+ oldPath?: string
171
+ /** Status: "Added", "Modified", "Deleted", "Renamed", "Copied", "Unknown" */
172
+ status: string
173
+ /** Number of lines added */
174
+ additions: number
175
+ /** Number of lines deleted */
176
+ deletions: number
177
+ }
178
+ /** Commit information */
179
+ export interface GitCommit {
180
+ /** Full commit hash */
181
+ hash: string
182
+ /** Short commit hash (7 characters) */
183
+ shortHash: string
184
+ /** Author name */
185
+ author: string
186
+ /** Author email */
187
+ email: string
188
+ /** Commit date (ISO 8601 format) */
189
+ date: string
190
+ /** Commit message (first line) */
191
+ message: string
192
+ }
193
+ /** Blame line information */
194
+ export interface GitBlameLine {
195
+ /** Commit hash that introduced the line */
196
+ commit: string
197
+ /** Author who wrote the line */
198
+ author: string
199
+ /** Date when line was written */
200
+ date: string
201
+ /** Line number (1-indexed) */
202
+ lineNumber: number
203
+ }
204
+ /** Infiniloom class for advanced usage */
205
+ export declare class Infiniloom {
206
+ /**
207
+ * Create a new Infiniloom instance
208
+ *
209
+ * # Arguments
210
+ * * `path` - Path to repository root
211
+ * * `model` - Optional model name (default: "claude")
212
+ */
213
+ constructor(path: string, model?: string | undefined | null)
214
+ /** Get repository statistics */
215
+ getStats(): ScanStats
216
+ /**
217
+ * Generate a repository map
218
+ *
219
+ * # Arguments
220
+ * * `budget` - Token budget (default: 2000)
221
+ * * `max_symbols` - Maximum symbols (default: 50)
222
+ */
223
+ generateMap(budget?: number | undefined | null, maxSymbols?: number | undefined | null): string
224
+ /** Pack repository with specific options */
225
+ pack(options?: PackOptions | undefined | null): string
226
+ /** Check for security issues */
227
+ securityScan(): Array<string>
228
+ }
229
+ /**
230
+ * Git repository wrapper for Node.js
231
+ *
232
+ * Provides access to git operations like status, diff, log, and blame.
233
+ *
234
+ * # Example
235
+ * ```javascript
236
+ * const { GitRepo } = require('@infiniloom/node');
237
+ *
238
+ * const repo = new GitRepo('./my-project');
239
+ * console.log(`Branch: ${repo.currentBranch()}`);
240
+ * console.log(`Commit: ${repo.currentCommit()}`);
241
+ *
242
+ * for (const file of repo.status()) {
243
+ * console.log(`${file.status}: ${file.path}`);
244
+ * }
245
+ * ```
246
+ */
247
+ export declare class GitRepo {
248
+ /**
249
+ * Open a git repository
250
+ *
251
+ * # Arguments
252
+ * * `path` - Path to the repository
253
+ *
254
+ * # Throws
255
+ * Error if path is not a git repository
256
+ */
257
+ constructor(path: string)
258
+ /**
259
+ * Get the current branch name
260
+ *
261
+ * # Returns
262
+ * Current branch name (e.g., "main", "feature/xyz")
263
+ */
264
+ currentBranch(): string
265
+ /**
266
+ * Get the current commit hash
267
+ *
268
+ * # Returns
269
+ * Full SHA-1 hash of HEAD commit
270
+ */
271
+ currentCommit(): string
272
+ /**
273
+ * Get working tree status
274
+ *
275
+ * Returns both staged and unstaged changes.
276
+ *
277
+ * # Returns
278
+ * Array of file status objects
279
+ */
280
+ status(): Array<GitFileStatus>
281
+ /**
282
+ * Get files changed between two commits
283
+ *
284
+ * # Arguments
285
+ * * `from_ref` - Starting commit/branch/tag
286
+ * * `to_ref` - Ending commit/branch/tag
287
+ *
288
+ * # Returns
289
+ * Array of changed files with diff stats
290
+ */
291
+ diffFiles(fromRef: string, toRef: string): Array<GitChangedFile>
292
+ /**
293
+ * Get recent commits
294
+ *
295
+ * # Arguments
296
+ * * `count` - Maximum number of commits to return (default: 10)
297
+ *
298
+ * # Returns
299
+ * Array of commit objects
300
+ */
301
+ log(count?: number | undefined | null): Array<GitCommit>
302
+ /**
303
+ * Get commits that modified a specific file
304
+ *
305
+ * # Arguments
306
+ * * `path` - File path (relative to repo root)
307
+ * * `count` - Maximum number of commits to return (default: 10)
308
+ *
309
+ * # Returns
310
+ * Array of commits that modified the file
311
+ */
312
+ fileLog(path: string, count?: number | undefined | null): Array<GitCommit>
313
+ /**
314
+ * Get blame information for a file
315
+ *
316
+ * # Arguments
317
+ * * `path` - File path (relative to repo root)
318
+ *
319
+ * # Returns
320
+ * Array of blame line objects
321
+ */
322
+ blame(path: string): Array<GitBlameLine>
323
+ /**
324
+ * Get list of files tracked by git
325
+ *
326
+ * # Returns
327
+ * Array of file paths tracked by git
328
+ */
329
+ lsFiles(): Array<string>
330
+ /**
331
+ * Get diff content between two commits for a file
332
+ *
333
+ * # Arguments
334
+ * * `from_ref` - Starting commit/branch/tag
335
+ * * `to_ref` - Ending commit/branch/tag
336
+ * * `path` - File path (relative to repo root)
337
+ *
338
+ * # Returns
339
+ * Unified diff content as string
340
+ */
341
+ diffContent(fromRef: string, toRef: string, path: string): string
342
+ /**
343
+ * Get diff content for uncommitted changes in a file
344
+ *
345
+ * Includes both staged and unstaged changes compared to HEAD.
346
+ *
347
+ * # Arguments
348
+ * * `path` - File path (relative to repo root)
349
+ *
350
+ * # Returns
351
+ * Unified diff content as string
352
+ */
353
+ uncommittedDiff(path: string): string
354
+ /**
355
+ * Get diff for all uncommitted changes
356
+ *
357
+ * Returns combined diff for all changed files.
358
+ *
359
+ * # Returns
360
+ * Unified diff content as string
361
+ */
362
+ allUncommittedDiffs(): string
363
+ /**
364
+ * Check if a file has uncommitted changes
365
+ *
366
+ * # Arguments
367
+ * * `path` - File path (relative to repo root)
368
+ *
369
+ * # Returns
370
+ * True if file has changes, false otherwise
371
+ */
372
+ hasChanges(path: string): boolean
373
+ /**
374
+ * Get the last commit that modified a file
375
+ *
376
+ * # Arguments
377
+ * * `path` - File path (relative to repo root)
378
+ *
379
+ * # Returns
380
+ * Commit information object
381
+ */
382
+ lastModifiedCommit(path: string): GitCommit
383
+ /**
384
+ * Get file change frequency in recent days
385
+ *
386
+ * Useful for determining file importance based on recent activity.
387
+ *
388
+ * # Arguments
389
+ * * `path` - File path (relative to repo root)
390
+ * * `days` - Number of days to look back (default: 30)
391
+ *
392
+ * # Returns
393
+ * Number of commits that modified the file in the period
394
+ */
395
+ fileChangeFrequency(path: string, days?: number | undefined | null): number
396
+ }
package/index.js ADDED
@@ -0,0 +1,321 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'infiniloom.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./infiniloom.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('@infiniloom/node-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'infiniloom.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./infiniloom.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('@infiniloom/node-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'infiniloom.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./infiniloom.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('@infiniloom/node-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'infiniloom.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./infiniloom.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('@infiniloom/node-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'infiniloom.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./infiniloom.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('@infiniloom/node-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'infiniloom.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./infiniloom.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('@infiniloom/node-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'infiniloom.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./infiniloom.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('@infiniloom/node-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'infiniloom.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./infiniloom.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('@infiniloom/node-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'infiniloom.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./infiniloom.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('@infiniloom/node-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'infiniloom.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./infiniloom.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('@infiniloom/node-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'infiniloom.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./infiniloom.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('@infiniloom/node-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'infiniloom.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./infiniloom.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('@infiniloom/node-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'infiniloom.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./infiniloom.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('@infiniloom/node-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'infiniloom.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./infiniloom.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@infiniloom/node-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'infiniloom.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./infiniloom.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@infiniloom/node-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'infiniloom.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./infiniloom.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@infiniloom/node-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'infiniloom.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./infiniloom.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@infiniloom/node-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'infiniloom.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./infiniloom.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('@infiniloom/node-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { pack, scan, countTokens, Infiniloom, semanticCompress, isGitRepo, GitRepo } = nativeBinding
314
+
315
+ module.exports.pack = pack
316
+ module.exports.scan = scan
317
+ module.exports.countTokens = countTokens
318
+ module.exports.Infiniloom = Infiniloom
319
+ module.exports.semanticCompress = semanticCompress
320
+ module.exports.isGitRepo = isGitRepo
321
+ module.exports.GitRepo = GitRepo
Binary file
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "infiniloom-node",
3
+ "version": "0.1.0",
4
+ "description": "Node.js bindings for infiniloom - Repository context engine for LLMs",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "napi": {
8
+ "name": "infiniloom",
9
+ "triples": {
10
+ "defaults": true,
11
+ "additional": [
12
+ "x86_64-unknown-linux-musl",
13
+ "aarch64-unknown-linux-gnu",
14
+ "armv7-unknown-linux-gnueabihf",
15
+ "aarch64-apple-darwin",
16
+ "aarch64-linux-android",
17
+ "x86_64-unknown-freebsd",
18
+ "aarch64-unknown-linux-musl",
19
+ "aarch64-pc-windows-msvc"
20
+ ]
21
+ }
22
+ },
23
+ "author": "Topos Labs",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/Topos-Labs/infiniloom.git",
28
+ "directory": "bindings/node"
29
+ },
30
+ "keywords": [
31
+ "infiniloom",
32
+ "llm",
33
+ "context",
34
+ "repository",
35
+ "code-analysis",
36
+ "napi-rs",
37
+ "rust"
38
+ ],
39
+ "engines": {
40
+ "node": ">= 16"
41
+ },
42
+ "publishConfig": {
43
+ "registry": "https://registry.npmjs.org/",
44
+ "access": "public"
45
+ },
46
+ "scripts": {
47
+ "artifacts": "napi artifacts",
48
+ "build": "napi build --platform --release",
49
+ "build:debug": "napi build --platform",
50
+ "prepublishOnly": "napi prepublish -t npm",
51
+ "test": "node --test",
52
+ "version": "napi version"
53
+ },
54
+ "devDependencies": {
55
+ "@napi-rs/cli": "^2.18.0"
56
+ },
57
+ "files": [
58
+ "index.js",
59
+ "index.d.ts",
60
+ "*.node"
61
+ ],
62
+ "bugs": {
63
+ "url": "https://github.com/Topos-Labs/infiniloom/issues"
64
+ },
65
+ "homepage": "https://github.com/Topos-Labs/infiniloom#readme"
66
+ }