@agentunion/kite 1.5.0 → 1.6.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 (573) hide show
  1. package/.claude/skills/kite/checklists/feature-checklist.md +496 -0
  2. package/.claude/skills/kite/references/event-patterns.md +180 -0
  3. package/.claude/skills/kite/references/health-check.md +202 -0
  4. package/.claude/skills/kite/references/http-service.md +199 -0
  5. package/.claude/skills/kite/references/module-md-spec.md +172 -0
  6. package/.claude/skills/kite/references/multi-connection.md +147 -0
  7. package/.claude/skills/kite/references/rpc-patterns.md +199 -0
  8. package/.claude/skills/kite/references/shutdown-sequence.md +146 -0
  9. package/.claude/skills/kite/references/stdin-protocol.md +147 -0
  10. package/.claude/skills/kite/references/test-center-integration.md +178 -0
  11. package/.claude/skills/kite/references/ws-lifecycle.md +301 -0
  12. package/.claude/skills/kite/skill.md +272 -0
  13. package/.claude/skills/kite/templates/go/README.md +20 -0
  14. package/.claude/skills/kite/templates/node/entry.js +134 -0
  15. package/.claude/skills/kite/templates/node/module.md +16 -0
  16. package/.claude/skills/kite/templates/node/server.js +351 -0
  17. package/.claude/skills/kite/templates/node/server_http.js +90 -0
  18. package/.claude/skills/kite/templates/python/entry.py +425 -0
  19. package/.claude/skills/kite/templates/python/module.md +26 -0
  20. package/.claude/skills/kite/templates/python/server.py +447 -0
  21. package/.claude/skills/kite/templates/python/server_http.py +433 -0
  22. package/cli.js +38 -4
  23. package/core/env_checker.py +96 -0
  24. package/docs/05-/347/237/255/344/277/241/350/256/244/350/257/201/344/270/216/347/224/250/346/210/267/344/277/241/346/201/257/346/216/245/345/217/243/346/226/207/346/241/243.md +507 -0
  25. package/docs/ACP/345/215/217/350/256/256/345/205/274/345/256/271/346/226/271/346/241/210.md +138 -0
  26. package/docs/CI/344/270/216AI/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/346/226/271/346/241/210.md +75 -0
  27. package/docs/CLI/345/274/200/345/217/221/350/256/241/345/210/222.md +595 -0
  28. package/docs/ClaudeCode/350/277/234/347/250/213/345/215/217/344/275/234/347/263/273/347/273/237-/346/212/200/346/234/257/350/257/204/344/274/260.md +535 -0
  29. package/docs/ClaudeCode/350/277/234/347/250/213/345/215/217/344/275/234/347/263/273/347/273/237/350/256/276/350/256/241.md +631 -0
  30. package/docs/Evol-App/344/275/277/347/224/250KernelClient/346/224/271/351/200/240/345/256/214/346/210/220.md +342 -0
  31. package/docs/Evol/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/346/246/202/350/246/201.md +604 -0
  32. package/docs/Evol/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/350/256/276/350/256/241.md +1708 -0
  33. package/docs/Evol/346/250/241/345/235/227/350/256/276/350/256/241/346/226/271/346/241/210.md +1154 -0
  34. package/docs/Evol/351/241/265/351/235/242/346/217/222/344/273/266/345/214/226-Evol/346/250/241/345/235/227/345/256/236/346/226/275/346/214/207/345/215/227.md +403 -0
  35. package/docs/Evol/351/241/265/351/235/242/346/217/222/344/273/266/345/214/226-/345/244/226/351/203/250/346/250/241/345/235/227/346/216/245/345/205/245/346/214/207/345/215/227.md +468 -0
  36. package/docs/HTTP-RPC/350/277/201/347/247/273/345/210/260WebSocket/350/256/241/345/210/222.md +318 -0
  37. package/docs/INDEX.md +388 -0
  38. package/docs/KITE_DOCS_GUIDE.md +33 -0
  39. package/docs/Kernel-Client-Kite-Token/346/224/257/346/214/201/345/256/236/346/226/275/345/256/214/346/210/220.md +330 -0
  40. package/docs/Kernel/344/270/273/345/212/250Ping/346/234/272/345/210/266-/346/255/243/347/241/256/345/256/236/347/216/260.md +235 -0
  41. package/docs/Kernel/344/270/273/345/212/250Ping/346/234/272/345/210/266/345/256/236/346/226/275/346/200/273/347/273/223.md +204 -0
  42. package/docs/Kite/345/256/211/350/243/205/351/227/256/351/242/230/350/247/243/345/206/263/346/226/271/346/241/210.md +362 -0
  43. package/docs/Kite/346/216/247/345/210/266/345/217/260/346/217/222/344/273/266/345/214/226/346/236/266/346/236/204/350/256/276/350/256/241-/347/273/210/346/236/201/347/233/256/346/240/207.md +721 -0
  44. package/docs/Kite/346/216/247/345/210/266/345/217/260/347/273/237/344/270/200WebSocket/346/224/271/351/200/240/346/226/271/346/241/210.md +821 -0
  45. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/01-/346/241/206/346/236/266/345/256/232/344/275/215.md +12 -0
  46. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/02-/346/240/270/345/277/203/346/246/202/345/277/265.md +341 -0
  47. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/03-/347/263/273/347/273/237/346/236/266/346/236/204.md +257 -0
  48. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/04-/346/250/241/345/235/227/350/247/204/350/214/203.md +263 -0
  49. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/05-/346/240/270/345/277/203/346/265/201/347/250/213-/346/226/260/347/211/210.md +267 -0
  50. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/05-/346/240/270/345/277/203/346/265/201/347/250/213.md +149 -0
  51. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/06-/347/233/256/345/275/225/347/273/223/346/236/204.md +231 -0
  52. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/07-/346/225/260/346/215/256/346/250/241/345/236/213.md +68 -0
  53. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/08-/346/211/251/345/261/225/346/200/247.md +34 -0
  54. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/09-/344/270/216/345/205/267/344/275/223/345/272/224/347/224/250/347/232/204/345/205/263/347/263/273.md +22 -0
  55. package/docs/Kite/346/241/206/346/236/266/350/256/276/350/256/241/README.md +46 -0
  56. package/docs/Kite/347/263/273/347/273/237/345/220/257/345/212/250/346/265/201/347/250/213.md +567 -0
  57. package/docs/Launcher/345/220/257/345/212/250/345/231/250/346/226/207/346/241/243.md +745 -0
  58. package/docs/Polyglot/350/277/220/350/241/214/346/227/266/344/270/216Clawdbot/345/205/274/345/256/271/346/200/247/350/256/276/350/256/241.md +321 -0
  59. package/docs/Redis/344/270/216/346/250/241/345/235/227/345/244/232/345/256/236/344/276/213/346/226/271/346/241/210.md +438 -0
  60. package/docs/Relay-Kite-Token/350/256/244/350/257/201/345/256/236/346/226/275/345/256/214/346/210/220.md +178 -0
  61. package/docs/Relay-Token/346/235/203/351/231/220/351/205/215/347/275/256/351/252/214/350/257/201.md +113 -0
  62. package/docs/Watchdog/345/201/245/345/272/267/346/243/200/346/237/245/344/270/216WebSocket-Ping/346/234/272/345/210/266/345/210/206/346/236/220.md +367 -0
  63. package/docs/Watchdog/350/265/204/346/272/220/347/233/221/346/216/247/347/255/226/347/225/245.md +92 -0
  64. package/docs/WebSocket/346/216/245/346/224/266/345/276/252/347/216/257/346/255/273/351/224/201/351/230/262/350/214/203/350/247/204/350/214/203.md +357 -0
  65. package/docs/WebSocket/350/277/236/346/216/245/351/237/247/346/200/247/344/270/216/351/207/215/350/277/236/346/234/272/345/210/266/345/256/214/346/225/264/346/226/271/346/241/210.md +531 -0
  66. package/docs/WebSocket/350/277/236/346/216/245/351/237/247/346/200/247/346/226/271/346/241/210.md +169 -0
  67. package/docs/WebSocket/351/207/215/350/277/236/346/234/272/345/210/266/346/265/213/350/257/225/346/212/245/345/221/212.md +169 -0
  68. package/docs/WebSocket/351/207/215/350/277/236/351/200/200/351/201/277/346/234/272/345/210/266/346/226/271/346/241/210.md +394 -0
  69. package/docs/Web/346/250/241/345/235/227/344/270/216Evol/346/250/241/345/235/227/351/207/215/346/236/204/345/210/206/346/236/220.md +521 -0
  70. package/docs/audit-api-guide.md +68 -0
  71. package/docs/audit-module-design.md +315 -0
  72. package/docs/audit-module-implementation-summary.md +149 -0
  73. package/docs/llm-context-design.md +52 -0
  74. package/docs/llm-test-enhancement-plan.md +970 -0
  75. package/docs/logs-api-guide.md +42 -0
  76. package/docs/npm/345/214/205Python/347/216/257/345/242/203/347/256/241/347/220/206/346/226/271/346/241/210.md +302 -0
  77. package/docs/npm/345/217/221/345/270/203/344/270/216CLI/344/275/277/347/224/250/346/214/207/345/215/227.md +245 -0
  78. package/docs/stdio/344/270/216/347/253/257/345/217/243/345/217/221/347/216/260/351/207/215/346/236/204.md +480 -0
  79. package/docs/web/346/250/241/345/235/227/344/270/255/350/275/254/346/234/215/345/212/241/350/256/276/350/256/241/346/226/271/346/241/210.md +449 -0
  80. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/346/234/272/345/210/266.md +388 -0
  81. package/docs//344/272/213/344/273/266/345/244/204/347/220/206/350/247/204/350/214/203.md +113 -0
  82. package/docs//344/272/213/344/273/266/350/256/242/351/230/205/351/200/232/351/205/215/347/254/246/350/247/204/350/214/203.md +256 -0
  83. package/docs//344/272/213/344/273/266/351/230/237/345/210/227/345/274/271/346/200/247/347/256/241/347/220/206.md +449 -0
  84. package/docs//344/272/244/344/272/222/345/274/217/347/273/210/347/253/257/346/216/247/345/210/266/346/226/271/346/241/210.md +301 -0
  85. package/docs//344/273/243/347/220/206/345/220/257/345/212/250/345/231/250/344/270/216/345/256/271/345/231/250/345/214/226.md +140 -0
  86. package/docs//344/273/243/347/240/201/347/273/237/350/256/241/345/267/245/345/205/267/344/275/277/347/224/250/350/257/264/346/230/216.md +217 -0
  87. package/docs//344/274/230/351/233/205/351/200/200/345/207/272/350/247/204/350/214/203.md +362 -0
  88. package/docs//344/276/235/350/265/226/347/256/241/347/220/206/350/257/264/346/230/216.md +141 -0
  89. package/docs//344/277/256/345/244/215/346/235/203/351/231/220/351/227/256/351/242/230-evol-RPC/346/235/203/351/231/220.md +268 -0
  90. package/docs//345/210/240/351/231/244kernel-client-example/345/256/214/346/210/220.md +309 -0
  91. package/docs//345/210/240/351/231/244ws-management/345/256/214/346/210/220.md +418 -0
  92. package/docs//345/220/257/345/212/250/344/274/230/345/214/226/346/226/271/346/241/210.md +522 -0
  93. package/docs//345/220/257/345/212/250/344/276/235/350/265/226/344/270/216/346/216/222/345/272/217.md +105 -0
  94. package/docs//345/256/211/350/243/205/350/204/232/346/234/254/345/274/200/345/217/221/346/226/207/346/241/243.md +643 -0
  95. package/docs//345/256/214/346/225/264/345/220/257/345/212/250/346/265/201/347/250/213/350/256/276/350/256/241.md +452 -0
  96. package/docs//345/256/236/347/216/260/350/247/204/345/210/222.md +195 -0
  97. package/docs//345/277/203/350/267/263/346/234/272/345/210/266/351/207/215/346/236/204/346/200/273/347/273/223.md +166 -0
  98. package/docs//346/217/241/346/211/213/350/256/244/350/257/201/346/226/271/346/241/210-/345/256/211/345/205/250/345/256/241/346/237/245.md +176 -0
  99. package/docs//346/217/241/346/211/213/350/256/244/350/257/201/346/226/271/346/241/210.md +908 -0
  100. package/docs//346/226/207/346/241/243/346/233/264/346/226/260/346/270/205/345/215/225.md +83 -0
  101. package/docs//346/227/245/345/277/227/344/270/216/345/274/202/345/270/270/345/244/204/347/220/206/350/247/204/350/214/203.md +829 -0
  102. package/docs//346/227/245/345/277/227/350/260/203/350/257/225/345/256/236/346/210/230/346/214/207/345/215/227.md +25 -0
  103. package/docs//346/236/266/346/236/204/345/200/237/351/211/264/346/214/207/345/215/227.md +977 -0
  104. package/docs//346/236/266/346/236/204/346/224/271/351/200/240-/345/256/214/346/210/220/346/200/273/347/273/223.md +440 -0
  105. package/docs//346/236/266/346/236/204/347/216/260/347/212/266/344/270/216/347/273/210/346/236/201/347/233/256/346/240/207/345/257/271/346/257/224/345/210/206/346/236/220.md +508 -0
  106. package/docs//346/250/241/345/235/227/345/244/232/350/277/236/346/216/245/346/216/247/345/210/266/347/255/226/347/225/245.md +220 -0
  107. package/docs//346/250/241/345/235/227/345/256/211/350/243/205/346/234/272/345/210/266/350/256/276/350/256/241.md +500 -0
  108. package/docs//346/250/241/345/235/227/345/274/200/345/217/221/346/214/207/345/215/227.md +1824 -0
  109. package/docs//346/250/241/345/235/227/347/203/255/346/233/264/346/226/260.md +89 -0
  110. package/docs//346/250/241/345/235/227/350/277/234/347/250/213/351/203/250/347/275/262/345/274/200/345/217/221/350/247/204/350/214/203.md +460 -0
  111. package/docs//346/250/241/345/235/227/351/200/200/345/207/272/346/234/272/345/210/266/345/256/214/346/225/264/346/226/271/346/241/210.md +303 -0
  112. package/docs//346/250/241/345/235/227/351/205/215/347/275/256/345/212/240/350/275/275/344/270/216/347/203/255/351/207/215/350/275/275/350/247/204/350/214/203.md +369 -0
  113. package/docs//346/265/213/350/257/225/344/270/255/345/277/203/346/267/273/345/212/240/346/250/241/345/235/227/346/265/213/350/257/225/346/214/207/345/215/227.md +147 -0
  114. package/docs//347/211/210/346/234/254/351/224/201/345/256/232/347/216/257/345/242/203/347/256/241/347/220/206/346/226/271/346/241/210.md +331 -0
  115. package/docs//347/216/257/345/242/203/345/217/230/351/207/217/344/270/216/350/277/220/350/241/214/346/227/266/347/233/256/345/275/225/350/256/276/350/256/241.md +499 -0
  116. package/docs//347/216/257/345/242/203/347/256/241/347/220/206/345/256/214/346/225/264/346/226/271/346/241/210.md +334 -0
  117. package/docs//350/231/232/346/213/237/346/250/241/345/235/227/344/270/255/350/275/254/346/234/215/345/212/241/345/256/214/346/225/264/350/256/276/350/256/241.md +1496 -0
  118. package/docs//350/231/232/346/213/237/347/216/257/345/242/203/345/267/245/344/275/234/345/216/237/347/220/206.md +163 -0
  119. package/docs//350/256/241/345/210/222/347/256/241/347/220/206/345/231/250/344/275/277/347/224/250/346/214/207/345/215/227.md +196 -0
  120. package/docs//350/256/244/350/257/201/346/250/241/345/235/227/344/270/216Gateway/350/256/276/350/256/241/346/226/271/346/241/210.md +765 -0
  121. package/docs//350/277/234/347/250/213/346/250/241/345/235/227/350/256/276/350/256/241-/346/227/247/347/211/210.md +1117 -0
  122. package/docs//350/277/234/347/250/213/346/250/241/345/235/227/350/256/276/350/256/241.md +451 -0
  123. package/docs//351/207/215/346/236/204/346/234/272/345/210/266/346/270/205/345/215/225.md +192 -0
  124. package/docs//351/223/276/350/267/257/350/277/275/350/270/252/346/226/271/346/241/210.md +242 -0
  125. package/docs//351/231/215/347/272/247/347/255/226/347/225/245/350/256/276/350/256/241/346/226/271/346/241/210.md +618 -0
  126. package/extensions/agents/assistant/entry.py +113 -14
  127. package/extensions/agents/assistant/module.md +27 -22
  128. package/extensions/agents/assistant/server.py +291 -105
  129. package/extensions/channels/acp_channel/entry.py +114 -16
  130. package/extensions/channels/acp_channel/module.md +4 -0
  131. package/extensions/channels/acp_channel/server.py +396 -105
  132. package/extensions/channels/phone_channel/__init__.py +1 -0
  133. package/extensions/channels/phone_channel/entry.py +503 -0
  134. package/extensions/channels/phone_channel/module.md +31 -0
  135. package/extensions/channels/phone_channel/server.py +686 -0
  136. package/extensions/event_hub_bench/entry.py +55 -12
  137. package/extensions/event_hub_bench/module.md +27 -27
  138. package/extensions/services/audit/README.md +134 -0
  139. package/extensions/services/audit/collector.py +73 -0
  140. package/extensions/services/audit/entry.py +444 -0
  141. package/extensions/services/audit/module.md +66 -0
  142. package/extensions/services/audit/query_audit.py +111 -0
  143. package/extensions/services/audit/routes/__init__.py +1 -0
  144. package/extensions/services/audit/routes/routes_audit.py +113 -0
  145. package/extensions/services/audit/schemas/__init__.py +5 -0
  146. package/extensions/services/audit/schemas/audit_event.py +92 -0
  147. package/extensions/services/audit/server.py +542 -0
  148. package/extensions/services/audit/storage.py +95 -0
  149. package/extensions/services/auth/entry.py +1054 -0
  150. package/extensions/services/auth/module.md +31 -0
  151. package/extensions/services/auth/token_store.py +185 -0
  152. package/extensions/services/auth/verifiers/evol_account.py +101 -0
  153. package/extensions/services/auth/verifiers/kite_token.py +38 -0
  154. package/extensions/services/auth/verifiers/pairing_code.py +71 -0
  155. package/extensions/services/backup/entry.py +494 -197
  156. package/extensions/services/backup/module.md +4 -2
  157. package/extensions/services/dataclaw/api/__init__.py +0 -0
  158. package/extensions/services/dataclaw/api/admin.py +367 -0
  159. package/extensions/services/dataclaw/api/copyright.py +175 -0
  160. package/extensions/services/dataclaw/api/credits.py +177 -0
  161. package/extensions/services/dataclaw/api/data.py +179 -0
  162. package/extensions/services/dataclaw/api/demands.py +269 -0
  163. package/extensions/services/dataclaw/api/feeds.py +262 -0
  164. package/extensions/services/dataclaw/api/identity.py +505 -0
  165. package/extensions/services/dataclaw/api/notifications.py +104 -0
  166. package/extensions/services/dataclaw/api/reviews.py +138 -0
  167. package/extensions/services/dataclaw/api/search.py +153 -0
  168. package/extensions/services/dataclaw/api/subscriptions.py +157 -0
  169. package/extensions/services/dataclaw/config.json5 +96 -0
  170. package/extensions/services/dataclaw/core/__init__.py +0 -0
  171. package/extensions/services/dataclaw/core/auth.py +95 -0
  172. package/extensions/services/dataclaw/core/config.py +50 -0
  173. package/extensions/services/dataclaw/core/database.py +70 -0
  174. package/extensions/services/dataclaw/entry.py +416 -0
  175. package/extensions/services/dataclaw/gofeed/351/241/271/347/233/256/346/211/200/346/234/211/346/235/203/350/275/254/347/247/273/346/265/201/347/250/213/350/257/264/346/230/216.md +309 -0
  176. package/extensions/services/dataclaw/migrate.py +283 -0
  177. package/extensions/services/dataclaw/models/__init__.py +0 -0
  178. package/extensions/services/dataclaw/module.md +49 -0
  179. package/extensions/services/dataclaw/requirements.txt +18 -0
  180. package/extensions/services/dataclaw/server.py +759 -0
  181. package/extensions/services/dataclaw/services/__init__.py +0 -0
  182. package/extensions/services/dataclaw/services/agent_service.py +132 -0
  183. package/extensions/services/dataclaw/services/credit_service.py +235 -0
  184. package/extensions/services/dataclaw/services/email_service.py +140 -0
  185. package/extensions/services/dataclaw/services/feed_service.py +259 -0
  186. package/extensions/services/dataclaw/services/notification_service.py +209 -0
  187. package/extensions/services/dataclaw/services/oauth_service.py +275 -0
  188. package/extensions/services/dataclaw/services/pricing.py +102 -0
  189. package/extensions/services/dataclaw/services/quality.py +79 -0
  190. package/extensions/services/dataclaw/services/reputation.py +142 -0
  191. package/extensions/services/dataclaw/services/sms_service.py +174 -0
  192. package/extensions/services/dataclaw/static/css/common.css +853 -0
  193. package/extensions/services/dataclaw/static/css/themes/blue.css +42 -0
  194. package/extensions/services/dataclaw/static/css/themes/dark.css +42 -0
  195. package/extensions/services/dataclaw/static/css/themes/light.css +35 -0
  196. package/extensions/services/dataclaw/static/js/api.js +103 -0
  197. package/extensions/services/dataclaw/static/js/common.js +321 -0
  198. package/extensions/services/dataclaw/static/js/i18n.js +95 -0
  199. package/extensions/services/dataclaw/static/js/pages/admin.js +152 -0
  200. package/extensions/services/dataclaw/static/js/pages/dashboard.js +82 -0
  201. package/extensions/services/dataclaw/static/js/pages/feed-detail.js +180 -0
  202. package/extensions/services/dataclaw/static/js/pages/feed-manage.js +158 -0
  203. package/extensions/services/dataclaw/static/js/theme.js +46 -0
  204. package/extensions/services/dataclaw/static/locales/en-US.json +464 -0
  205. package/extensions/services/dataclaw/static/locales/ja-JP.json +464 -0
  206. package/extensions/services/dataclaw/static/locales/zh-CN.json +464 -0
  207. package/extensions/services/dataclaw/templates/admin/index.html +90 -0
  208. package/extensions/services/dataclaw/templates/base.html +136 -0
  209. package/extensions/services/dataclaw/templates/credits/balance.html +106 -0
  210. package/extensions/services/dataclaw/templates/credits/deposit.html +164 -0
  211. package/extensions/services/dataclaw/templates/credits/history.html +90 -0
  212. package/extensions/services/dataclaw/templates/dashboard.html +52 -0
  213. package/extensions/services/dataclaw/templates/demands/create.html +78 -0
  214. package/extensions/services/dataclaw/templates/demands/detail.html +136 -0
  215. package/extensions/services/dataclaw/templates/demands/list.html +94 -0
  216. package/extensions/services/dataclaw/templates/feeds/create.html +95 -0
  217. package/extensions/services/dataclaw/templates/feeds/detail.html +110 -0
  218. package/extensions/services/dataclaw/templates/feeds/list.html +110 -0
  219. package/extensions/services/dataclaw/templates/feeds/manage.html +88 -0
  220. package/extensions/services/dataclaw/templates/index.html +185 -0
  221. package/extensions/services/dataclaw/templates/login.html +246 -0
  222. package/extensions/services/dataclaw/templates/register.html +164 -0
  223. package/extensions/services/dataclaw/templates/settings/notifications.html +96 -0
  224. package/extensions/services/dataclaw/templates/settings/profile.html +167 -0
  225. package/extensions/services/dataclaw/templates/subscriptions/list.html +64 -0
  226. package/extensions/services/dataclaw/tests/__init__.py +0 -0
  227. package/extensions/services/dataclaw/tests/conftest.py +68 -0
  228. package/extensions/services/dataclaw/tests/integration/__init__.py +0 -0
  229. package/extensions/services/dataclaw/tests/integration/test_workflows.py +239 -0
  230. package/extensions/services/dataclaw/tests/unit/__init__.py +0 -0
  231. package/extensions/services/dataclaw/tests/unit/test_admin.py +70 -0
  232. package/extensions/services/dataclaw/tests/unit/test_copyright.py +63 -0
  233. package/extensions/services/dataclaw/tests/unit/test_credits.py +80 -0
  234. package/extensions/services/dataclaw/tests/unit/test_data.py +98 -0
  235. package/extensions/services/dataclaw/tests/unit/test_demands.py +106 -0
  236. package/extensions/services/dataclaw/tests/unit/test_feeds.py +98 -0
  237. package/extensions/services/dataclaw/tests/unit/test_identity.py +88 -0
  238. package/extensions/services/dataclaw/tests/unit/test_notifications.py +36 -0
  239. package/extensions/services/dataclaw/tests/unit/test_reviews.py +68 -0
  240. package/extensions/services/dataclaw/tests/unit/test_search.py +64 -0
  241. package/extensions/services/dataclaw/tests/unit/test_subscriptions.py +65 -0
  242. package/extensions/services/dataclaw/tests/unit/test_system.py +106 -0
  243. package/extensions/services/dataclaw/utils/__init__.py +0 -0
  244. package/extensions/services/dataclaw/utils/crypto.py +38 -0
  245. package/extensions/services/dataclaw/utils/id_generator.py +52 -0
  246. package/extensions/services/dataclaw/ws/__init__.py +0 -0
  247. package/extensions/services/dataclaw/ws/handler.py +163 -0
  248. package/extensions/services/dataclaw//345/215/217/350/256/2561-/351/241/271/347/233/256/346/235/241/344/273/266/346/216/210/346/235/203/344/270/216/350/202/241/346/235/203/345/257/271/344/273/267/345/215/217/350/256/256.md +243 -0
  249. package/extensions/services/dataclaw//345/215/217/350/256/2562-/351/241/271/347/233/256/350/264/255/344/271/260/346/235/203/344/270/216/345/244/226/345/214/205/345/247/224/346/211/230/345/274/200/345/217/221/345/215/217/350/256/256.md +434 -0
  250. package/extensions/services/evol/__init__.py +1 -0
  251. package/extensions/services/evol/async_http.py +551 -0
  252. package/extensions/services/evol/auth_manager.py +602 -443
  253. package/extensions/services/evol/config.json5 +16 -0
  254. package/extensions/services/evol/entry.py +568 -406
  255. package/extensions/services/evol/evol_api.py +969 -173
  256. package/extensions/services/evol/mfa_totp.py +77 -0
  257. package/extensions/services/evol/module.md +150 -32
  258. package/extensions/services/evol/nonce_pool.py +113 -0
  259. package/extensions/services/evol/oauth_manager.py +223 -0
  260. package/extensions/services/evol/pairing.py +3 -2
  261. package/extensions/services/evol/pairing_codes.jsonl +1 -0
  262. package/extensions/services/evol/relay.py +1031 -682
  263. package/extensions/services/evol/relay_config.json5 +85 -67
  264. package/extensions/services/evol/routes/routes_llm.py +231 -0
  265. package/extensions/services/evol/routes/routes_rpc.py +90 -89
  266. package/extensions/services/evol/routes/routes_test.py +11 -4
  267. package/extensions/services/evol/server.py +2426 -875
  268. package/extensions/services/evol/static/assets/CommissionView-Cs_ys6Gm.js +1 -0
  269. package/extensions/services/evol/static/assets/CommissionView-DACet_Oo.css +1 -0
  270. package/extensions/services/evol/static/assets/IframePage-DbO11U9G.js +1 -0
  271. package/extensions/services/evol/static/assets/IframePage-c572lT8i.css +1 -0
  272. package/extensions/services/evol/static/assets/TeamDetailView-DULrGD7k.css +1 -0
  273. package/extensions/services/evol/static/assets/TeamDetailView-gy_MBEqG.js +139 -0
  274. package/extensions/services/evol/static/assets/element-plus-Bd7pZkkM.js +63 -0
  275. package/extensions/services/evol/static/assets/index-CmMONKzG.css +1 -0
  276. package/extensions/services/evol/static/assets/index-D44bBe__.js +2 -0
  277. package/extensions/services/evol/static/assets/vue-vendor-DtF-__I4.js +29 -0
  278. package/extensions/services/evol/static/index.html +16 -781
  279. package/extensions/services/evol/static/logo.png +0 -0
  280. package/extensions/services/evol/stats_manager.py +243 -240
  281. package/extensions/services/evol/web/README.md +89 -0
  282. package/extensions/services/evol/web/build.bat +44 -0
  283. package/extensions/services/evol/web/index.html +13 -0
  284. package/extensions/services/evol/web/package-lock.json +1718 -0
  285. package/extensions/services/evol/web/package.json +26 -0
  286. package/extensions/services/evol/web/public/logo.png +0 -0
  287. package/extensions/services/evol/web/src/App.vue +7 -0
  288. package/extensions/services/evol/web/src/components/layout/AppHeader.vue +202 -0
  289. package/extensions/services/evol/web/src/components/layout/AppLayout.vue +61 -0
  290. package/extensions/services/evol/web/src/components/layout/AppSidebar.vue +115 -0
  291. package/extensions/services/evol/web/src/components/login/LoginPage.vue +271 -0
  292. package/extensions/services/evol/web/src/components/team/AddMemberModal.vue +181 -0
  293. package/extensions/services/evol/web/src/components/team/GroupTreeNode.vue +156 -0
  294. package/extensions/services/evol/web/src/components/team/TeamAlertConfig.vue +221 -0
  295. package/extensions/services/evol/web/src/components/team/TeamBillModal.vue +165 -0
  296. package/extensions/services/evol/web/src/components/team/TeamMembersAndGroups.vue +499 -0
  297. package/extensions/services/evol/web/src/components/team/TeamStatsPanel.vue +907 -0
  298. package/extensions/services/evol/web/src/components/team/TreeNode.vue +331 -0
  299. package/extensions/services/evol/web/src/components/team/stats/StatsExportProgress.vue +44 -0
  300. package/extensions/services/evol/web/src/components/team/stats/StatsHeader.vue +89 -0
  301. package/extensions/services/evol/web/src/components/team/stats/StatsMemberDetail.vue +415 -0
  302. package/extensions/services/evol/web/src/components/team/stats/StatsSummary.vue +42 -0
  303. package/extensions/services/evol/web/src/components/team/stats/helpers.ts +195 -0
  304. package/extensions/services/evol/web/src/components/team/stats/stats.css +741 -0
  305. package/extensions/services/evol/web/src/components/team/stats/useStatsApi.ts +114 -0
  306. package/extensions/services/evol/web/src/components/team/stats/useStatsCharts.ts +242 -0
  307. package/extensions/services/evol/web/src/components/team/stats/useStatsExport.ts +232 -0
  308. package/extensions/services/evol/web/src/composables/useFormatters.ts +42 -0
  309. package/extensions/services/evol/web/src/composables/useTheme.ts +52 -0
  310. package/extensions/services/evol/web/src/env.d.ts +7 -0
  311. package/extensions/services/evol/web/src/i18n/en.ts +361 -0
  312. package/extensions/services/evol/web/src/i18n/index.ts +36 -0
  313. package/extensions/services/evol/web/src/i18n/zh.ts +379 -0
  314. package/extensions/services/evol/web/src/main.ts +21 -0
  315. package/extensions/services/evol/web/src/router/index.ts +81 -0
  316. package/extensions/services/evol/web/src/services/kernel-client.ts +406 -0
  317. package/extensions/services/evol/web/src/stores/auth.ts +189 -0
  318. package/extensions/services/evol/web/src/stores/connection.ts +134 -0
  319. package/extensions/services/evol/web/src/stores/pages.ts +79 -0
  320. package/extensions/services/evol/web/src/styles/base.css +213 -0
  321. package/extensions/services/evol/web/src/styles/variables.css +138 -0
  322. package/extensions/services/evol/web/src/types/rpc.ts +35 -0
  323. package/extensions/services/evol/web/src/types/token.ts +87 -0
  324. package/extensions/services/evol/web/src/views/AccountView.vue +1532 -0
  325. package/extensions/services/evol/web/src/views/AiServiceView.vue +219 -0
  326. package/extensions/services/evol/web/src/views/CommissionView.vue +1220 -0
  327. package/extensions/services/evol/web/src/views/CreditsView.vue +131 -0
  328. package/extensions/services/evol/web/src/views/EndpointView.vue +163 -0
  329. package/extensions/services/evol/web/src/views/IframePage.vue +120 -0
  330. package/extensions/services/evol/web/src/views/TeamDetailView.vue +473 -0
  331. package/extensions/services/evol/web/src/views/TeamView.vue +332 -0
  332. package/extensions/services/evol/web/tsconfig.json +31 -0
  333. package/extensions/services/evol/web/tsconfig.node.json +10 -0
  334. package/extensions/services/evol/web/vite.config.ts +49 -0
  335. package/extensions/services/evolmem/__init__.py +0 -0
  336. package/extensions/services/evolmem/entry.py +387 -0
  337. package/extensions/services/evolmem/hooks/__init__.py +0 -0
  338. package/extensions/services/evolmem/hooks/assistant_stop.py +228 -0
  339. package/extensions/services/evolmem/hooks/common.py +76 -0
  340. package/extensions/services/evolmem/hooks/pre_tool_use.py +56 -0
  341. package/extensions/services/evolmem/hooks/session_end.py +133 -0
  342. package/extensions/services/evolmem/hooks/session_start.py +229 -0
  343. package/extensions/services/evolmem/hooks/user_prompt.py +122 -0
  344. package/extensions/services/evolmem/module.md +48 -0
  345. package/extensions/services/evolmem/prompts/00-server-info.md +28 -0
  346. package/extensions/services/evolmem/prompts/01-behavior.md +46 -0
  347. package/extensions/services/evolmem/prompts/02-summary-format.md +112 -0
  348. package/extensions/services/evolmem/prompts/03-file-query.md +92 -0
  349. package/extensions/services/evolmem/prompts/04-topic-stats.md +11 -0
  350. package/extensions/services/evolmem/prompts/05-recent-topics.md +84 -0
  351. package/extensions/services/evolmem/scripts/__init__.py +0 -0
  352. package/extensions/services/evolmem/scripts/extract_keywords.py +40 -0
  353. package/extensions/services/evolmem/scripts/search_topics.py +91 -0
  354. package/extensions/services/evolmem/server.py +641 -0
  355. package/extensions/services/gateway/entry.py +964 -0
  356. package/extensions/services/gateway/module.md +29 -0
  357. package/extensions/services/gateway/nonce_pool.py +65 -0
  358. package/extensions/services/gateway/relay.py +133 -0
  359. package/extensions/services/gateway/ws_server.py +285 -0
  360. package/extensions/services/kite_console/auth_manager.py +603 -0
  361. package/extensions/services/kite_console/config.json5 +19 -0
  362. package/extensions/services/kite_console/config_loader.py +117 -0
  363. package/extensions/services/kite_console/entry.py +528 -0
  364. package/extensions/services/kite_console/evol_api.py +179 -0
  365. package/extensions/services/kite_console/evol_config.json5 +29 -0
  366. package/extensions/services/kite_console/mfa_totp.py +77 -0
  367. package/extensions/services/kite_console/migrate_tokens.py +122 -0
  368. package/extensions/services/kite_console/module.md +37 -0
  369. package/extensions/services/kite_console/nonce_pool.py +113 -0
  370. package/extensions/services/kite_console/oauth_manager.py +223 -0
  371. package/extensions/services/kite_console/pairing.py +280 -0
  372. package/extensions/services/kite_console/pairing_codes.jsonl +2 -0
  373. package/extensions/services/kite_console/relay.py +1350 -0
  374. package/extensions/services/kite_console/relay_config.json5 +96 -0
  375. package/extensions/services/kite_console/routes/__init__.py +1 -0
  376. package/extensions/services/kite_console/routes/routes_llm.py +231 -0
  377. package/extensions/services/kite_console/routes/routes_proxy.py +115 -0
  378. package/extensions/services/kite_console/routes/routes_rpc.py +89 -0
  379. package/extensions/services/kite_console/routes/routes_test.py +68 -0
  380. package/extensions/services/kite_console/server.py +1742 -0
  381. package/extensions/services/{evol → kite_console}/static/css/style.css +656 -2
  382. package/extensions/services/kite_console/static/index.html +1524 -0
  383. package/extensions/services/{evol → kite_console}/static/js/dialog.js +11 -4
  384. package/extensions/services/kite_console/static/js/evol-app.js +7740 -0
  385. package/extensions/services/{evol/static/js/evol-app.js → kite_console/static/js/evol-app.js.backup} +2777 -1949
  386. package/extensions/services/kite_console/static/js/kernel-client.js +560 -0
  387. package/extensions/services/{evol/static/js/kernel-client.js → kite_console/static/js/kernel-client.js.backup} +41 -3
  388. package/extensions/services/{evol → kite_console}/static/js/registry-tests.js +7 -0
  389. package/extensions/services/kite_console/static/js/tests/ARCHITECTURE.md +67 -0
  390. package/extensions/services/kite_console/static/js/tests/README.md +140 -0
  391. package/extensions/services/kite_console/static/js/tests/index.js +161 -0
  392. package/extensions/services/kite_console/static/js/tests/integration/auth.js +120 -0
  393. package/extensions/services/kite_console/static/js/tests/integration/channel-interaction.js +188 -0
  394. package/extensions/services/kite_console/static/js/tests/integration/elastic-connection.js +115 -0
  395. package/extensions/services/kite_console/static/js/tests/integration/full-workflow.js +43 -0
  396. package/extensions/services/kite_console/static/js/tests/integration/multi-instance.js +304 -0
  397. package/extensions/services/kite_console/static/js/tests/integration/nested-rpc.js +266 -0
  398. package/extensions/services/kite_console/static/js/tests/integration/pingpong.js +25 -0
  399. package/extensions/services/kite_console/static/js/tests/integration/redis.js +227 -0
  400. package/extensions/services/kite_console/static/js/tests/integration/registry-core.js +52 -0
  401. package/extensions/services/kite_console/static/js/tests/integration/remote-deploy.js +85 -0
  402. package/extensions/services/kite_console/static/js/tests/integration/require-init.js +96 -0
  403. package/extensions/services/kite_console/static/js/tests/integration/scaling-control.js +193 -0
  404. package/extensions/services/kite_console/static/js/tests/integration/trace.js +109 -0
  405. package/extensions/services/kite_console/static/js/tests/modules/acp_channel.js +339 -0
  406. package/extensions/services/kite_console/static/js/tests/modules/auth.js +96 -0
  407. package/extensions/services/kite_console/static/js/tests/modules/backup.js +49 -0
  408. package/extensions/services/kite_console/static/js/tests/modules/gateway.js +41 -0
  409. package/extensions/services/kite_console/static/js/tests/modules/kernel.js +90 -0
  410. package/extensions/services/kite_console/static/js/tests/modules/launcher.js +75 -0
  411. package/extensions/services/kite_console/static/js/tests/modules/multi_instance.js +129 -0
  412. package/extensions/services/kite_console/static/js/tests/modules/phone_channel.js +364 -0
  413. package/extensions/services/kite_console/static/js/tests/modules/redis.js +178 -0
  414. package/extensions/services/kite_console/static/js/tests/modules/watchdog.js +60 -0
  415. package/extensions/services/kite_console/static/js/tests/modules/web.js +70 -0
  416. package/extensions/services/kite_console/static/js/tests/test-runner.js +123 -0
  417. package/extensions/services/kite_console/static/js/virtual-list.js +200 -0
  418. package/extensions/services/kite_console/static/test_kernel_client_token.html +352 -0
  419. package/extensions/services/kite_console/stats_manager.py +247 -0
  420. package/extensions/services/logs/README.md +215 -0
  421. package/extensions/services/logs/api_logger.py +37 -0
  422. package/extensions/services/logs/baseline.py +121 -0
  423. package/extensions/services/logs/cleaner.py +76 -0
  424. package/extensions/services/logs/entry.py +449 -0
  425. package/extensions/services/logs/formatter.py +129 -0
  426. package/extensions/services/logs/module.md +38 -0
  427. package/extensions/services/logs/quick_diagnostic.py +128 -0
  428. package/extensions/services/logs/routes/__init__.py +1 -0
  429. package/extensions/services/logs/routes/routes_logs.py +218 -0
  430. package/extensions/services/logs/routes/routes_logs.py.backup +173 -0
  431. package/extensions/services/logs/scanner.py +100 -0
  432. package/extensions/services/logs/searcher.py +263 -0
  433. package/extensions/services/logs/server.py +553 -0
  434. package/extensions/services/logs.zip +0 -0
  435. package/extensions/services/model_service/config.json5 +30 -0
  436. package/extensions/services/model_service/entry.py +620 -171
  437. package/extensions/services/model_service/module.md +11 -2
  438. package/extensions/services/proxy/__init__.py +0 -0
  439. package/extensions/services/proxy/aid_manager.py +419 -0
  440. package/extensions/services/proxy/auth_bridge.py +182 -0
  441. package/extensions/services/proxy/config_store.py +79 -0
  442. package/extensions/services/proxy/entry.py +528 -0
  443. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +2 -2
  444. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +18 -28
  445. package/extensions/services/proxy/evol/presenter/configPresenter.py +80 -1127
  446. package/extensions/services/proxy/evol/presenter/userPresenter.py +71 -477
  447. package/extensions/services/proxy/evol/server/claude_proxy_async.py +11 -7
  448. package/extensions/services/proxy/module.md +151 -0
  449. package/extensions/services/proxy/server.py +952 -271
  450. package/extensions/services/redis/ALIGNMENT_CHECKLIST.md +121 -0
  451. package/extensions/services/redis/ALIGNMENT_STATUS.md +548 -0
  452. package/extensions/services/redis/config.json5 +8 -0
  453. package/extensions/services/redis/entry.py +1509 -0
  454. package/extensions/services/redis/entry.py.backup +405 -0
  455. package/extensions/services/redis/module.md +48 -0
  456. package/extensions/services/redis/redis_builtin.py +332 -0
  457. package/extensions/services/redis/redis_external.py +164 -0
  458. package/extensions/services/testUi/entry.py +446 -0
  459. package/extensions/services/testUi/module.md +18 -0
  460. package/extensions/services/testUi/ui/cards.html +131 -0
  461. package/extensions/services/testUi/ui/index.html +22 -0
  462. package/extensions/services/testUi/ui/particles.html +143 -0
  463. package/extensions/services/watchdog/entry.py +1258 -793
  464. package/extensions/services/watchdog/module.md +2 -0
  465. package/extensions/services/watchdog/monitor.py +465 -87
  466. package/extensions/services/web/auth_manager.py +602 -0
  467. package/extensions/services/web/config.json5 +11 -0
  468. package/extensions/services/web/entry.py +598 -478
  469. package/extensions/services/web/mfa_totp.py +77 -0
  470. package/extensions/services/web/module.md +16 -13
  471. package/extensions/services/web/nonce_pool.py +113 -0
  472. package/extensions/services/web/oauth_manager.py +223 -0
  473. package/extensions/services/web/pairing.py +3 -2
  474. package/extensions/services/web/pairing_codes.jsonl +1 -0
  475. package/extensions/services/web/relay.py +442 -63
  476. package/extensions/services/web/relay_config.json5 +1 -2
  477. package/extensions/services/web/routes/routes_rpc.py +6 -6
  478. package/extensions/services/web/server.py +360 -173
  479. package/extensions/services/web/static/index.html +1752 -1738
  480. package/extensions/services/web/static/js/app.js +32 -0
  481. package/extensions/services/web/static/js/kernel-client.js +48 -9
  482. package/extensions/services/web/vendor/bluetooth/audio.py +1 -1
  483. package/extensions/services/web/vendor/config.py +2 -2
  484. package/extensions/services/web/vendor/storage/identity.py +1 -1
  485. package/kernel/entry.py +77 -23
  486. package/kernel/event_hub.py +1122 -74
  487. package/kernel/module.md +2 -1
  488. package/kernel/registry_store.py +208 -11
  489. package/kernel/rpc_router.py +1400 -491
  490. package/kernel/server.py +1021 -134
  491. package/kite_cli/builders/__init__.py +4 -0
  492. package/kite_cli/builders/base.py +67 -0
  493. package/kite_cli/builders/custom.py +31 -0
  494. package/kite_cli/builders/detector.py +56 -0
  495. package/kite_cli/builders/go.py +34 -0
  496. package/kite_cli/builders/gradle.py +41 -0
  497. package/kite_cli/builders/maven.py +36 -0
  498. package/kite_cli/builders/npm.py +44 -0
  499. package/kite_cli/builders/python.py +37 -0
  500. package/kite_cli/commands/BUILD_GUIDE.md +109 -0
  501. package/kite_cli/commands/build.py +142 -0
  502. package/kite_cli/commands/check.py +60 -0
  503. package/kite_cli/commands/config.py +156 -0
  504. package/kite_cli/commands/deps.py +58 -0
  505. package/kite_cli/commands/deps_install.py +7 -7
  506. package/kite_cli/commands/disable.py +162 -0
  507. package/kite_cli/commands/enable.py +162 -0
  508. package/kite_cli/commands/export.py +96 -0
  509. package/kite_cli/commands/import_cmd.py +110 -0
  510. package/kite_cli/commands/install.py +50 -23
  511. package/kite_cli/commands/install_skill.py +107 -0
  512. package/kite_cli/commands/list.py +128 -31
  513. package/kite_cli/commands/outdated.py +202 -0
  514. package/kite_cli/commands/search.py +33 -17
  515. package/kite_cli/commands/update.py +115 -2
  516. package/kite_cli/commands/venv_setup.py +6 -6
  517. package/kite_cli/commands/why.py +48 -0
  518. package/kite_cli/core/config_manager.py +145 -0
  519. package/kite_cli/core/downloader.py +32 -2
  520. package/kite_cli/main.py +151 -5
  521. package/kite_cli/utils/colors.py +153 -0
  522. package/kite_cli/utils/dependency_graph.py +209 -0
  523. package/kite_cli/utils/process.py +55 -0
  524. package/kite_cli/utils/progress.py +207 -0
  525. package/kite_cli/utils/table.py +101 -0
  526. package/launcher/count_lines.py +192 -43
  527. package/launcher/entry.py +4543 -2802
  528. package/launcher/logging_setup.py +54 -1
  529. package/launcher/module.md +32 -6
  530. package/launcher/module_scanner.py +93 -20
  531. package/launcher/process_manager.py +355 -76
  532. package/main.py +6 -0
  533. package/package.json +4 -1
  534. package/requirements.txt +41 -38
  535. package/scripts/auto-fix-deps.py +128 -0
  536. package/scripts/env-manager.js +25 -2
  537. package/scripts/final-test.js +78 -0
  538. package/scripts/setup-python-env.js +700 -191
  539. package/scripts/test-alluser.js +48 -0
  540. package/scripts/test-different-version.js +86 -0
  541. package/scripts/test-direct.js +63 -0
  542. package/scripts/test-extract-installer.js +28 -0
  543. package/scripts/test-install-log.js +54 -0
  544. package/scripts/test-installer.js +39 -0
  545. package/scripts/test-integration.js +250 -0
  546. package/scripts/test-real-install.js +210 -0
  547. package/scripts/test-targetdir.js +49 -0
  548. package/scripts/test-venv-real.js +47 -0
  549. package/scripts/test-venv-simple.js +57 -0
  550. package/scripts/test-wait.js +49 -0
  551. package/scripts/test-with-log.js +63 -0
  552. package/extensions/services/evol/config.yaml +0 -149
  553. package/extensions/services/evol/routes/routes_management_ws.py +0 -127
  554. package/extensions/services/evol/static/index_evol.html +0 -14
  555. package/extensions/services/evol/static/js/app.js +0 -6304
  556. package/extensions/services/evol/static/js/auth.js +0 -326
  557. package/extensions/services/evol/static/js/evol-app-fixed.js +0 -50
  558. package/extensions/services/evol/static/js/evol-app.js.bak +0 -1800
  559. package/extensions/services/evol/static/js/kernel-client-example.js +0 -228
  560. package/extensions/services/evol/static/js/main.js +0 -141
  561. package/extensions/services/evol/static/js/stats.js +0 -217
  562. package/extensions/services/evol/static/js/token-manager.js +0 -175
  563. package/extensions/services/proxy/CHANGELOG_20260308.md +0 -258
  564. package/extensions/services/proxy/_fix_prints.py +0 -133
  565. package/extensions/services/proxy/_fix_prints2.py +0 -87
  566. package/extensions/services/proxy/console_auth.py +0 -109
  567. package/extensions/services/proxy/logs/websocket.log +0 -260
  568. package/extensions/services/proxy/main.py +0 -240
  569. package/extensions/services/proxy/requirements.txt +0 -13
  570. package/extensions/services/web/config.yaml +0 -149
  571. /package/extensions/services/{evol → kite_console}/static/pairing.html +0 -0
  572. /package/extensions/services/{evol → kite_console}/static/test_registry.html +0 -0
  573. /package/extensions/services/{evol → kite_console}/static/test_relay.html +0 -0
@@ -0,0 +1,907 @@
1
+ <template>
2
+ <div class="team-stats-panel">
3
+ <!-- Header -->
4
+ <StatsHeader
5
+ :statsMode="statsMode"
6
+ :dateRange="dateRange"
7
+ :selectedDate="selectedDate"
8
+ :loading="loading"
9
+ :isStatsExpanded="isStatsExpanded"
10
+ @switchMode="switchMode"
11
+ @toggleStats="isStatsExpanded = !isStatsExpanded"
12
+ @update:dateRange="dateRange = $event"
13
+ @update:selectedDate="selectedDate = $event"
14
+ @dateRangeChange="onDateRangeChange"
15
+ @customDateChange="onCustomDateChange"
16
+ @prevDay="goToPreviousDay"
17
+ @nextDay="goToNextDay"
18
+ @refresh="loadStats"
19
+ />
20
+
21
+ <!-- Loading -->
22
+ <div v-if="loading" class="loading-state">
23
+ <div class="spinner-small"></div>
24
+ <span>加载中...</span>
25
+ </div>
26
+
27
+ <!-- Content -->
28
+ <template v-else-if="hasData">
29
+ <!-- 汇总卡片 + 饼图 -->
30
+ <StatsSummary
31
+ v-show="isStatsExpanded"
32
+ ref="summaryRef"
33
+ :summary="summary"
34
+ :statsDays="currentStatsDays"
35
+ :pieChartRef="null"
36
+ @pieMount="onPieMount"
37
+ class="collapsible-content"
38
+ />
39
+
40
+ <!-- 实时模式:24小时趋势图 -->
41
+ <div v-if="statsMode === 'realtime'" v-show="isStatsExpanded" class="hourly-chart-section collapsible-content">
42
+ <div class="hourly-chart-header">
43
+ <div class="title-with-toggle">
44
+ <h4 class="section-subtitle">24小时消耗趋势</h4>
45
+ <button class="toggle-btn" @click="isHourlyChartExpanded = !isHourlyChartExpanded" :title="isHourlyChartExpanded ? '收起' : '展开'">
46
+ <span class="toggle-icon" :class="{ rotated: !isHourlyChartExpanded }">▼</span>
47
+ </button>
48
+ </div>
49
+ <div class="hourly-controls">
50
+ <select v-model="selectedHourlyMemberId" @change="onHourlyMemberChange" class="member-select" :disabled="memberRanking.length === 0">
51
+ <option :value="null">团队汇总</option>
52
+ <option v-for="member in memberRanking" :key="member.userId" :value="member.userId">
53
+ {{ member.memberNickname || member.nickName }}
54
+ </option>
55
+ </select>
56
+ <div v-if="hourlyStats" class="hourly-summary">
57
+ <span class="hourly-total">总消耗: <strong>{{ formatNumber(hourlyStats.totalCredits) }}</strong></span>
58
+ <span class="hourly-count">{{ hourlyStats.totalCount || 0 }} 次调用</span>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ <div v-if="hourlyStatsLoading" class="hourly-loading">
63
+ <div class="spinner-small"></div><span>加载中...</span>
64
+ </div>
65
+ <div v-else-if="hourlyStats && hourlyStats.hourlyData" v-show="isHourlyChartExpanded" class="hourly-chart collapsible-content">
66
+ <div ref="realtimeHourlyChartEl" class="echarts-line-container"></div>
67
+ </div>
68
+ <div v-else v-show="isHourlyChartExpanded" class="hourly-no-data collapsible-content">
69
+ <p>暂无24小时统计数据</p>
70
+ </div>
71
+ </div>
72
+
73
+ <!-- 历史模式:趋势图表 -->
74
+ <div v-if="statsMode === 'history'" v-show="isStatsExpanded" class="trend-stats-section collapsible-content">
75
+ <div class="trend-stats-header">
76
+ <div class="title-with-toggle">
77
+ <h4 class="section-subtitle">积分消耗趋势</h4>
78
+ <button class="toggle-btn" @click="isHourlyChartExpanded = !isHourlyChartExpanded" :title="isHourlyChartExpanded ? '收起' : '展开'">
79
+ <span class="toggle-icon" :class="{ rotated: !isHourlyChartExpanded }">▼</span>
80
+ </button>
81
+ </div>
82
+ <div class="trend-stats-controls">
83
+ <div class="period-selector">
84
+ <button class="period-btn" :class="{ active: trendPeriod === 'hourly' }" @click="trendPeriod = 'hourly'; onTrendPeriodChange()" :disabled="!canShowHourlyTrend" :title="!canShowHourlyTrend ? '仅在选择1天数据时可用' : '24小时趋势'">24小时</button>
85
+ <button class="period-btn" :class="{ active: trendPeriod === 'daily' }" @click="trendPeriod = 'daily'; onTrendPeriodChange()">日趋势</button>
86
+ <button class="period-btn" :class="{ active: trendPeriod === 'weekly' }" @click="trendPeriod = 'weekly'; onTrendPeriodChange()">周趋势</button>
87
+ <button class="period-btn" :class="{ active: trendPeriod === 'monthly' }" @click="trendPeriod = 'monthly'; onTrendPeriodChange()">月趋势</button>
88
+ </div>
89
+ <select v-model="selectedTrendMemberId" @change="onTrendMemberChange" class="member-select" :disabled="memberRanking.length === 0">
90
+ <option :value="null">团队汇总</option>
91
+ <option v-for="member in memberRanking" :key="member.userId" :value="member.userId">
92
+ {{ member.memberNickname || member.nickName }}
93
+ </option>
94
+ </select>
95
+ <div class="hourly-summary">
96
+ <span class="hourly-total">总消耗: <strong>{{ formatNumber(getCurrentTrendTotal()) }}</strong></span>
97
+ <span class="hourly-count">{{ getCurrentTrendCount() }} 次调用</span>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <div v-if="trendStatsLoading || hourlyStatsLoading" class="hourly-loading">
102
+ <div class="spinner-small"></div><span>加载中...</span>
103
+ </div>
104
+ <!-- 24小时趋势 -->
105
+ <div v-else-if="trendPeriod === 'hourly'" v-show="isHourlyChartExpanded" class="hourly-chart collapsible-content">
106
+ <div v-if="hourlyStats && hourlyStats.hourlyData">
107
+ <div ref="historyHourlyChartEl" class="echarts-line-container"></div>
108
+ </div>
109
+ <div v-else class="hourly-no-data"><p>暂无24小时统计数据</p></div>
110
+ </div>
111
+ <!-- 周趋势 -->
112
+ <div v-else-if="trendPeriod === 'weekly'" v-show="isHourlyChartExpanded" class="weekly-chart collapsible-content">
113
+ <div v-if="weeklyStats && weeklyStats.weeklyData && weeklyStats.weeklyData.length > 0">
114
+ <div ref="weeklyChartEl" class="echarts-line-container"></div>
115
+ </div>
116
+ <div v-else class="hourly-no-data"><p>暂无周趋势数据</p></div>
117
+ </div>
118
+ <!-- 月趋势 -->
119
+ <div v-else-if="trendPeriod === 'monthly'" v-show="isHourlyChartExpanded" class="monthly-chart collapsible-content">
120
+ <div v-if="monthlyStats && monthlyStats.monthlyData && monthlyStats.monthlyData.length > 0">
121
+ <div ref="monthlyChartEl" class="echarts-line-container"></div>
122
+ </div>
123
+ <div v-else class="hourly-no-data"><p>暂无月趋势数据</p></div>
124
+ </div>
125
+ <!-- 日趋势 -->
126
+ <div v-else-if="trendPeriod === 'daily'" v-show="isHourlyChartExpanded" class="daily-chart collapsible-content">
127
+ <div v-if="trendData && trendData.trend && trendData.trend.length > 0">
128
+ <div ref="trendLineChartEl" class="echarts-line-container"></div>
129
+ </div>
130
+ <div v-else class="hourly-no-data"><p>暂无日趋势数据</p></div>
131
+ </div>
132
+ </div>
133
+
134
+ <!-- 分组模式 -->
135
+ <div v-if="statsMode === 'group'" v-show="isStatsExpanded" class="group-stats-section collapsible-content">
136
+ <!-- 分组排行柱状图 -->
137
+ <div class="group-ranking-chart">
138
+ <div class="group-chart-header">
139
+ <h4 class="section-subtitle">分组消耗排行</h4>
140
+ <div class="group-chart-summary" v-if="groupStatsAllGroups.length > 0">
141
+ <span class="summary-text">共 {{ groupStatsAllGroups.length }} 个分组</span>
142
+ </div>
143
+ </div>
144
+ <div v-if="groupStatsLoading" class="hourly-loading">
145
+ <div class="spinner-small"></div><span>加载中...</span>
146
+ </div>
147
+ <div v-else-if="groupStatsAllGroups.length > 0" class="group-bars-container">
148
+ <div v-for="(group, index) in groupStatsAllGroups" :key="group.groupId || 'ungrouped'" class="group-bar-row">
149
+ <div class="group-bar-rank" :class="getRankClass(index)">{{ index + 1 }}</div>
150
+ <div class="group-bar-name" :title="group.groupPath || group.groupName">
151
+ {{ group.groupName }}
152
+ </div>
153
+ <div class="group-bar-track">
154
+ <div class="group-bar-stack">
155
+ <div class="group-bar-fill chatbot" :style="{ width: getGroupBarWidth(group.chatbotCredits) }" :title="`Chatbot: ${formatNumber(group.chatbotCredits)}`"></div>
156
+ <div class="group-bar-fill codex" :style="{ width: getGroupBarWidth(group.codexCredits) }" :title="`Codex: ${formatNumber(group.codexCredits)}`"></div>
157
+ <div class="group-bar-fill claudecode" :style="{ width: getGroupBarWidth(group.claudecodeCredits) }" :title="`Claude Code: ${formatNumber(group.claudecodeCredits)}`"></div>
158
+ <div v-if="group.geminiCredits" class="group-bar-fill gemini" :style="{ width: getGroupBarWidth(group.geminiCredits) }" :title="`Gemini: ${formatNumber(group.geminiCredits)}`"></div>
159
+ <div v-if="group.openclawCredits" class="group-bar-fill openclaw" :style="{ width: getGroupBarWidth(group.openclawCredits) }" :title="`OpenClaw: ${formatNumber(group.openclawCredits)}`"></div>
160
+ </div>
161
+ </div>
162
+ <div class="group-bar-value">{{ formatNumber(group.totalCredits) }}</div>
163
+ </div>
164
+ <div class="hourly-legend" style="margin-top: 12px;">
165
+ <div class="hourly-legend-item chatbot"><span class="legend-dot"></span><span>Chatbot</span></div>
166
+ <div class="hourly-legend-item codex"><span class="legend-dot"></span><span>Codex</span></div>
167
+ <div class="hourly-legend-item claudecode"><span class="legend-dot"></span><span>Claude Code</span></div>
168
+ <div class="hourly-legend-item gemini"><span class="legend-dot"></span><span>Gemini</span></div>
169
+ </div>
170
+ </div>
171
+ <div v-else class="hourly-no-data"><p>暂无分组统计数据</p></div>
172
+ </div>
173
+
174
+ <!-- 分组详细对比表格 -->
175
+ <div v-if="!groupStatsLoading && groupStatsAllGroups.length > 0" class="group-detail-table">
176
+ <h4 class="section-subtitle" style="margin-bottom: 12px;">分组详细对比</h4>
177
+ <div class="ranking-table-container">
178
+ <table class="ranking-table">
179
+ <thead>
180
+ <tr>
181
+ <th width="60">排名</th>
182
+ <th>分组</th>
183
+ <th width="80">成员数</th>
184
+ <th width="100">总消耗</th>
185
+ <th width="80">次数</th>
186
+ <th width="100">人均消耗</th>
187
+ <th width="100">Chatbot</th>
188
+ <th width="100">Codex</th>
189
+ <th width="100">Claude</th>
190
+ <th width="100">Gemini</th>
191
+ <th width="100">OpenClaw</th>
192
+ </tr>
193
+ </thead>
194
+ <tbody>
195
+ <tr v-for="(group, index) in groupStatsAllGroups" :key="group.groupId || 'ungrouped'">
196
+ <td><div class="rank-badge" :class="getRankClass(index)">{{ index + 1 }}</div></td>
197
+ <td>
198
+ <div class="member-cell">
199
+ <div class="member-name">{{ group.groupName }}</div>
200
+ <div v-if="group.groupPath && group.groupPath !== group.groupName" class="member-phone">{{ group.groupPath }}</div>
201
+ </div>
202
+ </td>
203
+ <td><div class="count-value">{{ group.memberCount || 0 }}</div></td>
204
+ <td><div class="credits-amount primary">{{ formatNumber(group.totalCredits) }}</div></td>
205
+ <td><div class="count-value">{{ group.totalCount || 0 }}</div></td>
206
+ <td><div class="credits-amount">{{ group.memberCount ? formatNumber(Math.round(group.totalCredits / group.memberCount)) : '-' }}</div></td>
207
+ <td><div class="type-credits">{{ formatNumber(group.chatbotCredits) }}</div></td>
208
+ <td><div class="type-credits">{{ formatNumber(group.codexCredits) }}</div></td>
209
+ <td><div class="type-credits">{{ formatNumber(group.claudecodeCredits) }}</div></td>
210
+ <td><div class="type-credits">{{ formatNumber(group.geminiCredits) }}</div></td>
211
+ <td><div class="type-credits">{{ formatNumber(group.openclawCredits) }}</div></td>
212
+ </tr>
213
+ </tbody>
214
+ </table>
215
+ </div>
216
+ </div>
217
+
218
+ <!-- 分组趋势图 -->
219
+ <div v-if="!groupStatsLoading && groupHistoryData && dateRange !== 'custom' && groupStatsAllGroups.length > 0" class="group-trend-section">
220
+ <h4 class="section-subtitle" style="margin-bottom: 12px;">分组消耗趋势</h4>
221
+ <div class="group-trend-chart">
222
+ <div class="group-trend-bars">
223
+ <div v-for="(dateItem, dIdx) in groupTrendDates" :key="dIdx" class="group-trend-col">
224
+ <div class="group-trend-bar-stack">
225
+ <div v-for="(group, gIdx) in groupTrendGroups" :key="group.groupId || 'ungrouped'" class="group-trend-bar" :class="getGroupColorClass(gIdx)" :style="{ height: getGroupTrendBarHeight(group, dateItem) }" :title="`${group.groupName}: ${formatNumber(getGroupDailyCredits(group, dateItem))}`"></div>
226
+ </div>
227
+ <div class="trend-bar-label">{{ formatTrendDate(dateItem) }}</div>
228
+ </div>
229
+ </div>
230
+ <div class="hourly-legend" style="margin-top: 12px;">
231
+ <div v-for="(group, gIdx) in groupTrendGroups" :key="group.groupId || 'ungrouped'" class="hourly-legend-item" :class="getGroupColorClass(gIdx)">
232
+ <span class="legend-dot"></span>
233
+ <span>{{ group.groupName }}</span>
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </div>
239
+
240
+ <!-- 成员消耗排行 -->
241
+ <div v-if="statsMode !== 'group'" class="member-ranking">
242
+ <div class="ranking-header">
243
+ <div class="title-with-toggle">
244
+ <h4 class="section-subtitle">成员消耗排行</h4>
245
+ <button class="toggle-btn" @click="isRankingExpanded = !isRankingExpanded" :title="isRankingExpanded ? '收起' : '展开'">
246
+ <span class="toggle-icon" :class="{ rotated: !isRankingExpanded }">▼</span>
247
+ </button>
248
+ </div>
249
+ <button v-if="memberRanking.length > 0" class="export-btn" @click="exportToExcel" title="导出为Excel">导出Excel</button>
250
+ </div>
251
+ <div v-if="memberRanking.length > 0" v-show="isRankingExpanded" class="ranking-table-container collapsible-content">
252
+ <table class="ranking-table">
253
+ <thead>
254
+ <tr>
255
+ <th width="60">排名</th>
256
+ <th>成员</th>
257
+ <th width="100">总消耗</th>
258
+ <th width="80">次数</th>
259
+ <th width="120">Chatbot</th>
260
+ <th width="120">Codex</th>
261
+ <th width="120">Claude</th>
262
+ <th width="120">Gemini</th>
263
+ <th width="120">OpenClaw</th>
264
+ <th width="100">操作</th>
265
+ </tr>
266
+ </thead>
267
+ <tbody>
268
+ <tr v-for="(member, index) in memberRanking" :key="member.userId">
269
+ <td><div class="rank-badge" :class="getRankClass(index)">{{ index + 1 }}</div></td>
270
+ <td>
271
+ <div class="member-cell">
272
+ <div class="member-name">
273
+ {{ member.memberNickname || member.nickName }}
274
+ <span v-if="member.memberNickname" class="member-tag">({{ member.nickName }})</span>
275
+ </div>
276
+ <div class="member-phone">{{ member.phonenumber || member.userName }}</div>
277
+ </div>
278
+ </td>
279
+ <td><div class="credits-amount primary">{{ formatNumber(member.totalCredits) }}</div></td>
280
+ <td><div class="count-value">{{ member.totalCount || 0 }}</div></td>
281
+ <td><div class="type-credits">{{ formatNumber(member.chatbotCredits) }}</div></td>
282
+ <td><div class="type-credits">{{ formatNumber(member.codexCredits) }}</div></td>
283
+ <td><div class="type-credits">{{ formatNumber(member.claudecodeCredits) }}</div></td>
284
+ <td><div class="type-credits">{{ formatNumber(member.geminiCredits) }}</div></td>
285
+ <td><div class="type-credits">{{ formatNumber(member.openclawCredits) }}</div></td>
286
+ <td>
287
+ <button class="detail-btn" @click="showMemberDetail(member)" title="查看消耗详情">详情</button>
288
+ </td>
289
+ </tr>
290
+ </tbody>
291
+ </table>
292
+ </div>
293
+ <div v-else v-show="isRankingExpanded" class="no-ranking collapsible-content">暂无成员消耗数据</div>
294
+ </div>
295
+ </template>
296
+
297
+ <!-- Empty -->
298
+ <div v-else class="empty-stats">
299
+ <p>该时间段内暂无统计数据</p>
300
+ </div>
301
+
302
+ <!-- 成员详情弹窗 -->
303
+ <StatsMemberDetail
304
+ :visible="showDetailDialog"
305
+ :loading="detailLoading"
306
+ :member="currentMember"
307
+ :details="memberModelDetails"
308
+ @close="closeDetailDialog"
309
+ />
310
+
311
+ <!-- 导出进度弹窗 -->
312
+ <StatsExportProgress :progress="exportProgress" />
313
+ </div>
314
+ </template>
315
+
316
+ <script setup lang="ts">
317
+ import { ref, computed, watch, onUnmounted, nextTick } from 'vue'
318
+ import { ElMessage } from 'element-plus'
319
+ import StatsHeader from './stats/StatsHeader.vue'
320
+ import StatsSummary from './stats/StatsSummary.vue'
321
+ import StatsMemberDetail from './stats/StatsMemberDetail.vue'
322
+ import StatsExportProgress from './stats/StatsExportProgress.vue'
323
+ import { useStatsApi } from './stats/useStatsApi'
324
+ import { useStatsCharts } from './stats/useStatsCharts'
325
+ import { useStatsExport } from './stats/useStatsExport'
326
+ import {
327
+ formatNumber, formatDate, formatTrendDate, getRankClass,
328
+ getDateRange as calcDateRange, getStatsDays, sumDailyStats,
329
+ getGroupColorClass
330
+ } from './stats/helpers'
331
+
332
+ const props = defineProps<{ teamId: number }>()
333
+
334
+ // API
335
+ const api = useStatsApi(() => props.teamId)
336
+
337
+ // Charts
338
+ const charts = useStatsCharts()
339
+
340
+ // 状态
341
+ const loading = ref(false)
342
+ const statsMode = ref('realtime')
343
+ const dateRange = ref('30')
344
+ const isStatsExpanded = ref(true)
345
+ const isRankingExpanded = ref(true)
346
+ const isHourlyChartExpanded = ref(true)
347
+
348
+ const summary = ref<any>({})
349
+ const memberRanking = ref<any[]>([])
350
+ const trendData = ref<any>(null)
351
+
352
+ // 24小时统计
353
+ const hourlyStats = ref<any>(null)
354
+ const hourlyStatsLoading = ref(false)
355
+ const selectedHourlyMemberId = ref<number | null>(null)
356
+
357
+ // 趋势
358
+ const trendPeriod = ref<'hourly' | 'weekly' | 'monthly' | 'daily'>('weekly')
359
+ const weeklyStats = ref<any>(null)
360
+ const monthlyStats = ref<any>(null)
361
+ const trendStatsLoading = ref(false)
362
+ const selectedTrendMemberId = ref<number | null>(null)
363
+
364
+ // 日期
365
+ const yesterday = new Date()
366
+ yesterday.setDate(yesterday.getDate() - 1)
367
+ const selectedDate = ref(formatDate(yesterday))
368
+
369
+ // 详情弹窗
370
+ const showDetailDialog = ref(false)
371
+ const detailLoading = ref(false)
372
+ const currentMember = ref<any>(null)
373
+ const memberModelDetails = ref<any>(null)
374
+
375
+ // 分组
376
+ const groupStatsData = ref<any>(null)
377
+ const groupHistoryData = ref<any>(null)
378
+ const groupStatsLoading = ref(false)
379
+
380
+ // Refs for chart DOM(通过 nextTick 绑定)
381
+ const realtimeHourlyChartEl = ref<HTMLElement | null>(null)
382
+ const historyHourlyChartEl = ref<HTMLElement | null>(null)
383
+ const weeklyChartEl = ref<HTMLElement | null>(null)
384
+ const monthlyChartEl = ref<HTMLElement | null>(null)
385
+ const trendLineChartEl = ref<HTMLElement | null>(null)
386
+
387
+ // 同步 chart refs
388
+ const syncChartRefs = () => {
389
+ charts.realtimeHourlyChartRef.value = realtimeHourlyChartEl.value
390
+ charts.historyHourlyChartRef.value = historyHourlyChartEl.value
391
+ charts.weeklyChartRef.value = weeklyChartEl.value
392
+ charts.monthlyChartRef.value = monthlyChartEl.value
393
+ charts.trendLineChartRef.value = trendLineChartEl.value
394
+ }
395
+
396
+ const onPieMount = (el: HTMLElement) => {
397
+ charts.pieChartRef.value = el
398
+ renderCharts()
399
+ }
400
+
401
+ // 导出
402
+ const { exportProgress, exportToExcel } = useStatsExport(
403
+ api,
404
+ () => memberRanking.value,
405
+ () => statsMode.value,
406
+ () => dateRange.value,
407
+ () => selectedDate.value
408
+ )
409
+
410
+ // Computed
411
+ const hasData = computed(() => {
412
+ if (statsMode.value === 'group') {
413
+ return groupStatsAllGroups.value.length > 0 || groupStatsLoading.value
414
+ }
415
+ return (summary.value && Object.keys(summary.value).length > 0) || memberRanking.value.length > 0
416
+ })
417
+
418
+ const currentStatsDays = computed(() => getStatsDays(statsMode.value, dateRange.value, selectedDate.value))
419
+
420
+ const canShowHourlyTrend = computed(() => {
421
+ if (statsMode.value !== 'history') return false
422
+ return dateRange.value === 'custom' || dateRange.value === '1'
423
+ })
424
+
425
+ // 分组计算
426
+ const groupStatsAllGroups = computed(() => {
427
+ if (groupStatsData.value) {
428
+ const groups = (groupStatsData.value.groups || []).map((g: any) => ({ ...g }))
429
+ const ungrouped = groupStatsData.value.ungrouped
430
+ if (ungrouped && (ungrouped.totalCredits > 0 || ungrouped.memberCount > 0)) {
431
+ groups.push({ ...ungrouped, groupId: null, groupName: '未分组', groupPath: '未分组' })
432
+ }
433
+ return groups.sort((a: any, b: any) => (b.totalCredits || 0) - (a.totalCredits || 0))
434
+ }
435
+ if (groupHistoryData.value) {
436
+ const groups = (groupHistoryData.value.groups || []).map((g: any) => {
437
+ const totals = sumDailyStats(g.dailyStats || [])
438
+ return { ...g, ...totals }
439
+ })
440
+ const ungrouped = groupHistoryData.value.ungrouped
441
+ if (ungrouped) {
442
+ const totals = sumDailyStats(ungrouped.dailyStats || [])
443
+ if (totals.totalCredits > 0 || ungrouped.memberCount > 0) {
444
+ groups.push({ ...ungrouped, ...totals, groupId: null, groupName: '未分组', groupPath: '未分组' })
445
+ }
446
+ }
447
+ return groups.sort((a: any, b: any) => (b.totalCredits || 0) - (a.totalCredits || 0))
448
+ }
449
+ return []
450
+ })
451
+
452
+ const groupTrendDates = computed(() => {
453
+ if (!groupHistoryData.value) return []
454
+ const allDates = new Set<string>()
455
+ const allGroups = [...(groupHistoryData.value.groups || [])]
456
+ if (groupHistoryData.value.ungrouped) allGroups.push(groupHistoryData.value.ungrouped)
457
+ allGroups.forEach((g: any) => (g.dailyStats || []).forEach((d: any) => allDates.add(d.date)))
458
+ return Array.from(allDates).sort()
459
+ })
460
+
461
+ const groupTrendGroups = computed(() => {
462
+ if (!groupHistoryData.value) return []
463
+ const groups = (groupHistoryData.value.groups || []).map((g: any) => ({
464
+ groupId: g.groupId, groupName: g.groupName, dailyStats: g.dailyStats || []
465
+ }))
466
+ const ungrouped = groupHistoryData.value.ungrouped
467
+ if (ungrouped && (ungrouped.dailyStats || []).length > 0) {
468
+ groups.push({ groupId: null, groupName: '未分组', dailyStats: ungrouped.dailyStats || [] })
469
+ }
470
+ return groups
471
+ })
472
+
473
+ const getGroupDailyCredits = (group: any, date: string) => {
474
+ const day = (group.dailyStats || []).find((d: any) => d.date === date)
475
+ return day ? day.totalCredits || 0 : 0
476
+ }
477
+
478
+ const getGroupTrendBarHeight = (group: any, date: string) => {
479
+ let maxVal = 0
480
+ groupTrendGroups.value.forEach((g: any) => {
481
+ groupTrendDates.value.forEach((d: string) => {
482
+ const val = getGroupDailyCredits(g, d)
483
+ if (val > maxVal) maxVal = val
484
+ })
485
+ })
486
+ if (maxVal === 0) return '0%'
487
+ return `${(Math.abs(getGroupDailyCredits(group, date)) / maxVal) * 100}%`
488
+ }
489
+
490
+ const getGroupBarWidth = (value: number) => {
491
+ const maxCredits = groupStatsAllGroups.value.length > 0
492
+ ? Math.max(...groupStatsAllGroups.value.map((g: any) => Math.abs(g.totalCredits || 0)))
493
+ : 0
494
+ if (maxCredits === 0) return '0%'
495
+ return `${(Math.abs(value || 0) / maxCredits) * 100}%`
496
+ }
497
+
498
+ // 渲染图表
499
+ const renderCharts = () => {
500
+ nextTick(() => {
501
+ syncChartRefs()
502
+ charts.renderVisibleCharts({
503
+ statsMode: statsMode.value,
504
+ trendPeriod: trendPeriod.value,
505
+ summary: summary.value,
506
+ hourlyStats: hourlyStats.value,
507
+ weeklyStats: weeklyStats.value,
508
+ monthlyStats: monthlyStats.value,
509
+ trendData: trendData.value,
510
+ })
511
+ })
512
+ }
513
+
514
+ // 趋势总消耗/次数
515
+ const getCurrentTrendTotal = () => {
516
+ if (trendPeriod.value === 'weekly' && weeklyStats.value) {
517
+ return weeklyStats.value.weeklyData?.reduce((sum: number, item: any) => sum + (item.totalCredits || 0), 0) || 0
518
+ } else if (trendPeriod.value === 'monthly' && monthlyStats.value) {
519
+ return monthlyStats.value.monthlyData?.reduce((sum: number, item: any) => sum + (item.totalCredits || 0), 0) || 0
520
+ } else if (trendPeriod.value === 'hourly' && hourlyStats.value) {
521
+ return hourlyStats.value.totalCredits || 0
522
+ } else if (trendPeriod.value === 'daily' && trendData.value) {
523
+ return trendData.value.trend?.reduce((sum: number, item: any) => sum + (item.totalCredits || 0), 0) || 0
524
+ }
525
+ return 0
526
+ }
527
+
528
+ const getCurrentTrendCount = () => {
529
+ if (trendPeriod.value === 'weekly' && weeklyStats.value) {
530
+ return weeklyStats.value.weeklyData?.reduce((sum: number, item: any) => sum + (item.totalCount || 0), 0) || 0
531
+ } else if (trendPeriod.value === 'monthly' && monthlyStats.value) {
532
+ return monthlyStats.value.monthlyData?.reduce((sum: number, item: any) => sum + (item.totalCount || 0), 0) || 0
533
+ } else if (trendPeriod.value === 'hourly' && hourlyStats.value) {
534
+ return hourlyStats.value.totalCount || 0
535
+ } else if (trendPeriod.value === 'daily' && trendData.value) {
536
+ return trendData.value.trend?.reduce((sum: number, item: any) => sum + (item.totalCount || 0), 0) || 0
537
+ }
538
+ return 0
539
+ }
540
+
541
+ // ==================== 数据加载 ====================
542
+
543
+ const loadRealtimeStats = async () => {
544
+ loading.value = true
545
+ selectedHourlyMemberId.value = null
546
+ try {
547
+ const [statsData, membersData, hourlyData] = await Promise.all([
548
+ api.getTodayStats(),
549
+ api.getTodayMembersStats(),
550
+ api.getHourlyStats({})
551
+ ])
552
+ if (statsData) summary.value = statsData
553
+ if (membersData) memberRanking.value = Array.isArray(membersData) ? membersData : []
554
+ hourlyStats.value = hourlyData || null
555
+ trendData.value = null
556
+ } catch (error) {
557
+ console.error('加载实时统计失败:', error)
558
+ ElMessage.error('加载实时统计失败')
559
+ } finally {
560
+ loading.value = false
561
+ renderCharts()
562
+ }
563
+ }
564
+
565
+ const loadHistoryStats = async () => {
566
+ loading.value = true
567
+ selectedTrendMemberId.value = null
568
+ try {
569
+ const { startDate, endDate } = calcDateRange(dateRange.value, selectedDate.value)
570
+ let days = 7
571
+ if (dateRange.value === 'month' || dateRange.value === 'lastMonth') {
572
+ const start = new Date(startDate)
573
+ const end = new Date(endDate)
574
+ days = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1
575
+ } else if (dateRange.value === 'week' || dateRange.value === 'lastWeek') {
576
+ days = 7
577
+ } else {
578
+ days = parseInt(dateRange.value) || 7
579
+ }
580
+
581
+ const trendParams: any = { days }
582
+ if (selectedTrendMemberId.value) trendParams.userId = selectedTrendMemberId.value
583
+
584
+ const [statsData, rankingData, trendRes, weeklyData] = await Promise.all([
585
+ api.getCreditsStats({ startDate, endDate }),
586
+ api.getMembersRanking({ startDate, endDate, limit: 999 }),
587
+ api.getTrend(trendParams),
588
+ api.getWeeklyStats({})
589
+ ])
590
+
591
+ if (statsData) summary.value = statsData
592
+ if (rankingData) memberRanking.value = Array.isArray(rankingData) ? rankingData : []
593
+ trendData.value = trendRes || null
594
+ weeklyStats.value = weeklyData || null
595
+ } catch (error) {
596
+ console.error('加载历史统计失败:', error)
597
+ ElMessage.error('加载历史统计失败')
598
+ } finally {
599
+ loading.value = false
600
+ renderCharts()
601
+ }
602
+ }
603
+
604
+ const loadCustomDateStats = async () => {
605
+ loading.value = true
606
+ trendPeriod.value = 'hourly'
607
+ selectedHourlyMemberId.value = null
608
+ selectedTrendMemberId.value = null
609
+ try {
610
+ if (!selectedDate.value) return
611
+ const startHour = `${selectedDate.value} 00:00:00`
612
+ const [statsData, rankingData, hourlyData] = await Promise.all([
613
+ api.getStatsByDate(selectedDate.value),
614
+ api.getMembersRankingByDate(selectedDate.value),
615
+ api.getHourlyStats({ startHour })
616
+ ])
617
+ if (statsData) summary.value = statsData
618
+ if (rankingData) memberRanking.value = Array.isArray(rankingData) ? rankingData : []
619
+ hourlyStats.value = hourlyData || null
620
+ trendData.value = null
621
+ } catch (error) {
622
+ console.error('加载指定日期统计失败:', error)
623
+ ElMessage.error('加载指定日期统计失败')
624
+ } finally {
625
+ loading.value = false
626
+ renderCharts()
627
+ }
628
+ }
629
+
630
+ // 分组数据加载
631
+ const loadGroupRealtimeStats = async () => {
632
+ loading.value = true
633
+ groupStatsLoading.value = true
634
+ groupStatsData.value = null
635
+ groupHistoryData.value = null
636
+ try {
637
+ const data = await api.getTodayGroupStats({ limit: 20 })
638
+ if (data) {
639
+ groupStatsData.value = data
640
+ const allGroups = groupStatsAllGroups.value
641
+ summary.value = {
642
+ totalCredits: allGroups.reduce((s: number, g: any) => s + (g.totalCredits || 0), 0),
643
+ totalCount: allGroups.reduce((s: number, g: any) => s + (g.totalCount || 0), 0),
644
+ memberCount: allGroups.reduce((s: number, g: any) => s + (g.memberCount || 0), 0),
645
+ chatbotCredits: allGroups.reduce((s: number, g: any) => s + (g.chatbotCredits || 0), 0),
646
+ codexCredits: allGroups.reduce((s: number, g: any) => s + (g.codexCredits || 0), 0),
647
+ claudecodeCredits: allGroups.reduce((s: number, g: any) => s + (g.claudecodeCredits || 0), 0),
648
+ geminiCredits: allGroups.reduce((s: number, g: any) => s + (g.geminiCredits || 0), 0),
649
+ openclawCredits: allGroups.reduce((s: number, g: any) => s + (g.openclawCredits || 0), 0),
650
+ }
651
+ }
652
+ } catch (error) {
653
+ console.error('加载分组实时统计失败:', error)
654
+ ElMessage.error('加载分组统计失败')
655
+ } finally {
656
+ loading.value = false
657
+ groupStatsLoading.value = false
658
+ }
659
+ }
660
+
661
+ const loadGroupHistoryStats = async () => {
662
+ loading.value = true
663
+ groupStatsLoading.value = true
664
+ groupStatsData.value = null
665
+ groupHistoryData.value = null
666
+ try {
667
+ const { startDate, endDate } = calcDateRange(dateRange.value, selectedDate.value)
668
+ const data = await api.getHistoryGroupStats({ startDate, endDate, limit: 20 })
669
+ if (data) {
670
+ groupHistoryData.value = data
671
+ const allGroups = groupStatsAllGroups.value
672
+ summary.value = {
673
+ totalCredits: allGroups.reduce((s: number, g: any) => s + (g.totalCredits || 0), 0),
674
+ totalCount: allGroups.reduce((s: number, g: any) => s + (g.totalCount || 0), 0),
675
+ memberCount: allGroups.reduce((s: number, g: any) => s + (g.memberCount || 0), 0),
676
+ chatbotCredits: allGroups.reduce((s: number, g: any) => s + (g.chatbotCredits || 0), 0),
677
+ codexCredits: allGroups.reduce((s: number, g: any) => s + (g.codexCredits || 0), 0),
678
+ claudecodeCredits: allGroups.reduce((s: number, g: any) => s + (g.claudecodeCredits || 0), 0),
679
+ geminiCredits: allGroups.reduce((s: number, g: any) => s + (g.geminiCredits || 0), 0),
680
+ openclawCredits: allGroups.reduce((s: number, g: any) => s + (g.openclawCredits || 0), 0),
681
+ }
682
+ }
683
+ } catch (error) {
684
+ console.error('加载分组历史统计失败:', error)
685
+ ElMessage.error('加载分组历史统计失败')
686
+ } finally {
687
+ loading.value = false
688
+ groupStatsLoading.value = false
689
+ }
690
+ }
691
+
692
+ const loadGroupCustomDateStats = async () => {
693
+ loading.value = true
694
+ groupStatsLoading.value = true
695
+ groupStatsData.value = null
696
+ groupHistoryData.value = null
697
+ if (!selectedDate.value) return
698
+ try {
699
+ const data = await api.getHistoryGroupStats({ startDate: selectedDate.value, endDate: selectedDate.value, limit: 20 })
700
+ if (data) {
701
+ groupHistoryData.value = data
702
+ const allGroups = groupStatsAllGroups.value
703
+ summary.value = {
704
+ totalCredits: allGroups.reduce((s: number, g: any) => s + (g.totalCredits || 0), 0),
705
+ totalCount: allGroups.reduce((s: number, g: any) => s + (g.totalCount || 0), 0),
706
+ memberCount: allGroups.reduce((s: number, g: any) => s + (g.memberCount || 0), 0),
707
+ chatbotCredits: allGroups.reduce((s: number, g: any) => s + (g.chatbotCredits || 0), 0),
708
+ codexCredits: allGroups.reduce((s: number, g: any) => s + (g.codexCredits || 0), 0),
709
+ claudecodeCredits: allGroups.reduce((s: number, g: any) => s + (g.claudecodeCredits || 0), 0),
710
+ geminiCredits: allGroups.reduce((s: number, g: any) => s + (g.geminiCredits || 0), 0),
711
+ openclawCredits: allGroups.reduce((s: number, g: any) => s + (g.openclawCredits || 0), 0),
712
+ }
713
+ }
714
+ } catch (error) {
715
+ console.error('加载分组指定日期统计失败:', error)
716
+ ElMessage.error('加载分组统计失败')
717
+ } finally {
718
+ loading.value = false
719
+ groupStatsLoading.value = false
720
+ }
721
+ }
722
+
723
+ const loadGroupStats = () => {
724
+ if (statsMode.value === 'realtime') loadGroupRealtimeStats()
725
+ else if (dateRange.value === 'custom') loadGroupCustomDateStats()
726
+ else loadGroupHistoryStats()
727
+ }
728
+
729
+ const loadStats = () => {
730
+ if (statsMode.value === 'realtime') loadRealtimeStats()
731
+ else if (statsMode.value === 'group') loadGroupStats()
732
+ else if (dateRange.value === 'custom') loadCustomDateStats()
733
+ else loadHistoryStats()
734
+ }
735
+
736
+ // ==================== 交互 ====================
737
+
738
+ const switchMode = (mode: string) => {
739
+ statsMode.value = mode
740
+ if (mode === 'history') {
741
+ dateRange.value = '30'
742
+ trendPeriod.value = 'weekly'
743
+ }
744
+ loadStats()
745
+ }
746
+
747
+ const onDateRangeChange = () => {
748
+ if (statsMode.value === 'history') {
749
+ trendPeriod.value = (dateRange.value === 'custom' || dateRange.value === '1') ? 'hourly' : 'weekly'
750
+ }
751
+ loadStats()
752
+ }
753
+
754
+ const onCustomDateChange = () => {
755
+ if (statsMode.value === 'group') { loadGroupCustomDateStats(); return }
756
+ loadCustomDateStats()
757
+ }
758
+
759
+ const goToPreviousDay = () => {
760
+ if (!selectedDate.value) return
761
+ const d = new Date(selectedDate.value)
762
+ d.setDate(d.getDate() - 1)
763
+ selectedDate.value = formatDate(d)
764
+ statsMode.value === 'group' ? loadGroupCustomDateStats() : loadCustomDateStats()
765
+ }
766
+
767
+ const goToNextDay = () => {
768
+ if (!selectedDate.value) return
769
+ const d = new Date(selectedDate.value)
770
+ const y = new Date(); y.setDate(y.getDate() - 1)
771
+ d.setDate(d.getDate() + 1)
772
+ if (d <= y) {
773
+ selectedDate.value = formatDate(d)
774
+ statsMode.value === 'group' ? loadGroupCustomDateStats() : loadCustomDateStats()
775
+ }
776
+ }
777
+
778
+ // 24小时成员筛选
779
+ const onHourlyMemberChange = async () => {
780
+ hourlyStatsLoading.value = true
781
+ try {
782
+ const params: any = {}
783
+ if (selectedHourlyMemberId.value) params.userId = selectedHourlyMemberId.value
784
+ if (statsMode.value !== 'realtime' && dateRange.value === 'custom' && selectedDate.value) {
785
+ params.startHour = `${selectedDate.value} 00:00:00`
786
+ }
787
+ hourlyStats.value = await api.getHourlyStats(params) || null
788
+ } catch (error) {
789
+ console.error('加载小时统计失败:', error)
790
+ hourlyStats.value = null
791
+ } finally {
792
+ hourlyStatsLoading.value = false
793
+ renderCharts()
794
+ }
795
+ }
796
+
797
+ // 趋势周期切换
798
+ const onTrendPeriodChange = () => {
799
+ loadTrendStats()
800
+ if (trendPeriod.value === 'daily') renderCharts()
801
+ }
802
+
803
+ const onTrendMemberChange = () => {
804
+ if (trendPeriod.value === 'hourly') {
805
+ selectedHourlyMemberId.value = selectedTrendMemberId.value
806
+ onHourlyMemberChange()
807
+ } else if (trendPeriod.value === 'daily') {
808
+ loadDailyTrendData()
809
+ } else {
810
+ loadTrendStats()
811
+ }
812
+ }
813
+
814
+ const loadTrendStats = async () => {
815
+ if (trendPeriod.value === 'weekly') {
816
+ trendStatsLoading.value = true
817
+ try {
818
+ const params: any = {}
819
+ if (selectedTrendMemberId.value) params.userId = selectedTrendMemberId.value
820
+ weeklyStats.value = await api.getWeeklyStats(params) || null
821
+ } catch (error) { console.error('加载周趋势失败:', error); weeklyStats.value = null }
822
+ finally { trendStatsLoading.value = false; renderCharts() }
823
+ } else if (trendPeriod.value === 'monthly') {
824
+ trendStatsLoading.value = true
825
+ try {
826
+ const params: any = {}
827
+ if (selectedTrendMemberId.value) params.userId = selectedTrendMemberId.value
828
+ monthlyStats.value = await api.getMonthlyStats(params) || null
829
+ } catch (error) { console.error('加载月趋势失败:', error); monthlyStats.value = null }
830
+ finally { trendStatsLoading.value = false; renderCharts() }
831
+ } else if (trendPeriod.value === 'hourly') {
832
+ hourlyStatsLoading.value = true
833
+ try {
834
+ const params: any = {}
835
+ if (selectedHourlyMemberId.value) params.userId = selectedHourlyMemberId.value
836
+ if (dateRange.value === 'custom' && selectedDate.value) {
837
+ params.startHour = `${selectedDate.value} 00:00:00`
838
+ } else if (dateRange.value === '1') {
839
+ const y = new Date(); y.setDate(y.getDate() - 1)
840
+ params.startHour = `${formatDate(y)} 00:00:00`
841
+ }
842
+ hourlyStats.value = await api.getHourlyStats(params) || null
843
+ } catch (error) { console.error('加载小时统计失败:', error); hourlyStats.value = null }
844
+ finally { hourlyStatsLoading.value = false; renderCharts() }
845
+ }
846
+ }
847
+
848
+ const loadDailyTrendData = async () => {
849
+ try {
850
+ const { startDate, endDate } = calcDateRange(dateRange.value, selectedDate.value)
851
+ let days = 7
852
+ if (dateRange.value === 'month' || dateRange.value === 'lastMonth') {
853
+ days = Math.ceil((new Date(endDate).getTime() - new Date(startDate).getTime()) / (1000 * 60 * 60 * 24)) + 1
854
+ } else if (dateRange.value === 'week' || dateRange.value === 'lastWeek') {
855
+ days = 7
856
+ } else { days = parseInt(dateRange.value) || 7 }
857
+ const trendParams: any = { days }
858
+ if (selectedTrendMemberId.value) trendParams.userId = selectedTrendMemberId.value
859
+ trendData.value = await api.getTrend(trendParams) || null
860
+ renderCharts()
861
+ } catch (error) { console.error('加载日趋势数据失败:', error) }
862
+ }
863
+
864
+ // 成员详情
865
+ const showMemberDetail = async (member: any) => {
866
+ currentMember.value = member
867
+ showDetailDialog.value = true
868
+ detailLoading.value = true
869
+ memberModelDetails.value = null
870
+ try {
871
+ if (statsMode.value === 'realtime') {
872
+ memberModelDetails.value = await api.getUserTodayModels(member.userId)
873
+ if (!memberModelDetails.value) ElMessage.error('获取消耗详情失败')
874
+ } else {
875
+ if (member.modelDetails && member.modelDetails.length > 0) {
876
+ memberModelDetails.value = {
877
+ totalCredits: member.totalCredits, totalCount: member.totalCount, totalCost: member.totalCost,
878
+ modelDetails: member.modelDetails,
879
+ ...(member.totalUsage && { totalUsage: member.totalUsage })
880
+ }
881
+ } else {
882
+ memberModelDetails.value = { totalCredits: member.totalCredits, totalCount: member.totalCount, modelDetails: [] }
883
+ }
884
+ }
885
+ } catch (error) {
886
+ console.error('获取成员消耗详情失败:', error)
887
+ ElMessage.error('获取消耗详情失败')
888
+ } finally { detailLoading.value = false }
889
+ }
890
+
891
+ const closeDetailDialog = () => {
892
+ showDetailDialog.value = false
893
+ currentMember.value = null
894
+ memberModelDetails.value = null
895
+ }
896
+
897
+ // Watch
898
+ watch(() => props.teamId, () => {
899
+ if (props.teamId) loadStats()
900
+ }, { immediate: true })
901
+
902
+ onUnmounted(() => {
903
+ charts.disposeAll()
904
+ })
905
+ </script>
906
+
907
+ <style src="./stats/stats.css"></style>