swain-doctor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Doctor

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

会话启动治理检查

  1. Detect the agent platform and locate the context file:
    PlatformContext fileDetection
    Claude Code
    CLAUDE.md
    (project root)
    Default — use if no other platform detected
    Cursor
    .cursor/rules/swain-governance.mdc
    .cursor/
    directory exists
  2. Check whether governance rules are already present:
    bash
    grep -l "swain governance" CLAUDE.md AGENTS.md .cursor/rules/swain-governance.mdc 2>/dev/null
    If any file matches, governance is already installed. Proceed to Legacy skill cleanup.
  3. If no match, run Legacy skill cleanup, then proceed to Governance injection.
  1. 检测Agent平台并定位上下文文件:
    平台上下文文件检测规则
    Claude Code
    CLAUDE.md
    (项目根目录)
    默认规则 —— 未检测到其他平台时使用
    Cursor
    .cursor/rules/swain-governance.mdc
    存在
    .cursor/
    目录时判定
  2. 检查是否已存在治理规则:
    bash
    grep -l "swain governance" CLAUDE.md AGENTS.md .cursor/rules/swain-governance.mdc 2>/dev/null
    若有任意文件匹配,说明治理规则已安装,直接进入遗留skill清理步骤。
  3. 若无匹配结果,先执行遗留skill清理,再进入治理规则注入步骤。

Legacy skill cleanup

遗留skill清理

Clean up skill directories that have been superseded by renames or retired entirely. Read the legacy mapping from
references/legacy-skills.json
in this skill's directory.
清理已被重命名或完全弃用的skill目录,从此skill目录下的
references/legacy-skills.json
文件读取遗留映射关系。

Renamed skills

已重命名的skill

For each entry in the
renamed
map:
  1. Check whether
    .claude/skills/<old-name>/
    exists.
  2. If it does NOT exist, skip (nothing to clean).
  3. If it exists, check whether
    .claude/skills/<new-name>/
    also exists. If the replacement is missing, skip and warn — the update may not have completed:
    Skipping cleanup of
    <old-name>
    — its replacement
    <new-name>
    is not installed.
  4. If both exist, fingerprint check: read
    .claude/skills/<old-name>/SKILL.md
    and check whether its content matches ANY of the fingerprints listed in
    legacy-skills.json
    . Specifically, grep the file for each fingerprint string — if at least one matches, the skill is confirmed to be a swain skill.
  5. If no fingerprint matches, skip and warn — this may be a third-party skill with the same name:
    Skipping cleanup of
    .claude/skills/<old-name>/
    — it does not appear to be a swain skill (no fingerprint match). If this is a stale swain skill, delete it manually.
  6. If fingerprint matches and replacement exists, delete the old directory:
    bash
    rm -rf .claude/skills/<old-name>
    Tell the user:
    Removed legacy skill
    .claude/skills/<old-name>/
    (replaced by
    <new-name>
    ).
遍历
renamed
映射中的每条记录:
  1. 检查
    .claude/skills/<old-name>/
    目录是否存在。
  2. 若不存在,跳过(无内容需要清理)。
  3. 若存在,检查
    .claude/skills/<new-name>/
    目录是否也存在。如果替换版本不存在,跳过并发出警告——可能是更新尚未完成:
    跳过
    <old-name>
    的清理——其替换版本
    <new-name>
    尚未安装。
  4. 若两个目录都存在,执行指纹校验:读取
    .claude/skills/<old-name>/SKILL.md
    的内容,检查是否匹配
    legacy-skills.json
    中列出的任意指纹。具体操作是对每个指纹字符串执行grep匹配——只要有一个匹配,即可确认该skill是官方swain skill。
  5. 若无匹配的指纹,跳过并发出警告——这可能是同名的第三方skill:
    跳过
    .claude/skills/<old-name>/
    的清理——该目录看起来不是swain skill(无匹配指纹)。如果确认是过时的swain skill,请手动删除。
  6. 若指纹匹配且替换版本存在,删除旧目录
    bash
    rm -rf .claude/skills/<old-name>
    告知用户:
    已移除遗留skill
    .claude/skills/<old-name>/
    (已被
    <new-name>
    替代)。

Retired skills

已弃用的skill

For each entry in the
retired
map (pre-swain skills absorbed into the ecosystem):
  1. Check whether
    .claude/skills/<old-name>/
    exists.
  2. If it does NOT exist, skip (nothing to clean).
  3. If it exists, fingerprint check: same as for renamed skills — read
    .claude/skills/<old-name>/SKILL.md
    and check whether its content matches ANY fingerprint in
    legacy-skills.json
    .
  4. If no fingerprint matches, skip and warn:
    Skipping cleanup of
    .claude/skills/<old-name>/
    — it does not appear to be a known pre-swain skill (no fingerprint match). Delete manually if stale.
  5. If fingerprint matches, delete the old directory:
    bash
    rm -rf .claude/skills/<old-name>
    Tell the user:
    Removed retired pre-swain skill
    .claude/skills/<old-name>/
    (functionality now in
    <absorbed-by>
    ).
After processing all entries, check whether the governance block in the context file references old skill names. If the governance block (between
<!-- swain governance -->
and
<!-- end swain governance -->
) contains any old-name from the
renamed
map, delete the entire block (inclusive of markers) and proceed to Governance injection to re-inject a fresh copy with current names.
遍历
retired
映射中的每条记录(被生态吸收的pre-swain skill):
  1. 检查
    .claude/skills/<old-name>/
    目录是否存在。
  2. 若不存在,跳过(无内容需要清理)。
  3. 若存在,执行指纹校验:和重命名skill的校验规则一致——读取
    .claude/skills/<old-name>/SKILL.md
    的内容,检查是否匹配
    legacy-skills.json
    中的任意指纹。
  4. 若无匹配的指纹,跳过并发出警告
    跳过
    .claude/skills/<old-name>/
    的清理——该目录看起来不是已知的pre-swain skill(无匹配指纹)。如果确认已过时,请手动删除。
  5. 若指纹匹配,删除旧目录
    bash
    rm -rf .claude/skills/<old-name>
    告知用户:
    已移除已弃用的pre-swain skill
    .claude/skills/<old-name>/
    (功能已整合到
    <absorbed-by>
    中)。
处理完所有条目后,检查上下文文件中的治理规则块是否引用了旧的skill名称。如果治理规则块(位于
<!-- swain governance -->
<!-- end swain governance -->
之间)包含
renamed
映射中的任意旧名称,删除整个规则块(包含标记符),然后进入治理规则注入步骤,重新注入包含最新名称的规则副本。

Platform dotfolder cleanup

平台点文件夹清理

The
npx skills add --all
command (or older versions of swain-update without autodetect) creates dotfolder stubs (e.g.,
.windsurf/
,
.cursor/
) for agent platforms that are not installed. These directories only contain symlinks back to
.agents/skills/
and clutter the working tree. See GitHub issue #21.
Read the platform data from
references/platform-dotfolders.json
in this skill's directory. Each entry in the
platforms
array has a
project_dotfolder
name and one or both detection strategies:
command
(CLI binary name) and
detection
(HOME config directory path). Entries with collision-prone command names (e.g.,
cmd
,
cortex
,
mux
,
pi
) omit
command
and rely on HOME detection only.
npx skills add --all
命令(或不带自动检测的旧版swain-update)会为未安装的Agent平台创建点文件夹存根(例如
.windsurf/
.cursor/
)。这些目录仅包含指向
.agents/skills/
的符号链接,会污染工作树。详情参见GitHub issue #21
从此skill目录下的
references/platform-dotfolders.json
文件读取平台数据。
platforms
数组中的每个条目都包含
project_dotfolder
名称,以及一种或两种检测策略:
command
(CLI二进制文件名)和
detection
(HOME配置目录路径)。命令名称容易冲突的条目(例如
cmd
cortex
mux
pi
)不包含
command
字段,仅依赖HOME目录检测。

Step 1 — Autodetect installed platforms

步骤1 —— 自动检测已安装的平台

Iterate over the
platforms
array. For each entry, a platform is considered installed if either check succeeds:
  1. If the entry has a
    command
    field → run
    command -v <command> &>/dev/null
    .
  2. If the entry has a
    detection
    field → expand the path (replace
    ~
    with
    $HOME
    , evaluate env var defaults like
    ${CODEX_HOME:-~/.codex}
    ) and check whether the directory exists.
Always consider
.claude
installed (current platform — never a cleanup candidate).
Requires:
jq
(for reading the JSON). If
jq
is not available, skip this section and warn.
bash
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
SKILL_DIR
with the actual path to this skill's directory.)
遍历
platforms
数组,对于每个条目,只要满足任意一项检查,即认为平台已安装
  1. 如果条目包含
    command
    字段 → 执行
    command -v <command> &>/dev/null
  2. 如果条目包含
    detection
    字段 → 展开路径(将
    ~
    替换为
    $HOME
    ,解析环境变量默认值,例如
    ${CODEX_HOME:-~/.codex}
    ),检查目录是否存在。
始终认为
.claude
已安装(当前平台——永远不会作为清理候选)。
依赖:
jq
(用于读取JSON)。如果没有安装
jq
,跳过此部分并发出警告。
bash
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_DIR
替换为此skill目录的实际路径。)

Step 2 — Build cleanup candidates

步骤2 —— 构建清理候选列表

Every entry in
platforms
whose
project_dotfolder
is NOT in the
installed_dotfolders
list is a cleanup candidate.
platforms
数组中所有
project_dotfolder
不在
installed_dotfolders
列表中的条目,都是清理候选。

Step 3 — Remove installer stubs

步骤3 —— 移除安装程序存根

For each candidate dotfolder:
  1. Check whether the directory exists in the project root.
  2. If it does NOT exist, skip.
  3. If it exists, verify it is installer-generated — the directory should contain only a
    skills/
    subdirectory (possibly with symlinks or further subdirectories). Check:
    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
      skills/
      subdirectory → remove it:
      bash
      rm -rf <dotfolder>
    • If the directory contains other files or directories besides
      skills/
      skip and warn:
      Skipping
      <dotfolder>
      — contains user content beyond installer symlinks. Remove manually if unused.
  4. After processing all entries, report:
    Removed N platform dotfolder(s) created by
    npx skills add
    (installer stubs for unused agent platforms).
    If none were found, this step is silent.
遍历每个候选点文件夹:
  1. 检查项目根目录下是否存在该目录。
  2. 若不存在,跳过。
  3. 若存在,验证是否为安装程序生成——该目录应仅包含
    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/
      子目录 → 移除该目录
      bash
      rm -rf <dotfolder>
    • 如果目录中除了
      skills/
      之外还有其他文件或目录 → 跳过并发出警告
      跳过
      <dotfolder>
      的清理——包含安装程序符号链接之外的用户内容。如果确认未使用,请手动移除。
  4. 处理完所有条目后,报告:
    已移除
    npx skills add
    生成的N个平台点文件夹(未使用的Agent平台的安装程序存根)。
    若未找到任何存根,此步骤无输出。

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:
  1. If
    CLAUDE.md
    exists and its content is just
    @AGENTS.md
    (the include pattern set up by swain-init), inject into
    AGENTS.md
    instead.
  2. Otherwise, inject into
    CLAUDE.md
    (create it if it doesn't exist).
Read the canonical governance content from
references/AGENTS.content.md
(relative to this skill's directory) and append it to the target file.
确定目标文件:
  1. 如果
    CLAUDE.md
    存在且内容仅为
    @AGENTS.md
    (swain-init设置的包含模式),则改为注入到
    AGENTS.md
    中。
  2. 否则,注入到
    CLAUDE.md
    中(如果文件不存在则创建)。
从此skill目录下的
references/AGENTS.content.md
读取标准治理内容,追加到目标文件末尾。

Cursor

Cursor

Write the governance rules to
.cursor/rules/swain-governance.mdc
. Create the directory if needed.
Prepend Cursor MDC frontmatter to the canonical content from
references/AGENTS.content.md
:
markdown
---
description: "swain governance — skill routing, pre-implementation protocol, issue tracking"
globs:
alwaysApply: true
---
Then append the full contents of
references/AGENTS.content.md
after the frontmatter.
将治理规则写入
.cursor/rules/swain-governance.mdc
,如果目录不存在则创建。
references/AGENTS.content.md
的标准内容前添加Cursor MDC前置元数据:
markdown
---
description: "swain governance — skill路由、预实现协议、问题跟踪"
globs:
alwaysApply: true
---
然后将
references/AGENTS.content.md
的完整内容追加到元数据之后。

After injection

注入完成后

Tell the user:
Governance rules installed in
<file>
. These ensure swain-design, swain-do, and swain-release skills are routable. You can customize the rules — just keep the
<!-- swain governance -->
markers so this skill can detect them on future sessions.
告知用户:
治理规则已安装到
<file>
。这些规则可确保swain-design、swain-do和swain-release skill可被路由。你可以自定义规则——只需保留
<!-- swain governance -->
标记,这样此skill在后续会话中可以检测到这些规则。

Beads gitignore hygiene

Beads gitignore合规检查

This section runs every session, after governance checks. It is idempotent. Skip entirely if
.beads/
does not exist
(the project has not initialized bd yet).
此部分在每次会话的治理检查之后运行,具备幂等性。如果
.beads/
不存在则完全跳过
(项目尚未初始化bd)。

Step 1 — Validate .beads/.gitignore

步骤1 —— 校验.beads/.gitignore

The following are the canonical ignore patterns. This list is kept in sync with
references/.beads-gitignore
in this skill's directory.
Canonical 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
  1. If
    .beads/.gitignore
    does not exist, create it from the reference file (
    references/.beads-gitignore
    ) and skip to Step 2.
  2. Read
    .beads/.gitignore
    . For each canonical pattern above, check whether it appears as a non-comment line in the file.
  3. Collect any missing patterns. If none are missing, this step is silent — move to Step 2.
  4. If patterns are missing, append them to
    .beads/.gitignore
    :
    
    # --- swain-managed entries (do not remove) ---
    <missing patterns, one per line>
  5. Tell the user:
    Patched
    .beads/.gitignore
    with N missing entries. These entries prevent runtime and database files from being tracked by git.
以下是标准忽略规则列表,与此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
  1. 如果
    .beads/.gitignore
    不存在,从参考文件
    references/.beads-gitignore
    创建该文件,直接进入步骤2。
  2. 读取
    .beads/.gitignore
    ,对上面列出的每个标准规则,检查是否作为非注释行存在于文件中。
  3. 收集所有缺失的规则,若无缺失,此步骤无输出——进入步骤2。
  4. 如果有缺失的规则,将它们追加到
    .beads/.gitignore
    末尾:
    
    # --- swain管理的条目(请勿删除) ---
    <缺失的规则,每行一个>
  5. 告知用户:
    已为
    .beads/.gitignore
    补充N条缺失的条目。这些条目可避免运行时文件和数据库文件被git跟踪。

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
done
This 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:
  1. Remove them from the index (this untracks them without deleting from disk):
    bash
    git rm --cached <file1> <file2> ...
  2. Tell the user:
    Untracked N file(s) from git that are now covered by
    .beads/.gitignore
    . These files still exist on disk but will no longer be committed. You should commit this change.
确认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规则的文件。
若未找到任何文件,此步骤无输出。
若找到匹配文件:
  1. 将它们从暂存区移除(仅取消跟踪,不会删除磁盘上的文件):
    bash
    git rm --cached <file1> <file2> ...
  2. 告知用户:
    已从git中取消跟踪N个现在被
    .beads/.gitignore
    覆盖的文件。这些文件仍存在于磁盘上,但不会被提交。建议你提交此变更。

Governance content reference

治理内容参考

The canonical governance rules live in
references/AGENTS.content.md
(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
<!-- swain governance -->
block from their context file and re-run this skill.
标准治理规则存放在此skill目录下的
references/AGENTS.content.md
中。swain-doctor和swain-init都从此单一数据源读取规则。如果上游规则在未来的swain版本中发生变更,更新该文件并提升skill版本即可。需要更新规则的用户可以从上下文文件中删除
<!-- swain governance -->
块,重新运行此skill即可。

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.
ToolCheckUsed byInstall hint (macOS)
git
command -v git
All skillsXcode Command Line Tools
jq
command -v jq
swain-status, swain-stage, swain-session, swain-do
brew install jq
多个skill都需要这些工具,如果缺失,向用户发出警告。
工具检查命令使用方安装提示(macOS)
git
command -v git
所有skillXcode Command Line Tools
jq
command -v jq
swain-status, swain-stage, swain-session, swain-do
brew install jq

Optional tools

可选工具

These tools enable specific features. If missing, note which features are degraded.
ToolCheckUsed byDegradationInstall hint (macOS)
bd
command -v bd
swain-do, swain-status (tasks)Task tracking falls back to text ledger; status skips task section
brew install beads
uv
command -v uv
swain-stage (MOTD TUI), swain-do (plan ingestion)MOTD falls back to bash script; plan ingestion unavailable
brew install uv
gh
command -v gh
swain-status (GitHub issues), swain-releaseStatus skips issues section; release can't create GitHub releases
brew install gh
tmux
command -v tmux
swain-stageWorkspace layouts unavailable (only relevant if user wants tmux features)
brew install tmux
fswatch
command -v fswatch
swain-design (specwatch live mode)Live artifact watching unavailable; on-demand
specwatch.sh scan
still works
brew install fswatch
这些工具支持特定功能,如果缺失,说明哪些功能会降级。
工具检查命令使用方功能降级说明安装提示(macOS)
bd
command -v bd
swain-do, swain-status (任务)任务跟踪回退到文本账本;状态页跳过任务模块
brew install beads
uv
command -v uv
swain-stage (MOTD TUI), swain-do (计划摄入)MOTD回退到bash脚本;计划摄入功能不可用
brew install uv
gh
command -v gh
swain-status (GitHub issues), swain-release状态页跳过issue模块;无法创建GitHub发布版本
brew install gh
tmux
command -v tmux
swain-stage工作区布局功能不可用(仅当用户需要tmux功能时相关)
brew install tmux
fswatch
command -v fswatch
swain-design (specwatch实时模式)实时产物监听功能不可用;按需执行的
specwatch.sh scan
仍可使用
brew install fswatch

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 fswatch
Only 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
status-cache.json
,
session.json
, and
stage-status.json
. Skills that write to this directory will fail silently or error if it doesn't exist.
Claude Code内存目录存储
status-cache.json
session.json
stage-status.json
。如果目录不存在,写入该目录的skill会静默失败或报错。

Step 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"
fi
If created, tell the user:
Created memory directory at
$MEMORY_DIR
. This is where swain-status, swain-session, and swain-stage store their caches.
If it already exists, this step is silent.
bash
if [[ ! -d "$MEMORY_DIR" ]]; then
  mkdir -p "$MEMORY_DIR"
fi
如果创建了目录,告知用户:
已在
$MEMORY_DIR
创建内存目录。swain-status、swain-session和swain-stage会在此存储缓存数据。
如果目录已存在,此步骤无输出。

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
done
Report any files that were removed due to corruption. This prevents skills from reading garbage data.
Requires:
jq
(skip this step if jq is not available — warn instead).
如果内存目录存在,检查其中所有现有的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
(如果未安装jq,跳过此步骤并发出警告)。

Settings 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
swain.settings.json
exists in the repo root:
bash
jq empty swain.settings.json 2>/dev/null
If this fails, warn:
swain.settings.json
contains invalid JSON. Skills will fall back to defaults. Fix the file or delete it to use defaults.
如果仓库根目录存在
swain.settings.json
bash
jq empty swain.settings.json 2>/dev/null
如果检查失败,发出警告:
swain.settings.json
包含无效的JSON。skill将回退到默认配置。修复该文件或删除它以使用默认配置。

Check user settings

检查用户配置

If
${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json
exists:
bash
jq empty "${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json" 2>/dev/null
If this fails, warn:
User settings file contains invalid JSON. Skills will fall back to project defaults. Fix the file or delete it.
Requires:
jq
(skip these checks if jq is not available).
如果
${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json
存在:
bash
jq empty "${XDG_CONFIG_HOME:-$HOME/.config}/swain/settings.json" 2>/dev/null
如果检查失败,发出警告:
用户配置文件包含无效的JSON。skill将回退到项目默认配置。修复该文件或删除它。
依赖:
jq
(如果未安装jq,跳过这些检查)。

Script permissions

脚本权限检查

All shell and Python scripts in
skills/*/scripts/
must be executable. Skills invoke these via
bash scripts/foo.sh
, which works regardless, but
uv run scripts/foo.py
and direct execution require the executable bit.
skills/*/scripts/
目录下的所有shell和Python脚本必须具备可执行权限。skill通过
bash scripts/foo.sh
调用时不受影响,但
uv run scripts/foo.py
和直接执行需要可执行权限位。

Check and repair

检查与修复

bash
find skills/*/scripts/ -type f \( -name '*.sh' -o -name '*.py' \) ! -perm -u+x
If 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
.agents/
directory stores per-project configuration for swain skills:
  • execution-tracking.vars.json
    — swain-do first-run config
  • specwatch.log
    — swain-design stale reference log
  • evidencewatch.log
    — swain-search pool refresh log
.agents/
目录存储swain skill的项目级配置:
  • execution-tracking.vars.json
    —— swain-do首次运行配置
  • specwatch.log
    —— swain-design过时引用日志
  • evidencewatch.log
    —— swain-search池刷新日志

Check and create

检查与创建

bash
if [[ ! -d ".agents" ]]; then
  mkdir -p ".agents"
fi
If created, tell the user:
Created
.agents/
directory for skill configuration storage.
If it already exists, this step is silent.
bash
if [[ ! -d ".agents" ]]; then
  mkdir -p ".agents"
fi
如果创建了目录,告知用户:
已创建
.agents/
目录,用于存储skill配置。
如果目录已存在,此步骤无输出。

Status cache bootstrap

状态缓存初始化

If the memory directory exists but
status-cache.json
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.
bash
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
If 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
swain-status
invocation.
如果内存目录存在但
status-cache.json
不存在,且状态脚本可用,生成初始缓存,这样swain-stage MOTD和其他消费方首次使用时就有数据。
bash
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-status
时会自动创建缓存。

bd health (extended .beads checks)

bd健康检查(扩展.beads检查)

This extends the existing Beads gitignore hygiene section. Skip entirely if
.beads/
does not exist.
此部分扩展了现有的Beads gitignore合规检查部分。如果
.beads/
不存在则完全跳过。

bd doctor

bd doctor

If
bd
is available and
.beads/
exists, run the bd built-in health check:
bash
bd doctor --json 2>/dev/null
If the exit code is non-zero, attempt automatic repair:
bash
bd doctor --fix 2>/dev/null
Report the result to the user. If
--fix
resolves all issues, note it. If issues persist, list them and suggest the user investigate.
如果已安装
bd
.beads/
存在,运行bd内置的健康检查:
bash
bd doctor --json 2>/dev/null
如果退出码非零,尝试自动修复:
bash
bd doctor --fix 2>/dev/null
向用户报告结果。如果
--fix
解决了所有问题,说明结果。如果问题仍然存在,列出问题并建议用户排查。

Stale 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
done
If stale files are found, warn:
Found stale bd runtime files. If bd is not currently running (
pgrep -f "bd serve"
shows nothing), these can be safely removed. Remove them? (list the files)
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)
如果有任何检查存在警告,在表格下方列出问题以及修复步骤。