UNPKG

@brianlovin/notion-skills

Version:

Sync agent skills from a Notion database to Claude Code, Codex, OpenCode, Cursor, Gemini CLI.

65 lines 2.44 kB
import chalk from "chalk"; const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; const SPINNER_INTERVAL_MS = 80; export function startTask(label) { const tty = !!process.stdout.isTTY; let interval; if (tty) { let frame = 0; process.stdout.write(` ${chalk.cyan(SPINNER_FRAMES[0])} ${label}`); interval = setInterval(() => { frame = (frame + 1) % SPINNER_FRAMES.length; process.stdout.write(`\r ${chalk.cyan(SPINNER_FRAMES[frame])} ${label}`); }, SPINNER_INTERVAL_MS); // Don't keep the event loop alive just for the spinner. interval.unref(); } const stop = () => { if (interval) { clearInterval(interval); interval = undefined; } }; return { done(note) { stop(); const tail = note ? ` ${chalk.dim(note)}` : ""; const line = ` ${chalk.green("✓")} ${label}${tail}\n`; process.stdout.write(tty ? `\r\x1b[2K${line}` : line); }, fail(reason) { stop(); const tail = reason ? ` ${chalk.dim(`(${reason})`)}` : ""; const line = ` ${chalk.red("✗")} ${label}${tail}\n`; process.stdout.write(tty ? `\r\x1b[2K${line}` : line); }, }; } /** * Wrap an async operation in a spinner. Resolves to the operation's * return value; on failure, marks the spinner failed and rethrows so * the caller (or top-level error handler) can decide what to do. * * Optional `noteFor` callback derives a one-line note shown after * the ✓ on success — useful for "✓ Querying Skills (17 pages)" * style outputs without forcing callers to drop down to startTask. * * Use this instead of static `chalk.dim("Doing thing…")` lines for * any user-visible wait > ~500ms — Notion API calls, GitHub fetches, * schema reconciliation. The braille spinner makes it obvious the * tool is alive vs hung. */ export async function withSpinner(label, fn, options = {}) { const task = startTask(label); try { const result = await fn(); task.done(options.noteFor ? options.noteFor(result) : undefined); return result; } catch (err) { const reason = err instanceof Error ? err.message.split("\n")[0] : String(err); task.fail(reason); throw err; } } //# sourceMappingURL=_progress.js.map