1use std::path::Path;
2
3use crate::cluster::{local, progress};
4use crate::engine::runner::git_ops;
5
6async fn git(dir: &Path, args: &[&str]) -> anyhow::Result<std::process::Output> {
7 Ok(tokio::process::Command::new("git")
8 .args(args)
9 .current_dir(dir)
10 .output()
11 .await?)
12}
13
14pub async fn run(done: &str, left: &str, state: &str) -> anyhow::Result<()> {
17 let cwd = std::env::current_dir()?;
18 let top = git(&cwd, &["rev-parse", "--show-toplevel"]).await?;
19 anyhow::ensure!(
20 top.status.success(),
21 "orch progress runs inside a task worktree"
22 );
23 let worktree = String::from_utf8_lossy(&top.stdout).trim().to_string();
24 let dir = Path::new(&worktree);
25
26 let task_id = std::env::var("TASK_ID").unwrap_or_default();
27 let agent = std::env::var("ORCH_AGENT").unwrap_or_else(|_| "agent".to_string());
28 let (cli_committed, cli_error) = match git_ops::auto_commit(
29 dir,
30 &task_id,
31 done,
32 &agent,
33 0,
34 crate::engine::runner::commit::When::Tested,
35 )
36 .await
37 {
38 Ok(committed) => (committed, None),
39 Err(e) => (false, Some(format!("{e:#}"))),
40 };
41
42 let report = progress::Report {
43 worktree,
44 done: done.to_string(),
45 left: left.to_string(),
46 state: state.to_string(),
47 cli_committed,
48 cli_error,
49 };
50 if !crate::cluster::enabled() {
51 eprintln!("committed locally. Recording progress needs a cluster section in the config");
52 return Ok(());
53 }
54
55 let Some(endpoint) = local::daemon_endpoint().await else {
56 eprintln!("orch service is not running: committed locally, nothing recorded or pushed");
57 return Ok(());
58 };
59 let record = local::send_progress(&endpoint, &report).await?;
60 println!(
61 "{} {} committed by {}, pushed by {}",
62 record.branch,
63 record.commit.chars().take(12).collect::<String>(),
64 record.committed_by,
65 record.pushed_by
66 );
67 if let Some(err) = record.error {
68 eprintln!("{err}");
69 }
70
71 Ok(())
72}