mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
docs: Add VS Code extension install paths / 添加 VS Code 扩展安装入口 (#6735)
* docs: add VS Code extension install links Summary: - document the Reasonix VS Code extension in both READMEs - add Marketplace and Open VSX install paths to the website - cover the new deep link and responsive download layout Verification: - cd site && npm test - cd site && npx astro build - Chromium checks at 1280px and 320px * docs: remove obsolete rewrite banner Context: The top-level 1.0 rewrite notice describes main-v2 as a new default and duplicates migration guidance that remains linked in the documentation section. Change: Remove the transitional notice from both English and Chinese READMEs while preserving the dedicated migration guide links. Verification: - git diff --check - confirmed both README migration links remain * docs: clarify Reasonix install paths Context: The bilingual README grouped install channels without helping readers choose between CLI, Desktop, editor, and source workflows. Change: Reorganize installation guidance into explicit paths with a platform table and first-run steps. Keep project support details at the bottom in a collapsed section so they remain available without distracting from the documentation. Verification: - git diff --check - verified release, desktop, extension, source, and donation links * docs: simplify support footer Context: The collapsed support block added unnecessary interaction at the very end of the README. Change: Replace the disclosure control in both README variants with a subtle horizontal divider and compact centered label while keeping the support details visible. Verification: - git diff --check - inspected the bilingual footer markup * docs: separate CLI and desktop quick starts Context: The README quick-start mixed CLI commands with desktop usage and duplicated detailed configuration guidance already covered by the docs. Change: Keep a minimal CLI/TUI command flow, add a distinct desktop download-and-launch path, and replace the inline configuration example with links to the authoritative CLI and configuration guides. Verification: - git diff --check - verified bilingual documentation targets - verified the desktop download URL returns HTTP 200 * docs: streamline documentation links Context: The README documentation section presented a long flat list, and its embedded Star History image currently fails to load. Change: Group bilingual documentation links into three concise categories, surface the configuration-path guide, label English-only links in the Chinese README, and replace the broken chart embed with a stable page link. Verification: - git diff --check - verified every referenced documentation file exists - verified the Star History page returns HTTP 200 * docs: restore the Star History chart Context: The README should display the existing project trend chart by default instead of reducing it to a text link. Change: Restore the exact bilingual Star History picture markup currently used by the upstream online README, including light and dark theme sources. Verification: - git diff --check - compared both restored sections byte-for-byte with origin/main-v2 * docs: keep README links language-specific Context: The Chinese README documentation index still linked to three English-only pages, making the language routing inconsistent. Change: Remove English-only Spec, migration, and checkpoint links from the Chinese index and retain them in the English README. Rename the remaining Chinese engineering group to match its contents. Verification: - git diff --check - confirmed every Chinese index link targets a zh-CN document - confirmed the English index contains no zh-CN links * docs: add missing Chinese references Context:\nThe Chinese README should keep the same documentation coverage as the English README without sending Chinese readers to English-only pages.\n\nChange:\nAdd Chinese engineering spec, migration, and checkpoints references, and restore their links in README.zh-CN.md.\n\nVerification:\nValidated Markdown fence balance, relative links, privacy-sensitive strings, and git diff whitespace. * site: place VS Code install tab last Context: The VS Code install channel should follow the existing desktop and package-manager options in the homepage tab order. Change: Move the VS Code tab after Homebrew and add a source contract assertion for the channel order. Verification: Ran the complete site test suite and verified the deep link still selects the VS Code pane in the local browser preview. * site: clarify editor extension install tab Context: The install pane covers both Visual Studio Marketplace and Open VSX, so a VS Code-only label is too narrow. Change: Rename the tab to Editor extension / 编辑器扩展 while preserving the vscode deep-link key, and add a bilingual copy contract assertion. Verification: Ran all site tests and verified the local deep link selects the renamed pane. * site: streamline hero secondary links Context: The hero secondary install guidance was a dense sentence with weak scanability and low visual contrast. Change: Turn it into a concise bilingual “More ways to use Reasonix” navigation row with wrapping, clearer hierarchy, visible link affordances, and focus styling. Verification: Ran all site tests and verified the local homepage in the in-app browser. * docs: clarify web dashboard recommendation Context: The migration guide said v2 no longer had a web dashboard, contradicting the supported `reasonix serve` browser UI. Change: Keep the web dashboard documented while recommending the Wails desktop app as the primary visual experience in both languages. Verification: - cd site && npm test - git diff --check - confirmed the obsolete no-dashboard wording is absent * docs: clarify explicit Goal activation Problem: The Chinese engineering spec did not explicitly state that AutoResearch requires an explicitly started Goal. Root cause: The translated summary predated main-v2's rule that ordinary chat never changes collaboration mode or creates durable AutoResearch state. Fix: State that users must choose Goal or run /goal before long-horizon work can enable AutoResearch, and that ordinary chat stays ordinary. Verification: - cd site && npm test - git diff --check - compared the Chinese wording with the latest main-v2 Goal contract * docs: clarify explicit Plan activation Problem: The Chinese engineering spec did not state that Plan Mode requires an explicit user choice. Root cause: The translation predated main-v2 retiring automatic Plan Mode. Fix: Document that ordinary chat cannot enter Plan automatically, that tool approval posture is independent, and that an approved-plan execution window cannot approve later plans. Verification: - cd site && npm test - git diff --check - compared the Chinese wording with the latest main-v2 Plan contract
This commit is contained in:
1 parent
222af64188
commit
9cd6c67a6e
11 files changed
+725
-163
No files matched your search
@@ -18,11 +18,6 @@
|
||||
<strong><a href="https://discord.gg/XF78rEME2D">Discord</a></strong>
|
||||
</p>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Reasonix 1.0 is a ground-up rewrite in Go** — this branch (`main-v2`) is the new default and where development happens now.
|
||||
> The earlier `0.x` TypeScript releases are **legacy**, living on the [`v1`](https://github.com/esengine/DeepSeek-Reasonix/tree/v1) branch (maintenance only).
|
||||
> See the **[migration guide](./docs/MIGRATING.md)**. `npm i -g reasonix` stays the install command — `1.0.0`+ delivers the Go binary, `0.x` is the legacy TS build.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/reasonix"><img src="https://img.shields.io/npm/v/reasonix.svg?style=flat-square&color=cb3837&labelColor=161b22&logo=npm&logoColor=white" alt="npm version"/></a>
|
||||
<a href="https://github.com/esengine/DeepSeek-Reasonix/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/esengine/DeepSeek-Reasonix/ci.yml?style=flat-square&label=ci&labelColor=161b22&logo=githubactions&logoColor=white" alt="CI"/></a>
|
||||
@@ -64,6 +59,14 @@
|
||||
|
||||
## Install
|
||||
|
||||
Choose the path that matches how you want to use Reasonix. The CLI/TUI,
|
||||
desktop app, and VS Code extension all use the same local Reasonix engine.
|
||||
|
||||
### Path A: CLI / TUI
|
||||
|
||||
Install the native binary through npm on any supported platform, or use
|
||||
Homebrew on macOS:
|
||||
|
||||
```sh
|
||||
npm i -g reasonix # any OS; pulls the prebuilt native binary
|
||||
brew install esengine/reasonix/reasonix # macOS
|
||||
@@ -72,90 +75,76 @@ brew install esengine/reasonix/reasonix # macOS
|
||||
Prebuilt archives (`darwin|linux|windows × amd64|arm64`) and `SHA256SUMS` are on
|
||||
every [GitHub release](https://github.com/esengine/DeepSeek-Reasonix/releases).
|
||||
|
||||
### Code signing
|
||||
### Path B: Desktop app
|
||||
|
||||
Windows builds are code-signed with a free certificate provided by the
|
||||
[SignPath Foundation](https://signpath.org/), with signing through
|
||||
[SignPath.io](https://signpath.io/).
|
||||
Use the [official download page](https://reasonix.io/?download=desktop#start)
|
||||
for the latest desktop build.
|
||||
|
||||
### Build from source
|
||||
| Platform | Package | Architecture |
|
||||
| --- | --- | --- |
|
||||
| macOS | Universal `.dmg` or `.zip` | Apple Silicon / Intel |
|
||||
| Windows | Installer `.exe` or portable `.zip` | x64 / ARM64 |
|
||||
| Linux | `.deb` or `.tar.gz` | x64 |
|
||||
|
||||
Windows installers are code-signed through [SignPath.io](https://signpath.io/)
|
||||
with a free certificate provided by the [SignPath Foundation](https://signpath.org/).
|
||||
|
||||
### Path C: VS Code extension
|
||||
|
||||
Complete Path A first. The extension does not bundle the CLI; it starts your
|
||||
local `reasonix acp` backend and adds native chat, editor context, tool-call
|
||||
approvals, model selection, and workspace sessions.
|
||||
|
||||
- **VS Code:** [install from Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=SivanLiu.reasonix-agent)
|
||||
- **VSCodium / Eclipse Theia:** [install from Open VSX Registry](https://open-vsx.org/extension/SivanLiu/reasonix-agent)
|
||||
- **Extension ID:** `SivanLiu.reasonix-agent` · [source and usage guide](https://github.com/SivanCola/reasonix-vscode)
|
||||
|
||||
### Path D: Build from source
|
||||
|
||||
```sh
|
||||
git clone https://github.com/esengine/DeepSeek-Reasonix.git
|
||||
cd DeepSeek-Reasonix
|
||||
make build # -> bin/reasonix(.exe)
|
||||
make cross # -> dist/ (darwin|linux|windows × amd64|arm64)
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
### CLI / TUI
|
||||
|
||||
These commands are for the CLI/TUI installed through Path A:
|
||||
|
||||
```sh
|
||||
reasonix setup # manage providers in the user config
|
||||
reasonix setup --local # optional: manage ./reasonix.toml
|
||||
export DEEPSEEK_API_KEY=sk-... # or let setup save it to Reasonix home .env
|
||||
reasonix # then run /init to generate AGENTS.md (project memory)
|
||||
reasonix setup # configure a provider and model
|
||||
reasonix # start an interactive session
|
||||
reasonix run "implement the TODOs in main.go"
|
||||
reasonix run --model deepseek-pro "add unit tests for this function"
|
||||
echo "explain this code" | reasonix run
|
||||
```
|
||||
|
||||
## Configuration
|
||||
In an interactive session, run `/init` when you want Reasonix to create project
|
||||
instructions.
|
||||
|
||||
A minimal `reasonix.toml` — one provider and a default model — is enough to start:
|
||||
### Desktop app
|
||||
|
||||
```toml
|
||||
default_model = "deepseek-flash"
|
||||
Download the installer for your platform from the
|
||||
[official download page](https://reasonix.io/?download=desktop#start), install
|
||||
and launch Reasonix, then configure a provider and model in the app. The CLI
|
||||
commands above are not required for the desktop app.
|
||||
|
||||
[[providers]]
|
||||
name = "deepseek-flash"
|
||||
kind = "openai"
|
||||
base_url = "https://api.deepseek.com"
|
||||
model = "deepseek-v4-flash"
|
||||
api_key_env = "DEEPSEEK_API_KEY"
|
||||
```
|
||||
|
||||
Resolution order is **flag > `./reasonix.toml` > the user config file >
|
||||
built-in defaults**; starting with **Reasonix v1.8.1**, the user file lives at
|
||||
`~/.reasonix/config.toml` on macOS/Linux and
|
||||
`%AppData%\reasonix\config.toml` on Windows. See
|
||||
**[Configuration paths](./docs/CONFIG_PATHS.md)** for migration details and the
|
||||
full `config.toml` / `.env` structure. Provider entries name secrets with
|
||||
`api_key_env`; the secret values themselves live in Reasonix's global
|
||||
`<Reasonix home>/.env`, shared by CLI and desktop. Project `.env` files are not
|
||||
provider-key runtime fallbacks, but still feed workspace-scoped, non-provider
|
||||
`${VAR}` expansion for MCP/plugin settings without importing Reasonix control
|
||||
variables. Permissions, the sandbox, plugins (MCP), slash
|
||||
commands, `@` references, and two-model setup are all in the
|
||||
**[Guide](./docs/GUIDE.md)**.
|
||||
For advanced CLI usage and configuration, see the **[CLI reference](./docs/CLI.md)**,
|
||||
**[Guide](./docs/GUIDE.md)**, and
|
||||
**[configuration paths](./docs/CONFIG_PATHS.md)**.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[CLI reference](./docs/CLI.md)** — interactive and one-shot commands,
|
||||
structured output, resume, permission modes, and searchable pickers.
|
||||
- **[Guide](./docs/GUIDE.md)** — configuration, permissions & sandbox, plugins
|
||||
(MCP), slash commands, `@` references, two-model collaboration.
|
||||
- **[ACP editor integration](./docs/ACP.md)** — launch Reasonix from an ACP
|
||||
host, manage sessions and configuration, and integrate mid-turn steering.
|
||||
- **[Subagent profiles](./docs/SUBAGENT_PROFILES.md)** — create, share, preview,
|
||||
run, edit, and safely delete isolated agent profiles from desktop or CLI.
|
||||
- **[Capability diagnostics](./docs/CAPABILITY_DIAGNOSTICS.md)** —
|
||||
`reasonix doctor capabilities`, desktop Settings → Diagnostics, and the
|
||||
`/reasonix-guide` skill for skills/hooks/MCP/plugin troubleshooting.
|
||||
- **[Recovery and Safe Mode](./docs/RECOVERY.md)** — Guard diagnostics,
|
||||
configuration snapshots, native recovery, update rollback, and optional
|
||||
AI-assisted repair plans.
|
||||
- **[Bot guide](./docs/BOT_GUIDE.md)** — connect Feishu, Lark, and WeChat bots
|
||||
from the desktop app, then use approvals, YOLO, and commands from IM.
|
||||
- **[Spec](./docs/SPEC.md)** — engineering contract: architecture, registries,
|
||||
data types, and roadmap.
|
||||
- **[Task contracts & pause policy](./docs/TASK_CONTRACT.md)** — structure
|
||||
complex requests with context, output boundaries, constraints, and when to ask.
|
||||
- **[Tool contract](./docs/TOOL_CONTRACT.md)** — provider-visible built-in tool
|
||||
names, read-only flags, and schema snapshot guard.
|
||||
- **[Migrating from 0.x](./docs/MIGRATING.md)** — moving from the legacy
|
||||
TypeScript releases to the 1.0 Go rewrite.
|
||||
- **[Checkpoints & rewind](./docs/CHECKPOINTS.md)** — the snapshot-based edit
|
||||
safety net (Esc-Esc / `/rewind`).
|
||||
|
||||
<br/>
|
||||
- **Getting started:** [Guide](./docs/GUIDE.md) · [CLI reference](./docs/CLI.md) ·
|
||||
[Configuration paths](./docs/CONFIG_PATHS.md) · [ACP editor integration](./docs/ACP.md)
|
||||
- **Features & troubleshooting:** [Subagent profiles](./docs/SUBAGENT_PROFILES.md) ·
|
||||
[Capability diagnostics](./docs/CAPABILITY_DIAGNOSTICS.md) ·
|
||||
[Recovery and Safe Mode](./docs/RECOVERY.md) · [Bot guide](./docs/BOT_GUIDE.md) ·
|
||||
[Checkpoints & rewind](./docs/CHECKPOINTS.md)
|
||||
- **Engineering & migration:** [Spec](./docs/SPEC.md) ·
|
||||
[Task contracts & pause policy](./docs/TASK_CONTRACT.md) ·
|
||||
[Tool contract](./docs/TOOL_CONTRACT.md) · [Migrating from 0.x](./docs/MIGRATING.md)
|
||||
|
||||
## Star History
|
||||
|
||||
@@ -169,19 +158,6 @@ commands, `@` references, and two-model setup are all in the
|
||||
|
||||
<br/>
|
||||
|
||||
## Support
|
||||
|
||||
If Reasonix has been useful and you'd like to say thanks, you can. It stays a coffee, not a contract — donations don't buy feature priority or change how issues get triaged.
|
||||
|
||||
- **International** — PayPal: [paypal.me/yuhuahui](https://paypal.me/yuhuahui)
|
||||
- **国内** — 微信支付(扫码)
|
||||
|
||||
<p align="center">
|
||||
<img src=".github/sponsor/wechat-pay.jpg" alt="WeChat Pay QR code" width="240"/>
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
A small list of folks whose work has shaped Reasonix the most — the current top
|
||||
@@ -217,3 +193,18 @@ for designing the project logo, and to
|
||||
<br/>
|
||||
<sub>Built by the community at <a href="https://github.com/esengine/DeepSeek-Reasonix/graphs/contributors">esengine/DeepSeek-Reasonix</a></sub>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<p align="center"><sub><strong>Support this project</strong></sub></p>
|
||||
|
||||
If Reasonix has been useful and you'd like to say thanks, you can. It stays a
|
||||
coffee, not a contract — donations don't buy feature priority or change how
|
||||
issues get triaged.
|
||||
|
||||
- **International** — PayPal: [paypal.me/yuhuahui](https://paypal.me/yuhuahui)
|
||||
- **国内** — 微信支付(扫码)
|
||||
|
||||
<p align="center">
|
||||
<img src=".github/sponsor/wechat-pay.jpg" alt="WeChat Pay QR code" width="180"/>
|
||||
</p>
|
||||
+71
-73
@@ -11,18 +11,13 @@
|
||||
·
|
||||
<a href="./docs/ACP.zh-CN.md">ACP</a>
|
||||
·
|
||||
<a href="./docs/SPEC.md">规格</a>
|
||||
<a href="./docs/SPEC.zh-CN.md">规格</a>
|
||||
·
|
||||
<a href="https://esengine.github.io/DeepSeek-Reasonix/">官方网站</a>
|
||||
·
|
||||
<strong><a href="https://discord.gg/XF78rEME2D">Discord</a></strong>
|
||||
</p>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Reasonix 1.0 是用 Go 从零重写的版本** —— 本分支(`main-v2`)已是新的默认分支,后续开发都在这里。
|
||||
> 早期的 `0.x` TypeScript 版本转为 **legacy**,保留在 [`v1`](https://github.com/esengine/DeepSeek-Reasonix/tree/v1) 分支(仅维护)。
|
||||
> 详见**[迁移指南](./docs/MIGRATING.md)**。`npm i -g reasonix` 仍是安装命令——`1.0.0`+ 装的是 Go 二进制,`0.x` 是 legacy TS 版。
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/reasonix"><img src="https://img.shields.io/npm/v/reasonix.svg?style=flat-square&color=cb3837&labelColor=161b22&logo=npm&logoColor=white" alt="npm version"/></a>
|
||||
<a href="https://github.com/esengine/DeepSeek-Reasonix/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/esengine/DeepSeek-Reasonix/ci.yml?style=flat-square&label=ci&labelColor=161b22&logo=githubactions&logoColor=white" alt="CI"/></a>
|
||||
@@ -60,6 +55,13 @@
|
||||
|
||||
## 安装
|
||||
|
||||
选择适合你的使用路径。CLI/TUI、桌面端和 VS Code 扩展都使用同一套本地
|
||||
Reasonix 引擎。
|
||||
|
||||
### 路径 A:CLI / TUI
|
||||
|
||||
任意支持的平台都可以通过 npm 安装原生二进制;macOS 也可以使用 Homebrew:
|
||||
|
||||
```sh
|
||||
npm i -g reasonix # 任意系统;自动拉取对应平台的原生二进制
|
||||
brew install esengine/reasonix/reasonix # macOS
|
||||
@@ -68,80 +70,75 @@ brew install esengine/reasonix/reasonix # macOS
|
||||
预编译归档(`darwin|linux|windows × amd64|arm64`)和 `SHA256SUMS` 见每个
|
||||
[GitHub release](https://github.com/esengine/DeepSeek-Reasonix/releases)。
|
||||
|
||||
### 代码签名
|
||||
### 路径 B:桌面端
|
||||
|
||||
Windows 构建使用 [SignPath 基金会](https://signpath.org/) 提供的免费代码签名证书,
|
||||
通过 [SignPath.io](https://signpath.io/) 完成签名。
|
||||
前往[官方下载页](https://reasonix.io/?download=desktop#start)获取最新桌面版本。
|
||||
|
||||
### 从源码构建
|
||||
| 平台 | 安装包 | 架构 |
|
||||
| --- | --- | --- |
|
||||
| macOS | 通用 `.dmg` 或 `.zip` | Apple Silicon / Intel |
|
||||
| Windows | 安装器 `.exe` 或便携 `.zip` | x64 / ARM64 |
|
||||
| Linux | `.deb` 或 `.tar.gz` | x64 |
|
||||
|
||||
Windows 安装器通过 [SignPath.io](https://signpath.io/) 完成代码签名,证书由
|
||||
[SignPath 基金会](https://signpath.org/) 免费提供。
|
||||
|
||||
### 路径 C:VS Code 扩展
|
||||
|
||||
请先完成路径 A。扩展不内置 CLI,而是启动本机的 `reasonix acp` 后端,
|
||||
并提供原生聊天、编辑器上下文、工具调用审批、模型选择和工作区会话。
|
||||
|
||||
- **VS Code:** [从 Visual Studio Marketplace 安装](https://marketplace.visualstudio.com/items?itemName=SivanLiu.reasonix-agent)
|
||||
- **VSCodium / Eclipse Theia:** [从 Open VSX Registry 安装](https://open-vsx.org/extension/SivanLiu/reasonix-agent)
|
||||
- **扩展 ID:** `SivanLiu.reasonix-agent` · [源码与使用说明](https://github.com/SivanCola/reasonix-vscode)
|
||||
|
||||
### 路径 D:从源码构建
|
||||
|
||||
```sh
|
||||
git clone https://github.com/esengine/DeepSeek-Reasonix.git
|
||||
cd DeepSeek-Reasonix
|
||||
make build # -> bin/reasonix(.exe)
|
||||
make cross # -> dist/(darwin|linux|windows × amd64|arm64)
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### CLI / TUI
|
||||
|
||||
以下命令仅适用于通过路径 A 安装的 CLI/TUI:
|
||||
|
||||
```sh
|
||||
reasonix setup # 管理用户配置中的 provider
|
||||
reasonix setup --local # 可选:管理 ./reasonix.toml
|
||||
export DEEPSEEK_API_KEY=sk-... # 也可以让 setup 保存到 Reasonix 全局 .env
|
||||
reasonix # 然后在会话里运行 /init 生成 AGENTS.md(项目记忆)
|
||||
reasonix setup # 配置 provider 和模型
|
||||
reasonix # 启动交互式会话
|
||||
reasonix run "把 main.go 里的 TODO 实现掉"
|
||||
reasonix run --model deepseek-pro "给这个函数补单元测试"
|
||||
echo "解释这段代码" | reasonix run
|
||||
```
|
||||
|
||||
## 配置
|
||||
需要项目指令时,可在交互式会话中运行 `/init`。
|
||||
|
||||
一个最小的 `reasonix.toml`——一个 provider 加一个默认模型——就够跑起来:
|
||||
### 桌面端
|
||||
|
||||
```toml
|
||||
default_model = "deepseek-flash"
|
||||
从[官方下载页](https://reasonix.io/?download=desktop#start)下载对应系统的安装包,
|
||||
安装并启动 Reasonix,然后在应用内配置 provider 和模型即可使用。桌面端无需执行
|
||||
上面的 CLI 命令。
|
||||
|
||||
[[providers]]
|
||||
name = "deepseek-flash"
|
||||
kind = "openai"
|
||||
base_url = "https://api.deepseek.com"
|
||||
model = "deepseek-v4-flash"
|
||||
api_key_env = "DEEPSEEK_API_KEY"
|
||||
```
|
||||
|
||||
优先级为 **flag > `./reasonix.toml` > 用户配置文件 > 内置默认值**;从
|
||||
**Reasonix v1.8.1** 开始,用户配置位于 macOS/Linux 的 `~/.reasonix/config.toml`,
|
||||
Windows 为 `%AppData%\reasonix\config.toml`。迁移细节见
|
||||
**[配置路径](./docs/CONFIG_PATHS.zh-CN.md)**,其中也说明了全局 `config.toml`
|
||||
和 `.env` 的完整结构。Provider 通过 `api_key_env` 命名密钥,真实密钥值保存在
|
||||
CLI 与桌面端共用的 Reasonix 全局 `<Reasonix home>/.env`;项目 `.env` 不再作为
|
||||
provider key 的运行时 fallback,但仍会作为当前 workspace 范围内的 MCP/plugin 非 provider `${VAR}` 展开来源,不导入 Reasonix 控制变量。权限、沙盒、插件(MCP)、
|
||||
斜杠命令、`@` 引用与双模型设置,全部在 **[指南](./docs/GUIDE.zh-CN.md)** 里。
|
||||
CLI 进阶用法和详细配置见 **[CLI 命令参考](./docs/CLI.zh-CN.md)**、
|
||||
**[指南](./docs/GUIDE.zh-CN.md)** 和
|
||||
**[配置路径](./docs/CONFIG_PATHS.zh-CN.md)**。
|
||||
|
||||
## 文档
|
||||
|
||||
- **[CLI 命令参考](./docs/CLI.zh-CN.md)** —— 交互与一次性命令、结构化输出、
|
||||
会话恢复、权限模式和可搜索选择器。
|
||||
- **[指南](./docs/GUIDE.zh-CN.md)** —— 配置、权限与沙盒、插件(MCP)、斜杠命令、
|
||||
`@` 引用、双模型协同。
|
||||
- **[ACP 编辑器接入](./docs/ACP.zh-CN.md)** —— 从 ACP host 启动 Reasonix、管理
|
||||
会话与配置,并接入回合中引导。
|
||||
- **[子智能体 Profile](./docs/SUBAGENT_PROFILES.zh-CN.md)** —— 在桌面端或 CLI
|
||||
创建、共享、预览、运行、编辑和安全删除隔离智能体 Profile。
|
||||
- **[能力诊断](./docs/CAPABILITY_DIAGNOSTICS.zh-CN.md)** ——
|
||||
`reasonix doctor capabilities`、桌面端 **设置 → 诊断**,以及内置 Skill
|
||||
`/reasonix-guide`,用于 skills / hooks / MCP / 插件排障。
|
||||
- **[恢复与安全模式](./docs/RECOVERY.zh-CN.md)** —— Guard 诊断、配置快照、
|
||||
原生恢复、更新回滚和可选 AI 修复计划。
|
||||
- **[机器人使用指南](./docs/BOT_GUIDE.zh-CN.md)** —— 桌面端连接飞书、Lark、微信
|
||||
Bot,以及 IM 里的审批、YOLO 和命令交互。
|
||||
- **[规格](./docs/SPEC.md)** —— 工程契约:架构、registry、数据类型与路线图。
|
||||
- **[任务合约与暂停策略](./docs/TASK_CONTRACT.zh-CN.md)** —— 用背景、输出边界、约束和暂停条件组织复杂请求。
|
||||
- **[工具合约](./docs/TOOL_CONTRACT.zh-CN.md)** —— provider 可见的内置工具名、
|
||||
read-only 标记和 schema 快照保护。
|
||||
- **[从 0.x 迁移](./docs/MIGRATING.md)** —— 从 legacy TypeScript 版本迁到 1.0 Go 重写版。
|
||||
- **[Checkpoints 与 rewind](./docs/CHECKPOINTS.md)** —— 基于快照的编辑安全网
|
||||
(Esc-Esc / `/rewind`)。
|
||||
|
||||
<br/>
|
||||
- **开始使用:** [指南](./docs/GUIDE.zh-CN.md) ·
|
||||
[CLI 命令参考](./docs/CLI.zh-CN.md) · [配置路径](./docs/CONFIG_PATHS.zh-CN.md) ·
|
||||
[ACP 编辑器接入](./docs/ACP.zh-CN.md)
|
||||
- **功能与排障:** [子智能体 Profile](./docs/SUBAGENT_PROFILES.zh-CN.md) ·
|
||||
[能力诊断](./docs/CAPABILITY_DIAGNOSTICS.zh-CN.md) ·
|
||||
[恢复与安全模式](./docs/RECOVERY.zh-CN.md) ·
|
||||
[机器人使用指南](./docs/BOT_GUIDE.zh-CN.md) ·
|
||||
[Checkpoints 与 rewind](./docs/CHECKPOINTS.zh-CN.md)
|
||||
- **工程与迁移:** [规格](./docs/SPEC.zh-CN.md) ·
|
||||
[任务合约与暂停策略](./docs/TASK_CONTRACT.zh-CN.md) ·
|
||||
[工具合约](./docs/TOOL_CONTRACT.zh-CN.md) ·
|
||||
[从 0.x 迁移](./docs/MIGRATING.zh-CN.md)
|
||||
|
||||
## Star 趋势
|
||||
|
||||
@@ -155,19 +152,6 @@ provider key 的运行时 fallback,但仍会作为当前 workspace 范围内
|
||||
|
||||
<br/>
|
||||
|
||||
## 支持本项目
|
||||
|
||||
如果 Reasonix 帮你省了时间或 token,欢迎请杯咖啡。捐助不会换来 feature 优先级,也不会影响 issue 的处理顺序——就是「谢谢」。
|
||||
|
||||
- **国内** — 微信支付(扫下方二维码)
|
||||
- **海外** — PayPal: [paypal.me/yuhuahui](https://paypal.me/yuhuahui)
|
||||
|
||||
<p align="center">
|
||||
<img src=".github/sponsor/wechat-pay.jpg" alt="微信支付收款码" width="240"/>
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
|
||||
## 致谢
|
||||
|
||||
下面这些朋友的工作塑造了 Reasonix 今天的样子 —— 当前按 commit 数统计的前 20 名贡献者。
|
||||
@@ -202,3 +186,17 @@ provider key 的运行时 fallback,但仍会作为当前 workspace 范围内
|
||||
<br/>
|
||||
<sub>由 <a href="https://github.com/esengine/DeepSeek-Reasonix/graphs/contributors">esengine/DeepSeek-Reasonix</a> 社区共建</sub>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<p align="center"><sub><strong>支持本项目</strong></sub></p>
|
||||
|
||||
如果 Reasonix 帮你省了时间或 token,欢迎请杯咖啡。捐助不会换来 feature
|
||||
优先级,也不会影响 issue 的处理顺序——就是「谢谢」。
|
||||
|
||||
- **国内** — 微信支付(扫下方二维码)
|
||||
- **海外** — PayPal: [paypal.me/yuhuahui](https://paypal.me/yuhuahui)
|
||||
|
||||
<p align="center">
|
||||
<img src=".github/sponsor/wechat-pay.jpg" alt="微信支付收款码" width="180"/>
|
||||
</p>
|
||||
@@ -0,0 +1,98 @@
|
||||
# 设计:Checkpoints 与 Rewind
|
||||
|
||||
<a href="./CHECKPOINTS.md">English</a>
|
||||
|
||||
状态:**Phase 1 + 2 已实现**——包括快照存储、统一捕获切入点、Esc-Esc / `/rewind` CLI 选择器、桌面端悬停 rewind,以及完整的 Claude Code 风格菜单:恢复代码、恢复会话、同时恢复、从此处分叉、从此处开始摘要或摘要到此处。当前实现基于快照并与 Claude Code 对齐;可选的 git-backed 模式是优先级较低的后续工作。这补上了 v1 用户最常请求的编辑安全网 / 撤销能力。
|
||||
|
||||
本文说明 rewind 快照机制。关于自主运行期间智能体何时应暂停并询问用户,参见[任务合约与暂停策略](./TASK_CONTRACT.zh-CN.md)。
|
||||
|
||||
## 目标
|
||||
|
||||
让用户把会话回退到之前的节点,并恢复**代码**、**会话**或**两者**,且不改动 git 历史。CLI 与桌面端采用同一套机制,并与 Claude Code 的 Esc-Esc / `/rewind` 行为对齐。
|
||||
|
||||
## 机制:文件快照,而不是 git
|
||||
|
||||
与 Claude Code(以及 v1 的 `checkpoints.ts`)相同,checkpoint 是独立于 git 的**文件快照**:
|
||||
|
||||
- **不污染 git**:不提交、不暂存,也不修改 `.git/`;在非 git 目录中同样可用。
|
||||
- **只跟踪可预览的编辑工具变更**:包括 `write_file`、`edit_file` 和 `multi_edit`。`move_file` 遵循同一工作区权限边界,但移动操作尚不会出现在 checkpoint 预览中。
|
||||
- **不跟踪 `bash` 副作用**:系统无法判断 shell 命令改动了哪些内容,这一点与 Claude Code 相同;高风险 Bash 操作由权限层负责拦截。
|
||||
- 编辑前保存完整文件内容。实现简单,存储量通过下文的保留策略限制。
|
||||
|
||||
可选的 **git-backed 模式**(v1 的 `auto-git-rollback`)适合需要 git 级安全保障的用户,但不在当前范围内。
|
||||
|
||||
## 锚点与捕获
|
||||
|
||||
- **每个用户回合创建一个 checkpoint。** 回合开始时(`Controller.Send` / `runTurn`)创建,并以用户提示作为标签。
|
||||
- **编辑前快照。** 在 `agent.(*Agent).executeOne` 中,执行非只读且实现 `tool.Previewer` 的工具前,调用 `Preview(args)` 获得 `diff.Change{Path, Kind, OldText}`,再把文件快照记录到当前 checkpoint。文件写工具已经实现 `tool.Previewer`,因此只需这一处统一切入点,不必逐个修改工具。
|
||||
- 同一回合内按路径去重:只保存**第一次**触碰前的内容,即该文件在回合开始时的状态。
|
||||
- `Kind == create` 表示文件原本不存在,保存 `Content = nil`,恢复时删除该文件;`modify` / `delete` 保存 `OldText`。
|
||||
- `bash` 没有实现 `Previewer`,因此自然排除,符合“只跟踪编辑工具”的约定。
|
||||
|
||||
## 数据模型
|
||||
|
||||
```go
|
||||
type FileSnap struct {
|
||||
Path string // workspace-relative
|
||||
Content *string // nil → file did not exist at the anchor (restore deletes it)
|
||||
}
|
||||
|
||||
type Checkpoint struct {
|
||||
Turn int // user-message index this anchors (0-based)
|
||||
Time time.Time
|
||||
Prompt string // user message text — the picker label
|
||||
Files []FileSnap // distinct files touched during this turn, turn-start state
|
||||
}
|
||||
```
|
||||
|
||||
## 存储
|
||||
|
||||
- **作为会话 sidecar 保存**:位于 `config.SessionDir()` 下的 `<session-id>.ckpt/`,每个 checkpoint 一个 JSON 文件并附带小型索引。这样删除成本低,单个快照损坏也只影响自身。它与消息 JSONL(`agent.Session.Save`)分开,因此无需改动会话格式。
|
||||
- **跨进程保留**:恢复会话时会重新加载 checkpoint,重启后仍可 rewind,与 Claude Code 保持一致。
|
||||
- **保留策略**:随会话清理,默认约 30 天并可配置,以限制完整内容快照占用的磁盘空间。
|
||||
|
||||
## Controller API:两个前端共用的统一入口
|
||||
|
||||
Checkpoint 位于 `control.Controller`,与 `SetPlanMode`、`Compact`、`NewSession` 并列。终端 TUI、桌面 WebView 和 HTTP/SSE server 都通过同一入口触发 rewind,不在各自前端重复实现逻辑。
|
||||
|
||||
```go
|
||||
type RewindScope int // Code | Conversation | Both
|
||||
|
||||
func (c *Controller) Checkpoints() []CheckpointMeta // for the picker
|
||||
func (c *Controller) Rewind(turn int, scope RewindScope) error
|
||||
```
|
||||
|
||||
- **Code**:遍历从 `turn` 到最新的所有 checkpoint,按路径选取最早的 `FileSnap`,把文件恢复到对应内容;若为 `nil` 则删除。也就是撤销 `turn` 及之后的全部编辑。恢复前会再次按当前工作区根目录检查路径逃逸。
|
||||
- **Conversation**:把 `Session.Messages` 截断到 `turn` 对应用户消息之前,重新 `Save`,并发送替换后的历史事件供前端重绘。所选回合的提示会回填到输入框,方便修改后重发。
|
||||
- **Both**:同时恢复代码与会话。
|
||||
|
||||
统一的 `Rewound` 事件(或复用 history-replace 事件)让所有前端以相同方式重绘。
|
||||
|
||||
## CLI 体验(与 Claude Code 对齐)
|
||||
|
||||
- 输入框为空时按两次 **`Esc`**,或执行 **`/rewind`**,打开用户回合列表,显示时间和每个回合改动的文件。`chat_tui` 已跟踪双 Esc 的时间窗口。
|
||||
- 选择一个回合后显示子菜单:**`[code+conversation] [conversation] [code] [cancel]`**。
|
||||
- 恢复 conversation 或 both 时,把所选提示回填到输入框。
|
||||
|
||||
## 桌面端体验(与 VS Code 扩展对齐)
|
||||
|
||||
- Transcript 中每条用户消息悬停时显示 **rewind** 控件,并提供:恢复代码、恢复会话、同时恢复、从此处分叉。
|
||||
- 前端通过 Wails binding 调用同一个 `controller.Rewind`;Controller 事件流推送恢复结果,React 负责重绘。前端不包含独立 rewind 逻辑。
|
||||
|
||||
## 非目标与边界情况
|
||||
|
||||
- **Bash / 外部副作用**:`rm`、`mv`、数据库写入、部署等不会被跟踪,也无法通过 rewind 撤销,这与 Claude Code 一致。
|
||||
- **回合之间的外部编辑**:快照保存的是回合开始时的内容,因此恢复会覆盖期间由 Reasonix 之外产生的改动。
|
||||
- **删除**:编辑工具执行的删除可以恢复,因为快照保存了原内容;`bash rm` 无法恢复。
|
||||
- **大文件**:当前保存完整快照,由保留策略控制磁盘占用;若成为问题,再引入按内容寻址的去重。
|
||||
|
||||
## 阶段划分
|
||||
|
||||
1. **Phase 1**:快照存储、`executeOne` 捕获切入点、`Controller.Rewind`(code / conversation / both)、CLI 选择器(Esc-Esc + `/rewind`)。
|
||||
2. **Phase 2**:桌面端悬停 rewind、“从此处分叉”、“从此处开始摘要 / 摘要到此处”,以及可选的 git-backed 模式。
|
||||
|
||||
## 待确认问题
|
||||
|
||||
- 是否在 `/compact` 和 `NewSession` 边界创建快照?
|
||||
- 默认保留窗口应为多久,是否需要在 `[checkpoints]` 配置中公开?
|
||||
- 是否从一开始就使用内容寻址去重,而不是每个快照一个文件?
|
||||
+4
-1
@@ -141,7 +141,10 @@ and DeepSeek prefix-cache–oriented design.
|
||||
not write resumable transcripts, and keep writer-capable `task` / `run_skill`
|
||||
out of those explicitly read-only child registries. Ordinary writer-capable
|
||||
delegation in Plan uses Permissions/Sandbox.
|
||||
- **No web dashboard** — the v2 line is terminal + desktop (Wails), by design.
|
||||
- **Web dashboard remains available; desktop is recommended**: run
|
||||
`reasonix serve` when a local browser UI is useful. For the primary visual
|
||||
experience, prefer the Wails desktop app; CLI/TUI remains the terminal-native
|
||||
path.
|
||||
- Some granular v1 tools are intentionally consolidated (e.g. file-management ops
|
||||
go through `bash`); a few v1 tools are not yet ported (tracked on Discussions).
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# 迁移到 Reasonix 1.0(Go 重写版)
|
||||
|
||||
<a href="./MIGRATING.md">English</a>
|
||||
|
||||
Reasonix 1.0 是一次从零开始的 **Go 重写**。它使用全新的代码库,并不是 `0.x` TypeScript 版本的增量升级。本文说明两个版本的差异以及迁移方法。
|
||||
|
||||
## 摘要
|
||||
|
||||
| | 旧版(v1) | Reasonix 1.0+(v2) |
|
||||
| --- | --- | --- |
|
||||
| 语言 | TypeScript / Node.js | Go |
|
||||
| 分支 | [`v1`](https://github.com/esengine/DeepSeek-Reasonix/tree/v1)(仅维护) | `main-v2`(默认、活跃开发) |
|
||||
| 版本 | `0.x`(最高 v0.54.x) | `1.0.0`+ |
|
||||
| 安装 | `npm i -g [email protected]`(固定到某个 `0.x` 版本) | `npm i -g reasonix`;也可使用 release 归档或源码构建 |
|
||||
| 代码智能 | embedding 语义搜索 + tree-sitter 符号索引 | LSP 辅助代码读取,以及 grep/read_file/glob;语义索引尚未移植 |
|
||||
|
||||
“v1”和“v2”表示代码库代际,而不是 semver 主版本:v1 从未发布 1.0,因此 Go 重写版使用 `1.x` 版本号。
|
||||
|
||||
## 安装 1.0
|
||||
|
||||
`npm` 仍是主要安装渠道。npm 包会下载预编译的 Go 二进制文件,方式与 esbuild/biome 类似;二进制本身是独立的 Go 可执行文件,npm 不是运行时依赖。
|
||||
|
||||
**`npm i -g reasonix` 会安装当前稳定的 `1.x` 版本。** npm 的 `latest` 标签已从 `1.17.5` 起切换到 Go 版本。候选版本继续使用 `next` 标签;旧版 `0.x` 仍可通过固定版本安装:
|
||||
|
||||
```sh
|
||||
npm i -g reasonix # 当前稳定的 1.x
|
||||
npm i -g reasonix@next # 候选版本(当其领先于稳定版时)
|
||||
npm i -g [email protected] # 固定到旧版 TypeScript 构建
|
||||
```
|
||||
|
||||
每个 GitHub release 都附带预编译归档(`reasonix-<os>-<arch>.tar.gz` / `.zip`)和桌面安装包。它们与 npm 是不同的安装渠道:桌面安装包不会改动通过 `npm i -g` 安装的 CLI,因此 shell 中的 npm `0.53` 与 `1.x` 桌面应用可以共存,并不冲突。
|
||||
|
||||
也可以从源码构建:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/esengine/DeepSeek-Reasonix # 默认分支 main-v2(Go)
|
||||
cd DeepSeek-Reasonix && make build # -> bin/reasonix(.exe)
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
| 旧版 | Reasonix 1.0 |
|
||||
| --- | --- |
|
||||
| TypeScript 配置文件 | 项目使用 `reasonix.toml`;从 v1.8.1 起,全局配置为 Reasonix home 下的 `config.toml`(macOS/Linux:`~/.reasonix/`;Windows:`%AppData%\reasonix\`)。参见 `reasonix.example.toml` 和[配置路径](./CONFIG_PATHS.zh-CN.md) |
|
||||
| 环境变量 / API key | provider 配置保留 `api_key_env`;保存的 key 位于 Reasonix home 的 `.env`(`DEEPSEEK_API_KEY`、`MIMO_API_KEY` 等) |
|
||||
| 项目记忆 | `REASONIX.md`(含自动记忆),兼容 Claude Code |
|
||||
| MCP server | 在 `reasonix.toml` 中使用 `[[plugins]]`,或直接读取 Claude Code 的 `.mcp.json` |
|
||||
|
||||
首次启动时,v1.8.1+ 会执行一次非破坏性导入。它会读取以下旧配置:
|
||||
|
||||
- `~/Library/Application Support/reasonix/config.toml`
|
||||
- `~/.config/reasonix/config.toml`
|
||||
- `~/.reasonix/reasonix.toml`
|
||||
- v0.x 的 `~/.reasonix/config.json`
|
||||
|
||||
导入内容包括 API key、base URL、语言和 MCP server;缺失的旧凭据会迁移到 `<Reasonix home>/.env`,旧会话也会从历史目录导入。原文件不会被修改,Reasonix 会在导入后显示启动提示。
|
||||
|
||||
会话会根据 v0.x sidecar 元数据回到原工作区,并沿用旧摘要作为标题;工作区已不存在的会话会进入全局会话目录。可通过 `--resume` 或历史面板恢复这些会话。自动配置导入仅在尚未存在 v1.8.1+ 配置时运行;若新配置已经生成,请手动补入缺失值。
|
||||
|
||||
如果首次启动时旧路径尚不可用,可在交互式会话中运行 `/migrate`。若看到 `unknown command`,请先升级到包含该命令的 Go 版本。该命令会扫描旧配置、凭据、记忆和会话,并仅导入尚未导入的内容;它不会覆盖已有 `config.toml` 或记忆文件,也不会绕过会话导入标记。
|
||||
|
||||
若旧 v0.x 会话位于自定义 Windows 目录,可指定来源:
|
||||
|
||||
```text
|
||||
/migrate --from "D:\OldReasonix"
|
||||
```
|
||||
|
||||
完整路径和限制见[配置路径](./CONFIG_PATHS.zh-CN.md)。
|
||||
|
||||
## 保持不变的部分
|
||||
|
||||
agent 核心延续了原有能力:循环、读写编辑与 glob/grep/bash 等工具、子智能体(`task`、explore/research/review)、Skill、Hook、Plan 模式、MCP 客户端,以及针对 DeepSeek 前缀缓存的设计。
|
||||
|
||||
## 主要变化
|
||||
|
||||
- **代码智能**:Go 重写版通过 LSP 辅助代码读取,并结合 `grep`、`read_file` 和 `glob` 理解本地代码。v1 的语义搜索与 tree-sitter 符号索引尚未移植,CodeGraph 也不再以内置 MCP server 形式提供。
|
||||
- **Plan 模式**:新增 `complete_step`,用于基于证据确认步骤完成。
|
||||
- **MCP 身份与 schema 缓存 URL 感知凭据**:userinfo 和 token/api_key/password 等查询值不会进入本机身份或缓存指纹,因此轮换凭据不会使项目授权失效。旧工作区凭据可一次性迁移为启动授权,旧工具快照不会沿用。
|
||||
- **MCP 添加后即可使用**:用户通过桌面端、全局配置、旧配置导入或已验证插件包添加的 server 会立即连接;未显式配置 MCP 审批策略时默认允许调用。仓库内 `reasonix.toml` / `.mcp.json` 声明的 server 则必须先针对稳定身份确认一次,确认前不会启动进程或发起网络请求。
|
||||
- **stdio MCP 连接持久化**:writer 调用不再创建新进程,浏览器或会话类 server 的状态可以保留。
|
||||
- **Plan 与权限策略相互独立**:普通内置工具和 Bash 仍遵循 Ask/Auto/YOLO 与 Sandbox;已安装或代理解析的 MCP 写入/破坏性工具及不受信任的读取工具在整个规划阶段保持阻止。`complete_step` 等执行阶段工具也要等计划获批后才能使用。
|
||||
- `[agent].plan_mode_allowed_tools` 与 `plan_mode_read_only_commands` 仍可解析和保存,以兼容旧配置,但不再决定主 Plan 流程能否调用工具。需要可信读取能力时,应在 `trusted_read_only_tools` 中声明已审计的原始 MCP 工具名。
|
||||
- 使用 `read_only_task` / `read_only_skill` 创建技术上只读的子智能体;普通 `task` / `run_skill` 仍可写入,并受权限与 Sandbox 控制。第三方 MCP 的 `readOnlyHint` 只影响常规权限和调度,不会自动获得专用 planner 或只读子智能体的信任。
|
||||
- MCP 可通过 `default_tools_approval_mode`、`tools.<raw>.approval_mode` 和 `approvals_reviewer` 覆盖默认审批策略。标记 `destructiveHint: true` 的调用在 `auto`、`prompt` 或 `writes` 下每次都需要人工重新批准;有效的 `approve` 模式则直接允许。
|
||||
- **Web Dashboard 仍然可用,桌面端更推荐**:需要浏览器访问时,可运行
|
||||
`reasonix serve` 启动本地 Web UI;日常可视化使用优先选择 Wails 桌面端,
|
||||
终端工作流继续使用 CLI/TUI。
|
||||
- 一些细粒度 v1 工具被合并,例如文件管理操作改由 `bash` 完成;少数工具尚未移植,进度在 Discussions 中跟踪。
|
||||
|
||||
## 文件编码
|
||||
|
||||
Reasonix 1.0 支持读取和编辑 UTF-8、UTF-8 BOM、UTF-16 LE/BE 与 GB18030(GBK 的超集),与 v1 行为一致。
|
||||
|
||||
- `read_file` 会把受支持编码解码为 UTF-8 后提供给模型。
|
||||
- `edit_file` 和 `multi_edit` 会保留文件原编码;编辑 GB18030 文件后仍以 GB18030 保存。
|
||||
- `write_file` 始终写入 UTF-8。
|
||||
- `grep` 会在匹配前解码,因此正则表达式可用于非 UTF-8 文件。
|
||||
|
||||
## 报告问题
|
||||
|
||||
Issue 和 PR 按代码线标记:**`v1`** 表示旧 TypeScript 版,**`v2`** 表示 Go 版。请按实际使用版本提交报告。旧 `v1` 线处于维护模式,只接收 bug 修复,不再新增功能。
|
||||
|
||||
如有问题,请发起 [Discussion](https://github.com/esengine/DeepSeek-Reasonix/discussions)。
|
||||
@@ -0,0 +1,266 @@
|
||||
# Reasonix 工程规格
|
||||
|
||||
<a href="./SPEC.md">English</a>
|
||||
|
||||
> Reasonix 是一个 coding agent:由极薄的 harness 驱动多个模型,所有能力都由配置和插件提供。本文是工程契约,代码应遵循它;需要改变行为时,应先更新契约,再修改代码。
|
||||
|
||||
英文原文是规范性版本;本文按相同章节提供中文说明,代码标识符、配置键和协议名保持原样。
|
||||
|
||||
## 1. 设计原则
|
||||
|
||||
1. **配置与插件驱动。** 核心只依赖接口;具体模型和工具通过 registry 按名称解析、在配置中声明,或由插件注入,不硬编码 `switch model`。
|
||||
2. **单一静态二进制。** 使用 `CGO_ENABLED=0`,一条命令完成跨平台编译,CLI 开箱即用。
|
||||
3. **精简依赖。** 默认使用标准库。第三方依赖必须是纯 Go、足够轻量,且不能破坏单二进制、跨平台和分发体验;TOML parser 是当前唯一接受的基础依赖。
|
||||
4. **两级扩展。** 编译期 built-in 通过 `init()` 自注册;运行时外部插件以 stdio JSON-RPC 子进程或 MCP 兼容传输接入。
|
||||
5. **接口优先、registry 驱动。** `Provider` 与 `Tool` 都是接口。
|
||||
6. **持续演进,不过度设计。**
|
||||
|
||||
所有代码、注释、面向用户的字符串、工具描述、system prompt 和英文规范以英语为主;README 同时维护英文版 `README.md` 与中文版 `README.zh-CN.md`。
|
||||
|
||||
## 2. 目录与依赖方向
|
||||
|
||||
```text
|
||||
reasonix/
|
||||
├── go.mod / go.sum
|
||||
├── Makefile
|
||||
├── README.md / README.zh-CN.md
|
||||
├── reasonix.example.toml
|
||||
├── docs/SPEC.md / docs/SPEC.zh-CN.md
|
||||
├── cmd/reasonix/main.go
|
||||
├── cmd/reasonix-plugin-example/
|
||||
└── internal/
|
||||
├── cli/
|
||||
├── config/
|
||||
├── provider/
|
||||
│ └── openai/
|
||||
├── tool/
|
||||
│ └── builtin/
|
||||
├── permission/
|
||||
├── command/
|
||||
├── plugin/
|
||||
├── remote/
|
||||
│ ├── forward/
|
||||
│ ├── sftpfs/
|
||||
│ └── bootstrap/
|
||||
└── agent/
|
||||
```
|
||||
|
||||
核心依赖方向保持无环:
|
||||
|
||||
```text
|
||||
cli → {agent, plugin, config} → {tool, provider}
|
||||
```
|
||||
|
||||
`provider/openai`、`tool/builtin` 等 built-in 子包导入父包完成自注册,父包不反向导入子包。Remote-SSH 采用 `cli → remote/bootstrap → remote` 的分层,`remote` 及其子包不依赖 `cli`、`agent` 或 `serve`;host key 和 secret prompt 等交互都通过 callback 暴露,供桌面端复用。
|
||||
|
||||
## 3. 核心抽象
|
||||
|
||||
### 3.1 Provider 与 registry(`internal/provider`)
|
||||
|
||||
```go
|
||||
type Provider interface {
|
||||
Name() string
|
||||
Stream(ctx context.Context, req Request) (<-chan Chunk, error)
|
||||
}
|
||||
|
||||
type Factory func(cfg Config) (Provider, error)
|
||||
|
||||
func Register(kind string, f Factory)
|
||||
func New(kind string, cfg Config) (Provider, error)
|
||||
```
|
||||
|
||||
- `openai` kind 实现 OpenAI-compatible `/chat/completions`。
|
||||
- OpenAI-compatible vendor 只是 `kind = "openai"` 的不同配置实例,通过 `base_url`、`model`、`api_key_env` 区分;新增兼容模型通常只需改配置。
|
||||
- 一个 provider 表示一个 vendor endpoint,可通过 `models` 暴露多个模型,并以 `default` 指定默认项。`default_model`、`--model` 和桌面端模型选择器都经 `Config.ResolveModel` 解析,可接受 provider 名、裸模型名或 `provider/model`。
|
||||
- `context_window` 是 provider 级默认值;`model_overrides.<model>.context_window` 可覆盖单个模型。
|
||||
- streaming tool-call delta 在 provider 内按 index 聚合,只向上层发出完整 `ToolCall`。
|
||||
|
||||
### 3.2 Tool 与 registry(`internal/tool`)
|
||||
|
||||
```go
|
||||
type Tool interface {
|
||||
Name() string
|
||||
Description() string
|
||||
Schema() json.RawMessage
|
||||
Execute(ctx context.Context, args json.RawMessage) (string, error)
|
||||
}
|
||||
```
|
||||
|
||||
- built-in tool 通过 `tool.RegisterBuiltin` 注册到进程级集合。
|
||||
- 每次运行创建独立 `*Registry`,由启用的 built-in 与插件工具组成;agent 只看到该 registry。
|
||||
- tool schema 在插入 registry 时 canonicalize;内置契约见[工具合约](./TOOL_CONTRACT.zh-CN.md),测试会校验文档与 canonical schema 不漂移。
|
||||
- `Execute` 自行解析原始 JSON 参数。错误作为结果返回给模型,让模型有机会自我修正,而不是直接终止进程。
|
||||
|
||||
### 3.3 插件与 MCP(`internal/plugin`)
|
||||
|
||||
外部插件是配置中声明的 MCP server。协议统一为 JSON-RPC 2.0,传输由 `transport` 接口抽象:
|
||||
|
||||
- `stdio`:本地持久子进程,每行一条 JSON 消息。
|
||||
- `http` / `streamable-http`:向远程 `url` POST,支持 `application/json` 和 SSE 响应,并复用 `Mcp-Session-Id`。
|
||||
- `sse`:识别旧版 2024-11-05 传输,但当前明确拒绝并提示改用 `http`。
|
||||
|
||||
`${VAR}` 与 `${VAR:-default}` 可用于 `command`、`args`、`env`、`url` 和 `headers`,使 secret 留在环境中。生命周期为 `initialize` → `notifications/initialized` → `tools/list`,调用使用 `tools/call`。
|
||||
|
||||
远程工具适配为 `Tool`,命名为 `mcp__<server>__<tool>`。`annotations.readOnlyHint` 映射为 `Tool.ReadOnly()`,默认 false;只有显式声明为只读的工具才进入并行读取与默认只读权限路径。MCP prompt 暴露为 slash command,resource 可通过 `@<server>:<uri>` 引用。
|
||||
|
||||
### 3.4 Agent loop(`internal/agent`)
|
||||
|
||||
`Session` 保存 `[]Message`。`Run(ctx, input)` 的主循环为:
|
||||
|
||||
1. 构建包含历史消息和 tool schema 的 `Request`。
|
||||
2. 调用 `provider.Stream` 并实时输出 text delta。
|
||||
3. 收集完整 tool call;若没有 tool call,则本回合结束。
|
||||
4. 执行 built-in 或 plugin tool,把结果加入会话后继续,直到完成或达到安全边界。
|
||||
|
||||
`ctx` 贯穿调用链,Ctrl-C 可以取消进行中的请求。`Agent` 与 `Coordinator` 都实现 `Runner`,因此 CLI 不需要区分单模型或双模型执行。
|
||||
|
||||
### 3.5 双模型协作(`Coordinator`)
|
||||
|
||||
当 `agent.planner_model` 与 executor 不同时,planner 与 executor 使用独立 session:
|
||||
|
||||
- planner 低频运行,只暴露经筛选的只读研究工具,生成简洁计划;
|
||||
- executor 在另一 session 中使用完整工具执行计划;
|
||||
- 两条会话互不混合,prompt prefix 都只追加增长,避免切换模型破坏 prefix cache。
|
||||
|
||||
### 3.6 上下文管理
|
||||
|
||||
Reasonix 通过低频 compaction 保持 cache-first:
|
||||
|
||||
- 低于 `agent.tool_result_snip_ratio` 时不改写历史;
|
||||
- 达到 snip ratio 后,归档并缩短较旧 tool result;
|
||||
- 达到 `agent.compact_ratio` 后,先把旧 tool result 修剪为占位符,仍超阈值才调用摘要;
|
||||
- 达到 `agent.compact_force_ratio` 后,可执行强制折叠;
|
||||
- `context_window = 0` 会关闭该实例的 compaction。
|
||||
|
||||
tool result 的 snip/prune 不删除消息,确保 assistant `tool_calls` 与 tool result 配对。摘要只折叠 assistant/tool 工作;正常大小的用户回合和既有 digest 原样保留。被移除的原文归档到 `reasonix/archive/<timestamp>.jsonl`。
|
||||
|
||||
`history` tool 支持对 session 与归档进行 BM25 搜索;`memory` tool 用于检索自动记忆,`remember` 与 `forget` 负责写入和归档。智能体发起的记忆写操作每次都需要人工确认,不能由 YOLO、自动审查或子智能体代为批准。详细约定见 `SESSION_MEMORY_RETRIEVAL.md`。
|
||||
|
||||
### 3.7 权限
|
||||
|
||||
权限层按单次 tool call 返回 `Allow`、`Ask` 或 `Deny`:
|
||||
|
||||
```go
|
||||
type Decision int
|
||||
const (Allow Decision = iota; Ask; Deny)
|
||||
|
||||
type Policy struct { Mode Decision; Allow, Ask, Deny []Rule }
|
||||
func (p Policy) Decide(toolName string, readOnly bool, args json.RawMessage) Decision
|
||||
```
|
||||
|
||||
- rule 可以是 `Tool` 或 `Tool(specifier)`,例如 `Bash(go test:*)`、`Edit(docs/**)`。
|
||||
- 优先级为 `deny > ask > allow > fallback`;只读工具 fallback 为 Allow,写工具 fallback 使用 `Mode`。
|
||||
- 交互模式中的 Ask 由用户选择单次允许、session scope 允许、持久允许或拒绝;显式 Deny 在所有模式下都不可绕过。
|
||||
- MCP 可设置 `auto|prompt|writes|approve`。标记 `destructiveHint: true` 的调用在 `auto`、`prompt` 或 `writes` 下每次都需要人工重新确认。
|
||||
- Plan 是协作流程,不等于全工具只读。普通 built-in 与 Bash 仍走 Ask/Auto/YOLO 和 Sandbox;MCP 写入/破坏性目标及不受信任读取工具在规划阶段保持阻止。
|
||||
- Plan 只能由用户显式选择进入,与当前工具审批姿态相互独立;普通聊天不会自动切换到 Plan。Auto/YOLO 不会回答 `ask`,也不会替用户批准 `exit_plan_mode`,获批计划的短期自动执行窗口也不会自动批准后续计划。
|
||||
- 桌面端协作模式分为 `normal`、`plan` 和 `goal`。Goal 会持续推进目标,直到完成、同一阻塞状态重复三次、用户停止或达到安全续跑边界。只有用户在输入框中选择 Goal 或运行 `/goal` 显式启动后,长周期研究、调试、优化或实现目标才可启用 AutoResearch;普通聊天不会隐式切换协作模式,也不会创建持久化 AutoResearch 状态。动态状态保存在 `.reasonix/autoresearch/.../`。
|
||||
|
||||
### 3.8 Slash command
|
||||
|
||||
Slash command 分为三类:
|
||||
|
||||
- built-in action:`/compact`、`/new`、`/clear`、`/effort`、`/mcp`、`/help`;
|
||||
- `.reasonix/commands/*.md` 与用户配置目录中的自定义命令;
|
||||
- MCP prompt:`/mcp__<server>__<prompt>`。
|
||||
|
||||
自定义命令支持简单 frontmatter、`$ARGUMENTS`、`$1…$N` 和 `$$`。加载失败的单个命令会被跳过,不应使应用整体退出。
|
||||
|
||||
Bubble Tea TUI 的 modal overlay 必须隐藏 composer;slash/`@` autocomplete 等 input-owned overlay 保留 composer。新增 overlay 时必须更新 `chat_tui.hideComposer()` 与 layout test。
|
||||
|
||||
### 3.9 `@` 引用
|
||||
|
||||
- `@<server>:<uri>` 读取 MCP resource;
|
||||
- `@<path>` 仅在本地路径真实存在时读取文件或目录,普通 `@mention` 与邮箱保持原文本;
|
||||
- 文件内容有大小限制,binary 只标记不展开;目录按深度优先列出并跳过 `.git`、`node_modules` 等噪音;
|
||||
- 解析异步进行,失败显示 notice 但不阻止本回合;
|
||||
- autocomplete 每次只读取一层目录,避免在大型目录中递归遍历。
|
||||
|
||||
### 3.10 子智能体 Profile
|
||||
|
||||
子智能体 Profile 是带 `runAs: subagent` 的 Skill。桌面端和 CLI 只允许修改简单、手动调用的 project/global profile;包含 `references/`、`scripts/` 或非托管 frontmatter 的丰富 Skill 不会被编辑器扁平化覆盖。
|
||||
|
||||
`reasonix subagent try` 使用只读 Skill runner;`reasonix subagent run` 使用常规权限与 Sandbox。`task` 支持 `profile`、`model`、`effort` 和 `write_paths`;`fleet` 在 session scheduler 上并发调度多个任务。详见[子智能体 Profile](./SUBAGENT_PROFILES.zh-CN.md)。
|
||||
|
||||
## 4. 数据类型
|
||||
|
||||
provider 层的核心类型包括 `Role`、`Message`、`ToolCall`、`ToolSchema`、`Request` 和 streaming `Chunk`。`Message` 保留 `tool_calls`、`tool_call_id` 与 `name`;`Chunk` 区分 text、tool call、done 和 error。字段定义以英文规范及 `internal/provider` 源码为准。
|
||||
|
||||
## 5. 配置
|
||||
|
||||
配置优先级:
|
||||
|
||||
```text
|
||||
flag > ./reasonix.toml > 用户 config.toml > 内置默认值
|
||||
```
|
||||
|
||||
从 v1.8.1 起,用户配置位于 macOS/Linux 的 `~/.reasonix/config.toml` 或 Windows 的 `%AppData%\reasonix\config.toml`。provider key 保存在 Reasonix home 的 `.env`;项目 `.env` 只用于 workspace 范围的非 provider 变量展开。完整路径见[配置路径](./CONFIG_PATHS.zh-CN.md)。
|
||||
|
||||
```toml
|
||||
default_model = "deepseek"
|
||||
|
||||
[agent]
|
||||
temperature = 0.0
|
||||
reasoning_language = "auto"
|
||||
|
||||
[[providers]]
|
||||
name = "deepseek"
|
||||
kind = "openai"
|
||||
base_url = "https://api.deepseek.com"
|
||||
models = ["deepseek-v4-flash", "deepseek-v4-pro"]
|
||||
default = "deepseek-v4-flash"
|
||||
api_key_env = "DEEPSEEK_API_KEY"
|
||||
context_window = 1000000
|
||||
|
||||
[tools]
|
||||
enabled = []
|
||||
bash_timeout_seconds = 120
|
||||
mcp_call_timeout_seconds = 300
|
||||
|
||||
[permissions]
|
||||
mode = "ask"
|
||||
deny = ["Bash(rm -rf*)", "Bash(git push*)"]
|
||||
allow = ["Bash(go test:*)", "Bash(git status:*)"]
|
||||
|
||||
[sandbox]
|
||||
# workspace_root = ""
|
||||
# allow_write = ["/tmp"]
|
||||
# forbid_read = ["${HOME}/.ssh"]
|
||||
|
||||
[serve]
|
||||
auth_mode = "none"
|
||||
```
|
||||
|
||||
`[sandbox]` 是权限策略之下的强制执行层。file writer 默认限制在 workspace root、Reasonix 用户配置目录和 `allow_write`;`forbid_read` 可阻止读取敏感路径。macOS 使用 Seatbelt,Linux 使用 bubblewrap;若声明 enforce 但平台 backend 不可用,Bash 应拒绝执行而不是静默降级。Windows 当前没有 OS 级 Bash sandbox,file tool 的路径限制仍然生效。
|
||||
|
||||
`[serve]` 控制 `reasonix serve` 的 browser frontend。默认 `auth_mode = "none"` 仅适合 loopback;暴露到其他机器时必须使用 token 或 password。只有位于可信 reverse proxy 后方时才能启用 `behind_proxy`。
|
||||
|
||||
项目根目录的 `.mcp.json` 可使用 Claude Code 的 `mcpServers` schema;与 `reasonix.toml` 同名时,以后者为准。
|
||||
|
||||
## 6. 错误处理
|
||||
|
||||
- library code 使用 `fmt.Errorf("...: %w", err)` 包装并返回错误,不打印也不调用 `os.Exit`;
|
||||
- 只有 `cli` / `main` 决定 exit code 和面向用户的信息;
|
||||
- tool error 返回给模型,不直接终止 agent loop;
|
||||
- network layer 应对 429 / 5xx 使用有界指数退避。
|
||||
|
||||
## 7. 代码风格
|
||||
|
||||
- `gofmt`、`go vet` 必须通过;
|
||||
- package name 使用小写,exported identifier 必须有文档;
|
||||
- 注释解释“为什么”,而不只是复述“做了什么”;
|
||||
- 避免过早抽象,优先清晰直接的实现。
|
||||
|
||||
## 8. 分发
|
||||
|
||||
- 构建:`CGO_ENABLED=0 go build -ldflags "-s -w -X main.version=$(VERSION)" -o reasonix ./cmd/reasonix`
|
||||
- 目标矩阵:`darwin|linux|windows × amd64|arm64`
|
||||
- 版本通过 ldflags 注入,来源为 `git describe --tags --always`
|
||||
- 支持预编译二进制、`go install` 与 Homebrew。
|
||||
|
||||
## 9. 路线图(当前范围之外)
|
||||
|
||||
- 完成 Sandbox Phase 1 的 escape prompt:检测 sandbox 不可用或拒绝时,提供一次明确、受权限控制的非 sandbox 重试。
|
||||
- MCP long tail:OAuth 2.0、`headersHelper`、更多 `.mcp.json` scope、tool-search 延迟加载、`list_changed`、channel、elicitation、root,以及可提供 provider 的插件。
|
||||
- 增加 Anthropic-native provider kind,用于验证 registry 不依赖单一 wire format,并支持原生 prompt cache control。
|
||||
- 把“始终允许”规则持久化到项目配置,以及为 `reasonix run` 提供 session 级权限覆盖。
|
||||
@@ -6,6 +6,9 @@ import community from '../data/community.json';
|
||||
const base = import.meta.env.BASE_URL.replace(/\/$/, '');
|
||||
const R2_LATEST = 'https://dl.reasonix.io/latest';
|
||||
const repo = 'https://github.com/esengine/DeepSeek-Reasonix';
|
||||
const vscodeMarketplace = 'https://marketplace.visualstudio.com/items?itemName=SivanLiu.reasonix-agent';
|
||||
const openVsx = 'https://open-vsx.org/extension/SivanLiu/reasonix-agent';
|
||||
const vscodeExtensionRepo = 'https://github.com/SivanCola/reasonix-vscode';
|
||||
|
||||
let desktopVersion = 'v1.1.0';
|
||||
let goVer = '1.1.0';
|
||||
@@ -76,7 +79,32 @@ const ld = {
|
||||
<span class="install"><span class="ps1">$</span>npm i -g reasonix<button data-copy="npm i -g reasonix">Copy</button></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="also reveal" style="--d:0.22s"><span class="l-en">Prefer package managers? Use <a href="#start" data-goto="brew">Homebrew</a>. Need a local browser UI? Run <code>reasonix serve</code>. Integrating an editor? Start <code>reasonix acp</code> and read the <a href={`${base}/docs/#acp`}>ACP guide</a>.</span><span class="l-zh">偏好包管理器? 可用 <a href="#start" data-goto="brew">Homebrew</a>。需要本地浏览器 UI? 运行 <code>reasonix serve</code>。接入编辑器时启动 <code>reasonix acp</code>,并查看 <a href={`${base}/docs/#acp`}>ACP 指南</a>。</span></div>
|
||||
<nav class="also reveal" style="--d:0.22s" aria-label="More ways to use Reasonix / 更多使用方式">
|
||||
<span class="l-en also-row">
|
||||
<strong class="also-label">More ways to use Reasonix:</strong>
|
||||
<span class="also-links">
|
||||
<a href="?download=vscode#start" data-goto="vscode">Editor extension</a>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<a href="#start" data-goto="brew">Homebrew</a>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<span>Local Web UI: <code>reasonix serve</code></span>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<a href={`${base}/docs/#acp`}>ACP editor integration</a>
|
||||
</span>
|
||||
</span>
|
||||
<span class="l-zh also-row">
|
||||
<strong class="also-label">更多使用方式:</strong>
|
||||
<span class="also-links">
|
||||
<a href="?download=vscode#start" data-goto="vscode">编辑器扩展</a>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<a href="#start" data-goto="brew">Homebrew</a>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<span>本地 Web UI:<code>reasonix serve</code></span>
|
||||
<span class="also-sep" aria-hidden="true">·</span>
|
||||
<a href={`${base}/docs/#acp`}>ACP 编辑器接入</a>
|
||||
</span>
|
||||
</span>
|
||||
</nav>
|
||||
|
||||
<div class="term-stage reveal" style="--d:0.26s">
|
||||
<div class="fig"><span class="l-en">fig. 01 — a live session, cache still warm</span><span class="l-zh">图 01 —— 一场实时会话,缓存依然温热</span></div>
|
||||
@@ -127,7 +155,7 @@ const ld = {
|
||||
<div class="feat reveal" style="--d:0.1s">
|
||||
<span class="tag">06 / cli + web + acp</span>
|
||||
<h3><span class="l-en">Terminal, browser, or editor</span><span class="l-zh">终端、浏览器或编辑器</span></h3>
|
||||
<p><span class="l-en">Use the full-screen TUI, run <code>reasonix serve</code> for a local browser UI, or launch <code>reasonix acp</code> from an ACP-compatible editor. Every surface uses the same local engine.</span><span class="l-zh">使用全屏 TUI、通过 <code>reasonix serve</code> 打开本地浏览器 UI,或从兼容 ACP 的编辑器启动 <code>reasonix acp</code>;所有入口都使用同一套本地引擎。</span></p>
|
||||
<p><span class="l-en">Use the full-screen TUI, run <code>reasonix serve</code> for a local browser UI, <a href="?download=vscode#start" data-goto="vscode">install the Reasonix VS Code extension</a>, or connect another ACP-compatible editor through <code>reasonix acp</code>. Every surface uses the same local engine.</span><span class="l-zh">使用全屏 TUI、通过 <code>reasonix serve</code> 打开本地浏览器 UI、<a href="?download=vscode#start" data-goto="vscode">安装 Reasonix VS Code 扩展</a>,或通过 <code>reasonix acp</code> 连接其他兼容 ACP 的编辑器;所有入口都使用同一套本地引擎。</span></p>
|
||||
<code class="feat-chip">$ reasonix acp</code>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,6 +280,7 @@ const ld = {
|
||||
<button class="dl-tab active" type="button" data-pane="desktop" role="tab"><span class="l-en">Desktop</span><span class="l-zh">桌面端</span></button>
|
||||
<button class="dl-tab" type="button" data-pane="npm" role="tab">npm</button>
|
||||
<button class="dl-tab" type="button" data-pane="brew" role="tab">Homebrew</button>
|
||||
<button class="dl-tab" type="button" data-pane="vscode" role="tab"><span class="l-en">Editor extension</span><span class="l-zh">编辑器扩展</span></button>
|
||||
</div>
|
||||
|
||||
<div class="dl-pane active" data-pane="desktop">
|
||||
@@ -294,6 +323,23 @@ const ld = {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dl-pane" data-pane="vscode">
|
||||
<div class="os-grid editor-grid">
|
||||
<div class="os-card editor-card editor-card--primary">
|
||||
<span class="os-chip"><span class="l-en">recommended</span><span class="l-zh">推荐</span></span>
|
||||
<h4>Visual Studio Marketplace</h4>
|
||||
<span class="meta"><span class="l-en">For Microsoft Visual Studio Code</span><span class="l-zh">适用于微软 Visual Studio Code</span></span>
|
||||
<a class="btn btn-dark" href={vscodeMarketplace} target="_blank" rel="noreferrer"><span class="l-en">Install extension</span><span class="l-zh">安装扩展</span></a>
|
||||
</div>
|
||||
<div class="os-card editor-card">
|
||||
<h4>Open VSX Registry</h4>
|
||||
<span class="meta"><span class="l-en">For VSCodium, Eclipse Theia, and compatible editors</span><span class="l-zh">适用于 VSCodium、Eclipse Theia 及兼容编辑器</span></span>
|
||||
<a class="btn btn-light" href={openVsx} target="_blank" rel="noreferrer"><span class="l-en">Install from Open VSX</span><span class="l-zh">从 Open VSX 安装</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dl-note editor-note"><span class="l-en">Extension ID <code>SivanLiu.reasonix-agent</code> · requires Reasonix 1.0+ installed and configured locally · the extension connects to <code>reasonix acp</code> and does not bundle the CLI · <a href={vscodeExtensionRepo}>source code →</a></span><span class="l-zh">扩展 ID <code>SivanLiu.reasonix-agent</code> · 需要先在本机安装并配置 Reasonix 1.0+ · 扩展连接 <code>reasonix acp</code>,不内置 CLI · <a href={vscodeExtensionRepo}>查看源码 →</a></span></div>
|
||||
</div>
|
||||
|
||||
<div class="dl-pane" data-pane="npm">
|
||||
<span class="install"><span class="ps1">$</span>npm i -g reasonix<button data-copy="npm i -g reasonix">Copy</button></span>
|
||||
<div class="chan">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const DOWNLOAD_PANES = new Set(["npm", "brew", "desktop"]);
|
||||
const DOWNLOAD_PANES = new Set(["npm", "brew", "desktop", "vscode"]);
|
||||
|
||||
// Return the requested install pane only for the homepage download section.
|
||||
// Plain #start links keep the default npm pane; updater links opt into desktop.
|
||||
// Plain #start links keep the rendered default pane; query links opt into one.
|
||||
export function downloadPaneFromURL(input, base = "https://reasonix.io/") {
|
||||
let url;
|
||||
try {
|
||||
|
||||
@@ -14,6 +14,7 @@ test("plain install links preserve the default pane", () => {
|
||||
test("recognized download panes are strict", () => {
|
||||
assert.equal(downloadPaneFromURL("/?download=brew#start"), "brew");
|
||||
assert.equal(downloadPaneFromURL("/?download=npm#start"), "npm");
|
||||
assert.equal(downloadPaneFromURL("/?download=vscode#start"), "vscode");
|
||||
assert.equal(downloadPaneFromURL("/?download=DESKTOP#start"), "");
|
||||
assert.equal(downloadPaneFromURL("/?download=unknown#start"), "");
|
||||
assert.equal(downloadPaneFromURL("not a url", "not a base"), "");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
|
||||
const source = (path) => readFile(new URL(path, import.meta.url), "utf8");
|
||||
|
||||
test("homepage presents one VS Code extension through both registries", async () => {
|
||||
const page = await source("../pages/index.astro");
|
||||
|
||||
assert.match(page, /data-pane="vscode"/);
|
||||
assert.match(page, /data-pane="desktop"[\s\S]*data-pane="npm"[\s\S]*data-pane="brew"[\s\S]*data-pane="vscode"/);
|
||||
assert.match(page, /Editor extension[\s\S]*编辑器扩展/);
|
||||
assert.match(page, /More ways to use Reasonix:[\s\S]*更多使用方式:/);
|
||||
assert.match(page, /Local Web UI:[\s\S]*reasonix serve[\s\S]*本地 Web UI:/);
|
||||
assert.match(page, /ACP editor integration[\s\S]*ACP 编辑器接入/);
|
||||
assert.match(page, /SivanLiu\.reasonix-agent/);
|
||||
assert.match(page, /marketplace\.visualstudio\.com\/items\?itemName=SivanLiu\.reasonix-agent/);
|
||||
assert.match(page, /open-vsx\.org\/extension\/SivanLiu\/reasonix-agent/);
|
||||
assert.match(page, /does not bundle the CLI/);
|
||||
assert.match(page, /data-goto="vscode"/);
|
||||
});
|
||||
|
||||
test("mobile download channels use a two-column tab grid", async () => {
|
||||
const css = await source("../styles/global.css");
|
||||
const mobile = css.slice(css.indexOf("@media (max-width: 640px)"), css.indexOf("@media (max-width: 360px)"));
|
||||
|
||||
assert.match(mobile, /\.dl-tabs \{\s*display: grid; grid-template-columns: repeat\(2, minmax\(0, 1fr\)\)/);
|
||||
});
|
||||
@@ -231,9 +231,22 @@ body[data-lang="zh"] .hero h1 { font-size: clamp(42px, 5.6vw, 72px); line-height
|
||||
}
|
||||
.install button.copied { background: oklch(0.55 0.14 155); color: #fff; }
|
||||
|
||||
.also { margin-top: 22px; font-size: 14px; color: var(--ink-3); }
|
||||
.also a { color: var(--accent); text-decoration: none; font-weight: 500; }
|
||||
.also a:hover { text-decoration: underline; }
|
||||
.also {
|
||||
max-width: 940px; margin: 22px auto 0;
|
||||
font-size: 14px; line-height: 1.8; color: var(--ink-2);
|
||||
}
|
||||
.also-row { display: flex; align-items: baseline; justify-content: center; gap: 12px; }
|
||||
.also-label { flex: none; color: var(--ink); font-weight: 600; }
|
||||
.also-links { display: flex; align-items: baseline; justify-content: center; gap: 0 11px; flex-wrap: wrap; }
|
||||
.also-sep { color: var(--ink-3); }
|
||||
.also code { color: var(--ink-2); font-size: 0.92em; }
|
||||
.also a {
|
||||
color: var(--accent); font-weight: 500;
|
||||
text-decoration: underline; text-decoration-color: color-mix(in oklch, var(--accent) 38%, transparent);
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
.also a:hover { text-decoration-color: currentColor; }
|
||||
.also a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }
|
||||
|
||||
/* 404 — CTA row + "gone cold" cache blocks */
|
||||
.hero-cta { margin-top: 38px; display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }
|
||||
@@ -610,6 +623,15 @@ body.how-flat .how-stage { position: static; min-height: 0; display: block; }
|
||||
}
|
||||
.os-card .alt a { color: var(--accent); text-decoration: none; font-weight: 500; }
|
||||
.os-card .alt a:hover { text-decoration: underline; }
|
||||
.editor-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 760px; }
|
||||
.editor-card { min-height: 190px; }
|
||||
.editor-card--primary {
|
||||
background: linear-gradient(180deg, color-mix(in oklch, var(--accent) 10%, var(--card)), var(--card) 82%);
|
||||
border: 1px solid color-mix(in oklch, var(--accent) 24%, var(--line));
|
||||
}
|
||||
.editor-card .btn { margin-top: auto; align-self: flex-start; }
|
||||
.editor-note { max-width: 820px; margin-inline: auto; line-height: 1.65; }
|
||||
.editor-note code { font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); }
|
||||
.btn-light { background: var(--accent-soft); color: var(--accent); }
|
||||
.btn-light:hover { background: color-mix(in oklch, var(--accent) 16%, var(--bg)); }
|
||||
.dl-help {
|
||||
@@ -942,6 +964,10 @@ footer { background: var(--bg); border-top: 1px solid var(--line); margin-top: 0
|
||||
.theme-switch button { padding: 6px 9px; }
|
||||
.docs-path-grid { grid-template-columns: 1fr; }
|
||||
.docs-main h1 { font-size: 34px; }
|
||||
.dl-tabs {
|
||||
display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
width: 100%; max-width: 360px; border-radius: var(--radius-sm);
|
||||
}
|
||||
.hero-install { --hero-action-width: 100%; }
|
||||
.install-option { padding: 18px; }
|
||||
.hero-install .install {
|
||||
@@ -951,6 +977,8 @@ footer { background: var(--bg); border-top: 1px solid var(--line); margin-top: 0
|
||||
border-radius: 24px;
|
||||
}
|
||||
.hero-install .install button { flex-basis: 100%; }
|
||||
.also-row { align-items: center; flex-direction: column; gap: 4px; }
|
||||
.also-links { gap: 0 8px; }
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
|
||||
Reference in new issue
Block a user