@michael-joseph-miller/ant-bot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/browser-OHRD7YI3.js +524 -0
- package/dist/browser-OHRD7YI3.js.map +7 -0
- package/dist/bundled-46DUK5PG.js +133 -0
- package/dist/bundled-46DUK5PG.js.map +7 -0
- package/dist/chunk-7BOHBPB2.js +287 -0
- package/dist/chunk-7BOHBPB2.js.map +7 -0
- package/dist/chunk-AHAON6J7.js +24 -0
- package/dist/chunk-AHAON6J7.js.map +7 -0
- package/dist/chunk-DYIJTUMY.js +321 -0
- package/dist/chunk-DYIJTUMY.js.map +7 -0
- package/dist/chunk-KSQOVWP5.js +310 -0
- package/dist/chunk-KSQOVWP5.js.map +7 -0
- package/dist/chunk-Z2YT2PZN.js +64 -0
- package/dist/chunk-Z2YT2PZN.js.map +7 -0
- package/dist/index.js +1562 -0
- package/dist/index.js.map +7 -0
- package/dist/install-IY2M3OUQ.js +36 -0
- package/dist/install-IY2M3OUQ.js.map +7 -0
- package/dist/plugin-POMHVGD4.js +53 -0
- package/dist/plugin-POMHVGD4.js.map +7 -0
- package/dist/scheduler-Q7OHNGP6.js +274 -0
- package/dist/scheduler-Q7OHNGP6.js.map +7 -0
- package/dist/server.js +3016 -0
- package/dist/server.js.map +7 -0
- package/dist/skills-66WRX64H.js +17 -0
- package/dist/skills-66WRX64H.js.map +7 -0
- package/dist/skills-spec.js +172 -0
- package/dist/skills-spec.js.map +7 -0
- package/dist/tools-P5537ASX.js +148 -0
- package/dist/tools-P5537ASX.js.map +7 -0
- package/package.json +51 -0
- package/skills/README.md +69 -0
- package/skills/SPEC.md +274 -0
- package/skills/bug-repro/SKILL.md +53 -0
- package/skills/deep-research/SKILL.md +451 -0
- package/skills/deep-research/references/V6_1_improvements.md +112 -0
- package/skills/deep-research/references/completeness_review_checklist.md +25 -0
- package/skills/deep-research/references/counter_review_team_guide.md +181 -0
- package/skills/deep-research/references/enterprise_analysis_frameworks.md +135 -0
- package/skills/deep-research/references/enterprise_mode.md +99 -0
- package/skills/deep-research/references/enterprise_quality_checklist.md +160 -0
- package/skills/deep-research/references/enterprise_research_methodology.md +164 -0
- package/skills/deep-research/references/formatting_rules.md +31 -0
- package/skills/deep-research/references/quality_gates.md +77 -0
- package/skills/deep-research/references/report_template_v6.md +82 -0
- package/skills/deep-research/references/research_notes_format.md +147 -0
- package/skills/deep-research/references/research_plan_checklist.md +26 -0
- package/skills/deep-research/references/research_report_template.md +49 -0
- package/skills/deep-research/references/source_accessibility_policy.md +179 -0
- package/skills/deep-research/references/source_quality_rubric.md +28 -0
- package/skills/deep-research/references/subagent_prompt.md +116 -0
- package/skills/inbox-digest/SKILL.md +51 -0
- package/skills/skill-author/SKILL.md +92 -0
- package/skills/weekly-report/SKILL.md +49 -0
- package/web/dist/assets/index-BLQ8rPiN.js +130 -0
- package/web/dist/assets/index-IEIkG_jd.css +2 -0
- package/web/dist/index.html +13 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/cli/src/index.ts", "../../packages/cli/src/args.ts", "../../packages/cli/src/help.ts", "../../packages/cli/src/version.ts", "../../packages/cli/src/doctor.ts", "../../packages/cli/src/proc.ts", "../../packages/cli/src/net.ts", "../../packages/server/src/config/config.ts", "../../packages/server/src/config/paths.ts", "../../packages/cli/src/serverBridge.ts", "../../packages/cli/src/color.ts", "../../packages/cli/src/daemon.ts", "../../packages/cli/src/pid.ts", "../../packages/cli/src/backup.ts", "../../packages/cli/src/skill.ts", "../../packages/cli/src/updateCommand.ts", "../../packages/cli/src/update.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\nimport fs from 'node:fs';\nimport readline from 'node:readline/promises';\nimport path from 'node:path';\nimport { parseArgs, CliError, type Command } from './args.js';\nimport { GLOBAL_HELP, commandHelp } from './help.js';\nimport { getCliVersion } from './version.js';\nimport { runDoctor, type CheckResult, type CheckStatus } from './doctor.js';\nimport { runCommand } from './proc.js';\nimport { probePort, getHealth } from './net.js';\nimport { loadConfig } from '@antbot/server/config/config.js';\nimport { importServerDependency } from './serverBridge.js';\nimport { bold, dim, green, red, yellow } from './color.js';\nimport {\n cmdStartDetached,\n cmdStartForeground,\n cmdStop,\n cmdRestart,\n cmdStatus,\n cmdOpen,\n loadPaths,\n} from './daemon.js';\nimport { createBackup, restoreBackup } from './backup.js';\nimport { runSkillCommand } from './skill.js';\nimport { runUpdateCommand, printUpdateNotice } from './updateCommand.js';\n\nasync function runDoctorCommand(): Promise<number> {\n const paths = loadPaths();\n const port = 4780;\n\n const report = await runDoctor({\n nodeVersion: process.versions.node,\n env: process.env,\n homeDir: process.env.HOME ?? process.env.USERPROFILE ?? '',\n dataDir: paths.root,\n port,\n\n fileExists: (p) => fs.existsSync(p),\n fileSize: (p) => {\n try {\n return fs.statSync(p).size;\n } catch {\n return 0;\n }\n },\n isDirWritable: (dir) => {\n try {\n fs.mkdirSync(dir, { recursive: true });\n fs.accessSync(dir, fs.constants.W_OK);\n return true;\n } catch {\n return false;\n }\n },\n\n exec: (cmd, args) => runCommand(cmd, args),\n probePort: (p) => probePort(p),\n healthCheck: (p) => getHealth(p),\n\n importBetterSqlite3: () => importServerDependency('better-sqlite3'),\n importPlaywright: async () => {\n const mod = (await importServerDependency('playwright')) as {\n default?: { chromium: { executablePath: () => string } };\n chromium?: { executablePath: () => string };\n };\n const pw = mod.default ?? mod;\n if (!pw.chromium) throw new Error('playwright module has no chromium export');\n return { chromium: pw.chromium };\n },\n });\n\n renderDoctorTable(report.results);\n return report.exitCode;\n}\n\nfunction symbolFor(status: CheckStatus): string {\n if (status === 'pass') return green('\u2713');\n if (status === 'warn') return yellow('\u26A0');\n return red('\u2717');\n}\n\nfunction renderDoctorTable(results: CheckResult[]): void {\n const nameWidth = Math.max(...results.map((r) => r.name.length));\n for (const r of results) {\n console.log(`${symbolFor(r.status)} ${bold(r.name.padEnd(nameWidth))} ${r.message}`);\n if (r.hint && r.status !== 'pass') {\n console.log(` ${dim(`-> ${r.hint}`)}`);\n }\n }\n const failed = results.filter((r) => r.status === 'fail').length;\n const warned = results.filter((r) => r.status === 'warn').length;\n console.log('');\n if (failed > 0) {\n console.log(red(`${failed} check(s) failed, ${warned} warning(s).`));\n } else if (warned > 0) {\n console.log(yellow(`All checks passed with ${warned} warning(s).`));\n } else {\n console.log(green('All checks passed.'));\n }\n}\n\nasync function runBackupCommand(outFlag: string | undefined): Promise<number> {\n const paths = loadPaths();\n const outPath =\n outFlag ?? path.join(paths.backups, `antbot-backup-${new Date().toISOString().replace(/[:.]/g, '-')}.tar.gz`);\n try {\n const result = await createBackup({\n root: paths.root,\n dbPath: paths.db,\n configPath: paths.config,\n skillsDir: paths.skills,\n botsDir: path.join(paths.workspace, 'bots'),\n outPath,\n });\n const kb = (result.bytes / 1024).toFixed(1);\n console.log(green(`Backup written to ${result.outPath} (${kb} KB)`));\n return 0;\n } catch (err) {\n console.error(red((err as Error).message));\n return 1;\n }\n}\n\nasync function runRestoreCommand(archivePath: string | undefined, skipConfirm: boolean): Promise<number> {\n if (!archivePath) {\n console.error(red('Usage: antbot restore <path> [--yes]'));\n return 2;\n }\n const paths = loadPaths();\n\n if (!skipConfirm) {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(\n `This will overwrite files under ${paths.root} with the contents of ${archivePath}. Continue? [y/N] `,\n );\n rl.close();\n if (!/^y(es)?$/i.test(answer.trim())) {\n console.log('Aborted.');\n return 0;\n }\n }\n\n try {\n await restoreBackup({ archivePath, root: paths.root });\n console.log(green(`Restored ${archivePath} into ${paths.root}`));\n return 0;\n } catch (err) {\n console.error(red((err as Error).message));\n return 1;\n }\n}\n\nasync function main(): Promise<void> {\n let parsed;\n try {\n parsed = parseArgs(process.argv.slice(2));\n } catch (err) {\n if (err instanceof CliError) {\n console.error(red(err.message));\n process.exit(2);\n }\n throw err;\n }\n\n if (parsed.version) {\n console.log(getCliVersion());\n process.exit(0);\n }\n\n if (parsed.help || !parsed.command) {\n console.log(parsed.command ? commandHelp(parsed.command) : GLOBAL_HELP);\n process.exit(0);\n }\n\n const command: Command = parsed.command;\n\n switch (command) {\n case 'start': {\n const port = typeof parsed.flags.port === 'number' ? parsed.flags.port : undefined;\n const foreground = Boolean(parsed.flags.foreground);\n const openAfter = Boolean(parsed.flags.open);\n if (foreground) {\n const code = await cmdStartForeground(port, openAfter);\n if (code !== 0) process.exit(code);\n return; // keep the event loop alive; the server owns it now\n }\n process.exit(await cmdStartDetached(port, openAfter));\n return;\n }\n case 'stop':\n process.exit(await cmdStop());\n return;\n case 'restart':\n process.exit(await cmdRestart(typeof parsed.flags.port === 'number' ? parsed.flags.port : undefined));\n return;\n // The update notice is printed here rather than inside the commands themselves: it is the\n // only thing in the CLI that touches the network, and keeping it at the dispatch layer means\n // neither cmdStatus nor runDoctor grows a dependency on it.\n case 'status': {\n const code = await cmdStatus();\n await printUpdateNotice();\n process.exit(code);\n return;\n }\n case 'doctor': {\n const code = await runDoctorCommand();\n await printUpdateNotice();\n process.exit(code);\n return;\n }\n case 'open':\n process.exit(await cmdOpen());\n return;\n case 'skill': {\n const cfg = loadConfig();\n process.exit(await runSkillCommand(parsed.positionals, cfg.port));\n return;\n }\n case 'backup':\n process.exit(await runBackupCommand(typeof parsed.flags.out === 'string' ? parsed.flags.out : undefined));\n return;\n case 'restore':\n process.exit(await runRestoreCommand(parsed.positionals[0], Boolean(parsed.flags.yes)));\n return;\n case 'update':\n process.exit(\n await runUpdateCommand({ check: Boolean(parsed.flags.check), yes: Boolean(parsed.flags.yes) }),\n );\n return;\n default: {\n const _exhaustive: never = command;\n throw new Error(`Unhandled command: ${String(_exhaustive)}`);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(red(`antbot: ${(err as Error).stack ?? (err as Error).message}`));\n process.exit(1);\n});\n", "// Hand-rolled argument parser. No external CLI framework.\n\nexport const KNOWN_COMMANDS = [\n 'start',\n 'stop',\n 'restart',\n 'status',\n 'doctor',\n 'open',\n 'skill',\n 'backup',\n 'restore',\n 'update',\n] as const;\n\nexport type Command = (typeof KNOWN_COMMANDS)[number];\n\nexport class CliError extends Error {}\n\nexport type FlagType = 'string' | 'boolean' | 'number';\n\nexport interface FlagDef {\n type: FlagType;\n default?: string | number | boolean;\n}\n\nexport type FlagSpecs = Record<string, FlagDef>;\n\n/** Per-command flag definitions, including defaults. */\nexport const COMMAND_FLAGS: Record<Command, FlagSpecs> = {\n start: {\n port: { type: 'number' },\n foreground: { type: 'boolean', default: false },\n open: { type: 'boolean', default: false },\n },\n stop: {},\n restart: {\n port: { type: 'number' },\n },\n status: {},\n doctor: {},\n open: {},\n skill: {},\n backup: {\n out: { type: 'string' },\n },\n restore: {\n yes: { type: 'boolean', default: false },\n },\n update: {\n check: { type: 'boolean', default: false },\n yes: { type: 'boolean', default: false },\n },\n};\n\nexport interface ParsedArgs {\n command: Command | null;\n help: boolean;\n version: boolean;\n positionals: string[];\n flags: Record<string, string | number | boolean>;\n}\n\nfunction isKnownCommand(value: string): value is Command {\n return (KNOWN_COMMANDS as readonly string[]).includes(value);\n}\n\n/**\n * Parse process.argv-style arguments (excluding `node`/script path).\n * Throws CliError on unknown command / unknown flag / missing flag value.\n */\nexport function parseArgs(argv: string[]): ParsedArgs {\n if (argv.length === 0) {\n return { command: null, help: true, version: false, positionals: [], flags: {} };\n }\n\n const first = argv[0];\n\n if (first === '--version' || first === '-v') {\n return { command: null, help: false, version: true, positionals: [], flags: {} };\n }\n\n if (first === '--help' || first === '-h') {\n return { command: null, help: true, version: false, positionals: [], flags: {} };\n }\n\n if (first.startsWith('-')) {\n throw new CliError(`Unknown option: ${first}\\nRun \"antbot --help\" for usage.`);\n }\n\n if (!isKnownCommand(first)) {\n throw new CliError(`Unknown command: \"${first}\"\\nRun \"antbot --help\" for usage.`);\n }\n\n const command = first;\n const spec = COMMAND_FLAGS[command];\n const rest = argv.slice(1);\n\n const flags: Record<string, string | number | boolean> = {};\n for (const [name, def] of Object.entries(spec)) {\n if (def.default !== undefined) flags[name] = def.default;\n }\n\n const positionals: string[] = [];\n let help = false;\n\n for (let i = 0; i < rest.length; i++) {\n const tok = rest[i];\n\n if (tok === '--help' || tok === '-h') {\n help = true;\n continue;\n }\n\n if (tok.startsWith('--')) {\n let name = tok.slice(2);\n let inlineValue: string | undefined;\n const eq = name.indexOf('=');\n if (eq !== -1) {\n inlineValue = name.slice(eq + 1);\n name = name.slice(0, eq);\n }\n\n const def = spec[name];\n if (!def) {\n throw new CliError(`Unknown flag \"--${name}\" for command \"${command}\"`);\n }\n\n if (def.type === 'boolean') {\n flags[name] = inlineValue === undefined ? true : inlineValue !== 'false';\n continue;\n }\n\n const raw = inlineValue !== undefined ? inlineValue : rest[++i];\n if (raw === undefined) {\n throw new CliError(`Flag \"--${name}\" requires a value`);\n }\n if (def.type === 'number') {\n const num = Number(raw);\n if (Number.isNaN(num)) {\n throw new CliError(`Flag \"--${name}\" must be a number, got \"${raw}\"`);\n }\n flags[name] = num;\n } else {\n flags[name] = raw;\n }\n continue;\n }\n\n positionals.push(tok);\n }\n\n return { command, help, version: false, positionals, flags };\n}\n", "import type { Command } from './args.js';\n\nexport const GLOBAL_HELP = `antbot \u2014 a local daemon and web UI for a roster of persistent Claude teammates.\n\nUsage: antbot <command> [options]\n\nGetting started:\n antbot doctor Check your environment (Node, claude CLI + login, data dir, port)\n antbot open Open the web UI, starting the daemon if it isn't running\n\nDaemon:\n start [options] Start the daemon in the background\n stop Stop the daemon\n restart [--port N] Stop and start again\n status Show whether the daemon is running, and where\n open Open the web UI (starts the daemon first if needed)\n doctor Diagnose the local environment\n\nData:\n skill <subcommand> Manage the skills your bots can use\n backup [--out PATH] Archive the database, config, skills, and bot memory\n restore <path> Restore from a backup archive\n\nMaintenance:\n update [--check] Update ant-bot to the latest published version\n\nOptions:\n -h, --help Show help; \"antbot <command> --help\" for one command\n -v, --version Show the CLI version\n\nEnvironment:\n ANTBOT_HOME Data directory (default: ~/.ant-bot)\n\nThe UI lives at http://127.0.0.1:4780 and is served by the daemon itself.`;\n\nconst COMMAND_HELP: Record<Command, string> = {\n start: `antbot start \u2014 start the daemon in the background\n\nUsage: antbot start [--port N] [--open] [--foreground]\n\n --port N Port to listen on (default: from config, usually 4780)\n --open Open the web UI once the daemon is healthy\n --foreground Run in this terminal instead of detaching (Ctrl-C stops it)\n\nDetached output goes to the log in your data directory; \"antbot status\" tells\nyou where that is. Starting an already-running daemon is a no-op.`,\n\n stop: `antbot stop \u2014 stop the daemon\n\nUsage: antbot stop\n\nSends SIGTERM, then SIGKILL if it hasn't exited after 10 seconds. Stopping a\ndaemon that isn't running succeeds quietly.`,\n\n restart: `antbot restart \u2014 stop the daemon and start it again\n\nUsage: antbot restart [--port N]\n\n --port N Port to listen on when starting back up\n\nBots, threads, and memory survive a restart.`,\n\n status: `antbot status \u2014 show daemon status\n\nUsage: antbot status\n\nPrints the URL, version, data directory, and bot count. Exits non-zero when the\ndaemon is not running, so it works in scripts.`,\n\n doctor: `antbot doctor \u2014 diagnose the local environment\n\nUsage: antbot doctor\n\nChecks Node.js version, the claude CLI, Claude authentication, ANTHROPIC_API_KEY,\ndata directory permissions, port availability, better-sqlite3, and Playwright's\nChromium install. Each failure prints the command that fixes it.\n\nExits non-zero if any check fails.`,\n\n open: `antbot open \u2014 open the web UI\n\nUsage: antbot open\n\nPrints the URL and hands it to your browser. If the daemon isn't running yet,\nit is started first \u2014 so this is the only command you need day to day.`,\n\n skill: `antbot skill \u2014 manage the skills your bots can use\n\nUsage:\n antbot skill list\n antbot skill add <source>\n antbot skill remove <slug>\n antbot skill lint [path]\n\nA skill is a directory containing a SKILL.md. \\`add\\` accepts:\n\n owner/repo a GitHub repository\n github.com/owner/repo the same, written out\n github.com/owner/repo#v2 pinned to a branch or tag\n github.com/owner/repo/tree/main/x one skill inside a monorepo\n git@github.com:owner/repo.git any git URL\n ./path/to/skill a local directory\n https://host/path/SKILL.md a single skill file\n\nA repository holding several skills installs all of them. Re-installing an\nexisting skill upgrades it in place and keeps it assigned to its bots.\n\nSkills committed to the ant-bot project's own skills/ directory are installed\nautomatically on every start.\n\n\\`lint\\` checks skills against the Agent Skills spec (skills/SPEC.md) and needs\nno running daemon. With no path it checks everything installed; give it a path\nto check one skill you are still writing, or a directory of them:\n\n antbot skill lint every installed skill\n antbot skill lint ./skills a directory of skills\n antbot skill lint ./skills/my-skill one skill\n\nExit status is 1 if anything is an error, 0 if only warnings.`,\n\n backup: `antbot backup \u2014 create a backup archive\n\nUsage: antbot backup [--out PATH]\n\n --out PATH Output path for the tar.gz (default: ~/.ant-bot/backups/<timestamp>.tar.gz)\n\nIncludes antbot.db, config.toml, skills, and each bot's memory directory.\nExcludes browser-profile and attachments.`,\n\n update: `antbot update \u2014 update ant-bot to the latest published version\n\nUsage: antbot update [--check] [--yes]\n\n --check Report whether a newer version exists and exit; change nothing\n --yes Skip the confirmation prompt\n\nRuns the package manager that installed this copy, then restarts the daemon if\nit was running. The check is cached for a day, so it costs no network most of\nthe time. ant-bot never updates itself in the background: the daemon holds a\nlive database handle and may be mid-turn.\n\nIn a git checkout there is nothing for a package manager to update \u2014 use\n\\`git pull && pnpm install\\` instead.`,\n\n restore: `antbot restore \u2014 restore from a backup archive\n\nUsage: antbot restore <path> [--yes]\n\n --yes Skip the confirmation prompt\n\nOverwrites files in your data directory. Stop the daemon first.`,\n};\n\nexport function commandHelp(command: Command): string {\n return COMMAND_HELP[command];\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Walks up to the nearest package.json rather than assuming `../package.json`, because the\n * published build bundles this file to a different depth than tsc does. Kept independent of\n * @antbot/server's identical helper for the reason given in serverBridge.ts.\n */\nexport function readVersionFrom(\n here: string,\n exists: (p: string) => boolean,\n read: (p: string) => string,\n): string {\n let dir = path.resolve(here);\n for (;;) {\n const pkg = path.join(dir, 'package.json');\n if (exists(pkg)) {\n try {\n return (JSON.parse(read(pkg)) as { version?: string }).version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return '0.0.0';\n dir = parent;\n }\n}\n\nexport function getCliVersion(): string {\n return readVersionFrom(\n path.dirname(fileURLToPath(import.meta.url)),\n (p) => fs.existsSync(p),\n (p) => fs.readFileSync(p, 'utf8'),\n );\n}\n", "import path from 'node:path';\n\nexport type CheckStatus = 'pass' | 'warn' | 'fail';\n\nexport interface CheckResult {\n name: string;\n status: CheckStatus;\n message: string;\n hint?: string;\n}\n\nexport interface ExecResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface PortHealth {\n ok: boolean;\n version?: string;\n}\n\n/**\n * Everything a doctor check needs, injected so checks are pure/testable without\n * touching the real filesystem, network, or child processes.\n */\nexport interface DoctorDeps {\n nodeVersion: string;\n env: Record<string, string | undefined>;\n homeDir: string;\n dataDir: string;\n port: number;\n\n fileExists: (path: string) => boolean;\n fileSize: (path: string) => number;\n isDirWritable: (dir: string) => boolean;\n\n exec: (cmd: string, args: string[]) => Promise<ExecResult>;\n probePort: (port: number) => Promise<'free' | 'occupied'>;\n healthCheck: (port: number) => Promise<PortHealth>;\n\n importBetterSqlite3: () => Promise<unknown>;\n importPlaywright: () => Promise<{ chromium: { executablePath: () => string } }>;\n}\n\nfunction pass(name: string, message: string): CheckResult {\n return { name, status: 'pass', message };\n}\nfunction warn(name: string, message: string, hint: string): CheckResult {\n return { name, status: 'warn', message, hint };\n}\nfunction fail(name: string, message: string, hint: string): CheckResult {\n return { name, status: 'fail', message, hint };\n}\n\nexport function checkNodeVersion(deps: Pick<DoctorDeps, 'nodeVersion'>): CheckResult {\n const major = Number.parseInt(deps.nodeVersion.split('.')[0] ?? '0', 10);\n if (Number.isFinite(major) && major >= 24) {\n return pass('Node.js version', `v${deps.nodeVersion}`);\n }\n return fail(\n 'Node.js version',\n `v${deps.nodeVersion} (ant-bot requires >= 24)`,\n 'Install Node.js 24 or later, e.g. via nvm: `nvm install 24`.',\n );\n}\n\nexport async function checkClaudeCli(deps: Pick<DoctorDeps, 'exec'>): Promise<CheckResult> {\n try {\n const res = await deps.exec('claude', ['--version']);\n if (res.code === 0) {\n return pass('claude CLI', res.stdout.trim() || 'installed');\n }\n return fail(\n 'claude CLI',\n `\"claude --version\" exited with code ${res.code}`,\n 'Install with `npm i -g @anthropic-ai/claude-code`.',\n );\n } catch {\n return fail(\n 'claude CLI',\n 'not found on PATH',\n 'Install with `npm i -g @anthropic-ai/claude-code`.',\n );\n }\n}\n\nexport function checkClaudeAuth(\n deps: Pick<DoctorDeps, 'fileExists' | 'fileSize' | 'homeDir'>,\n): CheckResult {\n const credentialsPath = path.join(deps.homeDir, '.claude', '.credentials.json');\n const claudeJsonPath = path.join(deps.homeDir, '.claude.json');\n\n if (deps.fileExists(credentialsPath)) {\n return pass('Claude authentication', `Found ${credentialsPath}`);\n }\n if (deps.fileExists(claudeJsonPath) && deps.fileSize(claudeJsonPath) > 50) {\n return pass('Claude authentication', `Found ${claudeJsonPath}`);\n }\n return warn(\n 'Claude authentication',\n 'No Claude Code credentials found',\n 'Run `claude` once and log in.',\n );\n}\n\nexport function checkApiKeyEnv(deps: Pick<DoctorDeps, 'env'>): CheckResult {\n const value = deps.env.ANTHROPIC_API_KEY;\n if (!value) {\n return pass('ANTHROPIC_API_KEY', 'Not set (turns bill to your Claude subscription)');\n }\n return warn(\n 'ANTHROPIC_API_KEY',\n 'Set in environment',\n \"Set, but ant-bot strips it so turns bill to your subscription. Set billingMode='api' in settings if you want API billing instead.\",\n );\n}\n\nexport function checkDataDirWritable(deps: Pick<DoctorDeps, 'isDirWritable' | 'dataDir'>): CheckResult {\n if (deps.isDirWritable(deps.dataDir)) {\n return pass('Data directory', `${deps.dataDir} is writable`);\n }\n return fail(\n 'Data directory',\n `${deps.dataDir} is not writable`,\n `Check permissions on ${deps.dataDir}.`,\n );\n}\n\nexport async function checkPortAvailability(\n deps: Pick<DoctorDeps, 'probePort' | 'healthCheck' | 'port'>,\n): Promise<CheckResult> {\n const state = await deps.probePort(deps.port);\n if (state === 'free') {\n return pass('Port', `Port ${deps.port} is free`);\n }\n const health = await deps.healthCheck(deps.port);\n if (health.ok) {\n return pass(\n 'Port',\n `Port ${deps.port} is in use by a running antbot daemon${health.version ? ` (v${health.version})` : ''}`,\n );\n }\n return fail(\n 'Port',\n `Port ${deps.port} is in use by another process`,\n `Stop the other process or run \\`antbot start --port <N>\\`.`,\n );\n}\n\nexport async function checkBetterSqlite3(\n deps: Pick<DoctorDeps, 'importBetterSqlite3'>,\n): Promise<CheckResult> {\n try {\n await deps.importBetterSqlite3();\n return pass('better-sqlite3', 'native module loads');\n } catch (err) {\n return fail(\n 'better-sqlite3',\n `failed to load (${(err as Error).message})`,\n 'Run `pnpm rebuild better-sqlite3`.',\n );\n }\n}\n\nexport async function checkPlaywrightChromium(\n deps: Pick<DoctorDeps, 'importPlaywright' | 'fileExists'>,\n): Promise<CheckResult> {\n try {\n const pw = await deps.importPlaywright();\n const execPath = pw.chromium.executablePath();\n if (deps.fileExists(execPath)) {\n return pass('Playwright Chromium', execPath);\n }\n return warn(\n 'Playwright Chromium',\n `Expected browser binary at ${execPath}`,\n 'Run `npx playwright install chromium`.',\n );\n } catch (err) {\n return warn(\n 'Playwright Chromium',\n `Could not verify Chromium install (${(err as Error).message})`,\n 'Run `npx playwright install chromium`.',\n );\n }\n}\n\nexport interface DoctorReport {\n results: CheckResult[];\n exitCode: 0 | 1;\n}\n\nexport async function runDoctor(deps: DoctorDeps): Promise<DoctorReport> {\n const results: CheckResult[] = [\n checkNodeVersion(deps),\n await checkClaudeCli(deps),\n checkClaudeAuth(deps),\n checkApiKeyEnv(deps),\n checkDataDirWritable(deps),\n await checkPortAvailability(deps),\n await checkBetterSqlite3(deps),\n await checkPlaywrightChromium(deps),\n ];\n const exitCode = results.some((r) => r.status === 'fail') ? 1 : 0;\n return { results, exitCode };\n}\n", "import { spawn } from 'node:child_process';\n\nexport interface RunResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\n/** Runs a command without a shell, capturing stdout/stderr. */\nexport function runCommand(cmd: string, args: string[], opts: { cwd?: string } = {}): Promise<RunResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { cwd: opts.cwd });\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n child.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n child.on('error', reject);\n child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));\n });\n}\n", "import net from 'node:net';\n\nexport interface HealthResult {\n ok: boolean;\n version?: string;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** TCP-connect probe: does anything answer on this port right now? */\nexport function probePort(port: number, host = '127.0.0.1'): Promise<'free' | 'occupied'> {\n return new Promise((resolve) => {\n const socket = net.connect({ port, host });\n let settled = false;\n const done = (state: 'free' | 'occupied') => {\n if (settled) return;\n settled = true;\n socket.destroy();\n resolve(state);\n };\n socket.setTimeout(1000);\n socket.once('connect', () => done('occupied'));\n socket.once('timeout', () => done('free'));\n socket.once('error', () => done('free'));\n });\n}\n\nexport async function getHealth(port: number): Promise<HealthResult> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/health`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return { ok: false };\n const body = (await res.json().catch(() => null)) as { version?: string } | null;\n return { ok: true, version: typeof body?.version === 'string' ? body.version : undefined };\n } catch {\n return { ok: false };\n }\n}\n\nexport async function getBotCount(port: number): Promise<number | null> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/bots`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) return null;\n const body: unknown = await res.json().catch(() => null);\n if (Array.isArray(body)) return body.length;\n if (body && typeof body === 'object' && Array.isArray((body as { bots?: unknown[] }).bots)) {\n return (body as { bots: unknown[] }).bots.length;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function waitForHealth(port: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n do {\n const health = await getHealth(port);\n if (health.ok) return true;\n await sleep(300);\n } while (Date.now() < deadline);\n return false;\n}\n\n/* --------------------------- generic JSON helpers --------------------------- */\n\nconst BASE = (port: number): string => `http://127.0.0.1:${port}`;\n\nasync function unwrap<T>(res: Response): Promise<T> {\n if (!res.ok) {\n const body = (await res.json().catch(() => null)) as { error?: string } | null;\n throw new Error(body?.error ?? `HTTP ${res.status}`);\n }\n return (await res.json()) as T;\n}\n\nexport async function getJson<T>(port: number, path: string): Promise<T> {\n return unwrap<T>(await fetch(`${BASE(port)}${path}`, { signal: AbortSignal.timeout(10_000) }));\n}\n\nexport async function postJson<T>(port: number, path: string, body: unknown): Promise<T> {\n return unwrap<T>(\n await fetch(`${BASE(port)}${path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n // Cloning a repository can take a while on a slow link.\n signal: AbortSignal.timeout(180_000),\n }),\n );\n}\n\nexport async function deleteJson<T>(port: number, path: string): Promise<T> {\n return unwrap<T>(\n await fetch(`${BASE(port)}${path}`, { method: 'DELETE', signal: AbortSignal.timeout(10_000) }),\n );\n}\n", "import fs from 'node:fs';\nimport { parse as parseToml, stringify as stringifyToml } from 'smol-toml';\nimport { SettingsSchema, type Settings } from '@antbot/shared';\nimport { resolvePaths, ensureDirs, type AntbotPaths } from './paths.js';\n\nexport interface AntbotConfig {\n paths: AntbotPaths;\n settings: Settings;\n port: number;\n host: string;\n}\n\nexport const DEFAULT_PORT = 4780;\nexport const DEFAULT_HOST = '127.0.0.1';\n\nexport function loadConfig(root?: string): AntbotConfig {\n const paths = resolvePaths(root);\n ensureDirs(paths);\n\n let raw: Record<string, unknown> = {};\n if (fs.existsSync(paths.config)) {\n try {\n raw = parseToml(fs.readFileSync(paths.config, 'utf8')) as Record<string, unknown>;\n } catch {\n raw = {};\n }\n }\n const server = (raw.server ?? {}) as Record<string, unknown>;\n const settings = SettingsSchema.parse({\n ...(typeof raw.settings === 'object' && raw.settings ? raw.settings : {}),\n timezone:\n (raw.settings as Record<string, unknown> | undefined)?.timezone ??\n Intl.DateTimeFormat().resolvedOptions().timeZone ??\n 'UTC',\n });\n\n const cfg: AntbotConfig = {\n paths,\n settings,\n port: Number(process.env.ANTBOT_PORT ?? server.port ?? DEFAULT_PORT),\n host: String(server.host ?? DEFAULT_HOST),\n };\n if (!fs.existsSync(paths.config)) writeConfig(cfg);\n return cfg;\n}\n\nexport function writeConfig(cfg: AntbotConfig): void {\n fs.writeFileSync(\n cfg.paths.config,\n stringifyToml({ server: { port: cfg.port, host: cfg.host }, settings: cfg.settings as unknown as Record<string, unknown> }),\n );\n}\n", "import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\nexport interface AntbotPaths {\n root: string;\n db: string;\n config: string;\n workspace: string;\n attachments: string;\n skills: string;\n browserProfile: string;\n backups: string;\n secrets: string;\n logs: string;\n}\n\nexport function resolvePaths(root?: string): AntbotPaths {\n const base = root ?? process.env.ANTBOT_HOME ?? path.join(os.homedir(), '.ant-bot');\n return {\n root: base,\n db: path.join(base, 'antbot.db'),\n config: path.join(base, 'config.toml'),\n workspace: path.join(base, 'workspace'),\n attachments: path.join(base, 'attachments'),\n skills: path.join(base, 'skills'),\n browserProfile: path.join(base, 'browser-profile'),\n backups: path.join(base, 'backups'),\n secrets: path.join(base, 'secrets.json'),\n logs: path.join(base, 'logs'),\n };\n}\n\nexport function ensureDirs(p: AntbotPaths): void {\n for (const d of [p.root, p.workspace, p.attachments, p.skills, p.backups, p.logs,\n path.join(p.workspace, 'projects'), path.join(p.workspace, 'bots')]) {\n fs.mkdirSync(d, { recursive: true });\n }\n}\n", "// Everything that talks to @antbot/server lives here so it can be imported\n// lazily and fail gracefully: the server package's exports (in particular\n// startServer) may not exist yet in-progress, and native deps like\n// better-sqlite3/playwright are @antbot/server's dependencies, not @antbot/cli's.\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nexport interface ResolveDeps {\n /** Directory of the calling module. */\n here: string;\n /** Resolves a bare specifier; throws when it is not installed, like require.resolve. */\n resolve: (specifier: string) => string;\n realpath: (p: string) => string;\n exists: (p: string) => boolean;\n}\n\n/**\n * Nearest ancestor of `from` holding a package.json. Deliberately a local copy of the server's\n * `util/locate.ts` helper rather than an import: this module exists so that nothing here touches\n * @antbot/server eagerly, and locating that package cannot itself depend on loading it.\n */\nfunction packageRootOf(from: string, exists: (p: string) => boolean): string | null {\n let dir = path.resolve(from);\n for (;;) {\n if (exists(path.join(dir, 'package.json'))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Where @antbot/server's dependencies can be resolved from. Three layouts, in order:\n *\n * 1. A real resolve of the package \u2014 correct under npm, pnpm and yarn regardless of how the\n * installer chose to hoist, which the old hardcoded `cli/node_modules/@antbot/server` symlink\n * was not (npm hoists to the root and never creates it).\n * 2. That symlink anyway, for a pnpm workspace where step 1 can miss.\n * 3. This package itself. In the published single-package build there is no separate\n * @antbot/server: the CLI and the daemon are one package, and better-sqlite3/playwright are\n * its own dependencies.\n */\nexport function resolveServerPackageDir(deps: ResolveDeps): string | null {\n try {\n return deps.realpath(path.dirname(deps.resolve('@antbot/server/package.json')));\n } catch { /* not a separate package here; try the other layouts */ }\n\n const pkg = packageRootOf(deps.here, deps.exists);\n if (pkg) {\n const link = path.join(pkg, 'node_modules', '@antbot', 'server');\n if (deps.exists(link)) {\n try {\n return deps.realpath(link);\n } catch { /* dangling symlink */ }\n }\n return pkg;\n }\n return null;\n}\n\nconst require_ = createRequire(import.meta.url);\n\nfunction findServerPackageDir(): string | null {\n return resolveServerPackageDir({\n here: path.dirname(fileURLToPath(import.meta.url)),\n resolve: (s) => require_.resolve(s),\n realpath: (p) => fs.realpathSync(p),\n exists: (p) => fs.existsSync(p),\n });\n}\n\n/**\n * Resolves and imports a module from @antbot/server's own dependency tree\n * (e.g. \"better-sqlite3\", \"playwright\") so doctor checks reflect what the\n * daemon will actually load, without @antbot/cli declaring those as its own\n * dependencies.\n */\nexport async function importServerDependency(specifier: string): Promise<unknown> {\n const serverDir = findServerPackageDir();\n if (!serverDir) {\n throw new Error(`could not locate the @antbot/server package to resolve \"${specifier}\"`);\n }\n const req = createRequire(path.join(serverDir, 'package.json'));\n const resolved = req.resolve(specifier);\n return import(pathToFileURL(resolved).href);\n}\n\nexport interface StartServerOptions {\n port: number;\n host: string;\n}\n\nexport interface ServerInstance {\n close?: () => Promise<void> | void;\n}\n\n/**\n * Lazily imports @antbot/server and calls its startServer() export, if present.\n *\n * NOTE: the specifier is held in a variable (not a string literal) on purpose.\n * @antbot/server does not export startServer() yet (it's being built\n * concurrently, and its package.json \"exports\" main entry may not resolve to\n * a build artifact at all times), so a literal `import('@antbot/server')`\n * would make this file's typecheck depend on that package's build state.\n * Routing through a variable makes TS treat the result as `Promise<any>`.\n */\n/**\n * Where a server module can be imported from, most portable first.\n *\n * The published build has no separate @antbot/server \u2014 the CLI and the daemon are bundled into\n * one package, side by side under `dist/`. `bareSpecifier` is what resolves in a checkout or a\n * multi-package install; `bundledFile` is the sibling that resolves in the published one.\n */\nexport function serverModuleCandidates(\n bareSpecifier: string,\n bundledFile: string,\n deps: Pick<ResolveDeps, 'here' | 'exists'>,\n): string[] {\n const out = [bareSpecifier];\n const pkg = packageRootOf(deps.here, deps.exists);\n if (pkg) {\n const sibling = path.join(pkg, 'dist', bundledFile);\n if (deps.exists(sibling)) out.push(pathToFileURL(sibling).href);\n }\n return out;\n}\n\nfunction candidates(bare: string, bundled: string): string[] {\n return serverModuleCandidates(bare, bundled, {\n here: path.dirname(fileURLToPath(import.meta.url)),\n exists: (p) => fs.existsSync(p),\n });\n}\n\n/** Tries each candidate in turn, reporting the first real failure rather than the last miss. */\nasync function importFirst(specs: string[], what: string): Promise<unknown> {\n let firstError: unknown;\n for (const spec of specs) {\n try {\n return await import(spec);\n } catch (err) {\n firstError ??= err;\n }\n }\n throw new Error(`could not load ${what}: ${(firstError as Error)?.message ?? 'not found'}`);\n}\n\n/**\n * Lazily imports the daemon and calls its startServer() export, if present.\n *\n * NOTE: the specifiers are held in variables (not string literals) on purpose.\n * @antbot/server's package.json \"exports\" main entry may not resolve to a build artifact at all\n * times, so a literal `import('@antbot/server')` would make this file's typecheck depend on that\n * package's build state. Routing through a variable makes TS treat the result as `Promise<any>`.\n */\nexport async function startAntbotServer(opts: StartServerOptions): Promise<ServerInstance> {\n const mod = (await importFirst(candidates('@antbot/server', 'server.js'), 'the ant-bot daemon')) as {\n startServer?: (opts: StartServerOptions) => Promise<ServerInstance> | ServerInstance;\n };\n if (typeof mod.startServer !== 'function') {\n throw new Error('@antbot/server does not export startServer() yet.');\n }\n return mod.startServer(opts);\n}\n\nexport interface SpecViolation {\n code: string;\n level: 'error' | 'warning';\n field?: string;\n message: string;\n}\n\nexport interface SkillSpecModule {\n validateSkillDir: (dir: string) => SpecViolation[];\n validateSkillsIn: (root: string) => { slug: string; violations: SpecViolation[] }[];\n}\n\n/**\n * Lazily imports the spec validator. Held in a variable for the same reason as\n * startAntbotServer above, and kept a *separate* entry point from the daemon on purpose:\n * `antbot skill lint` runs with no daemon, and must not drag better-sqlite3, fastify and\n * playwright into the process just to parse frontmatter.\n */\nexport async function importSkillSpec(): Promise<SkillSpecModule> {\n return (await importFirst(\n candidates('@antbot/server/skills/spec.js', 'skills-spec.js'),\n 'the skill spec validator',\n )) as SkillSpecModule;\n}\n", "const noColor = Boolean(process.env.NO_COLOR) || !process.stdout.isTTY;\n\nfunction wrap(code: string): (s: string) => string {\n return (s: string) => (noColor ? s : `\\x1b[${code}m${s}\\x1b[0m`);\n}\n\nexport const bold = wrap('1');\nexport const dim = wrap('2');\nexport const red = wrap('31');\nexport const green = wrap('32');\nexport const yellow = wrap('33');\nexport const cyan = wrap('36');\n", "import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { resolvePaths, ensureDirs, type AntbotPaths } from '@antbot/server/config/paths.js';\nimport { loadConfig, DEFAULT_PORT } from '@antbot/server/config/config.js';\nimport { pidFilePath, readPidFile, writePidFile, removePidFile, isProcessAlive } from './pid.js';\nimport { getHealth, getBotCount, waitForHealth } from './net.js';\nimport { startAntbotServer } from './serverBridge.js';\nimport { green, red, yellow, dim } from './color.js';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function loadPaths(): AntbotPaths {\n const paths = resolvePaths();\n ensureDirs(paths);\n return paths;\n}\n\n/** `antbot start --foreground`: runs the daemon in this process. */\nexport async function cmdStartForeground(port?: number, openAfter = false): Promise<number> {\n const cfg = loadConfig();\n const resolvedPort = port ?? cfg.port;\n try {\n const instance = await startAntbotServer({ port: resolvedPort, host: cfg.host });\n console.log(green(`antbot listening on http://${cfg.host}:${resolvedPort}`));\n if (openAfter) openInBrowser(`http://127.0.0.1:${resolvedPort}`);\n\n let shuttingDown = false;\n const shutdown = async (signal: string) => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.log(dim(`Received ${signal}, shutting down...`));\n try {\n await instance.close?.();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n process.on('SIGINT', () => void shutdown('SIGINT'));\n return 0;\n } catch (err) {\n console.error(red(`Failed to start antbot: ${(err as Error).message}`));\n return 1;\n }\n}\n\n/** `antbot start`: spawns a detached foreground instance and waits for health. */\nexport async function cmdStartDetached(port?: number, openAfter = false): Promise<number> {\n const cfg = loadConfig();\n const paths = loadPaths();\n const resolvedPort = port ?? cfg.port ?? DEFAULT_PORT;\n\n const pidPath = pidFilePath(paths.root);\n const existing = readPidFile(pidPath);\n if (existing && isProcessAlive(existing.pid)) {\n console.log(`antbot is already running at http://127.0.0.1:${existing.port} (pid ${existing.pid}).`);\n if (openAfter) openInBrowser(`http://127.0.0.1:${existing.port}`);\n return 0;\n }\n if (existing) removePidFile(pidPath);\n\n const logPath = path.join(paths.logs, 'antbot.log');\n fs.mkdirSync(paths.logs, { recursive: true });\n const logFd = fs.openSync(logPath, 'a');\n\n const selfEntry = process.argv[1];\n if (!selfEntry) {\n console.error(red('Could not determine the antbot entry point to spawn.'));\n return 1;\n }\n\n const child = spawn(\n process.execPath,\n [selfEntry, 'start', '--foreground', '--port', String(resolvedPort)],\n { detached: true, stdio: ['ignore', logFd, logFd] },\n );\n child.unref();\n\n if (!child.pid) {\n console.error(red('Failed to spawn the antbot daemon.'));\n return 1;\n }\n writePidFile(pidPath, { pid: child.pid, port: resolvedPort, startedAt: Date.now() });\n\n console.log(`Starting antbot (pid ${child.pid}) on port ${resolvedPort}...`);\n const ok = await waitForHealth(resolvedPort, 30000);\n if (!ok) {\n console.error(red(`Timed out waiting for antbot to become healthy. Check ${logPath}`));\n return 1;\n }\n console.log(green(`antbot is running at http://127.0.0.1:${resolvedPort}`));\n if (openAfter) openInBrowser(`http://127.0.0.1:${resolvedPort}`);\n return 0;\n}\n\nexport async function cmdStop(): Promise<number> {\n const paths = loadPaths();\n const pidPath = pidFilePath(paths.root);\n const data = readPidFile(pidPath);\n\n if (!data || !isProcessAlive(data.pid)) {\n console.log('antbot is not running.');\n if (data) removePidFile(pidPath);\n return 0;\n }\n\n console.log(`Stopping antbot (pid ${data.pid})...`);\n try {\n process.kill(data.pid, 'SIGTERM');\n } catch {\n /* already gone */\n }\n\n const deadline = Date.now() + 10000;\n while (Date.now() < deadline && isProcessAlive(data.pid)) {\n await sleep(200);\n }\n\n if (isProcessAlive(data.pid)) {\n console.log(yellow('Process did not exit in time, sending SIGKILL.'));\n try {\n process.kill(data.pid, 'SIGKILL');\n } catch {\n /* already gone */\n }\n }\n\n removePidFile(pidPath);\n console.log(green('antbot stopped.'));\n return 0;\n}\n\nexport async function cmdStatus(): Promise<number> {\n const paths = loadPaths();\n const pidPath = pidFilePath(paths.root);\n const data = readPidFile(pidPath);\n const alive = !!data && isProcessAlive(data.pid);\n\n // A daemon started outside the CLI (e.g. `node dist/main.js`, or a dev runner)\n // writes no pidfile, so fall back to probing the configured port before\n // declaring it down \u2014 otherwise `status` contradicts `doctor`.\n if (!alive || !data) {\n const cfgPort = loadConfig().port ?? DEFAULT_PORT;\n const probe = await getHealth(cfgPort);\n if (!probe.ok) {\n console.log(red('antbot is not running.'));\n return 1;\n }\n const count = await getBotCount(cfgPort);\n console.log(green('antbot is running (started outside the CLI \u2014 no pidfile)'));\n console.log(` URL: http://127.0.0.1:${cfgPort}`);\n console.log(` Version: ${probe.version ?? 'unknown'}`);\n console.log(` Data dir: ${paths.root}`);\n console.log(` Bots: ${count ?? 'unknown'}`);\n console.log(yellow(' Note: `antbot stop` cannot stop it; stop it where it was started.'));\n return 0;\n }\n\n const health = await getHealth(data.port);\n const botCount = health.ok ? await getBotCount(data.port) : null;\n\n console.log(green(`antbot is running (pid ${data.pid})`));\n console.log(` URL: http://127.0.0.1:${data.port}`);\n console.log(` Version: ${health.version ?? 'unknown'}`);\n console.log(` Data dir: ${paths.root}`);\n console.log(` Bots: ${botCount ?? 'unknown'}`);\n if (!health.ok) {\n console.log(yellow(' Warning: process is alive but /api/health is not responding.'));\n }\n return health.ok ? 0 : 1;\n}\n\n/** Hand a URL to the platform's default browser. Never fails the command. */\nexport function openInBrowser(url: string): void {\n console.log(url);\n const opener =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n try {\n const child = spawn(opener, [url], {\n stdio: 'ignore',\n detached: true,\n shell: process.platform === 'win32',\n });\n child.on('error', () => {\n console.log(dim(`Could not launch a browser automatically. Open ${url} manually.`));\n });\n child.unref();\n } catch {\n console.log(dim(`Could not launch a browser automatically. Open ${url} manually.`));\n }\n}\n\n/** `antbot restart`: stop if running, then start detached again. */\nexport async function cmdRestart(port?: number): Promise<number> {\n const stopCode = await cmdStop();\n if (stopCode !== 0) return stopCode;\n return cmdStartDetached(port);\n}\n\n/**\n * `antbot open`: open the UI, starting the daemon first if it is not up yet, so\n * one command gets you from a cold checkout to a working UI.\n */\nexport async function cmdOpen(): Promise<number> {\n const paths = loadPaths();\n const cfg = loadConfig();\n const pidPath = pidFilePath(paths.root);\n const data = readPidFile(pidPath);\n const port = data?.port ?? cfg.port ?? DEFAULT_PORT;\n\n const health = await getHealth(port);\n if (!health.ok) {\n console.log(dim('antbot is not running \u2014 starting it first...'));\n const code = await cmdStartDetached(port);\n if (code !== 0) return code;\n }\n\n openInBrowser(`http://127.0.0.1:${port}`);\n return 0;\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface PidFileData {\n pid: number;\n port: number;\n startedAt: number;\n}\n\nexport function pidFilePath(dataDir: string): string {\n return path.join(dataDir, 'antbot.pid');\n}\n\nexport function readPidFile(file: string): PidFileData | null {\n try {\n const raw = fs.readFileSync(file, 'utf8');\n const data = JSON.parse(raw) as Partial<PidFileData>;\n if (typeof data.pid === 'number' && typeof data.port === 'number') {\n return { pid: data.pid, port: data.port, startedAt: data.startedAt ?? 0 };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function writePidFile(file: string, data: PidFileData): void {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, JSON.stringify(data, null, 2));\n}\n\nexport function removePidFile(file: string): void {\n try {\n fs.unlinkSync(file);\n } catch {\n /* already gone */\n }\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { runCommand } from './proc.js';\n\n/** Path segments that must never end up in a backup archive. */\nexport const BACKUP_EXCLUDED_DIRS = ['browser-profile', 'attachments'];\n\nexport interface BackupSource {\n dbPath: string;\n configPath: string;\n skillsDir: string;\n /** ~/.ant-bot/workspace/bots */\n botsDir: string;\n /** directory names found under botsDir, e.g. ['scout', 'writer'] */\n botSlugs: string[];\n}\n\nexport interface BackupItem {\n /** absolute path on disk */\n source: string;\n /** path inside the archive, forward-slash separated */\n archivePath: string;\n}\n\n/**\n * Pure: computes exactly which paths belong in a backup archive, given an\n * already-enumerated list of bot slugs. Never includes browser-profile or\n * attachments.\n */\nexport function computeBackupItems(input: BackupSource): BackupItem[] {\n const items: BackupItem[] = [\n { source: input.dbPath, archivePath: 'antbot.db' },\n { source: input.configPath, archivePath: 'config.toml' },\n { source: input.skillsDir, archivePath: 'skills' },\n ];\n for (const slug of input.botSlugs) {\n items.push({\n source: path.join(input.botsDir, slug, 'memory'),\n archivePath: `workspace/bots/${slug}/memory`,\n });\n }\n return items;\n}\n\n/** Pure: true if a (forward-slash) relative archive path is in an excluded directory. */\nexport function isExcludedPath(relPath: string): boolean {\n const segments = relPath.replace(/\\\\/g, '/').split('/');\n return segments.some((seg) => BACKUP_EXCLUDED_DIRS.includes(seg));\n}\n\nexport interface CreateBackupOptions {\n root: string;\n dbPath: string;\n configPath: string;\n skillsDir: string;\n botsDir: string;\n outPath: string;\n}\n\nexport interface CreateBackupResult {\n outPath: string;\n bytes: number;\n items: BackupItem[];\n}\n\nfunction listBotSlugs(botsDir: string): string[] {\n try {\n return fs\n .readdirSync(botsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n } catch {\n return [];\n }\n}\n\n/** I/O: shells out to `tar czf` to build the archive. */\nexport async function createBackup(opts: CreateBackupOptions): Promise<CreateBackupResult> {\n const botSlugs = listBotSlugs(opts.botsDir);\n const allItems = computeBackupItems({\n dbPath: opts.dbPath,\n configPath: opts.configPath,\n skillsDir: opts.skillsDir,\n botsDir: opts.botsDir,\n botSlugs,\n });\n const items = allItems.filter((item) => fs.existsSync(item.source));\n if (items.length === 0) {\n throw new Error('Nothing to back up: no antbot.db, config.toml, skills, or bot memory found.');\n }\n\n fs.mkdirSync(path.dirname(opts.outPath), { recursive: true });\n\n const relPaths = items.map((item) => path.relative(opts.root, item.source));\n const args = ['czf', opts.outPath, '-C', opts.root, ...relPaths];\n\n let res;\n try {\n res = await runCommand('tar', args);\n } catch (err) {\n throw new Error(\n `Could not run \"tar\": ${(err as Error).message}. Is tar installed and on PATH?`,\n { cause: err },\n );\n }\n if (res.code !== 0) {\n throw new Error(`tar exited with code ${res.code}: ${res.stderr.trim()}`);\n }\n\n const { size } = fs.statSync(opts.outPath);\n return { outPath: opts.outPath, bytes: size, items };\n}\n\nexport interface RestoreBackupOptions {\n archivePath: string;\n root: string;\n}\n\n/** I/O: shells out to `tar xzf` to extract the archive into root. */\nexport async function restoreBackup(opts: RestoreBackupOptions): Promise<void> {\n if (!fs.existsSync(opts.archivePath)) {\n throw new Error(`Backup file not found: ${opts.archivePath}`);\n }\n fs.mkdirSync(opts.root, { recursive: true });\n\n let res;\n try {\n res = await runCommand('tar', ['xzf', opts.archivePath, '-C', opts.root]);\n } catch (err) {\n throw new Error(\n `Could not run \"tar\": ${(err as Error).message}. Is tar installed and on PATH?`,\n { cause: err },\n );\n }\n if (res.code !== 0) {\n throw new Error(`tar exited with code ${res.code}: ${res.stderr.trim()}`);\n }\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { getJson, postJson, deleteJson } from './net.js';\nimport { bold, dim, green, red, yellow } from './color.js';\nimport { importSkillSpec, type SpecViolation } from './serverBridge.js';\nimport { loadPaths } from './daemon.js';\n\ninterface SkillRow {\n id: string;\n slug: string;\n name: string;\n description: string;\n source: string;\n}\n\ninterface InstallResponse {\n installed: Array<{ skill: SkillRow; executables: string[]; manifest: string; replaced: boolean }>;\n}\n\nconst USAGE = `Usage:\n antbot skill list\n antbot skill add <source>\n antbot skill remove <slug>\n antbot skill lint [path]`;\n\nexport async function runSkillCommand(argv: string[], port: number): Promise<number> {\n const [sub, ...rest] = argv;\n\n if (!sub || sub === 'list') return listSkills(port);\n if (sub === 'add') return addSkill(rest, port);\n if (sub === 'remove' || sub === 'rm') return removeSkill(rest, port);\n if (sub === 'lint' || sub === 'check') return lintSkills(rest);\n\n console.error(red(`Unknown subcommand \"${sub}\".\\n${USAGE}`));\n return 2;\n}\n\nfunction notRunning(err: unknown): number {\n console.error(red(`Could not reach the antbot daemon: ${(err as Error).message}`));\n console.error(dim('Start it with `antbot start`.'));\n return 1;\n}\n\nasync function listSkills(port: number): Promise<number> {\n let skills: SkillRow[];\n try {\n skills = await getJson<SkillRow[]>(port, '/api/skills');\n } catch (err) {\n return notRunning(err);\n }\n if (!skills.length) {\n console.log('No skills installed. Add one with `antbot skill add <source>`.');\n return 0;\n }\n const width = Math.max(...skills.map((s) => s.slug.length));\n for (const s of skills) {\n console.log(`${bold(s.slug.padEnd(width))} ${s.description || s.name}`);\n }\n console.log('');\n console.log(dim(`${skills.length} skill(s). Assign them to a bot in Bot settings \u2192 Skills.`));\n return 0;\n}\n\nasync function addSkill(args: string[], port: number): Promise<number> {\n const source = args[0];\n if (!source) {\n console.error(red(`A source is required.\\n${USAGE}`));\n return 2;\n }\n let res: InstallResponse;\n try {\n res = await postJson<InstallResponse>(port, '/api/skills/install', { source });\n } catch (err) {\n const message = (err as Error).message;\n if (/ECONNREFUSED|not reach/i.test(message)) return notRunning(err);\n console.error(red(message));\n return 1;\n }\n\n for (const item of res.installed) {\n console.log(item.manifest.replace(/^\u2713 Installed/, green('\u2713 Installed')));\n if (item.replaced) console.log(dim(' (upgraded in place; existing bot assignments kept)'));\n console.log('');\n }\n const names = res.installed.map((i) => i.skill.slug).join(', ');\n console.log(dim(`Assign to a bot in Bot settings \u2192 Skills: ${names}`));\n return 0;\n}\n\nasync function removeSkill(args: string[], port: number): Promise<number> {\n const slug = args[0];\n if (!slug) {\n console.error(red(`A slug is required.\\n${USAGE}`));\n return 2;\n }\n let skills: SkillRow[];\n try {\n skills = await getJson<SkillRow[]>(port, '/api/skills');\n } catch (err) {\n return notRunning(err);\n }\n const match = skills.find((s) => s.slug === slug || s.name === slug);\n if (!match) {\n console.error(red(`No skill named \"${slug}\".`));\n console.error(dim(`Installed: ${skills.map((s) => s.slug).join(', ') || '(none)'}`));\n return 1;\n }\n try {\n await deleteJson(port, `/api/skills/${match.id}`);\n } catch (err) {\n return notRunning(err);\n }\n console.log(green(`\u2713 Removed '${match.slug}'`));\n console.log(dim(yellow('Bots that had it assigned no longer have it.')));\n return 0;\n}\n\n/**\n * `antbot skill lint [path]` \u2014 check skills against the Agent Skills spec (skills/SPEC.md).\n *\n * Deliberately does not go through the daemon: the most useful moment to run this is on a\n * skill directory you are still writing, before anything is installed anywhere.\n */\nasync function lintSkills(args: string[]): Promise<number> {\n const target = args[0];\n let spec: Awaited<ReturnType<typeof importSkillSpec>>;\n try {\n spec = await importSkillSpec();\n } catch (err) {\n console.error(red(`Could not load the skill validator: ${(err as Error).message}`));\n return 1;\n }\n\n let results: { slug: string; violations: SpecViolation[] }[];\n let scanned: string;\n\n if (target) {\n const dir = path.resolve(target);\n if (!fs.existsSync(dir)) {\n console.error(red(`No such directory: ${dir}`));\n return 2;\n }\n scanned = dir;\n // A path can be one skill or a directory of them; treating a SKILL.md as the signal\n // means `antbot skill lint .` works from inside a skill you are writing.\n results = fs.existsSync(path.join(dir, 'SKILL.md'))\n ? [{ slug: path.basename(dir), violations: spec.validateSkillDir(dir) }]\n : spec.validateSkillsIn(dir);\n } else {\n scanned = path.join(loadPaths().skills, 'skills');\n results = spec.validateSkillsIn(scanned);\n }\n\n if (results.length === 0) {\n console.log(`No skills found in ${scanned}.`);\n return 0;\n }\n\n let errors = 0;\n let warnings = 0;\n const width = Math.max(...results.map((r) => r.slug.length));\n for (const { slug, violations } of results) {\n if (violations.length === 0) {\n console.log(`${green('\u2713')} ${bold(slug.padEnd(width))} ${dim('conforms to the spec')}`);\n continue;\n }\n const worst = violations.some((v) => v.level === 'error') ? red('\u2717') : yellow('\u26A0');\n console.log(`${worst} ${bold(slug.padEnd(width))}`);\n for (const v of violations) {\n if (v.level === 'error') errors++;\n else warnings++;\n const tag = v.level === 'error' ? red('error') : yellow('warn ');\n console.log(` ${tag} ${dim(v.code)} ${v.message}`);\n }\n }\n\n console.log('');\n if (errors > 0) {\n console.log(red(`${errors} error(s), ${warnings} warning(s) across ${results.length} skill(s).`));\n console.log(dim('See skills/SPEC.md, or the skill-author skill, for how to fix each one.'));\n return 1;\n }\n if (warnings > 0) {\n console.log(yellow(`${warnings} warning(s) across ${results.length} skill(s).`));\n return 0;\n }\n console.log(green(`All ${results.length} skill(s) conform to the spec.`));\n return 0;\n}\n", "// The `antbot update` command and the cached notice that `status` and `doctor` print.\n// The decisions all live in update.ts; this file is the filesystem, network and process edge.\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport readline from 'node:readline/promises';\nimport { fileURLToPath } from 'node:url';\nimport { getCliVersion } from './version.js';\nimport { runCommand } from './proc.js';\nimport { loadPaths } from './daemon.js';\nimport { bold, dim, green, red, yellow } from './color.js';\nimport {\n checkForUpdate,\n detectPackageManager,\n fetchLatestVersion,\n isCheckoutInstall,\n updateCommand,\n type UpdateStatus,\n} from './update.js';\n\nconst CACHE_FILE = 'update-check.json';\n\nfunction cachePath(): string {\n return path.join(loadPaths().root, CACHE_FILE);\n}\n\nfunction installPath(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\n/**\n * The once-a-day check, wired to the real filesystem and registry. Silent on every failure \u2014\n * a command must not fail because a registry did not answer.\n */\nexport async function currentUpdateStatus(): Promise<UpdateStatus> {\n const file = cachePath();\n return checkForUpdate({\n currentVersion: getCliVersion(),\n now: Date.now(),\n readCache: () => {\n try {\n return fs.readFileSync(file, 'utf8');\n } catch {\n return null;\n }\n },\n writeCache: (contents) => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, contents, 'utf8');\n } catch {\n /* a read-only data dir is not worth a warning here */\n }\n },\n fetchLatest: () => fetchLatestVersion(),\n });\n}\n\n/**\n * Prints the update line for `status` and `doctor`, if there is one. A checkout is skipped:\n * telling a contributor to run `antbot update` on their own working tree is noise.\n */\nexport async function printUpdateNotice(): Promise<void> {\n if (isCheckoutInstall(installPath(), (p) => fs.existsSync(p))) return;\n const status = await currentUpdateStatus();\n if (status.notice) console.log(yellow(` ${status.notice}`));\n}\n\nexport async function runUpdateCommand(opts: { check: boolean; yes: boolean }): Promise<number> {\n const here = installPath();\n const current = getCliVersion();\n\n if (isCheckoutInstall(here, (p) => fs.existsSync(p))) {\n console.error(red('This is a git checkout, not a package-manager install.'));\n console.error(dim('Update it with: git pull && pnpm install'));\n return 2;\n }\n\n const status = await currentUpdateStatus();\n if (status.latest === null) {\n console.error(red('Could not reach the npm registry to check for updates.'));\n return 1;\n }\n if (!status.isUpgrade) {\n console.log(green(`ant-bot ${current} is up to date.`) + (status.cached ? dim(' (cached)') : ''));\n return 0;\n }\n\n console.log(bold(`ant-bot ${current} \u2192 ${status.latest}`));\n if (opts.check) return 0;\n\n const pm = detectPackageManager(here);\n const { cmd, args } = updateCommand(pm);\n\n if (!opts.yes) {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await rl.question(`Run \\`${cmd} ${args.join(' ')}\\`? [y/N] `);\n rl.close();\n if (!/^y(es)?$/i.test(answer.trim())) {\n console.log('Aborted.');\n return 0;\n }\n }\n\n console.log(dim(`$ ${cmd} ${args.join(' ')}`));\n const result = await runCommand(cmd, args);\n if (result.code !== 0) {\n console.error(red(`${cmd} exited with code ${result.code}`));\n if (result.stderr) console.error(dim(result.stderr.trim()));\n return 1;\n }\n\n // The freshly-installed copy has a different version; the cached answer is now wrong.\n try {\n fs.rmSync(cachePath(), { force: true });\n } catch {\n /* ignore */\n }\n\n console.log(green(`Updated to ${status.latest}.`));\n console.log(dim('Restart a running daemon to pick it up: antbot restart'));\n return 0;\n}\n", "// Update checking and self-update.\n//\n// The check is a notification, never an action. The daemon holds a live SQLite handle and may be\n// mid-turn spending subscription tokens; replacing its files underneath that is a bad trade for a\n// local-first tool. So: `antbot status` and `antbot doctor` mention a newer version, and the user\n// runs `antbot update` when it suits them.\n//\n// Pure core (`compareVersions`, `planUpdateCheck`, `detectPackageManager`, `updateCommand`)\n// decides; the I/O wrapper fetches, caches and spawns.\nimport path from 'node:path';\n\n// Scoped, because npm rejects `ant-bot` as too similar to the pre-existing `antbot` holding\n// package. The *binary* is still `antbot`; only the install/update command carries the scope.\nexport const PACKAGE_NAME = '@michael-joseph-miller/ant-bot';\n// encodeURIComponent so the scope separator reaches the registry as %2F.\nexport const REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;\n\n/** Once a day. A local-first tool has no business talking to a registry more often than that. */\nexport const UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport interface UpdateCache {\n latest: string;\n checkedAt: number;\n}\n\n/* ------------------------------- pure core ------------------------------- */\n\ninterface Parsed {\n parts: number[];\n prerelease: string | null;\n}\n\nfunction parse(version: string): Parsed | null {\n const m = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?/.exec(version.trim());\n if (!m) return null;\n return { parts: [Number(m[1]), Number(m[2]), Number(m[3])], prerelease: m[4] ?? null };\n}\n\n/**\n * Compares two semver strings: negative if `a` is older, positive if newer, 0 if equal.\n * Unparseable versions sort as equal, so a garbled registry answer never triggers a prompt.\n */\nexport function compareVersions(a: string, b: string): number {\n const pa = parse(a);\n const pb = parse(b);\n if (!pa || !pb) return 0;\n for (let i = 0; i < 3; i++) {\n if (pa.parts[i]! !== pb.parts[i]!) return pa.parts[i]! - pb.parts[i]!;\n }\n // 1.0.0-beta precedes 1.0.0. Beyond that, comparing prerelease identifiers by string is\n // close enough for \"is there something newer\" and avoids reimplementing semver.\n if (pa.prerelease === pb.prerelease) return 0;\n if (pa.prerelease === null) return 1;\n if (pb.prerelease === null) return -1;\n return pa.prerelease < pb.prerelease ? -1 : 1;\n}\n\n/**\n * Whether `latest` is worth telling the user about. A stable install is never nudged onto a\n * prerelease, however the registry's `latest` tag happens to be pointed \u2014 that is a choice the\n * user makes deliberately with `npm i -g @michael-joseph-miller/ant-bot@next`.\n */\nexport function isUpgrade(current: string, latest: string): boolean {\n const c = parse(current);\n const l = parse(latest);\n if (!c || !l) return false;\n if (l.prerelease !== null && c.prerelease === null) return false;\n return compareVersions(latest, current) > 0;\n}\n\n/** Whether the cached answer is still good, so a check costs no network at all. */\nexport function planUpdateCheck(\n cache: UpdateCache | null,\n now: number,\n ttlMs = UPDATE_CHECK_TTL_MS,\n): 'use-cache' | 'fetch' {\n if (!cache || typeof cache.checkedAt !== 'number' || typeof cache.latest !== 'string') return 'fetch';\n // A clock that moved backwards (timezone fix, VM restore) would otherwise pin the cache\n // as fresh until the clock caught up.\n if (cache.checkedAt > now) return 'fetch';\n return now - cache.checkedAt < ttlMs ? 'use-cache' : 'fetch';\n}\n\n/**\n * Which package manager installed this copy, inferred from where it lives. Each keeps its global\n * root in a recognisable place, and re-running the *wrong* one either fails or installs a second\n * copy that shadows the first.\n */\nexport function detectPackageManager(installPath: string): PackageManager {\n const p = installPath.split(path.sep).join('/');\n if (/\\/\\.bun\\//.test(p)) return 'bun';\n // pnpm's global store, and its content-addressed layout wherever it lives.\n if (/\\/\\.pnpm\\//.test(p) || /\\/pnpm\\/(global|store)\\//.test(p) || /\\/Library\\/pnpm\\//.test(p)) return 'pnpm';\n if (/\\/\\.yarn\\//.test(p) || /\\/yarn\\/global\\//.test(p) || /\\/\\.config\\/yarn\\//.test(p)) return 'yarn';\n return 'npm';\n}\n\n/** The command that upgrades a global install for each package manager. */\nexport function updateCommand(pm: PackageManager, pkg = PACKAGE_NAME): { cmd: string; args: string[] } {\n switch (pm) {\n case 'pnpm':\n return { cmd: 'pnpm', args: ['add', '-g', `${pkg}@latest`] };\n case 'yarn':\n return { cmd: 'yarn', args: ['global', 'add', `${pkg}@latest`] };\n case 'bun':\n return { cmd: 'bun', args: ['add', '-g', `${pkg}@latest`] };\n case 'npm':\n default:\n return { cmd: 'npm', args: ['install', '-g', `${pkg}@latest`] };\n }\n}\n\n/**\n * A checkout is not upgradable by a package manager. Recognising it is what keeps\n * `antbot update` from running `npm i -g` over someone's working tree.\n *\n * Two signals, both required, because each alone is wrong somewhere: a path outside\n * `node_modules` also describes an unpacked tarball, and a `.git` directory also sits above a\n * global install when someone's home directory is a dotfiles repo. Requiring both errs toward\n * \"installed\" \u2014 the cost of that mistake is a redundant global install, where the opposite\n * mistake tells a real user their working install cannot be updated.\n */\nexport function isCheckoutInstall(installPath: string, exists: (p: string) => boolean): boolean {\n if (installPath.split(path.sep).includes('node_modules')) return false;\n let dir = path.resolve(installPath);\n for (;;) {\n if (exists(path.join(dir, '.git'))) return true;\n const parent = path.dirname(dir);\n if (parent === dir) return false;\n dir = parent;\n }\n}\n\n/** One line for `antbot status` / `antbot doctor`, or null when there is nothing to say. */\nexport function updateNotice(current: string, latest: string | null): string | null {\n if (!latest || !isUpgrade(current, latest)) return null;\n return `A newer ant-bot is available: ${current} \u2192 ${latest}. Run \\`antbot update\\`.`;\n}\n\n/* ------------------------------- I/O wrapper ------------------------------- */\n\nexport interface UpdateCheckDeps {\n currentVersion: string;\n now: number;\n readCache: () => string | null;\n writeCache: (contents: string) => void;\n fetchLatest: () => Promise<string | null>;\n ttlMs?: number;\n}\n\nexport interface UpdateStatus {\n current: string;\n latest: string | null;\n isUpgrade: boolean;\n /** True when the answer came from cache and no request was made. */\n cached: boolean;\n notice: string | null;\n}\n\n/**\n * Never throws and never blocks a command from succeeding: an offline machine, a proxy, or a\n * registry outage must not make `antbot status` fail.\n */\nexport async function checkForUpdate(deps: UpdateCheckDeps): Promise<UpdateStatus> {\n let cache: UpdateCache | null = null;\n try {\n const raw = deps.readCache();\n if (raw) cache = JSON.parse(raw) as UpdateCache;\n } catch {\n /* an unreadable or corrupt cache is the same as no cache */\n }\n\n let latest: string | null;\n let cached = false;\n if (planUpdateCheck(cache, deps.now, deps.ttlMs) === 'use-cache') {\n latest = cache!.latest;\n cached = true;\n } else {\n try {\n latest = await deps.fetchLatest();\n if (latest) {\n deps.writeCache(`${JSON.stringify({ latest, checkedAt: deps.now } satisfies UpdateCache)}\\n`);\n }\n } catch {\n // Fall back to whatever was cached, however stale \u2014 a stale answer beats none.\n latest = cache?.latest ?? null;\n cached = latest !== null;\n }\n }\n\n return {\n current: deps.currentVersion,\n latest,\n isUpgrade: latest !== null && isUpgrade(deps.currentVersion, latest),\n cached,\n notice: updateNotice(deps.currentVersion, latest),\n };\n}\n\n/** Fetches the registry's `latest` dist-tag, with a short timeout. */\nexport async function fetchLatestVersion(timeoutMs = 3000): Promise<string | null> {\n const ac = new AbortController();\n const timer = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(REGISTRY_URL, {\n signal: ac.signal,\n headers: { accept: 'application/vnd.npm.install-v1+json' },\n });\n if (!res.ok) return null;\n const body = (await res.json()) as { version?: string };\n return typeof body.version === 'string' ? body.version : null;\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fs", "readline", "path", "path", "path", "fs", "path", "fs", "fs", "fs", "path", "fileURLToPath", "spawn", "fs", "path", "fs", "path", "sleep", "path", "fs", "spawn", "fs", "path", "path", "fs", "path", "fs", "path", "path", "fs", "fs", "path", "fileURLToPath", "path", "installPath", "path", "fileURLToPath", "fs", "fs", "path", "readline"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createRequire as __antbotCreateRequire } from 'node:module';
|
|
2
|
+
const require = __antbotCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
MAX_SKILL_BYTES,
|
|
5
|
+
classifyFiles,
|
|
6
|
+
copyTree,
|
|
7
|
+
describeSkillSource,
|
|
8
|
+
findSkillDirs,
|
|
9
|
+
isExecutableFile,
|
|
10
|
+
parseSkillSource,
|
|
11
|
+
renderManifest,
|
|
12
|
+
runGit,
|
|
13
|
+
stage,
|
|
14
|
+
stageFromGit,
|
|
15
|
+
stageFromPath,
|
|
16
|
+
stageFromUrl,
|
|
17
|
+
walkFiles
|
|
18
|
+
} from "./chunk-7BOHBPB2.js";
|
|
19
|
+
import "./chunk-KSQOVWP5.js";
|
|
20
|
+
export {
|
|
21
|
+
MAX_SKILL_BYTES,
|
|
22
|
+
classifyFiles,
|
|
23
|
+
copyTree,
|
|
24
|
+
describeSkillSource,
|
|
25
|
+
findSkillDirs,
|
|
26
|
+
isExecutableFile,
|
|
27
|
+
parseSkillSource,
|
|
28
|
+
renderManifest,
|
|
29
|
+
runGit,
|
|
30
|
+
stage,
|
|
31
|
+
stageFromGit,
|
|
32
|
+
stageFromPath,
|
|
33
|
+
stageFromUrl,
|
|
34
|
+
walkFiles
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=install-IY2M3OUQ.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createRequire as __antbotCreateRequire } from 'node:module';
|
|
2
|
+
const require = __antbotCreateRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// packages/server/src/skills/plugin.ts
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
var PLUGIN_NAME = "antbot";
|
|
8
|
+
function skillFilesDir(pluginRoot) {
|
|
9
|
+
return path.join(pluginRoot, "skills");
|
|
10
|
+
}
|
|
11
|
+
function ensureSkillPlugin(pluginRoot) {
|
|
12
|
+
const manifestDir = path.join(pluginRoot, ".claude-plugin");
|
|
13
|
+
fs.mkdirSync(manifestDir, { recursive: true });
|
|
14
|
+
fs.mkdirSync(skillFilesDir(pluginRoot), { recursive: true });
|
|
15
|
+
fs.writeFileSync(
|
|
16
|
+
path.join(manifestDir, "plugin.json"),
|
|
17
|
+
`${JSON.stringify(
|
|
18
|
+
{
|
|
19
|
+
name: PLUGIN_NAME,
|
|
20
|
+
description: "Skills installed into ant-bot and available to its bots.",
|
|
21
|
+
version: "1.0.0"
|
|
22
|
+
},
|
|
23
|
+
null,
|
|
24
|
+
2
|
|
25
|
+
)}
|
|
26
|
+
`
|
|
27
|
+
);
|
|
28
|
+
return pluginRoot;
|
|
29
|
+
}
|
|
30
|
+
function migrateLegacyLayout(pluginRoot) {
|
|
31
|
+
if (!fs.existsSync(pluginRoot)) return [];
|
|
32
|
+
const dest = skillFilesDir(pluginRoot);
|
|
33
|
+
const moved = [];
|
|
34
|
+
for (const entry of fs.readdirSync(pluginRoot, { withFileTypes: true })) {
|
|
35
|
+
if (!entry.isDirectory()) continue;
|
|
36
|
+
if (entry.name === "skills" || entry.name === ".claude-plugin") continue;
|
|
37
|
+
const from = path.join(pluginRoot, entry.name);
|
|
38
|
+
if (!fs.existsSync(path.join(from, "SKILL.md"))) continue;
|
|
39
|
+
const to = path.join(dest, entry.name);
|
|
40
|
+
if (fs.existsSync(to)) continue;
|
|
41
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
42
|
+
fs.renameSync(from, to);
|
|
43
|
+
moved.push(entry.name);
|
|
44
|
+
}
|
|
45
|
+
return moved;
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
PLUGIN_NAME,
|
|
49
|
+
ensureSkillPlugin,
|
|
50
|
+
migrateLegacyLayout,
|
|
51
|
+
skillFilesDir
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=plugin-POMHVGD4.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/server/src/skills/plugin.ts"],
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * The skills directory is exposed to the agent SDK as a **local plugin**, which is what\n * gives bots the real `Skill` tool (discovery, progressive disclosure, per-session\n * filtering) instead of a list of paths they have to read by hand.\n *\n * A local plugin is a directory containing `.claude-plugin/plugin.json` and a `skills/`\n * subdirectory, so the layout is:\n *\n * <root>/.claude-plugin/plugin.json generated, refreshed each boot\n * <root>/skills/<slug>/SKILL.md the skills themselves\n */\n\nexport const PLUGIN_NAME = 'antbot';\n\n/** Where individual skill directories live inside the plugin root. */\nexport function skillFilesDir(pluginRoot: string): string {\n return path.join(pluginRoot, 'skills');\n}\n\nexport function ensureSkillPlugin(pluginRoot: string): string {\n const manifestDir = path.join(pluginRoot, '.claude-plugin');\n fs.mkdirSync(manifestDir, { recursive: true });\n fs.mkdirSync(skillFilesDir(pluginRoot), { recursive: true });\n fs.writeFileSync(\n path.join(manifestDir, 'plugin.json'),\n `${JSON.stringify(\n {\n name: PLUGIN_NAME,\n description: 'Skills installed into ant-bot and available to its bots.',\n version: '1.0.0',\n },\n null,\n 2,\n )}\\n`,\n );\n return pluginRoot;\n}\n\n/**\n * Pre-plugin installs kept skills at `<root>/<slug>/SKILL.md`. Move them under\n * `<root>/skills/` so the plugin loader can see them. Idempotent; never overwrites a\n * skill already present at the destination.\n */\nexport function migrateLegacyLayout(pluginRoot: string): string[] {\n if (!fs.existsSync(pluginRoot)) return [];\n const dest = skillFilesDir(pluginRoot);\n const moved: string[] = [];\n\n for (const entry of fs.readdirSync(pluginRoot, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n if (entry.name === 'skills' || entry.name === '.claude-plugin') continue;\n const from = path.join(pluginRoot, entry.name);\n if (!fs.existsSync(path.join(from, 'SKILL.md'))) continue;\n\n const to = path.join(dest, entry.name);\n if (fs.existsSync(to)) continue; // destination wins; leave the stale copy in place\n fs.mkdirSync(dest, { recursive: true });\n fs.renameSync(from, to);\n moved.push(entry.name);\n }\n return moved;\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAcV,IAAM,cAAc;AAGpB,SAAS,cAAc,YAA4B;AACxD,SAAO,KAAK,KAAK,YAAY,QAAQ;AACvC;AAEO,SAAS,kBAAkB,YAA4B;AAC5D,QAAM,cAAc,KAAK,KAAK,YAAY,gBAAgB;AAC1D,KAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC7C,KAAG,UAAU,cAAc,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3D,KAAG;AAAA,IACD,KAAK,KAAK,aAAa,aAAa;AAAA,IACpC,GAAG,KAAK;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA,EACH;AACA,SAAO;AACT;AAOO,SAAS,oBAAoB,YAA8B;AAChE,MAAI,CAAC,GAAG,WAAW,UAAU,EAAG,QAAO,CAAC;AACxC,QAAM,OAAO,cAAc,UAAU;AACrC,QAAM,QAAkB,CAAC;AAEzB,aAAW,SAAS,GAAG,YAAY,YAAY,EAAE,eAAe,KAAK,CAAC,GAAG;AACvE,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,QAAI,MAAM,SAAS,YAAY,MAAM,SAAS,iBAAkB;AAChE,UAAM,OAAO,KAAK,KAAK,YAAY,MAAM,IAAI;AAC7C,QAAI,CAAC,GAAG,WAAW,KAAK,KAAK,MAAM,UAAU,CAAC,EAAG;AAEjD,UAAM,KAAK,KAAK,KAAK,MAAM,MAAM,IAAI;AACrC,QAAI,GAAG,WAAW,EAAE,EAAG;AACvB,OAAG,UAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACtC,OAAG,WAAW,MAAM,EAAE;AACtB,UAAM,KAAK,MAAM,IAAI;AAAA,EACvB;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|