Skip to content

Fix immediate stats after editor agent commits#1640

Open
Siddhant-K-code wants to merge 4 commits into
git-ai-project:mainfrom
Siddhant-K-code:siddhant/cursor-copilot-commit-stats-regressions
Open

Fix immediate stats after editor agent commits#1640
Siddhant-K-code wants to merge 4 commits into
git-ai-project:mainfrom
Siddhant-K-code:siddhant/cursor-copilot-commit-stats-regressions

Conversation

@Siddhant-K-code

@Siddhant-K-code Siddhant-K-code commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a best-effort daemon family sync before git-ai stats and git-ai status read attribution data
  • Add delayed daemon-side regression coverage for Cursor and VS Code Copilot editor-like commit flows
  • Add coverage that pasted/copied code without an agent hook remains untracked rather than AI-attributed

Fixes #1423.
Refs #1584.

Validation

Run from the repo root on this branch:

task fmt
task lint
task test TEST_FILTER=test_cursor_editor_commit_immediate_stats_waits_for_daemon_note
task test TEST_FILTER=test_copilot_vscode_commit_immediate_stats_waits_for_daemon_note
task test TEST_FILTER=test_copied_code_without_agent_hook_remains_untracked_after_immediate_stats

Expected outcomes:

  • task fmt exits cleanly with no rustfmt diffs.
  • task lint exits cleanly with no clippy/lint failures.
  • Cursor immediate-stats regression passes: git-ai status --json and immediate git-ai stats HEAD --json report ai_additions == 1 after the delayed daemon commit path.
  • Copilot VS Code immediate-stats regression passes with the same ai_additions == 1 expectation.
  • Copied-code regression passes: a commit without any agent hook reports ai_additions == 0 and keeps the new lines as unknown/untracked additions.

Broader regression sweep:

task test TEST_FILTER=stats
task test TEST_FILTER=cursor
task test TEST_FILTER=github_copilot

Expected outcome: stats, Cursor, and GitHub Copilot integration coverage pass with the daemon sync behavior enabled.

Additional whitespace check:

git diff --check origin/main..siddhant/cursor-copilot-commit-stats-regressions

Expected outcome: no output and exit code 0.

Docs

No docs change needed. This fixes timing of existing git-ai stats / git-ai status behavior and is covered by regression tests.

Notes

Draft PR for focused review and CI validation.

Co-authored-by: Codex <noreply@openai.com>
@Siddhant-K-code Siddhant-K-code force-pushed the siddhant/cursor-copilot-commit-stats-regressions branch 4 times, most recently from 08eac5f to f4028a2 Compare June 24, 2026 12:07
@Siddhant-K-code Siddhant-K-code marked this pull request as ready for review June 24, 2026 12:57
devin-ai-integration[bot]

This comment was marked as resolved.

@Siddhant-K-code Siddhant-K-code force-pushed the siddhant/cursor-copilot-commit-stats-regressions branch from f4028a2 to 79aa8a1 Compare June 24, 2026 13:49
@svarlamov

Copy link
Copy Markdown
Member

I would strongly prefer us not using daemon syncs in production -- it's really only meant for testing. Could we just check if it's a recent commit and it doesn't have a note, wait a couple seconds and try again? Or even just add special log output for these cases for the user to try again later?

The other thing to keep in mind, is it's easily possible for the daemon to be 30+ seconds behind if its processing a big rebase or something like that for the repo

@Siddhant-K-code

Copy link
Copy Markdown
Collaborator Author

@svarlamov - I remember we agreed on the above approach! What would you suggest as an alternative?

@devin-ai-integration devin-ai-integration Bot left a comment

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.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment thread src/commands/status.rs
Comment on lines +218 to +242
fn sync_daemon_before_status_read(repo: &Repository) {
let Ok(workdir) = repo.workdir() else {
return;
};
let Ok(config) = DaemonConfig::from_env_or_default_paths() else {
return;
};
let request = ControlRequest::SyncFamily {
repo_working_dir: workdir.to_string_lossy().to_string(),
};
match send_control_request(&config.control_socket_path, &request) {
Ok(response) if response.ok => {}
Ok(response) => {
tracing::debug!(
"daemon sync before status failed: {}",
response
.error
.unwrap_or_else(|| "unknown error".to_string())
);
}
Err(error) => {
tracing::debug!("daemon sync before status unavailable: {}", error);
}
}
}

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.

🟡 Identical daemon-sync helper is duplicated across two files instead of being shared

The daemon sync logic is copy-pasted verbatim into two separate private functions (sync_daemon_before_stats_read at src/commands/git_ai_handlers.rs:1062 and sync_daemon_before_status_read at src/commands/status.rs:218) differing only in a debug log string, rather than being extracted into a single reusable helper.

Impact: Violates the repository's mandatory code-reuse rule and increases maintenance burden for any future changes to the sync logic.

AGENTS.md rule #5 violation details

AGENTS.md states: "Reuse existing code. This is a large codebase. For nearly any operation you need, there is almost certainly a helper function already available and tested. Reuse code as much as practical -- it also keeps diffs small. PRs that fail to reuse existing code where applicable will be rejected immediately."

Both functions have identical structure:

  1. Get workdir from repo
  2. Get DaemonConfig from env/default paths
  3. Build a ControlRequest::SyncFamily with the workdir
  4. Call send_control_request and handle Ok/Err

The only difference is the debug log message ("stats" vs "status"). These should be a single shared function, possibly accepting a &str context label for the debug message.

src/commands/git_ai_handlers.rs:1062-1086 is identical to src/commands/status.rs:218-242.

Prompt for agents
The functions sync_daemon_before_stats_read (in src/commands/git_ai_handlers.rs:1062-1086) and sync_daemon_before_status_read (in src/commands/status.rs:218-242) are identical except for the debug log message string. Extract a single shared helper function (e.g., in a common module or as a public utility) that accepts a context label parameter (like "stats" or "status") for the debug messages. Then have both call sites use that shared helper. This satisfies the AGENTS.md rule about reusing existing code and keeping diffs small.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@Siddhant-K-code

Copy link
Copy Markdown
Collaborator Author

CIs will be better after #1734

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants