配置: 初始化 ISOS Agent Teams 软件研发模板
CI / lint (push) Successful in 6s

This commit is contained in:
2026-04-19 21:47:08 +08:00
parent 3ab6fe6504
commit 34346be862
202 changed files with 23544 additions and 0 deletions
View File
+52
View File
@@ -0,0 +1,52 @@
# ISOS 自动记忆
> 最后更新: 2026-04-19
> 项目核心规范在 [.claude/CLAUDE.md](../.claude/CLAUDE.md),此处仅记录跨会话学习内容。
## 用户偏好
- [user-preferences](user-preferences.md) — 文档层级管理、上下文管理
- [vcs-preference-jj](vcs-preference-jj.md) — 默认使用 jj 替代 git
- [memory-vs-team-responsibility](memory-vs-team-responsibility.md) — memory 记录项目经验/偏好,team 记录公共跨团队知识
## 文档规范
- [docs-chinese-naming](docs-chinese-naming.md) — docs/ 下所有 .md 文件强制使用中文名字
- [docs-readme-index](docs-readme-index.md) — 按场景加载文档到上下文的入口
- [doc-versioning-rules](doc-versioning-rules.md) — MAJOR 统一、MINOR/PATCH 独立、语义化版本
## 关键经验
- [terminology-consistency](terminology-consistency.md) — 术语澄清方法论:识别→判断→建边界→修复→补规范
- [member-directory-rules](member-directory-rules.md) — member/ 由用户编写或 hook 记录,Claude 禁止修改
- [tasks-directory-location](tasks-directory-location.md) — tasks 文档保存在 /workspace/tasks/
- [tasks-doc-line-limit](tasks-doc-line-limit.md) — 单个任务文件 ≤200 行(编排索引文档除外)
- [font-cross-platform](font-cross-platform.md) — 设计文档字体必须考虑目标平台可用性和 CJK 支持
- [agent-team-collaboration](agent-team-collaboration.md) — Agent 完成后立即 shutdown、验证产出物、SendMessage 带 summary
- [agent-team-tmux-constraints](agent-team-tmux-constraints.md) — 最多 1 Window 4 Pane
- [subagent-alternative](subagent-alternative.md) — GLM 环境下 SubAgent 不可用时用 tmux pane 替代
- [playwright-screenshots](playwright-screenshots.md) — 保存到 `.playwright-screenshots/`
- [agent-pane-cleanup](agent-pane-cleanup.md) — 快照覆盖竞态、清理策略增强、持久化日志
- [claude-code-model-config](claude-code-model-config.md) — settings.json env 覆盖陷阱、tmux 三层传播
- [cc-alias](cc-alias.md) — cc 是 bashrc 函数(runcc.sh),跳过权限用 claude --dangerously-skip-permissions
- [claude-code-rename](claude-code-rename.md) — --name 不可靠,必须用 /rename 持久化会话名称
- [devcontainer-sync](devcontainer-sync.md) — templates/ 是单一信源,运行时文件由 Dockerfile/post-create.sh 生成
- [tmux-send-keys-enter](tmux-send-keys-enter.md) — send-keys 后必须确认 Enter 已生效
## 项目历史
- [desktop-tech-stack-change](desktop-tech-stack-change.md) — PySide6/Qt → PyWebView + Svelte (2026-04-05)
## 设计模式
- [design-patterns](design-patterns.md) — Bridge API 通信、数据流完整性检查
## 参考
- [ui-testing](ui-testing.md) — Playwright E2E 测试方法
- [ci-cd-experience](ci-cd-experience.md) — Python 版本固定、Ruff 规则
- [pdf2md-usage](pdf2md-usage.md) — PDF 转 Markdown 工具(`/isos-pdf2md`
---
*此文件由 Claude 自动记忆功能维护。*
+60
View File
@@ -0,0 +1,60 @@
---
name: Agent Team pane 未关闭修复
description: tmux agent pane 收到关闭要求后未被关闭的根因分析和修复方案
type: feedback
originSessionId: 786eafcb-68a7-48e9-838a-174584e5d9e8
---
# Agent Team tmux Pane 未关闭 — 根因分析与修复
## 问题现象
Agent Team 的 teammate(如 arch-writer-3)收到 `shutdown_request` 后,其 tmux pane 未被关闭,成为孤立 pane。
## 根因分析(3 个)
### 根因 1: 快照文件被覆盖(最关键)
`agent-pane-track.sh``PreToolUse` 分支每次都会覆盖快照文件。当多个 Agent 同时 spawn 时:
```
Pre(Agent-A) → 写快照 S1 (3 panes)
Pre(Agent-B) → 覆盖为 S2 (3 panes,但时间点不同)
Post(Agent-A) → 用 S2 比较 → 可能遗漏 Agent-A 创建的 pane
```
**修复**: 仅在快照文件不存在时才创建(`if [ ! -f "${SNAPSHOT_FILE}" ]`),防止后续 Agent 调用覆盖初始快照。同时快照文件名加入 `team_name` 确保同一 team 共享。
### 根因 2: 清理终止策略不够强
Claude Code 是交互式 Node.js 进程,单次 Ctrl+C 触发确认提示而非退出:
- `sleep 1` 太短(Claude 需要更长时间处理中断)
- `exit` + Enter 在 Claude 仍在运行时被 Claude 拦截
- `kill-pane` 有条件检查,可能跳过
**修复**: 双次 Ctrl+C → 等 3 秒 → exit → 无条件 kill-pane → 验证关闭 → 失败重试。
### 根因 3: 无持久化日志
hook 脚本只写 stderrClaude Code 不持久化 stderr。出问题后无任何痕迹可查。
**修复**: 添加 `.claude/team-panes.log` 持久化日志,记录每次追踪和清理操作。
## Why: 为什么这些根因会导致问题
Agent Team 通常同时 spawn 多个 teammateparallel Agent 调用),这触发了快照覆盖的竞态条件。被遗漏的 pane 不会被记录到 `team-panes.json`,因此 `TeamDelete` 清理时根本不知道这些 pane 的存在。
## How to apply: 后续开发注意事项
1. **tmux hook 脚本必须考虑并发**: 多个 Agent 可能同时触发 hook,共享资源(文件、状态)需要原子操作
2. **kill-pane 应作为最终手段无条件执行**: 不要假设 graceful shutdown 一定成功
3. **持久化日志是必须的**: hook 的 stderr 不会持久化,必须写日志文件
4. **排查孤立 pane 时检查 `team-panes.log`**: 路径 `.claude/team-panes.log`
## 关键文件
| 文件 | 说明 |
|------|------|
| `.claude/hooks/agent-pane-track.sh` | pane 追踪 hook(已修复快照覆盖) |
| `.claude/hooks/team-pane-cleanup.sh` | pane 清理 hook(已增强终止策略) |
| `.claude/team-panes.json` | 运行时状态文件 |
| `.claude/team-panes.log` | 持久化日志(新增) |
+96
View File
@@ -0,0 +1,96 @@
---
name: Agent Team 协同经验教训
description: 基于 2026-04-13 文档团队实战总结的 Agent Team 协同问题、解决方案和关键经验
type: feedback
originSessionId: 4fd99c0b-ce4a-4ce4-8356-91880b65a867
---
# Agent Team 协同经验教训
> 来源: 2026-04-13 文档团队实战(4 Agent 并行:req-writer, ui-designer, ux-writer, claude-md-updater
---
## ⚠️ 关键经验(必须遵循)
### 1. Agent 完成工作后必须立即关闭
**规则**: Agent 完成任务并发送 idle 通知后,主 Agent 必须立即发送 shutdown_request。不要等待用户提醒。
**Why**: 空闲 Agent 持续占用 API 配额和系统资源(每个 Agent 约 1-2GB 内存)。本次任务中,3 个 Agent 完成后空闲了约 15 分钟,直到用户提醒才关闭。
**How to apply**: 收到 idle_notification 且任务已标记 completed 时,立即发送 shutdown_request。不要等「更好的时机」。
### 2. Agent 可能静默完成但不标记任务
**规则**: 不能仅依赖 TaskUpdate 状态判断 Agent 工作完成。必须同时验证产出物是否存在。
**Why**: ui-designer 创建了 2084 行的 docs/05-设计-UI.md 文件,但没有通过 TaskUpdate 将 Task#3 标记为 completed。进度追踪显示 "pending" 但实际已完成。发送进度查询消息后 ui-designer 也未回复。
**How to apply**: 当 Agent 进入 idle 且长时间未更新任务状态时,主动检查文件系统(`ls -la` / `wc -l`)确认产出物。不要仅依赖 TaskList。
### 3. SendMessage 参数格式必须包含 summary
**规则**: SendMessage 的 message 参数为字符串时,必须同时提供 summary 参数。
**Why**: 第一次尝试向 3 个 Agent 发送 shutdown_request 时全部失败,错误信息为 "summary is required when message is a string"。
**How to apply**: 所有 SendMessage 调用都必须包含 summary 字段,无论 message 是字符串还是 JSON 对象。
---
## 一般经验
### Agent 间通信
4. **消息不保证回复**: 向 Agent 发送消息后,Agent 可能进入 idle 而不回复。这不是错误,是 Agent 生命周期行为。需要通过其他手段(文件检查、任务状态)判断进展。
5. **shutdown 协议**: 发送 `{"type": "shutdown_request"}` 后,Agent 会回复 `{"type": "shutdown_response", "approve": true}` 并进入 idle。这是正常的确认流程。
### 文件编辑
6. **Edit 工具对空白敏感**: old_string 必须与文件内容完全匹配,包括制表符和空格。本次任务中 Mermaid 图表编辑失败,原因是 old_string 中的缩进(tab vs spaces)与文件实际内容不匹配。遇到编辑失败时,重新 Read 文件获取精确内容。
7. **大文件分段编辑**: 850 行的 req-review-report.md 不适合一次性替换。策略是按节分段编辑(§1.3 → §4.1 → §4.2 → §5.1 → ...),每次编辑一个小节。这样做的好处是:失败影响范围小、可以逐步验证。
### 团队管理
8. **TaskUpdate 由 Agent 自行完成**: 创建任务时在 prompt 中明确要求「完成后使用 TaskUpdate 标记为 completed」。但不要依赖 Agent 一定会执行。主 Agent 应该在 Agent 报告完成后再次确认。
9. **团队清理顺序**: TeamDelete 之前,确保所有 Agent 已 shutdown。本次任务中先发送 shutdown → 收到确认 → 再执行 TeamDelete,流程正确。
### 任务规划
10. **依赖任务串行执行**: Task#5(更新 req-review-report.md)依赖 Task#1-#4 的结果。通过 TaskUpdate 的 addBlockedBy 设置依赖关系是正确的做法。但阻塞解除后需要主 Agent 手动开始执行,不会自动触发。
11. **并行任务数量控制**: 本次 4 个 Agent 并行工作在 10GB 内存环境下是可行的,但接近上限。建议同时并行不超过 3 个 Agent 执行重 IO/长上下文任务。
---
## 问题清单
| # | 问题 | 影响 | 解决方案 | 严重度 |
|---|------|------|---------|--------|
| 1 | Agent 空闲未主动关闭 | 资源浪费 15min | 收到 idle+completed 立即 shutdown | 高 |
| 2 | ui-designer 未标记任务完成 | 进度追踪不准 | 主 Agent 主动检查文件系统 | 高 |
| 3 | SendMessage 缺 summary 参数 | 关闭请求失败 | 所有 SendMessage 必须带 summary | 中 |
| 4 | Edit 空白不匹配 | 编辑失败需重试 | 失败后重新 Read 获取精确内容 | 低 |
| 5 | Agent 不回复进度查询 | 无法了解进展 | 改用文件系统检查替代 | 中 |
---
## 推荐的 Agent Team 工作流程
```
1. 创建团队 (TeamCreate)
2. 创建任务 (TaskCreate) + 设置依赖 (TaskUpdate addBlockedBy)
3. 启动并行 Agent (Agent tool with team_name)
4. 监控进展:
- 收到 teammate message → 确认产出物
- 收到 idle notification → 检查任务状态 → 完成则立即 shutdown
5. 所有并行任务完成 → 启动依赖任务
6. 所有任务完成 → 发送 shutdown_request → TeamDelete
```
---
*最后更新: 2026-04-13*
+18
View File
@@ -0,0 +1,18 @@
---
name: Agent Team tmux 约束
description: 使用 Agent Team 分配工作时的 tmux 使用规范和容器资源限制
type: feedback
originSessionId: 6ffdfb76-9314-497d-9d3c-8ef5808a343b
---
# Agent Team tmux 约束
## 规则
使用 Agent Team 为 Agent 分配工作时,必须遵守以下约束:
1. **严格遵循 tmux 规范**: 按照 `/workspace/team/tmux.md` 的要求使用 tmux,包括 Session → Window → Pane 三层架构、命名规范、Agent 角色分配等
2. **资源限制**: 开发容器资源有限,只能使用 `/workspace/.claude/commands/isos-tmux-team.md` 来分配团队,确保当前 Session 中最多同时只开启 **1 个 Window、4 个 Pane**
**Why:** 开发容器资源受限,超过 4 个 Pane 会导致性能问题或容器不稳定;tmux.md 定义了团队协作的标准化布局和命名规范,统一使用可避免混乱
**How to apply:** 每次创建 Agent Team 时,先读取 tmux.md 了解规范,然后通过 isos-tmux-team 命令创建团队,不要手动创建额外的 Window 或 Pane,不要使用其他团队分配方式
+11
View File
@@ -0,0 +1,11 @@
---
name: cc 别名说明
description: cc 是 ~/.bashrc 中的函数(非 alias),参数透传到 runcc.sh,支持 -n/--name
type: feedback
originSessionId: 1f32ccfc-9806-4b86-91a1-367a9a07f713
---
`cc``~/.bashrc` 中定义的函数(`cc() { runcc.sh "$@"; }`),参数透传至 runcc.sh。模型快捷别名(cc45/cc51 等)是 `cc <model>` 的简写。runcc.sh 已内置 `--dangerously-skip-permissions`,无需额外传参。支持 `-n/--name` 设置会话名称(走 `/rename` 持久化)。
**Why:** 原先 cc 是 alias 无法灵活传参,改为 function 后 `cc51 -n 后端` 等组合用法自然支持。
**How to apply:** 直接使用 `cc``cc51``cc -n 名称 51` 等,无需手动传 `--dangerously-skip-permissions`
+33
View File
@@ -0,0 +1,33 @@
---
name: CI/CD 经验
description: Python 版本固定、工具版本一致性、Ruff 忽略规则等 CI/CD 相关经验
type: reference
---
# CI/CD 经验
## Python 版本固定
- 使用 `.python-version` 文件固定 Python 版本,确保 CI 和本地开发环境一致
- uv 会自动读取 `.python-version`
- 文件格式:单行版本号,如 `3.12.13`
## 工具版本一致性
- **Server 和 Desktop 的 `pyproject.toml` 必须保持工具版本一致**
- 当前统一版本:
- mypy: `>=1.19.1`
- ruff: `>=0.15.7`
- pytest: `>=9.0.2`
- 过于宽松的版本约束(如 `ruff>=0.2.0`)会导致 CI 检查结果与本地不一致
## Ruff 忽略规则分析
| 风险级别 | 规则 | 建议 |
|---------|------|------|
| 高 | RUF012 (可变类属性) | 应修复,使用 `ClassVar` 注解 |
| 高 | ARG001-005 (未使用参数) | Qt signal handler 场景可忽略 |
| 中 | I001 (导入排序) | 风格问题,可忽略 |
| 低 | RUF001 (中文字符) | 中文注释场景合理忽略 |
| 低 | TC001-003 (TYPE_CHECKING) | 仅影响导入优化,可忽略 |
| 低 | UP042, UP046 (类型语法) | Python 3.12 新语法,可忽略 |
+37
View File
@@ -0,0 +1,37 @@
---
name: Claude Code 模型配置传播
description: runcc.sh/cc4/cc5 模型切换机制,tmux 三层传播方案,settings.json 优先级问题
type: feedback
originSessionId: 3abc1791-7202-45cf-85af-98b1f235a3c9
---
## 模型配置传播机制
**规则**: Claude Code 的 `settings.json` `env` 段优先级高于 shell `export`,会将同名环境变量覆盖。因此模型配置变量(`ANTHROPIC_DEFAULT_*_MODEL`)不能放在 `settings.json` 中,必须通过 `runcc.sh` 启动时删除 + shell export 设置。
**Why**: 用户发现运行 `cc4` 时状态栏仍显示 `glm-5.1`,因为 `settings.json` 中的 `ANTHROPIC_DEFAULT_OPUS_MODEL: "glm-5.1"` 覆盖了 shell 的 `export ANTHROPIC_DEFAULT_OPUS_MODEL="glm-4.7"`
**How to apply**: `runcc.sh` 每次启动时先 `jq 'del(.env.ANTHROPIC_DEFAULT_*)'` 清理 settings.json,再 export 设置,再写入 tmux 三层传播。
## tmux 三层传播
| 层级 | 机制 | 覆盖范围 | 隔离能力 |
|------|------|----------|----------|
| 1 | shell `export` | 当前进程 | 进程级 |
| 2 | `tmux setenv -t <session>` | 该 session 内新 pane | session 级 |
| 3 | `tmux set-option -p @anthropic_*` + `.bashrc` 读取 | 同 session 不同 pane | pane 级 |
## 关键文件
- `runcc.sh` / `templates/runcc.sh`: 删除 settings.json 模型变量 → shell export → tmux 三层传播
- `templates/bashrc.tail.sh`: 新 shell 启动时读取 pane option(容器重建时自动生效)
- `.claude/hooks/agent-pane-track.sh`: 将 PM pane 的模型 option 复制到新增 Agent pane
## 经验教训
1. **settings.json env 优先级陷阱**: Claude Code 读取 settings.json env 并覆盖进程环境变量,即使 shell 已 export。模型切换变量必须从 settings.json 中删除。
2. **tmux 环境继承限制**: tmux 新 pane 从 tmux server 继承环境,不从父 shell 继承。需用 `tmux setenv` / `set-option` 显式传播。
3. **同 session 并发隔离**: `tmux setenv -t` 是 session 级的,同 session 不同 pane 无法隔离。用 pane option (per-pane) 实现隔离,`.bashrc` 读取后覆盖 session 级值。
4. **Agent Team 子 pane**: 新 pane 不继承父 pane 的 pane option,需在 hook 中显式复制。
5. **模板文件同步**: 修改 `runcc.sh``.bashrc` 时,必须同时更新 `templates/` 下的模板文件,确保容器重建后一致。
6. **GLM 模型代码必须完整前缀**: `4.5-air` 无效,正确代码是 `glm-4.5-air`。Explore agent 默认使用 haiku 层级,haiku 模型代码错误导致 Agent tool 报 1211。可用 `curl https://open.bigmodel.cn/api/paas/v4/models` 查询有效模型列表。
7. **settings.json env 的双面性**: 虽然它会覆盖 shell export(需要删除),但在已运行的会话中可临时写入正确值来修复子 agent 模型问题(利用其覆盖优先级),修复后再删除。
+11
View File
@@ -0,0 +1,11 @@
---
name: Claude Code --name vs /rename
description: Claude Code 的 --name CLI 参数不可靠,必须用 /rename 斜杠命令持久化会话名称
type: feedback
originSessionId: b34450b8-ed29-4bd1-9d26-88636b7fa9a6
---
Claude Code v2.1.112+ 的 `--name` CLI 参数不会写入 `custom-title``agent-name` JSONL 记录,仅在内存中设置 `currentSessionTitle`,持久化依赖时序敏感的 `reAppendSessionMetadata()` 竞态条件。`/rename` 斜杠命令显式调用 `AN()` + `oP6()` 写入两条 JSONL 记录,始终可靠。
**Why:** `--name` 是 bridge/remote-control 模式专用参数,缺少完整的持久化路径。UI 显示优先级为 `agentName > customTitle > summary``--name` 两个字段都不写。
**How to apply:** 需要设置会话名称时,将 `/rename <name>` 作为 Claude Code 初始提示传入,而非 `--name`。在 runcc.sh 中:`claude "${CC_ARGS[@]}" "/rename $SESSION_NAME"`
+30
View File
@@ -0,0 +1,30 @@
---
name: 设计模式与经验
description: PyWebView Bridge 通信模式和功能遗漏分析方法
type: reference
originSessionId: 74c25b75-4539-4e2e-befc-145f81f71d59
---
# 设计模式与经验
> 最后更新: 2026-04-19
## PyWebView Bridge API 通信模式
Desktop: Svelte 前端 + Python 后端,通过 pywebview JS Bridge 通信。
**关键规则**:
1. Bridge API 返回 JSON 字符串,前端解析
2. 剪贴板通过 Python 端 pyperclip(绕过 WebKitGTK 限制)
3. 敏感操作在 Python 端处理
## 功能遗漏分析方法
实现涉及数据存储的功能时,必须追踪端到端数据流:
```
数据从哪来?→ 谁处理?→ 存到哪里?→ 谁读取?→ 重启后能加载?
```
**检查清单**:
- 每个生成方法是否有对应保存方法
- config 中定义的路径是否有对应的读写逻辑
- UI 事件处理是否遗漏持久化步骤
+15
View File
@@ -0,0 +1,15 @@
---
name: Desktop 技术栈变更
description: Desktop 模块从 PySide6/Qt 迁移到 PyWebView + Svelte 的决策记录
type: project
originSessionId: 74c25b75-4539-4e2e-befc-145f81f71d59
---
# Desktop 技术栈变更 (2026-04-05)
**评估结果**: `specs/001-desktop-web-evaluation/spec.md`
**变更原因**: Claude 对 Web 前端代码生成准确率(~85-95%)远高于 PySide6~60-70%),Desktop 模块尚未编码(0%),是切换最佳时机。
**新架构**: Svelte SPA 前端 ←→ pywebview JS Bridge ←→ Python 后端
**关键规则**: Bridge API 返回 JSON 字符串 / 剪贴板通过 pyperclip / 敏感操作在 Python 端
+12
View File
@@ -0,0 +1,12 @@
---
name: devcontainer 模板同步机制
description: devcontainer 的模板文件(templates/)是单一信源,Dockerfile/post-create.sh 从模板生成运行时文件
type: reference
originSessionId: b34450b8-ed29-4bd1-9d26-88636b7fa9a6
---
devcontainer 文件生成链路:
1. **`templates/runcc.sh`** → `post-create.sh` 复制到 `.volumes/bin/runcc.sh`
2. **`templates/bashrc.tail.sh`** → `Dockerfile` sed 替换 `{{BIN_PATH}}`/`{{NODE_PATH}}` 占位符后追加到 `~/.bashrc`
修改运行时文件时必须同步更新模板,否则下次 `docker build` 会被覆盖。验证方法:`diff templates/X .volumes/X`,占位符替换后应内容一致。
+35
View File
@@ -0,0 +1,35 @@
---
name: 文档版本号规则
description: 项目所有 markdown 文档的版本号统一规则,包含版本含义和修改条件
type: feedback
originSessionId: bd3aefbc-d5bd-4d0e-8404-0bae02301ed4
---
## 版本号格式
`MAJOR.MINOR.PATCH`(语义化版本)
### 各位含义
| 位 | 含义 | 修改条件 | 示例 |
|----|------|----------|------|
| **MAJOR** | 大版本 | 项目重大重构、文档体系拆分/合并、核心架构变更 | v4 → v5 |
| **MINOR** | 小版本 | 文档内容实质性变更(新增/修改/删除功能需求、架构调整等) | v4.0 → v4.1 |
| **PATCH** | 补丁版本 | 修复错别字、格式调整、术语统一、链接修正 | v4.0.0 → v4.0.1 |
### 核心规则
1. **大版本按需独立**: 当文档发生重大重构(拆分/合并/核心架构变更)时,该文档可独立递增 MAJOR 版本,无需全部文档同步
2. **小版本独立**: 每个文档根据自己的变更频率独立递增 MINOR 版本
3. **补丁版本独立**: 每个文档独立递增 PATCH 版本
4. **版本号位置**: 文档头部 `**文档版本**: X.Y.Z` 格式
5. **版本历史**: 文档末尾必须维护版本历史记录
### 当前状态(2026-04-18
- **v5.x.x**: 测试文档(10-测试-方案、测试-计划、测试-用例、测试-接口、测试-单元及子文档)、04-用户故事、测试-报告
- **v4.x.x**: 其余文档(01-03、05-09、11-13、设计/运维/管理/评审)
- 测试文档因体系拆分(子文档化)升为 v5;用户故事因重构升为 v5
- 设计-Apple风格(原 v1.x)、13-Mermaid图集(原 v1.0.0)、管理-Agent-Team分工(原 v5.0.0)已于 2026-04-18 修正为 v4.x.x
**Why:** 用户发现文档版本号混乱(v1.0.0、v1.1.0、v4.0.0 混用),要求统一管理。后因测试文档体系拆分,部分文档 MAJOR 升至 v5
**How to apply:** 新建文档使用同类别文档的当前 MAJOR 版本;修改文档时按规则递增对应版本位;重大重构时可独立递增 MAJOR
+20
View File
@@ -0,0 +1,20 @@
---
name: docs 文件命名规则
description: docs 目录下 .md 文件的分类前缀命名规范(编号前缀 + 分类前缀)
type: feedback
originSessionId: 5f751a38-a1d3-40a9-bfb3-723b1ab129bf
---
docs/ 目录下所有 .md 文件使用**分类前缀 + 中文描述**的命名规范。前缀表示文档类别,描述部分避免与前缀重复。
**命名规则**
- **核心文档**: `01-` ~ `08-` 编号前缀(按 README 索引顺序)
- 01-用户需求、02-产品需求、03-功能列表、04-用户故事、07-系统架构、08-数据库设计、11-工程规范、09-API契约
- **设计文档**: `设计-` 前缀(如 设计-Apple风格.md、05-设计-UI.md、06-设计-UX.md
- **评审文档**: `评审-` 前缀(位于 review/ 目录,如 评审-需求综合.md、评审-复评.md)
- **管理文档**: `管理-` 前缀(如 12-管理-项目.md、管理-部署实施.md、管理-开发入门.md)
- **运维文档**: `运维-` 前缀(如 运维-安全审计.md、运维-故障排除.md、运维-性能基准.md)
- **测试文档**: `测试-` 前缀(如 10-测试-方案.md、测试-单元.md、测试-端到端.md)
**Why:** 用户要求按分类对 docs/ 文件进行系统化命名,便于快速识别文档类型。
**How to apply:** 创建新文档时根据其类别添加对应前缀。描述部分使用中文,避免与前缀重复(如 "测试-单元.md" 而非 "测试-单元测试.md")。仅 UI/UX 等通用缩写可在描述中保留英文。
+30
View File
@@ -0,0 +1,30 @@
---
name: docs README 快速索引
description: docs/README.md 是项目文档目录索引,按场景加载文档到上下文的入口
type: reference
originSessionId: 5f751a38-a1d3-40a9-bfb3-723b1ab129bf
---
# docs/README.md 快速索引
**位置**: `/workspace/docs/README.md`
**用途**: 项目文档总目录,包含 34 个 .md 文件的分类索引和阅读指引。
## 按场景快速加载
| 场景 | 加载文档 |
|------|----------|
| 快速了解项目 | `docs/01-用户需求.md``docs/07-系统架构.md``docs/03-功能列表.md` |
| 开发准备 | `docs/02-产品需求.md``docs/09-API契约.md``docs/08-数据库设计.md``docs/11-工程规范.md``docs/管理-开发环境搭建.md` |
| UI 开发 | `docs/设计-Apple风格.md``docs/05-设计-UI.md``docs/06-设计-UX.md``team/svelte.md` |
| 测试编写 | `docs/10-测试-方案.md``docs/测试-用例.md``docs/01-用户需求.md`(验收标准) |
| 安全相关 | `docs/02-产品需求.md`(安全架构) → `docs/运维-安全审计.md``docs/运维-性能基准.md` |
| 问题排查 | `docs/运维-故障排除.md``docs/管理-发布日志.md` |
## 文档分区
- **核心文档**(8): 01-用户需求、02-产品需求、03-功能列表、04-用户故事、05-系统架构、06-数据库设计、08-工程规范、07-API契约
- **设计文档**(3): 设计-Apple风格、设计-UI、设计-UX
- **管理文档**(6): 12-管理-项目、管理-部署实施、管理-开发入门、管理-开发环境搭建、管理-发布日志、管理-Agent-Team分工及提示词
- **运维文档**(3): 运维-安全审计、运维-故障排除、运维-性能基准
- **测试文档**(10): 测试-方案/计划/用例 + 测试-单元/功能/集成/系统/接口/端到端/验收
- **评审文档**(4): review/评审-需求综合、review/评审-复评、review/评审-内容一致性检查、review/评审-第二轮内容一致性检查
+26
View File
@@ -0,0 +1,26 @@
---
name: 字体体系跨平台调整经验
description: 设计文档使用平台专有字体(SF Pro)导致跨平台不可用的经验教训
type: feedback
originSessionId: db0433d0-22b3-4676-8741-4963be58cb24
---
## 经验教训:设计文档字体选择必须考虑目标平台可用性
**问题**: 设计文档指定 SF Pro Display/Text 作为排版字体,但 SF Pro 是 Apple 专有字体,在 Ubuntu 24.04 上不可用且不支持中文。
**Why**: 设计时过度参考 Apple 设计规范,未验证字体在目标平台(Linux)上的可用性。SF Pro 既不能合法安装在 Linux 上,也不含 CJK 字形。
**How to apply**:
1. 设计文档中的字体、色彩、组件等设计令牌必须在目标平台上**可实际获取**
2. 涉及 CJK 内容时,必须显式指定中文字体(如 Noto Sans SC
3. Dockerfile/Docker 配置中需要安装对应的字体包
4. 设计变更影响多个文档时,按设计令牌层→界面规格层→交互层逐级同步更新
5. 新项目初始化时就应确定字体体系,避免后期大规模替换
**替换方案**: Inter Display/Inter + Noto Sans SC + JetBrains Mono
- Inter: SF Pro 最佳开源替代品,x-height 和字重分布一致
- fonts-inter 包自带 Inter Display 变体,支持光学尺寸(≥20px 用 Display<20px 用 Inter
- Noto Sans SC: Google 出品 CJK 字体,Ubuntu 24.04 通过 fonts-noto-cjk 安装
- JetBrains Mono: 等宽字体,密码/代码/ID 字段使用
**变更范围**: 15 个文件(1 Dockerfile + 1 CSS + 9 设计文档 + 2 spec/plan + 2 member 日志)
+13
View File
@@ -0,0 +1,13 @@
---
name: member 目录规范
description: member/ 目录由用户主动编写或 hooks 自动记录,Claude 和所有 skills 禁止修改该目录内容
type: feedback
originSessionId: aba293d9-afa4-4828-98e3-1d64ad6e0eec
---
member/ 目录下所有文件由用户主动编写或 `user-prompt-submit.sh` hook 自动记录。
**规则**: Claude、/isos-req 命令及其他所有 skills 禁止修改 member/ 目录下的任何内容。
**Why**: member/ 是用户个人工作笔记空间,记录待办需求、架构思考等。由用户自主管理,Claude 不应干预。
**How to apply**: 任何时候都不要对 member/ 目录下的文件执行 Edit、Write 等写操作。只允许 Read 读取其中的内容作为上下文。
+19
View File
@@ -0,0 +1,19 @@
---
name: memory vs team 目录职责
description: 明确 memory/ 和 team/ 两个目录的内容边界和职责划分
type: feedback
---
## 规则
- **`memory/`** — 记录项目开发过程中的**经验、偏好、如何解决问题**。是 Claude 在开发过程中的个人学习记录,属于项目级、会话级上下文。
- **`team/`** — 记录具有**公共性质、能跨项目、跨团队成员**的经验和知识。是团队共享的规范和指南,属于通用级、团队级上下文。
**Why:** 两个目录定位不同。memory 是 Claude 的私有学习笔记,跟随项目;team 是团队公共知识库,可以跨项目复用。混用会导致职责不清、内容重复。
**How to apply:**
- 记忆文件必须保存在 `/workspace/memory/` 目录(由 `settings.local.json``autoMemoryDirectory` 配置)
- 写入前先判断内容的受众和复用范围
- 经验教训、偏好设定、问题排查 → `memory/`
- 编码规范、工具指南、团队流程 → `team/`
- 如果内容对其他开发者或其他项目也有用 → 放 `team/`
+43
View File
@@ -0,0 +1,43 @@
---
name: pdf2md 用法
description: PDF 转 Markdown 工具用法备忘,包括命令、参数、已知限制
type: reference
originSessionId: f1461373-2a42-4aa6-a186-df9af265c034
---
# pdf2md 工具用法
## 快速使用
```bash
# 基本转换
/workspace/scripts/pdf2md.sh input.pdf
# 指定输出
/workspace/scripts/pdf2md.sh input.pdf -o output.md
# 页码范围
/workspace/scripts/pdf2md.sh input.pdf -f 1 -l 10
# 原始文本(跳过后处理)
/workspace/scripts/pdf2md.sh input.pdf --raw
# 输出到 stdout
/workspace/scripts/pdf2md.sh input.pdf -o -
```
## 触发方式
- Claude Code Skill: `/isos-pdf2md <path>`
- 命令行: `/workspace/scripts/pdf2md.sh`
- Skill 文件: `.claude/skills/isos-pdf2md/SKILL.md`
## 依赖
- `poppler-utils`(提供 `pdftotext`
## 已知限制
- 不支持扫描件/图片型 PDF
- 复杂表格识别有限
- 多栏布局可能交错
- 不提取图片
+10
View File
@@ -0,0 +1,10 @@
---
name: Playwright 截图默认保存目录
description: 使用 Playwright 截图时默认保存到 .playwright-screenshots/ 目录
type: feedback
---
Playwright 截图必须保存在 `.playwright-screenshots/` 目录。`filename` 参数使用 `.playwright-screenshots/截图名称.png` 格式。
**Why:** 用户要求统一截图存放位置,保持项目根目录整洁。该目录已在 .gitignore 中配置。
**How to apply:** 调用 `browser_take_screenshot``filename` 使用 `.playwright-screenshots/<name>.png`
+18
View File
@@ -0,0 +1,18 @@
---
name: SubAgent 替代方案
description: GLM 环境下 Agent tool SubAgent 不可用时的替代方案:通过 tmux 创建独立 pane 执行并行任务
type: feedback
originSessionId: 6ac4a596-249e-45e3-bda1-6749001cc67c
---
当需要 SubAgent 但遇到 "模型不存在" 错误时,优先检查模型代码是否正确,再考虑 tmux 替代方案。
**Why:** `ANTHROPIC_DEFAULT_HAIKU_MODEL` 曾配置为 `4.5-air`(缺少 `glm-` 前缀),GLM API 报错 code 1211。已修正为 `glm-4.5-air`。Explore agent 默认使用 haiku 层级,因此最容易触发此错误。
**How to apply:**
1. Agent tool 报 1211 错误时,先检查对应层级的模型代码是否在 GLM API 上有效(`curl https://open.bigmodel.cn/api/paas/v4/models`
2. 如确认模型不可用,用 tmux pane 替代:`tmux split-window` → 新 pane 启动 `cc` → 文件系统协调结果
3. 简单任务直接用 Grep/Read 工具串行执行,无需创建 pane
相关工具:
- `/isos-tmux-team` 命令可创建 4-pane 团队布局(PM + Agent-A + Agent-B + Ops
- `scripts/tmux-team.sh` 底层实现脚本
+11
View File
@@ -0,0 +1,11 @@
---
name: tasks 目录位置
description: tasks 相关文档保存在项目根目录 /workspace/tasks/ 下
type: feedback
originSessionId: cdc3d1c2-1a21-44b0-8e76-1f85907b3977
---
tasks 相关文档必须保存在 `/workspace/tasks/` 目录下(项目根目录),不再使用 `.claude/tasks/`
**Why:** 用户于 2026-04-18 将 `.claude/tasks/` 迁移到 `tasks/`,使任务文档脱离 `.claude` 配置目录,更符合项目文件组织结构。
**How to apply:** 创建、更新任务相关文档时,路径使用 `/workspace/tasks/` 而非 `.claude/tasks/`
+15
View File
@@ -0,0 +1,15 @@
---
name: 提示词文档行数限制
description: tasks/ 和 .claude/commands/ 下的提示词文档强制不超过 200 行;编排索引文档例外
type: feedback
originSessionId: a7730210-c9bf-47df-8cec-a1a13a5e953d
---
## 规则:提示词文档 ≤200 行
**强制性要求**`tasks/``.claude/commands/` 目录下的每个提示词文档不能超过 200 行。
例外:`tasks/任务提示词目录和任务编排.md` 作为总索引和编排文档,不受 200 行限制,但尽量不超过 400 行。
**Why:** 用户于 2026-04-18 明确要求(2026-04-19 扩展至 commands),超过 200 行的提示词文档会导致 Agent 上下文过载、执行效率下降。
**How to apply:** 创建或更新提示词文档时,必须在完成后检查行数。如果超过 200 行,需拆分为多个文件或精简内容。编排索引文档除外。
+28
View File
@@ -0,0 +1,28 @@
---
name: 文档术语一致性
description: 术语歧义识别与统一方法论:设备vs客户端的澄清经验
type: feedback
originSessionId: 28a03600-d3f7-4b7e-bc74-4c53961c17b5
---
## 规则:文档术语必须语义边界清晰
**Why**: 项目文档中容易存在语义重叠的术语,导致越界混用。歧义术语不解决会随文档增长而扩散。
**How to apply**:
1. **识别重叠**:grep 统计两个候选词的出现频率和上下文
2. **判断是否可合并**:若语义完全相同则统一为一个词;若描述不同视角则保留两者但建边界
3. **制定规则**:按场景划分各术语的适用范围(如:密码统一用"客户端密码")
4. **修复越界**:仅修改不符合规则的用法,保留合理的
5. **补充规范**:在 `docs/11-工程规范.md` 术语表记录规则
### 已完成的术语澄清
| 术语 | 规则 | 文档 |
|------|------|------|
| 设备 vs 客户端 | 设备=服务端注册实体(ID/授权/管理);客户端=用户软件(密码/登录/功能) | `docs/11-工程规范.md` §1.5 |
### 术语边界定义(示例)
- 识别项目中语义重叠的术语对
- 按场景划分各术语的适用范围
- 在工程规范文档中记录规则
+41
View File
@@ -0,0 +1,41 @@
---
name: tmux send-keys 回车问题
description: tmux send-keys 发送长文本到 cc 时 Enter 可能未生效,已创建 tmux-send-prompt.sh 脚本解决
type: feedback
originSessionId: 1f32ccfc-9806-4b86-91a1-367a9a07f713
---
## 问题
`tmux send-keys -t %1 '长中文文本...' Enter` 在 cc 输入框中,Enter 可能未被正确接收。
## 根因
1. **文本和 Enter 同时发送**: `tmux send-keys 'text' Enter` 在长文本场景下,Enter 可能在 cc 还未准备好接收时就被发送
2. **前一个命令未完成**: `/effort max` 执行后 sleep 时间不够(只等 5s),cc 的 prompt(❯)还没出现
3. **无法确认提交状态**: 没有验证 Enter 是否生效
## 解决方案
使用 `/workspace/scripts/tmux-send-prompt.sh` 脚本:
```bash
/workspace/scripts/tmux-send-prompt.sh <pane_id> '文本内容'
/workspace/scripts/tmux-send-prompt.sh <pane_id> /path/to/prompt.md
```
脚本做了 4 件事:
1. 等待 prompt 就绪(检测 ❯ 字符,最多 30s)
2. 文本和 Enter 分开发送(先文本→sleep 1s→Enter
3. 验证提交状态(检查输入框是否清空)
4. 自动重试(最多 3 次)
## 手动发送注意事项
```bash
# 1. 发送文本(不带 Enter
tmux send-keys -t %1 '长文本内容'
sleep 1
# 2. 单独发送 Enter
tmux send-keys -t %1 Enter
sleep 2
# 3. 验证
tmux capture-pane -t %1 -p | tail -5
```
**Why:** pane-1/pane-2 发送评审任务后 Enter 未生效,内容停留在输入框中
**How to apply:** 向 cc 发送长文本时用 tmux-send-prompt.sh 脚本;手动发送时分两步(文本→sleep→Enter→验证)
+31
View File
@@ -0,0 +1,31 @@
---
name: UI 测试方法
description: Desktop 界面 Playwright E2E 测试方法
type: reference
originSessionId: 74c25b75-4539-4e2e-befc-145f81f71d59
---
# Desktop UI 测试方法
## 测试位置
```
apps/desktop/tests/
├── e2e/ # Playwright 端到端测试
├── unit/ # Python 后端单元测试
└── conftest.py
```
## 关键命令
```bash
uv run playwright install chromium # 首次安装
uv run pytest tests/e2e/ -v # 运行 E2E 测试
uv run pytest tests/e2e/ --headed -v # 调试模式
```
## 技术要点
- 所有可交互元素使用 `data-testid` 标识
- 开发时 Vite dev server (`localhost:5173`),生产用 `dist/index.html`
- 测试时可 mock `window.pywebview.api`
- Playwright 自动等待元素,无需手动 sleep
+11
View File
@@ -0,0 +1,11 @@
---
name: 用户偏好
description: 用户的开发偏好和工作方式
type: user
originSessionId: 74c25b75-4539-4e2e-befc-145f81f71d59
---
# 用户偏好
-`CLAUDE.md` 是入口指令,`.claude/CLAUDE.md` 是完整规范
- 偏好使用文档层级管理,避免信息重复
- 上下文接近上限时主动执行 `/compact`
+41
View File
@@ -0,0 +1,41 @@
---
name: VCS 偏好 jj
description: 默认使用 jj 替代 git 进行版本控制操作,含 fetch/同步/divergent 处理经验
type: feedback
originSessionId: 9d12ba86-e9e5-44bf-8d5b-7df3b86f5224
---
默认使用 Jujutsu (jj) 替代 git 进行版本控制操作。所有 bash 脚本、Python 代码、skills、commands 和文档中的 git 命令应优先使用 jj 等价命令。
**Why:** 用户决定将版本控制工具从 git 迁移到 jj。
**How to apply:**
- 新脚本/代码使用 jj 命令
- 修改现有文件时将 git 命令替换为 jj 等价命令
- 提交规范保持中文类型不变(`team/git.md` 中的规范仍适用)
- 参考命令对照表: `team/jj.md`
- jj 相关术语在文档中统一使用中文(书签、变基、摘选、变更标识、提交标识、版本集查询、并存模式等),仅命令行代码中保留英文原文
### Agent 并行开发
- jj 原生支持多工作副本(`jj workspace add`),详见 `team/jj.md`
- Claude Code Agent 并行开发**推荐使用内置 `EnterWorktree`**(走 git worktree),无需手动创建 jj workspace
- Agent 完成后主目录通过 `jj git fetch && jj git import` 同步
- 禁止多个 Agent 在同一目录编辑,必须各自在独立 worktree 中工作
### 远程同步与 Divergent 处理
**Why:** 2026-04-14 遇到 jj `git fetch` 返回 "Nothing changed" 但远程 trunk 实际有新提交的情况,根因是 divergent change ID 导致视觉混乱 + `auto-track-bookmarks` 默认关闭。
**How to apply:**
1. **fetch 后工作区不跟随远程书签时**`jj rebase -r @ -d trunk`
2. **出现 divergent change ID 时**:用 `jj op log` 查明原因,必要时 `jj op restore <id>` 回退
3. **不要轻易 `jj abandon` divergent 版本**:如果它是另一个版本的祖先,会产生冲突;应优先用 `jj op restore`
4. **已配置 `remotes.origin.auto-track-bookmarks = '*'`**:fetch 后本地书签自动跟随远程,容器重建也不会丢失(post-create.sh + 卷挂载双重保障)
5. **排查 fetch 问题时**:用 `jj bookmark list --all` 对比 `@origin` 和本地书签指向,用 `git log HEAD..origin/trunk` 交叉验证
### jj 配置持久化
- 用户级配置路径:`~/.config/jj/config.toml`
- DevContainer 中通过 `post-create.sh` 自动设置 + `.volumes/jj` 卷挂载持久化
- 关键配置:`user.name``user.email``remotes.origin.auto-track-bookmarks`