agileflow 2.42.0 → 2.44.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 (75) hide show
  1. package/package.json +2 -1
  2. package/scripts/generate-all.sh +77 -0
  3. package/scripts/generators/agent-registry.js +167 -0
  4. package/scripts/generators/command-registry.js +135 -0
  5. package/scripts/generators/index.js +87 -0
  6. package/scripts/generators/inject-babysit.js +167 -0
  7. package/scripts/generators/inject-help.js +109 -0
  8. package/scripts/generators/inject-readme.js +156 -0
  9. package/scripts/generators/skill-registry.js +144 -0
  10. package/src/core/agents/accessibility.md +8 -0
  11. package/src/core/agents/adr-writer.md +8 -0
  12. package/src/core/agents/analytics.md +8 -0
  13. package/src/core/agents/api.md +8 -2
  14. package/src/core/agents/ci.md +8 -0
  15. package/src/core/agents/compliance.md +8 -0
  16. package/src/core/agents/configuration/archival.md +23 -1
  17. package/src/core/agents/configuration/attribution.md +22 -1
  18. package/src/core/agents/configuration/ci.md +23 -1
  19. package/src/core/agents/configuration/git-config.md +23 -1
  20. package/src/core/agents/configuration/hooks.md +22 -1
  21. package/src/core/agents/configuration/precompact.md +8 -0
  22. package/src/core/agents/configuration/status-line.md +93 -13
  23. package/src/core/agents/configuration/verify.md +23 -1
  24. package/src/core/agents/database.md +8 -2
  25. package/src/core/agents/datamigration.md +8 -0
  26. package/src/core/agents/design.md +8 -0
  27. package/src/core/agents/devops.md +8 -2
  28. package/src/core/agents/documentation.md +8 -0
  29. package/src/core/agents/epic-planner.md +8 -0
  30. package/src/core/agents/integrations.md +8 -0
  31. package/src/core/agents/mentor.md +8 -3
  32. package/src/core/agents/mobile.md +8 -0
  33. package/src/core/agents/monitoring.md +8 -0
  34. package/src/core/agents/multi-expert.md +8 -0
  35. package/src/core/agents/performance.md +8 -2
  36. package/src/core/agents/product.md +8 -0
  37. package/src/core/agents/qa.md +8 -0
  38. package/src/core/agents/readme-updater.md +8 -0
  39. package/src/core/agents/refactor.md +8 -2
  40. package/src/core/agents/research.md +8 -0
  41. package/src/core/agents/security.md +8 -2
  42. package/src/core/agents/testing.md +8 -0
  43. package/src/core/agents/ui.md +8 -2
  44. package/src/core/commands/adr.md +2 -13
  45. package/src/core/commands/agent.md +2 -13
  46. package/src/core/commands/assign.md +2 -13
  47. package/src/core/commands/auto.md +2 -13
  48. package/src/core/commands/babysit.md +94 -88
  49. package/src/core/commands/baseline.md +2 -13
  50. package/src/core/commands/blockers.md +4 -13
  51. package/src/core/commands/board.md +4 -13
  52. package/src/core/commands/context.md +141 -5
  53. package/src/core/commands/deps.md +4 -15
  54. package/src/core/commands/docs.md +2 -15
  55. package/src/core/commands/epic.md +4 -15
  56. package/src/core/commands/help.md +3 -14
  57. package/src/core/commands/metrics.md +4 -15
  58. package/src/core/commands/packages.md +3 -14
  59. package/src/core/commands/pr.md +4 -13
  60. package/src/core/commands/readme-sync.md +7 -24
  61. package/src/core/commands/research.md +3 -14
  62. package/src/core/commands/retro.md +4 -15
  63. package/src/core/commands/sprint.md +8 -0
  64. package/src/core/commands/status.md +5 -14
  65. package/src/core/commands/story-validate.md +3 -14
  66. package/src/core/commands/story.md +17 -17
  67. package/src/core/commands/template.md +2 -15
  68. package/src/core/commands/tests.md +2 -15
  69. package/src/core/commands/update.md +2 -15
  70. package/src/core/commands/validate-expertise.md +2 -15
  71. package/src/core/commands/velocity.md +4 -15
  72. package/src/core/commands/verify.md +4 -15
  73. package/src/core/templates/agileflow-configure.js +123 -2
  74. package/src/core/templates/agileflow-metadata.json +12 -0
  75. package/src/core/templates/agileflow-statusline.sh +238 -44
@@ -44,6 +44,9 @@ const FEATURES = {
44
44
  statusline: { script: 'agileflow-statusline.sh' }
45
45
  };
46
46
 
47
+ // Statusline component names
48
+ const STATUSLINE_COMPONENTS = ['agileflow', 'model', 'story', 'epic', 'wip', 'context', 'cost', 'git'];
49
+
47
50
  const PROFILES = {
48
51
  full: {
49
52
  description: 'All features enabled',
@@ -615,6 +618,89 @@ function updateGitignore() {
615
618
  }
616
619
  }
617
620
 
621
+ // ============================================================================
622
+ // STATUSLINE COMPONENTS
623
+ // ============================================================================
624
+
625
+ function setStatuslineComponents(enableComponents = [], disableComponents = []) {
626
+ const metaPath = 'docs/00-meta/agileflow-metadata.json';
627
+
628
+ if (!fs.existsSync(metaPath)) {
629
+ warn('No metadata file found - run with --enable=statusline first');
630
+ return false;
631
+ }
632
+
633
+ const meta = readJSON(metaPath);
634
+ if (!meta) {
635
+ error('Cannot parse metadata file');
636
+ return false;
637
+ }
638
+
639
+ // Ensure statusline.components structure exists
640
+ meta.features = meta.features || {};
641
+ meta.features.statusline = meta.features.statusline || {};
642
+ meta.features.statusline.components = meta.features.statusline.components || {};
643
+
644
+ // Set defaults for any missing components
645
+ STATUSLINE_COMPONENTS.forEach(comp => {
646
+ if (meta.features.statusline.components[comp] === undefined) {
647
+ meta.features.statusline.components[comp] = true;
648
+ }
649
+ });
650
+
651
+ // Enable specified components
652
+ enableComponents.forEach(comp => {
653
+ if (STATUSLINE_COMPONENTS.includes(comp)) {
654
+ meta.features.statusline.components[comp] = true;
655
+ success(`Statusline component enabled: ${comp}`);
656
+ } else {
657
+ warn(`Unknown component: ${comp} (available: ${STATUSLINE_COMPONENTS.join(', ')})`);
658
+ }
659
+ });
660
+
661
+ // Disable specified components
662
+ disableComponents.forEach(comp => {
663
+ if (STATUSLINE_COMPONENTS.includes(comp)) {
664
+ meta.features.statusline.components[comp] = false;
665
+ success(`Statusline component disabled: ${comp}`);
666
+ } else {
667
+ warn(`Unknown component: ${comp} (available: ${STATUSLINE_COMPONENTS.join(', ')})`);
668
+ }
669
+ });
670
+
671
+ meta.updated = new Date().toISOString();
672
+ writeJSON(metaPath, meta);
673
+
674
+ return true;
675
+ }
676
+
677
+ function listStatuslineComponents() {
678
+ const metaPath = 'docs/00-meta/agileflow-metadata.json';
679
+
680
+ header('📊 Statusline Components');
681
+
682
+ if (!fs.existsSync(metaPath)) {
683
+ log(' No configuration found (defaults: all enabled)', c.dim);
684
+ STATUSLINE_COMPONENTS.forEach(comp => {
685
+ log(` ✅ ${comp}: enabled (default)`, c.green);
686
+ });
687
+ return;
688
+ }
689
+
690
+ const meta = readJSON(metaPath);
691
+ const components = meta?.features?.statusline?.components || {};
692
+
693
+ STATUSLINE_COMPONENTS.forEach(comp => {
694
+ const enabled = components[comp] !== false; // default true
695
+ const icon = enabled ? '✅' : '❌';
696
+ const color = enabled ? c.green : c.dim;
697
+ log(` ${icon} ${comp}: ${enabled ? 'enabled' : 'disabled'}`, color);
698
+ });
699
+
700
+ log('\nTo toggle: --show=<component> or --hide=<component>', c.dim);
701
+ log(`Components: ${STATUSLINE_COMPONENTS.join(', ')}`, c.dim);
702
+ }
703
+
618
704
  // ============================================================================
619
705
  // PROFILES
620
706
  // ============================================================================
@@ -683,8 +769,8 @@ ${c.cyan}Usage:${c.reset}
683
769
 
684
770
  ${c.cyan}Profiles:${c.reset}
685
771
  --profile=full All features (hooks, archival, statusline)
686
- --profile=basic SessionStart + PreCompact hooks only
687
- --profile=minimal Just SessionStart hook
772
+ --profile=basic SessionStart + PreCompact + archival
773
+ --profile=minimal SessionStart + archival only
688
774
  --profile=none Disable all AgileFlow features
689
775
 
690
776
  ${c.cyan}Feature Control:${c.reset}
@@ -693,6 +779,13 @@ ${c.cyan}Feature Control:${c.reset}
693
779
 
694
780
  Features: sessionstart, precompact, stop, archival, statusline
695
781
 
782
+ ${c.cyan}Statusline Components:${c.reset}
783
+ --show=<list> Show statusline components (comma-separated)
784
+ --hide=<list> Hide statusline components (comma-separated)
785
+ --components List statusline component status
786
+
787
+ Components: agileflow, model, story, epic, wip, context, cost, git
788
+
696
789
  ${c.cyan}Settings:${c.reset}
697
790
  --archival-days=N Set archival threshold (default: 7)
698
791
 
@@ -711,6 +804,15 @@ ${c.cyan}Examples:${c.reset}
711
804
  # Disable a feature
712
805
  node scripts/agileflow-configure.js --disable=statusline
713
806
 
807
+ # Show only agileflow branding and context in statusline
808
+ node scripts/agileflow-configure.js --hide=model,story,epic,wip,cost,git
809
+
810
+ # Re-enable git branch in statusline
811
+ node scripts/agileflow-configure.js --show=git
812
+
813
+ # List component status
814
+ node scripts/agileflow-configure.js --components
815
+
714
816
  # Fix format issues
715
817
  node scripts/agileflow-configure.js --migrate
716
818
 
@@ -730,18 +832,24 @@ function main() {
730
832
  let profile = null;
731
833
  let enable = [];
732
834
  let disable = [];
835
+ let show = [];
836
+ let hide = [];
733
837
  let archivalDays = 7;
734
838
  let migrate = false;
735
839
  let detect = false;
840
+ let components = false;
736
841
  let help = false;
737
842
 
738
843
  args.forEach(arg => {
739
844
  if (arg.startsWith('--profile=')) profile = arg.split('=')[1];
740
845
  else if (arg.startsWith('--enable=')) enable = arg.split('=')[1].split(',').map(s => s.trim().toLowerCase());
741
846
  else if (arg.startsWith('--disable=')) disable = arg.split('=')[1].split(',').map(s => s.trim().toLowerCase());
847
+ else if (arg.startsWith('--show=')) show = arg.split('=')[1].split(',').map(s => s.trim().toLowerCase());
848
+ else if (arg.startsWith('--hide=')) hide = arg.split('=')[1].split(',').map(s => s.trim().toLowerCase());
742
849
  else if (arg.startsWith('--archival-days=')) archivalDays = parseInt(arg.split('=')[1]) || 7;
743
850
  else if (arg === '--migrate') migrate = true;
744
851
  else if (arg === '--detect' || arg === '--validate') detect = true;
852
+ else if (arg === '--components') components = true;
745
853
  else if (arg === '--help' || arg === '-h') help = true;
746
854
  });
747
855
 
@@ -750,6 +858,19 @@ function main() {
750
858
  return;
751
859
  }
752
860
 
861
+ // Components list mode
862
+ if (components && show.length === 0 && hide.length === 0) {
863
+ listStatuslineComponents();
864
+ return;
865
+ }
866
+
867
+ // Component toggle mode
868
+ if (show.length > 0 || hide.length > 0) {
869
+ setStatuslineComponents(show, hide);
870
+ listStatuslineComponents();
871
+ return;
872
+ }
873
+
753
874
  // Always detect first
754
875
  const status = detectConfig();
755
876
  const hasIssues = printStatus(status);
@@ -9,6 +9,18 @@
9
9
  "adr": true,
10
10
  "research": true,
11
11
  "messagebus": true,
12
+ "statusline": {
13
+ "components": {
14
+ "agileflow": true,
15
+ "model": true,
16
+ "story": true,
17
+ "epic": true,
18
+ "wip": true,
19
+ "context": true,
20
+ "cost": true,
21
+ "git": true
22
+ }
23
+ },
12
24
  "mcp": {
13
25
  "github": false,
14
26
  "notion": false
@@ -12,7 +12,116 @@
12
12
  # .context_window.current_usage.input_tokens - Current input tokens
13
13
  # .workspace.current_dir - Current working directory
14
14
 
15
- # Read JSON input from stdin (Claude Code provides this)
15
+ # ============================================================================
16
+ # ANSI Color Codes
17
+ # ============================================================================
18
+ RESET="\033[0m"
19
+ BOLD="\033[1m"
20
+ DIM="\033[2m"
21
+
22
+ # Foreground colors
23
+ BLACK="\033[30m"
24
+ RED="\033[31m"
25
+ GREEN="\033[32m"
26
+ YELLOW="\033[33m"
27
+ BLUE="\033[34m"
28
+ MAGENTA="\033[35m"
29
+ CYAN="\033[36m"
30
+ WHITE="\033[37m"
31
+
32
+ # Bright foreground colors
33
+ BRIGHT_RED="\033[91m"
34
+ BRIGHT_GREEN="\033[92m"
35
+ BRIGHT_YELLOW="\033[93m"
36
+ BRIGHT_BLUE="\033[94m"
37
+ BRIGHT_MAGENTA="\033[95m"
38
+ BRIGHT_CYAN="\033[96m"
39
+
40
+ # Brand color (burnt orange #e8683a = RGB 232,104,58)
41
+ BRAND="\033[38;2;232;104;58m"
42
+
43
+ # ============================================================================
44
+ # Read Component Configuration
45
+ # ============================================================================
46
+ # Default: all components enabled
47
+ SHOW_AGILEFLOW=true
48
+ SHOW_MODEL=true
49
+ SHOW_STORY=true
50
+ SHOW_EPIC=true
51
+ SHOW_WIP=true
52
+ SHOW_CONTEXT=true
53
+ SHOW_COST=true
54
+ SHOW_GIT=true
55
+
56
+ # Check agileflow-metadata.json for component settings
57
+ if [ -f "docs/00-meta/agileflow-metadata.json" ]; then
58
+ COMPONENTS=$(jq '.features.statusline.components // null' docs/00-meta/agileflow-metadata.json 2>/dev/null)
59
+ if [ "$COMPONENTS" != "null" ] && [ -n "$COMPONENTS" ]; then
60
+ # Use 'if . == null then true else . end' to properly handle false values
61
+ # (jq's // operator treats false as falsy and applies the fallback)
62
+ SHOW_AGILEFLOW=$(echo "$COMPONENTS" | jq -r '.agileflow | if . == null then true else . end')
63
+ SHOW_MODEL=$(echo "$COMPONENTS" | jq -r '.model | if . == null then true else . end')
64
+ SHOW_STORY=$(echo "$COMPONENTS" | jq -r '.story | if . == null then true else . end')
65
+ SHOW_EPIC=$(echo "$COMPONENTS" | jq -r '.epic | if . == null then true else . end')
66
+ SHOW_WIP=$(echo "$COMPONENTS" | jq -r '.wip | if . == null then true else . end')
67
+ SHOW_CONTEXT=$(echo "$COMPONENTS" | jq -r '.context | if . == null then true else . end')
68
+ SHOW_COST=$(echo "$COMPONENTS" | jq -r '.cost | if . == null then true else . end')
69
+ SHOW_GIT=$(echo "$COMPONENTS" | jq -r '.git | if . == null then true else . end')
70
+ fi
71
+ fi
72
+
73
+ # ============================================================================
74
+ # AgileFlow Version & Update Check
75
+ # ============================================================================
76
+ AGILEFLOW_DISPLAY=""
77
+ if [ "$SHOW_AGILEFLOW" = "true" ]; then
78
+ # Get local version from package.json or metadata
79
+ LOCAL_VERSION=""
80
+ if [ -f ".agileflow/package.json" ]; then
81
+ LOCAL_VERSION=$(jq -r '.version // ""' .agileflow/package.json 2>/dev/null)
82
+ elif [ -f "docs/00-meta/agileflow-metadata.json" ]; then
83
+ LOCAL_VERSION=$(jq -r '.version // ""' docs/00-meta/agileflow-metadata.json 2>/dev/null)
84
+ fi
85
+
86
+ if [ -n "$LOCAL_VERSION" ] && [ "$LOCAL_VERSION" != "null" ]; then
87
+ # Check for updates (cached for 1 hour to avoid rate limiting)
88
+ UPDATE_CACHE="/tmp/agileflow-update-check"
89
+ UPDATE_AVAILABLE=""
90
+ LATEST_VERSION=""
91
+
92
+ # Only check npm if cache is stale (older than 1 hour)
93
+ if [ ! -f "$UPDATE_CACHE" ] || [ "$(find "$UPDATE_CACHE" -mmin +60 2>/dev/null)" ]; then
94
+ # Quick npm check (timeout after 2 seconds)
95
+ LATEST_VERSION=$(timeout 2 npm view agileflow version 2>/dev/null || echo "")
96
+ if [ -n "$LATEST_VERSION" ]; then
97
+ echo "$LATEST_VERSION" > "$UPDATE_CACHE"
98
+ fi
99
+ else
100
+ LATEST_VERSION=$(cat "$UPDATE_CACHE" 2>/dev/null)
101
+ fi
102
+
103
+ # Compare versions
104
+ if [ -n "$LATEST_VERSION" ] && [ "$LATEST_VERSION" != "$LOCAL_VERSION" ]; then
105
+ # Simple version comparison (works for semver)
106
+ if [ "$(printf '%s\n' "$LOCAL_VERSION" "$LATEST_VERSION" | sort -V | tail -n1)" = "$LATEST_VERSION" ] && [ "$LOCAL_VERSION" != "$LATEST_VERSION" ]; then
107
+ UPDATE_AVAILABLE="$LATEST_VERSION"
108
+ fi
109
+ fi
110
+
111
+ # Build display
112
+ if [ -n "$UPDATE_AVAILABLE" ]; then
113
+ AGILEFLOW_DISPLAY="${BRAND}agileflow${RESET} ${DIM}v${LOCAL_VERSION}${RESET} ${YELLOW}↑${UPDATE_AVAILABLE}${RESET}"
114
+ else
115
+ AGILEFLOW_DISPLAY="${BRAND}agileflow${RESET} ${DIM}v${LOCAL_VERSION}${RESET}"
116
+ fi
117
+ else
118
+ AGILEFLOW_DISPLAY="${BRAND}agileflow${RESET}"
119
+ fi
120
+ fi
121
+
122
+ # ============================================================================
123
+ # Parse Input JSON
124
+ # ============================================================================
16
125
  input=$(cat)
17
126
 
18
127
  # Parse model info
@@ -23,11 +132,24 @@ CONTEXT_SIZE=$(echo "$input" | jq -r '.context_window.context_window_size // 200
23
132
  USAGE=$(echo "$input" | jq '.context_window.current_usage // null')
24
133
 
25
134
  CTX_DISPLAY=""
135
+ CTX_COLOR="$GREEN"
26
136
  if [ "$USAGE" != "null" ]; then
27
137
  CURRENT_TOKENS=$(echo "$USAGE" | jq '.input_tokens + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)')
28
138
  if [ "$CURRENT_TOKENS" != "null" ] && [ "$CURRENT_TOKENS" -gt 0 ] 2>/dev/null; then
29
139
  PERCENT_USED=$((CURRENT_TOKENS * 100 / CONTEXT_SIZE))
30
- CTX_DISPLAY="${PERCENT_USED}% ctx"
140
+
141
+ # Color based on usage level
142
+ if [ "$PERCENT_USED" -ge 80 ]; then
143
+ CTX_COLOR="$BRIGHT_RED"
144
+ elif [ "$PERCENT_USED" -ge 60 ]; then
145
+ CTX_COLOR="$YELLOW"
146
+ elif [ "$PERCENT_USED" -ge 40 ]; then
147
+ CTX_COLOR="$BRIGHT_YELLOW"
148
+ else
149
+ CTX_COLOR="$GREEN"
150
+ fi
151
+
152
+ CTX_DISPLAY="${CTX_COLOR}${PERCENT_USED}%${RESET}"
31
153
  fi
32
154
  fi
33
155
 
@@ -35,10 +157,18 @@ fi
35
157
  TOTAL_COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
36
158
  COST_DISPLAY=""
37
159
  if [ "$TOTAL_COST" != "0" ] && [ "$TOTAL_COST" != "null" ]; then
38
- COST_DISPLAY=$(printf '$%.2f' "$TOTAL_COST")
160
+ COST_CENTS=$(echo "$TOTAL_COST * 100" | bc 2>/dev/null | cut -d. -f1)
161
+ if [ -n "$COST_CENTS" ] && [ "$COST_CENTS" -gt 100 ]; then
162
+ # Over $1 - show in yellow
163
+ COST_DISPLAY="${YELLOW}$(printf '$%.2f' "$TOTAL_COST")${RESET}"
164
+ else
165
+ COST_DISPLAY="${DIM}$(printf '$%.2f' "$TOTAL_COST")${RESET}"
166
+ fi
39
167
  fi
40
168
 
169
+ # ============================================================================
41
170
  # AgileFlow Status - Read from status.json
171
+ # ============================================================================
42
172
  STORY_DISPLAY=""
43
173
  EPIC_DISPLAY=""
44
174
  NEXT_STORY=""
@@ -59,7 +189,7 @@ if [ -f "docs/09-agents/status.json" ]; then
59
189
  if [ ${#STORY_TITLE} -gt 25 ]; then
60
190
  STORY_TITLE="${STORY_TITLE:0:22}..."
61
191
  fi
62
- STORY_DISPLAY="${STORY_ID}: ${STORY_TITLE}"
192
+ STORY_DISPLAY="${CYAN}${STORY_ID}${RESET}${DIM}:${RESET} ${STORY_TITLE}"
63
193
  fi
64
194
 
65
195
  # Get epic progress if we have an epic
@@ -71,12 +201,20 @@ if [ -f "docs/09-agents/status.json" ]; then
71
201
 
72
202
  if [ "$TOTAL_IN_EPIC" -gt 0 ] 2>/dev/null; then
73
203
  EPIC_PCT=$((DONE_IN_EPIC * 100 / TOTAL_IN_EPIC))
74
- EPIC_DISPLAY="${EPIC_ID}: ${DONE_IN_EPIC}/${TOTAL_IN_EPIC} (${EPIC_PCT}%)"
204
+
205
+ # Color epic progress based on completion
206
+ if [ "$EPIC_PCT" -ge 80 ]; then
207
+ EPIC_COLOR="$GREEN"
208
+ elif [ "$EPIC_PCT" -ge 50 ]; then
209
+ EPIC_COLOR="$YELLOW"
210
+ else
211
+ EPIC_COLOR="$DIM"
212
+ fi
213
+ EPIC_DISPLAY="${MAGENTA}${EPIC_ID}${RESET} ${EPIC_COLOR}${DONE_IN_EPIC}/${TOTAL_IN_EPIC}${RESET}"
75
214
  fi
76
215
  fi
77
216
  else
78
217
  # No story in-progress - find next READY story (priority: high > medium > low)
79
- # Look for stories with status "ready" or stories without blockers
80
218
  NEXT_ID=$(echo "$STATUS_JSON" | jq -r '
81
219
  .stories | to_entries
82
220
  | map(select(.value.status == "ready" or .value.status == "backlog" or .value.status == "draft"))
@@ -90,72 +228,128 @@ if [ -f "docs/09-agents/status.json" ]; then
90
228
  ')
91
229
 
92
230
  if [ -n "$NEXT_ID" ] && [ "$NEXT_ID" != "null" ]; then
93
- NEXT_TITLE=$(echo "$STATUS_JSON" | jq -r ".stories[\"$NEXT_ID\"].title // \"\"")
94
231
  NEXT_PRIORITY=$(echo "$STATUS_JSON" | jq -r ".stories[\"$NEXT_ID\"].priority // \"\"")
95
- if [ ${#NEXT_TITLE} -gt 20 ]; then
96
- NEXT_TITLE="${NEXT_TITLE:0:17}..."
97
- fi
98
- # Add priority indicator
99
- PRIORITY_ICON=""
232
+ # Color based on priority
100
233
  case "$NEXT_PRIORITY" in
101
- high) PRIORITY_ICON="🔴" ;;
102
- medium) PRIORITY_ICON="🟡" ;;
103
- *) PRIORITY_ICON="🟢" ;;
234
+ high) PRIORITY_COLOR="$RED" ;;
235
+ medium) PRIORITY_COLOR="$YELLOW" ;;
236
+ *) PRIORITY_COLOR="$GREEN" ;;
104
237
  esac
105
- NEXT_STORY="${PRIORITY_ICON} Next: ${NEXT_ID}"
238
+ NEXT_STORY="${DIM}Next:${RESET} ${PRIORITY_COLOR}${NEXT_ID}${RESET}"
106
239
  fi
107
240
  fi
108
241
 
109
242
  # Calculate WIP count
110
243
  WIP_COUNT=$(echo "$STATUS_JSON" | jq '[.stories | to_entries[] | select(.value.status == "in-progress" or .value.status == "in-review")] | length')
111
244
  WIP_LIMIT=3 # Default WIP limit
112
- if [ -n "$WIP_COUNT" ] && [ "$WIP_COUNT" != "null" ]; then
113
- WIP_DISPLAY="WIP: ${WIP_COUNT}/${WIP_LIMIT}"
245
+ if [ -n "$WIP_COUNT" ] && [ "$WIP_COUNT" != "null" ] && [ "$WIP_COUNT" -gt 0 ] 2>/dev/null; then
246
+ # Color WIP based on limit
247
+ if [ "$WIP_COUNT" -gt "$WIP_LIMIT" ]; then
248
+ WIP_COLOR="$RED"
249
+ elif [ "$WIP_COUNT" -eq "$WIP_LIMIT" ]; then
250
+ WIP_COLOR="$YELLOW"
251
+ else
252
+ WIP_COLOR="$GREEN"
253
+ fi
254
+ WIP_DISPLAY="${DIM}WIP${RESET} ${WIP_COLOR}${WIP_COUNT}${RESET}"
114
255
  fi
115
256
  fi
116
257
 
117
- # Get git branch
118
- GIT_BRANCH=""
258
+ # ============================================================================
259
+ # Git Branch with Colors
260
+ # ============================================================================
261
+ GIT_DISPLAY=""
119
262
  if git rev-parse --git-dir > /dev/null 2>&1; then
120
263
  BRANCH=$(git branch --show-current 2>/dev/null)
121
264
  if [ -n "$BRANCH" ]; then
122
- GIT_BRANCH="$BRANCH"
265
+ # Color based on branch type
266
+ case "$BRANCH" in
267
+ main|master)
268
+ GIT_COLOR="$GREEN"
269
+ ;;
270
+ develop|dev)
271
+ GIT_COLOR="$BLUE"
272
+ ;;
273
+ feature/*|feat/*)
274
+ GIT_COLOR="$CYAN"
275
+ ;;
276
+ fix/*|bugfix/*|hotfix/*)
277
+ GIT_COLOR="$RED"
278
+ ;;
279
+ release/*)
280
+ GIT_COLOR="$MAGENTA"
281
+ ;;
282
+ *)
283
+ GIT_COLOR="$DIM"
284
+ ;;
285
+ esac
286
+
287
+ # Truncate long branch names
288
+ if [ ${#BRANCH} -gt 20 ]; then
289
+ BRANCH="${BRANCH:0:17}..."
290
+ fi
291
+ GIT_DISPLAY="${GIT_COLOR}${BRANCH}${RESET}"
123
292
  fi
124
293
  fi
125
294
 
126
- # Build status line
127
- OUTPUT="[${MODEL_DISPLAY}]"
295
+ # ============================================================================
296
+ # Build Status Line
297
+ # ============================================================================
298
+ OUTPUT=""
128
299
 
129
- # Add current story OR next story suggestion
130
- if [ -n "$STORY_DISPLAY" ]; then
131
- OUTPUT="${OUTPUT} 📋 ${STORY_DISPLAY}"
132
- elif [ -n "$NEXT_STORY" ]; then
133
- OUTPUT="${OUTPUT} ${NEXT_STORY}"
300
+ # Separator
301
+ SEP=" ${DIM}│${RESET} "
302
+
303
+ # AgileFlow branding (if enabled)
304
+ if [ "$SHOW_AGILEFLOW" = "true" ] && [ -n "$AGILEFLOW_DISPLAY" ]; then
305
+ OUTPUT="${AGILEFLOW_DISPLAY}"
306
+ fi
307
+
308
+ # Model with subtle styling (if enabled)
309
+ if [ "$SHOW_MODEL" = "true" ]; then
310
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
311
+ OUTPUT="${OUTPUT}${DIM}[${RESET}${BOLD}${MODEL_DISPLAY}${RESET}${DIM}]${RESET}"
312
+ fi
313
+
314
+ # Add current story OR next story suggestion (if enabled)
315
+ if [ "$SHOW_STORY" = "true" ]; then
316
+ if [ -n "$STORY_DISPLAY" ]; then
317
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
318
+ OUTPUT="${OUTPUT}${STORY_DISPLAY}"
319
+ elif [ -n "$NEXT_STORY" ]; then
320
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
321
+ OUTPUT="${OUTPUT}${NEXT_STORY}"
322
+ fi
134
323
  fi
135
324
 
136
- # Add epic progress (if working on a story in an epic)
137
- if [ -n "$EPIC_DISPLAY" ]; then
138
- OUTPUT="${OUTPUT} | 📦 ${EPIC_DISPLAY}"
325
+ # Add epic progress (if enabled and working on a story in an epic)
326
+ if [ "$SHOW_EPIC" = "true" ] && [ -n "$EPIC_DISPLAY" ]; then
327
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
328
+ OUTPUT="${OUTPUT}${EPIC_DISPLAY}"
139
329
  fi
140
330
 
141
- # Add WIP count
142
- if [ -n "$WIP_DISPLAY" ]; then
143
- OUTPUT="${OUTPUT} | ${WIP_DISPLAY}"
331
+ # Add WIP count (if enabled)
332
+ if [ "$SHOW_WIP" = "true" ] && [ -n "$WIP_DISPLAY" ]; then
333
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
334
+ OUTPUT="${OUTPUT}${WIP_DISPLAY}"
144
335
  fi
145
336
 
146
- # Add context usage
147
- if [ -n "$CTX_DISPLAY" ]; then
148
- OUTPUT="${OUTPUT} | ${CTX_DISPLAY}"
337
+ # Add context usage (if enabled)
338
+ if [ "$SHOW_CONTEXT" = "true" ] && [ -n "$CTX_DISPLAY" ]; then
339
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
340
+ OUTPUT="${OUTPUT}${CTX_DISPLAY}"
149
341
  fi
150
342
 
151
- # Add cost
152
- if [ -n "$COST_DISPLAY" ]; then
153
- OUTPUT="${OUTPUT} | ${COST_DISPLAY}"
343
+ # Add cost (if enabled)
344
+ if [ "$SHOW_COST" = "true" ] && [ -n "$COST_DISPLAY" ]; then
345
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
346
+ OUTPUT="${OUTPUT}${COST_DISPLAY}"
154
347
  fi
155
348
 
156
- # Add git branch
157
- if [ -n "$GIT_BRANCH" ]; then
158
- OUTPUT="${OUTPUT} | ${GIT_BRANCH}"
349
+ # Add git branch (if enabled)
350
+ if [ "$SHOW_GIT" = "true" ] && [ -n "$GIT_DISPLAY" ]; then
351
+ [ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
352
+ OUTPUT="${OUTPUT}${GIT_DISPLAY}"
159
353
  fi
160
354
 
161
- echo "$OUTPUT"
355
+ echo -e "$OUTPUT"