agentsclimarketplace

Commit agent changes

Skill timi-ty/agent-forge/skills/commit-agent-changes

Portable collection of Cursor agent and Claude Code agent skills. Paste the repo URL into agent chat to install on any machine

Install
npx -y skills add timi-ty/agent-forge --skill commit-agent-changes

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Identify the current agent's code changes, create a branch, group changes into logical commits, and open a PR. Use when the user says "commit my changes", "commit agent changes", "create a PR from this session", "push what you changed", or wants to turn the current agent's work into a pull request.

SKILL.md

15.8 KB, ~3.9k tokens by cl100k_base, as published. Nobody here has run it

Commit Agent Changes

Turn the current agent session's code changes into a well-structured branch with logically grouped commits and a pull request.

Workflow

Copy this checklist and track progress:

Commit Progress:
- [ ] Phase 1: Identify agent's changes
- [ ] Phase 2: Detect branch state and confirm with user
- [ ] Phase 3: Branch out via worktree (skip if already on feature branch)
- [ ] Phase 4: Group and commit
- [ ] Phase 5: Push (and create PR if needed)
- [ ] Phase 6: Cleanup worktree and local changes

Phase 1 -- Identify the Agent's Changes

Use a three-layer hybrid approach to build the definitive list of files this agent changed.

Step 1: Introspect conversation context

Review your own conversation history (already in your context window). List every file you wrote, edited, or deleted during this session. Include the operation type for each:

  • modified -- edited an existing file (StrReplace)
  • new -- created a file that didn't exist (Write to new path)
  • deleted -- removed a file (Delete)

This is the primary source of truth.

Step 2: Parse transcript for validation (Cursor only)

Skip this step if running in Claude Code. Claude Code does not maintain agent transcripts. The conversation context (Step 1) and git state (Step 3) provide sufficient coverage.

Find the agent-transcripts folder. Its path follows the pattern:

~/.cursor/projects/<project-slug>/agent-transcripts/

where <project-slug> is the workspace path with / replaced by - (e.g., Users-timi-Documents-ngriid).

List .txt files sorted by modification time (most recent first):

ls -t <transcripts-folder>/*.txt | head -5

Read the most recent .txt file and extract file paths from write-operation tool calls:

  • [Tool call] Write -- look for the path: line
  • [Tool call] StrReplace -- look for the path: line
  • [Tool call] Delete -- look for the path: line

Ignore read-only tool calls (Read, Grep, Glob, SemanticSearch).

Merge any file paths found here that were missing from Step 1.

Step 3: Cross-reference with git

For each git repository in the workspace, run:

git status --porcelain
git diff --name-only
git diff --name-only --cached

Build the final change list: a file is included ONLY if it appears in BOTH the agent's list (Steps 1+2) AND git reports it as changed/untracked/deleted. This filters out pre-existing dirty state that the agent did not cause.

Step 4: Check for other uncommitted changes

Compare the agent's final file list against all dirty files reported by git. Any dirty file NOT in the agent's list belongs to another agent or pre-existing state. If such files exist, record them separately -- they will NOT be committed, but the user should be made aware of them in Phase 2 so they know other work is in progress.

Organize the final list by repository:

repo: <repo-name> (<repo-path>)
  modified: path/relative/to/repo
  new:      path/relative/to/repo
  deleted:  path/relative/to/repo
  (other uncommitted files not owned by this agent:)
    path/relative/to/repo
    path/relative/to/repo

If no files survive the intersection, inform the user that there are no uncommitted agent changes and stop.


Phase 2 -- Detect Branch State and Confirm with User

Step 1: Detect the current branch

For each repository with changes, run:

git rev-parse --abbrev-ref HEAD

Classify the result:

  • Default branch (main, master, develop) -- a new feature branch is needed (Phase 3 will run).
  • Feature branch (anything else) -- already on the right branch (Phase 3 will be skipped).

When on a feature branch, check for an existing open PR:

gh pr view --json number,title,url,baseRefName 2>/dev/null

Record three pieces of state per repo for use in later phases:

  • on_feature_branch: boolean
  • existing_pr: {number, title, url, baseRefName} or null
  • base_branch: from the existing PR's baseRefName, or to be asked

Step 2: Present the situation and confirm

Present the change list from Phase 1 to the user, along with the detected branch state. Ask the user to confirm.

The prompt varies by situation:

  • On a feature branch with an existing PR: "You're on refactor/remove-caching which has PR #42 open against main. Commit and push to it?" Options: proceed, exclude files.
  • On a feature branch with no PR: "You're on feat/ingestion-buffer with no open PR. Commit, push, and create a new PR?" Options: proceed, exclude files. Also ask for the base branch (present the repo's default branch as the default option).
  • On a default branch: "You're on main. I'll create a new feature branch." Options: proceed, exclude files. Ask for the base branch (present main as the default).

If other uncommitted changes were detected in Phase 1 Step 4, additionally note: "Other uncommitted changes exist in this repo (not owned by this agent): {list}. These will NOT be included."

If the user excludes files, remove them from the list before continuing.

Step 3: Verify remote branch state

Set $BRANCH to the current branch name (result of git rev-parse --abbrev-ref HEAD from Step 1).

For each repository, fetch the latest remote state (without merging):

git fetch origin

Compute the ahead/behind relationship against the current branch ($BRANCH):

git rev-list --count HEAD..origin/$BRANCH   # commits behind
git rev-list --count origin/$BRANCH..HEAD   # commits ahead

Act on the result:

  • Up to date (both = 0): continue.
  • Behind only (behind > 0, ahead = 0): ask the user: "Your branch is {N} commit(s) behind origin/{branch}. Fast-forward before proceeding?" If yes, run git pull --ff-only origin $BRANCH and continue. If no, abort.
  • Ahead only (behind = 0, ahead > 0): this is expected if there are already commits on the branch. Inform the user: "You have {N} existing commit(s) on {branch} not yet pushed. New commits will be added on top." Continue.
  • Diverged (both > 0): abort and tell the user: "Local {branch} has diverged from origin/{branch} ({N} ahead, {M} behind). Resolve the divergence manually before proceeding."

Note (applies to all of Phase 2): If changes span multiple repositories, confirm each repo separately. Each repo gets its own branch and PR.


Phase 3 -- Branch Out via Worktree

Skip this phase entirely if on_feature_branch is true for the repo. When skipped, set $COMMIT_DIR to the current workspace root and proceed directly to Phase 4.

For each repository that is on a default branch:

Step 1: Determine branch name

  1. Determine the branch type from the nature of the changes:

    • feat/ -- new functionality
    • fix/ -- bug fix
    • refactor/ -- restructuring without behavior change
    • chore/ -- tooling, config, dependencies
    • docs/ -- documentation only
  2. Generate a concise slug (3-5 words, kebab-case) summarizing the scope. Examples:

    • refactor/remove-telemetry-caching
    • feat/add-ingestion-buffer
    • fix/mqtt-reconnect-handling

If the branch name already exists, append a short numeric suffix (e.g., -2).

Step 2: Create the worktree

Determine $REPO_NAME from the git remote or directory name. Create a worktree with the new branch based on the current HEAD:

git worktree add -b <branch-name> ../$REPO_NAME-wt-commit HEAD

Set $COMMIT_DIR to the absolute path of the created worktree.

If the worktree path already exists (from a previous interrupted commit), remove it first:

git worktree remove ../$REPO_NAME-wt-commit --force

Sync build-essential non-tracked files

Copy non-version-controlled files needed for builds from the main repo to the worktree. These files are gitignored and therefore absent from a fresh worktree. This ensures pre-commit hooks that depend on environment files will work correctly.

REPO_ROOT=$(git rev-parse --show-toplevel)
for f in .env .env.local .env.production .env.development .env.production.local .env.development.local .env.test .env.test.local; do
  [ -f "$REPO_ROOT/$f" ] && cp "$REPO_ROOT/$f" "$COMMIT_DIR/$f"
done

For monorepos, also check subdirectories:

find "$REPO_ROOT" -mindepth 2 -name '.env*' -not -path '*/node_modules/*' -not -path '*/.git/*' | while read src; do
  rel="${src#$REPO_ROOT/}"
  mkdir -p "$COMMIT_DIR/$(dirname "$rel")"
  cp "$src" "$COMMIT_DIR/$rel"
done

If the project has a .env.example or .env.template in the repo root but no .env, warn the user: "No .env file found. The build may fail if environment variables are required."

Do not log or display the contents of these files -- they may contain secrets.

Step 3: Transfer the agent's changes to the worktree

Only the agent's changes (from the Phase 1 change list) are transferred. The user's working directory is not modified.

Modified files (tracked files with changes):

git diff -- <file1> <file2> ... > agent-changes.patch

Then apply in the worktree:

git -C $COMMIT_DIR apply <absolute-path-to>/agent-changes.patch

Delete the temporary patch file after applying.

If git apply fails (e.g., binary files, complex renames, encoding issues), fall back to direct file copy for the affected files: copy each failed file from the workspace root to the corresponding path in $COMMIT_DIR, overwriting the base-branch version.

New files (untracked):

Copy each new file to the corresponding path in $COMMIT_DIR, creating parent directories as needed.

Deleted files:

Remove each deleted file in $COMMIT_DIR.

After transfer, verify that git -C $COMMIT_DIR status --porcelain shows the expected changes.


Phase 4 -- Group and Commit

All git commands in this phase run in $COMMIT_DIR (the worktree if Phase 3 created one, or the workspace root if Phase 3 was skipped). Use git -C $COMMIT_DIR or set the working directory to $COMMIT_DIR before running commands.

Analyze and group

Read the diffs (git -C $COMMIT_DIR diff -- <file> for each file) and group them by cohesive concern. A "concern" is a single logical unit of work -- all the files needed to accomplish one thing.

Grouping rules:

  • Files that implement the same feature or fix go together.
  • A new utility/module AND the files that import it go in the same commit.
  • Pure renames or moves are their own commit.
  • Config/dependency changes are their own commit unless they directly enable a feature in the same PR.
  • Deletions of replaced code go in the same commit as the replacement.

Single commit when: All changes serve one cohesive purpose.

Multiple commits when: The session's work spans distinct concerns (e.g., a refactor + a new feature + a config update). Split into one commit per concern.

Commit each group

Process groups in dependency order (foundational changes first, consuming code after).

For each group, first add any new (untracked) files from this group:

git -C $COMMIT_DIR add <new-file1> <new-file2>

Then commit using pathspec to include only this group's files:

git -C $COMMIT_DIR commit -m "$(cat <<'EOF'
type(scope): concise description

Optional body explaining WHY, not what. One short paragraph max.
EOF
)" -- <file1> <file2> <file3>

Using git commit -- <files> stages and commits only the listed files. Even though the worktree should only contain agent changes, pathspec provides defense-in-depth against unexpected files (e.g., leftover artifacts from a failed patch apply).

Commit message rules:

  • Subject line: type(scope): description -- under 72 characters
  • type matches the branch prefix (feat, fix, refactor, chore, docs)
  • scope is the module or area affected (e.g., telemetry, mqtt, auth)
  • Body is optional; include only if the "why" isn't obvious from the subject
  • Never reference the agent, AI, Cursor, or Claude Code in commit messages

Phase 5 -- Push (and Create PR if Needed)

All git commands in this phase run in $COMMIT_DIR (same as Phase 4).

Push the commits:

git -C $COMMIT_DIR push -u origin HEAD

If an existing PR was found in Phase 2

The push is sufficient -- the PR is already open and will reflect the new commits. Display the existing PR URL to the user.

If no existing PR was found

Create a new PR (run gh from within $COMMIT_DIR so it picks up the correct branch):

cd $COMMIT_DIR
gh pr create --base <base-branch> --title "<title>" --body "$(cat <<'EOF'
## Summary

- <bullet 1: what changed and why>
- <bullet 2: what changed and why>
- <bullet 3 if needed>

## Commits

- `<hash-short>` type(scope): description
- `<hash-short>` type(scope): description

## Test plan

- [ ] <specific verification step>
- [ ] <specific verification step>
EOF
)"

PR title: Same format as the commit subject if single-commit. For multi-commit PRs, write a broader summary (still under 72 chars).

PR body rules:

  • Summary: 1-3 bullets focused on WHY, not WHAT
  • Commits: list each commit hash + message (get from git log --oneline <base>..HEAD)
  • Test plan: concrete steps someone can follow to verify the changes work

After pushing (or creating a PR), display the PR URL to the user.

If changes spanned multiple repos, repeat Phases 3-6 for each repo.


Phase 6 -- Cleanup Worktree and Local Changes

Skip this phase if Phase 3 was skipped (i.e., on_feature_branch was true and no worktree was created).

Step 1: Remove the worktree

git worktree remove ../$REPO_NAME-wt-commit

If removal fails, force it:

git worktree remove --force ../$REPO_NAME-wt-commit

Step 2: Clean up local changes

The agent's changes still exist as uncommitted modifications in the user's original working directory. Since they are now committed and pushed in the PR, ask the user whether to revert them locally.

Ask the user with these options:

  • Clean up -- revert the agent's changes in the working directory (recommended). This restores the working directory to a clean state.
  • Keep locally -- leave the changes in the working directory as-is. Useful if the user wants to keep iterating on them.

If "Clean up" is selected:

For modified files:

git checkout -- <file1> <file2> ...

For new (untracked) files:

rm <file1> <file2> ...

For deleted files -- no action needed; the file is already absent locally, and the deletion is captured in the PR.

If "Keep locally" is selected: Do nothing. Inform the user that the local changes remain uncommitted.

Step 3: Verify

Run git status in the original working directory to confirm the expected state and report it to the user.


Important Principles

  • Only commit agent changes: Never commit files the agent didn't touch, even if they have uncommitted changes.
  • Atomic commits: Each commit should compile and make sense on its own. Don't commit half a refactor.
  • No AI references: Commit messages, PR titles, and PR bodies should read as if a human wrote them. Never mention "agent", "AI", "Cursor", "Claude Code", or "automated".
  • Respect existing conventions: If the repo has a commit message convention or PR template, follow it instead of the defaults above.
  • Ask before acting: Always confirm the file list and base branch before creating any commits.
  • Never disturb the user's branch: When on a default branch, use a worktree to create the feature branch. The user's working directory stays on its original branch throughout.
  • Clean state: After creating the PR, run git status to confirm the expected state. Report any leftover uncommitted changes to the user.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.