@llmist/cli 10.1.1 → 10.3.1
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 +15 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +56 -0
- package/dist/index.js +552 -0
- package/dist/index.js.map +1 -0
- package/package.json +15 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/builtins/filesystem/edit-file.ts","../src/spawn.ts","../src/builtins/filesystem/utils.ts","../src/builtins/filesystem/list-directory.ts","../src/builtins/filesystem/read-file.ts","../src/builtins/filesystem/write-file.ts","../src/builtins/run-command.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { createGadget } from \"llmist\";\nimport { spawn } from \"../../spawn.js\";\nimport { validatePathIsWithinCwd } from \"./utils.js\";\n\n/**\n * EditFile gadget - Edit files using ed commands.\n * Shell escape commands (!) are filtered for security.\n */\nfunction filterDangerousCommands(commands: string): string {\n return commands\n .split(\"\\n\")\n .filter((line) => !line.trimStart().startsWith(\"!\"))\n .join(\"\\n\");\n}\n\nexport const editFile = createGadget({\n name: \"EditFile\",\n description:\n \"Edit a file using ed commands. Ed is a line-oriented text editor - pipe commands to it for precise file modifications. Commands are executed in sequence. Remember to end with 'w' (write) and 'q' (quit). Shell escape commands (!) are filtered for security.\",\n schema: z.object({\n filePath: z.string().describe(\"Path to the file to edit (relative or absolute)\"),\n commands: z.string().describe(\"Ed commands to execute, one per line\"),\n }),\n examples: [\n {\n params: {\n filePath: \"config.txt\",\n commands: `1,$p\nq`,\n },\n output: \"path=config.txt\\n\\n32\\nkey=value\\noption=true\",\n comment: \"Print entire file contents (ed shows byte count, then content)\",\n },\n {\n params: {\n filePath: \"data.txt\",\n commands: `1,$s/foo/bar/g\nw\nq`,\n },\n output: \"path=data.txt\\n\\n42\\n42\",\n comment: \"Replace all 'foo' with 'bar' (ed shows bytes read, then bytes written)\",\n },\n {\n params: {\n filePath: \"list.txt\",\n commands: `3d\nw\nq`,\n },\n output: \"path=list.txt\\n\\n45\\n28\",\n comment: \"Delete line 3, save and quit\",\n },\n {\n params: {\n filePath: \"readme.txt\",\n commands: `$a\nNew last line\n.\nw\nq`,\n },\n output: \"path=readme.txt\\n\\n40\\n56\",\n comment: \"Append text after last line ($ = last line, . = end input mode)\",\n },\n ],\n timeoutMs: 30000,\n execute: async ({ filePath, commands }) => {\n const validatedPath = validatePathIsWithinCwd(filePath);\n const safeCommands = filterDangerousCommands(commands);\n\n try {\n const proc = spawn([\"ed\", validatedPath], {\n stdin: \"pipe\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n // Write commands to ed's stdin\n if (!proc.stdin) {\n return `path=${filePath}\\n\\nerror: Failed to open stdin for ed process`;\n }\n proc.stdin.write(`${safeCommands}\\n`);\n proc.stdin.end();\n\n // Create timeout promise (30 seconds) with cleanup capability\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n proc.kill();\n reject(new Error(\"ed command timed out after 30000ms\"));\n }, 30000);\n });\n\n // Wait for process and consume streams concurrently to prevent deadlock.\n // If we await proc.exited first, large output can fill pipe buffers,\n // causing the process to block on write while we block on exit.\n const [exitCode, stdout, stderr] = await Promise.race([\n Promise.all([\n proc.exited,\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n ]),\n timeoutPromise,\n ]);\n\n // Clear timeout on normal exit to prevent dangling timer\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n\n if (exitCode !== 0) {\n return `path=${filePath}\\n\\n${output || \"ed exited with non-zero status\"}`;\n }\n\n return `path=${filePath}\\n\\n${output || \"(no output)\"}`;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return `path=${filePath}\\n\\nerror: ${message}`;\n }\n },\n});\n","/**\n * Cross-runtime spawn utility.\n *\n * Provides a consistent API for spawning child processes that works in both\n * Bun and Node.js environments. Uses Bun.spawn when available, falls back to\n * Node.js child_process.spawn otherwise.\n *\n * @module cli/spawn\n */\n\nimport { spawn as nodeSpawn } from \"node:child_process\";\nimport { Readable } from \"node:stream\";\n\n/**\n * Check if we're running in Bun runtime.\n */\nconst isBun = typeof Bun !== \"undefined\";\n\n/**\n * Stdio configuration for spawn.\n */\ntype StdioOption = \"pipe\" | \"inherit\" | \"ignore\";\n\n/**\n * Options for spawn function.\n */\nexport interface SpawnOptions {\n /** Working directory for the child process */\n cwd?: string;\n /** stdin configuration */\n stdin?: StdioOption;\n /** stdout configuration */\n stdout?: StdioOption;\n /** stderr configuration */\n stderr?: StdioOption;\n}\n\n/**\n * Writable stdin interface compatible with both runtimes.\n */\nexport interface SpawnStdin {\n write(data: string): void;\n end(): void;\n}\n\n/**\n * Result from spawn function, compatible with Bun.spawn return type.\n */\nexport interface SpawnResult {\n /** Promise that resolves to exit code when process exits */\n exited: Promise<number>;\n /** stdout stream (null if not piped) */\n stdout: ReadableStream<Uint8Array> | null;\n /** stderr stream (null if not piped) */\n stderr: ReadableStream<Uint8Array> | null;\n /** stdin writer (null if not piped) */\n stdin: SpawnStdin | null;\n /** Kill the child process */\n kill(): void;\n}\n\n/**\n * Adapt Bun.Subprocess to SpawnResult interface.\n * This explicit mapping ensures type safety and makes the contract between\n * our code and Bun's API explicit, catching any future API changes at compile time.\n *\n * Note: Bun returns `undefined` for non-piped streams, we normalize to `null`.\n */\nfunction adaptBunProcess(proc: {\n exited: Promise<number>;\n stdout: ReadableStream<Uint8Array> | undefined;\n stderr: ReadableStream<Uint8Array> | undefined;\n stdin: { write(data: string): number; end(): void } | undefined;\n kill(): void;\n}): SpawnResult {\n return {\n exited: proc.exited,\n stdout: proc.stdout ?? null,\n stderr: proc.stderr ?? null,\n stdin: proc.stdin\n ? {\n write(data: string) {\n proc.stdin?.write(data);\n },\n end() {\n proc.stdin?.end();\n },\n }\n : null,\n kill: () => proc.kill(),\n };\n}\n\n/**\n * Convert a Node.js Readable stream to a web ReadableStream.\n */\nfunction nodeStreamToReadableStream(nodeStream: Readable | null): ReadableStream<Uint8Array> | null {\n if (!nodeStream) return null;\n\n return new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on(\"data\", (chunk: Buffer) => {\n controller.enqueue(new Uint8Array(chunk));\n });\n nodeStream.on(\"end\", () => {\n controller.close();\n });\n nodeStream.on(\"error\", (err) => {\n controller.error(err);\n });\n },\n cancel() {\n nodeStream.destroy();\n },\n });\n}\n\n/**\n * Spawn a child process with a consistent API across Bun and Node.js.\n *\n * @param argv - Command and arguments as array (first element is the command)\n * @param options - Spawn options (cwd, stdin, stdout, stderr)\n * @returns SpawnResult with exited promise, streams, and kill function\n */\nexport function spawn(argv: string[], options: SpawnOptions = {}): SpawnResult {\n if (isBun) {\n // Use Bun's native spawn with type-safe adapter\n return adaptBunProcess(Bun.spawn(argv, options));\n }\n\n // Node.js fallback\n const [command, ...args] = argv;\n const proc = nodeSpawn(command, args, {\n cwd: options.cwd,\n stdio: [\n options.stdin === \"pipe\" ? \"pipe\" : options.stdin ?? \"ignore\",\n options.stdout === \"pipe\" ? \"pipe\" : options.stdout ?? \"ignore\",\n options.stderr === \"pipe\" ? \"pipe\" : options.stderr ?? \"ignore\",\n ],\n });\n\n // Create exited promise\n const exited = new Promise<number>((resolve, reject) => {\n proc.on(\"exit\", (code) => {\n resolve(code ?? 1);\n });\n proc.on(\"error\", (err) => {\n reject(err);\n });\n });\n\n // Create stdin wrapper\n const stdin: SpawnStdin | null = proc.stdin\n ? {\n write(data: string) {\n proc.stdin?.write(data);\n },\n end() {\n proc.stdin?.end();\n },\n }\n : null;\n\n return {\n exited,\n stdout: nodeStreamToReadableStream(proc.stdout),\n stderr: nodeStreamToReadableStream(proc.stderr),\n stdin,\n kill() {\n proc.kill();\n },\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Exception thrown when a path validation fails due to sandbox constraints.\n * This ensures all file operations are restricted to the current working directory.\n */\nexport class PathSandboxException extends Error {\n constructor(inputPath: string, reason: string) {\n super(`Path access denied: ${inputPath}. ${reason}`);\n this.name = \"PathSandboxException\";\n }\n}\n\n/**\n * Validates that a given path is within the current working directory.\n * This prevents directory traversal attacks and ensures all file operations\n * are sandboxed to the CWD and its subdirectories.\n *\n * @param inputPath - Path to validate (can be relative or absolute)\n * @returns The validated absolute path\n * @throws PathSandboxException if the path is outside the CWD\n * @throws Error for other file system errors\n */\nexport function validatePathIsWithinCwd(inputPath: string): string {\n const cwd = process.cwd();\n const resolvedPath = path.resolve(cwd, inputPath);\n\n // Try to get the real path to handle symlinks securely\n let finalPath: string;\n try {\n finalPath = fs.realpathSync(resolvedPath);\n } catch (error) {\n // If path doesn't exist, use the resolved path for validation\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code === \"ENOENT\") {\n finalPath = resolvedPath;\n } else {\n // Re-throw other errors (permission denied, etc.)\n throw error;\n }\n }\n\n // Ensure the path is within CWD or is CWD itself\n // Use path.sep to prevent matching partial directory names\n const cwdWithSep = cwd + path.sep;\n if (!finalPath.startsWith(cwdWithSep) && finalPath !== cwd) {\n throw new PathSandboxException(inputPath, \"Path is outside the current working directory\");\n }\n\n return finalPath;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { createGadget } from \"llmist\";\nimport { validatePathIsWithinCwd } from \"./utils.js\";\n\n/**\n * Represents metadata for a file system entry\n */\ninterface FileEntry {\n name: string;\n relativePath: string;\n type: \"file\" | \"directory\" | \"symlink\";\n size: number;\n modified: number; // Unix epoch seconds\n}\n\n/**\n * Lists all files and directories in a given path with optional recursion.\n * Skips entries that cannot be accessed due to permissions.\n *\n * @param dirPath - Absolute path to the directory\n * @param basePath - Base path for calculating relative paths (defaults to dirPath)\n * @param maxDepth - Maximum depth to recurse (1 = immediate children only)\n * @param currentDepth - Current recursion depth (internal use)\n * @returns Array of file entries with metadata\n */\nfunction listFiles(\n dirPath: string,\n basePath: string = dirPath,\n maxDepth: number = 1,\n currentDepth: number = 1,\n): FileEntry[] {\n const entries: FileEntry[] = [];\n\n try {\n const items = fs.readdirSync(dirPath);\n\n for (const item of items) {\n const fullPath = path.join(dirPath, item);\n const relativePath = path.relative(basePath, fullPath);\n\n try {\n const stats = fs.lstatSync(fullPath);\n let type: \"file\" | \"directory\" | \"symlink\";\n let size: number;\n\n if (stats.isSymbolicLink()) {\n type = \"symlink\";\n size = 0;\n } else if (stats.isDirectory()) {\n type = \"directory\";\n size = 0;\n } else {\n type = \"file\";\n size = stats.size;\n }\n\n entries.push({\n name: item,\n relativePath,\n type,\n size,\n modified: Math.floor(stats.mtime.getTime() / 1000),\n });\n\n // Recurse into directories if we haven't reached max depth\n if (type === \"directory\" && currentDepth < maxDepth) {\n // Validate subdirectory is still within CWD (security check)\n try {\n validatePathIsWithinCwd(fullPath);\n const subEntries = listFiles(fullPath, basePath, maxDepth, currentDepth + 1);\n entries.push(...subEntries);\n } catch {\n // Skip directories outside CWD or inaccessible\n }\n }\n } catch {\n // Skip entries that can't be accessed (permission denied, etc.)\n }\n }\n } catch {\n // If we can't read the directory, return empty array\n return [];\n }\n\n return entries;\n}\n\n/**\n * Formats age from Unix epoch timestamp to human-readable string.\n * Uses compact format: 5m, 2h, 3d, 2w, 4mo, 1y\n *\n * @param epochSeconds - Unix timestamp in seconds\n * @returns Compact age string\n */\nfunction formatAge(epochSeconds: number): string {\n const now = Math.floor(Date.now() / 1000);\n const seconds = now - epochSeconds;\n\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d`;\n const weeks = Math.floor(days / 7);\n if (weeks < 4) return `${weeks}w`;\n const months = Math.floor(days / 30);\n if (months < 12) return `${months}mo`;\n const years = Math.floor(days / 365);\n return `${years}y`;\n}\n\n/**\n * Formats file entries as a compact pipe-separated DSL.\n * Format: #T|N|S|A header (Type, Name, Size, Age)\n * Optimized for LLM token efficiency (~70% savings vs table format).\n *\n * @param entries - Array of file entries to format\n * @returns Compact DSL string\n */\nfunction formatEntriesAsString(entries: FileEntry[]): string {\n if (entries.length === 0) {\n return \"#empty\";\n }\n\n // Sort: directories first, then files, then symlinks, alphabetically within each\n const sortedEntries = [...entries].sort((a, b) => {\n const typeOrder = { directory: 0, file: 1, symlink: 2 };\n const typeCompare = typeOrder[a.type] - typeOrder[b.type];\n if (typeCompare !== 0) return typeCompare;\n return a.relativePath.localeCompare(b.relativePath);\n });\n\n // Type code mapping\n const typeCode: Record<FileEntry[\"type\"], string> = {\n directory: \"D\",\n file: \"F\",\n symlink: \"L\",\n };\n\n // URL-encode special chars that would break parsing\n const encodeName = (name: string) => name.replace(/\\|/g, \"%7C\").replace(/\\n/g, \"%0A\");\n\n // Build compact output\n const header = \"#T|N|S|A\";\n const rows = sortedEntries.map(\n (e) => `${typeCode[e.type]}|${encodeName(e.relativePath)}|${e.size}|${formatAge(e.modified)}`,\n );\n\n return [header, ...rows].join(\"\\n\");\n}\n\n/**\n * ListDirectory gadget - Lists files and directories with full metadata.\n * All directory paths are validated to be within the current working directory.\n */\nexport const listDirectory = createGadget({\n name: \"ListDirectory\",\n description:\n \"List files and directories in a directory with full details (names, types, sizes, modification dates). Use maxDepth to explore subdirectories recursively. The directory path must be within the current working directory or its subdirectories.\",\n schema: z.object({\n directoryPath: z.string().default(\".\").describe(\"Path to the directory to list\"),\n maxDepth: z\n .number()\n .int()\n .min(1)\n .max(10)\n .default(1)\n .describe(\n \"Maximum depth to recurse (1 = immediate children only, 2 = include grandchildren, etc.)\",\n ),\n }),\n examples: [\n {\n params: { directoryPath: \".\", maxDepth: 1 },\n output: \"path=. maxDepth=1\\n\\n#T|N|S|A\\nD|src|0|2h\\nD|tests|0|1d\\nF|package.json|2841|3h\",\n comment: \"List current directory\",\n },\n {\n params: { directoryPath: \"src\", maxDepth: 2 },\n output:\n \"path=src maxDepth=2\\n\\n#T|N|S|A\\nD|components|0|1d\\nD|utils|0|2d\\nF|index.ts|512|1h\\nF|components/Button.tsx|1024|3h\",\n comment: \"List src directory recursively\",\n },\n ],\n execute: ({ directoryPath, maxDepth }) => {\n // Validate path is within CWD\n const validatedPath = validatePathIsWithinCwd(directoryPath);\n\n // Verify it's actually a directory\n const stats = fs.statSync(validatedPath);\n if (!stats.isDirectory()) {\n throw new Error(`Path is not a directory: ${directoryPath}`);\n }\n\n // List files and format output\n const entries = listFiles(validatedPath, validatedPath, maxDepth);\n const formattedList = formatEntriesAsString(entries);\n\n // Show params on first line, listing follows\n return `path=${directoryPath} maxDepth=${maxDepth}\\n\\n${formattedList}`;\n },\n});\n","import fs from \"node:fs\";\nimport { z } from \"zod\";\nimport { createGadget } from \"llmist\";\nimport { validatePathIsWithinCwd } from \"./utils.js\";\n\n/**\n * ReadFile gadget - Reads the entire content of a file and returns it as text.\n * All file paths are validated to be within the current working directory.\n */\nexport const readFile = createGadget({\n name: \"ReadFile\",\n description:\n \"Read the entire content of a file and return it as text. The file path must be within the current working directory or its subdirectories.\",\n schema: z.object({\n filePath: z.string().describe(\"Path to the file to read (relative or absolute)\"),\n }),\n examples: [\n {\n params: { filePath: \"package.json\" },\n output: 'path=package.json\\n\\n{\\n \"name\": \"my-project\",\\n \"version\": \"1.0.0\"\\n ...\\n}',\n comment: \"Read a JSON config file\",\n },\n {\n params: { filePath: \"src/index.ts\" },\n output: \"path=src/index.ts\\n\\nexport function main() { ... }\",\n comment: \"Read a source file\",\n },\n ],\n execute: ({ filePath }) => {\n // Validate path is within CWD\n const validatedPath = validatePathIsWithinCwd(filePath);\n\n // Read and return file content\n const content = fs.readFileSync(validatedPath, \"utf-8\");\n\n // Show params on first line, content follows\n return `path=${filePath}\\n\\n${content}`;\n },\n});\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { createGadget } from \"llmist\";\nimport { validatePathIsWithinCwd } from \"./utils.js\";\n\n/**\n * WriteFile gadget - Writes content to a file.\n * Creates parent directories if needed. Overwrites existing files.\n * All file paths are validated to be within the current working directory.\n */\nexport const writeFile = createGadget({\n name: \"WriteFile\",\n description:\n \"Write content to a file. Creates parent directories if needed. Overwrites existing files. The file path must be within the current working directory or its subdirectories.\",\n schema: z.object({\n filePath: z.string().describe(\"Path to the file to write (relative or absolute)\"),\n content: z.string().describe(\"Content to write to the file\"),\n }),\n examples: [\n {\n params: { filePath: \"output.txt\", content: \"Hello, World!\" },\n output: \"path=output.txt\\n\\nWrote 13 bytes\",\n comment: \"Write a simple text file\",\n },\n {\n params: {\n filePath: \"src/server.ts\",\n content: `import { serve } from \"bun\";\n\nconst port = 3000;\n\nserve({\n port,\n fetch: (req) => new Response(\\`Hello from \\${req.url}\\`),\n});\n\nconsole.log(\\`Server running on http://localhost:\\${port}\\`);`,\n },\n output: \"path=src/server.ts\\n\\nWrote 198 bytes (created directory: src)\",\n comment:\n \"Write code with template literals - NO escaping needed inside heredoc (use <<<EOF...EOF)\",\n },\n ],\n execute: ({ filePath, content }) => {\n // Validate path is within CWD\n const validatedPath = validatePathIsWithinCwd(filePath);\n\n // Ensure parent directory exists (create if needed)\n const parentDir = path.dirname(validatedPath);\n let createdDir = false;\n if (!fs.existsSync(parentDir)) {\n // Validate parent dir is also within CWD before creating\n validatePathIsWithinCwd(parentDir);\n fs.mkdirSync(parentDir, { recursive: true });\n createdDir = true;\n }\n\n // Write the file\n fs.writeFileSync(validatedPath, content, \"utf-8\");\n const bytesWritten = Buffer.byteLength(content, \"utf-8\");\n\n // Format output following the established pattern\n const dirNote = createdDir ? ` (created directory: ${path.dirname(filePath)})` : \"\";\n return `path=${filePath}\\n\\nWrote ${bytesWritten} bytes${dirNote}`;\n },\n});\n","import { z } from \"zod\";\nimport { createGadget } from \"llmist\";\nimport { spawn } from \"../spawn.js\";\n\n/**\n * RunCommand gadget - Executes a command with arguments and returns its output.\n *\n * Uses argv array to bypass shell interpretation entirely - arguments are\n * passed directly to the process without any escaping or shell expansion.\n * This allows special characters (quotes, backticks, newlines) to work correctly.\n *\n * Safety should be added externally via the hook system (see example 10).\n *\n * Output format follows the established pattern: `status=N\\n\\n<output>`\n */\nexport const runCommand = createGadget({\n name: \"RunCommand\",\n description:\n \"Execute a command with arguments and return its output. Uses argv array to bypass shell - arguments are passed directly without interpretation. Returns stdout/stderr combined with exit status.\",\n schema: z.object({\n argv: z\n .array(z.string())\n .describe(\"Command and arguments as array (e.g., ['git', 'commit', '-m', 'message'])\"),\n cwd: z\n .string()\n .optional()\n .describe(\"Working directory for the command (default: current directory)\"),\n timeout: z.number().default(30000).describe(\"Timeout in milliseconds (default: 30000)\"),\n }),\n examples: [\n {\n params: { argv: [\"ls\", \"-la\"], timeout: 30000 },\n output:\n \"status=0\\n\\ntotal 24\\ndrwxr-xr-x 5 user staff 160 Nov 27 10:00 .\\ndrwxr-xr-x 3 user staff 96 Nov 27 09:00 ..\\n-rw-r--r-- 1 user staff 1024 Nov 27 10:00 package.json\",\n comment: \"List directory contents with details\",\n },\n {\n params: { argv: [\"echo\", \"Hello World\"], timeout: 30000 },\n output: \"status=0\\n\\nHello World\",\n comment: \"Echo without shell - argument passed directly\",\n },\n {\n params: { argv: [\"cat\", \"nonexistent.txt\"], timeout: 30000 },\n output: \"status=1\\n\\ncat: nonexistent.txt: No such file or directory\",\n comment: \"Command that fails returns non-zero status\",\n },\n {\n params: { argv: [\"pwd\"], cwd: \"/tmp\", timeout: 30000 },\n output: \"status=0\\n\\n/tmp\",\n comment: \"Execute command in a specific directory\",\n },\n {\n params: {\n argv: [\n \"gh\",\n \"pr\",\n \"review\",\n \"123\",\n \"--comment\",\n \"--body\",\n \"Review with `backticks` and 'quotes'\",\n ],\n timeout: 30000,\n },\n output: \"status=0\\n\\n(no output)\",\n comment: \"Complex arguments with special characters - no escaping needed\",\n },\n {\n params: {\n argv: [\n \"gh\",\n \"pr\",\n \"review\",\n \"123\",\n \"--approve\",\n \"--body\",\n \"## Review Summary\\n\\n**Looks good!**\\n\\n- Clean code\\n- Tests pass\",\n ],\n timeout: 30000,\n },\n output: \"status=0\\n\\nApproving pull request #123\",\n comment: \"Multiline body: --body flag and content must be SEPARATE array elements\",\n },\n ],\n execute: async ({ argv, cwd, timeout }) => {\n const workingDir = cwd ?? process.cwd();\n\n if (argv.length === 0) {\n return \"status=1\\n\\nerror: argv array cannot be empty\";\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n try {\n // Spawn process directly without shell - arguments passed as-is\n const proc = spawn(argv, {\n cwd: workingDir,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n // Create a timeout promise with cleanup\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n proc.kill();\n reject(new Error(`Command timed out after ${timeout}ms`));\n }, timeout);\n });\n\n // Wait for process and consume streams concurrently to prevent deadlock.\n // If we await proc.exited first, large output can fill pipe buffers,\n // causing the process to block on write while we block on exit.\n const [exitCode, stdout, stderr] = await Promise.race([\n Promise.all([\n proc.exited,\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n ]),\n timeoutPromise,\n ]);\n\n // Clear timeout on normal exit to prevent dangling timer\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Combine output (stdout first, then stderr if any)\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n\n return `status=${exitCode}\\n\\n${output || \"(no output)\"}`;\n } catch (error) {\n // Clear timeout on error path too\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n const message = error instanceof Error ? error.message : String(error);\n return `status=1\\n\\nerror: ${message}`;\n }\n },\n});\n"],"mappings":";AAAA,SAAS,SAAS;AAClB,SAAS,oBAAoB;;;ACS7B,SAAS,SAAS,iBAAiB;AAMnC,IAAM,QAAQ,OAAO,QAAQ;AAoD7B,SAAS,gBAAgB,MAMT;AACd,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,UAAU;AAAA,IACvB,QAAQ,KAAK,UAAU;AAAA,IACvB,OAAO,KAAK,QACR;AAAA,MACE,MAAM,MAAc;AAClB,aAAK,OAAO,MAAM,IAAI;AAAA,MACxB;AAAA,MACA,MAAM;AACJ,aAAK,OAAO,IAAI;AAAA,MAClB;AAAA,IACF,IACA;AAAA,IACJ,MAAM,MAAM,KAAK,KAAK;AAAA,EACxB;AACF;AAKA,SAAS,2BAA2B,YAAgE;AAClG,MAAI,CAAC,WAAY,QAAO;AAExB,SAAO,IAAI,eAA2B;AAAA,IACpC,MAAM,YAAY;AAChB,iBAAW,GAAG,QAAQ,CAAC,UAAkB;AACvC,mBAAW,QAAQ,IAAI,WAAW,KAAK,CAAC;AAAA,MAC1C,CAAC;AACD,iBAAW,GAAG,OAAO,MAAM;AACzB,mBAAW,MAAM;AAAA,MACnB,CAAC;AACD,iBAAW,GAAG,SAAS,CAAC,QAAQ;AAC9B,mBAAW,MAAM,GAAG;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,IACA,SAAS;AACP,iBAAW,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AASO,SAAS,MAAM,MAAgB,UAAwB,CAAC,GAAgB;AAC7E,MAAI,OAAO;AAET,WAAO,gBAAgB,IAAI,MAAM,MAAM,OAAO,CAAC;AAAA,EACjD;AAGA,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAC3B,QAAM,OAAO,UAAU,SAAS,MAAM;AAAA,IACpC,KAAK,QAAQ;AAAA,IACb,OAAO;AAAA,MACL,QAAQ,UAAU,SAAS,SAAS,QAAQ,SAAS;AAAA,MACrD,QAAQ,WAAW,SAAS,SAAS,QAAQ,UAAU;AAAA,MACvD,QAAQ,WAAW,SAAS,SAAS,QAAQ,UAAU;AAAA,IACzD;AAAA,EACF,CAAC;AAGD,QAAM,SAAS,IAAI,QAAgB,CAAC,SAAS,WAAW;AACtD,SAAK,GAAG,QAAQ,CAAC,SAAS;AACxB,cAAQ,QAAQ,CAAC;AAAA,IACnB,CAAC;AACD,SAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,aAAO,GAAG;AAAA,IACZ,CAAC;AAAA,EACH,CAAC;AAGD,QAAM,QAA2B,KAAK,QAClC;AAAA,IACE,MAAM,MAAc;AAClB,WAAK,OAAO,MAAM,IAAI;AAAA,IACxB;AAAA,IACA,MAAM;AACJ,WAAK,OAAO,IAAI;AAAA,IAClB;AAAA,EACF,IACA;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,2BAA2B,KAAK,MAAM;AAAA,IAC9C,QAAQ,2BAA2B,KAAK,MAAM;AAAA,IAC9C;AAAA,IACA,OAAO;AACL,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AACF;;;AC5KA,OAAO,QAAQ;AACf,OAAO,UAAU;AAMV,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAY,WAAmB,QAAgB;AAC7C,UAAM,uBAAuB,SAAS,KAAK,MAAM,EAAE;AACnD,SAAK,OAAO;AAAA,EACd;AACF;AAYO,SAAS,wBAAwB,WAA2B;AACjE,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,eAAe,KAAK,QAAQ,KAAK,SAAS;AAGhD,MAAI;AACJ,MAAI;AACF,gBAAY,GAAG,aAAa,YAAY;AAAA,EAC1C,SAAS,OAAO;AAEd,UAAM,YAAY;AAClB,QAAI,UAAU,SAAS,UAAU;AAC/B,kBAAY;AAAA,IACd,OAAO;AAEL,YAAM;AAAA,IACR;AAAA,EACF;AAIA,QAAM,aAAa,MAAM,KAAK;AAC9B,MAAI,CAAC,UAAU,WAAW,UAAU,KAAK,cAAc,KAAK;AAC1D,UAAM,IAAI,qBAAqB,WAAW,+CAA+C;AAAA,EAC3F;AAEA,SAAO;AACT;;;AF1CA,SAAS,wBAAwB,UAA0B;AACzD,SAAO,SACJ,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,WAAW,GAAG,CAAC,EAClD,KAAK,IAAI;AACd;AAEO,IAAM,WAAW,aAAa;AAAA,EACnC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQ,EAAE,OAAO;AAAA,IACf,UAAU,EAAE,OAAO,EAAE,SAAS,iDAAiD;AAAA,IAC/E,UAAU,EAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,EACtE,CAAC;AAAA,EACD,UAAU;AAAA,IACR;AAAA,MACE,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,UAAU;AAAA;AAAA,MAEZ;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,UAAU;AAAA;AAAA;AAAA,MAGZ;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,UAAU;AAAA;AAAA;AAAA,MAGZ;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,MAKZ;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,WAAW;AAAA,EACX,SAAS,OAAO,EAAE,UAAU,SAAS,MAAM;AACzC,UAAM,gBAAgB,wBAAwB,QAAQ;AACtD,UAAM,eAAe,wBAAwB,QAAQ;AAErD,QAAI;AACF,YAAM,OAAO,MAAM,CAAC,MAAM,aAAa,GAAG;AAAA,QACxC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAGD,UAAI,CAAC,KAAK,OAAO;AACf,eAAO,QAAQ,QAAQ;AAAA;AAAA;AAAA,MACzB;AACA,WAAK,MAAM,MAAM,GAAG,YAAY;AAAA,CAAI;AACpC,WAAK,MAAM,IAAI;AAGf,UAAI;AACJ,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,oBAAY,WAAW,MAAM;AAC3B,eAAK,KAAK;AACV,iBAAO,IAAI,MAAM,oCAAoC,CAAC;AAAA,QACxD,GAAG,GAAK;AAAA,MACV,CAAC;AAKD,YAAM,CAAC,UAAU,QAAQ,MAAM,IAAI,MAAM,QAAQ,KAAK;AAAA,QACpD,QAAQ,IAAI;AAAA,UACV,KAAK;AAAA,UACL,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,UAC/B,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,QACjC,CAAC;AAAA,QACD;AAAA,MACF,CAAC;AAGD,UAAI,WAAW;AACb,qBAAa,SAAS;AAAA,MACxB;AAEA,YAAM,SAAS,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK;AAEhE,UAAI,aAAa,GAAG;AAClB,eAAO,QAAQ,QAAQ;AAAA;AAAA,EAAO,UAAU,gCAAgC;AAAA,MAC1E;AAEA,aAAO,QAAQ,QAAQ;AAAA;AAAA,EAAO,UAAU,aAAa;AAAA,IACvD,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,aAAO,QAAQ,QAAQ;AAAA;AAAA,SAAc,OAAO;AAAA,IAC9C;AAAA,EACF;AACF,CAAC;;;AG5HD,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,KAAAC,UAAS;AAClB,SAAS,gBAAAC,qBAAoB;AAwB7B,SAAS,UACP,SACA,WAAmB,SACnB,WAAmB,GACnB,eAAuB,GACV;AACb,QAAM,UAAuB,CAAC;AAE9B,MAAI;AACF,UAAM,QAAQC,IAAG,YAAY,OAAO;AAEpC,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAWC,MAAK,KAAK,SAAS,IAAI;AACxC,YAAM,eAAeA,MAAK,SAAS,UAAU,QAAQ;AAErD,UAAI;AACF,cAAM,QAAQD,IAAG,UAAU,QAAQ;AACnC,YAAI;AACJ,YAAI;AAEJ,YAAI,MAAM,eAAe,GAAG;AAC1B,iBAAO;AACP,iBAAO;AAAA,QACT,WAAW,MAAM,YAAY,GAAG;AAC9B,iBAAO;AACP,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AACP,iBAAO,MAAM;AAAA,QACf;AAEA,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU,KAAK,MAAM,MAAM,MAAM,QAAQ,IAAI,GAAI;AAAA,QACnD,CAAC;AAGD,YAAI,SAAS,eAAe,eAAe,UAAU;AAEnD,cAAI;AACF,oCAAwB,QAAQ;AAChC,kBAAM,aAAa,UAAU,UAAU,UAAU,UAAU,eAAe,CAAC;AAC3E,oBAAQ,KAAK,GAAG,UAAU;AAAA,UAC5B,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAEN,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;AASA,SAAS,UAAU,cAA8B;AAC/C,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,UAAU,MAAM;AAEtB,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,QAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,MAAI,OAAO,EAAG,QAAO,GAAG,IAAI;AAC5B,QAAM,QAAQ,KAAK,MAAM,OAAO,CAAC;AACjC,MAAI,QAAQ,EAAG,QAAO,GAAG,KAAK;AAC9B,QAAM,SAAS,KAAK,MAAM,OAAO,EAAE;AACnC,MAAI,SAAS,GAAI,QAAO,GAAG,MAAM;AACjC,QAAM,QAAQ,KAAK,MAAM,OAAO,GAAG;AACnC,SAAO,GAAG,KAAK;AACjB;AAUA,SAAS,sBAAsB,SAA8B;AAC3D,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AAChD,UAAM,YAAY,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAAE;AACtD,UAAM,cAAc,UAAU,EAAE,IAAI,IAAI,UAAU,EAAE,IAAI;AACxD,QAAI,gBAAgB,EAAG,QAAO;AAC9B,WAAO,EAAE,aAAa,cAAc,EAAE,YAAY;AAAA,EACpD,CAAC;AAGD,QAAM,WAA8C;AAAA,IAClD,WAAW;AAAA,IACX,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAGA,QAAM,aAAa,CAAC,SAAiB,KAAK,QAAQ,OAAO,KAAK,EAAE,QAAQ,OAAO,KAAK;AAGpF,QAAM,SAAS;AACf,QAAM,OAAO,cAAc;AAAA,IACzB,CAAC,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC,IAAI,WAAW,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,IAAI,UAAU,EAAE,QAAQ,CAAC;AAAA,EAC7F;AAEA,SAAO,CAAC,QAAQ,GAAG,IAAI,EAAE,KAAK,IAAI;AACpC;AAMO,IAAM,gBAAgBE,cAAa;AAAA,EACxC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQC,GAAE,OAAO;AAAA,IACf,eAAeA,GAAE,OAAO,EAAE,QAAQ,GAAG,EAAE,SAAS,+BAA+B;AAAA,IAC/E,UAAUA,GACP,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,QAAQ,CAAC,EACT;AAAA,MACC;AAAA,IACF;AAAA,EACJ,CAAC;AAAA,EACD,UAAU;AAAA,IACR;AAAA,MACE,QAAQ,EAAE,eAAe,KAAK,UAAU,EAAE;AAAA,MAC1C,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,eAAe,OAAO,UAAU,EAAE;AAAA,MAC5C,QACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,SAAS,CAAC,EAAE,eAAe,SAAS,MAAM;AAExC,UAAM,gBAAgB,wBAAwB,aAAa;AAG3D,UAAM,QAAQH,IAAG,SAAS,aAAa;AACvC,QAAI,CAAC,MAAM,YAAY,GAAG;AACxB,YAAM,IAAI,MAAM,4BAA4B,aAAa,EAAE;AAAA,IAC7D;AAGA,UAAM,UAAU,UAAU,eAAe,eAAe,QAAQ;AAChE,UAAM,gBAAgB,sBAAsB,OAAO;AAGnD,WAAO,QAAQ,aAAa,aAAa,QAAQ;AAAA;AAAA,EAAO,aAAa;AAAA,EACvE;AACF,CAAC;;;AC7MD,OAAOI,SAAQ;AACf,SAAS,KAAAC,UAAS;AAClB,SAAS,gBAAAC,qBAAoB;AAOtB,IAAM,WAAWC,cAAa;AAAA,EACnC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQC,GAAE,OAAO;AAAA,IACf,UAAUA,GAAE,OAAO,EAAE,SAAS,iDAAiD;AAAA,EACjF,CAAC;AAAA,EACD,UAAU;AAAA,IACR;AAAA,MACE,QAAQ,EAAE,UAAU,eAAe;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,UAAU,eAAe;AAAA,MACnC,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,SAAS,CAAC,EAAE,SAAS,MAAM;AAEzB,UAAM,gBAAgB,wBAAwB,QAAQ;AAGtD,UAAM,UAAUC,IAAG,aAAa,eAAe,OAAO;AAGtD,WAAO,QAAQ,QAAQ;AAAA;AAAA,EAAO,OAAO;AAAA,EACvC;AACF,CAAC;;;ACtCD,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,KAAAC,UAAS;AAClB,SAAS,gBAAAC,qBAAoB;AAQtB,IAAM,YAAYC,cAAa;AAAA,EACpC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQC,GAAE,OAAO;AAAA,IACf,UAAUA,GAAE,OAAO,EAAE,SAAS,kDAAkD;AAAA,IAChF,SAASA,GAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,EAC7D,CAAC;AAAA,EACD,UAAU;AAAA,IACR;AAAA,MACE,QAAQ,EAAE,UAAU,cAAc,SAAS,gBAAgB;AAAA,MAC3D,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUX;AAAA,MACA,QAAQ;AAAA,MACR,SACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,SAAS,CAAC,EAAE,UAAU,QAAQ,MAAM;AAElC,UAAM,gBAAgB,wBAAwB,QAAQ;AAGtD,UAAM,YAAYC,MAAK,QAAQ,aAAa;AAC5C,QAAI,aAAa;AACjB,QAAI,CAACC,IAAG,WAAW,SAAS,GAAG;AAE7B,8BAAwB,SAAS;AACjC,MAAAA,IAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAC3C,mBAAa;AAAA,IACf;AAGA,IAAAA,IAAG,cAAc,eAAe,SAAS,OAAO;AAChD,UAAM,eAAe,OAAO,WAAW,SAAS,OAAO;AAGvD,UAAM,UAAU,aAAa,wBAAwBD,MAAK,QAAQ,QAAQ,CAAC,MAAM;AACjF,WAAO,QAAQ,QAAQ;AAAA;AAAA,QAAa,YAAY,SAAS,OAAO;AAAA,EAClE;AACF,CAAC;;;AClED,SAAS,KAAAE,UAAS;AAClB,SAAS,gBAAAC,qBAAoB;AActB,IAAM,aAAaC,cAAa;AAAA,EACrC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQC,GAAE,OAAO;AAAA,IACf,MAAMA,GACH,MAAMA,GAAE,OAAO,CAAC,EAChB,SAAS,2EAA2E;AAAA,IACvF,KAAKA,GACF,OAAO,EACP,SAAS,EACT,SAAS,gEAAgE;AAAA,IAC5E,SAASA,GAAE,OAAO,EAAE,QAAQ,GAAK,EAAE,SAAS,0CAA0C;AAAA,EACxF,CAAC;AAAA,EACD,UAAU;AAAA,IACR;AAAA,MACE,QAAQ,EAAE,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,IAAM;AAAA,MAC9C,QACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,MAAM,CAAC,QAAQ,aAAa,GAAG,SAAS,IAAM;AAAA,MACxD,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,MAAM,CAAC,OAAO,iBAAiB,GAAG,SAAS,IAAM;AAAA,MAC3D,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,MAAM,CAAC,KAAK,GAAG,KAAK,QAAQ,SAAS,IAAM;AAAA,MACrD,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,SAAS,OAAO,EAAE,MAAM,KAAK,QAAQ,MAAM;AACzC,UAAM,aAAa,OAAO,QAAQ,IAAI;AAEtC,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,QAAI;AAEJ,QAAI;AAEF,YAAM,OAAO,MAAM,MAAM;AAAA,QACvB,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAGD,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,oBAAY,WAAW,MAAM;AAC3B,eAAK,KAAK;AACV,iBAAO,IAAI,MAAM,2BAA2B,OAAO,IAAI,CAAC;AAAA,QAC1D,GAAG,OAAO;AAAA,MACZ,CAAC;AAKD,YAAM,CAAC,UAAU,QAAQ,MAAM,IAAI,MAAM,QAAQ,KAAK;AAAA,QACpD,QAAQ,IAAI;AAAA,UACV,KAAK;AAAA,UACL,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,UAC/B,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,QACjC,CAAC;AAAA,QACD;AAAA,MACF,CAAC;AAGD,UAAI,WAAW;AACb,qBAAa,SAAS;AAAA,MACxB;AAGA,YAAM,SAAS,CAAC,QAAQ,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK;AAEhE,aAAO,UAAU,QAAQ;AAAA;AAAA,EAAO,UAAU,aAAa;AAAA,IACzD,SAAS,OAAO;AAEd,UAAI,WAAW;AACb,qBAAa,SAAS;AAAA,MACxB;AACA,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,aAAO;AAAA;AAAA,SAAsB,OAAO;AAAA,IACtC;AAAA,EACF;AACF,CAAC;","names":["fs","path","z","createGadget","fs","path","createGadget","z","fs","z","createGadget","createGadget","z","fs","fs","path","z","createGadget","createGadget","z","path","fs","z","createGadget","createGadget","z"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmist/cli",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.3.1",
|
|
4
4
|
"description": "CLI for llmist - run LLM agents from the command line",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli.js",
|
|
@@ -8,6 +8,20 @@
|
|
|
8
8
|
"bin": {
|
|
9
9
|
"llmist": "dist/cli.js"
|
|
10
10
|
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/cli.d.ts",
|
|
15
|
+
"default": "./dist/cli.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./gadgets": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
11
25
|
"scripts": {
|
|
12
26
|
"build": "tsup",
|
|
13
27
|
"typecheck": "tsc --noEmit",
|