Skip to content

CodeMap 1.6.0

Latest

Choose a tag to compare

@RaCzKoViC RaCzKoViC released this 27 Sep 13:06
· 8 commits to main since this release

CodeMap dla agentów AI (faza 15): serwer MCP z 19 narzędziami, generowany ARCHITECTURE.md i codemap check przed
commitem (hook pre-commit, także jako narzędzie agenta). Dokładność 2.0 (faza 14): monorepo w korpusie na poziomie
pakietów, martwy kod zgodny z knip (JS/TS) i vulture (Python), graf wywołań sprawdzany checkerem TypeScriptu,
propozycja reguł architektury z macierzy zależności do zatwierdzenia jednym kliknięciem. Wydajność (faza 13): CLI
4× szybsze, duplikaty i trend zdrowia w workerach, benchmark analizy dużych repozytoriów w CI. CLI respektuje
.gitignore.

Dodane — Faza 15 (CodeMap dla agentów AI)

  • Serwer MCP — codemap mcp [ścieżka] (cli/mcp.mjs, bez zależności): JSON-RPC 2.0 po stdio (negocjacja wersji
    protokołu 2025-06-18 / 2025-03-26 / 2024-11-05, na stdout tylko protokół), analiza startuje od razu, refresh po
    zmianach. Narzędzia tylko do odczytu: project_overview, find_files, code_search (BM25 z fragmentów plików),
    file_info, dependencies, dependents, change_impact (ścieżki albo base — ryzyko z powodami, pliki dotknięte,
    recenzenci), hotspots, findings (filtr reguły / ważności / ścieżki), cycles (pliki i pakiety), owners, tests,
    change_coupling, ask_map, test_skeleton; --osv dodaje vulnerable_dependencies. Teksty narzędzi domyślnie po
    angielsku (odbiorcą jest agent). loadCodeMap({modules}) / runAnalysis({modules}) doładowują moduły MCP; paczka npm
    je zawiera, a npm-pack sprawdza zainstalowany codemap mcp.
  • Generowany ARCHITECTURE.md (cli/architecture.mjs): CLI --architecture <plik>, wejście akcji architecture,
    narzędzie MCP architecture. Foldery pierwszego poziomu w kolejności z macierzy zależności (najpierw dostawcy;
    zależność pod prąd = ⚠ cykl), pakiety przy ≥ 2, punkty wejścia (importują, nikt ich nie importuje), rdzeń
    (najczęściej importowane), hotspoty z właścicielami, własność folderów z historii git, testy z konwencją
    (CM.TestGen), .codemap.rules.json z liczbą naruszeń, cykle plików i pakietów, ukryte sprzężenia. Bez daty —
    deterministyczny; PL/EN. CI publikuje ARCHITECTURE.md samego CodeMap w artefakcie codemap-report.
  • codemap check — kontrola przed commitem (cli/check.mjs): stan „po" = indeks gita (to, co wejdzie do commita,
    także przy git add -p i git commit -a — hook dziedziczy GIT_INDEX_FILE), stan „przed" = HEAD; oba czytane
    poleceniami tylko do odczytu (ls-files -s, ls-tree, cat-file --batch), bez checkoutu. Ta sama analiza dla obu
    (bez historii git i pokrycia — porównywalnie), ryzyko, zależni i osoby znające kod z CM.PRCore z historią git.
    Kod 1 przy nowych znaleziskach z --fail-on (domyślnie archviolation,cycles,pkgcycle; none = tylko informacja),
    --json, --install-hook / --uninstall-hook (cudzego hooka nie nadpisuje, respektuje core.hooksPath),
    narzędzie MCP staged_check. runAnalysis({loaded}) przyjmuje listę plików z pamięci, applyGitHistory osobno.

Dodane — Faza 14 (dokładność 2.0)

  • Monorepo w korpusie referencyjnym: Preact Signals (pnpm, 16 pakietów, zagnieżdżone utils/runtime, importy po
    nazwie przez paths) — krawędzie plików jak dotąd plus poziom pakietów: lista pakietów CodeMap (graph.packages)
    vs pliki package.json i krawędzie pakiet → pakiet (to, z czego powstaje macierz zależności) vs importy z metafile
    esbuilda (rozwiązane pliki i nazwy pakietów workspace'u). Wynik 100 % / 100 %. paths z tsconfig repozytorium
    trafiają do esbuilda (tsconfigRaw zastępuje plik). Preact Signals także w galerii przykładów.

  • Reguła „Nieużywane eksporty" (unusedexport, JS/TS) — js/deadcode.js (CM.DeadCode): eksport, którego żaden plik
    projektu nie importuje. Analizator zapisuje nazwy z klauzul importu na zależnościach (names; * as, require,
    import() = wszystko; export * = star przekazujący dalej żądania importujących barrel), buildEdges scala je na
    krawędzi. Jak knip: export {a} from jest użyciem a, typ w sygnaturze eksportowanej wartości należy do API, typy
    z JSDoc import('./x').T są zależnościami tylko typu, ./x bez źródła rozwiązuje się do x.d.ts; pomijane wejścia
    pakietów (exports / main / module / bin z mapowaniem dist → src, domyślne index/main/cli), testy, pliki bez
    importujących (reguła osieroconych plików), treść napisów i regexów. Korpus porównuje wynik z knip 6.38
    (te same wejścia po obu stronach, w monorepo konfiguracja per workspace): preact 17/17, ky 8/8, petite-vue 1/1,
    Preact Signals 33/33 — 100 % / 100 %. Tylko ESM: knip nie widzi użycia require('x').y, więc CommonJS pominięty.
    SARIF z linią pierwszego nieużywanego eksportu (tag dead-code).

  • Martwy kod w Pythonie (ta sama reguła, CM.DeadCode.analyzePy): funkcja albo klasa najwyższego poziomu, do której
    nazwy nic w projekcie się nie odwołuje — jak vulture (import to nie użycie; atrybuty, __all__, f-stringi tak;
    docstringi, komentarze i napisy wygaszone). Świadome różnice: pomijane definicje z dekoratorem (rejestruje je framework),
    dundery i nazwy importowane w __init__.py (API pakietu). Korpus: vulture 2.14 — Flask 3/3 i nowe repozytorium
    Requests 2.32.5 9/9 (importy vs grimp 55/55), 100 % / 100 %.

  • Dokładność grafu wywołań vs TypeScript (korpus): krawędzie wywołań CodeMap (tree-sitter z devDependencies +
    CM.SymbolsCore.resolveCalls, graph.addSymbols jak w aplikacji) porównane z checkerem TypeScript 5.9.3
    (każde wywołanie i new w ciele definicji, aliasy importów rozwinięte, przeciążenie → deklaracja z ciałem): ky
    98,1 / 100 %, petite-vue 98,1 / 100 %, Preact 98,9 / 100 %, Preact Signals 93,9 / 99,5 % (reszta to wywołania przez
    interfejs, gdzie CodeMap wskazuje implementację). Osobne progi w CI: --min-call-precision 0.9 --min-call-recall 0.97.

  • Propozycja reguł architektury z warstw macierzy zależności (CM.DSM.proposeRules): warstwa = jednostka macierzy
    (katalog pakietu / folderu dir/**, zagnieżdżone przed rodzicem, korzeń ** albo *, */*… na końcu; powtórzone
    nazwy z katalogiem), zakazy dostawca → konsumenci jako listy — tylko pary bez dzisiejszej zależności pod prąd, więc
    reguły od razu przechodzą i blokują nowe; istniejące zależności pod prąd = wyjątki do naprawy; noCycles, gdy nie ma
    cykli plików. Okno DSM: Zaproponuj reguły → podgląd JSON, wyjątki, Zatwierdź (jedno kliknięcie: reguły od
    razu w Inspect przez graph.rulesDraft + plik — zapis do folderu na żywo, CM.Live.writeFile, inaczej pobranie),
    akcja ChatBota proposeRules; CLI codemap rules [--packages | --folders --depth N] [--out plik]; narzędzie MCP
    propose_rules; ARCHITECTURE.md bez reguł podpowiada codemap rules. .codemap.rules.json: from / to mogą być
    listami (rozwijane na pary).

Poprawione — Faza 14 (graf wywołań)

  • Wywołania metod prywatnych this.#m() nie były rozpoznawane (private_property_identifier) — na ky kompletność
    61 % → 100 %.
  • Rozwiązywanie wywołań korzysta z nazw importów: goła nazwa f() idzie przez import tylko, gdy f jest z tego pliku
    importowane (albo * / default), także o poziom dalej przez barrel; wywołanie przez kropkę (s.member) — przez
    każdy import, ale nie dla metod wbudowanych (map.get(), arr.push(), console.warn()…), chyba że przez this. /
    self. (s.self); metoda-owijka m(){ m(x) } łączy się z importowanym m. Precyzja na monorepo 85,8 % → 93,9 %.
  • ./x bez pliku źródłowego rozwiązuje się do x.d.ts; typy z JSDoc import('./x').T są zależnościami tylko typu.

Zmienione

  • CLI respektuje .gitignore (cli/gitignore.mjs): pliki i katalogi ignorowane przez gita nie trafiają do analizy,
    map, ARCHITECTURE.md, propozycji reguł ani serwera MCP (lokalne build/, prywatne foldery). Składnia gita (!, / na
    końcu, zakotwiczenie, **, [...], \), zagnieżdżone .gitignore, wzorce z katalogów nadrzędnych przy analizie
    podkatalogu, .git/info/exclude; raporty pokrycia z ignorowanych katalogów nadal zbierane. Test porównuje wzorce
    z git check-ignore. --no-gitignore (i gitignore: false w runAnalysis) przywraca poprzednie zachowanie;
    stats.gitignored w raporcie JSON.

Zmienione — Faza 13 (wydajność)

  • CLI, GitHub Action, rozszerzenie VS Code i testy ok. 4× szybsze: moduły analizy działają w kontekście vm utworzonym
    z vm.constants.DONT_CONTEXTIFY (Node ≥ 20.18 / 22.8) — globalny obiekt jest zwykłym obiektem, bez interceptorów
    „kontekstyfikacji", przez które każde odwołanie do globalnych (np. Math.imul w odciskach duplikatów, wołane
    miliony razy) było ok. 10× wolniejsze niż w przeglądarce. Na repozytorium CodeMap: analiza 2,9 s → 0,7 s (odciski
    duplikatów 3,1 s → 0,19 s, graf 0,52 → 0,21 s); starszy Node — dotychczasowy kontekst.
  • Duplikaty kodu w aplikacji liczone w workerze (js/dup-worker.js, CM.Metrics.findDuplicatesAsync): odciski i
    parowanie poza wątkiem interfejsu, z pamięcią odcisków po skrócie treści pliku — ponowna analiza (tryb na żywo, drugi
    Inspect) liczy od nowa tylko zmienione pliki; bez Workera (CLI, testy) albo gdy worker nie wstanie — jak dotąd.
  • Trend zdrowia w workerze (js/trend-worker.js): graf i analiza każdego punktu poza wątkiem interfejsu (przy django
    to ok. 2 s na punkt), z pamięcią punktów per commit (localStorage, klucz z wersją CodeMap, ≤ 400) — drugie
    otwarcie bez liczenia; CM.HealthTrend.compute przyjmuje cache. Bez workera — w wątku strony jak dotąd. Smoke
    buduje w przeglądarce prawdziwe mini-repozytorium .git (obiekty zlib, SHA-1) i sprawdza całą ścieżkę.
  • Benchmark analizy na dużych repozytoriach (tools/bench-cli.mjs): pełny przebieg CLI na przypiętych django 5.1
    (6 743 plików, 648 tys. linii — 5,4 s, 329 MB) i vite 6.0.0 (2 219 plików — 1,5 s); czasy etapów, pamięć, szybszy z
    dwóch przebiegów; w CI (zadanie corpus) próg regresji 1,5× względem ostatniego zielonego main i ponad 1 s.