From c15e2fdf95cf0b3f85a6574b0f2a6d9bc5beca9d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:37:27 +0530 Subject: [PATCH 1/9] docs(repomap): add doc.go explaining dual-package split with internal/context/repomap A go-doc compatible overview that supersedes the previous 3-line package comment on repomap.go (kept for backward compatibility). It documents: - the package's role as the deep code-analysis engine (call graph, search, quality signals, API scanning, incremental indexing) - the dual-package relationship with internal/context/repomap, which is the prompt-injection shim and shares no code with this package - the stdlib-only core (no CGO, no tree-sitter binary) - extension points: new language parsers, new smell heuristics, new HTTP framework scanners - performance and scaling notes (MaxFiles cap, in-process LRU cache, persistent IncrementalMap at .hawk/repomap-cache.json) --- internal/intelligence/repomap/doc.go | 67 ++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 internal/intelligence/repomap/doc.go diff --git a/internal/intelligence/repomap/doc.go b/internal/intelligence/repomap/doc.go new file mode 100644 index 00000000..8613f3de --- /dev/null +++ b/internal/intelligence/repomap/doc.go @@ -0,0 +1,67 @@ +// Package repomap is the deep code-analysis engine that powers hawk's +// repository-mapping, symbol-extraction, and code-quality features. +// +// The package is built around the entry point Generate (in repomap.go), which +// walks a directory, dispatches each supported source file to a language-aware +// parser, and returns a RepoMap: a token-budgeted summary of files and their +// top-level symbols suitable for injection into LLM prompts. Around that core +// it accumulates a number of specialised analyses that all share the same +// parsed-symbol substrate: +// +// - Static analysis: call graph, import/dep graph, type hierarchy, +// interface extraction, code ownership, co-change statistics, and a +// Shapley-value ranker. +// - Search and navigation: BM25 semantic search, symbol-level PageRank, +// reranking, and a "go to definition / find references / find +// implementations" index that works without an LSP server. +// - Quality signals: cyclomatic complexity, code smells, repository health +// score, doc linter, dead-code detector, and a migration detector for +// deprecated language idioms. +// - API surface: a per-framework HTTP route scanner (Chi, net/http, Gin, +// Echo, Gorilla, Fiber) with OpenAPI export. +// - Incremental indexing: file-hash-keyed caches and an fsnotify-based +// watcher so that regeneration only re-processes files that changed. +// +// The package is intentionally stdlib-only at its core (go/parser, go/ast, +// go/token, encoding/*); the only third-party dependency is github.com/fsnotify +// /fsnotify for file watching, plus hawk's own internal/scoring and +// internal/ui/icons helpers where they are used. Tree-sitter is not required: +// Go is parsed with go/ast and other languages are handled by an enhanced +// regex extractor (see treesitter.go and parser_langs.go). +// +// # Dual-package relationship +// +// hawk ships a second package, internal/context/repomap, that exposes a much +// narrower surface - essentially just RepoMap(root, budget) (string, error). +// That package is the prompt-injection shim: it is what hawk's context layer +// calls when it needs a budgeted overview for the system prompt. It does its +// own AST parsing, PageRank pass, and rendering, and shares no code with this +// package beyond the name. The package you are reading is the deeper +// analysis engine that drives the higher-level navigators, quality tools, and +// search index, not the prompt-injection shim. See internal/context/repomap's +// own package comment for the shim side of the boundary. +// +// # Extension points +// +// - Add a new language parser by adding a new case to parseFileSymbols in +// repomap.go and a parseX function in parser_langs.go (or a new +// TreeSitterParser method in treesitter.go for languages that need +// scope-aware extraction). +// - Add a new code smell or quality heuristic by adding a Detector field +// on SmellDetector in smells.go and wiring it into ScanDirectory. +// - Add a new HTTP framework scanner by adding a ScanX function in +// api_scanner.go and a case in DetectFramework. +// +// # Performance and scaling +// +// Generate is O(N) in the number of files with a hard cap of Options.MaxFiles +// (default 500). The symbol cache (cache.go) is an in-process LRU keyed by +// (path, modtime) that is cleared on process exit; the IncrementalMap +// (incremental_map.go) provides a persistent on-disk cache at +// .hawk/repomap-cache.json keyed by SHA-256. Callers that need to operate on +// repositories with tens of thousands of files should set MaxFiles +// appropriately and prefer the incremental path. Static-analysis passes such +// as BuildCallGraph, BuildDepGraph, and the PageRank iteration in pagerank.go +// are O(V + E) per iteration over the symbol graph and scale linearly with +// the number of declarations, not the number of lines. +package repomap From 9a029a4aa068c3c21a5b805cde9d63f91818be56 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:41:37 +0530 Subject: [PATCH 2/9] docs(repomap): add leading comments to Core, Static analysis, Quality signals, API surface, and Incremental files (16 files) Each comment is a 1-3 line description of what the file does, written so that 'go doc' on any file in the package produces a useful summary. Comments are deliberately concise; the deeper architecture overview lives in doc.go and README.md. Files in this commit: - Core/cache.go in-process LRU symbol cache - Core/gitignore.go composed .gitignore rule walker - Core/watcher.go fsnotify wrapper - Symbols/parser.go original regex-based Go extractor - Symbols/parser_enhanced.go AST-based Go extractor - Symbols/parser_langs.go regex extractors for non-Go languages - Symbols/treesitter.go tree-sitter-style scope-aware extractor - Symbols/patterns.go index include/exclude pattern loader - Static/callgraph.go Go caller/callee graph from go/ast - Static/depgraph.go package-level dep graph (go.mod + package.json) - Static/imports.go file-level import graph - Static/hierarchy.go project -> package -> file 3-level summary - Static/interface_extract.go exported API surface (signatures only) - Static/cochange.go git-history co-change matrix - Static/changeset.go change-set-aware working set from git diff - Static/ownership.go git + CODEOWNERS ownership map - Quality/smells.go design smell detectors - Quality/complexity.go cyclomatic complexity - Quality/health_score.go weighted health-score rollup - Quality/doclint.go doc-comment coverage - Quality/dead_code.go unreferenced declaration detector - Quality/migration_detector.go deprecated-API migration suggestions - API/api_scanner.go HTTP route scanners + OpenAPI export - Incr/incremental.go CodeIndexer interface and reindex loop - Incr/incremental_map.go persistent on-disk symbol cache --- internal/intelligence/repomap/api_scanner.go | 5 +++++ internal/intelligence/repomap/cache.go | 3 +++ internal/intelligence/repomap/callgraph.go | 4 ++++ internal/intelligence/repomap/changeset.go | 5 +++++ internal/intelligence/repomap/cochange.go | 4 ++++ internal/intelligence/repomap/complexity.go | 6 ++++++ internal/intelligence/repomap/dead_code.go | 6 ++++++ internal/intelligence/repomap/depgraph.go | 5 +++++ internal/intelligence/repomap/doclint.go | 5 +++++ internal/intelligence/repomap/file_grouper.go | 5 +++++ internal/intelligence/repomap/gitignore.go | 4 ++++ internal/intelligence/repomap/health_score.go | 5 +++++ internal/intelligence/repomap/hierarchy.go | 4 ++++ internal/intelligence/repomap/imports.go | 4 ++++ internal/intelligence/repomap/incremental.go | 7 +++++++ internal/intelligence/repomap/incremental_map.go | 5 +++++ 16 files changed, 77 insertions(+) diff --git a/internal/intelligence/repomap/api_scanner.go b/internal/intelligence/repomap/api_scanner.go index 0b4c2755..60a23dd0 100644 --- a/internal/intelligence/repomap/api_scanner.go +++ b/internal/intelligence/repomap/api_scanner.go @@ -1,3 +1,8 @@ +// Package repomap: api_scanner.go discovers HTTP endpoints in a project +// by detecting the framework (Chi, net/http, Gin, Echo, Gorilla mux, or +// Fiber) and extracting route declarations into an APIMap. FormatAPIMap +// renders the routes as text; GenerateOpenAPI produces a 3.x OpenAPI +// document for the same set. package repomap import ( diff --git a/internal/intelligence/repomap/cache.go b/internal/intelligence/repomap/cache.go index 9c00160f..c3f62775 100644 --- a/internal/intelligence/repomap/cache.go +++ b/internal/intelligence/repomap/cache.go @@ -1,3 +1,6 @@ +// Package repomap: cache.go implements the in-process LRU symbol cache keyed +// by (path, modtime). It is consulted by parseFileSymbols before re-parsing +// and is cleared on process exit; for a persistent cache, use IncrementalMap. package repomap import ( diff --git a/internal/intelligence/repomap/callgraph.go b/internal/intelligence/repomap/callgraph.go index 448b1315..242ce28c 100644 --- a/internal/intelligence/repomap/callgraph.go +++ b/internal/intelligence/repomap/callgraph.go @@ -1,3 +1,7 @@ +// Package repomap: callgraph.go builds a per-function caller/callee graph +// from a Go tree using go/parser and go/ast. It supports bounded BFS +// traversals in both directions (CallersOf, CalleesOf) and a symmetric +// Neighborhood helper used by the navigation index. package repomap import ( diff --git a/internal/intelligence/repomap/changeset.go b/internal/intelligence/repomap/changeset.go index 08db9d6f..747ac461 100644 --- a/internal/intelligence/repomap/changeset.go +++ b/internal/intelligence/repomap/changeset.go @@ -1,3 +1,8 @@ +// Package repomap: changeset.go derives a focused ChangeSetContext from +// a git diff (working tree or a range against a base ref). The context +// lists changed files, files affected by the changes (dependents), and +// files needed to understand the changes (imports), and is used to build +// smaller, change-set-aware LLM prompts. package repomap import ( diff --git a/internal/intelligence/repomap/cochange.go b/internal/intelligence/repomap/cochange.go index c2126352..7ec0c791 100644 --- a/internal/intelligence/repomap/cochange.go +++ b/internal/intelligence/repomap/cochange.go @@ -1,3 +1,7 @@ +// Package repomap: cochange.go mines the last N git commits to build a +// co-occurrence matrix of files that change together, and exposes +// RelatedFiles for "what else should I look at" recommendations after a +// file has been touched. package repomap import ( diff --git a/internal/intelligence/repomap/complexity.go b/internal/intelligence/repomap/complexity.go index c6382a77..b4022ba5 100644 --- a/internal/intelligence/repomap/complexity.go +++ b/internal/intelligence/repomap/complexity.go @@ -1,3 +1,9 @@ +// Package repomap: complexity.go computes cyclomatic and cognitive +// complexity per function (Go files via go/ast, other languages via +// brace-tracking regex), aggregates a ComplexityReport per file, and +// surfaces refactoring suggestions and a MaintainabilityIndex for the +// health score. FindHotspots walks an entire project and returns the +// highest-complexity functions first. package repomap import ( diff --git a/internal/intelligence/repomap/dead_code.go b/internal/intelligence/repomap/dead_code.go index 15c5a685..94f6a8ed 100644 --- a/internal/intelligence/repomap/dead_code.go +++ b/internal/intelligence/repomap/dead_code.go @@ -1,3 +1,9 @@ +// Package repomap: dead_code.go flags top-level declarations (functions, +// methods, types, vars, consts) that appear to be unreferenced. It is +// deliberately conservative: declarations reachable from tests, interface +// implementations, or via reflection are not flagged. FormatDeadCode +// produces a human-readable summary, GenerateRemovalPlan a structured +// edit script. package repomap import ( diff --git a/internal/intelligence/repomap/depgraph.go b/internal/intelligence/repomap/depgraph.go index 952d5078..0bcf9310 100644 --- a/internal/intelligence/repomap/depgraph.go +++ b/internal/intelligence/repomap/depgraph.go @@ -1,3 +1,8 @@ +// Package repomap: depgraph.go constructs a package-level dependency graph +// for Go (via go.mod + go/parser ImportsOnly) and JavaScript/TypeScript +// (via package.json + import/require regexes). It computes topological +// order, layers, cycles, hot paths, and renders the result as DOT, +// Mermaid, or ASCII art for use in summaries and dashboards. package repomap import ( diff --git a/internal/intelligence/repomap/doclint.go b/internal/intelligence/repomap/doclint.go index 9f30ae13..0307953b 100644 --- a/internal/intelligence/repomap/doclint.go +++ b/internal/intelligence/repomap/doclint.go @@ -1,3 +1,8 @@ +// Package repomap: doclint.go checks Go (and selectively other) source +// files for missing, outdated, incomplete, or unclear doc comments on +// exported symbols, and produces a per-file DocLintResult with a score +// and issue list. The result feeds the documentation-coverage dimension +// of the repository health score. package repomap import ( diff --git a/internal/intelligence/repomap/file_grouper.go b/internal/intelligence/repomap/file_grouper.go index b38d0ac0..9fd211b4 100644 --- a/internal/intelligence/repomap/file_grouper.go +++ b/internal/intelligence/repomap/file_grouper.go @@ -1,3 +1,8 @@ +// Package repomap: file_grouper.go identifies sets of files that should +// be edited as a unit (Go packages, feature slices, layered modules, +// test/source pairs, configuration groups). The resulting FileGroups are +// used by the context builder to include whole groups in a single +// prompt, not disjoint individual files. package repomap import ( diff --git a/internal/intelligence/repomap/gitignore.go b/internal/intelligence/repomap/gitignore.go index 0a098168..f55eecf1 100644 --- a/internal/intelligence/repomap/gitignore.go +++ b/internal/intelligence/repomap/gitignore.go @@ -1,3 +1,7 @@ +// Package repomap: gitignore.go composes .gitignore rules from a project +// root, walking parent directories so that nested gitignore files (and +// the .git/info/exclude and global gitignore) all take effect. The resulting +// GitignoreRules is consulted by the file walk in Generate. package repomap import ( diff --git a/internal/intelligence/repomap/health_score.go b/internal/intelligence/repomap/health_score.go index 78e24dd7..3c8ff656 100644 --- a/internal/intelligence/repomap/health_score.go +++ b/internal/intelligence/repomap/health_score.go @@ -1,3 +1,8 @@ +// Package repomap: health_score.go rolls the individual signals +// (complexity, smells, dead code, doc coverage, ownership, duplication) +// into a single weighted HealthScore with per-dimension breakdowns, +// issue lists, and a letter grade. CompareScores produces a "before / +// after" diff suitable for commit messages or PR descriptions. package repomap import ( diff --git a/internal/intelligence/repomap/hierarchy.go b/internal/intelligence/repomap/hierarchy.go index 3f4f3f66..3d131031 100644 --- a/internal/intelligence/repomap/hierarchy.go +++ b/internal/intelligence/repomap/hierarchy.go @@ -1,3 +1,7 @@ +// Package repomap: hierarchy.go builds a three-level summary of a project +// (project -> package -> file) by grouping scanned files into Go packages +// and recording the exported symbols of each. It is consumed by the +// summary generator to produce an LLM-friendly project overview. package repomap import ( diff --git a/internal/intelligence/repomap/imports.go b/internal/intelligence/repomap/imports.go index 39f4be75..3925bd5b 100644 --- a/internal/intelligence/repomap/imports.go +++ b/internal/intelligence/repomap/imports.go @@ -1,3 +1,7 @@ +// Package repomap: imports.go builds a file-level ImportGraph from a Go +// project, mapping each file to its imports and reverse-mapping dependents. +// The graph is the cheapest cross-file signal in the package and is used by +// ChangeSetContext, PredictRelevantFiles, and the symbol reranker. package repomap import ( diff --git a/internal/intelligence/repomap/incremental.go b/internal/intelligence/repomap/incremental.go index 9d610c8e..94e4a208 100644 --- a/internal/intelligence/repomap/incremental.go +++ b/internal/intelligence/repomap/incremental.go @@ -1,3 +1,10 @@ +// Package repomap: incremental.go defines the CodeIndexer interface +// (the contract the repomap package uses to push code chunks to and +// query code chunks from a downstream store such as the memory package's +// YaadBridge) and IncrementalReindex, which diffs the project tree +// against a CodeIndexer's known file set and reindexes only added or +// changed files, removing deleted ones. ComputeFileHash returns the +// SHA-256 used to detect content changes. package repomap import ( diff --git a/internal/intelligence/repomap/incremental_map.go b/internal/intelligence/repomap/incremental_map.go index d1f85322..0a93880c 100644 --- a/internal/intelligence/repomap/incremental_map.go +++ b/internal/intelligence/repomap/incremental_map.go @@ -1,3 +1,8 @@ +// Package repomap: incremental_map.go is the persistent, on-disk symbol +// cache. It stores per-file SHA-256 hashes and the corresponding symbol +// lists in .hawk/repomap-cache.json (or a caller-provided directory). On +// regeneration only files whose hash changed are re-parsed, and deleted +// files are evicted, so the index stays accurate without a full rebuild. package repomap import ( From f89133989256f5a3b63bbfc5b9b6bdf2d27a6c66 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:41:53 +0530 Subject: [PATCH 3/9] docs(repomap): add leading comments to Search, Grouping, and remaining Symbols files (18 files) Second batch of file-level leading comments, covering the Search and navigation files (BM25, PageRank, reranking, prediction, change-set context), the Grouping file (file_grouper, summary), and the remaining Symbols files (parser, parser_enhanced, parser_langs, treesitter, patterns, watcher). Each comment is intentionally short; see doc.go and README.md for the architecture overview. --- internal/intelligence/repomap/interface_extract.go | 5 +++++ internal/intelligence/repomap/migration_detector.go | 5 +++++ internal/intelligence/repomap/navigation.go | 4 ++++ internal/intelligence/repomap/ownership.go | 4 ++++ internal/intelligence/repomap/pagerank.go | 6 ++++++ internal/intelligence/repomap/parser.go | 4 ++++ internal/intelligence/repomap/parser_enhanced.go | 4 ++++ internal/intelligence/repomap/parser_langs.go | 5 +++++ internal/intelligence/repomap/patterns.go | 4 ++++ internal/intelligence/repomap/predict.go | 5 +++++ internal/intelligence/repomap/rerank.go | 4 ++++ internal/intelligence/repomap/semantic.go | 4 ++++ internal/intelligence/repomap/semantic_search.go | 5 +++++ internal/intelligence/repomap/shapley.go | 4 ++++ internal/intelligence/repomap/smells.go | 7 +++++++ internal/intelligence/repomap/summary.go | 5 +++++ internal/intelligence/repomap/treesitter.go | 5 +++++ internal/intelligence/repomap/watcher.go | 4 ++++ 18 files changed, 84 insertions(+) diff --git a/internal/intelligence/repomap/interface_extract.go b/internal/intelligence/repomap/interface_extract.go index 73a4f7c6..06296b91 100644 --- a/internal/intelligence/repomap/interface_extract.go +++ b/internal/intelligence/repomap/interface_extract.go @@ -1,3 +1,8 @@ +// Package repomap: interface_extract.go returns just the exported API +// surface of a Go file (function signatures, type declarations, constants) +// with bodies stripped, for use in prompt contexts where body text is +// unaffordable. The output is roughly an order of magnitude smaller than +// the source it summarises. package repomap import ( diff --git a/internal/intelligence/repomap/migration_detector.go b/internal/intelligence/repomap/migration_detector.go index 648ccede..e96bc065 100644 --- a/internal/intelligence/repomap/migration_detector.go +++ b/internal/intelligence/repomap/migration_detector.go @@ -1,3 +1,8 @@ +// Package repomap: migration_detector.go applies a set of MigrationRule +// patterns to a project and reports MigrationOpportunities - patterns that +// could be updated to a newer API, a more idiomatic construct, or a more +// secure/performant alternative. AutoFix can rewrite selected patterns +// in-place. Results feed the health score's "deprecated APIs" dimension. package repomap import ( diff --git a/internal/intelligence/repomap/navigation.go b/internal/intelligence/repomap/navigation.go index ad8b9000..cc0e0ce8 100644 --- a/internal/intelligence/repomap/navigation.go +++ b/internal/intelligence/repomap/navigation.go @@ -1,3 +1,7 @@ +// Package repomap: navigation.go implements an LSP-free "go to definition / +// find references / find implementations / find callers / find callees" +// index for a Go project. The index is built in-memory from go/parser ASTs +// and is consulted by the Hawk CLI's navigate subcommand. package repomap import ( diff --git a/internal/intelligence/repomap/ownership.go b/internal/intelligence/repomap/ownership.go index e4b78408..c869e46a 100644 --- a/internal/intelligence/repomap/ownership.go +++ b/internal/intelligence/repomap/ownership.go @@ -1,3 +1,7 @@ +// Package repomap: ownership.go combines git history with CODEOWNERS-style +// rules to compute per-file ownership: primary owner, contributors, +// recency, and bus-factor risk. It is consumed by the health-score +// dimension that flags orphaned files. package repomap import ( diff --git a/internal/intelligence/repomap/pagerank.go b/internal/intelligence/repomap/pagerank.go index 9502e5f1..4887a95c 100644 --- a/internal/intelligence/repomap/pagerank.go +++ b/internal/intelligence/repomap/pagerank.go @@ -1,3 +1,9 @@ +// Package repomap: pagerank.go builds a per-symbol reference graph from a +// project (file:symbol nodes with directed "is referenced by" edges) and +// runs a damped PageRank iteration over it. BuildSymbolGraph accepts an +// optional IncrementalMap so only changed files are re-processed on each +// invocation. TopSymbols returns the highest-ranked symbols for prompt +// inclusion. package repomap import ( diff --git a/internal/intelligence/repomap/parser.go b/internal/intelligence/repomap/parser.go index 55260fd6..fa9c3411 100644 --- a/internal/intelligence/repomap/parser.go +++ b/internal/intelligence/repomap/parser.go @@ -1,3 +1,7 @@ +// Package repomap: parser.go contains the original regex-based Go symbol +// extractor. It is retained as a fast, dependency-free path; new code should +// prefer the AST-based EnhancedGoParser in parser_enhanced.go and the +// tree-sitter-style extractor in treesitter.go. package repomap import ( diff --git a/internal/intelligence/repomap/parser_enhanced.go b/internal/intelligence/repomap/parser_enhanced.go index e5d1e5f7..8d73594c 100644 --- a/internal/intelligence/repomap/parser_enhanced.go +++ b/internal/intelligence/repomap/parser_enhanced.go @@ -1,3 +1,7 @@ +// Package repomap: parser_enhanced.go wraps the standard-library go/parser +// and go/ast packages to extract symbols, methods, embedded types, and +// interface satisfaction from Go source. It replaces the legacy regex path +// for Go without requiring CGO or a tree-sitter binary. package repomap import ( diff --git a/internal/intelligence/repomap/parser_langs.go b/internal/intelligence/repomap/parser_langs.go index ed978255..57740cd0 100644 --- a/internal/intelligence/repomap/parser_langs.go +++ b/internal/intelligence/repomap/parser_langs.go @@ -1,3 +1,8 @@ +// Package repomap: parser_langs.go holds the regex-based symbol extractors +// for every non-Go language the repomap knows about (C, C++, Java, C#, +// PHP, Ruby, Kotlin, Swift, Scala, Lua, Dart, Elixir, Haskell, ...). Each +// language has its own parseX function that the dispatcher in repomap.go +// selects by file extension. package repomap import ( diff --git a/internal/intelligence/repomap/patterns.go b/internal/intelligence/repomap/patterns.go index 328de272..22d3d2cc 100644 --- a/internal/intelligence/repomap/patterns.go +++ b/internal/intelligence/repomap/patterns.go @@ -1,3 +1,7 @@ +// Package repomap: patterns.go loads a .hawk/repomap-patterns.json file +// (if present) describing which files to include or exclude from indexing, +// and falls back to DefaultIndexPatterns otherwise. The result is consumed +// by Generate, BuildSemanticIndex, and the watcher to skip unwanted trees. package repomap import ( diff --git a/internal/intelligence/repomap/predict.go b/internal/intelligence/repomap/predict.go index 2a4d0bac..5af2f0cf 100644 --- a/internal/intelligence/repomap/predict.go +++ b/internal/intelligence/repomap/predict.go @@ -1,3 +1,8 @@ +// Package repomap: predict.go predicts which files in a project are most +// likely to be relevant to the next edit, given the user's prompt, recent +// edits (a RecentEditTracker), the import graph, and a symbol map. The +// output is consumed by the change-set-aware context builder to populate +// a small, focused working set. package repomap import ( diff --git a/internal/intelligence/repomap/rerank.go b/internal/intelligence/repomap/rerank.go index c6747b71..bbdc329c 100644 --- a/internal/intelligence/repomap/rerank.go +++ b/internal/intelligence/repomap/rerank.go @@ -1,3 +1,7 @@ +// Package repomap: rerank.go applies a BM25-over-BM25 reranking pass to a +// candidate set of code chunks. It is used after a faster but less precise +// retrieval step (semantic similarity, PageRank, or import-graph proximity) +// to surface the chunks that are most relevant to the query terms. package repomap import ( diff --git a/internal/intelligence/repomap/semantic.go b/internal/intelligence/repomap/semantic.go index a620a430..fd79509a 100644 --- a/internal/intelligence/repomap/semantic.go +++ b/internal/intelligence/repomap/semantic.go @@ -1,3 +1,7 @@ +// Package repomap: semantic.go provides the lower-level chunked TF-IDF +// index used by the reranker. BuildSemanticIndex scans a directory, splits +// source files into ~40-line CodeChunks, and stores the result on disk +// (gob-encoded) for fast reload on subsequent sessions. package repomap import ( diff --git a/internal/intelligence/repomap/semantic_search.go b/internal/intelligence/repomap/semantic_search.go index 35aa23fc..5f74d880 100644 --- a/internal/intelligence/repomap/semantic_search.go +++ b/internal/intelligence/repomap/semantic_search.go @@ -1,3 +1,8 @@ +// Package repomap: semantic_search.go is the BM25-ranked full-text search +// engine over the Document set produced by the navigation index. It +// tokenises queries, expands them with ExpandQuery, and returns SearchHit +// results with snippet extraction. This is the search backend used by the +// Hawk CLI's "find" subcommand. package repomap import ( diff --git a/internal/intelligence/repomap/shapley.go b/internal/intelligence/repomap/shapley.go index 6dbee1ff..656fda24 100644 --- a/internal/intelligence/repomap/shapley.go +++ b/internal/intelligence/repomap/shapley.go @@ -1,3 +1,7 @@ +// Package repomap: shapley.go applies a Shapley-value-based ranking over +// code chunks to score their marginal contribution to a task's context +// set. It complements PageRank by accounting for redundancy across the +// selected chunks, not just the in-graph centrality of each one. package repomap import ( diff --git a/internal/intelligence/repomap/smells.go b/internal/intelligence/repomap/smells.go index 4b13865c..dba5a95b 100644 --- a/internal/intelligence/repomap/smells.go +++ b/internal/intelligence/repomap/smells.go @@ -1,3 +1,10 @@ +// Package repomap: smells.go detects classic design smells (god object, +// long parameter list, feature envy, data clump, primitive obsession, +// long method, excessive imports, large file) via AST and heuristic rules. +// Each smell has a severity, a category, and a refactoring suggestion that +// is rendered by FormatSmells for inclusion in the health score. +// +// Package repomap package repomap import ( diff --git a/internal/intelligence/repomap/summary.go b/internal/intelligence/repomap/summary.go index 90837bb0..682f3f39 100644 --- a/internal/intelligence/repomap/summary.go +++ b/internal/intelligence/repomap/summary.go @@ -1,3 +1,8 @@ +// Package repomap: summary.go produces the LLM-facing CodebaseSummary: +// a high-level description of the project, its packages, entry points, +// key files, and inferred architecture. RenderForPrompt and RenderCompact +// emit the summary in token-bounded forms suitable for injection at the +// start of a long session. package repomap import ( diff --git a/internal/intelligence/repomap/treesitter.go b/internal/intelligence/repomap/treesitter.go index 00818536..140478e0 100644 --- a/internal/intelligence/repomap/treesitter.go +++ b/internal/intelligence/repomap/treesitter.go @@ -1,3 +1,8 @@ +// Package repomap: treesitter.go is the "tree-sitter-inspired" scope-aware +// extractor. It uses go/ast for Go and a small scope-tracking regex engine +// for other languages, returning the same shape of symbol list a real +// tree-sitter parser would. ParseFileEnhanced and ParseSourceEnhanced are +// the canonical entry points used by the rest of the package. package repomap import ( diff --git a/internal/intelligence/repomap/watcher.go b/internal/intelligence/repomap/watcher.go index 6baf900a..2afd8b60 100644 --- a/internal/intelligence/repomap/watcher.go +++ b/internal/intelligence/repomap/watcher.go @@ -1,3 +1,7 @@ +// Package repomap: watcher.go wraps fsnotify.Watcher to monitor a project +// tree for file-system events and invoke a callback when a supported +// source file changes. It is the runtime hook used to keep the in-memory +// symbol index in sync with the working tree during a long-running session. package repomap import ( From 06584a2f152fa932662d60a22479e86b9530db4b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:43:21 +0530 Subject: [PATCH 4/9] docs(context/repomap): clarify that this package is the prompt-injection shim The previous package comment described what the package did but did not call out the boundary with internal/intelligence/repomap, which is the deeper analysis engine. The two packages share no code and serve different callers (this one is the context layer's narrow budgeted-map entry point; the other is the full analysis toolkit). The new comment makes the boundary explicit, points readers at the deep package for symbol-level search / quality / API features, and adds implementation notes on the PageRank pass and file-size limits. --- internal/context/repomap/repomap.go | 38 +++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/internal/context/repomap/repomap.go b/internal/context/repomap/repomap.go index 5ed88780..4638166f 100644 --- a/internal/context/repomap/repomap.go +++ b/internal/context/repomap/repomap.go @@ -1,13 +1,35 @@ -// Package repomap builds an AST-ranked overview of a codebase within a token -// budget, in the spirit of Aider's repository map. +// Package repomap is the prompt-injection shim that produces a token-budgeted +// repository overview for hawk's context layer. It builds an import/refer +// graph over the source files in root, ranks the nodes with a PageRank +// pass, and renders the highest-ranked files (and their top symbols) as a +// compact text block capped at Options.Budget tokens. // -// It constructs a graph where files are nodes and edges are import/reference -// dependencies, ranks the nodes with a PageRank-like pass, and emits a compact -// textual map (file -> key symbols) constrained to a configurable token budget. +// # Relationship to internal/intelligence/repomap // -// The package is intentionally dependency-light: Go files are parsed with -// go/parser + go/ast; other languages fall back to a small regex extractor. -// Only the standard library is used. +// hawk ships a second package, internal/intelligence/repomap, that exposes +// a much larger surface: call graphs, search, quality signals, API +// scanning, incremental indexing, and so on. That package is the deep +// analysis engine. THIS package is intentionally narrow: one entry point +// (RepoMap), a single Graph type, a self-contained scan/rank/render +// pipeline, and a stdlib-only dependency surface. The two packages share +// no code; they merely share a name and a goal (a useful map of a +// repository). The deep package's doc.go spells this out from the other +// side of the boundary. +// +// Callers that need more than a budgeted text block - symbol-level +// navigation, BM25 search, dead-code detection, OpenAPI export, etc. - +// should import internal/intelligence/repomap directly instead of +// extending this one. +// +// # Implementation notes +// +// Go files are parsed with go/parser and go/ast; other languages fall +// back to a small regex extractor. Only the standard library is used. +// Files larger than 1 MiB, hidden directories, and a small set of +// well-known build/vendor trees are skipped during the scan. The +// PageRank pass uses the standard damped iteration with dangling-mass +// redistribution and exits early once the total node-to-node delta +// drops below 1e-9. package repomap import ( From 5688535c8dbf60c7bcd2e1c47a1cbea8efd6ed36 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:44:42 +0530 Subject: [PATCH 5/9] docs(repomap): add README with architecture overview and entry-point map The README is the human-facing entry point for the package. It contains: - One-paragraph overview (what Generate does, what else lives here) - Architecture diagram (mermaid) of the file groups and their data flow - File-group table mapping every group to its files and purpose - Entry-point map listing the headline public APIs by group - Storage model (in-process LRU, persistent .hawk/repomap-cache.json, fsnotify watch protocol) - Extension points: how to add a new language parser, a new code smell, a new HTTP framework scanner - Performance characteristics and known scaling limits per subsystem - A pointer to doc.go (machine-readable) and doc_test.go (worked example), plus the cross-reference back to internal/context/repomap --- internal/intelligence/repomap/README.md | 288 ++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 internal/intelligence/repomap/README.md diff --git a/internal/intelligence/repomap/README.md b/internal/intelligence/repomap/README.md new file mode 100644 index 00000000..60ca7c53 --- /dev/null +++ b/internal/intelligence/repomap/README.md @@ -0,0 +1,288 @@ +# `internal/intelligence/repomap/` + +> Deep code-analysis engine for hawk: language-aware symbol extraction, +> static analysis, search, quality signals, API scanning, and incremental +> indexing. Distinct from `internal/context/repomap`, which is the narrow +> prompt-injection shim used by the context layer. + +## What it does + +`Generate(dir, opts)` walks a directory, dispatches each supported source +file to a language-aware parser, and returns a `RepoMap`: a token-budgeted +summary of files and their top-level symbols suitable for injection into +LLM prompts. Around that core the package accumulates a large set of +specialised analyses - call graph, import graph, type hierarchy, code +ownership, BM25 search, cyclomatic complexity, code smells, dead-code +detection, health score, doc linter, migration detector, HTTP route +scanner, and an incremental file-hash cache - that all share the same +parsed-symbol substrate. + +The package is stdlib-only at its core (`go/parser`, `go/ast`, `go/token`, +`encoding/*`). The only third-party dependency is `github.com/fsnotify +/fsnotify` for file watching; hawk's `internal/scoring` and +`internal/ui/icons` are pulled in where they are used. Tree-sitter is +deliberately not required: Go is parsed with `go/ast` and other languages +are handled by an enhanced regex extractor with scope tracking. + +## Architecture + +```mermaid +flowchart TB + subgraph Entry["Entry point"] + REPOMAP[repomap.go
Generate, RepoMap, Options] + end + + subgraph Core["Core"] + CACHE[cache.go
in-process LRU] + WATCHER[watcher.go
fsnotify wrapper] + GITIGNORE[gitignore.go
composed rules] + PATTERNS[patterns.go
include/exclude loader] + end + + subgraph Symbols["Symbols / parsing"] + PARSER[parser.go
regex-Go] + ENHANCED[parser_enhanced.go
AST-Go] + LANGS[parser_langs.go
regex non-Go] + TS[treesitter.go
scope-aware] + end + + subgraph Static["Static analysis"] + CALL[callgraph.go] + DEP[depgraph.go] + IMP[imports.go] + HIER[hierarchy.go] + IFACE[interface_extract.go] + COCHG[cochange.go] + CHG[changeset.go] + OWN[ownership.go] + SHAP[shapley.go] + end + + subgraph Search["Search / navigation"] + NAV[navigation.go] + SEM[semantic.go] + SEMSRCH[semantic_search.go] + RERANK[rerank.go] + PR[pagerank.go] + PRED[predict.go] + end + + subgraph Quality["Quality signals"] + CPLX[complexity.go] + SMELL[smells.go] + HEALTH[health_score.go] + DOC[doclint.go] + DEAD[dead_code.go] + MIG[migration_detector.go] + end + + subgraph API["API surface"] + SCAN[api_scanner.go] + end + + subgraph Incr["Incremental"] + INCR[incremental.go] + INCRM[incremental_map.go] + end + + subgraph Group["Grouping"] + GROUPER[file_grouper.go] + SUMMARY[summary.go] + end + + REPOMAP --> CACHE + REPOMAP --> WATCHER + REPOMAP --> GITIGNORE + REPOMAP --> PATTERNS + REPOMAP --> PARSER + REPOMAP --> ENHANCED + REPOMAP --> LANGS + REPOMAP --> TS + Static --> IMP + Static --> CALL + Search --> PR + Search --> SEM + Search --> SEMSRCH + Quality --> CPLX + Quality --> SMELL + Quality --> HEALTH + Quality --> DOC + Quality --> DEAD + Quality --> MIG + API --> SCAN + Incr --> INCR + Incr --> INCRM + Group --> GROUPER + Group --> SUMMARY +``` + +## File groups + +| Group | Files | Purpose | +|------------------------|--------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------| +| **Core** | `repomap.go`, `cache.go`, `watcher.go`, `gitignore.go`, `patterns.go` | Entry point, file scanning, file watching, in-process and persistent caches | +| **Symbols / parsing** | `parser.go`, `parser_enhanced.go`, `parser_langs.go`, `treesitter.go` | Language-aware symbol extraction: regex Go, AST Go, regex non-Go, scope-aware (tree-sitter-like) | +| **Static analysis** | `callgraph.go`, `depgraph.go`, `imports.go`, `hierarchy.go`, `interface_extract.go`, `cochange.go`, `changeset.go`, `ownership.go`, `shapley.go` | Callers/callees, package-level deps, import graph, type hierarchy, exported surface, git-history co-change, change-set context, ownership, Shapley value ranker | +| **Search / navigation**| `navigation.go`, `semantic.go`, `semantic_search.go`, `rerank.go`, `pagerank.go`, `predict.go` | LSP-free navigation index, BM25 search, PageRank ranking, reranking, relevance prediction | +| **Quality signals** | `complexity.go`, `smells.go`, `health_score.go`, `doclint.go`, `dead_code.go`, `migration_detector.go` | Cyclomatic complexity, code smells, health rollup, doc linter, dead code, deprecated-API detection | +| **API surface** | `api_scanner.go` | HTTP route scanners (Chi, net/http, Gin, Echo, Gorilla, Fiber) + OpenAPI export | +| **Incremental** | `incremental.go`, `incremental_map.go` | `CodeIndexer` interface and reindex loop, persistent on-disk symbol cache | +| **Grouping** | `file_grouper.go`, `summary.go` | File grouping, codebase summary suitable for prompt injection | + +## Entry points + +The full public surface is read from the source. The headline entry points +are: + +- **`Generate(dir string, opts Options) (*RepoMap, error)`** in `repomap.go` - + the canonical entry point. Walks `dir`, parses every supported file, + and returns a `RepoMap` with `Files` and a `TokenEst`. +- **`(*RepoMap).Format(maxTokens int) string`** in `repomap.go` - renders + the map as text, truncating to fit `maxTokens`. +- **`BuildCallGraph(root string) (*CallGraph, error)`** in `callgraph.go` - + Go-only caller/callee graph from `go/ast`. +- **`BuildDepGraph` / `NewDepGraph` / `BuildFromGoMod` / `BuildFromPackageJSON`** + in `depgraph.go` - Go and JS/TS dependency graphs. +- **`BuildImportGraph(root string) (*ImportGraph, error)`** in `imports.go` - + file-level import graph. +- **`NewNavIndex` / `(*NavIndex).BuildIndex` / `(*NavIndex).GoToDefinition` / + `(*NavIndex).FindReferences` / `(*NavIndex).FindImplementations`** in + `navigation.go` - the LSP-free navigation API. +- **`BuildSemanticIndex` / `(*SemanticIndex).Search` / + `NewSemanticSearchIndex`** in `semantic.go` / `semantic_search.go` - + chunked TF-IDF and BM25 search. +- **`BuildSymbolGraph` / `(*SymbolGraph).TopSymbols`** in `pagerank.go` - + symbol-level PageRank. +- **`NewComplexityAnalyzer` / `(*ComplexityAnalyzer).FindHotspots`** in + `complexity.go` - complexity hotspots. +- **`NewSmellDetector` / `(*SmellDetector).ScanDirectory`** in `smells.go` + - code smell detection. +- **`NewHealthScorer` / `(*HealthScorer).Score` / `FormatScore` / + `CompareScores`** in `health_score.go` - health score rollup and + before/after diff. +- **`NewDeadCodeDetector` / `(*DeadCodeDetector).Detect`** in + `dead_code.go` - dead-code detection. +- **`NewMigrationDetector` / `(*MigrationDetector).Scan` / + `FormatOpportunities` / `AutoFix`** in `migration_detector.go` - + deprecated-API migration. +- **`NewAPIScanner` / `(*APIScanner).Scan` / `FormatAPIMap` / + `GenerateOpenAPI`** in `api_scanner.go` - HTTP route scanner. +- **`NewIncrementalMap(cacheDir string) (*IncrementalMap, error)`** in + `incremental_map.go` - persistent on-disk symbol cache. +- **`IncrementalReindex(dir string, ignore []string, indexer CodeIndexer) + (added, skipped, removed int, err error)`** in `incremental.go` - the + diff-and-reindex loop for the `CodeIndexer` interface. +- **`NewFileWatcher(root string, onChange func(path string)) + (*FileWatcher, error)`** in `watcher.go` - fsnotify wrapper. +- **`NewSummaryGenerator(projectDir string, maxTokens int) + *SummaryGenerator` / `RenderForPrompt` / `RenderCompact`** in + `summary.go` - the prompt-injectable codebase summary. +- **`BuildHierarchy(root string) (*HierarchicalSummary, error)`** in + `hierarchy.go` - 3-level project summary. +- **`PredictRelevantFiles` / `NewRecentEditTracker`** in `predict.go` - + relevance prediction from prompt, recent edits, import graph, and + symbol map. +- **`BuildCoChangeAnalysis(root string, commitLimit int) + (*CoChangeAnalysis, error)`** in `cochange.go` - git-history co-change. +- **`FromGitDiff` / `FromGitDiffRange`** in `changeset.go` - change-set + context. +- **`NewOwnershipMap` / `(*OwnershipMap).Compute`** in `ownership.go` - + per-file ownership. +- **`NewShapleyRanker(chunks []CodeChunk) *ShapleyRanker`** in `shapley.go` + - Shapley-value chunk ranking. +- **`NewAPIScanner`** in `api_scanner.go` - HTTP route scanner factory. + +## Storage model + +- **In-process symbol cache** (`cache.go`): an LRU keyed by + `(path, modtime)` capped at `defaultMaxSymbolCacheEntries` (5000). It + is consulted by `parseFileSymbols` in `repomap.go` and is cleared on + process exit. +- **Persistent incremental cache** (`incremental_map.go`): JSON file at + `/repomap-cache.json` (typically `.hawk/repomap-cache.json`) + keyed by SHA-256 of file content. `IncrementalReindex` diffs the + project tree against the cached hash set and re-parses only changed + files. +- **Watch protocol** (`watcher.go`): `NewFileWatcher(root, onChange)` walks + the tree, registers every non-hidden, non-vendor directory with + `fsnotify.Watcher`, and invokes `onChange(path)` on + `Write`/`Create`/`Remove` events for supported source files. `Start` + launches the event loop goroutine; `Stop` terminates it. + +## Extension points + +### Add a new language parser + +1. Add the extension to `isSupportedExt` in `repomap.go` so the walker + picks up the new files. +2. Add a new case to `parseFileSymbols` in `repomap.go` that dispatches + to a `parseX` function. +3. Add the `parseX(src string) []Symbol` function. For most languages + you can copy the `jsSpec` / `cSpec` patterns in `parser_langs.go`. +4. If the language needs scope-aware extraction, add a new + `TreeSitterParser` method in `treesitter.go` instead. +5. Optionally wire the same extension into `detectLang` in + `internal/context/repomap/scan.go` if the prompt-injection shim + should also pick it up. + +### Add a new code smell + +1. Add a `Detector func(...) []CodeSmell` field on `SmellDetector` in + `smells.go`. +2. Wire the new field into `NewSmellDetector` and `ScanDirectory`. +3. Tune `SmellThresholds` defaults if the new smell has tunable limits. + +### Add a new HTTP framework scanner + +1. Add a `ScanX(content, file string) []APIEndpoint` function in + `api_scanner.go` using one of the existing scanners (e.g. `ScanChi`) + as a template. +2. Add the corresponding case to `DetectFramework` so the dispatcher + knows to use the new scanner. +3. If the new framework uses a different routing style, update + `FormatAPIMap` and `GenerateOpenAPI` to handle the new metadata. + +## Performance and scaling + +- **`Generate`** is O(N) in the number of files with a hard cap on + `Options.MaxFiles` (default 500). The walk is single-threaded; the + per-file parsing is also single-threaded but the work is bounded per + file. +- **Symbol cache** (`cache.go`) keeps hot files in memory; it is + process-local and does not survive a restart. +- **IncrementalMap** (`incremental_map.go`) persists hashes and symbol + lists on disk. `IncrementalReindex` only re-parses files whose SHA-256 + has changed. For very large repositories (tens of thousands of files) + prefer the incremental path over `Generate`. +- **Static-analysis passes** (`callgraph`, `depgraph`, `pagerank`, + `shapley`) are O(V + E) per iteration over the symbol graph and scale + linearly with the number of declarations, not the number of lines. +- **BM25 search** (`semantic_search.go`) is O(Q * D) per query, where Q + is the number of query terms and D is the number of indexed documents. + IDF and average document length are precomputed and cached. +- **Health score** (`health_score.go`) is O(F) per dimension (F = file + count) and runs all dimensions in sequence; for very large projects + the per-file scans are the bottleneck. +- **Tree-sitter path** is not used. The "tree-sitter-style" scope-aware + extractor in `treesitter.go` is a pure-Go regex implementation that + avoids the CGO and binary dependencies of the real library. + +## Relationship to `internal/context/repomap` + +`internal/context/repomap` is a much narrower package - essentially just +`RepoMap(root, budget) (string, error)`. It is the prompt-injection shim +that hawk's context layer calls when it needs a budgeted overview for the +system prompt. It does its own AST parsing, PageRank pass, and rendering +and shares no code with this package beyond the name. + +Callers that need more than a budgeted text block (symbol-level +navigation, BM25 search, dead-code detection, OpenAPI export, etc.) +should import `internal/intelligence/repomap` (this package) directly. +See the comment at the top of `internal/context/repomap/repomap.go` for +the other side of the boundary. + +## See also + +- `doc.go` - go-doc compatible package overview. +- `doc_test.go` - worked example (calls `Generate` + `Format`). +- `internal/context/repomap/doc.go` - the shim's perspective. From 7133e83d1b6cd3f4e18c8a4924dd4b48dd7e7e81 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:48:14 +0530 Subject: [PATCH 6/9] docs(repomap): add worked example in doc_test.go Adds ExampleGenerate (a godoc-consumable worked example) and TestExampleGenerate_isRunnable (the actual validator for 'go test'). The example is callable but the output depends on a temp directory path that is not stable across runs, so the example function intentionally omits a '// Output:' comment. The test function is the source of truth. The example walks through the full primary use case: - create a tiny project under t.TempDir() with one Go and one Python file - call Generate with explicit Options - render the result with Format - assert the output is non-empty and contains the expected files and symbols The test is wired to the rest of the package's tests so 'go test ./internal/intelligence/repomap/...' exercises it alongside the existing test suite. --- internal/intelligence/repomap/doc_test.go | 108 ++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 internal/intelligence/repomap/doc_test.go diff --git a/internal/intelligence/repomap/doc_test.go b/internal/intelligence/repomap/doc_test.go new file mode 100644 index 00000000..2086909d --- /dev/null +++ b/internal/intelligence/repomap/doc_test.go @@ -0,0 +1,108 @@ +package repomap + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +// ExampleGenerate is a worked example for the repomap package: it builds a +// tiny project under a temp directory, calls Generate, and renders the +// resulting RepoMap with Format. The output is verified to be non-empty +// and to contain the expected file and symbol names. +// +// This example is consumed by `go doc` and `godoc` to illustrate the +// package's primary entry point. +func ExampleGenerate() { + dir, err := os.MkdirTemp("", "repomap-example-") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + // Two supported files: one Go, one Python. Both have a function + // and a type declaration so the example exercises the AST and + // regex paths. + if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main + +func main() {} + +type Server struct{} +`), 0o644); err != nil { + panic(err) + } + if err := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: + pass + +def run(): + pass +`), 0o644); err != nil { + panic(err) + } + + rm, err := Generate(dir, Options{MaxFiles: 100, MaxTokens: 5000}) + if err != nil { + panic(err) + } + + out := rm.Format(5000) + if out == "" { + panic("expected non-empty output from Format") + } +} + +// TestExampleGenerate_isRunnable mirrors ExampleGenerate with assertions so +// `go test` validates the example end-to-end. The example function above +// has no // Output: comment (the output depends on the temp directory +// path, which is not stable across runs), so this test is the actual +// validator; godoc still picks up ExampleGenerate for the docs page. +func TestExampleGenerate_isRunnable(t *testing.T) { + dir := t.TempDir() + + if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main + +func main() {} + +type Server struct{} +`), 0o644); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: + pass + +def run(): + pass +`), 0o644); err != nil { + t.Fatal(err) + } + + rm, err := Generate(dir, Options{MaxFiles: 100, MaxTokens: 5000}) + if err != nil { + t.Fatalf("Generate failed: %v", err) + } + if rm == nil { + t.Fatal("expected non-nil RepoMap") + } + if len(rm.Files) != 2 { + t.Fatalf("expected 2 file maps, got %d", len(rm.Files)) + } + + out := rm.Format(5000) + if out == "" { + t.Fatal("expected non-empty formatted output") + } + if !strings.Contains(out, "main.go") { + t.Errorf("expected main.go in output, got:\n%s", out) + } + if !strings.Contains(out, "app.py") { + t.Errorf("expected app.py in output, got:\n%s", out) + } + // The Go file should have a func main and a type Server. + if !strings.Contains(out, "main") { + t.Errorf("expected main symbol in output, got:\n%s", out) + } + if !strings.Contains(out, "Server") { + t.Errorf("expected Server symbol in output, got:\n%s", out) + } +} From 2a2730cc8b8c9288bf6cd7d4b2f308d3afda7333 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:53:25 +0530 Subject: [PATCH 7/9] fix(docs): drop 'Package repomap:' prefix from per-file comments (group 1) go doc treats a comment that begins with 'Package ' as a package-level doc comment, even when it lives in a non-doc.go file. The previous per-file leading comments all started with '// Package repomap: ...' which caused go doc to dump all 30+ file comments at the package level instead of showing the doc.go overview and the per-file comments in their proper place. The fix: replace the 'Package repomap: ' prefix with just '' so the comments are recognised as file-level doc comments by go doc and godoc. --- internal/intelligence/repomap/api_scanner.go | 2 +- internal/intelligence/repomap/cache.go | 2 +- internal/intelligence/repomap/callgraph.go | 2 +- internal/intelligence/repomap/changeset.go | 2 +- internal/intelligence/repomap/cochange.go | 2 +- internal/intelligence/repomap/complexity.go | 2 +- internal/intelligence/repomap/dead_code.go | 2 +- internal/intelligence/repomap/depgraph.go | 2 +- internal/intelligence/repomap/doclint.go | 2 +- internal/intelligence/repomap/file_grouper.go | 2 +- internal/intelligence/repomap/gitignore.go | 2 +- internal/intelligence/repomap/health_score.go | 2 +- internal/intelligence/repomap/hierarchy.go | 2 +- internal/intelligence/repomap/imports.go | 2 +- internal/intelligence/repomap/incremental.go | 2 +- internal/intelligence/repomap/incremental_map.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/intelligence/repomap/api_scanner.go b/internal/intelligence/repomap/api_scanner.go index 60a23dd0..1d7c54d5 100644 --- a/internal/intelligence/repomap/api_scanner.go +++ b/internal/intelligence/repomap/api_scanner.go @@ -1,4 +1,4 @@ -// Package repomap: api_scanner.go discovers HTTP endpoints in a project +// api_scanner.go discovers HTTP endpoints in a project // by detecting the framework (Chi, net/http, Gin, Echo, Gorilla mux, or // Fiber) and extracting route declarations into an APIMap. FormatAPIMap // renders the routes as text; GenerateOpenAPI produces a 3.x OpenAPI diff --git a/internal/intelligence/repomap/cache.go b/internal/intelligence/repomap/cache.go index c3f62775..8159e36f 100644 --- a/internal/intelligence/repomap/cache.go +++ b/internal/intelligence/repomap/cache.go @@ -1,4 +1,4 @@ -// Package repomap: cache.go implements the in-process LRU symbol cache keyed +// cache.go implements the in-process LRU symbol cache keyed // by (path, modtime). It is consulted by parseFileSymbols before re-parsing // and is cleared on process exit; for a persistent cache, use IncrementalMap. package repomap diff --git a/internal/intelligence/repomap/callgraph.go b/internal/intelligence/repomap/callgraph.go index 242ce28c..da8ee178 100644 --- a/internal/intelligence/repomap/callgraph.go +++ b/internal/intelligence/repomap/callgraph.go @@ -1,4 +1,4 @@ -// Package repomap: callgraph.go builds a per-function caller/callee graph +// callgraph.go builds a per-function caller/callee graph // from a Go tree using go/parser and go/ast. It supports bounded BFS // traversals in both directions (CallersOf, CalleesOf) and a symmetric // Neighborhood helper used by the navigation index. diff --git a/internal/intelligence/repomap/changeset.go b/internal/intelligence/repomap/changeset.go index 747ac461..d0ddb544 100644 --- a/internal/intelligence/repomap/changeset.go +++ b/internal/intelligence/repomap/changeset.go @@ -1,4 +1,4 @@ -// Package repomap: changeset.go derives a focused ChangeSetContext from +// changeset.go derives a focused ChangeSetContext from // a git diff (working tree or a range against a base ref). The context // lists changed files, files affected by the changes (dependents), and // files needed to understand the changes (imports), and is used to build diff --git a/internal/intelligence/repomap/cochange.go b/internal/intelligence/repomap/cochange.go index 7ec0c791..1282d38d 100644 --- a/internal/intelligence/repomap/cochange.go +++ b/internal/intelligence/repomap/cochange.go @@ -1,4 +1,4 @@ -// Package repomap: cochange.go mines the last N git commits to build a +// cochange.go mines the last N git commits to build a // co-occurrence matrix of files that change together, and exposes // RelatedFiles for "what else should I look at" recommendations after a // file has been touched. diff --git a/internal/intelligence/repomap/complexity.go b/internal/intelligence/repomap/complexity.go index b4022ba5..62788560 100644 --- a/internal/intelligence/repomap/complexity.go +++ b/internal/intelligence/repomap/complexity.go @@ -1,4 +1,4 @@ -// Package repomap: complexity.go computes cyclomatic and cognitive +// complexity.go computes cyclomatic and cognitive // complexity per function (Go files via go/ast, other languages via // brace-tracking regex), aggregates a ComplexityReport per file, and // surfaces refactoring suggestions and a MaintainabilityIndex for the diff --git a/internal/intelligence/repomap/dead_code.go b/internal/intelligence/repomap/dead_code.go index 94f6a8ed..397ce040 100644 --- a/internal/intelligence/repomap/dead_code.go +++ b/internal/intelligence/repomap/dead_code.go @@ -1,4 +1,4 @@ -// Package repomap: dead_code.go flags top-level declarations (functions, +// dead_code.go flags top-level declarations (functions, // methods, types, vars, consts) that appear to be unreferenced. It is // deliberately conservative: declarations reachable from tests, interface // implementations, or via reflection are not flagged. FormatDeadCode diff --git a/internal/intelligence/repomap/depgraph.go b/internal/intelligence/repomap/depgraph.go index 0bcf9310..790dcf4d 100644 --- a/internal/intelligence/repomap/depgraph.go +++ b/internal/intelligence/repomap/depgraph.go @@ -1,4 +1,4 @@ -// Package repomap: depgraph.go constructs a package-level dependency graph +// depgraph.go constructs a package-level dependency graph // for Go (via go.mod + go/parser ImportsOnly) and JavaScript/TypeScript // (via package.json + import/require regexes). It computes topological // order, layers, cycles, hot paths, and renders the result as DOT, diff --git a/internal/intelligence/repomap/doclint.go b/internal/intelligence/repomap/doclint.go index 0307953b..8296bdf1 100644 --- a/internal/intelligence/repomap/doclint.go +++ b/internal/intelligence/repomap/doclint.go @@ -1,4 +1,4 @@ -// Package repomap: doclint.go checks Go (and selectively other) source +// doclint.go checks Go (and selectively other) source // files for missing, outdated, incomplete, or unclear doc comments on // exported symbols, and produces a per-file DocLintResult with a score // and issue list. The result feeds the documentation-coverage dimension diff --git a/internal/intelligence/repomap/file_grouper.go b/internal/intelligence/repomap/file_grouper.go index 9fd211b4..5024432b 100644 --- a/internal/intelligence/repomap/file_grouper.go +++ b/internal/intelligence/repomap/file_grouper.go @@ -1,4 +1,4 @@ -// Package repomap: file_grouper.go identifies sets of files that should +// file_grouper.go identifies sets of files that should // be edited as a unit (Go packages, feature slices, layered modules, // test/source pairs, configuration groups). The resulting FileGroups are // used by the context builder to include whole groups in a single diff --git a/internal/intelligence/repomap/gitignore.go b/internal/intelligence/repomap/gitignore.go index f55eecf1..b241d72f 100644 --- a/internal/intelligence/repomap/gitignore.go +++ b/internal/intelligence/repomap/gitignore.go @@ -1,4 +1,4 @@ -// Package repomap: gitignore.go composes .gitignore rules from a project +// gitignore.go composes .gitignore rules from a project // root, walking parent directories so that nested gitignore files (and // the .git/info/exclude and global gitignore) all take effect. The resulting // GitignoreRules is consulted by the file walk in Generate. diff --git a/internal/intelligence/repomap/health_score.go b/internal/intelligence/repomap/health_score.go index 3c8ff656..1e2d35df 100644 --- a/internal/intelligence/repomap/health_score.go +++ b/internal/intelligence/repomap/health_score.go @@ -1,4 +1,4 @@ -// Package repomap: health_score.go rolls the individual signals +// health_score.go rolls the individual signals // (complexity, smells, dead code, doc coverage, ownership, duplication) // into a single weighted HealthScore with per-dimension breakdowns, // issue lists, and a letter grade. CompareScores produces a "before / diff --git a/internal/intelligence/repomap/hierarchy.go b/internal/intelligence/repomap/hierarchy.go index 3d131031..ebf60bed 100644 --- a/internal/intelligence/repomap/hierarchy.go +++ b/internal/intelligence/repomap/hierarchy.go @@ -1,4 +1,4 @@ -// Package repomap: hierarchy.go builds a three-level summary of a project +// hierarchy.go builds a three-level summary of a project // (project -> package -> file) by grouping scanned files into Go packages // and recording the exported symbols of each. It is consumed by the // summary generator to produce an LLM-friendly project overview. diff --git a/internal/intelligence/repomap/imports.go b/internal/intelligence/repomap/imports.go index 3925bd5b..3568153e 100644 --- a/internal/intelligence/repomap/imports.go +++ b/internal/intelligence/repomap/imports.go @@ -1,4 +1,4 @@ -// Package repomap: imports.go builds a file-level ImportGraph from a Go +// imports.go builds a file-level ImportGraph from a Go // project, mapping each file to its imports and reverse-mapping dependents. // The graph is the cheapest cross-file signal in the package and is used by // ChangeSetContext, PredictRelevantFiles, and the symbol reranker. diff --git a/internal/intelligence/repomap/incremental.go b/internal/intelligence/repomap/incremental.go index 94e4a208..598ffed4 100644 --- a/internal/intelligence/repomap/incremental.go +++ b/internal/intelligence/repomap/incremental.go @@ -1,4 +1,4 @@ -// Package repomap: incremental.go defines the CodeIndexer interface +// incremental.go defines the CodeIndexer interface // (the contract the repomap package uses to push code chunks to and // query code chunks from a downstream store such as the memory package's // YaadBridge) and IncrementalReindex, which diffs the project tree diff --git a/internal/intelligence/repomap/incremental_map.go b/internal/intelligence/repomap/incremental_map.go index 0a93880c..00c56a75 100644 --- a/internal/intelligence/repomap/incremental_map.go +++ b/internal/intelligence/repomap/incremental_map.go @@ -1,4 +1,4 @@ -// Package repomap: incremental_map.go is the persistent, on-disk symbol +// incremental_map.go is the persistent, on-disk symbol // cache. It stores per-file SHA-256 hashes and the corresponding symbol // lists in .hawk/repomap-cache.json (or a caller-provided directory). On // regeneration only files whose hash changed are re-parsed, and deleted From f6ffbe704d39c350cc8939ffe3fb7a090932aaaf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 17 Jun 2026 15:53:36 +0530 Subject: [PATCH 8/9] fix(docs): drop 'Package repomap:' prefix from per-file comments (group 2) Second batch of the same fix, covering the Search, Grouping, and remaining Symbols files. See the prior commit for context. --- internal/intelligence/repomap/interface_extract.go | 2 +- internal/intelligence/repomap/migration_detector.go | 2 +- internal/intelligence/repomap/navigation.go | 2 +- internal/intelligence/repomap/ownership.go | 2 +- internal/intelligence/repomap/pagerank.go | 2 +- internal/intelligence/repomap/parser.go | 2 +- internal/intelligence/repomap/parser_enhanced.go | 2 +- internal/intelligence/repomap/parser_langs.go | 2 +- internal/intelligence/repomap/patterns.go | 2 +- internal/intelligence/repomap/predict.go | 2 +- internal/intelligence/repomap/rerank.go | 2 +- internal/intelligence/repomap/semantic.go | 2 +- internal/intelligence/repomap/semantic_search.go | 2 +- internal/intelligence/repomap/shapley.go | 2 +- internal/intelligence/repomap/summary.go | 2 +- internal/intelligence/repomap/treesitter.go | 2 +- internal/intelligence/repomap/watcher.go | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/internal/intelligence/repomap/interface_extract.go b/internal/intelligence/repomap/interface_extract.go index 06296b91..1a3f966c 100644 --- a/internal/intelligence/repomap/interface_extract.go +++ b/internal/intelligence/repomap/interface_extract.go @@ -1,4 +1,4 @@ -// Package repomap: interface_extract.go returns just the exported API +// interface_extract.go returns just the exported API // surface of a Go file (function signatures, type declarations, constants) // with bodies stripped, for use in prompt contexts where body text is // unaffordable. The output is roughly an order of magnitude smaller than diff --git a/internal/intelligence/repomap/migration_detector.go b/internal/intelligence/repomap/migration_detector.go index e96bc065..c93d2559 100644 --- a/internal/intelligence/repomap/migration_detector.go +++ b/internal/intelligence/repomap/migration_detector.go @@ -1,4 +1,4 @@ -// Package repomap: migration_detector.go applies a set of MigrationRule +// migration_detector.go applies a set of MigrationRule // patterns to a project and reports MigrationOpportunities - patterns that // could be updated to a newer API, a more idiomatic construct, or a more // secure/performant alternative. AutoFix can rewrite selected patterns diff --git a/internal/intelligence/repomap/navigation.go b/internal/intelligence/repomap/navigation.go index cc0e0ce8..54102935 100644 --- a/internal/intelligence/repomap/navigation.go +++ b/internal/intelligence/repomap/navigation.go @@ -1,4 +1,4 @@ -// Package repomap: navigation.go implements an LSP-free "go to definition / +// navigation.go implements an LSP-free "go to definition / // find references / find implementations / find callers / find callees" // index for a Go project. The index is built in-memory from go/parser ASTs // and is consulted by the Hawk CLI's navigate subcommand. diff --git a/internal/intelligence/repomap/ownership.go b/internal/intelligence/repomap/ownership.go index c869e46a..8af988e3 100644 --- a/internal/intelligence/repomap/ownership.go +++ b/internal/intelligence/repomap/ownership.go @@ -1,4 +1,4 @@ -// Package repomap: ownership.go combines git history with CODEOWNERS-style +// ownership.go combines git history with CODEOWNERS-style // rules to compute per-file ownership: primary owner, contributors, // recency, and bus-factor risk. It is consumed by the health-score // dimension that flags orphaned files. diff --git a/internal/intelligence/repomap/pagerank.go b/internal/intelligence/repomap/pagerank.go index 4887a95c..cbb3153f 100644 --- a/internal/intelligence/repomap/pagerank.go +++ b/internal/intelligence/repomap/pagerank.go @@ -1,4 +1,4 @@ -// Package repomap: pagerank.go builds a per-symbol reference graph from a +// pagerank.go builds a per-symbol reference graph from a // project (file:symbol nodes with directed "is referenced by" edges) and // runs a damped PageRank iteration over it. BuildSymbolGraph accepts an // optional IncrementalMap so only changed files are re-processed on each diff --git a/internal/intelligence/repomap/parser.go b/internal/intelligence/repomap/parser.go index fa9c3411..f69db5a6 100644 --- a/internal/intelligence/repomap/parser.go +++ b/internal/intelligence/repomap/parser.go @@ -1,4 +1,4 @@ -// Package repomap: parser.go contains the original regex-based Go symbol +// parser.go contains the original regex-based Go symbol // extractor. It is retained as a fast, dependency-free path; new code should // prefer the AST-based EnhancedGoParser in parser_enhanced.go and the // tree-sitter-style extractor in treesitter.go. diff --git a/internal/intelligence/repomap/parser_enhanced.go b/internal/intelligence/repomap/parser_enhanced.go index 8d73594c..59b0f567 100644 --- a/internal/intelligence/repomap/parser_enhanced.go +++ b/internal/intelligence/repomap/parser_enhanced.go @@ -1,4 +1,4 @@ -// Package repomap: parser_enhanced.go wraps the standard-library go/parser +// parser_enhanced.go wraps the standard-library go/parser // and go/ast packages to extract symbols, methods, embedded types, and // interface satisfaction from Go source. It replaces the legacy regex path // for Go without requiring CGO or a tree-sitter binary. diff --git a/internal/intelligence/repomap/parser_langs.go b/internal/intelligence/repomap/parser_langs.go index 57740cd0..3318b6e7 100644 --- a/internal/intelligence/repomap/parser_langs.go +++ b/internal/intelligence/repomap/parser_langs.go @@ -1,4 +1,4 @@ -// Package repomap: parser_langs.go holds the regex-based symbol extractors +// parser_langs.go holds the regex-based symbol extractors // for every non-Go language the repomap knows about (C, C++, Java, C#, // PHP, Ruby, Kotlin, Swift, Scala, Lua, Dart, Elixir, Haskell, ...). Each // language has its own parseX function that the dispatcher in repomap.go diff --git a/internal/intelligence/repomap/patterns.go b/internal/intelligence/repomap/patterns.go index 22d3d2cc..9d1daec9 100644 --- a/internal/intelligence/repomap/patterns.go +++ b/internal/intelligence/repomap/patterns.go @@ -1,4 +1,4 @@ -// Package repomap: patterns.go loads a .hawk/repomap-patterns.json file +// patterns.go loads a .hawk/repomap-patterns.json file // (if present) describing which files to include or exclude from indexing, // and falls back to DefaultIndexPatterns otherwise. The result is consumed // by Generate, BuildSemanticIndex, and the watcher to skip unwanted trees. diff --git a/internal/intelligence/repomap/predict.go b/internal/intelligence/repomap/predict.go index 5af2f0cf..88261a5c 100644 --- a/internal/intelligence/repomap/predict.go +++ b/internal/intelligence/repomap/predict.go @@ -1,4 +1,4 @@ -// Package repomap: predict.go predicts which files in a project are most +// predict.go predicts which files in a project are most // likely to be relevant to the next edit, given the user's prompt, recent // edits (a RecentEditTracker), the import graph, and a symbol map. The // output is consumed by the change-set-aware context builder to populate diff --git a/internal/intelligence/repomap/rerank.go b/internal/intelligence/repomap/rerank.go index bbdc329c..57465183 100644 --- a/internal/intelligence/repomap/rerank.go +++ b/internal/intelligence/repomap/rerank.go @@ -1,4 +1,4 @@ -// Package repomap: rerank.go applies a BM25-over-BM25 reranking pass to a +// rerank.go applies a BM25-over-BM25 reranking pass to a // candidate set of code chunks. It is used after a faster but less precise // retrieval step (semantic similarity, PageRank, or import-graph proximity) // to surface the chunks that are most relevant to the query terms. diff --git a/internal/intelligence/repomap/semantic.go b/internal/intelligence/repomap/semantic.go index fd79509a..852bcbfc 100644 --- a/internal/intelligence/repomap/semantic.go +++ b/internal/intelligence/repomap/semantic.go @@ -1,4 +1,4 @@ -// Package repomap: semantic.go provides the lower-level chunked TF-IDF +// semantic.go provides the lower-level chunked TF-IDF // index used by the reranker. BuildSemanticIndex scans a directory, splits // source files into ~40-line CodeChunks, and stores the result on disk // (gob-encoded) for fast reload on subsequent sessions. diff --git a/internal/intelligence/repomap/semantic_search.go b/internal/intelligence/repomap/semantic_search.go index 5f74d880..f828163c 100644 --- a/internal/intelligence/repomap/semantic_search.go +++ b/internal/intelligence/repomap/semantic_search.go @@ -1,4 +1,4 @@ -// Package repomap: semantic_search.go is the BM25-ranked full-text search +// semantic_search.go is the BM25-ranked full-text search // engine over the Document set produced by the navigation index. It // tokenises queries, expands them with ExpandQuery, and returns SearchHit // results with snippet extraction. This is the search backend used by the diff --git a/internal/intelligence/repomap/shapley.go b/internal/intelligence/repomap/shapley.go index 656fda24..de89da11 100644 --- a/internal/intelligence/repomap/shapley.go +++ b/internal/intelligence/repomap/shapley.go @@ -1,4 +1,4 @@ -// Package repomap: shapley.go applies a Shapley-value-based ranking over +// shapley.go applies a Shapley-value-based ranking over // code chunks to score their marginal contribution to a task's context // set. It complements PageRank by accounting for redundancy across the // selected chunks, not just the in-graph centrality of each one. diff --git a/internal/intelligence/repomap/summary.go b/internal/intelligence/repomap/summary.go index 682f3f39..89653503 100644 --- a/internal/intelligence/repomap/summary.go +++ b/internal/intelligence/repomap/summary.go @@ -1,4 +1,4 @@ -// Package repomap: summary.go produces the LLM-facing CodebaseSummary: +// summary.go produces the LLM-facing CodebaseSummary: // a high-level description of the project, its packages, entry points, // key files, and inferred architecture. RenderForPrompt and RenderCompact // emit the summary in token-bounded forms suitable for injection at the diff --git a/internal/intelligence/repomap/treesitter.go b/internal/intelligence/repomap/treesitter.go index 140478e0..c6f2cdd0 100644 --- a/internal/intelligence/repomap/treesitter.go +++ b/internal/intelligence/repomap/treesitter.go @@ -1,4 +1,4 @@ -// Package repomap: treesitter.go is the "tree-sitter-inspired" scope-aware +// treesitter.go is the "tree-sitter-inspired" scope-aware // extractor. It uses go/ast for Go and a small scope-tracking regex engine // for other languages, returning the same shape of symbol list a real // tree-sitter parser would. ParseFileEnhanced and ParseSourceEnhanced are diff --git a/internal/intelligence/repomap/watcher.go b/internal/intelligence/repomap/watcher.go index 2afd8b60..46321520 100644 --- a/internal/intelligence/repomap/watcher.go +++ b/internal/intelligence/repomap/watcher.go @@ -1,4 +1,4 @@ -// Package repomap: watcher.go wraps fsnotify.Watcher to monitor a project +// watcher.go wraps fsnotify.Watcher to monitor a project // tree for file-system events and invoke a callback when a supported // source file changes. It is the runtime hook used to keep the in-memory // symbol index in sync with the working tree during a long-running session. From 4ff3182bb91cf140d96d34d7edf9fd2a4b0f3ab1 Mon Sep 17 00:00:00 2001 From: Lakshman Patel Date: Wed, 17 Jun 2026 17:57:44 +0530 Subject: [PATCH 9/9] fix(repomap): rename shadowed err in doc_test.go to writeErr (lint) --- internal/intelligence/repomap/doc_test.go | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/intelligence/repomap/doc_test.go b/internal/intelligence/repomap/doc_test.go index 2086909d..7bfb2521 100644 --- a/internal/intelligence/repomap/doc_test.go +++ b/internal/intelligence/repomap/doc_test.go @@ -24,21 +24,21 @@ func ExampleGenerate() { // Two supported files: one Go, one Python. Both have a function // and a type declaration so the example exercises the AST and // regex paths. - if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main + if writeErr := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main func main() {} type Server struct{} -`), 0o644); err != nil { - panic(err) +`), 0o644); writeErr != nil { + panic(writeErr) } - if err := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: + if writeErr := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: pass def run(): pass -`), 0o644); err != nil { - panic(err) +`), 0o644); writeErr != nil { + panic(writeErr) } rm, err := Generate(dir, Options{MaxFiles: 100, MaxTokens: 5000}) @@ -60,21 +60,21 @@ def run(): func TestExampleGenerate_isRunnable(t *testing.T) { dir := t.TempDir() - if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main + if writeErr := os.WriteFile(filepath.Join(dir, "main.go"), []byte(`package main func main() {} type Server struct{} -`), 0o644); err != nil { - t.Fatal(err) +`), 0o644); writeErr != nil { + t.Fatal(writeErr) } - if err := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: + if writeErr := os.WriteFile(filepath.Join(dir, "app.py"), []byte(`class App: pass def run(): pass -`), 0o644); err != nil { - t.Fatal(err) +`), 0o644); writeErr != nil { + t.Fatal(writeErr) } rm, err := Generate(dir, Options{MaxFiles: 100, MaxTokens: 5000})