Skip to content

Commit 96a4a0d

Browse files
committed
feat: add agent grid layout and UI polish
1 parent 674a2d5 commit 96a4a0d

14 files changed

Lines changed: 758 additions & 26 deletions

File tree

src/App.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { WalletPanel } from './panels/WalletPanel/WalletPanel'
1212
import { RecoveryPanel } from './panels/RecoveryPanel/RecoveryPanel'
1313
import { SettingsPanel } from './panels/SettingsPanel/SettingsPanel'
1414
import { ToolBrowser } from './panels/Tools/ToolBrowser'
15+
import { AgentGrid } from './panels/Terminal/AgentGrid'
1516
import { PluginManager } from './panels/PluginManager/PluginManager'
1617
import { PluginDashboard } from './panels/PluginDashboard/PluginDashboard'
1718
import { Titlebar } from './panels/Titlebar/Titlebar'
@@ -39,6 +40,7 @@ function App() {
3940
const setProjects = useUIStore((s) => s.setProjects)
4041
const activePluginId = usePluginStore((s) => s.activePluginId)
4142
const showOnboarding = useUIStore((s) => s.showOnboarding)
43+
const agentGridMode = useUIStore((s) => s.agentGridMode)
4244
const [showExplorer, setShowExplorer] = useState(true)
4345
const [showRightPanel, setShowRightPanel] = useState(true)
4446
const [showAgentLauncher, setShowAgentLauncher] = useState(false)
@@ -118,6 +120,9 @@ function App() {
118120
} else if ((e.ctrlKey || e.metaKey) && e.key === 'b') {
119121
e.preventDefault()
120122
setShowRightPanel((v) => !v)
123+
} else if ((e.ctrlKey || e.metaKey) && e.key === 'g') {
124+
e.preventDefault()
125+
useUIStore.getState().setAgentGridMode(!useUIStore.getState().agentGridMode)
121126
}
122127
}
123128
window.addEventListener('keydown', handleKeyDown)
@@ -154,7 +159,9 @@ function App() {
154159

155160
<div className="center-area">
156161
<div className="editor-area">
157-
{isCenterPanelPlugin && activePlugin ? (
162+
{agentGridMode ? (
163+
<AgentGrid />
164+
) : isCenterPanelPlugin && activePlugin ? (
158165
<PluginErrorBoundary>
159166
<Suspense fallback={<PluginFallback />}>
160167
<activePlugin.component />
@@ -164,10 +171,10 @@ function App() {
164171
<PluginDashboard />
165172
) : activePanel === 'env' ? <EnvManager /> : activePanel === 'git' ? <GitPanel /> : activePanel === 'recovery' ? <RecoveryPanel /> : activePanel === 'settings' ? <SettingsPanel /> : activePanel === 'tools' ? <ToolBrowser /> : <EditorPanel />}
166173
</div>
167-
<div className="splitter" {...splitterProps} />
168-
<div className="terminal-area" style={{ height: terminalHeight }}>
174+
{!agentGridMode && <div className="splitter" {...splitterProps} />}
175+
{!agentGridMode && <div className="terminal-area" style={{ height: terminalHeight }}>
169176
<TerminalPanel />
170-
</div>
177+
</div>}
171178
</div>
172179

173180
{shouldShowRightPanel && <aside className="right-panel">

src/panels/ClaudePanel/ClaudePanel.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@
208208
font-family: var(--font-code);
209209
}
210210

211+
.usage-value.usage-green {
212+
color: var(--green-dim);
213+
}
214+
215+
.usage-value.usage-red {
216+
color: var(--red-dim);
217+
}
218+
211219
.usage-period {
212220
font-size: 10px;
213221
color: var(--t3);

src/panels/ClaudePanel/ClaudePanel.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ export function ClaudePanel() {
3838
<div className="panel-header">Claude</div>
3939
<StatusBadge />
4040
<RestartButton />
41-
<CollapsibleSection title="Project MCP Servers" defaultOpen>
41+
<CollapsibleSection title="Last Session" defaultOpen>
42+
<UsageSection projectPath={activeProjectPath} />
43+
</CollapsibleSection>
44+
<CollapsibleSection title="Project MCP Servers" defaultOpen={false}>
4245
<McpSection
4346
loadFn={projectMcpLoadFn}
4447
toggleFn={projectMcpToggleFn}
@@ -56,9 +59,6 @@ export function ClaudePanel() {
5659
<CollapsibleSection title="Skills & Plugins" defaultOpen={false}>
5760
<SkillsSection />
5861
</CollapsibleSection>
59-
<CollapsibleSection title="Last Session" defaultOpen={false}>
60-
<UsageSection projectPath={activeProjectPath} />
61-
</CollapsibleSection>
6262
<ClaudeMdSection projectPath={activeProjectPath} />
6363
</div>
6464
)
@@ -217,19 +217,19 @@ function UsageSection({ projectPath }: { projectPath: string }) {
217217
<div className="usage-grid">
218218
<div className="usage-stat">
219219
<div className="usage-label">Input</div>
220-
<div className="usage-value">{formatTokens(totalInput)}</div>
220+
<div className="usage-value usage-green">{formatTokens(totalInput)}</div>
221221
</div>
222222
<div className="usage-stat">
223223
<div className="usage-label">Output</div>
224-
<div className="usage-value">{formatTokens(totalOutput)}</div>
224+
<div className="usage-value usage-green">{formatTokens(totalOutput)}</div>
225225
</div>
226226
<div className="usage-stat">
227227
<div className="usage-label">Cache</div>
228228
<div className="usage-value">{formatTokens(totalCache)}</div>
229229
</div>
230230
<div className="usage-stat">
231231
<div className="usage-label">Cost</div>
232-
<div className="usage-value">${usage.lastCost.toFixed(2)}</div>
232+
<div className="usage-value usage-red">${usage.lastCost.toFixed(2)}</div>
233233
</div>
234234
</div>
235235
{Object.entries(usage.models).map(([model, stats]) => (

src/panels/Editor/Editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ export function EditorPanel() {
473473
cursorBlinking: 'smooth',
474474
cursorSmoothCaretAnimation: 'on',
475475
bracketPairColorization: { enabled: true },
476-
wordWrap: 'off',
476+
wordWrap: 'on',
477477
tabSize: 2,
478478
glyphMargin: true,
479479
}}

src/panels/PluginDashboard/PluginDashboard.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@
5252
display: flex;
5353
flex-direction: column;
5454
gap: 12px;
55-
padding: 16px;
55+
padding: 20px 24px;
5656
background: var(--s1);
5757
border: 1px solid var(--border);
5858
border-radius: 8px;
5959
border-left: 3px solid transparent;
60-
min-height: 132px;
60+
min-height: 140px;
6161
cursor: default;
6262
transition: background 0.15s, border-color 0.15s;
6363
}
@@ -147,6 +147,8 @@
147147
align-items: center;
148148
justify-content: space-between;
149149
gap: 8px;
150+
margin-top: auto;
151+
min-height: 28px;
150152
}
151153

152154
.plugin-card-v2-btn {

src/panels/PluginManager/PluginManager.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212

1313
.plugin-card {
14-
padding: 10px 0;
14+
padding: 12px 8px;
1515
border-bottom: 1px solid var(--border);
1616
}
1717

@@ -50,9 +50,10 @@
5050
font-size: 10px;
5151
color: var(--t3);
5252
margin-top: 1px;
53-
white-space: nowrap;
53+
display: -webkit-box;
54+
-webkit-line-clamp: 2;
55+
-webkit-box-orient: vertical;
5456
overflow: hidden;
55-
text-overflow: ellipsis;
5657
}
5758

5859
.plugin-card-actions {

src/panels/StatusBar/StatusBar.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,17 @@
7676
}
7777

7878
.market-change.up {
79-
color: var(--success);
79+
color: var(--t3);
8080
}
8181

8282
.market-change.down {
83+
color: var(--t3);
84+
}
85+
86+
.market-change.up.significant {
87+
color: var(--success);
88+
}
89+
90+
.market-change.down.significant {
8391
color: var(--error);
8492
}

src/panels/StatusBar/StatusBar.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,19 @@ function MarketTape() {
9191

9292
return (
9393
<div className="market-tape">
94-
{items.map((item) => (
95-
<span key={item.symbol} className="market-tape-item">
96-
<span className="market-symbol">{item.symbol}</span>
97-
<span className="market-price">${formatCompactUsd(item.priceUsd)}</span>
98-
<span className={`market-change ${item.change24hPct >= 0 ? 'up' : 'down'}`}>
99-
{item.change24hPct >= 0 ? '+' : '-'}{Math.abs(item.change24hPct).toFixed(2)}%
94+
{items.map((item) => {
95+
const isSignificant = Math.abs(item.change24hPct) >= 5
96+
const direction = item.change24hPct >= 0 ? 'up' : 'down'
97+
return (
98+
<span key={item.symbol} className="market-tape-item">
99+
<span className="market-symbol">{item.symbol}</span>
100+
<span className="market-price">${formatCompactUsd(item.priceUsd)}</span>
101+
<span className={`market-change ${direction}${isSignificant ? ' significant' : ''}`}>
102+
{item.change24hPct >= 0 ? '+' : '-'}{Math.abs(item.change24hPct).toFixed(2)}%
103+
</span>
100104
</span>
101-
</span>
102-
))}
105+
)
106+
})}
103107
</div>
104108
)
105109
}

0 commit comments

Comments
 (0)