skills-experimental/abort-safe-sleep-pattern/SKILL.md
# Abort-Safe Sleep Pattern Skill Abort-Safe Sleep Pattern - sleep function + AbortSignal responsive + signal?.aborted check BEFORE timer + throwOnAbort option + abortError custom + unref timer + removeEventListener cleanup + setTimeout unref + withTimeout race + Promise.race pattern。 ## 功能概述 从Claude Code的utils/sleep.ts提取的Abort-safe sleep模式,用于OpenClaw的响应式延迟。 ## 核心机制 ### sleep Function ```typescript export function sleep( ms: number, signal?: AbortSignal, opts?: { throwOnAbort?: boolea
npx skillsauth add bianhaifeng789-hue/openclaw-config skills-experimental/abort-safe-sleep-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.
Abort-Safe Sleep Pattern - sleep function + AbortSignal responsive + signal?.aborted check BEFORE timer + throwOnAbort option + abortError custom + unref timer + removeEventListener cleanup + setTimeout unref + withTimeout race + Promise.race pattern。
从Claude Code的utils/sleep.ts提取的Abort-safe sleep模式,用于OpenClaw的响应式延迟。
export function sleep(
ms: number,
signal?: AbortSignal,
opts?: { throwOnAbort?: boolean; abortError?: () => Error; unref?: boolean },
): Promise<void> {
return new Promise((resolve, reject) => {
// ...
})
}
// Abort-responsive sleep
# Resolves after ms OR on signal abort
signal?.addEventListener('abort', onAbort, { once: true })
// Listen to abort signal
# Abort → resolve immediately (or reject)
# Backoff loops don't block shutdown
// Check aborted state BEFORE setting up the timer. If we defined
// onAbort first and called it synchronously here, it would reference
// `timer` while still in the Temporal Dead Zone.
if (signal?.aborted) {
if (opts?.throwOnAbort || opts?.abortError) {
void reject(opts.abortError?.() ?? new Error('aborted'))
} else {
void resolve()
}
return
}
// Check BEFORE timer setup
# Avoids TDZ (Temporal Dead Zone)
# timer not defined yet
if (opts?.throwOnAbort || opts?.abortError) {
void reject(opts.abortError?.() ?? new Error('aborted'))
} else {
void resolve()
}
// throwOnAbort: reject vs resolve
# Default: resolve silently
# throwOnAbort: reject with error
opts.abortError?.() ?? new Error('aborted')
// Custom abort error
# Useful for retry loops catching specific error class
# e.g., APIUserAbortError
const timer = setTimeout(...)
if (opts?.unref) {
timer.unref()
}
// unref: don't block process exit
# Allow process to exit while timer pending
const timer = setTimeout(
(signal, onAbort, resolve) => {
signal?.removeEventListener('abort', onAbort)
void resolve()
},
ms,
signal,
onAbort,
resolve,
)
// Cleanup on timer resolve
# removeEventListener('abort', onAbort)
# Prevent memory leak
timer.unref()
// Don't block process exit
# Timer doesn't keep Node process alive
export function withTimeout<T>(
promise: Promise<T>,
ms: number,
message: string,
): Promise<T> {
let timer: ReturnType<typeof setTimeout> | undefined
const timeoutPromise = new Promise<never>((_, reject) => {
timer = setTimeout(rejectWithTimeout, ms, reject, message)
if (typeof timer === 'object') timer.unref?.()
})
return Promise.race([promise, timeoutPromise]).finally(() => {
if (timer !== undefined) clearTimeout(timer)
})
}
// Race promise against timeout
# Timeout rejects with Error(message)
# unref timer
# finally clears timer
Promise.race([promise, timeoutPromise]).finally(() => {
if (timer !== undefined) clearTimeout(timer)
})
// Race between promise and timeout
# Timeout wins → reject
# Promise wins → resolve
# finally cleanup timer
{
"ms": 1000,
"aborted": false,
"throwOnAbort": false,
"unref": true
}
signal?.aborted check → BEFORE timer setup → avoid TDZ → timer not defined yet
# 在timer setup之前check abort
# 避免Temporal Dead Zone
# timer还未定义
throwOnAbort=false → resolve silently | throwOnAbort=true → reject with error → different behavior
# throwOnAbort决定abort行为
# false: resolve silently
# true: reject with error
timer.unref() → don't block process exit → allow exit while pending → Node.js pattern
# timer.unref()不阻塞进程退出
# 允许在timer pending时exit
# Node.js pattern
signal.removeEventListener('abort', onAbort) → cleanup on resolve → prevent memory leak
# removeEventListener cleanup
# 防止memory leak
# on resolve时cleanup
Promise.race([promise, timeout]).finally(clearTimeout(timer)) → race + cleanup → no dangling timer
# Promise.race + finally cleanup
# 清除dangling timer
# 无论谁赢都cleanup
utils/sleep.ts (84 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