codemap-core 0.2.2__tar.gz → 0.3.1__tar.gz

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 (130) hide show
  1. {codemap_core-0.2.2 → codemap_core-0.3.1}/CHANGELOG.md +144 -0
  2. {codemap_core-0.2.2 → codemap_core-0.3.1}/PKG-INFO +110 -3
  3. {codemap_core-0.2.2 → codemap_core-0.3.1}/README.md +109 -2
  4. codemap_core-0.3.1/docs/adr/0013-java-engine-tree-sitter-over-scip-java.md +115 -0
  5. codemap_core-0.3.1/docs/spikes/2026-06-23-scip-java-findings.md +142 -0
  6. codemap_core-0.3.1/docs/spikes/2026-06-24-codemap-refactor-execution-readiness.md +168 -0
  7. codemap_core-0.3.1/docs/spikes/2026-06-24-l1-refactor-next-steps.md +118 -0
  8. {codemap_core-0.2.2 → codemap_core-0.3.1}/pyproject.toml +21 -1
  9. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/index.py +96 -0
  10. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/main.py +30 -0
  11. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/config/schema.py +2 -0
  12. codemap_core-0.3.1/src/codemap/core/git_hotspots.py +43 -0
  13. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/models.py +3 -0
  14. codemap_core-0.3.1/src/codemap/emitters/__init__.py +3 -0
  15. codemap_core-0.3.1/src/codemap/emitters/base.py +43 -0
  16. codemap_core-0.3.1/src/codemap/emitters/registry.py +80 -0
  17. codemap_core-0.3.1/src/codemap/indexers/project_base.py +32 -0
  18. codemap_core-0.3.1/src/codemap/indexers/project_registry.py +81 -0
  19. codemap_core-0.3.1/tests/e2e/test_golden_precision.py +133 -0
  20. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/.gitignore +6 -0
  21. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/pom.xml +51 -0
  22. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/settings.xml +35 -0
  23. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/src/main/java/com/example/hellospring/controller/OrderController.java +25 -0
  24. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/src/main/java/com/example/hellospring/mapper/CouponMapper.java +9 -0
  25. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/src/main/java/com/example/hellospring/service/OrderService.java +27 -0
  26. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/src/main/resources/mapper/CouponMapper.xml +8 -0
  27. codemap_core-0.3.1/tests/fixtures/scip-samples/HelloSpring/web/OrderList.vue +14 -0
  28. codemap_core-0.3.1/tests/unit/test_emitter_registry.py +32 -0
  29. codemap_core-0.3.1/tests/unit/test_git_hotspots.py +32 -0
  30. codemap_core-0.3.1/tests/unit/test_models_kinds.py +26 -0
  31. codemap_core-0.3.1/tests/unit/test_orchestration_phases.py +126 -0
  32. codemap_core-0.3.1/tests/unit/test_project_indexer_registry.py +41 -0
  33. {codemap_core-0.2.2 → codemap_core-0.3.1}/.gitignore +0 -0
  34. {codemap_core-0.2.2 → codemap_core-0.3.1}/LICENSE +0 -0
  35. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0000-template.md +0 -0
  36. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0001-symbol-id-format.md +0 -0
  37. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0002-storage-backend.md +0 -0
  38. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0003-module-boundaries.md +0 -0
  39. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0004-indexer-bridge-plugin.md +0 -0
  40. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0005-exit-codes.md +0 -0
  41. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0006-schema-version.md +0 -0
  42. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0007-diagnostic-isolation.md +0 -0
  43. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0008-atomic-write.md +0 -0
  44. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0009-quality-gates.md +0 -0
  45. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0010-benchmark-regression.md +0 -0
  46. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0011-language-neutrality.md +0 -0
  47. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/adr/0012-first-language-cohort.md +0 -0
  48. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/bridges/http_route.md +0 -0
  49. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/cli.md +0 -0
  50. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/configuration.md +0 -0
  51. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/indexers/python.md +0 -0
  52. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/performance.md +0 -0
  53. {codemap_core-0.2.2 → codemap_core-0.3.1}/docs/plugin-guide.md +0 -0
  54. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/__init__.py +0 -0
  55. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/__init__.py +0 -0
  56. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/_common.py +0 -0
  57. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/__init__.py +0 -0
  58. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/callees.py +0 -0
  59. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/callers.py +0 -0
  60. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/config.py +0 -0
  61. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/diagnostics.py +0 -0
  62. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/doctor.py +0 -0
  63. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/get.py +0 -0
  64. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/routes.py +0 -0
  65. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/search.py +0 -0
  66. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/commands/trace.py +0 -0
  67. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/renderers/__init__.py +0 -0
  68. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/renderers/json.py +0 -0
  69. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/cli/renderers/text.py +0 -0
  70. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/config/__init__.py +0 -0
  71. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/config/loader.py +0 -0
  72. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/__init__.py +0 -0
  73. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/bridge/__init__.py +0 -0
  74. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/bridge/base.py +0 -0
  75. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/bridge/http_route.py +0 -0
  76. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/bridge/python_cross_module.py +0 -0
  77. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/bridge/registry.py +0 -0
  78. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/graph.py +0 -0
  79. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/store.py +0 -0
  80. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/core/symbol.py +0 -0
  81. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/diagnostics/__init__.py +0 -0
  82. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/diagnostics/exit_codes.py +0 -0
  83. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/diagnostics/logging.py +0 -0
  84. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/diagnostics/progress.py +0 -0
  85. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/indexers/__init__.py +0 -0
  86. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/indexers/_example_lang.py +0 -0
  87. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/indexers/base.py +0 -0
  88. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/indexers/python.py +0 -0
  89. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/indexers/registry.py +0 -0
  90. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/__init__.py +0 -0
  91. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/atomic.py +0 -0
  92. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/base.py +0 -0
  93. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/json_store.py +0 -0
  94. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/lock.py +0 -0
  95. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/io/manifest.py +0 -0
  96. {codemap_core-0.2.2 → codemap_core-0.3.1}/src/codemap/mcp/__init__.py +0 -0
  97. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/__init__.py +0 -0
  98. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/bench/__init__.py +0 -0
  99. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/bench/conftest.py +0 -0
  100. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/bench/test_index_perf.py +0 -0
  101. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/bench/test_query_perf.py +0 -0
  102. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/__init__.py +0 -0
  103. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_cli.py +0 -0
  104. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_config_integration.py +0 -0
  105. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_cross_module_callers.py +0 -0
  106. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_diagnostics.py +0 -0
  107. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_error_experience.py +0 -0
  108. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_http_pipeline.py +0 -0
  109. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_incremental.py +0 -0
  110. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/e2e/test_query_commands.py +0 -0
  111. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/basics/expected/symbol_ids.txt +0 -0
  112. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/basics/input/pkg/mod.py +0 -0
  113. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/imports/expected/symbol_ids.txt +0 -0
  114. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/imports/input/users.py +0 -0
  115. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/inheritance/expected/symbol_ids.txt +0 -0
  116. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/indexers/python/inheritance/input/shapes.py +0 -0
  117. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/smoke/a.example +0 -0
  118. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/fixtures/smoke/b.example +0 -0
  119. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/integration/__init__.py +0 -0
  120. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/integration/test_http_route_bridge_e2e.py +0 -0
  121. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/__init__.py +0 -0
  122. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_config.py +0 -0
  123. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_graph.py +0 -0
  124. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_http_route_bridge.py +0 -0
  125. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_indexer_registry.py +0 -0
  126. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_io.py +0 -0
  127. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_models.py +0 -0
  128. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_python_cross_module_bridge.py +0 -0
  129. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_python_indexer.py +0 -0
  130. {codemap_core-0.2.2 → codemap_core-0.3.1}/tests/unit/test_symbol.py +0 -0
@@ -8,6 +8,150 @@ During `0.x`, MINOR may introduce breaking changes — they will be marked `BREA
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.3.1] — 2026-06-25
12
+
13
+ Quick follow-up to 0.3.0. Lockstep version-only bump across all **20
14
+ packages** to keep the family in sync; the only source change is in
15
+ `codemap-aimemory`.
16
+
17
+ ### `codemap-aimemory` — LLM CLI configuration
18
+
19
+ * New subcommand group **`codemap llm config`** (registered through the
20
+ `codemap.cli_commands` entry-point group introduced in 0.3.0):
21
+ * `codemap llm config set api-key <key>` — persist to
22
+ `~/.config/codemap/llm.yaml` (or `$XDG_CONFIG_HOME/codemap/llm.yaml`),
23
+ written `chmod 600` because it carries a credential.
24
+ * `codemap llm config set base-url <url>` / `model` / `backend`.
25
+ * `codemap llm config unset <key>` — clear one field; the on-disk
26
+ file only contains non-`None` values.
27
+ * `codemap llm config show` — print the effective config with one of
28
+ `[env]` / `[file]` / `[default]` annotated per field; API keys are
29
+ masked.
30
+ * `codemap llm config path` — print the config file location.
31
+ * `codemap enrich` resolution order is now (first non-empty wins):
32
+ CLI flag → env var → file config (new in 0.3.1) → built-in defaults.
33
+ * Behavioural reminder: **API key is the LLM on/off switch.**
34
+ `codemap index` never calls any LLM; `codemap enrich` without a key
35
+ errors out cleanly, never silently. No background LLM traffic.
36
+
37
+ ### Documentation
38
+
39
+ * README + README.zh-CN: new "Output formats" section documenting every
40
+ file under `.codemap/` and `.ai-memory/` (kind, shape, who consumes it).
41
+ * README + README.zh-CN: new "LLM configuration" section with the
42
+ three-source resolution order and a Chinese / open-source LLM endpoint
43
+ cheatsheet (DeepSeek, GLM, MiniMax, Kimi, Qwen, MiMo, Ollama, native
44
+ Anthropic) — all use `--backend openai` with their own `base-url`.
45
+ * INSTALL: bump heading and mention the new CLI.
46
+
47
+ ### Plugin tests
48
+
49
+ 19 new unit tests in `codemap-aimemory` covering: XDG path resolution,
50
+ load / save / unset round-trip, `chmod 600` on save, corrupt-YAML
51
+ graceful fallback, dash-vs-underscore key aliasing, CLI set / show /
52
+ unset / path, source-annotation correctness in `show`. Plugin test
53
+ total: 38 → 57. Other plugins unchanged.
54
+
55
+ ## [0.3.0] — 2026-06-25
56
+
57
+ The four-layer-memory-model L1 release. The plugin family grows from
58
+ **18 to 20** distributions; every package bumps in lockstep to `0.3.0`,
59
+ and every plugin's `codemap-core` dependency widens to `>=0.3.0,<0.4`.
60
+
61
+ ### New plugins (opt-in)
62
+
63
+ * **`codemap-mybatis`** — MyBatis Mapper XML indexer. Per-file XML
64
+ parsing yields `sql_mapping` symbols + `table` symbols + DML
65
+ `accesses_table` edges (confidence graded by SQL complexity —
66
+ static / dynamic-tag / `${}` substitution). A new `MyBatisLinkBridge`
67
+ emits `maps_to` edges from Java Mapper interface methods to their
68
+ backing XML statements (requires `codemap-java` installed).
69
+ * **`codemap-aimemory`** — emits the four-layer memory model's L1
70
+ layout (`.ai-memory/entities/*.yml` + `.ai-memory/relations/*.yml`)
71
+ so AI agents can consume the index directly with stable
72
+ `entity_id` slugs (fn-* / cls-* / tbl-*). Atomic per-file writes
73
+ (tmp + rename). Includes an optional LLM enrichment overlay — the
74
+ core index itself remains LLM-free; enrichment writes to a
75
+ separate `enrichment/` directory keyed by `symbol_id` and is
76
+ merged only at emit time.
77
+
78
+ ### New core capability
79
+
80
+ * **Project-level indexer protocol** (`codemap.indexers.project_base`).
81
+ Mirrors the per-file `Indexer` but consumes the entire project in
82
+ one pass, for engines whose output is whole-project (Java semantic
83
+ resolver, future SCIP-backed importers). Lazy-discovered through
84
+ the new `codemap.project_indexers` entry-point group.
85
+ * **Emitter protocol** (`codemap.emitters`) — third plugin layer
86
+ alongside indexers / bridges. Registered through
87
+ `codemap.emitters` entry-point group with the same Protocol +
88
+ Registry pattern. The orchestrator runs emitters as the last
89
+ phase of `codemap index` (after bridges + hotspots).
90
+ * **CLI subcommand registration via entry-points**
91
+ (`codemap.cli_commands`). Plugins can ship typer subcommands —
92
+ `codemap-aimemory` uses this to register `codemap enrich`.
93
+ * **Git change-hotspot analyzer** (`codemap.core.git_hotspots`).
94
+ Language-neutral; surfaces `change_count_90d` on every symbol's
95
+ `extra`. Graceful skip on non-git / unavailable git.
96
+ * `EdgeKind` adds `overrides`, `accesses_table`; `SymbolKind` adds
97
+ `table`.
98
+
99
+ ### Java engine rewrite (ADR-0013)
100
+
101
+ * **`codemap-java`** moves from declaration-only to a full call
102
+ graph. The per-file indexer now captures `imports`, `supertypes`,
103
+ `pending_calls` (raw invocation records), method `params` /
104
+ `return_type`, and field `type` on `Symbol.extra`. A new
105
+ `JavaCallResolverBridge` (registered as `java_calls`) does
106
+ project-wide FQN resolution to emit `calls` / `extends` /
107
+ `implements` edges at `confidence=medium`. ADR-0013 documents
108
+ the deliberate trade-off (precision ceiling drops from
109
+ full-semantic `high` to FQN-resolved `medium`, in exchange for
110
+ zero external toolchain — no scip-java, no JVM build needed).
111
+ * Spring annotation extraction: type / method `@Annotation` nodes
112
+ land on `Symbol.annotations`; the indexer combines class-level
113
+ `@RequestMapping` prefix with method verb mappings
114
+ (`@GetMapping` / `@PostMapping` / …) and writes `http_route`
115
+ metadata so the existing `http_route` bridge auto-mints route
116
+ intermediates.
117
+
118
+ ### `codemap-vue` extends
119
+
120
+ * Captures `axios.<verb>(...)` / `this.$axios.<verb>(...)` /
121
+ `fetch(...)` invocations inside script blocks, attaching
122
+ `{method, url, confidence}` records to the enclosing
123
+ function/method symbol's `extra["http_calls"]`. The existing
124
+ `http_route` bridge now connects Vue clients to Spring routes
125
+ automatically.
126
+
127
+ ### `codemap enrich` CLI (new)
128
+
129
+ ```bash
130
+ codemap enrich --backend openai --model gpt-4o-mini
131
+ codemap enrich --backend anthropic --model claude-sonnet-4-5
132
+ codemap enrich --backend ollama --model llama3
133
+ codemap enrich --base-url http://my-proxy/v1 --api-key sk-…
134
+ ```
135
+
136
+ Reads `.codemap/`, calls the configured LLM for each
137
+ function/method symbol, writes overlay YAML files under
138
+ `.ai-memory/enrichment/`. Env-var fallback chain:
139
+ `CODEMAP_LLM_API_KEY` → `ANTHROPIC_API_KEY` → `OPENAI_API_KEY`;
140
+ `CODEMAP_LLM_BASE_URL` → `OPENAI_BASE_URL` → `ANTHROPIC_BASE_URL`.
141
+ The next `codemap index` merges the overlay into
142
+ `entities/functions.yml`. `--dry-run` reports without calling.
143
+
144
+ ### Default prune dirs
145
+
146
+ `DEFAULT_PRUNE_DIRS` now includes `target` (Maven) and `out`
147
+ (Gradle IDE default) so Java/Kotlin/Scala projects don't double-
148
+ index build output trees.
149
+
150
+ ### New import-linter contract
151
+
152
+ `emitters may not import cli/mcp/io` keeps the new emitter layer
153
+ honest to the same dependency rules as indexers and bridges.
154
+
11
155
  ## [0.2.2] — 2026-06-05
12
156
 
13
157
  Lockstep version-only bump across all **18 packages** to keep the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codemap-core
3
- Version: 0.2.2
3
+ Version: 0.3.1
4
4
  Summary: Language-neutral code index for AI agents
5
5
  Project-URL: Homepage, https://github.com/qxbyte/codemap
6
6
  Project-URL: Repository, https://github.com/qxbyte/codemap
@@ -78,8 +78,10 @@ mappings, and cross-file relationships without grepping the entire
78
78
  project. Indexing is static, fast, and reproducible — no LLM in the
79
79
  index path.
80
80
 
81
- **Status**: 0.2.0 stable. Installable from PyPI as `codemap-core`
82
- plus 17 `codemap-<lang>` plugins.
81
+ **Status**: 0.3.1 stable. Installable from PyPI as `codemap-core`
82
+ plus 17 `codemap-<lang>` plugins + 2 framework / output plugins
83
+ (`codemap-mybatis`, `codemap-aimemory`, added in 0.3.0; 0.3.1
84
+ adds the `codemap llm config` CLI).
83
85
 
84
86
  > 👉 **In a hurry?** The [`INSTALL.md`](./INSTALL.md) guide is the
85
87
  > definitive walkthrough — it covers `pipx` / `uv tool` / `pip`,
@@ -315,6 +317,14 @@ codemap routes # HTTP routes from the http_route bridge
315
317
 
316
318
  # Machine-readable output: all commands take --json
317
319
  codemap --json callers '<symbol-id>'
320
+
321
+ # Optional LLM enrichment (codemap-aimemory plugin, 0.3.0+)
322
+ codemap llm config set api-key sk-xxx # persist to ~/.config/codemap/llm.yaml
323
+ codemap llm config set base-url https://api.deepseek.com/v1
324
+ codemap llm config set model deepseek-chat
325
+ codemap llm config show # masked-key view + value source
326
+ codemap enrich . # fills .ai-memory/enrichment/*.yml
327
+ codemap enrich . --dry-run # count fn/method symbols, no API call
318
328
  ```
319
329
 
320
330
  Exit codes follow `sysexits.h` (ADR-005); see
@@ -322,6 +332,103 @@ Exit codes follow `sysexits.h` (ADR-005); see
322
332
 
323
333
  ---
324
334
 
335
+ ## Output formats
336
+
337
+ `codemap index` produces two parallel directories at the project root:
338
+
339
+ ```
340
+ <project>/
341
+ ├── .codemap/ ← deterministic, machine-friendly index (queried by `codemap …`)
342
+ └── .ai-memory/ ← four-layer-memory-model L1 layout (consumed by AI agents)
343
+ ```
344
+
345
+ ### `.codemap/` — deterministic index (JSON, 7 files)
346
+
347
+ | File | Contents |
348
+ |---|---|
349
+ | `symbols.json` | All symbols keyed by `SymbolID`. Each entry: `kind`, `language`, `file`, `range`, `signature`, `annotations`, `confidence`, `extra` (per-language metadata: `pending_calls`, `http_route`, `supertypes`, `imports`, `params`, `return_type`, `change_count_90d`, …). |
350
+ | `edges.json` | Directed relations: `calls` / `extends` / `implements` / `overrides` / `references` / `routes_to` / `maps_to` / `imports` / `accesses_table`. Each carries `confidence` ∈ {`high`, `medium`, `low`}. |
351
+ | `routes.json` | HTTP routes minted by the `http_route` bridge from `extra["http_route"]`. |
352
+ | `aliases.json` | Synthetic intermediate ↔ real symbol links (e.g. route → handler). |
353
+ | `manifest.json` | Project root, `codemap_version`, registered indexers + bridges + their versions, per-file sha256 / mtime / language. |
354
+ | `diagnostics.json` | Indexer / bridge warnings collected during the run (severity + code + message + producer). |
355
+ | `.lock` | Cross-process write lock; do not edit. |
356
+
357
+ ### `.ai-memory/` — four-layer memory L1 (YAML, 6 files)
358
+
359
+ Generated by `codemap-aimemory` when installed. AI agents read this
360
+ tree directly. Stable `entity_id` slugs are derived from the SCIP
361
+ `SymbolID` (e.g. `fn-calcPrice` / `cls-OrderService` / `tbl-sf_coupon`).
362
+
363
+ ```
364
+ .ai-memory/
365
+ ├── entities/
366
+ │ ├── functions.yml fn-* / cls-* with calls / called_by /
367
+ │ │ related_tables / signature / line_range /
368
+ │ │ confidence / change_count_90d / business_meaning
369
+ │ ├── tables.yml tbl-* table entities
370
+ │ └── files.yml file-* file entries
371
+ ├── relations/
372
+ │ ├── call-graph.yml `{from, to, type=calls, confidence}`
373
+ │ ├── table-relations.yml `{from, to, type=accesses_table, confidence}`
374
+ │ └── rule-constraints.yml empty placeholder (L2 owns)
375
+ └── enrichment/ OPTIONAL: LLM-generated explanations
376
+ └── <sha1[:12]>.yml `{symbol_id, business_meaning,
377
+ related_rules, confidence:"llm",
378
+ source_model, generated_at}`
379
+ ```
380
+
381
+ Two-hop fan-out: when a Java method `maps_to` a `sql_mapping` that
382
+ `accesses_table` T, T automatically lands on the method's
383
+ `related_tables`. So `fn-selectByUser.related_tables = [tbl-sf_coupon]`
384
+ without the agent needing to follow the chain itself.
385
+
386
+ ---
387
+
388
+ ## LLM configuration (optional)
389
+
390
+ The core index is **always LLM-free** — `codemap index` never calls any
391
+ LLM. Only the optional `codemap enrich` command in `codemap-aimemory`
392
+ writes the `enrichment/` overlay, and only when **you** invoke it. The
393
+ existence of an API key is the on/off switch: without one, `codemap
394
+ enrich` exits with a clear error and no network call is made.
395
+
396
+ Three configuration sources, **first non-empty wins**:
397
+
398
+ 1. **CLI flag** — `--api-key`, `--base-url`, `--model`, `--backend`
399
+ 2. **Environment variable** — `CODEMAP_LLM_API_KEY` (also
400
+ `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`); `CODEMAP_LLM_BASE_URL`
401
+ (also `OPENAI_BASE_URL`, `ANTHROPIC_BASE_URL`);
402
+ `CODEMAP_LLM_MODEL`; `CODEMAP_LLM_BACKEND`
403
+ 3. **Persistent file config** — `~/.config/codemap/llm.yaml` (managed
404
+ by `codemap llm config set/unset/show`; written `chmod 600`)
405
+ 4. Built-in defaults — backend `openai`, model `gpt-4o-mini`
406
+
407
+ ### Common provider endpoints (OpenAI-compatible — `--backend openai`)
408
+
409
+ | Provider | Model example | Base URL |
410
+ |---|---|---|
411
+ | OpenAI | `gpt-4o-mini` | `https://api.openai.com/v1` *(default)* |
412
+ | DeepSeek | `deepseek-chat` | `https://api.deepseek.com/v1` |
413
+ | 智谱 GLM | `glm-4-flash` | `https://open.bigmodel.cn/api/paas/v4/` |
414
+ | MiniMax | `abab6.5s-chat` | `https://api.minimax.chat/v1` |
415
+ | 月之暗面 Kimi | `moonshot-v1-8k` | `https://api.moonshot.cn/v1` |
416
+ | 阿里通义 | `qwen-plus` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
417
+ | 小米 MiMo | `mimo-large` | *(per vendor docs; OpenAI-compatible)* |
418
+ | Ollama (local) | `llama3` | `http://localhost:11434/v1` — use `--backend ollama` (key not needed) |
419
+ | Anthropic native | `claude-sonnet-4-5` | *(use `--backend anthropic`; requires `anthropic` SDK via `pip install codemap-aimemory[llm]`)* |
420
+
421
+ Example with DeepSeek:
422
+
423
+ ```bash
424
+ codemap llm config set base-url https://api.deepseek.com/v1
425
+ codemap llm config set api-key sk-xxx
426
+ codemap llm config set model deepseek-chat
427
+ codemap enrich .
428
+ ```
429
+
430
+ ---
431
+
325
432
  ## Configuration
326
433
 
327
434
  Project-level configuration lives at `.codemap/config.yaml` (committed
@@ -11,8 +11,10 @@ mappings, and cross-file relationships without grepping the entire
11
11
  project. Indexing is static, fast, and reproducible — no LLM in the
12
12
  index path.
13
13
 
14
- **Status**: 0.2.0 stable. Installable from PyPI as `codemap-core`
15
- plus 17 `codemap-<lang>` plugins.
14
+ **Status**: 0.3.1 stable. Installable from PyPI as `codemap-core`
15
+ plus 17 `codemap-<lang>` plugins + 2 framework / output plugins
16
+ (`codemap-mybatis`, `codemap-aimemory`, added in 0.3.0; 0.3.1
17
+ adds the `codemap llm config` CLI).
16
18
 
17
19
  > 👉 **In a hurry?** The [`INSTALL.md`](./INSTALL.md) guide is the
18
20
  > definitive walkthrough — it covers `pipx` / `uv tool` / `pip`,
@@ -248,6 +250,14 @@ codemap routes # HTTP routes from the http_route bridge
248
250
 
249
251
  # Machine-readable output: all commands take --json
250
252
  codemap --json callers '<symbol-id>'
253
+
254
+ # Optional LLM enrichment (codemap-aimemory plugin, 0.3.0+)
255
+ codemap llm config set api-key sk-xxx # persist to ~/.config/codemap/llm.yaml
256
+ codemap llm config set base-url https://api.deepseek.com/v1
257
+ codemap llm config set model deepseek-chat
258
+ codemap llm config show # masked-key view + value source
259
+ codemap enrich . # fills .ai-memory/enrichment/*.yml
260
+ codemap enrich . --dry-run # count fn/method symbols, no API call
251
261
  ```
252
262
 
253
263
  Exit codes follow `sysexits.h` (ADR-005); see
@@ -255,6 +265,103 @@ Exit codes follow `sysexits.h` (ADR-005); see
255
265
 
256
266
  ---
257
267
 
268
+ ## Output formats
269
+
270
+ `codemap index` produces two parallel directories at the project root:
271
+
272
+ ```
273
+ <project>/
274
+ ├── .codemap/ ← deterministic, machine-friendly index (queried by `codemap …`)
275
+ └── .ai-memory/ ← four-layer-memory-model L1 layout (consumed by AI agents)
276
+ ```
277
+
278
+ ### `.codemap/` — deterministic index (JSON, 7 files)
279
+
280
+ | File | Contents |
281
+ |---|---|
282
+ | `symbols.json` | All symbols keyed by `SymbolID`. Each entry: `kind`, `language`, `file`, `range`, `signature`, `annotations`, `confidence`, `extra` (per-language metadata: `pending_calls`, `http_route`, `supertypes`, `imports`, `params`, `return_type`, `change_count_90d`, …). |
283
+ | `edges.json` | Directed relations: `calls` / `extends` / `implements` / `overrides` / `references` / `routes_to` / `maps_to` / `imports` / `accesses_table`. Each carries `confidence` ∈ {`high`, `medium`, `low`}. |
284
+ | `routes.json` | HTTP routes minted by the `http_route` bridge from `extra["http_route"]`. |
285
+ | `aliases.json` | Synthetic intermediate ↔ real symbol links (e.g. route → handler). |
286
+ | `manifest.json` | Project root, `codemap_version`, registered indexers + bridges + their versions, per-file sha256 / mtime / language. |
287
+ | `diagnostics.json` | Indexer / bridge warnings collected during the run (severity + code + message + producer). |
288
+ | `.lock` | Cross-process write lock; do not edit. |
289
+
290
+ ### `.ai-memory/` — four-layer memory L1 (YAML, 6 files)
291
+
292
+ Generated by `codemap-aimemory` when installed. AI agents read this
293
+ tree directly. Stable `entity_id` slugs are derived from the SCIP
294
+ `SymbolID` (e.g. `fn-calcPrice` / `cls-OrderService` / `tbl-sf_coupon`).
295
+
296
+ ```
297
+ .ai-memory/
298
+ ├── entities/
299
+ │ ├── functions.yml fn-* / cls-* with calls / called_by /
300
+ │ │ related_tables / signature / line_range /
301
+ │ │ confidence / change_count_90d / business_meaning
302
+ │ ├── tables.yml tbl-* table entities
303
+ │ └── files.yml file-* file entries
304
+ ├── relations/
305
+ │ ├── call-graph.yml `{from, to, type=calls, confidence}`
306
+ │ ├── table-relations.yml `{from, to, type=accesses_table, confidence}`
307
+ │ └── rule-constraints.yml empty placeholder (L2 owns)
308
+ └── enrichment/ OPTIONAL: LLM-generated explanations
309
+ └── <sha1[:12]>.yml `{symbol_id, business_meaning,
310
+ related_rules, confidence:"llm",
311
+ source_model, generated_at}`
312
+ ```
313
+
314
+ Two-hop fan-out: when a Java method `maps_to` a `sql_mapping` that
315
+ `accesses_table` T, T automatically lands on the method's
316
+ `related_tables`. So `fn-selectByUser.related_tables = [tbl-sf_coupon]`
317
+ without the agent needing to follow the chain itself.
318
+
319
+ ---
320
+
321
+ ## LLM configuration (optional)
322
+
323
+ The core index is **always LLM-free** — `codemap index` never calls any
324
+ LLM. Only the optional `codemap enrich` command in `codemap-aimemory`
325
+ writes the `enrichment/` overlay, and only when **you** invoke it. The
326
+ existence of an API key is the on/off switch: without one, `codemap
327
+ enrich` exits with a clear error and no network call is made.
328
+
329
+ Three configuration sources, **first non-empty wins**:
330
+
331
+ 1. **CLI flag** — `--api-key`, `--base-url`, `--model`, `--backend`
332
+ 2. **Environment variable** — `CODEMAP_LLM_API_KEY` (also
333
+ `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`); `CODEMAP_LLM_BASE_URL`
334
+ (also `OPENAI_BASE_URL`, `ANTHROPIC_BASE_URL`);
335
+ `CODEMAP_LLM_MODEL`; `CODEMAP_LLM_BACKEND`
336
+ 3. **Persistent file config** — `~/.config/codemap/llm.yaml` (managed
337
+ by `codemap llm config set/unset/show`; written `chmod 600`)
338
+ 4. Built-in defaults — backend `openai`, model `gpt-4o-mini`
339
+
340
+ ### Common provider endpoints (OpenAI-compatible — `--backend openai`)
341
+
342
+ | Provider | Model example | Base URL |
343
+ |---|---|---|
344
+ | OpenAI | `gpt-4o-mini` | `https://api.openai.com/v1` *(default)* |
345
+ | DeepSeek | `deepseek-chat` | `https://api.deepseek.com/v1` |
346
+ | 智谱 GLM | `glm-4-flash` | `https://open.bigmodel.cn/api/paas/v4/` |
347
+ | MiniMax | `abab6.5s-chat` | `https://api.minimax.chat/v1` |
348
+ | 月之暗面 Kimi | `moonshot-v1-8k` | `https://api.moonshot.cn/v1` |
349
+ | 阿里通义 | `qwen-plus` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
350
+ | 小米 MiMo | `mimo-large` | *(per vendor docs; OpenAI-compatible)* |
351
+ | Ollama (local) | `llama3` | `http://localhost:11434/v1` — use `--backend ollama` (key not needed) |
352
+ | Anthropic native | `claude-sonnet-4-5` | *(use `--backend anthropic`; requires `anthropic` SDK via `pip install codemap-aimemory[llm]`)* |
353
+
354
+ Example with DeepSeek:
355
+
356
+ ```bash
357
+ codemap llm config set base-url https://api.deepseek.com/v1
358
+ codemap llm config set api-key sk-xxx
359
+ codemap llm config set model deepseek-chat
360
+ codemap enrich .
361
+ ```
362
+
363
+ ---
364
+
258
365
  ## Configuration
259
366
 
260
367
  Project-level configuration lives at `.codemap/config.yaml` (committed
@@ -0,0 +1,115 @@
1
+ # ADR-0013: Java engine — tree-sitter over scip-java
2
+
3
+ * **Status**: Accepted
4
+ * **Date**: 2026-06-24
5
+ * **Related**: design `2026-06-23-codemap-l1-知识图谱重构-design.md` §A1/§B1 · spike `2026-06-23-scip-java-findings.md` · ADR-0004 (indexer/bridge plugin) · ADR-0007 (diagnostic isolation) · ADR-L001 (language neutrality)
6
+
7
+ ## Context
8
+
9
+ The original L1 knowledge-graph design (2026-06-23) picked scip-java as Java's
10
+ semantic backend, citing maximum precision (interface→impl, overloads,
11
+ generics, cross-file resolution). Implementing it required:
12
+
13
+ * ~100 MB scip-java + coursier + JVM toolchain on the user's machine
14
+ * The target project must be `mvn`/`gradle` buildable (private-repo deps, JDK
15
+ pinning, multi-module)
16
+ * protoc / grpcio-tools to vendor `scip_pb2.py`
17
+ * A spike (Plan 0) to confirm the real SCIP symbol string format before
18
+ Plan 2's `symbol_map` / `extract_edges` could be written
19
+ * `mvn compile` on every full index — minute-scale, doesn't fit watch mode
20
+
21
+ The user explicitly rejected this weight tradeoff in favor of a lighter
22
+ default engine that still meets the spec's "high precision call graph"
23
+ ambition for the common path.
24
+
25
+ ## Decision
26
+
27
+ **Use tree-sitter-java as the sole Java engine.** Permanently drop scip-java.
28
+
29
+ The architecture stays the same — declarations come from a per-file
30
+ `JavaIndexer`, cross-file edges (calls/extends/implements) come from a
31
+ separate resolver — but the resolver runs in Python on tree-sitter AST plus
32
+ an import + FQN graph it builds itself, not on a `.scip` file.
33
+
34
+ Implementation shape:
35
+
36
+ 1. **`JavaIndexer` (per-file, existing — extended)**: in addition to today's
37
+ declarations, capture `import` statements and method invocations into
38
+ `Symbol.extra["pending_calls"]` (raw records: receiver name, method name,
39
+ argument arity, location).
40
+ 2. **`JavaCallResolverBridge` (new, runs in the bridge phase)**: read all
41
+ Java symbols + their pending_calls, build a project-wide FQN table from
42
+ the import statements, same-package declarations, and explicit
43
+ `extends`/`implements` relations, then emit `calls` / `extends` /
44
+ `implements` / `overrides` edges with `confidence: medium`.
45
+ 3. **Spring annotations + http_route metadata** stay in the indexer (Plan 3
46
+ Task 1/2) using tree-sitter — no scip-java needed for that anyway.
47
+ 4. **MyBatis** (Plan 3 Task 3) rebuilds the Java method `SymbolID` using the
48
+ codemap-java scheme (consistent with the new indexer), not the scip-java
49
+ symbol format. This removes the spike-Plan-0 dependency entirely.
50
+
51
+ ### Alternatives considered
52
+
53
+ * **B — Hybrid (tree-sitter default + scip-java optional)**: tempting but
54
+ doubles the implementation surface and forces every downstream consumer
55
+ to handle two backends with different fidelity.
56
+ * **C — Bytecode parsing (javap / asm)**: still requires `mvn compile`, so it
57
+ inherits scip-java's "your project must build" weight. Python bytecode-
58
+ parsing ecosystem is thinner than tree-sitter.
59
+
60
+ ## Consequences
61
+
62
+ What becomes easier:
63
+
64
+ * Zero external Java toolchain. `pip install codemap-core codemap-java`
65
+ works out of the box on any machine.
66
+ * No spike unblock required. Plan 2 can start TDD immediately.
67
+ * Watch mode and incremental indexing become realistic (per-file tree-sitter
68
+ parse is millisecond-scale).
69
+ * Plan 4's Golden test fixture no longer needs scip-java in CI.
70
+
71
+ What becomes harder / what we accept:
72
+
73
+ * **Precision ceiling drops from "high" to "medium" for `calls` edges.**
74
+ Realistic targets on Spring/MyBatis projects:
75
+ * `calls`: 70–80% precision (overload disambiguation by arity only; dynamic
76
+ dispatch through interface-typed fields resolved heuristically by
77
+ DI-known impls — see follow-up below)
78
+ * `implements`/`extends`: ~95% (explicit `implements X, Y` syntax)
79
+ * Annotation extraction: 100% (purely syntactic)
80
+ * Reflection, dynamic proxies, and Spring AOP-style indirection produce
81
+ edges that look correct syntactically but miss runtime targets. These are
82
+ the same blind spots tree-sitter has anywhere; we mark them with `medium`
83
+ confidence rather than pretend.
84
+ * The precision gate (Plan 4 Task 5) lowers its `high`-tier threshold,
85
+ effectively becoming a `medium`-tier `≥ 0.70` gate on `calls` and a
86
+ `≥ 0.95` gate on `implements`/`extends`. Regression-detection rationale
87
+ unchanged.
88
+
89
+ What we keep paying for:
90
+
91
+ * The FQN resolver is real code we own — when Java's grammar changes (new
92
+ language features, pattern-matching) tree-sitter-java updates flow
93
+ through, but our resolver has to keep up too.
94
+ * The `ProjectIndexer` protocol added in Plan 1 Task 2 is retained as a
95
+ generic extension point for future heavier engines (e.g. someone wants to
96
+ ship a scip-java backend later) — Java itself no longer uses it, but
97
+ emptying the slot would break the symmetry with `Indexer`/`Emitter`.
98
+
99
+ Follow-up ADRs / decisions:
100
+
101
+ * If/when a project demonstrates that medium precision is insufficient (e.g.
102
+ precision-gate alarms repeatedly), revisit and consider adding scip-java
103
+ as an *opt-in* second backend that publishes the same SymbolID shape — at
104
+ that point Hybrid (alternative B) becomes a focused upgrade rather than
105
+ default complexity.
106
+
107
+ ## References
108
+
109
+ * spec `2026-06-23-codemap-l1-知识图谱重构-design.md` (Obsidian vault) §A1/§B1
110
+ * spike `docs/spikes/2026-06-23-scip-java-findings.md` §0 (toolchain blocker
111
+ that triggered the rethink)
112
+ * `docs/adr/0004-indexer-bridge-plugin.md` (resolver lives as a bridge, not a
113
+ new plugin layer)
114
+ * `docs/adr/0007-diagnostic-isolation.md` (unresolved calls become
115
+ diagnostics, never crashes)