Skip to content

feat(cli): fix and enhance --dry-run flag for apply command#182

Open
geoffjay wants to merge 3 commits intomainfrom
issue-133
Open

feat(cli): fix and enhance --dry-run flag for apply command#182
geoffjay wants to merge 3 commits intomainfrom
issue-133

Conversation

@geoffjay
Copy link
Owner

@geoffjay geoffjay commented Mar 5, 2026

Summary

Fixes a bug where --dry-run on the apply command still made HTTP calls to the orchestrator when processing a single workflow file, and enhances the dry-run output to show full resolved configurations.

Changes

Bug fix

  • apply_workflow_file: moved the find_agent_by_name HTTP call to after the dry-run early-return. Previously running agent apply --dry-run .agentd/workflows/issue-worker.yml still contacted the orchestrator.

Enhanced output

  • apply_agent_file dry-run: shows resolved working_dir, shell, worktree, model, and env keys
  • apply_workflow_file dry-run: shows source details — no HTTP calls
  • apply_directory dry-run (JSON): emits full resolved config objects

New tests (8)

Each test uses http://127.0.0.1:1 — any HTTP call would immediately fail.

Closes #133

Closes #133

## What changed

### Bug fix
- `apply_workflow_file`: moved `find_agent_by_name` (HTTP) call to after the
  dry-run early-return so that `--dry-run` never contacts the orchestrator for
  workflow files.  Previously, passing `--dry-run` on a single workflow YAML
  file still made an HTTP request to resolve the agent UUID.

### Enhanced output
- `apply_agent_file` dry-run: shows resolved `working_dir`, `shell`,
  `worktree`, `model`, and `env` keys instead of just the agent name.
- `apply_workflow_file` dry-run: shows `agent`, `source`, `poll_interval`, and
  `enabled` without any HTTP calls; uses the agent name symbolically.
- `apply_directory` dry-run (JSON): emits full resolved config objects for
  every agent and workflow, not just the names.
- `apply_directory` dry-run (text): updated summary line to note "no changes
  made".

### New tests (8 total)
- `test_dry_run_agent_file_makes_no_http_calls`
- `test_dry_run_agent_file_json_output`
- `test_dry_run_workflow_file_makes_no_http_calls`
- `test_dry_run_workflow_file_json_no_http_calls`
- `test_dry_run_directory_makes_no_http_calls`
- `test_dry_run_directory_json_contains_full_configs`
- `test_dry_run_invalid_template_reports_error`
- `test_dry_run_workflow_missing_prompt_fails_validation`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 89.38053% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 26.34%. Comparing base (89cef92) to head (3f49566).

Files with missing lines Patch % Lines
crates/cli/src/commands/apply.rs 89.38% 12 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #182      +/-   ##
==========================================
+ Coverage   23.03%   26.34%   +3.31%     
==========================================
  Files          50       50              
  Lines        4620     4722     +102     
==========================================
+ Hits         1064     1244     +180     
+ Misses       3556     3478      -78     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@geoffjay geoffjay added the review-agent Used to invoke a review by an agent tracking this label label Mar 9, 2026
Copy link
Owner Author

@geoffjay geoffjay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Changes Needed 🔴

The bug fix and enhanced output direction are both correct and the test strategy (using http://127.0.0.1:1 to prove no HTTP calls are made) is clever. However there is one compile error that must be fixed before this can merge, plus a few non-blocking suggestions.


🔴 Blocking: non-exhaustive match on SourceTemplate (compile error)

SourceTemplate has two variants — GithubIssues and GithubPullRequests — but the three new dry-run match arms only cover GithubIssues. Rust will reject this at compile time with:

error[E0004]: non-exhaustive patterns: `GithubPullRequests { .. }` not covered

Affected locations (all new code):

  1. apply_workflow_file — JSON branch (match &tmpl.source { GithubIssues … })
  2. apply_workflow_file — human-readable branch (match &tmpl.source { GithubIssues … })
  3. apply_directory — JSON workflow builder (match &t.source { GithubIssues … })

The live code path (~line 400) already handles both variants correctly:

let source_config = match tmpl.source {
    SourceTemplate::GithubIssues { .. }       => TaskSourceConfig::GithubIssues { .. },
    SourceTemplate::GithubPullRequests { .. } => TaskSourceConfig::GithubPullRequests { .. },
};

Each new dry-run match needs a GithubPullRequests arm, e.g.:

let source_json = match &tmpl.source {
    SourceTemplate::GithubIssues { owner, repo, labels, state } => serde_json::json!({
        "type": "github_issues",
        "owner": owner, "repo": repo, "labels": labels, "state": state,
    }),
    SourceTemplate::GithubPullRequests { owner, repo, labels, state } => serde_json::json!({
        "type": "github_pull_requests",
        "owner": owner, "repo": repo, "labels": labels, "state": state,
    }),
};

Apply the same fix to all three sites (JSON + human-readable in apply_workflow_file, and the workflow builder in apply_directory). A test covering a github_pull_requests source in dry-run mode should accompany the fix.


🟡 Non-blocking suggestions

1. Duplicated working_dir resolution

The same resolution block appears in apply_agent_file (dry-run), apply_agent (live), and apply_directory (dry-run JSON). Extracting to a helper keeps the logic in one place and ensures all three paths stay in sync if the resolution rules ever change:

fn resolve_working_dir(tmpl_working_dir: &str, yaml_path: &Path) -> String {
    if tmpl_working_dir == "." {
        std::env::current_dir()
            .map(|p| p.to_string_lossy().to_string())
            .unwrap_or_else(|_| ".".to_string())
    } else {
        let base = yaml_path.parent().unwrap_or(Path::new("."));
        let full = base.join(tmpl_working_dir);
        full.canonicalize().unwrap_or(full).to_string_lossy().to_string()
    }
}

2. Tests use fixed temp directory names — prefer tempfile::TempDir

Tests like agentd_dry_run_agent_test, agentd_dry_run_workflow_test, etc. use fixed names under the system temp dir. Parallel cargo test runs can collide or leave stale state if a test panics before remove_dir_all. The project already uses tempfile in storage.rsTempDir::new() gives automatic cleanup and unique per-run names.

3. .gitignore change is out of scope

Adding ui/.vite/ is legitimate cleanup but unrelated to the dry-run fix. Ideally it belongs in a separate commit to keep this one focused.

4. resolve_prompt called twice in apply_directory dry-run

In Phase 0 (lines 475, 487), resolve_prompt is already called and validated. In the dry-run JSON builder (line 528) it's called again with unwrap_or_default(). Harmless, but caching the result in the workflow_templates vec (e.g. as (PathBuf, WorkflowTemplate, String)) avoids the redundant call and the silent unwrap_or_default.

@geoffjay geoffjay removed the review-agent Used to invoke a review by an agent tracking this label label Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --dry-run flag to CLI apply command

1 participant