feat(js): dependency-cruiser integration with stash+checkout diff#8
Merged
Conversation
…rocess Replace the closure-compiler/regex-based JsPlugin with a lazy batch subprocess pattern that spawns dependency-cruiser once for the entire source root, caches the JSON results, and serves subsequent file lookups from cache. This increases edge detection from 38 edges (0.078 ratio) to 627 edges (1.646 ratio) on real Vue projects, a 16x improvement. Key changes: - JsPlugin now uses dependency-cruiser via npx subprocess - Lazy batch: subprocess runs once on first parseFromContent() call - Filters node_modules, core modules (via coreModule flag), and builtins - Reports unresolved modules as blind spots - Protected runDependencyCruiser() for testability via subclass override - Node.js detection with actionable error message Deleted files (regex-based parser): - JsAstVisitor.java, VueFileExtractor.java, ModulePathResolver.java - ClosureCompilerValidationTest.java, ModulePathResolverTest.java Build changes: - Removed closure-compiler dependency - Added gson:2.10.1 for JSON parsing 28 tests passing, full build clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code review fixes: - Read stderr in separate thread to avoid blocking the 120s timeout - Close subprocess stdin immediately to prevent potential hangs - Add thread safety documentation to JsPlugin class - Add assertions to Windows path normalization test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and zero-arg mode - AgentOutputFormatter: compressed structured text output for AI agents, producing <=200 lines for a 500-node project with hotspots, cycles, domain coupling, and blind spots sections - --format agent flag on both AnalyzeCommand and DiffCommand with auto-detect when stdout is not a TTY (System.console() == null) - DiffCommand migrated to optional parameters (0-3 args): zero args compares working tree vs HEAD, one arg compares named ref vs working tree, two/three args retain existing behavior - CliGitAdapter.getWorkingTreeChanges() for staged + unstaged file listing - 12 new AgentOutputFormatter tests, 3 new CliGitAdapter tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent colored ANSI output from leaking into agent-format stream by computing all analysis data first, then checking format before printing any text output. Previously, cycles/hotspots/blindspots sections were printed in color before the agent format check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Suppress printStep() ANSI codes when console is null (agent/piped mode) - Remove CliGitAdapter cast, use interface method directly - Add --format field tests to AnalyzeCommandTest Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update command description to remove "Java" (it's multi-language) - Improve --json flag description for clarity - Add --languages flag to filter plugins by language (escape hatch) - Add file count breakdown by language before parsing - Add edge/node ratio warning for potentially incomplete analysis - Wrap plugin parsing in generic catch to preserve partial results when one plugin crashes - Add extensionLabel helper for human-readable language names - Add tests for languages flag, extensionLabel, partial result preservation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nore - DiffCommand.shortName() now handles JS/Vue path-style node IDs (src/components/Header.vue → Header.vue) not just Java FQCNs - Document that JsPlugin intentionally ignores content parameter since dependency-cruiser reads files from disk Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JsPlugin's lazy batch cache caused `archon diff` to produce zero diff for JS/TS files (base graph returned working-tree data from cache). Fix: when content is provided AND cache is populated (diff base graph via git show), parse the content directly with regex instead of using the dependency-cruiser cache. Includes Vue <script> section extraction. Also fixes from /review: - Empty cycle list guards in AgentOutputFormatter and DiffCommand - Stale step numbering removed from AnalyzeCommand Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ase workflow Add stashPush, stashPop, checkout, getCurrentBranch, and getHeadSha to enable stash+checkout approach for accurate JS/TS diff base graphs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Plugin Non-breaking SPI addition. Default returns false; JsPlugin overrides to true because dependency-cruiser must analyze an entire source root at once. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor buildBaseGraph() to partition changed files by plugin type: - Batch-parse plugins (JS/TS) use stash+checkout to get accurate base commit data via dependency-cruiser against the actual base working tree - Per-file plugins (Java/Python) continue using git show + parseFromContent - Fresh plugin instances are created for base parse to avoid stale cache - Crash recovery via .archon-restore.json lock file at startup - Fallback to per-file regex parsing if stash/checkout fails Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comprehensive tests covering the new diff infrastructure: - CliGitAdapter: getCurrentBranch, getHeadSha, stashPush, stashPop, checkout (8 new tests with real git repos using @tempdir) - DiffCommand: partitionChangedFiles logic, extractJsonString helper, lock file lifecycle (13 new tests via package-private visibility) - JsPlugin: supportsBatchParse returns true (1 new test) Make DiffCommand helper methods package-private for testability: partitionChangedFiles, extractJsonString, writeRestoreLockFile, deleteRestoreLockFile. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix printStep ANSI codes leaking in agent/piped mode - Move crash recovery lock file into .git/ (invisible to git status) - Write lock file once after stash (not before) for accurate stashRef - Preserve lock file on stashPop failure so user can recover manually - Specify UTF-8 charset when reading dependency-cruiser temp output - Pin dependency-cruiser to 17.3.10 for reproducible builds - Update lock file tests for new .git/ location Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Schr0d
added a commit
that referenced
this pull request
Apr 15, 2026
- Update AnalyzeCommand description to mention impact assessment - README/README-zh: remove view/impact/check/ecp references, update CLI to analyze+diff only, remove archon-viz from architecture, add v0.7 to roadmap, update blind spots (Spring DI now detected) - CHANGELOG: add v0.7.1.0 entry for SpringDIPostProcessor + command slash - skill.md/SKILL.md: replace view --format json with analyze --format agent, remove Spring DI from blind spots lists - TODOS: mark #4/#6/#8 DONE, mark #5/#7 OBSOLETE, update remaining items to reflect current state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Schr0d
added a commit
that referenced
this pull request
Apr 16, 2026
* feat(core): add SPRING_DI edge type to both EdgeType enums Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(spi): add postProcess() hook to LanguagePlugin for post-parse edge discovery Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(core): integrate postProcess hook into ParseOrchestrator with graph rebuild Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(java): add ArchUnit dependency and ClassDirectoryFinder for Maven/Gradle auto-detection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(java): SpringDIPostProcessor with ArchUnit bytecode scanning for Spring DI Uses ArchUnit ClassFileImporter to scan compiled .class files for Spring DI patterns: @Autowired fields, @resource fields, and constructor injection. Resolves interface types to concrete @Component/@Service/@repository implementations and reports ambiguous injections as blind spots. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(java): wire SpringDIPostProcessor into JavaPlugin.postProcess() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * legal: add THIRD-PARTY-NOTICES for ArchUnit Apache 2.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(java): support javax.annotation.Resource + add @Autowired constructor test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: bump version to 0.7.1.0 for SpringDIPostProcessor Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(cli): slash to analyze + diff only, merge impact into analyze --target Remove check, ecp, view commands. Impact analysis now via analyze --target. EcpGenerator stub removed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: sync all docs for v0.7.1.0 command consolidation + Spring DI - Update AnalyzeCommand description to mention impact assessment - README/README-zh: remove view/impact/check/ecp references, update CLI to analyze+diff only, remove archon-viz from architecture, add v0.7 to roadmap, update blind spots (Spring DI now detected) - CHANGELOG: add v0.7.1.0 entry for SpringDIPostProcessor + command slash - skill.md/SKILL.md: replace view --format json with analyze --format agent, remove Spring DI from blind spots lists - TODOS: mark #4/#6/#8 DONE, mark #5/#7 OBSOLETE, update remaining items to reflect current state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(cli): pipe buffer deadlock, ArchUnit log spam, and test coverage - Fix CliGitAdapter pipe buffer deadlock: drain output stream concurrently with waitFor() to prevent 60s hangs on large git show - Add logback.xml to suppress ArchUnit/Javaparser DEBUG logging - Cap unbounded module listing in analyze --target (max 20 shown) - Add 5 tests for resolveTarget/stripNamespacePrefix (replaced deleted ImpactCommandTest coverage) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update CHANGELOG with bug fixes for v0.7.1.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(viz): remove dead ViewCommand and visualization classes ViewCommand was removed from ArchonCli in the CLI consolidation but the class and its dependency tree were left behind. Removed: - ViewCommand, ViewCommandTest (dead CLI entry point) - TerminalRenderer, TerminalRendererTest (only used by ViewCommand) - PerspectiveBuilder, PerspectiveBuilderTest (unused visualization) - NodeGroup, NodeView, EdgeView, PerspectiveView (internal to above) Kept: JsonSerializer, DiffSerializer, ViewServer (used by analyze/diff) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(cli): --json output no longer mixed with text summary Moved --json output handling before agent format auto-detection so JSON output short-circuits cleanly instead of printing after the human-readable summary. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Core feature:
archon diffnow produces accurate JS/TS dependency changes by temporarily checking out the base commit and running dependency-cruiser against the real file tree.12 commits across 5 themes:
JS/TS Parser Rewrite
f4a8122)9a4646b)Agent Output & DX
AgentOutputFormatter,--format agentflag,DiffCommandzero-arg mode (07df8f0)f286501,5cca7a4)b0cbd13,04bd63f)Stash+Checkout Diff Pipeline
GitAdapter(7dbe3d1)supportsBatchParse()SPI method, override inJsPlugin(d149ac8)7abbb87)eaacae9)Review Fixes
d089bdd)Regex Fallback
0ee21ac)Pre-Landing Review
6 findings (0 critical, 6 informational), all fixed:
printStepANSI codes leak in agent mode → auto-fixed.git/stashPopfailure silently deletes lock file → preserves lock file@latestunpinned → pinned to 17.3.10Plan Completion
Plan file:
~/.claude/plans/abstract-moseying-lemon.mdAll 6 implementation steps completed + review fixes applied.
Documentation
4 files updated to match v0.7.0.0 changes:
--format agentand zero-arg diff, roadmap v0.6 checked/archon diffand/archon analyzedescriptions for zero-arg mode and--format agentTest plan
🤖 Generated with Claude Code