@lumy-pack/line-lore 0.0.5 → 0.0.7

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
@@ -40,6 +40,9 @@ npx @lumy-pack/line-lore graph pr 42 --depth 2
40
40
  # Check system health
41
41
  npx @lumy-pack/line-lore health
42
42
 
43
+ # Return cached results only (no API calls)
44
+ npx @lumy-pack/line-lore trace src/auth.ts -L 42 --cache-only
45
+
43
46
  # Clear caches
44
47
  npx @lumy-pack/line-lore cache clear
45
48
 
@@ -95,6 +98,48 @@ console.log(`Git version: ${report.gitVersion}`);
95
98
 
96
99
  No ML or heuristics — results are always reproducible.
97
100
 
101
+ ### PR Lookup Algorithm
102
+
103
+ Once a commit is identified, line-lore resolves it to a PR using a **cost-ascending sequential fallback chain**. Each strategy is tried in order; the first success returns immediately.
104
+
105
+ ```
106
+ lookupPR(commitSha)
107
+
108
+
109
+ Strategy 1 — Cache ─────────────────── cost: O(1), instant
110
+ │ ShardedCache<PRInfo> lookup by SHA
111
+ │ hit? → return cached PRInfo
112
+ │ miss + --cache-only? → return null (skip all fallbacks)
113
+
114
+ Strategy 2 — Ancestry-path + Message ─ cost: 1 git-log
115
+ │ 1st: git log --merges --ancestry-path --first-parent sha..HEAD
116
+ │ 2nd: (fallback) full ancestry-path without --first-parent
117
+ │ Parse merge subject with 3 regex patterns:
118
+ │ • /Merge pull request #(\d+)/ — GitHub merge commit
119
+ │ • /\(#(\d+)\)\s*$/ — Squash merge convention
120
+ │ • /!(\d+)\s*$/ — GitLab merge commit
121
+ │ If PR# found + adapter available → enrich via API
122
+ │ found? → return PRInfo
123
+
124
+ Strategy 3 — Platform API ──────────── cost: 1 HTTP request
125
+ │ gh api repos/{owner}/{repo}/commits/{sha}/pulls
126
+ │ Filter: merged PRs only (mergedAt != null)
127
+ │ found? → return PRInfo
128
+
129
+ Strategy 4 — Patch-ID matching ─────── cost: streaming 500+ commits
130
+ │ Compute target: git diff sha^..sha | git patch-id --stable
131
+ │ Batch scan: git log -500 -p HEAD | git patch-id --stable
132
+ │ (--deep mode: 2000 commits)
133
+ │ Find candidate with same patch-id but different SHA
134
+ │ match? → lookupPR(matchedSha) recursively
135
+
136
+ All failed → null
137
+ ```
138
+
139
+ **Why this order?** The chain is sorted by cost. Most repositories use merge or squash workflows, so Strategy 2 resolves >90% of lookups with zero API calls. Strategy 3 (single HTTP) is cheaper than Strategy 4 (streaming hundreds of commit diffs), so API is tried before patch-id scanning.
140
+
141
+ **Patch-ID explained**: `git patch-id --stable` generates a content-based hash from a commit's diff, ignoring all metadata (author, date, message). When a commit is rebased, its SHA changes but the patch-id stays the same — enabling deterministic matching of rebased commits.
142
+
98
143
  ## Understanding the Output
99
144
 
100
145
  ### TraceNode — the core unit of output
@@ -302,6 +347,7 @@ Trace a code line to its originating PR.
302
347
  | `deep` | `boolean` | no | `false` | Expand patch-id scan range (500→2000), continue search after merge commit match |
303
348
  | `noAst` | `boolean` | no | `false` | Disable AST analysis |
304
349
  | `noCache` | `boolean` | no | `false` | Disable cache reads and writes |
350
+ | `cacheOnly` | `boolean` | no | `false` | Return cached results only — skip API calls, ancestry traversal, and patch-id scan. If both `cacheOnly` and `noCache` are set, `cacheOnly` takes precedence (cache reads remain enabled) and a warning is emitted. |
305
351
 
306
352
  **Returns (`TraceFullResult`):**
307
353
 
@@ -499,6 +545,30 @@ async function analyzeChangedLines(file: string, lines: number[]) {
499
545
  }
500
546
  ```
501
547
 
548
+ ### Cache-Only Lookups
549
+
550
+ Use `cacheOnly` to instantly return previously cached PR data without any API calls or git operations beyond blame. Ideal for IDE integrations and repeated lookups where speed matters more than freshness.
551
+
552
+ ```typescript
553
+ import { trace } from '@lumy-pack/line-lore';
554
+
555
+ async function getCachedPR(filePath: string, lineNumber: number) {
556
+ const result = await trace({
557
+ file: filePath,
558
+ line: lineNumber,
559
+ cacheOnly: true, // return cached data only, never fetch
560
+ });
561
+
562
+ const pr = result.nodes.find(n => n.type === 'pull_request');
563
+ if (pr) {
564
+ return { number: pr.prNumber, url: pr.prUrl };
565
+ }
566
+
567
+ // Cache miss — no PR data available without fetching
568
+ return null;
569
+ }
570
+ ```
571
+
502
572
  ### Batch Processing with Cache Control
503
573
 
504
574
  ```typescript
@@ -566,6 +636,7 @@ import type {
566
636
  | `--end-line <num>` | Ending line for range |
567
637
  | `--deep` | Deep trace (squash merges) |
568
638
  | `--output <format>` | Output as json, llm, or human |
639
+ | `--cache-only` | Return cached results only (no API calls) |
569
640
  | `--quiet` | Suppress formatting |
570
641
  | `npx @lumy-pack/line-lore health` | Check system health |
571
642
  | `npx @lumy-pack/line-lore graph pr <num>` | Show issues linked to a PR |