@pennixrv/trellis 0.7.0-beta.46 → 0.7.0-beta.47

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.
Files changed (31) hide show
  1. package/dist/commands/workflow.js +1 -1
  2. package/dist/commands/workflow.js.map +1 -1
  3. package/dist/migrations/manifests/0.7.0-beta.47.json +9 -0
  4. package/dist/templates/codex/hooks/session-start.py +6 -6
  5. package/dist/templates/copilot/hooks/session-start.py +6 -6
  6. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +22 -22
  7. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +20 -20
  8. package/dist/templates/markdown/spec/backend/error-handling.md.txt +22 -22
  9. package/dist/templates/markdown/spec/backend/index.md.txt +19 -19
  10. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +22 -22
  11. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +22 -22
  12. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +25 -25
  13. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +20 -20
  14. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +22 -22
  15. package/dist/templates/markdown/spec/frontend/index.md.txt +20 -20
  16. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +22 -22
  17. package/dist/templates/markdown/spec/frontend/state-management.md.txt +22 -22
  18. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +22 -22
  19. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +80 -85
  20. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +164 -209
  21. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +161 -185
  22. package/dist/templates/markdown/spec/guides/index.md.txt +51 -51
  23. package/dist/templates/markdown/workspace-index.md +44 -44
  24. package/dist/templates/opencode/lib/session-utils.js +2 -2
  25. package/dist/templates/shared-hooks/session-start.py +7 -7
  26. package/dist/templates/trellis/scripts/add_session.py +35 -32
  27. package/dist/templates/trellis/scripts/common/developer.py +18 -18
  28. package/dist/templates/trellis/scripts/common/task_store.py +11 -11
  29. package/dist/templates/trellis/scripts/common/workflow_phase.py +4 -3
  30. package/dist/templates/trellis/workflow.md +403 -458
  31. package/package.json +2 -2
@@ -1,35 +1,35 @@
1
- # Cross-Platform Thinking Guide
1
+ # 跨平台思考指南(Cross-Platform Thinking Guide)
2
2
 
3
- > **Purpose**: Catch platform-specific assumptions before they become bugs.
3
+ > **目的(Purpose)**:在平台特定假设变成错误前发现它们。
4
4
 
5
5
  ---
6
6
 
7
- ## Why This Matters
7
+ ## 为什么重要(Why This Matters)
8
8
 
9
- **Most cross-platform bugs come from implicit assumptions**:
9
+ **大多数跨平台错误来自隐含假设:**
10
10
 
11
- - Assumed shebang works → breaks on Windows
12
- - Assumed `/` path separator → breaks on Windows
13
- - Assumed `\n` line endings → inconsistent behavior
14
- - Assumed command availability → `grep` vs `findstr`
11
+ - 假定 shebang 可用 → 在 Windows 上失败
12
+ - 假定使用 `/` 路径分隔符 → 在 Windows 上失败
13
+ - 假定使用 `\n` 换行 → 行为不一致
14
+ - 假定命令可用 → `grep` 与 `findstr` 不同
15
15
 
16
16
  ---
17
17
 
18
- ## Platform Differences Checklist
18
+ ## 平台差异清单(Platform Differences Checklist)
19
19
 
20
- ### 1. Script Execution
20
+ ### 1. 脚本执行(Script Execution)
21
21
 
22
- | Assumption | macOS/Linux | Windows |
22
+ | 假设(Assumption) | macOS/Linux | Windows |
23
23
  |------------|-------------|---------|
24
- | Shebang (`#!/usr/bin/env python3`) | ✅ Works | ❌ Ignored |
25
- | Direct execution (`./script.py`) | ✅ Works | ❌ Fails |
26
- | `python3` command | ✅ Always available | ⚠️ May need `python` |
27
- | `python` command | ⚠️ May be Python 2 | ✅ Usually Python 3 |
24
+ | Shebang (`#!/usr/bin/env python3`) | ✅ 可用 | ❌ 被忽略 |
25
+ | 直接执行(`./script.py`) | ✅ 可用 | ❌ 失败 |
26
+ | `python3` 命令 | ✅ 始终可用 | ⚠️ 可能需要 `python` |
27
+ | `python` 命令 | ⚠️ 可能是 Python 2 | ✅ 通常是 Python 3 |
28
28
 
29
- **Rule 1**: For user-facing docs, help text, and error messages, either:
29
+ **规则一**:对于面向用户的文档、帮助文本和错误消息,应当:
30
30
 
31
- - state the platform rule explicitly (`python` on Windows, `python3` elsewhere), or
32
- - render the command through the same platform-aware helper / placeholder the code uses.
31
+ - 明确说明平台规则(Windows 使用 `python`,其他平台使用 `python3`);或
32
+ - 使用代码采用的同一平台感知辅助函数/占位符生成命令。
33
33
 
34
34
  ```python
35
35
  # BAD - Assumes shebang works
@@ -41,7 +41,7 @@ print("Usage: python on Windows, python3 elsewhere")
41
41
  print("Run: {{PYTHON_CMD}} ./.trellis/scripts/task.py <args>")
42
42
  ```
43
43
 
44
- **Rule 2**: When generating config files at init time, use placeholder + platform detection:
44
+ **规则二**:在 init 时生成配置文件,应使用占位符和平台检测:
45
45
 
46
46
  ```typescript
47
47
  // In template file (settings.json):
@@ -57,7 +57,7 @@ function replacePlaceholders(content: string): string {
57
57
  }
58
58
  ```
59
59
 
60
- **Rule 3**: When calling Python at runtime from JavaScript, detect platform dynamically:
60
+ **规则三**:从 JavaScript 在运行时调用 Python 时,动态检测平台:
61
61
 
62
62
  ```javascript
63
63
  import { platform } from "os"
@@ -66,9 +66,7 @@ const PYTHON_CMD = platform() === "win32" ? "python" : "python3"
66
66
  execSync(`${PYTHON_CMD} "${scriptPath}"`, { ... })
67
67
  ```
68
68
 
69
- **Rule 4**: If you need to verify Python is actually installed (not just choose
70
- the command), probe the same platform-selected alias you will later render or
71
- execute:
69
+ **规则四**:如果需要确认 Python 确实已安装,而不只是选择命令,应探测之后将要生成或执行的同一平台别名:
72
70
 
73
71
  ```typescript
74
72
  function getPythonCommand(platform = process.platform): string {
@@ -85,9 +83,9 @@ function warnIfPythonTooOld(): void {
85
83
  }
86
84
  ```
87
85
 
88
- **Rule 5**: Don't assume the Python version the AI CLI uses matches your shell's `python3`. The user's terminal may resolve `python3` → homebrew 3.11, but AI CLI hosts (including enterprise-forked Claude Code / Cursor distributions) spawn hook subprocesses with a minimal PATH that resolves `python3` → `/usr/bin/python3` → macOS system 3.9. Distributed templates must either target the lowest plausible version or use `from __future__ import annotations` for PEP 604 syntax. See `cli/backend/script-conventions.md` → **CRITICAL: PEP 604 Annotations Require `from __future__ import annotations`** for the hard rule and audit check.
86
+ **规则五**:不要假定 AI CLI 使用的 Python 版本与 Shell 的 `python3` 相同。用户终端可能将 `python3` 解析为 Homebrew 3.11,但 AI CLI 宿主(包括企业分发的 Claude Code/Cursor)可能以最小 PATH 启动 Hook 子进程,将 `python3` 解析为 `/usr/bin/python3`,也就是 macOS 系统 3.9。分发模板必须面向合理的最低版本,或为 PEP 604 语法使用 `from __future__ import annotations`。硬规则和审查方法见 `cli/backend/script-conventions.md` 的 **CRITICAL: PEP 604 Annotations Require `from __future__ import annotations`**。
89
87
 
90
- **Rule 6**: When calling Python from Python, use `sys.executable`:
88
+ **规则六**:从 Python 调用 Python 时,使用 `sys.executable`:
91
89
 
92
90
  ```python
93
91
  import sys
@@ -100,15 +98,15 @@ subprocess.run(["python3", "other_script.py"])
100
98
  subprocess.run([sys.executable, "other_script.py"])
101
99
  ```
102
100
 
103
- ### 2. Path Handling
101
+ ### 2. 路径处理(Path Handling)
104
102
 
105
- | Assumption | macOS/Linux | Windows |
103
+ | 假设(Assumption) | macOS/Linux | Windows |
106
104
  |------------|-------------|---------|
107
- | `/` separator | ✅ Works | ⚠️ Sometimes works |
108
- | `\` separator | ❌ Escape char | ✅ Native |
109
- | `pathlib.Path` | ✅ Works | ✅ Works |
105
+ | `/` 分隔符 | ✅ 可用 | ⚠️ 部分情况下可用 |
106
+ | `\` 分隔符 | ❌ 转义字符 | ✅ 原生 |
107
+ | `pathlib.Path` | ✅ 可用 | ✅ 可用 |
110
108
 
111
- **Rule (Python)**: Use `pathlib.Path` for all path operations.
109
+ **规则(Python)**:所有路径操作使用 `pathlib.Path`。
112
110
 
113
111
  ```python
114
112
  # BAD - String concatenation
@@ -119,18 +117,18 @@ from pathlib import Path
119
117
  path = Path(base) / filename
120
118
  ```
121
119
 
122
- #### Logical key vs filesystem path (TypeScript)
120
+ #### 逻辑键与文件系统路径(Logical key vs filesystem path,TypeScript)
123
121
 
124
- A path string has two distinct roles. **Treat them differently.**
122
+ 路径字符串有两种不同角色,**必须区别处理**。
125
123
 
126
- | Role | OS-native (`\` on Windows) | Always POSIX (`/`) |
124
+ | 角色(Role) | 操作系统原生形式(Windows 使用 `\`) | 始终使用 POSIX(`/`) |
127
125
  |------|---------------------------|--------------------|
128
- | `fs.readFileSync(p)` / `path.join(cwd, x)` for fs call | ✅ Required | ❌ May fail on Windows |
129
- | `Map<relPath, content>` key, JSON field, hash dictionary key, anything persisted across OS | ❌ Cross-OS mismatch | ✅ Required |
126
+ | 文件系统调用中的 `fs.readFileSync(p)` / `path.join(cwd, x)` | ✅ 必需 | ❌ 在 Windows 上可能失败 |
127
+ | `Map<relPath, content>` 键、JSON 字段、哈希字典键及其他跨操作系统持久化内容 | ❌ 跨操作系统不匹配 | ✅ 必需 |
130
128
 
131
- **Rule**: Anywhere a path string crosses OS or persists (Map keys consumed by another OS, JSON fields, hash dictionary keys), normalize to POSIX. Anywhere it goes straight to `fs.*`, leave OS-native.
129
+ **规则**:路径字符串跨操作系统或持久化时(被另一操作系统消费的 Map 键、JSON 字段、哈希字典键),规范化为 POSIX。直接传给 `fs.*` 时保留操作系统原生形式。
132
130
 
133
- **Single source of truth**: `packages/cli/src/utils/posix.ts` exports `toPosix(p)`. Don't sprinkle `replaceAll('\\', '/')` at every `path.join` site — apply `toPosix` **once at the boundary**: collector exit (Map key entering hash dictionary) or write-time (`saveHashes` before `JSON.stringify`).
131
+ **唯一事实来源**:`packages/cli/src/utils/posix.ts` 导出 `toPosix(p)`。不要在每个 `path.join` 位置散落 `replaceAll('\\', '/')`,而是在边界处使用一次 `toPosix`:收集器出口(Map 键进入哈希字典时)或写入时(`JSON.stringify` 前的 `saveHashes`)。
134
132
 
135
133
  ```typescript
136
134
  // BAD - logical key carries OS-native separator
@@ -162,16 +160,16 @@ function saveHashes(cwd: string, hashes: Record<string, string>): void {
162
160
  }
163
161
  ```
164
162
 
165
- **Common offender**: `path.relative(cwd, fullPath)` produces `\` on Windows. If you then use that string as a hash dictionary lookup key (`hashes[relPath]`), `toPosix` it first, or the lookup misses on Windows.
163
+ **常见问题**:`path.relative(cwd, fullPath)` 在 Windows 上会产生 `\`。如果随后将该字符串用作哈希字典查找键(`hashes[relPath]`),必须先使用 `toPosix`,否则 Windows 上会查找失败。
166
164
 
167
- ### 3. Line Endings
165
+ ### 3. 换行符(Line Endings)
168
166
 
169
- | Format | macOS/Linux | Windows | Git |
167
+ | 格式(Format) | macOS/Linux | Windows | Git |
170
168
  |--------|-------------|---------|-----|
171
- | `\n` (LF) | ✅ Native | ⚠️ Some tools | ✅ Normalized |
172
- | `\r\n` (CRLF) | ⚠️ Extra char | ✅ Native | Converted |
169
+ | `\n`(LF) | ✅ 原生 | ⚠️ 部分工具支持 | ✅ 规范化 |
170
+ | `\r\n`(CRLF) | ⚠️ 多余字符 | ✅ 原生 | 转换 |
173
171
 
174
- **Rule 1**: Use `.gitattributes` to enforce consistent line endings.
172
+ **规则一**:使用 `.gitattributes` 强制统一换行符。
175
173
 
176
174
  ```gitattributes
177
175
  * text=auto eol=lf
@@ -179,7 +177,7 @@ function saveHashes(cwd: string, hashes: Record<string, string>): void {
179
177
  *.py text eol=lf
180
178
  ```
181
179
 
182
- **Rule 2**: When hashing or comparing **content** across platforms, normalize line endings before computing the hash. `.gitattributes` only governs git checkout — files written by users, scripts, or `core.autocrlf=true` may still arrive as CRLF, and `sha256(LF)` ≠ `sha256(CRLF)` for otherwise-identical content.
180
+ **规则二**:跨平台计算哈希或比较**内容**时,计算哈希前先规范化换行符。`.gitattributes` 只控制 Git checkout;用户、脚本或 `core.autocrlf=true` 写入的文件仍可能是 CRLF,对其他内容相同的文件而言,`sha256(LF)` ≠ `sha256(CRLF)`。
183
181
 
184
182
  ```typescript
185
183
  // BAD - Windows users with autocrlf=true get a different hash
@@ -194,17 +192,17 @@ export function computeHash(content: string): string {
194
192
  }
195
193
  ```
196
194
 
197
- Apply this rule wherever the hash crosses OS boundaries (template hash dictionary, content fingerprints stored in JSON, integrity checks against a remote registry).
195
+ 哈希跨操作系统边界时均应用此规则,包括模板哈希字典、JSON 中的内容指纹以及远端注册表完整性检查。
198
196
 
199
- ### 4. Environment Variables
197
+ ### 4. 环境变量(Environment Variables)
200
198
 
201
- | Variable | macOS/Linux | Windows |
199
+ | 变量(Variable) | macOS/Linux | Windows |
202
200
  |----------|-------------|---------|
203
- | `HOME` | ✅ Set | ❌ Use `USERPROFILE` |
204
- | `PATH` separator | `:` | `;` |
205
- | Case sensitivity | ✅ Case-sensitive | ❌ Case-insensitive |
201
+ | `HOME` | ✅ 已设置 | ❌ 使用 `USERPROFILE` |
202
+ | `PATH` 分隔符 | `:` | `;` |
203
+ | 大小写敏感性 | ✅ 区分大小写 | ❌ 不区分大小写 |
206
204
 
207
- **Rule 1**: Use `pathlib.Path.home()` instead of environment variables.
205
+ **规则一**:使用 `pathlib.Path.home()`,不要直接依赖环境变量。
208
206
 
209
207
  ```python
210
208
  # BAD
@@ -214,10 +212,7 @@ home = os.environ.get("HOME")
214
212
  home = Path.home()
215
213
  ```
216
214
 
217
- **Rule 2**: When injecting environment variables into shell commands, generate
218
- the prefix for the actual shell that will parse the command. Do not choose
219
- syntax from OS alone. AI tool "Bash" surfaces on Windows may execute through
220
- PowerShell, Git Bash, MSYS2, or another POSIX-like shell.
215
+ **规则二**:向 Shell 命令注入环境变量时,针对实际解析命令的 Shell 生成前缀。不要只依据操作系统选择语法。Windows 上的 AI 工具“Bash”界面可能通过 PowerShell、Git Bash、MSYS2 或其他类 POSIX Shell 执行。
221
216
 
222
217
  ```javascript
223
218
  // BAD - breaks when the host shell is PowerShell
@@ -230,25 +225,20 @@ const prefix = process.platform === "win32" && !isWindowsPosixShell(process.env)
230
225
  command = `${prefix}${command}`;
231
226
  ```
232
227
 
233
- On Windows, treat `MSYSTEM`, `MINGW_PREFIX`, `OSTYPE=msys|mingw|cygwin`,
234
- `SHELL=...bash`, or a platform-specific Git Bash setting as POSIX-shell
235
- signals. Keep PowerShell as the Windows default when there is no POSIX-shell
236
- signal.
228
+ 在 Windows 上,将 `MSYSTEM`、`MINGW_PREFIX`、`OSTYPE=msys|mingw|cygwin`、`SHELL=...bash` 或平台特定的 Git Bash 设置视为 POSIX Shell 信号。没有 POSIX Shell 信号时,将 PowerShell 作为 Windows 默认值。
237
229
 
238
- Also make duplicate-injection detection shell-aware. A guard that only matches
239
- `export VAR=` will miss PowerShell's `$env:VAR = ...` form and can wrap an
240
- already-correct command a second time.
230
+ 重复注入检测也必须感知 Shell。只匹配 `export VAR=` 的保护逻辑会遗漏 PowerShell 的 `$env:VAR = ...` 形式,并可能将已经正确的命令再次包装。
241
231
 
242
- ### 5. Command Availability
232
+ ### 5. 命令可用性(Command Availability)
243
233
 
244
- | Command | macOS/Linux | Windows |
234
+ | 命令(Command) | macOS/Linux | Windows |
245
235
  |---------|-------------|---------|
246
- | `grep` | ✅ Built-in | ❌ Not available |
247
- | `find` | ✅ Built-in | ⚠️ Different syntax |
248
- | `cat` | ✅ Built-in | ❌ Use `type` |
249
- | `tail -f` | ✅ Built-in | ❌ Not available |
236
+ | `grep` | ✅ 内置 | ❌ 不可用 |
237
+ | `find` | ✅ 内置 | ⚠️ 语法不同 |
238
+ | `cat` | ✅ 内置 | ❌ 使用 `type` |
239
+ | `tail -f` | ✅ 内置 | ❌ 不可用 |
250
240
 
251
- **Rule**: Use Python standard library instead of shell commands when possible.
241
+ **规则**:可行时使用 Python 标准库替代 Shell 命令。
252
242
 
253
243
  ```python
254
244
  # BAD - tail -f is not available on Windows
@@ -267,37 +257,28 @@ def tail_follow(file_path: Path) -> None:
267
257
  time.sleep(0.1)
268
258
  ```
269
259
 
270
- ### Optional Advisory Checks in Agent Sandboxes
260
+ ### Agent 沙箱中的可选提示检查(Optional Advisory Checks in Agent Sandboxes)
271
261
 
272
- AI CLI subprocesses may run with outbound network disabled even when the user's
273
- normal terminal has network access. Prefer local CLI probes over optional
274
- network probes when the local CLI already exposes the needed information.
262
+ 即使用户的普通终端可以访问网络,AI CLI 子进程也可能禁用出站网络。如果本地 CLI 已提供所需信息,优先使用本地 CLI 探测,而不是可选的网络探测。
275
263
 
276
- **Rule 1**: Do not let a failed optional advisory check consume a once-per-session
277
- marker. Write the marker only after the script resolves a usable value and can
278
- make the intended decision. Otherwise a transient sandbox/network failure hides
279
- the hint for the rest of the session.
264
+ **规则一**:失败的可选提示检查不得消耗每会话一次的标记。只有脚本解析出可用值并能够作出预期决策后才写入标记,否则沙箱/网络的临时错误会隐藏本会话剩余时间的提示。
280
265
 
281
- **Rule 2**: If a local command can provide the needed value, try it with a short
282
- timeout and captured output. For example, `trellis --version` already runs the
283
- CLI's version comparison logic and can support an actionable update prompt
284
- without duplicating npm registry parsing.
266
+ **规则二**:如果本地命令可以提供所需值,使用短超时和捕获输出进行尝试。例如,`trellis --version` 已经执行 CLI 版本比较逻辑,可以支持可执行的更新提示,而不必重复 npm registry 解析。
285
267
 
286
- **Rule 3**: Keep advisory checks silent on failure. The user-facing context output
287
- must not fail or become noisy because an advisory check could not complete.
268
+ **规则三**:提示检查失败时保持静默。面向用户的上下文输出不能因提示检查未完成而失败或变得嘈杂。
288
269
 
289
- ### 6. File Encoding
270
+ ### 6. 文件编码(File Encoding)
290
271
 
291
- | Default Encoding | macOS/Linux | Windows |
272
+ | 默认编码(Default Encoding) | macOS/Linux | Windows |
292
273
  |------------------|-------------|---------|
293
- | Terminal | UTF-8 | Often CP1252 or GBK |
294
- | File I/O | UTF-8 | System locale |
295
- | Git output | UTF-8 | May vary |
274
+ | 终端 | UTF-8 | 常为 CP1252 或 GBK |
275
+ | 文件 I/O | UTF-8 | 系统区域设置 |
276
+ | Git 输出 | UTF-8 | 可能不同 |
296
277
 
297
- **Rule**: Always explicitly specify `encoding="utf-8"` and use `errors="replace"`.
278
+ **规则**:始终显式指定 `encoding="utf-8"`,并使用 `errors="replace"`。
298
279
 
299
- > **Checklist**: When writing scripts that print non-ASCII, did you configure stdout encoding?
300
- > See `backend/script-conventions.md` for the specific pattern.
280
+ > **清单**:编写会输出非 ASCII 内容的脚本时,是否配置了 stdout 编码?
281
+ > 具体模式见 `backend/script-conventions.md`。
301
282
 
302
283
  ```python
303
284
  # BAD - Relies on system default
@@ -319,7 +300,7 @@ result = subprocess.run(
319
300
  )
320
301
  ```
321
302
 
322
- **Git commands**: Force UTF-8 output encoding:
303
+ **Git 命令(Git commands)**:强制使用 UTF-8 输出编码:
323
304
 
324
305
  ```python
325
306
  # Force git to output UTF-8
@@ -335,29 +316,29 @@ result = subprocess.run(
335
316
 
336
317
  ---
337
318
 
338
- ## Change Propagation Checklist
319
+ ## 变更传播清单(Change Propagation Checklist)
339
320
 
340
- When making platform-related changes, check **all these locations**:
321
+ 进行平台相关变更时,检查**以下所有位置**:
341
322
 
342
- ### Commands / Skills Sync
343
- - [ ] New command/skill added to ALL platforms (claude, cursor, iflow, codex, and any new platform)
344
- - [ ] Each platform's test file updated with new entry in `EXPECTED_COMMAND_NAMES` / `EXPECTED_SKILL_NAMES`
345
- - [ ] Platform-integration spec's required command table updated if adding a new required command
346
- - [ ] Command format matches platform convention (see `platform-integration.md` → Command Format by Platform)
323
+ ### 命令/Skill 同步(Commands / Skills Sync)
324
+ - [ ] 新命令/Skill 已添加到所有平台(claude、cursor、iflow、codex 和任何新平台)
325
+ - [ ] 每个平台的测试文件都已在 `EXPECTED_COMMAND_NAMES` / `EXPECTED_SKILL_NAMES` 中加入新条目
326
+ - [ ] 添加必需命令时,平台集成 spec 的必需命令表已更新
327
+ - [ ] 命令格式符合平台约定(见 `platform-integration.md` → 按平台划分的命令格式)
347
328
 
348
- ### Documentation & Help Text
349
- - [ ] Docstrings at top of Python files
350
- - [ ] `--help` output / argparse descriptions
351
- - [ ] Usage examples in README
352
- - [ ] Error messages that suggest commands
353
- - [ ] Markdown documentation (`.md` files)
329
+ ### 文档与帮助文本(Documentation & Help Text)
330
+ - [ ] Python 文件顶部的 Docstring
331
+ - [ ] `--help` 输出 / argparse 描述
332
+ - [ ] README 中的使用示例
333
+ - [ ] 建议命令的错误消息
334
+ - [ ] Markdown 文档(`.md` 文件)
354
335
 
355
- ### Code Locations
356
- - [ ] `src/templates/` - Template files for new projects
357
- - [ ] `.trellis/scripts/` - Project's own scripts (if self-hosting)
358
- - [ ] `dist/` - Built output (rebuild after changes)
336
+ ### 代码位置(Code Locations)
337
+ - [ ] `src/templates/`——新项目使用的模板文件
338
+ - [ ] `.trellis/scripts/`——项目自身脚本(如果项目自托管)
339
+ - [ ] `dist/`——构建输出(变更后重新构建)
359
340
 
360
- ### Search Pattern
341
+ ### 搜索模式(Search Pattern)
361
342
  ```bash
362
343
  # Find all places that might need updating
363
344
  grep -r "python [a-z]" --include="*.py" --include="*.md"
@@ -366,31 +347,31 @@ grep -r "{{PYTHON_CMD}}\\|python3\\|python " --include="*.py" --include="*.md"
366
347
 
367
348
  ---
368
349
 
369
- ## Pre-Commit Checklist
350
+ ## 提交前清单(Pre-Commit Checklist)
370
351
 
371
- Before committing cross-platform code:
352
+ 提交跨平台代码前:
372
353
 
373
- - [ ] User-facing Python invocations are platform-aware (`python` on Windows, `python3` elsewhere) or use `{{PYTHON_CMD}}`
374
- - [ ] Python subprocesses from Python use `sys.executable`
375
- - [ ] All paths use `pathlib.Path`
376
- - [ ] No hardcoded path separators (`/` or `\`)
377
- - [ ] Path strings used as logical/persisted keys (Map keys, JSON fields, hash dictionary keys) are normalized via `toPosix()`; `fs.*` calls keep OS-native paths
378
- - [ ] Content hashes computed across OSes normalize line endings (`\r\n` → `\n`) before hashing
379
- - [ ] Cross-OS JSON with potential legacy pollution carries a `__version` sentinel and the loader discards unknown/legacy versions
380
- - [ ] No platform-specific commands without fallbacks (e.g., `tail -f`)
381
- - [ ] Optional advisory checks do not burn once-per-session markers on failure
382
- - [ ] All file I/O specifies `encoding="utf-8"` and `errors="replace"`
383
- - [ ] All subprocess calls specify `encoding="utf-8"` and `errors="replace"`
384
- - [ ] Git commands use `-c i18n.logOutputEncoding=UTF-8`
385
- - [ ] External tool API formats verified from documentation
386
- - [ ] Documentation matches code behavior
387
- - [ ] Ran search to find all affected locations
354
+ - [ ] 面向用户的 Python 调用感知平台(Windows 使用 `python`,其他平台使用 `python3`),或使用 `{{PYTHON_CMD}}`
355
+ - [ ] Python 调用 Python 子进程时使用 `sys.executable`
356
+ - [ ] 所有路径使用 `pathlib.Path`
357
+ - [ ] 没有硬编码路径分隔符(`/` 或 `\`)
358
+ - [ ] 用作逻辑/持久化键的路径字符串(Map 键、JSON 字段、哈希字典键)经 `toPosix()` 规范化;`fs.*` 调用保留操作系统原生路径
359
+ - [ ] 跨操作系统内容哈希在计算前规范化换行符(`\r\n` → `\n`)
360
+ - [ ] 可能受旧格式污染的跨操作系统 JSON 带有 `__version` 标记,加载器丢弃未知或旧版本
361
+ - [ ] 平台特定命令都有替代路径(如 `tail -f`)
362
+ - [ ] 可选提示检查失败时不消耗每会话一次的标记
363
+ - [ ] 所有文件 I/O 显式指定 `encoding="utf-8"` 和 `errors="replace"`
364
+ - [ ] 所有子进程调用显式指定 `encoding="utf-8"` 和 `errors="replace"`
365
+ - [ ] Git 命令使用 `-c i18n.logOutputEncoding=UTF-8`
366
+ - [ ] 外部工具 API 格式已经文档核验
367
+ - [ ] 文档与代码行为一致
368
+ - [ ] 已搜索所有受影响位置
388
369
 
389
- ### 7. External Tool API Contracts
370
+ ### 7. 外部工具 API 合同(External Tool API Contracts)
390
371
 
391
- When integrating with external tools (Claude Code, Cursor, etc.), their API contracts are **implicit assumptions**.
372
+ 集成外部工具(Claude Code、Cursor 等)时,它们的 API 合同属于**隐含假设**。
392
373
 
393
- **Rule**: Verify API formats from official documentation, don't guess.
374
+ **规则**:从官方文档核验 API 格式,不要猜测。
394
375
 
395
376
  ```python
396
377
  # BAD - Guessed format
@@ -405,16 +386,16 @@ output = {
405
386
  }
406
387
  ```
407
388
 
408
- > **Warning**: Different hook types may have different output formats.
409
- > Always check the specific documentation for each hook event.
389
+ > **警告**:不同 Hook 类型可能有不同的输出格式。
390
+ > 始终检查每个 Hook 事件的具体文档。
410
391
 
411
392
  ---
412
393
 
413
- ## Cross-Platform Persisted JSON: Schema Migration Sentinel
394
+ ## 跨平台持久化 JSON:Schema 迁移标记(Cross-Platform Persisted JSON: Schema Migration Sentinel)
414
395
 
415
- When a JSON file may be read/written across OSes (committed to git, synced via cloud, copied between machines) **and an older format may already exist on user disks with cross-platform pollution** (Windows-style keys, CRLF-derived hashes, locale-encoded strings), add a `__version` sentinel and let the loader discard old formats so the writer regenerates clean data.
396
+ 当 JSON 文件可能跨操作系统读写(提交到 Git、通过云同步或在机器之间复制),并且用户磁盘上可能已有带跨平台污染的旧格式(Windows 风格键、由 CRLF 产生的哈希、本地编码字符串)时,增加 `__version` 标记,让加载器丢弃旧格式,由写入器重新生成干净数据。
416
397
 
417
- **Why not migrate-in-place?** Path-key migration (`\\` → `/`) plus hash-input migration (CRLF → LF re-hash) plus encoding fixes are correlated — trying to translate the old payload risks producing wrong values. Discarding and regenerating is **safe**: the data is recomputable from disk, and `loadX` returning `{}` triggers the existing init/update path to rebuild canonical entries.
398
+ **为什么不原地迁移?**路径键迁移(`\\` → `/`)、哈希输入迁移(CRLF → LF 后重新计算)和编码修复相互关联,直接翻译旧载荷可能产生错误值。丢弃并重新生成是**安全的**:数据可以从磁盘重新计算,`loadX` 返回 `{}` 会触发已有 init/update 路径重建规范条目。
418
399
 
419
400
  ```typescript
420
401
  const SCHEMA_VERSION = 2;
@@ -449,22 +430,22 @@ export function saveHashes(cwd: string, hashes: Record<string, string>): void {
449
430
  }
450
431
  ```
451
432
 
452
- **When to apply**:
453
- - Hash dictionaries / content fingerprints (e.g., `.template-hashes.json`)
454
- - Cache files where stale entries are recomputable from authoritative source
455
- - Any cross-OS persisted file where format change correlates with cross-platform fixes
433
+ **适用场景**:
434
+ - 哈希字典/内容指纹(例如 `.template-hashes.json`)
435
+ - 可从权威来源重新计算过期条目的缓存文件
436
+ - 格式变化与跨平台修复相关的其他跨操作系统持久化文件
456
437
 
457
- **When NOT to apply** — if losing the data hurts the user (task state, drafts, settings the user typed). Use real migration there. Sentinel + discard is only safe when data is recomputable.
438
+ **不适用场景**——丢失数据会伤害用户时(任务状态、草稿、用户输入的设置)。这些数据应使用真实迁移。只有数据可重新计算时,标记加丢弃才安全。
458
439
 
459
- **Reference**: `packages/cli/src/utils/template-hash.ts` v2 envelope.
440
+ **参考(Reference)**:`packages/cli/src/utils/template-hash.ts` 的 v2 封装结构。
460
441
 
461
442
  ---
462
443
 
463
- ## JSON/External Data Defensive Checks
444
+ ## JSON/外部数据防御性检查(JSON/External Data Defensive Checks)
464
445
 
465
- When parsing JSON or external data, TypeScript types are **compile-time only**. Runtime data may not match.
446
+ 解析 JSON 或外部数据时,TypeScript 类型**只在编译期生效**,运行时数据可能不匹配。
466
447
 
467
- **Rule**: Always add defensive checks for required fields before using them.
448
+ **规则**:使用必需字段前始终进行防御性检查。
468
449
 
469
450
  ```typescript
470
451
  // BAD - Trusts TypeScript type definition
@@ -484,13 +465,13 @@ function process(item: MigrationItem) {
484
465
  }
485
466
  ```
486
467
 
487
- **When to apply**:
488
- - Parsing JSON files (manifests, configs)
489
- - API responses
490
- - User input
491
- - Any data from external sources
468
+ **适用场景**:
469
+ - 解析 JSON 文件(manifest、配置)
470
+ - API 响应
471
+ - 用户输入
472
+ - 任何外部来源的数据
492
473
 
493
- **Pattern**: Check existence → then use
474
+ **模式**:先检查是否存在 → 再使用
494
475
 
495
476
  ```typescript
496
477
  // Filter pattern - skip invalid items
@@ -505,9 +486,9 @@ if (!data.requiredField) {
505
486
 
506
487
  ---
507
488
 
508
- ## Common Mistakes
489
+ ## 常见错误(Common Mistakes)
509
490
 
510
- ### 1. "It works on my Mac"
491
+ ### 1. “在我的 Mac 上可以工作”(“It works on my Mac”)
511
492
 
512
493
  ```python
513
494
  # Developer's Mac
@@ -517,21 +498,21 @@ subprocess.run(["./script.py"]) # Works!
517
498
  subprocess.run(["./script.py"]) # FileNotFoundError
518
499
  ```
519
500
 
520
- ### 2. "The shebang should handle it"
501
+ ### 2. “shebang 应该能处理”(“The shebang should handle it”)
521
502
 
522
503
  ```python
523
504
  #!/usr/bin/env python3
524
505
  # This line is IGNORED on Windows
525
506
  ```
526
507
 
527
- ### 3. "I updated the template"
508
+ ### 3. “我已经更新模板了”(“I updated the template”)
528
509
 
529
510
  ```
530
511
  src/templates/script.py ← Updated
531
512
  .trellis/scripts/script.py ← Forgot to sync!
532
513
  ```
533
514
 
534
- ### 4. "Python 3 is always python3"
515
+ ### 4. “Python 3 总是 python3”(“Python 3 is always python3”)
535
516
 
536
517
  ```bash
537
518
  # Developer's Mac/Linux
@@ -545,7 +526,7 @@ python script.py # Works!
545
526
  {{PYTHON_CMD}} script.py
546
527
  ```
547
528
 
548
- ### 5. "UTF-8 is the default everywhere"
529
+ ### 5. “任何地方默认都是 UTF-8”(“UTF-8 is the default everywhere”)
549
530
 
550
531
  ```python
551
532
  # Developer's Mac (UTF-8 default)
@@ -555,33 +536,33 @@ subprocess.run(cmd, capture_output=True, text=True) # Works!
555
536
  subprocess.run(cmd, capture_output=True, text=True) # Garbled Chinese/Unicode
556
537
  ```
557
538
 
558
- > **Note**: stdout encoding is also affected. See `backend/script-conventions.md` for the fix.
539
+ > **注意**:stdout 编码也会受到影响。修复方法见 `backend/script-conventions.md`。
559
540
 
560
541
  ---
561
542
 
562
- ## Recovery: When You Find a Platform Bug
543
+ ## 恢复:发现平台错误时(Recovery: When You Find a Platform Bug)
563
544
 
564
- 1. **Fix the immediate issue**
565
- 2. **Search for similar patterns** (grep the codebase)
566
- 3. **Update this guide** with the new pattern
567
- 4. **Add to pre-commit checklist** if recurring
545
+ 1. **修复当前问题**
546
+ 2. **搜索相似模式**(grep 代码库)
547
+ 3. **用新模式更新本指南**
548
+ 4. 如果问题会重复,**加入提交前清单**
568
549
 
569
550
  ---
570
551
 
571
- **Core Principle**: If it's not explicit, it's an assumption. And assumptions break.
552
+ **核心原则(Core Principle)**:没有明确说明的内容就是假设,而假设会失效。
572
553
 
573
554
  ---
574
555
 
575
- ## Release Checklist: Versioned Files
556
+ ## 发布清单:版本化文件(Release Checklist: Versioned Files)
576
557
 
577
- When releasing a new version, ensure **all versioned files** are created/updated:
558
+ 发布新版本时,确保创建或更新**所有版本化文件**:
578
559
 
579
- - [ ] `src/migrations/manifests/{version}.json` - Migration manifest exists
580
- - [ ] Manifest has correct version, description, changelog
581
- - [ ] `pnpm build` copies manifests to `dist/`
582
- - [ ] Test upgrade path from older versions (not just adjacent)
560
+ - [ ] `src/migrations/manifests/{version}.json`——迁移清单存在
561
+ - [ ] 清单包含正确的版本、描述和变更日志
562
+ - [ ] `pnpm build` 将迁移清单复制到 `dist/`
563
+ - [ ] 测试从较旧版本升级的路径(不只相邻版本)
583
564
 
584
- **Why this matters**: Missing manifests cause "path undefined" errors when users upgrade from older versions.
565
+ **原因(Why this matters)**:迁移清单缺失会让从较旧版本升级的用户遇到 "path undefined" 错误。
585
566
 
586
567
  ```bash
587
568
  # Verify all expected manifests exist
@@ -594,23 +575,18 @@ console.log('From 0.2.12:', getMigrationsForVersion('0.2.12', 'CURRENT').length)
594
575
  "
595
576
  ```
596
577
 
597
- ## Release Checklist: Bundled Assets
578
+ ## 发布清单:内置资产(Release Checklist: Bundled Assets)
598
579
 
599
- When release notes or docs claim an asset is bundled, installed automatically, or
600
- included with Trellis, verify the whole distribution path:
580
+ 发布说明或文档宣称某项资产内置、自动安装或随 Trellis 提供时,核验整个分发路径:
601
581
 
602
- - [ ] Source file exists in the branch being tagged, not only in another branch,
603
- docs submodule, or marketplace tree.
604
- - [ ] `pnpm build` copies the asset into `dist/templates/**`.
605
- - [ ] `npm pack --dry-run --json` includes the expected `dist/**` path.
606
- - [ ] The built binary installs the asset in a fresh temp repository.
607
- - [ ] `.trellis/.template-hashes.json` tracks the generated asset path.
608
- - [ ] `trellis update --dry-run` reports `Already up to date!` in that temp
609
- repository.
582
+ - [ ] 源文件存在于将打标签的分支,而非仅在其他分支、文档子模块或 marketplace 目录树中
583
+ - [ ] `pnpm build` 将资产复制到 `dist/templates/**`
584
+ - [ ] `npm pack --dry-run --json` 包含预期的 `dist/**` 路径
585
+ - [ ] 构建后的可执行文件能在新建临时仓库中安装资产
586
+ - [ ] `.trellis/.template-hashes.json` 跟踪生成资产的路径
587
+ - [ ] 临时仓库中 `trellis update --dry-run` 报告 `Already up to date!`
610
588
 
611
- **Why this matters**: docs/changelog text can move independently from the code
612
- branch that owns distributable templates. A feature can be documented as bundled
613
- while the published npm tarball still lacks the files.
589
+ **原因(Why this matters)**:文档和变更日志可以独立于分发模板所属代码分支更新。文档可能已经宣称功能内置,而发布的 npm 包仍缺少相应文件。
614
590
 
615
591
  ```bash
616
592
  pnpm --filter @pennixrv/trellis build