Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c42591f
chore(release): open v3.8.9 development cycle
diegosouzapw Jun 3, 2026
9141e98
fix(providers): fix claude-web 403, move no-auth providers out of web…
oyi77 Jun 3, 2026
43b1392
fix(autoCombo): rotate across all connections, never waste provider c…
oyi77 Jun 3, 2026
6999566
deps: bump electron-updater from 6.8.6 to 6.8.8 in /electron (#3084)
dependabot[bot] Jun 3, 2026
8a5feac
deps: bump electron from 42.2.0 to 42.3.2 in /electron (#3083)
dependabot[bot] Jun 3, 2026
e7f064d
deps(electron): bump electron-builder to 26.14.0
diegosouzapw Jun 3, 2026
9db306e
feat(observability): add Obsidian context source with 24 MCP tools (#…
branben Jun 3, 2026
c4fa7ad
deps: bump the development group with 5 updates (#3086)
dependabot[bot] Jun 3, 2026
e6db182
deps: bump the production group with 21 updates (#3085)
dependabot[bot] Jun 3, 2026
3c8646a
fix(mcp): remove duplicate notionTools registration introduced by merge
diegosouzapw Jun 3, 2026
28116c7
fix(cache): preserve client cache_control for Xiaomi MiMo (#3088) (#3…
diegosouzapw Jun 3, 2026
a296c34
docs(changelog): add v3.8.9 entries for merged PRs
diegosouzapw Jun 3, 2026
51d2ca8
feat(db): add apiKeyContextSources module + migration 092
diegosouzapw Jun 3, 2026
42821ee
test: update web-session-credentials to reflect veoaifree-web NOAUTH …
diegosouzapw Jun 3, 2026
948f232
fix: sync SiliconFlow models from configured endpoint (#3094)
xz-dev Jun 3, 2026
470df2d
docs(changelog): add SiliconFlow fix entry (#3094)
diegosouzapw Jun 3, 2026
7042d56
fix(sse): scope ollama-cloud per-model 403 to model lockout, not conn…
diegosouzapw Jun 3, 2026
365c29a
fix(providers): forward Grok sso-rw cookie to fix anti-bot 403 (#3063…
diegosouzapw Jun 3, 2026
8a25d9e
fix(dashboard): make 'Import from /models' work for no-auth providers…
diegosouzapw Jun 3, 2026
5f3b1e8
fix(db): dedup duplicate API keys per provider on connection create (…
diegosouzapw Jun 3, 2026
5f7f74d
fix(dashboard): qualify vendor-namespaced Playground models with prov…
diegosouzapw Jun 3, 2026
f0f776c
fix(i18n): fill missing zh-CN and ru UI translations (#3026, #3067) (…
diegosouzapw Jun 3, 2026
b57afb5
fix(sse): handle non-SSE JSON upstream body on streaming path + SSE-w…
diegosouzapw Jun 3, 2026
d5f2586
fix(sse): emit reasoning/content as separate SSE deltas to avoid dupl…
diegosouzapw Jun 3, 2026
aa64776
docs(claude): add bug fix validation protocol + both test runners rule
diegosouzapw Jun 3, 2026
277f530
Remove obsolete files: deleted unused test-debug.ts, .semgrep rules, …
diegosouzapw Jun 3, 2026
05c6335
build(layer0): unify standalone assembly into assembleStandalone.mjs
diegosouzapw Jun 3, 2026
27c0817
build(layer0): prepublish consumes single build via assembleStandalon…
diegosouzapw Jun 3, 2026
03b8aa1
build(layer0): electron prepare uses assembleStandalone (keep ABI nat…
diegosouzapw Jun 3, 2026
5b48473
build(layer1): isolate Next output to .build/next; gitignore .build/ …
diegosouzapw Jun 3, 2026
b7fdcdd
build(layer1): rename standalone output app/ -> dist/; delete both Ap…
diegosouzapw Jun 3, 2026
5efeeb1
build(layer1): add build:release clean rebuild + HEAD sentinel guard
diegosouzapw Jun 3, 2026
e390a8d
build(layer2+3): propagate .build/+dist/ to Docker/Electron/CI; codif…
diegosouzapw Jun 3, 2026
0231fbb
build(verify): close ralph-loop-1 gaps β€” align tests + fix stale .nex…
diegosouzapw Jun 3, 2026
c9620eb
chore(build): re-apply build-reorg follow-ups (compat fallback + depl…
diegosouzapw Jun 3, 2026
ed17022
fix(responses): resolve bare ChatGPT model ids to codex on HTTP fallb…
diegosouzapw Jun 3, 2026
261a910
fix(codex): preserve native Responses passthrough tools and history (…
yinaoxiong Jun 3, 2026
0331e81
fix: add AbortController timeout to fetchImageEndpoint (#3105)
mgarmash Jun 3, 2026
0594af6
feat(cursor): vision (image_url) input + tool-commit/output-constrain…
payne0420 Jun 3, 2026
5089669
fix+feat(sse): per-model 403 lockout (#3027) + deepseek-web memory (#…
diegosouzapw Jun 3, 2026
27b822e
fix(tools): keep opaque object schemas open (#3097)
nmime Jun 3, 2026
656e73e
Remove duplicate lowercase db-apikeys-crud.test.ts from tracking (#3125)
juandisay Jun 3, 2026
84b5cae
fix(sse): bound Antigravity 429 retry loop and lock quota-exhausted a…
ahmet-cetinkaya Jun 3, 2026
51345bf
fix(cli): handle Windows exe healthchecks with spaces (#3111)
EmpRider Jun 3, 2026
a718558
perf(logs): fix browser freeze and network saturation on /dashboard/l…
0xtbug Jun 3, 2026
80c9ca7
fix(cli): don't write STORAGE_ENCRYPTION_KEY to .env on informational…
diegosouzapw Jun 3, 2026
8dc93ad
fix(i18n): Turkish locale-aware search and sorting (#3115)
osrt91 Jun 3, 2026
652faee
docs(readme): feature Discord community invite prominently at the top
diegosouzapw Jun 3, 2026
cad93f3
fix(lint): escape quotes in ObsidianSourceCard JSX (react/no-unescape…
diegosouzapw Jun 3, 2026
49bfe98
docs(changelog): finalize v3.8.9 β€” add session PR entries + contribut…
diegosouzapw Jun 3, 2026
8dd9749
fix(build): correct modelResolution import path in responses route (#…
diegosouzapw Jun 3, 2026
838c2ca
test(sse-auth): unique default apiKey per seeded connection (align wi…
diegosouzapw Jun 3, 2026
20331af
fix(ci): allowlist build-time OMNIROUTE_BUILD_SHA in env-doc-sync
diegosouzapw Jun 3, 2026
f1c4235
fix(ci): raise t11 any-budget for cursor.ts (false-positive) + server…
diegosouzapw Jun 3, 2026
e1007ac
fix(cli): bare omniroute (default serve) must provision STORAGE_ENCRY…
diegosouzapw Jun 4, 2026
27229aa
test(cache): align stale cache-HIT tests with #2952 SSE-wrap behavior
diegosouzapw Jun 4, 2026
dff836a
fix(ci): resolve remaining CI failures (typecheck + build-reorg test …
diegosouzapw Jun 4, 2026
dd85309
fix(ci): hasStandaloneAppBundle dist/->app/ fallback + gate obsidian-…
diegosouzapw Jun 4, 2026
b6bda19
fix(quality): explicit promise-existence checks + protocol-aware WebD…
diegosouzapw Jun 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 73 additions & 7 deletions .agents/skills/deploy-vps-akamai-cc/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,102 @@ description: Deploy the latest OmniRoute code to the Akamai VPS (69.164.221.35)

# Deploy to Akamai VPS Workflow

Deploy OmniRoute to the Akamai VPS using `npm pack + scp` + PM2.
Deploy OmniRoute to the Akamai VPS using a clean `build:release` + `rsync` + PM2 restart.

**Akamai VPS:** `69.164.221.35`
**Process manager:** PM2 (`omniroute`)
**Port:** `20128`
**Remote install dir:** `/usr/lib/node_modules/omniroute/app/` (VPS image dir β€” unchanged)

> [!IMPORTANT]
> **Build must run where `node_modules` is REAL.** A git worktree with symlinked
> `node_modules` breaks the Next.js standalone assembly. Always build from the main
> checkout (or an `npm ci`'d worktree), never from `OmniRoute-*` worktrees unless
> you first ran `npm ci` inside them.

## Steps

### 1. Build + pack locally
### 1. Clean build + sentinel

Run from a checkout with a **real** `node_modules`:

// turbo

```bash
cd /home/diegosouzapw/dev/proxys/OmniRoute && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
cd /home/diegosouzapw/dev/proxys/OmniRoute && npm run build:release
```

`build:release` does:
1. Deletes `.build/` and `dist/` (clean rebuild β€” no stale cache)
2. Runs `next build` β†’ `.build/next/` (intermediates)
3. Assembles the shippable bundle into `dist/` via `assembleStandalone`
4. Writes `dist/BUILD_SHA` = `git rev-parse --short HEAD` (deploy sentinel)

Verify the sentinel before shipping:

```bash
cat /home/diegosouzapw/dev/proxys/OmniRoute/dist/BUILD_SHA && git -C /home/diegosouzapw/dev/proxys/OmniRoute rev-parse --short HEAD
```

### 2. Copy to Akamai VPS and install
Both lines must match. If they differ, the build is stale β€” re-run `build:release`.

### 2. Back up the running bundle on the VPS

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
ssh root@69.164.221.35 "cp -a /usr/lib/node_modules/omniroute/app /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION}"
```

### 3. Stop the process, then rsync `dist/` β†’ remote `app/`

The VPS image directory is still named `app/`; we ship the **contents** of our local `dist/`. **Stop the running process FIRST** so `rsync --delete` never removes chunk files out from under the live server β€” that race produces the transient `[Shutdown] Cannot find module ./chunks/NNNNN.js` seen mid-deploy:

// turbo-all

```bash
scp omniroute-*.tgz root@69.164.221.35:/tmp/
ssh root@69.164.221.35 "pm2 stop omniroute"
rsync -az --delete /home/diegosouzapw/dev/proxys/OmniRoute/dist/ root@69.164.221.35:/usr/lib/node_modules/omniroute/app/
```

### 4. Start + health check

`pm2 restart` on a stopped app starts it again with a clean module graph:

```bash
ssh root@69.164.221.35 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts --legacy-peer-deps && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && (pm2 delete omniroute 2>/dev/null || true) && pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo 'βœ… Akamai done'"
ssh root@69.164.221.35 "pm2 restart omniroute --update-env && pm2 save"
```

### 3. Verify the deployment
```bash
sleep 5 && curl -sf http://69.164.221.35:20128/api/monitoring/health | jq '{status:.status, version:.version}'
```

Expected: HTTP 200, `"status": "ok"` (or equivalent health payload).

### 5. Verify the deployment

```bash
curl -s -o /dev/null -w 'AKAMAI HTTP %{http_code}\n' http://69.164.221.35:20128/
```

## Rollback

If the health check fails, restore the backup:

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
ssh root@69.164.221.35 "rm -rf /usr/lib/node_modules/omniroute/app && cp -a /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION} /usr/lib/node_modules/omniroute/app && pm2 restart omniroute --update-env"
```

## Gotchas

- **Never build in a worktree with symlinked `node_modules`** β€” the standalone copy step
follows symlinks and produces a broken bundle. Use the main checkout or run `npm ci`
inside the worktree first.
- **`pm2 restart --update-env` does NOT re-read `ecosystem.config.cjs`** β€” if you changed
env vars in the ecosystem file, use `pm2 reload` or `pm2 delete + pm2 start` instead.
- **Parallel dev + release builds**: to avoid clobbering the dev server's `.build/next`,
pass `NEXT_DIST_DIR=.build/next-release` to `build:release` in CI or concurrent deploys:
`NEXT_DIST_DIR=.build/next-release npm run build:release`
then adjust the rsync source to `dist-release/` (or whatever `build:release` assembles into).
- **`dist/BUILD_SHA` must match the deployed HEAD** β€” always confirm before rsyncing.
A mismatch means the build ran from a dirty or incorrect commit.
92 changes: 82 additions & 10 deletions .agents/skills/deploy-vps-both-cc/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,118 @@ description: Deploy the latest OmniRoute code to BOTH the Akamai VPS and the Loc

# Deploy to VPS (Both) Workflow

Deploy OmniRoute to the production VPSs using `npm pack + scp` + PM2.
Deploy OmniRoute to both production VPSs using a clean `build:release` + `rsync` + PM2 restart.

**Akamai VPS:** `69.164.221.35`
**Local VPS:** `192.168.0.15`
**Process manager:** PM2 (`omniroute`)
**Port:** `20128`
**PM2 entry:** `/usr/lib/node_modules/omniroute/app/server.js`
**Remote install dir:** `/usr/lib/node_modules/omniroute/app/` (VPS image dir β€” unchanged)

> [!IMPORTANT]
> The npm registry rejects packages > 100MB, so deployment uses **npm pack + scp**.
> **Build must run where `node_modules` is REAL.** A git worktree with symlinked
> `node_modules` breaks the Next.js standalone assembly. Always build from the main
> checkout (or an `npm ci`'d worktree), never from `OmniRoute-*` worktrees unless
> you first ran `npm ci` inside them.

## Steps

### 1. Build + pack locally
### 1. Clean build + sentinel

Build **once** locally β€” the same `dist/` is shipped to both VPSs:

// turbo

```bash
cd /home/diegosouzapw/dev/proxys/OmniRoute && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
cd /home/diegosouzapw/dev/proxys/OmniRoute && npm run build:release
```

### 2. Copy to both VPS and install
`build:release` does:
1. Deletes `.build/` and `dist/` (clean rebuild β€” no stale cache)
2. Runs `next build` β†’ `.build/next/` (intermediates)
3. Assembles the shippable bundle into `dist/` via `assembleStandalone`
4. Writes `dist/BUILD_SHA` = `git rev-parse --short HEAD` (deploy sentinel)

Verify the sentinel before shipping:

```bash
cat /home/diegosouzapw/dev/proxys/OmniRoute/dist/BUILD_SHA && git -C /home/diegosouzapw/dev/proxys/OmniRoute rev-parse --short HEAD
```

Both lines must match. If they differ, the build is stale β€” re-run `build:release`.

### 2. Back up the running bundle on both VPSs

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
ssh root@69.164.221.35 "cp -a /usr/lib/node_modules/omniroute/app /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION}" &
ssh root@192.168.0.15 "cp -a /usr/lib/node_modules/omniroute/app /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION}" &
wait
```

### 3. Stop the processes, then rsync `dist/` β†’ remote `app/` on both VPSs

The VPS image directory is still named `app/`; we ship the **contents** of our local `dist/`. **Stop both running processes FIRST** so `rsync --delete` never removes chunk files out from under a live server β€” that race produces the transient `[Shutdown] Cannot find module ./chunks/NNNNN.js` seen mid-deploy:

// turbo-all

```bash
scp omniroute-*.tgz root@69.164.221.35:/tmp/ && scp omniroute-*.tgz root@192.168.0.15:/tmp/
ssh root@69.164.221.35 "pm2 stop omniroute" & ssh root@192.168.0.15 "pm2 stop omniroute" & wait
rsync -az --delete /home/diegosouzapw/dev/proxys/OmniRoute/dist/ root@69.164.221.35:/usr/lib/node_modules/omniroute/app/ && rsync -az --delete /home/diegosouzapw/dev/proxys/OmniRoute/dist/ root@192.168.0.15:/usr/lib/node_modules/omniroute/app/
```

### 4. Start + health check on both VPSs

`pm2 restart` on a stopped app starts it again with a clean module graph:

```bash
ssh root@69.164.221.35 "pm2 restart omniroute --update-env && pm2 save"
```

```bash
ssh root@69.164.221.35 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts --legacy-peer-deps && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && (pm2 delete omniroute 2>/dev/null || true) && pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo 'βœ… Akamai done'"
ssh root@192.168.0.15 "pm2 restart omniroute --update-env && pm2 save"
```

```bash
ssh root@192.168.0.15 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts --legacy-peer-deps && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && (pm2 delete omniroute 2>/dev/null || true) && pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo 'βœ… Local done'"
sleep 5
curl -sf http://69.164.221.35:20128/api/monitoring/health | jq '{status:.status, version:.version}'
curl -sf http://192.168.0.15:20128/api/monitoring/health | jq '{status:.status, version:.version}'
```

### 3. Verify the deployment
Expected: HTTP 200, `"status": "ok"` on both.

### 5. Verify the deployment

```bash
curl -s -o /dev/null -w 'AKAMAI HTTP %{http_code}\n' http://69.164.221.35:20128/
curl -s -o /dev/null -w 'LOCAL HTTP %{http_code}\n' http://192.168.0.15:20128/
```

## Rollback

If either VPS fails its health check, restore from backup (adjust host as needed):

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
# Akamai rollback:
ssh root@69.164.221.35 "rm -rf /usr/lib/node_modules/omniroute/app && cp -a /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION} /usr/lib/node_modules/omniroute/app && pm2 restart omniroute --update-env"
# Local rollback:
ssh root@192.168.0.15 "rm -rf /usr/lib/node_modules/omniroute/app && cp -a /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION} /usr/lib/node_modules/omniroute/app && pm2 restart omniroute --update-env"
```

## Gotchas

- **Never build in a worktree with symlinked `node_modules`** β€” the standalone copy step
follows symlinks and produces a broken bundle. Use the main checkout or run `npm ci`
inside the worktree first.
- **`pm2 restart --update-env` does NOT re-read `ecosystem.config.cjs`** β€” if you changed
env vars in the ecosystem file, use `pm2 reload` or `pm2 delete + pm2 start` instead.
- **Parallel dev + release builds**: to avoid clobbering the dev server's `.build/next`,
pass `NEXT_DIST_DIR=.build/next-release` to `build:release` in CI or concurrent deploys:
`NEXT_DIST_DIR=.build/next-release npm run build:release`
then adjust the rsync source to `dist-release/`.
- **`dist/BUILD_SHA` must match the deployed HEAD** β€” always confirm before rsyncing.
A mismatch means the build ran from a dirty or incorrect commit.
- **Build once, deploy to both** β€” never run two separate builds for the two VPSs.
The same `dist/` artifact (same `BUILD_SHA`) must land on both hosts to keep
versions in sync.
80 changes: 73 additions & 7 deletions .agents/skills/deploy-vps-local-cc/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,102 @@ description: Deploy the latest OmniRoute code to the Local VPS (192.168.0.15)

# Deploy to Local VPS Workflow

Deploy OmniRoute to the Local VPS using `npm pack + scp` + PM2.
Deploy OmniRoute to the Local VPS using a clean `build:release` + `rsync` + PM2 restart.

**Local VPS:** `192.168.0.15`
**Process manager:** PM2 (`omniroute`)
**Port:** `20128`
**Remote install dir:** `/usr/lib/node_modules/omniroute/app/` (VPS image dir β€” unchanged)

> [!IMPORTANT]
> **Build must run where `node_modules` is REAL.** A git worktree with symlinked
> `node_modules` breaks the Next.js standalone assembly. Always build from the main
> checkout (or an `npm ci`'d worktree), never from `OmniRoute-*` worktrees unless
> you first ran `npm ci` inside them.

## Steps

### 1. Build + pack locally
### 1. Clean build + sentinel

Run from a checkout with a **real** `node_modules`:

// turbo

```bash
cd /home/diegosouzapw/dev/proxys/OmniRoute && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
cd /home/diegosouzapw/dev/proxys/OmniRoute && npm run build:release
```

`build:release` does:
1. Deletes `.build/` and `dist/` (clean rebuild β€” no stale cache)
2. Runs `next build` β†’ `.build/next/` (intermediates)
3. Assembles the shippable bundle into `dist/` via `assembleStandalone`
4. Writes `dist/BUILD_SHA` = `git rev-parse --short HEAD` (deploy sentinel)

Verify the sentinel before shipping:

```bash
cat /home/diegosouzapw/dev/proxys/OmniRoute/dist/BUILD_SHA && git -C /home/diegosouzapw/dev/proxys/OmniRoute rev-parse --short HEAD
```

### 2. Copy to Local VPS and install
Both lines must match. If they differ, the build is stale β€” re-run `build:release`.

### 2. Back up the running bundle on the VPS

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
ssh root@192.168.0.15 "cp -a /usr/lib/node_modules/omniroute/app /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION}"
```

### 3. Stop the process, then rsync `dist/` β†’ remote `app/`

The VPS image directory is still named `app/`; we ship the **contents** of our local `dist/`. **Stop the running process FIRST** so `rsync --delete` never removes chunk files out from under the live server β€” that race produces the transient `[Shutdown] Cannot find module ./chunks/NNNNN.js` seen mid-deploy:

// turbo-all

```bash
scp omniroute-*.tgz root@192.168.0.15:/tmp/
ssh root@192.168.0.15 "pm2 stop omniroute"
rsync -az --delete /home/diegosouzapw/dev/proxys/OmniRoute/dist/ root@192.168.0.15:/usr/lib/node_modules/omniroute/app/
```

### 4. Start + health check

`pm2 restart` on a stopped app starts it again with a clean module graph:

```bash
ssh root@192.168.0.15 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts --legacy-peer-deps && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && (pm2 delete omniroute 2>/dev/null || true) && pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo 'βœ… Local done'"
ssh root@192.168.0.15 "pm2 restart omniroute --update-env && pm2 save"
```

### 3. Verify the deployment
```bash
sleep 5 && curl -sf http://192.168.0.15:20128/api/monitoring/health | jq '{status:.status, version:.version}'
```

Expected: HTTP 200, `"status": "ok"` (or equivalent health payload).

### 5. Verify the deployment

```bash
curl -s -o /dev/null -w 'LOCAL HTTP %{http_code}\n' http://192.168.0.15:20128/
```

## Rollback

If the health check fails, restore the backup:

```bash
OMNIROUTE_VERSION=$(node -p "require('/home/diegosouzapw/dev/proxys/OmniRoute/package.json').version")
ssh root@192.168.0.15 "rm -rf /usr/lib/node_modules/omniroute/app && cp -a /usr/lib/node_modules/omniroute/app.bak-${OMNIROUTE_VERSION} /usr/lib/node_modules/omniroute/app && pm2 restart omniroute --update-env"
```

## Gotchas

- **Never build in a worktree with symlinked `node_modules`** β€” the standalone copy step
follows symlinks and produces a broken bundle. Use the main checkout or run `npm ci`
inside the worktree first.
- **`pm2 restart --update-env` does NOT re-read `ecosystem.config.cjs`** β€” if you changed
env vars in the ecosystem file, use `pm2 reload` or `pm2 delete + pm2 start` instead.
- **Parallel dev + release builds**: to avoid clobbering the dev server's `.build/next`,
pass `NEXT_DIST_DIR=.build/next-release` to `build:release` in CI or concurrent deploys:
`NEXT_DIST_DIR=.build/next-release npm run build:release`
then adjust the rsync source to `dist-release/` (or whatever `build:release` assembles into).
- **`dist/BUILD_SHA` must match the deployed HEAD** β€” always confirm before rsyncing.
A mismatch means the build ran from a dirty or incorrect commit.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# Dependencies and build output
node_modules
.next
.build
out
build
dist
Expand Down
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,16 @@ APP_LOG_TO_FILE=true
# Used by: open-sse/executors/cursor.ts.
# CURSOR_STREAM_TIMEOUT_MS=300000

# Cursor tool-commit directive toggle. Default-on: when a request declares
# tools, a directive is prepended so composer-2.5 reliably issues tool calls
# instead of narrating intent. Set to 0 to disable.
# Used by: open-sse/executors/cursor.ts.
# CURSOR_TOOL_DIRECTIVE=1

# Per-image fetch timeout (ms) for remote image_url vision input. Default: 15000.
# Used by: open-sse/utils/cursorImages.ts.
# CURSOR_IMAGE_FETCH_TIMEOUT_MS=15000

# Cursor state DB path override (for cursor version detection).
# Used by: open-sse/utils/cursorVersionDetector.ts. Default: probed automatically.
# CURSOR_STATE_DB_PATH=
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,11 @@ jobs:
cache: npm
- run: npm ci
- run: npm run check:node-runtime
# build:cli runs a clean build into .build/next and assembles dist/
# For release builds prefer: npm run build:release (clean rebuild + HEAD sentinel)
- run: npm run build:cli
- name: Assert dist/server.js exists
run: test -f dist/server.js || (echo "dist/server.js missing β€” build:cli did not assemble correctly" && exit 1)
- run: npm run check:pack-artifact

electron-package-smoke:
Expand Down
Loading