swain-doctor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDoctor
Doctor
Session-start health checks for swain projects. Validates and repairs health across all swain skills — governance, tools, directories, settings, scripts, caches, and runtime state. Idempotent — run it every session; it only writes when repairs are needed.
Run checks in the order listed below. Collect all findings into a summary table at the end.
针对swain项目的会话启动健康检查工具。可校验并修复所有swain skill的健康问题:包括治理规则、工具、目录、配置、脚本、缓存和运行时状态。具备幂等性——每次会话都可运行,仅当需要修复时才会执行写入操作。
请按照下方列出的顺序执行检查,最后将所有检查结果汇总到摘要表格中。
Session-start governance check
会话启动治理检查
-
Detect the agent platform and locate the context file:
Platform Context file Detection Claude Code (project root)CLAUDE.mdDefault — use if no other platform detected Cursor .cursor/rules/swain-governance.mdcdirectory exists.cursor/ -
Check whether governance rules are already present:bash
grep -l "swain governance" CLAUDE.md AGENTS.md .cursor/rules/swain-governance.mdc 2>/dev/nullIf any file matches, governance is already installed. Proceed to Legacy skill cleanup. -
If no match, run Legacy skill cleanup, then proceed to Governance injection.
-
检测Agent平台并定位上下文文件:
平台 上下文文件 检测规则 Claude Code (项目根目录)CLAUDE.md默认规则 —— 未检测到其他平台时使用 Cursor .cursor/rules/swain-governance.mdc存在 目录时判定.cursor/ -
检查是否已存在治理规则:bash
grep -l "swain governance" CLAUDE.md AGENTS.md .cursor/rules/swain-governance.mdc 2>/dev/null若有任意文件匹配,说明治理规则已安装,直接进入遗留skill清理步骤。
Legacy skill cleanup
遗留skill清理
Clean up skill directories that have been superseded by renames or retired entirely. Read the legacy mapping from in this skill's directory.
references/legacy-skills.json清理已被重命名或完全弃用的skill目录,从此skill目录下的文件读取遗留映射关系。
references/legacy-skills.jsonRenamed skills
已重命名的skill
For each entry in the map:
renamed- Check whether exists.
.claude/skills/<old-name>/ - If it does NOT exist, skip (nothing to clean).
- If it exists, check whether also exists. If the replacement is missing, skip and warn — the update may not have completed:
.claude/skills/<new-name>/Skipping cleanup of— its replacement<old-name>is not installed.<new-name> - If both exist, fingerprint check: read and check whether its content matches ANY of the fingerprints listed in
.claude/skills/<old-name>/SKILL.md. Specifically, grep the file for each fingerprint string — if at least one matches, the skill is confirmed to be a swain skill.legacy-skills.json - If no fingerprint matches, skip and warn — this may be a third-party skill with the same name:
Skipping cleanup of— it does not appear to be a swain skill (no fingerprint match). If this is a stale swain skill, delete it manually.
.claude/skills/<old-name>/ - If fingerprint matches and replacement exists, delete the old directory:
Tell the user:bash
rm -rf .claude/skills/<old-name>Removed legacy skill(replaced by.claude/skills/<old-name>/).<new-name>
遍历映射中的每条记录:
renamed- 检查目录是否存在。
.claude/skills/<old-name>/ - 若不存在,跳过(无内容需要清理)。
- 若存在,检查目录是否也存在。如果替换版本不存在,跳过并发出警告——可能是更新尚未完成:
.claude/skills/<new-name>/跳过的清理——其替换版本<old-name>尚未安装。<new-name> - 若两个目录都存在,执行指纹校验:读取的内容,检查是否匹配
.claude/skills/<old-name>/SKILL.md中列出的任意指纹。具体操作是对每个指纹字符串执行grep匹配——只要有一个匹配,即可确认该skill是官方swain skill。legacy-skills.json - 若无匹配的指纹,跳过并发出警告——这可能是同名的第三方skill:
跳过的清理——该目录看起来不是swain skill(无匹配指纹)。如果确认是过时的swain skill,请手动删除。
.claude/skills/<old-name>/ - 若指纹匹配且替换版本存在,删除旧目录:
告知用户:bash
rm -rf .claude/skills/<old-name>已移除遗留skill(已被.claude/skills/<old-name>/替代)。<new-name>
Retired skills
已弃用的skill
For each entry in the map (pre-swain skills absorbed into the ecosystem):
retired- Check whether exists.
.claude/skills/<old-name>/ - If it does NOT exist, skip (nothing to clean).
- If it exists, fingerprint check: same as for renamed skills — read and check whether its content matches ANY fingerprint in
.claude/skills/<old-name>/SKILL.md.legacy-skills.json - If no fingerprint matches, skip and warn:
Skipping cleanup of— it does not appear to be a known pre-swain skill (no fingerprint match). Delete manually if stale.
.claude/skills/<old-name>/ - If fingerprint matches, delete the old directory:
Tell the user:bash
rm -rf .claude/skills/<old-name>Removed retired pre-swain skill(functionality now in.claude/skills/<old-name>/).<absorbed-by>
After processing all entries, check whether the governance block in the context file references old skill names. If the governance block (between and ) contains any old-name from the map, delete the entire block (inclusive of markers) and proceed to Governance injection to re-inject a fresh copy with current names.
<!-- swain governance --><!-- end swain governance -->renamed遍历映射中的每条记录(被生态吸收的pre-swain skill):
retired- 检查目录是否存在。
.claude/skills/<old-name>/ - 若不存在,跳过(无内容需要清理)。
- 若存在,执行指纹校验:和重命名skill的校验规则一致——读取的内容,检查是否匹配
.claude/skills/<old-name>/SKILL.md中的任意指纹。legacy-skills.json - 若无匹配的指纹,跳过并发出警告:
跳过的清理——该目录看起来不是已知的pre-swain skill(无匹配指纹)。如果确认已过时,请手动删除。
.claude/skills/<old-name>/ - 若指纹匹配,删除旧目录:
告知用户:bash
rm -rf .claude/skills/<old-name>已移除已弃用的pre-swain skill(功能已整合到.claude/skills/<old-name>/中)。<absorbed-by>
处理完所有条目后,检查上下文文件中的治理规则块是否引用了旧的skill名称。如果治理规则块(位于和之间)包含映射中的任意旧名称,删除整个规则块(包含标记符),然后进入治理规则注入步骤,重新注入包含最新名称的规则副本。
<!-- swain governance --><!-- end swain governance -->renamedPlatform dotfolder cleanup
平台点文件夹清理
The command (or older versions of swain-update without autodetect) creates dotfolder stubs (e.g., , ) for agent platforms that are not installed. These directories only contain symlinks back to and clutter the working tree. See GitHub issue #21.
npx skills add --all.windsurf/.cursor/.agents/skills/Read the platform data from in this skill's directory. Each entry in the array has a name and one or both detection strategies: (CLI binary name) and (HOME config directory path). Entries with collision-prone command names (e.g., , , , ) omit and rely on HOME detection only.
references/platform-dotfolders.jsonplatformsproject_dotfoldercommanddetectioncmdcortexmuxpicommandnpx skills add --all.windsurf/.cursor/.agents/skills/从此skill目录下的文件读取平台数据。数组中的每个条目都包含名称,以及一种或两种检测策略:(CLI二进制文件名)和(HOME配置目录路径)。命令名称容易冲突的条目(例如、、、)不包含字段,仅依赖HOME目录检测。
references/platform-dotfolders.jsonplatformsproject_dotfoldercommanddetectioncmdcortexmuxpicommandStep 1 — Autodetect installed platforms
步骤1 —— 自动检测已安装的平台
Iterate over the array. For each entry, a platform is considered installed if either check succeeds:
platforms- If the entry has a field → run
command.command -v <command> &>/dev/null - If the entry has a field → expand the path (replace
detectionwith~, evaluate env var defaults like$HOME) and check whether the directory exists.${CODEX_HOME:-~/.codex}
Always consider installed (current platform — never a cleanup candidate).
.claudeRequires: (for reading the JSON). If is not available, skip this section and warn.
jqjqbash
installed_dotfolders=(".claude")
while IFS= read -r entry; do
dotfolder=$(echo "$entry" | jq -r '.project_dotfolder')
cmd=$(echo "$entry" | jq -r '.command // empty')
det=$(echo "$entry" | jq -r '.detection // empty')
found=false
if [[ -n "$cmd" ]] && command -v "$cmd" &>/dev/null; then
found=true
fi
if [[ -n "$det" ]] && ! $found; then
det_expanded=$(echo "$det" | sed "s|~|$HOME|g")
det_expanded=$(eval echo "$det_expanded" 2>/dev/null)
[[ -d "$det_expanded" ]] && found=true
fi
$found && installed_dotfolders+=("$dotfolder")
done < <(jq -c '.platforms[]' "SKILL_DIR/references/platform-dotfolders.json")(Replace with the actual path to this skill's directory.)
SKILL_DIR遍历数组,对于每个条目,只要满足任意一项检查,即认为平台已安装:
platforms- 如果条目包含字段 → 执行
command。command -v <command> &>/dev/null - 如果条目包含字段 → 展开路径(将
detection替换为~,解析环境变量默认值,例如$HOME),检查目录是否存在。${CODEX_HOME:-~/.codex}
始终认为已安装(当前平台——永远不会作为清理候选)。
.claude依赖: (用于读取JSON)。如果没有安装,跳过此部分并发出警告。
jqjqbash
installed_dotfolders=(".claude")
while IFS= read -r entry; do
dotfolder=$(echo "$entry" | jq -r '.project_dotfolder')
cmd=$(echo "$entry" | jq -r '.command // empty')
det=$(echo "$entry" | jq -r '.detection // empty')
found=false
if [[ -n "$cmd" ]] && command -v "$cmd" &>/dev/null; then
found=true
fi
if [[ -n "$det" ]] && ! $found; then
det_expanded=$(echo "$det" | sed "s|~|$HOME|g")
det_expanded=$(eval echo "$det_expanded" 2>/dev/null)
[[ -d "$det_expanded" ]] && found=true
fi
$found && installed_dotfolders+=("$dotfolder")
done < <(jq -c '.platforms[]' "SKILL_DIR/references/platform-dotfolders.json")(将替换为此skill目录的实际路径。)
SKILL_DIRStep 2 — Build cleanup candidates
步骤2 —— 构建清理候选列表
Every entry in whose is NOT in the list is a cleanup candidate.
platformsproject_dotfolderinstalled_dotfoldersplatformsproject_dotfolderinstalled_dotfoldersStep 3 — Remove installer stubs
步骤3 —— 移除安装程序存根
For each candidate dotfolder:
-
Check whether the directory exists in the project root.
-
If it does NOT exist, skip.
-
If it exists, verify it is installer-generated — the directory should contain only asubdirectory (possibly with symlinks or further subdirectories). Check:
skills/bash# Count top-level entries (excluding . and ..) entries=$(ls -A "<dotfolder>" 2>/dev/null | wc -l) # Check if the only entry is "skills" if [[ "$entries" -le 1 ]] && [[ -d "<dotfolder>/skills" || "$entries" -eq 0 ]]; then # Safe to remove — installer-generated stub fi- If the directory is empty OR contains only a subdirectory → remove it:
skills/bashrm -rf <dotfolder> - If the directory contains other files or directories besides → skip and warn:
skills/Skipping— contains user content beyond installer symlinks. Remove manually if unused.<dotfolder>
- If the directory is empty OR contains only a
-
After processing all entries, report:Removed N platform dotfolder(s) created by(installer stubs for unused agent platforms).
npx skills addIf none were found, this step is silent.
遍历每个候选点文件夹:
-
检查项目根目录下是否存在该目录。
-
若不存在,跳过。
-
若存在,验证是否为安装程序生成——该目录应仅包含子目录(可能包含符号链接或更多子目录)。检查规则:
skills/bash# 统计顶级条目数量(排除.和..) entries=$(ls -A "<dotfolder>" 2>/dev/null | wc -l) # 检查是否唯一的条目是"skills" if [[ "$entries" -le 1 ]] && [[ -d "<dotfolder>/skills" || "$entries" -eq 0 ]]; then # 可安全移除——安装程序生成的存根 fi- 如果目录为空 OR 仅包含子目录 → 移除该目录:
skills/bashrm -rf <dotfolder> - 如果目录中除了之外还有其他文件或目录 → 跳过并发出警告:
skills/跳过的清理——包含安装程序符号链接之外的用户内容。如果确认未使用,请手动移除。<dotfolder>
- 如果目录为空 OR 仅包含
-
处理完所有条目后,报告:已移除生成的N个平台点文件夹(未使用的Agent平台的安装程序存根)。
npx skills add若未找到任何存根,此步骤无输出。
Governance injection
治理规则注入
When governance rules are not found (or were deleted during legacy cleanup), inject them into the appropriate context file.
当未找到治理规则(或在遗留清理过程中被删除)时,将规则注入到对应的上下文文件中。
Claude Code
Claude Code
Determine the target file:
- If exists and its content is just
CLAUDE.md(the include pattern set up by swain-init), inject into@AGENTS.mdinstead.AGENTS.md - Otherwise, inject into (create it if it doesn't exist).
CLAUDE.md
Read the canonical governance content from (relative to this skill's directory) and append it to the target file.
references/AGENTS.content.md确定目标文件:
- 如果存在且内容仅为
CLAUDE.md(swain-init设置的包含模式),则改为注入到@AGENTS.md中。AGENTS.md - 否则,注入到中(如果文件不存在则创建)。
CLAUDE.md
从此skill目录下的读取标准治理内容,追加到目标文件末尾。
references/AGENTS.content.mdCursor
Cursor
Write the governance rules to . Create the directory if needed.
.cursor/rules/swain-governance.mdcPrepend Cursor MDC frontmatter to the canonical content from :
references/AGENTS.content.mdmarkdown
---
description: "swain governance — skill routing, pre-implementation protocol, issue tracking"
globs:
alwaysApply: true
---Then append the full contents of after the frontmatter.
references/AGENTS.content.md将治理规则写入,如果目录不存在则创建。
.cursor/rules/swain-governance.mdc在的标准内容前添加Cursor MDC前置元数据:
references/AGENTS.content.mdmarkdown
---
description: "swain governance — skill路由、预实现协议、问题跟踪"
globs:
alwaysApply: true
---然后将的完整内容追加到元数据之后。
references/AGENTS.content.mdAfter injection
注入完成后
Tell the user:
Governance rules installed in. These ensure swain-design, swain-do, and swain-release skills are routable. You can customize the rules — just keep the<file>markers so this skill can detect them on future sessions.<!-- swain governance -->
告知用户:
治理规则已安装到。这些规则可确保swain-design、swain-do和swain-release skill可被路由。你可以自定义规则——只需保留<file>标记,这样此skill在后续会话中可以检测到这些规则。<!-- swain governance -->
Beads gitignore hygiene
Beads gitignore合规检查
This section runs every session, after governance checks. It is idempotent. Skip entirely if does not exist (the project has not initialized bd yet).
.beads/此部分在每次会话的治理检查之后运行,具备幂等性。如果不存在则完全跳过(项目尚未初始化bd)。
.beads/Step 1 — Validate .beads/.gitignore
步骤1 —— 校验.beads/.gitignore
The following are the canonical ignore patterns. This list is kept in sync with in this skill's directory.
references/.beads-gitignoreCanonical patterns (non-comment, non-blank lines):
dolt/
dolt-access.lock
bd.sock
bd.sock.startlock
sync-state.json
last-touched
.local_version
redirect
.sync.lock
export-state/
ephemeral.sqlite3
ephemeral.sqlite3-journal
ephemeral.sqlite3-wal
ephemeral.sqlite3-shm
dolt-server.pid
dolt-server.log
dolt-server.lock
dolt-server.port
dolt-server.activity
dolt-monitor.pid
backup/
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm
db.sqlite
bd.db
.beads-credential-key-
Ifdoes not exist, create it from the reference file (
.beads/.gitignore) and skip to Step 2.references/.beads-gitignore -
Read. For each canonical pattern above, check whether it appears as a non-comment line in the file.
.beads/.gitignore -
Collect any missing patterns. If none are missing, this step is silent — move to Step 2.
-
If patterns are missing, append them to:
.beads/.gitignore# --- swain-managed entries (do not remove) --- <missing patterns, one per line> -
Tell the user:Patchedwith N missing entries. These entries prevent runtime and database files from being tracked by git.
.beads/.gitignore
以下是标准忽略规则列表,与此skill目录下的保持同步。
references/.beads-gitignore标准规则(非注释、非空行):
dolt/
dolt-access.lock
bd.sock
bd.sock.startlock
sync-state.json
last-touched
.local_version
redirect
.sync.lock
export-state/
ephemeral.sqlite3
ephemeral.sqlite3-journal
ephemeral.sqlite3-wal
ephemeral.sqlite3-shm
dolt-server.pid
dolt-server.log
dolt-server.lock
dolt-server.port
dolt-server.activity
dolt-monitor.pid
backup/
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm
db.sqlite
bd.db
.beads-credential-key-
如果不存在,从参考文件
.beads/.gitignore创建该文件,直接进入步骤2。references/.beads-gitignore -
读取,对上面列出的每个标准规则,检查是否作为非注释行存在于文件中。
.beads/.gitignore -
收集所有缺失的规则,若无缺失,此步骤无输出——进入步骤2。
-
如果有缺失的规则,将它们追加到末尾:
.beads/.gitignore# --- swain管理的条目(请勿删除) --- <缺失的规则,每行一个> -
告知用户:已为补充N条缺失的条目。这些条目可避免运行时文件和数据库文件被git跟踪。
.beads/.gitignore
Step 2 — Clean tracked runtime files
步骤2 —— 清理已跟踪的运行时文件
After ensuring the gitignore is correct, check whether git is still tracking files that should now be ignored:
bash
cd "$(git rev-parse --show-toplevel)" && git ls-files --cached .beads/ | while IFS= read -r f; do
if git check-ignore -q "$f" 2>/dev/null; then
echo "$f"
fi
doneThis lists files that are both tracked (in the index) and matched by the current gitignore rules.
If no files are found, this step is silent.
If files are found:
-
Remove them from the index (this untracks them without deleting from disk):bash
git rm --cached <file1> <file2> ... -
Tell the user:Untracked N file(s) from git that are now covered by. These files still exist on disk but will no longer be committed. You should commit this change.
.beads/.gitignore
确认gitignore规则正确后,检查git是否仍在跟踪现在应该被忽略的文件:
bash
cd "$(git rev-parse --show-toplevel)" && git ls-files --cached .beads/ | while IFS= read -r f; do
if git check-ignore -q "$f" 2>/dev/null; then
echo "$f"
fi
done该命令会列出既在暂存区中被跟踪,又匹配当前gitignore规则的文件。
若未找到任何文件,此步骤无输出。
若找到匹配文件:
-
将它们从暂存区移除(仅取消跟踪,不会删除磁盘上的文件):bash
git rm --cached <file1> <file2> ... -
告知用户:已从git中取消跟踪N个现在被覆盖的文件。这些文件仍存在于磁盘上,但不会被提交。建议你提交此变更。
.beads/.gitignore
Governance content reference
治理内容参考
The canonical governance rules live in (relative to this skill's directory). Both swain-doctor and swain-init read from this single source of truth. If the upstream rules change in a future swain release, update that file and bump the skill version. Consumers who want the updated rules can delete the block from their context file and re-run this skill.
references/AGENTS.content.md<!-- swain governance -->标准治理规则存放在此skill目录下的中。swain-doctor和swain-init都从此单一数据源读取规则。如果上游规则在未来的swain版本中发生变更,更新该文件并提升skill版本即可。需要更新规则的用户可以从上下文文件中删除块,重新运行此skill即可。
references/AGENTS.content.md<!-- swain governance -->Tool availability
工具可用性检查
Check for required and optional external tools. Report results as a table. Never install tools automatically — only inform the user what's missing and how to install it.
检查必填和可选的外部工具,将结果以表格形式报告。绝对不要自动安装工具——仅告知用户缺失的工具以及安装方式。
Required tools
必选工具
These tools are needed by multiple skills. If missing, warn the user.
| Tool | Check | Used by | Install hint (macOS) |
|---|---|---|---|
| | All skills | Xcode Command Line Tools |
| | swain-status, swain-stage, swain-session, swain-do | |
多个skill都需要这些工具,如果缺失,向用户发出警告。
| 工具 | 检查命令 | 使用方 | 安装提示(macOS) |
|---|---|---|---|
| | 所有skill | Xcode Command Line Tools |
| | swain-status, swain-stage, swain-session, swain-do | |
Optional tools
可选工具
These tools enable specific features. If missing, note which features are degraded.
| Tool | Check | Used by | Degradation | Install hint (macOS) |
|---|---|---|---|---|
| | swain-do, swain-status (tasks) | Task tracking falls back to text ledger; status skips task section | |
| | swain-stage (MOTD TUI), swain-do (plan ingestion) | MOTD falls back to bash script; plan ingestion unavailable | |
| | swain-status (GitHub issues), swain-release | Status skips issues section; release can't create GitHub releases | |
| | swain-stage | Workspace layouts unavailable (only relevant if user wants tmux features) | |
| | swain-design (specwatch live mode) | Live artifact watching unavailable; on-demand | |
这些工具支持特定功能,如果缺失,说明哪些功能会降级。
| 工具 | 检查命令 | 使用方 | 功能降级说明 | 安装提示(macOS) |
|---|---|---|---|---|
| | swain-do, swain-status (任务) | 任务跟踪回退到文本账本;状态页跳过任务模块 | |
| | swain-stage (MOTD TUI), swain-do (计划摄入) | MOTD回退到bash脚本;计划摄入功能不可用 | |
| | swain-status (GitHub issues), swain-release | 状态页跳过issue模块;无法创建GitHub发布版本 | |
| | swain-stage | 工作区布局功能不可用(仅当用户需要tmux功能时相关) | |
| | swain-design (specwatch实时模式) | 实时产物监听功能不可用;按需执行的 | |
Reporting format
报告格式
After checking all tools, output a summary:
Tool availability:
git .............. ok
jq ............... ok
bd ............... ok
uv ............... ok
gh ............... ok
tmux ............. ok (in tmux session: yes)
fswatch .......... MISSING — live specwatch unavailable. Install: brew install fswatchOnly flag items that need attention. If all required tools are present, the check is silent except for missing optional tools that meaningfully degrade the experience.
检查完所有工具后,输出汇总信息:
工具可用性:
git .............. 正常
jq ............... 正常
bd ............... 正常
uv ............... 正常
gh ............... 正常
tmux ............. 正常 (是否处于tmux会话: 是)
fswatch .......... 缺失 —— 实时specwatch功能不可用。安装命令: brew install fswatch仅标记需要注意的条目。如果所有必选工具都已安装,除了会导致体验明显降级的可选工具缺失外,此检查无输出。
Memory directory
内存目录检查
The Claude Code memory directory stores , , and . Skills that write to this directory will fail silently or error if it doesn't exist.
status-cache.jsonsession.jsonstage-status.jsonClaude Code内存目录存储、和。如果目录不存在,写入该目录的skill会静默失败或报错。
status-cache.jsonsession.jsonstage-status.jsonStep 1 — Compute the correct path
步骤1 —— 计算正确路径
The directory slug is derived from the full absolute repo path, not just the project name:
bash
REPO_ROOT="$(git rev-parse --show-toplevel)"
_PROJECT_SLUG=$(echo "$REPO_ROOT" | tr '/' '-')
MEMORY_DIR="$HOME/.claude/projects/${_PROJECT_SLUG}/memory"目录slug基于仓库的完整绝对路径生成,而非仅使用项目名称:
bash
REPO_ROOT="$(git rev-parse --show-toplevel)"
_PROJECT_SLUG=$(echo "$REPO_ROOT" | tr '/' '-')
MEMORY_DIR="$HOME/.claude/projects/${_PROJECT_SLUG}/memory"Step 2 — Create if missing
步骤2 —— 不存在则创建
bash
if [[ ! -d "$MEMORY_DIR" ]]; then
mkdir -p "$MEMORY_DIR"
fiIf created, tell the user:
Created memory directory at. This is where swain-status, swain-session, and swain-stage store their caches.$MEMORY_DIR
If it already exists, this step is silent.
bash
if [[ ! -d "$MEMORY_DIR" ]]; then
mkdir -p "$MEMORY_DIR"
fi如果创建了目录,告知用户:
已在创建内存目录。swain-status、swain-session和swain-stage会在此存储缓存数据。$MEMORY_DIR
如果目录已存在,此步骤无输出。
Step 3 — Validate existing cache files
步骤3 —— 校验现有缓存文件
If the memory directory exists, check that any existing JSON files in it are valid:
bash
for f in "$MEMORY_DIR"/*.json; do
[[ -f "$f" ]] || continue
if ! jq empty "$f" 2>/dev/null; then
echo "warning: $f is corrupt JSON — removing"
rm "$f"
fi
doneReport any files that were removed due to corruption. This prevents skills from reading garbage data.
Requires: (skip this step if jq is not available — warn instead).
jq如果内存目录存在,检查其中所有现有的JSON文件是否有效:
bash
for f in "$MEMORY_DIR"/*.json; do
[[ -f "$f" ]] || continue
if ! jq empty "$f" 2>/dev/null; then
echo "警告: $f 是损坏的JSON文件 —— 正在移除"
rm "$f"
fi
done报告所有因损坏被移除的文件,避免skill读取无效数据。
依赖: (如果未安装jq,跳过此步骤并发出警告)。
jqSettings validation
配置校验
Swain uses a two-tier settings model. Malformed JSON in either file causes silent failures across multiple skills (swain-stage, swain-session, swain-status).
Swain使用两层配置模型。任意一个文件中的JSON格式错误都会导致多个skill(swain-stage、swain-session、swain-status)静默失败。
Check project settings
检查项目配置
If exists in the repo root:
swain.settings.jsonbash
jq empty swain.settings.json 2>/dev/nullIf this fails, warn:
contains invalid JSON. Skills will fall back to defaults. Fix the file or delete it to use defaults.swain.settings.json
如果仓库根目录存在:
swain.settings.jsonbash
jq empty swain.settings.json 2>/dev/null如果检查失败,发出警告:
包含无效的JSON。skill将回退到默认配置。修复该文件或删除它以使用默认配置。swain.settings.json
Check user settings
检查用户配置
If exists:
${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.jsonbash
jq empty "${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json" 2>/dev/nullIf this fails, warn:
User settings file contains invalid JSON. Skills will fall back to project defaults. Fix the file or delete it.
Requires: (skip these checks if jq is not available).
jq如果存在:
${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.jsonbash
jq empty "${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json" 2>/dev/null如果检查失败,发出警告:
用户配置文件包含无效的JSON。skill将回退到项目默认配置。修复该文件或删除它。
依赖: (如果未安装jq,跳过这些检查)。
jqScript permissions
脚本权限检查
All shell and Python scripts in must be executable. Skills invoke these via , which works regardless, but and direct execution require the executable bit.
skills/*/scripts/bash scripts/foo.shuv run scripts/foo.pyskills/*/scripts/bash scripts/foo.shuv run scripts/foo.pyCheck and repair
检查与修复
bash
find skills/*/scripts/ -type f \( -name '*.sh' -o -name '*.py' \) ! -perm -u+xIf any files are found without the executable bit:
bash
chmod +x <files...>Tell the user:
Fixed executable permissions on N script(s).
If all scripts are already executable, this step is silent.
bash
find skills/*/scripts/ -type f \( -name '*.sh' -o -name '*.py' \) ! -perm -u+x如果找到任何不具备可执行权限的文件:
bash
chmod +x <files...>告知用户:
已修复N个脚本的可执行权限。
如果所有脚本都已具备可执行权限,此步骤无输出。
.agents directory
.agents目录检查
The directory stores per-project configuration for swain skills:
.agents/- — swain-do first-run config
execution-tracking.vars.json - — swain-design stale reference log
specwatch.log - — swain-search pool refresh log
evidencewatch.log
.agents/- —— swain-do首次运行配置
execution-tracking.vars.json - —— swain-design过时引用日志
specwatch.log - —— swain-search池刷新日志
evidencewatch.log
Check and create
检查与创建
bash
if [[ ! -d ".agents" ]]; then
mkdir -p ".agents"
fiIf created, tell the user:
Createddirectory for skill configuration storage..agents/
If it already exists, this step is silent.
bash
if [[ ! -d ".agents" ]]; then
mkdir -p ".agents"
fi如果创建了目录,告知用户:
已创建目录,用于存储skill配置。.agents/
如果目录已存在,此步骤无输出。
Status cache bootstrap
状态缓存初始化
If the memory directory exists but does not, and the status script is available, seed an initial cache so that swain-stage MOTD and other consumers have data on first use.
status-cache.jsonbash
STATUS_SCRIPT="skills/swain-status/scripts/swain-status.sh"
if [[ -f "$STATUS_SCRIPT" && ! -f "$MEMORY_DIR/status-cache.json" ]]; then
bash "$STATUS_SCRIPT" --json > /dev/null 2>&1 || true
fiIf the cache was created, tell the user:
Seeded initial status cache. The MOTD and status dashboard now have data.
If the script is not available or the cache already exists, this step is silent. If the script fails, ignore — the cache will be created on the next invocation.
swain-status如果内存目录存在但不存在,且状态脚本可用,生成初始缓存,这样swain-stage MOTD和其他消费方首次使用时就有数据。
status-cache.jsonbash
STATUS_SCRIPT="skills/swain-status/scripts/swain-status.sh"
if [[ -f "$STATUS_SCRIPT" && ! -f "$MEMORY_DIR/status-cache.json" ]]; then
bash "$STATUS_SCRIPT" --json > /dev/null 2>&1 || true
fi如果创建了缓存,告知用户:
已生成初始状态缓存。MOTD和状态仪表板现在已有数据。
如果脚本不可用或缓存已存在,此步骤无输出。如果脚本执行失败,忽略错误——下次调用时会自动创建缓存。
swain-statusbd health (extended .beads checks)
bd健康检查(扩展.beads检查)
This extends the existing Beads gitignore hygiene section. Skip entirely if does not exist.
.beads/此部分扩展了现有的Beads gitignore合规检查部分。如果不存在则完全跳过。
.beads/bd doctor
bd doctor
If is available and exists, run the bd built-in health check:
bd.beads/bash
bd doctor --json 2>/dev/nullIf the exit code is non-zero, attempt automatic repair:
bash
bd doctor --fix 2>/dev/nullReport the result to the user. If resolves all issues, note it. If issues persist, list them and suggest the user investigate.
--fix如果已安装且存在,运行bd内置的健康检查:
bd.beads/bash
bd doctor --json 2>/dev/null如果退出码非零,尝试自动修复:
bash
bd doctor --fix 2>/dev/null向用户报告结果。如果解决了所有问题,说明结果。如果问题仍然存在,列出问题并建议用户排查。
--fixStale runtime files
过时运行时文件
Check for runtime files that may have been left behind by a crashed bd process:
bash
for f in .beads/bd.sock .beads/bd.sock.startlock .beads/dolt-server.pid .beads/dolt-server.lock .beads/.sync.lock; do
if [[ -f "$f" ]]; then
echo "stale: $f"
fi
doneIf stale files are found, warn:
Found stale bd runtime files. If bd is not currently running (shows nothing), these can be safely removed. Remove them? (list the files)pgrep -f "bd serve"
Do not auto-delete — ask the user first, since a bd process might actually be running.
检查bd进程崩溃可能遗留的运行时文件:
bash
for f in .beads/bd.sock .beads/bd.sock.startlock .beads/dolt-server.pid .beads/dolt-server.lock .beads/.sync.lock; do
if [[ -f "$f" ]]; then
echo "过时文件: $f"
fi
done如果找到过时文件,发出警告:
发现过时的bd运行时文件。如果bd当前未运行(无输出),可以安全删除这些文件。是否删除?(列出文件)pgrep -f "bd serve"
不要自动删除——先询问用户,因为可能确实有bd进程正在运行。
Summary report
汇总报告
After all checks complete, output a concise summary table:
swain-doctor summary:
Governance ......... ok
Legacy cleanup ..... ok (nothing to clean)
Platform dotfolders ok (nothing to clean)
.beads/.gitignore .. ok
Tools .............. ok (1 optional missing: fswatch)
Memory directory ... ok
Settings ........... ok
Script permissions . ok
.agents directory .. ok
Status cache ....... seeded
bd health .......... ok
3 checks performed repairs. 0 issues remain.Use these status values:
- ok — nothing to do
- repaired — issue found and fixed automatically
- warning — issue found, user action recommended (give specifics)
- skipped — check could not run (e.g., jq missing for JSON validation)
If any checks have warnings, list them below the table with remediation steps.
所有检查完成后,输出简洁的汇总表格:
swain-doctor汇总:
治理规则 ......... 正常
遗留清理 ..... 正常(无内容需要清理)
平台点文件夹 正常(无内容需要清理)
.beads/.gitignore .. 正常
工具 .............. 正常(1个可选工具缺失: fswatch)
内存目录 ... 正常
配置 ........... 正常
脚本权限 . 正常
.agents目录 .. 正常
状态缓存 ....... 已生成
bd健康 .......... 正常
3项检查执行了修复,剩余0个问题。使用以下状态值:
- 正常 —— 无需操作
- 已修复 —— 发现问题并自动修复
- 警告 —— 发现问题,建议用户操作(给出具体说明)
- 已跳过 —— 无法执行检查(例如JSON校验缺失jq)
如果有任何检查存在警告,在表格下方列出问题以及修复步骤。