@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/server/src/api/server.ts", "../../packages/server/src/app.ts", "../../packages/server/src/db/db.ts", "../../packages/server/src/db/migrations.ts", "../../packages/server/src/db/schema.ts", "../../packages/server/src/db/store.ts", "../../packages/server/src/util/bus.ts", "../../packages/server/src/permissions/rules.ts", "../../packages/server/src/permissions/local.ts", "../../packages/server/src/permissions/gateway.ts", "../../packages/server/src/permissions/autoreview.ts", "../../packages/server/src/agent/session.ts", "../../packages/server/src/bots/manager.ts", "../../packages/server/src/memory/memory.ts", "../../packages/server/src/bots/prompt.ts", "../../packages/server/src/config/config.ts", "../../packages/server/src/config/paths.ts", "../../packages/server/src/permissions/secrets.ts", "../../packages/server/src/bots/groups.ts", "../../packages/server/src/api/routes-core.ts", "../../packages/server/src/api/routes-ops.ts"],
|
|
4
|
+
"sourcesContent": ["import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createRequire } from 'node:module';\nimport Fastify, { type FastifyInstance } from 'fastify';\nimport cors from '@fastify/cors';\nimport multipart from '@fastify/multipart';\nimport websocket from '@fastify/websocket';\nimport fastifyStatic from '@fastify/static';\nimport { createApp, drainMailbox, type App } from '../app.js';\nimport { registerCoreRoutes } from './routes-core.js';\nimport { registerOpsRoutes } from './routes-ops.js';\nimport { logger } from '../util/log.js';\nimport { LIMITS } from '@antbot/shared';\nimport { findWebDist, nodeLocateDeps } from '../util/locate.js';\n\nconst log = logger('server');\n\nexport interface StartOptions {\n root?: string;\n port?: number;\n host?: string;\n withAgent?: boolean;\n serveStatic?: boolean;\n}\n\nexport interface RunningServer {\n fastify: FastifyInstance;\n app: App;\n url: string;\n close: () => Promise<void>;\n}\n\nconst require_ = createRequire(import.meta.url);\n\nfunction resolveWebDist(): string | null {\n return findWebDist(\n nodeLocateDeps(path.dirname(fileURLToPath(import.meta.url)), (spec) => {\n try {\n return require_.resolve(spec);\n } catch {\n return null;\n }\n }),\n );\n}\n\nexport async function startServer(opts: StartOptions = {}): Promise<RunningServer> {\n const app = await createApp({ root: opts.root, withAgent: opts.withAgent });\n const fastify = Fastify({ logger: false, bodyLimit: LIMITS.MAX_VIDEO_ATTACHMENT_BYTES });\n\n // Several endpoints are pure commands with no payload (stop, duplicate, read,\n // test-run). Fastify rejects a zero-length body when the client still sends\n // `content-type: application/json` \u2014 and it does so before any content-type\n // parser runs \u2014 so drop the header for genuinely empty requests.\n fastify.addHook('onRequest', (req, _reply, done) => {\n const len = req.headers['content-length'];\n const ct = req.headers['content-type'];\n if ((len === '0' || len === undefined) && ct?.includes('application/json')) {\n delete req.headers['content-type'];\n }\n done();\n });\n\n await fastify.register(cors, { origin: true });\n await fastify.register(multipart, {\n limits: { fileSize: LIMITS.MAX_VIDEO_ATTACHMENT_BYTES, files: LIMITS.MAX_ATTACHMENTS_PER_MESSAGE },\n });\n await fastify.register(websocket);\n\n registerCoreRoutes(fastify, app);\n registerOpsRoutes(fastify, app);\n\n /* ------------------------- event websocket ------------------------- */\n fastify.register(async (scope) => {\n scope.get('/api/events', { websocket: true }, (socket) => {\n const send = (payload: unknown): void => {\n try {\n if (socket.readyState === 1) socket.send(JSON.stringify(payload));\n } catch { /* client vanished */ }\n };\n const unsubscribe = app.bus.subscribe(send);\n // Handshake only \u2014 carries the current seq so the client can detect gaps.\n // Deliberately not a `notify`: connection state is UI chrome, not a user alert.\n send({ type: 'hello', seq: app.bus.currentSeq, threadId: null, botId: null });\n\n socket.on('message', (raw: Buffer) => {\n try {\n const msg = JSON.parse(raw.toString()) as { type?: string; seq?: number };\n if (msg.type === 'resume' && typeof msg.seq === 'number')\n for (const e of app.bus.since(msg.seq)) send(e);\n } catch { /* ignore malformed client frames */ }\n });\n socket.on('close', unsubscribe);\n socket.on('error', unsubscribe);\n });\n\n /* --------------------------- screencast -------------------------- */\n scope.get<{ Params: { botId: string } }>('/api/computer/screencast/:botId', { websocket: true }, async (socket, req) => {\n const botId = req.params.botId;\n if (!app.browser?.startScreencast) {\n try { socket.send(JSON.stringify({ type: 'error', message: 'Browser service unavailable' })); } catch { /* ignore */ }\n socket.close();\n return;\n }\n let stop: (() => void) | undefined;\n try {\n stop = await app.browser.startScreencast(botId, (data: string, w: number, h: number) => {\n try {\n if (socket.readyState === 1) socket.send(JSON.stringify({ type: 'frame', data, w, h }));\n } catch { /* ignore */ }\n });\n } catch (err) {\n try { socket.send(JSON.stringify({ type: 'error', message: (err as Error).message })); } catch { /* ignore */ }\n socket.close();\n return;\n }\n socket.on('close', () => stop?.());\n socket.on('error', () => stop?.());\n });\n });\n\n /* ---------------------------- static UI ---------------------------- */\n if (opts.serveStatic !== false) {\n const dist = resolveWebDist();\n if (dist) {\n await fastify.register(fastifyStatic, { root: dist, prefix: '/' });\n fastify.setNotFoundHandler((req, reply) => {\n if (req.url.startsWith('/api')) return reply.code(404).send({ error: 'Not found' });\n return reply.sendFile('index.html');\n });\n log.info(`serving UI from ${dist}`);\n } else {\n log.warn('web UI not built \u2014 run `pnpm --filter @antbot/web build`');\n fastify.setNotFoundHandler((req, reply) => {\n if (req.url.startsWith('/api')) return reply.code(404).send({ error: 'Not found' });\n return reply.type('text/html').send(\n `<!doctype html><meta charset=utf-8><title>ant-bot</title>\n <body style=\"font-family:system-ui;background:#0b0d10;color:#e6e8eb;padding:3rem\">\n <h1>ant-bot daemon is running</h1>\n <p>The web UI has not been built yet. Run:</p>\n <pre style=\"background:#151922;padding:1rem;border-radius:8px\">pnpm --filter @antbot/web build</pre>\n <p>The API is live at <code>/api/health</code>.</p>`,\n );\n });\n }\n }\n\n fastify.setErrorHandler((err: unknown, _req, reply) => {\n log.error('request failed', err);\n const e = err as { statusCode?: number; message?: string };\n const code = e.statusCode && e.statusCode >= 400 ? e.statusCode : 500;\n reply.code(code).send({ error: e.message ?? 'Internal error' });\n });\n\n const port = opts.port ?? app.cfg.port;\n const host = opts.host ?? app.cfg.host;\n await fastify.listen({ port, host });\n const url = `http://${host}:${port}`;\n\n const delivered = drainMailbox(app);\n if (delivered) log.info(`redelivered ${delivered} queued handoff message(s)`);\n\n // Mark any turn that was mid-flight when the daemon died as interrupted.\n const stale = app.store.listBots().filter((b) => b.state === 'running' || b.state === 'queued');\n for (const b of stale) app.store.updateBot(b.id, { state: 'idle' });\n app.db.prepare(`UPDATE messages SET streaming=0 WHERE streaming=1`).run();\n app.db.prepare(`UPDATE approvals SET status='expired', reason='Daemon restarted' WHERE status='pending'`).run();\n app.db.prepare(`UPDATE routine_runs SET status='interrupted', finished_at=? WHERE status='running'`).run(Date.now());\n\n log.info(`ant-bot listening on ${url}`);\n\n return {\n fastify,\n app,\n url,\n close: async () => {\n await fastify.close();\n await app.shutdown();\n },\n };\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport { openDb, type DB } from './db/db.js';\nimport { Store } from './db/store.js';\nimport { EventBus } from './util/bus.js';\nimport { PermissionGateway } from './permissions/gateway.js';\nimport { seedBuiltinRules } from './permissions/rules.js';\nimport { makeAutoReviewer, NullAutoReviewer } from './permissions/autoreview.js';\nimport { BotManager } from './bots/manager.js';\nimport { loadConfig, type AntbotConfig } from './config/config.js';\nimport { logger } from './util/log.js';\nimport type { Settings } from '@antbot/shared';\nimport { SecretsService, pickBackend } from './permissions/secrets.js';\n\nconst log = logger('app');\n\n/**\n * Load a subsystem that may not work on this machine \u2014 no Playwright installed, no fts5 \u2014 so the\n * daemon still boots without it.\n *\n * `load` must be a thunk around a *literal* dynamic import. This used to take a specifier string\n * and assemble it at runtime (`import(\\`${spec}\\`)`) so the compiler would not require the module\n * to exist; every one of them exists now, and the runtime-assembled form is invisible to a\n * bundler \u2014 the published build resolved them relative to the bundle, found nothing, and booted\n * with skills, browser and scheduler all silently missing.\n */\nasync function optionalImport(name: string, load: () => Promise<unknown>): Promise<any | null> {\n try {\n return await load();\n } catch (err) {\n log.warn(`${name} module could not be loaded`, (err as Error).message);\n return null;\n }\n}\n\nexport interface App {\n cfg: AntbotConfig;\n db: DB;\n store: Store;\n bus: EventBus;\n gateway: PermissionGateway;\n manager: BotManager;\n getSettings: () => Settings;\n /** Optional subsystems, wired if their modules are present. */\n scheduler?: any;\n browser?: any;\n skills?: any;\n secrets?: SecretsService;\n lastUserActivity: { at: number };\n /** Root of the local plugin carrying installed skills. */\n skillPluginPath?: string;\n shutdown: () => Promise<void>;\n}\n\nexport async function createApp(opts: { root?: string; withAgent?: boolean } = {}): Promise<App> {\n const cfg = loadConfig(opts.root);\n const db = openDb(cfg.paths.db, { backupsDir: cfg.paths.backups });\n const store = new Store(db);\n\n // config.toml holds first-run defaults; the DB is authoritative afterwards.\n const persisted = store.getSettings();\n const settingsCount = store.db.prepare(`SELECT COUNT(*) c FROM settings`).get() as { c: number };\n if (!settingsCount.c) {\n store.patchSettings(cfg.settings);\n }\n const getSettings = (): Settings => store.getSettings();\n void persisted;\n\n seedBuiltinRules(store);\n\n const bus = new EventBus();\n const reviewer = opts.withAgent === false\n ? new NullAutoReviewer()\n : makeAutoReviewer(getSettings, cfg.paths.workspace);\n const gateway = new PermissionGateway(store, bus, reviewer);\n\n const app: App = {\n cfg, db, store, bus, gateway, getSettings,\n manager: undefined as unknown as BotManager,\n lastUserActivity: { at: Date.now() },\n shutdown: async () => {},\n };\n\n app.manager = new BotManager({\n store, bus, gateway,\n workspace: cfg.paths.workspace,\n getSettings,\n skillPluginPath: () => app.skillPluginPath,\n installSkill: async (source: string, opts?: { allowMultiple?: boolean }) => {\n if (!app.skills?.installFromSource) throw new Error('Skill installation is unavailable.');\n const installed = await app.skills.installFromSource(source, opts ?? {});\n return installed.map((i: { skill: { name: string }; executables: string[] }) => ({\n name: i.skill.name,\n executables: i.executables,\n }));\n },\n listSkills: () =>\n store.listSkills().map((sk) => ({ slug: sk.slug, name: sk.name, description: sk.description })),\n // Routed through SkillStore so the directory and the registration go together \u2014 a bot\n // deleting directories with Bash is what leaves the registry pointing at nothing.\n removeSkill: async (slug: string) => {\n if (!app.skills?.deleteSkill) throw new Error('Skill removal is unavailable.');\n const skill = store.getSkillBySlug(slug);\n if (!skill) return { removed: false };\n app.skills.deleteSkill(skill.id);\n return { removed: true, name: skill.name };\n },\n browserTools: (botId: string) => {\n if (!app.browser?.toolServerFor) return undefined;\n try {\n return app.browser.toolServerFor(botId);\n } catch {\n return undefined;\n }\n },\n });\n\n // --- secrets (keychain-backed; values never reach the model) ---\n try {\n app.secrets = new SecretsService(\n await pickBackend(cfg.paths.secrets),\n `${cfg.paths.secrets}.index`,\n );\n log.info(`secrets backend: ${app.secrets.backendName}`);\n } catch (err) {\n log.warn('secrets backend unavailable', (err as Error).message);\n }\n\n // --- optional subsystems (built concurrently; wired only if present) ---\n await wireSkills(app);\n await wireBrowser(app);\n await wireScheduler(app);\n\n app.shutdown = async () => {\n try { app.scheduler?.stop?.(); } catch { /* ignore */ }\n try { await app.browser?.shutdown?.(); } catch { /* ignore */ }\n try { db.close(); } catch { /* ignore */ }\n };\n\n return app;\n}\n\nasync function wireSkills(app: App): Promise<void> {\n try {\n const mod = await optionalImport('skills', () => import('./skills/skills.js'));\n const pluginMod = await optionalImport('skill plugin', () => import('./skills/plugin.js'));\n const Ctor = mod?.SkillStore ?? mod?.default;\n if (!Ctor) return void log.warn('skills subsystem unavailable: no SkillStore export');\n\n // The skills directory doubles as a local plugin root so the SDK can load skills\n // natively; individual skills live one level down, under `skills/`.\n const pluginRoot = app.cfg.paths.skills;\n if (pluginMod?.ensureSkillPlugin) {\n pluginMod.ensureSkillPlugin(pluginRoot);\n const moved: string[] = pluginMod.migrateLegacyLayout?.(pluginRoot) ?? [];\n if (moved.length) log.info(`migrated ${moved.length} skill(s) into the plugin layout: ${moved.join(', ')}`);\n app.skillPluginPath = pluginRoot;\n }\n const filesDir: string = pluginMod?.skillFilesDir?.(pluginRoot) ?? pluginRoot;\n\n app.skills = new Ctor(app.store, filesDir);\n\n // Skills shipped with ant-bot are installed on every boot and refreshed in place, but\n // only while the user has not edited or deleted their copy \u2014 see skills/bundled.ts.\n const bundledMod = await optionalImport('bundled skills', () => import('./skills/bundled.js'));\n if (bundledMod?.syncBundledSkills) {\n try {\n const decisions: { slug: string; action: string }[] = bundledMod.syncBundledSkills(filesDir);\n const took = (action: string): string[] =>\n decisions.filter((d) => d.action === action).map((d) => d.slug);\n const installed = took('install');\n const updated = took('update');\n const kept = [...took('skip-modified'), ...took('skip-foreign')];\n if (installed.length) log.info(`installed ${installed.length} bundled skill(s): ${installed.join(', ')}`);\n if (updated.length) log.info(`updated ${updated.length} bundled skill(s): ${updated.join(', ')}`);\n if (kept.length) log.info(`left ${kept.length} locally-modified skill(s) alone: ${kept.join(', ')}`);\n\n // syncFromDisk only registers slugs the db has never seen, so a skill whose shipped\n // frontmatter `name` changed would keep its old registered name \u2014 and the SDK is handed\n // registered names as `enabledSkills`, so it would silently stop resolving for every bot\n // that had it enabled.\n const written = [...installed, ...updated, ...took('adopt')];\n const renamed: string[] = app.skills?.refreshFromDisk?.(written) ?? [];\n if (renamed.length) log.info(`refreshed metadata for ${renamed.length} skill(s): ${renamed.join(', ')}`);\n } catch (e) {\n log.warn('bundled skills not synced', (e as Error).message);\n }\n }\n app.skills.syncFromDisk?.();\n // Registry and disk drift apart when skills are removed by hand or a layout migration\n // moves files; left alone, the UI lists skills that cannot load.\n const fixed = app.skills.reconcile?.() as { repaired: string[]; removed: string[] } | undefined;\n if (fixed?.repaired.length) log.info(`repaired ${fixed.repaired.length} skill path(s): ${fixed.repaired.join(', ')}`);\n if (fixed?.removed.length) log.info(`dropped ${fixed.removed.length} skill row(s) with no files on disk`);\n log.info(`skills ready (${app.store.listSkills().length} registered)`);\n } catch (err) {\n log.warn('skills subsystem unavailable', (err as Error).message);\n }\n}\n\nasync function wireBrowser(app: App): Promise<void> {\n try {\n const mod = await optionalImport('browser', () => import('./computer/browser.js'));\n const Ctor = mod?.BrowserService ?? mod?.default;\n if (!Ctor) return void log.warn('browser subsystem unavailable: no BrowserService export');\n const svc = new Ctor({ profileDir: app.cfg.paths.browserProfile, bus: app.bus, headless: true });\n let toolsMod: any = null;\n toolsMod = await optionalImport('browser tools', () => import('./computer/tools.js'));\n // Each bot drives its own page (\"screen\") on the one shared browser profile.\n const cache = new Map<string, unknown>();\n svc.toolServerFor = (botId: string) => {\n if (!toolsMod?.createBrowserToolServer) return undefined;\n let s = cache.get(botId);\n if (!s) {\n s = toolsMod.createBrowserToolServer(svc, botId, app.cfg.paths.workspace);\n cache.set(botId, s);\n }\n return s;\n };\n app.browser = svc;\n log.info('browser computer service ready');\n } catch (err) {\n log.warn('browser subsystem unavailable', (err as Error).message);\n }\n}\n\nasync function wireScheduler(app: App): Promise<void> {\n try {\n const mod = await optionalImport('scheduler', () => import('./scheduler/scheduler.js'));\n const Ctor = mod?.Scheduler ?? mod?.default;\n if (!Ctor) return void log.warn('scheduler subsystem unavailable: no Scheduler export');\n app.scheduler = new Ctor({\n store: app.store, bus: app.bus, manager: app.manager, getSettings: app.getSettings,\n });\n app.scheduler.start?.();\n log.info(`scheduler started (${app.store.listRoutines().filter((r) => r.enabled).length} active routines)`);\n } catch (err) {\n log.warn('scheduler subsystem unavailable', (err as Error).message);\n }\n}\n\n/** Deliver queued bot-to-bot mail on boot so handoffs survive a restart. */\nexport function drainMailbox(app: App): number {\n let n = 0;\n for (const bot of app.store.listBots()) {\n for (const m of app.store.listMail(bot.id)) {\n const from = app.store.getBot(m.fromBotId);\n app.manager.enqueue({\n botId: bot.id, threadId: bot.threadId!, origin: 'bot', hops: m.hops,\n prompt: `**Handoff from @${from?.slug ?? 'unknown'}:**\\n\\n${m.contentMd}`,\n });\n app.store.markDelivered(m.id);\n n++;\n }\n }\n return n;\n}\n\nexport function workspaceRelative(root: string, p: string): string | null {\n const resolved = path.resolve(root, p);\n const rel = path.relative(root, resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) return null;\n return resolved;\n}\n\nexport function ensureWorkspaceFile(p: string): boolean {\n try { return fs.statSync(p).isFile(); } catch { return false; }\n}\n", "import Database from 'better-sqlite3';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { migrate } from './migrations.js';\nimport { logger } from '../util/log.js';\n\nexport type DB = Database.Database;\n\nconst log = logger('db');\n\nexport interface OpenDbOptions {\n /**\n * Where a pre-migration snapshot is written. Defaults to a `backups` sibling of the database\n * file, which is `paths.backups` for a real install. Ignored for `:memory:`.\n */\n backupsDir?: string;\n}\n\nexport function openDb(file: string, opts: OpenDbOptions = {}): DB {\n if (file !== ':memory:') fs.mkdirSync(path.dirname(file), { recursive: true });\n const db = new Database(file);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n db.pragma('busy_timeout = 5000');\n\n // The schema is applied by the migration runner, not by exec'ing SCHEMA_SQL here \u2014 see\n // migrations.ts for why a bare `CREATE TABLE IF NOT EXISTS` blob cannot ship an update to a\n // database that already exists on a user's machine.\n const backupsDir =\n file === ':memory:' ? undefined : (opts.backupsDir ?? path.join(path.dirname(file), 'backups'));\n const result = migrate(db, { backupsDir });\n // Creating the schema in an empty database is not news; upgrading one that already held a\n // user's data is the thing a support log needs to show.\n if (result.from > 0 && result.applied.length) {\n log.info(\n `schema ${result.from} -> ${result.to}: ${result.applied.map((a) => a.name).join(', ')}` +\n (result.backupPath ? ` (snapshot: ${result.backupPath})` : ''),\n );\n }\n return db;\n}\n", "// The schema evolves on the user's machine, not ours. Once ant-bot ships, a `CREATE TABLE IF NOT\n// EXISTS` blob is silently wrong: the statement succeeds against an old database and the new column\n// is simply absent, so the first query that reads it fails at runtime, far from the cause. This\n// module is the ordered ledger that makes a change actually reach an existing `~/.ant-bot/antbot.db`.\n//\n// Shape follows the rest of the codebase: `planMigrations` is the pure decision, `migrate` is the\n// I/O wrapper (see `detectBlockFromSignals` / `computeBackupItems` / `runDoctor(deps)`).\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { DB } from './db.js';\nimport { SCHEMA_SQL } from './schema.js';\n\nexport class MigrationError extends Error {\n constructor(\n public code: 'MIGRATION_ORDER' | 'MIGRATION_DOWNGRADE' | 'MIGRATION_FAILED',\n message: string,\n ) {\n super(message);\n this.name = 'MigrationError';\n }\n}\n\nexport interface Migration {\n /** Strictly increasing, starting at 1. Never renumber a released migration. */\n version: number;\n /** Short slug, recorded in the ledger so a support log says what ran. */\n name: string;\n /** Executed with `db.exec` inside a transaction. Must be idempotent-safe to re-read, not re-run. */\n up: string;\n}\n\n/**\n * Migration 1 is the schema as it stood when the runner was introduced. Every database in\n * existence at that point already has it, which is why `detectBaselineAdoption` exists \u2014 such a\n * database is adopted at this version rather than being mistaken for an empty one.\n */\nexport const BASELINE_VERSION = 1;\n\n/**\n * A table that only the baseline creates. Used to tell \"existing database, no ledger yet\" from\n * \"brand new file\"; `bots` has been in the schema since the first commit and is never dropped.\n */\nconst BASELINE_SENTINEL_TABLE = 'bots';\n\nexport const MIGRATIONS: Migration[] = [\n { version: BASELINE_VERSION, name: 'baseline', up: SCHEMA_SQL },\n];\n\nexport const SCHEMA_VERSION_SQL = `\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY, name TEXT NOT NULL, applied_at INTEGER NOT NULL\n);\n`;\n\n/* ------------------------------- pure core ------------------------------- */\n\n/**\n * A database created before the migration runner has the baseline schema but no ledger rows.\n * Recognising that is the difference between adopting it and re-running history over it.\n */\nexport function detectBaselineAdoption(hasLedgerRows: boolean, hasBaselineTable: boolean): boolean {\n return !hasLedgerRows && hasBaselineTable;\n}\n\n/**\n * Decides what to run. Throws rather than guessing: an out-of-order list is an authoring bug, and\n * a database numbered past the code is an older ant-bot opening a newer install's data \u2014 running\n * nothing there would let it write rows the newer schema forbids.\n */\nexport function planMigrations(currentVersion: number, migrations: Migration[]): Migration[] {\n const sorted = [...migrations].sort((a, b) => a.version - b.version);\n let prev = 0;\n for (const m of sorted) {\n if (!Number.isInteger(m.version) || m.version < 1) {\n throw new MigrationError('MIGRATION_ORDER', `migration \"${m.name}\" has invalid version ${m.version}`);\n }\n if (m.version === prev) {\n throw new MigrationError('MIGRATION_ORDER', `duplicate migration version ${m.version}`);\n }\n prev = m.version;\n }\n\n const latest = sorted.length ? sorted[sorted.length - 1]!.version : 0;\n if (currentVersion > latest) {\n throw new MigrationError(\n 'MIGRATION_DOWNGRADE',\n `database is at schema version ${currentVersion} but this build only knows up to ${latest}. ` +\n `Upgrade ant-bot (npm i -g @michael-joseph-miller/ant-bot) rather than downgrading the database.`,\n );\n }\n\n return sorted.filter((m) => m.version > currentVersion);\n}\n\n/* ------------------------------- I/O wrapper ------------------------------- */\n\nexport interface MigrateResult {\n from: number;\n to: number;\n applied: { version: number; name: string }[];\n /** Path of the pre-migration snapshot, when one was taken. */\n backupPath?: string;\n}\n\nexport interface MigrateOptions {\n /** Where a pre-migration snapshot is written. Omit to skip the snapshot (in-memory databases). */\n backupsDir?: string;\n migrations?: Migration[];\n now?: () => number;\n}\n\nfunction readCurrentVersion(db: DB): { version: number; adopted: boolean } {\n db.exec(SCHEMA_VERSION_SQL);\n const row = db.prepare(`SELECT MAX(version) v FROM schema_version`).get() as { v: number | null };\n if (row.v !== null) return { version: row.v, adopted: false };\n\n const sentinel = db\n .prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`)\n .get(BASELINE_SENTINEL_TABLE) as { name: string } | undefined;\n const adopted = detectBaselineAdoption(false, Boolean(sentinel));\n return { version: adopted ? BASELINE_VERSION : 0, adopted };\n}\n\n/**\n * Snapshots the database file before a migration touches it. `VACUUM INTO` is used rather than a\n * file copy because it checkpoints WAL content into the snapshot \u2014 copying `antbot.db` alone would\n * silently lose whatever is still sitting in `antbot.db-wal`.\n */\nfunction snapshot(db: DB, backupsDir: string, toVersion: number, now: () => number): string {\n fs.mkdirSync(backupsDir, { recursive: true });\n const stamp = new Date(now()).toISOString().replace(/[:.]/g, '-');\n const dest = path.join(backupsDir, `antbot-pre-v${toVersion}-${stamp}.db`);\n db.prepare(`VACUUM INTO ?`).run(dest);\n return dest;\n}\n\n/**\n * Brings `db` up to the latest schema version, snapshotting first if there is anything to lose.\n * Each migration commits on its own so a failure halfway through a list leaves the ledger honest\n * about how far it got.\n */\nexport function migrate(db: DB, opts: MigrateOptions = {}): MigrateResult {\n const migrations = opts.migrations ?? MIGRATIONS;\n const now = opts.now ?? Date.now;\n const { version: from, adopted } = readCurrentVersion(db);\n\n // OR IGNORE guards only the adoption row below; `planMigrations` already guarantees the loop\n // never re-inserts a version the ledger holds.\n const record = db.prepare(\n `INSERT OR IGNORE INTO schema_version (version, name, applied_at) VALUES (?, ?, ?)`,\n );\n // Write the adoption down the first time we see a pre-runner database. Without this the ledger\n // stays empty until some *later* migration runs, and then reads as though the baseline never\n // did \u2014 which is exactly the question a support log gets asked.\n if (adopted) {\n const baseline = migrations.find((m) => m.version === BASELINE_VERSION);\n record.run(BASELINE_VERSION, baseline?.name ?? 'baseline', now());\n }\n\n const pending = planMigrations(from, migrations);\n if (pending.length === 0) return { from, to: from, applied: [] };\n\n const target = pending[pending.length - 1]!.version;\n\n // A brand-new database (version 0) has nothing to lose, and snapshotting it would litter\n // `backups/` with an empty file on every first run.\n let backupPath: string | undefined;\n if (opts.backupsDir && from > 0) {\n backupPath = snapshot(db, opts.backupsDir, target, now);\n }\n\n const applied: { version: number; name: string }[] = [];\n for (const m of pending) {\n const run = db.transaction(() => {\n db.exec(m.up);\n record.run(m.version, m.name, now());\n });\n try {\n run();\n } catch (err) {\n throw new MigrationError(\n 'MIGRATION_FAILED',\n `migration ${m.version} (${m.name}) failed: ${(err as Error).message}` +\n (backupPath ? `. The pre-migration database was saved to ${backupPath}` : ''),\n );\n }\n applied.push({ version: m.version, name: m.name });\n }\n\n return { from, to: target, applied, backupPath };\n}\n", "export const SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS bots (\n id TEXT PRIMARY KEY, slug TEXT UNIQUE NOT NULL, name TEXT NOT NULL,\n title TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '',\n avatar_emoji TEXT NOT NULL DEFAULT '\uD83E\uDD16', model_tier TEXT NOT NULL DEFAULT 'sonnet',\n pinned INTEGER NOT NULL DEFAULT 0, hidden INTEGER NOT NULL DEFAULT 0,\n notifications INTEGER NOT NULL DEFAULT 1, session_id TEXT,\n state TEXT NOT NULL DEFAULT 'idle', attention TEXT NOT NULL DEFAULT 'none',\n thread_id TEXT, created_at INTEGER NOT NULL, deleted_at INTEGER\n);\nCREATE TABLE IF NOT EXISTS threads (\n id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK(kind IN ('dm','group')),\n title TEXT NOT NULL DEFAULT '', member_bot_ids TEXT NOT NULL DEFAULT '[]',\n pinned INTEGER NOT NULL DEFAULT 0, hidden INTEGER NOT NULL DEFAULT 0,\n last_read_at INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY, thread_id TEXT NOT NULL,\n author_kind TEXT NOT NULL CHECK(author_kind IN ('user','bot','system')),\n author_bot_id TEXT, reply_to_id TEXT, content_md TEXT NOT NULL DEFAULT '',\n cards TEXT NOT NULL DEFAULT '[]', streaming INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_messages_thread ON messages(thread_id, created_at);\nCREATE TABLE IF NOT EXISTS attachments (\n id TEXT PRIMARY KEY, message_id TEXT, path TEXT NOT NULL, name TEXT NOT NULL,\n mime TEXT NOT NULL, bytes INTEGER NOT NULL, created_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS approvals (\n id TEXT PRIMARY KEY, bot_id TEXT NOT NULL, thread_id TEXT NOT NULL,\n tool_name TEXT NOT NULL, input_summary TEXT NOT NULL, raw_input TEXT NOT NULL DEFAULT 'null',\n status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending','allowed','denied','expired')),\n decided_by TEXT CHECK(decided_by IN ('user','rule','auto_review')),\n reason TEXT NOT NULL DEFAULT '', rule_id TEXT,\n created_at INTEGER NOT NULL, decided_at INTEGER\n);\nCREATE INDEX IF NOT EXISTS idx_approvals_status ON approvals(status);\nCREATE TABLE IF NOT EXISTS rules (\n id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK(kind IN ('require','allow')),\n tool_pattern TEXT NOT NULL DEFAULT '*', input_pattern TEXT NOT NULL DEFAULT '',\n scope_note TEXT NOT NULL DEFAULT '', builtin INTEGER NOT NULL DEFAULT 0,\n enabled INTEGER NOT NULL DEFAULT 1, created_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS skills (\n id TEXT PRIMARY KEY, slug TEXT UNIQUE NOT NULL, name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '', path TEXT NOT NULL,\n source TEXT NOT NULL DEFAULT 'user' CHECK(source IN ('user','taught','imported')),\n created_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS bot_skills (\n bot_id TEXT NOT NULL, skill_id TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1,\n PRIMARY KEY (bot_id, skill_id)\n);\nCREATE TABLE IF NOT EXISTS routines (\n id TEXT PRIMARY KEY, bot_id TEXT NOT NULL, name TEXT NOT NULL,\n cron_expr TEXT NOT NULL, timezone TEXT NOT NULL DEFAULT 'UTC',\n instruction_md TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1,\n last_run_at INTEGER, next_run_at INTEGER, created_at INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_routines_bot ON routines(bot_id);\nCREATE TABLE IF NOT EXISTS routine_runs (\n id TEXT PRIMARY KEY, routine_id TEXT NOT NULL, started_at INTEGER NOT NULL,\n finished_at INTEGER, status TEXT NOT NULL CHECK(status IN ('running','ok','failed','interrupted')),\n summary TEXT NOT NULL DEFAULT '', thread_id TEXT, is_test INTEGER NOT NULL DEFAULT 0\n);\nCREATE INDEX IF NOT EXISTS idx_runs_routine ON routine_runs(routine_id, started_at DESC);\nCREATE TABLE IF NOT EXISTS mailbox (\n id TEXT PRIMARY KEY, from_bot_id TEXT NOT NULL, to_bot_id TEXT NOT NULL,\n content_md TEXT NOT NULL, hops INTEGER NOT NULL DEFAULT 1,\n delivered INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS usage (\n id TEXT PRIMARY KEY, bot_id TEXT NOT NULL, turn_id TEXT NOT NULL, model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0, output_tokens INTEGER NOT NULL DEFAULT 0,\n cache_read_tokens INTEGER NOT NULL DEFAULT 0, cost_estimate REAL NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_usage_created ON usage(created_at);\nCREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT NOT NULL);\nCREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(\n content_md, content='messages', content_rowid='rowid'\n);\nCREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN\n INSERT INTO messages_fts(rowid, content_md) VALUES (new.rowid, new.content_md);\nEND;\nCREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN\n INSERT INTO messages_fts(messages_fts, rowid, content_md) VALUES('delete', old.rowid, old.content_md);\nEND;\nCREATE TRIGGER IF NOT EXISTS messages_au AFTER UPDATE ON messages BEGIN\n INSERT INTO messages_fts(messages_fts, rowid, content_md) VALUES('delete', old.rowid, old.content_md);\n INSERT INTO messages_fts(rowid, content_md) VALUES (new.rowid, new.content_md);\nEND;\n`;\n", "import type { DB } from './db.js';\nimport { newId, now, slugify } from '../util/ids.js';\nimport {\n LIMITS, LIMIT_ERROR, LimitError,\n type Bot, type Thread, type Message, type Attachment, type Approval, type Rule,\n type Skill, type Routine, type RoutineRun, type MailboxEntry, type UsageRow,\n type Card, type BotState, type Attention, type ModelTier, type Settings,\n SettingsSchema,\n} from '@antbot/shared';\n\n/* ------------------------------ row mappers ------------------------------ */\nconst b = (v: unknown): boolean => v === 1 || v === true;\nconst i = (v: boolean | undefined, d = false): number => ((v ?? d) ? 1 : 0);\n\ntype Row = Record<string, any>;\n\nconst toBot = (r: Row): Bot => ({\n id: r.id, slug: r.slug, name: r.name, title: r.title, description: r.description,\n avatarEmoji: r.avatar_emoji, modelTier: r.model_tier as ModelTier,\n pinned: b(r.pinned), hidden: b(r.hidden), notifications: b(r.notifications),\n sessionId: r.session_id, state: r.state as BotState, attention: r.attention as Attention,\n threadId: r.thread_id, createdAt: r.created_at, deletedAt: r.deleted_at,\n});\nconst toThread = (r: Row): Thread => ({\n id: r.id, kind: r.kind, title: r.title, memberBotIds: JSON.parse(r.member_bot_ids),\n pinned: b(r.pinned), hidden: b(r.hidden), lastReadAt: r.last_read_at, createdAt: r.created_at,\n});\nconst toMessage = (r: Row): Message => ({\n id: r.id, threadId: r.thread_id, authorKind: r.author_kind, authorBotId: r.author_bot_id,\n replyToId: r.reply_to_id, contentMd: r.content_md, cards: JSON.parse(r.cards),\n streaming: b(r.streaming), createdAt: r.created_at,\n});\nconst toApproval = (r: Row): Approval => ({\n id: r.id, botId: r.bot_id, threadId: r.thread_id, toolName: r.tool_name,\n inputSummary: r.input_summary, rawInput: JSON.parse(r.raw_input), status: r.status,\n decidedBy: r.decided_by, reason: r.reason, ruleId: r.rule_id,\n createdAt: r.created_at, decidedAt: r.decided_at,\n});\nconst toRule = (r: Row): Rule => ({\n id: r.id, kind: r.kind, toolPattern: r.tool_pattern, inputPattern: r.input_pattern,\n scopeNote: r.scope_note, builtin: b(r.builtin), enabled: b(r.enabled), createdAt: r.created_at,\n});\nconst toSkill = (r: Row): Skill => ({\n id: r.id, slug: r.slug, name: r.name, description: r.description, path: r.path,\n source: r.source, createdAt: r.created_at,\n});\nconst toRoutine = (r: Row): Routine => ({\n id: r.id, botId: r.bot_id, name: r.name, cronExpr: r.cron_expr, timezone: r.timezone,\n instructionMd: r.instruction_md, enabled: b(r.enabled), lastRunAt: r.last_run_at,\n nextRunAt: r.next_run_at, createdAt: r.created_at,\n});\nconst toRun = (r: Row): RoutineRun => ({\n id: r.id, routineId: r.routine_id, startedAt: r.started_at, finishedAt: r.finished_at,\n status: r.status, summary: r.summary, threadId: r.thread_id, isTest: b(r.is_test),\n});\nconst toAttachment = (r: Row): Attachment => ({\n id: r.id, messageId: r.message_id, path: r.path, name: r.name, mime: r.mime,\n bytes: r.bytes, createdAt: r.created_at,\n});\nconst toMail = (r: Row): MailboxEntry => ({\n id: r.id, fromBotId: r.from_bot_id, toBotId: r.to_bot_id, contentMd: r.content_md,\n hops: r.hops, delivered: b(r.delivered), createdAt: r.created_at,\n});\nconst toUsage = (r: Row): UsageRow => ({\n id: r.id, botId: r.bot_id, turnId: r.turn_id, model: r.model, inputTokens: r.input_tokens,\n outputTokens: r.output_tokens, cacheReadTokens: r.cache_read_tokens,\n costEstimate: r.cost_estimate, createdAt: r.created_at,\n});\n\n/* -------------------------------- store --------------------------------- */\nexport class Store {\n constructor(public db: DB) {}\n\n /* ---- bots ---- */\n countBotsAndGroups(): number {\n const bots = this.db.prepare(`SELECT COUNT(*) c FROM bots WHERE deleted_at IS NULL`).get() as Row;\n const groups = this.db.prepare(`SELECT COUNT(*) c FROM threads WHERE kind='group'`).get() as Row;\n return bots.c + groups.c;\n }\n\n createBot(input: { name: string; title?: string; description?: string; avatarEmoji?: string; modelTier?: ModelTier }): Bot {\n if (this.countBotsAndGroups() >= LIMITS.MAX_BOTS_AND_GROUPS)\n throw new LimitError(LIMIT_ERROR.TOO_MANY_BOTS, `Limit of ${LIMITS.MAX_BOTS_AND_GROUPS} bots and groups reached`);\n const existing = new Set(\n (this.db.prepare(`SELECT slug FROM bots`).all() as Row[]).map((r) => r.slug as string),\n );\n const id = newId();\n const thread = this.createThread({ kind: 'dm', title: input.name, memberBotIds: [id] });\n this.db\n .prepare(\n `INSERT INTO bots (id,slug,name,title,description,avatar_emoji,model_tier,pinned,hidden,notifications,session_id,state,attention,thread_id,created_at)\n VALUES (@id,@slug,@name,@title,@description,@avatar_emoji,@model_tier,0,0,1,NULL,'idle','none',@thread_id,@created_at)`,\n )\n .run({\n id, slug: slugify(input.name, existing), name: input.name, title: input.title ?? '',\n description: input.description ?? '', avatar_emoji: input.avatarEmoji ?? '\uD83E\uDD16',\n model_tier: input.modelTier ?? 'sonnet', thread_id: thread.id, created_at: now(),\n });\n return this.getBot(id)!;\n }\n\n getBot(id: string): Bot | null {\n const r = this.db.prepare(`SELECT * FROM bots WHERE id=? AND deleted_at IS NULL`).get(id) as Row | undefined;\n return r ? toBot(r) : null;\n }\n getBotBySlug(slug: string): Bot | null {\n const r = this.db.prepare(`SELECT * FROM bots WHERE slug=? AND deleted_at IS NULL`).get(slug) as Row | undefined;\n return r ? toBot(r) : null;\n }\n listBots(includeHidden = true): Bot[] {\n const rows = this.db\n .prepare(`SELECT * FROM bots WHERE deleted_at IS NULL ${includeHidden ? '' : 'AND hidden=0'} ORDER BY pinned DESC, created_at ASC`)\n .all() as Row[];\n return rows.map(toBot);\n }\n updateBot(id: string, patch: Partial<Bot>): Bot | null {\n const cur = this.getBot(id);\n if (!cur) return null;\n const m: Record<string, unknown> = {\n name: patch.name ?? cur.name, title: patch.title ?? cur.title,\n description: patch.description ?? cur.description, avatar_emoji: patch.avatarEmoji ?? cur.avatarEmoji,\n model_tier: patch.modelTier ?? cur.modelTier,\n pinned: i(patch.pinned, cur.pinned), hidden: i(patch.hidden, cur.hidden),\n notifications: i(patch.notifications, cur.notifications),\n session_id: patch.sessionId !== undefined ? patch.sessionId : cur.sessionId,\n state: patch.state ?? cur.state, attention: patch.attention ?? cur.attention, id,\n };\n this.db.prepare(\n `UPDATE bots SET name=@name,title=@title,description=@description,avatar_emoji=@avatar_emoji,\n model_tier=@model_tier,pinned=@pinned,hidden=@hidden,notifications=@notifications,\n session_id=@session_id,state=@state,attention=@attention WHERE id=@id`,\n ).run(m);\n return this.getBot(id);\n }\n deleteBot(id: string): void {\n const bot = this.getBot(id);\n if (!bot) return;\n this.db.prepare(`UPDATE bots SET deleted_at=? WHERE id=?`).run(now(), id);\n this.db.prepare(`DELETE FROM routines WHERE bot_id=?`).run(id);\n if (bot.threadId) this.db.prepare(`DELETE FROM threads WHERE id=?`).run(bot.threadId);\n }\n duplicateBot(id: string): Bot | null {\n const src = this.getBot(id);\n if (!src) return null;\n const copy = this.createBot({\n name: `${src.name} copy`, title: src.title, description: src.description,\n avatarEmoji: src.avatarEmoji, modelTier: src.modelTier,\n });\n // carries skills + routines; NOT history or memory (outline \u00A74)\n for (const bs of this.db.prepare(`SELECT * FROM bot_skills WHERE bot_id=?`).all(id) as Row[])\n this.db.prepare(`INSERT OR REPLACE INTO bot_skills (bot_id,skill_id,enabled) VALUES (?,?,?)`).run(copy.id, bs.skill_id, bs.enabled);\n for (const r of this.listRoutines(id))\n this.createRoutine({ botId: copy.id, name: r.name, cronExpr: r.cronExpr, timezone: r.timezone, instructionMd: r.instructionMd, enabled: false });\n return copy;\n }\n\n /* ---- threads & messages ---- */\n createThread(input: { kind: 'dm' | 'group'; title?: string; memberBotIds: string[] }): Thread {\n if (input.kind === 'group') {\n const n = input.memberBotIds.length;\n if (n < LIMITS.MIN_GROUP_MEMBERS || n > LIMITS.MAX_GROUP_MEMBERS)\n throw new LimitError(LIMIT_ERROR.GROUP_SIZE, `A group needs ${LIMITS.MIN_GROUP_MEMBERS}\u2013${LIMITS.MAX_GROUP_MEMBERS} bots (got ${n})`);\n if (this.countBotsAndGroups() >= LIMITS.MAX_BOTS_AND_GROUPS)\n throw new LimitError(LIMIT_ERROR.TOO_MANY_BOTS, `Limit of ${LIMITS.MAX_BOTS_AND_GROUPS} bots and groups reached`);\n }\n const id = newId();\n this.db.prepare(\n `INSERT INTO threads (id,kind,title,member_bot_ids,pinned,hidden,last_read_at,created_at)\n VALUES (?,?,?,?,0,0,0,?)`,\n ).run(id, input.kind, input.title ?? '', JSON.stringify(input.memberBotIds), now());\n return this.getThread(id)!;\n }\n getThread(id: string): Thread | null {\n const r = this.db.prepare(`SELECT * FROM threads WHERE id=?`).get(id) as Row | undefined;\n return r ? toThread(r) : null;\n }\n listThreads(kind?: 'dm' | 'group'): Thread[] {\n const rows = (kind\n ? this.db.prepare(`SELECT * FROM threads WHERE kind=? ORDER BY created_at ASC`).all(kind)\n : this.db.prepare(`SELECT * FROM threads ORDER BY created_at ASC`).all()) as Row[];\n return rows.map(toThread);\n }\n updateThread(id: string, patch: Partial<Thread>): Thread | null {\n const cur = this.getThread(id);\n if (!cur) return null;\n this.db.prepare(\n `UPDATE threads SET title=?, member_bot_ids=?, pinned=?, hidden=?, last_read_at=? WHERE id=?`,\n ).run(\n patch.title ?? cur.title, JSON.stringify(patch.memberBotIds ?? cur.memberBotIds),\n i(patch.pinned, cur.pinned), i(patch.hidden, cur.hidden), patch.lastReadAt ?? cur.lastReadAt, id,\n );\n return this.getThread(id);\n }\n deleteThread(id: string): void {\n this.db.prepare(`DELETE FROM threads WHERE id=?`).run(id);\n this.db.prepare(`DELETE FROM messages WHERE thread_id=?`).run(id);\n }\n\n createMessage(input: {\n threadId: string; authorKind: 'user' | 'bot' | 'system'; authorBotId?: string | null;\n contentMd?: string; cards?: Card[]; streaming?: boolean; replyToId?: string | null;\n }): Message {\n const id = newId();\n this.db.prepare(\n `INSERT INTO messages (id,thread_id,author_kind,author_bot_id,reply_to_id,content_md,cards,streaming,created_at)\n VALUES (?,?,?,?,?,?,?,?,?)`,\n ).run(\n id, input.threadId, input.authorKind, input.authorBotId ?? null, input.replyToId ?? null,\n input.contentMd ?? '', JSON.stringify(input.cards ?? []), i(input.streaming), now(),\n );\n return this.getMessage(id)!;\n }\n getMessage(id: string): Message | null {\n const r = this.db.prepare(`SELECT * FROM messages WHERE id=?`).get(id) as Row | undefined;\n return r ? toMessage(r) : null;\n }\n listMessages(threadId: string, limit = 500): Message[] {\n const rows = this.db\n .prepare(`SELECT * FROM messages WHERE thread_id=? ORDER BY created_at ASC LIMIT ?`)\n .all(threadId, limit) as Row[];\n return rows.map(toMessage);\n }\n updateMessage(id: string, patch: { contentMd?: string; cards?: Card[]; streaming?: boolean }): Message | null {\n const cur = this.getMessage(id);\n if (!cur) return null;\n this.db.prepare(`UPDATE messages SET content_md=?, cards=?, streaming=? WHERE id=?`).run(\n patch.contentMd ?? cur.contentMd, JSON.stringify(patch.cards ?? cur.cards), i(patch.streaming, cur.streaming), id,\n );\n return this.getMessage(id);\n }\n appendCard(id: string, card: Card): number {\n const cur = this.getMessage(id);\n if (!cur) return -1;\n const cards = [...cur.cards, card];\n this.db.prepare(`UPDATE messages SET cards=? WHERE id=?`).run(JSON.stringify(cards), id);\n return cards.length - 1;\n }\n updateCard(id: string, index: number, card: Card): void {\n const cur = this.getMessage(id);\n if (!cur || !cur.cards[index]) return;\n const cards = [...cur.cards];\n cards[index] = card;\n this.db.prepare(`UPDATE messages SET cards=? WHERE id=?`).run(JSON.stringify(cards), id);\n }\n lastMessageAt(threadId: string): number {\n const r = this.db.prepare(`SELECT MAX(created_at) m FROM messages WHERE thread_id=?`).get(threadId) as Row;\n return r?.m ?? 0;\n }\n\n /* ---- attachments ---- */\n createAttachment(a: Omit<Attachment, 'id' | 'createdAt'>): Attachment {\n const isVideo = a.mime.startsWith('video/');\n const cap = isVideo ? LIMITS.MAX_VIDEO_ATTACHMENT_BYTES : LIMITS.MAX_ATTACHMENT_BYTES;\n if (a.bytes > cap)\n throw new LimitError(LIMIT_ERROR.ATTACHMENT_TOO_LARGE, `${a.name} is ${(a.bytes / 1048576).toFixed(1)} MB; limit is ${cap / 1048576} MB`);\n const id = newId();\n this.db.prepare(\n `INSERT INTO attachments (id,message_id,path,name,mime,bytes,created_at) VALUES (?,?,?,?,?,?,?)`,\n ).run(id, a.messageId ?? null, a.path, a.name, a.mime, a.bytes, now());\n return toAttachment(this.db.prepare(`SELECT * FROM attachments WHERE id=?`).get(id) as Row);\n }\n getAttachment(id: string): Attachment | null {\n const r = this.db.prepare(`SELECT * FROM attachments WHERE id=?`).get(id) as Row | undefined;\n return r ? toAttachment(r) : null;\n }\n attachToMessage(ids: string[], messageId: string): void {\n if (ids.length > LIMITS.MAX_ATTACHMENTS_PER_MESSAGE)\n throw new LimitError(LIMIT_ERROR.TOO_MANY_ATTACHMENTS, `At most ${LIMITS.MAX_ATTACHMENTS_PER_MESSAGE} attachments per message`);\n const stmt = this.db.prepare(`UPDATE attachments SET message_id=? WHERE id=?`);\n for (const id of ids) stmt.run(messageId, id);\n }\n listAttachmentsForMessage(messageId: string): Attachment[] {\n return (this.db.prepare(`SELECT * FROM attachments WHERE message_id=?`).all(messageId) as Row[]).map(toAttachment);\n }\n\n /* ---- approvals ---- */\n createApproval(a: { botId: string; threadId: string; toolName: string; inputSummary: string; rawInput: unknown; reason?: string }): Approval {\n const id = newId();\n this.db.prepare(\n `INSERT INTO approvals (id,bot_id,thread_id,tool_name,input_summary,raw_input,status,reason,created_at)\n VALUES (?,?,?,?,?,?, 'pending', ?, ?)`,\n ).run(id, a.botId, a.threadId, a.toolName, a.inputSummary, JSON.stringify(a.rawInput ?? null), a.reason ?? '', now());\n return this.getApproval(id)!;\n }\n getApproval(id: string): Approval | null {\n const r = this.db.prepare(`SELECT * FROM approvals WHERE id=?`).get(id) as Row | undefined;\n return r ? toApproval(r) : null;\n }\n listPendingApprovals(): Approval[] {\n return (this.db.prepare(`SELECT * FROM approvals WHERE status='pending' ORDER BY created_at ASC`).all() as Row[]).map(toApproval);\n }\n resolveApproval(id: string, status: 'allowed' | 'denied' | 'expired', decidedBy: 'user' | 'rule' | 'auto_review', ruleId?: string | null, reason?: string): Approval | null {\n const cur = this.getApproval(id);\n if (!cur) return null;\n this.db.prepare(`UPDATE approvals SET status=?, decided_by=?, rule_id=?, reason=?, decided_at=? WHERE id=?`)\n .run(status, decidedBy, ruleId ?? cur.ruleId, reason ?? cur.reason, now(), id);\n return this.getApproval(id);\n }\n\n /* ---- rules ---- */\n createRule(r: { kind: 'require' | 'allow'; toolPattern: string; inputPattern?: string; scopeNote?: string; builtin?: boolean }): Rule {\n const id = newId();\n this.db.prepare(\n `INSERT INTO rules (id,kind,tool_pattern,input_pattern,scope_note,builtin,enabled,created_at) VALUES (?,?,?,?,?,?,1,?)`,\n ).run(id, r.kind, r.toolPattern, r.inputPattern ?? '', r.scopeNote ?? '', i(r.builtin), now());\n return this.getRule(id)!;\n }\n getRule(id: string): Rule | null {\n const r = this.db.prepare(`SELECT * FROM rules WHERE id=?`).get(id) as Row | undefined;\n return r ? toRule(r) : null;\n }\n listRules(onlyEnabled = false): Rule[] {\n return (this.db.prepare(`SELECT * FROM rules ${onlyEnabled ? 'WHERE enabled=1' : ''} ORDER BY kind ASC, created_at ASC`).all() as Row[]).map(toRule);\n }\n setRuleEnabled(id: string, enabled: boolean): void {\n this.db.prepare(`UPDATE rules SET enabled=? WHERE id=?`).run(i(enabled), id);\n }\n deleteRule(id: string): void {\n this.db.prepare(`DELETE FROM rules WHERE id=? AND builtin=0`).run(id);\n }\n\n /* ---- skills ---- */\n createSkill(s: { slug: string; name: string; description?: string; path: string; source?: 'user' | 'taught' | 'imported' }): Skill {\n const id = newId();\n this.db.prepare(\n `INSERT OR REPLACE INTO skills (id,slug,name,description,path,source,created_at) VALUES (?,?,?,?,?,?,?)`,\n ).run(id, s.slug, s.name, s.description ?? '', s.path, s.source ?? 'user', now());\n return this.getSkillBySlug(s.slug)!;\n }\n getSkill(id: string): Skill | null {\n const r = this.db.prepare(`SELECT * FROM skills WHERE id=?`).get(id) as Row | undefined;\n return r ? toSkill(r) : null;\n }\n getSkillBySlug(slug: string): Skill | null {\n const r = this.db.prepare(`SELECT * FROM skills WHERE slug=?`).get(slug) as Row | undefined;\n return r ? toSkill(r) : null;\n }\n listSkills(): Skill[] {\n return (this.db.prepare(`SELECT * FROM skills ORDER BY name ASC`).all() as Row[]).map(toSkill);\n }\n /**\n * Update a skill's metadata in place, keeping its id so bot assignments survive a\n * re-install. Returns null if the skill is gone.\n */\n updateSkill(id: string, patch: { name?: string; description?: string; path?: string }): Skill | null {\n const existing = this.getSkill(id);\n if (!existing) return null;\n this.db.prepare(`UPDATE skills SET name=?, description=?, path=? WHERE id=?`).run(\n patch.name ?? existing.name,\n patch.description ?? existing.description,\n patch.path ?? existing.path,\n id,\n );\n return this.getSkill(id);\n }\n deleteSkill(id: string): void {\n this.db.prepare(`DELETE FROM skills WHERE id=?`).run(id);\n this.db.prepare(`DELETE FROM bot_skills WHERE skill_id=?`).run(id);\n }\n setBotSkills(botId: string, skillIds: string[]): void {\n this.db.prepare(`DELETE FROM bot_skills WHERE bot_id=?`).run(botId);\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO bot_skills (bot_id,skill_id,enabled) VALUES (?,?,1)`);\n for (const s of skillIds) stmt.run(botId, s);\n }\n listBotSkills(botId: string): Skill[] {\n return (this.db.prepare(\n `SELECT s.* FROM skills s JOIN bot_skills bs ON bs.skill_id=s.id WHERE bs.bot_id=? AND bs.enabled=1`,\n ).all(botId) as Row[]).map(toSkill);\n }\n\n /* ---- routines ---- */\n createRoutine(r: { botId: string; name: string; cronExpr: string; timezone?: string; instructionMd: string; enabled?: boolean }): Routine {\n const count = (this.db.prepare(`SELECT COUNT(*) c FROM routines WHERE bot_id=?`).get(r.botId) as Row).c;\n if (count >= LIMITS.MAX_ROUTINES_PER_BOT)\n throw new LimitError(LIMIT_ERROR.TOO_MANY_ROUTINES, `A bot can own at most ${LIMITS.MAX_ROUTINES_PER_BOT} routines`);\n const id = newId();\n this.db.prepare(\n `INSERT INTO routines (id,bot_id,name,cron_expr,timezone,instruction_md,enabled,created_at) VALUES (?,?,?,?,?,?,?,?)`,\n ).run(id, r.botId, r.name, r.cronExpr, r.timezone ?? 'UTC', r.instructionMd, i(r.enabled, true), now());\n return this.getRoutine(id)!;\n }\n getRoutine(id: string): Routine | null {\n const r = this.db.prepare(`SELECT * FROM routines WHERE id=?`).get(id) as Row | undefined;\n return r ? toRoutine(r) : null;\n }\n listRoutines(botId?: string): Routine[] {\n const rows = (botId\n ? this.db.prepare(`SELECT * FROM routines WHERE bot_id=? ORDER BY created_at ASC`).all(botId)\n : this.db.prepare(`SELECT * FROM routines ORDER BY created_at ASC`).all()) as Row[];\n return rows.map(toRoutine);\n }\n updateRoutine(id: string, patch: Partial<Routine>): Routine | null {\n const cur = this.getRoutine(id);\n if (!cur) return null;\n this.db.prepare(\n `UPDATE routines SET name=?,cron_expr=?,timezone=?,instruction_md=?,enabled=?,last_run_at=?,next_run_at=? WHERE id=?`,\n ).run(\n patch.name ?? cur.name, patch.cronExpr ?? cur.cronExpr, patch.timezone ?? cur.timezone,\n patch.instructionMd ?? cur.instructionMd, i(patch.enabled, cur.enabled),\n patch.lastRunAt !== undefined ? patch.lastRunAt : cur.lastRunAt,\n patch.nextRunAt !== undefined ? patch.nextRunAt : cur.nextRunAt, id,\n );\n return this.getRoutine(id);\n }\n deleteRoutine(id: string): void {\n this.db.prepare(`DELETE FROM routines WHERE id=?`).run(id);\n this.db.prepare(`DELETE FROM routine_runs WHERE routine_id=?`).run(id);\n }\n\n startRun(routineId: string, isTest = false, threadId?: string): RoutineRun {\n const id = newId();\n this.db.prepare(\n `INSERT INTO routine_runs (id,routine_id,started_at,status,summary,thread_id,is_test) VALUES (?,?,?,'running','',?,?)`,\n ).run(id, routineId, now(), threadId ?? null, i(isTest));\n return this.getRun(id)!;\n }\n finishRun(id: string, status: 'ok' | 'failed' | 'interrupted', summary: string): RoutineRun | null {\n this.db.prepare(`UPDATE routine_runs SET finished_at=?, status=?, summary=? WHERE id=?`).run(now(), status, summary, id);\n const run = this.getRun(id);\n if (run) this.pruneRuns(run.routineId);\n return run;\n }\n getRun(id: string): RoutineRun | null {\n const r = this.db.prepare(`SELECT * FROM routine_runs WHERE id=?`).get(id) as Row | undefined;\n return r ? toRun(r) : null;\n }\n listRuns(routineId: string): RoutineRun[] {\n return (this.db.prepare(\n `SELECT * FROM routine_runs WHERE routine_id=? ORDER BY started_at DESC LIMIT ?`,\n ).all(routineId, LIMITS.ROUTINE_RUNS_RETAINED) as Row[]).map(toRun);\n }\n /** Keep only the N most recent run records (outline \u00A713). */\n pruneRuns(routineId: string): void {\n this.db.prepare(\n `DELETE FROM routine_runs WHERE routine_id=? AND id NOT IN\n (SELECT id FROM routine_runs WHERE routine_id=? ORDER BY started_at DESC LIMIT ?)`,\n ).run(routineId, routineId, LIMITS.ROUTINE_RUNS_RETAINED);\n }\n\n /* ---- mailbox ---- */\n createMail(m: { fromBotId: string; toBotId: string; contentMd: string; hops?: number }): MailboxEntry {\n const hops = m.hops ?? 1;\n if (hops > LIMITS.MAX_BOT_TO_BOT_HOPS)\n throw new LimitError(LIMIT_ERROR.HOP_LIMIT, `Bot-to-bot hop limit (${LIMITS.MAX_BOT_TO_BOT_HOPS}) reached; a human must take the next step`);\n const id = newId();\n this.db.prepare(\n `INSERT INTO mailbox (id,from_bot_id,to_bot_id,content_md,hops,delivered,created_at) VALUES (?,?,?,?,?,0,?)`,\n ).run(id, m.fromBotId, m.toBotId, m.contentMd, hops, now());\n return toMail(this.db.prepare(`SELECT * FROM mailbox WHERE id=?`).get(id) as Row);\n }\n markDelivered(id: string): void {\n this.db.prepare(`UPDATE mailbox SET delivered=1 WHERE id=?`).run(id);\n }\n listMail(toBotId: string, onlyUndelivered = true): MailboxEntry[] {\n return (this.db.prepare(\n `SELECT * FROM mailbox WHERE to_bot_id=? ${onlyUndelivered ? 'AND delivered=0' : ''} ORDER BY created_at ASC`,\n ).all(toBotId) as Row[]).map(toMail);\n }\n\n /* ---- usage ---- */\n recordUsage(u: Omit<UsageRow, 'id' | 'createdAt'>): UsageRow {\n const id = newId();\n this.db.prepare(\n `INSERT INTO usage (id,bot_id,turn_id,model,input_tokens,output_tokens,cache_read_tokens,cost_estimate,created_at)\n VALUES (?,?,?,?,?,?,?,?,?)`,\n ).run(id, u.botId, u.turnId, u.model, u.inputTokens, u.outputTokens, u.cacheReadTokens, u.costEstimate, now());\n return toUsage(this.db.prepare(`SELECT * FROM usage WHERE id=?`).get(id) as Row);\n }\n listUsage(sinceMs = 0): UsageRow[] {\n return (this.db.prepare(`SELECT * FROM usage WHERE created_at>=? ORDER BY created_at DESC`).all(sinceMs) as Row[]).map(toUsage);\n }\n tokensToday(): number {\n const start = new Date(); start.setHours(0, 0, 0, 0);\n const r = this.db.prepare(\n `SELECT COALESCE(SUM(input_tokens+output_tokens),0) t FROM usage WHERE created_at>=?`,\n ).get(start.getTime()) as Row;\n return r.t;\n }\n\n /* ---- settings ---- */\n getSettings(): Settings {\n const rows = this.db.prepare(`SELECT * FROM settings`).all() as Row[];\n const obj: Record<string, unknown> = {};\n for (const r of rows) obj[r.key] = JSON.parse(r.value);\n return SettingsSchema.parse(obj);\n }\n patchSettings(patch: Partial<Settings>): Settings {\n const stmt = this.db.prepare(`INSERT OR REPLACE INTO settings (key,value) VALUES (?,?)`);\n for (const [k, v] of Object.entries(patch)) if (v !== undefined) stmt.run(k, JSON.stringify(v));\n return this.getSettings();\n }\n\n /* ---- search ---- */\n searchMessages(q: string, limit = 40): Message[] {\n if (!q.trim()) return [];\n const escaped = `\"${q.replace(/\"/g, '\"\"')}\"`;\n try {\n const rows = this.db.prepare(\n `SELECT m.* FROM messages_fts f JOIN messages m ON m.rowid=f.rowid\n WHERE messages_fts MATCH ? ORDER BY rank LIMIT ?`,\n ).all(escaped, limit) as Row[];\n return rows.map(toMessage);\n } catch {\n const rows = this.db.prepare(\n `SELECT * FROM messages WHERE content_md LIKE ? ORDER BY created_at DESC LIMIT ?`,\n ).all(`%${q}%`, limit) as Row[];\n return rows.map(toMessage);\n }\n }\n}\n", "import { EventEmitter } from 'node:events';\nimport type { ServerEvent } from '@antbot/shared';\n\n/** Distributive omit so the discriminated union survives (a plain Omit collapses it). */\ntype DistOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\ntype Emitted = DistOmit<ServerEvent, 'seq'> & { seq?: number };\n\n/** In-process event bus. Assigns a monotonic seq so the UI can order/reconcile. */\nexport class EventBus {\n private emitter = new EventEmitter();\n private seq = 0;\n private ring: ServerEvent[] = [];\n private readonly ringMax = 500;\n\n constructor() {\n this.emitter.setMaxListeners(200);\n }\n\n publish(e: Emitted): ServerEvent {\n const full = { ...e, seq: ++this.seq } as ServerEvent;\n this.ring.push(full);\n if (this.ring.length > this.ringMax) this.ring.shift();\n this.emitter.emit('event', full);\n return full;\n }\n\n subscribe(fn: (e: ServerEvent) => void): () => void {\n this.emitter.on('event', fn);\n return () => this.emitter.off('event', fn);\n }\n\n /** Replay events after a given seq (client reconnect). */\n since(seq: number): ServerEvent[] {\n return this.ring.filter((e) => e.seq > seq);\n }\n\n get currentSeq(): number {\n return this.seq;\n }\n}\n", "import type { Rule } from '@antbot/shared';\nimport type { Store } from '../db/store.js';\nimport { logger } from '../util/log.js';\n\nconst log = logger('rules');\n\n/** Convert a glob (only `*` is special) to an anchored, case-insensitive regex. */\nexport function globToRegExp(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*');\n return new RegExp(`^${escaped}$`, 'i');\n}\n\n/** Flatten a tool input into one searchable string so input patterns can match anywhere. */\nexport function serializeInput(input: unknown): string {\n if (input == null) return '';\n if (typeof input === 'string') return input;\n try {\n return JSON.stringify(input);\n } catch {\n return String(input);\n }\n}\n\n/**\n * Build the text a rule's `inputPattern` is tested against.\n *\n * Every string value in the input gets its own line, and the serialized form is\n * appended last. Patterns are matched multiline, so `^` anchors to the start of an\n * actual argument value (e.g. the Bash `command`) rather than to the start of a JSON\n * blob \u2014 without that, an anchored allow-rule can never fire and the action falls\n * through to a human prompt.\n */\nexport function buildMatchText(input: unknown): string {\n const lines: string[] = [];\n const walk = (v: unknown, depth: number): void => {\n if (depth > 6) return;\n if (typeof v === 'string') lines.push(v);\n else if (Array.isArray(v)) v.forEach((x) => walk(x, depth + 1));\n else if (v && typeof v === 'object') Object.values(v).forEach((x) => walk(x, depth + 1));\n else if (typeof v === 'number' || typeof v === 'boolean') lines.push(String(v));\n };\n walk(input, 0);\n const serialized = serializeInput(input);\n if (serialized && !lines.includes(serialized)) lines.push(serialized);\n return lines.join('\\n');\n}\n\nexport interface RuleMatch {\n rule: Rule;\n matched: true;\n}\n\n/**\n * Names a tool call can be matched against.\n *\n * Tools served over MCP arrive at the permission boundary fully namespaced as\n * `mcp__<server>__<tool>` \u2014 a live turn records the browser tools as\n * `mcp__browser__browser_navigate`. Rule tool patterns are anchored, so a rule written\n * against the bare name (`browser_click`, `send_to_bot`) could never match, silently\n * killing the consequential-click, credential-typing and handoff require-rules.\n *\n * Matching against both forms keeps rules authored either way working. Both `require`\n * and `allow` rules get the same treatment, so this cannot flip a blocked action into\n * an allowed one \u2014 `require` still wins (see `evaluateRules`).\n */\nexport function toolNameAliases(toolName: string): string[] {\n const m = /^mcp__.+?__(.+)$/.exec(toolName);\n return m?.[1] ? [toolName, m[1]] : [toolName];\n}\n\nexport function ruleMatches(rule: Rule, toolName: string, inputText: string): boolean {\n if (!rule.enabled) return false;\n const pattern = globToRegExp(rule.toolPattern);\n if (!toolNameAliases(toolName).some((n) => pattern.test(n))) return false;\n if (rule.inputPattern) {\n let re: RegExp;\n try {\n re = new RegExp(rule.inputPattern, 'im');\n } catch {\n return false; // an invalid stored pattern must never silently allow\n }\n if (!re.test(inputText)) return false;\n }\n return true;\n}\n\nexport type RuleDecision =\n | { kind: 'require'; rule: Rule }\n | { kind: 'allow'; rule: Rule }\n | { kind: 'none' };\n\n/**\n * Precedence, per outline \u00A79: an enabled `require` rule always wins over any\n * `allow` rule. Only when no `require` matches can an `allow` take effect.\n */\nexport function evaluateRules(rules: Rule[], toolName: string, input: unknown): RuleDecision {\n const inputText = buildMatchText(input);\n const required = rules.find((r) => r.kind === 'require' && ruleMatches(r, toolName, inputText));\n if (required) return { kind: 'require', rule: required };\n const allowed = rules.find((r) => r.kind === 'allow' && ruleMatches(r, toolName, inputText));\n if (allowed) return { kind: 'allow', rule: allowed };\n return { kind: 'none' };\n}\n\n/**\n * Default require-rules (WP-2.1). These ship enabled so that sending, publishing,\n * purchasing, deleting outside the workspace, installs, sudo and git push are all\n * behind approval out of the box.\n */\nexport const BUILTIN_RULES: Array<Omit<Rule, 'id' | 'createdAt'>> = [\n { kind: 'require', toolPattern: 'Bash', inputPattern: '\\\\bsudo\\\\b|\\\\bdoas\\\\b|\\\\bsu\\\\s+-', scopeNote: 'Privilege escalation', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: 'rm\\\\s+(-[a-zA-Z]*\\\\s+)*-?[rf]|shred\\\\b|mkfs\\\\b|dd\\\\s+if=', scopeNote: 'Destructive filesystem command', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: 'curl[^|]*\\\\|\\\\s*(ba)?sh|wget[^|]*\\\\|\\\\s*(ba)?sh', scopeNote: 'Piping a download into a shell', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: '\\\\b(npm|pnpm|yarn|pip|pip3|gem|cargo|apt|apt-get|dnf|brew|go)\\\\s+(i|install|add|get)\\\\b', scopeNote: 'Package install', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: 'git\\\\s+(push|remote\\\\s+add)|gh\\\\s+(pr|release|repo)\\\\s+(create|merge)', scopeNote: 'Publishing to a remote', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: '\\\\b(mail|sendmail|mutt|msmtp)\\\\b', scopeNote: 'Sending mail', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'Bash', inputPattern: 'curl[^\\\\n]*(-X\\\\s*(POST|PUT|PATCH|DELETE)|--data|-d\\\\s)', scopeNote: 'Outbound write request', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'WebFetch', inputPattern: '.', scopeNote: 'Fetching an external URL', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'browser_click', inputPattern: '(buy|purchase|checkout|pay|order|subscribe|confirm|delete|send|publish)', scopeNote: 'Consequential click', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'browser_type', inputPattern: '(password|passwd|secret|token|api[_-]?key|ssn|credit\\\\s*card)', scopeNote: 'Typing a credential \u2014 use takeover instead', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'send_to_bot', inputPattern: '', scopeNote: 'Handing work to another bot', builtin: false, enabled: false },\n { kind: 'require', toolPattern: 'install_skill', inputPattern: '', scopeNote: 'Installing a skill from an external source', builtin: true, enabled: true },\n { kind: 'require', toolPattern: 'remove_skill', inputPattern: '', scopeNote: 'Uninstalling a skill', builtin: true, enabled: true },\n { kind: 'allow', toolPattern: 'Read', inputPattern: '', scopeNote: 'Reading files is safe', builtin: true, enabled: true },\n { kind: 'allow', toolPattern: 'Glob', inputPattern: '', scopeNote: 'Listing files is safe', builtin: true, enabled: true },\n { kind: 'allow', toolPattern: 'Grep', inputPattern: '', scopeNote: 'Searching files is safe', builtin: true, enabled: true },\n { kind: 'allow', toolPattern: 'TodoWrite', inputPattern: '', scopeNote: 'Planning scratchpad', builtin: true, enabled: true },\n { kind: 'allow', toolPattern: 'Bash', inputPattern: '^\\\\s*(git\\\\s+(status|diff|log|show|branch)|ls|pwd|cat|head|tail|wc|echo|date|which|grep|find|rg)\\\\b', scopeNote: 'Read-only shell inspection', builtin: true, enabled: true },\n];\n\n/**\n * Ensure every builtin rule exists, adding only the ones that don't.\n *\n * Seeding all-or-nothing would mean a rule added in a later version never reaches an\n * existing database \u2014 the new gate would silently not apply to exactly the installs that\n * have been running longest. Rules already present are left alone, so a builtin the user\n * has disabled stays disabled.\n */\nexport function seedBuiltinRules(store: Store): void {\n // Match across every rule, not just `builtin` ones: one seeded entry (send_to_bot) is\n // deliberately created as a user rule, and filtering to builtins would re-add it each boot.\n const key = (r: { kind: string; toolPattern: string; inputPattern: string }): string =>\n `${r.kind}\\u0000${r.toolPattern}\\u0000${r.inputPattern}`;\n const existing = new Set(store.listRules().map(key));\n const added: string[] = [];\n for (const r of BUILTIN_RULES) {\n if (existing.has(key(r))) continue;\n const rule = store.createRule(r);\n if (!r.enabled) store.setRuleEnabled(rule.id, false);\n added.push(r.toolPattern);\n }\n if (added.length) log.info(`seeded ${added.length} builtin permission rule(s): ${added.join(', ')}`);\n}\n", "import path from 'node:path';\n\n/**\n * Decide whether a proposed tool call reaches OUTSIDE the shared workspace \u2014 i.e.\n * touches the user's own machine rather than the bots' computer.\n *\n * ant-bot has no separate cloud VM, so Grok Bot's \"execution on local computer\"\n * control maps onto this boundary: the workspace is the bots' computer, and\n * everything else is your machine.\n */\nexport type LocalReach = { reaches: boolean; evidence: string };\n\nconst HOME_ISH = /(^|[\\s\"'=:])(~|\\$HOME)\\//;\n\n/** Anything scheme://... \u2014 a URL's path is not a filesystem path. */\nconst URL_RE = /\\b[a-z][a-z0-9+.-]*:\\/\\/\\S+/gi;\n\n/**\n * Filesystem path candidates in a command string: absolute (`/etc`), home-relative\n * (`~/.ssh`), and dot-relative (`./src`, `../..`). Dot-relative forms are kept rather\n * than dropped because they resolve against the workspace, so `./src` reads as inside\n * while `../../.ssh` correctly reads as an escape.\n */\nexport function extractPaths(text: string): string[] {\n const out: string[] = [];\n const cleaned = text.replace(URL_RE, ' ');\n for (const m of cleaned.matchAll(/(?<![\\w\\-.:/])((?:~|\\.{1,2}\\/|\\.\\.(?=\\s|$)|\\/)[^\\s\"';|&)]*)/g)) {\n const p = m[1];\n if (p && p.length > 1) out.push(p);\n }\n return out;\n}\n\nexport function assessLocalReach(toolName: string, input: unknown, workspace: string): LocalReach {\n const o = (input ?? {}) as Record<string, unknown>;\n const str = (k: string): string => (typeof o[k] === 'string' ? (o[k] as string) : '');\n const ws = path.resolve(workspace);\n\n const insideWorkspace = (p: string): boolean => {\n if (p.startsWith('~')) return false;\n const abs = path.isAbsolute(p) ? path.resolve(p) : path.resolve(ws, p);\n const rel = path.relative(ws, abs);\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n };\n\n // File tools carry an explicit path.\n if (toolName === 'Read' || toolName === 'Write' || toolName === 'Edit' || toolName === 'NotebookEdit') {\n const p = str('file_path') || str('notebook_path');\n if (p && !insideWorkspace(p)) return { reaches: true, evidence: p };\n return { reaches: false, evidence: '' };\n }\n\n if (toolName === 'Bash') {\n const cmd = str('command');\n if (HOME_ISH.test(cmd)) {\n const m = cmd.match(HOME_ISH);\n return { reaches: true, evidence: m ? cmd.slice(Math.max(0, (m.index ?? 0)), (m.index ?? 0) + 60).trim() : '~' };\n }\n for (const p of extractPaths(cmd)) {\n if (!insideWorkspace(p)) return { reaches: true, evidence: p };\n }\n return { reaches: false, evidence: '' };\n }\n\n return { reaches: false, evidence: '' };\n}\n\nexport type LocalPolicy = 'ask' | 'always' | 'never';\n\nexport function localDecision(policy: LocalPolicy, reach: LocalReach):\n | { action: 'ignore' }\n | { action: 'require'; reason: string }\n | { action: 'deny'; reason: string } {\n if (!reach.reaches) return { action: 'ignore' };\n if (policy === 'always') return { action: 'ignore' };\n if (policy === 'never')\n return {\n action: 'deny',\n reason: `Blocked: this touches ${reach.evidence}, which is outside the shared workspace. \"Execution on local computer\" is set to Never in Settings.`,\n };\n return { action: 'require', reason: `Touches ${reach.evidence}, outside the shared workspace (your own machine)` };\n}\n", "import type { Store } from '../db/store.js';\nimport type { EventBus } from '../util/bus.js';\nimport { LIMITS, type Approval, type Settings } from '@antbot/shared';\nimport { evaluateRules, serializeInput, toolNameAliases } from './rules.js';\nimport { assessLocalReach, localDecision } from './local.js';\nimport { describeSkillSource } from '../skills/install.js';\nimport { logger } from '../util/log.js';\n\nconst log = logger('gateway');\n\nexport type GatewayDecision =\n | { behavior: 'allow'; reason: string; via: 'rule' | 'auto_review' | 'user' }\n | { behavior: 'deny'; message: string; via: 'rule' | 'auto_review' | 'user' | 'timeout' };\n\nexport interface AutoReviewer {\n /** Classify a proposed tool call. Never able to override a `require` rule. */\n classify(toolName: string, input: unknown, botDescription: string): Promise<{\n verdict: 'allow_ok' | 'needs_human' | 'deny_suggested';\n reason: string;\n }>;\n}\n\nexport interface PendingResolver {\n approvalId: string;\n resolve: (d: GatewayDecision) => void;\n timer: NodeJS.Timeout;\n}\n\n/** Human-readable one-line summary of a proposed action for the approval card. */\nexport function summarize(namespacedToolName: string, input: unknown): string {\n const o = (input ?? {}) as Record<string, unknown>;\n const s = (k: string): string => (typeof o[k] === 'string' ? (o[k] as string) : '');\n // MCP tools arrive as `mcp__<server>__<tool>`; summarize on the bare name so the\n // approval card stays legible. Falls back to the full name for anything unrecognized.\n const aliases = toolNameAliases(namespacedToolName);\n const toolName = aliases[aliases.length - 1]!;\n switch (toolName) {\n case 'Bash':\n return `Run: ${s('command').slice(0, 200)}`;\n case 'Write':\n return `Write file ${s('file_path')}`;\n case 'Edit':\n return `Edit file ${s('file_path')}`;\n case 'Read':\n return `Read file ${s('file_path')}`;\n case 'WebFetch':\n return `Fetch ${s('url')}`;\n case 'send_to_bot':\n return `Hand work to @${s('bot_slug')}`;\n // Scope is the whole decision here: one named skill, or every skill in a repository.\n case 'install_skill':\n return describeSkillSource(s('source'));\n case 'remove_skill':\n return `Uninstall the skill \"${s('slug')}\"`;\n default: {\n if (toolName.startsWith('browser_')) {\n const bits = [s('url'), s('selector'), s('text')].filter(Boolean).join(' ');\n return `${toolName.replace('browser_', 'Browser ')}: ${bits}`.trim();\n }\n const flat = serializeInput(input);\n return `${toolName}: ${flat.slice(0, 180)}`;\n }\n }\n}\n\nexport class PermissionGateway {\n private pending = new Map<string, PendingResolver>();\n\n constructor(\n private store: Store,\n private bus: EventBus,\n private autoReviewer?: AutoReviewer,\n ) {}\n\n /**\n * Decide whether a proposed tool call may run.\n * Order: deterministic rules \u2192 auto review (advisory) \u2192 human approval card.\n * A matching `require` rule can never be satisfied by auto review (outline \u00A79).\n */\n async check(args: {\n botId: string;\n threadId: string;\n toolName: string;\n input: unknown;\n botDescription: string;\n settings: Settings;\n signal?: AbortSignal;\n /** Absolute path of the shared workspace, for the local-execution boundary. */\n workspace: string;\n /** Fired when a human approval card is created, so the caller can render it inline. */\n onPending?: (approval: Approval) => void;\n }): Promise<GatewayDecision> {\n const { toolName, input, settings } = args;\n const rules = this.store.listRules(true);\n const decision = evaluateRules(rules, toolName, input);\n\n // The local-execution policy is checked before any allow rule: reaching outside\n // the shared workspace means touching the user's own machine, and a broad allow\n // rule must not silently authorize that.\n const local = localDecision(settings.localExecution, assessLocalReach(toolName, input, args.workspace));\n if (local.action === 'deny') {\n return { behavior: 'deny', message: local.reason, via: 'rule' };\n }\n if (local.action === 'require' && decision.kind !== 'require') {\n return this.askHuman({ ...args, reason: local.reason });\n }\n\n if (decision.kind === 'allow') {\n log.debug(`allow by rule ${decision.rule.id}: ${toolName}`);\n return { behavior: 'allow', reason: decision.rule.scopeNote || 'Matched an allow rule', via: 'rule' };\n }\n\n const requiredBy = decision.kind === 'require' ? decision.rule : null;\n\n // Auto review is advisory and only consulted when no `require` rule matched.\n if (!requiredBy && settings.autoReviewEnabled && this.autoReviewer) {\n try {\n const verdict = await this.autoReviewer.classify(toolName, input, args.botDescription);\n if (verdict.verdict === 'allow_ok')\n return { behavior: 'allow', reason: verdict.reason, via: 'auto_review' };\n if (verdict.verdict === 'deny_suggested')\n return this.askHuman({ ...args, reason: `Auto review flagged this: ${verdict.reason}` });\n return this.askHuman({ ...args, reason: verdict.reason });\n } catch (err) {\n log.warn('auto review failed; falling back to human approval', err);\n }\n }\n\n return this.askHuman({\n ...args,\n reason: requiredBy ? requiredBy.scopeNote || 'Matched a require-approval rule' : 'No rule covers this action',\n ruleId: requiredBy?.id ?? null,\n });\n }\n\n private askHuman(args: {\n botId: string; threadId: string; toolName: string; input: unknown;\n reason: string; ruleId?: string | null; signal?: AbortSignal;\n onPending?: (approval: Approval) => void;\n }): Promise<GatewayDecision> {\n const approval = this.store.createApproval({\n botId: args.botId,\n threadId: args.threadId,\n toolName: args.toolName,\n inputSummary: summarize(args.toolName, args.input),\n rawInput: args.input,\n reason: args.reason,\n });\n if (args.ruleId) this.store.db.prepare(`UPDATE approvals SET rule_id=? WHERE id=?`).run(args.ruleId, approval.id);\n\n const fresh = this.store.getApproval(approval.id)!;\n args.onPending?.(fresh);\n this.bus.publish({\n type: 'approval.pending',\n threadId: args.threadId,\n botId: args.botId,\n approval: fresh,\n });\n\n return new Promise<GatewayDecision>((resolve) => {\n const timer = setTimeout(() => {\n this.pending.delete(approval.id);\n this.store.resolveApproval(approval.id, 'expired', 'user', null, 'No response in time');\n this.bus.publish({\n type: 'approval.resolved', threadId: args.threadId, botId: args.botId,\n approval: this.store.getApproval(approval.id)!,\n });\n resolve({ behavior: 'deny', message: 'Approval request expired without a decision.', via: 'timeout' });\n }, LIMITS.APPROVAL_TIMEOUT_MS);\n\n this.pending.set(approval.id, { approvalId: approval.id, resolve, timer });\n\n args.signal?.addEventListener('abort', () => {\n const p = this.pending.get(approval.id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(approval.id);\n this.store.resolveApproval(approval.id, 'denied', 'user', null, 'Turn interrupted');\n resolve({ behavior: 'deny', message: 'Interrupted.', via: 'user' });\n });\n });\n }\n\n /** Resolve a pending approval from the UI. Returns the updated row. */\n decide(approvalId: string, decision: 'allow' | 'deny', alwaysRule?: { toolPattern: string; inputPattern?: string; scopeNote?: string }): Approval | null {\n const p = this.pending.get(approvalId);\n const existing = this.store.getApproval(approvalId);\n if (!existing) return null;\n if (existing.status !== 'pending') return existing;\n\n let ruleId: string | null = null;\n if (decision === 'allow' && alwaysRule) {\n const rule = this.store.createRule({\n kind: 'allow',\n toolPattern: alwaysRule.toolPattern,\n inputPattern: alwaysRule.inputPattern ?? '',\n scopeNote: alwaysRule.scopeNote ?? 'Saved from an approval',\n });\n ruleId = rule.id;\n }\n\n const updated = this.store.resolveApproval(\n approvalId, decision === 'allow' ? 'allowed' : 'denied', 'user', ruleId,\n decision === 'allow' ? 'Approved by you' : 'Denied by you',\n );\n this.bus.publish({\n type: 'approval.resolved', threadId: existing.threadId, botId: existing.botId, approval: updated!,\n });\n\n if (p) {\n clearTimeout(p.timer);\n this.pending.delete(approvalId);\n p.resolve(\n decision === 'allow'\n ? { behavior: 'allow', reason: 'Approved by you', via: 'user' }\n : { behavior: 'deny', message: 'You denied this action.', via: 'user' },\n );\n }\n return updated;\n }\n\n hasPending(approvalId: string): boolean {\n return this.pending.has(approvalId);\n }\n\n /** Cancel any pending approvals for a bot (used when a turn is interrupted). */\n cancelForBot(botId: string): void {\n for (const [id, p] of [...this.pending]) {\n const a = this.store.getApproval(id);\n if (a?.botId !== botId) continue;\n clearTimeout(p.timer);\n this.pending.delete(id);\n this.store.resolveApproval(id, 'denied', 'user', null, 'Turn interrupted');\n p.resolve({ behavior: 'deny', message: 'Interrupted.', via: 'user' });\n }\n }\n}\n", "import { query } from '@anthropic-ai/claude-agent-sdk';\nimport type { AutoReviewer } from './gateway.js';\nimport { buildEnv } from '../agent/session.js';\nimport type { Settings } from '@antbot/shared';\nimport { logger } from '../util/log.js';\nimport { summarize } from './gateway.js';\n\nconst log = logger('autoreview');\n\nconst SYSTEM = `You are the automated action reviewer for a local AI-teammate system.\nYou judge ONE proposed tool call and answer with a single JSON object.\n\nAnswer \"allow_ok\" only when the action is clearly routine, reversible and\nlow-consequence \u2014 reading files, inspecting state, searching, navigating to a\nnormal public page, writing inside the bot's own workspace.\n\nAnswer \"needs_human\" when the action is consequential or ambiguous: sending or\npublishing anything, contacting a person, spending money, changing permissions,\ntouching production, deleting or overwriting data outside the workspace,\ninstalling software, or anything whose blast radius you cannot determine.\n\nAnswer \"deny_suggested\" when the action looks actively unsafe or like an attempt\nto exfiltrate credentials.\n\nYou are advisory only and you are NOT the last line of defence. When in doubt,\nchoose needs_human.\n\nReply with ONLY: {\"verdict\":\"allow_ok|needs_human|deny_suggested\",\"reason\":\"<12 words max>\"}`;\n\n/** Haiku-backed reviewer. Advisory: it can never green-light past a `require` rule. */\nexport class HaikuAutoReviewer implements AutoReviewer {\n constructor(\n private getSettings: () => Settings,\n private cwd: string,\n ) {}\n\n async classify(toolName: string, input: unknown, botDescription: string) {\n const prompt = `Bot's standing job description:\n${botDescription.slice(0, 800) || '(none)'}\n\nProposed tool call:\ntool: ${toolName}\nsummary: ${summarize(toolName, input)}\nraw input: ${JSON.stringify(input).slice(0, 1500)}`;\n\n const q = query({\n prompt,\n options: {\n model: 'haiku',\n systemPrompt: SYSTEM,\n cwd: this.cwd,\n settingSources: [],\n env: buildEnv(this.getSettings()),\n maxTurns: 1,\n allowedTools: [],\n permissionMode: 'default',\n },\n });\n\n let out = '';\n for await (const m of q) {\n const msg = m as Record<string, any>;\n if (msg.type === 'result' && typeof msg.result === 'string') out = msg.result;\n }\n return parseVerdict(out);\n }\n}\n\nexport function parseVerdict(text: string): { verdict: 'allow_ok' | 'needs_human' | 'deny_suggested'; reason: string } {\n const fallback = { verdict: 'needs_human' as const, reason: 'Reviewer output was unreadable' };\n if (!text) return fallback;\n const match = text.match(/\\{[\\s\\S]*\\}/);\n if (!match) return fallback;\n try {\n const o = JSON.parse(match[0]) as { verdict?: string; reason?: string };\n if (o.verdict === 'allow_ok' || o.verdict === 'needs_human' || o.verdict === 'deny_suggested')\n return { verdict: o.verdict, reason: String(o.reason ?? '').slice(0, 200) };\n return fallback;\n } catch {\n return fallback;\n }\n}\n\n/** Deterministic reviewer used in tests and when auto review is disabled. */\nexport class NullAutoReviewer implements AutoReviewer {\n async classify() {\n return { verdict: 'needs_human' as const, reason: 'Auto review disabled' };\n }\n}\n\nexport function makeAutoReviewer(getSettings: () => Settings, cwd: string): AutoReviewer {\n try {\n return new HaikuAutoReviewer(getSettings, cwd);\n } catch (err) {\n log.warn('falling back to null reviewer', err);\n return new NullAutoReviewer();\n }\n}\n", "import { query, type Options, type SDKMessage } from '@anthropic-ai/claude-agent-sdk';\nimport type { ModelTier, Settings } from '@antbot/shared';\nimport { logger } from '../util/log.js';\n\nconst log = logger('agent');\n\nexport interface TurnEvent {\n kind: 'text' | 'tool_start' | 'tool_result' | 'session' | 'done' | 'error' | 'status';\n text?: string;\n toolName?: string;\n toolInput?: unknown;\n toolUseId?: string;\n result?: string;\n isError?: boolean;\n sessionId?: string;\n usage?: { model: string; inputTokens: number; outputTokens: number; cacheReadTokens: number; costUsd: number };\n message?: string;\n}\n\nexport interface TurnRequest {\n prompt: string;\n /** Prior SDK session to resume so context compounds across turns. */\n resumeSessionId?: string | null;\n modelTier: ModelTier;\n systemPrompt: string;\n cwd: string;\n settings: Settings;\n /** Extra directories the agent may read/write beyond cwd. */\n additionalDirectories?: string[];\n canUseTool?: Options['canUseTool'];\n mcpServers?: Options['mcpServers'];\n abortController?: AbortController;\n /** Root of the local plugin that carries installed skills. */\n skillPluginPath?: string;\n /**\n * Skill names this bot may use. `[]` means none \u2014 the SDK hides unlisted skills from\n * the model's listing and the Skill tool rejects them. Note this is a context filter,\n * not a sandbox: skill files stay readable via Read/Bash, so never put secrets in one.\n */\n enabledSkills?: string[];\n}\n\n/** `sonnet`/`opus`/`haiku` are CLI model aliases; keep routing fixed per surface. */\nexport function resolveModel(tier: ModelTier): string {\n return tier;\n}\n\n/**\n * Build the environment for the CLI subprocess.\n *\n * The daemon never holds Anthropic credentials: the SDK spawns the `claude` CLI,\n * which uses the user's existing subscription OAuth login. An ANTHROPIC_API_KEY in\n * the ambient environment would silently switch billing to metered API usage, so we\n * strip it unless the user explicitly opted into API billing (plan \u00A79).\n */\nexport function buildEnv(settings: Settings, base: NodeJS.ProcessEnv = process.env): Record<string, string | undefined> {\n const env: Record<string, string | undefined> = { ...base };\n if (settings.billingMode !== 'api') {\n delete env.ANTHROPIC_API_KEY;\n delete env.ANTHROPIC_AUTH_TOKEN;\n }\n return env;\n}\n\n/**\n * Run one turn and yield normalized events. The caller owns persistence; this\n * wrapper only translates the SDK's message stream into our vocabulary.\n */\nexport async function* runTurn(req: TurnRequest): AsyncGenerator<TurnEvent> {\n const abort = req.abortController ?? new AbortController();\n const options: Options = {\n model: resolveModel(req.modelTier),\n systemPrompt: { type: 'preset', preset: 'claude_code', append: req.systemPrompt },\n cwd: req.cwd,\n additionalDirectories: req.additionalDirectories,\n abortController: abort,\n includePartialMessages: true,\n permissionMode: 'default',\n canUseTool: req.canUseTool,\n mcpServers: req.mcpServers,\n env: buildEnv(req.settings),\n // Do not inherit the user's own Claude Code project settings into bot turns.\n settingSources: [],\n maxTurns: 60,\n };\n if (req.resumeSessionId) options.resume = req.resumeSessionId;\n // Load skills as a local plugin so the model gets the real `Skill` tool rather than a\n // pile of paths to read, then narrow to the ones assigned to this bot.\n if (req.skillPluginPath) {\n options.plugins = [{ type: 'local', path: req.skillPluginPath }];\n options.skills = req.enabledSkills ?? [];\n }\n\n let q: ReturnType<typeof query>;\n try {\n q = query({ prompt: req.prompt, options });\n } catch (err) {\n yield { kind: 'error', message: err instanceof Error ? err.message : String(err) };\n return;\n }\n\n const seenToolIds = new Set<string>();\n\n try {\n for await (const msg of q as AsyncGenerator<SDKMessage>) {\n const m = msg as Record<string, any>;\n switch (m.type) {\n case 'system':\n if (m.subtype === 'init' && m.session_id) yield { kind: 'session', sessionId: m.session_id };\n break;\n\n case 'stream_event': {\n const ev = m.event;\n if (ev?.type === 'content_block_delta' && ev.delta?.type === 'text_delta' && ev.delta.text)\n yield { kind: 'text', text: ev.delta.text };\n break;\n }\n\n case 'assistant': {\n for (const block of m.message?.content ?? []) {\n if (block.type === 'tool_use' && !seenToolIds.has(block.id)) {\n seenToolIds.add(block.id);\n yield { kind: 'tool_start', toolName: block.name, toolInput: block.input, toolUseId: block.id };\n }\n }\n break;\n }\n\n case 'user': {\n for (const block of m.message?.content ?? []) {\n if (block.type === 'tool_result') {\n const content = Array.isArray(block.content)\n ? block.content.map((c: any) => (typeof c?.text === 'string' ? c.text : '')).join('\\n')\n : typeof block.content === 'string'\n ? block.content\n : '';\n yield {\n kind: 'tool_result',\n toolUseId: block.tool_use_id,\n result: content.slice(0, 4000),\n isError: Boolean(block.is_error),\n };\n }\n }\n break;\n }\n\n case 'result': {\n const u = m.usage ?? {};\n yield {\n kind: 'done',\n sessionId: m.session_id,\n text: typeof m.result === 'string' ? m.result : undefined,\n isError: m.subtype !== 'success',\n usage: {\n model: m.modelUsage ? Object.keys(m.modelUsage)[0] ?? resolveModel(req.modelTier) : resolveModel(req.modelTier),\n inputTokens: u.input_tokens ?? 0,\n outputTokens: u.output_tokens ?? 0,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n costUsd: m.total_cost_usd ?? 0,\n },\n };\n break;\n }\n\n default:\n break;\n }\n }\n } catch (err) {\n if (abort.signal.aborted) {\n yield { kind: 'error', message: 'Interrupted.' };\n return;\n }\n log.error('turn failed', err);\n yield { kind: 'error', message: err instanceof Error ? err.message : String(err) };\n }\n}\n", "import path from 'node:path';\nimport fs from 'node:fs';\nimport { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';\nimport { z } from 'zod';\nimport type { Store } from '../db/store.js';\nimport type { EventBus } from '../util/bus.js';\nimport type { PermissionGateway } from '../permissions/gateway.js';\nimport { runTurn, type TurnEvent } from '../agent/session.js';\nimport { buildSystemPrompt } from './prompt.js';\nimport { ensureMemoryDir } from '../memory/memory.js';\nimport { logger } from '../util/log.js';\nimport { LIMITS, type Bot, type Card, type TurnOrigin, type Settings } from '@antbot/shared';\nimport { newId } from '../util/ids.js';\nimport { describeSkillSource } from '../skills/install.js';\n\nconst log = logger('bots');\n\nexport interface TurnJob {\n id: string;\n botId: string;\n threadId: string;\n prompt: string;\n origin: TurnOrigin;\n hops: number;\n /** Priority: interactive turns run before routine turns (plan \u00A79). */\n priority: number;\n onDone?: (summary: string, ok: boolean) => void;\n}\n\nexport interface ManagerDeps {\n store: Store;\n bus: EventBus;\n gateway: PermissionGateway;\n workspace: string;\n getSettings: () => Settings;\n /**\n * Root of the local plugin carrying installed skills. A resolver rather than a value\n * because the skills subsystem is wired after the manager is constructed.\n */\n skillPluginPath?: () => string | undefined;\n /** Install a skill from a user-supplied source. Gated by the `install_skill` require-rule. */\n installSkill?: (\n source: string,\n opts?: { allowMultiple?: boolean },\n ) => Promise<Array<{ name: string; executables: string[] }>>;\n /** Every installed skill, so a bot can check before installing or removing. */\n listSkills?: () => Array<{ slug: string; name: string; description: string }>;\n /** Uninstall by slug. Gated by the `remove_skill` require-rule. */\n removeSkill?: (slug: string) => Promise<{ removed: boolean; name?: string }>;\n browserTools?: (botId: string) => ReturnType<typeof createSdkMcpServer> | undefined;\n}\n\nexport class BotManager {\n private queue: TurnJob[] = [];\n private running = new Map<string, { job: TurnJob; abort: AbortController }>();\n private draining = false;\n\n constructor(private deps: ManagerDeps) {}\n\n get runningCount(): number {\n return this.running.size;\n }\n get queuedCount(): number {\n return this.queue.length;\n }\n isBusy(botId: string): boolean {\n return this.running.has(botId) || this.queue.some((j) => j.botId === botId);\n }\n\n /** Enqueue a turn. Interactive work sorts ahead of routine work. */\n enqueue(job: Omit<TurnJob, 'id' | 'priority'> & { priority?: number }): TurnJob {\n const full: TurnJob = {\n ...job,\n id: newId(),\n priority: job.priority ?? (job.origin === 'routine' ? 10 : 0),\n };\n this.queue.push(full);\n this.queue.sort((a, b) => a.priority - b.priority);\n this.setState(full.botId, 'queued');\n void this.drain();\n return full;\n }\n\n private async drain(): Promise<void> {\n if (this.draining) return;\n this.draining = true;\n try {\n const max = this.deps.getSettings().maxConcurrentSessions ?? LIMITS.DEFAULT_MAX_CONCURRENT_SESSIONS;\n while (this.queue.length && this.running.size < max) {\n const idx = this.queue.findIndex((j) => !this.running.has(j.botId));\n if (idx === -1) break;\n const [job] = this.queue.splice(idx, 1);\n void this.execute(job!);\n }\n } finally {\n this.draining = false;\n }\n }\n\n private setState(botId: string, state: Bot['state'], attention?: Bot['attention']): void {\n const bot = this.deps.store.updateBot(botId, { state, ...(attention ? { attention } : {}) });\n if (!bot) return;\n this.deps.bus.publish({\n type: 'bot.state', botId, threadId: bot.threadId, state: bot.state, attention: bot.attention,\n });\n }\n\n interrupt(botId: string): boolean {\n const r = this.running.get(botId);\n this.queue = this.queue.filter((j) => j.botId !== botId);\n this.deps.gateway.cancelForBot(botId);\n if (!r) {\n this.setState(botId, 'idle');\n return false;\n }\n r.abort.abort();\n return true;\n }\n\n /** Custom tools exposed to every bot turn: handoff, memory, secrets-safe helpers. */\n private buildToolServer(bot: Bot, threadId: string, hops: number) {\n const { store, workspace } = this.deps;\n return createSdkMcpServer({\n name: 'antbot',\n version: '1.0.0',\n tools: [\n tool(\n 'send_to_bot',\n 'Hand work to another bot on this account. The recipient wakes, handles the request in its own thread, and can reply later. Use when the job genuinely belongs to that role.',\n { bot_slug: z.string().describe('slug of the teammate, e.g. \"writer\"'), message: z.string().describe('the request, with all context they need') },\n async (args: { bot_slug: string; message: string }) => {\n const target = store.getBotBySlug(args.bot_slug);\n if (!target) return { content: [{ type: 'text' as const, text: `No bot with slug \"${args.bot_slug}\". Use one of: ${store.listBots().map((b) => b.slug).join(', ')}` }] };\n if (target.id === bot.id) return { content: [{ type: 'text' as const, text: 'You cannot hand work to yourthis.' }] };\n if (hops + 1 > LIMITS.MAX_BOT_TO_BOT_HOPS)\n return { content: [{ type: 'text' as const, text: `Hop limit of ${LIMITS.MAX_BOT_TO_BOT_HOPS} reached. Stop and report back to the human instead.` }] };\n store.createMail({ fromBotId: bot.id, toBotId: target.id, contentMd: args.message, hops: hops + 1 });\n this.postSystemCard(threadId, bot.id, { type: 'handoff', fromBotId: bot.id, toBotId: target.id, note: args.message.slice(0, 300) });\n this.enqueue({\n botId: target.id, threadId: target.threadId!, origin: 'bot', hops: hops + 1,\n prompt: `**Handoff from @${bot.slug} (${bot.name}):**\\n\\n${args.message}\\n\\n---\\nHandle this, then reply. If it belongs to someone else, say so rather than guessing.`,\n });\n return { content: [{ type: 'text' as const, text: `Handed to @${target.slug}. They will pick it up and reply in their own thread.` }] };\n },\n ),\n tool(\n 'remember',\n 'Save a durable preference or fact to your memory so it survives future turns. Use only for stable things, never for changing data.',\n { title: z.string().describe('short kebab-case file name'), note: z.string().describe('the fact, in markdown') },\n async (args: { title: string; note: string }) => {\n const dir = ensureMemoryDir(workspace, bot.slug);\n const file = path.join(dir, `${args.title.replace(/[^a-zA-Z0-9._-]/g, '-')}.md`);\n fs.writeFileSync(file, args.note);\n return { content: [{ type: 'text' as const, text: `Saved to memory: ${path.basename(file)}` }] };\n },\n ),\n tool(\n 'list_skills',\n 'List every skill installed on this account, with its slug. Check here before installing ' +\n 'something that may already be present, and to find the exact slug to pass to remove_skill.',\n {},\n async () => {\n const skills = this.deps.listSkills?.() ?? [];\n if (!skills.length)\n return { content: [{ type: 'text' as const, text: 'No skills are installed.' }] };\n const lines = skills.map((sk) => `- ${sk.slug} \u2014 ${sk.name}${sk.description ? `: ${sk.description}` : ''}`);\n return { content: [{ type: 'text' as const, text: `${skills.length} skill(s) installed:\\n${lines.join('\\n')}` }] };\n },\n ),\n tool(\n 'install_skill',\n 'Install a skill so you (and other bots) can use it. This always stops for the human\\'s ' +\n 'approval first, because a skill is instructions that will steer future work and may ship scripts. ' +\n 'Check list_skills before installing something you already have.\\n' +\n 'Install the NARROWEST source that covers the request. Accepted forms:\\n' +\n ' github.com/owner/repo/tree/<ref>/<dir> one skill inside a repository \u2014 prefer this\\n' +\n ' https://host/path/SKILL.md one skill, direct link\\n' +\n ' ./path/to/skill a local directory\\n' +\n ' owner/repo, github.com/owner/repo EVERY skill in the repository\\n' +\n 'A bare owner/repo pointing at a collection installs all of it. If the human asked for one ' +\n 'named skill, point at that skill\\'s directory instead; if you only have a link to the repo ' +\n 'root, call this anyway and the error will list what is inside so you can narrow it.',\n {\n source: z.string().describe('prefer owner/repo/tree/<ref>/<dir> or a /SKILL.md link; owner/repo installs the whole repository'),\n reason: z.string().describe('why you need this skill for the task at hand'),\n install_all: z\n .boolean()\n .optional()\n .describe('set true only when the human has asked for every skill in a multi-skill source'),\n },\n async (args: { source: string; reason: string; install_all?: boolean }) => {\n if (!this.deps.installSkill)\n return { content: [{ type: 'text' as const, text: 'Skill installation is unavailable on this server.' }] };\n try {\n const installed = await this.deps.installSkill(args.source, { allowMultiple: args.install_all === true });\n if (!installed.length)\n return { content: [{ type: 'text' as const, text: `No skill found at \"${args.source}\".` }] };\n const names = installed.map((i) => i.name).join(', ');\n const scripts = installed.flatMap((i) => i.executables);\n const note = scripts.length\n ? ` Note for the human: this shipped ${scripts.length} script(s): ${scripts.join(', ')}.`\n : '';\n return {\n content: [{\n type: 'text' as const,\n text: `Installed: ${names}.${note} A skill must still be assigned to you in Bot settings ` +\n 'before you can invoke it \u2014 ask the human to enable it, then retry.',\n }],\n };\n } catch (err) {\n const e = err as Error & { name?: string; names?: string[] };\n if (e.name === 'MultipleSkillsError' && Array.isArray(e.names)) {\n const listed = e.names.slice(0, 40).join(', ');\n const more = e.names.length > 40 ? `, and ${e.names.length - 40} more` : '';\n return {\n content: [{\n type: 'text' as const,\n text:\n `Nothing was installed. \"${args.source}\" holds ${e.names.length} skills: ${listed}${more}.\\n` +\n 'Pick the one you need and install just it, e.g. ' +\n `${args.source.replace(/^https?:\\/\\//, '').replace(/\\/$/, '')}/tree/main/<skill-directory>. ` +\n 'Only pass install_all if the human has asked for all of them.',\n }],\n };\n }\n return { content: [{ type: 'text' as const, text: `Install failed: ${e.message}` }] };\n }\n },\n ),\n tool(\n 'remove_skill',\n 'Uninstall a skill by slug \u2014 deletes its directory and its registration together. ' +\n 'Use this rather than deleting skill directories with Bash, which would leave the ' +\n 'registry pointing at files that no longer exist. Stops for the human\\'s approval.',\n {\n slug: z.string().describe('the skill slug, exactly as list_skills reports it'),\n reason: z.string().describe('why this skill should be removed'),\n },\n async (args: { slug: string; reason: string }) => {\n if (!this.deps.removeSkill)\n return { content: [{ type: 'text' as const, text: 'Skill removal is unavailable on this server.' }] };\n try {\n const res = await this.deps.removeSkill(args.slug);\n if (!res.removed) {\n const known = (this.deps.listSkills?.() ?? []).map((sk) => sk.slug).join(', ');\n return { content: [{ type: 'text' as const, text: `No skill with slug \"${args.slug}\". Installed: ${known || 'none'}.` }] };\n }\n return { content: [{ type: 'text' as const, text: `Removed \"${args.slug}\"${res.name ? ` (${res.name})` : ''}.` }] };\n } catch (err) {\n return { content: [{ type: 'text' as const, text: `Remove failed: ${(err as Error).message}` }] };\n }\n },\n ),\n tool(\n 'request_secret',\n 'Ask the human for a secret value (API key, token). The value goes straight to the keychain and is never shown to you. Never ask for passwords in chat \u2014 ask for computer takeover instead.',\n { name: z.string().describe('identifier, e.g. STRIPE_API_KEY'), reason: z.string() },\n async (args: { name: string; reason: string }) => {\n this.deps.bus.publish({ type: 'secret.request', botId: bot.id, threadId, requestId: newId(), name: args.name, reason: args.reason });\n return { content: [{ type: 'text' as const, text: `Asked the human for \"${args.name}\". It will be injected into your environment as that variable name; you will never see the value. Continue once they confirm.` }] };\n },\n ),\n ],\n });\n }\n\n private postSystemCard(threadId: string, botId: string, card: Card): void {\n const msg = this.deps.store.createMessage({ threadId, authorKind: 'system', authorBotId: botId, cards: [card] });\n this.deps.bus.publish({ type: 'message.created', threadId, botId, message: msg });\n }\n\n private async execute(job: TurnJob): Promise<void> {\n const { store, bus, gateway, workspace, getSettings } = this.deps;\n const bot = store.getBot(job.botId);\n if (!bot) return;\n\n const abort = new AbortController();\n this.running.set(job.botId, { job, abort });\n this.setState(job.botId, 'running', 'none');\n\n const settings = getSettings();\n const msg = store.createMessage({\n threadId: job.threadId, authorKind: 'bot', authorBotId: bot.id, contentMd: '', streaming: true,\n });\n bus.publish({ type: 'message.created', threadId: job.threadId, botId: bot.id, message: msg });\n\n const thread = store.getThread(job.threadId);\n const isGroup = thread?.kind === 'group';\n const botDir = path.join(workspace, 'bots', bot.slug);\n fs.mkdirSync(botDir, { recursive: true });\n\n const botSkills = store.listBotSkills(bot.id);\n const systemPrompt = buildSystemPrompt({\n bot, workspace, skills: botSkills,\n roster: store.listBots().map((x) => ({ slug: x.slug, name: x.name, title: x.title })),\n isGroup,\n });\n\n let text = '';\n let ok = true;\n let errorMessage = '';\n const toolCards = new Map<string, number>();\n\n const mcpServers: Record<string, any> = { antbot: this.buildToolServer(bot, job.threadId, job.hops) };\n const browser = this.deps.browserTools?.(bot.id);\n if (browser) mcpServers.browser = browser;\n\n try {\n for await (const ev of runTurn({\n prompt: job.prompt,\n resumeSessionId: bot.sessionId,\n modelTier: bot.modelTier,\n systemPrompt,\n cwd: workspace,\n settings,\n abortController: abort,\n mcpServers,\n skillPluginPath: this.deps.skillPluginPath?.(),\n // Skill names come from SKILL.md frontmatter, which is what the SDK matches on.\n enabledSkills: botSkills.map((s) => s.name),\n canUseTool: async (toolName, input) => {\n // Tools we provide ourselves are already scoped; the gateway still sees them.\n this.setState(job.botId, 'waiting_approval', 'needs_attention');\n const d = await gateway.check({\n botId: bot.id, threadId: job.threadId, toolName, input,\n botDescription: bot.description, settings, signal: abort.signal,\n workspace,\n // Render the approval inline in the transcript so the human can act on it\n // where the work is happening, not only in a global queue.\n onPending: (approval) => {\n const card: Card = { type: 'approval', approvalId: approval.id };\n const idx = store.appendCard(msg.id, card);\n bus.publish({\n type: 'message.card', threadId: job.threadId, botId: bot.id,\n messageId: msg.id, card, cardIndex: idx,\n });\n },\n });\n if (!abort.signal.aborted) this.setState(job.botId, 'running');\n return d.behavior === 'allow'\n ? { behavior: 'allow', updatedInput: input }\n : { behavior: 'deny', message: d.message };\n },\n })) {\n await this.applyEvent(ev, { job, bot, msgId: msg.id, toolCards });\n if (ev.kind === 'text' && ev.text) text += ev.text;\n if (ev.kind === 'done') {\n if (ev.text && !text.trim()) text = ev.text;\n ok = !ev.isError;\n }\n if (ev.kind === 'error') {\n ok = false;\n errorMessage = ev.message ?? 'Unknown error';\n }\n }\n } catch (err) {\n ok = false;\n errorMessage = err instanceof Error ? err.message : String(err);\n log.error('turn crashed', err);\n } finally {\n this.running.delete(job.botId);\n }\n\n if (errorMessage) {\n const idx = store.appendCard(msg.id, { type: 'error', message: errorMessage });\n bus.publish({ type: 'message.card', threadId: job.threadId, botId: bot.id, messageId: msg.id, card: { type: 'error', message: errorMessage }, cardIndex: idx });\n }\n\n const final = text.trim();\n store.updateMessage(msg.id, { contentMd: final, streaming: false });\n bus.publish({ type: 'message.done', threadId: job.threadId, botId: bot.id, messageId: msg.id, contentMd: final });\n\n const interrupted = abort.signal.aborted;\n this.setState(job.botId, interrupted ? 'interrupted' : 'idle', 'unread');\n if (interrupted) this.setState(job.botId, 'idle', 'unread');\n\n job.onDone?.(final || errorMessage, ok && !interrupted);\n void this.drain();\n }\n\n private async applyEvent(\n ev: TurnEvent,\n ctx: { job: TurnJob; bot: Bot; msgId: string; toolCards: Map<string, number> },\n ): Promise<void> {\n const { store, bus } = this.deps;\n const { job, bot, msgId, toolCards } = ctx;\n\n switch (ev.kind) {\n case 'session':\n if (ev.sessionId) store.updateBot(bot.id, { sessionId: ev.sessionId });\n break;\n\n case 'text':\n if (ev.text) {\n const cur = store.getMessage(msgId);\n store.updateMessage(msgId, { contentMd: (cur?.contentMd ?? '') + ev.text });\n bus.publish({ type: 'message.delta', threadId: job.threadId, botId: bot.id, messageId: msgId, delta: ev.text });\n }\n break;\n\n case 'tool_start': {\n const card: Card = {\n type: 'tool', toolName: ev.toolName ?? 'tool',\n summary: summarizeTool(ev.toolName ?? '', ev.toolInput),\n input: ev.toolInput, status: 'running',\n };\n const idx = store.appendCard(msgId, card);\n if (ev.toolUseId) toolCards.set(ev.toolUseId, idx);\n bus.publish({ type: 'message.card', threadId: job.threadId, botId: bot.id, messageId: msgId, card, cardIndex: idx });\n break;\n }\n\n case 'tool_result': {\n const idx = ev.toolUseId ? toolCards.get(ev.toolUseId) : undefined;\n if (idx === undefined) break;\n const cur = store.getMessage(msgId);\n const existing = cur?.cards[idx];\n if (!existing || existing.type !== 'tool') break;\n const denied = ev.isError && /denied|approval/i.test(ev.result ?? '');\n const card: Card = {\n ...existing,\n status: denied ? 'denied' : ev.isError ? 'error' : 'ok',\n result: (ev.result ?? '').slice(0, 2000),\n };\n store.updateCard(msgId, idx, card);\n bus.publish({ type: 'message.card', threadId: job.threadId, botId: bot.id, messageId: msgId, card, cardIndex: idx });\n break;\n }\n\n case 'done':\n if (ev.sessionId) store.updateBot(bot.id, { sessionId: ev.sessionId });\n if (ev.usage) {\n store.recordUsage({\n botId: bot.id, turnId: job.id, model: ev.usage.model,\n inputTokens: ev.usage.inputTokens, outputTokens: ev.usage.outputTokens,\n cacheReadTokens: ev.usage.cacheReadTokens, costEstimate: ev.usage.costUsd,\n });\n bus.publish({\n type: 'usage.tick', threadId: job.threadId, botId: bot.id,\n inputTokens: ev.usage.inputTokens, outputTokens: ev.usage.outputTokens, model: ev.usage.model,\n });\n }\n break;\n\n default:\n break;\n }\n }\n}\n\nexport function summarizeTool(name: string, input: unknown): string {\n const o = (input ?? {}) as Record<string, unknown>;\n const s = (k: string): string => (typeof o[k] === 'string' ? (o[k] as string) : '');\n if (name === 'Bash') return s('command').slice(0, 160);\n if (name === 'Read' || name === 'Write' || name === 'Edit') return s('file_path');\n if (name === 'WebFetch') return s('url');\n if (name.includes('send_to_bot')) return `\u2192 @${s('bot_slug')}`;\n if (name.includes('install_skill')) return describeSkillSource(s('source'));\n if (name.includes('remove_skill')) return `remove skill: ${s('slug')}`;\n if (name.includes('list_skills')) return 'list installed skills';\n if (name.includes('remember')) return `memory: ${s('title')}`;\n if (name.startsWith('browser_') || name.includes('browser')) return [s('url'), s('selector'), s('text')].filter(Boolean).join(' ').slice(0, 160);\n const j = JSON.stringify(input ?? {});\n return j.length > 160 ? `${j.slice(0, 160)}\u2026` : j;\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\n\n/** Per-bot memory lives as markdown on the shared computer: workspace/bots/<slug>/memory/*.md */\nexport function memoryDir(workspace: string, slug: string): string {\n return path.join(workspace, 'bots', slug, 'memory');\n}\n\nexport function ensureMemoryDir(workspace: string, slug: string): string {\n const dir = memoryDir(workspace, slug);\n fs.mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport interface MemoryFile { name: string; content: string }\n\nexport function readMemory(workspace: string, slug: string): MemoryFile[] {\n const dir = memoryDir(workspace, slug);\n if (!fs.existsSync(dir)) return [];\n return fs\n .readdirSync(dir)\n .filter((f) => f.endsWith('.md'))\n .sort()\n .map((name) => ({ name, content: fs.readFileSync(path.join(dir, name), 'utf8') }));\n}\n\nexport function writeMemory(workspace: string, slug: string, name: string, content: string): void {\n const dir = ensureMemoryDir(workspace, slug);\n const safe = name.replace(/[^a-zA-Z0-9._-]/g, '-');\n fs.writeFileSync(path.join(dir, safe.endsWith('.md') ? safe : `${safe}.md`), content);\n}\n\nexport function deleteMemory(workspace: string, slug: string, name: string): void {\n const f = path.join(memoryDir(workspace, slug), name.replace(/[^a-zA-Z0-9._-]/g, '-'));\n if (fs.existsSync(f)) fs.unlinkSync(f);\n}\n\nexport function renderMemoryBlock(files: MemoryFile[]): string {\n if (!files.length) return '';\n const body = files.map((f) => `### ${f.name}\\n${f.content.trim()}`).join('\\n\\n');\n return `\\n\\n## Your memory\\nStable preferences and facts you recorded earlier. Memory is a working\\nnote, not an authoritative source \u2014 re-check the source system before any\\nconsequential decision.\\n\\n${body}`;\n}\n", "import type { Bot, Skill } from '@antbot/shared';\nimport { readMemory, renderMemoryBlock } from '../memory/memory.js';\n\nexport interface PromptContext {\n bot: Bot;\n workspace: string;\n skills: Skill[];\n roster: Array<{ slug: string; name: string; title: string }>;\n isGroup: boolean;\n groupMembers?: string[];\n}\n\n/**\n * System prompt = base teammate persona + bot profile + memory + roster + boundaries.\n * The description carries standing rules; the conversation carries task instructions\n * (the durable/ephemeral split from outline \u00A74).\n */\nexport function buildSystemPrompt(ctx: PromptContext): string {\n const { bot, workspace } = ctx;\n const parts: string[] = [];\n\n parts.push(`You are **${bot.name}**${bot.title ? `, ${bot.title}` : ''} \u2014 a persistent AI teammate in ant-bot.\n\nYou are not a general chat assistant. You own a job and finish work end to end,\nthen report back with evidence. You keep working across turns; your files,\nmemory and browser sessions persist.`);\n\n if (bot.description.trim()) {\n parts.push(`## Your standing job description\nThese are durable rules for how you work. They outrank any single message.\n\n${bot.description.trim()}`);\n }\n\n parts.push(`## Your computer\nYou share one computer with every other bot on this account.\n- Shared workspace: \\`${workspace}\\` \u2014 keep durable project files here.\n- Your own folder: \\`${workspace}/bots/${bot.slug}/\\`\n- Files, logins and installed tools are visible to all bots. Bots are **not** a\n security boundary. Do not store anything here another bot should not see.`);\n\n const mem = renderMemoryBlock(readMemory(workspace, bot.slug));\n if (mem) parts.push(mem.trim());\n\n if (ctx.skills.length) {\n parts.push(`## Your skills\n${ctx.skills.map((s) => `- **${s.name}** (${s.slug}): ${s.description}`).join('\\n')}\nRead the skill file before following it.`);\n }\n\n const others = ctx.roster.filter((r) => r.slug !== bot.slug);\n if (others.length) {\n parts.push(`## Your teammates\n${others.map((r) => `- @${r.slug} \u2014 ${r.name}${r.title ? `, ${r.title}` : ''}`).join('\\n')}\n\nUse the \\`send_to_bot\\` tool to hand work to a teammate when the job genuinely\nbelongs to their role. Keep one owner per stage \u2014 do not fan the same task out\nto several bots at once.`);\n }\n\n if (ctx.isGroup) {\n parts.push(`## Group conversation\nYou are in a group chat. Other bots can see and reply to these messages.\nAnswer only when the request is yours to own, or when you were @-mentioned.\nSay who should take the next step. Keep replies short \u2014 the humans are reading.`);\n }\n\n parts.push(`## How to work\n- Lead with the result. Put evidence \u2014 links, file paths, quoted output \u2014 under it.\n- Separate: facts found, assumptions, actions taken, actions awaiting approval,\n open questions.\n- Write deliverables as real files in the workspace, not as walls of chat text.\n- Never guess at a credential. If a step needs a password, 2FA code or CAPTCHA,\n stop and ask the human to take over the computer.\n- Some actions pause for the human's approval. That is normal \u2014 propose the\n action and wait. Approval covers only the proposed step; it does not undo\n anything you already did.`);\n\n return parts.join('\\n\\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", "import fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { logger } from '../util/log.js';\n\nconst exec = promisify(execFile);\nconst log = logger('secrets');\n\nexport interface SecretBackend {\n readonly name: string;\n set(key: string, value: string): Promise<void>;\n get(key: string): Promise<string | null>;\n delete(key: string): Promise<void>;\n list(): Promise<string[]>;\n}\n\nconst SERVICE = 'ant-bot';\n\n/** libsecret on Linux via `secret-tool`. */\nclass SecretToolBackend implements SecretBackend {\n readonly name = 'libsecret (secret-tool)';\n async set(key: string, value: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const p = execFile('secret-tool', ['store', '--label', `${SERVICE}: ${key}`, 'service', SERVICE, 'account', key],\n (err) => (err ? reject(err) : resolve()));\n p.stdin?.end(value);\n });\n }\n async get(key: string): Promise<string | null> {\n try {\n const { stdout } = await exec('secret-tool', ['lookup', 'service', SERVICE, 'account', key]);\n return stdout;\n } catch {\n return null;\n }\n }\n async delete(key: string): Promise<void> {\n try { await exec('secret-tool', ['clear', 'service', SERVICE, 'account', key]); } catch { /* absent */ }\n }\n async list(): Promise<string[]> { return []; } // secret-tool has no reliable enumeration\n}\n\n/** macOS Keychain via `security`. */\nclass MacKeychainBackend implements SecretBackend {\n readonly name = 'macOS Keychain';\n async set(key: string, value: string): Promise<void> {\n await exec('security', ['add-generic-password', '-U', '-s', SERVICE, '-a', key, '-w', value]);\n }\n async get(key: string): Promise<string | null> {\n try {\n const { stdout } = await exec('security', ['find-generic-password', '-s', SERVICE, '-a', key, '-w']);\n return stdout.replace(/\\n$/, '');\n } catch {\n return null;\n }\n }\n async delete(key: string): Promise<void> {\n try { await exec('security', ['delete-generic-password', '-s', SERVICE, '-a', key]); } catch { /* absent */ }\n }\n async list(): Promise<string[]> { return []; }\n}\n\n/**\n * Encrypted-file fallback. Explicitly weaker than an OS keychain: the key is derived\n * from a machine-local file with 0600 permissions, so anything running as this user\n * can read it. Surfaced in the UI as such.\n */\nexport class EncryptedFileBackend implements SecretBackend {\n readonly name = 'encrypted file (weaker than a system keychain)';\n private keyFile: string;\n constructor(private file: string) {\n this.keyFile = `${file}.key`;\n }\n private key(): Buffer {\n if (!fs.existsSync(this.keyFile)) {\n fs.mkdirSync(path.dirname(this.keyFile), { recursive: true });\n fs.writeFileSync(this.keyFile, crypto.randomBytes(32), { mode: 0o600 });\n }\n return fs.readFileSync(this.keyFile);\n }\n private read(): Record<string, string> {\n if (!fs.existsSync(this.file)) return {};\n try {\n const raw = JSON.parse(fs.readFileSync(this.file, 'utf8')) as Record<string, { iv: string; tag: string; data: string }>;\n const key = this.key();\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(raw)) {\n const d = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(v.iv, 'base64'));\n d.setAuthTag(Buffer.from(v.tag, 'base64'));\n out[k] = Buffer.concat([d.update(Buffer.from(v.data, 'base64')), d.final()]).toString('utf8');\n }\n return out;\n } catch {\n return {};\n }\n }\n private write(values: Record<string, string>): void {\n const key = this.key();\n const out: Record<string, { iv: string; tag: string; data: string }> = {};\n for (const [k, v] of Object.entries(values)) {\n const iv = crypto.randomBytes(12);\n const c = crypto.createCipheriv('aes-256-gcm', key, iv);\n const data = Buffer.concat([c.update(v, 'utf8'), c.final()]);\n out[k] = { iv: iv.toString('base64'), tag: c.getAuthTag().toString('base64'), data: data.toString('base64') };\n }\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n fs.writeFileSync(this.file, JSON.stringify(out), { mode: 0o600 });\n }\n async set(key: string, value: string): Promise<void> { const v = this.read(); v[key] = value; this.write(v); }\n async get(key: string): Promise<string | null> { return this.read()[key] ?? null; }\n async delete(key: string): Promise<void> { const v = this.read(); delete v[key]; this.write(v); }\n async list(): Promise<string[]> { return Object.keys(this.read()); }\n}\n\nexport async function pickBackend(fallbackFile: string): Promise<SecretBackend> {\n const has = async (bin: string, args: string[]): Promise<boolean> => {\n try { await exec(bin, args); return true; } catch (err) {\n return (err as { code?: string }).code !== 'ENOENT';\n }\n };\n if (process.platform === 'darwin' && (await has('security', ['-h']))) return new MacKeychainBackend();\n if (process.platform === 'linux' && (await has('secret-tool', ['--version']))) return new SecretToolBackend();\n log.warn('no system keychain available; using the encrypted-file fallback');\n return new EncryptedFileBackend(fallbackFile);\n}\n\n/**\n * Secrets are stored by NAME only in the index; values live in the backend and are\n * injected into tool environments. A value is never written to the transcript and is\n * never placed in the model's context (outline \u00A75, \"secure secret request\").\n */\nexport class SecretsService {\n private names = new Set<string>();\n constructor(\n private backend: SecretBackend,\n private indexFile: string,\n ) {\n if (fs.existsSync(indexFile)) {\n try { this.names = new Set(JSON.parse(fs.readFileSync(indexFile, 'utf8')) as string[]); } catch { /* ignore */ }\n }\n }\n private persist(): void {\n fs.mkdirSync(path.dirname(this.indexFile), { recursive: true });\n fs.writeFileSync(this.indexFile, JSON.stringify([...this.names]), { mode: 0o600 });\n }\n get backendName(): string { return this.backend.name; }\n async set(name: string, value: string): Promise<void> {\n await this.backend.set(name, value);\n this.names.add(name);\n this.persist();\n }\n async remove(name: string): Promise<void> {\n await this.backend.delete(name);\n this.names.delete(name);\n this.persist();\n }\n /** Names only \u2014 values are never returned to the API surface. */\n list(): string[] { return [...this.names]; }\n /** Build an env overlay for a tool subprocess. Values never touch the transcript. */\n async envOverlay(): Promise<Record<string, string>> {\n const out: Record<string, string> = {};\n for (const n of this.names) {\n const v = await this.backend.get(n);\n if (v !== null) out[n] = v;\n }\n return out;\n }\n}\n", "import { query } from '@anthropic-ai/claude-agent-sdk';\nimport { buildEnv } from '../agent/session.js';\nimport type { Settings, Bot } from '@antbot/shared';\nimport { logger } from '../util/log.js';\n\nconst log = logger('groups');\n\n/**\n * Pick which bots should answer a group message.\n * Explicit @-mentions always win; otherwise a cheap Haiku pass routes it.\n * Falls back to the first member so a group is never silent.\n */\nexport async function routeGroupMessage(args: {\n text: string;\n members: Bot[];\n mentionBotIds?: string[];\n mentionEveryone?: boolean;\n settings: Settings;\n cwd: string;\n}): Promise<Bot[]> {\n const { text, members, mentionBotIds, mentionEveryone, settings, cwd } = args;\n if (mentionEveryone) return members;\n if (mentionBotIds?.length) {\n const picked = members.filter((m) => mentionBotIds.includes(m.id));\n if (picked.length) return picked;\n }\n\n const inline = members.filter((m) => new RegExp(`@${m.slug}\\\\b`, 'i').test(text));\n if (inline.length) return inline;\n\n try {\n const roster = members.map((m) => `- ${m.slug}: ${m.name}${m.title ? `, ${m.title}` : ''}. ${m.description.slice(0, 200)}`).join('\\n');\n const q = query({\n prompt: `Team:\\n${roster}\\n\\nMessage:\\n${text.slice(0, 2000)}\\n\\nWhich single teammate should own this? Reply with only the slug.`,\n options: {\n model: 'haiku',\n systemPrompt: 'You route work to the right teammate. Reply with exactly one slug from the list and nothing else.',\n cwd, settingSources: [], env: buildEnv(settings), maxTurns: 1, allowedTools: [],\n },\n });\n let out = '';\n for await (const m of q) {\n const msg = m as Record<string, any>;\n if (msg.type === 'result' && typeof msg.result === 'string') out = msg.result;\n }\n const slug = out.trim().toLowerCase().replace(/[^a-z0-9-]/g, '');\n const found = members.find((m) => m.slug === slug);\n if (found) return [found];\n } catch (err) {\n log.warn('group router failed; defaulting to first member', err);\n }\n return members.slice(0, 1);\n}\n\n/** Extract @slug mentions from raw composer text. */\nexport function parseMentions(text: string, members: Bot[]): { botIds: string[]; everyone: boolean } {\n const everyone = /@everyone\\b/i.test(text);\n const botIds = members.filter((m) => new RegExp(`@${m.slug}\\\\b`, 'i').test(text)).map((m) => m.id);\n return { botIds, everyone };\n}\n", "import type { FastifyInstance } from 'fastify';\nimport type { App } from '../app.js';\nimport {\n CreateBotRequest, UpdateBotRequest, CreateThreadRequest, PostMessageRequest,\n LimitError, type RosterEntry, type ThreadWithMessages,\n} from '@antbot/shared';\nimport { routeGroupMessage, parseMentions } from '../bots/groups.js';\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { readPackageVersion } from '../util/locate.js';\nimport { readMemory, writeMemory, deleteMemory } from '../memory/memory.js';\n\n// Read from package.json rather than hardcoded, so a release bump cannot leave /api/health\n// claiming a version the CLI disagrees with.\nexport const SERVER_VERSION = readPackageVersion(\n path.dirname(fileURLToPath(import.meta.url)),\n (p) => fs.existsSync(p),\n (p) => fs.readFileSync(p, 'utf8'),\n);\n\nexport function registerCoreRoutes(f: FastifyInstance, app: App): void {\n const { store, bus, manager } = app;\n\n f.get('/api/health', async () => ({\n ok: true,\n seq: bus.currentSeq,\n version: SERVER_VERSION,\n bots: store.listBots().length,\n }));\n\n /* ------------------------------- bots ------------------------------- */\n f.get('/api/bots', async (): Promise<RosterEntry[]> =>\n store.listBots().map((bot) => ({\n bot,\n thread: bot.threadId ? store.getThread(bot.threadId) : null,\n lastMessageAt: bot.threadId ? store.lastMessageAt(bot.threadId) : 0,\n })),\n );\n\n f.post('/api/bots', async (req, reply) => {\n const parsed = CreateBotRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: parsed.error.issues[0]?.message ?? 'Invalid body' });\n try {\n return store.createBot(parsed.data);\n } catch (err) {\n if (err instanceof LimitError) return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n f.get<{ Params: { id: string } }>('/api/bots/:id', async (req, reply) => {\n const bot = store.getBot(req.params.id);\n return bot ?? reply.code(404).send({ error: 'No such bot' });\n });\n\n f.patch<{ Params: { id: string } }>('/api/bots/:id', async (req, reply) => {\n const parsed = UpdateBotRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n const bot = store.updateBot(req.params.id, parsed.data);\n if (!bot) return reply.code(404).send({ error: 'No such bot' });\n bus.publish({ type: 'bot.state', botId: bot.id, threadId: bot.threadId, state: bot.state, attention: bot.attention });\n return bot;\n });\n\n f.delete<{ Params: { id: string } }>('/api/bots/:id', async (req, reply) => {\n if (!store.getBot(req.params.id)) return reply.code(404).send({ error: 'No such bot' });\n manager.interrupt(req.params.id);\n store.deleteBot(req.params.id);\n return { ok: true };\n });\n\n f.post<{ Params: { id: string } }>('/api/bots/:id/duplicate', async (req, reply) => {\n try {\n const copy = store.duplicateBot(req.params.id);\n return copy ?? reply.code(404).send({ error: 'No such bot' });\n } catch (err) {\n if (err instanceof LimitError) return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n f.post<{ Params: { id: string } }>('/api/bots/:id/stop', async (req) => ({\n stopped: manager.interrupt(req.params.id),\n }));\n\n /* ------------------------------ memory ------------------------------ */\n f.get<{ Params: { id: string } }>('/api/bots/:id/memory', async (req, reply) => {\n const bot = store.getBot(req.params.id);\n if (!bot) return reply.code(404).send({ error: 'No such bot' });\n return readMemory(app.cfg.paths.workspace, bot.slug);\n });\n\n f.put<{ Params: { id: string }; Body: { name: string; content: string } }>('/api/bots/:id/memory', async (req, reply) => {\n const bot = store.getBot(req.params.id);\n if (!bot) return reply.code(404).send({ error: 'No such bot' });\n const { name, content } = req.body ?? {};\n if (!name || typeof content !== 'string') return reply.code(400).send({ error: 'name and content are required' });\n writeMemory(app.cfg.paths.workspace, bot.slug, name, content);\n return { ok: true };\n });\n\n f.delete<{ Params: { id: string; name: string } }>('/api/bots/:id/memory/:name', async (req, reply) => {\n const bot = store.getBot(req.params.id);\n if (!bot) return reply.code(404).send({ error: 'No such bot' });\n deleteMemory(app.cfg.paths.workspace, bot.slug, req.params.name);\n return { ok: true };\n });\n\n f.get<{ Params: { id: string } }>('/api/bots/:id/skills', async (req, reply) => {\n if (!store.getBot(req.params.id)) return reply.code(404).send({ error: 'No such bot' });\n return store.listBotSkills(req.params.id);\n });\n\n f.put<{ Params: { id: string }; Body: { skillIds: string[] } }>('/api/bots/:id/skills', async (req, reply) => {\n if (!store.getBot(req.params.id)) return reply.code(404).send({ error: 'No such bot' });\n store.setBotSkills(req.params.id, req.body?.skillIds ?? []);\n return { ok: true };\n });\n\n /* ----------------------------- threads ------------------------------ */\n f.get('/api/threads', async () => store.listThreads());\n\n f.post('/api/threads', async (req, reply) => {\n const parsed = CreateThreadRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n try {\n const members = parsed.data.memberBotIds.map((id) => store.getBot(id)).filter(Boolean);\n if (members.length !== parsed.data.memberBotIds.length)\n return reply.code(400).send({ error: 'One or more bots do not exist' });\n const title = parsed.data.title || members.map((m) => m!.name).join(', ');\n return store.createThread({ ...parsed.data, title });\n } catch (err) {\n if (err instanceof LimitError) return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n f.get<{ Params: { id: string } }>('/api/threads/:id', async (req, reply) => {\n const thread = store.getThread(req.params.id);\n if (!thread) return reply.code(404).send({ error: 'No such thread' });\n const payload: ThreadWithMessages = { thread, messages: store.listMessages(thread.id) };\n return payload;\n });\n\n f.delete<{ Params: { id: string } }>('/api/threads/:id', async (req) => {\n store.deleteThread(req.params.id);\n return { ok: true };\n });\n\n f.post<{ Params: { id: string } }>('/api/threads/:id/read', async (req, reply) => {\n const thread = store.getThread(req.params.id);\n if (!thread) return reply.code(404).send({ error: 'No such thread' });\n store.updateThread(thread.id, { lastReadAt: Date.now() });\n for (const id of thread.memberBotIds) {\n const bot = store.getBot(id);\n if (bot && bot.attention !== 'needs_attention') {\n store.updateBot(id, { attention: 'none' });\n bus.publish({ type: 'bot.state', botId: id, threadId: thread.id, state: bot.state, attention: 'none' });\n }\n }\n return { ok: true };\n });\n\n /* ----------------------------- messages ----------------------------- */\n f.post<{ Params: { id: string } }>('/api/threads/:id/messages', async (req, reply) => {\n const parsed = PostMessageRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n const thread = store.getThread(req.params.id);\n if (!thread) return reply.code(404).send({ error: 'No such thread' });\n\n app.lastUserActivity.at = Date.now();\n\n const msg = store.createMessage({\n threadId: thread.id, authorKind: 'user', contentMd: parsed.data.contentMd,\n replyToId: parsed.data.replyToId ?? null,\n });\n if (parsed.data.attachmentIds?.length) {\n try {\n store.attachToMessage(parsed.data.attachmentIds, msg.id);\n } catch (err) {\n if (err instanceof LimitError) return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n }\n bus.publish({ type: 'message.created', threadId: thread.id, botId: null, message: store.getMessage(msg.id)! });\n\n const attachments = store.listAttachmentsForMessage(msg.id);\n const attachNote = attachments.length\n ? `\\n\\nAttached files (read them from disk):\\n${attachments.map((a) => `- ${a.name} \u2192 ${a.path}`).join('\\n')}`\n : '';\n const prompt = parsed.data.contentMd + attachNote;\n\n const members = thread.memberBotIds.map((id) => store.getBot(id)).filter(Boolean) as NonNullable<ReturnType<typeof store.getBot>>[];\n if (!members.length) return msg;\n\n if (thread.kind === 'dm') {\n manager.enqueue({ botId: members[0]!.id, threadId: thread.id, prompt, origin: 'user', hops: 0 });\n } else {\n const inline = parseMentions(parsed.data.contentMd, members);\n const targets = await routeGroupMessage({\n text: parsed.data.contentMd,\n members,\n mentionBotIds: parsed.data.mentionBotIds ?? inline.botIds,\n mentionEveryone: parsed.data.mentionEveryone ?? inline.everyone,\n settings: app.getSettings(),\n cwd: app.cfg.paths.workspace,\n });\n for (const t of targets)\n manager.enqueue({ botId: t.id, threadId: thread.id, prompt, origin: 'user', hops: 0 });\n }\n return msg;\n });\n}\n", "import fs from 'node:fs';\nimport path from 'node:path';\nimport type { FastifyInstance } from 'fastify';\nimport type { App } from '../app.js';\nimport { workspaceRelative } from '../app.js';\nimport {\n ApprovalDecisionRequest, CreateRuleRequest, CreateRoutineRequest, CreateSkillRequest,\n SettingsPatchSchema, LimitError, type UsageSummary, type SearchResult,\n} from '@antbot/shared';\n\nexport function registerOpsRoutes(f: FastifyInstance, app: App): void {\n const { store, gateway, bus } = app;\n\n /* ---------------------------- approvals ---------------------------- */\n f.get('/api/approvals', async () => store.listPendingApprovals());\n\n f.post<{ Params: { id: string } }>('/api/approvals/:id', async (req, reply) => {\n const parsed = ApprovalDecisionRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n const updated = gateway.decide(req.params.id, parsed.data.decision, parsed.data.alwaysRule);\n return updated ?? reply.code(404).send({ error: 'No such approval' });\n });\n\n /* ------------------------------ rules ------------------------------ */\n f.get('/api/rules', async () => store.listRules());\n\n f.post('/api/rules', async (req, reply) => {\n const parsed = CreateRuleRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n try {\n new RegExp(parsed.data.inputPattern || '');\n } catch {\n return reply.code(400).send({ error: 'inputPattern is not a valid regular expression' });\n }\n return store.createRule(parsed.data);\n });\n\n f.patch<{ Params: { id: string }; Body: { enabled: boolean } }>('/api/rules/:id', async (req, reply) => {\n const rule = store.getRule(req.params.id);\n if (!rule) return reply.code(404).send({ error: 'No such rule' });\n store.setRuleEnabled(rule.id, Boolean(req.body?.enabled));\n return store.getRule(rule.id);\n });\n\n f.delete<{ Params: { id: string } }>('/api/rules/:id', async (req, reply) => {\n const rule = store.getRule(req.params.id);\n if (!rule) return reply.code(404).send({ error: 'No such rule' });\n if (rule.builtin) return reply.code(400).send({ error: 'Built-in rules cannot be deleted; disable it instead.' });\n store.deleteRule(rule.id);\n return { ok: true };\n });\n\n /* ------------------------------ skills ----------------------------- */\n f.get('/api/skills', async () => store.listSkills());\n\n f.post('/api/skills', async (req, reply) => {\n const parsed = CreateSkillRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n if (!app.skills?.writeSkill) return reply.code(503).send({ error: 'Skills subsystem unavailable' });\n return app.skills.writeSkill(parsed.data);\n });\n\n // Install from a source (git repo, local path, or a raw SKILL.md URL). This is the\n // simple path: no hand-built JSON body, just the source string.\n f.post<{ Body: { source?: string } }>('/api/skills/install', async (req, reply) => {\n const source = (req.body?.source ?? '').trim();\n if (!source) return reply.code(400).send({ error: 'A \"source\" is required' });\n if (!app.skills?.installFromSource) return reply.code(503).send({ error: 'Skills subsystem unavailable' });\n try {\n // A human typing `antbot skill add owner/repo` is asking for that repository, whatever\n // it holds; the multi-skill guard exists for bots choosing a source on their own.\n const installed = await app.skills.installFromSource(source, { allowMultiple: true });\n return {\n installed: installed.map((i: { skill: unknown; executables: string[]; manifestText: string; replaced: boolean }) => ({\n skill: i.skill,\n executables: i.executables,\n manifest: i.manifestText,\n replaced: i.replaced,\n })),\n };\n } catch (err) {\n return reply.code(400).send({ error: (err as Error).message });\n }\n });\n\n f.get<{ Params: { id: string } }>('/api/skills/:id', async (req, reply) => {\n const skill = store.getSkill(req.params.id);\n if (!skill) return reply.code(404).send({ error: 'No such skill' });\n if (app.skills?.readSkill) return app.skills.readSkill(skill.id);\n return { ...skill, bodyMd: '' };\n });\n\n f.delete<{ Params: { id: string } }>('/api/skills/:id', async (req, reply) => {\n const skill = store.getSkill(req.params.id);\n if (!skill) return reply.code(404).send({ error: 'No such skill' });\n if (app.skills?.deleteSkill) app.skills.deleteSkill(skill.id);\n else store.deleteSkill(skill.id);\n return { ok: true };\n });\n\n /* ------------------------- secrets (WP-2.4) ------------------------ */\n // Values go straight to the OS keychain. Only NAMES are ever returned here, and a\n // value is never written to a transcript or placed in the model's context.\n f.get('/api/secrets', async () => ({\n backend: app.secrets?.backendName ?? 'unavailable',\n names: app.secrets?.list() ?? [],\n }));\n\n f.post<{ Body: { name?: string; value?: string } }>('/api/secrets', async (req, reply) => {\n if (!app.secrets) return reply.code(503).send({ error: 'Secrets backend unavailable' });\n const name = (req.body?.name ?? '').trim();\n const value = req.body?.value ?? '';\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))\n return reply.code(400).send({ error: 'Name must be a valid environment-variable identifier' });\n if (!value) return reply.code(400).send({ error: 'A value is required' });\n await app.secrets.set(name, value);\n return { ok: true, names: app.secrets.list() };\n });\n\n f.delete<{ Params: { name: string } }>('/api/secrets/:name', async (req, reply) => {\n if (!app.secrets) return reply.code(503).send({ error: 'Secrets backend unavailable' });\n await app.secrets.remove(req.params.name);\n return { ok: true, names: app.secrets.list() };\n });\n\n /* ----------------------------- routines ---------------------------- */\n f.get<{ Querystring: { botId?: string } }>('/api/routines', async (req) => store.listRoutines(req.query.botId));\n\n f.post('/api/routines', async (req, reply) => {\n const parsed = CreateRoutineRequest.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid body' });\n if (!store.getBot(parsed.data.botId)) return reply.code(400).send({ error: 'No such bot' });\n try {\n const routine = store.createRoutine({ ...parsed.data, timezone: parsed.data.timezone ?? app.getSettings().timezone });\n app.scheduler?.reload?.(routine.id);\n return routine;\n } catch (err) {\n if (err instanceof LimitError) return reply.code(409).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n f.patch<{ Params: { id: string } }>('/api/routines/:id', async (req, reply) => {\n const routine = store.updateRoutine(req.params.id, (req.body ?? {}) as Record<string, never>);\n if (!routine) return reply.code(404).send({ error: 'No such routine' });\n app.scheduler?.reload?.(routine.id);\n return routine;\n });\n\n f.delete<{ Params: { id: string } }>('/api/routines/:id', async (req, reply) => {\n if (!store.getRoutine(req.params.id)) return reply.code(404).send({ error: 'No such routine' });\n store.deleteRoutine(req.params.id);\n app.scheduler?.reload?.(req.params.id);\n return { ok: true };\n });\n\n f.get<{ Params: { id: string } }>('/api/routines/:id/runs', async (req) => store.listRuns(req.params.id));\n\n f.post<{ Params: { id: string } }>('/api/routines/:id/test-run', async (req, reply) => {\n const routine = store.getRoutine(req.params.id);\n if (!routine) return reply.code(404).send({ error: 'No such routine' });\n if (!app.scheduler?.testRun) return reply.code(503).send({ error: 'Scheduler unavailable' });\n const runId = await app.scheduler.testRun(routine.id);\n return { runId };\n });\n\n /* ---------------------------- attachments -------------------------- */\n f.post('/api/attachments', async (req, reply) => {\n const anyReq = req as unknown as { file?: () => Promise<any>; isMultipart?: () => boolean };\n if (typeof anyReq.file !== 'function') return reply.code(400).send({ error: 'Expected a multipart upload' });\n const part = await anyReq.file();\n if (!part) return reply.code(400).send({ error: 'No file in request' });\n const buf: Buffer = await part.toBuffer();\n const safe = String(part.filename ?? 'file').replace(/[^a-zA-Z0-9._-]/g, '_');\n const dest = path.join(app.cfg.paths.attachments, `${Date.now()}-${safe}`);\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, buf);\n try {\n return store.createAttachment({\n messageId: null, path: dest, name: safe,\n mime: part.mimetype ?? 'application/octet-stream', bytes: buf.byteLength,\n });\n } catch (err) {\n fs.unlinkSync(dest);\n if (err instanceof LimitError) return reply.code(413).send({ error: err.message, code: err.code });\n throw err;\n }\n });\n\n f.get<{ Params: { id: string } }>('/api/attachments/:id', async (req, reply) => {\n const a = store.getAttachment(req.params.id);\n if (!a || !fs.existsSync(a.path)) return reply.code(404).send({ error: 'No such attachment' });\n return reply.type(a.mime).send(fs.createReadStream(a.path));\n });\n\n /* ------------------------------ usage ------------------------------ */\n f.get('/api/usage', async (): Promise<UsageSummary> => {\n const rows = store.listUsage(0);\n const totals = { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0 };\n const byBot = new Map<string, { inputTokens: number; outputTokens: number }>();\n const byDay = new Map<string, { inputTokens: number; outputTokens: number }>();\n const byModel = new Map<string, { inputTokens: number; outputTokens: number }>();\n for (const r of rows) {\n totals.inputTokens += r.inputTokens;\n totals.outputTokens += r.outputTokens;\n totals.cacheReadTokens += r.cacheReadTokens;\n const day = new Date(r.createdAt).toISOString().slice(0, 10);\n for (const [map, key] of [[byBot, r.botId], [byDay, day], [byModel, r.model]] as const) {\n const cur = map.get(key) ?? { inputTokens: 0, outputTokens: 0 };\n cur.inputTokens += r.inputTokens;\n cur.outputTokens += r.outputTokens;\n map.set(key, cur);\n }\n }\n return {\n totals,\n byBot: [...byBot].map(([botId, v]) => ({ botId, botName: store.getBot(botId)?.name ?? 'deleted', ...v })),\n byDay: [...byDay].map(([day, v]) => ({ day, ...v })).sort((a, b) => a.day.localeCompare(b.day)),\n byModel: [...byModel].map(([model, v]) => ({ model, ...v })),\n };\n });\n\n /* ------------------------------ search ----------------------------- */\n f.get<{ Querystring: { q?: string } }>('/api/search', async (req): Promise<SearchResult[]> => {\n const q = (req.query.q ?? '').trim();\n if (!q) return [];\n const out: SearchResult[] = [];\n for (const b of store.listBots()) {\n if (b.name.toLowerCase().includes(q.toLowerCase()) || b.title.toLowerCase().includes(q.toLowerCase()))\n out.push({ kind: 'bot', id: b.id, threadId: b.threadId, botId: b.id, title: b.name, snippet: b.title || b.description.slice(0, 120), createdAt: b.createdAt });\n }\n for (const m of store.searchMessages(q)) {\n const idx = m.contentMd.toLowerCase().indexOf(q.toLowerCase());\n const start = Math.max(0, idx - 60);\n out.push({\n kind: 'message', id: m.id, threadId: m.threadId, botId: m.authorBotId,\n title: m.authorKind === 'user' ? 'You' : store.getBot(m.authorBotId ?? '')?.name ?? 'Bot',\n snippet: `${start > 0 ? '\u2026' : ''}${m.contentMd.slice(start, start + 180)}`,\n createdAt: m.createdAt,\n });\n }\n for (const r of store.listRoutines()) {\n if (r.name.toLowerCase().includes(q.toLowerCase()))\n out.push({ kind: 'routine', id: r.id, threadId: null, botId: r.botId, title: r.name, snippet: r.cronExpr, createdAt: r.createdAt });\n }\n return out.slice(0, 50);\n });\n\n /* ----------------------------- settings ---------------------------- */\n f.get('/api/settings', async () => store.getSettings());\n\n f.patch('/api/settings', async (req, reply) => {\n const parsed = SettingsPatchSchema.safeParse(req.body);\n if (!parsed.success) return reply.code(400).send({ error: 'Invalid settings' });\n const next = store.patchSettings(parsed.data);\n app.scheduler?.syncAll?.();\n bus.publish({ type: 'notify', botId: null, threadId: null, title: 'Settings updated', body: '', level: 'info' });\n return next;\n });\n\n /* ---------------------------- workspace ---------------------------- */\n f.get<{ Querystring: { path?: string } }>('/api/workspace/tree', async (req, reply) => {\n const root = app.cfg.paths.workspace;\n const target = workspaceRelative(root, req.query.path ?? '.');\n if (!target) return reply.code(400).send({ error: 'Path is outside the workspace' });\n if (!fs.existsSync(target)) return [];\n return fs.readdirSync(target, { withFileTypes: true })\n .map((d) => {\n const full = path.join(target, d.name);\n let bytes = 0;\n try { bytes = d.isFile() ? fs.statSync(full).size : 0; } catch { /* ignore */ }\n return { name: d.name, path: path.relative(root, full), dir: d.isDirectory(), bytes };\n })\n .sort((a, b) => (a.dir === b.dir ? a.name.localeCompare(b.name) : a.dir ? -1 : 1));\n });\n\n f.get<{ Querystring: { path?: string } }>('/api/workspace/file', async (req, reply) => {\n const root = app.cfg.paths.workspace;\n const target = workspaceRelative(root, req.query.path ?? '');\n if (!target || !fs.existsSync(target) || !fs.statSync(target).isFile())\n return reply.code(404).send({ error: 'No such file' });\n const ext = path.extname(target).toLowerCase();\n const mime: Record<string, string> = {\n '.md': 'text/markdown', '.txt': 'text/plain', '.json': 'application/json',\n '.csv': 'text/csv', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',\n '.gif': 'image/gif', '.svg': 'image/svg+xml', '.pdf': 'application/pdf', '.html': 'text/html',\n };\n return reply.type(mime[ext] ?? 'application/octet-stream').send(fs.createReadStream(target));\n });\n\n /* ----------------------------- computer ---------------------------- */\n f.get('/api/computer/status', async () => {\n if (!app.browser?.status) return { available: false, reason: 'Browser service not built', mode: 'host', headless: true, pages: [] };\n try {\n return await app.browser.status();\n } catch (err) {\n return { available: false, reason: (err as Error).message, mode: 'host', headless: true, pages: [] };\n }\n });\n\n f.post<{ Body: { botId?: string } }>('/api/computer/takeover', async (req, reply) => {\n if (!app.browser?.takeOver) return reply.code(503).send({ error: 'Browser service unavailable' });\n return app.browser.takeOver(req.body?.botId ?? 'shared');\n });\n\n f.delete<{ Body: { botId?: string } }>('/api/computer/takeover', async (req, reply) => {\n if (!app.browser?.returnControl) return reply.code(503).send({ error: 'Browser service unavailable' });\n await app.browser.returnControl(req.body?.botId ?? 'shared');\n return { ok: true };\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "fileURLToPath", "path", "fs", "path", "b", "now", "fs", "path", "log", "path", "log", "query", "log", "log", "query", "path", "fs", "fs", "path", "log", "b", "path", "fs", "i", "fs", "path", "fs", "fs", "fs", "path", "log", "fs", "path", "log", "opts", "i", "path", "query", "log", "query", "fs", "path", "path", "fs", "fs", "path", "i", "path", "fs", "b", "log", "path", "fileURLToPath", "b"]
|
|
7
|
+
}
|