agileflow 2.41.0 → 2.43.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 (67) hide show
  1. package/package.json +1 -1
  2. package/src/core/agents/accessibility.md +8 -0
  3. package/src/core/agents/adr-writer.md +8 -0
  4. package/src/core/agents/analytics.md +8 -0
  5. package/src/core/agents/api.md +8 -2
  6. package/src/core/agents/ci.md +8 -0
  7. package/src/core/agents/compliance.md +8 -0
  8. package/src/core/agents/configuration/archival.md +46 -1
  9. package/src/core/agents/configuration/attribution.md +22 -1
  10. package/src/core/agents/configuration/ci.md +23 -1
  11. package/src/core/agents/configuration/git-config.md +23 -1
  12. package/src/core/agents/configuration/hooks.md +22 -1
  13. package/src/core/agents/configuration/precompact.md +8 -0
  14. package/src/core/agents/configuration/status-line.md +116 -13
  15. package/src/core/agents/configuration/verify.md +23 -1
  16. package/src/core/agents/database.md +8 -2
  17. package/src/core/agents/datamigration.md +8 -0
  18. package/src/core/agents/design.md +8 -0
  19. package/src/core/agents/devops.md +8 -2
  20. package/src/core/agents/documentation.md +8 -0
  21. package/src/core/agents/epic-planner.md +8 -0
  22. package/src/core/agents/integrations.md +8 -0
  23. package/src/core/agents/mentor.md +8 -3
  24. package/src/core/agents/mobile.md +8 -0
  25. package/src/core/agents/monitoring.md +8 -0
  26. package/src/core/agents/multi-expert.md +8 -0
  27. package/src/core/agents/performance.md +8 -2
  28. package/src/core/agents/product.md +8 -0
  29. package/src/core/agents/qa.md +8 -0
  30. package/src/core/agents/readme-updater.md +8 -0
  31. package/src/core/agents/refactor.md +8 -2
  32. package/src/core/agents/research.md +8 -0
  33. package/src/core/agents/security.md +8 -2
  34. package/src/core/agents/testing.md +8 -0
  35. package/src/core/agents/ui.md +8 -2
  36. package/src/core/commands/adr.md +2 -13
  37. package/src/core/commands/agent.md +2 -13
  38. package/src/core/commands/assign.md +2 -13
  39. package/src/core/commands/auto.md +2 -13
  40. package/src/core/commands/babysit.md +94 -88
  41. package/src/core/commands/baseline.md +2 -13
  42. package/src/core/commands/blockers.md +4 -13
  43. package/src/core/commands/board.md +4 -13
  44. package/src/core/commands/configure.md +187 -433
  45. package/src/core/commands/deps.md +4 -15
  46. package/src/core/commands/docs.md +2 -15
  47. package/src/core/commands/epic.md +4 -15
  48. package/src/core/commands/help.md +3 -14
  49. package/src/core/commands/metrics.md +4 -15
  50. package/src/core/commands/packages.md +3 -14
  51. package/src/core/commands/pr.md +4 -13
  52. package/src/core/commands/readme-sync.md +7 -24
  53. package/src/core/commands/research.md +3 -14
  54. package/src/core/commands/retro.md +4 -15
  55. package/src/core/commands/sprint.md +8 -0
  56. package/src/core/commands/status.md +5 -14
  57. package/src/core/commands/story-validate.md +3 -14
  58. package/src/core/commands/story.md +17 -17
  59. package/src/core/commands/template.md +2 -15
  60. package/src/core/commands/tests.md +2 -15
  61. package/src/core/commands/update.md +2 -15
  62. package/src/core/commands/validate-expertise.md +2 -15
  63. package/src/core/commands/velocity.md +4 -15
  64. package/src/core/commands/verify.md +4 -15
  65. package/src/core/templates/agileflow-configure.js +927 -0
  66. package/src/core/templates/agileflow-metadata.json +12 -0
  67. package/src/core/templates/agileflow-statusline.sh +238 -44
@@ -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"