@desplega.ai/agent-swarm 1.172.0 → 2.0.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 (525) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-fpecx1g1.js → acp-adapter-sj2g0m84.js} +18 -17
  3. package/dist/{actions-pw87a1a8.js → actions-fegk44gr.js} +65 -35
  4. package/dist/{amp-adapter-8jem2bc0.js → amp-adapter-ad8ft89x.js} +8 -7
  5. package/dist/{anthropic-messages-8ee2f22q.js → anthropic-messages-r6czkjv1.js} +7 -7
  6. package/dist/{app-wmf0m843.js → app-kfvgbvzy.js} +19 -13
  7. package/dist/{assistant-emp1e108.js → assistant-z7zdy9ja.js} +65 -38
  8. package/dist/{boot-reembed-1de4f4aj.js → boot-reembed-5c2z0mbe.js} +11 -9
  9. package/dist/{boot-reembed-4ymn9atn.js → boot-reembed-j8xa181e.js} +11 -9
  10. package/dist/{boot-scrub-sweep-adhk1s8c.js → boot-scrub-sweep-hnkn3rgt.js} +12 -10
  11. package/dist/{boot-seeds-8q637aew.js → boot-seeds-kwjq4d2z.js} +15 -13
  12. package/dist/{claude-adapter-t26cv8a4.js → claude-adapter-9vmvpvgd.js} +20 -19
  13. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-k9qae05j.js} +7 -5
  14. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-q54zx5q2.js} +6 -4
  15. package/dist/{claude-sdk-session-gsfsh662.js → claude-sdk-session-9jye6cxr.js} +12698 -11995
  16. package/dist/{cli-k46r9hmk.js → cli-03gedhng.js} +16 -14
  17. package/dist/{cli-kb4ehzx5.js → cli-1e4b6bzh.js} +7 -7
  18. package/dist/{cli-d603qf86.js → cli-29jc5q7w.js} +10 -8
  19. package/dist/cli-2m1ktfzz.js +17795 -0
  20. package/dist/{cli-8vs9trd4.js → cli-3dj8k4vy.js} +1 -1
  21. package/dist/{cli-zxm9p3x4.js → cli-3fbmmawm.js} +5 -5
  22. package/dist/{cli-gmdajfw5.js → cli-4jxm2qtz.js} +4987 -1708
  23. package/dist/{cli-tadfgd0t.js → cli-5hkm7whv.js} +33 -4
  24. package/dist/{cli-6jb2rf77.js → cli-5t4f29ez.js} +3 -3
  25. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  26. package/dist/cli-6cvfxs8r.js +47 -0
  27. package/dist/{cli-pj6x9qce.js → cli-6jyj59nb.js} +2 -2
  28. package/dist/{cli-388egyf6.js → cli-6razj6t4.js} +2 -2
  29. package/dist/{cli-qsztpfry.js → cli-74ahz61x.js} +2 -2
  30. package/dist/{cli-4nz8p1p5.js → cli-7x0g4sn1.js} +15474 -16082
  31. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  32. package/dist/{cli-81r1wjyv.js → cli-9nfx44eh.js} +1 -1
  33. package/dist/cli-9traj3dn.js +638 -0
  34. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  35. package/dist/{cli-bf7485pm.js → cli-apx87jne.js} +2 -2
  36. package/dist/{cli-ztrv9y21.js → cli-bzszjf2p.js} +3689 -1081
  37. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  38. package/dist/{cli-hsem16hb.js → cli-cgtksawx.js} +7 -4
  39. package/dist/{cli-db3m6zdt.js → cli-d2qr7aj4.js} +1 -1
  40. package/dist/{cli-1hgat6pa.js → cli-d5f9ed5c.js} +5 -5
  41. package/dist/cli-e3g5mbkz.js +776 -0
  42. package/dist/{cli-7jykv7ef.js → cli-e6mpjhed.js} +1 -1
  43. package/dist/{cli-j6kpj9az.js → cli-ee9gtz70.js} +1553 -68
  44. package/dist/{cli-e0a9sk00.js → cli-eejsgvm4.js} +4 -4
  45. package/dist/{cli-tgpfnm6r.js → cli-ef1hg1wv.js} +518 -59
  46. package/dist/cli-f527ce74.js +781 -0
  47. package/dist/{cli-ppy4nnnh.js → cli-f7kr7svz.js} +2 -2
  48. package/dist/cli-hjwmhcg1.js +10622 -0
  49. package/dist/{cli-2bw3w47j.js → cli-hnhtk6cj.js} +1 -1
  50. package/dist/{cli-ywm1azg9.js → cli-hnmhtzvh.js} +6 -4
  51. package/dist/{cli-4fnb6884.js → cli-hvqbtna4.js} +7 -1259
  52. package/dist/{cli-pstq9888.js → cli-j0pfptdp.js} +220 -103
  53. package/dist/cli-jta2eyzc.js +619 -0
  54. package/dist/{cli-esnpehf5.js → cli-k382tshb.js} +12 -13
  55. package/dist/cli-k3dp5tpf.js +263 -0
  56. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  57. package/dist/cli-kceah1eh.js +92 -0
  58. package/dist/{cli-prrt9fa0.js → cli-ke896fcf.js} +10 -10
  59. package/dist/{cli-nv4zd0b9.js → cli-kt6zqg0e.js} +6 -6
  60. package/dist/{cli-g6t9texm.js → cli-m50t4309.js} +5 -18
  61. package/dist/cli-n2wq4j7m.js +6985 -0
  62. package/dist/{cli-c2pq2rjb.js → cli-n3hzg89b.js} +46 -15
  63. package/dist/{cli-tmhsxhb8.js → cli-n5vwg842.js} +23 -6
  64. package/dist/{cli-5rv1j9ga.js → cli-ne236afy.js} +53 -7
  65. package/dist/cli-p0sg24zp.js +16 -0
  66. package/dist/{cli-d161g69q.js → cli-p1x85d2t.js} +50 -2
  67. package/dist/{cli-7pz3b7x5.js → cli-przpmdgr.js} +25 -0
  68. package/dist/{cli-g4f5pj26.js → cli-q0ke1yww.js} +111 -25
  69. package/dist/{cli-e3pmyt39.js → cli-q50942rs.js} +1 -1
  70. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  71. package/dist/{cli-gj81e47t.js → cli-r2pnvj8g.js} +2 -2
  72. package/dist/{cli-r8smj8b8.js → cli-r62a35ea.js} +19 -3
  73. package/dist/{cli-cd0hv9nh.js → cli-ra0xzggj.js} +2 -2
  74. package/dist/cli-rhs9pz33.js +294 -0
  75. package/dist/{cli-nyhb1r6x.js → cli-s2sp957d.js} +52 -29
  76. package/dist/{cli-1x7da0de.js → cli-s4setq91.js} +8 -8
  77. package/dist/{cli-xczpdp9e.js → cli-se8w6wny.js} +6 -6
  78. package/dist/cli-skxvvpap.js +10140 -0
  79. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  80. package/dist/{cli-0p3enk35.js → cli-tqaazemc.js} +9 -1
  81. package/dist/{cli-cf69s3ew.js → cli-tr4sxp68.js} +3 -3
  82. package/dist/{cli-8hzfb6xz.js → cli-tsde1hdr.js} +15 -15
  83. package/dist/{cli-cceskcvt.js → cli-txqb9s38.js} +8 -8
  84. package/dist/{cli-aspcaef3.js → cli-v1yb0rqb.js} +6 -6
  85. package/dist/{cli-j1pmc07z.js → cli-vatyhshy.js} +268 -40
  86. package/dist/{cli-04emfe2q.js → cli-vdach5a9.js} +5 -5
  87. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  88. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  89. package/dist/{cli-hwwvy36w.js → cli-wayw93nt.js} +3 -3
  90. package/dist/cli-wmgrkscj.js +23254 -0
  91. package/dist/{cli-gp1rtyvk.js → cli-z5jjpaxw.js} +29 -6
  92. package/dist/{cli-451ks6aw.js → cli-zkpks3r3.js} +1 -1
  93. package/dist/cli.js +32 -48
  94. package/dist/{codex-adapter-m4tgdysy.js → codex-adapter-y81sssk0.js} +16 -15
  95. package/dist/{codex-login-841kv5fk.js → codex-login-f2rcfpp9.js} +3 -2
  96. package/dist/{codex-session-runner-ymwzm6ea.js → codex-session-runner-8vx4j6a9.js} +16 -15
  97. package/dist/{commands-n0hshcvs.js → commands-kcpvpcrr.js} +21 -10
  98. package/dist/{controller-hq5ggpcp.js → controller-ywrmt6yd.js} +5 -4
  99. package/dist/{controllers-connect-y07cqcvy.js → controllers-connect-kwpvj3rf.js} +45 -38
  100. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-cehv1qns.js} +7 -6
  101. package/dist/{db-hkqvrdcb.js → db-k8ankj20.js} +13 -11
  102. package/dist/{db-4w7tmt1g.js → db-ww5d7jq3.js} +29 -9
  103. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-x1022qb1.js} +3 -2
  104. package/dist/{dispatcher-5sd69y14.js → dispatcher-e8gq5m68.js} +41 -34
  105. package/dist/{docker-f503k9p0.js → docker-ff6y1190.js} +3 -2
  106. package/dist/{dsh-adapter-2h8m4cab.js → dsh-adapter-3epjm3af.js} +7 -6
  107. package/dist/{e2b-66xra4az.js → e2b-8ygwhg0f.js} +4 -3
  108. package/dist/{e2b-xwhyj8cw.js → e2b-swhnpw3n.js} +4 -3
  109. package/dist/{event-bus-vjtv82gm.js → event-bus-6axnngdj.js} +3 -2
  110. package/dist/external-channel-h3359cwn.js +52 -0
  111. package/dist/{google-generative-ai-7pavrbv7.js → google-generative-ai-g8db7x0f.js} +5 -3
  112. package/dist/{google-vertex-3f1jk41f.js → google-vertex-r2692q0r.js} +5 -3
  113. package/dist/{grok-adapter-8m9yqzbq.js → grok-adapter-0d4x7gkx.js} +19 -18
  114. package/dist/{handlers-s20xr10r.js → handlers-an1gzv21.js} +44 -37
  115. package/dist/{heartbeat-3k31q4g2.js → heartbeat-6dakeb61.js} +46 -39
  116. package/dist/{hook-gdn6a2fn.js → hook-6v6cv6d5.js} +12 -24
  117. package/dist/{hook-ygwerrdh.js → hook-sa5xye4y.js} +13 -12
  118. package/dist/{http-jdteeg81.js → http-r7f3eky0.js} +1598 -279
  119. package/dist/index-52j1aja4.js +3465 -0
  120. package/dist/{index-e0snym4t.js → index-7ep4gzdk.js} +41 -34
  121. package/dist/index-9gw58n4k.js +193 -0
  122. package/dist/index-9j87mcm8.js +56305 -0
  123. package/dist/index-bsmcresk.js +79424 -0
  124. package/dist/index-mh85qhec.js +475 -0
  125. package/dist/{index-vm3bm9t7.js → index-rmpw9a8q.js} +41 -34
  126. package/dist/{index-6ksewd5y.js → index-s2wxgzr0.js} +1015 -732
  127. package/dist/{index-tsszt7g9.js → index-v1v6n7hg.js} +46 -39
  128. package/dist/index-we27kd31.js +12810 -0
  129. package/dist/{index-ffqzqgwb.js → index-zk96aq1k.js} +11 -9
  130. package/dist/{keepalive-jekc896t.js → keepalive-be9vwy5h.js} +13 -11
  131. package/dist/{lead-4k9s9szx.js → lead-0861cwrf.js} +64 -57
  132. package/dist/{maintenance-shazch4n.js → maintenance-mzzgc8bn.js} +11 -9
  133. package/dist/node-c9we95xf.js +1 -1
  134. package/dist/{node-fkajaq96.js → node-mn1zs7an.js} +2 -1
  135. package/dist/{oauth-refresh-sweep-5gb36kn8.js → oauth-refresh-sweep-cpdnfwdj.js} +12 -10
  136. package/dist/{onboard-ydrbnvww.js → onboard-fh8qs4r3.js} +11 -3
  137. package/dist/{opencode-adapter-5zh0he20.js → opencode-adapter-nm42wwj8.js} +19 -14
  138. package/dist/{otel-impl-6pf5cv86.js → otel-impl-x6c1c9g4.js} +248 -869
  139. package/dist/{pi-mono-adapter-ef9wwx9m.js → pi-mono-adapter-9n2ya240.js} +245 -107
  140. package/dist/{pricing-refresh-s52nsa5q.js → pricing-refresh-qb0rv0ap.js} +13 -11
  141. package/dist/{rbac-roles-aq3msh4e.js → rbac-roles-1gzdwbh1.js} +12 -10
  142. package/dist/{rbac-roles-q5gb5e8v.js → rbac-roles-3mraey52.js} +13 -11
  143. package/dist/{render-v2-pd1rg54q.js → render-v2-agpa45zz.js} +19 -13
  144. package/dist/{resume-gw4a2c6v.js → resume-x0ydy9s9.js} +27 -21
  145. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  146. package/dist/{setup-jda1ksdh.js → setup-as9ga0d6.js} +2 -2
  147. package/dist/{virtual-modules-b3ga2m65.js → virtual-modules-9gkxqrap.js} +7 -6
  148. package/dist/{work-objects-tb7ycye8.js → work-objects-y5g1y7ev.js} +49 -37
  149. package/dist/{worker-njjccz5d.js → worker-860c3e38.js} +64 -57
  150. package/dist/{x-qfmygqqv.js → x-m477fr0h.js} +3 -2
  151. package/openapi.json +951 -356
  152. package/package.json +12 -13
  153. package/src/apps/catalog.generated.json +1309 -53
  154. package/src/apps/page-validator.ts +93 -31
  155. package/src/azure-devops/api.ts +94 -18
  156. package/src/azure-devops/auth.ts +32 -0
  157. package/src/azure-devops/boards-sync.ts +708 -0
  158. package/src/azure-devops/handlers.ts +52 -8
  159. package/src/azure-devops/html.ts +26 -0
  160. package/src/azure-devops/index.ts +15 -0
  161. package/src/azure-devops/templates.ts +86 -0
  162. package/src/azure-devops/types.ts +65 -1
  163. package/src/be/config-refs.ts +60 -0
  164. package/src/be/db/page-versions.ts +15 -0
  165. package/src/be/db/runtime.ts +35 -8
  166. package/src/be/db/skill-name-resolution.ts +36 -0
  167. package/src/be/db/tasks/read.ts +230 -0
  168. package/src/be/db/tasks/write.ts +7 -0
  169. package/src/be/db.ts +74 -13
  170. package/src/be/migrations/213_script_connections_sql.sql +79 -0
  171. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  172. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  173. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  174. package/src/be/model-catalog-store.ts +5 -1
  175. package/src/be/model-tier-resolution.ts +12 -1
  176. package/src/be/model-validation.ts +5 -2
  177. package/src/be/models-catalog.ts +26 -1
  178. package/src/be/modelsdev-cache.json +198 -63
  179. package/src/be/modelsdev-cache.ts +9 -1
  180. package/src/be/script-connections.ts +47 -8
  181. package/src/be/script-credential-broker.ts +39 -2
  182. package/src/be/scripts/run-saved.ts +1 -0
  183. package/src/be/scripts/typecheck.ts +10 -8
  184. package/src/be/seed/runner.ts +13 -1
  185. package/src/be/seed/state-db.ts +5 -0
  186. package/src/be/seed/types.ts +6 -0
  187. package/src/be/seed-pricing.ts +19 -2
  188. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  189. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  190. package/src/be/seed-skills/bundled-files.generated.json +10 -18
  191. package/src/be/seed-skills/index.ts +107 -3
  192. package/src/be/sql-connections.ts +118 -0
  193. package/src/be/swarm-config-guard.ts +53 -0
  194. package/src/cli.tsx +0 -16
  195. package/src/commands/onboard/non-interactive.ts +4 -2
  196. package/src/commands/profile-sync.ts +5 -3
  197. package/src/commands/provider-credentials.ts +52 -6
  198. package/src/commands/runner.ts +196 -56
  199. package/src/e2b/env.ts +5 -0
  200. package/src/extensions/contract-types.generated.ts +1 -1
  201. package/src/extensions/contract.ts +45 -0
  202. package/src/extensions/dispatcher.ts +7 -0
  203. package/src/extensions/post-bridge.ts +40 -0
  204. package/src/github/handlers.ts +11 -4
  205. package/src/heartbeat/templates.ts +8 -5
  206. package/src/hooks/hook.ts +0 -26
  207. package/src/http/all-routes.ts +0 -1
  208. package/src/http/config.ts +36 -17
  209. package/src/http/core.ts +4 -0
  210. package/src/http/index.ts +14 -2
  211. package/src/http/integrations.ts +88 -1
  212. package/src/http/mcp-oauth.ts +6 -13
  213. package/src/http/mcp.ts +15 -5
  214. package/src/http/page-proxy.ts +2 -4
  215. package/src/http/pages-public.ts +6 -5
  216. package/src/http/pages.ts +5 -14
  217. package/src/http/poll.ts +28 -68
  218. package/src/http/requested-by.ts +54 -0
  219. package/src/http/route-def.ts +7 -6
  220. package/src/http/script-connection-proxy.ts +51 -4
  221. package/src/http/script-connections.ts +5 -2
  222. package/src/http/scripts.ts +1 -0
  223. package/src/http/session-cost-recompute.ts +12 -2
  224. package/src/http/session-data.ts +4 -0
  225. package/src/http/stats.ts +1 -30
  226. package/src/http/tasks.ts +61 -5
  227. package/src/http/utils.ts +14 -0
  228. package/src/http/webhooks.ts +183 -2
  229. package/src/http/x.ts +1 -0
  230. package/src/integrations/chat-sdk/adapters.ts +129 -0
  231. package/src/integrations/chat-sdk/attachments.ts +232 -0
  232. package/src/integrations/chat-sdk/background.ts +36 -0
  233. package/src/integrations/chat-sdk/commands.ts +194 -0
  234. package/src/integrations/chat-sdk/config.ts +198 -0
  235. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  236. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  237. package/src/integrations/chat-sdk/handlers.ts +28 -0
  238. package/src/integrations/chat-sdk/inbound.ts +426 -0
  239. package/src/integrations/chat-sdk/limits.ts +48 -0
  240. package/src/integrations/chat-sdk/logger.ts +81 -0
  241. package/src/integrations/chat-sdk/outbound.ts +123 -0
  242. package/src/integrations/chat-sdk/relay.ts +172 -0
  243. package/src/integrations/chat-sdk/router.ts +169 -0
  244. package/src/integrations/chat-sdk/runtime.ts +351 -0
  245. package/src/integrations/chat-sdk/schema.ts +245 -0
  246. package/src/integrations/chat-sdk/state.ts +243 -0
  247. package/src/integrations/chat-sdk/status.ts +244 -0
  248. package/src/integrations/chat-sdk/steering.ts +58 -0
  249. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  250. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  251. package/src/integrations/chat-sdk/templates.ts +16 -0
  252. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  253. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  254. package/src/integrations/chat-sdk/typing.ts +65 -0
  255. package/src/jira/adf.ts +3 -1
  256. package/src/kv-reserved-namespaces.ts +2 -0
  257. package/src/oauth/mcp-wrapper.ts +10 -6
  258. package/src/otel-impl.ts +2 -1
  259. package/src/pages/version.ts +4 -5
  260. package/src/prompts/base-prompt.ts +111 -45
  261. package/src/providers/acp-target-catalog.ts +6 -0
  262. package/src/providers/acp-targets.ts +56 -3
  263. package/src/providers/amp-adapter.ts +1 -1
  264. package/src/providers/claude-adapter.ts +27 -2
  265. package/src/providers/claude-flag-settings.ts +133 -0
  266. package/src/providers/claude-managed-adapter.ts +1 -1
  267. package/src/providers/claude-sdk-session.ts +7 -0
  268. package/src/providers/claude-session-events.ts +6 -1
  269. package/src/providers/dsh-adapter.ts +1 -1
  270. package/src/providers/opencode-adapter.ts +268 -37
  271. package/src/providers/opencode-billing.ts +86 -0
  272. package/src/providers/opencode-swarm-plugin.ts +51 -0
  273. package/src/providers/pi-mono-adapter.ts +398 -153
  274. package/src/providers/pricing-sources.md +37 -3
  275. package/src/providers/reasoning-effort.ts +27 -0
  276. package/src/providers/types.ts +11 -2
  277. package/src/rbac/legacy-policy.ts +8 -2
  278. package/src/rbac/permissions.ts +21 -0
  279. package/src/scheduler/scheduler.ts +4 -2
  280. package/src/scripts-runtime/api-client.ts +15 -1
  281. package/src/scripts-runtime/api-types.ts +9 -1
  282. package/src/scripts-runtime/ctx.ts +1 -1
  283. package/src/scripts-runtime/loader.ts +19 -7
  284. package/src/scripts-runtime/mcp-client.ts +30 -19
  285. package/src/scripts-runtime/sdk-allowlist.ts +8 -6
  286. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  287. package/src/scripts-runtime/types/stdlib.d.ts +27 -15
  288. package/src/scripts-runtime/types/swarm-extension.d.ts +63 -1
  289. package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -15
  290. package/src/server.ts +52 -18
  291. package/src/slack/actions.ts +29 -1
  292. package/src/slack/app.ts +14 -2
  293. package/src/slack/assistant.ts +36 -2
  294. package/src/slack/channel-join.ts +3 -16
  295. package/src/slack/commands.ts +9 -1
  296. package/src/slack/event-dedup.ts +1 -1
  297. package/src/slack/external-channel-egress.ts +113 -0
  298. package/src/slack/external-channel.ts +309 -0
  299. package/src/slack/handlers.ts +61 -0
  300. package/src/slack/render-v2.ts +40 -47
  301. package/src/slack/work-objects.ts +5 -0
  302. package/src/tasks/additive-buffer.ts +4 -2
  303. package/src/tasks/context-key.ts +94 -2
  304. package/src/tasks/model-pin.ts +67 -0
  305. package/src/tasks/worker-follow-up.ts +4 -31
  306. package/src/telemetry.ts +2 -1
  307. package/src/tests/acp-adapter.test.ts +42 -0
  308. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  309. package/src/tests/apps-catalog-feedback.test.ts +310 -0
  310. package/src/tests/apps-catalog-inputs.test.ts +70 -0
  311. package/src/tests/apps-catalog-table.test.ts +113 -0
  312. package/src/tests/azure-devops-boards-sync.test.ts +584 -0
  313. package/src/tests/azure-devops-html.test.ts +13 -0
  314. package/src/tests/azure-devops-webhook-malformed.test.ts +4 -0
  315. package/src/tests/base-prompt.test.ts +58 -54
  316. package/src/tests/chat-sdk-commands.test.ts +191 -0
  317. package/src/tests/chat-sdk-config.test.ts +334 -0
  318. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  319. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  320. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  321. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  322. package/src/tests/chat-sdk-harness.ts +146 -0
  323. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  324. package/src/tests/chat-sdk-relay.test.ts +470 -0
  325. package/src/tests/chat-sdk-reload.test.ts +128 -0
  326. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  327. package/src/tests/chat-sdk-slack.test.ts +268 -0
  328. package/src/tests/chat-sdk-state.test.ts +163 -0
  329. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  330. package/src/tests/chat-sdk-teams.test.ts +277 -0
  331. package/src/tests/chat-sdk-tools.test.ts +520 -0
  332. package/src/tests/chat-sdk-typing.test.ts +120 -0
  333. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  334. package/src/tests/claude-adapter-binary.test.ts +144 -0
  335. package/src/tests/claude-flag-settings.test.ts +114 -0
  336. package/src/tests/claude-managed-adapter.test.ts +1 -1
  337. package/src/tests/claude-sdk-lifecycle.test.ts +148 -1
  338. package/src/tests/claude-sdk-process.fixture.ts +7 -0
  339. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  340. package/src/tests/claude-worker-parity.test.ts +2 -7
  341. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  342. package/src/tests/config-refs.test.ts +66 -0
  343. package/src/tests/context-key.test.ts +51 -0
  344. package/src/tests/cors-allowlist.test.ts +25 -0
  345. package/src/tests/create-page-tool.test.ts +18 -0
  346. package/src/tests/credential-check.test.ts +139 -0
  347. package/src/tests/credentials.test.ts +21 -0
  348. package/src/tests/db-runtime.test.ts +61 -0
  349. package/src/tests/db-task-read-contract.test.ts +20 -0
  350. package/src/tests/db-task-write-contract.test.ts +10 -0
  351. package/src/tests/deferred-task-wake.test.ts +52 -4
  352. package/src/tests/docs-index-footprint.test.js +3 -3
  353. package/src/tests/dsh-adapter.test.ts +1 -1
  354. package/src/tests/enabled-capabilities.test.ts +20 -0
  355. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  356. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  357. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  358. package/src/tests/explicit-model-validation.test.ts +105 -1
  359. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  360. package/src/tests/extensions-post-bridge.test.ts +51 -0
  361. package/src/tests/fetch-resolved-env.test.ts +128 -0
  362. package/src/tests/fixtures/azure-boards/workitem.commented.json +89 -0
  363. package/src/tests/fixtures/azure-boards/workitem.created.json +81 -0
  364. package/src/tests/fixtures/azure-boards/workitem.deleted.json +70 -0
  365. package/src/tests/fixtures/azure-boards/workitem.restored.json +82 -0
  366. package/src/tests/fixtures/azure-boards/workitem.updated.json +130 -0
  367. package/src/tests/fixtures/catalog-feedback-definition.json.txt +860 -0
  368. package/src/tests/fixtures/catalog-inputs-definition.json.txt +910 -0
  369. package/src/tests/fixtures/catalog-table-definition.json.txt +468 -0
  370. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  371. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  372. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  373. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  374. package/src/tests/fixtures/runner-identity-refresh.ts +3 -0
  375. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  376. package/src/tests/github-handlers.test.ts +35 -0
  377. package/src/tests/harness-provider-resolution.test.ts +12 -0
  378. package/src/tests/heartbeat-checklist.test.ts +3 -2
  379. package/src/tests/hook-runtime-close.test.ts +0 -2
  380. package/src/tests/http-api-integration.test.ts +0 -25
  381. package/src/tests/migration-046-budgets.test.ts +17 -16
  382. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  383. package/src/tests/model-tier-resolution.test.ts +93 -0
  384. package/src/tests/models-catalog.test.ts +42 -1
  385. package/src/tests/node-env-runtime.test.ts +98 -0
  386. package/src/tests/openai-compatible-providers.test.ts +134 -0
  387. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  388. package/src/tests/opencode-adapter.test.ts +348 -3
  389. package/src/tests/opencode-billing.test.ts +28 -0
  390. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  391. package/src/tests/opencode-shell-env.test.ts +145 -0
  392. package/src/tests/openrouter-base-url.test.ts +101 -151
  393. package/src/tests/page-proxy.test.ts +1 -1
  394. package/src/tests/pages-browser-sdk.test.ts +76 -0
  395. package/src/tests/pages-feedback.test.ts +1 -1
  396. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  397. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  398. package/src/tests/pi-mono-adapter.test.ts +385 -5
  399. package/src/tests/pi-shell-env.test.ts +170 -0
  400. package/src/tests/prompt-template-remaining.test.ts +35 -0
  401. package/src/tests/rbac-engine.test.ts +11 -3
  402. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  403. package/src/tests/runner-identity-refresh.test.ts +3 -0
  404. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  405. package/src/tests/script-connections-sql.test.ts +675 -0
  406. package/src/tests/script-connections.test.ts +7 -1
  407. package/src/tests/scripts-http.test.ts +201 -1
  408. package/src/tests/scripts-only-gating.test.ts +2 -3
  409. package/src/tests/scripts-runtime.test.ts +58 -40
  410. package/src/tests/secret-scrubber.test.ts +86 -0
  411. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  412. package/src/tests/seed-skills-retire.test.ts +182 -0
  413. package/src/tests/send-task-requester-gate.test.ts +58 -0
  414. package/src/tests/session-cost-recompute-unit.test.ts +94 -0
  415. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  416. package/src/tests/slack-channel-join.test.ts +4 -1
  417. package/src/tests/slack-external-channel-config.test.ts +65 -0
  418. package/src/tests/slack-external-channel-egress.test.ts +237 -0
  419. package/src/tests/slack-external-channel-guard.test.ts +280 -0
  420. package/src/tests/slack-external-channel-tools.test.ts +173 -0
  421. package/src/tests/slack-external-channel.test.ts +370 -0
  422. package/src/tests/slack-render-v2.test.ts +86 -10
  423. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  424. package/src/tests/spec-base-url.test.ts +16 -1
  425. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  426. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  427. package/src/tests/swarm-diff.test.ts +1 -1
  428. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  429. package/src/tests/task-session-prompts.test.ts +132 -0
  430. package/src/tests/task-tool-manifest.test.ts +14 -0
  431. package/src/tests/task-tools-ctx.test.ts +2 -0
  432. package/src/tests/tool-annotations.test.ts +6 -6
  433. package/src/tests/ui-logs-parser.test.ts +43 -0
  434. package/src/tests/used-by-route.test.ts +6 -0
  435. package/src/tests/vendored-openapi.test.ts +16 -1
  436. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  437. package/src/tests/workflow-swarm-script.test.ts +38 -0
  438. package/src/tests/workflow-wait-filter.test.ts +5 -3
  439. package/src/tools/chat-access.ts +41 -0
  440. package/src/tools/chat-open-dm.ts +59 -0
  441. package/src/tools/chat-post.ts +74 -0
  442. package/src/tools/chat-read-thread.ts +100 -0
  443. package/src/tools/chat-reply.ts +75 -0
  444. package/src/tools/create-page.ts +3 -13
  445. package/src/tools/defer-task.ts +17 -0
  446. package/src/tools/model-catalog/index.ts +2 -1
  447. package/src/tools/register-chat-channel.ts +139 -0
  448. package/src/tools/send-task.ts +24 -0
  449. package/src/tools/skills/skill-get.ts +17 -9
  450. package/src/tools/slack-post.ts +6 -0
  451. package/src/tools/slack-read.ts +8 -0
  452. package/src/tools/slack-reply.ts +6 -0
  453. package/src/tools/slack-start-thread.ts +6 -0
  454. package/src/tools/slack-update.ts +6 -0
  455. package/src/tools/slack-upload-file.ts +6 -0
  456. package/src/tools/swarm-config/get-config.ts +2 -1
  457. package/src/tools/swarm-config/list-config.ts +2 -1
  458. package/src/tools/swarm-config/set-config.ts +16 -3
  459. package/src/tools/tool-config.ts +8 -6
  460. package/src/types.ts +12 -2
  461. package/src/utils/config-env-export.ts +74 -0
  462. package/src/utils/credentials.test.ts +92 -0
  463. package/src/utils/credentials.ts +52 -4
  464. package/src/utils/harness-provider.ts +15 -6
  465. package/src/utils/node-env.ts +24 -0
  466. package/src/utils/runtime-model-catalog.ts +11 -1
  467. package/src/utils/secret-scrubber.ts +71 -2
  468. package/src/utils/task-tool-manifest.ts +19 -2
  469. package/src/workflows/executors/swarm-script.ts +1 -0
  470. package/templates/skills/agent-browser/SKILL.md +1 -1
  471. package/templates/skills/agent-browser/content.md +1 -1
  472. package/templates/skills/apps/SKILL.md +749 -0
  473. package/templates/skills/apps/content.md +60 -22
  474. package/templates/skills/chat-sdk/config.json +14 -0
  475. package/templates/skills/chat-sdk/content.md +84 -0
  476. package/templates/skills/composio-gmail/content.md +7 -0
  477. package/templates/skills/composio-google-docs/content.md +1 -1
  478. package/templates/skills/email-domain-health/config.json +14 -0
  479. package/templates/skills/email-domain-health/content.md +131 -0
  480. package/templates/skills/kv-storage/content.md +2 -2
  481. package/templates/skills/pages/content.md +8 -10
  482. package/templates/skills/qa-loom/config.json +14 -0
  483. package/templates/skills/qa-loom/content.md +187 -0
  484. package/templates/skills/qa-loom/files/build-loom.mjs +221 -0
  485. package/templates/skills/qa-loom/files/run-qa.sh +57 -0
  486. package/templates/skills/slack-interaction/content.md +4 -0
  487. package/templates/skills/swarm-extensions/content.md +2 -0
  488. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  489. package/templates/skills/swarm-scripts/config.json +1 -1
  490. package/templates/skills/swarm-scripts/content.md +4 -2
  491. package/templates/skills/workflow-iterate/content.md +38 -0
  492. package/dist/artifact-eczsknc3.js +0 -3843
  493. package/dist/cli-9xsmdpdt.js +0 -56377
  494. package/dist/cli-bd957dgb.js +0 -153
  495. package/dist/cli-q51yprfq.js +0 -1104
  496. package/dist/cli-t1ze64h3.js +0 -811
  497. package/dist/index-9ch1n761.js +0 -1102
  498. package/src/artifact-sdk/index.ts +0 -2
  499. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  500. package/src/artifact-sdk/port.ts +0 -12
  501. package/src/artifact-sdk/server.ts +0 -183
  502. package/src/artifact-sdk/tunnel.ts +0 -19
  503. package/src/commands/artifact.ts +0 -249
  504. package/src/http/ecosystem.ts +0 -77
  505. package/src/tests/artifact-commands.test.ts +0 -92
  506. package/src/tests/artifact-sdk.test.ts +0 -793
  507. package/src/tests/register-service-security.test.ts +0 -194
  508. package/src/tools/list-services.ts +0 -107
  509. package/src/tools/register-service.ts +0 -177
  510. package/src/tools/unregister-service.ts +0 -73
  511. package/src/tools/update-service-status.ts +0 -96
  512. package/templates/skills/artifacts/config.json +0 -14
  513. package/templates/skills/artifacts/content.md +0 -344
  514. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  515. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  516. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  517. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  518. package/dist/{azure-openai-responses-ap1gwxgr.js → azure-openai-responses-ygfreq4t.js} +5 -5
  519. package/dist/{cli-5rqrj7q0.js → cli-pw7ebjdt.js} +0 -0
  520. package/dist/{openai-codex-responses-33qhkkdy.js → openai-codex-responses-3bk0grnr.js} +4 -4
  521. package/dist/{openai-completions-s88xm3ns.js → openai-completions-5d4jpakc.js} +9 -9
  522. package/dist/{openai-responses-7xd2f2e2.js → openai-responses-krb51f59.js} +5 -5
  523. package/dist/{pi-messages-xszk613n.js → pi-messages-x9gzynm1.js} +3 -3
  524. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
  525. /package/src/{artifact-sdk → pages}/feedback-overlay.ts +0 -0
@@ -17,6 +17,16 @@
17
17
  "Metric",
18
18
  "Alert",
19
19
  "Badge",
20
+ "Icon",
21
+ "Progress",
22
+ "EmptyState",
23
+ "CopyButton",
24
+ "Kbd",
25
+ "Skeleton",
26
+ "Spinner",
27
+ "AvatarStack",
28
+ "Section",
29
+ "Chips",
20
30
  "Table",
21
31
  "Form",
22
32
  "Drawer",
@@ -30,6 +40,7 @@
30
40
  "actionTypes": [
31
41
  "swarm.sdk",
32
42
  "swarm.call",
43
+ "ui.toast",
33
44
  "app.mutate",
34
45
  "app.refresh",
35
46
  "app.action",
@@ -37,7 +48,7 @@
37
48
  ],
38
49
  "components": {
39
50
  "Stack": {
40
- "description": "THE primary layout primitive — a flex column (default) or row of its children. `gap`/`padding` use the shared spacing scale (none|xs|sm|md|lg|xl, default gap md); `align` is the cross axis, `justify` the main axis, `wrap` lets a row reflow. For rows, set `collapseBelow` (sm|md|lg) so the row stacks vertically on narrow viewports — filter bars should always set it. Use this as the page root and for every section; `Container` is the legacy 2-prop alias kept for older pages.",
51
+ "description": "THE primary layout primitive — a flex column (default) or row of its children. `gap`/`padding` use the shared spacing scale (none|xs|sm|md|lg|xl, default gap md); `align` is the cross axis, `justify` the main axis, `wrap` lets a row reflow. For rows, set `collapseBelow` (sm|md|lg) so the row stacks vertically on narrow viewports — filter bars should always set it. `motion` (rise|fade|none, default rise) is the entrance of the direct children on first paint: a 200ms fade plus a 4px rise, staggered 30ms; it never replays on data polls, nested Stacks inherit the parent's entrance, and reduced-motion viewers get a short fade. Use this as the page root and for every section; `Container` is the legacy 2-prop alias kept for older pages.",
41
52
  "slots": ["default"],
42
53
  "props": {
43
54
  "$schema": "http://json-schema.org/draft-07/schema#",
@@ -69,6 +80,10 @@
69
80
  "collapseBelow": {
70
81
  "type": "string",
71
82
  "enum": ["sm", "md", "lg"]
83
+ },
84
+ "motion": {
85
+ "type": "string",
86
+ "enum": ["rise", "fade", "none"]
72
87
  }
73
88
  },
74
89
  "additionalProperties": false
@@ -172,7 +187,7 @@
172
187
  }
173
188
  },
174
189
  "Tabs": {
175
- "description": "Tabbed sections. POSITIONAL children: children[i] is the body of tabs[i], so declare exactly as many children as tabs, in the same order. Only the active tab is visible but every child stays mounted, so polled Tables in background tabs keep their data warm. The active key is mirrored into state at `/ui/<id>/tab`, so other components can bind `{ \"$state\": \"/ui/<id>/tab\" }`. `defaultTab` picks the initial key (defaults to the first tab).",
190
+ "description": "Tabbed sections. POSITIONAL children: children[i] is the body of tabs[i], so declare exactly as many children as tabs, in the same order. Only the active tab is visible but every child stays mounted, so polled Tables in background tabs keep their data warm. The active key is mirrored into state at `/ui/<id>/tab`, so other components can bind `{ \"$state\": \"/ui/<id>/tab\" }`. `defaultTab` picks the initial key (defaults to the first tab). Tab entries take an optional `icon` and `count` (a small count pill; a literal or a bound number). `variant: \"segmented\"` renders a compact segmented control instead of the tab strip (same state and warm panels).",
176
191
  "slots": ["default"],
177
192
  "props": {
178
193
  "$schema": "http://json-schema.org/draft-07/schema#",
@@ -192,6 +207,54 @@
192
207
  },
193
208
  "label": {
194
209
  "type": "string"
210
+ },
211
+ "icon": {
212
+ "type": "string",
213
+ "enum": [
214
+ "plus",
215
+ "refresh-cw",
216
+ "search",
217
+ "filter",
218
+ "download",
219
+ "upload",
220
+ "external-link",
221
+ "copy",
222
+ "check",
223
+ "x",
224
+ "trash-2",
225
+ "pencil",
226
+ "eye",
227
+ "calendar",
228
+ "clock",
229
+ "user",
230
+ "users",
231
+ "bot",
232
+ "git-pull-request",
233
+ "git-branch",
234
+ "github",
235
+ "slack",
236
+ "mail",
237
+ "link",
238
+ "file-text",
239
+ "folder",
240
+ "database",
241
+ "zap",
242
+ "sparkles",
243
+ "flag",
244
+ "star",
245
+ "tag",
246
+ "alert-triangle",
247
+ "info",
248
+ "circle-check",
249
+ "trending-up",
250
+ "trending-down",
251
+ "dollar-sign",
252
+ "activity",
253
+ "rocket"
254
+ ]
255
+ },
256
+ "count": {
257
+ "type": "number"
195
258
  }
196
259
  },
197
260
  "required": ["key"],
@@ -200,6 +263,10 @@
200
263
  },
201
264
  "defaultTab": {
202
265
  "type": "string"
266
+ },
267
+ "variant": {
268
+ "type": "string",
269
+ "enum": ["line", "segmented"]
203
270
  }
204
271
  },
205
272
  "required": ["id", "tabs"],
@@ -293,7 +360,7 @@
293
360
  }
294
361
  },
295
362
  "SearchInput": {
296
- "description": "Free-text search box. Writes the debounced (~200ms) query into state at `/ui/<id>/value`; bind it into a Table with `\"search\": { \"$state\": \"/ui/<id>/value\" }`. Purely client-side — it filters rows the page already polled, it does not re-run the query.",
363
+ "description": "Free-text search box. Writes the debounced (~200ms) query into state at `/ui/<id>/value`; bind it into a Table with `\"search\": { \"$state\": \"/ui/<id>/value\" }`. Purely client-side — it filters rows the page already polled, it does not re-run the query. `shortcut` (usually `\"/\"`) shows a keycap hint and focuses the field when pressed outside a text field.",
297
364
  "props": {
298
365
  "$schema": "http://json-schema.org/draft-07/schema#",
299
366
  "type": "object",
@@ -306,6 +373,11 @@
306
373
  },
307
374
  "label": {
308
375
  "type": "string"
376
+ },
377
+ "shortcut": {
378
+ "type": "string",
379
+ "minLength": 1,
380
+ "maxLength": 12
309
381
  }
310
382
  },
311
383
  "required": ["id"],
@@ -313,7 +385,7 @@
313
385
  }
314
386
  },
315
387
  "Select": {
316
- "description": "Dropdown filter/picker. `options` are plain strings or `{ value, label }` objects. Writes the chosen value into state at `/ui/<id>/value` (clearing writes `null`); bind it into a Table with `\"filters\": { \"<column>\": { \"$state\": \"/ui/<id>/value\" } }`. `clearable` (default true) shows a clear button.",
388
+ "description": "Dropdown filter/picker. `options` are plain strings or `{ value, label?, icon?, hint? }` objects. Writes the chosen value into state at `/ui/<id>/value` (clearing writes `null`); bind it into a Table with `\"filters\": { \"<column>\": { \"$state\": \"/ui/<id>/value\" } }`. `clearable` (default true) shows a clear button. `searchable` adds a type-to-filter field (on by default past 8 options; `searchPlaceholder` sets its hint). `multiple` picks several: the value is a string array (empty = nothing picked), which a Table filter reads as \"cell is one of\".",
317
389
  "props": {
318
390
  "$schema": "http://json-schema.org/draft-07/schema#",
319
391
  "type": "object",
@@ -337,6 +409,54 @@
337
409
  },
338
410
  "label": {
339
411
  "type": "string"
412
+ },
413
+ "icon": {
414
+ "type": "string",
415
+ "enum": [
416
+ "plus",
417
+ "refresh-cw",
418
+ "search",
419
+ "filter",
420
+ "download",
421
+ "upload",
422
+ "external-link",
423
+ "copy",
424
+ "check",
425
+ "x",
426
+ "trash-2",
427
+ "pencil",
428
+ "eye",
429
+ "calendar",
430
+ "clock",
431
+ "user",
432
+ "users",
433
+ "bot",
434
+ "git-pull-request",
435
+ "git-branch",
436
+ "github",
437
+ "slack",
438
+ "mail",
439
+ "link",
440
+ "file-text",
441
+ "folder",
442
+ "database",
443
+ "zap",
444
+ "sparkles",
445
+ "flag",
446
+ "star",
447
+ "tag",
448
+ "alert-triangle",
449
+ "info",
450
+ "circle-check",
451
+ "trending-up",
452
+ "trending-down",
453
+ "dollar-sign",
454
+ "activity",
455
+ "rocket"
456
+ ]
457
+ },
458
+ "hint": {
459
+ "type": "string"
340
460
  }
341
461
  },
342
462
  "required": ["value"],
@@ -353,6 +473,15 @@
353
473
  },
354
474
  "clearable": {
355
475
  "type": "boolean"
476
+ },
477
+ "searchable": {
478
+ "type": "boolean"
479
+ },
480
+ "multiple": {
481
+ "type": "boolean"
482
+ },
483
+ "searchPlaceholder": {
484
+ "type": "string"
356
485
  }
357
486
  },
358
487
  "required": ["id", "options"],
@@ -360,7 +489,7 @@
360
489
  }
361
490
  },
362
491
  "Button": {
363
- "description": "Interactive button. Wire to actions via `on.press`. `variant: \"destructive-outline\"` is the canonical red-outlined destructive look (standalone deletes should use it, not solid red). `disabled` accepts a constant or a bound boolean; `busyWith: \"<actionName>\"` disables the button and shows a spinner while that custom action is running.",
492
+ "description": "Interactive button. Wire to actions via `on.press`. `variant: \"destructive-outline\"` is the canonical red-outlined destructive look (standalone deletes should use it, not solid red). `disabled` accepts a constant or a bound boolean; `busyWith: \"<actionName>\"` swaps the label for a spinner (presses ignored) while that custom action is running, then shows a check plus `successLabel` for ~1.5s when it finishes ok. `icon` + `iconPosition` (start|end) add an icon from the curated set; `size` sm|default|lg. `shortcut` (one key, e.g. `\"n\"`) shows a keycap inside the button and presses it from anywhere on the page (not while typing in a field, not with Ctrl/Cmd/Alt). `hint` is a hover tooltip.",
364
493
  "props": {
365
494
  "$schema": "http://json-schema.org/draft-07/schema#",
366
495
  "type": "object",
@@ -384,6 +513,70 @@
384
513
  },
385
514
  "busyWith": {
386
515
  "type": "string"
516
+ },
517
+ "icon": {
518
+ "type": "string",
519
+ "enum": [
520
+ "plus",
521
+ "refresh-cw",
522
+ "search",
523
+ "filter",
524
+ "download",
525
+ "upload",
526
+ "external-link",
527
+ "copy",
528
+ "check",
529
+ "x",
530
+ "trash-2",
531
+ "pencil",
532
+ "eye",
533
+ "calendar",
534
+ "clock",
535
+ "user",
536
+ "users",
537
+ "bot",
538
+ "git-pull-request",
539
+ "git-branch",
540
+ "github",
541
+ "slack",
542
+ "mail",
543
+ "link",
544
+ "file-text",
545
+ "folder",
546
+ "database",
547
+ "zap",
548
+ "sparkles",
549
+ "flag",
550
+ "star",
551
+ "tag",
552
+ "alert-triangle",
553
+ "info",
554
+ "circle-check",
555
+ "trending-up",
556
+ "trending-down",
557
+ "dollar-sign",
558
+ "activity",
559
+ "rocket"
560
+ ]
561
+ },
562
+ "iconPosition": {
563
+ "type": "string",
564
+ "enum": ["start", "end"]
565
+ },
566
+ "successLabel": {
567
+ "type": "string"
568
+ },
569
+ "size": {
570
+ "type": "string",
571
+ "enum": ["sm", "default", "lg"]
572
+ },
573
+ "shortcut": {
574
+ "type": "string",
575
+ "minLength": 1,
576
+ "maxLength": 12
577
+ },
578
+ "hint": {
579
+ "type": "string"
387
580
  }
388
581
  },
389
582
  "required": ["label"],
@@ -391,7 +584,7 @@
391
584
  }
392
585
  },
393
586
  "Metric": {
394
- "description": "Single label/value tile for status pages. Bind `loading` to the backing query (`{ \"$state\": \"/queries/<name>/loading\" }`) to show a skeleton instead of a blank value while it loads.",
587
+ "description": "Stat tile (the dashboard `StatPanel`): label, value, optional `detail` line and `trend: { direction: \"up\"|\"down\"|\"flat\", label }` (arrow plus success/error/muted text). `icon` adds a tile tinted by `tone` (neutral|success|active|error|info|pending|warning|paused); `info` is a one-sentence explanation in a tooltip next to the label. Bind `loading` to the backing query (`{ \"$state\": \"/queries/<name>/loading\" }`) to show a skeleton instead of a blank value while it loads; an empty value renders an em dash.",
395
588
  "props": {
396
589
  "$schema": "http://json-schema.org/draft-07/schema#",
397
590
  "type": "object",
@@ -411,6 +604,84 @@
411
604
  },
412
605
  "loading": {
413
606
  "type": "boolean"
607
+ },
608
+ "icon": {
609
+ "type": "string",
610
+ "enum": [
611
+ "plus",
612
+ "refresh-cw",
613
+ "search",
614
+ "filter",
615
+ "download",
616
+ "upload",
617
+ "external-link",
618
+ "copy",
619
+ "check",
620
+ "x",
621
+ "trash-2",
622
+ "pencil",
623
+ "eye",
624
+ "calendar",
625
+ "clock",
626
+ "user",
627
+ "users",
628
+ "bot",
629
+ "git-pull-request",
630
+ "git-branch",
631
+ "github",
632
+ "slack",
633
+ "mail",
634
+ "link",
635
+ "file-text",
636
+ "folder",
637
+ "database",
638
+ "zap",
639
+ "sparkles",
640
+ "flag",
641
+ "star",
642
+ "tag",
643
+ "alert-triangle",
644
+ "info",
645
+ "circle-check",
646
+ "trending-up",
647
+ "trending-down",
648
+ "dollar-sign",
649
+ "activity",
650
+ "rocket"
651
+ ]
652
+ },
653
+ "tone": {
654
+ "type": "string",
655
+ "enum": [
656
+ "neutral",
657
+ "success",
658
+ "active",
659
+ "error",
660
+ "info",
661
+ "pending",
662
+ "warning",
663
+ "paused"
664
+ ]
665
+ },
666
+ "detail": {
667
+ "type": "string"
668
+ },
669
+ "info": {
670
+ "type": "string"
671
+ },
672
+ "trend": {
673
+ "type": "object",
674
+ "properties": {
675
+ "direction": {
676
+ "type": "string",
677
+ "enum": ["up", "down", "flat"]
678
+ },
679
+ "label": {
680
+ "type": "string"
681
+ }
682
+ },
683
+ "required": ["direction", "label"],
684
+ "additionalProperties": false
414
685
  }
415
686
  },
416
687
  "required": ["label", "value"],
@@ -418,7 +689,7 @@
418
689
  }
419
690
  },
420
691
  "Alert": {
421
- "description": "Status-toned inline alert.",
692
+ "description": "Status-toned inline alert. `icon` overrides the tone's default icon. `actionLabel` adds a button inside the callout that emits the element's `press` event (wire it with `on.press`).",
422
693
  "props": {
423
694
  "$schema": "http://json-schema.org/draft-07/schema#",
424
695
  "type": "object",
@@ -426,54 +697,553 @@
426
697
  "message": {
427
698
  "type": "string"
428
699
  },
429
- "tone": {
430
- "type": "string",
431
- "enum": ["info", "success", "warning", "error"]
700
+ "tone": {
701
+ "type": "string",
702
+ "enum": ["info", "success", "warning", "error"]
703
+ },
704
+ "title": {
705
+ "type": "string"
706
+ },
707
+ "icon": {
708
+ "type": "string",
709
+ "enum": [
710
+ "plus",
711
+ "refresh-cw",
712
+ "search",
713
+ "filter",
714
+ "download",
715
+ "upload",
716
+ "external-link",
717
+ "copy",
718
+ "check",
719
+ "x",
720
+ "trash-2",
721
+ "pencil",
722
+ "eye",
723
+ "calendar",
724
+ "clock",
725
+ "user",
726
+ "users",
727
+ "bot",
728
+ "git-pull-request",
729
+ "git-branch",
730
+ "github",
731
+ "slack",
732
+ "mail",
733
+ "link",
734
+ "file-text",
735
+ "folder",
736
+ "database",
737
+ "zap",
738
+ "sparkles",
739
+ "flag",
740
+ "star",
741
+ "tag",
742
+ "alert-triangle",
743
+ "info",
744
+ "circle-check",
745
+ "trending-up",
746
+ "trending-down",
747
+ "dollar-sign",
748
+ "activity",
749
+ "rocket"
750
+ ]
751
+ },
752
+ "actionLabel": {
753
+ "type": "string"
754
+ }
755
+ },
756
+ "required": ["message"],
757
+ "additionalProperties": false
758
+ }
759
+ },
760
+ "Badge": {
761
+ "description": "Small chip. `variant`: `tag` (default, the uppercase status chip with a tone dot), `status` (11px sentence-case pill with a dot or icon), `count` (compact rounded numeric pill), `beta` (the BETA tag; `hint` is its tooltip). `tone` is neutral|success|active|error|info|pending|warning|paused; `icon` replaces the dot. `status` takes a lifecycle value (pending, in_progress, completed, failed, cancelled, paused, ...) and renders the dashboard status chip with its icon and label — any other value falls back to a toned pill showing `text`. `hint` adds a hover tooltip.",
762
+ "props": {
763
+ "$schema": "http://json-schema.org/draft-07/schema#",
764
+ "type": "object",
765
+ "properties": {
766
+ "text": {
767
+ "anyOf": [
768
+ {
769
+ "type": "string"
770
+ },
771
+ {
772
+ "type": "number"
773
+ }
774
+ ]
775
+ },
776
+ "tone": {
777
+ "type": "string",
778
+ "enum": [
779
+ "neutral",
780
+ "success",
781
+ "active",
782
+ "error",
783
+ "info",
784
+ "pending",
785
+ "warning",
786
+ "paused"
787
+ ]
788
+ },
789
+ "icon": {
790
+ "type": "string",
791
+ "enum": [
792
+ "plus",
793
+ "refresh-cw",
794
+ "search",
795
+ "filter",
796
+ "download",
797
+ "upload",
798
+ "external-link",
799
+ "copy",
800
+ "check",
801
+ "x",
802
+ "trash-2",
803
+ "pencil",
804
+ "eye",
805
+ "calendar",
806
+ "clock",
807
+ "user",
808
+ "users",
809
+ "bot",
810
+ "git-pull-request",
811
+ "git-branch",
812
+ "github",
813
+ "slack",
814
+ "mail",
815
+ "link",
816
+ "file-text",
817
+ "folder",
818
+ "database",
819
+ "zap",
820
+ "sparkles",
821
+ "flag",
822
+ "star",
823
+ "tag",
824
+ "alert-triangle",
825
+ "info",
826
+ "circle-check",
827
+ "trending-up",
828
+ "trending-down",
829
+ "dollar-sign",
830
+ "activity",
831
+ "rocket"
832
+ ]
833
+ },
834
+ "status": {
835
+ "type": "string"
836
+ },
837
+ "variant": {
838
+ "type": "string",
839
+ "enum": ["tag", "status", "count", "beta"]
840
+ },
841
+ "hint": {
842
+ "type": "string"
843
+ }
844
+ },
845
+ "required": ["text"],
846
+ "additionalProperties": false
847
+ }
848
+ },
849
+ "Icon": {
850
+ "description": "One icon from the curated lucide set (`plus`, `refresh-cw`, `search`, `filter`, `download`, `upload`, `external-link`, `copy`, `check`, `x`, `trash-2`, `pencil`, `eye`, `calendar`, `clock`, `user`, `users`, `bot`, `git-pull-request`, `git-branch`, `github`, `slack`, `mail`, `link`, `file-text`, `folder`, `database`, `zap`, `sparkles`, `flag`, `star`, `tag`, `alert-triangle`, `info`, `circle-check`, `trending-up`, `trending-down`, `dollar-sign`, `activity`, `rocket`). The same names work on every `icon` prop (Button, Badge, Metric, Alert, Tabs entries, Chips options, EmptyState, Table columns, row actions and Drawer actions). Decorative unless `label` is set. `size` sm|md|lg, `tone` default|muted|success|warning|error|info.",
851
+ "props": {
852
+ "$schema": "http://json-schema.org/draft-07/schema#",
853
+ "type": "object",
854
+ "properties": {
855
+ "name": {
856
+ "type": "string",
857
+ "enum": [
858
+ "plus",
859
+ "refresh-cw",
860
+ "search",
861
+ "filter",
862
+ "download",
863
+ "upload",
864
+ "external-link",
865
+ "copy",
866
+ "check",
867
+ "x",
868
+ "trash-2",
869
+ "pencil",
870
+ "eye",
871
+ "calendar",
872
+ "clock",
873
+ "user",
874
+ "users",
875
+ "bot",
876
+ "git-pull-request",
877
+ "git-branch",
878
+ "github",
879
+ "slack",
880
+ "mail",
881
+ "link",
882
+ "file-text",
883
+ "folder",
884
+ "database",
885
+ "zap",
886
+ "sparkles",
887
+ "flag",
888
+ "star",
889
+ "tag",
890
+ "alert-triangle",
891
+ "info",
892
+ "circle-check",
893
+ "trending-up",
894
+ "trending-down",
895
+ "dollar-sign",
896
+ "activity",
897
+ "rocket"
898
+ ]
899
+ },
900
+ "size": {
901
+ "type": "string",
902
+ "enum": ["sm", "md", "lg"]
903
+ },
904
+ "tone": {
905
+ "type": "string",
906
+ "enum": ["default", "muted", "success", "warning", "error", "info"]
907
+ },
908
+ "label": {
909
+ "type": "string"
910
+ }
911
+ },
912
+ "required": ["name"],
913
+ "additionalProperties": false
914
+ }
915
+ },
916
+ "Progress": {
917
+ "description": "Progress readout. `value` against `max` (default 100), usually bound to state. `variant: \"bar\"` (default) is a toned bar (`tone` neutral|success|active|error|info|pending|warning|paused) with an optional `label` above it; `\"ring\"` is the dashboard progress ring (done arc). `showValue` (default true) prints the percent (bar) or `value / max` (ring).",
918
+ "props": {
919
+ "$schema": "http://json-schema.org/draft-07/schema#",
920
+ "type": "object",
921
+ "properties": {
922
+ "value": {
923
+ "type": "number"
924
+ },
925
+ "max": {
926
+ "type": "number",
927
+ "exclusiveMinimum": 0
928
+ },
929
+ "tone": {
930
+ "type": "string",
931
+ "enum": [
932
+ "neutral",
933
+ "success",
934
+ "active",
935
+ "error",
936
+ "info",
937
+ "pending",
938
+ "warning",
939
+ "paused"
940
+ ]
941
+ },
942
+ "label": {
943
+ "type": "string"
944
+ },
945
+ "variant": {
946
+ "type": "string",
947
+ "enum": ["bar", "ring"]
948
+ },
949
+ "showValue": {
950
+ "type": "boolean"
951
+ }
952
+ },
953
+ "required": ["value"],
954
+ "additionalProperties": false
955
+ }
956
+ },
957
+ "EmptyState": {
958
+ "description": "Centered empty state: `icon` (curated set, default inbox), `title`, optional `body`. `actionLabel` adds a button that emits the element's `press` event — wire it with `on.press` like a Button.",
959
+ "props": {
960
+ "$schema": "http://json-schema.org/draft-07/schema#",
961
+ "type": "object",
962
+ "properties": {
963
+ "icon": {
964
+ "type": "string",
965
+ "enum": [
966
+ "plus",
967
+ "refresh-cw",
968
+ "search",
969
+ "filter",
970
+ "download",
971
+ "upload",
972
+ "external-link",
973
+ "copy",
974
+ "check",
975
+ "x",
976
+ "trash-2",
977
+ "pencil",
978
+ "eye",
979
+ "calendar",
980
+ "clock",
981
+ "user",
982
+ "users",
983
+ "bot",
984
+ "git-pull-request",
985
+ "git-branch",
986
+ "github",
987
+ "slack",
988
+ "mail",
989
+ "link",
990
+ "file-text",
991
+ "folder",
992
+ "database",
993
+ "zap",
994
+ "sparkles",
995
+ "flag",
996
+ "star",
997
+ "tag",
998
+ "alert-triangle",
999
+ "info",
1000
+ "circle-check",
1001
+ "trending-up",
1002
+ "trending-down",
1003
+ "dollar-sign",
1004
+ "activity",
1005
+ "rocket"
1006
+ ]
1007
+ },
1008
+ "title": {
1009
+ "type": "string"
1010
+ },
1011
+ "body": {
1012
+ "type": "string"
1013
+ },
1014
+ "actionLabel": {
1015
+ "type": "string"
1016
+ }
1017
+ },
1018
+ "required": ["title"],
1019
+ "additionalProperties": false
1020
+ }
1021
+ },
1022
+ "CopyButton": {
1023
+ "description": "Copies `value` to the clipboard; the icon swaps to a check on copy. `label` is the visible text; without it the button is icon-only.",
1024
+ "props": {
1025
+ "$schema": "http://json-schema.org/draft-07/schema#",
1026
+ "type": "object",
1027
+ "properties": {
1028
+ "value": {
1029
+ "anyOf": [
1030
+ {
1031
+ "type": "string"
1032
+ },
1033
+ {
1034
+ "type": "number"
1035
+ }
1036
+ ]
1037
+ },
1038
+ "label": {
1039
+ "type": "string"
1040
+ }
1041
+ },
1042
+ "required": ["value"],
1043
+ "additionalProperties": false
1044
+ }
1045
+ },
1046
+ "Kbd": {
1047
+ "description": "Keycaps for a keyboard shortcut, one per entry in `keys` (e.g. `[\"⌘\", \"K\"]`). Display only.",
1048
+ "props": {
1049
+ "$schema": "http://json-schema.org/draft-07/schema#",
1050
+ "type": "object",
1051
+ "properties": {
1052
+ "keys": {
1053
+ "minItems": 1,
1054
+ "type": "array",
1055
+ "items": {
1056
+ "type": "string"
1057
+ }
1058
+ }
1059
+ },
1060
+ "required": ["keys"],
1061
+ "additionalProperties": false
1062
+ }
1063
+ },
1064
+ "Skeleton": {
1065
+ "description": "Loading placeholder. `shape`: `line` (text lines), `block` (one box, `height` in px, default 128), `rows` (table-like rows), `metric` (stat tiles), `card` (a card sketch). `count` repeats lines, rows or tiles. Pair with `visible` on a query's `loading` state.",
1066
+ "props": {
1067
+ "$schema": "http://json-schema.org/draft-07/schema#",
1068
+ "type": "object",
1069
+ "properties": {
1070
+ "shape": {
1071
+ "type": "string",
1072
+ "enum": ["line", "block", "rows", "metric", "card"]
1073
+ },
1074
+ "count": {
1075
+ "type": "integer",
1076
+ "minimum": 1,
1077
+ "maximum": 20
1078
+ },
1079
+ "height": {
1080
+ "type": "integer",
1081
+ "minimum": 8,
1082
+ "maximum": 800
1083
+ }
1084
+ },
1085
+ "required": ["shape"],
1086
+ "additionalProperties": false
1087
+ }
1088
+ },
1089
+ "Spinner": {
1090
+ "description": "Inline busy indicator with `role=status`. `variant` ring|ellipsis|bars (default: the dashboard spinner), `size` sm|md, `label` shown next to it (and its accessible name; defaults to an sr-only \"Loading\").",
1091
+ "props": {
1092
+ "$schema": "http://json-schema.org/draft-07/schema#",
1093
+ "type": "object",
1094
+ "properties": {
1095
+ "variant": {
1096
+ "type": "string",
1097
+ "enum": ["ring", "ellipsis", "bars"]
1098
+ },
1099
+ "size": {
1100
+ "type": "string",
1101
+ "enum": ["sm", "md"]
1102
+ },
1103
+ "label": {
1104
+ "type": "string"
1105
+ }
1106
+ },
1107
+ "additionalProperties": false
1108
+ }
1109
+ },
1110
+ "AvatarStack": {
1111
+ "description": "Overlapping initials avatars for `users` (display names), up to `max` (default 4) then a `+N` count; hover lists every name.",
1112
+ "props": {
1113
+ "$schema": "http://json-schema.org/draft-07/schema#",
1114
+ "type": "object",
1115
+ "properties": {
1116
+ "users": {
1117
+ "type": "array",
1118
+ "items": {
1119
+ "type": "string"
1120
+ }
1121
+ },
1122
+ "max": {
1123
+ "type": "integer",
1124
+ "minimum": 1,
1125
+ "maximum": 20
1126
+ }
1127
+ },
1128
+ "required": ["users"],
1129
+ "additionalProperties": false
1130
+ }
1131
+ },
1132
+ "Section": {
1133
+ "description": "Titled section around its children: `title`, optional `description`. `collapsible` folds the body under a toggle header (`defaultOpen`, default true).",
1134
+ "slots": ["default"],
1135
+ "props": {
1136
+ "$schema": "http://json-schema.org/draft-07/schema#",
1137
+ "type": "object",
1138
+ "properties": {
1139
+ "title": {
1140
+ "type": "string"
1141
+ },
1142
+ "description": {
1143
+ "type": "string"
1144
+ },
1145
+ "collapsible": {
1146
+ "type": "boolean"
1147
+ },
1148
+ "defaultOpen": {
1149
+ "type": "boolean"
1150
+ }
1151
+ },
1152
+ "required": ["title"],
1153
+ "additionalProperties": false
1154
+ }
1155
+ },
1156
+ "Chips": {
1157
+ "description": "Toggle chips for quick filters. `options` are strings or `{ value, label?, icon? }`. Writes the selection to `/ui/<id>/value`: one string or `null` (pressing the selected chip clears it), or with `multiple` a string array (empty = nothing picked). Bind it into a Table with `\"filters\": { \"<column>\": { \"$state\": \"/ui/<id>/value\" } }` — an array filter matches rows whose cell is one of the values. `label` names the group for screen readers.",
1158
+ "props": {
1159
+ "$schema": "http://json-schema.org/draft-07/schema#",
1160
+ "type": "object",
1161
+ "properties": {
1162
+ "id": {
1163
+ "type": "string"
1164
+ },
1165
+ "options": {
1166
+ "minItems": 1,
1167
+ "type": "array",
1168
+ "items": {
1169
+ "anyOf": [
1170
+ {
1171
+ "type": "string"
1172
+ },
1173
+ {
1174
+ "type": "object",
1175
+ "properties": {
1176
+ "value": {
1177
+ "type": "string"
1178
+ },
1179
+ "label": {
1180
+ "type": "string"
1181
+ },
1182
+ "icon": {
1183
+ "type": "string",
1184
+ "enum": [
1185
+ "plus",
1186
+ "refresh-cw",
1187
+ "search",
1188
+ "filter",
1189
+ "download",
1190
+ "upload",
1191
+ "external-link",
1192
+ "copy",
1193
+ "check",
1194
+ "x",
1195
+ "trash-2",
1196
+ "pencil",
1197
+ "eye",
1198
+ "calendar",
1199
+ "clock",
1200
+ "user",
1201
+ "users",
1202
+ "bot",
1203
+ "git-pull-request",
1204
+ "git-branch",
1205
+ "github",
1206
+ "slack",
1207
+ "mail",
1208
+ "link",
1209
+ "file-text",
1210
+ "folder",
1211
+ "database",
1212
+ "zap",
1213
+ "sparkles",
1214
+ "flag",
1215
+ "star",
1216
+ "tag",
1217
+ "alert-triangle",
1218
+ "info",
1219
+ "circle-check",
1220
+ "trending-up",
1221
+ "trending-down",
1222
+ "dollar-sign",
1223
+ "activity",
1224
+ "rocket"
1225
+ ]
1226
+ }
1227
+ },
1228
+ "required": ["value"],
1229
+ "additionalProperties": false
1230
+ }
1231
+ ]
1232
+ }
1233
+ },
1234
+ "multiple": {
1235
+ "type": "boolean"
432
1236
  },
433
- "title": {
1237
+ "label": {
434
1238
  "type": "string"
435
1239
  }
436
1240
  },
437
- "required": ["message"],
438
- "additionalProperties": false
439
- }
440
- },
441
- "Badge": {
442
- "description": "Status pill (uppercase tag chip) with a semantic tone.",
443
- "props": {
444
- "$schema": "http://json-schema.org/draft-07/schema#",
445
- "type": "object",
446
- "properties": {
447
- "text": {
448
- "anyOf": [
449
- {
450
- "type": "string"
451
- },
452
- {
453
- "type": "number"
454
- }
455
- ]
456
- },
457
- "tone": {
458
- "type": "string",
459
- "enum": [
460
- "neutral",
461
- "success",
462
- "active",
463
- "error",
464
- "info",
465
- "pending",
466
- "warning",
467
- "paused"
468
- ]
469
- }
470
- },
471
- "required": ["text"],
1241
+ "required": ["id", "options"],
472
1242
  "additionalProperties": false
473
1243
  }
474
1244
  },
475
1245
  "Table": {
476
- "description": "Data table. Bind `data`/`loading`/`error` to a named query (`/queries/<name>/...`). `rowActions` chains receive `{ \"$row\": \"<col>\" }` (or `{ \"$row\": \"\" }` for the whole row) and `{ \"$rowIndex\": true }`. Destructive row actions always confirm via a dialog; override the copy with `confirm: { title, description, confirmLabel }`. `search` (case-insensitive substring across every listed column) and `filters` (per-column equality, `null`/`\"\"` disables one) narrow the polled rows client-side — bind them to a `SearchInput` / `Select` via `/ui/<id>/value`, or pin a constant (e.g. `\"filters\": { \"pinned\": true }`). Columns take `pinned: \"left\"|\"right\"` to survive horizontal scroll; `pagination` pages large row sets (auto past 200 rows); `density: \"compact\"` tightens row height.",
1246
+ "description": "Data table. Bind `data`/`loading`/`error` to a named query (`/queries/<name>/...`). `rowActions` chains receive `{ \"$row\": \"<col>\" }` (or `{ \"$row\": \"\" }` for the whole row) and `{ \"$rowIndex\": true }`. Destructive row actions always confirm via a dialog; override the copy with `confirm: { title, description, confirmLabel }`. `search` (case-insensitive substring across every listed column) and `filters` (per-column equality, `null`/`\"\"` disables one; an array means \"one of\", which is what a multiple `Chips` writes, and an empty array disables it) narrow the polled rows client-side — bind them to a `SearchInput` / `Select` via `/ui/<id>/value`, or pin a constant (e.g. `\"filters\": { \"pinned\": true }`). Columns take `pinned: \"left\"|\"right\"` to survive horizontal scroll; `pagination` pages large row sets (auto past 200 rows); `density: \"compact\"` tightens row height. Column kinds: `status` (lifecycle values like pending/in_progress/completed/failed get the dashboard status icon, anything else a `tones` pill), `user` / `agent` (avatar + name), `relative` (smart time with the exact time on hover), `duration` (ms → 1m 23s), `progress` (bar, `max` default 100), `copy` (value + copy button), `switch` (runs the column's `onChange` chain with `$row` set to the new value; read-only without it), `link` (http(s) URL, opens in a new tab). Columns also take `align`, `truncate: \"middle\"` (ids, paths), a header `icon` and `tooltip` (a row field shown on hover). `onRowClick` runs a chain with `$row` when a row is clicked — pair it with `app.navigate` + a Drawer and bind `selectedId` to the drawer param to highlight the open row. `rowId` names the id field (default `id`). Below 768px the table renders as a phone list (`mobile: \"list\"`, fields picked by `mobileFields: { title, subtitle?, meta?, status? }`); `mobile: \"scroll\"` keeps the grid. `emptyState: { icon?, title, body? }` replaces the empty message. Row actions take `icon` and `placement: \"menu\"` (collected into a More menu).",
477
1247
  "props": {
478
1248
  "$schema": "http://json-schema.org/draft-07/schema#",
479
1249
  "type": "object",
@@ -501,7 +1271,24 @@
501
1271
  },
502
1272
  "kind": {
503
1273
  "type": "string",
504
- "enum": ["text", "string", "number", "boolean", "date", "badge", "enum"]
1274
+ "enum": [
1275
+ "text",
1276
+ "string",
1277
+ "number",
1278
+ "boolean",
1279
+ "date",
1280
+ "badge",
1281
+ "enum",
1282
+ "status",
1283
+ "user",
1284
+ "agent",
1285
+ "relative",
1286
+ "duration",
1287
+ "progress",
1288
+ "copy",
1289
+ "switch",
1290
+ "link"
1291
+ ]
505
1292
  },
506
1293
  "tones": {
507
1294
  "type": "object",
@@ -528,6 +1315,86 @@
528
1315
  "pinned": {
529
1316
  "type": "string",
530
1317
  "enum": ["left", "right"]
1318
+ },
1319
+ "align": {
1320
+ "type": "string",
1321
+ "enum": ["start", "end"]
1322
+ },
1323
+ "truncate": {
1324
+ "type": "string",
1325
+ "enum": ["end", "middle"]
1326
+ },
1327
+ "icon": {
1328
+ "type": "string",
1329
+ "enum": [
1330
+ "plus",
1331
+ "refresh-cw",
1332
+ "search",
1333
+ "filter",
1334
+ "download",
1335
+ "upload",
1336
+ "external-link",
1337
+ "copy",
1338
+ "check",
1339
+ "x",
1340
+ "trash-2",
1341
+ "pencil",
1342
+ "eye",
1343
+ "calendar",
1344
+ "clock",
1345
+ "user",
1346
+ "users",
1347
+ "bot",
1348
+ "git-pull-request",
1349
+ "git-branch",
1350
+ "github",
1351
+ "slack",
1352
+ "mail",
1353
+ "link",
1354
+ "file-text",
1355
+ "folder",
1356
+ "database",
1357
+ "zap",
1358
+ "sparkles",
1359
+ "flag",
1360
+ "star",
1361
+ "tag",
1362
+ "alert-triangle",
1363
+ "info",
1364
+ "circle-check",
1365
+ "trending-up",
1366
+ "trending-down",
1367
+ "dollar-sign",
1368
+ "activity",
1369
+ "rocket"
1370
+ ]
1371
+ },
1372
+ "tooltip": {
1373
+ "type": "string"
1374
+ },
1375
+ "max": {
1376
+ "type": "number",
1377
+ "exclusiveMinimum": 0
1378
+ },
1379
+ "onChange": {
1380
+ "type": "array",
1381
+ "items": {
1382
+ "type": "object",
1383
+ "properties": {
1384
+ "action": {
1385
+ "type": "string"
1386
+ },
1387
+ "params": {
1388
+ "type": "object",
1389
+ "propertyNames": {
1390
+ "type": "string"
1391
+ },
1392
+ "additionalProperties": {}
1393
+ }
1394
+ },
1395
+ "required": ["action"],
1396
+ "additionalProperties": false
1397
+ }
531
1398
  }
532
1399
  },
533
1400
  "required": ["key"],
@@ -597,6 +1464,55 @@
597
1464
  "required": ["action"],
598
1465
  "additionalProperties": false
599
1466
  }
1467
+ },
1468
+ "icon": {
1469
+ "type": "string",
1470
+ "enum": [
1471
+ "plus",
1472
+ "refresh-cw",
1473
+ "search",
1474
+ "filter",
1475
+ "download",
1476
+ "upload",
1477
+ "external-link",
1478
+ "copy",
1479
+ "check",
1480
+ "x",
1481
+ "trash-2",
1482
+ "pencil",
1483
+ "eye",
1484
+ "calendar",
1485
+ "clock",
1486
+ "user",
1487
+ "users",
1488
+ "bot",
1489
+ "git-pull-request",
1490
+ "git-branch",
1491
+ "github",
1492
+ "slack",
1493
+ "mail",
1494
+ "link",
1495
+ "file-text",
1496
+ "folder",
1497
+ "database",
1498
+ "zap",
1499
+ "sparkles",
1500
+ "flag",
1501
+ "star",
1502
+ "tag",
1503
+ "alert-triangle",
1504
+ "info",
1505
+ "circle-check",
1506
+ "trending-up",
1507
+ "trending-down",
1508
+ "dollar-sign",
1509
+ "activity",
1510
+ "rocket"
1511
+ ]
1512
+ },
1513
+ "placement": {
1514
+ "type": "string",
1515
+ "enum": ["inline", "menu"]
600
1516
  }
601
1517
  },
602
1518
  "required": ["label", "actions"],
@@ -639,6 +1555,22 @@
639
1555
  },
640
1556
  {
641
1557
  "type": "boolean"
1558
+ },
1559
+ {
1560
+ "type": "array",
1561
+ "items": {
1562
+ "anyOf": [
1563
+ {
1564
+ "type": "string"
1565
+ },
1566
+ {
1567
+ "type": "number"
1568
+ },
1569
+ {
1570
+ "type": "boolean"
1571
+ }
1572
+ ]
1573
+ }
642
1574
  }
643
1575
  ]
644
1576
  },
@@ -654,6 +1586,137 @@
654
1586
  "density": {
655
1587
  "type": "string",
656
1588
  "enum": ["comfortable", "compact"]
1589
+ },
1590
+ "rowId": {
1591
+ "type": "string"
1592
+ },
1593
+ "onRowClick": {
1594
+ "type": "array",
1595
+ "items": {
1596
+ "type": "object",
1597
+ "properties": {
1598
+ "action": {
1599
+ "type": "string"
1600
+ },
1601
+ "params": {
1602
+ "type": "object",
1603
+ "propertyNames": {
1604
+ "type": "string"
1605
+ },
1606
+ "additionalProperties": {}
1607
+ }
1608
+ },
1609
+ "required": ["action"],
1610
+ "additionalProperties": false
1611
+ }
1612
+ },
1613
+ "selectedId": {
1614
+ "anyOf": [
1615
+ {
1616
+ "anyOf": [
1617
+ {
1618
+ "type": "string"
1619
+ },
1620
+ {
1621
+ "type": "number"
1622
+ }
1623
+ ]
1624
+ },
1625
+ {
1626
+ "type": "null"
1627
+ }
1628
+ ]
1629
+ },
1630
+ "mobile": {
1631
+ "type": "string",
1632
+ "enum": ["list", "scroll"]
1633
+ },
1634
+ "mobileFields": {
1635
+ "type": "object",
1636
+ "properties": {
1637
+ "title": {
1638
+ "type": "string"
1639
+ },
1640
+ "subtitle": {
1641
+ "type": "string"
1642
+ },
1643
+ "meta": {
1644
+ "anyOf": [
1645
+ {
1646
+ "type": "string"
1647
+ },
1648
+ {
1649
+ "type": "array",
1650
+ "items": {
1651
+ "type": "string"
1652
+ }
1653
+ }
1654
+ ]
1655
+ },
1656
+ "status": {
1657
+ "type": "string"
1658
+ }
1659
+ },
1660
+ "required": ["title"],
1661
+ "additionalProperties": false
1662
+ },
1663
+ "emptyState": {
1664
+ "type": "object",
1665
+ "properties": {
1666
+ "icon": {
1667
+ "type": "string",
1668
+ "enum": [
1669
+ "plus",
1670
+ "refresh-cw",
1671
+ "search",
1672
+ "filter",
1673
+ "download",
1674
+ "upload",
1675
+ "external-link",
1676
+ "copy",
1677
+ "check",
1678
+ "x",
1679
+ "trash-2",
1680
+ "pencil",
1681
+ "eye",
1682
+ "calendar",
1683
+ "clock",
1684
+ "user",
1685
+ "users",
1686
+ "bot",
1687
+ "git-pull-request",
1688
+ "git-branch",
1689
+ "github",
1690
+ "slack",
1691
+ "mail",
1692
+ "link",
1693
+ "file-text",
1694
+ "folder",
1695
+ "database",
1696
+ "zap",
1697
+ "sparkles",
1698
+ "flag",
1699
+ "star",
1700
+ "tag",
1701
+ "alert-triangle",
1702
+ "info",
1703
+ "circle-check",
1704
+ "trending-up",
1705
+ "trending-down",
1706
+ "dollar-sign",
1707
+ "activity",
1708
+ "rocket"
1709
+ ]
1710
+ },
1711
+ "title": {
1712
+ "type": "string"
1713
+ },
1714
+ "body": {
1715
+ "type": "string"
1716
+ }
1717
+ },
1718
+ "required": ["title"],
1719
+ "additionalProperties": false
657
1720
  }
658
1721
  },
659
1722
  "required": ["columns"],
@@ -734,7 +1797,7 @@
734
1797
  }
735
1798
  },
736
1799
  "Drawer": {
737
- "description": "Route-driven slide-in side panel (sheet). Open exactly when the route param named by `param` is set — open it with `app.navigate` (e.g. a rowAction setting `{ \"panel\": { \"$row\": \"id\" } }`), and the URL stays shareable: a deep link with the param renders the drawer open, and closing it clears the param. Children mount only while open (a Table inside does NOT stay warm when closed — unlike Tabs). `side` right (default) or left; `size` sm|md|lg|xl width.",
1800
+ "description": "Route-driven slide-in side panel (sheet). Open exactly when the route param named by `param` is set — open it with `app.navigate` (e.g. a rowAction setting `{ \"panel\": { \"$row\": \"id\" } }`), and the URL stays shareable: a deep link with the param renders the drawer open, and closing it clears the param. Children mount only while open (a Table inside does NOT stay warm when closed — unlike Tabs). `side` right (default) or left; `size` sm|md|lg|xl width. `actions: [{ label, icon?, variant?, confirm?, actions }]` render in a sticky footer with the Table rowActions confirm rules (destructive variants confirm, an `app.mutate` delete always confirms); chains have no `$row`, so read the open record id with `{ \"$state\": \"/route/params/<param>\" }`.",
738
1801
  "slots": ["default"],
739
1802
  "props": {
740
1803
  "$schema": "http://json-schema.org/draft-07/schema#",
@@ -756,6 +1819,120 @@
756
1819
  "size": {
757
1820
  "type": "string",
758
1821
  "enum": ["sm", "md", "lg", "xl"]
1822
+ },
1823
+ "actions": {
1824
+ "type": "array",
1825
+ "items": {
1826
+ "type": "object",
1827
+ "properties": {
1828
+ "label": {
1829
+ "type": "string"
1830
+ },
1831
+ "variant": {
1832
+ "type": "string",
1833
+ "enum": [
1834
+ "default",
1835
+ "secondary",
1836
+ "outline",
1837
+ "ghost",
1838
+ "destructive",
1839
+ "destructive-outline"
1840
+ ]
1841
+ },
1842
+ "confirm": {
1843
+ "anyOf": [
1844
+ {
1845
+ "type": "boolean"
1846
+ },
1847
+ {
1848
+ "type": "object",
1849
+ "properties": {
1850
+ "title": {
1851
+ "type": "string"
1852
+ },
1853
+ "description": {
1854
+ "type": "string"
1855
+ },
1856
+ "confirmLabel": {
1857
+ "type": "string"
1858
+ }
1859
+ },
1860
+ "additionalProperties": false
1861
+ },
1862
+ {
1863
+ "type": "string"
1864
+ }
1865
+ ]
1866
+ },
1867
+ "actions": {
1868
+ "type": "array",
1869
+ "items": {
1870
+ "type": "object",
1871
+ "properties": {
1872
+ "action": {
1873
+ "type": "string"
1874
+ },
1875
+ "params": {
1876
+ "type": "object",
1877
+ "propertyNames": {
1878
+ "type": "string"
1879
+ },
1880
+ "additionalProperties": {}
1881
+ }
1882
+ },
1883
+ "required": ["action"],
1884
+ "additionalProperties": false
1885
+ }
1886
+ },
1887
+ "icon": {
1888
+ "type": "string",
1889
+ "enum": [
1890
+ "plus",
1891
+ "refresh-cw",
1892
+ "search",
1893
+ "filter",
1894
+ "download",
1895
+ "upload",
1896
+ "external-link",
1897
+ "copy",
1898
+ "check",
1899
+ "x",
1900
+ "trash-2",
1901
+ "pencil",
1902
+ "eye",
1903
+ "calendar",
1904
+ "clock",
1905
+ "user",
1906
+ "users",
1907
+ "bot",
1908
+ "git-pull-request",
1909
+ "git-branch",
1910
+ "github",
1911
+ "slack",
1912
+ "mail",
1913
+ "link",
1914
+ "file-text",
1915
+ "folder",
1916
+ "database",
1917
+ "zap",
1918
+ "sparkles",
1919
+ "flag",
1920
+ "star",
1921
+ "tag",
1922
+ "alert-triangle",
1923
+ "info",
1924
+ "circle-check",
1925
+ "trending-up",
1926
+ "trending-down",
1927
+ "dollar-sign",
1928
+ "activity",
1929
+ "rocket"
1930
+ ]
1931
+ }
1932
+ },
1933
+ "required": ["label", "actions"],
1934
+ "additionalProperties": false
1935
+ }
759
1936
  }
760
1937
  },
761
1938
  "required": ["param"],
@@ -763,7 +1940,7 @@
763
1940
  }
764
1941
  },
765
1942
  "DetailList": {
766
- "description": "Read-only label/value detail view for ONE record. Bind `data` to a single row — usually `{ \"$state\": \"/queries/<name>/data/0\" }` with a `$param`-filtered query. `fields` pick and format properties with the same kinds as Table columns (badge tones, relative dates) plus `code` for raw/JSON values. Bind `loading` to the query (`/queries/<name>/loading`) for skeleton fields while it loads; `emptyMessage` shows when the record is genuinely missing.",
1943
+ "description": "Read-only label/value detail view for ONE record. Bind `data` to a single row — usually `{ \"$state\": \"/queries/<name>/data/0\" }` with a `$param`-filtered query. `fields` pick and format properties with the same kinds as Table columns (badge tones, relative dates) plus `status` (lifecycle chip), `user` (avatar + name), `relative` (smart time, exact on hover), `copy` (value + copy button), `code` (monospace block) and `json` (collapsible JSON tree). Bind `loading` to the query (`/queries/<name>/loading`) for skeleton fields while it loads; `emptyMessage` shows when the record is genuinely missing.",
767
1944
  "props": {
768
1945
  "$schema": "http://json-schema.org/draft-07/schema#",
769
1946
  "type": "object",
@@ -796,7 +1973,21 @@
796
1973
  },
797
1974
  "kind": {
798
1975
  "type": "string",
799
- "enum": ["text", "string", "number", "boolean", "date", "badge", "enum", "code"]
1976
+ "enum": [
1977
+ "text",
1978
+ "string",
1979
+ "number",
1980
+ "boolean",
1981
+ "date",
1982
+ "badge",
1983
+ "enum",
1984
+ "code",
1985
+ "status",
1986
+ "user",
1987
+ "relative",
1988
+ "copy",
1989
+ "json"
1990
+ ]
800
1991
  },
801
1992
  "tones": {
802
1993
  "type": "object",
@@ -846,7 +2037,7 @@
846
2037
  }
847
2038
  },
848
2039
  "Kanban": {
849
- "description": "Kanban board: one card per row, grouped into `columns` by the row's `columnField`. Bind `data`/`loading` to a named query. `titleField` is the card title; `cardFields` add label/value lines with Table column kinds (badge tones, relative dates). Dragging a card to another column runs `onMove` with `$row` = the moved row, `columnField` already set to the new column — typically `[{ \"action\": \"app.mutate\", \"params\": { \"model\": \"<m>\", \"op\": \"update\", \"rowId\": { \"$row\": \"id\" }, \"values\": { \"<columnField>\": { \"$row\": \"<columnField>\" } } } }]`. Without `onMove` the board is read-only. `onCardClick` runs with `$row` (e.g. an `app.navigate` that opens a Drawer).",
2040
+ "description": "Kanban board: one card per row, grouped into `columns` by the row's `columnField`. Bind `data`/`loading` to a named query. `titleField` is the card title; `cardFields` add label/value lines with the DetailList field kinds (badge tones, status, user, relative, copy, ...). Dragging a card to another column runs `onMove` with `$row` = the moved row, `columnField` already set to the new column — typically `[{ \"action\": \"app.mutate\", \"params\": { \"model\": \"<m>\", \"op\": \"update\", \"rowId\": { \"$row\": \"id\" }, \"values\": { \"<columnField>\": { \"$row\": \"<columnField>\" } } } }]`. Without `onMove` the board is read-only. `onCardClick` runs with `$row` (e.g. an `app.navigate` that opens a Drawer).",
850
2041
  "props": {
851
2042
  "$schema": "http://json-schema.org/draft-07/schema#",
852
2043
  "type": "object",
@@ -907,7 +2098,21 @@
907
2098
  },
908
2099
  "kind": {
909
2100
  "type": "string",
910
- "enum": ["text", "string", "number", "boolean", "date", "badge", "enum", "code"]
2101
+ "enum": [
2102
+ "text",
2103
+ "string",
2104
+ "number",
2105
+ "boolean",
2106
+ "date",
2107
+ "badge",
2108
+ "enum",
2109
+ "code",
2110
+ "status",
2111
+ "user",
2112
+ "relative",
2113
+ "copy",
2114
+ "json"
2115
+ ]
911
2116
  },
912
2117
  "tones": {
913
2118
  "type": "object",
@@ -1191,6 +2396,57 @@
1191
2396
  "additionalProperties": false
1192
2397
  }
1193
2398
  },
2399
+ "ui.toast": {
2400
+ "description": "Show a toast: `message`, optional `description`, `tone` success|error|info|warning (default info). `undo: { label?, actions }` adds an Undo button (label defaults to \"Undo\") that runs `actions` as a chain — e.g. an `app.mutate` that restores the row a delete just removed.",
2401
+ "params": {
2402
+ "$schema": "http://json-schema.org/draft-07/schema#",
2403
+ "type": "object",
2404
+ "properties": {
2405
+ "message": {
2406
+ "type": "string"
2407
+ },
2408
+ "description": {
2409
+ "type": "string"
2410
+ },
2411
+ "tone": {
2412
+ "type": "string",
2413
+ "enum": ["success", "error", "info", "warning"]
2414
+ },
2415
+ "undo": {
2416
+ "type": "object",
2417
+ "properties": {
2418
+ "label": {
2419
+ "type": "string"
2420
+ },
2421
+ "actions": {
2422
+ "type": "array",
2423
+ "items": {
2424
+ "type": "object",
2425
+ "properties": {
2426
+ "action": {
2427
+ "type": "string"
2428
+ },
2429
+ "params": {
2430
+ "type": "object",
2431
+ "propertyNames": {
2432
+ "type": "string"
2433
+ },
2434
+ "additionalProperties": {}
2435
+ }
2436
+ },
2437
+ "required": ["action"],
2438
+ "additionalProperties": false
2439
+ }
2440
+ }
2441
+ },
2442
+ "required": ["actions"],
2443
+ "additionalProperties": false
2444
+ }
2445
+ },
2446
+ "required": ["message"],
2447
+ "additionalProperties": false
2448
+ }
2449
+ },
1194
2450
  "app.mutate": {
1195
2451
  "description": "Create / update / delete a swarm-app row, then refetch every named query on the same model.",
1196
2452
  "params": {