@songsid/agend 2.3.0-beta.2 → 2.3.0-beta.21

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 (502) hide show
  1. package/README.md +7 -1
  2. package/README.zh-TW.md +7 -1
  3. package/dist/agent-cli-instructions.md +9 -2
  4. package/dist/agent-cli.js +63 -2
  5. package/dist/agent-cli.js.map +1 -1
  6. package/dist/agent-endpoint.js +4 -0
  7. package/dist/agent-endpoint.js.map +1 -1
  8. package/dist/agent-file-read.d.ts +4 -1
  9. package/dist/agent-file-read.js +189 -16
  10. package/dist/agent-file-read.js.map +1 -1
  11. package/dist/agent-whats-new.d.ts +11 -0
  12. package/dist/agent-whats-new.js +29 -5
  13. package/dist/agent-whats-new.js.map +1 -1
  14. package/dist/auth-api.d.ts +30 -1
  15. package/dist/auth-api.js +45 -13
  16. package/dist/auth-api.js.map +1 -1
  17. package/dist/authority/authority-state.d.ts +38 -0
  18. package/dist/authority/authority-state.js +114 -0
  19. package/dist/authority/authority-state.js.map +1 -0
  20. package/dist/authority/session-authorizations.d.ts +43 -0
  21. package/dist/authority/session-authorizations.js +102 -0
  22. package/dist/authority/session-authorizations.js.map +1 -0
  23. package/dist/authority/web-authority.d.ts +120 -0
  24. package/dist/authority/web-authority.js +157 -0
  25. package/dist/authority/web-authority.js.map +1 -0
  26. package/dist/backend/claude-code.d.ts +2 -2
  27. package/dist/backend/claude-code.js +18 -8
  28. package/dist/backend/claude-code.js.map +1 -1
  29. package/dist/backend/codex-metadata.d.ts +8 -0
  30. package/dist/backend/codex-metadata.js +74 -17
  31. package/dist/backend/codex-metadata.js.map +1 -1
  32. package/dist/backend/codex.js +15 -2
  33. package/dist/backend/codex.js.map +1 -1
  34. package/dist/backend/credential-profile.d.ts +2 -0
  35. package/dist/backend/credential-profile.js +2 -0
  36. package/dist/backend/credential-profile.js.map +1 -1
  37. package/dist/backend/types.d.ts +6 -0
  38. package/dist/backend/types.js +15 -0
  39. package/dist/backend/types.js.map +1 -1
  40. package/dist/backend-availability.d.ts +120 -0
  41. package/dist/backend-availability.js +396 -0
  42. package/dist/backend-availability.js.map +1 -0
  43. package/dist/backend-command.d.ts +23 -3
  44. package/dist/backend-command.js +25 -4
  45. package/dist/backend-command.js.map +1 -1
  46. package/dist/bug-report-cli.d.ts +30 -0
  47. package/dist/bug-report-cli.js +138 -0
  48. package/dist/bug-report-cli.js.map +1 -0
  49. package/dist/bug-report.d.ts +47 -0
  50. package/dist/bug-report.js +136 -0
  51. package/dist/bug-report.js.map +1 -0
  52. package/dist/bundled-skills.d.ts +14 -0
  53. package/dist/bundled-skills.js +29 -0
  54. package/dist/bundled-skills.js.map +1 -0
  55. package/dist/cache-ledger.d.ts +16 -3
  56. package/dist/cache-ledger.js +33 -13
  57. package/dist/cache-ledger.js.map +1 -1
  58. package/dist/cache-service.d.ts +55 -3
  59. package/dist/cache-service.js +152 -16
  60. package/dist/cache-service.js.map +1 -1
  61. package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
  62. package/dist/channel/adapters/discord-client-retirement.js +57 -0
  63. package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
  64. package/dist/channel/adapters/discord.d.ts +9 -0
  65. package/dist/channel/adapters/discord.js +49 -4
  66. package/dist/channel/adapters/discord.js.map +1 -1
  67. package/dist/channel/mcp-tools.js +22 -11
  68. package/dist/channel/mcp-tools.js.map +1 -1
  69. package/dist/channel/types.d.ts +6 -0
  70. package/dist/classic-channel-manager.d.ts +10 -5
  71. package/dist/classic-channel-manager.js +12 -9
  72. package/dist/classic-channel-manager.js.map +1 -1
  73. package/dist/cli.js +224 -111
  74. package/dist/cli.js.map +1 -1
  75. package/dist/config-validator.d.ts +6 -0
  76. package/dist/config-validator.js +129 -3
  77. package/dist/config-validator.js.map +1 -1
  78. package/dist/config.d.ts +13 -1
  79. package/dist/config.js +14 -5
  80. package/dist/config.js.map +1 -1
  81. package/dist/cross-instance-notice.d.ts +7 -0
  82. package/dist/cross-instance-notice.js +10 -0
  83. package/dist/cross-instance-notice.js.map +1 -1
  84. package/dist/daemon.d.ts +24 -1
  85. package/dist/daemon.js +151 -19
  86. package/dist/daemon.js.map +1 -1
  87. package/dist/decision-list.d.ts +25 -0
  88. package/dist/decision-list.js +30 -0
  89. package/dist/decision-list.js.map +1 -0
  90. package/dist/delivery-outbox.d.ts +10 -0
  91. package/dist/delivery-outbox.js +17 -1
  92. package/dist/delivery-outbox.js.map +1 -1
  93. package/dist/diagnostic-redaction.d.ts +10 -0
  94. package/dist/diagnostic-redaction.js +167 -0
  95. package/dist/diagnostic-redaction.js.map +1 -0
  96. package/dist/fleet-context.d.ts +10 -0
  97. package/dist/fleet-manager.d.ts +505 -15
  98. package/dist/fleet-manager.js +1870 -204
  99. package/dist/fleet-manager.js.map +1 -1
  100. package/dist/fleet-process-handlers.d.ts +18 -0
  101. package/dist/fleet-process-handlers.js +69 -0
  102. package/dist/fleet-process-handlers.js.map +1 -0
  103. package/dist/fleet-traffic.d.ts +74 -0
  104. package/dist/fleet-traffic.js +196 -0
  105. package/dist/fleet-traffic.js.map +1 -0
  106. package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
  107. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +17 -6
  108. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
  109. package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
  110. package/dist/general-knowledge/skills/multi-channel/SKILL.md +3 -2
  111. package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
  112. package/dist/general-knowledge/skills/scheduling/SKILL.md +4 -0
  113. package/dist/general-knowledge/skills/web-appearance/SKILL.md +190 -47
  114. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +545 -0
  115. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  116. package/dist/human-delivery-receipts.d.ts +24 -1
  117. package/dist/human-delivery-receipts.js +64 -11
  118. package/dist/human-delivery-receipts.js.map +1 -1
  119. package/dist/instance-config-impact.js +7 -1
  120. package/dist/instance-config-impact.js.map +1 -1
  121. package/dist/instance-lifecycle.d.ts +10 -1
  122. package/dist/instance-lifecycle.js +79 -18
  123. package/dist/instance-lifecycle.js.map +1 -1
  124. package/dist/instance-names.d.ts +4 -0
  125. package/dist/instance-names.js +12 -0
  126. package/dist/instance-names.js.map +1 -0
  127. package/dist/instructions.d.ts +12 -1
  128. package/dist/instructions.js +13 -2
  129. package/dist/instructions.js.map +1 -1
  130. package/dist/locale.js +173 -12
  131. package/dist/locale.js.map +1 -1
  132. package/dist/log-steps.d.ts +1 -0
  133. package/dist/log-steps.js +15 -0
  134. package/dist/log-steps.js.map +1 -1
  135. package/dist/login-controller.d.ts +45 -0
  136. package/dist/login-controller.js +101 -5
  137. package/dist/login-controller.js.map +1 -1
  138. package/dist/ls-attach-resolve.d.ts +96 -0
  139. package/dist/ls-attach-resolve.js +180 -0
  140. package/dist/ls-attach-resolve.js.map +1 -0
  141. package/dist/ls-rows.d.ts +12 -0
  142. package/dist/ls-rows.js +82 -3
  143. package/dist/ls-rows.js.map +1 -1
  144. package/dist/memory-hogs.d.ts +27 -0
  145. package/dist/memory-hogs.js +124 -0
  146. package/dist/memory-hogs.js.map +1 -0
  147. package/dist/needs-you.d.ts +10 -0
  148. package/dist/needs-you.js +2 -1
  149. package/dist/needs-you.js.map +1 -1
  150. package/dist/outbound-handlers.d.ts +11 -0
  151. package/dist/outbound-handlers.js +139 -11
  152. package/dist/outbound-handlers.js.map +1 -1
  153. package/dist/outbound-schemas.d.ts +200 -4
  154. package/dist/outbound-schemas.js +124 -11
  155. package/dist/outbound-schemas.js.map +1 -1
  156. package/dist/public-web-gateway.js +17 -4
  157. package/dist/public-web-gateway.js.map +1 -1
  158. package/dist/public-web-link.d.ts +9 -0
  159. package/dist/public-web-link.js +8 -0
  160. package/dist/public-web-link.js.map +1 -1
  161. package/dist/quickstart-api.d.ts +19 -1
  162. package/dist/quickstart-api.js +94 -4
  163. package/dist/quickstart-api.js.map +1 -1
  164. package/dist/reply-buttons-controller.d.ts +4 -0
  165. package/dist/reply-buttons-controller.js +2 -2
  166. package/dist/reply-buttons-controller.js.map +1 -1
  167. package/dist/restart-progress.d.ts +80 -1
  168. package/dist/restart-progress.js +306 -21
  169. package/dist/restart-progress.js.map +1 -1
  170. package/dist/rollout-index.d.ts +5 -0
  171. package/dist/rollout-index.js +26 -5
  172. package/dist/rollout-index.js.map +1 -1
  173. package/dist/scheduler/db.d.ts +40 -13
  174. package/dist/scheduler/db.js +123 -89
  175. package/dist/scheduler/db.js.map +1 -1
  176. package/dist/scheduler/task-board-text.d.ts +26 -0
  177. package/dist/scheduler/task-board-text.js +135 -0
  178. package/dist/scheduler/task-board-text.js.map +1 -0
  179. package/dist/scheduler/task-board.d.ts +650 -0
  180. package/dist/scheduler/task-board.js +1938 -0
  181. package/dist/scheduler/task-board.js.map +1 -0
  182. package/dist/scheduler/types.d.ts +6 -1
  183. package/dist/search/search-docs.d.ts +58 -0
  184. package/dist/search/search-docs.js +63 -0
  185. package/dist/search/search-docs.js.map +1 -0
  186. package/dist/search/search-index.d.ts +141 -0
  187. package/dist/search/search-index.js +440 -0
  188. package/dist/search/search-index.js.map +1 -0
  189. package/dist/search/search-store.d.ts +122 -0
  190. package/dist/search/search-store.js +236 -0
  191. package/dist/search/search-store.js.map +1 -0
  192. package/dist/search/search-worker.d.ts +1 -0
  193. package/dist/search/search-worker.js +163 -0
  194. package/dist/search/search-worker.js.map +1 -0
  195. package/dist/service-installer.js +12 -0
  196. package/dist/service-installer.js.map +1 -1
  197. package/dist/settings-api.d.ts +23 -0
  198. package/dist/settings-api.js +164 -3
  199. package/dist/settings-api.js.map +1 -1
  200. package/dist/settings-change.js +104 -0
  201. package/dist/settings-change.js.map +1 -1
  202. package/dist/settings-confirmation.d.ts +3 -1
  203. package/dist/settings-confirmation.js +2 -0
  204. package/dist/settings-confirmation.js.map +1 -1
  205. package/dist/settings-effect.js +34 -3
  206. package/dist/settings-effect.js.map +1 -1
  207. package/dist/settings-http-confirmation.d.ts +11 -0
  208. package/dist/settings-http-confirmation.js +10 -0
  209. package/dist/settings-http-confirmation.js.map +1 -1
  210. package/dist/setup-form.d.ts +1 -1
  211. package/dist/setup-form.js +23 -7
  212. package/dist/setup-form.js.map +1 -1
  213. package/dist/spawn-gate.d.ts +1 -0
  214. package/dist/spawn-gate.js +13 -3
  215. package/dist/spawn-gate.js.map +1 -1
  216. package/dist/task-board-tool.d.ts +25 -0
  217. package/dist/task-board-tool.js +154 -0
  218. package/dist/task-board-tool.js.map +1 -0
  219. package/dist/task-board-waker.d.ts +44 -0
  220. package/dist/task-board-waker.js +128 -0
  221. package/dist/task-board-waker.js.map +1 -0
  222. package/dist/tmux-exec-helper.d.ts +94 -0
  223. package/dist/tmux-exec-helper.js +407 -0
  224. package/dist/tmux-exec-helper.js.map +1 -0
  225. package/dist/tmux-manager.d.ts +5 -0
  226. package/dist/tmux-manager.js +42 -11
  227. package/dist/tmux-manager.js.map +1 -1
  228. package/dist/tool-permissions.d.ts +0 -7
  229. package/dist/tool-permissions.js +44 -5
  230. package/dist/tool-permissions.js.map +1 -1
  231. package/dist/topic-commands.d.ts +17 -1
  232. package/dist/topic-commands.js +45 -19
  233. package/dist/topic-commands.js.map +1 -1
  234. package/dist/tunnel/cloudflared.js +37 -2
  235. package/dist/tunnel/cloudflared.js.map +1 -1
  236. package/dist/tunnel/types.d.ts +3 -1
  237. package/dist/tunnel/types.js.map +1 -1
  238. package/dist/types.d.ts +63 -1
  239. package/dist/ui/app-effects.js +90 -32
  240. package/dist/ui/backend-signin.js +297 -0
  241. package/dist/ui/chat-ambient.js +307 -0
  242. package/dist/ui/chat-effect-posters.js +8 -8
  243. package/dist/ui/chat-effects.js +110 -15
  244. package/dist/ui/chat-msg-actions.js +176 -0
  245. package/dist/ui/chat-render.js +21 -3
  246. package/dist/ui/chat-store.js +64 -12
  247. package/dist/ui/chat-strings.js +85 -8
  248. package/dist/ui/chat-thread.js +204 -21
  249. package/dist/ui/effect-trial-controller.js +13 -8
  250. package/dist/ui/effect-trial-panel.js +19 -16
  251. package/dist/ui/effects-waker.js +70 -0
  252. package/dist/ui/fleet-canvas-layout.js +117 -0
  253. package/dist/ui/fleet-canvas.js +555 -0
  254. package/dist/ui/fleet-org.js +27 -12
  255. package/dist/ui/fleet-route-scene.js +207 -0
  256. package/dist/ui/fleet-route-worker.js +21 -0
  257. package/dist/ui/fleet-route.js +88 -0
  258. package/dist/ui/fleet-task-card.js +436 -0
  259. package/dist/ui/fleet-task-common.js +448 -0
  260. package/dist/ui/fleet-tasks.js +535 -0
  261. package/dist/ui/fleet-traffic.js +359 -0
  262. package/dist/ui/fleet-usage.js +435 -0
  263. package/dist/ui/panel-chat.js +264 -66
  264. package/dist/ui/panel-details.js +2 -1
  265. package/dist/ui/panel-fleet.js +65 -83
  266. package/dist/ui/panel-needs.js +4 -2
  267. package/dist/ui/panel-settings.js +56 -11
  268. package/dist/ui/preview.js +3 -2
  269. package/dist/ui/search-dialog.js +349 -0
  270. package/dist/ui/settings-appearance.js +44 -19
  271. package/dist/ui/settings-apply.js +3 -3
  272. package/dist/ui/settings-catalog.js +92 -0
  273. package/dist/ui/settings-confirm.js +7 -2
  274. package/dist/ui/settings-dialogs.js +40 -12
  275. package/dist/ui/settings-effects.js +4 -3
  276. package/dist/ui/settings-guests.js +117 -0
  277. package/dist/ui/settings-learn.js +25 -0
  278. package/dist/ui/settings-model.js +15 -6
  279. package/dist/ui/settings-mods.js +23 -9
  280. package/dist/ui/settings-owner-effects.js +15 -13
  281. package/dist/ui/settings-strings.js +122 -42
  282. package/dist/ui/settings-web-authority.js +91 -0
  283. package/dist/ui/shared/agend-auth.js +1 -1
  284. package/dist/ui/shared/app-i18n.js +11 -2
  285. package/dist/ui/shared/app-prefs.js +17 -4
  286. package/dist/ui/shared/app-route.js +19 -1
  287. package/dist/ui/shared/app-session.js +2 -0
  288. package/dist/ui/shared/app-shell.js +174 -30
  289. package/dist/ui/shared/app-store.js +26 -1
  290. package/dist/ui/shared/app-stream.js +5 -1
  291. package/dist/ui/shared/app-themes.js +140 -7
  292. package/dist/ui/shared/app.css +705 -20
  293. package/dist/ui/shared/app.js +26 -15
  294. package/dist/ui/shared/card-strings.js +8 -0
  295. package/dist/ui/shared/effect-app-runtime.js +68 -19
  296. package/dist/ui/shared/effect-chat-runtime.js +16 -3
  297. package/dist/ui/shared/effect-frame.js +26 -7
  298. package/dist/ui/shared/effect-geometry.js +24 -9
  299. package/dist/ui/shared/effect-owner-source.js +8 -1
  300. package/dist/ui/shared/effect-policy.js +21 -7
  301. package/dist/ui/shared/effect-profiler.js +31 -9
  302. package/dist/ui/shared/effect-registry.js +97 -50
  303. package/dist/ui/shared/effect-stock-snapshot.js +9 -0
  304. package/dist/ui/shared/effect-stock-trust.js +62 -10
  305. package/dist/ui/shared/effect-trial-shadow.js +62 -0
  306. package/dist/ui/shared/effect-trial-source.js +1 -1
  307. package/dist/ui/shared/effect-trial-stage.js +54 -31
  308. package/dist/ui/shared/effect-trial.css +40 -0
  309. package/dist/ui/shared/fx-motion.js +67 -0
  310. package/dist/ui/shared/identity-card.js +100 -11
  311. package/dist/ui/shared/identity-color.js +14 -10
  312. package/dist/ui/shared/instance-nav.js +179 -23
  313. package/dist/ui/shared/owner-css.js +30 -1
  314. package/dist/ui/shared/panel-view.js +24 -4
  315. package/dist/ui/shared/tokens.css +9 -3
  316. package/dist/ui/shared/ui-icons.js +2 -0
  317. package/dist/ui/shared/ui-menu.js +20 -7
  318. package/dist/ui/shared/ui-toast.js +16 -3
  319. package/dist/ui/shared/usage-dialog.js +34 -3
  320. package/dist/ui/shared/view-strings.js +72 -0
  321. package/dist/ui/shared/web-authorize.js +198 -0
  322. package/dist/ui/web-terminal/terminal.css +4 -4
  323. package/dist/ui/web-terminal/terminal.html +1 -1
  324. package/dist/update-launch.d.ts +9 -0
  325. package/dist/update-launch.js +38 -12
  326. package/dist/update-launch.js.map +1 -1
  327. package/dist/usage/format-rich.js +6 -3
  328. package/dist/usage/format-rich.js.map +1 -1
  329. package/dist/usage/i18n-keys.d.ts +1 -1
  330. package/dist/usage/i18n-keys.js +2 -1
  331. package/dist/usage/i18n-keys.js.map +1 -1
  332. package/dist/usage/i18n.d.ts +13 -1
  333. package/dist/usage/i18n.js +29 -0
  334. package/dist/usage/i18n.js.map +1 -1
  335. package/dist/usage/providers.d.ts +81 -2
  336. package/dist/usage/providers.js +240 -38
  337. package/dist/usage/providers.js.map +1 -1
  338. package/dist/usage/usage-api.d.ts +5 -1
  339. package/dist/usage/usage-api.js +184 -58
  340. package/dist/usage/usage-api.js.map +1 -1
  341. package/dist/usage-report.d.ts +158 -0
  342. package/dist/usage-report.js +226 -0
  343. package/dist/usage-report.js.map +1 -0
  344. package/dist/usage-rollup.d.ts +51 -0
  345. package/dist/usage-rollup.js +168 -0
  346. package/dist/usage-rollup.js.map +1 -0
  347. package/dist/user-systemd.d.ts +24 -0
  348. package/dist/user-systemd.js +75 -0
  349. package/dist/user-systemd.js.map +1 -0
  350. package/dist/view-api.d.ts +39 -0
  351. package/dist/view-api.js +69 -6
  352. package/dist/view-api.js.map +1 -1
  353. package/dist/web-ambient.d.ts +72 -0
  354. package/dist/web-ambient.js +161 -0
  355. package/dist/web-ambient.js.map +1 -0
  356. package/dist/web-api.d.ts +98 -14
  357. package/dist/web-api.js +1027 -83
  358. package/dist/web-api.js.map +1 -1
  359. package/dist/web-appearance-policy.d.ts +4 -6
  360. package/dist/web-appearance-policy.js +5 -12
  361. package/dist/web-appearance-policy.js.map +1 -1
  362. package/dist/web-appearance-tools.d.ts +3 -0
  363. package/dist/web-appearance-tools.js +22 -3
  364. package/dist/web-appearance-tools.js.map +1 -1
  365. package/dist/web-appearance-view.d.ts +27 -2
  366. package/dist/web-appearance-view.js +129 -14
  367. package/dist/web-appearance-view.js.map +1 -1
  368. package/dist/web-appearance.d.ts +17 -3
  369. package/dist/web-appearance.js +85 -8
  370. package/dist/web-appearance.js.map +1 -1
  371. package/dist/web-asset-parts.d.ts +2 -2
  372. package/dist/web-asset-parts.js +3 -3
  373. package/dist/web-asset-parts.js.map +1 -1
  374. package/dist/web-auth.js +3 -1
  375. package/dist/web-auth.js.map +1 -1
  376. package/dist/web-backend-login.d.ts +130 -0
  377. package/dist/web-backend-login.js +225 -0
  378. package/dist/web-backend-login.js.map +1 -0
  379. package/dist/web-card.d.ts +14 -0
  380. package/dist/web-card.js +40 -6
  381. package/dist/web-card.js.map +1 -1
  382. package/dist/web-channel-echo.d.ts +7 -1
  383. package/dist/web-channel-echo.js +6 -2
  384. package/dist/web-channel-echo.js.map +1 -1
  385. package/dist/web-chat-history.d.ts +83 -0
  386. package/dist/web-chat-history.js +137 -5
  387. package/dist/web-chat-history.js.map +1 -1
  388. package/dist/web-commands.d.ts +6 -1
  389. package/dist/web-commands.js +1 -1
  390. package/dist/web-commands.js.map +1 -1
  391. package/dist/web-effect-bootstrap.d.ts +12 -0
  392. package/dist/web-effect-bootstrap.js +49 -0
  393. package/dist/web-effect-bootstrap.js.map +1 -0
  394. package/dist/web-effect-bundle.js +46 -1
  395. package/dist/web-effect-bundle.js.map +1 -1
  396. package/dist/web-effect-playback.d.ts +30 -0
  397. package/dist/web-effect-playback.js +71 -0
  398. package/dist/web-effect-playback.js.map +1 -0
  399. package/dist/web-effect-profiles.d.ts +4 -4
  400. package/dist/web-effect-service.d.ts +11 -4
  401. package/dist/web-effect-service.js +25 -4
  402. package/dist/web-effect-service.js.map +1 -1
  403. package/dist/web-effect-tools.d.ts +1 -0
  404. package/dist/web-effect-tools.js +4 -4
  405. package/dist/web-effect-tools.js.map +1 -1
  406. package/dist/web-effect-trials.d.ts +2 -2
  407. package/dist/web-effect-trials.js +3 -3
  408. package/dist/web-effect-trials.js.map +1 -1
  409. package/dist/web-effect-upload.js +1 -1
  410. package/dist/web-effect-upload.js.map +1 -1
  411. package/dist/web-effect-worker.d.ts +1 -1
  412. package/dist/web-effect-worker.js +2 -2
  413. package/dist/web-effect-worker.js.map +1 -1
  414. package/dist/web-effect.d.ts +1 -1
  415. package/dist/web-guest-access.d.ts +126 -0
  416. package/dist/web-guest-access.js +238 -0
  417. package/dist/web-guest-access.js.map +1 -0
  418. package/dist/web-guest-rooms.d.ts +82 -0
  419. package/dist/web-guest-rooms.js +135 -0
  420. package/dist/web-guest-rooms.js.map +1 -0
  421. package/dist/web-host-guard.d.ts +11 -0
  422. package/dist/web-host-guard.js +11 -0
  423. package/dist/web-host-guard.js.map +1 -1
  424. package/dist/web-identity-color.d.ts +1 -1
  425. package/dist/web-identity-color.js +2 -2
  426. package/dist/web-identity-color.js.map +1 -1
  427. package/dist/web-identity-palette.d.ts +1 -1
  428. package/dist/web-identity-palette.js +2 -2
  429. package/dist/web-identity-palette.js.map +1 -1
  430. package/dist/web-image-meta.d.ts +13 -0
  431. package/dist/web-image-meta.js +62 -0
  432. package/dist/web-image-meta.js.map +1 -1
  433. package/dist/web-libavoid.d.ts +14 -0
  434. package/dist/web-libavoid.js +46 -0
  435. package/dist/web-libavoid.js.map +1 -0
  436. package/dist/web-login.d.ts +47 -0
  437. package/dist/web-login.js +115 -0
  438. package/dist/web-login.js.map +1 -1
  439. package/dist/web-mod-agent.d.ts +1 -1
  440. package/dist/web-mod-agent.js +7 -5
  441. package/dist/web-mod-agent.js.map +1 -1
  442. package/dist/web-mod-bundle.d.ts +9 -1
  443. package/dist/web-mod-bundle.js +62 -3
  444. package/dist/web-mod-bundle.js.map +1 -1
  445. package/dist/web-mod-export.d.ts +9 -0
  446. package/dist/web-mod-export.js +21 -0
  447. package/dist/web-mod-export.js.map +1 -1
  448. package/dist/web-mod-store.d.ts +7 -1
  449. package/dist/web-mod-store.js +19 -6
  450. package/dist/web-mod-store.js.map +1 -1
  451. package/dist/web-owner-css-store.d.ts +44 -1
  452. package/dist/web-owner-css-store.js +70 -9
  453. package/dist/web-owner-css-store.js.map +1 -1
  454. package/dist/web-prefs.d.ts +14 -0
  455. package/dist/web-prefs.js +37 -4
  456. package/dist/web-prefs.js.map +1 -1
  457. package/dist/web-preview.d.ts +6 -2
  458. package/dist/web-preview.js +4 -2
  459. package/dist/web-preview.js.map +1 -1
  460. package/dist/web-returning-device.d.ts +41 -0
  461. package/dist/web-returning-device.js +57 -5
  462. package/dist/web-returning-device.js.map +1 -1
  463. package/dist/web-session-authorization.d.ts +132 -0
  464. package/dist/web-session-authorization.js +193 -0
  465. package/dist/web-session-authorization.js.map +1 -0
  466. package/dist/web-session.d.ts +70 -10
  467. package/dist/web-session.js +137 -22
  468. package/dist/web-session.js.map +1 -1
  469. package/dist/web-settings-patch.d.ts +49 -2
  470. package/dist/web-settings-patch.js +145 -1
  471. package/dist/web-settings-patch.js.map +1 -1
  472. package/dist/web-settings-tools.d.ts +94 -0
  473. package/dist/web-settings-tools.js +301 -0
  474. package/dist/web-settings-tools.js.map +1 -0
  475. package/dist/web-shell-routes.d.ts +1 -1
  476. package/dist/web-shell-routes.js +1 -1
  477. package/dist/web-shell-routes.js.map +1 -1
  478. package/dist/web-terminal-http.js +15 -2
  479. package/dist/web-terminal-http.js.map +1 -1
  480. package/dist/web-theme-store.d.ts +39 -0
  481. package/dist/web-theme-store.js +122 -11
  482. package/dist/web-theme-store.js.map +1 -1
  483. package/dist/web-theme.d.ts +31 -0
  484. package/dist/web-theme.js +99 -2
  485. package/dist/web-theme.js.map +1 -1
  486. package/dist/web-upload.d.ts +13 -0
  487. package/dist/web-upload.js +39 -3
  488. package/dist/web-upload.js.map +1 -1
  489. package/dist/windows-shortcuts.d.ts +78 -0
  490. package/dist/windows-shortcuts.js +203 -0
  491. package/dist/windows-shortcuts.js.map +1 -0
  492. package/dist/workflow-templates/default.md +4 -1
  493. package/dist/yaml-shared-nodes.d.ts +25 -0
  494. package/dist/yaml-shared-nodes.js +185 -0
  495. package/dist/yaml-shared-nodes.js.map +1 -0
  496. package/launcher/agend-install.cjs +553 -0
  497. package/launcher/install-admission.cjs +4 -39
  498. package/launcher/postinstall.cjs +14 -12
  499. package/package.json +4 -2
  500. package/scripts/preinstall-guard.cjs +2 -5
  501. package/templates/windows-shortcuts.ps1 +181 -0
  502. package/launcher/old-updater-note.cjs +0 -48
@@ -11,6 +11,7 @@ import { t, register } from "/assets/app-i18n.js";
11
11
  import { chatPath } from "/assets/app-route.js";
12
12
  import { Empty, Skeleton } from "/assets/ui-states.js";
13
13
  import { Icon } from "/assets/ui-icons.js";
14
+ import { modelText } from "/assets/instance-nav.js";
14
15
 
15
16
  register("org", {
16
17
  en: {
@@ -19,6 +20,7 @@ register("org", {
19
20
  missing: "Not in the fleet", thread_discord: "Discord thread", thread_telegram: "Telegram topic", openChat: "Open chat",
20
21
  classic: "ClassicBot room", empty: "No instances yet", emptyHint: "Instances and teams show here once the fleet has them.",
21
22
  noTeams: "No teams yet — define them in Fleet → Teams to group the chart.", newTab: "(opens in a new tab)",
23
+ sending: "Sending:", queuedNote: "(queued)", workingNote: "(in progress)",
22
24
  },
23
25
  "zh-TW": {
24
26
  title: "組織圖", general: "General", unteamed: "未加入 team", members: "{0} 名成員", member: "1 名成員", instances: "{0} 個 instance", instance: "1 個 instance",
@@ -26,6 +28,7 @@ register("org", {
26
28
  missing: "不在 fleet 中", thread_discord: "Discord 討論串", thread_telegram: "Telegram topic", openChat: "開啟聊天",
27
29
  classic: "ClassicBot 頻道", empty: "還沒有 instance", emptyHint: "fleet 有 instance 和 team 後會顯示在這裡。",
28
30
  noTeams: "還沒有 team——到 Fleet → Teams 定義後,組織圖會依 team 分組。", newTab: "(在新分頁開啟)",
31
+ sending: "傳送中:", queuedNote: "(排隊中)", workingNote: "(進行中)",
29
32
  },
30
33
  });
31
34
  const to = (k, ...v) => t(`org.${k}`, ...v);
@@ -83,15 +86,22 @@ export function buildOrgView(org, app) {
83
86
  return { top: general.map(node), teams, rest: { nodes: rest, counts: counts(rest) }, total: all.length, counts: counts(all) };
84
87
  }
85
88
 
86
- function Summary({ counts }) {
89
+ /** The states in a group, most pressing first, with how many are in each (the canvas's bar shows it too). */
90
+ export function OrgSummary({ counts }) {
87
91
  return html`<ul class="org-counts">${counts.map(([s, n]) => html`<li key=${s} class=${`org-count st-${s}`}>
88
92
  <span class=${`dot ${DOT[s]}`} aria-hidden="true"></span>${n} ${to(s)}</li>`)}</ul>`;
89
93
  }
90
94
 
91
- function Node({ n }) {
95
+ /** #1918: what an instance is sending now, in words — the canvas's live traffic for the list (and a screen reader). */
96
+ const KIND_WORD = { task: "delegate_task", report: "report_result", query: "request_information", update: "send_to_instance", send: "send_to_instance", broadcast: "broadcast" };
97
+ function Sending({ list }) {
98
+ return html`<p class="org-sending"><span class="muted">${to("sending")}</span> ${list.map((s, i) => html`<span key=${s.key} class=${`org-send k-${s.kind}`}>${i ? ", " : ""}${KIND_WORD[s.kind] || s.kind} → ${s.to}${s.working ? ` ${to("workingNote")}` : s.queued ? ` ${to("queuedNote")}` : ""}</span>`)}</p>`;
99
+ }
100
+
101
+ function Node({ n, sending }) {
92
102
  const alias = n.i && typeof n.i.display_name === "string" && n.i.display_name.trim() && n.i.display_name.trim() !== n.name ? n.i.display_name.trim() : "";
93
103
  const thread = n.info.thread;
94
- const model = n.i && n.i.model ? n.i.model : "";
104
+ const model = n.i && n.i.model ? modelText(n.i) : "";
95
105
  return html`<li class=${`org-node st-${n.state}`}>
96
106
  <div class="org-node-head">
97
107
  <span class=${`dot ${DOT[n.state]}`} aria-hidden="true"></span>
@@ -100,6 +110,7 @@ function Node({ n }) {
100
110
  <span class=${`org-state st-${n.state}`}>${to(n.state)}</span>
101
111
  </div>
102
112
  ${n.info.description ? html`<p class="org-desc" title=${n.info.description}>${n.info.description}</p>` : null}
113
+ ${sending && sending.length ? html`<${Sending} list=${sending} />` : null}
103
114
  ${n.i ? html`<div class="org-meta">${n.i.backend ? html`<span class="org-chip">${n.i.backend}</span>` : null}
104
115
  ${model ? html`<span class="org-model mono" title=${model}>${model}</span>` : null}
105
116
  ${n.info.classic ? html`<span class="org-chip">${to("classic")}</span>` : null}</div>` : null}
@@ -111,32 +122,36 @@ function Node({ n }) {
111
122
  </li>`;
112
123
  }
113
124
 
114
- function Team({ id, name, description, nodes, counts, icon }) {
125
+ function Team({ id, name, description, nodes, counts, icon, sending }) {
115
126
  return html`<section class="org-team" aria-labelledby=${id}>
116
127
  <header class="org-team-head">
117
128
  <h3 id=${id}><${Icon} name=${icon} size=${16} /><span>${name}</span></h3>
118
129
  ${description ? html`<p class="org-team-desc">${description}</p>` : null}
119
- <div class="org-team-sub"><span class="muted">${count("member", "members", nodes.length)}</span><${Summary} counts=${counts} /></div>
130
+ <div class="org-team-sub"><span class="muted">${count("member", "members", nodes.length)}</span><${OrgSummary} counts=${counts} /></div>
120
131
  </header>
121
- <ul class="org-nodes">${nodes.map((n) => html`<${Node} key=${n.name} n=${n} />`)}</ul>
132
+ <ul class="org-nodes">${nodes.map((n) => html`<${Node} key=${n.name} n=${n} sending=${sending && sending.get(n.name)} />`)}</ul>
122
133
  </section>`;
123
134
  }
124
135
 
125
- /** The tab's body. `org`: what /ui/org answered (the Fleet panel's loader); `app`: the app store. */
126
- export function OrgChart({ org, app }) {
136
+ /**
137
+ * The chart as a list. `org`: what /ui/org answered (the Fleet panel's loader); `app`: the app store. #1918: `bare` when
138
+ * the canvas's bar (fleet-canvas.js) already shows the count and the states; `sending` what each instance is sending
139
+ * now (name → list), null when Live is off.
140
+ */
141
+ export function OrgChart({ org, app, bare = false, sending = null }) {
127
142
  if (!app.ready) return html`<${Skeleton} lines=${4} />`;
128
143
  const view = buildOrgView(org, app);
129
144
  if (!view.total) return html`<${Empty} icon="team" title=${to("empty")} hint=${to("emptyHint")} />`;
130
145
  return html`<div class="org">
131
- <div class="list-head org-head"><span>${count("instance", "instances", view.total)}</span><${Summary} counts=${view.counts} /></div>
146
+ ${bare ? null : html`<div class="list-head org-head"><span>${count("instance", "instances", view.total)}</span><${OrgSummary} counts=${view.counts} /></div>`}
132
147
  ${view.top.length ? html`<section class="org-top" aria-labelledby="org-general">
133
148
  <h3 id="org-general" class="sr-only">${to("general")}</h3>
134
- <ul class="org-nodes">${view.top.map((n) => html`<${Node} key=${n.name} n=${n} />`)}</ul>
149
+ <ul class="org-nodes">${view.top.map((n) => html`<${Node} key=${n.name} n=${n} sending=${sending && sending.get(n.name)} />`)}</ul>
135
150
  </section>` : null}
136
151
  ${view.teams.length ? null : html`<p class="note org-note">${to("noTeams")}</p>`}
137
152
  <div class="org-teams">
138
- ${view.teams.map((team, k) => html`<${Team} key=${team.name} id=${`org-team-${k}`} icon="team" ...${team} />`)}
139
- ${view.rest.nodes.length ? html`<${Team} id="org-rest" icon="fleet" name=${to("unteamed")} description="" ...${view.rest} />` : null}
153
+ ${view.teams.map((team, k) => html`<${Team} key=${team.name} id=${`org-team-${k}`} icon="team" sending=${sending} ...${team} />`)}
154
+ ${view.rest.nodes.length ? html`<${Team} id="org-rest" icon="fleet" name=${to("unteamed")} description="" sending=${sending} ...${view.rest} />` : null}
140
155
  </div>
141
156
  </div>`;
142
157
  }
@@ -0,0 +1,207 @@
1
+ // #2182: the org canvas's traffic lines routed around the canvas, not along fixed lanes. libavoid (Adaptagrams, through
2
+ // libavoid-js 0.4.5, LGPL-2.1-or-later, an npm dependency served unmodified from /ui/vendor/) routes each line between
3
+ // fixed obstacles; this module says what the obstacles are (pure: the worker, the page and the tests share it).
4
+ //
5
+ // - Obstacles: every card (General's and the members'), a folded team's box, each open box's header band (its name and
6
+ // count are drawn over the lines) and its border as wall pieces in front of its cards. The gaps between the pieces —
7
+ // the box's padding and the gutters between its rows and columns (L.pad, L.gap: wide enough for a few lines each)
8
+ // — are the only doors, so a line crosses a border at right angles, through a door, and never runs along it.
9
+ // - Ends: pins on each card's sides (several on the long sides, one on the short), facing out; a line ends on a card,
10
+ // never on a box. A card with more lines than pins gets more, so two lines never start at one point.
11
+ // - Separation: libavoid nudges lines that share a run ROUTE.NUDGE apart; the same two ends and kind are one line (×N)
12
+ // before they get here (fleet-traffic.js).
13
+ // A route that comes back otherwise (not orthogonal, not ending on its two shapes) is not drawn: that line keeps the
14
+ // lane route (fleet-traffic.js route()).
15
+ import { OC } from "./fleet-canvas-layout.js";
16
+
17
+ /** Buffer around every obstacle, the distance nudging keeps between lines, the cost of a bend, pins on a long side. */
18
+ export const ROUTE = { BUF: 5, NUDGE: 8, SEG: 60, PINS: 4, MAX_PINS: 64, MAX_POINTS: 64, MAX_SHAPES: 600, MAX_CONNS: 120 };
19
+ /** libavoid's ConnDirFlags: the way a line leaves a pin. */
20
+ const UP = 1, DOWN = 2, LEFT = 4, RIGHT = 8;
21
+ const PINS_PER_CARD = ROUTE.PINS * 2 + 2;
22
+
23
+ /** The shape a line's end is on: a card (General's or a member's) or a folded team's box. Null: not routed here. */
24
+ function endShape(end) {
25
+ if (!end) return null;
26
+ if (end.kind === "top" || end.kind === "cell") return { key: end.key, x: end.c.x, y: end.c.y, w: end.c.w, h: end.c.h };
27
+ if (end.kind === "box" && end.b.folded) return { key: end.key, x: end.b.x, y: end.b.y, w: end.b.w, h: end.b.h };
28
+ return null;
29
+ }
30
+
31
+ /**
32
+ * The scene for layout `L` and the lines `lines` ([{ key, a, z }], a and z ends as fleet-traffic.js endOf gives them):
33
+ * { shapes: [{ x, y, w, h, pins }], conns: [{ key, a, z }], boxes: [{ x, y, w, h }] } — `pins` 0 none (an obstacle
34
+ * only), 1 the usual pins, more: that many on each long side (a busy card); every pin takes one line; `a`/`z` index
35
+ * shapes; `boxes` the open teams' outlines (separate() keeps lines off them). A line whose end is not a card or a folded box is left out (it keeps its lane).
36
+ */
37
+ export function routeScene(L, lines) {
38
+ const shapes = [], boxes = [], at = new Map();
39
+ const add = (s, pins) => { shapes.push({ x: s.x, y: s.y, w: s.w, h: s.h, pins }); return shapes.length - 1; };
40
+ for (const c of L.tops) at.set(c.key, add(c, 1));
41
+ const { NW, NH, HEAD } = OC, PAD = L.pad ?? OC.PAD, GAP = L.gap ?? OC.GAP;
42
+ for (const b of L.boxes) {
43
+ if (b.folded) { at.set(`box:${b.key}`, add(b, 1)); continue; }
44
+ if (!b.cells.length) { add(b, 0); continue; }
45
+ boxes.push({ x: b.x, y: b.y, w: b.w, h: b.h });
46
+ for (const c of b.cells) at.set(c.key, add(c, 1));
47
+ add({ x: b.x - 1, y: b.y - 1, w: b.w + 2, h: HEAD + 1 }, 0);
48
+ const lines = Math.ceil(b.cells.length / b.cols);
49
+ for (let col = 0; col < b.cols; col++) add({ x: b.x + PAD + col * (NW + GAP), y: b.y + b.h - 1, w: NW, h: 2 }, 0);
50
+ for (const x of [b.x - 1, b.x + b.w - 1]) for (let row = 0; row < lines; row++) add({ x, y: b.y + HEAD + PAD + row * (NH + GAP), w: 2, h: NH }, 0);
51
+ }
52
+ const conns = [], demand = new Map();
53
+ for (const ln of lines) {
54
+ const a = endShape(ln.a), z = endShape(ln.z);
55
+ if (!a || !z || !at.has(a.key) || !at.has(z.key) || a.key === z.key) continue;
56
+ const ia = at.get(a.key), iz = at.get(z.key);
57
+ conns.push({ key: ln.key, a: ia, z: iz });
58
+ for (const i of [ia, iz]) demand.set(i, (demand.get(i) || 0) + 1);
59
+ }
60
+ // A line each: a shape with more lines than pins gets more pins on its long sides (two lines never leave one point:
61
+ // libavoid cannot nudge apart runs that start at the same point).
62
+ for (const [i, n] of demand) if (n > PINS_PER_CARD) shapes[i].pins = Math.min(ROUTE.MAX_PINS, Math.ceil((n - 2) / 2));
63
+ return { shapes, conns, boxes };
64
+ }
65
+
66
+ /** A scene from anywhere else (the worker's message): only numbers in range, only indexes it has. Null: refused. */
67
+ export function sceneOk(s) {
68
+ if (!s || !Array.isArray(s.shapes) || !Array.isArray(s.conns) || !Array.isArray(s.boxes) || s.shapes.length > ROUTE.MAX_SHAPES || s.conns.length > ROUTE.MAX_CONNS
69
+ || s.boxes.length > ROUTE.MAX_SHAPES) return null;
70
+ const num = (v) => typeof v === "number" && Number.isFinite(v) && Math.abs(v) < 1e6;
71
+ for (const b of s.boxes) if (!b || ![b.x, b.y, b.w, b.h].every(num) || b.w <= 0 || b.h <= 0) return null;
72
+ for (const sh of s.shapes) if (!sh || ![sh.x, sh.y, sh.w, sh.h].every(num) || sh.w <= 0 || sh.h <= 0 || !Number.isInteger(sh.pins) || sh.pins < 0 || sh.pins > ROUTE.MAX_PINS) return null;
73
+ for (const c of s.conns) {
74
+ if (!c || typeof c.key !== "string" || c.key.length > 2048) return null;
75
+ for (const i of [c.a, c.z]) if (!Number.isInteger(i) || i < 0 || i >= s.shapes.length || !s.shapes[i].pins) return null;
76
+ }
77
+ return s;
78
+ }
79
+
80
+ const onEdge = (p, s) => (Math.abs(p.x - s.x) < 0.5 || Math.abs(p.x - s.x - s.w) < 0.5) && p.y >= s.y - 0.5 && p.y <= s.y + s.h + 0.5
81
+ || (Math.abs(p.y - s.y) < 0.5 || Math.abs(p.y - s.y - s.h) < 0.5) && p.x >= s.x - 0.5 && p.x <= s.x + s.w + 0.5;
82
+ /**
83
+ * A route for connection `c` of `scene`, or null: at most MAX_POINTS finite points, every segment horizontal or
84
+ * vertical, starting on its first shape's edge and ending on its second's.
85
+ */
86
+ export function routeOk(pts, scene, c) {
87
+ if (!Array.isArray(pts) || pts.length < 2 || pts.length > ROUTE.MAX_POINTS) return null;
88
+ for (const p of pts) if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return null;
89
+ for (let i = 1; i < pts.length; i++) if (pts[i].x !== pts[i - 1].x && pts[i].y !== pts[i - 1].y) return null;
90
+ if (!onEdge(pts[0], scene.shapes[c.a]) || !onEdge(pts[pts.length - 1], scene.shapes[c.z])) return null;
91
+ return pts.map((p) => ({ x: p.x, y: p.y }));
92
+ }
93
+
94
+ /** The worker's answer to a route request `m`: its scene checked (sceneOk) before libavoid sees any of it. */
95
+ export function answerRoute(A, m) {
96
+ const scene = sceneOk(m && m.scene);
97
+ return { type: "routes", id: m.id, routes: scene ? [...routeWith(A, scene)] : null };
98
+ }
99
+
100
+ /**
101
+ * libavoid nudges lines that share a run apart, but not always: in a channel shared by many lines it packs them closer
102
+ * than ROUTE.NUDGE, and lines fanning out of one card can come back on the very same run. This pass moves the middle
103
+ * segments of such lines (never a line's first or last, which end on a pin) sideways to the nearest place at least
104
+ * SEPARATE from every parallel line along them — only where the moved segment and the two it joins stay clear of
105
+ * every shape's buffer and keep their direction. What cannot move stays as libavoid left it.
106
+ */
107
+ export const SEPARATE = 6;
108
+ export function separate(routes, scene) {
109
+ const B = ROUTE.BUF - 0.5, OVER = 8;
110
+ const segsOf = (r, p) => p.slice(1).map((q, i) => ({ r, i, h: p[i].y === q.y }));
111
+ const coord = (p, s) => (s.h ? p[s.i].y : p[s.i].x);
112
+ const span = (p, s) => (s.h ? [Math.min(p[s.i].x, p[s.i + 1].x), Math.max(p[s.i].x, p[s.i + 1].x)] : [Math.min(p[s.i].y, p[s.i + 1].y), Math.max(p[s.i].y, p[s.i + 1].y)]);
113
+ /**
114
+ * A segment from a to b clear of every shape's buffer (but `own`, the card a line's first or last run starts on at its
115
+ * pin), and not along a box's border (through a door, say).
116
+ */
117
+ const clear = (a, b, own = -1) => {
118
+ const x0 = Math.min(a.x, b.x), x1 = Math.max(a.x, b.x), y0 = Math.min(a.y, b.y), y1 = Math.max(a.y, b.y), h = y0 === y1;
119
+ return scene.shapes.every((sh, k) => k === own || x1 <= sh.x - B || x0 >= sh.x + sh.w + B || y1 <= sh.y - B || y0 >= sh.y + sh.h + B)
120
+ && (scene.boxes ?? []).every((bx) => (h ? [bx.y, bx.y + bx.h].every((v) => Math.abs(v - y0) >= SEPARATE + 1) || Math.min(x1, bx.x + bx.w) - Math.max(x0, bx.x) <= 12
121
+ : [bx.x, bx.x + bx.w].every((v) => Math.abs(v - x0) >= SEPARATE + 1) || Math.min(y1, bx.y + bx.h) - Math.max(y0, bx.y) <= 12));
122
+ };
123
+ const keys = [...routes.keys()];
124
+ const connOf = new Map(scene.conns.map((c) => [c.key, c]));
125
+ const pts = keys.map((k) => routes.get(k).map((p) => ({ x: p.x, y: p.y })));
126
+ /** The segments of other lines (and this one's) parallel to segment s of line r, overlapping it, closer than SEPARATE. */
127
+ const near = (r, s, c, lo, hi) => {
128
+ const out = [];
129
+ pts.forEach((p, r2) => segsOf(r2, p).forEach((t) => {
130
+ if (t.h !== s.h || (r2 === r && t.i === s.i)) return;
131
+ const [l2, h2] = span(p, t);
132
+ if (Math.min(hi, h2) - Math.max(lo, l2) > OVER) out.push(coord(p, t));
133
+ }));
134
+ return out.filter((c2) => Math.abs(c2 - c) < SEPARATE);
135
+ };
136
+ for (let pass = 0; pass < 8; pass++) {
137
+ let moved = false;
138
+ pts.forEach((p, r) => segsOf(r, p).forEach((s) => {
139
+ if (s.i === 0 || s.i + 1 >= p.length - 1) return; // a first or last segment ends on a pin
140
+ const c = coord(p, s), [lo, hi] = span(p, s);
141
+ const close = near(r, s, c, lo, hi);
142
+ if (!close.length) return;
143
+ // Try the nearest places SEPARATE from the lines it is close to, both ways.
144
+ const tries = [...new Set(close.flatMap((c2) => [1, 2, 3, 4, 5, 6].flatMap((m) => [c2 + m * SEPARATE, c2 - m * SEPARATE])))].sort((u, v) => Math.abs(u - c) - Math.abs(v - c));
145
+ for (const c2 of tries) {
146
+ const a = { ...p[s.i] }, b = { ...p[s.i + 1] };
147
+ if (s.h) { a.y = c2; b.y = c2; } else { a.x = c2; b.x = c2; }
148
+ const prev = p[s.i - 1], next = p[s.i + 2];
149
+ // The joining segments keep their direction (never shrink through zero).
150
+ const dir = (u, v) => Math.sign(s.h ? v.y - u.y : v.x - u.x);
151
+ if (dir(prev, a) !== dir(prev, p[s.i]) || dir(b, next) !== dir(p[s.i + 1], next) || dir(prev, a) === 0 || dir(b, next) === 0) continue;
152
+ const c0 = connOf.get(keys[r]);
153
+ if (!clear(a, b) || !clear(prev, a, s.i - 1 === 0 && c0 ? c0.a : -1) || !clear(b, next, s.i + 2 === p.length - 1 && c0 ? c0.z : -1)) continue;
154
+ const old = [p[s.i], p[s.i + 1]];
155
+ p[s.i] = a; p[s.i + 1] = b;
156
+ const ok = !near(r, s, c2, lo, hi).length && [s.i - 1, s.i + 1].every((j) => { const t = { r, i: j, h: !s.h }; const [l3, h3] = span(p, t); return !near(r, t, coord(p, t), l3, h3).length; });
157
+ if (ok) { moved = true; break; }
158
+ [p[s.i], p[s.i + 1]] = old;
159
+ }
160
+ }));
161
+ if (!moved) break;
162
+ }
163
+ return new Map(keys.map((k, i) => [k, pts[i]]));
164
+ }
165
+
166
+ /**
167
+ * Route `scene` with libavoid instance `A` (libavoid-js 0.4.5's: its constants are numbers on `A`). A Map of
168
+ * connection key → points, for the routes that pass routeOk only.
169
+ */
170
+ export function routeWith(A, scene) {
171
+ const r = new A.Router(A.OrthogonalRouting);
172
+ try {
173
+ r.setRoutingParameter(A.shapeBufferDistance, ROUTE.BUF);
174
+ r.setRoutingParameter(A.idealNudgingDistance, ROUTE.NUDGE);
175
+ r.setRoutingParameter(A.segmentPenalty, ROUTE.SEG);
176
+ r.setRoutingOption(A.nudgeOrthogonalSegmentsConnectedToShapes, true);
177
+ r.setRoutingOption(A.nudgeSharedPathsWithCommonEndPoint, true);
178
+ for (const [k, v] of Object.entries(ROUTE.EXTRA_OPT ?? {})) r.setRoutingOption(A[k], v);
179
+ for (const [k, v] of Object.entries(ROUTE.EXTRA_PARAM ?? {})) r.setRoutingParameter(A[k], v);
180
+ // The router owns its shapes, pins and connectors (A.destroy(r) frees them); the points, rectangles and ends it
181
+ // copies are freed here, or the wasm heap grows with every route.
182
+ const temp = (o) => { made.push(o); return o; }, made = [];
183
+ const refs = scene.shapes.map((s) => {
184
+ const ref = new A.ShapeRef(r, temp(new A.Rectangle(temp(new A.Point(s.x, s.y)), temp(new A.Point(s.x + s.w, s.y + s.h)))));
185
+ if (s.pins) {
186
+ const k = s.pins === 1 ? ROUTE.PINS : s.pins;
187
+ const pin = (x, y, dir) => new A.ShapeConnectionPin(ref, 1, x, y, true, 0, dir).setExclusive(true);
188
+ for (let i = 1; i <= k; i++) { pin(i / (k + 1), 0, UP); pin(i / (k + 1), 1, DOWN); }
189
+ pin(0, 0.5, LEFT); pin(1, 0.5, RIGHT);
190
+ }
191
+ return ref;
192
+ });
193
+ const conns = scene.conns.map((c) => new A.ConnRef(r, temp(new A.ConnEnd(refs[c.a], 1)), temp(new A.ConnEnd(refs[c.z], 1))));
194
+ for (const o of made.splice(0)) A.destroy(o);
195
+ r.processTransaction();
196
+ const out = new Map();
197
+ scene.conns.forEach((c, i) => {
198
+ const line = conns[i].displayRoute(), pts = [];
199
+ for (let k = 0; k < line.size() && k <= ROUTE.MAX_POINTS; k++) { const p = line.get_ps(k); pts.push({ x: p.x, y: p.y }); }
200
+ const ok = routeOk(pts, scene, c);
201
+ if (ok) out.set(c.key, ok);
202
+ });
203
+ return ROUTE.SEPARATE === false ? out : separate(out, scene);
204
+ } finally {
205
+ A.destroy(r);
206
+ }
207
+ }
@@ -0,0 +1,21 @@
1
+ // #2182: the worker that routes the org canvas's traffic lines (fleet-route-scene.js says what to route). It is served
2
+ // with a policy of its own (web-host-guard.ts ROUTE_WORKER_CSP): WebAssembly may run here, as it may not on the page,
3
+ // and it may reach nothing — the page fetches libavoid.wasm and hands the bytes over; they are instantiated from a
4
+ // blob: URL. It receives numbers and answers numbers; the page checks both.
5
+ import { AvoidLib } from "/ui/vendor/libavoid-0.4.5/libavoid.js";
6
+ import { answerRoute } from "./fleet-route-scene.js";
7
+
8
+ let ready = null;
9
+ self.onmessage = (ev) => {
10
+ const m = ev.data;
11
+ if (!m || typeof m !== "object") return;
12
+ if (m.type === "init" && !ready && m.wasm instanceof ArrayBuffer) {
13
+ const url = URL.createObjectURL(new Blob([m.wasm], { type: "application/wasm" }));
14
+ ready = AvoidLib.load(url).then(() => AvoidLib.getInstance()).finally(() => URL.revokeObjectURL(url));
15
+ ready.then(() => self.postMessage({ type: "ready" }), () => self.postMessage({ type: "failed" }));
16
+ return;
17
+ }
18
+ if (m.type === "route" && ready && Number.isInteger(m.id)) {
19
+ ready.then((A) => self.postMessage(answerRoute(A, m))).catch(() => self.postMessage({ type: "routes", id: m.id, routes: null }));
20
+ }
21
+ };
@@ -0,0 +1,88 @@
1
+ // #2182: the page's side of the traffic router — one worker (fleet-route-worker.js), started the first time Live
2
+ // traffic is drawn, fed the libavoid.wasm bytes the page fetched. One scene at a time: a newer one replaces any still
3
+ // waiting (the older one's answer would be stale anyway). A worker that fails, or takes longer than TIMEOUT_MS, is
4
+ // ended; after FAIL_LIMIT failures in a row this page stops asking, and every line keeps its lane route (the caller's
5
+ // fallback for a null answer).
6
+ import { routeOk } from "./fleet-route-scene.js";
7
+
8
+ export const WORKER_URL = "/ui/js/fleet-route-worker.js";
9
+ export const WASM_URL = "/ui/vendor/libavoid-0.4.5/libavoid.wasm";
10
+ export const TIMEOUT_MS = 4000;
11
+ const FAIL_LIMIT = 2;
12
+
13
+ /**
14
+ * A client: route(scene) → a Promise of a Map (connection key → points, checked against the scene) or null (not
15
+ * routed: superseded, failed, unavailable). `deps` replaces Worker, fetch and the clock in tests.
16
+ */
17
+ export function createRouteClient(deps = {}) {
18
+ const W = deps.Worker ?? (typeof Worker === "function" ? Worker : null);
19
+ const get = deps.fetch ?? ((...a) => fetch(...a));
20
+ const timers = deps.timers ?? { set: (f, ms) => setTimeout(f, ms), clear: (t) => clearTimeout(t) };
21
+ let worker = null, wasm = null, fails = 0, nextId = 1;
22
+ let busy = null, waiting = null; // { id, scene, resolve, timer }
23
+ const end = () => { try { worker?.terminate(); } catch { /* gone */ } worker = null; };
24
+ const fail = () => {
25
+ fails++;
26
+ end();
27
+ if (busy) { timers.clear(busy.timer); busy.resolve(null); busy = null; }
28
+ if (fails >= FAIL_LIMIT && waiting) { waiting.resolve(null); waiting = null; }
29
+ pump();
30
+ };
31
+ async function start(job) {
32
+ if (!wasm) {
33
+ const res = await get(WASM_URL, { credentials: "same-origin" });
34
+ if (!res.ok) throw new Error(`libavoid.wasm: ${res.status}`);
35
+ wasm = await res.arrayBuffer();
36
+ }
37
+ // #2194 review: closed, timed out or replaced while the .wasm was on its way — start nothing (a worker made now
38
+ // would be nobody's, and a later start would make another).
39
+ if (busy !== job || worker) return;
40
+ const w = new W(WORKER_URL, { type: "module" });
41
+ w.onmessage = (ev) => {
42
+ const m = ev.data;
43
+ if (!m || typeof m !== "object" || w !== worker) return;
44
+ if (m.type === "failed") { fail(); return; }
45
+ if (m.type !== "routes" || !busy || m.id !== busy.id) return;
46
+ const { scene, resolve, timer } = busy;
47
+ busy = null;
48
+ timers.clear(timer);
49
+ if (!Array.isArray(m.routes)) { fail(); resolve(null); return; }
50
+ fails = 0;
51
+ const out = new Map();
52
+ for (const pair of m.routes.slice(0, scene.conns.length)) {
53
+ if (!Array.isArray(pair) || typeof pair[0] !== "string") continue;
54
+ const c = scene.conns.find((x) => x.key === pair[0]);
55
+ const pts = c && routeOk(pair[1], scene, c);
56
+ if (pts) out.set(c.key, pts);
57
+ }
58
+ resolve(out);
59
+ pump();
60
+ };
61
+ w.onerror = (e) => { e?.preventDefault?.(); if (w === worker) fail(); };
62
+ worker = w;
63
+ w.postMessage({ type: "init", wasm: wasm.slice(0) });
64
+ }
65
+ function pump() {
66
+ if (busy || !waiting) return;
67
+ if (fails >= FAIL_LIMIT || !W) { waiting.resolve(null); waiting = null; return; }
68
+ busy = waiting; waiting = null;
69
+ const job = busy;
70
+ job.timer = timers.set(() => { if (busy === job) fail(); }, TIMEOUT_MS);
71
+ (worker ? Promise.resolve() : start(job)).then(() => {
72
+ if (busy === job) worker.postMessage({ type: "route", id: job.id, scene: job.scene });
73
+ }, () => { if (busy === job) fail(); });
74
+ }
75
+ return {
76
+ route(scene) {
77
+ if (waiting) waiting.resolve(null);
78
+ return new Promise((resolve) => { waiting = { id: nextId++, scene, resolve, timer: null }; pump(); });
79
+ },
80
+ /** Off: the worker ended; what was waiting gets null. */
81
+ close() {
82
+ if (waiting) { waiting.resolve(null); waiting = null; }
83
+ if (busy) { timers.clear(busy.timer); busy.resolve(null); busy = null; }
84
+ end();
85
+ },
86
+ get available() { return !!W && fails < FAIL_LIMIT; },
87
+ };
88
+ }