@tacrine_f/oh-my-dsh-omo-fork-chs 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -30,6 +30,31 @@ copied modules, `A9`/`A12`/`A13`/`A15` for the licence documents and the patch).
30
30
  **Counts.** The tool now runs **22** structural and license assertions rather than 21, and the test
31
31
  suite totals **56** tests rather than 55.
32
32
 
33
+ ## [0.2.1] — 2026-10-31
34
+
35
+ **What this release is for.** The repository now ships **one** README, in Chinese. `README.md`
36
+ carries the Simplified Chinese text that used to live in `README.zh.md`, so the GitHub landing page
37
+ and the npm package page both open in Chinese — which is what a `-chs` fork should do. The English
38
+ document is **not** retained as a second file: it is gone, and `README.zh.md` is deleted rather than
39
+ left as a pointer, because two files carrying the same content drift apart by construction.
40
+
41
+ This is a **documentation-only** release. No persona prose, no orchestration doctrine, no cordis
42
+ patch, no runtime module and no license term changes. The MIT scope list in `LICENSE-MIT.md`, the
43
+ scope map in `NOTICE.md`, the `files[]` array, and the four scope lists inside
44
+ `tools/check-package.mjs` all lose exactly one entry — `README.zh.md` — because that path no longer
45
+ exists; every other byte of those documents is unchanged.
46
+
47
+ ### Changed
48
+
49
+ - **`README.md` is now the Chinese document.** Its content is the former `README.zh.md`, unchanged
50
+ except for removing `README.zh.md` from the MIT scope list it quotes.
51
+ - **`README.zh.md` is removed.** The nine places that named it were updated in the same commit:
52
+ `README.md`, `package.json` (`files[]`), `LICENSE-MIT.md`, `NOTICE.md`, and five lists in
53
+ `tools/check-package.mjs` (`REQUIRED_FILES`, `ANCHOR_DOCUMENTS`, the machine-local package-name
54
+ predicate chain, `EXPECTED_SCOPE.mit`, `MIT_ANCHORS`). The three mentions in older `CHANGELOG.md` entries are left
55
+ verbatim: they record what was true when those releases shipped, and editing them would falsify
56
+ the history rather than fix anything.
57
+
33
58
  ## [0.2.0] — 2026-10-30
34
59
 
35
60
  **What this release is for.** The 9 subagent rows are migrated from the old
package/LICENSE-MIT.md CHANGED
@@ -2,7 +2,7 @@ MIT License
2
2
 
3
3
  Copyright (c) 2026 Tacrine
4
4
 
5
- Applies to: tools/, test/, .github/, baseline/README.md, package.json, .gitignore, .gitattributes, README.md, README.zh.md, CHANGELOG.md, NOTICE.md.
5
+ Applies to: tools/, test/, .github/, baseline/README.md, package.json, .gitignore, .gitattributes, README.md, CHANGELOG.md, NOTICE.md.
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  of this software and associated documentation files (the "Software"), to deal
package/NOTICE.md CHANGED
@@ -103,7 +103,6 @@ package.json
103
103
  .gitignore
104
104
  .gitattributes
105
105
  README.md
106
- README.zh.md
107
106
  CHANGELOG.md
108
107
  NOTICE.md
109
108
  ```
package/README.md CHANGED
@@ -1,94 +1,88 @@
1
1
  # oh-my-dsh-omo-fork-chs
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@tacrine_f/oh-my-dsh-omo-fork-chs)](https://www.npmjs.com/package/@tacrine_f/oh-my-dsh-omo-fork-chs)
4
- [![license: SUL-1.0 (content) + MIT (packaging)](https://img.shields.io/badge/license-SUL--1.0_(content)_%2B_MIT_(packaging)-orange)](#license)
5
- [![node](https://img.shields.io/badge/node-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-blue)](#peer-model)
6
-
7
- The **Simplified-Chinese unofficial fork** of the `tri-agent` agent preset, packaged for
8
- [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh) as a publishable Cordis
9
- bundle. Its preset id is `omo-fork-chs` and its `order` is `11`, so it sits beside `tri-agent`
10
- rather than replacing it: this package **does not change the default preset** and does not change
11
- which preset a session picks. Only the persona prose is translated; the toolchain composition and
12
- the orchestration doctrine are the upstream design.
13
-
14
- The preset gives an agent a two-mode identity and a full coding toolchain:
15
-
16
- - **Atlas** is the standing orchestrator. It does not implement, verify, or review; it reads the
17
- plan, the notepad and the evidence, does the bookkeeping, and delegates every unit of work to a
18
- named subagent.
19
- - **Prometheus** is the planning doctrine. While a session is in plan mode (`/plan`), the identity
20
- swaps to Prometheus for the whole planning session and then swaps back. A single plugin,
21
- `plan-aware-persona.mjs`, owns the one `deployment:persona-prefix` slot and chooses the text per
22
- assembly by reading the public `plan` session projection. The `planMode` service is deliberately
23
- not injected: it lives inside the `isolate: { planMode: true }` realm, so injecting it from
24
- outside would never resolve.
25
-
26
- Around that identity the preset mounts the coding toolchain: filesystem and shell tools, background
27
- jobs, skills, goals, plan mode, compaction, delegation and workflows. The declaration carries 40
28
- `- id:` rows, of which 9 are anchored subagent rows (explore, librarian, oracle, momus,
29
- multimodal-looker, sisyphus-junior, metis, hephaestus, sisyphus). The package ships **11 persona
30
- files**; the plugin reads `atlas.md` and `prometheus.md` itself, and the other 9 are anchored to the
31
- subagent rows.
32
-
33
- ## What ships
34
-
35
- | File | Purpose |
4
+ [![license: SUL-1.0 (content) + MIT (packaging)](https://img.shields.io/badge/license-SUL--1.0_(content)_%2B_MIT_(packaging)-orange)](#许可)
5
+ [![node](https://img.shields.io/badge/node-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-blue)](#peer-模型)
6
+
7
+ `tri-agent` agent preset 的**简体中文非官方 fork**,面向
8
+ [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh) 打包为可发布的 Cordis bundle。
9
+ 它的 preset id 是 `omo-fork-chs`,`order` 是 `11`,因此它与 `tri-agent` **并存**而不是取而代之:
10
+ 本包**不改变默认 preset**,也不改变会话选中哪一个 preset。只有 persona 正文被翻译;工具链组成与
11
+ 编排 doctrine 都沿用上游设计。
12
+
13
+ 这个 preset 给 agent 一套「双身份 + 完整编码工具链」:
14
+
15
+ - **Atlas** 是常驻的指挥者。它不亲自实现、验证或审查;它读计划、notepad 与证据,做簿记,并把每一个
16
+ 工作单元委派给具名子代理。
17
+ - **Prometheus** 是规划 doctrine。当会话进入 plan 模式(`/plan`)时,身份在整个规划会话期间切换为
18
+ Prometheus,结束后切回。单个插件 `plan-aware-persona.mjs` 占用唯一的 `deployment:persona-prefix`
19
+ 槽位,通过读取公开的 `plan` session projection 在每次装配时选择文本。`planMode` service 被刻意
20
+ **不**注入:它位于 `isolate: { planMode: true }` realm 内部,从外部注入永远不会解析成功。
21
+
22
+ 在身份之外,preset 挂载了编码工具链:文件系统与 shell 工具、后台任务、skills、goals、plan mode、
23
+ compaction、委派与 workflows。该 declaration 共 40 条 `- id:` row,其中 9 条是锚定的子代理 row
24
+ (explore、librarian、oracle、momus、multimodal-looker、sisyphus-junior、metis、hephaestus、
25
+ sisyphus)。本包附带 **11 个 persona 文件**;插件自身读取 `atlas.md` 与 `prometheus.md`,另外 9 个
26
+ 锚定在子代理 row 上。
27
+
28
+ ## 随包内容
29
+
30
+ | 文件 | 用途 |
36
31
  | --- | --- |
37
- | `cordis.patch.yml` | The published bundle patch: the preset declaration (`id: preset-omo-fork-chs`, `config.id: omo-fork-chs`, `config.name: 'Oh My DSH Chs - OMO Fork'`, `order: 11`) and its `plugins:` list. 540 lines, 11 rewritten sites. |
38
- | `plan-aware-persona.mjs` | The package entry that registers the plan-aware persona prefix and the configured suffix. Exported as `./persona`. |
39
- | `index.js` | The package root. It is intentionally empty: the bundle's behaviour lives in `cordis.patch.yml` and in `./persona`. |
40
- | `personas/` | 11 persona documents, translated into Simplified Chinese. |
41
- | `baseline/` | A frozen snapshot of the pre-port patch plus a sidecar that explains what it does and does not prove. |
42
- | `tools/` | The port, verification, baseline and package-check CLIs. |
43
- | `test/` | The zero-dependency test suite, run with `node --test`. |
44
- | `LICENSE-MIT.md` | The MIT terms that cover our own work. |
45
- | `LICENSE-SUL-1.0.md` | The verbatim upstream Sustainable Use License 1.0 terms, which cover the upstream-derived content. |
46
- | `NOTICE.md` | The modification notice, the upstream attribution, and the machine-readable license scope mapping. |
32
+ | `cordis.patch.yml` | 已发布的 bundle patch:preset 声明(`id: preset-omo-fork-chs`、`config.id: omo-fork-chs`、`config.name: 'Oh My DSH Chs - OMO Fork'`、`order: 11`)及其 `plugins:` 列表。共 540 行,11 处被改写。 |
33
+ | `plan-aware-persona.mjs` | 包入口,注册 plan-aware persona 前缀与配置的 suffix。以 `./persona` 导出。 |
34
+ | `index.js` | 包根。它刻意留空:bundle 的行为在 `cordis.patch.yml` 与 `./persona` 里。 |
35
+ | `personas/` | 11 个 persona 文件,已译为简体中文。 |
36
+ | `baseline/` | 移植前 patch 的冻结快照,外加一份说明它能证明什么、不能证明什么的 sidecar。 |
37
+ | `tools/` | 移植、验证、baseline 与包结构检查的命令行工具。 |
38
+ | `test/` | 零依赖测试套件,用 `node --test` 运行。 |
39
+ | `LICENSE-MIT.md` | 覆盖我们自己作品的 MIT 条款。 |
40
+ | `LICENSE-SUL-1.0.md` | 上游 Sustainable Use License 1.0 的逐字副本,覆盖上游衍生内容。 |
41
+ | `NOTICE.md` | 修改声明、上游署名,以及机器可读的许可范围映射。 |
47
42
 
48
- The patch mounts the following peer packages, which DSH provides:
43
+ 该 patch 挂载了下列由 DSH 提供的 peer 包:
49
44
 
50
- `@deepseek-ai/dsh-agent-preset`, `dsh-agent-instructions`, `dsh-tool-bash`, `dsh-tool-pwsh`,
51
- `dsh-tool-fs`, `dsh-tool-fs-search`, `dsh-tool-jobs`, `dsh-skill-filesystem`, `dsh-tool-skill`,
52
- `dsh-command-goal`, `dsh-tool-goal`, `dsh-plan-mode`, `dsh-compaction-basic`, `dsh-command-compact`,
53
- `dsh-compaction-tool-result-pruner`, `dsh-tool-subagent-control`, `dsh-tool-subagent`,
54
- `dsh-workflow-ptc`, `dsh-tool-workflow`, `dsh-tool-ralph`, `dsh-tool-ask-user`, `dsh-tool-todo`,
55
- `dsh-tool-web`, `dsh-tool-present`, plus `@deepseek-ai/cordis`. That is 25 peer dependencies in
56
- total.
45
+ `@deepseek-ai/dsh-agent-preset`、`dsh-agent-instructions`、`dsh-tool-bash`、`dsh-tool-pwsh`、
46
+ `dsh-tool-fs`、`dsh-tool-fs-search`、`dsh-tool-jobs`、`dsh-skill-filesystem`、`dsh-tool-skill`、
47
+ `dsh-command-goal`、`dsh-tool-goal`、`dsh-plan-mode`、`dsh-compaction-basic`、`dsh-command-compact`、
48
+ `dsh-compaction-tool-result-pruner`、`dsh-tool-subagent-control`、`dsh-tool-subagent`、
49
+ `dsh-workflow-ptc`、`dsh-tool-workflow`、`dsh-tool-ralph`、`dsh-tool-ask-user`、`dsh-tool-todo`、
50
+ `dsh-tool-web`、`dsh-tool-present`,外加 `@deepseek-ai/cordis`。合计 25 条 peer 依赖。
57
51
 
58
- ## Install
52
+ ## 安装
59
53
 
60
- Installation is **two explicit steps**. Step 1 installs the dependency; step 2 tells the profile to
61
- load it. Both are required, and `dsh` is not assumed to be on your `PATH`.
54
+ 安装是**两个显式步骤**。第 1 步安装依赖;第 2 步告诉 profile 去加载它。两步都必需,并且不假设
55
+ `dsh` 在 `PATH` 上。
62
56
 
63
- ### Step 1: install the package into the profile
57
+ ### 第 1 步:把包安装进 profile
64
58
 
65
- Point the CLI at your DSH checkout's bin file, and forward the install to the profile:
59
+ 把 CLI 指向你的 DSH checkout 的 bin 文件,并把安装转发给 profile:
66
60
 
67
61
  ```powershell
68
62
  node "<dsh bin>" plugin --profile <profile> add -w @tacrine_f/oh-my-dsh-omo-fork-chs
69
63
  ```
70
64
 
71
- For example, on a checkout whose runtime is `<dsh runtime>`, `<dsh bin>` is
72
- `<dsh runtime>\@deepseek-ai\dsh\lib\bin.js`, so:
65
+ 例如,某个 checkout 的 runtime 是 `<dsh runtime>`,那么 `<dsh bin>` 就是
66
+ `<dsh runtime>\@deepseek-ai\dsh\lib\bin.js`,于是:
73
67
 
74
68
  ```powershell
75
69
  node "<dsh runtime>\@deepseek-ai\dsh\lib\bin.js" plugin --profile web add -w @tacrine_f/oh-my-dsh-omo-fork-chs
76
70
  ```
77
71
 
78
- This runs pnpm inside `$DSH_HOME\profiles\<profile>\`, so it writes a `dependencies` entry. **It
79
- does not touch `dsh.profile.bundles`.**
72
+ 它会在 `$DSH_HOME\profiles\<profile>\` 内运行 pnpm,因此会写入一条 `dependencies` 记录。**它不会
73
+ 改动 `dsh.profile.bundles`。**
80
74
 
81
- ### Step 2: add the package to `dsh.profile.bundles` and restart
75
+ ### 第 2 步:把包加入 `dsh.profile.bundles` 并重启
82
76
 
83
- Open `$DSH_HOME\profiles\<profile>\package.json` and add the package name to the profile's
84
- `dsh.profile.bundles` array:
77
+ 打开 `$DSH_HOME\profiles\<profile>\package.json`,把包名加入该 profile 的 `dsh.profile.bundles`
78
+ 数组:
85
79
 
86
80
  ```jsonc
87
81
  {
88
82
  "dsh": {
89
83
  "profile": {
90
84
  "bundles": [
91
- // ...your existing bundles...
85
+ // ...你已有的 bundle...
92
86
  "@tacrine_f/oh-my-dsh-omo-fork-chs"
93
87
  ]
94
88
  }
@@ -96,32 +90,28 @@ Open `$DSH_HOME\profiles\<profile>\package.json` and add the package name to the
96
90
  }
97
91
  ```
98
92
 
99
- Then **restart the Host and start a new session.** A live agent keeps the composition it booted
100
- with, so an already-running session will not pick the preset up; a new session is required.
93
+ 然后**重启 Host 并新开一个会话。** 正在运行的 agent 保留它启动时的 composition,所以已经跑着的会话
94
+ 不会加载这个 preset;必须新开会话。
101
95
 
102
- ### Verify the install composed
96
+ ### 验证安装已生效
103
97
 
104
98
  ```powershell
105
99
  $env:DSH_HOME = "<dsh home>"
106
100
  node "<dsh bin>" --profile <profile> --dump-config
107
101
  ```
108
102
 
109
- The output should contain a `preset-omo-fork-chs` row whose `name` is
110
- `@deepseek-ai/dsh-agent-preset`, whose `config.id` is `omo-fork-chs`, whose `config.name` is
111
- `'Oh My DSH Chs - OMO Fork'` and whose `config.order` is `11`, plus nine `personas` expressions
112
- resolving through this package. `--dump-config` prints the raw `!!js` expression text, so the nine
113
- anchors appear as the `resolve('<pkg>/package.json')` form rather than as resolved filesystem
114
- paths.
103
+ 输出中应当有一条 `preset-omo-fork-chs` row,其 `name` 为 `@deepseek-ai/dsh-agent-preset`,
104
+ `config.id` 为 `omo-fork-chs`,`config.name` 为 `'Oh My DSH Chs - OMO Fork'`,`config.order` 为
105
+ `11`,另有九条经由本包解析的 `personas` 表达式。`--dump-config` 打印的是原始 `!!js` 表达式文本,
106
+ 所以那九条锚点呈现为 `resolve('<pkg>/package.json')` 形式,而不是解析后的文件系统路径。
115
107
 
116
- ## Post-install edits you may need
108
+ ## 安装后你可能需要自己做的改动
117
109
 
118
- The published patch ships **only** the portable preset declaration. Two things that were local to
119
- the machine this fork came from are deliberately **not** shipped, so you may want to re-add them
120
- yourself:
110
+ 已发布的 patch **只**包含可移植的 preset 声明。有两样东西原本属于产出这个 fork 的那台机器,它们被
111
+ 刻意**不**发布,因此你可能想自己把它们加回去:
121
112
 
122
- 1. **Making `omo-fork-chs` your default preset.** The published patch does **not** set a default
123
- preset, and this package never forces one. If you want this preset to be the default, set the
124
- registry row yourself in your own profile or overlay patch:
113
+ 1. **把 `omo-fork-chs` 设成默认 preset。** 已发布的 patch **不**设置默认 preset,本包也从不强加
114
+ 一个。如果你希望它成为默认,请在你自己的 profile 或 overlay patch 里自行设置 registry row:
125
115
 
126
116
  ```yaml
127
117
  - id: agent-preset-registry
@@ -129,259 +119,202 @@ yourself:
129
119
  default: omo-fork-chs
130
120
  ```
131
121
 
132
- (`@deepseek-ai/dsh-web-app` inserts that row with `default: standard`; the row above replaces the
133
- whole config, so only the default changes.)
122
+ (`@deepseek-ai/dsh-web-app` 会插入同一条 row,但 `default: standard`;上面这条会替换整个
123
+ config,所以只有 default 改变。)
134
124
 
135
- 2. **Giving `subagent_multimodal_looker` a model route.** The bundle this fork was derived from
136
- carried a machine-specific `provider` and `model` route for that row, and that route is **not
137
- portable**, so the published patch carries no `agentOptions` row at all. Without one the
138
- multimodal subagent inherits the deployment's route. To pin one, add an `agentOptions` block to
139
- that row in your own overlay:
125
+ 2. **给 `subagent_multimodal_looker` 一条模型路由。** 产出这个 fork 的 bundle 曾为那条 row 带一条
126
+ 机器专属的 `provider` 与 `model` 路由,而那条路由**不可移植**,所以已发布的 patch 完全不包含
127
+ `agentOptions` row。没有它时,多模态子代理会继承 deployment 的路由。若要固定一条,请在你自己的
128
+ overlay 里给那条 row 加一个 `agentOptions` 块:
140
129
 
141
130
  ```yaml
142
131
  - id: tool-subagent-multimodal-looker
143
132
  name: '@deepseek-ai/dsh-tool-subagent'
144
133
  config:
145
- # ...the shipped config...
134
+ # ...已发布的 config...
146
135
  agentOptions:
147
136
  provider: <your provider>
148
137
  model: <your model>
149
138
  ```
150
139
 
151
- ## Failure mode: it fails loud on purpose
140
+ ## 失败模式:刻意 fail loud
152
141
 
153
- `plan-aware-persona.mjs` reads its persona prose from disk at mount time. A **missing or empty
154
- persona file fails the mount**, naming the file in the error:
142
+ `plan-aware-persona.mjs` 在挂载时从磁盘读取自己的 persona 正文。**persona 文件缺失或为空会让挂载
143
+ 失败**,并在错误里点出文件名:
155
144
 
156
145
  ```
157
146
  plan-aware-persona: cannot read persona "file:///.../personas/atlas.md"
158
147
  plan-aware-persona: persona "file:///.../personas/atlas.md" is empty
159
148
  ```
160
149
 
161
- That is deliberate. An empty persona prefix would silently strip the agent's identity, so a mount
162
- error that names the file is far easier to act on than an agent that quietly lost its instructions.
150
+ 这是刻意的。空的 persona 前缀会悄悄剥掉 agent 的身份,所以一条点出文件名的挂载错误,远比一个安静地
151
+ 丢掉自己指令的 agent 更容易处理。
163
152
 
164
- ## Peer model
153
+ ## Peer 模型
165
154
 
166
- Every `@deepseek-ai/*` package the patch mounts is declared as a **`peerDependency`**, never as a
167
- regular `dependency`. DSH provides them; the bundle must not install its own copies. Peer ranges are
168
- declared as `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`, which keeps the
169
- 0.1.7 line and adds the 0.2 line (and `@deepseek-ai/cordis` as `^4.0.1`). The package declares 25
170
- peers and **no** runtime dependencies and **no** dev dependencies, so nothing has to be installed
171
- for the tests or for the zero-dependency part of the check chain.
155
+ patch 挂载的每个 `@deepseek-ai/*` 包都声明为 **`peerDependency`**,而不是普通 `dependency`。它们由
156
+ DSH 提供;bundle 不得安装自己的副本。peer 范围声明为
157
+ `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`,既保留 0.1.7 线,又加入
158
+ 0.2 线(`@deepseek-ai/cordis` 为 `^4.0.1`)。本包声明 25 条 peer,且**没有**运行期依赖、**没有**开发依赖,因此测试与检查链中零依赖
159
+ 的那部分都不需要安装任何东西。
172
160
 
173
- The DSH profile's `.npmrc` sets `auto-install-peers=false`, so these peers are **declarative only**:
174
- pnpm will not fetch them, and a missing peer surfaces as a resolution error at mount time rather
175
- than being silently installed.
161
+ DSH profile 的 `.npmrc` 设置了 `auto-install-peers=false`,所以这些 peer 是**纯声明式**的:pnpm 不会
162
+ 去拉取它们,缺失的 peer 会在挂载时表现为解析错误,而不是被悄悄装上。
176
163
 
177
- ## Verification
164
+ ## 验证
178
165
 
179
- Everything below runs from the repository root with **no install**, except `check:full`, which needs
180
- a runtime and is marked as such.
166
+ 下面全部在仓库根目录运行,且**无需安装**,只有 `check:full` 例外,它需要 runtime,并已如此标注。
181
167
 
182
168
  ```powershell
183
- # 1. The test suite. Zero dependencies. 56 tests.
169
+ # 1. 测试套件。零依赖。56 个测试。
184
170
  npm run test
185
171
 
186
- # 2. The check chain. Zero dependencies, no runtime needed.
172
+ # 2. 检查链。零依赖,不需要 runtime。
187
173
  npm run check
188
174
 
189
- # 3. The same check with the deep YAML comparison enabled. Needs a runtime.
175
+ # 3. 同一条检查,但启用 YAML 深比较。需要 runtime。
190
176
  npm run setup:verify
191
177
  $env:DSH_RUNTIME = "<absolute path to a node_modules holding js-yaml and @deepseek-ai/cordis-plugin-include>"
192
178
  npm run check:full
193
179
 
194
- # 4. Regenerate the frozen baseline from the published patch and check it.
180
+ # 4. 从已发布的 patch 重新推导冻结的 baseline 并检查它。
195
181
  npm run baseline
196
182
  npm run baseline -- --check
197
183
 
198
- # 5. Re-port the published patch from a source patch directory.
184
+ # 5. 从某个源 patch 目录重新移植已发布的 patch。
199
185
  npm run port -- --src <dir holding cordis.patch.yml>
200
186
  ```
201
187
 
202
- What each one proves:
203
-
204
- - **`npm run test`** runs the `node:test` suite: the three forward rewrites, the inverse rewrites
205
- and their round trip, the argument parsers, the machine-path pattern from both sides, the
206
- zero-byte guard, and the package check's negative paths. It is 56 tests and it needs nothing
207
- installed.
208
- - **`npm run check`** is `node tools/check-package.mjs && node tools/verify-patch.mjs`. The first
209
- runs 22 structural and license assertions (manifest identity, the four `exports`, the single
210
- self-reference row, the nine persona anchors and their files, the `files[]` coverage, the eleven
211
- persona byte counts, the license pointers, the three license documents, the paths that must never
212
- ship, the untracked-file check over every directory `files[]` lists and the untracked root files
213
- npm auto-includes, the upstream fingerprint
214
- when one is supplied, the modification-notice claims, the license scope mapping and the per-entry
215
- anchors
216
- that pin each scope block to the content it claims, the machine-path
217
- scan and the classes that govern where the pre-port package name may appear, the SHA256 of the
218
- two modules the package copies out of this repository, the internal markdown anchors of every
219
- document that carries one, and the patch's
220
- shape). The second proves the published patch
221
- still equals what the three documented rewrites compute from the frozen baseline, and reports
222
- `verdict: "IDENTICAL"` with 11 rewrite sites. Both are **zero-dependency**, so they pass in a
223
- clean clone with no install.
224
- - **`npm run check:full`** is `node tools/verify-patch.mjs` on its own. With `DSH_RUNTIME` pointing
225
- at an absolute `node_modules` that holds `js-yaml` and `@deepseek-ai/cordis-plugin-include`, the
226
- verifier parses both documents with the real entry-list dialect and compares them structurally,
227
- reporting `yamlCompare: "ok"` and `sites.length` of 11. **Without a runtime it reports
228
- `yamlCompare: "skipped"` and still exits 0**, which is why the exit code alone is not evidence
229
- here: assert on the field. That is also why this step is separate from `check`, and why
230
- `npm run setup:verify` exists: it installs the runtime into `.dsh-verify/` without adding a
231
- dependency to this package. The tool reads `DSH_RUNTIME` itself rather than taking a `--runtime`
232
- flag, because Windows npm runs scripts through `cmd.exe` and POSIX shells expand variables
233
- differently, so one script string would behave differently on the two platforms.
234
- - **`npm run baseline`** re-derives `baseline/cordis.patch.yml` from the published patch by
235
- applying the inverse of the three rewrites, and `-- --check` compares the committed baseline
236
- against a freshly derived copy, printing the differing lines and exiting non-zero on drift.
237
- - **`npm run port -- --src <dir>`** applies the three rewrites to the `cordis.patch.yml` in `<dir>`
238
- and writes the result. `--src` has **no default**, because the only honest default would be a
239
- machine-local directory; the error message names the baseline directory as the alternative
240
- source, and `npm run port -- --src baseline` reproduces the committed patch byte for byte.
241
-
242
- > **`npm run check` and `npm test` must run inside a git checkout.** Three of the package check's
243
- > assertions (the license scope
244
- > mapping, the machine-path scan, and the classes that govern where the pre-port package name may
245
- > appear) are defined over the set of **tracked**
246
- > files, so the tool asks `git ls-files` for that set. If git cannot answer, the tool fails with
247
- > `run inside a git checkout` rather than silently skipping those three. `npm test` needs the same
248
- > checkout for the same reason: its last case runs the package check against the real tree, so
249
- > unpacking the tarball outside a repository fails there too. A consumer who unpacks the
250
- > published tarball outside a repository will therefore see that error, and it is deliberate: a
251
- > mapping check that reports success for work it never did is worse than no check at all. The
252
- > published package includes the tools and the test suite so the chain can be re-run from a clone.
253
-
254
- > **Counting a document's lines in PowerShell: `Measure-Object -Line` counts non-empty lines
255
- > only.** `(Get-Content README.md | Measure-Object -Line).Lines` reports **311** for this file,
256
- > while `(Get-Content README.md).Count` reports **374** — the same file, two readings, and the
257
- > difference is 63 blank lines that the first command never saw. Nothing in the command's name or
258
- > output says so, so a length check built on it silently under-counts any file with blank lines in
259
- > it. Use `.Count`, or `[IO.File]::ReadAllLines(path).Count`, when you want the raw line count. The
260
- > same trap has already produced wrong readings of a plan file in this repository twice, from two
261
- > separate contributors, because the two numbers look equally plausible when you have not measured
262
- > both.
263
-
264
- ## License
265
-
266
- This repository is **dual-licensed**, and the two licenses are not alternatives you may choose
267
- between: each file is covered by exactly one of them. It is **not** MIT-only.
268
-
269
- The scope mapping, matching the two blocks in [`NOTICE.md`](./NOTICE.md):
270
-
271
- - [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md) covers the upstream-derived content:
272
- `personas/`, `cordis.patch.yml`, `plan-aware-persona.mjs`, `index.js` and
273
- `baseline/cordis.patch.yml`.
274
- - [`LICENSE-MIT.md`](./LICENSE-MIT.md) covers our own work: `tools/`, `test/`, `.github/`,
275
- `baseline/README.md`, `package.json`, `.gitignore`, `.gitattributes`, `README.md`, `README.zh.md`,
188
+ 每一条各自证明什么:
189
+
190
+ - **`npm run test`** 运行 `node:test` 套件:三组正向改写、反向改写及其往返、参数解析器、从两侧检验
191
+ 机器路径模式、零字节守卫,以及包检查的失败路径。共 56 个测试,不需要安装任何东西。
192
+ - **`npm run check`** 是 `node tools/check-package.mjs && node tools/verify-patch.mjs`。前者运行 22 条
193
+ 结构与许可断言(manifest 身份、四个 `exports`、唯一一条自引用 row、九条 persona 锚点及其文件、
194
+ `files[]` 覆盖、11 个 persona 的字节数、许可指针、三份许可文档、绝不允许进入 tarball 的路径,
195
+ 对 `files[]` 所列每个目录的未跟踪文件检查,以及 npm 无论 `files[]` 如何都会自动收录的根目录文件、
196
+ 提供了上游指纹时的比对、
197
+ 修改声明的各项主张、许可范围映射及逐条把每个范围块钉到其所声明内容的锚点、机器路径扫描、
198
+ 约束移植前包名出现位置的类、本仓库向消费者复制的两个模块的 SHA256、
199
+ 每份带内部锚点的文档中锚点是否都能解析到标题,以及 patch 的形状)。
200
+ 后者证明已发布的 patch 仍然等于三项已记录改写从冻结 baseline 算出的结果,并报告
201
+ `verdict: "IDENTICAL"` 与 11 处改写点。两者都**零依赖**,因此在干净克隆里、无需安装即可通过。
202
+ - **`npm run check:full`** 就是单独运行 `node tools/verify-patch.mjs`。当 `DSH_RUNTIME` 指向一个包含
203
+ `js-yaml` 与 `@deepseek-ai/cordis-plugin-include` 的绝对 `node_modules` 时,校验器会用真正的
204
+ entry-list dialect 解析两份文档并做结构化比对,报告 `yamlCompare: "ok"` 与 `sites.length` 为 11。
205
+ **没有 runtime 时它报告 `yamlCompare: "skipped"` 并仍然以 0 退出**,所以在这里只看退出码不算证据:
206
+ 必须断言字段。这也是为什么这一步与 `check` 分开,以及为什么存在 `npm run setup:verify`:它把
207
+ runtime 装进 `.dsh-verify/`,而不给本包增加依赖。该工具自己读取 `DSH_RUNTIME`,而不是接受一个
208
+ `--runtime` flag,因为 Windows 上 npm 通过 `cmd.exe` 运行脚本,而 POSIX shell 会展开变量,同一个
209
+ 脚本字符串在两个平台上的行为会不同。
210
+ - **`npm run baseline`** 通过对三项改写施加逆变换,从已发布的 patch 重新推导出
211
+ `baseline/cordis.patch.yml`;`-- --check` 把已提交的 baseline 与一份新推导出的副本比对,打印出差异行
212
+ 并在出现漂移时以非零退出。
213
+ - **`npm run port -- --src <dir>`** 对 `<dir>` 里的 `cordis.patch.yml` 施加三项改写并写出结果。
214
+ `--src` **没有默认值**,因为唯一诚实的默认值会是一个机器专属目录;错误消息把 baseline 目录作为
215
+ 替代来源点出来,而 `npm run port -- --src baseline` 会逐字节复现已提交的 patch。
216
+
217
+ > **`npm run check` 与 `npm test` 都必须在 git checkout 内运行。** 包检查的三条断言(许可范围映射、
218
+ > 机器路径扫描,以及约束
219
+ > 移植前包名出现位置的类)都定义在**受版本跟踪的**文件集合之上,所以该工具向 `git ls-files` 索取这个
220
+ > 集合。如果 git 无法回答,工具会以 `run inside a git checkout` 失败,而不是悄悄跳过这三条。`npm test`
221
+ > 出于同样的原因也需要检出:它的最后一个用例会针对真实目录树运行包检查,所以在仓库之外解包同样会失败。
222
+ > 因此,
223
+ > 在仓库之外解包已发布 tarball 的使用者会看到这个错误,而这是刻意的:一条对从未做过的工作报告成功的
224
+ > 映射检查,比没有检查更糟。已发布的包里包含这些工具与测试套件,所以这条链可以从克隆里重跑。
225
+
226
+ ## 许可
227
+
228
+ 本仓库是**双许可**的,且两个许可不是你可以二选一的关系:每个文件都恰好被其中一个覆盖。它**不是**
229
+ 仅 MIT。
230
+
231
+ 范围映射与 [`NOTICE.md`](./NOTICE.md) 中的两个块一致:
232
+
233
+ - [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md) 覆盖上游衍生内容:`personas/`、`cordis.patch.yml`、
234
+ `plan-aware-persona.mjs`、`index.js` 与 `baseline/cordis.patch.yml`。
235
+ - [`LICENSE-MIT.md`](./LICENSE-MIT.md) 覆盖我们自己的作品:`tools/`、`test/`、`.github/`、
236
+ `baseline/README.md`、`package.json`、`.gitignore`、`.gitattributes`、`README.md`、
276
237
  `CHANGELOG.md`
277
- and `NOTICE.md`.
278
- - [`NOTICE.md`](./NOTICE.md) is the authoritative declaration: the modification notice, the upstream
279
- attribution, and the machine-readable scope mapping, including the match rule that decides which
280
- block covers each tracked path. In any disagreement between this README and `NOTICE.md`, the
281
- notice wins.
282
-
283
- The upstream terms are the **Sustainable Use License 1.0**, held verbatim in
284
- [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md). SUL-1.0 is a **source-available** license. It is
285
- **not** an OSI-approved open source license, and this repository does not claim otherwise.
286
-
287
- The upstream terms permit use, copying, distribution and derivative works only for your own
288
- internal business purposes, or for non-commercial or personal use, and they permit distribution
289
- only if you do so **free of charge** and for **non-commercial** purposes. This package is
290
- distributed under exactly those terms: free of charge, non-commercial, and not for resale. The
291
- upstream license is **not sublicensable**, which is why the MIT license covering our own files
292
- cannot be extended over the upstream-derived ones, and why `LICENSE-SUL-1.0.md` must travel with
293
- every copy.
294
-
295
- One carve-out applies to the MIT scope: the files under `tools/` and `test/` are our own work and
296
- are licensed under MIT, but they embed verbatim fragments of the upstream bundle patch expressions,
297
- quoted so that the patch can be generated and verified. Those **quoted fragments** remain subject to
298
- the upstream SUL-1.0 terms and are not relicensed by the MIT license that covers the surrounding
299
- code. The same carve-out is stated in `NOTICE.md`, and the two documents agree.
300
-
301
- This repository is an **unofficial fork**. It is **not affiliated** with, endorsed by, or sponsored
302
- by the upstream project or its author, and nothing here implies any affiliation or endorsement.
303
- Upstream names and trademarks belong to their owners.
304
-
305
- ## Known issues
306
-
307
- - **This version requires DSH ≥ 0.2.2.** The 0.2.0 patch selects each of the 9
308
- subagent presets with `agentPreset`, a field that only the 0.2.2
309
- `dsh-tool-subagent` reads; 0.2.2 also removed the `persona` and `toolFilter`
310
- fields the old rows used. On DSH 0.2.1 and earlier the rows still mount, but
311
- `agentPreset` is accepted and then never read (the schema merges unknown keys
312
- instead of rejecting them), so the child gets **no persona and no tool
313
- restriction** and inherits the parent's full toolset: a read-only child such as
314
- explore or oracle would silently gain write and subagent-spawning tools. That is
315
- a silent privilege escalation, not a mount failure. The declared peer range
316
- below still admits older 0.2.x builds, so this is a functional requirement
317
- rather than a semver constraint. Verified on `0.2.2-alpha.2`; do not run this
318
- version on DSH older than 0.2.2.
319
- - **The declared peer range covers the 0.1.7 line and the 0.2 line. The range check was verified on two 0.2.x builds, but `0.2.1-alpha.1` only with the 0.1.x patch.** The 24
320
- `@deepseek-ai/dsh-*` peers are declared as
321
- `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`, which keeps the range this
322
- fork inherited from upstream and adds the 0.2 line. The host decides compatibility with a semver
323
- range check over those peers, evaluating prereleases, so the range accepts `0.2.0`,
324
- `0.2.1-alpha.1` and the later prerelease `0.2.2-beta`, and rejects `0.3.0-alpha.1`.
325
- **Verified by experiment on `0.2.1-alpha.1` (0.1.x patch only) and `0.2.2-alpha.2` (this patch)**: with
326
- no exemption present in the profile, a config dump of this package exits 0, writes **0 bytes to
327
- stderr**, and carries the preset with all nine persona anchors; the `0.2.2-alpha.2` run was against
328
- a profile that registers this package as a bundle. That is a claim about the mount and the anchor
329
- paths, not about the personas' bytes and not about the preset's behaviour: no agent was invoked,
330
- and a persona that still existed but had been truncated would pass the same check.
331
- **`0.3.0-alpha.1` is the re-entry condition**: a future runtime in that range is rejected again,
332
- with the same incompatibility warning on stderr and the same exit 0, so the failure stays silent
333
- unless you read stderr. On such a version you must either run a dsh inside the declared range, or
334
- grant the exact-version exemption with
335
- `dsh plugin allow-version "<pkg>@<version>" --dsh-version <version> --accept-risk`. That exemption
336
- is the host's own escape hatch and carries the risk the host itself warns about, so it is a
337
- deliberate acceptance of risk rather than a supported configuration. **It is still needed for cases
338
- this widening does not cover**: the published `0.1.0` on npm carries the old narrower range, and any
339
- future 0.3.x runtime will need it. `@deepseek-ai/cordis` is declared at `^4.0.1` as well, but the
340
- host never tests it — it only evaluates peers named `@deepseek-ai/dsh` or `@deepseek-ai/dsh-*` —
341
- so that entry is not a compatibility constraint the host enforces.
342
- - **`baseline/` proves reproducibility, not correctness.** The baseline is a frozen snapshot of the
343
- pre-port patch, committed so the round trip can be checked anywhere. It is byte-identical to the
344
- source patch, and the derivation proves the port is **reproducible**: the published patch and the
345
- baseline are related by exactly the three documented rewrites and nothing else. It does **not**
346
- prove the content is correct. If the source patch had been wrong, the derivation would faithfully
347
- reproduce that wrongness and every check here would still pass.
348
- - **The prior evidence for content correctness is not shipped.** That evidence is the
349
- `omo-fork-chs-*` evidence set produced by the Simplified-Chinese port work, whose
350
- `verify-omo-fork-chs-bundle` checker reported **`FAITHFUL`** and whose `verify-omo-fork-chs-deport`
351
- checker reported **`CLEAN`**. Those checkers are **machine-local**: they run against directories
352
- that exist only on the machine the port was prepared on, and they are deliberately not shipped
353
- with this package.
354
- - **The vendored persona prose carries machine-local paths.** Ten lines across three persona
355
- documents name absolute paths from the machine the localization work was done on. They violate
356
- this repository's rule that no committed file names a machine absolute path, and they are
357
- tolerated only because byte identity with the source bundle is the harder constraint. The affected
358
- lines are enumerated in `tools/check-package.mjs`, whose scan accepts a match only at those exact
359
- positions. `NOTICE.md` records this as modification entry 8. The paths are not reproduced here
360
- because this document is itself covered by that scan.
361
- - **This repository coexists with the English fork.** `Tacrine/oh-my-dsh-omo-fork` is a separate
362
- repository with its own package, its own preset id and its own scope mapping. Neither repository
363
- affects the other: they share the upstream lineage, and nothing in this package reads, writes or
364
- depends on the other one.
365
- - **0.1.0 is the first release of this repository; no earlier version was published.** This package
366
- has no predecessor on npm, so there is no older artifact to compare against and no upgrade path
367
- from one.
368
-
369
- ## Lineage
370
-
371
- This package descends from the Simplified-Chinese agent-preset bundle, which lived as a **link
372
- install**: a private dependency wired into one machine's DSH profile, pointing at a local directory.
373
- That form cannot be installed anywhere else, because its patch named a machine-local package and its
374
- persona anchors resolved relative to the profile directory.
375
-
376
- This repository turns that bundle into an **npm-installable** form. The three documented rewrites do
377
- the work: the package self-reference and the nine persona path anchors are re-pointed at this
378
- package's own name and its `package.json`, and the header comment follows. The result is a patch
379
- that resolves in any install layout, a frozen baseline that makes the round trip checkable without
380
- the original machine, and a check chain that proves the published patch still matches the source it
381
- was derived from.
382
-
383
- The upstream project is **oh-my-openagent**, formerly published as **oh-my-opencode**
384
- (https://github.com/code-yeongyu/oh-my-openagent). The content in this repository is derived from
385
- upstream commit `3c711483856207ef530c09d062fa9077c225debbe`, which carries upstream version **5.0.1**.
386
- The persona prose, the toolchain composition and the plugin are the upstream design; this fork's
387
- contribution is the translation into Simplified Chinese and the packaging split.
238
+ 与 `NOTICE.md`。
239
+ - [`NOTICE.md`](./NOTICE.md) 是权威声明:修改声明、上游署名,以及机器可读的许可范围映射,其中包含
240
+ 决定每个受跟踪路径归哪个块的匹配规则。若本 README 与 `NOTICE.md` 有任何不一致,以 NOTICE 为准。
241
+
242
+ 上游条款是 **Sustainable Use License 1.0**,逐字保存在
243
+ [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md) 中。SUL-1.0 是一个 **source-available** 许可。它
244
+ **不是** OSI 批准的开源许可,本仓库也不作此主张。
245
+
246
+ 上游条款只允许你为自己的内部业务目的,或为非商业、个人用途,去使用、复制、分发和制作衍生作品;
247
+ 并且只允许你在**免费**且**非商业**的前提下分发。本包正是按这些条款分发:免费、非商业、不可转售。
248
+ 上游许可是**不可再授权**的,这就是为什么覆盖我们自己文件的 MIT 许可无法延伸到上游衍生的文件之上,
249
+ 也是为什么 `LICENSE-SUL-1.0.md` 必须随每一份副本一起传播。
250
+
251
+ MIT 范围上有一条界定:`tools/` 与 `test/` 下的文件是我们自己的作品、按 MIT 授权,但它们内嵌了上游
252
+ bundle patch 表达式的**逐字片段**,以便生成和校验该 patch。那些**逐字片段**仍受上游 SUL-1.0 条款
253
+ 约束,并不会因为周围代码适用 MIT 而被重新授权。同一条界定也写在 `NOTICE.md` 里,两份文档一致。
254
+
255
+ 本仓库是一个**非官方 fork**。它**未获**上游项目及其作者的背书、赞助或关联,这里也没有任何内容暗示
256
+ 存在关联或背书。上游名称与商标归其所有者所有。
257
+
258
+ ## 已知问题
259
+
260
+ - **本版本要求 DSH ≥ 0.2.2。** 0.2.0 patch 用 `agentPreset` 为 9 个子代理各选一个 preset,
261
+ 而这个字段只有 0.2.2 的 `dsh-tool-subagent` 才会读取;0.2.2 同时移除了旧行使用的 `persona`
262
+ 与 `toolFilter` 字段。在 DSH 0.2.1 及更早版本上,这些行**照常挂载**,但 `agentPreset` 只是被
263
+ 接受、随后从不被读取(schema 会合并未知键而不是拒绝它),于是子代理**既没有 persona,也没有
264
+ 任何工具限制**,直接继承父代理的全部工具集:像 explore 或 oracle 这样的只读子代理会静默获得
265
+ 写文件与派生子代理的能力。这是**静默提权,不是挂载失败**。下面声明的 peer 范围仍然放行更旧的
266
+ 0.2.x 构建,所以这是一条功能性要求,而不是 semver 约束。已于 `0.2.2-alpha.2` 验证;请不要在
267
+ 低于 0.2.2 的 DSH 上运行本版本。
268
+ - **声明的 peer 范围覆盖 0.1.7 线与 0.2 线。范围检查在两个 0.2.x 构建上验证过,但 `0.2.1-alpha.1` 只验证过 0.1.x 的 patch。** 24 个
269
+ `@deepseek-ai/dsh-*` peer 声明为
270
+ `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`,既保留本 fork 从上游继承的
271
+ 范围,又加入 0.2 线。宿主用一个 semver 范围检查来判定这些 peer 是否兼容,并且会把预发布版本纳入比较,
272
+ 因此该范围接受 `0.2.0`、`0.2.1-alpha.1` 与更晚的预发布版本 `0.2.2-beta`,而拒绝 `0.3.0-alpha.1`。
273
+ **已用实验在 `0.2.1-alpha.1`(仅 0.1.x 的 patch)与 `0.2.2-alpha.2`(本 patch)上验证**:在 profile 中不存在任何
274
+ 豁免的情况下,对本包做 config dump 会以 0 退出、向 **stderr 写入 0 字节**,并在 dump 中带上该 preset 与
275
+ 全部九条 persona 锚点;其中 `0.2.2-alpha.2` 这次运行针对的是把本包注册为 bundle 的 profile。这证明的是
276
+ 挂载与锚点路径,而不是 persona 的字节内容,也不是 preset 的行为:本次验证没有调用任何 agent,
277
+ 一个仍然存在但已被截断的 persona 同样会通过这项检查。
278
+ **`0.3.0-alpha.1` 是重新触发的条件**:将来的运行时一旦落在该范围内就会再次被拒,stderr 上出现同样的
279
+ 不兼容警告,退出码同样是 0,所以除非去看 stderr,这个失败仍然是静默的。在这类版本上,你必须要么使用
280
+ 落在声明范围内的 dsh,要么用
281
+ `dsh plugin allow-version "<pkg>@<version>" --dsh-version <version> --accept-risk` 授予精确版本
282
+ 豁免。该豁免是宿主自带的逃生舱,并带有宿主自己警告过的风险,因此它是对风险的刻意接受,而不是受支持的
283
+ 配置。**对于本次放宽没有覆盖的情形,它仍然是必需的**:npm 上已发布的 `0.1.0` 携带的是旧的、更窄的范围,
284
+ 而将来任何 0.3.x 运行时也都需要它。`@deepseek-ai/cordis` 同样声明为 `^4.0.1`,但宿主从不检查它——
285
+ 宿主只评估名为 `@deepseek-ai/dsh` 或以 `@deepseek-ai/dsh-` 开头的 peer——所以那一条并不是宿主会执行的
286
+ 兼容性约束。
287
+ - **`baseline/` 证明的是可复现,而不是正确。** baseline 是移植前 patch 的冻结快照,提交它是为了让往返
288
+ 校验在任何地方都能跑。它与源 patch 逐字节一致,而这次推导证明移植是**可复现**的:已发布的 patch 与
289
+ baseline 之间恰好由三项已记录改写相连,别无其他。它**不**证明内容正确。如果源 patch 本身是错的,
290
+ 这次推导会忠实复现那份错误,而这里所有检查依然会通过。
291
+ - **内容正确性的既有证据不随包发布。** 那份证据是简体中文移植工作产出的 `omo-fork-chs-*` 证据集,其中
292
+ `verify-omo-fork-chs-bundle` 校验器报告 **`FAITHFUL`**,`verify-omo-fork-chs-deport` 校验器报告
293
+ **`CLEAN`**。这些校验器是**机器相关**的:它们针对只存在于移植准备机器上的目录运行,并且刻意不随本包
294
+ 发布。
295
+ - **内嵌的 persona 正文带有机器本地路径。** 三份 persona 文档中一共十行写出了本地化工作所在机器上的
296
+ 绝对路径。它们违反了本仓库「任何提交的文件都不得写出机器绝对路径」的规则,之所以被容忍,只是因为与
297
+ 源 bundle 的字节一致性是更硬的约束。受影响的那些行在 `tools/check-package.mjs` 中逐条列举,该扫描
298
+ 只在这些确切位置接受匹配。`NOTICE.md` 把这件事记为修改条目 8。本文档不复制那些路径,因为它本身也
299
+ 在该扫描的覆盖范围内。
300
+ - **本仓库与英文 fork 并存。** `Tacrine/oh-my-dsh-omo-fork` 是一个独立仓库,有自己的包、自己的
301
+ preset id 和自己的范围映射。两个仓库互不影响:它们共享上游血缘,而本包中没有任何内容读取、写入或
302
+ 依赖另一个。
303
+ - **0.1.0 是本仓库的首次发布,此前没有任何版本发布过。** 本包在 npm 上没有前身,因此没有更早的产物可
304
+ 供对照,也不存在从旧版本升级的路径。
305
+
306
+ ## 源流
307
+
308
+ 本包源自那份简体中文 agent-preset bundle,它当时以 **link 安装**的形态存在:一个接入某台机器 DSH
309
+ profile 的私有依赖,指向一个本地目录。那种形态无法安装到别处,因为它的 patch 写出的是机器本地的包名,
310
+ 而它的 persona 锚点是相对于 profile 目录解析的。
311
+
312
+ 本仓库把那份 bundle 变成**可从 npm 安装**的形态。三项已记录改写完成了这件事:包自引用与九条 persona
313
+ 路径锚点被重新指向本包自己的名字及其 `package.json`,头部注释随之更新。结果是一个在任何安装布局下都能
314
+ 解析的 patch、一份让往返校验不再需要原机器的冻结 baseline,以及一条证明已发布 patch 仍等于其来源的
315
+ 检查链。
316
+
317
+ 上游项目是 **oh-my-openagent**,曾以 **oh-my-opencode** 之名发布
318
+ (https://github.com/code-yeongyu/oh-my-openagent)。本仓库中的内容派生自上游 commit
319
+ `3c711483856207ef530c09d062fa9077c225debbe`,该 commit 对应上游版本 **5.0.1**。persona 正文、
320
+ 工具链组成与插件都沿用上游设计;本 fork 的贡献是简体中文翻译与打包拆分。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tacrine_f/oh-my-dsh-omo-fork-chs",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "description": "The unofficial Simplified Chinese fork of the tri-agent agent preset (Atlas orchestration plus Prometheus planning), packaged for DeepSeek Harness as a Cordis bundle; the vendored upstream content is licensed under SUL-1.0.",
6
6
  "type": "module",
@@ -17,7 +17,6 @@
17
17
  "personas/",
18
18
  "cordis.patch.yml",
19
19
  "README.md",
20
- "README.zh.md",
21
20
  "CHANGELOG.md",
22
21
  "LICENSE-MIT.md",
23
22
  "LICENSE-SUL-1.0.md",
@@ -70,7 +70,7 @@ import { pathToFileURL } from 'node:url'
70
70
  /** The package identity this repository is expected to publish under. */
71
71
  const EXPECTED = {
72
72
  name: '@tacrine_f/oh-my-dsh-omo-fork-chs',
73
- version: '0.2.0',
73
+ version: '0.2.1',
74
74
  license: 'SEE LICENSE IN NOTICE.md',
75
75
  }
76
76
 
@@ -99,7 +99,6 @@ const REQUIRED_FILES = [
99
99
  'test/',
100
100
  'tools/',
101
101
  'README.md',
102
- 'README.zh.md',
103
102
  'CHANGELOG.md',
104
103
  'LICENSE-MIT.md',
105
104
  'LICENSE-SUL-1.0.md',
@@ -119,7 +118,7 @@ const LICENSE_DOCUMENTS = ['LICENSE-MIT.md', 'LICENSE-SUL-1.0.md', 'NOTICE.md']
119
118
  * silently ignoring a document nobody thought to include. A document named in a
120
119
  * report cannot be quietly skipped.
121
120
  */
122
- const ANCHOR_DOCUMENTS = ['README.md', 'README.zh.md', 'CHANGELOG.md', 'NOTICE.md']
121
+ const ANCHOR_DOCUMENTS = ['README.md', 'CHANGELOG.md', 'NOTICE.md']
123
122
 
124
123
  /**
125
124
  * The `files[]` entries A19 treats as directories, spelled the way `REQUIRED_FILES`
@@ -294,7 +293,6 @@ const LOCAL_CLASSES = [
294
293
  path === 'index.js' ||
295
294
  path.startsWith('personas/') ||
296
295
  path === 'README.md' ||
297
- path === 'README.zh.md' ||
298
296
  path === 'CHANGELOG.md' ||
299
297
  path === 'LICENSE-MIT.md' ||
300
298
  path === 'LICENSE-SUL-1.0.md',
@@ -881,16 +879,16 @@ function main() {
881
879
  // cover a real file inside them.
882
880
  const EXPECTED_SCOPE = {
883
881
  sul: ['personas/', 'cordis.patch.yml', 'plan-aware-persona.mjs', 'index.js', 'baseline/cordis.patch.yml'],
884
- mit: ['tools/', 'test/', '.github/', 'baseline/README.md', 'package.json', '.gitignore', '.gitattributes', 'README.md', 'README.zh.md', 'CHANGELOG.md', 'NOTICE.md'],
882
+ mit: ['tools/', 'test/', '.github/', 'baseline/README.md', 'package.json', '.gitignore', '.gitattributes', 'README.md', 'CHANGELOG.md', 'NOTICE.md'],
885
883
  }
886
884
  // The two anchor lists below carry a property the entry-set comparison above does
887
885
  // not: each path here is checked against both blocks, so a path that is covered by
888
886
  // the block it should not be in fails as well as one that is missing from the block
889
- // it should be in. The lists are pinned to the same eleven mit entries as
887
+ // it should be in. The lists are pinned to the same ten mit entries as
890
888
  // `EXPECTED_SCOPE.mit`, so no path can be named in the scope block without also
891
889
  // being resolved against the block that claims it.
892
890
  const SUL_ANCHORS = ['baseline/cordis.patch.yml', 'cordis.patch.yml', 'plan-aware-persona.mjs', 'index.js', 'personas/atlas.md']
893
- const MIT_ANCHORS = ['README.md', 'README.zh.md', 'CHANGELOG.md', 'package.json', 'tools/check-package.mjs', 'test/parse-args.test.mjs', '.github/workflows/ci.yml', '.gitignore', '.gitattributes', 'baseline/README.md', 'NOTICE.md']
891
+ const MIT_ANCHORS = ['README.md', 'CHANGELOG.md', 'package.json', 'tools/check-package.mjs', 'test/parse-args.test.mjs', '.github/workflows/ci.yml', '.gitignore', '.gitattributes', 'baseline/README.md', 'NOTICE.md']
894
892
  const blockFor = (id) => scopeBlocks.find((block) => block.id === id)
895
893
  const blockCovers = (block, path) => block.entries.some((entry) => entryMatches(entry, path))
896
894
  for (const [id, expected] of Object.entries(EXPECTED_SCOPE)) {
package/README.zh.md DELETED
@@ -1,320 +0,0 @@
1
- # oh-my-dsh-omo-fork-chs
2
-
3
- [![npm version](https://img.shields.io/npm/v/@tacrine_f/oh-my-dsh-omo-fork-chs)](https://www.npmjs.com/package/@tacrine_f/oh-my-dsh-omo-fork-chs)
4
- [![license: SUL-1.0 (content) + MIT (packaging)](https://img.shields.io/badge/license-SUL--1.0_(content)_%2B_MIT_(packaging)-orange)](#许可)
5
- [![node](https://img.shields.io/badge/node-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-blue)](#peer-模型)
6
-
7
- `tri-agent` agent preset 的**简体中文非官方 fork**,面向
8
- [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh) 打包为可发布的 Cordis bundle。
9
- 它的 preset id 是 `omo-fork-chs`,`order` 是 `11`,因此它与 `tri-agent` **并存**而不是取而代之:
10
- 本包**不改变默认 preset**,也不改变会话选中哪一个 preset。只有 persona 正文被翻译;工具链组成与
11
- 编排 doctrine 都沿用上游设计。
12
-
13
- 这个 preset 给 agent 一套「双身份 + 完整编码工具链」:
14
-
15
- - **Atlas** 是常驻的指挥者。它不亲自实现、验证或审查;它读计划、notepad 与证据,做簿记,并把每一个
16
- 工作单元委派给具名子代理。
17
- - **Prometheus** 是规划 doctrine。当会话进入 plan 模式(`/plan`)时,身份在整个规划会话期间切换为
18
- Prometheus,结束后切回。单个插件 `plan-aware-persona.mjs` 占用唯一的 `deployment:persona-prefix`
19
- 槽位,通过读取公开的 `plan` session projection 在每次装配时选择文本。`planMode` service 被刻意
20
- **不**注入:它位于 `isolate: { planMode: true }` realm 内部,从外部注入永远不会解析成功。
21
-
22
- 在身份之外,preset 挂载了编码工具链:文件系统与 shell 工具、后台任务、skills、goals、plan mode、
23
- compaction、委派与 workflows。该 declaration 共 40 条 `- id:` row,其中 9 条是锚定的子代理 row
24
- (explore、librarian、oracle、momus、multimodal-looker、sisyphus-junior、metis、hephaestus、
25
- sisyphus)。本包附带 **11 个 persona 文件**;插件自身读取 `atlas.md` 与 `prometheus.md`,另外 9 个
26
- 锚定在子代理 row 上。
27
-
28
- ## 随包内容
29
-
30
- | 文件 | 用途 |
31
- | --- | --- |
32
- | `cordis.patch.yml` | 已发布的 bundle patch:preset 声明(`id: preset-omo-fork-chs`、`config.id: omo-fork-chs`、`config.name: 'Oh My DSH Chs - OMO Fork'`、`order: 11`)及其 `plugins:` 列表。共 540 行,11 处被改写。 |
33
- | `plan-aware-persona.mjs` | 包入口,注册 plan-aware persona 前缀与配置的 suffix。以 `./persona` 导出。 |
34
- | `index.js` | 包根。它刻意留空:bundle 的行为在 `cordis.patch.yml` 与 `./persona` 里。 |
35
- | `personas/` | 11 个 persona 文件,已译为简体中文。 |
36
- | `baseline/` | 移植前 patch 的冻结快照,外加一份说明它能证明什么、不能证明什么的 sidecar。 |
37
- | `tools/` | 移植、验证、baseline 与包结构检查的命令行工具。 |
38
- | `test/` | 零依赖测试套件,用 `node --test` 运行。 |
39
- | `LICENSE-MIT.md` | 覆盖我们自己作品的 MIT 条款。 |
40
- | `LICENSE-SUL-1.0.md` | 上游 Sustainable Use License 1.0 的逐字副本,覆盖上游衍生内容。 |
41
- | `NOTICE.md` | 修改声明、上游署名,以及机器可读的许可范围映射。 |
42
-
43
- 该 patch 挂载了下列由 DSH 提供的 peer 包:
44
-
45
- `@deepseek-ai/dsh-agent-preset`、`dsh-agent-instructions`、`dsh-tool-bash`、`dsh-tool-pwsh`、
46
- `dsh-tool-fs`、`dsh-tool-fs-search`、`dsh-tool-jobs`、`dsh-skill-filesystem`、`dsh-tool-skill`、
47
- `dsh-command-goal`、`dsh-tool-goal`、`dsh-plan-mode`、`dsh-compaction-basic`、`dsh-command-compact`、
48
- `dsh-compaction-tool-result-pruner`、`dsh-tool-subagent-control`、`dsh-tool-subagent`、
49
- `dsh-workflow-ptc`、`dsh-tool-workflow`、`dsh-tool-ralph`、`dsh-tool-ask-user`、`dsh-tool-todo`、
50
- `dsh-tool-web`、`dsh-tool-present`,外加 `@deepseek-ai/cordis`。合计 25 条 peer 依赖。
51
-
52
- ## 安装
53
-
54
- 安装是**两个显式步骤**。第 1 步安装依赖;第 2 步告诉 profile 去加载它。两步都必需,并且不假设
55
- `dsh` 在 `PATH` 上。
56
-
57
- ### 第 1 步:把包安装进 profile
58
-
59
- 把 CLI 指向你的 DSH checkout 的 bin 文件,并把安装转发给 profile:
60
-
61
- ```powershell
62
- node "<dsh bin>" plugin --profile <profile> add -w @tacrine_f/oh-my-dsh-omo-fork-chs
63
- ```
64
-
65
- 例如,某个 checkout 的 runtime 是 `<dsh runtime>`,那么 `<dsh bin>` 就是
66
- `<dsh runtime>\@deepseek-ai\dsh\lib\bin.js`,于是:
67
-
68
- ```powershell
69
- node "<dsh runtime>\@deepseek-ai\dsh\lib\bin.js" plugin --profile web add -w @tacrine_f/oh-my-dsh-omo-fork-chs
70
- ```
71
-
72
- 它会在 `$DSH_HOME\profiles\<profile>\` 内运行 pnpm,因此会写入一条 `dependencies` 记录。**它不会
73
- 改动 `dsh.profile.bundles`。**
74
-
75
- ### 第 2 步:把包加入 `dsh.profile.bundles` 并重启
76
-
77
- 打开 `$DSH_HOME\profiles\<profile>\package.json`,把包名加入该 profile 的 `dsh.profile.bundles`
78
- 数组:
79
-
80
- ```jsonc
81
- {
82
- "dsh": {
83
- "profile": {
84
- "bundles": [
85
- // ...你已有的 bundle...
86
- "@tacrine_f/oh-my-dsh-omo-fork-chs"
87
- ]
88
- }
89
- }
90
- }
91
- ```
92
-
93
- 然后**重启 Host 并新开一个会话。** 正在运行的 agent 保留它启动时的 composition,所以已经跑着的会话
94
- 不会加载这个 preset;必须新开会话。
95
-
96
- ### 验证安装已生效
97
-
98
- ```powershell
99
- $env:DSH_HOME = "<dsh home>"
100
- node "<dsh bin>" --profile <profile> --dump-config
101
- ```
102
-
103
- 输出中应当有一条 `preset-omo-fork-chs` row,其 `name` 为 `@deepseek-ai/dsh-agent-preset`,
104
- `config.id` 为 `omo-fork-chs`,`config.name` 为 `'Oh My DSH Chs - OMO Fork'`,`config.order` 为
105
- `11`,另有九条经由本包解析的 `personas` 表达式。`--dump-config` 打印的是原始 `!!js` 表达式文本,
106
- 所以那九条锚点呈现为 `resolve('<pkg>/package.json')` 形式,而不是解析后的文件系统路径。
107
-
108
- ## 安装后你可能需要自己做的改动
109
-
110
- 已发布的 patch **只**包含可移植的 preset 声明。有两样东西原本属于产出这个 fork 的那台机器,它们被
111
- 刻意**不**发布,因此你可能想自己把它们加回去:
112
-
113
- 1. **把 `omo-fork-chs` 设成默认 preset。** 已发布的 patch **不**设置默认 preset,本包也从不强加
114
- 一个。如果你希望它成为默认,请在你自己的 profile 或 overlay patch 里自行设置 registry row:
115
-
116
- ```yaml
117
- - id: agent-preset-registry
118
- config:
119
- default: omo-fork-chs
120
- ```
121
-
122
- (`@deepseek-ai/dsh-web-app` 会插入同一条 row,但 `default: standard`;上面这条会替换整个
123
- config,所以只有 default 改变。)
124
-
125
- 2. **给 `subagent_multimodal_looker` 一条模型路由。** 产出这个 fork 的 bundle 曾为那条 row 带一条
126
- 机器专属的 `provider` 与 `model` 路由,而那条路由**不可移植**,所以已发布的 patch 完全不包含
127
- `agentOptions` row。没有它时,多模态子代理会继承 deployment 的路由。若要固定一条,请在你自己的
128
- overlay 里给那条 row 加一个 `agentOptions` 块:
129
-
130
- ```yaml
131
- - id: tool-subagent-multimodal-looker
132
- name: '@deepseek-ai/dsh-tool-subagent'
133
- config:
134
- # ...已发布的 config...
135
- agentOptions:
136
- provider: <your provider>
137
- model: <your model>
138
- ```
139
-
140
- ## 失败模式:刻意 fail loud
141
-
142
- `plan-aware-persona.mjs` 在挂载时从磁盘读取自己的 persona 正文。**persona 文件缺失或为空会让挂载
143
- 失败**,并在错误里点出文件名:
144
-
145
- ```
146
- plan-aware-persona: cannot read persona "file:///.../personas/atlas.md"
147
- plan-aware-persona: persona "file:///.../personas/atlas.md" is empty
148
- ```
149
-
150
- 这是刻意的。空的 persona 前缀会悄悄剥掉 agent 的身份,所以一条点出文件名的挂载错误,远比一个安静地
151
- 丢掉自己指令的 agent 更容易处理。
152
-
153
- ## Peer 模型
154
-
155
- patch 挂载的每个 `@deepseek-ai/*` 包都声明为 **`peerDependency`**,而不是普通 `dependency`。它们由
156
- DSH 提供;bundle 不得安装自己的副本。peer 范围声明为
157
- `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`,既保留 0.1.7 线,又加入
158
- 0.2 线(`@deepseek-ai/cordis` 为 `^4.0.1`)。本包声明 25 条 peer,且**没有**运行期依赖、**没有**开发依赖,因此测试与检查链中零依赖
159
- 的那部分都不需要安装任何东西。
160
-
161
- DSH profile 的 `.npmrc` 设置了 `auto-install-peers=false`,所以这些 peer 是**纯声明式**的:pnpm 不会
162
- 去拉取它们,缺失的 peer 会在挂载时表现为解析错误,而不是被悄悄装上。
163
-
164
- ## 验证
165
-
166
- 下面全部在仓库根目录运行,且**无需安装**,只有 `check:full` 例外,它需要 runtime,并已如此标注。
167
-
168
- ```powershell
169
- # 1. 测试套件。零依赖。56 个测试。
170
- npm run test
171
-
172
- # 2. 检查链。零依赖,不需要 runtime。
173
- npm run check
174
-
175
- # 3. 同一条检查,但启用 YAML 深比较。需要 runtime。
176
- npm run setup:verify
177
- $env:DSH_RUNTIME = "<absolute path to a node_modules holding js-yaml and @deepseek-ai/cordis-plugin-include>"
178
- npm run check:full
179
-
180
- # 4. 从已发布的 patch 重新推导冻结的 baseline 并检查它。
181
- npm run baseline
182
- npm run baseline -- --check
183
-
184
- # 5. 从某个源 patch 目录重新移植已发布的 patch。
185
- npm run port -- --src <dir holding cordis.patch.yml>
186
- ```
187
-
188
- 每一条各自证明什么:
189
-
190
- - **`npm run test`** 运行 `node:test` 套件:三组正向改写、反向改写及其往返、参数解析器、从两侧检验
191
- 机器路径模式、零字节守卫,以及包检查的失败路径。共 56 个测试,不需要安装任何东西。
192
- - **`npm run check`** 是 `node tools/check-package.mjs && node tools/verify-patch.mjs`。前者运行 22 条
193
- 结构与许可断言(manifest 身份、四个 `exports`、唯一一条自引用 row、九条 persona 锚点及其文件、
194
- `files[]` 覆盖、11 个 persona 的字节数、许可指针、三份许可文档、绝不允许进入 tarball 的路径,
195
- 对 `files[]` 所列每个目录的未跟踪文件检查,以及 npm 无论 `files[]` 如何都会自动收录的根目录文件、
196
- 提供了上游指纹时的比对、
197
- 修改声明的各项主张、许可范围映射及逐条把每个范围块钉到其所声明内容的锚点、机器路径扫描、
198
- 约束移植前包名出现位置的类、本仓库向消费者复制的两个模块的 SHA256、
199
- 每份带内部锚点的文档中锚点是否都能解析到标题,以及 patch 的形状)。
200
- 后者证明已发布的 patch 仍然等于三项已记录改写从冻结 baseline 算出的结果,并报告
201
- `verdict: "IDENTICAL"` 与 11 处改写点。两者都**零依赖**,因此在干净克隆里、无需安装即可通过。
202
- - **`npm run check:full`** 就是单独运行 `node tools/verify-patch.mjs`。当 `DSH_RUNTIME` 指向一个包含
203
- `js-yaml` 与 `@deepseek-ai/cordis-plugin-include` 的绝对 `node_modules` 时,校验器会用真正的
204
- entry-list dialect 解析两份文档并做结构化比对,报告 `yamlCompare: "ok"` 与 `sites.length` 为 11。
205
- **没有 runtime 时它报告 `yamlCompare: "skipped"` 并仍然以 0 退出**,所以在这里只看退出码不算证据:
206
- 必须断言字段。这也是为什么这一步与 `check` 分开,以及为什么存在 `npm run setup:verify`:它把
207
- runtime 装进 `.dsh-verify/`,而不给本包增加依赖。该工具自己读取 `DSH_RUNTIME`,而不是接受一个
208
- `--runtime` flag,因为 Windows 上 npm 通过 `cmd.exe` 运行脚本,而 POSIX shell 会展开变量,同一个
209
- 脚本字符串在两个平台上的行为会不同。
210
- - **`npm run baseline`** 通过对三项改写施加逆变换,从已发布的 patch 重新推导出
211
- `baseline/cordis.patch.yml`;`-- --check` 把已提交的 baseline 与一份新推导出的副本比对,打印出差异行
212
- 并在出现漂移时以非零退出。
213
- - **`npm run port -- --src <dir>`** 对 `<dir>` 里的 `cordis.patch.yml` 施加三项改写并写出结果。
214
- `--src` **没有默认值**,因为唯一诚实的默认值会是一个机器专属目录;错误消息把 baseline 目录作为
215
- 替代来源点出来,而 `npm run port -- --src baseline` 会逐字节复现已提交的 patch。
216
-
217
- > **`npm run check` 与 `npm test` 都必须在 git checkout 内运行。** 包检查的三条断言(许可范围映射、
218
- > 机器路径扫描,以及约束
219
- > 移植前包名出现位置的类)都定义在**受版本跟踪的**文件集合之上,所以该工具向 `git ls-files` 索取这个
220
- > 集合。如果 git 无法回答,工具会以 `run inside a git checkout` 失败,而不是悄悄跳过这三条。`npm test`
221
- > 出于同样的原因也需要检出:它的最后一个用例会针对真实目录树运行包检查,所以在仓库之外解包同样会失败。
222
- > 因此,
223
- > 在仓库之外解包已发布 tarball 的使用者会看到这个错误,而这是刻意的:一条对从未做过的工作报告成功的
224
- > 映射检查,比没有检查更糟。已发布的包里包含这些工具与测试套件,所以这条链可以从克隆里重跑。
225
-
226
- ## 许可
227
-
228
- 本仓库是**双许可**的,且两个许可不是你可以二选一的关系:每个文件都恰好被其中一个覆盖。它**不是**
229
- 仅 MIT。
230
-
231
- 范围映射与 [`NOTICE.md`](./NOTICE.md) 中的两个块一致:
232
-
233
- - [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md) 覆盖上游衍生内容:`personas/`、`cordis.patch.yml`、
234
- `plan-aware-persona.mjs`、`index.js` 与 `baseline/cordis.patch.yml`。
235
- - [`LICENSE-MIT.md`](./LICENSE-MIT.md) 覆盖我们自己的作品:`tools/`、`test/`、`.github/`、
236
- `baseline/README.md`、`package.json`、`.gitignore`、`.gitattributes`、`README.md`、`README.zh.md`、
237
- `CHANGELOG.md`
238
- 与 `NOTICE.md`。
239
- - [`NOTICE.md`](./NOTICE.md) 是权威声明:修改声明、上游署名,以及机器可读的许可范围映射,其中包含
240
- 决定每个受跟踪路径归哪个块的匹配规则。若本 README 与 `NOTICE.md` 有任何不一致,以 NOTICE 为准。
241
-
242
- 上游条款是 **Sustainable Use License 1.0**,逐字保存在
243
- [`LICENSE-SUL-1.0.md`](./LICENSE-SUL-1.0.md) 中。SUL-1.0 是一个 **source-available** 许可。它
244
- **不是** OSI 批准的开源许可,本仓库也不作此主张。
245
-
246
- 上游条款只允许你为自己的内部业务目的,或为非商业、个人用途,去使用、复制、分发和制作衍生作品;
247
- 并且只允许你在**免费**且**非商业**的前提下分发。本包正是按这些条款分发:免费、非商业、不可转售。
248
- 上游许可是**不可再授权**的,这就是为什么覆盖我们自己文件的 MIT 许可无法延伸到上游衍生的文件之上,
249
- 也是为什么 `LICENSE-SUL-1.0.md` 必须随每一份副本一起传播。
250
-
251
- MIT 范围上有一条界定:`tools/` 与 `test/` 下的文件是我们自己的作品、按 MIT 授权,但它们内嵌了上游
252
- bundle patch 表达式的**逐字片段**,以便生成和校验该 patch。那些**逐字片段**仍受上游 SUL-1.0 条款
253
- 约束,并不会因为周围代码适用 MIT 而被重新授权。同一条界定也写在 `NOTICE.md` 里,两份文档一致。
254
-
255
- 本仓库是一个**非官方 fork**。它**未获**上游项目及其作者的背书、赞助或关联,这里也没有任何内容暗示
256
- 存在关联或背书。上游名称与商标归其所有者所有。
257
-
258
- ## 已知问题
259
-
260
- - **本版本要求 DSH ≥ 0.2.2。** 0.2.0 patch 用 `agentPreset` 为 9 个子代理各选一个 preset,
261
- 而这个字段只有 0.2.2 的 `dsh-tool-subagent` 才会读取;0.2.2 同时移除了旧行使用的 `persona`
262
- 与 `toolFilter` 字段。在 DSH 0.2.1 及更早版本上,这些行**照常挂载**,但 `agentPreset` 只是被
263
- 接受、随后从不被读取(schema 会合并未知键而不是拒绝它),于是子代理**既没有 persona,也没有
264
- 任何工具限制**,直接继承父代理的全部工具集:像 explore 或 oracle 这样的只读子代理会静默获得
265
- 写文件与派生子代理的能力。这是**静默提权,不是挂载失败**。下面声明的 peer 范围仍然放行更旧的
266
- 0.2.x 构建,所以这是一条功能性要求,而不是 semver 约束。已于 `0.2.2-alpha.2` 验证;请不要在
267
- 低于 0.2.2 的 DSH 上运行本版本。
268
- - **声明的 peer 范围覆盖 0.1.7 线与 0.2 线。范围检查在两个 0.2.x 构建上验证过,但 `0.2.1-alpha.1` 只验证过 0.1.x 的 patch。** 24 个
269
- `@deepseek-ai/dsh-*` peer 声明为
270
- `>=0.1.7-rc.2 <0.2.0 || >=0.2.0-0 <0.3.0-0 || >=0.2.1-alpha.1 <0.3.0-0`,既保留本 fork 从上游继承的
271
- 范围,又加入 0.2 线。宿主用一个 semver 范围检查来判定这些 peer 是否兼容,并且会把预发布版本纳入比较,
272
- 因此该范围接受 `0.2.0`、`0.2.1-alpha.1` 与更晚的预发布版本 `0.2.2-beta`,而拒绝 `0.3.0-alpha.1`。
273
- **已用实验在 `0.2.1-alpha.1`(仅 0.1.x 的 patch)与 `0.2.2-alpha.2`(本 patch)上验证**:在 profile 中不存在任何
274
- 豁免的情况下,对本包做 config dump 会以 0 退出、向 **stderr 写入 0 字节**,并在 dump 中带上该 preset 与
275
- 全部九条 persona 锚点;其中 `0.2.2-alpha.2` 这次运行针对的是把本包注册为 bundle 的 profile。这证明的是
276
- 挂载与锚点路径,而不是 persona 的字节内容,也不是 preset 的行为:本次验证没有调用任何 agent,
277
- 一个仍然存在但已被截断的 persona 同样会通过这项检查。
278
- **`0.3.0-alpha.1` 是重新触发的条件**:将来的运行时一旦落在该范围内就会再次被拒,stderr 上出现同样的
279
- 不兼容警告,退出码同样是 0,所以除非去看 stderr,这个失败仍然是静默的。在这类版本上,你必须要么使用
280
- 落在声明范围内的 dsh,要么用
281
- `dsh plugin allow-version "<pkg>@<version>" --dsh-version <version> --accept-risk` 授予精确版本
282
- 豁免。该豁免是宿主自带的逃生舱,并带有宿主自己警告过的风险,因此它是对风险的刻意接受,而不是受支持的
283
- 配置。**对于本次放宽没有覆盖的情形,它仍然是必需的**:npm 上已发布的 `0.1.0` 携带的是旧的、更窄的范围,
284
- 而将来任何 0.3.x 运行时也都需要它。`@deepseek-ai/cordis` 同样声明为 `^4.0.1`,但宿主从不检查它——
285
- 宿主只评估名为 `@deepseek-ai/dsh` 或以 `@deepseek-ai/dsh-` 开头的 peer——所以那一条并不是宿主会执行的
286
- 兼容性约束。
287
- - **`baseline/` 证明的是可复现,而不是正确。** baseline 是移植前 patch 的冻结快照,提交它是为了让往返
288
- 校验在任何地方都能跑。它与源 patch 逐字节一致,而这次推导证明移植是**可复现**的:已发布的 patch 与
289
- baseline 之间恰好由三项已记录改写相连,别无其他。它**不**证明内容正确。如果源 patch 本身是错的,
290
- 这次推导会忠实复现那份错误,而这里所有检查依然会通过。
291
- - **内容正确性的既有证据不随包发布。** 那份证据是简体中文移植工作产出的 `omo-fork-chs-*` 证据集,其中
292
- `verify-omo-fork-chs-bundle` 校验器报告 **`FAITHFUL`**,`verify-omo-fork-chs-deport` 校验器报告
293
- **`CLEAN`**。这些校验器是**机器相关**的:它们针对只存在于移植准备机器上的目录运行,并且刻意不随本包
294
- 发布。
295
- - **内嵌的 persona 正文带有机器本地路径。** 三份 persona 文档中一共十行写出了本地化工作所在机器上的
296
- 绝对路径。它们违反了本仓库「任何提交的文件都不得写出机器绝对路径」的规则,之所以被容忍,只是因为与
297
- 源 bundle 的字节一致性是更硬的约束。受影响的那些行在 `tools/check-package.mjs` 中逐条列举,该扫描
298
- 只在这些确切位置接受匹配。`NOTICE.md` 把这件事记为修改条目 8。本文档不复制那些路径,因为它本身也
299
- 在该扫描的覆盖范围内。
300
- - **本仓库与英文 fork 并存。** `Tacrine/oh-my-dsh-omo-fork` 是一个独立仓库,有自己的包、自己的
301
- preset id 和自己的范围映射。两个仓库互不影响:它们共享上游血缘,而本包中没有任何内容读取、写入或
302
- 依赖另一个。
303
- - **0.1.0 是本仓库的首次发布,此前没有任何版本发布过。** 本包在 npm 上没有前身,因此没有更早的产物可
304
- 供对照,也不存在从旧版本升级的路径。
305
-
306
- ## 源流
307
-
308
- 本包源自那份简体中文 agent-preset bundle,它当时以 **link 安装**的形态存在:一个接入某台机器 DSH
309
- profile 的私有依赖,指向一个本地目录。那种形态无法安装到别处,因为它的 patch 写出的是机器本地的包名,
310
- 而它的 persona 锚点是相对于 profile 目录解析的。
311
-
312
- 本仓库把那份 bundle 变成**可从 npm 安装**的形态。三项已记录改写完成了这件事:包自引用与九条 persona
313
- 路径锚点被重新指向本包自己的名字及其 `package.json`,头部注释随之更新。结果是一个在任何安装布局下都能
314
- 解析的 patch、一份让往返校验不再需要原机器的冻结 baseline,以及一条证明已发布 patch 仍等于其来源的
315
- 检查链。
316
-
317
- 上游项目是 **oh-my-openagent**,曾以 **oh-my-opencode** 之名发布
318
- (https://github.com/code-yeongyu/oh-my-openagent)。本仓库中的内容派生自上游 commit
319
- `3c711483856207ef530c09d062fa9077c225debbe`,该 commit 对应上游版本 **5.0.1**。persona 正文、
320
- 工具链组成与插件都沿用上游设计;本 fork 的贡献是简体中文翻译与打包拆分。