infiniloom-node 0.3.2 → 0.4.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 CHANGED
@@ -221,6 +221,105 @@ for (const finding of findings) {
221
221
  }
222
222
  ```
223
223
 
224
+ ### Call Graph API
225
+
226
+ Query caller/callee relationships and navigate your codebase programmatically.
227
+
228
+ #### `buildIndex(path: string, options?: IndexOptions): IndexStatus`
229
+
230
+ Build or update the symbol index for a repository (required for call graph queries).
231
+
232
+ ```javascript
233
+ const { buildIndex } = require('infiniloom-node');
234
+
235
+ const status = buildIndex('./my-repo');
236
+ console.log(`Indexed ${status.symbolCount} symbols`);
237
+ ```
238
+
239
+ #### `findSymbol(path: string, name: string): SymbolInfo[]`
240
+
241
+ Find symbols by name.
242
+
243
+ ```javascript
244
+ const { findSymbol, buildIndex } = require('infiniloom-node');
245
+
246
+ buildIndex('./my-repo');
247
+ const symbols = findSymbol('./my-repo', 'processRequest');
248
+ for (const s of symbols) {
249
+ console.log(`${s.name} (${s.kind}) at ${s.file}:${s.line}`);
250
+ }
251
+ ```
252
+
253
+ #### `getCallers(path: string, symbolName: string): SymbolInfo[]`
254
+
255
+ Get all functions/methods that call the target symbol.
256
+
257
+ ```javascript
258
+ const { getCallers, buildIndex } = require('infiniloom-node');
259
+
260
+ buildIndex('./my-repo');
261
+ const callers = getCallers('./my-repo', 'authenticate');
262
+ console.log(`authenticate is called by ${callers.length} functions`);
263
+ for (const c of callers) {
264
+ console.log(` ${c.name} at ${c.file}:${c.line}`);
265
+ }
266
+ ```
267
+
268
+ #### `getCallees(path: string, symbolName: string): SymbolInfo[]`
269
+
270
+ Get all functions/methods that the target symbol calls.
271
+
272
+ ```javascript
273
+ const { getCallees, buildIndex } = require('infiniloom-node');
274
+
275
+ buildIndex('./my-repo');
276
+ const callees = getCallees('./my-repo', 'main');
277
+ console.log(`main calls ${callees.length} functions`);
278
+ ```
279
+
280
+ #### `getReferences(path: string, symbolName: string): ReferenceInfo[]`
281
+
282
+ Get all references to a symbol (calls, imports, inheritance).
283
+
284
+ ```javascript
285
+ const { getReferences, buildIndex } = require('infiniloom-node');
286
+
287
+ buildIndex('./my-repo');
288
+ const refs = getReferences('./my-repo', 'UserService');
289
+ for (const r of refs) {
290
+ console.log(`${r.kind}: ${r.symbol.name} at ${r.symbol.file}:${r.symbol.line}`);
291
+ }
292
+ ```
293
+
294
+ #### `getCallGraph(path: string, options?: CallGraphOptions): CallGraph`
295
+
296
+ Get the complete call graph with all symbols and call relationships.
297
+
298
+ ```javascript
299
+ const { getCallGraph, buildIndex } = require('infiniloom-node');
300
+
301
+ buildIndex('./my-repo');
302
+ const graph = getCallGraph('./my-repo');
303
+ console.log(`${graph.stats.totalSymbols} symbols, ${graph.stats.totalCalls} calls`);
304
+
305
+ // Find most called functions
306
+ const callCounts = new Map();
307
+ for (const edge of graph.edges) {
308
+ callCounts.set(edge.callee, (callCounts.get(edge.callee) || 0) + 1);
309
+ }
310
+ const sorted = [...callCounts.entries()].sort((a, b) => b[1] - a[1]);
311
+ console.log('Most called:', sorted.slice(0, 5));
312
+ ```
313
+
314
+ #### Async versions
315
+
316
+ All call graph functions have async versions:
317
+ - `findSymbolAsync(path, name)`
318
+ - `getCallersAsync(path, symbolName)`
319
+ - `getCalleesAsync(path, symbolName)`
320
+ - `getReferencesAsync(path, symbolName)`
321
+ - `getCallGraphAsync(path, options)`
322
+
224
323
  #### `isGitRepo(path: string): boolean`
225
324
 
226
325
  Check if a path is a git repository.
@@ -257,6 +356,13 @@ interface PackOptions {
257
356
  includeTests?: boolean; // Include test files (default: false)
258
357
  securityThreshold?: string;// Minimum severity to block: "critical", "high", "medium", "low"
259
358
  tokenBudget?: number; // Limit total output tokens (0 = no limit)
359
+ // Git-based filtering options (PR review integration)
360
+ changedOnly?: boolean; // Only include files changed in git
361
+ baseSha?: string; // Base SHA/ref for diff comparison (e.g., "main", "HEAD~5")
362
+ headSha?: string; // Head SHA/ref for diff comparison (default: working tree)
363
+ stagedOnly?: boolean; // Include staged changes only
364
+ includeRelated?: boolean; // Include related files (importers/dependencies)
365
+ relatedDepth?: number; // Depth for related file traversal (1-3, default: 1)
260
366
  }
261
367
  ```
262
368
 
@@ -355,6 +461,30 @@ interface GitBlameLine {
355
461
  }
356
462
  ```
357
463
 
464
+ #### `GitDiffLine`
465
+
466
+ ```typescript
467
+ interface GitDiffLine {
468
+ changeType: string; // "add", "remove", or "context"
469
+ oldLine?: number; // Line number in old file (for remove/context)
470
+ newLine?: number; // Line number in new file (for add/context)
471
+ content: string; // Line content (without +/- prefix)
472
+ }
473
+ ```
474
+
475
+ #### `GitDiffHunk`
476
+
477
+ ```typescript
478
+ interface GitDiffHunk {
479
+ oldStart: number; // Starting line in old file
480
+ oldCount: number; // Number of lines in old file
481
+ newStart: number; // Starting line in new file
482
+ newCount: number; // Number of lines in new file
483
+ header: string; // Hunk header (e.g., "@@ -1,5 +1,6 @@ function name")
484
+ lines: GitDiffLine[]; // Lines in this hunk
485
+ }
486
+ ```
487
+
358
488
  ### Infiniloom Class
359
489
 
360
490
  #### `new Infiniloom(path: string, model?: string)`
@@ -499,6 +629,75 @@ Get file change frequency in recent days.
499
629
 
500
630
  **Returns:** Number of commits that modified the file in the period
501
631
 
632
+ #### `fileAtRef(path: string, gitRef: string): string`
633
+
634
+ Get file content at a specific git ref (commit, branch, tag).
635
+
636
+ **Parameters:**
637
+ - `path` - File path relative to repo root
638
+ - `gitRef` - Git ref (commit hash, branch name, tag, HEAD~n, etc.)
639
+
640
+ **Returns:** File content as string
641
+
642
+ ```javascript
643
+ const repo = new GitRepo('./my-project');
644
+ const oldVersion = repo.fileAtRef('src/main.js', 'HEAD~5');
645
+ const mainVersion = repo.fileAtRef('src/main.js', 'main');
646
+ ```
647
+
648
+ #### `diffHunks(fromRef: string, toRef: string, path?: string): GitDiffHunk[]`
649
+
650
+ Parse diff between two refs into structured hunks with line-level changes.
651
+ Useful for PR review tools that need to post comments at specific lines.
652
+
653
+ **Parameters:**
654
+ - `fromRef` - Starting ref (e.g., "main", "HEAD~5", commit hash)
655
+ - `toRef` - Ending ref (e.g., "HEAD", "feature-branch")
656
+ - `path` - Optional file path to filter to a single file
657
+
658
+ **Returns:** Array of diff hunks with line-level change information
659
+
660
+ ```javascript
661
+ const repo = new GitRepo('./my-project');
662
+ const hunks = repo.diffHunks('main', 'HEAD', 'src/index.js');
663
+ for (const hunk of hunks) {
664
+ console.log(`Hunk at old:${hunk.oldStart} new:${hunk.newStart}`);
665
+ for (const line of hunk.lines) {
666
+ console.log(`${line.changeType}: ${line.content}`);
667
+ }
668
+ }
669
+ ```
670
+
671
+ #### `uncommittedHunks(path?: string): GitDiffHunk[]`
672
+
673
+ Parse uncommitted changes (working tree vs HEAD) into structured hunks.
674
+
675
+ **Parameters:**
676
+ - `path` - Optional file path to filter to a single file
677
+
678
+ **Returns:** Array of diff hunks for uncommitted changes
679
+
680
+ ```javascript
681
+ const repo = new GitRepo('./my-project');
682
+ const hunks = repo.uncommittedHunks('src/index.js');
683
+ console.log(`${hunks.length} hunks with uncommitted changes`);
684
+ ```
685
+
686
+ #### `stagedHunks(path?: string): GitDiffHunk[]`
687
+
688
+ Parse staged changes into structured hunks.
689
+
690
+ **Parameters:**
691
+ - `path` - Optional file path to filter to a single file
692
+
693
+ **Returns:** Array of diff hunks for staged changes only
694
+
695
+ ```javascript
696
+ const repo = new GitRepo('./my-project');
697
+ const hunks = repo.stagedHunks('src/index.js');
698
+ console.log(`${hunks.length} hunks staged for commit`);
699
+ ```
700
+
502
701
  **Example:**
503
702
 
504
703
  ```javascript
package/index.d.ts CHANGED
@@ -31,6 +31,18 @@ export interface PackOptions {
31
31
  securityThreshold?: string
32
32
  /** Token budget for total output (0 = no limit). Files are included by importance until budget is reached. */
33
33
  tokenBudget?: number
34
+ /** Only include files changed in git (requires baseSha or uses uncommitted changes) */
35
+ changedOnly?: boolean
36
+ /** Base SHA/ref for diff comparison (e.g., "main", "HEAD~5", commit hash) */
37
+ baseSha?: string
38
+ /** Head SHA/ref for diff comparison (default: working tree or HEAD) */
39
+ headSha?: string
40
+ /** Include staged changes only (if changedOnly is true and no refs specified) */
41
+ stagedOnly?: boolean
42
+ /** Include related files (importers/dependencies of changed files) */
43
+ includeRelated?: boolean
44
+ /** Depth for related file traversal (1-3, default: 1) */
45
+ relatedDepth?: number
34
46
  }
35
47
  /** Statistics from scanning a repository */
36
48
  export interface ScanStats {
@@ -246,6 +258,32 @@ export interface GitBlameLine {
246
258
  /** Line number (1-indexed) */
247
259
  lineNumber: number
248
260
  }
261
+ /** Diff line information for structured diff parsing */
262
+ export interface GitDiffLine {
263
+ /** Change type: "add", "remove", or "context" */
264
+ changeType: string
265
+ /** Line number in old file (for remove/context lines) */
266
+ oldLine?: number
267
+ /** Line number in new file (for add/context lines) */
268
+ newLine?: number
269
+ /** Line content (without +/- prefix) */
270
+ content: string
271
+ }
272
+ /** Diff hunk information for structured diff parsing */
273
+ export interface GitDiffHunk {
274
+ /** Starting line in old file */
275
+ oldStart: number
276
+ /** Number of lines in old file */
277
+ oldCount: number
278
+ /** Starting line in new file */
279
+ newStart: number
280
+ /** Number of lines in new file */
281
+ newCount: number
282
+ /** Hunk header (e.g., "@@ -1,5 +1,6 @@ function name") */
283
+ header: string
284
+ /** Lines in this hunk */
285
+ lines: Array<GitDiffLine>
286
+ }
249
287
  /** Security finding information */
250
288
  export interface SecurityFinding {
251
289
  /** File where the finding was detected */
@@ -473,4 +511,698 @@ export declare class GitRepo {
473
511
  * Number of commits that modified the file in the period
474
512
  */
475
513
  fileChangeFrequency(path: string, days?: number | undefined | null): number
514
+ /**
515
+ * Get file content at a specific git ref (commit, branch, tag)
516
+ *
517
+ * Uses `git show <ref>:<path>` to retrieve file content at that revision.
518
+ *
519
+ * # Arguments
520
+ * * `path` - File path (relative to repo root)
521
+ * * `gitRef` - Git ref (commit hash, branch name, tag, HEAD~n, etc.)
522
+ *
523
+ * # Returns
524
+ * File content as string
525
+ *
526
+ * # Example
527
+ * ```javascript
528
+ * const repo = new GitRepo('./my-project');
529
+ * const oldVersion = repo.fileAtRef('src/main.js', 'HEAD~5');
530
+ * const mainVersion = repo.fileAtRef('src/main.js', 'main');
531
+ * ```
532
+ */
533
+ fileAtRef(path: string, gitRef: string): string
534
+ /**
535
+ * Parse diff between two refs into structured hunks
536
+ *
537
+ * Returns detailed hunk information including line numbers for each change.
538
+ * Useful for PR review tools that need to post comments at specific lines.
539
+ *
540
+ * # Arguments
541
+ * * `fromRef` - Starting ref (e.g., "main", "HEAD~5", commit hash)
542
+ * * `toRef` - Ending ref (e.g., "HEAD", "feature-branch")
543
+ * * `path` - Optional file path to filter to a single file
544
+ *
545
+ * # Returns
546
+ * Array of diff hunks with line-level change information
547
+ *
548
+ * # Example
549
+ * ```javascript
550
+ * const repo = new GitRepo('./my-project');
551
+ * const hunks = repo.diffHunks('main', 'HEAD', 'src/index.js');
552
+ * for (const hunk of hunks) {
553
+ * console.log(`Hunk at old:${hunk.oldStart} new:${hunk.newStart}`);
554
+ * for (const line of hunk.lines) {
555
+ * console.log(`${line.changeType}: ${line.content}`);
556
+ * }
557
+ * }
558
+ * ```
559
+ */
560
+ diffHunks(fromRef: string, toRef: string, path?: string | undefined | null): Array<GitDiffHunk>
561
+ /**
562
+ * Parse uncommitted changes (working tree vs HEAD) into structured hunks
563
+ *
564
+ * # Arguments
565
+ * * `path` - Optional file path to filter to a single file
566
+ *
567
+ * # Returns
568
+ * Array of diff hunks for uncommitted changes
569
+ *
570
+ * # Example
571
+ * ```javascript
572
+ * const repo = new GitRepo('./my-project');
573
+ * const hunks = repo.uncommittedHunks('src/index.js');
574
+ * console.log(`${hunks.length} hunks with uncommitted changes`);
575
+ * ```
576
+ */
577
+ uncommittedHunks(path?: string | undefined | null): Array<GitDiffHunk>
578
+ /**
579
+ * Parse staged changes into structured hunks
580
+ *
581
+ * # Arguments
582
+ * * `path` - Optional file path to filter to a single file
583
+ *
584
+ * # Returns
585
+ * Array of diff hunks for staged changes only
586
+ *
587
+ * # Example
588
+ * ```javascript
589
+ * const repo = new GitRepo('./my-project');
590
+ * const hunks = repo.stagedHunks('src/index.js');
591
+ * console.log(`${hunks.length} hunks staged for commit`);
592
+ * ```
593
+ */
594
+ stagedHunks(path?: string | undefined | null): Array<GitDiffHunk>
595
+ }
596
+
597
+ // ============================================================================
598
+ // Index API - Build and query symbol indexes
599
+ // ============================================================================
600
+
601
+ /** Options for building an index */
602
+ export interface IndexOptions {
603
+ /** Force full rebuild even if index exists */
604
+ force?: boolean
605
+ /** Include test files in index */
606
+ includeTests?: boolean
607
+ /** Maximum file size to index (bytes) */
608
+ maxFileSize?: number
609
+ }
610
+
611
+ /** Index status information */
612
+ export interface IndexStatus {
613
+ /** Whether an index exists */
614
+ exists: boolean
615
+ /** Number of files indexed */
616
+ fileCount: number
617
+ /** Number of symbols indexed */
618
+ symbolCount: number
619
+ /** Last build timestamp (ISO 8601) */
620
+ lastBuilt?: string
621
+ /** Index version */
622
+ version?: string
623
+ }
624
+
625
+ /**
626
+ * Build or update the symbol index for a repository
627
+ *
628
+ * The index enables fast diff-to-context lookups and impact analysis.
629
+ *
630
+ * # Arguments
631
+ * * `path` - Path to repository root
632
+ * * `options` - Optional index build options
633
+ *
634
+ * # Returns
635
+ * Index status after building
636
+ *
637
+ * # Example
638
+ * ```javascript
639
+ * const { buildIndex } = require('infiniloom-node');
640
+ *
641
+ * const status = buildIndex('./my-repo');
642
+ * console.log(`Indexed ${status.symbolCount} symbols`);
643
+ *
644
+ * // Force rebuild
645
+ * const status2 = buildIndex('./my-repo', { force: true });
646
+ * ```
647
+ */
648
+ export declare function buildIndex(path: string, options?: IndexOptions | undefined | null): IndexStatus
649
+
650
+ /**
651
+ * Get the status of an existing index
652
+ *
653
+ * # Arguments
654
+ * * `path` - Path to repository root
655
+ *
656
+ * # Returns
657
+ * Index status information
658
+ *
659
+ * # Example
660
+ * ```javascript
661
+ * const { indexStatus } = require('infiniloom-node');
662
+ *
663
+ * const status = indexStatus('./my-repo');
664
+ * if (status.exists) {
665
+ * console.log(`Index has ${status.symbolCount} symbols`);
666
+ * } else {
667
+ * console.log('No index found, run buildIndex first');
668
+ * }
669
+ * ```
670
+ */
671
+ export declare function indexStatus(path: string): IndexStatus
672
+
673
+ // ============================================================================
674
+ // Call Graph API - Query symbol relationships
675
+ // ============================================================================
676
+
677
+ /** Information about a symbol in the call graph */
678
+ export interface SymbolInfo {
679
+ /** Symbol ID */
680
+ id: number
681
+ /** Symbol name */
682
+ name: string
683
+ /** Symbol kind (function, class, method, etc.) */
684
+ kind: string
685
+ /** File path containing the symbol */
686
+ file: string
687
+ /** Start line number */
688
+ line: number
689
+ /** End line number */
690
+ endLine: number
691
+ /** Function/method signature */
692
+ signature?: string
693
+ /** Visibility (public, private, etc.) */
694
+ visibility: string
695
+ }
696
+
697
+ /** A reference to a symbol with context */
698
+ export interface ReferenceInfo {
699
+ /** Symbol making the reference */
700
+ symbol: SymbolInfo
701
+ /** Reference kind (call, import, inherit, implement) */
702
+ kind: string
703
+ }
704
+
705
+ /** An edge in the call graph */
706
+ export interface CallGraphEdge {
707
+ /** Caller symbol ID */
708
+ callerId: number
709
+ /** Callee symbol ID */
710
+ calleeId: number
711
+ /** Caller symbol name */
712
+ caller: string
713
+ /** Callee symbol name */
714
+ callee: string
715
+ /** File containing the call site */
716
+ file: string
717
+ /** Line number of the call */
718
+ line: number
719
+ }
720
+
721
+ /** Call graph statistics */
722
+ export interface CallGraphStats {
723
+ /** Total number of symbols */
724
+ totalSymbols: number
725
+ /** Total number of call edges */
726
+ totalCalls: number
727
+ /** Number of functions/methods */
728
+ functions: number
729
+ /** Number of classes/structs */
730
+ classes: number
731
+ }
732
+
733
+ /** Complete call graph with nodes and edges */
734
+ export interface CallGraph {
735
+ /** All symbols (nodes) */
736
+ nodes: Array<SymbolInfo>
737
+ /** Call relationships (edges) */
738
+ edges: Array<CallGraphEdge>
739
+ /** Summary statistics */
740
+ stats: CallGraphStats
741
+ }
742
+
743
+ /** Options for call graph queries */
744
+ export interface CallGraphOptions {
745
+ /** Maximum number of nodes to return (default: unlimited) */
746
+ maxNodes?: number
747
+ /** Maximum number of edges to return (default: unlimited) */
748
+ maxEdges?: number
749
+ }
750
+
751
+ /**
752
+ * Find a symbol by name
753
+ *
754
+ * Searches the index for all symbols matching the given name.
755
+ * Requires an index to be built first (use buildIndex).
756
+ *
757
+ * # Arguments
758
+ * * `path` - Path to repository root
759
+ * * `name` - Symbol name to search for
760
+ *
761
+ * # Returns
762
+ * Array of matching symbols
763
+ *
764
+ * # Example
765
+ * ```javascript
766
+ * const { findSymbol, buildIndex } = require('infiniloom-node');
767
+ *
768
+ * buildIndex('./my-repo');
769
+ * const symbols = findSymbol('./my-repo', 'processRequest');
770
+ * console.log(`Found ${symbols.length} symbols named processRequest`);
771
+ * ```
772
+ */
773
+ export declare function findSymbol(path: string, name: string): Array<SymbolInfo>
774
+
775
+ /**
776
+ * Get all callers of a symbol
777
+ *
778
+ * Returns symbols that call any symbol with the given name.
779
+ * Requires an index to be built first (use buildIndex).
780
+ *
781
+ * # Arguments
782
+ * * `path` - Path to repository root
783
+ * * `symbolName` - Name of the symbol to find callers for
784
+ *
785
+ * # Returns
786
+ * Array of symbols that call the target symbol
787
+ *
788
+ * # Example
789
+ * ```javascript
790
+ * const { getCallers, buildIndex } = require('infiniloom-node');
791
+ *
792
+ * buildIndex('./my-repo');
793
+ * const callers = getCallers('./my-repo', 'authenticate');
794
+ * console.log(`authenticate is called by ${callers.length} functions`);
795
+ * for (const c of callers) {
796
+ * console.log(` ${c.name} at ${c.file}:${c.line}`);
797
+ * }
798
+ * ```
799
+ */
800
+ export declare function getCallers(path: string, symbolName: string): Array<SymbolInfo>
801
+
802
+ /**
803
+ * Get all callees of a symbol
804
+ *
805
+ * Returns symbols that are called by any symbol with the given name.
806
+ * Requires an index to be built first (use buildIndex).
807
+ *
808
+ * # Arguments
809
+ * * `path` - Path to repository root
810
+ * * `symbolName` - Name of the symbol to find callees for
811
+ *
812
+ * # Returns
813
+ * Array of symbols that the target symbol calls
814
+ *
815
+ * # Example
816
+ * ```javascript
817
+ * const { getCallees, buildIndex } = require('infiniloom-node');
818
+ *
819
+ * buildIndex('./my-repo');
820
+ * const callees = getCallees('./my-repo', 'main');
821
+ * console.log(`main calls ${callees.length} functions`);
822
+ * for (const c of callees) {
823
+ * console.log(` ${c.name} at ${c.file}:${c.line}`);
824
+ * }
825
+ * ```
826
+ */
827
+ export declare function getCallees(path: string, symbolName: string): Array<SymbolInfo>
828
+
829
+ /**
830
+ * Get all references to a symbol
831
+ *
832
+ * Returns all locations where a symbol is referenced (calls, imports, inheritance).
833
+ * Requires an index to be built first (use buildIndex).
834
+ *
835
+ * # Arguments
836
+ * * `path` - Path to repository root
837
+ * * `symbolName` - Name of the symbol to find references for
838
+ *
839
+ * # Returns
840
+ * Array of reference information including the referencing symbol and kind
841
+ *
842
+ * # Example
843
+ * ```javascript
844
+ * const { getReferences, buildIndex } = require('infiniloom-node');
845
+ *
846
+ * buildIndex('./my-repo');
847
+ * const refs = getReferences('./my-repo', 'UserService');
848
+ * console.log(`UserService is referenced ${refs.length} times`);
849
+ * for (const r of refs) {
850
+ * console.log(` ${r.kind}: ${r.symbol.name} at ${r.symbol.file}:${r.symbol.line}`);
851
+ * }
852
+ * ```
853
+ */
854
+ export declare function getReferences(path: string, symbolName: string): Array<ReferenceInfo>
855
+
856
+ /**
857
+ * Get the complete call graph
858
+ *
859
+ * Returns all symbols and their call relationships.
860
+ * Requires an index to be built first (use buildIndex).
861
+ *
862
+ * # Arguments
863
+ * * `path` - Path to repository root
864
+ * * `options` - Optional filtering options
865
+ *
866
+ * # Returns
867
+ * Call graph with nodes (symbols), edges (calls), and statistics
868
+ *
869
+ * # Example
870
+ * ```javascript
871
+ * const { getCallGraph, buildIndex } = require('infiniloom-node');
872
+ *
873
+ * buildIndex('./my-repo');
874
+ * const graph = getCallGraph('./my-repo');
875
+ * console.log(`Call graph: ${graph.stats.totalSymbols} symbols, ${graph.stats.totalCalls} calls`);
876
+ *
877
+ * // Find most called functions
878
+ * const callCounts = new Map();
879
+ * for (const edge of graph.edges) {
880
+ * callCounts.set(edge.callee, (callCounts.get(edge.callee) || 0) + 1);
881
+ * }
882
+ * const sorted = [...callCounts.entries()].sort((a, b) => b[1] - a[1]);
883
+ * console.log('Most called functions:', sorted.slice(0, 10));
884
+ * ```
885
+ */
886
+ export declare function getCallGraph(path: string, options?: CallGraphOptions | undefined | null): CallGraph
887
+
888
+ /** Async version of findSymbol */
889
+ export declare function findSymbolAsync(path: string, name: string): Promise<Array<SymbolInfo>>
890
+
891
+ /** Async version of getCallers */
892
+ export declare function getCallersAsync(path: string, symbolName: string): Promise<Array<SymbolInfo>>
893
+
894
+ /** Async version of getCallees */
895
+ export declare function getCalleesAsync(path: string, symbolName: string): Promise<Array<SymbolInfo>>
896
+
897
+ /** Async version of getReferences */
898
+ export declare function getReferencesAsync(path: string, symbolName: string): Promise<Array<ReferenceInfo>>
899
+
900
+ /** Async version of getCallGraph */
901
+ export declare function getCallGraphAsync(path: string, options?: CallGraphOptions | undefined | null): Promise<CallGraph>
902
+
903
+ // ============================================================================
904
+ // Chunk API - Split repositories into manageable pieces
905
+ // ============================================================================
906
+
907
+ /** Options for chunking a repository */
908
+ export interface ChunkOptions {
909
+ /** Chunking strategy: "fixed", "file", "module", "symbol", "semantic", "dependency" */
910
+ strategy?: string
911
+ /** Maximum tokens per chunk (default: 8000) */
912
+ maxTokens?: number
913
+ /** Token overlap between chunks (default: 0) */
914
+ overlap?: number
915
+ /** Target model for token counting (default: "claude") */
916
+ model?: string
917
+ /** Output format: "xml", "markdown", "json" (default: "xml") */
918
+ format?: string
919
+ /** Sort chunks by priority (core modules first) */
920
+ priorityFirst?: boolean
921
+ }
922
+
923
+ /** A chunk of repository content */
924
+ export interface RepoChunk {
925
+ /** Chunk index (0-based) */
926
+ index: number
927
+ /** Total number of chunks */
928
+ total: number
929
+ /** Primary focus/topic of this chunk */
930
+ focus: string
931
+ /** Estimated token count */
932
+ tokens: number
933
+ /** Files included in this chunk */
934
+ files: Array<string>
935
+ /** Formatted content of the chunk */
936
+ content: string
937
+ }
938
+
939
+ /**
940
+ * Split a repository into chunks for incremental processing
941
+ *
942
+ * Useful for processing large repositories that exceed LLM context limits.
943
+ *
944
+ * # Arguments
945
+ * * `path` - Path to repository root
946
+ * * `options` - Optional chunking options
947
+ *
948
+ * # Returns
949
+ * Array of repository chunks
950
+ *
951
+ * # Example
952
+ * ```javascript
953
+ * const { chunk } = require('infiniloom-node');
954
+ *
955
+ * const chunks = chunk('./large-repo', {
956
+ * strategy: 'module',
957
+ * maxTokens: 50000,
958
+ * model: 'claude'
959
+ * });
960
+ *
961
+ * for (const c of chunks) {
962
+ * console.log(`Chunk ${c.index}/${c.total}: ${c.focus} (${c.tokens} tokens)`);
963
+ * // Process c.content with LLM
964
+ * }
965
+ * ```
966
+ */
967
+ export declare function chunk(path: string, options?: ChunkOptions | undefined | null): Array<RepoChunk>
968
+
969
+ // ============================================================================
970
+ // Impact API - Analyze change impact
971
+ // ============================================================================
972
+
973
+ /** Options for impact analysis */
974
+ export interface ImpactOptions {
975
+ /** Depth of dependency traversal (1-3, default: 2) */
976
+ depth?: number
977
+ /** Include test files in analysis */
978
+ includeTests?: boolean
979
+ }
980
+
981
+ /** Symbol affected by a change */
982
+ export interface AffectedSymbol {
983
+ /** Symbol name */
984
+ name: string
985
+ /** Symbol kind (function, class, etc.) */
986
+ kind: string
987
+ /** File containing the symbol */
988
+ file: string
989
+ /** Line number */
990
+ line: number
991
+ /** How the symbol is affected: "direct", "caller", "callee", "dependent" */
992
+ impactType: string
993
+ }
994
+
995
+ /** Impact analysis result */
996
+ export interface ImpactResult {
997
+ /** Files directly changed */
998
+ changedFiles: Array<string>
999
+ /** Files that depend on changed files */
1000
+ dependentFiles: Array<string>
1001
+ /** Related test files */
1002
+ testFiles: Array<string>
1003
+ /** Symbols affected by the changes */
1004
+ affectedSymbols: Array<AffectedSymbol>
1005
+ /** Overall impact level: "low", "medium", "high", "critical" */
1006
+ impactLevel: string
1007
+ /** Summary of the impact */
1008
+ summary: string
1009
+ }
1010
+
1011
+ /**
1012
+ * Analyze the impact of changes to files or symbols
1013
+ *
1014
+ * Requires an index to be built first (use buildIndex).
1015
+ *
1016
+ * # Arguments
1017
+ * * `path` - Path to repository root
1018
+ * * `files` - Files to analyze (can be paths or globs)
1019
+ * * `options` - Optional analysis options
1020
+ *
1021
+ * # Returns
1022
+ * Impact analysis result
1023
+ *
1024
+ * # Example
1025
+ * ```javascript
1026
+ * const { buildIndex, analyzeImpact } = require('infiniloom-node');
1027
+ *
1028
+ * // Build index first
1029
+ * buildIndex('./my-repo');
1030
+ *
1031
+ * // Analyze impact of changes
1032
+ * const impact = analyzeImpact('./my-repo', ['src/auth.ts']);
1033
+ * console.log(`Impact level: ${impact.impactLevel}`);
1034
+ * console.log(`Affected files: ${impact.dependentFiles.length}`);
1035
+ * ```
1036
+ */
1037
+ export declare function analyzeImpact(path: string, files: Array<string>, options?: ImpactOptions | undefined | null): ImpactResult
1038
+
1039
+ // ============================================================================
1040
+ // Diff Context API - Get context-aware diffs
1041
+ // ============================================================================
1042
+
1043
+ /** Options for diff context */
1044
+ export interface DiffContextOptions {
1045
+ /** Depth of context expansion (1-3, default: 2) */
1046
+ depth?: number
1047
+ /** Token budget for context (default: 50000) */
1048
+ budget?: number
1049
+ /** Include the actual diff content (default: false) */
1050
+ includeDiff?: boolean
1051
+ /** Output format: "xml", "markdown", "json" (default: "xml") */
1052
+ format?: string
1053
+ }
1054
+
1055
+ /** A changed file with surrounding context */
1056
+ export interface DiffFileContext {
1057
+ /** File path */
1058
+ path: string
1059
+ /** Change type: "Added", "Modified", "Deleted", "Renamed" */
1060
+ changeType: string
1061
+ /** Lines added */
1062
+ additions: number
1063
+ /** Lines deleted */
1064
+ deletions: number
1065
+ /** Unified diff content (if includeDiff is true) */
1066
+ diff?: string
1067
+ /** Relevant code context around changes */
1068
+ contextSnippets: Array<string>
1069
+ }
1070
+
1071
+ /** Symbol context information */
1072
+ export interface ContextSymbolInfo {
1073
+ /** Symbol name */
1074
+ name: string
1075
+ /** Symbol kind */
1076
+ kind: string
1077
+ /** File containing symbol */
1078
+ file: string
1079
+ /** Line number */
1080
+ line: number
1081
+ /** Why this symbol is included: "changed", "caller", "callee", "dependent" */
1082
+ reason: string
1083
+ /** Symbol signature/definition */
1084
+ signature?: string
476
1085
  }
1086
+
1087
+ /** Context-aware diff result */
1088
+ export interface DiffContextResult {
1089
+ /** Changed files with context */
1090
+ changedFiles: Array<DiffFileContext>
1091
+ /** Related symbols and their context */
1092
+ contextSymbols: Array<ContextSymbolInfo>
1093
+ /** Related test files */
1094
+ relatedTests: Array<string>
1095
+ /** Formatted output (if format specified) */
1096
+ formattedOutput?: string
1097
+ /** Total token count */
1098
+ totalTokens: number
1099
+ }
1100
+
1101
+ /**
1102
+ * Get context-aware diff with surrounding symbols and dependencies
1103
+ *
1104
+ * Unlike basic diffFiles, this provides semantic context around changes.
1105
+ * Requires an index (will build on-the-fly if not present).
1106
+ *
1107
+ * # Arguments
1108
+ * * `path` - Path to repository root
1109
+ * * `fromRef` - Starting commit/branch (use "" for unstaged changes)
1110
+ * * `toRef` - Ending commit/branch (use "HEAD" for staged, "" for working tree)
1111
+ * * `options` - Optional context options
1112
+ *
1113
+ * # Returns
1114
+ * Context-aware diff result with related symbols
1115
+ *
1116
+ * # Example
1117
+ * ```javascript
1118
+ * const { getDiffContext } = require('infiniloom-node');
1119
+ *
1120
+ * // Get context for last commit
1121
+ * const context = getDiffContext('./my-repo', 'HEAD~1', 'HEAD', {
1122
+ * depth: 2,
1123
+ * budget: 50000,
1124
+ * includeDiff: true
1125
+ * });
1126
+ *
1127
+ * console.log(`Changed: ${context.changedFiles.length} files`);
1128
+ * console.log(`Related symbols: ${context.contextSymbols.length}`);
1129
+ * console.log(`Related tests: ${context.relatedTests.length}`);
1130
+ * ```
1131
+ */
1132
+ export declare function getDiffContext(path: string, fromRef: string, toRef: string, options?: DiffContextOptions | undefined | null): DiffContextResult
1133
+
1134
+ // ============================================================================
1135
+ // Async API - Async versions of key functions
1136
+ // ============================================================================
1137
+
1138
+ /**
1139
+ * Async version of pack
1140
+ *
1141
+ * # Example
1142
+ * ```javascript
1143
+ * const { packAsync } = require('infiniloom-node');
1144
+ *
1145
+ * const context = await packAsync('./my-repo', { format: 'xml' });
1146
+ * ```
1147
+ */
1148
+ export declare function packAsync(path: string, options?: PackOptions | undefined | null): Promise<string>
1149
+
1150
+ /**
1151
+ * Async version of scan
1152
+ *
1153
+ * # Example
1154
+ * ```javascript
1155
+ * const { scanAsync } = require('infiniloom-node');
1156
+ *
1157
+ * const stats = await scanAsync('./my-repo', 'claude');
1158
+ * ```
1159
+ */
1160
+ export declare function scanAsync(path: string, model?: string | undefined | null): Promise<ScanStats>
1161
+
1162
+ /**
1163
+ * Async version of buildIndex
1164
+ *
1165
+ * # Example
1166
+ * ```javascript
1167
+ * const { buildIndexAsync } = require('infiniloom-node');
1168
+ *
1169
+ * const status = await buildIndexAsync('./my-repo', { force: true });
1170
+ * ```
1171
+ */
1172
+ export declare function buildIndexAsync(path: string, options?: IndexOptions | undefined | null): Promise<IndexStatus>
1173
+
1174
+ /**
1175
+ * Async version of chunk
1176
+ *
1177
+ * # Example
1178
+ * ```javascript
1179
+ * const { chunkAsync } = require('infiniloom-node');
1180
+ *
1181
+ * const chunks = await chunkAsync('./large-repo', { maxTokens: 50000 });
1182
+ * ```
1183
+ */
1184
+ export declare function chunkAsync(path: string, options?: ChunkOptions | undefined | null): Promise<Array<RepoChunk>>
1185
+
1186
+ /**
1187
+ * Async version of analyzeImpact
1188
+ *
1189
+ * # Example
1190
+ * ```javascript
1191
+ * const { analyzeImpactAsync } = require('infiniloom-node');
1192
+ *
1193
+ * const impact = await analyzeImpactAsync('./my-repo', ['src/auth.ts']);
1194
+ * ```
1195
+ */
1196
+ export declare function analyzeImpactAsync(path: string, files: Array<string>, options?: ImpactOptions | undefined | null): Promise<ImpactResult>
1197
+
1198
+ /**
1199
+ * Async version of getDiffContext
1200
+ *
1201
+ * # Example
1202
+ * ```javascript
1203
+ * const { getDiffContextAsync } = require('infiniloom-node');
1204
+ *
1205
+ * const context = await getDiffContextAsync('./my-repo', 'HEAD~1', 'HEAD');
1206
+ * ```
1207
+ */
1208
+ export declare function getDiffContextAsync(path: string, fromRef: string, toRef: string, options?: DiffContextOptions | undefined | null): Promise<DiffContextResult>
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "infiniloom-node",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Node.js bindings for infiniloom - Repository context engine for LLMs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",