chore: import upstream snapshot with attribution
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:10:34 +08:00
commit a789495a98
1551 changed files with 718128 additions and 0 deletions
@@ -0,0 +1,395 @@
//! Interactive, animated demo of the inline swarm gallery.
//!
//! This runs as a real full-screen terminal app so you can *see* the inline
//! gallery the way it looks live in the jcode TUI, without touching any running
//! agents. It simulates a handful of mock swarm workers that stream output,
//! change status, and finish over time, rendering them through the exact same
//! `render_swarm_gallery` layout the real TUI uses.
//!
//! Run with:
//! cargo run --profile selfdev -p jcode-tui-render --example swarm_gallery_live
//!
//! Controls:
//! q / Esc quit
//! + / - more / fewer agents
//! [ / ] shrink / grow the gallery band (the max_pct knob)
//! space pause / resume the animation
use std::io::{self, Stdout};
use std::time::{Duration, Instant};
use ratatui::crossterm::{
event::{self, Event, KeyCode, KeyModifiers},
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
};
use ratatui::prelude::*;
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Wrap};
use jcode_tui_render::swarm_gallery::{GalleryMember, humanize_age, render_gallery};
/// A simulated worker, mirroring the fields the real adapter reads from a
/// `SwarmMemberStatus` (name, role, status, streamed output tail).
struct MockWorker {
name: String,
role: Option<&'static str>,
status: String,
/// Full streamed transcript so far; the tile shows the tail.
transcript: Vec<String>,
/// Scripted lines this worker will "stream" over time.
script: Vec<String>,
next_line: usize,
/// Ticks until the next line is appended.
cooldown: u16,
started: Instant,
}
impl MockWorker {
fn new(name: &str, role: Option<&'static str>, script: Vec<&str>) -> Self {
Self {
name: name.to_string(),
role,
status: "spawned".to_string(),
transcript: Vec::new(),
script: script.into_iter().map(|s| s.to_string()).collect(),
next_line: 0,
cooldown: 2,
started: Instant::now(),
}
}
fn tick(&mut self) {
if self.next_line >= self.script.len() {
if self.status != "completed" {
self.status = "completed".to_string();
}
return;
}
if self.cooldown > 0 {
self.cooldown -= 1;
// While waiting, alternate running/thinking to show the badge change.
if self.transcript.is_empty() {
self.status = "thinking".to_string();
}
return;
}
let line = self.script[self.next_line].clone();
self.status = if line.starts_with("! ") {
"blocked".to_string()
} else {
"running".to_string()
};
self.transcript
.push(line.trim_start_matches("! ").to_string());
self.next_line += 1;
self.cooldown = 2 + (self.next_line as u16 % 3);
}
fn age_secs(&self) -> u64 {
self.started.elapsed().as_secs()
}
}
fn workers_to_members(workers: &[MockWorker]) -> Vec<GalleryMember> {
workers
.iter()
.map(|w| {
let mut body: Vec<String> = w.transcript.clone();
body.push(format!("· {} ago", humanize_age(w.age_secs())));
GalleryMember {
label: w.name.clone(),
icon: None,
status: w.status.clone(),
task: None,
role: w.role.map(str::to_string),
body,
sort_key: w.name.clone(),
todo: None,
todo_items: Vec::new(),
model: None,
provider: None,
auth_method: None,
effort: None,
elapsed_secs: Some(w.age_secs()),
}
})
.collect()
}
fn make_workers(n: usize) -> Vec<MockWorker> {
let pool: Vec<(&str, Option<&'static str>, Vec<&str>)> = vec![
(
"researcher",
Some("coordinator"),
vec![
"Searching the codebase for the auth flow...",
"Found 12 candidate files.",
"Reading crates/jcode-app-core/src/auth.rs",
"The OAuth callback is handled in handle_login()",
"Now cross-referencing the token refresh path.",
"Refresh happens in refresh_session() (line 412).",
"Summarizing findings for the implementer.",
],
),
(
"implementer",
None,
vec![
"Editing crates/jcode-base/src/config.rs",
"Added swarm_spawn_mode = inline",
"Running cargo check...",
"warning: unused import `Foo`",
"Fixing the import.",
"cargo check clean.",
"Wiring the gallery into the draw path.",
],
),
(
"reviewer",
None,
vec![
"Waiting for the implementer to finish.",
"Reviewing the diff...",
"Reviewed 4 files.",
"! Blocked: needs a test for the new branch.",
"Test added, re-reviewing.",
"No blocking issues found.",
"LGTM",
],
),
(
"tester",
None,
vec![
"Building the selfdev profile...",
"Compiling jcode-tui-render",
"Running 5 tests",
"test cells_are_width_bounded ... ok",
"test many_agents_form_multiple_columns ... ok",
"All tests passed.",
],
),
(
"doc-writer",
None,
vec![
"Drafting the config docs.",
"Documenting swarm_gallery_max_pct.",
"Adding an example to default_file.rs.",
"Proofreading.",
"Docs ready.",
],
),
(
"packager",
None,
vec![
"Preparing the release worktree.",
"Bumping version.",
"Staging changes.",
"Commit drafted.",
],
),
(
"benchmarker",
None,
vec![
"Warming up the bench harness.",
"Running memory_recall_bench...",
"p50 latency 18ms",
"p99 latency 64ms",
"Results recorded.",
],
),
(
"linter",
None,
vec![
"Running clippy...",
"warning: needless clone (3)",
"Auto-fixing.",
"clippy clean.",
],
),
];
pool.into_iter()
.take(n.max(1))
.map(|(name, role, script)| MockWorker::new(name, role, script))
.collect()
}
fn render_gallery_lines(
workers: &[MockWorker],
width: usize,
max_height: usize,
) -> Vec<Line<'static>> {
// Delegate to the exact same shared renderer the live TUI uses; only the
// member data (built from mock workers) differs.
render_gallery(&workers_to_members(workers), width, max_height)
}
fn draw(f: &mut Frame, workers: &[MockWorker], max_pct: usize, paused: bool) {
let area = f.area();
// Reserve a top band like the real TUI does: a configurable share of the
// chat column height, capped, with a >=5 row floor before it shows.
let budget = ((area.height as usize * max_pct) / 100).clamp(0, 18);
let lines = if budget >= 5 && area.width >= 24 {
render_gallery_lines(workers, area.width as usize, budget)
} else {
Vec::new()
};
let band_h = if lines.is_empty() {
0u16
} else {
((lines.len() as u16) + 1).min(area.height / 2)
};
let band = Rect {
x: area.x,
y: area.y,
width: area.width,
height: band_h,
};
let chat = Rect {
x: area.x,
y: area.y + band_h,
width: area.width,
height: area.height.saturating_sub(band_h),
};
if band_h > 0 {
f.render_widget(Clear, band);
f.render_widget(Paragraph::new(lines), band);
}
// Mock chat / instructions below the band.
let help = vec![
Line::from(vec![Span::styled(
" inline swarm gallery — live demo (no real agents touched)",
Style::default()
.fg(Color::Rgb(200, 200, 210))
.add_modifier(Modifier::BOLD),
)]),
Line::from(""),
Line::from(vec![Span::styled(
" The band above is the same renderer the jcode TUI shows above your chat",
Style::default().fg(Color::Rgb(150, 150, 160)),
)]),
Line::from(vec![Span::styled(
" when you run a swarm with swarm_spawn_mode = \"inline\".",
Style::default().fg(Color::Rgb(150, 150, 160)),
)]),
Line::from(""),
Line::from(vec![
Span::styled(
" band size: ",
Style::default().fg(Color::Rgb(150, 150, 160)),
),
Span::styled(
format!("{max_pct}% "),
Style::default().fg(Color::Rgb(255, 200, 100)),
),
Span::styled(
"(agents.swarm_gallery_max_pct)",
Style::default().fg(Color::Rgb(110, 110, 120)),
),
Span::styled(
if paused { " [PAUSED]" } else { "" },
Style::default().fg(Color::Rgb(255, 170, 80)),
),
]),
Line::from(""),
Line::from(vec![Span::styled(
" keys: q/Esc quit +/- agents [ / ] band size space pause",
Style::default().fg(Color::Rgb(120, 120, 130)),
)]),
];
let block = Block::default()
.borders(Borders::TOP)
.border_style(Style::default().fg(Color::Rgb(70, 70, 80)))
.title(Span::styled(
" chat ",
Style::default().fg(Color::Rgb(120, 120, 130)),
));
f.render_widget(
Paragraph::new(help).block(block).wrap(Wrap { trim: false }),
chat,
);
}
fn main() -> io::Result<()> {
let mut stdout = io::stdout();
enable_raw_mode()?;
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let res = run(&mut terminal);
disable_raw_mode()?;
execute!(
terminal.backend_mut() as &mut CrosstermBackend<Stdout>,
LeaveAlternateScreen
)?;
terminal.show_cursor()?;
res
}
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> io::Result<()> {
let mut n_agents = 4usize;
let mut workers = make_workers(n_agents);
let mut max_pct = 40usize;
let mut paused = false;
let tick = Duration::from_millis(350);
let mut last_tick = Instant::now();
loop {
terminal.draw(|f| draw(f, &workers, max_pct, paused))?;
let timeout = tick.saturating_sub(last_tick.elapsed());
if event::poll(timeout)?
&& let Event::Key(key) = event::read()?
{
let ctrl_c =
key.modifiers.contains(KeyModifiers::CONTROL) && key.code == KeyCode::Char('c');
match key.code {
KeyCode::Char('q') | KeyCode::Esc => break,
_ if ctrl_c => break,
KeyCode::Char('+') | KeyCode::Char('=') => {
n_agents = (n_agents + 1).min(8);
workers = make_workers(n_agents);
}
KeyCode::Char('-') | KeyCode::Char('_') => {
n_agents = n_agents.saturating_sub(1).max(1);
workers = make_workers(n_agents);
}
KeyCode::Char(']') => max_pct = (max_pct + 5).min(90),
KeyCode::Char('[') => max_pct = max_pct.saturating_sub(5).max(5),
KeyCode::Char(' ') => paused = !paused,
KeyCode::Char('r') => {
workers = make_workers(n_agents);
}
_ => {}
}
}
if last_tick.elapsed() >= tick {
if !paused {
for w in workers.iter_mut() {
w.tick();
}
// When everything is done, loop the demo after a short beat.
if workers.iter().all(|w| w.status == "completed")
&& workers.iter().all(|w| w.age_secs() > 1)
{
// restart so the demo keeps streaming
workers = make_workers(n_agents);
}
}
last_tick = Instant::now();
}
}
Ok(())
}
@@ -0,0 +1,304 @@
//! Visual preview of the swarm gallery layout against mock streams.
//!
//! Run with: `cargo run --profile selfdev -p jcode-tui-render --example swarm_gallery_preview`
use jcode_tui_render::swarm_gallery::{
GalleryMember, SwarmStripHint, render_swarm_compact, render_swarm_dock, render_swarm_panel,
render_swarm_strip, render_swarm_strip_vertical,
};
use jcode_tui_render::swarm_tiles::{SwarmGalleryConfig, SwarmTile, render_swarm_gallery};
use ratatui::prelude::*;
fn accent(status: &str) -> Color {
match status {
"running" => Color::Rgb(255, 200, 100),
"thinking" => Color::Rgb(140, 180, 255),
"done" => Color::Rgb(100, 200, 100),
"blocked" => Color::Rgb(255, 170, 80),
"failed" => Color::Rgb(255, 100, 100),
_ => Color::Rgb(140, 140, 150),
}
}
fn mk(name: &str, role: Option<&str>, status: &str, body: &[&str]) -> SwarmTile {
let mut t = SwarmTile::new(name, status, accent(status))
.with_body(body.iter().map(|s| s.to_string()).collect());
if let Some(r) = role {
t = t.with_role_glyph(r);
}
t
}
fn print_lines(label: &str, lines: &[Line<'static>]) {
println!("\n=== {label} ===");
for line in lines {
let text: String = line.spans.iter().map(|s| s.content.as_ref()).collect();
println!("{text}");
}
}
fn main() {
let header = Line::from(Span::styled(
"🐝 swarm · 3 agents running",
Style::default().fg(Color::Rgb(255, 200, 100)),
));
let three = vec![
mk(
"researcher",
Some(""),
"thinking",
&[
"Searching the codebase for the auth flow...",
"Found 12 candidate files.",
"Reading crates/jcode-app-core/src/auth.rs",
"The OAuth callback is handled in handle_login()",
"Now cross-referencing the token refresh path.",
],
),
mk(
"implementer",
None,
"running",
&[
"Editing crates/jcode-base/src/config.rs",
"Added swarm_spawn_mode = inline",
"Running cargo check...",
"warning: unused import `Foo`",
"Fixing the import.",
],
),
mk(
"reviewer",
None,
"done",
&["Reviewed 4 files.", "No blocking issues found.", "LGTM ✓"],
),
];
let cfg = SwarmGalleryConfig::default();
print_lines(
"3 agents @ width 100",
&render_swarm_gallery(&three, 100, &cfg, Some(header.clone())),
);
print_lines(
"3 agents @ width 60",
&render_swarm_gallery(&three, 60, &cfg, Some(header.clone())),
);
let six: Vec<SwarmTile> = (0..6)
.map(|i| {
let status = ["running", "thinking", "done", "blocked"][i % 4];
mk(
&format!("agent-{i}"),
None,
status,
&[
&format!("step {i}.1 doing work"),
&format!("step {i}.2 still going"),
&format!("step {i}.3 almost there"),
],
)
})
.collect();
print_lines(
"6 agents @ width 120",
&render_swarm_gallery(&six, 120, &cfg, Some(header.clone())),
);
let many: Vec<SwarmTile> = (0..12)
.map(|i| {
mk(
&format!("worker-{i:02}"),
None,
"running",
&["...", "working"],
)
})
.collect();
let tight = SwarmGalleryConfig {
max_height: 12,
..Default::default()
};
print_lines(
"12 agents @ width 120, height 12",
&render_swarm_gallery(&many, 120, &tight, Some(header)),
);
// ---- New list+detail panel ----
let gm = |name: &str, role: Option<&str>, status: &str, body: &[&str]| GalleryMember {
label: name.to_string(),
icon: None,
status: status.to_string(),
task: None,
role: role.map(str::to_string),
body: body.iter().map(|s| s.to_string()).collect(),
sort_key: name.to_string(),
todo: None,
todo_items: Vec::new(),
model: None,
provider: None,
auth_method: None,
effort: None,
elapsed_secs: None,
};
let panel_members = vec![
gm(
"researcher",
Some("coordinator"),
"thinking",
&["Cross-referencing the token refresh path.", "· 2s ago"],
),
gm(
"implementer",
None,
"running",
&[
"Running cargo check...",
"warning: unused import `Foo`",
"· 5s ago",
],
),
gm("reviewer", None, "done", &["LGTM ✓", "· 1m ago"]),
gm(
"doc-writer",
None,
"blocked",
&["waiting on reviewer", "· 12s ago"],
),
];
print_lines(
"PANEL: 4 agents, selected #1 (implementer), focused @ width 70 h 14",
&render_swarm_panel(&panel_members, 1, true, 70, 14),
);
print_lines(
"PANEL: 4 agents, selected #0, unfocused @ width 70 h 14",
&render_swarm_panel(&panel_members, 0, false, 70, 14),
);
print_lines(
"PANEL: narrow @ width 44 h 12",
&render_swarm_panel(&panel_members, 2, true, 44, 12),
);
// ---- New compact strip (above status line) ----
let hints = vec![
SwarmStripHint {
key: "alt+↑/↓".into(),
label: "select".into(),
},
SwarmStripHint {
key: "alt+o".into(),
label: "open".into(),
},
SwarmStripHint {
key: "alt+shift+p".into(),
label: "prompt".into(),
},
SwarmStripHint {
key: "esc".into(),
label: "exit".into(),
},
];
print_lines(
"STRIP: unfocused @ width 90",
&render_swarm_strip(
&panel_members,
1,
false,
&hints,
Some("alt+n controls"),
0,
90,
12,
),
);
print_lines(
"STRIP: focused, selected #1 @ width 90",
&render_swarm_strip(&panel_members, 1, true, &hints, None, 3, 90, 12),
);
print_lines(
"STRIP: focused narrow @ width 54",
&render_swarm_strip(&panel_members, 0, true, &hints, None, 5, 54, 12),
);
// ---- Vertical strip (default layout: one agent per row) ----
let mut vert_members = panel_members.clone();
for (m, icon) in vert_members.iter_mut().zip(["🦊", "🐝", "🐅", "🦉"]) {
m.icon = Some(icon.to_string());
m.task = Some(match m.label.as_str() {
"researcher" => "wire the auth flow".to_string(),
"implementer" => "audit the webhook path".to_string(),
"reviewer" => "support/contact page".to_string(),
_ => "misc background task".to_string(),
});
}
vert_members[1].todo = Some((3, 9));
print_lines(
"VERTICAL: unfocused @ width 90",
&render_swarm_strip_vertical(
&vert_members,
1,
false,
&hints,
Some("alt+n controls"),
0,
90,
4,
12,
),
);
print_lines(
"VERTICAL: focused (accordion), selected #1 @ width 90",
&render_swarm_strip_vertical(&vert_members, 1, true, &hints, None, 3, 90, 4, 12),
);
print_lines(
"VERTICAL: 7 agents overflow @ width 80",
&render_swarm_strip_vertical(
&{
let mut many = Vec::new();
for i in 0..7 {
let mut m = gm(&format!("agent-{i}"), None, "running", &[]);
m.icon = Some("🐜".to_string());
many.push(m);
}
many
},
0,
false,
&hints,
Some("alt+n controls"),
0,
80,
4,
12,
),
);
// ---- Dock (vertical agent list for the info-widget margins) ----
print_lines(
"DOCK: 4 agents, selected #0, unfocused @ width 34 h 12",
&render_swarm_dock(&panel_members, 0, false, Some((3, 7)), 0, 34, 12),
);
print_lines(
"DOCK: 4 agents, selected #1, focused @ width 34 h 14",
&render_swarm_dock(&panel_members, 1, true, Some((3, 7)), 2, 34, 14),
);
print_lines(
"DOCK: narrow @ width 24 h 8",
&render_swarm_dock(&panel_members, 2, false, None, 0, 24, 8),
);
// ---- Compact summary (two lines: tally + plan bar) ----
print_lines(
"COMPACT: 4 agents, nodes 5/12 (3 running) @ width 34",
&render_swarm_compact(&panel_members, Some((5, 3, 12)), 34, 2),
);
print_lines(
"COMPACT: no plan @ width 34",
&render_swarm_compact(&panel_members, None, 34, 2),
);
print_lines(
"COMPACT: narrow @ width 20",
&render_swarm_compact(&panel_members, Some((5, 3, 12)), 20, 2),
);
}