Skip to content
Agentmart
Submit a tool

AGENTS.md · kdlbs/kandev

AGENTS.md from kdlbs/kandev: 301 lines covering Repo Layout, Tooling, Scoped guidance, Best Practices and more.

Template by kdlbs

IndexedAGPL-3.0★ 1,003
Write a review

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.

We use your email only for this newsletter. Privacy

About

The AGENTS.md file that kdlbs/kandev (1,003 stars) keeps for coding agents. It has 301 lines in 6 sections: Repo Layout; Tooling; Scoped guidance; Best Practices; Maintaining This File; Remote cloud environment. Use it as a model for your own project's instructions.

Use cases: documentation

No 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

  1. Repo Layout
  2. Tooling
  3. Scoped guidance
  4. Best Practices
  5. Maintaining This File
  6. 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
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from kdlbs

Cite this page

AGENTS.md · kdlbs/kandev. Agent Mart. https://agentmart.dev/templates/kdlbs-kandev-agents-md (last updated 2026-10-24)