Skip to content

feat(runtime-api): expose git status metadata for Agent View#2862

Merged
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/v090-agent-view-git-status
Jun 6, 2026
Merged

feat(runtime-api): expose git status metadata for Agent View#2862
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/v090-agent-view-git-status

Conversation

@Hmbown
Copy link
Copy Markdown
Owner

@Hmbown Hmbown commented Jun 6, 2026

Summary

  • extend read-only runtime thread summaries with current Git head and dirty metadata for editor/Agent View lanes
  • add the same head / dirty fields to /v1/workspace/status responses
  • document the runtime API contract and v0.9 acceptance evidence for the read-only GUI visibility slice

Stewardship / credit

This is a narrow maintainer slice in the GUI/VS Code lane. It keeps #2808 open as useful design input but does not harvest its mutation endpoints (retry, undo, patch-undo, or restore-over-HTTP). Thanks @gaord for the GUI runtime API direction in #2808. The existing changelog trail also preserves the broader VS Code/GUI contributors and reporters.

Verification

  • cargo fmt --all -- --check
  • git diff --check
  • cmp -s CHANGELOG.md crates/tui/CHANGELOG.md
  • ./scripts/release/check-versions.sh
  • ./scripts/release/check-ohos-deps.sh
  • cargo test -p codewhale-tui workspace_status_reports_head_and_dirty_counts --locked
  • cargo test -p codewhale-tui thread_summary_includes_workspace_branch_metadata --locked
  • cargo test -p codewhale-tui workspace_and_automation_endpoints_work --locked

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Hmbown has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@Hmbown Hmbown merged commit 5bd2f6a into codex/v0.9.0-stewardship Jun 6, 2026
2 checks passed
@Hmbown Hmbown deleted the codex/v090-agent-view-git-status branch June 6, 2026 09:51
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds Git HEAD commit and dirty worktree state metadata to the workspace and thread summaries, updating the relevant API documentation, changelogs, and tests. The review feedback focuses on optimizing performance by reducing the number of spawned Git processes. Specifically, it suggests combining multiple Git queries into a single rev-parse command and avoiding redundant git status checks when collecting workspace status.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

}
}

let workspace_git = collect_workspace_git_metadata(&thread.workspace);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Pass true to collect_workspace_git_metadata to include the dirty status check for thread summaries.

Suggested change
let workspace_git = collect_workspace_git_metadata(&thread.workspace);
let workspace_git = collect_workspace_git_metadata(&thread.workspace, true);

Comment on lines +2034 to 2039
let metadata = collect_workspace_git_metadata(workspace);
status.branch = metadata.branch;
status.head = metadata.head;
status.dirty = metadata.dirty;

if let Some(porcelain) = run_git(workspace, &["status", "--porcelain=v1"]) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

To avoid running the expensive git status --porcelain=v1 command twice (once inside collect_workspace_git_metadata and once directly here), pass false to collect_workspace_git_metadata to skip the dirty check, and compute status.dirty directly from the porcelain output.

Suggested change
let metadata = collect_workspace_git_metadata(workspace);
status.branch = metadata.branch;
status.head = metadata.head;
status.dirty = metadata.dirty;
if let Some(porcelain) = run_git(workspace, &["status", "--porcelain=v1"]) {
let metadata = collect_workspace_git_metadata(workspace, false);
status.branch = metadata.branch;
status.head = metadata.head;
if let Some(porcelain) = run_git(workspace, &["status", "--porcelain=v1"]) {
status.dirty = !porcelain.trim().is_empty();

Comment on lines +2071 to +2085
fn collect_workspace_git_metadata(workspace: &std::path::Path) -> WorkspaceGitMetadata {
let Some(repo_check) = run_git(workspace, &["rev-parse", "--is-inside-work-tree"]) else {
return WorkspaceGitMetadata::default();
};
if repo_check.trim() != "true" {
return WorkspaceGitMetadata::default();
}

WorkspaceGitMetadata {
branch: current_git_branch(workspace),
head: current_git_head(workspace),
dirty: run_git(workspace, &["status", "--porcelain=v1"])
.is_some_and(|porcelain| !porcelain.trim().is_empty()),
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The current implementation spawns up to 5-6 separate git processes per workspace check (including redundant checks for --is-inside-work-tree and multiple rev-parse calls). This can be optimized to a single rev-parse call that queries the repository status, branch name, and short HEAD hash simultaneously, significantly improving performance.

fn collect_workspace_git_metadata(workspace: &std::path::Path, include_dirty: bool) -> WorkspaceGitMetadata {
    let Some(rev_parse) = run_git(workspace, &["rev-parse", "--is-inside-work-tree", "--abbrev-ref", "HEAD", "--short", "HEAD"]) else {
        return WorkspaceGitMetadata::default();
    };
    let mut lines = rev_parse.lines();
    let is_repo = lines.next().map(|s| s.trim() == "true").unwrap_or(false);
    if !is_repo {
        return WorkspaceGitMetadata::default();
    }
    let branch_raw = lines.next().map(|s| s.trim()).unwrap_or("");
    let head_raw = lines.next().map(|s| s.trim()).unwrap_or("");

    let branch = if branch_raw.is_empty() {
        None
    } else if branch_raw == "HEAD" {
        (!head_raw.is_empty()).then(|| format!("detached@{head_raw}"))
    } else {
        Some(branch_raw.to_string())
    };

    let head = (!head_raw.is_empty()).then(|| head_raw.to_string());
    let dirty = include_dirty && run_git(workspace, &["status", "--porcelain=v1"])
        .is_some_and(|porcelain| !porcelain.trim().is_empty());

    WorkspaceGitMetadata {
        branch,
        head,
        dirty,
    }
}

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.

1 participant