feat: OpenCode integration Phase 5 — API routes, frontend UI

API changes:
- GET /api/opencode/status — check if OpenCode CLI is available
- POST /api/sessions — support mode: 'opencode' with openCodeConfig
- POST /api/quick-start — support mode: 'opencode', guard writeHooksConfig
- Fix hardcoded mode: 'claude' in lifecycle logs (use session.mode)

Schema changes:
- Add 'opencode' to mode enums in CreateSessionSchema, QuickStartSchema
- Add OpenCodeConfigSchema (model, autoAllowTools, continueSession, etc.)
- Add 'OPENCODE_' to ALLOWED_ENV_PREFIXES
- Block OPENCODE_SERVER_PASSWORD in BLOCKED_ENV_KEYS (atomic with prefix addition)

Frontend UI:
- "Run OC" button in toolbar + "Run OpenCode" on welcome screen
- Green "oc" tab badge for OpenCode sessions (matching green brand)
- runOpenCode() method — checks availability, quick-starts with autoAllowTools
- Feature gating: hide Respawn/Context/Ralph tabs for OpenCode sessions
- Session options defaults to Summary tab for OpenCode
- CSS: OpenCode button styles, tab badge styles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
arkon
2026-02-26 10:16:20 +01:00
co-authored by Claude Opus 4.6
parent 0b60f2691f
commit 02f3bea3c1
5 changed files with 153 additions and 19 deletions
+32
View File
@@ -616,6 +616,11 @@ body {
color: var(--yellow);
}
.session-tab .tab-mode.opencode {
background: rgba(16, 185, 129, 0.2);
color: #10b981;
}
/* Timer Banner - Compact */
.timer-banner {
display: flex;
@@ -1727,6 +1732,19 @@ body {
color: #fff;
}
.welcome-btn-opencode {
background: linear-gradient(135deg, #0a2e2a 0%, #0d4a40 100%);
border-color: #10b981;
color: #6ee7b7;
}
.welcome-btn-opencode:hover {
background: linear-gradient(135deg, #0d4a40 0%, #116a58 100%);
border-color: #34d399;
box-shadow: 0 0 12px rgba(16, 185, 129, 0.4);
color: #a7f3d0;
}
.welcome-btn-ralph {
background: linear-gradient(135deg, #3d3415 0%, #4a3f1a 100%);
border-color: #6b5a1e;
@@ -1876,6 +1894,20 @@ body {
color: #a8d8a8;
}
.btn-toolbar.btn-opencode {
background: linear-gradient(135deg, #0a2e2a 0%, #0d4a40 100%);
border-color: #10b981;
color: #6ee7b7;
font-weight: 500;
}
.btn-toolbar.btn-opencode:hover {
background: linear-gradient(135deg, #0d4a40 0%, #116a58 100%);
border-color: #34d399;
box-shadow: 0 0 8px rgba(16, 185, 129, 0.4);
color: #a7f3d0;
}
/* Stop button - hidden on desktop, shown on mobile */
.btn-toolbar.btn-stop {
display: none;