Skip to content

Commit 8a87c05

Browse files
authored
Merge pull request #70 from optave/feat/dogfood-suggestions
feat: implement dogfood report suggestions
2 parents 6f1e79e + 242066f commit 8a87c05

9 files changed

Lines changed: 182 additions & 69 deletions

File tree

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#!/bin/sh
12
npx --no -- commitlint --edit $1
23

34
# Append codegraph impact summary if available

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
#!/bin/sh
12
npm run lint
23
codegraph build 2>/dev/null || node src/cli.js build . 2>/dev/null || true

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#!/bin/sh
12
IMPACT=$(codegraph diff-impact origin/main --json -T 2>/dev/null || node src/cli.js diff-impact origin/main --json -T 2>/dev/null)
23
if [ -n "$IMPACT" ]; then
34
AFFECTED=$(echo "$IMPACT" | node -e "

generated/DOGFOOD-REPORT-2.1.0.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ All test directories show `cohesion=0.00`, which is technically correct (tests i
129129

130130
## 5. Suggestions for Improvement
131131

132-
### 5.1 UX: Default `--no-tests` in Config
132+
### 5.1 UX: Default `--no-tests` in Config — IMPLEMENTED
133133

134134
Many codebases have large test directories. A `.codegraphrc.json` option like `"excludeTests": true` would let users default to production-only views:
135135
```json
@@ -139,21 +139,29 @@ Many codebases have large test directories. A `.codegraphrc.json` option like `"
139139
```
140140
This would save typing `-T` on every command while still allowing `--include-tests` to override.
141141

142-
### 5.2 UX: `map` Could Show Coupling Score
142+
**Implementation:** Added `query.excludeTests` to config defaults (`config.js`). CLI loads config at startup and uses a `resolveNoTests()` helper: `--include-tests` flag always overrides to include, `-T` always excludes, otherwise falls back to config value. All commands with `--no-tests` now also accept `--include-tests`.
143+
144+
### 5.2 UX: `map` Could Show Coupling Score — IMPLEMENTED
143145

144146
The `map` command shows fan-in/fan-out bars, but doesn't show the actual coupling score (in+out combined). The `stats` command shows "Top 5 coupling hotspots" — `map` could integrate this as a column since it already has the data.
145147

146-
### 5.3 UX: `explain` Is the Most Useful Command for AI Workflows
148+
**Implementation:** Added `coupling` field (in+out) to `moduleMapData` and display as `=NNN` column in `map` output.
149+
150+
### 5.3 UX: `explain` Is the Most Useful Command for AI Workflows — IMPLEMENTED
147151

148152
The `explain` command produces the most AI-agent-friendly output — structured sections (exports, internals, data flow) that give an LLM exactly the context it needs. Consider:
149153
- Making it the default recommendation in the README for AI workflows
150154
- Adding a `--depth` option to recursively explain dependencies
151155

152-
### 5.4 Performance: Status Messages to stderr
156+
**Implementation:** Added `--depth <n>` option (default 0) to the `explain` command. When depth > 0 on a function target, recursively explains each callee's structure (callees, callers, signature, tests) up to N levels deep with cycle-safe visited tracking. Works with both text and JSON output.
157+
158+
### 5.4 Performance: Status Messages to stderr — IMPLEMENTED
153159

154160
The native engine still prints "Using native engine" to stdout, which pollutes piped output. Consider using `process.stderr.write` for status messages, keeping stdout clean for actual data output.
155161

156-
### 5.5 UX: `--no-tests` Help Text Consistency
162+
**Implementation:** Replaced all `console.log` status messages in `builder.js` with `info()` from the logger (which writes to stderr).
163+
164+
### 5.5 UX: `--no-tests` Help Text Consistency — ALREADY DONE
157165

158166
All commands now use `'Exclude test/spec files from results'` after this fix. Future commands should follow the same wording.
159167

@@ -163,7 +171,7 @@ All commands now use `'Exclude test/spec files from results'` after this fix. Fu
163171

164172
Codegraph v2.1.0 on Windows x64 with the native engine is **solid**. All 22 commands work correctly, edge cases are handled gracefully, the test suite is comprehensive (494 tests), and the native binary installs cleanly as an optional dependency.
165173

166-
The bugs found (missing `--no-tests` wiring on 6 CLI commands + 4 MCP tools, hook not catching `gh pr create`) are fixed in this PR. The engine parity gap is the most significant technical observation — worth tracking but not blocking since both engines produce usable graphs.
174+
The bugs found (missing `--no-tests` wiring on 6 CLI commands + 4 MCP tools, hook not catching `gh pr create`) are fixed in this PR. All 5 suggestions from section 5 have been implemented. The engine parity gap is the most significant technical observation — worth tracking but not blocking since both engines produce usable graphs.
167175

168-
**Rating: 9/10** — Production-ready with minor consistency issues.
176+
**Rating: 9/10** — Production-ready with minor consistency issues. All suggestions addressed.
169177

src/builder.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { loadConfig } from './config.js';
55
import { EXTENSIONS, IGNORE_DIRS, normalizePath } from './constants.js';
66
import { initSchema, openDb } from './db.js';
77
import { readJournal, writeJournalHeader } from './journal.js';
8-
import { debug, warn } from './logger.js';
8+
import { debug, info, warn } from './logger.js';
99
import { getActiveEngine, parseFilesAuto } from './parser.js';
1010
import { computeConfidence, resolveImportPath, resolveImportsBatch } from './resolve.js';
1111

@@ -344,7 +344,7 @@ export async function buildGraph(rootDir, opts = {}) {
344344
// Engine selection: 'native', 'wasm', or 'auto' (default)
345345
const engineOpts = { engine: opts.engine || 'auto' };
346346
const { name: engineName, version: engineVersion } = getActiveEngine(engineOpts);
347-
console.log(`Using ${engineName} engine${engineVersion ? ` (v${engineVersion})` : ''}`);
347+
info(`Using ${engineName} engine${engineVersion ? ` (v${engineVersion})` : ''}`);
348348

349349
const aliases = loadPathAliases(rootDir);
350350
// Merge config aliases
@@ -357,15 +357,15 @@ export async function buildGraph(rootDir, opts = {}) {
357357
}
358358

359359
if (aliases.baseUrl || Object.keys(aliases.paths).length > 0) {
360-
console.log(
360+
info(
361361
`Loaded path aliases: baseUrl=${aliases.baseUrl || 'none'}, ${Object.keys(aliases.paths).length} path mappings`,
362362
);
363363
}
364364

365365
const collected = collectFiles(rootDir, [], config, new Set());
366366
const files = collected.files;
367367
const discoveredDirs = collected.directories;
368-
console.log(`Found ${files.length} files to parse`);
368+
info(`Found ${files.length} files to parse`);
369369

370370
// Check for incremental build
371371
const { changed, removed, isFullBuild } = incremental
@@ -396,7 +396,7 @@ export async function buildGraph(rootDir, opts = {}) {
396396
/* ignore heal errors */
397397
}
398398
}
399-
console.log('No changes detected. Graph is up to date.');
399+
info('No changes detected. Graph is up to date.');
400400
db.close();
401401
writeJournalHeader(rootDir, Date.now());
402402
return;
@@ -407,7 +407,7 @@ export async function buildGraph(rootDir, opts = {}) {
407407
'PRAGMA foreign_keys = OFF; DELETE FROM node_metrics; DELETE FROM edges; DELETE FROM nodes; PRAGMA foreign_keys = ON;',
408408
);
409409
} else {
410-
console.log(`Incremental: ${parseChanges.length} changed, ${removed.length} removed`);
410+
info(`Incremental: ${parseChanges.length} changed, ${removed.length} removed`);
411411
// Remove metrics/edges/nodes for changed and removed files
412412
const deleteNodesForFile = db.prepare('DELETE FROM nodes WHERE file = ?');
413413
const deleteEdgesForFile = db.prepare(`
@@ -527,7 +527,7 @@ export async function buildGraph(rootDir, opts = {}) {
527527

528528
const parsed = allSymbols.size;
529529
const skipped = filesToParse.length - parsed;
530-
console.log(`Parsed ${parsed} files (${skipped} skipped)`);
530+
info(`Parsed ${parsed} files (${skipped} skipped)`);
531531

532532
// Clean up removed file hashes
533533
if (upsertHash && removed.length > 0) {
@@ -821,8 +821,8 @@ export async function buildGraph(rootDir, opts = {}) {
821821
}
822822

823823
const nodeCount = db.prepare('SELECT COUNT(*) as c FROM nodes').get().c;
824-
console.log(`Graph built: ${nodeCount} nodes, ${edgeCount} edges`);
825-
console.log(`Stored in ${dbPath}`);
824+
info(`Graph built: ${nodeCount} nodes, ${edgeCount} edges`);
825+
info(`Stored in ${dbPath}`);
826826
db.close();
827827

828828
// Write journal header after successful build

0 commit comments

Comments
 (0)