<div align="center">
  <img src="./public/app-icon.png" alt="TiyCode logo" width="120" />
  <h1>TiyCode</h1>
  <p><strong>An AI-first desktop coding agent.</strong></p>
  <p>Designed for a new coding collaboration paradigm. Humans express goals, constraints, and feedback through conversation, while agents take the lead in understanding, execution, and forward progress.</p>
  <p>
    <a href="./README_zh.md">简体中文</a>
  </p>
  <p>
    <img src="https://img.shields.io/github/actions/workflow/status/tiylabs/tiycode/ci.yml?branch=master&style=flat-square&label=CI" alt="CI" />
    <img src="https://img.shields.io/github/v/release/tiylabs/tiycode?style=flat-square&label=Release" alt="Release" />
    <img src="https://img.shields.io/github/downloads/tiylabs/tiycode/total?style=flat-square&label=Downloads" alt="Downloads" />
    <img src="https://img.shields.io/github/license/tiylabs/tiycode?style=flat-square" alt="License" />
    <img src="https://img.shields.io/badge/Rust-1.77%2B-orange?style=flat-square&logo=rust&logoColor=white" alt="Rust" />
    <img src="https://img.shields.io/badge/Platform-macOS%20%7C%20Windows%20%7C%20Linux-blue?style=flat-square&logo=tauri" alt="Platform" />
  </p>
  <br />
  <img width="1611" height="1032"  alt="TiyCode screenshot" src="https://github.com/user-attachments/assets/d30c016c-8642-43fe-bde9-0dac9feb2148" />
</div>

## Why TiyCode

TiyCode <sub>/taɪ koʊd/</sub> is built for people who want coding to feel native to the AI era. Conversation is not a companion to the workflow here, but the starting point of it. You define goals, constraints, and feedback. The agent understands context, uses tools, and drives execution forward inside a real workspace.

Around that collaboration model, TiyCode brings together Agent Profiles, workspace-based threads, code review, version control, terminal workflows, and an extensible runtime in one local-first desktop product.

## Highlights

- **AI-first coding collaboration.** TiyCode is designed around the idea that humans express intent through conversation while agents take the lead in execution.
- **Agent Profiles.** Mix models from different providers, tune response style, language, and custom instructions, and switch profiles flexibly for different kinds of work.
- **Persistent goal management.** Define long-running objectives for agents to pursue across multiple turns. An independent Judge subagent evaluates completion against actual file changes, command outputs, and commit history — eliminating self-attestation bias.
- **Custom Agents.** Create purpose-built sub-agents in Settings — each with its own name, system prompt, model tier, and allowed tools — then grant per-profile access and delegate work from the composer.
- **Three-tier model architecture.** Each profile supports a Primary model for core reasoning, an Auxiliary model for helper tasks, and a Lightweight model for fast operations — with automatic fallback chains across tiers.
- **Multi-provider support.** Connect to 13+ LLM providers out of the box — OpenAI, Anthropic, Google, Ollama, xAI, Groq, OpenRouter, DeepSeek, MiniMax, Kimi, and more — or add any OpenAI-compatible endpoint as a custom provider.
- **Workspace-centered execution.** Threads stay grounded in the local workspace and connect naturally to code review, version control, repository inspection, Git worktrees, and terminal workflows.
- **Task-aware execution.** Thread-scoped task boards, plan checkpoints, tool status events, and subagent progress make longer runs easier to follow and review.
- **Real-time execution streaming.** A rich thread stream event system delivers live updates — message deltas, tool calls, requested/active statuses, reasoning steps, subagent progress, and plan updates — all rendered through purpose-built AI Elements components.
- **Rich composer inputs.** Prompt input supports text, file/photo attachments, screenshots, slash command structured argument interpolation (`--key=value`, positional args, `{{placeholder}}` templates), and large-paste handling.
- **Steer & Queue.** While the agent is running, choose to steer the conversation mid-execution or queue a follow-up message for the next round — keeping you in control without interrupting the workflow.
- **Extensible by design.** Plugins, MCP servers, and Skills are treated as first-class building blocks through the `Extensions Center`.
- **ACP Server support.** TiyCode can run as a headless ACP (Agent Client Protocol) server via `tiycode acp --stdio` or `tiycode acp --http <addr>`, letting external tools and IDE plugins drive the agent runtime through a standard JSON-RPC protocol without the desktop GUI.
- **IM channel gateway.** Connect TiyCode to WeChat or WeCom so you can chat with the agent directly from your messaging app — scan a QR code to log in, send messages and attachments, and receive streaming responses without opening the desktop GUI.
- **Operator-friendly experience.** Slash commands with structured argument parsing, smart conversation titles, context compression controls, commit message generation, external terminal handoff including Ghostty, and compact workbench controls help the product feel fast and practical in day-to-day use.
- **Thread-level elapsed timer.** Track active execution time per thread, excluding pauses, with persistent tracking across sessions.
- **Built-in runtime path.** The main execution flow is `Frontend -> Rust Core -> BuiltInAgentRuntime -> tiycore -> LLM`.
- **Bilingual interface.** Full i18n coverage with English and Simplified Chinese, switchable at any time.

## Tech Stack

- **Desktop shell:** Tauri 2
- **Frontend:** React 19, TypeScript, Vite
- **Backend / native core:** Rust
- **AI runtime:** [`tiycore`](https://github.com/tiylabs/tiycore)
- **UI foundation:** Tailwind CSS v4, shadcn/ui (Radix UI primitives), Vercel AI SDK (UI types), Lucide React icons, Motion animations
- **Terminal:** xterm.js with addon-fit
- **Code highlighting:** Shiki
- **Persistence:** SQLite
- **Testing:** Vitest with `@vitest/coverage-v8` for frontend units, plus Rust integration tests under Cargo
- **Desktop integrations:** Tauri plugins for updater, autostart, window state, dialog, opener, and process control

## Quick Start

### Install via Homebrew (macOS)

```bash
brew tap tiylabs/tap
brew install --cask tiycode
```

To upgrade later:

```bash
brew upgrade tiycode
```

### Download from GitHub Releases

Pre-built binaries for macOS, Windows, and Linux are available on the [Releases](https://github.com/tiylabs/tiycode/releases) page.

> **macOS requirement:** TiyCode currently requires **macOS 10.15 Catalina or later**. We recommend using a newer supported macOS release for the best compatibility.
>
> **Windows requirement:** TiyCode currently requires **Windows 10 version 1809 (build 17763) or later**. We recommend using the latest available version of **Windows 10 or Windows 11** for the best compatibility. The desktop app also depends on the **Microsoft Edge WebView2 Runtime**. On Windows 11 it is typically preinstalled; on supported Windows 10 systems the Tauri installer usually takes care of installing or updating it. In offline environments, you may need to install WebView2 manually before launching the app.

### Build from Source

#### Prerequisites

Before running the app, make sure your environment has the toolchain needed for a Tauri 2 project:

- Node.js and npm
- Rust toolchain
- Platform dependencies required by Tauri

#### Run in development

```bash
npm install
npm run dev
```

#### Run the web UI only

```bash
npm install
npm run dev:web
```

#### Build

```bash
npm run build
```

#### Type-check the frontend

```bash
npm run typecheck
```

#### Run Rust tests

```bash
cargo test --manifest-path src-tauri/Cargo.toml
```

## Architecture at a Glance

TiyCode separates UI rendering, desktop orchestration, and agent execution into distinct layers:

```mermaid
flowchart LR
  UI[React + TypeScript UI] --> TAURI[Tauri Rust Core]
  TAURI --> RUNTIME[BuiltInAgentRuntime]
  RUNTIME --> CORE[tiycore]
  TAURI --> TOOLS[Workspace / Git / Worktree / Terminal]
  TAURI --> TASKS[Task Boards / Plans]
  TAURI --> CATALOG[Provider Catalog / Model Metadata]
  TAURI --> EXT[Extension Host]
  EXT --> PLUGINS[Plugins / MCP / Skills]
  TAURI --> ACP[ACP Server]
  ACP --> CLIENT[External Clients / IDE Plugins]
  CORE --> LLM[LLM Providers]
  TAURI --> DB[(SQLite)]
  UI -.->|Thread Stream| TAURI
```

At a high level:

1. The **React UI** handles workbench rendering, thread interactions, and streaming updates. AI Elements components render messages, code blocks, reasoning, tool calls, and plans in a purpose-built thread surface.
2. The **Rust core** is the source of truth for system access, policy decisions, persistence, and performance-sensitive local operations. Settings, threads, provider configurations, task boards, attachments, workspaces, and Git worktree metadata are persisted through SQLite and focused repository modules.
3. The **built-in runtime** manages agent sessions, helper orchestration, tool profiles, task-board/plan events, and event folding. The three-tier model plan (Primary / Auxiliary / Lightweight) is resolved from Agent Profiles at run time, with provider catalog metadata used for model capabilities and normalization.
4. The **extension host** integrates plugin, MCP, and skill capabilities into the desktop product model, governed by tool gateways, policy checks, and approval boundaries.

## Repository Structure

```text
src/
  app/           app bootstrap, routing, providers (theme, language), and global styles
  pages/         route-level surfaces such as onboarding and workbench entry points
  modules/       domain modules: workbench shell, onboarding, settings center, extensions center
  features/      platform-facing capabilities: terminal (xterm.js), system metadata
  components/    AI Elements — message, prompt input, code block, reasoning, plan, tool, confirmation, etc.
  shared/        reusable UI primitives (shadcn/ui), helpers, types, and config
  services/
    bridge/      Tauri invoke commands (settings, agents, threads, git, terminal, extensions)
    thread-stream/  real-time event streaming between Rust core and React UI
  i18n/          internationalization — English and Simplified Chinese locale files
src-tauri/
  src/commands/    Rust command modules
  src/core/        runtime/session orchestration, prompts, subagents, tools, workspaces, worktrees
  src/acp/         ACP server — transport, session map, protocol handlers, event/permission bridges
  src/extensions/  extension host, registries, and runtime integration
  src/ipc/         frontend event/channel bridge
  bundled-catalog/ provider model catalog snapshots bundled into the app
  migrations/      database migrations
  tests/           Rust integration tests
public/            static assets
```

## Development Commands

```bash
npm run dev        # Start the full Tauri desktop app
npm run dev:web    # Start the Vite frontend only
npm run build      # Build the desktop app
npm run build:web  # Type-check and bundle web assets
npm run typecheck  # Run TypeScript validation
npm run test:unit  # Run Vitest unit tests
npm run test:unit -- --coverage
cargo test --locked --manifest-path src-tauri/Cargo.toml
cargo fmt --check --manifest-path src-tauri/Cargo.toml
```

## Continuous Integration

Pull requests to `master` run GitHub Actions checks for commit message format, frontend type-checking, Vitest unit tests, web asset builds, Rust formatting, and locked Rust tests. An optional PR review workflow can run `TiyAgents/code-review-agent-action` when the required LLM secrets and variables are configured.

## Extensions Model

TiyCode treats extensibility as a first-class part of the desktop workbench.

- **Plugins** provide locally installed extension packages with hooks, tools, commands, and skill packs.
- **MCP** is modeled as its own extension category and managed by the Rust host, including user/workspace scoped configuration.
- **Skills** act as reusable agent capability assets and are indexed from builtin, workspace, or plugin sources.
- **Provider catalogs** are bundled as snapshots and can be normalized or refreshed so model capabilities stay aligned with runtime behavior.

These capabilities are surfaced through the `Extensions Center`, while runtime access is still governed by the host through tool gateways, policy checks, approvals, and audit boundaries.

## ACP Server

TiyCode can expose its agent runtime as an **ACP (Agent Client Protocol)** server, allowing external tools and IDE plugins to interact with TiyCode's agent capabilities through a standard JSON-RPC protocol — without requiring the desktop GUI.

### Transport modes

| Mode | Command | Description |
|------|---------|-------------|
| **stdio** | `tiycode acp --stdio` | Headless server over stdin/stdout. Stdout is reserved for ACP JSON-RPC; logs go to stderr. |
| **HTTP / WebSocket** | `tiycode acp --http 127.0.0.1:0` | Opt-in HTTP endpoint with WebSocket transport at `GET /acp` and a health check at `GET /health`. |

> The HTTP/WebSocket mode is **disabled by default** and only listens on loopback addresses. It does not perform ACP authentication and is intended only for trusted local processes. Do not expose it to non-loopback interfaces without adding an external authentication layer.

### CLI setup

To make the `tiycode` command available system-wide, install it to PATH via **Settings → General → ACP Server → CLI in PATH**, or manually:

```bash
# After installing TiyCode desktop app
sudo ln -s /Applications/TiyCode.app/Contents/MacOS/TiyCode /usr/local/bin/tiycode
```

On macOS/Linux you can also set `TIY_ACP_HTTP_LISTEN=127.0.0.1:0` before launching the desktop app to enable the HTTP/WebSocket ACP endpoint alongside the GUI.

### Key capabilities

- **Local execution.** File operations and terminal commands run inside TiyCode's agent runtime — the ACP client does not need to handle `fs/*` or `terminal/*` requests.
- **Streaming updates.** Clients receive live assistant messages, tool call status and results, plan updates, and file-change metadata.
- **Permission delegation.** When the policy engine requires approval, the client receives a `session/request_permission` request with `allow_once` / `reject_once` options. Unanswered requests are auto-rejected after 60 seconds.
- **Session mapping.** ACP `SessionId` maps to an internal TiyCode thread ID. Creating, loading, listing, prompting, cancelling, and closing sessions all bridge to the existing thread/run managers.

See [`docs/acp-server.md`](./docs/acp-server.md) for the full protocol and implementation details.

## Troubleshooting & Debugging

When something goes wrong — model requests not being sent, responses not arriving, or behavior not matching expectations — you can use the `RUST_LOG` environment variable to control log verbosity on the Rust / tiycore side.

| `RUST_LOG` value | What you get |
|---|---|
| `RUST_LOG=tiycore=debug` | Model request metadata and response content summaries — good for verifying which model is called, what prompt is sent, and whether a response is received. |
| `RUST_LOG=tiycore=trace` | Full SSE stream data including every chunk — useful when you need to inspect raw streaming payloads or diagnose streaming-level issues. |
| `RUST_LOG=debug` | Debug-level logs for **all** crates (noisy, but covers the entire stack). |
| `RUST_LOG=info` | Default level — informational messages only. |

### How to set it

**From source (development):**

```bash
# macOS / Linux
RUST_LOG=tiycore=debug npm run dev

# Or export before running
export RUST_LOG=tiycore=debug
npm run dev
```

**Installed app (macOS):**

```bash
RUST_LOG=tiycore=debug /Applications/TiyCode.app/Contents/MacOS/TiyCode
```

**Windows (PowerShell):**

```powershell
$env:RUST_LOG="tiycore=debug"
npm run dev
```

Logs are written to stderr / the terminal where the app was launched. For installed builds, you can also check the log file in the TiyCode data directory.

### Common scenarios

- **Model not responding:** Start with `RUST_LOG=tiycore=debug` to confirm the request is being sent and check the status code / error message in the summary.
- **Streaming looks broken or partial:** Use `RUST_LOG=tiycore=trace` to inspect the raw SSE events and see exactly where the stream stops or diverges.
- **Something deeper in the Rust core:** Try `RUST_LOG=debug` to capture logs from all crates, then narrow down the relevant module.

## Current Project Status

The repository already contains a substantial desktop shell, workbench UI, onboarding flow, settings center, built-in runtime path, Git/worktree drawer, task boards, attachments, provider catalog handling, and extension architecture. At the same time, it should still be read as an actively evolving project rather than a polished end-user release with exhaustive product documentation.

That means the best use cases today are:

1. Evaluating the architecture and product direction.
2. Running the desktop app locally from source.
3. Extending the workbench, runtime, or extension system as a contributor.

## License

This project is licensed under the Apache License 2.0. See `LICENSE` for details.

## Community

Join our WeChat group to connect with the author and other users!

<div align="center">
  <img width="320" alt="WeChat Group" src="https://tiy.ai/images/wechat-qrcode.jpg" />
</div>

## Acknowledgements

This project was inspired by the following projects and tools:

- [pi-mono](https://github.com/badlogic/pi-mono)
- [nanobot](https://github.com/HKUDS/nanobot)
- [lobe-icons](https://github.com/lobehub/lobe-icons)
- Codex
- ClaudeCode
