关于 swain-session
swain-session 是面向 Agent 工作环境的会话管理 Skill,通过 AGENTS.md 自动调用,管理会话身份、偏好和上下文延续。它涵盖会话启动、恢复、决策记录与关闭,并提供预检和状态脚本。
主要功能
- 01会话启动时恢复上下文
- 02读取并应用用户偏好
- 03记录会话决策与进度
- 04管理会话关闭和恢复
- 05提供预检及问候脚本
适用场景
- 01开始工作时恢复上次会话
- 02跨会话保留上下文书签
- 03结束会话并生成进度记录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cristoslc/ swain --skill swain-session安装后在 Claude Code 中输入/swain-session确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/agent-summary-template.mdbookmark-protocol.mdsession-check-preamble.mdstatus-format.mdscripts/swain-bookmark.shswain-focus.shswain-preflight-timing.shswain-progress-log.shswain-session-archive.shswain-session-bootstrap.shswain-session-check.shswain-session-digest.shswain-session-greeting.shswain-session-preflight.shswain-session-state.shswain-startup-timing.shswain-status.shswain-tab-name.shswain-worktree-name.shtest-session-greeting.shtests/test-bootstrap.shtest-progress-log.shtest-session-close-integration.shtest-session-digest.shtest-tab-name.sh详细介绍
会话
管理 Agent 会话之间的会话身份、偏好设置和上下文连续性。此技能与 Agent 无关——它依赖 AGENTS.md 自动调用。
自动运行行为
此技能会在会话开始时自动调用(参见 AGENTS.md)。自动调用时:
- 恢复标签页名称 — 运行标签页命名脚本
- 加载偏好设置 — 读取 session.json 并应用已存储的偏好设置
- 显示上下文书签 — 如果上一个会话留下了上下文备注,则显示该备注
手动调用时,用户可以更改偏好设置或为上下文添加书签。
会话目的文本
当操作者使用自由文本启动时(例如,swain new bug about timestamps),启动器会导出 SWAIN_PURPOSE,并且对于接受初始提示词的运行时,还会以内联方式传入 /swain-session Session purpose: new bug about timestamps。
启动器负责选择保存该书签的工作副本:
- 如果操作者从主工作副本启动,启动器会先打开一个新的工作树,然后才传入会话目的。
- 如果操作者从已有书签的关联工作树中启动,启动器应引导其恢复/完成该工作树,或在重新使用目的文本之前打开另一个工作树。
问候脚本(swain-session-greeting.sh)会读取 $SWAIN_PURPOSE,并以确定性方式写入书签(SPEC-297)。问候 JSON 会在 purpose 字段中提供捕获的文本。
当问候 JSON 的 purpose 字段不为 null 时:
- 向操作者显示:
**Session purpose:** <text>。
不要重新解析初始提示词,也不要自行调用 swain-bookmark.sh——问候脚本已完成这两项操作。内联提示词文本仅用于显示上下文;环境变量才是事实来源。
预检
执行任何步骤之前,先运行预检脚本,一次性收集所有会话状态。此脚本取代旧的子进程调用链(greeting → bootstrap → tab-name),是只读脚本。
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
PREFLIGHT_SCRIPT="$(find "$REPO_ROOT" -path '*/swain-session/scripts/swain-session-preflight.sh' -print -quit 2>/dev/null)"
PREFLIGHT_JSON=$( bash "$PREFLIGHT_SCRIPT" --repo-root "$REPO_ROOT" 2>/dev/null )
echo "$PREFLIGHT_JSON"
将 PREFLIGHT_JSON 保存下来,以供以下所有步骤使用。每项决策都要引用此 JSON 中的字段——除非要执行变更,否则不要运行其他检查命令。
步骤 1 — 快速问候(SPEC-194)
运行问候脚本。它会在内部调用预检,并执行轻量级变更(设置标签页名称、清理锁、创建 .agents 目录)。它不会调用 specgraph、GitHub API 或完整状态仪表板。
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-greeting.sh" --json
问候脚本会输出结构化 JSON:
{
"greeting": true,
"branch": "trunk",
"dirty": false,
"isolated": false,
"bookmark": "Left off implementing the bootstrap script",
"focus": "VISION-001",
"tab": "project @ branch",
"warnings": []
}
预检 JSON 还会在 prev_session 下包含上一个会话的状态,因此无需单独调用 swain-session-state.sh resume:
{
"prev_session": {
"exists": true,
"status": "closed",
"session_id": "session-20260404-215204-9576",
"focus_lane": "INITIATIVE-002",
"phase": "closed",
"start_time": "2026-04-05T01:52:04Z",
"end_time": "2026-04-06T04:10:09Z",
"decisions_made": 0,
"walkaway": "Reviewed and fixed SPIKE-058"
}
}
收到问候 JSON 后:
-
向操作者展示问候信息——分支、脏状态、书签(如有)、关注泳道(如有)和警告。
-
如果
prev_session.exists为 true,展示上一个会话的上下文(来自预检 JSON),让操作者决定是继续还是重新开始。 -
如果
isolated为false,且操作者尚未开始工作,此时不要创建工作树——工作树由 bin/swain 预启动流程创建(SPEC-245)。如果需要工作树名称以供参考,则生成该名称:bash "$REPO_ROOT/.agents/bin/swain-worktree-name.sh" "context"然后使用
--path重新运行问候脚本,以刷新标签页名称和上下文:bash "$REPO_ROOT/.agents/bin/swain-session-greeting.sh" --path "$(pwd)" --json -
如果
bookmark不为 null,则显示该书签:恢复会话 — 上次:{bookmark}
-
现在会话已准备好开始工作。完整状态仪表板可按需使用(参见状态仪表板(SPEC-122))。
如果未设置 $TMUX(JSON 中没有 tab 即表示检测到此情况),请检查是否已安装 tmux:
- 未安装 tmux: 提供安装选项(
brew install tmux)。 - 已安装 tmux 但不在会话中: 显示:
[note] 不在 tmux 会话中 — 会话标签页和窗格功能不可用
操作者可以随时说“exit worktree”或“back to main”——这会结束会话。运行时退出后,bin/swain 会处理工作树清理(SPEC-245)。
工作树/分支变更(与 Agent 无关)
当 Agent 进入工作树或切换分支时,使用 --path 重新运行引导脚本以更新标签名称:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-bootstrap.sh" --path "$NEW_WORKDIR" --skip-worktree --auto
这与 Agent 无关——适用于 Claude Code、opencode、gemini cli、codex、copilot,或任何会读取 AGENTS.md 并能运行 bash 命令的 Agent。
Session.json 架构
{
"lastBranch": "trunk",
"lastContext": "Working on swain-session skill",
"preferences": {
"verbosity": "concise"
},
"bookmark": {
"note": "Left off implementing the bootstrap script",
"files": ["SKILL.md"],
"timestamp": "2026-03-10T14:32:00Z"
}
}
迁移: 如果 .agents/session.json 不存在,但旧的全局位置(~/.claude/projects/<project-path-slug>/memory/session.json)存在,引导脚本会自动复制它。
README 核对检查点(SPEC-209)
在问候之后、开始工作之前,将 README.md 与制品树进行比较。此检查在每个会话中只运行一次,在选择焦点泳道时进行。
触发条件
设置焦点泳道时(从上一会话恢复或新选择),且 README.md 存在:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
[ -f "$REPO_ROOT/README.md" ] && echo "has_readme" || echo "no_readme"
如果不存在 README,则静默跳过核对——swain-doctor 会标记 README 缺失。
流程
- 阅读 README.md 并提取其中的陈述——任何关于项目用途、目标用户、运作方式、支持内容或行为表现的说明。将整个 README 作为普通文本阅读;无需标记或章节约定。
- 将这些陈述与当前的 Active Visions、Designs、Journeys 和 Persona 制品进行比较。查找:
- 过时的承诺——README 声称有某项功能或行为,但制品明确指出该项已弃用或被取代。
- 内容缺失——某项制品描述了 README 未提及的能力。
- 相互矛盾——README 与制品对行为、受众或范围的说法不一致。
- 对每处不匹配,向操作人员提出具体问题:
“README 写着‘{claim}’,但 {artifact-id} {describes the conflict}。哪一个才是正确的?”
核对方向
双向核对。出现偏差并不意味着制品一定正确:
- 新的 Vision 可能意味着需要更新 README。
- README 可能是正确的,而 Vision 需要调整。
- 某项承诺可能是有意弃用的,需要从两者中移除。
延后跟踪
操作人员可以延后处理任何不匹配项。延后项会记录在 .agents/session.json 的 readme_deferrals 键下:
{
"readme_deferrals": [
{
"claim": "real-time sync",
"conflict_artifact": "VISION-003",
"deferred_at": "2026-03-31T14:00:00Z"
}
]
}
延后项会在下一次会话开始时再次提出。操作人员处理延后项(更新 README 或制品)后,请将其从列表中移除。
静默通过
如果未发现偏差,核对检查将静默通过——不向操作人员输出任何内容。
会话生命周期(SPEC-119)
swain-session 负责管理有明确边界的会话生命周期:开始 → 工作 → 关闭 → 恢复。会话状态通过 swain-session-state.sh 脚本记录在 .agents/session-state.json 中。
会话开始
引导完成且工作树就绪后,初始化会话生命周期:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-state.sh" init --focus "<FOCUS-ID>" --session-roadmap "$(pwd)/SESSION-ROADMAP.md" --repo-root "$REPO_ROOT"
此操作会:
- 创建
.agents/session-state.json,其中包含焦点泳道、决策预算(默认为 5)和开始时间 - 通过
chart.sh session --focus <ID>生成SESSION-ROADMAP.md
焦点泳道默认为上一会话的泳道(来自引导 JSON 中的 session.focus)。请与操作人员确认,或接受其指定的其他泳道。
自定义决策预算:--budget 7
工作期间——记录决策
当操作人员或 Agent 作出决策时(批准规格、选择方案、确定方向),请记录:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-state.sh" record-decision --note "Approved SPEC-119 implementation approach"
会话关闭
当操作人员说“完成”“收尾”“关闭会话”,或达到决策预算时,执行以下关闭流程。重要: swain-retro 必须在会话仍处于活动状态时运行,以便读取会话状态。运行回顾之前不要关闭会话。
步骤 1——生成会话摘要和进度日志
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-digest.sh" --session-id "$(jq -r .session_id "$REPO_ROOT/.agents/session-state.json")" --output "$REPO_ROOT/.agents/session-log.jsonl"
bash "$REPO_ROOT/.agents/bin/swain-progress-log.sh" --digest "$REPO_ROOT/.agents/session-log.jsonl"
此操作会追加一条 JSONL 摘要记录,并更新每个受影响的 EPIC/Initiative 的 progress.md 和 ## Progress 部分。
步骤 2 — 运行 retro(会话仍处于活动状态)
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SWAIN_RETRO_SKILL="$REPO_ROOT/.claude/skills/swain-retro/SKILL.md"
Skill("$SWAIN_RETRO_SKILL", "Session close — session is closing. Run /swain-retro to capture session learnings before the session state is cleared.")
重要: Retro 会在 session.json 和 session-state.json 仍有内容时读取它们。此步骤之前不要调用 session-state.sh close。
步骤 3 — 关闭会话
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-state.sh" close --walkaway "Completed SPEC-119 tests and state management" --session-roadmap "$(pwd)/SESSION-ROADMAP.md"
这会将会话阶段设为 closed,记录结束时间,并将离开信号追加到 SESSION-ROADMAP.md。
步骤 4 — 运行会话拆除
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SWAIN_TEARDOWN_SKILL="$REPO_ROOT/.claude/skills/swain-teardown/SKILL.md"
Skill("$SWAIN_TEARDOWN_SKILL", "Session teardown — --session-chain flag passed from swain-session close handler.")
这会运行孤立工作树检查、git 脏状态检查、工单同步提示,并写入交接摘要。--session-chain 标志会告知拆除流程跳过冗余的会话活动状态检查,因为处理程序已确认会话状态。
步骤 5 — 提交 SESSION-ROADMAP.md
最后,将 SESSION-ROADMAP.md 提交到 git。
恢复会话
下次会话开始时,从预检 JSON 中读取 prev_session(参见预检)。其中包含上一个会话的关注方向、离开备注、决策数量和过时状态——无需单独调用脚本。
如果需要直接调用 session-state.sh(例如,从不包含预检 JSON 的脚本中调用):
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-session-state.sh" resume
显示上一个会话的上下文,以便操作员决定是继续还是重新开始。
会话状态架构
{
"session_id": "session-20260328-220634-4ad1",
"focus_lane": "INITIATIVE-019",
"phase": "active",
"start_time": "2026-03-28T22:06:34Z",
"last_activity_time": "2026-03-28T22:06:34Z",
"end_time": null,
"decision_budget": 5,
"decisions_made": 0,
"decisions": [],
"walkaway": null
}
手动调用命令
用户明确调用时,支持以下操作:
设置标签页名称
用户说类似“将标签页名称设为 X”或“重命名标签页”:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-tab-name.sh" "Custom Name"
添加上下文书签
用户说“记住我现在的位置”或“为此添加书签”:
- 根据对话上下文推断他们正在处理的内容,或使用他们提供的备注——不要提示用户
- 将包含备注、相关文件和时间戳的内容写入 session.json 的
bookmark字段 - 如果已存在书签,无需询问确认,直接静默覆盖——
swain-bookmark.sh会处理原子写入
清除书签
用户说“清除书签”或“重新开始”:
- 从 session.json 中移除
bookmark字段
显示会话信息
用户说“会话信息”或“我的会话是什么”:
- 显示当前标签页名称、分支、偏好设置和书签状态
- 如果书签备注包含工件 ID(例如
SPEC-052、EPIC-018),显示 Vision 祖先关系路径,提供战略上下文。运行bash "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/bin/chart.sh" scope <ID> 2>/dev/null | head -5获取父级链。显示为:Context: Swain > Operator Situational Awareness > Vision-Rooted Chart Hierarchy
设置偏好
用户说“将偏好 X 设为 Y”:
- 更新 session.json 中的
preferences
操作后书签(自动更新协议)
其他 swain 技能会在操作后更新会话书签。请阅读 references/bookmark-protocol.md,了解协议、调用模式和示例。
焦点通道
操作员可以设置焦点通道,将推荐范围限定在一个愿景或计划内。这是一种引导机制——它不会隐藏其他工作,而是围绕操作员当前的重点组织推荐内容。
设置焦点: 当操作员说“聚焦安全”或“我正在处理 VISION-001”时,将名称解析为工件 ID,并调用焦点脚本。
**名称到 ID 的解析:**如果操作员使用名称而非 ID(例如,说“安全”而不是“VISION-001”),使用 swain chart 搜索愿景和计划工件标题,找到最佳匹配:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/chart.sh" --ids --flat 2>/dev/null | grep -i "<name>"
如果只有一个匹配项,就使用它。如果有多个匹配项,请操作员明确选择。如果没有匹配项,告知操作员没有名称匹配的愿景或计划,并提出创建一个。
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-focus.sh" set <RESOLVED-ID>
清除焦点:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-focus.sh" clear
检查焦点:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
bash "$REPO_ROOT/.agents/bin/swain-focus.sh"
对焦点 ID 调用 artifact-context.sh,将焦点工件显示为上下文行。如果该工具不可用,则使用纯 ID。
焦点通道存储在 .agents/session.json 的 focus_lane 键下。它会在一个会话内的状态检查之间持续保留。状态仪表板会读取该值,以筛选推荐内容,并显示非焦点愿景的外围信息。
状态仪表板(SPEC-122)
swain-session 现在负责项目状态仪表板。当操作员说“状态”“接下来做什么”“仪表板”“概览”“目前进展如何”“我该做什么”或“显示优先级”时,运行状态脚本:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
STATUS_SCRIPT="$REPO_ROOT/.agents/bin/swain-status.sh"
[ -f "$STATUS_SCRIPT" ] && bash "$STATUS_SCRIPT" --refresh || echo "status dashboard script not found"
紧凑模式(MOTD):bash "$STATUS_SCRIPT" --compact
脚本运行后,按照 references/agent-summary-template.md 提供结构化的 Agent 摘要。
缓存
状态会写入 .agents/status-cache.json,TTL 为 120 秒。使用 --refresh 绕过缓存,使用 --json 获取原始输出。
推荐
从 JSON 缓存中读取 .priority.recommendations[0]。设置焦点通道后,推荐范围将限定在该愿景或计划内。
丰富上下文的显示
向操作员展示工件(推荐内容、焦点通道、待处理决策)时,使用工件上下文工具,而不是纯 ID:
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
CONTEXT=$(bash "$REPO_ROOT/.agents/bin/artifact-context.sh" <ARTIFACT-ID> 2>/dev/null)
如果该工具可用且有输出,则使用上下文行。如果该工具不可用或输出为空,则回退为 <ID> — <title>(当前行为)。
显示格式:标题 ID — 范围。进度。
模式推断
- 两份规范都在审核中,且有待处理的战略决策 → 询问操作员
- 规范等待审核 → 详细模式
- 已设置焦点通道,且有待处理决策 → 愿景模式
- 没有可执行事项 → 愿景模式(主计划镜像)
待处理决策(路线图集成)
使用 chart.sh roadmap --json 进行 Eisenhower 分类。显示“立即处理”和“安排处理”象限中需要操作员决策的前 5 项。
设置
此技能读取 swain.settings.json(项目根目录)和 ~/.config/swain/settings.json(用户覆盖项)。用户设置优先。
相关设置:
terminal.tabNameFormat— 标签页名称的格式字符串。支持{project}和{branch}占位符。默认值:{project} @ {branch}
错误处理
- 如果没有 jq,警告用户并跳过 JSON 操作。没有 jq 仍可设置标签页名称。
- 如果没有 git,则使用目录名称作为项目名称,并跳过分支检测。
- 绝不彻底失败——会话管理是便利功能,而非门槛。