Skip to content

Commit 00cdf51

Browse files
Release 0.25.0 "Supreme": flagship UX upgrade
- WelcomeBanner: redesigned empty-state with 8 smart starter cards (Build, Fix a bug, Explain codebase, Write tests, Review changes, Plan refactor, Security audit, Optimize performance). One click fills composer + sets mode. - ModeTabs: replace cryptic mode dropdown with accessible icon-tablist; each tab shows a hover description of what that mode does. - Header declutter: consolidate "20-Min Flow" + "Open Weights" text pills into clean icon-only buttons — same function, much less visual noise. - Context bar: replace "Context X% · N tokens" text with compact 48 px visual fill-bar; turns danger-red above 80%; full detail available on hover. - Status bar: remove model name (already visible in composer picker); move git branch inline; cleaner and less technical. - Help overlay: categorised shortcuts (Task control / Navigation / Other) and a "What can I ask?" section with 6 example prompts. - CSS micro-polish: composer focus-ring glow; send-button scale animation; suggestion cards lift on hover; fade-up animation on welcome banner. - Font rendering: optimizeLegibility, font-feature-settings liga+kern, -moz-osx-font-smoothing grayscale. - Dark mode parity for all new components; mobile: starter-grid 2-col <540px, mode tab labels hidden (icons remain).
1 parent 5c22580 commit 00cdf51

13 files changed

Lines changed: 623 additions & 181 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
# Changelog
22

3+
## 0.25.0 — "Supreme"
4+
5+
- **Welcome Banner**: redesigned empty-state with 8 smart starter cards (Build a
6+
feature, Fix a bug, Explain this codebase, Write tests, Review my changes,
7+
Plan a refactor, Security audit, Optimize performance). Each card populates
8+
the composer and sets the correct mode in one click.
9+
- **Mode Tabs**: replaced the cryptic "Build/Plan/Review/Test" dropdown with
10+
accessible `role="tablist"` icon-tabs that show a hover description of exactly
11+
what each mode does.
12+
- **Header declutter**: consolidated the "20-Min Flow" and "Open Weights" text
13+
pills into clean icon-only buttons — less noise, same functionality.
14+
- **Context bar**: replaced the "Context X% · Ntokens" text in the status bar
15+
with a compact 48 px visual fill-bar that shows remaining context at a glance
16+
(turns danger-red above 80%). Full detail is available on hover.
17+
- **Status bar cleanup**: removed the model name from the status bar (visible in
18+
the composer model picker) and moved the git branch inline for less clutter.
19+
- **CSS micro-polish**: composer ring glow on focus; send-button subtle
20+
scale-up/down on hover/active; suggestion cards lift on hover; smooth
21+
`fade-up` animation on the welcome banner; improved font rendering.
22+
- **Dark mode parity**: all new components (WelcomeBanner, ModeTabs, starter
23+
cards, ctx-bar) have matching dark-mode tokens and no flash-of-wrong-colour.
24+
- **Mobile**: starter-grid collapses to 2-column below 540 px; mode tab labels
25+
are hidden on very small screens (icons remain).
26+
327
## 0.24.0
428

29+
530
- Vendor CLI agent backends: spawn the official Claude, Codex, or Grok CLI in a
631
trusted workspace. ShadowCode never reads, stores, or proxies vendor OAuth
732
tokens. Login remains `claude auth login`, `codex login`, and `grok login`.

‎Cargo.lock‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ default-members = ["native/core"]
44
resolver = "2"
55

66
[workspace.package]
7-
version = "0.24.0"
7+
version = "0.25.0"
88
edition = "2021"
99
rust-version = "1.95"
1010
license = "MIT"

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "shadow-agent"
7-
version = "0.24.0"
7+
version = "0.25.0"
88
description = "Linux-native, model-agnostic coding-agent harness (Claude Code / Codex alternative)"
99
readme = "README.md"
1010
requires-python = ">=3.12"

‎src-tauri/tauri.conf.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "ShadowCode",
4-
"version": "0.24.0",
4+
"version": "0.25.0",
55
"identifier": "com.shadowfetch.shadowcode",
66
"build": {
77
"beforeDevCommand": {

‎src/shadow_agent/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""ShadowCode — Linux-native autonomous coding-agent harness (brand: ShadowCode; binary: shadow; desktop id: shadow-agent)."""
22

3-
__version__ = "0.24.0"
3+
__version__ = "0.25.0"

‎ui/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "shadow-agent-ui",
3-
"version": "0.24.0",
3+
"version": "0.25.0",
44
"private": true,
55
"type": "module",
66
"scripts": {

‎ui/src/App.tsx‎

Lines changed: 48 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
import {
99
ArrowDown,
1010
ArrowUp,
11-
ArrowUpRight,
1211
Check,
1312
ChevronRight,
1413
Code2,
@@ -26,7 +25,6 @@ import {
2625
Sparkles,
2726
Square,
2827
TerminalSquare,
29-
TestTube2,
3028
X,
3129
Cpu,
3230
} from "lucide-react";
@@ -53,6 +51,8 @@ import { Markdown } from "./components/Markdown";
5351
import { Onboarding } from "./components/Onboarding";
5452
import { FlowGuide } from "./components/FlowGuide";
5553
import { OpenWeightHub } from "./components/OpenWeightHub";
54+
import { WelcomeBanner } from "./components/WelcomeBanner";
55+
import { ModeTabs } from "./components/ModeTabs";
5656
import {
5757
CustomModelDialog,
5858
Help,
@@ -1165,23 +1165,21 @@ export default function App() {
11651165
<div className="top-right">
11661166
<button
11671167
type="button"
1168-
className="top-action flow-guide-btn"
1169-
aria-label="20-Minute Fast-Track Guide"
1170-
title="20-Minute Fast-Track Guide"
1171-
onClick={() => setOverlay("flow-guide")}
1168+
className="icon-btn"
1169+
aria-label="Open-Weight Models & Vendor CLIs"
1170+
title="Models & AI providers"
1171+
onClick={() => setOverlay("open-weights")}
11721172
>
1173-
<Sparkles size={14} />
1174-
<span>20-Min Flow</span>
1173+
<Cpu size={17} />
11751174
</button>
11761175
<button
11771176
type="button"
1178-
className="top-action open-weights-btn"
1179-
aria-label="Open-Weight Models Showcase"
1180-
title="Open-Weight Models Showcase"
1181-
onClick={() => setOverlay("open-weights")}
1177+
className="icon-btn"
1178+
aria-label="20-Minute Fast-Track Guide"
1179+
title="Fast-track guide (new to ShadowCode?)"
1180+
onClick={() => setOverlay("flow-guide")}
11821181
>
1183-
<Cpu size={14} />
1184-
<span>Open Weights</span>
1182+
<Sparkles size={16} />
11851183
</button>
11861184
<button
11871185
type="button"
@@ -1391,131 +1389,15 @@ export default function App() {
13911389
Opening task…
13921390
</div>
13931391
) : empty && !conversation.history.viewing ? (
1394-
<div className="welcome">
1395-
<div className="welcome-symbol">
1396-
<img src="/icon.svg" alt="" />
1397-
</div>
1398-
<div className="eyebrow">
1399-
PILLAR FOR OPEN SOURCE & OPEN WEIGHTS · LINUX NATIVE
1400-
</div>
1401-
<h1>What are we building today?</h1>
1402-
<p>
1403-
A focused, autonomous workspace powered by local open-weight
1404-
models.
1405-
</p>
1406-
1407-
<div className="welcome-meta-bar">
1408-
<button
1409-
type="button"
1410-
className="workspace-badge"
1411-
title={workspace}
1412-
onClick={() => setOverlay("project")}
1413-
>
1414-
<FolderOpen size={14} />
1415-
<span>
1416-
{workspace.split("/").pop() || "Choose a project"}
1417-
</span>
1418-
<ChevronRight size={13} />
1419-
</button>
1420-
1421-
<button
1422-
type="button"
1423-
className="model-hero-badge"
1424-
title="Configure open-weight models"
1425-
onClick={() => setOverlay("open-weights")}
1426-
>
1427-
<Cpu size={14} />
1428-
<span>{model || "Choose Open-Weight Model"}</span>
1429-
<span className="badge-tag">
1430-
{isVendorProvider(
1431-
selectedModel?.provider ||
1432-
String(status?.model?.provider || ""),
1433-
)
1434-
? VENDOR_GROUP
1435-
: LOCAL_GROUP}
1436-
</span>
1437-
</button>
1438-
1439-
<button
1440-
type="button"
1441-
className="guide-hero-badge"
1442-
onClick={() => setOverlay("flow-guide")}
1443-
>
1444-
<Sparkles size={14} />
1445-
<span>20-Min Fast-Track Flow</span>
1446-
</button>
1447-
</div>
1448-
1449-
<div className="suggestions grid-3">
1450-
{[
1451-
{
1452-
icon: Code2,
1453-
title: "Build a feature",
1454-
body: "Turn an idea into working code with verification",
1455-
prompt: "Help me build ",
1456-
mode: "coder",
1457-
},
1458-
{
1459-
icon: ListChecks,
1460-
title: "Plan milestones",
1461-
body: "Non-destructive plan & architectural blueprint",
1462-
prompt:
1463-
"Create a detailed implementation plan and milestone roadmap for ",
1464-
mode: "planner",
1465-
},
1466-
{
1467-
icon: GitPullRequest,
1468-
title: "Find & fix bugs",
1469-
body: "Scan for edge cases and reliability issues",
1470-
prompt:
1471-
"Review this project for bugs and reliability issues. Explain your findings before changing files.",
1472-
mode: "reviewer",
1473-
},
1474-
{
1475-
icon: Sparkles,
1476-
title: "Codebase tour",
1477-
body: "Understand the architecture and entry points",
1478-
prompt:
1479-
"Explore this workspace and explain its architecture, key entry points, and how to run it in 3 bullet points.",
1480-
mode: "reviewer",
1481-
},
1482-
{
1483-
icon: TestTube2,
1484-
title: "Generate tests",
1485-
body: "Author unit tests and verify coverage",
1486-
prompt:
1487-
"Write automated tests for the core modules and verify they pass.",
1488-
mode: "tester",
1489-
},
1490-
{
1491-
icon: ShieldCheck,
1492-
title: "Security audit",
1493-
body: "Audit for vulnerabilities and exposed secrets",
1494-
prompt:
1495-
"Audit this workspace for security risks, unvalidated inputs, and exposed secrets.",
1496-
mode: "reviewer",
1497-
},
1498-
].map((s) => (
1499-
<button
1500-
type="button"
1501-
className="suggestion"
1502-
key={s.title}
1503-
onClick={() => {
1504-
setTask(s.prompt);
1505-
setMode(s.mode);
1506-
promptRef.current?.focus();
1507-
}}
1508-
>
1509-
<s.icon size={18} />
1510-
<strong>
1511-
{s.title}
1512-
<ArrowUpRight size={13} />
1513-
</strong>
1514-
<span>{s.body}</span>
1515-
</button>
1516-
))}
1517-
</div>
1518-
</div>
1392+
<WelcomeBanner
1393+
workspace={workspace}
1394+
model={model || status?.model.name || ""}
1395+
onSelect={(prompt, selectedMode) => {
1396+
setTask(prompt);
1397+
setMode(selectedMode);
1398+
promptRef.current?.focus();
1399+
}}
1400+
/>
15191401
) : (
15201402
<>
15211403
{transcript.items.map((item, i) =>
@@ -1863,17 +1745,11 @@ export default function App() {
18631745
}
18641746
/>
18651747
<span className="control-divider" />
1866-
<select
1867-
className="mode-select"
1868-
aria-label="Agent mode"
1748+
<ModeTabs
18691749
value={mode}
1870-
onChange={(e) => setMode(e.target.value)}
1871-
>
1872-
<option value="coder">Build</option>
1873-
<option value="planner">Plan</option>
1874-
<option value="reviewer">Review</option>
1875-
<option value="tester">Test</option>
1876-
</select>
1750+
onChange={setMode}
1751+
disabled={busy && !isNative()}
1752+
/>
18771753
<span className="grow" />
18781754
<span className="composer-hint">
18791755
{commandWaiting
@@ -1935,7 +1811,7 @@ export default function App() {
19351811
</div>
19361812
<footer className="statusline" aria-live="polite">
19371813
<span className={`status-dot ${busy ? "active" : ""}`} />
1938-
<span>
1814+
<span className="status-label">
19391815
{busy
19401816
? job?.status === "paused"
19411817
? "Paused"
@@ -1944,23 +1820,30 @@ export default function App() {
19441820
? "Reconnecting"
19451821
: "Ready"}
19461822
</span>
1947-
<span className="sep">/</span>
1948-
<span title={model}>{model}</span>
1949-
<span className="grow" />
1950-
<span title="Input tokens as a percentage of this task's model context limit">
1951-
Context {ctx}%
1952-
</span>
1953-
<span className="sep">·</span>
1954-
<span>{formatTokens(transcript.usage.total_tokens || 0)} tokens</span>
19551823
{git.branch && (
1956-
<button
1957-
type="button"
1958-
title="Review git changes"
1959-
onClick={() => setPanel("changes")}
1824+
<>
1825+
<span className="sep">·</span>
1826+
<button
1827+
type="button"
1828+
title="Review git changes"
1829+
onClick={() => setPanel("changes")}
1830+
>
1831+
<GitBranch size={12} />
1832+
{git.branch}
1833+
</button>
1834+
</>
1835+
)}
1836+
<span className="grow" />
1837+
{ctx > 0 && (
1838+
<span
1839+
className={`ctx-bar${ctx >= 80 ? " ctx-warn" : ""}`}
1840+
title={`${ctx}% of context used · ${formatTokens(transcript.usage.total_tokens || 0)} tokens`}
19601841
>
1961-
<GitBranch size={12} />
1962-
{git.branch}
1963-
</button>
1842+
<span
1843+
className="ctx-fill"
1844+
style={{ width: `${Math.min(ctx, 100)}%` }}
1845+
/>
1846+
</span>
19641847
)}
19651848
<span className="version">
19661849
{health?.version ? `v${health.version}` : "Connecting"}

0 commit comments

Comments
 (0)