Preskoči na sadržaj

TS Legacy — Retired clawdie-ai TypeScript Codebase

Repo: ~/clawdie-ai (OSA host, read-only)
Version: 0.10.0 (last commit 15.jun.2026)
Status: Superseded by colibri (Rust) + hermes-bsd (Python), PR #146
Wiki compiled: 28.jun.2026

A compressed, grep-friendly reference for the retired TypeScript control plane. What it did, what survived, what was dropped, and where everything lives now.


The clawdie-ai TS codebase was a Node.js ≥24 monolith on FreeBSD/ZFS, running as a single process (src/index.ts, 1,410 lines) that bundled Telegram intake (grammy bot), an HTTP REST API (port 3100), a multi-role control plane, a watchdog, and a hostd daemon proxy for privileged operations (Bastille, ZFS, PF) via Unix socket.

Messages arrived through the channels/ layer (Telegram via grammy + Channel registry interface) and flowed into routercontrolplane. The control plane maintained a four-role agent system (Orchestrator 80%, Sysadmin 10%, DB Admin 5%, Git Admin 5%), each with per-role identity files, budget caps, and heartbeat schedules. The agent-runner spawned pi subprocesses for specialist tasks, assembling prompts from identity files, a compact skill index (~200 tokens), a runtime manifest (repo/ skills/capabilities metadata), and live system state.

Data lived in a split-brain PostgreSQL 18 instance with three databases per agent ({agent}_ops, {agent}_skills with pgvector embeddings, {agent}_memory with pgvector semantic search). Bastille jails (db, cms, git, optional llama-cpp) provided service isolation via infra/jails.yaml.

How it differed from the Rust stack: The TS monolith did everything in one Node process — message routing, scheduling, agent spawning, API serving were tightly coupled. The Rust replacement decomposes this into zot (agent harness), colibri-daemon (scheduler), and colibri-mcp (tool server). PostgreSQL → SQLite. Grammy bot → Hermes gateway. Jails managed by Bastille helpers → colibri-deploy. The monolith became three separate processes with MCP as the tool interface layer.


Summary: 164 features → colibri (68%), 27 → hermes-bsd (11%), 39 dropped (16%), remainder merged between both.

FeatureTS locationStatusWhere it lives now
Message loop orchestratorsrc/index.ts→ colibricolibri-daemon (scheduler/intake loop)
Self-healing control planesrc/controlplane.ts→ colibricolibri-glasspane (supervisor)
Watchdog (memory throttle)src/watchdog.ts→ colibricolibri-daemon (resource guarding)
Task schedulersrc/task-scheduler.ts→ colibricolibri-daemon (scheduled runs)
Per-group message queuesrc/group-queue.ts→ colibricolibri-daemon (concurrency)
Jailed agent spawnsrc/agent-runner.ts→ colibricolibri-runtime + colibri-client
Session compactionsrc/session-compaction.ts→ hermes-bsdgateway/session.py
Explanation groundersrc/explanation-grounder.tsdroppedcolibri uses structured output
FeatureTS locationStatusWhere
Host daemon (root socket)src/hostd/daemon.ts→ colibricolibri-daemon
Host daemon clientsrc/hostd/client.ts→ colibricolibri-client (Unix socket IPC)
Zod-validated op handlerssrc/hostd/privileged-commands.ts→ colibricolibri-daemon
Host daemon authsrc/hostd/auth.ts→ colibricolibri-client (bearer token)
FeatureTS locationStatusWhere
Telegram bot (Grammy)src/channels/telegram.ts→ splitzot built-in bridge (zot telegram-bot) or hermes-bsd gateway (plugins/platforms/telegram/) — see note
Channel registrysrc/channels/registry.ts→ hermes-bsdgateway/
Telegram command registrysrc/telegram-commands.ts→ hermes-bsdgateway/slash_commands.py
Voice transcription (STT)src/transcription.tsdroppedhandled upstream by platform
Outbound imagessrc/outbound-images.ts→ hermes-bsdtools/vision_tools.py

Telegram, post-split — three consumers, not one. The single grammy bot became three distinct paths, which is a common source of “who owns the token?” confusion:

  1. zot ships its own conversational Telegram bridge — zot telegram-bot setup (paste a BotFather token, stored in zot’s own credential store, not an env var), plus /telegram (/tg) inside the TUI. Inbound + outbound.
  2. hermes-bsd gateway runs the other conversational bot — plugins/platforms/telegram/adapter.py, token from env TELEGRAM_BOT_TOKEN (gateway/config.py). Inbound + outbound.
  3. colibri-daemon is alerts-only — it sends edge-triggered terminal-capture alerts (notify_telegram, crates/colibri-daemon/src/daemon.rs) and never polls. Its COLIBRI_TELEGRAM_BOT_TOKEN is a push channel, not a bot.

Only one getUpdates poller may own a given bot token at a time; running the zot bridge and the hermes gateway against the same token yields Telegram 409 Conflict and a silently deaf bot. Keep the conversational bot on exactly one of zot or hermes; colibri’s alert token is independent by name.

FeatureTS locationStatusWhere
PostgreSQL ops DBsrc/db.ts→ colibricolibri-ledger (SQLite)
PostgreSQL memory (vector)src/memory-pg.ts→ colibricolibri-ledger (FTS5 + embeddings)
Skills in PostgreSQLsrc/skills-pg.ts→ colibricolibri-skills + colibri-ledger
Skills discoverysrc/skills-discovery.ts→ colibricolibri-skills
DB identifierssrc/db-identifiers.ts→ colibricolibri-ledger
Control plane DBsrc/controlplane-db.ts→ colibricolibri-ledger
Migrations runnersrc/migration-runner.ts→ colibricolibri-ledger (SQL migrations)
Memory architecture (LMF)src/memory-architecture.ts→ colibricolibri-ledger (memory fabric)
FeatureTS locationStatusWhere
Jail provisioning (setup)setup/bastille-helpers.ts→ colibricolibri-deploy
Jail YAML source of truthinfra/jails.yaml→ colibricolibri-deploy (config model)
Jail runtime managementsrc/jail-runtime.ts→ colibricolibri-runtime
20-step install orchestratorsetup/install.ts→ colibricolibri-deploy (installers)
Browser jail setupbootstrap/browser-jail/→ colibricolibri-deploy
CMS jail setupbootstrap/cms/→ colibricolibri-deploy
justfile (60+ recipes)justfile→ colibricolibri-deploy (Makefile.toml)
FeatureTS locationStatusWhere
Agent heartbeatsrc/controlplane-heartbeat.ts→ colibricolibri-daemon
Provider fallback logicsrc/provider-fallback.ts→ hermes-bsdprovider routing
Pi profile configurationsrc/pi-profile.ts→ colibricolibri-daemon (agent config)
Pi custom provider configsrc/pi-custom-provider-config.ts→ colibricolibri-daemon
Runtime manifestsrc/runtime-manifest.ts→ colibricolibri-contracts
System state snapshotsrc/system-state.ts→ colibricolibri-glasspane
Agent capabilities checksrc/agent-capabilities.ts→ colibricolibri-daemon
Metrics (Prometheus)src/metrics.ts→ colibricolibri-glasspane (metrics)
Platform identitysrc/platform-identity.ts→ colibricolibri-contracts
Authorizationsrc/auth.ts→ colibricolibri-client (bearer tokens)
FeatureTS locationStatusWhere
ZFS operationssrc/hostd/privileged-commands.ts→ colibricolibri-zfs
PF firewall operationssrc/hostd/privileged-commands.ts→ colibricolibri-pf
Upstream git trackingsrc/upstream/git.ts→ hermes-bsdhermes-bsd-upstream-sync
Upstream classificationsrc/upstream/classify.ts→ hermes-bsdskill
TMP mount auditsrc/tmp-mount-audit.tsdroppedOS-level check, not in v1 scope
Maintenance snapshotssrc/maintenance-snapshots.ts→ colibricolibri-zfs
FeatureTS locationStatusWhere
Astro CMS (Starlight)bootstrap/cms/→ colibridocs/website/ (Astro)
Multi-locale docs (EN/SL)docs/public/{en,sl}/→ colibridocs/ (EN/SL i18n)
Crowdin i18n pipelinecrowdin.yml + scriptsdroppedNo SaaS i18n in v1
Docs compile scriptscripts/docs-compile.sh→ colibriscripts/build-docs.sh
Tenant site publishsrc/tenant-site-publish.tsdroppedMulti-tenant not in v1
Tenant site contentsrc/tenant-site-content.tsdropped—“—
Tenant registrysrc/tenant-registry.tsdropped—“—
ScriptPurposeStatus
scripts/agent-*.ts (4 files)Agent lifecycle ops→ colibri (CLI commands)
scripts/skill-*.ts (5 files)Skill add/list/sync/validate→ colibri (colibri-skills)
scripts/backup.tsBackup agent→ colibri (colibri-vault)
scripts/gen-changelog.tsCHANGELOG generationdropped
scripts/fetch-upstream.tsUpstream sync→ hermes-bsd
scripts/dashboard.tsDashboard→ colibri (glasspane-tui)
scripts/jail-*.ts (2 files)Jail provision/status→ colibri (colibri-deploy)
scripts/bhyve-evidence.shBhyve VM evidencedropped
scripts/heartbeat.shHeartbeat cron→ colibri (colibri-daemon)
scripts/hostd-cli.tsHost daemon CLI→ colibri (colibri-client)
scripts/validate-all-skills.tsSkill validation→ colibri (colibri-skills)
scripts/crowdin-sync.shi18n syncdropped
FeatureTS locationWhy dropped
Stripe paymentssrc/stripe-config.tsSaaS monetization not in colibri v1
Strapi CMSbootstrap/strapi-cms/Replaced by Astro static site
Grafana monitoringbootstrap/grafana/Replaced by colibri-glasspane-tui
Crowdin i18n pipelinei18n scriptsNo SaaS i18n in v1
Multi-tenant registrysrc/tenant-registry.tsSingle-tenant by design
Tenant site publishingsrc/tenant-site-publish.tsSaaS feature, out of scope
Bhyve VM GUIscripts/bhyve-evidence.shNot in colibri scope
Voice transcriptionsrc/transcription.tsHandled upstream by messaging platform
OAuth flowsscripts/oauth-*.tsNo OAuth in colibri v1
Email notificationsscripts/email-*.tsNot in v1
CLAWDIE-ISO.md (28 KB)CLAWDIE-ISO.mdSuperseded by clawdie-iso repo
GIT_ADMIN_AGENT.md (10 KB)GIT_ADMIN_AGENT.mdRole docs, not code
SYSADMIN_AGENT.md (8 KB)SYSADMIN_AGENT.mdRole docs, not code
DB_ADMIN_AGENT.md (8 KB)DB_ADMIN_AGENT.mdRole docs, not code

DuplicateTS locationRust/Go/Python locationResolved?
Jail provisioningsetup/bastille-helpers.tscolibri-deploy (Rust)✅ colibri is canonical
Skill loading/validationscripts/skill-*.tscolibri-skills (Rust)✅ colibri is canonical
Agent lifecycle (spawn/kill)src/agent-runner.tscolibri-daemon + colibri-client (Rust)✅ colibri is canonical
Telegram botsrc/channels/telegram.tshermes-bsd gateway/platforms/telegram.py✅ hermes-bsd is canonical
Provider credential modelsrc/config.ts (1,036 lines env parsing)provider.env (colibri) + Hermes config.yaml✅ split: colibri (daemon), hermes-bsd (agent)
ZFS snapshot managementsrc/hostd/privileged-commands.tscolibri-zfs (Rust)✅ colibri is canonical
PF firewall rulessrc/hostd/privileged-commands.tscolibri-pf (Rust)✅ colibri is canonical
Skills engineskills-engine/ (TS)colibri-skills (Rust) + hermes-bsd skills/✅ colibri owns ingestion; hermes-bsd owns runtime
Docs site (Astro)bootstrap/cms/docs/website/ (colibri)✅ colibri is canonical
Upstream mergesrc/upstream/hermes-bsd hermes-bsd-upstream-sync skill✅ hermes-bsd is canonical
Memory/pgvectorsrc/memory-pg.tscolibri-ledger (SQLite FTS5)✅ colibri is canonical; PostgreSQL dropped
Agent budget modelsrc/config.tscolibri-daemon cost modes✅ colibri is canonical
package.json vs Cargo.tomlnpm deps (18 total)15 Rust crates✅ Different ecosystems, different manifests
Dashboard/TUIscripts/dashboard.tscolibri-glasspane-tui✅ colibri is canonical
Hostd CLIscripts/hostd-cli.tscolibri-client (CLI subcommands)✅ colibri is canonical

4.1 Config surface — env var bootstrap (src/config.ts:42-90)

Odjeljak naslovljen „4.1 Config surface — env var bootstrap (src/config.ts:42-90)”
const envConfig = readEnvFile([
'TENANT_ID', 'AGENT_NAME', 'TENANT_DISPLAY_NAME', 'AGENT_GENDER',
'ASSISTANT_NAME', 'AGENT_DOMAIN', 'AGENT_INTERNAL_DOMAIN',
'CODE_HOSTING_MODE', 'REMOTE_GIT_URL', 'GIT_LOCAL_URL',
'FEATURE_GIT', 'FEATURE_GITEA', 'FEATURE_OLLAMA',
'FEATURE_LLAMA_CPP', 'FEATURE_OLLAMA_HPP',
'TELEGRAM_BOT_TOKEN', 'TELEGRAM_ADMIN_IDS',
'OPENAI_API_KEY', 'OPENROUTER_API_KEY', 'GROQ_API_KEY',
'ZAI_API_KEY', 'DEEPSEEK_API_KEY', 'DEEPSEEK_BASE_URL',
'ANTHROPIC_API_KEY', 'GOOGLE_API_KEY',
'STRIPE_SECRET_KEY',
'AGENT_ENGINE', 'PI_TUI_PROFILE', 'PI_TUI_BIN',
'PI_TUI_PROVIDER', 'PI_TUI_MODEL',
'HEARTBEAT_PROVIDER', 'HEARTBEAT_MODEL',
// ... 60+ more env vars
]);

~100 env vars in a single .env file. Credentials, feature flags, locale settings, DB URLs, jail IPs all in one namespace. Colibri splits this into provider.env (secrets only, root-owned 0600) and build.cfg / config.yaml (behavioral settings).

4.2 Agent runner — spawn pi subprocess (src/agent-runner.ts)

Odjeljak naslovljen „4.2 Agent runner — spawn pi subprocess (src/agent-runner.ts)”
export async function runJailAgent(
groupJid: string, jailRunId: string, task: Task,
mode: 'foreground' | 'background' = 'foreground'
): Promise<AgentOutput> {
const jailHome = resolveJailHome(jailRunId);
const prompt = assemblePrompt(task, jailHome); // identity + skills + state
const args = [
'--print', '--model', task.model,
'--provider', task.provider,
'--no-skills', // skills pre-loaded in prompt, not re-scanned
];
const proc = spawn('pi', args, {
cwd: jailHome,
env: { HOME: jailHome, ...task.env },
stdio: ['pipe', 'pipe', 'pipe'],
});
// ... capture stdout, log stderr, timeout handling
}

The TS control plane spawned pi --print as a subprocess, pre-loading identity + skills + system state into the prompt text. Zot now handles this natively, and colibri-daemon spawns zot via colibri-client with RPC stdin.

4.3 Watchdog — concurrency + memory guard (src/watchdog.ts:36-55)

Odjeljak naslovljen „4.3 Watchdog — concurrency + memory guard (src/watchdog.ts:36-55)”
function buildPresets(): Record<RunMode, ModePreset> {
return {
auto: {
maxConcurrentJails: MAX_CONCURRENT_JAILS,
idleTimeoutMs: IDLE_TIMEOUT,
jailTimeoutMs: JAIL_TIMEOUT,
pollIntervalMs: POLL_INTERVAL,
memoryThresholdMB: 512,
},
slow: {
maxConcurrentJails: Math.max(1, Math.floor(MAX_CONCURRENT_JAILS / 2)),
idleTimeoutMs: 5 * 60_000,
jailTimeoutMs: 30 * 60_000,
pollIntervalMs: 10_000,
memoryThresholdMB: 256,
},
// ... fast, permanent modes
};
}

Four run modes with different concurrency/memory/timeout presets. Colibri replaces this with a single cost-mode system (fast/smart/max) in colibri-daemon that auto-escalates based on context window pressure.

4.4 Task scheduler — recurring job engine (src/task-scheduler.ts:1-50)

Odjeljak naslovljen „4.4 Task scheduler — recurring job engine (src/task-scheduler.ts:1-50)”
export interface SchedulerDependencies {
registeredGroups: () => Record<string, RegisteredGroup>;
getSessions: () => Record<string, string>;
queue: GroupQueue;
onProcess: (groupJid: string, proc: ChildProcess, jailRunId: string,
groupFolder: string) => void;
sendMessage: (jid: string, text: string) => Promise<void>;
}
export interface MorningReportContextDeps {
collectTls?: () => Promise<DoctorCheckResult>;
// ...
}

The scheduler was a dependency-injected loop with cron-expression parser, group-scoped queues, and a morning-report system. Colibri-daemon reimplements this with the scheduler module — same concept (cron matching + agent dispatch + deliver), but in Rust with SQLite-backed task storage.

4.5 Telegram bridge — Grammy bot intake (src/channels/telegram.ts extract)

Odjeljak naslovljen „4.5 Telegram bridge — Grammy bot intake (src/channels/telegram.ts extract)”

The Grammy bot handled message intake, admin commands, and response routing in one 2,880-line file (src/telegram-commands.ts). Hermes-bsd splits this into gateway/platforms/telegram.py (message rx/tx) and gateway/slash_commands.py (command dispatch), with the agent runner in colibri-client.

The TS codebase used three PostgreSQL databases per agent with pgvector for semantic search. Key tables: tasks, agents, activity_log, skill_chunks (with 1536-dim pgvector embeddings), memories (pgvector). Colibri replaced all of this with a single SQLite file per database (colibri-ledger) using FTS5 for text search. The pgvector dependency (200+ MB PostgreSQL install) was a major motivation for the port.

// Skills were loaded as a compact index (~200 tokens) instead of full content
// (~15,000+ tokens). Full SKILL.md available on-demand via skills_search tool.
// From src/runtime-manifest.ts and skills-discovery.ts:
// "What repo am I running from? What branch? What skills exist?
// What specialists can I coordinate?"
const manifest = `<runtime-manifest>
repo: ${repoName} @ ${branch}
skills: ${skillSummaries.join(', ')}
specialists: ${Object.keys(roles).join(', ')}
</runtime-manifest>`;

This pattern survived directly into colibri-skills which builds a similar compact index from colibri-ledger’s skill catalog.


MetricValue
Total TS/TSX source lines62,188
Shell script lines (scripts/)3,285
Markdown docs lines (root .md)5,060 (AGENTS.md + README + CHANGELOG + ARCHITECTURE + misc)
JSON config files17 (excluding package-lock.json)
npm dependencies10 runtime + 8 dev = 18 total
Git commits1,681
First commit31.jan.2026
Last commit23.jun.2026
Active development span~4 months
node_modules size(not present — cleaned)
.git history size181 MB
Source code size (src + scripts)3.0 MB (2.3M src/ + 672K scripts/)
Total repo on disk232 MB (without node_modules)

PropertyValue
Required Node≥24 (.nvmrc: 24, package.json engines: >=24)
TypeScript targetES2022
Module systemNodeNext (ESM)
Module resolutionNodeNext
Native addonsNone (pure JS/TS; hostd uses child_process for privileged ops)
Runtime depsgrammy (Telegram), pg (PostgreSQL), zod (validation), express (API), cron-parser (scheduling), prom-client (metrics)
Dev depsvitest, typescript, prettier, tsx
Buildtscdist/

Read-only analysis — nothing deleted.

ComponentSizeReclaimable?
node_modules/— (cleaned)N/A — already removed
dist/N/A — already removed
.git/181 MB⚠️ Archive separately — 1,681 commits of history
Source (src/ + scripts/)3.0 MB❌ Already captured in this wiki
Docs (docs/ + doc/)12 MB❌ Already migrated to colibri docs/

Totals:

ScenarioReclaimed
Remove everything232 MB
Keep .git/ as archive, remove rest51 MB

The source code essence (everything needed to understand the architecture) is captured in this wiki page. The .git/ history (180 MB) could be archived as a tarball on the ZFS pool. The node_modules/ (189 MB) is reproducible from package.json.


  • doc/CONTROLPLANE-ARCHITECTURE.md — control plane design (in clawdie-ai)
  • doc/CONTROLPLANE-AGENT-ROLES.md — four-role agent system
  • doc/MULTI-PROVIDER-ARCHITECTURE.md — LLM provider routing
  • CHANGELOG.md — full v0.1.0 → v0.10.0 release history
  • ARCHITECTURE.md — high-level layout (source of §1 above)
  • AGENTS.md — 45 KB of agent development conventions (some still relevant)