Files
issue-core/.capability/agent-context.md
tegwick 324453bd8d feat: transform to agent coordination platform with comprehensive documentation
Transform Issue Facade from a universal CLI tool into an agent coordination platform with comprehensive documentation and enhanced capabilities for autonomous coding agents.

Major Changes:
- Complete README rewrite focusing on agent-driven coordination
- New comprehensive documentation (AGENT_INTEGRATION.md, CLAUDE.md, ROADMAP.md)
- Capability integration setup with CAPABILITY.yaml and integration scripts
- Enhanced Makefile with local development targets for easier workflows

Bug Fixes:
- Fix schema initialization using executescript() for multi-line SQL support
- Disable FTS5 triggers due to compatibility issues (documented for future re-enablement)

Features:
- Enhanced CLI list command with full parameter passthrough
- New examples directory with agent integration patterns
- New comprehensive test suite (test_core_models.py, test_local_backend.py)

Code Quality:
- Remove @cached_property decorators for Label properties (simplification)
- Clean up test organization (removed old test_gitea_integration.py)

This milestone establishes Issue Facade as a production-ready coordination layer for multi-agent software development, with clear integration paths and comprehensive developer documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 19:32:37 +01:00

9.1 KiB

Issue Facade - Agent Integration Context

🤖 For Coding Agents: Read this to understand how to use issue tracking in this project.

Critical: DO NOT Bypass This Capability

⚠️ IMPORTANT: If you need to work with issues, you MUST use this capability. Do NOT:

  • Make direct API calls to Gitea/GitHub/GitLab
  • Use platform CLIs (gh, glab, etc.)
  • Import platform libraries (PyGithub, python-gitlab, etc.)
  • Parse HTML/scrape issue tracker web UIs

Why? Bypassing this capability causes:

  • Credential management chaos (tokens scattered everywhere)
  • Inconsistent issue state across agents
  • Massive token waste (redundant API calls)
  • Platform lock-in (can't switch Gitea → GitHub easily)
  • Race conditions in multi-agent scenarios

Quick Reference

Check if Capability is Available

# Verify installation
issue --version
# or
python -c "from issue_tracker.backends.gitea import GiteaBackend; print('OK')"

Basic Usage (Python)

from issue_tracker.backends.gitea import GiteaBackend
from issue_tracker.core.models import Issue, Label, IssueState, User, Comment
from issue_tracker.core.interfaces import IssueFilter
from datetime import datetime, timezone
import os

# Connect (assumes backend is configured)
backend = GiteaBackend()
backend.connect({
    'base_url': os.environ['GITEA_URL'],
    'token': os.environ['GITEA_API_TOKEN'],
    'owner': os.environ['GITEA_OWNER'],
    'repo': os.environ['GITEA_REPO']
})

# List issues for me
my_issues = backend.list_issues(IssueFilter(
    state='open',
    assignee='my-agent-id',
    labels=['needs-implementation']
))

# Create issue
new_issue = Issue(
    id=None, number=0,
    title="Implement feature X",
    description="Details...",
    state=IssueState.OPEN,
    created_at=datetime.now(timezone.utc),
    updated_at=datetime.now(timezone.utc),
    labels=[Label(name="feature"), Label(name="priority:high")]
)
created = backend.create_issue(new_issue)

# Update issue
created.state = IssueState.IN_PROGRESS
created.assignees = [User(id="agent-id", username="agent-id")]
backend.update_issue(created)

# Add comment
comment = Comment(
    id=None,
    body="Implementation started. Working on database schema.",
    author=User(id="agent-id", username="agent-id"),
    created_at=datetime.now(timezone.utc)
)
backend.add_comment(created.id, comment)

# Close when done
created.state = IssueState.CLOSED
created.closed_at = datetime.now(timezone.utc)
backend.update_issue(created)

Basic Usage (CLI)

# List my open issues
issue list --state=open --assignee=agent-id --format=json

# Create issue
issue create "Implement feature X" \
  --label=feature \
  --label=priority:high \
  --description="Details here"

# Update state
issue edit 42 --state=in_progress --assignee=agent-id

# Add comment
issue comment 42 "Implementation started"

# Close
issue close 42 --comment="Completed successfully"

Common Patterns

Pattern 1: Find Work

# Get next available task
available_tasks = backend.list_issues(IssueFilter(
    state='open',
    labels=['ready', 'needs-implementation']
))

# Filter to unassigned
unassigned = [t for t in available_tasks if not t.assignees]

if unassigned:
    task = unassigned[0]
    # Claim it...

Pattern 2: Claim Issue (Prevent Race Conditions)

def claim_issue(issue: Issue, agent_id: str) -> bool:
    """Claim an issue safely."""
    # Check if already claimed
    if issue.assignees:
        return False  # Already taken

    # Claim it
    issue.state = IssueState.IN_PROGRESS
    issue.assignees = [User(id=agent_id, username=agent_id)]
    backend.update_issue(issue)

    # Announce claim
    backend.add_comment(issue.id, Comment(
        id=None,
        body=f"🤖 Claimed by {agent_id}",
        author=User(id=agent_id, username=agent_id),
        created_at=datetime.now(timezone.utc)
    ))
    return True

Pattern 3: Progress Updates

def report_progress(issue: Issue, message: str, agent_id: str):
    """Report progress on an issue."""
    backend.add_comment(issue.id, Comment(
        id=None,
        body=f"**Progress Update:**\n\n{message}",
        author=User(id=agent_id, username=agent_id),
        created_at=datetime.now(timezone.utc)
    ))

Pattern 4: Agent-to-Agent Communication

import json

def post_agent_message(issue_id: str, msg_type: str, data: dict, agent_id: str):
    """Post structured message for other agents."""
    message = {
        'type': msg_type,
        'agent': agent_id,
        'timestamp': datetime.now(timezone.utc).isoformat(),
        'data': data
    }
    backend.add_comment(issue_id, Comment(
        id=None,
        body=f"```agent-message\n{json.dumps(message, indent=2)}\n```",
        author=User(id=agent_id, username=agent_id),
        created_at=datetime.now(timezone.utc)
    ))

def read_agent_messages(issue_id: str, msg_type: str = None):
    """Read messages from other agents."""
    comments = backend.get_comments(issue_id)
    messages = []
    for comment in comments:
        if '```agent-message' in comment.body:
            try:
                json_str = comment.body.split('```agent-message\n')[1].split('\n```')[0]
                msg = json.loads(json_str)
                if msg_type is None or msg['type'] == msg_type:
                    messages.append(msg)
            except:
                continue
    return messages

Configuration Check

Before using issue tracking, verify configuration:

def verify_issue_backend() -> bool:
    """Verify issue backend is configured."""
    try:
        backend = GiteaBackend()
        backend.connect({
            'base_url': os.environ['GITEA_URL'],
            'token': os.environ['GITEA_API_TOKEN'],
            'owner': os.environ['GITEA_OWNER'],
            'repo': os.environ['GITEA_REPO']
        })
        return backend.test_connection()
    except Exception as e:
        print(f"Issue backend not configured: {e}")
        return False

# Use it
if not verify_issue_backend():
    print("ERROR: Issue tracking not available. Check configuration.")
    sys.exit(1)

Error Handling

from issue_tracker.backends.gitea.backend import GiteaAPIError

try:
    issue = backend.get_issue_by_number(42)
except GiteaAPIError as e:
    if e.status_code == 404:
        print("Issue not found")
    elif e.status_code == 401:
        print("Authentication failed - check GITEA_API_TOKEN")
    elif e.status_code == 429:
        print("Rate limited - wait and retry")
    else:
        print(f"API error: {e}")

Performance Tips

  1. Use filters instead of fetching all issues:

    # BAD: Get all, filter in Python
    all_issues = backend.list_issues()
    my_issues = [i for i in all_issues if i.assignees and i.assignees[0].username == 'me']
    
    # GOOD: Filter at backend
    my_issues = backend.list_issues(IssueFilter(assignee='me'))
    
  2. Use JSON output for CLI parsing:

    issue list --format=json | jq '.[] | select(.state == "open")'
    
  3. Batch comments instead of rapid-fire updates

  4. Check local cache before querying (if available)

Troubleshooting

"Backend not configured"

# Check config
issue backend list

# If empty, configure
export GITEA_API_TOKEN="your-token"
issue backend add myproject gitea
issue backend set-default myproject

"Authentication failed"

# Verify token
curl -H "Authorization: token $GITEA_API_TOKEN" $GITEA_URL/api/v1/user

"Issue not found"

# Use get_issue_by_number, not get_issue
issue = backend.get_issue_by_number(42)  # Correct
# issue = backend.get_issue("42")  # Wrong - needs backend_id

Full Documentation

  • Integration Guide: AGENT_INTEGRATION.md (comprehensive patterns and strategies)
  • API Reference: CLAUDE.md (for developers extending the capability)
  • Examples: examples/agents/ (working agent implementations)
  • Roadmap: ROADMAP.md (upcoming features)

Current Limitations (v1.0)

Be aware of these limitations:

  1. Manual Configuration: Backend must be configured before use (auto-detect in v1.1)
  2. User Context: Uses hardcoded user for CLI operations (agent identity in v1.2)
  3. No Built-in Locking: Use assignee + comment workaround for claiming (native in v1.2)
  4. Basic Conflicts: Manual resolution required for complex sync conflicts (advanced in v2.0)

Workarounds are documented in AGENT_INTEGRATION.md.

Questions?

If you're unsure whether to use this capability for something:

ASK: "Does this involve creating, reading, updating, or searching issues?"

  • YES → Use this capability
  • NO → You can use other methods

Example:

  • "Create an issue for the bug I found" → Use issue-facade
  • "Read the project README" → Don't need issue-facade
  • "Check if issue #42 exists" → Use issue-facade
  • "Clone the repository" → Don't need issue-facade