@react-grab/cli 0.1.48-dev.f29c951 → 0.1.48-dev.fe982d7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["VERSION","VERSION","VERSION","VERSION","VERSION"],"sources":["../src/utils/is-non-interactive.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/handle-error.ts","../src/utils/unref-stdin.ts","../src/utils/prompts.ts","../src/utils/spinner.ts","../src/utils/prompt-skill-install.ts","../src/commands/add.ts","../src/utils/diff.ts","../src/utils/constants.ts","../src/utils/format-activation-key.ts","../src/commands/configure.ts","../src/utils/cli-helpers.ts","../src/utils/is-telemetry-enabled.ts","../src/commands/init.ts","../src/utils/sleep.ts","../src/utils/clipboard.ts","../src/utils/daemon.ts","../src/utils/grab-log.ts","../src/utils/read-args.ts","../src/commands/pull.ts","../src/commands/remove.ts","../src/commands/stop.ts","../src/commands/upgrade.ts","../src/commands/watch.ts","../src/cli.ts"],"sourcesContent":["const AGENT_ENVIRONMENT_VARIABLES = [\n \"CI\",\n \"CLAUDECODE\",\n \"CURSOR_AGENT\",\n \"CODEX_CI\",\n \"OPENCODE\",\n \"AMP_HOME\",\n \"AMI\",\n] as const;\n\nconst isEnvironmentVariableSet = (variable: string): boolean => Boolean(process.env[variable]);\n\nexport const detectNonInteractive = (yesFlag: boolean): boolean =>\n yesFlag || AGENT_ENVIRONMENT_VARIABLES.some(isEnvironmentVariableSet) || !process.stdin.isTTY;\n","import pc from \"picocolors\";\n\nexport const highlighter = {\n error: pc.red,\n warn: pc.yellow,\n info: pc.cyan,\n success: pc.green,\n dim: pc.dim,\n};\n","import { highlighter } from \"./highlighter.js\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import { logger } from \"./logger.js\";\n\nexport const handleError = (error: unknown) => {\n logger.break();\n logger.error(\"Something went wrong. Please check the error below for more details.\");\n logger.error(\"If the problem persists, please open an issue on GitHub.\");\n logger.error(\"\");\n if (error instanceof Error) {\n logger.error(error.message);\n }\n logger.break();\n process.exit(1);\n};\n","// HACK: this is a one-shot CLI, but when stdin (fd 0) is an inherited pipe or\n// socket Node keeps the event loop alive for as long as that handle is open —\n// even though the only thing that ever reads stdin is an interactive prompt.\n// When the CLI is spawned by a parent that holds the stdin write-end open (eval\n// runners, CI harnesses, editor integrations), the command finishes yet the\n// process never exits: the inherited `Socket fd=0` refs the loop. Unref-ing fd\n// 0 makes an idle pipe/socket incapable of holding the process open.\n//\n// We MUST NOT unref an interactive TTY. A real terminal is the only case that\n// shows prompts, and `prompts` never re-refs an unref'd stdin handle: its base\n// element does `readline.createInterface(...)` + `setRawMode(true)` but never\n// `resume()`, none of which re-ref the libuv handle. Unref-ing a TTY would let\n// the event loop drain while a prompt is still waiting for input — the CLI\n// would render the prompt and then exit by itself before the user can answer.\n// Guarding on `isTTY` keeps the one-shot exit fix without breaking prompts.\nexport const unrefStdin = (): void => {\n if (process.stdin.isTTY) return;\n process.stdin.unref?.();\n};\n","import basePrompts, { type PromptObject, type Answers } from \"prompts\";\nimport { logger } from \"./logger.js\";\nimport { unrefStdin } from \"./unref-stdin.js\";\n\nconst onCancel = () => {\n logger.break();\n logger.log(\"Cancelled.\");\n logger.break();\n process.exit(0);\n};\n\nexport const prompts = <T extends string = string>(\n questions: PromptObject<T> | PromptObject<T>[],\n): Promise<Answers<T>> => {\n // HACK: each prompt re-refs stdin and never unrefs it on close, so re-unref\n // once it settles or the one-shot CLI hangs. See `unref-stdin.ts` for why.\n return basePrompts(questions, { onCancel }).finally(unrefStdin);\n};\n","import ora from \"ora\";\n\nexport const spinner = (text: string) => ora({ text });\n","import { detectAvailableAgents } from \"./detect-agents.js\";\nimport { highlighter } from \"./highlighter.js\";\nimport { agentLabel, installSkill } from \"./install-skill.js\";\nimport { logger } from \"./logger.js\";\nimport { prompts } from \"./prompts.js\";\nimport { spinner } from \"./spinner.js\";\n\ninterface PromptSkillInstallOptions {\n yes?: boolean;\n global?: boolean;\n cwd?: string;\n}\n\nexport const promptSkillInstall = async ({\n yes = false,\n global = false,\n cwd = process.cwd(),\n}: PromptSkillInstallOptions = {}): Promise<boolean> => {\n const detectedAgents = await detectAvailableAgents();\n if (detectedAgents.length === 0) {\n logger.warn(\"No supported agents detected.\");\n return false;\n }\n\n let selectedAgents = detectedAgents;\n if (!yes) {\n const { confirmed } = await prompts({\n type: \"confirm\",\n name: \"confirmed\",\n message: `Install the React Grab skill (${global ? \"global\" : \"this project\"})?`,\n initial: true,\n });\n if (!confirmed) return false;\n\n const { agents } = await prompts({\n type: \"multiselect\",\n name: \"agents\",\n message: `Install the React Grab skill (${global ? \"global\" : \"this project\"}) for:`,\n choices: detectedAgents.map((agent) => ({\n title: agentLabel(agent),\n value: agent,\n selected: true,\n })),\n instructions: false,\n min: 1,\n });\n selectedAgents = agents ?? [];\n if (selectedAgents.length === 0) return false;\n }\n\n const installSpinner = spinner(\"Installing React Grab skill.\").start();\n const { installed, failed } = await installSkill({ agents: selectedAgents, global, cwd });\n\n if (installed.length === 0) {\n installSpinner.fail(\"Failed to install React Grab skill.\");\n return false;\n }\n installSpinner.succeed(\n `Installed React Grab skill for ${installed.map((record) => agentLabel(record.agent)).join(\", \")}.`,\n );\n for (const record of failed) {\n logger.log(` ${highlighter.error(\"\\u2717\")} ${agentLabel(record.agent)} ${record.error}`);\n }\n return true;\n};\n","import { resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { promptSkillInstall } from \"../utils/prompt-skill-install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const add = new Command()\n .name(\"add\")\n .alias(\"install\")\n .description(\"install the React Grab skill for your agent\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"install the skill globally instead of in the project\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n const projectInfo = await detectProject(opts.cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n logger.break();\n\n const didInstall = await promptSkillInstall({\n yes: isNonInteractive,\n global: opts.global,\n cwd: resolve(opts.cwd),\n });\n // In non-interactive mode a falsy result is a real failure (no agents or\n // install error), not a user declining the prompt — surface it to CI.\n if (!didInstall && isNonInteractive) {\n logger.break();\n process.exit(1);\n }\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","interface DiffLine {\n type: \"added\" | \"removed\" | \"unchanged\";\n content: string;\n lineNumber?: number;\n}\n\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst GRAY = \"\\x1b[90m\";\nconst RESET = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\n\nexport const generateDiff = (originalContent: string, newContent: string): DiffLine[] => {\n const originalLines = originalContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const diff: DiffLine[] = [];\n\n let originalIndex = 0;\n let newIndex = 0;\n\n while (originalIndex < originalLines.length || newIndex < newLines.length) {\n const originalLine = originalLines[originalIndex];\n const newLine = newLines[newIndex];\n\n if (originalLine === newLine) {\n diff.push({\n type: \"unchanged\",\n content: originalLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n } else if (originalLine === undefined) {\n diff.push({ type: \"added\", content: newLine, lineNumber: newIndex + 1 });\n newIndex++;\n } else if (newLine === undefined) {\n diff.push({ type: \"removed\", content: originalLine });\n originalIndex++;\n } else {\n const originalInNew = newLines.indexOf(originalLine, newIndex);\n const newInOriginal = originalLines.indexOf(newLine, originalIndex);\n\n if (\n originalInNew !== -1 &&\n (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)\n ) {\n while (newIndex < originalInNew) {\n diff.push({\n type: \"added\",\n content: newLines[newIndex],\n lineNumber: newIndex + 1,\n });\n newIndex++;\n }\n } else if (newInOriginal !== -1) {\n while (originalIndex < newInOriginal) {\n diff.push({ type: \"removed\", content: originalLines[originalIndex] });\n originalIndex++;\n }\n } else {\n diff.push({ type: \"removed\", content: originalLine });\n diff.push({\n type: \"added\",\n content: newLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n }\n }\n }\n\n return diff;\n};\n\nexport const formatDiff = (diff: DiffLine[], contextLines: number = 3): string => {\n const lines: string[] = [];\n let lastPrintedIndex = -1;\n let hasChanges = false;\n\n const changedIndices = diff\n .map((line, index) => (line.type !== \"unchanged\" ? index : -1))\n .filter((index) => index !== -1);\n\n if (changedIndices.length === 0) {\n return `${GRAY}No changes${RESET}`;\n }\n\n for (const changedIndex of changedIndices) {\n const startContext = Math.max(0, changedIndex - contextLines);\n const endContext = Math.min(diff.length - 1, changedIndex + contextLines);\n\n if (startContext > lastPrintedIndex + 1 && lastPrintedIndex !== -1) {\n lines.push(`${GRAY} ...${RESET}`);\n }\n\n for (\n let lineIndex = Math.max(startContext, lastPrintedIndex + 1);\n lineIndex <= endContext;\n lineIndex++\n ) {\n const diffLine = diff[lineIndex];\n\n if (diffLine.type === \"added\") {\n lines.push(`${GREEN}+ ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else if (diffLine.type === \"removed\") {\n lines.push(`${RED}- ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else {\n lines.push(`${GRAY} ${diffLine.content}${RESET}`);\n }\n\n lastPrintedIndex = lineIndex;\n }\n }\n\n return hasChanges ? lines.join(\"\\n\") : `${GRAY}No changes${RESET}`;\n};\n\nexport const printDiff = (filePath: string, originalContent: string, newContent: string): void => {\n console.log(`\\n${BOLD}File: ${filePath}${RESET}`);\n console.log(\"─\".repeat(60));\n\n const diff = generateDiff(originalContent, newContent);\n console.log(formatDiff(diff));\n\n console.log(\"─\".repeat(60));\n};\n","export const MAX_SUGGESTIONS_COUNT = 30;\nexport const MAX_KEY_HOLD_DURATION_MS = 2000;\nexport const MAX_CONTEXT_LINES = 50;\n\nexport const DEFAULT_WATCH_DIR = \".react-grab\";\nexport const DEFAULT_WATCH_INTERVAL_MS = 800;\nexport const READ_WAIT_POLL_MS = 200;\nexport const DAEMON_CLAIM_MAX_ATTEMPTS = 50;\nexport const READ_DEFAULT_LIMIT = 50;\nexport const DEFAULT_GRAB_AGE_MS = 5 * 60 * 1000;\n// A single read must never build a >512 MB string (V8's cap); a bigger backlog\n// drains across calls. Must exceed the largest single grab line.\nexport const MAX_READ_HISTORY_BYTES = 128 * 1024 * 1024;\n\n// Buffer size for the legacy-cursor migration's chunked newline scan, which\n// counts newline bytes without materializing the whole history as a string.\nexport const MIGRATION_SCAN_CHUNK_BYTES = 1024 * 1024;\n","import type { ReactGrabOptions } from \"./transform.js\";\n\nexport const formatActivationKeyDisplay = (\n activationKey: ReactGrabOptions[\"activationKey\"],\n): string => {\n const defaultLabel = process.platform === \"darwin\" ? \"Option\" : \"Alt\";\n if (!activationKey) return `Default (${defaultLabel})`;\n return activationKey\n .split(\"+\")\n .map((part) => {\n const lower = part.toLowerCase();\n if (lower === \"meta\") return process.platform === \"darwin\" ? \"⌘\" : \"Win\";\n if (lower === \"alt\") return process.platform === \"darwin\" ? \"⌥\" : \"Alt\";\n if (lower === \"ctrl\") return \"Ctrl\";\n if (lower === \"shift\") return \"Shift\";\n if (lower === \"space\" || lower === \" \") return \"Space\";\n return part.toUpperCase();\n })\n .join(\" + \");\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n applyTransform,\n previewCdnTransform,\n previewOptionsTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport {\n MAX_SUGGESTIONS_COUNT,\n MAX_KEY_HOLD_DURATION_MS,\n MAX_CONTEXT_LINES,\n} from \"../utils/constants.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\ninterface ConfigOption {\n id: string;\n title: string;\n description: string;\n}\n\nconst isMac = process.platform === \"darwin\";\nconst META_LABEL = isMac ? \"Cmd\" : \"Win\";\nconst ALT_LABEL = isMac ? \"Option\" : \"Alt\";\n\nconst MODIFIER_ALIASES: Record<string, string> = {\n cmd: \"meta\",\n command: \"meta\",\n win: \"meta\",\n windows: \"meta\",\n meta: \"meta\",\n ctrl: \"ctrl\",\n control: \"ctrl\",\n shift: \"shift\",\n alt: \"alt\",\n option: \"alt\",\n opt: \"alt\",\n};\n\nconst MODIFIERS = [\"meta\", \"ctrl\", \"shift\", \"alt\"] as const;\n\nconst BASE_KEYS: Array<{ key: string; aliases: string[] }> = [\n { key: \" \", aliases: [\"space\", \"spacebar\"] },\n { key: \"Enter\", aliases: [\"enter\", \"return\"] },\n { key: \"Escape\", aliases: [\"escape\", \"esc\"] },\n { key: \"Tab\", aliases: [\"tab\"] },\n { key: \"Backspace\", aliases: [\"backspace\", \"back\"] },\n { key: \"Delete\", aliases: [\"delete\", \"del\"] },\n { key: \"Insert\", aliases: [\"insert\", \"ins\"] },\n { key: \"Home\", aliases: [\"home\"] },\n { key: \"End\", aliases: [\"end\"] },\n { key: \"PageUp\", aliases: [\"pageup\", \"pgup\"] },\n { key: \"PageDown\", aliases: [\"pagedown\", \"pgdn\", \"pgdown\"] },\n { key: \"ArrowUp\", aliases: [\"arrowup\", \"up\"] },\n { key: \"ArrowDown\", aliases: [\"arrowdown\", \"down\"] },\n { key: \"ArrowLeft\", aliases: [\"arrowleft\", \"left\"] },\n { key: \"ArrowRight\", aliases: [\"arrowright\", \"right\"] },\n ...Array.from({ length: 12 }, (_, i) => ({\n key: `F${i + 1}`,\n aliases: [`f${i + 1}`],\n })),\n ...Array.from({ length: 26 }, (_, i) => {\n const letter = String.fromCharCode(97 + i);\n return { key: letter, aliases: [letter] };\n }),\n ...Array.from({ length: 10 }, (_, i) => ({\n key: String(i),\n aliases: [String(i)],\n })),\n { key: \"`\", aliases: [\"backtick\", \"grave\", \"`\"] },\n { key: \"-\", aliases: [\"minus\", \"dash\", \"-\"] },\n { key: \"=\", aliases: [\"equals\", \"equal\", \"=\"] },\n { key: \"[\", aliases: [\"leftbracket\", \"lbracket\", \"[\"] },\n { key: \"]\", aliases: [\"rightbracket\", \"rbracket\", \"]\"] },\n { key: \"\\\\\", aliases: [\"backslash\", \"\\\\\"] },\n { key: \";\", aliases: [\"semicolon\", \";\"] },\n { key: \"'\", aliases: [\"quote\", \"apostrophe\", \"'\"] },\n { key: \",\", aliases: [\"comma\", \",\"] },\n { key: \".\", aliases: [\"period\", \"dot\", \".\"] },\n { key: \"/\", aliases: [\"slash\", \"forwardslash\", \"/\"] },\n];\n\ninterface KeyCombo {\n key: string;\n metaKey?: boolean;\n ctrlKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n}\n\ninterface KeyChoice {\n title: string;\n value: KeyCombo;\n}\n\nconst formatCombo = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(META_LABEL);\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(ALT_LABEL);\n const keyDisplay =\n combo.key === \" \" ? \"Space\" : combo.key.length === 1 ? combo.key.toUpperCase() : combo.key;\n parts.push(keyDisplay);\n return parts.join(\"+\");\n};\n\nconst parseInput = (input: string): { modifiers: Set<string>; partial: string } => {\n const normalized = input.toLowerCase().replace(/\\s+/g, \"\");\n const parts = normalized.split(/[+-]/);\n const modifiers = new Set<string>();\n let partial = \"\";\n\n for (const part of parts) {\n if (!part) continue;\n const modifierKey = MODIFIER_ALIASES[part];\n if (modifierKey) {\n modifiers.add(modifierKey);\n } else {\n partial = part;\n }\n }\n\n return { modifiers, partial };\n};\n\nconst POPULAR_KEYS = [\"g\", \"k\", \"e\", \"d\", \"b\", \" \", \"Escape\", \"Enter\"];\n\nconst generateSuggestions = (input: string): KeyChoice[] => {\n const { modifiers, partial } = parseInput(input);\n const suggestions: KeyChoice[] = [];\n\n if (!partial && modifiers.size === 0 && !input) {\n for (const mod of MODIFIERS) {\n const label =\n mod === \"meta\"\n ? META_LABEL\n : mod === \"alt\"\n ? ALT_LABEL\n : mod.charAt(0).toUpperCase() + mod.slice(1);\n for (const popularKey of POPULAR_KEYS) {\n const keyDisplay =\n popularKey === \" \"\n ? \"Space\"\n : popularKey.length === 1\n ? popularKey.toUpperCase()\n : popularKey;\n suggestions.push({\n title: `${label}+${keyDisplay}`,\n value: {\n key: popularKey,\n ...(mod === \"meta\" ? { metaKey: true } : {}),\n ...(mod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mod === \"shift\" ? { shiftKey: true } : {}),\n ...(mod === \"alt\" ? { altKey: true } : {}),\n },\n });\n }\n }\n for (const baseKey of BASE_KEYS) {\n suggestions.push({\n title:\n baseKey.key === \" \"\n ? \"Space\"\n : baseKey.key.length === 1\n ? baseKey.key.toUpperCase()\n : baseKey.key,\n value: { key: baseKey.key },\n });\n }\n return suggestions;\n }\n\n const buildCombo = (key: string, mods: Set<string>, extraMod?: string): KeyCombo => ({\n key,\n ...(mods.has(\"meta\") || extraMod === \"meta\" ? { metaKey: true } : {}),\n ...(mods.has(\"ctrl\") || extraMod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mods.has(\"shift\") || extraMod === \"shift\" ? { shiftKey: true } : {}),\n ...(mods.has(\"alt\") || extraMod === \"alt\" ? { altKey: true } : {}),\n });\n\n for (const baseKey of BASE_KEYS) {\n const matches = partial ? baseKey.aliases.some((alias) => alias.startsWith(partial)) : true;\n if (matches) {\n const combo = buildCombo(baseKey.key, modifiers);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n\n if (!partial) {\n const unusedMods = MODIFIERS.filter((m) => !modifiers.has(m));\n for (const mod of unusedMods) {\n for (const popularKey of POPULAR_KEYS) {\n const combo = buildCombo(popularKey, modifiers, mod);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n }\n\n return suggestions.slice(0, MAX_SUGGESTIONS_COUNT);\n};\n\nconst CONFIG_OPTIONS: ConfigOption[] = [\n {\n id: \"activationKey\",\n title: \"Shortcut\",\n description: \"The shortcut used to activate React Grab (e.g., g, k, space)\",\n },\n {\n id: \"activationMode\",\n title: \"Activation Mode\",\n description: \"Toggle (press to activate/deactivate) or Hold (hold key)\",\n },\n {\n id: \"keyHoldDuration\",\n title: \"Key Hold Duration\",\n description: \"Milliseconds to hold the key before activation (hold mode)\",\n },\n {\n id: \"allowActivationInsideInput\",\n title: \"Allow Activation Inside Input\",\n description: \"Whether to allow activation when focused on input fields\",\n },\n {\n id: \"maxContextLines\",\n title: \"Max Context Lines\",\n description: \"Max source-location lines in copied context (raise for large apps)\",\n },\n];\n\nconst comboToString = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(\"Meta\");\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(\"Alt\");\n if (combo.key) {\n const keyDisplay = combo.key === \" \" ? \"Space\" : combo.key;\n parts.push(keyDisplay);\n }\n return parts.join(\"+\");\n};\n\nexport const configure = new Command()\n .name(\"configure\")\n .alias(\"config\")\n .description(\"configure React Grab options\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-k, --key <key>\", \"shortcut (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"-m, --mode <mode>\", \"activation mode (toggle, hold)\")\n .option(\"--hold-duration <ms>\", \"key hold duration in milliseconds (for hold mode)\")\n .option(\"--allow-input <boolean>\", \"allow activation inside input fields (true/false)\")\n .option(\"--context-lines <lines>\", \"max context lines to include\")\n .option(\"--cdn <domain>\", \"CDN domain (e.g., unpkg.com, custom.react-grab.com)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n if (!projectInfo.isReactGrabConfigured) {\n preflightSpinner.fail(\"React Grab is installed, but setup is missing.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"react-grab init\")} to add the setup script/import before configuring options.`,\n );\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (opts.cdn) {\n const result = previewCdnTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n opts.cdn,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.break();\n process.exit(1);\n }\n\n if (result.noChanges) {\n logger.break();\n logger.log(\"No changes needed.\");\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} CDN updated.`);\n logger.break();\n return;\n }\n\n const hasFlags =\n opts.key || opts.mode || opts.holdDuration || opts.allowInput || opts.contextLines;\n\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (hasFlags) {\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (opts.mode) {\n if (opts.mode !== \"toggle\" && opts.mode !== \"hold\") {\n logger.error(`Invalid mode: ${opts.mode}. Use \"toggle\" or \"hold\".`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.activationMode = opts.mode;\n logger.log(` Activation mode: ${highlighter.info(opts.mode)}`);\n }\n\n if (opts.holdDuration) {\n const duration = parseInt(opts.holdDuration, 10);\n if (isNaN(duration) || duration < 0 || duration > MAX_KEY_HOLD_DURATION_MS) {\n logger.error(`Invalid hold duration. Must be 0-${MAX_KEY_HOLD_DURATION_MS}ms.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.keyHoldDuration = duration;\n logger.log(` Key hold duration: ${highlighter.info(`${duration}ms`)}`);\n }\n\n if (opts.allowInput !== undefined) {\n const allowInput = opts.allowInput === \"true\" || opts.allowInput === true;\n collectedOptions.allowActivationInsideInput = allowInput;\n logger.log(` Allow activation inside input: ${highlighter.info(String(allowInput))}`);\n }\n\n if (opts.contextLines) {\n const lines = parseInt(opts.contextLines, 10);\n if (isNaN(lines) || lines < 0 || lines > MAX_CONTEXT_LINES) {\n logger.error(`Invalid context lines. Must be 0-${MAX_CONTEXT_LINES}.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.maxContextLines = lines;\n logger.log(` Max context lines: ${highlighter.info(String(lines))}`);\n }\n } else {\n const { selectedOption } = await prompts({\n type: \"autocomplete\",\n name: \"selectedOption\",\n message: \"Search for an option to configure:\",\n choices: CONFIG_OPTIONS.map((option) => ({\n title: option.title,\n value: option.id,\n description: option.description,\n })),\n suggest: (input, choices) =>\n Promise.resolve(\n choices.filter(\n (choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()) ||\n (choice.description?.toLowerCase().includes(input.toLowerCase()) ?? false),\n ),\n ),\n });\n\n if (selectedOption === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (selectedOption === \"activationKey\") {\n const { selectedCombo } = await prompts({\n type: \"autocomplete\",\n name: \"selectedCombo\",\n message: \"Type key combination (e.g. ctrl+shift+g):\",\n choices: generateSuggestions(\"\"),\n suggest: (input) => Promise.resolve(generateSuggestions(input)),\n });\n\n if (selectedCombo === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = comboToString(selectedCombo);\n\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (selectedOption === \"activationMode\") {\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n }\n\n if (selectedOption === \"keyHoldDuration\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n if (selectedOption === \"allowActivationInsideInput\") {\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n }\n\n if (selectedOption === \"maxContextLines\") {\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n }\n }\n\n const result = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!result.success) {\n logger.break();\n logger.warn(result.message);\n logger.break();\n\n const configJson = JSON.stringify(collectedOptions);\n logger.log(\n `Add this to your ${highlighter.info(\"init()\")} call or ${highlighter.info(\"data-options\")} attribute:`,\n );\n logger.break();\n console.log(` ${pc.cyan(configJson)}`);\n logger.break();\n process.exit(1);\n }\n\n const hasChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasChanges) {\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n } else {\n logger.break();\n logger.log(\"No changes needed.\");\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab options have been configured.`);\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import type { PackageManager } from \"./detect.js\";\nimport { applyTransform, type TransformResult } from \"./transform.js\";\nimport { handleError } from \"./handle-error.js\";\nimport { installPackages } from \"./install.js\";\nimport { logger } from \"./logger.js\";\nimport { spinner } from \"./spinner.js\";\n\nexport const applyTransformWithFeedback = (result: TransformResult, message?: string): void => {\n const writeSpinner = spinner(message ?? `Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n};\n\nexport const installPackagesWithFeedback = async (\n packages: string[],\n packageManager: PackageManager,\n projectRoot: string,\n): Promise<void> => {\n if (packages.length === 0) return;\n const installSpinner = spinner(`Installing ${packages.join(\", \")}.`).start();\n try {\n await installPackages(packages, { packageManager, cwd: projectRoot });\n installSpinner.succeed();\n } catch (error) {\n installSpinner.fail();\n handleError(error);\n }\n};\n","export const isTelemetryEnabled = (): boolean => {\n const doNotTrack = process.env.DO_NOT_TRACK;\n return doNotTrack !== \"1\" && doNotTrack !== \"true\";\n};\n","import { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { applyTransformWithFeedback, installPackagesWithFeedback } from \"../utils/cli-helpers.js\";\nimport { promptSkillInstall } from \"../utils/prompt-skill-install.js\";\nimport {\n detectProject,\n findReactProjects,\n type Framework,\n type PackageManager,\n type UnsupportedFramework,\n type WorkspaceProject,\n} from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { getPackagesToInstall } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n hasFrameworkEntryPoint,\n previewOptionsTransform,\n previewTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\nimport { isTelemetryEnabled } from \"../utils/is-telemetry-enabled.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst REPORT_URL = \"https://react-grab.com/api/report-cli\";\nconst DOCS_URL = \"https://github.com/aidenybai/react-grab\";\n\ninterface ReportConfig {\n framework: string;\n packageManager: string;\n router?: string;\n agent?: string;\n isMonorepo: boolean;\n}\n\nconst reportToCli = (type: \"error\" | \"completed\", config?: ReportConfig, error?: Error): void => {\n if (!isTelemetryEnabled()) return;\n fetch(REPORT_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n type,\n version: VERSION,\n config,\n error: error ? { message: error.message, stack: error.stack } : undefined,\n timestamp: new Date().toISOString(),\n }),\n }).catch(() => {});\n};\n\nconst FRAMEWORK_NAMES: Record<Framework, string> = {\n next: \"Next.js\",\n vite: \"Vite\",\n tanstack: \"TanStack Start\",\n webpack: \"Webpack\",\n unknown: \"Unknown\",\n};\n\nconst PACKAGE_MANAGER_NAMES: Record<PackageManager, string> = {\n npm: \"npm\",\n yarn: \"Yarn\",\n pnpm: \"pnpm\",\n bun: \"Bun\",\n};\n\nconst UNSUPPORTED_FRAMEWORK_NAMES: Record<NonNullable<UnsupportedFramework>, string> = {\n remix: \"Remix\",\n astro: \"Astro\",\n sveltekit: \"SvelteKit\",\n gatsby: \"Gatsby\",\n};\n\nconst sortProjectsByFramework = (projects: WorkspaceProject[]): WorkspaceProject[] =>\n [...projects].sort((projectA, projectB) => {\n if (projectA.framework === \"unknown\" && projectB.framework !== \"unknown\") return 1;\n if (projectA.framework !== \"unknown\" && projectB.framework === \"unknown\") return -1;\n return 0;\n });\n\nconst printSubprojects = (searchRoot: string, sortedProjects: WorkspaceProject[]): void => {\n logger.break();\n logger.log(\"Found the following projects:\");\n logger.break();\n for (const project of sortedProjects) {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n const relativePath = relative(searchRoot, project.path);\n logger.log(\n ` ${highlighter.info(project.name)}${frameworkLabel} ${highlighter.dim(relativePath)}`,\n );\n }\n logger.break();\n logger.log(`Re-run with ${highlighter.info(\"-c <path>\")} to specify a project:`);\n logger.break();\n logger.log(\n ` ${highlighter.dim(\"$\")} npx grab@latest init -c ${relative(searchRoot, sortedProjects[0].path)}`,\n );\n logger.break();\n};\n\nconst SUPPORTED_FRAMEWORKS_LINE =\n \"React Grab supports Next.js, Vite, TanStack Start, and Webpack projects.\";\n\nconst failWithManualSetup = (\n failingSpinner: ReturnType<typeof spinner>,\n message: string,\n { listSupportedFrameworks = false } = {},\n): never => {\n failingSpinner.fail(message);\n logger.break();\n if (listSupportedFrameworks) logger.log(SUPPORTED_FRAMEWORKS_LINE);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n};\n\nexport const init = new Command()\n .name(\"init\")\n .alias(\"setup\")\n .description(\"initialize React Grab in your project\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-f, --force\", \"re-run setup checks even when React Grab is already configured\", false)\n .option(\"-k, --key <key>\", \"shortcut (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"--skip-install\", \"skip package installation\", false)\n .option(\"--pkg <pkg>\", \"custom package URL for CLI (e.g., grab)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"install the skill globally instead of in the project\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n if (!existsSync(cwd)) {\n logger.break();\n logger.error(`Directory does not exist: ${highlighter.info(cwd)}`);\n logger.break();\n process.exit(1);\n }\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (projectInfo.isReactGrabConfigured && !opts.force) {\n preflightSpinner.succeed();\n\n if (isNonInteractive) {\n logger.break();\n logger.warn(\"React Grab is already installed.\");\n logger.log(\n `Use ${highlighter.info(\"--force\")} to re-run setup checks, or remove ${highlighter.info(\"--yes\")} for interactive mode.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.success(\"React Grab is already installed.\");\n logger.break();\n\n const { wantCustomizeOptions } = await prompts({\n type: \"confirm\",\n name: \"wantCustomizeOptions\",\n message: `Would you like to customize ${highlighter.info(\"options\")}?`,\n initial: false,\n });\n\n if (wantCustomizeOptions === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantCustomizeOptions || opts.key) {\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n } else {\n const { wantActivationKey } = await prompts({\n type: \"confirm\",\n name: \"wantActivationKey\",\n message: `Configure ${highlighter.info(\"shortcut\")}?`,\n initial: false,\n });\n\n if (wantActivationKey === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantActivationKey) {\n const { key } = await prompts({\n type: \"text\",\n name: \"key\",\n message: \"Enter the shortcut (e.g., g, k, space):\",\n initial: \"\",\n });\n\n if (key === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = key ? key.toLowerCase() : undefined;\n\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n }\n\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n\n if (activationMode === \"hold\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n\n const optionsResult = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!optionsResult.success) {\n logger.break();\n logger.error(optionsResult.message);\n logger.break();\n process.exit(1);\n }\n\n const hasOptionsChanges =\n !optionsResult.noChanges && optionsResult.originalContent && optionsResult.newContent;\n\n if (hasOptionsChanges) {\n logger.break();\n printDiff(\n optionsResult.filePath,\n optionsResult.originalContent!,\n optionsResult.newContent!,\n );\n\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Options configuration cancelled.\");\n } else {\n applyTransformWithFeedback(optionsResult);\n\n logger.break();\n logger.success(\"React Grab options have been configured.\");\n }\n } else {\n logger.break();\n logger.log(\"No option changes needed.\");\n }\n }\n\n logger.break();\n await promptSkillInstall({ yes: isNonInteractive, global: opts.global, cwd });\n\n logger.break();\n process.exit(0);\n }\n\n preflightSpinner.succeed();\n\n const frameworkSpinner = spinner(\"Verifying framework.\").start();\n\n if (projectInfo.unsupportedFramework) {\n const frameworkName = UNSUPPORTED_FRAMEWORK_NAMES[projectInfo.unsupportedFramework];\n frameworkSpinner.fail(`Found ${highlighter.info(frameworkName)}.`);\n logger.break();\n logger.log(`${frameworkName} is not yet supported by automatic setup.`);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n // A detected framework whose entry file is missing is only ambiguous in a\n // monorepo, where the real app lives in a workspace and the root config is\n // tooling. For a standalone project we keep the framework so previewTransform\n // can surface its specific manual-setup guidance instead of searching elsewhere.\n const shouldSearchForProject =\n projectInfo.framework === \"unknown\" ||\n (projectInfo.isMonorepo &&\n !hasFrameworkEntryPoint(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n ));\n\n if (shouldSearchForProject) {\n let searchRoot = cwd;\n let reactProjects = findReactProjects(searchRoot);\n if (reactProjects.length === 0 && cwd !== process.cwd()) {\n searchRoot = process.cwd();\n reactProjects = findReactProjects(searchRoot);\n }\n\n if (reactProjects.length > 0) {\n frameworkSpinner.info(\n `Verifying framework. Found ${reactProjects.length} project${reactProjects.length === 1 ? \"\" : \"s\"}.`,\n );\n\n const sortedProjects = sortProjectsByFramework(reactProjects);\n\n if (isNonInteractive) {\n printSubprojects(searchRoot, sortedProjects);\n process.exit(1);\n }\n\n logger.break();\n const { selectedProject } = await prompts({\n type: \"select\",\n name: \"selectedProject\",\n message: \"Select a project to install React Grab:\",\n choices: [\n ...sortedProjects.map((project) => {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n return {\n title: `${project.name}${frameworkLabel}`,\n value: project.path,\n };\n }),\n { title: \"Skip\", value: \"skip\" },\n ],\n });\n\n if (!selectedProject || selectedProject === \"skip\") {\n logger.break();\n process.exit(0);\n }\n\n process.chdir(selectedProject);\n const newProjectInfo = await detectProject(selectedProject);\n Object.assign(projectInfo, newProjectInfo);\n\n const newFrameworkSpinner = spinner(\"Verifying framework.\").start();\n if (newProjectInfo.framework === \"unknown\") {\n failWithManualSetup(\n newFrameworkSpinner,\n \"Could not detect a supported framework in this project.\",\n { listSupportedFrameworks: true },\n );\n }\n newFrameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[newProjectInfo.framework])}.`,\n );\n } else if (projectInfo.framework !== \"unknown\") {\n failWithManualSetup(\n frameworkSpinner,\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}, but could not find an entry file.`,\n );\n } else {\n failWithManualSetup(frameworkSpinner, \"Could not detect a supported framework.\", {\n listSupportedFrameworks: true,\n });\n }\n } else {\n frameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}.`,\n );\n }\n\n if (projectInfo.framework === \"next\") {\n const routerSpinner = spinner(\"Detecting router type.\").start();\n routerSpinner.succeed(\n `Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === \"app\" ? \"App Router\" : \"Pages Router\")}.`,\n );\n }\n\n const packageManagerSpinner = spinner(\"Detecting package manager.\").start();\n packageManagerSpinner.succeed(\n `Detecting package manager. Found ${highlighter.info(PACKAGE_MANAGER_NAMES[projectInfo.packageManager])}.`,\n );\n\n const finalFramework = projectInfo.framework;\n const finalPackageManager = projectInfo.packageManager;\n const finalNextRouterType = projectInfo.nextRouterType;\n let didInstallSkill = false;\n\n if (!isNonInteractive) {\n logger.break();\n didInstallSkill = await promptSkillInstall({\n yes: isNonInteractive,\n global: opts.global,\n cwd,\n });\n }\n\n const result = previewTransform(\n projectInfo.projectRoot,\n finalFramework,\n finalNextRouterType,\n projectInfo.isReactGrabConfigured,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.error(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n const hasLayoutChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasLayoutChanges) {\n logger.break();\n\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n logger.break();\n logger.warn(\"Auto-detection may not be 100% accurate.\");\n logger.warn(\"Please verify the changes before committing.\");\n\n if (!isNonInteractive) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n }\n\n const shouldInstallReactGrab = !projectInfo.hasReactGrab;\n\n if (!opts.skipInstall && shouldInstallReactGrab) {\n await installPackagesWithFeedback(\n getPackagesToInstall(shouldInstallReactGrab),\n finalPackageManager,\n projectInfo.projectRoot,\n );\n }\n\n if (hasLayoutChanges) {\n applyTransformWithFeedback(result);\n }\n\n logger.break();\n if (hasLayoutChanges) {\n logger.log(`${highlighter.success(\"Success!\")} React Grab has been installed.`);\n } else {\n logger.log(`${highlighter.success(\"Success!\")} ${result.message}.`);\n }\n logger.log(\"You may now start your development server.\");\n logger.break();\n\n reportToCli(\"completed\", {\n framework: finalFramework,\n packageManager: finalPackageManager,\n router: finalNextRouterType,\n agent: didInstallSkill ? \"skill\" : undefined,\n isMonorepo: projectInfo.isMonorepo,\n });\n } catch (error) {\n handleError(error);\n reportToCli(\"error\", undefined, error as Error);\n }\n });\n","export const sleep = (durationMs: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, durationMs));\n","import { spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { sleep } from \"./sleep.js\";\n\nexport const HISTORY_FILE_NAME = \"history.jsonl\";\n\nexport const NO_READER_MESSAGE =\n \"no clipboard reader available. Linux: install xclip or wl-clipboard. macOS: install Xcode CLI tools (swiftc) or rely on pbpaste. Windows: ensure PowerShell is on PATH.\";\n\n// Native readers (read-clipboard.swift / .ps1) are copied next to the compiled\n// CLI at build time (see scripts/copy-native-readers.mjs).\nconst READERS_DIR = path.dirname(fileURLToPath(import.meta.url));\n\nconst READ_TIMEOUT_MS = 2500;\nconst MAX_CLIPBOARD_BYTES = 64 * 1024 * 1024;\nconst ID_RADIX = 36;\nconst HASH_LENGTH = 12;\nconst PICKLE_HEADER_BYTES = 4;\nconst PICKLE_ALIGN_BYTES = 4;\nconst SIGNATURE_SCAN_CHARS = 32 * 1024;\n\nexport const GRAB_MIME = \"application/x-react-grab\";\nconst CHROMIUM_CUSTOM_FORMAT = \"chromium/x-web-custom-data\";\n\n// React Grab plain-text payloads always carry a component-stack frame such as\n// \"in LoginForm (at components/login-form.tsx:46:19)\". Used to recognize a grab\n// when the structured custom clipboard format is unavailable (text fallback).\n// `[^\\n]{1,400}?` allows parentheses in paths (e.g. Next.js route groups\n// `(auth)`) while bounding backtracking on hostile clipboard text.\nconst GRAB_TEXT_SIGNATURE = /\\bin\\s+\\S+\\s+\\(at\\s+[^\\n]{1,400}?:\\d+:\\d+\\)/;\n\ninterface GrabEntry {\n tagName?: string;\n componentName?: string;\n content?: string;\n commentText?: string;\n}\n\ninterface GrabRecord {\n source: \"custom\" | \"text\";\n timestamp: number;\n version?: string;\n content: string;\n entries: GrabEntry[];\n prompt?: string;\n}\n\ninterface CapturedGrab extends GrabRecord {\n id: string;\n receivedAt: number;\n}\n\n// What a platform reader returns each poll. `grab` is the resolved\n// application/x-react-grab JSON string when present.\ninterface ClipboardSnapshot {\n changeCount: number | null;\n text?: string;\n grab?: string;\n}\n\n// What the native helpers (Swift/PowerShell) emit; the watcher resolves `grab`\n// from `grab` directly or by decoding `pickleBase64`.\ninterface NativeRead {\n changeCount?: number | null;\n text?: string;\n grab?: string;\n pickleBase64?: string;\n}\n\ninterface ClipboardReader {\n mode: string;\n read: () => ClipboardSnapshot | null;\n}\n\ninterface LinuxTool {\n name: string;\n readText: () => string | null;\n readCustom: (() => Buffer | null) | null;\n}\n\ninterface CreateReaderOptions {\n textOnly: boolean;\n // Writable directory for the compiled native binary (e.g. macOS `pbread`).\n workDir: string;\n}\n\nconst shortHash = (text: string): string =>\n createHash(\"sha1\").update(text).digest(\"hex\").slice(0, HASH_LENGTH);\n\n// Chromium serializes web custom data as a base::Pickle on every platform, only\n// the clipboard format name differs. Layout (little-endian):\n// [payloadSize u32][pairCount u32] then per pair:\n// [len u32 in UTF-16 code units][utf16le string, padded to 4 bytes] x2 (format, data).\nconst alignUp = (value: number): number =>\n (value + PICKLE_ALIGN_BYTES - 1) & ~(PICKLE_ALIGN_BYTES - 1);\n\nexport const parseChromiumPickle = (buffer: Buffer | null | undefined): Record<string, string> => {\n const formats: Record<string, string> = {};\n if (!buffer || buffer.length < PICKLE_HEADER_BYTES + 4) return formats;\n let offset = PICKLE_HEADER_BYTES;\n const pairCount = buffer.readUInt32LE(offset);\n offset += 4;\n for (let pairIndex = 0; pairIndex < pairCount; pairIndex += 1) {\n if (offset + 4 > buffer.length) break;\n const formatCodeUnits = buffer.readUInt32LE(offset);\n offset += 4;\n if (offset + formatCodeUnits * 2 > buffer.length) break;\n const format = buffer.toString(\"utf16le\", offset, offset + formatCodeUnits * 2);\n offset = alignUp(offset + formatCodeUnits * 2);\n if (offset + 4 > buffer.length) break;\n const dataCodeUnits = buffer.readUInt32LE(offset);\n offset += 4;\n if (offset + dataCodeUnits * 2 > buffer.length) break;\n const value = buffer.toString(\"utf16le\", offset, offset + dataCodeUnits * 2);\n offset = alignUp(offset + dataCodeUnits * 2);\n formats[format] = value;\n }\n return formats;\n};\n\nexport const extractGrab = (raw: NativeRead): string | undefined => {\n if (raw.grab) return raw.grab;\n if (raw.pickleBase64)\n return parseChromiumPickle(Buffer.from(raw.pickleBase64, \"base64\"))[GRAB_MIME];\n return undefined;\n};\n\nexport const isGrabText = (text: string): boolean =>\n GRAB_TEXT_SIGNATURE.test(\n text.length > SIGNATURE_SCAN_CHARS ? text.slice(0, SIGNATURE_SCAN_CHARS) : text,\n );\n\n// A grab can carry the user's own instruction (React Grab prompt mode). It lives\n// in entries[].commentText when structured, otherwise it is prepended above the\n// bracketed element references in `content`. Returns that comment, or undefined.\nexport const extractPrompt = (record: {\n entries?: unknown;\n content?: unknown;\n}): string | undefined => {\n const entries = Array.isArray(record.entries) ? (record.entries as GrabEntry[]) : [];\n const comments = entries.map((entry) => entry?.commentText?.trim?.()).filter(Boolean);\n if (comments.length > 0) return comments.join(\"\\n\");\n const content = typeof record.content === \"string\" ? record.content : \"\";\n const lines = content.split(\"\\n\");\n const firstReferenceLine = lines.findIndex((line) => line.startsWith(\"[\"));\n if (firstReferenceLine <= 0) return undefined;\n return lines.slice(0, firstReferenceLine).join(\"\\n\").trim() || undefined;\n};\n\nconst hasCommand = (name: string): boolean => {\n const probe = process.platform === \"win32\" ? \"where\" : \"which\";\n return spawnSync(probe, [name], { stdio: \"ignore\" }).status === 0;\n};\n\nconst runText = (command: string, args: string[]): string | null => {\n const output = spawnSync(command, args, {\n encoding: \"utf8\",\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n return output.status === 0 ? output.stdout : null;\n};\n\nconst runBuffer = (command: string, args: string[]): Buffer | null => {\n const output = spawnSync(command, args, {\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n return output.status === 0 && output.stdout?.length ? output.stdout : null;\n};\n\nconst runJson = (command: string, args: string[]): NativeRead | null => {\n const output = spawnSync(command, args, {\n encoding: \"utf8\",\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n if (output.status !== 0 || !output.stdout) return null;\n try {\n return JSON.parse(output.stdout) as NativeRead;\n } catch {\n return null;\n }\n};\n\nconst compileSwiftReader = (readersDir: string, workDir: string): string | null => {\n if (!hasCommand(\"swiftc\")) return null;\n const source = path.join(readersDir, \"read-clipboard.swift\");\n if (!fs.existsSync(source)) return null;\n const binary = path.join(workDir, \"pbread\");\n const isStale =\n !fs.existsSync(binary) || fs.statSync(source).mtimeMs > fs.statSync(binary).mtimeMs;\n if (isStale && spawnSync(\"swiftc\", [\"-O\", source, \"-o\", binary]).status !== 0) return null;\n return binary;\n};\n\nconst createDarwinReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const binary = options.textOnly ? null : compileSwiftReader(READERS_DIR, options.workDir);\n if (binary) {\n return {\n mode: \"darwin-native\",\n read: () => {\n const raw = runJson(binary, []);\n if (!raw) return null;\n return { changeCount: raw.changeCount ?? null, text: raw.text, grab: extractGrab(raw) };\n },\n };\n }\n if (!hasCommand(\"pbpaste\")) return null;\n return {\n mode: \"darwin-text\",\n read: () => {\n const text = runText(\"pbpaste\", []);\n return text == null ? null : { changeCount: null, text, grab: undefined };\n },\n };\n};\n\nexport const detectLinuxTool = (): LinuxTool | null => {\n const preferWayland = Boolean(process.env.WAYLAND_DISPLAY) && hasCommand(\"wl-paste\");\n if (preferWayland || (hasCommand(\"wl-paste\") && !hasCommand(\"xclip\"))) {\n return {\n name: \"wl-paste\",\n readText: () =>\n runText(\"wl-paste\", [\"-n\", \"-t\", \"text/plain\"]) ?? runText(\"wl-paste\", [\"-n\"]),\n readCustom: () => runBuffer(\"wl-paste\", [\"-n\", \"-t\", CHROMIUM_CUSTOM_FORMAT]),\n };\n }\n if (hasCommand(\"xclip\")) {\n return {\n name: \"xclip\",\n readText: () => runText(\"xclip\", [\"-selection\", \"clipboard\", \"-o\"]),\n readCustom: () =>\n runBuffer(\"xclip\", [\"-selection\", \"clipboard\", \"-t\", CHROMIUM_CUSTOM_FORMAT, \"-o\"]),\n };\n }\n if (hasCommand(\"xsel\")) {\n return {\n name: \"xsel\",\n readText: () => runText(\"xsel\", [\"--clipboard\", \"--output\"]),\n readCustom: null,\n };\n }\n return null;\n};\n\nconst createLinuxReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const tool = detectLinuxTool();\n if (!tool) return null;\n const useCustom = !options.textOnly && Boolean(tool.readCustom);\n return {\n mode: useCustom ? `linux-${tool.name}` : `linux-${tool.name}-text`,\n read: () => {\n const text = tool.readText();\n if (text == null) return null;\n // No clipboard sequence number on X11/Wayland, so always read the custom\n // blob; its timestamp dedups re-grabs of the identical element.\n const grab =\n useCustom && tool.readCustom\n ? parseChromiumPickle(tool.readCustom())[GRAB_MIME]\n : undefined;\n return { changeCount: null, text, grab };\n },\n };\n};\n\nconst detectPowershell = (): string | null =>\n hasCommand(\"pwsh\") ? \"pwsh\" : hasCommand(\"powershell\") ? \"powershell\" : null;\n\nconst createWindowsReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const shell = detectPowershell();\n if (!shell) return null;\n const scriptPath = path.join(READERS_DIR, \"read-clipboard.ps1\");\n if (options.textOnly || !fs.existsSync(scriptPath)) {\n return {\n mode: \"win-text\",\n read: () => {\n const text = runText(shell, [\"-NoProfile\", \"-Command\", \"Get-Clipboard -Raw\"]);\n return text == null ? null : { changeCount: null, text, grab: undefined };\n },\n };\n }\n const args = [\"-NoProfile\", \"-ExecutionPolicy\", \"Bypass\", \"-File\", scriptPath];\n // Warm the cached C# compile once (untimed) so the first timed poll does not\n // race the first-run compile and kill it.\n spawnSync(shell, args, { stdio: \"ignore\", maxBuffer: MAX_CLIPBOARD_BYTES });\n return {\n mode: \"win-native\",\n read: () => {\n const raw = runJson(shell, args);\n if (!raw) return null;\n return {\n changeCount: raw.changeCount ?? null,\n text: raw.text ?? undefined,\n grab: extractGrab(raw),\n };\n },\n };\n};\n\nexport const createReader = (options: CreateReaderOptions): ClipboardReader | null => {\n if (process.platform === \"darwin\") return createDarwinReader(options);\n if (process.platform === \"linux\") return createLinuxReader(options);\n if (process.platform === \"win32\") return createWindowsReader(options);\n return null;\n};\n\n// On a shared host an attacker could pre-create the work dir (or its log as a\n// symlink) to redirect appends; refuse anything we do not own.\nconst ensureSafeDir = (dir: string): void => {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(dir);\n } catch {\n return;\n }\n if (stats.isSymbolicLink()) throw new Error(`Refusing to use ${dir}: it is a symlink.`);\n if (process.getuid && stats.uid !== process.getuid()) {\n throw new Error(`Refusing to use ${dir}: owned by another user.`);\n }\n};\n\n// Creates the work dir and drops a self-ignoring .gitignore so the captured\n// history never lands in the user's repo.\nexport const prepareWorkDir = (dir: string): void => {\n ensureSafeDir(dir);\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n const gitignore = path.join(dir, \".gitignore\");\n if (!fs.existsSync(gitignore)) fs.writeFileSync(gitignore, \"*\\n\");\n};\n\ninterface RunWatchLoopOptions {\n reader: ClipboardReader;\n dir: string;\n intervalMs: number;\n replayLast: boolean;\n onWarn?: (message: string) => void;\n}\n\n// Baselines the current clipboard first so a grab already sitting there is not\n// replayed (unless replayLast), then appends each newly captured grab forever.\nexport const runWatchLoop = async (options: RunWatchLoopOptions): Promise<void> => {\n const { reader, dir, intervalMs, replayLast, onWarn } = options;\n const logPath = path.join(dir, HISTORY_FILE_NAME);\n const { read } = reader;\n\n let lastChangeCount: number | null = null;\n let lastTimestamp = 0;\n let lastTextHash = \"\";\n let lastErrorMessage = \"\";\n let sequence = 0;\n\n const initial = read();\n if (initial && !replayLast) {\n lastChangeCount = initial.changeCount;\n if (initial.text) lastTextHash = shortHash(initial.text);\n if (initial.grab) {\n try {\n lastTimestamp = (JSON.parse(initial.grab) as { timestamp?: number }).timestamp ?? 0;\n } catch {}\n }\n }\n\n while (true) {\n await sleep(intervalMs);\n // Clipboard payloads are untrusted (any web page can forge one), so a single\n // malformed/hostile grab must never crash the loop. Distinct errors surface\n // via onWarn so a persistent failure is diagnosable rather than silent.\n try {\n const snapshot = read();\n if (!snapshot) continue;\n if (snapshot.changeCount !== null && snapshot.changeCount === lastChangeCount) continue;\n\n const textHash = snapshot.text ? shortHash(snapshot.text) : \"\";\n const didTextChange = textHash !== lastTextHash;\n\n let record: GrabRecord | null = null;\n let nextTimestamp = lastTimestamp;\n if (snapshot.grab) {\n let parsed: {\n timestamp?: number;\n version?: string;\n content?: unknown;\n entries?: unknown;\n } | null = null;\n try {\n parsed = JSON.parse(snapshot.grab);\n } catch {}\n if (parsed && typeof parsed.timestamp === \"number\" && parsed.timestamp > lastTimestamp) {\n nextTimestamp = parsed.timestamp;\n record = {\n source: \"custom\",\n timestamp: parsed.timestamp,\n version: typeof parsed.version === \"string\" ? parsed.version : undefined,\n content: typeof parsed.content === \"string\" ? parsed.content : \"\",\n entries: Array.isArray(parsed.entries) ? (parsed.entries as GrabEntry[]) : [],\n };\n }\n } else if (didTextChange && snapshot.text && isGrabText(snapshot.text)) {\n record = { source: \"text\", timestamp: Date.now(), content: snapshot.text, entries: [] };\n }\n\n if (!record) {\n // The clipboard changed but carried no new grab; advance the dedup\n // state so the same content is not re-scanned every poll.\n lastChangeCount = snapshot.changeCount;\n lastTextHash = textHash;\n continue;\n }\n\n const prompt = extractPrompt(record);\n if (prompt) record.prompt = prompt;\n\n const captured: CapturedGrab = {\n id: `${record.timestamp}-${(sequence += 1).toString(ID_RADIX)}`,\n receivedAt: Date.now(),\n ...record,\n };\n // Commit the dedup state only after the write succeeds; a failed append\n // must leave the grab eligible for retry on the next poll, not lost.\n fs.appendFileSync(logPath, `${JSON.stringify(captured)}\\n`);\n lastChangeCount = snapshot.changeCount;\n lastTextHash = textHash;\n lastTimestamp = nextTimestamp;\n } catch (error) {\n const message = String((error as Error)?.message ?? error);\n if (message !== lastErrorMessage) {\n lastErrorMessage = message;\n onWarn?.(message);\n }\n }\n }\n};\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createReader } from \"./clipboard.js\";\nimport { DAEMON_CLAIM_MAX_ATTEMPTS } from \"./constants.js\";\n\nconst PID_FILE_NAME = \"watch.pid\";\n\nconst pidFilePath = (dir: string): string => path.join(dir, PID_FILE_NAME);\n\nconst cliEntryPath = (): string => process.argv[1] ?? fileURLToPath(import.meta.url);\n\n// Signal 0 only runs the kernel's permission/existence checks without delivering\n// anything: ESRCH means the process is gone, EPERM means it exists under another\n// user (still \"alive\" for dedup purposes).\nconst isProcessAlive = (pid: number): boolean => {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n};\n\nexport const readDaemonPid = (dir: string): number | null => {\n try {\n const pid = Number.parseInt(fs.readFileSync(pidFilePath(dir), \"utf8\").trim(), 10);\n return Number.isInteger(pid) && pid > 0 ? pid : null;\n } catch {\n return null;\n }\n};\n\nexport const isDaemonRunning = (dir: string): boolean => {\n const pid = readDaemonPid(dir);\n return pid !== null && isProcessAlive(pid);\n};\n\n// Atomic `wx` create acts as the per-dir lock; a file left by a crashed daemon is\n// reclaimed. The post-write re-read closes the open->write window where a racing\n// claimant could see a momentarily-empty file and steal it.\nexport const claimDaemon = (dir: string): boolean => {\n const file = pidFilePath(dir);\n for (let attempt = 0; attempt < DAEMON_CLAIM_MAX_ATTEMPTS; attempt += 1) {\n try {\n const handle = fs.openSync(file, \"wx\");\n fs.writeFileSync(handle, String(process.pid));\n fs.closeSync(handle);\n return readDaemonPid(dir) === process.pid;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n if (isDaemonRunning(dir)) return false;\n try {\n fs.rmSync(file, { force: true });\n } catch {}\n }\n }\n return false;\n};\n\n// Removes the pid file only when this process still owns it, so a freshly\n// restarted daemon's file is never clobbered by a predecessor's late cleanup.\nexport const releaseDaemon = (dir: string): void => {\n if (readDaemonPid(dir) === process.pid) {\n try {\n fs.rmSync(pidFilePath(dir), { force: true });\n } catch {}\n }\n};\n\n// Removes the pid file only if it still names the pid we signalled, so a\n// successor that already re-claimed the dir is not clobbered.\nexport const stopDaemon = (dir: string): number | null => {\n const pid = readDaemonPid(dir);\n if (pid === null) return null;\n const wasAlive = isProcessAlive(pid);\n if (wasAlive) {\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {}\n }\n if (readDaemonPid(dir) === pid) {\n try {\n fs.rmSync(pidFilePath(dir), { force: true });\n } catch {}\n }\n return wasAlive ? pid : null;\n};\n\ninterface EnsureDaemonOptions {\n dir: string;\n intervalMs: number;\n textOnly: boolean;\n replayLast: boolean;\n}\n\n// Detached + unref'd so the caller exits immediately while the daemon keeps\n// running. Re-execs the hidden `watch` command, which is the capture-daemon body.\nconst spawnDaemon = (options: EnsureDaemonOptions): void => {\n const args = [\n cliEntryPath(),\n \"watch\",\n \"--dir\",\n options.dir,\n \"--interval\",\n String(options.intervalMs),\n ];\n if (options.textOnly) args.push(\"--text-only\");\n if (options.replayLast) args.push(\"--replay-last\");\n const child = spawn(process.execPath, args, {\n detached: true,\n stdio: \"ignore\",\n windowsHide: true,\n });\n child.unref();\n};\n\nexport type EnsureDaemonResult = \"already-running\" | \"started\" | \"no-reader\";\n\n// Starts the capture daemon if one isn't already watching `dir`. Validates the\n// clipboard reader first: the detached daemon's stderr is discarded, so a missing\n// reader would otherwise fail invisibly.\nexport const ensureDaemon = (options: EnsureDaemonOptions): EnsureDaemonResult => {\n if (isDaemonRunning(options.dir)) return \"already-running\";\n if (!createReader({ textOnly: options.textOnly, workDir: options.dir })) return \"no-reader\";\n spawnDaemon(options);\n return \"started\";\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { HISTORY_FILE_NAME } from \"./clipboard.js\";\nimport { MAX_READ_HISTORY_BYTES, MIGRATION_SCAN_CHUNK_BYTES } from \"./constants.js\";\n\nconst CURSOR_FILE_NAME = \"cursor.txt\";\nconst NEWLINE_BYTE = 0x0a;\n\nconst cursorFilePath = (dir: string): string => path.join(dir, CURSOR_FILE_NAME);\nconst historyFilePath = (dir: string): string => path.join(dir, HISTORY_FILE_NAME);\n\nconst fileSize = (filePath: string): number => {\n try {\n return fs.statSync(filePath).size;\n } catch {\n return 0;\n }\n};\n\nconst readHistoryRange = (dir: string, start: number, length: number): string => {\n if (length <= 0) return \"\";\n const fd = fs.openSync(historyFilePath(dir), \"r\");\n try {\n const buffer = Buffer.allocUnsafe(length);\n const bytesRead = fs.readSync(fd, buffer, 0, length, start);\n return buffer.toString(\"utf8\", 0, bytesRead);\n } finally {\n fs.closeSync(fd);\n }\n};\n\n// temp + rename so a crash mid-write can't leave a truncated cursor. Tagged as\n// JSON so a legacy bare-integer (line-index) cursor is distinguishable on read.\nconst writeGrabCursor = (dir: string, offset: number): void => {\n const target = cursorFilePath(dir);\n const tempPath = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(tempPath, JSON.stringify({ offset }));\n fs.renameSync(tempPath, target);\n};\n\n// Exact byte offset after `lineCount` newlines, scanned in bounded chunks so a\n// huge legacy history neither materializes a >512 MB string nor clamps to a scan\n// window (which would re-deliver or drop records on migration). `\\n` (0x0A) never\n// occurs inside a multi-byte UTF-8 sequence, so counting bytes is correct.\nconst byteOffsetAfterLines = (dir: string, lineCount: number): number => {\n const filePath = historyFilePath(dir);\n const size = fileSize(filePath);\n if (lineCount <= 0 || size === 0) return 0;\n const fd = fs.openSync(filePath, \"r\");\n try {\n const buffer = Buffer.allocUnsafe(MIGRATION_SCAN_CHUNK_BYTES);\n let position = 0;\n let seen = 0;\n while (position < size) {\n const bytesRead = fs.readSync(fd, buffer, 0, MIGRATION_SCAN_CHUNK_BYTES, position);\n if (bytesRead <= 0) break;\n for (let index = 0; index < bytesRead; index += 1) {\n if (buffer[index] !== NEWLINE_BYTE) continue;\n seen += 1;\n if (seen === lineCount) return position + index + 1;\n }\n position += bytesRead;\n }\n } finally {\n fs.closeSync(fd);\n }\n // Fewer than lineCount complete lines exist; the legacy cursor consumed all of them.\n return size;\n};\n\n// Byte offset into history.jsonl (not a line index), so an idle poll can tell\n// \"nothing new\" from the file size without reading.\nexport const readGrabCursor = (dir: string): number => {\n let raw: string;\n try {\n raw = fs.readFileSync(cursorFilePath(dir), \"utf8\").trim();\n } catch {\n return 0;\n }\n if (raw === \"\") return 0;\n let parsed: { offset?: unknown } | number;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return 0;\n }\n if (typeof parsed === \"number\") {\n // A bare integer is a legacy line-index cursor from before byte offsets.\n // Convert it to the byte position after that many lines (and persist) so\n // already-consumed grabs are not re-delivered after an upgrade.\n if (!Number.isInteger(parsed) || parsed < 0) return 0;\n const offset = byteOffsetAfterLines(dir, parsed);\n writeGrabCursor(dir, offset);\n return offset;\n }\n return typeof parsed.offset === \"number\" && Number.isInteger(parsed.offset) && parsed.offset >= 0\n ? parsed.offset\n : 0;\n};\n\nexport const readCompleteGrabLines = (dir: string): string[] => {\n const size = fileSize(historyFilePath(dir));\n if (size === 0) return [];\n const raw = readHistoryRange(dir, 0, size);\n const lastNewline = raw.lastIndexOf(\"\\n\");\n if (lastNewline < 0) return [];\n return raw.slice(0, lastNewline).split(\"\\n\").filter(Boolean);\n};\n\ninterface ConsumeGrabsOptions {\n limit: number;\n all: boolean;\n maxAgeMs: number;\n}\n\nexport const consumeGrabs = (dir: string, options: ConsumeGrabsOptions): string[] => {\n if (options.all) return readCompleteGrabLines(dir);\n\n const size = fileSize(historyFilePath(dir));\n const cursor = readGrabCursor(dir);\n // A cursor past EOF means the history was truncated/rotated under us; restart.\n const start = cursor > size ? 0 : cursor;\n if (start >= size) {\n // Persist the reset, or a later-grown file would be read from the stale offset.\n if (start !== cursor) writeGrabCursor(dir, start);\n return [];\n }\n\n const chunk = readHistoryRange(dir, start, Math.min(size - start, MAX_READ_HISTORY_BYTES));\n const lastNewline = chunk.lastIndexOf(\"\\n\");\n if (lastNewline < 0) return [];\n\n const now = Date.now();\n const fresh: string[] = [];\n let consumedBytes = 0;\n let lineStart = 0;\n while (lineStart <= lastNewline && (options.limit <= 0 || fresh.length < options.limit)) {\n const newlineIndex = chunk.indexOf(\"\\n\", lineStart);\n const line = chunk.slice(lineStart, newlineIndex);\n consumedBytes += Buffer.byteLength(chunk.slice(lineStart, newlineIndex + 1), \"utf8\");\n lineStart = newlineIndex + 1;\n if (line.length === 0) continue;\n let parsed: { receivedAt?: unknown };\n try {\n parsed = JSON.parse(line);\n } catch {\n // Corrupt or partial line; skip it (the cursor still advances past it).\n continue;\n }\n if (options.maxAgeMs > 0 && typeof parsed.receivedAt === \"number\") {\n if (now - parsed.receivedAt > options.maxAgeMs) continue;\n }\n fresh.push(line);\n }\n\n const nextCursor = start + consumedBytes;\n if (nextCursor !== cursor) writeGrabCursor(dir, nextCursor);\n return fresh;\n};\n","export const parseWaitMs = (raw: string | undefined): number | null => {\n if (raw === undefined) return 0;\n const trimmed = raw.trim();\n if (trimmed === \"\") return 0;\n if (/^(inf|infinite|infinity|forever)$/i.test(trimmed)) return Number.POSITIVE_INFINITY;\n const ms = Number(trimmed);\n return Number.isFinite(ms) && ms >= 0 ? ms : null;\n};\n\nexport const parseNonNegativeInt = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const trimmed = raw.trim();\n // Number(\"\") and Number(\" \") are 0, which would mask empty/garbage input.\n if (trimmed === \"\") return null;\n const value = Number(trimmed);\n return Number.isInteger(value) && value >= 0 ? value : null;\n};\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { NO_READER_MESSAGE, prepareWorkDir } from \"../utils/clipboard.js\";\nimport {\n DEFAULT_GRAB_AGE_MS,\n DEFAULT_WATCH_DIR,\n DEFAULT_WATCH_INTERVAL_MS,\n READ_DEFAULT_LIMIT,\n READ_WAIT_POLL_MS,\n} from \"../utils/constants.js\";\nimport { ensureDaemon } from \"../utils/daemon.js\";\nimport { consumeGrabs } from \"../utils/grab-log.js\";\nimport { parseNonNegativeInt, parseWaitMs } from \"../utils/read-args.js\";\nimport { sleep } from \"../utils/sleep.js\";\nimport { unrefStdin } from \"../utils/unref-stdin.js\";\n\ninterface PullOptions {\n dir: string;\n wait: string;\n limit: string;\n maxAge: string;\n textOnly?: boolean;\n all?: boolean;\n}\n\nconst fail = (message: string): never => {\n process.stderr.write(`react-grab pull: ${message}\\n`);\n process.exit(1);\n};\n\n// Exit only after the write flushes; process.exit() mid-write can truncate a pipe.\nconst emitAndExit = (lines: string[]): void => {\n process.stdout.write(`${lines.join(\"\\n\")}\\n`, () => process.exit(0));\n};\n\nexport const pull = new Command()\n .name(\"pull\")\n .description(\"start the watcher if needed, then wait for and print the next React Grab grab(s)\")\n .option(\"-d, --dir <dir>\", \"work dir for history.jsonl + watch.pid\", DEFAULT_WATCH_DIR)\n .option(\n \"-w, --wait <ms>\",\n \"how long to wait for a grab: ms, 'infinite', or 0 for none\",\n \"infinite\",\n )\n .option(\n \"-n, --limit <count>\",\n \"max grabs to print per call (0 = no limit)\",\n String(READ_DEFAULT_LIMIT),\n )\n .option(\n \"--max-age <ms>\",\n \"skip grabs captured longer ago than <ms> (0 = never)\",\n String(DEFAULT_GRAB_AGE_MS),\n )\n .option(\n \"--text-only\",\n \"watcher uses the plain-text clipboard reader (ignored if already running)\",\n )\n .option(\"--all\", \"print the whole history without advancing the cursor\")\n .action(async (options: PullOptions) => {\n const dir = path.resolve(options.dir);\n\n try {\n prepareWorkDir(dir);\n } catch (error) {\n fail(String((error as Error)?.message ?? error));\n }\n\n const waitMs = parseWaitMs(options.wait);\n if (waitMs === null) fail(`invalid --wait \"${options.wait}\" (use milliseconds or \"infinite\")`);\n const limit = parseNonNegativeInt(options.limit);\n if (limit === null) fail(`invalid --limit \"${options.limit}\" (use a non-negative integer)`);\n const maxAgeMs = parseNonNegativeInt(options.maxAge);\n if (maxAgeMs === null)\n fail(`invalid --max-age \"${options.maxAge}\" (use milliseconds, 0 to disable)`);\n\n const all = Boolean(options.all);\n const textOnly = Boolean(options.textOnly);\n\n if (\n ensureDaemon({ dir, intervalMs: DEFAULT_WATCH_INTERVAL_MS, textOnly, replayLast: false }) ===\n \"no-reader\"\n ) {\n fail(NO_READER_MESSAGE);\n }\n\n unrefStdin();\n const consume = (): string[] => consumeGrabs(dir, { limit, all, maxAgeMs });\n\n const first = consume();\n if (first.length > 0) {\n emitAndExit(first);\n return;\n }\n\n const deadline = Date.now() + waitMs;\n while (Date.now() < deadline) {\n await sleep(READ_WAIT_POLL_MS);\n const batch = consume();\n if (batch.length > 0) {\n emitAndExit(batch);\n return;\n }\n }\n process.exit(0);\n });\n","import { resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { agentLabel, removeSkill } from \"../utils/install-skill.js\";\nimport { logger } from \"../utils/logger.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const remove = new Command()\n .name(\"remove\")\n .description(\"uninstall the React Grab skill from your agent\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"remove the globally-installed skill instead of the project's\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n logger.break();\n const removedAgents = await removeSkill({ cwd: resolve(opts.cwd), global: opts.global });\n for (const agent of removedAgents) {\n logger.log(` ${highlighter.success(\"\\u2713\")} ${agentLabel(agent)}`);\n }\n\n logger.break();\n if (removedAgents.length === 0) {\n logger.log(\"React Grab skill is not installed in any detected agent.\");\n } else {\n logger.log(\n `${highlighter.success(\"Removed\")} the React Grab skill from ${removedAgents.length} agent${removedAgents.length === 1 ? \"\" : \"s\"}.`,\n );\n }\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { DEFAULT_WATCH_DIR } from \"../utils/constants.js\";\nimport { stopDaemon } from \"../utils/daemon.js\";\n\nexport const stop = new Command()\n .name(\"stop\")\n .description(\"stop the React Grab watcher for this dir\")\n .option(\"-d, --dir <dir>\", \"work dir holding watch.pid\", DEFAULT_WATCH_DIR)\n .action((options: { dir: string }) => {\n const dir = path.resolve(options.dir);\n const stoppedPid = stopDaemon(dir);\n process.stderr.write(\n stoppedPid\n ? `react-grab stop: stopped watcher (pid ${stoppedPid})\\n`\n : `react-grab stop: no watcher running for ${dir}\\n`,\n );\n process.exit(0);\n });\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installPackages } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/react-grab/latest\";\n\ninterface NpmPackageInfo {\n version: string;\n}\n\nconst fetchLatestVersion = async (): Promise<string | null> => {\n try {\n const response = await fetch(NPM_REGISTRY_URL);\n const data: NpmPackageInfo = await response.json();\n return data.version ?? null;\n } catch {\n return null;\n }\n};\n\nconst isDevDependency = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return true;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.devDependencies?.[\"react-grab\"]) return true;\n if (packageJson.dependencies?.[\"react-grab\"]) return false;\n } catch {}\n return true;\n};\n\nexport const upgrade = new Command()\n .name(\"upgrade\")\n .alias(\"update\")\n .description(\"upgrade react-grab to the latest version\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n\n const detectSpinner = spinner(\"Detecting project.\").start();\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n detectSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"npx grab@latest init\")} first to install React Grab.`,\n );\n logger.break();\n process.exit(1);\n }\n\n detectSpinner.succeed();\n\n const versionSpinner = spinner(\"Checking for updates.\").start();\n const latestVersion = await fetchLatestVersion();\n\n if (!latestVersion) {\n versionSpinner.fail(\"Could not check for updates.\");\n logger.break();\n logger.error(\"Failed to reach the npm registry. Check your network connection.\");\n logger.break();\n process.exit(1);\n }\n\n const installedVersion = projectInfo.reactGrabVersion;\n\n if (installedVersion && installedVersion === latestVersion) {\n versionSpinner.succeed(\n `Already on the latest version ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n process.exit(0);\n }\n\n const fromLabel = installedVersion ? `v${installedVersion}` : \"unknown\";\n versionSpinner.succeed(\n `Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`,\n );\n\n const upgradeSpinner = spinner(\"Upgrading react-grab.\").start();\n\n try {\n await installPackages([\"react-grab@latest\"], {\n packageManager: projectInfo.packageManager,\n cwd: projectInfo.projectRoot,\n isDev: isDevDependency(projectInfo.projectRoot),\n });\n upgradeSpinner.succeed();\n } catch {\n upgradeSpinner.fail();\n logger.break();\n logger.error(\"Failed to upgrade. Check your network connection and try again.\");\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n logger.log(\n `${highlighter.success(\"Success!\")} React Grab has been upgraded to ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n HISTORY_FILE_NAME,\n NO_READER_MESSAGE,\n createReader,\n prepareWorkDir,\n runWatchLoop,\n} from \"../utils/clipboard.js\";\nimport { DEFAULT_WATCH_DIR, DEFAULT_WATCH_INTERVAL_MS } from \"../utils/constants.js\";\nimport { claimDaemon, releaseDaemon } from \"../utils/daemon.js\";\n\ninterface WatchOptions {\n dir: string;\n interval: string;\n textOnly?: boolean;\n replayLast?: boolean;\n}\n\nconst writeStatus = (message: string): void => {\n process.stderr.write(`react-grab watch: ${message}\\n`);\n};\n\n// The capture-daemon body that `pull` re-execs detached. Claims the per-dir lock\n// (exits quietly if another daemon already owns it), then polls the clipboard\n// into history.jsonl until the process is killed.\nexport const watch = new Command()\n .name(\"watch\")\n .description(\"run the React Grab capture daemon in the foreground (used internally by `pull`)\")\n .option(\"-d, --dir <dir>\", \"work dir for history.jsonl + watch.pid\", DEFAULT_WATCH_DIR)\n .option(\"-i, --interval <ms>\", \"clipboard poll interval in ms\", String(DEFAULT_WATCH_INTERVAL_MS))\n .option(\"--text-only\", \"skip the native reader and use the plain-text fallback\")\n .option(\"--replay-last\", \"also capture the grab already on the clipboard at startup\")\n .action((options: WatchOptions) => {\n const dir = path.resolve(options.dir);\n const intervalRaw = Number(options.interval);\n const intervalMs =\n Number.isFinite(intervalRaw) && intervalRaw > 0 ? intervalRaw : DEFAULT_WATCH_INTERVAL_MS;\n\n try {\n prepareWorkDir(dir);\n } catch (error) {\n writeStatus(String((error as Error)?.message ?? error));\n process.exit(1);\n }\n\n if (!claimDaemon(dir)) process.exit(0);\n process.on(\"exit\", () => releaseDaemon(dir));\n\n const reader = createReader({ textOnly: Boolean(options.textOnly), workDir: dir });\n if (!reader) {\n writeStatus(NO_READER_MESSAGE);\n process.exit(1);\n }\n\n writeStatus(\n `watching clipboard via ${reader.mode}; history → ${path.join(dir, HISTORY_FILE_NAME)}`,\n );\n\n runWatchLoop({\n reader,\n dir,\n intervalMs,\n replayLast: Boolean(options.replayLast),\n onWarn: writeStatus,\n }).catch((error) => {\n writeStatus(String((error as Error)?.message ?? error));\n process.exit(1);\n });\n });\n","import { Command } from \"commander\";\nimport { add } from \"./commands/add.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { init } from \"./commands/init.js\";\nimport { pull } from \"./commands/pull.js\";\nimport { remove } from \"./commands/remove.js\";\nimport { stop } from \"./commands/stop.js\";\nimport { upgrade } from \"./commands/upgrade.js\";\nimport { watch } from \"./commands/watch.js\";\nimport { isTelemetryEnabled } from \"./utils/is-telemetry-enabled.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst VERSION_API_URL = \"https://www.react-grab.com/api/version\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\ntry {\n if (isTelemetryEnabled()) {\n fetch(`${VERSION_API_URL}?source=cli&v=${VERSION}&t=${Date.now()}`).catch(() => {});\n }\n} catch {}\n\nconst program = new Command()\n .name(\"grab\")\n .description(\"add React Grab to your project\")\n .version(VERSION, \"-v, --version\", \"display the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(remove);\nprogram.addCommand(configure);\nprogram.addCommand(upgrade);\nprogram.addCommand(pull);\nprogram.addCommand(stop);\nprogram.addCommand(watch, { hidden: true });\n\nconst main = async () => {\n await program.parseAsync();\n};\n\nmain();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["VERSION","VERSION","VERSION","VERSION","VERSION"],"sources":["../src/utils/is-non-interactive.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/handle-error.ts","../src/utils/unref-stdin.ts","../src/utils/prompts.ts","../src/utils/spinner.ts","../src/utils/prompt-skill-install.ts","../src/commands/add.ts","../src/utils/diff.ts","../src/utils/cli-helpers.ts","../src/utils/constants.ts","../src/utils/format-activation-key.ts","../src/commands/configure.ts","../src/utils/is-telemetry-enabled.ts","../src/commands/init.ts","../src/utils/sleep.ts","../src/utils/clipboard.ts","../src/utils/daemon.ts","../src/utils/grab-log.ts","../src/utils/read-args.ts","../src/commands/pull.ts","../src/commands/remove.ts","../src/commands/stop.ts","../src/commands/upgrade.ts","../src/commands/watch.ts","../src/cli.ts"],"sourcesContent":["const AGENT_ENVIRONMENT_VARIABLES = [\n \"CI\",\n \"CLAUDECODE\",\n \"CURSOR_AGENT\",\n \"CODEX_CI\",\n \"OPENCODE\",\n \"AMP_HOME\",\n \"AMI\",\n] as const;\n\nconst isEnvironmentVariableSet = (variable: string): boolean => Boolean(process.env[variable]);\n\nexport const detectNonInteractive = (yesFlag: boolean): boolean =>\n yesFlag || AGENT_ENVIRONMENT_VARIABLES.some(isEnvironmentVariableSet) || !process.stdin.isTTY;\n","import pc from \"picocolors\";\n\nexport const highlighter = {\n error: pc.red,\n warn: pc.yellow,\n info: pc.cyan,\n success: pc.green,\n dim: pc.dim,\n};\n","import { highlighter } from \"./highlighter.js\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import { logger } from \"./logger.js\";\n\nexport const handleError = (error: unknown) => {\n logger.break();\n logger.error(\"Something went wrong. Please check the error below for more details.\");\n logger.error(\"If the problem persists, please open an issue on GitHub.\");\n logger.error(\"\");\n if (error instanceof Error) {\n logger.error(error.message);\n }\n logger.break();\n process.exit(1);\n};\n","// HACK: this is a one-shot CLI, but when stdin (fd 0) is an inherited pipe or\n// socket Node keeps the event loop alive for as long as that handle is open —\n// even though the only thing that ever reads stdin is an interactive prompt.\n// When the CLI is spawned by a parent that holds the stdin write-end open (eval\n// runners, CI harnesses, editor integrations), the command finishes yet the\n// process never exits: the inherited `Socket fd=0` refs the loop. Unref-ing fd\n// 0 makes an idle pipe/socket incapable of holding the process open.\n//\n// We MUST NOT unref an interactive TTY. A real terminal is the only case that\n// shows prompts, and `prompts` never re-refs an unref'd stdin handle: its base\n// element does `readline.createInterface(...)` + `setRawMode(true)` but never\n// `resume()`, none of which re-ref the libuv handle. Unref-ing a TTY would let\n// the event loop drain while a prompt is still waiting for input — the CLI\n// would render the prompt and then exit by itself before the user can answer.\n// Guarding on `isTTY` keeps the one-shot exit fix without breaking prompts.\nexport const unrefStdin = (): void => {\n if (process.stdin.isTTY) return;\n process.stdin.unref?.();\n};\n","import basePrompts, { type PromptObject, type Answers } from \"prompts\";\nimport { logger } from \"./logger.js\";\nimport { unrefStdin } from \"./unref-stdin.js\";\n\nconst onCancel = () => {\n logger.break();\n logger.log(\"Cancelled.\");\n logger.break();\n process.exit(0);\n};\n\nexport const prompts = <T extends string = string>(\n questions: PromptObject<T> | PromptObject<T>[],\n): Promise<Answers<T>> => {\n // HACK: each prompt re-refs stdin and never unrefs it on close, so re-unref\n // once it settles or the one-shot CLI hangs. See `unref-stdin.ts` for why.\n return basePrompts(questions, { onCancel }).finally(unrefStdin);\n};\n","import ora from \"ora\";\n\nexport const spinner = (text: string) => ora({ text });\n","import { detectAvailableAgents } from \"./detect-agents.js\";\nimport { highlighter } from \"./highlighter.js\";\nimport { agentLabel, installSkill } from \"./install-skill.js\";\nimport { logger } from \"./logger.js\";\nimport { prompts } from \"./prompts.js\";\nimport { spinner } from \"./spinner.js\";\n\ninterface PromptSkillInstallOptions {\n yes?: boolean;\n global?: boolean;\n cwd?: string;\n}\n\nexport const promptSkillInstall = async ({\n yes = false,\n global = false,\n cwd = process.cwd(),\n}: PromptSkillInstallOptions = {}): Promise<boolean> => {\n const detectedAgents = await detectAvailableAgents();\n if (detectedAgents.length === 0) {\n logger.warn(\"No supported agents detected.\");\n return false;\n }\n\n let selectedAgents = detectedAgents;\n if (!yes) {\n const { confirmed } = await prompts({\n type: \"confirm\",\n name: \"confirmed\",\n message: `Install the React Grab skill (${global ? \"global\" : \"this project\"})?`,\n initial: true,\n });\n if (!confirmed) return false;\n\n const { agents } = await prompts({\n type: \"multiselect\",\n name: \"agents\",\n message: `Install the React Grab skill (${global ? \"global\" : \"this project\"}) for:`,\n choices: detectedAgents.map((agent) => ({\n title: agentLabel(agent),\n value: agent,\n selected: true,\n })),\n instructions: false,\n min: 1,\n });\n selectedAgents = agents ?? [];\n if (selectedAgents.length === 0) return false;\n }\n\n const installSpinner = spinner(\"Installing React Grab skill.\").start();\n const { installed, failed } = await installSkill({ agents: selectedAgents, global, cwd });\n\n if (installed.length === 0) {\n installSpinner.fail(\"Failed to install React Grab skill.\");\n return false;\n }\n installSpinner.succeed(\n `Installed React Grab skill for ${installed.map((record) => agentLabel(record.agent)).join(\", \")}.`,\n );\n for (const record of failed) {\n logger.log(` ${highlighter.error(\"\\u2717\")} ${agentLabel(record.agent)} ${record.error}`);\n }\n return true;\n};\n","import { resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { promptSkillInstall } from \"../utils/prompt-skill-install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const add = new Command()\n .name(\"add\")\n .alias(\"install\")\n .description(\"install the React Grab skill for your agent\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"install the skill globally instead of in the project\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n const projectInfo = await detectProject(opts.cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n logger.break();\n\n const didInstall = await promptSkillInstall({\n yes: isNonInteractive,\n global: opts.global,\n cwd: resolve(opts.cwd),\n });\n // In non-interactive mode a falsy result is a real failure (no agents or\n // install error), not a user declining the prompt — surface it to CI.\n if (!didInstall && isNonInteractive) {\n logger.break();\n process.exit(1);\n }\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","interface DiffLine {\n type: \"added\" | \"removed\" | \"unchanged\";\n content: string;\n lineNumber?: number;\n}\n\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst GRAY = \"\\x1b[90m\";\nconst RESET = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\n\nexport const generateDiff = (originalContent: string, newContent: string): DiffLine[] => {\n const originalLines = originalContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const diff: DiffLine[] = [];\n\n let originalIndex = 0;\n let newIndex = 0;\n\n while (originalIndex < originalLines.length || newIndex < newLines.length) {\n const originalLine = originalLines[originalIndex];\n const newLine = newLines[newIndex];\n\n if (originalLine === newLine) {\n diff.push({\n type: \"unchanged\",\n content: originalLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n } else if (originalLine === undefined) {\n diff.push({ type: \"added\", content: newLine, lineNumber: newIndex + 1 });\n newIndex++;\n } else if (newLine === undefined) {\n diff.push({ type: \"removed\", content: originalLine });\n originalIndex++;\n } else {\n const originalInNew = newLines.indexOf(originalLine, newIndex);\n const newInOriginal = originalLines.indexOf(newLine, originalIndex);\n\n if (\n originalInNew !== -1 &&\n (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)\n ) {\n while (newIndex < originalInNew) {\n diff.push({\n type: \"added\",\n content: newLines[newIndex],\n lineNumber: newIndex + 1,\n });\n newIndex++;\n }\n } else if (newInOriginal !== -1) {\n while (originalIndex < newInOriginal) {\n diff.push({ type: \"removed\", content: originalLines[originalIndex] });\n originalIndex++;\n }\n } else {\n diff.push({ type: \"removed\", content: originalLine });\n diff.push({\n type: \"added\",\n content: newLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n }\n }\n }\n\n return diff;\n};\n\nexport const formatDiff = (diff: DiffLine[], contextLines: number = 3): string => {\n const lines: string[] = [];\n let lastPrintedIndex = -1;\n let hasChanges = false;\n\n const changedIndices = diff\n .map((line, index) => (line.type !== \"unchanged\" ? index : -1))\n .filter((index) => index !== -1);\n\n if (changedIndices.length === 0) {\n return `${GRAY}No changes${RESET}`;\n }\n\n for (const changedIndex of changedIndices) {\n const startContext = Math.max(0, changedIndex - contextLines);\n const endContext = Math.min(diff.length - 1, changedIndex + contextLines);\n\n if (startContext > lastPrintedIndex + 1 && lastPrintedIndex !== -1) {\n lines.push(`${GRAY} ...${RESET}`);\n }\n\n for (\n let lineIndex = Math.max(startContext, lastPrintedIndex + 1);\n lineIndex <= endContext;\n lineIndex++\n ) {\n const diffLine = diff[lineIndex];\n\n if (diffLine.type === \"added\") {\n lines.push(`${GREEN}+ ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else if (diffLine.type === \"removed\") {\n lines.push(`${RED}- ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else {\n lines.push(`${GRAY} ${diffLine.content}${RESET}`);\n }\n\n lastPrintedIndex = lineIndex;\n }\n }\n\n return hasChanges ? lines.join(\"\\n\") : `${GRAY}No changes${RESET}`;\n};\n\nexport const printDiff = (filePath: string, originalContent: string, newContent: string): void => {\n console.log(`\\n${BOLD}File: ${filePath}${RESET}`);\n console.log(\"─\".repeat(60));\n\n const diff = generateDiff(originalContent, newContent);\n console.log(formatDiff(diff));\n\n console.log(\"─\".repeat(60));\n};\n","import type { PackageManager } from \"./detect.js\";\nimport { applyTransform, type TransformResult } from \"./transform.js\";\nimport { handleError } from \"./handle-error.js\";\nimport { installPackages } from \"./install.js\";\nimport { logger } from \"./logger.js\";\nimport { spinner } from \"./spinner.js\";\n\nexport const applyTransformWithFeedback = (result: TransformResult, message?: string): void => {\n const writeSpinner = spinner(message ?? `Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n};\n\nexport const installPackagesWithFeedback = async (\n packages: string[],\n packageManager: PackageManager,\n projectRoot: string,\n): Promise<void> => {\n if (packages.length === 0) return;\n const installSpinner = spinner(`Installing ${packages.join(\", \")}.`).start();\n try {\n await installPackages(packages, { packageManager, cwd: projectRoot });\n installSpinner.succeed();\n } catch (error) {\n installSpinner.fail();\n handleError(error);\n }\n};\n","export const MAX_SUGGESTIONS_COUNT = 30;\nexport const MAX_KEY_HOLD_DURATION_MS = 2000;\nexport const MAX_CONTEXT_LINES = 50;\n\nexport const DEFAULT_WATCH_DIR = \".react-grab\";\nexport const DEFAULT_WATCH_INTERVAL_MS = 800;\nexport const READ_WAIT_POLL_MS = 200;\nexport const DAEMON_CLAIM_MAX_ATTEMPTS = 50;\nexport const READ_DEFAULT_LIMIT = 50;\nexport const DEFAULT_GRAB_AGE_MS = 5 * 60 * 1000;\n// A single read must never build a >512 MB string (V8's cap); a bigger backlog\n// drains across calls. Must exceed the largest single grab line.\nexport const MAX_READ_HISTORY_BYTES = 128 * 1024 * 1024;\n\n// Buffer size for the legacy-cursor migration's chunked newline scan, which\n// counts newline bytes without materializing the whole history as a string.\nexport const MIGRATION_SCAN_CHUNK_BYTES = 1024 * 1024;\n","import type { ReactGrabOptions } from \"./transform.js\";\n\nexport const formatActivationKeyDisplay = (\n activationKey: ReactGrabOptions[\"activationKey\"],\n): string => {\n const defaultLabel = process.platform === \"darwin\" ? \"Option\" : \"Alt\";\n if (!activationKey) return `Default (${defaultLabel})`;\n return activationKey\n .split(\"+\")\n .map((part) => {\n const lower = part.toLowerCase();\n if (lower === \"meta\") return process.platform === \"darwin\" ? \"⌘\" : \"Win\";\n if (lower === \"alt\") return process.platform === \"darwin\" ? \"⌥\" : \"Alt\";\n if (lower === \"ctrl\") return \"Ctrl\";\n if (lower === \"shift\") return \"Shift\";\n if (lower === \"space\" || lower === \" \") return \"Space\";\n return part.toUpperCase();\n })\n .join(\" + \");\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n previewCdnTransform,\n previewOptionsTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport { applyTransformWithFeedback } from \"../utils/cli-helpers.js\";\nimport {\n MAX_SUGGESTIONS_COUNT,\n MAX_KEY_HOLD_DURATION_MS,\n MAX_CONTEXT_LINES,\n} from \"../utils/constants.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\ninterface ConfigOption {\n id: string;\n title: string;\n description: string;\n}\n\nconst isMac = process.platform === \"darwin\";\nconst META_LABEL = isMac ? \"Cmd\" : \"Win\";\nconst ALT_LABEL = isMac ? \"Option\" : \"Alt\";\n\nconst MODIFIER_ALIASES: Record<string, string> = {\n cmd: \"meta\",\n command: \"meta\",\n win: \"meta\",\n windows: \"meta\",\n meta: \"meta\",\n ctrl: \"ctrl\",\n control: \"ctrl\",\n shift: \"shift\",\n alt: \"alt\",\n option: \"alt\",\n opt: \"alt\",\n};\n\nconst MODIFIERS = [\"meta\", \"ctrl\", \"shift\", \"alt\"] as const;\n\nconst BASE_KEYS: Array<{ key: string; aliases: string[] }> = [\n { key: \" \", aliases: [\"space\", \"spacebar\"] },\n { key: \"Enter\", aliases: [\"enter\", \"return\"] },\n { key: \"Escape\", aliases: [\"escape\", \"esc\"] },\n { key: \"Tab\", aliases: [\"tab\"] },\n { key: \"Backspace\", aliases: [\"backspace\", \"back\"] },\n { key: \"Delete\", aliases: [\"delete\", \"del\"] },\n { key: \"Insert\", aliases: [\"insert\", \"ins\"] },\n { key: \"Home\", aliases: [\"home\"] },\n { key: \"End\", aliases: [\"end\"] },\n { key: \"PageUp\", aliases: [\"pageup\", \"pgup\"] },\n { key: \"PageDown\", aliases: [\"pagedown\", \"pgdn\", \"pgdown\"] },\n { key: \"ArrowUp\", aliases: [\"arrowup\", \"up\"] },\n { key: \"ArrowDown\", aliases: [\"arrowdown\", \"down\"] },\n { key: \"ArrowLeft\", aliases: [\"arrowleft\", \"left\"] },\n { key: \"ArrowRight\", aliases: [\"arrowright\", \"right\"] },\n ...Array.from({ length: 12 }, (_, i) => ({\n key: `F${i + 1}`,\n aliases: [`f${i + 1}`],\n })),\n ...Array.from({ length: 26 }, (_, i) => {\n const letter = String.fromCharCode(97 + i);\n return { key: letter, aliases: [letter] };\n }),\n ...Array.from({ length: 10 }, (_, i) => ({\n key: String(i),\n aliases: [String(i)],\n })),\n { key: \"`\", aliases: [\"backtick\", \"grave\", \"`\"] },\n { key: \"-\", aliases: [\"minus\", \"dash\", \"-\"] },\n { key: \"=\", aliases: [\"equals\", \"equal\", \"=\"] },\n { key: \"[\", aliases: [\"leftbracket\", \"lbracket\", \"[\"] },\n { key: \"]\", aliases: [\"rightbracket\", \"rbracket\", \"]\"] },\n { key: \"\\\\\", aliases: [\"backslash\", \"\\\\\"] },\n { key: \";\", aliases: [\"semicolon\", \";\"] },\n { key: \"'\", aliases: [\"quote\", \"apostrophe\", \"'\"] },\n { key: \",\", aliases: [\"comma\", \",\"] },\n { key: \".\", aliases: [\"period\", \"dot\", \".\"] },\n { key: \"/\", aliases: [\"slash\", \"forwardslash\", \"/\"] },\n];\n\ninterface KeyCombo {\n key: string;\n metaKey?: boolean;\n ctrlKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n}\n\ninterface KeyChoice {\n title: string;\n value: KeyCombo;\n}\n\nconst formatCombo = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(META_LABEL);\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(ALT_LABEL);\n const keyDisplay =\n combo.key === \" \" ? \"Space\" : combo.key.length === 1 ? combo.key.toUpperCase() : combo.key;\n parts.push(keyDisplay);\n return parts.join(\"+\");\n};\n\nconst parseInput = (input: string): { modifiers: Set<string>; partial: string } => {\n const normalized = input.toLowerCase().replace(/\\s+/g, \"\");\n const parts = normalized.split(/[+-]/);\n const modifiers = new Set<string>();\n let partial = \"\";\n\n for (const part of parts) {\n if (!part) continue;\n const modifierKey = MODIFIER_ALIASES[part];\n if (modifierKey) {\n modifiers.add(modifierKey);\n } else {\n partial = part;\n }\n }\n\n return { modifiers, partial };\n};\n\nconst POPULAR_KEYS = [\"g\", \"k\", \"e\", \"d\", \"b\", \" \", \"Escape\", \"Enter\"];\n\nconst generateSuggestions = (input: string): KeyChoice[] => {\n const { modifiers, partial } = parseInput(input);\n const suggestions: KeyChoice[] = [];\n\n if (!partial && modifiers.size === 0 && !input) {\n for (const mod of MODIFIERS) {\n const label =\n mod === \"meta\"\n ? META_LABEL\n : mod === \"alt\"\n ? ALT_LABEL\n : mod.charAt(0).toUpperCase() + mod.slice(1);\n for (const popularKey of POPULAR_KEYS) {\n const keyDisplay =\n popularKey === \" \"\n ? \"Space\"\n : popularKey.length === 1\n ? popularKey.toUpperCase()\n : popularKey;\n suggestions.push({\n title: `${label}+${keyDisplay}`,\n value: {\n key: popularKey,\n ...(mod === \"meta\" ? { metaKey: true } : {}),\n ...(mod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mod === \"shift\" ? { shiftKey: true } : {}),\n ...(mod === \"alt\" ? { altKey: true } : {}),\n },\n });\n }\n }\n for (const baseKey of BASE_KEYS) {\n suggestions.push({\n title:\n baseKey.key === \" \"\n ? \"Space\"\n : baseKey.key.length === 1\n ? baseKey.key.toUpperCase()\n : baseKey.key,\n value: { key: baseKey.key },\n });\n }\n return suggestions;\n }\n\n const buildCombo = (key: string, mods: Set<string>, extraMod?: string): KeyCombo => ({\n key,\n ...(mods.has(\"meta\") || extraMod === \"meta\" ? { metaKey: true } : {}),\n ...(mods.has(\"ctrl\") || extraMod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mods.has(\"shift\") || extraMod === \"shift\" ? { shiftKey: true } : {}),\n ...(mods.has(\"alt\") || extraMod === \"alt\" ? { altKey: true } : {}),\n });\n\n for (const baseKey of BASE_KEYS) {\n const matches = partial ? baseKey.aliases.some((alias) => alias.startsWith(partial)) : true;\n if (matches) {\n const combo = buildCombo(baseKey.key, modifiers);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n\n if (!partial) {\n const unusedMods = MODIFIERS.filter((m) => !modifiers.has(m));\n for (const mod of unusedMods) {\n for (const popularKey of POPULAR_KEYS) {\n const combo = buildCombo(popularKey, modifiers, mod);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n }\n\n return suggestions.slice(0, MAX_SUGGESTIONS_COUNT);\n};\n\nconst CONFIG_OPTIONS: ConfigOption[] = [\n {\n id: \"activationKey\",\n title: \"Shortcut\",\n description: \"The shortcut used to activate React Grab (e.g., g, k, space)\",\n },\n {\n id: \"activationMode\",\n title: \"Activation Mode\",\n description: \"Toggle (press to activate/deactivate) or Hold (hold key)\",\n },\n {\n id: \"keyHoldDuration\",\n title: \"Key Hold Duration\",\n description: \"Milliseconds to hold the key before activation (hold mode)\",\n },\n {\n id: \"allowActivationInsideInput\",\n title: \"Allow Activation Inside Input\",\n description: \"Whether to allow activation when focused on input fields\",\n },\n {\n id: \"maxContextLines\",\n title: \"Max Context Lines\",\n description: \"Max source-location lines in copied context (raise for large apps)\",\n },\n];\n\nconst comboToString = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(\"Meta\");\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(\"Alt\");\n if (combo.key) {\n const keyDisplay = combo.key === \" \" ? \"Space\" : combo.key;\n parts.push(keyDisplay);\n }\n return parts.join(\"+\");\n};\n\nexport const configure = new Command()\n .name(\"configure\")\n .alias(\"config\")\n .description(\"configure React Grab options\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-k, --key <key>\", \"shortcut (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"-m, --mode <mode>\", \"activation mode (toggle, hold)\")\n .option(\"--hold-duration <ms>\", \"key hold duration in milliseconds (for hold mode)\")\n .option(\"--allow-input <boolean>\", \"allow activation inside input fields (true/false)\")\n .option(\"--context-lines <lines>\", \"max context lines to include\")\n .option(\"--cdn <domain>\", \"CDN domain (e.g., unpkg.com, custom.react-grab.com)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n if (!projectInfo.isReactGrabConfigured) {\n preflightSpinner.fail(\"React Grab is installed, but setup is missing.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"react-grab init\")} to add the setup script/import before configuring options.`,\n );\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (opts.cdn) {\n const result = previewCdnTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n opts.cdn,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.break();\n process.exit(1);\n }\n\n if (result.noChanges) {\n logger.break();\n logger.log(\"No changes needed.\");\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n applyTransformWithFeedback(result);\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} CDN updated.`);\n logger.break();\n return;\n }\n\n const hasFlags =\n opts.key || opts.mode || opts.holdDuration || opts.allowInput || opts.contextLines;\n\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (hasFlags) {\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (opts.mode) {\n if (opts.mode !== \"toggle\" && opts.mode !== \"hold\") {\n logger.error(`Invalid mode: ${opts.mode}. Use \"toggle\" or \"hold\".`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.activationMode = opts.mode;\n logger.log(` Activation mode: ${highlighter.info(opts.mode)}`);\n }\n\n if (opts.holdDuration) {\n const duration = parseInt(opts.holdDuration, 10);\n if (isNaN(duration) || duration < 0 || duration > MAX_KEY_HOLD_DURATION_MS) {\n logger.error(`Invalid hold duration. Must be 0-${MAX_KEY_HOLD_DURATION_MS}ms.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.keyHoldDuration = duration;\n logger.log(` Key hold duration: ${highlighter.info(`${duration}ms`)}`);\n }\n\n if (opts.allowInput !== undefined) {\n const allowInput = opts.allowInput === \"true\" || opts.allowInput === true;\n collectedOptions.allowActivationInsideInput = allowInput;\n logger.log(` Allow activation inside input: ${highlighter.info(String(allowInput))}`);\n }\n\n if (opts.contextLines) {\n const lines = parseInt(opts.contextLines, 10);\n if (isNaN(lines) || lines < 0 || lines > MAX_CONTEXT_LINES) {\n logger.error(`Invalid context lines. Must be 0-${MAX_CONTEXT_LINES}.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.maxContextLines = lines;\n logger.log(` Max context lines: ${highlighter.info(String(lines))}`);\n }\n } else {\n const { selectedOption } = await prompts({\n type: \"autocomplete\",\n name: \"selectedOption\",\n message: \"Search for an option to configure:\",\n choices: CONFIG_OPTIONS.map((option) => ({\n title: option.title,\n value: option.id,\n description: option.description,\n })),\n suggest: (input, choices) =>\n Promise.resolve(\n choices.filter(\n (choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()) ||\n (choice.description?.toLowerCase().includes(input.toLowerCase()) ?? false),\n ),\n ),\n });\n\n if (selectedOption === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (selectedOption === \"activationKey\") {\n const { selectedCombo } = await prompts({\n type: \"autocomplete\",\n name: \"selectedCombo\",\n message: \"Type key combination (e.g. ctrl+shift+g):\",\n choices: generateSuggestions(\"\"),\n suggest: (input) => Promise.resolve(generateSuggestions(input)),\n });\n\n if (selectedCombo === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = comboToString(selectedCombo);\n\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (selectedOption === \"activationMode\") {\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n }\n\n if (selectedOption === \"keyHoldDuration\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n if (selectedOption === \"allowActivationInsideInput\") {\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n }\n\n if (selectedOption === \"maxContextLines\") {\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n }\n }\n\n const result = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!result.success) {\n logger.break();\n logger.warn(result.message);\n logger.break();\n\n const configJson = JSON.stringify(collectedOptions);\n logger.log(\n `Add this to your ${highlighter.info(\"init()\")} call or ${highlighter.info(\"data-options\")} attribute:`,\n );\n logger.break();\n console.log(` ${pc.cyan(configJson)}`);\n logger.break();\n process.exit(1);\n }\n\n const hasChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasChanges) {\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n applyTransformWithFeedback(result);\n } else {\n logger.break();\n logger.log(\"No changes needed.\");\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab options have been configured.`);\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","export const isTelemetryEnabled = (): boolean => {\n const doNotTrack = process.env.DO_NOT_TRACK;\n return doNotTrack !== \"1\" && doNotTrack !== \"true\";\n};\n","import { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { applyTransformWithFeedback, installPackagesWithFeedback } from \"../utils/cli-helpers.js\";\nimport { promptSkillInstall } from \"../utils/prompt-skill-install.js\";\nimport {\n detectProject,\n findReactProjects,\n type Framework,\n type PackageManager,\n type UnsupportedFramework,\n type WorkspaceProject,\n} from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { getPackagesToInstall } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n hasFrameworkEntryPoint,\n previewOptionsTransform,\n previewTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\nimport { isTelemetryEnabled } from \"../utils/is-telemetry-enabled.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst REPORT_URL = \"https://react-grab.com/api/report-cli\";\nconst DOCS_URL = \"https://github.com/aidenybai/react-grab\";\n\ninterface ReportConfig {\n framework: string;\n packageManager: string;\n router?: string;\n agent?: string;\n isMonorepo: boolean;\n}\n\nconst reportToCli = (type: \"error\" | \"completed\", config?: ReportConfig, error?: Error): void => {\n if (!isTelemetryEnabled()) return;\n fetch(REPORT_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n type,\n version: VERSION,\n config,\n error: error ? { message: error.message, stack: error.stack } : undefined,\n timestamp: new Date().toISOString(),\n }),\n }).catch(() => {});\n};\n\nconst FRAMEWORK_NAMES: Record<Framework, string> = {\n next: \"Next.js\",\n vite: \"Vite\",\n tanstack: \"TanStack Start\",\n webpack: \"Webpack\",\n unknown: \"Unknown\",\n};\n\nconst PACKAGE_MANAGER_NAMES: Record<PackageManager, string> = {\n npm: \"npm\",\n yarn: \"Yarn\",\n pnpm: \"pnpm\",\n bun: \"Bun\",\n};\n\nconst UNSUPPORTED_FRAMEWORK_NAMES: Record<NonNullable<UnsupportedFramework>, string> = {\n remix: \"Remix\",\n astro: \"Astro\",\n sveltekit: \"SvelteKit\",\n gatsby: \"Gatsby\",\n};\n\nconst sortProjectsByFramework = (projects: WorkspaceProject[]): WorkspaceProject[] =>\n [...projects].sort((projectA, projectB) => {\n if (projectA.framework === \"unknown\" && projectB.framework !== \"unknown\") return 1;\n if (projectA.framework !== \"unknown\" && projectB.framework === \"unknown\") return -1;\n return 0;\n });\n\nconst printSubprojects = (searchRoot: string, sortedProjects: WorkspaceProject[]): void => {\n logger.break();\n logger.log(\"Found the following projects:\");\n logger.break();\n for (const project of sortedProjects) {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n const relativePath = relative(searchRoot, project.path);\n logger.log(\n ` ${highlighter.info(project.name)}${frameworkLabel} ${highlighter.dim(relativePath)}`,\n );\n }\n logger.break();\n logger.log(`Re-run with ${highlighter.info(\"-c <path>\")} to specify a project:`);\n logger.break();\n logger.log(\n ` ${highlighter.dim(\"$\")} npx grab@latest init -c ${relative(searchRoot, sortedProjects[0].path)}`,\n );\n logger.break();\n};\n\nconst SUPPORTED_FRAMEWORKS_LINE =\n \"React Grab supports Next.js, Vite, TanStack Start, and Webpack projects.\";\n\nconst failWithManualSetup = (\n failingSpinner: ReturnType<typeof spinner>,\n message: string,\n { listSupportedFrameworks = false } = {},\n): never => {\n failingSpinner.fail(message);\n logger.break();\n if (listSupportedFrameworks) logger.log(SUPPORTED_FRAMEWORKS_LINE);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n};\n\nexport const init = new Command()\n .name(\"init\")\n .alias(\"setup\")\n .description(\"initialize React Grab in your project\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-f, --force\", \"re-run setup checks even when React Grab is already configured\", false)\n .option(\"-k, --key <key>\", \"shortcut (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"--skip-install\", \"skip package installation\", false)\n .option(\"--pkg <pkg>\", \"custom package URL for CLI (e.g., grab)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"install the skill globally instead of in the project\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n if (!existsSync(cwd)) {\n logger.break();\n logger.error(`Directory does not exist: ${highlighter.info(cwd)}`);\n logger.break();\n process.exit(1);\n }\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (projectInfo.isReactGrabConfigured && !opts.force) {\n preflightSpinner.succeed();\n\n if (isNonInteractive) {\n logger.break();\n logger.warn(\"React Grab is already installed.\");\n logger.log(\n `Use ${highlighter.info(\"--force\")} to re-run setup checks, or remove ${highlighter.info(\"--yes\")} for interactive mode.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.success(\"React Grab is already installed.\");\n logger.break();\n\n const { wantCustomizeOptions } = await prompts({\n type: \"confirm\",\n name: \"wantCustomizeOptions\",\n message: `Would you like to customize ${highlighter.info(\"options\")}?`,\n initial: false,\n });\n\n if (wantCustomizeOptions === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantCustomizeOptions || opts.key) {\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n } else {\n const { wantActivationKey } = await prompts({\n type: \"confirm\",\n name: \"wantActivationKey\",\n message: `Configure ${highlighter.info(\"shortcut\")}?`,\n initial: false,\n });\n\n if (wantActivationKey === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantActivationKey) {\n const { key } = await prompts({\n type: \"text\",\n name: \"key\",\n message: \"Enter the shortcut (e.g., g, k, space):\",\n initial: \"\",\n });\n\n if (key === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = key ? key.toLowerCase() : undefined;\n\n logger.log(\n ` Shortcut: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n }\n\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n\n if (activationMode === \"hold\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n\n const optionsResult = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!optionsResult.success) {\n logger.break();\n logger.error(optionsResult.message);\n logger.break();\n process.exit(1);\n }\n\n const hasOptionsChanges =\n !optionsResult.noChanges && optionsResult.originalContent && optionsResult.newContent;\n\n if (hasOptionsChanges) {\n logger.break();\n printDiff(\n optionsResult.filePath,\n optionsResult.originalContent!,\n optionsResult.newContent!,\n );\n\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Options configuration cancelled.\");\n } else {\n applyTransformWithFeedback(optionsResult);\n\n logger.break();\n logger.success(\"React Grab options have been configured.\");\n }\n } else {\n logger.break();\n logger.log(\"No option changes needed.\");\n }\n }\n\n logger.break();\n await promptSkillInstall({ yes: isNonInteractive, global: opts.global, cwd });\n\n logger.break();\n process.exit(0);\n }\n\n preflightSpinner.succeed();\n\n const frameworkSpinner = spinner(\"Verifying framework.\").start();\n\n if (projectInfo.unsupportedFramework) {\n const frameworkName = UNSUPPORTED_FRAMEWORK_NAMES[projectInfo.unsupportedFramework];\n frameworkSpinner.fail(`Found ${highlighter.info(frameworkName)}.`);\n logger.break();\n logger.log(`${frameworkName} is not yet supported by automatic setup.`);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n // A detected framework whose entry file is missing is only ambiguous in a\n // monorepo, where the real app lives in a workspace and the root config is\n // tooling. For a standalone project we keep the framework so previewTransform\n // can surface its specific manual-setup guidance instead of searching elsewhere.\n const shouldSearchForProject =\n projectInfo.framework === \"unknown\" ||\n (projectInfo.isMonorepo &&\n !hasFrameworkEntryPoint(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n ));\n\n if (shouldSearchForProject) {\n let searchRoot = cwd;\n let reactProjects = findReactProjects(searchRoot);\n if (reactProjects.length === 0 && cwd !== process.cwd()) {\n searchRoot = process.cwd();\n reactProjects = findReactProjects(searchRoot);\n }\n\n if (reactProjects.length > 0) {\n frameworkSpinner.info(\n `Verifying framework. Found ${reactProjects.length} project${reactProjects.length === 1 ? \"\" : \"s\"}.`,\n );\n\n const sortedProjects = sortProjectsByFramework(reactProjects);\n\n if (isNonInteractive) {\n printSubprojects(searchRoot, sortedProjects);\n process.exit(1);\n }\n\n logger.break();\n const { selectedProject } = await prompts({\n type: \"select\",\n name: \"selectedProject\",\n message: \"Select a project to install React Grab:\",\n choices: [\n ...sortedProjects.map((project) => {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n return {\n title: `${project.name}${frameworkLabel}`,\n value: project.path,\n };\n }),\n { title: \"Skip\", value: \"skip\" },\n ],\n });\n\n if (!selectedProject || selectedProject === \"skip\") {\n logger.break();\n process.exit(0);\n }\n\n process.chdir(selectedProject);\n const newProjectInfo = await detectProject(selectedProject);\n Object.assign(projectInfo, newProjectInfo);\n\n const newFrameworkSpinner = spinner(\"Verifying framework.\").start();\n if (newProjectInfo.framework === \"unknown\") {\n failWithManualSetup(\n newFrameworkSpinner,\n \"Could not detect a supported framework in this project.\",\n { listSupportedFrameworks: true },\n );\n }\n newFrameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[newProjectInfo.framework])}.`,\n );\n } else if (projectInfo.framework !== \"unknown\") {\n failWithManualSetup(\n frameworkSpinner,\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}, but could not find an entry file.`,\n );\n } else {\n failWithManualSetup(frameworkSpinner, \"Could not detect a supported framework.\", {\n listSupportedFrameworks: true,\n });\n }\n } else {\n frameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}.`,\n );\n }\n\n if (projectInfo.framework === \"next\") {\n const routerSpinner = spinner(\"Detecting router type.\").start();\n routerSpinner.succeed(\n `Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === \"app\" ? \"App Router\" : \"Pages Router\")}.`,\n );\n }\n\n const packageManagerSpinner = spinner(\"Detecting package manager.\").start();\n packageManagerSpinner.succeed(\n `Detecting package manager. Found ${highlighter.info(PACKAGE_MANAGER_NAMES[projectInfo.packageManager])}.`,\n );\n\n const finalFramework = projectInfo.framework;\n const finalPackageManager = projectInfo.packageManager;\n const finalNextRouterType = projectInfo.nextRouterType;\n let didInstallSkill = false;\n\n if (!isNonInteractive) {\n logger.break();\n didInstallSkill = await promptSkillInstall({\n yes: isNonInteractive,\n global: opts.global,\n cwd,\n });\n }\n\n const result = previewTransform(\n projectInfo.projectRoot,\n finalFramework,\n finalNextRouterType,\n projectInfo.isReactGrabConfigured,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.error(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n const hasLayoutChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasLayoutChanges) {\n logger.break();\n\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n logger.break();\n logger.warn(\"Auto-detection may not be 100% accurate.\");\n logger.warn(\"Please verify the changes before committing.\");\n\n if (!isNonInteractive) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n }\n\n const shouldInstallReactGrab = !projectInfo.hasReactGrab;\n\n if (!opts.skipInstall && shouldInstallReactGrab) {\n await installPackagesWithFeedback(\n getPackagesToInstall(shouldInstallReactGrab),\n finalPackageManager,\n projectInfo.projectRoot,\n );\n }\n\n if (hasLayoutChanges) {\n applyTransformWithFeedback(result);\n }\n\n logger.break();\n if (hasLayoutChanges) {\n logger.log(`${highlighter.success(\"Success!\")} React Grab has been installed.`);\n } else {\n logger.log(`${highlighter.success(\"Success!\")} ${result.message}.`);\n }\n logger.log(\"You may now start your development server.\");\n logger.break();\n\n reportToCli(\"completed\", {\n framework: finalFramework,\n packageManager: finalPackageManager,\n router: finalNextRouterType,\n agent: didInstallSkill ? \"skill\" : undefined,\n isMonorepo: projectInfo.isMonorepo,\n });\n } catch (error) {\n handleError(error);\n reportToCli(\"error\", undefined, error as Error);\n }\n });\n","export const sleep = (durationMs: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, durationMs));\n","import { spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { sleep } from \"./sleep.js\";\n\nexport const HISTORY_FILE_NAME = \"history.jsonl\";\n\nexport const NO_READER_MESSAGE =\n \"no clipboard reader available. Linux: install xclip or wl-clipboard. macOS: install Xcode CLI tools (swiftc) or rely on pbpaste. Windows: ensure PowerShell is on PATH.\";\n\n// Native readers (read-clipboard.swift / .ps1) are copied next to the compiled\n// CLI at build time (see scripts/copy-native-readers.mjs).\nconst READERS_DIR = path.dirname(fileURLToPath(import.meta.url));\n\nconst READ_TIMEOUT_MS = 2500;\nconst MAX_CLIPBOARD_BYTES = 64 * 1024 * 1024;\nconst ID_RADIX = 36;\nconst HASH_LENGTH = 12;\nconst PICKLE_HEADER_BYTES = 4;\nconst PICKLE_ALIGN_BYTES = 4;\nconst SIGNATURE_SCAN_CHARS = 32 * 1024;\n\nexport const GRAB_MIME = \"application/x-react-grab\";\nconst CHROMIUM_CUSTOM_FORMAT = \"chromium/x-web-custom-data\";\n\n// React Grab plain-text payloads always carry a component-stack frame such as\n// \"in LoginForm (at components/login-form.tsx:46:19)\". Used to recognize a grab\n// when the structured custom clipboard format is unavailable (text fallback).\n// `[^\\n]{1,400}?` allows parentheses in paths (e.g. Next.js route groups\n// `(auth)`) while bounding backtracking on hostile clipboard text.\nconst GRAB_TEXT_SIGNATURE = /\\bin\\s+\\S+\\s+\\(at\\s+[^\\n]{1,400}?:\\d+:\\d+\\)/;\n\ninterface GrabEntry {\n tagName?: string;\n componentName?: string;\n content?: string;\n commentText?: string;\n}\n\ninterface GrabRecord {\n source: \"custom\" | \"text\";\n timestamp: number;\n version?: string;\n content: string;\n entries: GrabEntry[];\n prompt?: string;\n}\n\ninterface CapturedGrab extends GrabRecord {\n id: string;\n receivedAt: number;\n}\n\n// What a platform reader returns each poll. `grab` is the resolved\n// application/x-react-grab JSON string when present.\ninterface ClipboardSnapshot {\n changeCount: number | null;\n text?: string;\n grab?: string;\n}\n\n// What the native helpers (Swift/PowerShell) emit; the watcher resolves `grab`\n// from `grab` directly or by decoding `pickleBase64`.\ninterface NativeRead {\n changeCount?: number | null;\n text?: string;\n grab?: string;\n pickleBase64?: string;\n}\n\ninterface ClipboardReader {\n mode: string;\n read: () => ClipboardSnapshot | null;\n}\n\ninterface LinuxTool {\n name: string;\n readText: () => string | null;\n readCustom: (() => Buffer | null) | null;\n}\n\ninterface CreateReaderOptions {\n textOnly: boolean;\n // Writable directory for the compiled native binary (e.g. macOS `pbread`).\n workDir: string;\n}\n\nconst shortHash = (text: string): string =>\n createHash(\"sha1\").update(text).digest(\"hex\").slice(0, HASH_LENGTH);\n\n// Chromium serializes web custom data as a base::Pickle on every platform, only\n// the clipboard format name differs. Layout (little-endian):\n// [payloadSize u32][pairCount u32] then per pair:\n// [len u32 in UTF-16 code units][utf16le string, padded to 4 bytes] x2 (format, data).\nconst alignUp = (value: number): number =>\n (value + PICKLE_ALIGN_BYTES - 1) & ~(PICKLE_ALIGN_BYTES - 1);\n\nexport const parseChromiumPickle = (buffer: Buffer | null | undefined): Record<string, string> => {\n const formats: Record<string, string> = {};\n if (!buffer || buffer.length < PICKLE_HEADER_BYTES + 4) return formats;\n let offset = PICKLE_HEADER_BYTES;\n const pairCount = buffer.readUInt32LE(offset);\n offset += 4;\n for (let pairIndex = 0; pairIndex < pairCount; pairIndex += 1) {\n if (offset + 4 > buffer.length) break;\n const formatCodeUnits = buffer.readUInt32LE(offset);\n offset += 4;\n if (offset + formatCodeUnits * 2 > buffer.length) break;\n const format = buffer.toString(\"utf16le\", offset, offset + formatCodeUnits * 2);\n offset = alignUp(offset + formatCodeUnits * 2);\n if (offset + 4 > buffer.length) break;\n const dataCodeUnits = buffer.readUInt32LE(offset);\n offset += 4;\n if (offset + dataCodeUnits * 2 > buffer.length) break;\n const value = buffer.toString(\"utf16le\", offset, offset + dataCodeUnits * 2);\n offset = alignUp(offset + dataCodeUnits * 2);\n formats[format] = value;\n }\n return formats;\n};\n\nexport const extractGrab = (raw: NativeRead): string | undefined => {\n if (raw.grab) return raw.grab;\n if (raw.pickleBase64)\n return parseChromiumPickle(Buffer.from(raw.pickleBase64, \"base64\"))[GRAB_MIME];\n return undefined;\n};\n\nexport const isGrabText = (text: string): boolean =>\n GRAB_TEXT_SIGNATURE.test(\n text.length > SIGNATURE_SCAN_CHARS ? text.slice(0, SIGNATURE_SCAN_CHARS) : text,\n );\n\n// A grab can carry the user's own instruction (React Grab prompt mode). It lives\n// in entries[].commentText when structured, otherwise it is prepended above the\n// bracketed element references in `content`. Returns that comment, or undefined.\nexport const extractPrompt = (record: {\n entries?: unknown;\n content?: unknown;\n}): string | undefined => {\n const entries = Array.isArray(record.entries) ? (record.entries as GrabEntry[]) : [];\n const comments = entries.map((entry) => entry?.commentText?.trim?.()).filter(Boolean);\n if (comments.length > 0) return comments.join(\"\\n\");\n const content = typeof record.content === \"string\" ? record.content : \"\";\n const lines = content.split(\"\\n\");\n const firstReferenceLine = lines.findIndex((line) => line.startsWith(\"[\"));\n if (firstReferenceLine <= 0) return undefined;\n return lines.slice(0, firstReferenceLine).join(\"\\n\").trim() || undefined;\n};\n\nconst hasCommand = (name: string): boolean => {\n const probe = process.platform === \"win32\" ? \"where\" : \"which\";\n return spawnSync(probe, [name], { stdio: \"ignore\" }).status === 0;\n};\n\nconst runText = (command: string, args: string[]): string | null => {\n const output = spawnSync(command, args, {\n encoding: \"utf8\",\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n return output.status === 0 ? output.stdout : null;\n};\n\nconst runBuffer = (command: string, args: string[]): Buffer | null => {\n const output = spawnSync(command, args, {\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n return output.status === 0 && output.stdout?.length ? output.stdout : null;\n};\n\nconst runJson = (command: string, args: string[]): NativeRead | null => {\n const output = spawnSync(command, args, {\n encoding: \"utf8\",\n maxBuffer: MAX_CLIPBOARD_BYTES,\n timeout: READ_TIMEOUT_MS,\n });\n if (output.status !== 0 || !output.stdout) return null;\n try {\n return JSON.parse(output.stdout) as NativeRead;\n } catch {\n return null;\n }\n};\n\nconst compileSwiftReader = (readersDir: string, workDir: string): string | null => {\n if (!hasCommand(\"swiftc\")) return null;\n const source = path.join(readersDir, \"read-clipboard.swift\");\n if (!fs.existsSync(source)) return null;\n const binary = path.join(workDir, \"pbread\");\n const isStale =\n !fs.existsSync(binary) || fs.statSync(source).mtimeMs > fs.statSync(binary).mtimeMs;\n if (isStale && spawnSync(\"swiftc\", [\"-O\", source, \"-o\", binary]).status !== 0) return null;\n return binary;\n};\n\nconst createDarwinReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const binary = options.textOnly ? null : compileSwiftReader(READERS_DIR, options.workDir);\n if (binary) {\n return {\n mode: \"darwin-native\",\n read: () => {\n const raw = runJson(binary, []);\n if (!raw) return null;\n return { changeCount: raw.changeCount ?? null, text: raw.text, grab: extractGrab(raw) };\n },\n };\n }\n if (!hasCommand(\"pbpaste\")) return null;\n return {\n mode: \"darwin-text\",\n read: () => {\n const text = runText(\"pbpaste\", []);\n return text == null ? null : { changeCount: null, text, grab: undefined };\n },\n };\n};\n\nexport const detectLinuxTool = (): LinuxTool | null => {\n const preferWayland = Boolean(process.env.WAYLAND_DISPLAY) && hasCommand(\"wl-paste\");\n if (preferWayland || (hasCommand(\"wl-paste\") && !hasCommand(\"xclip\"))) {\n return {\n name: \"wl-paste\",\n readText: () =>\n runText(\"wl-paste\", [\"-n\", \"-t\", \"text/plain\"]) ?? runText(\"wl-paste\", [\"-n\"]),\n readCustom: () => runBuffer(\"wl-paste\", [\"-n\", \"-t\", CHROMIUM_CUSTOM_FORMAT]),\n };\n }\n if (hasCommand(\"xclip\")) {\n return {\n name: \"xclip\",\n readText: () => runText(\"xclip\", [\"-selection\", \"clipboard\", \"-o\"]),\n readCustom: () =>\n runBuffer(\"xclip\", [\"-selection\", \"clipboard\", \"-t\", CHROMIUM_CUSTOM_FORMAT, \"-o\"]),\n };\n }\n if (hasCommand(\"xsel\")) {\n return {\n name: \"xsel\",\n readText: () => runText(\"xsel\", [\"--clipboard\", \"--output\"]),\n readCustom: null,\n };\n }\n return null;\n};\n\nconst createLinuxReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const tool = detectLinuxTool();\n if (!tool) return null;\n const useCustom = !options.textOnly && Boolean(tool.readCustom);\n return {\n mode: useCustom ? `linux-${tool.name}` : `linux-${tool.name}-text`,\n read: () => {\n const text = tool.readText();\n if (text == null) return null;\n // No clipboard sequence number on X11/Wayland, so always read the custom\n // blob; its timestamp dedups re-grabs of the identical element.\n const grab =\n useCustom && tool.readCustom\n ? parseChromiumPickle(tool.readCustom())[GRAB_MIME]\n : undefined;\n return { changeCount: null, text, grab };\n },\n };\n};\n\nconst detectPowershell = (): string | null =>\n hasCommand(\"pwsh\") ? \"pwsh\" : hasCommand(\"powershell\") ? \"powershell\" : null;\n\nconst createWindowsReader = (options: CreateReaderOptions): ClipboardReader | null => {\n const shell = detectPowershell();\n if (!shell) return null;\n const scriptPath = path.join(READERS_DIR, \"read-clipboard.ps1\");\n if (options.textOnly || !fs.existsSync(scriptPath)) {\n return {\n mode: \"win-text\",\n read: () => {\n const text = runText(shell, [\"-NoProfile\", \"-Command\", \"Get-Clipboard -Raw\"]);\n return text == null ? null : { changeCount: null, text, grab: undefined };\n },\n };\n }\n const args = [\"-NoProfile\", \"-ExecutionPolicy\", \"Bypass\", \"-File\", scriptPath];\n // Warm the cached C# compile once (untimed) so the first timed poll does not\n // race the first-run compile and kill it.\n spawnSync(shell, args, { stdio: \"ignore\", maxBuffer: MAX_CLIPBOARD_BYTES });\n return {\n mode: \"win-native\",\n read: () => {\n const raw = runJson(shell, args);\n if (!raw) return null;\n return {\n changeCount: raw.changeCount ?? null,\n text: raw.text ?? undefined,\n grab: extractGrab(raw),\n };\n },\n };\n};\n\nexport const createReader = (options: CreateReaderOptions): ClipboardReader | null => {\n if (process.platform === \"darwin\") return createDarwinReader(options);\n if (process.platform === \"linux\") return createLinuxReader(options);\n if (process.platform === \"win32\") return createWindowsReader(options);\n return null;\n};\n\n// On a shared host an attacker could pre-create the work dir (or its log as a\n// symlink) to redirect appends; refuse anything we do not own.\nconst ensureSafeDir = (dir: string): void => {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(dir);\n } catch {\n return;\n }\n if (stats.isSymbolicLink()) throw new Error(`Refusing to use ${dir}: it is a symlink.`);\n if (process.getuid && stats.uid !== process.getuid()) {\n throw new Error(`Refusing to use ${dir}: owned by another user.`);\n }\n};\n\n// Creates the work dir and drops a self-ignoring .gitignore so the captured\n// history never lands in the user's repo.\nexport const prepareWorkDir = (dir: string): void => {\n ensureSafeDir(dir);\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n const gitignore = path.join(dir, \".gitignore\");\n if (!fs.existsSync(gitignore)) fs.writeFileSync(gitignore, \"*\\n\");\n};\n\ninterface RunWatchLoopOptions {\n reader: ClipboardReader;\n dir: string;\n intervalMs: number;\n replayLast: boolean;\n onWarn?: (message: string) => void;\n}\n\n// Baselines the current clipboard first so a grab already sitting there is not\n// replayed (unless replayLast), then appends each newly captured grab forever.\nexport const runWatchLoop = async (options: RunWatchLoopOptions): Promise<void> => {\n const { reader, dir, intervalMs, replayLast, onWarn } = options;\n const logPath = path.join(dir, HISTORY_FILE_NAME);\n const { read } = reader;\n\n let lastChangeCount: number | null = null;\n let lastTimestamp = 0;\n let lastTextHash = \"\";\n let lastErrorMessage = \"\";\n let sequence = 0;\n\n const initial = read();\n if (initial && !replayLast) {\n lastChangeCount = initial.changeCount;\n if (initial.text) lastTextHash = shortHash(initial.text);\n if (initial.grab) {\n try {\n lastTimestamp = (JSON.parse(initial.grab) as { timestamp?: number }).timestamp ?? 0;\n } catch {}\n }\n }\n\n while (true) {\n await sleep(intervalMs);\n // Clipboard payloads are untrusted (any web page can forge one), so a single\n // malformed/hostile grab must never crash the loop. Distinct errors surface\n // via onWarn so a persistent failure is diagnosable rather than silent.\n try {\n const snapshot = read();\n if (!snapshot) continue;\n if (snapshot.changeCount !== null && snapshot.changeCount === lastChangeCount) continue;\n\n const textHash = snapshot.text ? shortHash(snapshot.text) : \"\";\n const didTextChange = textHash !== lastTextHash;\n\n let record: GrabRecord | null = null;\n let nextTimestamp = lastTimestamp;\n if (snapshot.grab) {\n let parsed: {\n timestamp?: number;\n version?: string;\n content?: unknown;\n entries?: unknown;\n } | null = null;\n try {\n parsed = JSON.parse(snapshot.grab);\n } catch {}\n if (parsed && typeof parsed.timestamp === \"number\" && parsed.timestamp > lastTimestamp) {\n nextTimestamp = parsed.timestamp;\n record = {\n source: \"custom\",\n timestamp: parsed.timestamp,\n version: typeof parsed.version === \"string\" ? parsed.version : undefined,\n content: typeof parsed.content === \"string\" ? parsed.content : \"\",\n entries: Array.isArray(parsed.entries) ? (parsed.entries as GrabEntry[]) : [],\n };\n }\n } else if (didTextChange && snapshot.text && isGrabText(snapshot.text)) {\n record = { source: \"text\", timestamp: Date.now(), content: snapshot.text, entries: [] };\n }\n\n if (!record) {\n // The clipboard changed but carried no new grab; advance the dedup\n // state so the same content is not re-scanned every poll.\n lastChangeCount = snapshot.changeCount;\n lastTextHash = textHash;\n continue;\n }\n\n const prompt = extractPrompt(record);\n if (prompt) record.prompt = prompt;\n\n const captured: CapturedGrab = {\n id: `${record.timestamp}-${(sequence += 1).toString(ID_RADIX)}`,\n receivedAt: Date.now(),\n ...record,\n };\n // Commit the dedup state only after the write succeeds; a failed append\n // must leave the grab eligible for retry on the next poll, not lost.\n fs.appendFileSync(logPath, `${JSON.stringify(captured)}\\n`);\n lastChangeCount = snapshot.changeCount;\n lastTextHash = textHash;\n lastTimestamp = nextTimestamp;\n } catch (error) {\n const message = String((error as Error)?.message ?? error);\n if (message !== lastErrorMessage) {\n lastErrorMessage = message;\n onWarn?.(message);\n }\n }\n }\n};\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { createReader } from \"./clipboard.js\";\nimport { DAEMON_CLAIM_MAX_ATTEMPTS } from \"./constants.js\";\n\nconst PID_FILE_NAME = \"watch.pid\";\n\nconst pidFilePath = (dir: string): string => path.join(dir, PID_FILE_NAME);\n\nconst cliEntryPath = (): string => process.argv[1] ?? fileURLToPath(import.meta.url);\n\n// Signal 0 only runs the kernel's permission/existence checks without delivering\n// anything: ESRCH means the process is gone, EPERM means it exists under another\n// user (still \"alive\" for dedup purposes).\nconst isProcessAlive = (pid: number): boolean => {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === \"EPERM\";\n }\n};\n\nexport const readDaemonPid = (dir: string): number | null => {\n try {\n const pid = Number.parseInt(fs.readFileSync(pidFilePath(dir), \"utf8\").trim(), 10);\n return Number.isInteger(pid) && pid > 0 ? pid : null;\n } catch {\n return null;\n }\n};\n\nexport const isDaemonRunning = (dir: string): boolean => {\n const pid = readDaemonPid(dir);\n return pid !== null && isProcessAlive(pid);\n};\n\n// Atomic `wx` create acts as the per-dir lock; a file left by a crashed daemon is\n// reclaimed. The post-write re-read closes the open->write window where a racing\n// claimant could see a momentarily-empty file and steal it.\nexport const claimDaemon = (dir: string): boolean => {\n const file = pidFilePath(dir);\n for (let attempt = 0; attempt < DAEMON_CLAIM_MAX_ATTEMPTS; attempt += 1) {\n try {\n const handle = fs.openSync(file, \"wx\");\n fs.writeFileSync(handle, String(process.pid));\n fs.closeSync(handle);\n return readDaemonPid(dir) === process.pid;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n if (isDaemonRunning(dir)) return false;\n try {\n fs.rmSync(file, { force: true });\n } catch {}\n }\n }\n return false;\n};\n\n// Removes the pid file only when this process still owns it, so a freshly\n// restarted daemon's file is never clobbered by a predecessor's late cleanup.\nexport const releaseDaemon = (dir: string): void => {\n if (readDaemonPid(dir) === process.pid) {\n try {\n fs.rmSync(pidFilePath(dir), { force: true });\n } catch {}\n }\n};\n\n// Removes the pid file only if it still names the pid we signalled, so a\n// successor that already re-claimed the dir is not clobbered.\nexport const stopDaemon = (dir: string): number | null => {\n const pid = readDaemonPid(dir);\n if (pid === null) return null;\n const wasAlive = isProcessAlive(pid);\n if (wasAlive) {\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {}\n }\n if (readDaemonPid(dir) === pid) {\n try {\n fs.rmSync(pidFilePath(dir), { force: true });\n } catch {}\n }\n return wasAlive ? pid : null;\n};\n\ninterface EnsureDaemonOptions {\n dir: string;\n intervalMs: number;\n textOnly: boolean;\n replayLast: boolean;\n}\n\n// Detached + unref'd so the caller exits immediately while the daemon keeps\n// running. Re-execs the hidden `watch` command, which is the capture-daemon body.\nconst spawnDaemon = (options: EnsureDaemonOptions): void => {\n const args = [\n cliEntryPath(),\n \"watch\",\n \"--dir\",\n options.dir,\n \"--interval\",\n String(options.intervalMs),\n ];\n if (options.textOnly) args.push(\"--text-only\");\n if (options.replayLast) args.push(\"--replay-last\");\n const child = spawn(process.execPath, args, {\n detached: true,\n stdio: \"ignore\",\n windowsHide: true,\n });\n child.unref();\n};\n\nexport type EnsureDaemonResult = \"already-running\" | \"started\" | \"no-reader\";\n\n// Starts the capture daemon if one isn't already watching `dir`. Validates the\n// clipboard reader first: the detached daemon's stderr is discarded, so a missing\n// reader would otherwise fail invisibly.\nexport const ensureDaemon = (options: EnsureDaemonOptions): EnsureDaemonResult => {\n if (isDaemonRunning(options.dir)) return \"already-running\";\n if (!createReader({ textOnly: options.textOnly, workDir: options.dir })) return \"no-reader\";\n spawnDaemon(options);\n return \"started\";\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { HISTORY_FILE_NAME } from \"./clipboard.js\";\nimport { MAX_READ_HISTORY_BYTES, MIGRATION_SCAN_CHUNK_BYTES } from \"./constants.js\";\n\nconst CURSOR_FILE_NAME = \"cursor.txt\";\nconst NEWLINE_BYTE = 0x0a;\n\nconst cursorFilePath = (dir: string): string => path.join(dir, CURSOR_FILE_NAME);\nconst historyFilePath = (dir: string): string => path.join(dir, HISTORY_FILE_NAME);\n\nconst fileSize = (filePath: string): number => {\n try {\n return fs.statSync(filePath).size;\n } catch {\n return 0;\n }\n};\n\nconst readHistoryRange = (dir: string, start: number, length: number): string => {\n if (length <= 0) return \"\";\n const fd = fs.openSync(historyFilePath(dir), \"r\");\n try {\n const buffer = Buffer.allocUnsafe(length);\n const bytesRead = fs.readSync(fd, buffer, 0, length, start);\n return buffer.toString(\"utf8\", 0, bytesRead);\n } finally {\n fs.closeSync(fd);\n }\n};\n\n// temp + rename so a crash mid-write can't leave a truncated cursor. Tagged as\n// JSON so a legacy bare-integer (line-index) cursor is distinguishable on read.\nconst writeGrabCursor = (dir: string, offset: number): void => {\n const target = cursorFilePath(dir);\n const tempPath = `${target}.${process.pid}.tmp`;\n fs.writeFileSync(tempPath, JSON.stringify({ offset }));\n fs.renameSync(tempPath, target);\n};\n\n// Exact byte offset after `lineCount` newlines, scanned in bounded chunks so a\n// huge legacy history neither materializes a >512 MB string nor clamps to a scan\n// window (which would re-deliver or drop records on migration). `\\n` (0x0A) never\n// occurs inside a multi-byte UTF-8 sequence, so counting bytes is correct.\nconst byteOffsetAfterLines = (dir: string, lineCount: number): number => {\n const filePath = historyFilePath(dir);\n const size = fileSize(filePath);\n if (lineCount <= 0 || size === 0) return 0;\n const fd = fs.openSync(filePath, \"r\");\n try {\n const buffer = Buffer.allocUnsafe(MIGRATION_SCAN_CHUNK_BYTES);\n let position = 0;\n let seen = 0;\n while (position < size) {\n const bytesRead = fs.readSync(fd, buffer, 0, MIGRATION_SCAN_CHUNK_BYTES, position);\n if (bytesRead <= 0) break;\n for (let index = 0; index < bytesRead; index += 1) {\n if (buffer[index] !== NEWLINE_BYTE) continue;\n seen += 1;\n if (seen === lineCount) return position + index + 1;\n }\n position += bytesRead;\n }\n } finally {\n fs.closeSync(fd);\n }\n // Fewer than lineCount complete lines exist; the legacy cursor consumed all of them.\n return size;\n};\n\n// Byte offset into history.jsonl (not a line index), so an idle poll can tell\n// \"nothing new\" from the file size without reading.\nexport const readGrabCursor = (dir: string): number => {\n let raw: string;\n try {\n raw = fs.readFileSync(cursorFilePath(dir), \"utf8\").trim();\n } catch {\n return 0;\n }\n if (raw === \"\") return 0;\n let parsed: { offset?: unknown } | number;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return 0;\n }\n if (typeof parsed === \"number\") {\n // A bare integer is a legacy line-index cursor from before byte offsets.\n // Convert it to the byte position after that many lines (and persist) so\n // already-consumed grabs are not re-delivered after an upgrade.\n if (!Number.isInteger(parsed) || parsed < 0) return 0;\n const offset = byteOffsetAfterLines(dir, parsed);\n writeGrabCursor(dir, offset);\n return offset;\n }\n return typeof parsed.offset === \"number\" && Number.isInteger(parsed.offset) && parsed.offset >= 0\n ? parsed.offset\n : 0;\n};\n\nexport const readCompleteGrabLines = (dir: string): string[] => {\n const size = fileSize(historyFilePath(dir));\n if (size === 0) return [];\n const raw = readHistoryRange(dir, 0, size);\n const lastNewline = raw.lastIndexOf(\"\\n\");\n if (lastNewline < 0) return [];\n return raw.slice(0, lastNewline).split(\"\\n\").filter(Boolean);\n};\n\ninterface ConsumeGrabsOptions {\n limit: number;\n all: boolean;\n maxAgeMs: number;\n}\n\nexport const consumeGrabs = (dir: string, options: ConsumeGrabsOptions): string[] => {\n if (options.all) return readCompleteGrabLines(dir);\n\n const size = fileSize(historyFilePath(dir));\n const cursor = readGrabCursor(dir);\n // A cursor past EOF means the history was truncated/rotated under us; restart.\n const start = cursor > size ? 0 : cursor;\n if (start >= size) {\n // Persist the reset, or a later-grown file would be read from the stale offset.\n if (start !== cursor) writeGrabCursor(dir, start);\n return [];\n }\n\n const chunk = readHistoryRange(dir, start, Math.min(size - start, MAX_READ_HISTORY_BYTES));\n const lastNewline = chunk.lastIndexOf(\"\\n\");\n if (lastNewline < 0) return [];\n\n const now = Date.now();\n const fresh: string[] = [];\n let consumedBytes = 0;\n let lineStart = 0;\n while (lineStart <= lastNewline && (options.limit <= 0 || fresh.length < options.limit)) {\n const newlineIndex = chunk.indexOf(\"\\n\", lineStart);\n const line = chunk.slice(lineStart, newlineIndex);\n consumedBytes += Buffer.byteLength(chunk.slice(lineStart, newlineIndex + 1), \"utf8\");\n lineStart = newlineIndex + 1;\n if (line.length === 0) continue;\n let parsed: { receivedAt?: unknown };\n try {\n parsed = JSON.parse(line);\n } catch {\n // Corrupt or partial line; skip it (the cursor still advances past it).\n continue;\n }\n if (options.maxAgeMs > 0 && typeof parsed.receivedAt === \"number\") {\n if (now - parsed.receivedAt > options.maxAgeMs) continue;\n }\n fresh.push(line);\n }\n\n const nextCursor = start + consumedBytes;\n if (nextCursor !== cursor) writeGrabCursor(dir, nextCursor);\n return fresh;\n};\n","export const parseWaitMs = (raw: string | undefined): number | null => {\n if (raw === undefined) return 0;\n const trimmed = raw.trim();\n if (trimmed === \"\") return 0;\n if (/^(inf|infinite|infinity|forever)$/i.test(trimmed)) return Number.POSITIVE_INFINITY;\n const ms = Number(trimmed);\n return Number.isFinite(ms) && ms >= 0 ? ms : null;\n};\n\nexport const parseNonNegativeInt = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const trimmed = raw.trim();\n // Number(\"\") and Number(\" \") are 0, which would mask empty/garbage input.\n if (trimmed === \"\") return null;\n const value = Number(trimmed);\n return Number.isInteger(value) && value >= 0 ? value : null;\n};\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { NO_READER_MESSAGE, prepareWorkDir } from \"../utils/clipboard.js\";\nimport {\n DEFAULT_GRAB_AGE_MS,\n DEFAULT_WATCH_DIR,\n DEFAULT_WATCH_INTERVAL_MS,\n READ_DEFAULT_LIMIT,\n READ_WAIT_POLL_MS,\n} from \"../utils/constants.js\";\nimport { ensureDaemon } from \"../utils/daemon.js\";\nimport { consumeGrabs } from \"../utils/grab-log.js\";\nimport { parseNonNegativeInt, parseWaitMs } from \"../utils/read-args.js\";\nimport { sleep } from \"../utils/sleep.js\";\nimport { unrefStdin } from \"../utils/unref-stdin.js\";\n\ninterface PullOptions {\n dir: string;\n wait: string;\n limit: string;\n maxAge: string;\n textOnly?: boolean;\n all?: boolean;\n}\n\nconst fail = (message: string): never => {\n process.stderr.write(`react-grab pull: ${message}\\n`);\n process.exit(1);\n};\n\n// Exit only after the write flushes; process.exit() mid-write can truncate a pipe.\nconst emitAndExit = (lines: string[]): void => {\n process.stdout.write(`${lines.join(\"\\n\")}\\n`, () => process.exit(0));\n};\n\nexport const pull = new Command()\n .name(\"pull\")\n .description(\"start the watcher if needed, then wait for and print the next React Grab grab(s)\")\n .option(\"-d, --dir <dir>\", \"work dir for history.jsonl + watch.pid\", DEFAULT_WATCH_DIR)\n .option(\n \"-w, --wait <ms>\",\n \"how long to wait for a grab: ms, 'infinite', or 0 for none\",\n \"infinite\",\n )\n .option(\n \"-n, --limit <count>\",\n \"max grabs to print per call (0 = no limit)\",\n String(READ_DEFAULT_LIMIT),\n )\n .option(\n \"--max-age <ms>\",\n \"skip grabs captured longer ago than <ms> (0 = never)\",\n String(DEFAULT_GRAB_AGE_MS),\n )\n .option(\n \"--text-only\",\n \"watcher uses the plain-text clipboard reader (ignored if already running)\",\n )\n .option(\"--all\", \"print the whole history without advancing the cursor\")\n .action(async (options: PullOptions) => {\n const dir = path.resolve(options.dir);\n\n try {\n prepareWorkDir(dir);\n } catch (error) {\n fail(String((error as Error)?.message ?? error));\n }\n\n const waitMs = parseWaitMs(options.wait);\n if (waitMs === null) fail(`invalid --wait \"${options.wait}\" (use milliseconds or \"infinite\")`);\n const limit = parseNonNegativeInt(options.limit);\n if (limit === null) fail(`invalid --limit \"${options.limit}\" (use a non-negative integer)`);\n const maxAgeMs = parseNonNegativeInt(options.maxAge);\n if (maxAgeMs === null)\n fail(`invalid --max-age \"${options.maxAge}\" (use milliseconds, 0 to disable)`);\n\n const all = Boolean(options.all);\n const textOnly = Boolean(options.textOnly);\n\n if (\n ensureDaemon({ dir, intervalMs: DEFAULT_WATCH_INTERVAL_MS, textOnly, replayLast: false }) ===\n \"no-reader\"\n ) {\n fail(NO_READER_MESSAGE);\n }\n\n unrefStdin();\n const consume = (): string[] => consumeGrabs(dir, { limit, all, maxAgeMs });\n\n const first = consume();\n if (first.length > 0) {\n emitAndExit(first);\n return;\n }\n\n const deadline = Date.now() + waitMs;\n while (Date.now() < deadline) {\n await sleep(READ_WAIT_POLL_MS);\n const batch = consume();\n if (batch.length > 0) {\n emitAndExit(batch);\n return;\n }\n }\n process.exit(0);\n });\n","import { resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { agentLabel, removeSkill } from \"../utils/install-skill.js\";\nimport { logger } from \"../utils/logger.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const remove = new Command()\n .name(\"remove\")\n .description(\"uninstall the React Grab skill from your agent\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .option(\"-g, --global\", \"remove the globally-installed skill instead of the project's\", false)\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n logger.break();\n const removedAgents = await removeSkill({ cwd: resolve(opts.cwd), global: opts.global });\n for (const agent of removedAgents) {\n logger.log(` ${highlighter.success(\"\\u2713\")} ${agentLabel(agent)}`);\n }\n\n logger.break();\n if (removedAgents.length === 0) {\n logger.log(\"React Grab skill is not installed in any detected agent.\");\n } else {\n logger.log(\n `${highlighter.success(\"Removed\")} the React Grab skill from ${removedAgents.length} agent${removedAgents.length === 1 ? \"\" : \"s\"}.`,\n );\n }\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { DEFAULT_WATCH_DIR } from \"../utils/constants.js\";\nimport { stopDaemon } from \"../utils/daemon.js\";\n\nexport const stop = new Command()\n .name(\"stop\")\n .description(\"stop the React Grab watcher for this dir\")\n .option(\"-d, --dir <dir>\", \"work dir holding watch.pid\", DEFAULT_WATCH_DIR)\n .action((options: { dir: string }) => {\n const dir = path.resolve(options.dir);\n const stoppedPid = stopDaemon(dir);\n process.stderr.write(\n stoppedPid\n ? `react-grab stop: stopped watcher (pid ${stoppedPid})\\n`\n : `react-grab stop: no watcher running for ${dir}\\n`,\n );\n process.exit(0);\n });\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installPackages } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/react-grab/latest\";\n\ninterface NpmPackageInfo {\n version: string;\n}\n\nconst fetchLatestVersion = async (): Promise<string | null> => {\n try {\n const response = await fetch(NPM_REGISTRY_URL);\n const data: NpmPackageInfo = await response.json();\n return data.version ?? null;\n } catch {\n return null;\n }\n};\n\nconst isDevDependency = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return true;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.devDependencies?.[\"react-grab\"]) return true;\n if (packageJson.dependencies?.[\"react-grab\"]) return false;\n } catch {}\n return true;\n};\n\nexport const upgrade = new Command()\n .name(\"upgrade\")\n .alias(\"update\")\n .description(\"upgrade react-grab to the latest version\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n\n const detectSpinner = spinner(\"Detecting project.\").start();\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n detectSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"npx grab@latest init\")} first to install React Grab.`,\n );\n logger.break();\n process.exit(1);\n }\n\n detectSpinner.succeed();\n\n const versionSpinner = spinner(\"Checking for updates.\").start();\n const latestVersion = await fetchLatestVersion();\n\n if (!latestVersion) {\n versionSpinner.fail(\"Could not check for updates.\");\n logger.break();\n logger.error(\"Failed to reach the npm registry. Check your network connection.\");\n logger.break();\n process.exit(1);\n }\n\n const installedVersion = projectInfo.reactGrabVersion;\n\n if (installedVersion && installedVersion === latestVersion) {\n versionSpinner.succeed(\n `Already on the latest version ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n process.exit(0);\n }\n\n const fromLabel = installedVersion ? `v${installedVersion}` : \"unknown\";\n versionSpinner.succeed(\n `Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`,\n );\n\n const upgradeSpinner = spinner(\"Upgrading react-grab.\").start();\n\n try {\n await installPackages([\"react-grab@latest\"], {\n packageManager: projectInfo.packageManager,\n cwd: projectInfo.projectRoot,\n isDev: isDevDependency(projectInfo.projectRoot),\n });\n upgradeSpinner.succeed();\n } catch {\n upgradeSpinner.fail();\n logger.break();\n logger.error(\"Failed to upgrade. Check your network connection and try again.\");\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n logger.log(\n `${highlighter.success(\"Success!\")} React Grab has been upgraded to ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n HISTORY_FILE_NAME,\n NO_READER_MESSAGE,\n createReader,\n prepareWorkDir,\n runWatchLoop,\n} from \"../utils/clipboard.js\";\nimport { DEFAULT_WATCH_DIR, DEFAULT_WATCH_INTERVAL_MS } from \"../utils/constants.js\";\nimport { claimDaemon, releaseDaemon } from \"../utils/daemon.js\";\n\ninterface WatchOptions {\n dir: string;\n interval: string;\n textOnly?: boolean;\n replayLast?: boolean;\n}\n\nconst writeStatus = (message: string): void => {\n process.stderr.write(`react-grab watch: ${message}\\n`);\n};\n\n// The capture-daemon body that `pull` re-execs detached. Claims the per-dir lock\n// (exits quietly if another daemon already owns it), then polls the clipboard\n// into history.jsonl until the process is killed.\nexport const watch = new Command()\n .name(\"watch\")\n .description(\"run the React Grab capture daemon in the foreground (used internally by `pull`)\")\n .option(\"-d, --dir <dir>\", \"work dir for history.jsonl + watch.pid\", DEFAULT_WATCH_DIR)\n .option(\"-i, --interval <ms>\", \"clipboard poll interval in ms\", String(DEFAULT_WATCH_INTERVAL_MS))\n .option(\"--text-only\", \"skip the native reader and use the plain-text fallback\")\n .option(\"--replay-last\", \"also capture the grab already on the clipboard at startup\")\n .action((options: WatchOptions) => {\n const dir = path.resolve(options.dir);\n const intervalRaw = Number(options.interval);\n const intervalMs =\n Number.isFinite(intervalRaw) && intervalRaw > 0 ? intervalRaw : DEFAULT_WATCH_INTERVAL_MS;\n\n try {\n prepareWorkDir(dir);\n } catch (error) {\n writeStatus(String((error as Error)?.message ?? error));\n process.exit(1);\n }\n\n if (!claimDaemon(dir)) process.exit(0);\n process.on(\"exit\", () => releaseDaemon(dir));\n\n const reader = createReader({ textOnly: Boolean(options.textOnly), workDir: dir });\n if (!reader) {\n writeStatus(NO_READER_MESSAGE);\n process.exit(1);\n }\n\n writeStatus(\n `watching clipboard via ${reader.mode}; history → ${path.join(dir, HISTORY_FILE_NAME)}`,\n );\n\n runWatchLoop({\n reader,\n dir,\n intervalMs,\n replayLast: Boolean(options.replayLast),\n onWarn: writeStatus,\n }).catch((error) => {\n writeStatus(String((error as Error)?.message ?? error));\n process.exit(1);\n });\n });\n","import { Command } from \"commander\";\nimport { add } from \"./commands/add.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { init } from \"./commands/init.js\";\nimport { pull } from \"./commands/pull.js\";\nimport { remove } from \"./commands/remove.js\";\nimport { stop } from \"./commands/stop.js\";\nimport { upgrade } from \"./commands/upgrade.js\";\nimport { watch } from \"./commands/watch.js\";\nimport { isTelemetryEnabled } from \"./utils/is-telemetry-enabled.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst VERSION_API_URL = \"https://www.react-grab.com/api/version\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\ntry {\n if (isTelemetryEnabled()) {\n fetch(`${VERSION_API_URL}?source=cli&v=${VERSION}&t=${Date.now()}`).catch(() => {});\n }\n} catch {}\n\nconst program = new Command()\n .name(\"grab\")\n .description(\"add React Grab to your project\")\n .version(VERSION, \"-v, --version\", \"display the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(remove);\nprogram.addCommand(configure);\nprogram.addCommand(upgrade);\nprogram.addCommand(pull);\nprogram.addCommand(stop);\nprogram.addCommand(watch, { hidden: true });\n\nconst main = async () => {\n await program.parseAsync();\n};\n\nmain();\n"],"mappings":"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"}