diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac4050d4..a9a128d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,16 @@ jobs: # thing a plain run will not exercise. - run: go test -race ./... + docs: + name: Docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + # Neither gate below reads Markdown, so a link broken by a file move and + # Chinese left in an English-only doc both land on main unnoticed. + - run: python3 scripts/check-docs.py + frontend: name: Frontend runs-on: ubuntu-latest diff --git a/CLAUDE.md b/CLAUDE.md index 1dafdb52..c676aeec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -73,6 +73,30 @@ codegraph explore "binding Service Install" - `docs/decisions/`:ADR。被推翻的决策保留原文并标注 Superseded 及其去向,不删改历史。 - `docs/internal/`:维护者视角的完工记录与验证清单。不放未实施的计划——那属于 issue。 +## 文档语言 + +对外文档一律英文,只有两处例外提供中文: + +| 位置 | 语言 | +| --- | --- | +| `README.md` | 英文;中文在 `README_ZH.md`,两份内容必须同步 | +| `docs/` 根的规范、`docs/decisions/` 的 ADR | 仅英文 | +| `docs/ai-agent-kit/` | 双语,`en/` 与 `zh/` 各自成套 | +| `CLAUDE.md`、`docs/internal/` | 中文。读者是维护者自己,双语只增加分叉成本 | + +英文术语以 `frontend/src/i18n.tsx` 为准,那是产品界面的真源:运行时 = Runtimes、 +配置模板 = Profiles、环境总览 = Environment overview、仅引导 = Guide only、 +激活步骤 = Setup steps。文档另起一套译法会让用户在界面和文档之间对不上。 +`Agent`、`Provider`、`Profile`、`technical-preview-unsigned`、`agents.lock.json` +这类标识符不译。 + +**界面文案的方向与文档相反**:`translate()` 只在 `locale === "en"` 时查表,否则直接 +返回中文 key,所以 i18n **以中文为源语言**。新增界面文案仍然先写中文 key 再补英文 +翻译,不要因为文档转英文就去改 key——那会连带改掉全部条目。 + +`python3 scripts/check-docs.py` 检查相对链接是否解析、英文文档里是否残留中文。 +改动文档后跑它;`.github/workflows/ci.yml` 也会跑。 + README、workflow、Taskfile 和 AI Agent Kit 里的命令必须对应当前仓库文件。`docs/internal/` 里引用已移除工具的命令块用 ` ```text ` 而不是 ` ```bash `,避免被当成可运行指令。 diff --git a/README.md b/README.md index e2e7674d..06d3a41c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,31 @@ # OneAgent -OneAgent 是一个本地 AI 开发环境激活器。React 向导和纯 Go CLI 共用同一套 Go 用例,负责检测 Agent、安装最新版本、探测 Provider、合并配置、创建备份并收紧权限。桌面应用使用 Wails v3 binding;生产进程不监听业务 TCP 端口。 +**English** · [简体中文](README_ZH.md) -OneAgent 不重新分发 Agent 包,也不捆绑 Node.js、系统 WebView、Git 或 API Key。缺少运行前置条件时返回明确错误和官方安装指引。 +OneAgent is a local AI development environment activator. A React wizard and a pure Go +CLI share the same Go use cases: detecting agents, installing the latest version, probing +Providers, merging configuration, creating backups, and tightening permissions. The +desktop app uses Wails v3 bindings, and the production process listens on no application +TCP port. -## 当前状态 +OneAgent does not redistribute agent packages, and it bundles no Node.js, system WebView, +Git, or API key. When a prerequisite is missing it returns a specific error and points at +the official install instructions. -当前版本为 `0.3.0-dev`,Wails 仍处于 Alpha,因此发布渠道只能是 `technical-preview-unsigned`。Python 迁移已经完成:受版本控制的旧实现、测试、PyInstaller/wheel 打包链路均已删除;普通构建、测试、运行和发布只需要 Go、Node、pnpm 11.17.0(构建前端)及目标平台 WebView。Aider 是唯一例外:只有用户选择安装 Aider 时,才要求本机已有 Python 3.12,OneAgent 不会下载或管理它。 +## Current status -## 架构 +The current version is `0.3.0-dev`. Wails is still in Alpha, so the only release channel +is `technical-preview-unsigned`. + +The Python migration is complete: the previous implementation, its tests, and the +PyInstaller/wheel packaging chain are all deleted. Building, testing, running, and +releasing need only Go, Node, pnpm 11.17.0 (to build the frontend), and the target +platform's WebView. Installing Aider needs Python 3.12, but no longer needs one +preinstalled — `uv` resolves it, reusing a matching local interpreter or downloading a +managed CPython into `~/.oneagent/runtimes/python`. Python never ships in a release +package. + +## Architecture ```text React + TypeScript + Vite @@ -25,21 +42,26 @@ Status / Provider / Agent / Profile services Pure Go CLI --------------------^ ``` -公开站不在这张图里,也不在这个仓库里:它已迁出到 -[MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site)。它从 -GitHub Releases API 读取下载信息,并把 `agents.lock.json`、`providers.lock.json` -vendor 到自己仓库,从发行 tag 刷新——所以改本仓库这两个文件不会自动改变站上内容。 +The public website is neither in this diagram nor in this repository. It moved to +[MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site), reads download +information from the GitHub Releases API, and vendors `agents.lock.json` and +`providers.lock.json` into its own repository, refreshed from release tags. Changing +those two files here does not change the site, and should not: the site describes what a +published version supports. -- `cmd/oneagent-desktop`:Wails 桌面入口。 -- `cmd/oneagent`:纯 Go headless CLI。 -- `internal/`:桌面和 CLI 共用的 Go 核心。 -- `frontend/`:React 应用;发行包只携带构建后的静态资源。 -- `agents.lock.json`:Agent 包名、来源、配置适配器和许可证的唯一清单;不固定 Agent 版本或包哈希。 -- `providers.lock.json`:内置 Provider 端点、fallback probe model 和公开站披露字段清单;桌面端用户 Provider 保存在本机 `~/.oneagent/providers.json`。 +- `cmd/oneagent-desktop`: the Wails desktop entry point. +- `cmd/oneagent`: the pure Go headless CLI. +- `internal/`: the Go core shared by desktop and CLI. +- `frontend/`: the React app. Release packages carry only its built static assets. +- `agents.lock.json`: the single manifest of agent package names, sources, config + adapters, and licences. It pins neither agent versions nor package hashes. +- `providers.lock.json`: built-in Provider endpoints, fallback probe models, and the + disclosure fields the public site reads. User-defined Providers live on the machine in + `~/.oneagent/providers.json`. -## 快速启动 +## Quick start -### 桌面应用 +### Desktop app ```bash cd frontend @@ -49,7 +71,9 @@ cd .. go run -tags wails ./cmd/oneagent-desktop ``` -生产构建需要目标平台的 Wails/WebView 依赖。Linux 当前使用 `gtk3` tag(Ubuntu 22.04 cleanroom);macOS 使用系统 WKWebView;Windows 使用 WebView2 Runtime。 +A production build needs the target platform's Wails/WebView dependencies. Linux +currently uses the `gtk3` tag (Ubuntu 22.04 cleanroom), macOS uses the system WKWebView, +and Windows uses the WebView2 Runtime. ### CLI @@ -57,33 +81,22 @@ go run -tags wails ./cmd/oneagent-desktop go build -o bin/oneagent ./cmd/oneagent ``` -Windows CMD: +On Windows CMD: ```cmd go build -o bin\oneagent.exe .\cmd\oneagent bin\oneagent.exe agent set codex --provider ppio --model your-model-id --api-key your-api-key ``` -日常使用优先通过桌面粘贴或已保存 profile 传递凭据;`ONEAGENT_API_KEY` 和 `--api-key` 仅保留给受控脚本。 `--registry` 默认是官方 npm registry,镜像必须显式选择并使用 HTTPS。 - -### 公开站 +Day to day, pass credentials by pasting into the desktop app or from a saved profile. +`ONEAGENT_API_KEY` and `--api-key` exist for controlled scripts. `--registry` defaults to +the official npm registry; a mirror must be chosen explicitly and must use HTTPS. -```bash -cd site -pnpm install --frozen-lockfile -pnpm test -pnpm run build -pnpm exec playwright install chromium -pnpm run test:e2e -``` +## Agents and Providers -站点只读取 GitHub Release、`agents.lock.json` 和 `providers.lock.json`,不读取本地 `release/`,也不依赖桌面构建环境。 +Automatically configured agents: -## Agent 与 Provider - -自动配置 Agent: - -| Agent | 包 | 安装器 | 协议 | +| Agent | Package | Installer | Protocol | | --- | --- | --- | --- | | Codex | `@openai/codex` | npm | Responses | | Claude Code | `@anthropic-ai/claude-code` | npm | Anthropic Messages | @@ -91,17 +104,28 @@ pnpm run test:e2e | Kilo CLI | `@kilocode/cli` | npm | OpenAI-compatible | | Aider | `aider-chat` | uv tool | OpenAI-compatible | -安装器默认让 npm 或 uv 解析最新版本。需要复现特定版本时可传 `--agent-version VERSION`,例如 `oneagent --agent codex --install-agent --check-agent-only --agent-version 0.145.0`。 +By default the installer lets npm or uv resolve the latest version. To reproduce a +specific one, pass `--agent-version VERSION`, for example +`oneagent --agent codex --install-agent --check-agent-only --agent-version 0.145.0`. -OpenClaw、Hermes、Cursor、Kiro、Gemini CLI、Cline、Continue、Qwen Code 和 Kilo VS Code 仅提供官方安装引导,不安装包、不写私有配置、不启动后台服务。 +OpenClaw, Hermes, and Cursor are guide only: OneAgent shows the official install steps +without installing a package, writing private configuration, or starting a background +service. -内置 PPIO、Novita,并支持在 Provider 页面增删改用户 Provider。配置后按 Agent 实际协议探测:Codex 使用 `/v1/responses`,Claude Code 使用 `/v1/messages`,其余自动配置 Agent 使用 `/v1/chat/completions`。协议不兼容时返回 `PROTOCOL_UNSUPPORTED`,不会先写入不可用配置。 +PPIO and Novita are built in, and Providers can be added, edited, or removed on the +Provider page. After configuration, each agent is probed over the protocol it actually +speaks: Codex via `/v1/responses`, Claude Code via `/v1/messages`, and the remaining +automatic agents via `/v1/chat/completions`. An incompatible protocol returns +`PROTOCOL_UNSUPPORTED` rather than writing configuration that cannot work. -Aider 的安装命令由 Go 后端固定为 `uv tool install --force --python 3.12 ...`,由 uv 复用或提供匹配的 Python。这条路径只在选择 Aider 时执行;缺少 `uv` 会返回 `PREREQUISITE_MISSING`。 +Aider's install command is fixed by the Go backend as +`uv tool install --force --python 3.12 ...`, leaving uv to reuse or supply a matching +Python. This path runs only when Aider is selected, and a missing `uv` returns +`PREREQUISITE_MISSING`. -## 开发与测试 +## Development and testing -Go 核心、发行工具和 RC 工具: +Go core: ```bash go vet ./... @@ -110,7 +134,8 @@ go test -race ./... go run honnef.co/go/tools/cmd/staticcheck@2025.1.1 ./... go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./... ``` -React/Wails 测试: + +React and Wails: ```bash cd frontend @@ -121,50 +146,70 @@ pnpm exec playwright install chromium pnpm run test:e2e ``` -每个 pull request 都会运行 `.github/workflows/ci.yml`:Go 侧是 `go vet` 加 -`go test -race`,前端侧是 `pnpm run test` 加 `pnpm run build`。 +Documentation: + +```bash +python3 scripts/check-docs.py +``` + +Every pull request runs `.github/workflows/ci.yml`: `go vet` plus `go test -race` on the +Go side, `pnpm run test` plus `pnpm run build` on the frontend side, and the +documentation link and language check. + +## Releasing -## 发行 +Release packages are built by `.github/workflows/build-artifacts.yml`, triggered manually +via `workflow_dispatch`. It builds x64 and arm64 Wails desktop binaries and pure Go CLIs +for macOS and Windows, packaging the macOS artifacts as `.app`. -发行包由 `.github/workflows/build-artifacts.yml` 构建,手动触发(`workflow_dispatch`)。 -它为 macOS 与 Windows 各构建 x64/arm64 的 Wails 桌面二进制和纯 Go CLI,macOS 产物打成 -`.app`。 +Wails is still in Alpha, so there is no Stable release, and no platform signing, +notarization, or store distribution. The signing gate for Stable is deferred to a later +release stage. -Wails 仍处于 Alpha,当前不发布 Stable,不做平台签名、公证或商店分发。Stable 的签名门禁 -保留在后续发行阶段。 +To reproduce an equivalent artifact locally, use the desktop build steps under Quick +start. Channel labels, the SHA-256 manifest, and third-party notices were once generated +by `cmd/oneagent-release`; that tool was removed in `23805b0` when the build moved to +GitHub Actions. Third-party attribution now lives in [NOTICE](NOTICE) at the repository +root. -本机要复现一份等价产物,见「快速启动」里的桌面构建步骤;发行渠道标签、SHA-256 清单和 -第三方 notices 曾由 `cmd/oneagent-release` 生成,该工具已于 `23805b0` 随构建流程迁移到 -GitHub Actions 而移除。第三方归属现在维护在仓库根的 [NOTICE](NOTICE)。 +## Documentation -## 文档 +`docs/` is layered by audience: current specifications at the root, architecture +decisions in `decisions/`, and maintainer history in `internal/`. -`docs/` 按受众分三层:根下是当前有效的规范,`decisions/` 是架构决策, -`internal/` 是维护者视角的历史记录。 +Outward-facing documentation is written in English. The AI Agent Kit is also available in +Chinese, and this README has a [Chinese version](README_ZH.md). `docs/internal/` is +maintainer-facing and stays in Chinese. -**使用与规范** +**Usage and specifications** -- [AI Agent Kit](docs/ai-agent-kit/00-start-here.md):从零配置一个 Agent 环境 -- [产品边界基线](docs/product-boundary-baseline.md):做什么、不做什么,以及为什么 -- [分发与合规政策](docs/distribution-compliance-policy.md):发行前的权利、安全与渠道要求 -- [公开站运营手册](docs/public-site-operations.md) +- [AI Agent Kit](docs/ai-agent-kit/README.md): set up an agent environment from scratch +- [Product boundary baseline](docs/product-boundary-baseline.md): what OneAgent does, what + it does not, and why +- [Distribution and compliance policy](docs/distribution-compliance-policy.md): the + rights, security, and channel requirements that precede a release +- [Public site operations](docs/public-site-operations.md) -**架构决策** +**Architecture decisions** -- [decisions/](docs/decisions/):ADR-001 至 ADR-009,含已被取代的决策及其去向 -- [Wails v3 / Go 迁移](docs/decisions/ADR-007-wails-v3-go-migration.md) -- [按 Agent 协议验证](docs/decisions/ADR-004-per-agent-protocol-verification.md) -- [凭据写入 Agent 配置文件](docs/decisions/ADR-008-credentials-in-agent-config-files.md) +- [decisions/](docs/decisions/): ADR-001 through ADR-009, including superseded decisions + and where they went +- [Wails v3 / Go migration](docs/decisions/ADR-007-wails-v3-go-migration.md) +- [Per-agent protocol verification](docs/decisions/ADR-004-per-agent-protocol-verification.md) +- [Credentials in agent config files](docs/decisions/ADR-008-credentials-in-agent-config-files.md) -**内部实现记录** +**Internal records** -- [internal/](docs/internal/README.md):各次改造的完工记录与验证清单。里面的命令可能已随 - 工具移除而失效,该目录的 README 说明了当前的替代入口。 +- [internal/](docs/internal/README.md): completion records and verification checklists for + past work. Commands in there may have stopped working as tools were removed; that + directory's README names the current entry points. -## 许可证 +## Licence -Apache License 2.0,见 [LICENSE](LICENSE)。 +Apache License 2.0. See [LICENSE](LICENSE). -[NOTICE](NOTICE) 列出随二进制分发的第三方组件及其许可证,以及运行时下载但不再分发的 -Node.js、uv 和 Agent 包。界面中显示的各 Agent 官方标识属于 nominative use,用于指明某一 -行对应哪个工具,不表示背书或关联,商标归各自所有者。 +[NOTICE](NOTICE) lists the third-party components distributed with the binary and their +licences, along with Node.js, uv, and the agent packages that are downloaded at runtime +rather than redistributed. Agent marks shown in the interface are nominative use, +identifying which tool a row refers to. They imply no endorsement or affiliation, and each +mark belongs to its owner. diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 00000000..07226abc --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,160 @@ +# OneAgent + +[English](README.md) · **简体中文** + +OneAgent 是一个本地 AI 开发环境激活器。React 向导和纯 Go CLI 共用同一套 Go 用例,负责检测 Agent、安装最新版本、探测 Provider、合并配置、创建备份并收紧权限。桌面应用使用 Wails v3 binding;生产进程不监听业务 TCP 端口。 + +OneAgent 不重新分发 Agent 包,也不捆绑 Node.js、系统 WebView、Git 或 API Key。缺少运行前置条件时返回明确错误和官方安装指引。 + +## 当前状态 + +当前版本为 `0.3.0-dev`,Wails 仍处于 Alpha,因此发布渠道只能是 `technical-preview-unsigned`。 + +Python 迁移已经完成:受版本控制的旧实现、测试、PyInstaller/wheel 打包链路均已删除;构建、测试、运行和发布只需要 Go、Node、pnpm 11.17.0(构建前端)及目标平台 WebView。安装 Aider 需要 Python 3.12,但不再要求本机预装——`uv` 自己解析解释器,本机有匹配版本就复用,否则下载一份托管 CPython 到 `~/.oneagent/runtimes/python`。Python 不进发行包。 + +## 架构 + +```text +React + TypeScript + Vite + | + | generated Wails bindings + v +Status / Provider / Agent / Profile services + | + v + Go application use cases + | + catalog / provider / install / config / profile / securefs + +Pure Go CLI --------------------^ +``` + +公开站不在这张图里,也不在这个仓库里:它已迁出到 +[MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site)。它从 +GitHub Releases API 读取下载信息,并把 `agents.lock.json`、`providers.lock.json` +vendor 到自己仓库,从发行 tag 刷新——改本仓库这两个文件不会自动改变站上内容,也不应该:站描述的是已发布版本支持什么。 + +- `cmd/oneagent-desktop`:Wails 桌面入口。 +- `cmd/oneagent`:纯 Go headless CLI。 +- `internal/`:桌面和 CLI 共用的 Go 核心。 +- `frontend/`:React 应用;发行包只携带构建后的静态资源。 +- `agents.lock.json`:Agent 包名、来源、配置适配器和许可证的唯一清单;不固定 Agent 版本或包哈希。 +- `providers.lock.json`:内置 Provider 端点、fallback probe model 和公开站披露字段清单;用户 Provider 保存在本机 `~/.oneagent/providers.json`。 + +## 快速启动 + +### 桌面应用 + +```bash +cd frontend +pnpm install --frozen-lockfile +pnpm run build +cd .. +go run -tags wails ./cmd/oneagent-desktop +``` + +生产构建需要目标平台的 Wails/WebView 依赖。Linux 当前使用 `gtk3` tag(Ubuntu 22.04 cleanroom);macOS 使用系统 WKWebView;Windows 使用 WebView2 Runtime。 + +### CLI + +```bash +go build -o bin/oneagent ./cmd/oneagent +``` + +Windows CMD: + +```cmd +go build -o bin\oneagent.exe .\cmd\oneagent +bin\oneagent.exe agent set codex --provider ppio --model your-model-id --api-key your-api-key +``` + +日常使用优先通过桌面粘贴或已保存 profile 传递凭据;`ONEAGENT_API_KEY` 和 `--api-key` 仅保留给受控脚本。`--registry` 默认是官方 npm registry,镜像必须显式选择并使用 HTTPS。 + +## Agent 与 Provider + +自动配置 Agent: + +| Agent | 包 | 安装器 | 协议 | +| --- | --- | --- | --- | +| Codex | `@openai/codex` | npm | Responses | +| Claude Code | `@anthropic-ai/claude-code` | npm | Anthropic Messages | +| OpenCode | `opencode-ai` | npm | OpenAI-compatible | +| Kilo CLI | `@kilocode/cli` | npm | OpenAI-compatible | +| Aider | `aider-chat` | uv tool | OpenAI-compatible | + +安装器默认让 npm 或 uv 解析最新版本。需要复现特定版本时可传 `--agent-version VERSION`,例如 `oneagent --agent codex --install-agent --check-agent-only --agent-version 0.145.0`。 + +OpenClaw、Hermes 和 Cursor 仅提供官方安装引导,不安装包、不写私有配置、不启动后台服务。 + +内置 PPIO、Novita,并支持在 Provider 页面增删改用户 Provider。配置后按 Agent 实际协议探测:Codex 使用 `/v1/responses`,Claude Code 使用 `/v1/messages`,其余自动配置 Agent 使用 `/v1/chat/completions`。协议不兼容时返回 `PROTOCOL_UNSUPPORTED`,不会先写入不可用配置。 + +Aider 的安装命令由 Go 后端固定为 `uv tool install --force --python 3.12 ...`,由 uv 复用或提供匹配的 Python。这条路径只在选择 Aider 时执行;缺少 `uv` 会返回 `PREREQUISITE_MISSING`。 + +## 开发与测试 + +Go 核心: + +```bash +go vet ./... +go test ./... +go test -race ./... +go run honnef.co/go/tools/cmd/staticcheck@2025.1.1 ./... +go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./... +``` + +React/Wails 测试: + +```bash +cd frontend +pnpm install --frozen-lockfile +pnpm run test:coverage +pnpm run build +pnpm exec playwright install chromium +pnpm run test:e2e +``` + +文档: + +```bash +python3 scripts/check-docs.py +``` + +每个 pull request 都会运行 `.github/workflows/ci.yml`:Go 侧是 `go vet` 加 `go test -race`,前端侧是 `pnpm run test` 加 `pnpm run build`,另有文档链接与语言检查。 + +## 发行 + +发行包由 `.github/workflows/build-artifacts.yml` 构建,手动触发(`workflow_dispatch`)。它为 macOS 与 Windows 各构建 x64/arm64 的 Wails 桌面二进制和纯 Go CLI,macOS 产物打成 `.app`。 + +Wails 仍处于 Alpha,当前不发布 Stable,不做平台签名、公证或商店分发。Stable 的签名门禁保留在后续发行阶段。 + +本机要复现一份等价产物,见「快速启动」里的桌面构建步骤;发行渠道标签、SHA-256 清单和第三方 notices 曾由 `cmd/oneagent-release` 生成,该工具已于 `23805b0` 随构建流程迁移到 GitHub Actions 而移除。第三方归属现在维护在仓库根的 [NOTICE](NOTICE)。 + +## 文档 + +`docs/` 按受众分三层:根下是当前有效的规范,`decisions/` 是架构决策,`internal/` 是维护者视角的历史记录。 + +对外文档以英文撰写。AI Agent Kit 另有中文版,本 README 也有[英文版](README.md)。`docs/internal/` 面向维护者,保持中文。 + +**使用与规范** + +- [AI Agent Kit](docs/ai-agent-kit/zh/README.md):从零配置一个 Agent 环境 +- [产品边界基线](docs/product-boundary-baseline.md):做什么、不做什么,以及为什么(英文) +- [分发与合规政策](docs/distribution-compliance-policy.md):发行前的权利、安全与渠道要求(英文) +- [公开站运营手册](docs/public-site-operations.md)(英文) + +**架构决策** + +- [decisions/](docs/decisions/):ADR-001 至 ADR-009,含已被取代的决策及其去向(英文) +- [Wails v3 / Go 迁移](docs/decisions/ADR-007-wails-v3-go-migration.md) +- [按 Agent 协议验证](docs/decisions/ADR-004-per-agent-protocol-verification.md) +- [凭据写入 Agent 配置文件](docs/decisions/ADR-008-credentials-in-agent-config-files.md) + +**内部实现记录** + +- [internal/](docs/internal/README.md):各次改造的完工记录与验证清单。里面的命令可能已随工具移除而失效,该目录的 README 说明了当前的替代入口。 + +## 许可证 + +Apache License 2.0,见 [LICENSE](LICENSE)。 + +[NOTICE](NOTICE) 列出随二进制分发的第三方组件及其许可证,以及运行时下载但不再分发的 Node.js、uv 和 Agent 包。界面中显示的各 Agent 官方标识属于 nominative use,用于指明某一行对应哪个工具,不表示背书或关联,商标归各自所有者。 diff --git a/docs/ai-agent-kit/README.md b/docs/ai-agent-kit/README.md index 50f24720..8b5fb4e2 100644 --- a/docs/ai-agent-kit/README.md +++ b/docs/ai-agent-kit/README.md @@ -1,29 +1,35 @@ -# OneAgent AI 开发环境激活文档 +# AI Agent Kit -这是一套面向个人开发者、团队和组织发行方的 AI Agent 环境配置文档。 +Documentation for setting up an AI Agent environment with OneAgent — for individual +developers, teams, and organizations that redistribute the kit. -文中以 **PPIO** 作为贯穿示例。OneAgent 内置的另一个 Provider 是 **Novita**,此外还支持 -自定义 OpenAI-compatible 端点;三者在应用里的配置步骤相同,只是 Base URL 和 Key 来源不同, -所以下面的流程对它们同样适用。内置 Provider 的真源是仓库根的 `providers.lock.json`。 +**English** · [简体中文](./zh/README.md) -产品边界以 [OneAgent 产品边界基线](../product-boundary-baseline.md) 为准。组织发行方可以在项目外部提供自己的兑换码或项目说明,但不改变 OneAgent 核心流程。 +The English translation is in progress. Pages that are not translated yet link to the +Chinese original, which is complete and current. -## 推荐阅读顺序 +## Reading order -1. [开始使用](./00-start-here.md) -2. [PPIO 账号和 Provider 准备](./01-ppio-account.md) -3. [创建和保存 API Key](./02-api-key.md) -4. [配置工具选择](./03-config-tools.md) -5. [Agent 分类和安装指引](./04-agent-guides.md) -6. [第一次请求验证](./05-first-request.md) +1. [Start here](./en/00-start-here.md) +2. [PPIO account and Provider setup](./en/01-ppio-account.md) +3. [Create and store an API key](./en/02-api-key.md) +4. [Choosing a config tool](./en/03-config-tools.md) +5. [Agent categories and install guides](./en/04-agent-guides.md) +6. [Verify your first request](./en/05-first-request.md) -需要使用 CC Switch 的用户,再阅读 [CC Switch 配置 PPIO 指引](./tools/cc-switch.md)。 +If you use CC Switch, also read [Configuring PPIO in CC Switch](./en/tools/cc-switch.md). -## 文档原则 +Distributors: see the [kit manifest](./en/manifest.md) for what a release package +contains and what must never be bundled. -- Provider 账号和 API Key 属于用户自己的账户。 -- OneAgent 负责本地检测、官方安装引导和配置写入。 -- 不在文档包中存放真实 API Key。 -- 不把第三方配置工具的托管服务地址当作 Provider Base URL。 -- Provider 的公开权益以账户页面实际显示为准,不由 OneAgent 承诺固定额度。 -- 用户无法访问官方安装源时,使用合规网络、授权镜像或手动安装,不使用 OneAgent 提供的 VPN、代理或绕过方案。 +## Scope + +PPIO is used as the running example. OneAgent also ships **Novita** as a built-in +Provider and supports any custom OpenAI-compatible endpoint. The setup steps are the +same for all three — only the base URL and where the key comes from differ. The source +of truth for built-in Providers is `providers.lock.json` at the repository root. + +The product boundary is defined by the +[product boundary baseline](../product-boundary-baseline.md). A distributing +organization may offer its own redemption codes or onboarding material outside this +project, but that does not change OneAgent's core flow. diff --git a/docs/ai-agent-kit/en/00-start-here.md b/docs/ai-agent-kit/en/00-start-here.md new file mode 100644 index 00000000..40f80199 --- /dev/null +++ b/docs/ai-agent-kit/en/00-start-here.md @@ -0,0 +1,74 @@ +# Start here + +[简体中文](../zh/00-start-here.md) · **English** + +This kit walks you through three things: + +1. Get a model Provider ready to use. +2. Install or configure an AI agent. +3. Make a first model request that succeeds. + +## Before you start + +- A supported macOS, Windows, or Linux machine. The normal OneAgent flow needs no Python. +- A working model Provider account, or be ready to sign up for one. +- The agent you intend to use — Codex, Claude Code, OpenCode, or Aider, for example. + +## The path + +```text +Launch OneAgent +→ Sign up for or log in to a Provider +→ Create an API key +→ Pick an agent +→ Pick a config tool +→ Pick a model +→ Run the setup +→ Make your first request +``` + +If you are already comfortable switching between Providers, choose **CC Switch** on the +config method page, then read [Choosing a config tool](./03-config-tools.md) and the +[CC Switch guide](./tools/cc-switch.md). + +## Launching the desktop app + +Download the `technical-preview-unsigned` package for your platform, unpack it, and +launch it directly: `OneAgent.app` on macOS, `oneagent-desktop.exe` on Windows. Packages +at this stage are neither signed nor notarized, so the first launch needs manual approval +from your operating system. + +To run from source instead, for development or review: + +```bash +cd frontend && pnpm install --frozen-lockfile && pnpm run build +cd .. +go run -tags wails ./cmd/oneagent-desktop +``` + +## Three safety rules + +1. Never paste an API key into a chat, an issue, homework, or a screenshot. +2. Never commit an API key to a repository. +3. If you are unsure whether a config tool is trustworthy, fall back to OneAgent's + built-in configuration path. + +## When an agent will not download + +If the official install source is unreachable from your network: + +1. Use the compliant network access your organization or ISP provides. +2. Use an authorized mirror, and verify the version and checksum. +3. Install manually from another compliant environment, then return to OneAgent to + detect it locally. + +OneAgent does not provide a VPN, a proxy, node subscriptions, or any configuration that +circumvents network restrictions. + +## If something goes wrong + +- Provider trouble: see [PPIO account and Provider setup](./01-ppio-account.md). +- Key trouble: see [Create and store an API key](./02-api-key.md). +- Config tool trouble: see [Choosing a config tool](./03-config-tools.md). +- Agent trouble: see [Agent categories and install guides](./04-agent-guides.md). +- Request trouble: see [Verify your first request](./05-first-request.md). diff --git a/docs/ai-agent-kit/en/01-ppio-account.md b/docs/ai-agent-kit/en/01-ppio-account.md new file mode 100644 index 00000000..22d8bed1 --- /dev/null +++ b/docs/ai-agent-kit/en/01-ppio-account.md @@ -0,0 +1,50 @@ +# PPIO account and Provider setup + +[简体中文](../zh/01-ppio-account.md) · **English** + +> PPIO is the example here. The built-in Novita Provider and any custom +> OpenAI-compatible endpoint follow the same steps — substitute that Provider's own +> website and base URL. + +## 1. Open the official site + +Reach the PPIO website from OneAgent or from the official documentation. Do not download +scripts or submit account details through links from unknown group chats. + +If you already have a PPIO account, log in. Otherwise sign up as the page directs. + +## 2. Check your account status + +Complete whatever account verification the site requires, and confirm the account has +usable credit or a published allowance. + +A Provider's free credit, new-user allowance, referral rewards, and other published +benefits may carry eligibility rules, expiry dates, and model restrictions. Treat what +your account page shows right now as authoritative, and do not write any fixed amount +into project configuration or promotional copy. + +## 3. If there is no published allowance + +You can: + +1. Read the available credit and benefit terms on your account page. +2. Top up, or choose another lawful option, per the Provider's official pages. +3. Use a custom Provider, as long as it exposes an OpenAI-compatible API and permits + your use case. + +OneAgent does not top up on your behalf and does not automate account benefit pages. + +## 4. Move on to the API key + +Once the account and its credit are ready, continue to +[Create and store an API key](./02-api-key.md). + +Never send your API key to anyone so they can "check the balance for you." When you need +support, share only the status code, whether the model ID exists, whether the base URL is +correct, and redacted logs. + +## Official references + +- PPIO website: +- PPIO quickstart: +- PPIO FAQ: diff --git a/docs/ai-agent-kit/en/02-api-key.md b/docs/ai-agent-kit/en/02-api-key.md new file mode 100644 index 00000000..f4f8872f --- /dev/null +++ b/docs/ai-agent-kit/en/02-api-key.md @@ -0,0 +1,53 @@ +# Create and store a PPIO API key + +[简体中文](../zh/02-api-key.md) · **English** + +## Before you create one + +Confirm that: + +- You are logged in to the right PPIO account. +- The account has usable credit or an allowance. +- You know which machine and which project this key is for. + +## Steps + +1. Open the API key page in the PPIO console. +2. Create a new API key. +3. Copy it the moment it is first shown. +4. Paste it into OneAgent's password field. +5. Click **Test connection**. + +The key is shown only once. Do not leave the page expecting to read it again later. + +## How OneAgent handles the key + +OneAgent's standing constraints: + +- The key travels from the local form to the local install flow, and nowhere else. +- The key is never passed as a command-line argument. +- The key is never written to logs or error messages. +- The key is never uploaded to a OneAgent server. +- A timestamped backup is created before any configuration is overwritten. + +## Recommended local environment variables + +```bash +export ONEAGENT_API_KEY='your PPIO API key' +export ONEAGENT_API_BASE_URL='https://api.ppio.com/openai' +export ONEAGENT_MODEL='your model ID' +``` + +If you use CC Switch, put the key only in CC Switch's local profile, and follow the local +storage and permission guidance for the version you have installed. + +## If a key leaks + +Revoke the old key in the PPIO console immediately, create a new one, and run OneAgent's +setup again. Deleting the chat message or the git commit is not enough — the key may +already sit in a cache, a log, or a screenshot. + +## Official references + +- PPIO API keys: +- PPIO API integration: diff --git a/docs/ai-agent-kit/en/03-config-tools.md b/docs/ai-agent-kit/en/03-config-tools.md new file mode 100644 index 00000000..bd073294 --- /dev/null +++ b/docs/ai-agent-kit/en/03-config-tools.md @@ -0,0 +1,78 @@ +# Choosing a config tool + +[简体中文](../zh/03-config-tools.md) · **English** + +OneAgent offers three ways to configure an agent. For a first run, use the built-in +configuration. Reach for a local tool like CC Switch once you need several Providers or +several accounts. + +## Option 1: OneAgent's built-in configuration + +Good for: + +- Using PPIO for the first time. +- Needing only one Provider. +- Wanting the setup to be as easy to review and debug as possible. + +What it does: + +1. Detects whether the agent is installed. +2. Calls the official install source, or shows the official install command. +3. Writes to the target agent's official configuration entry point. +4. Fetches the model list via `/v1/models`. +5. Sends one minimal request to verify. + +This is the default path on a first run. + +## Option 2: CC Switch + +Good for: + +- Switching between PPIO, other OpenAI-compatible services, and first-party accounts. +- Keeping different configurations for different projects. +- Moving frequently between Claude Code, Codex, OpenCode, and similar tools. + +CC Switch is an optional local configuration tool, not a OneAgent dependency. Get the +current version from its own official project page — OneAgent does not repackage its +binary or install script into the kit. + +For the steps, see the [CC Switch guide](./tools/cc-switch.md). + +## Option 3: Manual configuration + +Good for: + +- Agents that manage their own configuration their own way. +- Not wanting an extra local configuration tool. +- Debugging what an automatic setup produced. + +Manual configuration means confirming at least: + +```text +Base URL: https://api.ppio.com/openai +Models: GET /v1/models +Chat: POST /v1/chat/completions +Key: local secure storage only +``` + +## Which to pick + +| Situation | Recommended | +| --- | --- | +| First run | OneAgent built-in configuration | +| A single PPIO account | OneAgent built-in configuration | +| Several Providers | CC Switch or a comparable profile tool | +| OpenClaw / Hermes gateway | Official docs, verified by hand | +| IDE extensions | The extension's own Provider settings | +| Unsure where a tool came from | Manual or OneAgent built-in configuration | + +## One distinction that matters + +CC Switch being a local configuration tool and a third-party hosted API service are two +different things. Using CC Switch means switching configuration on your own machine. It +does not mean your PPIO key is handed to a CC Switch server, and it does not mean that +tool's service address can be used as the PPIO base URL. + +No config tool substitutes for compliant network access. OneAgent provides no VPN, proxy, +node subscription, or circumvention capability. If a tool or install source is +unreachable, go back to [Start here](./00-start-here.md) for the manual install path. diff --git a/docs/ai-agent-kit/en/04-agent-guides.md b/docs/ai-agent-kit/en/04-agent-guides.md new file mode 100644 index 00000000..76cba33f --- /dev/null +++ b/docs/ai-agent-kit/en/04-agent-guides.md @@ -0,0 +1,84 @@ +# Agent categories and install guides + +[简体中文](../zh/04-agent-guides.md) · **English** + +## One-click configuration + +### Codex + +- Prefer the official install source. +- OneAgent writes `~/.codex/config.toml`, and the key into `~/.codex/auth.json` beside it. +- No environment variables involved. Restart codex after a configuration change. + +### Claude Code + +- Prefer the official install source. +- OneAgent writes `~/.claude/settings.json`. +- Configured through `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`, and the model field. +- Restart Claude Code after a configuration change. + +### OpenCode + +- Uses an OpenAI-compatible Provider. OneAgent writes + `~/.config/opencode/opencode.json`. +- The base URL takes the form `https://api.ppio.com/openai/v1`. +- The API key goes directly into that file's `provider.oneagent.options.apiKey`, with + permissions tightened to 0600. No environment variables involved. + +### Kilo CLI + +- Uses an OpenAI-compatible Provider. OneAgent writes `~/.config/kilo/kilo.jsonc`. +- As with OpenCode, the API key lives in the config file's `options.apiKey`, with + permissions tightened to 0600. + +### Aider + +- Python 3.12 is needed only if you choose to install Aider, and `uv` resolves it itself: + a matching local interpreter is reused, otherwise a managed CPython is downloaded to + `~/.oneagent/runtimes/python`. No other agent, and not OneAgent itself, needs Python. +- OneAgent installs `uv` as a runtime into `~/.oneagent/runtimes`. You do not need it + preinstalled. +- PPIO settings are kept in a dedicated environment file. +- Aider loads it itself at launch via `aider --env-file ~/.oneagent/aider.env`. There is + no need to source anything in your shell. +- When using the `openai/` form, follow the guidance for your installed Aider + version. + +## Gateway agents + +### OpenClaw + +OneAgent V1 only detects the install and describes the official flow. It does not install +a gateway daemon, expose a port, or enable plugins by default. + +### Hermes + +OneAgent only provides install and model configuration guidance. It does not write +private configuration or start a gateway. + +## Agents with their own accounts + +### Cursor + +Prefer the official account, subscription, and login flow. Do not force a Provider base +URL into a tool that has no stable official configuration contract, and OneAgent will not +write private configuration for one either. + +## Other tools + +`agents.lock.json` is the single source of truth for the agent catalog. Tools that are not +in it — IDE extensions, other terminal agents — are neither detected nor configured by +OneAgent. Such tools usually take an OpenAI-compatible endpoint in their own Provider +settings; you can copy the field values from +[Verify your first request](./05-first-request.md), but do it in that tool's own +interface. OneAgent does not modify an IDE's private state files. + +## Debugging order + +```text +Test the PPIO API first +→ then confirm the model ID +→ then confirm the agent's config file +→ restart the agent +→ then retry the first request +``` diff --git a/docs/ai-agent-kit/en/05-first-request.md b/docs/ai-agent-kit/en/05-first-request.md new file mode 100644 index 00000000..eb90b397 --- /dev/null +++ b/docs/ai-agent-kit/en/05-first-request.md @@ -0,0 +1,54 @@ +# Verify your first request + +[简体中文](../zh/05-first-request.md) · **English** + +## 1. Check the model list first + +```bash +curl https://api.ppio.com/openai/v1/models \ + -H "Authorization: Bearer $ONEAGENT_API_KEY" +``` + +Confirm the model ID you intend to use appears in the response. + +## 2. Verify with a minimal chat request + +```bash +curl https://api.ppio.com/openai/v1/chat/completions \ + -H "Authorization: Bearer $ONEAGENT_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "YOUR_MODEL_ID", + "messages": [{"role": "user", "content": "Reply with OK."}], + "max_tokens": 8 + }' +``` + +Do not use real project code, personal information, or a long prompt as your first test. + +## 3. Common status codes + +| Status | Meaning | What to do | +| --- | --- | --- | +| 200 | Request succeeded | Go ahead and start the agent | +| 401 / 403 | Key rejected, or no permission | Create a new key; check it was pasted in full | +| 404 / 405 | Address or endpoint unsupported | Check the base URL has no duplicated `/v1` or full path | +| 429 | Rate or quota limit | Review your account credit and request rate | +| 500 | Server error | Note the time and status code, retry later | + +## 4. Verify through the agent + +Start the agent and try a small task: + +```text +Read the README in the current directory and list three things that could be improved. +Do not modify any files. +``` + +If the agent returns a result, the install, key, model, and base configuration are all +working. + +## Official references + +- PPIO model overview: +- PPIO API integration: diff --git a/docs/ai-agent-kit/en/manifest.md b/docs/ai-agent-kit/en/manifest.md new file mode 100644 index 00000000..2e5804ad --- /dev/null +++ b/docs/ai-agent-kit/en/manifest.md @@ -0,0 +1,53 @@ +# Kit release package manifest + +[简体中文](../zh/manifest.md) · **English** + +## Runtime files + +| File | Purpose | Needs a key | +| --- | --- | --- | +| `OneAgent.app` (macOS) / `oneagent-desktop.exe` (Windows) | Desktop app | No | +| `oneagent` / `oneagent.exe` | Headless CLI | No | + +Release packages are built by `.github/workflows/build-artifacts.yml`. Earlier versions +launched a local GUI through three scripts — `launcher`, `start.sh`, and `start.command` — +which the Go/Wails migration made unnecessary. + +## Documentation files + +| Document | Audience | +| --- | --- | +| `00-start-here.md` | Everyone | +| `01-ppio-account.md` | Users who need to set up a Provider account | +| `02-api-key.md` | Users at the API key step | +| `03-config-tools.md` | Users choosing a config tool | +| `tools/cc-switch.md` | CC Switch users | +| `04-agent-guides.md` | Users picking an agent | +| `05-first-request.md` | Users who have finished setup and are verifying it | + +## Version and provenance record + +Every release package should record: + +```text +Package version: +Release date: +Provider documentation verified on: +Agent version range: +Config tool version range: +``` + +A distributing organization may maintain its own redemption codes or onboarding notes +outside the package, but that content does not enter OneAgent's core manifest. + +Never write a real API key, a shared gateway key, or personal account details into the +manifest. + +## Never bundle + +- VPN or proxy clients. +- Proxy nodes, subscription links, or cross-border relay configuration. +- Agent packages whose licence has not been confirmed. +- Unlicensed binaries of commercial agents. +- Shared Provider API keys. +- User passwords, phone numbers, or identity documents. diff --git a/docs/ai-agent-kit/en/tools/cc-switch.md b/docs/ai-agent-kit/en/tools/cc-switch.md new file mode 100644 index 00000000..6dad59cd --- /dev/null +++ b/docs/ai-agent-kit/en/tools/cc-switch.md @@ -0,0 +1,116 @@ +# Configuring PPIO in CC Switch + +[简体中文](../../zh/tools/cc-switch.md) · **English** + +> This guide treats CC Switch as a local profile-switching tool. Its interface, supported +> agents, and configuration fields may change between versions — follow its official +> project page for installation and updates. + +## 1. Get CC Switch + +Reach the download and install instructions through CC Switch's official GitHub +repository or official project website. Do not use unofficial repackaged builds. + +Once installed, open CC Switch and confirm it starts correctly before adding a PPIO +profile. + +## 2. Create a PPIO profile + +Create a new Provider or profile in CC Switch, with these fields: + +```text +Name: PPIO +Base URL: https://api.ppio.com/openai +API Key: your PPIO API key +Model: a model ID returned by PPIO /v1/models +``` + +Whether CC Switch labels the field `Endpoint`, `API Base`, or `Base URL`, enter only the +base address. Do not put the full `/v1/chat/completions` path into the base URL. + +## 3. Filling in the model + +Prefer the result of OneAgent's "fetch model list". For OpenAI-compatible configuration +the model ID is the raw ID the server returned — do not add an `openai/` or `ppio/` +prefix yourself unless the target agent's official documentation requires it. + +If CC Switch offers a model test, verify with a minimal request. Do not paste private +code, personal data, or long text into the test input. + +## 4. What takes effect after switching + +After switching profiles: + +1. Close the running agent terminal or application. +2. Reopen the agent. +3. Check which model and Provider the agent now reports. +4. Send one minimal request. + +Agents differ in how configuration takes effect. Do not conclude that an agent has +reloaded its configuration just because CC Switch says the profile was switched. + +## 5. How this relates to OneAgent + +Recommended order: + +```text +OneAgent probes PPIO +→ OneAgent fetches the model list +→ OneAgent verifies one request +→ CC Switch stores the same PPIO profile +→ You switch profiles per project +``` + +That way, when something breaks, you can return to OneAgent's built-in configuration to +tell whether PPIO itself is working before questioning the CC Switch profile. + +## 6. Common mistakes + +### Putting the full request path in the base URL + +Wrong: + +```text +https://api.ppio.com/openai/v1/chat/completions +``` + +Right: + +```text +https://api.ppio.com/openai +``` + +### Using a model ID that is not a PPIO model + +Fetch the current model list through OneAgent, confirm the model ID, and then copy it into +CC Switch. + +### The agent still uses the old configuration after switching + +Close and restart the agent. Open a new terminal if needed, so the new environment +variables apply. + +### Sending your key to someone for debugging + +Never send the full key. Send only the HTTP status code, whether the model ID exists, +whether the base URL is correct, and redacted logs. + +## 7. Version verification + +A release package should record: + +```text +Tool name: CC Switch +Tool source: https://github.com/farion1231/cc-switch +Verified on: 2026-07-21 +Verified: can create a profile, store the PPIO base URL, and complete a minimal + request after switching +``` + +After every CC Switch upgrade, re-verify at least one representative agent among Claude +Code, Codex, and OpenCode. + +## Official references + +- CC Switch official GitHub repository: +- CC Switch official project website: diff --git a/docs/ai-agent-kit/00-start-here.md b/docs/ai-agent-kit/zh/00-start-here.md similarity index 97% rename from docs/ai-agent-kit/00-start-here.md rename to docs/ai-agent-kit/zh/00-start-here.md index 6d0e98f2..2c51bdb9 100644 --- a/docs/ai-agent-kit/00-start-here.md +++ b/docs/ai-agent-kit/zh/00-start-here.md @@ -1,5 +1,7 @@ # OneAgent AI 开发环境激活指南 +[English](../en/00-start-here.md) · **简体中文** + 这套启动包帮助你完成三件事: 1. 准备一个可用的模型 Provider。 diff --git a/docs/ai-agent-kit/01-ppio-account.md b/docs/ai-agent-kit/zh/01-ppio-account.md similarity index 96% rename from docs/ai-agent-kit/01-ppio-account.md rename to docs/ai-agent-kit/zh/01-ppio-account.md index f9b509ce..6718bfe8 100644 --- a/docs/ai-agent-kit/01-ppio-account.md +++ b/docs/ai-agent-kit/zh/01-ppio-account.md @@ -1,5 +1,7 @@ # PPIO 账号和 Provider 准备 +[English](../en/01-ppio-account.md) · **简体中文** + > 本文用 PPIO 举例。内置的 Novita 和自定义 OpenAI-compatible 端点步骤相同,把官网入口和 > Base URL 换成对应 Provider 的即可。 diff --git a/docs/ai-agent-kit/02-api-key.md b/docs/ai-agent-kit/zh/02-api-key.md similarity index 96% rename from docs/ai-agent-kit/02-api-key.md rename to docs/ai-agent-kit/zh/02-api-key.md index a70926aa..7684a853 100644 --- a/docs/ai-agent-kit/02-api-key.md +++ b/docs/ai-agent-kit/zh/02-api-key.md @@ -1,5 +1,7 @@ # 创建和保存 PPIO API Key +[English](../en/02-api-key.md) · **简体中文** + ## 创建前确认 先确认: diff --git a/docs/ai-agent-kit/03-config-tools.md b/docs/ai-agent-kit/zh/03-config-tools.md similarity index 97% rename from docs/ai-agent-kit/03-config-tools.md rename to docs/ai-agent-kit/zh/03-config-tools.md index 1ce4603d..e378962a 100644 --- a/docs/ai-agent-kit/03-config-tools.md +++ b/docs/ai-agent-kit/zh/03-config-tools.md @@ -1,5 +1,7 @@ # 配置工具选择 +[English](../en/03-config-tools.md) · **简体中文** + OneAgent 提供三种配置方式。第一次使用建议选择内置配置;需要多个 Provider 或多个账号时,再选择 CC Switch 等本机工具。 ## 方式一:OneAgent 内置配置 diff --git a/docs/ai-agent-kit/04-agent-guides.md b/docs/ai-agent-kit/zh/04-agent-guides.md similarity index 97% rename from docs/ai-agent-kit/04-agent-guides.md rename to docs/ai-agent-kit/zh/04-agent-guides.md index 42005c80..555b16a7 100644 --- a/docs/ai-agent-kit/04-agent-guides.md +++ b/docs/ai-agent-kit/zh/04-agent-guides.md @@ -1,5 +1,7 @@ # Agent 分类和安装指引 +[English](../en/04-agent-guides.md) · **简体中文** + ## 可一键配置 ### Codex diff --git a/docs/ai-agent-kit/05-first-request.md b/docs/ai-agent-kit/zh/05-first-request.md similarity index 96% rename from docs/ai-agent-kit/05-first-request.md rename to docs/ai-agent-kit/zh/05-first-request.md index c3538a71..811d62fe 100644 --- a/docs/ai-agent-kit/05-first-request.md +++ b/docs/ai-agent-kit/zh/05-first-request.md @@ -1,5 +1,7 @@ # 第一次请求验证 +[English](../en/05-first-request.md) · **简体中文** + ## 1. 先验证模型列表 ```bash diff --git a/docs/ai-agent-kit/zh/README.md b/docs/ai-agent-kit/zh/README.md new file mode 100644 index 00000000..a1a48be2 --- /dev/null +++ b/docs/ai-agent-kit/zh/README.md @@ -0,0 +1,31 @@ +# OneAgent AI 开发环境激活文档 + +[English](../README.md) · **简体中文** + +这是一套面向个人开发者、团队和组织发行方的 AI Agent 环境配置文档。 + +文中以 **PPIO** 作为贯穿示例。OneAgent 内置的另一个 Provider 是 **Novita**,此外还支持 +自定义 OpenAI-compatible 端点;三者在应用里的配置步骤相同,只是 Base URL 和 Key 来源不同, +所以下面的流程对它们同样适用。内置 Provider 的真源是仓库根的 `providers.lock.json`。 + +产品边界以 [OneAgent 产品边界基线](../../product-boundary-baseline.md) 为准。组织发行方可以在项目外部提供自己的兑换码或项目说明,但不改变 OneAgent 核心流程。 + +## 推荐阅读顺序 + +1. [开始使用](./00-start-here.md) +2. [PPIO 账号和 Provider 准备](./01-ppio-account.md) +3. [创建和保存 API Key](./02-api-key.md) +4. [配置工具选择](./03-config-tools.md) +5. [Agent 分类和安装指引](./04-agent-guides.md) +6. [第一次请求验证](./05-first-request.md) + +需要使用 CC Switch 的用户,再阅读 [CC Switch 配置 PPIO 指引](./tools/cc-switch.md)。 + +## 文档原则 + +- Provider 账号和 API Key 属于用户自己的账户。 +- OneAgent 负责本地检测、官方安装引导和配置写入。 +- 不在文档包中存放真实 API Key。 +- 不把第三方配置工具的托管服务地址当作 Provider Base URL。 +- Provider 的公开权益以账户页面实际显示为准,不由 OneAgent 承诺固定额度。 +- 用户无法访问官方安装源时,使用合规网络、授权镜像或手动安装,不使用 OneAgent 提供的 VPN、代理或绕过方案。 diff --git a/docs/ai-agent-kit/manifest.md b/docs/ai-agent-kit/zh/manifest.md similarity index 96% rename from docs/ai-agent-kit/manifest.md rename to docs/ai-agent-kit/zh/manifest.md index 1728fbb4..5cecef41 100644 --- a/docs/ai-agent-kit/manifest.md +++ b/docs/ai-agent-kit/zh/manifest.md @@ -1,5 +1,7 @@ # AI 开发环境启动包清单 +[English](../en/manifest.md) · **简体中文** + ## 运行时文件 | 文件 | 作用 | 是否需要密钥 | diff --git a/docs/ai-agent-kit/tools/cc-switch.md b/docs/ai-agent-kit/zh/tools/cc-switch.md similarity index 98% rename from docs/ai-agent-kit/tools/cc-switch.md rename to docs/ai-agent-kit/zh/tools/cc-switch.md index a51dc99c..cf30dac3 100644 --- a/docs/ai-agent-kit/tools/cc-switch.md +++ b/docs/ai-agent-kit/zh/tools/cc-switch.md @@ -1,5 +1,7 @@ # CC Switch 配置 PPIO 指引 +[English](../../en/tools/cc-switch.md) · **简体中文** + > 本文把 CC Switch 当作“本机配置 Profile 切换工具”使用。CC Switch 的界面、支持的 Agent 和配置字段可能随版本变化;安装和更新请以其官方项目入口为准。 ## 1. 获取 CC Switch diff --git a/docs/decisions/ADR-001-local-launcher-and-config-tools.md b/docs/decisions/ADR-001-local-launcher-and-config-tools.md index 655f1cc0..9ec20be0 100644 --- a/docs/decisions/ADR-001-local-launcher-and-config-tools.md +++ b/docs/decisions/ADR-001-local-launcher-and-config-tools.md @@ -1,4 +1,4 @@ -# ADR-001:本地启动器采用内置配置加可选配置工具模式 +# ADR-001: A built-in configuration path plus optional config tools ## Status @@ -10,67 +10,78 @@ Accepted ## Context -OneAgent 的目标是帮助不同类型的用户激活一个真正可用的本地 AI 开发环境。用户可能只使用一个 Provider,也可能需要在多个 Provider、账号和模型之间切换。 +OneAgent aims to help different kinds of users activate a genuinely usable local AI +development environment. A user may need only one Provider, or may need to switch between +several Providers, accounts, and models. -CC Switch 等第三方工具可以帮助用户管理本机 Profile,但把它们直接打进 OneAgent 会引入版本、许可证、安装脚本和配置兼容性风险。 +Third-party tools such as CC Switch can manage local profiles for a user, but bundling +them into OneAgent would import their version, licence, install script, and configuration +compatibility risks. ## Decision -OneAgent 采用三层配置方式: +OneAgent offers three configuration layers: -1. OneAgent 内置配置:默认路径,负责首次 Provider 激活和 Agent 配置。 -2. CC Switch 等第三方工具:可选路径,通过独立文档使用,不自动安装。 -3. 手动配置:兜底路径,用于未支持 Agent、高级用户和故障排查。 +1. OneAgent's built-in configuration: the default path, responsible for first-time + Provider activation and agent configuration. +2. Third-party tools such as CC Switch: an optional path, documented separately and never + installed automatically. +3. Manual configuration: the fallback, for unsupported agents, advanced users, and + debugging. -OneAgent 不把第三方配置工具、第三方托管 API 服务或共享 Provider Key 作为核心依赖。 +OneAgent does not treat a third-party config tool, a third-party hosted API service, or a +shared Provider key as a core dependency. -所有配置工具说明必须注明: +Documentation for any config tool must state: -- 官方来源。 -- 支持的 Agent。 -- Profile 字段和 Base URL 格式。 -- API Key 保存位置。 -- 切换后是否需要重启。 -- 配置备份和恢复方式。 +- Its official source. +- Which agents it supports. +- Its profile fields and base URL format. +- Where it stores the API key. +- Whether a restart is needed after switching. +- How to back up and restore configuration. ## Alternatives Considered -### 把 CC Switch 直接内置到启动包 +### Bundle CC Switch directly into the kit -- 优点:用户少一步安装。 -- 缺点:需要承担第三方版本、许可证、签名、更新和配置兼容性问题。 -- 结论:拒绝。OneAgent 通过文档提供可选入口。 +- Upside: one less install step for the user. +- Downside: OneAgent would own a third party's versioning, licensing, signing, updates, + and configuration compatibility. +- Conclusion: rejected. OneAgent offers it as an optional path through documentation. -### 只支持手动配置 +### Support manual configuration only -- 优点:实现简单,兼容性边界清楚。 -- 缺点:首次用户容易在 Base URL、模型 ID 和配置文件位置上出错。 -- 结论:拒绝。内置配置作为默认路径,手动配置作为兜底。 +- Upside: simple to implement, with clear compatibility boundaries. +- Downside: first-time users readily get the base URL, model ID, and config file location + wrong. +- Conclusion: rejected. Built-in configuration is the default; manual is the fallback. -### 允许任意第三方配置工具自动写入私有状态文件 +### Let any third-party config tool write private state files automatically -- 优点:可以覆盖更多 Agent。 -- 缺点:私有文件格式不稳定,容易破坏用户配置,也难以审计。 -- 结论:拒绝。只写已经确认的官方配置入口。 +- Upside: would cover more agents. +- Downside: private file formats are unstable, easy to corrupt, and hard to audit. +- Conclusion: rejected. Only confirmed official configuration entry points are written. ## Consequences ### Positive -- 第一次配置路径简单、可测试。 -- 第三方工具可以独立升级,不拖累 OneAgent。 -- 用户可以按照熟悉程度选择内置配置、CC Switch 或手动配置。 -- OneAgent 不需要承担第三方配置工具的长期维护责任。 +- The first-run configuration path is simple and testable. +- Third-party tools can upgrade independently without holding OneAgent back. +- Users can choose built-in configuration, CC Switch, or manual configuration according to + their own familiarity. +- OneAgent takes on no long-term maintenance duty for a third-party config tool. ### Negative -- 使用 CC Switch 的用户需要阅读额外文档。 -- OneAgent 需要维护配置工具兼容矩阵。 -- 不同 Agent 的重启和配置生效方式无法完全统一。 +- CC Switch users have to read an additional document. +- OneAgent has to maintain a config tool compatibility matrix. +- How a restart applies configuration cannot be made uniform across agents. ## Follow-up -- 为每个配置工具增加 `verified_at`、`source_url` 和 `supported_agents` 元数据。 -- 每次配置工具升级后,重新验证至少一个代表性 Agent。 -- 如果未来要自动安装第三方工具,先增加签名校验、版本锁定和用户确认。 - +- Add `verified_at`, `source_url`, and `supported_agents` metadata for each config tool. +- After every config tool upgrade, re-verify at least one representative agent. +- Before ever installing a third-party tool automatically, add signature verification, + version pinning, and user confirmation. diff --git a/docs/decisions/ADR-002-product-boundary-and-network-access.md b/docs/decisions/ADR-002-product-boundary-and-network-access.md index 58bd48c4..334607cf 100644 --- a/docs/decisions/ADR-002-product-boundary-and-network-access.md +++ b/docs/decisions/ADR-002-product-boundary-and-network-access.md @@ -1,4 +1,4 @@ -# ADR-002:固定 OneAgent 的网络访问、分发和用户范围边界 +# ADR-002: Fixing OneAgent's Network Access, Distribution and User Scope Boundary ## Status @@ -10,80 +10,109 @@ Accepted ## Context -OneAgent 面向需要本地 AI 开发环境的个人、团队和组织发行方,提供 Provider 注册引导、API Key 配置、模型选择和 Agent 安装引导。 +OneAgent targets individuals, teams and organizational redistributors who need a +local AI development environment. It provides guided Provider signup, API Key +configuration, model selection and guided Agent installation. -部分 Agent 的官方安装源可能在用户当前网络环境中不可达。如果为了提高“一键成功率”而内置 VPN、代理、节点订阅或跨境中转,产品就会从本地配置器变成网络接入服务,并增加合规、运营和安全风险。 +The official installation source for some Agents may be unreachable from the +user's current network. If we were to bundle a VPN, a proxy, node subscriptions +or cross-border relays in order to raise the "one-click success rate", the +product would turn from a local configurator into a network access service, and +would take on compliance, operational and security risk. -启动包还涉及第三方 Agent、开源许可证、CC Switch 等配置工具和用户 API Key,需要固定分发、权限和数据边界。 +The starter bundle also involves third-party Agents, open source licenses, +configuration tools such as CC Switch, and user API Keys, so the distribution, +permission and data boundaries need to be fixed. ## Decision -OneAgent 固定为: +OneAgent is fixed as: -> Provider 账号和模型 API 的本地激活引导器、Agent 官方安装协调器和本地配置器。 +> A local activation guide for Provider accounts and model APIs, a coordinator +> for official Agent installation, and a local configurator. -明确不提供: +Explicitly out of scope: -- VPN、代理、专线或绕过网络限制的能力。 -- 共享 Provider API Key 或统一网关。 -- 自动登录、验证码处理和自动领取账户权益。 -- 未获许可的商业 Agent 包体分发。 -- 默认上传 Key、Prompt、代码和完整请求内容。 +- VPN, proxy, dedicated lines, or any ability to bypass network restrictions. +- Shared Provider API Keys or a unified gateway. +- Automatic login, captcha handling, or automatic claiming of account benefits. +- Distribution of commercial Agent packages without permission. +- Uploading Keys, prompts, code or full request content by default. -软件下载采用“官方源 → 授权镜像 → 用户手动安装 → 文档引导”的降级策略。网络不可达时,产品只能报告不可达并提供手动路径,不提供网络绕过方案。 +Software download follows a fallback chain of "official source → authorized +mirror → manual user install → documented guidance". When the network is +unreachable, the product may only report it as unreachable and offer the manual +path; it does not offer a way around the network. -用户可以直接使用 Provider 当前账户页面显示的公开权益或其他合法额度,但 OneAgent 不承诺固定免费额度,也不把任何权益写入核心业务模型。 +Users may make direct use of the public benefits shown on their current Provider +account page, or any other legitimate quota, but OneAgent does not promise a +fixed free quota and does not write any benefit into the core business model. -API Key 固定采用用户自己的 Key 本地保存模式。统一网关另立项目,不纳入当前 MVP。 +API Keys are fixed to a model where the user's own Key is stored locally. A +unified gateway is a separate project and is not part of the current MVP. -CC Switch 固定为可选的本机配置工具文档,不打包、不默认安装、不替代 Provider。 +CC Switch is fixed as documentation for an optional local configuration tool. It +is not packaged, not installed by default, and does not replace a Provider. ## Alternatives Considered -### 内置 VPN 或代理以保证下载成功 +### Bundle a VPN or proxy to guarantee downloads succeed -- 优点:用户体验表面上更顺畅。 -- 缺点:改变产品性质,增加网络服务、数据安全和运营责任。 -- 结论:拒绝。 +- Pro: the user experience looks smoother on the surface. +- Con: changes what the product is, and adds network service, data security and + operational responsibility. +- Conclusion: rejected. -### 把所有 Agent 包体直接塞进压缩包 +### Put every Agent package straight into the archive -- 优点:离线安装体验更好。 -- 缺点:许可证、商业授权、版本更新和安全校验成本高。 -- 结论:拒绝。第一版使用官方源、授权镜像和手动安装检测。 +- Pro: better offline install experience. +- Con: high cost in licensing, commercial authorization, version updates and + security verification. +- Conclusion: rejected. The first version uses official sources, authorized + mirrors and detection of manual installs. -### 默认采集 API Key 和请求日志 +### Collect API Keys and request logs by default -- 优点:平台可以集中排错和统计。 -- 缺点:形成高风险敏感数据集中存储,超出本地启动器的必要范围。 -- 结论:拒绝。只保留本地日志和可选的最小匿名事件。 +- Pro: the platform can troubleshoot and gather statistics centrally. +- Con: creates a high-risk central store of sensitive data, beyond what a local + launcher needs. +- Conclusion: rejected. Only local logs and optional minimal anonymous events are + kept. ## Consequences ### Positive -- 产品边界可对外统一表达。 -- 不同用户共用一套启动逻辑。 -- 网络不可达不再被产品解释为需要绕过网络限制。 -- 软件分发、API Key 和第三方工具的责任边界清晰。 -- 后续若要做统一网关或网络服务,可以独立评估,不污染 MVP。 +- The product boundary can be stated the same way to everyone. +- Different users share one activation flow. +- An unreachable network is no longer read by the product as a need to bypass + network restrictions. +- Responsibility boundaries for software distribution, API Keys and third-party + tools are clear. +- If a unified gateway or network service is wanted later, it can be assessed + independently without contaminating the MVP. ### Negative -- 某些网络环境下不能保证一键下载成功。 -- 用户可能需要手动安装或使用其所在组织提供的合规网络。 -- 需要维护官方源、授权镜像和版本校验信息。 -- 公开权益不能由 OneAgent 保证。 +- One-click download cannot be guaranteed to succeed on some networks. +- Users may need to install manually, or use a compliant network provided by + their organization. +- Official sources, authorized mirrors and version verification data have to be + maintained. +- Public benefits cannot be guaranteed by OneAgent. ## Release Gate -发布前必须检查: - -- 包体和脚本不含 VPN、代理、节点订阅和跨境中转。 -- 公开页面不出现“翻墙”“突破限制”“固定免费额度”等表述。 -- 用户 Key 不经过 OneAgent 服务端。 -- Agent 许可证、上游地址、版本和校验值齐全。 -- Provider 权益说明链接到官方页面,并注明以账户实际显示为准。 -- CC Switch 只作为可选配置文档。 -- 网络不可达时有明确、合规的手动安装提示。 - +The following must be checked before release: + +- The package and scripts contain no VPN, proxy, node subscription or + cross-border relay. +- Public pages do not use wording such as "bypass the firewall", "break through + restrictions" or "fixed free quota". +- User Keys do not pass through an OneAgent server. +- Agent licenses, upstream addresses, versions and checksums are complete. +- Provider benefit descriptions link to the official page and note that what the + account actually shows is authoritative. +- CC Switch appears only as optional configuration documentation. +- There is a clear, compliant manual install hint when the network is + unreachable. diff --git a/docs/decisions/ADR-003-three-platform-python-core-and-release-policy.md b/docs/decisions/ADR-003-three-platform-python-core-and-release-policy.md index 18ce5223..638838a8 100644 --- a/docs/decisions/ADR-003-three-platform-python-core-and-release-policy.md +++ b/docs/decisions/ADR-003-three-platform-python-core-and-release-policy.md @@ -1,33 +1,58 @@ -# ADR-003:三平台运行时与版本锁定发行策略(已废弃) - -> 状态:**Superseded**(2026-07-31)。当前实现和发行规则由 [ADR-007](ADR-007-wails-v3-go-migration.md)、[ADR-005](ADR-005-channel-neutral-distribution-and-compliance.md) 和 `cmd/oneagent-release` 定义。本文件只保留历史背景,不是安装或发布操作指南。 - -> 补注(2026-08-04):本文提到的 `cmd/oneagent-release`、`cmd/oneagent-rc`、 -> `cmd/oneagent-provider-smoke` 已于 `23805b0` 移除,职责交给 -> `.github/workflows/build-artifacts.yml`。相关命令是历史背景,不可执行。 - -## 历史背景 - -早期 OneAgent 使用跨平台脚本和 Python 标准库实现 Agent catalog、配置适配、安装编排和本地 HTTP GUI。该方案曾强调三平台路径、权限、锁定版本、npm/uv allowlist、完整错误码和 cleanroom 证据。 - -这些产品约束仍然有效,但实现已经迁移为: - -- Go catalog、provider、install、config、profile、securefs 和 process 包。 -- `cmd/oneagent` 纯 Go CLI 与 `cmd/oneagent-desktop` Wails 应用。 -- React 通过生成的 Wails bindings 调用 Go service。 -- `cmd/oneagent-release` 生成原生 Wails/Go 包、manifest、SHA-256 和第三方 notices。 -- `cmd/oneagent-rc` 与 `cmd/oneagent-provider-smoke` 承担发行候选检查。 - -## 仍保留的产品约束 - -- Agent 包不进入 OneAgent 发行包;安装只能来自 lock 声明的官方源或用户明确选择的 HTTPS 镜像。 -- 子进程使用参数数组、受控环境和超时;禁止 shell 拼接和未审查的下载管道。 -- API Key 不进入 profile、日志、URL、命令行、React 状态或发行附件。 -- 配置写入必须备份、原子替换并收紧 Unix mode/Windows ACL。 -- Codex、Claude Code 和 OpenAI-compatible Agent 按实际协议分别探测。 -- Wails Alpha 阶段只发布 `technical-preview-unsigned`;Stable 需要单独的签名、公证和原生验证证据。 -- Aider 是可选外部上游例外:用户选择安装时需要已有 Python 3.12,OneAgent 不捆绑或下载该运行时。 - -## 迁移记录 - -Python 实现、Python 测试、PyInstaller/wheel/setuptools 配置和相关工作流已删除。新的验收清单见 [Wails v3 迁移收尾计划](../internal/wails-v3-migration-plan.md)。 +# ADR-003: Three-Platform Runtime and Version-Locked Release Policy (Obsolete) + +> Status: **Superseded** (2026-07-31). The current implementation and release +> rules are defined by [ADR-007](ADR-007-wails-v3-go-migration.md), +> [ADR-005](ADR-005-channel-neutral-distribution-and-compliance.md) and +> `cmd/oneagent-release`. This file is kept for historical background only; it is +> not an install or release guide. + +> Addendum (2026-08-04): `cmd/oneagent-release`, `cmd/oneagent-rc` and +> `cmd/oneagent-provider-smoke`, mentioned in this document, were removed in +> `23805b0`, with their responsibilities handed to +> `.github/workflows/build-artifacts.yml`. The commands involved are historical +> background and are not executable. + +## Historical Background + +Early OneAgent used cross-platform scripts and the Python standard library to +implement the Agent catalog, config adaptation, install orchestration and a local +HTTP GUI. That approach emphasized three-platform paths, permissions, locked +versions, an npm/uv allowlist, a complete set of error codes, and cleanroom +evidence. + +Those product constraints still hold, but the implementation has since moved to: + +- Go catalog, provider, install, config, profile, securefs and process packages. +- The pure Go CLI `cmd/oneagent` and the Wails app `cmd/oneagent-desktop`. +- React calling Go services through generated Wails bindings. +- `cmd/oneagent-release` producing native Wails/Go packages, manifests, SHA-256 + values and third-party notices. +- `cmd/oneagent-rc` and `cmd/oneagent-provider-smoke` carrying out release + candidate checks. + +## Product Constraints That Still Hold + +- Agent packages do not go into the OneAgent release bundle; installation may + only come from an official source declared in the lock file, or an HTTPS mirror + the user explicitly chose. +- Subprocesses use argument arrays, a controlled environment and timeouts; shell + string concatenation and unreviewed download pipelines are forbidden. +- API Keys do not go into a profile, a log, a URL, a command line, React state, + or a release attachment. +- Config writes must back up, replace atomically, and tighten the Unix mode or + Windows ACL. +- Codex, Claude Code and OpenAI-compatible Agents are probed separately according + to the protocol each one actually uses. +- During the Wails Alpha phase, only `technical-preview-unsigned` is released; + Stable requires separate signing, notarization and native verification + evidence. +- Aider is an optional external upstream exception: when a user chooses to + install it, Python 3.12 must already be present, and OneAgent neither bundles + nor downloads that runtime. + +## Migration Record + +The Python implementation, the Python tests, the PyInstaller/wheel/setuptools +configuration and the related workflows have been deleted. For the new acceptance +checklist see the +[Wails v3 migration wrap-up plan](../internal/wails-v3-migration-plan.md). diff --git a/docs/decisions/ADR-004-per-agent-protocol-verification.md b/docs/decisions/ADR-004-per-agent-protocol-verification.md index 137d220e..7001e925 100644 --- a/docs/decisions/ADR-004-per-agent-protocol-verification.md +++ b/docs/decisions/ADR-004-per-agent-protocol-verification.md @@ -1,4 +1,4 @@ -# ADR-004:按 Agent 协议验证与 `PROTOCOL_UNSUPPORTED` 错误码 +# ADR-004: Per-Agent Protocol Verification and the `PROTOCOL_UNSUPPORTED` Error Code ## Status @@ -10,61 +10,98 @@ Accepted ## Context -[ADR-003](ADR-003-three-platform-python-core-and-release-policy.md) 冻结了五个自动配置 Agent 与配置适配器映射,但早期连接测试始终只发一种请求:`POST /v1/chat/completions`。 +[ADR-003](ADR-003-three-platform-python-core-and-release-policy.md) froze the five +auto-configured Agents and their config adapter mapping, but the early connection +test only ever sent one kind of request: `POST /v1/chat/completions`. -这与 Agent 配置后的真实行为不一致: +That does not match what an Agent actually does once it is configured: -| Agent | 配置写入的协议 | +| Agent | Protocol written by the config | | --- | --- | -| Codex | Responses(`installer.write_codex_config` 写死 `wire_api = "responses"`) | +| Codex | Responses (`installer.write_codex_config` hardcodes `wire_api = "responses"`) | | Claude Code | Anthropic Messages | -| OpenCode、Kilo CLI、Aider | OpenAI-compatible | +| OpenCode, Kilo CLI, Aider | OpenAI-compatible | -README 早已声明"同一个模型 ID 不一定同时兼容 OpenAI、Anthropic 和 Responses 协议",但这一约束没有进入任何代码路径。 +The README had long stated that "the same model ID is not necessarily compatible +with the OpenAI, Anthropic, and Responses protocols at the same time", but that +constraint never reached any code path. -2026 年 7 月 26 日对一个 OpenAI-compatible 中转端点的 36 个文本模型实测(跳过 24 个图像、视频、语音与 embedding 模型,因为用对话载荷调用它们可能触发单独计费的生成任务): +On 2026-07-26 we measured 36 text models on an OpenAI-compatible relay endpoint, +skipping 24 image, video, speech, and embedding models because calling them with a +chat payload can trigger a separately billed generation job: -| 协议 | 通过 | +| Protocol | Passed | | --- | --- | | Chat Completions | 31 / 36 | | Anthropic Messages | 23 / 36 | | Responses | 10 / 36 | -在 30 个能明确判定的模型中只有 10 个支持 Responses。端点以两种形式明确拒绝,均可检测: +Of the 30 models that could be judged conclusively, only 10 support Responses. The +endpoint rejects the request in two explicit forms, both detectable: -- `400 INVALID_REQUEST_BODY`,消息含 `does not support endpoint: responses` -- `500`,消息含 `not implemented` +- `400 INVALID_REQUEST_BODY`, with a message containing + `does not support endpoint: responses` +- `500`, with a message containing `not implemented` -因此原实现存在一条可复现的失败路径:用户选择一个只支持 Chat Completions 的模型 → 连接测试通过 → OneAgent 写入 Codex 配置 → Codex 首次请求失败,且 OneAgent 的输出中没有任何线索指向根因。 +So the original implementation had a reproducible failure path: the user picks a +model that only supports Chat Completions, the connection test passes, OneAgent +writes the Codex config, Codex fails on its first request, and nothing in +OneAgent's output points at the root cause. ## Decision -### 协议映射 +### Protocol mapping -每个 Agent 的推理协议由 `agents.lock.json` 的 `config_adapter` 推导,映射表位于 `internal/catalog`,与配置写入使用同一来源,避免两处漂移。未登记的适配器回退为 OpenAI-compatible。 +Each Agent's inference protocol is derived from the `config_adapter` field in +`agents.lock.json`. The mapping table lives in `internal/catalog` and uses the same +source as config writing, so the two cannot drift apart. An unregistered adapter +falls back to OpenAI-compatible. -### 验证时机 +### When verification runs -`install_many` 在写入任何配置**之前**,对所选 Agent 涉及的每种协议各发一次最小请求。相同协议只探测一次。`--skip-test` 与 `--check-agent-only` 维持原语义,跳过探测。 +**Before** writing any config, `install_many` sends one minimal request for each +protocol involved in the selected Agents. The same protocol is probed only once. +`--skip-test` and `--check-agent-only` keep their original meaning and skip the +probe. -### 失败处理 +### Failure handling -探测到协议不兼容时,该 Agent 以 `PROTOCOL_UNSUPPORTED` 失败,**不写入配置文件,也不写入环境摘要**。不提供"忽略警告继续写入"的路径:写出一份注定失败的配置,只会把错误从 OneAgent 转移到 Agent 内部,且失去可读的错误信息。 +When the probe finds a protocol incompatibility, that Agent fails with +`PROTOCOL_UNSUPPORTED` and **no config file and no environment summary are +written**. There is no "ignore the warning and write anyway" path: writing a config +that is guaranteed to fail only moves the error out of OneAgent and into the Agent, +where the readable error message is lost. -### 错误码 +### Error code -新增 `PROTOCOL_UNSUPPORTED`,退出码 `7`。这是对 [ADR-003](ADR-003-three-platform-python-core-and-release-policy.md) 错误契约的**增量扩展**:不修改、不复用任何既有错误码,既有客户端的行为不变。 +`PROTOCOL_UNSUPPORTED` is added, with exit code `7`. This is an **additive +extension** of the [ADR-003](ADR-003-three-platform-python-core-and-release-policy.md) +error contract: no existing error code is modified or reused, and existing clients +behave exactly as before. -该错误 `retryable = false`。配额超限(`429`)、上游过载(`503`)和超时仍按原有的可重试语义处理——繁忙的上游不等于不支持该协议的模型。 +This error has `retryable = false`. Quota exhaustion (`429`), upstream overload +(`503`), and timeouts keep their existing retryable semantics -- a busy upstream is +not the same thing as a model that does not support the protocol. -### 本地 API +### Local API -`POST /api/probe` 接受可选的 `agents` 数组,按其协议逐一探测,并在 `protocols` 字段返回每种协议的结果。未提供 `agents` 时维持原有的 OpenAI-compatible 单协议行为,保证旧客户端兼容。 +`POST /api/probe` accepts an optional `agents` array, probes each one according to +its protocol, and returns per-protocol results in the `protocols` field. When +`agents` is not supplied it keeps the original single-protocol OpenAI-compatible +behavior, which preserves compatibility for older clients. ## Consequences -- 用户在写入配置前就会知道模型与 Agent 不兼容,而不是在 Agent 内部遇到无上下文的错误。 -- 同一个模型对不同 Agent 的判定相互独立:一个模型可能被 Codex 拒绝、同时正常配置 OpenCode。 -- 一次多选 Agent 的激活最多发出三次探测请求,而非一次。 -- `/v1/models` 返回的清单仍未按协议过滤或标注,用户仍可能选中非对话模型;此时探测必然失败,因此不会写出损坏配置,但错误信息表述为"不支持该协议"而非"这不是对话模型"。该问题单独跟踪。 -- 正式 Release Candidate 仍须以真实 Agent 首次请求为门禁;本地探测不能替代 PPIO 与 Novita 的正式验收。 +- The user learns that a model is incompatible with an Agent before any config is + written, instead of hitting a context-free error inside the Agent. +- The verdict for one model is independent per Agent: a model may be rejected by + Codex and configure OpenCode successfully at the same time. +- Activating several Agents at once sends at most three probe requests instead of + one. +- The list returned by `/v1/models` is still neither filtered nor annotated by + protocol, so the user can still select a non-chat model. The probe is then + guaranteed to fail, so no broken config is written, but the error message reads + "this protocol is not supported" rather than "this is not a chat model". That + problem is tracked separately. +- A formal Release Candidate must still gate on a real Agent's first request; a + local probe is no substitute for formal acceptance against PPIO and Novita. diff --git a/docs/decisions/ADR-005-channel-neutral-distribution-and-compliance.md b/docs/decisions/ADR-005-channel-neutral-distribution-and-compliance.md index f835c986..b5346c39 100644 --- a/docs/decisions/ADR-005-channel-neutral-distribution-and-compliance.md +++ b/docs/decisions/ADR-005-channel-neutral-distribution-and-compliance.md @@ -1,8 +1,9 @@ -# ADR-005:渠道无关的二进制分发与合规门禁 +# ADR-005: Channel-Neutral Binary Distribution and Compliance Gates -> 补注(2026-08-04):本文提到的 `cmd/oneagent-release`、`cmd/oneagent-rc`、 -> `cmd/oneagent-provider-smoke` 已于 `23805b0` 移除,职责交给 -> `.github/workflows/build-artifacts.yml`。相关命令是历史背景,不可执行。 +> Addendum (2026-08-04): `cmd/oneagent-release`, `cmd/oneagent-rc`, and +> `cmd/oneagent-provider-smoke`, all mentioned below, were removed in `23805b0`; +> their responsibilities moved to `.github/workflows/build-artifacts.yml`. The +> commands here are historical background and are not executable. ## Status @@ -14,92 +15,155 @@ Accepted ## Context -早期发行计划以 GitHub Actions、四平台产物和 GitHub Release 为中心。当前产品目标已经收敛为直接分发 OneAgent 二进制包,下载渠道可能是 GitHub、官网、网盘或企业云盘,并不固定在某个平台。 +The early release plan was built around GitHub Actions, four-platform artifacts, and +GitHub Releases. The current product goal has narrowed to distributing the OneAgent +binary package directly, where the download channel may be GitHub, the official +site, a file-sharing service, or a corporate cloud drive, and is not tied to any one +platform. -如果每个渠道独立重新打包,或者把第三方 Agent 二进制转存到网盘,会产生版本不可追溯、校验值不一致、许可证义务遗漏、品牌混淆和安全撤回不完整等问题。渠道可用也不代表包体内容具有再分发权利。 +If every channel repackages independently, or third-party Agent binaries get +re-hosted on a file-sharing service, the result is untraceable versions, +inconsistent checksums, missed licence obligations, brand confusion, and incomplete +security withdrawals. A channel being available also does not mean the package +contents carry redistribution rights. ## Decision -### 分发模型 - -OneAgent 采用“一个官方构建、多个同包镜像”的分发模型: - -- GitHub、官网、网盘和企业云盘只是可替换的下载渠道。 -- 同一版本的所有渠道必须分发字节一致、SHA-256 一致的产物。 -- 渠道方不得重新压缩、替换文件、加入推广内容或改变版本标识。 -- 每个镜像写入渠道台账,并支持跨渠道同步撤回。台账为人工流程,没有自动门禁。 - -### 包体边界 - -- 默认只分发 OneAgent 自有代码和完成许可证义务的运行依赖。 -- 不分发第三方 Agent 二进制,不把官方可下载等同于允许再分发。 -- Agent 安装继续采用官方源、授权镜像、用户手动安装和 `guide-only` 的降级顺序。 -- 不捆绑 Node.js、Git Bash、VPN、代理、共享 Key 或第三方配置工具;Aider 的 Python 3.12 仅是用户选择 Aider 时的外部上游前置条件。 - -### 当前发行范围 - -- 当前目标是可直接下载和运行的技术预览二进制包。分渠道分发不要求四平台全部齐备,但每个实际发布的平台仍须在对应操作系统原生构建,并以 `ci.yml` 的 cleanroom 作业或 Release Candidate 流程作为平台验收证据。 -- 每个产物只声明其实际构建和验证过的目标环境,不对未构建环境作兼容承诺。 -- 平台签名、公证、商店分发和自动更新不属于当前阶段。 -- 未完成更高等级发行门禁前继续使用 `technical-preview-unsigned`,不使用 Stable 标签。Stable 门槛本身仍然有效,并由 `cmd/oneagent-release` 的后续签名阶段对产物执行验证(macOS `codesign` / Windows Authenticode);当前阶段只是不发布 Stable。 - -### 合规门禁 - -所有渠道共享同一套权利、品牌、secret、安全、隐私、包体和渠道台账检查。完整规范见 [OneAgent 多渠道分发与合规政策](../distribution-compliance-policy.md)。 +### Distribution model + +OneAgent uses a "one official build, many identical mirrors" distribution model: + +- GitHub, the official site, file-sharing services, and corporate cloud drives are + interchangeable download channels, nothing more. +- Every channel for a given version must distribute byte-identical artifacts with + identical SHA-256 checksums. +- Channel operators must not recompress, substitute files, add promotional content, + or alter version identifiers. +- Every mirror is recorded in the channel ledger, which supports withdrawal + synchronized across channels. The ledger is a manual process with no automated + gate. + +### Package boundary + +- By default, only OneAgent's own code and the runtime dependencies whose licence + obligations have been satisfied are distributed. +- Third-party Agent binaries are not distributed; being officially downloadable is + not equivalent to being redistributable. +- Agent installation keeps its fallback order: official source, authorized mirror, + manual user installation, then `guide-only`. +- Node.js, Git Bash, VPNs, proxies, shared Keys, and third-party configuration tools + are not bundled. Aider's Python 3.12 is an external upstream prerequisite that + applies only when the user chooses Aider. + +### Current release scope + +- The current target is a technical preview binary package that can be downloaded + and run directly. Per-channel distribution does not require all four platforms to + be complete, but each platform that is actually released must still be built + natively on the corresponding operating system, with the `ci.yml` cleanroom job or + the Release Candidate process as the platform acceptance evidence. +- Each artifact declares only the target environments it was actually built and + verified on, and makes no compatibility promise for environments that were not + built. +- Platform signing, notarization, store distribution, and auto-update are out of + scope for the current stage. +- `technical-preview-unsigned` remains in use until the higher-tier release gates + are met; the Stable label is not used. The Stable bar itself remains in force and + is verified against the artifacts by the later signing stage of + `cmd/oneagent-release` (macOS `codesign` / Windows Authenticode); the current + stage simply does not publish Stable. + +### Compliance gates + +All channels share one set of rights, brand, secret, security, privacy, package, and +channel-ledger checks. For the full specification see +[OneAgent multi-channel distribution and compliance policy](../distribution-compliance-policy.md). ## Relationship To Previous Decisions -- ADR-002 的网络访问、共享 Key、第三方 Agent 和配置工具边界继续有效。 -- ADR-003 的版本锁定、配置适配和权限约束继续有效;其旧运行时实现已由 ADR-007 的 Go/Wails 路径取代。 -- ADR-003 中“四平台同时作为当前发行门槛”的部分被本 ADR 收窄:解除“四平台必须同时齐备”的耦合,不解除任何单平台的原生构建与验收要求;平台矩阵可以作为后续扩展,不再阻塞当前渠道分发目标。 -- ADR-004 的按 Agent 协议验证继续有效。 +- The ADR-002 boundaries on network access, shared Keys, third-party Agents, and + configuration tools remain in force. +- The ADR-003 version pinning, config adaptation, and permission constraints remain + in force; its old runtime implementation has been replaced by the Go/Wails path in + ADR-007. +- The part of ADR-003 that made "all four platforms simultaneously" the current + release bar is narrowed by this ADR: the coupling requiring all four platforms to + be complete at once is removed, and no single platform's native build and + acceptance requirement is removed. The platform matrix can be a later expansion + and no longer blocks the current channel distribution goal. +- The ADR-004 per-Agent protocol verification remains in force. ## Alternatives Considered -### 指定一个渠道为权威源,其余标注为镜像 - -- 优点:概念简单,信任链清晰。 -- 缺点:接收方需要跨渠道核对才能建立信任,而离线拷贝和企业云盘根本无法核对。权威源不可达时,镜像产物退化为不可验证。 -- 结论:拒绝。可验证性必须内含在产物本身,而不是依附于下载来源。 - -### 允许渠道重打包,但由渠道重新生成 manifest 与校验和 - -- 优点:渠道可以自由添加自己的说明文件或调整目录结构。 -- 缺点:等于每个渠道各自签发一套校验值,接收方无法判断哪一套是官方的,恶意篡改与善意重打包不可区分。 -- 结论:拒绝。渠道特定说明只能写在渠道页面,不进包体。 - -### 引入 GPG 或 sigstore 发布签名替代校验和自证 - -- 优点:能提供来源证明,而非仅完整性证明。 -- 缺点:需要密钥管理、轮换与吊销流程,接收方还需安装验证工具。当前连 macOS/Windows 代码签名证书都没有,先做发布签名属于顺序颠倒。 -- 结论:暂不采用。取得代码签名证书、进入 Stable 路径后重新评估,届时需要新的 ADR。 - -### 把全部合规规则继续散列在 README 与产品边界基线中 - -- 优点:不增加文档数量。 -- 缺点:本次落地前的状态已经证明会漂移——同一批规则在两处措辞和粒度都不同,发包时无法确定以哪份为准,并且出现过文档声称门禁已解除而代码仍在强制的矛盾。 -- 结论:拒绝。改为分层:产品边界基线负责“能不能做”的准入判断,本 ADR 与合规政策负责“怎么发”的操作约束,README 保留面向读者的摘要并链向政策。三者不重复列举同一条规则。 +### Designate one channel as the authoritative source and mark the rest as mirrors + +- Pro: conceptually simple, with a clear chain of trust. +- Con: recipients have to cross-check across channels to establish trust, and offline + copies and corporate cloud drives cannot be cross-checked at all. When the + authoritative source is unreachable, mirror artifacts degrade to unverifiable. +- Conclusion: rejected. Verifiability must be contained in the artifact itself rather + than depend on the download source. + +### Allow channels to repackage, with the channel regenerating the manifest and checksums + +- Pro: channels are free to add their own notes or adjust the directory layout. +- Con: this amounts to each channel issuing its own set of checksums; recipients + cannot tell which set is official, and malicious tampering becomes + indistinguishable from well-intentioned repackaging. +- Conclusion: rejected. Channel-specific notes belong on the channel page, not in the + package. + +### Adopt GPG or sigstore release signing in place of self-attesting checksums + +- Pro: provides proof of provenance rather than only proof of integrity. +- Con: it requires key management, rotation, and revocation processes, and recipients + also have to install verification tooling. We do not yet have even macOS/Windows + code signing certificates, so doing release signing first is out of order. +- Conclusion: not adopted for now. Reassess after obtaining code signing certificates + and entering the Stable path; that will require a new ADR. + +### Keep all compliance rules scattered across the README and the product boundary baseline + +- Pro: no increase in the number of documents. +- Con: the state before this work landed already proved that this drifts -- the same + set of rules had different wording and granularity in two places, there was no way + to tell which one governed at release time, and at one point the docs claimed a + gate had been lifted while the code still enforced it. +- Conclusion: rejected. Replaced by a layered split: the product boundary baseline + owns the "may we do this" admission decision, this ADR and the compliance policy + own the "how do we ship it" operational constraints, and the README keeps a + reader-facing summary that links to the policy. None of the three restates the same + rule. ## Consequences ### Positive -- GitHub、网盘和官网可以使用相同产物,不需要维护渠道分支。 -- 用户可以通过 SHA-256 判断镜像是否被替换。 -- 不把第三方 Agent 包体混入 OneAgent,降低版权、供应链和版本维护风险。 -- 发生漏洞、密钥泄露或版权投诉时,可以定位并同步撤回全部渠道。 +- GitHub, file-sharing services, and the official site can use the same artifact, with + no channel branches to maintain. +- Users can tell from the SHA-256 whether a mirror has been substituted. +- Not mixing third-party Agent packages into OneAgent lowers copyright, supply chain, + and version maintenance risk. +- When a vulnerability, key leak, or copyright complaint occurs, every channel can be + located and withdrawn in sync. ### Negative -- 网络不可达时不能通过转存第三方 Agent 二进制保证一键安装。 -- 需要维护渠道台账、许可证清单和跨渠道撤回流程。 -- 未覆盖的平台不能因为源码理论兼容就出现在发行承诺中。 +- When the network is unreachable, one-click installation cannot be guaranteed by + re-hosting third-party Agent binaries. +- The channel ledger, licence inventory, and cross-channel withdrawal process have to + be maintained. +- Platforms that are not covered must not appear in release promises just because the + source is theoretically compatible. ## Release Gate -- 所有镜像 SHA-256 一致。 -- 包内不存在未授权 Agent 二进制、共享凭据、代理工具和用户配置。 -- 权利清单、第三方许可证、版本清单和发行说明齐全。 -- 自动安装来源位于固定 allowlist。 -- 技术预览状态、目标环境和已知限制明确。 -- 渠道负责人、链接、上传时间和撤回状态可追溯。 +- SHA-256 identical across all mirrors. +- No unauthorized Agent binaries, shared credentials, proxy tools, or user configs in + the package. +- Rights inventory, third-party licences, version manifest, and release notes all + complete. +- Automatic installation sources confined to a fixed allowlist. +- Technical preview status, target environments, and known limitations stated + explicitly. +- Channel owner, link, upload time, and withdrawal status traceable. diff --git a/docs/decisions/ADR-006-multi-profile-and-long-term-management.md b/docs/decisions/ADR-006-multi-profile-and-long-term-management.md index b1654ae3..1c7c775a 100644 --- a/docs/decisions/ADR-006-multi-profile-and-long-term-management.md +++ b/docs/decisions/ADR-006-multi-profile-and-long-term-management.md @@ -1,9 +1,10 @@ -# ADR-006:多 Profile 与长期环境管理 +# ADR-006: Multiple Profiles and Long-Term Environment Management ## Status -Implemented,凭据投递部分已被 [ADR-008](ADR-008-credentials-in-agent-config-files.md) 取代 -(详见下方「修订」小节)。多 Profile 与长期管理的结论仍然有效。 +Implemented; the credential delivery part is superseded by +[ADR-008](ADR-008-credentials-in-agent-config-files.md) (see the "Revision" section +below). The conclusions about multiple Profiles and long-term management still hold. ## Date @@ -11,90 +12,155 @@ Implemented,凭据投递部分已被 [ADR-008](ADR-008-credentials-in-agent-co ## Context -OneAgent 目前是一次性向导:激活完成即结束,`~/.oneagent/profile.json` 只保存单一激活态(`schema_version: 1`:一个 provider、一个 model、一份 agent 列表),`EnvironmentOverviewPage` 是只读页面。激活之后用户的长期需求没有载体: - -- 在多个 Provider(或同一 Provider 的多个模型)之间切换,必须重走一遍七页向导。 -- Agent 版本落后于 `agents.lock.json` 的锁定版本时(`status_payload` 已能对比出 `version` 与 `lockedVersion`),界面没有任何提示。 -- 写入配置时 `atomic_write` 已经产生 `*.backup-` 备份,但用户看不到、也无法回滚。 - -用户事实上在用 CC Switch 做 Profile 切换(见 [CC Switch 配置指引](../ai-agent-kit/tools/cc-switch.md))。这说明切换需求真实存在,CC Switch 文档也记录了一条关键教训:**切换配置后 Agent 不会自动重新加载**,不能显示"已切换"就了事。 +OneAgent is currently a one-shot wizard: it ends the moment setup completes, +`~/.oneagent/profile.json` stores a single active state (`schema_version: 1`: one +provider, one model, one agent list), and `EnvironmentOverviewPage` is a read-only +page. After setup there is nowhere for the user's long-term needs to live: + +- Switching between Providers, or between models of the same Provider, means walking + through all seven wizard pages again. +- When an Agent version falls behind the version pinned in `agents.lock.json` -- + `status_payload` can already compare `version` against `lockedVersion` -- the UI + gives no hint at all. +- Config writes already produce `*.backup-` backups through `atomic_write`, but + the user cannot see them and cannot roll back. + +Users are in fact using CC Switch to switch Profiles (see the +[CC Switch configuration guide](../ai-agent-kit/zh/tools/cc-switch.md)). That shows +the need to switch is real, and the CC Switch document also records one key lesson: +**an Agent does not reload its configuration automatically after a switch**, so it is +not enough to display "switched" and stop there. ## Decision -### 存储布局 +### Storage layout ```text ~/.oneagent/ - profile.json # schema_version: 2,当前激活指针 {active: } - profiles/ # 每套配置一个文件,不含 Key + profile.json # schema_version: 2, active pointer {active: } + profiles/ # one file per configuration, no Key inside .json - secrets/ # 每套配置的密钥文件,0600 / Windows ACL + secrets/ # secret file per configuration, 0600 / Windows ACL .env ``` -- Profile 记录:`id`、`label`、`provider`、`api_base_url`、`model`、`agent_ids`、`created_at`、`last_activated_at`。**Key 不进 profile 文件**(产品边界与 CLAUDE.md 硬约束)。 -- `id` 是受限 slug(`[a-z0-9][a-z0-9_-]*`),非法输入返回 `INVALID_REQUEST`。 -- `secrets/.env` 保存该 profile 模板的 Key 与 Base URL。Agent 实际读取的凭据在各自的配置文件里(见下方修订小节与 ADR-008)。 - -### v1 → v2 迁移 - -读到 `schema_version: 1` 的 `profile.json` 时自动迁移:先 `backup_file` 备份原文件,再把内容转成 `profiles/default.json` 并写入 v2 指针。任何情况下不对旧文件直接报错。迁移必须由测试固定("读 v1 文件"用例),防止后续重构悄悄破坏老用户。 - -### 写入与切换 - -- 向导激活(`install_many` 收尾的 `write_profile`)变为"更新或创建当前激活 profile":同一 `provider + model` 沿用原 id 并保留 `agent_ids` 合并语义,否则新建。 -- 切换 = 用另一组参数重写同一批配置文件,**完全复用现有写入链路**(`_write_agent_config` 分派 + `atomic_write` + 备份),不引入新的写入逻辑。 -- `POST /api/activate` 的响应必须携带逐 Agent 的**重启指引**(采纳 CC Switch 教训:Agent 不自动重载配置),而不是只返回"已切换"。 -- Profile 操作统一复用 Go `ProfileService` 和 `securefs` 写入边界,不新增 HTTP 通道。Key 只落 `secrets/`,binding 返回公开摘要。 +- A Profile record holds `id`, `label`, `provider`, `api_base_url`, `model`, + `agent_ids`, `created_at`, `last_activated_at`. **The Key does not go into the + profile file** (a product boundary and a hard constraint in CLAUDE.md). +- `id` is a restricted slug (`[a-z0-9][a-z0-9_-]*`); invalid input returns + `INVALID_REQUEST`. +- `secrets/.env` stores the Key and Base URL for that profile template. The + credentials an Agent actually reads live in its own config file (see the Revision + section below and ADR-008). + +### v1 to v2 migration + +When a `profile.json` with `schema_version: 1` is read, migrate it automatically: +back the original file up with `backup_file` first, then convert its contents into +`profiles/default.json` and write the v2 pointer. Under no circumstances does an old +file cause an error outright. The migration must be pinned by a test (the "read a v1 +file" case), so that later refactoring cannot quietly break existing users. + +### Writing and switching + +- Wizard setup (the `write_profile` that closes out `install_many`) becomes "update or + create the currently active profile": the same `provider + model` reuses the + original id and keeps the `agent_ids` merge semantics, otherwise a new profile is + created. +- Switching means rewriting the same set of config files with another set of + parameters, **fully reusing the existing write path** (`_write_agent_config` + dispatch plus `atomic_write` plus backup); no new write logic is introduced. +- The response to `POST /api/activate` must carry per-Agent **restart instructions** + (adopting the CC Switch lesson that an Agent does not reload config on its own), + rather than returning only "switched". +- Profile operations all reuse the Go `ProfileService` and the `securefs` write + boundary; no new HTTP channel is added. The Key only lands in `secrets/`, and the + binding returns a public summary. ### CLI -新增子命令 `oneagent profile list / add / activate / remove`。`argv[1]` 不是已知子命令时走原有扁平解析器,保持向后兼容。 - -### Overview 管理化 - -- Profile 卡片 + 激活标识 + 一键切换。 -- Agent 行展示 `version` 对 `lockedVersion` 的漂移,"更新"走现有安装链路。 -- 路由调整:已有 profile 时根路径进 `/overview`,没有才进向导。这一条是"长期工具"定位最直接的体现。 -- 备份的列表与回滚(`*.backup-` 已存在但未暴露)作为可选的后续增量(3b),需要新端点,单独评估。 - -### 明确不做 - -- **自动改写 shell rc**:`--wire-shell` 仍作为独立显式开关,在第 2 层之后单独评估。 -- **Agent 进程自动重载**:不同 Agent 的生效方式不同,不做进程操作,只给重启指引。 - -## 修订:从全局 profile 改为 per-agent 独立配置 - -本 ADR 初稿把「per-agent 独立 profile」列为不做,理由是 `~/.oneagent/env` 天然全局共享。该理由已被推翻:共享 env 不是外部约束,而是我们自己写进三个 Agent 配置的同名变量 `ONEAGENT_API_KEY` 造成的人为耦合。五个 Agent 的配置本来就落在各自的文件里,Claude Code 与 Aider 的凭据早已独立,只有 Codex、OpenCode、Kilo CLI 因为共用一个变量名才无法在同一 shell 里指向不同 Provider。 - -因此改为 per-agent 独立凭据。第一版用 `ONEAGENT_API_KEY_` 加 `~/.oneagent/agents/.env` 实现,**已被 ADR-008 取代**:凭据现在写进 Agent 自己的配置文件(Codex 用 `~/.codex/auth.json`,Claude Code 用 `settings.json` 的 `env` 块,OpenCode/Kilo 用配置里的 `options.apiKey`),不再需要 sourced env 文件。解耦与「失败只影响单个 Agent」的结论不变。 - -`profiles/` 存储保留,语义从「唯一激活态」改为**可复用模板**:三个 Agent 共用同一 Provider 与 Key 是常见场景,模板避免重复输入。 +Add the subcommands `oneagent profile list / add / activate / remove`. When `argv[1]` +is not a known subcommand, fall through to the existing flat parser to stay backward +compatible. + +### Turning Overview into a management surface + +- Profile cards, an active marker, and one-click switching. +- Agent rows show the drift of `version` against `lockedVersion`; "update" goes + through the existing install path. +- Routing change: when a profile exists, the root path goes to `/overview`; only + without one does it go to the wizard. This is the most direct expression of the + "long-term tool" positioning. +- Listing and rolling back backups (`*.backup-` already exist but are not + exposed) is an optional follow-up increment (3b); it needs a new endpoint and is + evaluated separately. + +### Explicitly out of scope + +- **Rewriting shell rc automatically**: `--wire-shell` remains a separate explicit + flag, evaluated on its own after layer 2. +- **Reloading Agent processes automatically**: different Agents apply configuration + differently, so we do not operate on processes; we only give restart instructions. + +## Revision: from a global profile to per-agent independent configuration + +The first draft of this ADR listed "per-agent independent profiles" as out of scope, +on the grounds that `~/.oneagent/env` is inherently shared globally. That reasoning +has been overturned: a shared env is not an external constraint but artificial +coupling we created ourselves by writing the same variable name, +`ONEAGENT_API_KEY`, into three Agent configs. The configs of all five Agents already +land in separate files, and the credentials for Claude Code and Aider have long been +independent; only Codex, OpenCode, and Kilo CLI could not point at different +Providers in the same shell, and only because they shared one variable name. + +So the decision changes to per-agent independent credentials. The first version +implemented this with `ONEAGENT_API_KEY_` plus +`~/.oneagent/agents/.env`, and **has been superseded by ADR-008**: +credentials are now written into the Agent's own config file (Codex uses +`~/.codex/auth.json`, Claude Code uses the `env` block of `settings.json`, +OpenCode/Kilo use `options.apiKey` in their config), so sourced env files are no +longer needed. The conclusions about decoupling and about a failure affecting only a +single Agent are unchanged. + +The `profiles/` storage stays, with its meaning changed from "the one active state" +to **reusable templates**: three Agents sharing the same Provider and Key is a common +case, and templates avoid retyping. ## Alternatives Considered -### 单个 profile.json 内嵌所有 profile +### Embed every profile inside a single profile.json -- 优点:原子替换简单,无需目录同步。 -- 缺点:文件随 profile 增长;密钥隔离与文件粒度错位;与 CC Switch 用户的心智模型不一致。 -- 结论:拒绝。每 profile 一个文件读写面更小,密钥文件天然分离。 +- Upside: atomic replacement is simple, no directory to keep in sync. +- Downside: the file grows with the number of profiles; secret isolation is + misaligned with file granularity; it does not match the mental model of CC Switch + users. +- Conclusion: rejected. One file per profile has a smaller read/write surface, and + secret files separate naturally. -### per-agent 独立配置 +### Per-agent independent configuration -- 优点:每个 Agent 可以指向不同 Provider。 -- 缺点:共享 env 契约失效,密钥文件数量翻倍,切换语义复杂一档。 -- 结论:拒绝;全局 profile 先行,后续有真实需求再扩展。 +- Upside: each Agent can point at a different Provider. +- Downside: the shared env contract stops working, the number of secret files + doubles, and switching semantics get one level more complex. +- Conclusion: rejected; ship the global profile first and extend later if a real need + appears. -### 维持现状,继续推荐 CC Switch +### Keep things as they are and keep recommending CC Switch -- 优点:零开发量。 -- 缺点:OneAgent 固化为一次性工具,探测/验证能力与切换能力割裂在两个产品里。 -- 结论:拒绝。 +- Upside: zero development effort. +- Downside: OneAgent hardens into a one-shot tool, and the probe/verify capability is + split away from the switching capability across two products. +- Conclusion: rejected. ## Consequences -- `profile.json` schema 变更,迁移是唯一的数据风险点:备份先行 + 测试固定。 -- `status_payload` 增加 `profiles` / `activeProfile` 字段,必须同步 `frontend/src/types/api.ts`(传输契约规则)。 -- CC Switch 文档的推荐顺序需要调整:OneAgent 内置切换为主路径,CC Switch 作为可选下游。 -- Go profile/config tests、React state tests 和 Wails binding tests 覆盖新端点与迁移路径。 -- 备份回滚 UI、per-agent profile、`--wire-shell` 需要各自的后续评估,其中回滚 UI 需要新端点。 +- The `profile.json` schema changes, and migration is the only data risk point: + backup first, and pin it with tests. +- `status_payload` gains `profiles` and `activeProfile` fields, which must be mirrored + in `frontend/src/types/api.ts` (the transport contract rule). +- The recommendation order in the CC Switch document needs adjusting: switching built + into OneAgent is the main path, with CC Switch as an optional downstream. +- Go profile/config tests, React state tests, and Wails binding tests cover the new + endpoints and the migration path. +- The backup rollback UI, per-agent profiles, and `--wire-shell` each need their own + follow-up evaluation; the rollback UI among them needs a new endpoint. diff --git a/docs/decisions/ADR-008-credentials-in-agent-config-files.md b/docs/decisions/ADR-008-credentials-in-agent-config-files.md index b3bc498d..2c071332 100644 --- a/docs/decisions/ADR-008-credentials-in-agent-config-files.md +++ b/docs/decisions/ADR-008-credentials-in-agent-config-files.md @@ -1,4 +1,4 @@ -# ADR-008:凭据写入 Agent 自己的配置文件 +# ADR-008: Credentials Written Into Each Agent's Own Config File ## Status @@ -8,55 +8,100 @@ Implemented 2026-08-03 -- Supersedes: ADR-006 的 `ONEAGENT_API_KEY_` + `~/.oneagent/agents/.env` 凭据投递方案 +- Supersedes: the `ONEAGENT_API_KEY_` + `~/.oneagent/agents/.env` + credential delivery scheme in ADR-006 ## Context -ADR-006 修订版让每个 Agent 读自己的环境变量:`~/.oneagent/agents/.env` 写 `ONEAGENT_API_KEY_`,Codex 的 `config.toml` 用 `env_key` 指向它,OpenCode / Kilo 的 JSON 用 `"apiKey": "{env:...}"` 引用它。这解决了三个 Agent 共用一个变量名的耦合,但保留了 env 文件本身的代价: - -- 配置只在 sourced 过 env 文件的 shell 里生效。用户从 Dock、桌面快捷方式或已开着的终端启动 Agent 就会看到未认证错误,而 OneAgent 的界面显示"已配置"。 -- 每个 Agent 的重启指引都得带一句 `source ~/.oneagent/agents/.env`,桌面的 Launch 按钮也得把这句拼进终端命令,否则打开的窗口跑的是未配置的 Agent。 -- 同一份 Key 落在两处(`secrets/.env` 和 `agents/.env`),加上 `~/.oneagent/env` 兼容层是三处。 - -三个 Agent 都有自己的凭据文件位置,且都是 OneAgent 已经在写的那个文件或它的同目录邻居。CC Switch(Tauri)走的正是这条路:Codex 写 `~/.codex/auth.json`,Claude 写 `settings.json` 的 `env` 块,OpenCode 写 `opencode.json` 的 `provider..options.apiKey`,没有任何 env 文件。 +The revised ADR-006 had every Agent read its own environment variable: +`~/.oneagent/agents/.env` wrote `ONEAGENT_API_KEY_`, the Codex +`config.toml` pointed at it through `env_key`, and the OpenCode / Kilo JSON referenced +it with `"apiKey": "{env:...}"`. That solved the coupling of three Agents sharing one +variable name, but it kept the cost of the env file itself: + +- The configuration only takes effect in a shell that has sourced the env file. A user + who starts an Agent from the Dock, a desktop shortcut, or an already-open terminal + sees an unauthenticated error while the OneAgent UI shows "configured". +- Every Agent's restart instructions had to carry a + `source ~/.oneagent/agents/.env` line, and the desktop Launch button had to + splice that line into the terminal command as well, or the window it opened would be + running an unconfigured Agent. +- The same Key landed in two places (`secrets/.env` and `agents/.env`), three + once you count the `~/.oneagent/env` compatibility layer. + +All three Agents have their own credential file location, and each is either the file +OneAgent already writes or a neighbor in the same directory. CC Switch (Tauri) takes +exactly this route: Codex writes `~/.codex/auth.json`, Claude writes the `env` block +of `settings.json`, OpenCode writes `provider..options.apiKey` in +`opencode.json`, with no env file anywhere. ## Decision -凭据写进 Agent 自己的配置文件,删除全部 env 文件写入逻辑。 +Credentials are written into each Agent's own config file, and all env-file write +logic is deleted. -| Agent | 凭据位置 | +| Agent | Credential location | | --- | --- | -| Codex | `~/.codex/auth.json` 的 `OPENAI_API_KEY`,`auth_mode` 置为 `apikey` | -| Claude Code | `~/.claude/settings.json` 的 `env.ANTHROPIC_AUTH_TOKEN`(本来就是这样) | -| OpenCode | `~/.config/opencode/opencode.json` 的 `provider.oneagent.options.apiKey` | -| Kilo CLI | `~/.config/kilo/kilo.jsonc` 的同一位置 | -| Aider | `~/.oneagent/aider.env`(由 Aider 的 `--env-file` 直接加载) | - -配套改动: - -- Codex 的 `[model_providers.oneagent]` 去掉 `env_key`,加 `requires_openai_auth = true`,让 Codex 用 `auth.json` 里的 Key 认证托管 provider。`auth_mode` 必须显式写成 `apikey`:残留的 `chatgpt` 会让 Codex 优先用缓存的 OAuth token,把新 Key 忽略掉。 -- `auth.json` 先写、`config.toml` 后写。指向一个认证不了的 provider 比留一个暂时没人引用的 Key 更糟。写入复用 `securefs.AtomicWrite`,`auth.json` 按 secret 处理(0600 / Windows ACL,备份同样收紧权限)。 -- OpenCode / Kilo 的配置文件现在含明文 Key,因此按 secret 写入。 -- OpenCode 的路径从 `opencode.jsonc` 改为 `opencode.json`:Key 进了这个文件之后它是 OneAgent 的主要写入目标,`.json` 是 OpenCode 自己的默认名。JSONC 注释检测不再看扩展名(OpenCode 用 JSON5 解析,`.json` 里也可能有注释),检测到就拒写并保留原文件。 -- 删除:`internal/config/env.go`(`WriteAgentEnv` / `WriteSharedEnv` / `agentEnvVar`)、`agents.lock.json` 的 `credential_delivery` 字段、status 的 `paths.env_file` 与 `backups.env`、重启指引和 Launch 命令里的 `source` 前缀;Aider 改由 `--env-file` 加载唯一保留的环境文件。 +| Codex | `OPENAI_API_KEY` in `~/.codex/auth.json`, with `auth_mode` set to `apikey` | +| Claude Code | `env.ANTHROPIC_AUTH_TOKEN` in `~/.claude/settings.json` (already the case) | +| OpenCode | `provider.oneagent.options.apiKey` in `~/.config/opencode/opencode.json` | +| Kilo CLI | the same location in `~/.config/kilo/kilo.jsonc` | +| Aider | `~/.oneagent/aider.env` (loaded directly by Aider's `--env-file`) | + +Accompanying changes: + +- The Codex `[model_providers.oneagent]` block drops `env_key` and adds + `requires_openai_auth = true`, so Codex authenticates the hosted provider with the + Key in `auth.json`. `auth_mode` must be written explicitly as `apikey`: a leftover + `chatgpt` makes Codex prefer a cached OAuth token and ignore the new Key. +- `auth.json` is written first, `config.toml` second. Pointing at a provider that + cannot authenticate is worse than leaving a Key that nothing references yet. The + write reuses `securefs.AtomicWrite`, and `auth.json` is handled as a secret (0600 / + Windows ACL, with the backup's permissions tightened the same way). +- The OpenCode / Kilo config files now contain a plaintext Key, so they are written as + secrets. +- The OpenCode path changes from `opencode.jsonc` to `opencode.json`: once the Key + goes into this file it is OneAgent's primary write target, and `.json` is OpenCode's + own default name. JSONC comment detection no longer looks at the extension (OpenCode + parses with JSON5, so a `.json` file may also contain comments); on detection it + refuses to write and leaves the original file intact. +- Deleted: `internal/config/env.go` (`WriteAgentEnv` / `WriteSharedEnv` / + `agentEnvVar`), the `credential_delivery` field in `agents.lock.json`, the status + fields `paths.env_file` and `backups.env`, and the `source` prefix in the restart + instructions and Launch command; Aider switches to loading the one remaining + environment file through `--env-file`. ## Alternatives Considered -### Codex 继续用 env_key,只改 OpenCode / Kilo +### Keep env_key for Codex and change only OpenCode / Kilo -- 优点:不动 `auth.json`,不碰 Codex 的登录态。 -- 缺点:Codex 是最主要的 Agent,留着 env 文件等于「不依赖环境变量」这个目标没达成,`source` 指引和 Launch 拼接逻辑都得留着。 -- 结论:拒绝。 +- Upside: `auth.json` is left alone, and Codex's login state is untouched. +- Downside: Codex is the primary Agent, so keeping the env file means the goal of "not + depending on environment variables" is not met, and the `source` instructions and + the Launch splicing logic all have to stay. +- Conclusion: rejected. -### `codex login --api-key` 代替直接写 auth.json +### `codex login --api-key` instead of writing auth.json directly -- 优点:用 Codex 官方入口,格式由它自己保证。 -- 缺点:多一次子进程调用与超时处理,且它会覆盖整个 `auth.json`(丢掉用户的 OAuth 缓存)。直接 merge 只改两个键。 -- 结论:拒绝。 +- Upside: it uses the official Codex entry point, which guarantees the format itself. +- Downside: one more subprocess call and timeout to handle, and it overwrites the + whole of `auth.json` (losing the user's OAuth cache). Merging directly touches only + two keys. +- Conclusion: rejected. ## Consequences -- `auth_mode = "apikey"` 会让 Codex Desktop 把账号视作 API-Key 认证,ChatGPT 登录相关的功能(Fast mode 等)不可用。这是用托管 provider 的必然结果,CC Switch 也记录了同一现象;OneAgent 的定位就是把 Codex 指向第三方 Provider,所以接受。 -- OpenCode / Kilo 的配置文件从「可以公开」变成「含密钥」,写入路径与权限断言随之收紧,任何未来的读取投影都不能回传这两个文件的原文。 -- `~/.oneagent/env`、`~/.oneagent/agents/*.env` 不再写入。旧版本留下的文件不会被删除,但也不再被引用;用户手工清理。 -- status 传输契约变更(`paths` 少一个键、`backups` 少一个键),已同步 `frontend/src/types/api.ts` 使用方与冻结的 status fixture。 +- `auth_mode = "apikey"` makes Codex Desktop treat the account as API-Key + authenticated, so features tied to ChatGPT login (Fast mode and the like) are + unavailable. That is an unavoidable result of using a hosted provider, and CC Switch + records the same behavior; OneAgent's whole purpose is to point Codex at a + third-party Provider, so this is accepted. +- The OpenCode / Kilo config files go from "can be published" to "contains a secret", + so the write path and permission assertions tighten accordingly, and no future read + projection may return the raw contents of these two files. +- `~/.oneagent/env` and `~/.oneagent/agents/*.env` are no longer written. Files left + behind by older versions are not deleted, but they are no longer referenced either; + users clean them up by hand. +- The status transport contract changes (`paths` has one key fewer, `backups` one key + fewer), and the consumers in `frontend/src/types/api.ts` and the frozen status + fixture have been updated to match. diff --git a/docs/decisions/ADR-009-public-site-and-generated-release-index.md b/docs/decisions/ADR-009-public-site-and-generated-release-index.md index 917c2d55..62f87fb4 100644 --- a/docs/decisions/ADR-009-public-site-and-generated-release-index.md +++ b/docs/decisions/ADR-009-public-site-and-generated-release-index.md @@ -1,28 +1,46 @@ -# ADR-009:独立公开站与 GitHub Release 事实源 +# ADR-009: Standalone Public Site and GitHub Release as the Source of Truth -- 状态:Partially Superseded(2026-08-04)——决策 1 中「在同一仓库维护」已被推翻,站点 - 迁出到 [MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site); - 同一决策中「不把营销路由加入本地 Launcher」以及决策 2–5 仍然有效。决策 4 的读取路径 - 变为站点仓库 vendor 的 `data/` 副本,从发行 tag 刷新。当前操作指南见 - [public-site-operations.md](../public-site-operations.md),本文件只作背景保留。 -- 日期:2026-07-28(原编号 ADR-006,与《多 Profile 与长期环境管理》撞号,2026-08-04 改为 009; - ADR-008 的 Supersedes 指向的是那一份,不是本文) +- Status: Partially Superseded (2026-08-04) -- "maintained in the same repository" in + decision 1 has been overturned, and the site moved out to + [MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site); "do not add + marketing routes to the local Launcher" in that same decision, and decisions 2-5, + still hold. The read path in decision 4 becomes the `data/` copy vendored by the site + repository, refreshed from release tags. For the current operating guide see + [public-site-operations.md](../public-site-operations.md); this file is kept as + background only. +- Date: 2026-07-28 (originally numbered ADR-006, which collided with "Multiple Profiles + and Long-Term Environment Management", renumbered to 009 on 2026-08-04; the + Supersedes line in ADR-008 points at that one, not at this document) -## 背景 +## Context -OneAgent 的 React 前端是随本地 Wails Launcher 打包的操作界面。公开下载、搜索内容、发行证据和企业服务需要静态可索引页面,两者的安全、缓存、路由和发布周期不同。站点构建直接读取 Release API 和仓库 JSON,保持独立发布周期。 +The OneAgent React frontend is the operating UI bundled with the local Wails Launcher. +Public downloads, searchable content, release evidence, and enterprise services need +static indexable pages, and the two differ in security, caching, routing, and release +cadence. The site build reads the Release API and repository JSON directly, keeping an +independent release cadence. -## 决策 +## Decision -1. 在同一仓库维护独立 `site/` Astro 静态站,不把营销路由加入本地 Launcher。 -2. App 工作流只创建 GitHub Release;站点工作流由站点变更、Release 发布或人工操作独立触发。 -3. 公开版本、发布日期、下载资产、大小和摘要只读取 GitHub Releases API,不读取本地 App 构建目录,也不维护手工回退版本。 -4. Agent 兼容目录直接读取 `agents.lock.json`;Provider 运行时端点和商业披露统一读取 `providers.lock.json`,商业字段不能影响 rank 或技术结论。 -5. 网站默认不加载客户端分析脚本;Launcher 保持默认无遥测。 +1. Maintain a standalone `site/` Astro static site in the same repository, and do not + add marketing routes to the local Launcher. +2. The App workflow only creates a GitHub Release; the site workflow is triggered + independently by site changes, a Release publication, or manual action. +3. Public versions, release dates, download assets, sizes, and digests are read only + from the GitHub Releases API, not from a local App build directory, and no + hand-maintained fallback version is kept. +4. The Agent compatibility catalog reads `agents.lock.json` directly; Provider runtime + endpoints and commercial disclosure both read `providers.lock.json`, and commercial + fields must not influence rank or technical conclusions. +5. The site loads no client-side analytics scripts by default; the Launcher stays + telemetry-free by default. -## 后果 +## Consequences -- Launcher 无需为官网 SEO、域名或外部托管做重构。 -- Draft 和本地构建不会出现在官网;只有已发布 GitHub Release 能产生版本和下载按钮。 -- GitHub Pages 发布不构建 App,App 发布也不构建或部署 Pages。 -- 网站只需要 Node 工具链;App 源代码包不再携带站点源码。 +- The Launcher needs no refactoring for site SEO, domains, or external hosting. +- Drafts and local builds never appear on the site; only a published GitHub Release can + produce a version and a download button. +- A GitHub Pages deploy does not build the App, and an App release neither builds nor + deploys Pages. +- The site needs only the Node toolchain; the App source package no longer carries the + site source. diff --git a/docs/distribution-compliance-policy.md b/docs/distribution-compliance-policy.md index 83cb944f..0d19fa89 100644 --- a/docs/distribution-compliance-policy.md +++ b/docs/distribution-compliance-policy.md @@ -1,42 +1,61 @@ -# OneAgent 多渠道分发与合规政策 +# OneAgent multi-channel distribution and compliance policy -## 状态 +## Status -- 状态:Frozen / 规范性政策 -- 生效日期:2026-07-27 -- 适用对象:OneAgent 维护者、构建人员、渠道上传人员、组织发行方和文档维护者 -- 适用渠道:GitHub Release、官网、国内外网盘、企业云盘及其他公开或定向下载渠道 -- 例外处理:任何例外必须先新增 ADR,记录权利依据、风险、负责人和撤回方案 +- Status: Frozen / normative policy +- Effective date: 2026-07-27 +- Applies to: OneAgent maintainers, build engineers, channel uploaders, organizational + distributors, and documentation maintainers +- Applicable channels: GitHub Release, the official site, domestic and overseas + file-sharing services, corporate cloud drives, and any other public or targeted + download channel +- Exceptions: any exception must first add an ADR that records the rights basis, the + risk, the owner, and the withdrawal plan -本文是 OneAgent 的工程和运营合规基线,不替代针对具体软件、许可证、商标或运营方式的正式法律意见。 +This document is OneAgent's engineering and operations compliance baseline. It does not +replace formal legal advice on any specific piece of software, licence, trademark, or +mode of operation. -## 1. 固定产品定义 +## 1. Fixed product definition -> OneAgent 是通过本地 GUI 帮助用户检测、安装、配置和验证 AI 开发工具的环境激活器。 +> OneAgent is an environment activator that helps users detect, install, configure, and +> verify AI development tools through a local GUI. -OneAgent 可以通过多个合法渠道分发自己的构建产物,但分发渠道不改变包体的权利要求和安全要求。网盘、企业云盘和 GitHub 都只是下载镜像,不是第三方软件再分发授权的替代品。 +OneAgent may distribute its own build artifacts through multiple lawful channels, but +the distribution channel does not change the rights requirements or the security +requirements that apply to the package. File-sharing services, corporate cloud drives, +and GitHub are download mirrors and nothing more; they are not a substitute for a +redistribution authorization covering third-party software. -OneAgent 默认不分发第三方 Agent 二进制。Agent 应通过官方安装源、经过书面授权的镜像、用户手动安装或文档引导获得。 +By default OneAgent does not distribute third-party Agent binaries. Agents must be +obtained from an official installation source, a mirror covered by written +authorization, a manual user installation, or documentation guidance. -## 2. 多渠道同包原则 +## 2. Identical package across channels -同一版本在不同渠道必须使用完全相同的官方构建产物,不允许渠道运营人员重新压缩、替换文件、追加推广内容或二次签名。 +For a given version, every channel must use exactly the same official build artifact. +Channel operators must not recompress it, substitute files, append promotional content, +or re-sign it. -每个公开版本至少包含: +Every public release contains at least: -- OneAgent 二进制压缩包。 -- 与压缩包对应的 SHA-256。 -- 版本、构建时间、目标环境和发布状态。 -- 第三方许可证清单。当前由仓库根的 [NOTICE](../NOTICE) 承担;它同时区分随包分发的组件 - 与运行时下载、不再分发的组件(Node.js、uv、Agent 包)。生成这份清单的 - `cmd/oneagent-release` 已于 `23805b0` 移除,因此 `NOTICE` 现在是手工维护的真源,新增 - 随包依赖或界面第三方标识时必须同步。 -- Agent 版本锁定清单和官方来源。 -- 发行说明、已知问题和撤回联系方式。 +- The OneAgent binary archive. +- The SHA-256 matching that archive. +- The version, the build time, the target environments, and the release status. +- The third-party licence inventory. This is currently carried by [NOTICE](../NOTICE) at + the repository root; it also separates the components redistributed inside the package + from the components downloaded at run time and no longer redistributed (Node.js, uv, + Agent packages). `cmd/oneagent-release`, which generated this inventory, was removed + in `23805b0`, so `NOTICE` is now a hand-maintained source of truth and must be updated + whenever a bundled dependency or an in-app third-party marking is added. +- The Agent version pinning manifest and the official sources. +- Release notes, known issues, and a withdrawal contact. -源码 ZIP、SBOM 和签名可以作为附加产物;若某个版本声称提供这些文件,则所有官方镜像必须保持同一版本和同一校验值。 +A source ZIP, an SBOM, and signatures may be shipped as additional artifacts. If a given +version claims to provide those files, then every official mirror must carry the same +version and the same checksums. -每个渠道必须在发行台账中记录: +Every channel must record the following in the release ledger: ```text release_version @@ -51,145 +70,212 @@ withdrawn_at withdrawal_reason ``` -`status` 只能是 `active`、`deprecated` 或 `withdrawn`。原文件被网盘重新处理或校验值发生变化时,不得继续标记为官方镜像。 - -## 3. 包体允许内容 - -允许进入 OneAgent 发行包的内容: - -- OneAgent 自有 Go 代码和构建后的 React 静态资源。 -- OneAgent 自有图标、文档和配置模板。 -- 许可证明确允许再分发,且已经完成对应义务的第三方依赖。 -- `agents.lock.json`、官方安装入口和手动配置说明。 -- Provider 官网、注册、API Key 和模型文档入口。 -- CC Switch 等第三方配置工具的独立说明文档。 - -每个第三方文件必须能在权利清单中回答:来源、版本、许可证、是否允许二进制再分发、需要附带什么 Notice、是否需要提供源码、由谁复核。 - -## 4. 包体禁止内容 - -以下内容不得进入二进制包、源码包、网盘附件、发行说明或自动化脚本: - -- 未获再分发授权的 Codex、Claude Code、Cursor、Kiro、OpenClaw、Hermes 或其他第三方 Agent 二进制。 -- 从 npm、uv、GitHub 或其他来源下载后直接复制进包内,但没有完成许可证审查的软件。 -- 修改、破解、补丁化或绕过签名的第三方软件。 -- VPN、代理、节点订阅、机场、专线或其他绕过网络限制的工具和配置。 -- 共享账号、共享 API Key、长期 Token、Cookie、验证码处理或批量注册工具。 -- 用户 HOME、历史配置、日志、Prompt、源代码、认证文件或测试 Key。 -- 未获授权的第三方 Logo、字体、宣传图片和容易造成官方合作误解的品牌资产。 -- 为规避渠道审核而制作的加密包、密码包、分卷包或伪装扩展名。 -- source map、测试缓存、概念图、Docker 测试镜像和非运行必需的开发产物。 - -## 5. Agent 获取与安装规则 - -Agent 获取顺序固定为: - -1. 官方包管理器或官方发布源。 -2. 具有明确许可证或书面授权的镜像。 -3. 用户手动安装后由 OneAgent 检测。 -4. 只展示官方说明的 `guide-only` 模式。 - -自动安装必须满足: - -- 包管理器、包名和平台位于固定 allowlist。 -- Agent 默认安装包管理器解析出的最新版本;需要复现时由调用方显式指定版本。 -- 命令以参数数组执行,禁止 `shell=True` 和动态拼接 shell 命令。 -- 安装前显示软件名称、来源、版本策略和将执行的动作,并由用户确认。 -- API Key、Token 和账号信息不得出现在命令行参数中。 -- 不自动安装 Node.js、Git、VPN 或系统级网络组件。Aider 的外部 Python 3.12 只在用户明确选择 Aider 时由上游安装流程自行要求,绝不进入 OneAgent 包体。 -- 不执行未经固定和审查的 `curl | bash`。 - -官方来源不可达时,只能报告不可达并提供手动安装入口。OneAgent 不配置代理,不提供绕过网络限制的说明,也不把第三方二进制转存到网盘作为临时替代。 - -## 6. Provider、账号和 API Key - -- 用户自行在 Provider 官方渠道注册或登录。 -- 用户自行创建和管理 API Key。 -- OneAgent 不承诺固定免费额度、永久免费、特定活动资格或账号权益。 -- Key 只保存在用户本机允许的密钥文件中,不进入 profile、日志、截图、遥测、URL、命令行、发行包或测试报告。 -- GUI 必须显示实际 Base URL 和即将发送数据的目标地址。 -- 自定义 Provider 必须拒绝 URL 凭据、非法 scheme 和控制字符。 -- OneAgent 不运营共享 Key 池,不代用户转发模型请求,不把本地激活器描述为统一 API 网关。 - -如果未来增加统一网关、远程配置、账号体系、下载统计、崩溃上报或请求代理,必须独立评估个人信息、网络数据和生成式人工智能服务相关义务,不能沿用本地工具的默认边界。 - -## 7. 品牌和对外文案 - -允许使用第三方产品的文字名称描述兼容性,但不得暗示 OneAgent 是相关厂商的官方产品、国内版、联合版本或授权代理。 - -推荐使用: - -> OneAgent 是独立开发的环境配置工具,可帮助用户安装或配置部分第三方 AI 开发工具。相关产品和商标归其权利人所有。 - -禁止使用: - -- “Claude Code 国内官方版” -- “Codex 绿色破解版” -- “Cursor 国内增强版” -- “OpenAI 官方合作安装器” -- “内置 Claude/Codex,无需官方账号” - -产品主视觉使用 OneAgent 自有资产或通用图标,不把第三方 Logo 作为 OneAgent 的品牌标识。 - -## 8. 渠道运营规则 - -- 渠道上传账号必须由明确负责人管理,不使用无法追溯的个人临时账号作为唯一来源。 -- 官方页面至少公布一个可信 SHA-256 来源;网盘页面中的校验值不能成为唯一校验依据。 -- 不允许渠道方改变文件名中的版本、平台、架构或发布状态。 -- 不在压缩包内植入渠道专属推广、兑换码、共享 Key 或组织业务逻辑。 -- 网盘或平台要求删除时,应保留通知、版本、链接、处理人和处理结果。 -- 发现版权、密钥泄露、恶意篡改或高危漏洞时,所有渠道必须同步撤回,不得只删除 GitHub 版本。 -- 已撤回版本不得换链接继续分发;修复后必须发布新版本和新校验值。 - -## 9. 发布门禁 - -每次公开或定向分发前必须全部通过: - -### 权利与品牌 - -- [ ] 包内每个第三方文件都有来源、许可证和再分发依据。 -- [ ] 需要附带的许可证、Notice 或源码已包含。 -- [ ] 不包含未授权 Agent 二进制、字体、Logo 或宣传素材。 -- [ ] 产品名称和宣传文案不造成官方合作或来源混淆。 - -### 安全与隐私 - -- [ ] secret scan 没有发现 Key、Token、Cookie、账号或本机认证文件。 -- [ ] 包内没有 VPN、代理、节点、绕过脚本或共享凭据。 -- [ ] React 构建没有 source map、远程脚本、远程字体或 CDN 运行依赖。 -- [ ] API Key 不进入日志、URL、命令行、profile、遥测和测试产物。 -- [ ] 自动安装命令全部来自固定 allowlist,并经过参数数组执行。 - -### 发行完整性 - -- [ ] 在全新临时 HOME 中完成二进制启动和核心流程冒烟。 -- [ ] 包内没有 Agent 二进制、用户配置、测试缓存和历史构建残留。 -- [ ] 版本清单、许可证清单、SHA-256 和发行说明齐全。 -- [ ] 所有渠道上传的是同一份产物,校验值一致。 -- [ ] 渠道台账包含上传人、时间、链接和状态。 -- [ ] 已准备跨渠道撤回和安全事件响应方式。 - -任何一项失败都必须阻止发布。不得以“仅网盘分享”“仅小范围测试”或“用户自行承担风险”为理由跳过门禁。 - -## 10. 合规证据保留 - -每个版本至少保留: - -- 构建 commit、构建环境和构建日志摘要。 -- 发行包文件清单、SBOM 或等价依赖清单。 -- 第三方许可证与权利复核记录。 -- secret、恶意软件和发行策略扫描结果。 -- 二进制 cleanroom 冒烟结果。 -- SHA-256 和渠道台账。 -- 撤回、投诉和安全事件处理记录。 - -证据中不得保存用户 API Key、Authorization header、完整模型请求或真实用户目录内容。 - -## 11. 参考依据 - -- 《中华人民共和国著作权法》: -- 《计算机软件保护条例》: -- 《中华人民共和国个人信息保护法》: -- 《生成式人工智能服务管理暂行办法》: -- 《网络信息内容生态治理规定》: -- 《中华人民共和国反不正当竞争法》: +`status` may only be `active`, `deprecated`, or `withdrawn`. Once the original file has +been reprocessed by a file-sharing service, or its checksum has changed, it must not +continue to be marked as an official mirror. + +## 3. Permitted package contents + +The following may enter the OneAgent release package: + +- OneAgent's own Go code and the built React static assets. +- OneAgent's own icons, documentation, and Profiles. +- Third-party dependencies whose licence explicitly permits redistribution and whose + corresponding obligations have already been satisfied. +- `agents.lock.json`, the official installation entry points, and the manual + configuration instructions. +- Entry points to Provider websites, registration, API Keys, and model documentation. +- Standalone documentation for third-party configuration tools such as CC Switch. + +For every third-party file, the rights inventory must be able to answer: the source, the +version, the licence, whether binary redistribution is permitted, what Notice has to be +included, whether source code has to be provided, and who reviewed it. + +## 4. Prohibited package contents + +The following must not enter the binary package, the source package, file-sharing +attachments, the release notes, or the automation scripts: + +- Codex, Claude Code, Cursor, Kiro, OpenClaw, Hermes, or other third-party Agent + binaries that are not covered by a redistribution authorization. +- Software downloaded from npm, uv, GitHub, or another source and copied straight into + the package without a completed licence review. +- Third-party software that has been modified, cracked, patched, or made to bypass + signature checks. +- VPNs, proxies, node subscriptions, "airport" relay services, dedicated lines, or other + tools and configurations for bypassing network restrictions. +- Shared accounts, shared API Keys, long-lived tokens, cookies, CAPTCHA-solving, or bulk + registration tools. +- User HOME contents, historical configuration, logs, prompts, source code, + authentication files, or test Keys. +- Unauthorized third-party logos, fonts, promotional images, and brand assets that could + easily create the impression of an official partnership. +- Encrypted archives, password-protected archives, split archives, or disguised file + extensions produced in order to evade channel review. +- Source maps, test caches, concept diagrams, Docker test images, and other development + artifacts that are not required at run time. + +## 5. Agent acquisition and installation rules + +The Agent acquisition order is fixed as: + +1. The official package manager or the official release source. +2. A mirror with an explicit licence or written authorization. +3. Detection by OneAgent after the user installs manually. +4. `guide-only` mode, which shows only the official instructions. + +Automatic installation must satisfy all of the following: + +- The package manager, the package name, and the platform are on a fixed allowlist. +- By default an Agent installs the latest version resolved by the package manager; when + reproducibility is needed, the caller specifies the version explicitly. +- Commands are executed with an argument array; `shell=True` and dynamically + concatenated shell commands are prohibited. +- Before installing, the software name, the source, the version policy, and the actions + about to be taken are shown and confirmed by the user. +- API Keys, tokens, and account information must not appear in command-line arguments. +- Node.js, Git, VPNs, and system-level networking components are not installed + automatically. Aider's external Python 3.12 is required by the upstream installation + flow itself, only when the user explicitly chooses Aider, and never enters the + OneAgent package. +- Executing a `curl | bash` that has not been pinned and reviewed is prohibited. + +When an official source is unreachable, the only permitted response is to report it as +unreachable and offer a manual installation entry point. OneAgent does not configure +proxies, does not provide instructions for bypassing network restrictions, and does not +re-host third-party binaries on a file-sharing service as a stopgap substitute. + +## 6. Providers, accounts, and API Keys + +- The user registers or signs in through the Provider's official channels themselves. +- The user creates and manages API Keys themselves. +- OneAgent makes no promise of a fixed free quota, permanent free use, eligibility for a + particular campaign, or account benefits. +- Keys are stored only in the permitted key file on the user's own machine, and do not + enter Profiles, logs, screenshots, telemetry, URLs, command lines, the release + package, or test reports. +- The GUI must display the actual Base URL and the destination address that data is + about to be sent to. +- A custom Provider must reject URL credentials, invalid schemes, and control + characters. +- OneAgent does not operate a shared Key pool, does not forward model requests on the + user's behalf, and does not describe a local activator as a unified API gateway. + +If a unified gateway, remote configuration, an account system, download statistics, +crash reporting, or request proxying is added in the future, the obligations relating to +personal information, network data, and generative AI services must be assessed +independently; the default boundaries of a local tool cannot simply be carried over. + +## 7. Brand and public copy + +Using the textual names of third-party products to describe compatibility is permitted, +but it must not imply that OneAgent is an official product, a domestic edition, a joint +edition, or an authorized agent of the vendor in question. + +Recommended wording: + +> OneAgent is an independently developed environment configuration tool that helps users +> install or configure some third-party AI development tools. The relevant products and +> trademarks belong to their respective rights holders. + +Prohibited wording: + +- "Claude Code, official domestic edition" +- "Codex, cracked portable edition" +- "Cursor, domestic enhanced edition" +- "Official OpenAI partner installer" +- "Claude/Codex built in, no official account needed" + +The product's primary visual identity uses OneAgent's own assets or generic icons; a +third-party logo is not used as OneAgent's brand mark. + +## 8. Channel operations rules + +- Channel upload accounts must be managed by a named owner; an untraceable personal + throwaway account must not be the sole source. +- The official page publishes at least one trustworthy source for the SHA-256; a + checksum shown on a file-sharing page cannot be the only basis for verification. +- Channel operators are not permitted to change the version, platform, architecture, or + release status in the file name. +- No channel-specific promotion, redemption codes, shared Keys, or organizational + business logic is embedded inside the archive. +- When a file-sharing service or platform requires removal, the notice, the version, the + link, the person who handled it, and the outcome should be retained. +- On discovering a copyright issue, a key leak, malicious tampering, or a high-severity + vulnerability, every channel must withdraw in sync; deleting only the GitHub version + is prohibited. +- A withdrawn version must not continue to be distributed under a different link; once + fixed, a new version with new checksums must be published. + +## 9. Release gate + +All of the following must pass before any public or targeted distribution: + +### Rights and brand + +- [ ] Every third-party file in the package has a source, a licence, and a + redistribution basis. +- [ ] The licences, Notices, or source code that have to be included are included. +- [ ] No unauthorized Agent binaries, fonts, logos, or promotional material are + included. +- [ ] The product name and the promotional copy do not create confusion about an + official partnership or about origin. + +### Security and privacy + +- [ ] The secret scan found no Keys, tokens, cookies, accounts, or local authentication + files. +- [ ] The package contains no VPNs, proxies, nodes, bypass scripts, or shared + credentials. +- [ ] The React build has no source maps, remote scripts, remote fonts, or CDN run-time + dependencies. +- [ ] API Keys do not enter logs, URLs, command lines, Profiles, telemetry, or test + artifacts. +- [ ] Every automatic installation command comes from the fixed allowlist and is + executed with an argument array. + +### Release integrity + +- [ ] Binary startup and a smoke test of the core flows completed in a fresh temporary + HOME. +- [ ] The package contains no Agent binaries, user configuration, test caches, or + leftovers from previous builds. +- [ ] The version manifest, the licence inventory, the SHA-256, and the release notes + are all complete. +- [ ] Every channel uploaded the same artifact, with matching checksums. +- [ ] The channel ledger contains the uploader, the time, the link, and the status. +- [ ] Cross-channel withdrawal and a security incident response path are ready. + +Any single failure must block the release. The gate must not be skipped on the grounds +that it is "only a file-sharing link", "only a small-scale test", or that "users accept +the risk themselves". + +## 10. Retention of compliance evidence + +For every version, retain at least: + +- The build commit, the build environment, and a summary of the build log. +- The release package file manifest, and an SBOM or an equivalent dependency inventory. +- Third-party licence and rights review records. +- The results of the secret, malware, and release policy scans. +- The binary cleanroom smoke test results. +- The SHA-256 and the channel ledger. +- Records of withdrawals, complaints, and security incident handling. + +The evidence must not retain user API Keys, Authorization headers, complete model +requests, or the contents of real user directories. + +## 11. References + +- Copyright Law of the People's Republic of China: + +- Regulations on Computer Software Protection: + +- Personal Information Protection Law of the People's Republic of China: + +- Interim Measures for the Management of Generative AI Services: + +- Provisions on the Governance of the Online Information Content Ecosystem: + +- Anti-Unfair Competition Law of the People's Republic of China: + diff --git a/docs/internal/README.md b/docs/internal/README.md index 897a091a..a1643f41 100644 --- a/docs/internal/README.md +++ b/docs/internal/README.md @@ -5,7 +5,7 @@ 面向使用者的文档在上一层:[产品边界基线](../product-boundary-baseline.md)、 [分发与合规政策](../distribution-compliance-policy.md)、 -[AI Agent Kit](../ai-agent-kit/00-start-here.md);架构决策在 +[AI Agent Kit](../ai-agent-kit/README.md);架构决策在 [decisions/](../decisions/)。 ## 为什么分开放 diff --git a/docs/internal/cc-switch-reference-notes.md b/docs/internal/cc-switch-reference-notes.md index c1c8bd05..e1ad1401 100644 --- a/docs/internal/cc-switch-reference-notes.md +++ b/docs/internal/cc-switch-reference-notes.md @@ -165,4 +165,4 @@ CC Switch 依赖 **`@lobehub/icons-static-svg`**(MIT,723 个 AI 品牌 SVG - 商业合作伙伴字段与推广排序 —— 与公开权益文案约束冲突。 - 拖拽排序、健康徽章 —— 当前无对应需求。 -相关文档:[前端管理控制台改造计划](frontend-management-console-plan.md)、[产品边界基线](../product-boundary-baseline.md)、[CC Switch 可选配置说明](../ai-agent-kit/tools/cc-switch.md)。 +相关文档:[前端管理控制台改造计划](frontend-management-console-plan.md)、[产品边界基线](../product-boundary-baseline.md)、[CC Switch 可选配置说明](../ai-agent-kit/zh/tools/cc-switch.md)。 diff --git a/docs/product-boundary-baseline.md b/docs/product-boundary-baseline.md index 3c07dc25..a87e332d 100644 --- a/docs/product-boundary-baseline.md +++ b/docs/product-boundary-baseline.md @@ -1,159 +1,184 @@ -# OneAgent 产品边界基线 +# OneAgent Product Boundary Baseline -## 状态 +## Status -- 状态:Frozen / 固定基线 -- 生效日期:2026-07-27 -- 适用范围:OneAgent、本地启动器、公开或定向下载包、所有下载镜像、文档和发行页面 -- 变更方式:任何突破本文件“禁止范围”的需求,必须新增 ADR 并经过合规复核 +- Status: Frozen / fixed baseline +- Effective date: 2026-07-27 +- Scope: OneAgent, the local launcher, public or targeted download packages, all + download mirrors, documentation, and release pages +- How to change it: any requirement that breaks the "prohibited scope" in this + document must add an ADR and pass a compliance review -## 1. 一句话定义 +## 1. One-sentence definition -> OneAgent 是一个帮助用户激活、配置和启动本地 AI 开发环境的工具。 +> OneAgent is a tool that helps users activate, configure, and launch a local AI development environment. -它连接 Provider、模型、Agent、IDE 和本机配置工具,目标是帮助用户完成第一次成功的 AI Agent 请求。 +It connects Providers, models, Agents, IDEs, and local config tools. The goal is to help +the user complete their first successful AI Agent request. -OneAgent 不是 VPN、代理、跨境网络接入服务、共享 API Key 平台或商业 Agent 包体合集。 +OneAgent is not a VPN, a proxy, a cross-border network access service, a shared API Key +platform, or a collection of commercial Agent packages. -## 2. 目标用户 +## 2. Target users -OneAgent 面向所有需要本地 AI 开发环境的用户: +OneAgent is for everyone who needs a local AI development environment: -- 第一次使用 AI Agent 的个人用户。 -- 已有 Provider 账号和 API Key 的开发者。 -- 需要多个 Provider、账号或模型 Profile 的高级用户。 -- 公司、社区和其他组织发行方。 +- Individual users trying an AI Agent for the first time. +- Developers who already have a Provider account and an API Key. +- Advanced users who need multiple Providers, accounts, or model Profiles. +- Companies, communities, and other organization distributors. -组织发行方可以在项目外部提供项目、兑换码或权益说明,但这些内容不属于 OneAgent 核心产品模型。 +Organization distributors may offer programs, redemption codes, or benefit descriptions +outside the project, but that content is not part of the OneAgent core product model. -## 3. 明确允许的能力 +## 3. Capabilities explicitly allowed -### 3.1 本地启动和配置 +### 3.1 Local launch and configuration -- 启动 `127.0.0.1` 本地 GUI。 -- 检测本机 Agent 和运行环境。 -- 调用官方 npm、uv tool、Git 或系统安装源。 -- 用户手动安装后由 OneAgent 检测。 -- 写入已经确认的官方配置入口。 -- 调用 Provider 的 OpenAI-compatible API 做模型发现和最小请求验证。 +- Launch a local GUI on `127.0.0.1`. +- Detect the Agents and runtime environment on the machine. +- Call official npm, uv tool, Git, or system install sources. +- Detect what the user installed manually. +- Write to config entry points that have already been confirmed as official. +- Call a Provider's OpenAI-compatible API for model discovery and minimal request + validation. -### 3.2 官方构建、文档和授权镜像 +### 3.2 Official builds, documentation, and licensed mirrors -可以提供: +The following are permitted: -- 由 OneAgent 官方构建的二进制包和源码包。 -- GitHub、官网、网盘和企业云盘上的同包镜像。 -- Provider 官方注册、API Key 和模型文档。 -- Agent 官方安装说明。 -- 许可证允许的开源软件镜像。 -- 固定版本、SHA-256 校验值、上游地址和许可证文件。 -- 组织发行方在包外维护的项目模板和说明。 +- Binary and source packages built officially by OneAgent. +- Same-package mirrors on GitHub, the official site, file-hosting services, and + enterprise cloud drives. +- Official Provider registration, API Key, and model documentation. +- Official Agent install instructions. +- Mirrors of open-source software where the license permits. +- Pinned versions, SHA-256 checksums, upstream addresses, and license files. +- Project templates and instructions that organization distributors maintain outside + the package. -同一版本的所有渠道必须使用相同产物和相同 SHA-256。渠道运营人员不得重新打包、替换文件或向压缩包内追加推广内容。 +All channels carrying the same version must use identical artifacts and an identical +SHA-256. Channel operators must not repackage, replace files, or add promotional content +inside the archive. -### 3.3 配置工具 +### 3.3 Config tools -可以提供: +The following are permitted: -- OneAgent 内置配置。 -- CC Switch 等第三方本机 Profile 工具的独立使用说明。 -- 手动配置和恢复备份说明。 +- OneAgent's built-in configuration. +- Standalone instructions for third-party local Profile tools such as CC Switch. +- Manual configuration and backup restore instructions. -配置工具只负责本机配置管理,不负责网络绕过。 +Config tools are responsible for local configuration management only, not for network +circumvention. -## 4. 明确禁止的能力 +## 4. Capabilities explicitly prohibited -以下内容不得进入产品代码、压缩包、官方文档、宣传页或自动化脚本: +The following must not enter the product code, the archives, the official documentation, +promotional pages, or automation scripts: -- VPN、代理、机场、专线或其他绕过网络限制的工具。 -- 自动配置代理节点、代理订阅或跨境网络路由。 -- “翻墙下载”“突破限制”“免代理访问受限网站”等产品表述。 -- 自动登录、自动处理验证码、自动领取账户权益。 -- 将 OneAgent 的服务器作为用户访问境外网站的中转代理。 -- 把长期 Provider Key 写入压缩包、前端代码或公共脚本。 -- 未经许可重新分发商业 Agent 包体。 -- 未经许可证确认的开源 Agent 二进制或源码镜像。 -- 为规避渠道审核制作加密包、密码包、分卷包或伪装文件。 -- 使用第三方品牌、Logo 或文案造成 OneAgent 是官方产品或联合产品的误解。 -- 在不同渠道发布版本号相同但内容或校验值不同的压缩包。 -- 默认上传用户 API Key、Prompt、源代码或完整模型请求。 +- VPNs, proxies, "airport" services, dedicated lines, or any other tool for bypassing + network restrictions. +- Automatic configuration of proxy nodes, proxy subscriptions, or cross-border network + routing. +- Product wording such as "download over the wall", "break through restrictions", or + "reach restricted sites without a proxy". +- Automatic login, automatic CAPTCHA solving, or automatic claiming of account benefits. +- Using OneAgent's servers as a relay proxy for users to reach overseas websites. +- Writing a long-lived Provider Key into an archive, frontend code, or a public script. +- Redistributing commercial Agent packages without permission. +- Mirroring open-source Agent binaries or source without license confirmation. +- Producing encrypted, password-protected, split, or disguised packages to evade channel + review. +- Using third-party brands, logos, or copy in a way that creates the misimpression that + OneAgent is an official or joint product. +- Publishing archives that share a version number across channels but differ in content + or checksum. +- Uploading user API Keys, prompts, source code, or complete model requests by default. -## 5. 软件获取策略 +## 5. Software acquisition policy -每个 Agent 必须配置一个下载策略: +Every Agent must be configured with one download strategy: -| 优先级 | 策略 | 说明 | +| Priority | Strategy | Notes | | --- | --- | --- | -| 1 | 官方安装源 | npm、uv tool、官方 Git、官方发布页 | -| 2 | 授权镜像 | 有许可证、版本锁定、校验值和上游地址 | -| 3 | 用户手动安装 | OneAgent 只检测路径和版本 | -| 4 | 文档引导 | 不自动执行安装,只显示官方步骤 | +| 1 | Official install source | npm, uv tool, official Git, official release page | +| 2 | Licensed mirror | Has a license, a pinned version, a checksum, and an upstream address | +| 3 | User manual install | OneAgent only detects the path and version | +| 4 | Documentation guidance | Does not run the install; only shows the official steps | -如果官方站点在用户当前网络不可达,OneAgent 只显示“安装源不可达”和可选的手动安装路径,不提供代理或绕过网络限制的方法。 +If the official site is unreachable from the user's current network, OneAgent only shows +"install source unreachable" plus optional manual install paths. It does not offer a +proxy or any method of bypassing network restrictions. -## 6. Provider 和 API Key +## 6. Providers and API Keys -### 6.1 用户自己的账号模式:默认 +### 6.1 The user's own account model: the default ```text -用户注册或登录 Provider -→ 用户创建 API Key -→ Key 保存在用户本机 -→ OneAgent 写入 Agent 配置 +The user signs up for or logs in to a Provider +→ The user creates an API Key +→ The Key is stored on the user's own machine +→ OneAgent writes the Agent configuration ``` -用户可以使用 Provider 账户页面显示的公开权益或其他合法额度,但 OneAgent 不承诺固定免费额度、永久免费或特定账户资格。 +Users may use the published benefits shown on their Provider account page, or any other +lawful quota, but OneAgent makes no promise of a fixed free quota, of permanently free +access, or of any particular account eligibility. -### 6.2 统一网关模式:不属于当前 MVP +### 6.2 Unified gateway model: not part of the current MVP -如果以后提供统一 API 网关,必须新增独立产品设计和合规评估,至少包含: +If a unified API gateway is offered later, it must add its own product design and +compliance review, covering at least: -- 用户级 Token。 -- 租户级和用户级配额。 -- 速率限制。 -- 成本和余额预警。 -- Key 撤销机制。 -- 日志脱敏和数据保留策略。 -- 服务协议、隐私政策和运营主体信息。 +- Per-user tokens. +- Tenant-level and user-level quotas. +- Rate limiting. +- Cost and balance alerts. +- A key revocation mechanism. +- Log redaction and a data retention policy. +- Terms of service, a privacy policy, and operator entity information. -在完成上述评估前,禁止在启动包中嵌入共享 Provider Key。 +Until that review is complete, embedding a shared Provider Key in the launcher package +is prohibited. -## 7. 配置工具边界 +## 7. Config tool boundary -### OneAgent 内置配置 +### OneAgent built-in configuration -- 所有用户的默认路径。 -- 负责第一次 Provider 配置和请求验证。 -- 不依赖第三方配置工具。 +- The default path for all users. +- Responsible for the first Provider setup and request validation. +- Does not depend on a third-party config tool. ### CC Switch -- 可选的本机配置 Profile 工具。 -- 不打进启动包。 -- 不由 OneAgent 默认安装。 -- 使用官方项目入口和当前版本说明。 -- 不把 CC Switch 的任何服务地址当作 Provider Base URL。 -- 切换后要求用户重启目标 Agent 并做最小请求验证。 +- An optional local Profile tool. +- Not bundled into the launcher package. +- Not installed by OneAgent by default. +- Uses the official project entry point and the current version's instructions. +- Must not treat any CC Switch service address as a Provider Base URL. +- After switching, requires the user to restart the target Agent and run a minimal + request validation. -### 手动配置 +### Manual configuration -- 作为所有 Agent 的兜底路径。 -- 只提供已验证字段、配置路径和恢复方式。 -- 不修改未知的私有状态文件。 +- The fallback path for every Agent. +- Provides only verified fields, config paths, and restore procedures. +- Does not modify unknown private state files. -## 8. 数据和隐私基线 +## 8. Data and privacy baseline -### 默认不采集 +### Not collected by default -- API Key。 -- 账号密码。 -- Prompt 和源代码。 -- 完整请求体和模型响应。 -- 身份证、手机号、学号等非必要个人信息。 +- API Keys. +- Account passwords. +- Prompts and source code. +- Complete request bodies and model responses. +- Unnecessary personal information such as ID numbers, phone numbers, or student IDs. -### 如需统计激活 +### If activation statistics are needed -仅允许采集经过说明和同意的最小事件: +Only the minimal set of events, disclosed and consented to, may be collected: ```text package_version @@ -164,105 +189,123 @@ result_status timestamp ``` -事件采集应默认关闭或提供明确选择,且不能通过错误日志、崩溃报告或调试模式间接上传 Key 和用户内容。 +Event collection should be off by default or offer an explicit choice, and it must not +indirectly upload Keys or user content through error logs, crash reports, or debug mode. -## 9. 固定的产品文案 +## 9. Fixed product copy -### 使用 +### Usage -> OneAgent 帮助你注册或登录 Provider、创建 API Key,并完成本地 Agent 的安装和配置。 +> OneAgent helps you sign up for or log in to a Provider, create an API Key, and install and configure a local Agent. -### 网络不可达 +### Network unreachable -> 当前官方安装源不可达。请使用所在组织或网络服务商提供的合规网络接入,或手动安装后返回 OneAgent 检测。OneAgent 不提供 VPN、代理或绕过网络限制的功能。 +> The official install source is currently unreachable. Please use the compliant network access provided by your organization or network service provider, or install manually and return to OneAgent to detect it. OneAgent does not provide VPN, proxy, or network-restriction-bypassing features. -### 公开权益 +### Published benefits -> Provider 的新用户权益、邀请权益和公开说明以账户页面当前显示为准,OneAgent 不保证固定额度或永久免费。 +> A Provider's new-user benefits, referral benefits, and public descriptions are whatever the account page currently shows. OneAgent does not guarantee a fixed quota or permanently free access. ### API Key -> API Key 由你在 Provider 官方账户中创建,只保存在你的本机。请勿将 Key 发给他人或提交到代码仓库。 - -## 10. 当前版本固定范围 - -### V1 包含 - -- PPIO、Novita 和 Custom OpenAI-compatible Provider。 -- Codex、Claude Code、OpenCode、Kilo CLI、Aider 的本地配置路径。 -- 其他 Agent 的官方安装和配置指引。 -- 模型列表获取和第一次请求验证。 -- OneAgent 内置配置。 -- CC Switch 可选说明文档。 -- 手动配置和备份恢复。 -- 通用项目模板。 - -### V1 不包含 - -- 组织发行方的专属业务逻辑。 -- 固定免费额度承诺。 -- VPN、代理和跨境网络中转。 -- 共享 Provider Key。 -- 统一 API 网关。 -- 未授权 Agent 包体分发。 -- 默认遥测。 - -### V1 分发形态 - -- 通过 GitHub、官网、网盘、企业云盘或其他合法渠道直接分发 OneAgent 官方二进制。 -- 所有渠道只承担镜像作用,不改变包体内容、版本、发布状态和校验值。 -- 默认不把第三方 Agent 二进制放入 OneAgent 压缩包。 -- 每个产物只声明其实际构建和验证过的目标环境,不承诺未验证平台。 -- 平台商店、自动更新、macOS 公证和 Windows Authenticode 不属于当前阶段。 -- 详细规则以 [多渠道分发与合规政策](distribution-compliance-policy.md) 为准。 - -## 11. 发布门禁 - -每个公开包或组织发行包发布前必须确认: - -- [ ] 包体内没有 Key、代理节点、VPN 和未授权二进制。 -- [ ] 包内每个第三方文件都有来源、许可证和再分发依据。 -- [ ] 每个 Agent 都有官方来源、许可证或手动安装说明。 -- [ ] 每个镜像都有版本、SHA-256、负责人、上传时间和可撤回状态。 -- [ ] 同一版本在所有渠道的文件内容和 SHA-256 完全一致。 -- [ ] Provider 文档链接已复核。 -- [ ] CC Switch 仍然是可选文档,不是隐藏依赖。 -- [ ] API Key 不出现在日志、截图、遥测和命令行参数中。 -- [ ] 网络不可达时不会引导用户绕过网络限制。 -- [ ] 公开权益文案没有承诺固定免费额度。 -- [ ] 发行说明只声明当前产物实际构建和验证过的目标环境。 -- [ ] 每个实际发布平台都有原生构建和 cleanroom 验收证据(`ci.yml` 或 Release Candidate 流程)。 -- [ ] 渠道台账已人工同步本次发布(台账为人工流程,没有自动门禁)。 -- [ ] 品牌和文案没有造成官方合作、国内版或授权代理的误解。 -- [ ] 已准备跨渠道撤回、投诉和安全事件处理方式。 -- [ ] 默认安装官方最新版本,发行包附包名和许可证清单;复现任务可显式指定版本。 -- [ ] 未签名构建明确标记为 `technical-preview-unsigned`,没有使用 Stable 标签。 - -完整门禁和证据要求见 [OneAgent 多渠道分发与合规政策](distribution-compliance-policy.md)。 - -## 12. 变更控制 - -以下变化必须新增 ADR,并重新做合规评估: - -- 从本地配置改成统一 API 网关。 -- 增加代理、专线或跨境网络能力。 -- 自动安装第三方配置工具。 -- 重新分发商业 Agent 包体。 -- 允许渠道方重新打包、修改官方产物或维护渠道专属版本。 -- 使用第三方品牌资产或官方合作表述。 -- 收集用户账号、组织身份或请求内容。 -- 将启动器扩展为公开商业化 API 服务。 - -## 官方参考 - -- 《中华人民共和国计算机信息网络国际联网管理暂行规定(2024 修订)》: -- 工业和信息化部关于清理规范互联网网络接入服务市场的通知: -- 《中华人民共和国个人信息保护法》: -- 《中华人民共和国著作权法》: -- 《计算机软件保护条例》: -- 《生成式人工智能服务管理暂行办法》: -- 《网络信息内容生态治理规定》: -- 《中华人民共和国反不正当竞争法》: -- PPIO 官网: -- PPIO API Key 文档: -- CC Switch 官方仓库: +> You create the API Key in your official Provider account, and it is stored only on your own machine. Do not send the Key to anyone else or commit it to a code repository. + +## 10. Fixed scope of the current version + +### Included in V1 + +- PPIO, Novita, and Custom OpenAI-compatible Providers. +- Local config paths for Codex, Claude Code, OpenCode, Kilo CLI, and Aider. +- Official install and configuration guidance for other Agents. +- Model list retrieval and first-request validation. +- OneAgent built-in configuration. +- Optional CC Switch documentation. +- Manual configuration and backup restore. +- Generic project templates. + +### Not included in V1 + +- Business logic specific to an organization distributor. +- Promises of a fixed free quota. +- VPN, proxy, and cross-border network relay. +- Shared Provider Keys. +- A unified API gateway. +- Distribution of unlicensed Agent packages. +- Telemetry on by default. + +### V1 distribution form + +- Distribute the official OneAgent binaries directly through GitHub, the official site, + file-hosting services, enterprise cloud drives, or other lawful channels. +- All channels serve only as mirrors; they do not change package contents, version, + release status, or checksums. +- Third-party Agent binaries are not placed in the OneAgent archive by default. +- Each artifact declares only the target environments it was actually built and verified + for, and promises nothing for unverified platforms. +- Platform stores, automatic updates, macOS notarization, and Windows Authenticode are + out of scope for the current stage. +- The detailed rules are governed by the + [Multi-channel distribution and compliance policy](distribution-compliance-policy.md). + +## 11. Release gates + +Before every public or organization-distributor package is released, confirm: + +- [ ] The package contains no Keys, proxy nodes, VPNs, or unlicensed binaries. +- [ ] Every third-party file in the package has a source, a license, and a redistribution basis. +- [ ] Every Agent has an official source, a license, or manual install instructions. +- [ ] Every mirror has a version, SHA-256, owner, upload time, and withdrawable status. +- [ ] The same version has exactly identical file contents and SHA-256 across all channels. +- [ ] Provider documentation links have been rechecked. +- [ ] CC Switch is still optional documentation, not a hidden dependency. +- [ ] API Keys do not appear in logs, screenshots, telemetry, or command-line arguments. +- [ ] When the network is unreachable, users are not guided toward bypassing network restrictions. +- [ ] The published-benefits copy promises no fixed free quota. +- [ ] The release notes declare only the target environments the current artifacts were actually built and verified for. +- [ ] Every platform actually released has native build and cleanroom acceptance evidence (`ci.yml` or the Release Candidate process). +- [ ] The channel ledger has been synced manually for this release (the ledger is a manual process; there is no automated gate). +- [ ] Branding and copy create no misimpression of official partnership, a domestic edition, or authorized agency. +- [ ] Cross-channel withdrawal, complaint, and security incident procedures are ready. +- [ ] The official latest version is installed by default; release packages ship a package name and license manifest; reproduction tasks may pin an explicit version. +- [ ] Unsigned builds are clearly marked `technical-preview-unsigned` and do not use a Stable label. + +For the complete gates and evidence requirements, see +[OneAgent multi-channel distribution and compliance policy](distribution-compliance-policy.md). + +## 12. Change control + +The following changes must add an ADR and redo the compliance assessment: + +- Moving from local configuration to a unified API gateway. +- Adding proxy, dedicated line, or cross-border network capability. +- Automatically installing a third-party config tool. +- Redistributing commercial Agent packages. +- Allowing channel operators to repackage, modify official artifacts, or maintain + channel-specific builds. +- Using third-party brand assets or official-partnership wording. +- Collecting user accounts, organization identity, or request contents. +- Extending the launcher into a public commercial API service. + +## Official references + +- Interim Provisions of the People's Republic of China on the Administration of + International Networking of Computer Information Networks (2024 revision): + +- Ministry of Industry and Information Technology notice on cleaning up and regulating + the internet network access service market: + +- Personal Information Protection Law of the People's Republic of China: + +- Copyright Law of the People's Republic of China: + +- Regulations on the Protection of Computer Software: + +- Interim Measures for the Administration of Generative Artificial Intelligence Services: + +- Provisions on the Governance of the Online Information Content Ecosystem: + +- Anti-Unfair Competition Law of the People's Republic of China: + +- PPIO official site: +- PPIO API Key documentation: +- CC Switch official repository: diff --git a/docs/public-site-operations.md b/docs/public-site-operations.md index 6c3ba051..5885189c 100644 --- a/docs/public-site-operations.md +++ b/docs/public-site-operations.md @@ -1,39 +1,47 @@ -# OneAgent 公开站运营与发布手册 - -状态:已迁出。站点自己的构建命令、环境变量和部署步骤见 -[MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site) 的 README。 - -公开站曾经是本仓库的 `site/` 目录,现在是独立仓库。本文件只保留仍然约束本仓库的部分, -不再重复站点侧的操作步骤——两处各写一份必然慢慢分叉。 - -本文原先描述的 `.github/workflows/technical-preview.yml` 和 `.github/workflows/site.yml` -都已不存在(本仓库当前只有 `build-artifacts.yml`),按那两个工作流写的发布顺序因此 -已经失效,不要照着执行。 - -## 仍然由本仓库承担的部分 - -**GitHub Release 是公开版本与资产的事实源。** 站点在构建时调用 GitHub Releases API, -只读取已发布、非 Draft 的 Release;页面上的版本标签、发布日期、下载地址、文件大小和 -SHA-256 都来自那里,站点不读取本地 `release/` 目录,不复制下载资产,也不维护版本回退值。 -所以本仓库这边的义务是:Release 一旦发布就是公开事实,资产、校验和、签名状态必须在发布 -**之前**检查完毕。 - -**`providers.lock.json` 是商业披露字段的真源。** Provider 的 `relationship`、 -`disclosure`、`referral_url` 在这里维护,且不能影响 Agent rank、兼容性结论、默认选择 -或连接测试。这条边界属于本仓库,站点只把结果展示出来。 - -**改 lock 文件不会自动改变站上内容。** 站点把 `agents.lock.json` 和 -`providers.lock.json` vendor 到它自己的 `data/` 目录,从发行 tag 刷新而不是跟随本仓库 -`main`。这是刻意的:站描述的是已发布版本支持什么,跟着 `main` 会把已合并但未发布的 -Agent 宣传成可用。新增 Agent 或调整披露字段后,需要到站点仓库按其 `data/README.md` -刷新一次。 - -**Stable 门禁不变。** 各平台的签名、公证和原生 cleanroom 门禁仍是 App 发布流程的要求, -GitHub Release 不替代产物验证。 - -## 历史背景 - -设计决策记录在 -[ADR-009](decisions/ADR-009-public-site-and-generated-release-index.md)。该 ADR 中 -「在同一仓库维护 `site/`」的部分已被本次拆分取代;不把营销路由加入本地 Launcher 的 -结论仍然有效。 +# OneAgent public site operations and release handbook + +Status: moved out. For the site's own build commands, environment variables, and +deployment steps, see the README in +[MaimoryLab/OneAgent-site](https://github.com/MaimoryLab/OneAgent-site). + +The public site used to be this repository's `site/` directory and is now a separate +repository. This file keeps only the parts that still constrain this repository, and no +longer repeats the site-side steps -- two copies would drift apart sooner or later. + +The `.github/workflows/technical-preview.yml` and `.github/workflows/site.yml` this +document originally described no longer exist (this repository now has only +`build-artifacts.yml`), so the release sequence written around those two workflows is +obsolete. Do not follow it. + +## What this repository still owns + +**A GitHub Release is the source of truth for a public version and its assets.** At build +time the site calls the GitHub Releases API and reads only published, non-draft releases. +The version tag, release date, download URL, file size, and SHA-256 shown on the page all +come from there. The site does not read a local `release/` directory, does not copy +download assets, and maintains no fallback version values. This repository's obligation +follows from that: once a release is published it is public fact, so assets, checksums, +and signing status must be verified **before** publishing. + +**`providers.lock.json` is the source of truth for commercial disclosure fields.** A +Provider's `relationship`, `disclosure`, and `referral_url` are maintained here, and they +must not influence Agent rank, compatibility conclusions, default selection, or connection +tests. That boundary belongs to this repository; the site only displays the result. + +**Changing a lock file does not change the site.** The site vendors `agents.lock.json` +and `providers.lock.json` into its own `data/` directory, refreshed from release tags +rather than tracking this repository's `main`. This is deliberate: the site describes what +a published version supports, and following `main` would advertise an Agent that is merged +but not yet released. After adding an Agent or adjusting a disclosure field, refresh the +site repository per its `data/README.md`. + +**The Stable gate is unchanged.** Per-platform signing, notarization, and the native +cleanroom gate remain requirements of the app release process. A GitHub Release does not +substitute for verifying the artifacts. + +## Background + +The design decision is recorded in +[ADR-009](decisions/ADR-009-public-site-and-generated-release-index.md). The part of that +ADR about maintaining `site/` in the same repository has been superseded by this split; +its conclusion about not adding marketing routes to the local Launcher still holds. diff --git a/scripts/check-docs.py b/scripts/check-docs.py new file mode 100644 index 00000000..d0be1350 --- /dev/null +++ b/scripts/check-docs.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +"""Check Markdown cross-links and the language split of outward-facing docs. + +Two failures this catches that a build cannot: a relative link that stopped +resolving after a file moved, and Chinese text left in a document that is +declared English-only. Both are invisible to `go vet` and `pnpm run build`, +which is how docs drift in the first place. + +Usage: python3 scripts/check-docs.py +""" + +from __future__ import annotations + +import pathlib +import re +import sys + +ROOT = pathlib.Path(__file__).resolve().parent.parent + +# Inline links, minus image embeds. Bare autolinks () never point at +# a repository path, so they are out of scope. +LINK = re.compile(r"(? list[pathlib.Path]: + import subprocess + + out = subprocess.run( + ["git", "ls-files", "*.md"], + cwd=ROOT, + capture_output=True, + text=True, + check=True, + ).stdout + return [ROOT / line for line in out.splitlines() if line] + + +def check_links(paths: list[pathlib.Path]) -> list[str]: + errors = [] + for path in paths: + text = path.read_text(encoding="utf-8") + for match in LINK.finditer(text): + target = match.group(1) + if target.startswith(("http://", "https://", "mailto:", "#")): + continue + anchor = target.split("#", 1)[0] + if not anchor: + continue + resolved = (path.parent / anchor).resolve() + if not resolved.exists(): + line = text[: match.start()].count("\n") + 1 + rel = path.relative_to(ROOT) + errors.append(f"{rel}:{line}: broken link -> {target}") + return errors + + +def check_language(paths: list[pathlib.Path]) -> list[str]: + errors = [] + for path in paths: + rel = path.relative_to(ROOT).as_posix() + if rel in ENGLISH_ONLY_EXCEPTIONS: + continue + if not any(rel == p or rel.startswith(p + "/") for p in ENGLISH_ONLY): + continue + for number, line in enumerate(path.read_text(encoding="utf-8").split("\n"), 1): + if not CJK.search(line): + continue + if any(token in line for token in ALLOWED_CJK_LINES): + continue + errors.append(f"{rel}:{number}: Chinese text in an English-only doc") + return errors + + +def main() -> int: + paths = tracked_markdown() + errors = check_links(paths) + check_language(paths) + if errors: + for error in errors: + print(error, file=sys.stderr) + print(f"\n{len(errors)} problem(s) in {len(paths)} markdown files", file=sys.stderr) + return 1 + print(f"ok: {len(paths)} markdown files, links resolve, language split holds") + return 0 + + +if __name__ == "__main__": + sys.exit(main())