# Mosaic Stack Self-hosted, multi-user AI agent platform. One config, every runtime, same standards. Mosaic gives you a unified launcher for Claude Code, Codex, OpenCode, and Pi — injecting consistent system prompts, guardrails, skills, and mission context into every session. A NestJS gateway provides the API surface, a Next.js dashboard gives you the UI, and a plugin system connects Discord, Telegram, and more. ## Quick Install ```bash curl -fsSL https://mosaicstack.dev/install.sh | bash ``` Or use the direct URL: ```bash bash <(curl -fsSL https://git.mosaicstack.dev/mosaicstack/stack/raw/branch/main/tools/install.sh) ``` The installer auto-launches the setup wizard, which walks you through gateway install and verification. Flags for non-interactive use: ```bash bash <(curl -fsSL …) --yes # Accept all defaults bash <(curl -fsSL …) --yes --no-auto-launch # Install only, skip wizard ``` This installs both components: | Component | What | Where | | ----------------------- | ---------------------------------------------------------------- | -------------------- | | **Framework** | Bash launcher, guides, runtime configs, tools, skills | `~/.config/mosaic/` | | **@mosaicstack/mosaic** | Unified `mosaic` CLI — TUI, gateway client, wizard, auto-updater | `~/.npm-global/bin/` | ### Install lanes | Lane | Command | Use when | Source | | ------------------------ | ------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------- | | Stable | `bash tools/install.sh` | You want the released Mosaic CLI/framework | npm registry `@mosaicstack/mosaic@latest` + framework archive at `main` | | Prerelease integration | `bash tools/install.sh --next` | You want the current `next` integration branch | Build-from-source at `next` | | Contributor/source build | `bash tools/install.sh --dev --ref X` | You are testing a branch before release; `--ref` wins | Build-from-source at the requested ref | `--next` is shorthand for the prerelease integration lane: it enables source-build mode and uses `next` unless an explicit `--ref` or `MOSAIC_REF` is provided. After install, the wizard runs automatically or you can invoke it manually: ```bash mosaic wizard # Full guided setup (gateway install → verify) ``` ### Requirements - Node.js ≥ 22 - npm (for global @mosaicstack/mosaic install) - One or more runtimes: - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) - [Codex](https://github.com/openai/codex) - [OpenCode](https://opencode.ai) - [Pi](https://pi.dev) ## Usage ### Launching Agent Sessions ```bash mosaic pi # Launch Pi with Mosaic injection mosaic claude # Launch Claude Code with Mosaic injection mosaic codex # Launch Codex with Mosaic injection mosaic opencode # Launch OpenCode with Mosaic injection mosaic yolo claude # Claude with dangerous-permissions mode mosaic yolo pi # Pi in yolo mode ``` The launcher verifies your config, checks for `SOUL.md`, injects your `AGENTS.md` standards into the runtime, and forwards all arguments. Pi launches default to a token-lean skill posture: `mosaic pi` passes `--no-skills` so Pi does not preload every global skill description into the system prompt. Use `MOSAIC_PI_SKILL_MODE=all mosaic pi` for the legacy all-skills catalog, or `MOSAIC_PI_SKILL_MODE=discover mosaic pi` to let Pi use its native settings/project skill discovery. Mosaic also loads its Pi extensions from `~/.config/mosaic/runtime/pi/`. Inside Pi, `/goal set ` starts a bounded persistent loop that checks every turn and successful compaction, requires two evidence-bearing completion reports, and can be inspected or stopped with `/goal status`, `/goal pause`, `/goal resume`, and `/goal cancel`. Controller-owned goal-state entries redact common credential shapes, but Pi's model/tool-call history is separate, so goals and evidence must never contain secrets or raw sensitive output. Mosaic does not install this extension into `~/.pi/agent/extensions/`. ### TUI & Gateway ```bash mosaic tui # Interactive TUI connected to the gateway mosaic gateway login # Authenticate with a gateway instance mosaic sessions list # List active agent sessions ``` ### Gateway Management ```bash mosaic gateway install # Install and configure the gateway service mosaic gateway verify # Post-install health check mosaic gateway login # Authenticate and store a session token mosaic gateway config rotate-token # Rotate your API token mosaic gateway config recover-token # Recover a token via BetterAuth cookie ``` If you already have a gateway account but no token, use `mosaic gateway config recover-token` to retrieve one without recreating your account. ### Configuration Mosaic supports three storage tiers: `local` (PGlite, single-host), `standalone` (PostgreSQL, single-host), and `federated` (PostgreSQL + pgvector + Valkey, multi-host). See [Federated Tier Setup](docs/federation/SETUP.md) for multi-user and production deployments, or [Migrating to Federated](docs/guides/migrate-tier.md) to upgrade from existing tiers. ```bash mosaic config show # Print full config as JSON mosaic config get # Read a specific key mosaic config set # Write a key mosaic config edit # Open config in $EDITOR mosaic config path # Print config file path ``` ### Management ```bash mosaic doctor # Health audit — detect drift and missing files mosaic sync # Sync skills from canonical source mosaic skill list # Audit Claude skill registrations and conflicts mosaic skill register # Register one canonical skill with Claude Code mosaic skill unregister # Remove one Mosaic-owned Claude link mosaic update # Update CLI/framework and auto-register canonical skills mosaic wizard # Full guided setup wizard mosaic bootstrap # Bootstrap a repo with Mosaic standards mosaic coord init # Initialize a new orchestration mission mosaic prdy init # Create a PRD via guided session ``` ### Sub-package Commands Each Mosaic sub-package exposes its API surface through the unified CLI: ```bash # User management mosaic auth users list mosaic auth users create mosaic auth sso # Agent brain (projects, missions, tasks) mosaic brain projects mosaic brain missions mosaic brain tasks mosaic brain conversations # Agent forge pipeline mosaic forge run [--simulate] # fails closed (FORGE_NO_EXECUTOR) with no executor wired; --simulate for typed simulated runs mosaic forge status mosaic forge resume [--simulate] # same fail-closed rule as forge run mosaic forge personas # Structured logging mosaic log tail mosaic log search mosaic log export mosaic log level # MACP protocol mosaic macp tasks mosaic macp submit mosaic macp gate mosaic macp events # Agent memory mosaic memory search mosaic memory stats mosaic memory insights mosaic memory preferences # Task queue (Valkey) mosaic queue list mosaic queue stats mosaic queue pause mosaic queue resume mosaic queue jobs mosaic queue drain # Object storage mosaic storage status mosaic storage tier mosaic storage export mosaic storage import # Schema migration is unavailable in this release. The current storage wrapper shells # directly to `pnpm --filter @mosaicstack/db db:migrate`; it is legacy N-1, # uncertified, and MUST NOT be invoked pending KBN-101-02/-03/-06/-08 activation. # Future schema migration is non-operative: external bootstrap → TLS/roles → runner # --run → runner --verify → readiness. Tier copy uses only the separately held secure # migrate-tier route. ``` ### Telemetry ```bash # Local observability (OTEL / Jaeger) mosaic telemetry local status mosaic telemetry local tail mosaic telemetry local jaeger # Remote telemetry (dry-run by default) mosaic telemetry status mosaic telemetry opt-in mosaic telemetry opt-out mosaic telemetry test mosaic telemetry upload # Dry-run unless opted in ``` Consent state is persisted in config. Remote upload is a no-op until you run `mosaic telemetry opt-in`. ## Standalone container deployment The `stack` profile runs PostgreSQL, Valkey, the gateway, and the bundled webUI. Copy `.env.example` to `.env`, generate `BETTER_AUTH_SECRET`, then start the profile: ```bash cp .env.example .env printf 'BETTER_AUTH_SECRET=%s\n' "$(openssl rand -hex 32)" >> .env docker compose --profile stack up -d ``` The optional dogfood overlay gives one dedicated in-stack agent a writable stack worktree and its own read-only credential slot. It does not mount the fleet brain or any other seat. Prepare a `next`-based worktree and an unprivileged `code-dogfood-01` functional seat outside the container, then set these paths in `.env`: ```dotenv MOSAIC_DOGFOOD_WORKTREE=/path/to/mosaic-stack-worktrees/dogfood-1487 MOSAIC_DOGFOOD_COMMON_GIT_DIR=/path/to/mosaic-stack/.git MOSAIC_DOGFOOD_SEAT_HOME=/path/to/.mosaic/fleet/agents/code-dogfood-01 ``` The common Git directory must match the worktree's `.git` pointer. The seat home must contain only that seat's credential at `secrets/gitea-mosaicstack-code-dogfood-01.token`. Never place the token value in `.env`. Start the overlay with: ```bash docker compose \ -f docker-compose.yml \ -f docker-compose.dogfood.yml \ --profile stack up -d ``` The overlay removes the general shell tool for every session, including admins. File tools stay inside the mounted checkout. Two dedicated delivery tools stage explicit paths, run the CI queue guard, push through `git-credential-mosaic`, and open PRs through `pr-create.sh`. They resolve only the `code-dogfood-01` slot and fail if it is absent. The overlay enables Docker's init process so the R4 helper can establish the gateway's seat lineage below PID 1. This deployment route is separate from the local source-development restrictions below. ## Development ### Prerequisites - Node.js ≥ 22 - pnpm 10.6+ - Docker & Docker Compose ### Setup ```bash git clone git@git.mosaicstack.dev:mosaicstack/stack.git cd stack # Install dependencies. The local tier uses in-process PGlite; leave DATABASE_URL unset. # The pnpm store defaults to $HOME/.local/share/pnpm/store. Override it without # editing the checkout with NPM_CONFIG_STORE_DIR=$HOME/another-store if needed. pnpm install # Verify dependencies and generated state before running source-quality gates. # Missing dependencies exit 42; stale/foreign apps/web/.next state exits 43. # The web build certifies its exact standalone symlink manifest; added, removed, # retargeted, or manifest-only-tampered generated links also exit 43. This detects # accidental, independent, stale, and foreign-residue mutation—the class exposed by # a five-month-stale .next that produced 19 phantom TS2307 errors. # It does NOT defend against a same-UID actor that can rewrite both manifest and # marker consistently (CWE-345). RM-59 tracks the required executor/spine-side # trust anchor outside worktree authority. pnpm preflight # Optional local queue service only. This does not start PostgreSQL. docker compose up -d valkey # The current Gateway/Web local process is held; see docs/guides/dev-guide.md. # Do not start it until KBN-101-02 makes inherited dotenv/DSN state fail closed. ``` ### Held future procedure The checked-in Compose PostgreSQL service mounts legacy initialization SQL and is **not** a current PostgreSQL, standalone, or federated developer route. Do not start it with Compose, invoke initialization SQL, or treat the planned migrator as currently executable. **Held future activation procedure — non-operative and no current command authority until KBN-101-00, KBN-101-03, and KBN-101-05 land:** external bootstrap → TLS/roles → `mosaic-db-migrator --run` → `mosaic-db-migrator --verify` → Gateway/Compose readiness. The future deployment artifacts—not this README—will provide the reviewed commands and secret-consumer interface. For local data-layer work, PGlite needs no PostgreSQL service. The optional Compose command above starts only Valkey; OTEL Collector and Jaeger may likewise be started individually if needed, without starting PostgreSQL. A Gateway/Web local process is not currently a safe PGlite route: its unguarded dotenv loader may inherit a daemon PostgreSQL DSN. Do not use root `pnpm dev` or a Gateway start command until KBN-101-02 makes that state fail closed. ### Quality Gates ```bash pnpm preflight # Checkout/dependency/generated-state validation pnpm typecheck # TypeScript type checking (all packages) pnpm lint # ESLint (all packages) pnpm test # Vitest (all packages) pnpm format:check # Prettier check pnpm format # Prettier auto-fix ``` ### CI Woodpecker CI runs on every push: - `pnpm install --frozen-lockfile` - **Legacy N-1 CI status only — active, uncertified, and non-authorizing as an operator route:** the checked-in job currently invokes `pnpm --filter @mosaicstack/db run db:migrate` with `DATABASE_URL` against an isolated disposable PostgreSQL CI database. It performs direct DDL in that CI database, is not approved ordinary behavior or an operator route, and remains a known exception pending KBN-101-06 removal/replacement by the certified runner-backed CI path. - `pnpm test` (Turbo-orchestrated across all packages) npm packages are published to the Gitea package registry on main merges. ## Architecture ``` stack/ ├── apps/ │ ├── gateway/ NestJS API + WebSocket hub (Fastify, Socket.IO, OTEL) │ └── web/ Next.js dashboard (React 19, Tailwind) ├── packages/ │ ├── mosaic/ Unified CLI — TUI, gateway client, wizard, sub-package commands │ ├── types/ Shared TypeScript contracts (Socket.IO typed events) │ ├── db/ Drizzle ORM schema + migrations (pgvector) │ ├── auth/ BetterAuth configuration │ ├── brain/ Data layer (PG-backed) │ ├── queue/ Valkey task queue + MCP │ ├── coord/ Mission coordination │ ├── forge/ Multi-stage AI pipeline (intake → board → plan → code → review) │ ├── macp/ MACP protocol — credential resolution, gate runner, events │ ├── agent/ Agent session management │ ├── memory/ Agent memory layer │ ├── log/ Structured logging │ ├── prdy/ PRD creation and validation │ ├── quality-rails/ Quality templates (TypeScript, Next.js, monorepo) │ └── design-tokens/ Shared design tokens ├── plugins/ │ ├── discord/ Discord channel plugin (discord.js) │ ├── telegram/ Telegram channel plugin (Telegraf) │ ├── macp/ OpenClaw MACP runtime plugin │ └── mosaic-framework/ OpenClaw framework injection plugin ├── tools/ │ └── install.sh Unified installer (framework + npm CLI, --yes / --no-auto-launch) ├── scripts/agent/ Agent session lifecycle scripts ├── docker-compose.yml Dev infrastructure └── .woodpecker/ CI pipeline configs ``` ### Key Design Decisions - **Gateway is the single API surface** — all clients (TUI, web, Discord, Telegram) connect through it - **ESM everywhere** — `"type": "module"`, `.js` extensions in imports, NodeNext resolution - **Socket.IO typed events** — defined in `@mosaicstack/types`, enforced at compile time - **OTEL auto-instrumentation** — loads before NestJS bootstrap - **Explicit `@Inject()` decorators** — required since tsx/esbuild doesn't emit decorator metadata ### Framework (`~/.config/mosaic/`) The framework is the bash-based standards layer installed to every developer machine: ``` ~/.config/mosaic/ ├── AGENTS.md ← Central standards (loaded into every runtime) ├── SOUL.md ← Agent identity (name, style, guardrails) ├── USER.md ← User profile (name, timezone, preferences) ├── TOOLS.md ← Machine-level tool reference ├── bin/mosaic ← Unified launcher (claude, codex, opencode, pi, yolo) ├── guides/ ← E2E delivery, orchestrator protocol, PRD, etc. ├── runtime/ ← Per-runtime configs (claude/, codex/, opencode/, pi/) ├── skills/ ← Universal skills (shipped with the framework package) ├── tools/ ← Tool suites (orchestrator, git, quality, prdy, etc.) └── memory/ ← Persistent agent memory (preserved across upgrades) ``` ### Forge Pipeline Forge is a multi-stage AI pipeline for autonomous feature delivery: ``` Intake → Discovery → Board Review → Planning (3 stages) → Coding → Review → Remediation → Test → Deploy ``` Each stage has a dispatch mode (`exec` for research/review, `yolo` for coding), quality gates, and timeouts. The board review uses multiple AI personas (CEO, CTO, CFO, COO + specialists) to evaluate briefs before committing resources. ## Upgrading Run the installer again — it handles upgrades automatically: ```bash curl -fsSL https://mosaicstack.dev/install.sh | bash ``` Or use the direct URL: ```bash bash <(curl -fsSL https://git.mosaicstack.dev/mosaicstack/stack/raw/branch/main/tools/install.sh) ``` Or use the CLI: ```bash mosaic update # Check + install CLI updates mosaic update --check # Check only, don't install ``` The CLI also performs a background update check on every invocation (cached for 1 hour). ### Installer Flags ```bash bash tools/install.sh --check # Version check only bash tools/install.sh --framework # Framework only (skip npm CLI) bash tools/install.sh --cli # npm CLI only (skip framework) bash tools/install.sh --next # Prerelease lane: source build from next bash tools/install.sh --dev # Contributor lane: source build at --ref/main bash tools/install.sh --ref v1.0 # Install from a specific git ref (--ref wins over --next) bash tools/install.sh --yes # Non-interactive, accept all defaults bash tools/install.sh --no-auto-launch # Skip auto-launch of wizard ``` The installer rejects unrecognized flags or positional arguments before making changes and prints the supported-option usage. ## Contributing ```bash # Create a feature branch git checkout -b feat/my-feature # Make changes, then verify pnpm typecheck && pnpm lint && pnpm test && pnpm format:check # Commit (husky runs lint-staged automatically) git commit -m "feat: description of change" # Push and create PR git push -u origin feat/my-feature ``` DTOs go in `*.dto.ts` files at module boundaries. Scratchpads (`docs/scratchpads/`) are mandatory for non-trivial tasks. See `AGENTS.md` for the full standards reference. ## License Proprietary — all rights reserved.