Upstream Cial — pull mirror of https://github.com/techforces-ai/Cial.git, syncs every 10m
Find a file
Eliot M bcf2d2b9c3 feat(dev:tenant): replace native dev mode with Docker single-tenant container
dev:tenant now runs a single Linux container that mirrors the prod
tenant container shape (5 processes, port 8080) but with hot reload,
single root user, and credentials injected from the host's macOS
Keychain on startup. Source is bind-mounted; Linux-built node_modules
live in named volumes so they don't collide with macOS-built ones.

New files:
  cial-core/docker/Dockerfile.dev      single-user dev image (claude binary baked in)
  cial-core/docker/dev-entrypoint.sh   creds → ~/.claude → pnpm install → pre-build → exec supervisor
  cial-core/edge/src/supervisor.dev.ts container-side supervisor with watchers

Rewritten:
  scripts/dev-tenant.mjs               extracts host keychain + drives docker build/run

Volumes (survive Ctrl-C, wiped by `node scripts/dev-tenant.mjs --reset`):
  cial-dev-tenant-state       /var/lib/cial (sqlite db, claude home)
  cial-dev-tenant-modules     /workspace/node_modules + per-package shadows
  cial-dev-tenant-pnpm-store  /pnpm-store (install cache)

Trade-offs:
  - First boot is slow (pnpm install in-container). Subsequent boots fast.
  - protocol/sdk/edge dist files are written through the bind mount to the host.
  - macOS Keychain stays the source of truth for credentials; the container's
    OAuth refreshes don't propagate back.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 18:27:08 +00:00
cial-app Await tenant reconcile during app-api boot 2026-04-26 15:31:25 +00:00
cial-core feat(dev:tenant): replace native dev mode with Docker single-tenant container 2026-04-26 18:27:08 +00:00
cial-platform dev:tenant: auto-login as dev@local (instance_admin) 2026-04-26 15:55:47 +00:00
scripts feat(dev:tenant): replace native dev mode with Docker single-tenant container 2026-04-26 18:27:08 +00:00
.editorconfig phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
.env.example phase(L1): docker compose + Postgres + Better-Auth owner signup 2026-04-26 11:17:53 +00:00
.gitignore Add pnpm dev:tenant — single-tenant native dev mode with hot reload 2026-04-26 15:40:56 +00:00
.nvmrc phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
.prettierignore phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
.prettierrc.json phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
docker-compose.yml phase(L5): SSO handoff app -> tenant Core 2026-04-26 12:26:41 +00:00
eslint.config.js phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
LICENSE phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
package.json Add pnpm dev:tenant — single-tenant native dev mode with hot reload 2026-04-26 15:40:56 +00:00
PHASE-5.md phase(5a): sessions schema + REST CRUD 2026-04-26 17:04:37 +00:00
PLAN-LOCAL.md phase(L0): tenant container runs full Core + Platform stack 2026-04-26 10:46:16 +00:00
PLAN.md phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
pnpm-lock.yaml phase(5e): SessionsClient SDK + live UI streaming 2026-04-26 17:43:13 +00:00
pnpm-workspace.yaml phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
README.md phase(1): add pnpm smoke E2E harness 2026-04-26 09:48:48 +00:00
tsconfig.base.json phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00
turbo.json phase(1): scaffold all 10 workspace packages 2026-04-26 09:33:57 +00:00

Cial

Closed Core. Editable Platform. One container per tenant. Multi-tenant App layer.

See PLAN.md for the build plan and /app/data/cial-production-infrastructure.md for the architecture rationale.


Repository layout

cial/
├─ cial-core/         CLOSED — the harness shipped as a Docker image to every tenant
│   ├─ back/          Express + WS · AI sessions · auth · git engine · vault · DB proxy
│   ├─ front/         Next.js · the rescue UI served at /.cial/*
│   ├─ sdk/           @cial/sdk    — Platform code talks to Core through this
│   ├─ protocol/      @cial/protocol — shared TS types + Zod schemas
│   └─ docker/        Multi-stage Dockerfile · two Linux users (cial + agent)
│
├─ cial-platform/     OPEN — starter cloned into /platform/ of every tenant container
│   ├─ front/         Next.js · the editable user-owned frontend
│   └─ back/          Node · the editable user-owned backend
│
└─ cial-app/          CLOSED — multi-tenant ops layer
    ├─ api/           Next.js · owner signup, billing, admin
    ├─ orchestrator/  Fly Machines provisioning
    ├─ router/        Subdomain → tenant Machine ID
    ├─ scheduler/     Central cron / trigger fabric
    └─ docker/        Dockerfile for App itself

Stack

  • Node 22 · pnpm 9 · turbo 2
  • TypeScript 5.7 strict · NodeNext
  • Express 4 (Core Back, Platform Back, App orchestrator)
  • Next.js 16 with Turbopack (Core Front, Platform Front, App api)
  • better-sqlite3 (per-tenant DB) · Postgres + Drizzle (App DB)
  • Better-Auth · Zod · pino
  • ESLint 9 (flat) · Prettier

Common commands

pnpm install              # install all workspace deps
pnpm dev                  # run everything in parallel
pnpm build                # build everything
pnpm typecheck            # tsc --noEmit across packages
pnpm lint                 # eslint
pnpm format               # prettier --write
pnpm smoke                # boot all 5 services on isolated ports + probe

Per-package:

pnpm --filter @cial/back dev
pnpm --filter @cial/platform-front build

Architecture conventions (Express services)

  • Modular layout: src/modules/<feature>/{routes,service,repository,schemas,types}.ts
  • Routes never touch the database
  • Services never touch Express (req/res)
  • Repositories never touch services (data access only)
  • Validation at the edge with Zod
  • Dependency injection by hand at src/index.ts
  • Centralized error middleware (last app.use)
  • Structured logs via pino · no console.log
  • Graceful shutdown on SIGTERM/SIGINT

Smoke harness

pnpm smoke boots every service on isolated high ports (1800018100), polls each one until it responds, runs an HTTP probe matrix (health + a 501-stub envelope check on Core Back), then tears everything down. Exits 0 on success.

Service Port Probe
@cial/back 18080 /healthz → 200, /vault → 501 envelope
@cial/platform-back 18081 /health → 200
@cial/app-api 18100 /api/health → 200
@cial/front 18001 /.cial → 200
@cial/platform-front 18000 / → 200

Status

Scaffolding only. See PLAN.md for the phased implementation plan.