thursday-agent 0.16.0 → 0.17.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.
Files changed (277) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/prerender-manifest.json +3 -3
  4. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  5. package/.next/server/app/_global-error.html +1 -1
  6. package/.next/server/app/_global-error.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  11. package/.next/server/app/_not-found.html +1 -1
  12. package/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  15. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/api/artifact/route.js +9 -9
  17. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  18. package/.next/server/app/api/bot/memory/files/route.js +3 -3
  19. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
  20. package/.next/server/app/api/bot/memory/route.js +8 -8
  21. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
  22. package/.next/server/app/api/bot/route.js +8 -8
  23. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  24. package/.next/server/app/api/bot/thread/[id]/route.js +3 -3
  25. package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
  26. package/.next/server/app/api/bot/thread/route.js +3 -3
  27. package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
  28. package/.next/server/app/api/config/route.js.nft.json +1 -1
  29. package/.next/server/app/api/events/route.js.nft.json +1 -1
  30. package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
  31. package/.next/server/app/api/file/[...path]/route.js +4 -4
  32. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  33. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  34. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
  35. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  36. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
  37. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  38. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  39. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  40. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  41. package/.next/server/app/api/memory/edit/route.js +11 -11
  42. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
  43. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  44. package/.next/server/app/api/reach/route.js +11 -11
  45. package/.next/server/app/api/reach/route.js.nft.json +1 -1
  46. package/.next/server/app/api/routine/route.js +7 -7
  47. package/.next/server/app/api/routine/route.js.nft.json +1 -1
  48. package/.next/server/app/api/signins/route.js +5 -5
  49. package/.next/server/app/api/signins/route.js.nft.json +1 -1
  50. package/.next/server/app/api/skills/[source]/[name]/route.js +7 -7
  51. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  52. package/.next/server/app/api/skills/route.js +7 -7
  53. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  54. package/.next/server/app/api/thursday/call/route.js +5 -5
  55. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  56. package/.next/server/app/api/thursday/settings/route.js +5 -5
  57. package/.next/server/app/api/thursday/settings/route.js.nft.json +1 -1
  58. package/.next/server/app/api/thursday/text/route.js +13 -13
  59. package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
  60. package/.next/server/app/api/thursday/tool-call/route.js +12 -12
  61. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  62. package/.next/server/app/api/workspace/files/route.js +8 -8
  63. package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
  64. package/.next/server/app/api/workspace/route.js +9 -9
  65. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  66. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +3 -3
  67. package/.next/server/app/artifact/[...path]/page.js +4 -4
  68. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  69. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  70. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  71. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  72. package/.next/server/app/page/server-reference-manifest.json +60 -60
  73. package/.next/server/app/page.js +5 -5
  74. package/.next/server/app/page.js.nft.json +1 -1
  75. package/.next/server/app/page_client-reference-manifest.js +1 -1
  76. package/.next/server/chunks/[root-of-the-server]__00qyw01._.js +1 -1
  77. package/.next/server/chunks/[root-of-the-server]__01ypm_z._.js +3 -0
  78. package/.next/server/chunks/[root-of-the-server]__021dkui._.js +3 -0
  79. package/.next/server/chunks/{[root-of-the-server]__18e65_-._.js → [root-of-the-server]__03xamry._.js} +2 -2
  80. package/.next/server/chunks/[root-of-the-server]__05dp5tr._.js +1 -1
  81. package/.next/server/chunks/[root-of-the-server]__09gdscj._.js +7 -0
  82. package/.next/server/chunks/{[root-of-the-server]__10_7vqz._.js → [root-of-the-server]__0b36yfw._.js} +1 -1
  83. package/.next/server/chunks/{[root-of-the-server]__1gamvcz._.js → [root-of-the-server]__0jzwdg-._.js} +2 -2
  84. package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
  85. package/.next/server/chunks/[root-of-the-server]__0nmust6._.js +5 -0
  86. package/.next/server/chunks/[root-of-the-server]__0svzjwa._.js +7 -0
  87. package/.next/server/chunks/{[root-of-the-server]__16yw3mb._.js → [root-of-the-server]__12m24xl._.js} +1 -1
  88. package/.next/server/chunks/{[root-of-the-server]__1zrwxis._.js → [root-of-the-server]__12tahb4._.js} +1 -1
  89. package/.next/server/chunks/{[root-of-the-server]__1ep-pao._.js → [root-of-the-server]__1_h4hf9._.js} +4 -4
  90. package/.next/server/chunks/{[root-of-the-server]__1-tdj60._.js → [root-of-the-server]__1de1o6m._.js} +2 -2
  91. package/.next/server/chunks/{[root-of-the-server]__1voqqyc._.js → [root-of-the-server]__1ignh6-._.js} +1 -1
  92. package/.next/server/chunks/[root-of-the-server]__1t02-1p._.js +3 -0
  93. package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
  94. package/.next/server/chunks/{[root-of-the-server]__11g20j-._.js → [root-of-the-server]__1yl5l25._.js} +1 -1
  95. package/.next/server/chunks/{[root-of-the-server]__1mbd2w_._.js → [root-of-the-server]__208vmyf._.js} +1 -1
  96. package/.next/server/chunks/{_1mfu9a3._.js → _02lipqs._.js} +1 -1
  97. package/.next/server/chunks/_05sa7xl._.js +1 -1
  98. package/.next/server/chunks/{_1rg5bfd._.js → _074f2ts._.js} +1 -1
  99. package/.next/server/chunks/_07nxi75._.js +3 -3
  100. package/.next/server/chunks/_08btiir._.js +7 -0
  101. package/.next/server/chunks/_0caua_s._.js +1 -1
  102. package/.next/server/chunks/{_0qoush_._.js → _0gt6cbj._.js} +1 -1
  103. package/.next/server/chunks/_0xygcxs._.js +3 -3
  104. package/.next/server/chunks/{_09c4we8._.js → _17i1lt2._.js} +1 -1
  105. package/.next/server/chunks/_19kea1l._.js +9 -9
  106. package/.next/server/chunks/_1gn2r2q._.js +3 -3
  107. package/.next/server/chunks/{_03niwml._.js → _1ntwp1s._.js} +1 -1
  108. package/.next/server/chunks/_1q6e56i._.js +3 -3
  109. package/.next/server/chunks/{_02fn1o3._.js → _1tkzgtm._.js} +1 -1
  110. package/.next/server/chunks/_1wl2g8_._.js +2 -2
  111. package/.next/server/chunks/{_1w6uf9k._.js → _1y3mnz4._.js} +1 -1
  112. package/.next/server/chunks/features_workspace_workspace_ts_13h82gv._.js +4 -4
  113. package/.next/server/chunks/features_workspace_workspace_ts_1iyjroj._.js +4 -4
  114. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0cux6zt._.js → node_modules_consola_dist_chunks_prompt_mjs_04oxl25._.js} +1 -1
  115. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0w32bqh._.js → node_modules_consola_dist_chunks_prompt_mjs_0g87zst._.js} +1 -1
  116. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_1clmnaj._.js → node_modules_consola_dist_chunks_prompt_mjs_1341cnf._.js} +1 -1
  117. package/.next/server/chunks/ssr/{[root-of-the-server]__02jdtqa._.js → [root-of-the-server]__07660xu._.js} +2 -2
  118. package/.next/server/chunks/ssr/{[root-of-the-server]__0rnjkw2._.js → [root-of-the-server]__149x25m._.js} +2 -2
  119. package/.next/server/chunks/ssr/[root-of-the-server]__17h1ggo._.js +1 -1
  120. package/.next/server/chunks/ssr/[root-of-the-server]__19s8qyj._.js +3 -0
  121. package/.next/server/chunks/ssr/[root-of-the-server]__1jyeu61._.js +1 -1
  122. package/.next/server/chunks/ssr/_088vzgn._.js +3 -0
  123. package/.next/server/chunks/ssr/{_0wupyvd._.js → _0_vnw9v._.js} +2 -2
  124. package/.next/server/chunks/ssr/{_1u5vsy-._.js → _0aeknva._.js} +2 -2
  125. package/.next/server/chunks/ssr/_0fo4552._.js +3 -3
  126. package/.next/server/chunks/ssr/{_0-ou1b0._.js → _0n2scfq._.js} +2 -2
  127. package/.next/server/chunks/ssr/_0o_o9ji._.js +3 -0
  128. package/.next/server/chunks/ssr/_0qne8xs._.js +3 -0
  129. package/.next/server/chunks/ssr/_0r0g9ki._.js +1 -1
  130. package/.next/server/chunks/ssr/_0v9r8g2._.js +3 -0
  131. package/.next/server/chunks/ssr/_0x8ophf._.js +1 -1
  132. package/.next/server/chunks/ssr/{_0ncuqct._.js → _0ztbn5q._.js} +2 -2
  133. package/.next/server/chunks/ssr/{_0w8r7o7._.js → _1-41lck._.js} +2 -2
  134. package/.next/server/chunks/ssr/{_10fwcz_._.js → _14dfh7a._.js} +2 -2
  135. package/.next/server/chunks/ssr/{_1f6s34p._.js → _15m5ctz._.js} +2 -2
  136. package/.next/server/chunks/ssr/{_11pnnvd._.js → _18-e7zi._.js} +2 -2
  137. package/.next/server/chunks/ssr/{_0y28gl3._.js → _1c5iqz1._.js} +3 -3
  138. package/.next/server/chunks/ssr/{_1dqaksc._.js → _1hbjh6n._.js} +2 -2
  139. package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
  140. package/.next/server/chunks/ssr/{_1k0efi3._.js → _1sttj8x._.js} +2 -2
  141. package/.next/server/chunks/ssr/_1uij_rj._.js +1 -1
  142. package/.next/server/chunks/ssr/_1umbr78._.js +1 -1
  143. package/.next/server/chunks/ssr/{_17ble8k._.js → _1vtgiou._.js} +3 -3
  144. package/.next/server/chunks/ssr/_1w9w1ok._.js +1 -1
  145. package/.next/server/chunks/ssr/{_1z586yw._.js → _1z6pirx._.js} +2 -2
  146. package/.next/server/chunks/ssr/features_0796o8r._.js +1 -1
  147. package/.next/server/chunks/ssr/features_bot_1knyan7._.js +3 -0
  148. package/.next/server/chunks/ssr/features_bot_1kr0_m-._.js +3 -0
  149. package/.next/server/chunks/ssr/{features_config_11dpa7r._.js → features_config_0n0zu89._.js} +3 -3
  150. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  151. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
  152. package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
  153. package/.next/server/chunks/ssr/features_workspace_workspace_ts_1wc7_u_._.js +4 -4
  154. package/.next/server/chunks/ssr/{node_modules_1r5o-bo._.js → node_modules_00h1t1j._.js} +1 -1
  155. package/.next/server/chunks/ssr/{node_modules_1o9n7_n._.js → node_modules_02ficyi._.js} +1 -1
  156. package/.next/server/chunks/ssr/{node_modules_0u24mg0._.js → node_modules_03q71_j._.js} +1 -1
  157. package/.next/server/chunks/ssr/{node_modules_138kcrz._.js → node_modules_03uejh6._.js} +1 -1
  158. package/.next/server/chunks/ssr/{node_modules_0x_2io2._.js → node_modules_06grs09._.js} +1 -1
  159. package/.next/server/chunks/ssr/{node_modules_0n1js5k._.js → node_modules_07mo9rn._.js} +1 -1
  160. package/.next/server/chunks/ssr/{node_modules_0bas34k._.js → node_modules_09e8kz_._.js} +1 -1
  161. package/.next/server/chunks/ssr/{node_modules_1dzye0n._.js → node_modules_09ikzel._.js} +1 -1
  162. package/.next/server/chunks/ssr/{node_modules_18yn_bs._.js → node_modules_0_d_7gq._.js} +1 -1
  163. package/.next/server/chunks/ssr/{node_modules_0ka8te1._.js → node_modules_0_p8w7p._.js} +1 -1
  164. package/.next/server/chunks/ssr/{node_modules_0mark4f._.js → node_modules_0f5bmkb._.js} +1 -1
  165. package/.next/server/chunks/ssr/{node_modules_0sdjzae._.js → node_modules_0kwie-o._.js} +1 -1
  166. package/.next/server/chunks/ssr/{node_modules_1ozyial._.js → node_modules_0r-9e4n._.js} +1 -1
  167. package/.next/server/chunks/ssr/{node_modules_156m1qh._.js → node_modules_0u_8z64._.js} +1 -1
  168. package/.next/server/chunks/ssr/{node_modules_0-ew8f8._.js → node_modules_0zf3wuu._.js} +1 -1
  169. package/.next/server/chunks/ssr/{node_modules_1xua-g1._.js → node_modules_1-7fc7h._.js} +1 -1
  170. package/.next/server/chunks/ssr/{node_modules_0ld7p-1._.js → node_modules_142z3o5._.js} +1 -1
  171. package/.next/server/chunks/ssr/{node_modules_0-8r9yw._.js → node_modules_180l3i0._.js} +1 -1
  172. package/.next/server/chunks/ssr/{node_modules_1tj7_9z._.js → node_modules_197vh1s._.js} +1 -1
  173. package/.next/server/chunks/ssr/{node_modules_0y5uubt._.js → node_modules_1_n9o9s._.js} +1 -1
  174. package/.next/server/chunks/ssr/{node_modules_0etz1i0._.js → node_modules_1fw32pg._.js} +1 -1
  175. package/.next/server/chunks/ssr/{node_modules_0bbwe-u._.js → node_modules_1hefp6h._.js} +1 -1
  176. package/.next/server/chunks/ssr/{node_modules_097cl9f._.js → node_modules_1irot3r._.js} +1 -1
  177. package/.next/server/chunks/ssr/{node_modules_0uibk9z._.js → node_modules_1om2itc._.js} +1 -1
  178. package/.next/server/chunks/ssr/{node_modules_1zkzksd._.js → node_modules_1ubln7w._.js} +1 -1
  179. package/.next/server/chunks/ssr/{node_modules_02uwbwp._.js → node_modules_1wyhtw9._.js} +1 -1
  180. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_133hjui._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0aczkbn._.js} +1 -1
  181. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b3vwd3._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0ah684s._.js} +1 -1
  182. package/.next/server/middleware-build-manifest.js +3 -3
  183. package/.next/server/pages/404.html +1 -1
  184. package/.next/server/pages/500.html +1 -1
  185. package/.next/server/server-reference-manifest.js +1 -1
  186. package/.next/server/server-reference-manifest.json +61 -61
  187. package/.next/static/chunks/{1ub9obhgfm4jl.js → 024plctckvq-1.js} +1 -1
  188. package/.next/static/chunks/04toe_3nqfjqt.js +1 -0
  189. package/.next/static/chunks/{0609ejkwuy4sf.js → 0_b_bi2pobasx.js} +2 -2
  190. package/.next/static/chunks/{3ro66d9dc70bc.js → 0dfvwgnyrp8qt.js} +1 -1
  191. package/.next/static/chunks/{314szf8yer-3n.js → 0f47nnshdlucs.js} +1 -1
  192. package/.next/static/chunks/0sowxe4nnl5qu.js +1 -0
  193. package/.next/static/chunks/{07vcuxousbmy1.js → 0sv142q1yrva2.js} +1 -1
  194. package/.next/static/chunks/{0q4ws7qd21chx.js → 0tp868040z9nn.js} +2 -2
  195. package/.next/static/chunks/{0unonxbajyknw.js → 1-63yde5eaz7i.js} +1 -1
  196. package/.next/static/chunks/14qitm0kwsb6g.js +15 -0
  197. package/.next/static/chunks/{2xjr5b-yk_h3o.js → 1bgvxd3xny53w.js} +1 -1
  198. package/.next/static/chunks/{245_cp14iz637.js → 1cyrrz4q871aj.js} +1 -1
  199. package/.next/static/chunks/1st3b0c9vhxg3.js +1 -0
  200. package/.next/static/chunks/{39miwvg4k-b2d.js → 1wbqaidq7vc3_.js} +1 -1
  201. package/.next/static/chunks/{0cl_fgkphk1oz.js → 28sxb_k460e9h.js} +1 -1
  202. package/.next/static/chunks/{3j-l8un0d77v7.js → 2v6e_9p95o2e3.js} +1 -1
  203. package/.next/static/chunks/{23tx-2paw9qa6.js → 3-qp777vtfglj.js} +1 -1
  204. package/.next/static/chunks/{2jbjyazqfqyoh.js → 33ekkscpcq-z1.js} +1 -1
  205. package/.next/static/chunks/388l-zszwa_jf.js +1 -0
  206. package/.next/static/chunks/{3vwjs5kq11417.js → 38edd4rpcbvzp.js} +1 -1
  207. package/.next/static/chunks/3bwrvpjk95_x4.js +1 -0
  208. package/.next/static/chunks/{42m371fn687r5.js → 3itdg6t243u6f.js} +1 -1
  209. package/.next/static/chunks/{2oa4gpkzjtpni.js → 44vre0f7xqsh-.js} +1 -1
  210. package/README.md +12 -12
  211. package/guide/bots.md +48 -8
  212. package/guide/calls.md +13 -12
  213. package/guide/setup.md +4 -2
  214. package/package.json +1 -1
  215. package/public/sounds/NOTICE +3 -0
  216. package/public/sounds/opening-land.ogg +0 -0
  217. package/public/sounds/opening-rise.ogg +0 -0
  218. package/public/sounds/opening-step-1.ogg +0 -0
  219. package/public/sounds/opening-step-2.ogg +0 -0
  220. package/public/sounds/opening-step-3.ogg +0 -0
  221. package/skills/README.md +3 -0
  222. package/skills/artifact/SKILL.md +6 -5
  223. package/skills/artifact/references/book.md +22 -8
  224. package/skills/artifact/references/deck.md +4 -2
  225. package/skills/artifact/references/document.md +9 -0
  226. package/skills/artifact/references/sheet.md +108 -0
  227. package/skills/artifact/runtime/book/book.css +75 -0
  228. package/skills/artifact/runtime/book/book.html +6 -3
  229. package/skills/artifact/runtime/book/book.js +21 -0
  230. package/skills/artifact/runtime/canvas/canvas.css +1 -1
  231. package/skills/artifact/runtime/canvas/canvas.js +11 -1
  232. package/skills/artifact/runtime/deck/deck.css +164 -1
  233. package/skills/artifact/runtime/deck/deck.js +76 -1
  234. package/skills/artifact/runtime/document/docx.js +631 -0
  235. package/skills/artifact/runtime/document/markdown.mjs +58 -2
  236. package/skills/artifact/runtime/document/quick.css +66 -0
  237. package/skills/artifact/runtime/document/quick.html +1 -0
  238. package/skills/artifact/runtime/document/quick.js +154 -0
  239. package/skills/artifact/runtime/document/word.mjs +65 -0
  240. package/skills/artifact/runtime/sheet/format.mjs +385 -0
  241. package/skills/artifact/runtime/sheet/formula.mjs +755 -0
  242. package/skills/artifact/runtime/sheet/sheet.css +499 -0
  243. package/skills/artifact/runtime/sheet/sheet.html +102 -0
  244. package/skills/artifact/runtime/sheet/sheet.js +1361 -0
  245. package/skills/artifact/runtime/sheet/xlsx.mjs +320 -0
  246. package/skills/artifact/runtime/shell/head.html +1 -1
  247. package/skills/artifact/runtime/shell/shell.css +3 -0
  248. package/skills/artifact/runtime/shell/wear.mjs +47 -1
  249. package/skills/artifact/runtime/vendor/fflate.LICENSE.md +23 -0
  250. package/skills/artifact/runtime/vendor/fflate.mjs +2710 -0
  251. package/skills/artifact/scripts/book.mjs +141 -5
  252. package/skills/artifact/scripts/chart.mjs +229 -11
  253. package/skills/artifact/scripts/document.mjs +29 -2
  254. package/skills/artifact/scripts/spreadsheet.mjs +1068 -0
  255. package/skills/data-report/SKILL.md +8 -1
  256. package/.next/server/chunks/[root-of-the-server]__0aijj66._.js +0 -3
  257. package/.next/server/chunks/[root-of-the-server]__0tvoct-._.js +0 -3
  258. package/.next/server/chunks/[root-of-the-server]__118qjk_._.js +0 -7
  259. package/.next/server/chunks/[root-of-the-server]__1b8tp42._.js +0 -5
  260. package/.next/server/chunks/[root-of-the-server]__1gzcbda._.js +0 -3
  261. package/.next/server/chunks/[root-of-the-server]__1qcn1ti._.js +0 -7
  262. package/.next/server/chunks/_0xx3ryc._.js +0 -7
  263. package/.next/server/chunks/ssr/[root-of-the-server]__1y5_1cv._.js +0 -3
  264. package/.next/server/chunks/ssr/_0l1-xc6._.js +0 -3
  265. package/.next/server/chunks/ssr/_1g48r6t._.js +0 -3
  266. package/.next/server/chunks/ssr/features_bot_1k25jdg._.js +0 -3
  267. package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +0 -3
  268. package/.next/server/chunks/ssr/lib_utils_ts_0_f1xvm._.js +0 -3
  269. package/.next/static/chunks/00d54fcfm-lko.js +0 -1
  270. package/.next/static/chunks/0gjlsu6vrfzod.js +0 -1
  271. package/.next/static/chunks/17yqt1p_svv13.js +0 -1
  272. package/.next/static/chunks/203pbwecfs3tm.js +0 -1
  273. package/.next/static/chunks/3ghvoe_mlljzs.js +0 -15
  274. package/.next/static/chunks/3gn7dubb4-pwy.js +0 -1
  275. /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_buildManifest.js +0 -0
  276. /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_clientMiddlewareManifest.js +0 -0
  277. /package/.next/static/{RtLRT9EEaGn-OqwpMFdYg → VtbCMn-0G969p8QJsWdGv}/_ssgManifest.js +0 -0
@@ -17,9 +17,12 @@
17
17
  // - [x] done / - [ ] next a checklist the reader can tick
18
18
  // ![What it shows](photo.jpg) alone in its paragraph: a picture with its caption
19
19
  // | Item | Value | a column aligned right (---:) is read as numbers
20
+ // a claim.[^1] a footnote, numbered as it is first cited, its line
21
+ // [^1]: Where it comes from anywhere, gathered at the end of the document
20
22
  //
21
23
  // HTML written inside the Markdown passes through untouched, for tabs, a chip, a figure a
22
24
  // chart is drawn into. Comments are dropped: the outlines' guidance never reaches the page.
25
+ import { markSvg } from "../shell/wear.mjs";
23
26
  import { Marked, Tokenizer } from "../vendor/marked.mjs";
24
27
 
25
28
  const escape = (text) =>
@@ -157,6 +160,52 @@ const markdown = new Marked({
157
160
  },
158
161
  });
159
162
 
163
+ /** A footnote's own line, `[^id]: what it says`, and a citation of one in the text. */
164
+ const NOTE_LINE = /^\[\^([^\]\s]+)\]:\s*(.+)$/;
165
+ const CITE = /\[\^([^\]\s]+)\](?!:)/g;
166
+ const FENCE = /^\s*(```|~~~)/;
167
+
168
+ /**
169
+ * `[^id]` citations and `[^id]: …` lines as the document's own footnotes (quick.css): each
170
+ * citation a numbered link, in the order first cited, and the notes gathered at the end.
171
+ * Code is left as written; a citation with no note, or a note never cited, stays as text.
172
+ */
173
+ function footnotes(text) {
174
+ const notes = new Map();
175
+ const kept = [];
176
+ let fenced = false;
177
+ for (const line of text.split("\n")) {
178
+ if (FENCE.test(line)) fenced = !fenced;
179
+ const note = fenced ? null : NOTE_LINE.exec(line);
180
+ if (note) notes.set(note[1], note[2]);
181
+ else kept.push(line);
182
+ }
183
+ if (!notes.size) return { text, notes: "" };
184
+ const order = [];
185
+ const anchor = (id) => `fn-${id.replace(/[^\p{L}\p{N}_-]/gu, "-")}`;
186
+ fenced = false;
187
+ const cited = kept.map((line) => {
188
+ if (FENCE.test(line)) fenced = !fenced;
189
+ if (fenced) return line;
190
+ return line.replace(CITE, (whole, id) => {
191
+ if (!notes.has(id)) return whole;
192
+ if (!order.includes(id)) order.push(id);
193
+ const n = order.indexOf(id) + 1;
194
+ return `<sup class="fn"><a href="#${anchor(id)}" id="${anchor(id)}-ref">${n}</a></sup>`;
195
+ });
196
+ });
197
+ const items = order.map(
198
+ (id) =>
199
+ `<li id="${anchor(id)}">${markdown.parseInline(notes.get(id))} <a class="fn-back" href="#${anchor(id)}-ref" aria-label="Back to the text">↩</a></li>`,
200
+ );
201
+ return {
202
+ text: cited.join("\n"),
203
+ notes: items.length
204
+ ? `\n<ol class="footnotes">\n${items.join("\n")}\n</ol>\n`
205
+ : "",
206
+ };
207
+ }
208
+
160
209
  /** The keys the line over and under the title is made of. */
161
210
  const KEY_LINE = /^(kicker|date|by|status|tone)\s*:\s*\S/i;
162
211
 
@@ -189,14 +238,21 @@ function frontMatter(text) {
189
238
  /** The document's body, as the page's put writes it, from a Markdown text. */
190
239
  export function documentBody(text) {
191
240
  const { meta, rest } = frontMatter(text.replace(/<!--[\s\S]*?-->/g, ""));
192
- let html = markdown.parse(rest);
241
+ const cited = footnotes(rest);
242
+ let html = markdown.parse(cited.text) + cited.notes;
193
243
 
194
244
  // `by` may name several, split by commas: who a memo is from and for, who attended
195
245
  const who = (meta.by ?? "")
196
246
  .split(",")
197
247
  .map((one) => one.trim())
198
248
  .filter(Boolean)
199
- .map((one) => `<span class="chip who">${escape(one)}</span>`);
249
+ .map((one) =>
250
+ // The bot writing now wears its own face, as the page's head does
251
+ one.toLowerCase() === process.env.THURSDAY_BOT?.trim().toLowerCase() &&
252
+ markSvg(14)
253
+ ? `<span class="chip who bot">${markSvg(14)}${escape(one)}</span>`
254
+ : `<span class="chip who">${escape(one)}</span>`,
255
+ );
200
256
  const tone = ["good", "warn", "bad"].includes(meta.tone)
201
257
  ? ` ${meta.tone}`
202
258
  : "";
@@ -296,6 +296,31 @@ body.pg-toc-shut .pg-toc {
296
296
  :where(.pg-paper) .chip.who::before {
297
297
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/svg%3E");
298
298
  }
299
+ :where(.pg-paper) .chip.who.bot::before {
300
+ display: none;
301
+ }
302
+ /* The bot that wrote it, by its face (shell/wear.mjs markSvg) */
303
+ :where(.pg-paper) .chip .sh-mark {
304
+ margin-right: 0.3rem;
305
+ vertical-align: -0.15em;
306
+ }
307
+ /* How long it takes to read, worked out as it opens (quick.js); never kept in the file */
308
+ :where(.pg-paper) .chip.read::before {
309
+ content: "";
310
+ display: inline-block;
311
+ width: 0.85em;
312
+ height: 0.85em;
313
+ margin-right: 0.3rem;
314
+ vertical-align: -0.1em;
315
+ background: currentColor;
316
+ opacity: 0.7;
317
+ mask:
318
+ center / contain no-repeat
319
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3 2'/%3E%3C/svg%3E");
320
+ }
321
+ :where(.pg-paper) .chip.read {
322
+ color: var(--muted);
323
+ }
299
324
  :where(.pg-paper) .chip.status::after {
300
325
  content: "";
301
326
  display: inline-block;
@@ -369,6 +394,47 @@ body.pg-toc-shut .pg-toc {
369
394
  :where(.pg-paper) sup {
370
395
  line-height: 0;
371
396
  }
397
+ :where(.pg-paper) sup.fn a {
398
+ padding: 0 0.15em;
399
+ font-weight: 600;
400
+ text-decoration: none;
401
+ }
402
+ :where(.pg-paper) .fn-back {
403
+ text-decoration: none;
404
+ }
405
+ /* A footnote read where it is cited: the note, shown beside the number (quick.js) */
406
+ #fn-card {
407
+ position: absolute;
408
+ z-index: 30;
409
+ max-width: 22rem;
410
+ padding: 0.7rem 0.9rem;
411
+ border: 1px solid var(--line);
412
+ border-radius: 12px;
413
+ background: var(--bg);
414
+ color: var(--fg);
415
+ box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
416
+ font-size: 0.85rem;
417
+ line-height: 1.6;
418
+ }
419
+ #fn-card .fn-back {
420
+ display: none;
421
+ }
422
+ /* A table's column put in order by a press on its heading, while reading (quick.js) */
423
+ body:not(.pg-editing) :where(.pg-paper) th[data-sort] {
424
+ cursor: pointer;
425
+ user-select: none;
426
+ }
427
+ body:not(.pg-editing) :where(.pg-paper) th[data-sort]:hover {
428
+ color: var(--fg);
429
+ }
430
+ :where(.pg-paper) th[aria-sort]::after {
431
+ content: "↑";
432
+ margin-left: 0.3rem;
433
+ color: var(--accent, currentColor);
434
+ }
435
+ :where(.pg-paper) th[aria-sort="descending"]::after {
436
+ content: "↓";
437
+ }
372
438
  :where(.pg-paper) ol.footnotes {
373
439
  margin-top: 2.4rem;
374
440
  padding: 1rem 0 0 1.3rem;
@@ -34,6 +34,7 @@
34
34
  <details class="sh-menu">
35
35
  {{shell.export}}
36
36
  <div class="sh-list">
37
+ <button type="button" class="sh-item" data-docx>Word file<small>.docx</small></button>
37
38
  <button type="button" class="sh-item" data-export="print">Print<small>PDF</small></button>
38
39
  {{shell.download}}
39
40
  </div>
@@ -160,6 +160,130 @@
160
160
  contents();
161
161
  spy();
162
162
 
163
+ /* ── reading: a column in order, a footnote in place, the time it takes ──── */
164
+
165
+ // Each table's rows in the order they were written: a sort is a view of the page, and
166
+ // the file keeps that order (shell.clean puts it back in the copy it keeps)
167
+ const written = new WeakMap();
168
+ const collator = new Intl.Collator(undefined, { numeric: true });
169
+ const numberIn = (text) => {
170
+ const n = Number.parseFloat(text.replace(/[^\d.-]/g, ""));
171
+ return Number.isFinite(n) ? n : null;
172
+ };
173
+ const tables = () =>
174
+ [...paper.querySelectorAll("table")].filter(
175
+ (table) => table.tHead?.rows[0] && table.tBodies[0]?.rows.length > 1,
176
+ );
177
+ for (const table of tables()) {
178
+ [...table.tBodies[0].rows].forEach((row, at) => {
179
+ written.set(row, at);
180
+ });
181
+ for (const th of table.tHead.rows[0].cells) {
182
+ th.dataset.sort = "";
183
+ th.tabIndex = 0;
184
+ }
185
+ }
186
+ /** Every table back in its written order, its headings unmarked. */
187
+ const unsort = () => {
188
+ for (const table of tables()) {
189
+ const rows = [...table.tBodies[0].rows];
190
+ rows.sort((a, b) => (written.get(a) ?? 0) - (written.get(b) ?? 0));
191
+ table.tBodies[0].append(...rows);
192
+ for (const th of table.tHead.rows[0].cells)
193
+ th.removeAttribute("aria-sort");
194
+ }
195
+ };
196
+ /** Up, down, then as written: one heading's column at a time. */
197
+ const sortBy = (th) => {
198
+ const table = th.closest("table");
199
+ const body = table.tBodies[0];
200
+ const at = th.cellIndex;
201
+ const was = th.getAttribute("aria-sort");
202
+ const next = was === "ascending" ? "descending" : was ? null : "ascending";
203
+ for (const one of table.tHead.rows[0].cells)
204
+ one.removeAttribute("aria-sort");
205
+ const rows = [...body.rows];
206
+ const key = (row) => row.cells[at]?.textContent.trim() ?? "";
207
+ const numeric =
208
+ th.classList.contains("num") ||
209
+ rows.every((row) => numberIn(key(row)) !== null);
210
+ if (next) {
211
+ th.setAttribute("aria-sort", next);
212
+ const sign = next === "ascending" ? 1 : -1;
213
+ rows.sort(
214
+ (a, b) =>
215
+ sign *
216
+ (numeric
217
+ ? numberIn(key(a)) - numberIn(key(b))
218
+ : collator.compare(key(a), key(b))),
219
+ );
220
+ } else rows.sort((a, b) => (written.get(a) ?? 0) - (written.get(b) ?? 0));
221
+ body.append(...rows);
222
+ };
223
+ const browsing = () => !document.body.classList.contains("pg-editing");
224
+ paper.addEventListener("click", (event) => {
225
+ const th = event.target.closest?.("th[data-sort]");
226
+ if (th && browsing()) sortBy(th);
227
+ });
228
+ paper.addEventListener("keydown", (event) => {
229
+ const th = event.target.closest?.("th[data-sort]");
230
+ if (!th || !browsing() || (event.key !== "Enter" && event.key !== " "))
231
+ return;
232
+ event.preventDefault();
233
+ sortBy(th);
234
+ });
235
+
236
+ // A footnote's note, beside the number that cites it, while the pointer or focus is there
237
+ let card = null;
238
+ const hideNote = () => card?.remove();
239
+ const showNote = (link) => {
240
+ const note = document.getElementById(
241
+ decodeURIComponent(link.hash.slice(1)),
242
+ );
243
+ if (!note) return;
244
+ card ??= Object.assign(document.createElement("div"), { id: "fn-card" });
245
+ card.setAttribute("role", "tooltip");
246
+ card.innerHTML = note.innerHTML;
247
+ document.body.append(card);
248
+ const box = link.getBoundingClientRect();
249
+ const left = Math.min(
250
+ box.left + scrollX,
251
+ scrollX + document.documentElement.clientWidth - card.offsetWidth - 12,
252
+ );
253
+ card.style.left = `${Math.max(scrollX + 12, left)}px`;
254
+ card.style.top = `${box.bottom + scrollY + 6}px`;
255
+ };
256
+ paper.addEventListener("mouseover", (event) => {
257
+ const link = event.target.closest?.("sup.fn a");
258
+ if (link && browsing()) showNote(link);
259
+ });
260
+ paper.addEventListener("mouseout", (event) => {
261
+ if (event.target.closest?.("sup.fn a")) hideNote();
262
+ });
263
+ paper.addEventListener("focusin", (event) => {
264
+ const link = event.target.closest?.("sup.fn a");
265
+ if (link && browsing()) showNote(link);
266
+ else hideNote();
267
+ });
268
+ addEventListener("scroll", hideNote, { passive: true });
269
+
270
+ // How long it reads, beside the other facts under the title, in the reader's language
271
+ const byline = paper.querySelector(".byline");
272
+ if (byline && typeof Intl.Segmenter === "function") {
273
+ let words = 0;
274
+ const segmenter = new Intl.Segmenter(undefined, { granularity: "word" });
275
+ for (const piece of segmenter.segment(paper.textContent))
276
+ if (piece.isWordLike) words++;
277
+ const minutes = Math.max(1, Math.round(words / 200));
278
+ const chip = document.createElement("span");
279
+ chip.className = "chip read";
280
+ chip.textContent = new Intl.NumberFormat(
281
+ document.documentElement.lang || undefined,
282
+ { style: "unit", unit: "minute", unitDisplay: "short" },
283
+ ).format(minutes);
284
+ byline.append(" ", chip);
285
+ }
286
+
163
287
  /* ── keeping it (shell.edits) ────────────────────────────────────────────── */
164
288
 
165
289
  const changed = () => shell.edits.changed();
@@ -203,6 +327,30 @@
203
327
  }
204
328
  for (const el of copy.querySelectorAll(".pg-hot"))
205
329
  el.classList.remove("pg-hot");
330
+ // What reading put on the page: a column's order, the time it takes, a note shown
331
+ const live = [...paper.querySelectorAll("table")];
332
+ copy.querySelectorAll("#paper table").forEach((table, at) => {
333
+ const body = table.tBodies[0];
334
+ const order = [...(live[at]?.tBodies[0]?.rows ?? [])].map((row) =>
335
+ written.get(row),
336
+ );
337
+ if (
338
+ body &&
339
+ order.length === body.rows.length &&
340
+ order.every((n) => n !== undefined)
341
+ ) {
342
+ const rows = [...body.rows];
343
+ body.append(
344
+ ...order.map((_, i) => rows[order.indexOf(i)]).filter(Boolean),
345
+ );
346
+ }
347
+ for (const th of table.querySelectorAll("th")) {
348
+ th.removeAttribute("aria-sort");
349
+ th.removeAttribute("data-sort");
350
+ th.removeAttribute("tabindex");
351
+ }
352
+ });
353
+ for (const el of copy.querySelectorAll(".chip.read, #fn-card")) el.remove();
206
354
  for (const tabs of copy.querySelectorAll(".tabs")) {
207
355
  tabs.querySelector('[role="tablist"]')?.remove();
208
356
  for (const panel of tabs.querySelectorAll("[role=tabpanel]")) {
@@ -264,6 +412,12 @@
264
412
  };
265
413
 
266
414
  shell.edits.onToggle((on) => {
415
+ // Edits are made on the page as written: no column in order, no reading time among the chips
416
+ if (on) {
417
+ unsort();
418
+ hideNote();
419
+ for (const chip of paper.querySelectorAll(".chip.read")) chip.remove();
420
+ }
267
421
  document.body.classList.toggle("pg-editing", on);
268
422
  paper.contentEditable = on ? "true" : "false";
269
423
  seal();
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * A document's page as a Word file: the page opened in a headless browser of its own and
4
+ * turned into a .docx there by the page's own converter (docx.js), as Export › Word file does
5
+ * for someone reading it — the kit's converter as it is now, over the copy the page was made
6
+ * with, so a page made before a fix to it gets the fix. Prints the file written, and the
7
+ * pictures that could not be put in.
8
+ *
9
+ * node word.mjs <page.html> --out <file.docx>
10
+ */
11
+ import { readFileSync, writeFileSync } from "node:fs";
12
+ import { basename, dirname, join, resolve } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ import { serveFolder } from "../../../browser/scripts/serve.mjs";
15
+ import {
16
+ fail,
17
+ inPageApart,
18
+ orFail,
19
+ parseArgs,
20
+ } from "../../../browser/scripts/session.mjs";
21
+
22
+ const opts = parseArgs();
23
+ const file = opts._[0] && resolve(opts._[0]);
24
+ if (!file || typeof opts.out !== "string")
25
+ fail("usage: node word.mjs <page.html> --out <file.docx>");
26
+ const converter = readFileSync(
27
+ join(dirname(fileURLToPath(import.meta.url)), "docx.js"),
28
+ "utf8",
29
+ );
30
+
31
+ // The page's folder, so pictures beside it load
32
+ const served = await serveFolder(dirname(file));
33
+ try {
34
+ const done = orFail(
35
+ await inPageApart(
36
+ async (page, { url, converter }) => {
37
+ const tab = await page.context().newPage();
38
+ try {
39
+ await tab.setViewportSize({ width: 1024, height: 1400 });
40
+ await tab.goto(url, { waitUntil: "load" });
41
+ await tab.evaluate(() => document.fonts.ready);
42
+ await tab.addScriptTag({ content: converter });
43
+ return await tab.evaluate(async () => {
44
+ if (!window.shell?.docx)
45
+ return { error: "this page is not a document: no #paper in it" };
46
+ const { bytes, missed } = await window.shell.docx();
47
+ let text = "";
48
+ for (let i = 0; i < bytes.length; i += 0x8000)
49
+ text += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
50
+ return { data: btoa(text), missed };
51
+ });
52
+ } finally {
53
+ await tab.close();
54
+ }
55
+ },
56
+ { url: served.url(basename(file)), converter },
57
+ ),
58
+ );
59
+ writeFileSync(opts.out, Buffer.from(done.data, "base64"));
60
+ console.log(
61
+ JSON.stringify({ file: resolve(opts.out), missed: done.missed ?? [] }),
62
+ );
63
+ } finally {
64
+ served.close();
65
+ }