T24c: Agent, changes
- FileChangeCard: a proposed change to one file, its path and counts, Reject and Accept in a slot that keeps presses off the header; opened, the diff through a headless git::DiffViewer with its folds opening - MultiFileDiffReview: every file at once, the total counts, how many are reviewed, Reject all and Accept all; verdicts as collab::Decision - git::DiffViewer gains headless, leaving the file's header to its owner - CommandExecutionCard is terminal::CommandBlock - gallery: three proposed files and a command's block
This commit is contained in:
1 parent
859a9051d8
commit
0a44a2d905
9 files changed
+591
-26
No files matched your search
@@ -0,0 +1,93 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use ely_gpui_component::{
|
||||
agent::{ChangeState, FileChange, MultiFileDiffReview},
|
||||
collab::Decision,
|
||||
terminal::{CommandBlock, CommandState},
|
||||
};
|
||||
use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, section, set},
|
||||
};
|
||||
|
||||
const LIFT_OLD: &str =
|
||||
"pub fn lift(color: Hsla, by: f32) -> Hsla {\n color.mix(white(), by)\n}\n";
|
||||
const LIFT_NEW: &str = "pub fn lift(color: Hsla, by: f32, dark: bool) -> Hsla {\n let by = if dark { by * 1.5 } else { by };\n color.mix(white(), by.min(1.0))\n}\n";
|
||||
const TOKENS_OLD: &str =
|
||||
"pub const ACCENT_LIFT: f32 = 0.12;\npub const SURFACE_LIFT: f32 = 0.04;\n";
|
||||
const TOKENS_NEW: &str =
|
||||
"pub const ACCENT_LIFT: f32 = 0.18;\npub const SURFACE_LIFT: f32 = 0.04;\n";
|
||||
const NOTE_NEW: &str = "## 0.9\n\nDark themes lift their accents further.\n";
|
||||
|
||||
fn changes() -> Vec<FileChange> {
|
||||
[
|
||||
("src/theme/lift.rs", LIFT_OLD, LIFT_NEW),
|
||||
("src/theme/tokens.rs", TOKENS_OLD, TOKENS_NEW),
|
||||
("CHANGELOG.md", "", NOTE_NEW),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(path, old, new)| FileChange {
|
||||
path: path.into(),
|
||||
old: old.into(),
|
||||
new: new.into(),
|
||||
state: ChangeState::Proposed,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// `changes` after `decision`.
|
||||
fn decided(mut changes: Vec<FileChange>, decision: Decision) -> Vec<FileChange> {
|
||||
let verdict = |accepted| {
|
||||
if accepted {
|
||||
ChangeState::Accepted
|
||||
} else {
|
||||
ChangeState::Rejected
|
||||
}
|
||||
};
|
||||
match decision {
|
||||
Decision::Accept(ix) => changes[ix].state = verdict(true),
|
||||
Decision::Reject(ix) => changes[ix].state = verdict(false),
|
||||
Decision::AcceptAll | Decision::RejectAll => {
|
||||
let state = verdict(decision == Decision::AcceptAll);
|
||||
for change in changes
|
||||
.iter_mut()
|
||||
.filter(|change| change.state == ChangeState::Proposed)
|
||||
{
|
||||
change.state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
changes
|
||||
}
|
||||
|
||||
pub fn changes_section(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let files = keep("agent-changes", changes, window, cx);
|
||||
let now = files.read(cx).clone();
|
||||
section(
|
||||
"FileChangeCard / MultiFileDiff Review / CommandExecutionCard",
|
||||
"What an agent would change, file by file: how much moves, the diff a press away, and a verdict each or for all. A command it ran is terminal::CommandBlock.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
probe(
|
||||
"agent-changes",
|
||||
div().w(px(640.)).child(
|
||||
MultiFileDiffReview::new("agent-review", now).on_decide(move |decision, _, cx| {
|
||||
let next = decided(files.read(cx).clone(), decision);
|
||||
set(&files, next, cx)
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div().w(px(640.)).child(CommandBlock::new(
|
||||
"agent-command",
|
||||
"~/ely",
|
||||
"cargo test --lib theme",
|
||||
"\u{1b}[32m Compiling\u{1b}[0m ely-gpui-component v0.9.0\n\u{1b}[32m Finished\u{1b}[0m test profile in 8.4s\nrunning 12 tests\ntest theme::lift_keeps_hue ... \u{1b}[32mok\u{1b}[0m\ntest theme::dark_lifts_further ... \u{1b}[32mok\u{1b}[0m\n\ntest result: \u{1b}[32mok\u{1b}[0m. 12 passed; 0 failed",
|
||||
CommandState::Done { code: 0, took: Duration::from_millis(9_200) },
|
||||
)),
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod changes;
|
||||
mod progress;
|
||||
mod tools;
|
||||
|
||||
@@ -10,7 +11,7 @@ pub const PAGE: Page = Page {
|
||||
number: 24,
|
||||
slug: "agent",
|
||||
title: "Agent",
|
||||
summary: "An assistant at work: the tools it calls, what it asks before it acts, and how far it has come.",
|
||||
summary: "An assistant at work: the tools it calls, what it asks before it acts, how far it has come and what it would change.",
|
||||
render,
|
||||
script: SCRIPT,
|
||||
};
|
||||
@@ -31,6 +32,13 @@ const SCRIPT: &[Step] = &[
|
||||
Step::Click("agent-advance"),
|
||||
Step::Wait(300),
|
||||
Step::Shot("plan"),
|
||||
Step::DownAt("agent-changes", 30.0, 51.0),
|
||||
Step::UpAt("agent-changes", 30.0, 51.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("changes"),
|
||||
Step::DownAt("agent-changes", 30.0, 51.0),
|
||||
Step::UpAt("agent-changes", 30.0, 51.0),
|
||||
Step::Wait(200),
|
||||
];
|
||||
|
||||
fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
@@ -39,5 +47,6 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
.child(tools::approval(window, cx))
|
||||
.child(progress::steps(window, cx))
|
||||
.child(progress::agents(window, cx))
|
||||
.child(changes::changes_section(window, cx))
|
||||
.into_any_element()
|
||||
}
|
||||
Reference in new issue
Block a user