Files
fusion/docs/architecture.md
Fusion d2e9423f75 feat(FN-3292): document research boundary contract
Documents the research boundary contract in the architecture docs and research hardening preflight guide, updating architecture documentation and adding a new boundary definition file.

Fusion-Task-Id: FN-3292
2026-05-04 13:17:57 -07:00

55 KiB

Fusion Architecture

← Docs index

This document describes the actual architecture of Fusion as implemented in this repository (gsxdsm/fusion). It is intended as a practical onboarding map for developers and AI agents.


1) Overview

Fusion is an AI-orchestrated task board. It takes tasks through a structured lifecycle (planning → todo → in-progress → in-review → done → archived) and automates planning, execution, review, merge, and operational recovery.

At a high level, Fusion is split into:

  • Core domain + persistence (@fusion/core)
  • Execution engine (@fusion/engine)
  • Dashboard API + SPA (@fusion/dashboard)
  • CLI + Pi extension (@runfusion/fusion)
  • Desktop shell (@fusion/desktop)
  • Terminal dashboard (part of @runfusion/fusion — see packages/cli/src/commands/dashboard-tui/)

High-level runtime diagram

                        ┌──────────────────────────────┐
                        │   Human + AI Interactions    │
                        │ (Dashboard SPA, CLI, Pi)     │
                        └──────────────┬───────────────┘
                                       │
                ┌──────────────────────┼──────────────────────┐
                │                      │                      │
      ┌─────────▼─────────┐  ┌─────────▼─────────┐  ┌─────────▼─────────┐
      │  Dashboard (API)  │  │ CLI `fn` router   │  │ Pi extension tools │
      │ + React SPA       │  │ + TUI component   │  │ (extension.ts)     │
      │ (lazy-loaded)     │  │ (commands/*)      │  │                    │
      └─────────┬─────────┘  └─────────┬─────────┘  └─────────┬─────────┘
                └──────────────┬────────┴──────────────┬───────┘
                               │                       │
                      ┌────────▼───────────────────────▼───────┐
                      │            Engine Runtime               │
                      │ Scheduler / Planning / Executor / Merger │
                      │ Heartbeat / Self-healing / Autopilot   │
                      └────────┬───────────────────────┬────────┘
                               │                       │
                   ┌───────────▼──────────┐   ┌────────▼─────────────┐
                   │ @fusion/core         │   │ External systems      │
                   │ stores + types       │   │ git, GitHub, models   │
                   └───────┬──────────────┘   └───────────────────────┘
                           │
          ┌────────────────▼────────────────┐
          │ Persistence                      │
          │ - .fusion/fusion.db (SQLite/WAL)
          │ - .fusion/tasks/* (PROMPT/logs)
          │ - ~/.fusion/fusion-central.db │
          └──────────────────────────────────┘

2) Monorepo Structure

Package Published Role Key files
@fusion/core Private Domain model, stores, SQLite adapters, settings, shared types packages/core/src/types.ts, store.ts, db.ts, central-core.ts, agent-store.ts
@fusion/engine Private AI orchestration runtime (planning, scheduler, executor, merger, recovery) planning processor, scheduler.ts, executor.ts, merger.ts, project-runtime.ts
@fusion/dashboard Private Express API server + React app packages/dashboard/src/server.ts, routes.ts, sse.ts, websocket.ts, packages/dashboard/app/App.tsx
@runfusion/fusion Published CLI binary (fn) + Pi extension packages/cli/src/bin.ts, commands/*, project-resolver.ts, extension.ts
@fusion/desktop Private Electron shell around Fusion dashboard/client packages/desktop/src/main.ts, ipc.ts, preload.ts, scripts/build.ts
@fusion/mobile Private Capacitor + PWA mobile packaging of dashboard assets packages/mobile/capacitor.config.ts, packages/mobile/src/*
@fusion/plugin-sdk Private Plugin SDK for building Fusion extensions packages/plugin-sdk/src/*

3) Package Dependencies

Workspace dependency graph

A ──▶ B means A depends on B.

@fusion/engine ───────────────▶ @fusion/core
@fusion/dashboard ────────────▶ @fusion/core
@fusion/dashboard ────────────▶ @fusion/engine
@runfusion/fusion (CLI) ─────────▶ @fusion/core
@runfusion/fusion (CLI) ─────────▶ @fusion/engine
@runfusion/fusion (CLI) ─────────▶ @fusion/dashboard
@fusion/plugin-sdk (peerDep) ─▶ @fusion/core

@fusion/desktop: no workspace package dependencies
@fusion/mobile:  no workspace package dependencies

Concrete references:

  • @fusion/engine has a workspace dependency on @fusion/core (packages/engine/package.json)
  • @fusion/dashboard has workspace dependencies on @fusion/core and @fusion/engine (packages/dashboard/package.json)
  • @runfusion/fusion has workspace development dependencies on @fusion/core, @fusion/engine, and @fusion/dashboard for composition/build packaging (packages/cli/package.json)
  • @fusion/plugin-sdk declares a peer dependency on @fusion/core (packages/plugin-sdk/package.json)
  • @fusion/desktop embeds dashboard assets at build time via script (packages/desktop/scripts/build.ts) but does not declare workspace deps in package.json
  • @fusion/mobile triggers dashboard build/sync via scripts (packages/mobile/package.json) but does not declare workspace deps in package.json

4) Core Package (@fusion/core)

Responsibility

@fusion/core is the shared domain and persistence layer.

Main components

  • Types and constants: packages/core/src/types.ts
    • Columns: COLUMNS
    • Transition map: VALID_TRANSITIONS
    • Settings defaults: DEFAULT_GLOBAL_SETTINGS, DEFAULT_PROJECT_SETTINGS
    • Workflow types (WorkflowStep, WorkflowStepPhase, etc.)
  • TaskStore: packages/core/src/store.ts
    • Main task CRUD + lifecycle store
    • Emits board events (task:created, task:moved, task:updated, ...)
    • Hybrid model: SQLite metadata + filesystem blobs under .fusion/tasks/{id}
  • Database adapter: packages/core/src/db.ts
    • SQLite (node:sqlite) with WAL mode + foreign keys
    • JSON helpers: toJson, toJsonNullable, fromJson
    • Core schema tables include: tasks, config, workflow_steps, activityLog, archivedTasks, automations, agents, agentHeartbeats, task_documents, task_document_revisions, mission hierarchy tables (missions, milestones, slices, mission_features, mission_events), plugin/routine tables (plugins, routines), roadmap tables (roadmaps, roadmap_milestones, roadmap_features), insight tables (project_insights, project_insight_runs), todo tables (todo_lists, todo_items), __meta
    • Migration-created tables include: ai_sessions, messages, agentRatings, chat_sessions, chat_messages, runAuditEvents, mission_contract_assertions, mission_feature_assertions, mission_validator_runs, mission_validator_failures, mission_fix_feature_lineage
    • ai_sessions.status lifecycle includes draft (pre-start planning session), then generating, awaiting_input, terminal complete / error
  • Standalone roadmap model: packages/core/src/roadmap-types.ts, roadmap-ordering.ts, roadmap-store.ts
    • Roadmap-first entity types (Roadmap, RoadmapMilestone, RoadmapFeature)
    • Pure ordering helpers for contiguous 0-based milestone/feature order and deterministic cross-milestone feature moves
    • RoadmapStore for CRUD operations, deterministic ordering, and atomic reorder/move operations
    • Dashboard API routes in packages/dashboard/src/roadmap-routes.ts
    • Exported from @fusion/core for downstream persistence/API/UI work
  • CentralCore: packages/core/src/central-core.ts
    • Global project registry, health, central activity feed, global concurrency
    • Backed by packages/core/src/central-db.ts (~/.fusion/fusion-central.db)
  • Specialized stores:
    • AgentStore (agent-store.ts) — filesystem-based agent metadata + heartbeat run history
    • MissionStore (mission-store.ts) — mission/milestone/slice/feature hierarchy
    • AutomationStore (automation-store.ts) — scheduled jobs with global/project scope isolation
    • MessageStore (message-store.ts) — mailbox/inbox/outbox messaging
    • ChatStore (chat-store.ts) — session/message persistence for agent chat
    • InsightStore (insight-store.ts) — project insight persistence + dedupe/run tracking
    • ReflectionStore (reflection-store.ts) — agent reflection records and performance snapshots
    • PluginStore (plugin-store.ts) — plugin registry/state/settings persistence
    • RoutineStore (routine-store.ts) — recurring routine definitions and run history
    • RoadmapStore (roadmap-store.ts) — standalone roadmap CRUD with deterministic ordering and atomic reorder/move operations
    • TodoStore (todo-store.ts) — project-scoped todo lists/items with completion, reorder, and composite list+items queries

Chat System

  • ChatStore (packages/core/src/chat-store.ts) and chat-types.ts provide session-oriented chat state (chat_sessions, chat_messages tables)
  • Dashboard chat UX lives in packages/dashboard/app/components/ChatView.tsx and hooks useChat.ts / useQuickChat.ts
  • Chat message submission uses SSE streaming responses from dashboard chat routes

Agent Companies

  • Import/export utilities: agent-companies-parser.ts, agent-companies-exporter.ts, agent-companies-types.ts
  • Supports YAML-frontmatter manifests for company/team/agent/project/task/skill definitions
  • Includes conversion helpers from parsed manifests to AgentCreateInput and export helpers for directory bundles

Project Insights

  • InsightStore (insight-store.ts, insight-types.ts) persists extracted project learnings
  • Uses fingerprint-based deduplication and run tracking
  • Run lifecycle is hardened through insight-run-executor.ts + InsightStore transition guards:
    • single active run per projectId + trigger (pending|running conflict)
    • terminal-state immutability for run rows
    • persisted failure classification (cancelled, timed_out, retryable_transient, non_retryable) and retry lineage metadata
    • append-only durable event trail in project_insight_run_events
  • Dashboard routes (insights-routes.ts) consume the core executor/store APIs for run start, cancel, retry, and event inspection (/api/insights/runs/:id/events)
  • POST /api/insights/:id/create-task remains a draft-payload endpoint (returns suggestedTitle/suggestedDescription); the dashboard InsightsView now uses that payload to create a real task through the normal app task-creation path (column: triage, sourceType: dashboard_ui, source metadata indicating insights origin)
  • Backed by project_insights, project_insight_runs, and project_insight_run_events

Research Runs

  • ResearchStore (research-store.ts, research-types.ts, research-settings.ts) persists bounded research runs, sources/events, exports, lifecycle metadata, and retry/cancel state transitions.
  • Backed by research_runs, research_exports, and research_run_events.
  • Engine orchestration is implemented in packages/engine/src/research-orchestrator.ts + research-step-runner.ts.
  • Dashboard/API surface is implemented under /api/research (packages/dashboard/src/research-routes.ts) with ResearchView.tsx in the app.
  • CLI surface is implemented in packages/cli/src/commands/research.ts with six subcommands (create, list, show, export, cancel, retry).
  • Agent tool surface is exposed via packages/cli/src/extension.ts (fn_research_run, fn_research_list, fn_research_get, fn_research_cancel, fn_research_retry).
  • Boundary contract (FN-3292):
    • ResearchStore owns persistence and lifecycle writes (status transitions, lifecycle event log rows, sources/results snapshots).
    • ResearchStepRunner owns provider I/O concerns only (provider selection, timeout/abort/provider-error classification, synthesis call execution); it does not read/write run state.
    • ResearchOrchestrator owns sequencing and failure policy (phase progression, provider fallback, partial-step continuation, terminal status choice) and interacts with store only through public store methods.
    • Provider substitution must remain data-driven: source metadata can carry provider identity, and fetching should resolve providers per source rather than relying on provider ordering.
  • Boundary note: research and insights are parallel subsystems sharing host infrastructure, not one table/store family.

Plugin System

  • PluginStore (plugin-store.ts) stores plugin installation state and settings (plugins table)
  • PluginLoader (plugin-loader.ts) loads/unloads plugin modules and emits lifecycle events
  • Plugin contributions now include both embedded uiSlots and top-level dashboardViews
  • Discovery endpoints:
    • GET /api/plugins/ui-slots
    • GET /api/plugins/dashboard-views
  • Dashboard management routes are implemented in packages/dashboard/src/plugin-routes.ts

Prompt Overrides

  • prompt-overrides.ts defines prompt key catalogs and per-role override validation
  • Provides override resolution/validation helpers (resolvePrompt, resolveRolePrompts, assertValidPromptOverrideMap)

Agent Permissions

  • agent-permissions.ts normalizes permissions and computes effective access state
  • Core helpers: normalizePermissions, computeAccessState, ROLE_DEFAULT_PERMISSIONS

Standalone roadmap model

Fusion now has two planning models in core:

  • Roadmap hierarchyRoadmap → RoadmapMilestone → RoadmapFeature
  • Mission hierarchyMission → Milestone → Slice → Feature → Task

The roadmap model is intentionally lightweight and independent from MissionStore/mission lifecycle semantics. It is meant for standalone planning, ordering, drag-and-drop moves, and future conversion flows into missions or tasks without coupling roadmap data to slice activation, autopilot, or mission status rollups.

Roadmap persistence (FN-1690/FN-1691):

  • RoadmapStore provides CRUD operations with atomic reorder/move semantics
  • All list queries use deterministic ordering: ORDER BY orderIndex ASC, createdAt ASC, id ASC
  • Covering indexes ensure efficient ordered reads without temp B-tree sorts
  • Cross-milestone feature moves atomically renumber both source and destination milestone scopes
  • FK cascade integrity: deleting a roadmap removes milestones and features
  • Export/handoff DTO methods for integration with downstream systems:
    • getRoadmapExport()RoadmapExportBundle (flat export payload)
    • getMissionPlanningHandoff()RoadmapMissionPlanningHandoff (mission conversion)
    • listFeatureTaskPlanningHandoffs()RoadmapFeatureTaskPlanningHandoff[] (all features as task handoffs)
    • getRoadmapFeatureHandoff()RoadmapFeatureTaskPlanningHandoff (single feature task handoff)
  • Pure handoff mapping helpers in roadmap-handoff.ts for read-only transformations

Roadmap handoff contract boundary (FN-1674):

  • Handoffs are read-only transformations — no mission/task records are created
  • Source lineage is preserved on every emitted item (roadmapId, milestoneId, featureId, titles, order indices)
  • Ordering is deterministic using normalizeRoadmapMilestoneOrder and normalizeRoadmapFeatureOrder
  • Not-found semantics: store handoff methods throw when roadmapId is unknown; routes map to HTTP 404
  • The combined handoff endpoint (GET /:roadmapId/handoff) returns both mission and task handoffs

Key roadmap invariants:

  • milestone ordering is scoped to a single roadmap and must remain contiguous + 0-based
  • feature ordering is scoped to a single milestone and must remain contiguous + 0-based
  • repair/normalization uses deterministic tie-breakers: orderIndex ASC, createdAt ASC, id ASC
  • cross-milestone feature moves must renumber both the source and destination milestone deterministically

Roadmap REST API endpoints (/api/roadmaps):

  • Roadmaps: GET /, POST /, GET /:roadmapId, PATCH /:roadmapId, DELETE /:roadmapId
  • Milestones: GET /:roadmapId/milestones, POST /:roadmapId/milestones, PATCH /milestones/:milestoneId, DELETE /milestones/:milestoneId, POST /:roadmapId/milestones/reorder
  • Features: GET /milestones/:milestoneId/features, POST /milestones/:milestoneId/features, PATCH /features/:featureId, DELETE /features/:featureId, POST /milestones/:milestoneId/features/reorder, POST /features/:featureId/move
  • Export/Handoff: GET /:roadmapId/export, GET /:roadmapId/handoff, GET /:roadmapId/handoff/mission, GET /:roadmapId/milestones/:milestoneId/features/:featureId/handoff/task

Database schema:

  • roadmaps — roadmap metadata (id, title, description, timestamps)
  • roadmap_milestones — milestone data with roadmapId FK
  • roadmap_features — feature data with milestoneId FK
  • idxRoadmapMilestonesRoadmapOrder — covering index for deterministic milestone ordering
  • idxRoadmapFeaturesMilestoneOrder — covering index for deterministic feature ordering

Shared utilities

From packages/core/src/index.ts exports (selected high-impact modules):

  • Memory + knowledge: memory-backend.ts, memory-compaction.ts, memory-dreams.ts, project-memory.ts, memory-insights.ts, insight-store.ts, insight-types.ts
  • Stores and plugin/routine helpers: chat-store.ts, routine-store.ts, plugin-store.ts, plugin-loader.ts, reflection-store.ts
  • Execution/runtime helpers: run-command.ts, board.ts, task-merge.ts, archive-db.ts
  • Settings + prompts + permissions: settings-schema.ts, prompt-overrides.ts, agent-permissions.ts, agent-prompts.ts
  • Node/system infrastructure: node-connection.ts, node-discovery.ts, system-metrics.ts, migration-orchestrator.ts
  • Identity/version/extensions: daemon-token.ts, app-version.ts, pi-extensions.ts
  • Agent companies import/export: agent-companies-parser.ts, agent-companies-exporter.ts, agent-companies-types.ts

Memory System

Fusion uses OpenClaw-style project memory files and separates memory into two responsibilities:

  1. Layered backend runtime memory (memory-backend.ts, project-memory.ts)
    • canonical long-term + layered memory access used by agents and dashboard APIs
  2. Insight extraction automation (memory-insights.ts, InsightStore)
    • scheduled extraction/pruning workflows over project memory plus insight/audit artifacts

Both systems currently use .fusion/memory/MEMORY.md as the canonical working source-of-truth.

Primary memory files:

  • Long-term: .fusion/memory/MEMORY.md
  • Daily notes: .fusion/memory/YYYY-MM-DD.md
  • Dream processing: .fusion/memory/DREAMS.md

Memory subsystems:

  • memory-backend.ts — backend contracts + file/readonly/qmd implementations
  • memory-compaction.ts — summarization/compaction automation
  • memory-dreams.ts — background dream processing for agent and project memory
  • memory-insights.ts + InsightStore — extracted insight synthesis and persistent insight/run storage

Pluggable backends (memory-backend.ts):

Backend Type Capabilities
FileMemoryBackend file Read/Write, Atomic writes, Persistent
ReadOnlyMemoryBackend readonly Read only, Non-persistent
QmdMemoryBackend qmd Read/Write, Persistent, CLI-based with file fallback

Backend registration:

import { registerMemoryBackend, resolveMemoryBackend } from "@fusion/core";

// Register custom backend
registerMemoryBackend(customBackend);

// Resolve based on settings
const backend = resolveMemoryBackend(settings);

Settings integration:

  • memoryEnabled: Toggle controls whether memory instructions are injected into prompts
  • memoryBackendType: Select which backend to use (file, readonly, qmd, or custom). Unknown types are accepted and persisted verbatim; runtime resolution falls back to DEFAULT_MEMORY_BACKEND (qmd).

QMD Backend Behavior: The QMD backend (qmd) delegates read/write I/O to the file backend and schedules background QMD index refreshes. For search, it attempts QMD query first and falls back to local .fusion/memory/ file search when QMD is unavailable, errors, or returns no matches.

Dashboard API:

  • GET /api/memory/backend — Returns current backend status and capabilities

See Memory Plugin Contract for the full plan.


5) Engine Package (@fusion/engine)

@fusion/engine executes the autonomous workflow.

Agent roles

  • Planning: the planning processor generates task plans (PROMPT.md) and selects eligible planning tasks by priority first, then FIFO (createdAt ascending) within each priority tier.
  • Executor: TaskExecutor (executor.ts) implements tasks in worktrees
  • Reviewer: reviewStep() (reviewer.ts) performs plan/code reviews
  • Merger: aiMergeTask() (merger.ts) merges approved work

Scheduling and execution

  • Scheduler (scheduler.ts) — dependency-aware task scheduling that dispatches eligible todo tasks by priority first, then FIFO (createdAt ascending) within each priority tier.
  • StepSessionExecutor (step-session-executor.ts) — per-step sessions + parallel wave execution
  • TaskCompletion (task-completion.ts) — completion gate helpers
  • SpecStaleness (spec-staleness.ts) — stale spec detection utilities
  • MissionExecutionLoop (mission-execution-loop.ts) — validator/fix loop orchestration
  • MissionFeatureSync (mission-feature-sync.ts) — feature↔task status synchronization
  • MissionAutopilot (mission-autopilot.ts) — mission slice auto-progression

Routine + cron automation

  • RoutineRunner (routine-runner.ts) — executes routine steps
  • RoutineScheduler (routine-scheduler.ts) — schedules due routines
  • CronRunner (cron-runner.ts) — cron-based AI/script jobs

Execution context + skills

  • SkillResolver (skill-resolver.ts) — resolves active skill sets for sessions
  • SessionSkillContext (session-skill-context.ts) — skill context materialization per run
  • ContextLimitDetector (context-limit-detector.ts) — context-window pressure checks
  • TokenCapDetector (token-cap-detector.ts) — token-cap enforcement checks
  • PluginRunner (plugin-runner.ts) — runtime plugin callback execution
  • AgentRuntime (agent-runtime.ts) — runtime adapter interface contract
  • RuntimeResolution (runtime-resolution.ts) — runtime selection and fallback logic
  • AgentSessionHelpers (agent-session-helpers.ts) — runtime-aware session creation helpers

Concurrency, recovery, and resiliency

  • AgentSemaphore (concurrency.ts) — slot acquisition
  • RecoveryPolicy (recovery-policy.ts) — retry/recovery decision policy
  • StuckTaskDetector (stuck-task-detector.ts) — inactivity/loop stall detection
  • GridlockDetector (gridlock-detector.ts) — detects all-blocked todo pipelines and emits notification events (plus explicit clear signals when gridlock resolves)
  • TransientErrorDetector (transient-error-detector.ts) — retriable error classification
  • SelfHealingManager (self-healing.ts) — auto-unpause/maintenance recovery actions
    • recoverGhostReviewTasks() is a fallback only for idle, non-terminal in-review states. Terminal/actionable states (notably status: "failed") are preserved and not auto-kicked back to todo.
    • recoverMergeableReviewTasks() only re-enqueues truly eligible tasks; retry-exhausted review tasks are skipped to avoid re-enqueue/no-op loops that keep refreshing updatedAt.
  • ProjectEngine settings lifecycle handlers (project-engine.ts) treat enginePaused as a soft pause: clearing it dispatches runtime resume and, when autoMerge is enabled, performs an in-review eligibility sweep to requeue mergeable review tasks.
  • UsageLimitPauser (usage-limit-detector.ts) and withRateLimitRetry (rate-limit-retry.ts)

Worktree and naming helpers

  • WorktreePool (worktree-pool.ts) — idle worktree reuse
  • WorktreeNames (worktree-names.ts) — deterministic worktree/branch naming

Observability and reflection

  • AgentLogger (agent-logger.ts) — structured per-agent run logging
  • RunAudit (run-audit.ts) — mutation audit tracking (DB/git/filesystem)
  • Notifier (notifier.ts) — legacy ntfy compatibility shim (NtfyNotifier) plus shared ntfy helpers
    • Runtime ownership: NtfyNotifier no longer owns an independent task-lifecycle listener graph; ProjectEngine injects the canonical NotificationService instance so task lifecycle notifications (task:moved, task:updated, task:merged) are emitted through a single path.
    • Compatibility scope: NtfyNotifier remains responsible for gridlock-only compatibility notifications (notifyGridlock) and legacy helper APIs.
    • Legacy gridlock ntfy delivery is cooldown-throttled: first detection notifies immediately, subsequent detections are suppressed for 15 minutes (even if blocked-task membership changes), and the cooldown resets as soon as gridlock fully clears.
  • NotificationService (notification/notification-service.ts) — provider lifecycle + event dispatch orchestration
  • NotificationProvider interface (@fusion/core notification/provider.ts) — pluggable provider contract
  • Built-in providers: NtfyNotificationProvider (notification/ntfy-provider.ts), WebhookNotificationProvider (notification/webhook-provider.ts)
  • AgentReflection (agent-reflection.ts) — reflection extraction and persistence

Heartbeat execution

Implemented in agent-heartbeat.ts:

  • HeartbeatMonitor
  • HeartbeatTriggerScheduler (timer, assignment, on-demand triggers)
  • WakeContext / per-agent runtime config support

Node/mesh runtime services

  • NodeHealthMonitor (node-health-monitor.ts) — remote node liveness/metrics checks
  • PeerExchangeService (peer-exchange-service.ts) — peer sync orchestration
  • Process lifecycle ownership:
    • fn serve / fn dashboard start a single process-level PeerExchangeService and stop it during shutdown.
    • CentralCore.startDiscovery() is invoked from CLI startup only after HTTP bind completes so discovery advertises the actual listening port.
    • InProcessRuntime stays project-scoped and intentionally does not own mesh startup/shutdown.

Remote access runtime

Operator setup + troubleshooting guide: Remote Access runbook.

  • remote-access/tunnel-process-manager.ts owns tunnel lifecycle orchestration with spawn-based, non-blocking process supervision.
  • remote-access/types.ts defines the runtime contract used by downstream API/TUI/headless layers:
    • Providers: "tailscale" | "cloudflare"
    • Lifecycle states: "stopped" | "starting" | "running" | "stopping" | "failed"
    • Error codes: invalid_config, start_failed, stop_failed, switch_failed, readiness_timeout, process_exit, etc.
  • remote-access/provider-adapters.ts provides provider-specific command composition + readiness parsing while enforcing config validation.
  • Cloudflare has two command variants:
    • Named tunnel mode: cloudflared tunnel --no-autoupdate run <tunnelName> (token from env)
    • Quick tunnel mode: cloudflared tunnel --url http://localhost:<dashboardPort> (ephemeral trycloudflare.com URL, no token)
  • Credential inputs are reference-based (tokenEnvVar, credentialsPath) and validated without logging raw secret values.
  • Redaction is applied to command previews and emitted log lines before publishing status/log events.
  • Deterministic stop semantics: graceful shutdown (SIGTERM) first, bounded wait, then force-kill fallback (SIGKILL).
  • Safe provider switching is stop-first: active provider fully stops before target start is attempted; failed starts emit switch_failed terminal status.
  • ProjectEngine.start() instantiates a per-project tunnel manager and applies startup restore policy from remoteAccess.lifecycle:
    • restore is attempted only when rememberLastRunning is true, a prior-running marker exists, provider config is valid, and runtime prerequisites are available.
    • restore skips/failures are non-fatal to engine startup and clear stale running markers to avoid restart loops.
  • Manual lifecycle remains explicit: only startRemoteTunnel() / stopRemoteTunnel() transitions mutate runtime state; provider/settings updates do not auto-start tunnels.
  • ProjectEngine exposes restore diagnostics via getRemoteTunnelRestoreDiagnostics() (applied|skipped|failed + machine-readable reason).

Multi-runtime support + IPC

  • Runtime contracts: project-runtime.ts
  • Orchestration: ProjectManager and HybridExecutor
  • Runtime implementations:
    • runtimes/in-process-runtime.ts
    • runtimes/child-process-runtime.ts
    • runtimes/remote-node-runtime.ts
  • IPC protocol/transport:
    • ipc/ipc-protocol.ts
    • ipc/ipc-host.ts
    • ipc/ipc-worker.ts
    • worker entrypoint: runtimes/child-process-worker.ts

6) Dashboard Package (@fusion/dashboard)

Server layer

  • Entry exports: packages/dashboard/src/index.ts
  • Main server factory: createServer() in packages/dashboard/src/server.ts
  • Primary API router: createApiRoutes() in packages/dashboard/src/routes.ts

Key server capabilities:

  • REST APIs for tasks, git, GitHub, agents, missions, planning, automations/routines, settings
  • System stats snapshot and vitest process controls APIs (GET /api/system-stats, POST /api/kill-vitest) exposing dashboard process/system telemetry (including host memory rendered as both numeric values and a visual usage bar in the System Stats modal), task/agent aggregates, and manual vitest process termination
  • Remote access APIs (/api/remote/*) for provider config, activation, tunnel lifecycle, status, token issuance, authenticated URL generation, and QR payload generation
    • Operational runbook (prereqs/security/troubleshooting): docs/remote-access.md
    • /api/remote/tunnel/start, /api/remote/tunnel/stop, and /api/remote/tunnel/kill-external cover tunnel lifecycle and external funnel cleanup.
    • /api/remote/status includes tunnel status, external funnel detection (externalTunnel when managed tunnel is stopped), plus restore diagnostics (restore.outcome + restore.reason) with parity between dashboard and headless fn serve runtimes.
  • Remote auth handoff endpoints:
    • POST /api/remote-access/auth/login-url (daemon-auth protected) issues a tokenized phone-login URL for either persistent or short-lived mode.
    • GET /remote-login?rt=<token> (public) validates remote token strategy and redirects to dashboard auth handoff (/?token=<daemonToken> when daemon auth is enabled, otherwise /).
    • Invalid/missing/expired remote tokens return 401 JSON with deterministic codes: remote_token_invalid, remote_token_missing, remote_token_expired.
  • Chat APIs (/api/chat/*) with streaming response support (routes.ts, chat.ts)
  • Dev-server lifecycle + persistence APIs (/api/dev-server/*) backed by:
    • dev-server-routes.ts (router factory + per-project runtime registry)
    • dev-server-process.ts (DevServerProcessManager for spawn/stop/restart/url-detection)
    • dev-server-store.ts (durable .fusion/dev-server.json state + log ring buffer)
    • dev-server-detect.ts (project/workspace script auto-detection + confidence scoring)
    • Note: this hyphenated dev-server-* family is the canonical runtime owner today; see docs/dev-server-module-boundary-audit.md for the FN-2212 boundary/consolidation audit covering parallel devserver-* modules.
  • Plugin management routes (plugin-routes.ts)
  • Insights routes (insights-routes.ts)
  • Research routes (research-routes.ts) — /api/research surface for runs, details, cancel/retry, exports, create-task, and attach-task actions; supports graceful degradation envelopes via availability payloads when capabilities are unavailable
  • Roadmap routes (roadmap-routes.ts)
  • Project-scoped store reuse via project-store-resolver.ts
  • Rate limiting (rate-limit.ts)
  • Static SPA hosting (Vite build output)

Runtime diagnostics logging contract

  • Dashboard/server runtime diagnostics use the shared RuntimeLogger contract (packages/dashboard/src/runtime-logger.ts) instead of ad hoc console.* calls.
  • createServer() accepts ServerOptions.runtimeLogger; when omitted it defaults to a console-backed logger, preserving readable output in non-TTY/headless modes.
  • CLI TTY dashboard sessions inject a logger backed by DashboardLogSink, so runtime diagnostics from server/routes are captured in the TUI log buffer.
  • Sensitive remote-auth material is never logged raw; route/UI responses mask persistent token values unless explicitly requested by token-generation actions.
  • Short-lived remote auth tokens are runtime-ephemeral (in-memory only, cleared on process restart) and TTL-enforced server-side against persisted remoteAccess.tokenStrategy.shortLived.ttlMs plus issued expiry metadata.
  • Remote login links carry auth material in query params (rt then token on redirect). Treat links/QR screenshots as secrets: they can leak through history, screenshots, and chat logs; prefer short-lived mode for sharing.
  • Intentional startup/banner text in fn dashboard and fn serve remains direct plain output for readability and backward-compatible scripting behavior.

Real-time channels

  • SSE: /api/events (sse.ts)
    • Emits task:*, mission events, AI session updates, automation schedule events (schedule:created, schedule:updated, schedule:deleted, schedule:run), and research run lifecycle events (research:run:created, research:run:updated, research:run:completed, research:run:failed, research:run:cancelled) when available
    • Project-scoped: resolves project context from query param or engine manager
    • Canonical maintainer contract (ownership/lifecycle/scoping/pitfalls and shared-vs-dedicated stream boundaries): docs/dashboard-realtime.md
  • Chat streaming: /api/chat/sessions/:id/messages (routes.ts + chat.ts)
    • Streams assistant responses as SSE events for chat sessions
  • Chat session queries: /api/chat/sessions (routes.ts)
    • Existing list behavior is unchanged (status=active|archived|all returns an array)
    • Quick Chat resume uses targeted lookup params: agentId, optional modelProvider + modelId, plus resume=1
    • Validation requires modelProvider and modelId together; partial model pairs return 400
    • Targeted lookup returns only the newest matching active session (or null) to avoid scanning every active session client-side
  • Task log stream: /api/tasks/:id/logs/stream (server.ts)
    • SSE endpoint for live task log streaming with project scope resolution
  • Dev-server stream: /api/dev-server/logs/stream (dev-server-routes.ts)
    • SSE stream emits history, log, stopped, and failed events
    • initial connection replays persisted logHistory and then follows live process output
    • companion endpoints: /api/dev-server/detect, /config, /status, /start, /stop, /restart, /preview-url
  • Badge WebSocket: /api/ws (server.ts, websocket.ts)
    • Scope-keyed channels (badge:{scopeKey}:{taskId}) prevent cross-project collisions
  • Terminal WebSocket: /api/terminal/ws (server.ts, terminal-service.ts)
    • Project-scoped terminal session validation + safe unscoped fallback

Frontend SPA layer

  • App entry: packages/dashboard/app/main.tsx
  • Root composition: packages/dashboard/app/App.tsx
  • Core board components: Board.tsx, Column.tsx, TaskCard.tsx, TaskDetailModal.tsx, ListView.tsx
  • Board column ordering (board view only): task cards within each board column are sorted by priority descending (urgenthighnormallow) and then by numeric task ID ascending (lower ID first). Missing or invalid priority values normalize to normal. In the in-review column, tasks with status === "merging" or status === "merging-pr" are pinned above non-merging tasks, with the priority-then-ID ordering applied within each pinned/non-pinned group.
  • Task detail surface is shared through TaskDetailContent (exported from TaskDetailModal.tsx): desktop/tablet ListView renders it inline in the split right pane, while mobile and non-list entry points continue using TaskDetailModal.
  • In desktop split mode, ListView now uses a compact sidebar-first control layout (count/actions/summary chips + collapsible "View options" panel) to keep list controls dense alongside the inline detail pane; mobile keeps the card-first flow with a toolbar "View options" entry point for the same visibility/filter toggles.
  • Chat system UI: ChatView.tsx, QuickChatFAB.tsx
  • Planning/roadmap/insight UI: MissionManager.tsx, RoadmapsView.tsx, TodoView.tsx, InsightsView.tsx, DocumentsView.tsx
  • Dev server UI: DevServerView.tsx (controls + status/log panel + embedded preview with iframe fallback messaging)

CSS Architecture

The dashboard's CSS is split between a consolidated global stylesheet and modular per-component files:

  • Global stylesheet (packages/dashboard/app/styles.css, ~4,500 lines)
    • Design tokens (spacing, colors, shadows, transitions, fonts)
    • Primitive component classes (.btn, .card, .modal, .form-input)
    • Cross-component @media overrides and breakpoint definitions
  • Per-component stylesheets (56+ files in packages/dashboard/app/components/)
    • Each component has a co-located ComponentName.css file
    • Each ComponentName.tsx imports its stylesheet: import "./ComponentName.css";
    • Component-specific CSS rules live in the component's .css file, not in the root stylesheet

Lazy-loaded views (bundle size optimization): The following 15 views are lazy-loaded via React.lazy() with <Suspense fallback={null}>:

  • AgentsView, RoadmapsView, TodoView, NodesView, ChatView, MemoryView, ResearchView
  • DevServerView, InsightsView, DocumentsView, SkillsView
  • SetupWizardModal, PluginManager, PiExtensionsManager, `AgentDetailView

A prefetchLazyViews() function runs once on mount via requestIdleCallback to warm chunks. Do not make these views eager — bundle size is carefully managed.

Key hooks

  • Task + realtime: useTasks.ts, useBadgeWebSocket.ts, useAiSessionSync.ts
  • Chat: useChat.ts, useQuickChat.ts
  • Documents/insights/memory: useDocuments.ts, useInsights.ts, useMemoryBackendStatus.ts, useMemoryData.ts
  • Planning/roadmaps: useRoadmaps.ts
  • Dev server: useDevServer.ts (status hydration, command controls, reconnect stream handling, project-scope reset)
  • Project/agents/setup: useProjects.ts, useCurrentProject.ts, useAgents.ts, useSetupReadiness.ts
  • UX/platform helpers: useFavorites.ts, useAuthOnboarding.ts, useDeepLink.ts, useTerminal.ts

Planning and decomposition features

  • Backend planners: planning.ts, subtask-breakdown.ts, roadmap-suggestions.ts
  • UI modals: PlanningModeModal.tsx, SubtaskBreakdownModal.tsx, milestone interview flows
  • Multi-task creation endpoints are wired under planning/subtask routes in routes.ts

Health and monitoring endpoints

  • Health check: GET /api/health
    • Returns liveness status for load balancers and monitoring
    • Response: { status: "ok", version: string, uptime: number }
    • No authentication required

Node settings sync and update-check endpoints

Method Path Description
GET /api/nodes/:id/settings Fetch settings from a remote node.
POST /api/nodes/:id/settings/push Push local settings to a remote node.
POST /api/nodes/:id/settings/pull Pull settings from a remote node.
GET /api/nodes/:id/settings/sync-status Get sync status and diff summary.
POST /api/nodes/:id/auth/sync Sync model auth credentials.
POST /api/settings/sync-receive Receive pushed settings (inbound).
POST /api/settings/auth-receive Receive auth credentials (inbound).
GET /api/settings/auth-export Export local auth credentials.
GET /api/update-check Read cached/TTL-guarded npm update status for @runfusion/fusion (respects updateCheckEnabled).
POST /api/update-check/refresh Clear cached update data and force a fresh npm update check.
GET /api/updates/check Perform an on-demand npm registry check for the latest @runfusion/fusion version (no cache).

Run Audit API

The run-audit system records every mutation performed by the engine across three domains:

  • Database — task:create, task:update, task:move, etc.
  • Git — worktree:create, commit:create, merge:resolve, etc.
  • Filesystem — file:write, prompt:write, attachment:create, etc.

Events are tied to specific run IDs for end-to-end traceability.

Run audit endpoint:

  • GET /api/agents/:id/runs/:runId/audit — Returns audit trail for a specific agent run
    • Query params: ?domain=database|git|filesystem for filtering
    • Requires agent ownership or admin access

7) CLI Package (@runfusion/fusion)

Command entrypoint

  • packages/cli/src/bin.ts
    • Bootstraps environment
    • Parses global flags (including --project)
    • Routes subcommands (task, project, settings, git, backup, mission, agent, message, etc.)

Command modules

  • packages/cli/src/commands/*
    • Task operations, settings, git wrappers, backup operations, project/node management
    • TUI component (packages/cli/src/commands/dashboard-tui/)
      • Ink-based terminal UI (status panel, logs, cursor visibility, tail-follow)
      • Merged from former @fusion/tui package
      • Invoked as part of the fn command (no separate package or pnpm tui command)

Project selection

  • packages/cli/src/project-resolver.ts
    • Resolution order: explicit --project → CWD detection (.fusion) → default/fallback logic
    • Integrates CentralCore and ProjectManager

Pi extension

  • packages/cli/src/extension.ts
    • Registers tool set for in-chat task/mission operations
    • Uses TaskStore directly for extension-side actions

Binary identity

  • Published package defines fn binary (packages/cli/package.json)
  • Running fn with no arguments defaults to dashboard (web UI by default)

8) Storage Architecture

Fusion uses a hybrid storage model.

Per-project storage

  • SQLite DB: .fusion/fusion.db
  • Filesystem blobs (task-local artifacts):
    • .fusion/tasks/{TASK_ID}/PROMPT.md
    • .fusion/tasks/{TASK_ID}/agent.log
    • .fusion/tasks/{TASK_ID}/attachments/*

SQLite schema is initialized in packages/core/src/db.ts and uses:

  • WAL mode (PRAGMA journal_mode = WAL)
  • Foreign keys (PRAGMA foreign_keys = ON)
  • __meta.lastModified for change detection/polling

Central storage (multi-project)

  • Central DB: ~/.fusion/fusion-central.db
  • Schema in packages/core/src/central-db.ts
    • projects, projectHealth, centralActivityLog, globalConcurrency, nodes, peerNodes, settingsSyncState, __meta

Memory files

  • OpenClaw-style memory workspace:
    • .fusion/memory/MEMORY.md
    • .fusion/memory/YYYY-MM-DD.md
    • .fusion/memory/DREAMS.md
  • The legacy top-level memory file is migration-compatibility only (seed/alias behavior) and is not canonical storage.

File-based side stores

Some data remains intentionally filesystem-based:

  • Agents: .fusion/agents/* (AgentStore)
  • Messages: .fusion/messages/* (MessageStore)

Migration from legacy file storage

  • Detection + migration: packages/core/src/db-migrate.ts
  • Migrates legacy task/config/log/archive/automation/agent data into SQLite
  • Creates .bak backups (for example task.json.bak, config.json.bak, archive.jsonl.bak)

Archive system

  • Archived task snapshots are stored in SQLite archivedTasks
  • TaskStore archive helpers:
    • archiveTaskAndCleanup()
    • cleanupArchivedTasks()
    • readArchiveLog() / findInArchive()
    • unarchiveTask() with restore behavior

9) Task Lifecycle

Lifecycle constants are defined in packages/core/src/types.ts:

  • Columns: planning, todo, in-progress, in-review, done, archived
  • Transition rules via VALID_TRANSITIONS

Lifecycle flow

planning
  │ (Planning processor writes PROMPT.md)
  ▼
todo
  │ (Scheduler selects task, dependencies satisfied)
  ▼
in-progress
  │ (TaskExecutor runs in worktree)
  ▼
in-review
  │ (implementation complete + pre-merge workflow steps)
  ▼
done
  │
  └──────────────▶ archived

Execution detail

  • Planning phase: the planning processor generates an executable plan
  • Execution phase: TaskExecutor performs implementation, tool calls, tests/build commands
  • Review phase: optional reviewStep() workflow depending on prompt review level (bypassed in fast mode)
  • Merge phase: aiMergeTask() handles merge strategy and post-merge workflow steps

Fast Mode: Tasks with executionMode: "fast" bypass the review_step tool injection and pre-merge workflow steps. Completion blockers (tests, build, typecheck from PROMPT.md) and post-merge workflow steps remain enforced.

Step status model

Task steps use statuses: pending, in-progress, done, skipped.

Workflow steps

  • Defined in project config as WorkflowStep
  • Pre-merge steps run in executor (runWorkflowSteps()) — bypassed in fast mode
  • Post-merge steps run in merger (runPostMergeWorkflowSteps())

10) Agent System

Fusion has two complementary agent models:

  1. Task pipeline agents (planning/executor/reviewer/merger) managed by engine runtime
  2. Persistent registered agents managed by AgentStore

Persistent agent storage

packages/core/src/agent-store.ts persists to:

  • .fusion/agents/{id}.json
  • .fusion/agents/{id}-heartbeats.jsonl
  • .fusion/agents/{id}-keys.jsonl
  • .fusion/agents/{id}-revisions.jsonl

Agent spawning from executor

TaskExecutor supports hierarchical child agents via:

  • createSpawnAgentTool()
  • runSpawnedChild()
  • terminateChildAgent() / terminateAllChildren()

Limits are controlled by project settings (maxSpawnedAgentsPerParent, maxSpawnedAgentsGlobal).

Heartbeat monitoring and triggers

agent-heartbeat.ts provides:

  • Health monitoring and run tracking (HeartbeatMonitor)
  • Trigger scheduling (HeartbeatTriggerScheduler) for:
    • timer
    • task assignment
    • on-demand runs

Custom instructions

packages/engine/src/agent-instructions.ts resolves per-agent instruction text/path with path-traversal and extension validation.


11) Multi-Project Architecture

Multi-project orchestration spans core + engine.

Core control plane

  • CentralCore (packages/core/src/central-core.ts) maintains:
    • Project registry
    • Health metrics
    • Unified central activity feed
    • Global concurrency state
    • Node registry (local / remote)

Engine orchestration

  • HybridExecutor (packages/engine/src/hybrid-executor.ts) is the top-level orchestrator
  • ProjectManager instantiates per-project runtimes and forwards events with project attribution

Runtime abstraction

Defined in project-runtime.ts:

  • ProjectRuntime interface
  • RuntimeStatus and RuntimeMetrics

Implementations:

  • InProcessRuntime
  • ChildProcessRuntime
  • RemoteNodeRuntime

IPC protocol (child-process mode)

In packages/engine/src/ipc/ipc-protocol.ts:

  • Host commands: START_RUNTIME, STOP_RUNTIME, GET_STATUS, GET_METRICS, PING
  • Worker events: TASK_CREATED, TASK_MOVED, TASK_UPDATED, ERROR_EVENT, HEALTH_CHANGED

Multi-project runtime diagram

                   HybridExecutor
                        │
                ┌───────┴────────┐
                │   ProjectManager│
                └───┬─────────┬───┘
                    │         │
        ┌───────────▼───┐  ┌──▼──────────────┐
        │InProcessRuntime│  │ChildProcessRuntime│
        │(local process) │  │(fork + IPC host)  │
        └──────┬─────────┘  └──┬───────────────┘
               │                │
          TaskStore/Scheduler   │
                                ▼
                        child-process-worker
                        + InProcessRuntime

Task Routing Architecture

Task dispatch routing is resolved in two layers:

  1. Task routing resolution (packages/engine/src/effective-node.ts)
    • resolveEffectiveNode(task, settings) applies precedence:
      1. Task.nodeIdtask-override
      2. ProjectSettings.defaultNodeIdproject-default
      3. no node set → local
  2. Runtime selection (packages/engine/src/project-manager.ts)
    • child-process isolation always uses ChildProcessRuntime
    • in-process isolation uses RemoteNodeRuntime when the registered project host node is remote
    • otherwise uses InProcessRuntime

Dispatch flow in scheduler

Unavailable-node policy

unavailableNodePolicy is a validated/stored project setting (block default, fallback-local allowed) and is enforced during scheduler dispatch when both conditions are true:

  • effective routing selected a remote node, and
  • SchedulerOptions.nodeHealthMonitor is configured.

Behavior summary:

  • block (default): unhealthy node status (offline, error, connecting) blocks dispatch for that poll cycle and keeps the task in todo.
  • fallback-local: unhealthy remote node reroutes dispatch to local execution (effectiveNodeId: null, effectiveNodeSource: "local").
  • unknown node health (undefined) is treated as allow/continue.

Active-task node-override guard

packages/core/src/node-override-guard.ts enforces immutable routing overrides for active tasks:

  • validateNodeOverrideChange() blocks node override updates while task column is in-progress
  • returns reason task-in-progress

TaskStore.updateTask() applies this guard before persisting nodeId changes.

Routing activity visibility

Routing decisions are visible in task activity/log entries and in task metadata (effectiveNodeId, effectiveNodeSource), and surfaced in dashboard routing UI + fn task show output.

See also:


12) Settings Hierarchy

Settings are split by scope.

Global scope

  • File: ~/.fusion/settings.json
  • Managed by GlobalSettingsStore (packages/core/src/global-settings.ts)
  • Examples: themeMode, colorTheme, default model/provider, notification preferences (ntfy* legacy fields and notificationProviders)

Project scope

  • Stored in per-project config (config table + compatibility file .fusion/config.json)
  • Includes engine/runtime controls (maxConcurrent, autoMerge, worktree and workflow behavior, etc.)

Merged view

  • Settings combines global + project values
  • Defaults in DEFAULT_GLOBAL_SETTINGS and DEFAULT_PROJECT_SETTINGS
  • Scope key lists in GLOBAL_SETTINGS_KEYS and PROJECT_SETTINGS_KEYS

Model controls

  • Per-task model overrides on task fields:
    • modelProvider / modelId
    • validatorModelProvider / validatorModelId
    • planningModelProvider / planningModelId
    • thinkingLevel
  • Reusable presets via ModelPreset
  • Agent prompt template overrides via agentPrompts

13) Git Integration

Git behavior is implemented primarily in engine executor/merger + dashboard/CLI git APIs.

Worktree model

  • Each active task runs in isolated worktree under .worktrees/*
  • Executor creates branches like fusion/{task-id} (executor.ts)
  • WorktreePool can recycle idle worktrees when enabled

Merge strategies

  • Setting type: MergeStrategy = "direct" | "pull-request" (types.ts)
  • aiMergeTask() in merger.ts performs merge flow
  • Supports workflow-step execution after merge (post-merge phase)

Conflict handling

merger.ts includes conflict classification and auto-resolution helpers:

  • lock files (LOCKFILE_PATTERNS)
  • generated files (GENERATED_PATTERNS)
  • whitespace-trivial conflicts

PR and badge integration

  • Engine PR monitor: pr-monitor.ts and pr-comment-handler.ts
  • Dashboard GitHub APIs + webhook route in routes.ts
  • Badge snapshots are streamed via /api/ws and useBadgeWebSocket.ts

14) Key Design Decisions

  1. SQLite + WAL for local-first reliability

    • Chosen for simple deployment and strong transactional behavior
    • WAL mode enables concurrent readers/writers with low ops overhead
  2. Hybrid persistence (DB + filesystem blobs)

    • Structured metadata in SQLite, large text/artifacts in task directories
    • Keeps DB efficient while preserving inspectable task artifacts
  3. Git worktree isolation as core execution primitive

    • Prevents cross-task interference
    • Makes concurrent task execution safer
    • Enables deterministic cleanup/retry/recovery
  4. Agent-as-tool-caller pattern

    • Engine tools (task_update, task_log, review_step, spawn_agent, etc.) create explicit, auditable state transitions
    • Prompts are role-specific (TRIAGE_SYSTEM_PROMPT, EXECUTOR_SYSTEM_PROMPT, etc.)
  5. Separation of real-time channels by concern

    • SSE for broad board/missions/session state updates (/api/events)
    • Dedicated badge WebSocket (/api/ws) for lightweight PR/issue badge snapshots
  6. Multi-project control plane with runtime abstraction

    • CentralCore decouples registry/health/concurrency from per-project execution
    • ProjectRuntime interface allows multiple isolation strategies (in-process, child-process, remote node)

Source Map (quick navigation)

  • Core exports: packages/core/src/index.ts
  • Engine exports: packages/engine/src/index.ts
  • Dashboard exports: packages/dashboard/src/index.ts
  • CLI entry: packages/cli/src/bin.ts
  • Pi extension: packages/cli/src/extension.ts
  • Runtime abstraction: packages/engine/src/project-runtime.ts
  • Multi-project orchestrator: packages/engine/src/hybrid-executor.ts
  • Task routing resolver: packages/engine/src/effective-node.ts
  • Node override guard: packages/core/src/node-override-guard.ts