approvals: ship raw diff text instead of pre-rendered html; client classifies per-line
This commit is contained in:
parent
fb669c17c8
commit
d48cee7c2d
3 changed files with 29 additions and 37 deletions
|
|
@ -3,7 +3,6 @@
|
|||
//! repo, plus approve/deny buttons), and the manager.
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::fmt::Write as _;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -256,8 +255,13 @@ struct ApprovalView {
|
|||
kind: &'static str,
|
||||
/// First 12 chars of the `commit_ref`, for `ApplyCommit` only.
|
||||
sha_short: Option<String>,
|
||||
/// Pre-rendered syntax-coloured diff HTML, for `ApplyCommit` only.
|
||||
diff_html: Option<String>,
|
||||
/// Raw unified diff text, for `ApplyCommit` only. The client splits
|
||||
/// on `\n` and per-line classifies (`+` / `-` / `@@` / `--- ` / `+++ `
|
||||
/// → diff-add / diff-del / diff-hunk / diff-file). Shipping raw
|
||||
/// instead of pre-rendered HTML saves bytes on the wire (no
|
||||
/// per-line `<span>` markup) and removes the only HTML-escape
|
||||
/// surface from the snapshot.
|
||||
diff: Option<String>,
|
||||
/// Manager-supplied description shown on the approval card.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
description: Option<String>,
|
||||
|
|
@ -639,7 +643,7 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
|
|||
agent: a.agent.clone(),
|
||||
kind: "apply_commit",
|
||||
sha_short: Some(sha),
|
||||
diff_html: Some(render_diff_lines(&diff)),
|
||||
diff: Some(diff),
|
||||
description: a.description,
|
||||
}
|
||||
}
|
||||
|
|
@ -648,7 +652,7 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
|
|||
agent: a.agent,
|
||||
kind: "spawn",
|
||||
sha_short: None,
|
||||
diff_html: None,
|
||||
diff: None,
|
||||
description: a.description,
|
||||
},
|
||||
});
|
||||
|
|
@ -1345,29 +1349,6 @@ fn gc_orphans(coord: &Coordinator, approvals: Vec<Approval>) -> Vec<Approval> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Render a unified diff with per-line CSS classes so the dashboard can
|
||||
/// colour adds / dels / hunk headers / context. Each line becomes a
|
||||
/// `<span>` tagged by its leading character; the wrapping `<pre>` keeps
|
||||
/// whitespace intact.
|
||||
fn render_diff_lines(diff: &str) -> String {
|
||||
let mut out = String::new();
|
||||
for raw in diff.lines() {
|
||||
let cls = match raw.as_bytes().first() {
|
||||
// file headers (`--- a/...` / `+++ b/...`) come before any
|
||||
// line starting with a single `+`/`-`. similar-rs emits them
|
||||
// with the doubled prefix.
|
||||
_ if raw.starts_with("--- ") => "diff-file",
|
||||
_ if raw.starts_with("+++ ") => "diff-file",
|
||||
Some(b'@') => "diff-hunk",
|
||||
Some(b'+') => "diff-add",
|
||||
Some(b'-') => "diff-del",
|
||||
_ => "diff-ctx",
|
||||
};
|
||||
let _ = writeln!(out, "<span class=\"{cls}\">{}</span>", html_escape(raw),);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Host-side mirror of `hive_ag3nt::login::has_session`. Returns true if the
|
||||
/// agent's bound `~/.claude/` dir on disk contains any regular file. The
|
||||
/// dashboard reads this each render so logins driven from the agent web UI
|
||||
|
|
@ -1415,8 +1396,3 @@ async fn git_diff_main_to(applied_dir: &Path, target_ref: &str) -> Result<String
|
|||
Ok(String::from_utf8_lossy(&out.stdout).into_owned())
|
||||
}
|
||||
|
||||
fn html_escape(s: &str) -> String {
|
||||
s.replace('&', "&")
|
||||
.replace('<', "<")
|
||||
.replace('>', ">")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue