@meetquinn/animactl 0.1.2 → 0.1.3

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 (289) hide show
  1. package/README.md +11 -6
  2. package/dist/server/{runtime/activity-payload.d.ts → activities/format.d.ts} +4 -1
  3. package/dist/server/activities/format.d.ts.map +1 -0
  4. package/dist/server/{runtime/activity-payload.js → activities/format.js} +16 -1
  5. package/dist/server/agents/agent-skills.d.ts +7 -3
  6. package/dist/server/agents/agent-skills.d.ts.map +1 -1
  7. package/dist/server/agents/agent-skills.js +243 -38
  8. package/dist/server/agents/agent-slack.service.d.ts +15 -0
  9. package/dist/server/agents/agent-slack.service.d.ts.map +1 -1
  10. package/dist/server/agents/agent-slack.service.js +43 -6
  11. package/dist/server/agents/default-skills.d.ts +9 -0
  12. package/dist/server/agents/default-skills.d.ts.map +1 -0
  13. package/dist/server/agents/default-skills.js +52 -0
  14. package/dist/server/cli/runtime-cli.d.ts +7 -1
  15. package/dist/server/cli/runtime-cli.d.ts.map +1 -1
  16. package/dist/server/cli/runtime-cli.js +107 -3
  17. package/dist/server/cli/services-cli.d.ts.map +1 -1
  18. package/dist/server/cli/services-cli.js +39 -0
  19. package/dist/server/inbox/slack-subscriber.d.ts +2 -0
  20. package/dist/server/inbox/slack-subscriber.d.ts.map +1 -1
  21. package/dist/server/inbox/slack-subscriber.js +28 -2
  22. package/dist/server/inbox/slack-subscription.service.d.ts.map +1 -1
  23. package/dist/server/inbox/slack-subscription.service.js +13 -1
  24. package/dist/server/inbox/wake-queue.service.d.ts +3 -1
  25. package/dist/server/inbox/wake-queue.service.d.ts.map +1 -1
  26. package/dist/server/inbox/wake-queue.service.js +5 -3
  27. package/dist/server/provider-usage/http.d.ts +1 -0
  28. package/dist/server/provider-usage/http.d.ts.map +1 -1
  29. package/dist/server/provider-usage/http.js +23 -1
  30. package/dist/server/provider-usage/provider-usage.service.d.ts +1 -4
  31. package/dist/server/provider-usage/provider-usage.service.d.ts.map +1 -1
  32. package/dist/server/provider-usage/provider-usage.service.js +1 -18
  33. package/dist/server/provider-usage/providers/claude.d.ts +1 -1
  34. package/dist/server/provider-usage/providers/claude.d.ts.map +1 -1
  35. package/dist/server/provider-usage/providers/claude.js +1 -1
  36. package/dist/server/provider-usage/providers/codex.d.ts +1 -1
  37. package/dist/server/provider-usage/providers/codex.d.ts.map +1 -1
  38. package/dist/server/provider-usage/providers/codex.js +1 -1
  39. package/dist/server/provider-usage/providers/kimi.d.ts +1 -1
  40. package/dist/server/provider-usage/providers/kimi.d.ts.map +1 -1
  41. package/dist/server/provider-usage/providers/kimi.js +4 -4
  42. package/dist/server/provider-usage/result.d.ts +5 -0
  43. package/dist/server/provider-usage/result.d.ts.map +1 -0
  44. package/dist/server/provider-usage/result.js +18 -0
  45. package/dist/server/providers/active-runtime.d.ts +1 -1
  46. package/dist/server/providers/active-runtime.d.ts.map +1 -1
  47. package/dist/server/providers/claude-events.d.ts +1 -1
  48. package/dist/server/providers/claude-events.d.ts.map +1 -1
  49. package/dist/server/providers/claude-events.js +2 -2
  50. package/dist/server/providers/claude.d.ts +1 -1
  51. package/dist/server/providers/claude.d.ts.map +1 -1
  52. package/dist/server/providers/claude.js +2 -2
  53. package/dist/server/providers/codex-app-server.d.ts +1 -1
  54. package/dist/server/providers/codex-app-server.d.ts.map +1 -1
  55. package/dist/server/providers/codex-app-server.js +1 -1
  56. package/dist/server/providers/codex-events.js +1 -1
  57. package/dist/server/providers/codex.d.ts +1 -1
  58. package/dist/server/providers/codex.d.ts.map +1 -1
  59. package/dist/server/providers/codex.js +2 -2
  60. package/dist/server/{runtime/provider-contract.d.ts → providers/contract.d.ts} +1 -1
  61. package/dist/server/providers/contract.d.ts.map +1 -0
  62. package/dist/server/providers/factory.d.ts +1 -1
  63. package/dist/server/providers/factory.d.ts.map +1 -1
  64. package/dist/server/providers/kimi-events.d.ts +1 -1
  65. package/dist/server/providers/kimi-events.d.ts.map +1 -1
  66. package/dist/server/providers/kimi-events.js +1 -1
  67. package/dist/server/providers/kimi.d.ts +1 -1
  68. package/dist/server/providers/kimi.d.ts.map +1 -1
  69. package/dist/server/providers/kimi.js +3 -2
  70. package/dist/server/providers/reasoning-events.js +1 -1
  71. package/dist/server/runtime/active-run-control.d.ts +19 -0
  72. package/dist/server/runtime/active-run-control.d.ts.map +1 -0
  73. package/dist/server/runtime/active-run-control.js +89 -0
  74. package/dist/server/runtime/activity.js +1 -1
  75. package/dist/server/runtime/agent-runner.d.ts +1 -1
  76. package/dist/server/runtime/agent-runner.d.ts.map +1 -1
  77. package/dist/server/runtime/delivery-prompt.d.ts +6 -0
  78. package/dist/server/runtime/delivery-prompt.d.ts.map +1 -1
  79. package/dist/server/runtime/delivery-prompt.js +53 -34
  80. package/dist/server/runtime/followup-appender.d.ts +20 -0
  81. package/dist/server/runtime/followup-appender.d.ts.map +1 -0
  82. package/dist/server/runtime/followup-appender.js +128 -0
  83. package/dist/server/runtime/host.d.ts +2 -0
  84. package/dist/server/runtime/host.d.ts.map +1 -1
  85. package/dist/server/runtime/host.js +8 -0
  86. package/dist/server/runtime/provider-runner.d.ts +16 -0
  87. package/dist/server/runtime/provider-runner.d.ts.map +1 -0
  88. package/dist/server/runtime/provider-runner.js +86 -0
  89. package/dist/server/runtime/runtime-bridge.d.ts +1 -1
  90. package/dist/server/runtime/runtime-bridge.d.ts.map +1 -1
  91. package/dist/server/runtime/runtime-session.service.d.ts +1 -1
  92. package/dist/server/runtime/runtime-session.service.d.ts.map +1 -1
  93. package/dist/server/runtime/runtime-session.service.js +1 -1
  94. package/dist/server/runtime/runtime-worker.d.ts +2 -10
  95. package/dist/server/runtime/runtime-worker.d.ts.map +1 -1
  96. package/dist/server/runtime/runtime-worker.js +60 -286
  97. package/dist/server/runtime-management/managed-runtime.d.ts.map +1 -0
  98. package/dist/server/runtime-management/runtime-release.d.ts.map +1 -0
  99. package/dist/server/{runtime → runtime-management}/runtime-upgrade.d.ts +1 -0
  100. package/dist/server/runtime-management/runtime-upgrade.d.ts.map +1 -0
  101. package/dist/server/{runtime → runtime-management}/runtime-upgrade.js +14 -0
  102. package/dist/server/services/system.service.d.ts +41 -0
  103. package/dist/server/services/system.service.d.ts.map +1 -0
  104. package/dist/server/services/system.service.js +154 -0
  105. package/dist/server/settings/settings.service.d.ts +2 -1
  106. package/dist/server/settings/settings.service.d.ts.map +1 -1
  107. package/dist/server/settings/settings.service.js +9 -1
  108. package/dist/server/slack/shortcuts.d.ts +0 -3
  109. package/dist/server/slack/shortcuts.d.ts.map +1 -1
  110. package/dist/server/slack/shortcuts.js +0 -3
  111. package/dist/server/slack-interactions/shortcut-ids.d.ts +4 -0
  112. package/dist/server/slack-interactions/shortcut-ids.d.ts.map +1 -0
  113. package/dist/server/slack-interactions/shortcut-ids.js +3 -0
  114. package/dist/server/slack-interactions/shortcut-views.d.ts +65 -0
  115. package/dist/server/slack-interactions/shortcut-views.d.ts.map +1 -0
  116. package/dist/server/slack-interactions/shortcut-views.js +211 -0
  117. package/dist/server/{slack → slack-interactions}/shortcut.service.d.ts +2 -47
  118. package/dist/server/slack-interactions/shortcut.service.d.ts.map +1 -0
  119. package/dist/server/slack-interactions/shortcut.service.js +227 -0
  120. package/dist/server/storage/jsonl-log.d.ts +9 -0
  121. package/dist/server/storage/jsonl-log.d.ts.map +1 -1
  122. package/dist/server/storage/jsonl-log.js +36 -1
  123. package/dist/server/storage/schema/server.store.d.ts +5 -0
  124. package/dist/server/storage/schema/server.store.d.ts.map +1 -1
  125. package/dist/server/storage/schema/server.store.js +2 -1
  126. package/dist/server/storage/schema/wake-queue.store.d.ts +15 -1
  127. package/dist/server/storage/schema/wake-queue.store.d.ts.map +1 -1
  128. package/dist/server/storage/schema/wake-queue.store.js +5 -3
  129. package/dist/server/tests/agent-config.test.d.ts +2 -0
  130. package/dist/server/tests/agent-config.test.d.ts.map +1 -0
  131. package/dist/server/tests/agent-config.test.js +229 -0
  132. package/dist/server/tests/agent-runtime.test.d.ts +2 -0
  133. package/dist/server/tests/agent-runtime.test.d.ts.map +1 -0
  134. package/dist/server/tests/agent-runtime.test.js +1110 -0
  135. package/dist/server/tests/agent-seed-memory.test.d.ts +2 -0
  136. package/dist/server/tests/agent-seed-memory.test.d.ts.map +1 -0
  137. package/dist/server/tests/agent-seed-memory.test.js +16 -0
  138. package/dist/server/tests/agent-skills.test.d.ts +2 -0
  139. package/dist/server/tests/agent-skills.test.d.ts.map +1 -0
  140. package/dist/server/tests/agent-skills.test.js +140 -0
  141. package/dist/server/tests/anima-home.d.ts +2 -0
  142. package/dist/server/tests/anima-home.d.ts.map +1 -0
  143. package/dist/server/tests/anima-home.js +4 -0
  144. package/dist/server/tests/cli-file.test.d.ts +2 -0
  145. package/dist/server/tests/cli-file.test.d.ts.map +1 -0
  146. package/dist/server/tests/cli-file.test.js +596 -0
  147. package/dist/server/tests/cli-message.test.d.ts +2 -0
  148. package/dist/server/tests/cli-message.test.d.ts.map +1 -0
  149. package/dist/server/tests/cli-message.test.js +1196 -0
  150. package/dist/server/tests/client-error-routes.test.d.ts +2 -0
  151. package/dist/server/tests/client-error-routes.test.d.ts.map +1 -0
  152. package/dist/server/tests/client-error-routes.test.js +163 -0
  153. package/dist/server/tests/config.test.d.ts +2 -0
  154. package/dist/server/tests/config.test.d.ts.map +1 -0
  155. package/dist/server/tests/config.test.js +497 -0
  156. package/dist/server/tests/default-skills.test.d.ts +2 -0
  157. package/dist/server/tests/default-skills.test.d.ts.map +1 -0
  158. package/dist/server/tests/default-skills.test.js +57 -0
  159. package/dist/server/tests/helpers/inbox.d.ts +10 -0
  160. package/dist/server/tests/helpers/inbox.d.ts.map +1 -0
  161. package/dist/server/tests/helpers/inbox.js +21 -0
  162. package/dist/server/tests/helpers/slack.d.ts +11 -0
  163. package/dist/server/tests/helpers/slack.d.ts.map +1 -0
  164. package/dist/server/tests/helpers/slack.js +17 -0
  165. package/dist/server/tests/helpers/state.d.ts +19 -0
  166. package/dist/server/tests/helpers/state.d.ts.map +1 -0
  167. package/dist/server/tests/helpers/state.js +69 -0
  168. package/dist/server/tests/inbox-slack-events.test.d.ts +2 -0
  169. package/dist/server/tests/inbox-slack-events.test.d.ts.map +1 -0
  170. package/dist/server/tests/inbox-slack-events.test.js +271 -0
  171. package/dist/server/tests/inbox.test.d.ts +2 -0
  172. package/dist/server/tests/inbox.test.d.ts.map +1 -0
  173. package/dist/server/tests/inbox.test.js +144 -0
  174. package/dist/server/tests/interactive-ask.test.d.ts +2 -0
  175. package/dist/server/tests/interactive-ask.test.d.ts.map +1 -0
  176. package/dist/server/tests/interactive-ask.test.js +387 -0
  177. package/dist/server/tests/kb.test.d.ts +2 -0
  178. package/dist/server/tests/kb.test.d.ts.map +1 -0
  179. package/dist/server/tests/kb.test.js +371 -0
  180. package/dist/server/tests/message.service.test.d.ts +2 -0
  181. package/dist/server/tests/message.service.test.d.ts.map +1 -0
  182. package/dist/server/tests/message.service.test.js +151 -0
  183. package/dist/server/tests/messages.test.d.ts +2 -0
  184. package/dist/server/tests/messages.test.d.ts.map +1 -0
  185. package/dist/server/tests/messages.test.js +12 -0
  186. package/dist/server/tests/prompt-attachments.test.d.ts +2 -0
  187. package/dist/server/tests/prompt-attachments.test.d.ts.map +1 -0
  188. package/dist/server/tests/prompt-attachments.test.js +274 -0
  189. package/dist/server/tests/provider-usage.test.d.ts +2 -0
  190. package/dist/server/tests/provider-usage.test.d.ts.map +1 -0
  191. package/dist/server/tests/provider-usage.test.js +97 -0
  192. package/dist/server/tests/reminders.test.d.ts +2 -0
  193. package/dist/server/tests/reminders.test.d.ts.map +1 -0
  194. package/dist/server/tests/reminders.test.js +383 -0
  195. package/dist/server/tests/runtime-cli.test.d.ts +2 -0
  196. package/dist/server/tests/runtime-cli.test.d.ts.map +1 -0
  197. package/dist/server/tests/runtime-cli.test.js +21 -0
  198. package/dist/server/tests/runtime-upgrade.test.d.ts +2 -0
  199. package/dist/server/tests/runtime-upgrade.test.d.ts.map +1 -0
  200. package/dist/server/tests/runtime-upgrade.test.js +307 -0
  201. package/dist/server/tests/runtime-worker.test.d.ts +2 -0
  202. package/dist/server/tests/runtime-worker.test.d.ts.map +1 -0
  203. package/dist/server/tests/runtime-worker.test.js +1021 -0
  204. package/dist/server/tests/runtime.test.d.ts +2 -0
  205. package/dist/server/tests/runtime.test.d.ts.map +1 -0
  206. package/dist/server/tests/runtime.test.js +354 -0
  207. package/dist/server/tests/services.test.d.ts +2 -0
  208. package/dist/server/tests/services.test.d.ts.map +1 -0
  209. package/dist/server/tests/services.test.js +636 -0
  210. package/dist/server/tests/slack-files.test.d.ts +2 -0
  211. package/dist/server/tests/slack-files.test.d.ts.map +1 -0
  212. package/dist/server/tests/slack-files.test.js +118 -0
  213. package/dist/server/tests/slack-shortcuts.test.d.ts +2 -0
  214. package/dist/server/tests/slack-shortcuts.test.d.ts.map +1 -0
  215. package/dist/server/tests/slack-shortcuts.test.js +310 -0
  216. package/dist/server/tests/slack.test.d.ts +2 -0
  217. package/dist/server/tests/slack.test.d.ts.map +1 -0
  218. package/dist/server/tests/slack.test.js +213 -0
  219. package/dist/server/tests/state-cache.test.d.ts +2 -0
  220. package/dist/server/tests/state-cache.test.d.ts.map +1 -0
  221. package/dist/server/tests/state-cache.test.js +184 -0
  222. package/dist/server/tests/subscriptions.test.d.ts +2 -0
  223. package/dist/server/tests/subscriptions.test.d.ts.map +1 -0
  224. package/dist/server/tests/subscriptions.test.js +292 -0
  225. package/dist/server/tests/system-service.test.d.ts +2 -0
  226. package/dist/server/tests/system-service.test.d.ts.map +1 -0
  227. package/dist/server/tests/system-service.test.js +20 -0
  228. package/dist/server/tests/url-routes.test.d.ts +2 -0
  229. package/dist/server/tests/url-routes.test.d.ts.map +1 -0
  230. package/dist/server/tests/url-routes.test.js +217 -0
  231. package/dist/server/tests/web-api.test.d.ts +2 -0
  232. package/dist/server/tests/web-api.test.d.ts.map +1 -0
  233. package/dist/server/tests/web-api.test.js +1759 -0
  234. package/dist/server/web/app.d.ts.map +1 -1
  235. package/dist/server/web/app.js +2 -0
  236. package/dist/server/web/client-error-routes.d.ts +3 -0
  237. package/dist/server/web/client-error-routes.d.ts.map +1 -0
  238. package/dist/server/web/client-error-routes.js +101 -0
  239. package/dist/server/web/system-routes.d.ts.map +1 -1
  240. package/dist/server/web/system-routes.js +21 -131
  241. package/dist/shared/agent-config.d.ts +8 -18
  242. package/dist/shared/agent-config.d.ts.map +1 -1
  243. package/dist/shared/agent-config.js +3 -4
  244. package/dist/shared/inbox.d.ts +27 -0
  245. package/dist/shared/inbox.d.ts.map +1 -1
  246. package/dist/shared/inbox.js +1 -0
  247. package/dist/shared/server-info.d.ts +6 -5
  248. package/dist/shared/server-info.d.ts.map +1 -1
  249. package/dist/shared/server-info.js +3 -1
  250. package/dist/shared/server-settings.d.ts +6 -0
  251. package/dist/shared/server-settings.d.ts.map +1 -1
  252. package/dist/shared/server-settings.js +1 -0
  253. package/dist/shared/skills.d.ts +24 -3
  254. package/dist/shared/skills.d.ts.map +1 -1
  255. package/dist/web/assets/activity-DHjip8tY.js +7 -0
  256. package/dist/web/assets/clipboard-D2NSC52v.js +1 -0
  257. package/dist/web/assets/{external-link-Dt0qTpmV.js → external-link-Bhr1WdRS.js} +1 -1
  258. package/dist/web/assets/{file-text-Dd9ys6py.js → file-text-CYMA_SMA.js} +1 -1
  259. package/dist/web/assets/{index-CzAQnbuO.js → index-CVpew409.js} +5 -5
  260. package/dist/web/assets/index-mh0uJTkY.css +2 -0
  261. package/dist/web/assets/kb-DDVpYkT9.js +35 -0
  262. package/dist/web/assets/profile-CBy6GNzp.js +1 -0
  263. package/dist/web/assets/reminders-Bbwb9QNT.js +1 -0
  264. package/dist/web/favicon.svg +1 -1
  265. package/dist/web/index.html +2 -2
  266. package/package.json +1 -1
  267. package/templates/runtime-standing-prompt.md +16 -2
  268. package/templates/skills/find-skills/SKILL.md +133 -0
  269. package/dist/server/runtime/activity-payload.d.ts.map +0 -1
  270. package/dist/server/runtime/activity-text.d.ts +0 -4
  271. package/dist/server/runtime/activity-text.d.ts.map +0 -1
  272. package/dist/server/runtime/activity-text.js +0 -16
  273. package/dist/server/runtime/managed-runtime.d.ts.map +0 -1
  274. package/dist/server/runtime/provider-contract.d.ts.map +0 -1
  275. package/dist/server/runtime/runtime-release.d.ts.map +0 -1
  276. package/dist/server/runtime/runtime-upgrade.d.ts.map +0 -1
  277. package/dist/server/slack/shortcut.service.d.ts.map +0 -1
  278. package/dist/server/slack/shortcut.service.js +0 -493
  279. package/dist/web/assets/activity-BP0C81IV.js +0 -7
  280. package/dist/web/assets/globe-DmDZSgDP.js +0 -1
  281. package/dist/web/assets/index-DKecrvN0.css +0 -2
  282. package/dist/web/assets/kb-3wFeP2Jt.js +0 -32
  283. package/dist/web/assets/profile-D7wPZXW_.js +0 -1
  284. package/dist/web/assets/reminders-DOhroVwo.js +0 -1
  285. /package/dist/server/{runtime/provider-contract.js → providers/contract.js} +0 -0
  286. /package/dist/server/{runtime → runtime-management}/managed-runtime.d.ts +0 -0
  287. /package/dist/server/{runtime → runtime-management}/managed-runtime.js +0 -0
  288. /package/dist/server/{runtime → runtime-management}/runtime-release.d.ts +0 -0
  289. /package/dist/server/{runtime → runtime-management}/runtime-release.js +0 -0
@@ -1,8 +1,8 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { withAnimaHome } from '../anima-home.js';
3
3
  import { defaultServerSettingsService } from '../settings/settings.service.js';
4
- import { DEFAULT_RUNTIME_PACKAGE, currentRuntimePackageInfo, ensureManagedRuntime, installManagedRuntime, readManagedRuntimeStatus, resolveManagedAnimaHome, } from '../runtime/managed-runtime.js';
5
- import { RuntimeUpgradeService, runRuntimeUpgradeWorker, } from '../runtime/runtime-upgrade.js';
4
+ import { DEFAULT_RUNTIME_PACKAGE, currentRuntimePackageInfo, ensureManagedRuntime, installManagedRuntime, readManagedRuntimeStatus, resolveManagedAnimaHome, } from '../runtime-management/managed-runtime.js';
5
+ import { RuntimeUpgradeService, runRuntimeUpgradeWorker, } from '../runtime-management/runtime-upgrade.js';
6
6
  import { RuntimeReleaseTrack } from '../../shared/runtime-upgrade.js';
7
7
  export function registerRuntimeCommand(program) {
8
8
  const runtime = program
@@ -64,6 +64,12 @@ function registerRuntimeCommands(program, options) {
64
64
  process.exitCode = 1;
65
65
  });
66
66
  }
67
+ program
68
+ .command('dashboard')
69
+ .description('Launch the local Anima dashboard in your browser')
70
+ .action(async () => {
71
+ await runDashboardCommand();
72
+ });
67
73
  program
68
74
  .command('upgrade-status')
69
75
  .description('Check whether the managed runtime has an available update')
@@ -109,6 +115,7 @@ function registerRuntimeCommands(program, options) {
109
115
  });
110
116
  serviceCommand(program, 'start', { installable: true })
111
117
  .description('Install the managed runtime if needed, then start local Anima services')
118
+ .option('--no-browser', 'Do not launch the dashboard after starting services')
112
119
  .action(async (options) => {
113
120
  await runManagedServiceCommand('start', options);
114
121
  });
@@ -216,8 +223,11 @@ async function runManagedServiceCommand(command, options) {
216
223
  }
217
224
  }
218
225
  const exitCode = await runAnimactlServices(paths.animactlScript, paths.packageDir, command, options);
219
- if (exitCode !== 0)
226
+ if (exitCode !== 0) {
220
227
  process.exitCode = exitCode;
228
+ return;
229
+ }
230
+ await handleDashboardAfterServiceCommand(command, options);
221
231
  }
222
232
  async function installRuntimeForService(options) {
223
233
  const current = await currentRuntimePackageInfo();
@@ -232,6 +242,95 @@ async function installRuntimeForService(options) {
232
242
  console.log(`dir: ${result.paths.runtimeDir}`);
233
243
  return { paths: result.paths };
234
244
  }
245
+ async function runDashboardCommand() {
246
+ const url = await managedDashboardUrl();
247
+ if (!(await dashboardIsReachable(url))) {
248
+ console.error(`Dashboard is not reachable at ${url}. Run \`npx -y @meetquinn/animactl start\` first.`);
249
+ process.exitCode = 1;
250
+ return;
251
+ }
252
+ console.log(`Dashboard: ${url}`);
253
+ await launchDashboard(url);
254
+ }
255
+ async function handleDashboardAfterServiceCommand(command, options) {
256
+ if (options.only === 'agent')
257
+ return;
258
+ if (command !== 'start' && command !== 'status')
259
+ return;
260
+ const url = await managedDashboardUrl();
261
+ console.log(`Dashboard: ${url}`);
262
+ if (command === 'start' && options.browser !== false && process.stdout.isTTY) {
263
+ if (await waitForDashboard(url, 5000)) {
264
+ await launchDashboard(url);
265
+ }
266
+ else {
267
+ console.warn(`Dashboard did not become reachable yet. Open it manually when ready: ${url}`);
268
+ }
269
+ }
270
+ }
271
+ async function managedDashboardUrl() {
272
+ return withAnimaHome(resolveManagedAnimaHome(), async () => {
273
+ const { host, port } = await defaultServerSettingsService.getDashboardSettings({
274
+ defaultHost: '0.0.0.0',
275
+ defaultPort: 4174,
276
+ });
277
+ return dashboardUrl(host, port);
278
+ });
279
+ }
280
+ export function dashboardUrl(host, port) {
281
+ const displayHost = host === '0.0.0.0' ? '127.0.0.1' : host;
282
+ return `http://${displayHost}:${port}`;
283
+ }
284
+ async function waitForDashboard(url, timeoutMs) {
285
+ const deadline = Date.now() + timeoutMs;
286
+ do {
287
+ if (await dashboardIsReachable(url, 500))
288
+ return true;
289
+ await sleep(150);
290
+ } while (Date.now() < deadline);
291
+ return false;
292
+ }
293
+ async function dashboardIsReachable(url, timeoutMs = 1000) {
294
+ try {
295
+ const controller = new AbortController();
296
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
297
+ try {
298
+ const response = await fetch(`${url}/api/health`, { signal: controller.signal });
299
+ return response.ok;
300
+ }
301
+ finally {
302
+ clearTimeout(timeout);
303
+ }
304
+ }
305
+ catch {
306
+ return false;
307
+ }
308
+ }
309
+ async function launchDashboard(url) {
310
+ const launcher = dashboardLaunchCommand(url, process.platform);
311
+ await new Promise((resolveOpened, reject) => {
312
+ const child = spawn(launcher.command, launcher.args, {
313
+ detached: true,
314
+ stdio: 'ignore',
315
+ });
316
+ child.once('error', reject);
317
+ child.once('spawn', () => {
318
+ child.unref();
319
+ resolveOpened();
320
+ });
321
+ }).catch((error) => {
322
+ console.warn(`Unable to launch dashboard automatically. Open it manually: ${url}`);
323
+ if (error instanceof Error && error.message)
324
+ console.warn(error.message);
325
+ });
326
+ }
327
+ export function dashboardLaunchCommand(url, platform) {
328
+ if (platform === 'darwin')
329
+ return { command: 'open', args: [url] };
330
+ if (platform === 'win32')
331
+ return { command: 'cmd', args: ['/c', 'start', '', url] };
332
+ return { command: 'xdg-open', args: [url] };
333
+ }
235
334
  function assertServiceOptions(options) {
236
335
  if (options.only && options.only !== 'agent' && options.only !== 'web') {
237
336
  throw new Error('--only must be "agent" or "web"');
@@ -274,6 +373,11 @@ async function runAnimactlServices(animactlScript, packageDir, command, options)
274
373
  });
275
374
  });
276
375
  }
376
+ function sleep(ms) {
377
+ return new Promise((resolveSleep) => {
378
+ setTimeout(resolveSleep, ms);
379
+ });
380
+ }
277
381
  function parseNonNegativeInteger(value) {
278
382
  const parsed = Number(value);
279
383
  if (!Number.isInteger(parsed) || parsed < 0)
@@ -1 +1 @@
1
- {"version":3,"file":"services-cli.d.ts","sourceRoot":"","sources":["../../../server/cli/services-cli.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4CzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuD9D"}
1
+ {"version":3,"file":"services-cli.d.ts","sourceRoot":"","sources":["../../../server/cli/services-cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4CzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+D9D"}
@@ -1,5 +1,6 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import { resolve as resolvePath } from 'node:path';
3
+ import { spawn } from 'node:child_process';
3
4
  import { defaultServerSettingsService } from '../settings/settings.service.js';
4
5
  import { resolveAnimaHome } from '../anima-home.js';
5
6
  import { clearRestartDrain, } from '../services/restart-drain.js';
@@ -48,12 +49,20 @@ export function registerServicesCommand(program) {
48
49
  const opts = command.optsWithGlobals();
49
50
  await runStatus(opts);
50
51
  });
52
+ services
53
+ .command('dashboard')
54
+ .description('Launch the local Anima dashboard')
55
+ .action(async (_, command) => {
56
+ const opts = command.optsWithGlobals();
57
+ await runDashboard(opts);
58
+ });
51
59
  }
52
60
  async function runStart(opts) {
53
61
  const { specs, supervisor } = await resolveServices(opts);
54
62
  for (const spec of specs)
55
63
  await startService(spec, supervisor);
56
64
  await printStatus(specs);
65
+ printDashboardHint(specs);
57
66
  }
58
67
  async function runStop(opts) {
59
68
  const { specs } = await resolveServices(opts);
@@ -77,6 +86,7 @@ async function runRestart(opts) {
77
86
  for (const spec of specs)
78
87
  await startService(spec, supervisor);
79
88
  await printStatus(specs);
89
+ printDashboardHint(specs);
80
90
  await writeRestartResult(gate.result);
81
91
  if (gate.drainResult?.resumedCount) {
82
92
  console.log(`restart: ${gate.drainResult.resumedCount} agent item(s) resumed after restart`);
@@ -96,6 +106,15 @@ async function runRestart(opts) {
96
106
  async function runStatus(opts) {
97
107
  const { specs } = await resolveServices(opts);
98
108
  await printStatus(specs);
109
+ printDashboardHint(specs);
110
+ }
111
+ async function runDashboard(opts) {
112
+ const { specs } = await resolveServices(opts);
113
+ const url = dashboardUrl(specs);
114
+ if (!url)
115
+ throw new Error('No web service URL is configured.');
116
+ console.log(`Dashboard: ${url}`);
117
+ await launchDashboard(url);
99
118
  }
100
119
  async function resolveServices(opts) {
101
120
  const animaHome = resolveAnimaHome();
@@ -131,6 +150,26 @@ async function resolveServices(opts) {
131
150
  const cwd = process.cwd();
132
151
  return { specs, supervisor: { animactl, cwd } };
133
152
  }
153
+ function printDashboardHint(specs) {
154
+ const url = dashboardUrl(specs);
155
+ if (url)
156
+ console.log(`Dashboard: ${url}`);
157
+ }
158
+ function dashboardUrl(specs) {
159
+ return specs.find((spec) => spec.id === 'web')?.url;
160
+ }
161
+ async function launchDashboard(url) {
162
+ const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
163
+ const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
164
+ await new Promise((resolveOpen, reject) => {
165
+ const child = spawn(command, args, { detached: true, stdio: 'ignore' });
166
+ child.once('error', reject);
167
+ child.once('spawn', () => {
168
+ child.unref();
169
+ resolveOpen();
170
+ });
171
+ });
172
+ }
134
173
  function assertCanControlServices(specs) {
135
174
  if (!specs.some((spec) => spec.id === 'agent'))
136
175
  return;
@@ -9,6 +9,7 @@ export declare class SlackInboxSubscriber {
9
9
  private readonly options;
10
10
  private readonly app;
11
11
  private readonly slackProfiles;
12
+ private botDisplayInfoSyncInFlight;
12
13
  constructor(options: SlackInboxSubscriberOptions);
13
14
  start(): Promise<void>;
14
15
  stop(): Promise<void>;
@@ -18,6 +19,7 @@ export declare class SlackInboxSubscriber {
18
19
  private handleInteractiveAskAction;
19
20
  private handleSlackWorkspaceDirectoryEvent;
20
21
  private handleSlackEvent;
22
+ private maybeSyncBotDisplayInfo;
21
23
  private slackPermalink;
22
24
  }
23
25
  //# sourceMappingURL=slack-subscriber.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slack-subscriber.d.ts","sourceRoot":"","sources":["../../../server/inbox/slack-subscriber.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,gBAAgB,EAA+B,MAAM,yBAAyB,CAAC;AAExF,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,qBAAa,oBAAoB;IAInB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;gBAE/B,OAAO,EAAE,2BAA2B;IAI3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,OAAO,CAAC,SAAS;YA4EH,oBAAoB;YASpB,qBAAqB;YAOrB,0BAA0B;YA2C1B,kCAAkC;YAYlC,gBAAgB;YA2DhB,cAAc;CAgB7B"}
1
+ {"version":3,"file":"slack-subscriber.d.ts","sourceRoot":"","sources":["../../../server/inbox/slack-subscriber.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,gBAAgB,EAA+B,MAAM,yBAAyB,CAAC;AAExF,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAG5D,OAAO,CAAC,0BAA0B,CAAS;gBAEd,OAAO,EAAE,2BAA2B;IAI3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,OAAO,CAAC,SAAS;YA4EH,oBAAoB;YASpB,qBAAqB;YAOrB,0BAA0B;YA2C1B,kCAAkC;YAYlC,gBAAgB;IAgE9B,OAAO,CAAC,uBAAuB;YAajB,cAAc;CAgB7B"}
@@ -1,10 +1,11 @@
1
1
  import { App, LogLevel } from '@slack/bolt';
2
2
  import { activityServiceForAgent } from '../activities/activity.service.js';
3
+ import { agentSlackServiceForAgent } from '../agents/agent-slack.service.js';
3
4
  import { interactiveAskServiceForAgent } from '../asks/interactive-ask.service.js';
4
5
  import { errorMessage, slackMessageEventId } from '../ids.js';
5
6
  import { createSlackWebClient } from '../slack/client.js';
6
- import { defaultSlackShortcutService, userIdFromShortcutBody, } from '../slack/shortcut.service.js';
7
- import { SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID, SLACK_VIEW_REMINDER_DETAIL_ACTION_ID, SLACK_VIEW_REMINDERS_ACTION_ID } from '../slack/shortcuts.js';
7
+ import { defaultSlackShortcutService, userIdFromShortcutBody, } from '../slack-interactions/shortcut.service.js';
8
+ import { SLACK_STOP_CONFIRM_VIEW_CALLBACK_ID, SLACK_VIEW_REMINDER_DETAIL_ACTION_ID, SLACK_VIEW_REMINDERS_ACTION_ID, } from '../slack-interactions/shortcut-ids.js';
8
9
  import { SlackWorkspaceDirectoryService } from '../slack/workspace-directory.service.js';
9
10
  import { replaceSlackChannelMentions, replaceSlackUserMentions, normalizeSlackEventFiles, } from '../slack/slack.helper.js';
10
11
  import { isSlackEvent, isRoutableSlackMessage, normalizeSlackMessage, slackSurfaceForEvent, } from './slack-events.js';
@@ -14,6 +15,9 @@ export class SlackInboxSubscriber {
14
15
  options;
15
16
  app;
16
17
  slackProfiles = new SlackProfileResolver();
18
+ // Guards the fire-and-forget bot display-info refresh so overlapping inbound
19
+ // messages don't trigger concurrent syncs.
20
+ botDisplayInfoSyncInFlight = false;
17
21
  constructor(options) {
18
22
  this.options = options;
19
23
  this.app = this.createApp();
@@ -183,6 +187,7 @@ export class SlackInboxSubscriber {
183
187
  return;
184
188
  }
185
189
  const webClient = client ?? createSlackWebClient(this.options.botToken);
190
+ this.maybeSyncBotDisplayInfo(webClient);
186
191
  const userProfile = await this.slackProfiles.user({
187
192
  client: webClient,
188
193
  teamId,
@@ -225,6 +230,23 @@ export class SlackInboxSubscriber {
225
230
  }
226
231
  console.log(JSON.stringify(slackDecisionLog(decision, this.options.agentRuntimeKind, runtimeDecision), null, 2));
227
232
  }
233
+ // Opportunistically refresh the bot's own display info (avatar, name,
234
+ // workspace icon) while we're already handling a message. Throttled to once
235
+ // per TTL by the service, fire-and-forget so it never blocks or fails message
236
+ // routing, and guarded against overlapping runs within this process.
237
+ maybeSyncBotDisplayInfo(client) {
238
+ if (this.botDisplayInfoSyncInFlight)
239
+ return;
240
+ this.botDisplayInfoSyncInFlight = true;
241
+ agentSlackServiceForAgent(this.options.queue.agentId)
242
+ .syncDisplayInfoIfStale({ client, ttlMs: BOT_DISPLAY_INFO_SYNC_TTL_MS })
243
+ .catch((error) => {
244
+ console.warn(`bot display-info sync failed: ${errorMessage(error)}`);
245
+ })
246
+ .finally(() => {
247
+ this.botDisplayInfoSyncInFlight = false;
248
+ });
249
+ }
228
250
  async slackPermalink(event, client) {
229
251
  if (!event.channel || !event.ts)
230
252
  return undefined;
@@ -241,6 +263,10 @@ export class SlackInboxSubscriber {
241
263
  }
242
264
  }
243
265
  }
266
+ // Refresh the bot's own Slack display info at most once every 6h while handling
267
+ // messages — frequent enough to pick up an avatar/name change soon after it
268
+ // happens, rare enough to add no meaningful Slack API load.
269
+ const BOT_DISPLAY_INFO_SYNC_TTL_MS = 6 * 60 * 60 * 1000;
244
270
  const SLACK_DIRECTORY_EVENTS = [
245
271
  'channel_archive',
246
272
  'channel_created',
@@ -1 +1 @@
1
- {"version":3,"file":"slack-subscription.service.d.ts","sourceRoot":"","sources":["../../../server/inbox/slack-subscription.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-subscription.service.d.ts","sourceRoot":"","sources":["../../../server/inbox/slack-subscription.service.ts"],"names":[],"mappings":"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"}
@@ -212,7 +212,7 @@ export async function ensureThreadSubscriptionForSentMessage(input) {
212
212
  const now = new Date(nowMs).toISOString();
213
213
  const threadTs = input.threadTs || input.messageTs;
214
214
  const store = new SubscriptionStore(input.agentId);
215
- return followThread({
215
+ const primary = await followThread({
216
216
  agentId: input.agentId,
217
217
  channelId: input.channelId,
218
218
  now,
@@ -221,6 +221,18 @@ export async function ensureThreadSubscriptionForSentMessage(input) {
221
221
  threadTs,
222
222
  unmute: true,
223
223
  });
224
+ if (input.threadTs && input.messageTs !== input.threadTs) {
225
+ await followThread({
226
+ agentId: input.agentId,
227
+ channelId: input.channelId,
228
+ now,
229
+ posted: true,
230
+ store,
231
+ threadTs: input.messageTs,
232
+ unmute: true,
233
+ });
234
+ }
235
+ return primary;
224
236
  }
225
237
  function followThread(input) {
226
238
  return input.store.find(threadSubscriptionId(input.agentId, input.channelId, input.threadTs))
@@ -35,7 +35,9 @@ export declare class WakeQueueService {
35
35
  }): Promise<InboxItem[]>;
36
36
  complete(itemId: string): Promise<void>;
37
37
  fail(itemId: string): Promise<void>;
38
- requeue(itemId: string): Promise<void>;
38
+ requeue(itemId: string, options?: {
39
+ resumeReason?: 'runtime_restart';
40
+ }): Promise<void>;
39
41
  requestStop(itemId: string): Promise<InboxItem>;
40
42
  requestDrain(input: {
41
43
  itemId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"wake-queue.service.d.ts","sourceRoot":"","sources":["../../../server/inbox/wake-queue.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpD;AAED,UAAU,eAAe;IACvB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAID,qBAAa,gBAAgB;IAEzB,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHd,OAAO,EAAE,MAAM,EACP,KAAK,GAAE,cAA4C,EACnD,QAAQ,GAAE,wBAA0D,EACpE,MAAM,GAAE,eAAyB;IAG9C,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAWhE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAIpD,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAIhD,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAI5B,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAI9B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAM3D,iBAAiB,CAAC,KAAK,EAAE;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAY5B,kBAAkB,CAAC,KAAK,EAAE;QAC9B,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;KAC9C,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAYlB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAI/C,YAAY,CAAC,KAAK,EAAE;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,SAAS,CAAC;IAItB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIrD,WAAW,CAAC,KAAK,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,CAAC;IAIhB,WAAW,CAAC,KAAK,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAMpB,gBAAgB;YAShB,aAAa;YAQb,eAAe;CAU9B"}
1
+ {"version":3,"file":"wake-queue.service.d.ts","sourceRoot":"","sources":["../../../server/inbox/wake-queue.service.ts"],"names":[],"mappings":"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"}
@@ -58,7 +58,9 @@ export class WakeQueueService {
58
58
  continue;
59
59
  if (item.handling.workerId && input.isWorkerAlive(item.handling.workerId))
60
60
  continue;
61
- await this.store.requeue(item.id);
61
+ await this.store.requeue(item.id, {
62
+ ...(item.handling.drainRequestedAt ? { resumeReason: 'runtime_restart' } : {}),
63
+ });
62
64
  const updated = await this.find(item.id);
63
65
  if (updated?.handling.status === 'queued')
64
66
  recovered.push(updated);
@@ -73,8 +75,8 @@ export class WakeQueueService {
73
75
  await this.store.fail(itemId);
74
76
  await this.pruneOldSettled();
75
77
  }
76
- requeue(itemId) {
77
- return this.store.requeue(itemId);
78
+ requeue(itemId, options = {}) {
79
+ return this.store.requeue(itemId, options);
78
80
  }
79
81
  requestStop(itemId) {
80
82
  return this.store.requestStop(itemId);
@@ -13,4 +13,5 @@ export interface FetchJsonResult {
13
13
  }
14
14
  export declare function fetchJson({ body, headers, method, timeoutMs, url, }: FetchJsonOptions): Promise<FetchJsonResult>;
15
15
  export declare function bearer(token: string): string;
16
+ export declare function providerUsageNetworkErrorMessage(error: unknown): string;
16
17
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../server/provider-usage/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,EAC9B,IAAI,EACJ,OAAY,EACZ,MAAc,EACd,SAAkB,EAClB,GAAG,GACJ,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC7C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5C"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../server/provider-usage/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,EAC9B,IAAI,EACJ,OAAY,EACZ,MAAc,EACd,SAAkB,EAClB,GAAG,GACJ,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAiC7C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAwBvE"}
@@ -28,7 +28,7 @@ export async function fetchJson({ body, headers = {}, method = 'GET', timeoutMs
28
28
  return {
29
29
  error: {
30
30
  type: 'network_error',
31
- message: error instanceof Error ? error.message : 'Provider usage request failed',
31
+ message: providerUsageNetworkErrorMessage(error),
32
32
  },
33
33
  };
34
34
  }
@@ -37,3 +37,25 @@ export function bearer(token) {
37
37
  const trimmed = token.trim();
38
38
  return trimmed.toLowerCase().startsWith('bearer ') ? trimmed : `Bearer ${trimmed}`;
39
39
  }
40
+ export function providerUsageNetworkErrorMessage(error) {
41
+ if (error instanceof Error && error.name === 'AbortError') {
42
+ return 'Provider usage request timed out.';
43
+ }
44
+ const cause = error instanceof Error ? error.cause : undefined;
45
+ const code = typeof cause === 'object' && cause !== null && 'code' in cause
46
+ ? String(cause.code ?? '')
47
+ : '';
48
+ if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {
49
+ return 'Provider usage service could not be resolved.';
50
+ }
51
+ if (code === 'ETIMEDOUT' || code === 'UND_ERR_CONNECT_TIMEOUT') {
52
+ return 'Provider usage request timed out.';
53
+ }
54
+ if (code === 'ECONNRESET' || code === 'ECONNREFUSED' || code === 'UND_ERR_SOCKET') {
55
+ return 'Provider usage connection was interrupted.';
56
+ }
57
+ if (code.includes('CERT') || code.includes('TLS') || code === 'DEPTH_ZERO_SELF_SIGNED_CERT') {
58
+ return 'Provider usage TLS check failed.';
59
+ }
60
+ return 'Provider usage request could not reach the provider service.';
61
+ }
@@ -1,4 +1,4 @@
1
- import type { ProviderUsageError, ProviderUsageKind, ProviderUsageResponse, ProviderUsageRow } from '../../shared/provider-usage.js';
1
+ import type { ProviderUsageKind, ProviderUsageResponse, ProviderUsageRow } from '../../shared/provider-usage.js';
2
2
  export interface ProviderUsageAdapter {
3
3
  label: string;
4
4
  provider: ProviderUsageKind;
@@ -11,9 +11,6 @@ export declare class ProviderUsageService {
11
11
  list(): Promise<ProviderUsageResponse>;
12
12
  private fetchProvider;
13
13
  }
14
- export declare function usageError(type: ProviderUsageError['type'], message: string): ProviderUsageError;
15
- export declare function unavailable(error: ProviderUsageError): Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>;
16
- export declare function available(windows: ProviderUsageRow['windows'], extras?: ProviderUsageRow['extras']): Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>;
17
14
  export declare function defaultProviderUsageAdapters(): ProviderUsageAdapter[];
18
15
  export declare const defaultProviderUsageService: ProviderUsageService;
19
16
  //# sourceMappingURL=provider-usage.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-usage.service.d.ts","sourceRoot":"","sources":["../../../server/provider-usage/provider-usage.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AAKxC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;CAC7F;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,oBAAoB,EAAmC;IAExF,IAAI,IAAI,OAAO,CAAC,qBAAqB,CAAC;YAK9B,aAAa;CAuB5B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAEhG;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAO5H;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,EACpC,MAAM,GAAE,gBAAgB,CAAC,QAAQ,CAAM,GACtC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAMvE;AAED,wBAAgB,4BAA4B,IAAI,oBAAoB,EAAE,CAqBrE;AAED,eAAO,MAAM,2BAA2B,sBAA6B,CAAC"}
1
+ {"version":3,"file":"provider-usage.service.d.ts","sourceRoot":"","sources":["../../../server/provider-usage/provider-usage.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AAMxC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;CAC7F;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,oBAAoB,EAAmC;IAExF,IAAI,IAAI,OAAO,CAAC,qBAAqB,CAAC;YAK9B,aAAa;CAuB5B;AAED,wBAAgB,4BAA4B,IAAI,oBAAoB,EAAE,CAqBrE;AAED,eAAO,MAAM,2BAA2B,sBAA6B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { fetchClaudeUsage } from './providers/claude.js';
2
2
  import { fetchCodexUsage } from './providers/codex.js';
3
3
  import { fetchKimiUsage } from './providers/kimi.js';
4
+ import { usageError } from './result.js';
4
5
  export class ProviderUsageService {
5
6
  adapters;
6
7
  constructor(adapters = defaultProviderUsageAdapters()) {
@@ -35,24 +36,6 @@ export class ProviderUsageService {
35
36
  }
36
37
  }
37
38
  }
38
- export function usageError(type, message) {
39
- return { message, type };
40
- }
41
- export function unavailable(error) {
42
- return {
43
- error,
44
- extras: [],
45
- status: 'unavailable',
46
- windows: [],
47
- };
48
- }
49
- export function available(windows, extras = []) {
50
- return {
51
- extras,
52
- status: 'available',
53
- windows,
54
- };
55
- }
56
39
  export function defaultProviderUsageAdapters() {
57
40
  return [
58
41
  {
@@ -1,5 +1,5 @@
1
1
  import type { ProviderUsageExtra, ProviderUsageRow, ProviderUsageWindow } from '../../../shared/provider-usage.js';
2
- import { usageError } from '../provider-usage.service.js';
2
+ import { usageError } from '../result.js';
3
3
  interface ClaudeCredentials {
4
4
  accessToken: string;
5
5
  rateLimitTier?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/claude.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAiBlF,UAAU,iBAAiB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAmBvH;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,WAAW,GAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,kBAAkB,CAAM,GAC9E;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA+BzG"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/claude.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,cAAc,CAAC;AAiBlE,UAAU,iBAAiB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAmBvH;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,WAAW,GAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,kBAAkB,CAAM,GAC9E;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA+BzG"}
@@ -1,7 +1,7 @@
1
1
  import { execFile } from 'node:child_process';
2
2
  import { promisify } from 'node:util';
3
3
  import { bearer, fetchJson } from '../http.js';
4
- import { available, unavailable, usageError } from '../provider-usage.service.js';
4
+ import { available, unavailable, usageError } from '../result.js';
5
5
  import { clampPercent, homePath, numberValue, readJsonFile, record, resetAtFromValue, stringValue, } from './common.js';
6
6
  const execFileAsync = promisify(execFile);
7
7
  const CLAUDE_USAGE_API = 'https://api.anthropic.com/api/oauth/usage';
@@ -1,5 +1,5 @@
1
1
  import type { ProviderUsageExtra, ProviderUsageRow, ProviderUsageWindow } from '../../../shared/provider-usage.js';
2
- import { usageError } from '../provider-usage.service.js';
2
+ import { usageError } from '../result.js';
3
3
  export declare function fetchCodexUsage(): Promise<Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>>;
4
4
  export declare function parseCodexUsageResponse(data: unknown): {
5
5
  error?: ReturnType<typeof usageError>;
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAUlF,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAatH;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,GACZ;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA4BzG"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,cAAc,CAAC;AAUlE,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAatH;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,GACZ;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA4BzG"}
@@ -1,5 +1,5 @@
1
1
  import { bearer, fetchJson } from '../http.js';
2
- import { available, unavailable, usageError } from '../provider-usage.service.js';
2
+ import { available, unavailable, usageError } from '../result.js';
3
3
  import { homePath, numberValue, readJsonFile, record, stringValue, windowFromUsedPercent } from './common.js';
4
4
  const CODEX_USAGE_API = 'https://chatgpt.com/backend-api/wham/usage';
5
5
  const CODEX_AUTH_PATH = ['.codex', 'auth.json'];
@@ -1,5 +1,5 @@
1
1
  import type { ProviderUsageExtra, ProviderUsageRow, ProviderUsageWindow } from '../../../shared/provider-usage.js';
2
- import { usageError } from '../provider-usage.service.js';
2
+ import { usageError } from '../result.js';
3
3
  export declare function fetchKimiUsage(): Promise<Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>>;
4
4
  export declare function parseKimiUsageResponse(data: unknown): {
5
5
  error?: ReturnType<typeof usageError>;
@@ -1 +1 @@
1
- {"version":3,"file":"kimi.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/kimi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAgBlF,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAarH;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,GACZ;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA2BzG"}
1
+ {"version":3,"file":"kimi.d.ts","sourceRoot":"","sources":["../../../../server/provider-usage/providers/kimi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnH,OAAO,EAA0B,UAAU,EAAE,MAAM,cAAc,CAAC;AAgBlE,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,CAarH;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,GACZ;IAAE,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,mBAAmB,EAAE,CAAA;CAAE,CA2BzG"}
@@ -1,6 +1,6 @@
1
1
  import { join } from 'node:path';
2
2
  import { bearer, fetchJson } from '../http.js';
3
- import { available, unavailable, usageError } from '../provider-usage.service.js';
3
+ import { available, unavailable, usageError } from '../result.js';
4
4
  import { clampPercent, homePath, numberValue, readJsonFile, record, resetAtFromSeconds, resetAtFromValue, stringValue, } from './common.js';
5
5
  const KIMI_USAGE_API = 'https://api.kimi.com/coding/v1/usages';
6
6
  const KIMI_CREDENTIALS_PATH = ['.kimi', 'credentials', 'kimi-code.json'];
@@ -25,10 +25,8 @@ export function parseKimiUsageResponse(data) {
25
25
  const root = record(data);
26
26
  if (!root)
27
27
  return { error: usageError('parse_error', 'Kimi usage response is not an object'), extras: [], windows: [] };
28
- const windows = [];
29
28
  const summary = kimiUsageWindow('Weekly', record(root.usage));
30
- if (summary)
31
- windows.push(summary);
29
+ const windows = [];
32
30
  const limits = Array.isArray(root.limits) ? root.limits : [];
33
31
  for (const [index, rawLimit] of limits.entries()) {
34
32
  const limit = record(rawLimit);
@@ -38,6 +36,8 @@ export function parseKimiUsageResponse(data) {
38
36
  if (parsed)
39
37
  windows.push(parsed);
40
38
  }
39
+ if (summary)
40
+ windows.push(summary);
41
41
  if (windows.length === 0) {
42
42
  return { error: usageError('parse_error', 'Kimi usage response did not include usage windows'), extras: [], windows: [] };
43
43
  }
@@ -0,0 +1,5 @@
1
+ import type { ProviderUsageError, ProviderUsageRow } from '../../shared/provider-usage.js';
2
+ export declare function usageError(type: ProviderUsageError['type'], message: string): ProviderUsageError;
3
+ export declare function unavailable(error: ProviderUsageError): Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>;
4
+ export declare function available(windows: ProviderUsageRow['windows'], extras?: ProviderUsageRow['extras']): Omit<ProviderUsageRow, 'checkedAt' | 'label' | 'provider' | 'source'>;
5
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../../server/provider-usage/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AAExC,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAEhG;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAO5H;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,EACpC,MAAM,GAAE,gBAAgB,CAAC,QAAQ,CAAM,GACtC,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAMvE"}