@desplega.ai/agent-swarm 2.7.6 → 2.7.7

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 (244) hide show
  1. package/dist/{acp-adapter-bp91d37f.js → acp-adapter-7b4vk3h5.js} +5 -4
  2. package/dist/{actions-yj0eeaqh.js → actions-3tt153af.js} +18 -18
  3. package/dist/{amp-adapter-4pg9h34q.js → amp-adapter-njpts0yr.js} +1 -1
  4. package/dist/{anthropic-messages-x4q6rfq5.js → anthropic-messages-xey2skwx.js} +7 -7
  5. package/dist/{app-909e97cr.js → app-nky4378f.js} +3 -3
  6. package/dist/{assistant-qdyb5fyy.js → assistant-jnb669pa.js} +19 -19
  7. package/dist/{azure-openai-responses-s1w5n70z.js → azure-openai-responses-26t7j9ra.js} +5 -5
  8. package/dist/{boot-reembed-fk0s9z18.js → boot-reembed-9mgvaztt.js} +1 -1
  9. package/dist/{boot-reembed-gs1rzrnh.js → boot-reembed-qs2djdej.js} +1 -1
  10. package/dist/{boot-scrub-sweep-4qfd4kfx.js → boot-scrub-sweep-yjpdj7s1.js} +3 -3
  11. package/dist/{boot-seeds-yr00k13d.js → boot-seeds-5cm6ambd.js} +4 -4
  12. package/dist/{boxd-vdmfssd9.js → boxd-nv507va8.js} +1 -1
  13. package/dist/{claude-adapter-qta1f1xn.js → claude-adapter-fn287zmm.js} +5 -4
  14. package/dist/{claude-managed-setup-sc6j4dm0.js → claude-managed-setup-wtdz2mj2.js} +1 -1
  15. package/dist/{claude-sdk-session-zgrz6yvc.js → claude-sdk-session-x91kqyhm.js} +8288 -8224
  16. package/dist/{cli-wp9sp1qb.js → cli-08bmz9z9.js} +1 -1
  17. package/dist/{cli-yy3rhsdw.js → cli-1c6tzt8g.js} +7 -7
  18. package/dist/{cli-q0k1w5zd.js → cli-35rsp8ye.js} +1 -1
  19. package/dist/{cli-xnrwazav.js → cli-3fg0bdcv.js} +1 -1
  20. package/dist/{cli-89knwags.js → cli-5b456bpf.js} +2 -2
  21. package/dist/{cli-drr5v6av.js → cli-5jnhv72d.js} +1 -1
  22. package/dist/{cli-dxae2yg7.js → cli-5zx699j9.js} +2 -2
  23. package/dist/{cli-0at8w34w.js → cli-6g0hb4cp.js} +8 -8
  24. package/dist/{cli-e3r2neck.js → cli-6pfd54vx.js} +5 -5
  25. package/dist/{cli-bsn8nhrq.js → cli-6vcp76qk.js} +3 -3
  26. package/dist/{cli-ekwks2vs.js → cli-72v799xn.js} +1 -1
  27. package/dist/cli-82j36f2m.js +45 -0
  28. package/dist/{cli-yx4kfngt.js → cli-8305gbq0.js} +29 -16
  29. package/dist/{cli-4necwtsv.js → cli-8sckt74b.js} +8 -8
  30. package/dist/{cli-vvpx3gsx.js → cli-95jzxcp3.js} +1 -1
  31. package/dist/{cli-hr2e2fft.js → cli-adeegh7d.js} +7 -7
  32. package/dist/{cli-m48g6p95.js → cli-afkqkrtw.js} +3 -3
  33. package/dist/{cli-0qatpy8q.js → cli-ayayvfg4.js} +24 -4
  34. package/dist/{cli-bqt1mptt.js → cli-az48n0nr.js} +4 -4
  35. package/dist/{cli-zm72anhg.js → cli-bfv7vdg6.js} +9 -9
  36. package/dist/{cli-hgaazk69.js → cli-caj33vcq.js} +5 -5
  37. package/dist/{cli-3ypk9vk1.js → cli-cb2a8pna.js} +1 -1
  38. package/dist/{cli-waqbxg08.js → cli-cppkf404.js} +17 -17
  39. package/dist/{cli-yn4kxs06.js → cli-ddaanqkd.js} +4 -4
  40. package/dist/{cli-386tyxxg.js → cli-e0kmphd6.js} +2 -2
  41. package/dist/{cli-54t00gt8.js → cli-e46hg0xw.js} +1 -1
  42. package/dist/{cli-jm2vfpfd.js → cli-e5bzrn01.js} +1 -1
  43. package/dist/{cli-436532ck.js → cli-excnnjg2.js} +165 -153
  44. package/dist/{cli-71ptav7x.js → cli-ferkkrg9.js} +1 -1
  45. package/dist/{cli-vpf89f34.js → cli-fmjd0t1y.js} +3 -3
  46. package/dist/{cli-pd7vagab.js → cli-fyt2g4wd.js} +3 -3
  47. package/dist/{cli-gdhpcbhf.js → cli-g08zdaec.js} +1 -1
  48. package/dist/{cli-ehq736cn.js → cli-g7s47cc5.js} +4 -4
  49. package/dist/{cli-svj5090z.js → cli-gz6q4eve.js} +3 -3
  50. package/dist/{cli-8snvgs5r.js → cli-je518txm.js} +10 -10
  51. package/dist/{cli-rmmmrjkd.js → cli-jtjtabxe.js} +1 -1
  52. package/dist/{cli-611a1294.js → cli-k0wwfqbg.js} +18 -1
  53. package/dist/{cli-es6va8jk.js → cli-k1nje3v3.js} +38 -43
  54. package/dist/{cli-p5gp8pcx.js → cli-k8196sh2.js} +6 -6
  55. package/dist/{cli-nwj0ee2w.js → cli-k899ehvh.js} +2 -2
  56. package/dist/{cli-decfb6v8.js → cli-m0da8j35.js} +23 -9
  57. package/dist/{cli-he9wchme.js → cli-mkk9rnzz.js} +4 -4
  58. package/dist/{cli-nhrvpaj7.js → cli-n6bv12jn.js} +510 -4
  59. package/dist/{cli-8bc1w0tw.js → cli-nmzhp1b5.js} +14 -12
  60. package/dist/{cli-0yv5z2pg.js → cli-p82cnnjq.js} +1 -1
  61. package/dist/{cli-c60vetmm.js → cli-pc6n7fre.js} +1 -1
  62. package/dist/{cli-xds5f77d.js → cli-pjctyea3.js} +2 -2
  63. package/dist/{cli-xbbndvjy.js → cli-pq73h5mz.js} +3 -3
  64. package/dist/{cli-aa6yxc7m.js → cli-pz4rk021.js} +1 -1
  65. package/dist/{cli-xnqgpshy.js → cli-q3tkegby.js} +1 -1
  66. package/dist/cli-qghe0h66.js +67 -0
  67. package/dist/{cli-zbbwez0r.js → cli-qh4d4tvk.js} +4 -4
  68. package/dist/{cli-w6dt9ged.js → cli-rtt8g4v9.js} +1 -1
  69. package/dist/{cli-1h3wcpbw.js → cli-snpj5zbj.js} +2 -2
  70. package/dist/{cli-a7v854rf.js → cli-tgrv9cjx.js} +263 -12
  71. package/dist/{cli-faxe6thg.js → cli-vz22fyqv.js} +186 -54
  72. package/dist/{cli-k2gzwsj2.js → cli-wk5yrfwd.js} +160 -26
  73. package/dist/{cli-shpbx5ee.js → cli-ws19768n.js} +1641 -49
  74. package/dist/{cli-70r77n04.js → cli-xae4g51r.js} +1 -1
  75. package/dist/{cli-kqdg1bsb.js → cli-yndmfxb3.js} +2 -2
  76. package/dist/{cli-bjb3z51z.js → cli-yyj3j5m4.js} +2 -2
  77. package/dist/cli.js +21 -21
  78. package/dist/{cloudflare-workers-ai-system-one-bm60fjm0.js → cloudflare-workers-ai-system-one-ef2a980q.js} +2 -2
  79. package/dist/{codex-adapter-ayd1fb6h.js → codex-adapter-cf2yxe9m.js} +3 -2
  80. package/dist/{codex-hook-9efm2x1m.js → codex-hook-a0c6g6t6.js} +1 -1
  81. package/dist/{codex-session-runner-jesa32xc.js → codex-session-runner-6vfzdgbd.js} +3 -2
  82. package/dist/{commands-hanewgf2.js → commands-t3mfy7vn.js} +3 -3
  83. package/dist/{controller-dt1n3c1q.js → controller-q7xrbaz0.js} +3 -3
  84. package/dist/{controllers-connect-xx8x64n5.js → controllers-connect-c6nm70kg.js} +19 -19
  85. package/dist/{cursor-adapter-9s4dwwdw.js → cursor-adapter-ftd81ga8.js} +1 -1
  86. package/dist/{db-3vttcbv4.js → db-dk572x25.js} +3 -3
  87. package/dist/{db-9dv0g1ab.js → db-vemtpmcc.js} +4 -2
  88. package/dist/{dispatcher-tx9hd1sv.js → dispatcher-kh7ecxh9.js} +17 -17
  89. package/dist/{dsh-adapter-007y4ejs.js → dsh-adapter-v8628r89.js} +1 -1
  90. package/dist/{e2b-we6hs6q5.js → e2b-fr12yccx.js} +1 -1
  91. package/dist/{e2b-a19d28rz.js → e2b-x6ywzak3.js} +1 -1
  92. package/dist/{easter-egg-3d-rgbrqb8s.js → easter-egg-3d-nenw4x63.js} +1 -1
  93. package/dist/{embedding-space-ny1e2940.js → embedding-space-0jepb239.js} +6 -6
  94. package/dist/{embeddings-2t386t13.js → embeddings-xxt49yxg.js} +1 -1
  95. package/dist/{execute-pksh0ceh.js → execute-1mhw6e4x.js} +1 -1
  96. package/dist/{external-channel-phgmhmd7.js → external-channel-55v12e60.js} +2 -2
  97. package/dist/{fx-adapter-fy8rr921.js → fx-adapter-bs8wqrk5.js} +6 -5
  98. package/dist/{google-generative-ai-8y3m3k4b.js → google-generative-ai-v94hr7h0.js} +5 -5
  99. package/dist/{google-vertex-w3v98n7b.js → google-vertex-g7vr6cf8.js} +5 -5
  100. package/dist/{grok-adapter-q0abvpaj.js → grok-adapter-gpjqmkcq.js} +6 -5
  101. package/dist/handlers-zxmp1ta4.js +32 -0
  102. package/dist/{heartbeat-kadyek8p.js → heartbeat-k42svnr0.js} +20 -20
  103. package/dist/{hook-9k551xnj.js → hook-114m7hap.js} +4 -3
  104. package/dist/{hook-5zs3msf6.js → hook-6nphweh0.js} +24 -9
  105. package/dist/{http-mhz9vw1f.js → http-r8cc4wz7.js} +1025 -173
  106. package/dist/index-a8phxqnk.js +37 -0
  107. package/dist/{index-vdygbq10.js → index-e3s8wmxy.js} +1 -1
  108. package/dist/{index-q361cg2f.js → index-fpk4bcd9.js} +1 -1
  109. package/dist/index-k6h00t4c.js +30 -0
  110. package/dist/{index-rvr00sg7.js → index-nh3wyqdt.js} +1017 -574
  111. package/dist/index-xrz7te8h.js +33 -0
  112. package/dist/{keepalive-w56f32cg.js → keepalive-x060nt9p.js} +3 -3
  113. package/dist/lead-956sd2yc.js +71 -0
  114. package/dist/{maintenance-7mdgxcea.js → maintenance-2xxfexhf.js} +1 -1
  115. package/dist/{mistral-conversations-4pmwj1c0.js → mistral-conversations-3gjpdb4b.js} +4 -4
  116. package/dist/{oauth-refresh-sweep-29txy9vk.js → oauth-refresh-sweep-fckc4ar5.js} +2 -2
  117. package/dist/{onboard-kpsrkarj.js → onboard-zc48j237.js} +3 -3
  118. package/dist/{openai-codex-responses-44j573nm.js → openai-codex-responses-8pbxq9h5.js} +5 -5
  119. package/dist/{openai-completions-a4gee2a8.js → openai-completions-rm00s912.js} +4 -4
  120. package/dist/{openai-decisions-w4qkrcar.js → openai-decisions-8v957r2r.js} +1 -1
  121. package/dist/{openai-responses-rbp6h5kr.js → openai-responses-agxpf96k.js} +5 -5
  122. package/dist/{opencode-adapter-j25vm3rr.js → opencode-adapter-r690h1cr.js} +4 -3
  123. package/dist/{otel-impl-6kkct7a8.js → otel-impl-r5xbh81q.js} +4 -4
  124. package/dist/{pi-mono-adapter-exhkzhn2.js → pi-mono-adapter-c7v8sdec.js} +7 -6
  125. package/dist/{pricing-refresh-n2x7jh6k.js → pricing-refresh-3pmre11v.js} +3 -3
  126. package/dist/{rbac-roles-81ypx6es.js → rbac-roles-3vbshwsb.js} +1 -1
  127. package/dist/{rbac-roles-b5htkjby.js → rbac-roles-910mmkgz.js} +2 -2
  128. package/dist/{render-v2-qn6jmpk4.js → render-v2-pxykkbab.js} +3 -3
  129. package/dist/{resume-wd30wx23.js → resume-adda0bwy.js} +6 -6
  130. package/dist/{runtime-4hsg7h60.js → runtime-fnbm7stk.js} +1 -1
  131. package/dist/{session-access-5qvfevhk.js → session-access-2fvamrdc.js} +4 -4
  132. package/dist/{session-source-backfill-n1czavbr.js → session-source-backfill-08xvv0sm.js} +2 -2
  133. package/dist/{setup-dnb56qy5.js → setup-1aqmvmh1.js} +1 -1
  134. package/dist/{typesafe-system-one-5mavm259.js → typesafe-system-one-0bmqcxfg.js} +2 -2
  135. package/dist/{virtual-modules-76xxv9fs.js → virtual-modules-d2pjk9j1.js} +5 -5
  136. package/dist/{work-objects-4n21tfkm.js → work-objects-9s0yrm5j.js} +20 -20
  137. package/dist/{worker-follow-up-77hvzxww.js → worker-follow-up-3q78fqmr.js} +17 -17
  138. package/dist/worker-y15hy08h.js +71 -0
  139. package/openapi.json +197 -4
  140. package/package.json +5 -5
  141. package/src/apps/definition.ts +6 -5
  142. package/src/be/db/page-theme-tokens.ts +12 -0
  143. package/src/be/db/tasks/read.ts +9 -1
  144. package/src/be/db/tasks/write.ts +19 -0
  145. package/src/be/db-client.ts +107 -7
  146. package/src/be/db.ts +34 -2
  147. package/src/be/migrations/269_pages_design_system.sql +23 -0
  148. package/src/be/seed/schedules-seeder.ts +0 -10
  149. package/src/be/seed-scripts/catalog/catalog-report.inline.ts +2 -0
  150. package/src/be/seed-scripts/catalog/catalog-report.ts +2 -0
  151. package/src/be/seed-scripts/catalog/memory-eval.ts +2 -0
  152. package/src/be/seed-scripts/catalog/swarm-update-check.ts +150 -0
  153. package/src/be/seed-scripts/index.ts +9 -0
  154. package/src/be/seed-skills/bundled-files.generated.json +3 -3
  155. package/src/be/swarm-config-guard.ts +32 -0
  156. package/src/be/task-auto-title-listener.ts +127 -0
  157. package/src/commands/onboard/agent-fs-version.ts +1 -1
  158. package/src/commands/profile-sync.ts +151 -16
  159. package/src/commands/runner.ts +15 -7
  160. package/src/hooks/hook.ts +20 -9
  161. package/src/http/index.ts +3 -0
  162. package/src/http/pages-public.ts +93 -129
  163. package/src/http/pages.ts +94 -21
  164. package/src/pages/browser-sdk.ts +48 -21
  165. package/src/pages/color-literals.ts +115 -0
  166. package/src/pages/page-head.ts +766 -0
  167. package/src/pages/version.ts +3 -0
  168. package/src/providers/amp-adapter.ts +1 -1
  169. package/src/providers/codex-adapter.ts +1 -0
  170. package/src/providers/codex-app-server.ts +27 -1
  171. package/src/providers/pi-mono-extension.ts +30 -15
  172. package/src/tasks/follow-up-gate.ts +318 -0
  173. package/src/tasks/worker-follow-up.ts +21 -1
  174. package/src/tests/codex-app-server.test.ts +59 -0
  175. package/src/tests/codex-gateway-route.test.ts +50 -1
  176. package/src/tests/create-page-tool.test.ts +501 -0
  177. package/src/tests/db-client-busy-retry.test.ts +81 -0
  178. package/src/tests/db-task-read-contract.test.ts +1 -0
  179. package/src/tests/db-task-write-contract.test.ts +2 -0
  180. package/src/tests/db-tasks-read.test.ts +21 -0
  181. package/src/tests/fixtures/pages/head-v1.html +56 -0
  182. package/src/tests/follow-up-gate-shadow.test.ts +513 -0
  183. package/src/tests/identity-field-budget.test.ts +1 -1
  184. package/src/tests/internal-ai/credentials.test.ts +62 -0
  185. package/src/tests/internal-ai/task-title.test.ts +283 -0
  186. package/src/tests/merge-gate-detect-changes.test.ts +145 -0
  187. package/src/tests/page-proxy.test.ts +1 -1
  188. package/src/tests/page-session-dev-cookie.test.ts +188 -0
  189. package/src/tests/pages-frame-ancestors.test.ts +28 -1
  190. package/src/tests/pages-head-v2.test.ts +534 -0
  191. package/src/tests/pages-http.test.ts +330 -0
  192. package/src/tests/pages-public-html.test.ts +43 -0
  193. package/src/tests/pages-storage.test.ts +182 -0
  194. package/src/tests/pages-versioning.test.ts +72 -0
  195. package/src/tests/profile-sync-stale-writeback.test.ts +334 -0
  196. package/src/tests/profile-sync.test.ts +11 -15
  197. package/src/tests/scheduled-task-required-params-migration.test.ts +3 -1
  198. package/src/tests/script-connections.test.ts +2 -0
  199. package/src/tests/seed-registry.test.ts +28 -6
  200. package/src/tests/seed-schedules.test.ts +61 -8
  201. package/src/tests/seed-scripts.test.ts +142 -2
  202. package/src/tests/swarm-diff.test.ts +121 -2
  203. package/src/tests/task-auto-title-config-guard.test.ts +37 -0
  204. package/src/tests/task-auto-title-listener.test.ts +165 -0
  205. package/src/tests/theme-import.test.ts +758 -0
  206. package/src/tests/themes-page-theme.test.ts +155 -0
  207. package/src/tests/themes-presets.test.ts +172 -0
  208. package/src/tests/workflow-script-principal.test.ts +2 -1
  209. package/src/themes/classics.ts +949 -0
  210. package/src/themes/import.ts +420 -0
  211. package/src/themes/page-fields.ts +40 -0
  212. package/src/themes/page-theme.ts +102 -0
  213. package/src/themes/presets.ts +561 -0
  214. package/src/themes/tokens.ts +218 -0
  215. package/src/tools/app-upsert.ts +1 -1
  216. package/src/tools/create-page.ts +118 -12
  217. package/src/tools/utils.ts +33 -0
  218. package/src/types.ts +45 -3
  219. package/src/utils/constants.ts +19 -0
  220. package/src/utils/follow-up-gate-schedule-ids.ts +13 -0
  221. package/src/utils/internal-ai/credentials.ts +146 -93
  222. package/src/utils/internal-ai/index.ts +10 -0
  223. package/src/utils/internal-ai/models.ts +18 -0
  224. package/src/utils/internal-ai/task-title.ts +282 -0
  225. package/src/utils/page-session.ts +37 -0
  226. package/templates/schedules/daily-status-report/content.md +88 -2
  227. package/templates/schedules/daily-swarm-update-check/content.md +16 -40
  228. package/templates/skills/apps/SKILL.md +1 -1
  229. package/templates/skills/apps/content.md +1 -1
  230. package/templates/skills/heartbeat-runbook/content.md +1 -1
  231. package/templates/skills/pages/config.json +1 -1
  232. package/templates/skills/pages/content.md +539 -86
  233. package/templates/skills/pages/files/examples/annotated-pr.html +21 -12
  234. package/templates/skills/pages/files/examples/multiplayer-board.html +41 -41
  235. package/templates/skills/pages/files/examples/report-page.html +125 -124
  236. package/dist/cli-2pnswgh8.js +0 -189
  237. package/dist/handlers-by3sfxyx.js +0 -32
  238. package/dist/index-4f2pvxae.js +0 -37
  239. package/dist/index-98gz7tmp.js +0 -30
  240. package/dist/index-k08z2cak.js +0 -33
  241. package/dist/lead-enq35nqp.js +0 -70
  242. package/dist/worker-gg1576j3.js +0 -70
  243. package/templates/schedules/daily-workflow-health-audit/config.json +0 -19
  244. package/templates/schedules/daily-workflow-health-audit/content.md +0 -191
@@ -4,32 +4,41 @@
4
4
 
5
5
  No <script> import and no bundling: <swarm-diff>, <swarm-diff-jumps> and
6
6
  window.swarmUi.renderDiff are injected into every HTML page automatically.
7
- Each hunk gets id="swarm-diff-<file-slug>-<old_start>" so <swarm-diff-jumps>
8
- can build the jump list and external links can deep-link a specific hunk.
7
+
8
+ Each "text" is the code line WITHOUT its +, - or space marker: the
9
+ component draws the marker in its own column. old_lines counts the context
10
+ and deleted lines, and new_lines counts the context and added lines. Inside
11
+ the JSON, write < as \u003c and & as \u0026.
12
+
13
+ Each hunk gets id="swarm-diff-<slug>". The slug is <file>-<old_start> in
14
+ lowercase, with each run of characters other than a-z and 0-9 changed to
15
+ one "-". So src/foo.ts at old_start 10 gets id="swarm-diff-src-foo-ts-10".
16
+ <swarm-diff-jumps> builds its jump list from these ids, and external links
17
+ can deep-link a specific hunk.
9
18
  -->
10
19
  <html lang="en">
11
20
  <head>
12
21
  <meta charset="utf-8">
13
22
  <meta name="viewport" content="width=device-width, initial-scale=1">
14
- <title>PR #1234 — console.log cleanup</title>
23
+ <title>PR #1234: console.log cleanup</title>
15
24
  </head>
16
25
  <body>
17
- <h1>PR #1234 — cleanup raw <code>console.log</code> calls</h1>
26
+ <h1>PR #1234: cleanup raw <code>console.log</code> calls</h1>
18
27
  <p>Replaces ad-hoc logging with the project logger.</p>
19
28
 
20
29
  <swarm-diff-jumps></swarm-diff-jumps>
21
30
 
22
31
  <swarm-diff file="src/foo.ts" base-sha="abc123" head-sha="def456">
23
32
  { "hunks": [
24
- { "old_start": 10, "old_lines": 3, "new_start": 10, "new_lines": 4,
33
+ { "old_start": 10, "old_lines": 2, "new_start": 10, "new_lines": 3,
25
34
  "lines": [
26
- { "type": "context", "text": " const x = 1;" },
27
- { "type": "del", "text": "- console.log(x);" },
28
- { "type": "add", "text": "+ logger.info({ x });" },
29
- { "type": "add", "text": "+ return x;" }
35
+ { "type": "context", "text": "export function load(id) {" },
36
+ { "type": "del", "text": " console.log(id);" },
37
+ { "type": "add", "text": " logger.info({ id });" },
38
+ { "type": "add", "text": " return cache.get(id);" }
30
39
  ],
31
40
  "annotations": [
32
- { "line": 12, "severity": "warn", "text": "Avoid raw console.log" }
41
+ { "line": 12, "severity": "warn", "text": "Returns undefined on a cache miss" }
33
42
  ]
34
43
  }
35
44
  ] }
@@ -39,8 +48,8 @@
39
48
  { "hunks": [
40
49
  { "old_start": 5, "old_lines": 1, "new_start": 5, "new_lines": 1,
41
50
  "lines": [
42
- { "type": "del", "text": "- console.error('boom');" },
43
- { "type": "add", "text": "+ logger.error('boom');" }
51
+ { "type": "del", "text": "console.error('boom');" },
52
+ { "type": "add", "text": "logger.error('boom');" }
44
53
  ]
45
54
  }
46
55
  ] }
@@ -6,9 +6,9 @@
6
6
  <title>Shared board</title>
7
7
  <style>
8
8
  :root {
9
- color: #252522;
10
- background: #f7f6f3;
11
- font-family: "SF Pro Display", "Helvetica Neue", ui-sans-serif, system-ui, sans-serif;
9
+ color: var(--color-foreground);
10
+ background: var(--color-background);
11
+ font-family: var(--font-sans);
12
12
  font-synthesis: none;
13
13
  }
14
14
 
@@ -18,24 +18,24 @@
18
18
  margin: 0;
19
19
  min-width: 320px;
20
20
  padding: 0;
21
- background: #f7f6f3;
22
- color: #252522;
23
- font-family: "SF Pro Display", "Helvetica Neue", ui-sans-serif, system-ui, sans-serif;
21
+ background: var(--color-background);
22
+ color: var(--color-foreground);
23
+ font-family: var(--font-sans);
24
24
  }
25
25
 
26
26
  button, input, textarea { font: inherit; }
27
27
 
28
28
  button {
29
- border: 1px solid #252522;
30
- border-radius: 8px;
31
- background: #252522;
32
- color: #fff;
29
+ border: 1px solid var(--color-primary);
30
+ border-radius: var(--radius-md);
31
+ background: var(--color-primary);
32
+ color: var(--color-primary-foreground);
33
33
  cursor: pointer;
34
34
  padding: 10px 14px;
35
35
  }
36
36
 
37
- button:hover { background: #3c3c37; }
38
- button:focus-visible, input:focus-visible, textarea:focus-visible { outline: 3px solid #e1a52c; outline-offset: 2px; }
37
+ button:hover { background: color-mix(in oklab, var(--color-primary) 90%, transparent); }
38
+ button:focus-visible, input:focus-visible, textarea:focus-visible { outline: 3px solid var(--color-ring); outline-offset: 2px; }
39
39
  button:disabled { cursor: not-allowed; opacity: .5; }
40
40
 
41
41
  .page { max-width: 1120px; margin: 0 auto; padding: 32px 24px 56px; }
@@ -45,26 +45,26 @@
45
45
  align-items: flex-start;
46
46
  justify-content: space-between;
47
47
  gap: 24px;
48
- border-bottom: 1px solid #d9d7d0;
48
+ border-bottom: 1px solid var(--color-border);
49
49
  padding-bottom: 24px;
50
50
  }
51
51
 
52
52
  h1, h2, p { margin-top: 0; }
53
53
  h1 { font-size: clamp(2rem, 5vw, 3rem); letter-spacing: -.04em; margin-bottom: 8px; }
54
54
  h2 { font-size: 1.15rem; letter-spacing: -.02em; margin-bottom: 16px; }
55
- .lede, .muted { color: #67665f; }
55
+ .lede, .muted { color: var(--color-muted-foreground); }
56
56
  .lede { max-width: 46rem; margin-bottom: 0; }
57
57
 
58
58
  .viewer {
59
59
  min-width: 170px;
60
- border: 1px solid #d9d7d0;
61
- border-radius: 8px;
62
- background: #fff;
60
+ border: 1px solid var(--color-border);
61
+ border-radius: var(--radius-md);
62
+ background: var(--color-card);
63
63
  padding: 12px;
64
64
  }
65
65
 
66
66
  .eyebrow {
67
- color: #67665f;
67
+ color: var(--color-muted-foreground);
68
68
  display: block;
69
69
  font-size: .72rem;
70
70
  font-weight: 700;
@@ -76,28 +76,28 @@
76
76
  .viewer-name { font-weight: 700; overflow-wrap: anywhere; }
77
77
 
78
78
  .notice {
79
- border: 1px solid #d9d7d0;
80
- border-left: 4px solid #e1a52c;
81
- border-radius: 8px;
82
- background: #fffdf8;
79
+ border: 1px solid var(--color-border);
80
+ border-left: 4px solid var(--color-primary);
81
+ border-radius: var(--radius-md);
82
+ background: var(--color-card);
83
83
  margin: 24px 0;
84
84
  min-height: 47px;
85
85
  padding: 12px 14px;
86
86
  }
87
87
 
88
- .notice[data-tone="error"] { border-left-color: #a34736; background: #fff9f7; }
89
- .notice[data-tone="stale"] { border-left-color: #e1a52c; background: #fffdf8; }
88
+ .notice[data-tone="error"] { border-left-color: var(--color-status-error); background: color-mix(in oklab, var(--color-status-error) 10%, var(--color-card)); }
89
+ .notice[data-tone="stale"] { border-left-color: var(--color-status-warning); background: color-mix(in oklab, var(--color-status-warning) 10%, var(--color-card)); }
90
90
  .notice:empty { display: none; }
91
91
 
92
92
  .grid { display: grid; gap: 24px; grid-template-columns: minmax(0, 1.65fr) minmax(260px, .85fr); }
93
- .panel { border: 1px solid #d9d7d0; border-radius: 12px; background: #fff; padding: 20px; }
93
+ .panel { border: 1px solid var(--color-border); border-radius: var(--radius-xl); background: var(--color-card); padding: 20px; }
94
94
  .panel + .panel { margin-top: 24px; }
95
95
 
96
96
  .add-row { display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr) auto; margin-bottom: 16px; }
97
97
  input, textarea {
98
- border: 1px solid #bdbbb4;
99
- border-radius: 8px;
100
- background: #fff;
98
+ border: 1px solid var(--color-input);
99
+ border-radius: var(--radius-md);
100
+ background: var(--color-card);
101
101
  color: inherit;
102
102
  padding: 10px 12px;
103
103
  width: 100%;
@@ -107,10 +107,10 @@
107
107
  label { display: block; font-size: .88rem; font-weight: 650; margin-bottom: 8px; }
108
108
 
109
109
  .cards, .peers { list-style: none; margin: 0; padding: 0; }
110
- .cards { border-top: 1px solid #e7e5df; }
110
+ .cards { border-top: 1px solid var(--color-border-subtle); }
111
111
  .card {
112
112
  align-items: center;
113
- border-bottom: 1px solid #e7e5df;
113
+ border-bottom: 1px solid var(--color-border-subtle);
114
114
  display: flex;
115
115
  gap: 12px;
116
116
  justify-content: space-between;
@@ -119,31 +119,31 @@
119
119
 
120
120
  .card-title { font-weight: 650; overflow-wrap: anywhere; }
121
121
  .card-status {
122
- background: #fff;
123
- border-color: #bdbbb4;
124
- color: #252522;
122
+ background: var(--color-card);
123
+ border-color: var(--color-input);
124
+ color: var(--color-foreground);
125
125
  flex: 0 0 auto;
126
126
  font-size: .82rem;
127
127
  padding: 7px 10px;
128
128
  }
129
129
 
130
- .card-status[data-done="true"] { background: #f6efd9; border-color: #c89429; }
131
- .empty { color: #67665f; padding: 16px 0 4px; }
132
- .agent-note { background: #f7f6f3; border-radius: 8px; min-height: 46px; padding: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
133
- .agent-note:empty::before { color: #67665f; content: "No note yet. A server-side agent can write one here."; }
130
+ .card-status[data-done="true"] { background: var(--color-status-success); border-color: var(--color-status-success-strong); color: var(--color-status-success-foreground); }
131
+ .empty { color: var(--color-muted-foreground); padding: 16px 0 4px; }
132
+ .agent-note { background: var(--color-muted); border-radius: var(--radius-md); min-height: 46px; padding: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
133
+ .agent-note:empty::before { color: var(--color-muted-foreground); content: "No note yet. A server-side agent can write one here."; }
134
134
 
135
135
  .peers { display: grid; gap: 8px; }
136
136
  .peer {
137
- border: 1px solid #e7e5df;
138
- border-radius: 8px;
137
+ border: 1px solid var(--color-border-subtle);
138
+ border-radius: var(--radius-md);
139
139
  display: grid;
140
140
  gap: 3px;
141
141
  padding: 10px;
142
142
  }
143
143
 
144
144
  .peer-name { font-weight: 650; overflow-wrap: anywhere; }
145
- .room-meta { color: #67665f; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .75rem; margin: 0 0 16px; }
146
- .save-state { color: #67665f; font-size: .82rem; margin: 8px 0 0; min-height: 1.2em; }
145
+ .room-meta { color: var(--color-muted-foreground); font-family: var(--font-mono); font-size: .75rem; margin: 0 0 16px; }
146
+ .save-state { color: var(--color-muted-foreground); font-size: .82rem; margin: 8px 0 0; min-height: 1.2em; }
147
147
 
148
148
  @media (max-width: 720px) {
149
149
  .page { padding: 24px 16px 40px; }
@@ -1,12 +1,11 @@
1
1
  <!doctype html>
2
2
  <!--
3
- Reference report page — minimalist taste baseline + report density layer.
3
+ Reference report page for the swarm design system (designVersion 2).
4
4
 
5
- Copy this as the starting point for any dense report/dashboard page, then
6
- replace the content. The CSS already encodes the baseline documented in the
7
- `pages` skill: warm monochrome canvas, single-column 1120px spine, 8/12/16/
8
- 24/32/48/72 spacing scale, tabular numerals, flat bordered cards, table
9
- horizontal scroll on mobile, and no decorative gradients or nested cards.
5
+ Copy this as the starting point for a dense report or dashboard page, then
6
+ replace the content. It uses only the swarm-* primitives, the theme tokens,
7
+ and a few Tailwind layout utilities. It has zero color literals, so it
8
+ follows the viewer's theme and dark mode inside the dashboard.
10
9
 
11
10
  Publish with:
12
11
  create_page({
@@ -23,134 +22,95 @@
23
22
  <meta charset="utf-8">
24
23
  <meta name="viewport" content="width=device-width, initial-scale=1">
25
24
  <title>Q2 SEO Performance</title>
26
- <style>
27
- :root {
28
- color-scheme: light;
29
- --bg: #f6f4f0;
30
- --panel: #ffffff;
31
- --ink: #18181b;
32
- --muted: #62646a;
33
- --line: #dedbd2;
34
- --accent: #2563eb;
35
- --danger: #b42318;
36
- --warn: #b54708;
37
- --ok: #067647;
38
- --radius: 8px;
39
- --shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
40
- }
41
- * { box-sizing: border-box; }
42
- body {
43
- margin: 0;
44
- background: var(--bg);
45
- color: var(--ink);
46
- font-family: "SF Pro Display", "Geist Sans", "Helvetica Neue", ui-sans-serif, system-ui, sans-serif;
47
- font-size: 16px;
48
- line-height: 1.55;
49
- }
50
- main {
51
- width: min(1120px, calc(100% - 32px));
52
- margin: 0 auto;
53
- padding: 48px 0 72px;
54
- }
55
- header { margin-bottom: 32px; }
56
- .eyebrow {
57
- margin: 0 0 8px;
58
- color: var(--muted);
59
- font-size: 13px;
60
- font-weight: 700;
61
- letter-spacing: 0.08em;
62
- text-transform: uppercase;
63
- }
64
- h1 {
65
- margin: 0;
66
- max-width: 780px;
67
- font-size: clamp(2rem, 4vw, 3rem);
68
- line-height: 1.05;
69
- letter-spacing: 0;
70
- }
71
- .lede {
72
- max-width: 760px;
73
- margin: 16px 0 0;
74
- color: var(--muted);
75
- font-size: 18px;
76
- }
77
- .metrics {
78
- display: grid;
79
- grid-template-columns: repeat(4, minmax(0, 1fr));
80
- gap: 12px;
81
- margin: 32px 0;
82
- }
83
- .metric, .section {
84
- background: var(--panel);
85
- border: 1px solid var(--line);
86
- border-radius: var(--radius);
87
- box-shadow: var(--shadow);
88
- }
89
- .metric { padding: 18px; }
90
- .metric strong {
91
- display: block;
92
- font-size: 32px;
93
- line-height: 1;
94
- font-variant-numeric: tabular-nums;
95
- }
96
- .metric span {
97
- display: block;
98
- margin-top: 8px;
99
- color: var(--muted);
100
- font-size: 13px;
101
- font-weight: 650;
102
- }
103
- .section {
104
- margin-top: 18px;
105
- padding: 24px;
106
- }
107
- h2 { margin: 0 0 12px; font-size: 24px; line-height: 1.2; }
108
- h3 { margin: 0 0 8px; font-size: 17px; line-height: 1.3; }
109
- p { margin: 0 0 12px; }
110
- .table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
111
- table { width: 100%; border-collapse: collapse; min-width: 640px; }
112
- th, td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
113
- th { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; }
114
- td { font-size: 14px; font-variant-numeric: tabular-nums; }
115
- code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
116
- details { margin-top: 24px; }
117
- summary { cursor: pointer; font-weight: 700; }
118
- pre { overflow: auto; padding: 16px; background: #111827; color: #f9fafb; border-radius: var(--radius); }
119
- @media (max-width: 760px) {
120
- main { width: min(100% - 24px, 1120px); padding-top: 32px; }
121
- .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
122
- .section { padding: 18px; }
123
- }
124
- @media (max-width: 520px) {
125
- .metrics { grid-template-columns: 1fr; }
126
- .lede { font-size: 16px; }
127
- }
128
- </style>
129
25
  </head>
130
26
  <body>
131
- <main>
27
+ <main class="swarm-page">
132
28
  <header>
133
- <p class="eyebrow">Generated 2026-06-04</p>
29
+ <p class="swarm-eyebrow">Search Console · Generated 2026-06-04</p>
134
30
  <h1>Q2 SEO Performance</h1>
135
- <p class="lede">Organic traffic grew sharply, but the next gains depend on fixing thin page metadata and publishing three high-intent pillar pages.</p>
31
+ <p class="swarm-lede">Organic clicks grew 50% this quarter. The next gains depend on fixing thin page metadata and on three high-intent pillar pages.</p>
32
+ <span class="swarm-badge" data-tone="success" data-dot>On track</span>
136
33
  </header>
137
34
 
138
- <section class="metrics" aria-label="Key metrics">
139
- <div class="metric"><strong>18.6k</strong><span>Organic clicks</span></div>
140
- <div class="metric"><strong>+50%</strong><span>Quarter over quarter</span></div>
141
- <div class="metric"><strong>23</strong><span>Metadata fixes</span></div>
142
- <div class="metric"><strong>3</strong><span>Priority pages</span></div>
35
+ <section class="swarm-metrics" aria-label="Key metrics">
36
+ <div class="swarm-metric">
37
+ <div class="swarm-metric-value">18.6k</div>
38
+ <div class="swarm-metric-label">Organic clicks</div>
39
+ </div>
40
+ <div class="swarm-metric" data-tone="success">
41
+ <div class="swarm-metric-value">+50%</div>
42
+ <div class="swarm-metric-label">Quarter over quarter</div>
43
+ </div>
44
+ <div class="swarm-metric" data-tone="warning">
45
+ <div class="swarm-metric-value">23</div>
46
+ <div class="swarm-metric-label">Metadata fixes</div>
47
+ </div>
48
+ <div class="swarm-metric">
49
+ <div class="swarm-metric-value">3</div>
50
+ <div class="swarm-metric-label">Priority pages</div>
51
+ </div>
143
52
  </section>
144
53
 
145
- <section class="section">
146
- <h2>Summary</h2>
147
- <p>Start with the conclusion. Add tables only after the reader understands what changed and what to do next.</p>
148
- <div class="table-wrap">
149
- <table>
150
- <thead><tr><th>Metric</th><th>Q1</th><th>Q2</th><th>Change</th></tr></thead>
151
- <tbody><tr><td>Organic clicks</td><td>12,400</td><td>18,600</td><td>+50%</td></tr></tbody>
54
+ <section class="swarm-section" aria-labelledby="findings-heading">
55
+ <h2 id="findings-heading">Findings</h2>
56
+ <div class="swarm-callout" data-tone="warning">
57
+ <strong>Thin metadata caps growth.</strong> 23 ranking pages share a generic title and description. Fix them before new content ships.
58
+ </div>
59
+ <div class="swarm-callout">
60
+ <strong>One post drives the growth.</strong> The agent swarms post brought about a quarter of the new clicks.
61
+ </div>
62
+ </section>
63
+
64
+ <section class="swarm-section" aria-labelledby="pages-heading">
65
+ <h2 id="pages-heading">Top pages</h2>
66
+ <div class="swarm-toolbar">
67
+ <input class="swarm-input" id="page-filter" type="search" placeholder="Filter pages" aria-label="Filter pages">
68
+ <div class="swarm-segmented" role="group" aria-label="Status">
69
+ <button type="button" data-status-filter="all" aria-pressed="true">All</button>
70
+ <button type="button" data-status-filter="fix" aria-pressed="false">Needs fix</button>
71
+ </div>
72
+ <button class="swarm-button" id="filter-reset" type="button">Reset</button>
73
+ </div>
74
+ <div class="swarm-table-wrap">
75
+ <table class="swarm-table" id="pages-table">
76
+ <thead>
77
+ <tr><th>Page</th><th>Status</th><th class="num">Q1 clicks</th><th class="num">Q2 clicks</th><th class="num">Change</th></tr>
78
+ </thead>
79
+ <tbody>
80
+ <tr data-status="ok"><td class="nowrap">/pricing</td><td><span class="swarm-badge" data-tone="success">Healthy</span></td><td class="num">4,100</td><td class="num">6,900</td><td class="num">+68%</td></tr>
81
+ <tr data-status="fix"><td class="nowrap">/docs/install</td><td><span class="swarm-badge" data-tone="warning">Thin title</span></td><td class="num">3,200</td><td class="num">3,350</td><td class="num">+5%</td></tr>
82
+ <tr data-status="ok"><td class="nowrap">/blog/agent-swarms</td><td><span class="swarm-badge" data-tone="success">Healthy</span></td><td class="num">1,500</td><td class="num">3,100</td><td class="num">+107%</td></tr>
83
+ <tr data-status="fix"><td class="nowrap">/integrations/slack</td><td><span class="swarm-badge" data-tone="error">No description</span></td><td class="num">1,900</td><td class="num">1,700</td><td class="num text-status-error-strong">-11%</td></tr>
84
+ <tr data-status="review"><td class="nowrap">/changelog</td><td><span class="swarm-badge">Not reviewed</span></td><td class="num">400</td><td class="num">1,150</td><td class="num">+188%</td></tr>
85
+ </tbody>
152
86
  </table>
153
87
  </div>
88
+ <p class="text-muted-foreground" id="filter-empty" hidden>No pages match the filter.</p>
89
+ </section>
90
+
91
+ <section class="swarm-section" aria-labelledby="actions-heading">
92
+ <h2 id="actions-heading">Next actions</h2>
93
+ <div class="grid gap-4 md:grid-cols-2">
94
+ <article class="swarm-panel">
95
+ <h3>Fix thin metadata</h3>
96
+ <dl class="swarm-kv">
97
+ <dt>Owner</dt><dd>Content team</dd>
98
+ <dt>Pages</dt><dd>23</dd>
99
+ <dt>Due</dt><dd>2026-07-15</dd>
100
+ </dl>
101
+ </article>
102
+ <article class="swarm-panel">
103
+ <h3>Publish three pillar pages</h3>
104
+ <dl class="swarm-kv">
105
+ <dt>Owner</dt><dd>Growth team</dd>
106
+ <dt>Topics</dt><dd>Agent orchestration, task routing, swarm costs</dd>
107
+ <dt>Due</dt><dd>2026-08-01</dd>
108
+ </dl>
109
+ </article>
110
+ </div>
111
+ <div class="mt-4">
112
+ <a class="swarm-button" data-variant="primary" href="https://search.google.com/search-console">Open Search Console</a>
113
+ </div>
154
114
  </section>
155
115
 
156
116
  <details>
@@ -158,5 +118,46 @@
158
118
  <pre>{ "source": "search-console", "range": "2026-04-01/2026-06-30" }</pre>
159
119
  </details>
160
120
  </main>
121
+
122
+ <script>
123
+ (() => {
124
+ const filter = document.getElementById("page-filter");
125
+ const reset = document.getElementById("filter-reset");
126
+ const empty = document.getElementById("filter-empty");
127
+ const statusButtons = document.querySelectorAll("[data-status-filter]");
128
+ const rows = document.querySelectorAll("#pages-table tbody tr");
129
+ let status = "all";
130
+
131
+ function applyFilter() {
132
+ const query = filter.value.trim().toLowerCase();
133
+ let shown = 0;
134
+ for (const row of rows) {
135
+ const visible =
136
+ row.textContent.toLowerCase().includes(query) &&
137
+ (status === "all" || row.dataset.status === status);
138
+ row.style.display = visible ? "" : "none";
139
+ if (visible) shown += 1;
140
+ }
141
+ empty.hidden = shown > 0;
142
+ }
143
+
144
+ function setStatus(next) {
145
+ status = next;
146
+ for (const button of statusButtons) {
147
+ button.setAttribute("aria-pressed", String(button.dataset.statusFilter === next));
148
+ }
149
+ applyFilter();
150
+ }
151
+
152
+ for (const button of statusButtons) {
153
+ button.addEventListener("click", () => setStatus(button.dataset.statusFilter));
154
+ }
155
+ filter.addEventListener("input", applyFilter);
156
+ reset.addEventListener("click", () => {
157
+ filter.value = "";
158
+ setStatus("all");
159
+ });
160
+ })();
161
+ </script>
161
162
  </body>
162
163
  </html>