mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-02 13:39:41 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0809f59f0f | ||
|
|
eda95adaa9 |
@@ -1,5 +1,24 @@
|
|||||||
# aicodeman
|
# aicodeman
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
### Major Changes
|
||||||
|
|
||||||
|
- # Codeman 1.0.0 🎉
|
||||||
|
|
||||||
|
The first stable release of Codeman — and it comes with a fresh new look.
|
||||||
|
|
||||||
|
**New: theme skins.** Codeman now ships a built-in skin switcher (App Settings → Display → Appearance):
|
||||||
|
- **OG Codeman** — the original look, preserved exactly.
|
||||||
|
- **Daylight Green** — a fresh emerald-on-slate theme.
|
||||||
|
- **Daylight Blue** — bright sky-blue on lifted slate (the new default).
|
||||||
|
|
||||||
|
Skins apply instantly, persist per device (with a pre-paint script so there's no flash on load), and re-theme any open terminals live. The system is built on `html[data-skin]` design tokens and self-hosted Manrope (UI) + JetBrains Mono (terminal) fonts — no external CDN, CSP-safe.
|
||||||
|
|
||||||
|
**1.0.0 milestone.** This marks the start of the stable 1.x line: the CLI, documented environment variables, and the `{ success, data }` HTTP/SSE API envelope follow semantic versioning (see `docs/versioning-policy.md`).
|
||||||
|
|
||||||
|
**Thank you to everyone who helped build Codeman.** This release is dedicated to all of our contributors for their work on the project: Ark0N, Aamer Akhter (@aakhter), Tenggan Zhang (@TeigenZhang), zhouyuan / @sunnyzhouy, jaypark, Marco Migozzi, Skúli Arnlaugsson, Aaron Fields, Loïc Sculier, and Noah Waldner (@noahwaldner). 💙
|
||||||
|
|
||||||
## 0.9.14
|
## 0.9.14
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ When user says "COM":
|
|||||||
|
|
||||||
CI runs `npm run check:lockfile` on every push/PR, so lockfile drift fails the build even if the `version-packages` script is bypassed.
|
CI runs `npm run check:lockfile` on every push/PR, so lockfile drift fails the build even if the `version-packages` script is bypassed.
|
||||||
|
|
||||||
**Version**: 0.9.14 (must match `package.json`)
|
**Version**: 1.0.0 (must match `package.json`)
|
||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "aicodeman",
|
"name": "aicodeman",
|
||||||
"version": "0.9.14",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "aicodeman",
|
"name": "aicodeman",
|
||||||
"version": "0.9.14",
|
"version": "1.0.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "aicodeman",
|
"name": "aicodeman",
|
||||||
"version": "0.9.14",
|
"version": "1.0.0",
|
||||||
"description": "Mission control for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
|
"description": "Mission control for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -580,6 +580,7 @@ class CodemanApp {
|
|||||||
const _kbSettings = this.loadAppSettingsFromStorage();
|
const _kbSettings = this.loadAppSettingsFromStorage();
|
||||||
if (_kbSettings.extendedKeyboardBar) KeyboardAccessoryBar.setMode('extended');
|
if (_kbSettings.extendedKeyboardBar) KeyboardAccessoryBar.setMode('extended');
|
||||||
this.applyHeaderVisibilitySettings();
|
this.applyHeaderVisibilitySettings();
|
||||||
|
this.applySkin();
|
||||||
this.applyTabWrapSettings();
|
this.applyTabWrapSettings();
|
||||||
this.applyMonitorVisibility();
|
this.applyMonitorVisibility();
|
||||||
// Remove mobile-init class now that JS has applied visibility settings.
|
// Remove mobile-init class now that JS has applied visibility settings.
|
||||||
@@ -637,6 +638,7 @@ class CodemanApp {
|
|||||||
// Load server-stored settings (async, re-applies visibility after load)
|
// Load server-stored settings (async, re-applies visibility after load)
|
||||||
this.loadAppSettingsFromServer(settingsPromise).then(() => {
|
this.loadAppSettingsFromServer(settingsPromise).then(() => {
|
||||||
this.applyHeaderVisibilitySettings();
|
this.applyHeaderVisibilitySettings();
|
||||||
|
this.applySkin();
|
||||||
this.applyTabWrapSettings();
|
this.applyTabWrapSettings();
|
||||||
this.applyMonitorVisibility();
|
this.applyMonitorVisibility();
|
||||||
});
|
});
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+22
-10
@@ -8,7 +8,7 @@
|
|||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||||
<meta name="description" content="Claude Code session manager with web interface">
|
<meta name="description" content="Claude Code session manager with web interface">
|
||||||
<meta name="theme-color" content="#0a0a0a">
|
<meta name="theme-color" content="#11151c">
|
||||||
<meta name="google" content="notranslate">
|
<meta name="google" content="notranslate">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
@@ -41,15 +41,17 @@
|
|||||||
<script defer src="vendor/marked.min.js"></script>
|
<script defer src="vendor/marked.min.js"></script>
|
||||||
<!-- Synchronous mobile detection — runs before first paint to prevent panel flash -->
|
<!-- Synchronous mobile detection — runs before first paint to prevent panel flash -->
|
||||||
<script>if(window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024))document.documentElement.classList.add('mobile-init');</script>
|
<script>if(window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024))document.documentElement.classList.add('mobile-init');</script>
|
||||||
|
<!-- Synchronous skin selection — runs before first paint to prevent theme flash -->
|
||||||
|
<script>try{var s=localStorage.getItem('codeman:skin');if(s!=='og'&&s!=='daylight-green'&&s!=='daylight-blue')s='daylight-blue';document.documentElement.dataset.skin=s;window.__codemanSkin=s;}catch(e){document.documentElement.dataset.skin='daylight-blue';window.__codemanSkin='daylight-blue';}</script>
|
||||||
<!-- Inline critical CSS for instant skeleton paint (before styles.css loads) -->
|
<!-- Inline critical CSS for instant skeleton paint (before styles.css loads) -->
|
||||||
<style>
|
<style>
|
||||||
.loading-skeleton{display:flex;flex-direction:column;height:100vh;height:100dvh;background:#09090b}
|
.loading-skeleton{display:flex;flex-direction:column;height:100vh;height:100dvh;background:#11151c}
|
||||||
.skeleton-header{height:40px;background:rgba(19,19,22,0.85);border-bottom:1px solid rgba(255,255,255,0.06);display:flex;align-items:center;padding:0 12px}
|
.skeleton-header{height:40px;background:rgba(31,38,48,0.85);border-bottom:1px solid rgba(255,255,255,0.08);display:flex;align-items:center;padding:0 12px}
|
||||||
.skeleton-brand{color:#60a5fa;font-size:14px;font-weight:700;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;opacity:.7}
|
.skeleton-brand{color:#38b6f0;font-size:14px;font-weight:700;font-family:'Manrope',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;opacity:.85}
|
||||||
.skeleton-tabs{display:flex;gap:4px;margin-left:16px}
|
.skeleton-tabs{display:flex;gap:4px;margin-left:16px}
|
||||||
.skeleton-tab{width:80px;height:24px;background:rgba(255,255,255,0.04);border-radius:6px}
|
.skeleton-tab{width:80px;height:24px;background:rgba(255,255,255,0.04);border-radius:6px}
|
||||||
.skeleton-terminal{flex:1;background:#0d0d0d}
|
.skeleton-terminal{flex:1;background:#161b23}
|
||||||
.skeleton-toolbar{height:42px;background:rgba(19,19,22,0.85);border-top:1px solid rgba(255,255,255,0.06)}
|
.skeleton-toolbar{height:42px;background:rgba(31,38,48,0.85);border-top:1px solid rgba(255,255,255,0.08)}
|
||||||
.app-loaded .loading-skeleton{display:none}
|
.app-loaded .loading-skeleton{display:none}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -178,8 +180,8 @@
|
|||||||
<svg viewBox="0 0 36 36" class="ralph-ring-svg">
|
<svg viewBox="0 0 36 36" class="ralph-ring-svg">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="ralphGradientMini" x1="0%" y1="0%" x2="100%" y2="100%">
|
<linearGradient id="ralphGradientMini" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
<stop offset="0%" stop-color="#3b82f6" />
|
<stop offset="0%" stop-color="#3ec8ee" />
|
||||||
<stop offset="100%" stop-color="#22c55e" />
|
<stop offset="100%" stop-color="#2b8fd9" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
<circle class="ralph-ring-bg" cx="18" cy="18" r="15.9" />
|
<circle class="ralph-ring-bg" cx="18" cy="18" r="15.9" />
|
||||||
@@ -224,8 +226,8 @@
|
|||||||
<svg viewBox="0 0 100 100" class="ralph-ring-svg-large">
|
<svg viewBox="0 0 100 100" class="ralph-ring-svg-large">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="ralphGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
<linearGradient id="ralphGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
<stop offset="0%" stop-color="#3b82f6" />
|
<stop offset="0%" stop-color="#3ec8ee" />
|
||||||
<stop offset="100%" stop-color="#22c55e" />
|
<stop offset="100%" stop-color="#2b8fd9" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
<circle class="ralph-ring-track" cx="50" cy="50" r="42" />
|
<circle class="ralph-ring-track" cx="50" cy="50" r="42" />
|
||||||
@@ -918,6 +920,16 @@
|
|||||||
<!-- Display Tab -->
|
<!-- Display Tab -->
|
||||||
<div class="modal-tab-content" id="settings-display">
|
<div class="modal-tab-content" id="settings-display">
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
|
<!-- Appearance Section -->
|
||||||
|
<div class="settings-section-header">Appearance</div>
|
||||||
|
<div class="settings-item settings-item-skin" title="Visual theme for this device (not synced)">
|
||||||
|
<span class="settings-item-label">Skin</span>
|
||||||
|
<select id="appSettingsSkin" class="form-select">
|
||||||
|
<option value="daylight-blue">Daylight Blue</option>
|
||||||
|
<option value="daylight-green">Daylight Green</option>
|
||||||
|
<option value="og">OG Codeman</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<!-- Input Section -->
|
<!-- Input Section -->
|
||||||
<div class="settings-section-header">Input</div>
|
<div class="settings-section-header">Input</div>
|
||||||
<div class="settings-item settings-item-multiline" title="Shows typed characters instantly via overlay while forwarding keystrokes to the server in the background. Enables Tab completion, preserves input across tab switches, and protects against session crashes. Recommended for mobile and high-latency connections.">
|
<div class="settings-item settings-item-multiline" title="Shows typed characters instantly via overlay while forwarding keystrokes to the server in the background. Enables Tab completion, preserves input across tab switches, and protects against session crashes. Recommended for mobile and high-latency connections.">
|
||||||
|
|||||||
@@ -1550,29 +1550,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const terminal = new Terminal({
|
const terminal = new Terminal({
|
||||||
theme: {
|
theme: { ...window.codemanCurrentXtermTheme() },
|
||||||
background: '#0d0d0d',
|
|
||||||
foreground: '#e0e0e0',
|
|
||||||
cursor: '#e0e0e0',
|
|
||||||
cursorAccent: '#0d0d0d',
|
|
||||||
selection: 'rgba(255, 255, 255, 0.3)',
|
|
||||||
black: '#0d0d0d',
|
|
||||||
red: '#ff6b6b',
|
|
||||||
green: '#51cf66',
|
|
||||||
yellow: '#ffd43b',
|
|
||||||
blue: '#339af0',
|
|
||||||
magenta: '#cc5de8',
|
|
||||||
cyan: '#22b8cf',
|
|
||||||
white: '#e0e0e0',
|
|
||||||
brightBlack: '#495057',
|
|
||||||
brightRed: '#ff8787',
|
|
||||||
brightGreen: '#69db7c',
|
|
||||||
brightYellow: '#ffe066',
|
|
||||||
brightBlue: '#5c7cfa',
|
|
||||||
brightMagenta: '#da77f2',
|
|
||||||
brightCyan: '#66d9e8',
|
|
||||||
brightWhite: '#ffffff',
|
|
||||||
},
|
|
||||||
fontFamily: '"Fira Code", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, monospace',
|
fontFamily: '"Fira Code", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, monospace',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
document.getElementById('appSettingsShowCost').checked = settings.showCost ?? defaults.showCost ?? false;
|
document.getElementById('appSettingsShowCost').checked = settings.showCost ?? defaults.showCost ?? false;
|
||||||
document.getElementById('appSettingsShowLifecycleLog').checked = settings.showLifecycleLog ?? defaults.showLifecycleLog ?? true;
|
document.getElementById('appSettingsShowLifecycleLog').checked = settings.showLifecycleLog ?? defaults.showLifecycleLog ?? true;
|
||||||
document.getElementById('appSettingsShowResponseViewer').checked = settings.showResponseViewer ?? defaults.showResponseViewer ?? false;
|
document.getElementById('appSettingsShowResponseViewer').checked = settings.showResponseViewer ?? defaults.showResponseViewer ?? false;
|
||||||
|
document.getElementById('appSettingsSkin').value = settings.skin ?? defaults.skin ?? 'daylight-blue';
|
||||||
document.getElementById('appSettingsShowMonitor').checked = settings.showMonitor ?? defaults.showMonitor ?? false;
|
document.getElementById('appSettingsShowMonitor').checked = settings.showMonitor ?? defaults.showMonitor ?? false;
|
||||||
document.getElementById('appSettingsShowProjectInsights').checked = settings.showProjectInsights ?? defaults.showProjectInsights ?? false;
|
document.getElementById('appSettingsShowProjectInsights').checked = settings.showProjectInsights ?? defaults.showProjectInsights ?? false;
|
||||||
document.getElementById('appSettingsShowFileBrowser').checked = settings.showFileBrowser ?? defaults.showFileBrowser ?? false;
|
document.getElementById('appSettingsShowFileBrowser').checked = settings.showFileBrowser ?? defaults.showFileBrowser ?? false;
|
||||||
@@ -1377,6 +1378,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
cjkInputEnabled: document.getElementById('appSettingsCjkInput').checked,
|
cjkInputEnabled: document.getElementById('appSettingsCjkInput').checked,
|
||||||
extendedKeyboardBar: document.getElementById('appSettingsExtendedKeyboardBar').checked,
|
extendedKeyboardBar: document.getElementById('appSettingsExtendedKeyboardBar').checked,
|
||||||
tabTwoRows: document.getElementById('appSettingsTabTwoRows').checked,
|
tabTwoRows: document.getElementById('appSettingsTabTwoRows').checked,
|
||||||
|
skin: document.getElementById('appSettingsSkin').value,
|
||||||
// Claude CLI settings
|
// Claude CLI settings
|
||||||
claudeMode: document.getElementById('appSettingsClaudeMode').value,
|
claudeMode: document.getElementById('appSettingsClaudeMode').value,
|
||||||
allowedTools: document.getElementById('appSettingsAllowedTools').value.trim(),
|
allowedTools: document.getElementById('appSettingsAllowedTools').value.trim(),
|
||||||
@@ -1491,6 +1493,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
|
|
||||||
// Apply header visibility immediately
|
// Apply header visibility immediately
|
||||||
this.applyHeaderVisibilitySettings();
|
this.applyHeaderVisibilitySettings();
|
||||||
|
this.applySkin();
|
||||||
this.applyTabWrapSettings();
|
this.applyTabWrapSettings();
|
||||||
this._updateTokensImmediate(); // Re-render token display (picks up showCost change)
|
this._updateTokensImmediate(); // Re-render token display (picks up showCost change)
|
||||||
this.applyMonitorVisibility();
|
this.applyMonitorVisibility();
|
||||||
@@ -1505,7 +1508,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
|
|
||||||
// Save to server (includes notification prefs for cross-browser persistence)
|
// Save to server (includes notification prefs for cross-browser persistence)
|
||||||
// Strip device-specific keys — localEchoEnabled/cjkInputEnabled are per-platform
|
// Strip device-specific keys — localEchoEnabled/cjkInputEnabled are per-platform
|
||||||
const { localEchoEnabled: _leo, cjkInputEnabled: _cjk, extendedKeyboardBar: _ekb, ...serverSettings } = settings;
|
const { localEchoEnabled: _leo, cjkInputEnabled: _cjk, extendedKeyboardBar: _ekb, skin: _skin, ...serverSettings } = settings;
|
||||||
try {
|
try {
|
||||||
const res = await this._apiPut('/api/settings', {
|
const res = await this._apiPut('/api/settings', {
|
||||||
...serverSettings,
|
...serverSettings,
|
||||||
@@ -1664,6 +1667,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
ralphTrackerEnabled: false,
|
ralphTrackerEnabled: false,
|
||||||
tabTwoRows: false,
|
tabTwoRows: false,
|
||||||
cjkInputEnabled: false,
|
cjkInputEnabled: false,
|
||||||
|
skin: 'daylight-blue',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Desktop defaults - rely on ?? operators in apply functions
|
// Desktop defaults - rely on ?? operators in apply functions
|
||||||
@@ -1701,6 +1705,24 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Apply the chosen skin live: sets the html[data-skin] attribute, syncs BOTH
|
||||||
|
// localStorage locations (the standalone 'codeman:skin' key the pre-paint head
|
||||||
|
// script reads + the app-settings blob field written by saveAppSettingsToStorage),
|
||||||
|
// updates window.__codemanSkin, and re-themes any live terminals.
|
||||||
|
applySkin() {
|
||||||
|
const settings = this.loadAppSettingsFromStorage();
|
||||||
|
const defaults = this.getDefaultSettings();
|
||||||
|
const skin = settings.skin ?? defaults.skin ?? 'daylight-blue';
|
||||||
|
document.documentElement.setAttribute('data-skin', skin);
|
||||||
|
window.__codemanSkin = skin;
|
||||||
|
try {
|
||||||
|
localStorage.setItem('codeman:skin', skin);
|
||||||
|
} catch (_e) {
|
||||||
|
/* private mode */
|
||||||
|
}
|
||||||
|
if (typeof this.applyTerminalSkin === 'function') this.applyTerminalSkin(skin);
|
||||||
|
},
|
||||||
|
|
||||||
applyHeaderVisibilitySettings() {
|
applyHeaderVisibilitySettings() {
|
||||||
const settings = this.loadAppSettingsFromStorage();
|
const settings = this.loadAppSettingsFromStorage();
|
||||||
const defaults = this.getDefaultSettings();
|
const defaults = this.getDefaultSettings();
|
||||||
@@ -1944,6 +1966,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
'showLifecycleLog', 'showResponseViewer',
|
'showLifecycleLog', 'showResponseViewer',
|
||||||
'showMonitor', 'showProjectInsights', 'showFileBrowser', 'showSubagents',
|
'showMonitor', 'showProjectInsights', 'showFileBrowser', 'showSubagents',
|
||||||
'subagentActiveTabOnly', 'tabTwoRows', 'localEchoEnabled', 'cjkInputEnabled', 'extendedKeyboardBar',
|
'subagentActiveTabOnly', 'tabTwoRows', 'localEchoEnabled', 'cjkInputEnabled', 'extendedKeyboardBar',
|
||||||
|
'skin',
|
||||||
]);
|
]);
|
||||||
// Merge settings: non-display keys always sync from server,
|
// Merge settings: non-display keys always sync from server,
|
||||||
// display keys only seed from server when localStorage has no value
|
// display keys only seed from server when localStorage has no value
|
||||||
|
|||||||
+373
-26
@@ -1,36 +1,65 @@
|
|||||||
/* Codeman - Terminal-First UI */
|
/* Codeman - Terminal-First UI */
|
||||||
|
|
||||||
|
/* Self-hosted UI + mono fonts (Carbon Aurora · Daylight) — served from /fonts,
|
||||||
|
no external CDN, CSP-safe (font-src 'self'). Variable woff2 cover all weights. */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Manrope';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400 800;
|
||||||
|
src: url('fonts/manrope-variable.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains Mono';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400 700;
|
||||||
|
src: url('fonts/jetbrains-mono-variable.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--bg-dark: #09090b;
|
/* Carbon Aurora · Daylight — deep-but-not-black slate, surfaces step UP into the light */
|
||||||
--bg-card: #131316;
|
--bg-dark: #11151c;
|
||||||
--bg-input: #1a1a1f;
|
--bg-card: #1b222c;
|
||||||
--bg-hover: #1f1f26;
|
--bg-input: #202833;
|
||||||
--border: #232329;
|
--bg-hover: #2a323d;
|
||||||
--border-light: #2e2e38;
|
--border: #2b333f;
|
||||||
--text: #ececf0;
|
--border-light: #3a4350;
|
||||||
--text-dim: #8b8b97;
|
--text: #f3f6fa;
|
||||||
--text-muted: #52525e;
|
--text-dim: #98a2b1;
|
||||||
--accent: #3b82f6;
|
--text-muted: #717b8c;
|
||||||
--accent-hover: #60a5fa;
|
/* SINGLE cohesive accent — optimistic emerald → teal (replaces the old blue) */
|
||||||
--green: #22c55e;
|
--accent: #38b6f0;
|
||||||
--yellow: #eab308;
|
--accent-hover: #3ec8ee;
|
||||||
--red: #ef4444;
|
/* calmer secondary green for non-primary pills/dots so Run + ring stay focal */
|
||||||
|
--green: #44b993;
|
||||||
|
/* warm, quiet "working" amber (no second saturated hue) */
|
||||||
|
--yellow: #f0c25a;
|
||||||
|
--red: #e06363;
|
||||||
|
/* Daylight accent extras — referenced by the v1.0 override block at end of file */
|
||||||
|
--accent-d: #2487c9;
|
||||||
|
--emerald: #3ec8ee;
|
||||||
|
--teal: #2b8fd9;
|
||||||
|
--accent-soft: #44b993;
|
||||||
|
--accent-ink: #04223a;
|
||||||
|
--warm: #e8c79a;
|
||||||
|
--ring-glow: 0 0 12px -2px rgba(56, 182, 240, 0.55);
|
||||||
--header-height: 36px;
|
--header-height: 36px;
|
||||||
--toolbar-height: 42px;
|
--toolbar-height: 42px;
|
||||||
--glass-bg: rgba(19, 19, 22, 0.85);
|
--glass-bg: rgba(31, 38, 48, 0.85);
|
||||||
--glass-border: rgba(255, 255, 255, 0.06);
|
--glass-border: rgba(255, 255, 255, 0.08);
|
||||||
--subtle-shadow: 0 -1px 3px rgba(0, 0, 0, 0.3), 0 -4px 16px rgba(0, 0, 0, 0.15);
|
--subtle-shadow: 0 -1px 3px rgba(0, 0, 0, 0.3), 0 -4px 16px rgba(0, 0, 0, 0.15);
|
||||||
--btn-radius: 6px;
|
--btn-radius: 6px;
|
||||||
--transition-smooth: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
--transition-smooth: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
||||||
/* Session color palette */
|
/* Session color palette — retoned toward the Daylight system */
|
||||||
--session-red: #ef4444;
|
--session-red: #e06363;
|
||||||
--session-orange: #f97316;
|
--session-orange: #e8a45c;
|
||||||
--session-yellow: #eab308;
|
--session-yellow: #f0c25a;
|
||||||
--session-green: #22c55e;
|
--session-green: #44b993;
|
||||||
--session-blue: #3b82f6;
|
--session-blue: #2b8fd9;
|
||||||
--session-purple: #a855f7;
|
--session-purple: #a98fe0;
|
||||||
--session-pink: #ec4899;
|
--session-pink: #e07db0;
|
||||||
|
|
||||||
/* Safe area insets for notched devices (iPhone X+, Dynamic Island) */
|
/* Safe area insets for notched devices (iPhone X+, Dynamic Island) */
|
||||||
--safe-area-top: env(safe-area-inset-top, 0px);
|
--safe-area-top: env(safe-area-inset-top, 0px);
|
||||||
@@ -40,6 +69,78 @@
|
|||||||
|
|
||||||
/* Touch target minimum (iOS Human Interface Guidelines) */
|
/* Touch target minimum (iOS Human Interface Guidelines) */
|
||||||
--touch-target-min: 44px;
|
--touch-target-min: 44px;
|
||||||
|
|
||||||
|
/* UI font + accent/gradient/hover tokens referenced by the v1.0 override block.
|
||||||
|
These :root values equal the daylight-blue palette so the no-attribute fallback
|
||||||
|
matches current behavior. */
|
||||||
|
--ui-font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||||
|
--accent-rgb: 56, 182, 240;
|
||||||
|
--accent-grad-a: #3ec8ee;
|
||||||
|
--accent-grad-b: #2b8fd9;
|
||||||
|
--run-hover-a: #5cc4f5;
|
||||||
|
--run-hover-b: #3aa3e2;
|
||||||
|
--gear-hover: #2a93d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Skin: Daylight Blue (current default) ===== */
|
||||||
|
html[data-skin="daylight-blue"] {
|
||||||
|
--bg-dark: #11151c; --bg-card: #1b222c; --bg-input: #202833; --bg-hover: #2a323d;
|
||||||
|
--border: #2b333f; --border-light: #3a4350;
|
||||||
|
--text: #f3f6fa; --text-dim: #98a2b1; --text-muted: #717b8c;
|
||||||
|
--accent: #38b6f0; --accent-hover: #3ec8ee;
|
||||||
|
--term-bg: #161b23;
|
||||||
|
--green: #44b993; --yellow: #f0c25a; --red: #e06363;
|
||||||
|
--glass-bg: rgba(31, 38, 48, 0.85); --glass-border: rgba(255, 255, 255, 0.08);
|
||||||
|
--accent-d: #2487c9; --emerald: #3ec8ee; --teal: #2b8fd9;
|
||||||
|
--accent-soft: #44b993; --accent-ink: #04223a;
|
||||||
|
--accent-rgb: 56, 182, 240;
|
||||||
|
--accent-grad-a: #3ec8ee; --accent-grad-b: #2b8fd9;
|
||||||
|
--run-hover-a: #5cc4f5; --run-hover-b: #3aa3e2; --gear-hover: #2a93d0;
|
||||||
|
--ring-glow: 0 0 12px -2px rgba(56, 182, 240, 0.55);
|
||||||
|
--session-red: #e06363; --session-orange: #e8a45c; --session-yellow: #f0c25a;
|
||||||
|
--session-green: #44b993; --session-blue: #2b8fd9; --session-purple: #a98fe0; --session-pink: #e07db0;
|
||||||
|
--ui-font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Skin: Daylight Green ===== */
|
||||||
|
html[data-skin="daylight-green"] {
|
||||||
|
--bg-dark: #11151c; --bg-card: #1b222c; --bg-input: #202833; --bg-hover: #2a323d;
|
||||||
|
--border: #2b333f; --border-light: #3a4350;
|
||||||
|
--text: #f3f6fa; --text-dim: #98a2b1; --text-muted: #717b8c;
|
||||||
|
--accent: #2fd3aa; --accent-hover: #34d8a0;
|
||||||
|
--term-bg: #161b23;
|
||||||
|
--green: #44b993; --yellow: #f0c25a; --red: #e06363;
|
||||||
|
--glass-bg: rgba(31, 38, 48, 0.85); --glass-border: rgba(255, 255, 255, 0.08);
|
||||||
|
--accent-d: #19a987; --emerald: #34d8a0; --teal: #2bcbbb;
|
||||||
|
--accent-soft: #44b993; --accent-ink: #062019;
|
||||||
|
--accent-rgb: 47, 211, 170;
|
||||||
|
--accent-grad-a: #34d8a0; --accent-grad-b: #2bcbbb;
|
||||||
|
--run-hover-a: #3ee0aa; --run-hover-b: #34d4c4; --gear-hover: #1cbd97;
|
||||||
|
--ring-glow: 0 0 12px -2px rgba(47, 211, 170, 0.55);
|
||||||
|
--session-red: #e06363; --session-orange: #e8a45c; --session-yellow: #f0c25a;
|
||||||
|
--session-green: #44b993; --session-blue: #2bcbbb; --session-purple: #a98fe0; --session-pink: #e07db0;
|
||||||
|
--ui-font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Skin: OG Codeman (original look — no Daylight polish, system font) ===== */
|
||||||
|
html[data-skin="og"] {
|
||||||
|
--bg-dark: #09090b; --bg-card: #131316; --bg-input: #1a1a1f; --bg-hover: #1f1f26;
|
||||||
|
--border: #232329; --border-light: #2e2e38;
|
||||||
|
--text: #ececf0; --text-dim: #8b8b97; --text-muted: #52525e;
|
||||||
|
--accent: #3b82f6; --accent-hover: #60a5fa;
|
||||||
|
--term-bg: #0d0d0d;
|
||||||
|
--green: #22c55e; --yellow: #eab308; --red: #ef4444;
|
||||||
|
--glass-bg: rgba(19, 19, 22, 0.85); --glass-border: rgba(255, 255, 255, 0.06);
|
||||||
|
/* daylight-only extras left at sane neutral defaults (unused — override block does not apply to og) */
|
||||||
|
--accent-d: #3b82f6; --emerald: #3b82f6; --teal: #2563eb;
|
||||||
|
--accent-soft: #22c55e; --accent-ink: #0b1220;
|
||||||
|
--accent-rgb: 59, 130, 246;
|
||||||
|
--accent-grad-a: #3b82f6; --accent-grad-b: #2563eb;
|
||||||
|
--run-hover-a: #60a5fa; --run-hover-b: #3b82f6; --gear-hover: #2563eb;
|
||||||
|
--ring-glow: 0 0 12px -2px rgba(59, 130, 246, 0.55);
|
||||||
|
--session-red: #ef4444; --session-orange: #f97316; --session-yellow: #eab308;
|
||||||
|
--session-green: #22c55e; --session-blue: #3b82f6; --session-purple: #a855f7; --session-pink: #ec4899;
|
||||||
|
--ui-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -129,7 +230,7 @@ textarea:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
font-family: var(--ui-font);
|
||||||
background: var(--bg-dark);
|
background: var(--bg-dark);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@@ -2097,7 +2198,7 @@ body.solo-mode .btn-lifecycle-log {
|
|||||||
|
|
||||||
.terminal-container {
|
.terminal-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: #0d0d0d;
|
background: var(--term-bg, #161b23);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
/* Performance: isolate layout and paint operations.
|
/* Performance: isolate layout and paint operations.
|
||||||
@@ -3828,6 +3929,22 @@ body.solo-mode .btn-lifecycle-log {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skin picker: full-width row (not squeezed into a half-width grid cell) with an
|
||||||
|
auto-width select, so the "Skin" label keeps its space instead of truncating. */
|
||||||
|
.settings-item-skin {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
.settings-item-skin .settings-item-label {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
.settings-item-skin .form-select {
|
||||||
|
width: auto;
|
||||||
|
min-width: 220px;
|
||||||
|
max-width: 320px;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-item-multiline {
|
.settings-item-multiline {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
@@ -9057,3 +9174,233 @@ body.touch-device.cjk-input-visible .main {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
=== v1.0 Carbon Aurora · Daylight overrides ===
|
||||||
|
Single appended block — trivially removable. Retones the hardcoded
|
||||||
|
component colors that don't flow through :root: the active session
|
||||||
|
tab (#00FF66), the banners' literal gradients, the Ralph Material
|
||||||
|
palette, the Run/welcome/stop gradient buttons, the panels' glass,
|
||||||
|
and the welcome title. Calms heavy glows; the ONLY real saturation/
|
||||||
|
glow is reserved for the Run button + the progress ring.
|
||||||
|
============================================================ */
|
||||||
|
|
||||||
|
html:not([data-skin="og"]) {
|
||||||
|
/* ---- Brand wordmark: emerald, calm (kill the blue glow) ---- */
|
||||||
|
.logo:hover {
|
||||||
|
color: var(--accent-hover);
|
||||||
|
text-shadow: none;
|
||||||
|
filter: brightness(1.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Active session tab: crisp emerald (replaces neon #00FF66) ---- */
|
||||||
|
.session-tab.active {
|
||||||
|
background: rgba(var(--accent-rgb), 0.13) !important;
|
||||||
|
border: 1px solid var(--accent) !important;
|
||||||
|
color: var(--text) !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.session-tab:hover {
|
||||||
|
background: rgba(var(--accent-rgb), 0.06);
|
||||||
|
border-color: rgba(var(--accent-rgb), 0.2);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.session-tab .tab-number {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.session-tab.active .tab-number {
|
||||||
|
background: rgba(var(--accent-rgb), 0.2) !important;
|
||||||
|
border-color: rgba(var(--accent-rgb), 0.45) !important;
|
||||||
|
color: var(--accent-hover) !important;
|
||||||
|
}
|
||||||
|
/* per-color active tints: calm the glow, keep the identity hue as a quiet border */
|
||||||
|
.session-tab.active[data-color] {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
/* tab status dots: quiet, no halo */
|
||||||
|
.session-tab .tab-status.idle,
|
||||||
|
.session-tab .tab-status.busy {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.tab-glow { animation: none; box-shadow: none; }
|
||||||
|
|
||||||
|
/* ---- Timer banner: emerald-teal, flat ---- */
|
||||||
|
.timer-banner {
|
||||||
|
background: linear-gradient(90deg, rgba(31, 38, 48, 0.92), rgba(22, 27, 35, 0.92));
|
||||||
|
border-bottom: 1px solid var(--glass-border);
|
||||||
|
}
|
||||||
|
.timer-value { color: var(--accent); }
|
||||||
|
.timer-progress-fill { background: linear-gradient(90deg, var(--accent-grad-a), var(--accent-grad-b)); }
|
||||||
|
|
||||||
|
/* ---- Respawn banner: lifted slate, calm green hairline ---- */
|
||||||
|
.respawn-banner {
|
||||||
|
background: linear-gradient(90deg, rgba(31, 38, 48, 0.9), rgba(22, 27, 35, 0.9));
|
||||||
|
border-bottom: 1px solid var(--glass-border);
|
||||||
|
}
|
||||||
|
.respawn-countdown-timer .respawn-timer-value,
|
||||||
|
.action-type { color: var(--accent); }
|
||||||
|
.respawn-timer-progress { background: var(--accent); }
|
||||||
|
.respawn-action-log { border-left-color: rgba(var(--accent-rgb), 0.18); }
|
||||||
|
.respawn-action-log::-webkit-scrollbar-thumb { background: rgba(var(--accent-rgb), 0.28); }
|
||||||
|
|
||||||
|
/* ---- Ralph panel: replace the blue->green ring gradient + Material badges ---- */
|
||||||
|
.ralph-ring-text {
|
||||||
|
background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
.ralph-ring-bg, .ralph-ring-track { stroke: rgba(255, 255, 255, 0.1); }
|
||||||
|
/* Ralph status badges: collapse the off-token Material palette onto the system */
|
||||||
|
.ralph-status-badge { color: var(--text-dim); }
|
||||||
|
.ralph-status-dot { box-shadow: none; }
|
||||||
|
.ralph-info { background: rgba(var(--accent-rgb), 0.05); }
|
||||||
|
|
||||||
|
/* ---- Bottom toolbar + neutral buttons ---- */
|
||||||
|
.toolbar { box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.22), 0 -4px 14px rgba(0, 0, 0, 0.14); }
|
||||||
|
.btn-toolbar {
|
||||||
|
background: rgba(255, 255, 255, 0.045);
|
||||||
|
border-color: rgba(255, 255, 255, 0.09);
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.btn-toolbar:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: rgba(255, 255, 255, 0.14);
|
||||||
|
color: var(--text);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- RUN button: THE focal saturated accent (flat emerald->teal fill) ---- */
|
||||||
|
.btn-toolbar.btn-run,
|
||||||
|
.btn-toolbar.btn-run.mode-claude {
|
||||||
|
background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
font-weight: 700;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-run:hover,
|
||||||
|
.btn-toolbar.btn-run.mode-claude:hover {
|
||||||
|
background: linear-gradient(135deg, var(--run-hover-a), var(--run-hover-b));
|
||||||
|
box-shadow: 0 0 14px -2px rgba(var(--accent-rgb), 0.5);
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-run.mode-opencode {
|
||||||
|
background: linear-gradient(135deg, var(--accent-d), var(--accent-grad-b));
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-run.mode-opencode:hover { box-shadow: 0 0 14px -2px rgba(var(--accent-rgb), 0.45); }
|
||||||
|
.btn-toolbar.btn-run.mode-codex {
|
||||||
|
background: linear-gradient(135deg, var(--accent-grad-b), #5cc6e8);
|
||||||
|
border-color: var(--accent-grad-b);
|
||||||
|
color: #061c20;
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-run.mode-codex:hover { box-shadow: 0 0 14px -2px rgba(43, 203, 187, 0.45); }
|
||||||
|
.btn-toolbar.btn-run-gear {
|
||||||
|
background: var(--accent-d);
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-run-gear:hover { background: var(--gear-hover); box-shadow: none; }
|
||||||
|
.run-mode-dot.claude { background: var(--accent); }
|
||||||
|
.run-mode-dot.opencode { background: var(--accent-soft); }
|
||||||
|
.run-mode-dot.codex { background: var(--accent-grad-b); }
|
||||||
|
|
||||||
|
/* ---- Shell button: quiet neutral with a calm green tint ---- */
|
||||||
|
.btn-toolbar.btn-shell {
|
||||||
|
background: rgba(68, 185, 147, 0.1);
|
||||||
|
border: 1px solid rgba(68, 185, 147, 0.28);
|
||||||
|
color: var(--green);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-shell:hover {
|
||||||
|
background: rgba(68, 185, 147, 0.16);
|
||||||
|
border-color: rgba(68, 185, 147, 0.4);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Stop button: quiet neutral control (no rose glow) ---- */
|
||||||
|
.btn-toolbar.btn-stop {
|
||||||
|
background: rgba(255, 255, 255, 0.045);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||||
|
color: var(--text-dim);
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-stop:hover {
|
||||||
|
background: rgba(224, 99, 99, 0.14);
|
||||||
|
border-color: rgba(224, 99, 99, 0.4);
|
||||||
|
color: #f0a0a0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.btn-toolbar.btn-stop.confirming {
|
||||||
|
background: linear-gradient(135deg, #5a4a1a, #6b5620);
|
||||||
|
border-color: rgba(240, 194, 90, 0.6);
|
||||||
|
color: var(--yellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Case selector + add ---- */
|
||||||
|
.toolbar-select {
|
||||||
|
background: rgba(255, 255, 255, 0.045);
|
||||||
|
border-color: rgba(255, 255, 255, 0.09);
|
||||||
|
color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.toolbar-select:hover { background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.14); }
|
||||||
|
.toolbar-select:focus {
|
||||||
|
border-color: var(--accent);
|
||||||
|
box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.25);
|
||||||
|
}
|
||||||
|
.btn-case-add { color: var(--accent-soft); }
|
||||||
|
|
||||||
|
/* ---- Header system stats: cohesive accent meters ---- */
|
||||||
|
.stat-bar-mem { background: linear-gradient(90deg, var(--accent), var(--accent-hover)); }
|
||||||
|
.header-tokens.clickable:hover { background: rgba(var(--accent-rgb), 0.16); }
|
||||||
|
|
||||||
|
/* ---- Monitor + Subagents panels: lifted frosted slate ---- */
|
||||||
|
.monitor-panel,
|
||||||
|
.subagents-panel {
|
||||||
|
background: rgba(31, 38, 48, 0.95);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Subagent progress ring: emerald, calm glow ---- */
|
||||||
|
.subagent-ring-progress,
|
||||||
|
.subagent-ring circle.progress { stroke: var(--accent); }
|
||||||
|
|
||||||
|
/* ---- PROGRESS RING (Ralph large): the one place a soft glow lives ---- */
|
||||||
|
.ralph-ring-fill { filter: drop-shadow(0 0 6px rgba(var(--accent-rgb), 0.45)); }
|
||||||
|
|
||||||
|
/* ---- Welcome overlay: emerald title + Daylight buttons ---- */
|
||||||
|
.welcome-title {
|
||||||
|
background: linear-gradient(135deg, var(--accent-grad-a) 0%, var(--accent-grad-b) 50%, var(--accent-grad-a) 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
.welcome-btn-claude {
|
||||||
|
background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
}
|
||||||
|
.welcome-btn-claude:hover { box-shadow: 0 0 28px -4px rgba(var(--accent-rgb), 0.3); }
|
||||||
|
.welcome-btn-opencode {
|
||||||
|
background: linear-gradient(135deg, var(--accent-d), var(--accent-grad-b));
|
||||||
|
border-color: rgba(var(--accent-rgb), 0.4);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
}
|
||||||
|
.welcome-btn-opencode:hover { box-shadow: 0 0 28px -4px rgba(var(--accent-rgb), 0.25); }
|
||||||
|
.welcome-btn-tunnel {
|
||||||
|
background: linear-gradient(135deg, rgba(46, 55, 67, 0.9), rgba(56, 66, 79, 0.9));
|
||||||
|
border-color: var(--border-light);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.welcome-btn-tunnel:hover { box-shadow: none; }
|
||||||
|
.welcome-btn-tunnel.active {
|
||||||
|
background: linear-gradient(135deg, var(--accent-d), var(--accent-grad-a));
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent-ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Focus rings (driven by --accent, now emerald) stay accessible ---- */
|
||||||
|
:focus-visible { outline-color: var(--accent); }
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,11 +28,27 @@
|
|||||||
return isTerminalQueryResponse(data);
|
return isTerminalQueryResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Per-skin xterm.js palettes. The 'daylight-blue' object equals the legacy hardcoded
|
||||||
|
// theme, so default behavior is unchanged. Shared at module scope and exported on the
|
||||||
|
// global so both terminal-ui.js (main terminal) and panels-ui.js (teammate terminals,
|
||||||
|
// a separate IIFE) can read the current skin's palette.
|
||||||
|
const CODEMAN_XTERM_THEMES = {
|
||||||
|
og: { background: '#0d0d0d', foreground: '#e0e0e0', cursor: '#e0e0e0', cursorAccent: '#0d0d0d', selection: 'rgba(255,255,255,0.3)', black: '#0d0d0d', red: '#ff6b6b', green: '#51cf66', yellow: '#ffd43b', blue: '#339af0', magenta: '#cc5de8', cyan: '#22b8cf', white: '#e0e0e0', brightBlack: '#495057', brightRed: '#ff8787', brightGreen: '#69db7c', brightYellow: '#ffe066', brightBlue: '#5c7cfa', brightMagenta: '#da77f2', brightCyan: '#66d9e8', brightWhite: '#ffffff' },
|
||||||
|
'daylight-green': { background: '#161b23', foreground: '#dfe6ef', cursor: '#2fd3aa', cursorAccent: '#161b23', selection: 'rgba(47,211,170,0.22)', black: '#161b23', red: '#ff8585', green: '#34d8a0', yellow: '#f0c25a', blue: '#5cc6e8', magenta: '#c79af2', cyan: '#2bcbbb', white: '#dfe6ef', brightBlack: '#5b6675', brightRed: '#ffa0a0', brightGreen: '#5fe6b8', brightYellow: '#ffd884', brightBlue: '#82d4ee', brightMagenta: '#d6b3f7', brightCyan: '#5ee0d4', brightWhite: '#f3f6fa' },
|
||||||
|
'daylight-blue': { background: '#161b23', foreground: '#dfe6ef', cursor: '#38b6f0', cursorAccent: '#161b23', selection: 'rgba(56,182,240,0.22)', black: '#161b23', red: '#ff8585', green: '#34d8a0', yellow: '#f0c25a', blue: '#5cc6e8', magenta: '#c79af2', cyan: '#2bcbbb', white: '#dfe6ef', brightBlack: '#5b6675', brightRed: '#ffa0a0', brightGreen: '#5fe6b8', brightYellow: '#ffd884', brightBlue: '#82d4ee', brightMagenta: '#d6b3f7', brightCyan: '#5ee0d4', brightWhite: '#f3f6fa' },
|
||||||
|
};
|
||||||
|
function currentXtermTheme() {
|
||||||
|
const skin = (typeof document !== 'undefined' && document.documentElement.dataset.skin) || 'daylight-blue';
|
||||||
|
return CODEMAN_XTERM_THEMES[skin] || CODEMAN_XTERM_THEMES['daylight-blue'];
|
||||||
|
}
|
||||||
|
|
||||||
global.CodemanTerminalInput = {
|
global.CodemanTerminalInput = {
|
||||||
isTerminalQueryResponse,
|
isTerminalQueryResponse,
|
||||||
shouldSuppressTerminalQueryResponse,
|
shouldSuppressTerminalQueryResponse,
|
||||||
USER_SCROLL_STICKY_SUPPRESS_MS,
|
USER_SCROLL_STICKY_SUPPRESS_MS,
|
||||||
};
|
};
|
||||||
|
global.CODEMAN_XTERM_THEMES = CODEMAN_XTERM_THEMES;
|
||||||
|
global.codemanCurrentXtermTheme = currentXtermTheme;
|
||||||
})(window);
|
})(window);
|
||||||
|
|
||||||
Object.assign(CodemanApp.prototype, {
|
Object.assign(CodemanApp.prototype, {
|
||||||
@@ -47,29 +63,7 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
const scrollback = Number.isFinite(stored) && stored > 0 ? Math.max(stored, DEFAULT_SCROLLBACK) : DEFAULT_SCROLLBACK;
|
const scrollback = Number.isFinite(stored) && stored > 0 ? Math.max(stored, DEFAULT_SCROLLBACK) : DEFAULT_SCROLLBACK;
|
||||||
|
|
||||||
this.terminal = new Terminal({
|
this.terminal = new Terminal({
|
||||||
theme: {
|
theme: { ...window.codemanCurrentXtermTheme() },
|
||||||
background: '#0d0d0d',
|
|
||||||
foreground: '#e0e0e0',
|
|
||||||
cursor: '#e0e0e0',
|
|
||||||
cursorAccent: '#0d0d0d',
|
|
||||||
selection: 'rgba(255, 255, 255, 0.3)',
|
|
||||||
black: '#0d0d0d',
|
|
||||||
red: '#ff6b6b',
|
|
||||||
green: '#51cf66',
|
|
||||||
yellow: '#ffd43b',
|
|
||||||
blue: '#339af0',
|
|
||||||
magenta: '#cc5de8',
|
|
||||||
cyan: '#22b8cf',
|
|
||||||
white: '#e0e0e0',
|
|
||||||
brightBlack: '#495057',
|
|
||||||
brightRed: '#ff8787',
|
|
||||||
brightGreen: '#69db7c',
|
|
||||||
brightYellow: '#ffe066',
|
|
||||||
brightBlue: '#5c7cfa',
|
|
||||||
brightMagenta: '#da77f2',
|
|
||||||
brightCyan: '#66d9e8',
|
|
||||||
brightWhite: '#ffffff',
|
|
||||||
},
|
|
||||||
fontFamily: '"Fira Code", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, monospace',
|
fontFamily: '"Fira Code", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, monospace',
|
||||||
// Use smaller font on mobile to fit more columns (prevents wrapping of Claude's status line)
|
// Use smaller font on mobile to fit more columns (prevents wrapping of Claude's status line)
|
||||||
fontSize: MobileDetection.getDeviceType() === 'mobile' ? 10 : 14,
|
fontSize: MobileDetection.getDeviceType() === 'mobile' ? 10 : 14,
|
||||||
@@ -2182,4 +2176,27 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
document.getElementById('dirDisplay').textContent = value || 'No directory';
|
document.getElementById('dirDisplay').textContent = value || 'No directory';
|
||||||
}, 100);
|
}, 100);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Re-theme all live xterm terminals (main + teammate) to the given skin's palette.
|
||||||
|
// Uses the xterm v5+ live setter (full object assignment triggers a repaint for both
|
||||||
|
// DOM and WebGL renderers) plus a belt-and-suspenders refresh().
|
||||||
|
applyTerminalSkin(skin) {
|
||||||
|
const theme = { ...(window.CODEMAN_XTERM_THEMES[skin] || window.CODEMAN_XTERM_THEMES['daylight-blue']) };
|
||||||
|
if (this.terminal) {
|
||||||
|
this.terminal.options.theme = theme;
|
||||||
|
try {
|
||||||
|
this.terminal.refresh(0, this.terminal.rows - 1);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
if (this.teammateTerminals) {
|
||||||
|
for (const [, entry] of this.teammateTerminals) {
|
||||||
|
if (entry && entry.terminal) {
|
||||||
|
entry.terminal.options.theme = { ...theme };
|
||||||
|
try {
|
||||||
|
entry.terminal.refresh(0, entry.terminal.rows - 1);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user