@beevibe/core
The shared library. Domain types, port interfaces, services, and adapters that every other package imports. No entry point of its own.
Core defines the shape of the system. The API uses it. The scheduler uses it. The daemon uses it. The web app uses its domain types. When you build a new adapter or swap a runtime, you do it here.
Four layers, one direction
The package is organized in layers and the dependency direction is enforced by lint:
Domain pure types
Plain TypeScript types — agents, tasks, sessions, memory, rooms. No I/O. Depends on nothing.
Ports interfaces
Repository interfaces and infrastructure ports — what services need from the outside world. Depends on domain only.
Services business logic
Orchestrates work end-to-end. Sessions, memory promotion, dispatch, task lifecycle. Depends on domain and ports — never on adapters.
Adapters implementations
The concrete code that talks to Postgres, OpenAI, Anthropic, the Claude CLI, and the local workspace. Implements port interfaces.
Quick example
How you'd wire a session by hand. In practice the API does this for you on every dispatch.
import { createPool, PostgresAgentRepository } from "@beevibe/core/adapters/postgres";
import { ClaudeCodeRuntime } from "@beevibe/core/adapters/claude-code";
import { LocalWorkspaceManager } from "@beevibe/core/adapters/local-workspace";
import { AgentSession } from "@beevibe/core/services/agent-session";
const pool = createPool({ connectionString: process.env.DATABASE_URL! });
const runtime = new ClaudeCodeRuntime({ maxTurns: 50 });
const workspace = new LocalWorkspaceManager();
const session = new AgentSession({ /* repos, runtime, memoryAgent */ });
const result = await session.run({
agentId: "agt_…",
intent: "Audit the new migration.",
workspace,
});
typescript
Domain types
The vocabulary in the source matches the one in Concepts — Agent, Task, Session, Memory, Room, MeshRequest, Escalation, Runtime. Plain types, no methods, no I/O.
Ports
Roughly fifteen repository interfaces (tasks, agents, sessions, rooms, memory facts, escalations, etc.) plus infrastructure ports for the LLM, embeddings, the runtime, and the workspace. Services hold ports; adapters fulfill them.
Services
- AgentSession — orchestrates one CLI run end-to-end. The thing the daemon spawns into.
- DispatchService — resolves
runtime_id, pins resume sessions to their original daemon, wakes the daemon hub for new work. - MemoryAgent — assembles the brief, runs vector search, decides what to promote.
- FactPromoter — judges scope promotion (
ic→team→org) using Claude. - TaskService — the task lifecycle (approve, revise, cancel, rollup).
Adapters
- Postgres — raw
pgdriver. No ORM. Schema lives in/migrations/. - Claude Code CLI — spawns the CLI, streams output, parses tool calls.
- OpenAI — embeddings for memory facts.
- Anthropic — Claude calls for fact promotion judgements.
- Local workspace — per-agent directories under
~/.beevibe/workspaces/with their MCP config.
Auth
Token lookup lives here so every package can resolve a bearer the same way.
import { lookupApiKey } from "@beevibe/core/auth";
const caller = await lookupApiKey(repos, "bv_a_…");
// → { source: "agent", agent_id, hierarchy_level, … }
// → { source: "human", person_id, … }
// → { source: "daemon", daemon_id, owner_person_id, … }
typescript
Source
Subpath exports keep imports tree-shakable: @beevibe/core/domain, @beevibe/core/auth, @beevibe/core/adapters/*, @beevibe/core/services/*.
For the full type and port reference, see packages/core/README.md on GitHub.