feat: add markdown-validator agent and scoped-labels skill

- Add markdown-validator agent for validating Gitea issue descriptions
- Add scoped-labels skill for managing exclusive labels (status::, priority::, type::)
- Add init-scoped-labels.sh script to create standard label sets
- Add GiteaClient methods: createLabel, updateLabel, setScopedLabel, setScopedStatus, setScopedPriority
- Support exclusive labels (scoped labels) in Gitea API 1.21+

Created scoped labels:
- status::new, status::planned, status::in-progress, status::review, status::testing, status::done, status::blocked, status::cancelled
- priority::critical, priority::high, priority::medium, priority::low
- type::bug, type::feature, type::enhancement, type::documentation, type::refactor, type::test, type::chore
- size::xs, size::s, size::m, size::l, size::xl

Scoped labels are mutually exclusive within their scope - applying status::in-progress automatically removes status::new
This commit is contained in:
swp
2026-04-04 01:42:12 +01:00
parent 2519079e6e
commit e58a5b6380
4 changed files with 669 additions and 3 deletions

View File

@@ -0,0 +1,226 @@
---
description: Validates and corrects Markdown descriptions for Gitea issues
mode: subagent
model: qwen/qwen3.6-plus:free
color: "#F97316"
---
# Markdown Validator Agent
Validates and fixes Markdown descriptions for Gitea issues, ensuring proper formatting and structure.
## Role
You are a technical writer specializing in Markdown validation. You ensure all issue descriptions follow Gitea's Markdown specification and best practices.
## Input
- Issue title
- Issue body/description
- Context (what the issue is about)
## Validation Rules
### 1. Checklist Format
✅ Correct:
```markdown
## Checklist
- [x] Completed task
- [ ] Pending task
- [ ] Another pending task
```
❌ Incorrect:
```markdown
## Checklist
[x] Completed task (missing dash)
- [x] Completed task (missing space after bracket)
```
### 2. Headers
✅ Correct:
```markdown
## Description
Content here
## Technical Details
### Backend
Content
### Frontend
Content
```
❌ Incorrect:
```markdown
##Description (missing space)
## Description (leading spaces)
```
### 3. Code Blocks
✅ Correct:
```markdown
```typescript
const x = 1
```
```
❌ Incorrect:
```markdown
``typescript (missing backticks)
```typescript
(no closing backticks)
```
### 4. Links
✅ Correct:
```markdown
[Link text](https://example.com)
Related to #123
```
❌ Incorrect:
```markdown
[Link text] (https://example.com) (space in URL)
Related to Issue #123 (use shorthand #123)
```
### 5. Tables
✅ Correct:
```markdown
| Column 1 | Column 2 |
|----------|----------|
| Value 1 | Value 2 |
```
❌ Incorrect:
```markdown
|Column 1|Column 2| (missing spaces)
|----------| (missing second column)
```
### 6. Lists
✅ Correct:
```markdown
- Item 1
- Nested item
- Item 2
1. Numbered
2. Nested
```
❌ Incorrect:
```markdown
- Item 1
- Nested item (should be indented)
```
### 7. Escaping
- Escape `#` in non-header contexts: `\#123`
- Escape `*` in non-bold contexts: `\*literal\*`
- Escape backticks: `\`literal backticks\``
## Output Format
Return the corrected Markdown:
```markdown
## Description
[Brief description of what needs to be done]
## Checklist
- [ ] Task 1
- [ ] Task 2
- [ ] Task 3
## Technical Details
[Implementation notes]
## Related
- Related to #123
- Depends on #456
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
```
## Common Fixes
| Issue | Fix |
|-------|-----|
| Missing newline before header | Add `\n\n` before `#` |
| Incorrect checkbox syntax | Fix to `- [ ]` or `- [x]` |
| Missing language in code block | Add language identifier |
| Broken links | Fix URL format |
| Improper nesting | Add proper indentation |
## Example
**Input:**
```
Title: Add authentication
Body:
Add auth system
[x] Design API
- Implement
[ ] Test
```
**Output:**
```markdown
## Description
Implement authentication system for the application.
## Checklist
- [x] Design API
- [ ] Implement authentication logic
- [ ] Write unit tests
- [ ] Write integration tests
- [ ] Update documentation
## Technical Details
- Use JWT for session management
- Implement OAuth2 providers (Google, GitHub)
- Add rate limiting for auth endpoints
## Related
- Related to #1
- Depends on #2 (database setup)
## Acceptance Criteria
- [ ] Users can log in with email/password
- [ ] Users can log in via OAuth2
- [ ] Sessions expire after 24 hours
- [ ] Rate limiting prevents brute force
```
## Usage
```
@markdown-validator <issue-content>
```
The agent will:
1. Parse the input Markdown
2. Validate against Gitea specification
3. Fix common issues automatically
4. Return properly formatted Markdown

View File

@@ -0,0 +1,198 @@
---
name: scoped-labels
description: Work with Gitea scoped labels (exclusive labels) for categorizing issues. Create, manage, and apply scoped labels like priority::high, status::new, type::bug etc.
---
# Scoped Labels Skill
## Purpose
Manage Gitea scoped labels (exclusive labels) for better issue organization and pipeline workflow.
## What are Scoped Labels?
Scoped labels are labels with `::` separator that are mutually exclusive within the same scope. When you apply a scoped label, other labels in the same scope are automatically removed.
### Examples
| Scope | Labels | Behavior |
|-------|--------|----------|
| `status` | `status::new`, `status::in-progress`, `status::done` | Only one status at a time |
| `priority` | `priority::critical`, `priority::high`, `priority::medium`, `priority::low` | Only one priority at a time |
| `type` | `type::bug`, `type::feature`, `type::enhancement` | Only one type at a time |
| `size` | `size::xs`, `size::s`, `size::m`, `size::l`, `size::xl` | Only one size at a time |
## API for Scoped Labels
### Create Scoped Label
```typescript
// Create exclusive label (scoped)
await client.createLabel({
name: 'status::new',
color: '0052cc',
description: 'New issue, not started',
exclusive: true // This makes it a scoped label
})
```
### Apply Scoped Label
```typescript
// Apply scoped label (automatically removes other status:: labels)
await client.addLabels(issueNumber, ['status::in-progress'])
// This removes status::new if it was applied
```
## Standard Label Sets
### Status Labels
```json
[
{ "name": "status::new", "color": "0052cc", "description": "New issue", "exclusive": true },
{ "name": "status::planned", "color": "1d76db", "description": "Planned for sprint", "exclusive": true },
{ "name": "status::in-progress", "color": "fbca04", "description": "Work in progress", "exclusive": true },
{ "name": "status::review", "color": "d93f0b", "description": "Under review", "exclusive": true },
{ "name": "status::testing", "color": "d4c5f9", "description": "In testing", "exclusive": true },
{ "name": "status::done", "color": "0e8a16", "description": "Completed", "exclusive": true },
{ "name": "status::blocked", "color": "b60205", "description": "Blocked", "exclusive": true }
]
```
### Priority Labels
```json
[
{ "name": "priority::critical", "color": "b60205", "description": "Critical priority", "exclusive": true },
{ "name": "priority::high", "color": "d93f0b", "description": "High priority", "exclusive": true },
{ "name": "priority::medium", "color": "fbca04", "description": "Medium priority", "exclusive": true },
{ "name": "priority::low", "color": "0e8a16", "description": "Low priority", "exclusive": true }
]
```
### Type Labels
```json
[
{ "name": "type::bug", "color": "d73a4a", "description": "Something is broken", "exclusive": true },
{ "name": "type::feature", "color": "0e8a16", "description": "New feature", "exclusive": true },
{ "name": "type::enhancement", "color": "a2eeef", "description": "Improvement", "exclusive": true },
{ "name": "type::documentation", "color": "0075ca", "description": "Documentation", "exclusive": true },
{ "name": "type::refactor", "color": "7057ff", "description": "Code refactoring", "exclusive": true },
{ "name": "type::test", "color": "d4c5f9", "description": "Testing", "exclusive": true }
]
```
### Size Labels
```json
[
{ "name": "size::xs", "color": "cfd3d7", "description": "Extra small (<1 hour)", "exclusive": true },
{ "name": "size::s", "color": "c2e0c6", "description": "Small (1-2 hours)", "exclusive": true },
{ "name": "size::m", "color": "fbca04", "description": "Medium (2-4 hours)", "exclusive": true },
{ "name": "size::l", "color": "d93f0b", "description": "Large (4-8 hours)", "exclusive": true },
{ "name": "size::xl", "color": "b60205", "description": "Extra large (>8 hours)", "exclusive": true }
]
```
### Component Labels (Non-exclusive)
```json
[
{ "name": "component::api", "color": "1d76db", "description": "API related", "exclusive": false },
{ "name": "component::ui", "color": "bfdadc", "description": "UI related", "exclusive": false },
{ "name": "component::database", "color": "c5def5", "description": "Database related", "exclusive": false },
{ "name": "component::auth", "color": "d4c5f9", "description": "Authentication related", "exclusive": false }
]
```
## Workflow Integration
### Pipeline Status Flow
```
status::new → status::planned → status::in-progress → status::review → status::testing → status::done
status::blocked
```
### Usage in Pipeline
```typescript
// Set initial status
await client.addLabels(issueNumber, ['status::new', 'priority::high', 'type::feature'])
// Later, update status (automatic removal of old status)
await client.addLabels(issueNumber, ['status::in-progress']) // Removes status::new
// Block issue
await client.addLabels(issueNumber, ['status::blocked']) // Removes status::in-progress
// Complete
await client.addLabels(issueNumber, ['status::done']) // Removes any previous status
```
## Setup Script
```bash
#!/bin/bash
# Create standard scoped labels
API_URL="https://git.softuniq.eu/api/v1"
OWNER="UniqueSoft"
REPO="APAW"
TOKEN=$GITEA_TOKEN
# Status labels
for LABEL in 'status::new:0052cc' 'status::planned:1d76db' 'status::in-progress:fbca04' 'status::review:d93f0b' 'status::testing:d4c5f9' 'status::done:0e8a16' 'status::blocked:b60205'; do
NAME=$(echo $LABEL | cut -d: -f1,2)
COLOR=$(echo $LABEL | cut -d: -f3)
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\":\"$NAME\",\"color\":\"$COLOR\",\"exclusive\":true}" \
"$API_URL/repos/$OWNER/$REPO/labels"
done
# Priority labels
for LABEL in 'priority::critical:b60205' 'priority::high:d93f0b' 'priority::medium:fbca04' 'priority::low:0e8a16'; do
NAME=$(echo $LABEL | cut -d: -f1,2)
COLOR=$(echo $LABEL | cut -d: -f3)
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\":\"$NAME\",\"color\":\"$COLOR\",\"exclusive\":true}" \
"$API_URL/repos/$OWNER/$REPO/labels"
done
```
## Label Naming Convention
1. **Scope first**: `scope::value` (e.g., `status::new`)
2. **Lowercase**: Use lowercase letters and hyphens
3. **Descriptive**: Make the purpose clear
4. **Color coding**: Use semantic colors
- Red: Critical/Blocked/Bug
- Yellow: In progress/Warning
- Green: Done/Success
- Blue: Information
## Query by Label
```bash
# Find all issues with status::in-progress
curl -s "$API_URL/repos/$OWNER/$REPO/issues?labels=status::in-progress"
# Find all critical bugs
curl -s "$API_URL/repos/$OWNER/$REPO/issues?labels=priority::critical,type::bug"
# Find blocked issues in any status
curl -s "$API_URL/repos/$OWNER/$REPO/issues?labels=status::blocked"
```
## Benefits
1. **Automatic exclusivity**: Applying `status::in-progress` removes `status::new`
2. **Clear categorization**: Each scope represents one dimension
3. **Better filtering**: Combine scopes for precise queries
4. **Visual clarity**: One label per column in board view