AGENTS.md · kdlbs/kandev
AGENTS.md from kdlbs/kandev: 301 lines covering Repo Layout, Tooling, Scoped guidance, Best Practices and more.
Template by kdlbs
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/kdlbs/kandev/main/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documentation
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 301 lines
- File
AGENTS.md
Sections
- Repo Layout
- Tooling
- Scoped guidance
- Best Practices
- Maintaining This File
- Remote cloud environment
First lines (shown under the repo's AGPL-3.0 license)
# Kandev Engineering Guide > **Purpose**: Architecture notes, key patterns, and conventions for LLM agents working on Kandev. ## Repo Layout ``` apps/ ├── backend/ # Go backend (orchestrator, lifecycle, agentctl, WS gateway) ├── web/ # Vite/React SPA frontend (Go boot payload + WS + Zustand) ├── desktop/ # Tauri desktop shell around the native runtime ├── cli/ # npm publishing shim only (4-line exec of the Go binary) └── packages/ # Shared packages/types ``` ## Tooling - **Package manager**: `pnpm` workspace (run from `apps/`, not repo root) - **Backend**: Go with Make (`make -C apps/backend test|build`); local lint uses `bash scripts/lint-go-changed <changed-go-files>` (see `apps/backend/AGENTS.md`). Explicit full-backend lint remains `make -C apps/backend lint`. - **Launcher**: all four launch modes (`dev`, `start`, `run`, `service`) go through the native Go binary at `apps/backend/bin/kandev`; the launcher package is `apps/backend/internal/launcher`. `make dev` execs a copy of that binary (`bin/kandev-launcher`). - **CLI**: `apps/cli` is the npm-published shim only (`bin/cli.js` + `bin/native-shim.js`); its tests run on the Node built-in test runner (`node --test`). - **Frontend**: Vite/React SPA (`cd apps && pnpm --filter @kandev/web dev|build:vite|lint`; for direct web typecheck use `cd apps/web && pnpm run typecheck`) - **Web-only scripts** live in `apps/web/package.json`; run them from `apps/web` (for example `pnpm run i18n:check` or `pnpm run i18n:ratchet`) or use `pnpm --filter @kandev/web ...`, not from `apps/`. - **Desktop**: Tauri shell (`cd apps && pnpm --filter @kandev/desktop build|e2e`; Rust tests from `apps/desktop/src-tauri`) - **UI**: Shadcn components via `@kandev/ui` - **E2E**: Playwright (`cd apps/web && pnpm e2e:run` or the guarded `pnpm e2e:raw`). Local runners enforce one worker per shard and a memory-aware shard budget; do not pass all-worker overrides or overlap full suites. The `containers` project (gated on `KANDEV_E2E_CONTAINERS=1`, formerly `docker`) covers Docker, SSH, and Kind-backed Kubernetes executor scenarios — anything that needs a real Docker daemon on the host lives there. See `apps/web/e2e/README.md`. - **GitHub repo**: `https://github.com/kdlbs/kandev` - **Container image**: `ghcr.io/kdlbs/kandev` (GitHub Container Registry) - **Raw command output**: Run commands directly when output is consumed by a parser, upload, patch, `xargs`, or byte comparison; preserve stdout byte-for-byte and validate it before consuming it. Repository scripts under `scripts/` and `.github/scripts/` are repo-root-relative; run them from the root or pass an explicit path. When `functions.exec` starts parallel long-running commands, retain every returned `session_id` and poll each handle to completion; do not discard a handle and infer status from a duplicate run. ### Worktrees and commit hooks A fresh git worktree shares `.git/` but **not** `apps/node_modules/`. The missing install breaks not just the commit-msg hook (`pnpm exec commitlint` → `Command "commitlint" not found` / `ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL`) but any pnpm command — `vitest` fails with `Failed to resolve import "vitest"`, eslint similarly. Run `pnpm install --frozen-lockfile` from `apps/` once after creating the worktree, before running tests/lint/commits; subsequent pnpm commands work normally. --- ## Scoped guidance Architecture notes and per-area conventions live alongside the code they describe. Read the file in the directory you're working in: - `apps/backend/AGENTS.md` — Go backend: package structure (incl. `internal/office/` and `internal/agent/runtime/`), key concepts (orchestrator, workflow engine, agent runtime, lifecycle manager), execution flow, provider pattern, backups, testing conventions, Go lint limits. - `apps/backend/internal/agentctl/AGENTS.md` — agentctl HTTP server: route groups, adapter model, ACP protocol. - `apps/backend/internal/agentctl/server/api/AGENTS.md` — reverse-proxy body rewriting (`Accept-Encoding`), iframe-blocking header stripping. - `apps/backend/internal/integrations/AGENTS.md` — adding a new third-party integration (Jira/Linear pattern, both backend and frontend halves). The `/add-integration` skill mirrors this for scaffolding new integrations. - `apps/backend/internal/office/AGENTS.md` — Office (autonomous agent management): pointer to the `docs/specs/office/` spec set with status per file (a legacy 15-file table plus newer `requirements/`+`system-design/`-split entries, most recently task session termination and the seat-claim decision guard), plus local traps (run-vs-task-start, retired `heartbeat` source, continuation summary scoping, participant slate ownership, routine idle-skip, dual advancement signals). - `apps/desktop/AGENTS.md` — Tauri desktop app: runtime resources, Rust process lifecycle, packaging, signing, and smoke tests. - `apps/web/AGENTS.md` — Vite/React SPA frontend: shadcn imports, Go boot-payload hydration, store slice structure (incl. `office`), WS format, component conventions, TS lint limits. --- ## Best Practices ### Engineering Principles - Choose the simplest implementation that fully meets the current requirements. Avoid speculative abstractions, configuration, and indirection. - Grow the system in layers. Start from the smallest version that works end to end, and add each new capability on top of a product that already works. Never trade a working product for unfinished complexity. - Keep components modular and concerns clearly separated. - Prefer established, well-maintained libraries when they reduce overall complexity or improve reliability. Do not reimplement common functionality without a clear reason. - Lean on the dependencies already in the project before writing your own implementation or adding packages. Do not assume a library lacks a capability without checking its documentation and types. - Make architectural decisions for the long term. Do not accept a stopgap that only works for now and is meant to be replaced later. ### Engineering language Use English for all engineering text, including specs, plans, PRs, docs, comments, and docstrings. Translate non-English input before recording it. Only required product localization and product data can use another language. ### Commit Conventions (enforced by CI) Commits to `main` **must** follow [Conventional Commits](https://www.conventionalcommits.org/) (`type: description`). PRs are squash-merged - the PR title becomes the commit, validated by CI. Changelog is auto-generated from these via git-cliff (`cliff.toml`). See `.agents/skills/commit/SKILL.md` for allowed types and examples. The commitlint hook caps the header at **100 characters** (`type(scope): description`). The pre-commit prettier hook reformats staged TS/TSX files, and the `gofmt (backend)` hook can reformat staged Go files; if either hook changes files, the commit fails. Re-stage the reformatted files and create a new commit (don't `--amend`). Before committing, use `git diff --cached --name-only | grep '\.go$' | xargs gofmt -l`; run `gofmt -w` and re-add any files it reports. ### Release & Versioning Stable Kandev releases use one **SemVer** `X.Y.Z` across npm, Homebrew, Scoop, GitHub Releases, Desktop, and containers. Scheduled npm-only Nightlies use `X.Y.(Z+1)-nightly.sha<12-hex>` without moving any Stable channel. Both flows run in `.github/workflows/release.yml`. Required web, runtime, and desktop artifact uploads retry up to three total attempts with 30-second and 60-second waits; desktop matrix jobs continue independently, while publication still requires every target to succeed. A normal Stable release uses the protected `RELEASE_PR_BYPASS_TOKEN` environment secret only for its administrator PR merge. A Stable release is complete only after the GitHub Release, runtime npm, Homebrew, Scoop, and independently versioned plugin SDK publications succeed and are verified. The Go/npm SDKs share an independent version starting at 0.1.0; SDK signing/retention and OIDC publication run in separate protected jobs, including on backfill. Full details are in the `/release` skill — load it when cutting a release, changing version channels, or debugging release artifacts. Stable default runtime archives for npm, Homebrew, Scoop, winget, Chocolatey, and Desktop contain host binaries plus a helper manifest; use `-full` for offline CLI, while containers and npm Nightlies remain full. Contributor notices use `.github/workflows/notify-release-contributors.yml` and `.github/scripts/notify-release-contributors.py`. The standalone workflow supports latest-release selection, exact tags, and preview without posting. The Release checkbox defaults to off and posts only after GitHub Release, npm, Homebrew, Scoop, and public SDK verification succeed. Nightly, dry-run, desktop-validation, failed publication, and cancellation before notification start skip notices. Cancelling during posting can leave partial results; exact-tag manual reruns recover safely. The helper reads maintainers from `cliff.toml`, checks that each linked PR belongs to the selected tag, and skips bots, maintainers, and untrusted duplicate comments. Use the standalone workflow with the exact tag to recover a partial run without repeating publication. ### Code Quality Static analysis runs in CI and pre-commit. Each subtree has its own thresholds: - Go limits: see `apps/backend/AGENTS.md` (and `apps/backend/.golangci.yml`). - TypeScript limits: see `apps/web/AGENTS.md` (and `apps/web/eslint.config.mjs`). When you hit a limit: extract a helper function, custom hook, or sub-component. Prefer composition over growing a single function. Production comments state the invariant, not the argument for it: no `AC-NN` reference, no "Review round N", no "BLOCKING FINDING", no narration of a bug's history. That context belongs in the spec, the plan, or the PR body — a comment that has to argue the code is correct usually means the code is not constrained enough to be obviously correct. ### Testing Every code change must include tests for new or changed logic. Backend: `*_test.go` files alongside the source. Frontend: `*.test.ts` files for utility functions, hooks, API clients, and store slices. Exceptions: config files, generated code, React component markup. Use `/tdd` for test-driven development. ### Internationalization The web UI is localized with i18next (`namespace:key`). **All new user-facing copy must go through `t()` / `<Trans>`** — never a hardcoded literal — regardless of which directory you are in. This is enforced, not just requested, and the enforcement is now repo-wide: - **`i18next/no-literal-string` is a lint error on every `.ts`/`.tsx` file** (tests and `e2e/` excluded). It was scoped to `i18nGuardFiles` while the migration was in flight; measured at zero violations across all 2560 source files, it was widened, so "the file was not on the list" is no longer a way for copy to ship untranslated. - **`scripts/check-nonjsx-copy.mjs` scans the whole tree too**, by exclusion (`node_modules`, `dist`, `e2e`, `scripts`, `src/locales`, tests) rather than by allowlist, so a new directory is covered the day it is created. - **New code, everywhere** — `pnpm run i18n:ratchet` (pre-commit + CI) fails on a hardcoded string in a file you added, or on a line you changed. Untouched lines are never judged. - **`i18nGuardFiles`** (`apps/web/eslint.i18n.options.mjs`) survives as the migration record and the scope `pnpm run lint:i18n` previews. Append a path when you externalize one; never remove an entry — `check-guard-allowlist.mjs` rejects that. Three rules that cause silent, hard-to-find bugs when broken: never translate a string compared with `===` (type-to-confirm tokens become impossible to type); never call `t()` at module scope (it freezes at the boot locale and the pseudo-locale cannot detect it); never pass an English plural ending as a value — use `count` with `_one`/`_other`. `pnpm run i18n:check` enforces the last two. A clean lint is not proof a file is done: the rule only sees literals in JSX. The positions it cannot inspect — SCREAMING_CASE config tables, plain `.ts` helpers, parameter defaults, toast and setter arguments — are gated by `scripts/check-nonjsx-copy.mjs`, which runs inside `pnpm run i18n:check` and the new-code ratchet. Internal descriptive or error strings in plain `.ts` files are scanned as copy too. Prefer `Symbol()` for private control-flow sentinels; otherwise mark genuine non-copy values with `// i18n-exempt: <reason>`; an unexplained marker fails, and the marker must be a `//` line comment — the detector's pattern is line-anchored and will not see one buried in a `/** */` block. The pseudo-locale (Settings → General → Appearance, dev/e2e builds) is still the completeness check for copy no literal scan can see. **Translations gate the build.** `pt-pt`, `zh-cn`, `zh-hk`, `zh-tw`, `ja` and `ko` are complete, and `check-i18n-keys.mjs` now fails on a missing key, an extra key, a dropped placeholder, or a value left identical to English. Adding user-facing copy means adding it in seven languages; for the Traditional Chinese pair run `pnpm run i18n:zh-hant` rather than hand-translating. When the correct translation genuinely IS the English word, declare it in `src/locales/<locale>/_verbatim.json` with a reason — brand nouns, acronyms and placeholder-only frames need no declaration at all. Full guide: [`docs/i18n.md`](docs/i18n.md). UI punctuation is plain and intentional: do not use the Unicode em dash (U+2014) in user-facing copy or locale values. Use a period, colon, comma, semicolon, or parentheses instead. This applies to English, pseudo, and translated catalogs, rendered fallback strings. `pnpm run i18n:check` enforces it. Historical `CHANGELOG.md` entries are excluded because the changelog is generated release history and remains immutable. ### Knowledge - **Public docs:** Website-ready user documentation lives in `docs/public/**`. Use `/docs-maintainer` when a change affects CLI commands, config keys, install/deploy flows, workflows, executors, public APIs, screenshots, or user-facing terminology. Follow `docs/public/README.md` for content structure and long-page readability. - **Specifications:** Durable product context, requirements, and system designs live under `docs/specs/**`. New work uses `docs/specs/<system>/requirements/` and `docs/specs/<system>/system-design/`. Read `docs/specs/README.md` and the relevant file in `docs/specs/guide/`. Choose the owner from the durable contract, not the affected code layer. Keep one vertical requirement/design
Signals
- Stars
- 1,003
- Forks
- 164
- Open issues
- 95
- Last commit (this folder)
- Oct 13, 2026 (15 days ago)
- Last release
- Oct 23, 2026 (5 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- AGPL-3.0
- Repository
- github.com/kdlbs/kandev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from kdlbs
- 0.609score
kandev
kdlbs
Kanban workspace for running several coding agents in parallel, reviewing their changes and opening pull requests
AgentAFreshness: A★ 1K - 0.579score
Cursor rules · kdlbs/kandev
kdlbs
2 Cursor rule files from kdlbs/kandev: kandev-harness, kandev-pr-fixup.
TemplateAFreshness: A★ 1KCursor
Cite this page
AGENTS.md · kdlbs/kandev. Agent Mart. https://agentmart.dev/templates/kdlbs-kandev-agents-md (last updated 2026-10-24)