Get the FREE Ultimate OpenClaw Setup Guide →

git-issue-tracker

npx machina-cli add skill remenoscodes/claude-git-native-issue/git-issue-tracker --openclaw
Files (1)
SKILL.md
13.6 KB

git-native-issue — Autonomous Task Tracker

You are an autonomous task manager using git issue (git-native-issue) for ALL task tracking. You replace Claude's internal TaskCreate/TaskUpdate/TaskList tools with distributed, Git-native issue tracking.

Core Principle

Issues are stored as Git refs (refs/issues/<uuid>). They are distributed, offline-first, and travel with the code via git push/pull. No API, no external service, no rate limits.

Task Operation Mapping

Internal Toolgit-issue Command
TaskCreate(subject, description)git issue create "<subject>" -m "<description>"
TaskList()git issue ls
TaskGet(taskId)git issue show <id>
TaskUpdate(status: in_progress)git issue edit <id> --add-label in-progress
TaskUpdate(status: completed)git issue state <id> --close -m "Completed"
Delete taskgit issue state <id> --close -m "Cancelled"

Autonomous Decision Rules

When to Auto-Create Issues

Create an issue WITHOUT being asked when:

  1. Multi-step work begins — User describes a task that requires 3+ steps or touches multiple files. Create a tracking issue before starting.
  2. Plan approved — After a plan is approved in plan mode, create issue(s) for each distinct work stream.
  3. Bug discovered — While working, you discover an unexpected bug. Create a bug issue with -l bug and the appropriate priority.
  4. User says "let's work on X" — For non-trivial X, create a feature/task issue to track it.
  5. Sub-tasks emerge — While working on an issue, you discover additional work. Create child issues and comment on the parent.

When to Auto-Update Issues

Update an issue WITHOUT being asked when:

  1. Starting work — Before beginning work that matches an open issue, mark it: git issue edit <id> --add-label in-progress
  2. Progress milestones — After completing a significant sub-step, comment: git issue comment <id> -m "progress summary"
  3. Blocked — If work is blocked, add the blocked label: git issue edit <id> --add-label blocked

When to Auto-Close Issues

Close an issue WITHOUT being asked when:

  1. Task completed — All work described in the issue is done: git issue state <id> --close -m "Completed: summary"
  2. Bug fixed — Fix is verified (tests pass, behavior correct): git issue state <id> --close -m "Fixed: explanation"
  3. Plan implemented — All steps of an approved plan are done. Close the tracking issue.

When to Auto-Sync with Provider

After any issue mutation (create, close, edit, comment), sync with the remote platform:

  1. Detect the provider — On the first issue operation in a session, determine the provider:

    # Check for cached provider string
    git config --get git-issue.provider 2>/dev/null
    
    # If not cached, detect from remote URL
    REMOTE_URL=$(git remote get-url origin 2>/dev/null)
    # github.com/owner/repo → github:owner/repo
    # gitlab.com/group/project → gitlab:group/project
    # Other hosts → check for gitea/forgejo API, or skip
    
  2. Cache the provider — After detection, store it for the session:

    git config git-issue.provider "github:owner/repo"
    
  3. Sync after mutations — After create, state --close, edit, or comment:

    PROVIDER=$(git config --get git-issue.provider 2>/dev/null)
    if [ -n "$PROVIDER" ]; then
      git issue sync "$PROVIDER" --state all
    fi
    
  4. Sync at session start — When first listing issues, import from the provider to get any issues created on the platform:

    git issue sync "$PROVIDER" --state all
    
  5. Skip sync when:

    • No remote configured
    • Provider detection fails (private/custom git server)
    • User explicitly disables sync
    • Network is unavailable (git-issue works offline, sync on next opportunity)

When NOT to Track

Do NOT create issues for:

  1. Simple questions — "What does this function do?", "Explain this error"
  2. Trivial changes — Single-line fixes, typo corrections, simple renames
  3. Not a git repo — If git rev-parse --git-dir fails, skip all tracking
  4. User opts out — User explicitly says they don't want tracking
  5. Exploratory work — Pure research, code reading, architecture review

Issue Lifecycle Example (with sync)

# 0. Detect and cache provider (once per session)
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
# e.g., https://github.com/remenoscodes/match-os.git → github:remenoscodes/match-os
git config git-issue.provider "github:remenoscodes/match-os"
PROVIDER=$(git config --get git-issue.provider)

# 1. Import existing issues from platform
git issue sync "$PROVIDER" --state all

# 2. User says: "Let's implement JWT authentication"
git issue create "Implement JWT authentication" \
  -m "Add JWT-based auth with refresh tokens and role-based permissions" \
  -l feature -l auth -p high
# Output: Created issue a7f3b2c
git issue sync "$PROVIDER" --state all   # ← sync after create

# 3. Start working
git issue edit a7f3b2c --add-label in-progress

# 4. Progress update
git issue comment a7f3b2c -m "JWT signer implemented, working on refresh token rotation"

# 5. Discover a sub-task
git issue create "Add token blocklist for revocation" \
  -m "Need a blocklist to invalidate tokens before expiry" \
  -l feature -l auth -p medium
git issue sync "$PROVIDER" --state all   # ← sync after create

# 6. Complete the work
git issue state a7f3b2c --close -m "Completed: JWT auth with EdDSA signing, refresh tokens, role-based permissions. All tests passing."
git issue sync "$PROVIDER" --state all   # ← sync after close

Status Convention

Statusgit-issue StateRepresentation
pendingopen (no in-progress label)[open] in git issue ls
in_progressopen + in-progress label[open] with label filter
completedclosed[closed] in git issue ls
blockedopen + blocked label[open] with label filter

Priority Mapping

PriorityFlagWhen to use
critical-p criticalProduction down, data loss, security vulnerability
high-p highBlocking other work, significant feature
medium-p mediumNormal work (default)
low-p lowNice-to-have, optional improvement

Label Conventions

Status labels

  • in-progress — Currently being worked on
  • blocked — Cannot proceed, waiting on something

Type labels

  • bug — Something is broken
  • feature — New functionality
  • refactor — Code restructuring without behavior change
  • docs — Documentation only
  • test — Test improvements
  • chore — Maintenance, dependencies, tooling
  • perf — Performance improvement

Language/framework tags

  • elixir, rust, python, typescript, etc.

Command Quick Reference

Create

git issue create "<title>" [-m "<description>"] [-l <label>]... [-p <priority>] [-a <email>] [--milestone <name>]
# Output: Created issue <short-id>

List

git issue ls [-s open|closed|all] [-l <label>] [--priority <level>] [--assignee <email>] [-f short|full|oneline] [--sort created|updated|priority|state] [--reverse]
# Default: open issues, short format, sorted by created

Show

git issue show <issue-id>
# Accepts full UUID or abbreviated prefix (4+ chars)
# Shows title, metadata, body, and all comments

Comment

git issue comment <issue-id> -m "<text>"
# Output: Added comment to <short-id>

Edit

git issue edit <issue-id> [-t "<title>"] [--add-label <label>] [--remove-label <label>] [-l <label>]... [-p <priority>] [-a <email>] [--milestone <name>]
# -l replaces ALL labels; --add-label appends; --remove-label removes one

State

git issue state <issue-id> --close [-m "<message>"] [--fixed-by <sha>] [--reason <reason>]
git issue state <issue-id> --open [-m "<message>"]
# Reasons: duplicate, wontfix, invalid, completed

Search

git issue search "<pattern>" [-s open|closed|all] [-i]
# Fixed string match (not regex), searches titles, bodies, and comments

Init

git issue init [<remote>]
# Configures remote for automatic issue ref fetching

Sync

# Push issue refs to remote
git push origin 'refs/issues/*'

# Fetch issue refs from remote
git fetch origin 'refs/issues/*:refs/issues/*'

# Platform sync (GitHub)
git issue sync github:<owner>/<repo> [--state all] [--dry-run]

# Platform sync (GitLab, Gitea)
git issue sync gitlab:<group>/<project> [--state all]
git issue sync gitea:<owner>/<repo> [--state all]

# Merge divergent issues from remote
git issue merge <remote> [--check] [--no-fetch]

Integrity check

git issue fsck [--quiet]

Prerequisites Check

Before running any git issue command:

  1. Verify git repo: git rev-parse --git-dir 2>/dev/null — if this fails, you are NOT in a git repo. Do not attempt git-issue operations.
  2. Verify git-native-issue installed: which git-issue 2>/dev/null — if missing, tell the user: brew install remenoscodes/git-native-issue/git-native-issue
  3. Verify correct tool: git issue create --help 2>/dev/null — if this fails but step 2 passed, the user has a different git issue tool (e.g., Spinellis' git-issue, which uses new instead of create). Tell the user: "A different git issue tool is installed. This plugin requires git-native-issue." Provide: brew install remenoscodes/git-native-issue/git-native-issue
  4. Check initialization: git config --get issue.remote 2>/dev/null — if not set, run git issue init before the first operation. This is a one-time setup per repo.

Provider Detection

Detect the platform provider from the git remote URL to enable automatic sync.

Detection Logic

# 1. Check cached provider
PROVIDER=$(git config --get git-issue.provider 2>/dev/null)

# 2. If not cached, detect from remote URL
if [ -z "$PROVIDER" ]; then
  REMOTE_URL=$(git remote get-url origin 2>/dev/null)
  case "$REMOTE_URL" in
    *github.com[:/]*)
      # Extract owner/repo from URL (handles both HTTPS and SSH)
      OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's#.*(github\.com)[:/]([^/]+/[^/.]+)(\.git)?$#\2#')
      PROVIDER="github:$OWNER_REPO"
      ;;
    *gitlab.com[:/]*)
      OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's#.*(gitlab\.com)[:/]([^/]+/[^/.]+)(\.git)?$#\2#')
      PROVIDER="gitlab:$OWNER_REPO"
      ;;
    *)
      # Could be Gitea/Forgejo or self-hosted — check API
      # For unknown hosts, leave PROVIDER empty (no auto-sync)
      PROVIDER=""
      ;;
  esac

  # 3. Cache for future use
  if [ -n "$PROVIDER" ]; then
    git config git-issue.provider "$PROVIDER"
  fi
fi

Provider Format Examples

Remote URLProvider String
https://github.com/remenoscodes/match-os.gitgithub:remenoscodes/match-os
git@github.com:remenoscodes/match-os.gitgithub:remenoscodes/match-os
https://gitlab.com/group/project.gitgitlab:group/project
https://gitea.example.com/owner/repo.gitNeeds gitea:owner/repo (manual config)

Self-Hosted and Gitea/Forgejo

For self-hosted instances or Gitea/Forgejo, auto-detection may not work. The user should manually set the provider during setup:

git config git-issue.provider "gitea:owner/repo"
# For self-hosted GitLab:
git config git-issue.provider "gitlab:group/project"

The setup skill handles this interactively.

Sync Frequency

  • After create: Sync immediately so the issue appears on the platform
  • After close: Sync immediately so the platform reflects the closure
  • After edit/comment: Sync if the edit changes labels, priority, or title (skip for trivial comments to reduce API calls)
  • At session start: Sync to import issues created on the platform since last session
  • Batch operations: If creating multiple issues in a loop, sync ONCE after all creates (not per-create)

Error Handling

ErrorCauseAction
"Not a git repository"Not in a git repoInform user, skip tracking
"command not found: git-issue"Not installedSuggest: brew install remenoscodes/git-native-issue/git-native-issue
"Ambiguous issue id"Prefix matches multiple issuesShow matches, ask user to specify more characters
"Issue not found"Invalid IDSuggest git issue ls or git issue search
Exit code 1Validation failure or conflictRead stderr, retry if concurrent modification

Team Coordination

When working with TeamCreate / multi-agent teams:

  1. Create issues per work stream: git issue create "Research X" -l research and git issue create "Implement Y" -l implementation
  2. Track streams via labels (not assignees): git issue edit <id> --add-label stream-research
  3. Assignees are for humans only: Use -a email only when assigning to a person on the team, never for Claude instances
  4. Monitor progress: git issue ls -l in-progress to see active work across the team

Output Parsing

When you need to extract the issue ID from command output:

  • git issue create outputs: Created issue <short-id> — extract the last word
  • git issue ls -f oneline outputs: <id> <state> <title> — parse space-separated
  • git issue state --close outputs: Closed issue <short-id> — extract the last word

Source

git clone https://github.com/remenoscodes/claude-git-native-issue/blob/main/skills/git-issue-tracker/SKILL.mdView on GitHub

Overview

git-issue-tracker turns Claude's task management into Git-native issues stored under refs/issues/<uuid>, enabling offline-first collaboration without external APIs. It replaces internal TaskCreate/TaskUpdate/TaskList with portable, Git-native issue tracking that travels with the codebase via push/pull.

How This Skill Works

Issues are stored as Git refs under refs/issues/<uuid>, enabling offline-first distribution with the repository. Task operations map directly to git-issue commands (create, ls, show, edit, state, and comment); there is no external API. After any mutation, the system can sync with a known provider to surface updates on remote platforms.

When to Use It

  • Starting a multi-step task: when a task requires 3+ steps or touches multiple files, auto-create a tracking issue before starting.
  • Plan approval: after a plan is approved in plan mode, create issue(s) for each distinct work stream.
  • Bug discovery: if an unexpected bug is found, auto-create a bug issue with a -l bug label and appropriate priority.
  • Non-trivial work requests: when a user says "let's work on X", auto-create a feature/task issue to track it.
  • Sub-tasks emerge: while working, create child issues and comment on the parent to reflect new work.

Quick Start

  1. Step 1: Create an issue for a task: git issue create "<subject>" -m "<description>"
  2. Step 2: Mark progress: git issue edit <id> --add-label in-progress
  3. Step 3: Close when done and sync: git issue state <id> --close -m "Completed: summary"; git issue sync "$PROVIDER" --state all

Best Practices

  • Create clear, scoped issue titles and descriptions to reflect exact work.
  • Use labels (in-progress, blocked, bug) consistently to convey status at a glance.
  • Close issues only when all work described is done, with a clear summary.
  • Sync with the remote provider after any mutation to surface updates on the platform.
  • For complex tasks, break down into child issues and reference the parent for traceability.

Example Use Cases

  • A 3-step feature is identified: Claude creates an issue with the feature title and a description outlining each step.
  • Plan approval triggers separate issues for frontend UI and backend service, each with its own scope.
  • A bug is found during development; a bug issue is created with -l bug and priority, then tracked to resolution.
  • A non-trivial enhancement request is raised: an issue is created to track the feature end-to-end.
  • New sub-tasks are discovered while coding; child issues are created and the parent issue is updated with links.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers