agileflow 2.76.0 → 2.78.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.
- package/README.md +3 -3
- package/package.json +6 -1
- package/scripts/agileflow-configure.js +185 -13
- package/scripts/agileflow-statusline.sh +266 -27
- package/scripts/agileflow-welcome.js +160 -52
- package/scripts/auto-self-improve.js +63 -20
- package/scripts/check-update.js +1 -4
- package/scripts/damage-control-bash.js +232 -0
- package/scripts/damage-control-edit.js +243 -0
- package/scripts/damage-control-write.js +243 -0
- package/scripts/get-env.js +15 -7
- package/scripts/lib/frontmatter-parser.js +4 -1
- package/scripts/obtain-context.js +59 -48
- package/scripts/ralph-loop.js +25 -13
- package/scripts/validate-expertise.sh +19 -15
- package/src/core/agents/accessibility.md +124 -53
- package/src/core/agents/adr-writer.md +192 -52
- package/src/core/agents/analytics.md +139 -60
- package/src/core/agents/api.md +173 -63
- package/src/core/agents/ci.md +139 -57
- package/src/core/agents/compliance.md +159 -68
- package/src/core/agents/configuration/damage-control.md +356 -0
- package/src/core/agents/database.md +162 -61
- package/src/core/agents/datamigration.md +179 -66
- package/src/core/agents/design.md +179 -57
- package/src/core/agents/devops.md +160 -3
- package/src/core/agents/documentation.md +204 -60
- package/src/core/agents/epic-planner.md +147 -55
- package/src/core/agents/integrations.md +197 -69
- package/src/core/agents/mentor.md +158 -57
- package/src/core/agents/mobile.md +159 -67
- package/src/core/agents/monitoring.md +154 -65
- package/src/core/agents/multi-expert.md +115 -43
- package/src/core/agents/orchestrator.md +77 -24
- package/src/core/agents/performance.md +130 -75
- package/src/core/agents/product.md +151 -55
- package/src/core/agents/qa.md +162 -74
- package/src/core/agents/readme-updater.md +178 -76
- package/src/core/agents/refactor.md +148 -95
- package/src/core/agents/research.md +143 -72
- package/src/core/agents/security.md +154 -65
- package/src/core/agents/testing.md +176 -97
- package/src/core/agents/ui.md +170 -79
- package/src/core/commands/adr/list.md +171 -0
- package/src/core/commands/adr/update.md +235 -0
- package/src/core/commands/adr/view.md +252 -0
- package/src/core/commands/adr.md +207 -50
- package/src/core/commands/agent.md +16 -0
- package/src/core/commands/assign.md +148 -44
- package/src/core/commands/auto.md +18 -1
- package/src/core/commands/babysit.md +361 -36
- package/src/core/commands/baseline.md +14 -0
- package/src/core/commands/blockers.md +170 -51
- package/src/core/commands/board.md +144 -66
- package/src/core/commands/changelog.md +15 -0
- package/src/core/commands/ci.md +179 -69
- package/src/core/commands/compress.md +18 -0
- package/src/core/commands/configure.md +16 -0
- package/src/core/commands/context/export.md +193 -4
- package/src/core/commands/context/full.md +191 -18
- package/src/core/commands/context/note.md +248 -4
- package/src/core/commands/debt.md +17 -0
- package/src/core/commands/deploy.md +208 -65
- package/src/core/commands/deps.md +15 -0
- package/src/core/commands/diagnose.md +16 -0
- package/src/core/commands/docs.md +196 -64
- package/src/core/commands/epic/list.md +170 -0
- package/src/core/commands/epic/view.md +242 -0
- package/src/core/commands/epic.md +192 -69
- package/src/core/commands/feedback.md +191 -71
- package/src/core/commands/handoff.md +162 -48
- package/src/core/commands/help.md +9 -0
- package/src/core/commands/ideate.md +446 -0
- package/src/core/commands/impact.md +16 -0
- package/src/core/commands/metrics.md +141 -37
- package/src/core/commands/multi-expert.md +77 -0
- package/src/core/commands/packages.md +16 -0
- package/src/core/commands/pr.md +161 -67
- package/src/core/commands/readme-sync.md +16 -0
- package/src/core/commands/research/analyze.md +568 -0
- package/src/core/commands/research/ask.md +345 -20
- package/src/core/commands/research/import.md +562 -19
- package/src/core/commands/research/list.md +173 -5
- package/src/core/commands/research/view.md +181 -8
- package/src/core/commands/retro.md +135 -48
- package/src/core/commands/review.md +219 -47
- package/src/core/commands/session/end.md +209 -0
- package/src/core/commands/session/history.md +210 -0
- package/src/core/commands/session/init.md +116 -0
- package/src/core/commands/session/new.md +296 -0
- package/src/core/commands/session/resume.md +166 -0
- package/src/core/commands/session/status.md +166 -0
- package/src/core/commands/skill/create.md +115 -17
- package/src/core/commands/skill/delete.md +117 -0
- package/src/core/commands/skill/edit.md +104 -0
- package/src/core/commands/skill/list.md +128 -0
- package/src/core/commands/skill/test.md +135 -0
- package/src/core/commands/skill/upgrade.md +542 -0
- package/src/core/commands/sprint.md +17 -1
- package/src/core/commands/status.md +133 -21
- package/src/core/commands/story/list.md +176 -0
- package/src/core/commands/story/view.md +265 -0
- package/src/core/commands/story-validate.md +101 -1
- package/src/core/commands/story.md +204 -51
- package/src/core/commands/template.md +16 -1
- package/src/core/commands/tests.md +226 -64
- package/src/core/commands/update.md +17 -1
- package/src/core/commands/validate-expertise.md +16 -0
- package/src/core/commands/velocity.md +140 -36
- package/src/core/commands/verify.md +14 -0
- package/src/core/commands/whats-new.md +30 -0
- package/src/core/skills/_learnings/README.md +91 -0
- package/src/core/skills/_learnings/_template.yaml +106 -0
- package/src/core/skills/_learnings/commit.yaml +69 -0
- package/src/core/templates/damage-control-patterns.yaml +234 -0
- package/src/core/templates/skill-template.md +53 -11
- package/tools/cli/commands/list.js +3 -1
- package/tools/cli/commands/start.js +180 -0
- package/tools/cli/commands/uninstall.js +4 -5
- package/tools/cli/commands/update.js +11 -3
- package/tools/cli/lib/content-injector.js +6 -1
- package/tools/cli/tui/Dashboard.js +66 -0
- package/tools/cli/tui/StoryList.js +69 -0
- package/tools/cli/tui/index.js +16 -0
|
@@ -29,7 +29,7 @@ MAGENTA="\033[35m"
|
|
|
29
29
|
CYAN="\033[36m"
|
|
30
30
|
WHITE="\033[37m"
|
|
31
31
|
|
|
32
|
-
# Bright foreground colors
|
|
32
|
+
# Bright foreground colors (standard ANSI)
|
|
33
33
|
BRIGHT_RED="\033[91m"
|
|
34
34
|
BRIGHT_GREEN="\033[92m"
|
|
35
35
|
BRIGHT_YELLOW="\033[93m"
|
|
@@ -37,9 +37,74 @@ BRIGHT_BLUE="\033[94m"
|
|
|
37
37
|
BRIGHT_MAGENTA="\033[95m"
|
|
38
38
|
BRIGHT_CYAN="\033[96m"
|
|
39
39
|
|
|
40
|
+
# 256-color palette (vibrant modern colors from cc-statusline)
|
|
41
|
+
# Use these for context/session indicators for better visibility
|
|
42
|
+
CTX_GREEN="\033[38;5;158m" # Mint green - healthy context
|
|
43
|
+
CTX_YELLOW="\033[38;5;215m" # Peach - moderate usage
|
|
44
|
+
CTX_ORANGE="\033[38;5;215m" # Peach/orange - high usage
|
|
45
|
+
CTX_RED="\033[38;5;203m" # Coral red - critical
|
|
46
|
+
|
|
47
|
+
SESSION_GREEN="\033[38;5;194m" # Light green - plenty of time
|
|
48
|
+
SESSION_YELLOW="\033[38;5;228m" # Light yellow - getting low
|
|
49
|
+
SESSION_RED="\033[38;5;210m" # Light pink/red - critical
|
|
50
|
+
|
|
40
51
|
# Brand color (burnt orange #e8683a = RGB 232,104,58)
|
|
41
52
|
BRAND="\033[38;2;232;104;58m"
|
|
42
53
|
|
|
54
|
+
# ============================================================================
|
|
55
|
+
# Helper Functions
|
|
56
|
+
# ============================================================================
|
|
57
|
+
|
|
58
|
+
# Progress bar with custom characters: ▓ (filled) ░ (empty)
|
|
59
|
+
# Usage: progress_bar <percent> <width>
|
|
60
|
+
# Example: progress_bar 75 10 → "▓▓▓▓▓▓▓░░░"
|
|
61
|
+
progress_bar() {
|
|
62
|
+
local pct="${1:-0}"
|
|
63
|
+
local width="${2:-10}"
|
|
64
|
+
|
|
65
|
+
# Validate and clamp percentage
|
|
66
|
+
[[ "$pct" =~ ^[0-9]+$ ]] || pct=0
|
|
67
|
+
((pct < 0)) && pct=0
|
|
68
|
+
((pct > 100)) && pct=100
|
|
69
|
+
|
|
70
|
+
local filled=$(( pct * width / 100 ))
|
|
71
|
+
local empty=$(( width - filled ))
|
|
72
|
+
|
|
73
|
+
# Build bar with custom characters
|
|
74
|
+
local bar=""
|
|
75
|
+
for ((i=0; i<filled; i++)); do bar+="▓"; done
|
|
76
|
+
for ((i=0; i<empty; i++)); do bar+="░"; done
|
|
77
|
+
|
|
78
|
+
echo "$bar"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Convert ISO timestamp to epoch seconds (cross-platform)
|
|
82
|
+
to_epoch() {
|
|
83
|
+
local ts="$1"
|
|
84
|
+
# Try gdate first (macOS with coreutils)
|
|
85
|
+
if command -v gdate >/dev/null 2>&1; then
|
|
86
|
+
gdate -d "$ts" +%s 2>/dev/null && return
|
|
87
|
+
fi
|
|
88
|
+
# Try BSD date (macOS)
|
|
89
|
+
date -u -j -f "%Y-%m-%dT%H:%M:%S%z" "${ts/Z/+0000}" +%s 2>/dev/null && return
|
|
90
|
+
# Fallback to Python
|
|
91
|
+
python3 - "$ts" <<'PY' 2>/dev/null
|
|
92
|
+
import sys, datetime
|
|
93
|
+
s=sys.argv[1].replace('Z','+00:00')
|
|
94
|
+
print(int(datetime.datetime.fromisoformat(s).timestamp()))
|
|
95
|
+
PY
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# Format epoch to HH:MM
|
|
99
|
+
fmt_time_hm() {
|
|
100
|
+
local epoch="$1"
|
|
101
|
+
if date -r 0 +%s >/dev/null 2>&1; then
|
|
102
|
+
date -r "$epoch" +"%H:%M"
|
|
103
|
+
else
|
|
104
|
+
date -d "@$epoch" +"%H:%M"
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
43
108
|
# ============================================================================
|
|
44
109
|
# Read Component Configuration
|
|
45
110
|
# ============================================================================
|
|
@@ -50,6 +115,8 @@ SHOW_STORY=true
|
|
|
50
115
|
SHOW_EPIC=true
|
|
51
116
|
SHOW_WIP=true
|
|
52
117
|
SHOW_CONTEXT=true
|
|
118
|
+
SHOW_CONTEXT_BAR=true
|
|
119
|
+
SHOW_SESSION_TIME=true
|
|
53
120
|
SHOW_COST=true
|
|
54
121
|
SHOW_GIT=true
|
|
55
122
|
|
|
@@ -65,6 +132,8 @@ if [ -f "docs/00-meta/agileflow-metadata.json" ]; then
|
|
|
65
132
|
SHOW_EPIC=$(echo "$COMPONENTS" | jq -r '.epic | if . == null then true else . end')
|
|
66
133
|
SHOW_WIP=$(echo "$COMPONENTS" | jq -r '.wip | if . == null then true else . end')
|
|
67
134
|
SHOW_CONTEXT=$(echo "$COMPONENTS" | jq -r '.context | if . == null then true else . end')
|
|
135
|
+
SHOW_CONTEXT_BAR=$(echo "$COMPONENTS" | jq -r '.context_bar | if . == null then true else . end')
|
|
136
|
+
SHOW_SESSION_TIME=$(echo "$COMPONENTS" | jq -r '.session_time | if . == null then true else . end')
|
|
68
137
|
SHOW_COST=$(echo "$COMPONENTS" | jq -r '.cost | if . == null then true else . end')
|
|
69
138
|
SHOW_GIT=$(echo "$COMPONENTS" | jq -r '.git | if . == null then true else . end')
|
|
70
139
|
fi
|
|
@@ -124,35 +193,75 @@ fi
|
|
|
124
193
|
# ============================================================================
|
|
125
194
|
input=$(cat)
|
|
126
195
|
|
|
127
|
-
# Parse model info
|
|
128
|
-
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name //
|
|
196
|
+
# Parse model info (fallback to empty if no input)
|
|
197
|
+
MODEL_DISPLAY=$(echo "$input" | jq -r '.model.display_name // empty' 2>/dev/null)
|
|
198
|
+
[ -z "$MODEL_DISPLAY" ] && MODEL_DISPLAY=""
|
|
129
199
|
|
|
130
|
-
#
|
|
131
|
-
|
|
132
|
-
|
|
200
|
+
# ============================================================================
|
|
201
|
+
# Context Window Usage (reads from session JSONL file like cc-statusline)
|
|
202
|
+
# ============================================================================
|
|
203
|
+
# Claude Code doesn't pass context usage via stdin reliably, so we read it
|
|
204
|
+
# directly from the session's JSONL file (same approach as cc-statusline)
|
|
133
205
|
|
|
134
206
|
CTX_DISPLAY=""
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
207
|
+
CTX_BAR_DISPLAY=""
|
|
208
|
+
CTX_COLOR="$CTX_GREEN"
|
|
209
|
+
PERCENT_USED=0
|
|
210
|
+
|
|
211
|
+
# Get session_id and current_dir from input
|
|
212
|
+
SESSION_ID=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null)
|
|
213
|
+
CURRENT_DIR=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // empty' 2>/dev/null)
|
|
214
|
+
|
|
215
|
+
# Determine max context based on model (all modern models use 200K)
|
|
216
|
+
get_max_context() {
|
|
217
|
+
local model="$1"
|
|
218
|
+
case "$model" in
|
|
219
|
+
*"Claude 3 Haiku"*|*"claude 3 haiku"*)
|
|
220
|
+
echo "100000" # 100K for original Claude 3 Haiku
|
|
221
|
+
;;
|
|
222
|
+
*)
|
|
223
|
+
echo "200000" # 200K for Opus, Sonnet, modern Haiku
|
|
224
|
+
;;
|
|
225
|
+
esac
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
MAX_CONTEXT=$(get_max_context "$MODEL_DISPLAY")
|
|
229
|
+
|
|
230
|
+
if [ -n "$SESSION_ID" ] && [ -n "$CURRENT_DIR" ]; then
|
|
231
|
+
# Convert current dir to session file path (same as cc-statusline)
|
|
232
|
+
# e.g., /home/coder/AgileFlow -> home-coder-AgileFlow
|
|
233
|
+
PROJECT_DIR=$(echo "$CURRENT_DIR" | sed "s|^$HOME|~|g" | sed "s|~|$HOME|g" | sed 's|/|-|g' | sed 's|^-||')
|
|
234
|
+
SESSION_FILE="$HOME/.claude/projects/-${PROJECT_DIR}/${SESSION_ID}.jsonl"
|
|
235
|
+
|
|
236
|
+
if [ -f "$SESSION_FILE" ]; then
|
|
237
|
+
# Get the latest input token count from the session file (last 20 lines)
|
|
238
|
+
LATEST_TOKENS=$(tail -20 "$SESSION_FILE" | jq -r 'select(.message.usage) | .message.usage | ((.input_tokens // 0) + (.cache_read_input_tokens // 0))' 2>/dev/null | tail -1)
|
|
239
|
+
|
|
240
|
+
if [ -n "$LATEST_TOKENS" ] && [ "$LATEST_TOKENS" -gt 0 ] 2>/dev/null; then
|
|
241
|
+
PERCENT_USED=$((LATEST_TOKENS * 100 / MAX_CONTEXT))
|
|
242
|
+
# Cap at 100%
|
|
243
|
+
[ "$PERCENT_USED" -gt 100 ] && PERCENT_USED=100
|
|
150
244
|
fi
|
|
151
|
-
|
|
152
|
-
CTX_DISPLAY="${CTX_COLOR}${PERCENT_USED}%${RESET}"
|
|
153
245
|
fi
|
|
154
246
|
fi
|
|
155
247
|
|
|
248
|
+
# Color based on usage level (using vibrant 256-color palette)
|
|
249
|
+
if [ "$PERCENT_USED" -ge 80 ]; then
|
|
250
|
+
CTX_COLOR="$CTX_RED" # Coral red - critical
|
|
251
|
+
elif [ "$PERCENT_USED" -ge 60 ]; then
|
|
252
|
+
CTX_COLOR="$CTX_ORANGE" # Peach - high usage
|
|
253
|
+
elif [ "$PERCENT_USED" -ge 40 ]; then
|
|
254
|
+
CTX_COLOR="$CTX_YELLOW" # Peach - moderate
|
|
255
|
+
else
|
|
256
|
+
CTX_COLOR="$CTX_GREEN" # Mint green - healthy
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
CTX_DISPLAY="${CTX_COLOR}${PERCENT_USED}%${RESET}"
|
|
260
|
+
|
|
261
|
+
# Generate progress bar (8 chars wide for compactness)
|
|
262
|
+
CTX_BAR=$(progress_bar "$PERCENT_USED" 8)
|
|
263
|
+
CTX_BAR_DISPLAY="${DIM}[${RESET}${CTX_COLOR}${CTX_BAR}${RESET}${DIM}]${RESET}"
|
|
264
|
+
|
|
156
265
|
# Parse cost
|
|
157
266
|
TOTAL_COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
|
|
158
267
|
COST_DISPLAY=""
|
|
@@ -166,6 +275,125 @@ if [ "$TOTAL_COST" != "0" ] && [ "$TOTAL_COST" != "null" ]; then
|
|
|
166
275
|
fi
|
|
167
276
|
fi
|
|
168
277
|
|
|
278
|
+
# ============================================================================
|
|
279
|
+
# Session Time Remaining (Native - reads Claude Code's local JSONL files)
|
|
280
|
+
# ============================================================================
|
|
281
|
+
# Claude Code uses 5-hour billing blocks. Block starts with first message activity.
|
|
282
|
+
# We scan ~/.claude/projects/*/*.jsonl to find the earliest message in the current
|
|
283
|
+
# 5-hour window and calculate remaining time.
|
|
284
|
+
#
|
|
285
|
+
# Algorithm (like ccusage):
|
|
286
|
+
# 1. Find all timestamps from JSONL files modified in last 5 hours
|
|
287
|
+
# 2. Sort and find the earliest timestamp >= (now - 5 hours)
|
|
288
|
+
# 3. That's the block start; block end = block start + 5 hours
|
|
289
|
+
# 4. Remaining = block end - now
|
|
290
|
+
#
|
|
291
|
+
# Optimization: Cache result for 60 seconds to avoid repeated scans
|
|
292
|
+
SESSION_DISPLAY=""
|
|
293
|
+
if [ "$SHOW_SESSION_TIME" = "true" ]; then
|
|
294
|
+
SESSION_CACHE="/tmp/agileflow-session-cache"
|
|
295
|
+
CACHE_MAX_AGE=60 # seconds
|
|
296
|
+
NOW_SEC=$(date +%s)
|
|
297
|
+
|
|
298
|
+
# Check cache first
|
|
299
|
+
CACHED_BLOCK_START=""
|
|
300
|
+
if [ -f "$SESSION_CACHE" ]; then
|
|
301
|
+
CACHE_DATA=$(cat "$SESSION_CACHE" 2>/dev/null)
|
|
302
|
+
CACHE_TIME=$(echo "$CACHE_DATA" | cut -d: -f1)
|
|
303
|
+
CACHE_VALUE=$(echo "$CACHE_DATA" | cut -d: -f2)
|
|
304
|
+
if [ -n "$CACHE_TIME" ] && [ $((NOW_SEC - CACHE_TIME)) -lt "$CACHE_MAX_AGE" ] 2>/dev/null; then
|
|
305
|
+
CACHED_BLOCK_START="$CACHE_VALUE"
|
|
306
|
+
fi
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
BLOCK_START_SEC=""
|
|
310
|
+
|
|
311
|
+
if [ -n "$CACHED_BLOCK_START" ] && [ "$CACHED_BLOCK_START" != "none" ]; then
|
|
312
|
+
BLOCK_START_SEC="$CACHED_BLOCK_START"
|
|
313
|
+
elif [ "$CACHED_BLOCK_START" != "none" ]; then
|
|
314
|
+
# Need to scan - use Python for speed (handles ISO timestamps natively)
|
|
315
|
+
CLAUDE_DATA_DIR="$HOME/.claude/projects"
|
|
316
|
+
BLOCK_DURATION=$((5 * 60 * 60)) # 5 hours in seconds
|
|
317
|
+
WINDOW_START=$((NOW_SEC - BLOCK_DURATION))
|
|
318
|
+
|
|
319
|
+
if [ -d "$CLAUDE_DATA_DIR" ]; then
|
|
320
|
+
BLOCK_START_SEC=$(python3 - "$CLAUDE_DATA_DIR" "$WINDOW_START" <<'PYTHON' 2>/dev/null
|
|
321
|
+
import sys, os, json, glob
|
|
322
|
+
from datetime import datetime
|
|
323
|
+
|
|
324
|
+
data_dir = sys.argv[1]
|
|
325
|
+
window_start = int(sys.argv[2])
|
|
326
|
+
|
|
327
|
+
earliest = None
|
|
328
|
+
# Only check files modified in last 5 hours (300 minutes)
|
|
329
|
+
for jsonl_path in glob.glob(f"{data_dir}/*/*.jsonl"):
|
|
330
|
+
try:
|
|
331
|
+
mtime = os.path.getmtime(jsonl_path)
|
|
332
|
+
if mtime < window_start:
|
|
333
|
+
continue # Skip old files
|
|
334
|
+
with open(jsonl_path, 'r') as f:
|
|
335
|
+
for line in f:
|
|
336
|
+
if '"timestamp"' not in line:
|
|
337
|
+
continue
|
|
338
|
+
try:
|
|
339
|
+
data = json.loads(line)
|
|
340
|
+
ts_str = data.get('timestamp', '')
|
|
341
|
+
if ts_str:
|
|
342
|
+
# Parse ISO timestamp
|
|
343
|
+
ts_str = ts_str.replace('Z', '+00:00')
|
|
344
|
+
dt = datetime.fromisoformat(ts_str)
|
|
345
|
+
epoch = int(dt.timestamp())
|
|
346
|
+
if epoch >= window_start:
|
|
347
|
+
if earliest is None or epoch < earliest:
|
|
348
|
+
earliest = epoch
|
|
349
|
+
except:
|
|
350
|
+
pass
|
|
351
|
+
except:
|
|
352
|
+
pass
|
|
353
|
+
|
|
354
|
+
if earliest:
|
|
355
|
+
print(earliest)
|
|
356
|
+
PYTHON
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
# Cache the result
|
|
360
|
+
if [ -n "$BLOCK_START_SEC" ] && [ "$BLOCK_START_SEC" -gt 0 ] 2>/dev/null; then
|
|
361
|
+
echo "${NOW_SEC}:${BLOCK_START_SEC}" > "$SESSION_CACHE"
|
|
362
|
+
else
|
|
363
|
+
echo "${NOW_SEC}:none" > "$SESSION_CACHE"
|
|
364
|
+
fi
|
|
365
|
+
fi
|
|
366
|
+
fi
|
|
367
|
+
|
|
368
|
+
# Calculate remaining time if we found a block start
|
|
369
|
+
if [ -n "$BLOCK_START_SEC" ] && [ "$BLOCK_START_SEC" -gt 0 ] 2>/dev/null; then
|
|
370
|
+
BLOCK_DURATION=$((5 * 60 * 60))
|
|
371
|
+
BLOCK_END_SEC=$((BLOCK_START_SEC + BLOCK_DURATION))
|
|
372
|
+
REMAINING=$((BLOCK_END_SEC - NOW_SEC))
|
|
373
|
+
[ "$REMAINING" -lt 0 ] && REMAINING=0
|
|
374
|
+
|
|
375
|
+
# Format remaining time
|
|
376
|
+
RH=$((REMAINING / 3600))
|
|
377
|
+
RM=$(((REMAINING % 3600) / 60))
|
|
378
|
+
|
|
379
|
+
# Color based on time remaining (using vibrant 256-color palette)
|
|
380
|
+
if [ "$RH" -eq 0 ] && [ "$RM" -lt 30 ]; then
|
|
381
|
+
SESSION_COLOR="$SESSION_RED" # Light pink - critical
|
|
382
|
+
elif [ "$RH" -eq 0 ]; then
|
|
383
|
+
SESSION_COLOR="$SESSION_YELLOW" # Light yellow - getting low
|
|
384
|
+
else
|
|
385
|
+
SESSION_COLOR="$SESSION_GREEN" # Light green - plenty of time
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
# Build compact display: "⏱2h15m" or "⏱45m"
|
|
389
|
+
if [ "$RH" -gt 0 ]; then
|
|
390
|
+
SESSION_DISPLAY="${SESSION_COLOR}⏱${RH}h${RM}m${RESET}"
|
|
391
|
+
else
|
|
392
|
+
SESSION_DISPLAY="${SESSION_COLOR}⏱${RM}m${RESET}"
|
|
393
|
+
fi
|
|
394
|
+
fi
|
|
395
|
+
fi
|
|
396
|
+
|
|
169
397
|
# ============================================================================
|
|
170
398
|
# AgileFlow Status - Read from status.json
|
|
171
399
|
# ============================================================================
|
|
@@ -305,8 +533,8 @@ if [ "$SHOW_AGILEFLOW" = "true" ] && [ -n "$AGILEFLOW_DISPLAY" ]; then
|
|
|
305
533
|
OUTPUT="${AGILEFLOW_DISPLAY}"
|
|
306
534
|
fi
|
|
307
535
|
|
|
308
|
-
# Model with subtle styling (if enabled)
|
|
309
|
-
if [ "$SHOW_MODEL" = "true" ]; then
|
|
536
|
+
# Model with subtle styling (if enabled and available)
|
|
537
|
+
if [ "$SHOW_MODEL" = "true" ] && [ -n "$MODEL_DISPLAY" ]; then
|
|
310
538
|
[ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
|
|
311
539
|
OUTPUT="${OUTPUT}${DIM}[${RESET}${BOLD}${MODEL_DISPLAY}${RESET}${DIM}]${RESET}"
|
|
312
540
|
fi
|
|
@@ -334,10 +562,21 @@ if [ "$SHOW_WIP" = "true" ] && [ -n "$WIP_DISPLAY" ]; then
|
|
|
334
562
|
OUTPUT="${OUTPUT}${WIP_DISPLAY}"
|
|
335
563
|
fi
|
|
336
564
|
|
|
337
|
-
# Add context usage (if enabled)
|
|
565
|
+
# Add context usage (if enabled) - percentage and/or bar
|
|
338
566
|
if [ "$SHOW_CONTEXT" = "true" ] && [ -n "$CTX_DISPLAY" ]; then
|
|
339
567
|
[ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
|
|
340
|
-
|
|
568
|
+
if [ "$SHOW_CONTEXT_BAR" = "true" ] && [ -n "$CTX_BAR_DISPLAY" ]; then
|
|
569
|
+
# Show both percentage and bar: "45% [▓▓▓▓░░░░]"
|
|
570
|
+
OUTPUT="${OUTPUT}${CTX_DISPLAY} ${CTX_BAR_DISPLAY}"
|
|
571
|
+
else
|
|
572
|
+
OUTPUT="${OUTPUT}${CTX_DISPLAY}"
|
|
573
|
+
fi
|
|
574
|
+
fi
|
|
575
|
+
|
|
576
|
+
# Add session time remaining (if enabled and available)
|
|
577
|
+
if [ "$SHOW_SESSION_TIME" = "true" ] && [ -n "$SESSION_DISPLAY" ]; then
|
|
578
|
+
[ -n "$OUTPUT" ] && OUTPUT="${OUTPUT}${SEP}"
|
|
579
|
+
OUTPUT="${OUTPUT}${SESSION_DISPLAY}"
|
|
341
580
|
fi
|
|
342
581
|
|
|
343
582
|
# Add cost (if enabled)
|