-
Notifications
You must be signed in to change notification settings - Fork 0
Smart Indexer #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -324,6 +324,20 @@ func (t *dirTracker) results() (indexed, skipped, errors int) { | |||||||||||||||||||||||||||||||||||
| return int(t.indexed.Load()), int(t.skipped.Load()), int(t.errors.Load()) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // topLevelSummaries returns summaries of top-level directories (direct children of root). | ||||||||||||||||||||||||||||||||||||
| func (t *dirTracker) topLevelSummaries() map[string]string { | ||||||||||||||||||||||||||||||||||||
| t.mu.Lock() | ||||||||||||||||||||||||||||||||||||
| defer t.mu.Unlock() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| result := make(map[string]string) | ||||||||||||||||||||||||||||||||||||
| for dir, summary := range t.dirSummary { | ||||||||||||||||||||||||||||||||||||
| if filepath.Dir(dir) == "." { | ||||||||||||||||||||||||||||||||||||
| result[dir] = summary | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| return result | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Run executes the full indexing cycle for the project. | ||||||||||||||||||||||||||||||||||||
| func Run(configPath string, force bool, logger *slog.Logger) error { | ||||||||||||||||||||||||||||||||||||
| cfg, err := config.Load(configPath) | ||||||||||||||||||||||||||||||||||||
|
|
@@ -402,6 +416,7 @@ func Run(configPath string, force bool, logger *slog.Logger) error { | |||||||||||||||||||||||||||||||||||
| RootPath: rootPath, | ||||||||||||||||||||||||||||||||||||
| MaxFileSize: cfg.Indexer.MaxFileSize, | ||||||||||||||||||||||||||||||||||||
| IgnorePatterns: cfg.Indexer.IgnorePatterns, | ||||||||||||||||||||||||||||||||||||
| TreeFileDepth: cfg.Indexer.TreeFileDepth, | ||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("walking project: %w", err) | ||||||||||||||||||||||||||||||||||||
|
|
@@ -522,6 +537,10 @@ func Run(configPath string, force bool, logger *slog.Logger) error { | |||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| logger.Info(fmt.Sprintf("Found %d items to analyze (%d files, %d dirs)", totalItems, len(walkResult.Files), totalDirs)) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Collect root-level file summaries for Phase 3 (enriched overview) | ||||||||||||||||||||||||||||||||||||
| var rootFilesMu sync.Mutex | ||||||||||||||||||||||||||||||||||||
| var rootFileSummaries []*fileInfo | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| for _, relPath := range walkResult.Files { | ||||||||||||||||||||||||||||||||||||
| absPath := filepath.Join(rootPath, relPath) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
@@ -542,6 +561,14 @@ func Run(configPath string, force bool, logger *slog.Logger) error { | |||||||||||||||||||||||||||||||||||
| logger.Debug("file skipped (unchanged)", "file", relPath, "hash", hash) | ||||||||||||||||||||||||||||||||||||
| skippedCount++ | ||||||||||||||||||||||||||||||||||||
| tracker.fileCompleted(relPath, existing.Summary, existing.FileHash) | ||||||||||||||||||||||||||||||||||||
| if filepath.Dir(relPath) == "." { | ||||||||||||||||||||||||||||||||||||
| rootFilesMu.Lock() | ||||||||||||||||||||||||||||||||||||
| rootFileSummaries = append(rootFileSummaries, &fileInfo{ | ||||||||||||||||||||||||||||||||||||
| filePath: relPath, | ||||||||||||||||||||||||||||||||||||
| summary: existing.Summary, | ||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||
| rootFilesMu.Unlock() | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
|
@@ -628,13 +655,50 @@ func Run(configPath string, force bool, logger *slog.Logger) error { | |||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| tracker.fileCompleted(relPath, analysis.Summary, hash) | ||||||||||||||||||||||||||||||||||||
| if filepath.Dir(relPath) == "." { | ||||||||||||||||||||||||||||||||||||
| rootFilesMu.Lock() | ||||||||||||||||||||||||||||||||||||
| rootFileSummaries = append(rootFileSummaries, &fileInfo{ | ||||||||||||||||||||||||||||||||||||
| filePath: relPath, | ||||||||||||||||||||||||||||||||||||
| summary: analysis.Summary, | ||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||
| rootFilesMu.Unlock() | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| indexedCount.Add(1) | ||||||||||||||||||||||||||||||||||||
| }(relPath, content, hash) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| wg.Wait() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| dirIndexed, dirSkipped, dirErrors := tracker.results() | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // --- Stage 3: Enriched project overview --- | ||||||||||||||||||||||||||||||||||||
| logger.Info("\n--- Stage 3: Enriched project overview ---") | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| topLevelDirs := tracker.topLevelSummaries() | ||||||||||||||||||||||||||||||||||||
| if len(topLevelDirs) > 0 || len(rootFileSummaries) > 0 { | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
| if len(topLevelDirs) > 0 || len(rootFileSummaries) > 0 { | |
| if len(topLevelDirs) > 0 || len(rootFileSummaries) > 0 { | |
| if len(rootFileSummaries) > 0 { | |
| sort.Slice(rootFileSummaries, func(i, j int) bool { | |
| return rootFileSummaries[i].FilePath < rootFileSummaries[j].FilePath | |
| }) | |
| } |
Copilot
AI
Mar 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stage 3 writes the enriched overview back to overviewPath (project_overview.md), overwriting the Stage 1 structure-only overview saved earlier in the run. If both are useful, consider saving the enriched output to a separate file name (or appending a clearly separated section) to avoid losing the original output.
| if err := os.WriteFile(overviewPath, []byte(enrichedOverview), 0o644); err != nil { | |
| logger.Error(fmt.Sprintf("Error saving enriched overview: %v", err)) | |
| } else { | |
| logger.Info(fmt.Sprintf("Enriched project overview saved to %s", overviewPath)) | |
| // Save enriched overview to a separate file to avoid overwriting the structure-only overview. | |
| enrichedOverviewPath := overviewPath | |
| if ext := filepath.Ext(overviewPath); ext != "" { | |
| base := strings.TrimSuffix(overviewPath, ext) | |
| enrichedOverviewPath = base + "_enriched" + ext | |
| } else { | |
| enrichedOverviewPath = overviewPath + "_enriched" | |
| } | |
| if err := os.WriteFile(enrichedOverviewPath, []byte(enrichedOverview), 0o644); err != nil { | |
| logger.Error(fmt.Sprintf("Error saving enriched overview: %v", err)) | |
| } else { | |
| logger.Info(fmt.Sprintf("Enriched project overview saved to %s", enrichedOverviewPath)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TreeFileDepth=0 is documented in walker.Options as a meaningful value ("root only"), but config loading treats 0 as "unset" (merge only copies when != 0, and defaults force <=0 to DefaultTreeFileDepth). This makes it impossible to configure root-only file display via YAML. Consider using a pointer (e.g., *int) to distinguish unset vs 0, or adopting a sentinel like -1 for "unset" and validating negative values.