devlensio 1.0.2 → 1.0.3

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.
@@ -46,6 +46,7 @@ export interface PipelineResult {
46
46
  isGithubRepo: boolean;
47
47
  gitInfo: GitInfo;
48
48
  }
49
+ export declare function worktreeCommitHash(nodes: CodeNode[]): string;
49
50
  export declare function routesToCodeNodes(routes: (RouteNode | BackendRouteNode)[], repoPath: string): CodeNode[];
50
51
  export declare function analyzePipeline(repoPath: string, isGithubRepo: boolean, options?: PipelineOptions): Promise<PipelineResult>;
51
52
  export declare function refilterPipeline(stored: PipelineResult, thresholds: FilterThresholds): Pick<PipelineResult, "nodes" | "edges" | "stats">;
@@ -15,6 +15,12 @@ function generateGraphId(repoPath, isGithubRepo) {
15
15
  .digest("hex")
16
16
  .slice(0, 16);
17
17
  }
18
+ // Stable id for repos without git: derived from node ids + code hashes, so the
19
+ // same content overwrites one snapshot in place instead of accumulating timestamps
20
+ export function worktreeCommitHash(nodes) {
21
+ const parts = nodes.map((n) => `${n.id}:${n.codeHash ?? ""}`).sort();
22
+ return "worktree-" + createHash("sha256").update(parts.join("|")).digest("hex").slice(0, 12);
23
+ }
18
24
  // Gets current git state of the repo
19
25
  // Falls back gracefully if git is not initialized
20
26
  function getGitInfo(repoPath) {
@@ -28,9 +34,11 @@ function getGitInfo(repoPath) {
28
34
  return { commitHash, branch, message, hasGit: true };
29
35
  }
30
36
  catch {
31
- // No git, or no commits yet — use timestamp as version key
37
+ // No git, or no commits yet. Placeholder resolved to a content-derived
38
+ // id after extraction (see worktreeCommitHash) so unchanged repos reuse
39
+ // one snapshot instead of growing a new timestamped one per analyze
32
40
  return {
33
- commitHash: Date.now().toString(),
41
+ commitHash: "worktree-pending",
34
42
  branch: "unknown",
35
43
  message: "no git history",
36
44
  hasGit: false,
@@ -221,6 +229,10 @@ export async function analyzePipeline(repoPath, isGithubRepo, options) {
221
229
  }
222
230
  const allNodes = extractorResult.nodes;
223
231
  const allEdges = extractorResult.edges;
232
+ if (!gitInfo.hasGit) {
233
+ gitInfo.commitHash = worktreeCommitHash(allNodes);
234
+ gitInfo.message = "worktree snapshot";
235
+ }
224
236
  // Step 5: Score and filter
225
237
  console.log("\n[5/5] Scoring and filtering...");
226
238
  const scoringResult = scoreAndFilter(allNodes, allEdges, options?.thresholds);
@@ -21,6 +21,7 @@ export interface CommitSummary {
21
21
  edgeCount: number;
22
22
  hasGit: boolean;
23
23
  isSummarized?: boolean;
24
+ isIndexed?: boolean;
24
25
  }
25
26
  export interface GraphMeta {
26
27
  graphId: string;
@@ -101,6 +102,8 @@ export declare function deleteCommit(graphId: string, commitHash: string): boole
101
102
  export declare function diffCommits(graphId: string, fromHash: string, toHash: string): NodeDiff | undefined;
102
103
  export declare function markCommitSummarized(graphId: string, commitHash: string): void;
103
104
  export declare function isCommitSummarized(graphId: string, commitHash: string): boolean;
105
+ export declare function markCommitIndexed(graphId: string, commitHash: string): void;
106
+ export declare function isCommitIndexed(graphId: string, commitHash: string): boolean;
104
107
  export declare function findLastSummarizedAncestor(graphId: string, commitHash: string, repoPath: string): Promise<string | undefined>;
105
108
  export declare function saveNodeSummaries(graphId: string, commitHash: string, nodeUpdates: Map<string, {
106
109
  technicalSummary: string;
@@ -182,9 +182,14 @@ export function saveGraph(result, options) {
182
182
  commits: [],
183
183
  summarizedCommits: [],
184
184
  };
185
- // Replace if same commit already exists, else append
185
+ // Replace if same commit already exists, else append.
186
+ // Carry over flags the rebuilt summary does not know about (same hazard as
187
+ // isSummarized: buildCommitSummary starts from scratch)
186
188
  const existingCommit = meta.commits.findIndex((c) => c.commitHash === commitHash);
187
189
  if (existingCommit >= 0) {
190
+ const prev = meta.commits[existingCommit];
191
+ if (prev.isIndexed)
192
+ newSummary.isIndexed = true;
188
193
  meta.commits[existingCommit] = newSummary;
189
194
  }
190
195
  else {
@@ -500,6 +505,23 @@ export function isCommitSummarized(graphId, commitHash) {
500
505
  return false;
501
506
  return meta.summarizedCommits?.includes(commitHash);
502
507
  }
508
+ // Marks a commit as having a derived .search.json index
509
+ export function markCommitIndexed(graphId, commitHash) {
510
+ const meta = readMeta(graphId);
511
+ if (!meta)
512
+ return;
513
+ const commit = meta.commits.find((c) => c.commitHash === commitHash);
514
+ if (!commit || commit.isIndexed)
515
+ return;
516
+ commit.isIndexed = true;
517
+ writeMeta(meta);
518
+ }
519
+ export function isCommitIndexed(graphId, commitHash) {
520
+ const meta = readMeta(graphId);
521
+ if (!meta)
522
+ return false;
523
+ return meta.commits.find((c) => c.commitHash === commitHash)?.isIndexed === true;
524
+ }
503
525
  // Finds the most recent ancestor commit that has been summarized.
504
526
  // Uses simple-git to walk the commit history of the repo.
505
527
  // Returns undefined if no summarized ancestor exists (= full summarization needed).
@@ -601,6 +623,8 @@ export const fileStorage = {
601
623
  diffCommits,
602
624
  markCommitSummarized,
603
625
  isCommitSummarized,
626
+ markCommitIndexed,
627
+ isCommitIndexed,
604
628
  findLastSummarizedAncestor,
605
629
  saveNodeSummaries,
606
630
  getCheckpointPath,
@@ -11,6 +11,8 @@ export interface GraphStorage {
11
11
  diffCommits(graphId: string, fromHash: string, toHash: string): NodeDiff | undefined;
12
12
  markCommitSummarized(graphId: string, commitHash: string): void;
13
13
  isCommitSummarized(graphId: string, commitHash: string): boolean;
14
+ markCommitIndexed(graphId: string, commitHash: string): void;
15
+ isCommitIndexed(graphId: string, commitHash: string): boolean;
14
16
  findLastSummarizedAncestor(graphId: string, commitHash: string, repoPath: string): Promise<string | undefined>;
15
17
  saveNodeSummaries(graphId: string, commitHash: string, nodeUpdates: Map<string, {
16
18
  technicalSummary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devlensio",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Codebase intelligence engine for TypeScript/JavaScript/React/Next.js, Python, Java, Go, and Rust repositories.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",