@the-bearded-bear/claude-craft 5.6.0 → 5.7.0-next.bf058ea

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.
@@ -0,0 +1,353 @@
1
+ #!/usr/bin/env bash
2
+ # =============================================================================
3
+ # Agent Teams - Cost Dashboard
4
+ # Displays a comparative cost/time table BEFORE launching a team operation
5
+ #
6
+ # Uses cost-estimator.sh functions internally for calculations.
7
+ # =============================================================================
8
+ set -euo pipefail
9
+
10
+ # =============================================================================
11
+ # Resolve script directory and source dependencies
12
+ # =============================================================================
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ source "${SCRIPT_DIR}/cost-estimator.sh"
16
+
17
+ # =============================================================================
18
+ # Dashboard Box Drawing Characters
19
+ # =============================================================================
20
+
21
+ DASH_TL="╔"
22
+ DASH_TR="╗"
23
+ DASH_BL="╚"
24
+ DASH_BR="╝"
25
+ DASH_H="═"
26
+ DASH_V="║"
27
+ DASH_ML="╠"
28
+ DASH_MR="╣"
29
+
30
+ # =============================================================================
31
+ # Dashboard Configuration
32
+ # =============================================================================
33
+
34
+ DASHBOARD_WIDTH=60
35
+ DRY_RUN=false
36
+
37
+ # =============================================================================
38
+ # Usage
39
+ # =============================================================================
40
+
41
+ show_help() {
42
+ cat <<'HELP'
43
+ Agent Teams - Cost Dashboard
44
+
45
+ Displays a comparative table showing estimated cost, time, and token
46
+ usage for sequential vs parallel execution BEFORE launching a team.
47
+
48
+ USAGE:
49
+ cost-dashboard.sh [OPTIONS]
50
+
51
+ OPTIONS:
52
+ --techs N Number of technology stacks (default: 2)
53
+ --checks N Number of checks per technology (default: 5)
54
+ --worker-model M Worker agent model: haiku|sonnet|opus (default: sonnet)
55
+ --leader-model M Leader agent model: haiku|sonnet|opus (default: opus)
56
+ --tokens-per-check N Override tokens per check estimate (default: 12500)
57
+ --width N Dashboard width in characters (default: 60)
58
+ --dry-run Show what would be displayed without color
59
+ --help Show this help
60
+
61
+ EXAMPLES:
62
+ # Show cost comparison for 2-tech project
63
+ cost-dashboard.sh --techs 2 --checks 5
64
+
65
+ # Cost comparison with Haiku workers (cheaper)
66
+ cost-dashboard.sh --techs 3 --worker-model haiku
67
+
68
+ # Dry-run to see plain-text output
69
+ cost-dashboard.sh --techs 2 --dry-run
70
+
71
+ RECOMMENDATION LOGIC:
72
+ USE PARALLEL when:
73
+ - Time saved > 30% AND extra token cost < 50%
74
+ STAY SEQUENTIAL otherwise.
75
+ HELP
76
+ }
77
+
78
+ # =============================================================================
79
+ # Argument Parsing
80
+ # =============================================================================
81
+
82
+ dashboard_parse_args() {
83
+ local n_techs=$DEFAULT_TECHS
84
+ local n_checks=$DEFAULT_CHECKS
85
+ local worker_model=$DEFAULT_WORKER_MODEL
86
+ local leader_model=$DEFAULT_LEADER_MODEL
87
+ local tokens_check=$TOKENS_PER_CHECK
88
+
89
+ while [[ $# -gt 0 ]]; do
90
+ case "$1" in
91
+ --techs)
92
+ n_techs="$2"
93
+ shift 2
94
+ ;;
95
+ --checks)
96
+ n_checks="$2"
97
+ shift 2
98
+ ;;
99
+ --worker-model)
100
+ worker_model="$2"
101
+ shift 2
102
+ ;;
103
+ --leader-model)
104
+ leader_model="$2"
105
+ shift 2
106
+ ;;
107
+ --tokens-per-check)
108
+ tokens_check="$2"
109
+ shift 2
110
+ ;;
111
+ --width)
112
+ DASHBOARD_WIDTH="$2"
113
+ shift 2
114
+ ;;
115
+ --dry-run)
116
+ DRY_RUN=true
117
+ shift
118
+ ;;
119
+ --help|-h)
120
+ show_help
121
+ exit 0
122
+ ;;
123
+ *)
124
+ echo "ERROR: Unknown option: $1" >&2
125
+ echo "Use --help for usage information." >&2
126
+ exit 1
127
+ ;;
128
+ esac
129
+ done
130
+
131
+ # Validate inputs
132
+ if [[ ! "$n_techs" =~ ^[1-9][0-9]*$ ]]; then
133
+ echo "ERROR: --techs must be a positive integer, got: $n_techs" >&2
134
+ exit 1
135
+ fi
136
+ if [[ ! "$n_checks" =~ ^[1-9][0-9]*$ ]]; then
137
+ echo "ERROR: --checks must be a positive integer, got: $n_checks" >&2
138
+ exit 1
139
+ fi
140
+ if [[ -z "${MODEL_INPUT_PRICE[$worker_model]+x}" ]]; then
141
+ echo "ERROR: --worker-model must be haiku|sonnet|opus, got: $worker_model" >&2
142
+ exit 1
143
+ fi
144
+ if [[ -z "${MODEL_INPUT_PRICE[$leader_model]+x}" ]]; then
145
+ echo "ERROR: --leader-model must be haiku|sonnet|opus, got: $leader_model" >&2
146
+ exit 1
147
+ fi
148
+
149
+ # Export to globals
150
+ N_TECHS=$n_techs
151
+ N_CHECKS=$n_checks
152
+ WORKER_MODEL=$worker_model
153
+ LEADER_MODEL=$leader_model
154
+ TOKENS_PER_CHECK=$tokens_check
155
+ }
156
+
157
+ # =============================================================================
158
+ # Dashboard Rendering Helpers
159
+ # =============================================================================
160
+
161
+ # Print a horizontal line
162
+ dash_line() {
163
+ local char="${1:-$DASH_H}"
164
+ local left="${2:-$DASH_TL}"
165
+ local right="${3:-$DASH_TR}"
166
+ local w=$((DASHBOARD_WIDTH - 2))
167
+
168
+ printf "%s" "$left"
169
+ for ((i = 0; i < w; i++)); do printf "%s" "$char"; done
170
+ printf "%s\n" "$right"
171
+ }
172
+
173
+ # Print a padded content line
174
+ dash_content() {
175
+ local text="$1"
176
+ local text_len=${#text}
177
+ local padding=$((DASHBOARD_WIDTH - text_len - 4))
178
+
179
+ if [[ $padding -lt 0 ]]; then
180
+ padding=0
181
+ fi
182
+
183
+ printf "%s %s%*s%s\n" "$DASH_V" "$text" "$padding" "" "$DASH_V"
184
+ }
185
+
186
+ # Print an empty line inside the box
187
+ dash_empty() {
188
+ local w=$((DASHBOARD_WIDTH - 2))
189
+ printf "%s%*s%s\n" "$DASH_V" "$w" "" "$DASH_V"
190
+ }
191
+
192
+ # =============================================================================
193
+ # Main Dashboard Display
194
+ # =============================================================================
195
+
196
+ render_cost_dashboard() {
197
+ # Calculate all estimates
198
+ local seq_tokens
199
+ local par_tokens
200
+ local seq_time
201
+ local par_time
202
+ local seq_cost
203
+ local par_cost
204
+ local recommendation
205
+ local break_even
206
+
207
+ seq_tokens=$(estimate_sequential_tokens "$N_TECHS" "$N_CHECKS" "$TOKENS_PER_CHECK")
208
+ par_tokens=$(estimate_parallel_tokens "$N_TECHS" "$N_CHECKS" "$TOKENS_PER_CHECK" "$WORKER_MODEL")
209
+ seq_time=$(estimate_sequential_time "$N_TECHS" "$N_CHECKS")
210
+ par_time=$(estimate_parallel_time "$N_TECHS" "$N_CHECKS")
211
+ seq_cost=$(calculate_cost "$LEADER_MODEL" "$seq_tokens")
212
+ par_cost=$(calculate_parallel_cost "$LEADER_MODEL" "$WORKER_MODEL" "$par_tokens" "$N_TECHS")
213
+ recommendation=$(get_recommendation "$seq_time" "$par_time" "$seq_tokens" "$par_tokens")
214
+ break_even=$(calculate_break_even "$N_TECHS")
215
+
216
+ # Derived values
217
+ local token_overhead_pct
218
+ token_overhead_pct=$(awk "BEGIN {
219
+ if ($seq_tokens <= 0) print 0
220
+ else printf \"%d\", (($par_tokens - $seq_tokens) / $seq_tokens) * 100
221
+ }")
222
+
223
+ local time_saved_pct
224
+ time_saved_pct=$(awk "BEGIN {
225
+ if ($seq_time <= 0) print 0
226
+ else printf \"%d\", (($seq_time - $par_time) / $seq_time) * 100
227
+ }")
228
+
229
+ local time_saved_min
230
+ time_saved_min=$(awk "BEGIN { printf \"%.1f\", $seq_time - $par_time }")
231
+
232
+ local seq_tokens_fmt
233
+ seq_tokens_fmt=$(format_tokens "$seq_tokens")
234
+
235
+ local par_tokens_fmt
236
+ par_tokens_fmt=$(format_tokens "$par_tokens")
237
+
238
+ local seq_cost_fmt
239
+ seq_cost_fmt=$(format_cost "$seq_cost")
240
+
241
+ local par_cost_fmt
242
+ par_cost_fmt=$(format_cost "$par_cost")
243
+
244
+ # Render the dashboard box
245
+ echo ""
246
+ dash_line "$DASH_H" "$DASH_TL" "$DASH_TR"
247
+ dash_content "Agent Teams Cost Estimate"
248
+ dash_line "$DASH_H" "$DASH_ML" "$DASH_MR"
249
+ dash_content "Config: ${N_TECHS} techs x ${N_CHECKS} checks | ${WORKER_MODEL} workers"
250
+ dash_line "$DASH_H" "$DASH_ML" "$DASH_MR"
251
+ dash_content "Sequential: ~${seq_tokens_fmt} tokens | ~${seq_time} min | ~${seq_cost_fmt}"
252
+ dash_content "Parallel: ~${par_tokens_fmt} tokens | ~${par_time} min | ~${par_cost_fmt}"
253
+ dash_line "$DASH_H" "$DASH_ML" "$DASH_MR"
254
+ dash_content "Time saved: ${time_saved_min} min (${time_saved_pct}%)"
255
+ dash_content "Extra cost: +${token_overhead_pct}% tokens"
256
+ dash_content "Break-even: ${break_even}"
257
+ dash_line "$DASH_H" "$DASH_ML" "$DASH_MR"
258
+ dash_content "Recommendation: ${recommendation}"
259
+ dash_line "$DASH_H" "$DASH_BL" "$DASH_BR"
260
+ echo ""
261
+ }
262
+
263
+ # =============================================================================
264
+ # Dry Run: Plain Text Output
265
+ # =============================================================================
266
+
267
+ render_dry_run_dashboard() {
268
+ local seq_tokens
269
+ local par_tokens
270
+
271
+ seq_tokens=$(estimate_sequential_tokens "$N_TECHS" "$N_CHECKS" "$TOKENS_PER_CHECK")
272
+ par_tokens=$(estimate_parallel_tokens "$N_TECHS" "$N_CHECKS" "$TOKENS_PER_CHECK" "$WORKER_MODEL")
273
+
274
+ local seq_time par_time seq_cost par_cost recommendation
275
+
276
+ seq_time=$(estimate_sequential_time "$N_TECHS" "$N_CHECKS")
277
+ par_time=$(estimate_parallel_time "$N_TECHS" "$N_CHECKS")
278
+ seq_cost=$(calculate_cost "$LEADER_MODEL" "$seq_tokens")
279
+ par_cost=$(calculate_parallel_cost "$LEADER_MODEL" "$WORKER_MODEL" "$par_tokens" "$N_TECHS")
280
+ recommendation=$(get_recommendation "$seq_time" "$par_time" "$seq_tokens" "$par_tokens")
281
+
282
+ local token_overhead_pct
283
+ token_overhead_pct=$(awk "BEGIN {
284
+ if ($seq_tokens <= 0) print 0
285
+ else printf \"%d\", (($par_tokens - $seq_tokens) / $seq_tokens) * 100
286
+ }")
287
+
288
+ local time_saved_pct
289
+ time_saved_pct=$(awk "BEGIN {
290
+ if ($seq_time <= 0) print 0
291
+ else printf \"%d\", (($seq_time - $par_time) / $seq_time) * 100
292
+ }")
293
+
294
+ cat <<EOF
295
+ === Agent Teams Cost Estimate (Dry Run) ===
296
+
297
+ Configuration:
298
+ Technologies: $N_TECHS
299
+ Checks per tech: $N_CHECKS
300
+ Worker model: $WORKER_MODEL
301
+ Leader model: $LEADER_MODEL
302
+ Agents: $((N_TECHS + 1)) (1 leader + $N_TECHS workers)
303
+
304
+ Sequential Estimate:
305
+ Tokens: ~$(format_tokens "$seq_tokens")
306
+ Time: ~${seq_time} min
307
+ Cost: ~$(format_cost "$seq_cost")
308
+
309
+ Parallel Estimate:
310
+ Tokens: ~$(format_tokens "$par_tokens")
311
+ Time: ~${par_time} min
312
+ Cost: ~$(format_cost "$par_cost")
313
+
314
+ Comparison:
315
+ Time saved: $(awk "BEGIN { printf \"%.1f\", $seq_time - $par_time }") min (${time_saved_pct}%)
316
+ Extra tokens: +${token_overhead_pct}%
317
+
318
+ Recommendation: $recommendation
319
+ EOF
320
+ }
321
+
322
+ # =============================================================================
323
+ # Public API: display_cost_dashboard
324
+ # Can be called from other scripts after sourcing this file
325
+ # =============================================================================
326
+
327
+ display_cost_dashboard() {
328
+ local techs="${1:-$DEFAULT_TECHS}"
329
+ local checks="${2:-$DEFAULT_CHECKS}"
330
+ local worker="${3:-$DEFAULT_WORKER_MODEL}"
331
+ local leader="${4:-$DEFAULT_LEADER_MODEL}"
332
+
333
+ N_TECHS=$techs
334
+ N_CHECKS=$checks
335
+ WORKER_MODEL=$worker
336
+ LEADER_MODEL=$leader
337
+
338
+ render_cost_dashboard
339
+ }
340
+
341
+ # =============================================================================
342
+ # Main Entrypoint
343
+ # =============================================================================
344
+
345
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
346
+ dashboard_parse_args "$@"
347
+
348
+ if [[ "$DRY_RUN" == "true" ]]; then
349
+ render_dry_run_dashboard
350
+ else
351
+ render_cost_dashboard
352
+ fi
353
+ fi