@desplega.ai/agent-swarm 1.173.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{acp-adapter-ccm9xrep.js → acp-adapter-sj2g0m84.js} +17 -16
- package/dist/{actions-sgeyv08k.js → actions-fegk44gr.js} +39 -34
- package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-ad8ft89x.js} +8 -7
- package/dist/{app-km9qnv2f.js → app-kfvgbvzy.js} +18 -14
- package/dist/{assistant-5r8tcvvd.js → assistant-z7zdy9ja.js} +40 -35
- package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-5c2z0mbe.js} +10 -9
- package/dist/{boot-reembed-16rv9843.js → boot-reembed-j8xa181e.js} +10 -9
- package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-hnkn3rgt.js} +11 -10
- package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-kwjq4d2z.js} +14 -13
- package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-9vmvpvgd.js} +19 -18
- package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-k9qae05j.js} +7 -5
- package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-q54zx5q2.js} +6 -4
- package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-9jye6cxr.js} +11881 -11472
- package/dist/{cli-94b48jhk.js → cli-03gedhng.js} +16 -14
- package/dist/{cli-1w0vj3gw.js → cli-1e4b6bzh.js} +7 -7
- package/dist/{cli-d603qf86.js → cli-29jc5q7w.js} +10 -8
- package/dist/cli-2m1ktfzz.js +17795 -0
- package/dist/{cli-x119kdba.js → cli-3dj8k4vy.js} +1 -1
- package/dist/{cli-srqq3gc5.js → cli-3fbmmawm.js} +5 -5
- package/dist/{cli-gmdajfw5.js → cli-4jxm2qtz.js} +4987 -1708
- package/dist/{cli-tadfgd0t.js → cli-5hkm7whv.js} +33 -4
- package/dist/{cli-42qhyvwx.js → cli-5t4f29ez.js} +3 -3
- package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
- package/dist/cli-6cvfxs8r.js +47 -0
- package/dist/{cli-0kxf81jj.js → cli-6jyj59nb.js} +2 -2
- package/dist/{cli-w1apjecb.js → cli-6razj6t4.js} +2 -2
- package/dist/{cli-anzdk0z4.js → cli-74ahz61x.js} +2 -2
- package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
- package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
- package/dist/{cli-81r1wjyv.js → cli-9nfx44eh.js} +1 -1
- package/dist/cli-9traj3dn.js +638 -0
- package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
- package/dist/{cli-na2pxe4f.js → cli-apx87jne.js} +2 -2
- package/dist/{cli-rfz2ve55.js → cli-bzszjf2p.js} +2855 -862
- package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
- package/dist/{cli-hsem16hb.js → cli-cgtksawx.js} +7 -4
- package/dist/{cli-db3m6zdt.js → cli-d2qr7aj4.js} +1 -1
- package/dist/{cli-rfs4vddv.js → cli-d5f9ed5c.js} +5 -5
- package/dist/cli-e3g5mbkz.js +776 -0
- package/dist/{cli-7jykv7ef.js → cli-e6mpjhed.js} +1 -1
- package/dist/{cli-7a93cv8c.js → cli-ee9gtz70.js} +98 -23
- package/dist/{cli-3nxdmjrc.js → cli-eejsgvm4.js} +4 -4
- package/dist/{cli-fmhj1ehj.js → cli-ef1hg1wv.js} +470 -51
- package/dist/cli-f527ce74.js +781 -0
- package/dist/{cli-ppy4nnnh.js → cli-f7kr7svz.js} +2 -2
- package/dist/cli-hjwmhcg1.js +10622 -0
- package/dist/{cli-2bw3w47j.js → cli-hnhtk6cj.js} +1 -1
- package/dist/{cli-ywm1azg9.js → cli-hnmhtzvh.js} +6 -4
- package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
- package/dist/{cli-s8z6x4b4.js → cli-j0pfptdp.js} +218 -102
- package/dist/cli-jta2eyzc.js +619 -0
- package/dist/{cli-5er5gjbm.js → cli-k382tshb.js} +10 -11
- package/dist/{cli-v3zhnxsb.js → cli-k3dp5tpf.js} +2 -2
- package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
- package/dist/cli-kceah1eh.js +92 -0
- package/dist/{cli-ne7smj1b.js → cli-ke896fcf.js} +10 -10
- package/dist/{cli-xc7p7s3g.js → cli-kt6zqg0e.js} +6 -6
- package/dist/{cli-wrh08zjd.js → cli-m50t4309.js} +5 -18
- package/dist/cli-n2wq4j7m.js +6985 -0
- package/dist/{cli-bv2etw2y.js → cli-n3hzg89b.js} +46 -15
- package/dist/{cli-tmhsxhb8.js → cli-n5vwg842.js} +23 -6
- package/dist/{cli-qm1448f9.js → cli-ne236afy.js} +8 -8
- package/dist/{cli-d161g69q.js → cli-p1x85d2t.js} +50 -2
- package/dist/{cli-7pz3b7x5.js → cli-przpmdgr.js} +25 -0
- package/dist/{cli-0a7mm3zp.js → cli-q0ke1yww.js} +25 -21
- package/dist/{cli-e3pmyt39.js → cli-q50942rs.js} +1 -1
- package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
- package/dist/{cli-phcqp1b9.js → cli-r2pnvj8g.js} +2 -2
- package/dist/{cli-jpc4r224.js → cli-r62a35ea.js} +19 -3
- package/dist/{cli-cd0hv9nh.js → cli-ra0xzggj.js} +2 -2
- package/dist/cli-rhs9pz33.js +294 -0
- package/dist/{cli-r4fqfpwf.js → cli-s2sp957d.js} +50 -27
- package/dist/{cli-1x7da0de.js → cli-s4setq91.js} +8 -8
- package/dist/{cli-6thk4jz3.js → cli-se8w6wny.js} +6 -6
- package/dist/cli-skxvvpap.js +10140 -0
- package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
- package/dist/{cli-0p3enk35.js → cli-tqaazemc.js} +9 -1
- package/dist/{cli-nwrdx840.js → cli-tr4sxp68.js} +3 -3
- package/dist/{cli-r0byd61h.js → cli-tsde1hdr.js} +15 -15
- package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
- package/dist/{cli-6r2f7edk.js → cli-v1yb0rqb.js} +6 -6
- package/dist/{cli-saqyage0.js → cli-vatyhshy.js} +179 -27
- package/dist/{cli-5wpw4rab.js → cli-vdach5a9.js} +5 -5
- package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
- package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
- package/dist/{cli-c3rk1v0x.js → cli-wayw93nt.js} +3 -3
- package/dist/cli-wmgrkscj.js +23254 -0
- package/dist/{cli-9xf7fdtp.js → cli-z5jjpaxw.js} +29 -6
- package/dist/{cli-451ks6aw.js → cli-zkpks3r3.js} +1 -1
- package/dist/cli.js +29 -45
- package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-y81sssk0.js} +15 -14
- package/dist/{codex-login-841kv5fk.js → codex-login-f2rcfpp9.js} +3 -2
- package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-8vx4j6a9.js} +15 -14
- package/dist/{commands-z8fq9qna.js → commands-kcpvpcrr.js} +11 -10
- package/dist/{controller-hq5ggpcp.js → controller-ywrmt6yd.js} +5 -4
- package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-kwpvj3rf.js} +42 -37
- package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-cehv1qns.js} +7 -6
- package/dist/{db-yyhqqrbf.js → db-k8ankj20.js} +12 -11
- package/dist/{db-qfpq4bt7.js → db-ww5d7jq3.js} +28 -9
- package/dist/{devin-adapter-xgtj680j.js → devin-adapter-x1022qb1.js} +3 -2
- package/dist/{dispatcher-x0x7qfcq.js → dispatcher-e8gq5m68.js} +38 -33
- package/dist/{docker-f503k9p0.js → docker-ff6y1190.js} +3 -2
- package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-3epjm3af.js} +7 -6
- package/dist/{e2b-66xra4az.js → e2b-8ygwhg0f.js} +4 -3
- package/dist/{e2b-xwhyj8cw.js → e2b-swhnpw3n.js} +4 -3
- package/dist/{event-bus-vjtv82gm.js → event-bus-6axnngdj.js} +3 -2
- package/dist/{external-channel-h1fjecwe.js → external-channel-h3359cwn.js} +11 -10
- package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
- package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
- package/dist/{grok-adapter-e7mr287e.js → grok-adapter-0d4x7gkx.js} +18 -17
- package/dist/{handlers-znb9n7d4.js → handlers-an1gzv21.js} +41 -36
- package/dist/{heartbeat-bm4qkn8d.js → heartbeat-6dakeb61.js} +43 -38
- package/dist/{hook-254r4mza.js → hook-6v6cv6d5.js} +11 -23
- package/dist/{hook-xaa3q80s.js → hook-sa5xye4y.js} +12 -11
- package/dist/{http-3dgrgp8y.js → http-r7f3eky0.js} +1499 -251
- package/dist/index-52j1aja4.js +3465 -0
- package/dist/{index-fx3jqq1e.js → index-7ep4gzdk.js} +38 -33
- package/dist/index-9gw58n4k.js +193 -0
- package/dist/index-9j87mcm8.js +56305 -0
- package/dist/index-bsmcresk.js +79424 -0
- package/dist/index-mh85qhec.js +475 -0
- package/dist/{index-g2byveez.js → index-rmpw9a8q.js} +38 -33
- package/dist/{index-2ybk7khy.js → index-s2wxgzr0.js} +468 -683
- package/dist/{index-bdsqa799.js → index-v1v6n7hg.js} +43 -38
- package/dist/index-we27kd31.js +12810 -0
- package/dist/{index-jd7sejm2.js → index-zk96aq1k.js} +10 -9
- package/dist/{keepalive-6ywhpja1.js → keepalive-be9vwy5h.js} +12 -11
- package/dist/{lead-cw45n21s.js → lead-0861cwrf.js} +61 -56
- package/dist/{maintenance-ss1a1ge9.js → maintenance-mzzgc8bn.js} +10 -9
- package/dist/{node-fkajaq96.js → node-mn1zs7an.js} +2 -1
- package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-cpdnfwdj.js} +11 -10
- package/dist/{onboard-8hzdhc1k.js → onboard-fh8qs4r3.js} +11 -3
- package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-nm42wwj8.js} +18 -13
- package/dist/{otel-impl-e6mnvc4v.js → otel-impl-x6c1c9g4.js} +242 -868
- package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-9n2ya240.js} +244 -106
- package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-qb0rv0ap.js} +12 -11
- package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-1gzdwbh1.js} +11 -10
- package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-3mraey52.js} +12 -11
- package/dist/{render-v2-907cy6sa.js → render-v2-agpa45zz.js} +18 -14
- package/dist/{resume-42stcaz0.js → resume-x0ydy9s9.js} +25 -21
- package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
- package/dist/{setup-adbc1c10.js → setup-as9ga0d6.js} +2 -2
- package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
- package/dist/{work-objects-wpj8ck95.js → work-objects-y5g1y7ev.js} +41 -36
- package/dist/{worker-bzdra9rf.js → worker-860c3e38.js} +61 -56
- package/dist/{x-qfmygqqv.js → x-m477fr0h.js} +3 -2
- package/openapi.json +523 -344
- package/package.json +10 -11
- package/src/be/config-refs.ts +60 -0
- package/src/be/db/page-versions.ts +15 -0
- package/src/be/db/runtime.ts +35 -8
- package/src/be/db/skill-name-resolution.ts +36 -0
- package/src/be/db/tasks/read.ts +230 -0
- package/src/be/db/tasks/write.ts +7 -0
- package/src/be/db.ts +52 -7
- package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
- package/src/be/migrations/216_task_resolved_effort.sql +5 -0
- package/src/be/migrations/217_chat_sdk_state.sql +104 -0
- package/src/be/model-catalog-store.ts +5 -1
- package/src/be/model-tier-resolution.ts +12 -1
- package/src/be/model-validation.ts +5 -2
- package/src/be/models-catalog.ts +26 -1
- package/src/be/modelsdev-cache.json +198 -63
- package/src/be/modelsdev-cache.ts +9 -1
- package/src/be/script-credential-broker.ts +39 -2
- package/src/be/scripts/run-saved.ts +1 -0
- package/src/be/scripts/typecheck.ts +10 -8
- package/src/be/seed/runner.ts +13 -1
- package/src/be/seed/state-db.ts +5 -0
- package/src/be/seed/types.ts +6 -0
- package/src/be/seed-pricing.ts +19 -2
- package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
- package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
- package/src/be/seed-skills/bundled-files.generated.json +0 -18
- package/src/be/seed-skills/index.ts +104 -3
- package/src/be/swarm-config-guard.ts +52 -0
- package/src/cli.tsx +0 -16
- package/src/commands/onboard/non-interactive.ts +4 -2
- package/src/commands/provider-credentials.ts +52 -6
- package/src/commands/runner.ts +190 -54
- package/src/e2b/env.ts +5 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +45 -0
- package/src/extensions/dispatcher.ts +7 -0
- package/src/extensions/post-bridge.ts +40 -0
- package/src/github/handlers.ts +11 -4
- package/src/heartbeat/templates.ts +8 -5
- package/src/hooks/hook.ts +0 -26
- package/src/http/all-routes.ts +0 -1
- package/src/http/config.ts +36 -17
- package/src/http/core.ts +4 -0
- package/src/http/index.ts +14 -2
- package/src/http/integrations.ts +88 -1
- package/src/http/mcp.ts +15 -5
- package/src/http/page-proxy.ts +2 -4
- package/src/http/pages-public.ts +3 -3
- package/src/http/pages.ts +3 -13
- package/src/http/poll.ts +28 -68
- package/src/http/requested-by.ts +54 -0
- package/src/http/scripts.ts +1 -0
- package/src/http/stats.ts +1 -30
- package/src/http/tasks.ts +61 -5
- package/src/http/utils.ts +14 -0
- package/src/http/webhooks.ts +159 -1
- package/src/http/x.ts +1 -0
- package/src/integrations/chat-sdk/adapters.ts +129 -0
- package/src/integrations/chat-sdk/attachments.ts +232 -0
- package/src/integrations/chat-sdk/background.ts +36 -0
- package/src/integrations/chat-sdk/commands.ts +194 -0
- package/src/integrations/chat-sdk/config.ts +198 -0
- package/src/integrations/chat-sdk/discord-api.ts +63 -0
- package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
- package/src/integrations/chat-sdk/handlers.ts +28 -0
- package/src/integrations/chat-sdk/inbound.ts +426 -0
- package/src/integrations/chat-sdk/limits.ts +48 -0
- package/src/integrations/chat-sdk/logger.ts +81 -0
- package/src/integrations/chat-sdk/outbound.ts +123 -0
- package/src/integrations/chat-sdk/relay.ts +172 -0
- package/src/integrations/chat-sdk/router.ts +169 -0
- package/src/integrations/chat-sdk/runtime.ts +351 -0
- package/src/integrations/chat-sdk/schema.ts +245 -0
- package/src/integrations/chat-sdk/state.ts +243 -0
- package/src/integrations/chat-sdk/status.ts +244 -0
- package/src/integrations/chat-sdk/steering.ts +58 -0
- package/src/integrations/chat-sdk/teams-origin.ts +77 -0
- package/src/integrations/chat-sdk/telegram-api.ts +56 -0
- package/src/integrations/chat-sdk/templates.ts +16 -0
- package/src/integrations/chat-sdk/test-hooks.ts +37 -0
- package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
- package/src/integrations/chat-sdk/typing.ts +65 -0
- package/src/pages/version.ts +4 -5
- package/src/prompts/base-prompt.ts +111 -45
- package/src/providers/acp-target-catalog.ts +6 -0
- package/src/providers/acp-targets.ts +55 -2
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/claude-adapter.ts +1 -1
- package/src/providers/claude-flag-settings.ts +17 -5
- package/src/providers/claude-managed-adapter.ts +1 -1
- package/src/providers/claude-session-events.ts +6 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/opencode-adapter.ts +243 -26
- package/src/providers/opencode-swarm-plugin.ts +31 -0
- package/src/providers/pi-mono-adapter.ts +398 -153
- package/src/providers/pricing-sources.md +33 -2
- package/src/providers/reasoning-effort.ts +27 -0
- package/src/providers/types.ts +6 -2
- package/src/rbac/legacy-policy.ts +8 -2
- package/src/rbac/permissions.ts +21 -0
- package/src/scheduler/scheduler.ts +4 -2
- package/src/scripts-runtime/loader.ts +19 -7
- package/src/scripts-runtime/sdk-allowlist.ts +8 -6
- package/src/scripts-runtime/swarm-sdk.ts +0 -11
- package/src/scripts-runtime/types/stdlib.d.ts +27 -15
- package/src/scripts-runtime/types/swarm-extension.d.ts +63 -1
- package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -15
- package/src/server.ts +52 -18
- package/src/slack/event-dedup.ts +1 -1
- package/src/tasks/additive-buffer.ts +4 -2
- package/src/tasks/context-key.ts +60 -1
- package/src/tasks/model-pin.ts +67 -0
- package/src/tasks/worker-follow-up.ts +4 -31
- package/src/tests/acp-adapter.test.ts +42 -0
- package/src/tests/api-drain-worker-e2e.test.ts +1 -6
- package/src/tests/base-prompt.test.ts +58 -54
- package/src/tests/chat-sdk-commands.test.ts +191 -0
- package/src/tests/chat-sdk-config.test.ts +334 -0
- package/src/tests/chat-sdk-discord-api.test.ts +68 -0
- package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
- package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
- package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
- package/src/tests/chat-sdk-harness.ts +146 -0
- package/src/tests/chat-sdk-inbound.test.ts +363 -0
- package/src/tests/chat-sdk-relay.test.ts +470 -0
- package/src/tests/chat-sdk-reload.test.ts +128 -0
- package/src/tests/chat-sdk-shutdown.test.ts +220 -0
- package/src/tests/chat-sdk-slack.test.ts +268 -0
- package/src/tests/chat-sdk-state.test.ts +163 -0
- package/src/tests/chat-sdk-status-route.test.ts +382 -0
- package/src/tests/chat-sdk-teams.test.ts +277 -0
- package/src/tests/chat-sdk-tools.test.ts +520 -0
- package/src/tests/chat-sdk-typing.test.ts +120 -0
- package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
- package/src/tests/claude-adapter-binary.test.ts +9 -4
- package/src/tests/claude-flag-settings.test.ts +11 -3
- package/src/tests/claude-managed-adapter.test.ts +1 -1
- package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
- package/src/tests/claude-thinking-tokens.test.ts +57 -0
- package/src/tests/claude-worker-parity.test.ts +2 -7
- package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
- package/src/tests/config-refs.test.ts +66 -0
- package/src/tests/context-key.test.ts +19 -0
- package/src/tests/cors-allowlist.test.ts +25 -0
- package/src/tests/create-page-tool.test.ts +18 -0
- package/src/tests/credential-check.test.ts +139 -0
- package/src/tests/credentials.test.ts +21 -0
- package/src/tests/db-runtime.test.ts +61 -0
- package/src/tests/db-task-read-contract.test.ts +20 -0
- package/src/tests/db-task-write-contract.test.ts +10 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/enabled-capabilities.test.ts +20 -0
- package/src/tests/entrypoint-api-readiness.test.ts +14 -8
- package/src/tests/entrypoint-config-env-export.test.ts +5 -2
- package/src/tests/entrypoint-export-to-env.test.ts +78 -0
- package/src/tests/explicit-model-validation.test.ts +105 -1
- package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
- package/src/tests/extensions-post-bridge.test.ts +51 -0
- package/src/tests/fetch-resolved-env.test.ts +128 -0
- package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
- package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
- package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
- package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
- package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
- package/src/tests/github-handlers.test.ts +35 -0
- package/src/tests/harness-provider-resolution.test.ts +12 -0
- package/src/tests/heartbeat-checklist.test.ts +3 -2
- package/src/tests/hook-runtime-close.test.ts +0 -2
- package/src/tests/http-api-integration.test.ts +0 -25
- package/src/tests/migration-046-budgets.test.ts +17 -16
- package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
- package/src/tests/model-tier-resolution.test.ts +93 -0
- package/src/tests/models-catalog.test.ts +42 -1
- package/src/tests/openai-compatible-providers.test.ts +134 -0
- package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
- package/src/tests/opencode-adapter.test.ts +216 -2
- package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
- package/src/tests/opencode-shell-env.test.ts +145 -0
- package/src/tests/openrouter-base-url.test.ts +101 -151
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/pages-browser-sdk.test.ts +76 -0
- package/src/tests/pages-feedback.test.ts +1 -1
- package/src/tests/paused-tasks-requested-by.test.ts +102 -0
- package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
- package/src/tests/pi-mono-adapter.test.ts +385 -5
- package/src/tests/pi-shell-env.test.ts +170 -0
- package/src/tests/prompt-template-remaining.test.ts +35 -0
- package/src/tests/rbac-engine.test.ts +11 -3
- package/src/tests/runner-exit-after-tasks.test.ts +0 -4
- package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/scripts-http.test.ts +201 -1
- package/src/tests/scripts-only-gating.test.ts +2 -3
- package/src/tests/scripts-runtime.test.ts +58 -40
- package/src/tests/secret-scrubber.test.ts +86 -0
- package/src/tests/seed-skills-bundled-files.test.ts +45 -53
- package/src/tests/seed-skills-retire.test.ts +182 -0
- package/src/tests/send-task-requester-gate.test.ts +58 -0
- package/src/tests/session-cost-recompute-unit.test.ts +46 -0
- package/src/tests/skill-get-name-resolution.test.ts +137 -0
- package/src/tests/sonnet-5-5-registry.test.ts +9 -1
- package/src/tests/swarm-config-export-to-env.test.ts +267 -0
- package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
- package/src/tests/swarm-diff.test.ts +1 -1
- package/src/tests/task-model-effort-rerun.test.ts +164 -0
- package/src/tests/task-session-prompts.test.ts +132 -0
- package/src/tests/task-tool-manifest.test.ts +14 -0
- package/src/tests/task-tools-ctx.test.ts +2 -0
- package/src/tests/tool-annotations.test.ts +6 -6
- package/src/tests/ui-logs-parser.test.ts +43 -0
- package/src/tests/used-by-route.test.ts +6 -0
- package/src/tests/vercel-ai-gateway.test.ts +149 -0
- package/src/tests/workflow-swarm-script.test.ts +38 -0
- package/src/tests/workflow-wait-filter.test.ts +5 -3
- package/src/tools/chat-access.ts +41 -0
- package/src/tools/chat-open-dm.ts +59 -0
- package/src/tools/chat-post.ts +74 -0
- package/src/tools/chat-read-thread.ts +100 -0
- package/src/tools/chat-reply.ts +75 -0
- package/src/tools/create-page.ts +3 -13
- package/src/tools/model-catalog/index.ts +2 -1
- package/src/tools/register-chat-channel.ts +139 -0
- package/src/tools/send-task.ts +24 -0
- package/src/tools/skills/skill-get.ts +17 -9
- package/src/tools/swarm-config/get-config.ts +2 -1
- package/src/tools/swarm-config/list-config.ts +2 -1
- package/src/tools/swarm-config/set-config.ts +16 -3
- package/src/tools/tool-config.ts +8 -6
- package/src/types.ts +12 -2
- package/src/utils/config-env-export.ts +74 -0
- package/src/utils/credentials.test.ts +92 -0
- package/src/utils/credentials.ts +52 -4
- package/src/utils/harness-provider.ts +15 -6
- package/src/utils/runtime-model-catalog.ts +11 -1
- package/src/utils/secret-scrubber.ts +71 -2
- package/src/utils/task-tool-manifest.ts +19 -2
- package/src/workflows/executors/swarm-script.ts +1 -0
- package/templates/skills/agent-browser/SKILL.md +1 -1
- package/templates/skills/agent-browser/content.md +1 -1
- package/templates/skills/apps/SKILL.md +8 -1
- package/templates/skills/apps/content.md +8 -1
- package/templates/skills/chat-sdk/config.json +14 -0
- package/templates/skills/chat-sdk/content.md +84 -0
- package/templates/skills/composio-gmail/content.md +7 -0
- package/templates/skills/composio-google-docs/content.md +1 -1
- package/templates/skills/email-domain-health/config.json +14 -0
- package/templates/skills/email-domain-health/content.md +131 -0
- package/templates/skills/kv-storage/content.md +2 -2
- package/templates/skills/pages/content.md +8 -10
- package/templates/skills/swarm-extensions/content.md +2 -0
- package/templates/skills/swarm-scripts/SKILL.md +4 -2
- package/templates/skills/swarm-scripts/config.json +1 -1
- package/templates/skills/swarm-scripts/content.md +4 -2
- package/templates/skills/workflow-iterate/content.md +38 -0
- package/dist/artifact-eczsknc3.js +0 -3843
- package/dist/cli-bd957dgb.js +0 -153
- package/dist/cli-q51yprfq.js +0 -1104
- package/dist/cli-t1ze64h3.js +0 -811
- package/dist/cli-tcc4wd5d.js +0 -56471
- package/dist/index-9ch1n761.js +0 -1102
- package/src/artifact-sdk/index.ts +0 -2
- package/src/artifact-sdk/localtunnel.d.ts +0 -20
- package/src/artifact-sdk/port.ts +0 -12
- package/src/artifact-sdk/server.ts +0 -183
- package/src/artifact-sdk/tunnel.ts +0 -19
- package/src/commands/artifact.ts +0 -249
- package/src/http/ecosystem.ts +0 -77
- package/src/tests/artifact-commands.test.ts +0 -92
- package/src/tests/artifact-sdk.test.ts +0 -793
- package/src/tests/register-service-security.test.ts +0 -194
- package/src/tools/list-services.ts +0 -107
- package/src/tools/register-service.ts +0 -177
- package/src/tools/unregister-service.ts +0 -73
- package/src/tools/update-service-status.ts +0 -96
- package/templates/skills/artifacts/config.json +0 -14
- package/templates/skills/artifacts/content.md +0 -344
- package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
- package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
- package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
- package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
- /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
- /package/src/{artifact-sdk → pages}/feedback-overlay.ts +0 -0
package/dist/cli-t1ze64h3.js
DELETED
|
@@ -1,811 +0,0 @@
|
|
|
1
|
-
// src/artifact-sdk/browser-sdk.ts
|
|
2
|
-
var BROWSER_SDK_JS = `
|
|
3
|
-
class SwarmSDK {
|
|
4
|
-
constructor() {
|
|
5
|
-
let realtime;
|
|
6
|
-
const loadRealtime = () => realtime || (realtime = import('/@swarm/realtime.js'));
|
|
7
|
-
this.room = async (name, options) => (await loadRealtime()).room(name, options);
|
|
8
|
-
this.channel = async (name) => (await loadRealtime()).channel(name);
|
|
9
|
-
|
|
10
|
-
const base = '/@swarm/api';
|
|
11
|
-
const call = async (method, path, body) => {
|
|
12
|
-
const init = { method };
|
|
13
|
-
if (body !== undefined) {
|
|
14
|
-
init.headers = { 'Content-Type': 'application/json' };
|
|
15
|
-
init.body = JSON.stringify(body);
|
|
16
|
-
}
|
|
17
|
-
const res = await fetch(base + path, init);
|
|
18
|
-
const text = await res.text();
|
|
19
|
-
let parsed = null;
|
|
20
|
-
if (text) {
|
|
21
|
-
try { parsed = JSON.parse(text); } catch { parsed = text; }
|
|
22
|
-
}
|
|
23
|
-
if (!res.ok) {
|
|
24
|
-
const err = new Error('SwarmSDK ' + method + ' ' + path + ': ' + res.status);
|
|
25
|
-
err.status = res.status;
|
|
26
|
-
err.response = parsed;
|
|
27
|
-
throw err;
|
|
28
|
-
}
|
|
29
|
-
return parsed;
|
|
30
|
-
};
|
|
31
|
-
const qs = (obj) => {
|
|
32
|
-
if (!obj) return '';
|
|
33
|
-
const p = new URLSearchParams();
|
|
34
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
35
|
-
if (v === undefined || v === null) continue;
|
|
36
|
-
p.set(k, String(v));
|
|
37
|
-
}
|
|
38
|
-
const s = p.toString();
|
|
39
|
-
return s ? '?' + s : '';
|
|
40
|
-
};
|
|
41
|
-
const enc = encodeURIComponent;
|
|
42
|
-
|
|
43
|
-
this.tasks = {
|
|
44
|
-
create: (body) => call('POST', '/tasks', body),
|
|
45
|
-
list: (filters) => call('GET', '/tasks' + qs(filters)),
|
|
46
|
-
get: (id) => call('GET', '/tasks/' + enc(id)),
|
|
47
|
-
storeProgress: (id, data) => call('POST', '/tasks/' + enc(id) + '/progress', data),
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
this.agents = {
|
|
51
|
-
list: () => call('GET', '/agents'),
|
|
52
|
-
get: (id) => call('GET', '/agents/' + enc(id)),
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
this.events = {
|
|
56
|
-
create: (body) => call('POST', '/events', body),
|
|
57
|
-
list: (filters) => call('GET', '/events' + qs(filters)),
|
|
58
|
-
batch: (body) => call('POST', '/events/batch', body),
|
|
59
|
-
counts: (filters) => call('GET', '/events/counts' + qs(filters)),
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
this.memory = {
|
|
63
|
-
search: (body) => call('POST', '/memory/search', body),
|
|
64
|
-
list: (filters) => call('GET', '/memory/list' + qs(filters)),
|
|
65
|
-
get: (id) => call('GET', '/memory/' + enc(id)),
|
|
66
|
-
rate: (body) => call('POST', '/memory/rate', body),
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
this.repos = {
|
|
70
|
-
list: () => call('GET', '/repos'),
|
|
71
|
-
get: (id) => call('GET', '/repos/' + enc(id)),
|
|
72
|
-
create: (body) => call('POST', '/repos', body),
|
|
73
|
-
update: (id, body) => call('PUT', '/repos/' + enc(id), body),
|
|
74
|
-
delete: (id) => call('DELETE', '/repos/' + enc(id)),
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
this.schedules = {
|
|
78
|
-
list: () => call('GET', '/schedules'),
|
|
79
|
-
get: (id) => call('GET', '/schedules/' + enc(id)),
|
|
80
|
-
create: (body) => call('POST', '/schedules', body),
|
|
81
|
-
update: (id, body) => call('PUT', '/schedules/' + enc(id), body),
|
|
82
|
-
delete: (id) => call('DELETE', '/schedules/' + enc(id)),
|
|
83
|
-
run: (id) => call('POST', '/schedules/' + enc(id) + '/run'),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
this.approvalRequests = {
|
|
87
|
-
list: (filters) => call('GET', '/approval-requests' + qs(filters)),
|
|
88
|
-
get: (id) => call('GET', '/approval-requests/' + enc(id)),
|
|
89
|
-
create: (body) => call('POST', '/approval-requests', body),
|
|
90
|
-
respond: (id, body) => call('POST', '/approval-requests/' + enc(id) + '/respond', body),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
this.assets = {
|
|
94
|
-
list: (filters) => call('GET', '/assets' + qs(filters)),
|
|
95
|
-
audit: () => call('GET', '/assets/key-audit'),
|
|
96
|
-
registerMapping: (body) => call('POST', '/assets/mappings', body),
|
|
97
|
-
move: (entityType, id, key) => call(
|
|
98
|
-
'PATCH',
|
|
99
|
-
'/assets/' + enc(entityType) + '/' + enc(id) + '/key',
|
|
100
|
-
{ key },
|
|
101
|
-
),
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// KV store. The namespace is FORCED by the page-proxy to \`task:page:<id>\`
|
|
105
|
-
// (it injects X-Page-Id which the kv handler treats as highest priority).
|
|
106
|
-
// No namespace argument is exposed — pages cannot read/write any other
|
|
107
|
-
// namespace via this SDK.
|
|
108
|
-
this.kv = {
|
|
109
|
-
get: (key) => call('GET', '/kv/' + enc(key)),
|
|
110
|
-
set: (key, value, opts) => call('PUT', '/kv/' + enc(key), {
|
|
111
|
-
value,
|
|
112
|
-
valueType: opts && opts.valueType,
|
|
113
|
-
expiresInSec: opts && opts.expiresInSec,
|
|
114
|
-
}),
|
|
115
|
-
del: (key) => call('DELETE', '/kv/' + enc(key)),
|
|
116
|
-
incr: (key, by) => call('POST', '/kv/' + enc(key) + '/incr', { by: by == null ? 1 : by }),
|
|
117
|
-
list: (opts) => call('GET', '/kv' + qs(opts)),
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Expose BOTH the class (for \`new SwarmSDK()\`) AND a ready-to-use singleton
|
|
123
|
-
// on \`window.swarmSdk\` so pages can call e.g. \`window.swarmSdk.agents.list()\`
|
|
124
|
-
// directly without instantiating.
|
|
125
|
-
window.SwarmSDK = SwarmSDK;
|
|
126
|
-
window.swarmSdk = new SwarmSDK();
|
|
127
|
-
`;
|
|
128
|
-
var SWARM_UI_JS = `
|
|
129
|
-
(function() {
|
|
130
|
-
if (typeof window === 'undefined' || !window.customElements) return;
|
|
131
|
-
if (window.customElements.get('swarm-diff')) return;
|
|
132
|
-
|
|
133
|
-
// Keep page-owned presence fields alongside the cursor. Room.presence.set
|
|
134
|
-
// replaces its payload, so retain each room's latest page data and merge
|
|
135
|
-
// the reserved __cursor field into it when the cursor moves.
|
|
136
|
-
var roomPresenceTrackers = new WeakMap();
|
|
137
|
-
|
|
138
|
-
function clonePresenceRecord(data) {
|
|
139
|
-
return data && typeof data === 'object' && !Array.isArray(data)
|
|
140
|
-
? structuredClone(data)
|
|
141
|
-
: {};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function mergeCursorPresence(data, cursor) {
|
|
145
|
-
var merged = clonePresenceRecord(data);
|
|
146
|
-
if (cursor) merged.__cursor = { x: cursor.x, y: cursor.y };
|
|
147
|
-
else delete merged.__cursor;
|
|
148
|
-
return merged;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function trackRoomPresence(room) {
|
|
152
|
-
if (!room || !room.presence || typeof room.presence.set !== 'function') return null;
|
|
153
|
-
var existing = roomPresenceTrackers.get(room);
|
|
154
|
-
if (existing) return existing;
|
|
155
|
-
|
|
156
|
-
var presence = room.presence;
|
|
157
|
-
var originalSet = presence.set;
|
|
158
|
-
var pageData = {};
|
|
159
|
-
var cursor = null;
|
|
160
|
-
var tracker = {
|
|
161
|
-
setCursor: function(nextCursor) {
|
|
162
|
-
cursor = nextCursor;
|
|
163
|
-
return originalSet.call(presence, mergeCursorPresence(pageData, cursor));
|
|
164
|
-
},
|
|
165
|
-
clearCursor: function() {
|
|
166
|
-
if (!cursor) return;
|
|
167
|
-
return tracker.setCursor(null);
|
|
168
|
-
},
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
presence.set = function(data) {
|
|
172
|
-
pageData = clonePresenceRecord(data);
|
|
173
|
-
return originalSet.call(presence, cursor ? mergeCursorPresence(pageData, cursor) : data);
|
|
174
|
-
};
|
|
175
|
-
roomPresenceTrackers.set(room, tracker);
|
|
176
|
-
return tracker;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Wrap room creation before page scripts run so presence.set calls made by
|
|
180
|
-
// page code are tracked even when they happen before <swarm-cursors> connects.
|
|
181
|
-
var cursorRoomRecords = new Map();
|
|
182
|
-
var sdkRoomMethods = new WeakMap();
|
|
183
|
-
var observedRoomClosers = new WeakSet();
|
|
184
|
-
var originalRoom = null;
|
|
185
|
-
function roomRecordKey(name) {
|
|
186
|
-
return name === undefined ? 'default' : name;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function observeRoom(record, room) {
|
|
190
|
-
record.hasResolvedRoom = true;
|
|
191
|
-
if (!cursorRoomRecords.has(record.name)) cursorRoomRecords.set(record.name, record);
|
|
192
|
-
trackRoomPresence(room);
|
|
193
|
-
if (room && typeof room.close === 'function' && !observedRoomClosers.has(room)) {
|
|
194
|
-
var originalClose = room.close;
|
|
195
|
-
room.close = function() {
|
|
196
|
-
if (cursorRoomRecords.get(record.name) === record) cursorRoomRecords.delete(record.name);
|
|
197
|
-
return originalClose.apply(room, arguments);
|
|
198
|
-
};
|
|
199
|
-
observedRoomClosers.add(room);
|
|
200
|
-
}
|
|
201
|
-
return room;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function observeRoomPromise(record, result) {
|
|
205
|
-
var observed = Promise.resolve(result).then(function(room) {
|
|
206
|
-
var resolvedRoom = observeRoom(record, room);
|
|
207
|
-
record.pageRequests--;
|
|
208
|
-
record.hasPageUse = true;
|
|
209
|
-
record.pageUsed = true;
|
|
210
|
-
record.promise = Promise.resolve(resolvedRoom);
|
|
211
|
-
return resolvedRoom;
|
|
212
|
-
}).catch(function(error) {
|
|
213
|
-
record.pageRequests--;
|
|
214
|
-
record.pageUsed = record.hasPageUse || record.pageRequests > 0;
|
|
215
|
-
if (!record.hasResolvedRoom
|
|
216
|
-
&& record.pageRequests === 0
|
|
217
|
-
&& cursorRoomRecords.get(record.name) === record)
|
|
218
|
-
cursorRoomRecords.delete(record.name);
|
|
219
|
-
if (record.cursorRefs === 0 && record.openedByCursor && !record.pageUsed)
|
|
220
|
-
closeCursorRoomIfUnused(record);
|
|
221
|
-
throw error;
|
|
222
|
-
});
|
|
223
|
-
record.pageRequests++;
|
|
224
|
-
record.pageUsed = true;
|
|
225
|
-
if (!record.promise) record.promise = observed;
|
|
226
|
-
return observed;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function closeCursorRoomIfUnused(record) {
|
|
230
|
-
if (record.closing || record.cursorRefs || !record.openedByCursor || record.pageUsed) return;
|
|
231
|
-
record.closing = true;
|
|
232
|
-
record.promise.then(function(room) {
|
|
233
|
-
if (record.cursorRefs || record.pageUsed) {
|
|
234
|
-
record.closing = false;
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
if (cursorRoomRecords.get(record.name) === record) cursorRoomRecords.delete(record.name);
|
|
238
|
-
if (room && typeof room.close === 'function') return room.close();
|
|
239
|
-
}).catch(function() {
|
|
240
|
-
record.closing = false;
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function instrumentSdk(sdk) {
|
|
245
|
-
if (!sdk || typeof sdk.room !== 'function') return null;
|
|
246
|
-
var existing = sdkRoomMethods.get(sdk);
|
|
247
|
-
if (existing) return existing;
|
|
248
|
-
|
|
249
|
-
var sdkOriginalRoom = sdk.room;
|
|
250
|
-
var wrappedRoom = function(name, options) {
|
|
251
|
-
var key = roomRecordKey(name);
|
|
252
|
-
var record = cursorRoomRecords.get(key);
|
|
253
|
-
var result = sdkOriginalRoom.call(sdk, name, options);
|
|
254
|
-
if (!record) {
|
|
255
|
-
record = {
|
|
256
|
-
name: key,
|
|
257
|
-
cursorRefs: 0,
|
|
258
|
-
openedByCursor: false,
|
|
259
|
-
pageUsed: false,
|
|
260
|
-
hasPageUse: false,
|
|
261
|
-
pageRequests: 0,
|
|
262
|
-
hasResolvedRoom: false,
|
|
263
|
-
promise: null,
|
|
264
|
-
};
|
|
265
|
-
cursorRoomRecords.set(key, record);
|
|
266
|
-
}
|
|
267
|
-
return observeRoomPromise(record, result);
|
|
268
|
-
};
|
|
269
|
-
sdk.room = wrappedRoom;
|
|
270
|
-
var methods = { original: sdkOriginalRoom, wrapped: wrappedRoom };
|
|
271
|
-
sdkRoomMethods.set(sdk, methods);
|
|
272
|
-
return methods;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (window.swarmSdk) {
|
|
276
|
-
var singletonRoomMethods = instrumentSdk(window.swarmSdk);
|
|
277
|
-
originalRoom = singletonRoomMethods && singletonRoomMethods.original;
|
|
278
|
-
}
|
|
279
|
-
if (typeof window.SwarmSDK === 'function') {
|
|
280
|
-
var OriginalSwarmSDK = window.SwarmSDK;
|
|
281
|
-
window.SwarmSDK = new Proxy(OriginalSwarmSDK, {
|
|
282
|
-
construct: function(target, args, newTarget) {
|
|
283
|
-
var sdk = Reflect.construct(target, args, newTarget);
|
|
284
|
-
instrumentSdk(sdk);
|
|
285
|
-
return sdk;
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function acquireCursorRoom(name, options) {
|
|
291
|
-
var key = roomRecordKey(name);
|
|
292
|
-
var record = cursorRoomRecords.get(key);
|
|
293
|
-
if (record) {
|
|
294
|
-
record.cursorRefs++;
|
|
295
|
-
return { record: record, promise: record.promise };
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
record = {
|
|
299
|
-
name: key,
|
|
300
|
-
cursorRefs: 1,
|
|
301
|
-
openedByCursor: true,
|
|
302
|
-
pageUsed: false,
|
|
303
|
-
hasPageUse: false,
|
|
304
|
-
pageRequests: 0,
|
|
305
|
-
hasResolvedRoom: false,
|
|
306
|
-
closing: false,
|
|
307
|
-
promise: null,
|
|
308
|
-
};
|
|
309
|
-
cursorRoomRecords.set(key, record);
|
|
310
|
-
record.promise = Promise.resolve().then(function() {
|
|
311
|
-
return originalRoom(name, options);
|
|
312
|
-
}).then(function(room) {
|
|
313
|
-
return observeRoom(record, room);
|
|
314
|
-
}).catch(function(error) {
|
|
315
|
-
if (cursorRoomRecords.get(key) === record) cursorRoomRecords.delete(key);
|
|
316
|
-
throw error;
|
|
317
|
-
});
|
|
318
|
-
return { record: record, promise: record.promise };
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function releaseCursorRoom(record, presence) {
|
|
322
|
-
if (!record || record.cursorRefs < 1) return;
|
|
323
|
-
if (record.cursorRefs === 1 && presence) presence.clearCursor();
|
|
324
|
-
record.cursorRefs--;
|
|
325
|
-
closeCursorRoomIfUnused(record);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
var SEV_COLOR = {
|
|
329
|
-
error: '#ef4444',
|
|
330
|
-
warn: '#f59e0b',
|
|
331
|
-
info: '#3b82f6',
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
function esc(s) {
|
|
335
|
-
return String(s == null ? '' : s)
|
|
336
|
-
.replace(/&/g, '&')
|
|
337
|
-
.replace(/</g, '<')
|
|
338
|
-
.replace(/>/g, '>')
|
|
339
|
-
.replace(/"/g, '"')
|
|
340
|
-
.replace(/'/g, ''');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
function slugifyAttr(s) {
|
|
344
|
-
return String(s || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function parseHunks(jsonText) {
|
|
348
|
-
var trimmed = (jsonText || '').trim();
|
|
349
|
-
if (!trimmed) return [];
|
|
350
|
-
try {
|
|
351
|
-
var parsed = JSON.parse(trimmed);
|
|
352
|
-
if (parsed && Array.isArray(parsed.hunks)) return parsed.hunks;
|
|
353
|
-
if (Array.isArray(parsed)) return parsed;
|
|
354
|
-
return [];
|
|
355
|
-
} catch (e) {
|
|
356
|
-
console.warn('[swarm-diff] failed to parse JSON body:', e);
|
|
357
|
-
return [];
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function renderAnnotation(ann) {
|
|
362
|
-
var color = SEV_COLOR[ann && ann.severity] || SEV_COLOR.info;
|
|
363
|
-
return (
|
|
364
|
-
'<span class="swarm-diff-annot no-print" '
|
|
365
|
-
+ 'style="display:inline-block;margin-left:8px;padding:1px 6px;'
|
|
366
|
-
+ 'border-radius:4px;font-size:11px;font-weight:600;'
|
|
367
|
-
+ 'background:' + color + '22;color:' + color + ';border:1px solid ' + color + '55;">'
|
|
368
|
-
+ esc((ann && ann.severity ? ann.severity.toUpperCase() : 'INFO')) + ' · ' + esc(ann && ann.text || '')
|
|
369
|
-
+ '</span>'
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function renderHunk(hunk, hunkIdx, file) {
|
|
374
|
-
var oldLines = hunk.old_lines || 0;
|
|
375
|
-
var newLines = hunk.new_lines || 0;
|
|
376
|
-
var oldStart = hunk.old_start || 0;
|
|
377
|
-
var newStart = hunk.new_start || 0;
|
|
378
|
-
var lines = Array.isArray(hunk.lines) ? hunk.lines : [];
|
|
379
|
-
var annotations = Array.isArray(hunk.annotations) ? hunk.annotations : [];
|
|
380
|
-
// Index annotations by new-side line number for fast lookup per row.
|
|
381
|
-
var annByLine = {};
|
|
382
|
-
for (var i = 0; i < annotations.length; i++) {
|
|
383
|
-
var a = annotations[i];
|
|
384
|
-
if (a && typeof a.line === 'number') {
|
|
385
|
-
if (!annByLine[a.line]) annByLine[a.line] = [];
|
|
386
|
-
annByLine[a.line].push(a);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
var rowsHtml = '';
|
|
391
|
-
var oldN = oldStart;
|
|
392
|
-
var newN = newStart;
|
|
393
|
-
for (var j = 0; j < lines.length; j++) {
|
|
394
|
-
var line = lines[j] || {};
|
|
395
|
-
var type = line.type || 'context';
|
|
396
|
-
var text = line.text == null ? '' : line.text;
|
|
397
|
-
var bg, oldCell, newCell, sign;
|
|
398
|
-
if (type === 'add') {
|
|
399
|
-
bg = 'rgba(34,197,94,0.10)';
|
|
400
|
-
oldCell = '';
|
|
401
|
-
newCell = String(newN++);
|
|
402
|
-
sign = '+';
|
|
403
|
-
} else if (type === 'del') {
|
|
404
|
-
bg = 'rgba(239,68,68,0.10)';
|
|
405
|
-
oldCell = String(oldN++);
|
|
406
|
-
newCell = '';
|
|
407
|
-
sign = '-';
|
|
408
|
-
} else {
|
|
409
|
-
bg = 'transparent';
|
|
410
|
-
oldCell = String(oldN++);
|
|
411
|
-
newCell = String(newN++);
|
|
412
|
-
sign = ' ';
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
var annHtml = '';
|
|
416
|
-
var anns = annByLine[Number(newCell)] || annByLine[Number(oldCell)] || [];
|
|
417
|
-
for (var k = 0; k < anns.length; k++) annHtml += renderAnnotation(anns[k]);
|
|
418
|
-
|
|
419
|
-
rowsHtml += (
|
|
420
|
-
'<tr style="background:' + bg + ';">'
|
|
421
|
-
+ '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(oldCell) + '</td>'
|
|
422
|
-
+ '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(newCell) + '</td>'
|
|
423
|
-
+ '<td class="swarm-diff-sign" style="user-select:none;text-align:center;padding:0 4px;color:#7c8aa6;font-size:12px;width:18px;">' + esc(sign) + '</td>'
|
|
424
|
-
+ '<td class="swarm-diff-code" style="padding:0 8px;white-space:pre-wrap;word-break:break-word;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(text) + annHtml + '</td>'
|
|
425
|
-
+ '</tr>'
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
var anchorSlug = slugifyAttr((file || 'hunk') + '-' + (oldStart || hunkIdx + 1));
|
|
430
|
-
var anchorId = 'swarm-diff-' + anchorSlug;
|
|
431
|
-
var header = (
|
|
432
|
-
'@@ -' + oldStart + ',' + oldLines + ' +' + newStart + ',' + newLines + ' @@'
|
|
433
|
-
);
|
|
434
|
-
|
|
435
|
-
return (
|
|
436
|
-
'<a id="' + esc(anchorId) + '" class="swarm-diff-anchor" data-hunk="' + esc(anchorSlug) + '"></a>'
|
|
437
|
-
+ '<div class="swarm-diff-hunk-header" style="padding:6px 12px;background:rgba(124,138,166,0.10);color:#7c8aa6;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;border-top:1px solid var(--swarm-border,#22304a);">'
|
|
438
|
-
+ esc(header)
|
|
439
|
-
+ '</div>'
|
|
440
|
-
+ '<table class="swarm-diff-table" style="width:100%;border-collapse:collapse;table-layout:fixed;">'
|
|
441
|
-
+ '<tbody>' + rowsHtml + '</tbody>'
|
|
442
|
-
+ '</table>'
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
function renderDiff(rootEl, diffData) {
|
|
447
|
-
var hunks = (diffData && Array.isArray(diffData.hunks)) ? diffData.hunks : (Array.isArray(diffData) ? diffData : []);
|
|
448
|
-
var file = rootEl.getAttribute('file') || '';
|
|
449
|
-
var baseSha = rootEl.getAttribute('base-sha') || '';
|
|
450
|
-
var headSha = rootEl.getAttribute('head-sha') || '';
|
|
451
|
-
|
|
452
|
-
var shaLine = '';
|
|
453
|
-
if (baseSha || headSha) {
|
|
454
|
-
shaLine = '<span class="swarm-diff-sha" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;color:#7c8aa6;">'
|
|
455
|
-
+ esc(baseSha) + ' → ' + esc(headSha)
|
|
456
|
-
+ '</span>';
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
var hunksHtml = '';
|
|
460
|
-
for (var i = 0; i < hunks.length; i++) {
|
|
461
|
-
hunksHtml += renderHunk(hunks[i] || {}, i, file);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
rootEl.innerHTML = (
|
|
465
|
-
'<div class="swarm-diff-root" style="border:1px solid var(--swarm-border,#22304a);border-radius:8px;background:var(--swarm-card,#121826);overflow:hidden;margin:12px 0;break-inside:avoid;">'
|
|
466
|
-
+ '<div class="swarm-diff-header" style="display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:rgba(59,130,246,0.10);border-bottom:1px solid var(--swarm-border,#22304a);">'
|
|
467
|
-
+ '<span class="swarm-diff-file" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:13px;font-weight:700;color:var(--swarm-text,#e6eaf2);">' + esc(file || '(untitled)') + '</span>'
|
|
468
|
-
+ shaLine
|
|
469
|
-
+ '</div>'
|
|
470
|
-
+ hunksHtml
|
|
471
|
-
+ '</div>'
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// Public function form lives on window.swarmUi so callers can render an
|
|
476
|
-
// arbitrary root element programmatically. The custom element below is just
|
|
477
|
-
// a declarative wrapper around the same render function.
|
|
478
|
-
window.swarmUi = window.swarmUi || {};
|
|
479
|
-
window.swarmUi.renderDiff = renderDiff;
|
|
480
|
-
|
|
481
|
-
// Defer the parse-and-render so the HTML parser has time to finish
|
|
482
|
-
// appending JSON text children. \`connectedCallback\` fires on the opening
|
|
483
|
-
// tag — \`this.textContent\` is empty until children parse. Without a
|
|
484
|
-
// defer, every declarative <swarm-diff> renders an empty header and the
|
|
485
|
-
// JSON text remains visible as orphan children.
|
|
486
|
-
//
|
|
487
|
-
// queueMicrotask alone is NOT enough — Chrome's streaming parser drains
|
|
488
|
-
// microtasks between chunks, so the microtask can run BEFORE the JSON
|
|
489
|
-
// child is appended. We need to wait for the parser to finish the current
|
|
490
|
-
// document load, then read textContent.
|
|
491
|
-
//
|
|
492
|
-
// * \`document.readyState === 'loading'\` ⇒ parser still streaming →
|
|
493
|
-
// wait for DOMContentLoaded (fires after all children are parsed).
|
|
494
|
-
// * otherwise (element was created/inserted dynamically post-load) ⇒
|
|
495
|
-
// queueMicrotask is fine — DOM is stable, just give the caller a tick.
|
|
496
|
-
//
|
|
497
|
-
// Re-entrancy (element moved/reconnected) re-fires connectedCallback so
|
|
498
|
-
// we re-render against current textContent.
|
|
499
|
-
class SwarmDiffElement extends HTMLElement {
|
|
500
|
-
connectedCallback() {
|
|
501
|
-
var self = this;
|
|
502
|
-
var doRender = function() {
|
|
503
|
-
if (!self.isConnected) return;
|
|
504
|
-
var raw = self.textContent || '';
|
|
505
|
-
renderDiff(self, { hunks: parseHunks(raw) });
|
|
506
|
-
// Notify <swarm-diff-jumps> instances so they can pick up new anchors.
|
|
507
|
-
self.dispatchEvent(new CustomEvent('swarm-diff:rendered', { bubbles: true }));
|
|
508
|
-
};
|
|
509
|
-
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
510
|
-
document.addEventListener('DOMContentLoaded', doRender, { once: true });
|
|
511
|
-
} else {
|
|
512
|
-
queueMicrotask(doRender);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
window.customElements.define('swarm-diff', SwarmDiffElement);
|
|
517
|
-
|
|
518
|
-
// Sibling-anchor jump list. Walks subsequent siblings, finds every
|
|
519
|
-
// <swarm-diff data-hunk=...> anchor, and renders a small list of links.
|
|
520
|
-
//
|
|
521
|
-
// Same parse-order hazard as <swarm-diff>: <swarm-diff-jumps> usually
|
|
522
|
-
// appears in the document BEFORE the <swarm-diff> elements it indexes, so
|
|
523
|
-
// we also defer to a microtask AND re-render whenever a <swarm-diff> in the
|
|
524
|
-
// document finishes rendering its anchors.
|
|
525
|
-
class SwarmDiffJumpsElement extends HTMLElement {
|
|
526
|
-
connectedCallback() {
|
|
527
|
-
var self = this;
|
|
528
|
-
var renderJumps = function() {
|
|
529
|
-
var anchors = document.querySelectorAll('.swarm-diff-anchor[data-hunk]');
|
|
530
|
-
if (!anchors.length) {
|
|
531
|
-
self.innerHTML = '<span class="no-print" style="color:#7c8aa6;font-size:12px;">No hunks yet.</span>';
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
var items = '';
|
|
535
|
-
for (var i = 0; i < anchors.length; i++) {
|
|
536
|
-
var a = anchors[i];
|
|
537
|
-
var slug = a.getAttribute('data-hunk') || ('hunk-' + i);
|
|
538
|
-
// Hunk title = nearest preceding diff's file attribute if available.
|
|
539
|
-
var diff = a.closest && a.closest('swarm-diff');
|
|
540
|
-
var file = (diff && diff.getAttribute('file')) || slug;
|
|
541
|
-
items += '<li style="margin:0;padding:2px 0;"><a href="#' + esc(a.id) + '" style="color:#3b82f6;text-decoration:none;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(file) + '</a></li>';
|
|
542
|
-
}
|
|
543
|
-
self.innerHTML = (
|
|
544
|
-
'<nav class="swarm-diff-jumps no-print" style="padding:8px 12px;border:1px dashed var(--swarm-border,#22304a);border-radius:8px;background:rgba(124,138,166,0.05);">'
|
|
545
|
-
+ '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.08em;color:#7c8aa6;margin-bottom:4px;">Jump to</div>'
|
|
546
|
-
+ '<ul style="list-style:none;padding:0;margin:0;">' + items + '</ul>'
|
|
547
|
-
+ '</nav>'
|
|
548
|
-
);
|
|
549
|
-
};
|
|
550
|
-
// Wait for the parser to finish initial load before first query —
|
|
551
|
-
// <swarm-diff> elements also defer to DOMContentLoaded so we must
|
|
552
|
-
// run AFTER they finish rendering their anchors. The event listener
|
|
553
|
-
// below handles the live-update case.
|
|
554
|
-
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
555
|
-
document.addEventListener('DOMContentLoaded', function() { queueMicrotask(renderJumps); }, { once: true });
|
|
556
|
-
} else {
|
|
557
|
-
queueMicrotask(renderJumps);
|
|
558
|
-
}
|
|
559
|
-
// Re-render whenever a sibling <swarm-diff> finishes its async render.
|
|
560
|
-
self._onDiffRendered = function() { renderJumps(); };
|
|
561
|
-
document.addEventListener('swarm-diff:rendered', self._onDiffRendered);
|
|
562
|
-
}
|
|
563
|
-
disconnectedCallback() {
|
|
564
|
-
if (this._onDiffRendered) {
|
|
565
|
-
document.removeEventListener('swarm-diff:rendered', this._onDiffRendered);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
window.customElements.define('swarm-diff-jumps', SwarmDiffJumpsElement);
|
|
570
|
-
|
|
571
|
-
var CURSOR_IDLE_MS = 3000;
|
|
572
|
-
var CURSOR_SMOOTHING = 0.28;
|
|
573
|
-
|
|
574
|
-
function cursorColor(userId) {
|
|
575
|
-
var hash = 2166136261;
|
|
576
|
-
var value = String(userId || '');
|
|
577
|
-
for (var i = 0; i < value.length; i++) {
|
|
578
|
-
hash ^= value.charCodeAt(i);
|
|
579
|
-
hash = Math.imul(hash, 16777619);
|
|
580
|
-
}
|
|
581
|
-
return 'hsl(' + ((hash >>> 0) % 360) + ', 72%, 42%)';
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
function documentSize() {
|
|
585
|
-
var root = document.documentElement || {};
|
|
586
|
-
return {
|
|
587
|
-
width: Math.max(1, root.scrollWidth || root.clientWidth || window.innerWidth || 1),
|
|
588
|
-
height: Math.max(1, root.scrollHeight || root.clientHeight || window.innerHeight || 1),
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
function cursorMarkup(name, color) {
|
|
593
|
-
// CursorPointer + CursorBody label structure adapted from Kibo UI (MIT):
|
|
594
|
-
// https://github.com/shadcnblocks/kibo/blob/main/packages/cursor/index.tsx
|
|
595
|
-
return '<svg aria-hidden="true" focusable="false" height="20" width="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" style="width:20px;height:20px;flex:none;filter:drop-shadow(0 1px 1px rgba(0,0,0,.2));">'
|
|
596
|
-
+ '<path d="M19.438 6.716 1.115.05A.832.832 0 0 0 .05 1.116L6.712 19.45a.834.834 0 0 0 1.557.025l3.198-8 7.995-3.2a.833.833 0 0 0 0-1.559h-.024Z" fill="currentColor"></path>'
|
|
597
|
-
+ '</svg>'
|
|
598
|
-
+ '<span style="position:relative;margin-left:14px;display:flex;flex-direction:column;white-space:nowrap;border-radius:12px;padding:4px 12px 4px 10px;font-family:system-ui,sans-serif;font-size:12px;font-weight:500;line-height:1.4;background:' + color + ';color:#fff;box-shadow:0 2px 6px rgba(0,0,0,.18);">'
|
|
599
|
-
+ esc(name || 'Guest')
|
|
600
|
-
+ '</span>';
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
class SwarmCursorsElement extends HTMLElement {
|
|
604
|
-
connectedCallback() {
|
|
605
|
-
if (this._startPromise) return;
|
|
606
|
-
var roomName = this.getAttribute('room');
|
|
607
|
-
if (!roomName || !originalRoom) return;
|
|
608
|
-
|
|
609
|
-
var self = this;
|
|
610
|
-
var lifecycle = (this._lifecycle || 0) + 1;
|
|
611
|
-
this._lifecycle = lifecycle;
|
|
612
|
-
var begin = function() {
|
|
613
|
-
self._onDomReady = null;
|
|
614
|
-
if (!self.isConnected || self._lifecycle !== lifecycle) return;
|
|
615
|
-
var schemaVersion = self.getAttribute('schema-version');
|
|
616
|
-
var options = schemaVersion == null ? {} : { schemaVersion: Number(schemaVersion) };
|
|
617
|
-
var acquired = acquireCursorRoom(roomName, options);
|
|
618
|
-
self._roomRecord = acquired.record;
|
|
619
|
-
self._startPromise = acquired.promise.then(function(room) {
|
|
620
|
-
if (!self.isConnected || self._lifecycle !== lifecycle) return;
|
|
621
|
-
self._startPromise = null;
|
|
622
|
-
self._room = room;
|
|
623
|
-
self._presence = trackRoomPresence(room);
|
|
624
|
-
if (!self._presence) return;
|
|
625
|
-
self._pointers = new Map();
|
|
626
|
-
self._cursorStates = new Map();
|
|
627
|
-
|
|
628
|
-
self._overlay = document.createElement('div');
|
|
629
|
-
self._overlay.setAttribute('aria-hidden', 'true');
|
|
630
|
-
self._overlay.style.cssText = 'position:fixed;inset:0;z-index:2147483647;pointer-events:none;overflow:hidden;';
|
|
631
|
-
var parent = document.body || document.documentElement;
|
|
632
|
-
if (parent) parent.appendChild(self._overlay);
|
|
633
|
-
|
|
634
|
-
self._onPresence = function(peers) { self._renderPeers(peers || []); };
|
|
635
|
-
self._onPointerMove = function(event) {
|
|
636
|
-
var size = documentSize();
|
|
637
|
-
var scrollX = window.scrollX || window.pageXOffset || 0;
|
|
638
|
-
var scrollY = window.scrollY || window.pageYOffset || 0;
|
|
639
|
-
var pageX = typeof event.pageX === 'number' ? event.pageX : event.clientX + scrollX;
|
|
640
|
-
var pageY = typeof event.pageY === 'number' ? event.pageY : event.clientY + scrollY;
|
|
641
|
-
var x = Math.max(0, Math.min(1, pageX / size.width));
|
|
642
|
-
var y = Math.max(0, Math.min(1, pageY / size.height));
|
|
643
|
-
self._presence.setCursor({ x: x, y: y });
|
|
644
|
-
};
|
|
645
|
-
self._onPointerLeave = function() {
|
|
646
|
-
self._presence.clearCursor();
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
self._unsubscribe = room.on('presence', self._onPresence);
|
|
650
|
-
document.addEventListener('pointermove', self._onPointerMove, { passive: true });
|
|
651
|
-
document.addEventListener('pointerleave', self._onPointerLeave);
|
|
652
|
-
self._renderPeers(room.presence.peers || []);
|
|
653
|
-
}).catch(function(error) {
|
|
654
|
-
self._startPromise = null;
|
|
655
|
-
console.warn('[swarm-cursors] failed to join room:', error);
|
|
656
|
-
});
|
|
657
|
-
};
|
|
658
|
-
if (document.readyState === 'loading') {
|
|
659
|
-
this._onDomReady = function() { queueMicrotask(begin); };
|
|
660
|
-
this._startPromise = Promise.resolve();
|
|
661
|
-
document.addEventListener('DOMContentLoaded', this._onDomReady, { once: true });
|
|
662
|
-
} else {
|
|
663
|
-
begin();
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
_renderPeers(peers) {
|
|
668
|
-
if (!this._pointers) return;
|
|
669
|
-
var seen = new Set();
|
|
670
|
-
var activePeerIds = new Set();
|
|
671
|
-
var includeAgents = this.hasAttribute('include-agents');
|
|
672
|
-
var ownId = this._room && this._room.me && this._room.me.userId;
|
|
673
|
-
var now = Date.now();
|
|
674
|
-
|
|
675
|
-
for (var i = 0; i < peers.length; i++) {
|
|
676
|
-
var peer = peers[i];
|
|
677
|
-
if (!peer || !peer.userId || peer.userId === ownId) continue;
|
|
678
|
-
if (peer.kind === 'agent' && !includeAgents) continue;
|
|
679
|
-
var data = peer.data && typeof peer.data === 'object' ? peer.data : null;
|
|
680
|
-
var cursor = data && data.__cursor;
|
|
681
|
-
if (!cursor || typeof cursor.x !== 'number' || typeof cursor.y !== 'number'
|
|
682
|
-
|| !Number.isFinite(cursor.x) || !Number.isFinite(cursor.y)) continue;
|
|
683
|
-
|
|
684
|
-
var id = String(peer.userId);
|
|
685
|
-
activePeerIds.add(id);
|
|
686
|
-
var state = this._cursorStates.get(id);
|
|
687
|
-
if (!state || state.x !== cursor.x || state.y !== cursor.y) {
|
|
688
|
-
state = { x: cursor.x, y: cursor.y, lastSeen: now };
|
|
689
|
-
this._cursorStates.set(id, state);
|
|
690
|
-
}
|
|
691
|
-
if (now - state.lastSeen > CURSOR_IDLE_MS) continue;
|
|
692
|
-
|
|
693
|
-
var entry = this._pointers.get(id);
|
|
694
|
-
if (!entry) {
|
|
695
|
-
entry = this._createPointer(peer);
|
|
696
|
-
this._pointers.set(id, entry);
|
|
697
|
-
}
|
|
698
|
-
entry.cursor = { x: state.x, y: state.y };
|
|
699
|
-
entry.lastSeen = state.lastSeen;
|
|
700
|
-
if (entry.name !== peer.name) {
|
|
701
|
-
entry.name = peer.name || 'Guest';
|
|
702
|
-
entry.node.innerHTML = cursorMarkup(entry.name, entry.color);
|
|
703
|
-
}
|
|
704
|
-
seen.add(id);
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
var ids = Array.from(this._pointers.keys());
|
|
708
|
-
for (var j = 0; j < ids.length; j++) {
|
|
709
|
-
if (!seen.has(ids[j])) this._removePointer(ids[j]);
|
|
710
|
-
}
|
|
711
|
-
var stateIds = Array.from(this._cursorStates.keys());
|
|
712
|
-
for (var k = 0; k < stateIds.length; k++) {
|
|
713
|
-
if (!activePeerIds.has(stateIds[k])) this._cursorStates.delete(stateIds[k]);
|
|
714
|
-
}
|
|
715
|
-
this._scheduleFrame();
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
_createPointer(peer) {
|
|
719
|
-
var color = cursorColor(peer.userId);
|
|
720
|
-
var node = document.createElement('div');
|
|
721
|
-
node.style.cssText = 'position:absolute;left:0;top:0;display:flex;align-items:flex-start;pointer-events:none;user-select:none;will-change:transform;color:' + color + ';';
|
|
722
|
-
node.innerHTML = cursorMarkup(peer.name || 'Guest', color);
|
|
723
|
-
this._overlay.appendChild(node);
|
|
724
|
-
return {
|
|
725
|
-
node: node,
|
|
726
|
-
color: color,
|
|
727
|
-
name: peer.name || 'Guest',
|
|
728
|
-
cursor: null,
|
|
729
|
-
x: null,
|
|
730
|
-
y: null,
|
|
731
|
-
lastSeen: Date.now(),
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
_removePointer(id) {
|
|
736
|
-
var entry = this._pointers.get(id);
|
|
737
|
-
if (entry && entry.node.parentNode) entry.node.parentNode.removeChild(entry.node);
|
|
738
|
-
this._pointers.delete(id);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
_scheduleFrame() {
|
|
742
|
-
if (this._frameId != null || !this._pointers || !this._pointers.size
|
|
743
|
-
|| typeof window.requestAnimationFrame !== 'function') return;
|
|
744
|
-
var self = this;
|
|
745
|
-
this._frameId = window.requestAnimationFrame(function() { self._animate(); });
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
_animate() {
|
|
749
|
-
this._frameId = null;
|
|
750
|
-
if (!this._pointers || !this._overlay) return;
|
|
751
|
-
var now = Date.now();
|
|
752
|
-
var size = documentSize();
|
|
753
|
-
var scrollX = window.scrollX || window.pageXOffset || 0;
|
|
754
|
-
var scrollY = window.scrollY || window.pageYOffset || 0;
|
|
755
|
-
var ids = Array.from(this._pointers.keys());
|
|
756
|
-
|
|
757
|
-
for (var i = 0; i < ids.length; i++) {
|
|
758
|
-
var id = ids[i];
|
|
759
|
-
var entry = this._pointers.get(id);
|
|
760
|
-
if (now - entry.lastSeen > CURSOR_IDLE_MS) {
|
|
761
|
-
this._removePointer(id);
|
|
762
|
-
continue;
|
|
763
|
-
}
|
|
764
|
-
var targetX = entry.cursor.x * size.width - scrollX;
|
|
765
|
-
var targetY = entry.cursor.y * size.height - scrollY;
|
|
766
|
-
if (entry.x == null || entry.y == null) {
|
|
767
|
-
entry.x = targetX;
|
|
768
|
-
entry.y = targetY;
|
|
769
|
-
} else {
|
|
770
|
-
// Exponential interpolation keeps 50 ms presence updates from jumping.
|
|
771
|
-
entry.x += (targetX - entry.x) * CURSOR_SMOOTHING;
|
|
772
|
-
entry.y += (targetY - entry.y) * CURSOR_SMOOTHING;
|
|
773
|
-
}
|
|
774
|
-
entry.node.style.transform = 'translate3d(' + Math.round(entry.x) + 'px,' + Math.round(entry.y) + 'px,0)';
|
|
775
|
-
}
|
|
776
|
-
this._scheduleFrame();
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
disconnectedCallback() {
|
|
780
|
-
this._lifecycle = (this._lifecycle || 0) + 1;
|
|
781
|
-
this._startPromise = null;
|
|
782
|
-
if (this._onDomReady) {
|
|
783
|
-
document.removeEventListener('DOMContentLoaded', this._onDomReady);
|
|
784
|
-
this._onDomReady = null;
|
|
785
|
-
}
|
|
786
|
-
if (this._unsubscribe) this._unsubscribe();
|
|
787
|
-
if (this._onPointerMove) document.removeEventListener('pointermove', this._onPointerMove);
|
|
788
|
-
if (this._onPointerLeave) document.removeEventListener('pointerleave', this._onPointerLeave);
|
|
789
|
-
if (this._roomRecord) releaseCursorRoom(this._roomRecord, this._presence);
|
|
790
|
-
if (this._frameId != null && typeof window.cancelAnimationFrame === 'function')
|
|
791
|
-
window.cancelAnimationFrame(this._frameId);
|
|
792
|
-
if (this._pointers) {
|
|
793
|
-
var ids = Array.from(this._pointers.keys());
|
|
794
|
-
for (var i = 0; i < ids.length; i++) this._removePointer(ids[i]);
|
|
795
|
-
}
|
|
796
|
-
if (this._overlay && this._overlay.parentNode)
|
|
797
|
-
this._overlay.parentNode.removeChild(this._overlay);
|
|
798
|
-
this._room = null;
|
|
799
|
-
this._roomRecord = null;
|
|
800
|
-
this._presence = null;
|
|
801
|
-
this._overlay = null;
|
|
802
|
-
this._pointers = null;
|
|
803
|
-
this._cursorStates = null;
|
|
804
|
-
this._frameId = null;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
window.customElements.define('swarm-cursors', SwarmCursorsElement);
|
|
808
|
-
})();
|
|
809
|
-
`;
|
|
810
|
-
|
|
811
|
-
export { BROWSER_SDK_JS, SWARM_UI_JS };
|