Releases: aahlijia/dekko
Release list
v0.43.45
dekko 0.43.45
Fifty commits since 0.43.13 — a sustained correctness/reliability pass driven by six rounds of real-world evaluation (awesome-go, claude-buddy, claude-code, cline, spring-boot, tensorflow, zed) against dekko's own CLI/MCP surface. Every fix below traces to a reproduced finding on one of those repos.
Resolver & call-graph correctness
- Cross-language false-positive call matches eliminated via language-family-aware resolver fallback.
- Rust: crate-root resolution hardened against decoy/vendor/fixture crates sharing a real crate's name — was causing near-total under-resolution on large repos (1/383 trait implementors found on one).
- C++: "most vexing parse" constructor-argument calls (
Type name(Ctor(), deleter);, idiomatic RAII) recovered — previously dropped from the call graph entirely. - JS/TS:
EventEmitter/EventTargetmethod names no longer misattributed as user calls;tsconfig.json/jsconfig.jsonpath aliases now resolve (0 → 2,024 import edges on one repo). - New arity-gated resolution: single-candidate calls now check argument-count plausibility before accepting, instead of accepting on name alone.
- TypeScript
type X = ...aliases are now indexed — previously invisible toquery_symbol/find_type_usages/heritage/unused, despite being the dominant type-declaration idiom in real TS/TSX code. get_context_packno longer returns false hop-2 callers/callees — a direction-less BFS traversal bug is fixed.
New capabilities
dekko sanity --all— repo-wide sanity sweep with--jobs/--max-names/--fail-on-unexplainedfor CI gating.dekko sanity --unused NAME— cross-checks a flagged-dead symbol against a grep sweep.dekko unused --suspect/--dispatch/--kinds {callables,types,all}— surfaces ambiguous-collision false negatives, dispatch-shaped candidates, and now scans types (including aliases) via heritage + type-usage evidence.dekko query throws/catches --lang— cuts cross-language noise on mixed-language repos.- A standing high-ambiguous-call-rate flag across
summary/doctor/hooks output. - Output self-disclosure hints throughout (
query symbol,context,sanity --group-by-file). - Session-start hook gains a hard token ceiling for oversized repos.
Reliability
- Daemon-routed
diff/affected/worksettimeout scaling recalibrated against real large-repo measurements; cold-rev-cache misses now default to all-core parallelism. - Daemon/status/process reliability batch: honest stop exit codes, worker-pool timeout hardening, a transient post-bind socket race now retried instead of failing.
Minor breaking change
dekko export --scoperenamed to--granularity(the old flag was widely misread as scoping to a symbol).--scopestill works as a deprecated alias.
Full changelog
v0.43.13
v0.43.13 — Resolver, sanity, and query correctness fixes
Ten patch releases' worth of correctness fixes to dekko's resolver, sanity, and query/context commands, plus one CI/pool-hang hardening pass and one packaging fix. No breaking changes; no schema changes to map.json.
Fixed
Resolver correctness
- Cross-language false matches: same-named symbols in unrelated languages no longer win a confident wrong resolution — candidates are now filtered by language (and language-family, e.g. C/C++, JS/TS/TSX) before falling back to the unfiltered set.
dekko ambiguousmisfiled noise-suppressed builtin-method calls (trim,.then(),get,resolve,create, ...) as genuine ambiguity, inflating reported ambiguity rates 2-3x on JS/TS repos.affected/worksetfalse-flagged tests via a Node builtin module-name collision (e.g. a repo's ownserver/path.tsmatching Node'spath).- Heritage resolution (
query subtypes/supertypes) lost same-named C/C++ base classes and Rust trait implementors toambiguous— whole-file#includehints and crate-aware import matching are now threaded into heritage resolution the same way call resolution already had them. - Rust resolver now follows
crate::Xinto custom-named crate roots ([lib] path = "src/foo.rs") and resolves bare cross-crateuse other_crate::X;imports against sibling workspace crates instead of assuming external.
dekko sanity
- Truncated grep sweeps (>5,000 lines) no longer silently report a false zero count; snippets are now length-capped; added
CAUSE_IMPORT_STATEMENTclassification for both single-line and multi-line destructured imports; own-definition-line exclusion now covers every same-named symbol, not just the query target.
dekko query/dekko context
- Importer listings now show the real bare import source instead of the resolver-internal
module/nameencoding. - Module-level pseudo-caller rows always show per-site line numbers when recorded, not just under
--sites. - The JS/TS caveat note is now conditional on the repo actually containing JS/TS.
Reliability
dekko map --jobs 0no longer hangs indefinitely past its documented 600s timeout under concurrent load — everyProcessPoolExecutorcall site now tears its pool down without waiting on wedged workers on timeout.dekko daemon stopno longer falsely reports success (exit 0) when the daemon is confirmed alive and busy.- README logo now renders correctly on PyPI (absolute asset URLs, not relative).
Added
dekko map --forceto explicitly opt into overwriting an existing full-repo map with a narrower subpath-scoped one (previously silent; now refused by default).scripts/sync_plugin_version.py+ pre-commit hook + release-workflow check, so the Claude plugin manifests can't drift out of sync withpyproject.tomlagain.
v0.43.2
Release v0.43.2
Previous release: v0.31.1
Another large release — twelve minor/patch versions of accumulated work landing in one tag. Headline additions are six new read-side analysis commands (module dependency graphs, error-flow tracing, env-var reads, dead-type detection) and four new Claude Code integrations built directly from real-world eval friction (dekko doctor, dekko sanity, and a dekko-review-context skill). Underneath that, several rounds of 7-repo real-world evaluation (awesome-go, claude-buddy, claude-code, cline, spring-boot, tensorflow, zed) drove a substantial correctness pass on the resolver, heritage/throws labeling, and dead-code detection.
✨ Highlights
dekko deps— module-level dependency graph. File-to-file import graph resolved from rawimport/use/#includesource text (full resolution for Python, JS/TS/TSX, Rust, Java, C/C++).--filefor one file's imports/importers/external sources,--cyclesfor circular-import detection,--topfor most-depended-on ranking,--export {mermaid,dot}.dekko query throws/catches/env/importers/peers/cohesion— a batch of new structural queries: exception/error-flow tracing (scoped pilot: full support for Python/Java/C++), static env-var read detection across all 9 Tier-1 languages, reverse shared-dependency lookups, callee-overlap peer detection, and intra-file symbol-cohesion clustering.dekko unused --kinds {callables,types,all}andworkset --type-impact— dead-type detection (classes/interfaces/enums/structs/traits, counting heritage and type-usage evidence) and combined call-graph + type-usage + heritage blast-radius reporting.dekko doctor//doctor— unified environment/install-state diagnostic. Catches PATH shadowing (a stale globally-installeddekkobinary silently producing wrong/empty answers — the single most-repeated friction point across past eval rounds), map freshness, MCP/plugin registration, hook install state, and theCLAUDE.mdpolicy block, each check degrading independently rather than aborting the rest.dekko sanity <target>//sanity— cross-checks acallers/usesresult against a scoped, word-boundedgrepsweep, classifying any grep-only miss's likely cause (qualified call, unsupported language, test-filter exclusion, generic name, or a bare-name mention in a nearby comment/docstring). Automates the manual spot checkdekko-verifyalready documented.dekko-review-contextskill — orchestratesworkset+impacted_tests+check_ambiguousto give PR-description and code-review flows a structural head start on a diff, ahead of a dedicateddekko reviewcommand (tracked as #14).
🛠 Correctness fixes
- Resolver / heritage / throws labeling:
.hheader files are now content-sniffed for C vs. C++ instead of always parsing as C (was silently mis-resolving heritage/call edges on LLVM/gRPC/Chromium/TensorFlow-style codebases); same-file TypeScript type aliases used withimplements/extendsnow resolve instead of being mislabeled(external); Javainstanceof-pattern-bound rethrow variables no longer mislabeled as a fake external type;dekko depsnow recognizes Rust crates whoseCargo.toml[lib] pathisn'tsrc/lib.rs(was undercounting resolved edges on ~90% of a real repo's crates in one eval case). - Dead-code detection:
dekko unusedno longer false-flags Java methods only reached viathis::method/Class::methodreferences, or module-levelconstvariables read as binary/ternary operands rather than called. dekko deps/query importers/query peers/query throws/query catches: fixed self-import false positives, ambiguous--filematches, env-write detection,--exactmatching, JS/TS side-effect/namespace imports, NodeNext/ESM relative-import resolution, several false positives, a truncation-footer miscount, and a leaf-function mislabeling on ambiguously-resolved calls.- MCP server robustness: every
ProcessPoolExecutorcall site now retries once at a reduced worker count onBrokenProcessPoolinstead of an opaque crash; a long-lived MCP server reading a newermap.jsonformat now gets a clear "restart the server" (or "regenerate the map," for a genuinely malformed doc) instead of a bareTypeError. - Disclosure fixes: files dropped by the 1MB size cap are now disclosed instead of silently omitted;
affected/worksetno longer overstate a cold-resolve file count;query catchesreflects the languages actually present in the scanned repo instead of a hardcoded exclusion list;throws/catchesdisclose Rust/Go/C's lack of a syntax-level exception concept in-CLI, not just in docs. --claude-md-uninstallnow deletesCLAUDE.mdwhen removing the dekko usage block leaves nothing behind, instead of leaving a 0-byte file.
⚡ Performance
.dekko/map.jsonon-disk size cut 5.6–7.9x on large repos (measured: zed 853.5MB→117.2MB, spring-boot 894.2MB→113.9MB, tensorflow 1212.4MB→217.6MB) via symbol-id interning and dropping pretty-printing, now thatmap.jsonhas no human-reader use case.- Resolver parallelism — call/ref/throws/catches resolution passes now use oversubscribed chunking plus a shared-index pool initializer, cutting run-to-run variance on heterogeneous-core machines from ~2.2–3.9x swings to a tight ~3% spread at a consistent ~3.3–3.5x speedup.
🔧 Internal
src/dekko/cli.py's repo-loading/map pipeline extracted intosrc/dekko/repo_ops.py(no behavior change); daemon auth token comparison now usessecrets.compare_digest, closing a timing side-channel.- CI now reports test coverage (
--cov=dekko, no gate yet) and runs a non-blockingpip-auditjob — which, until this release, false-failed on nearly every run because it was trying to audit dekko's own dev version against PyPI;uv export --no-emit-projectnow excludes the local package from the audited set.
Compatibility
- All new commands, hooks, and skills are opt-in — no behavior change for existing installs until you turn them on.
map.json's schema version (MAP_DOC_VERSION) advanced 4→10 across this range (id interning, then same-file type-alias tracking); existing files keep reading correctly via version-branch handling inload_map(), and a plaindekko mapre-run upgrades an already-mapped repo to the current format.- No breaking changes to existing MCP tool signatures.
Full changelog: see CHANGELOG.md for the complete per-version breakdown ([0.31.2] → [0.43.2]).
v0.31.1
Release v0.31.1
Previous release: v0.21.3
A large release — ten minor/patch versions of accumulated work landing in one tag. Headline additions are semantic search, daemon-mode CLI, and stronger dekko-usage enforcement for Claude Code sessions; underneath that, two full rounds of real-world evaluation (against awesome-go, claude-buddy, claude-code, cline, spring-boot, tensorflow, zed) drove a substantial correctness pass on the resolver, search relevance, and daemon subsystem.
✨ Highlights
- Semantic search —
dekko search "<query>"/search_codeMCP tool ranks every symbol by BM25 lexical relevance by default (no new dependencies), with opt-in--scorer embedding(offline hashing-trick embeddings,pip install dekko[search], no model download) and--scorer both(reciprocal rank fusion of both). - Daemon-mode CLI —
dekko daemon start/stop/statusruns a per-repo background process that keeps a warm map cache across CLI calls, so repeatedquery/outline/affected/diff/worksetinvocations skip re-parsingmap.jsonfrom scratch. Explicit start/stop, fails open to normal direct execution if the daemon isn't running. - Stronger dekko-usage enforcement — real sessions showed agents falling back to
grep/whole-file reads instead of dekko's structural tools even with hooks installed. Newdekko --claude-md-installwrites an idempotent usage-policy block into your project'sCLAUDE.md(a materially stronger lever than per-turn hook context), and a new opt-inpre-bashhook interrupts grep/find/cat fallbacks with the dekko equivalent instead of only nudging.
Also new
- Two new Claude Code skills:
dekko-verify(sanity-check suspiciously low/zero call-graph results before trusting them) anddekko-daemon(when to use daemon mode). query's:LINEdisambiguation qualifier for overloaded symbols,dekko[fastjson]extra for faster JSON I/O, cross-platform regen file locking,--dry-runfor install/uninstall flags.
🛠 Correctness fixes
- Resolver: eliminated false positives on built-in/global calls, fixed C++
#includedisambiguation, Go cross-package resolution, several bare-name self-resolution collisions, and receiver-typed method resolution. - Search relevance: fixed inconsistent scoring across differently-sized result batches, false
1.00scores on partial matches, and common-term-crowds-out ranking. - Change analysis:
diff/affectedno longer re-parse redundantly, and no longer report phantom "added" symbols from gitignore mismatches. - Fixed an O(N²) hang in
dekko leanon large repos, and JVM-source-root false positives in vendored-directory detection. - Multiple daemon reliability fixes, including two Windows-specific transport bugs and a race where
daemon stopcould report success before teardown actually finished.
⚡ Performance
- Server-side map caching, a disk-backed cache for resolved historical git revisions (speeds up repeated
diff/affected), and cached BM25 tokenization for repeat searches.
🔧 Internal
src/dekko/reorganized from 42 flat modules into six role-based subpackages (core/,render/,analysis/,daemon/,integrations/,storage/) — no behavior change for anyone using thedekkoCLI or MCP server. If you import dekko internals directly (e.g.from dekko.cli import mainrather than through the CLI/MCP), update to the new paths (e.g.dekko.integrations.cli).
Compatibility
- All new CLI subcommands, flags, and the
pre-bashhook are opt-in — no behavior change for existing installs until you turn them on. dekko[search]anddekko[fastjson]are new optional extras; the defaultlexicalscorer and base install are unaffected.- No changes to
map.jsonschema or existing MCP tool signatures.
Full changelog: see CHANGELOG.md for the complete per-version breakdown ([0.21.3] → [0.31.1]).
v0.21.3
Added
- README logo. A small eye mark (light/dark SVG variants under
assets/, swapped viaprefers-color-scheme) now heads the
README — a nod to the name itself ("dekko" is British slang for a
look or glance). - MCP Registry metadata. Added
server.jsonand anmcp-name: io.github.aahlijia/dekkomarker in the README so dekko can be
published to the official MCP
Registry.
feat: Release Version 0.21.2
[0.21.2] — 2026-08-03
Changed
- Claude plugin files moved into
integrations/claude/.
.claude-plugin/,commands/,skills/, and.mcp.jsonwere
cluttering the repo root; they're now grouped under
integrations/claude/(integrations/claude/.claude-plugin/,
integrations/claude/commands/,integrations/claude/skills/,
integrations/claude/.mcp.json), leaving room for other editor
integrations alongside it underintegrations/. Pure source-tree
reorg — the wheel'sdekko/_plugin/layout (what
dekko --claude-installactually uses) is unchanged, so installed
users see no difference.
[0.21.1] — 2026-08-03
Fixed
- Documented why
dekko://summarystays unbounded. An audit of
skills//commands/flagged the MCP resource's uncapped output as
an apparent inconsistency with thesummarytool's ~2000-token
default. It's intentional, not a bug: a resource is fetched by
reference on demand rather than re-sent as cache on every
conversation turn like a tool result, so the token-bloat concern
that justified capping the tool doesn't apply. Added a comment on
_handle_resources_readexplaining the asymmetry; no behavior
change (seetest_mcp_summary_resource_stays_unbudgeted).
[0.21.0] — 2026-08-03
Added
- Persistent
.dekko/.dekkoignore.dekko map --exclude GLOB
now also appends each new pattern to.dekko/.dekkoignore(created
and tracked alongsidenotes.json), so exclusions survive as
project state instead of shell history — a baredekko mapwith no
flags honors patterns persisted by an earlier--excluderun.
.dekkoignoreis hand-editable gitignore syntax (comments,
negation,**, trailing-slash dir patterns), parsed with
pathspec/gitwildmatch— a different matching engine than
--exclude's plainfnmatch, so files it skips are reported under
a distinct"ignored"skip reason (--excludekeeps"excluded").
Note the resulting matching-semantics divergence for
extension-filtered directory patterns:--exclude 'dir/*.py'
reaches intodir/sub/nested.pytoday (fnmatch isn't slash-aware),
but the identical string persisted to.dekkoignoreonly matches
the direct child once re-parsed as gitwildmatch.regen_map/
--if-staleauto-regen never re-persist; staleness from a hand-edit
falls out of the existing freshness check with no new provenance
field. - Community health files:
CODE_OF_CONDUCT.md,SECURITY.md,
.github/ISSUE_TEMPLATE/(bug report, feature request), and
.github/PULL_REQUEST_TEMPLATE.md. - README: a "Why dekko?" section with the headline benchmark
numbers and a comparison toctags/gtags-style navigation, plus
downloads/ruff badges. pyproject.tomlkeywords extended withllm-agents,
codebase-indexing,model-context-protocolto match the GitHub
topics used for discovery.
v0.20.0
Added
- Community health files:
CODE_OF_CONDUCT.md,SECURITY.md,
.github/ISSUE_TEMPLATE/(bug report, feature request), and
.github/PULL_REQUEST_TEMPLATE.md. - README: a "Why dekko?" section with the headline benchmark
numbers and a comparison toctags/gtags-style navigation, plus
downloads/ruff badges. pyproject.tomlkeywords extended withllm-agents,
codebase-indexing,model-context-protocolto match the GitHub
topics used for discovery.
[0.20.0] — 2026-08-02
Changed
- MCP agent surface trimmed 18 → 13 tools.
trace_path,
find_unused,stats,lean, andledgerare CLI-only now: every
MCP schema is paid in context tokens each session (~2.8k → ~2.1k),
and live agent transcripts (2026-07-10 A/B eval) never reached for
them. The CLI commands are unchanged. summaryandoutlineMCP tools default to a ~2000-token budget
(override withbudget). An un-cappedsummaryon a large monorepo
rendered ~30k chars as the session's first call and was re-read as
cache every turn.dekko summarygained a matching--budgetflag;
thedekko://summaryresource stays uncapped.- Symbol targets accept
::(file.py::name,Class::method) —
the Rust/C++ habit agents fall into — retried as both grammar
readings instead of dead-ending. dekko maptakes a true no-op fast path. When the incremental
cache determines nothing needs re-parsing, no file was added or
removed, and the on-disk map already matches this dekko build,
mapnow skipsresolve()/render/write entirely and prints
dekko: unchanged (N files, commit X) — nothing writteninstead of
unconditionally re-serializing MAP.md/map.json/shards on every
invocation.--fullalways bypasses this path.get_context_pack's tool description now shows a worked
target/taskexample (target="awardXp", task="who calls this"), the one parameter agents most often guessed wrong on.- CLI help documents the
--rootsplit:dekko map [DIR]takes
its root positionally; every other subcommand uses--root DIR.
Added
--cline-install/--cline-uninstallregister/remove the MCP
server in Cline'scline_mcp_settings.json(--cline-scope vscode|global,--cline-config PATHto override auto-detection,
--cline-forceto reset a malformed existing file instead of
aborting).dekko serve --mcpneeded no changes — it's a
client-agnostic stdio JSON-RPC server; only Claude Code's install
path (.mcp.json,claude mcp add) was ever Claude-specific. Cline
has no plugin system, so there is no/map-equivalent for it — only
the MCP tools are installed.- Near-miss suggestions on failed lookups.
query symbol(and the
MCP relation tools) list the closest symbols when a target resolves
to nothing;query usessuggests close external names. Keeps agents
inside the map instead of ejecting them to grep/full reads. - Top-level
const/letexports indexed as symbols (new
kind="variable") in JS/TS/TSX.export const jobs = [...]was
previously invisible to the symbol table — only arrow-function/
function-expression values were captured — soquery symbol jobs/get_callersreturned "no symbol matches" even for exported
data.dekko summary/MAP.md/the HTML map now report avariables
count alongside functions/methods and classes. interface/enum/struct/record/traitkinds. TS
interfaces/enums, Go structs/interfaces, Java interfaces/enums/
records, and Rust structs/enums/traits used to all come back as
kind: classfromquery_symbol/outline. Every renderer that
countedkind == "class"(dekko summary,MAP.md, the HTML map)
now counts the full set so the "classes" total doesn't undercount.ambiguous_incounts onquery symbol/get_callers. A call
whose name matches more than one repo-wide candidate was already
recorded in map.json but never loaded back for reading — a low
fan-in can now be qualified as "+N ambiguous call sites not counted"
instead of read as exhaustive.- Unparsed-language coverage note on "not found" replies.
query_symbol/outline/get_context_pack/get_callers/
get_calleesnow attach the same "N files unparsed" note
summary/statusalready show when a target resolves to nothing,
so a symbol that only exists in an unsupported file (e.g..astro)
doesn't read as a confident "doesn't exist." - Anonymous-callback callers in
get_context_pack. A call site
with no named enclosing function used to be demoted to a terser,
line-number-lessmodule_callerssummary line; it now also appears
in the maincallers:list with a real line number
(module_callersis kept for backward compatibility). referencededges (map.json schema v3 → v4). A function passed
by reference (an object-literal property value, array element,
bare call argument, or assignment/declarator right-hand side in
JS/TS/TSX) is now tracked separately from calls via a new
RawRef/referenced/referenced_in/referenced_outtable —
deliberately never merged withedges/calls_in/calls_out, so
"wired up as a callback" stays distinguishable from "invoked here."
query symbolreports areferenced-by: N (not called)line next
to fan-in/fan-out;get_callerson a reference-only symbol prints a
referenced (not called):section instead of the bare(no callers of X)line. Old (pre-v4) maps simply have empty referenced tables.
Fixed
- Stale map/cache could silently serve outdated extraction results
forever..dekko/cache.jsonand.dekko/map.jsonnow carry a
spec_hashfingerprint of the extraction queries, invalidating a
cached extraction (or flagging a map as stale) on any extractor
change — not just a released version bump.dekko status/
map_statusreport why a map is stale (reason: "version"vs.
"content"vs."missing") with an actionable "built by dekko X,
running Y" message for a version mismatch, instead of a silent
false "fresh." - Nested closures no longer inherit the enclosing class's
qualname/kind. Aconst helper = () => {}(or Rust nestedfn)
declared inside a method body was reported asClass.helper, kind
method— a closure-local helper mislabeled as a class member. The
container-qualification climb now stops dead at the first enclosing
function/method/closure in JS/TS/TSX and Rust. dekko unusedno longer flags pass-by-reference callbacks as dead
code. A callback wired up by name (JS/TS/TSX) and never itself
called was invisible toget_callers/fan-in/unusedentirely — the
newreferenced_intable (see Added) now counts it as used.- Every MCP reply built from a default (unspecified)
rootnow
echoes the resolved path. Omittingrootsilently answered
against the server's cwd — often the wrong repo in a multi-project
session — with no visible sign anything was off. A reply built this
way now opens with(root: /resolved/path — no 'root' argument was given; pass one to target a different repo), so a wrong-repo answer
is visually distinct from a correct one instead of looking identical. get_callers/fan-in undercounted calls made through a typed
variable, a function's own typed parameter, ornew X()
construction. The resolver's ladder now also matches a call
through one of the calling function's declared-typed parameters, and
credits a class's own constructor (JS/TSconstructor, Python
__init__, Java's same-named constructor declaration) when a call
resolves to that class —new Controller(...)no longer leaves
Controller.constructor's fan-in at 0. Scope note: this covers
declared parameter types only; local-variable type inference outside
a parameter list still isn't tracked.find_usagesgives no caveat when a shadowing in-repo symbol
returns a wrong or incomplete external-reference result. It
already refused cleanly when a query matched only an in-repo
symbol; now any query whose name collides with an in-repo symbol —
even one that still returns some external hits — carries a "this
result may be incomplete" caveat, in both text and JSON
(shadow_warning) output.get_context_pack's budget trimming could zero out the very
callers/callees a task asked about while its import list survived
untouched. Imports are now trimmed to empty first; callers/callees
are never the first thing cut under a tight budget.workset's impacted-tests listing ignored--budgetentirely.
The pytest-command hint now caps at 20 paths (+N more impacted test files not shown), and the JSON output reports a budget-fitted
impacted_testslist alongside a separateimpacted_tests_totalso
the two are never conflated.outlinegives no signal when a file's shape looks anomalously
thin for its size (e.g. a file built mostly from anonymous-
callback registration, which has few named symbols to hang an
outline row on). A file at least ~500 tokens with ≤8 named symbols
covering ≤15% of its full length now carries a caveat that the
outline may be missing most of the file's real content.- Ambiguous-symbol lookups dumped every candidate unconditionally
(a baremainin a Rust workspace with ~90 binaries listed all of
them). The candidate list is now capped at 20 with a "+N more
(qualify withfile.py:nameto narrow)" note. - Type symbols (class/struct/interface/enum/record/trait) with zero
call/reference edges read as "unused" even when heavily referenced
as a parameter, field, or return type.query symbolnow attaches
a caveat to a zero-fan type symbol explaining that call/reference
edges only track invocations, not type usage.
###...
v0.12.1
[0.12.1] — 2026-06-16
Added
- CI matrix (
.github/workflows/ci.yml): on every push/PR to
develop/main, the suite runs across
{ubuntu, macos, windows} × {3.10, 3.13}withruff check,
ruff format --check, andpytest. Windows iscontinue-on-error
(best-effort for 1.0.0); Linux/macOS are blocking. This turns
cross-platform correctness from opinion into a checked fact.
Changed
- Tier-1 grammars now install offline; Tier-2 moves behind
dekko[all]. A defaultpip install dekkoships the nine Tier-1
languages (C, C++, Go, Java, JavaScript, Python, Rust, TypeScript,
TSX) as individual, pinned grammar packages, so mapping them makes
no network call — no more runtime grammar download, offline
failure, or supply-chain surface from the catch-all pack. The ~55
generic Tier-2 languages now requirepip install dekko[all], which
pulls intree-sitter-language-pack; without it, a Tier-2 file is
skipped with a "needsdekko[all]" note rather than parsed. Grammar
resolution moved behind a newgrammars.get_grammarseam (cached, so
each grammar loads once). Map output for any installed grammar is
unchanged. - Release workflow is hardened around the version tag.
release.yml
still fires only on av*tag, but now rejects a tag whose version
does not match the built wheel (catches a forgotten version bump), and
the publish job carries an explicitrefs/tags/v*guard so it can
never run off a non-release ref. The workflow header documents the
gating and the one-time PyPI trusted-publisher prerequisite. dekko diffno longer shells out totar. The earlier-rev export
now capturesgit archive --format=tarand extracts it with the
stdlibtarfilemodule instead of piping to an externaltar
binary, removing an undocumented POSIX dependency (a step toward
Windows support). Extraction refuses path traversal (thedata
filter on 3.12+, an explicit guard on 3.10/3.11). Map output is
unchanged.
Fixed
- Windows: the
claudeCLI is now invoked by its resolved full path
rather than the bare name, so the plugin/MCP install and uninstall
commands launch aclaude.cmdshim thatsubprocesswould otherwise
fail to start. No change on macOS/Linux. - Windows: the session ledger now finds its transcript. The
~/.claude/projectsdirectory key now encodes backslashes and the
drive colon (not just POSIX/), matching Claude Code's per-platform
naming. Still best-effort — a miss degrades to an empty ledger.
Documentation
- README install & platform pass: the install section now states the
offline Tier-1 footprint, points topip install dekko[all]for the
Tier-2 languages, and notes the tested-platforms line (macOS/Linux;
Windows best-effort via CI). The "Language support" and "Development"
sections match the new packaging.
[0.11.0] — 2026-06-16
Active Context Layer
dekko grows from a pull context server into a session-aware push
layer: it ranks context by the live task, knows what the agent already
holds, and can deliver orientation through opt-in Claude Code hooks.
Added
- Task-aware ranking (
--task) onlean,workset, andcontext
(and the matching MCP tools): a free-text task description is blended
with structural centrality and the working diff so the most relevant
code survives a tight budget. Lexical and dependency-free; output is
byte-for-byte unchanged when no task is given. Newrelevancemodule
with a pluggableScorer(lexical now, embeddings a future drop-in). dekko lean --dense(and MCPdense): keeps full signatures only
on the most central symbols, names for the rest — the tersest
whole-repo map.dekko ledger(and MCPledger): projects the Claude Code session
transcript into "what is already in context" — files read, symbols
seen, and real tokens consumed (from the transcript's usage). dekko
persists no session state of its own, so it also sees direct reads.dekko hooks install|uninstall|run: opt-in push hooks merged into
project.claude/settings.json—session-start(steering preamble +
budget-capped lean map),prompt-submit(relevance-ranked pointer to
files not yet in context), andpre-read(non-blocking advisory to
outline a large file first,permissionDecision: "defer"). Every hook
is fail-silent and individually toggleable; uninstall touches only
dekko's entries.- Density metric (FR-D3):
Meterand the lean report now expose
signalsand tokens-per-signal, so output cost can be measured against
coverage. Abenchmarks/harness records the baseline reduction (dekko
mapping its own source: ~92% fewer tokens than whole-file reads).
[0.10.0] — 2026-06-16
Context & token management for agents: every list-shaped command can now
be held to a token budget, and new commands (outline, lean,
workset, orient) let an agent orient and scope a change without
reading whole files.
Added
dekko lean: a budget-capped, whole-repo navigation map for agents —
the middle ground betweendekko summary(~400 tokens) andMAP.md
(tens of thousands). Every in-scope file with its purpose, each
symbol's name (signatures on the most central, by fan-in × churn),
the coarse module-dependency edges, and an optional architecture
diagram, all shed in a fixed priority order to fit a hard token cap
that scales with repo size. The header reports what was elided and the
command to recover it. Prints to stdout, writes a file with
--output(e.g..dekko/LEAN.md, gitignored like other maps), or
emits--json; also an MCPleantool.- Universal token budgeting across
query,unused,affected, and
context. Each command now ranks its rows by relevance (production
before tests, more-connected before leaves), keeps as many as fit, and
self-meters: text output carries a(~N tokens · M of T omitted · raise --budget)footer and JSON carries a matchingmetaobject. A
--budgetflag capsquery/unused/affected; the relation MCP
tools gained an equivalentbudgetargument. dekko outline <path|dir>: a file's (or directory's) structure —
module purpose, each symbol's signature, doc first line, and line
number, with no bodies — at roughly a tenth the cost of reading the
file, plus afull ≈ X · outline ≈ Y (P%)size frame. Exposed as an
MCP tool whose description steers agents to prefer it before reading a
file.dekko workset [REV] | --symbol NAME: one budgeted bundle for a whole
change — the impacted test files (with a ready-to-pastepytesthint),
outlines of the touched files, and context packs for the most central
touched symbols. A single shared budget (default 6000) trims
detail-first so breadth survives a tight cap;--packscontrols how
many symbols get a pack. Also available as an MCP tool.dekko orient: an opt-in orientation layer. With no arguments it
prints a steering digest (a budgeted repo summary plus pointers to the
query surface); with--read PATHit emits a one-line nudge to outline
a file before reading it, but only when the file is large enough to be
worth it, and never blocks. Ships with adekko-orientskill and
documented (opt-in)SessionStart/PreToolUsehook snippets.- Optional accurate token counting for every
--budgetcap and the lean
map:pip install dekko[tokenizer]addstiktoken(o200k_base) and
dekko uses it automatically, replacing the default~4 chars/token
estimate (which systematically under-counts code). The default install
is unchanged — no dependency, byte-stable output.DEKKO_TOKENIZER= chars4forces the estimate back on for reproducible output even when
the extra is installed.
Changed
- Internal: shared helpers were promoted for reuse by the lean map —
textutil.dir_of,summary.file_churn, andexport.dir_graph(the
directory-level graph behind both MAP.md's diagram and the lean map's
module edges). No user-visible change.
[0.9.0] — 2026-06-14
Track B: the human-readable map. MAP.md is now a navigable document —
an overview with rankings and an architecture diagram, sharded pages for
large repos, hotspots and a freshness line — plus a standalone
interactive HTML export.
Added
MAP.mdnow renders purpose lines from the v3 schema'sdoc
fields: the Contents index shows each file's module purpose after
its symbol count, file section headers carry the same purpose, and
each symbol block shows its docstring first line under the
signature. Files with no doc, and parse-error files, render cleanly
with no placeholder noise.MAP.mdnow opens with an## Overviewsection: a per-directory
rollup table (files, symbols, internal vs. cross-directory call
edges, purpose), linked load-bearing and orchestrator rankings,
entry points, and parse errors. It is the markdown skin of
dekko summary— one computation, two renderings — so the digest
and the document always agree. Cross-directory edge counts are the
new "coupling at a glance" number.- The
MAP.mdOverview now embeds amermaidarchitecture diagram,
rendered natively by GitHub (no toolchain or network). A scale guard
tiers it down as the repo grows: the file-scope graph while it fits
under--max-nodes(300), then a directory-scope collapse, then a
one-line pointer todekko export --format mermaid. MAP.md and
dekko exportshare one graph generator. dekko map --shard auto|always|never(defaultauto): large maps
split into per-directorymap/<dir-slug>.mdpages withMAP.mdas
the index (Overview + linked TOC);autoshards once the single
document would exceed ~4,000 lines or 200 KB. Anchor ids are global,
so a ...
v0.7.0
0.7.0 — 2026-06-12
Close out the roadmap backlog: path tracing, a complete MCP surface, and
extractor/resolver correctness and performance work.
Added
dekko trace FROM TO— shortest call path(s) between two symbols over
the resolved graph (--max-paths K,--json). "No path" is a clean
exit1, not an error; unknown/ambiguous endpoints exit3/4like
the other read commands. It auto-regenerates a stale map.- Three new MCP tools so the server now mirrors the whole read surface
(nine tools):trace_path,find_unused, andstats. dekko map --jobs N— parallel extraction across a process pool
(0= all cores; sequential by default). Cache hits stay in-process and
results re-assemble in discovery order, so output is identical to a
single-worker run.dekko --claude-uninstall— reverses--claude-install, removing the
bundled plugin and its marketplace registration.dekko --mcp-uninstall— reverses--mcp-install, removing the
standalone MCP server (claude mcp remove dekko).
Changed
- The
.dekkoextraction cache is now tagged with thedekko
version and discarded on a version change, so an upgrade re-parses once
and always reflects extractor changes (no manual--full). - Resolver same-file and self-container checks use a pre-built
(name, path)bucket instead of rescanning every repo-wide candidate,
cutting the worst case for very common names. Resolution results are
unchanged. - Renamed from lidar-map /
lidarto dekko /dekkobefore the
first PyPI release. The PyPI package, CLI command, Python import package,
cache directory (.dekko/), and MCP server name all changed; no published
packages were affected. MAP.mdandmap.jsonare now written into the.dekko/directory by
default (alongside the cache) instead of the repository root;--output
still overrides the location.
Fixed
- Relative-import sources no longer double the leading dot
(from . import xrendered as..x); they now read.x/..x/
.pkg.xcorrectly in context packs. install.shinvokes the freshly installed CLI by absolute path — a
repo-local.venv/bin/dekkocould shadow it onPATHand break
--claude-install— and forces a rebuild with--refresh-package, so a
re-install at the same version no longer reuses a stale cached wheel.
Documented
- A "Limitations" section in the README: calls inside Rust macro bodies
are invisible to tree-sitter token trees, and dynamic dispatch has no
static call site.
0.6.0 — 2026-06-12
Graph analysis: turn the map into a source of code-health insight.
Added
dekko unused— symbols with no inbound calls, minus roots (main,
test files, decorated/annotated symbols, the language's public surface
— Rustpub, Go capitals, Javapublic, JS/TSexport— Python
dunders and__init__.pyre-exports, plus--roots GLOB). A class is
kept when any of its methods is called.--limit,--json; exits1
when any are found. It is call-graph based, so it reports leads, not
verdicts.dekko stats— file/symbol/edge totals, language mix, top fan-in/out
hotspots, and largest files (--top,--json).dekko export— render the call graph as--format mermaid|dot, at
--scope symbol|file, with a--max-nodesguard.Symbolnow recordsdecoratedandexportedfacts (Python
decorators, Rust attributes/pub, Java annotations/public, JS/TS
decorators/export), serialized into map.json.- A test asserting the four declared version strings (pyproject, both
plugin manifests, uv.lock) agree.
0.5.0 — 2026-06-12
Expose the map to agents over the Model Context Protocol.
Added
dekko serve --mcp— a hand-rolled MCP server speaking
newline-delimited JSON-RPC 2.0 over stdio, with no SDK dependency.
Six tools mirror the read surface:query_symbol,get_callers,
get_callees,get_context_pack,map_status,refresh_map.- The plugin ships an
.mcp.json(withcwdset to
${CLAUDE_PROJECT_DIR}), sodekko --claude-installwires the server
automatically. dekko --mcp-installregisters the server for non-plugin setups via
claude mcp add dekko -- dekko serve --mcp.
Changed
- Map regeneration was factored into a reusable
regen_maphelper so the
server can force a full rebuild.
0.4.0 — 2026-06-12
Change-awareness and incremental mapping.
Added
dekko diff [REV]— symbols added/removed/changed since a git rev
(default: the commit the map was generated at), each with its impacted
callers. Compares the working tree againstgit archiveof the rev;
"changed" means the symbol's source text differs.--limit,--json;
exits0(no differences) /1(differences) /2(bad rev).- A per-file extraction cache under
.dekko/, keyed on the provenance
content hash, so re-mapping only re-parses files whose contents
changed.dekko map --fullforces a cold rebuild.
Changed
- The first time the cache is written,
.dekko/is made self-ignoring
and appended to the repository.gitignore.
0.3.0 — 2026-06-12
From a one-shot generator to a queryable context service.
Added
- A subcommand CLI:
map,query,context,status. The v0.2 flags
(--map,--claude-install,--version) keep working as aliases. dekko query—callers,callees,symbol, andfilelookups
against map.json, with exit codes3(not found) and4(ambiguous).
Targets acceptname,Class.method, orfile.py:name.dekko context— a minimal signature neighborhood for editing a
symbol, with--hops Nand a--budget TOKENStrimmer.dekko status— freshness report from the provenance stamp; exits0
(fresh) /1(stale).- map.json provenance (document version 2): tool version, git commit,
discovery options, and per-file content hashes. - Read commands auto-regenerate a stale map (
--no-regento opt out);
dekko map --if-staleshort-circuits when the map is already fresh.
0.2.0 — 2026-06-11
Packaged for distribution.
Changed
- Converted from a
uv-run script into a pip-installable package:
tool/→src/dekko/, a hatchling build, and adekkoconsole
script. Distributed on PyPI as dekko. - The Claude Code plugin is embedded in the wheel and installed with
dekko --claude-install.
Added
--map [DIR] [SUBPATH],--output,--claude-install, and
--versionflags.- A GitHub Actions release workflow using PyPI trusted publishing.
0.1.1 — 2026-06-11
Fixed
/mappermission failure caused by command substitution in the
command preamble.- A Python 3.11+ f-string that failed to compile on the declared 3.10
floor. - Repeated tree-sitter query recompilation (now cached), cutting a
representative run from ~0.26s to ~0.17s.
Added
- A test that compiles every tool module against the declared Python
floor.
0.1.0 — 2026-06-11
Initial release: the dekko Claude Code plugin.
Added
- A
/mapcommand that scans the repository with tree-sitter and writes
MAP.md(files, functions, parameters with types, return types, and
bidirectional call links) plus a machine-readablemap.json— without
spending model tokens on parsing. - Tier-1 languages with full type fidelity (Python, Rust, C, C++,
JavaScript, TypeScript/TSX, Go, Java) and a generic Tier-2 fallback for
every other grammar in the language pack. - Best-effort static call resolution (same container → same file →
imports → unique repo-wide match); ambiguous calls are marked, never
guessed.