gitnexus 1.6.10-rc.12 → 1.6.10-rc.13

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.
@@ -424,10 +424,27 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
424
424
  // clear it, the on-disk index may be in a half-state. Cheapest path
425
425
  // back to a known-good index is to wipe + rebuild from scratch.
426
426
  if (existingMeta?.incrementalInProgress) {
427
+ const dirty = existingMeta.incrementalInProgress;
428
+ const dirtyDetails = typeof dirty === 'object'
429
+ ? [
430
+ dirty.phase ? `phase=${dirty.phase}` : undefined,
431
+ `toWrite=${dirty.toWriteCount}`,
432
+ dirty.importerExpansion !== undefined
433
+ ? `importerExpansion=${dirty.importerExpansion}`
434
+ : undefined,
435
+ dirty.effectiveWriteCount !== undefined
436
+ ? `effectiveWrite=${dirty.effectiveWriteCount}`
437
+ : undefined,
438
+ dirty.deleteCount !== undefined ? `deleteCount=${dirty.deleteCount}` : undefined,
439
+ ]
440
+ .filter(Boolean)
441
+ .join(', ')
442
+ : 'legacy dirty flag';
427
443
  log(
428
444
  // "analyze run", not "incremental run" — since #2099 F1 the flag is a
429
445
  // generic dirty marker written by BOTH writeback branches.
430
446
  'Previous analyze run did not complete cleanly (incrementalInProgress flag set); ' +
447
+ `last dirty state: ${dirtyDetails}; ` +
431
448
  'forcing full rebuild to restore a known-good index.');
432
449
  options = { ...options, force: true };
433
450
  // Reload meta after clearing the flag in-memory; we still want fileHashes
@@ -728,11 +745,15 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
728
745
  `(skipping wipe + ${allFilePaths.length - hashDiff.toWrite.length} unchanged file rows preserved)`);
729
746
  // Set the dirty flag BEFORE any destructive DB mutation. Cleared on
730
747
  // success at the meta-save step. Scoped to this branch's meta.json.
748
+ const now = Date.now();
731
749
  await saveMeta(metaDir, {
732
750
  ...existingMeta,
733
751
  incrementalInProgress: {
734
- startedAt: Date.now(),
752
+ startedAt: now,
753
+ updatedAt: now,
754
+ phase: 'pre-write',
735
755
  toWriteCount: hashDiff.toWrite.length,
756
+ directWriteCount: hashDiff.toWrite.length,
736
757
  },
737
758
  });
738
759
  }
@@ -746,9 +767,15 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
746
767
  // pdg flip, certify zombie/missing BasicBlock rows indefinitely).
747
768
  // toWriteCount: 0 is the full-path sentinel (no incremental write set).
748
769
  if (existingMeta) {
770
+ const now = Date.now();
749
771
  await saveMeta(metaDir, {
750
772
  ...existingMeta,
751
- incrementalInProgress: { startedAt: Date.now(), toWriteCount: 0 },
773
+ incrementalInProgress: {
774
+ startedAt: now,
775
+ updatedAt: now,
776
+ phase: 'full-rebuild',
777
+ toWriteCount: 0,
778
+ },
752
779
  });
753
780
  }
754
781
  await closeLbug();
@@ -808,6 +835,20 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
808
835
  const MAX_IMPORTER_BFS_DEPTH = 4;
809
836
  const writableFiles = new Set(hashDiff.toWrite);
810
837
  const directlyChangedCount = writableFiles.size;
838
+ const dirtyStartedAt = existingMeta.incrementalInProgress?.startedAt ?? Date.now();
839
+ const saveIncrementalDirtyState = async (phase, extra = {}) => {
840
+ await saveMeta(metaDir, {
841
+ ...existingMeta,
842
+ incrementalInProgress: {
843
+ startedAt: dirtyStartedAt,
844
+ updatedAt: Date.now(),
845
+ phase,
846
+ toWriteCount: writableFiles.size,
847
+ directWriteCount: directlyChangedCount,
848
+ ...extra,
849
+ },
850
+ });
851
+ };
811
852
  // Shadow-seed: for ADDED files, queryImporters returns 0 (the new
812
853
  // file has no IMPORTS rows in the pre-pipeline DB yet). But pre-
813
854
  // existing unchanged files may have IMPORTS edges whose module-
@@ -850,6 +891,10 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
850
891
  }
851
892
  }
852
893
  const importerExpansion = writableFiles.size - directlyChangedCount;
894
+ await saveIncrementalDirtyState('importer-bfs', {
895
+ importerExpansion,
896
+ shadowSeedCount: shadowSeed.length,
897
+ });
853
898
  if (importerExpansion > 0) {
854
899
  log(`Incremental: +${importerExpansion} importer(s) added to writable set ` +
855
900
  `(BFS depth ≤ ${MAX_IMPORTER_BFS_DEPTH}` +
@@ -876,6 +921,12 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
876
921
  // would otherwise call deleteNodesForFile twice for the same file
877
922
  // (Bugbot LOW finding on PR #1479).
878
923
  const filesToDelete = [...new Set([...effectiveWriteSet, ...hashDiff.deleted])];
924
+ await saveIncrementalDirtyState('effective-write-set', {
925
+ importerExpansion,
926
+ shadowSeedCount: shadowSeed.length,
927
+ effectiveWriteCount: effectiveWriteSet.size,
928
+ deleteCount: filesToDelete.length,
929
+ });
879
930
  for (let i = 0; i < filesToDelete.length; i++) {
880
931
  const f = filesToDelete[i];
881
932
  try {
@@ -925,6 +976,12 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
925
976
  // the SAME effectiveWriteSet so the subgraph and the deletes
926
977
  // cover identical files (asymmetry would silently corrupt).
927
978
  const subgraph = extractChangedSubgraph(pipelineResult.graph, effectiveWriteSet);
979
+ await saveIncrementalDirtyState('load-graph', {
980
+ importerExpansion,
981
+ shadowSeedCount: shadowSeed.length,
982
+ effectiveWriteCount: effectiveWriteSet.size,
983
+ deleteCount: filesToDelete.length,
984
+ });
928
985
  await loadGraphToLbug(subgraph, pipelineResult.repoPath, storagePath, (msg) => {
929
986
  lbugMsgCount++;
930
987
  const pct = Math.min(84, 65 + Math.round((lbugMsgCount / (lbugMsgCount + 10)) * 19));
@@ -110,9 +110,23 @@ export interface RepoMeta {
110
110
  incrementalInProgress?: {
111
111
  /** When the run started (epoch ms). */
112
112
  startedAt: number;
113
+ /** Last dirty-flag refresh (epoch ms). */
114
+ updatedAt?: number;
113
115
  /** Number of files in the writable set, for diagnostic logs.
114
116
  * `0` on the full-rebuild path (no incremental write set exists). */
115
117
  toWriteCount: number;
118
+ /** Last completed writeback phase before the process stopped. */
119
+ phase?: string;
120
+ /** Directly changed/added files before importer expansion. */
121
+ directWriteCount?: number;
122
+ /** Extra files pulled into the writable set by importer BFS. */
123
+ importerExpansion?: number;
124
+ /** Files in the effective write set after graph-boundary expansion. */
125
+ effectiveWriteCount?: number;
126
+ /** Files whose persisted rows were scheduled for deletion. */
127
+ deleteCount?: number;
128
+ /** Added-file shadow seeds included in importer BFS. */
129
+ shadowSeedCount?: number;
116
130
  };
117
131
  /**
118
132
  * Name of the git branch this index represents (#2106). Absent for the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.10-rc.12",
3
+ "version": "1.6.10-rc.13",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",