# OpenLife v1.16 — Changelog

**Branch:** `main`
**Predecessor:** v1.15.0 (tagged 2026-05-21)
**Released:** 2026-05-22

v1.16 is the **SaaS Scaffold + first template** milestone — Track B
phase 1 of the v1.15→v1.18 SaaS Forge arc. It ships:

1. A scaffold engine + template registry that can apply any
   manifest-driven template to a target directory, with token
   substitution and exclude rules.
2. A bundled production-grade Next.js + Supabase + Clerk + Stripe
   template (25 files) that produces a working SaaS skeleton you
   can `npm install && npm run dev` immediately after scaffolding.
3. `openlife scaffold {list, info, apply, custom}` CLI surface.

Per-subsystem detail follows.

## What landed by subsystem

### Phase B1 — Engine + Registry + CLI

| Component | Surface |
|---|---|
| `src/orchestrator/scaffold/TemplateRegistry.ts` | `list() / get(id)`. Discovers bundled templates in `templates/` + user templates in `~/.openlife/templates/`. User wins on id collision. |
| `src/orchestrator/scaffold/ScaffoldEngine.ts` | `apply(templateId, targetDir, opts)`. Copies files with `{{token}}` substitution, renames `__token__.ext` filenames, honors `manifest.exclude[]`, refuses non-empty target unless `force: true`, supports `dryRun`. |
| `src/cli/ScaffoldCommand.ts` | `scaffold {list, info <id>, apply <name> --template=<id>, custom <name> --from=<path>}`. |
| Substitution scope | Content of all text files + filenames (`__var__` pattern) + `post_install_steps` array in manifest. Binary files (png/jpg/woff/etc.) copied verbatim. |
| Unresolved token reporting | Post-apply scan emits warnings listing files with surviving `{{token}}` patterns. |

### Phase B2 — Bundled template: nextjs-supabase-clerk-stripe

25 files producing a working Next.js 16 SaaS scaffold:

| Layer | What |
|---|---|
| **Framework** | Next.js 16 App Router + Server Components, React 19, TypeScript strict |
| **Auth** | Clerk middleware (`middleware.ts`), sign-in / sign-up routes at `(auth)/`, `UserButton`, `requireUserId()` / `getUserId()` server helpers |
| **Database** | Supabase Postgres with RLS. `lib/db.ts` exposes `getPublicSupabase()` + `getServiceSupabase()`. Migration `0001_initial.sql` creates `users` + `subscriptions` tables with self-select RLS policies |
| **Billing** | Stripe SDK in `lib/stripe.ts` with `listPlans()` + `getOrCreateStripeCustomerId()`. Subscription webhook handler at `app/api/webhooks/stripe/route.ts` mirrors lifecycle into `subscriptions` table |
| **Clerk → DB sync** | Webhook at `app/api/webhooks/clerk/route.ts` upserts Clerk users into `users` table on `user.created/updated/deleted` |
| **Styling** | Tailwind v3.4 + globals.css. Pre-wired for shadcn/ui drop-in |
| **Deploy** | `vercel.json` declares framework + env mappings; `.env.example` documents the 8 required keys |

### CLI examples

```bash
openlife scaffold list
# 1 template(s)
#   nextjs-supabase-clerk-stripe   nextjs@16 + supabase + clerk + stripe
#                                  Production-grade SaaS scaffold...

openlife scaffold info nextjs-supabase-clerk-stripe   # full manifest

openlife scaffold my-saas --template=nextjs-supabase-clerk-stripe
# ✓ Scaffolded 24 file(s) into /cwd/my-saas
#   Template: Next.js + Supabase + Clerk + Stripe (SaaS-ready)
#   Substituted: 5 file(s)
# Next steps:
#   cd my-saas
#   Copy .env.example to .env.local and fill in the keys
#   npm install
#   supabase db push
#   npm run dev
```

### Phase B4 — Tests + docs + ship

7 new test scenarios in `test_scaffold_engine.ts`:

1. TemplateRegistry discovers user templates
2. apply substitutes content + renames token-named files
3. manifest.exclude[] honored (files AND directories)
4. Empty-target enforcement (force:true overrides)
5. dry-run reports counts without writing
6. Post-install steps get substitution
7. Bundled nextjs template smoke (24 files copied, key files verified)

All pass. No regression in 23 v1.15 + v1.14 adjacent tests verified.

## Security model

- **Token substitution scope** — only `{{var}}` patterns are
  rewritten. No code execution, no eval, no shell expansion.
- **Target directory** — refuses non-empty unless `force: true`.
  Prevents accidental overwrites.
- **User templates** — discovered only from `~/.openlife/templates/`.
  No automatic network fetching.
- **`scaffold custom --from=<path>`** — currently local paths only.
  Git URL support deferred to v1.16.1 (will route through
  `SecurityDownloadGuard` scan before applying).
- **Bundled template secrets** — `.env.example` documents what's
  needed but ships no real values.

## Out of scope (deferred)

- **SvelteKit + Postgres + Lucia template** — moved to v1.16.1.
  Same engine, just needs the template files written out.
- **Git URL templates** — `scaffold custom --from=<git-url>`
  requires SecurityDownloadGuard.downloadAndScan integration.
  v1.16.1.
- **Template marketplace** — community submission + rating —
  deferred to v1.19+.
- **Mobile (Expo/RN) templates** — v1.19+.
- **More SaaS variants** (CRM, marketplace, task-manager templates) —
  community via `--from=<path>`.

## Tarball impact

```
v1.15.0 → v1.16.0
package size:    1.9MB → 1.95MB  (+50KB)
unpacked size:   7.3MB → 7.5MB   (+200KB)
total files:     1166  → 1196    (+30)
```

The 25-file Next.js template adds ~50KB tarball / 200KB unpacked.

## Upgrade

```bash
openlife update --global
# or:
npm install -g @openlife/cli@latest

# Verify
openlife --version              # 1.16.0
openlife scaffold --help        # shows list/info/apply/custom
openlife scaffold list          # 1 template (nextjs-supabase-clerk-stripe)
```

## File summary

**New (28):**
- `src/orchestrator/scaffold/TemplateRegistry.ts`
- `src/orchestrator/scaffold/ScaffoldEngine.ts`
- `src/cli/ScaffoldCommand.ts`
- `src/test_scaffold_engine.ts`
- `templates/nextjs-supabase-clerk-stripe/` (25 files)
- `docs/v1.16-changelog.md`, `docs/scaffold.md`

**Modified (3):**
- `src/index.ts` — register ScaffoldCommand
- `package.json` — `files[]`, new test scripts, version bump
- `CHANGELOG.md` — release entry

## Roadmap continuation

- **v1.16.1** — SvelteKit-Postgres-Lucia template + `scaffold custom --from=<git-url>` support
- **v1.17.0** — Autonomous Story Loop (Track B phase 2)
- **v1.18.0** — Ship + Deploy + SaaS Skills (Track B phase 3)
