@desplega.ai/agent-swarm 2.7.5 → 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.
- package/dist/{acp-adapter-g3ads55s.js → acp-adapter-7b4vk3h5.js} +5 -4
- package/dist/{actions-zwfykqqk.js → actions-3tt153af.js} +18 -17
- package/dist/{amp-adapter-z3s0ssdt.js → amp-adapter-njpts0yr.js} +1 -1
- package/dist/{anthropic-messages-x4q6rfq5.js → anthropic-messages-xey2skwx.js} +7 -7
- package/dist/{app-vmp4fgep.js → app-nky4378f.js} +3 -3
- package/dist/{assistant-vwde653f.js → assistant-jnb669pa.js} +24 -22
- package/dist/{azure-openai-responses-s1w5n70z.js → azure-openai-responses-26t7j9ra.js} +5 -5
- package/dist/{boot-reembed-375t7tbk.js → boot-reembed-9mgvaztt.js} +1 -1
- package/dist/{boot-reembed-gq9rcpnj.js → boot-reembed-qs2djdej.js} +1 -1
- package/dist/{boot-scrub-sweep-nd938kyf.js → boot-scrub-sweep-yjpdj7s1.js} +3 -3
- package/dist/{boot-seeds-aykx51v3.js → boot-seeds-5cm6ambd.js} +4 -4
- package/dist/{boxd-k1j26g3h.js → boxd-nv507va8.js} +5 -5
- package/dist/{claude-adapter-8j4hm099.js → claude-adapter-fn287zmm.js} +5 -4
- package/dist/{claude-managed-setup-0wyynpn1.js → claude-managed-setup-wtdz2mj2.js} +1 -1
- package/dist/{claude-sdk-session-q6wj5hmy.js → claude-sdk-session-x91kqyhm.js} +9677 -9514
- package/dist/{cli-j3jvnpe8.js → cli-08bmz9z9.js} +1 -1
- package/dist/{cli-gjr2y2xk.js → cli-0agcv1v5.js} +4 -1
- package/dist/{cli-y24sc29k.js → cli-1c6tzt8g.js} +30 -8
- package/dist/{cli-mjzynrse.js → cli-35rsp8ye.js} +1 -1
- package/dist/{cli-rpm2sgv0.js → cli-3fg0bdcv.js} +19 -2
- package/dist/{cli-nn4d8dne.js → cli-5b456bpf.js} +2 -2
- package/dist/{cli-bhjt02p8.js → cli-5jnhv72d.js} +1 -1
- package/dist/{cli-fqzx7gwa.js → cli-5zx699j9.js} +2 -2
- package/dist/{cli-hf6zt5m6.js → cli-69szn7w7.js} +17 -1
- package/dist/{cli-vqypxzh4.js → cli-6g0hb4cp.js} +8 -8
- package/dist/{cli-tqgg40ek.js → cli-6pfd54vx.js} +9 -8
- package/dist/{cli-bsn8nhrq.js → cli-6vcp76qk.js} +3 -3
- package/dist/{cli-zppwg9p9.js → cli-72v799xn.js} +1 -1
- package/dist/cli-82j36f2m.js +45 -0
- package/dist/{cli-hn9hxmz9.js → cli-8305gbq0.js} +29 -16
- package/dist/{cli-z8eh3ex8.js → cli-8sckt74b.js} +8 -8
- package/dist/{cli-bnz7a7qf.js → cli-95jzxcp3.js} +1 -1
- package/dist/{cli-0bxqnvq9.js → cli-adeegh7d.js} +29 -7
- package/dist/{cli-g61qxmge.js → cli-afkqkrtw.js} +3 -3
- package/dist/{cli-7a42nfy0.js → cli-ayayvfg4.js} +24 -4
- package/dist/{cli-bqt1mptt.js → cli-az48n0nr.js} +4 -4
- package/dist/{cli-z6jkx23q.js → cli-bfv7vdg6.js} +9 -9
- package/dist/{cli-pywf3eh5.js → cli-caj33vcq.js} +5 -5
- package/dist/{cli-5pag6rmn.js → cli-cb2a8pna.js} +1 -1
- package/dist/{cli-wvaawacd.js → cli-cppkf404.js} +5236 -72
- package/dist/{cli-mry0qzym.js → cli-ddaanqkd.js} +123 -10
- package/dist/{cli-0gey5fzy.js → cli-e0kmphd6.js} +2 -2
- package/dist/{cli-zh3fp8v2.js → cli-e46hg0xw.js} +1 -1
- package/dist/{cli-jm2vfpfd.js → cli-e5bzrn01.js} +1 -1
- package/dist/{cli-qxnf8z2z.js → cli-excnnjg2.js} +165 -153
- package/dist/{cli-71ptav7x.js → cli-ferkkrg9.js} +1 -1
- package/dist/{cli-vpf89f34.js → cli-fmjd0t1y.js} +3 -3
- package/dist/{cli-rm6hqj3z.js → cli-fyt2g4wd.js} +33 -139
- package/dist/cli-g08zdaec.js +55 -0
- package/dist/{cli-ehq736cn.js → cli-g7s47cc5.js} +4 -4
- package/dist/{cli-82ae98pz.js → cli-gz6q4eve.js} +3 -3
- package/dist/{cli-82jg7fp9.js → cli-he5nxaa8.js} +1 -1
- package/dist/{cli-rqkxrmgw.js → cli-je518txm.js} +39 -14
- package/dist/{cli-8hs41zy2.js → cli-jtjtabxe.js} +1 -1
- package/dist/{cli-611a1294.js → cli-k0wwfqbg.js} +18 -1
- package/dist/{cli-nzxr556s.js → cli-k1nje3v3.js} +38 -43
- package/dist/{cli-3h4nhjn8.js → cli-k8196sh2.js} +9 -7
- package/dist/{cli-afrrppsw.js → cli-k899ehvh.js} +2 -2
- package/dist/{cli-0731hvbw.js → cli-m0da8j35.js} +23 -9
- package/dist/cli-m2z8jagn.js +12078 -0
- package/dist/{cli-8veytvbh.js → cli-mkk9rnzz.js} +5 -5
- package/dist/{cli-7wspm5gm.js → cli-n6bv12jn.js} +528 -6
- package/dist/{cli-spknvxbq.js → cli-nmzhp1b5.js} +14 -12
- package/dist/{cli-p599f1qm.js → cli-p82cnnjq.js} +1 -1
- package/dist/{cli-xtjhfmpc.js → cli-pc6n7fre.js} +1 -1
- package/dist/{cli-vbyfwh92.js → cli-pjctyea3.js} +2 -2
- package/dist/{cli-nmbmy64z.js → cli-pq73h5mz.js} +3 -3
- package/dist/{cli-aa6yxc7m.js → cli-pz4rk021.js} +1 -1
- package/dist/{cli-7wcyk2s5.js → cli-q3tkegby.js} +1 -1
- package/dist/cli-qghe0h66.js +67 -0
- package/dist/{cli-6s7vdcta.js → cli-qh4d4tvk.js} +4 -4
- package/dist/{cli-mmwm7zbf.js → cli-rtt8g4v9.js} +1 -1
- package/dist/{cli-kg8hchyg.js → cli-sa02jsqt.js} +1 -1
- package/dist/{cli-1h3wcpbw.js → cli-snpj5zbj.js} +2 -2
- package/dist/{cli-a7v854rf.js → cli-tgrv9cjx.js} +263 -12
- package/dist/{cli-a47xy8eq.js → cli-vz22fyqv.js} +186 -54
- package/dist/{cli-1ayk1eas.js → cli-wk5yrfwd.js} +285 -42
- package/dist/{cli-1338796d.js → cli-ws19768n.js} +1755 -119
- package/dist/{cli-70r77n04.js → cli-xae4g51r.js} +1 -1
- package/dist/{cli-gf5hbmdr.js → cli-yjdgea32.js} +3 -3
- package/dist/{cli-xbkdm710.js → cli-yndmfxb3.js} +3 -3
- package/dist/{cli-rhw40jgb.js → cli-yyj3j5m4.js} +2 -2
- package/dist/cli.js +26 -25
- package/dist/{cloudflare-workers-ai-system-one-bm60fjm0.js → cloudflare-workers-ai-system-one-ef2a980q.js} +2 -2
- package/dist/{codex-adapter-q6k3gnyg.js → codex-adapter-cf2yxe9m.js} +3 -2
- package/dist/{codex-hook-9efm2x1m.js → codex-hook-a0c6g6t6.js} +1 -1
- package/dist/{codex-session-runner-3mwmk3d9.js → codex-session-runner-6vfzdgbd.js} +3 -2
- package/dist/{commands-evrenjn9.js → commands-t3mfy7vn.js} +9 -3
- package/dist/{controller-xjp8vswh.js → controller-q7xrbaz0.js} +8 -3
- package/dist/{controllers-connect-pp5jnxvc.js → controllers-connect-c6nm70kg.js} +20 -19
- package/dist/{cursor-adapter-yf47w4t0.js → cursor-adapter-ftd81ga8.js} +1 -1
- package/dist/{db-zxpw6aht.js → db-dk572x25.js} +3 -3
- package/dist/{db-rgfsh91f.js → db-vemtpmcc.js} +14 -4
- package/dist/{devtools-82fzqra8.js → devtools-qxfgbsqz.js} +1 -1
- package/dist/{dispatcher-smasgws7.js → dispatcher-kh7ecxh9.js} +17 -16
- package/dist/{docker-rrjhaqt9.js → docker-c1a3gqmf.js} +89 -22
- package/dist/{dsh-adapter-ftyy8dnp.js → dsh-adapter-v8628r89.js} +1 -1
- package/dist/{e2b-w1p0bnpm.js → e2b-fr12yccx.js} +5 -5
- package/dist/{e2b-qcaj675y.js → e2b-x6ywzak3.js} +3 -3
- package/dist/{easter-egg-3d-yyts7p16.js → easter-egg-3d-nenw4x63.js} +1 -1
- package/dist/{embedding-space-1z0mbg95.js → embedding-space-0jepb239.js} +6 -6
- package/dist/{embeddings-ygeg7tm7.js → embeddings-xxt49yxg.js} +1 -1
- package/dist/{execute-14qhqp4d.js → execute-1mhw6e4x.js} +1 -1
- package/dist/{external-channel-ttgrs3sx.js → external-channel-55v12e60.js} +2 -2
- package/dist/{fx-adapter-gt6pncj2.js → fx-adapter-bs8wqrk5.js} +6 -5
- package/dist/{google-generative-ai-yvmdxyxa.js → google-generative-ai-v94hr7h0.js} +5 -5
- package/dist/{google-vertex-jrtdh9gs.js → google-vertex-g7vr6cf8.js} +5 -5
- package/dist/{grok-adapter-sm4m5k4g.js → grok-adapter-gpjqmkcq.js} +6 -5
- package/dist/handlers-zxmp1ta4.js +32 -0
- package/dist/{heartbeat-qahz4p62.js → heartbeat-k42svnr0.js} +20 -19
- package/dist/{hook-4fd5wq5w.js → hook-114m7hap.js} +4 -3
- package/dist/{hook-kj3d398m.js → hook-6nphweh0.js} +24 -9
- package/dist/{http-1ted0j1k.js → http-r8cc4wz7.js} +1196 -211
- package/dist/index-a8phxqnk.js +37 -0
- package/dist/{index-q4b917zs.js → index-e3s8wmxy.js} +1 -1
- package/dist/{index-6rq3r5zb.js → index-fpk4bcd9.js} +1 -1
- package/dist/{index-5rk6rfzr.js → index-fvzke5kx.js} +1 -1
- package/dist/index-k6h00t4c.js +30 -0
- package/dist/{index-7v51awbn.js → index-nh3wyqdt.js} +1027 -577
- package/dist/{index-yqhz88yy.js → index-pxn30mse.js} +8 -8
- package/dist/index-xrz7te8h.js +33 -0
- package/dist/{keepalive-6cf311t5.js → keepalive-x060nt9p.js} +3 -3
- package/dist/lead-956sd2yc.js +71 -0
- package/dist/{maintenance-a4bm1bmt.js → maintenance-2xxfexhf.js} +1 -1
- package/dist/{mistral-conversations-4pmwj1c0.js → mistral-conversations-3gjpdb4b.js} +4 -4
- package/dist/{oauth-refresh-sweep-3h0dfw1k.js → oauth-refresh-sweep-fckc4ar5.js} +2 -2
- package/dist/{onboard-myn5hraa.js → onboard-zc48j237.js} +5 -5
- package/dist/{openai-codex-responses-44j573nm.js → openai-codex-responses-8pbxq9h5.js} +5 -5
- package/dist/{openai-completions-a4gee2a8.js → openai-completions-rm00s912.js} +4 -4
- package/dist/{openai-decisions-w4qkrcar.js → openai-decisions-8v957r2r.js} +1 -1
- package/dist/{openai-responses-rbp6h5kr.js → openai-responses-agxpf96k.js} +5 -5
- package/dist/{opencode-adapter-p2nkb5am.js → opencode-adapter-r690h1cr.js} +4 -3
- package/dist/{otel-impl-a1a0ef6b.js → otel-impl-r5xbh81q.js} +4 -4
- package/dist/{pi-mono-adapter-rzmpb72a.js → pi-mono-adapter-c7v8sdec.js} +7 -6
- package/dist/{pricing-refresh-83drrnxj.js → pricing-refresh-3pmre11v.js} +3 -3
- package/dist/{rbac-roles-s8y6ecb5.js → rbac-roles-3vbshwsb.js} +1 -1
- package/dist/{rbac-roles-0fb6e7pj.js → rbac-roles-910mmkgz.js} +2 -2
- package/dist/{render-v2-twmbgrz4.js → render-v2-pxykkbab.js} +3 -3
- package/dist/{resume-zfqc36xj.js → resume-adda0bwy.js} +6 -6
- package/dist/{runtime-qwggdpqr.js → runtime-fnbm7stk.js} +1 -1
- package/dist/{session-access-sc9pn9da.js → session-access-2fvamrdc.js} +4 -4
- package/dist/{session-source-backfill-qh07xr8g.js → session-source-backfill-08xvv0sm.js} +2 -2
- package/dist/{setup-4fr0m7a1.js → setup-1aqmvmh1.js} +3 -3
- package/dist/{typesafe-system-one-5mavm259.js → typesafe-system-one-0bmqcxfg.js} +2 -2
- package/dist/{virtual-modules-fh4ha15b.js → virtual-modules-d2pjk9j1.js} +5 -5
- package/dist/{work-objects-0wr8zxct.js → work-objects-9s0yrm5j.js} +20 -19
- package/dist/{worker-follow-up-ktyyazyp.js → worker-follow-up-3q78fqmr.js} +17 -16
- package/dist/worker-y15hy08h.js +71 -0
- package/openapi.json +289 -4
- package/package.json +9 -8
- package/src/apps/definition.ts +6 -5
- package/src/be/db/page-theme-tokens.ts +12 -0
- package/src/be/db/script-runs.ts +23 -0
- package/src/be/db/tasks/read.ts +131 -4
- package/src/be/db/tasks/write.ts +19 -0
- package/src/be/db-client.ts +114 -11
- package/src/be/db.ts +49 -6
- package/src/be/memory/providers/sqlite-store.ts +49 -12
- package/src/be/migrations/260_runtime_pool_cache.sql +20 -0
- package/src/be/migrations/262_session_visibility_indexes.sql +18 -0
- package/src/be/migrations/263_task_list_filter_index.sql +11 -0
- package/src/be/migrations/264_slack_thread_cover_index.sql +9 -0
- package/src/be/migrations/266_script_runs_source_task.sql +11 -0
- package/src/be/migrations/269_pages_design_system.sql +23 -0
- package/src/be/runtime-pools/cache-cleanup.ts +109 -0
- package/src/be/runtime-pools/db.ts +65 -6
- package/src/be/runtime-pools/remote-controller.ts +5 -0
- package/src/be/runtime-pools/supervisor.ts +33 -2
- package/src/be/scripts/typecheck.ts +22 -0
- package/src/be/seed/schedules-seeder.ts +0 -10
- package/src/be/seed-scripts/catalog/catalog-report.inline.ts +2 -0
- package/src/be/seed-scripts/catalog/catalog-report.ts +2 -0
- package/src/be/seed-scripts/catalog/memory-eval.ts +2 -0
- package/src/be/seed-scripts/catalog/swarm-update-check.ts +150 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +5 -1
- package/src/be/seed-scripts/index.ts +9 -0
- package/src/be/seed-skills/bundled-files.generated.json +3 -3
- package/src/be/swarm-config-guard.ts +32 -0
- package/src/be/task-auto-title-listener.ts +127 -0
- package/src/commands/controller.ts +4 -0
- package/src/commands/entrypoint-api-readiness.ts +74 -0
- package/src/commands/onboard/agent-fs-version.ts +1 -1
- package/src/commands/profile-sync.ts +151 -16
- package/src/commands/runner.ts +15 -7
- package/src/hooks/hook.ts +20 -9
- package/src/http/index.ts +4 -1
- package/src/http/list-total-cache.ts +14 -7
- package/src/http/memory.ts +38 -9
- package/src/http/pages-public.ts +93 -129
- package/src/http/pages.ts +94 -21
- package/src/http/script-runs.ts +174 -5
- package/src/http/status.ts +10 -2
- package/src/http/tasks.ts +4 -2
- package/src/pages/browser-sdk.ts +48 -21
- package/src/pages/color-literals.ts +115 -0
- package/src/pages/page-head.ts +766 -0
- package/src/pages/version.ts +3 -0
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +1 -0
- package/src/providers/codex-app-server.ts +27 -1
- package/src/providers/fx-adapter.ts +1 -1
- package/src/providers/pi-mono-extension.ts +30 -15
- package/src/runtime-providers/controller-protocol.ts +14 -1
- package/src/runtime-providers/controller.ts +5 -0
- package/src/runtime-providers/docker.ts +108 -23
- package/src/runtime-providers/types.ts +16 -0
- package/src/script-workflows/workflow-ctx.ts +8 -0
- package/src/scripts-runtime/types/stdlib.d.ts +22 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +22 -0
- package/src/server-user.ts +1 -0
- package/src/slack/commands.ts +5 -1
- package/src/slack/handlers.ts +37 -2
- package/src/slack/left-threads.ts +27 -4
- package/src/tasks/follow-up-gate.ts +318 -0
- package/src/tasks/follow-up-redelegation-guard.ts +155 -0
- package/src/tasks/worker-follow-up.ts +21 -1
- package/src/tests/claude-artifacts-read-script.test.ts +209 -0
- package/src/tests/codex-app-server.test.ts +59 -0
- package/src/tests/codex-gateway-route.test.ts +50 -1
- package/src/tests/create-page-tool.test.ts +501 -0
- package/src/tests/db-client-busy-retry.test.ts +81 -0
- package/src/tests/db-client.test.ts +21 -0
- package/src/tests/db-task-read-contract.test.ts +9 -2
- package/src/tests/db-task-write-contract.test.ts +7 -1
- package/src/tests/db-tasks-read.test.ts +21 -0
- package/src/tests/entrypoint-api-readiness.test.ts +416 -210
- package/src/tests/explicit-model-validation.test.ts +14 -8
- package/src/tests/fixtures/pages/head-v1.html +56 -0
- package/src/tests/follow-up-gate-shadow.test.ts +513 -0
- package/src/tests/follow-up-redelivery-guard.test.ts +432 -202
- package/src/tests/identity-field-budget.test.ts +1 -1
- package/src/tests/internal-ai/credentials.test.ts +62 -0
- package/src/tests/internal-ai/task-title.test.ts +283 -0
- package/src/tests/list-total-cache.test.ts +27 -2
- package/src/tests/memory-fts-populate.test.ts +11 -9
- package/src/tests/memory-retrieval-purge.test.ts +80 -0
- package/src/tests/merge-gate-detect-changes.test.ts +145 -0
- package/src/tests/migration-260-runtime-pool-cache.test.ts +118 -0
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/page-session-dev-cookie.test.ts +188 -0
- package/src/tests/pages-frame-ancestors.test.ts +28 -1
- package/src/tests/pages-head-v2.test.ts +534 -0
- package/src/tests/pages-http.test.ts +330 -0
- package/src/tests/pages-public-html.test.ts +43 -0
- package/src/tests/pages-storage.test.ts +182 -0
- package/src/tests/pages-versioning.test.ts +72 -0
- package/src/tests/profile-sync-stale-writeback.test.ts +334 -0
- package/src/tests/profile-sync.test.ts +11 -15
- package/src/tests/query-audit-plans.test.ts +27 -0
- package/src/tests/runtime-cache-cleanup.test.ts +367 -0
- package/src/tests/runtime-e2b-pools.test.ts +41 -0
- package/src/tests/runtime-pools-db.test.ts +98 -0
- package/src/tests/runtime-pools-http.test.ts +29 -0
- package/src/tests/runtime-providers-docker.test.ts +253 -0
- package/src/tests/runtime-remote-controller.test.ts +66 -2
- package/src/tests/runtime-supervisor.test.ts +66 -2
- package/src/tests/scheduled-task-required-params-migration.test.ts +3 -1
- package/src/tests/script-connections.test.ts +13 -0
- package/src/tests/script-runs-http.test.ts +684 -2
- package/src/tests/seed-registry.test.ts +28 -6
- package/src/tests/seed-schedules.test.ts +61 -8
- package/src/tests/seed-scripts.test.ts +168 -2
- package/src/tests/slack-leave-thread.test.ts +145 -5
- package/src/tests/slack-render-v2-query-plans.test.ts +24 -2
- package/src/tests/status.test.ts +11 -0
- package/src/tests/swarm-diff.test.ts +121 -2
- package/src/tests/task-auto-title-config-guard.test.ts +37 -0
- package/src/tests/task-auto-title-listener.test.ts +165 -0
- package/src/tests/tasks-readable-row.test.ts +155 -0
- package/src/tests/theme-import.test.ts +758 -0
- package/src/tests/themes-page-theme.test.ts +155 -0
- package/src/tests/themes-presets.test.ts +172 -0
- package/src/tests/workflow-script-principal.test.ts +2 -1
- package/src/themes/classics.ts +949 -0
- package/src/themes/import.ts +420 -0
- package/src/themes/page-fields.ts +40 -0
- package/src/themes/page-theme.ts +102 -0
- package/src/themes/presets.ts +561 -0
- package/src/themes/tokens.ts +218 -0
- package/src/tools/app-upsert.ts +1 -1
- package/src/tools/create-page.ts +118 -12
- package/src/tools/send-task.ts +35 -47
- package/src/tools/slack-leave-thread.ts +1 -1
- package/src/tools/task-dedup.ts +45 -21
- package/src/tools/utils.ts +33 -0
- package/src/types.ts +83 -3
- package/src/utils/constants.ts +19 -0
- package/src/utils/follow-up-gate-schedule-ids.ts +13 -0
- package/src/utils/internal-ai/credentials.ts +146 -93
- package/src/utils/internal-ai/index.ts +10 -0
- package/src/utils/internal-ai/models.ts +18 -0
- package/src/utils/internal-ai/task-title.ts +282 -0
- package/src/utils/page-session.ts +37 -0
- package/templates/schedules/daily-status-report/content.md +88 -2
- package/templates/schedules/daily-swarm-update-check/content.md +16 -40
- package/templates/skills/apps/SKILL.md +1 -1
- package/templates/skills/apps/content.md +1 -1
- package/templates/skills/composio-google-docs/content.md +10 -0
- package/templates/skills/heartbeat-runbook/content.md +1 -1
- package/templates/skills/pages/config.json +1 -1
- package/templates/skills/pages/content.md +539 -86
- package/templates/skills/pages/files/examples/annotated-pr.html +21 -12
- package/templates/skills/pages/files/examples/multiplayer-board.html +41 -41
- package/templates/skills/pages/files/examples/report-page.html +125 -124
- package/templates/skills/script-workflows/content.md +19 -1
- package/templates/skills/swarm-docs/content.md +1 -0
- package/templates/skills/swarm-scripts/SKILL.md +2 -0
- package/templates/skills/swarm-scripts/content.md +2 -0
- package/dist/cli-2pnswgh8.js +0 -189
- package/dist/cli-dznrgaep.js +0 -30
- package/dist/cli-w3hcrxht.js +0 -6985
- package/dist/handlers-vwmba1m2.js +0 -31
- package/dist/index-5r71rf98.js +0 -32
- package/dist/index-anmwxs87.js +0 -29
- package/dist/index-spp0ra5c.js +0 -36
- package/dist/lead-fjy418cw.js +0 -69
- package/dist/worker-0c5tyzqe.js +0 -69
- package/templates/schedules/daily-workflow-health-audit/config.json +0 -19
- package/templates/schedules/daily-workflow-health-audit/content.md +0 -191
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# Pages
|
|
1
|
+
# Pages: DB-backed Static Artifacts
|
|
2
2
|
|
|
3
3
|
DB-backed static content (HTML or JSON) served by the API directly. Cheap,
|
|
4
4
|
versioned, share-able by URL. No server process, no tunnel, no port
|
|
5
5
|
allocation.
|
|
6
6
|
|
|
7
7
|
A page should be a clean human-facing artifact, not a raw dump with a URL. This
|
|
8
|
-
skill covers both halves: **how to publish** a page, and **the
|
|
9
|
-
every page should
|
|
8
|
+
skill covers both halves: **how to publish** a page, and **the design system**
|
|
9
|
+
every page should use.
|
|
10
10
|
|
|
11
11
|
> **Capability gate**: the `create_page` MCP tool is only available when the
|
|
12
12
|
> agent's `CAPABILITIES` env var includes `pages`
|
|
@@ -29,10 +29,10 @@ in a single call), use pages. If it needs stored data and actions, use apps.
|
|
|
29
29
|
|
|
30
30
|
Do **not** use pages for:
|
|
31
31
|
|
|
32
|
-
- In-flight progress notes
|
|
32
|
+
- In-flight progress notes: use `store-progress.progress`
|
|
33
33
|
- Secrets, private credentials, or unapproved personal data
|
|
34
|
-
- Large binary files
|
|
35
|
-
- Raw verbose logs
|
|
34
|
+
- Large binary files: use agent-fs for PNG/MP4
|
|
35
|
+
- Raw verbose logs: summarize, and link the raw file as an artifact
|
|
36
36
|
|
|
37
37
|
## Quick Start
|
|
38
38
|
|
|
@@ -47,7 +47,7 @@ Do **not** use pages for:
|
|
|
47
47
|
"authMode": "authed",
|
|
48
48
|
"body": "<!doctype html><html><body><h1>Q2 Status</h1>...</body></html>"
|
|
49
49
|
}
|
|
50
|
-
// → { id, version: 1, app_url, api_url }
|
|
50
|
+
// → { id, version: 1, designVersion: 2, app_url, api_url }
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
Share `app_url` (the SPA route) for the general case; share `api_url` for a
|
|
@@ -56,8 +56,8 @@ no-SPA-required direct link.
|
|
|
56
56
|
Use `authMode: "public"` only when the page is intentionally safe for anyone
|
|
57
57
|
with the URL to view.
|
|
58
58
|
|
|
59
|
-
A complete
|
|
60
|
-
**`examples/report-page.html
|
|
59
|
+
A complete report built from the design system below is bundled at
|
|
60
|
+
**`examples/report-page.html`**. Copy it as your starting point instead of
|
|
61
61
|
writing CSS from scratch.
|
|
62
62
|
|
|
63
63
|
### Authed JSON dashboard
|
|
@@ -80,28 +80,451 @@ swarm API.
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
-
# Design
|
|
83
|
+
# Design system
|
|
84
|
+
|
|
85
|
+
HTML pages with `designVersion: 2` get the swarm design system. It is the
|
|
86
|
+
dashboard's own look (the Hive preset), built from the dashboard's theme
|
|
87
|
+
tokens. One theme switch restyles the whole page. New pages get
|
|
88
|
+
`designVersion: 2` by default.
|
|
89
|
+
|
|
90
|
+
The design system styles HTML pages only. JSON pages render inside the
|
|
91
|
+
dashboard and use the dashboard theme.
|
|
92
|
+
|
|
93
|
+
Before you create a page, write a one-line design read for yourself:
|
|
94
|
+
|
|
95
|
+
> Reading this as: `<page kind>` for `<audience>`, using the design system plus `<density needs>`.
|
|
96
|
+
|
|
97
|
+
## What a designVersion 2 page gets
|
|
98
|
+
|
|
99
|
+
The API injects these into the `<head>` of every designVersion 2 HTML page:
|
|
100
|
+
|
|
101
|
+
- **Element defaults**: plain HTML elements look finished with zero CSS. See Element defaults below for the full list.
|
|
102
|
+
- **Theme tokens**: CSS variables such as `var(--color-primary)`. Each color token has a light value and a dark value.
|
|
103
|
+
- **Primitives**: `swarm-*` classes for page structure, metrics, panels, badges, tables, buttons, and callouts.
|
|
104
|
+
- **Tailwind v4 utilities** that map to the tokens, such as `bg-card` and `text-muted-foreground`. Preflight stays off, so the element defaults stay.
|
|
105
|
+
- **Fonts**: Space Grotesk for text and Space Mono for code.
|
|
106
|
+
- **Light print**: print always uses the light tokens.
|
|
107
|
+
|
|
108
|
+
The element defaults, the primitives, and the Tailwind utilities sit in CSS
|
|
109
|
+
cascade layers. A Tailwind utility beats a primitive, and a primitive beats an
|
|
110
|
+
element default. Your own `<style>` rules are not in a layer, so they beat all
|
|
111
|
+
three. Use your own CSS for layout, and take every color from a token. For an
|
|
112
|
+
edge-to-edge layout, set `body { padding: 0 }`.
|
|
113
|
+
|
|
114
|
+
## Element defaults
|
|
115
|
+
|
|
116
|
+
The head styles these elements. They need no class. Do not restyle an element
|
|
117
|
+
only to get the look that it already has.
|
|
118
|
+
|
|
119
|
+
| Element | Default look |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `html`, `body` | The background and foreground tokens. The body uses `--font-sans` at 15px with a 1.55 line height. It has 24px of padding, and 16px at 640px wide and below. |
|
|
122
|
+
| `h1` to `h6` | Weight 600. `h1` is 30px, `h2` is 20px, `h3` is 16px, `h4` is 15px, and `h5` and `h6` are 13px. |
|
|
123
|
+
| `p`, `ul`, `ol`, `li` | Paragraphs and lists have a 12px bottom margin. List markers are muted. |
|
|
124
|
+
| `dl`, `dt`, `dd` | `dt` is weight 500. For a key and value grid, use `.swarm-kv`. |
|
|
125
|
+
| `a` | The primary color with a soft underline. The underline gets stronger on hover. |
|
|
126
|
+
| `strong`, `b` | Weight 600. |
|
|
127
|
+
| `mark` | A soft highlight in the pending tone. |
|
|
128
|
+
| `hr` | A 1px `--color-border-subtle` rule, with 32px above and below. |
|
|
129
|
+
| `blockquote` | Muted text with a 2px left rule. |
|
|
130
|
+
| `code`, `samp` | `--font-mono` at 0.85em. `code` has a muted fill. |
|
|
131
|
+
| `kbd` | A key with a 1px border and a thicker bottom edge, in `--font-mono`. |
|
|
132
|
+
| `pre` | A bordered surface block in `--font-mono`. It scrolls when a line is too long. |
|
|
133
|
+
| `img`, `video` | Block elements that are never wider than their container. |
|
|
134
|
+
| `figure`, `figcaption` | `figcaption` is 13px muted text, 8px below the content. |
|
|
135
|
+
| `table`, `th`, `td` | Full width, 14px, collapsed borders, and tabular digits. `th` is an 11px uppercase muted label. Each row has a subtle bottom rule. |
|
|
136
|
+
| `caption` | 13px muted text, aligned left. |
|
|
137
|
+
| `tfoot` | A totals row: weight 600 with a `--color-border` rule above it. Print shows it once, at the end of the table. |
|
|
138
|
+
| `th scope="row"` | A row header that looks like a normal cell. |
|
|
139
|
+
| `details`, `summary` | `summary` is weight 500 with a muted marker. |
|
|
140
|
+
| Text `input`, `select`, `textarea` | The `.swarm-input` look. `select` has its own arrow. `textarea` is at least 80px tall and resizes vertically. |
|
|
141
|
+
| `button`, and `input` of type `button`, `submit`, or `reset` | The outline `.swarm-button` look. A plain `<button>` needs no class. |
|
|
142
|
+
| `input type="file"` | A small outline button opens the file picker. |
|
|
143
|
+
| Checkbox, radio, range, `progress` | The primary color. |
|
|
144
|
+
| `fieldset`, `legend` | A bordered group with a 13px muted legend. |
|
|
145
|
+
| Form states | Placeholders are muted. Disabled controls have 50% opacity. `aria-invalid="true"` makes the border destructive. |
|
|
146
|
+
| `:focus-visible` | A 2px ring in `--color-ring`. |
|
|
147
|
+
| `::selection` | The primary fill. |
|
|
148
|
+
| Every element | `border: 0 solid var(--color-border)`. A bare `border` class draws a 1px line in the border token. |
|
|
149
|
+
|
|
150
|
+
Blocks such as `p`, lists, `table`, `pre`, and `figure` have a 12px or 16px
|
|
151
|
+
bottom margin. A heading that is the first child of its container has no top
|
|
152
|
+
margin. The last block in a container has no bottom margin.
|
|
153
|
+
|
|
154
|
+
The head sets `<base target="_blank">`, so a link to another page opens in a
|
|
155
|
+
new tab. A link inside the page (`href="#id"`) without a `target` stays in the
|
|
156
|
+
page.
|
|
157
|
+
|
|
158
|
+
## No hardcoded colors
|
|
159
|
+
|
|
160
|
+
Take every color from a token. Inside the dashboard, the page follows the
|
|
161
|
+
viewer's theme and mode. A hardcoded color stays the same in every theme and
|
|
162
|
+
mode, so it can break contrast.
|
|
163
|
+
|
|
164
|
+
- Do not write color literals: hex values (`#2563eb`), `rgb()`, `rgba()`, `hsl()`, `hsla()`, `oklch()`, or named colors such as `white` and `black`.
|
|
165
|
+
- Do not use Tailwind palette classes such as `bg-blue-500`, `text-zinc-600`, `bg-white`, or `text-black`, or arbitrary colors such as `bg-[#fff]`. They ignore the theme. For example, a `bg-white` card in dark mode puts light text on white.
|
|
166
|
+
- In CSS, use `var(--color-*)`. In markup, use the Tailwind class of the token, such as `bg-primary` or `text-muted-foreground`.
|
|
167
|
+
- For a tint, add an opacity modifier: `bg-primary/10`. In CSS, write `color-mix(in oklab, var(--color-primary) 10%, transparent)`.
|
|
168
|
+
- In inline SVG, use `fill-chart-1`, `stroke-border`, or `currentColor`.
|
|
169
|
+
- For a canvas chart, read the token value at runtime: `getComputedStyle(document.documentElement).getPropertyValue("--color-chart-1")`.
|
|
170
|
+
|
|
171
|
+
`create_page` counts the hardcoded colors in your `<style>` blocks, `style`
|
|
172
|
+
attributes, and `class` attributes. At 8 or more, its result tells you to use
|
|
173
|
+
tokens. A page with 8 or more hardcoded colors stays light, also when the
|
|
174
|
+
viewer uses dark mode.
|
|
175
|
+
|
|
176
|
+
To restyle a page, set `theme` or `themeTokens` (see Theming). Do not write
|
|
177
|
+
your own palette.
|
|
178
|
+
|
|
179
|
+
## Theme tokens
|
|
180
|
+
|
|
181
|
+
The tokens use the dashboard's names. The font and radius tokens have one
|
|
182
|
+
value for both modes.
|
|
183
|
+
|
|
184
|
+
| CSS variable | Tailwind class | Meaning |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| `--color-background` | `bg-background` | The page canvas. |
|
|
187
|
+
| `--color-foreground` | `text-foreground` | Main text. |
|
|
188
|
+
| `--color-card`, `--color-card-foreground` | `bg-card`, `text-card-foreground` | Panels and the text on them. |
|
|
189
|
+
| `--color-surface` | `bg-surface` | A recessed step between canvas and card, for nested blocks. |
|
|
190
|
+
| `--color-popover`, `--color-popover-foreground` | `bg-popover`, `text-popover-foreground` | Menus, tooltips, and other floating layers. |
|
|
191
|
+
| `--color-primary`, `--color-primary-foreground` | `bg-primary`, `text-primary`, `text-primary-foreground` | The one accent: links, primary buttons, and active state. The foreground is the text on a primary fill. |
|
|
192
|
+
| `--color-secondary`, `--color-secondary-foreground` | `bg-secondary`, `text-secondary-foreground` | Secondary buttons and quiet fills. |
|
|
193
|
+
| `--color-muted`, `--color-muted-foreground` | `bg-muted`, `text-muted-foreground` | Quiet resting fills. Secondary text, labels, and captions. |
|
|
194
|
+
| `--color-accent`, `--color-accent-foreground` | `hover:bg-accent`, `text-accent-foreground` | The hover and highlight fill. For the brand accent, use `primary`. |
|
|
195
|
+
| `--color-destructive`, `--color-destructive-foreground` | `bg-destructive`, `text-destructive` | Destructive actions only. |
|
|
196
|
+
| `--color-border` | `border-border` | Structure lines: panels, inputs, table frames. |
|
|
197
|
+
| `--color-border-subtle` | `border-border-subtle`, `divide-border-subtle` | Quiet lines: row rules and separators. |
|
|
198
|
+
| `--color-input` | `border-input` | Form control borders. |
|
|
199
|
+
| `--color-ring` | `ring-ring`, `outline-ring` | The focus ring. |
|
|
200
|
+
| `--color-chart-1` to `--color-chart-5` | `bg-chart-1`, `fill-chart-2`, `stroke-chart-3` | Chart series, in order. |
|
|
201
|
+
| `--color-status-<tone>` | `bg-status-success` | A pale status fill. |
|
|
202
|
+
| `--color-status-<tone>-strong` | `text-status-error-strong` | Status text on a neutral surface. |
|
|
203
|
+
| `--color-status-<tone>-foreground` | `text-status-success-foreground` | The text on a pale status fill. |
|
|
204
|
+
| `--color-status-success-solid`, `--color-status-active-solid` | `bg-status-success-solid` | Saturated stops for small dots and icons. |
|
|
205
|
+
| `--font-sans` | `font-sans` | Text. Space Grotesk by default. |
|
|
206
|
+
| `--font-mono` | `font-mono` | Code, IDs, logs, and other machine output. Space Mono by default. |
|
|
207
|
+
| `--radius-sm`, `--radius-md`, `--radius-lg`, `--radius-xl` | `rounded-sm`, `rounded-md`, `rounded-lg`, `rounded-xl` | Corner radii, from tags (`sm`) to panels (`xl`). |
|
|
208
|
+
|
|
209
|
+
`<tone>` is `success`, `active`, `error`, `info`, `pending`, `warning`,
|
|
210
|
+
`paused`, or `neutral`. Status colors carry meaning. Use them for states, not
|
|
211
|
+
for decoration.
|
|
212
|
+
|
|
213
|
+
The old `--swarm-bg`, `--swarm-card`, `--swarm-border`, `--swarm-text`,
|
|
214
|
+
`--swarm-muted`, and `--swarm-primary` variables still work. On designVersion
|
|
215
|
+
2 pages, they are aliases of the tokens. Use the token names in new pages.
|
|
216
|
+
|
|
217
|
+
## Primitives
|
|
218
|
+
|
|
219
|
+
The primitives are plain CSS classes. They use only tokens, so they work in
|
|
220
|
+
both modes and under every preset. Add Tailwind utilities for spacing and
|
|
221
|
+
layout.
|
|
222
|
+
|
|
223
|
+
**`.swarm-page`**: the reading spine. It centers the content at a maximum width of 1120px.
|
|
224
|
+
|
|
225
|
+
```html
|
|
226
|
+
<main class="swarm-page">...</main>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**`.swarm-eyebrow`**: a small uppercase label above a title.
|
|
230
|
+
|
|
231
|
+
```html
|
|
232
|
+
<p class="swarm-eyebrow">Weekly report · 2026-10-31</p>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**`.swarm-lede`**: the summary paragraph under the title. It is larger, muted, and about 68 characters wide.
|
|
236
|
+
|
|
237
|
+
```html
|
|
238
|
+
<p class="swarm-lede">Error rates fell 40% after the retry fix shipped.</p>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**`.swarm-section`**: a titled block with vertical rhythm.
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<section class="swarm-section"><h2>Findings</h2><p>...</p></section>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**`.swarm-metrics`** and **`.swarm-metric`**: a responsive grid of key numbers. Each metric holds a `.swarm-metric-value` (large, tabular digits) and a `.swarm-metric-label` (muted). Add a `data-tone` (see Tones) to a metric to color its value. Without it, the value uses the foreground color.
|
|
248
|
+
|
|
249
|
+
```html
|
|
250
|
+
<div class="swarm-metrics">
|
|
251
|
+
<div class="swarm-metric"><div class="swarm-metric-value">18.6k</div><div class="swarm-metric-label">Clicks</div></div>
|
|
252
|
+
<div class="swarm-metric" data-tone="error"><div class="swarm-metric-value">7</div><div class="swarm-metric-label">Failed runs</div></div>
|
|
253
|
+
</div>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**`.swarm-panel`** (alias **`.swarm-card`**): a flat surface with a 1px border, the `--radius-xl` radius, and padding. Do not put a panel inside a panel.
|
|
257
|
+
|
|
258
|
+
```html
|
|
259
|
+
<div class="swarm-panel"><h3>Owner</h3><p>Platform team</p></div>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**`.swarm-badge`**: a soft status pill that never wraps. Set `data-tone` to a tone (see Tones). The default is `neutral`. Add `data-dot` for a leading dot in the tone color. The badge has a 6px gap between the dot and the text, so do not add margins inside a badge.
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<span class="swarm-badge" data-tone="success" data-dot>Healthy</span>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
For a category label (a team, a region, a product line), do not use a status tone. Use a neutral badge with a dot, and set the dot color with `--swarm-dot` and a chart token. Give each category its own token, from `--color-chart-1` to `--color-chart-5`.
|
|
269
|
+
|
|
270
|
+
```html
|
|
271
|
+
<span class="swarm-badge" data-dot style="--swarm-dot: var(--color-chart-1)">Construction</span>
|
|
272
|
+
<span class="swarm-badge" data-dot style="--swarm-dot: var(--color-chart-2)">Interiors</span>
|
|
273
|
+
```
|
|
84
274
|
|
|
85
|
-
|
|
275
|
+
**`.swarm-table-wrap`** and **`.swarm-table`**: a scroll container and a compact table. The table has a sticky header, subtle row rules, and row hover. Add `.num` to number cells: right aligned, tabular, no wrap. Add `.nowrap` to keep any cell on one line.
|
|
86
276
|
|
|
87
|
-
|
|
277
|
+
The wrap is already a bordered card surface: the card fill, a 1px border, and the `--radius-xl` radius. Do not put it inside a panel. Its maximum height is `min(70vh, 720px)`. A taller table scrolls inside the wrap, and the header stays in view. To remove the cap, add `max-h-none` to the wrap. Then the page scrolls instead, and the header does not stay in view. Print always removes the cap. When the table is wider than the wrap, a soft shadow shows at each side that hides columns.
|
|
278
|
+
|
|
279
|
+
```html
|
|
280
|
+
<div class="swarm-table-wrap">
|
|
281
|
+
<table class="swarm-table">
|
|
282
|
+
<thead><tr><th>Route</th><th class="num">p95 ms</th></tr></thead>
|
|
283
|
+
<tbody><tr><td class="nowrap">/api/tasks</td><td class="num">182</td></tr></tbody>
|
|
284
|
+
</table>
|
|
285
|
+
</div>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**`.swarm-button`**: a button look for `<button>` and `<a>`. Set `data-variant` to `outline` (the default), `primary`, or `ghost`. A plain `<button>` also gets the outline look. For a bare icon button, remove it with utilities: `border-0 bg-transparent p-0`.
|
|
289
|
+
|
|
290
|
+
```html
|
|
291
|
+
<button class="swarm-button" data-variant="primary" type="button">Rerun checks</button>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**`.swarm-input`**: the look for text inputs and selects. Plain form controls get the same base look.
|
|
295
|
+
|
|
296
|
+
```html
|
|
297
|
+
<input class="swarm-input" type="search" placeholder="Filter rows" aria-label="Filter rows">
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**`.swarm-toolbar`**: a row for search, filters, and actions. It wraps on narrow screens. A text or search input placed directly in the toolbar grows to fill the free space, so do not give it a fixed width.
|
|
301
|
+
|
|
302
|
+
```html
|
|
303
|
+
<div class="swarm-toolbar">
|
|
304
|
+
<input class="swarm-input" type="search" placeholder="Filter" aria-label="Filter">
|
|
305
|
+
<button class="swarm-button" type="button">Reset</button>
|
|
306
|
+
</div>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**`.swarm-segmented`**: a segmented control. Mark the active item with `aria-pressed="true"` or `data-active`.
|
|
310
|
+
|
|
311
|
+
```html
|
|
312
|
+
<div class="swarm-segmented" role="group" aria-label="Range">
|
|
313
|
+
<button type="button" aria-pressed="true">Week</button>
|
|
314
|
+
<button type="button" aria-pressed="false">Month</button>
|
|
315
|
+
</div>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**`.swarm-callout`**: a box for a finding or a note. Set `data-tone` to a tone (see Tones). The default is `info`.
|
|
319
|
+
|
|
320
|
+
```html
|
|
321
|
+
<div class="swarm-callout" data-tone="warning"><strong>Retry storm.</strong> Three agents retried one task 40 times.</div>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**`.swarm-kv`**: a key and value grid for a `<dl>`. Each `<dt>` is a muted key, and the `<dd>` after it holds the value.
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<dl class="swarm-kv"><dt>Owner</dt><dd>Platform team</dd><dt>Window</dt><dd>7 days</dd></dl>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Tones
|
|
331
|
+
|
|
332
|
+
`.swarm-badge`, `.swarm-callout`, and `.swarm-metric` share one set of
|
|
333
|
+
`data-tone` values:
|
|
334
|
+
|
|
335
|
+
| `data-tone` | Use it for | Color token |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| `neutral` | Offline, backlog, cancelled, skipped, or not reviewed. The badge default. | `--color-status-neutral` |
|
|
338
|
+
| `primary` | A highlight that is not a state, in the page accent. | `--color-primary` |
|
|
339
|
+
| `success` | Completed, healthy, approved, or passed. | `--color-status-success` |
|
|
340
|
+
| `warning` | Timeouts, threshold warnings, and risks to fix soon. | `--color-status-warning` |
|
|
341
|
+
| `error` | Failed, unhealthy, rejected, or blocked. | `--color-status-error` |
|
|
342
|
+
| `info` | Facts and notes. The callout default. | `--color-status-info` |
|
|
343
|
+
| `pending` | Pending, waiting, or starting. | `--color-status-pending` |
|
|
344
|
+
| `paused` | Paused or in review. | `--color-status-paused` |
|
|
345
|
+
| `active` | Running, busy, or in progress. | `--color-status-active` |
|
|
346
|
+
|
|
347
|
+
Each status tone uses its token for fills and borders, and its `-strong` token
|
|
348
|
+
for text. `primary` uses `--color-primary` for both. A badge takes its text,
|
|
349
|
+
fill, and border from the tone. A callout takes only its fill and border from
|
|
350
|
+
the tone, so its text keeps the foreground color. A metric colors its value.
|
|
351
|
+
|
|
352
|
+
The bundled **`examples/report-page.html`** puts these together, with zero
|
|
353
|
+
color literals.
|
|
354
|
+
|
|
355
|
+
## Theming
|
|
356
|
+
|
|
357
|
+
The API picks the preset of a designVersion 2 page in this order:
|
|
358
|
+
|
|
359
|
+
1. The page's `theme`, when it is set.
|
|
360
|
+
2. The viewer's dashboard preset, when the page opens inside the dashboard.
|
|
361
|
+
3. `hive`.
|
|
362
|
+
|
|
363
|
+
Then the page's `themeTokens` apply on top of the preset. The mode (light or
|
|
364
|
+
dark) always comes from the viewer. `create_page`, `POST /api/pages`, and
|
|
365
|
+
`PUT /api/pages/:id` accept both fields.
|
|
366
|
+
|
|
367
|
+
### `theme`: a preset id
|
|
368
|
+
|
|
369
|
+
| Id | Look |
|
|
370
|
+
|---|---|
|
|
371
|
+
| `hive` | The default: a zinc field with one amber accent. |
|
|
372
|
+
| `meadow`, `iris`, `rose` | The Hive field with an emerald, violet, or deep rose accent. |
|
|
373
|
+
| `cobalt` | A cool slate field with a saturated blue accent. |
|
|
374
|
+
| `ember` | A warm stone field with a burnt orange accent. |
|
|
375
|
+
| `carbon` | Pure monochrome. |
|
|
376
|
+
| `paper` | The warm editorial paper look: an off-white canvas, white cards, warm borders, and a blue accent. |
|
|
377
|
+
| `github`, `vscode`, `material`, `solarized`, `tokyo`, `monokai`, `gruvbox`, `catppuccin` | Classic editor and platform palettes, with their own status colors. |
|
|
378
|
+
|
|
379
|
+
An unknown id fails the write, and the error lists the valid ids. Set `theme`
|
|
380
|
+
only when the page needs a fixed look. Without it, the page matches the
|
|
381
|
+
viewer's dashboard. On an update, `theme: null` clears it. An update or upsert
|
|
382
|
+
that omits `theme` keeps the stored preset.
|
|
383
|
+
|
|
384
|
+
### `themeTokens`: token overrides
|
|
385
|
+
|
|
386
|
+
`themeTokens` overrides individual tokens on top of the preset. Tokens that
|
|
387
|
+
you do not set keep their preset values. The input has two formats: a token
|
|
388
|
+
map (the default) and a CSS block (`"format": "css"`). Another `format` fails
|
|
389
|
+
the write.
|
|
390
|
+
|
|
391
|
+
**Set colors for both modes.** A color that you set only in `light` does not
|
|
392
|
+
reach dark mode. Dark mode keeps the preset's dark value for that token. So
|
|
393
|
+
set each color in both the `light` and the `dark` map, or add a `.dark` block
|
|
394
|
+
in the css format. Fonts and radius have one value for both modes. A font or
|
|
395
|
+
radius token that you set only in `light` applies to dark mode too.
|
|
396
|
+
|
|
397
|
+
**Send the full map.** A write that sends `themeTokens` replaces the stored
|
|
398
|
+
map. It does not merge with it. A token that you leave out goes back to its
|
|
399
|
+
preset value. An update or upsert that omits `themeTokens` keeps the stored
|
|
400
|
+
map. On an update, `themeTokens: null` clears it.
|
|
401
|
+
|
|
402
|
+
A token map:
|
|
403
|
+
|
|
404
|
+
```jsonc
|
|
405
|
+
// Tool call: create_page
|
|
406
|
+
{
|
|
407
|
+
"title": "Launch review",
|
|
408
|
+
"contentType": "text/html",
|
|
409
|
+
"body": "<!doctype html>...",
|
|
410
|
+
"theme": "paper",
|
|
411
|
+
"themeTokens": {
|
|
412
|
+
"light": { "--color-primary": "oklch(0.52 0.15 150)", "--color-ring": "oklch(0.52 0.15 150)", "--radius-xl": "14px" },
|
|
413
|
+
"dark": { "--color-primary": "oklch(0.72 0.14 150)", "--color-ring": "oklch(0.72 0.14 150)" }
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
A CSS block takes the output of shadcn, tweakcn, or a Tailwind v4 `@theme`
|
|
419
|
+
block without changes. A `@theme` block holds light values only, so add a
|
|
420
|
+
`.dark` block for dark mode. Send the block as one string:
|
|
421
|
+
`"themeTokens": { "format": "css", "css": "<the block>" }`. For example, this
|
|
422
|
+
shadcn paste:
|
|
423
|
+
|
|
424
|
+
```css
|
|
425
|
+
:root {
|
|
426
|
+
--radius: 0.5rem;
|
|
427
|
+
--primary: oklch(0.205 0 0);
|
|
428
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
429
|
+
--sidebar: oklch(0.985 0 0);
|
|
430
|
+
}
|
|
431
|
+
.dark {
|
|
432
|
+
--primary: oklch(0.922 0 0);
|
|
433
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
sets the primary colors for both modes and all four radius tokens. `--sidebar`
|
|
438
|
+
is not a page token, so the response lists it in `ignoredTokens`.
|
|
439
|
+
|
|
440
|
+
The importer rules:
|
|
441
|
+
|
|
442
|
+
- `--color-primary`, `--primary`, `color-primary`, and `primary` all name the same token. Font and radius names work the same way (`--font-sans`, `font-sans`).
|
|
443
|
+
- In a CSS block, `:root`, `:host`, `html`, `@theme`, and `@theme inline` set the light values. `.dark`, `:root.dark`, `html.dark`, and `[data-theme=dark]` (quoted or not) set the dark values. So does `:root`, `:host`, or `html` inside `@media (prefers-color-scheme: dark)`. A selector list such as `:root, :host` also works.
|
|
444
|
+
- The importer skips comments and blocks under other selectors. The response lists the custom properties of a skipped block in `ignoredTokens` with the block, for example `--ring (in .card)`. A CSS block with no light or dark block fails the write.
|
|
445
|
+
- A shadcn `--radius` sets all four radius tokens. `sm` is the radius minus 4px, `md` is minus 2px, `lg` is the radius, and `xl` is plus 4px.
|
|
446
|
+
- The importer wraps a bare HSL triplet from an older shadcn theme (`222.2 47.4% 11.2%`) as `hsl(222.2 47.4% 11.2%)`.
|
|
447
|
+
- The importer ignores names outside the token contract, such as `--sidebar`, `--shadow-sm`, and `--font-serif`. It does not reject them. The response lists them in `ignoredTokens`.
|
|
448
|
+
- The importer drops a token whose value references a variable outside the contract, such as `--font-sans: var(--font-geist-sans)`. The response lists it in `ignoredTokens` with the variable that it references, for example `--font-sans (references --font-geist-sans)`. Write the value itself instead, for example a font stack.
|
|
449
|
+
- A value has 1 to 200 characters. It must not contain `;`, `{`, `}`, `<`, `>`, `\`, or a line break. It must not contain `url(`, `expression(`, `@import`, or `javascript:`. A bad value fails the write.
|
|
450
|
+
- The API stores the tokens in normalized form.
|
|
451
|
+
|
|
452
|
+
When you change `--color-primary`, also set `--color-ring`. If the text on the
|
|
453
|
+
new accent needs more contrast, set `--color-primary-foreground` too.
|
|
454
|
+
|
|
455
|
+
Do not set tokens in your own `:root` rule. The theme's dark rule is more
|
|
456
|
+
specific, so your value reaches light mode only.
|
|
457
|
+
|
|
458
|
+
To use another font, load it from Google Fonts in your page `<head>`. Then set
|
|
459
|
+
`--font-sans` in `themeTokens`.
|
|
460
|
+
|
|
461
|
+
## Dark mode
|
|
462
|
+
|
|
463
|
+
Inside the dashboard, a designVersion 2 page follows the viewer's mode. In dark
|
|
464
|
+
mode, the injected head adds the `dark` class to `<html>`, and the tokens
|
|
465
|
+
switch to their dark values. A page built on tokens needs no extra dark-mode
|
|
466
|
+
code.
|
|
467
|
+
|
|
468
|
+
- Do not set `color-scheme` yourself. The theme sets it.
|
|
469
|
+
- A `themeTokens` color that you set only in `light` does not reach dark mode. Set it in both maps (see `themeTokens`).
|
|
470
|
+
- Use the `dark:` variant only for a rare mode-specific change, such as a logo pair: `<img class="dark:hidden" ...>` and `<img class="hidden dark:block" ...>`.
|
|
471
|
+
- A direct link (`api_url`) renders in light mode, with the page `theme` or Hive.
|
|
472
|
+
- To check a page in dark mode, add `?__swarm-mode=dark` to its `api_url`. On a page without a `theme`, add `__swarm-theme=<preset id>` to try a preset.
|
|
473
|
+
- Do not use `__swarm-mode` or `__swarm-theme` as your own query parameters.
|
|
474
|
+
|
|
475
|
+
## Design versions
|
|
476
|
+
|
|
477
|
+
Each page has a `designVersion`. It is separate from the edit `version`
|
|
478
|
+
counter.
|
|
479
|
+
|
|
480
|
+
- `1`: the old head, with the Tailwind v3 Play CDN and the `--swarm-*` hex tokens, in light mode only. Pages created before the design system have version 1. They keep their old look and ignore the viewer's theme and mode.
|
|
481
|
+
- `2`: the design system. New pages get version 2 by default.
|
|
482
|
+
|
|
483
|
+
An upsert or update that omits `designVersion` keeps the stored version. The
|
|
484
|
+
`create_page` result reports the saved `designVersion`. A page created before
|
|
485
|
+
the design system stays on version 1, also when you upsert it with design
|
|
486
|
+
system markup. So pass `designVersion: 2` when you rewrite an old page or
|
|
487
|
+
upsert a recurring report. On a version 2 page, it changes nothing.
|
|
488
|
+
|
|
489
|
+
To move a version 1 page, rewrite it and pass `designVersion: 2`. Then fix these
|
|
490
|
+
Tailwind v3 to v4 changes:
|
|
491
|
+
|
|
492
|
+
| v3 class (version 1) | v4 class (version 2) |
|
|
493
|
+
|---|---|
|
|
494
|
+
| `shadow-sm`, `shadow` | `shadow-xs`, `shadow-sm` |
|
|
495
|
+
| `rounded-sm`, `rounded` | `rounded-xs`, `rounded-sm` |
|
|
496
|
+
| `ring` (3px) | `ring-3`. A bare `ring` is now 1px. |
|
|
497
|
+
| `outline-none` | `outline-hidden`. `outline-none` now sets `outline-style: none`. |
|
|
498
|
+
| `bg-opacity-50` and the other `*-opacity-*` classes | Removed. Use an opacity modifier, such as `bg-primary/50`. |
|
|
499
|
+
| `bg-[--my-var]` | `bg-(--my-var)` |
|
|
500
|
+
|
|
501
|
+
Also check these points:
|
|
502
|
+
|
|
503
|
+
- A bare `border` draws a `--color-border` line (Tailwind v3 drew gray). For another line, name its token, such as `border-border-subtle`.
|
|
504
|
+
- Remove any Tailwind `<script>` or `tailwind.config` that the page loads itself. The head already loads Tailwind v4.
|
|
505
|
+
- Do not write any `@import` in a `text/tailwindcss` block. `@import "tailwindcss"` enables Preflight again, and the browser also requests every `@import` path as a file next to the page.
|
|
506
|
+
- Replace the color literals with tokens.
|
|
88
507
|
|
|
89
508
|
## Universal baseline
|
|
90
509
|
|
|
91
|
-
The
|
|
92
|
-
|
|
510
|
+
The design system overrides `taste-minimalist-skill`. It replaces every color,
|
|
511
|
+
font, spacing, and motion value in the taste skill. Use the taste skill only
|
|
512
|
+
for restraint in layout and copy.
|
|
93
513
|
|
|
94
|
-
-
|
|
95
|
-
- Build a clear type hierarchy with
|
|
96
|
-
- Use
|
|
97
|
-
- Prefer flat surfaces: crisp `1px` borders
|
|
98
|
-
- Use
|
|
514
|
+
- Keep the canvas quiet. Let the theme supply the field and the text colors, and use the accent sparingly.
|
|
515
|
+
- Build a clear type hierarchy with the built-in heading scale. Use `font-mono` for IDs, metadata, and machine output. The head already styles `<code>`, `<pre>`, and `<kbd>`.
|
|
516
|
+
- Use whitespace and strong alignment. Give summaries room to breathe and keep tables compact enough to scan.
|
|
517
|
+
- Prefer flat surfaces: crisp `1px` borders and practically no shadows.
|
|
518
|
+
- Use motion only where it clarifies hierarchy or interaction state. Do not animate content blocks on scroll.
|
|
99
519
|
- Keep visual language quiet and precise: no AI-purple gradient mesh, centered hero plus three equal cards, decorative glassmorphism, emojis as UI decoration, fake screenshots made from rectangles, oversized decorative art, nested cards, or low-contrast text.
|
|
100
520
|
- Make responsive behavior explicit: readable type, stable grids, horizontal table scroll where needed, and no overlapping content.
|
|
101
521
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
522
|
+
When the full `taste-minimalist-skill` source is available, take only its
|
|
523
|
+
restraint rules: the banned elements, and plain, specific copy with realistic
|
|
524
|
+
names and no AI clichés. Ignore its hex colors, font stacks, `py-24` and
|
|
525
|
+
`py-32` section padding, scroll animations, background gradients, fake window
|
|
526
|
+
chrome, and uppercase badges. The tokens, the element defaults, and the
|
|
527
|
+
`swarm-*` primitives replace them.
|
|
105
528
|
|
|
106
529
|
## Report density layer
|
|
107
530
|
|
|
@@ -113,16 +536,14 @@ information-architecture layer, not a separate aesthetic.
|
|
|
113
536
|
Every dense page should be useful at a glance.
|
|
114
537
|
|
|
115
538
|
- Put the page's point in the first viewport: title, one-sentence summary, and 3-6 key numbers or statuses.
|
|
116
|
-
- Use a single-column reading spine
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
- Prefer flat bordered cards only for repeated records or metrics. Do not nest cards inside cards.
|
|
123
|
-
- Use shadows only when they solve a hierarchy problem; keep them ultra-diffuse and below `0.05` opacity.
|
|
539
|
+
- Use a single-column reading spine (`.swarm-page`, 1120px wide). Keep prose near 65-75 characters, and use denser grids only for metrics and evidence.
|
|
540
|
+
- For your own gaps and margins, use the steps that the primitives use most: 4, 8, 12, 16, 24, and 40px. In Tailwind units, that is `1`, `2`, `3`, `4`, `6`, and `10` (for example, `gap-4` is 16px).
|
|
541
|
+
- Keep the built-in type scale (`h1` about 30px, body 15px). Do not inflate titles to hero sizes.
|
|
542
|
+
- Keep tables readable: `.swarm-table` gives a sticky header, padded cells, subtle row rules, and tabular numbers. Put it in a `.swarm-table-wrap` so it scrolls on narrow screens.
|
|
543
|
+
- Prefer flat bordered panels only for repeated records or metrics. Do not nest panels inside panels. A `.swarm-table-wrap` is already a panel.
|
|
544
|
+
- Use a shadow only when it solves a hierarchy problem, and keep it barely visible (`shadow-xs`).
|
|
124
545
|
- Hide raw JSON behind a collapsed `<details>` block at the bottom.
|
|
125
|
-
-
|
|
546
|
+
- Mobile is built in. At 640px wide and below, the body padding drops to 16px. The metric grid and the toolbar wrap, and a toolbar search input grows to fill its row. Add responsive variants only for your own grids, such as `grid-cols-1 md:grid-cols-2`. Allow no overflow except table scroll.
|
|
126
547
|
|
|
127
548
|
## Content structure
|
|
128
549
|
|
|
@@ -150,9 +571,9 @@ Before publishing:
|
|
|
150
571
|
- Raw JSON/logs are collapsed or linked, not the primary experience.
|
|
151
572
|
- No nested cards, decorative gradients, oversized art, or cramped default browser styles.
|
|
152
573
|
- No text overlaps, clipped buttons, or unreadable low-contrast text.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
574
|
+
- No color literals. Every color comes from a token, in CSS or as a Tailwind class.
|
|
575
|
+
- The page reads well in light and dark mode. Add `?__swarm-mode=dark` to the `api_url` to check.
|
|
576
|
+
- The `create_page` result shows `designVersion: 2`. If it shows 1, publish again with `designVersion: 2`.
|
|
156
577
|
|
|
157
578
|
---
|
|
158
579
|
|
|
@@ -180,7 +601,7 @@ To check a page by screenshot, open it from an origin its data endpoints allow.
|
|
|
180
601
|
| URL | Shape | Notes |
|
|
181
602
|
|---|---|---|
|
|
182
603
|
| `app_url` | `${APP_URL}/pages/:id` | SPA route. Renders HTML in a sandboxed iframe, JSON via `@json-render/react`. Default share target. |
|
|
183
|
-
| `app_url` (full mode) | `${APP_URL}/pages/:id?mode=full` | Same SPA route, maximized
|
|
604
|
+
| `app_url` (full mode) | `${APP_URL}/pages/:id?mode=full` | Same SPA route, maximized: hides the SPA sidebar/header so the page body gets the full viewport. Slim header with title + Exit-Full button. Useful for embeds + standalone dashboards. |
|
|
184
605
|
| `api_url` | `${MCP_BASE_URL}/p/:id` | Direct API render. HTML inlines and serves; JSON 302-redirects to `app_url`. Useful for no-SPA-required links. |
|
|
185
606
|
|
|
186
607
|
`${APP_URL}` is the deployment's SPA origin and `${MCP_BASE_URL}` is its API
|
|
@@ -199,14 +620,14 @@ where the unfurl preview only follows the API origin).
|
|
|
199
620
|
Every overwrite (update via `update_page` or `PUT /api/pages/:id`) snapshots
|
|
200
621
|
the **pre-update** state into `page_versions` and writes the new state to the
|
|
201
622
|
parent row. The wire `version` field is a monotonically-increasing
|
|
202
|
-
"edit counter"
|
|
623
|
+
"edit counter": version 1 is the initial create.
|
|
203
624
|
|
|
204
625
|
| Operation | Endpoint | Returns |
|
|
205
626
|
|---|---|---|
|
|
206
627
|
| List versions | `GET /api/pages/:id/versions` | `{ versions: PageVersion[] }` newest first |
|
|
207
628
|
| Read a version | `GET /api/pages/:id/versions/:version` | Single snapshot |
|
|
208
629
|
|
|
209
|
-
Snapshots are full body copies
|
|
630
|
+
Snapshots are full body copies. Keep this in mind for large pages (the
|
|
210
631
|
per-version body cap is 5 MiB).
|
|
211
632
|
|
|
212
633
|
## Browser SDK
|
|
@@ -214,8 +635,8 @@ per-version body cap is 5 MiB).
|
|
|
214
635
|
Every HTML page automatically gets `window.SwarmSDK` (the class) and
|
|
215
636
|
`window.swarmSdk` (a ready-to-use singleton) injected. The SDK routes through
|
|
216
637
|
the `/@swarm/api/*` proxy, which resolves the page's own `page_session_<id>`
|
|
217
|
-
cookie to a user identity and forwards with proper auth headers server-side
|
|
218
|
-
|
|
638
|
+
cookie to a user identity and forwards with proper auth headers server-side.
|
|
639
|
+
Your page never sees or handles tokens. The SDK names its page in the
|
|
219
640
|
`X-Swarm-Page-Id` header. A direct `fetch('/@swarm/api/...')` from the page
|
|
220
641
|
works too: the proxy falls back to the `/p/<id>` Referer.
|
|
221
642
|
|
|
@@ -239,7 +660,7 @@ Inline usage:
|
|
|
239
660
|
|
|
240
661
|
```html
|
|
241
662
|
<script>
|
|
242
|
-
// Singleton is ready immediately
|
|
663
|
+
// Singleton is ready immediately: no `new SwarmSDK()` needed.
|
|
243
664
|
const tasks = await window.swarmSdk.tasks.list({ status: 'in_progress' });
|
|
244
665
|
const agents = await window.swarmSdk.agents.list();
|
|
245
666
|
|
|
@@ -263,7 +684,7 @@ HTTP status.
|
|
|
263
684
|
|
|
264
685
|
### Full signature
|
|
265
686
|
|
|
266
|
-
This is the entire surface
|
|
687
|
+
This is the entire surface. Copy it into your page if you want autocomplete
|
|
267
688
|
hints in an editor. The runtime version is auto-injected; you don't need to
|
|
268
689
|
include this in the page source.
|
|
269
690
|
|
|
@@ -323,21 +744,25 @@ class SwarmSDK {
|
|
|
323
744
|
|
|
324
745
|
For the full list of fields each endpoint accepts/returns, see
|
|
325
746
|
[**docs.agent-swarm.dev/docs/api-reference**](https://docs.agent-swarm.dev/docs/api-reference).
|
|
326
|
-
The SDK is a thin domain wrapper
|
|
747
|
+
The SDK is a thin domain wrapper: anything documented there is reachable.
|
|
327
748
|
|
|
328
|
-
## Built-in
|
|
749
|
+
## Built-in web components
|
|
329
750
|
|
|
330
|
-
Every HTML page automatically gets a small set of zero-dep web components
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
751
|
+
Every HTML page automatically gets a small set of zero-dep web components,
|
|
752
|
+
injected beside the Browser SDK. Put them in your page body. They need no
|
|
753
|
+
`<script>` import, no bundling, and no Tailwind. Tailwind utilities also work:
|
|
754
|
+
Tailwind v4 on designVersion 2 pages, and the Tailwind v3 Play CDN on
|
|
755
|
+
designVersion 1 pages. For the `swarm-*` CSS classes, see Primitives under
|
|
756
|
+
Design system.
|
|
334
757
|
|
|
335
|
-
### `<swarm-diff
|
|
758
|
+
### `<swarm-diff>`: unified diff renderer
|
|
336
759
|
|
|
337
760
|
Render a unified diff with a two-column gutter, severity annotations, and a
|
|
338
761
|
deterministic anchor id per hunk (so deep-linking + jump lists work). The
|
|
339
762
|
element reads its payload from its `textContent` as JSON of shape
|
|
340
763
|
`{ hunks: [{ old_start, old_lines, new_start, new_lines, lines, annotations? }] }`.
|
|
764
|
+
On designVersion 2 pages, its colors and fonts follow the theme tokens and dark
|
|
765
|
+
mode.
|
|
341
766
|
|
|
342
767
|
```html
|
|
343
768
|
<swarm-diff
|
|
@@ -345,21 +770,25 @@ element reads its payload from its `textContent` as JSON of shape
|
|
|
345
770
|
base-sha="abc123"
|
|
346
771
|
head-sha="def456">
|
|
347
772
|
{ "hunks": [
|
|
348
|
-
{ "old_start": 10, "old_lines":
|
|
773
|
+
{ "old_start": 10, "old_lines": 2, "new_start": 10, "new_lines": 3,
|
|
349
774
|
"lines": [
|
|
350
|
-
{ "type": "context", "text": "
|
|
351
|
-
{ "type": "del", "text": "
|
|
352
|
-
{ "type": "add", "text": "
|
|
353
|
-
{ "type": "add", "text": "
|
|
775
|
+
{ "type": "context", "text": "export function load(id) {" },
|
|
776
|
+
{ "type": "del", "text": " console.log(id);" },
|
|
777
|
+
{ "type": "add", "text": " logger.info({ id });" },
|
|
778
|
+
{ "type": "add", "text": " return cache.get(id);" }
|
|
354
779
|
],
|
|
355
780
|
"annotations": [
|
|
356
|
-
{ "line": 12, "severity": "warn", "text": "
|
|
781
|
+
{ "line": 12, "severity": "warn", "text": "Returns undefined on a cache miss" }
|
|
357
782
|
]
|
|
358
783
|
}
|
|
359
784
|
] }
|
|
360
785
|
</swarm-diff>
|
|
361
786
|
```
|
|
362
787
|
|
|
788
|
+
The browser reads the JSON as HTML text first. Inside the JSON, write `<` as
|
|
789
|
+
`\u003c` and `&` as `\u0026`. Otherwise the browser turns
|
|
790
|
+
`Promise<void>` into a tag, and `&` into `&`.
|
|
791
|
+
|
|
363
792
|
**Inputs**
|
|
364
793
|
|
|
365
794
|
| Attribute | Required | Notes |
|
|
@@ -368,28 +797,47 @@ element reads its payload from its `textContent` as JSON of shape
|
|
|
368
797
|
| `base-sha` | no | Pre-change SHA. Rendered in the header next to `head-sha`. |
|
|
369
798
|
| `head-sha` | no | Post-change SHA. |
|
|
370
799
|
|
|
800
|
+
**Hunk shape**
|
|
801
|
+
|
|
802
|
+
| Field | Notes |
|
|
803
|
+
|---|---|
|
|
804
|
+
| `old_start`, `new_start` | The first line number on the old side and on the new side. |
|
|
805
|
+
| `old_lines` | The number of context and deleted lines in the hunk. |
|
|
806
|
+
| `new_lines` | The number of context and added lines in the hunk. |
|
|
807
|
+
|
|
808
|
+
The hunk header shows `@@ -old_start,old_lines +new_start,new_lines @@`. The
|
|
809
|
+
component prints the counts that you send. It does not check them.
|
|
810
|
+
|
|
371
811
|
**Line shape**
|
|
372
812
|
|
|
373
813
|
| Field | Values | Notes |
|
|
374
814
|
|---|---|---|
|
|
375
815
|
| `type` | `context` \| `add` \| `del` | Drives row tint (green / red / neutral) and gutter line numbering. |
|
|
376
|
-
| `text` | string |
|
|
816
|
+
| `text` | string | The line without its `+`, `-`, or space marker. The component draws the marker in its own column. Keep the indentation. The text is HTML-escaped. |
|
|
377
817
|
|
|
378
|
-
**Annotation shape
|
|
379
|
-
as a margin badge on that row.
|
|
818
|
+
**Annotation shape**: a margin badge on one row.
|
|
380
819
|
|
|
381
820
|
| Field | Values | Notes |
|
|
382
821
|
|---|---|---|
|
|
383
|
-
| `line` | integer |
|
|
822
|
+
| `line` | integer | The new-side line number of an added or context row. For a deleted row, use its old-side number. If a deleted row and another row have that number, the badge shows on both. |
|
|
384
823
|
| `severity` | `error` \| `warn` \| `info` | Drives badge color. |
|
|
385
824
|
| `text` | string | Badge body. |
|
|
386
825
|
|
|
387
826
|
**Anchor id**
|
|
388
827
|
|
|
389
|
-
Each hunk gets `id="swarm-diff-<
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
828
|
+
Each hunk gets an anchor with `id="swarm-diff-<slug>"`. The slug is
|
|
829
|
+
`<file>-<old_start>` in lowercase. Each run of characters other than `a-z` and
|
|
830
|
+
`0-9` becomes one `-`, and a `-` at the start or end is removed. For example,
|
|
831
|
+
`file="src/foo.ts"` with `old_start: 10` gives `id="swarm-diff-src-foo-ts-10"`.
|
|
832
|
+
Without `file`, the slug starts with `hunk`. When `old_start` is 0 or missing,
|
|
833
|
+
the slug ends with the hunk's position (1 for the first hunk). Two hunks with
|
|
834
|
+
the same file and `old_start` get the same id, so keep them unique.
|
|
835
|
+
|
|
836
|
+
Link to a hunk with `href="#swarm-diff-src-foo-ts-10"`. On a designVersion 1
|
|
837
|
+
page, add `target="_self"` to the link, or it opens in a new tab. Use
|
|
838
|
+
`<swarm-diff-jumps></swarm-diff-jumps>` anywhere in the page body to render a
|
|
839
|
+
tiny "Jump to" navigation of every diff hunk on the page. It is handy when an
|
|
840
|
+
agent ships a multi-file annotated PR.
|
|
393
841
|
|
|
394
842
|
**Programmatic form**
|
|
395
843
|
|
|
@@ -409,21 +857,26 @@ A full annotated-PR page using `<swarm-diff>` is bundled at
|
|
|
409
857
|
|
|
410
858
|
## Print / PDF export
|
|
411
859
|
|
|
412
|
-
Every HTML page also gets
|
|
413
|
-
|
|
414
|
-
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
860
|
+
Every HTML page also gets `@media print` rules in its injected head. Print is
|
|
861
|
+
always light:
|
|
862
|
+
- A designVersion 2 page prints with its light tokens, also when the viewer
|
|
863
|
+
runs dark mode.
|
|
864
|
+
- The page prints on a white background, with black text and underlined
|
|
865
|
+
links.
|
|
866
|
+
- Anything with the `.no-print` class is hidden. Annotation badges and the
|
|
867
|
+
jump list already carry this class. Add it to page chrome that you want out
|
|
868
|
+
of the PDF.
|
|
869
|
+
- `.swarm-panel`, `.swarm-card`, `.swarm-metric`, and `<swarm-diff>` get
|
|
870
|
+
`break-inside: avoid`, so they do not split across pages. (On designVersion
|
|
871
|
+
1 pages, only `.swarm-card` and `<swarm-diff>` get it.)
|
|
872
|
+
|
|
873
|
+
Trigger the export from the SPA's "Export PDF" button on `/pages/:id`. It
|
|
421
874
|
opens the iframe's native print dialog (HTML pages) or the SPA's print
|
|
422
|
-
dialog (JSON pages). The browser's "Print → Save as PDF"
|
|
423
|
-
file. No headless Chromium, no server-side rendering
|
|
875
|
+
dialog (JSON pages). The browser's "Print → Save as PDF" makes the actual
|
|
876
|
+
file. No headless Chromium, no server-side rendering, zero infra weight.
|
|
424
877
|
|
|
425
|
-
> Want a custom print layout?
|
|
426
|
-
> `<style>` block
|
|
878
|
+
> Want a custom print layout? Add `@media print` rules to your page's own
|
|
879
|
+
> `<style>` block.
|
|
427
880
|
|
|
428
881
|
## Viewer feedback
|
|
429
882
|
|
|
@@ -458,7 +911,7 @@ redirecting to the SPA), `401`/`403` (auth gate), and `404` do NOT bump.
|
|
|
458
911
|
The count is exposed on `GET /api/pages` listing (`viewCount` field) and the
|
|
459
912
|
SPA `/pages` index renders it as a small eye-count badge per row.
|
|
460
913
|
|
|
461
|
-
No per-viewer dedup
|
|
914
|
+
No per-viewer dedup: this is a coarse popularity signal, not analytics.
|
|
462
915
|
Bumps are best-effort (wrapped in try/catch so a counter write never fails
|
|
463
916
|
the response).
|
|
464
917
|
|
|
@@ -499,7 +952,7 @@ See the `@json-render/core` docs for the supported node types (`text`,
|
|
|
499
952
|
`passwordHash`) and the page's own KV. Every other route returns 403, and every RBAC verb denies a guest.
|
|
500
953
|
- Browser SDK memory operations use the page owner's agent scope through verified page execution context.
|
|
501
954
|
Viewer authentication, permissions, and audit identity remain separate from this resource scope.
|
|
502
|
-
- Treat agent-generated HTML / JSON like trusted code
|
|
955
|
+
- Treat agent-generated HTML / JSON like trusted code: the agent already
|
|
503
956
|
has equivalent MCP access, so a malicious page is no worse than a
|
|
504
957
|
malicious tool call. But: don't ship pages to **external** users (via
|
|
505
958
|
`password`) without reviewing the body first.
|
|
@@ -509,14 +962,14 @@ See the `@json-render/core` docs for the supported node types (`text`,
|
|
|
509
962
|
page still has the SwarmSDK access of its session: full for user and
|
|
510
963
|
operator sessions, page record and KV only for password guests.
|
|
511
964
|
- All page bodies pass through `scrubSecrets` at the egress boundary
|
|
512
|
-
(`/p/:id`, `/p/:id.json`, listing endpoint)
|
|
965
|
+
(`/p/:id`, `/p/:id.json`, listing endpoint). Accidental secrets in
|
|
513
966
|
the body get masked at serve time, not at write time. Don't rely on
|
|
514
|
-
scrubbing as a security boundary
|
|
967
|
+
scrubbing as a security boundary. Keep secrets out of bodies.
|
|
515
968
|
|
|
516
969
|
## Limits
|
|
517
970
|
|
|
518
971
|
- **Body size**: 5 MiB per version (HTML or JSON). Bumping requires careful
|
|
519
|
-
thought about SQLite write-amplification
|
|
972
|
+
thought about SQLite write-amplification: full bodies are snapshotted on
|
|
520
973
|
every update.
|
|
521
974
|
- **TTL**: none. Pages persist until explicitly deleted via `DELETE
|
|
522
975
|
/api/pages/:id` (or the SPA listing UI when it gains a delete affordance).
|
|
@@ -538,11 +991,11 @@ human-facing summary.
|
|
|
538
991
|
|
|
539
992
|
## See Also
|
|
540
993
|
|
|
541
|
-
- The **`apps`** skill
|
|
542
|
-
- The **`agent-fs`** skill
|
|
543
|
-
- The **`kv-storage`** skill
|
|
544
|
-
- `runbooks/secret-scrubbing.md
|
|
545
|
-
- SPA listing: `${APP_URL}/pages
|
|
994
|
+
- The **`apps`** skill: schema-backed records, named queries, and actions.
|
|
995
|
+
- The **`agent-fs`** skill: durable file storage and share links.
|
|
996
|
+
- The **`kv-storage`** skill: page-scoped state via `swarmSdk.kv`.
|
|
997
|
+
- `runbooks/secret-scrubbing.md`: egress scrubbing details.
|
|
998
|
+
- SPA listing: `${APP_URL}/pages`, the same `APP_URL` used for share links above.
|
|
546
999
|
Prefer the `app_url` that `create_page` returns; build URLs by hand only when
|
|
547
1000
|
you have no page id.
|
|
548
1001
|
|
|
@@ -609,7 +1062,7 @@ Array insertion takes `path`, `index`, and `values`. Text editing takes `path`,
|
|
|
609
1062
|
Presence updates default to one transmission per 50 milliseconds. Presence never enters the persisted document.
|
|
610
1063
|
Use `await room.close()` when the page no longer needs a room.
|
|
611
1064
|
|
|
612
|
-
### `<swarm-cursors
|
|
1065
|
+
### `<swarm-cursors>`: shared page pointers
|
|
613
1066
|
|
|
614
1067
|
Add this element to opt a page into named cursors for an existing room:
|
|
615
1068
|
|