issue-update
Update existing ticket/issue with status changes, comments, or field updates
What this skill does
<!-- AIWG-SKILL-CALLOUT -->
> **Skill access pattern (post-kernel-pivot, 2026.5+)**
>
> Skill names referenced in this document are AIWG skills, **not slash commands**. Most are not kernel-listed and cannot be invoked as `/skill-name` by the platform. Reach them via:
>
> ```bash
> aiwg discover "<capability>"
> aiwg show skill <name>
> ```
>
> Only kernel-listed skills (`aiwg-doctor`, `aiwg-refresh`, `aiwg-status`, `aiwg-help`, `use`, `steward`) are directly invokable as slash commands. See [skill-discovery rule](../../../addons/aiwg-utils/rules/skill-discovery.md).
# Issue Update
## Purpose
Update an existing ticket/issue with status transitions, progress comments, assignee changes, or metadata updates. Automatically uses the configured ticketing provider (Gitea, GitHub, Jira, Linear) or local file-based tracking.
## Task
Given a ticket ID and update parameters:
1. **Load configuration** from `.aiwg/config.yaml` or project `CLAUDE.md`
2. **Validate ticket exists** on provider or in local files
3. **Apply updates** (status, comment, assignee, labels, priority)
4. **Return confirmation** with updated ticket details
## Parameters
- **`<ticket-id>`** (required): Issue identifier (e.g., `ISSUE-001`, `#42`, `PROJECT-123`, `ENG-456`)
- **`--status STATE`** (optional): Update ticket status
- Valid states: `open`, `in_progress`, `closed`, `blocked`, `review`
- Provider-specific mappings applied automatically
- **`--comment "text"`** (optional): Add progress comment or note
- **`--assignee USER`** (optional): Assign to user (or `unassigned` to clear)
- **`--labels "label1,label2"`** (optional): Replace labels (comma-separated)
- **`--add-labels "label1,label2"`** (optional): Add labels without replacing existing
- **`--remove-labels "label1,label2"`** (optional): Remove specific labels
- **`--priority LEVEL`** (optional): Update priority (low|medium|high|critical)
- **`--milestone NAME`** (optional): Associate with milestone (provider-dependent)
- **`--provider NAME`** (optional): Override configured provider
## Inputs
**Configuration sources** (same as `issue-create`):
1. `.aiwg/config.yaml` - Project-level configuration
2. `CLAUDE.md` - User-level configuration
3. Default: `local` provider
## Outputs
**All Providers**:
- Confirmation of update
- Updated ticket details
- URL or file path to view changes
## Workflow
### Step 1: Parse Parameters
Extract from command invocation:
```bash
# Update status
/issue-update ISSUE-001 --status in_progress
# Add comment
/issue-update ISSUE-001 --comment "Completed authentication module, working on authorization next"
# Update status with comment
/issue-update ISSUE-001 --status closed --comment "Fixed in commit abc123"
# Assign ticket
/issue-update ISSUE-001 --assignee johndoe
# Update multiple fields
/issue-update ISSUE-001 --status in_progress --assignee johndoe --priority high --comment "Started implementation"
# Add labels without replacing
/issue-update ISSUE-001 --add-labels "urgent,needs-review"
# Remove labels
/issue-update ISSUE-001 --remove-labels "wip,blocked"
# Replace all labels
/issue-update ISSUE-001 --labels "completed,tested"
```
**Parameter extraction**:
- Issue ID: First argument (required)
- Flags: Parse `--flag value` pairs
- At least one update flag required (status, comment, assignee, labels, priority)
### Step 2: Load Configuration
Same as `issue-create` command:
1. Check `.aiwg/config.yaml`
2. Fallback to `CLAUDE.md`
3. Default to `local` provider
Override with `--provider` if specified.
### Step 3: Validate Issue Exists
**Gitea**:
```bash
# Fetch issue to verify existence
curl -s -H "Authorization: token $(cat ~/.config/gitea/token)" \
"${URL}/api/v1/repos/${OWNER}/${REPO}/issues/${TICKET_NUM}"
# Check HTTP status: 200 = exists, 404 = not found
```
**GitHub**:
```bash
# Fetch issue via gh CLI
gh issue view "${TICKET_NUM}" --repo "${OWNER}/${REPO}"
# Exit code 0 = exists, non-zero = not found
```
**Jira**:
```bash
# Fetch issue via REST API
curl -s -u "${JIRA_EMAIL}:${JIRA_API_TOKEN}" \
"${JIRA_URL}/rest/api/3/issue/${ISSUE_KEY}"
# Check HTTP status: 200 = exists, 404 = not found
```
**Linear**:
```bash
# Fetch issue via GraphQL
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: ${LINEAR_API_TOKEN}" \
-d '{"query": "query { issue(id: \"'${ISSUE_ID}'\") { id identifier title } }"}'
# Check if issue returned in response
```
**Local**:
```bash
# Check if file exists
if [ -f ".aiwg/issues/${TICKET_ID}.md" ]; then
echo "Issue exists"
else
echo "Issue not found"
fi
```
**Error if not found**:
```
❌ Issue not found: ISSUE-001
Available tickets:
- ISSUE-002: Add dark mode
- ISSUE-003: Fix navigation bug
List all tickets: /issue-list
```
### Step 4: Map Status to Provider-Specific Values
**Status mapping table**:
| Generic | Gitea | GitHub | Jira | Linear | Local |
|---------|-------|--------|------|--------|-------|
| `open` | open | open | To Do | Backlog | open |
| `in_progress` | open | open | In Progress | In Progress | in_progress |
| `closed` | closed | closed | Done | Done | closed |
| `blocked` | open | open | Blocked | Blocked | blocked |
| `review` | open | open | In Review | In Review | review |
**Implementation**:
```bash
case "${PROVIDER}" in
gitea|github)
case "${STATUS}" in
closed) PROVIDER_STATUS="closed" ;;
*) PROVIDER_STATUS="open" ;;
esac
;;
jira)
case "${STATUS}" in
open) PROVIDER_STATUS="To Do" ;;
in_progress) PROVIDER_STATUS="In Progress" ;;
closed) PROVIDER_STATUS="Done" ;;
blocked) PROVIDER_STATUS="Blocked" ;;
review) PROVIDER_STATUS="In Review" ;;
esac
;;
linear)
case "${STATUS}" in
open) PROVIDER_STATUS="Backlog" ;;
in_progress) PROVIDER_STATUS="In Progress" ;;
closed) PROVIDER_STATUS="Done" ;;
blocked) PROVIDER_STATUS="Blocked" ;;
review) PROVIDER_STATUS="In Review" ;;
esac
;;
local)
PROVIDER_STATUS="${STATUS}"
;;
esac
```
**Note**: Gitea and GitHub don't have separate "in_progress" state - use labels instead (e.g., add "in-progress" label when status changes to `in_progress`)
### Step 5: Update Issue (Provider-Specific)
#### Gitea
Use MCP tools `mcp__gitea__edit_issue` and `mcp__gitea__create_issue_comment`:
**Edit issue metadata**:
```bash
# Update status (state)
# Use mcp__gitea__edit_issue
# Parameters:
# owner: ${OWNER}
# repo: ${REPO}
# issue_number: ${TICKET_NUM}
# state: "open" | "closed"
# assignee: ${ASSIGNEE} (optional)
# labels: [${LABELS}] (optional)
```
**Add comment**:
```bash
# Use mcp__gitea__create_issue_comment
# Parameters:
# owner: ${OWNER}
# repo: ${REPO}
# issue_number: ${TICKET_NUM}
# body: ${COMMENT}
```
**Combined workflow**:
1. If status/assignee/labels specified → use `mcp__gitea__edit_issue`
2. If comment specified → use `mcp__gitea__create_issue_comment`
3. Both can be called in sequence if needed
#### GitHub
Use `gh` CLI:
**Update status**:
```bash
# Open issue
gh issue reopen "${TICKET_NUM}" --repo "${OWNER}/${REPO}"
# Close issue
gh issue close "${TICKET_NUM}" --repo "${OWNER}/${REPO}"
```
**Add comment**:
```bash
gh issue comment "${TICKET_NUM}" \
--repo "${OWNER}/${REPO}" \
--body "${COMMENT}"
```
**Update assignee**:
```bash
# Assign
gh issue edit "${TICKET_NUM}" \
--repo "${OWNER}/${REPO}" \
--add-assignee "${ASSIGNEE}"
# Unassign
gh issue edit "${TICKET_NUM}" \
--repo "${OWNER}/${REPO}" \
--remove-assignee "${ASSIGNEE}"
```
**Update labels**:
```bash
# Add labels
gh issue edit "${TICKET_NUM}" \
--repo "${OWNER}/${REPO}" \
--add-label "label1,label2"
# Remove labels
gh issue edit "${TICKET_NUM}" \
--repo "${OWNER}/${REPO}" \
--remove-label "label1,label2"
```
#### Jira
Use Jira REST API v3:
**Update issue fields**:
```bash
cat > /tmp/jira-update.json <<EOF
{
"fields": {
"status": {
"name": "${PROVIDER_STATUS}"
},
"assignee": {
"name": "${ASSIGNEE}"
},
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.