mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 02:36:01 -10:00
docs: the references and code the deletion commit left behind
68b031ae5was pushed with only its deletions and renames staged. Its `git add` named CHANGELOG.md, which was already removed, and the failed pathspec skipped every modification after it. That commit alone does not build: - productdocs still imports reasonix/release-notes; - repolint still calls checkSpecParity; - the extension golden test reads the old fixture path. This commit carries the changes68b031ae5describes: productdocs and docs-manifest without the release catalog, repolint without spec-parity, the golden test on testdata, the /docs tests, the link fixes, ci.yml, CODEOWNERS, the standard, the theme generator and the lowered baseline. Verified locally on this exact tree before68b031ae5was pushed: go test ./... passes and make lint is clean.
This commit is contained in:
1 parent
68b031ae5d
commit
99c5360fd0
24 files changed
+130
-585
No files matched your search
@@ -14,13 +14,11 @@
|
||||
/README.md @SivanCola @esengine
|
||||
/README.zh-CN.md @SivanCola @esengine
|
||||
/SECURITY.md @SivanCola @esengine
|
||||
/CHANGELOG.md @SivanCola @esengine
|
||||
|
||||
# Contracts and processes the Studio line runs on.
|
||||
/docs/DOCS_STANDARD.md @esengine @SivanCola
|
||||
/docs/STUDIO_*.md @esengine @SivanCola
|
||||
/docs/SESSION_MEMORY_RETRIEVAL.md @esengine @SivanCola
|
||||
/docs/research/ @esengine @SivanCola
|
||||
/release-notes/ @esengine @SivanCola
|
||||
|
||||
# Release signing: provider policy, its contract and the workflow that uses it.
|
||||
|
||||
@@ -461,11 +461,8 @@ jobs:
|
||||
run: |
|
||||
go run github.com/rhysd/actionlint/cmd/[email protected] \
|
||||
-ignore 'label "windows-11-arm" is unknown' \
|
||||
.github/workflows/prepare-release-notes.yml \
|
||||
.github/workflows/release-studio.yml \
|
||||
.github/workflows/release-verify-issues.yml \
|
||||
.github/workflows/ci.yml
|
||||
node scripts/check-single-release-public-contract.mjs
|
||||
|
||||
# The site/ auth client has security-sensitive redirect-validation logic
|
||||
# (safeNext) covered by node:test unit tests. Those tests use only Node
|
||||
|
||||
+19
-19
@@ -9,11 +9,11 @@
|
||||
·
|
||||
<a href="./docs/GUIDE.zh-CN.md">指南</a>
|
||||
·
|
||||
<a href="./docs/ACP.zh-CN.md">ACP</a>
|
||||
<a href="./docs/ACP.md">ACP</a>
|
||||
·
|
||||
<a href="./docs/EXTENSIONS.zh-CN.md">扩展开发</a>
|
||||
<a href="./docs/EXTENSIONS.md">扩展开发</a>
|
||||
·
|
||||
<a href="./docs/SPEC.zh-CN.md">规格</a>
|
||||
<a href="./docs/SPEC.md">规格</a>
|
||||
·
|
||||
<a href="https://esengine.github.io/DeepSeek-Reasonix/">官方网站</a>
|
||||
·
|
||||
@@ -135,26 +135,26 @@ reasonix run "把 main.go 里的 TODO 实现掉"
|
||||
|
||||
CLI 进阶用法和详细配置见 **[CLI 命令参考](./docs/CLI.zh-CN.md)**、
|
||||
**[指南](./docs/GUIDE.zh-CN.md)** 和
|
||||
**[配置路径](./docs/CONFIG_PATHS.zh-CN.md)**。
|
||||
**[配置路径](./docs/CONFIG_PATHS.md)**。
|
||||
|
||||
## 文档
|
||||
|
||||
- **开始使用:** [指南](./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) ·
|
||||
[Context Engine v2](./docs/SESSION_MEMORY_RETRIEVAL.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)
|
||||
- **扩展开发:** [扩展概览](./docs/EXTENSIONS.zh-CN.md) ·
|
||||
[插件包与 Manifest v1](./docs/PLUGIN_PACKAGES.zh-CN.md) ·
|
||||
[Extension Protocol](./docs/EXTENSION_PROTOCOL.zh-CN.md) ·
|
||||
[CLI 命令参考](./docs/CLI.zh-CN.md) · [配置路径](./docs/CONFIG_PATHS.md) ·
|
||||
[ACP 编辑器接入](./docs/ACP.md)
|
||||
- **功能与排障:** [子智能体 Profile](./docs/SUBAGENT_PROFILES.md) ·
|
||||
[Context Engine v2](./docs/SESSION_MEMORY_RETRIEVAL.md) ·
|
||||
[能力诊断](./docs/CAPABILITY_DIAGNOSTICS.md) ·
|
||||
[恢复与安全模式](./docs/RECOVERY.md) ·
|
||||
[机器人使用指南](./docs/BOT_GUIDE.md) ·
|
||||
[Checkpoints 与 rewind](./docs/CHECKPOINTS.md)
|
||||
- **工程与迁移:** [规格](./docs/SPEC.md) ·
|
||||
[任务合约与暂停策略](./docs/TASK_CONTRACT.md) ·
|
||||
[工具合约](./docs/TOOL_CONTRACT.md) ·
|
||||
[从 0.x 迁移](./docs/MIGRATING.md)
|
||||
- **扩展开发:** [扩展概览](./docs/EXTENSIONS.md) ·
|
||||
[插件包与 Manifest v1](./docs/PLUGIN_PACKAGES.md) ·
|
||||
[Extension Protocol](./docs/EXTENSION_PROTOCOL.md) ·
|
||||
[Go SDK 与 starter](./sdk/go/README.md)
|
||||
|
||||
## Star 趋势
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
<a href="../README.md">README</a>
|
||||
·
|
||||
<a href="./ACP.zh-CN.md">简体中文</a>
|
||||
·
|
||||
<a href="./GUIDE.md">Guide</a>
|
||||
·
|
||||
<a href="https://agentclientprotocol.com/">ACP specification</a>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
<a href="../README.md">README</a>
|
||||
·
|
||||
<a href="./BOT_GUIDE.zh-CN.md">简体中文</a>
|
||||
·
|
||||
<a href="./GUIDE.md">General guide</a>
|
||||
|
||||
> For desktop and CLI users. This guide explains how to connect Feishu, Lark,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Capability diagnostics
|
||||
|
||||
<a href="./CAPABILITY_DIAGNOSTICS.zh-CN.md">简体中文</a>
|
||||
·
|
||||
<a href="./GUIDE.md">Guide</a>
|
||||
·
|
||||
<a href="./PLUGIN_PACKAGES.md">Plugin packages</a>
|
||||
|
||||
+4
-4
@@ -412,10 +412,10 @@ reasonix doctor catalogs [--json]
|
||||
reasonix catalogs reindex history [--dir PATH ...] [--json]
|
||||
```
|
||||
|
||||
详见 [历史搜索 Catalog](./HISTORY_SEARCH_CATALOG.zh-CN.md)。
|
||||
详见 [历史搜索 Catalog](./HISTORY_SEARCH_CATALOG.md)。
|
||||
用量统计使用独立的可丢弃 rollup 投影:
|
||||
reasonix catalogs reindex usage [--json]
|
||||
详见 [用量 Catalog](./USAGE_CATALOG.zh-CN.md)。
|
||||
详见 [用量 Catalog](./USAGE_CATALOG.md)。
|
||||
|
||||
### 记忆诊断与恢复
|
||||
|
||||
@@ -435,7 +435,7 @@ reasonix catalogs reindex usage [--json]
|
||||
这些命令始终作用于当前 session controller。当会话位于远端主机上(`reasonix remote
|
||||
connect` 或桌面的远程网页窗口)时,它们使用远程 memory catalog,绝不回退读取桌面本机
|
||||
记忆。权限、自动召回、写入确认和迁移行为见
|
||||
[Context Engine v2](./SESSION_MEMORY_RETRIEVAL.zh-CN.md)。
|
||||
[Context Engine v2](./SESSION_MEMORY_RETRIEVAL.md)。
|
||||
|
||||
|
||||
用量统计使用独立的可丢弃 rollup 投影:
|
||||
@@ -447,7 +447,7 @@ reasonix catalogs reindex usage [--json]
|
||||
|
||||
```
|
||||
|
||||
详见 [用量 Catalog](./USAGE_CATALOG.zh-CN.md)。
|
||||
详见 [用量 Catalog](./USAGE_CATALOG.md)。
|
||||
|
||||
### 记忆诊断与恢复
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Windows and Linux Desktop crash diagnostics runbook
|
||||
|
||||
<a href="./DESKTOP_CRASH_DIAGNOSTICS_RUNBOOK.zh-CN.md">简体中文</a>
|
||||
|
||||
This is the release, privacy, performance, and root-cause checklist for the
|
||||
cross-platform Desktop diagnostics pipeline. Windows build `17763` remains a
|
||||
priority experiment, not a code whitelist. A diagnostic release does not by
|
||||
|
||||
@@ -24,8 +24,8 @@ Current areas:
|
||||
| Area | Paths | Primary | Backup |
|
||||
| --- | --- | --- | --- |
|
||||
| Kernel, Studio shell, tooling, standing instructions | `*` | @esengine | @SivanCola |
|
||||
| User guides and references | `docs/`, `sdk/`, `README*`, `SECURITY.md`, `CHANGELOG.md` | @SivanCola | @esengine |
|
||||
| Studio contracts and processes | `docs/STUDIO_*.md`, `docs/DOCS_STANDARD.md`, `docs/research/` | @esengine | @SivanCola |
|
||||
| User guides and references | `docs/`, `sdk/`, `README*`, `SECURITY.md` | @SivanCola | @esengine |
|
||||
| Studio contracts and processes | `docs/STUDIO_*.md`, `docs/DOCS_STANDARD.md` | @esengine | @SivanCola |
|
||||
| Release notes and release signing | `release-notes/`, `.signpath/`, `release-studio.yml` | @esengine | @SivanCola |
|
||||
|
||||
## 2. Document classes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Extension Runtime v2 (Spatiotemporal Composability)
|
||||
|
||||
English overview of the Reasonix plugin/runtime v2 model. Chinese: [EXTENSION_RUNTIME_V2.zh-CN.md](./EXTENSION_RUNTIME_V2.zh-CN.md).
|
||||
English overview of the Reasonix plugin/runtime v2 model.
|
||||
|
||||
## Protocol and manifest
|
||||
|
||||
|
||||
+12
-19
@@ -584,8 +584,7 @@ events.
|
||||
|
||||
The injected hook context is dynamic current-turn context. It does not change
|
||||
the stable system prompt, memory prefix, or tool schema, though dynamic content
|
||||
can still reduce cache reuse for that turn. The detailed desktop hook schema and
|
||||
loading model are documented in [the Chinese desktop hooks guide](./DESKTOP_HOOKS.zh-CN.md).
|
||||
can still reduce cache reuse for that turn.
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
@@ -1190,32 +1189,26 @@ MCP prompts also appear here as `/mcp__<server>__<prompt>`.
|
||||
|
||||
## Embedded documentation retrieval
|
||||
|
||||
Reasonix bundles the Markdown files from `docs/` and the reviewed
|
||||
`release-notes/releases.json` catalog into each CLI and Desktop build. The
|
||||
read-only `docs` tool searches that exact offline corpus with local BM25
|
||||
retrieval and can read a complete matching section with source provenance. It
|
||||
renders every release in both languages under paths such as
|
||||
`changelog/v1.19.5.md` and `changelog/v1.19.5.zh-CN.md`, so questions about a
|
||||
specific version, upgrades, fixes, or known risks work offline. The agent should
|
||||
use the tool before web search or assumptions when a question concerns Reasonix
|
||||
configuration, CLI/Desktop behavior, release history, permissions, MCP, memory,
|
||||
Reasonix bundles the Markdown files from `docs/` into each CLI and Desktop
|
||||
build. The read-only `docs` tool searches that exact offline corpus with local
|
||||
BM25 retrieval and can read a complete matching section with source provenance.
|
||||
The agent should use the tool before web search or assumptions when a question
|
||||
concerns Reasonix configuration, CLI/Desktop behavior, permissions, MCP, memory,
|
||||
recovery, providers, or maintainer workflows.
|
||||
|
||||
No setup, network connection, vector database, or embedding service is needed.
|
||||
Search results prefer the query language while retaining explicit `en`,
|
||||
`zh-CN`, audience, and catalog filters. Balanced and Delivery profiles expose the
|
||||
tool directly; Economy connects the `docs` source on demand. Every result reports
|
||||
the product version, immutable source revision, and corpus SHA-256 digest. Release
|
||||
CI compiles the CLI and rejects publication unless that embedded manifest matches
|
||||
the candidate's `docs/*.md`, `release-notes/releases.json`, and build identity. A
|
||||
newer online `main-v2` page therefore cannot silently replace version-matched
|
||||
local guidance or release history.
|
||||
the product version, immutable source revision, and corpus SHA-256 digest. The
|
||||
embedded manifest is bound to the candidate's `docs/*.md` and build identity, so
|
||||
an online page cannot silently replace version-matched local guidance.
|
||||
|
||||
Use `/docs` to inspect the bundled corpus identity and usage examples without
|
||||
calling a model. Use `/docs <question>` (for example,
|
||||
`/docs 1.19.5 changelog`) to make Reasonix search the corpus locally first and
|
||||
then pass the version-matched evidence to the currently configured AI for a
|
||||
sourced answer. This command path does not depend on the model deciding to call
|
||||
`/docs how to configure an MCP server`) to make Reasonix search the corpus
|
||||
locally first and then pass the matched sections to the currently configured AI
|
||||
for a sourced answer. This command path does not depend on the model deciding to call
|
||||
the `docs` tool, while ordinary natural-language questions may still use the
|
||||
tool automatically. Existing custom commands and compatible plugin or skill
|
||||
aliases keep ownership of `/docs`; when that happens, CLI and Desktop normally
|
||||
|
||||
+24
-33
@@ -12,15 +12,14 @@
|
||||
## 目录
|
||||
|
||||
- [配置](#配置)
|
||||
- [计费与展示币种](./BILLING.zh-CN.md)
|
||||
- [计费与展示币种](./BILLING.md)
|
||||
- [CLI 命令参考](./CLI.zh-CN.md)
|
||||
- [环境变量](#环境变量)
|
||||
- [Web 前端](#web-前端)
|
||||
- [配置路径](./CONFIG_PATHS.zh-CN.md)
|
||||
- [思考语言](./REASONING_LANGUAGE.zh-CN.md)
|
||||
- [任务合约与暂停策略](./TASK_CONTRACT.zh-CN.md)
|
||||
- [配置路径](./CONFIG_PATHS.md)
|
||||
- [思考语言](./REASONING_LANGUAGE.md)
|
||||
- [任务合约与暂停策略](./TASK_CONTRACT.md)
|
||||
- [自定义 OpenAI-compatible provider](#自定义-openai-compatible-provider)
|
||||
- [桌面端 Hooks](./DESKTOP_HOOKS.zh-CN.md)
|
||||
- [快捷键](#快捷键)
|
||||
- [权限与沙盒](#权限与沙盒)
|
||||
- [能力诊断](#能力诊断)
|
||||
@@ -35,13 +34,12 @@
|
||||
优先级:**flag > `./reasonix.toml` > 用户配置文件 > 内置默认值**。从
|
||||
**Reasonix v1.8.1** 开始,用户配置位于 macOS/Linux 的
|
||||
`~/.reasonix/config.toml`,Windows 为 `%AppData%\reasonix\config.toml`;迁移和相关数据路径见
|
||||
[配置路径](./CONFIG_PATHS.zh-CN.md)。标注为“仅用户/全局”的字段(包括 agent 轮数上限)不会被 `./reasonix.toml` 覆盖。
|
||||
[配置路径](./CONFIG_PATHS.md)。标注为“仅用户/全局”的字段(包括 agent 轮数上限)不会被 `./reasonix.toml` 覆盖。
|
||||
Provider 通过 `api_key_env` 命名密钥,真实密钥值保存在 CLI 与桌面端共用的
|
||||
Reasonix 全局 `<Reasonix home>/.env`。项目 `.env`、home `.env`、继承的 shell 环境变量、旧 credentials 和系统 keyring 都不再作为 provider key 的运行时 fallback;旧凭据只作为迁移来源读取。项目 `.env` 仍会作为当前 workspace 范围内的 MCP/plugin 非 provider `${VAR}` 展开来源,但不会导入 provider key 或 Reasonix 控制变量。全局 `config.toml` 和 `.env` 的完整结构见
|
||||
[配置路径](./CONFIG_PATHS.zh-CN.md)。
|
||||
[配置路径](./CONFIG_PATHS.md)。
|
||||
|
||||
桌面端和 CLI 端的可见思考语言设置,见 [思考语言](./REASONING_LANGUAGE.zh-CN.md)。
|
||||
桌面端 Hooks 的 JSON 配置、事件 key 和 payload 字段,见 [桌面端 Hooks](./DESKTOP_HOOKS.zh-CN.md)。
|
||||
桌面端和 CLI 端的可见思考语言设置,见 [思考语言](./REASONING_LANGUAGE.md)。
|
||||
`SessionStart` hook 可通过 stdout 或 `hookSpecificOutput.additionalContext` 把插件/工作流 bootstrap 内容一次性注入下一轮真实用户输入上下文,而不是写入稳定 system prompt。
|
||||
插件包可通过 `hooks/session-start-codex` 或插件根目录 `CLAUDE.md` 提供该启动上下文;Claude 风格 `.claude/settings.json` command hooks 也会按同名事件映射到 Reasonix hooks。
|
||||
|
||||
@@ -255,7 +253,7 @@ Goal、由 `todo_write` 工具驱动的实时 Todo 面板、扩展发布的 stat
|
||||
## 通过 ACP 接入编辑器
|
||||
|
||||
`reasonix acp` 把 Reasonix 作为 ACP v1 stdio agent 提供给编辑器和其他 host 客户端。
|
||||
独立的 **[ACP 编辑器接入](./ACP.zh-CN.md)** 文档集中说明启动方式、能力协商、会话生命周期、
|
||||
独立的 **[ACP 编辑器接入](./ACP.md)** 文档集中说明启动方式、能力协商、会话生命周期、
|
||||
彼此独立的模型/工作/协作/审批控制轴、客户端文件与 terminal 能力、MCP server、权限请求,
|
||||
以及 Reasonix 的回合中引导扩展。
|
||||
|
||||
@@ -573,7 +571,7 @@ CLI/TUI 文本输入可通过 `[ui].cursor_shape` 设置光标形状,支持 `u
|
||||
| `Ctrl+O` | 切换详细 reasoning 显示 | 也可通过 `/verbose` 使用。 |
|
||||
| `Ctrl+B` | 展开或收起较长 shell 输出 | 较长 shell 输出的提示行也可点击;全屏 TUI 开启鼠标接管时,文本选区由应用内处理。 |
|
||||
| `/goal <目标>`、`/goal status`、`/goal pause`、`/goal resume`、`/goal clear` | 启动、查看、暂停、恢复或清除 Goal | Goal 默认持续执行;只有用户显式预算会按数字暂停。 |
|
||||
| `/migrate`、`/migrate --from <旧目录>` | 重试旧数据迁移,或从指定 v0.x 来源导入 sessions | Windows v0.52 自定义安装/数据目录用 `--from`;该形式只导入 sessions。详见[配置路径](./CONFIG_PATHS.zh-CN.md)。 |
|
||||
| `/migrate`、`/migrate --from <旧目录>` | 重试旧数据迁移,或从指定 v0.x 来源导入 sessions | Windows v0.52 自定义安装/数据目录用 `--from`;该形式只导入 sessions。详见[配置路径](./CONFIG_PATHS.md)。 |
|
||||
|
||||
选择器与审批:
|
||||
|
||||
@@ -670,7 +668,7 @@ compaction 摘要数,以及可用时的桌面端 token/cache telemetry。结
|
||||
## 能力诊断
|
||||
|
||||
当 skill、斜杠命令、Hook、插件包、MCP 或 `AGENTS.md` 缺失、被覆盖或启动失败时,用统一只读诊断。完整参数、JSON schema 与 issue code 见
|
||||
**[能力诊断](./CAPABILITY_DIAGNOSTICS.zh-CN.md)**。
|
||||
**[能力诊断](./CAPABILITY_DIAGNOSTICS.md)**。
|
||||
|
||||
```bash
|
||||
# 静态(默认):无网络、不启动 MCP 子进程
|
||||
@@ -778,7 +776,7 @@ headers = { Authorization = "Bearer ${STRIPE_KEY}" }
|
||||
启用的 MCP 服务器会在会话开始后于后台自动连接,因此工具上线期间聊天仍可正常使用。
|
||||
用 `/mcp` 或桌面端 MCP 面板可刷新状态、重连服务器、查看失败原因,或在当前会话内禁用某个服务器。
|
||||
若要跨 skills / hooks / 插件包 / MCP 做只读健康检查(不改配置),见
|
||||
[能力诊断](./CAPABILITY_DIAGNOSTICS.zh-CN.md)
|
||||
[能力诊断](./CAPABILITY_DIAGNOSTICS.md)
|
||||
(`reasonix doctor capabilities` 或 **设置 → 诊断**)。
|
||||
|
||||
交互调用方只会为冷启动短暂等待;即使等待结束,共享启动仍会在后台继续,不会被杀掉后反复重启,
|
||||
@@ -809,7 +807,7 @@ RPC 调用。两者都可按服务器覆盖。
|
||||
内置 **Skill**(如 `/init`、`/explore`、`/test`、`/reasonix-guide`)也会出现在斜杠菜单,
|
||||
并可通过 `run_skill` 调用(正文按需加载;只有索引行进入缓存稳定前缀)。配置或能力排障时
|
||||
用 `/reasonix-guide`,它会引导运行 `reasonix doctor capabilities`(见
|
||||
[能力诊断](./CAPABILITY_DIAGNOSTICS.zh-CN.md))。
|
||||
[能力诊断](./CAPABILITY_DIAGNOSTICS.md))。
|
||||
`/new` 会开启新会话,同时保存之前的 transcript 供历史记录和恢复使用;`/clear` 会二次确认,确认后丢弃当前上下文且不保存。
|
||||
`/tree` 查看已保存的对话分支,`/branch [name]` 从当前对话末端分支,`/switch <id|name>`
|
||||
切换到另一个分支。**自定义命令**
|
||||
@@ -843,7 +841,7 @@ custom path 或包含更多手写结构的 Skill,避免丢失 frontmatter、re
|
||||
`--model` 和 `--effort`,并写入与桌面设置页相同的按名称覆盖配置。
|
||||
|
||||
完整 CLI 参数、Skill 文件格式、模型优先级、安全行为和排障说明见
|
||||
[子智能体 Profile](./SUBAGENT_PROFILES.zh-CN.md)。
|
||||
[子智能体 Profile](./SUBAGENT_PROFILES.md)。
|
||||
|
||||
Context Engine v2 把上下文分成两个用途不同的层:
|
||||
|
||||
@@ -920,7 +918,7 @@ feedback、更新、重复项、敏感/超长内容,以及所有 `forget` 仍
|
||||
|
||||
旧事实会原地获得确定性 ID 和 revision 1;缺失 scope 时根据所在目录推导。Migration 幂等,
|
||||
旧客户端仍能安全路由,旧 Memory v5 transcript 也继续可读。完整行为、隐私与 cache 契约见
|
||||
[`Context Engine v2`](SESSION_MEMORY_RETRIEVAL.zh-CN.md)。
|
||||
[`Context Engine v2`](SESSION_MEMORY_RETRIEVAL.md)。
|
||||
|
||||
```markdown
|
||||
---
|
||||
@@ -935,24 +933,20 @@ Review the staged diff. Focus on $ARGUMENTS, list bugs with file:line.
|
||||
|
||||
## 内置文档检索
|
||||
|
||||
Reasonix 会把 `docs/` 中的 Markdown 文档和已审查的 `release-notes/releases.json` 更新日志
|
||||
目录随 CLI 和桌面端一起编译发布。只读 `docs` 工具通过本地 BM25 检索这份与当前安装版本
|
||||
完全一致的离线语料,并可按命中的 `section_id` 读取完整章节及来源。每个版本都会生成
|
||||
`changelog/v1.19.5.md`、`changelog/v1.19.5.zh-CN.md` 这类中英文虚拟文档,因此可以离线
|
||||
查询指定版本的新增功能、升级说明、修复和已知风险。涉及 Reasonix 配置、CLI/桌面端行为、
|
||||
版本历史、权限、MCP、记忆、恢复、Provider 或维护流程的问题,Agent 应先查询这里,再考虑
|
||||
联网搜索或凭经验回答。
|
||||
Reasonix 会把 `docs/` 中的 Markdown 文档随 CLI 和桌面端一起编译发布。只读 `docs` 工具
|
||||
通过本地 BM25 检索这份与当前安装版本完全一致的离线语料,并可按命中的 `section_id` 读取
|
||||
完整章节及来源。涉及 Reasonix 配置、CLI/桌面端行为、权限、MCP、记忆、恢复、Provider 或
|
||||
维护流程的问题,Agent 应先查询这里,再考虑联网搜索或凭经验回答。
|
||||
|
||||
普通路径不需要设置、联网、向量数据库或 embedding 服务。搜索会优先匹配提问语言,同时支持
|
||||
显式 `en`、`zh-CN`、受众和目录筛选。Balanced 与 Delivery 默认暴露该工具;Economy 会在需要时
|
||||
按需连接 `docs` 来源。每次返回都会给出产品版本、不可变源码 revision 与语料 SHA-256 digest。
|
||||
发布 CI 会实际编译 CLI;只有编译后的清单与候选提交的 `docs/*.md`、
|
||||
`release-notes/releases.json` 和构建身份完全一致时才允许发布。因此,更新较快的在线
|
||||
`main-v2` 页面不会静默覆盖与本地版本匹配的说明或更新历史。
|
||||
编译后的清单与候选提交的 `docs/*.md` 和构建身份一一对应,因此在线页面不会静默覆盖与本地
|
||||
版本匹配的说明。
|
||||
|
||||
直接输入 `/docs` 会在本地显示内置语料的版本、revision、digest 和使用示例,不调用模型。
|
||||
输入 `/docs <问题>`(例如 `/docs 1.19.5 更新日志`)时,Reasonix 会先在本地完成检索,再把
|
||||
与当前版本匹配的证据交给当前配置的 AI 生成带来源的回答。这个命令路径不依赖模型是否主动
|
||||
输入 `/docs <问题>`(例如 `/docs 如何配置 MCP 服务器`)时,Reasonix 会先在本地完成检索,再把
|
||||
命中的文档片段交给当前配置的 AI 生成带来源的回答。这个命令路径不依赖模型是否主动
|
||||
选择 `docs` 工具;普通自然语言问题仍可由模型自动调用该工具。已有自定义命令以及兼容插件或
|
||||
Skill 别名会继续拥有 `/docs`;发生冲突时,CLI 与桌面端通常会改为通过 `/reasonix:docs` 暴露
|
||||
内置语料。如果这个限定名也已被占用,Reasonix 会选择下一个空闲的 `reasonix:` 限定后备名,
|
||||
@@ -988,7 +982,7 @@ token、可选的显式 token 阈值和工作时间。每个目标 turn 结束
|
||||
continue/complete/blocked;没有报告时由独立的有界 evaluator 判定一次,任何 evaluator
|
||||
故障都会安全暂停目标而不是静默继续。
|
||||
|
||||
复杂任务建议把目标写成[任务合约](./TASK_CONTRACT.zh-CN.md):Context、Request、
|
||||
复杂任务建议把目标写成[任务合约](./TASK_CONTRACT.md):Context、Request、
|
||||
Output format、Constraints 和 Pause policy。Goal 模式会把这些部分当作自主执行的边界;
|
||||
除非下一步需要不可逆或对外可见操作、任务范围变化,或必须由用户提供信息,否则会继续采用合理默认值推进,并在最后汇报假设与结果。
|
||||
|
||||
@@ -1167,11 +1161,8 @@ provider 可见核心工具面(直接读/bash/编辑/写入、后台 shell 生
|
||||
`reasonix config reasoning-language auto|zh|en`。只有明确想为
|
||||
reasoning-language 写项目级覆盖时,才给 shell 命令加 `--local`。
|
||||
|
||||
桌面端“协作方式”菜单里的计划模式、目标模式和“轻量 / 均衡 / 交付优先”三档运行模式的使用方法与注意事项,
|
||||
见 [`COLLABORATION_MODES.zh-CN.md`](./COLLABORATION_MODES.zh-CN.md)。
|
||||
|
||||
桌面端“工具权限”里的询问、自动和 Yolo 模式的区别与使用场景,
|
||||
见 [`TOOL_APPROVAL_MODES.zh-CN.md`](./TOOL_APPROVAL_MODES.zh-CN.md)。
|
||||
见 [`TOOL_APPROVAL_MODES.md`](./TOOL_APPROVAL_MODES.md)。
|
||||
|
||||
分离 session(让各模型前缀缓存稳定)背后的取舍见
|
||||
[`SPEC.md` §3.5](./SPEC.md#35-two-model-collaboration-coordinator)。
|
||||
@@ -1,8 +1,6 @@
|
||||
# Reasoning Language
|
||||
|
||||
<a href="./GUIDE.md">Guide</a>
|
||||
·
|
||||
<a href="./REASONING_LANGUAGE.zh-CN.md">简体中文</a>
|
||||
|
||||
`agent.reasoning_language` controls the preferred language of visible
|
||||
reasoning or thinking text when a provider exposes it.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# Task Contracts and Pause Policy
|
||||
|
||||
<a href="./GUIDE.md">Guide</a>
|
||||
·
|
||||
<a href="./TASK_CONTRACT.zh-CN.md">Simplified Chinese</a>
|
||||
|
||||
Reasonix works best when nontrivial work is described as a **task contract**:
|
||||
what the work is for, what action is requested, how the result should be
|
||||
|
||||
@@ -6,8 +6,6 @@ the home and task/workspace scenes. They **cannot** run CSS, JavaScript, fonts,
|
||||
remote URLs, or SVG scripts. V1 packs remain valid and use the home image in
|
||||
both scenes.
|
||||
|
||||
> Chinese: [THEME_PACK.zh-CN.md](./THEME_PACK.zh-CN.md)
|
||||
|
||||
## Goals (first release)
|
||||
|
||||
- Built-in styles, user themes, backgrounds, live preview, import/export, local library
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Tool Contract
|
||||
|
||||
<a href="./TOOL_CONTRACT.zh-CN.md">简体中文</a>
|
||||
|
||||
This document records the provider-visible contract for Reasonix compile-time built-in tools. It is generated from the same canonical schema path used by the runtime registry.
|
||||
|
||||
| Tool | Read-only | Description |
|
||||
|
||||
@@ -46,18 +46,15 @@ func docsManifestCommand(args []string, cliVersion string) int {
|
||||
return 1
|
||||
}
|
||||
if sourceDir := strings.TrimSpace(*verifySource); sourceDir != "" {
|
||||
source, err := productdocs.SourceManifest(
|
||||
os.DirFS(filepath.Join(sourceDir, "docs")),
|
||||
os.DirFS(filepath.Join(sourceDir, "release-notes")),
|
||||
)
|
||||
source, err := productdocs.SourceManifest(os.DirFS(filepath.Join(sourceDir, "docs")))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error: load source documentation:", err)
|
||||
return 1
|
||||
}
|
||||
if manifest.Digest != source.Digest || manifest.Documents != source.Documents || manifest.Sections != source.Sections || manifest.ReleaseNotes != source.ReleaseNotes {
|
||||
fmt.Fprintf(os.Stderr, "error: embedded docs do not match %s: embedded=%s/%d/%d/%d source=%s/%d/%d/%d\n",
|
||||
sourceDir, manifest.Digest, manifest.Documents, manifest.Sections, manifest.ReleaseNotes,
|
||||
source.Digest, source.Documents, source.Sections, source.ReleaseNotes)
|
||||
if manifest.Digest != source.Digest || manifest.Documents != source.Documents || manifest.Sections != source.Sections {
|
||||
fmt.Fprintf(os.Stderr, "error: embedded docs do not match %s: embedded=%s/%d/%d source=%s/%d/%d\n",
|
||||
sourceDir, manifest.Digest, manifest.Documents, manifest.Sections,
|
||||
source.Digest, source.Documents, source.Sections)
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,12 +1163,12 @@ func TestSubmitDocsShowsLocalOverviewAndGroundsModelTurn(t *testing.T) {
|
||||
t.Fatalf("bare /docs should not start a model turn, inputs=%q", runner.inputs)
|
||||
}
|
||||
|
||||
c.Submit("/docs 1.19.5 更新日志")
|
||||
c.Submit("/docs REASONIX_HOME configuration paths")
|
||||
waitForTurnDone(t, events)
|
||||
if len(runner.inputs) != 1 {
|
||||
t.Fatalf("/docs query model turns = %d, inputs=%q", len(runner.inputs), runner.inputs)
|
||||
}
|
||||
for _, want := range []string{"1.19.5 更新日志", "changelog/v1.19.5.zh-CN.md", "embedded_docs_search_results"} {
|
||||
for _, want := range []string{"REASONIX_HOME configuration paths", "docs/CONFIG_PATHS.md", "embedded_docs_search_results"} {
|
||||
if !strings.Contains(runner.inputs[0], want) {
|
||||
t.Fatalf("grounded /docs prompt missing %q:\n%s", want, runner.inputs[0])
|
||||
}
|
||||
@@ -1220,12 +1220,12 @@ func TestSubmitQualifiedReasonixDocsPreservesExistingCommandAndUsesNextFallback(
|
||||
}
|
||||
waitIdle(t, c)
|
||||
|
||||
c.Submit("/reasonix:builtin:docs 1.19.5 update notes")
|
||||
c.Submit("/reasonix:builtin:docs REASONIX_HOME configuration paths")
|
||||
waitForTurnDone(t, events)
|
||||
if len(runner.inputs) != 2 {
|
||||
t.Fatalf("generated docs fallback model turns = %d, inputs=%q", len(runner.inputs), runner.inputs)
|
||||
}
|
||||
for _, want := range []string{"1.19.5 update notes", "changelog/v1.19.5.md", "embedded_docs_search_results"} {
|
||||
for _, want := range []string{"REASONIX_HOME configuration paths", "docs/CONFIG_PATHS.md", "embedded_docs_search_results"} {
|
||||
if !strings.Contains(runner.inputs[1], want) {
|
||||
t.Fatalf("qualified docs prompt missing %q:\n%s", want, runner.inputs[1])
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"reasonix/internal/extension"
|
||||
@@ -12,13 +11,7 @@ import (
|
||||
|
||||
func fixturesDir(t *testing.T) string {
|
||||
t.Helper()
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
t.Fatal("runtime.Caller failed")
|
||||
}
|
||||
// internal/extension -> repo root
|
||||
root := filepath.Clean(filepath.Join(filepath.Dir(file), "..", ".."))
|
||||
return filepath.Join(root, "docs", "superpowers", "specs", "fixtures", "spatiotemporal-v2")
|
||||
return filepath.Join("testdata", "spatiotemporal-v2")
|
||||
}
|
||||
|
||||
func TestGoldenLifecycleStates(t *testing.T) {
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"hash"
|
||||
"io/fs"
|
||||
"path"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
productcontent "reasonix/docs"
|
||||
"reasonix/internal/retrieval"
|
||||
"reasonix/internal/tool"
|
||||
releasenotes "reasonix/release-notes"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -41,14 +39,12 @@ const (
|
||||
)
|
||||
|
||||
type document struct {
|
||||
path string
|
||||
source string
|
||||
title string
|
||||
locale string
|
||||
audience string
|
||||
releaseNote bool
|
||||
releaseVersion string
|
||||
sections []*section
|
||||
path string
|
||||
source string
|
||||
title string
|
||||
locale string
|
||||
audience string
|
||||
sections []*section
|
||||
}
|
||||
|
||||
type section struct {
|
||||
@@ -65,40 +61,32 @@ type section struct {
|
||||
}
|
||||
|
||||
func (d *document) displayPath() string {
|
||||
if d.releaseNote {
|
||||
return d.path
|
||||
}
|
||||
return "docs/" + d.path
|
||||
}
|
||||
|
||||
func (d *document) sourceRange(startLine, endLine int) string {
|
||||
if d.releaseNote {
|
||||
return fmt.Sprintf("%s rendered-lines=%d-%d", d.source, startLine, endLine)
|
||||
}
|
||||
return fmt.Sprintf("%s:%d-%d", d.source, startLine, endLine)
|
||||
}
|
||||
|
||||
type catalog struct {
|
||||
digest string
|
||||
docs []*document
|
||||
byPath map[string]*document
|
||||
byID map[string]*section
|
||||
sections []*section
|
||||
df map[string]int
|
||||
avgLen float64
|
||||
releaseNotes int
|
||||
digest string
|
||||
docs []*document
|
||||
byPath map[string]*document
|
||||
byID map[string]*section
|
||||
sections []*section
|
||||
df map[string]int
|
||||
avgLen float64
|
||||
}
|
||||
|
||||
// Manifest identifies the exact documentation corpus bundled into one build.
|
||||
// Version and Revision describe the product binary; Digest binds the sorted
|
||||
// Markdown sources plus the structured release catalog consumed by retrieval.
|
||||
// Markdown sources consumed by retrieval.
|
||||
type Manifest struct {
|
||||
Version string `json:"version"`
|
||||
Revision string `json:"revision"`
|
||||
Digest string `json:"digest"`
|
||||
Documents int `json:"documents"`
|
||||
Sections int `json:"sections"`
|
||||
ReleaseNotes int `json:"release_notes"`
|
||||
Version string `json:"version"`
|
||||
Revision string `json:"revision"`
|
||||
Digest string `json:"digest"`
|
||||
Documents int `json:"documents"`
|
||||
Sections int `json:"sections"`
|
||||
}
|
||||
|
||||
type searchHit struct {
|
||||
@@ -112,8 +100,6 @@ type docsTool struct {
|
||||
}
|
||||
|
||||
var (
|
||||
queryVersionRe = regexp.MustCompile(`(?i)\bv?([0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9a-z.-]+)?)\b`)
|
||||
|
||||
defaultOnce sync.Once
|
||||
defaultCatalog *catalog
|
||||
defaultLoadErr error
|
||||
@@ -132,7 +118,7 @@ func NewTool() tool.Tool {
|
||||
|
||||
func loadDefaultCatalog() (*catalog, error) {
|
||||
defaultOnce.Do(func() {
|
||||
defaultCatalog, defaultLoadErr = loadCatalogWithReleaseNotes(productcontent.Content, releasenotes.Content)
|
||||
defaultCatalog, defaultLoadErr = loadCatalog(productcontent.Content)
|
||||
})
|
||||
return defaultCatalog, defaultLoadErr
|
||||
}
|
||||
@@ -160,14 +146,14 @@ func CommandOverviewFor(language, commandName string) (string, error) {
|
||||
}
|
||||
m := c.manifest()
|
||||
identity := fmt.Sprintf("version=%s revision=%s digest=%s", m.Version, m.Revision, m.Digest)
|
||||
stats := fmt.Sprintf("documents=%d sections=%d releases=%d", m.Documents, m.Sections, m.ReleaseNotes)
|
||||
stats := fmt.Sprintf("documents=%d sections=%d", m.Documents, m.Sections)
|
||||
switch strings.ToLower(strings.TrimSpace(language)) {
|
||||
case "zh", "zh-cn":
|
||||
return fmt.Sprintf("内置 Reasonix 文档\n%s\n%s\n\n用法:%s <问题>\n示例:%s 1.19.5 更新日志\n\n搜索在本地完成,命中的版本匹配资料会交给当前配置的 AI 组织答案。", identity, stats, commandName, commandName), nil
|
||||
return fmt.Sprintf("内置 Reasonix 文档\n%s\n%s\n\n用法:%s <问题>\n示例:%s 如何配置 MCP 服务器\n\n搜索在本地完成,命中的文档片段会交给当前配置的 AI 组织答案。", identity, stats, commandName, commandName), nil
|
||||
case "zh-tw":
|
||||
return fmt.Sprintf("內建 Reasonix 文件\n%s\n%s\n\n用法:%s <問題>\n範例:%s 1.19.5 更新日誌\n\n搜尋在本機完成,命中的版本匹配資料會交給目前設定的 AI 組織答案。", identity, stats, commandName, commandName), nil
|
||||
return fmt.Sprintf("內建 Reasonix 文件\n%s\n%s\n\n用法:%s <問題>\n範例:%s 如何設定 MCP 伺服器\n\n搜尋在本機完成,命中的文件片段會交給目前設定的 AI 組織答案。", identity, stats, commandName, commandName), nil
|
||||
default:
|
||||
return fmt.Sprintf("Embedded Reasonix documentation\n%s\n%s\n\nUsage: %s <question>\nExample: %s 1.19.5 changelog\n\nSearch runs locally, then the version-matched evidence is passed to the configured AI to compose the answer.", identity, stats, commandName, commandName), nil
|
||||
return fmt.Sprintf("Embedded Reasonix documentation\n%s\n%s\n\nUsage: %s <question>\nExample: %s how to configure an MCP server\n\nSearch runs locally, then the matched sections are passed to the configured AI to compose the answer.", identity, stats, commandName, commandName), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,10 +168,10 @@ func SearchEmbedded(ctx context.Context, query string) (string, error) {
|
||||
return (&docsTool{catalog: c}).search(ctx, query, "auto", "all", defaultLimit)
|
||||
}
|
||||
|
||||
// SourceManifest computes the corpus identity from the source Markdown and
|
||||
// structured release catalog used by a build.
|
||||
func SourceManifest(docsFS, releaseNotesFS fs.FS) (Manifest, error) {
|
||||
c, err := loadCatalogWithReleaseNotes(docsFS, releaseNotesFS)
|
||||
// SourceManifest computes the corpus identity from the source Markdown used by
|
||||
// a build.
|
||||
func SourceManifest(docsFS fs.FS) (Manifest, error) {
|
||||
c, err := loadCatalog(docsFS)
|
||||
if err != nil {
|
||||
return Manifest{}, err
|
||||
}
|
||||
@@ -195,12 +181,11 @@ func SourceManifest(docsFS, releaseNotesFS fs.FS) (Manifest, error) {
|
||||
func (c *catalog) manifest() Manifest {
|
||||
version, revision := buildIdentity()
|
||||
return Manifest{
|
||||
Version: version,
|
||||
Revision: revision,
|
||||
Digest: "sha256:" + c.digest,
|
||||
Documents: len(c.docs),
|
||||
Sections: len(c.sections),
|
||||
ReleaseNotes: c.releaseNotes,
|
||||
Version: version,
|
||||
Revision: revision,
|
||||
Digest: "sha256:" + c.digest,
|
||||
Documents: len(c.docs),
|
||||
Sections: len(c.sections),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +322,6 @@ func (t *docsTool) search(ctx context.Context, query, language, audience string,
|
||||
preferredLanguage = detectQueryLanguage(query)
|
||||
}
|
||||
queryLower := strings.ToLower(query)
|
||||
queryVersions := queryVersionRe.FindAllStringSubmatch(queryLower, -1)
|
||||
hits := make([]searchHit, 0, len(t.catalog.sections))
|
||||
for _, section := range t.catalog.sections {
|
||||
if err := ctx.Err(); err != nil {
|
||||
@@ -350,21 +334,9 @@ func (t *docsTool) search(ctx context.Context, query, language, audience string,
|
||||
continue
|
||||
}
|
||||
score := retrieval.BM25Score(section.counts, section.length, queryTerms, t.catalog.df, len(t.catalog.sections), t.catalog.avgLen)
|
||||
exactReleaseVersion := false
|
||||
for _, match := range queryVersions {
|
||||
if len(match) > 1 && strings.EqualFold(section.document.releaseVersion, match[1]) {
|
||||
exactReleaseVersion = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if score <= 0 && !exactReleaseVersion {
|
||||
if score <= 0 {
|
||||
continue
|
||||
}
|
||||
if exactReleaseVersion {
|
||||
// Release-note virtual paths carry the exact requested version. Keep
|
||||
// that stronger than generic terms such as "changelog" or "更新日志".
|
||||
score += 100
|
||||
}
|
||||
for _, term := range queryTerms {
|
||||
if section.headingHits[term] > 0 {
|
||||
score += 0.35
|
||||
@@ -444,11 +416,7 @@ func (t *docsTool) list(language, audience string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func loadCatalog(fsys fs.FS) (*catalog, error) {
|
||||
return loadCatalogWithReleaseNotes(fsys, nil)
|
||||
}
|
||||
|
||||
func loadCatalogWithReleaseNotes(docsFS, releaseNotesFS fs.FS) (*catalog, error) {
|
||||
func loadCatalog(docsFS fs.FS) (*catalog, error) {
|
||||
entries, err := fs.ReadDir(docsFS, ".")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -479,35 +447,6 @@ func loadCatalogWithReleaseNotes(docsFS, releaseNotesFS fs.FS) (*catalog, error)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if releaseNotesFS != nil {
|
||||
data, err := fs.ReadFile(releaseNotesFS, "releases.json")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read release-notes/releases.json: %w", err)
|
||||
}
|
||||
if !utf8.Valid(data) {
|
||||
return nil, fmt.Errorf("read release-notes/releases.json: JSON is not valid UTF-8")
|
||||
}
|
||||
writeDigestRecord(hash, "release-notes/releases.json", data)
|
||||
rendered, releaseCount, err := renderReleaseDocuments(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, virtual := range rendered {
|
||||
doc := parseDocumentWithParser(virtual.path, virtual.content, markdownParser)
|
||||
doc.source = virtual.source
|
||||
doc.locale = virtual.locale
|
||||
doc.audience = "user"
|
||||
doc.releaseNote = true
|
||||
doc.releaseVersion = virtual.version
|
||||
if len(doc.sections) == 0 {
|
||||
return nil, fmt.Errorf("rendered release note %s contains no sections", virtual.path)
|
||||
}
|
||||
if err := c.addDocument(doc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c.releaseNotes = releaseCount
|
||||
}
|
||||
if len(c.docs) == 0 || len(c.sections) == 0 {
|
||||
return nil, fmt.Errorf("embedded documentation corpus is empty")
|
||||
}
|
||||
@@ -762,9 +701,9 @@ func detectDocumentLanguage(name, content string) string {
|
||||
func documentAudience(name string) string {
|
||||
stem := strings.TrimSuffix(strings.TrimSuffix(name, ".md"), ".zh-CN")
|
||||
switch strings.ToUpper(stem) {
|
||||
case "RELEASING", "SIGNPATH_WINDOWS_ADMIN_SOP", "PRODUCTION_CHECKLIST", "THEME_ASSETS", "STUDIO_RELEASE", "DOCS_STANDARD":
|
||||
case "THEME_ASSETS", "STUDIO_RELEASE", "DOCS_STANDARD":
|
||||
return "maintainer"
|
||||
case "CHECKPOINTS", "GOAL_ENFORCEMENT", "SESSION_REFERENCE_ARCHITECTURE", "SPEC", "TASK_CONTRACT", "TOOL_CONTRACT":
|
||||
case "CHECKPOINTS", "SPEC", "TASK_CONTRACT", "TOOL_CONTRACT":
|
||||
return "developer"
|
||||
default:
|
||||
return "user"
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
productcontent "reasonix/docs"
|
||||
"reasonix/internal/provider"
|
||||
releasenotes "reasonix/release-notes"
|
||||
)
|
||||
|
||||
func TestEmbeddedCatalogLoadsDeterministically(t *testing.T) {
|
||||
@@ -24,8 +23,8 @@ func TestEmbeddedCatalogLoadsDeterministically(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("loadCatalog second time: %v", err)
|
||||
}
|
||||
if len(first.docs) < 40 {
|
||||
t.Fatalf("embedded docs = %d, want at least 40", len(first.docs))
|
||||
if len(first.docs) < 30 {
|
||||
t.Fatalf("embedded docs = %d, want at least 30", len(first.docs))
|
||||
}
|
||||
if len(first.sections) < len(first.docs) {
|
||||
t.Fatalf("embedded sections = %d, docs = %d", len(first.sections), len(first.docs))
|
||||
@@ -46,7 +45,7 @@ func TestEmbeddedAndSourceManifestsMatch(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("EmbeddedManifest: %v", err)
|
||||
}
|
||||
source, err := SourceManifest(productcontent.Content, releasenotes.Content)
|
||||
source, err := SourceManifest(productcontent.Content)
|
||||
if err != nil {
|
||||
t.Fatalf("SourceManifest: %v", err)
|
||||
}
|
||||
@@ -56,9 +55,6 @@ func TestEmbeddedAndSourceManifestsMatch(t *testing.T) {
|
||||
if !strings.HasPrefix(embedded.Digest, "sha256:") || embedded.Version == "" || embedded.Revision == "" {
|
||||
t.Fatalf("manifest is missing build identity: %#v", embedded)
|
||||
}
|
||||
if embedded.ReleaseNotes < 10 {
|
||||
t.Fatalf("embedded release notes = %d, want release history", embedded.ReleaseNotes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocsCommandOverviewAndSearchUseEmbeddedCorpus(t *testing.T) {
|
||||
@@ -66,7 +62,7 @@ func TestDocsCommandOverviewAndSearchUseEmbeddedCorpus(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, want := range []string{"内置 Reasonix 文档", "version=", "revision=", "digest=sha256:", "/docs 1.19.5 更新日志"} {
|
||||
for _, want := range []string{"内置 Reasonix 文档", "version=", "revision=", "digest=sha256:", "/docs 如何配置 MCP 服务器"} {
|
||||
if !strings.Contains(overview, want) {
|
||||
t.Fatalf("command overview missing %q:\n%s", want, overview)
|
||||
}
|
||||
@@ -79,14 +75,12 @@ func TestDocsCommandOverviewAndSearchUseEmbeddedCorpus(t *testing.T) {
|
||||
t.Fatalf("qualified command overview used the wrong invocation:\n%s", qualified)
|
||||
}
|
||||
|
||||
results, err := SearchEmbedded(context.Background(), "1.19.5 更新日志")
|
||||
results, err := SearchEmbedded(context.Background(), "REASONIX_HOME configuration paths")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
firstStart := strings.Index(results, "\n1. ")
|
||||
firstEnd := strings.Index(results, "\n2. ")
|
||||
if firstStart < 0 || firstEnd <= firstStart || !strings.Contains(results[firstStart:firstEnd], "path=changelog/v1.19.5.zh-CN.md") || !strings.Contains(results, "digest=sha256:") {
|
||||
t.Fatalf("command search did not use the embedded release catalog:\n%s", results)
|
||||
if !strings.Contains(results, "path=docs/CONFIG_PATHS.md") || !strings.Contains(results, "digest=sha256:") {
|
||||
t.Fatalf("command search did not use the embedded corpus:\n%s", results)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,11 +91,8 @@ func TestExtensionDeveloperGuidesAreEmbeddedAndSearchable(t *testing.T) {
|
||||
}
|
||||
for _, path := range []string{
|
||||
"EXTENSIONS.md",
|
||||
"EXTENSIONS.zh-CN.md",
|
||||
"EXTENSION_PROTOCOL.md",
|
||||
"EXTENSION_PROTOCOL.zh-CN.md",
|
||||
"PLUGIN_PACKAGES.md",
|
||||
"PLUGIN_PACKAGES.zh-CN.md",
|
||||
} {
|
||||
if _, ok := c.byPath[path]; !ok {
|
||||
t.Fatalf("extension developer guide %q is missing from the embedded catalog", path)
|
||||
@@ -116,22 +107,14 @@ func TestExtensionDeveloperGuidesAreEmbeddedAndSearchable(t *testing.T) {
|
||||
if !strings.Contains(english, "path=docs/EXTENSIONS.md") || !strings.Contains(english, "path=docs/PLUGIN_PACKAGES.md") {
|
||||
t.Fatalf("English extension search did not expose the overview and manifest reference:\n%s", english)
|
||||
}
|
||||
|
||||
chinese, err := tool.search(context.Background(), "Sidecar 插件 Manifest v2 扩展开发", "zh-CN", "all", 10)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(chinese, "path=docs/EXTENSIONS.zh-CN.md") || !strings.Contains(chinese, "path=docs/PLUGIN_PACKAGES.zh-CN.md") {
|
||||
t.Fatalf("Chinese extension search did not expose the overview and manifest reference:\n%s", chinese)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceManifestChangesWithMarkdownBytes(t *testing.T) {
|
||||
first, err := SourceManifest(fstest.MapFS{"GUIDE.md": {Data: []byte("# Guide\n\nFirst.\n")}}, nil)
|
||||
first, err := SourceManifest(fstest.MapFS{"GUIDE.md": {Data: []byte("# Guide\n\nFirst.\n")}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := SourceManifest(fstest.MapFS{"GUIDE.md": {Data: []byte("# Guide\n\nSecond.\n")}}, nil)
|
||||
second, err := SourceManifest(fstest.MapFS{"GUIDE.md": {Data: []byte("# Guide\n\nSecond.\n")}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -167,14 +150,14 @@ func TestSourceManifestDigestUsesUnambiguousFileFraming(t *testing.T) {
|
||||
first, err := SourceManifest(fstest.MapFS{
|
||||
"A.md": {Data: firstA},
|
||||
"B.md": {Data: firstB},
|
||||
}, nil)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := SourceManifest(fstest.MapFS{
|
||||
"A.md": {Data: secondA},
|
||||
"B.md": {Data: secondB},
|
||||
}, nil)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -221,107 +204,6 @@ func TestSearchRejectsOversizedQueriesBeforeRetrieval(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseNotesAreSearchableInBothLanguages(t *testing.T) {
|
||||
c, err := loadCatalogWithReleaseNotes(productcontent.Content, releasenotes.Content)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tl := &docsTool{catalog: c}
|
||||
|
||||
english, err := tl.search(context.Background(), "v1.19.5 usage statistics dashboard", "en", "user", 5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(english, "path=changelog/v1.19.5.md") || !strings.Contains(english, "source=release-notes/releases.json#v1.19.5") {
|
||||
t.Fatalf("English release search missing versioned changelog:\n%s", english)
|
||||
}
|
||||
|
||||
chinese, err := tl.search(context.Background(), "v1.19.5 用量统计面板", "zh-CN", "user", 5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(chinese, "path=changelog/v1.19.5.zh-CN.md") {
|
||||
t.Fatalf("Chinese release search missing versioned changelog:\n%s", chinese)
|
||||
}
|
||||
|
||||
sections, err := tl.read("", "changelog/v1.19.5.zh-CN.md")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(sections, "source: release-notes/releases.json#v1.19.5") {
|
||||
t.Fatalf("release section listing missing JSON provenance:\n%s", sections)
|
||||
}
|
||||
section, err := tl.read("changelog/v1.19.5.zh-CN.md::s002", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(section, "source: release-notes/releases.json#v1.19.5 rendered-lines=") {
|
||||
t.Fatalf("release section missing rendered provenance:\n%s", section)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseSearchDoesNotTreatPreviewAsExactStableVersion(t *testing.T) {
|
||||
docsFS := fstest.MapFS{
|
||||
"GUIDE.md": {Data: []byte("# Guide\n\nEmbedded documentation.\n")},
|
||||
}
|
||||
releaseNotesFS := fstest.MapFS{
|
||||
"releases.json": {Data: []byte(`{
|
||||
"releases": [
|
||||
{"version":"1.19.0","title":{"en":"Stable","zh":"稳定版"},"summary":{"en":"Stable changelog","zh":"稳定版更新日志"}},
|
||||
{"version":"1.19.0-preview.1","title":{"en":"Preview","zh":"预览版"},"summary":{"en":"Preview-only changelog","zh":"仅预览版更新日志"}}
|
||||
]
|
||||
}`)},
|
||||
}
|
||||
c, err := loadCatalogWithReleaseNotes(docsFS, releaseNotesFS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tl := &docsTool{catalog: c}
|
||||
|
||||
stable, err := tl.search(context.Background(), "1.19.0 changelog", "en", "user", 10)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(stable, "path=changelog/v1.19.0.md") {
|
||||
t.Fatalf("stable release search missing exact changelog:\n%s", stable)
|
||||
}
|
||||
if strings.Contains(stable, "path=changelog/v1.19.0-preview.1.md") {
|
||||
t.Fatalf("stable release search treated preview as an exact version match:\n%s", stable)
|
||||
}
|
||||
|
||||
preview, err := tl.search(context.Background(), "1.19.0-preview.1 changelog", "en", "user", 10)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(preview, "path=changelog/v1.19.0-preview.1.md") {
|
||||
t.Fatalf("preview release search missing exact changelog:\n%s", preview)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceManifestChangesWithReleaseCatalogBytes(t *testing.T) {
|
||||
docsFS := fstest.MapFS{"GUIDE.md": {Data: []byte("# Guide\n\nBody.\n")}}
|
||||
firstNotes := fstest.MapFS{"releases.json": {Data: []byte(`{"releases":[{"version":"1.0.0","title":{"en":"First","zh":"第一"},"summary":{"en":"Body","zh":"正文"}}]}`)}}
|
||||
secondNotes := fstest.MapFS{"releases.json": {Data: []byte(`{"releases":[{"version":"1.0.0","title":{"en":"Second","zh":"第二"},"summary":{"en":"Body","zh":"正文"}}]}`)}}
|
||||
first, err := SourceManifest(docsFS, firstNotes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := SourceManifest(docsFS, secondNotes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if first.Digest == second.Digest || first.ReleaseNotes != 1 || second.ReleaseNotes != 1 {
|
||||
t.Fatalf("release catalog was not bound into manifests: first=%#v second=%#v", first, second)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseCatalogRejectsUnsafeVirtualPathVersion(t *testing.T) {
|
||||
_, _, err := renderReleaseDocuments([]byte(`{"releases":[{"version":"../secret","title":{"en":"Bad","zh":"错误"},"summary":{"en":"Body","zh":"正文"}}]}`))
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid version") {
|
||||
t.Fatalf("unsafe release version error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchPrefersRelevantChineseAndEnglishSections(t *testing.T) {
|
||||
c, err := loadCatalog(productcontent.Content)
|
||||
if err != nil {
|
||||
@@ -333,8 +215,8 @@ func TestSearchPrefersRelevantChineseAndEnglishSections(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Chinese search: %v", err)
|
||||
}
|
||||
if !strings.Contains(zh, "docs/TOOL_APPROVAL_MODES.zh-CN.md") {
|
||||
t.Fatalf("Chinese search did not find the permission guide:\n%s", zh)
|
||||
if !strings.Contains(zh, "path=docs/CLI.zh-CN.md") || !strings.Contains(zh, "权限") {
|
||||
t.Fatalf("Chinese search did not find the permission reference:\n%s", zh)
|
||||
}
|
||||
|
||||
en, err := tl.search(context.Background(), "REASONIX_HOME configuration paths", "auto", "all", 5)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Emit docs/THEME_ASSETS.md + .zh-CN.md — provenance & licence ledger for the
|
||||
"""Emit docs/THEME_ASSETS.md — provenance & licence ledger for the
|
||||
official theme assets. Reads hashes from out/report.json (produced by build.py).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
@@ -68,30 +68,9 @@ def main():
|
||||
en.append(f"| {name} (`{tid}`) | `{prompt}` | `{bg}` | `{pv}` |")
|
||||
en.append("")
|
||||
|
||||
zh = []
|
||||
zh.append("# 官方主题素材来源与许可记录\n")
|
||||
zh.append("八款 Reasonix 官方主题的全部图片均为**原创**,由 `scripts/official-theme-art/` 中的脚本")
|
||||
zh.append("从零程序化生成(numpy + Pillow,固定随机种子,可完全复现)。视觉*方向*参考了 MIT 许可的")
|
||||
zh.append("[Codex-Dream-Skin](https://github.com/Fei-Away/Codex-Dream-Skin) 概念图库,但是:\n")
|
||||
zh.append("- **未复制参考项目或任何第三方素材的任何像素**、布局、界面元素、文字、标志或水印;")
|
||||
zh.append(" 所有背景均为代码重新生成的独立素材。")
|
||||
zh.append("- 图中人物均为生成器绘制的**原创虚构成年人**:插画女性(玫瑰晨光)、吉祥程序员(鸿运工坊)、")
|
||||
zh.append(" 读者(鼠尾草清风)、动漫人物(灵感手账)、剪影女性(紫曜星夜)、数字表演者(青岚舞台)、")
|
||||
zh.append(" 绅士(黑金序曲)。赤曜新城不含人物。")
|
||||
zh.append("- 背景中不含窗口、侧栏、卡片、按钮、输入框或可读文字,并已去除 EXIF 等元数据。\n")
|
||||
zh.append("素材随 Reasonix 仓库以 MIT 许可发布,© Reasonix Contributors。人工审核:Reasonix Contributors(发布 PR 审核)。\n")
|
||||
zh.append(f"生成日期:{today}\n")
|
||||
zh.append("| 主题 | 生成器(最终提示词等价物) | background.webp SHA-256 | preview.webp SHA-256 |")
|
||||
zh.append("| --- | --- | --- | --- |")
|
||||
for tid, name, prompt, bg, pv in rows:
|
||||
zh.append(f"| {name}(`{tid}`) | `{prompt}` | `{bg}` | `{pv}` |")
|
||||
zh.append("")
|
||||
|
||||
with open(os.path.join(DOCS, "THEME_ASSETS.md"), "w") as f:
|
||||
f.write("\n".join(en))
|
||||
with open(os.path.join(DOCS, "THEME_ASSETS.zh-CN.md"), "w") as f:
|
||||
f.write("\n".join(zh))
|
||||
print("wrote docs/THEME_ASSETS.md + .zh-CN.md")
|
||||
print("wrote docs/THEME_ASSETS.md")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
"codeowners": 0,
|
||||
"commented-code": 0,
|
||||
"complexity": 1495,
|
||||
"doc-language": 33,
|
||||
"doc-owner": 91,
|
||||
"doc-prose": 2755,
|
||||
"doc-language": 0,
|
||||
"doc-owner": 44,
|
||||
"doc-prose": 2375,
|
||||
"error-text": 9,
|
||||
"essay": 3207,
|
||||
"file-size": 31285,
|
||||
@@ -21,7 +21,6 @@
|
||||
"orphan": 80,
|
||||
"refusal-path": 0,
|
||||
"release-note": 661,
|
||||
"spec-parity": 0,
|
||||
"struct-state": 32,
|
||||
"wire-parity": 0
|
||||
},
|
||||
@@ -29,10 +28,6 @@
|
||||
".github/pull_request_template.md": {
|
||||
"doc-prose": 1
|
||||
},
|
||||
"CHANGELOG.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 94
|
||||
},
|
||||
"CONTRIBUTING.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
@@ -40,9 +35,6 @@
|
||||
"README.md": {
|
||||
"doc-prose": 1
|
||||
},
|
||||
"README.zh-CN.md": {
|
||||
"doc-prose": 1
|
||||
},
|
||||
"REASONIX.md": {
|
||||
"doc-prose": 92
|
||||
},
|
||||
@@ -99,46 +91,22 @@
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 13
|
||||
},
|
||||
"docs/ACP.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/BILLING.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/BILLING.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/BOT_GUIDE.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 27
|
||||
},
|
||||
"docs/BOT_GUIDE.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 11
|
||||
},
|
||||
"docs/CAPABILITY_DIAGNOSTICS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 5
|
||||
},
|
||||
"docs/CAPABILITY_DIAGNOSTICS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/CHECKPOINTS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 4
|
||||
},
|
||||
"docs/CHECKPOINTS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/CLI.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 50
|
||||
@@ -147,42 +115,18 @@
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 17
|
||||
},
|
||||
"docs/COLLABORATION_MODES.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/CONFIG_PATHS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 30
|
||||
},
|
||||
"docs/CONFIG_PATHS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 12
|
||||
},
|
||||
"docs/DESKTOP_CRASH_DIAGNOSTICS_RUNBOOK.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 11
|
||||
},
|
||||
"docs/DESKTOP_CRASH_DIAGNOSTICS_RUNBOOK.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/DESKTOP_HOOKS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 10
|
||||
},
|
||||
"docs/EXTENSIONS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 16
|
||||
},
|
||||
"docs/EXTENSIONS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 4
|
||||
},
|
||||
"docs/EXTENSION_PROTOCOL.generated.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
@@ -190,121 +134,54 @@
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 20
|
||||
},
|
||||
"docs/EXTENSION_PROTOCOL.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 6
|
||||
},
|
||||
"docs/EXTENSION_RUNTIME_V2.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 13
|
||||
},
|
||||
"docs/EXTENSION_RUNTIME_V2.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 6
|
||||
},
|
||||
"docs/EXTENSION_RUNTIME_V2_PERF.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 9
|
||||
},
|
||||
"docs/EXTENSION_RUNTIME_V2_PERF.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/GOAL_ENFORCEMENT.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 8
|
||||
},
|
||||
"docs/GUIDE.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 372
|
||||
"doc-prose": 366
|
||||
},
|
||||
"docs/GUIDE.zh-CN.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 178
|
||||
"doc-prose": 173
|
||||
},
|
||||
"docs/HISTORY_SEARCH_CATALOG.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 8
|
||||
},
|
||||
"docs/HISTORY_SEARCH_CATALOG.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/MIGRATING.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 44
|
||||
},
|
||||
"docs/MIGRATING.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/PLUGIN_PACKAGES.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 103
|
||||
},
|
||||
"docs/PLUGIN_PACKAGES.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 69
|
||||
},
|
||||
"docs/REASONING_LANGUAGE.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/REASONING_LANGUAGE.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/REASONING_PROVIDERS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 23
|
||||
},
|
||||
"docs/REASONING_PROVIDERS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 11
|
||||
},
|
||||
"docs/RECOVERY.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/RECOVERY.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/RELEASING.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 7
|
||||
},
|
||||
"docs/SESSION_MEMORY_RETRIEVAL.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 15
|
||||
},
|
||||
"docs/SESSION_MEMORY_RETRIEVAL.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/SESSION_REFERENCE_ARCHITECTURE.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/SIGNPATH_WINDOWS_ADMIN_SOP.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/SPEC.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 341
|
||||
},
|
||||
"docs/SPEC.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 78
|
||||
},
|
||||
"docs/STUDIO_SHELL_BOUNDARIES.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
@@ -313,113 +190,34 @@
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 4
|
||||
},
|
||||
"docs/SUBAGENT_PROFILES.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/SUBAGENT_PROGRESS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 5
|
||||
},
|
||||
"docs/SUBAGENT_PROGRESS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/TASK_CONTRACT.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/TASK_CONTRACT.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/THEME_ASSETS.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/THEME_ASSETS.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/THEME_PACK.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 5
|
||||
},
|
||||
"docs/THEME_PACK.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/TOOL_APPROVAL_MODES.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 10
|
||||
},
|
||||
"docs/TOOL_APPROVAL_MODES.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/TOOL_CONTRACT.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 41
|
||||
},
|
||||
"docs/TOOL_CONTRACT.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 20
|
||||
},
|
||||
"docs/USAGE_CATALOG.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/USAGE_CATALOG.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/WINDOWS_LTSC_2019_CRASH_RUNBOOK.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/WINDOWS_LTSC_2019_CRASH_RUNBOOK.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/production_checklist.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/production_checklist.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/research/cache-aware-compaction-design.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/research/goal-verification-authority.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/research/subagent-handoff-baseline.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"docs/superpowers/audits/2026-06-30-autoresearch-runtime-verification.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/superpowers/plans/2026-06-29-autoresearch-runtime-implementation.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 1
|
||||
},
|
||||
"docs/superpowers/plans/billing-currency-acceptance.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"docs/superpowers/specs/2026-06-29-autoresearch-runtime-design.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 2
|
||||
},
|
||||
"docs/superpowers/specs/2026-08-07-spatiotemporal-composability-v2.md": {
|
||||
"doc-owner": 1,
|
||||
"doc-prose": 3
|
||||
},
|
||||
"internal/acp/clientio.go": {
|
||||
"essay": 4
|
||||
},
|
||||
@@ -2043,10 +1841,6 @@
|
||||
"sdk/go/examples/starterextension/README.md": {
|
||||
"doc-owner": 1
|
||||
},
|
||||
"sdk/go/examples/starterextension/README.zh-CN.md": {
|
||||
"doc-language": 1,
|
||||
"doc-owner": 1
|
||||
},
|
||||
"sdk/go/sdk.go": {
|
||||
"essay": 27,
|
||||
"file-size": 367
|
||||
|
||||
@@ -37,7 +37,6 @@ const (
|
||||
ruleRefusalPath = "refusal-path"
|
||||
ruleErrorText = "error-text"
|
||||
ruleClaudeDialect = "claude-dialect"
|
||||
ruleSpecParity = "spec-parity"
|
||||
ruleWireParity = "wire-parity"
|
||||
ruleFrontendParity = "frontend-parity"
|
||||
ruleFlatView = "flat-view"
|
||||
@@ -53,7 +52,7 @@ var allRules = []string{
|
||||
ruleEssay, ruleBanner, ruleMarker, ruleDeadCode,
|
||||
ruleNarrative, ruleFileSize, ruleLayering,
|
||||
ruleFuncSize, ruleComplexity, ruleStructState, ruleRefusalPath, ruleErrorText,
|
||||
ruleClaudeDialect, ruleSpecParity, ruleWireParity, ruleOrphan,
|
||||
ruleClaudeDialect, ruleWireParity, ruleOrphan,
|
||||
ruleFrontendParity, ruleFlatView, ruleBuildArtifact,
|
||||
ruleCodeOwners, ruleDocOwner, ruleDocProse, ruleDocLanguage, ruleReleaseNote,
|
||||
}
|
||||
@@ -197,7 +196,6 @@ func run(root string) ([]Finding, error) {
|
||||
}
|
||||
findings = append(findings, orphans.findings()...)
|
||||
findings = append(findings, checkLayering(imports)...)
|
||||
findings = append(findings, checkSpecParity(root)...)
|
||||
findings = append(findings, checkBuildArtifacts(root)...)
|
||||
findings = append(findings, checkCodeOwners(root)...)
|
||||
findings = append(findings, checkDocs(root)...)
|
||||
|
||||
Reference in new issue
Block a user