thursday-agent 0.11.0 → 0.13.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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +4 -4
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +18 -19
- package/.next/server/app/_not-found.segments/_full.segment.rsc +18 -19
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -15
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +8 -8
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/keep-working/route.js +7 -7
- package/.next/server/app/api/bot/keep-working/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js +7 -7
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js +7 -7
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route.js +5 -5
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/route.js +3 -3
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +3 -3
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +2 -2
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +4 -4
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js +4 -4
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js +6 -6
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js +6 -6
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js +5 -5
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +5 -5
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +5 -5
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js +15 -14
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js +4 -4
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/reach/route.js +13 -12
- package/.next/server/app/api/reach/route.js.nft.json +1 -1
- package/.next/server/app/api/routine/route.js +8 -9
- package/.next/server/app/api/routine/route.js.nft.json +1 -1
- package/.next/server/app/api/signins/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +2 -2
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +2 -2
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +6 -6
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +6 -6
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/text/route.js +14 -13
- package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +15 -14
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/files/route.js +10 -6
- package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +9 -4
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +2 -2
- package/.next/server/app/artifact/[...path]/page.js +5 -4
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +67 -56
- package/.next/server/app/page.js +10 -11
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__0o49ztf._.js → [root-of-the-server]__0-k4_ie._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__0209ah4._.js +6 -6
- package/.next/server/chunks/[root-of-the-server]__04wldw9._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0h_x6q6._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__0i23tc1._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0nr-v8s._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0paqm5y._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0qog7sm._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0yisc5v._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1-swlkw._.js +3 -3
- package/.next/server/chunks/[root-of-the-server]__12iddfq._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__15p29m3._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__17ses32._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__18-2tsq._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__1cjxw0-._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1gi2nns._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1iauz8a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1k3j52n._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__209k6pk._.js → [root-of-the-server]__1lb_pxg._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__1ndi14y._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1xqsrqq._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__2163i40._.js +5 -0
- package/.next/server/chunks/_0ci0abh._.js +3 -0
- package/.next/server/chunks/_0eauz4t._.js +1 -1
- package/.next/server/chunks/_0f6ts7z._.js +1 -1
- package/.next/server/chunks/_0fg-1oj._.js +5 -0
- package/.next/server/chunks/_0khihjk._.js +2 -2
- package/.next/server/chunks/_0n74zsf._.js +1 -1
- package/.next/server/chunks/_0na2fj1._.js +2 -2
- package/.next/server/chunks/_0oh_99-._.js +3 -0
- package/.next/server/chunks/_0x-ej3f._.js +24 -24
- package/.next/server/chunks/_0z3nz21._.js +3 -0
- package/.next/server/chunks/_10tkr26._.js +1 -1
- package/.next/server/chunks/_12-amdu._.js +2 -2
- package/.next/server/chunks/_136j09a._.js +1 -1
- package/.next/server/chunks/_15740dw._.js +1 -1
- package/.next/server/chunks/_18izeh1._.js +5 -0
- package/.next/server/chunks/_1_5mnq4._.js +1 -1
- package/.next/server/chunks/_1ajbhv6._.js +2 -2
- package/.next/server/chunks/_1dc_d1q._.js +2 -2
- package/.next/server/chunks/_1drgfx4._.js +1 -1
- package/.next/server/chunks/_1e48czp._.js +2 -2
- package/.next/server/chunks/_1f06zo4._.js +3 -0
- package/.next/server/chunks/_1ic3bew._.js +2 -2
- package/.next/server/chunks/_1jn-aep._.js +2 -2
- package/.next/server/chunks/_1jn5btd._.js +6 -0
- package/.next/server/chunks/_1kg70wc._.js +2 -2
- package/.next/server/chunks/_1m2i5pt._.js +5 -0
- package/.next/server/chunks/_1ogqovh._.js +4 -4
- package/.next/server/chunks/_1qxheoa._.js +1 -1
- package/.next/server/chunks/_1ry6afh._.js +18 -0
- package/.next/server/chunks/_1taa4bs._.js +1 -1
- package/.next/server/chunks/_1tpr507._.js +1 -1
- package/.next/server/chunks/_1y8w80a._.js +1 -1
- package/.next/server/chunks/_1zxp-p6._.js +1 -1
- package/.next/server/chunks/_204744f._.js +5 -0
- package/.next/server/chunks/_20fsr_z._.js +1 -1
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0-cnt0l._.js +1 -1
- package/.next/server/chunks/features_0hdaci0._.js +1 -1
- package/.next/server/chunks/features_0p85gv6._.js +3 -0
- package/.next/server/chunks/{node_modules_zod_v4_0_v5xf5._.js → node_modules_zod_v4_01bha1c._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_0q9hvql._.js → node_modules_zod_v4_0b99z6a._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_1jg8iwg._.js → node_modules_zod_v4_1zz6lo1._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__04upd5v._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0dxszdt._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0eezycw._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0hpp3nw._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0yngu44._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16z72ny._.js +6 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1u_ry86._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__1iwyp1e._.js → [root-of-the-server]__1unh_ew._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__20re7ya._.js +3 -0
- package/.next/server/chunks/ssr/_00pgq9d._.js +5 -0
- package/.next/server/chunks/ssr/_07ke63g._.js +3 -0
- package/.next/server/chunks/ssr/_0agcbk7._.js +3 -0
- package/.next/server/chunks/ssr/_0e-gw2_._.js +3 -0
- package/.next/server/chunks/ssr/{_1ybo1hd._.js → _0f_om6y._.js} +3 -3
- package/.next/server/chunks/ssr/_0fqhhwi._.js +1 -1
- package/.next/server/chunks/ssr/{_026qnc9._.js → _0gpn71k._.js} +3 -3
- package/.next/server/chunks/ssr/_0iizjr9._.js +3 -0
- package/.next/server/chunks/ssr/_0ixvzo6._.js +75 -0
- package/.next/server/chunks/ssr/_0kkdx7t._.js +3 -0
- package/.next/server/chunks/ssr/_0lufvw7._.js +118 -0
- package/.next/server/chunks/ssr/_0vi6ky6._.js +115 -0
- package/.next/server/chunks/ssr/{_0ouzu9f._.js → _0yhji3e._.js} +2 -2
- package/.next/server/chunks/ssr/_0z38nha._.js +3 -0
- package/.next/server/chunks/ssr/{_1w2oba6._.js → _11nx2d4._.js} +2 -2
- package/.next/server/chunks/ssr/_12mijol._.js +2 -2
- package/.next/server/chunks/ssr/{_19ps4p3._.js → _150463c._.js} +8 -8
- package/.next/server/chunks/ssr/{_1bhy4yg._.js → _17d2ikl._.js} +2 -2
- package/.next/server/chunks/ssr/_19jez1a._.js +3 -0
- package/.next/server/chunks/ssr/_1blui1m._.js +3 -0
- package/.next/server/chunks/ssr/_1d423aj._.js +4 -4
- package/.next/server/chunks/ssr/{_1kd843u._.js → _1kbk28w._.js} +2 -2
- package/.next/server/chunks/ssr/_1kj_r9v._.js +3 -0
- package/.next/server/chunks/ssr/_1mqn9mc._.js +1 -1
- package/.next/server/chunks/ssr/_1myh7ss._.js +3 -0
- package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
- package/.next/server/chunks/ssr/_1ou5sj0._.js +3 -0
- package/.next/server/chunks/ssr/_1p8xorg._.js +1 -1
- package/.next/server/chunks/ssr/_1tzacpl._.js +3 -0
- package/.next/server/chunks/ssr/_1xoch6f._.js +1 -1
- package/.next/server/chunks/ssr/_1yh5bj5._.js +1 -1
- package/.next/server/chunks/ssr/{_0btzccu._.js → _2021n9-._.js} +2 -2
- package/.next/server/chunks/ssr/{_1kq2ye_._.js → _20argo3._.js} +2 -2
- package/.next/server/chunks/ssr/features_bot_1ll3wp7._.js +3 -0
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +1 -1
- package/.next/server/chunks/ssr/features_bot_thread_query_ts_023eklt._.js +1 -1
- package/.next/server/chunks/ssr/features_config_1qxe5ur._.js +20 -0
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +3 -3
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
- package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
- package/.next/server/chunks/ssr/features_workspace_00jz2hu._.js +1 -1
- package/.next/server/chunks/ssr/{node_modules_18jn2qo._.js → node_modules_06e0wlv._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1rjt833._.js → node_modules_0cj26-9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0yqy-0b._.js → node_modules_0d1rf5e._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zqddke._.js → node_modules_0e86703._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09dj429._.js → node_modules_0es09am._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1c0pg3k._.js → node_modules_0gr_dzf._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1en2jx5._.js → node_modules_0gtcwz9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0gmdur8._.js → node_modules_0hi9h8f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1qe-oxg._.js → node_modules_0lkop0t._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1-53ebx._.js → node_modules_0nghisk._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_02zt4az._.js → node_modules_0stovz0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_11bltzp._.js → node_modules_0we85kr._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_00pocul._.js → node_modules_0ya7y1s._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1p-c8cr._.js → node_modules_0yrbwkj._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_06i6bli._.js → node_modules_1-x70ie._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1-y9aho._.js → node_modules_12fd9g0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1x6uwvn._.js → node_modules_12wxrgr._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1tzw5sn._.js → node_modules_139uu4q._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0rbaymq._.js → node_modules_14gpoe1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_05ojmcl._.js → node_modules_18fmji6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0tf8_1e._.js → node_modules_19kkel8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_te3bu._.js → node_modules_1gcine1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_211zgim._.js → node_modules_1h4trkm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0evjwh1._.js → node_modules_1mub_qu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0auzgvx._.js → node_modules_1p78svs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0j3te-1._.js → node_modules_1xp-7ep._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0y51bqj._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0ay7_oi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1sc114e._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_182ydq_._.js} +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +69 -58
- package/.next/static/chunks/{39gj5vxz1zpm_.js → 01xjer0i_e5z5.js} +1 -1
- package/.next/static/chunks/{4440mws9jz3mt.js → 025bmrgeukcb2.js} +1 -1
- package/.next/static/chunks/03df16hs01-xi.js +1 -0
- package/.next/static/chunks/{1r4zajz14jp9-.js → 04e-e--5lk26x.js} +1 -1
- package/.next/static/chunks/0crocb7272z8k.js +1 -0
- package/.next/static/chunks/{03bhu4mk8en2q.js → 0dqsenl3uk_8z.js} +1 -1
- package/.next/static/chunks/0hhn8mf953761.js +1 -0
- package/.next/static/chunks/0n1o3k0z4m7c_.js +1 -0
- package/.next/static/chunks/0oe2zavre2a7d.css +1 -0
- package/.next/static/chunks/{1qzfgplyo18tc.js → 0oyz95sujd2c7.js} +1 -1
- package/.next/static/chunks/0srg9tv4105-i.js +1 -0
- package/.next/static/chunks/0t599wrclly7i.js +18 -0
- package/.next/static/chunks/{2-jn4xscbm-i2.js → 0u3ktztrzu1fa.js} +1 -1
- package/.next/static/chunks/{0r6nwxg4dv83t.js → 0u9ae9k_2g7k3.js} +1 -1
- package/.next/static/chunks/0x34bhth_sn35.js +1 -0
- package/.next/static/chunks/{0x_w4shtvrrfg.js → 0x_6z8vt8hyf4.js} +3 -3
- package/.next/static/chunks/{04imzjhvzw65d.js → 1_wstwzu1md-6.js} +2 -2
- package/.next/static/chunks/1aughn81slf90.js +1 -0
- package/.next/static/chunks/1g1j03h_l-e67.js +1 -0
- package/.next/static/chunks/1lp02y2nmddxg.js +1 -0
- package/.next/static/chunks/{35wdx3wt7cg4a.js → 1u5i-jti87jbo.js} +1 -1
- package/.next/static/chunks/211s4xjtecj2l.js +1 -0
- package/.next/static/chunks/2244-cat2jlvd.js +1 -0
- package/.next/static/chunks/{12scesro428m7.js → 2eev_i93slion.js} +1 -1
- package/.next/static/chunks/{3x6pggb-2kyrk.js → 2gocl3dq0_h1s.js} +1 -1
- package/.next/static/chunks/{3tz4dr0_8pq1-.js → 2m267diam_vib.js} +1 -1
- package/.next/static/chunks/{0hzbj7f48cmx0.js → 2o4dndk0d68do.js} +1 -1
- package/.next/static/chunks/{0ympuji_ufypd.js → 2sdwbfs1x5skp.js} +1 -1
- package/.next/static/chunks/2sjq4gsimlfqr.js +113 -0
- package/.next/static/chunks/{39vrqy1r_00jc.js → 2uleilh8ph06-.js} +1 -1
- package/.next/static/chunks/{0gljzv9fz1g7d.js → 2zchsg03a1pdp.js} +1 -1
- package/.next/static/chunks/32tmfirfjpulv.js +1 -0
- package/.next/static/chunks/{26-eblxwnykck.js → 337g9g_ux2gj-.js} +1 -1
- package/.next/static/chunks/376-s_i83irs-.js +1 -0
- package/.next/static/chunks/3blk-kpn39xr-.js +1 -0
- package/.next/static/chunks/3eieehp7wquyu.js +1 -0
- package/.next/static/chunks/3kc-e7pcj50ae.js +1 -0
- package/.next/static/chunks/3rwpyuo9nrrop.js +17 -0
- package/.next/static/chunks/3sf4l25l353ja.js +1 -0
- package/.next/static/chunks/{0zmrz4zfzm4dt.js → 3t9huugh-5_ps.js} +1 -1
- package/.next/static/chunks/3vz7m1w688juj.js +3 -0
- package/.next/static/chunks/{2kzwhbuobpkw3.js → 43q9cgbuw8krx.js} +2 -2
- package/.next/static/chunks/43skgt0h9woyu.js +1 -0
- package/app/api/events/app-event.client.ts +8 -2
- package/app/api/events/app-event.server.ts +7 -5
- package/app/api/events/app-event.ts +19 -8
- package/app/api/query-key.ts +13 -5
- package/bin/database.mjs +21 -11
- package/bin/thursday.mjs +5 -2
- package/components/ui/shiny-text.tsx +2 -2
- package/database/migrations/20260920024909_messy_baron_strucker/migration.sql +1 -0
- package/database/migrations/20260920024909_messy_baron_strucker/snapshot.json +1937 -0
- package/features/ai/components/model-picker.tsx +8 -2
- package/features/ai/model.schema.ts +26 -0
- package/features/artifact/components/artifact-setting.tsx +18 -24
- package/features/bot/bot.action.ts +3 -0
- package/features/bot/bot.runner.ts +25 -3
- package/features/bot/bot.seed.ts +98 -22
- package/features/bot/components/bot-badge.tsx +2 -2
- package/features/bot/components/bot-mark.tsx +12 -3
- package/features/bot/components/bot-room.tsx +36 -16
- package/features/bot/components/bot-setting.tsx +88 -34
- package/features/bot/components/crew-motion.ts +161 -0
- package/features/bot/components/mark-palette.tsx +3 -3
- package/features/bot/components/room-conversation.tsx +13 -8
- package/features/bot/components/room-list.tsx +9 -5
- package/features/bot/components/room-pill.tsx +171 -94
- package/features/bot/components/thread-badge.tsx +4 -4
- package/features/bot/components/thread-setting.tsx +58 -19
- package/features/bot/mark.const.ts +24 -0
- package/features/bot/thread.query.ts +32 -14
- package/features/bot/thread.store.ts +19 -16
- package/features/config/components/config-badge.tsx +7 -1
- package/features/config/components/config-setting.tsx +83 -214
- package/features/config/components/models-badge.tsx +5 -7
- package/features/config/components/voice-key.tsx +24 -1
- package/features/config/config.const.ts +9 -1
- package/features/connectors/components/mcp-setting.tsx +60 -29
- package/features/intro/components/intro.tsx +4 -18
- package/features/memory/components/memory-setting.tsx +11 -7
- package/features/reach/channel.ts +9 -1
- package/features/reach/components/reach-guide.tsx +606 -105
- package/features/reach/discord.ts +18 -3
- package/features/reach/reach.schema.ts +6 -0
- package/features/reach/reach.ts +55 -2
- package/features/reach/slack.ts +2 -1
- package/features/reach/telegram.ts +5 -1
- package/features/routine/components/routine-setting.tsx +46 -18
- package/features/settings/components/setting-ui.tsx +16 -58
- package/features/settings/components/settings.tsx +7 -4
- package/features/settings/settings.alert.ts +10 -9
- package/features/skills/components/skills-setting.tsx +78 -12
- package/features/skills/skills.action.ts +12 -0
- package/features/skills/skills.query.ts +24 -0
- package/features/thursday/components/call-log.tsx +19 -14
- package/features/thursday/components/side-captions.tsx +3 -2
- package/features/thursday/components/tab-state.tsx +5 -2
- package/features/thursday/components/thursday-setting.tsx +5 -6
- package/features/thursday/components/thursday.tsx +60 -29
- package/features/thursday/components/write-line.tsx +19 -5
- package/features/thursday/thursday.action.ts +4 -0
- package/features/thursday/thursday.query.ts +3 -2
- package/features/thursday/thursday.schema.ts +5 -0
- package/features/thursday/use-call-ring.ts +6 -1
- package/features/thursday/use-text-call.ts +25 -10
- package/features/thursday/use-thursday.ts +10 -1
- package/features/workspace/components/artifact-view.tsx +42 -33
- package/features/workspace/components/file-thumb.tsx +8 -4
- package/features/workspace/components/file-view.tsx +25 -2
- package/features/workspace/components/workspace-setting.tsx +27 -23
- package/features/workspace/workspace.query.ts +20 -1
- package/features/workspace/workspace.ts +14 -0
- package/guide/bots.md +27 -4
- package/guide/calls.md +7 -4
- package/guide/phone.md +23 -12
- package/guide/setup.md +24 -6
- package/guide/trouble.md +1 -1
- package/hooks/use-theme.ts +14 -0
- package/lib/protocol/events.client.ts +56 -14
- package/lib/protocol/events.server.ts +41 -12
- package/lib/utils.ts +1 -1
- package/package.json +1 -1
- package/scripts/reach-channels.test.mts +15 -2
- package/seed-skills/brief/daily-brief/SKILL.md +39 -0
- package/seed-skills/brief/daily-brief/page/brief.css +406 -0
- package/seed-skills/brief/daily-brief/references/brief.md +106 -0
- package/seed-skills/brief/daily-brief/references/preferences.md +67 -0
- package/seed-skills/brief/daily-brief/scripts/glance.mjs +128 -0
- package/seed-skills/brief/daily-brief/scripts/lib.mjs +182 -0
- package/seed-skills/brief/daily-brief/scripts/news.mjs +320 -0
- package/seed-skills/brief/daily-brief/scripts/page.mjs +322 -0
- package/seed-skills/brief/daily-brief/scripts/story.mjs +265 -0
- package/seed-skills/digest/README.md +20 -0
- package/seed-skills/digest/media-digest/SKILL.md +32 -0
- package/seed-skills/digest/media-digest/references/no-captions.md +20 -0
- package/seed-skills/digest/media-digest/references/page.md +56 -0
- package/seed-skills/digest/media-digest/references/reading.md +56 -0
- package/seed-skills/digest/media-digest/scripts/audio.mjs +232 -0
- package/seed-skills/digest/media-digest/scripts/digest.mjs +379 -0
- package/seed-skills/digest/media-digest/scripts/lib.mjs +284 -0
- package/seed-skills/digest/media-digest/scripts/part.mjs +16 -0
- package/seed-skills/digest/media-digest/scripts/text.mjs +287 -0
- package/seed-skills/digest/media-digest/scripts/yt.mjs +487 -0
- package/seed-skills/docs/README.md +32 -0
- package/seed-skills/docs/documents/SKILL.md +34 -0
- package/seed-skills/docs/documents/kit/package-lock.json +1596 -0
- package/seed-skills/docs/documents/kit/package.json +17 -0
- package/seed-skills/docs/documents/references/deck.md +63 -0
- package/seed-skills/docs/documents/references/invoice.md +64 -0
- package/seed-skills/docs/documents/references/pdf.md +59 -0
- package/seed-skills/docs/documents/references/print.md +43 -0
- package/seed-skills/docs/documents/references/sheets.md +49 -0
- package/seed-skills/docs/documents/references/translate.md +37 -0
- package/seed-skills/docs/documents/references/word.md +45 -0
- package/seed-skills/docs/documents/scripts/doc.mjs +123 -0
- package/seed-skills/docs/documents/scripts/lib/browser.mjs +259 -0
- package/seed-skills/docs/documents/scripts/lib/deck-chart.mjs +150 -0
- package/seed-skills/docs/documents/scripts/lib/deck.mjs +1132 -0
- package/seed-skills/docs/documents/scripts/lib/invoice.mjs +505 -0
- package/seed-skills/docs/documents/scripts/lib/kit.mjs +244 -0
- package/seed-skills/docs/documents/scripts/lib/pdf.mjs +645 -0
- package/seed-skills/docs/documents/scripts/lib/report.mjs +38 -0
- package/seed-skills/docs/documents/scripts/lib/sheet.mjs +523 -0
- package/seed-skills/docs/documents/scripts/lib/templates.mjs +34 -0
- package/seed-skills/docs/documents/scripts/lib/translate.mjs +691 -0
- package/seed-skills/docs/documents/scripts/lib/word.mjs +678 -0
- package/seed-skills/docs/documents/templates/letter.html +56 -0
- package/seed-skills/docs/documents/templates/print.css +219 -0
- package/seed-skills/docs/documents/templates/report.html +47 -0
- package/seed-skills/docs/documents/templates/resume.html +61 -0
- package/seed-skills/insta/instagram/references/post.md +31 -7
- package/seed-skills/trip/README.md +11 -0
- package/seed-skills/trip/travel/SKILL.md +40 -0
- package/seed-skills/trip/travel/page/itinerary.css +488 -0
- package/seed-skills/trip/travel/references/itinerary.md +70 -0
- package/seed-skills/trip/travel/references/plan.md +75 -0
- package/seed-skills/trip/travel/references/watch-and-book.md +39 -0
- package/seed-skills/trip/travel/scripts/flights.mjs +374 -0
- package/seed-skills/trip/travel/scripts/fx.mjs +57 -0
- package/seed-skills/trip/travel/scripts/hotels.mjs +356 -0
- package/seed-skills/trip/travel/scripts/itinerary.mjs +482 -0
- package/seed-skills/trip/travel/scripts/lib.mjs +120 -0
- package/seed-skills/trip/travel/scripts/selectors.mjs +78 -0
- package/seed-skills/trip/travel/scripts/watch.mjs +147 -0
- package/seed-skills/trip/travel/scripts/weather.mjs +150 -0
- package/seed-skills/tutor/picture-book/SKILL.md +6 -0
- package/seed-skills/tutor/picture-book/references/picture-book.md +22 -2
- package/.next/server/chunks/[root-of-the-server]__014ydvq._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__01d285y._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__04r4h-2._.js +0 -7
- package/.next/server/chunks/[root-of-the-server]__0ayldfn._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0cfszwn._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0npn_pn._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0rqgb17._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__17weeeg._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1ai5lme._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1tg5got._.js +0 -3
- package/.next/server/chunks/_05v8k21._.js +0 -7
- package/.next/server/chunks/_0k6qjcf._.js +0 -5
- package/.next/server/chunks/_1d_enhu._.js +0 -3
- package/.next/server/chunks/_1jc5g4p._.js +0 -6
- package/.next/server/chunks/_1nfr-75._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0md6j0x._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_14ih1vy._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1d6ez5-._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0m7u9j-._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0tzekbl._.js +0 -68
- package/.next/server/chunks/ssr/[root-of-the-server]__1756892._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1cz2rz5._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1nqw56a._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1w9hqq8._.js +0 -8
- package/.next/server/chunks/ssr/_05pl_u8._.js +0 -3
- package/.next/server/chunks/ssr/_097-ljd._.js +0 -4
- package/.next/server/chunks/ssr/_0evkpto._.js +0 -3
- package/.next/server/chunks/ssr/_0hjzb5o._.js +0 -3
- package/.next/server/chunks/ssr/_0lu1n_x._.js +0 -3
- package/.next/server/chunks/ssr/_0u7ko71._.js +0 -3
- package/.next/server/chunks/ssr/_0wd_o8-._.js +0 -3
- package/.next/server/chunks/ssr/_0ya0cb0._.js +0 -3
- package/.next/server/chunks/ssr/_10yyqtk._.js +0 -67
- package/.next/server/chunks/ssr/_12eyown._.js +0 -5
- package/.next/server/chunks/ssr/_132qkfz._.js +0 -5
- package/.next/server/chunks/ssr/_15zqt-t._.js +0 -3
- package/.next/server/chunks/ssr/_184327j._.js +0 -3
- package/.next/server/chunks/ssr/_1q683w8._.js +0 -20
- package/.next/server/chunks/ssr/_1tawxu2._.js +0 -3
- package/.next/server/chunks/ssr/_1xx4zlb._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_0s11m4r._.js +0 -3
- package/.next/static/chunks/03-724sj0nk_z.js +0 -3
- package/.next/static/chunks/0c_g4-11sha-1.js +0 -1
- package/.next/static/chunks/0h0lythv1ql93.js +0 -1
- package/.next/static/chunks/0lwunwbl7u7pt.js +0 -1
- package/.next/static/chunks/0rn9nbg6aif9f.js +0 -17
- package/.next/static/chunks/0vlgzqo9ka90v.js +0 -1
- package/.next/static/chunks/11tlxkr7a_rpc.js +0 -1
- package/.next/static/chunks/16s2fx3890_jd.js +0 -65
- package/.next/static/chunks/1g9yyvculuxj2.js +0 -1
- package/.next/static/chunks/1s6m4cmbn7htf.js +0 -1
- package/.next/static/chunks/1wl9t1-3i-q8p.css +0 -1
- package/.next/static/chunks/2-asot3p1j3yg.js +0 -1
- package/.next/static/chunks/22h9gvclqtx_2.js +0 -1
- package/.next/static/chunks/23nfu5g4vl_m7.js +0 -1
- package/.next/static/chunks/2m6jd3586ijb-.js +0 -1
- package/.next/static/chunks/2ndw4w4u2x51r.js +0 -1
- package/.next/static/chunks/304q9p54tcgm1.js +0 -1
- package/.next/static/chunks/37unh9460im7v.js +0 -18
- package/.next/static/chunks/3dipmu0mptqum.js +0 -1
- package/.next/static/chunks/3gki-squw28yu.js +0 -1
- package/.next/static/chunks/3nnzdl_te20hv.js +0 -1
- package/features/reach/components/reach-state.tsx +0 -71
- /package/.next/static/{En1vUPazxcYjPjnnahcN5 → fiNGsQfna8qldl8wU8wqr}/_buildManifest.js +0 -0
- /package/.next/static/{En1vUPazxcYjPjnnahcN5 → fiNGsQfna8qldl8wU8wqr}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{En1vUPazxcYjPjnnahcN5 → fiNGsQfna8qldl8wU8wqr}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// The browser the shell's session already has, used as a typesetter: HTML in, PDF or
|
|
2
|
+
// PNG out. Driven only through the shipped browser skill's session.mjs; a file is
|
|
3
|
+
// served from its own folder on a port the system picks, so two jobs never meet.
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import {
|
|
6
|
+
copyFileSync,
|
|
7
|
+
createReadStream,
|
|
8
|
+
existsSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
statSync,
|
|
11
|
+
writeFileSync,
|
|
12
|
+
} from "node:fs";
|
|
13
|
+
import { createServer } from "node:http";
|
|
14
|
+
import { basename, dirname, extname, join, resolve, sep } from "node:path";
|
|
15
|
+
import { kitFile, Stop, shippedSkill } from "./kit.mjs";
|
|
16
|
+
|
|
17
|
+
const TYPES = {
|
|
18
|
+
".html": "text/html; charset=utf-8",
|
|
19
|
+
".css": "text/css",
|
|
20
|
+
".js": "text/javascript",
|
|
21
|
+
".mjs": "text/javascript",
|
|
22
|
+
".json": "application/json",
|
|
23
|
+
".png": "image/png",
|
|
24
|
+
".jpg": "image/jpeg",
|
|
25
|
+
".jpeg": "image/jpeg",
|
|
26
|
+
".webp": "image/webp",
|
|
27
|
+
".gif": "image/gif",
|
|
28
|
+
".svg": "image/svg+xml",
|
|
29
|
+
".woff2": "font/woff2",
|
|
30
|
+
".woff": "font/woff",
|
|
31
|
+
".ttf": "font/ttf",
|
|
32
|
+
".otf": "font/otf",
|
|
33
|
+
".pdf": "application/pdf",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Where the kit's own files are served, beside the document's folder. */
|
|
37
|
+
const KIT_ROUTE = "/__docs-kit/";
|
|
38
|
+
|
|
39
|
+
let session = null;
|
|
40
|
+
async function sessionScripts() {
|
|
41
|
+
if (!session) {
|
|
42
|
+
session = await import(
|
|
43
|
+
shippedSkill("browser", "scripts", "session.mjs")
|
|
44
|
+
).catch(() => {
|
|
45
|
+
throw new Stop(
|
|
46
|
+
"The shipped browser skill's session.mjs is missing; this command prints through the browser.",
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
// A job that has not opened its browser yet gets a headless one; an open one is left as it is
|
|
50
|
+
try {
|
|
51
|
+
execFileSync("playwright-cli", ["--raw", "eval", "1"], {
|
|
52
|
+
stdio: "ignore",
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
try {
|
|
56
|
+
execFileSync("playwright-cli", ["open"], { stdio: "ignore" });
|
|
57
|
+
} catch {
|
|
58
|
+
throw new Stop(
|
|
59
|
+
"No browser could be opened (`playwright-cli open` failed): the browser skill's Install section.",
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return session;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Serves `root` and the kit on a free port; resolves to its base url and a stop. */
|
|
68
|
+
async function serve(root) {
|
|
69
|
+
const kitRoot = kitFile();
|
|
70
|
+
const server = createServer((req, res) => {
|
|
71
|
+
const path = decodeURIComponent(new URL(req.url, "http://x").pathname);
|
|
72
|
+
const [base, rel] = path.startsWith(KIT_ROUTE)
|
|
73
|
+
? [kitRoot, path.slice(KIT_ROUTE.length)]
|
|
74
|
+
: [root, path];
|
|
75
|
+
const full = resolve(base, `.${sep}${rel}`);
|
|
76
|
+
if (
|
|
77
|
+
!full.startsWith(base + sep) ||
|
|
78
|
+
!existsSync(full) ||
|
|
79
|
+
statSync(full).isDirectory()
|
|
80
|
+
) {
|
|
81
|
+
res.writeHead(404).end();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
res.writeHead(200, {
|
|
85
|
+
"content-type":
|
|
86
|
+
TYPES[extname(full).toLowerCase()] ?? "application/octet-stream",
|
|
87
|
+
});
|
|
88
|
+
createReadStream(full).pipe(res);
|
|
89
|
+
});
|
|
90
|
+
await new Promise((ok) => server.listen(0, "127.0.0.1", ok));
|
|
91
|
+
return {
|
|
92
|
+
base: `http://127.0.0.1:${server.address().port}`,
|
|
93
|
+
close: () => server.close(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Inter for Latin, Greek and Cyrillic, served from the kit, so a document prints the same on
|
|
99
|
+
* every machine; everything else falls through to the system's fonts.
|
|
100
|
+
*/
|
|
101
|
+
function fontCss() {
|
|
102
|
+
const css = readFileSync(
|
|
103
|
+
kitFile("@fontsource-variable", "inter", "wght.css"),
|
|
104
|
+
"utf8",
|
|
105
|
+
);
|
|
106
|
+
const italic = readFileSync(
|
|
107
|
+
kitFile("@fontsource-variable", "inter", "wght-italic.css"),
|
|
108
|
+
"utf8",
|
|
109
|
+
);
|
|
110
|
+
return `${css}\n${italic}`.replaceAll(
|
|
111
|
+
"url(./files/",
|
|
112
|
+
`url(${KIT_ROUTE}@fontsource-variable/inter/files/`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Opens `file` in a tab of its own, with the kit's fonts, and runs `work(tab, args)` in the
|
|
118
|
+
* session's VM (not Node: see session.mjs). Resolves to what `work` returned.
|
|
119
|
+
*/
|
|
120
|
+
export async function inTab(file, work, args = {}, { viewport } = {}) {
|
|
121
|
+
const { inPage, orFail } = await sessionScripts();
|
|
122
|
+
const server = await serve(dirname(file));
|
|
123
|
+
try {
|
|
124
|
+
return orFail(
|
|
125
|
+
await inPage(
|
|
126
|
+
async (page, a, h) => {
|
|
127
|
+
const tab = await page.context().newPage();
|
|
128
|
+
try {
|
|
129
|
+
if (a.viewport) await tab.setViewportSize(a.viewport);
|
|
130
|
+
await tab.goto(a.url, { waitUntil: "load" });
|
|
131
|
+
await tab.addStyleTag({ content: a.fonts });
|
|
132
|
+
await tab.evaluate(async () => {
|
|
133
|
+
await document.fonts.ready;
|
|
134
|
+
await Promise.all(
|
|
135
|
+
[...document.images].map((i) => i.decode().catch(() => {})),
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
const broken = await tab.evaluate(() =>
|
|
139
|
+
[...document.images]
|
|
140
|
+
.filter((i) => !i.naturalWidth)
|
|
141
|
+
.map((i) => i.getAttribute("src")),
|
|
142
|
+
);
|
|
143
|
+
const result = await h.work(tab, a.args);
|
|
144
|
+
return { result, broken };
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return { error: String(error?.message ?? error).slice(0, 800) };
|
|
147
|
+
} finally {
|
|
148
|
+
await tab.close();
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
url: `${server.base}/${encodeURIComponent(basename(file))}`,
|
|
153
|
+
fonts: fontCss(),
|
|
154
|
+
args,
|
|
155
|
+
viewport,
|
|
156
|
+
},
|
|
157
|
+
{ work },
|
|
158
|
+
),
|
|
159
|
+
);
|
|
160
|
+
} finally {
|
|
161
|
+
server.close();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Prints an HTML file to PDF. The page size and margins are the file's own `@page` rule.
|
|
167
|
+
* Resolves to the pictures that did not load and what overflows the page's width.
|
|
168
|
+
*/
|
|
169
|
+
export async function printPdf(file, out) {
|
|
170
|
+
const done = await inTab(
|
|
171
|
+
file,
|
|
172
|
+
async (tab, { out }) => {
|
|
173
|
+
await tab.emulateMedia({ media: "print" });
|
|
174
|
+
// Lay the page out at the printed width, from its own @page rule, to find what
|
|
175
|
+
// sticks out sideways: print cuts it rather than wrapping it
|
|
176
|
+
const page = await tab.evaluate(() => {
|
|
177
|
+
for (const sheet of document.styleSheets)
|
|
178
|
+
for (const rule of sheet.cssRules ?? [])
|
|
179
|
+
if (rule instanceof CSSPageRule && !rule.selectorText)
|
|
180
|
+
return {
|
|
181
|
+
size: rule.style.getPropertyValue("size"),
|
|
182
|
+
left: rule.style.getPropertyValue("margin-left"),
|
|
183
|
+
right: rule.style.getPropertyValue("margin-right"),
|
|
184
|
+
};
|
|
185
|
+
return null;
|
|
186
|
+
});
|
|
187
|
+
const PX = { mm: 96 / 25.4, cm: 96 / 2.54, in: 96, pt: 96 / 72, px: 1 };
|
|
188
|
+
const length = (v) => {
|
|
189
|
+
const m = /^([\d.]+)(mm|cm|in|pt|px)$/.exec(String(v).trim());
|
|
190
|
+
return m ? Number(m[1]) * PX[m[2]] : null;
|
|
191
|
+
};
|
|
192
|
+
const NAMED = {
|
|
193
|
+
a4: 793.7,
|
|
194
|
+
a5: 559.4,
|
|
195
|
+
a3: 1122.5,
|
|
196
|
+
letter: 816,
|
|
197
|
+
legal: 816,
|
|
198
|
+
};
|
|
199
|
+
const words = String(page?.size ?? "")
|
|
200
|
+
.toLowerCase()
|
|
201
|
+
.split(/\s+/);
|
|
202
|
+
const named = words.find((w) => w in NAMED);
|
|
203
|
+
let width = named ? NAMED[named] : (length(words[0]) ?? NAMED.letter);
|
|
204
|
+
if (words.includes("landscape"))
|
|
205
|
+
width =
|
|
206
|
+
{ a4: 1122.5, a5: 793.7, a3: 1587.4, letter: 1056, legal: 1344 }[
|
|
207
|
+
named
|
|
208
|
+
] ?? width;
|
|
209
|
+
width -= (length(page?.left) ?? 0) + (length(page?.right) ?? 0);
|
|
210
|
+
await tab.setViewportSize({ width: Math.round(width), height: 1000 });
|
|
211
|
+
const wide = await tab.evaluate(() => {
|
|
212
|
+
const limit = document.documentElement.clientWidth + 1;
|
|
213
|
+
const found = [];
|
|
214
|
+
for (const el of document.body.querySelectorAll("*")) {
|
|
215
|
+
const box = el.getBoundingClientRect();
|
|
216
|
+
if (box.width && box.right > limit && found.length < 5)
|
|
217
|
+
found.push(
|
|
218
|
+
`<${el.tagName.toLowerCase()}${el.className ? ` class="${el.className}"` : ""}> ${(el.textContent ?? "").trim().slice(0, 40)}`,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
return found;
|
|
222
|
+
});
|
|
223
|
+
await tab.pdf({
|
|
224
|
+
path: out,
|
|
225
|
+
preferCSSPageSize: true,
|
|
226
|
+
printBackground: true,
|
|
227
|
+
});
|
|
228
|
+
return { wide };
|
|
229
|
+
},
|
|
230
|
+
{ out },
|
|
231
|
+
);
|
|
232
|
+
return { broken: done.broken, wide: done.result.wide };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* A picture PowerPoint and Word cannot take (WebP, AVIF, GIF, SVG) redrawn as a PNG in `dir`,
|
|
237
|
+
* by the browser, which reads them all.
|
|
238
|
+
*/
|
|
239
|
+
export async function asPng(file, dir) {
|
|
240
|
+
const name = basename(file);
|
|
241
|
+
const out = join(dir, `${name.replace(/\.[^.]+$/, "")}.png`);
|
|
242
|
+
copyFileSync(file, join(dir, name));
|
|
243
|
+
const page = join(dir, "picture.html");
|
|
244
|
+
writeFileSync(
|
|
245
|
+
page,
|
|
246
|
+
`<!doctype html><style>html,body{margin:0;background:transparent}img{display:block;max-width:2400px}</style><img src="${encodeURIComponent(name)}">`,
|
|
247
|
+
);
|
|
248
|
+
const done = await inTab(
|
|
249
|
+
page,
|
|
250
|
+
async (tab, { out }) => {
|
|
251
|
+
await tab.locator("img").screenshot({ path: out, omitBackground: true });
|
|
252
|
+
},
|
|
253
|
+
{ out },
|
|
254
|
+
{ viewport: { width: 2400, height: 1600 } },
|
|
255
|
+
);
|
|
256
|
+
if (done.broken.length)
|
|
257
|
+
throw new Stop(`${name} is not a picture the browser can open.`);
|
|
258
|
+
return out;
|
|
259
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// A chart in the deck's PDF twin, drawn as SVG in the deck's colours. The .pptx carries
|
|
2
|
+
// PowerPoint's own chart of the same numbers, which stays editable there.
|
|
3
|
+
import { escapeHtml as esc } from "./kit.mjs";
|
|
4
|
+
|
|
5
|
+
const PX = 96;
|
|
6
|
+
|
|
7
|
+
/** The value as the chart labels it: its prefix and unit around a short number. */
|
|
8
|
+
const chartLabel = (c, v) =>
|
|
9
|
+
`${c.prefix ?? ""}${new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(v)}${v === 0 ? "" : (c.unit ?? "")}`;
|
|
10
|
+
|
|
11
|
+
export function chartSvg(s, t) {
|
|
12
|
+
const c = s.chart;
|
|
13
|
+
const w = s.w * PX;
|
|
14
|
+
const h = s.h * PX;
|
|
15
|
+
const kind = c.type ?? "bar";
|
|
16
|
+
const colors = t.series;
|
|
17
|
+
const series = c.series.map((one) => ({
|
|
18
|
+
name: String(one.name ?? ""),
|
|
19
|
+
values: one.values.map(Number),
|
|
20
|
+
}));
|
|
21
|
+
const fmt = (v) => chartLabel(c, v);
|
|
22
|
+
const legend = series.length > 1 && kind !== "pie" && kind !== "doughnut";
|
|
23
|
+
const font = `font-family="${esc(t.font)}, sans-serif"`;
|
|
24
|
+
if (kind === "pie" || kind === "doughnut") {
|
|
25
|
+
const values = series[0].values;
|
|
26
|
+
const total = values.reduce((a, b) => a + b, 0) || 1;
|
|
27
|
+
const r = Math.min(h * 0.42, w * 0.25);
|
|
28
|
+
const cx = r + 20;
|
|
29
|
+
const cy = h / 2;
|
|
30
|
+
let a0 = -Math.PI / 2;
|
|
31
|
+
const arcs = values
|
|
32
|
+
.map((v, i) => {
|
|
33
|
+
const a1 = a0 + (v / total) * Math.PI * 2;
|
|
34
|
+
const large = a1 - a0 > Math.PI ? 1 : 0;
|
|
35
|
+
const p = (a) => `${cx + r * Math.cos(a)},${cy + r * Math.sin(a)}`;
|
|
36
|
+
const d = `M${cx},${cy} L${p(a0)} A${r},${r} 0 ${large} 1 ${p(a1)} Z`;
|
|
37
|
+
a0 = a1;
|
|
38
|
+
return `<path d="${d}" fill="#${colors[i % colors.length]}" stroke="#fff" stroke-width="2"/>`;
|
|
39
|
+
})
|
|
40
|
+
.join("");
|
|
41
|
+
const hole =
|
|
42
|
+
kind === "doughnut"
|
|
43
|
+
? `<circle cx="${cx}" cy="${cy}" r="${r * 0.55}" fill="#${t.bg}"/>`
|
|
44
|
+
: "";
|
|
45
|
+
const keys = c.labels
|
|
46
|
+
.map(
|
|
47
|
+
(label, i) =>
|
|
48
|
+
`<rect x="${cx + r + 40}" y="${cy - (c.labels.length * 30) / 2 + i * 30}" width="14" height="14" rx="3" fill="#${colors[i % colors.length]}"/><text x="${cx + r + 64}" y="${cy - (c.labels.length * 30) / 2 + i * 30 + 12}" font-size="16" fill="#${t.ink}" ${font}>${esc(label)} <tspan fill="#${t.soft}">${c.unit === "%" ? "" : `${fmt(values[i])} · `}${Math.round((values[i] / total) * 100)}%</tspan></text>`,
|
|
49
|
+
)
|
|
50
|
+
.join("");
|
|
51
|
+
return `<svg width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">${arcs}${hole}${keys}</svg>`;
|
|
52
|
+
}
|
|
53
|
+
const horizontal = kind === "bar" && c.horizontal;
|
|
54
|
+
const all = series.flatMap((one) => one.values);
|
|
55
|
+
const max = Math.max(0, ...all);
|
|
56
|
+
const min = Math.min(0, ...all);
|
|
57
|
+
const step = niceStep((max - min) / 5);
|
|
58
|
+
const top = Math.ceil(max / step) * step || step;
|
|
59
|
+
const bottom = Math.floor(min / step) * step;
|
|
60
|
+
const padL = horizontal ? 150 : 64;
|
|
61
|
+
const padB = legend ? 70 : 40;
|
|
62
|
+
const padT = 14;
|
|
63
|
+
const plotW = w - padL - 16;
|
|
64
|
+
const plotH = h - padB - padT;
|
|
65
|
+
const ticks = [];
|
|
66
|
+
for (let v = bottom; v <= top + step / 2; v += step) ticks.push(v);
|
|
67
|
+
const n = c.labels.length;
|
|
68
|
+
const out = [];
|
|
69
|
+
if (horizontal) {
|
|
70
|
+
const sx = (v) => padL + ((v - bottom) / (top - bottom)) * plotW;
|
|
71
|
+
for (const v of ticks)
|
|
72
|
+
out.push(
|
|
73
|
+
`<line x1="${sx(v)}" x2="${sx(v)}" y1="${padT}" y2="${padT + plotH}" stroke="#${t.rule}"/><text x="${sx(v)}" y="${padT + plotH + 22}" font-size="13" text-anchor="middle" fill="#${t.soft}" ${font}>${fmt(v)}</text>`,
|
|
74
|
+
);
|
|
75
|
+
const band = plotH / n;
|
|
76
|
+
const bh = (band * 0.7) / series.length;
|
|
77
|
+
c.labels.forEach((label, i) => {
|
|
78
|
+
out.push(
|
|
79
|
+
`<text x="${padL - 10}" y="${padT + band * i + band / 2 + 5}" font-size="14" text-anchor="end" fill="#${t.ink}" ${font}>${esc(label)}</text>`,
|
|
80
|
+
);
|
|
81
|
+
series.forEach((one, k) => {
|
|
82
|
+
const y = padT + band * i + band * 0.15 + bh * k;
|
|
83
|
+
out.push(
|
|
84
|
+
`<rect x="${sx(Math.min(0, one.values[i]))}" y="${y}" width="${Math.abs(sx(one.values[i]) - sx(0))}" height="${bh - 2}" fill="#${colors[k % colors.length]}"/>`,
|
|
85
|
+
);
|
|
86
|
+
if (c.values !== false && series.length === 1)
|
|
87
|
+
out.push(
|
|
88
|
+
`<text x="${sx(one.values[i]) + 6}" y="${y + bh / 2 + 4}" font-size="13" fill="#${t.ink}" ${font}>${fmt(one.values[i])}</text>`,
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
const sy = (v) => padT + plotH - ((v - bottom) / (top - bottom)) * plotH;
|
|
94
|
+
for (const v of ticks)
|
|
95
|
+
out.push(
|
|
96
|
+
`<line x1="${padL}" x2="${padL + plotW}" y1="${sy(v)}" y2="${sy(v)}" stroke="#${t.rule}"/><text x="${padL - 10}" y="${sy(v) + 4}" font-size="13" text-anchor="end" fill="#${t.soft}" ${font}>${fmt(v)}</text>`,
|
|
97
|
+
);
|
|
98
|
+
const band = plotW / n;
|
|
99
|
+
c.labels.forEach((label, i) => {
|
|
100
|
+
out.push(
|
|
101
|
+
`<text x="${padL + band * i + band / 2}" y="${padT + plotH + 22}" font-size="14" text-anchor="middle" fill="#${t.ink}" ${font}>${esc(label)}</text>`,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
if (kind === "line") {
|
|
105
|
+
series.forEach((one, k) => {
|
|
106
|
+
const pts = one.values.map(
|
|
107
|
+
(v, i) => `${padL + band * i + band / 2},${sy(v)}`,
|
|
108
|
+
);
|
|
109
|
+
out.push(
|
|
110
|
+
`<polyline points="${pts.join(" ")}" fill="none" stroke="#${colors[k % colors.length]}" stroke-width="3.5" stroke-linejoin="round"/>`,
|
|
111
|
+
);
|
|
112
|
+
one.values.forEach((v, i) =>
|
|
113
|
+
out.push(
|
|
114
|
+
`<circle cx="${padL + band * i + band / 2}" cy="${sy(v)}" r="4.5" fill="#${colors[k % colors.length]}"/>`,
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
const bw = (band * 0.66) / series.length;
|
|
120
|
+
c.labels.forEach((_, i) => {
|
|
121
|
+
series.forEach((one, k) => {
|
|
122
|
+
const x = padL + band * i + band * 0.17 + bw * k;
|
|
123
|
+
const v = one.values[i];
|
|
124
|
+
out.push(
|
|
125
|
+
`<rect x="${x}" y="${Math.min(sy(v), sy(0))}" width="${bw - 3}" height="${Math.abs(sy(v) - sy(0))}" fill="#${colors[k % colors.length]}"/>`,
|
|
126
|
+
);
|
|
127
|
+
if (c.values !== false && series.length === 1)
|
|
128
|
+
out.push(
|
|
129
|
+
`<text x="${x + (bw - 3) / 2}" y="${sy(v) - 8}" font-size="13" text-anchor="middle" fill="#${t.ink}" ${font}>${fmt(v)}</text>`,
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (legend)
|
|
136
|
+
series.forEach((one, k) => {
|
|
137
|
+
const x = padL + k * 180;
|
|
138
|
+
out.push(
|
|
139
|
+
`<rect x="${x}" y="${h - 24}" width="14" height="14" rx="3" fill="#${colors[k % colors.length]}"/><text x="${x + 22}" y="${h - 12}" font-size="14" fill="#${t.ink}" ${font}>${esc(one.name)}</text>`,
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
return `<svg width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">${out.join("")}</svg>`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function niceStep(raw) {
|
|
146
|
+
if (!(raw > 0)) return 1;
|
|
147
|
+
const mag = 10 ** Math.floor(Math.log10(raw));
|
|
148
|
+
const f = raw / mag;
|
|
149
|
+
return (f <= 1 ? 1 : f <= 2 ? 2 : f <= 2.5 ? 2.5 : f <= 5 ? 5 : 10) * mag;
|
|
150
|
+
}
|