TKCode is a native desktop client for working with AI coding agents. It runs its agent loop in a separate Agent Host process, talks to models through three wire protocols, and keeps every session as a local, append-only JSONL file. The whole client is designed to publish as a NativeAOT binary.
Status: early development. The core pieces (protocol adapters, agent loop, session store, Host process, desktop UI) exist, but the app is not yet a finished product, and APIs and file formats may change.
- Project- and session-centric UI. Dark-first design with light and system-following themes, Chinese and English UI, and a command palette (⌘K) with nested pages and keyboard navigation.
- Multiple providers and models. Built-in provider catalog with one API key per provider, custom OpenAI-compatible and local endpoints, and hot-reloaded settings.
- Three protocol adapters: OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages, with thinking / reasoning replay and fast mode where the provider supports it.
- Coding tools for the built-in agent:
read,write,edit,ls,glob,grep,bash(with background tasks), task lists,web_fetch,web_search, and sub-agents. - External agent runtimes. Claude Code, Codex, and ACP agents found on the machine run inside TKCode and share its approval flow.
- Approvals and permission modes. Read-only actions inside the workspace pass; everything else can ask the UI first, once or for the whole session.
- Composer.
@file mentions,/commands and skills, Agent / Plan roles, and image attachments. Global assets live in~/.tkcode, project assets in.agents/. - MCP. stdio and HTTP servers from
settings.jsonor.mcp.json, with tools, resources, prompts, elicitation, and import / export. - Workbench. File tree, code and Markdown previews, and an integrated terminal (libghostty-vt, separate pty host that keeps sessions alive, search).
- Resumable sessions. Sessions are stored as JSONL trees under
~/.tkcode/sessions/and can be listed, renamed, pinned, reopened, and continued. - Streaming Markdown via StreamMark (code highlighting, Mermaid, LaTeX).
- In-app updates from GitHub Releases, plus a system tray icon.
The screenshots are rendered headlessly from a sample project. Regenerate them with tools/readme-screenshots.sh.
TKCode.Desktop ──(JSON-RPC 2.0 over stdio)──▶ TKCode.AgentHost
│ │
└──▶ TKCode.Rpc.Contracts ◀───────────────────┤
▼
TKCode.Agent.Coding sessions, tools, system prompt, AGENTS.md
▼
TKCode.Agent agent loop, tool contract, events
▼
TKCode.Ai message model, streaming events, wire adapters
| Project | Responsibility |
|---|---|
src/TKCode.Ai |
Unified message model, streaming events, OpenAI / Anthropic adapters |
src/TKCode.Agent |
Agent loop, tool abstraction, approval hook, steer / follow-up queues |
src/TKCode.Agent.Coding |
Coding session, JSONL session store, system prompt builder, built-in tools |
src/TKCode.Rpc.Contracts |
Host ↔ UI interfaces and DTOs, minimal JSON-RPC 2.0 implementation |
src/TKCode.AgentHost |
Standalone process that hosts sessions and translates agent events into RPC notifications |
src/TKCode.Config |
Settings types and parsing, shared by Host and Desktop |
src/TKCode.Runtimes |
External agent runtimes: Claude Code, Codex, ACP |
src/TKCode.Mcp |
MCP client: server configuration, connection pool, tool / resource / prompt bridging |
src/TKCode.Terminal.* |
Terminal: libghostty-vt core, PTY, pty host process and protocol, Avalonia view |
src/TKCode.Desktop |
Avalonia application: window, theme, views, view models, Host connection |
Dependencies point one way. TKCode.Ai, TKCode.Agent, and TKCode.Agent.Coding have no UI dependency and are marked IsAotCompatible.
-
.NET 11 RC2 SDK (
11.0.100-rc.2.26504.105or newer in the same major/minor release; pinned inglobal.json,latestFeatureroll-forward with prereleases enabled). Runtime Async is enabled for all projects, including NativeAOT builds. -
.NET 10 Runtime, required by AtomUI 6.2.6's isolated build tools. A .NET 10 SDK installation also provides it. Published NativeAOT applications include their runtime.
-
A Rust toolchain, used once to build the native LaTeX library for StreamMark.
-
StreamMark comes in as a git submodule (
external/StreamMark). ItsStreamMark.*packages are read from a local feed (packages/streammark, set innuget.config), so pack them first:git submodule update --init tools/streammark/pack.sh
-
AtomUI (
AtomUI.Desktop.Controls6.2.6) is consumed from nuget.org; Avalonia is pinned to 12.1.4, AtomUI's minimum. No source checkout is needed.
dotnet build TKCode.slnx
dotnet run --project src/TKCode.DesktopThe desktop build copies the Agent Host into the output directory's agenthost/ folder, and the app starts it on demand.
dotnet test TKCode.slnxThe Desktop tests render real components headlessly (Avalonia.Headless + Skia) and write PNG snapshots to the test output's snapshots/ directory, or to TKCODE_SNAPSHOT_DIR if set. tools/readme-screenshots.sh renders the README screenshots into docs/images/ the same way.
Both the desktop app and the Agent Host are published with PublishAot=true. On macOS you can build an app bundle:
tools/package_macos_app.sh osx-arm64 # outputs artifacts/TKCode.appOr publish directly:
dotnet publish src/TKCode.Desktop -c Release -r osx-arm64Smoke test a published build (runs the real app headlessly against the Fake provider):
artifacts/publish/osx-arm64/TKCode --smoke --out=frame.pngSettings live in ~/.tkcode/settings.json (JSONC, with a generated JSON Schema for editor completion). Set TKCODE_HOME to use a different directory. The file is hot-reloaded; invalid edits keep the last good configuration and show the error in the settings view.
API keys can be plain text, {env:VAR}, or $VAR. Saving from the UI sets the file mode to 0600. See docs/settings.md for the full specification.
| Document | Contents |
|---|---|
| docs/architecture.md | Technical decisions, layering, RPC, UI and theming, NativeAOT rules |
| docs/settings.md | settings.json format and merge rules |
| docs/design/builtin-agent-tools.md | Built-in agent system prompt and tool design |
| docs/design/external-agent-runtimes.md | Claude Code, Codex, and ACP runtimes |
| docs/design/composer.md | Composer: mentions, commands, skills, roles |
| docs/design/mcp.md | MCP client |
| docs/design/auto-update.md | In-app updates and the release pipeline |
| docs/terminal/ | Terminal architecture, pty host, and roadmap |
| docs/design/motion.md | Motion guidelines |
| docs/protocols/ | Wire protocol specs the adapters implement |
- Harden the protocol adapters and external runtimes against recorded provider traffic.
- Context compaction, session branching and fork, and a diff view for changes.
- Terminal: split panes, shell profiles, SSH, and agent integration (see docs/terminal/13-roadmap.md).
- Signed and notarized macOS builds.
Issues and pull requests are welcome once the project settles. Please keep these rules in mind:
- NativeAOT.
TKCode.Ai,TKCode.Agent,TKCode.Agent.Coding,TKCode.Desktop, andTKCode.AgentHostmust stay AOT-safe. Use source-generated JSON contexts and no reflection or runtime code generation. Check that an AOT publish produces zero IL/AOT warnings. - UI components. Use AtomUI through NuGet and its public theme tokens. Do not copy or modify AtomUI source.
- Strings. UI text comes from
src/TKCode.Desktop/Localization/strings.tsv. Regenerate the catalogs withtools/gen_strings.py; do not hand-edit the generated files.
TKCode is licensed under the Apache License 2.0.






{ "$schema": "./settings.schema.json", "model": "anthropic/claude-opus-5-5", // <provider>/<model> "language": "en-US", // zh-CN | en-US "theme": "system", // system | dark | light "providers": { // Built-in provider: only the key is required "anthropic": { "apiKey": "{env:ANTHROPIC_API_KEY}" }, // Custom OpenAI-compatible endpoint "my-gateway": { "name": "My Gateway", "api": "chat", // chat | responses | messages "baseUrl": "https://gw.example.com/v1", "apiKey": "{env:MY_GATEWAY_KEY}", "models": { "qwen3-coder": { "contextWindow": 262144, "reasoning": true } } } } }