claude-flow-novice 2.2.4 → 2.2.5

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 (288) hide show
  1. package/package.json +9 -8
  2. package/scripts/.claude-flow/metrics/agent-metrics.json +1 -0
  3. package/scripts/.claude-flow/metrics/performance.json +9 -0
  4. package/scripts/.claude-flow/metrics/task-metrics.json +10 -0
  5. package/scripts/CLEANUP_OPTIMIZATION_REPORT.json +312 -0
  6. package/scripts/CLEANUP_PERFORMANCE_OPTIMIZATION.md +387 -0
  7. package/scripts/CLEANUP_QUICK_START.md +268 -0
  8. package/scripts/CLEANUP_TEST_RESULTS.md +205 -0
  9. package/scripts/README.md +339 -0
  10. package/scripts/ace-query.sh +384 -0
  11. package/scripts/agent-token-analysis.js +430 -0
  12. package/scripts/auto-setup.js +332 -0
  13. package/scripts/build/README.md +167 -0
  14. package/scripts/build/build-config.js +27 -0
  15. package/scripts/build/build-prompt-copier.sh +30 -0
  16. package/scripts/build/performance-monitor.js +869 -0
  17. package/scripts/build/prepare-publish.js +150 -0
  18. package/scripts/build/typescript-fixer.js +621 -0
  19. package/scripts/build/unified-builder.sh +428 -0
  20. package/scripts/build/update-bin-version.js +32 -0
  21. package/scripts/build/validate-agents.js +238 -0
  22. package/scripts/build-index.js +43 -0
  23. package/scripts/build-orchestrator.js +320 -0
  24. package/scripts/check-routing-stats.cjs +122 -0
  25. package/scripts/ci-validation.js +375 -0
  26. package/scripts/cleanup-blocking-coordination.sh +420 -0
  27. package/scripts/cleanup-idle-sessions.sh +59 -0
  28. package/scripts/collect-build-metrics.js +65 -0
  29. package/scripts/demo/README.md +79 -0
  30. package/scripts/demo/autoscaling-demo-simplified.js +963 -0
  31. package/scripts/demo/comprehensive-dashboard-test.js +693 -0
  32. package/scripts/demo/confidence-log.js +87 -0
  33. package/scripts/demo/confidence-report.js +82 -0
  34. package/scripts/demo/demo-multi-swarm-coordination.js +325 -0
  35. package/scripts/demo/demo-production-deployment.js +399 -0
  36. package/scripts/demo/demo-visualization-system.js +149 -0
  37. package/scripts/demo/performance-analysis.cjs +71 -0
  38. package/scripts/demo/performance-analysis.js +71 -0
  39. package/scripts/demo/test-autoscaling-demo.js +314 -0
  40. package/scripts/dependency-optimizer.js +349 -0
  41. package/scripts/dependency-security-assessment.js +331 -0
  42. package/scripts/deploy-sdk.sh +176 -0
  43. package/scripts/deployment-readiness-report.json +179 -0
  44. package/scripts/dev/README.md +264 -0
  45. package/scripts/dev/claude-flow-wrapper.sh +35 -0
  46. package/scripts/dev/claude-monitor.py +419 -0
  47. package/scripts/dev/claude-sparc.sh +562 -0
  48. package/scripts/dev/claude-wrapper.sh +17 -0
  49. package/scripts/dev/demo-phase3-compliance.js +172 -0
  50. package/scripts/dev/demo-task-system.ts +224 -0
  51. package/scripts/dev/deployment-validator.js +315 -0
  52. package/scripts/dev/spawn-claude-terminal.sh +32 -0
  53. package/scripts/dev/start-portal.sh +506 -0
  54. package/scripts/dev/start-web-ui.js +15 -0
  55. package/scripts/dev/stop-portal.sh +311 -0
  56. package/scripts/dev/validate-examples.ts +288 -0
  57. package/scripts/dev/validate-phase2.cjs +451 -0
  58. package/scripts/dev/validate-phase2.js +785 -0
  59. package/scripts/dev/validate-phase3.cjs +208 -0
  60. package/scripts/dev/validate-security-remediation.js +1 -0
  61. package/scripts/ecosystem.config.cjs +90 -0
  62. package/scripts/fix-js-extensions.js +167 -0
  63. package/scripts/generate-basic-types.js +73 -0
  64. package/scripts/generate-changelog.js +318 -0
  65. package/scripts/git-hooks/pre-commit.sh +143 -0
  66. package/scripts/health-checks.js +634 -0
  67. package/scripts/hook-wrapper.sh +54 -0
  68. package/scripts/install/README.md +375 -0
  69. package/scripts/install/REDIS_SETUP_VALIDATION.json +245 -0
  70. package/scripts/install/check-prerequisites.js +303 -0
  71. package/scripts/install/config-wizard.js +606 -0
  72. package/scripts/install/dependency-checker.js +385 -0
  73. package/scripts/install/health-check.js +765 -0
  74. package/scripts/install/install.js +256 -0
  75. package/scripts/install/installation-benchmark.js +461 -0
  76. package/scripts/install/quick-install.js +720 -0
  77. package/scripts/install/quick-start-wizard.js +295 -0
  78. package/scripts/install/redis-cli.js +289 -0
  79. package/scripts/install/redis-install-guides.md +407 -0
  80. package/scripts/install/redis-setup.js +559 -0
  81. package/scripts/install/redis-test.js +278 -0
  82. package/scripts/install/service-manager.js +672 -0
  83. package/scripts/install/setup.js +832 -0
  84. package/scripts/install/uninstall.js +526 -0
  85. package/scripts/install/update.js +461 -0
  86. package/scripts/install-pre-commit-hook.sh +127 -0
  87. package/scripts/legacy/README.md +272 -0
  88. package/scripts/legacy/batch-fix-ts.sh +54 -0
  89. package/scripts/legacy/build-migration.sh +105 -0
  90. package/scripts/legacy/build-monitor.js +209 -0
  91. package/scripts/legacy/build-with-filter.sh +84 -0
  92. package/scripts/legacy/build-workaround.sh +71 -0
  93. package/scripts/legacy/fix-ts-advanced.js +358 -0
  94. package/scripts/legacy/fix-ts-final.sh +50 -0
  95. package/scripts/legacy/fix-ts-targeted.sh +49 -0
  96. package/scripts/legacy/fix-typescript-errors.js +305 -0
  97. package/scripts/legacy/force-build.sh +63 -0
  98. package/scripts/legacy/optimize-performance.js +400 -0
  99. package/scripts/legacy/performance-monitor.js +263 -0
  100. package/scripts/legacy/performance-monitoring.js +532 -0
  101. package/scripts/legacy/performance-test-runner.js +645 -0
  102. package/scripts/legacy/quick-fix-ts.js +281 -0
  103. package/scripts/legacy/safe-build.sh +63 -0
  104. package/scripts/memory-monitor-coordinator.js +322 -0
  105. package/scripts/migrate-to-sdk.sh +520 -0
  106. package/scripts/migration/QUICK-START.md +189 -0
  107. package/scripts/migration/QUICK-START.md.backup-1760135091363 +189 -0
  108. package/scripts/migration/README.md +464 -0
  109. package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md +500 -0
  110. package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md.backup-1760135091348 +500 -0
  111. package/scripts/migration/UPDATE-PATHS-README.md +464 -0
  112. package/scripts/migration/UPDATE-PATHS-README.md.backup-1760135091337 +464 -0
  113. package/scripts/migration/example-patterns.json +19 -0
  114. package/scripts/migration/install-arm64.js +78 -0
  115. package/scripts/migration/install.js +83 -0
  116. package/scripts/migration/migrate-hooks.js +173 -0
  117. package/scripts/migration/migration-examples.ts +318 -0
  118. package/scripts/migration/reorganize-workspace.js +504 -0
  119. package/scripts/migration/test-update-paths.js +359 -0
  120. package/scripts/migration/update-paths.js +664 -0
  121. package/scripts/migration/validate-migration.js +647 -0
  122. package/scripts/monitor-loop.sh +65 -0
  123. package/scripts/monitor-memory.sh +47 -0
  124. package/scripts/monitor-migration.js +339 -0
  125. package/scripts/monitor.py +43 -0
  126. package/scripts/monitoring/README.md +178 -0
  127. package/scripts/monitoring/alert-monitor.sh +220 -0
  128. package/scripts/monitoring/analyze-resources.sh +199 -0
  129. package/scripts/monitoring/dashboards/rate-limiting-dashboard.json +211 -0
  130. package/scripts/monitoring/dynamic-monitor.sh +85 -0
  131. package/scripts/monitoring/launch-stability-test.sh +184 -0
  132. package/scripts/monitoring/monitor-test.sh +93 -0
  133. package/scripts/monitoring/pre-test-validation.sh +208 -0
  134. package/scripts/monitoring/quick-test-alerting.sh +118 -0
  135. package/scripts/monitoring/quick-test-rate-limiting.sh +206 -0
  136. package/scripts/monitoring/rate-limiting-monitor.sh +380 -0
  137. package/scripts/monitoring/resource-monitor.sh +126 -0
  138. package/scripts/monitoring/stability-monitor.js +429 -0
  139. package/scripts/monitoring/test-monitor-quick.sh +54 -0
  140. package/scripts/monitoring/view-alerts.sh +307 -0
  141. package/scripts/npm-metrics-collector.js +482 -0
  142. package/scripts/npm-package-validation.cjs +299 -0
  143. package/scripts/optimization/build-optimizer.js +438 -0
  144. package/scripts/optimization/config-validator.js +761 -0
  145. package/scripts/optimization/test-optimization.js +432 -0
  146. package/scripts/optimization/unified-activation.js +839 -0
  147. package/scripts/optimize-package-swarm.js +54 -0
  148. package/scripts/performance/ACTIVATION_COMMANDS.md +292 -0
  149. package/scripts/performance/sqlite-enhanced-activation.sh +583 -0
  150. package/scripts/performance/test-enhanced-backend.sh +504 -0
  151. package/scripts/performance-monitor.js +644 -0
  152. package/scripts/performance-test-runner.js +698 -0
  153. package/scripts/post-deployment-monitoring.js +350 -0
  154. package/scripts/post-edit-pipeline.js +2091 -0
  155. package/scripts/post-install-claude-md.js +78 -0
  156. package/scripts/postinstall.js +79 -0
  157. package/scripts/pre-publish-validation.cjs +212 -0
  158. package/scripts/pre-publish-validation.js +429 -0
  159. package/scripts/redis-lua/cleanup-blocking-coordination.lua +198 -0
  160. package/scripts/release-announcement.js +425 -0
  161. package/scripts/release-notification.js +248 -0
  162. package/scripts/release-rollback.js +376 -0
  163. package/scripts/release-validation.js +460 -0
  164. package/scripts/rollback-sdk.sh +66 -0
  165. package/scripts/run-production-validation.ts +590 -0
  166. package/scripts/run-stability-validation.sh +687 -0
  167. package/scripts/security/README.md +339 -0
  168. package/scripts/security/deployment-validation.cjs +279 -0
  169. package/scripts/security/envelope-encryption-confidence-report.cjs +422 -0
  170. package/scripts/security/install-git-hooks.sh +132 -0
  171. package/scripts/security/install-git-secrets.sh +295 -0
  172. package/scripts/security/rotate-api-keys.js +469 -0
  173. package/scripts/security/ruv-swarm-safe.js +74 -0
  174. package/scripts/security/security-audit.cjs +538 -0
  175. package/scripts/security/setup-redis-auth.sh +397 -0
  176. package/scripts/security/validate-envelope-encryption.cjs +340 -0
  177. package/scripts/security-scan.js +492 -0
  178. package/scripts/src/web/frontend/.claude-flow/metrics/agent-metrics.json +1 -0
  179. package/scripts/src/web/frontend/.claude-flow/metrics/performance.json +9 -0
  180. package/scripts/src/web/frontend/.claude-flow/metrics/task-metrics.json +10 -0
  181. package/scripts/switch-api.sh +158 -0
  182. package/scripts/sync-agents.js +290 -0
  183. package/scripts/test/50-agent-test.js +625 -0
  184. package/scripts/test/NEW_STABILITY_TEST_GUIDE.md +407 -0
  185. package/scripts/test/README.md +236 -0
  186. package/scripts/test/STABILITY_TEST_EXAMPLE.md +347 -0
  187. package/scripts/test/STABILITY_TEST_README.md +480 -0
  188. package/scripts/test/agent-worker.js +309 -0
  189. package/scripts/test/ai-coordination-test.js +650 -0
  190. package/scripts/test/ai-mesh-coordination-test.js +416 -0
  191. package/scripts/test/check-links.ts +274 -0
  192. package/scripts/test/check-performance-regression.ts +168 -0
  193. package/scripts/test/cli-agent-coordination-test.js +313 -0
  194. package/scripts/test/coordinator-multilingual-test.js +396 -0
  195. package/scripts/test/coordinator-transparency-demo.js +585 -0
  196. package/scripts/test/coverage-report.ts +692 -0
  197. package/scripts/test/generate-swarm-tests.js +633 -0
  198. package/scripts/test/integration-test-validation.cjs +253 -0
  199. package/scripts/test/load-test-swarm.js +576 -0
  200. package/scripts/test/mesh-coordination-zero-overlap-test.js +740 -0
  201. package/scripts/test/multilingual-hello-world-test.js +390 -0
  202. package/scripts/test/quick-multilingual-demo.js +464 -0
  203. package/scripts/test/real-agent-test.js +312 -0
  204. package/scripts/test/run-phase3-compliance-tests.js +427 -0
  205. package/scripts/test/run-stability-test-examples.sh +292 -0
  206. package/scripts/test/stability-results/stability-metrics.jsonl +83 -0
  207. package/scripts/test/stability-results/stability-test-report.json +128 -0
  208. package/scripts/test/stability-results/stability-test.log +1827 -0
  209. package/scripts/test/stability-test-50-agents.js +734 -0
  210. package/scripts/test/test-batch-tasks.ts +29 -0
  211. package/scripts/test/test-byzantine-resolution.js +246 -0
  212. package/scripts/test/test-claude-spawn-options.sh +63 -0
  213. package/scripts/test/test-cli-wizard.js +331 -0
  214. package/scripts/test/test-comprehensive.js +401 -0
  215. package/scripts/test/test-coordination-features.ts +238 -0
  216. package/scripts/test/test-fallback-systems.js +276 -0
  217. package/scripts/test/test-init-command.ts +302 -0
  218. package/scripts/test/test-mcp.ts +251 -0
  219. package/scripts/test/test-runner.ts +568 -0
  220. package/scripts/test/test-swarm-integration.sh +92 -0
  221. package/scripts/test/test-swarm.ts +142 -0
  222. package/scripts/test/validation-summary.ts +408 -0
  223. package/scripts/test-cleanup-performance.sh +416 -0
  224. package/scripts/test-dashboard-auth.cjs +203 -0
  225. package/scripts/test-docker-deployment.sh +207 -0
  226. package/scripts/test-npm-package.cjs +167 -0
  227. package/scripts/test-provider-routing.cjs +226 -0
  228. package/scripts/test-routing-telemetry.cjs +147 -0
  229. package/scripts/test-runner.cjs +154 -0
  230. package/scripts/test-zai-10k.cjs +81 -0
  231. package/scripts/test-zai-api.cjs +191 -0
  232. package/scripts/test-zai-diagnostic.cjs +151 -0
  233. package/scripts/test-zai-final.cjs +128 -0
  234. package/scripts/test-zai-with-env.cjs +85 -0
  235. package/scripts/utils/README.md +261 -0
  236. package/scripts/utils/clean-build-artifacts.sh +94 -0
  237. package/scripts/utils/cleanup-root.sh +69 -0
  238. package/scripts/utils/fix-cliffy-imports.js +307 -0
  239. package/scripts/utils/fix-duplicate-imports.js +114 -0
  240. package/scripts/utils/fix-error-handling.cjs +70 -0
  241. package/scripts/utils/fix-import-paths.js +104 -0
  242. package/scripts/utils/fix-imports.js +116 -0
  243. package/scripts/utils/fix-shebang.js +78 -0
  244. package/scripts/utils/fix-test-modules.js +27 -0
  245. package/scripts/utils/fix-timezone-issue-246.js +200 -0
  246. package/scripts/utils/fix-ts-comprehensive.py +182 -0
  247. package/scripts/utils/fix-ts-targeted-batch.js +250 -0
  248. package/scripts/utils/remove-benchmark-conflicts.sh +140 -0
  249. package/scripts/utils/simple-test-fixer.js +190 -0
  250. package/scripts/utils/validate-metrics-structure.cjs +144 -0
  251. package/scripts/validate-agent-hooks.js +506 -0
  252. package/scripts/validate-changelog.js +241 -0
  253. package/scripts/validate-coordination-cli.js +69 -0
  254. package/scripts/validate-coordination-toggle-integration.cjs +501 -0
  255. package/scripts/validate-docker-infrastructure.sh +502 -0
  256. package/scripts/validate-entry-points.js +300 -0
  257. package/scripts/validate-stage3-performance.ts +377 -0
  258. package/scripts/validate-template-bundling.js +180 -0
  259. package/scripts/validation/README.md +33 -0
  260. package/scripts/validation/acl-security-validation.cjs +214 -0
  261. package/scripts/validation/acl-security-validation.js +402 -0
  262. package/scripts/validation/byzantine-verification.js +407 -0
  263. package/scripts/validation/final-phase-2-consensus.cjs +219 -0
  264. package/scripts/validation/final-security-validation.js +791 -0
  265. package/scripts/validation/final-wasm-validation.cjs +840 -0
  266. package/scripts/validation/integration-test-analysis.js +105 -0
  267. package/scripts/validation/phase-0-comprehensive-validation.js +474 -0
  268. package/scripts/validation/phase-0-consensus-report.js +139 -0
  269. package/scripts/validation/phase-0-final-report.js +112 -0
  270. package/scripts/validation/phase-0-redis-consensus-report.js +129 -0
  271. package/scripts/validation/phase-0-validation-improved.js +490 -0
  272. package/scripts/validation/phase-0-validation-test.js +65 -0
  273. package/scripts/validation/phase-1-consensus-report.cjs +342 -0
  274. package/scripts/validation/phase-1-consensus-validation.cjs +551 -0
  275. package/scripts/validation/phase-1-consensus-validation.js +551 -0
  276. package/scripts/validation/phase-2-consensus-report.cjs +186 -0
  277. package/scripts/validation/phase-2-validation.cjs +171 -0
  278. package/scripts/validation/phase-2-validation.js +171 -0
  279. package/scripts/validation/phase-4-consensus-report.js +181 -0
  280. package/scripts/validation/phase-4-final-validation.js +351 -0
  281. package/scripts/validation/phase-5-consensus-report.cjs +113 -0
  282. package/scripts/validation/phase-5-consensus-report.js +113 -0
  283. package/scripts/validation/security-analysis.js +49 -0
  284. package/scripts/validation/security-validation.js +492 -0
  285. package/scripts/validation/simple-security-validation.js +464 -0
  286. package/scripts/verify-installation.js +112 -0
  287. package/scripts/verify-mcp-server.js +86 -0
  288. package/scripts/verify-sdk-phase1.cjs +293 -0
@@ -0,0 +1,419 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import subprocess
4
+ import json
5
+ import sys
6
+ import time
7
+ from datetime import datetime, timedelta, timezone
8
+ import os
9
+ import argparse
10
+ import pytz
11
+
12
+
13
+ def run_ccusage():
14
+ """Execute ccusage blocks --json command and return parsed JSON data."""
15
+ try:
16
+ result = subprocess.run(['ccusage', 'blocks', '--json'], capture_output=True, text=True, check=True)
17
+ return json.loads(result.stdout)
18
+ except subprocess.CalledProcessError as e:
19
+ print(f"Error running ccusage: {e}")
20
+ return None
21
+ except json.JSONDecodeError as e:
22
+ print(f"Error parsing JSON: {e}")
23
+ return None
24
+
25
+
26
+ def format_time(minutes):
27
+ """Format minutes into human-readable time (e.g., '3h 45m')."""
28
+ if minutes < 60:
29
+ return f"{int(minutes)}m"
30
+ hours = int(minutes // 60)
31
+ mins = int(minutes % 60)
32
+ if mins == 0:
33
+ return f"{hours}h"
34
+ return f"{hours}h {mins}m"
35
+
36
+
37
+ def create_token_progress_bar(percentage, width=50):
38
+ """Create a token usage progress bar with bracket style."""
39
+ filled = int(width * percentage / 100)
40
+
41
+ # Create the bar with green fill and red empty space
42
+ green_bar = '█' * filled
43
+ red_bar = '░' * (width - filled)
44
+
45
+ # Color codes
46
+ green = '\033[92m' # Bright green
47
+ red = '\033[91m' # Bright red
48
+ reset = '\033[0m'
49
+
50
+ return f"🟢 [{green}{green_bar}{red}{red_bar}{reset}] {percentage:.1f}%"
51
+
52
+
53
+ def create_time_progress_bar(elapsed_minutes, total_minutes, width=50):
54
+ """Create a time progress bar showing time until reset."""
55
+ if total_minutes <= 0:
56
+ percentage = 0
57
+ else:
58
+ percentage = min(100, (elapsed_minutes / total_minutes) * 100)
59
+
60
+ filled = int(width * percentage / 100)
61
+
62
+ # Create the bar with blue fill and red empty space
63
+ blue_bar = '█' * filled
64
+ red_bar = '░' * (width - filled)
65
+
66
+ # Color codes
67
+ blue = '\033[94m' # Bright blue
68
+ red = '\033[91m' # Bright red
69
+ reset = '\033[0m'
70
+
71
+ remaining_time = format_time(max(0, total_minutes - elapsed_minutes))
72
+ return f"⏰ [{blue}{blue_bar}{red}{red_bar}{reset}] {remaining_time}"
73
+
74
+
75
+ def print_header():
76
+ """Print the stylized header with sparkles."""
77
+ cyan = '\033[96m'
78
+ blue = '\033[94m'
79
+ reset = '\033[0m'
80
+
81
+ # Sparkle pattern
82
+ sparkles = f"{cyan}✦ ✧ ✦ ✧ {reset}"
83
+
84
+ print(f"{sparkles}{cyan}CLAUDE TOKEN MONITOR{reset} {sparkles}")
85
+ print(f"{blue}{'=' * 60}{reset}")
86
+ print()
87
+
88
+
89
+ def get_velocity_indicator(burn_rate):
90
+ """Get velocity emoji based on burn rate."""
91
+ if burn_rate < 50:
92
+ return '🐌' # Slow
93
+ elif burn_rate < 150:
94
+ return '➡️' # Normal
95
+ elif burn_rate < 300:
96
+ return '🚀' # Fast
97
+ else:
98
+ return '⚡' # Very fast
99
+
100
+
101
+ def calculate_hourly_burn_rate(blocks, current_time):
102
+ """Calculate burn rate based on all sessions in the last hour."""
103
+ if not blocks:
104
+ return 0
105
+
106
+ one_hour_ago = current_time - timedelta(hours=1)
107
+ total_tokens = 0
108
+
109
+ for block in blocks:
110
+ start_time_str = block.get('startTime')
111
+ if not start_time_str:
112
+ continue
113
+
114
+ # Parse start time
115
+ start_time = datetime.fromisoformat(start_time_str.replace('Z', '+00:00'))
116
+
117
+ # Skip gaps
118
+ if block.get('isGap', False):
119
+ continue
120
+
121
+ # Determine session end time
122
+ if block.get('isActive', False):
123
+ # For active sessions, use current time
124
+ session_actual_end = current_time
125
+ else:
126
+ # For completed sessions, use actualEndTime or current time
127
+ actual_end_str = block.get('actualEndTime')
128
+ if actual_end_str:
129
+ session_actual_end = datetime.fromisoformat(actual_end_str.replace('Z', '+00:00'))
130
+ else:
131
+ session_actual_end = current_time
132
+
133
+ # Check if session overlaps with the last hour
134
+ if session_actual_end < one_hour_ago:
135
+ # Session ended before the last hour
136
+ continue
137
+
138
+ # Calculate how much of this session falls within the last hour
139
+ session_start_in_hour = max(start_time, one_hour_ago)
140
+ session_end_in_hour = min(session_actual_end, current_time)
141
+
142
+ if session_end_in_hour <= session_start_in_hour:
143
+ continue
144
+
145
+ # Calculate portion of tokens used in the last hour
146
+ total_session_duration = (session_actual_end - start_time).total_seconds() / 60 # minutes
147
+ hour_duration = (session_end_in_hour - session_start_in_hour).total_seconds() / 60 # minutes
148
+
149
+ if total_session_duration > 0:
150
+ session_tokens = block.get('totalTokens', 0)
151
+ tokens_in_hour = session_tokens * (hour_duration / total_session_duration)
152
+ total_tokens += tokens_in_hour
153
+
154
+ # Return tokens per minute
155
+ return total_tokens / 60 if total_tokens > 0 else 0
156
+
157
+
158
+ def get_next_reset_time(current_time, custom_reset_hour=None, timezone_str='Europe/Warsaw'):
159
+ """Calculate next token reset time based on fixed 5-hour intervals.
160
+ Default reset times in specified timezone: 04:00, 09:00, 14:00, 18:00, 23:00
161
+ Or use custom reset hour if provided.
162
+ """
163
+ # Convert to specified timezone
164
+ try:
165
+ target_tz = pytz.timezone(timezone_str)
166
+ except pytz.exceptions.UnknownTimeZoneError:
167
+ print(f"Warning: Unknown timezone '{timezone_str}', using Europe/Warsaw")
168
+ target_tz = pytz.timezone('Europe/Warsaw')
169
+
170
+ # If current_time is timezone-aware, convert to target timezone
171
+ if current_time.tzinfo is not None:
172
+ target_time = current_time.astimezone(target_tz)
173
+ else:
174
+ # Assume current_time is in target timezone if not specified
175
+ target_time = target_tz.localize(current_time)
176
+
177
+ if custom_reset_hour is not None:
178
+ # Use single daily reset at custom hour
179
+ reset_hours = [custom_reset_hour]
180
+ else:
181
+ # Default 5-hour intervals
182
+ reset_hours = [4, 9, 14, 18, 23]
183
+
184
+ # Get current hour and minute
185
+ current_hour = target_time.hour
186
+ current_minute = target_time.minute
187
+
188
+ # Find next reset hour
189
+ next_reset_hour = None
190
+ for hour in reset_hours:
191
+ if current_hour < hour or (current_hour == hour and current_minute == 0):
192
+ next_reset_hour = hour
193
+ break
194
+
195
+ # If no reset hour found today, use first one tomorrow
196
+ if next_reset_hour is None:
197
+ next_reset_hour = reset_hours[0]
198
+ next_reset_date = target_time.date() + timedelta(days=1)
199
+ else:
200
+ next_reset_date = target_time.date()
201
+
202
+ # Create next reset datetime in target timezone
203
+ next_reset = target_tz.localize(
204
+ datetime.combine(next_reset_date, datetime.min.time().replace(hour=next_reset_hour)),
205
+ is_dst=None
206
+ )
207
+
208
+ # Convert back to the original timezone if needed
209
+ if current_time.tzinfo is not None and current_time.tzinfo != target_tz:
210
+ next_reset = next_reset.astimezone(current_time.tzinfo)
211
+
212
+ return next_reset
213
+
214
+
215
+ def parse_args():
216
+ """Parse command line arguments."""
217
+ parser = argparse.ArgumentParser(description='Claude Token Monitor - Real-time token usage monitoring')
218
+ parser.add_argument('--plan', type=str, default='pro',
219
+ choices=['pro', 'max5', 'max20', 'custom_max'],
220
+ help='Claude plan type (default: pro). Use "custom_max" to auto-detect from highest previous block')
221
+ parser.add_argument('--reset-hour', type=int,
222
+ help='Change the reset hour (0-23) for daily limits')
223
+ parser.add_argument('--timezone', type=str, default='Europe/Warsaw',
224
+ help='Timezone for reset times (default: Europe/Warsaw). Examples: US/Eastern, Asia/Tokyo, UTC')
225
+ return parser.parse_args()
226
+
227
+
228
+ def get_token_limit(plan, blocks=None):
229
+ """Get token limit based on plan type."""
230
+ if plan == 'custom_max' and blocks:
231
+ # Find the highest token count from all previous blocks
232
+ max_tokens = 0
233
+ for block in blocks:
234
+ if not block.get('isGap', False) and not block.get('isActive', False):
235
+ tokens = block.get('totalTokens', 0)
236
+ if tokens > max_tokens:
237
+ max_tokens = tokens
238
+ # Return the highest found, or default to pro if none found
239
+ return max_tokens if max_tokens > 0 else 7000
240
+
241
+ limits = {
242
+ 'pro': 7000,
243
+ 'max5': 35000,
244
+ 'max20': 140000
245
+ }
246
+ return limits.get(plan, 7000)
247
+
248
+
249
+ def main():
250
+ """Main monitoring loop."""
251
+ args = parse_args()
252
+
253
+ # For 'custom_max' plan, we need to get data first to determine the limit
254
+ if args.plan == 'custom_max':
255
+ initial_data = run_ccusage()
256
+ if initial_data and 'blocks' in initial_data:
257
+ token_limit = get_token_limit(args.plan, initial_data['blocks'])
258
+ else:
259
+ token_limit = get_token_limit('pro') # Fallback to pro
260
+ else:
261
+ token_limit = get_token_limit(args.plan)
262
+
263
+ try:
264
+ # Initial screen clear and hide cursor
265
+ os.system('clear' if os.name == 'posix' else 'cls')
266
+ print('\033[?25l', end='', flush=True) # Hide cursor
267
+
268
+ while True:
269
+ # Move cursor to top without clearing
270
+ print('\033[H', end='', flush=True)
271
+
272
+ data = run_ccusage()
273
+ if not data or 'blocks' not in data:
274
+ print("Failed to get usage data")
275
+ continue
276
+
277
+ # Find the active block
278
+ active_block = None
279
+ for block in data['blocks']:
280
+ if block.get('isActive', False):
281
+ active_block = block
282
+ break
283
+
284
+ if not active_block:
285
+ print("No active session found")
286
+ continue
287
+
288
+ # Extract data from active block
289
+ tokens_used = active_block.get('totalTokens', 0)
290
+
291
+ # Check if tokens exceed limit and switch to custom_max if needed
292
+ if tokens_used > token_limit and args.plan == 'pro':
293
+ # Auto-switch to custom_max when pro limit is exceeded
294
+ new_limit = get_token_limit('custom_max', data['blocks'])
295
+ if new_limit > token_limit:
296
+ token_limit = new_limit
297
+
298
+ usage_percentage = (tokens_used / token_limit) * 100 if token_limit > 0 else 0
299
+ tokens_left = token_limit - tokens_used
300
+
301
+ # Time calculations
302
+ start_time_str = active_block.get('startTime')
303
+ if start_time_str:
304
+ start_time = datetime.fromisoformat(start_time_str.replace('Z', '+00:00'))
305
+ current_time = datetime.now(start_time.tzinfo)
306
+ elapsed = current_time - start_time
307
+ elapsed_minutes = elapsed.total_seconds() / 60
308
+ else:
309
+ elapsed_minutes = 0
310
+
311
+ session_duration = 300 # 5 hours in minutes
312
+ remaining_minutes = max(0, session_duration - elapsed_minutes)
313
+
314
+ # Calculate burn rate from ALL sessions in the last hour
315
+ burn_rate = calculate_hourly_burn_rate(data['blocks'], current_time)
316
+
317
+ # Reset time calculation - use fixed schedule or custom hour with timezone
318
+ reset_time = get_next_reset_time(current_time, args.reset_hour, args.timezone)
319
+
320
+ # Calculate time to reset
321
+ time_to_reset = reset_time - current_time
322
+ minutes_to_reset = time_to_reset.total_seconds() / 60
323
+
324
+ # Predicted end calculation - when tokens will run out based on burn rate
325
+ if burn_rate > 0 and tokens_left > 0:
326
+ minutes_to_depletion = tokens_left / burn_rate
327
+ predicted_end_time = current_time + timedelta(minutes=minutes_to_depletion)
328
+ else:
329
+ # If no burn rate or tokens already depleted, use reset time
330
+ predicted_end_time = reset_time
331
+
332
+ # Color codes
333
+ cyan = '\033[96m'
334
+ green = '\033[92m'
335
+ blue = '\033[94m'
336
+ red = '\033[91m'
337
+ yellow = '\033[93m'
338
+ white = '\033[97m'
339
+ gray = '\033[90m'
340
+ reset = '\033[0m'
341
+
342
+ # Display header
343
+ print_header()
344
+
345
+ # Token Usage section
346
+ print(f"📊 {white}Token Usage:{reset} {create_token_progress_bar(usage_percentage)}")
347
+ print()
348
+
349
+ # Time to Reset section - calculate progress based on time since last reset
350
+ # Estimate time since last reset (max 5 hours = 300 minutes)
351
+ time_since_reset = max(0, 300 - minutes_to_reset)
352
+ print(f"⏳ {white}Time to Reset:{reset} {create_time_progress_bar(time_since_reset, 300)}")
353
+ print()
354
+
355
+ # Detailed stats
356
+ print(f"🎯 {white}Tokens:{reset} {white}{tokens_used:,}{reset} / {gray}~{token_limit:,}{reset} ({cyan}{tokens_left:,} left{reset})")
357
+ print(f"🔥 {white}Burn Rate:{reset} {yellow}{burn_rate:.1f}{reset} {gray}tokens/min{reset}")
358
+ print()
359
+
360
+ # Predictions - convert to configured timezone for display
361
+ try:
362
+ local_tz = pytz.timezone(args.timezone)
363
+ except:
364
+ local_tz = pytz.timezone('Europe/Warsaw')
365
+ predicted_end_local = predicted_end_time.astimezone(local_tz)
366
+ reset_time_local = reset_time.astimezone(local_tz)
367
+
368
+ predicted_end_str = predicted_end_local.strftime("%H:%M")
369
+ reset_time_str = reset_time_local.strftime("%H:%M")
370
+ print(f"🏁 {white}Predicted End:{reset} {predicted_end_str}")
371
+ print(f"🔄 {white}Token Reset:{reset} {reset_time_str}")
372
+ print()
373
+
374
+ # Show notification if we switched to custom_max
375
+ show_switch_notification = False
376
+ if tokens_used > 7000 and args.plan == 'pro' and token_limit > 7000:
377
+ show_switch_notification = True
378
+
379
+ # Notification when tokens exceed max limit
380
+ show_exceed_notification = tokens_used > token_limit
381
+
382
+ # Show notifications
383
+ if show_switch_notification:
384
+ print(f"🔄 {yellow}Tokens exceeded Pro limit - switched to custom_max ({token_limit:,}){reset}")
385
+ print()
386
+
387
+ if show_exceed_notification:
388
+ print(f"🚨 {red}TOKENS EXCEEDED MAX LIMIT! ({tokens_used:,} > {token_limit:,}){reset}")
389
+ print()
390
+
391
+ # Warning if tokens will run out before reset
392
+ if predicted_end_time < reset_time:
393
+ print(f"⚠️ {red}Tokens will run out BEFORE reset!{reset}")
394
+ print()
395
+
396
+ # Status line
397
+ current_time_str = datetime.now().strftime("%H:%M:%S")
398
+ print(f"⏰ {gray}{current_time_str}{reset} 📝 {cyan}Smooth sailing...{reset} | {gray}Ctrl+C to exit{reset} 🟨")
399
+
400
+ # Clear any remaining lines below to prevent artifacts
401
+ print('\033[J', end='', flush=True)
402
+
403
+ time.sleep(3)
404
+
405
+ except KeyboardInterrupt:
406
+ # Show cursor before exiting
407
+ print('\033[?25h', end='', flush=True)
408
+ print(f"\n\n{cyan}Monitoring stopped.{reset}")
409
+ # Clear the terminal
410
+ os.system('clear' if os.name == 'posix' else 'cls')
411
+ sys.exit(0)
412
+ except Exception:
413
+ # Show cursor on any error
414
+ print('\033[?25h', end='', flush=True)
415
+ raise
416
+
417
+
418
+ if __name__ == "__main__":
419
+ main()