fix cmd
This commit is contained in:
@@ -63,6 +63,8 @@ pub struct AgentConfig {
|
||||
pub host: Option<String>,
|
||||
#[serde(default)]
|
||||
pub protocol: Option<String>,
|
||||
#[serde(default)]
|
||||
pub depends_on: Vec<String>,
|
||||
}
|
||||
|
||||
fn default_cwd() -> String {
|
||||
@@ -128,7 +130,7 @@ fn load_file_full(path: &Path) -> LoadedConfig {
|
||||
}
|
||||
if let (Some(name), Some(task), Some(cwd)) = (multi.name, multi.task, multi.cwd) {
|
||||
return LoadedConfig {
|
||||
agents: vec![AgentConfig { name, task, cwd, host: None, protocol: None }],
|
||||
agents: vec![AgentConfig { name, task, cwd, host: None, protocol: None, depends_on: vec![] }],
|
||||
interval: multi.interval,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ pub fn run(config_or_task: &str, cwd_override: Option<&str>, name_override: Opti
|
||||
.map(|p| p.display().to_string())
|
||||
.unwrap_or_else(|_| ".".to_string()));
|
||||
let name = name_override.unwrap_or("task").to_string();
|
||||
(vec![config::AgentConfig { name, task: config_or_task.to_string(), cwd, host: None, protocol: None }], None)
|
||||
(vec![config::AgentConfig { name, task: config_or_task.to_string(), cwd, host: None, protocol: None, depends_on: vec![] }], None)
|
||||
};
|
||||
|
||||
if configs.is_empty() {
|
||||
@@ -355,28 +355,63 @@ fn strip_dir_listing(text: &str) -> &str {
|
||||
}
|
||||
|
||||
fn spawn_and_wait(configs: &[config::AgentConfig], running: &Arc<AtomicBool>) -> Vec<Agent> {
|
||||
let mut agents = Vec::new();
|
||||
let mut agents: Vec<Agent> = Vec::new();
|
||||
let mut pending: Vec<&config::AgentConfig> = Vec::new();
|
||||
let mut next_id = 1;
|
||||
|
||||
// Spawn agents without dependencies immediately, defer the rest
|
||||
for cfg in configs {
|
||||
let cwd = expand_tilde(&cfg.cwd);
|
||||
match Agent::spawn_with_config(next_id, &cfg.name, &cfg.task, &cwd, cfg.host.as_deref(), cfg.protocol.as_deref()) {
|
||||
Ok(agent) => {
|
||||
eprintln!(" started: {} ({})", cfg.name, cwd);
|
||||
agents.push(agent);
|
||||
next_id += 1;
|
||||
if cfg.depends_on.is_empty() {
|
||||
let cwd = expand_tilde(&cfg.cwd);
|
||||
match Agent::spawn_with_config(next_id, &cfg.name, &cfg.task, &cwd, cfg.host.as_deref(), cfg.protocol.as_deref()) {
|
||||
Ok(agent) => {
|
||||
eprintln!(" started: {} ({})", cfg.name, cwd);
|
||||
agents.push(agent);
|
||||
next_id += 1;
|
||||
}
|
||||
Err(e) => eprintln!(" failed: {}: {e}", cfg.name),
|
||||
}
|
||||
Err(e) => eprintln!(" failed: {}: {e}", cfg.name),
|
||||
} else {
|
||||
eprintln!(" waiting: {} (depends on: {})", cfg.name, cfg.depends_on.join(", "));
|
||||
pending.push(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
let mut last_status: Vec<String> = Vec::new();
|
||||
while running.load(Ordering::Relaxed) {
|
||||
// Poll running agents
|
||||
let mut any_running = false;
|
||||
for agent in &mut agents {
|
||||
agent.poll();
|
||||
if agent.is_running() { any_running = true; }
|
||||
}
|
||||
|
||||
// Check if any pending agents can now start
|
||||
let mut newly_started = Vec::new();
|
||||
pending.retain(|cfg| {
|
||||
let deps_met = cfg.depends_on.iter().all(|dep| {
|
||||
agents.iter().any(|a| &a.name == dep && !a.is_running())
|
||||
});
|
||||
if deps_met {
|
||||
let cwd = expand_tilde(&cfg.cwd);
|
||||
match Agent::spawn_with_config(next_id, &cfg.name, &cfg.task, &cwd, cfg.host.as_deref(), cfg.protocol.as_deref()) {
|
||||
Ok(agent) => {
|
||||
eprintln!(" started: {} ({})", cfg.name, cwd);
|
||||
newly_started.push(agent);
|
||||
}
|
||||
Err(e) => eprintln!(" failed: {}: {e}", cfg.name),
|
||||
}
|
||||
false // remove from pending
|
||||
} else {
|
||||
true // keep waiting
|
||||
}
|
||||
});
|
||||
for a in newly_started {
|
||||
next_id += 1;
|
||||
any_running = true;
|
||||
agents.push(a);
|
||||
}
|
||||
|
||||
if agents.iter().any(|a| a.dirty) {
|
||||
write_state(&agents);
|
||||
for a in &mut agents { a.dirty = false; }
|
||||
@@ -393,7 +428,7 @@ fn spawn_and_wait(configs: &[config::AgentConfig], running: &Arc<AtomicBool>) ->
|
||||
last_status = current;
|
||||
}
|
||||
|
||||
if !any_running { break; }
|
||||
if !any_running && pending.is_empty() { break; }
|
||||
std::thread::sleep(Duration::from_millis(200));
|
||||
}
|
||||
agents
|
||||
@@ -426,7 +461,7 @@ fn extract_agent_configs(text: &str) -> Vec<config::AgentConfig> {
|
||||
};
|
||||
|
||||
if name.is_empty() || task.is_empty() { return None; }
|
||||
Some(config::AgentConfig { name, task, cwd, host: None, protocol: None })
|
||||
Some(config::AgentConfig { name, task, cwd, host: None, protocol: None, depends_on: vec![] })
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -749,6 +784,7 @@ pub fn commit() {
|
||||
cwd,
|
||||
host: None,
|
||||
protocol: None,
|
||||
depends_on: vec![],
|
||||
}];
|
||||
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
|
||||
@@ -26,8 +26,7 @@ fn main() {
|
||||
println!("{}", env!("CARGO_PKG_VERSION"));
|
||||
}
|
||||
Some("help" | "--help" | "-h") => print_help(),
|
||||
None => print_help(),
|
||||
Some("tui") => {
|
||||
None | Some("tui") => {
|
||||
// Show logo before entering alternate screen
|
||||
eprintln!("\x1b[38;5;226m{}\x1b[0m\n\x1b[1m aishell\x1b[0m v{}\n",
|
||||
LOGO, env!("CARGO_PKG_VERSION"));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"ssh": "[protocol: ssh]\n[host: {host}]\nExecute commands via: ssh {host} \"command\"",
|
||||
"https": "[protocol: https]\n[endpoint: {host}]\nAccess via HTTP/HTTPS API calls.",
|
||||
"ssh": "[protocol: ssh]\n[host: {host}]\nThe host value is an SSH config name or user@host. Execute commands via: ssh {host} \"command\"\nDo not specify port or identity file — they are configured in ~/.ssh/config.\nIf the command fails, report the error. Do not retry with different connection parameters.",
|
||||
"https": "[protocol: https]\n[endpoint: {host}]\nAccess via HTTP/HTTPS API calls. Use curl or equivalent.",
|
||||
"at": "[protocol: at]\n[did: {host}]\nAccess via AT Protocol. Use ailog or atproto API.",
|
||||
"git": "[protocol: git]\n[remote: {host}]\nAccess via git commands."
|
||||
"git": "[protocol: git]\n[remote: {host}]\nAccess via git commands (clone, pull, push, log, etc)."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user