skills/skills/ticky/SKILL.md
--- name: ticky description: Full lifecycle ticket management — draft, submit, sync, and clean Azure DevOps work items across repos. user-invocable: true allowed-tools: Bash, Read, Write, Edit, Glob, Grep argument-hint: <mode> [args...] — modes: draft, submit, clean, update, get, create --- # Ticky — Full Lifecycle Ticket Management Manage Azure DevOps work items through their full lifecycle: draft locally, submit to ADO, sync status, and clean up cross-repo tickets. **CLI:** `${TICKY_HOME:-$
npx skillsauth add msifoss/ai-dlc skills/skills/tickyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage Azure DevOps work items through their full lifecycle: draft locally, submit to ADO, sync status, and clean up cross-repo tickets.
CLI: ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py
PAT: ${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txt
/ticky draft "Short description of what's needed"
/ticky draft "Short description" --priority 1 --tags "Tag1; Tag2" --type Bug
/ticky submit docs/tickets/20260302-143000-my-ticket-draft.md
/ticky submit docs/tickets/20260302-143000-my-ticket-draft.md --assign "Muhammad Usman"
/ticky clean [--dry-run]
/ticky update <slug-or-ado-id> [--pull] [--push]
/ticky get <ado-id> [--json]
/ticky create docs/tickets/my-ticket.yaml
/ticky create docs/tickets/my-ticket.yaml --assign "Name"
Arguments: $ARGUMENTS
Trigger: /ticky draft "description" or /ticky "description of ticket needed"
Creates a local .md ticket file and registers it in tickets.json. No ADO API call.
$ARGUMENTS for the description text and optional flags (--priority N, --tags "X; Y", --type Bug|Task|Issue, --dry-run)YYYYMMDD-HHMMSSdocs/tickets/YYYYMMDD-HHMMSS-slug-draft.md using the Ticket .md Format below${TICKY_HOME:-$HOME/repos/ticky}/templates/ticket-prompt.md to generate the HTML body sections (TL;DR, Description, What's Needed, Steps, Reference, Impact, Time, Contact)docs/tickets/tickets.json (create the file if it doesn't exist) — see tickets.json Schema below--dry-run was passed, show what would be created (filename, slug, frontmatter) without creating any files, then stop.---
title: "Short title"
type: Issue
priority: 2
tags: "Tag1; Tag2"
status: draft
ado_id: null
assigned_to: null
created: 2026-03-02T14:30:00
submitted: null
---
<h2>TL;DR</h2>
<p>...</p>
<h2>Description</h2>
<p>...</p>
<h2>What's Needed</h2>
<p><strong>...</strong></p>
<h2>Steps to Complete</h2>
<table border="1" cellpadding="6" cellspacing="0">
<tr style="background-color:#1B3A5C;color:#FFFFFF;"><th>Step</th><th>Action</th></tr>
<tr><td>1</td><td>...</td></tr>
</table>
<h2>Reference</h2>
<table border="1" cellpadding="6" cellspacing="0">
<tr style="background-color:#1B3A5C;color:#FFFFFF;"><th>Item</th><th>Value</th></tr>
<tr><td>Repo</td><td>...</td></tr>
</table>
<h2>Impact if Not Resolved</h2>
<p>...</p>
<h2>Estimated Time</h2>
<p><strong>X minutes</strong></p>
<h2>Contact</h2>
<p><strong>Requestor:</strong> <!-- Read from ~/.ticky.conf or git config user.name --><br/>
<strong>Email:</strong> <!-- Read from ~/.ticky.conf or git config user.email --><br/>
Available for questions or a quick call if needed.</p>
Trigger: /ticky submit <path-to-draft.md> or /ticky submit <path> --assign "Name"
Submits a draft ticket to ADO, updates the local file and tickets.json.
TICKY_PAT="$(cat ${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txt)"
.md file and validate it has frontmatter with status: draftpython3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT" --dry-run
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT"
--assign "Name" was specified, assign via:
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <ado_id> --assign "Name" --pat "$TICKY_PAT"
.md frontmatter:
status: submittedado_id: <id>assigned_to: <name> (if assigned)submitted: <ISO timestamp>-submitted.md) first, then remove the old draft file. This ensures no data loss if the process is interrupted.docs/tickets/tickets.json with the new state, ADO ID, URL, and filenameTrigger: /ticky clean or /ticky clean --dry-run
Normalizes tickets in the current repo to the new naming/format. Creates tickets.json. Use --all-repos to scan all repos under ~/repos/.
IMPORTANT: Always run --dry-run first and show the user what will change before doing anything.
| Pattern | Example | How to Handle |
|---------|---------|---------------|
| ticky-<name>.yaml | ticky-graph-explorer.yaml | Use file mtime for timestamp |
| YYYYMMDD-ticket-<name>.md | 20260212-ticket-ses-config.md | Extract date from filename |
| NNN-<name>.yaml | 001-enable-eventbridge.yaml | Use file mtime for timestamp |
| YYYYMMDD-<name>.md | 20250628-tinygo-wasm-support.md | Extract date, merge existing frontmatter |
| NNNN-<name>.yaml | 5139-secretsmanager-write.yaml | Extract ADO ID from prefix |
| YYYY-MM-DD-<name>.yaml | 2025-02-25-initial-setup.yaml | Reformat date |
docs/tickets/ for ticket files (.yaml, .yml, .md). To scan all repos, user must pass --all-repos flag explicitly.tickets.json already exists, read it first. Skip any ticket files that already have an entry in tickets.json with matching slug and status.CHANGELOG.md in the tickets dir for ADO IDs and states
c. Determine the canonical name: YYYYMMDD-HHMMSS-slug-status.md
d. Handle duplicate .yaml + .md pairs by merging (YAML has structured data, MD may have richer body)
e. Generate the new .md file with proper frontmatter
f. Build the tickets.json database--dry-run mode: print what would be created/renamed/merged, but change nothingtickets.json, but do not delete old files — leave them for user to clean up after verifyingFor repos like callhero that track ADO IDs in CHANGELOG.md:
#5139, ADO-5139, or ID: 5139 to extract ADO work item IDs[Closed], [Active], [Resolved] next to ticket entriesTrigger: /ticky update <slug-or-ado-id> or /ticky update --all
Syncs state between local ticket files and ADO.
| Field | Who Wins | Rationale | |-------|----------|-----------| | State, AssignedTo | ADO wins | Workflow fields managed in ADO board | | Title, Description, Priority, Tags | Local wins | Content fields managed by author |
tickets.json) or by ADO ID.md file and tickets.json entrypython3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py get <ado_id> --json --pat "$TICKY_PAT"
assigned_to from ADO System.AssignedTotickets.json field ado_state from ADO System.Statelast_synced timestamppython3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <ado_id> --title "X" --priority N --tags "X" --pat "$TICKY_PAT"
.md fileWhen /ticky update --all is used:
docs/tickets/tickets.json in the current repoado_id, run the sync steps above. Process in batches of 10 with a 2-second pause between batches to respect ADO's rate limit (200 requests/minute).Trigger: /ticky create <path-to-file> or /ticky <path-to-yaml>
Direct submission without the draft/submit lifecycle. Works exactly as before.
$ARGUMENTS for file path and optional --assign "Name" flagpython3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py validate <file>
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT"
--assign "Name", run:
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <ado_id> --assign "Name" --pat "$TICKY_PAT"
Trigger: /ticky get <ado-id>
Fetch and display a work item from ADO.
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py get <id> --pat "$TICKY_PAT"
For raw JSON: add --json flag.
Per-repo database at docs/tickets/tickets.json:
{
"schema_version": 1,
"last_sync": "2026-03-02T15:00:00",
"tickets": {
"20260302-143000-m365-admin-approval": {
"file": "20260302-143000-m365-admin-approval-submitted.md",
"ado_id": 5542,
"ado_url": "https://dev.azure.com/membersolutionsinc/DevOps/_workitems/edit/5542",
"status": "submitted",
"assigned_to": "Christopher Griffith",
"priority": 2,
"created": "2026-03-02T14:30:00",
"submitted": "2026-03-02T14:35:00",
"last_synced": "2026-03-02T15:00:00",
"ado_state": "New"
}
}
}
20260302-143000-m365-admin-approval), matching the file naming convention. If two tickets collide on slug, append -2, -3, etc.{"schema_version": 1, "last_sync": null, "tickets": {}})last_sync when any operation touches the filestatus values: draft, submitted, closedado_state mirrors the ADO board state: New, Active, Resolved, Closedado_state changes to Closed or Resolved, automatically set local status to closed and rename the file suffix from -submitted.md to -closed.mdAll ticket files follow: YYYYMMDD-HHMMSS-slug-status.md
| Part | Example | Notes |
|------|---------|-------|
| Date | 20260302 | Creation date |
| Time | 143000 | Creation time (HHMMSS) |
| Slug | m365-admin-approval | See Slug Generation Rules below |
| Status | draft or submitted | Current lifecycle status |
| Extension | .md | Always markdown with YAML frontmatter |
a-z, 0-9, and -tickets.json, append -2, -3, etc.Examples:
20260302-143000-m365-admin-approval-draft.md20260302-143000-m365-admin-approval-submitted.md${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txtps output):
TICKY_PAT="$(cat ${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txt)"
Then use --pat "$TICKY_PAT" in commands, or export it so ticky.py reads from env.chmod 600 ${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txt~/.ticky.conf: membersolutionsinc/DevOps# Load PAT once per session (NEVER pass PAT as a bare CLI argument — use env var)
TICKY_PAT="$(cat ${TICKY_HOME:-$HOME/repos/ticky}/tickypat.txt)"
# Validate (YAML, JSON, or MD)
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py validate <file>
# Create (submit to ADO)
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT"
# Dry run
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT" --dry-run
# Get work item by ID
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py get <id> --pat "$TICKY_PAT"
# Get as raw JSON
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py get <id> --json --pat "$TICKY_PAT"
# Update work item fields
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <id> --state Active --pat "$TICKY_PAT"
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <id> --assign "Name" --priority 1 --tags "Tag1; Tag2" --pat "$TICKY_PAT"
# Dry-run update
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py update <id> --tags "test" --dry-run --pat "$TICKY_PAT"
# Verbose logging
python3 ${TICKY_HOME:-$HOME/repos/ticky}/ticky.py create <file> --pat "$TICKY_PAT" -v
If a ticket was submitted in error:
.md frontmatter: set status: draft, clear ado_id and submitted-submitted.md back to -draft.mdstatus to draft, clear ado_id, ado_url, submittedThere is no automated retract command — this is intentional to prevent accidental mass-retraction. The steps above are manual and auditable.
Parse $ARGUMENTS to determine the mode:
| First Arg | Mode |
|-----------|------|
| draft | Draft mode |
| submit | Submit mode |
| clean | Clean mode |
| update | Update mode |
| get | Get mode (pass-through to CLI) |
| create or path to .yaml/.yml | Legacy create mode |
| Quoted text (no mode keyword) | If text matches an existing file path → Legacy create mode; otherwise → Draft mode (treat as description) |
development
Team sync for Astro website repos — checks git/GitHub/server state and tells you exactly what to do next
development
Simple team guide for website collaborators — checks your situation and tells you what to do in plain English
testing
# /staff — Staff Engineer Panel Analysis Convene a panel of 4 staff engineers from top tech companies + Will Larson as moderator to independently analyze a technical problem, debate options, and produce a consensus decision with implementation plan. > Like a real Staff Engineer round-table: each engineer brings their company's culture and battle scars. They disagree, challenge assumptions, find latent bugs, and converge on the smallest change that eliminates the actual risk. ## Trigger User
testing
# /prodstatus — CallHero Production Health Dashboard > **CONFIDENTIAL** — This skill contains internal infrastructure references (resource names, stack identifiers, queue names). Do not share outside the team or commit to public repositories. > Read-only diagnostic skill. No writes, no deploys, no doc updates. Pure observability. ## When to Use - Quick health check before a deploy - After a deploy to verify both stacks - Investigating an alarm or incident - Weekly status review ## Platform