Skip to content

Commit 0b83d22

Browse files
arul28claude
andauthored
ADE Code TUI: kill drawer flicker + marketing site refresh (#594)
* ADE Code TUI: kill drawer flicker + marketing site refresh ADE Code (TUI): - Kill drawer flicker: single-line lane cards so selecting a lane only adds a violet border (no row reflow); a shared ChatRow renders the expanded + compact chat lists identically; drop the CHATS header and timestamps; stableInkViewportRows reserves a row to avoid Ink-5 full-screen clears; terminal-preview frame dedup; visible-only PTY buffering with bounded flush. - Sync provider glyphs/colors 1:1 to the model picker; per-draft notice scoping (draft:N); simplified cross-terminal mouse baseline; modified-key word backspace; grid Tab escapes to side panes. Web: - PNG -> WebP image migration; HomePage editorial restructure into FeatureGrid / ShipShowcase; new OgImage /_og card; vercel cache headers for images/videos; brand + demo media assets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ci+review): commit README hero asset + address CodeRabbit feedback - assets/readme/hero.png: force-add the README hero image (gitignored as *.png, so validate-docs failed in CI on the missing target while passing locally). Matches the existing tracked-PNG pattern (og-image.png, logo.png). - vercel.json: drop `immutable` for /images + /videos (stable, non-fingerprinted filenames) in favor of `max-age=0, s-maxage=31536000, must-revalidate` so the CDN still caches a year but browsers pick up media updates. - FeatureGrid Lightbox: add modal focus containment + restoration (focus the close button on open, trap Tab inside the dialog, restore focus on close). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 6637b86 commit 0b83d22

221 files changed

Lines changed: 1806 additions & 964 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
11
<p align="center">
22
<a href="https://ade-app.dev">
3-
<img src="assets/logo.png" alt="ADE" width="260" />
3+
<img src="assets/logo.png" alt="ADE" width="240" />
44
</a>
55
</p>
66

77
<p align="center">
88
<strong>A single native workspace for every AI coding agent.</strong><br />
9-
<em>macOS, Windows, iOS, CLI — synced in real time.</em>
9+
<em>macOS, iOS, CLI — synced in real time.</em>
1010
</p>
1111

1212
<p align="center">
13-
<a href="https://ade-app.dev"><strong>Website</strong></a>
14-
&nbsp;·&nbsp;
15-
<a href="https://ade-app.dev/docs"><strong>Docs</strong></a>
16-
&nbsp;·&nbsp;
17-
<a href="https://github.com/arul28/ADE/releases/latest"><strong>Download</strong></a>
18-
&nbsp;·&nbsp;
19-
<a href="https://www.ade-app.dev/docs/changelog"><strong>Changelog</strong></a>
13+
<a href="https://github.com/arul28/ADE/releases/latest"><img src="https://img.shields.io/badge/Download_for_macOS-7C3AED?style=for-the-badge&logo=apple&logoColor=white" alt="Download for macOS" /></a>
14+
&nbsp;
15+
<a href="https://ade-app.dev"><img src="https://img.shields.io/badge/Website-12101a?style=for-the-badge&logo=googlechrome&logoColor=a78bfa" alt="Website" /></a>
16+
&nbsp;
17+
<a href="https://ade-app.dev/docs"><img src="https://img.shields.io/badge/Docs-12101a?style=for-the-badge&logo=readthedocs&logoColor=a78bfa" alt="Docs" /></a>
18+
&nbsp;
19+
<a href="https://github.com/arul28/ADE"><img src="https://img.shields.io/badge/GitHub-12101a?style=for-the-badge&logo=github&logoColor=a78bfa" alt="GitHub" /></a>
2020
</p>
2121

2222
<p align="center">
23-
<img src="https://img.shields.io/badge/100%25%20Free-7c3aed?style=flat-square&labelColor=1a1a24" alt="100% Free" />
24-
<img src="https://img.shields.io/badge/Open%20Source-a78bfa?style=flat-square&labelColor=1a1a24" alt="Open source" />
25-
<a href="LICENSE"><img src="https://img.shields.io/badge/AGPL--3.0-efe6d0?style=flat-square&labelColor=1a1a24" alt="AGPL-3.0 license" /></a>
26-
<a href="https://github.com/arul28/ADE/releases/latest"><img src="https://img.shields.io/github/v/release/arul28/ADE?label=latest&style=flat-square&labelColor=1a1a24&color=a78bfa" alt="Latest release" /></a>
27-
<a href="https://github.com/arul28/ADE/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/arul28/ADE/ci.yml?branch=main&label=CI&style=flat-square&labelColor=1a1a24" alt="CI status" /></a>
23+
<a href="https://github.com/arul28/ADE/releases/latest"><img src="https://img.shields.io/github/v/release/arul28/ADE?style=flat-square&label=release&labelColor=12101a&color=a78bfa" alt="Latest release" /></a>
24+
<a href="https://github.com/arul28/ADE/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/arul28/ADE/ci.yml?branch=main&style=flat-square&label=CI&labelColor=12101a&color=7c3aed" alt="CI" /></a>
25+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-7c3aed?style=flat-square&labelColor=12101a" alt="AGPL-3.0" /></a>
26+
<img src="https://img.shields.io/github/downloads/arul28/ADE/total?style=flat-square&label=downloads&labelColor=12101a&color=a78bfa" alt="Downloads" />
27+
<a href="https://github.com/arul28/ADE/stargazers"><img src="https://img.shields.io/github/stars/arul28/ADE?style=flat-square&labelColor=12101a&color=a78bfa" alt="Stars" /></a>
28+
<img src="https://img.shields.io/badge/macOS-13%2B-efe6d0?style=flat-square&labelColor=12101a" alt="macOS 13+" />
2829
</p>
2930

3031
<p align="center">
31-
<img src="assets/readme/hero-desktop.png" alt="ADE on macOS" width="720" />
32-
&nbsp;
33-
<img src="assets/readme/hero-iphone.png" alt="ADE on iOS" width="180" />
32+
<a href="https://ade-app.dev"><img src="assets/readme/hero.png" alt="ADE — every AI coding tool, one app that runs everywhere" width="900" /></a>
3433
</p>
3534

3635
ADE runs **Claude Code, Codex, Cursor, Factory Droid, OpenCode** — every major AI coding agent — inside one native workspace. Claude runs through the bundled Claude Agent SDK, while desktop and `ade code` share the same worktree-scoped chat runtime. Every task is its own git worktree, so agents ship features in parallel. Review and merge PRs in-app. Approve a diff from your phone while another agent tests on your Mac.
@@ -42,12 +41,12 @@ Free, open source, local-first. Bring your own keys or subs.
4241
<table>
4342
<tr>
4443
<td width="55%" valign="middle">
45-
<img src="apps/web/public/images/screenshots/lanes.png" alt="Parallel worktrees" />
44+
<img src="assets/readme/auto-worktrees.gif" alt="Auto-create a git worktree from a task" />
4645
</td>
4746
<td width="45%" valign="middle">
4847

4948
### Manage worktrees. In parallel.
50-
Every task gets its own git worktree. Branch, edit, test, and commit side by side no stashing, no rebasing, no context switch.
49+
Every task gets its own git worktree. Describe it and ADE spins up the branch — edit, test, and commit side by side, with no stashing, no rebasing, no context switch.
5150

5251
</td>
5352
</tr>
@@ -56,52 +55,70 @@ Every task gets its own git worktree. Branch, edit, test, and commit side by sid
5655
<td width="45%" valign="middle">
5756

5857
### Every coding agent. One workspace.
59-
Claude Code, Codex, Cursor, Factory Droid, OpenCode — pick whichever model fits the task. All run against the same worktree, with live diffs and approval gates.
58+
Claude Code, Codex, Cursor, Factory Droid, OpenCode — pick whichever model fits the task. All run against the same worktree, with live diffs and approval gates. Grid view tiles every run side by side.
6059

6160
</td>
6261
<td width="55%" valign="middle">
63-
<img src="apps/web/public/images/screenshots/run.png" alt="An agent executing live" />
62+
<img src="assets/readme/grid-view.gif" alt="Grid view — multiple agents running in parallel" />
6463
</td>
6564
</tr>
6665

6766
<tr>
6867
<td width="55%" valign="middle">
69-
<img src="apps/web/public/images/screenshots/prs.png" alt="Pull request review" />
68+
<img src="assets/readme/ade-code-tui.gif" alt="ADE Code — the terminal-native TUI" />
7069
</td>
7170
<td width="45%" valign="middle">
7271

72+
### The whole IDE. In your terminal.
73+
`ade code` is ADE, terminal-native — the same worktrees, chats, and PRs in a fast TUI. Start in the shell, finish on the desktop or your phone.
74+
75+
</td>
76+
</tr>
77+
78+
<tr>
79+
<td width="45%" valign="middle">
80+
7381
### Open, review, and merge PRs.
7482
Every PR your agents open lands in ADE — diff, CI, comments, merge button. No GitHub tab. Auto-merge when green.
7583

84+
</td>
85+
<td width="55%" valign="middle">
86+
<img src="assets/readme/pr-review.webp" alt="Pull request review inside ADE" />
7687
</td>
7788
</tr>
7889

7990
<tr>
91+
<td width="55%" valign="middle">
92+
<img src="assets/readme/cto.webp" alt="The CTO — a team of worker agents" />
93+
</td>
8094
<td width="45%" valign="middle">
8195

8296
### The conductor for your agents.
8397
An always-on CTO with context across every worktree. Pulls work from Linear, dispatches to the right worker, reports back when it's done.
8498

85-
</td>
86-
<td width="55%" valign="middle">
87-
<img src="apps/web/public/images/screenshots/cto.png" alt="The CTO agent" />
8899
</td>
89100
</tr>
90101

91102
<tr>
92-
<td width="55%" valign="middle" align="center">
93-
<img src="apps/web/public/images/screenshots/agent-chat.png" alt="ADE on iOS" width="240" />
94-
</td>
95103
<td width="45%" valign="middle">
96104

97105
### Everything above. On your phone.
98106
Every worktree, every agent, every PR — synced to iOS. Start a task on macOS, approve the diff from the train.
99107

108+
</td>
109+
<td width="55%" valign="middle" align="center">
110+
<img src="assets/readme/mobile-chat.webp" alt="ADE on iOS — agent chat" width="216" />
111+
&nbsp;
112+
<img src="assets/readme/mobile-pr.webp" alt="ADE on iOS — pull requests" width="216" />
100113
</td>
101114
</tr>
102115
</table>
103116

104-
Plus files, terminals, git history, workspace graph, multi-tasking, Linear sync, cron automations, computer-use proofs, and the `ade` CLI.
117+
<p align="center">
118+
<img src="assets/readme/worktree-graph.webp" alt="The worktree graph — dependencies, conflict risk, and rebase order" width="900" />
119+
</p>
120+
121+
Plus files, terminals, git history, the workspace graph, multi-tasking, Linear sync, cron automations, computer-use proofs, and the `ade` CLI.
105122

106123
## Install
107124

apps/ade-cli/src/tuiClient/__tests__/Drawer.test.tsx

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ afterEach(() => {
4242
});
4343

4444
describe("Drawer diff stats", () => {
45-
it("renders the selected lane's diff stats from line stats, not ahead/behind, and hides others", () => {
45+
it("renders every lane's diff stats inline (not just the selected one) and shows no timestamp", () => {
4646
vi.useFakeTimers();
4747
vi.setSystemTime(new Date("2026-05-12T12:00:00.000Z"));
4848

@@ -55,7 +55,7 @@ describe("Drawer diff stats", () => {
5555
"lane-2": { additions: 428, deletions: 112, files: 6 },
5656
};
5757

58-
const frameSelectFirst = stripAnsi(render(
58+
const frame = stripAnsi(render(
5959
<Drawer
6060
lanes={lanes}
6161
sessions={[]}
@@ -69,36 +69,17 @@ describe("Drawer diff stats", () => {
6969
/>,
7070
).lastFrame() ?? "");
7171

72-
// lane-1 is selected → its diff renders; lane-2 stays hidden.
73-
expect(frameSelectFirst).toContain("+64");
74-
expect(frameSelectFirst).toContain("−18");
75-
expect(frameSelectFirst).toContain("5m");
76-
expect(frameSelectFirst).not.toContain("+428");
77-
expect(frameSelectFirst).not.toContain("−112");
78-
expect(frameSelectFirst).not.toContain("+492");
79-
expect(frameSelectFirst).not.toContain("−130");
80-
expect(frameSelectFirst).not.toContain("+141 / −112");
81-
expect(frameSelectFirst).not.toContain("-18");
82-
83-
const frameSelectSecond = stripAnsi(render(
84-
<Drawer
85-
lanes={lanes}
86-
sessions={[]}
87-
activeLaneId="lane-2"
88-
activeSessionId={null}
89-
browsingLaneId="lane-2"
90-
selectedLaneIndex={1}
91-
selectedChatIndex={-1}
92-
panelHeight={30}
93-
diffByLaneId={diffByLaneId}
94-
/>,
95-
).lastFrame() ?? "");
96-
97-
// lane-2 selected → its diff shows; lane-1 stays hidden.
98-
expect(frameSelectSecond).toContain("+428");
99-
expect(frameSelectSecond).toContain("−112");
100-
expect(frameSelectSecond).not.toContain("+64");
101-
expect(frameSelectSecond).not.toContain("−18");
72+
// The diff is shown on every lane card, selected or not — it replaced the
73+
// green "run" chip and refreshes in place.
74+
expect(frame).toContain("+64");
75+
expect(frame).toContain("−18");
76+
expect(frame).toContain("+428");
77+
expect(frame).toContain("−112");
78+
// ahead/behind line stats are not surfaced, and the lane card no longer
79+
// carries a "Xm" age timestamp.
80+
expect(frame).not.toContain("+141 / −112");
81+
expect(frame).not.toContain("-18");
82+
expect(frame).not.toContain("5m");
10283
});
10384
});
10485

@@ -166,7 +147,11 @@ describe("Drawer lane and chat navigation layout", () => {
166147
expect(laneModeFrame).toContain("First chat");
167148
expect(laneModeFrame).toContain("enter chats");
168149
expect(laneModeFrame).not.toContain("││");
169-
expect(chatModeFrame).toContain("CHATS · 1");
150+
// The expanded chat list no longer carries a "CHATS · N" sub-header — a
151+
// selected lane looks like a collapsed one plus its violet border and the
152+
// trailing "+ new chat" row.
153+
expect(chatModeFrame).not.toContain("CHATS ·");
154+
expect(chatModeFrame).toContain("First chat");
170155
expect(chatModeFrame.indexOf("First chat")).toBeLessThan(chatModeFrame.indexOf("+ new chat"));
171156
expect(chatModeFrame).not.toContain("││");
172157
// Chats-mode footer now hints at how to escape the chat list since arrows
@@ -277,7 +262,6 @@ describe("Drawer lane and chat navigation layout", () => {
277262
).lastFrame() ?? "");
278263

279264
expect(frame).toContain("miss");
280-
expect(frame).toContain("CHATS · unavailable");
281265
expect(frame).toContain("worktree missing");
282266
expect(frame).toContain("lane unavailable");
283267
expect(frame).not.toContain("+ new chat");
@@ -380,6 +364,9 @@ describe("Drawer active chat indicator", () => {
380364
/>,
381365
).lastFrame() ?? "");
382366

383-
expect(frame).toMatch(/[] now/);
367+
// The active chat carries a live spinner (no "now"/age text — the panel
368+
// shows no timestamps).
369+
expect(frame).toMatch(/[]/);
370+
expect(frame).not.toContain("now");
384371
});
385372
});

0 commit comments

Comments
 (0)