ion-design/ditto.site
GitHub: ion-design/ditto.site
ditto.site 是一个将公开网页 URL 确定性地转换为可运行的 Next.js 或 Vite React TypeScript 应用的编译器工具。
Stars: 542 | Forks: 75
# [ditto.site](https://ditto.site)
[](https://github.com/ion-design/ditto.site/actions/workflows/ci.yml)
[](LICENSE)
[](.nvmrc)
ditto.site 能将公开的 URL 转换为独立的 TypeScript 应用。它会捕获浏览器实际渲染的内容,然后默认生成确定性的 Next.js App Router 项目,或者根据需要生成 Vite React 项目。
该编译器并非 LLM 页面生成器。它是一条“捕获到代码”(capture-to-code)的流水线:输入相同的冻结捕获数据,即可输出在字节层面稳定的应用程序。
请在 [docs/METHODOLOGY.md](docs/METHODOLOGY.md) 中阅读公开的开发与评估方法。如需查看所有文档的索引,请参阅 [docs/README.md](docs/README.md)。
## 用法
- REST API:`https://api.ditto.site`
- MCP server:`https://api.ditto.site/mcp`
在 `https://www.ditto.site/api-key` 获取托管的 API 密钥,或者直接调用经过邮箱验证的注册流程:
```
curl -sS -X POST "https://api.ditto.site/v1/signup/request" \
-H "content-type: application/json" \
-d '{"email":"you@example.com"}'
```
通过电子邮件发送的验证链接会指向 `/api-key?token=...`,该地址会调用 `POST /v1/signup/verify` 并在验证成功后显示新的 `dtto_live_...` 密钥。
### REST API
启动一个克隆任务:
```
export DITTO_API_URL="https://api.ditto.site"
export DITTO_API_KEY="ditto_live_example"
curl -sS -X POST "$DITTO_API_URL/v1/clones" \
-H "authorization: Bearer $DITTO_API_KEY" \
-H "content-type: application/json" \
-d '{
"url": "https://example.com/",
"options": {
"mode": "single",
"styling": "tailwind",
"framework": "next"
}
}'
```
服务会返回一个排队的任务或一个内联结果。完成后的结果是一个文件映射——每个生成的文件都以其相对于应用路径的路径作为键名:
```
{
"jobId": "job_123",
"status": "succeeded",
"files": {
"package.json": { "type": "text", "content": "{ ... }", "bytes": 812, "sha256": "..." },
"src/app/page.tsx": { "type": "text", "content": "export default ...", "bytes": 2048, "sha256": "..." },
"public/assets/logo.png": { "type": "binary", "url": ".../files/public/assets/logo.png", "bytes": 5123, "sha256": "..." }
}
}
```
**使用官方解包工具将该 JSON 转换为磁盘上的项目**——在检出的 `ditto.site` 代码库并安装好依赖后,直接通过管道将响应传入,无需临时文件:
```
curl -sS -X POST "$DITTO_API_URL/v1/clones" \
-H "authorization: Bearer $DITTO_API_KEY" \
-H "content-type: application/json" \
-d '{"url":"https://example.com/","options":{"mode":"single"}}' \
| npm run --silent unpack -- - ./out
```
`npm run unpack --
` 会直接写入文本文件,并将二进制资源实体化(支持内联 base64,或使用 `$DITTO_API_URL` / `$DITTO_API_KEY` 从其 `url` 获取)。在 npm 分发方案准备就绪之前,该 CLI 包仅限代码库本地使用,因此暂不要使用 `npx ditto`。相关选项请参阅 [`packages/cli`](packages/cli/README.md)。
如果你收到的是一个排队的任务(`{ "jobId": "job_123", "status": "queued" }`),请轮询其状态,然后解包完成的结果——或者将整个应用作为单个归档文件下载:
```
JOB_ID="job_123"
# 轮询 status,然后解压已完成的 file map
curl -sS -H "authorization: Bearer $DITTO_API_KEY" \
"$DITTO_API_URL/v1/clones/$JOB_ID/result" \
| npm run --silent unpack -- - ./out
# ...或者以单个 archive 的形式获取整个 app
curl -L -H "authorization: Bearer $DITTO_API_KEY" \
"$DITTO_API_URL/v1/clones/$JOB_ID/bundle?format=tgz" \
-o ditto-clone.tgz
```
实用选项:
| 选项 | 取值 | 默认值 |
| --- | --- | --- |
| `mode` | `single`, `multi` | `single` |
| `styling` | `tailwind`, `css` | `tailwind` |
| `framework` | `next`, `vite` | `next` |
| `verify` | `true`, `false` | `false` |
| `asyncVerify` | `true`, `false` | `false` |
| `maxRoutes` | 数字 | 服务默认值 |
REST endpoint:
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| `POST` | `/v1/clones` | 启动克隆 |
| `GET` | `/v1/clones/:id` | 读取任务状态和元数据 |
| `GET` | `/v1/clones/:id/result` | 读取生成的文件映射 |
| `GET` | `/v1/clones/:id/files/*` | 流式传输单个生成的文件 |
| `GET` | `/v1/clones/:id/bundle?format=tgz` | 下载整个应用 |
| `DELETE` | `/v1/clones/:id` | 删除克隆及其相关产物 |
### MCP
将 MCP 客户端连接到托管的 Streamable HTTP endpoint:
```
{
"mcpServers": {
"ditto": {
"url": "https://api.ditto.site/mcp",
"headers": {
"Authorization": "Bearer ${DITTO_API_KEY}"
}
}
}
}
```
该 MCP server 专为 agent 设计。它会优先返回任务 ID、元数据、清单和文件引用,然后让 agent 仅读取它所需的文件。
核心 MCP 工具:
| 工具 | 用途 |
| --- | --- |
| `clone_website` | 启动克隆并返回 `{ jobId, status }` |
| `get_clone_status` | 轮询任务进度 |
| `get_clone_result` | 读取结果元数据(不含文件内容) |
| `list_clone_files` | 列出生成的文件路径、大小和哈希值 |
| `read_clone_files` | 读取选定的文本文件或二进制 URL |
| `get_clone_bundle` | 获取生成应用的下载 URL |
agent 提示词示例:
```
Use the ditto MCP server to clone https://example.com as a Next.js app.
Wait for the job to finish, list the generated files, then read package.json,
src/app/page.tsx, and src/app/ditto.css.
```
### 本地 CLI
```
# 这个 git clone 会获取 ditto.site 工具本身——你稍后 clone 到的
# codebase 的 URL,将作为 `npm run clone` 的参数传入。
git clone https://github.com/ion-design/ditto.site.git
cd ditto.site
npm ci
npx playwright install chromium
npm run clone -- https://example.com/ --out=./output
```
生成的应用会存放在 `output//app` 目录下。成功后,CLI 会打印一条可直接复制粘贴的摘要——包含一条带引号的 `cd … && npm install && npm run dev` 命令行,以及指向可安全编辑文件(`src/app/content.ts`、`src/app/components/`;应用的 `AGENTS.md` 中包含完整指南)的指引。
若要跳过复制粘贴直接进入运行预览状态:
```
npm run clone -- https://example.com/ --serve # clone, npm install, npm run dev
npm run clone -- https://example.com/ --open # ...and open the browser too
```
常见的本地变体命令:
```
npm run clone -- https://example.com/ --mode=multi
npm run clone -- https://example.com/ --styling=css
npm run clone -- https://example.com/ --framework=vite
npm run validate-site -- runs/site-example.com/
```
如果不指定 `--out`,运行结果会存放在 `runs///` 下,同时会有一个稳定的 `runs//latest` 符号链接始终指向最新的克隆,这样脚本和 `cd` 目标路径就不依赖于时间戳了。
### 本地 REST 和 MCP 服务
快速内联模式(无需数据库):
```
npm ci
npx playwright install chromium
SSRF_ALLOW_LOOPBACK=true npm run dev:api
```
随后调用本地 REST API:
```
curl -sS -X POST "http://localhost:8787/v1/clones" \
-H "content-type: application/json" \
-d '{"url":"https://example.com/","options":{"mode":"single"}}'
```
若要使用 Postgres 和 MinIO 运行排队服务:
```
docker compose up -d
cp .env.example .env
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ditto_site \
npm run db:migrate
npm run dev:api
npm run dev:worker
```
本地 MCP endpoint 为 `http://localhost:8787/mcp`。
## 产出内容
生成的应用包含:
- 可运行的 Next.js 或 Vite React 项目、
- 重建的页面和路由模块、
- 捕获的资源、字体、图标、清单文件和元数据、
- 可发现时提取的 `robots`、`sitemap`、`llms.txt` 和 JSON-LD、
- 用于识别交互和动画的轻量级 `ditto` runtime 辅助工具、
- 生成的 `AGENTS.md` 和 `ARCHITECTURE.md` 移交文档。
在验证阶段,交付输出位于 `generated/app/` 目录下;而在 CLI 交付时,输出位于 `//app` 目录下。
## 工作原理
```
URL
-> browser capture
-> normalized render IR
-> deterministic inference
-> app generation
-> asset materialization
-> optional validation
```
捕获操作会记录 DOM、计算样式、布局框、源元数据、CSS、字体、资源、屏幕截图、交互状态,以及在能被安全观测到的情况下的可复现动画。不支持重现的内容包括:应用逻辑、身份验证、支付、个性化功能以及任意第三方 JavaScript。
有关详细的服务 API,请参阅 [docs/SERVICE.md](docs/SERVICE.md)。有关部署信息,请参阅 [docs/DEPLOY.md](docs/DEPLOY.md)。有关编译器背后的开发方法,请参阅 [docs/METHODOLOGY.md](docs/METHODOLOGY.md)。
托管部署时应将 `/v1/clones*` 和 `/mcp` 置于 API 密钥身份验证的保护之下。
在数据库模式下当 `SIGNUP_ENABLED=true` 时,基于 Resend 的 `POST /v1/signup/request` 和 `POST /v1/signup/verify` 流程可以通过验证的电子邮件链接公开生成 `dtto_live_...` 密钥,同时仅存储密钥的哈希值。
除非有意进行直接的无身份验证生成,否则在生产环境中请保持 `SIGNUP_DIRECT_ENABLED=false`。
## 仓库结构图
| 路径 | 用途 |
| --- | --- |
| `compiler/` | 确定性捕获、推理、生成和验证 |
| `packages/core/` | 编译器适配器和文件映射辅助工具 |
| `packages/cli/` | `ditto` CLI —— 将克隆结果的 JSON 解包到项目目录树中 |
| `packages/api/` | Hono REST API 和 MCP server |
| `packages/db/` | Drizzle schema、迁移、repository 和队列封装 |
| `packages/storage/` | 本地及 S3/R2 的产物存储 |
| `packages/worker/` | 排队克隆运行器和可选的验证功能 |
| `docs/` | 方法论、服务、部署、发布和负责任使用文档 |
| `examples/` | 基准测试结果和视觉证据 |
## 负责任地使用
仅在你拥有检查、复制、转换和操作目标内容合法权利的情况下使用 ditto.site。请勿用于网络钓鱼、冒充、凭证窃取、绕过访问控制,或在未经许可的情况下进行大规模的第三方内容抓取。
请参阅 [docs/RESPONSIBLE_USE.md](docs/RESPONSIBLE_USE.md)。
## 许可证
[MIT](LICENSE) © ion-design 及其贡献者。标签:MITM代理, React, Syscalls, 代码生成, 渗透测试工具, 特征检测, 网络测绘, 网页克隆, 自动化攻击, 请求拦截