@avantmedia/af 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +539 -0
  3. package/af +2 -0
  4. package/bun-upgrade.ts +130 -0
  5. package/commands/bun.ts +55 -0
  6. package/commands/changes.ts +35 -0
  7. package/commands/e2e.ts +12 -0
  8. package/commands/help.ts +236 -0
  9. package/commands/install-extension.ts +133 -0
  10. package/commands/jira.ts +577 -0
  11. package/commands/licenses.ts +32 -0
  12. package/commands/npm.ts +55 -0
  13. package/commands/scaffold.ts +105 -0
  14. package/commands/setup.tsx +156 -0
  15. package/commands/spec.ts +405 -0
  16. package/commands/stop-hook.ts +90 -0
  17. package/commands/todo.ts +208 -0
  18. package/commands/versions.ts +150 -0
  19. package/commands/watch.ts +344 -0
  20. package/commands/worktree.ts +424 -0
  21. package/components/change-select.tsx +71 -0
  22. package/components/confirm.tsx +41 -0
  23. package/components/file-conflict.tsx +52 -0
  24. package/components/input.tsx +53 -0
  25. package/components/layout.tsx +70 -0
  26. package/components/messages.tsx +48 -0
  27. package/components/progress.tsx +71 -0
  28. package/components/select.tsx +90 -0
  29. package/components/status-display.tsx +74 -0
  30. package/components/table.tsx +79 -0
  31. package/generated/setup-manifest.ts +67 -0
  32. package/git-worktree.ts +184 -0
  33. package/main.ts +12 -0
  34. package/npm-upgrade.ts +117 -0
  35. package/package.json +83 -0
  36. package/resources/copy-prompt-reporter.ts +443 -0
  37. package/router.ts +220 -0
  38. package/setup/.claude/commands/commit-work.md +47 -0
  39. package/setup/.claude/commands/complete-work.md +34 -0
  40. package/setup/.claude/commands/e2e.md +29 -0
  41. package/setup/.claude/commands/start-work.md +51 -0
  42. package/setup/.claude/skills/pm/SKILL.md +294 -0
  43. package/setup/.claude/skills/pm/templates/api-endpoint.md +69 -0
  44. package/setup/.claude/skills/pm/templates/bug-fix.md +77 -0
  45. package/setup/.claude/skills/pm/templates/feature.md +87 -0
  46. package/setup/.claude/skills/pm/templates/ui-component.md +78 -0
  47. package/utils/change-select-render.tsx +44 -0
  48. package/utils/claude.ts +9 -0
  49. package/utils/config.ts +58 -0
  50. package/utils/env.ts +53 -0
  51. package/utils/git.ts +120 -0
  52. package/utils/ink-render.tsx +50 -0
  53. package/utils/openspec.ts +54 -0
  54. package/utils/output.ts +104 -0
  55. package/utils/proposal.ts +160 -0
  56. package/utils/resources.ts +64 -0
  57. package/utils/setup-files.ts +230 -0
package/router.ts ADDED
@@ -0,0 +1,220 @@
1
+ import { handleBunUpgrade } from './commands/bun.ts';
2
+ import { handleChanges } from './commands/changes.ts';
3
+ import { handleE2e } from './commands/e2e.ts';
4
+ import { handleHelp } from './commands/help.ts';
5
+ import { handleInstallExtension } from './commands/install-extension.ts';
6
+ import { handleJira } from './commands/jira.ts';
7
+ import { handleLicenses } from './commands/licenses.ts';
8
+ import { handleNpmUpgrade } from './commands/npm.ts';
9
+ import { handleScaffold } from './commands/scaffold.ts';
10
+ import { handleSetup } from './commands/setup.tsx';
11
+ import {
12
+ handleCommitApply,
13
+ handleCommitSave,
14
+ handleSpecApply,
15
+ handleSpecArchive,
16
+ handleSpecPropose,
17
+ } from './commands/spec.ts';
18
+ import { handleStopHook } from './commands/stop-hook.ts';
19
+ import { handleTodo } from './commands/todo.ts';
20
+ import { handleVersionsPush, handleVersionsReset } from './commands/versions.ts';
21
+ import { handleWatch } from './commands/watch.ts';
22
+ import { handleWorktree } from './commands/worktree.ts';
23
+ import { error } from './utils/output.ts';
24
+
25
+ /**
26
+ * Route command-line arguments to the appropriate command handler.
27
+ * Parses the command structure and delegates to command modules.
28
+ *
29
+ * @param args - Command-line arguments (excluding node executable and script path)
30
+ * @returns Exit code (0 for success, 1 for error)
31
+ */
32
+ export async function route(args: string[]): Promise<number> {
33
+ // Handle no arguments - show help
34
+ if (args.length === 0) {
35
+ return await handleHelp();
36
+ }
37
+
38
+ const [command, subcommand] = args;
39
+
40
+ // Handle --help and -h flags
41
+ if (command === '--help' || command === '-h') {
42
+ return await handleHelp();
43
+ }
44
+
45
+ // Handle command-specific --help flag
46
+ if (subcommand === '--help' || subcommand === '-h') {
47
+ return await handleHelp(command);
48
+ }
49
+
50
+ // Route npm commands
51
+ if (command === 'npm') {
52
+ if (subcommand === 'upgrade') {
53
+ return await handleNpmUpgrade();
54
+ } else if (!subcommand) {
55
+ error('Error: npm command requires a subcommand');
56
+ console.error("Run 'af help npm' for more information.");
57
+ return 1;
58
+ } else {
59
+ error(`Error: Unknown npm subcommand: ${subcommand}`);
60
+ console.error("Run 'af help npm' for available subcommands.");
61
+ return 1;
62
+ }
63
+ }
64
+
65
+ // Route bun commands
66
+ if (command === 'bun') {
67
+ if (subcommand === 'upgrade') {
68
+ return await handleBunUpgrade();
69
+ } else if (!subcommand) {
70
+ error('Error: bun command requires a subcommand');
71
+ console.error("Run 'af help bun' for more information.");
72
+ return 1;
73
+ } else {
74
+ error(`Error: Unknown bun subcommand: ${subcommand}`);
75
+ console.error("Run 'af help bun' for available subcommands.");
76
+ return 1;
77
+ }
78
+ }
79
+
80
+ // Route spec commands
81
+ if (command === 'spec') {
82
+ if (subcommand === 'apply') {
83
+ const changeId = args[2];
84
+ return await handleSpecApply(changeId);
85
+ } else if (subcommand === 'archive') {
86
+ const specId = args[2];
87
+ return await handleSpecArchive(specId);
88
+ } else if (subcommand === 'propose') {
89
+ const proposalText = args.slice(2).join(' ');
90
+ return await handleSpecPropose(proposalText);
91
+ } else if (!subcommand) {
92
+ error('Error: spec command requires a subcommand');
93
+ console.error("Run 'af help spec' for more information.");
94
+ return 1;
95
+ } else {
96
+ error(`Error: Unknown spec subcommand: ${subcommand}`);
97
+ console.error("Run 'af help spec' for available subcommands.");
98
+ return 1;
99
+ }
100
+ }
101
+
102
+ // Route commit commands
103
+ if (command === 'commit') {
104
+ if (subcommand === 'save') {
105
+ // commit save "<message>" [Key=Value...]
106
+ const message = args[2];
107
+ const trailerArgs = args.slice(3);
108
+ return handleCommitSave(message, trailerArgs);
109
+ } else if (subcommand === 'apply' || !subcommand) {
110
+ // Both 'commit apply' and 'commit' (shorthand) do the same thing
111
+ const changeId = subcommand === 'apply' ? args[2] : args[1];
112
+ return await handleCommitApply(changeId);
113
+ } else {
114
+ error(`Error: Unknown commit subcommand: ${subcommand}`);
115
+ console.error("Run 'af help commit' for available subcommands.");
116
+ return 1;
117
+ }
118
+ }
119
+
120
+ // Route shorthand commands
121
+ if (command === 'apply') {
122
+ const changeId = args[1];
123
+ return await handleSpecApply(changeId);
124
+ }
125
+
126
+ if (command === 'propose') {
127
+ const proposalText = args.slice(1).join(' ');
128
+ return await handleSpecPropose(proposalText);
129
+ }
130
+
131
+ if (command === 'archive') {
132
+ const specId = args[1];
133
+ return await handleSpecArchive(specId);
134
+ }
135
+
136
+ if (command === 'changes') {
137
+ // Pass true if any additional arguments were provided
138
+ const hasArgs = args.length > 1;
139
+ return await handleChanges(hasArgs);
140
+ }
141
+
142
+ // Route e2e command
143
+ if (command === 'e2e') {
144
+ return await handleE2e(args.slice(1));
145
+ }
146
+
147
+ // Route stop-hook command
148
+ if (command === 'stop-hook') {
149
+ return await handleStopHook();
150
+ }
151
+
152
+ if (command === 'todo') {
153
+ // Pass true if any additional arguments were provided
154
+ const hasArgs = args.length > 1;
155
+ return await handleTodo(hasArgs);
156
+ }
157
+
158
+ if (command === 'watch') {
159
+ // Pass true if any additional arguments were provided
160
+ const hasArgs = args.length > 1;
161
+ return await handleWatch(hasArgs);
162
+ }
163
+
164
+ // Route jira commands
165
+ if (command === 'jira') {
166
+ return await handleJira(args.slice(1));
167
+ }
168
+
169
+ // Route versions commands
170
+ if (command === 'versions') {
171
+ if (subcommand === 'reset') {
172
+ return await handleVersionsReset();
173
+ } else if (subcommand === 'push') {
174
+ return await handleVersionsPush();
175
+ } else if (!subcommand) {
176
+ error('Error: versions command requires a subcommand');
177
+ console.error("Run 'af help versions' for more information.");
178
+ return 1;
179
+ } else {
180
+ error(`Error: Unknown versions subcommand: ${subcommand}`);
181
+ console.error("Run 'af help versions' for available subcommands.");
182
+ return 1;
183
+ }
184
+ }
185
+
186
+ // Route help command
187
+ if (command === 'help') {
188
+ return await handleHelp(subcommand);
189
+ }
190
+
191
+ // Route licenses command
192
+ if (command === 'licenses') {
193
+ return await handleLicenses();
194
+ }
195
+
196
+ // Route scaffold command
197
+ if (command === 'scaffold') {
198
+ return handleScaffold(args.slice(1));
199
+ }
200
+
201
+ // Route setup command
202
+ if (command === 'setup') {
203
+ return await handleSetup(args.slice(1));
204
+ }
205
+
206
+ // Route install-extension command
207
+ if (command === 'install-extension') {
208
+ return await handleInstallExtension();
209
+ }
210
+
211
+ // Route worktree command
212
+ if (command === 'worktree') {
213
+ return await handleWorktree(args.slice(1));
214
+ }
215
+
216
+ // Unknown command
217
+ error(`Error: Unknown command: ${command}`);
218
+ console.error("Run 'af help' to see all available commands.");
219
+ return 1;
220
+ }
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: Commit Work
3
+ description: Commit all changes with the OpenSpec proposal title and ID as a trailer.
4
+ category: Workflow
5
+ tags: [git, openspec, workflow]
6
+ ---
7
+
8
+ **Usage**
9
+
10
+ ```
11
+ /commit-work [openspec-id] [title]
12
+ ```
13
+
14
+ Examples:
15
+ - `/commit-work` — Uses the ID and title from context
16
+ - `/commit-work add-user-auth "Add User Authentication"` — Uses provided arguments
17
+
18
+ **Steps**
19
+
20
+ 1. **Determine OpenSpec ID and title:**
21
+ - If arguments are provided, use them
22
+ - If you are currently working on an OpenSpec, use that ID and title
23
+ - Otherwise:
24
+ 1. Run `openspec list` to find active changes
25
+ 2. If exactly one active change exists, use that ID
26
+ 3. If multiple changes exist, ask the user which one to use
27
+ 4. If no changes exist, ask the user for the ID and title
28
+ 5. Extract the title from the first heading in `openspec/changes/<id>/proposal.md`
29
+
30
+ 2. **Archive the OpenSpec change (if not already archived):**
31
+ - Check if `openspec/changes/<id>/` directory exists
32
+ - If it exists, perform the OPSX archive workflow:
33
+ 1. Check artifact completion: `openspec status --change "<id>" --json`
34
+ 2. Check task completion: read `openspec/changes/<id>/tasks.md`, count `- [ ]` vs `- [x]`
35
+ 3. Check for delta specs at `openspec/changes/<id>/specs/` — if they exist, perform agent-driven sync to main specs (same as `/opsx:sync`)
36
+ 4. Archive: `mkdir -p openspec/changes/archive && mv openspec/changes/<id> openspec/changes/archive/YYYY-MM-DD-<id>`
37
+ 5. Ensure everything meets the project's formatting rules (run `bun run format` if needed)
38
+ - If the directory does not exist (already archived), skip this step
39
+
40
+ 3. Run the following command to stage all changes and create a commit:
41
+ ```bash
42
+ af commit save "<title>" OpenSpec-Id=<openspec-id>
43
+ ```
44
+
45
+ **Reference**
46
+
47
+ - Run `af help commit` for commit subcommand options
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Complete Work
3
+ description: Archive an OpenSpec change and transition the Jira issue to Done.
4
+ category: Workflow
5
+ tags: [jira, openspec, workflow]
6
+ ---
7
+
8
+ **Usage**
9
+
10
+ ```
11
+ /complete-work <issue-key>
12
+ ```
13
+
14
+ Example: `/complete-work MUSH-123`
15
+
16
+ **Steps**
17
+
18
+ 1. Fetch the issue details using `af jira get <issue-key>` to verify it exists and get the summary.
19
+ 2. Find the associated OpenSpec change by searching `openspec/changes/*/proposal.md` files for the issue key using grep or by running `openspec list` and checking which change references this issue.
20
+ 3. Archive the OpenSpec change using the OPSX workflow:
21
+ 1. Check artifact completion: `openspec status --change "<change-id>" --json`
22
+ - If incomplete artifacts, warn but continue
23
+ 2. Check task completion: read `openspec/changes/<change-id>/tasks.md`, count `- [ ]` vs `- [x]`
24
+ - If incomplete tasks, warn but continue
25
+ 3. Check for delta specs at `openspec/changes/<change-id>/specs/`
26
+ - If delta specs exist, perform agent-driven sync to main specs (same as `/opsx:sync`)
27
+ 4. Archive: `mkdir -p openspec/changes/archive && mv openspec/changes/<change-id> openspec/changes/archive/YYYY-MM-DD-<change-id>`
28
+ 4. Run the following command: `./scripts/create-commit.sh "<issue-summary>" "<issue-key>"` where `<issue-summary>` is derived from the Jira issue. This adds the issue key as a commit trailer.
29
+ 6. Transition the issue to "Done" using `af jira transition <issue-key> --to "Done"`. If this fails, run `af jira transitions <issue-key>` to find the correct completion status name.
30
+
31
+ **Reference**
32
+
33
+ - See `openspec/AGENTS.md` for OpenSpec conventions (Stage 3: Archiving Changes)
34
+ - Run `af jira --help` for Jira CLI options
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: Run E2E tests
3
+ description: Run E2E tests and fix any failures
4
+ category: Testing
5
+ tags: [e2e, playwright]
6
+ ---
7
+
8
+ **Guardrails**
9
+
10
+ - Run only inside Docker via `af e2e` — never run Playwright directly
11
+ - For specific tests: `af e2e npm run e2e -- --grep "pattern"`
12
+ - For specific files: `af e2e npm run e2e -- tests/Feature.spec.ts`
13
+
14
+ **Steps**
15
+
16
+ 1. Run `af e2e` (defaults to `--max-failures=1` for fast feedback)
17
+ 2. On failure, read the reporter output — it includes error messages, DOM snapshots, and file paths
18
+ 3. For deeper debugging, read `./test-results/*/error-context.md` for full page state
19
+ 4. Fix the code or test
20
+ 5. If the failure is a visual regression from an intentional change, update baselines:
21
+ `af e2e npm run e2e -- --update-snapshots`
22
+ 6. Use `--grep "pattern"` to iterate faster on the specific failing test
23
+ 7. Once the targeted test passes, run the full suite without `--grep` to confirm nothing else broke
24
+
25
+ **Reference**
26
+
27
+ - Use the `e2e-testing` skill for test patterns, selectors, and debugging tips
28
+ - HTML report: `./playwright-report/index.html`
29
+ - Trace files: `./test-results/*/trace.zip`
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: Start Work
3
+ description: Assign a Jira issue to yourself and convert it into an OpenSpec proposal.
4
+ category: Workflow
5
+ tags: [jira, openspec, workflow]
6
+ ---
7
+
8
+ **Usage**
9
+
10
+ ```
11
+ /start-work [issue-key]
12
+ ```
13
+
14
+ Examples:
15
+ - `/start-work` — Takes the topmost issue from the backlog
16
+ - `/start-work MUSH-123` — Uses the specified issue
17
+
18
+ **Steps**
19
+
20
+ 0. **If no issue-key is provided**, fetch the topmost issue from the backlog:
21
+ 1. Detect project key by running `af jira projects --json`
22
+ - If single project: use it
23
+ - If multiple projects: ask the user to choose
24
+ 2. Fetch the topmost backlog issue using:
25
+ ```bash
26
+ af jira search "project = <PROJECT> AND status = Backlog ORDER BY priority DESC, created ASC" --limit 1 --json
27
+ ```
28
+ 3. Display the issue summary and ask the user for confirmation before proceeding
29
+ 4. If no backlog issues found: inform the user the backlog is empty and stop
30
+ 1. Fetch the issue details using `af jira get <issue-key>`.
31
+ 2. Assign the issue to yourself using `af jira assign <issue-key> --to $(af jira get <issue-key> --json | jq -r '.reporter.emailAddress')` — but first check who the current user is by looking at the Jira config or asking.
32
+ 3. Transition the issue to "In Progress" using `af jira transition <issue-key> --to "In Progress"`. If this fails, run `af jira transitions <issue-key>` to find the correct status name.
33
+ 4. Create an OpenSpec change using the artifact workflow:
34
+ - Derive a `change-id` from the issue key and summary (kebab-case, verb-led)
35
+ - Create the change: `openspec new change "<change-id>"`
36
+ - Get the artifact status: `openspec status --change "<change-id>" --json`
37
+ - Get proposal artifact instructions: `openspec instructions proposal --change "<change-id>" --json`
38
+ - Create the proposal artifact using the template from instructions, enriching it with:
39
+ - Jira issue link: `**Jira**: [ISSUE-KEY](jira-url)`
40
+ - Why section derived from Jira issue description
41
+ - What Changes derived from issue details
42
+ - Show the updated status
43
+ 5. **STOP and hand off to OPSX workflow**
44
+
45
+ Suggest: "Proposal created. Run `/opsx:continue` to create the next artifact, or `/opsx:ff` to generate all remaining artifacts."
46
+
47
+ **Reference**
48
+
49
+ - See `openspec/AGENTS.md` for OpenSpec conventions
50
+ - Run `af jira --help` for Jira CLI options
51
+ - See `/opsx:new` and `/opsx:ff` for the full artifact workflow
@@ -0,0 +1,294 @@
1
+ ---
2
+ name: pm
3
+ description: Project management workflows for sprint planning, epic breakdowns, progress reporting, and backlog grooming. Uses the jira skill for all Jira operations.
4
+ ---
5
+
6
+ # Project Manager Skill
7
+
8
+ High-level project management workflows that use the Jira CLI (`jira` skill) for operations.
9
+
10
+ ## When to Use This Skill
11
+
12
+ Use the PM skill when the user wants to:
13
+ - Plan sprints or prioritize backlog items
14
+ - Break down epics or features into tasks
15
+ - Generate progress reports or standup summaries
16
+ - Identify risks (overdue, blocked, stale issues)
17
+ - Get project context for informed planning decisions
18
+ - Groom or refine the backlog
19
+
20
+ For individual issue operations (get, update, transition, comment), use the `jira` skill directly.
21
+
22
+ ## Prerequisites
23
+
24
+ The `jira` skill must be configured. See `.claude/skills/jira/SKILL.md` for setup.
25
+
26
+ ## Sub-Agent Behavior
27
+
28
+ When acting as a PM sub-agent, follow these guidelines:
29
+
30
+ ### 1. Always Load Context First
31
+
32
+ Before planning or making recommendations, gather project state:
33
+
34
+ ```bash
35
+ # Get open sprint issues
36
+ af jira search "project = PROJ AND sprint in openSprints() ORDER BY priority DESC"
37
+
38
+ # Check for blockers
39
+ af jira search "project = PROJ AND (status = Blocked OR labels = blocked)"
40
+
41
+ # Recent activity (last 48h)
42
+ af jira search "project = PROJ AND updated >= -2d ORDER BY updated DESC"
43
+ ```
44
+
45
+ ### 2. Use Templates for Consistency
46
+
47
+ When breaking down work, use templates from `.claude/skills/pm/templates/`:
48
+ - `api-endpoint.md` - REST/GraphQL endpoint implementation
49
+ - `ui-component.md` - React component development
50
+ - `bug-fix.md` - Bug investigation and fix
51
+ - `feature.md` - General feature implementation
52
+
53
+ ### 3. Validate Before Executing
54
+
55
+ For bulk operations (creating multiple issues, updating priorities):
56
+ 1. Show the user what will be created/modified
57
+ 2. Wait for confirmation before executing
58
+ 3. Execute one operation at a time, reporting progress
59
+
60
+ ### 4. Track Dependencies
61
+
62
+ When creating related tasks, use Jira linking:
63
+ - Parent/subtask relationships via `--parent` flag
64
+ - Note blocking relationships in descriptions
65
+
66
+ ### 5. Report on Completion
67
+
68
+ After multi-step workflows, provide a summary:
69
+ - What was created/modified
70
+ - Any issues encountered
71
+ - Next recommended actions
72
+
73
+ ## Workflows
74
+
75
+ ### Load Project Context
76
+
77
+ Gather comprehensive project state before planning:
78
+
79
+ ```bash
80
+ # 1. Active sprint overview
81
+ af jira search "project = PROJ AND sprint in openSprints() ORDER BY status ASC, priority DESC" --limit 50
82
+
83
+ # 2. Blocked issues requiring attention
84
+ af jira search "project = PROJ AND (status = Blocked OR labels = blocked) ORDER BY priority DESC"
85
+
86
+ # 3. Upcoming deadlines (next 7 days)
87
+ af jira search "project = PROJ AND duedate >= now() AND duedate <= 7d AND status != Done ORDER BY duedate ASC"
88
+
89
+ # 4. Unassigned high-priority items
90
+ af jira search "project = PROJ AND assignee IS EMPTY AND priority in (Highest, High) ORDER BY created ASC"
91
+ ```
92
+
93
+ Present findings organized by:
94
+ - Sprint progress (done/in-progress/todo counts)
95
+ - Blockers requiring attention
96
+ - Upcoming deadlines
97
+ - Unassigned work
98
+
99
+ ### Sprint Planning
100
+
101
+ Help plan upcoming sprints:
102
+
103
+ ```bash
104
+ # 1. Check current sprint velocity (completed in last sprint)
105
+ af jira search "project = PROJ AND sprint in closedSprints() AND status = Done ORDER BY resolutiondate DESC" --limit 30
106
+
107
+ # 2. Get backlog candidates (not in any sprint, prioritized)
108
+ af jira search "project = PROJ AND sprint IS EMPTY AND status = Backlog ORDER BY priority DESC, created ASC" --limit 30
109
+
110
+ # 3. Check team capacity (assigned work)
111
+ af jira search "project = PROJ AND assignee IS NOT EMPTY AND status != Done"
112
+ ```
113
+
114
+ Planning steps:
115
+ 1. Calculate velocity from recent sprints
116
+ 2. Present top backlog items with estimates
117
+ 3. Suggest sprint composition based on capacity
118
+ 4. Create issues or move items to sprint after confirmation
119
+
120
+ ### Epic Breakdown
121
+
122
+ Break down an epic into implementable tasks:
123
+
124
+ ```bash
125
+ # 1. Get epic details
126
+ af jira get PROJ-123
127
+
128
+ # 2. Check for existing subtasks
129
+ af jira search "parent = PROJ-123"
130
+ ```
131
+
132
+ Breakdown process:
133
+ 1. Read the epic description and acceptance criteria
134
+ 2. Select appropriate template from `.claude/skills/pm/templates/`
135
+ 3. Generate subtask list with estimates
136
+ 4. Present for review
137
+ 5. Create subtasks after confirmation:
138
+
139
+ ```bash
140
+ af jira create --project PROJ --type Sub-task --summary "Task title" --parent PROJ-123
141
+ ```
142
+
143
+ ### Progress Report
144
+
145
+ Generate status reports:
146
+
147
+ **Daily Report:**
148
+ ```bash
149
+ # Completed yesterday
150
+ af jira search "project = PROJ AND status changed to Done AFTER -1d"
151
+
152
+ # In progress today
153
+ af jira search "project = PROJ AND status = 'In Progress' ORDER BY assignee"
154
+
155
+ # Blocked
156
+ af jira search "project = PROJ AND (status = Blocked OR labels = blocked)"
157
+ ```
158
+
159
+ **Weekly Report:**
160
+ ```bash
161
+ # Completed this week
162
+ af jira search "project = PROJ AND status changed to Done AFTER -7d ORDER BY resolutiondate DESC"
163
+
164
+ # Created this week
165
+ af jira search "project = PROJ AND created >= -7d ORDER BY created DESC"
166
+
167
+ # Scope changes (added to sprint mid-week)
168
+ af jira search "project = PROJ AND sprint in openSprints() AND created >= -7d"
169
+ ```
170
+
171
+ **Sprint Report:**
172
+ ```bash
173
+ # Sprint completion
174
+ af jira search "project = PROJ AND sprint in openSprints()" --limit 100
175
+
176
+ # Calculate: done / total issues
177
+ # Identify: carried over items, added mid-sprint items
178
+ ```
179
+
180
+ ### Standup Summary
181
+
182
+ Generate daily standup content from Jira activity:
183
+
184
+ ```bash
185
+ # Done (status changed to Done in last 24h)
186
+ af jira search "project = PROJ AND status changed to Done AFTER -1d"
187
+
188
+ # In Progress (currently being worked on)
189
+ af jira search "project = PROJ AND status = 'In Progress' AND assignee = currentUser()"
190
+
191
+ # Blockers
192
+ af jira search "project = PROJ AND (status = Blocked OR labels = blocked) AND assignee = currentUser()"
193
+ ```
194
+
195
+ Format as:
196
+ - **Done**: [list of completed items]
197
+ - **Today**: [list of in-progress items]
198
+ - **Blockers**: [list of blocked items with reasons]
199
+
200
+ ### Risk Identification
201
+
202
+ Find issues that need attention:
203
+
204
+ ```bash
205
+ # Overdue (past due date, not done)
206
+ af jira search "project = PROJ AND duedate < now() AND status != Done ORDER BY duedate ASC"
207
+
208
+ # Stale (no updates in 7+ days, not done)
209
+ af jira search "project = PROJ AND status != Done AND updated < -7d ORDER BY updated ASC"
210
+
211
+ # Blocked
212
+ af jira search "project = PROJ AND (status = Blocked OR labels = blocked)"
213
+
214
+ # Scope creep (added to sprint after start)
215
+ af jira search "project = PROJ AND sprint in openSprints() AND created >= startOfSprint()"
216
+
217
+ # Under-resourced (unassigned high priority)
218
+ af jira search "project = PROJ AND assignee IS EMPTY AND priority in (Highest, High) AND status != Done"
219
+ ```
220
+
221
+ Categorize and present:
222
+ - **Critical**: Overdue items, high-priority blockers
223
+ - **Warning**: Stale items, scope creep indicators
224
+ - **Attention**: Unassigned high-priority work
225
+
226
+ ### Backlog Grooming
227
+
228
+ Help prioritize and refine backlog:
229
+
230
+ ```bash
231
+ # Get backlog items
232
+ af jira search "project = PROJ AND sprint IS EMPTY AND status = Backlog ORDER BY created ASC" --limit 50
233
+
234
+ # Check for duplicates or related items
235
+ af jira search "project = PROJ AND summary ~ 'keyword'"
236
+ ```
237
+
238
+ Grooming activities:
239
+ 1. Review items for clarity and completeness
240
+ 2. Suggest priority adjustments based on:
241
+ - Age (older items may need re-evaluation)
242
+ - Dependencies (blocking other work)
243
+ - Business value indicators in description
244
+ 3. Identify candidates for archiving (very old, low priority)
245
+ 4. Flag items needing more detail
246
+
247
+ To update priority after confirmation:
248
+ ```bash
249
+ af jira update PROJ-123 --priority High
250
+ ```
251
+
252
+ ### Dependency Analysis
253
+
254
+ Map dependencies for an issue:
255
+
256
+ ```bash
257
+ # Get issue with links
258
+ af jira get PROJ-123
259
+
260
+ # Find related issues by summary/labels
261
+ af jira search "project = PROJ AND (summary ~ 'related-keyword' OR labels = related-label)"
262
+
263
+ # Find potential blockers (same component, earlier in pipeline)
264
+ af jira search "project = PROJ AND component = 'Component' AND status != Done"
265
+ ```
266
+
267
+ Present as:
268
+ - **Blocks**: Issues this blocks
269
+ - **Blocked by**: Issues blocking this
270
+ - **Related**: Similar or dependent work
271
+
272
+ ## JQL Quick Reference
273
+
274
+ Common queries for project management:
275
+
276
+ | Purpose | JQL |
277
+ |---------|-----|
278
+ | My open issues | `assignee = currentUser() AND status != Done` |
279
+ | Open sprint | `project = PROJ AND sprint in openSprints()` |
280
+ | Blocked | `project = PROJ AND (status = Blocked OR labels = blocked)` |
281
+ | Overdue | `project = PROJ AND duedate < now() AND status != Done` |
282
+ | Stale (7d) | `project = PROJ AND status != Done AND updated < -7d` |
283
+ | Unassigned | `project = PROJ AND assignee IS EMPTY` |
284
+ | High priority | `project = PROJ AND priority in (Highest, High)` |
285
+ | Created this week | `project = PROJ AND created >= -7d` |
286
+ | Done this week | `project = PROJ AND status changed to Done AFTER -7d` |
287
+ | Backlog | `project = PROJ AND sprint IS EMPTY AND status = Backlog` |
288
+
289
+ ## Tips
290
+
291
+ - **Replace PROJ**: Substitute with actual project key in all queries
292
+ - **Adjust time ranges**: `-7d`, `-2d`, etc. can be customized
293
+ - **Use --json for parsing**: When you need to analyze results programmatically
294
+ - **Combine with jira**: This skill provides workflows; jira provides operations