> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/docs/deployment.md).

# Deployment

## Local Build

Use Bun 1.3.14 for release parity with CI. The repository `.bun-version` and GitHub Actions workflows pin the same version.

```bash
bun install
bun run build
```

The build command runs `bun run seed:data` before `vite build`, so a fallback `src/data/live-data.json` exists if no generated local data file is present.

### Build Output

`bun run build` produces two Vite build passes (client + SSR) into `dist/`:

```
dist/
  client/
    assets/          # Static assets (JS, CSS, images, SVGs)
  server/
    index.js         # Worker entry point
    wrangler.json    # Generated Wrangler config (resolved from wrangler.jsonc)
    assets/          # SSR assets (JS chunks, images, CSS)
    .vite/
      manifest.json  # Vite SSR manifest
```

The client build emits code-split JS chunks and a single CSS bundle. The server build emits a Worker entry (`index.js`) that imports SSR chunks and serves the client assets from `../client`.

### Known Build Caveats

* **3D vendor chunks**: `three.module` and `react-force-graph-3d` are still the largest client chunks, but the enforced 1.6 MB total client JS gzip budget currently passes. Keep them on the performance watchlist if the total budget tightens.
* **Vite preview**: `bun run preview` remains incompatible with the current Cloudflare Worker build output. Use Wrangler local dev for Worker SSR preview.

## Local Preview

**Note**: `bun run preview` (`vite preview`) currently fails because TanStack Start's preview plugin expects `dist/server/server.js` but the Cloudflare vite plugin produces `dist/server/index.js`. Use Wrangler local dev instead (see below). Tracked in `docs/deployment-blockers.md` as B010.

## Wrangler Local Dev

```bash
bun run worker:preview
```

Builds the app and runs the built Worker locally using the package-pinned Wrangler 4.92.0 miniflare runtime at `http://127.0.0.1:8788`, with the inspector on `127.0.0.1:9231`. This tests the complete SSR path including `src/server.ts` error handling.

Install certification expects the local Worker preview to serve `/health`, `/`, and `/favicon.svg` with HTTP 200.

## Cloudflare Workers Deployment

### Configuration

| File             | Purpose                                             |
| ---------------- | --------------------------------------------------- |
| `wrangler.jsonc` | Worker name, compatibility date, flags, entry point |
| `src/server.ts`  | Worker fetch handler (SSR with error normalization) |

### Deploy Command

```bash
bun run worker:deploy
```

This builds the app and uploads the `dist/server/` bundle to Cloudflare Workers using the package-pinned Wrangler 4.92.0 binary. The generated `dist/server/wrangler.json` resolves the entry to `index.js` and points static assets to `../client`.

### Deploy Prerequisites

Before first production deployment:

1. Cloudflare account with Workers enabled.
2. `wrangler login` locally, or `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` in CI.
3. Verify `wrangler.jsonc` name matches the desired Worker name.
4. No runtime environment variables are required -- the app uses fallback data.
5. Review `docs/deployment-blockers.md` for known issues.

## Cloudflare Pages Public Demo

The public demo uses Cloudflare Pages as a separate static deployment target. It does not replace the Worker deployment path and does not use Pages Functions, `_worker.js`, analytics, hosted collectors, local bridge endpoints, credentials, or server storage.

The production demo URL is `https://demo.aiagentsos.com`, backed by the `ai-os-public-demo` Cloudflare Pages project on branch `main`.

The current production direct upload was deployed on 2026-06-25 from source commit `079d26316793`; Cloudflare returned deployment URL `https://032a8040.ai-os-public-demo.pages.dev`.

The latest verified Phase 33 direct upload used project `ai-os-public-demo`, branch `main`, source commit `7681a517980f`, and deployment URL `https://ad0c5fdf.ai-os-public-demo.pages.dev` before the production custom domain was attached.

### Pages Fixture Boundary

Pages routes read committed browser-safe fixtures from `demo-website/public/` and generated static output from `demo-website/dist/`.

```bash
bun run demo:snapshot
bun run demo:build:pages
bun run demo:scan:pages
bun run demo:budget:pages
```

`bun run demo:snapshot` is an operator-local authoring command. It may read private local inputs, but it writes only allowlisted fixture output after the privacy scan passes. Cloudflare Pages builds should consume committed fixtures; they should not run source collection, schedulers, account auth, local bridge reads, or file uploads.

The current committed fixture metadata records capture time `2026-06-25T05:03:40.752Z`, 24 covered public-demo routes, scan status `pass`, 0 scan issues, 8 Trend Finder topics, 32 Trend Finder evidence rows, 3 Trend Finder sources, 3 watchlist rows, a sanitized Engine Replay trace, and 4 allowlisted Dream Review prescriptions.

### Pages Git Deployment

Use a dedicated Cloudflare Pages project with these Git settings:

```
Root directory: repo root
Build command: bun run demo:build:pages
Build output directory: demo-website/dist
Production branch: main or the selected demo branch
Environment variables: BUN_VERSION=1.3.14
```

The Pages project name is external operator configuration and is not committed to this repository.

For the production demo, attach `demo.aiagentsos.com` to the `ai-os-public-demo` Pages project and point DNS at `ai-os-public-demo.pages.dev`.

### Pages Direct Upload

Build and validate the static output before uploading:

```bash
bun run demo:build:pages
bun run demo:scan:pages
bun run demo:budget:pages
bun run demo:deploy:pages --project-name <pages-project-name> --branch main
```

The deploy helper prints a dry-run command by default. After reviewing the generated `wrangler pages deploy demo-website/dist ...` command, add `--execute` to perform the upload:

```bash
bun run demo:deploy:pages --project-name <pages-project-name> --branch main --execute
```

Replace `<pages-project-name>` with the operator-supplied Cloudflare Pages project name. Missing project name is the expected external constraint for direct-upload smoke in this repository.

### Pages Static Preview

Run the static Pages preview separately from Worker preview:

```bash
bun run demo:preview:pages
```

This serves `demo-website/dist` through `wrangler pages dev` and does not start the normal Worker SSR path. Use the route smoke tests against the preview URL to verify the public demo route matrix and no `/__*` local bridge requests.

If Wrangler Pages dev picks up repository Worker configuration instead of the static Pages root, serve an isolated temporary copy of `demo-website/dist` and run the same route smoke checks against that copy.

## Health Check

The Worker exposes `GET /health` which returns:

```json
{ "status": "healthy", "timestamp": "2026-05-13T00:00:00.000Z" }
```

This endpoint is handled before SSR in `src/server.ts` and can be used for uptime monitoring.

## CI/CD Pipeline

GitHub Actions workflows cover quality gates, PR integration checks, and main-branch deployment. All Bun jobs use dependency caching (`actions/cache` keyed on `bun.lock` hash) and pin Bun 1.3.14 through `oven-sh/setup-bun`.

| Job               | Command                     | Purpose                          |
| ----------------- | --------------------------- | -------------------------------- |
| Lint              | `bun run lint`              | ESLint static analysis           |
| Format Check      | `bun run format:check`      | Prettier formatting gate         |
| Type Check        | `bun run typecheck`         | TypeScript compiler check        |
| Script Type Check | `bun run typecheck:scripts` | Script-level TypeScript check    |
| Tests             | `bun run test`              | Vitest unit and route tests      |
| Coverage          | `bun run test:coverage`     | Vitest with coverage report      |
| Browser Tests     | `bun run test:e2e`          | Playwright end-to-end tests      |
| Build             | `bun run build`             | Production build verification    |
| Bundle Budget     | `bun run budget:check`      | Per-chunk and total JS size gate |
| Dependency Audit  | `bun audit`                 | Known vulnerability check        |
| Secret Scan       | gitleaks                    | Leaked secret detection          |

Additional workflows:

* `.github/workflows/integration.yml` runs production build and Playwright E2E checks on pull requests to `main`.
* `.github/workflows/deploy.yml` runs a quality gate, builds the Worker, deploys with Wrangler on pushes to `main` or manual dispatch when `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` are configured, skips deployment with a notice when either secret is missing, and performs an optional post-deploy `/health` smoke test when `PRODUCTION_URL` is configured.
* `.github/workflows/release.yml` creates a GitHub Release from pushed `v*` tags.

For secret scanning details and false-positive handling, see [CI Security](/ai-os-and-trend-finder-docs/docs/ci-security.md).

## Release Process

1. Run `bun run typecheck`.
2. Run `bun run typecheck:scripts`.
3. Run `bun run test`.
4. Run `bun run test:coverage`.
5. Run `bun run test:e2e`.
6. Run `bun run lint`.
7. Run `bun run format:check`.
8. Run `bun run build`.
9. Review documentation changes.
10. Run `bun run worker:deploy`.
11. Verify the app renders and expected routes load.

## Rollback

Use Wrangler's deployment history to revert the Worker to a previous version:

```bash
bunx wrangler deployments list --config dist/server/wrangler.json
bunx wrangler rollback <version-id> --config dist/server/wrangler.json --message "Rollback <reason>"
```

Then verify the deployed Worker:

```bash
curl -sf "$PRODUCTION_URL/health"
```

If the local build output is stale or missing, run `bun run build` first so `dist/server/wrangler.json` exists. The same rollback can be performed from the Cloudflare dashboard by selecting the `ai-os` Worker, opening Deployments, and rolling back to the last known-good version. After rollback, keep or open a `deploy-failure` issue with the failed run URL, commit SHA, rollback version ID, and follow-up owner.

## Deployment Gaps

See `docs/deployment-blockers.md` for the full list of known issues preventing production release.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/docs/deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
