Build CodeSpring
KINDAreplaces $53/mosaves $636/yrback to the verdict
A local planning tool whose hard problems are keeping the plan in the repository rather than in a database the agent cannot see, stopping a generated draft from being mistaken for an approved specification, and noticing when a plan has gone stale against the code it describes.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the planning tool and the export.
Get it nodejs.org, or your version manager. open ↗
Verify
node --version prints v22 or higher - installfree
Why The plan lives in the repository and task status is read from branches and commits, so a scratch folder will not exercise any of it.
Get it Use an existing project, or create one and make at least one commit.
Verify
git log prints at least one commit in the target directory - API keypay per call; a planning session is small change, and the monthly ceiling in this build is what keeps it that way
Why Generation is one call per feature and is the only part that leaves your machine or costs money.
Get it Create a key with the provider you prefer and set a spend limit in their console.
Verify
One feature produces a draft that parses against your schema - have readyfree or whatever you already pay
Why The whole last phase is about writing files that agent reads, and the only way to know it read them is to ask it to quote one back.
Get it Whichever agent or editor you already work in.
Verify
After an export, the agent can quote a line from your approved specification - decidefree
Why This path is the contract between the tool, git and the agent, and changing it later means rewriting every link.
Get it Write down the directory, the file naming rule and the frontmatter keys before any code.
Verify
docs/file-format.md exists and the indexer reads it as specification
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- features(id, slug, title, status, parent_id, map_x, map_y, file_path, created_at, updated_at) · the row is an index entry, the file is the record - edges(from_feature, to_feature, kind) · depends_on or splits_into, drawn on the map and used to order tasks - specs(feature_id, draft_path, approved_path, model_id, prompt_version, generated_at, approved_at, approved_by) - tasks(id, feature_id, title, acceptance, expected_files_json, status, branch, commit_sha, closed_at) - runs(id, feature_id, model_id, input_tokens, output_tokens, cost_minor, at) · every model call, so the month has a number attached to it - staleness(feature_id, checked_at, referenced_paths_json, repo_changed_at) · which approved plans describe code that has since moved - Nothing here is authoritative. Every row points at a file git already tracks, so deleting the database and reindexing loses precisely nothing.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
REPO_PATH | required | /home/you/code/your-project | The git working tree holding the plan. The tool refuses anything that is not one. |
PLAN_DIR | required | docs/plan | Directory inside the repository for feature files, drafts and approved specs. |
INDEX_PATH | required | ./.cache/plan-index.db | The SQLite index. Deletable at any time; reindex rebuilds it. |
MODEL_API_KEYsecret | required | sk-...redacted | The generation model. Set a provider-side spend limit as well. |
MODEL_ID | required | a text model identifier | Recorded with every draft, because a different model writes a different specification. |
MONTHLY_TOKEN_CEILING | required | 2000000 | Generation stops here for the month. Everything else keeps working. |
TASK_ID_PREFIX | required | TASK- | Used to match branches and commit messages back to tasks. |
The build, in order
The repository is the record
Every feature is a markdown file inside the target repository and the database is only an index of them.
The directory, the file name and the frontmatter keys are the contract everything else depends on.
Files
docs/file-format.mdsrc/store/files.tsProve the index is disposable by disposing of it in a test.
Files
src/store/index.tstests/reindex.test.tsterminalnpm run reindex
Titles change constantly and every link into the plan must survive it.
Files
src/store/ids.ts
done when · tick each as it passeswatch out- Keeping the plan in SQLite and exporting it on demand gives you two copies that disagree inside a day, and the agent always reads the exported one, which is the stale one. Write the file first, index second, and treat the database as something you can delete at any moment without asking anybody.
A map you can read without the tool
Features and their dependencies can be arranged quickly, and the arrangement lives in the feature files.
Two numbers a human can read beat a proprietary diagram document.
Files
src/map/persist.tsA cycle is a planning mistake, and it should be caught where it was made.
Files
src/map/graph.tstests/graph.test.tsMost of this work is faster with a keyboard than with a mouse.
Files
src/app/list/page.tsx
done when · tick each as it passeswatch out- Handing layout to a diagram library that stores its own document format means the map is unreadable and unmergeable outside your tool, and the first git conflict on it is unresolvable by a human. Store coordinates as two numbers in frontmatter and keep the edges as ordinary lines in a file.
A draft is not a specification
Generation produces a draft at a separate path that a person has to approve before anything downstream reads it.
The approved file is the one containing corrections somebody made by hand.
Files
src/generate/spec.tsApproval is the only moment a human is definitely in the loop.
Files
src/app/spec/[id]/page.tsxsrc/store/specs.tsSix weeks later you will want to know which prompt produced a strange section.
Files
src/store/specs.tstests/spec-approval.test.ts
done when · tick each as it passeswatch out- Regenerating straight over the approved file destroys the human edits, which are the only part of the document that was ever reliable, and you will not notice until the agent builds the wrong thing from a sentence you had already corrected. Generate to a draft path, diff, and make approval an explicit act that is recorded.
Tasks that point at code
Each task carries acceptance criteria and expected files, and its status is read from the repository rather than asserted.
A task without a falsifiable criterion is a note, not a task.
Files
src/tasks/derive.tsGit already holds the answer and does not forget.
Files
src/tasks/status.tstests/status.test.tsterminalgit log --oneline --grep=TASK-
Otherwise every regeneration resets the board.
Files
src/tasks/derive.ts
done when · tick each as it passeswatch out- A board whose columns are only moved by hand drifts from reality in about a week, and then every planning session starts with reconciling cards nobody has touched since the work shipped. Read what git already knows, and label any status a human typed as a human's claim rather than a fact.
Handing it over, and knowing what it costproduct builder
The plan leaves as the conventional files an agent already looks for, with a spend ceiling and a staleness report.
The closest file to the edited file is the one that wins.
Files
src/export/agents.tstests/export.test.tsterminalnpm run export
A rented model with no ceiling is a surprise bill.
Files
src/generate/cost.tsA stale plan is more dangerous than no plan, because it is confident.
Files
src/staleness.ts
done when · tick each as it passeswatch out- Exporting a zip of planning documents into a folder the agent has never been told to read means the agent never reads it, and you conclude the model ignores your plan. Write to the conventional path at the repository root, check it into git, and confirm by asking the agent to quote a line back to you.
That is the whole plan for CodeSpring. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Running the coding agent for you.
- A hosted board with collaborators.
- Semantic search over documentation.
- A protocol server exposing the plan.
- polished drag-and-drop mind-map canvas
- MCP server integration with Cursor/Claude Code/Codex
- semantic docs search
- hosted kanban sync across devices
- prebuilt skills library
- A per-task context bundle that lists only the files that task expects to touch
- A weekly diff of the plan against the repository, mailed to yourself, so staleness is noticed rather than discovered
- Estimates recorded at approval time and compared with what the work actually took
Need the files? The project pack on the verdict page hands your agent the whole brief · more dev tools.