crontick 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-FMGZ3SSS.js → chunk-5LHE6MWX.js} +2 -2
- package/dist/{chunk-LPAFZNXK.js → chunk-KNOV44I4.js} +121 -26
- package/dist/chunk-KNOV44I4.js.map +1 -0
- package/dist/cli/index.cjs +120 -25
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/daemon/index.cjs +120 -25
- package/dist/daemon/index.cjs.map +1 -1
- package/dist/daemon/index.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.js +1 -1
- package/package.json +5 -2
- package/dist/chunk-LPAFZNXK.js.map +0 -1
- /package/dist/{chunk-FMGZ3SSS.js.map → chunk-5LHE6MWX.js.map} +0 -0
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts","../../src/version.ts","../../src/paths.ts","../../src/schemas/job.ts","../../src/errors.ts","../../src/autostart/win32.ts","../../src/autostart/manual.ts","../../src/autostart/darwin.ts","../../src/autostart/linux.ts","../../src/autostart/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { spawn, spawnSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, existsSync, rmSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\nimport { createInterface } from 'node:readline';\nimport { VERSION } from '../version.js';\nimport { portFilePath, pidFilePath, dataDir, ensureDirs } from '../paths.js';\nimport { JobSchema } from '../schemas/job.js';\nimport { CrontickError } from '../errors.js';\nimport { createAutostart } from '../autostart/index.js';\nimport type { AutostartBackend } from '../autostart/index.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── API client ────────────────────────────────────────────────────────────────\n\nfunction getPort(): number {\n const pf = portFilePath();\n if (!existsSync(pf)) {\n throw new CrontickError(\n 'DAEMON_NOT_RUNNING',\n 'Daemon is not running. Start it with: crontick daemon start',\n );\n }\n const port = parseInt(readFileSync(pf, 'utf-8').trim(), 10);\n if (isNaN(port)) {\n throw new CrontickError('DAEMON_NOT_RUNNING', 'Could not read daemon port file');\n }\n return port;\n}\n\nasync function api(\n method: string,\n path: string,\n body?: unknown,\n): Promise<unknown> {\n const port = getPort();\n const url = `http://127.0.0.1:${port}${path}`;\n const options: RequestInit = {\n method,\n headers: { 'Content-Type': 'application/json' },\n };\n if (body !== undefined) options.body = JSON.stringify(body);\n const res = await fetch(url, options);\n const text = await res.text();\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new CrontickError('PARSE_ERROR', `Unexpected response: ${text.slice(0, 200)}`);\n }\n if (!res.ok) {\n const err = (data as { error?: { code?: string; message?: string } })?.error;\n throw new CrontickError(err?.code ?? 'API_ERROR', err?.message ?? `HTTP ${res.status}`);\n }\n return data;\n}\n\n// ── Output helpers ────────────────────────────────────────────────────────────\n\nfunction print(data: unknown, useJson: boolean): void {\n if (useJson) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log('(no items)');\n return;\n }\n const rows = data as Array<Record<string, unknown>>;\n const keys = Object.keys(rows[0]);\n console.log(keys.join('\\t'));\n for (const row of rows) {\n console.log(\n keys\n .map((k) => {\n const v = row[k];\n return v !== null && typeof v === 'object' ? JSON.stringify(v) : String(v ?? '');\n })\n .join('\\t'),\n );\n }\n } else if (data !== null && typeof data === 'object') {\n const obj = data as Record<string, unknown>;\n for (const [key, value] of Object.entries(obj)) {\n const display =\n value !== null && typeof value === 'object' ? JSON.stringify(value) : String(value ?? '');\n console.log(`${key}: ${display}`);\n }\n } else {\n console.log(String(data ?? ''));\n }\n}\n\nfunction handleError(err: unknown): never {\n if (err instanceof CrontickError) {\n console.error(`Error [${err.code}]: ${err.message}`);\n } else {\n console.error(`Error: ${String(err)}`);\n }\n process.exit(1);\n}\n\n// ── Daemon helpers ────────────────────────────────────────────────────────────\n\nfunction daemonScript(): string {\n // In dist: __dirname = dist/cli/, daemon is at dist/daemon/index.js\n // In source via ts-node/vitest: paths differ, but tests build first\n return resolve(__dirname, '../daemon/index.js');\n}\n\nfunction waitForPort(timeout = 10_000): Promise<number> {\n const start = Date.now();\n return new Promise((resolve, reject) => {\n const check = () => {\n try {\n const port = getPort();\n resolve(port);\n } catch {\n if (Date.now() - start > timeout) {\n reject(new CrontickError('DAEMON_TIMEOUT', 'Timed out waiting for daemon to start'));\n } else {\n setTimeout(check, 200);\n }\n }\n };\n check();\n });\n}\n\n// ── Program ───────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name('crontick')\n .description('A standalone cron daemon, CLI, and MCP server for local scheduled jobs.')\n .version(VERSION)\n .option('--json', 'Output as JSON');\n\n// ── new ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('new <id>')\n .description('Create a new job')\n .option('--cron <expr>', 'Cron expression (e.g. \"0 9 * * *\")')\n .option('--every <sec>', 'Interval in seconds', parseInt)\n .option('--at <iso>', 'One-shot run-at ISO-8601 time')\n .option('--tz <tz>', 'Timezone for cron schedule')\n .option('--script <body>', 'Inline script body')\n .option('--exec <cmd>', 'Command to exec (use -- for args)')\n .option('--file <path>', 'Load full job from JSON file')\n .option('--shell <shell>', 'Shell: auto|bash|pwsh|cmd', 'auto')\n .option('--env-file <path>', 'Load extra environment variables from a .env file')\n .option('--timeout <sec>', 'Timeout in seconds', parseInt)\n .option('--overlap <policy>', 'Overlap policy: skip|queue|cancel-previous', 'skip')\n .option('--retry <max>', 'Retry count', parseInt)\n .option('--desc <description>', 'Job description')\n .action(async (id: string, opts) => {\n try {\n let jobData: unknown;\n\n if (opts.file) {\n const raw = readFileSync(resolve(process.cwd(), opts.file as string), 'utf-8');\n jobData = JSON.parse(raw);\n } else {\n // Build schedule\n let schedule: unknown;\n if (opts.cron) {\n schedule = { kind: 'cron', cron: opts.cron as string, tz: opts.tz as string | undefined };\n } else if (opts.every) {\n schedule = { kind: 'interval', everySec: opts.every as number };\n } else if (opts.at) {\n schedule = { kind: 'one-shot', runAt: opts.at as string };\n } else {\n throw new CrontickError('MISSING_ARG', 'Provide --cron, --every <sec>, or --at <iso>');\n }\n\n // Build action\n let action: unknown;\n if (opts.script) {\n action = {\n kind: 'script',\n script: opts.script as string,\n shell: opts.shell as string,\n envFile: opts.envFile as string | undefined,\n timeoutSec: opts.timeout as number | undefined,\n };\n } else if (opts.exec) {\n const parts = (opts.exec as string).split(/\\s+/);\n action = {\n kind: 'exec',\n command: parts[0],\n args: parts.slice(1),\n envFile: opts.envFile as string | undefined,\n timeoutSec: opts.timeout as number | undefined,\n };\n } else {\n throw new CrontickError('MISSING_ARG', 'Provide --script or --exec');\n }\n\n jobData = {\n id,\n description: opts.desc as string | undefined,\n schedule,\n action,\n overlap: opts.overlap as string,\n retry: opts.retry !== undefined ? { max: opts.retry as number, backoffSec: 30 } : undefined,\n };\n }\n\n const parsed = JobSchema.safeParse(jobData);\n if (!parsed.success) {\n throw new CrontickError('VALIDATION_ERROR', 'Invalid job', parsed.error.format());\n }\n\n const result = await api('POST', '/api/jobs', parsed.data);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── list ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command('list')\n .description('List all jobs')\n .action(async () => {\n try {\n const jobs = await api('GET', '/api/jobs');\n print(jobs, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── get ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('get <id>')\n .description('Get a job by ID')\n .action(async (id: string) => {\n try {\n const job = await api('GET', `/api/jobs/${encodeURIComponent(id)}`);\n print(job, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── enable / disable / delete ─────────────────────────────────────────────────\n\nprogram\n .command('enable <id>')\n .description('Enable a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/enable`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('disable <id>')\n .description('Disable a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/disable`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('delete <id>')\n .description('Delete a job')\n .action(async (id: string) => {\n try {\n const result = await api('DELETE', `/api/jobs/${encodeURIComponent(id)}`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── run-now ───────────────────────────────────────────────────────────────────\n\nprogram\n .command('run-now <id>')\n .description('Trigger an immediate run of a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/run`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── logs ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command('logs <runId>')\n .description('Get logs for a run')\n .option('--follow', 'Follow (SSE stream) — not implemented in CLI yet; use --tail')\n .option('--tail <n>', 'Show last N lines', parseInt)\n .action(async (runId: string, opts) => {\n try {\n const useJson = !!(program.opts() as { json?: boolean }).json;\n const logs = await api('GET', `/api/runs/${encodeURIComponent(runId)}/logs`) as Array<{\n stream: string;\n ts: number;\n data: string;\n }>;\n const lines = (Array.isArray(logs) ? logs : []) as Array<{ stream: string; ts: number; data: string }>;\n const tail = opts.tail as number | undefined;\n const display = tail ? lines.slice(-tail) : lines;\n if (useJson) {\n console.log(JSON.stringify(display, null, 2));\n } else {\n for (const entry of display) {\n process.stdout.write(`[${entry.stream}] ${entry.data}`);\n }\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── export / import ───────────────────────────────────────────────────────────\n\nprogram\n .command('export')\n .description('Export all jobs')\n .option('--out <file>', 'Output file (default: stdout)')\n .action(async (opts) => {\n try {\n const data = await api('GET', '/api/export');\n const json = JSON.stringify(data, null, 2);\n if (opts.out) {\n writeFileSync(resolve(process.cwd(), opts.out as string), json, 'utf-8');\n console.log(`Exported to ${opts.out as string}`);\n } else {\n console.log(json);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('import <file>')\n .description('Import jobs from a JSON file')\n .action(async (file: string) => {\n try {\n const raw = readFileSync(resolve(process.cwd(), file), 'utf-8');\n const data = JSON.parse(raw);\n const result = await api('POST', '/api/import', data);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── doctor ────────────────────────────────────────────────────────────────────\n\nprogram\n .command('doctor')\n .description('Check system health')\n .action(async () => {\n const checks: Array<{ name: string; ok: boolean; note?: string }> = [];\n\n // Node version\n const major = parseInt(process.versions.node.split('.')[0], 10);\n checks.push({\n name: 'Node.js >= 22.5',\n ok: major >= 22,\n note: `v${process.versions.node}`,\n });\n\n // SQLite availability\n try {\n const { DatabaseSync } = await import('node:sqlite');\n new DatabaseSync(':memory:').close();\n checks.push({ name: 'node:sqlite', ok: true });\n } catch (err) {\n checks.push({ name: 'node:sqlite', ok: false, note: String(err) });\n }\n\n // Data dir\n try {\n ensureDirs();\n checks.push({ name: 'data dir writable', ok: true });\n } catch (err) {\n checks.push({ name: 'data dir writable', ok: false, note: String(err) });\n }\n\n // Port file\n const portFile = portFilePath();\n const portFileExists = existsSync(portFile);\n checks.push({ name: 'port file readable', ok: portFileExists, note: portFileExists ? portFile : 'not found' });\n\n // Daemon reachable\n try {\n await api('GET', '/health');\n checks.push({ name: 'daemon reachable', ok: true });\n } catch {\n checks.push({ name: 'daemon reachable', ok: false, note: 'not running' });\n }\n\n // Dashboard reachable\n try {\n const port2 = getPort();\n const dashRes = await fetch(`http://127.0.0.1:${port2}/dashboard`, {\n signal: AbortSignal.timeout(2000),\n });\n const text = await dashRes.text();\n checks.push({\n name: 'dashboard reachable',\n ok: dashRes.status === 200 && text.includes('crontick'),\n note: dashRes.status === 200 ? 'ok' : `HTTP ${dashRes.status}`,\n });\n } catch {\n checks.push({ name: 'dashboard reachable', ok: false, note: 'daemon not running or no dashboard' });\n }\n\n // Autostart status\n try {\n const asResult = await api('GET', '/api/autostart/status');\n const as = asResult as { installed?: boolean; backend?: string };\n checks.push({\n name: 'autostart',\n ok: true,\n note: `backend=${as.backend ?? '?'}, installed=${String(as.installed ?? false)}`,\n });\n } catch {\n checks.push({ name: 'autostart', ok: false, note: 'could not check (daemon not running)' });\n }\n\n // MCP server binary\n const mcpScript = resolve(__dirname, '../mcp/index.js');\n checks.push({\n name: 'MCP server binary',\n ok: existsSync(mcpScript),\n note: mcpScript,\n });\n\n // MCP server --help smoke test\n try {\n const result = spawnSync(process.execPath, [mcpScript, '--help'], {\n timeout: 5000,\n encoding: 'utf-8',\n env: { ...process.env, CRONTICK_MCP_NO_AUTOSTART: '1' },\n });\n // --help exits 0 on commander; if exit code is 0 or it printed help text it's fine\n const helpOk = result.status === 0 || (result.stdout ?? '').includes('stdio');\n checks.push({ name: 'MCP server --help', ok: helpOk });\n } catch (err) {\n checks.push({ name: 'MCP server --help', ok: false, note: String(err) });\n }\n\n for (const c of checks) {\n const icon = c.ok ? '✓' : '✗';\n console.log(`${icon} ${c.name}${c.note ? ` (${c.note})` : ''}`);\n }\n\n const failed = checks.filter((c) => !c.ok);\n if (failed.length > 0) process.exit(1);\n });\n\n// ── daemon ────────────────────────────────────────────────────────────────────\n\nconst daemon = program.command('daemon').description('Manage the crontick daemon');\n\ndaemon\n .command('start')\n .description('Start the daemon (detached by default)')\n .option('--foreground', 'Run in foreground (blocking)')\n .action(async (opts) => {\n try {\n const script = daemonScript();\n if (!existsSync(script)) {\n throw new CrontickError('NOT_BUILT', `Daemon script not found: ${script}. Run: npm run build`);\n }\n\n if (opts.foreground as boolean) {\n // Run inline (blocking — for testing/debugging)\n const result = spawnSync(process.execPath, [script], {\n stdio: 'inherit',\n env: process.env,\n });\n process.exit(result.status ?? 0);\n } else {\n const child = spawn(process.execPath, [script], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n });\n child.unref();\n console.log(`Starting daemon (pid will be written to port file)…`);\n const port = await waitForPort();\n console.log(`Daemon started on port ${port}`);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('stop')\n .description('Stop the daemon')\n .action(async () => {\n try {\n const pidFile = pidFilePath();\n if (!existsSync(pidFile)) {\n console.log('Daemon is not running');\n return;\n }\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n process.kill(pid, 'SIGTERM');\n console.log(`Sent SIGTERM to daemon (pid ${pid})`);\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('status')\n .description('Show daemon status')\n .action(async () => {\n try {\n const status = await api('GET', '/api/daemon/status');\n print(status, !!(program.opts() as { json?: boolean }).json);\n } catch {\n console.log('Daemon is not running');\n }\n });\n\ndaemon\n .command('reload')\n .description('Reload jobs from disk')\n .action(async () => {\n try {\n const result = await api('POST', '/api/daemon/reload');\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('restart')\n .description('Restart the daemon')\n .action(async () => {\n try {\n // Stop if running\n const pidFile = pidFilePath();\n if (existsSync(pidFile)) {\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n try {\n process.kill(pid, 'SIGTERM');\n await new Promise((r) => setTimeout(r, 1000));\n } catch {\n // ignore\n }\n }\n\n // Start\n const script = daemonScript();\n const child = spawn(process.execPath, [script], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n });\n child.unref();\n const port = await waitForPort();\n console.log(`Daemon restarted on port ${port}`);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── autostart ─────────────────────────────────────────────────────────────────\n\nconst autostart = program.command('autostart').description('Manage daemon autostart at login');\n\nautostart\n .command('install')\n .description('Register the daemon to start automatically at login')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.install();\n print(result, !!(program.opts() as { json?: boolean }).json);\n if (process.platform !== 'win32' && !backend) {\n const statusResult = await as.status();\n const details = (statusResult.details as Record<string, unknown> | undefined);\n const instr = details?.['instructions'] as string | undefined;\n if (instr) console.log('\\nManual setup instructions:\\n' + instr);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\nautostart\n .command('remove')\n .description('Remove the daemon from automatic startup')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.remove();\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nautostart\n .command('status')\n .description('Check whether the daemon is registered for automatic startup')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.status();\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── uninstall ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('uninstall')\n .description('Remove autostart entry and optionally delete all crontick data')\n .option('--purge', 'Also delete the data directory (jobs, runs, config)')\n .option('--yes', 'Skip confirmation prompts')\n .action(async (opts) => {\n try {\n // Remove autostart\n const as = createAutostart();\n await as.remove();\n console.log('✓ Autostart entry removed.');\n\n if (opts.purge as boolean) {\n const dir = dataDir();\n let confirmed = opts.yes as boolean;\n if (!confirmed) {\n confirmed = await new Promise<boolean>((resolve) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(`Delete all crontick data at ${dir}? [y/N] `, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y');\n });\n });\n }\n if (confirmed) {\n rmSync(dir, { recursive: true, force: true });\n console.log(`✓ Data directory deleted: ${dir}`);\n } else {\n console.log('Skipped data directory deletion.');\n }\n } else {\n console.log(\n 'Data directory preserved. Run `crontick uninstall --purge` to also delete it.',\n );\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── dashboard ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('dashboard')\n .description('Open the crontick dashboard in a browser')\n .option('--open', 'Open in the default browser')\n .action(async (opts) => {\n try {\n const port = getPort();\n const url = `http://127.0.0.1:${port}/dashboard`;\n if (opts.open as boolean) {\n if (process.platform === 'win32') {\n spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' }).unref();\n } else if (process.platform === 'darwin') {\n spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();\n } else {\n try {\n spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();\n } catch {\n // xdg-open not available\n }\n }\n console.log(`Dashboard opened: ${url}`);\n } else {\n console.log(`Dashboard: ${url}`);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── mcp ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('mcp')\n .description('Start the crontick MCP server on stdio (for use with Claude Desktop, Copilot, Cursor, etc.)')\n .option('--no-autostart', 'Do not auto-start the daemon if it is not already running')\n .option('--daemon-url <url>', 'Override the daemon URL (default: resolved from port file)')\n .addHelpText(\n 'after',\n `\nTransport: stdio (JSON-RPC 2.0 over stdin/stdout)\nTool prefix: crontick_\nAutostart: Daemon is auto-started unless --no-autostart or CRONTICK_MCP_NO_AUTOSTART=1 is set\n\nExample MCP host config (Claude Desktop):\n {\n \"mcpServers\": {\n \"crontick\": { \"command\": \"crontick\", \"args\": [\"mcp\"] }\n }\n }`,\n )\n .action((opts) => {\n const mcpScript = resolve(__dirname, '../mcp/index.js');\n if (!existsSync(mcpScript)) {\n console.error(`MCP server script not found: ${mcpScript}. Run: npm run build`);\n process.exit(1);\n }\n const env: NodeJS.ProcessEnv = { ...process.env };\n if (opts.noAutostart) env['CRONTICK_MCP_NO_AUTOSTART'] = '1';\n if (opts.daemonUrl) env['CRONTICK_DAEMON_URL'] = opts.daemonUrl as string;\n const result = spawnSync(process.execPath, [mcpScript], {\n stdio: 'inherit',\n env,\n });\n process.exit(result.status ?? 0);\n });\n\n// ── parse ─────────────────────────────────────────────────────────────────────\n\nprogram.parse();\n","// Version constant injected at build time by tsup/esbuild (define: __CRONTICK_VERSION__)\n// and at test time by vitest (define in vitest.config.ts).\ndeclare const __CRONTICK_VERSION__: string;\nexport const VERSION: string = __CRONTICK_VERSION__;\n","import envPaths from 'env-paths';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nfunction root(): string {\n const override = process.env['CRONTICK_HOME'];\n if (override) return override;\n // env-paths v3: data dir on windows = %LOCALAPPDATA%\\crontick\n return envPaths('crontick', { suffix: '' }).data;\n}\n\nexport function dataDir(): string {\n return root();\n}\n\nexport function jobsDir(): string {\n return join(root(), 'jobs');\n}\n\nexport function runsDbPath(): string {\n return join(root(), 'runs.db');\n}\n\nexport function logsDir(): string {\n return join(root(), 'logs');\n}\n\nexport function configPath(): string {\n return join(root(), 'config.json');\n}\n\nexport function pidFilePath(): string {\n return join(root(), 'daemon.pid');\n}\n\nexport function portFilePath(): string {\n return join(root(), 'daemon.port');\n}\n\nexport function autostartDir(): string {\n return join(root(), 'autostart');\n}\n\nexport function ensureDirs(): void {\n for (const dir of [dataDir(), jobsDir(), logsDir()]) {\n mkdirSync(dir, { recursive: true });\n }\n}\n","import { z } from 'zod';\n\n// ── Schedule ──────────────────────────────────────────────────────────────────\n\nexport const CronScheduleSchema = z.object({\n kind: z.literal('cron'),\n cron: z.string().min(1),\n tz: z.string().optional(),\n});\n\nexport const IntervalScheduleSchema = z.object({\n kind: z.literal('interval'),\n everySec: z.number().positive(),\n startAt: z.string().optional(), // ISO-8601\n});\n\nexport const OneShotScheduleSchema = z.object({\n kind: z.literal('one-shot'),\n runAt: z.string().min(1), // ISO-8601\n});\n\nexport const ScheduleSchema = z.discriminatedUnion('kind', [\n CronScheduleSchema,\n IntervalScheduleSchema,\n OneShotScheduleSchema,\n]);\n\n// ── Action ────────────────────────────────────────────────────────────────────\n\nexport const ScriptActionSchema = z.object({\n kind: z.literal('script'),\n script: z.string().min(1),\n shell: z.enum(['auto', 'bash', 'pwsh', 'cmd']).default('auto'),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n envFile: z.string().optional(),\n timeoutSec: z.number().positive().optional(),\n});\n\nexport const ExecActionSchema = z.object({\n kind: z.literal('exec'),\n command: z.string().min(1),\n args: z.array(z.string()).default([]),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n envFile: z.string().optional(),\n timeoutSec: z.number().positive().optional(),\n // shell is intentionally absent: exec always uses shell=false to prevent injection\n});\n\nexport const ActionSchema = z.discriminatedUnion('kind', [ScriptActionSchema, ExecActionSchema]);\n\n// ── Supporting types ──────────────────────────────────────────────────────────\n\nexport const RetrySchema = z.object({\n max: z.number().int().min(0).default(0),\n backoffSec: z.number().positive().default(30),\n});\n\nexport const BudgetsSchema = z.object({\n maxRunsPerDay: z.number().int().positive().nullable().default(null),\n maxTokensPerRun: z.number().int().positive().nullable().default(null),\n});\n\n// ── Job ───────────────────────────────────────────────────────────────────────\n\nconst kebabCase = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nexport const JobSchema = z.object({\n id: z.string().regex(kebabCase, 'Job ID must be kebab-case (e.g. \"my-job\")'),\n description: z.string().optional(),\n enabled: z.boolean().default(true),\n schedule: ScheduleSchema,\n action: ActionSchema,\n catchup: z.enum(['run-once', 'run-all', 'skip']).default('skip'),\n overlap: z.enum(['skip', 'queue', 'cancel-previous']).default('skip'),\n retry: RetrySchema.default({ max: 0, backoffSec: 30 }),\n budgets: BudgetsSchema.default({ maxRunsPerDay: null, maxTokensPerRun: null }),\n});\n\nexport type Job = z.infer<typeof JobSchema>;\nexport type JobInput = z.input<typeof JobSchema>;\nexport type Schedule = z.infer<typeof ScheduleSchema>;\nexport type Action = z.infer<typeof ActionSchema>;\n","export class CrontickError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = 'CrontickError';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, CrontickError.prototype);\n }\n\n toJSON(): { code: string; message: string; details?: unknown } {\n return { code: this.code, message: this.message, details: this.details };\n }\n}\n","/**\n * Windows autostart backend — HKCU Run key + hidden VBS shim.\n *\n * Registry key: HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n * Value name: crontick-daemon (or CRONTICK_AUTOSTART_TEST_VALUE for tests)\n * Value data: wscript.exe \"<dataDir>\\autostart\\crontick-daemon.vbs\"\n *\n * The VBS shim launches crontick-daemon via `cmd /c` with window style 0 (hidden).\n */\nimport { spawnSync } from 'node:child_process';\nimport {\n writeFileSync,\n existsSync,\n unlinkSync,\n mkdirSync,\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { autostartDir } from '../paths.js';\nimport type { AutostartStatus } from './index.js';\n\nconst RUN_KEY = 'HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run';\n\nfunction getValueName(): string {\n return process.env['CRONTICK_AUTOSTART_TEST_VALUE'] ?? 'crontick-daemon';\n}\n\nfunction getVbsPath(): string {\n return join(autostartDir(), 'crontick-daemon.vbs');\n}\n\n/**\n * Locate the absolute path to the crontick-daemon binary/cmd wrapper.\n * Prefers `where.exe` detection so PATH changes don't break the shim.\n * CRONTICK_DAEMON_BINARY env var overrides detection (useful in CI/tests).\n */\nfunction findDaemonBinary(): string | null {\n // 0. Test / CI override\n const override = process.env['CRONTICK_DAEMON_BINARY'];\n if (override) return override;\n\n // 1. Try where.exe\n const whereResult = spawnSync('where.exe', ['crontick-daemon'], {\n encoding: 'utf-8',\n timeout: 5_000,\n windowsHide: true,\n });\n if (whereResult.status === 0 && whereResult.stdout.trim()) {\n const first = whereResult.stdout.trim().split(/[\\r\\n]+/)[0]?.trim();\n if (first) return first;\n }\n\n // 2. Fallback: look in the same directory as the Node.js executable\n const nodeDir = dirname(process.execPath);\n for (const candidate of ['crontick-daemon.cmd', 'crontick-daemon']) {\n const p = join(nodeDir, candidate);\n if (existsSync(p)) return p;\n }\n\n return null;\n}\n\nfunction buildVbsContent(daemonPath: string): string {\n // Remove any double-quotes in path (shouldn't exist in valid Win paths)\n const safePath = daemonPath.replace(/\"/g, '');\n return [\n \"' crontick-daemon autostart shim — generated by crontick autostart install\",\n \"' Do not edit manually. Run: crontick autostart install to regenerate.\",\n 'Set WshShell = CreateObject(\"WScript.Shell\")',\n `WshShell.Run \"cmd /c \"\"${safePath}\"\"\", 0, False`,\n '',\n ].join('\\r\\n');\n}\n\nfunction regQuery(valueName: string): string | null {\n const result = spawnSync(\n 'reg',\n ['query', RUN_KEY, '/v', valueName],\n { encoding: 'utf-8', timeout: 5_000, windowsHide: true },\n );\n if (result.status !== 0 || !result.stdout) return null;\n // Output format: \" valueName REG_SZ <data>\"\n const match = result.stdout.match(/REG_SZ\\s+(.+)/i);\n return match?.[1]?.trim() ?? null;\n}\n\nfunction regWrite(valueName: string, data: string): void {\n const result = spawnSync(\n 'reg',\n ['add', RUN_KEY, '/v', valueName, '/t', 'REG_SZ', '/d', data, '/f'],\n { encoding: 'utf-8', timeout: 5_000, windowsHide: true },\n );\n if (result.status !== 0) {\n throw new Error(\n `reg.exe add failed (exit ${result.status ?? '?'}): ${result.stderr?.trim() ?? 'unknown error'}`,\n );\n }\n}\n\nfunction regDelete(valueName: string): void {\n spawnSync(\n 'reg',\n ['delete', RUN_KEY, '/v', valueName, '/f'],\n { encoding: 'utf-8', timeout: 5_000, windowsHide: true },\n );\n // Ignore errors (value may not exist)\n}\n\nexport class Win32Autostart {\n async install(): Promise<{ ok: true }> {\n const daemonPath = findDaemonBinary();\n if (!daemonPath) {\n throw new Error(\n 'crontick-daemon binary not found. Ensure crontick is installed globally: npm i -g crontick',\n );\n }\n\n const vbsPath = getVbsPath();\n const valueName = getValueName();\n\n // Ensure directory and write VBS shim\n mkdirSync(autostartDir(), { recursive: true });\n writeFileSync(vbsPath, buildVbsContent(daemonPath), 'utf-8');\n\n // Idempotent: remove previous value before writing\n regDelete(valueName);\n regWrite(valueName, `wscript.exe \"${vbsPath}\"`);\n\n return { ok: true };\n }\n\n async remove(): Promise<{ ok: true }> {\n const valueName = getValueName();\n regDelete(valueName);\n\n // Remove VBS shim if it exists\n const vbsPath = getVbsPath();\n if (existsSync(vbsPath)) {\n try { unlinkSync(vbsPath); } catch { /* ignore */ }\n }\n\n return { ok: true };\n }\n\n async status(): Promise<AutostartStatus> {\n const valueName = getValueName();\n const data = regQuery(valueName);\n const installed = data !== null;\n return {\n installed,\n backend: 'win32',\n details: installed\n ? { registryValue: valueName, registryData: data, vbsPath: getVbsPath() }\n : { registryValue: valueName },\n };\n }\n}\n","/**\n * Manual autostart backend — prints per-platform instructions.\n * Works on any platform; used as the default on non-Windows in v1.\n */\nimport type { AutostartStatus } from './index.js';\n\nfunction instructions(): string {\n switch (process.platform) {\n case 'win32':\n return (\n 'Windows: add the following command to your startup folder or HKCU Run key:\\n' +\n ' crontick-daemon\\n' +\n 'Or run: crontick autostart install (uses HKCU Run + hidden VBS shim)'\n );\n case 'darwin':\n return (\n 'macOS (post-v1): create a launchd plist at\\n' +\n ' ~/Library/LaunchAgents/com.crontick.daemon.plist\\n' +\n 'with ProgramArguments pointing to the crontick-daemon binary.\\n' +\n 'Then run: launchctl load ~/Library/LaunchAgents/com.crontick.daemon.plist\\n' +\n '\\nFor now, add the following to your shell profile (~/.zprofile or ~/.bash_profile):\\n' +\n ' crontick-daemon &'\n );\n case 'linux':\n return (\n 'Linux (post-v1): create a systemd user unit at\\n' +\n ' ~/.config/systemd/user/crontick.service\\n' +\n 'Then run: systemctl --user enable --now crontick.service\\n' +\n '\\nFor now, add the following to your shell profile (~/.profile or ~/.bashrc):\\n' +\n ' crontick-daemon &\\n' +\n 'Or add a @reboot crontab entry: crontab -e\\n' +\n ' @reboot crontick-daemon'\n );\n default:\n return (\n 'Add `crontick-daemon` to your system startup mechanism.\\n' +\n 'The daemon listens on a random localhost port; the port is written to the data directory.'\n );\n }\n}\n\nexport class ManualAutostart {\n async install(): Promise<{ ok: true }> {\n return { ok: true };\n }\n\n async remove(): Promise<{ ok: true }> {\n return { ok: true };\n }\n\n async status(): Promise<AutostartStatus> {\n return {\n installed: false,\n backend: 'manual',\n details: { instructions: instructions() },\n };\n }\n}\n","/**\n * macOS autostart backend — STUB for post-v1.\n *\n * TODO (darwin implementation, post-v1):\n * - install():\n * 1. Build a launchd plist string for com.crontick.daemon\n * 2. Write to ~/Library/LaunchAgents/com.crontick.daemon.plist\n * 3. Run: launchctl load ~/Library/LaunchAgents/com.crontick.daemon.plist\n * - remove():\n * 1. Run: launchctl unload ~/Library/LaunchAgents/com.crontick.daemon.plist\n * 2. Delete ~/Library/LaunchAgents/com.crontick.daemon.plist\n * - status():\n * Run: launchctl list com.crontick.daemon (exit 0 = loaded)\n *\n * Plist template:\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n * <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" ...>\n * <plist version=\"1.0\"><dict>\n * <key>Label</key><string>com.crontick.daemon</string>\n * <key>ProgramArguments</key>\n * <array><string>/usr/local/bin/crontick-daemon</string></array>\n * <key>RunAtLoad</key><true/>\n * <key>StandardOutPath</key><string>~/.local/state/crontick/logs/daemon.stdout.log</string>\n * <key>StandardErrorPath</key><string>~/.local/state/crontick/logs/daemon.stderr.log</string>\n * </dict></plist>\n */\nimport { NotImplementedInV1Error } from './index.js';\nimport type { AutostartStatus } from './index.js';\n\nexport class DarwinAutostart {\n async install(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now. ' +\n 'See https://github.com/crontick/crontick for updates.',\n );\n }\n\n async remove(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now.',\n );\n }\n\n async status(): Promise<AutostartStatus> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now.',\n );\n }\n}\n","/**\n * Linux autostart backend — STUB for post-v1.\n *\n * TODO (linux implementation, post-v1):\n * - install():\n * 1. Create ~/.config/systemd/user/ if absent\n * 2. Write unit file to ~/.config/systemd/user/crontick.service:\n *\n * [Unit]\n * Description=crontick daemon\n * After=default.target\n *\n * [Service]\n * Type=simple\n * ExecStart=/usr/local/bin/crontick-daemon\n * Restart=on-failure\n * RestartSec=5\n *\n * [Install]\n * WantedBy=default.target\n *\n * 3. Run: systemctl --user daemon-reload\n * 4. Run: systemctl --user enable --now crontick.service\n *\n * - remove():\n * 1. Run: systemctl --user disable --now crontick.service\n * 2. Delete ~/.config/systemd/user/crontick.service\n * 3. Run: systemctl --user daemon-reload\n *\n * - status():\n * Run: systemctl --user is-active crontick.service (exit 0 = active)\n */\nimport { NotImplementedInV1Error } from './index.js';\nimport type { AutostartStatus } from './index.js';\n\nexport class LinuxAutostart {\n async install(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now. ' +\n 'See https://github.com/crontick/crontick for updates.',\n );\n }\n\n async remove(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now.',\n );\n }\n\n async status(): Promise<AutostartStatus> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now.',\n );\n }\n}\n","/**\n * Autostart abstraction — factory + types.\n * v1: win32 (HKCU Run + VBS shim) and manual (prints instructions).\n * darwin/linux are stubs that throw NotImplementedInV1Error.\n */\nimport { Win32Autostart } from './win32.js';\nimport { ManualAutostart } from './manual.js';\nimport { DarwinAutostart } from './darwin.js';\nimport { LinuxAutostart } from './linux.js';\n\nexport type AutostartBackend = 'win32' | 'darwin' | 'linux' | 'manual';\n\nexport interface AutostartStatus {\n installed: boolean;\n backend: AutostartBackend;\n details?: unknown;\n}\n\nexport interface Autostart {\n install(): Promise<{ ok: true }>;\n remove(): Promise<{ ok: true }>;\n status(): Promise<AutostartStatus>;\n}\n\n/** Thrown by darwin/linux stubs; serialised as HTTP 501 by the daemon API. */\nexport class NotImplementedInV1Error extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotImplementedInV1Error';\n Object.setPrototypeOf(this, NotImplementedInV1Error.prototype);\n }\n}\n\n/**\n * Factory: default = win32 on Windows, manual everywhere else.\n * An explicit `opts.backend` always overrides the default.\n */\nexport function createAutostart(opts?: { backend?: AutostartBackend }): Autostart {\n const backend: AutostartBackend =\n opts?.backend ?? (process.platform === 'win32' ? 'win32' : 'manual');\n switch (backend) {\n case 'win32': return new Win32Autostart();\n case 'darwin': return new DarwinAutostart();\n case 'linux': return new LinuxAutostart();\n case 'manual':\n default: return new ManualAutostart();\n }\n}\n"],"mappings":"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","names":["import_node_child_process","import_node_fs","import_node_path","envPaths","import_node_fs","import_node_path","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts","../../src/version.ts","../../src/paths.ts","../../src/schemas/job.ts","../../src/errors.ts","../../src/autostart/win32.ts","../../src/autostart/manual.ts","../../src/autostart/darwin.ts","../../src/autostart/linux.ts","../../src/autostart/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { spawn, spawnSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, existsSync, rmSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\nimport { createInterface } from 'node:readline';\nimport { VERSION } from '../version.js';\nimport { portFilePath, pidFilePath, dataDir, ensureDirs } from '../paths.js';\nimport { JobSchema } from '../schemas/job.js';\nimport { CrontickError } from '../errors.js';\nimport { createAutostart } from '../autostart/index.js';\nimport type { AutostartBackend } from '../autostart/index.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── API client ────────────────────────────────────────────────────────────────\n\nfunction getPort(): number {\n const pf = portFilePath();\n if (!existsSync(pf)) {\n throw new CrontickError(\n 'DAEMON_NOT_RUNNING',\n 'Daemon is not running. Start it with: crontick daemon start',\n );\n }\n const port = parseInt(readFileSync(pf, 'utf-8').trim(), 10);\n if (isNaN(port)) {\n throw new CrontickError('DAEMON_NOT_RUNNING', 'Could not read daemon port file');\n }\n return port;\n}\n\nasync function api(\n method: string,\n path: string,\n body?: unknown,\n): Promise<unknown> {\n const port = getPort();\n const url = `http://127.0.0.1:${port}${path}`;\n const options: RequestInit = {\n method,\n headers: { 'Content-Type': 'application/json' },\n };\n if (body !== undefined) options.body = JSON.stringify(body);\n const res = await fetch(url, options);\n const text = await res.text();\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new CrontickError('PARSE_ERROR', `Unexpected response: ${text.slice(0, 200)}`);\n }\n if (!res.ok) {\n const err = (data as { error?: { code?: string; message?: string } })?.error;\n throw new CrontickError(err?.code ?? 'API_ERROR', err?.message ?? `HTTP ${res.status}`);\n }\n return data;\n}\n\n// ── Output helpers ────────────────────────────────────────────────────────────\n\nfunction print(data: unknown, useJson: boolean): void {\n if (useJson) {\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log('(no items)');\n return;\n }\n const rows = data as Array<Record<string, unknown>>;\n const keys = Object.keys(rows[0]);\n console.log(keys.join('\\t'));\n for (const row of rows) {\n console.log(\n keys\n .map((k) => {\n const v = row[k];\n return v !== null && typeof v === 'object' ? JSON.stringify(v) : String(v ?? '');\n })\n .join('\\t'),\n );\n }\n } else if (data !== null && typeof data === 'object') {\n const obj = data as Record<string, unknown>;\n for (const [key, value] of Object.entries(obj)) {\n const display =\n value !== null && typeof value === 'object' ? JSON.stringify(value) : String(value ?? '');\n console.log(`${key}: ${display}`);\n }\n } else {\n console.log(String(data ?? ''));\n }\n}\n\nfunction handleError(err: unknown): never {\n if (err instanceof CrontickError) {\n console.error(`Error [${err.code}]: ${err.message}`);\n } else {\n console.error(`Error: ${String(err)}`);\n }\n process.exit(1);\n}\n\n// ── Daemon helpers ────────────────────────────────────────────────────────────\n\nfunction daemonScript(): string {\n // In dist: __dirname = dist/cli/, daemon is at dist/daemon/index.js\n // In source via ts-node/vitest: paths differ, but tests build first\n return resolve(__dirname, '../daemon/index.js');\n}\n\nfunction waitForPort(timeout = 10_000): Promise<number> {\n const start = Date.now();\n return new Promise((resolve, reject) => {\n const check = () => {\n try {\n const port = getPort();\n resolve(port);\n } catch {\n if (Date.now() - start > timeout) {\n reject(new CrontickError('DAEMON_TIMEOUT', 'Timed out waiting for daemon to start'));\n } else {\n setTimeout(check, 200);\n }\n }\n };\n check();\n });\n}\n\n// ── Program ───────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name('crontick')\n .description('A standalone cron daemon, CLI, and MCP server for local scheduled jobs.')\n .version(VERSION)\n .option('--json', 'Output as JSON');\n\n// ── new ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('new <id>')\n .description('Create a new job')\n .option('--cron <expr>', 'Cron expression (e.g. \"0 9 * * *\")')\n .option('--every <sec>', 'Interval in seconds', parseInt)\n .option('--at <iso>', 'One-shot run-at ISO-8601 time')\n .option('--tz <tz>', 'Timezone for cron schedule')\n .option('--script <body>', 'Inline script body')\n .option('--exec <cmd>', 'Command to exec (use -- for args)')\n .option('--file <path>', 'Load full job from JSON file')\n .option('--shell <shell>', 'Shell: auto|bash|pwsh|cmd', 'auto')\n .option('--env-file <path>', 'Load extra environment variables from a .env file')\n .option('--timeout <sec>', 'Timeout in seconds', parseInt)\n .option('--overlap <policy>', 'Overlap policy: skip|queue|cancel-previous', 'skip')\n .option('--retry <max>', 'Retry count', parseInt)\n .option('--desc <description>', 'Job description')\n .action(async (id: string, opts) => {\n try {\n let jobData: unknown;\n\n if (opts.file) {\n const raw = readFileSync(resolve(process.cwd(), opts.file as string), 'utf-8');\n jobData = JSON.parse(raw);\n } else {\n // Build schedule\n let schedule: unknown;\n if (opts.cron) {\n schedule = { kind: 'cron', cron: opts.cron as string, tz: opts.tz as string | undefined };\n } else if (opts.every) {\n schedule = { kind: 'interval', everySec: opts.every as number };\n } else if (opts.at) {\n schedule = { kind: 'one-shot', runAt: opts.at as string };\n } else {\n throw new CrontickError('MISSING_ARG', 'Provide --cron, --every <sec>, or --at <iso>');\n }\n\n // Build action\n let action: unknown;\n if (opts.script) {\n action = {\n kind: 'script',\n script: opts.script as string,\n shell: opts.shell as string,\n envFile: opts.envFile as string | undefined,\n timeoutSec: opts.timeout as number | undefined,\n };\n } else if (opts.exec) {\n const parts = (opts.exec as string).split(/\\s+/);\n action = {\n kind: 'exec',\n command: parts[0],\n args: parts.slice(1),\n envFile: opts.envFile as string | undefined,\n timeoutSec: opts.timeout as number | undefined,\n };\n } else {\n throw new CrontickError('MISSING_ARG', 'Provide --script or --exec');\n }\n\n jobData = {\n id,\n description: opts.desc as string | undefined,\n schedule,\n action,\n overlap: opts.overlap as string,\n retry: opts.retry !== undefined ? { max: opts.retry as number, backoffSec: 30 } : undefined,\n };\n }\n\n const parsed = JobSchema.safeParse(jobData);\n if (!parsed.success) {\n throw new CrontickError('VALIDATION_ERROR', 'Invalid job', parsed.error.format());\n }\n\n const result = await api('POST', '/api/jobs', parsed.data);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── list ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command('list')\n .description('List all jobs')\n .action(async () => {\n try {\n const jobs = await api('GET', '/api/jobs');\n print(jobs, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── get ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('get <id>')\n .description('Get a job by ID')\n .action(async (id: string) => {\n try {\n const job = await api('GET', `/api/jobs/${encodeURIComponent(id)}`);\n print(job, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── enable / disable / delete ─────────────────────────────────────────────────\n\nprogram\n .command('enable <id>')\n .description('Enable a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/enable`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('disable <id>')\n .description('Disable a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/disable`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('delete <id>')\n .description('Delete a job')\n .action(async (id: string) => {\n try {\n const result = await api('DELETE', `/api/jobs/${encodeURIComponent(id)}`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── run-now ───────────────────────────────────────────────────────────────────\n\nprogram\n .command('run-now <id>')\n .description('Trigger an immediate run of a job')\n .action(async (id: string) => {\n try {\n const result = await api('POST', `/api/jobs/${encodeURIComponent(id)}/run`);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── logs ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command('logs <runId>')\n .description('Get logs for a run')\n .option('--follow', 'Follow (SSE stream) — not implemented in CLI yet; use --tail')\n .option('--tail <n>', 'Show last N lines', parseInt)\n .action(async (runId: string, opts) => {\n try {\n const useJson = !!(program.opts() as { json?: boolean }).json;\n const logs = await api('GET', `/api/runs/${encodeURIComponent(runId)}/logs`) as Array<{\n stream: string;\n ts: number;\n data: string;\n }>;\n const lines = (Array.isArray(logs) ? logs : []) as Array<{ stream: string; ts: number; data: string }>;\n const tail = opts.tail as number | undefined;\n const display = tail ? lines.slice(-tail) : lines;\n if (useJson) {\n console.log(JSON.stringify(display, null, 2));\n } else {\n for (const entry of display) {\n process.stdout.write(`[${entry.stream}] ${entry.data}`);\n }\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── export / import ───────────────────────────────────────────────────────────\n\nprogram\n .command('export')\n .description('Export all jobs')\n .option('--out <file>', 'Output file (default: stdout)')\n .action(async (opts) => {\n try {\n const data = await api('GET', '/api/export');\n const json = JSON.stringify(data, null, 2);\n if (opts.out) {\n writeFileSync(resolve(process.cwd(), opts.out as string), json, 'utf-8');\n console.log(`Exported to ${opts.out as string}`);\n } else {\n console.log(json);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\nprogram\n .command('import <file>')\n .description('Import jobs from a JSON file')\n .action(async (file: string) => {\n try {\n const raw = readFileSync(resolve(process.cwd(), file), 'utf-8');\n const data = JSON.parse(raw);\n const result = await api('POST', '/api/import', data);\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── doctor ────────────────────────────────────────────────────────────────────\n\nprogram\n .command('doctor')\n .description('Check system health')\n .action(async () => {\n const checks: Array<{ name: string; ok: boolean; note?: string }> = [];\n\n // Node version\n const major = parseInt(process.versions.node.split('.')[0], 10);\n checks.push({\n name: 'Node.js >= 22.5',\n ok: major >= 22,\n note: `v${process.versions.node}`,\n });\n\n // SQLite availability\n try {\n const { DatabaseSync } = await import('node:sqlite');\n new DatabaseSync(':memory:').close();\n checks.push({ name: 'node:sqlite', ok: true });\n } catch (err) {\n checks.push({ name: 'node:sqlite', ok: false, note: String(err) });\n }\n\n // Data dir\n try {\n ensureDirs();\n checks.push({ name: 'data dir writable', ok: true });\n } catch (err) {\n checks.push({ name: 'data dir writable', ok: false, note: String(err) });\n }\n\n // Port file\n const portFile = portFilePath();\n const portFileExists = existsSync(portFile);\n checks.push({ name: 'port file readable', ok: portFileExists, note: portFileExists ? portFile : 'not found' });\n\n // Daemon reachable\n try {\n await api('GET', '/health');\n checks.push({ name: 'daemon reachable', ok: true });\n } catch {\n checks.push({ name: 'daemon reachable', ok: false, note: 'not running' });\n }\n\n // Dashboard reachable\n try {\n const port2 = getPort();\n const dashRes = await fetch(`http://127.0.0.1:${port2}/dashboard`, {\n signal: AbortSignal.timeout(2000),\n });\n const text = await dashRes.text();\n checks.push({\n name: 'dashboard reachable',\n ok: dashRes.status === 200 && text.includes('crontick'),\n note: dashRes.status === 200 ? 'ok' : `HTTP ${dashRes.status}`,\n });\n } catch {\n checks.push({ name: 'dashboard reachable', ok: false, note: 'daemon not running or no dashboard' });\n }\n\n // Autostart status\n try {\n const asResult = await api('GET', '/api/autostart/status');\n const as = asResult as { installed?: boolean; backend?: string };\n checks.push({\n name: 'autostart',\n ok: true,\n note: `backend=${as.backend ?? '?'}, installed=${String(as.installed ?? false)}`,\n });\n } catch {\n checks.push({ name: 'autostart', ok: false, note: 'could not check (daemon not running)' });\n }\n\n // MCP server binary\n const mcpScript = resolve(__dirname, '../mcp/index.js');\n checks.push({\n name: 'MCP server binary',\n ok: existsSync(mcpScript),\n note: mcpScript,\n });\n\n // MCP server --help smoke test\n try {\n const result = spawnSync(process.execPath, [mcpScript, '--help'], {\n timeout: 5000,\n encoding: 'utf-8',\n env: { ...process.env, CRONTICK_MCP_NO_AUTOSTART: '1' },\n });\n // --help exits 0 on commander; if exit code is 0 or it printed help text it's fine\n const helpOk = result.status === 0 || (result.stdout ?? '').includes('stdio');\n checks.push({ name: 'MCP server --help', ok: helpOk });\n } catch (err) {\n checks.push({ name: 'MCP server --help', ok: false, note: String(err) });\n }\n\n for (const c of checks) {\n const icon = c.ok ? '✓' : '✗';\n console.log(`${icon} ${c.name}${c.note ? ` (${c.note})` : ''}`);\n }\n\n const failed = checks.filter((c) => !c.ok);\n if (failed.length > 0) process.exit(1);\n });\n\n// ── daemon ────────────────────────────────────────────────────────────────────\n\nconst daemon = program.command('daemon').description('Manage the crontick daemon');\n\ndaemon\n .command('start')\n .description('Start the daemon (detached by default)')\n .option('--foreground', 'Run in foreground (blocking)')\n .action(async (opts) => {\n try {\n const script = daemonScript();\n if (!existsSync(script)) {\n throw new CrontickError('NOT_BUILT', `Daemon script not found: ${script}. Run: npm run build`);\n }\n\n if (opts.foreground as boolean) {\n // Run inline (blocking — for testing/debugging)\n const result = spawnSync(process.execPath, [script], {\n stdio: 'inherit',\n env: process.env,\n });\n process.exit(result.status ?? 0);\n } else {\n const child = spawn(process.execPath, [script], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n });\n child.unref();\n console.log(`Starting daemon (pid will be written to port file)…`);\n const port = await waitForPort();\n console.log(`Daemon started on port ${port}`);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('stop')\n .description('Stop the daemon')\n .action(async () => {\n try {\n const pidFile = pidFilePath();\n if (!existsSync(pidFile)) {\n console.log('Daemon is not running');\n return;\n }\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n process.kill(pid, 'SIGTERM');\n console.log(`Sent SIGTERM to daemon (pid ${pid})`);\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('status')\n .description('Show daemon status')\n .action(async () => {\n try {\n const status = await api('GET', '/api/daemon/status');\n print(status, !!(program.opts() as { json?: boolean }).json);\n } catch {\n console.log('Daemon is not running');\n }\n });\n\ndaemon\n .command('reload')\n .description('Reload jobs from disk')\n .action(async () => {\n try {\n const result = await api('POST', '/api/daemon/reload');\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\ndaemon\n .command('restart')\n .description('Restart the daemon')\n .action(async () => {\n try {\n // Stop if running\n const pidFile = pidFilePath();\n if (existsSync(pidFile)) {\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n try {\n process.kill(pid, 'SIGTERM');\n await new Promise((r) => setTimeout(r, 1000));\n } catch {\n // ignore\n }\n }\n\n // Start\n const script = daemonScript();\n const child = spawn(process.execPath, [script], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n });\n child.unref();\n const port = await waitForPort();\n console.log(`Daemon restarted on port ${port}`);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── autostart ─────────────────────────────────────────────────────────────────\n\nconst autostart = program.command('autostart').description('Manage daemon autostart at login');\n\nautostart\n .command('install')\n .description('Register the daemon to start automatically at login')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.install();\n print(result, !!(program.opts() as { json?: boolean }).json);\n if (process.platform !== 'win32' && !backend) {\n const statusResult = await as.status();\n const details = (statusResult.details as Record<string, unknown> | undefined);\n const instr = details?.['instructions'] as string | undefined;\n if (instr) console.log('\\nManual setup instructions:\\n' + instr);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\nautostart\n .command('remove')\n .description('Remove the daemon from automatic startup')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.remove();\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\nautostart\n .command('status')\n .description('Check whether the daemon is registered for automatic startup')\n .option('--backend <backend>', 'Backend: win32|darwin|linux|manual (default: auto-detect)')\n .action(async (opts) => {\n try {\n const backend = opts.backend as AutostartBackend | undefined;\n const as = createAutostart({ backend });\n const result = await as.status();\n print(result, !!(program.opts() as { json?: boolean }).json);\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── uninstall ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('uninstall')\n .description('Remove autostart entry and optionally delete all crontick data')\n .option('--purge', 'Also delete the data directory (jobs, runs, config)')\n .option('--yes', 'Skip confirmation prompts')\n .action(async (opts) => {\n try {\n // Remove autostart\n const as = createAutostart();\n await as.remove();\n console.log('✓ Autostart entry removed.');\n\n if (opts.purge as boolean) {\n const dir = dataDir();\n let confirmed = opts.yes as boolean;\n if (!confirmed) {\n confirmed = await new Promise<boolean>((resolve) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(`Delete all crontick data at ${dir}? [y/N] `, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y');\n });\n });\n }\n if (confirmed) {\n rmSync(dir, { recursive: true, force: true });\n console.log(`✓ Data directory deleted: ${dir}`);\n } else {\n console.log('Skipped data directory deletion.');\n }\n } else {\n console.log(\n 'Data directory preserved. Run `crontick uninstall --purge` to also delete it.',\n );\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── dashboard ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('dashboard')\n .description('Open the crontick dashboard in a browser')\n .option('--open', 'Open in the default browser')\n .action(async (opts) => {\n try {\n const port = getPort();\n const url = `http://127.0.0.1:${port}/dashboard`;\n if (opts.open as boolean) {\n if (process.platform === 'win32') {\n spawn('cmd', ['/c', 'start', url], { detached: true, stdio: 'ignore' }).unref();\n } else if (process.platform === 'darwin') {\n spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();\n } else {\n try {\n spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();\n } catch {\n // xdg-open not available\n }\n }\n console.log(`Dashboard opened: ${url}`);\n } else {\n console.log(`Dashboard: ${url}`);\n }\n } catch (err) {\n handleError(err);\n }\n });\n\n// ── mcp ───────────────────────────────────────────────────────────────────────\n\nprogram\n .command('mcp')\n .description('Start the crontick MCP server on stdio (for use with Claude Desktop, Copilot, Cursor, etc.)')\n .option('--no-autostart', 'Do not auto-start the daemon if it is not already running')\n .option('--daemon-url <url>', 'Override the daemon URL (default: resolved from port file)')\n .addHelpText(\n 'after',\n `\nTransport: stdio (JSON-RPC 2.0 over stdin/stdout)\nTool prefix: crontick_\nAutostart: Daemon is auto-started unless --no-autostart or CRONTICK_MCP_NO_AUTOSTART=1 is set\n\nExample MCP host config (Claude Desktop):\n {\n \"mcpServers\": {\n \"crontick\": { \"command\": \"crontick\", \"args\": [\"mcp\"] }\n }\n }`,\n )\n .action((opts) => {\n const mcpScript = resolve(__dirname, '../mcp/index.js');\n if (!existsSync(mcpScript)) {\n console.error(`MCP server script not found: ${mcpScript}. Run: npm run build`);\n process.exit(1);\n }\n const env: NodeJS.ProcessEnv = { ...process.env };\n if (opts.noAutostart) env['CRONTICK_MCP_NO_AUTOSTART'] = '1';\n if (opts.daemonUrl) env['CRONTICK_DAEMON_URL'] = opts.daemonUrl as string;\n const result = spawnSync(process.execPath, [mcpScript], {\n stdio: 'inherit',\n env,\n });\n process.exit(result.status ?? 0);\n });\n\n// ── parse ─────────────────────────────────────────────────────────────────────\n\nprogram.parse();\n","// Version constant injected at build time by tsup/esbuild (define: __CRONTICK_VERSION__)\n// and at test time by vitest (define in vitest.config.ts).\ndeclare const __CRONTICK_VERSION__: string;\nexport const VERSION: string = __CRONTICK_VERSION__;\n","import envPaths from 'env-paths';\nimport { mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nfunction root(): string {\n const override = process.env['CRONTICK_HOME'];\n if (override) return override;\n // env-paths v3: data dir on windows = %LOCALAPPDATA%\\crontick\n return envPaths('crontick', { suffix: '' }).data;\n}\n\nexport function dataDir(): string {\n return root();\n}\n\nexport function jobsDir(): string {\n return join(root(), 'jobs');\n}\n\nexport function runsDbPath(): string {\n return join(root(), 'runs.db');\n}\n\nexport function logsDir(): string {\n return join(root(), 'logs');\n}\n\nexport function configPath(): string {\n return join(root(), 'config.json');\n}\n\nexport function pidFilePath(): string {\n return join(root(), 'daemon.pid');\n}\n\nexport function portFilePath(): string {\n return join(root(), 'daemon.port');\n}\n\nexport function autostartDir(): string {\n return join(root(), 'autostart');\n}\n\nexport function ensureDirs(): void {\n for (const dir of [dataDir(), jobsDir(), logsDir()]) {\n mkdirSync(dir, { recursive: true });\n }\n}\n","import { z } from 'zod';\n\n// ── Schedule ──────────────────────────────────────────────────────────────────\n\nexport const CronScheduleSchema = z.object({\n kind: z.literal('cron'),\n cron: z.string().min(1),\n tz: z.string().optional(),\n});\n\nexport const IntervalScheduleSchema = z.object({\n kind: z.literal('interval'),\n everySec: z.number().positive(),\n startAt: z.string().optional(), // ISO-8601\n});\n\nexport const OneShotScheduleSchema = z.object({\n kind: z.literal('one-shot'),\n runAt: z.string().min(1), // ISO-8601\n});\n\nexport const ScheduleSchema = z.discriminatedUnion('kind', [\n CronScheduleSchema,\n IntervalScheduleSchema,\n OneShotScheduleSchema,\n]);\n\n// ── Action ────────────────────────────────────────────────────────────────────\n\nexport const ScriptActionSchema = z.object({\n kind: z.literal('script'),\n script: z.string().min(1),\n shell: z.enum(['auto', 'bash', 'pwsh', 'cmd']).default('auto'),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n envFile: z.string().optional(),\n timeoutSec: z.number().positive().optional(),\n});\n\nexport const ExecActionSchema = z.object({\n kind: z.literal('exec'),\n command: z.string().min(1),\n args: z.array(z.string()).default([]),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n envFile: z.string().optional(),\n timeoutSec: z.number().positive().optional(),\n // shell is intentionally absent: exec always uses shell=false to prevent injection\n});\n\nexport const ActionSchema = z.discriminatedUnion('kind', [ScriptActionSchema, ExecActionSchema]);\n\n// ── Supporting types ──────────────────────────────────────────────────────────\n\nexport const RetrySchema = z.object({\n max: z.number().int().min(0).default(0),\n backoffSec: z.number().positive().default(30),\n});\n\nexport const BudgetsSchema = z.object({\n maxRunsPerDay: z.number().int().positive().nullable().default(null),\n maxTokensPerRun: z.number().int().positive().nullable().default(null),\n});\n\n// ── Job ───────────────────────────────────────────────────────────────────────\n\nconst kebabCase = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nexport const JobSchema = z.object({\n id: z.string().regex(kebabCase, 'Job ID must be kebab-case (e.g. \"my-job\")'),\n description: z.string().optional(),\n enabled: z.boolean().default(true),\n schedule: ScheduleSchema,\n action: ActionSchema,\n catchup: z.enum(['run-once', 'run-all', 'skip']).default('skip'),\n overlap: z.enum(['skip', 'queue', 'cancel-previous']).default('skip'),\n retry: RetrySchema.default({ max: 0, backoffSec: 30 }),\n budgets: BudgetsSchema.default({ maxRunsPerDay: null, maxTokensPerRun: null }),\n});\n\nexport type Job = z.infer<typeof JobSchema>;\nexport type JobInput = z.input<typeof JobSchema>;\nexport type Schedule = z.infer<typeof ScheduleSchema>;\nexport type Action = z.infer<typeof ActionSchema>;\n","export class CrontickError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = 'CrontickError';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, CrontickError.prototype);\n }\n\n toJSON(): { code: string; message: string; details?: unknown } {\n return { code: this.code, message: this.message, details: this.details };\n }\n}\n","/**\n * Windows autostart backend — HKCU Run key + hidden VBS shim.\n *\n * Registry key: HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n * Value name: crontick-daemon (or CRONTICK_AUTOSTART_TEST_VALUE for tests)\n * Value data: wscript.exe \"<dataDir>\\autostart\\crontick-daemon.vbs\"\n *\n * The VBS shim launches crontick-daemon via `cmd /c` with window style 0 (hidden).\n */\nimport { spawnSync } from 'node:child_process';\nimport {\n writeFileSync,\n existsSync,\n unlinkSync,\n mkdirSync,\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { autostartDir } from '../paths.js';\nimport type { AutostartStatus } from './index.js';\n\nconst RUN_KEY = 'Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run';\n\ntype RegistryValue = {\n readonly name: string;\n readonly type: string;\n readonly data: string | number;\n};\n\ntype RegistryJsModule = {\n readonly HKEY: { readonly HKEY_CURRENT_USER: string };\n readonly RegistryValueType: { readonly REG_SZ: string };\n readonly setValue: (\n key: string,\n subkey: string,\n valueName: string,\n valueType: string,\n valueData: string,\n ) => boolean;\n readonly createKey?: (key: string, subkey: string) => boolean;\n readonly deleteValue?: (key: string, subkey: string, valueName: string) => boolean;\n readonly enumerateValues: (key: string, subkey: string) => ReadonlyArray<RegistryValue>;\n};\n\nlet registryJs: RegistryJsModule | null = null;\n\ntype RegistryGlobal = typeof globalThis & { __crontickRegistryJs?: RegistryJsModule };\n\nasync function loadRegistryJs(): Promise<RegistryJsModule> {\n const testRegistryJs = (globalThis as RegistryGlobal).__crontickRegistryJs;\n if (testRegistryJs) return testRegistryJs;\n if (!registryJs) {\n const imported = await import('registry-js') as RegistryJsModule & { default?: RegistryJsModule };\n registryJs = imported.default ?? imported;\n }\n return registryJs;\n}\n\nfunction getValueName(): string {\n return process.env['CRONTICK_AUTOSTART_TEST_VALUE'] ?? 'crontick-daemon';\n}\n\nfunction getVbsPath(): string {\n return join(autostartDir(), 'crontick-daemon.vbs');\n}\n\n/**\n * Locate the absolute path to the crontick-daemon binary/cmd wrapper.\n * Prefers `where.exe` detection so PATH changes don't break the shim.\n * CRONTICK_DAEMON_BINARY env var overrides detection (useful in CI/tests).\n */\nfunction findDaemonBinary(): string | null {\n // 0. Test / CI override\n const override = process.env['CRONTICK_DAEMON_BINARY'];\n if (override) return override;\n\n // 1. Try where.exe\n const whereResult = spawnSync('where.exe', ['crontick-daemon'], {\n encoding: 'utf-8',\n timeout: 5_000,\n windowsHide: true,\n });\n if (whereResult.status === 0 && whereResult.stdout.trim()) {\n const first = whereResult.stdout.trim().split(/[\\r\\n]+/)[0]?.trim();\n if (first) return first;\n }\n\n // 2. Fallback: look in the same directory as the Node.js executable\n const nodeDir = dirname(process.execPath);\n for (const candidate of ['crontick-daemon.cmd', 'crontick-daemon']) {\n const p = join(nodeDir, candidate);\n if (existsSync(p)) return p;\n }\n\n return null;\n}\n\nfunction buildVbsContent(daemonPath: string): string {\n // Remove any double-quotes in path (shouldn't exist in valid Win paths)\n const safePath = daemonPath.replace(/\"/g, '');\n return [\n \"' crontick-daemon autostart shim — generated by crontick autostart install\",\n \"' Do not edit manually. Run: crontick autostart install to regenerate.\",\n 'Set WshShell = CreateObject(\"WScript.Shell\")',\n `WshShell.Run \"cmd /c \"\"${safePath}\"\"\", 0, False`,\n '',\n ].join('\\r\\n');\n}\n\nfunction getRunKey(registry: RegistryJsModule): string {\n return registry.HKEY.HKEY_CURRENT_USER;\n}\n\nfunction isMissingRegistryValueError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n return /not found|cannot find|file not found|ERROR_FILE_NOT_FOUND|ENOENT/i.test(error.message);\n}\n\nfunction quotePowerShellLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction runPowerShellRegistryScript(script: string): string {\n const result = spawnSync(\n 'powershell.exe',\n ['-NoProfile', '-NonInteractive', '-Command', script],\n { encoding: 'utf-8', timeout: 5_000, windowsHide: true },\n );\n if (result.status !== 0) {\n throw new Error(\n `PowerShell registry operation failed (exit ${result.status ?? '?'}): ${result.stderr?.trim() ?? 'unknown error'}`,\n );\n }\n return result.stdout;\n}\n\nfunction queryWithPowerShellRegistryApi(valueName: string): string | null {\n const literalPath = `Registry::HKEY_CURRENT_USER\\\\${RUN_KEY}`;\n const script = [\n '$ErrorActionPreference = \"Stop\";',\n `try { $item = Get-ItemProperty -LiteralPath ${quotePowerShellLiteral(literalPath)} -Name ${quotePowerShellLiteral(valueName)};`,\n `$value = $item.${quotePowerShellLiteral(valueName)};`,\n 'if ($null -ne $value) { [Console]::Out.Write([string]$value) } }',\n 'catch [System.Management.Automation.ItemNotFoundException] { exit 2 }',\n 'catch [System.Management.Automation.PSArgumentException] { exit 2 }',\n 'catch { throw }',\n ].join(' ');\n\n try {\n const stdout = runPowerShellRegistryScript(script);\n return stdout.length > 0 ? stdout : null;\n } catch (error) {\n if (error instanceof Error && /exit 2/.test(error.message)) return null;\n throw error;\n }\n}\n\nfunction writeWithPowerShellRegistryApi(valueName: string, data: string): void {\n const literalPath = `Registry::HKEY_CURRENT_USER\\\\${RUN_KEY}`;\n const script = [\n '$ErrorActionPreference = \"Stop\"',\n `New-Item -Path ${quotePowerShellLiteral(literalPath)} -Force | Out-Null`,\n `New-ItemProperty -LiteralPath ${quotePowerShellLiteral(literalPath)} -Name ${quotePowerShellLiteral(valueName)} -Value ${quotePowerShellLiteral(data)} -PropertyType String -Force | Out-Null`,\n ].join('; ');\n runPowerShellRegistryScript(script);\n}\n\nfunction deleteWithPowerShellRegistryApi(valueName: string): void {\n const literalPath = `Registry::HKEY_CURRENT_USER\\\\${RUN_KEY}`;\n const script = [\n 'Remove-ItemProperty',\n '-LiteralPath', quotePowerShellLiteral(literalPath),\n '-Name', quotePowerShellLiteral(valueName),\n '-ErrorAction', 'SilentlyContinue',\n ].join(' ');\n runPowerShellRegistryScript(script);\n}\n\nasync function registryQuery(valueName: string): Promise<string | null> {\n try {\n const registry = await loadRegistryJs();\n let values: ReadonlyArray<RegistryValue>;\n try {\n values = registry.enumerateValues(getRunKey(registry), RUN_KEY);\n } catch (error) {\n if (isMissingRegistryValueError(error)) return null;\n throw error;\n }\n const entry = values.find((value) => value.name.toLowerCase() === valueName.toLowerCase());\n return typeof entry?.data === 'string' ? entry.data : null;\n } catch {\n return queryWithPowerShellRegistryApi(valueName);\n }\n}\n\nasync function registryWrite(valueName: string, data: string): Promise<void> {\n try {\n const registry = await loadRegistryJs();\n registry.createKey?.(getRunKey(registry), RUN_KEY);\n const ok = registry.setValue(\n getRunKey(registry),\n RUN_KEY,\n valueName,\n registry.RegistryValueType.REG_SZ,\n data,\n );\n if (ok) return;\n } catch {\n // Fallback below.\n }\n writeWithPowerShellRegistryApi(valueName, data);\n}\n\nasync function registryDelete(valueName: string): Promise<void> {\n let registry: RegistryJsModule;\n try {\n registry = await loadRegistryJs();\n } catch {\n deleteWithPowerShellRegistryApi(valueName);\n return;\n }\n\n try {\n if (typeof registry.deleteValue !== 'function') {\n deleteWithPowerShellRegistryApi(valueName);\n return;\n }\n registry.deleteValue(getRunKey(registry), RUN_KEY, valueName);\n } catch (error) {\n if (isMissingRegistryValueError(error)) return;\n deleteWithPowerShellRegistryApi(valueName);\n }\n}\n\nexport class Win32Autostart {\n async install(): Promise<{ ok: true }> {\n const daemonPath = findDaemonBinary();\n if (!daemonPath) {\n throw new Error(\n 'crontick-daemon binary not found. Ensure crontick is installed globally: npm i -g crontick',\n );\n }\n\n const vbsPath = getVbsPath();\n const valueName = getValueName();\n\n // Ensure directory and write VBS shim\n mkdirSync(autostartDir(), { recursive: true });\n writeFileSync(vbsPath, buildVbsContent(daemonPath), 'utf-8');\n\n await registryWrite(valueName, `wscript.exe \"${vbsPath}\"`);\n\n return { ok: true };\n }\n\n async remove(): Promise<{ ok: true }> {\n const valueName = getValueName();\n await registryDelete(valueName);\n\n // Remove VBS shim if it exists\n const vbsPath = getVbsPath();\n if (existsSync(vbsPath)) {\n try { unlinkSync(vbsPath); } catch { /* ignore */ }\n }\n\n return { ok: true };\n }\n\n async status(): Promise<AutostartStatus> {\n const valueName = getValueName();\n const data = await registryQuery(valueName);\n const installed = data !== null;\n return {\n installed,\n backend: 'win32',\n details: installed\n ? { registryValue: valueName, registryData: data, vbsPath: getVbsPath() }\n : { registryValue: valueName },\n };\n }\n}\n","/**\n * Manual autostart backend — prints per-platform instructions.\n * Works on any platform; used as the default on non-Windows in v1.\n */\nimport type { AutostartStatus } from './index.js';\n\nfunction instructions(): string {\n switch (process.platform) {\n case 'win32':\n return (\n 'Windows: add the following command to your startup folder or HKCU Run key:\\n' +\n ' crontick-daemon\\n' +\n 'Or run: crontick autostart install (uses HKCU Run + hidden VBS shim)'\n );\n case 'darwin':\n return (\n 'macOS (post-v1): create a launchd plist at\\n' +\n ' ~/Library/LaunchAgents/com.crontick.daemon.plist\\n' +\n 'with ProgramArguments pointing to the crontick-daemon binary.\\n' +\n 'Then run: launchctl load ~/Library/LaunchAgents/com.crontick.daemon.plist\\n' +\n '\\nFor now, add the following to your shell profile (~/.zprofile or ~/.bash_profile):\\n' +\n ' crontick-daemon &'\n );\n case 'linux':\n return (\n 'Linux (post-v1): create a systemd user unit at\\n' +\n ' ~/.config/systemd/user/crontick.service\\n' +\n 'Then run: systemctl --user enable --now crontick.service\\n' +\n '\\nFor now, add the following to your shell profile (~/.profile or ~/.bashrc):\\n' +\n ' crontick-daemon &\\n' +\n 'Or add a @reboot crontab entry: crontab -e\\n' +\n ' @reboot crontick-daemon'\n );\n default:\n return (\n 'Add `crontick-daemon` to your system startup mechanism.\\n' +\n 'The daemon listens on a random localhost port; the port is written to the data directory.'\n );\n }\n}\n\nexport class ManualAutostart {\n async install(): Promise<{ ok: true }> {\n return { ok: true };\n }\n\n async remove(): Promise<{ ok: true }> {\n return { ok: true };\n }\n\n async status(): Promise<AutostartStatus> {\n return {\n installed: false,\n backend: 'manual',\n details: { instructions: instructions() },\n };\n }\n}\n","/**\n * macOS autostart backend — STUB for post-v1.\n *\n * TODO (darwin implementation, post-v1):\n * - install():\n * 1. Build a launchd plist string for com.crontick.daemon\n * 2. Write to ~/Library/LaunchAgents/com.crontick.daemon.plist\n * 3. Run: launchctl load ~/Library/LaunchAgents/com.crontick.daemon.plist\n * - remove():\n * 1. Run: launchctl unload ~/Library/LaunchAgents/com.crontick.daemon.plist\n * 2. Delete ~/Library/LaunchAgents/com.crontick.daemon.plist\n * - status():\n * Run: launchctl list com.crontick.daemon (exit 0 = loaded)\n *\n * Plist template:\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n * <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" ...>\n * <plist version=\"1.0\"><dict>\n * <key>Label</key><string>com.crontick.daemon</string>\n * <key>ProgramArguments</key>\n * <array><string>/usr/local/bin/crontick-daemon</string></array>\n * <key>RunAtLoad</key><true/>\n * <key>StandardOutPath</key><string>~/.local/state/crontick/logs/daemon.stdout.log</string>\n * <key>StandardErrorPath</key><string>~/.local/state/crontick/logs/daemon.stderr.log</string>\n * </dict></plist>\n */\nimport { NotImplementedInV1Error } from './index.js';\nimport type { AutostartStatus } from './index.js';\n\nexport class DarwinAutostart {\n async install(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now. ' +\n 'See https://github.com/crontick/crontick for updates.',\n );\n }\n\n async remove(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now.',\n );\n }\n\n async status(): Promise<AutostartStatus> {\n throw new NotImplementedInV1Error(\n 'darwin autostart is planned for post-v1; use manual for now.',\n );\n }\n}\n","/**\n * Linux autostart backend — STUB for post-v1.\n *\n * TODO (linux implementation, post-v1):\n * - install():\n * 1. Create ~/.config/systemd/user/ if absent\n * 2. Write unit file to ~/.config/systemd/user/crontick.service:\n *\n * [Unit]\n * Description=crontick daemon\n * After=default.target\n *\n * [Service]\n * Type=simple\n * ExecStart=/usr/local/bin/crontick-daemon\n * Restart=on-failure\n * RestartSec=5\n *\n * [Install]\n * WantedBy=default.target\n *\n * 3. Run: systemctl --user daemon-reload\n * 4. Run: systemctl --user enable --now crontick.service\n *\n * - remove():\n * 1. Run: systemctl --user disable --now crontick.service\n * 2. Delete ~/.config/systemd/user/crontick.service\n * 3. Run: systemctl --user daemon-reload\n *\n * - status():\n * Run: systemctl --user is-active crontick.service (exit 0 = active)\n */\nimport { NotImplementedInV1Error } from './index.js';\nimport type { AutostartStatus } from './index.js';\n\nexport class LinuxAutostart {\n async install(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now. ' +\n 'See https://github.com/crontick/crontick for updates.',\n );\n }\n\n async remove(): Promise<{ ok: true }> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now.',\n );\n }\n\n async status(): Promise<AutostartStatus> {\n throw new NotImplementedInV1Error(\n 'linux autostart is planned for post-v1; use manual for now.',\n );\n }\n}\n","/**\n * Autostart abstraction — factory + types.\n * v1: win32 (HKCU Run + VBS shim) and manual (prints instructions).\n * darwin/linux are stubs that throw NotImplementedInV1Error.\n */\nimport { Win32Autostart } from './win32.js';\nimport { ManualAutostart } from './manual.js';\nimport { DarwinAutostart } from './darwin.js';\nimport { LinuxAutostart } from './linux.js';\n\nexport type AutostartBackend = 'win32' | 'darwin' | 'linux' | 'manual';\n\nexport interface AutostartStatus {\n installed: boolean;\n backend: AutostartBackend;\n details?: unknown;\n}\n\nexport interface Autostart {\n install(): Promise<{ ok: true }>;\n remove(): Promise<{ ok: true }>;\n status(): Promise<AutostartStatus>;\n}\n\n/** Thrown by darwin/linux stubs; serialised as HTTP 501 by the daemon API. */\nexport class NotImplementedInV1Error extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotImplementedInV1Error';\n Object.setPrototypeOf(this, NotImplementedInV1Error.prototype);\n }\n}\n\n/**\n * Factory: default = win32 on Windows, manual everywhere else.\n * An explicit `opts.backend` always overrides the default.\n */\nexport function createAutostart(opts?: { backend?: AutostartBackend }): Autostart {\n const backend: AutostartBackend =\n opts?.backend ?? (process.platform === 'win32' ? 'win32' : 'manual');\n switch (backend) {\n case 'win32': return new Win32Autostart();\n case 'darwin': return new DarwinAutostart();\n case 'linux': return new LinuxAutostart();\n case 'manual':\n default: return new ManualAutostart();\n }\n}\n"],"mappings":"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","names":["import_node_child_process","import_node_fs","import_node_path","envPaths","import_node_fs","import_node_path","resolve"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createAutostart
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-KNOV44I4.js";
|
|
5
5
|
import {
|
|
6
6
|
CrontickError
|
|
7
7
|
} from "../chunk-YMAT5MON.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
ensureDirs,
|
|
12
12
|
pidFilePath,
|
|
13
13
|
portFilePath
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-5LHE6MWX.js";
|
|
15
15
|
import {
|
|
16
16
|
JobSchema
|
|
17
17
|
} from "../chunk-35FFLWP3.js";
|
package/dist/daemon/index.cjs
CHANGED
|
@@ -945,13 +945,23 @@ var import_node_url2 = require("url");
|
|
|
945
945
|
init_job();
|
|
946
946
|
|
|
947
947
|
// src/version.ts
|
|
948
|
-
var VERSION = "0.1.
|
|
948
|
+
var VERSION = "0.1.1";
|
|
949
949
|
|
|
950
950
|
// src/autostart/win32.ts
|
|
951
951
|
var import_node_child_process2 = require("child_process");
|
|
952
952
|
var import_node_fs4 = require("fs");
|
|
953
953
|
var import_node_path4 = require("path");
|
|
954
|
-
var RUN_KEY = "
|
|
954
|
+
var RUN_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
|
955
|
+
var registryJs = null;
|
|
956
|
+
async function loadRegistryJs() {
|
|
957
|
+
const testRegistryJs = globalThis.__crontickRegistryJs;
|
|
958
|
+
if (testRegistryJs) return testRegistryJs;
|
|
959
|
+
if (!registryJs) {
|
|
960
|
+
const imported = await import("registry-js");
|
|
961
|
+
registryJs = imported.default ?? imported;
|
|
962
|
+
}
|
|
963
|
+
return registryJs;
|
|
964
|
+
}
|
|
955
965
|
function getValueName() {
|
|
956
966
|
return process.env["CRONTICK_AUTOSTART_TEST_VALUE"] ?? "crontick-daemon";
|
|
957
967
|
}
|
|
@@ -987,34 +997,120 @@ function buildVbsContent(daemonPath) {
|
|
|
987
997
|
""
|
|
988
998
|
].join("\r\n");
|
|
989
999
|
}
|
|
990
|
-
function
|
|
991
|
-
|
|
992
|
-
"reg",
|
|
993
|
-
["query", RUN_KEY, "/v", valueName],
|
|
994
|
-
{ encoding: "utf-8", timeout: 5e3, windowsHide: true }
|
|
995
|
-
);
|
|
996
|
-
if (result.status !== 0 || !result.stdout) return null;
|
|
997
|
-
const match = result.stdout.match(/REG_SZ\s+(.+)/i);
|
|
998
|
-
return match?.[1]?.trim() ?? null;
|
|
1000
|
+
function getRunKey(registry) {
|
|
1001
|
+
return registry.HKEY.HKEY_CURRENT_USER;
|
|
999
1002
|
}
|
|
1000
|
-
function
|
|
1003
|
+
function isMissingRegistryValueError(error) {
|
|
1004
|
+
if (!(error instanceof Error)) return false;
|
|
1005
|
+
return /not found|cannot find|file not found|ERROR_FILE_NOT_FOUND|ENOENT/i.test(error.message);
|
|
1006
|
+
}
|
|
1007
|
+
function quotePowerShellLiteral(value) {
|
|
1008
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
1009
|
+
}
|
|
1010
|
+
function runPowerShellRegistryScript(script) {
|
|
1001
1011
|
const result = (0, import_node_child_process2.spawnSync)(
|
|
1002
|
-
"
|
|
1003
|
-
["
|
|
1012
|
+
"powershell.exe",
|
|
1013
|
+
["-NoProfile", "-NonInteractive", "-Command", script],
|
|
1004
1014
|
{ encoding: "utf-8", timeout: 5e3, windowsHide: true }
|
|
1005
1015
|
);
|
|
1006
1016
|
if (result.status !== 0) {
|
|
1007
1017
|
throw new Error(
|
|
1008
|
-
`
|
|
1018
|
+
`PowerShell registry operation failed (exit ${result.status ?? "?"}): ${result.stderr?.trim() ?? "unknown error"}`
|
|
1009
1019
|
);
|
|
1010
1020
|
}
|
|
1021
|
+
return result.stdout;
|
|
1011
1022
|
}
|
|
1012
|
-
function
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
{
|
|
1017
|
-
|
|
1023
|
+
function queryWithPowerShellRegistryApi(valueName) {
|
|
1024
|
+
const literalPath = `Registry::HKEY_CURRENT_USER\\${RUN_KEY}`;
|
|
1025
|
+
const script = [
|
|
1026
|
+
'$ErrorActionPreference = "Stop";',
|
|
1027
|
+
`try { $item = Get-ItemProperty -LiteralPath ${quotePowerShellLiteral(literalPath)} -Name ${quotePowerShellLiteral(valueName)};`,
|
|
1028
|
+
`$value = $item.${quotePowerShellLiteral(valueName)};`,
|
|
1029
|
+
"if ($null -ne $value) { [Console]::Out.Write([string]$value) } }",
|
|
1030
|
+
"catch [System.Management.Automation.ItemNotFoundException] { exit 2 }",
|
|
1031
|
+
"catch [System.Management.Automation.PSArgumentException] { exit 2 }",
|
|
1032
|
+
"catch { throw }"
|
|
1033
|
+
].join(" ");
|
|
1034
|
+
try {
|
|
1035
|
+
const stdout = runPowerShellRegistryScript(script);
|
|
1036
|
+
return stdout.length > 0 ? stdout : null;
|
|
1037
|
+
} catch (error) {
|
|
1038
|
+
if (error instanceof Error && /exit 2/.test(error.message)) return null;
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
function writeWithPowerShellRegistryApi(valueName, data) {
|
|
1043
|
+
const literalPath = `Registry::HKEY_CURRENT_USER\\${RUN_KEY}`;
|
|
1044
|
+
const script = [
|
|
1045
|
+
'$ErrorActionPreference = "Stop"',
|
|
1046
|
+
`New-Item -Path ${quotePowerShellLiteral(literalPath)} -Force | Out-Null`,
|
|
1047
|
+
`New-ItemProperty -LiteralPath ${quotePowerShellLiteral(literalPath)} -Name ${quotePowerShellLiteral(valueName)} -Value ${quotePowerShellLiteral(data)} -PropertyType String -Force | Out-Null`
|
|
1048
|
+
].join("; ");
|
|
1049
|
+
runPowerShellRegistryScript(script);
|
|
1050
|
+
}
|
|
1051
|
+
function deleteWithPowerShellRegistryApi(valueName) {
|
|
1052
|
+
const literalPath = `Registry::HKEY_CURRENT_USER\\${RUN_KEY}`;
|
|
1053
|
+
const script = [
|
|
1054
|
+
"Remove-ItemProperty",
|
|
1055
|
+
"-LiteralPath",
|
|
1056
|
+
quotePowerShellLiteral(literalPath),
|
|
1057
|
+
"-Name",
|
|
1058
|
+
quotePowerShellLiteral(valueName),
|
|
1059
|
+
"-ErrorAction",
|
|
1060
|
+
"SilentlyContinue"
|
|
1061
|
+
].join(" ");
|
|
1062
|
+
runPowerShellRegistryScript(script);
|
|
1063
|
+
}
|
|
1064
|
+
async function registryQuery(valueName) {
|
|
1065
|
+
try {
|
|
1066
|
+
const registry = await loadRegistryJs();
|
|
1067
|
+
let values;
|
|
1068
|
+
try {
|
|
1069
|
+
values = registry.enumerateValues(getRunKey(registry), RUN_KEY);
|
|
1070
|
+
} catch (error) {
|
|
1071
|
+
if (isMissingRegistryValueError(error)) return null;
|
|
1072
|
+
throw error;
|
|
1073
|
+
}
|
|
1074
|
+
const entry = values.find((value) => value.name.toLowerCase() === valueName.toLowerCase());
|
|
1075
|
+
return typeof entry?.data === "string" ? entry.data : null;
|
|
1076
|
+
} catch {
|
|
1077
|
+
return queryWithPowerShellRegistryApi(valueName);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
async function registryWrite(valueName, data) {
|
|
1081
|
+
try {
|
|
1082
|
+
const registry = await loadRegistryJs();
|
|
1083
|
+
registry.createKey?.(getRunKey(registry), RUN_KEY);
|
|
1084
|
+
const ok = registry.setValue(
|
|
1085
|
+
getRunKey(registry),
|
|
1086
|
+
RUN_KEY,
|
|
1087
|
+
valueName,
|
|
1088
|
+
registry.RegistryValueType.REG_SZ,
|
|
1089
|
+
data
|
|
1090
|
+
);
|
|
1091
|
+
if (ok) return;
|
|
1092
|
+
} catch {
|
|
1093
|
+
}
|
|
1094
|
+
writeWithPowerShellRegistryApi(valueName, data);
|
|
1095
|
+
}
|
|
1096
|
+
async function registryDelete(valueName) {
|
|
1097
|
+
let registry;
|
|
1098
|
+
try {
|
|
1099
|
+
registry = await loadRegistryJs();
|
|
1100
|
+
} catch {
|
|
1101
|
+
deleteWithPowerShellRegistryApi(valueName);
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
try {
|
|
1105
|
+
if (typeof registry.deleteValue !== "function") {
|
|
1106
|
+
deleteWithPowerShellRegistryApi(valueName);
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
registry.deleteValue(getRunKey(registry), RUN_KEY, valueName);
|
|
1110
|
+
} catch (error) {
|
|
1111
|
+
if (isMissingRegistryValueError(error)) return;
|
|
1112
|
+
deleteWithPowerShellRegistryApi(valueName);
|
|
1113
|
+
}
|
|
1018
1114
|
}
|
|
1019
1115
|
var Win32Autostart = class {
|
|
1020
1116
|
async install() {
|
|
@@ -1028,13 +1124,12 @@ var Win32Autostart = class {
|
|
|
1028
1124
|
const valueName = getValueName();
|
|
1029
1125
|
(0, import_node_fs4.mkdirSync)(autostartDir(), { recursive: true });
|
|
1030
1126
|
(0, import_node_fs4.writeFileSync)(vbsPath, buildVbsContent(daemonPath), "utf-8");
|
|
1031
|
-
|
|
1032
|
-
regWrite(valueName, `wscript.exe "${vbsPath}"`);
|
|
1127
|
+
await registryWrite(valueName, `wscript.exe "${vbsPath}"`);
|
|
1033
1128
|
return { ok: true };
|
|
1034
1129
|
}
|
|
1035
1130
|
async remove() {
|
|
1036
1131
|
const valueName = getValueName();
|
|
1037
|
-
|
|
1132
|
+
await registryDelete(valueName);
|
|
1038
1133
|
const vbsPath = getVbsPath();
|
|
1039
1134
|
if ((0, import_node_fs4.existsSync)(vbsPath)) {
|
|
1040
1135
|
try {
|
|
@@ -1046,7 +1141,7 @@ var Win32Autostart = class {
|
|
|
1046
1141
|
}
|
|
1047
1142
|
async status() {
|
|
1048
1143
|
const valueName = getValueName();
|
|
1049
|
-
const data =
|
|
1144
|
+
const data = await registryQuery(valueName);
|
|
1050
1145
|
const installed = data !== null;
|
|
1051
1146
|
return {
|
|
1052
1147
|
installed,
|