skills-experimental/exit-worktree-tool/SKILL.md
# Exit Worktree Tool Skill 退出Worktree工具 - Change count fail-closed + Session scope guard + Project root restore + Hooks snapshot restore。 ## 功能概述 从Claude Code的ExitWorktreeTool提取的worktree退出模式,用于OpenClaw的git worktree管理。 ## 核心机制 ### Change Count Fail-Closed ```typescript async function countWorktreeChanges(worktreePath: string, originalHeadCommit: string | undefined): Promise<ChangeSummary | null> { const status = await execFileNoThrow('git', ['-C', worktreePath, 'status', '--porcelain'])
npx skillsauth add bianhaifeng789-hue/openclaw-config skills-experimental/exit-worktree-toolInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
退出Worktree工具 - Change count fail-closed + Session scope guard + Project root restore + Hooks snapshot restore。
从Claude Code的ExitWorktreeTool提取的worktree退出模式,用于OpenClaw的git worktree管理。
async function countWorktreeChanges(worktreePath: string, originalHeadCommit: string | undefined): Promise<ChangeSummary | null> {
const status = await execFileNoThrow('git', ['-C', worktreePath, 'status', '--porcelain'])
if (status.code !== 0) return null // git failure → null
const changedFiles = count(status.stdout.split('\n'), l => l.trim() !== '')
if (!originalHeadCommit) return null // no baseline → null, fail-closed
const revList = await execFileNoThrow('git', ['-C', worktreePath, 'rev-list', '--count', `${originalHeadCommit}..HEAD`])
if (revList.code !== 0) return null
const commits = parseInt(revList.stdout.trim(), 10) || 0
return { changedFiles, commits }
}
// git失败 → null (fail-closed)
// silent 0/0 would destroy real work
const session = getCurrentWorktreeSession()
if (!session) {
return {
result: false,
message: 'No-op: there is no active EnterWorktree session to exit. This tool only operates on worktrees created by EnterWorktree in the current session — it will not touch worktrees created manually or in a previous session.',
errorCode: 1
}
}
// 只操作EnterWorktree创建的worktree
// 不touch手动创建的
// Scope guard
function restoreSessionToOriginalCwd(originalCwd: string, projectRootIsWorktree: boolean): void {
setCwd(originalCwd)
setOriginalCwd(originalCwd)
if (projectRootIsWorktree) {
setProjectRoot(originalCwd) // only restore when actually changed
updateHooksConfigSnapshot() // symmetric restore
}
saveWorktreeState(null)
clearSystemPromptSections()
clearMemoryFileCaches()
getPlansDirectory.cache.clear?.()
}
// projectRoot只在was changed时restore
// 保持"stable project identity" contract
if (projectRootIsWorktree) {
updateHooksConfigSnapshot() // setup.ts's --worktree block called it, restore symmetrically
}
// --worktree startup → hooks from worktree
// Exit → restore hooks from original
// Symmetric
if (input.action === 'remove' && !input.discard_changes) {
const summary = await countWorktreeChanges(session.worktreePath, session.originalHeadCommit)
if (summary === null) {
return { result: false, message: 'Could not verify worktree state. Refusing without discard_changes: true', errorCode: 3 }
}
if (summary.changedFiles > 0 || summary.commits > 0) {
return { result: false, message: `Worktree has ${changedFiles} files and ${commits} commits. Confirm with discard_changes: true`, errorCode: 2 }
}
}
// remove + 有changes → require discard_changes: true
// 不自动删除
if (tmuxSessionName) {
await killTmuxSession(tmuxSessionName)
}
// tmux session → kill
// 完整清理
{
"action": "keep",
"originalCwd": "/path/to/main",
"worktreePath": "/path/to/worktree",
"worktreeBranch": "feature-branch",
"changedFiles": 3,
"commits": 2,
"tmuxSession": "wt-123"
}
git failure → null → refuse without explicit confirmation
// 不silent 0/0
// 保护用户数据
getCurrentWorktreeSession() null → no-op, won't touch manual worktrees
// 只操作自己创建的
// 安全边界
EnterWorktree → set hooks/config
ExitWorktree → restore hooks/config
// 对称restore
remove + changes → require discard_changes: true
// explicit confirmation
// 不意外删除
tools/ExitWorktreeTool/ExitWorktreeTool.ts (8KB+)business
IAA 日报飞书输出能力。 支持把固定 CSV 模板一键转换成: - 中文运营结论 - 飞书卡片 JSON - 飞书发送载荷 Use when: - 需要把 IAA 日报直接发到飞书 - 需要从 CSV 一键生成运营日报
data-ai
IAA日报分析模型 功能: - 渠道日报自动分析 - 小时级+日级ROI联动判断 - 按地区输出加量/降量/停投建议 - 按产品类型输出阈值 - 自动识别利润区/观察区/止损区 Use when: - 分析每天投放数据 - 生成运营日报结论 - 判断是否加量/降量/停投 - 对比美加澳/日韩表现 Keywords: - 日报模型, 投放日报, 加量, 降量, 停投, ROI日报, 分地区分析
data-ai
IAA固定日报分析模板 功能: - 固定字段模板(可直接贴每天数据) - 自动输出总盘结论 - 自动输出美加澳/日韩结论 - 自动给出加量/降量/停投建议 - 适配文件修复/清理两类产品 Use when: - 需要固定日报格式 - 每天复盘渠道表现 - 给运营团队出统一结论 Keywords: - 固定模板, 日报模板, ROI模板, IAA日报, 运营模板
development
# HyperlinkPool Pattern Skill HyperlinkPool Pattern - HyperlinkPool class + strings array + stringMap + Index 0 no hyperlink + intern(hyperlink) + get(id) + undefined handling + 5-minute reset + OSC8 hyperlink interning。 ## 功能概述 从Claude Code的ink/screen.ts提取的HyperlinkPool模式,用于OpenClaw的OSC8超链接池管理。 ## 核心机制 ### HyperlinkPool Class ```typescript export class HyperlinkPool { private strings: string[] = [''] // Index 0 = no hyperlink private stringMap = new Map<string, number>() // strings