agent: improved capability integration
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
This commit is contained in:
323
.claude/capabilities/issue-facade.md
Normal file
323
.claude/capabilities/issue-facade.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# Verify installation
|
||||
issue --version
|
||||
# or
|
||||
python -c "from issue_tracker.backends.gitea import GiteaBackend; print('OK')"
|
||||
```
|
||||
|
||||
### Basic Usage (Python)
|
||||
|
||||
```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)
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```python
|
||||
# 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)
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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:
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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:
|
||||
```python
|
||||
# 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:
|
||||
```bash
|
||||
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"
|
||||
```bash
|
||||
# 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"
|
||||
```bash
|
||||
# Verify token
|
||||
curl -H "Authorization: token $GITEA_API_TOKEN" $GITEA_URL/api/v1/user
|
||||
```
|
||||
|
||||
### "Issue not found"
|
||||
```python
|
||||
# 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
|
||||
6
.claude/commands/use-issues.md
Normal file
6
.claude/commands/use-issues.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Use the issue-facade capability for all issue tracking operations.
|
||||
|
||||
**Quick reference:** See `.claude/capabilities/issue-facade.md`
|
||||
**Examples:** See `capabilities/issue-facade/examples/agents/`
|
||||
|
||||
**DO NOT use direct API calls or platform CLIs!**
|
||||
8
.claude/context/capabilities.md
Normal file
8
.claude/context/capabilities.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Available Capabilities
|
||||
|
||||
## Issue Tracking: issue-facade
|
||||
|
||||
**CRITICAL:** Always use this for issue operations. Never bypass with direct API calls.
|
||||
|
||||
**Docs:** `.claude/capabilities/issue-facade.md`
|
||||
**Usage:** `/use-issues`
|
||||
Submodule capabilities/issue-facade updated: 2dfe5130a3...324453bd8d
Submodule capabilities/testdrive-jsui updated: 1aea8b0d7d...b8f13b4ae5
Reference in New Issue
Block a user