spec-gen-cli 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +197 -11
  2. package/dist/api/generate.d.ts.map +1 -1
  3. package/dist/api/generate.js +5 -4
  4. package/dist/api/generate.js.map +1 -1
  5. package/dist/cli/commands/analyze.d.ts.map +1 -1
  6. package/dist/cli/commands/analyze.js +101 -41
  7. package/dist/cli/commands/analyze.js.map +1 -1
  8. package/dist/cli/commands/generate.d.ts.map +1 -1
  9. package/dist/cli/commands/generate.js +25 -21
  10. package/dist/cli/commands/generate.js.map +1 -1
  11. package/dist/cli/commands/mcp.d.ts +353 -10
  12. package/dist/cli/commands/mcp.d.ts.map +1 -1
  13. package/dist/cli/commands/mcp.js +236 -45
  14. package/dist/cli/commands/mcp.js.map +1 -1
  15. package/dist/cli/commands/view.d.ts.map +1 -1
  16. package/dist/cli/commands/view.js +33 -4
  17. package/dist/cli/commands/view.js.map +1 -1
  18. package/dist/constants.d.ts +10 -0
  19. package/dist/constants.d.ts.map +1 -1
  20. package/dist/constants.js +10 -0
  21. package/dist/constants.js.map +1 -1
  22. package/dist/core/analyzer/ast-chunker.d.ts +24 -0
  23. package/dist/core/analyzer/ast-chunker.d.ts.map +1 -0
  24. package/dist/core/analyzer/ast-chunker.js +198 -0
  25. package/dist/core/analyzer/ast-chunker.js.map +1 -0
  26. package/dist/core/analyzer/call-graph.d.ts +51 -4
  27. package/dist/core/analyzer/call-graph.d.ts.map +1 -1
  28. package/dist/core/analyzer/call-graph.js +634 -44
  29. package/dist/core/analyzer/call-graph.js.map +1 -1
  30. package/dist/core/analyzer/code-shaper.d.ts.map +1 -1
  31. package/dist/core/analyzer/code-shaper.js +5 -0
  32. package/dist/core/analyzer/code-shaper.js.map +1 -1
  33. package/dist/core/analyzer/codebase-digest.d.ts +40 -0
  34. package/dist/core/analyzer/codebase-digest.d.ts.map +1 -0
  35. package/dist/core/analyzer/codebase-digest.js +194 -0
  36. package/dist/core/analyzer/codebase-digest.js.map +1 -0
  37. package/dist/core/analyzer/cpp-header-resolver.d.ts +30 -0
  38. package/dist/core/analyzer/cpp-header-resolver.d.ts.map +1 -0
  39. package/dist/core/analyzer/cpp-header-resolver.js +71 -0
  40. package/dist/core/analyzer/cpp-header-resolver.js.map +1 -0
  41. package/dist/core/analyzer/function-registry-trie.d.ts +21 -0
  42. package/dist/core/analyzer/function-registry-trie.d.ts.map +1 -0
  43. package/dist/core/analyzer/function-registry-trie.js +39 -0
  44. package/dist/core/analyzer/function-registry-trie.js.map +1 -0
  45. package/dist/core/analyzer/import-resolver-bridge.d.ts +25 -0
  46. package/dist/core/analyzer/import-resolver-bridge.d.ts.map +1 -0
  47. package/dist/core/analyzer/import-resolver-bridge.js +99 -0
  48. package/dist/core/analyzer/import-resolver-bridge.js.map +1 -0
  49. package/dist/core/analyzer/signature-extractor.d.ts.map +1 -1
  50. package/dist/core/analyzer/signature-extractor.js +72 -3
  51. package/dist/core/analyzer/signature-extractor.js.map +1 -1
  52. package/dist/core/analyzer/subgraph-extractor.d.ts +10 -2
  53. package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -1
  54. package/dist/core/analyzer/subgraph-extractor.js +25 -7
  55. package/dist/core/analyzer/subgraph-extractor.js.map +1 -1
  56. package/dist/core/analyzer/type-inference-engine.d.ts +23 -0
  57. package/dist/core/analyzer/type-inference-engine.d.ts.map +1 -0
  58. package/dist/core/analyzer/type-inference-engine.js +130 -0
  59. package/dist/core/analyzer/type-inference-engine.js.map +1 -0
  60. package/dist/core/analyzer/vector-index.d.ts +35 -6
  61. package/dist/core/analyzer/vector-index.d.ts.map +1 -1
  62. package/dist/core/analyzer/vector-index.js +308 -54
  63. package/dist/core/analyzer/vector-index.js.map +1 -1
  64. package/dist/core/generator/schemas.d.ts +365 -0
  65. package/dist/core/generator/schemas.d.ts.map +1 -0
  66. package/dist/core/generator/schemas.js +190 -0
  67. package/dist/core/generator/schemas.js.map +1 -0
  68. package/dist/core/generator/spec-pipeline.d.ts +31 -11
  69. package/dist/core/generator/spec-pipeline.d.ts.map +1 -1
  70. package/dist/core/generator/spec-pipeline.js +172 -40
  71. package/dist/core/generator/spec-pipeline.js.map +1 -1
  72. package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -1
  73. package/dist/core/generator/stages/stage2-entities.js +4 -2
  74. package/dist/core/generator/stages/stage2-entities.js.map +1 -1
  75. package/dist/core/generator/stages/stage3-services.d.ts.map +1 -1
  76. package/dist/core/generator/stages/stage3-services.js +4 -2
  77. package/dist/core/generator/stages/stage3-services.js.map +1 -1
  78. package/dist/core/generator/stages/stage4-api.d.ts.map +1 -1
  79. package/dist/core/generator/stages/stage4-api.js +4 -2
  80. package/dist/core/generator/stages/stage4-api.js.map +1 -1
  81. package/dist/core/generator/stages/stage5-architecture.d.ts +2 -1
  82. package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -1
  83. package/dist/core/generator/stages/stage5-architecture.js +15 -3
  84. package/dist/core/generator/stages/stage5-architecture.js.map +1 -1
  85. package/dist/core/generator/stages/stage6-adr.d.ts.map +1 -1
  86. package/dist/core/generator/stages/stage6-adr.js +2 -1
  87. package/dist/core/generator/stages/stage6-adr.js.map +1 -1
  88. package/dist/core/services/chat-agent.d.ts +5 -0
  89. package/dist/core/services/chat-agent.d.ts.map +1 -1
  90. package/dist/core/services/chat-agent.js +14 -0
  91. package/dist/core/services/chat-agent.js.map +1 -1
  92. package/dist/core/services/chat-tools.d.ts.map +1 -1
  93. package/dist/core/services/chat-tools.js +172 -50
  94. package/dist/core/services/chat-tools.js.map +1 -1
  95. package/dist/core/services/llm-service.d.ts +2 -0
  96. package/dist/core/services/llm-service.d.ts.map +1 -1
  97. package/dist/core/services/llm-service.js +47 -5
  98. package/dist/core/services/llm-service.js.map +1 -1
  99. package/dist/core/services/mcp-handlers/analysis.d.ts +12 -0
  100. package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -1
  101. package/dist/core/services/mcp-handlers/analysis.js +138 -2
  102. package/dist/core/services/mcp-handlers/analysis.js.map +1 -1
  103. package/dist/core/services/mcp-handlers/graph.d.ts +21 -1
  104. package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -1
  105. package/dist/core/services/mcp-handlers/graph.js +142 -2
  106. package/dist/core/services/mcp-handlers/graph.js.map +1 -1
  107. package/dist/core/services/mcp-handlers/orient.d.ts +17 -0
  108. package/dist/core/services/mcp-handlers/orient.d.ts.map +1 -0
  109. package/dist/core/services/mcp-handlers/orient.js +200 -0
  110. package/dist/core/services/mcp-handlers/orient.js.map +1 -0
  111. package/dist/core/services/mcp-handlers/semantic.d.ts +18 -4
  112. package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
  113. package/dist/core/services/mcp-handlers/semantic.js +161 -17
  114. package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
  115. package/dist/core/services/mcp-handlers/utils.d.ts +43 -0
  116. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
  117. package/dist/core/services/mcp-handlers/utils.js +66 -1
  118. package/dist/core/services/mcp-handlers/utils.js.map +1 -1
  119. package/dist/core/services/mcp-watcher.d.ts +41 -0
  120. package/dist/core/services/mcp-watcher.d.ts.map +1 -0
  121. package/dist/core/services/mcp-watcher.js +177 -0
  122. package/dist/core/services/mcp-watcher.js.map +1 -0
  123. package/dist/types/index.d.ts +1 -1
  124. package/dist/types/index.d.ts.map +1 -1
  125. package/dist/types/pipeline.d.ts +7 -0
  126. package/dist/types/pipeline.d.ts.map +1 -1
  127. package/package.json +3 -2
  128. package/src/viewer/InteractiveGraphViewer.jsx +33 -8
  129. package/src/viewer/components/ChatPanel.jsx +8 -5
  130. package/src/viewer/components/ClassGraph.jsx +699 -0
  131. package/src/viewer/utils/graph-helpers.js +1 -1
  132. package/src/viewer/utils/themes.js +36 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@ Reverse-engineer [OpenSpec](https://github.com/Fission-AI/OpenSpec) specificatio
6
6
 
7
7
  Most software has no specification. The code is the spec, scattered across thousands of files, tribal knowledge, and stale documentation. Tools like `openspec init` create empty scaffolding, but someone still has to write everything. By the time specs are written manually, the code has already changed.
8
8
 
9
- spec-gen automates this. It analyzes your codebase through static analysis, generates structured specifications using an LLM, and continuously detects when code and specs fall out of sync.
9
+ spec-gen automates this. It analyzes your codebase through static analysis, generates structured specifications using an LLM, and continuously detects when code and specs fall out of sync. It also exposes the analysis as an MCP server so AI agents can navigate your codebase with GraphRAG-style retrieval — semantic search combined with call-graph expansion and spec-linked peer discovery.
10
10
 
11
11
  ## Quick Start
12
12
 
@@ -492,7 +492,7 @@ spec-gen analyze [options]
492
492
  --include <glob> # Additional include patterns
493
493
  --exclude <glob> # Additional exclude patterns
494
494
  --force # Force re-analysis (bypass 1-hour cache)
495
- --embed # Build semantic vector index after analysis (requires embedding config)
495
+ --no-embed # Skip building the semantic vector index (index is built by default when embedding is configured)
496
496
  --reindex-specs # Re-index OpenSpec specs into the vector index without re-running full analysis
497
497
  ```
498
498
 
@@ -531,6 +531,95 @@ Checks performed:
531
531
 
532
532
  Run `spec-gen doctor` whenever setup instructions aren't working — it tells you exactly what to fix and how.
533
533
 
534
+ ## Agent Setup
535
+
536
+ ### Passive context vs active tools
537
+
538
+ Agents have two ways to acquire knowledge about your codebase:
539
+
540
+ - **Passive (zero friction):** files referenced in `CLAUDE.md` / `.clinerules` are read automatically at session start, before the agent even processes your first message. No decision required, no tool call to make.
541
+ - **Active (friction):** MCP tools must be consciously selected from a list, called, and their output integrated into context. Even when the information would help, agents often skip this step and read files directly instead — it's always the safe fallback.
542
+
543
+ This means architectural context delivered passively is far more reliably absorbed than context behind a tool call. `spec-gen analyze` generates `.spec-gen/analysis/CODEBASE.md` specifically for this purpose: a compact, agent-optimized digest (~100 lines) that agents absorb at session start without any decision cost.
544
+
545
+ ### What CODEBASE.md contains
546
+
547
+ Generated from the static analysis artifacts, it surfaces what an agent most needs before touching code:
548
+
549
+ - **Entry points** — functions with no internal callers (where execution starts)
550
+ - **Critical hubs** — highest fan-in functions (most risky to modify)
551
+ - **Spec domains** — which `openspec/specs/` domains exist and what they cover
552
+ - **Most coupled files** — high in-degree in the dependency graph (touch with care)
553
+ - **God functions / oversized orchestrators** — complexity hotspots
554
+ - **Layer violations** — if any
555
+
556
+ This is structural signal, not prose. It complements `openspec/specs/overview/spec.md`, which provides the functional view (what the system does, what domains exist). Together they give agents both the architectural topology and the business intent.
557
+
558
+ ### Setup
559
+
560
+ After running `spec-gen analyze`, wire the generated digest into your agent's context:
561
+
562
+ **Claude Code** — add to `CLAUDE.md`:
563
+
564
+ ```markdown
565
+ @.spec-gen/analysis/CODEBASE.md
566
+ @openspec/specs/overview/spec.md
567
+
568
+ ## spec-gen MCP tools — when to use them
569
+
570
+ | Situation | Tool |
571
+ |-----------|------|
572
+ | Starting any new task | `orient` — returns functions, files, specs, call paths, and insertion points in one call |
573
+ | Don't know which file/function handles a concept | `search_code` |
574
+ | Need call topology across many files | `get_subgraph` / `analyze_impact` |
575
+ | Planning where to add a feature | `suggest_insertion_points` |
576
+ | Reading a spec before writing code | `get_spec` |
577
+ | Checking if code still matches spec | `check_spec_drift` |
578
+ | Finding spec requirements by meaning | `search_specs` |
579
+
580
+ For all other cases (reading a file, grepping, listing files) use native tools directly.
581
+ ```
582
+
583
+ **Cline / Roo Code / Kilocode** — create `.clinerules/spec-gen.md`:
584
+
585
+ ```markdown
586
+ # spec-gen
587
+
588
+ spec-gen provides static analysis artifacts and MCP tools to help you navigate this codebase.
589
+ Always use these before writing or modifying code.
590
+
591
+ ## Before starting any task
592
+
593
+ - Read `.spec-gen/analysis/CODEBASE.md` — architectural digest: entry points, critical hubs,
594
+ god functions, most-coupled files, and available spec domains. Generated locally by `spec-gen analyze`.
595
+ - Read `openspec/specs/overview/spec.md` — functional domain map: what the system does,
596
+ which domains exist, data-flow requirements.
597
+
598
+ ## MCP tools — use these instead of grep/read when exploring
599
+
600
+ - **Orient first**: call `orient` at the start of every task — it returns relevant functions,
601
+ files, specs, call paths, and insertion points in one shot.
602
+ - **Finding code**: use `search_code` when you don't know which file or function handles a concept.
603
+ - **Call topology**: use `get_subgraph` or `analyze_impact` when you need to understand
604
+ how calls flow across multiple files (not just a single file).
605
+ - **Adding a feature**: call `suggest_insertion_points` before deciding where to add code —
606
+ it accounts for the dependency graph, not just filenames.
607
+ - **Reading specs**: call `get_spec <domain>` before writing code in that domain;
608
+ use `search_specs` to find requirements by meaning when you don't know the domain name.
609
+ - **Checking drift**: call `check_spec_drift` after modifying a file to verify it still
610
+ matches its spec — do not skip this step before opening a PR.
611
+
612
+ Use native tools (Read, Grep, Glob) only for cases not covered above.
613
+ ```
614
+
615
+ `CODEBASE.md` gives the agent passive architectural context. `overview/spec.md` gives the functional domain map. The table tells it when the passive context isn't enough and an active MCP tool call is warranted.
616
+
617
+ > **Tip:** `spec-gen analyze` prints these snippets after every run as a reminder.
618
+
619
+ > **Note:** `.spec-gen/analysis/` is git-ignored — each developer generates it locally. Re-run `spec-gen analyze` after significant structural changes to keep the digest current.
620
+
621
+ ---
622
+
534
623
  ## MCP Server
535
624
 
536
625
  `spec-gen mcp` starts spec-gen as a [Model Context Protocol](https://modelcontextprotocol.io/) server over stdio, exposing static analysis as tools that any MCP-compatible AI agent (Cline, Roo Code, Kilocode, Claude Code, Cursor...) can call directly -- no API key required.
@@ -565,6 +654,31 @@ or for local development:
565
654
 
566
655
  **Cline / Roo Code / Kilocode** -- add the same block under `mcpServers` in the MCP settings JSON of your editor.
567
656
 
657
+ ### Watch mode (keep search_code and orient fresh)
658
+
659
+ By default the MCP server reads `llm-context.json` from the last `analyze` run. With `--watch-auto`, it also watches source files for changes and incrementally re-indexes signatures so `search_code` and `orient` reflect your latest edits without waiting for the next commit.
660
+
661
+ Add `--watch-auto` to your MCP config args:
662
+
663
+ ```json
664
+ {
665
+ "mcpServers": {
666
+ "spec-gen": {
667
+ "command": "spec-gen",
668
+ "args": ["mcp", "--watch-auto"]
669
+ }
670
+ }
671
+ }
672
+ ```
673
+
674
+ The watcher starts automatically on the first tool call — no hardcoded path needed. It re-extracts signatures for any changed source file and patches `llm-context.json` within ~500 ms of a save. If an embedding server is reachable, it also re-embeds changed functions into the vector index automatically. The call graph is not rebuilt on every change; it stays current via the [post-commit hook](#cicd-integration) (`spec-gen analyze --force`).
675
+
676
+ | Option | Default | Description |
677
+ |---|---|---|
678
+ | `--watch-auto` | off | Auto-detect project root from first tool call |
679
+ | `--watch <dir>` | — | Watch a fixed directory (alternative to `--watch-auto`) |
680
+ | `--watch-debounce <ms>` | 400 | Delay before re-indexing after a file change |
681
+
568
682
  ### Cline / Roo Code / Kilocode
569
683
 
570
684
  For editors with MCP support, after adding the `mcpServers` block to your settings, download the slash command workflows:
@@ -640,23 +754,36 @@ All tools run on **pure static analysis** -- no LLM quota consumed.
640
754
 
641
755
  | Tool | Description | Requires prior analysis |
642
756
  |------|-------------|:---:|
757
+ | `orient` | **Single entry point for any new task.** Given a natural-language task description, returns in one call: relevant functions, source files, spec domains, call neighbourhoods, insertion-point candidates, and matching spec sections. Start here. | Yes (+ embedding) |
643
758
  | `get_subgraph` | Depth-limited subgraph centred on a function. Direction: `downstream` (what it calls), `upstream` (who calls it), or `both`. Output as JSON or Mermaid diagram. | Yes |
644
759
  | `get_architecture_overview` | High-level cluster map: roles (entry layer, orchestrator, core utilities, API layer, internal), inter-cluster dependencies, global entry points, and critical hubs. No LLM required. | Yes |
645
760
  | `get_function_skeleton` | Noise-stripped view of a source file: logs, inline comments, and non-JSDoc block comments removed. Signatures, control flow, return/throw, and call expressions preserved. Returns reduction %. | No |
646
- | `suggest_insertion_points` | Semantic search over the vector index to find the best existing functions to extend or hook into when implementing a new feature. Returns ranked candidates with role and strategy. | Yes (+ `--embed`) |
647
- | `search_code` | Natural-language semantic search over indexed functions. Returns the closest matches by meaning with similarity score. Useful for navigating unfamiliar codebases. | Yes (+ `--embed`) |
761
+ | `get_function_body` | Return the exact source code of a named function in a file. | No |
762
+ | `get_file_dependencies` | Return the file-level import dependencies for a given source file (imports, imported-by, or both). | Yes |
763
+ | `trace_execution_path` | Find all call-graph paths between two functions (DFS, configurable depth/max-paths). Use this when debugging: "how does request X reach function Y?" Returns shortest path, all paths sorted by hops, and a step-by-step chain per path. | Yes |
764
+ | `suggest_insertion_points` | Semantic search over the vector index to find the best existing functions to extend or hook into when implementing a new feature. Returns ranked candidates with role and strategy. Falls back to BM25 keyword search when no embedding server is configured. | Yes (+ embedding) |
765
+ | `search_code` | Natural-language semantic search over indexed functions. Returns the closest matches by meaning with similarity score, call-graph neighbourhood enrichment, and spec-linked peer functions. Falls back to BM25 keyword search when no embedding server is configured. | Yes (+ embedding) |
648
766
 
649
767
  **Specs**
650
768
 
651
769
  | Tool | Description | Requires prior analysis |
652
770
  |------|-------------|:---:|
771
+ | `get_spec` | Read the full content of an OpenSpec domain spec by domain name. | Yes (generate) |
653
772
  | `get_mapping` | Requirement->function mapping produced by `spec-gen generate`. Shows which functions implement which spec requirements, confidence level, and orphan functions with no spec coverage. | Yes (generate) |
773
+ | `get_decisions` | List or search Architecture Decision Records (ADRs) stored in `openspec/decisions/`. Optional keyword query. | Yes (generate) |
654
774
  | `check_spec_drift` | Detect code changes not reflected in OpenSpec specs. Compares git-changed files against spec coverage maps. Issues: gap / stale / uncovered / orphaned-spec / adr-gap. | Yes (generate) |
655
- | `search_specs` | Semantic search over OpenSpec specifications to find requirements, design notes, and architecture decisions by meaning. Returns linked source files for graph highlighting. Use this when asked "which spec covers X?" or "where should we implement Z?". Requires a spec index built with `spec-gen analyze --embed` or `--reindex-specs`. | Yes (generate) |
775
+ | `search_specs` | Semantic search over OpenSpec specifications to find requirements, design notes, and architecture decisions by meaning. Returns linked source files for graph highlighting. Use this when asked "which spec covers X?" or "where should we implement Z?". Requires a spec index built with `spec-gen analyze` or `--reindex-specs`. | Yes (generate) |
656
776
  | `list_spec_domains` | List all OpenSpec domains available in this project. Use this to discover what domains exist before doing a targeted `search_specs` call. | Yes (generate) |
657
777
 
658
778
  ### Parameters
659
779
 
780
+ **`orient`**
781
+ ```
782
+ directory string Absolute path to the project directory
783
+ task string Natural-language description of the task, e.g. "add rate limiting to the API"
784
+ limit number Max relevant functions to return (default: 5, max: 20)
785
+ ```
786
+
660
787
  **`analyze_codebase`**
661
788
  ```
662
789
  directory string Absolute path to the project directory
@@ -754,6 +881,41 @@ directory string Absolute path to the project directory
754
881
  filePath string Path to the file, relative to the project directory
755
882
  ```
756
883
 
884
+ **`get_function_body`**
885
+ ```
886
+ directory string Absolute path to the project directory
887
+ filePath string Path to the file, relative to the project directory
888
+ functionName string Name of the function to extract
889
+ ```
890
+
891
+ **`get_file_dependencies`**
892
+ ```
893
+ directory string Absolute path to the project directory
894
+ filePath string Path to the file, relative to the project directory
895
+ direction string "imports" | "importedBy" | "both" (default: "both")
896
+ ```
897
+
898
+ **`trace_execution_path`**
899
+ ```
900
+ directory string Absolute path to the project directory
901
+ entryFunction string Name of the starting function (case-insensitive partial match)
902
+ targetFunction string Name of the target function (case-insensitive partial match)
903
+ maxDepth number Maximum path length in hops (default: 6)
904
+ maxPaths number Maximum number of paths to return (default: 10, max: 50)
905
+ ```
906
+
907
+ **`get_decisions`**
908
+ ```
909
+ directory string Absolute path to the project directory
910
+ query string Optional keyword to filter ADRs by title or content
911
+ ```
912
+
913
+ **`get_spec`**
914
+ ```
915
+ directory string Absolute path to the project directory
916
+ domain string Domain name (e.g. "auth", "user", "api")
917
+ ```
918
+
757
919
  **`get_god_functions`**
758
920
  ```
759
921
  directory string Absolute path to the project directory
@@ -813,6 +975,20 @@ section string Filter by section type: "requirements" | "purpose" | "design
813
975
  2. get_mapping({ directory, orphansOnly: true }) # functions with no spec coverage
814
976
  ```
815
977
 
978
+ **Scenario D -- Starting a new task (fastest orientation)**
979
+ ```
980
+ 1. orient({ directory, task: "add rate limiting to the API" })
981
+ # Returns in one call:
982
+ # - relevant functions (semantic search or BM25 fallback)
983
+ # - source files and spec domains that cover them
984
+ # - call-graph neighbourhood for each top function
985
+ # - best insertion-point candidates
986
+ # - spec-linked peer functions (cross-graph traversal)
987
+ # - matching spec sections
988
+ 2. get_spec({ directory, domain: "..." }) # read full spec before writing code
989
+ 3. check_spec_drift({ directory }) # verify after implementation
990
+ ```
991
+
816
992
  ## Interactive Graph Viewer
817
993
 
818
994
  `spec-gen view` launches a local React app that visualises your codebase analysis and lets you explore spec requirements side-by-side with the dependency graph.
@@ -936,9 +1112,19 @@ Static analysis output is stored in `.spec-gen/analysis/`:
936
1112
 
937
1113
  `spec-gen analyze` also writes **`ARCHITECTURE.md`** to your project root -- a Markdown overview of module clusters, entry points, and critical hubs, refreshed on every run.
938
1114
 
939
- ## Semantic Search
1115
+ ## Semantic Search & GraphRAG
940
1116
 
941
- `spec-gen analyze --embed` builds a vector index over all functions in the call graph, enabling natural-language search via the `search_code` and `suggest_insertion_points` MCP tools, and the search bar in the viewer.
1117
+ `spec-gen analyze` builds a vector index over all functions in the call graph, enabling natural-language search via the `search_code`, `orient`, and `suggest_insertion_points` MCP tools, and the search bar in the viewer.
1118
+
1119
+ ### GraphRAG retrieval expansion
1120
+
1121
+ Semantic search is only the starting point. spec-gen combines three retrieval layers into every search result — this is what makes it genuinely useful for AI agents navigating unfamiliar codebases:
1122
+
1123
+ 1. **Semantic seed** — dense vector search (or BM25 keyword fallback) finds the top-N functions closest in meaning to the query.
1124
+ 2. **Call-graph expansion** — BFS up to depth 2 follows callee edges from every seed function, pulling in the files those functions depend on. During `generate`, this ensures the LLM sees the full call neighbourhood, not just the most obvious files.
1125
+ 3. **Spec-linked peer functions** — each seed function's spec domain is looked up in the requirement→function mapping. Functions from the same spec domain that live in *different files* are surfaced as `specLinkedFunctions`. This crosses the call-graph boundary: implementations that share a spec requirement but are not directly connected by calls are retrieved automatically.
1126
+
1127
+ The result: a single `orient` or `search_code` call returns not just "functions that mention this concept" but the interconnected cluster of code and specs that collectively implement it. Agents spend less time chasing cross-file references manually and more time making changes with confidence.
942
1128
 
943
1129
  ### Embedding configuration
944
1130
 
@@ -950,8 +1136,8 @@ EMBED_BASE_URL=https://api.openai.com/v1
950
1136
  EMBED_MODEL=text-embedding-3-small
951
1137
  EMBED_API_KEY=sk-... # optional for local servers
952
1138
 
953
- # Then run:
954
- spec-gen analyze --embed
1139
+ # Then run (embedding is automatic when configured):
1140
+ spec-gen analyze
955
1141
  ```
956
1142
 
957
1143
  **Config file (`.spec-gen/config.json`):**
@@ -1146,11 +1332,11 @@ for (const [key, req] of Object.entries(requirements)) {
1146
1332
  npm install # Install dependencies
1147
1333
  npm run dev # Development mode (watch)
1148
1334
  npm run build # Build
1149
- npm run test:run # Run tests (1526 unit tests)
1335
+ npm run test:run # Run tests (2000+ unit tests)
1150
1336
  npm run typecheck # Type check
1151
1337
  ```
1152
1338
 
1153
- 1526 unit tests covering static analysis, call graph, refactor analysis, spec mapping, drift detection, LLM enhancement, ADR generation, and the full CLI.
1339
+ 2000+ unit tests covering static analysis, call graph, refactor analysis, spec mapping, drift detection, LLM enhancement, ADR generation, MCP handlers, and the full CLI.
1154
1340
 
1155
1341
  ## Links
1156
1342
 
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/api/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAoDvF;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8M/F"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/api/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AA2DvF;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8M/F"}
@@ -13,7 +13,7 @@ import { OpenSpecFormatGenerator } from '../core/generator/openspec-format-gener
13
13
  import { OpenSpecWriter } from '../core/generator/openspec-writer.js';
14
14
  import { ADRGenerator } from '../core/generator/adr-generator.js';
15
15
  import { MappingGenerator } from '../core/generator/mapping-generator.js';
16
- import { DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_OPENAI_COMPAT_MODEL, DEFAULT_GEMINI_MODEL, SPEC_GEN_DIR, SPEC_GEN_ANALYSIS_SUBDIR, SPEC_GEN_LOGS_SUBDIR, SPEC_GEN_ANALYSIS_REL_PATH, SPEC_GEN_GENERATION_SUBDIR, OPENSPEC_DIR, ARTIFACT_REPO_STRUCTURE, ARTIFACT_LLM_CONTEXT, ARTIFACT_DEPENDENCY_GRAPH, } from '../constants.js';
16
+ import { DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_OPENAI_COMPAT_MODEL, DEFAULT_GEMINI_MODEL, SPEC_GEN_DIR, SPEC_GEN_ANALYSIS_SUBDIR, SPEC_GEN_LOGS_SUBDIR, SPEC_GEN_ANALYSIS_REL_PATH, SPEC_GEN_GENERATION_SUBDIR, OPENSPEC_DIR, ARTIFACT_REPO_STRUCTURE, ARTIFACT_LLM_CONTEXT, ARTIFACT_DEPENDENCY_GRAPH, ARTIFACT_REFACTOR_PRIORITIES, } from '../constants.js';
17
17
  function progress(onProgress, step, status, detail) {
18
18
  onProgress?.({ phase: 'generate', step, status, detail });
19
19
  }
@@ -27,7 +27,8 @@ async function loadAnalysisData(analysisPath) {
27
27
  phase3_validation: { purpose: 'Validation', files: [], totalTokens: 0 },
28
28
  };
29
29
  const depGraph = await readJsonFile(join(analysisPath, ARTIFACT_DEPENDENCY_GRAPH), ARTIFACT_DEPENDENCY_GRAPH) ?? undefined;
30
- return { repoStructure, llmContext, depGraph };
30
+ const refactorReport = await readJsonFile(join(analysisPath, ARTIFACT_REFACTOR_PRIORITIES), ARTIFACT_REFACTOR_PRIORITIES) ?? undefined;
31
+ return { repoStructure, llmContext, depGraph, refactorReport };
31
32
  }
32
33
  /**
33
34
  * Generate OpenSpec specification files from analysis results using LLM.
@@ -60,7 +61,7 @@ export async function specGenGenerate(options = {}) {
60
61
  if (!analysisData) {
61
62
  throw new Error('No analysis found. Run specGenAnalyze() first.');
62
63
  }
63
- const { repoStructure, llmContext, depGraph } = analysisData;
64
+ const { repoStructure, llmContext, depGraph, refactorReport } = analysisData;
64
65
  progress(onProgress, 'Loading analysis', 'complete', `${repoStructure.statistics.analyzedFiles} files`);
65
66
  // Resolve provider
66
67
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
@@ -142,7 +143,7 @@ export async function specGenGenerate(options = {}) {
142
143
  });
143
144
  let pipelineResult;
144
145
  try {
145
- pipelineResult = await pipeline.run(repoStructure, llmContext, depGraph);
146
+ pipelineResult = await pipeline.run(repoStructure, llmContext, depGraph, refactorReport);
146
147
  }
147
148
  catch (error) {
148
149
  await llm.saveLogs().catch(() => { });
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/api/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/api/generate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/analyze.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAEhG,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AAiBnD,UAAU,cAAc;IACtB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAiCD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GACA,OAAO,CAAC,cAAc,CAAC,CAiEzB;AAMD,eAAO,MAAM,cAAc,SA4bvB,CAAC"}
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/analyze.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAEhG,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;AAkBnD,UAAU,cAAc;IACtB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAiCD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GACA,OAAO,CAAC,cAAc,CAAC,CAiEzB;AAMD,eAAO,MAAM,cAAc,SA4bvB,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * Outputs repository map, dependency graph, and file significance scores.
6
6
  */
7
7
  import { Command } from 'commander';
8
- import { stat, writeFile, mkdir } from 'node:fs/promises';
8
+ import { stat, writeFile, mkdir, readFile } from 'node:fs/promises';
9
9
  import { join } from 'node:path';
10
10
  import { logger } from '../../utils/logger.js';
11
11
  import { fileExists, formatDuration, formatAge } from '../../utils/command-helpers.js';
@@ -16,6 +16,7 @@ import { DependencyGraphBuilder, } from '../../core/analyzer/dependency-graph.js
16
16
  import { AnalysisArtifactGenerator, } from '../../core/analyzer/artifact-generator.js';
17
17
  import { buildArchitectureOverview, writeArchitectureMd, } from '../../core/analyzer/architecture-writer.js';
18
18
  import { EmbeddingService } from '../../core/analyzer/embedding-service.js';
19
+ import { generateCodebaseDigest } from '../../core/analyzer/codebase-digest.js';
19
20
  // ============================================================================
20
21
  // HELPER FUNCTIONS
21
22
  // ============================================================================
@@ -105,7 +106,8 @@ export const analyzeCommand = new Command('analyze')
105
106
  .option('--include <glob>', 'Additional glob patterns to include (repeatable)', collect, [])
106
107
  .option('--exclude <glob>', 'Additional glob patterns to exclude (repeatable)', collect, [])
107
108
  .option('--force', 'Force re-analysis even if recent analysis exists', false)
108
- .option('--embed', 'Build a semantic vector index after analysis (requires EMBED_BASE_URL + EMBED_MODEL)', false)
109
+ .option('--embed', 'Build a semantic vector index after analysis (requires EMBED_BASE_URL + EMBED_MODEL)', true)
110
+ .option('--no-embed', 'Skip vector index build (overrides default --embed)')
109
111
  .option('--reindex-specs', 'Re-index OpenSpec specs into the vector index without re-running full analysis (requires EMBED_BASE_URL + EMBED_MODEL)', false)
110
112
  .addHelpText('after', `
111
113
  Examples:
@@ -119,7 +121,7 @@ Examples:
119
121
  $ spec-gen analyze --output ./my-analysis
120
122
  Custom output location
121
123
  $ spec-gen analyze --force Force re-analysis
122
- $ spec-gen analyze --embed Also build semantic vector index (code + specs)
124
+ $ spec-gen analyze --no-embed Skip vector index build
123
125
  $ spec-gen analyze --reindex-specs Re-index specs only (no full re-analysis)
124
126
 
125
127
  Output files:
@@ -214,6 +216,10 @@ After analysis, run 'spec-gen generate' to create OpenSpec files.
214
216
  logger.info('Domains detected', repoStructure.domains.map((d) => d.name).join(', ') || 'None');
215
217
  logger.info('Architecture', repoStructure.architecture.pattern);
216
218
  logger.blank();
219
+ // If embed is requested, run the embed step (incremental: only re-embeds changed functions)
220
+ if (opts.embed) {
221
+ await runEmbedStep(rootPath, outputPath, specGenConfig, opts.force ?? false, null);
222
+ }
217
223
  logger.info('Next step', "Run 'spec-gen generate' to create OpenSpec files");
218
224
  return;
219
225
  }
@@ -406,6 +412,8 @@ After analysis, run 'spec-gen generate' to create OpenSpec files.
406
412
  catch (archErr) {
407
413
  logger.debug(`ARCHITECTURE.md generation skipped: ${archErr.message}`);
408
414
  }
415
+ // Generate .spec-gen/analysis/CODEBASE.md — agent-readable architecture digest
416
+ const digestWritten = await generateCodebaseDigest(artifacts.llmContext, depGraph, { rootPath, outputDir: outputPath });
409
417
  // Files generated
410
418
  console.log(' Output Files:');
411
419
  console.log(` ├─ ${opts.output}repo-structure.json`);
@@ -414,52 +422,35 @@ After analysis, run 'spec-gen generate' to create OpenSpec files.
414
422
  console.log(` ├─ ${opts.output}dependencies.mermaid`);
415
423
  if (architectureMdWritten) {
416
424
  console.log(` ├─ ${opts.output}SUMMARY.md`);
417
- console.log(' └─ ARCHITECTURE.md');
425
+ console.log(' ├─ ARCHITECTURE.md');
418
426
  }
419
427
  else {
420
- console.log(` └─ ${opts.output}SUMMARY.md`);
428
+ console.log(` ├─ ${opts.output}SUMMARY.md`);
429
+ }
430
+ if (digestWritten) {
431
+ console.log(` └─ ${opts.output}CODEBASE.md`);
432
+ console.log('');
433
+ console.log(' Agent setup (one-time):');
434
+ console.log(` Add to your CLAUDE.md or .clinerules:`);
435
+ console.log('');
436
+ console.log(` @.spec-gen/analysis/CODEBASE.md`);
437
+ console.log('');
438
+ console.log(' ## spec-gen MCP tools — when to use them');
439
+ console.log(' | Situation | Tool |');
440
+ console.log(' |-------------------------------------------------|-----------------------------------|');
441
+ console.log(" | Don't know which file/function handles a concept | search_code |");
442
+ console.log(' | Need call topology across many files | get_subgraph / analyze_impact |');
443
+ console.log(' | Starting a new task on an unfamiliar codebase | orient |');
444
+ console.log(' | Planning where to add a feature | suggest_insertion_points |');
445
+ console.log(' | Checking if code still matches spec | check_spec_drift |');
446
+ console.log(' | Finding spec requirements by meaning | search_specs |');
421
447
  }
422
448
  console.log('');
423
449
  // ========================================================================
424
450
  // PHASE 5 (optional): BUILD VECTOR INDEX
425
451
  // ========================================================================
426
452
  if (opts.embed) {
427
- console.log(' Building semantic vector index...');
428
- try {
429
- const { VectorIndex } = await import('../../core/analyzer/vector-index.js');
430
- // Resolve embedding config: env vars take priority, then .spec-gen/config.json
431
- let embedSvc;
432
- try {
433
- embedSvc = EmbeddingService.fromEnv();
434
- }
435
- catch {
436
- const cfg = await readSpecGenConfig(rootPath);
437
- if (!cfg)
438
- throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .spec-gen/config.json');
439
- const svcFromConfig = EmbeddingService.fromConfig(cfg);
440
- if (!svcFromConfig)
441
- throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .spec-gen/config.json');
442
- embedSvc = svcFromConfig;
443
- }
444
- const cg = result.artifacts.llmContext.callGraph;
445
- const sigs = result.artifacts.llmContext.signatures ?? [];
446
- if (!cg || cg.nodes.length === 0) {
447
- console.log(' ⚠ No call graph data — function index skipped');
448
- }
449
- else {
450
- const hubIds = new Set(cg.hubFunctions.map(f => f.id));
451
- const entryIds = new Set(cg.entryPoints.map(f => f.id));
452
- await VectorIndex.build(outputPath, cg.nodes, sigs, hubIds, entryIds, embedSvc);
453
- console.log(` ✓ Function index built (${cg.nodes.length} functions)`);
454
- console.log(` → ${opts.output}vector-index/`);
455
- }
456
- // Also index specs if they exist
457
- await runSpecIndexing(rootPath, outputPath, specGenConfig);
458
- }
459
- catch (embedErr) {
460
- console.log(` ✗ Vector index failed: ${embedErr.message}`);
461
- }
462
- console.log('');
453
+ await runEmbedStep(rootPath, outputPath, specGenConfig, opts.force ?? false, result.artifacts.llmContext);
463
454
  }
464
455
  // Duration
465
456
  const totalDuration = Date.now() - startTime;
@@ -478,6 +469,75 @@ After analysis, run 'spec-gen generate' to create OpenSpec files.
478
469
  }
479
470
  });
480
471
  // ============================================================================
472
+ // EMBED STEP HELPER
473
+ // ============================================================================
474
+ /**
475
+ * Build (or incrementally update) the vector index from a LLMContext.
476
+ * When llmContext is null, reads llm-context.json from outputDir (cache path).
477
+ * Non-fatal: prints a warning on failure without throwing.
478
+ */
479
+ async function runEmbedStep(rootPath, outputPath, specGenConfig, force, llmContext) {
480
+ console.log(' Building semantic vector index...');
481
+ try {
482
+ const { EmbeddingService } = await import('../../core/analyzer/embedding-service.js');
483
+ const { VectorIndex } = await import('../../core/analyzer/vector-index.js');
484
+ // Resolve embedding service
485
+ let embedSvc;
486
+ try {
487
+ embedSvc = EmbeddingService.fromEnv();
488
+ }
489
+ catch {
490
+ const cfg = specGenConfig ?? await readSpecGenConfig(rootPath);
491
+ if (!cfg)
492
+ throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .spec-gen/config.json');
493
+ const svcFromConfig = EmbeddingService.fromConfig(cfg);
494
+ if (!svcFromConfig)
495
+ throw new Error('No embedding config found. Set EMBED_BASE_URL and EMBED_MODEL, or add "embedding" to .spec-gen/config.json');
496
+ embedSvc = svcFromConfig;
497
+ }
498
+ // Load context from disk if not provided (cache hit path)
499
+ if (!llmContext) {
500
+ try {
501
+ const raw = await readFile(join(outputPath, 'llm-context.json'), 'utf-8');
502
+ llmContext = JSON.parse(raw);
503
+ }
504
+ catch {
505
+ console.log(' ⚠ Could not read llm-context.json — run spec-gen analyze --force');
506
+ return;
507
+ }
508
+ }
509
+ const cg = llmContext.callGraph;
510
+ const sigs = llmContext.signatures ?? [];
511
+ if (!cg || cg.nodes.length === 0) {
512
+ console.log(' ⚠ No call graph data — function index skipped');
513
+ }
514
+ else {
515
+ const hubIds = new Set(cg.hubFunctions.map(f => f.id));
516
+ const entryIds = new Set(cg.entryPoints.map(f => f.id));
517
+ const fileContents = new Map();
518
+ const uniquePaths = new Set(cg.nodes.map(n => n.filePath));
519
+ await Promise.all([...uniquePaths].map(async (fp) => {
520
+ try {
521
+ fileContents.set(fp, await readFile(join(rootPath, fp), 'utf-8'));
522
+ }
523
+ catch { /* skip unreadable files */ }
524
+ }));
525
+ const { embedded, reused } = await VectorIndex.build(outputPath, cg.nodes, sigs, hubIds, entryIds, embedSvc, fileContents,
526
+ /* incremental */ !force);
527
+ const total = embedded + reused;
528
+ const cacheNote = reused > 0 ? ` (${embedded} embedded, ${reused} cached)` : '';
529
+ console.log(` ✓ Function index built (${total} functions${cacheNote}, ${fileContents.size} files with skeleton bodies)`);
530
+ console.log(` → ${outputPath.replace(rootPath + '/', '')}vector-index/`);
531
+ }
532
+ // Also index specs if they exist
533
+ await runSpecIndexing(rootPath, outputPath, specGenConfig);
534
+ }
535
+ catch (embedErr) {
536
+ console.log(` ✗ Vector index failed: ${embedErr.message}`);
537
+ }
538
+ console.log('');
539
+ }
540
+ // ============================================================================
481
541
  // SPEC INDEXING HELPER
482
542
  // ============================================================================
483
543
  /**