@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
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page theme token contract: the dashboard token names that HTML pages
|
|
3
|
+
* (design version 2) expose.
|
|
4
|
+
*
|
|
5
|
+
* A page's look comes only from these custom properties. Presets, per-page
|
|
6
|
+
* overrides and imported themes all resolve to this set, so one switch
|
|
7
|
+
* restyles the whole page. Sidebar, action, peer, type-scale and easing
|
|
8
|
+
* tokens are dashboard-only and stay out of the contract.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Color tokens: one value per mode. */
|
|
12
|
+
export const PAGE_THEME_COLOR_TOKENS = [
|
|
13
|
+
"--color-background",
|
|
14
|
+
"--color-foreground",
|
|
15
|
+
"--color-card",
|
|
16
|
+
"--color-card-foreground",
|
|
17
|
+
"--color-surface",
|
|
18
|
+
"--color-popover",
|
|
19
|
+
"--color-popover-foreground",
|
|
20
|
+
"--color-primary",
|
|
21
|
+
"--color-primary-foreground",
|
|
22
|
+
"--color-secondary",
|
|
23
|
+
"--color-secondary-foreground",
|
|
24
|
+
"--color-muted",
|
|
25
|
+
"--color-muted-foreground",
|
|
26
|
+
"--color-accent",
|
|
27
|
+
"--color-accent-foreground",
|
|
28
|
+
"--color-destructive",
|
|
29
|
+
"--color-destructive-foreground",
|
|
30
|
+
"--color-border",
|
|
31
|
+
"--color-border-subtle",
|
|
32
|
+
"--color-input",
|
|
33
|
+
"--color-ring",
|
|
34
|
+
"--color-chart-1",
|
|
35
|
+
"--color-chart-2",
|
|
36
|
+
"--color-chart-3",
|
|
37
|
+
"--color-chart-4",
|
|
38
|
+
"--color-chart-5",
|
|
39
|
+
"--color-status-success",
|
|
40
|
+
"--color-status-success-strong",
|
|
41
|
+
"--color-status-success-foreground",
|
|
42
|
+
"--color-status-active",
|
|
43
|
+
"--color-status-active-strong",
|
|
44
|
+
"--color-status-active-foreground",
|
|
45
|
+
"--color-status-error",
|
|
46
|
+
"--color-status-error-strong",
|
|
47
|
+
"--color-status-error-foreground",
|
|
48
|
+
"--color-status-info",
|
|
49
|
+
"--color-status-info-strong",
|
|
50
|
+
"--color-status-info-foreground",
|
|
51
|
+
"--color-status-pending",
|
|
52
|
+
"--color-status-pending-strong",
|
|
53
|
+
"--color-status-pending-foreground",
|
|
54
|
+
"--color-status-warning",
|
|
55
|
+
"--color-status-warning-strong",
|
|
56
|
+
"--color-status-warning-foreground",
|
|
57
|
+
"--color-status-paused",
|
|
58
|
+
"--color-status-paused-strong",
|
|
59
|
+
"--color-status-paused-foreground",
|
|
60
|
+
"--color-status-neutral",
|
|
61
|
+
"--color-status-neutral-strong",
|
|
62
|
+
"--color-status-neutral-foreground",
|
|
63
|
+
"--color-status-success-solid",
|
|
64
|
+
"--color-status-active-solid",
|
|
65
|
+
] as const;
|
|
66
|
+
|
|
67
|
+
/** Font and radius tokens: one value for both modes. */
|
|
68
|
+
export const PAGE_THEME_SHARED_TOKENS = [
|
|
69
|
+
"--font-sans",
|
|
70
|
+
"--font-mono",
|
|
71
|
+
"--radius-sm",
|
|
72
|
+
"--radius-md",
|
|
73
|
+
"--radius-lg",
|
|
74
|
+
"--radius-xl",
|
|
75
|
+
] as const;
|
|
76
|
+
|
|
77
|
+
export const PAGE_THEME_TOKENS = [...PAGE_THEME_COLOR_TOKENS, ...PAGE_THEME_SHARED_TOKENS] as const;
|
|
78
|
+
|
|
79
|
+
export type PageThemeToken = (typeof PAGE_THEME_TOKENS)[number];
|
|
80
|
+
export type PageThemeTokenValues = Partial<Record<PageThemeToken, string>>;
|
|
81
|
+
export type PageThemeTokens = { light: PageThemeTokenValues; dark: PageThemeTokenValues };
|
|
82
|
+
|
|
83
|
+
type PageThemeColorToken = (typeof PAGE_THEME_COLOR_TOKENS)[number];
|
|
84
|
+
type PageThemeSharedToken = (typeof PAGE_THEME_SHARED_TOKENS)[number];
|
|
85
|
+
|
|
86
|
+
/** Hive values from the light `@theme` block of `apps/ui/src/styles/globals.css`. */
|
|
87
|
+
const HIVE_SHARED_TOKENS: Record<PageThemeSharedToken, string> = {
|
|
88
|
+
"--font-sans": '"Space Grotesk", sans-serif',
|
|
89
|
+
"--font-mono": '"Space Mono", monospace',
|
|
90
|
+
"--radius-sm": "0.375rem",
|
|
91
|
+
"--radius-md": "0.5rem",
|
|
92
|
+
"--radius-lg": "0.625rem",
|
|
93
|
+
"--radius-xl": "0.625rem",
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const HIVE_LIGHT_COLORS: Record<PageThemeColorToken, string> = {
|
|
97
|
+
"--color-background": "oklch(1 0 0)",
|
|
98
|
+
"--color-foreground": "oklch(0.141 0.005 285.823)",
|
|
99
|
+
"--color-card": "oklch(1 0 0)",
|
|
100
|
+
"--color-card-foreground": "oklch(0.141 0.005 285.823)",
|
|
101
|
+
"--color-surface": "oklch(0.985 0.0015 286)",
|
|
102
|
+
"--color-popover": "oklch(1 0 0)",
|
|
103
|
+
"--color-popover-foreground": "oklch(0.141 0.005 285.823)",
|
|
104
|
+
"--color-primary": "oklch(0.555 0.163 48.998)",
|
|
105
|
+
"--color-primary-foreground": "oklch(0.985 0 0)",
|
|
106
|
+
"--color-secondary": "oklch(0.967 0.001 286.375)",
|
|
107
|
+
"--color-secondary-foreground": "oklch(0.21 0.006 285.885)",
|
|
108
|
+
"--color-muted": "oklch(0.967 0.001 286.375)",
|
|
109
|
+
"--color-muted-foreground": "oklch(0.552 0.016 285.938)",
|
|
110
|
+
"--color-accent": "oklch(0.943 0.003 286.375)",
|
|
111
|
+
"--color-accent-foreground": "oklch(0.21 0.006 285.885)",
|
|
112
|
+
"--color-destructive": "oklch(0.577 0.245 27.325)",
|
|
113
|
+
"--color-destructive-foreground": "oklch(0.985 0 0)",
|
|
114
|
+
"--color-border": "oklch(0.92 0.004 286.32)",
|
|
115
|
+
"--color-border-subtle": "oklch(0.945 0.003 286)",
|
|
116
|
+
"--color-input": "oklch(0.92 0.004 286.32)",
|
|
117
|
+
"--color-ring": "oklch(0.555 0.163 48.998)",
|
|
118
|
+
"--color-chart-1": "oklch(0.646 0.222 41.116)",
|
|
119
|
+
"--color-chart-2": "oklch(0.6 0.118 184.704)",
|
|
120
|
+
"--color-chart-3": "oklch(0.398 0.07 227.392)",
|
|
121
|
+
"--color-chart-4": "oklch(0.828 0.189 84.429)",
|
|
122
|
+
"--color-chart-5": "oklch(0.769 0.188 70.08)",
|
|
123
|
+
"--color-status-success": "oklch(0.74 0.1 163)",
|
|
124
|
+
"--color-status-success-strong": "oklch(0.5 0.09 163)",
|
|
125
|
+
"--color-status-success-foreground": "oklch(0.21 0.006 285.885)",
|
|
126
|
+
"--color-status-active": "oklch(0.81 0.11 75)",
|
|
127
|
+
"--color-status-active-strong": "oklch(0.55 0.1 68)",
|
|
128
|
+
"--color-status-active-foreground": "oklch(0.21 0.006 285.885)",
|
|
129
|
+
"--color-status-error": "oklch(0.72 0.12 25)",
|
|
130
|
+
"--color-status-error-strong": "oklch(0.51 0.14 25)",
|
|
131
|
+
"--color-status-error-foreground": "oklch(0.21 0.006 285.885)",
|
|
132
|
+
"--color-status-info": "oklch(0.74 0.09 235)",
|
|
133
|
+
"--color-status-info-strong": "oklch(0.5 0.09 240)",
|
|
134
|
+
"--color-status-info-foreground": "oklch(0.21 0.006 285.885)",
|
|
135
|
+
"--color-status-pending": "oklch(0.84 0.1 95)",
|
|
136
|
+
"--color-status-pending-strong": "oklch(0.55 0.09 90)",
|
|
137
|
+
"--color-status-pending-foreground": "oklch(0.21 0.006 285.885)",
|
|
138
|
+
"--color-status-warning": "oklch(0.76 0.11 55)",
|
|
139
|
+
"--color-status-warning-strong": "oklch(0.53 0.11 50)",
|
|
140
|
+
"--color-status-warning-foreground": "oklch(0.21 0.006 285.885)",
|
|
141
|
+
"--color-status-paused": "oklch(0.71 0.1 262)",
|
|
142
|
+
"--color-status-paused-strong": "oklch(0.5 0.1 262)",
|
|
143
|
+
"--color-status-paused-foreground": "oklch(0.21 0.006 285.885)",
|
|
144
|
+
"--color-status-neutral": "oklch(0.62 0.014 286)",
|
|
145
|
+
"--color-status-neutral-strong": "oklch(0.48 0.014 286)",
|
|
146
|
+
"--color-status-neutral-foreground": "oklch(0.21 0.006 285.885)",
|
|
147
|
+
"--color-status-success-solid": "oklch(0.627 0.194 149.2)",
|
|
148
|
+
"--color-status-active-solid": "oklch(0.666 0.179 58.318)",
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const HIVE_DARK_COLORS: Record<PageThemeColorToken, string> = {
|
|
152
|
+
"--color-background": "oklch(0.141 0.005 285.823)",
|
|
153
|
+
"--color-foreground": "oklch(0.985 0 0)",
|
|
154
|
+
"--color-card": "oklch(0.21 0.006 285.885)",
|
|
155
|
+
"--color-card-foreground": "oklch(0.985 0 0)",
|
|
156
|
+
"--color-surface": "oklch(0.185 0.006 286)",
|
|
157
|
+
"--color-popover": "oklch(0.21 0.006 285.885)",
|
|
158
|
+
"--color-popover-foreground": "oklch(0.985 0 0)",
|
|
159
|
+
"--color-primary": "oklch(0.769 0.188 70.08)",
|
|
160
|
+
"--color-primary-foreground": "oklch(0.21 0.006 285.885)",
|
|
161
|
+
"--color-secondary": "oklch(0.274 0.006 286.033)",
|
|
162
|
+
"--color-secondary-foreground": "oklch(0.985 0 0)",
|
|
163
|
+
"--color-muted": "oklch(0.274 0.006 286.033)",
|
|
164
|
+
"--color-muted-foreground": "oklch(0.705 0.015 286.067)",
|
|
165
|
+
"--color-accent": "oklch(0.274 0.006 286.033)",
|
|
166
|
+
"--color-accent-foreground": "oklch(0.985 0 0)",
|
|
167
|
+
"--color-destructive": "oklch(0.704 0.191 22.216)",
|
|
168
|
+
"--color-destructive-foreground": "oklch(0.985 0 0)",
|
|
169
|
+
"--color-border": "oklch(1 0 0 / 10%)",
|
|
170
|
+
"--color-border-subtle": "oklch(1 0 0 / 8%)",
|
|
171
|
+
"--color-input": "oklch(1 0 0 / 15%)",
|
|
172
|
+
"--color-ring": "oklch(0.769 0.188 70.08)",
|
|
173
|
+
"--color-chart-1": "oklch(0.488 0.243 264.376)",
|
|
174
|
+
"--color-chart-2": "oklch(0.696 0.17 162.48)",
|
|
175
|
+
"--color-chart-3": "oklch(0.769 0.188 70.08)",
|
|
176
|
+
"--color-chart-4": "oklch(0.627 0.265 303.9)",
|
|
177
|
+
"--color-chart-5": "oklch(0.645 0.246 16.439)",
|
|
178
|
+
"--color-status-success": "oklch(0.78 0.1 163)",
|
|
179
|
+
"--color-status-success-strong": "oklch(0.78 0.1 163)",
|
|
180
|
+
"--color-status-success-foreground": "oklch(0.21 0.006 285.885)",
|
|
181
|
+
"--color-status-active": "oklch(0.84 0.1 80)",
|
|
182
|
+
"--color-status-active-strong": "oklch(0.84 0.1 80)",
|
|
183
|
+
"--color-status-active-foreground": "oklch(0.21 0.006 285.885)",
|
|
184
|
+
"--color-status-error": "oklch(0.74 0.11 22)",
|
|
185
|
+
"--color-status-error-strong": "oklch(0.74 0.11 22)",
|
|
186
|
+
"--color-status-error-foreground": "oklch(0.21 0.006 285.885)",
|
|
187
|
+
"--color-status-info": "oklch(0.78 0.09 235)",
|
|
188
|
+
"--color-status-info-strong": "oklch(0.78 0.09 235)",
|
|
189
|
+
"--color-status-info-foreground": "oklch(0.21 0.006 285.885)",
|
|
190
|
+
"--color-status-pending": "oklch(0.86 0.09 95)",
|
|
191
|
+
"--color-status-pending-strong": "oklch(0.86 0.09 95)",
|
|
192
|
+
"--color-status-pending-foreground": "oklch(0.21 0.006 285.885)",
|
|
193
|
+
"--color-status-warning": "oklch(0.79 0.1 55)",
|
|
194
|
+
"--color-status-warning-strong": "oklch(0.79 0.1 55)",
|
|
195
|
+
"--color-status-warning-foreground": "oklch(0.21 0.006 285.885)",
|
|
196
|
+
"--color-status-paused": "oklch(0.74 0.09 260)",
|
|
197
|
+
"--color-status-paused-strong": "oklch(0.74 0.09 260)",
|
|
198
|
+
"--color-status-paused-foreground": "oklch(0.21 0.006 285.885)",
|
|
199
|
+
"--color-status-neutral": "oklch(0.72 0.012 286)",
|
|
200
|
+
"--color-status-neutral-strong": "oklch(0.72 0.012 286)",
|
|
201
|
+
"--color-status-neutral-foreground": "oklch(0.21 0.006 285.885)",
|
|
202
|
+
"--color-status-success-solid": "oklch(0.723 0.219 149.6)",
|
|
203
|
+
"--color-status-active-solid": "oklch(0.769 0.188 70.08)",
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Full Hive values for every contract token, copied from the light `@theme`
|
|
208
|
+
* and `.dark` blocks of `apps/ui/src/styles/globals.css` (keep in sync;
|
|
209
|
+
* `themes-presets.test.ts` fails on drift). The shared font and radius
|
|
210
|
+
* tokens come from the light block and apply to both modes.
|
|
211
|
+
*/
|
|
212
|
+
export const HIVE_PAGE_TOKENS: {
|
|
213
|
+
light: Record<PageThemeToken, string>;
|
|
214
|
+
dark: Record<PageThemeToken, string>;
|
|
215
|
+
} = {
|
|
216
|
+
light: { ...HIVE_LIGHT_COLORS, ...HIVE_SHARED_TOKENS },
|
|
217
|
+
dark: { ...HIVE_DARK_COLORS, ...HIVE_SHARED_TOKENS },
|
|
218
|
+
};
|
package/src/tools/app-upsert.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const registerAppUpsertTool = (server: McpServer) => {
|
|
|
24
24
|
{
|
|
25
25
|
title: "Create or update an app",
|
|
26
26
|
description:
|
|
27
|
-
"Stores a schema-backed app definition with models, queries/actions, pages, reusable elements, optional userConfig fields, and an optional top-level theme (a dashboard preset slug for the app's canvas
|
|
27
|
+
"Stores a schema-backed app definition with models, queries/actions, pages, reusable elements, optional userConfig fields, and an optional top-level theme (a dashboard preset slug for the app's canvas: hive (stock; omit to inherit the viewer's theme), meadow, iris, rose, cobalt, ember, carbon, paper (the warm editorial paper look), plus the classic presets github, vscode, material, solarized, tokyo, monokai, gruvbox, catppuccin; viewers can override it per-user; unknown slugs degrade to the viewer's dashboard theme), then returns its dashboard URL. userConfig is versioned schema only; each user's values are stored separately, survive rollback, and schema changes are always compatible. Pages may bind a declared field read-only at exactly /user/<field>; pure and bound reusable elements must receive that value through a prop. Elements are private by default: pure elements read declared props, allow $item/$index inside repeats, may expose one leaf ElementSlot, and cannot invoke actions; bound elements may use the defining app's queries/actions, while exported bound elements cannot navigate. Prop kinds include enum with a required non-empty enum values array. Pages or elements reuse them with literal ElementRef targets, and cross-app refs require export: true. Zero-model pure-UI apps are valid. Pass appId to update; breaking a referenced export is blocked by the compatibility gate unless forceElementBreak explicitly names it.",
|
|
28
28
|
annotations: { destructiveHint: false },
|
|
29
29
|
inputSchema: z.object({
|
|
30
30
|
name: z.string().min(1).describe("Human-readable app name."),
|
package/src/tools/create-page.ts
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
* the title slugifies to empty (e.g. all symbols), fall back to the
|
|
13
13
|
* generated page id.
|
|
14
14
|
*
|
|
15
|
+
* Design fields: `theme`, `themeTokens` and `designVersion` set how an HTML
|
|
16
|
+
* page is styled. A new page gets designVersion 2. On an upsert, an omitted
|
|
17
|
+
* field keeps the stored value, and `null` clears `theme` / `themeTokens`.
|
|
18
|
+
*
|
|
15
19
|
* Architecture note: this tool runs on the API server (per
|
|
16
20
|
* `src/server.ts:155`+ pattern) and accesses `src/be/db` directly. The
|
|
17
21
|
* worker-side DB-boundary invariant doesn't apply because `src/tools/*`
|
|
@@ -23,9 +27,18 @@ import { authorizeAssetKeyWrite } from "@/be/asset-key-auth";
|
|
|
23
27
|
import { resolveTaskAuditUserId } from "@/be/audit-user";
|
|
24
28
|
import { createPage, getPage, getPageBySlug, updatePage } from "@/be/db";
|
|
25
29
|
import { getPageEditCounter } from "@/be/db/page-versions";
|
|
30
|
+
import { classAttributeValues, countColorLiterals } from "@/pages/color-literals";
|
|
26
31
|
import { snapshotPage } from "@/pages/version";
|
|
32
|
+
import { readThemeFields } from "@/themes/page-fields";
|
|
33
|
+
import { PAGE_THEME_COLOR_TOKENS } from "@/themes/tokens";
|
|
27
34
|
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
28
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
AssetKeySchema,
|
|
37
|
+
type Page,
|
|
38
|
+
PageAuthModeSchema,
|
|
39
|
+
PageContentTypeSchema,
|
|
40
|
+
PageThemeTokensInputSchema,
|
|
41
|
+
} from "@/types";
|
|
29
42
|
import { getAppUrl, getPublicMcpBaseUrl } from "@/utils/constants";
|
|
30
43
|
|
|
31
44
|
/** Same slugifier used by the HTTP createPage handler. */
|
|
@@ -46,6 +59,26 @@ function getAppBaseUrl(): string {
|
|
|
46
59
|
return getAppUrl();
|
|
47
60
|
}
|
|
48
61
|
|
|
62
|
+
/** A `swarm-` primitive class inside one class attribute value. */
|
|
63
|
+
const SWARM_CLASS = /(?:^|\s)swarm-/;
|
|
64
|
+
const COLOR_TOKEN_REFERENCE = /var\(\s*--color-/i;
|
|
65
|
+
const PAGE_COLOR_TOKENS: ReadonlySet<string> = new Set<string>(PAGE_THEME_COLOR_TOKENS);
|
|
66
|
+
|
|
67
|
+
/** The body uses a `swarm-` class or a `var(--color-...)` token, which only design version 2 styles. */
|
|
68
|
+
function bodyUsesDesignSystem(html: string): boolean {
|
|
69
|
+
return (
|
|
70
|
+
COLOR_TOKEN_REFERENCE.test(html) ||
|
|
71
|
+
classAttributeValues(html).some((value) => SWARM_CLASS.test(value))
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The stored overrides set light colors and no dark colors, so dark mode keeps the preset's colors. */
|
|
76
|
+
function hasLightOnlyColors(tokens: Page["themeTokens"]): boolean {
|
|
77
|
+
if (!tokens) return false;
|
|
78
|
+
const isColor = (name: string) => PAGE_COLOR_TOKENS.has(name);
|
|
79
|
+
return Object.keys(tokens.light).some(isColor) && !Object.keys(tokens.dark).some(isColor);
|
|
80
|
+
}
|
|
81
|
+
|
|
49
82
|
export const registerCreatePageTool = (server: McpServer) => {
|
|
50
83
|
createToolRegistrar(server)(
|
|
51
84
|
"create_page",
|
|
@@ -56,7 +89,15 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
56
89
|
"Calls are upsert-by-(agent, slug): if you previously created a page " +
|
|
57
90
|
"with the same slug, its prior state is snapshotted and the row is " +
|
|
58
91
|
"updated. Use this for static reports, dashboards, or JSON action " +
|
|
59
|
-
"specs that don't need a long-lived process."
|
|
92
|
+
"specs that don't need a long-lived process. " +
|
|
93
|
+
"HTML pages use the swarm design system (designVersion 2): theme " +
|
|
94
|
+
"tokens such as var(--color-primary), the swarm-* primitives, and " +
|
|
95
|
+
"Tailwind v4 utilities such as bg-card and text-muted-foreground. " +
|
|
96
|
+
"Set `theme` to a preset id or pass `themeTokens` (a token map, or a " +
|
|
97
|
+
'CSS variable block with format "css") to restyle the whole page. ' +
|
|
98
|
+
"Do not hardcode colors: inside the dashboard the page follows the " +
|
|
99
|
+
"viewer's theme and dark mode. Pages created before designVersion 2 " +
|
|
100
|
+
"keep the old look; pass designVersion: 2 when you rewrite one.",
|
|
60
101
|
annotations: { destructiveHint: false },
|
|
61
102
|
inputSchema: z.object({
|
|
62
103
|
key: AssetKeySchema.optional().describe(
|
|
@@ -99,6 +140,27 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
99
140
|
.describe(
|
|
100
141
|
"Declared credential needs for JSON pages (renderer ignores for v1 — reserved for follow-up).",
|
|
101
142
|
),
|
|
143
|
+
theme: z
|
|
144
|
+
.string()
|
|
145
|
+
.nullable()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe(
|
|
148
|
+
"Theme preset id that restyles the whole page, for example paper, github or hive. An unknown id returns an error that lists every preset. Omit to follow the viewer's theme (on update, to keep the stored one). Pass null to clear it.",
|
|
149
|
+
),
|
|
150
|
+
themeTokens: PageThemeTokensInputSchema.nullable()
|
|
151
|
+
.optional()
|
|
152
|
+
.describe(
|
|
153
|
+
'Per-page token overrides, applied on top of the preset. Send { light, dark } maps of token name to CSS value (for example { light: { "--color-primary": "oklch(0.55 0.2 260)" } }), or { format: "css", css } with a CSS variable block (:root, .dark, @theme) as shadcn, tweakcn and Tailwind v4 export it. Stored normalized. Names outside the token contract, and values that reference a variable outside it, are ignored and reported in the result. Replaces the stored overrides. Omit to keep them on update. Pass null to clear them.',
|
|
154
|
+
),
|
|
155
|
+
designVersion: z
|
|
156
|
+
.number()
|
|
157
|
+
.int()
|
|
158
|
+
.min(1)
|
|
159
|
+
.max(2)
|
|
160
|
+
.optional()
|
|
161
|
+
.describe(
|
|
162
|
+
"Design system version. 2 is the swarm design system and the default for new pages. 1 is the original look that older pages keep. Omit on update to keep the stored value.",
|
|
163
|
+
),
|
|
102
164
|
}),
|
|
103
165
|
outputSchema: swarmToolOutputSchema({
|
|
104
166
|
yourAgentId: z.string().optional(),
|
|
@@ -107,6 +169,11 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
107
169
|
version: z.number().optional(),
|
|
108
170
|
app_url: z.string().optional(),
|
|
109
171
|
api_url: z.string().optional(),
|
|
172
|
+
designVersion: z.number().optional(),
|
|
173
|
+
ignoredTokens: z.array(z.string()).optional(),
|
|
174
|
+
colorLiteralCount: z.number().optional(),
|
|
175
|
+
usesDesignSystem: z.boolean().optional(),
|
|
176
|
+
lightOnlyColors: z.boolean().optional(),
|
|
110
177
|
}),
|
|
111
178
|
},
|
|
112
179
|
async (input, requestInfo, _meta) => {
|
|
@@ -115,6 +182,9 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
115
182
|
return toolErr(msg);
|
|
116
183
|
}
|
|
117
184
|
|
|
185
|
+
const themeFields = readThemeFields(input);
|
|
186
|
+
if ("error" in themeFields) return toolErr(themeFields.error);
|
|
187
|
+
|
|
118
188
|
const slug = input.slug ?? slugify(input.title);
|
|
119
189
|
const finalSlug = slug || "page"; // Fallback if title slugifies to empty.
|
|
120
190
|
|
|
@@ -167,6 +237,10 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
167
237
|
passwordHash: passwordHash ?? null,
|
|
168
238
|
body: input.body,
|
|
169
239
|
needsCredentials: needsCredentialsNames ?? null,
|
|
240
|
+
// Omitted design fields keep the stored values.
|
|
241
|
+
theme: themeFields.theme,
|
|
242
|
+
themeTokens: themeFields.themeTokens,
|
|
243
|
+
designVersion: input.designVersion,
|
|
170
244
|
});
|
|
171
245
|
if (!updated) {
|
|
172
246
|
const msg = `Failed to update existing page ${existing.id}.`;
|
|
@@ -188,6 +262,9 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
188
262
|
passwordHash,
|
|
189
263
|
body: input.body,
|
|
190
264
|
needsCredentials: needsCredentialsNames,
|
|
265
|
+
theme: themeFields.theme,
|
|
266
|
+
themeTokens: themeFields.themeTokens,
|
|
267
|
+
designVersion: input.designVersion,
|
|
191
268
|
});
|
|
192
269
|
id = created.id;
|
|
193
270
|
} catch (err) {
|
|
@@ -209,17 +286,46 @@ export const registerCreatePageTool = (server: McpServer) => {
|
|
|
209
286
|
const appUrl = `${getAppBaseUrl()}/pages/${id}`;
|
|
210
287
|
const version = await getPageEditCounter(id);
|
|
211
288
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
289
|
+
// Judged on the saved page, so an upsert that keeps an older design
|
|
290
|
+
// version is judged by the version it keeps. The NUDGES entry for this
|
|
291
|
+
// tool reads these flags. Only HTML pages get the design system head.
|
|
292
|
+
const designFlags =
|
|
293
|
+
fresh.contentType === "text/html"
|
|
294
|
+
? {
|
|
295
|
+
usesDesignSystem:
|
|
296
|
+
typeof input.theme === "string" ||
|
|
297
|
+
Boolean(input.themeTokens) ||
|
|
298
|
+
bodyUsesDesignSystem(fresh.body),
|
|
299
|
+
lightOnlyColors: hasLightOnlyColors(fresh.themeTokens),
|
|
300
|
+
...(fresh.designVersion >= 2
|
|
301
|
+
? { colorLiteralCount: countColorLiterals(fresh.body) }
|
|
302
|
+
: {}),
|
|
303
|
+
}
|
|
304
|
+
: {};
|
|
305
|
+
const { ignored } = themeFields;
|
|
306
|
+
|
|
307
|
+
return toolOk(
|
|
308
|
+
`Page "${input.title}" saved (slug=${finalSlug}, version=${version}, designVersion=${fresh.designVersion}).` +
|
|
309
|
+
(ignored.length > 0
|
|
310
|
+
? " Some theme tokens were ignored (outside the page token contract or referencing a variable outside it)."
|
|
311
|
+
: ""),
|
|
312
|
+
{
|
|
313
|
+
details:
|
|
314
|
+
`API: ${apiUrl}\n App: ${appUrl}` +
|
|
315
|
+
(ignored.length > 0 ? `\n Ignored theme tokens: ${ignored.join(", ")}` : ""),
|
|
316
|
+
data: {
|
|
317
|
+
yourAgentId: requestInfo.agentId,
|
|
318
|
+
id,
|
|
319
|
+
key: fresh.key,
|
|
320
|
+
version,
|
|
321
|
+
app_url: appUrl,
|
|
322
|
+
api_url: apiUrl,
|
|
323
|
+
designVersion: fresh.designVersion,
|
|
324
|
+
...(ignored.length > 0 ? { ignoredTokens: ignored } : {}),
|
|
325
|
+
...designFlags,
|
|
326
|
+
},
|
|
221
327
|
},
|
|
222
|
-
|
|
328
|
+
);
|
|
223
329
|
},
|
|
224
330
|
);
|
|
225
331
|
};
|
package/src/tools/send-task.ts
CHANGED
|
@@ -5,9 +5,7 @@ import { resolveTaskAuditUserId } from "@/be/audit-user";
|
|
|
5
5
|
import {
|
|
6
6
|
createTaskExtended,
|
|
7
7
|
extensionAgentAssignmentError,
|
|
8
|
-
findCompletedTaskInThread,
|
|
9
8
|
findExistingLinearTrackerContextWork,
|
|
10
|
-
findRecentCancelledTaskInThread,
|
|
11
9
|
getActiveTaskCount,
|
|
12
10
|
getAgentById,
|
|
13
11
|
getDbClient,
|
|
@@ -23,6 +21,10 @@ import { repointTrackerSyncBySwarmId } from "@/be/db-queries/tracker";
|
|
|
23
21
|
import { explicitModelErrorForAgent } from "@/be/model-validation";
|
|
24
22
|
import { applyPreTaskCreate } from "@/extensions/apply-task-create";
|
|
25
23
|
import { can } from "@/rbac";
|
|
24
|
+
import {
|
|
25
|
+
evaluateFollowUpRedelegation,
|
|
26
|
+
followUpThreadForSourceTask,
|
|
27
|
+
} from "@/tasks/follow-up-redelegation-guard";
|
|
26
28
|
import { checkSlackRoutingCoherence } from "@/tasks/slack-routing";
|
|
27
29
|
import { findDuplicateTask } from "@/tools/task-dedup";
|
|
28
30
|
import { ownerCtx, type ToolCtx } from "@/tools/task-tool-ctx";
|
|
@@ -163,7 +165,13 @@ export const sendTaskInputSchema = z
|
|
|
163
165
|
.boolean()
|
|
164
166
|
.default(false)
|
|
165
167
|
.describe(
|
|
166
|
-
"If true, skip duplicate detection and create the task even if a similar one exists.",
|
|
168
|
+
"If true, skip duplicate detection and create the task even if a similar one exists. Does not bypass the follow-up re-delegation guard; see allowRedelegation.",
|
|
169
|
+
),
|
|
170
|
+
allowRedelegation: z
|
|
171
|
+
.boolean()
|
|
172
|
+
.default(false)
|
|
173
|
+
.describe(
|
|
174
|
+
"Only matters when you call send-task from a follow-up task in a Slack thread. Such a dispatch is blocked when it repeats a task already completed in that thread (same-work rule, unless a task there was cancelled or failed after that completion), or when you already dispatched 10 tasks into the thread in the last 6 hours (loop-cap rule). Set true to dispatch anyway; the override is logged. Use it only for deliberate re-runs or long chains, never to retry a block you have not read.",
|
|
167
175
|
),
|
|
168
176
|
slackChannelId: z
|
|
169
177
|
.string()
|
|
@@ -292,6 +300,7 @@ export async function sendTaskHandler(
|
|
|
292
300
|
effort,
|
|
293
301
|
profile,
|
|
294
302
|
allowDuplicate,
|
|
303
|
+
allowRedelegation,
|
|
295
304
|
slackChannelId,
|
|
296
305
|
slackThreadTs,
|
|
297
306
|
slackUserId,
|
|
@@ -316,6 +325,7 @@ export async function sendTaskHandler(
|
|
|
316
325
|
const requestedLeadOnly = ctx.kind === "user" ? false : leadOnly;
|
|
317
326
|
const requestedCapabilities = ctx.kind === "user" ? undefined : requiredCapabilities;
|
|
318
327
|
const requestedAllowDuplicate = ctx.kind === "user" ? false : allowDuplicate;
|
|
328
|
+
const requestedAllowRedelegation = ctx.kind === "user" ? false : allowRedelegation;
|
|
319
329
|
const requestedOverrideSlackContext = ctx.kind === "user" ? false : overrideSlackContext;
|
|
320
330
|
|
|
321
331
|
// Defense in depth for direct TypeScript callers that bypass MCP schema parsing.
|
|
@@ -572,7 +582,9 @@ export async function sendTaskHandler(
|
|
|
572
582
|
// Every read in this handler releases the FIFO lock, so two concurrent
|
|
573
583
|
// send-task calls with the same creator and text otherwise both pass the
|
|
574
584
|
// guards and both create a task (no UNIQUE index arbitrates them).
|
|
575
|
-
const evaluateDedupGuards = async (
|
|
585
|
+
const evaluateDedupGuards = async (
|
|
586
|
+
logOverride: boolean,
|
|
587
|
+
): Promise<{
|
|
576
588
|
ok: boolean;
|
|
577
589
|
message: string;
|
|
578
590
|
task?: AgentTask;
|
|
@@ -602,59 +614,35 @@ export async function sendTaskHandler(
|
|
|
602
614
|
}
|
|
603
615
|
}
|
|
604
616
|
|
|
605
|
-
// Guard: prevent re-delegation from follow-up tasks
|
|
606
|
-
//
|
|
607
|
-
//
|
|
608
|
-
// This prevents the cycle: worker completes → follow-up → Lead re-delegates → repeat.
|
|
609
|
-
//
|
|
610
|
-
// Exception: if a MORE RECENT task in the same thread was cancelled (exit 130,
|
|
611
|
-
// status='cancelled', or status='failed' with failureReason containing
|
|
612
|
-
// "cancelled"), bypass the guard. A cancellation means the work was
|
|
613
|
-
// interrupted — re-dispatch is the correct response, not a deduped no-op.
|
|
614
|
-
// Without this bypass, a cancelled worker permanently jams the thread
|
|
615
|
-
// against re-delegation when an earlier completed sibling exists.
|
|
617
|
+
// Guard: prevent re-delegation from follow-up tasks (same-work and
|
|
618
|
+
// loop-cap rules, see src/tasks/follow-up-redelegation-guard.ts).
|
|
619
|
+
// allowRedelegation bypasses both and is logged.
|
|
616
620
|
//
|
|
617
621
|
// NOTE: `taskType === "resume"` (created by createResumeFollowUp on
|
|
618
622
|
// supersede) is intentionally NOT in this guard — a resume IS the legitimate
|
|
619
623
|
// re-dispatch and bypassing the check is correct. Do not add "resume" here.
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
624
|
+
const followUpThread = creatorAgentId ? await followUpThreadForSourceTask(sourceTaskId) : null;
|
|
625
|
+
if (followUpThread && creatorAgentId) {
|
|
626
|
+
const blocked = await evaluateFollowUpRedelegation({
|
|
627
|
+
...followUpThread,
|
|
628
|
+
creatorAgentId,
|
|
629
|
+
taskDescription,
|
|
630
|
+
targetAgentId: taskOptions.agentId ?? taskOptions.offeredTo,
|
|
631
|
+
});
|
|
632
|
+
if (blocked && !requestedAllowRedelegation) {
|
|
633
|
+
return { ok: false, message: blocked.message };
|
|
634
|
+
}
|
|
635
|
+
if (blocked && logOverride) {
|
|
636
|
+
console.log(
|
|
637
|
+
`[send-task] follow-up re-delegation override: rule=${blocked.rule} creatorAgentId=${creatorAgentId} sourceTaskId=${sourceTaskId} thread=${followUpThread.channelId}/${followUpThread.threadTs}`,
|
|
631
638
|
);
|
|
632
|
-
if (recentCompleted) {
|
|
633
|
-
const recentCancelled = await findRecentCancelledTaskInThread(
|
|
634
|
-
sourceTask.slackChannelId,
|
|
635
|
-
sourceTask.slackThreadTs,
|
|
636
|
-
2880,
|
|
637
|
-
);
|
|
638
|
-
const cancelledMoreRecent =
|
|
639
|
-
recentCancelled &&
|
|
640
|
-
new Date(recentCancelled.lastUpdatedAt).getTime() >
|
|
641
|
-
new Date(recentCompleted.lastUpdatedAt).getTime();
|
|
642
|
-
if (!cancelledMoreRecent) {
|
|
643
|
-
return {
|
|
644
|
-
ok: false,
|
|
645
|
-
message: `Blocked: re-delegation from follow-up task in a thread that already has completed work (task ${recentCompleted.id.slice(0, 8)}). The original request was already handled.`,
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
// else: fall through — the cancellation is more recent than the
|
|
649
|
-
// completion, so re-delegation is legitimate.
|
|
650
|
-
}
|
|
651
639
|
}
|
|
652
640
|
}
|
|
653
641
|
|
|
654
642
|
return null;
|
|
655
643
|
};
|
|
656
644
|
|
|
657
|
-
const guard = await evaluateDedupGuards();
|
|
645
|
+
const guard = await evaluateDedupGuards(true);
|
|
658
646
|
if (guard) {
|
|
659
647
|
const guardData = {
|
|
660
648
|
yourAgentId: creatorAgentId,
|
|
@@ -669,7 +657,7 @@ export async function sendTaskHandler(
|
|
|
669
657
|
// Authoritative re-check: the reads above are separated from the INSERT by
|
|
670
658
|
// the whole handler, so only a guard inside this transaction can see a
|
|
671
659
|
// concurrent send-task's committed task.
|
|
672
|
-
const raced = await evaluateDedupGuards();
|
|
660
|
+
const raced = await evaluateDedupGuards(false);
|
|
673
661
|
if (raced) return { success: raced.ok, message: raced.message, task: raced.task };
|
|
674
662
|
|
|
675
663
|
// This transaction already checked the tracker key, excluding the caller's
|
|
@@ -94,7 +94,7 @@ export const registerSlackLeaveThreadTool = (server: McpServer) => {
|
|
|
94
94
|
return toolErr("No Slack thread context available.");
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
await leaveSlackThread(slackChannelId, slackThreadTs, agent.id);
|
|
97
|
+
await leaveSlackThread(slackChannelId, slackThreadTs, { agentId: agent.id });
|
|
98
98
|
return toolOk(
|
|
99
99
|
`Left Slack thread ${slackChannelId}/${slackThreadTs}. Messages there are ignored until someone @mentions the bot.`,
|
|
100
100
|
{ data: { channelId: slackChannelId, threadTs: slackThreadTs } },
|