@signalcore/ui 0.1.0 → 1.0.0-beta.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 (611) hide show
  1. package/README.md +896 -513
  2. package/dist/AgentAbout.d.ts +186 -0
  3. package/dist/AgentAbout.js +1020 -0
  4. package/dist/AgentAbout.js.map +1 -0
  5. package/dist/AgentCard.d.ts +49 -0
  6. package/dist/AgentCard.js +77 -0
  7. package/dist/AgentCard.js.map +1 -0
  8. package/dist/AgentChat.d.ts +233 -0
  9. package/dist/AgentChat.js +1119 -0
  10. package/dist/AgentChat.js.map +1 -0
  11. package/dist/AgentSpace.d.ts +112 -0
  12. package/dist/AgentSpace.js +339 -0
  13. package/dist/AgentSpace.js.map +1 -0
  14. package/dist/AgentTasks.d.ts +48 -0
  15. package/dist/AgentTasks.js +120 -0
  16. package/dist/AgentTasks.js.map +1 -0
  17. package/dist/BrowserView.d.ts +52 -0
  18. package/dist/BrowserView.js +328 -0
  19. package/dist/BrowserView.js.map +1 -0
  20. package/dist/FileView.d.ts +63 -0
  21. package/dist/FileView.js +449 -0
  22. package/dist/FileView.js.map +1 -0
  23. package/dist/Modes.d.ts +13 -0
  24. package/dist/Modes.js +75 -0
  25. package/dist/Modes.js.map +1 -0
  26. package/dist/VoiceCall.d.ts +91 -0
  27. package/dist/VoiceCall.js +302 -0
  28. package/dist/VoiceCall.js.map +1 -0
  29. package/dist/about.d.ts +212 -0
  30. package/dist/about.js +136 -0
  31. package/dist/about.js.map +1 -0
  32. package/dist/agentIcons.d.ts +33 -0
  33. package/dist/agentIcons.js +36 -0
  34. package/dist/agentIcons.js.map +1 -0
  35. package/dist/automation/Automation.d.ts +35 -0
  36. package/dist/automation/Automation.js +268 -0
  37. package/dist/automation/Automation.js.map +1 -0
  38. package/dist/automation/RunView.d.ts +25 -0
  39. package/dist/automation/RunView.js +187 -0
  40. package/dist/automation/RunView.js.map +1 -0
  41. package/dist/automation/cron.d.ts +41 -0
  42. package/dist/automation/cron.js +169 -0
  43. package/dist/automation/cron.js.map +1 -0
  44. package/dist/automation/marks.js +121 -0
  45. package/dist/automation/marks.js.map +1 -0
  46. package/dist/automation/messages.d.ts +113 -0
  47. package/dist/automation/messages.js +113 -0
  48. package/dist/automation/messages.js.map +1 -0
  49. package/dist/automation/record.d.ts +47 -0
  50. package/dist/automation/record.js +177 -0
  51. package/dist/automation/record.js.map +1 -0
  52. package/dist/automation/types.d.ts +143 -0
  53. package/dist/automation/when.d.ts +36 -0
  54. package/dist/automation/when.js +168 -0
  55. package/dist/automation/when.js.map +1 -0
  56. package/dist/blocks.d.ts +185 -0
  57. package/dist/browser.js +292 -0
  58. package/dist/browser.js.map +1 -0
  59. package/dist/call.d.ts +89 -0
  60. package/dist/call.js +218 -0
  61. package/dist/call.js.map +1 -0
  62. package/dist/channelParts.js +26 -0
  63. package/dist/channelParts.js.map +1 -0
  64. package/dist/classes.js +8 -3
  65. package/dist/classes.js.map +1 -0
  66. package/dist/client.d.ts +146 -54
  67. package/dist/client.js +204 -1
  68. package/dist/client.js.map +1 -0
  69. package/dist/conversationFiles.js +46 -0
  70. package/dist/conversationFiles.js.map +1 -0
  71. package/dist/credentials.d.ts +45 -0
  72. package/dist/credentials.js +98 -0
  73. package/dist/credentials.js.map +1 -0
  74. package/dist/dev.js +17 -0
  75. package/dist/dev.js.map +1 -0
  76. package/dist/es.d.ts +17 -0
  77. package/dist/es.js +382 -0
  78. package/dist/es.js.map +1 -0
  79. package/dist/files.d.ts +21 -0
  80. package/dist/files.js +214 -0
  81. package/dist/files.js.map +1 -0
  82. package/dist/frames.d.ts +115 -0
  83. package/dist/frames.js +219 -0
  84. package/dist/frames.js.map +1 -0
  85. package/dist/icons.js +29 -0
  86. package/dist/icons.js.map +1 -0
  87. package/dist/index.d.ts +63 -60
  88. package/dist/index.js +59 -45
  89. package/dist/kit/AudioPlayer.d.ts +20 -0
  90. package/dist/kit/AudioPlayer.js +116 -0
  91. package/dist/kit/AudioPlayer.js.map +1 -0
  92. package/dist/kit/Button.d.ts +29 -0
  93. package/dist/kit/Button.js +59 -0
  94. package/dist/kit/Button.js.map +1 -0
  95. package/dist/kit/Card.d.ts +16 -0
  96. package/dist/kit/Card.js +36 -0
  97. package/dist/kit/Card.js.map +1 -0
  98. package/dist/kit/Chart.js +152 -0
  99. package/dist/kit/Chart.js.map +1 -0
  100. package/dist/kit/Choices.d.ts +21 -0
  101. package/dist/kit/Choices.js +99 -0
  102. package/dist/kit/Choices.js.map +1 -0
  103. package/dist/kit/Combobox.d.ts +26 -0
  104. package/dist/kit/Combobox.js +190 -0
  105. package/dist/kit/Combobox.js.map +1 -0
  106. package/dist/kit/DateField.d.ts +17 -0
  107. package/dist/kit/DateField.js +133 -0
  108. package/dist/kit/DateField.js.map +1 -0
  109. package/dist/kit/Field.d.ts +40 -0
  110. package/dist/kit/Field.js +98 -0
  111. package/dist/kit/Field.js.map +1 -0
  112. package/dist/kit/FileField.d.ts +113 -0
  113. package/dist/kit/FileField.js +341 -0
  114. package/dist/kit/FileField.js.map +1 -0
  115. package/dist/kit/FileMark.d.ts +15 -0
  116. package/dist/kit/FileMark.js +39 -0
  117. package/dist/kit/FileMark.js.map +1 -0
  118. package/dist/kit/Inputs.d.ts +59 -0
  119. package/dist/kit/Inputs.js +205 -0
  120. package/dist/kit/Inputs.js.map +1 -0
  121. package/dist/kit/List.d.ts +47 -0
  122. package/dist/kit/List.js +85 -0
  123. package/dist/kit/List.js.map +1 -0
  124. package/dist/kit/Mark.d.ts +30 -0
  125. package/dist/kit/Mark.js +27 -0
  126. package/dist/kit/Mark.js.map +1 -0
  127. package/dist/kit/MarkStack.d.ts +15 -0
  128. package/dist/kit/MarkStack.js +26 -0
  129. package/dist/kit/MarkStack.js.map +1 -0
  130. package/dist/kit/Note.d.ts +11 -0
  131. package/dist/kit/Note.js +31 -0
  132. package/dist/kit/Note.js.map +1 -0
  133. package/dist/kit/Popover.js +90 -0
  134. package/dist/kit/Popover.js.map +1 -0
  135. package/dist/kit/RangeField.d.ts +14 -0
  136. package/dist/kit/RangeField.js +47 -0
  137. package/dist/kit/RangeField.js.map +1 -0
  138. package/dist/kit/RatingField.d.ts +14 -0
  139. package/dist/kit/RatingField.js +50 -0
  140. package/dist/kit/RatingField.js.map +1 -0
  141. package/dist/kit/Stat.d.ts +26 -0
  142. package/dist/kit/Stat.js +46 -0
  143. package/dist/kit/Stat.js.map +1 -0
  144. package/dist/kit/Switch.d.ts +14 -0
  145. package/dist/kit/Switch.js +21 -0
  146. package/dist/kit/Switch.js.map +1 -0
  147. package/dist/kit/Tag.d.ts +16 -0
  148. package/dist/kit/Tag.js +20 -0
  149. package/dist/kit/Tag.js.map +1 -0
  150. package/dist/kit/Tile.d.ts +34 -0
  151. package/dist/kit/Tile.js +52 -0
  152. package/dist/kit/Tile.js.map +1 -0
  153. package/dist/kit/TimeField.d.ts +31 -0
  154. package/dist/kit/TimeField.js +109 -0
  155. package/dist/kit/TimeField.js.map +1 -0
  156. package/dist/kit/context.d.ts +22 -0
  157. package/dist/kit/context.js +46 -0
  158. package/dist/kit/context.js.map +1 -0
  159. package/dist/kit/dates.d.ts +14 -0
  160. package/dist/kit/dates.js +129 -0
  161. package/dist/kit/dates.js.map +1 -0
  162. package/dist/kit/messages.d.ts +99 -0
  163. package/dist/kit/messages.js +66 -0
  164. package/dist/kit/messages.js.map +1 -0
  165. package/dist/kit/numbers.d.ts +12 -0
  166. package/dist/kit/numbers.js +40 -0
  167. package/dist/kit/numbers.js.map +1 -0
  168. package/dist/kit/options.d.ts +10 -0
  169. package/dist/kit/options.js +23 -0
  170. package/dist/kit/options.js.map +1 -0
  171. package/dist/kit/uploads.d.ts +42 -0
  172. package/dist/kit/uploads.js +165 -0
  173. package/dist/kit/uploads.js.map +1 -0
  174. package/dist/kit/waveform.js +76 -0
  175. package/dist/kit/waveform.js.map +1 -0
  176. package/dist/locale.d.ts +1 -0
  177. package/dist/locale.js +1 -0
  178. package/dist/markdown.js +84 -0
  179. package/dist/markdown.js.map +1 -0
  180. package/dist/marks.js +217 -0
  181. package/dist/marks.js.map +1 -0
  182. package/dist/reveal.js +48 -0
  183. package/dist/reveal.js.map +1 -0
  184. package/dist/stepGlyphs.js +62 -0
  185. package/dist/stepGlyphs.js.map +1 -0
  186. package/dist/surface/Form.js +264 -0
  187. package/dist/surface/Form.js.map +1 -0
  188. package/dist/surface/Markdown.js +42 -0
  189. package/dist/surface/Markdown.js.map +1 -0
  190. package/dist/surface/Surface.d.ts +31 -17
  191. package/dist/surface/Surface.js +480 -57
  192. package/dist/surface/Surface.js.map +1 -0
  193. package/dist/surface/scope.d.ts +32 -0
  194. package/dist/surface/scope.js +23 -0
  195. package/dist/surface/scope.js.map +1 -0
  196. package/dist/surface/values.d.ts +44 -0
  197. package/dist/surface/values.js +237 -0
  198. package/dist/surface/values.js.map +1 -0
  199. package/dist/tint.d.ts +10 -0
  200. package/dist/tint.js +19 -0
  201. package/dist/tint.js.map +1 -0
  202. package/dist/types.d.ts +534 -0
  203. package/dist/types.js +16 -0
  204. package/dist/types.js.map +1 -0
  205. package/dist/useAgentFace.d.ts +18 -0
  206. package/dist/useAgentFace.js +45 -0
  207. package/dist/useAgentFace.js.map +1 -0
  208. package/dist/useCall.d.ts +39 -0
  209. package/dist/useCall.js +273 -0
  210. package/dist/useCall.js.map +1 -0
  211. package/dist/useConversation.d.ts +77 -0
  212. package/dist/useConversation.js +523 -0
  213. package/dist/useConversation.js.map +1 -0
  214. package/dist/useDictation.d.ts +17 -0
  215. package/dist/useDictation.js +68 -0
  216. package/dist/useDictation.js.map +1 -0
  217. package/dist/useLive.d.ts +26 -0
  218. package/dist/useLive.js +88 -0
  219. package/dist/useLive.js.map +1 -0
  220. package/dist/usePolled.js +68 -0
  221. package/dist/usePolled.js.map +1 -0
  222. package/dist/voice/Orb.d.ts +10 -9
  223. package/dist/voice/Orb.js +43 -39
  224. package/dist/voice/Orb.js.map +1 -0
  225. package/dist/voice/StillOrb.js +33 -0
  226. package/dist/voice/StillOrb.js.map +1 -0
  227. package/dist/voice/WebGLOrb.js +98 -0
  228. package/dist/voice/WebGLOrb.js.map +1 -0
  229. package/dist/voice/fluidDots.js +161 -0
  230. package/dist/voice/fluidDots.js.map +1 -0
  231. package/dist/voice/motion.js +84 -0
  232. package/dist/voice/motion.js.map +1 -0
  233. package/dist/voice/orbs.d.ts +32 -0
  234. package/dist/voice/orbs.js +16 -0
  235. package/dist/voice/orbs.js.map +1 -0
  236. package/dist/voice/useReducedMotion.js +16 -16
  237. package/dist/voice/useReducedMotion.js.map +1 -0
  238. package/dist/voice/wave.js +116 -0
  239. package/dist/voice/wave.js.map +1 -0
  240. package/dist/voice/webgl.js +177 -0
  241. package/dist/voice/webgl.js.map +1 -0
  242. package/dist/widget.js +284 -8
  243. package/package.json +49 -39
  244. package/src/AgentAbout.tsx +1621 -0
  245. package/src/AgentCard.tsx +123 -0
  246. package/src/AgentChat.tsx +1795 -0
  247. package/src/AgentSpace.tsx +540 -0
  248. package/src/AgentTasks.tsx +163 -0
  249. package/src/BrowserView.tsx +442 -0
  250. package/src/FileView.tsx +620 -0
  251. package/src/Modes.tsx +112 -0
  252. package/src/VoiceCall.tsx +411 -0
  253. package/src/about.ts +355 -0
  254. package/src/agentIcons.ts +56 -0
  255. package/src/automation/Automation.tsx +308 -0
  256. package/src/automation/RunView.tsx +213 -0
  257. package/src/automation/cron.ts +196 -0
  258. package/src/automation/marks.tsx +144 -0
  259. package/src/automation/messages.ts +231 -0
  260. package/src/automation/record.ts +206 -0
  261. package/src/automation/types.ts +146 -0
  262. package/src/automation/when.ts +195 -0
  263. package/src/blocks.ts +249 -0
  264. package/src/browser.ts +334 -0
  265. package/src/call.ts +300 -0
  266. package/src/channelParts.ts +17 -0
  267. package/src/classes.ts +10 -0
  268. package/src/client.ts +397 -0
  269. package/src/conversationFiles.ts +54 -0
  270. package/src/credentials.ts +158 -0
  271. package/src/dev.ts +20 -0
  272. package/src/es.ts +423 -0
  273. package/src/files.ts +238 -0
  274. package/src/frames.ts +291 -0
  275. package/src/icons.tsx +49 -0
  276. package/src/index.ts +270 -0
  277. package/src/kit/AudioPlayer.tsx +129 -0
  278. package/src/kit/Button.tsx +97 -0
  279. package/src/kit/Card.tsx +47 -0
  280. package/src/kit/Chart.tsx +129 -0
  281. package/src/kit/Choices.tsx +131 -0
  282. package/src/kit/Combobox.tsx +247 -0
  283. package/src/kit/DateField.tsx +156 -0
  284. package/src/kit/Field.tsx +137 -0
  285. package/src/kit/FileField.tsx +492 -0
  286. package/src/kit/FileMark.tsx +56 -0
  287. package/src/kit/Inputs.tsx +250 -0
  288. package/src/kit/List.tsx +135 -0
  289. package/src/kit/Mark.tsx +64 -0
  290. package/src/kit/MarkStack.tsx +29 -0
  291. package/src/kit/Note.tsx +42 -0
  292. package/src/kit/Popover.tsx +121 -0
  293. package/src/kit/RangeField.tsx +53 -0
  294. package/src/kit/RatingField.tsx +62 -0
  295. package/src/kit/Stat.tsx +60 -0
  296. package/src/kit/Switch.tsx +28 -0
  297. package/src/kit/Tag.tsx +32 -0
  298. package/src/kit/Tile.tsx +74 -0
  299. package/src/kit/TimeField.tsx +157 -0
  300. package/src/kit/context.tsx +246 -0
  301. package/src/kit/dates.ts +150 -0
  302. package/src/kit/messages.ts +160 -0
  303. package/src/kit/numbers.ts +44 -0
  304. package/src/kit/options.ts +30 -0
  305. package/src/kit/uploads.ts +244 -0
  306. package/src/kit/waveform.ts +84 -0
  307. package/src/locale.ts +6 -0
  308. package/src/markdown.ts +69 -0
  309. package/src/marks.tsx +328 -0
  310. package/src/reveal.ts +52 -0
  311. package/src/stepGlyphs.ts +83 -0
  312. package/src/styles.css +6961 -0
  313. package/src/surface/Form.tsx +299 -0
  314. package/src/surface/Markdown.tsx +55 -0
  315. package/src/surface/Surface.tsx +605 -0
  316. package/src/surface/scope.ts +82 -0
  317. package/src/surface/values.ts +361 -0
  318. package/src/tint.ts +14 -0
  319. package/src/types.ts +596 -0
  320. package/src/useAgentFace.ts +47 -0
  321. package/src/useCall.ts +292 -0
  322. package/src/useConversation.ts +627 -0
  323. package/src/useDictation.ts +83 -0
  324. package/src/useLive.ts +115 -0
  325. package/src/usePolled.ts +60 -0
  326. package/src/voice/Orb.tsx +45 -0
  327. package/src/voice/StillOrb.tsx +29 -0
  328. package/src/voice/WebGLOrb.tsx +98 -0
  329. package/src/voice/fluidDots.tsx +171 -0
  330. package/src/voice/motion.ts +112 -0
  331. package/src/voice/orbs.ts +39 -0
  332. package/src/voice/useReducedMotion.ts +24 -0
  333. package/src/voice/wave.tsx +129 -0
  334. package/src/voice/webgl.ts +209 -0
  335. package/src/widget/css.d.ts +5 -0
  336. package/src/widget/element.tsx +535 -0
  337. package/src/widget/index.ts +10 -0
  338. package/src/widget/mount.ts +27 -0
  339. package/src/widget/widget.css +253 -0
  340. package/dist/SignalcoreProvider.d.ts +0 -113
  341. package/dist/SignalcoreProvider.js +0 -84
  342. package/dist/automations/AppMarks.d.ts +0 -11
  343. package/dist/automations/AppMarks.js +0 -18
  344. package/dist/automations/AutomationCard.d.ts +0 -27
  345. package/dist/automations/AutomationCard.js +0 -53
  346. package/dist/automations/AutomationsWindow.d.ts +0 -38
  347. package/dist/automations/AutomationsWindow.js +0 -57
  348. package/dist/automations/Card.d.ts +0 -46
  349. package/dist/automations/Card.js +0 -45
  350. package/dist/automations/ScheduleMarks.d.ts +0 -13
  351. package/dist/automations/ScheduleMarks.js +0 -24
  352. package/dist/automations/presentationIcons.d.ts +0 -7
  353. package/dist/automations/presentationIcons.js +0 -67
  354. package/dist/automations/schedule.d.ts +0 -25
  355. package/dist/automations/schedule.js +0 -59
  356. package/dist/automations/time.d.ts +0 -3
  357. package/dist/automations/time.js +0 -25
  358. package/dist/browser/BrowserView.d.ts +0 -43
  359. package/dist/browser/BrowserView.js +0 -94
  360. package/dist/browser/room.d.ts +0 -21
  361. package/dist/browser/room.js +0 -33
  362. package/dist/browser/useBrowserSession.d.ts +0 -17
  363. package/dist/browser/useBrowserSession.js +0 -67
  364. package/dist/builder/BuilderChat.d.ts +0 -32
  365. package/dist/builder/BuilderChat.js +0 -41
  366. package/dist/builder/BuilderTranscript.d.ts +0 -49
  367. package/dist/builder/BuilderTranscript.js +0 -62
  368. package/dist/builder/StatusLine.d.ts +0 -8
  369. package/dist/builder/StatusLine.js +0 -17
  370. package/dist/builder/answer.d.ts +0 -7
  371. package/dist/builder/answer.js +0 -8
  372. package/dist/builder/blocks.d.ts +0 -31
  373. package/dist/builder/blocks.js +0 -74
  374. package/dist/builder/items.d.ts +0 -15
  375. package/dist/builder/items.js +0 -21
  376. package/dist/builder/steps.d.ts +0 -20
  377. package/dist/builder/steps.js +0 -120
  378. package/dist/builder/time.d.ts +0 -4
  379. package/dist/builder/time.js +0 -24
  380. package/dist/builder/useBuildSession.d.ts +0 -36
  381. package/dist/builder/useBuildSession.js +0 -130
  382. package/dist/builder/workingOn.d.ts +0 -7
  383. package/dist/builder/workingOn.js +0 -15
  384. package/dist/chat/AgentChat.d.ts +0 -37
  385. package/dist/chat/AgentChat.js +0 -21
  386. package/dist/chat/ChatView.d.ts +0 -25
  387. package/dist/chat/ChatView.js +0 -34
  388. package/dist/chat/Composer.d.ts +0 -20
  389. package/dist/chat/Composer.js +0 -22
  390. package/dist/chat/MessageRow.d.ts +0 -22
  391. package/dist/chat/MessageRow.js +0 -32
  392. package/dist/chat/arrival.d.ts +0 -15
  393. package/dist/chat/arrival.js +0 -25
  394. package/dist/chat/history.d.ts +0 -24
  395. package/dist/chat/history.js +0 -45
  396. package/dist/chat/moments.d.ts +0 -25
  397. package/dist/chat/moments.js +0 -72
  398. package/dist/chat/types.d.ts +0 -12
  399. package/dist/chat/types.js +0 -1
  400. package/dist/chat/useComposer.d.ts +0 -46
  401. package/dist/chat/useComposer.js +0 -62
  402. package/dist/chat/useConversation.d.ts +0 -35
  403. package/dist/chat/useConversation.js +0 -71
  404. package/dist/chat/useStickToBottom.d.ts +0 -9
  405. package/dist/chat/useStickToBottom.js +0 -33
  406. package/dist/chat/useTurns.d.ts +0 -49
  407. package/dist/chat/useTurns.js +0 -111
  408. package/dist/classes.d.ts +0 -2
  409. package/dist/development.d.ts +0 -5
  410. package/dist/development.js +0 -8
  411. package/dist/flow/FlowWindow.d.ts +0 -42
  412. package/dist/flow/FlowWindow.js +0 -126
  413. package/dist/flow/index.d.ts +0 -16
  414. package/dist/flow/index.js +0 -16
  415. package/dist/flow/kinds.d.ts +0 -23
  416. package/dist/flow/kinds.js +0 -48
  417. package/dist/flow/map.d.ts +0 -44
  418. package/dist/flow/map.js +0 -225
  419. package/dist/flow/nodePaths.d.ts +0 -7
  420. package/dist/flow/nodePaths.js +0 -17
  421. package/dist/flow/relations.d.ts +0 -42
  422. package/dist/flow/relations.js +0 -174
  423. package/dist/host.d.ts +0 -124
  424. package/dist/host.js +0 -1
  425. package/dist/live/LiveView.d.ts +0 -28
  426. package/dist/live/LiveView.js +0 -55
  427. package/dist/live/capture.d.ts +0 -20
  428. package/dist/live/capture.js +0 -100
  429. package/dist/live/follow.d.ts +0 -26
  430. package/dist/live/follow.js +0 -72
  431. package/dist/live/paint.d.ts +0 -13
  432. package/dist/live/paint.js +0 -77
  433. package/dist/live/useLiveStream.d.ts +0 -16
  434. package/dist/live/useLiveStream.js +0 -57
  435. package/dist/look.d.ts +0 -33
  436. package/dist/look.js +0 -241
  437. package/dist/messages/en.d.ts +0 -3
  438. package/dist/messages/en.js +0 -251
  439. package/dist/messages/es.d.ts +0 -3
  440. package/dist/messages/es.js +0 -251
  441. package/dist/messages/index.d.ts +0 -16
  442. package/dist/messages/index.js +0 -33
  443. package/dist/messages/types.d.ts +0 -246
  444. package/dist/messages/types.js +0 -1
  445. package/dist/parts/Button.d.ts +0 -18
  446. package/dist/parts/Button.js +0 -17
  447. package/dist/parts/Icon.d.ts +0 -39
  448. package/dist/parts/Icon.js +0 -37
  449. package/dist/parts/Input.d.ts +0 -6
  450. package/dist/parts/Input.js +0 -11
  451. package/dist/parts/Spinner.d.ts +0 -2
  452. package/dist/parts/Spinner.js +0 -7
  453. package/dist/patterns.d.ts +0 -15
  454. package/dist/patterns.js +0 -5
  455. package/dist/presets.d.ts +0 -82
  456. package/dist/presets.js +0 -81
  457. package/dist/primitives.d.ts +0 -22
  458. package/dist/primitives.js +0 -58
  459. package/dist/request/RequestCard.d.ts +0 -34
  460. package/dist/request/RequestCard.js +0 -101
  461. package/dist/request/approval/ApprovalPreview.d.ts +0 -5
  462. package/dist/request/approval/ApprovalPreview.js +0 -27
  463. package/dist/request/approval/shapes.d.ts +0 -32
  464. package/dist/request/approval/shapes.js +0 -68
  465. package/dist/request/apps.d.ts +0 -11
  466. package/dist/request/apps.js +0 -27
  467. package/dist/request/cards.d.ts +0 -12
  468. package/dist/request/cards.js +0 -24
  469. package/dist/request/deliver.d.ts +0 -12
  470. package/dist/request/deliver.js +0 -21
  471. package/dist/request/handOver.d.ts +0 -18
  472. package/dist/request/handOver.js +0 -33
  473. package/dist/request/kinds/Approval.d.ts +0 -3
  474. package/dist/request/kinds/Approval.js +0 -9
  475. package/dist/request/kinds/Choice.d.ts +0 -3
  476. package/dist/request/kinds/Choice.js +0 -8
  477. package/dist/request/kinds/Connect.d.ts +0 -9
  478. package/dist/request/kinds/Connect.js +0 -119
  479. package/dist/request/kinds/FreeText.d.ts +0 -3
  480. package/dist/request/kinds/FreeText.js +0 -20
  481. package/dist/request/kinds/HandOver.d.ts +0 -13
  482. package/dist/request/kinds/HandOver.js +0 -20
  483. package/dist/request/kinds/Secret.d.ts +0 -7
  484. package/dist/request/kinds/Secret.js +0 -49
  485. package/dist/request/kinds/Upload.d.ts +0 -6
  486. package/dist/request/kinds/Upload.js +0 -47
  487. package/dist/request/types.d.ts +0 -83
  488. package/dist/request/types.js +0 -1
  489. package/dist/safeUrl.d.ts +0 -6
  490. package/dist/safeUrl.js +0 -8
  491. package/dist/stream/builder.d.ts +0 -176
  492. package/dist/stream/builder.js +0 -202
  493. package/dist/stream/reduce.d.ts +0 -51
  494. package/dist/stream/reduce.js +0 -58
  495. package/dist/stream/untilAborted.d.ts +0 -7
  496. package/dist/stream/untilAborted.js +0 -32
  497. package/dist/stream/useRunStream.d.ts +0 -26
  498. package/dist/stream/useRunStream.js +0 -137
  499. package/dist/styles.css +0 -2318
  500. package/dist/surface/HostNode.d.ts +0 -14
  501. package/dist/surface/HostNode.js +0 -30
  502. package/dist/surface/Node.d.ts +0 -7
  503. package/dist/surface/Node.js +0 -49
  504. package/dist/surface/SurfaceBoundary.d.ts +0 -26
  505. package/dist/surface/SurfaceBoundary.js +0 -20
  506. package/dist/surface/bindings.d.ts +0 -14
  507. package/dist/surface/bindings.js +0 -37
  508. package/dist/surface/check.d.ts +0 -27
  509. package/dist/surface/check.js +0 -102
  510. package/dist/surface/format.d.ts +0 -10
  511. package/dist/surface/format.js +0 -32
  512. package/dist/surface/hosts.d.ts +0 -6
  513. package/dist/surface/hosts.js +0 -11
  514. package/dist/surface/scene.d.ts +0 -21
  515. package/dist/surface/scene.js +0 -8
  516. package/dist/surface/templates/Browser.d.ts +0 -6
  517. package/dist/surface/templates/Browser.js +0 -11
  518. package/dist/surface/templates/Chart.d.ts +0 -6
  519. package/dist/surface/templates/Chart.js +0 -13
  520. package/dist/surface/templates/Choices.d.ts +0 -3
  521. package/dist/surface/templates/Choices.js +0 -12
  522. package/dist/surface/templates/Form.d.ts +0 -3
  523. package/dist/surface/templates/Form.js +0 -44
  524. package/dist/surface/templates/KeyValue.d.ts +0 -3
  525. package/dist/surface/templates/KeyValue.js +0 -7
  526. package/dist/surface/templates/Layout.d.ts +0 -5
  527. package/dist/surface/templates/Layout.js +0 -16
  528. package/dist/surface/templates/Live.d.ts +0 -6
  529. package/dist/surface/templates/Live.js +0 -9
  530. package/dist/surface/templates/Media.d.ts +0 -5
  531. package/dist/surface/templates/Media.js +0 -13
  532. package/dist/surface/templates/Slots.d.ts +0 -3
  533. package/dist/surface/templates/Slots.js +0 -19
  534. package/dist/surface/templates/Table.d.ts +0 -3
  535. package/dist/surface/templates/Table.js +0 -12
  536. package/dist/surface/templates/Text.d.ts +0 -4
  537. package/dist/surface/templates/Text.js +0 -15
  538. package/dist/surface/templates/index.d.ts +0 -7
  539. package/dist/surface/templates/index.js +0 -32
  540. package/dist/surface/types.d.ts +0 -68
  541. package/dist/surface/types.js +0 -6
  542. package/dist/theme.d.ts +0 -62
  543. package/dist/theme.js +0 -9
  544. package/dist/useTokens.d.ts +0 -7
  545. package/dist/useTokens.js +0 -41
  546. package/dist/voice/VoiceWindow.d.ts +0 -18
  547. package/dist/voice/VoiceWindow.js +0 -35
  548. package/dist/voice/index.d.ts +0 -13
  549. package/dist/voice/index.js +0 -12
  550. package/dist/voice/meter.d.ts +0 -16
  551. package/dist/voice/meter.js +0 -52
  552. package/dist/voice/orbColors.d.ts +0 -16
  553. package/dist/voice/orbColors.js +0 -75
  554. package/dist/voice/pushable.d.ts +0 -16
  555. package/dist/voice/pushable.js +0 -56
  556. package/dist/voice/useDictation.d.ts +0 -24
  557. package/dist/voice/useDictation.js +0 -60
  558. package/dist/voice/useReducedMotion.d.ts +0 -5
  559. package/dist/voice/useVoice.d.ts +0 -70
  560. package/dist/voice/useVoice.js +0 -197
  561. package/dist/voice/useVoicePrimitives.d.ts +0 -7
  562. package/dist/voice/useVoicePrimitives.js +0 -11
  563. package/dist/voice/voice.d.ts +0 -55
  564. package/dist/voice/voice.js +0 -9
  565. package/dist/voice/webSpeech.d.ts +0 -33
  566. package/dist/voice/webSpeech.js +0 -258
  567. package/dist/widget.js.map +0 -1
  568. package/dist/windows/AgentSpace.d.ts +0 -78
  569. package/dist/windows/AgentSpace.js +0 -135
  570. package/dist/windows/Captions.d.ts +0 -13
  571. package/dist/windows/Captions.js +0 -22
  572. package/dist/windows/Dock.d.ts +0 -37
  573. package/dist/windows/Dock.js +0 -22
  574. package/dist/windows/Journal.d.ts +0 -15
  575. package/dist/windows/Journal.js +0 -19
  576. package/dist/windows/KindMark.d.ts +0 -7
  577. package/dist/windows/KindMark.js +0 -31
  578. package/dist/windows/Pending.d.ts +0 -8
  579. package/dist/windows/Pending.js +0 -17
  580. package/dist/windows/Stage.d.ts +0 -18
  581. package/dist/windows/Stage.js +0 -21
  582. package/dist/windows/StatusLabel.d.ts +0 -9
  583. package/dist/windows/StatusLabel.js +0 -7
  584. package/dist/windows/Strip.d.ts +0 -17
  585. package/dist/windows/Strip.js +0 -42
  586. package/dist/windows/SurfaceWindow.d.ts +0 -20
  587. package/dist/windows/SurfaceWindow.js +0 -12
  588. package/dist/windows/WindowFrame.d.ts +0 -23
  589. package/dist/windows/WindowFrame.js +0 -22
  590. package/dist/windows/hearing.d.ts +0 -11
  591. package/dist/windows/hearing.js +0 -26
  592. package/dist/windows/kinds.d.ts +0 -47
  593. package/dist/windows/kinds.js +0 -28
  594. package/dist/windows/reduce.d.ts +0 -98
  595. package/dist/windows/reduce.js +0 -151
  596. package/dist/windows/registry.d.ts +0 -18
  597. package/dist/windows/registry.js +0 -61
  598. package/dist/windows/reveal.d.ts +0 -9
  599. package/dist/windows/reveal.js +0 -6
  600. package/dist/windows/space.d.ts +0 -21
  601. package/dist/windows/space.js +0 -6
  602. package/dist/windows/status.d.ts +0 -11
  603. package/dist/windows/status.js +0 -30
  604. package/dist/windows/types.d.ts +0 -15
  605. package/dist/windows/types.js +0 -1
  606. package/dist/windows/useLoaded.d.ts +0 -44
  607. package/dist/windows/useLoaded.js +0 -58
  608. package/dist/windows/useUnread.d.ts +0 -7
  609. package/dist/windows/useUnread.js +0 -21
  610. package/dist/windows/useWindows.d.ts +0 -70
  611. package/dist/windows/useWindows.js +0 -60
@@ -0,0 +1,206 @@
1
+ /**
2
+ * A run's record in words: each call as what it did ("Buscó en Gmail", "Añadió una fila a
3
+ * Citas"; a test's writes as what it would have done), gathered under the step it ran in, the same
4
+ * call made several times in a row said once with how many. Pure, so it is tested without a page.
5
+ */
6
+
7
+ import { toolName } from "../about";
8
+ import type { CallMessages, Verb } from "./messages";
9
+ import type { Automation, RunStep } from "./types";
10
+
11
+ /** The words in a tool's name that say what it does, first match wins; the rest only use it. */
12
+ const VERBS: readonly (readonly [Verb, ReadonlySet<string>])[] = [
13
+ ["send", new Set(["send", "post", "reply", "forward", "notify", "publish"])],
14
+ ["remove", new Set(["delete", "remove", "trash", "archive", "cancel"])],
15
+ ["update", new Set(["update", "edit", "patch", "modify", "move", "mark", "set", "rename"])],
16
+ ["create", new Set(["create", "add", "insert", "new", "upload", "book", "schedule", "draft"])],
17
+ [
18
+ "search",
19
+ new Set(["search", "fetch", "list", "get", "find", "read", "query", "retrieve", "lookup"]),
20
+ ],
21
+ ];
22
+
23
+ /**
24
+ * What a tool does, from its name (`GMAIL_SEND_EMAIL`, `Gmail.SendEmail`): the first of its
25
+ * words that says so; none, it only uses the app.
26
+ */
27
+ export function verbOf(tool: string): Verb {
28
+ const words = tool
29
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
30
+ .split(/[^A-Za-z0-9]+/)
31
+ .map((word) => word.toLowerCase())
32
+ .filter(Boolean);
33
+ for (const word of words) {
34
+ for (const [verb, names] of VERBS) if (names.has(word)) return verb;
35
+ }
36
+ return "use";
37
+ }
38
+
39
+ /** How a record names an app and a table: the app by its display name, the table by its title. */
40
+ export interface Names {
41
+ app: (alias: string) => string;
42
+ /** The app's logo, when the automation knows it. */
43
+ icon: (alias: string) => string | null;
44
+ table: (name: string) => string;
45
+ }
46
+
47
+ /**
48
+ * The names an automation knows: its apps' (from its steps' uses and its event's trigger) and
49
+ * its board's table; anything else by its own name, in words.
50
+ */
51
+ export function namingOf(
52
+ automation: Pick<Automation, "steps" | "trigger" | "board"> | null,
53
+ ): Names {
54
+ const apps = new Map<string, { title: string; icon: string | null }>();
55
+ const trigger = automation?.trigger;
56
+ if (trigger?.app && trigger.app_title) {
57
+ apps.set(trigger.app, { title: trigger.app_title, icon: trigger.icon });
58
+ }
59
+ for (const step of automation?.steps ?? []) {
60
+ for (const use of step.uses) {
61
+ if (use.kind === "app" && use.app !== null && use.title !== null) {
62
+ apps.set(use.app, { title: use.title, icon: use.icon });
63
+ }
64
+ }
65
+ }
66
+ const board = automation?.board ?? null;
67
+ return {
68
+ app: (alias) => apps.get(alias)?.title ?? toolName(alias),
69
+ icon: (alias) => apps.get(alias)?.icon ?? null,
70
+ table: (name) => (board !== null && board.table === name ? board.title : toolName(name)),
71
+ };
72
+ }
73
+
74
+ /** The app an app's tool call reached (`tool:gmail.GMAIL_SEND_EMAIL` is `gmail`); null for the rest. */
75
+ export function appOf(call: string): string | null {
76
+ if (!call.startsWith("tool:")) return null;
77
+ const target = call.slice(5);
78
+ const dot = target.indexOf(".");
79
+ return dot === -1 ? target : target.slice(0, dot);
80
+ }
81
+
82
+ const field = (value: unknown, name: string): string | null => {
83
+ if (typeof value !== "object" || value === null || !(name in value)) return null;
84
+ const found: unknown = (value as Record<string, unknown>)[name];
85
+ return typeof found === "string" ? found : null;
86
+ };
87
+
88
+ function hostOf(url: string | null): string {
89
+ if (url === null) return "";
90
+ try {
91
+ return new URL(url).host;
92
+ } catch {
93
+ return url;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * The channel a `send` went out on: what the record says it reached (a test's stand-in names the
99
+ * one asked for), else the one asked for; null when neither says.
100
+ */
101
+ export function sentOn(step: RunStep): string | null {
102
+ return field(step.output, "channel") ?? field(step.input, "via");
103
+ }
104
+
105
+ /** Who a `send` went to, as words can say it: a number as it was given; a contact's id, "". */
106
+ const recipientOf = (contact: string | null): string =>
107
+ contact === null || /^ctc_/.test(contact) ? "" : contact;
108
+
109
+ /** A file's name from its path, as a call names it; "" when the call didn't say. */
110
+ const nameOf = (path: string | null): string =>
111
+ (path ?? "").slice((path ?? "").lastIndexOf("/") + 1);
112
+
113
+ /** One call of a run in words; a call the package doesn't know keeps its own name. */
114
+ export function callWords(step: RunStep, words: CallMessages, names: Names): string {
115
+ const { call, would } = step;
116
+ const app = appOf(call);
117
+ if (app !== null) {
118
+ return words.tool(verbOf(call.slice(5 + app.length + 1)), names.app(app), would);
119
+ }
120
+ const table = () => names.table(field(step.input, "table") ?? "");
121
+ switch (call) {
122
+ case "ai":
123
+ return words.ai;
124
+ case "notify":
125
+ return words.notify(would);
126
+ case "send":
127
+ return words.send(sentOn(step), recipientOf(field(step.input, "contact")), would);
128
+ case "agent.start":
129
+ return words.start(would);
130
+ case "data.find":
131
+ return words.find(table());
132
+ case "data.add":
133
+ return words.add(table(), would);
134
+ case "data.update":
135
+ return words.change(table(), would);
136
+ case "http":
137
+ return words.http(hostOf(field(step.input, "url")), would);
138
+ case "files.search":
139
+ return words.files;
140
+ case "files.read":
141
+ return words.read(nameOf(field(step.input, "path")));
142
+ case "files.write":
143
+ return words.wrote(nameOf(field(step.input, "path")), would);
144
+ case "files.list":
145
+ return words.listed;
146
+ case "memory.remember":
147
+ return words.remember(would);
148
+ case "memory.recall":
149
+ return words.recall;
150
+ default:
151
+ return call;
152
+ }
153
+ }
154
+
155
+ /** One line of a step: what was done, how many times in a row, and why it failed when it did. */
156
+ export interface CallLine {
157
+ /** The first call's place in the record. */
158
+ seq: number;
159
+ text: string;
160
+ count: number;
161
+ error: string | null;
162
+ would: boolean;
163
+ /** Every call the line stands for: their inputs and outputs, for whoever reads them. */
164
+ calls: RunStep[];
165
+ }
166
+
167
+ /** The calls made in one step, in their order; `step` null for those made outside any. */
168
+ export interface StepGroup {
169
+ step: string | null;
170
+ lines: CallLine[];
171
+ }
172
+
173
+ /**
174
+ * A run's calls under the step each ran in, in the record's order: a new group each time the
175
+ * step changes, and in a group the same words in a row (none failed) as one line with a count.
176
+ */
177
+ export function groupsOf(
178
+ steps: readonly RunStep[],
179
+ words: CallMessages,
180
+ names: Names,
181
+ ): StepGroup[] {
182
+ const groups: StepGroup[] = [];
183
+ for (const step of [...steps].sort((a, b) => a.seq - b.seq)) {
184
+ let group = groups[groups.length - 1];
185
+ if (group === undefined || group.step !== step.step) {
186
+ group = { step: step.step, lines: [] };
187
+ groups.push(group);
188
+ }
189
+ const text = callWords(step, words, names);
190
+ const last = group.lines[group.lines.length - 1];
191
+ if (last !== undefined && last.text === text && last.error === null && step.error === null) {
192
+ last.count += 1;
193
+ last.calls.push(step);
194
+ } else {
195
+ group.lines.push({
196
+ seq: step.seq,
197
+ text,
198
+ count: 1,
199
+ error: step.error,
200
+ would: step.would,
201
+ calls: [step],
202
+ });
203
+ }
204
+ }
205
+ return groups;
206
+ }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * An agent's automations and their runs, as the API gives them (v3/AUTOMATIONS.md): what starts
3
+ * each one, the steps its code names, the table it moves, and every run with its record. Written
4
+ * by hand, one to one with the API's answers; times are ISO 8601 in UTC.
5
+ */
6
+
7
+ /**
8
+ * What a step uses, as the manifest reads it from the code before any run: an app, the model,
9
+ * the agent, the owner's inbox, a message to a contact on a channel (`sc.send`), a table, the web.
10
+ */
11
+ export interface Use {
12
+ kind: "app" | "ai" | "agent" | "notify" | "send" | "data" | "http";
13
+ /** An app's: the connection's name (its alias). */
14
+ app: string | null;
15
+ /** An app's: its display name. */
16
+ title: string | null;
17
+ /** An app's: its logo (https), when known. */
18
+ icon: string | null;
19
+ }
20
+
21
+ /** A step of the code (`sc.step("…")`), in the code's order, with what it uses. */
22
+ export interface Step {
23
+ name: string;
24
+ uses: Use[];
25
+ }
26
+
27
+ /** What starts an automation: a time (cron, on a zone's clock), a call to its URL, an app's event. */
28
+ export interface Trigger {
29
+ kind: "schedule" | "webhook" | "event";
30
+ /** Five-field cron. */
31
+ schedule: string | null;
32
+ /** IANA zone. */
33
+ timezone: string | null;
34
+ /** The webhook's full URL. */
35
+ url: string | null;
36
+ /** An event's app: the connection's name, its display name, its logo. */
37
+ app: string | null;
38
+ app_title: string | null;
39
+ /** The provider's event slug, and the event in words when the provider gives them. */
40
+ event: string | null;
41
+ event_title: string | null;
42
+ icon: string | null;
43
+ }
44
+
45
+ /** The table an automation moves, as counts of its rows per value of one field. */
46
+ export interface Board {
47
+ table: string;
48
+ /** The table's title. */
49
+ title: string;
50
+ /** The field the rows are counted by. */
51
+ field: string;
52
+ /** Per value, biggest first, at most 8. */
53
+ counts: { value: string; count: number }[];
54
+ }
55
+
56
+ export type RunStatus = "running" | "waiting" | "done" | "failed" | "skipped";
57
+
58
+ /** What started a run: its time, a call, an app's event, the agent in a chat, a test. */
59
+ export type RunBy = "schedule" | "webhook" | "event" | "agent" | "test";
60
+
61
+ /** One start of an automation, whatever started it. */
62
+ export interface Run {
63
+ id: string;
64
+ agent_id: string;
65
+ /** The automation's name. */
66
+ automation: string;
67
+ /** The automation's title when it ran. */
68
+ title: string;
69
+ by: RunBy;
70
+ /** Started by the agent: the conversation it was asked in. */
71
+ conversation_id: string | null;
72
+ status: RunStatus;
73
+ /** What the code returned: the run's one line. */
74
+ summary: string | null;
75
+ /** Why it failed, in words, naming the step: "Paró en «…»: …". */
76
+ error: string | null;
77
+ /** A test: what would change the world was recorded, not done. */
78
+ dry: boolean;
79
+ started_at: string;
80
+ ended_at: string | null;
81
+ tokens_in: number;
82
+ tokens_out: number;
83
+ /** The conversations it opened. */
84
+ opened: string[];
85
+ }
86
+
87
+ /** One call of a run's record, in the order it was made. */
88
+ export interface RunStep {
89
+ seq: number;
90
+ /** The `sc.step` it ran in. */
91
+ step: string | null;
92
+ /**
93
+ * `tool:<app>.<TOOL>` · `ai` · `notify` · `send` · `agent.start` · `data.find` · `data.add` ·
94
+ * `data.update` · `http` · `files.search` · `memory.remember` · `memory.recall`.
95
+ */
96
+ call: string;
97
+ /** Both trimmed. */
98
+ input: unknown;
99
+ output: unknown;
100
+ error: string | null;
101
+ ms: number;
102
+ at: string;
103
+ /** A test's write: recorded, not done. */
104
+ would: boolean;
105
+ }
106
+
107
+ /** A run with its record (`GET /runs/{id}`). */
108
+ export type RunRecord = Run & { steps: RunStep[] };
109
+
110
+ export type AutomationState = "active" | "paused" | "failing";
111
+
112
+ /** One automation: `automations/<name>.py` in the agent's folder, with its trigger and its state. */
113
+ export interface Automation {
114
+ /** Its trigger's id. */
115
+ id: string;
116
+ agent_id: string;
117
+ /** Its file's name; unique per agent. */
118
+ name: string;
119
+ title: string;
120
+ /** What it does, in the owner's words. */
121
+ summary: string;
122
+ trigger: Trigger;
123
+ on: boolean;
124
+ next_run_at: string | null;
125
+ steps: Step[];
126
+ board: Board | null;
127
+ /** `failing`: its last finished real run failed. */
128
+ state: AutomationState;
129
+ /** Its newest run, tests included. */
130
+ last_run: Run | null;
131
+ }
132
+
133
+ /** An automation with its newest runs (`GET /agents/{id}/automations/{name}`: 20; in a block: 5). */
134
+ export type AutomationView = Automation & { runs: Run[] };
135
+
136
+ /**
137
+ * A task the agent runs for one contact (`GET /agents/{id}/tasks`): set up in words in a
138
+ * conversation with them, read as an automation is (its instruction is its `summary`, its trigger
139
+ * a schedule: a cron line, or none for a task once at `next_run_at`), with its newest five runs.
140
+ */
141
+ export type Task = AutomationView & {
142
+ contact_id: string;
143
+ /** The conversation it runs in: the one it was set up in. */
144
+ conversation_id: string | null;
145
+ created_at: string;
146
+ };
@@ -0,0 +1,195 @@
1
+ /**
2
+ * When an automation runs, and when one ran, as a person says it: its trigger in a sentence
3
+ * ("Cada día laborable a las 9:00"), its next run ("próxima mañana"), the moment a run started
4
+ * ("Ayer 16:12"), how long it took. The words are the host's (`AutomationMessages`); the locale's
5
+ * code writes the times, the days and the lists. Pure, so it is tested without a page.
6
+ */
7
+
8
+ import { parseCron, type Cron } from "./cron";
9
+ import type { AutomationMessages, DayRef } from "./messages";
10
+ import type { Automation, Trigger } from "./types";
11
+
12
+ /** A time of day as the locale writes it ("9:00", "9:00 AM"), from a cron line's hour and minute. */
13
+ export function clockOf(hour: number, minute: number, code: string): string {
14
+ return new Intl.DateTimeFormat(code, {
15
+ hour: "numeric",
16
+ minute: "2-digit",
17
+ timeZone: "UTC",
18
+ }).format(new Date(Date.UTC(2026, 0, 1, hour, minute)));
19
+ }
20
+
21
+ /** A trigger in words, and whether it names the one time of day it runs (so the next needs none). */
22
+ export interface When {
23
+ text: string;
24
+ timed: boolean;
25
+ }
26
+
27
+ /** A trigger in words: its schedule as a sentence, a webhook's call, an app's event. */
28
+ export function whenOf(trigger: Trigger, words: AutomationMessages, code: string): When {
29
+ switch (trigger.kind) {
30
+ case "schedule":
31
+ return trigger.schedule === null
32
+ ? { text: words.custom, timed: false }
33
+ : scheduleOf(trigger.schedule, words, code);
34
+ case "webhook":
35
+ return { text: words.webhook, timed: false };
36
+ case "event":
37
+ return {
38
+ text: words.event(trigger.app_title ?? trigger.app, trigger.event_title),
39
+ timed: false,
40
+ };
41
+ }
42
+ }
43
+
44
+ const sorted = (values: ReadonlySet<number>): number[] => [...values].sort((a, b) => a - b);
45
+
46
+ /** Whether the values are every `step`-th one from `from` up to `to`: 0, 15, 30, 45. */
47
+ function stepOf(values: number[]): number | null {
48
+ if (values.length < 2) return null;
49
+ const step = (values[1] ?? 0) - (values[0] ?? 0);
50
+ return values.every((value, at) => value === (values[0] ?? 0) + at * step) ? step : null;
51
+ }
52
+
53
+ /** Monday first, as a week is read; Sunday is 0 in cron. */
54
+ const weekOrder = (day: number) => (day + 6) % 7;
55
+
56
+ function weekdayName(day: number, code: string): string {
57
+ // 4 January 2026 is a Sunday.
58
+ return new Intl.DateTimeFormat(code, { weekday: "long", timeZone: "UTC" }).format(
59
+ new Date(Date.UTC(2026, 0, 4 + day)),
60
+ );
61
+ }
62
+
63
+ /** The days a line runs on, in words; null for what a sentence can't say. */
64
+ function daysOf(cron: Cron, words: AutomationMessages, code: string): string | null {
65
+ if (cron.months.size !== 12) return null;
66
+ if (cron.anyDay && cron.anyWeekday) return words.daily;
67
+ if (cron.anyDay) {
68
+ const days = [...cron.weekdays].sort((a, b) => weekOrder(a) - weekOrder(b));
69
+ const key = days.join(",");
70
+ if (days.length === 7) return words.daily;
71
+ if (key === "1,2,3,4,5") return words.weekdays;
72
+ if (key === "6,0") return words.weekends;
73
+ return words.weekly(days.map((day) => weekdayName(day, code)));
74
+ }
75
+ if (cron.anyWeekday) return words.monthly(sorted(cron.days));
76
+ return null;
77
+ }
78
+
79
+ /** At most this many times are listed one by one; more read as a frequency. */
80
+ const LISTED = 4;
81
+
82
+ /** The times a line runs at in a day: listed ("a las 9:00"), or how often ("cada hora"). */
83
+ function timesOf(
84
+ cron: Cron,
85
+ words: AutomationMessages,
86
+ code: string,
87
+ ): { text: string; listed: number } | null {
88
+ const hours = sorted(cron.hours);
89
+ const minutes = sorted(cron.minutes);
90
+ const first = hours[0] ?? 0;
91
+ const last = hours[hours.length - 1] ?? 0;
92
+ if (hours.length * minutes.length <= LISTED) {
93
+ const times = hours.flatMap((hour) => minutes.map((minute) => clockOf(hour, minute, code)));
94
+ return { text: words.at(times), listed: times.length };
95
+ }
96
+ // Once in each of its hours, every few hours; or every few minutes through its hours.
97
+ const minuteStep = minutes.length === 60 ? 1 : stepOf(minutes);
98
+ const hourStep = hours.length === 24 || hours.length === 1 ? 1 : stepOf(hours);
99
+ let often: string;
100
+ if (minutes.length === 1 && hourStep !== null) {
101
+ often = words.every(hourStep, "hour");
102
+ } else if (minuteStep !== null && minutes[0] === 0 && 60 % minuteStep === 0 && hourStep === 1) {
103
+ often = words.every(minuteStep, "minute");
104
+ } else {
105
+ return null;
106
+ }
107
+ // The whole day ("cada 2 horas"), or a part of it ("cada hora de 8:00 a 18:00").
108
+ const whole = hourStep !== null && hours.length * hourStep === 24 && first < hourStep;
109
+ if (whole) return { text: often, listed: 0 };
110
+ const from = clockOf(first, minutes[0] ?? 0, code);
111
+ const to = clockOf(last, minutes[minutes.length - 1] ?? 0, code);
112
+ return { text: `${often} ${words.between(from, to)}`, listed: 0 };
113
+ }
114
+
115
+ /** A cron line as a sentence: its days, then its times or how often. */
116
+ export function scheduleOf(line: string, words: AutomationMessages, code: string): When {
117
+ const cron = parseCron(line);
118
+ const days = cron && daysOf(cron, words, code);
119
+ const times = cron && timesOf(cron, words, code);
120
+ if (!days || !times) return { text: words.custom, timed: false };
121
+ if (times.listed > 0) return { text: `${days} ${times.text}`, timed: times.listed === 1 };
122
+ return { text: days === words.daily ? times.text : words.on(times.text, days), timed: false };
123
+ }
124
+
125
+ /** A calendar day where the person is, as a count of days from the epoch's. */
126
+ const dayNumber = (moment: Date): number =>
127
+ Math.round(
128
+ (new Date(moment.getFullYear(), moment.getMonth(), moment.getDate()).getTime() -
129
+ new Date(1970, 0, 1).getTime()) /
130
+ 86_400_000,
131
+ );
132
+
133
+ /**
134
+ * A moment's day beside `now`, where the person is: today, yesterday, tomorrow, a weekday within
135
+ * the week, else its date (with its year when not this one).
136
+ */
137
+ export function dayRefOf(
138
+ moment: Date,
139
+ now: Date,
140
+ code: string,
141
+ weekday: "short" | "long" = "short",
142
+ ): DayRef {
143
+ const days = dayNumber(moment) - dayNumber(now);
144
+ if (days === 0) return { kind: "today" };
145
+ if (days === -1) return { kind: "yesterday" };
146
+ if (days === 1) return { kind: "tomorrow" };
147
+ if (Math.abs(days) < 7) {
148
+ return { kind: "weekday", name: new Intl.DateTimeFormat(code, { weekday }).format(moment) };
149
+ }
150
+ return {
151
+ kind: "date",
152
+ name: new Intl.DateTimeFormat(code, {
153
+ day: "numeric",
154
+ month: "short",
155
+ ...(moment.getFullYear() === now.getFullYear() ? {} : { year: "numeric" }),
156
+ }).format(moment),
157
+ };
158
+ }
159
+
160
+ /** A moment's time of day where the person is: "9:00". */
161
+ export const timeOf = (moment: Date, code: string): string =>
162
+ new Intl.DateTimeFormat(code, { hour: "numeric", minute: "2-digit" }).format(moment);
163
+
164
+ /** When a run started: "Hoy 9:00", "Ayer 16:12", "Lun 9:00", "3 oct 9:00". */
165
+ export function momentOf(at: Date, now: Date, words: AutomationMessages, code: string): string {
166
+ return words.moment(dayRefOf(at, now, code), timeOf(at, code));
167
+ }
168
+
169
+ /**
170
+ * The line under an automation's title: when it runs and, while it is on and has a next run,
171
+ * when that is ("Cada día laborable a las 9:00, próxima mañana"). The next run's time is said
172
+ * when the sentence doesn't already say it, and always when it is today.
173
+ */
174
+ export function lineOf(
175
+ automation: Pick<Automation, "trigger" | "on" | "next_run_at">,
176
+ now: Date,
177
+ words: AutomationMessages,
178
+ code: string,
179
+ ): string {
180
+ const when = whenOf(automation.trigger, words, code);
181
+ if (!automation.on || automation.next_run_at === null) return when.text;
182
+ const next = new Date(automation.next_run_at);
183
+ const day = dayRefOf(next, now, code, "long");
184
+ const time = when.timed && day.kind !== "today" ? null : timeOf(next, code);
185
+ return `${when.text}, ${words.next(day, time)}`;
186
+ }
187
+
188
+ /** How long a run took, once it ended. */
189
+ export function tookOf(
190
+ run: { started_at: string; ended_at: string | null },
191
+ words: AutomationMessages,
192
+ ): string | null {
193
+ if (run.ended_at === null) return null;
194
+ return words.took(Math.max(0, Date.parse(run.ended_at) - Date.parse(run.started_at)));
195
+ }