A worker-first local AI operations platform. BFrost is a control room you run on your own machine. Every capability — assistants, channels, scheduled jobs, model providers, publishing destinations — is a worker. The core knows how to install, configure, schedule, run, observe, and uninstall workers; it knows nothing about any specific workflow. Add a worker to add a feature. Remove it to remove the feature.
BFrost is local-first by design: model inference, scheduler state, queue state, and dashboard operations all run on your machine. There is no hosted service, no remote loading, no worker marketplace yet. Workers are loaded from local directories you control.
BFrost is published as a public preview. The worker-first contract is in place end-to-end:
- Core decoupled from built-in worker names (Workstream 1 ✅).
- Tools, channels, and providers are worker types (Workstream 2 ✅).
- Shared Item Bus and per-worker storage (Workstream 3 ✅).
- Local worker execution runtime with TypeScript compile-on-load, lifecycle hooks, dashboard bundles, and a typed
bfrostSDK (Workstream 4 ✅, minus the sandbox/permission model below).
What still gates a v1.0.0 tag:
- Permissioned action runtime (Workstream 5). Workers can already produce items, run jobs, and surface UIs, but the formal approval queue + per-worker filesystem/network/credential scopes are not yet wired up. Use the existing approval gates on the queue, and keep destructive workers narrow until this lands.
- Frontend smoke tests, per-worker metrics, accessibility pass, and guarded SQLite restore tooling (Workstream 6).
- Hosted docs site, scripted demo, Worker Gallery in the dashboard, and a
CONTRIBUTING.mdexpansion (Workstream 7). The browsable documentation at https://convertprivately.com/bfrost/ already covers getting started, architecture, example workers, and authoring with Claude Code.
The full punch list lives in ROADMAP.md. Issues, worker proposals, and PRs are welcome.
- Worker-first core.
src/outsidesrc/workers/ships with zero domain knowledge. Even the bundled news, X publisher, and research automations are workers undersrc/workers/builtin/, shipped in the same shape a contributor would author. - Item Bus for cross-worker work. A producer publishes typed items; one or more consumers subscribe. Adding "publish to Mastodon" is a new consumer worker, not a core change. See
docs/item-bus.md. - Local-first. Your data, models, credentials, and run history stay on your machine.
- Approval-gated. Risky actions (posting, file writes, shell commands) are designed to be reviewed before they run.
- Inspectable. Every job, queue item, event, and run is durable, attributable, and visible in the dashboard.
- Extensible without forks. New jobs, tools, channels, providers, and publishers ship as workers. Authoring a worker is a manifest, a job runner, a README, and a test. See
docs/worker-authoring.md.
These workers ship with BFrost and double as worked examples. They use the same contract a contributor uses.
core.news— scheduled harvesting with source-quality scoring and near-duplicate detection. Producesnews.articleitems.core.publisher.x— consumesnews.articleitems and posts to X with approval gating.core.research— scheduled Markdown research notes synthesised with a local model.core.memory,core.search.google,core.article-fetch— assistant-tool workers.core.channels.telegram— Telegram channel worker.core.providers.lmstudio— LM Studio model provider worker.
Each has a one-page README in src/workers/builtin/<id>/README.md covering what it produces/consumes, which credentials it reads, and operational caveats.
src/index.ts— boots channels, providers, scheduler, and admin server.src/workers/registry.ts— small aggregator over worker manifests.src/workers/builtin/<id>/— bundled reference workers.src/workers/local.ts— local manifest discovery and compatibility validation.src/workers/loader.ts+src/workers/build.ts— load compiled JS / compile TS sources on install.src/jobs/item-bus.ts— typed producer/consumer queue shared across workers.src/workers/storage.ts+src/workers/db.ts— namespaced per-worker KV and SQLite tables.src/admin-server.ts— local HTTP API and static dashboard hosting.web/— React dashboard. Worker-specific UI lives inweb/src/workers/.workers/— local worker examples and authoring docs.data/— local state and run artefacts.
- Node.js 20+
sqlite3- a Telegram bot token (only for the Telegram channel worker)
- an OpenAI-compatible local model endpoint
- the LM Studio CLI binary available at the configured path
ffmpegwhisper-cli- a Whisper model file
- Google Custom Search credentials — for
core.search.google,core.news, andcore.research. - X credentials — for
core.publisher.x. - A WordPress site with Application Passwords enabled — if you install the
wordpress-publisherexample to publish news items to your own WP site. - Research topics configured from the dashboard — for
core.research.
npm install
cp .env.example .env
npm run build
npm startOpen the dashboard at http://127.0.0.1:3030.
npm run build— compile the backend and build the React dashboard.npm run build:server/npm run build:web— compile one side only.npm start— run the bot, scheduler, and admin dashboard server.npm run dev— run unit tests, then start backend and Vite dashboard together.npm run dev:watch— watch TypeScript backend files.npm run dev:web— Vite dev mode for the dashboard.npm run task -- --job <id>— run a named job manually (e.g.news-digest,personal-research).
- Read
docs/worker-authoring.mdfor the workflow. - Read
docs/item-bus.mdif your worker produces or consumes work items. - Copy a scaffold from
workers/examples/(simple-job,research-style-job,complete-capability, ordashboard-view). - Drop your worker under
workers/local/<id>/, then Rescan in the dashboard's Workers tab. - Enable it, run it, watch the events feed.
Two worker-authoring skills ship with the repo under .claude/skills/:
.claude/skills/bfrost-worker-author/— for BFrost installs. Ask Claude to "create a new BFrost worker".
Claude Code loads skills from .claude/skills/ automatically when you open the repo. Both skills enforce the worker-first contract — core files are off-limits, and a violation surfaces as an explicit contract gap rather than a silent core edit.
Codex does not load .claude/skills/ automatically. To get the same guardrails, copy the relevant SKILL.md into a file your assistant reads at session start — for example:
- paste its contents into your Codex system prompt, or
- add it to your
AGENTS.md/CODEX.mdat the repo root (Codex picks upAGENTS.mdautomatically).
The skill text is plain Markdown with no Claude-specific syntax; it works as a plain instruction set for any assistant.
The platform separates private state from cross-worker sharing:
- Per-worker storage (
openWorkerKv,openWorkerDb) is private. Keys land underworker.<id>.<key>; tables land asworker_<id>_<name>. No other worker can read them. - The Item Bus (
src/jobs/item-bus.ts) is the contract for sharing across workers. A producer publishes items with a typeditemTypeand a JSONpayload; any consumer can subscribe and write its own outcome into the item's namespacedmetadata. The News → X Publisher pipeline runs on this bus, and adding a new publisher (WordPress, Mastodon, BlueSky, …) requires no change to existing workers — seeworkers/examples/wordpress-publisher/for a full consumer example.
Reach for the Item Bus when workers need to talk to each other; reach for worker storage when a worker needs to remember something privately.
From the dashboard you can:
- enable/disable workers and inspect their health, credentials, and dependencies
- configure and monitor scheduled jobs
- trigger jobs manually
- inspect queue pressure and recent digest runs
- inspect recent operational events
- manage LM Studio runtime actions
- switch the default model
- review configuration and local dependency health
OLLAMA_BASE_URL configures the OpenAI-compatible endpoint URL even when the runtime is LM Studio. Point it at whichever local server exposes the compatible API.
Most mutable local state is stored in the SQLite database configured by APP_DB_PATH. Legacy JSON files under data/ are imported on first use when the corresponding SQLite record does not exist yet.
Before publishing or sharing a branch, check that data/, logs/, models/, .env, SQLite files, generated research notes, and private worker scratch directories are not staged.
docs/worker-authoring.md— consolidated worker authoring guide.docs/item-bus.md— Item Bus and per-worker storage reference.workers/README.md— manifest contract reference.ROADMAP.md— evolution plan and current workstreams.CONTRIBUTING.md— contributor setup and code style.SECURITY.md,CODE_OF_CONDUCT.md— project policies.
MIT. See LICENSE.