ci: add GitHub Actions workflows with semantic-release auto-versioning

chore: fix all 702 clippy warnings across codebase
- auto-fix 475 via cargo clippy --fix
- fix remaining 227 manually: uninlined_format_args, redundant_closure, match_same_arms,
  underscore_binding, format_push_string, items_after_statements, needless_pass_by_value,
  clone_on_copy, case_sensitive_extension, single_match/let-else, write_with_newline,
  and other clippy lints
This commit is contained in:
asepharyana
2026-07-13 08:12:12 +07:00
parent be921d6836
commit 29a9fae3f6
79 changed files with 826 additions and 904 deletions
+27 -27
View File
@@ -83,7 +83,7 @@ pub type LiveStateFn = Arc<dyn Fn(String, String, AgentStatus) + Send + Sync>;
/// any findings from earlier sibling agents. Updates live state before and
/// after to reflect Running → Completed/Failed transitions.
///
/// Flow: push agent as `Running` → build SubagentContext with prompt +
/// Flow: push agent as `Running` → build `SubagentContext` with prompt +
/// findings preamble, linking the `workflow_findings` Arc so the subagent's
/// `note_finding` tool pushes into the same vec → call `run_subagent`
/// (draining the event channel into a consumer so events are not blocked)
@@ -98,11 +98,12 @@ pub type LiveStateFn = Arc<dyn Fn(String, String, AgentStatus) + Send + Sync>;
/// a stuck stage from blocking the entire pipeline forever.
///
/// Return: the agent's text output, or an error on failure.
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
fn spawn_single_agent(
agent_id: &str,
agent_name: &str,
prompt: &str,
findings_snapshot: Vec<String>,
findings_snapshot: &[String],
findings: &Arc<Mutex<Vec<String>>>,
live: Option<&LiveStateFn>,
session_dir: &std::path::Path,
@@ -134,7 +135,7 @@ fn spawn_single_agent(
let def = AgentDefinition::new(agent_name.to_string(), "coder".to_string())
.with_max_steps(50);
let mut ctx = build_subagent_context(def);
let mut ctx = build_subagent_context(&def);
ctx.session_dir = session_dir.to_path_buf();
ctx.workspaces = workspaces.to_vec();
@@ -152,7 +153,7 @@ fn spawn_single_agent(
)
};
ctx.system_prompt = format!("{}{}", prompt, findings_section);
ctx.system_prompt = format!("{prompt}{findings_section}");
// Link the shared findings Arc so note_finding calls within this
// subagent write into the same vec visible to sibling agents.
ctx.workflow_findings = Some(findings.clone());
@@ -174,8 +175,8 @@ fn spawn_single_agent(
let mut rx = rx;
while let Some(event) = rx.blocking_recv() {
match &event {
SubagentEvent::ToolCall { _tool, _args } => {
tracing::debug!("[subagent] tool call: {}", _tool);
SubagentEvent::ToolCall { tool, .. } => {
tracing::debug!("[subagent] tool call: {}", tool);
// Push intra-division progress: which tool is running
if let Some(ref f) = drain_live {
f(
@@ -186,13 +187,13 @@ fn spawn_single_agent(
started_at: Some(drain_started_at),
completed_at: None,
error: None,
progress: Some(format!("tool: {}", _tool)),
progress: Some(format!("tool: {tool}")),
},
);
}
}
SubagentEvent::ToolResult { _tool, .. } => {
tracing::debug!("[subagent] tool result: {}", _tool);
SubagentEvent::ToolResult { tool, .. } => {
tracing::debug!("[subagent] tool result: {}", tool);
if let Some(ref f) = drain_live {
f(
drain_agent_id.clone(),
@@ -202,16 +203,16 @@ fn spawn_single_agent(
started_at: Some(drain_started_at),
completed_at: None,
error: None,
progress: Some(format!("done: {}", _tool)),
progress: Some(format!("done: {tool}")),
},
);
}
}
SubagentEvent::StepCompleted { _step, .. } => {
tracing::trace!("[subagent] step {} completed", _step);
SubagentEvent::StepCompleted { .. } => {
tracing::trace!("[subagent] step completed");
}
SubagentEvent::StepFailed { _step, _error } => {
tracing::warn!("[subagent] step {} failed: {}", _step, _error);
SubagentEvent::StepFailed { step, error } => {
tracing::warn!("[subagent] step {} failed: {}", step, error);
}
SubagentEvent::Completed { .. } => {
tracing::debug!("[subagent] completed");
@@ -230,17 +231,16 @@ fn spawn_single_agent(
let timeout_ctx = ctx;
let timeout_tx = tx;
std::thread::spawn(move || {
let _ = done_tx.send(run_subagent(timeout_ctx, timeout_tx));
let _ = done_tx.send(run_subagent(&timeout_ctx, &timeout_tx));
});
match done_rx.recv_timeout(Duration::from_millis(timeout)) {
Ok(r) => r,
Err(_) => Err(anyhow::anyhow!(
"subagent '{}' timed out after {}ms",
agent_name, timeout,
"subagent '{agent_name}' timed out after {timeout}ms",
)),
}
} else {
run_subagent(ctx, tx)
run_subagent(&ctx, &tx)
};
let completed_at = chrono::Utc::now().timestamp_millis();
@@ -299,6 +299,7 @@ type ParallelResult = (usize, anyhow::Result<Vec<String>>);
///
/// Return: a `Vec<String>` of all agent outputs (or error strings) in
/// the order they were submitted.
#[allow(clippy::too_many_arguments)]
pub fn execute_primitive(
primitive: &ScriptPrimitive,
args: &HashMap<String, String>,
@@ -316,7 +317,7 @@ pub fn execute_primitive(
let findings_snapshot = findings.lock().map(|f| f.clone()).unwrap_or_default();
let agent_id = uuid::Uuid::new_v4().to_string();
let agent_name = resolved.chars().take(40).collect::<String>();
match spawn_single_agent(&agent_id, &agent_name, &resolved, findings_snapshot, findings, live, session_dir, workspaces, timeout_ms) {
match spawn_single_agent(&agent_id, &agent_name, &resolved, &findings_snapshot, findings, live, session_dir, workspaces, timeout_ms) {
Ok(text) => Ok(vec![text]),
Err(e) => {
if continue_on_error {
@@ -380,7 +381,7 @@ pub fn execute_primitive(
for (_, res) in locked.drain(..) {
match res {
Ok(outputs) => all.extend(outputs),
Err(e) => all.push(format!("agent error: {}", e)),
Err(e) => all.push(format!("agent error: {e}")),
}
}
Ok(all)
@@ -399,7 +400,7 @@ pub fn execute_primitive(
Ok(outputs) => all.extend(outputs),
Err(e) => {
if continue_on_error {
all.push(format!("pipeline stage {} error: {}", idx, e));
all.push(format!("pipeline stage {idx} error: {e}"));
} else {
return Err(e);
}
@@ -437,13 +438,13 @@ pub fn run_workflow(
///
/// Why: findings are scoped to an `Arc<Mutex<Vec<String>>>` rather than a
/// global static, so concurrent `run_workflow_tracked` calls from different
/// spawn_agents invocations remain fully isolated.
/// `spawn_agents` invocations remain fully isolated.
///
/// Return: a human-readable summary string.
pub fn run_workflow_tracked(
script: &WorkflowScript,
args: &HashMap<String, String>,
live: Option<LiveStateFn>,
live: Option<&LiveStateFn>,
session_dir: &std::path::Path,
workspaces: &[std::path::PathBuf],
) -> anyhow::Result<String> {
@@ -453,11 +454,10 @@ pub fn run_workflow_tracked(
10
};
let live_ref = live.as_ref();
let findings = Arc::new(Mutex::new(Vec::new()));
let results = execute_primitive(
&script.script, args, concurrency_cap,
script.options.continue_on_error, live_ref,
script.options.continue_on_error, live,
session_dir, workspaces, &findings,
script.options.timeout_ms,
)?;
@@ -489,7 +489,7 @@ pub fn run_workflow_tracked(
fn resolve_template(template: &str, args: &HashMap<String, String>) -> String {
let mut result = template.to_string();
for (key, value) in args {
result = result.replace(&format!("{{{{{}}}}}", key), value);
result = result.replace(&format!("{{{{{key}}}}}"), value);
}
result
}
@@ -535,7 +535,7 @@ struct SemaphoreGuard<'a> {
sem: &'a Semaphore,
}
impl<'a> Drop for SemaphoreGuard<'a> {
impl Drop for SemaphoreGuard<'_> {
fn drop(&mut self) {
let mut count = self.sem.count.lock().unwrap_or_else(|e| {
tracing::warn!("[semaphore] mutex poisoned in drop, recovering");