内容
<div align="center">
# 蒂拉
**多机代理工作持久状态和制品存储**
Git 仓库外的基于内容寻址的制品。模式验证的记录。<br>
防止竞争的协调原语。
将它部署到您自己的 Cloudflare 账户,或在本地运行,无需任何基础设施。
> **状态:** [v0.2.7 发布](https://github.com/davebream/tila/releases/latest)。API 已经稳定到足以对抗的程度;预计在 v1.0 之前会有破坏性更改。
</div>
**适用于:** 框架作者、AI 自动驾驶仪构建者和小型团队(3 至 6 名工程师),他们的代理需要在多台机器上共享状态。
---
## 目录
- [为什么需要蒂拉](#-为什么需要蒂拉)
- [它是什么样子](#-它是什么样子)
- [自托管](#-自托管)
- [何时需要蒂拉](#-何时需要蒂拉)
- [快速入门](#-快速入门)
- [适用于 AI 编码代理](#适用于-AI-编码代理)
- [单体仓库包](#-单体仓库包)
- [相关项目](#-相关项目)
- [贡献](#-贡献)
- [FAQ](#-FAQ)
---
## 🪨 为什么需要蒂拉
代理生成的制品(计划、设计、分析报告、构建输出)迅速积累。如果将它们提交到您的仓库中,它们将在上下文中腐烂:编码代理将花费令牌解析过时的中间文件,您的 Git 历史记录充满了人类不会审查的噪音。如果忽略它们,它们将在克隆时消失,无法在机器之间共享,代理在上下文切换时将失去访问权限。单独的仓库只是将问题转移。
一旦您解决了“制品放在哪里”的问题,下一个问题就是共享状态。读取和写入管道配置、服务目录或功能标志的代理需要该状态是键入的、验证的并受保护以免并发写入,而不是分散在临时 JSON 文件中。
蒂拉同时处理这两者。制品存储基于内容寻址,具有重复数据删除、生命周期和全文搜索。每个记录写入都是模式验证的,并跟踪修订。协调使用先写者赢的围栏;过时的写入会得到 409,而不是静默覆盖。
---
## 🔬 它是什么样子
<p align="center">
<img src="docs/assets/tila-dashboard.png" width="100%" alt="蒂拉的只读仪表盘,显示一组编码代理在一个共享任务图上进行协调 — 一个史诗分成里程碑和任务,每个任务都有状态(完成、进行中、阻塞、失败、排队)和每个代理的所有权">
<br>
<sub>只读仪表盘:代理在共享状态、任务层次结构、实时状态和每个代理所有权上进行协调。</sub>
</p>
### 基于内容寻址的制品:不可变且重复数据删除
```bash
$ tila artifact put plan.md --kind=plan --resource=T-142 --fence=1
# => 上传制品:produced/T-142/a7f3b2c1d4e5.md(238 字节,sha256=a7f3b2c1)
$ tila artifact put plan.md --kind=plan --resource=T-142 --fence=1
# => 重复数据删除:相同的 sha256,无需上传
$ tila artifact search "auth migration"
# => 2 个资源中的 3 个结果
```
制品通过 sha256 键入。两次上传相同的内容,它只存储一次。跨索引内容进行全文搜索。工作程序和医生路径处理跨存储协调;保留行为仍在 v0.1 中不断演化。
### 类型记录:结构化状态,而不是临时 JSON
```bash
# 在 tila.schema.toml 中声明记录类型,然后读取和写入它们:
$ tila record set service api ./api.yaml
# => 创建记录 service:api revision=1 fence=1
$ tila record get service api
# => { "version": "2.3.1", "owner": "platform", "deploy_target": "prod-us" }
$ tila record patch service api --json '{"owner":"infra"}' --fence=1
# => 更新记录 service:api revision=2 fence=2
$ tila record history service api
# => r2 2026-05-16T10:35 patch {owner: "platform" → "infra"}
# => r1 2026-05-16T10:34 set (初始)
```
每次写入都经过模式验证。每次更改都需要一个围栏令牌。每次更改都跟踪修订。
### 协调:声明、门和围栏令牌
```
代理 A 代理 B
─────────────────────────────────── ───────────────────────────────────
$ tila task claim T-142 $ tila task claim T-142
=> fence=42 => 409 已被 agent-a 持有
$ tila artifact put plan.md \ (等待 A 释放)
--resource=T-142 --fence=42
=> ok $ tila task claim T-142
=> fence=43
```
先写者赢得围栏。过时的写入到蒂拉管理状态会得到 409 而不是静默覆盖。门在外部要求解决之前阻止就绪集选择。
### 核心概念
- **日志** — 每次状态转换的追加审计日志(谁在何时更改了什么,使用哪个围栏)
- **信号** — 轻量级代理间通知,不同于日志事件
- **存在** — 连接代理的 TTL 活动跟踪
- **模式演化** — 容忍读取,验证写入,差异模式用于迁移跟踪
- **记录** — 类型化的可变 JSON,具有可选的 R2 快照用于时间点恢复
---
## 🏠 自托管
蒂拉部署到您自己的 Cloudflare 账户(Worker + DO + D1 + R2)。没有蒂拉托管的控制平面用于您项目的数据。
- **每月 5 美元的 Cloudflare 付费计划涵盖大多数小型团队。** Worker、Durable Object、D1 和 R2 包含配额
- **免费层适用于评估和轻度使用。** 10ms CPU 每请求限制约束持续工作负载
- **本地模式。** `tila project create --local` 将所有内容存储在 `~/.tila/` 中,使用 bun:sqlite。不需要账户。核心任务、声明和存在工作流程在本地工作;完整的 CLI 兼容性仍在进行中
- **没有按席位定价。** 成本是您的 Cloudflare 账户中的使用成本
- **智能放置** 在 Cloudflare 路径上默认启用。两个路径共享 `@tila/ops-sqlite` 以实现实体、协调、制品、日志、门和信号逻辑
---
## 🧩 何时需要蒂拉
- 您的代理生成的制品(计划、报告、构建输出)不属于 git,但需要持久、可搜索且跨机器可访问
- 您的代理共享类型化状态(管道配置、服务目录、代理策略、功能标志),您希望进行模式验证、修订历史和审计日志
- 多个代理在多台机器上需要协调共享资源以防止写入
- 您希望审批门户将阻止的工作排除在就绪集之外
- 您已经超越了“一名开发者,一台机器,git 就足够了”,但不想操作 Postgres 或 Temporal
---
## 🤝 相关项目
这些项目解决了相邻的问题,与蒂拉配合良好:
| 项目 | 擅长领域 | 与蒂拉的关系 |
|---------|-------------------|---------------------|
| [beads](https://github.com/gastownhall/beads) | Dolt 驱动的分布式问题跟踪器,带有代理内存、依赖图、上下文压缩和跨机器同步 | 不同的层。Beads 跟踪代理应该执行和记住的内容;蒂拉存储共享的类型化状态和制品 |
| [claude-task-master](https://github.com/eyaltoledano/claude-task-master) | PRD 到任务分解,带有依赖图和复杂性分析 | 良好的搭配。Task-master 计划工作;蒂拉是下面的状态平面 |
| [ccpm](https://github.com/automazeio/ccpm) | GitHub 问题作为协调中心,带有自动工作树隔离 | 当 GitHub 已经是团队的项目中心时,是一个不错的选择 |
| [claude-mem](https://github.com/thedotmack/claude-mem) | 具有跨代理会话的向量搜索的语义内存 | 不同的关注点。内存和协调没有太多重叠 |
| [mcp_agent_mail](https://github.com/Dicklesworthstone/mcp_agent_mail) | 异步代理到代理消息传递,带有可搜索的线程对话 | 不同的层。代理之间的消息传递;蒂拉是代理的共享状态 |
| [aweb](https://github.com/awebai/aweb) | 代理消息传递、任务管理和文件预留在一个界面 | 有一些重叠。aweb 捆绑了多个关注点;蒂拉专注于类型化状态和围栏检查写入 |
**如果您有一名开发者、一台机器和一个代理,** 您可能还不需要蒂拉。上述任何工具可能是一个更好的起点。当多个代理可能写入同一资源时,蒂拉才有价值。
---
## For AI 编码代理
`tila-mcp-server` 和 `tila-sdk` 包发布在 npm 上(参见 [最新发布](https://github.com/davebream/tila/releases/latest))。MCP 注册表的 ID 为 `io.github.davebream/tila`(参见 [MCP 注册表](https://registry.modelcontextprotocol.io))。有三种连接方式:
**1. 一条命令**(自动检测您的编辑器)
```sh
tila mcp init
```
**2. 手动配置**
`.mcp.json`(Claude Code): `{ "mcpServers": { "tila": { "command": "npx", "args": ["-y", "tila-mcp-server"] } } }`
`.cursor/mcp.json`(Cursor)— 相同的形状。 `.vscode/mcp.json`(VS Code)— 使用 `"servers"` 代替 `"mcpServers"`。
> 如果您的项目使用 GitHub 身份验证(`.tila/config.toml` 中的 `[auth] mode = "github-repo"`),则不需要 `TILA_API_TOKEN` — 服务器会自动读取凭证。对于基于令牌的身份验证,请在上面的配置中添加 `"env": { "TILA_API_TOKEN": "<token>" }`。
**3. TypeScript SDK**
```sh
npm install tila-sdk
```
完整设置(身份验证模式、环境变量、资源):[`packages/mcp-server/README.md`](packages/mcp-server/README.md)
---
## 📥 安装
CLI 作为 `tila-cli` 发布在 npm 上(未作用域的 `tila` 名称被无关项目占用,因此未用于此 CLI)。全局安装:
```bash
npm install -g tila-cli
```
分发渠道:
| 方法 | 命令 | 状态 |
|--------|---------|--------|
| npm | `npm install -g tila-cli` | ✅ 可用(v0.2.7) |
| 直接下载 | 从 [最新发布](https://github.com/davebream/tila/releases/latest) 获取 `tila-<platform>`(+ `checksums.txt`) | ✅ 可用(v0.2.7) |
| curl(Unix) | `curl -fsSL https://github.com/davebream/tila/releases/latest/download/install.sh \| sh` | ✅ 可用(v0.2.7) |
| PowerShell(Windows) | `irm https://github.com/davebream/tila/releases/latest/download/install.ps1 \| iex` | ✅ 可用(v0.2.7) |
| Homebrew | `brew install davebream/tap/tila` | ✅ 可用(v0.2.7) |
**从源代码运行(用于开发):**
```bash
git clone https://github.com/davebream/tila.git
cd tila
pnpm install
pnpm --filter tila-cli dev -- --help
```
在源代码检出中使用 `pnpm --filter tila-cli dev -- <command>` 代替 `tila <command>`。
---
## 🏁 快速入门
### Cloudflare 路径
```bash
tila project create # 配置 Worker + DO + D1 + R2
tila task new "Migrate auth" # 创建一个工作单元
tila task claim T-abc123 # 获取围栏令牌
tila artifact put plan.md --kind=plan --resource=T-abc123 --fence=1
tila artifact search "auth" # 跨制品进行全文搜索
```
> GitHub 身份验证在 `tila project create` 期间自动配置。队友通过 `tila init` 加入 — 无需共享 API 令牌。
### 本地路径
```bash
tila project create --local # 不需要 Cloudflare 账户
tila record set service api ./api.yaml
tila task new "Migrate auth"
# 状态存储在 ~/.tila/<org>/<project>.db 中,制品存储在 ~/.tila/artifacts/
```
参见 [它是什么样子](#-它是什么样子) 以获取带有输出的详细用法示例。
---
## 📄 文档
- [CLI 参考](packages/cli/README.md):所有命令和工作流程
- [MCP 服务器](packages/mcp-server/README.md):42 种工具、身份验证模式、资源
- [TypeScript SDK](packages/sdk/README.md):客户端 API、声明、制品、错误处理
- [入门教程](docs/tutorial-getting-started.md):从 `tila init` 到 UI 仪表盘
- [架构](docs/02-ARCHITECTURE.md):完整的技术规范
- [路线图](docs/03-ROADMAP.md):v0.1 交付的内容和延期内容
- [持久化模式](docs/04-PERSISTENCE-SCHEMA.md):DO SQLite、D1 和 R2 布局
- [操作](docs/05-OPERATIONS.md):部署、监控、维护
- [搜索](docs/06-SEARCH.md):可搜索的制品类型和 FTS5 使用
- [GitHub 范围身份验证](docs/07-GITHUB-SCOPED-AUTH.md):GitHub 身份验证(默认)和仓库允许列表
- [记录](docs/08-RECORDS.md):类型化的可变 JSON 状态基元
- [共享项目共存](docs/09-SHARED-PROJECT-COEXISTENCE.md):在框架和直接使用之间共享项目
---
## 📦 单体仓库包
| 包 | 描述 |
|---|---|
| `@tila/schemas` | Zod 模式、规范 JSON 帮助程序、无运行时依赖 |
| `@tila/core` | 后端接口、围栏逻辑、模式演化 |
| `@tila/ops-sqlite` | 共享 SQLite 操作(实体、协调、制品、日志、门、信号、清理) |
| `@tila/backend-d1` | D1 后端(身份验证令牌、会话、幂等、仓库允许列表) |
| `@tila/backend-do` | Durable Object SQLite 后端(Cloudflare 路径) |
| `@tila/backend-local` | bun:sqlite 加文件系统后端(本地路径) |
| `@tila/backend-r2` | R2 制品后端(基于内容的地址块) |
| `@tila/worker` | Cloudflare Worker(Hono 路由、智能放置) |
| `@tila/ui` | Worker 提供只读 SPA |
| `tila-cli` | `tila` CLI 二进制文件(Bun 编译) |
| `tila-sdk` | 用于框架消费者的类型化 TypeScript 客户端 |
| `tila-mcp-server` | MCP 服务器将蒂拉公开为工具和选择加入资源 |
| `@tila/integration-tests` | 通过 `@cloudflare/vitest-pool-workers` 进行端到端测试 |
---
## 🛠 开发
```bash
pnpm install
pnpm dev:setup # 生成开发配置,应用 D1 迁移,播种项目 + 令牌
pnpm dev # 在 :8787 上启动 Worker
pnpm --filter @tila/ui dev # 在 :5173 上启动 UI(单独的终端)
bash scripts/dev-seed.sh # 用示例数据填充(实体、声明、存在、制品)
pnpm test # 运行测试套件
pnpm typecheck # TypeScript 类型检查
pnpm check # Biome lint 和格式检查
pnpm build # 生产构建
```
`dev:setup` 是幂等的:重新运行会清除本地状态并从头重新应用。`dev-seed.sh` 需要 Worker 正在运行。
---
## 贡献
欢迎贡献。参见 [CONTRIBUTING.md](CONTRIBUTING.md) 获取开发设置、提交约定和 PR 指南。
---
## 💬 FAQ
<details>
<summary><b>蒂拉是托管服务吗?</b></summary>
不。参见 [自托管](#-自托管)。
</details>
<details>
<summary><b>为什么选择 Cloudflare 而不是 Postgres?</b></summary>
可序列化、按项目状态、地理边缘放置和每月 5 美元的零运维。Postgres 很出色,但需要您来运维。
</details>
<details>
<summary><b>我可以在没有 Cloudflare 账户的情况下使用蒂拉吗?</b></summary>
是的。`tila project create --local` — 参见 [自托管](#-自托管) 获取详细信息。
</details>
<details>
<summary><b>这与 LangGraph 或 CrewAI 有何不同?</b></summary>
那些是代理编排框架。它们运行代理并在它们之间路由消息。蒂拉是这些框架下的状态和协调层。
</details>
<details>
<summary><b>这与 beads 有何不同?</b></summary>
Beads 是一个基于 Dolt 的分布式问题跟踪器,具有代理内存、依赖图、上下文压缩和跨机器同步。适用于为编码代理提供结构化任务感知能力。蒂拉是具有类型化记录、基于内容的存储、模式验证和围栏保护写入的状态和制品引擎。它们位于不同的层级:Beads 跟踪代理应该执行和记住的内容,蒂拉存储共享的类型化状态和制品。
</details>
<details>
<summary><b>为什么使用全文搜索而不是向量数据库?</b></summary>
蒂拉的搜索是关键字检索:“查找身份验证迁移”,而不是“查找与身份验证相关的文档”。FTS5 在 DO SQLite 中处理此问题,具有 BM25 排名、短语和前缀查询、亚毫秒延迟以及与制品写入的交易一致性 — 所有这些都无需额外的基础设施。如果您的工作流程需要对蒂拉制品进行语义搜索,消费框架可以通过制品 API 维护自己的向量索引。
</details>
<details>
<summary><b>如果我丢失了 Cloudflare 账户会怎样?</b></summary>
您的 Cloudflare 账户持有持久状态。备份由您负责。Durable Object SQLite 支持时间点恢复;R2 支持生命周期规则。v0.2 路线图添加了显式导出和备份命令。
</details>
<details>
<summary><b>稳定吗?</b></summary>
参见 [最新发布](https://github.com/davebream/tila/releases/latest) 获取当前版本。API 足够稳定,可以对抗,但预计在 v1.0 之前会有破坏性更改。请固定到特定版本。
</details>
<details>
<summary><b>什么许可证?</b></summary>
MIT。
</details>
---
## 许可证
MIT
</div>