Thanks for your interest in improving Codeoid. This guide covers local setup, the development loop, and what we expect on a pull request.
Codeoid is a Bun daemon that wraps the Claude Agent SDK and
serves multiple frontends (web, Telegram) from one process. The terminal client
lives in a separate repo, codeoid-ui
(Rust/Ratatui) — see README § Terminal client.
src/
├── cli.ts # CLI entry: start, login, ls, new, attach, send, …
├── config.ts # ~/.codeoid/config.json + ~/.codeoid/.env + env vars
├── daemon/ # Bun.serve() server, SessionManager, Session, store, auth, memory
├── protocol/ # client↔daemon message types + permission scopes
└── frontends/ # web-ui (SolidJS at /ui), telegram (Grammy)
web/ # the SolidJS web app (built to web/dist, served at /ui)
A fuller map lives in CLAUDE.md.
- Bun v1.0+
- A ZeroID key for running end to end (
codeoid login— see the README) - Claude auth via
claude loginorANTHROPIC_API_KEY
bun install # install deps (also installs web/ deps)
bun run dev # daemon with --watch (hot reload)
bun run typecheck # tsc --noEmit — must pass
bun run lint # biome check
bun test # daemon + unit tests (src/tests, src/daemon)
# Web app (SolidJS) — from web/
cd web
bun run dev # vite dev server (standalone)
bun run typecheck # tsc -b --noEmit
bun run build # IMPORTANT: builds with --base=/ui/ (served under /ui)
bun run test # vitestThe web app is served by the daemon under
/ui/, so it must be built with Vitebase=/ui/.bun run buildalready does this — don't callvite builddirectly without the base or assets will 404.
- TypeScript, 2-space indentation. Match the surrounding code — comment density, naming, and idioms should read like the file you're editing.
- Keep changes focused; prefer small, reviewable PRs.
- Don't introduce new runtime dependencies casually — Codeoid ships as a small single-bundle binary and values a lean dependency tree.
bun run typecheckis clean.bun test(andcd web && bun run testif you touched the web app) passes.- New behavior has a test where practical — the daemon has good coverage of session lifecycle, attachments, memory, and protocol handling; add to it.
- If you changed the client↔daemon protocol (
src/protocol/), keep the Rust protocol crate incodeoid-ui(crates/codeoid-protocol) in lockstep — the wire format is shared.
- Functional bugs: open an issue with repro steps, expected vs actual, and
daemon logs (
/tmp/codeoid.logby default) when relevant. - Security issues: do not open a public issue — see
SECURITY.md.
By contributing, you agree your contributions are licensed under the project's MIT License.
This project uses the Developer Certificate of Origin (DCO) rather than a CLA — a lightweight, per-commit attestation that you wrote, or otherwise have the right to submit, the code you contribute.
Sign off every commit:
git commit -s -m "your message"That appends a trailer derived from your Git identity:
Signed-off-by: Your Name <you@example.com>
By signing off you agree to the DCO (full text at https://developercertificate.org/). If a commit is missing the trailer, amend it with git commit --amend -s (or git rebase --signoff for a range) before pushing.