Align web UI to design system
This commit is contained in:
parent
677df4b4f2
commit
ce4927543a
|
|
@ -76,7 +76,7 @@ function TerminalTestPageContent() {
|
|||
</div>
|
||||
|
||||
{/* The Problem */}
|
||||
<section className="mb-8 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="mb-8 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
🐛 The Problem
|
||||
</h2>
|
||||
|
|
@ -97,7 +97,7 @@ function TerminalTestPageContent() {
|
|||
</section>
|
||||
|
||||
{/* Root Cause */}
|
||||
<section className="mb-8 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="mb-8 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
🔍 Root Cause Analysis
|
||||
</h2>
|
||||
|
|
@ -110,7 +110,7 @@ function TerminalTestPageContent() {
|
|||
<li>tmux uses OSC 52 escape sequences to synchronize clipboard with terminals</li>
|
||||
<li>
|
||||
Format:{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">\x1b]52;c;<base64>\x07</code>
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">\x1b]52;c;<base64>\x07</code>
|
||||
</li>
|
||||
<li>Terminal must support OSC 52 and have proper capabilities declared</li>
|
||||
</ul>
|
||||
|
|
@ -123,7 +123,7 @@ function TerminalTestPageContent() {
|
|||
<ul className="ml-6 list-disc space-y-1 text-[var(--color-text-secondary)]">
|
||||
<li>tmux queries terminal capabilities using Device Attributes (DA/XDA)</li>
|
||||
<li>
|
||||
XDA query: <code className="rounded bg-black px-1 py-0.5">CSI > q</code> (also
|
||||
XDA query: <code className="rounded-[2px] bg-black px-1 py-0.5">CSI > q</code> (also
|
||||
called XTVERSION)
|
||||
</li>
|
||||
<li>
|
||||
|
|
@ -138,14 +138,14 @@ function TerminalTestPageContent() {
|
|||
<h3 className="mb-2 font-semibold text-[var(--color-text-primary)]">
|
||||
3. The Missing Piece
|
||||
</h3>
|
||||
<div className="rounded-lg border border-[var(--color-accent-red)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<div className="rounded-[2px] border border-[var(--color-accent-red)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<p className="font-semibold text-[var(--color-accent-red)]">
|
||||
xterm.js does NOT implement XDA (Extended Device Attributes)
|
||||
</p>
|
||||
<ul className="ml-6 mt-2 list-disc space-y-1 text-[var(--color-text-secondary)]">
|
||||
<li>
|
||||
XDA is marked as TODO in xterm.js codebase:{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
test.skip('CSI > Ps q - Report xterm name and version (XTVERSION)')
|
||||
</code>
|
||||
</li>
|
||||
|
|
@ -164,7 +164,7 @@ function TerminalTestPageContent() {
|
|||
<ul className="ml-6 list-disc space-y-1 text-[var(--color-text-secondary)]">
|
||||
<li>
|
||||
iTerm2 sends proper XDA response identifying itself as{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">"iTerm2 "</code>
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">"iTerm2 "</code>
|
||||
</li>
|
||||
<li>tmux detects this and enables clipboard for the entire session</li>
|
||||
<li>
|
||||
|
|
@ -177,7 +177,7 @@ function TerminalTestPageContent() {
|
|||
</section>
|
||||
|
||||
{/* The Solution */}
|
||||
<section className="mb-8 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="mb-8 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
✅ The Solution
|
||||
</h2>
|
||||
|
|
@ -190,7 +190,7 @@ function TerminalTestPageContent() {
|
|||
Created custom terminal component that registers an XDA handler using xterm.js
|
||||
parser API:
|
||||
</p>
|
||||
<pre className="overflow-x-auto rounded-lg bg-black p-4 text-xs">
|
||||
<pre className="overflow-x-auto rounded-[2px] bg-black p-4 text-xs">
|
||||
<code className="text-[var(--color-accent-green)]">
|
||||
{`terminal.parser.registerCsiHandler(
|
||||
{ prefix: ">", final: "q" }, // CSI > q is XDA query
|
||||
|
|
@ -211,7 +211,7 @@ function TerminalTestPageContent() {
|
|||
<ol className="ml-6 list-decimal space-y-1 text-[var(--color-text-secondary)]">
|
||||
<li>Intercepts XDA queries from tmux</li>
|
||||
<li>
|
||||
Responds with <code className="rounded bg-black px-1 py-0.5">XTerm(370)</code>{" "}
|
||||
Responds with <code className="rounded-[2px] bg-black px-1 py-0.5">XTerm(370)</code>{" "}
|
||||
identification
|
||||
</li>
|
||||
<li>tmux detects "XTerm(" in response and enables TTYC_MS capability</li>
|
||||
|
|
@ -245,12 +245,12 @@ function TerminalTestPageContent() {
|
|||
</section>
|
||||
|
||||
{/* Node Version Requirement */}
|
||||
<section className="mb-8 rounded-lg border border-[var(--color-accent-orange)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="mb-8 rounded-[2px] border border-[var(--color-accent-orange)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
⚠️ Node Version Requirement
|
||||
</h2>
|
||||
<div className="space-y-3 text-sm">
|
||||
<div className="rounded-lg border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<div className="rounded-[2px] border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<p className="font-semibold text-[var(--color-accent-orange)]">
|
||||
CRITICAL: This implementation requires Node 20.x (currently 20.20.0)
|
||||
</p>
|
||||
|
|
@ -264,7 +264,7 @@ function TerminalTestPageContent() {
|
|||
</li>
|
||||
<li>
|
||||
Error on Node 25.6.1:{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">posix_spawnp failed</code>
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">posix_spawnp failed</code>
|
||||
</li>
|
||||
<li>
|
||||
Root cause: node-pty's native module (darwin-arm64 prebuild) fails to spawn
|
||||
|
|
@ -294,7 +294,7 @@ function TerminalTestPageContent() {
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg bg-[var(--color-bg-tertiary)] p-4">
|
||||
<div className="rounded-[2px] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<h3 className="mb-2 font-semibold text-[var(--color-text-primary)]">
|
||||
⚡ Testing Instructions for Upgrades
|
||||
</h3>
|
||||
|
|
@ -304,13 +304,13 @@ function TerminalTestPageContent() {
|
|||
<ol className="ml-6 list-decimal space-y-1 text-xs text-[var(--color-text-secondary)]">
|
||||
<li>
|
||||
Test node-pty directly:{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
node -e "const pty = require('node-pty'); pty.spawn('/bin/bash', [],
|
||||
{})"
|
||||
</code>
|
||||
</li>
|
||||
<li>
|
||||
If no <code className="rounded bg-black px-1 py-0.5">posix_spawnp failed</code>{" "}
|
||||
If no <code className="rounded-[2px] bg-black px-1 py-0.5">posix_spawnp failed</code>{" "}
|
||||
error, proceed
|
||||
</li>
|
||||
<li>Start dev servers and open this page</li>
|
||||
|
|
@ -327,7 +327,7 @@ function TerminalTestPageContent() {
|
|||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
onClick={() => setShowComparison(!showComparison)}
|
||||
className="rounded-lg bg-[var(--color-accent-blue)] px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-80"
|
||||
className="rounded-[2px] bg-[var(--color-accent-blue)] px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-80"
|
||||
>
|
||||
{showComparison ? "Hide" : "Show"} Side-by-Side Comparison
|
||||
</button>
|
||||
|
|
@ -336,10 +336,10 @@ function TerminalTestPageContent() {
|
|||
</span>
|
||||
</div>
|
||||
{oldSessionId === newSessionId && (
|
||||
<div className="mt-2 rounded border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-2 text-xs text-[var(--color-text-secondary)]">
|
||||
<div className="mt-2 rounded-[2px] border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-2 text-xs text-[var(--color-text-secondary)]">
|
||||
⚠️ Using same session for both terminals. To avoid port conflicts, use different
|
||||
sessions:
|
||||
<code className="ml-1 rounded bg-black px-1">
|
||||
<code className="ml-1 rounded-[2px] bg-black px-1">
|
||||
?old_session=ao-orchestrator&new_session=ao-20
|
||||
</code>
|
||||
</div>
|
||||
|
|
@ -351,9 +351,9 @@ function TerminalTestPageContent() {
|
|||
<section className="mb-8">
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
{/* Old Implementation */}
|
||||
<div className="rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="mb-3 flex items-center gap-2">
|
||||
<span className="rounded bg-[var(--color-accent-red)] px-2 py-1 text-xs font-semibold text-white">
|
||||
<span className="rounded-[2px] bg-[var(--color-accent-red)] px-2 py-1 text-xs font-semibold text-white">
|
||||
OLD
|
||||
</span>
|
||||
<h3 className="text-sm font-semibold text-[var(--color-text-primary)]">
|
||||
|
|
@ -370,9 +370,9 @@ function TerminalTestPageContent() {
|
|||
</div>
|
||||
|
||||
{/* New Implementation */}
|
||||
<div className="rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="mb-3 flex items-center gap-2">
|
||||
<span className="rounded bg-[var(--color-accent-green)] px-2 py-1 text-xs font-semibold text-white">
|
||||
<span className="rounded-[2px] bg-[var(--color-accent-green)] px-2 py-1 text-xs font-semibold text-white">
|
||||
NEW
|
||||
</span>
|
||||
<h3 className="text-sm font-semibold text-[var(--color-text-primary)]">
|
||||
|
|
@ -390,7 +390,7 @@ function TerminalTestPageContent() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 rounded-lg border border-[var(--color-accent-blue)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="mt-4 rounded-[2px] border border-[var(--color-accent-blue)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<h3 className="mb-2 text-sm font-semibold text-[var(--color-text-primary)]">
|
||||
🧪 How to Test Clipboard
|
||||
</h3>
|
||||
|
|
@ -409,13 +409,13 @@ function TerminalTestPageContent() {
|
|||
)}
|
||||
|
||||
{/* Debugging Journey */}
|
||||
<section className="rounded-lg border border-[var(--color-accent-purple)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="rounded-[2px] border border-[var(--color-accent)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
🔬 The Debugging Journey
|
||||
</h2>
|
||||
|
||||
<div className="space-y-4 text-sm text-[var(--color-text-secondary)]">
|
||||
<div className="rounded-lg bg-[var(--color-bg-tertiary)] p-4">
|
||||
<div className="rounded-[2px] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<p className="font-semibold text-[var(--color-accent-red)]">
|
||||
Total Time Wasted: 12+ hours across Feb 15-16, 2026
|
||||
</p>
|
||||
|
|
@ -446,7 +446,7 @@ function TerminalTestPageContent() {
|
|||
</li>
|
||||
<li>
|
||||
<strong>Tried force-enabling tmux clipboard</strong> - Used{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
set-option -s set-clipboard on
|
||||
</code>{" "}
|
||||
in tmux.conf. Didn't help - tmux needs the terminal to declare support.
|
||||
|
|
@ -462,11 +462,11 @@ function TerminalTestPageContent() {
|
|||
<p>
|
||||
<strong>What finally worked:</strong> Registering an XDA (Extended Device
|
||||
Attributes) handler in xterm.js using{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
terminal.parser.registerCsiHandler()
|
||||
</code>
|
||||
</p>
|
||||
<pre className="mt-2 overflow-x-auto rounded-lg bg-black p-3 text-xs">
|
||||
<pre className="mt-2 overflow-x-auto rounded-[2px] bg-black p-3 text-xs">
|
||||
<code className="text-[var(--color-accent-green)]">
|
||||
{`terminal.parser.registerCsiHandler(
|
||||
{ prefix: ">", final: "q" },
|
||||
|
|
@ -492,12 +492,12 @@ function TerminalTestPageContent() {
|
|||
<li>
|
||||
<strong>Deep-dive into tmux source code</strong> - Used DeepWiki.com to analyze
|
||||
tmux's terminal capability detection logic in{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">tty-keys.c</code> and{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">tty.c</code>
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">tty-keys.c</code> and{" "}
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">tty.c</code>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Discovered XDA queries</strong> - Found that tmux sends{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">CSI > q</code> (XTVERSION) to
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">CSI > q</code> (XTVERSION) to
|
||||
detect terminal type
|
||||
</li>
|
||||
<li>
|
||||
|
|
@ -508,7 +508,7 @@ function TerminalTestPageContent() {
|
|||
<li>
|
||||
<strong>Checked xterm.js implementation</strong> - Found that XDA is marked as
|
||||
TODO in xterm.js tests:{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
test.skip('CSI > Ps q - Report xterm name and version (XTVERSION)')
|
||||
</code>
|
||||
</li>
|
||||
|
|
@ -519,7 +519,7 @@ function TerminalTestPageContent() {
|
|||
</ol>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<div className="rounded-[2px] border border-[var(--color-accent-orange)] bg-[var(--color-bg-tertiary)] p-4">
|
||||
<h3 className="mb-2 font-semibold text-[var(--color-text-primary)]">
|
||||
⚡ How We Could Have Figured It Out Faster
|
||||
</h3>
|
||||
|
|
@ -531,7 +531,7 @@ function TerminalTestPageContent() {
|
|||
</li>
|
||||
<li>
|
||||
<strong>Monitor escape sequences</strong> - Running{" "}
|
||||
<code className="rounded bg-black px-1 py-0.5">tmux -vvv</code> or using a
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">tmux -vvv</code> or using a
|
||||
terminal protocol analyzer would have revealed the XDA queries being sent
|
||||
</li>
|
||||
<li>
|
||||
|
|
@ -560,7 +560,7 @@ function TerminalTestPageContent() {
|
|||
<li>xterm.js parser API documentation</li>
|
||||
<li>XTerm Control Sequences: XTVERSION / Device Attributes</li>
|
||||
<li>
|
||||
tmux <code className="rounded bg-black px-1 py-0.5">tty-keys.c</code>: Terminal
|
||||
tmux <code className="rounded-[2px] bg-black px-1 py-0.5">tty-keys.c</code>: Terminal
|
||||
type detection logic
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -569,25 +569,25 @@ function TerminalTestPageContent() {
|
|||
</section>
|
||||
|
||||
{/* Implementation Files */}
|
||||
<section className="mt-6 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<section className="mt-6 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-6">
|
||||
<h2 className="mb-4 text-xl font-bold text-[var(--color-text-primary)]">
|
||||
📁 Implementation Files
|
||||
</h2>
|
||||
<ul className="ml-6 list-disc space-y-1 text-sm text-[var(--color-text-secondary)]">
|
||||
<li>
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
packages/web/src/components/DirectTerminal.tsx
|
||||
</code>{" "}
|
||||
- Main component with XDA handler
|
||||
</li>
|
||||
<li>
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
packages/web/server/direct-terminal-ws.ts
|
||||
</code>{" "}
|
||||
- WebSocket server using node-pty
|
||||
</li>
|
||||
<li>
|
||||
<code className="rounded bg-black px-1 py-0.5">
|
||||
<code className="rounded-[2px] bg-black px-1 py-0.5">
|
||||
packages/web/src/app/dev/terminal-test/page.tsx
|
||||
</code>{" "}
|
||||
- This test page
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@
|
|||
|
||||
/* ── Light mode (default) ─────────────────────────────────────────── */
|
||||
:root {
|
||||
/* Base surfaces — Linear-standard light palette */
|
||||
--color-bg-base: #ffffff;
|
||||
/* Base surfaces — design-system light palette */
|
||||
--color-bg-base: #f5f5f7;
|
||||
--color-bg-surface: #ffffff;
|
||||
--color-bg-elevated: #ffffff;
|
||||
--color-bg-elevated-hover: #f7f7f8;
|
||||
--color-bg-subtle: #f2f2f2;
|
||||
--color-bg-subtle: #f0f0f2;
|
||||
|
||||
/* Backward-compat aliases */
|
||||
--color-bg-primary: var(--color-bg-base);
|
||||
|
|
@ -39,9 +39,9 @@
|
|||
--color-bg-tertiary: var(--color-bg-elevated);
|
||||
|
||||
/* Borders */
|
||||
--color-border-subtle: #e8e8ec;
|
||||
--color-border-subtle: #e7e7ec;
|
||||
--color-border-default: #d9d9de;
|
||||
--color-border-strong: #c1c1c6;
|
||||
--color-border-strong: #c9c9d2;
|
||||
|
||||
/* Backward-compat aliases */
|
||||
--color-border-muted: var(--color-border-subtle);
|
||||
|
|
@ -50,8 +50,8 @@
|
|||
/* Text */
|
||||
--color-text-primary: #1b1b1f;
|
||||
--color-text-secondary: #5e5e66;
|
||||
--color-text-tertiary: #8b8b93;
|
||||
--color-text-muted: #8b8b93;
|
||||
--color-text-tertiary: #8e8e96;
|
||||
--color-text-muted: #8e8e96;
|
||||
--color-text-inverse: #ffffff;
|
||||
|
||||
/* Interactive accent */
|
||||
|
|
@ -75,15 +75,15 @@
|
|||
--color-accent-yellow: #9a6700;
|
||||
--color-accent-orange: #bc4c00;
|
||||
--color-accent-red: #dc2626;
|
||||
--color-accent-violet: #8250df;
|
||||
--color-accent-purple: #8250df;
|
||||
--color-accent-violet: #5B7EF8;
|
||||
--color-accent-purple: #5B7EF8;
|
||||
|
||||
/* Theme-adaptive tints (bg tints behind status pills) */
|
||||
--color-tint-blue: rgba(91, 126, 248, 0.08);
|
||||
--color-tint-green: rgba(22, 163, 74, 0.08);
|
||||
--color-tint-yellow: rgba(154, 103, 0, 0.08);
|
||||
--color-tint-red: rgba(220, 38, 38, 0.08);
|
||||
--color-tint-violet: rgba(130, 80, 223, 0.08);
|
||||
--color-tint-violet: rgba(91, 126, 248, 0.08);
|
||||
--color-tint-orange: rgba(188, 76, 0, 0.08);
|
||||
--color-tint-neutral: rgba(0, 0, 0, 0.04);
|
||||
|
||||
|
|
@ -151,8 +151,8 @@
|
|||
--color-alert-ci-unknown: #9a6700;
|
||||
--color-alert-review: #1a7f37;
|
||||
--color-alert-review-bg: #1a7f37;
|
||||
--color-alert-changes: #8250df;
|
||||
--color-alert-changes-bg: #7c3aed;
|
||||
--color-alert-changes: #5B7EF8;
|
||||
--color-alert-changes-bg: #5B7EF8;
|
||||
--color-alert-conflict: #9a6700;
|
||||
--color-alert-conflict-bg: #92400e;
|
||||
--color-alert-comment: #bc4c00;
|
||||
|
|
@ -199,7 +199,7 @@
|
|||
--color-status-review: #06b6d4;
|
||||
--color-status-attention: #f1be64;
|
||||
--color-status-idle: #293142;
|
||||
--color-status-done: #202838;
|
||||
--color-status-done: #3a4252;
|
||||
--color-status-error: #ef4444;
|
||||
|
||||
/* Semantic aliases */
|
||||
|
|
@ -208,15 +208,15 @@
|
|||
--color-accent-yellow: #f1be64;
|
||||
--color-accent-orange: #ff9d57;
|
||||
--color-accent-red: #ef4444;
|
||||
--color-accent-violet: #b59cff;
|
||||
--color-accent-purple: #b59cff;
|
||||
--color-accent-violet: #5B7EF8;
|
||||
--color-accent-purple: #5B7EF8;
|
||||
|
||||
/* Theme-adaptive tints */
|
||||
--color-tint-blue: rgba(91, 126, 248, 0.12);
|
||||
--color-tint-green: rgba(34, 197, 94, 0.12);
|
||||
--color-tint-yellow: rgba(241, 190, 100, 0.12);
|
||||
--color-tint-red: rgba(239, 68, 68, 0.12);
|
||||
--color-tint-violet: rgba(181, 156, 255, 0.12);
|
||||
--color-tint-violet: rgba(91, 126, 248, 0.12);
|
||||
--color-tint-orange: rgba(255, 157, 87, 0.12);
|
||||
--color-tint-neutral: rgba(255, 255, 255, 0.05);
|
||||
|
||||
|
|
@ -233,7 +233,7 @@
|
|||
|
||||
/* Body */
|
||||
--color-body-gradient-blue: rgba(110, 143, 255, 0.2);
|
||||
--color-body-gradient-violet: rgba(91, 208, 177, 0.08);
|
||||
--color-body-gradient-violet: rgba(91, 126, 248, 0.08);
|
||||
|
||||
/* Nav glass */
|
||||
--color-nav-bg: rgba(10, 13, 18, 0.82);
|
||||
|
|
@ -288,8 +288,8 @@
|
|||
--color-alert-ci-unknown: #d4a72c;
|
||||
--color-alert-review: #4dab6e;
|
||||
--color-alert-review-bg: rgba(77, 171, 110, 0.25);
|
||||
--color-alert-changes: #9b8afb;
|
||||
--color-alert-changes-bg: rgba(155, 138, 251, 0.25);
|
||||
--color-alert-changes: #5B7EF8;
|
||||
--color-alert-changes-bg: rgba(91, 126, 248, 0.25);
|
||||
--color-alert-conflict: #d4a72c;
|
||||
--color-alert-conflict-bg: rgba(212, 167, 44, 0.25);
|
||||
--color-alert-comment: #c88a2e;
|
||||
|
|
@ -412,7 +412,7 @@ body {
|
|||
|
||||
/* Light mode: solid white, NO gradient */
|
||||
html:not(.dark) body {
|
||||
background: #ffffff;
|
||||
background: var(--color-bg-base);
|
||||
}
|
||||
|
||||
/* Radial gradient only for dark mode */
|
||||
|
|
@ -515,10 +515,12 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
@keyframes activity-pulse {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 var(--color-activity-pulse);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 0 4px var(--color-activity-pulse-end);
|
||||
transform: scale(1.16);
|
||||
opacity: 0.72;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -617,10 +619,6 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
border-color 0.12s ease;
|
||||
}
|
||||
|
||||
.orchestrator-btn:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.orchestrator-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
background: linear-gradient(
|
||||
|
|
@ -632,6 +630,11 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
box-shadow: var(--btn-shadow-hover);
|
||||
}
|
||||
|
||||
.orchestrator-btn:active,
|
||||
.orchestrator-btn:hover:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
/* ── Glass nav ────────────────────────────────────────────────────────── */
|
||||
|
||||
.nav-glass {
|
||||
|
|
@ -663,9 +666,9 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
position: relative;
|
||||
overflow: visible;
|
||||
border: 1px solid var(--color-border-default);
|
||||
border-radius: 0;
|
||||
border-radius: 2px;
|
||||
background: var(--color-bg-surface);
|
||||
box-shadow: 0 10px 24px rgba(2, 6, 12, 0.06);
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
.dashboard-hero__backdrop {
|
||||
|
|
@ -718,7 +721,6 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background: currentColor;
|
||||
box-shadow: 0 0 18px currentColor;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
|
|
@ -796,8 +798,8 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
}
|
||||
|
||||
.dashboard-alert {
|
||||
border-radius: 0;
|
||||
box-shadow: 0 16px 34px rgba(0, 0, 0, 0.08);
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--detail-card-shadow);
|
||||
}
|
||||
|
||||
/* ── Detail page cards — subtle depth, no hover lift ─────────────────── */
|
||||
|
|
@ -805,7 +807,7 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
.detail-card {
|
||||
background: var(--detail-card-bg);
|
||||
box-shadow: var(--detail-card-shadow);
|
||||
border-radius: 0;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.session-detail-page {
|
||||
|
|
@ -826,6 +828,7 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
padding: 14px 16px;
|
||||
background: var(--detail-card-bg);
|
||||
box-shadow: var(--detail-card-shadow);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
|
|
@ -893,7 +896,7 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
min-height: 28px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: 0;
|
||||
border-radius: 2px;
|
||||
background: color-mix(in srgb, var(--color-bg-elevated) 88%, transparent);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 11px;
|
||||
|
|
@ -948,6 +951,11 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 1px 0 color-mix(in srgb, white 16%, transparent);
|
||||
transition:
|
||||
transform 0.16s ease-out,
|
||||
opacity 0.16s ease-out,
|
||||
background 0.16s ease-out,
|
||||
border-color 0.16s ease-out;
|
||||
}
|
||||
|
||||
.session-detail-status-pill__dot {
|
||||
|
|
@ -992,40 +1000,34 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
|
||||
@keyframes session-status-active-breathe {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 16%, transparent),
|
||||
0 0 0 0 color-mix(in srgb, var(--color-status-working) 0%, transparent);
|
||||
transform: translateY(0);
|
||||
opacity: 0.96;
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 18%, transparent),
|
||||
0 0 0 3px color-mix(in srgb, var(--color-status-working) 10%, transparent);
|
||||
transform: translateY(-1px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes session-status-ready-breathe {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 16%, transparent),
|
||||
0 0 0 0 color-mix(in srgb, var(--color-status-ready) 0%, transparent);
|
||||
transform: translateY(0);
|
||||
opacity: 0.96;
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 20%, transparent),
|
||||
0 0 0 3px color-mix(in srgb, var(--color-status-ready) 12%, transparent);
|
||||
transform: translateY(-1px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes session-status-waiting-breathe {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 16%, transparent),
|
||||
0 0 0 0 color-mix(in srgb, var(--color-status-attention) 0%, transparent);
|
||||
transform: translateY(0);
|
||||
opacity: 0.95;
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in srgb, white 18%, transparent),
|
||||
0 0 0 3px color-mix(in srgb, var(--color-status-attention) 10%, transparent);
|
||||
transform: translateY(-1px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3129,7 +3131,7 @@ html.light .xterm .xterm-viewport:hover::-webkit-scrollbar-thumb:active {
|
|||
}
|
||||
|
||||
.toast--success .toast__icon {
|
||||
background: var(--color-status-ready);
|
||||
background: var(--color-status-working);
|
||||
}
|
||||
|
||||
.toast--error .toast__icon {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ function TestDirectPageContent() {
|
|||
<br />
|
||||
tmux should recognize it as XTerm and enable clipboard support (OSC 52).
|
||||
</p>
|
||||
<div className="mt-4 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="mt-4 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<h2 className="mb-2 text-sm font-semibold text-[var(--color-text-primary)]">
|
||||
Testing: <span className="text-[var(--color-accent-green)]">{sessionId}</span>
|
||||
</h2>
|
||||
|
|
@ -56,7 +56,7 @@ function TestDirectPageContent() {
|
|||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div className="mt-4 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<div className="mt-4 rounded-[2px] border border-[var(--color-border-default)] bg-[var(--color-bg-secondary)] p-4">
|
||||
<h2 className="mb-2 text-sm font-semibold text-[var(--color-text-primary)]">
|
||||
Technical Details:
|
||||
</h2>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import type { FitAddon as FitAddonType } from "@xterm/addon-fit";
|
|||
interface DirectTerminalProps {
|
||||
sessionId: string;
|
||||
startFullscreen?: boolean;
|
||||
/** Visual variant. "orchestrator" uses violet accent; "agent" (default) uses blue. */
|
||||
/** Visual variant. Orchestrator keeps the same design-system blue accent as the rest of the app. */
|
||||
variant?: "agent" | "orchestrator";
|
||||
/** CSS height for the terminal container in normal (non-fullscreen) mode.
|
||||
* Defaults to "max(440px, calc(100vh - 440px))". */
|
||||
|
|
@ -46,11 +46,7 @@ export function buildTerminalThemes(variant: TerminalVariant): { dark: ITheme; l
|
|||
selDark: "rgba(91, 126, 248, 0.30)",
|
||||
selLight: "rgba(91, 126, 248, 0.25)",
|
||||
};
|
||||
const orchAccent = {
|
||||
cursor: "#a371f7",
|
||||
selDark: "rgba(163, 113, 247, 0.25)",
|
||||
selLight: "rgba(130, 80, 223, 0.20)",
|
||||
};
|
||||
const orchAccent = agentAccent;
|
||||
const accent = variant === "orchestrator" ? orchAccent : agentAccent;
|
||||
|
||||
const dark: ITheme = {
|
||||
|
|
@ -66,7 +62,7 @@ export function buildTerminalThemes(variant: TerminalVariant): { dark: ITheme; l
|
|||
green: "#22c55e",
|
||||
yellow: "#f59e0b",
|
||||
blue: "#5b7ef8",
|
||||
magenta: "#a371f7",
|
||||
magenta: "#5b7ef8",
|
||||
cyan: "#22d3ee",
|
||||
white: "#d4d4d8",
|
||||
brightBlack: "#50506a",
|
||||
|
|
@ -74,7 +70,7 @@ export function buildTerminalThemes(variant: TerminalVariant): { dark: ITheme; l
|
|||
brightGreen: "#4ade80",
|
||||
brightYellow: "#fbbf24",
|
||||
brightBlue: "#7b9cfb",
|
||||
brightMagenta: "#c084fc",
|
||||
brightMagenta: "#7b9cfb",
|
||||
brightCyan: "#67e8f9",
|
||||
brightWhite: "#eeeef5",
|
||||
};
|
||||
|
|
@ -92,7 +88,7 @@ export function buildTerminalThemes(variant: TerminalVariant): { dark: ITheme; l
|
|||
green: "#1f7a3d",
|
||||
yellow: "#8a5a00",
|
||||
blue: "#175cd3",
|
||||
magenta: "#8e24aa",
|
||||
magenta: "#175cd3",
|
||||
cyan: "#0b7285",
|
||||
white: "#4b5563",
|
||||
brightBlack: "#374151",
|
||||
|
|
@ -100,7 +96,7 @@ export function buildTerminalThemes(variant: TerminalVariant): { dark: ITheme; l
|
|||
brightGreen: "#176639",
|
||||
brightYellow: "#6f4a00",
|
||||
brightBlue: "#1d4ed8",
|
||||
brightMagenta: "#7b1fa2",
|
||||
brightMagenta: "#1d4ed8",
|
||||
brightCyan: "#155e75",
|
||||
brightWhite: "#374151",
|
||||
};
|
||||
|
|
@ -609,8 +605,7 @@ export function DirectTerminal({
|
|||
};
|
||||
}, [fullscreen]);
|
||||
|
||||
const accentColor =
|
||||
variant === "orchestrator" ? "var(--color-accent-violet)" : "var(--color-accent)";
|
||||
const accentColor = "var(--color-accent)";
|
||||
|
||||
const statusDotClass =
|
||||
status === "connected"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function PRStatus({ pr }: PRStatusProps) {
|
|||
|
||||
{/* Merged badge */}
|
||||
{pr.state === "merged" && (
|
||||
<span className="inline-flex items-center rounded-full bg-[rgba(163,113,247,0.1)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-accent-violet)]">
|
||||
<span className="inline-flex items-center rounded-full bg-[var(--color-chip-bg)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-text-secondary)]">
|
||||
merged
|
||||
</span>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -538,7 +538,10 @@ function SessionDetailPRCard({ pr, sessionId }: { pr: DashboardPR; sessionId: st
|
|||
<span className="text-[var(--color-text-tertiary)]">·</span>
|
||||
<span
|
||||
className="px-2 py-0.5 text-[10px] font-semibold"
|
||||
style={{ color: "#a371f7", background: "rgba(163,113,247,0.12)" }}
|
||||
style={{
|
||||
color: "var(--color-text-secondary)",
|
||||
background: "var(--color-chip-bg)",
|
||||
}}
|
||||
>
|
||||
Merged
|
||||
</span>
|
||||
|
|
@ -631,7 +634,7 @@ function SessionDetailPRCard({ pr, sessionId }: { pr: DashboardPR; sessionId: st
|
|||
onClick={() => handleAskAgentToFix(c)}
|
||||
disabled={sendingComments.has(c.url)}
|
||||
className={cn(
|
||||
"mt-1.5 px-3 py-1 text-[11px] font-semibold transition-all",
|
||||
"mt-1.5 px-3 py-1 text-[11px] font-semibold transition-colors duration-150",
|
||||
sentComments.has(c.url)
|
||||
? "bg-[var(--color-status-ready)] text-white"
|
||||
: errorComments.has(c.url)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export function Terminal({ sessionId }: TerminalProps) {
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"overflow-hidden rounded-lg border border-[var(--color-border-default)] bg-black",
|
||||
"overflow-hidden rounded-[2px] border border-[var(--color-border-default)] bg-black",
|
||||
fullscreen && "fixed inset-0 z-50 rounded-none border-0",
|
||||
)}
|
||||
>
|
||||
|
|
@ -68,7 +68,7 @@ export function Terminal({ sessionId }: TerminalProps) {
|
|||
</span>
|
||||
<button
|
||||
onClick={() => setFullscreen(!fullscreen)}
|
||||
className="ml-auto rounded px-2 py-0.5 text-[11px] text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-bg-secondary)] hover:text-[var(--color-text-primary)]"
|
||||
className="ml-auto rounded-[2px] px-2 py-0.5 text-[11px] text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-bg-secondary)] hover:text-[var(--color-text-primary)]"
|
||||
>
|
||||
{fullscreen ? "exit fullscreen" : "fullscreen"}
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Reference in New Issue