Skip to content

chore: remove local mode (sql.js, MANIFEST_MODE, manifest plugin)#1539

Merged
brunobuddy merged 2 commits intomainfrom
chore/remove-local-mode
Apr 13, 2026
Merged

chore: remove local mode (sql.js, MANIFEST_MODE, manifest plugin)#1539
brunobuddy merged 2 commits intomainfrom
chore/remove-local-mode

Conversation

@brunobuddy
Copy link
Copy Markdown
Member

@brunobuddy brunobuddy commented Apr 13, 2026

Summary

Remove Manifest's local mode and the manifest OpenClaw plugin. Manifest now runs exclusively on PostgreSQL with Better Auth, shipped either via the Docker image (manifestdotbuild/manifest) with a bundled Postgres container or the hosted cloud version at app.manifest.build. The self-contained manifest npm package (embedded Nest server, SQLite via sql.js, loopback-trust auth) is deprecated and removed from the repository.

Bundles three related changes into one atomic PR:

  1. Local mode removal — ~80 files. Deletes LocalAuthGuard, LocalBootstrapService, local-mode.constants, limit-check-local.service, version-check.service, sql-dialect.spec, the manifest plugin package, and all isLocalMode() branches across backend + frontend. Drops sql.js from backend deps and the backend-sqljs CI job. Simplifies sql-dialect.ts to Postgres-only (keeps function signatures to avoid touching 17 entities and 6 services).
  2. Docker production-mode hardening — flips docker-compose.yml to NODE_ENV=production and introduces a dedicated AUTO_MIGRATE=true env var instead of the previous NODE_ENV=development workaround. Activates trust proxy for reverse-proxied deployments, upstream error sanitization, and Better Auth verification enforcement. Compose file now fails fast if BETTER_AUTH_SECRET is unset, adds init: true for proper PID 1, restart: unless-stopped, and a compose-level healthcheck.
  3. Unified EMAIL_* env vars — covers both Better Auth transactional emails (signup verification, password reset) and threshold alert notifications via the existing Pipeline B → Pipeline A fallback. Supports Resend (recommended for self-hosting — no domain setup), Mailgun, and SendGrid. Legacy MAILGUN_API_KEY/MAILGUN_DOMAIN still work for backward compat.

Why one PR

The three concerns share file boundaries (auth, database, compose, DOCKER_README, env.example). Splitting them would require dead-code shims in every intermediate state. Review surface is ~225 files but strictly subtractive (+1080 / −8832).

Migration guide for existing self-hosted local-mode users

  1. Download docker/docker-compose.yml and docker/.env.example from this repo.
  2. cp .env.example .env and set BETTER_AUTH_SECRET with openssl rand -hex 32.
  3. docker compose up -d. First boot runs migrations (via AUTO_MIGRATE=true) and seeds the admin user (via SEED_DATA=true).
  4. Log in at http://localhost:3001 with admin@manifest.build / manifest and immediately change the password.
  5. For transactional emails: set EMAIL_PROVIDER=resend + EMAIL_API_KEY + EMAIL_FROM in .env (Resend is easiest — no domain setup).
  6. For OAuth logins: set {GOOGLE,GITHUB,DISCORD}_CLIENT_ID + _CLIENT_SECRET in .env.
  7. Existing local-mode data at ~/.openclaw/manifest/manifest.db (SQLite) has no automated migration path. Export telemetry manually via the dashboard before upgrading, or stay on the last manifest@X release.

Breaking changes

  • MANIFEST_MODE, MANIFEST_DB_PATH, MANIFEST_UPDATE_CHECK_OPTOUT, MANIFEST_TRUST_LAN env vars are removed (no-op if set)
  • NODE_ENV=development in production Docker deployments is no longer the trigger for auto-migrations — use AUTO_MIGRATE=true
  • BETTER_AUTH_SECRET is now required in docker-compose.yml (no placeholder); compose startup fails with a helpful error if unset
  • The manifest npm package is deprecated and will receive no further releases
  • /api/v1/health no longer returns mode, devMode, or version fields

Test plan

  • cd packages/backend && npx tsc --noEmit — passes
  • cd packages/frontend && npx tsc --noEmit — passes
  • cd packages/backend && npx jest — 3489/3489 pass across 179 suites
  • cd packages/backend && npm run test:e2e (against fresh Postgres) — 99/99 pass across 14 suites
  • cd packages/frontend && npx vitest run — 2147/2147 pass across 108 suites
  • npm run build — shared, frontend, backend, manifest-model-router all build clean
  • Grep sanity: zero hits for MANIFEST_MODE, sql.js, LocalAuthGuard, LocalBootstrap, MANIFEST_TRUST_LAN, local-mode.constants in packages/{backend,frontend,shared}/src, docker/, CLAUDE.md, CONTRIBUTING.md
  • Runtime smoke test — docker compose up -d against the new compose file; verify seeded admin logs in, health endpoint returns {status: healthy, uptime_seconds: N} only, reverse-proxy headers are trusted, no "Dev" badge in header
  • Release workflow sanity — changeset entry created for manifest-model-router patch bump (only publishable package left)

Summary by cubic

Removed local mode and the manifest OpenClaw plugin. Manifest now runs only on PostgreSQL with Better Auth; Docker and email config are updated for simpler, safer self‑hosting.

  • Refactors

    • Postgres-only backend; removed sql.js, MANIFEST_MODE, local guards/services, and LAN/loopback bypass. SQL helpers simplified; /api/v1/health now returns only status and uptime.
    • Unified email env for both Better Auth and threshold alerts: EMAIL_PROVIDER, EMAIL_API_KEY, EMAIL_DOMAIN, EMAIL_FROM (supports Resend, Mailgun, SendGrid). Legacy MAILGUN_* still works.
    • Docker: added AUTO_MIGRATE=true, trust proxy enabled in production, docker/.env.example, compose healthcheck, init: true, restart: unless-stopped, OAuth env passthrough. Set NODE_ENV=production for deployments; compose remains dev‑friendly by default.
    • CI/docs: removed the sql.js job; removed the manifest npm package; only manifest-model-router is published.
  • Migration

    • Self-hosted: use docker/docker-compose.yml with manifestdotbuild/manifest. Set BETTER_AUTH_SECRET (openssl rand -hex 32), optional EMAIL_*/OAuth env, and AUTO_MIGRATE=true for first boot. A default admin (admin@manifest.build / manifest) is seeded—change the password.
    • Replace migration-on-boot via NODE_ENV=development with AUTO_MIGRATE=true. Set NODE_ENV=production in deployments.
    • Remove old envs: MANIFEST_MODE, MANIFEST_DB_PATH, MANIFEST_TRUST_LAN, MANIFEST_UPDATE_CHECK_OPTOUT.
    • No automated migration from local SQLite at ~/.openclaw/manifest/manifest.db.

Written for commit 9d1a78a. Summary will update on new commits.

Remove Manifest's local mode and the `manifest` OpenClaw plugin.
Manifest now runs exclusively on PostgreSQL with Better Auth, shipped
either via the Docker image (manifestdotbuild/manifest) or the hosted
cloud version. The self-contained `manifest` npm package — embedded
Nest server, SQLite via sql.js, loopback-trust auth — is deprecated
and removed from the repository.

Docker hardening bundled in:
- NODE_ENV=production by default (activates trust proxy, sanitizes
  upstream errors, hides Dev badge, enforces verification when Mailgun
  is configured)
- New AUTO_MIGRATE=true env var replaces NODE_ENV=development as the
  migration-on-boot trigger
- docker-compose.yml: fail-fast if BETTER_AUTH_SECRET unset, init:true
  for proper PID 1, restart:unless-stopped, compose-level healthcheck,
  overridable POSTGRES_PASSWORD
- docker/.env.example template with Resend/Mailgun/SendGrid and OAuth
- Dropped MANIFEST_TRUST_LAN (dead without LocalAuthGuard)

Unified email provider scheme:
- New EMAIL_PROVIDER / EMAIL_API_KEY / EMAIL_DOMAIN / EMAIL_FROM env
  vars cover BOTH Better Auth transactional emails AND threshold alert
  notifications via the existing Pipeline B → Pipeline A fallback
- Supports resend (recommended for self-hosting, no domain needed),
  mailgun, sendgrid
- Legacy MAILGUN_API_KEY/DOMAIN still work for backward compat

Backend changes:
- Delete local-mode.constants, local-auth.guard, local-bootstrap.service,
  limit-check-local.service, version-check.service, sql-dialect.spec,
  local-ip.spec
- Simplify sql-dialect.ts to Postgres-only (keeps function signatures to
  avoid touching 17 entities and 6 services)
- auth.instance.ts: no more null branch, BETTER_AUTH_SECRET always
  required outside test mode
- app.module.ts: SessionGuard is the only APP_GUARD (no LocalAuthGuard
  swap)
- database.module.ts: Postgres-only TypeORM config; seeder runs on
  SEED_DATA=true regardless of NODE_ENV
- agent-key-auth.guard.ts: drop local-mode IP bypass, keep dev-mode
  loopback shortcut
- health.controller.ts: drop mode/devMode/version fields
- Drop sql.js from backend dependencies
- Rewrite E2E test helpers to use Postgres instead of sql.js

Frontend changes:
- Delete services/local-mode.ts and VersionIndicator component
- Remove isLocalMode/isDevMode branches from Login, Settings, Account,
  Limits, MessageLog, Header, AuthGuard, AgentGuard, ProviderSelect*,
  ProviderApiKeyTab, ProviderDetailView, EmailProviderModal
- Update ~25 test files to match

CI/docs:
- Delete backend-sqljs and manifest-plugin CI jobs
- Update CLAUDE.md, CONTRIBUTING.md, DOCKER_README.md, .env.example
  files to reflect Postgres-only, new env vars, and single publishable
  package (manifest-model-router)
- Delete .claude/skills/* that automated the local-mode plugin
  (setup-manifest-plugin, uninstall-manifest-plugin, manifest-status,
  ensure-manifest-docs-consistency)
- Delete skills/manifest/SKILL.md (referenced the deleted plugin)

Breaking:
- MANIFEST_MODE, MANIFEST_DB_PATH, MANIFEST_UPDATE_CHECK_OPTOUT,
  MANIFEST_TRUST_LAN env vars are removed (no-op if set)
- NODE_ENV=development in production Docker is no longer supported;
  use AUTO_MIGRATE=true instead
- BETTER_AUTH_SECRET now required in docker-compose (no placeholder)
- manifest npm package is deprecated
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 225 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritises the most important files to review.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="CLAUDE.md">

<violation number="1" location="CLAUDE.md:541">
P2: Changeset CI documentation is incorrect: it omits the required `manifest` changeset for backend/frontend PRs.</violation>
</file>

<file name="CONTRIBUTING.md">

<violation number="1" location="CONTRIBUTING.md:197">
P2: The updated changeset guidance is inconsistent with CI: backend/frontend changes are documented as not requiring changesets, but CI still requires a `manifest` changeset for those paths.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread CLAUDE.md Outdated
Comment thread CONTRIBUTING.md Outdated
Resolves conflicts after main merged parallel cleanup PRs (#1528, #1533,
#1534, #1536, #1537, #1538) that removed both openclaw-plugins packages.
Takes main's direction on:
- openclaw-plugins/manifest-model-router removal (main deleted both)
- docker-compose.yml local-testing framing (main's choice)
- Dockerfile healthcheck start-period=45s (main's fix)

Keeps this branch's unique contributions:
- Backend: delete all local-mode source files (LocalAuthGuard,
  local-mode.constants, local-bootstrap.service, limit-check-local,
  version-check.service), simplify sql-dialect.ts to Postgres-only,
  drop sql.js dep, remove backend-sqljs CI job
- Frontend: delete services/local-mode.ts, VersionIndicator component,
  remove isLocalMode/isDevMode branches across ~14 components
- AUTO_MIGRATE env var in database.module.ts + seeder
- Unified EMAIL_* env var scheme in send-email.ts + app.config.ts +
  notification-email.service.ts (covers both Better Auth transactional
  and threshold alerts via existing fallback)
- Docker compose: add AUTO_MIGRATE, EMAIL_*, OAuth env var passthroughs;
  drop MANIFEST_TRUST_LAN (dead after LocalAuthGuard removal)
- backend/.env.example: new EMAIL_* block, deprecate legacy MAILGUN_*
- Rewrite E2E test helpers to use Postgres (was sql.js)
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.90%. Comparing base (473e1f8) to head (9d1a78a).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1539      +/-   ##
==========================================
- Coverage   98.43%   97.90%   -0.54%     
==========================================
  Files         118      116       -2     
  Lines        8653     8458     -195     
  Branches     3278     3186      -92     
==========================================
- Hits         8518     8281     -237     
- Misses        134      175      +41     
- Partials        1        2       +1     
Flag Coverage Δ
frontend 97.90% <100.00%> (-0.54%) ⬇️
shared 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 13, 2026

Bundle Report

Changes will decrease total bundle size by 19.32kB (-2.97%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
manifest-frontend-esm 631.87kB -19.32kB (-2.97%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: manifest-frontend-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/Routing-*.js 650 bytes 109.97kB 0.59%
assets/index-*.js -2.9kB 33.76kB -7.91%
assets/Limits-*.js -14.74kB 16.86kB -46.65%
assets/Settings-*.js -72 bytes 12.21kB -0.59%
assets/MessageLog-*.js -19 bytes 8.98kB -0.21%
assets/Account-*.js -843 bytes 5.52kB -13.24%
assets/Login-*.js -406 bytes 2.92kB -12.2%
assets/api-*.js -46 bytes 2.13kB -2.12%
assets/provider-*.js (Deleted) -949 bytes 0 bytes -100.0% 🗑️

@brunobuddy brunobuddy merged commit d7df080 into main Apr 13, 2026
15 of 17 checks passed
@brunobuddy brunobuddy deleted the chore/remove-local-mode branch April 13, 2026 03:39
brunobuddy added a commit that referenced this pull request Apr 13, 2026
Replaces the obsolete work in PR 1542 — main has since landed #1539
(remove-local-mode) and #1541 (synthetic package) which already added
docker/.env.example, the email + OAuth compose vars, and the broader
.gitignore negation. This commit layers the remaining still-needed
pieces on top of the new main.

- README.md: drop the unmaintained npm version + downloads badges, add
  a Docker image-size badge, inline the two-command Docker quickstart
  under "Self-hosted (Docker)" so it's visible on the first screenful,
  and note that the npm package is deprecated.
- docker/DOCKER_README.md: fix the OpenClaw-only framing (now lists
  OpenClaw, Hermes, and OpenAI-compatible agents), add a table of
  contents, PowerShell + CMD variants for the docker run example,
  an Upgrading section (docker compose pull && up -d), a Backup &
  persistence section covering the pgdata volume + pg_dump, and a
  new "Option 3: one-command install script" section with a
  review-before-running note.
- docker/docker-compose.yml: switch BETTER_AUTH_SECRET, BETTER_AUTH_URL,
  and SEED_DATA to ${VAR:-default} interpolation so that overrides from
  .env actually take effect — currently these are hardcoded literals
  that silently ignore .env values, which breaks the self-host flow
  advertised in .env.example. POSTGRES_PASSWORD and DATABASE_URL stay
  hardcoded (the internal Postgres has no published port, and
  interpolating the password into the URL risks URI-encoding bugs).
- docker/install.sh: hardened one-command installer. set -euo pipefail,
  confirmation prompt (or --yes), --dry-run, --dir, refuses to clobber
  non-empty dirs, generates a secret via openssl (falls back to
  /dev/urandom), waits on the healthcheck, prints login info.
- .github/workflows/docker.yml: force flavor: latest=true on
  metadata-action so the compose file's :latest reference is reliably
  updated on every workflow_dispatch publish; add a
  peter-evans/dockerhub-description@v4 step to sync
  docker/DOCKER_README.md and a 65-character short description to
  Docker Hub on publish; add .env.example + install.sh to the PR
  path filter so future edits trigger the validate job.
brunobuddy added a commit that referenced this pull request Apr 13, 2026
The release workflow was failing again with:

  🦋 error Found changeset remove-local-mode for package
    manifest-model-router which is not in the workspace

.changeset/remove-local-mode.md was added in #1539 but targets
manifest-model-router, which was deleted in #1528. Changesets
fast-fails on any dangling package reference.

The changeset content itself is genuinely useful — it documents the
local-mode removal, the Docker hardening, the new AUTO_MIGRATE env
var, and the unified EMAIL_* scheme. Rather than deleting it (which
is what #1534 did for a similar situation), retarget it to 'manifest'
so the content lands in packages/manifest/CHANGELOG.md on the next
release.

Also drop the now-stale final sentence that described
manifest-model-router as 'the recommended way to route OpenClaw
requests through Manifest' — that package no longer exists. Replaced
with a correct note pointing users at configuring Manifest as a
generic OpenAI-compatible provider (which is what the dashboard
setup modal shows them).
andychu666 added a commit to andychu666/manifest that referenced this pull request Apr 15, 2026
Upstream removed both plugin packages (mnfst#1527, mnfst#1528) and local mode
(mnfst#1539) in favor of Docker-only self-hosting. This fork preserves local
OpenClaw support via manifest-local, which fixes the embedded NestJS
architecture that motivated upstream's deprecation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant