planflow-plugin 0.1.0

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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/bin/cli.js +169 -0
  4. package/bin/postinstall.js +87 -0
  5. package/commands/pfActivity/SKILL.md +725 -0
  6. package/commands/pfAssign/SKILL.md +623 -0
  7. package/commands/pfCloudLink/SKILL.md +192 -0
  8. package/commands/pfCloudList/SKILL.md +222 -0
  9. package/commands/pfCloudNew/SKILL.md +187 -0
  10. package/commands/pfCloudUnlink/SKILL.md +152 -0
  11. package/commands/pfComment/SKILL.md +227 -0
  12. package/commands/pfComments/SKILL.md +159 -0
  13. package/commands/pfConnectionStatus/SKILL.md +433 -0
  14. package/commands/pfDiscord/SKILL.md +740 -0
  15. package/commands/pfGithubBranch/SKILL.md +672 -0
  16. package/commands/pfGithubIssue/SKILL.md +963 -0
  17. package/commands/pfGithubLink/SKILL.md +859 -0
  18. package/commands/pfGithubPr/SKILL.md +1335 -0
  19. package/commands/pfGithubUnlink/SKILL.md +401 -0
  20. package/commands/pfLive/SKILL.md +185 -0
  21. package/commands/pfLogin/SKILL.md +249 -0
  22. package/commands/pfLogout/SKILL.md +155 -0
  23. package/commands/pfMyTasks/SKILL.md +198 -0
  24. package/commands/pfNotificationSettings/SKILL.md +619 -0
  25. package/commands/pfNotifications/SKILL.md +420 -0
  26. package/commands/pfNotificationsClear/SKILL.md +421 -0
  27. package/commands/pfReact/SKILL.md +232 -0
  28. package/commands/pfSlack/SKILL.md +659 -0
  29. package/commands/pfSyncPull/SKILL.md +210 -0
  30. package/commands/pfSyncPush/SKILL.md +299 -0
  31. package/commands/pfSyncStatus/SKILL.md +212 -0
  32. package/commands/pfTeamInvite/SKILL.md +161 -0
  33. package/commands/pfTeamList/SKILL.md +253 -0
  34. package/commands/pfTeamRemove/SKILL.md +115 -0
  35. package/commands/pfTeamRole/SKILL.md +160 -0
  36. package/commands/pfTestWebhooks/SKILL.md +722 -0
  37. package/commands/pfUnassign/SKILL.md +134 -0
  38. package/commands/pfWhoami/SKILL.md +258 -0
  39. package/commands/pfWorkload/SKILL.md +219 -0
  40. package/commands/planExportCsv/SKILL.md +106 -0
  41. package/commands/planExportGithub/SKILL.md +222 -0
  42. package/commands/planExportJson/SKILL.md +159 -0
  43. package/commands/planExportSummary/SKILL.md +158 -0
  44. package/commands/planNew/SKILL.md +641 -0
  45. package/commands/planNext/SKILL.md +1200 -0
  46. package/commands/planSettingsAutoSync/SKILL.md +199 -0
  47. package/commands/planSettingsLanguage/SKILL.md +201 -0
  48. package/commands/planSettingsReset/SKILL.md +237 -0
  49. package/commands/planSettingsShow/SKILL.md +482 -0
  50. package/commands/planSpec/SKILL.md +929 -0
  51. package/commands/planUpdate/SKILL.md +2518 -0
  52. package/commands/team/SKILL.md +740 -0
  53. package/locales/en.json +1499 -0
  54. package/locales/ka.json +1499 -0
  55. package/package.json +48 -0
  56. package/templates/PROJECT_PLAN.template.md +157 -0
  57. package/templates/backend-api.template.md +562 -0
  58. package/templates/frontend-spa.template.md +610 -0
  59. package/templates/fullstack.template.md +397 -0
  60. package/templates/ka/backend-api.template.md +562 -0
  61. package/templates/ka/frontend-spa.template.md +610 -0
  62. package/templates/ka/fullstack.template.md +397 -0
  63. package/templates/sections/architecture.md +21 -0
  64. package/templates/sections/overview.md +15 -0
  65. package/templates/sections/tasks.md +22 -0
  66. package/templates/sections/tech-stack.md +19 -0
@@ -0,0 +1,1200 @@
1
+ ---
2
+ name: planNext
3
+ description: Plan Next Task Recommendation
4
+ ---
5
+
6
+ # Plan Next Task Recommendation
7
+
8
+ You are an intelligent task prioritization assistant. Your role is to analyze the project plan and recommend the best next task to work on.
9
+
10
+ ## Objective
11
+
12
+ Analyze PROJECT_PLAN.md to find the optimal next task based on dependencies, current phase, complexity, and project momentum.
13
+
14
+ ## Usage
15
+
16
+ ```bash
17
+ /planNext
18
+ ```
19
+
20
+ No arguments needed - analyzes the entire project state.
21
+
22
+ ## Process
23
+
24
+ ### Step 0: Load User Language & Translations
25
+
26
+ **CRITICAL: Execute this step FIRST, before any output!**
27
+
28
+ Load user's language preference using hierarchical config (local → global → default) and translation file.
29
+
30
+ **Pseudo-code:**
31
+ ```javascript
32
+ // Read config with hierarchy (v1.1.1+)
33
+ function getConfig() {
34
+ // Try local config first
35
+ if (fileExists("./.plan-config.json")) {
36
+ try {
37
+ return JSON.parse(readFile("./.plan-config.json"))
38
+ } catch (error) {}
39
+ }
40
+
41
+ // Fall back to global config
42
+ const globalPath = expandPath("~/.config/claude/plan-plugin-config.json")
43
+ if (fileExists(globalPath)) {
44
+ try {
45
+ return JSON.parse(readFile(globalPath))
46
+ } catch (error) {}
47
+ }
48
+
49
+ // Fall back to defaults
50
+ return { "language": "en" }
51
+ }
52
+
53
+ const config = getConfig()
54
+ const language = config.language || "en"
55
+
56
+ // Cloud config (v1.2.0+) - MERGE global and local configs
57
+ function getMergedConfig() {
58
+ let globalConfig = {}
59
+ let localConfig = {}
60
+
61
+ const globalPath = expandPath("~/.config/claude/plan-plugin-config.json")
62
+ if (fileExists(globalPath)) {
63
+ try { globalConfig = JSON.parse(readFile(globalPath)) } catch (e) {}
64
+ }
65
+
66
+ if (fileExists("./.plan-config.json")) {
67
+ try { localConfig = JSON.parse(readFile("./.plan-config.json")) } catch (e) {}
68
+ }
69
+
70
+ return {
71
+ ...globalConfig,
72
+ ...localConfig,
73
+ cloud: {
74
+ ...(globalConfig.cloud || {}),
75
+ ...(localConfig.cloud || {})
76
+ }
77
+ }
78
+ }
79
+
80
+ const mergedConfig = getMergedConfig()
81
+ const cloudConfig = mergedConfig.cloud || {}
82
+ const isAuthenticated = !!cloudConfig.apiToken
83
+ const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
84
+ const autoSync = cloudConfig.autoSync || false
85
+ const projectId = cloudConfig.projectId || null
86
+ const currentUserEmail = cloudConfig.userEmail || null
87
+
88
+ // Load translations
89
+ const translationPath = `locales/${language}.json`
90
+ const t = JSON.parse(readFile(translationPath))
91
+ ```
92
+
93
+ **Instructions for Claude:**
94
+
95
+ 1. Try to read `./.plan-config.json` (local, highest priority)
96
+ 2. If not found/corrupted, try `~/.config/claude/plan-plugin-config.json` (global)
97
+ 3. If not found/corrupted, use default: `language = "en"`
98
+ 4. Use Read tool: `locales/{language}.json`
99
+ 5. Store as `t` variable
100
+
101
+ ### Step 0.5: Show Notification Badge (v1.6.0+)
102
+
103
+ **Purpose:** Display unread notification count to keep users informed of team activity.
104
+
105
+ **When to Execute:** Only if authenticated AND linked to a project.
106
+
107
+ **Pseudo-code:**
108
+ ```javascript
109
+ async function showNotificationBadge(cloudConfig, t) {
110
+ // Skip if not authenticated or not linked
111
+ if (!cloudConfig.apiToken || !cloudConfig.projectId) {
112
+ return // Silently skip
113
+ }
114
+
115
+ const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
116
+
117
+ try {
118
+ // Fetch unread count (lightweight call with short timeout)
119
+ const response = await fetch(
120
+ `${apiUrl}/projects/${cloudConfig.projectId}/notifications?limit=1&unread=true`,
121
+ {
122
+ method: "GET",
123
+ headers: {
124
+ "Authorization": `Bearer ${cloudConfig.apiToken}`,
125
+ "Accept": "application/json"
126
+ },
127
+ timeout: 5000 // 5 second max
128
+ }
129
+ )
130
+
131
+ if (response.ok) {
132
+ const data = response.data
133
+ const unreadCount = data.unreadCount || 0
134
+
135
+ if (unreadCount > 0) {
136
+ // Display badge
137
+ const label = unreadCount === 1
138
+ ? t.skills.notificationBadge.unreadOne
139
+ : t.skills.notificationBadge.unreadMultiple
140
+ console.log(`🔔 ${unreadCount} ${label} — /pfNotifications ${t.skills.notificationBadge.toView}`)
141
+ console.log("") // Blank line before main output
142
+ }
143
+ }
144
+ } catch (error) {
145
+ // Silently fail - don't block the command
146
+ }
147
+ }
148
+ ```
149
+
150
+ **Bash Implementation:**
151
+ ```bash
152
+ API_URL="https://api.planflow.tools"
153
+ TOKEN="$API_TOKEN"
154
+ PROJECT_ID="$PROJECT_ID"
155
+
156
+ # Only proceed if authenticated and linked
157
+ if [ -n "$TOKEN" ] && [ -n "$PROJECT_ID" ]; then
158
+ # Fetch unread count with short timeout
159
+ RESPONSE=$(curl -s --connect-timeout 3 --max-time 5 \
160
+ -X GET \
161
+ -H "Accept: application/json" \
162
+ -H "Authorization: Bearer $TOKEN" \
163
+ "${API_URL}/projects/${PROJECT_ID}/notifications?limit=1&unread=true" 2>/dev/null)
164
+
165
+ if [ $? -eq 0 ]; then
166
+ UNREAD_COUNT=$(echo "$RESPONSE" | grep -o '"unreadCount":[0-9]*' | grep -o '[0-9]*')
167
+ if [ -n "$UNREAD_COUNT" ] && [ "$UNREAD_COUNT" -gt 0 ]; then
168
+ echo "🔔 $UNREAD_COUNT unread notification(s) — /pfNotifications to view"
169
+ echo ""
170
+ fi
171
+ fi
172
+ fi
173
+ ```
174
+
175
+ **Example Output (if 3 unread):**
176
+ ```
177
+ 🔔 3 unread notifications — /pfNotifications to view
178
+
179
+ ╭──────────────────────────────────────────────────────────────────────────────╮
180
+ │ 🎯 Recommended Next Task │
181
+ ...
182
+ ```
183
+
184
+ **Instructions for Claude:**
185
+
186
+ 1. After loading config and translations (Step 0), check if `cloudConfig.apiToken` AND `cloudConfig.projectId` exist
187
+ 2. If yes, make a quick API call to fetch notification count
188
+ 3. If unreadCount > 0, display the badge line with a blank line after
189
+ 4. If any error occurs (timeout, network, auth), silently skip and continue
190
+ 5. Proceed to Step 1 regardless of badge result
191
+
192
+ **Important:** Never let this step block or delay the main command. Use short timeouts and fail silently.
193
+
194
+ ### Step 1: Read PROJECT_PLAN.md
195
+
196
+ Use the Read tool to read PROJECT_PLAN.md from the current working directory.
197
+
198
+ If file doesn't exist, output:
199
+ ```
200
+ {t.commands.update.planNotFound}
201
+
202
+ {t.commands.update.runPlanNew}
203
+ ```
204
+
205
+ **Example:**
206
+ - EN: "❌ Error: PROJECT_PLAN.md not found in current directory. Please run /planNew first to create a project plan."
207
+ - KA: "❌ შეცდომა: PROJECT_PLAN.md არ მოიძებნა მიმდინარე დირექტორიაში. გთხოვთ ჯერ გაუშვათ /planNew პროექტის გეგმის შესაქმნელად."
208
+
209
+ ### Step 2: Parse All Tasks
210
+
211
+ Extract all tasks with their properties:
212
+
213
+ For each task (`#### TX.Y: Task Name`), extract:
214
+ - **Task ID**: e.g., T1.1
215
+ - **Task Name**: e.g., "Project Setup"
216
+ - **Status**: TODO, IN_PROGRESS, DONE, BLOCKED
217
+ - **Complexity**: Low, Medium, High
218
+ - **Estimated**: Hours (e.g., "2 hours")
219
+ - **Dependencies**: List of task IDs or "None"
220
+ - **Phase**: Derived from task ID (T1.X = Phase 1, T2.X = Phase 2, etc.)
221
+ - **Description**: Task details
222
+
223
+ Create a mental model of all tasks.
224
+
225
+ ### Step 3: Filter Available Tasks
226
+
227
+ A task is **available** if:
228
+ 1. ✅ Status is TODO (not DONE, not IN_PROGRESS, not BLOCKED)
229
+ 2. ✅ All dependencies are completed (status = DONE)
230
+ 3. ✅ Task is in current phase or earlier incomplete phase
231
+
232
+ **Current Phase** = Lowest phase number that still has incomplete tasks
233
+
234
+ Example:
235
+ - Phase 1: 3/4 tasks done → Phase 1 is current
236
+ - Phase 2: 0/5 tasks done → Not current yet
237
+ - Phase 3: 0/3 tasks done → Not current yet
238
+
239
+ ### Step 4: Rank Available Tasks
240
+
241
+ Score each available task using multiple factors:
242
+
243
+ #### Factor 1: Phase Priority (Weight: 40%)
244
+ ```
245
+ Score = 100 if in current phase
246
+ Score = 50 if in next phase
247
+ Score = 0 if beyond next phase
248
+ ```
249
+
250
+ Complete earlier phases before starting later ones (mostly).
251
+
252
+ #### Factor 2: Dependency Impact (Weight: 30%)
253
+ ```
254
+ Count how many tasks depend on this task (directly or indirectly)
255
+ Score = (dependent_count / max_dependent_count) × 100
256
+ ```
257
+
258
+ Prioritize tasks that unlock many others (critical path).
259
+
260
+ #### Factor 3: Complexity Balance (Weight: 20%)
261
+ ```
262
+ Check recently completed tasks' complexity:
263
+ - If last task was High → prefer Low or Medium (Score: 100)
264
+ - If last task was Low → prefer Medium or High (Score: 100)
265
+ - Otherwise → Medium complexity gets Score: 100
266
+
267
+ Prevents burnout and maintains momentum.
268
+ ```
269
+
270
+ #### Factor 4: Natural Flow (Weight: 10%)
271
+ ```
272
+ Score = 100 if task ID is sequential (e.g., T1.1, T1.2, T1.3)
273
+ Score = 50 otherwise
274
+
275
+ Following sequential order often makes sense.
276
+ ```
277
+
278
+ #### Calculate Total Score
279
+ ```
280
+ Total = (Phase × 0.4) + (Dependencies × 0.3) + (Complexity × 0.2) + (Flow × 0.1)
281
+ ```
282
+
283
+ Sort tasks by total score (highest first).
284
+
285
+ ### Step 5: Select Top Recommendation
286
+
287
+ Pick the highest-scored task as the primary recommendation.
288
+
289
+ Also identify 2-3 alternative tasks (next highest scores).
290
+
291
+ ### Step 5.5: Fetch Task Assignments (v1.6.0+)
292
+
293
+ If authenticated and linked to a cloud project, fetch task assignments to show who is working on what.
294
+
295
+ **Pseudo-code:**
296
+ ```javascript
297
+ let taskAssignments = {} // Map of taskId -> assignee info
298
+
299
+ if (isAuthenticated && projectId) {
300
+ // Fetch tasks with assignments from cloud
301
+ const response = await fetch(
302
+ `${apiUrl}/projects/${projectId}/tasks`,
303
+ {
304
+ method: "GET",
305
+ headers: {
306
+ "Authorization": `Bearer ${cloudConfig.apiToken}`,
307
+ "Accept": "application/json"
308
+ }
309
+ }
310
+ )
311
+
312
+ if (response.ok) {
313
+ const data = response.data
314
+ const tasks = data.tasks || []
315
+
316
+ for (const task of tasks) {
317
+ if (task.assignee) {
318
+ taskAssignments[task.taskId] = {
319
+ email: task.assignee.email,
320
+ name: task.assignee.name || task.assignee.email,
321
+ isCurrentUser: task.assignee.email === currentUserEmail
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+ ```
328
+
329
+ **Bash Implementation:**
330
+ ```bash
331
+ API_URL="https://api.planflow.tools"
332
+ TOKEN="$API_TOKEN"
333
+ PROJECT_ID="$PROJECT_ID"
334
+
335
+ # Fetch tasks with assignments
336
+ RESPONSE=$(curl -s \
337
+ --connect-timeout 5 \
338
+ --max-time 10 \
339
+ -X GET \
340
+ -H "Accept: application/json" \
341
+ -H "Authorization: Bearer $TOKEN" \
342
+ "${API_URL}/projects/${PROJECT_ID}/tasks")
343
+
344
+ # Parse assignee info from response
345
+ # Each task has: taskId, assignee: { email, name }
346
+ ```
347
+
348
+ **Instructions for Claude:**
349
+
350
+ 1. Only fetch assignments if authenticated AND projectId exists
351
+ 2. Use a short timeout (5s connect, 10s max) to avoid blocking
352
+ 3. If fetch fails, continue without assignments (graceful degradation)
353
+ 4. Store assignments in a map for quick lookup by taskId
354
+ 5. Track if assignee is the current user for special messaging
355
+
356
+ ### Step 5.6: Fetch GitHub Status (v1.6.0+ - T13.6)
357
+
358
+ If authenticated, linked to a cloud project, and GitHub is integrated, fetch GitHub-related data for tasks (branches, issues, PRs).
359
+
360
+ **Pseudo-code:**
361
+ ```javascript
362
+ let githubIntegration = null // GitHub integration info
363
+ let taskGithubStatus = {} // Map of taskId -> { branch, issue, pr }
364
+
365
+ if (isAuthenticated && projectId) {
366
+ // Step 1: Check if GitHub is integrated
367
+ const integrationResponse = await fetch(
368
+ `${apiUrl}/projects/${projectId}/integrations/github`,
369
+ {
370
+ method: "GET",
371
+ headers: {
372
+ "Authorization": `Bearer ${cloudConfig.apiToken}`,
373
+ "Accept": "application/json"
374
+ },
375
+ timeout: 5000
376
+ }
377
+ )
378
+
379
+ if (integrationResponse.ok) {
380
+ const data = integrationResponse.data
381
+ if (data.owner && data.repo) {
382
+ githubIntegration = {
383
+ owner: data.owner,
384
+ repo: data.repo,
385
+ url: `https://github.com/${data.owner}/${data.repo}`
386
+ }
387
+
388
+ // Step 2: Fetch GitHub status for all tasks
389
+ const githubStatusResponse = await fetch(
390
+ `${apiUrl}/projects/${projectId}/github/status`,
391
+ {
392
+ method: "GET",
393
+ headers: {
394
+ "Authorization": `Bearer ${cloudConfig.apiToken}`,
395
+ "Accept": "application/json"
396
+ },
397
+ timeout: 5000
398
+ }
399
+ )
400
+
401
+ if (githubStatusResponse.ok) {
402
+ const statusData = githubStatusResponse.data
403
+ const tasks = statusData.tasks || []
404
+
405
+ for (const task of tasks) {
406
+ taskGithubStatus[task.taskId] = {
407
+ branch: task.branch || null, // e.g., "feature/T2.1-implement-login"
408
+ issue: task.issue || null, // e.g., { number: 42, state: "open", url: "..." }
409
+ pr: task.pr || null // e.g., { number: 45, state: "open", url: "...", reviewStatus: "awaiting" }
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ ```
417
+
418
+ **Bash Implementation:**
419
+ ```bash
420
+ API_URL="https://api.planflow.tools"
421
+ TOKEN="$API_TOKEN"
422
+ PROJECT_ID="$PROJECT_ID"
423
+
424
+ # Step 1: Check if GitHub is integrated
425
+ GITHUB_RESPONSE=$(curl -s --connect-timeout 3 --max-time 5 \
426
+ -X GET \
427
+ -H "Accept: application/json" \
428
+ -H "Authorization: Bearer $TOKEN" \
429
+ "${API_URL}/projects/${PROJECT_ID}/integrations/github" 2>/dev/null)
430
+
431
+ GITHUB_OWNER=$(echo "$GITHUB_RESPONSE" | jq -r '.data.owner // empty' 2>/dev/null)
432
+ GITHUB_REPO=$(echo "$GITHUB_RESPONSE" | jq -r '.data.repo // empty' 2>/dev/null)
433
+
434
+ if [ -n "$GITHUB_OWNER" ] && [ -n "$GITHUB_REPO" ]; then
435
+ GITHUB_LINKED=true
436
+
437
+ # Step 2: Fetch task GitHub status
438
+ STATUS_RESPONSE=$(curl -s --connect-timeout 3 --max-time 5 \
439
+ -X GET \
440
+ -H "Accept: application/json" \
441
+ -H "Authorization: Bearer $TOKEN" \
442
+ "${API_URL}/projects/${PROJECT_ID}/github/status" 2>/dev/null)
443
+
444
+ # Parse GitHub status for each task
445
+ # Response format: { tasks: [{ taskId, branch, issue: { number, state }, pr: { number, state, reviewStatus } }] }
446
+ fi
447
+ ```
448
+
449
+ **Fallback: Check Local Git Repository:**
450
+
451
+ If cloud GitHub status is unavailable, check for local branches:
452
+
453
+ ```bash
454
+ # Check if we're in a git repo and have branches for tasks
455
+ if git rev-parse --git-dir > /dev/null 2>&1; then
456
+ for TASK_ID in $RECOMMENDED_TASKS; do
457
+ # Check for branches matching pattern: feature/T1.1-*, feat/T1.1-*, T1.1-*
458
+ BRANCH=$(git branch --list "feature/${TASK_ID}-*" "feat/${TASK_ID}-*" "${TASK_ID}-*" 2>/dev/null | head -1 | sed 's/^[* ]*//')
459
+ if [ -n "$BRANCH" ]; then
460
+ TASK_BRANCHES["$TASK_ID"]="$BRANCH"
461
+ fi
462
+ done
463
+ fi
464
+ ```
465
+
466
+ **Instructions for Claude:**
467
+
468
+ 1. Only fetch GitHub status if authenticated AND projectId exists
469
+ 2. First check if GitHub is integrated (via `/integrations/github`)
470
+ 3. If integrated, fetch task-specific GitHub data (via `/github/status`)
471
+ 4. Use short timeouts (3s connect, 5s max) to avoid blocking
472
+ 5. If cloud fetch fails, try to detect local branches as fallback
473
+ 6. Store status in a map for quick lookup by taskId
474
+ 7. Continue without GitHub status if any step fails (graceful degradation)
475
+
476
+ ### Step 6: Generate Recommendation
477
+
478
+ Display a detailed recommendation using translations.
479
+
480
+ **Pseudo-code:**
481
+ ```javascript
482
+ const task = recommendedTask
483
+ const complexityText = t.templates.complexity[task.complexity.toLowerCase()]
484
+ // EN: "Low", "Medium", "High"
485
+ // KA: "დაბალი", "საშუალო", "მაღალი"
486
+
487
+ // Get assignee info for this task (v1.6.0+)
488
+ const assignee = taskAssignments[`T${task.id}`] || null
489
+
490
+ // Get GitHub status for this task (v1.6.0+ T13.6)
491
+ const github = taskGithubStatus[`T${task.id}`] || null
492
+
493
+ let output = t.commands.next.title + "\n\n"
494
+ output += t.commands.next.recommendedTask + "\n"
495
+ output += `T${task.id}: ${task.name}\n\n`
496
+ output += t.commands.next.complexity + " " + complexityText + "\n"
497
+ output += t.commands.next.estimated + " " + task.estimated + "\n"
498
+ output += t.commands.next.phase + " " + task.phase + "\n"
499
+
500
+ // Show assignee (v1.6.0+)
501
+ if (assignee) {
502
+ if (assignee.isCurrentUser) {
503
+ output += t.commands.next.assignedToYou + "\n"
504
+ } else {
505
+ output += t.commands.next.assignedTo + " " + assignee.name + "\n"
506
+ }
507
+ } else {
508
+ output += t.commands.next.unassigned + "\n"
509
+ }
510
+
511
+ // Show GitHub status (v1.6.0+ T13.6)
512
+ if (githubIntegration && github) {
513
+ output += formatGithubStatus(github, t)
514
+ }
515
+
516
+ output += "\n" + t.commands.next.dependenciesCompleted + "\n\n"
517
+ output += t.commands.next.whyThisTask + "\n"
518
+ output += reasons.map(r => "• " + r).join("\n") + "\n"
519
+
520
+ // Add assignee-specific hints (v1.6.0+)
521
+ if (assignee && !assignee.isCurrentUser) {
522
+ output += "• " + t.commands.next.assignedHint + "\n"
523
+ } else if (assignee && assignee.isCurrentUser) {
524
+ output += "• " + t.commands.next.youAreAssigned + "\n"
525
+ }
526
+
527
+ output += "\n" + t.commands.next.taskDetails + "\n"
528
+ output += task.description + "\n\n"
529
+ output += t.commands.next.readyToStart + "\n"
530
+ output += `/planUpdate T${task.id} start\n\n`
531
+ output += "─".repeat(60) + "\n\n"
532
+ output += t.commands.next.alternatives + "\n\n"
533
+
534
+ // Show assignee and GitHub status in alternatives too (v1.6.0+)
535
+ output += alternatives.map((alt, i) => {
536
+ const altAssignee = taskAssignments[`T${alt.id}`]
537
+ const altGithub = taskGithubStatus[`T${alt.id}`]
538
+ let suffixInfo = ""
539
+
540
+ // Add assignee info
541
+ if (altAssignee) {
542
+ if (altAssignee.isCurrentUser) {
543
+ suffixInfo += " 👤 (you)"
544
+ } else {
545
+ suffixInfo += ` 👤 ${altAssignee.name}`
546
+ }
547
+ }
548
+
549
+ // Add compact GitHub info
550
+ if (githubIntegration && altGithub) {
551
+ suffixInfo += formatGithubStatusCompact(altGithub)
552
+ }
553
+
554
+ return `${i+1}. T${alt.id}: ${alt.name} - ${alt.complexity} - ${alt.estimated}${suffixInfo}`
555
+ }).join("\n")
556
+
557
+ // Helper function to format GitHub status for main recommendation
558
+ function formatGithubStatus(github, t) {
559
+ let output = ""
560
+
561
+ if (github.branch) {
562
+ // Show branch name (truncate if too long)
563
+ const branchName = github.branch.length > 35
564
+ ? github.branch.substring(0, 32) + "..."
565
+ : github.branch
566
+ output += ` 🌿 ${t.commands.next.github.branch}: ${branchName}\n`
567
+ }
568
+
569
+ if (github.issue) {
570
+ const issueState = github.issue.state === "open"
571
+ ? t.commands.next.github.open
572
+ : t.commands.next.github.closed
573
+ output += ` 📋 ${t.commands.next.github.issue}: #${github.issue.number} (${issueState})\n`
574
+ }
575
+
576
+ if (github.pr) {
577
+ let prStatus = ""
578
+ if (github.pr.state === "merged") {
579
+ prStatus = t.commands.next.github.merged
580
+ } else if (github.pr.state === "closed") {
581
+ prStatus = t.commands.next.github.closed
582
+ } else if (github.pr.reviewStatus === "approved") {
583
+ prStatus = t.commands.next.github.approved
584
+ } else if (github.pr.reviewStatus === "changes_requested") {
585
+ prStatus = t.commands.next.github.changesRequested
586
+ } else if (github.pr.reviewStatus === "awaiting") {
587
+ prStatus = t.commands.next.github.awaitingReview
588
+ } else {
589
+ prStatus = t.commands.next.github.open
590
+ }
591
+ output += ` 🔀 ${t.commands.next.github.pr}: #${github.pr.number} (${prStatus})\n`
592
+ }
593
+
594
+ if (!github.branch && !github.issue && !github.pr) {
595
+ // No GitHub activity yet
596
+ output += ` 🐙 ${t.commands.next.github.noActivity}\n`
597
+ }
598
+
599
+ return output
600
+ }
601
+
602
+ // Helper function for compact GitHub status (used in alternatives list)
603
+ function formatGithubStatusCompact(github) {
604
+ const parts = []
605
+
606
+ if (github.branch) {
607
+ parts.push("🌿") // Has branch
608
+ }
609
+
610
+ if (github.issue) {
611
+ const state = github.issue.state === "open" ? "" : "✓"
612
+ parts.push(`#${github.issue.number}${state}`)
613
+ }
614
+
615
+ if (github.pr) {
616
+ let prIcon = "🔀"
617
+ if (github.pr.state === "merged") {
618
+ prIcon = "✅"
619
+ } else if (github.pr.reviewStatus === "approved") {
620
+ prIcon = "👍"
621
+ } else if (github.pr.reviewStatus === "changes_requested") {
622
+ prIcon = "⚠️"
623
+ }
624
+ parts.push(`${prIcon}PR#${github.pr.number}`)
625
+ }
626
+
627
+ return parts.length > 0 ? ` [${parts.join(" ")}]` : ""
628
+ }
629
+ ```
630
+
631
+ **Example output (English - Unassigned task, no GitHub activity):**
632
+
633
+ ```
634
+ ╭──────────────────────────────────────────────────────────────────────────────╮
635
+ │ 🎯 Recommended Next Task │
636
+ ├──────────────────────────────────────────────────────────────────────────────┤
637
+ │ │
638
+ │ T1.2: Database Setup │
639
+ │ │
640
+ │ ── Task Details ────────────────────────────────────────────────────────── │
641
+ │ │
642
+ │ 📊 Complexity: Medium │
643
+ │ ⏱️ Estimated: 4 hours │
644
+ │ 🎯 Phase: 1 - Foundation │
645
+ │ 👤 Assigned: Unassigned │
646
+ │ 🐙 GitHub: No activity yet │
647
+ │ │
648
+ │ ✅ All dependencies completed │
649
+ │ │
650
+ │ ── Why This Task? ──────────────────────────────────────────────────────── │
651
+ │ │
652
+ │ • Unlocks 3 other tasks │
653
+ │ • Critical for Phase 2 progress │
654
+ │ • Good complexity balance after previous task │
655
+ │ │
656
+ │ ── Description ─────────────────────────────────────────────────────────── │
657
+ │ │
658
+ │ Configure PostgreSQL database with connection pooling │
659
+ │ and initial schema setup... │
660
+ │ │
661
+ ├──────────────────────────────────────────────────────────────────────────────┤
662
+ │ │
663
+ │ 💡 Ready to start? │
664
+ │ • /planUpdate T1.2 start │
665
+ │ • /pfGithubBranch T1.2 Create a branch │
666
+ │ │
667
+ ╰──────────────────────────────────────────────────────────────────────────────╯
668
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
669
+
670
+ ── Alternative Tasks ────────────────────────────────────────────────────────
671
+
672
+ 1. T1.3: Authentication Setup - High - 6 hours
673
+ 2. T2.1: API Endpoints - Medium - 5 hours 👤 jane@company.com [🌿 #42]
674
+ ```
675
+
676
+ **Example output (English - With GitHub branch, issue, and PR):**
677
+
678
+ ```
679
+ ╭──────────────────────────────────────────────────────────────────────────────╮
680
+ │ 🎯 Recommended Next Task │
681
+ ├──────────────────────────────────────────────────────────────────────────────┤
682
+ │ │
683
+ │ T2.1: Implement Login API │
684
+ │ │
685
+ │ ── Task Details ────────────────────────────────────────────────────────── │
686
+ │ │
687
+ │ 📊 Complexity: High │
688
+ │ ⏱️ Estimated: 6 hours │
689
+ │ 🎯 Phase: 2 - Core Features │
690
+ │ 👤 Assigned to you │
691
+ │ 🌿 Branch: feature/T2.1-implement-login-api │
692
+ │ 📋 Issue: #42 (open) │
693
+ │ 🔀 PR: #45 (awaiting review) │
694
+ │ │
695
+ │ ✅ All dependencies completed │
696
+ │ │
697
+ │ ── Why This Task? ──────────────────────────────────────────────────────── │
698
+ │ │
699
+ │ • PR is awaiting review - finish the review cycle! │
700
+ │ • This task is assigned to you │
701
+ │ • Unlocks 3 other tasks │
702
+ │ │
703
+ ├──────────────────────────────────────────────────────────────────────────────┤
704
+ │ │
705
+ │ 💡 Continue working: │
706
+ │ • git checkout feature/T2.1-implement-login-api │
707
+ │ • Address PR review comments │
708
+ │ │
709
+ ╰──────────────────────────────────────────────────────────────────────────────╯
710
+ ```
711
+
712
+ **Example output (English - Assigned to current user):**
713
+ ```
714
+ 🎯 Recommended Next Task
715
+
716
+ T2.1: API Endpoints
717
+
718
+ Complexity: Medium
719
+ Estimated: 5 hours
720
+ Phase: 2 - Core Features
721
+ 👤 Assigned to you
722
+
723
+ ✅ All dependencies completed
724
+
725
+ 🎯 Why this task?
726
+ • Unlocks 3 other tasks
727
+ • Critical for Phase 2 progress
728
+ • This task is assigned to you - ready to work on!
729
+
730
+ 📝 Task Details:
731
+ Implement REST API endpoints for user management...
732
+
733
+ Ready to start?
734
+ /planUpdate T2.1 start
735
+
736
+ ────────────────────────────────────────────────────────────
737
+
738
+ 💡 Alternative Tasks (if this doesn't fit):
739
+
740
+ 1. T2.2: Data Validation - Low - 2 hours
741
+ 2. T2.3: Error Handling - Medium - 3 hours 👤 bob@company.com
742
+ ```
743
+
744
+ **Example output (English - Assigned to someone else):**
745
+ ```
746
+ 🎯 Recommended Next Task
747
+
748
+ T2.3: Error Handling
749
+
750
+ Complexity: Medium
751
+ Estimated: 3 hours
752
+ Phase: 2 - Core Features
753
+ 👤 Assigned to: Jane Smith
754
+
755
+ ✅ All dependencies completed
756
+
757
+ 🎯 Why this task?
758
+ • Unlocks 2 other tasks
759
+ • This task is already assigned. Consider picking an unassigned task.
760
+
761
+ 📝 Task Details:
762
+ Implement global error handling middleware...
763
+
764
+ Ready to start?
765
+ /planUpdate T2.3 start
766
+
767
+ ────────────────────────────────────────────────────────────
768
+
769
+ 💡 Alternative Tasks (if this doesn't fit):
770
+
771
+ 1. T2.4: Logging Setup - Low - 2 hours
772
+ 2. T2.5: Rate Limiting - Medium - 4 hours 👤 (you)
773
+ ```
774
+
775
+ **Example output (Georgian):**
776
+ ```
777
+ 🎯 რეკომენდებული შემდეგი ამოცანა
778
+
779
+ T1.2: მონაცემთა ბაზის დაყენება
780
+
781
+ სირთულე: საშუალო
782
+ შეფასებული: 4 საათი
783
+ ეტაპი: 1 - საფუძველი
784
+ 👤 დაუნიშნავი
785
+
786
+ ✅ ყველა დამოკიდებულება დასრულდა
787
+
788
+ 🎯 რატომ ეს ამოცანა?
789
+ • ხსნის 3 სხვა ამოცანას
790
+ • კრიტიკული მე-2 ეტაპის პროგრესისთვის
791
+ • კარგი სირთულის ბალანსი წინა ამოცანის შემდეგ
792
+
793
+ 📝 ამოცანის დეტალები:
794
+ PostgreSQL-ის დაყენება connection pooling-ით
795
+ და საწყისი სქემის დაყენებით...
796
+
797
+ მზად ხართ დასაწყებად?
798
+ /planUpdate T1.2 start
799
+
800
+ ────────────────────────────────────────────────────────────
801
+
802
+ 💡 ალტერნატიული ამოცანები (თუ ეს არ გიხდებათ):
803
+
804
+ 1. T1.3: ავთენტიფიკაციის დაყენება - მაღალი - 6 საათი
805
+ 2. T2.1: API Endpoints - საშუალო - 5 საათი 👤 jane@company.com
806
+ ```
807
+
808
+ **Instructions for Claude:**
809
+
810
+ Use translation keys for all output:
811
+ - Title: `t.commands.next.title`
812
+ - Recommended task: `t.commands.next.recommendedTask`
813
+ - Complexity: `t.commands.next.complexity` + `t.templates.complexity.{low/medium/high}`
814
+ - Estimated: `t.commands.next.estimated`
815
+ - Phase: `t.commands.next.phase`
816
+ - Dependencies: `t.commands.next.dependenciesCompleted`
817
+ - Why: `t.commands.next.whyThisTask`
818
+ - Details: `t.commands.next.taskDetails`
819
+ - Ready: `t.commands.next.readyToStart`
820
+ - Alternatives: `t.commands.next.alternatives`
821
+
822
+ **Assignee translation keys (v1.6.0+):**
823
+ - Assigned to: `t.commands.next.assignedTo` + assignee name
824
+ - Unassigned: `t.commands.next.unassigned`
825
+ - Assigned to you: `t.commands.next.assignedToYou`
826
+ - Assigned hint: `t.commands.next.assignedHint` (shown when task is assigned to someone else)
827
+ - You are assigned: `t.commands.next.youAreAssigned` (shown when task is assigned to current user)
828
+
829
+ **GitHub status translation keys (v1.6.0+ T13.6):**
830
+ - Branch: `t.commands.next.github.branch`
831
+ - Issue: `t.commands.next.github.issue`
832
+ - PR: `t.commands.next.github.pr`
833
+ - Open: `t.commands.next.github.open`
834
+ - Closed: `t.commands.next.github.closed`
835
+ - Merged: `t.commands.next.github.merged`
836
+ - Approved: `t.commands.next.github.approved`
837
+ - Changes Requested: `t.commands.next.github.changesRequested`
838
+ - Awaiting Review: `t.commands.next.github.awaitingReview`
839
+ - No activity: `t.commands.next.github.noActivity`
840
+ - Create branch hint: `t.commands.next.github.createBranchHint`
841
+ - Continue working: `t.commands.next.github.continueWorking`
842
+ - PR awaiting hint: `t.commands.next.github.prAwaitingHint`
843
+
844
+ ### Step 7: Handle Special Cases
845
+
846
+ #### Case 1: No Available Tasks (All Blocked or Waiting)
847
+
848
+ **Pseudo-code:**
849
+ ```javascript
850
+ let output = t.commands.next.noTasks + "\n\n"
851
+ output += t.commands.next.projectStatus + "\n"
852
+ output += t.commands.next.completed + " " + completedCount + "/" + totalCount + "\n"
853
+ output += t.commands.next.inProgress + " " + inProgressCount + "\n"
854
+ output += t.commands.next.blocked + " " + blockedCount + "\n"
855
+ output += t.commands.next.waitingOnDeps + " " + waitingCount + "\n\n"
856
+
857
+ if (inProgressTasks.length > 0) {
858
+ output += t.commands.next.tasksInProgress + "\n"
859
+ output += inProgressTasks.map(t => ` ${t.id}: ${t.name}`).join("\n") + "\n\n"
860
+ }
861
+
862
+ if (blockedTasks.length > 0) {
863
+ output += t.commands.next.blockedTasks + "\n"
864
+ output += blockedTasks.map(t => ` ${t.id}: ${t.name}`).join("\n") + "\n\n"
865
+ }
866
+
867
+ output += t.commands.next.suggestedActions + "\n"
868
+ output += "1. " + t.commands.next.completeInProgress + "\n"
869
+ output += "2. " + t.commands.next.resolveBlockers + "\n"
870
+ output += "3. " + t.commands.next.reviewDependencies
871
+ ```
872
+
873
+ **Example output (English):**
874
+
875
+ ```
876
+ ╭──────────────────────────────────────────────────────────────────────────────╮
877
+ │ ⚠️ No Tasks Available │
878
+ ├──────────────────────────────────────────────────────────────────────────────┤
879
+ │ │
880
+ │ No tasks currently available to work on. │
881
+ │ │
882
+ │ ── Project Status ──────────────────────────────────────────────────────── │
883
+ │ │
884
+ │ ✅ Completed: 5/18 │
885
+ │ 🔄 In Progress: 2 │
886
+ │ 🚫 Blocked: 1 │
887
+ │ ⏳ Waiting on Dependencies: 10 │
888
+ │ │
889
+ │ ── Tasks In Progress ───────────────────────────────────────────────────── │
890
+ │ │
891
+ │ • T1.2: Database Setup │
892
+ │ • T1.3: Authentication │
893
+ │ │
894
+ │ ── Blocked Tasks ───────────────────────────────────────────────────────── │
895
+ │ │
896
+ │ • T2.1: API Endpoints (waiting on design) │
897
+ │ │
898
+ ├──────────────────────────────────────────────────────────────────────────────┤
899
+ │ │
900
+ │ 💡 Suggested Actions: │
901
+ │ 1. Complete in-progress tasks │
902
+ │ 2. Resolve blockers on blocked tasks │
903
+ │ 3. Review dependencies if tasks seem stuck │
904
+ │ │
905
+ ╰──────────────────────────────────────────────────────────────────────────────╯
906
+ ```
907
+
908
+ **Instructions for Claude:**
909
+
910
+ Use translation keys:
911
+ - `t.commands.next.noTasks`
912
+ - `t.commands.next.projectStatus`
913
+ - `t.commands.next.completed`
914
+ - `t.commands.next.inProgress`
915
+ - `t.commands.next.blocked`
916
+ - `t.commands.next.waitingOnDeps`
917
+ - `t.commands.next.tasksInProgress`
918
+ - `t.commands.next.blockedTasks`
919
+ - `t.commands.next.suggestedActions`
920
+ - `t.commands.next.completeInProgress`
921
+ - `t.commands.next.resolveBlockers`
922
+ - `t.commands.next.reviewDependencies`
923
+
924
+ #### Case 2: All Tasks Complete
925
+
926
+ **Pseudo-code:**
927
+ ```javascript
928
+ let output = t.commands.next.allComplete + "\n\n"
929
+ output += t.commands.next.projectComplete + "\n\n"
930
+ output += t.commands.next.whatsNext + "\n"
931
+ output += t.commands.next.deploy + "\n"
932
+ output += t.commands.next.postMortem + "\n"
933
+ output += t.commands.next.gatherFeedback + "\n"
934
+ output += t.commands.next.planNextVersion + "\n"
935
+ output += t.commands.next.celebrate + "\n\n"
936
+ output += t.commands.next.greatWork
937
+ ```
938
+
939
+ **Example output (English):**
940
+
941
+ ```
942
+ ╭──────────────────────────────────────────────────────────────────────────────╮
943
+ │ 🎉 PROJECT COMPLETE │
944
+ ├──────────────────────────────────────────────────────────────────────────────┤
945
+ │ │
946
+ │ Congratulations! All tasks are complete! │
947
+ │ │
948
+ │ ── Project Summary ─────────────────────────────────────────────────────── │
949
+ │ │
950
+ │ ✅ Project: [PROJECT_NAME] │
951
+ │ 📊 Progress: ████████████████████████████████ 100% │
952
+ │ 🏆 Tasks: [Total] completed across [N] phases │
953
+ │ │
954
+ │ ╭────────────────────────────────────────────────────────────────────────╮ │
955
+ │ │ ✨ Project Status: COMPLETE │ │
956
+ │ ╰────────────────────────────────────────────────────────────────────────╯ │
957
+ │ │
958
+ │ ── What's Next? ────────────────────────────────────────────────────────── │
959
+ │ │
960
+ │ • Deploy to production (if not already) │
961
+ │ • Write post-mortem / lessons learned │
962
+ │ • Gather user feedback │
963
+ │ • Plan next version/features │
964
+ │ • Celebrate your success! 🎊 │
965
+ │ │
966
+ │ Great work on completing this project! 🚀 │
967
+ │ │
968
+ ╰──────────────────────────────────────────────────────────────────────────────╯
969
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
970
+ ```
971
+
972
+ #### Case 3: Only High-Complexity Tasks Left
973
+
974
+ ```
975
+ 🎯 Recommended Next Task
976
+
977
+ ╔══════════════════════════════════════════════════════════╗
978
+ ║ T[X].[Y]: [Task Name] ║
979
+ ║ 📊 Complexity: High ⚠️ ║
980
+ ║ ⏱️ Estimated: [X] hours ║
981
+ ╚══════════════════════════════════════════════════════════╝
982
+
983
+ ⚠️ Note: This is a complex task. Consider:
984
+ • Breaking it down into subtasks
985
+ • Setting aside focused time
986
+ • Getting help if needed
987
+ • Taking breaks during implementation
988
+
989
+ [Rest of normal recommendation]
990
+ ```
991
+
992
+ #### Case 4: Many In-Progress Tasks
993
+
994
+ If 3+ tasks are IN_PROGRESS:
995
+
996
+ ```
997
+ ⚠️ You have [N] tasks in progress.
998
+
999
+ 💡 Tip: Consider finishing in-progress tasks before starting new ones:
1000
+
1001
+ 🔄 In Progress:
1002
+ 1. T[X].[Y]: [Name] ([Complexity])
1003
+ 2. T[A].[B]: [Name] ([Complexity])
1004
+ 3. T[C].[D]: [Name] ([Complexity])
1005
+
1006
+ Benefits of finishing first:
1007
+ • Clear sense of progress
1008
+ • Unlock dependent tasks
1009
+ • Maintain focus and momentum
1010
+ • Avoid context switching
1011
+
1012
+ ────────────────────────────────────────────────────────────
1013
+
1014
+ Still want to start something new? Here's the recommendation:
1015
+ [Normal recommendation follows]
1016
+ ```
1017
+
1018
+ ### Step 8: Consider Context
1019
+
1020
+ Provide context-aware advice based on project state:
1021
+
1022
+ #### Early in Project (< 25% complete)
1023
+ ```
1024
+ 🌟 Early Stage Tips:
1025
+ • Focus on foundation tasks
1026
+ • Don't skip setup steps
1027
+ • Document as you go
1028
+ • Test early and often
1029
+ ```
1030
+
1031
+ #### Mid Project (25-75% complete)
1032
+ ```
1033
+ 🚀 Building Momentum:
1034
+ • You're making great progress!
1035
+ • Keep quality high
1036
+ • Watch for scope creep
1037
+ • Refactor if needed
1038
+ ```
1039
+
1040
+ #### Late Project (> 75% complete)
1041
+ ```
1042
+ 🏁 Final Sprint:
1043
+ • Almost there!
1044
+ • Don't rush quality
1045
+ • Test thoroughly
1046
+ • Update documentation
1047
+ • Plan deployment
1048
+ ```
1049
+
1050
+ ## Reasoning Examples
1051
+
1052
+ ### Example 1: Dependency Unlock
1053
+
1054
+ ```
1055
+ 🎯 Why this task?
1056
+ • Unlocks 3 other tasks (T2.2, T2.3, T2.4)
1057
+ • Critical path item - other work depends on this
1058
+ • Completing this opens up parallel work opportunities
1059
+ ```
1060
+
1061
+ ### Example 2: Complexity Balance
1062
+
1063
+ ```
1064
+ 🎯 Why this task?
1065
+ • Medium complexity - good after completing complex T1.3
1066
+ • Prevents burnout with more manageable scope
1067
+ • Maintains momentum without overwhelming difficulty
1068
+ ```
1069
+
1070
+ ### Example 3: Phase Progression
1071
+
1072
+ ```
1073
+ 🎯 Why this task?
1074
+ • Last task in Phase 1 - completes foundation
1075
+ • Allows moving to Phase 2 (core features)
1076
+ • Natural progression point in project
1077
+ ```
1078
+
1079
+ ### Example 4: Quick Win
1080
+
1081
+ ```
1082
+ 🎯 Why this task?
1083
+ • Low complexity - quick win opportunity
1084
+ • Boosts progress percentage significantly
1085
+ • Good for maintaining motivation
1086
+ • Easy to fit into short work session
1087
+ ```
1088
+
1089
+ ## Algorithms
1090
+
1091
+ ### Finding Dependent Tasks
1092
+
1093
+ For a given task TX.Y, find tasks that list it in dependencies:
1094
+
1095
+ ```
1096
+ For each task T:
1097
+ If T.dependencies contains TX.Y:
1098
+ Add T to dependents list
1099
+ ```
1100
+
1101
+ Count these to determine "unlock value".
1102
+
1103
+ ### Checking Dependency Satisfaction
1104
+
1105
+ For a task to be available, check each dependency:
1106
+
1107
+ ```
1108
+ For each dependency D in task.dependencies:
1109
+ Find task with ID = D
1110
+ If task.status != DONE:
1111
+ Return False (not satisfied)
1112
+ Return True (all satisfied)
1113
+ ```
1114
+
1115
+ ### Phase Detection
1116
+
1117
+ ```
1118
+ Extract phase number from task ID:
1119
+ T1.1 → Phase 1
1120
+ T2.3 → Phase 2
1121
+ T15.7 → Phase 15
1122
+
1123
+ Find current phase:
1124
+ For phase in [1, 2, 3, 4, ...]:
1125
+ If any task in phase is not DONE:
1126
+ Return phase
1127
+ ```
1128
+
1129
+ ## Edge Cases
1130
+
1131
+ 1. **Circular Dependencies**: Detect and warn user
1132
+ ```
1133
+ ⚠️ Warning: Circular dependency detected between T2.1 and T2.3
1134
+ Please review and fix the dependencies in PROJECT_PLAN.md
1135
+ ```
1136
+
1137
+ 2. **Missing Dependencies**: Task references non-existent task
1138
+ ```
1139
+ ⚠️ Warning: Task T2.3 depends on T1.5, which doesn't exist
1140
+ Treating as satisfied for now.
1141
+ ```
1142
+
1143
+ 3. **Empty Plan**: No tasks defined
1144
+ ```
1145
+ ⚠️ No tasks found in PROJECT_PLAN.md
1146
+ Please add tasks to the "Tasks & Implementation Plan" section.
1147
+ ```
1148
+
1149
+ ## Output Formatting
1150
+
1151
+ Use visual elements for clarity:
1152
+ - ✅ Checkmarks for completed items
1153
+ - 🔄 In progress indicator
1154
+ - 🚫 Blocked indicator
1155
+ - 📊 Complexity indicator
1156
+ - ⏱️ Time estimate
1157
+ - 🎯 Goal/recommendation
1158
+ - 💡 Tips and suggestions
1159
+ - ⚠️ Warnings
1160
+ - 🎉 Celebrations
1161
+
1162
+ Keep output scannable and actionable.
1163
+
1164
+ ## Success Criteria
1165
+
1166
+ A good recommendation should:
1167
+ - ✅ Consider all relevant factors (dependencies, phase, complexity)
1168
+ - ✅ Provide clear reasoning
1169
+ - ✅ Show task details
1170
+ - ✅ Offer alternatives
1171
+ - ✅ Give actionable next steps
1172
+ - ✅ Be contextually aware
1173
+ - ✅ Help maintain project momentum
1174
+ - ✅ Show assignee information when connected to cloud (v1.6.0+)
1175
+ - ✅ Indicate if task is assigned to current user or someone else
1176
+ - ✅ Gracefully degrade when not authenticated (no assignee info shown)
1177
+ - ✅ Show GitHub status when GitHub is integrated (v1.6.0+ T13.6)
1178
+ - ✅ Display branch name if created for the task
1179
+ - ✅ Display linked GitHub issue number and state
1180
+ - ✅ Display linked PR number, state, and review status
1181
+ - ✅ Provide GitHub-aware hints (create branch, address PR comments)
1182
+ - ✅ Show compact GitHub info in alternatives list
1183
+ - ✅ Gracefully degrade when GitHub is not integrated
1184
+
1185
+ ## Implementation Notes
1186
+
1187
+ 1. **Parse carefully**: Use regex or string matching to extract task details
1188
+ 2. **Handle variations**: Tasks may have slightly different formatting
1189
+ 3. **Be robust**: Don't fail on minor formatting issues
1190
+ 4. **Calculate accurately**: Ensure dependency logic is correct
1191
+ 5. **Explain well**: Users should understand WHY this task is recommended
1192
+ 6. **Stay positive**: Encourage users and maintain motivation
1193
+ 7. **Fetch assignments gracefully (v1.6.0+)**: Only fetch when authenticated and linked; use short timeouts; continue without assignments if fetch fails
1194
+ 8. **Show assignee context**: Help users understand who is working on what to avoid conflicts
1195
+ 9. **Prioritize unassigned tasks**: When recommending, consider that unassigned tasks may be better choices for the user
1196
+ 10. **Fetch GitHub status gracefully (v1.6.0+ T13.6)**: Check GitHub integration first; use short timeouts; fallback to local git branch detection if cloud unavailable
1197
+ 11. **Provide GitHub-aware hints**: When a task has a branch, suggest checkout; when PR exists, suggest addressing reviews; when no activity, suggest creating a branch
1198
+ 12. **Show compact GitHub info in alternatives**: Use icons (🌿, 🔀, ✅, ⚠️) to indicate GitHub status without overwhelming the list
1199
+
1200
+ This command is about **intelligent guidance**, not just listing tasks!