@nicnocquee/dataqueue 1.33.0 → 1.34.0

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,"sources":["../src/init-command.ts","../src/cli.ts"],"names":["path"],"mappings":"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","file":"cli.js","sourcesContent":["import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from 'fs';\nimport path from 'path';\n\ntype JsonObject = Record<string, unknown>;\ntype JsonMap = Record<string, string>;\n\nconst DEPENDENCIES_TO_ADD = [\n '@nicnocquee/dataqueue',\n '@nicnocquee/dataqueue-dashboard',\n '@nicnocquee/dataqueue-react',\n] as const;\n\nconst DEV_DEPENDENCIES_TO_ADD = [\n 'dotenv-cli',\n 'ts-node',\n 'node-pg-migrate',\n] as const;\n\nconst SCRIPTS_TO_ADD = {\n cron: 'bash cron.sh',\n 'migrate-dataqueue': 'dotenv -e .env.local -- dataqueue-cli migrate',\n} as const;\n\n/**\n * App router endpoint template for queue management.\n */\nexport const APP_ROUTER_ROUTE_TEMPLATE = `/**\n * This end point is used to manage the job queue.\n * It supports the following tasks:\n * - reclaim: Reclaim stuck jobs\n * - cleanup: Cleanup old jobs\n * - process: Process jobs\n *\n * Example usage with default values (reclaim stuck jobs for 10 minutes, cleanup old jobs for 30 days, and process jobs with batch size 3, concurrency 2, and verbose true):\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\"\n *\n * Example usage with custom values:\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"maxProcessingTimeMinutes\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"daysToKeep\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"batchSize\": 5, \"concurrency\": 3, \"verbose\": false, \"workerId\": \"custom-worker-id\"}' -H \"Content-Type: application/json\"\n *\n * During development, you can run the following script to run the cron jobs continuously in the background:\n * pnpm cron\n */\nimport { getJobQueue, jobHandlers } from '@/lib/dataqueue/queue';\nimport { NextResponse } from 'next/server';\n\nexport async function POST(\n request: Request,\n { params }: { params: Promise<{ task: string[] }> },\n) {\n const { task } = await params;\n const authHeader = request.headers.get('authorization');\n if (authHeader !== \\`Bearer \\${process.env.CRON_SECRET}\\`) {\n return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });\n }\n\n if (!task || task.length === 0) {\n return NextResponse.json({ message: 'Task is required' }, { status: 400 });\n }\n\n const supportedTasks = ['reclaim', 'cleanup', 'process'];\n const theTask = task[0];\n if (!supportedTasks.includes(theTask)) {\n return NextResponse.json(\n { message: 'Task not supported' },\n { status: 400 },\n );\n }\n\n try {\n const jobQueue = getJobQueue();\n\n if (theTask === 'reclaim') {\n let maxProcessingTimeMinutes = 10;\n try {\n const body = await request.json();\n maxProcessingTimeMinutes = body.maxProcessingTimeMinutes || 10;\n } catch {\n // ignore parsing error and use default value\n }\n const reclaimed = await jobQueue.reclaimStuckJobs(\n maxProcessingTimeMinutes,\n );\n console.log(\\`Reclaimed \\${reclaimed} stuck jobs\\`);\n return NextResponse.json({\n message: \\`Stuck jobs reclaimed: \\${reclaimed} with maxProcessingTimeMinutes: \\${maxProcessingTimeMinutes}\\`,\n reclaimed,\n });\n }\n\n if (theTask === 'cleanup') {\n let daysToKeep = 30;\n try {\n const body = await request.json();\n daysToKeep = body.daysToKeep || 30;\n } catch {\n // ignore parsing error and use default value\n }\n const deleted = await jobQueue.cleanupOldJobs(daysToKeep);\n console.log(\\`Deleted \\${deleted} old jobs\\`);\n return NextResponse.json({\n message: \\`Old jobs cleaned up: \\${deleted} with daysToKeep: \\${daysToKeep}\\`,\n deleted,\n });\n }\n\n if (theTask === 'process') {\n let batchSize = 3;\n let concurrency = 2;\n let verbose = true;\n let workerId = \\`manage-\\${theTask}-\\${Date.now()}\\`;\n try {\n const body = await request.json();\n batchSize = body.batchSize || 3;\n concurrency = body.concurrency || 2;\n verbose = body.verbose || true;\n workerId = body.workerId || \\`manage-\\${theTask}-\\${Date.now()}\\`;\n } catch {\n // ignore parsing error and use default value\n }\n const processor = jobQueue.createProcessor(jobHandlers, {\n workerId,\n batchSize,\n concurrency,\n verbose,\n });\n const processed = await processor.start();\n\n return NextResponse.json({\n message: \\`Jobs processed: \\${processed} with workerId: \\${workerId}, batchSize: \\${batchSize}, concurrency: \\${concurrency}, and verbose: \\${verbose}\\`,\n processed,\n });\n }\n\n return NextResponse.json(\n { message: 'Task not supported' },\n { status: 400 },\n );\n } catch (error) {\n console.error('Error processing jobs:', error);\n return NextResponse.json(\n { message: 'Failed to process jobs' },\n { status: 500 },\n );\n }\n}\n`;\n\n/**\n * Pages router endpoint template for queue management.\n */\nexport const PAGES_ROUTER_ROUTE_TEMPLATE = `/**\n * This end point is used to manage the job queue.\n * It supports the following tasks:\n * - reclaim: Reclaim stuck jobs\n * - cleanup: Cleanup old jobs\n * - process: Process jobs\n *\n * Example usage with default values (reclaim stuck jobs for 10 minutes, cleanup old jobs for 30 days, and process jobs with batch size 3, concurrency 2, and verbose true):\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\"\n *\n * Example usage with custom values:\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"maxProcessingTimeMinutes\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"daysToKeep\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"batchSize\": 5, \"concurrency\": 3, \"verbose\": false, \"workerId\": \"custom-worker-id\"}' -H \"Content-Type: application/json\"\n *\n * During development, you can run the following script to run the cron jobs continuously in the background:\n * pnpm cron\n */\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { getJobQueue, jobHandlers } from '@/lib/dataqueue/queue';\n\ntype ResponseBody = {\n message: string;\n reclaimed?: number;\n deleted?: number;\n processed?: number;\n};\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse<ResponseBody>,\n) {\n if (req.method !== 'POST') {\n res.setHeader('Allow', 'POST');\n return res.status(405).json({ message: 'Method not allowed' });\n }\n\n const authHeader = req.headers.authorization;\n if (authHeader !== \\`Bearer \\${process.env.CRON_SECRET}\\`) {\n return res.status(401).json({ message: 'Unauthorized' });\n }\n\n const task = req.query.task;\n const taskArray = Array.isArray(task) ? task : task ? [task] : [];\n if (!taskArray.length) {\n return res.status(400).json({ message: 'Task is required' });\n }\n\n const supportedTasks = ['reclaim', 'cleanup', 'process'];\n const theTask = taskArray[0];\n if (!supportedTasks.includes(theTask)) {\n return res.status(400).json({ message: 'Task not supported' });\n }\n\n try {\n const jobQueue = getJobQueue();\n const body = typeof req.body === 'object' && req.body ? req.body : {};\n\n if (theTask === 'reclaim') {\n const maxProcessingTimeMinutes = body.maxProcessingTimeMinutes || 10;\n const reclaimed = await jobQueue.reclaimStuckJobs(maxProcessingTimeMinutes);\n console.log(\\`Reclaimed \\${reclaimed} stuck jobs\\`);\n return res.status(200).json({\n message: \\`Stuck jobs reclaimed: \\${reclaimed} with maxProcessingTimeMinutes: \\${maxProcessingTimeMinutes}\\`,\n reclaimed,\n });\n }\n\n if (theTask === 'cleanup') {\n const daysToKeep = body.daysToKeep || 30;\n const deleted = await jobQueue.cleanupOldJobs(daysToKeep);\n console.log(\\`Deleted \\${deleted} old jobs\\`);\n return res.status(200).json({\n message: \\`Old jobs cleaned up: \\${deleted} with daysToKeep: \\${daysToKeep}\\`,\n deleted,\n });\n }\n\n const batchSize = body.batchSize || 3;\n const concurrency = body.concurrency || 2;\n const verbose = body.verbose || true;\n const workerId = body.workerId || \\`manage-\\${theTask}-\\${Date.now()}\\`;\n const processor = jobQueue.createProcessor(jobHandlers, {\n workerId,\n batchSize,\n concurrency,\n verbose,\n });\n const processed = await processor.start();\n\n return res.status(200).json({\n message: \\`Jobs processed: \\${processed} with workerId: \\${workerId}, batchSize: \\${batchSize}, concurrency: \\${concurrency}, and verbose: \\${verbose}\\`,\n processed,\n });\n } catch (error) {\n console.error('Error processing jobs:', error);\n return res.status(500).json({ message: 'Failed to process jobs' });\n }\n}\n`;\n\n/**\n * Cron script template for local queue processing.\n */\nexport const CRON_SH_TEMPLATE = `#!/bin/bash\n\n# This script is used to run the cron jobs for the demo app during development.\n# Run it with \\`pnpm cron\\` from the apps/demo directory.\n\nset -a\nsource \"$(dirname \"$0\")/.env.local\"\nset +a\n\nif [ -z \"$CRON_SECRET\" ]; then\n echo \"Error: CRON_SECRET environment variable is not set in .env.local\"\n exit 1\nfi\n\ncleanup() {\n kill 0\n wait\n}\ntrap cleanup SIGINT SIGTERM\n\nwhile true; do\n echo \"Processing jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/process -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 10 # Process jobs every 10 seconds\ndone &\n\nwhile true; do\n echo \"Reclaiming stuck jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/reclaim -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 20 # Reclaim stuck jobs every 20 seconds\ndone &\n\nwhile true; do\n echo \"Cleaning up old jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/cleanup -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 30 # Cleanup old jobs every 30 seconds\ndone &\n\nwait\n`;\n\n/**\n * Queue placeholder template with a single `send_email` job.\n */\nexport const QUEUE_TEMPLATE = `import { initJobQueue, JobHandlers } from '@nicnocquee/dataqueue';\n\nexport type JobPayloadMap = {\n send_email: {\n to: string;\n subject: string;\n body: string;\n };\n};\n\nlet jobQueue: ReturnType<typeof initJobQueue<JobPayloadMap>> | null = null;\n\nexport const getJobQueue = () => {\n if (!jobQueue) {\n jobQueue = initJobQueue<JobPayloadMap>({\n databaseConfig: {\n connectionString: process.env.PG_DATAQUEUE_DATABASE,\n },\n verbose: process.env.NODE_ENV === 'development',\n });\n }\n return jobQueue;\n};\n\nexport const jobHandlers: JobHandlers<JobPayloadMap> = {\n send_email: async (payload) => {\n const { to, subject, body } = payload;\n console.log('send_email placeholder:', { to, subject, body });\n },\n};\n`;\n\nexport interface InitDeps {\n log?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n exit?: (code: number) => void;\n cwd?: string;\n readFileSyncImpl?: typeof readFileSync;\n writeFileSyncImpl?: typeof writeFileSync;\n existsSyncImpl?: typeof existsSync;\n mkdirSyncImpl?: typeof mkdirSync;\n chmodSyncImpl?: typeof chmodSync;\n}\n\ntype RouterKind = 'app' | 'pages';\n\ninterface ProjectDetails {\n cwd: string;\n packageJsonPath: string;\n packageJson: JsonObject;\n srcRoot: string;\n router: RouterKind;\n}\n\n/**\n * Runs the `dataqueue-cli init` command.\n */\nexport function runInit({\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n cwd = process.cwd(),\n readFileSyncImpl = readFileSync,\n writeFileSyncImpl = writeFileSync,\n existsSyncImpl = existsSync,\n mkdirSyncImpl = mkdirSync,\n chmodSyncImpl = chmodSync,\n}: InitDeps = {}): void {\n try {\n log(`dataqueue: Initializing in ${cwd}...`);\n log('');\n\n const details = detectNextJsAndRouter({\n cwd,\n existsSyncImpl,\n readFileSyncImpl,\n });\n\n createScaffoldFiles({\n details,\n log,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n chmodSyncImpl,\n });\n\n updatePackageJson({\n details,\n log,\n writeFileSyncImpl,\n });\n\n log('');\n log(\n \"Done! Run your package manager's install command to install new dependencies.\",\n );\n exit(0);\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n error(`dataqueue: ${message}`);\n exit(1);\n }\n}\n\n/**\n * Detects that the current directory is a Next.js app and chooses the router.\n */\nexport function detectNextJsAndRouter({\n cwd,\n existsSyncImpl,\n readFileSyncImpl,\n}: {\n cwd: string;\n existsSyncImpl: typeof existsSync;\n readFileSyncImpl: typeof readFileSync;\n}): ProjectDetails {\n const packageJsonPath = path.join(cwd, 'package.json');\n if (!existsSyncImpl(packageJsonPath)) {\n throw new Error('package.json not found in current directory.');\n }\n\n const packageJson = parsePackageJson(\n readFileSyncImpl(packageJsonPath, 'utf8'),\n packageJsonPath,\n );\n if (!isNextJsProject(packageJson)) {\n throw new Error(\n \"Not a Next.js project. Could not find 'next' in package.json dependencies.\",\n );\n }\n\n const srcDir = path.join(cwd, 'src');\n const srcRoot = existsSyncImpl(srcDir) ? 'src' : '.';\n const appDir = path.join(cwd, srcRoot, 'app');\n const pagesDir = path.join(cwd, srcRoot, 'pages');\n const hasAppDir = existsSyncImpl(appDir);\n const hasPagesDir = existsSyncImpl(pagesDir);\n\n if (!hasAppDir && !hasPagesDir) {\n throw new Error(\n 'Could not detect Next.js router. Expected either app/ or pages/ directory.',\n );\n }\n\n const router: RouterKind = hasAppDir ? 'app' : 'pages';\n return { cwd, packageJsonPath, packageJson, srcRoot, router };\n}\n\n/**\n * Updates package.json with required dependencies and scripts.\n */\nfunction updatePackageJson({\n details,\n log,\n writeFileSyncImpl,\n}: {\n details: ProjectDetails;\n log: (...args: any[]) => void;\n writeFileSyncImpl: typeof writeFileSync;\n}): void {\n const packageJson = details.packageJson;\n const dependencies = ensureStringMapSection(packageJson, 'dependencies');\n const devDependencies = ensureStringMapSection(\n packageJson,\n 'devDependencies',\n );\n const scripts = ensureStringMapSection(packageJson, 'scripts');\n\n for (const dependency of DEPENDENCIES_TO_ADD) {\n if (dependencies[dependency]) {\n log(` [skipped] dependency ${dependency} (already exists)`);\n continue;\n }\n dependencies[dependency] = 'latest';\n log(` [added] dependency ${dependency}`);\n }\n\n for (const devDependency of DEV_DEPENDENCIES_TO_ADD) {\n if (devDependencies[devDependency]) {\n log(` [skipped] devDependency ${devDependency} (already exists)`);\n continue;\n }\n devDependencies[devDependency] = 'latest';\n log(` [added] devDependency ${devDependency}`);\n }\n\n for (const [scriptName, scriptValue] of Object.entries(SCRIPTS_TO_ADD)) {\n if (scripts[scriptName]) {\n log(` [skipped] script \"${scriptName}\" (already exists)`);\n continue;\n }\n scripts[scriptName] = scriptValue;\n log(` [added] script \"${scriptName}\"`);\n }\n\n writeFileSyncImpl(\n details.packageJsonPath,\n `${JSON.stringify(packageJson, null, 2)}\\n`,\n );\n}\n\n/**\n * Creates all scaffold files for the detected router without overwriting.\n */\nfunction createScaffoldFiles({\n details,\n log,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n chmodSyncImpl,\n}: {\n details: ProjectDetails;\n log: (...args: any[]) => void;\n existsSyncImpl: typeof existsSync;\n mkdirSyncImpl: typeof mkdirSync;\n writeFileSyncImpl: typeof writeFileSync;\n chmodSyncImpl: typeof chmodSync;\n}): void {\n const appRoutePath = path.join(\n details.cwd,\n details.srcRoot,\n 'app',\n 'api',\n 'dataqueue',\n 'manage',\n '[[...task]]',\n 'route.ts',\n );\n const pagesRoutePath = path.join(\n details.cwd,\n details.srcRoot,\n 'pages',\n 'api',\n 'dataqueue',\n 'manage',\n '[[...task]].ts',\n );\n const queuePath = path.join(\n details.cwd,\n details.srcRoot,\n 'lib',\n 'dataqueue',\n 'queue.ts',\n );\n const cronPath = path.join(details.cwd, 'cron.sh');\n\n if (details.router === 'app') {\n createFileIfMissing({\n absolutePath: appRoutePath,\n content: APP_ROUTER_ROUTE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, appRoutePath),\n });\n log(\n ' [skipped] pages/api/dataqueue/manage/[[...task]].ts (router not selected)',\n );\n } else {\n log(\n ' [skipped] app/api/dataqueue/manage/[[...task]]/route.ts (router not selected)',\n );\n createFileIfMissing({\n absolutePath: pagesRoutePath,\n content: PAGES_ROUTER_ROUTE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, pagesRoutePath),\n });\n }\n\n createFileIfMissing({\n absolutePath: cronPath,\n content: CRON_SH_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: 'cron.sh',\n });\n if (existsSyncImpl(cronPath)) {\n chmodSyncImpl(cronPath, 0o755);\n }\n\n createFileIfMissing({\n absolutePath: queuePath,\n content: QUEUE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, queuePath),\n });\n}\n\n/**\n * Creates a file only if it does not already exist.\n */\nfunction createFileIfMissing({\n absolutePath,\n content,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath,\n}: {\n absolutePath: string;\n content: string;\n existsSyncImpl: typeof existsSync;\n mkdirSyncImpl: typeof mkdirSync;\n writeFileSyncImpl: typeof writeFileSync;\n log: (...args: any[]) => void;\n logPath: string;\n}): void {\n if (existsSyncImpl(absolutePath)) {\n log(` [skipped] ${logPath} (already exists)`);\n return;\n }\n\n mkdirSyncImpl(path.dirname(absolutePath), { recursive: true });\n writeFileSyncImpl(absolutePath, content);\n log(` [created] ${logPath}`);\n}\n\n/**\n * Parses package.json content with clear source context.\n */\nfunction parsePackageJson(content: string, filePath: string): JsonObject {\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('package.json must contain an object.');\n }\n return parsed as JsonObject;\n } catch (cause) {\n throw new Error(\n `Failed to parse package.json at ${filePath}: ${\n cause instanceof Error ? cause.message : String(cause)\n }`,\n );\n }\n}\n\n/**\n * Returns true when package.json declares Next.js in deps or devDeps.\n */\nfunction isNextJsProject(packageJson: JsonObject): boolean {\n const dependencies = packageJson.dependencies;\n const devDependencies = packageJson.devDependencies;\n\n return (\n hasPackage(dependencies, 'next') || hasPackage(devDependencies, 'next')\n );\n}\n\n/**\n * Returns true when a package name exists in a dependency section object.\n */\nfunction hasPackage(section: unknown, packageName: string): boolean {\n if (!section || typeof section !== 'object' || Array.isArray(section)) {\n return false;\n }\n return Boolean((section as JsonMap)[packageName]);\n}\n\n/**\n * Ensures package.json has a string map section and returns it.\n */\nfunction ensureStringMapSection(\n packageJson: JsonObject,\n sectionName: 'dependencies' | 'devDependencies' | 'scripts',\n): JsonMap {\n const currentValue = packageJson[sectionName];\n if (\n !currentValue ||\n typeof currentValue !== 'object' ||\n Array.isArray(currentValue)\n ) {\n packageJson[sectionName] = {};\n }\n return packageJson[sectionName] as JsonMap;\n}\n\n/**\n * Converts an absolute path to a stable relative path for log output.\n */\nfunction toRelativePath(cwd: string, absolutePath: string): string {\n const relative = path.relative(cwd, absolutePath);\n return relative || '.';\n}\n","// Testable CLI logic for dataqueue\nimport { spawnSync, SpawnSyncReturns } from 'child_process';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { InitDeps, runInit } from './init-command.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface CliDeps {\n log?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n exit?: (code: number) => void;\n spawnSyncImpl?: (...args: any[]) => SpawnSyncReturns<any>;\n migrationsDir?: string;\n initDeps?: InitDeps;\n runInitImpl?: (deps?: InitDeps) => void;\n}\n\nexport function runCli(\n argv: string[],\n {\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n spawnSyncImpl = spawnSync,\n migrationsDir = path.join(__dirname, '../migrations'),\n initDeps,\n runInitImpl = runInit,\n }: CliDeps = {},\n): void {\n const [, , command, ...restArgs] = argv;\n\n /**\n * Prints CLI usage and exits with non-zero code.\n */\n function printUsage() {\n log('Usage:');\n log(\n ' dataqueue-cli migrate [--envPath <path>] [-s <schema> | --schema <schema>]',\n );\n log(' dataqueue-cli init');\n log('');\n log('Options for migrate:');\n log(\n ' --envPath <path> Path to a .env file to load environment variables (passed to node-pg-migrate)',\n );\n log(\n ' -s, --schema <schema> Set the schema to use (passed to node-pg-migrate)',\n );\n log('');\n log('Notes:');\n log(\n ' - The PG_DATAQUEUE_DATABASE environment variable must be set to your Postgres connection string.',\n );\n log(\n ' - For managed Postgres (e.g., DigitalOcean) with SSL, set PGSSLMODE=require and PGSSLROOTCERT to your CA .crt file.',\n );\n log(\n ' Example: PGSSLMODE=require NODE_EXTRA_CA_CERTS=/absolute/path/to/ca.crt PG_DATAQUEUE_DATABASE=... npx dataqueue-cli migrate',\n );\n log('');\n log('Notes for init:');\n log(\n ' - Supports both Next.js App Router and Pages Router (prefers App Router if both exist).',\n );\n log(\n ' - Scaffolds endpoint, cron.sh, queue placeholder, and package.json entries.',\n );\n exit(1);\n }\n\n if (command === 'migrate') {\n // Support for -s or --schema argument\n let schemaArg: string[] = [];\n const sIndex = restArgs.indexOf('-s');\n const schemaIndex = restArgs.indexOf('--schema');\n if (sIndex !== -1 && restArgs[sIndex + 1]) {\n schemaArg = ['-s', restArgs[sIndex + 1], '--create-schema'];\n restArgs.splice(sIndex, 2);\n } else if (schemaIndex !== -1 && restArgs[schemaIndex + 1]) {\n schemaArg = ['-s', restArgs[schemaIndex + 1], '--create-schema'];\n restArgs.splice(schemaIndex, 2);\n }\n\n // Support for --envPath argument\n let envPathArg: string[] = [];\n const envPathIndex = restArgs.indexOf('--envPath');\n if (envPathIndex !== -1 && restArgs[envPathIndex + 1]) {\n envPathArg = ['--envPath', restArgs[envPathIndex + 1]];\n }\n\n const result: SpawnSyncReturns<any> = spawnSyncImpl(\n 'npx',\n [\n 'node-pg-migrate',\n 'up',\n '-t',\n 'dataqueuedev_migrations',\n '-d',\n 'PG_DATAQUEUE_DATABASE',\n '-m',\n migrationsDir,\n ...schemaArg,\n ...envPathArg,\n ...restArgs,\n ],\n { stdio: 'inherit' },\n );\n exit(result.status ?? 1);\n } else if (command === 'init') {\n runInitImpl({\n log,\n error,\n exit,\n ...initDeps,\n });\n } else {\n printUsage();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/init-command.ts","../src/install-skills-command.ts","../src/install-rules-command.ts","../src/install-mcp-command.ts","../src/mcp-server.ts","../src/cli.ts"],"names":["path","existsSync","mkdirSync","__filename","fileURLToPath","__dirname","readFileSync","fs","writeFileSync","client","readline"],"mappings":";;;;;;;;;;AAYA,IAAM,mBAAA,GAAsB;AAAA,EAC1B,uBAAA;AAAA,EACA,iCAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,uBAAA,GAA0B;AAAA,EAC9B,YAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,cAAA,GAAiB;AAAA,EACrB,IAAA,EAAM,cAAA;AAAA,EACN,mBAAA,EAAqB;AACvB,CAAA;AAKO,IAAM,yBAAA,GAA4B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgIlC,IAAM,2BAAA,GAA8B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA0GpC,IAAM,gBAAA,GAAmB,CAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA;AA+CzB,IAAM,cAAA,GAAiB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyDvB,SAAS,OAAA,CAAQ;AAAA,EACtB,MAAM,OAAA,CAAQ,GAAA;AAAA,EACd,QAAQ,OAAA,CAAQ,KAAA;AAAA,EAChB,IAAA,GAAO,CAAC,IAAA,KAAiB,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC1C,GAAA,GAAM,QAAQ,GAAA,EAAI;AAAA,EAClB,gBAAA,GAAmB,YAAA;AAAA,EACnB,iBAAA,GAAoB,aAAA;AAAA,EACpB,cAAA,GAAiB,UAAA;AAAA,EACjB,aAAA,GAAgB,SAAA;AAAA,EAChB,aAAA,GAAgB;AAClB,CAAA,GAAc,EAAC,EAAS;AACtB,EAAA,IAAI;AACF,IAAA,GAAA,CAAI,CAAA,2BAAA,EAA8B,GAAG,CAAA,GAAA,CAAK,CAAA;AAC1C,IAAA,GAAA,CAAI,EAAE,CAAA;AAEN,IAAA,MAAM,UAAU,qBAAA,CAAsB;AAAA,MACpC,GAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,mBAAA,CAAoB;AAAA,MAClB,OAAA;AAAA,MACA,GAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,iBAAA,CAAkB;AAAA,MAChB,OAAA;AAAA,MACA,GAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,GAAA,CAAI,EAAE,CAAA;AACN,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA,WACC,KAAA,EAAO;AACd,IAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,IAAA,KAAA,CAAM,CAAA,WAAA,EAAc,OAAO,CAAA,CAAE,CAAA;AAC7B,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA;AAEV;AAKO,SAAS,qBAAA,CAAsB;AAAA,EACpC,GAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAImB;AACjB,EAAA,MAAM,eAAA,GAAkBA,KAAA,CAAK,IAAA,CAAK,GAAA,EAAK,cAAc,CAAA;AACrD,EAAA,IAAI,CAAC,cAAA,CAAe,eAAe,CAAA,EAAG;AACpC,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA;AAGhE,EAAA,MAAM,WAAA,GAAc,gBAAA;AAAA,IAClB,gBAAA,CAAiB,iBAAiB,MAAM,CAAA;AAAA,IACxC;AAAA,GACF;AACA,EAAA,IAAI,CAAC,eAAA,CAAgB,WAAW,CAAA,EAAG;AACjC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAGF,EAAA,MAAM,MAAA,GAASA,KAAA,CAAK,IAAA,CAAK,GAAA,EAAK,KAAK,CAAA;AACnC,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,MAAM,CAAA,GAAI,KAAA,GAAQ,GAAA;AACjD,EAAA,MAAM,MAAA,GAASA,KAAA,CAAK,IAAA,CAAK,GAAA,EAAK,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAWA,KAAA,CAAK,IAAA,CAAK,GAAA,EAAK,SAAS,OAAO,CAAA;AAChD,EAAA,MAAM,SAAA,GAAY,eAAe,MAAM,CAAA;AACvC,EAAA,MAAM,WAAA,GAAc,eAAe,QAAQ,CAAA;AAE3C,EAAA,IAAI,CAAC,SAAA,IAAa,CAAC,WAAA,EAAa;AAC9B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAGF,EAAA,MAAM,MAAA,GAAqB,YAAY,KAAA,GAAQ,OAAA;AAC/C,EAAA,OAAO,EAAE,GAAA,EAAK,eAAA,EAAiB,WAAA,EAAa,SAAS,MAAA,EAAO;AAC9D;AAKA,SAAS,iBAAA,CAAkB;AAAA,EACzB,OAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA,EAIS;AACP,EAAA,MAAM,cAAc,OAAA,CAAQ,WAAA;AAC5B,EAAA,MAAM,YAAA,GAAe,sBAAA,CAAuB,WAAA,EAAa,cAAc,CAAA;AACvE,EAAA,MAAM,eAAA,GAAkB,sBAAA;AAAA,IACtB,WAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,OAAA,GAAU,sBAAA,CAAuB,WAAA,EAAa,SAAS,CAAA;AAE7D,EAAA,KAAA,MAAW,cAAc,mBAAA,EAAqB;AAC5C,IAAA,IAAI,YAAA,CAAa,UAAU,CAAA,EAAG;AAC5B,MAAA,GAAA,CAAI,CAAA,uBAAA,EAA0B,UAAU,CAAA,iBAAA,CAAmB,CAAA;AAC3D,MAAA;AAAA;AAEF,IAAA,YAAA,CAAa,UAAU,CAAA,GAAI,QAAA;AAC3B,IAAA,GAAA,CAAI,CAAA,uBAAA,EAA0B,UAAU,CAAA,CAAE,CAAA;AAAA;AAG5C,EAAA,KAAA,MAAW,iBAAiB,uBAAA,EAAyB;AACnD,IAAA,IAAI,eAAA,CAAgB,aAAa,CAAA,EAAG;AAClC,MAAA,GAAA,CAAI,CAAA,0BAAA,EAA6B,aAAa,CAAA,iBAAA,CAAmB,CAAA;AACjE,MAAA;AAAA;AAEF,IAAA,eAAA,CAAgB,aAAa,CAAA,GAAI,QAAA;AACjC,IAAA,GAAA,CAAI,CAAA,0BAAA,EAA6B,aAAa,CAAA,CAAE,CAAA;AAAA;AAGlD,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,WAAW,KAAK,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,EAAG;AACtE,IAAA,IAAI,OAAA,CAAQ,UAAU,CAAA,EAAG;AACvB,MAAA,GAAA,CAAI,CAAA,oBAAA,EAAuB,UAAU,CAAA,kBAAA,CAAoB,CAAA;AACzD,MAAA;AAAA;AAEF,IAAA,OAAA,CAAQ,UAAU,CAAA,GAAI,WAAA;AACtB,IAAA,GAAA,CAAI,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAA,CAAG,CAAA;AAAA;AAG1C,EAAA,iBAAA;AAAA,IACE,OAAA,CAAQ,eAAA;AAAA,IACR,GAAG,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,EAAM,CAAC,CAAC;AAAA;AAAA,GACzC;AACF;AAKA,SAAS,mBAAA,CAAoB;AAAA,EAC3B,OAAA;AAAA,EACA,GAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,EAOS;AACP,EAAA,MAAM,eAAeA,KAAA,CAAK,IAAA;AAAA,IACxB,OAAA,CAAQ,GAAA;AAAA,IACR,OAAA,CAAQ,OAAA;AAAA,IACR,KAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,iBAAiBA,KAAA,CAAK,IAAA;AAAA,IAC1B,OAAA,CAAQ,GAAA;AAAA,IACR,OAAA,CAAQ,OAAA;AAAA,IACR,OAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,YAAYA,KAAA,CAAK,IAAA;AAAA,IACrB,OAAA,CAAQ,GAAA;AAAA,IACR,OAAA,CAAQ,OAAA;AAAA,IACR,KAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,QAAA,GAAWA,KAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,KAAK,SAAS,CAAA;AAEjD,EAAA,IAAI,OAAA,CAAQ,WAAW,KAAA,EAAO;AAC5B,IAAA,mBAAA,CAAoB;AAAA,MAClB,YAAA,EAAc,YAAA;AAAA,MACd,OAAA,EAAS,yBAAA;AAAA,MACT,cAAA;AAAA,MACA,aAAA;AAAA,MACA,iBAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAK,YAAY;AAAA,KAClD,CAAA;AACD,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AAAA,GACF,MAAO;AACL,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,mBAAA,CAAoB;AAAA,MAClB,YAAA,EAAc,cAAA;AAAA,MACd,OAAA,EAAS,2BAAA;AAAA,MACT,cAAA;AAAA,MACA,aAAA;AAAA,MACA,iBAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAK,cAAc;AAAA,KACpD,CAAA;AAAA;AAGH,EAAA,mBAAA,CAAoB;AAAA,IAClB,YAAA,EAAc,QAAA;AAAA,IACd,OAAA,EAAS,gBAAA;AAAA,IACT,cAAA;AAAA,IACA,aAAA;AAAA,IACA,iBAAA;AAAA,IACA,GAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACV,CAAA;AACD,EAAA,IAAI,cAAA,CAAe,QAAQ,CAAA,EAAG;AAC5B,IAAA,aAAA,CAAc,UAAU,GAAK,CAAA;AAAA;AAG/B,EAAA,mBAAA,CAAoB;AAAA,IAClB,YAAA,EAAc,SAAA;AAAA,IACd,OAAA,EAAS,cAAA;AAAA,IACT,cAAA;AAAA,IACA,aAAA;AAAA,IACA,iBAAA;AAAA,IACA,GAAA;AAAA,IACA,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAK,SAAS;AAAA,GAC/C,CAAA;AACH;AAKA,SAAS,mBAAA,CAAoB;AAAA,EAC3B,YAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA,EAQS;AACP,EAAA,IAAI,cAAA,CAAe,YAAY,CAAA,EAAG;AAChC,IAAA,GAAA,CAAI,CAAA,YAAA,EAAe,OAAO,CAAA,iBAAA,CAAmB,CAAA;AAC7C,IAAA;AAAA;AAGF,EAAA,aAAA,CAAcA,MAAK,OAAA,CAAQ,YAAY,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC7D,EAAA,iBAAA,CAAkB,cAAc,OAAO,CAAA;AACvC,EAAA,GAAA,CAAI,CAAA,YAAA,EAAe,OAAO,CAAA,CAAE,CAAA;AAC9B;AAKA,SAAS,gBAAA,CAAiB,SAAiB,QAAA,EAA8B;AACvE,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACjC,IAAA,IAAI,CAAC,UAAU,OAAO,MAAA,KAAW,YAAY,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClE,MAAA,MAAM,IAAI,MAAM,sCAAsC,CAAA;AAAA;AAExD,IAAA,OAAO,MAAA;AAAA,WACA,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,gCAAA,EAAmC,QAAQ,CAAA,EAAA,EACzC,KAAA,YAAiB,QAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CACvD,CAAA;AAAA,KACF;AAAA;AAEJ;AAKA,SAAS,gBAAgB,WAAA,EAAkC;AACzD,EAAA,MAAM,eAAe,WAAA,CAAY,YAAA;AACjC,EAAA,MAAM,kBAAkB,WAAA,CAAY,eAAA;AAEpC,EAAA,OACE,WAAW,YAAA,EAAc,MAAM,CAAA,IAAK,UAAA,CAAW,iBAAiB,MAAM,CAAA;AAE1E;AAKA,SAAS,UAAA,CAAW,SAAkB,WAAA,EAA8B;AAClE,EAAA,IAAI,CAAC,WAAW,OAAO,OAAA,KAAY,YAAY,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG;AACrE,IAAA,OAAO,KAAA;AAAA;AAET,EAAA,OAAO,OAAA,CAAS,OAAA,CAAoB,WAAW,CAAC,CAAA;AAClD;AAKA,SAAS,sBAAA,CACP,aACA,WAAA,EACS;AACT,EAAA,MAAM,YAAA,GAAe,YAAY,WAAW,CAAA;AAC5C,EAAA,IACE,CAAC,gBACD,OAAO,YAAA,KAAiB,YACxB,KAAA,CAAM,OAAA,CAAQ,YAAY,CAAA,EAC1B;AACA,IAAA,WAAA,CAAY,WAAW,IAAI,EAAC;AAAA;AAE9B,EAAA,OAAO,YAAY,WAAW,CAAA;AAChC;AAKA,SAAS,cAAA,CAAe,KAAa,YAAA,EAA8B;AACjE,EAAA,MAAM,QAAA,GAAWA,KAAA,CAAK,QAAA,CAAS,GAAA,EAAK,YAAY,CAAA;AAChD,EAAA,OAAO,QAAA,IAAY,GAAA;AACrB;AChsBA,IAAM,UAAA,GAAa,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAM,SAAA,GAAYA,KAAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AAczC,IAAM,UAAA,GAAa,CAAC,gBAAA,EAAkB,oBAAA,EAAsB,iBAAiB,CAAA;AActE,SAAS,aAAA,CACd,GAAA,EACAC,WAAAA,GAAqC,EAAA,CAAG,UAAA,EAC9B;AACV,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,MAAA,GACJ;AAAA,IACE;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,SAAA,EAAW,SAAA;AAAA,MACX,SAAA,EAAW;AAAA,KACb;AAAA,IACA;AAAA,MACE,IAAA,EAAM,aAAA;AAAA,MACN,SAAA,EAAW,SAAA;AAAA,MACX,SAAA,EAAW;AAAA,KACb;AAAA,IACA;AAAA,MACE,IAAA,EAAM,gBAAA;AAAA,MACN,SAAA,EAAW,SAAA;AAAA,MACX,SAAA,EAAW;AAAA;AACb,GACF;AAEF,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,IAAIA,YAAWD,KAAAA,CAAK,IAAA,CAAK,KAAK,KAAA,CAAM,SAAS,CAAC,CAAA,EAAG;AAC/C,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,CAAM,MAAM,SAAA,EAAW,KAAA,CAAM,WAAW,CAAA;AAAA;AAC7D;AAGF,EAAA,OAAO,KAAA;AACT;AAOO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,MAAM,OAAA,CAAQ,GAAA;AAAA,EACd,QAAQ,OAAA,CAAQ,KAAA;AAAA,EAChB,IAAA,GAAO,CAAC,IAAA,KAAiB,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC1C,GAAA,GAAM,QAAQ,GAAA,EAAI;AAAA,EAClB,UAAA,EAAAC,cAAa,EAAA,CAAG,UAAA;AAAA,EAChB,SAAA,EAAAC,aAAY,EAAA,CAAG,SAAA;AAAA,EACf,eAAe,EAAA,CAAG,YAAA;AAAA,EAClB,cAAc,EAAA,CAAG,WAAA;AAAA,EACjB,eAAA,GAAkBF,KAAAA,CAAK,IAAA,CAAK,SAAA,EAAW,cAAc;AACvD,CAAA,GAAuB,EAAC,EAAS;AAC/B,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,EAAKC,WAAU,CAAA;AAE3C,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,GAAA,CAAI,iEAAiE,CAAA;AACrE,IAAA,GAAA,CAAI,iDAAiD,CAAA;AACrD,IAAA,KAAA,CAAM,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,kBAAkB,CAAA;AAAA;AAG5D,EAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,GAAA,CAAI;AAAA,sBAAA,EAA2B,IAAA,CAAK,IAAI,CAAA,GAAA,CAAK,CAAA;AAE7C,IAAA,KAAA,MAAW,YAAY,UAAA,EAAY;AACjC,MAAA,MAAM,MAAA,GAASD,KAAAA,CAAK,IAAA,CAAK,eAAA,EAAiB,QAAQ,CAAA;AAClD,MAAA,MAAM,UAAUA,KAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,WAAW,QAAQ,CAAA;AAEvD,MAAA,IAAI;AACF,QAAAE,UAAAA,CAAU,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAEtC,QAAA,MAAM,KAAA,GAAQ,YAAY,MAAM,CAAA;AAChC,QAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,UAAA,YAAA,CAAaF,KAAAA,CAAK,KAAK,MAAA,EAAQ,IAAI,GAAGA,KAAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA;AAGhE,QAAA,GAAA,CAAI,CAAA,SAAA,EAAO,QAAQ,CAAA,CAAE,CAAA;AACrB,QAAA,SAAA,EAAA;AAAA,eACO,GAAA,EAAK;AACZ,QAAA,KAAA,CAAM,CAAA,2BAAA,EAAyB,QAAQ,CAAA,CAAA,CAAA,EAAK,GAAG,CAAA;AAAA;AACjD;AACF;AAGF,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,GAAA;AAAA,MACE;AAAA,gBAAA,EAAqB,SAAS,CAAA,cAAA,EAAiB,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,KACpF;AAAA,GACF,MAAO;AACL,IAAA,KAAA,CAAM,2BAA2B,CAAA;AACjC,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA;AAEV;ACtHA,IAAMG,WAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAMC,UAAAA,GAAYL,KAAAA,CAAK,OAAA,CAAQG,WAAU,CAAA;AAiBzC,IAAM,UAAA,GAAa,CAAC,UAAA,EAAY,aAAA,EAAe,oBAAoB,CAAA;AAqBnE,IAAM,YAAA,GAAe,gCAAA;AACrB,IAAM,UAAA,GAAa,8BAAA;AASZ,SAAS,mBAAA,CACd,QAAA,EACA,OAAA,EACA,IAAA,EAKM;AACN,EAAA,MAAM,KAAA,GAAQ,GAAG,YAAY;AAAA,EAAK,OAAO;AAAA,EAAK,UAAU,CAAA,CAAA;AAExD,EAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC9B,IAAA,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,KAAA,GAAQ,IAAI,CAAA;AACzC,IAAA;AAAA;AAGF,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AACpD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,YAAY,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA;AAE1C,EAAA,IAAI,QAAA,KAAa,EAAA,IAAM,MAAA,KAAW,EAAA,EAAI;AACpC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,MAAA,GAAS,WAAW,MAAM,CAAA;AACvD,IAAA,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,MAAA,GAAS,KAAA,GAAQ,KAAK,CAAA;AAAA,GACrD,MAAO;AACL,IAAA,IAAA,CAAK,cAAc,QAAA,EAAU,QAAA,CAAS,SAAQ,GAAI,MAAA,GAAS,QAAQ,IAAI,CAAA;AAAA;AAE3E;AAEA,SAAS,kBAAA,CACP,gBACAG,aAAAA,EACQ;AACR,EAAA,OAAO,UAAA,CAAW,GAAA;AAAA,IAAI,CAAC,MACrBA,aAAAA,CAAaN,KAAAA,CAAK,KAAK,cAAA,EAAgB,CAAC,GAAG,OAAO;AAAA,GACpD,CAAE,KAAK,MAAM,CAAA;AACf;AAEA,IAAM,OAAA,GAAwC;AAAA,EAC5C,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,QAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,WAAWA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,WAAW,OAAO,CAAA;AACvD,MAAA,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAE5C,MAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,QAAA,MAAM,MAAM,IAAA,CAAK,YAAA;AAAA,UACfA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,IAAI,CAAA;AAAA,UACnC;AAAA,SACF;AACA,QAAA,MAAM,WAAW,CAAA,UAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAC,CAAA,CAAA;AAC3D,QAAA,IAAA,CAAK,cAAcA,KAAAA,CAAK,IAAA,CAAK,QAAA,EAAU,QAAQ,GAAG,GAAG,CAAA;AACrD,QAAA,IAAA,CAAK,GAAA,CAAI,CAAA,uBAAA,EAAqB,QAAQ,CAAA,CAAE,CAAA;AAAA;AAC1C;AACF,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,aAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,OAAA,GAAU,kBAAA;AAAA,QACd,IAAA,CAAK,cAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AACA,MAAA,MAAM,QAAA,GAAWA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,WAAW,CAAA;AAChD,MAAA,mBAAA,CAAoB,QAAA,EAAU,SAAS,IAAI,CAAA;AAC3C,MAAA,IAAA,CAAK,IAAI,CAAA,kBAAA,CAAe,CAAA;AAAA;AAC1B,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,oCAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,OAAA,GAAU,kBAAA;AAAA,QACd,IAAA,CAAK,cAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AACA,MAAA,MAAM,QAAA,GAAWA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,WAAW,CAAA;AAChD,MAAA,mBAAA,CAAoB,QAAA,EAAU,SAAS,IAAI,CAAA;AAC3C,MAAA,IAAA,CAAK,IAAI,CAAA,kBAAA,CAAe,CAAA;AAAA;AAC1B,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,gBAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,OAAA,GAAU,kBAAA;AAAA,QACd,IAAA,CAAK,cAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AACA,MAAA,IAAA,CAAK,SAAA,CAAUA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,SAAS,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAClE,MAAA,MAAM,WAAWA,KAAAA,CAAK,IAAA;AAAA,QACpB,IAAA,CAAK,GAAA;AAAA,QACL,SAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,mBAAA,CAAoB,QAAA,EAAU,SAAS,IAAI,CAAA;AAC3C,MAAA,IAAA,CAAK,IAAI,CAAA,wCAAA,CAAqC,CAAA;AAAA;AAChD,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,UAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,OAAA,GAAU,kBAAA;AAAA,QACd,IAAA,CAAK,cAAA;AAAA,QACL,IAAA,CAAK;AAAA,OACP;AACA,MAAA,MAAM,QAAA,GAAWA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,gBAAgB,CAAA;AACrD,MAAA,mBAAA,CAAoB,QAAA,EAAU,SAAS,IAAI,CAAA;AAC3C,MAAA,IAAA,CAAK,IAAI,CAAA,uBAAA,CAAoB,CAAA;AAAA;AAC/B;AAEJ,CAAA;AAOA,eAAsB,eAAA,CAAgB;AAAA,EACpC,MAAM,OAAA,CAAQ,GAAA;AAAA,EACd,QAAQ,OAAA,CAAQ,KAAA;AAAA,EAChB,IAAA,GAAO,CAAC,IAAA,KAAiB,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC1C,GAAA,GAAM,QAAQ,GAAA,EAAI;AAAA,EAClB,YAAA,EAAAM,gBAAeC,EAAAA,CAAG,YAAA;AAAA,EAClB,aAAA,EAAAC,iBAAgBD,EAAAA,CAAG,aAAA;AAAA,EACnB,iBAAiBA,EAAAA,CAAG,cAAA;AAAA,EACpB,SAAA,EAAAL,aAAYK,EAAAA,CAAG,SAAA;AAAA,EACf,UAAA,EAAAN,cAAaM,EAAAA,CAAG,UAAA;AAAA,EAChB,cAAA,GAAiBP,KAAAA,CAAK,IAAA,CAAKK,UAAAA,EAAW,aAAa,CAAA;AAAA,EACnD;AACF,CAAA,GAAsB,EAAC,EAAkB;AACvC,EAAA,GAAA,CAAI,mCAAmC,CAAA;AACvC,EAAA,GAAA,CAAI,0BAA0B,CAAA;AAE9B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAKI,OAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AACnD,IAAA,GAAA,CAAI,CAAA,EAAA,EAAK,GAAG,CAAA,EAAA,EAAKA,OAAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AAAA;AAEjC,EAAA,GAAA,CAAI,EAAE,CAAA;AAEN,EAAA,IAAI,MAAA,GAAS,cAAA;AAEb,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,EAAA,GAAK,SAAS,eAAA,CAAgB;AAAA,MAClC,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAED,IAAA,MAAA,GAAS,MAAM,IAAI,OAAA,CAAgB,CAAC,OAAA,KAAY;AAC9C,MAAA,EAAA,CAAG,QAAA,CAAS,sBAAA,EAAwB,CAAC,MAAA,KAAW;AAC9C,QAAA,EAAA,CAAG,KAAA,EAAM;AACT,QAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA;AAAA,OACtB,CAAA;AAAA,KACF,CAAA;AAAA;AAGH,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM,CAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAClD,IAAA,IAAA,CAAK,CAAC,CAAA;AACN,IAAA;AAAA;AAGF,EAAA,GAAA,CAAI;AAAA,qBAAA,EAA0B,MAAA,CAAO,KAAK,CAAA,GAAA,CAAK,CAAA;AAE/C,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,OAAA,CAAQ;AAAA,MACb,GAAA;AAAA,MACA,YAAA,EAAAH,aAAAA;AAAA,MACA,aAAA,EAAAE,cAAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA,EAAAN,UAAAA;AAAA,MACA,UAAA,EAAAD,WAAAA;AAAA,MACA,GAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,GAAA,CAAI,SAAS,CAAA;AAAA,WACN,GAAA,EAAK;AACZ,IAAA,KAAA,CAAM,4BAA4B,GAAG,CAAA;AACrC,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA;AAEV;AC9LO,SAAS,eAAA,CACd,QAAA,EACA,SAAA,EACA,YAAA,EACA,IAAA,EAKM;AACN,EAAA,IAAI,SAAkC,EAAC;AAEvC,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC7B,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,KAAK,KAAA,CAAM,IAAA,CAAK,YAAA,CAAa,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,KAC1D,CAAA,MAAQ;AACN,MAAA,MAAA,GAAS,EAAC;AAAA;AACZ;AAGF,EAAA,IAAI,CAAC,MAAA,CAAO,UAAA,IAAc,OAAO,MAAA,CAAO,eAAe,QAAA,EAAU;AAC/D,IAAA,MAAA,CAAO,aAAa,EAAC;AAAA;AAGvB,EAAC,MAAA,CAAO,UAAA,CAAuC,SAAS,CAAA,GAAI,YAAA;AAC5D,EAAA,IAAA,CAAK,aAAA,CAAc,UAAU,IAAA,CAAK,SAAA,CAAU,QAAQ,IAAA,EAAM,CAAC,IAAI,IAAI,CAAA;AACrE;AAEA,IAAM,iBAAA,GAAoB;AAAA,EACxB,OAAA,EAAS,KAAA;AAAA,EACT,IAAA,EAAM,CAAC,eAAA,EAAiB,KAAK;AAC/B,CAAA;AAEA,IAAM,WAAA,GAA+C;AAAA,EACnD,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,QAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,SAAA,GAAYD,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,SAAS,CAAA;AAC/C,MAAA,IAAA,CAAK,SAAA,CAAU,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC7C,MAAA,MAAM,UAAA,GAAaA,KAAAA,CAAK,IAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAClD,MAAA,eAAA,CAAgB,UAAA,EAAY,WAAA,EAAa,iBAAA,EAAmB,IAAI,CAAA;AAChE,MAAA,IAAA,CAAK,IAAI,CAAA,yBAAA,CAAsB,CAAA;AAAA;AACjC,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,aAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,UAAA,GAAaA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,WAAW,CAAA;AAClD,MAAA,eAAA,CAAgB,UAAA,EAAY,WAAA,EAAa,iBAAA,EAAmB,IAAI,CAAA;AAChE,MAAA,IAAA,CAAK,IAAI,CAAA,kBAAA,CAAe,CAAA;AAAA;AAC1B,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,mBAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,SAAA,GAAYA,KAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,SAAS,CAAA;AAC/C,MAAA,IAAA,CAAK,SAAA,CAAU,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC7C,MAAA,MAAM,UAAA,GAAaA,KAAAA,CAAK,IAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAClD,MAAA,eAAA,CAAgB,UAAA,EAAY,WAAA,EAAa,iBAAA,EAAmB,IAAI,CAAA;AAChE,MAAA,IAAA,CAAK,IAAI,CAAA,yBAAA,CAAsB,CAAA;AAAA;AACjC,GACF;AAAA,EACA,GAAA,EAAK;AAAA,IACH,KAAA,EAAO,UAAA;AAAA,IACP,OAAA,EAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,UAAU,OAAA,CAAQ,GAAA,CAAI,IAAA,IAAQ,OAAA,CAAQ,IAAI,WAAA,IAAe,EAAA;AAC/D,MAAA,MAAM,aAAaA,KAAAA,CAAK,IAAA;AAAA,QACtB,OAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAA,CAAK,SAAA,CAAUA,MAAK,OAAA,CAAQ,UAAU,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5D,MAAA,eAAA,CAAgB,UAAA,EAAY,WAAA,EAAa,iBAAA,EAAmB,IAAI,CAAA;AAChE,MAAA,IAAA,CAAK,IAAI,CAAA,4CAAA,CAAyC,CAAA;AAAA;AACpD;AAEJ,CAAA;AAOA,eAAsB,aAAA,CAAc;AAAA,EAClC,MAAM,OAAA,CAAQ,GAAA;AAAA,EACd,QAAQ,OAAA,CAAQ,KAAA;AAAA,EAChB,IAAA,GAAO,CAAC,IAAA,KAAiB,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC1C,GAAA,GAAM,QAAQ,GAAA,EAAI;AAAA,EAClB,YAAA,EAAAM,gBAAeC,EAAAA,CAAG,YAAA;AAAA,EAClB,aAAA,EAAAC,iBAAgBD,EAAAA,CAAG,aAAA;AAAA,EACnB,SAAA,EAAAL,aAAYK,EAAAA,CAAG,SAAA;AAAA,EACf,UAAA,EAAAN,cAAaM,EAAAA,CAAG,UAAA;AAAA,EAChB;AACF,CAAA,GAAoB,EAAC,EAAkB;AACrC,EAAA,GAAA,CAAI,kCAAkC,CAAA;AACtC,EAAA,GAAA,CAAI,0BAA0B,CAAA;AAE9B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAKE,OAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,EAAG;AACvD,IAAA,GAAA,CAAI,CAAA,EAAA,EAAK,GAAG,CAAA,EAAA,EAAKA,OAAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AAAA;AAEjC,EAAA,GAAA,CAAI,EAAE,CAAA;AAEN,EAAA,IAAI,MAAA,GAAS,cAAA;AAEb,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,EAAA,GAAKC,SAAS,eAAA,CAAgB;AAAA,MAClC,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAED,IAAA,MAAA,GAAS,MAAM,IAAI,OAAA,CAAgB,CAAC,OAAA,KAAY;AAC9C,MAAA,EAAA,CAAG,QAAA,CAAS,sBAAA,EAAwB,CAAC,MAAA,KAAW;AAC9C,QAAA,EAAA,CAAG,KAAA,EAAM;AACT,QAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA;AAAA,OACtB,CAAA;AAAA,KACF,CAAA;AAAA;AAGH,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM,CAAA;AACjC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAClD,IAAA,IAAA,CAAK,CAAC,CAAA;AACN,IAAA;AAAA;AAGF,EAAA,GAAA,CAAI;AAAA,0BAAA,EAA+B,MAAA,CAAO,KAAK,CAAA,GAAA,CAAK,CAAA;AAEpD,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,OAAA,CAAQ;AAAA,MACb,GAAA;AAAA,MACA,YAAA,EAAAJ,aAAAA;AAAA,MACA,aAAA,EAAAE,cAAAA;AAAA,MACA,SAAA,EAAAN,UAAAA;AAAA,MACA,UAAA,EAAAD,WAAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,GAAA,CAAI,4DAA4D,CAAA;AAAA,WACzD,GAAA,EAAK;AACZ,IAAA,KAAA,CAAM,iCAAiC,GAAG,CAAA;AAC1C,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA;AAEV;AC1KA,IAAME,WAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAMC,UAAAA,GAAYL,KAAAA,CAAK,OAAA,CAAQG,WAAU,CAAA;AAUlC,SAAS,gBACd,QAAA,GAAmBH,KAAAA,CAAK,IAAA,CAAKK,UAAAA,EAAW,yBAAyB,CAAA,EACtD;AACX,EAAA,MAAM,GAAA,GAAME,EAAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC7C,EAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AACvB;AAGO,SAAS,iBAAA,CAAkB,MAAe,UAAA,EAA8B;AAC7E,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,WAAA,EAAY;AAC1C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,WAAA,EAAY;AAC/C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAY;AAE9C,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,IAAI,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,EAAG,KAAA,IAAS,EAAA;AACxC,IAAA,IAAI,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,EAAG,KAAA,IAAS,CAAA;AAEvC,IAAA,MAAM,cAAA,GAAiB,YAAA,CAAa,KAAA,CAAM,IAAI,EAAE,MAAA,GAAS,CAAA;AACzD,IAAA,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,cAAA,EAAgB,EAAE,CAAA;AAAA;AAEtC,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,cAAA,CACd,OAAA,EACA,UAAA,EACA,SAAA,GAAY,GAAA,EACJ;AACR,EAAA,MAAM,KAAA,GAAQ,QAAQ,WAAA,EAAY;AAClC,EAAA,IAAI,aAAA,GAAgB,EAAA;AAEpB,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA;AAC9B,IAAA,IAAI,GAAA,KAAQ,EAAA,KAAO,aAAA,KAAkB,EAAA,IAAM,MAAM,aAAA,CAAA,EAAgB;AAC/D,MAAA,aAAA,GAAgB,GAAA;AAAA;AAClB;AAGF,EAAA,IAAI,kBAAkB,EAAA,EAAI;AACxB,IAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA;AAAA;AAGnC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,gBAAgB,GAAG,CAAA;AAC7C,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,QAAQ,SAAS,CAAA;AACtD,EAAA,IAAI,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA;AAEtC,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,OAAA,GAAU,KAAA,GAAQ,OAAA;AACjC,EAAA,IAAI,GAAA,GAAM,OAAA,CAAQ,MAAA,EAAQ,OAAA,GAAU,OAAA,GAAU,KAAA;AAE9C,EAAA,OAAO,OAAA;AACT;AAOA,eAAsB,cAAA,CACpB,IAAA,GAGI,EAAC,EACe;AACpB,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,QAAQ,CAAA;AAE3C,EAAA,MAAM,MAAA,GAAS,IAAI,SAAA,CAAU;AAAA,IAC3B,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACV,CAAA;AAED,EAAA,MAAA,CAAO,QAAA,CAAS,UAAA,EAAY,sBAAA,EAAwB,YAAY;AAC9D,IAAA,MAAM,WAAWP,KAAAA,CAAK,IAAA;AAAA,MACpBK,UAAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAUE,EAAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAAA,KAC7C,CAAA,MAAQ;AACN,MAAA,OAAA,GAAU,MACP,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAA,EAAM,EAAE,KAAK;;AAAA,MAAA,EAAa,EAAE,IAAI;;AAAA,EAAO,CAAA,CAAE,WAAW,CAAA,CAAE,CAAA,CACjE,KAAK,MAAM,CAAA;AAAA;AAEhB,IAAA,OAAO,EAAE,UAAU,CAAC,EAAE,KAAK,sBAAA,EAAwB,IAAA,EAAM,OAAA,EAAS,CAAA,EAAE;AAAA,GACrE,CAAA;AAED,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,gBAAA;AAAA,IACA,gFAAA;AAAA,IACA,EAAC;AAAA,IACD,YAAY;AACV,MAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAChC,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,aAAa,CAAA,CAAE;AAAA,OACjB,CAAE,CAAA;AACF,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA,UACP,EAAE,MAAM,MAAA,EAAiB,IAAA,EAAM,KAAK,SAAA,CAAU,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA;AAAE;AAClE,OACF;AAAA;AACF,GACF;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,cAAA;AAAA,IACA,qFAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,CAAA,CACH,MAAA,EAAO,CACP,SAAS,4DAA4D;AAAA,KAC1E;AAAA,IACA,OAAO,EAAE,IAAA,EAAK,KAAM;AAClB,MAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAC9C,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM,oBAAoB,IAAI,CAAA,6CAAA;AAAA;AAChC,WACF;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA;AAEF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,GAChB,CAAA,EAAA,EAAK,KAAK,KAAK;;AAAA,EAAA,EAAS,KAAK,WAAW;;AAAA,CAAA,GACxC,CAAA,EAAA,EAAK,KAAK,KAAK;;AAAA,CAAA;AACnB,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,QAAiB,IAAA,EAAM,MAAA,GAAS,IAAA,CAAK,OAAA,EAAS;AAAA,OAClE;AAAA;AACF,GACF;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,aAAA;AAAA,IACA,6HAAA;AAAA,IACA;AAAA,MACE,KAAA,EAAO,CAAA,CACJ,MAAA,EAAO,CACP,SAAS,wDAAwD;AAAA,KACtE;AAAA,IACA,OAAO,EAAE,KAAA,EAAM,KAAM;AACnB,MAAA,MAAM,UAAA,GAAa,KAAA,CAChB,WAAA,EAAY,CACZ,KAAA,CAAM,KAAK,CAAA,CACX,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AAE7B,MAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,gCAAA;AAAiC,WAClE;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA;AAGF,MAAA,MAAM,MAAA,GAAS,KAAA,CACZ,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,QACd,IAAA;AAAA,QACA,KAAA,EAAO,iBAAA,CAAkB,IAAA,EAAM,UAAU;AAAA,OAC3C,CAAE,EACD,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAA,GAAQ,CAAC,CAAA,CACzB,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAA,CAChC,KAAA,CAAM,GAAG,CAAC,CAAA;AAEb,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM,mBAAmB,KAAK,CAAA,0DAAA;AAAA;AAChC;AACF,SACF;AAAA;AAGF,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM;AAChC,QAAA,MAAM,OAAA,GAAU,cAAA,CAAe,CAAA,CAAE,IAAA,CAAK,SAAS,UAAU,CAAA;AACzD,QAAA,OAAO,MAAM,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,IAAI,CAAA;;AAAA,EAAQ,CAAA,CAAE,KAAK,WAAW;;AAAA,EAAO,OAAO,CAAA,CAAA;AAAA,OAClF,CAAA;AAED,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAiB,MAAM,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA,EAAG;AAAA,OACxE;AAAA;AACF,GACF;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,IAAa,IAAI,oBAAA,EAAqB;AAC7D,EAAA,MAAM,MAAA,CAAO,QAAQ,SAAS,CAAA;AAC9B,EAAA,OAAO,MAAA;AACT;AAEA,IAAM,cACJ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KACb,QAAQ,IAAA,CAAK,CAAC,CAAA,CAAE,QAAA,CAAS,gBAAgB,CAAA,IACxC,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAE,SAAS,iBAAiB,CAAA,CAAA;AAE9C,IAAI,WAAA,EAAa;AACf,EAAA,cAAA,EAAe,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAC9B,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,GAAG,CAAA;AAChD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,GACf,CAAA;AACH;;;ACzNA,IAAMJ,WAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAMC,UAAAA,GAAYL,KAAAA,CAAK,OAAA,CAAQG,WAAU,CAAA;AAmBlC,SAAS,OACd,IAAA,EACA;AAAA,EACE,MAAM,OAAA,CAAQ,GAAA;AAAA,EACd,QAAQ,OAAA,CAAQ,KAAA;AAAA,EAChB,IAAA,GAAO,CAAC,IAAA,KAAiB,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC1C,aAAA,GAAgB,SAAA;AAAA,EAChB,aAAA,GAAgBH,KAAAA,CAAK,IAAA,CAAKK,UAAAA,EAAW,eAAe,CAAA;AAAA,EACpD,QAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,iBAAA;AAAA,EACA,oBAAA,GAAuB,gBAAA;AAAA,EACvB,gBAAA;AAAA,EACA,mBAAA,GAAsB,eAAA;AAAA,EACtB,cAAA;AAAA,EACA,iBAAA,GAAoB,aAAA;AAAA,EACpB,kBAAA,GAAqB;AACvB,CAAA,GAAa,EAAC,EACR;AACN,EAAA,MAAM,KAAK,OAAA,EAAS,GAAG,QAAQ,CAAA,GAAI,IAAA;AAEnC,EAAA,SAAS,UAAA,GAAa;AACpB,IAAA,GAAA,CAAI,QAAQ,CAAA;AACZ,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,GAAA,CAAI,sBAAsB,CAAA;AAC1B,IAAA,GAAA,CAAI,gCAAgC,CAAA;AACpC,IAAA,GAAA,CAAI,+BAA+B,CAAA;AACnC,IAAA,GAAA,CAAI,6BAA6B,CAAA;AACjC,IAAA,GAAA,CAAI,qBAAqB,CAAA;AACzB,IAAA,GAAA,CAAI,EAAE,CAAA;AACN,IAAA,GAAA,CAAI,sBAAsB,CAAA;AAC1B,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,GAAA,CAAI,EAAE,CAAA;AACN,IAAA,GAAA,CAAI,sBAAsB,CAAA;AAC1B,IAAA,GAAA,CAAI,sEAAsE,CAAA;AAC1E,IAAA,GAAA,CAAI,mEAAmE,CAAA;AACvE,IAAA,GAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,GAAA,CAAI,6DAA6D,CAAA;AACjE,IAAA,IAAA,CAAK,CAAC,CAAA;AAAA;AAGR,EAAA,IAAI,YAAY,SAAA,EAAW;AAEzB,IAAA,IAAI,YAAsB,EAAC;AAC3B,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,IAAI,CAAA;AACpC,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,UAAU,CAAA;AAC/C,IAAA,IAAI,MAAA,KAAW,EAAA,IAAM,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA,EAAG;AACzC,MAAA,SAAA,GAAY,CAAC,IAAA,EAAM,QAAA,CAAS,MAAA,GAAS,CAAC,GAAG,iBAAiB,CAAA;AAC1D,MAAA,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAC,CAAA;AAAA,eAChB,WAAA,KAAgB,EAAA,IAAM,QAAA,CAAS,WAAA,GAAc,CAAC,CAAA,EAAG;AAC1D,MAAA,SAAA,GAAY,CAAC,IAAA,EAAM,QAAA,CAAS,WAAA,GAAc,CAAC,GAAG,iBAAiB,CAAA;AAC/D,MAAA,QAAA,CAAS,MAAA,CAAO,aAAa,CAAC,CAAA;AAAA;AAIhC,IAAA,IAAI,aAAuB,EAAC;AAC5B,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAA;AACjD,IAAA,IAAI,YAAA,KAAiB,EAAA,IAAM,QAAA,CAAS,YAAA,GAAe,CAAC,CAAA,EAAG;AACrD,MAAA,UAAA,GAAa,CAAC,WAAA,EAAa,QAAA,CAAS,YAAA,GAAe,CAAC,CAAC,CAAA;AAAA;AAGvD,IAAA,MAAM,MAAA,GAAgC,aAAA;AAAA,MACpC,KAAA;AAAA,MACA;AAAA,QACE,iBAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,yBAAA;AAAA,QACA,IAAA;AAAA,QACA,uBAAA;AAAA,QACA,IAAA;AAAA,QACA,aAAA;AAAA,QACA,GAAG,SAAA;AAAA,QACH,GAAG,UAAA;AAAA,QACH,GAAG;AAAA,OACL;AAAA,MACA,EAAE,OAAO,SAAA;AAAU,KACrB;AACA,IAAA,IAAA,CAAK,MAAA,CAAO,UAAU,CAAC,CAAA;AAAA,GACzB,MAAA,IAAW,YAAY,MAAA,EAAQ;AAC7B,IAAA,WAAA,CAAY;AAAA,MACV,GAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,GACH,MAAA,IAAW,YAAY,gBAAA,EAAkB;AACvC,IAAA,oBAAA,CAAqB;AAAA,MACnB,GAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,GACH,MAAA,IAAW,YAAY,eAAA,EAAiB;AACtC,IAAA,mBAAA,CAAoB;AAAA,MAClB,GAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,GACH,MAAA,IAAW,YAAY,aAAA,EAAe;AACpC,IAAA,iBAAA,CAAkB;AAAA,MAChB,GAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAAA,GACH,MAAA,IAAW,YAAY,KAAA,EAAO;AAC5B,IAAA,kBAAA,EAAmB,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAClC,MAAA,KAAA,CAAM,+BAA+B,GAAG,CAAA;AACxC,MAAA,IAAA,CAAK,CAAC,CAAA;AAAA,KACP,CAAA;AAAA,GACH,MAAO;AACL,IAAA,UAAA,EAAW;AAAA;AAEf","file":"cli.js","sourcesContent":["import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from 'fs';\nimport path from 'path';\n\ntype JsonObject = Record<string, unknown>;\ntype JsonMap = Record<string, string>;\n\nconst DEPENDENCIES_TO_ADD = [\n '@nicnocquee/dataqueue',\n '@nicnocquee/dataqueue-dashboard',\n '@nicnocquee/dataqueue-react',\n] as const;\n\nconst DEV_DEPENDENCIES_TO_ADD = [\n 'dotenv-cli',\n 'ts-node',\n 'node-pg-migrate',\n] as const;\n\nconst SCRIPTS_TO_ADD = {\n cron: 'bash cron.sh',\n 'migrate-dataqueue': 'dotenv -e .env.local -- dataqueue-cli migrate',\n} as const;\n\n/**\n * App router endpoint template for queue management.\n */\nexport const APP_ROUTER_ROUTE_TEMPLATE = `/**\n * This end point is used to manage the job queue.\n * It supports the following tasks:\n * - reclaim: Reclaim stuck jobs\n * - cleanup: Cleanup old jobs\n * - process: Process jobs\n *\n * Example usage with default values (reclaim stuck jobs for 10 minutes, cleanup old jobs for 30 days, and process jobs with batch size 3, concurrency 2, and verbose true):\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\"\n *\n * Example usage with custom values:\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"maxProcessingTimeMinutes\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"daysToKeep\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"batchSize\": 5, \"concurrency\": 3, \"verbose\": false, \"workerId\": \"custom-worker-id\"}' -H \"Content-Type: application/json\"\n *\n * During development, you can run the following script to run the cron jobs continuously in the background:\n * pnpm cron\n */\nimport { getJobQueue, jobHandlers } from '@/lib/dataqueue/queue';\nimport { NextResponse } from 'next/server';\n\nexport async function POST(\n request: Request,\n { params }: { params: Promise<{ task: string[] }> },\n) {\n const { task } = await params;\n const authHeader = request.headers.get('authorization');\n if (authHeader !== \\`Bearer \\${process.env.CRON_SECRET}\\`) {\n return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });\n }\n\n if (!task || task.length === 0) {\n return NextResponse.json({ message: 'Task is required' }, { status: 400 });\n }\n\n const supportedTasks = ['reclaim', 'cleanup', 'process'];\n const theTask = task[0];\n if (!supportedTasks.includes(theTask)) {\n return NextResponse.json(\n { message: 'Task not supported' },\n { status: 400 },\n );\n }\n\n try {\n const jobQueue = getJobQueue();\n\n if (theTask === 'reclaim') {\n let maxProcessingTimeMinutes = 10;\n try {\n const body = await request.json();\n maxProcessingTimeMinutes = body.maxProcessingTimeMinutes || 10;\n } catch {\n // ignore parsing error and use default value\n }\n const reclaimed = await jobQueue.reclaimStuckJobs(\n maxProcessingTimeMinutes,\n );\n console.log(\\`Reclaimed \\${reclaimed} stuck jobs\\`);\n return NextResponse.json({\n message: \\`Stuck jobs reclaimed: \\${reclaimed} with maxProcessingTimeMinutes: \\${maxProcessingTimeMinutes}\\`,\n reclaimed,\n });\n }\n\n if (theTask === 'cleanup') {\n let daysToKeep = 30;\n try {\n const body = await request.json();\n daysToKeep = body.daysToKeep || 30;\n } catch {\n // ignore parsing error and use default value\n }\n const deleted = await jobQueue.cleanupOldJobs(daysToKeep);\n console.log(\\`Deleted \\${deleted} old jobs\\`);\n return NextResponse.json({\n message: \\`Old jobs cleaned up: \\${deleted} with daysToKeep: \\${daysToKeep}\\`,\n deleted,\n });\n }\n\n if (theTask === 'process') {\n let batchSize = 3;\n let concurrency = 2;\n let verbose = true;\n let workerId = \\`manage-\\${theTask}-\\${Date.now()}\\`;\n try {\n const body = await request.json();\n batchSize = body.batchSize || 3;\n concurrency = body.concurrency || 2;\n verbose = body.verbose || true;\n workerId = body.workerId || \\`manage-\\${theTask}-\\${Date.now()}\\`;\n } catch {\n // ignore parsing error and use default value\n }\n const processor = jobQueue.createProcessor(jobHandlers, {\n workerId,\n batchSize,\n concurrency,\n verbose,\n });\n const processed = await processor.start();\n\n return NextResponse.json({\n message: \\`Jobs processed: \\${processed} with workerId: \\${workerId}, batchSize: \\${batchSize}, concurrency: \\${concurrency}, and verbose: \\${verbose}\\`,\n processed,\n });\n }\n\n return NextResponse.json(\n { message: 'Task not supported' },\n { status: 400 },\n );\n } catch (error) {\n console.error('Error processing jobs:', error);\n return NextResponse.json(\n { message: 'Failed to process jobs' },\n { status: 500 },\n );\n }\n}\n`;\n\n/**\n * Pages router endpoint template for queue management.\n */\nexport const PAGES_ROUTER_ROUTE_TEMPLATE = `/**\n * This end point is used to manage the job queue.\n * It supports the following tasks:\n * - reclaim: Reclaim stuck jobs\n * - cleanup: Cleanup old jobs\n * - process: Process jobs\n *\n * Example usage with default values (reclaim stuck jobs for 10 minutes, cleanup old jobs for 30 days, and process jobs with batch size 3, concurrency 2, and verbose true):\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\"\n *\n * Example usage with custom values:\n * curl -X POST http://localhost:3000/api/dataqueue/manage/reclaim -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"maxProcessingTimeMinutes\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/cleanup -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"daysToKeep\": 15}' -H \"Content-Type: application/json\"\n * curl -X POST http://localhost:3000/api/dataqueue/manage/process -H \"Authorization: Bearer $CRON_SECRET\" -d '{\"batchSize\": 5, \"concurrency\": 3, \"verbose\": false, \"workerId\": \"custom-worker-id\"}' -H \"Content-Type: application/json\"\n *\n * During development, you can run the following script to run the cron jobs continuously in the background:\n * pnpm cron\n */\nimport type { NextApiRequest, NextApiResponse } from 'next';\nimport { getJobQueue, jobHandlers } from '@/lib/dataqueue/queue';\n\ntype ResponseBody = {\n message: string;\n reclaimed?: number;\n deleted?: number;\n processed?: number;\n};\n\nexport default async function handler(\n req: NextApiRequest,\n res: NextApiResponse<ResponseBody>,\n) {\n if (req.method !== 'POST') {\n res.setHeader('Allow', 'POST');\n return res.status(405).json({ message: 'Method not allowed' });\n }\n\n const authHeader = req.headers.authorization;\n if (authHeader !== \\`Bearer \\${process.env.CRON_SECRET}\\`) {\n return res.status(401).json({ message: 'Unauthorized' });\n }\n\n const task = req.query.task;\n const taskArray = Array.isArray(task) ? task : task ? [task] : [];\n if (!taskArray.length) {\n return res.status(400).json({ message: 'Task is required' });\n }\n\n const supportedTasks = ['reclaim', 'cleanup', 'process'];\n const theTask = taskArray[0];\n if (!supportedTasks.includes(theTask)) {\n return res.status(400).json({ message: 'Task not supported' });\n }\n\n try {\n const jobQueue = getJobQueue();\n const body = typeof req.body === 'object' && req.body ? req.body : {};\n\n if (theTask === 'reclaim') {\n const maxProcessingTimeMinutes = body.maxProcessingTimeMinutes || 10;\n const reclaimed = await jobQueue.reclaimStuckJobs(maxProcessingTimeMinutes);\n console.log(\\`Reclaimed \\${reclaimed} stuck jobs\\`);\n return res.status(200).json({\n message: \\`Stuck jobs reclaimed: \\${reclaimed} with maxProcessingTimeMinutes: \\${maxProcessingTimeMinutes}\\`,\n reclaimed,\n });\n }\n\n if (theTask === 'cleanup') {\n const daysToKeep = body.daysToKeep || 30;\n const deleted = await jobQueue.cleanupOldJobs(daysToKeep);\n console.log(\\`Deleted \\${deleted} old jobs\\`);\n return res.status(200).json({\n message: \\`Old jobs cleaned up: \\${deleted} with daysToKeep: \\${daysToKeep}\\`,\n deleted,\n });\n }\n\n const batchSize = body.batchSize || 3;\n const concurrency = body.concurrency || 2;\n const verbose = body.verbose || true;\n const workerId = body.workerId || \\`manage-\\${theTask}-\\${Date.now()}\\`;\n const processor = jobQueue.createProcessor(jobHandlers, {\n workerId,\n batchSize,\n concurrency,\n verbose,\n });\n const processed = await processor.start();\n\n return res.status(200).json({\n message: \\`Jobs processed: \\${processed} with workerId: \\${workerId}, batchSize: \\${batchSize}, concurrency: \\${concurrency}, and verbose: \\${verbose}\\`,\n processed,\n });\n } catch (error) {\n console.error('Error processing jobs:', error);\n return res.status(500).json({ message: 'Failed to process jobs' });\n }\n}\n`;\n\n/**\n * Cron script template for local queue processing.\n */\nexport const CRON_SH_TEMPLATE = `#!/bin/bash\n\n# This script is used to run the cron jobs for the demo app during development.\n# Run it with \\`pnpm cron\\` from the apps/demo directory.\n\nset -a\nsource \"$(dirname \"$0\")/.env.local\"\nset +a\n\nif [ -z \"$CRON_SECRET\" ]; then\n echo \"Error: CRON_SECRET environment variable is not set in .env.local\"\n exit 1\nfi\n\ncleanup() {\n kill 0\n wait\n}\ntrap cleanup SIGINT SIGTERM\n\nwhile true; do\n echo \"Processing jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/process -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 10 # Process jobs every 10 seconds\ndone &\n\nwhile true; do\n echo \"Reclaiming stuck jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/reclaim -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 20 # Reclaim stuck jobs every 20 seconds\ndone &\n\nwhile true; do\n echo \"Cleaning up old jobs...\"\n curl http://localhost:3000/api/dataqueue/manage/cleanup -X POST -H \"Authorization: Bearer $CRON_SECRET\"\n echo \"\"\n sleep 30 # Cleanup old jobs every 30 seconds\ndone &\n\nwait\n`;\n\n/**\n * Queue placeholder template with a single `send_email` job.\n */\nexport const QUEUE_TEMPLATE = `import { initJobQueue, JobHandlers } from '@nicnocquee/dataqueue';\n\nexport type JobPayloadMap = {\n send_email: {\n to: string;\n subject: string;\n body: string;\n };\n};\n\nlet jobQueue: ReturnType<typeof initJobQueue<JobPayloadMap>> | null = null;\n\nexport const getJobQueue = () => {\n if (!jobQueue) {\n jobQueue = initJobQueue<JobPayloadMap>({\n databaseConfig: {\n connectionString: process.env.PG_DATAQUEUE_DATABASE,\n },\n verbose: process.env.NODE_ENV === 'development',\n });\n }\n return jobQueue;\n};\n\nexport const jobHandlers: JobHandlers<JobPayloadMap> = {\n send_email: async (payload) => {\n const { to, subject, body } = payload;\n console.log('send_email placeholder:', { to, subject, body });\n },\n};\n`;\n\nexport interface InitDeps {\n log?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n exit?: (code: number) => void;\n cwd?: string;\n readFileSyncImpl?: typeof readFileSync;\n writeFileSyncImpl?: typeof writeFileSync;\n existsSyncImpl?: typeof existsSync;\n mkdirSyncImpl?: typeof mkdirSync;\n chmodSyncImpl?: typeof chmodSync;\n}\n\ntype RouterKind = 'app' | 'pages';\n\ninterface ProjectDetails {\n cwd: string;\n packageJsonPath: string;\n packageJson: JsonObject;\n srcRoot: string;\n router: RouterKind;\n}\n\n/**\n * Runs the `dataqueue-cli init` command.\n */\nexport function runInit({\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n cwd = process.cwd(),\n readFileSyncImpl = readFileSync,\n writeFileSyncImpl = writeFileSync,\n existsSyncImpl = existsSync,\n mkdirSyncImpl = mkdirSync,\n chmodSyncImpl = chmodSync,\n}: InitDeps = {}): void {\n try {\n log(`dataqueue: Initializing in ${cwd}...`);\n log('');\n\n const details = detectNextJsAndRouter({\n cwd,\n existsSyncImpl,\n readFileSyncImpl,\n });\n\n createScaffoldFiles({\n details,\n log,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n chmodSyncImpl,\n });\n\n updatePackageJson({\n details,\n log,\n writeFileSyncImpl,\n });\n\n log('');\n log(\n \"Done! Run your package manager's install command to install new dependencies.\",\n );\n exit(0);\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n error(`dataqueue: ${message}`);\n exit(1);\n }\n}\n\n/**\n * Detects that the current directory is a Next.js app and chooses the router.\n */\nexport function detectNextJsAndRouter({\n cwd,\n existsSyncImpl,\n readFileSyncImpl,\n}: {\n cwd: string;\n existsSyncImpl: typeof existsSync;\n readFileSyncImpl: typeof readFileSync;\n}): ProjectDetails {\n const packageJsonPath = path.join(cwd, 'package.json');\n if (!existsSyncImpl(packageJsonPath)) {\n throw new Error('package.json not found in current directory.');\n }\n\n const packageJson = parsePackageJson(\n readFileSyncImpl(packageJsonPath, 'utf8'),\n packageJsonPath,\n );\n if (!isNextJsProject(packageJson)) {\n throw new Error(\n \"Not a Next.js project. Could not find 'next' in package.json dependencies.\",\n );\n }\n\n const srcDir = path.join(cwd, 'src');\n const srcRoot = existsSyncImpl(srcDir) ? 'src' : '.';\n const appDir = path.join(cwd, srcRoot, 'app');\n const pagesDir = path.join(cwd, srcRoot, 'pages');\n const hasAppDir = existsSyncImpl(appDir);\n const hasPagesDir = existsSyncImpl(pagesDir);\n\n if (!hasAppDir && !hasPagesDir) {\n throw new Error(\n 'Could not detect Next.js router. Expected either app/ or pages/ directory.',\n );\n }\n\n const router: RouterKind = hasAppDir ? 'app' : 'pages';\n return { cwd, packageJsonPath, packageJson, srcRoot, router };\n}\n\n/**\n * Updates package.json with required dependencies and scripts.\n */\nfunction updatePackageJson({\n details,\n log,\n writeFileSyncImpl,\n}: {\n details: ProjectDetails;\n log: (...args: any[]) => void;\n writeFileSyncImpl: typeof writeFileSync;\n}): void {\n const packageJson = details.packageJson;\n const dependencies = ensureStringMapSection(packageJson, 'dependencies');\n const devDependencies = ensureStringMapSection(\n packageJson,\n 'devDependencies',\n );\n const scripts = ensureStringMapSection(packageJson, 'scripts');\n\n for (const dependency of DEPENDENCIES_TO_ADD) {\n if (dependencies[dependency]) {\n log(` [skipped] dependency ${dependency} (already exists)`);\n continue;\n }\n dependencies[dependency] = 'latest';\n log(` [added] dependency ${dependency}`);\n }\n\n for (const devDependency of DEV_DEPENDENCIES_TO_ADD) {\n if (devDependencies[devDependency]) {\n log(` [skipped] devDependency ${devDependency} (already exists)`);\n continue;\n }\n devDependencies[devDependency] = 'latest';\n log(` [added] devDependency ${devDependency}`);\n }\n\n for (const [scriptName, scriptValue] of Object.entries(SCRIPTS_TO_ADD)) {\n if (scripts[scriptName]) {\n log(` [skipped] script \"${scriptName}\" (already exists)`);\n continue;\n }\n scripts[scriptName] = scriptValue;\n log(` [added] script \"${scriptName}\"`);\n }\n\n writeFileSyncImpl(\n details.packageJsonPath,\n `${JSON.stringify(packageJson, null, 2)}\\n`,\n );\n}\n\n/**\n * Creates all scaffold files for the detected router without overwriting.\n */\nfunction createScaffoldFiles({\n details,\n log,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n chmodSyncImpl,\n}: {\n details: ProjectDetails;\n log: (...args: any[]) => void;\n existsSyncImpl: typeof existsSync;\n mkdirSyncImpl: typeof mkdirSync;\n writeFileSyncImpl: typeof writeFileSync;\n chmodSyncImpl: typeof chmodSync;\n}): void {\n const appRoutePath = path.join(\n details.cwd,\n details.srcRoot,\n 'app',\n 'api',\n 'dataqueue',\n 'manage',\n '[[...task]]',\n 'route.ts',\n );\n const pagesRoutePath = path.join(\n details.cwd,\n details.srcRoot,\n 'pages',\n 'api',\n 'dataqueue',\n 'manage',\n '[[...task]].ts',\n );\n const queuePath = path.join(\n details.cwd,\n details.srcRoot,\n 'lib',\n 'dataqueue',\n 'queue.ts',\n );\n const cronPath = path.join(details.cwd, 'cron.sh');\n\n if (details.router === 'app') {\n createFileIfMissing({\n absolutePath: appRoutePath,\n content: APP_ROUTER_ROUTE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, appRoutePath),\n });\n log(\n ' [skipped] pages/api/dataqueue/manage/[[...task]].ts (router not selected)',\n );\n } else {\n log(\n ' [skipped] app/api/dataqueue/manage/[[...task]]/route.ts (router not selected)',\n );\n createFileIfMissing({\n absolutePath: pagesRoutePath,\n content: PAGES_ROUTER_ROUTE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, pagesRoutePath),\n });\n }\n\n createFileIfMissing({\n absolutePath: cronPath,\n content: CRON_SH_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: 'cron.sh',\n });\n if (existsSyncImpl(cronPath)) {\n chmodSyncImpl(cronPath, 0o755);\n }\n\n createFileIfMissing({\n absolutePath: queuePath,\n content: QUEUE_TEMPLATE,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath: toRelativePath(details.cwd, queuePath),\n });\n}\n\n/**\n * Creates a file only if it does not already exist.\n */\nfunction createFileIfMissing({\n absolutePath,\n content,\n existsSyncImpl,\n mkdirSyncImpl,\n writeFileSyncImpl,\n log,\n logPath,\n}: {\n absolutePath: string;\n content: string;\n existsSyncImpl: typeof existsSync;\n mkdirSyncImpl: typeof mkdirSync;\n writeFileSyncImpl: typeof writeFileSync;\n log: (...args: any[]) => void;\n logPath: string;\n}): void {\n if (existsSyncImpl(absolutePath)) {\n log(` [skipped] ${logPath} (already exists)`);\n return;\n }\n\n mkdirSyncImpl(path.dirname(absolutePath), { recursive: true });\n writeFileSyncImpl(absolutePath, content);\n log(` [created] ${logPath}`);\n}\n\n/**\n * Parses package.json content with clear source context.\n */\nfunction parsePackageJson(content: string, filePath: string): JsonObject {\n try {\n const parsed = JSON.parse(content);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('package.json must contain an object.');\n }\n return parsed as JsonObject;\n } catch (cause) {\n throw new Error(\n `Failed to parse package.json at ${filePath}: ${\n cause instanceof Error ? cause.message : String(cause)\n }`,\n );\n }\n}\n\n/**\n * Returns true when package.json declares Next.js in deps or devDeps.\n */\nfunction isNextJsProject(packageJson: JsonObject): boolean {\n const dependencies = packageJson.dependencies;\n const devDependencies = packageJson.devDependencies;\n\n return (\n hasPackage(dependencies, 'next') || hasPackage(devDependencies, 'next')\n );\n}\n\n/**\n * Returns true when a package name exists in a dependency section object.\n */\nfunction hasPackage(section: unknown, packageName: string): boolean {\n if (!section || typeof section !== 'object' || Array.isArray(section)) {\n return false;\n }\n return Boolean((section as JsonMap)[packageName]);\n}\n\n/**\n * Ensures package.json has a string map section and returns it.\n */\nfunction ensureStringMapSection(\n packageJson: JsonObject,\n sectionName: 'dependencies' | 'devDependencies' | 'scripts',\n): JsonMap {\n const currentValue = packageJson[sectionName];\n if (\n !currentValue ||\n typeof currentValue !== 'object' ||\n Array.isArray(currentValue)\n ) {\n packageJson[sectionName] = {};\n }\n return packageJson[sectionName] as JsonMap;\n}\n\n/**\n * Converts an absolute path to a stable relative path for log output.\n */\nfunction toRelativePath(cwd: string, absolutePath: string): string {\n const relative = path.relative(cwd, absolutePath);\n return relative || '.';\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface InstallSkillsDeps {\n log?: (...args: unknown[]) => void;\n error?: (...args: unknown[]) => void;\n exit?: (code: number) => void;\n cwd?: string;\n existsSync?: (p: string) => boolean;\n mkdirSync?: (p: string, opts?: fs.MakeDirectoryOptions) => void;\n copyFileSync?: (src: string, dest: string) => void;\n readdirSync?: (p: string) => string[];\n skillsSourceDir?: string;\n}\n\nconst SKILL_DIRS = ['dataqueue-core', 'dataqueue-advanced', 'dataqueue-react'];\n\ninterface AiTool {\n name: string;\n targetDir: string;\n}\n\n/**\n * Detects which AI tools have config directories in the project.\n *\n * @param cwd - Current working directory to scan.\n * @param existsSync - Injectable fs.existsSync.\n * @returns Array of detected AI tools with their skills target directories.\n */\nexport function detectAiTools(\n cwd: string,\n existsSync: (p: string) => boolean = fs.existsSync,\n): AiTool[] {\n const tools: AiTool[] = [];\n const checks: Array<{ name: string; indicator: string; targetDir: string }> =\n [\n {\n name: 'Cursor',\n indicator: '.cursor',\n targetDir: '.cursor/skills',\n },\n {\n name: 'Claude Code',\n indicator: '.claude',\n targetDir: '.claude/skills',\n },\n {\n name: 'GitHub Copilot',\n indicator: '.github',\n targetDir: '.github/skills',\n },\n ];\n\n for (const check of checks) {\n if (existsSync(path.join(cwd, check.indicator))) {\n tools.push({ name: check.name, targetDir: check.targetDir });\n }\n }\n\n return tools;\n}\n\n/**\n * Installs DataQueue skill files into detected AI tool directories.\n *\n * @param deps - Injectable dependencies for testing.\n */\nexport function runInstallSkills({\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n cwd = process.cwd(),\n existsSync = fs.existsSync,\n mkdirSync = fs.mkdirSync,\n copyFileSync = fs.copyFileSync,\n readdirSync = fs.readdirSync,\n skillsSourceDir = path.join(__dirname, '../ai/skills'),\n}: InstallSkillsDeps = {}): void {\n const tools = detectAiTools(cwd, existsSync);\n\n if (tools.length === 0) {\n log('No AI tool directories detected (.cursor/, .claude/, .github/).');\n log('Creating .cursor/skills/ as the default target.');\n tools.push({ name: 'Cursor', targetDir: '.cursor/skills' });\n }\n\n let installed = 0;\n\n for (const tool of tools) {\n log(`\\nInstalling skills for ${tool.name}...`);\n\n for (const skillDir of SKILL_DIRS) {\n const srcDir = path.join(skillsSourceDir, skillDir);\n const destDir = path.join(cwd, tool.targetDir, skillDir);\n\n try {\n mkdirSync(destDir, { recursive: true });\n\n const files = readdirSync(srcDir);\n for (const file of files) {\n copyFileSync(path.join(srcDir, file), path.join(destDir, file));\n }\n\n log(` ✓ ${skillDir}`);\n installed++;\n } catch (err) {\n error(` ✗ Failed to install ${skillDir}:`, err);\n }\n }\n }\n\n if (installed > 0) {\n log(\n `\\nDone! Installed ${installed} skill(s) for ${tools.map((t) => t.name).join(', ')}.`,\n );\n } else {\n error('No skills were installed.');\n exit(1);\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport readline from 'readline';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface InstallRulesDeps {\n log?: (...args: unknown[]) => void;\n error?: (...args: unknown[]) => void;\n exit?: (code: number) => void;\n cwd?: string;\n readFileSync?: (p: string, enc: BufferEncoding) => string;\n writeFileSync?: (p: string, data: string) => void;\n appendFileSync?: (p: string, data: string) => void;\n mkdirSync?: (p: string, opts?: fs.MakeDirectoryOptions) => void;\n existsSync?: (p: string) => boolean;\n rulesSourceDir?: string;\n /** Override for selecting the client (skips interactive prompt). */\n selectedClient?: string;\n}\n\nconst RULE_FILES = ['basic.md', 'advanced.md', 'react-dashboard.md'];\n\ninterface ClientConfig {\n label: string;\n install: (\n deps: Required<\n Pick<\n InstallRulesDeps,\n | 'cwd'\n | 'readFileSync'\n | 'writeFileSync'\n | 'appendFileSync'\n | 'mkdirSync'\n | 'existsSync'\n | 'log'\n | 'rulesSourceDir'\n >\n >,\n ) => void;\n}\n\nconst MARKER_START = '<!-- DATAQUEUE RULES START -->';\nconst MARKER_END = '<!-- DATAQUEUE RULES END -->';\n\n/**\n * Appends or replaces a marked section in a file.\n *\n * @param filePath - Path to the file to update.\n * @param content - Content to insert between markers.\n * @param deps - Injectable file system functions.\n */\nexport function upsertMarkedSection(\n filePath: string,\n content: string,\n deps: {\n readFileSync: (p: string, enc: BufferEncoding) => string;\n writeFileSync: (p: string, data: string) => void;\n existsSync: (p: string) => boolean;\n },\n): void {\n const block = `${MARKER_START}\\n${content}\\n${MARKER_END}`;\n\n if (!deps.existsSync(filePath)) {\n deps.writeFileSync(filePath, block + '\\n');\n return;\n }\n\n const existing = deps.readFileSync(filePath, 'utf-8');\n const startIdx = existing.indexOf(MARKER_START);\n const endIdx = existing.indexOf(MARKER_END);\n\n if (startIdx !== -1 && endIdx !== -1) {\n const before = existing.slice(0, startIdx);\n const after = existing.slice(endIdx + MARKER_END.length);\n deps.writeFileSync(filePath, before + block + after);\n } else {\n deps.writeFileSync(filePath, existing.trimEnd() + '\\n\\n' + block + '\\n');\n }\n}\n\nfunction getAllRulesContent(\n rulesSourceDir: string,\n readFileSync: (p: string, enc: BufferEncoding) => string,\n): string {\n return RULE_FILES.map((f) =>\n readFileSync(path.join(rulesSourceDir, f), 'utf-8'),\n ).join('\\n\\n');\n}\n\nconst CLIENTS: Record<string, ClientConfig> = {\n '1': {\n label: 'Cursor',\n install: (deps) => {\n const rulesDir = path.join(deps.cwd, '.cursor', 'rules');\n deps.mkdirSync(rulesDir, { recursive: true });\n\n for (const file of RULE_FILES) {\n const src = deps.readFileSync(\n path.join(deps.rulesSourceDir, file),\n 'utf-8',\n );\n const destName = `dataqueue-${file.replace(/\\.md$/, '.mdc')}`;\n deps.writeFileSync(path.join(rulesDir, destName), src);\n deps.log(` ✓ .cursor/rules/${destName}`);\n }\n },\n },\n '2': {\n label: 'Claude Code',\n install: (deps) => {\n const content = getAllRulesContent(\n deps.rulesSourceDir,\n deps.readFileSync,\n );\n const filePath = path.join(deps.cwd, 'CLAUDE.md');\n upsertMarkedSection(filePath, content, deps);\n deps.log(` ✓ CLAUDE.md`);\n },\n },\n '3': {\n label: 'AGENTS.md (Codex, Jules, OpenCode)',\n install: (deps) => {\n const content = getAllRulesContent(\n deps.rulesSourceDir,\n deps.readFileSync,\n );\n const filePath = path.join(deps.cwd, 'AGENTS.md');\n upsertMarkedSection(filePath, content, deps);\n deps.log(` ✓ AGENTS.md`);\n },\n },\n '4': {\n label: 'GitHub Copilot',\n install: (deps) => {\n const content = getAllRulesContent(\n deps.rulesSourceDir,\n deps.readFileSync,\n );\n deps.mkdirSync(path.join(deps.cwd, '.github'), { recursive: true });\n const filePath = path.join(\n deps.cwd,\n '.github',\n 'copilot-instructions.md',\n );\n upsertMarkedSection(filePath, content, deps);\n deps.log(` ✓ .github/copilot-instructions.md`);\n },\n },\n '5': {\n label: 'Windsurf',\n install: (deps) => {\n const content = getAllRulesContent(\n deps.rulesSourceDir,\n deps.readFileSync,\n );\n const filePath = path.join(deps.cwd, 'CONVENTIONS.md');\n upsertMarkedSection(filePath, content, deps);\n deps.log(` ✓ CONVENTIONS.md`);\n },\n },\n};\n\n/**\n * Installs DataQueue agent rules for the selected AI client.\n *\n * @param deps - Injectable dependencies for testing.\n */\nexport async function runInstallRules({\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n cwd = process.cwd(),\n readFileSync = fs.readFileSync,\n writeFileSync = fs.writeFileSync,\n appendFileSync = fs.appendFileSync,\n mkdirSync = fs.mkdirSync,\n existsSync = fs.existsSync,\n rulesSourceDir = path.join(__dirname, '../ai/rules'),\n selectedClient,\n}: InstallRulesDeps = {}): Promise<void> {\n log('DataQueue Agent Rules Installer\\n');\n log('Select your AI client:\\n');\n\n for (const [key, client] of Object.entries(CLIENTS)) {\n log(` ${key}) ${client.label}`);\n }\n log('');\n\n let choice = selectedClient;\n\n if (!choice) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n choice = await new Promise<string>((resolve) => {\n rl.question('Enter choice (1-5): ', (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n }\n\n const client = CLIENTS[choice];\n if (!client) {\n error(`Invalid choice: \"${choice}\". Expected 1-5.`);\n exit(1);\n return;\n }\n\n log(`\\nInstalling rules for ${client.label}...`);\n\n try {\n client.install({\n cwd,\n readFileSync,\n writeFileSync,\n appendFileSync,\n mkdirSync,\n existsSync,\n log,\n rulesSourceDir,\n });\n log('\\nDone!');\n } catch (err) {\n error('Failed to install rules:', err);\n exit(1);\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport readline from 'readline';\n\nexport interface InstallMcpDeps {\n log?: (...args: unknown[]) => void;\n error?: (...args: unknown[]) => void;\n exit?: (code: number) => void;\n cwd?: string;\n readFileSync?: (p: string, enc: BufferEncoding) => string;\n writeFileSync?: (p: string, data: string) => void;\n mkdirSync?: (p: string, opts?: fs.MakeDirectoryOptions) => void;\n existsSync?: (p: string) => boolean;\n /** Override for selecting the client (skips interactive prompt). */\n selectedClient?: string;\n}\n\ninterface McpClientConfig {\n label: string;\n install: (\n deps: Required<\n Pick<\n InstallMcpDeps,\n | 'cwd'\n | 'readFileSync'\n | 'writeFileSync'\n | 'mkdirSync'\n | 'existsSync'\n | 'log'\n >\n >,\n ) => void;\n}\n\n/**\n * Merges the dataqueue MCP server config into an existing JSON config file.\n *\n * @param filePath - Path to the MCP config file.\n * @param serverKey - Key name for the server entry.\n * @param serverConfig - Server configuration object.\n * @param deps - Injectable file system functions.\n */\nexport function upsertMcpConfig(\n filePath: string,\n serverKey: string,\n serverConfig: Record<string, unknown>,\n deps: {\n readFileSync: (p: string, enc: BufferEncoding) => string;\n writeFileSync: (p: string, data: string) => void;\n existsSync: (p: string) => boolean;\n },\n): void {\n let config: Record<string, unknown> = {};\n\n if (deps.existsSync(filePath)) {\n try {\n config = JSON.parse(deps.readFileSync(filePath, 'utf-8'));\n } catch {\n config = {};\n }\n }\n\n if (!config.mcpServers || typeof config.mcpServers !== 'object') {\n config.mcpServers = {};\n }\n\n (config.mcpServers as Record<string, unknown>)[serverKey] = serverConfig;\n deps.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n');\n}\n\nconst MCP_SERVER_CONFIG = {\n command: 'npx',\n args: ['dataqueue-cli', 'mcp'],\n};\n\nconst MCP_CLIENTS: Record<string, McpClientConfig> = {\n '1': {\n label: 'Cursor',\n install: (deps) => {\n const configDir = path.join(deps.cwd, '.cursor');\n deps.mkdirSync(configDir, { recursive: true });\n const configFile = path.join(configDir, 'mcp.json');\n upsertMcpConfig(configFile, 'dataqueue', MCP_SERVER_CONFIG, deps);\n deps.log(` ✓ .cursor/mcp.json`);\n },\n },\n '2': {\n label: 'Claude Code',\n install: (deps) => {\n const configFile = path.join(deps.cwd, '.mcp.json');\n upsertMcpConfig(configFile, 'dataqueue', MCP_SERVER_CONFIG, deps);\n deps.log(` ✓ .mcp.json`);\n },\n },\n '3': {\n label: 'VS Code (Copilot)',\n install: (deps) => {\n const configDir = path.join(deps.cwd, '.vscode');\n deps.mkdirSync(configDir, { recursive: true });\n const configFile = path.join(configDir, 'mcp.json');\n upsertMcpConfig(configFile, 'dataqueue', MCP_SERVER_CONFIG, deps);\n deps.log(` ✓ .vscode/mcp.json`);\n },\n },\n '4': {\n label: 'Windsurf',\n install: (deps) => {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '';\n const configFile = path.join(\n homeDir,\n '.codeium',\n 'windsurf',\n 'mcp_config.json',\n );\n deps.mkdirSync(path.dirname(configFile), { recursive: true });\n upsertMcpConfig(configFile, 'dataqueue', MCP_SERVER_CONFIG, deps);\n deps.log(` ✓ ~/.codeium/windsurf/mcp_config.json`);\n },\n },\n};\n\n/**\n * Installs the DataQueue MCP server config for the selected AI client.\n *\n * @param deps - Injectable dependencies for testing.\n */\nexport async function runInstallMcp({\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n cwd = process.cwd(),\n readFileSync = fs.readFileSync,\n writeFileSync = fs.writeFileSync,\n mkdirSync = fs.mkdirSync,\n existsSync = fs.existsSync,\n selectedClient,\n}: InstallMcpDeps = {}): Promise<void> {\n log('DataQueue MCP Server Installer\\n');\n log('Select your AI client:\\n');\n\n for (const [key, client] of Object.entries(MCP_CLIENTS)) {\n log(` ${key}) ${client.label}`);\n }\n log('');\n\n let choice = selectedClient;\n\n if (!choice) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n choice = await new Promise<string>((resolve) => {\n rl.question('Enter choice (1-4): ', (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n }\n\n const client = MCP_CLIENTS[choice];\n if (!client) {\n error(`Invalid choice: \"${choice}\". Expected 1-4.`);\n exit(1);\n return;\n }\n\n log(`\\nInstalling MCP config for ${client.label}...`);\n\n try {\n client.install({\n cwd,\n readFileSync,\n writeFileSync,\n mkdirSync,\n existsSync,\n log,\n });\n log('\\nDone! The MCP server will run via: npx dataqueue-cli mcp');\n } catch (err) {\n error('Failed to install MCP config:', err);\n exit(1);\n }\n}\n","#!/usr/bin/env node\n\n/**\n * DataQueue MCP Server — exposes documentation search over stdio.\n * Run via: dataqueue-cli mcp\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\ninterface DocPage {\n slug: string;\n title: string;\n description: string;\n content: string;\n}\n\n/** @internal Loads docs-content.json from the ai/ directory bundled with the package. */\nexport function loadDocsContent(\n docsPath: string = path.join(__dirname, '../ai/docs-content.json'),\n): DocPage[] {\n const raw = fs.readFileSync(docsPath, 'utf-8');\n return JSON.parse(raw) as DocPage[];\n}\n\n/** @internal Scores a doc page against a search query using simple term matching. */\nexport function scorePageForQuery(page: DocPage, queryTerms: string[]): number {\n const titleLower = page.title.toLowerCase();\n const descLower = page.description.toLowerCase();\n const contentLower = page.content.toLowerCase();\n\n let score = 0;\n for (const term of queryTerms) {\n if (titleLower.includes(term)) score += 10;\n if (descLower.includes(term)) score += 5;\n\n const contentMatches = contentLower.split(term).length - 1;\n score += Math.min(contentMatches, 10);\n }\n return score;\n}\n\n/** @internal Extracts a relevant excerpt around the first match of any query term. */\nexport function extractExcerpt(\n content: string,\n queryTerms: string[],\n maxLength = 500,\n): string {\n const lower = content.toLowerCase();\n let earliestIndex = -1;\n\n for (const term of queryTerms) {\n const idx = lower.indexOf(term);\n if (idx !== -1 && (earliestIndex === -1 || idx < earliestIndex)) {\n earliestIndex = idx;\n }\n }\n\n if (earliestIndex === -1) {\n return content.slice(0, maxLength);\n }\n\n const start = Math.max(0, earliestIndex - 100);\n const end = Math.min(content.length, start + maxLength);\n let excerpt = content.slice(start, end);\n\n if (start > 0) excerpt = '...' + excerpt;\n if (end < content.length) excerpt = excerpt + '...';\n\n return excerpt;\n}\n\n/**\n * Creates and starts the DataQueue MCP server over stdio.\n *\n * @param deps - Injectable dependencies for testing.\n */\nexport async function startMcpServer(\n deps: {\n docsPath?: string;\n transport?: InstanceType<typeof StdioServerTransport>;\n } = {},\n): Promise<McpServer> {\n const pages = loadDocsContent(deps.docsPath);\n\n const server = new McpServer({\n name: 'dataqueue-docs',\n version: '1.0.0',\n });\n\n server.resource('llms-txt', 'dataqueue://llms.txt', async () => {\n const llmsPath = path.join(\n __dirname,\n '../ai/skills/dataqueue-core/SKILL.md',\n );\n let content: string;\n try {\n content = fs.readFileSync(llmsPath, 'utf-8');\n } catch {\n content = pages\n .map((p) => `## ${p.title}\\n\\nSlug: ${p.slug}\\n\\n${p.description}`)\n .join('\\n\\n');\n }\n return { contents: [{ uri: 'dataqueue://llms.txt', text: content }] };\n });\n\n server.tool(\n 'list-doc-pages',\n 'List all available DataQueue documentation pages with titles and descriptions.',\n {},\n async () => {\n const listing = pages.map((p) => ({\n slug: p.slug,\n title: p.title,\n description: p.description,\n }));\n return {\n content: [\n { type: 'text' as const, text: JSON.stringify(listing, null, 2) },\n ],\n };\n },\n );\n\n server.tool(\n 'get-doc-page',\n 'Fetch a specific DataQueue doc page by slug. Returns full page content as markdown.',\n {\n slug: z\n .string()\n .describe('The doc page slug, e.g. \"usage/add-job\" or \"api/job-queue\"'),\n },\n async ({ slug }) => {\n const page = pages.find((p) => p.slug === slug);\n if (!page) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Page not found: \"${slug}\". Use list-doc-pages to see available slugs.`,\n },\n ],\n isError: true,\n };\n }\n const header = page.description\n ? `# ${page.title}\\n\\n> ${page.description}\\n\\n`\n : `# ${page.title}\\n\\n`;\n return {\n content: [{ type: 'text' as const, text: header + page.content }],\n };\n },\n );\n\n server.tool(\n 'search-docs',\n 'Full-text search across all DataQueue documentation pages. Returns matching sections with page titles and content excerpts.',\n {\n query: z\n .string()\n .describe('Search query, e.g. \"cron scheduling\" or \"waitForToken\"'),\n },\n async ({ query }) => {\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 1);\n\n if (queryTerms.length === 0) {\n return {\n content: [\n { type: 'text' as const, text: 'Please provide a search query.' },\n ],\n isError: true,\n };\n }\n\n const scored = pages\n .map((page) => ({\n page,\n score: scorePageForQuery(page, queryTerms),\n }))\n .filter((r) => r.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, 5);\n\n if (scored.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No results for \"${query}\". Try different keywords or use list-doc-pages to browse.`,\n },\n ],\n };\n }\n\n const results = scored.map((r) => {\n const excerpt = extractExcerpt(r.page.content, queryTerms);\n return `## ${r.page.title} (${r.page.slug})\\n\\n${r.page.description}\\n\\n${excerpt}`;\n });\n\n return {\n content: [{ type: 'text' as const, text: results.join('\\n\\n---\\n\\n') }],\n };\n },\n );\n\n const transport = deps.transport ?? new StdioServerTransport();\n await server.connect(transport);\n return server;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n (process.argv[1].endsWith('/mcp-server.js') ||\n process.argv[1].endsWith('/mcp-server.cjs'));\n\nif (isDirectRun) {\n startMcpServer().catch((err) => {\n console.error('Failed to start MCP server:', err);\n process.exit(1);\n });\n}\n","// Testable CLI logic for dataqueue\nimport { spawnSync, SpawnSyncReturns } from 'child_process';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { InitDeps, runInit } from './init-command.js';\nimport {\n runInstallSkills,\n InstallSkillsDeps,\n} from './install-skills-command.js';\nimport { runInstallRules, InstallRulesDeps } from './install-rules-command.js';\nimport { runInstallMcp, InstallMcpDeps } from './install-mcp-command.js';\nimport { startMcpServer } from './mcp-server.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface CliDeps {\n log?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n exit?: (code: number) => void;\n spawnSyncImpl?: (...args: any[]) => SpawnSyncReturns<any>;\n migrationsDir?: string;\n initDeps?: InitDeps;\n runInitImpl?: (deps?: InitDeps) => void;\n installSkillsDeps?: InstallSkillsDeps;\n runInstallSkillsImpl?: (deps?: InstallSkillsDeps) => void;\n installRulesDeps?: InstallRulesDeps;\n runInstallRulesImpl?: (deps?: InstallRulesDeps) => Promise<void>;\n installMcpDeps?: InstallMcpDeps;\n runInstallMcpImpl?: (deps?: InstallMcpDeps) => Promise<void>;\n startMcpServerImpl?: typeof startMcpServer;\n}\n\nexport function runCli(\n argv: string[],\n {\n log = console.log,\n error = console.error,\n exit = (code: number) => process.exit(code),\n spawnSyncImpl = spawnSync,\n migrationsDir = path.join(__dirname, '../migrations'),\n initDeps,\n runInitImpl = runInit,\n installSkillsDeps,\n runInstallSkillsImpl = runInstallSkills,\n installRulesDeps,\n runInstallRulesImpl = runInstallRules,\n installMcpDeps,\n runInstallMcpImpl = runInstallMcp,\n startMcpServerImpl = startMcpServer,\n }: CliDeps = {},\n): void {\n const [, , command, ...restArgs] = argv;\n\n function printUsage() {\n log('Usage:');\n log(\n ' dataqueue-cli migrate [--envPath <path>] [-s <schema> | --schema <schema>]',\n );\n log(' dataqueue-cli init');\n log(' dataqueue-cli install-skills');\n log(' dataqueue-cli install-rules');\n log(' dataqueue-cli install-mcp');\n log(' dataqueue-cli mcp');\n log('');\n log('Options for migrate:');\n log(\n ' --envPath <path> Path to a .env file to load environment variables (passed to node-pg-migrate)',\n );\n log(\n ' -s, --schema <schema> Set the schema to use (passed to node-pg-migrate)',\n );\n log('');\n log('AI tooling commands:');\n log(' install-skills Install DataQueue skill files for AI assistants');\n log(' install-rules Install DataQueue agent rules for AI clients');\n log(\n ' install-mcp Configure the DataQueue MCP server for AI clients',\n );\n log(' mcp Start the DataQueue MCP server (stdio)');\n exit(1);\n }\n\n if (command === 'migrate') {\n // Support for -s or --schema argument\n let schemaArg: string[] = [];\n const sIndex = restArgs.indexOf('-s');\n const schemaIndex = restArgs.indexOf('--schema');\n if (sIndex !== -1 && restArgs[sIndex + 1]) {\n schemaArg = ['-s', restArgs[sIndex + 1], '--create-schema'];\n restArgs.splice(sIndex, 2);\n } else if (schemaIndex !== -1 && restArgs[schemaIndex + 1]) {\n schemaArg = ['-s', restArgs[schemaIndex + 1], '--create-schema'];\n restArgs.splice(schemaIndex, 2);\n }\n\n // Support for --envPath argument\n let envPathArg: string[] = [];\n const envPathIndex = restArgs.indexOf('--envPath');\n if (envPathIndex !== -1 && restArgs[envPathIndex + 1]) {\n envPathArg = ['--envPath', restArgs[envPathIndex + 1]];\n }\n\n const result: SpawnSyncReturns<any> = spawnSyncImpl(\n 'npx',\n [\n 'node-pg-migrate',\n 'up',\n '-t',\n 'dataqueuedev_migrations',\n '-d',\n 'PG_DATAQUEUE_DATABASE',\n '-m',\n migrationsDir,\n ...schemaArg,\n ...envPathArg,\n ...restArgs,\n ],\n { stdio: 'inherit' },\n );\n exit(result.status ?? 1);\n } else if (command === 'init') {\n runInitImpl({\n log,\n error,\n exit,\n ...initDeps,\n });\n } else if (command === 'install-skills') {\n runInstallSkillsImpl({\n log,\n error,\n exit,\n ...installSkillsDeps,\n });\n } else if (command === 'install-rules') {\n runInstallRulesImpl({\n log,\n error,\n exit,\n ...installRulesDeps,\n });\n } else if (command === 'install-mcp') {\n runInstallMcpImpl({\n log,\n error,\n exit,\n ...installMcpDeps,\n });\n } else if (command === 'mcp') {\n startMcpServerImpl().catch((err) => {\n error('Failed to start MCP server:', err);\n exit(1);\n });\n } else {\n printUsage();\n }\n}\n"]}
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
5
+ var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
6
+ var zod = require('zod');
7
+ var fs = require('fs');
8
+ var path = require('path');
9
+ var url = require('url');
10
+
11
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
15
+ var path__default = /*#__PURE__*/_interopDefault(path);
16
+
17
+ var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('mcp-server.cjs', document.baseURI).href)));
18
+ var __dirname$1 = path__default.default.dirname(__filename$1);
19
+ function loadDocsContent(docsPath = path__default.default.join(__dirname$1, "../ai/docs-content.json")) {
20
+ const raw = fs__default.default.readFileSync(docsPath, "utf-8");
21
+ return JSON.parse(raw);
22
+ }
23
+ function scorePageForQuery(page, queryTerms) {
24
+ const titleLower = page.title.toLowerCase();
25
+ const descLower = page.description.toLowerCase();
26
+ const contentLower = page.content.toLowerCase();
27
+ let score = 0;
28
+ for (const term of queryTerms) {
29
+ if (titleLower.includes(term)) score += 10;
30
+ if (descLower.includes(term)) score += 5;
31
+ const contentMatches = contentLower.split(term).length - 1;
32
+ score += Math.min(contentMatches, 10);
33
+ }
34
+ return score;
35
+ }
36
+ function extractExcerpt(content, queryTerms, maxLength = 500) {
37
+ const lower = content.toLowerCase();
38
+ let earliestIndex = -1;
39
+ for (const term of queryTerms) {
40
+ const idx = lower.indexOf(term);
41
+ if (idx !== -1 && (earliestIndex === -1 || idx < earliestIndex)) {
42
+ earliestIndex = idx;
43
+ }
44
+ }
45
+ if (earliestIndex === -1) {
46
+ return content.slice(0, maxLength);
47
+ }
48
+ const start = Math.max(0, earliestIndex - 100);
49
+ const end = Math.min(content.length, start + maxLength);
50
+ let excerpt = content.slice(start, end);
51
+ if (start > 0) excerpt = "..." + excerpt;
52
+ if (end < content.length) excerpt = excerpt + "...";
53
+ return excerpt;
54
+ }
55
+ async function startMcpServer(deps = {}) {
56
+ const pages = loadDocsContent(deps.docsPath);
57
+ const server = new mcp_js.McpServer({
58
+ name: "dataqueue-docs",
59
+ version: "1.0.0"
60
+ });
61
+ server.resource("llms-txt", "dataqueue://llms.txt", async () => {
62
+ const llmsPath = path__default.default.join(
63
+ __dirname$1,
64
+ "../ai/skills/dataqueue-core/SKILL.md"
65
+ );
66
+ let content;
67
+ try {
68
+ content = fs__default.default.readFileSync(llmsPath, "utf-8");
69
+ } catch {
70
+ content = pages.map((p) => `## ${p.title}
71
+
72
+ Slug: ${p.slug}
73
+
74
+ ${p.description}`).join("\n\n");
75
+ }
76
+ return { contents: [{ uri: "dataqueue://llms.txt", text: content }] };
77
+ });
78
+ server.tool(
79
+ "list-doc-pages",
80
+ "List all available DataQueue documentation pages with titles and descriptions.",
81
+ {},
82
+ async () => {
83
+ const listing = pages.map((p) => ({
84
+ slug: p.slug,
85
+ title: p.title,
86
+ description: p.description
87
+ }));
88
+ return {
89
+ content: [
90
+ { type: "text", text: JSON.stringify(listing, null, 2) }
91
+ ]
92
+ };
93
+ }
94
+ );
95
+ server.tool(
96
+ "get-doc-page",
97
+ "Fetch a specific DataQueue doc page by slug. Returns full page content as markdown.",
98
+ {
99
+ slug: zod.z.string().describe('The doc page slug, e.g. "usage/add-job" or "api/job-queue"')
100
+ },
101
+ async ({ slug }) => {
102
+ const page = pages.find((p) => p.slug === slug);
103
+ if (!page) {
104
+ return {
105
+ content: [
106
+ {
107
+ type: "text",
108
+ text: `Page not found: "${slug}". Use list-doc-pages to see available slugs.`
109
+ }
110
+ ],
111
+ isError: true
112
+ };
113
+ }
114
+ const header = page.description ? `# ${page.title}
115
+
116
+ > ${page.description}
117
+
118
+ ` : `# ${page.title}
119
+
120
+ `;
121
+ return {
122
+ content: [{ type: "text", text: header + page.content }]
123
+ };
124
+ }
125
+ );
126
+ server.tool(
127
+ "search-docs",
128
+ "Full-text search across all DataQueue documentation pages. Returns matching sections with page titles and content excerpts.",
129
+ {
130
+ query: zod.z.string().describe('Search query, e.g. "cron scheduling" or "waitForToken"')
131
+ },
132
+ async ({ query }) => {
133
+ const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 1);
134
+ if (queryTerms.length === 0) {
135
+ return {
136
+ content: [
137
+ { type: "text", text: "Please provide a search query." }
138
+ ],
139
+ isError: true
140
+ };
141
+ }
142
+ const scored = pages.map((page) => ({
143
+ page,
144
+ score: scorePageForQuery(page, queryTerms)
145
+ })).filter((r) => r.score > 0).sort((a, b) => b.score - a.score).slice(0, 5);
146
+ if (scored.length === 0) {
147
+ return {
148
+ content: [
149
+ {
150
+ type: "text",
151
+ text: `No results for "${query}". Try different keywords or use list-doc-pages to browse.`
152
+ }
153
+ ]
154
+ };
155
+ }
156
+ const results = scored.map((r) => {
157
+ const excerpt = extractExcerpt(r.page.content, queryTerms);
158
+ return `## ${r.page.title} (${r.page.slug})
159
+
160
+ ${r.page.description}
161
+
162
+ ${excerpt}`;
163
+ });
164
+ return {
165
+ content: [{ type: "text", text: results.join("\n\n---\n\n") }]
166
+ };
167
+ }
168
+ );
169
+ const transport = deps.transport ?? new stdio_js.StdioServerTransport();
170
+ await server.connect(transport);
171
+ return server;
172
+ }
173
+ var isDirectRun = process.argv[1] && (process.argv[1].endsWith("/mcp-server.js") || process.argv[1].endsWith("/mcp-server.cjs"));
174
+ if (isDirectRun) {
175
+ startMcpServer().catch((err) => {
176
+ console.error("Failed to start MCP server:", err);
177
+ process.exit(1);
178
+ });
179
+ }
180
+
181
+ exports.extractExcerpt = extractExcerpt;
182
+ exports.loadDocsContent = loadDocsContent;
183
+ exports.scorePageForQuery = scorePageForQuery;
184
+ exports.startMcpServer = startMcpServer;
185
+ //# sourceMappingURL=mcp-server.cjs.map
186
+ //# sourceMappingURL=mcp-server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp-server.ts"],"names":["__filename","fileURLToPath","__dirname","path","fs","McpServer","z","StdioServerTransport"],"mappings":"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","file":"mcp-server.cjs","sourcesContent":["#!/usr/bin/env node\n\n/**\n * DataQueue MCP Server — exposes documentation search over stdio.\n * Run via: dataqueue-cli mcp\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\ninterface DocPage {\n slug: string;\n title: string;\n description: string;\n content: string;\n}\n\n/** @internal Loads docs-content.json from the ai/ directory bundled with the package. */\nexport function loadDocsContent(\n docsPath: string = path.join(__dirname, '../ai/docs-content.json'),\n): DocPage[] {\n const raw = fs.readFileSync(docsPath, 'utf-8');\n return JSON.parse(raw) as DocPage[];\n}\n\n/** @internal Scores a doc page against a search query using simple term matching. */\nexport function scorePageForQuery(page: DocPage, queryTerms: string[]): number {\n const titleLower = page.title.toLowerCase();\n const descLower = page.description.toLowerCase();\n const contentLower = page.content.toLowerCase();\n\n let score = 0;\n for (const term of queryTerms) {\n if (titleLower.includes(term)) score += 10;\n if (descLower.includes(term)) score += 5;\n\n const contentMatches = contentLower.split(term).length - 1;\n score += Math.min(contentMatches, 10);\n }\n return score;\n}\n\n/** @internal Extracts a relevant excerpt around the first match of any query term. */\nexport function extractExcerpt(\n content: string,\n queryTerms: string[],\n maxLength = 500,\n): string {\n const lower = content.toLowerCase();\n let earliestIndex = -1;\n\n for (const term of queryTerms) {\n const idx = lower.indexOf(term);\n if (idx !== -1 && (earliestIndex === -1 || idx < earliestIndex)) {\n earliestIndex = idx;\n }\n }\n\n if (earliestIndex === -1) {\n return content.slice(0, maxLength);\n }\n\n const start = Math.max(0, earliestIndex - 100);\n const end = Math.min(content.length, start + maxLength);\n let excerpt = content.slice(start, end);\n\n if (start > 0) excerpt = '...' + excerpt;\n if (end < content.length) excerpt = excerpt + '...';\n\n return excerpt;\n}\n\n/**\n * Creates and starts the DataQueue MCP server over stdio.\n *\n * @param deps - Injectable dependencies for testing.\n */\nexport async function startMcpServer(\n deps: {\n docsPath?: string;\n transport?: InstanceType<typeof StdioServerTransport>;\n } = {},\n): Promise<McpServer> {\n const pages = loadDocsContent(deps.docsPath);\n\n const server = new McpServer({\n name: 'dataqueue-docs',\n version: '1.0.0',\n });\n\n server.resource('llms-txt', 'dataqueue://llms.txt', async () => {\n const llmsPath = path.join(\n __dirname,\n '../ai/skills/dataqueue-core/SKILL.md',\n );\n let content: string;\n try {\n content = fs.readFileSync(llmsPath, 'utf-8');\n } catch {\n content = pages\n .map((p) => `## ${p.title}\\n\\nSlug: ${p.slug}\\n\\n${p.description}`)\n .join('\\n\\n');\n }\n return { contents: [{ uri: 'dataqueue://llms.txt', text: content }] };\n });\n\n server.tool(\n 'list-doc-pages',\n 'List all available DataQueue documentation pages with titles and descriptions.',\n {},\n async () => {\n const listing = pages.map((p) => ({\n slug: p.slug,\n title: p.title,\n description: p.description,\n }));\n return {\n content: [\n { type: 'text' as const, text: JSON.stringify(listing, null, 2) },\n ],\n };\n },\n );\n\n server.tool(\n 'get-doc-page',\n 'Fetch a specific DataQueue doc page by slug. Returns full page content as markdown.',\n {\n slug: z\n .string()\n .describe('The doc page slug, e.g. \"usage/add-job\" or \"api/job-queue\"'),\n },\n async ({ slug }) => {\n const page = pages.find((p) => p.slug === slug);\n if (!page) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Page not found: \"${slug}\". Use list-doc-pages to see available slugs.`,\n },\n ],\n isError: true,\n };\n }\n const header = page.description\n ? `# ${page.title}\\n\\n> ${page.description}\\n\\n`\n : `# ${page.title}\\n\\n`;\n return {\n content: [{ type: 'text' as const, text: header + page.content }],\n };\n },\n );\n\n server.tool(\n 'search-docs',\n 'Full-text search across all DataQueue documentation pages. Returns matching sections with page titles and content excerpts.',\n {\n query: z\n .string()\n .describe('Search query, e.g. \"cron scheduling\" or \"waitForToken\"'),\n },\n async ({ query }) => {\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 1);\n\n if (queryTerms.length === 0) {\n return {\n content: [\n { type: 'text' as const, text: 'Please provide a search query.' },\n ],\n isError: true,\n };\n }\n\n const scored = pages\n .map((page) => ({\n page,\n score: scorePageForQuery(page, queryTerms),\n }))\n .filter((r) => r.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, 5);\n\n if (scored.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No results for \"${query}\". Try different keywords or use list-doc-pages to browse.`,\n },\n ],\n };\n }\n\n const results = scored.map((r) => {\n const excerpt = extractExcerpt(r.page.content, queryTerms);\n return `## ${r.page.title} (${r.page.slug})\\n\\n${r.page.description}\\n\\n${excerpt}`;\n });\n\n return {\n content: [{ type: 'text' as const, text: results.join('\\n\\n---\\n\\n') }],\n };\n },\n );\n\n const transport = deps.transport ?? new StdioServerTransport();\n await server.connect(transport);\n return server;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n (process.argv[1].endsWith('/mcp-server.js') ||\n process.argv[1].endsWith('/mcp-server.cjs'));\n\nif (isDirectRun) {\n startMcpServer().catch((err) => {\n console.error('Failed to start MCP server:', err);\n process.exit(1);\n });\n}\n"]}
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+
5
+ /**
6
+ * DataQueue MCP Server — exposes documentation search over stdio.
7
+ * Run via: dataqueue-cli mcp
8
+ */
9
+
10
+ interface DocPage {
11
+ slug: string;
12
+ title: string;
13
+ description: string;
14
+ content: string;
15
+ }
16
+ /** @internal Loads docs-content.json from the ai/ directory bundled with the package. */
17
+ declare function loadDocsContent(docsPath?: string): DocPage[];
18
+ /** @internal Scores a doc page against a search query using simple term matching. */
19
+ declare function scorePageForQuery(page: DocPage, queryTerms: string[]): number;
20
+ /** @internal Extracts a relevant excerpt around the first match of any query term. */
21
+ declare function extractExcerpt(content: string, queryTerms: string[], maxLength?: number): string;
22
+ /**
23
+ * Creates and starts the DataQueue MCP server over stdio.
24
+ *
25
+ * @param deps - Injectable dependencies for testing.
26
+ */
27
+ declare function startMcpServer(deps?: {
28
+ docsPath?: string;
29
+ transport?: InstanceType<typeof StdioServerTransport>;
30
+ }): Promise<McpServer>;
31
+
32
+ export { extractExcerpt, loadDocsContent, scorePageForQuery, startMcpServer };
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+
5
+ /**
6
+ * DataQueue MCP Server — exposes documentation search over stdio.
7
+ * Run via: dataqueue-cli mcp
8
+ */
9
+
10
+ interface DocPage {
11
+ slug: string;
12
+ title: string;
13
+ description: string;
14
+ content: string;
15
+ }
16
+ /** @internal Loads docs-content.json from the ai/ directory bundled with the package. */
17
+ declare function loadDocsContent(docsPath?: string): DocPage[];
18
+ /** @internal Scores a doc page against a search query using simple term matching. */
19
+ declare function scorePageForQuery(page: DocPage, queryTerms: string[]): number;
20
+ /** @internal Extracts a relevant excerpt around the first match of any query term. */
21
+ declare function extractExcerpt(content: string, queryTerms: string[], maxLength?: number): string;
22
+ /**
23
+ * Creates and starts the DataQueue MCP server over stdio.
24
+ *
25
+ * @param deps - Injectable dependencies for testing.
26
+ */
27
+ declare function startMcpServer(deps?: {
28
+ docsPath?: string;
29
+ transport?: InstanceType<typeof StdioServerTransport>;
30
+ }): Promise<McpServer>;
31
+
32
+ export { extractExcerpt, loadDocsContent, scorePageForQuery, startMcpServer };