Every engineering team has that one project. The one where no one knows exactly what lib/helpers.js does. The one where onboarding takes two weeks because the documentation is a six-year-old Confluence page with broken screenshots. The one where you open the repo and feel the weight of someone else's decisions pressing down on you.
CodiLay starts from the belief that documentation has to be generated, not written — and that the generator should think like an investigator, not a summarizer.
"A detective doesn't read a crime scene and produce a bullet-point list. They trace the wires."
Reading code the way a human does
When an experienced engineer explores a new codebase, they don't read files alphabetically. They find the entry point, follow the imports, note what they haven't seen yet, and circle back. CodiLay replicates this exact behavior through a mechanism called wires.
A wire opens the moment the agent encounters something it hasn't documented yet — an imported module, a called service, an unknown dependency. That wire gets tracked, carried forward in active memory, and prioritized. The agent reorders its reading queue around it. When a later file finally explains the other end of that reference, the wire closes, the link gets recorded, and it retires from memory permanently.
| State | Meaning |
|---|---|
OPEN |
Reference seen, target unknown |
CLOSED |
Both ends documented, link formed |
Closed wires never re-enter the LLM context. This matters more than it sounds. Most documentation agents bloat their prompts as the codebase grows. CodiLay's context window stays lean by design — each LLM call only carries what's genuinely unresolved.
Triage before analysis
The first thing CodiLay does after reading the file tree is triage. A single LLM call looks at filenames and paths — no file content — and categorizes everything into three buckets: core, skim, and skip.
A Flutter project, for example, gets its ios/, android/, and build/ folders automatically moved to skip. The agent recognizes standard scaffolding and doesn't waste budget analyzing generated code. You get to review the triage decision before anything else runs.
Then the planner takes over — another single LLM call, this time with the curated file list — and produces a reading order. Files get ranked by how many open wires they're likely to close. The ones with no context yet go into a parked queue and get unparked as more of the codebase becomes clear.
Big files don't break it
Files over 6,000 tokens get a two-pass treatment. The first pass extracts only symbols and docstrings, builds a skeleton, and surfaces whatever wires are detectable from the shape of the code. The second pass reads the actual implementation chunk by chunk, filling in the skeleton with real understanding.
The threshold is configurable. The logic — read the shape before reading the substance — stays constant.
What comes out the other end
The final output is a CODEBASE.md — a living document with an overview, component sections for every file, a dependency graph rendered as a table, and an Unresolved References section that surfaces whatever wires stayed open at the end of the run.
That last section is genuinely useful. Open wires that point to external packages are expected. Open wires that point inward — to files that should exist but don't — are potential dead code or missing modules. The agent hands you the signal. What you do with it is up to you.
A machine-readable links.json comes alongside it — a dependency graph you can query, render, or feed into other tools.
When the run ends, the current git commit hash gets stored. Next time you run CodiLay, only the changed files get re-analyzed.
The web layer on top
Beyond the CLI, CodiLay ships with a web reader that turns the generated documentation into an interactive interface. At the base layer, it renders CODEBASE.md and the dependency graph statically. Above that, a chatbot answers questions scoped to the documentation context. When the documentation doesn't have the answer, a deeper agent escalates directly to the source code.
Any insight the deep agent surfaces gets patched back into the permanent doc. The documentation improves itself through use.
What it's built from
The core is Python 3.10+. Token counting runs through tiktoken. The CLI renders through Rich. A FastAPI backend serves the web UI and chat endpoints. Gitignore parsing uses pathspec for full glob compatibility. The LLM layer wraps a unified interface over multiple providers — the underlying model is swappable through config.
The honest part
Documentation tools tend to fall into one of two failure modes: they're too shallow to be useful, or they require so much setup that no one uses them. CodiLay's bet is that a system designed around genuine code comprehension — not just summarization — produces output worth the setup cost.
The wire model is the foundation of that bet. Treat every unknown as something to be resolved, carry only what's unresolved, and retire knowledge the moment it's complete. That's the circuit. CodiLay traces it until the map is done.
Top comments (0)