skills-experimental/combined-abort-signal-pattern/SKILL.md
# Combined Abort Signal Pattern Skill Combined Abort Signal Pattern - createCombinedAbortSignal + signal + signalB + timeoutMs + cleanup function + setTimeout + clearTimeout cleanup + removeEventListener cleanup + unref timer + Bun AbortSignal.timeout memory leak avoid + multi-source abort。 ## 功能概述 从Claude Code的utils/combinedAbortSignal.ts提取的Combined abort signal模式,用于OpenClaw的多源Abort组合。 ## 核心机制 ### createCombinedAbortSignal ```typescript export function createCombinedAbortSignal( signal:
npx skillsauth add bianhaifeng789-hue/openclaw-config skills-experimental/combined-abort-signal-patternInstall 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.
Combined Abort Signal Pattern - createCombinedAbortSignal + signal + signalB + timeoutMs + cleanup function + setTimeout + clearTimeout cleanup + removeEventListener cleanup + unref timer + Bun AbortSignal.timeout memory leak avoid + multi-source abort。
从Claude Code的utils/combinedAbortSignal.ts提取的Combined abort signal模式,用于OpenClaw的多源Abort组合。
export function createCombinedAbortSignal(
signal: AbortSignal | undefined,
opts?: { signalB?: AbortSignal; timeoutMs?: number },
): { signal: AbortSignal; cleanup: () => void } {
const { signalB, timeoutMs } = opts ?? {}
const combined = createAbortController()
// Fast path: already aborted
if (signal?.aborted || signalB?.aborted) {
combined.abort()
return { signal: combined.signal, cleanup: () => {} }
}
// Setup listeners and timer
// ...
return { signal: combined.signal, cleanup }
}
// Combined abort signal
# Aborts on: signal abort, signalB abort, timeout
# Returns cleanup function
signal: AbortSignal | undefined // Primary signal
signalB?: AbortSignal // Secondary signal
timeoutMs?: number // Timeout in milliseconds
// Three abort sources
# Primary signal
# Secondary signal
# Timeout
return { signal: combined.signal, cleanup }
// cleanup: () => void
// Removes event listeners
// Clears timeout timer
# Cleanup on completion
let timer: ReturnType<typeof setTimeout> | undefined
const abortCombined = () => {
if (timer !== undefined) clearTimeout(timer)
combined.abort()
}
if (timeoutMs !== undefined) {
timer = setTimeout(abortCombined, timeoutMs)
timer.unref?.()
}
const cleanup = () => {
if (timer !== undefined) clearTimeout(timer)
signal?.removeEventListener('abort', abortCombined)
signalB?.removeEventListener('abort', abortCombined)
}
// Timer + cleanup
# setTimeout for timeout
# clearTimeout in cleanup
const cleanup = () => {
if (timer !== undefined) clearTimeout(timer)
signal?.removeEventListener('abort', abortCombined)
signalB?.removeEventListener('abort', abortCombined)
}
// Remove listeners in cleanup
# Prevent memory leak
# Cleanup on completion
timer = setTimeout(abortCombined, timeoutMs)
timer.unref?.()
// unref: don't block process exit
# Timer doesn't keep Node alive
// Use `timeoutMs` instead of passing `AbortSignal.timeout(ms)` as a signal —
// under Bun, `AbortSignal.timeout` timers are finalized lazily and accumulate
// in native memory until they fire (measured ~2.4KB/call held for the full
// timeout duration). This implementation uses `setTimeout` + `clearTimeout`
// so the timer is freed immediately on cleanup.
// Bun AbortSignal.timeout memory leak
# ~2.4KB/call held for full timeout
# setTimeout + clearTimeout freed immediately
signal?.addEventListener('abort', abortCombined)
signalB?.addEventListener('abort', abortCombined)
if (timeoutMs !== undefined) timer = setTimeout(abortCombined, timeoutMs)
// Three abort sources
# Any source → combined.abort()
# Multi-source abort
{
"signal": "AbortSignal",
"signalB": "AbortSignal",
"timeoutMs": 30000,
"aborted": false,
"cleanup": "() => void"
}
return {signal: combined.signal, cleanup: () => {...}} → cleanup removes listeners + clears timer → cleanup on completion
# cleanup function返回
# removes listeners + clears timer
# completion时cleanup
setTimeout → abortCombined | clearTimeout(timer) → cleanup → immediate free → no native memory accumulation
# setTimeout + clearTimeout pattern
# 立即free timer
# 无native memory accumulation
AbortSignal.timeout(ms) → ~2.4KB/call native memory → lazy finalize → setTimeout/clearTimeout → immediate free
# Bun AbortSignal.timeout memory leak
# ~2.4KB/call native memory
# lazy finalize
# setTimeout/clearTimeout立即free
timer.unref() → don't block process exit → allow Node exit while timer pending
# unref不阻塞exit
# Node可以在timer pending时exit
signal abort | signalB abort | timeout → combined.abort() → any source → abort
# multi-source abort
# 任一source触发abort
utils/combinedAbortSignal.ts (64 lines)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