dsh-mobile-plugin 0.5.28 → 0.5.29

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 (350) hide show
  1. package/extensions/catalog.json +10 -1
  2. package/extensions/magpie/agentcompact.js +104 -0
  3. package/extensions/magpie/app.css +4902 -0
  4. package/extensions/magpie/app.js +24474 -0
  5. package/extensions/magpie/autobackup.js +185 -0
  6. package/extensions/magpie/autoresetown.js +151 -0
  7. package/extensions/magpie/balfound.js +38 -0
  8. package/extensions/magpie/boot.js +23 -0
  9. package/extensions/magpie/cfgblocked.js +39 -0
  10. package/extensions/magpie/checkinnow.js +111 -0
  11. package/extensions/magpie/claudemode.js +92 -0
  12. package/extensions/magpie/compat.js +41 -0
  13. package/extensions/magpie/context.css +433 -0
  14. package/extensions/magpie/context.js +1576 -0
  15. package/extensions/magpie/ctxtext.js +223 -0
  16. package/extensions/magpie/fonts.js +42 -0
  17. package/extensions/magpie/i18n.js +18942 -0
  18. package/extensions/magpie/icons/ai21.svg +1 -0
  19. package/extensions/magpie/icons/ai302-color.svg +1 -0
  20. package/extensions/magpie/icons/ai360-color.svg +1 -0
  21. package/extensions/magpie/icons/aihubmix-color.svg +1 -0
  22. package/extensions/magpie/icons/aionui.svg +1 -0
  23. package/extensions/magpie/icons/air.svg +4 -0
  24. package/extensions/magpie/icons/alibaba-color.svg +1 -0
  25. package/extensions/magpie/icons/alibabacloud-color.svg +1 -0
  26. package/extensions/magpie/icons/alma.png +0 -0
  27. package/extensions/magpie/icons/anthropic.svg +1 -0
  28. package/extensions/magpie/icons/antigravity-color.svg +1 -0
  29. package/extensions/magpie/icons/anyscale-color.svg +1 -0
  30. package/extensions/magpie/icons/app-alma.png +0 -0
  31. package/extensions/magpie/icons/app-cc-switch.png +0 -0
  32. package/extensions/magpie/icons/apple-touch-icon.png +0 -0
  33. package/extensions/magpie/icons/aside.svg +28 -0
  34. package/extensions/magpie/icons/astrbot.svg +1 -0
  35. package/extensions/magpie/icons/atomcode.png +0 -0
  36. package/extensions/magpie/icons/aws.svg +1 -0
  37. package/extensions/magpie/icons/azure-color.svg +1 -0
  38. package/extensions/magpie/icons/azureai-color.svg +1 -0
  39. package/extensions/magpie/icons/baichuan-color.svg +1 -0
  40. package/extensions/magpie/icons/baidu-color.svg +1 -0
  41. package/extensions/magpie/icons/baiducloud-color.svg +1 -0
  42. package/extensions/magpie/icons/bailian-color.svg +1 -0
  43. package/extensions/magpie/icons/baseten.svg +1 -0
  44. package/extensions/magpie/icons/bedrock-color.svg +1 -0
  45. package/extensions/magpie/icons/burncloud-color.svg +1 -0
  46. package/extensions/magpie/icons/bytedance-color.svg +1 -0
  47. package/extensions/magpie/icons/cerebras.svg +1 -0
  48. package/extensions/magpie/icons/chatglm-color.svg +1 -0
  49. package/extensions/magpie/icons/cherryin-color.svg +1 -0
  50. package/extensions/magpie/icons/chutes.svg +1 -0
  51. package/extensions/magpie/icons/cindy.png +0 -0
  52. package/extensions/magpie/icons/claude-color.svg +1 -0
  53. package/extensions/magpie/icons/claudecode-color.svg +1 -0
  54. package/extensions/magpie/icons/cline.svg +1 -0
  55. package/extensions/magpie/icons/cloudflare-color.svg +1 -0
  56. package/extensions/magpie/icons/codebuddy-color.svg +1 -0
  57. package/extensions/magpie/icons/codex-color.svg +1 -0
  58. package/extensions/magpie/icons/cohere-color.svg +1 -0
  59. package/extensions/magpie/icons/cometapi-color.svg +1 -0
  60. package/extensions/magpie/icons/commandcode.svg +1 -0
  61. package/extensions/magpie/icons/copilot-color.svg +1 -0
  62. package/extensions/magpie/icons/coze.svg +1 -0
  63. package/extensions/magpie/icons/crush.png +0 -0
  64. package/extensions/magpie/icons/curl.svg +1 -0
  65. package/extensions/magpie/icons/cursor.svg +1 -0
  66. package/extensions/magpie/icons/deepinfra-color.svg +1 -0
  67. package/extensions/magpie/icons/deepmind-color.svg +1 -0
  68. package/extensions/magpie/icons/deepseek-color.svg +1 -0
  69. package/extensions/magpie/icons/deveco-color.svg +12 -0
  70. package/extensions/magpie/icons/devin.svg +1 -0
  71. package/extensions/magpie/icons/doubao-color.svg +1 -0
  72. package/extensions/magpie/icons/empryo-color.svg +1 -0
  73. package/extensions/magpie/icons/factory.svg +1 -0
  74. package/extensions/magpie/icons/favicon.svg +1 -0
  75. package/extensions/magpie/icons/featherless-color.svg +1 -0
  76. package/extensions/magpie/icons/fireworks-color.svg +1 -0
  77. package/extensions/magpie/icons/friendli.svg +1 -0
  78. package/extensions/magpie/icons/fx.svg +1 -0
  79. package/extensions/magpie/icons/gemini-color.svg +1 -0
  80. package/extensions/magpie/icons/geminicli-color.svg +1 -0
  81. package/extensions/magpie/icons/gemma-color.svg +1 -0
  82. package/extensions/magpie/icons/giteeai.svg +1 -0
  83. package/extensions/magpie/icons/github.svg +1 -0
  84. package/extensions/magpie/icons/githubcopilot.svg +1 -0
  85. package/extensions/magpie/icons/glama.svg +1 -0
  86. package/extensions/magpie/icons/gmicloud.svg +1 -0
  87. package/extensions/magpie/icons/google-color.svg +1 -0
  88. package/extensions/magpie/icons/googlecloud-color.svg +1 -0
  89. package/extensions/magpie/icons/goose.svg +1 -0
  90. package/extensions/magpie/icons/grok.svg +1 -0
  91. package/extensions/magpie/icons/groq.svg +1 -0
  92. package/extensions/magpie/icons/hanako.png +0 -0
  93. package/extensions/magpie/icons/hermes.svg +1 -0
  94. package/extensions/magpie/icons/huawei-color.svg +1 -0
  95. package/extensions/magpie/icons/huaweicloud-color.svg +1 -0
  96. package/extensions/magpie/icons/huggingface-color.svg +1 -0
  97. package/extensions/magpie/icons/hunyuan-color.svg +1 -0
  98. package/extensions/magpie/icons/hyperbolic-color.svg +1 -0
  99. package/extensions/magpie/icons/icon-512.png +0 -0
  100. package/extensions/magpie/icons/iflytekcloud-color.svg +1 -0
  101. package/extensions/magpie/icons/inference.svg +1 -0
  102. package/extensions/magpie/icons/infinigence-color.svg +1 -0
  103. package/extensions/magpie/icons/internlm-color.svg +1 -0
  104. package/extensions/magpie/icons/jcode.svg +1 -0
  105. package/extensions/magpie/icons/jina.svg +1 -0
  106. package/extensions/magpie/icons/kilo.svg +1 -0
  107. package/extensions/magpie/icons/kilocode.svg +1 -0
  108. package/extensions/magpie/icons/kimi-code-desktop.png +0 -0
  109. package/extensions/magpie/icons/kimi.svg +1 -0
  110. package/extensions/magpie/icons/kiro-color.svg +1 -0
  111. package/extensions/magpie/icons/kling-color.svg +1 -0
  112. package/extensions/magpie/icons/lambda.svg +1 -0
  113. package/extensions/magpie/icons/leptonai-color.svg +1 -0
  114. package/extensions/magpie/icons/liquid.svg +1 -0
  115. package/extensions/magpie/icons/liveagent-color.svg +1 -0
  116. package/extensions/magpie/icons/llmapi.svg +1 -0
  117. package/extensions/magpie/icons/lmstudio.svg +1 -0
  118. package/extensions/magpie/icons/lody.png +0 -0
  119. package/extensions/magpie/icons/longcat.svg +1 -0
  120. package/extensions/magpie/icons/magpie.svg +1 -0
  121. package/extensions/magpie/icons/meta-color.svg +1 -0
  122. package/extensions/magpie/icons/metaai-color.svg +1 -0
  123. package/extensions/magpie/icons/microsoft-color.svg +1 -0
  124. package/extensions/magpie/icons/mimocode.svg +1 -0
  125. package/extensions/magpie/icons/minimax-color.svg +1 -0
  126. package/extensions/magpie/icons/mistermorph-color.svg +1 -0
  127. package/extensions/magpie/icons/mistral-color.svg +1 -0
  128. package/extensions/magpie/icons/mlx-serve.png +0 -0
  129. package/extensions/magpie/icons/modelscope-color.svg +1 -0
  130. package/extensions/magpie/icons/monica-color.svg +1 -0
  131. package/extensions/magpie/icons/moonshot.svg +1 -0
  132. package/extensions/magpie/icons/morph-color.svg +1 -0
  133. package/extensions/magpie/icons/mothx.png +0 -0
  134. package/extensions/magpie/icons/nebius.svg +1 -0
  135. package/extensions/magpie/icons/newapi-color.svg +1 -0
  136. package/extensions/magpie/icons/nousresearch.svg +1 -0
  137. package/extensions/magpie/icons/nova-color.svg +1 -0
  138. package/extensions/magpie/icons/novita-color.svg +1 -0
  139. package/extensions/magpie/icons/nvidia-color.svg +1 -0
  140. package/extensions/magpie/icons/ollama.svg +1 -0
  141. package/extensions/magpie/icons/omlx.svg +1 -0
  142. package/extensions/magpie/icons/omo.svg +1 -0
  143. package/extensions/magpie/icons/omp.svg +1 -0
  144. package/extensions/magpie/icons/openai.svg +1 -0
  145. package/extensions/magpie/icons/openchamber.svg +11 -0
  146. package/extensions/magpie/icons/openclaw.svg +1 -0
  147. package/extensions/magpie/icons/opencode.svg +1 -0
  148. package/extensions/magpie/icons/openmausbot.svg +1 -0
  149. package/extensions/magpie/icons/openrouter.svg +1 -0
  150. package/extensions/magpie/icons/openwebui.svg +1 -0
  151. package/extensions/magpie/icons/parasail.svg +1 -0
  152. package/extensions/magpie/icons/penguin-color.svg +1 -0
  153. package/extensions/magpie/icons/perplexity-color.svg +1 -0
  154. package/extensions/magpie/icons/phala-color.svg +1 -0
  155. package/extensions/magpie/icons/pi.svg +1 -0
  156. package/extensions/magpie/icons/pipellm-color.svg +5 -0
  157. package/extensions/magpie/icons/poe.svg +1 -0
  158. package/extensions/magpie/icons/ppio-color.svg +1 -0
  159. package/extensions/magpie/icons/prime-agent.svg +1 -0
  160. package/extensions/magpie/icons/qiniu-color.svg +1 -0
  161. package/extensions/magpie/icons/qoder.svg +1 -0
  162. package/extensions/magpie/icons/qwen-color.svg +1 -0
  163. package/extensions/magpie/icons/qwenpaw.svg +1 -0
  164. package/extensions/magpie/icons/raycast.svg +1 -0
  165. package/extensions/magpie/icons/reasonix-color.svg +48 -0
  166. package/extensions/magpie/icons/reka.svg +1 -0
  167. package/extensions/magpie/icons/replicate.svg +1 -0
  168. package/extensions/magpie/icons/roocode.svg +1 -0
  169. package/extensions/magpie/icons/rtk.png +0 -0
  170. package/extensions/magpie/icons/sambanova-color.svg +1 -0
  171. package/extensions/magpie/icons/sensenova-color.svg +1 -0
  172. package/extensions/magpie/icons/siliconcloud-color.svg +1 -0
  173. package/extensions/magpie/icons/snow.png +0 -0
  174. package/extensions/magpie/icons/snowflake-color.svg +1 -0
  175. package/extensions/magpie/icons/sophnet-color.svg +1 -0
  176. package/extensions/magpie/icons/spark-color.svg +1 -0
  177. package/extensions/magpie/icons/stepfun-color.svg +1 -0
  178. package/extensions/magpie/icons/straico-color.svg +1 -0
  179. package/extensions/magpie/icons/submodel-color.svg +1 -0
  180. package/extensions/magpie/icons/t3code.svg +4 -0
  181. package/extensions/magpie/icons/targon-color.svg +1 -0
  182. package/extensions/magpie/icons/tencent-color.svg +1 -0
  183. package/extensions/magpie/icons/tencentcloud-color.svg +1 -0
  184. package/extensions/magpie/icons/tiangong-color.svg +1 -0
  185. package/extensions/magpie/icons/together-color.svg +1 -0
  186. package/extensions/magpie/icons/trae.svg +1 -0
  187. package/extensions/magpie/icons/typesafe.png +0 -0
  188. package/extensions/magpie/icons/upstage-color.svg +1 -0
  189. package/extensions/magpie/icons/venice-color.svg +1 -0
  190. package/extensions/magpie/icons/vercel.svg +1 -0
  191. package/extensions/magpie/icons/vertexai-color.svg +1 -0
  192. package/extensions/magpie/icons/vllm-color.svg +1 -0
  193. package/extensions/magpie/icons/volcengine-color.svg +1 -0
  194. package/extensions/magpie/icons/voyage-color.svg +1 -0
  195. package/extensions/magpie/icons/vscode.svg +1 -0
  196. package/extensions/magpie/icons/wenxin-color.svg +1 -0
  197. package/extensions/magpie/icons/windsurf.svg +1 -0
  198. package/extensions/magpie/icons/workbuddy-color.svg +1 -0
  199. package/extensions/magpie/icons/workersai-color.svg +1 -0
  200. package/extensions/magpie/icons/xai.svg +1 -0
  201. package/extensions/magpie/icons/xiaomimimo.svg +1 -0
  202. package/extensions/magpie/icons/xinference-color.svg +1 -0
  203. package/extensions/magpie/icons/yi.svg +1 -0
  204. package/extensions/magpie/icons/yuanbao-color.svg +1 -0
  205. package/extensions/magpie/icons/yylx.svg +5 -0
  206. package/extensions/magpie/icons/zai.svg +1 -0
  207. package/extensions/magpie/icons/zcode.png +0 -0
  208. package/extensions/magpie/icons/zed.svg +1 -0
  209. package/extensions/magpie/icons/zenmux.svg +1 -0
  210. package/extensions/magpie/icons/zeroone.svg +1 -0
  211. package/extensions/magpie/icons/zhipu-color.svg +1 -0
  212. package/extensions/magpie/icons/zoo-code.png +0 -0
  213. package/extensions/magpie/index.html +572 -0
  214. package/extensions/magpie/kernel.js +274 -0
  215. package/extensions/magpie/keyspend.js +63 -0
  216. package/extensions/magpie/layout.js +26 -0
  217. package/extensions/magpie/manifest.json +37 -0
  218. package/extensions/magpie/navlamp.js +47 -0
  219. package/extensions/magpie/omarchy.css +72 -0
  220. package/extensions/magpie/omarchy.js +46 -0
  221. package/extensions/magpie/passerrors.js +21 -0
  222. package/extensions/magpie/pluginpages.js +405 -0
  223. package/extensions/magpie/plugins/gateway/client.js +1194 -0
  224. package/extensions/magpie/plugins/gateway/keys.js +972 -0
  225. package/extensions/magpie/plugins/gateway/settings.js +459 -0
  226. package/extensions/magpie/plugins/library/client.js +6788 -0
  227. package/extensions/magpie/plugins/library/i18n.js +3228 -0
  228. package/extensions/magpie/plugins/library/library.css +848 -0
  229. package/extensions/magpie/plugins/otel/i18n.js +48 -0
  230. package/extensions/magpie/plugins/otel/page.js +189 -0
  231. package/extensions/magpie/plugins/redact/client.js +46 -0
  232. package/extensions/magpie/plugins/redact/demo.js +461 -0
  233. package/extensions/magpie/plugins/redact/i18n.js +432 -0
  234. package/extensions/magpie/plugins/redact/page.js +985 -0
  235. package/extensions/magpie/plugins/redact/redact.css +385 -0
  236. package/extensions/magpie/plugins/redact/settings.js +248 -0
  237. package/extensions/magpie/plugins/redact/xq_dark.jpg +0 -0
  238. package/extensions/magpie/plugins/redact/xq_dark.webm +0 -0
  239. package/extensions/magpie/plugins/redact/xq_light.jpg +0 -0
  240. package/extensions/magpie/plugins/redact/xq_light.webm +0 -0
  241. package/extensions/magpie/plugins/routing/client.js +8593 -0
  242. package/extensions/magpie/plugins/routing/i18n.js +2696 -0
  243. package/extensions/magpie/plugins/routing/routing.css +1111 -0
  244. package/extensions/magpie/plugins/search/settings.js +460 -0
  245. package/extensions/magpie/plugins/sessions/client.js +1622 -0
  246. package/extensions/magpie/plugins/sessions/i18n.js +360 -0
  247. package/extensions/magpie/plugins/sessions/sessions.css +181 -0
  248. package/extensions/magpie/plugins/sessions/settings.js +100 -0
  249. package/extensions/magpie/plugins/usage/client.js +150 -0
  250. package/extensions/magpie/plugins/usage/i18n.js +984 -0
  251. package/extensions/magpie/plugins/usage/page.js +4307 -0
  252. package/extensions/magpie/plugins.css +319 -0
  253. package/extensions/magpie/plugins.js +1926 -0
  254. package/extensions/magpie/profilerename.js +27 -0
  255. package/extensions/magpie/purposes.js +2 -0
  256. package/extensions/magpie/quitask.js +79 -0
  257. package/extensions/magpie/quotaall.js +142 -0
  258. package/extensions/magpie/ratewindows.js +123 -0
  259. package/extensions/magpie/registry.js +87 -0
  260. package/extensions/magpie/resetask.js +137 -0
  261. package/extensions/magpie/ruleedit.js +53 -0
  262. package/extensions/magpie/scrollends.js +91 -0
  263. package/extensions/magpie/settingshints.js +75 -0
  264. package/extensions/magpie/signsheets.js +86 -0
  265. package/extensions/magpie/start.js +26 -0
  266. package/extensions/magpie/syncfiles.js +216 -0
  267. package/extensions/magpie/theme.js +29 -0
  268. package/extensions/magpie/traywindows.js +41 -0
  269. package/extensions/magpie/webfonts.js +130 -0
  270. package/extensions/magpie/whatsnew.js +252 -0
  271. package/extensions/magpie.zip +0 -0
  272. package/knowledge/apps/baijiahao.md +30 -0
  273. package/knowledge/apps/bilibili.md +1 -0
  274. package/knowledge/apps/dedao.md +33 -0
  275. package/knowledge/apps/feishu.md +35 -0
  276. package/knowledge/apps/gmail.md +33 -0
  277. package/knowledge/apps/jike.md +31 -0
  278. package/knowledge/apps/kuaishou.md +34 -0
  279. package/knowledge/apps/linkedin.md +33 -0
  280. package/knowledge/apps/qqmail.md +30 -0
  281. package/knowledge/apps/telegram.md +27 -0
  282. package/knowledge/apps/toutiao.md +32 -0
  283. package/knowledge/apps/uber-eats.md +26 -0
  284. package/knowledge/apps/uber.md +27 -0
  285. package/knowledge/apps/whatsapp.md +27 -0
  286. package/knowledge/apps/x.md +32 -0
  287. package/knowledge/apps/xiaohongshu.md +1 -0
  288. package/knowledge/apps/zhihu.md +1 -0
  289. package/knowledge/sites/bilibili.com/SITE.md +50 -0
  290. package/knowledge/sites/bilibili.com/references/view-fields.md +17 -0
  291. package/knowledge/sites/github.com/SITE.md +51 -0
  292. package/knowledge/sites/github.com/references/repo-fields.md +13 -0
  293. package/knowledge/sites/x.com/SITE.md +47 -0
  294. package/knowledge/sites/xiaohongshu.com/SITE.md +48 -0
  295. package/knowledge/sites/xiaohongshu.com/references/note-fields.md +18 -0
  296. package/knowledge/sites/youtube.com/SITE.md +49 -0
  297. package/knowledge/sites/youtube.com/references/innertube-fields.md +14 -0
  298. package/knowledge/sites/zhihu.com/SITE.md +47 -0
  299. package/knowledge/sites/zhihu.com/references/api-fields.md +21 -0
  300. package/lib/mobile/extension-catalog.js +41 -1
  301. package/lib/mobile/extension-data.js +224 -0
  302. package/lib/mobile/extension-dev.js +3 -1
  303. package/lib/mobile/file-ops.js +252 -0
  304. package/lib/mobile/history-derive.js +80 -4
  305. package/lib/mobile/host-bridge/endpoints.js +48 -6
  306. package/lib/mobile/host-bridge/event-synthesis.js +33 -6
  307. package/lib/mobile/jobs-control.js +118 -0
  308. package/lib/mobile/memory.js +635 -0
  309. package/lib/mobile/model-badges.js +77 -0
  310. package/lib/mobile/pet-tools.js +50 -4
  311. package/lib/mobile/pets.js +214 -18
  312. package/lib/mobile/phone/access.js +85 -0
  313. package/lib/mobile/phone/evidence.js +228 -0
  314. package/lib/mobile/phone/gate.js +290 -0
  315. package/lib/mobile/phone/grounding.js +314 -0
  316. package/lib/mobile/phone/guard.js +465 -0
  317. package/lib/mobile/phone/irreversible.js +88 -8
  318. package/lib/mobile/phone/knowledge-tools.js +665 -0
  319. package/lib/mobile/phone/learn.js +329 -0
  320. package/lib/mobile/phone/redact.js +237 -0
  321. package/lib/mobile/phone/risk.js +95 -0
  322. package/lib/mobile/phone/routes.js +28 -1
  323. package/lib/mobile/phone/service.js +23 -0
  324. package/lib/mobile/phone/site-commands.js +271 -0
  325. package/lib/mobile/phone/step-summary.js +201 -0
  326. package/lib/mobile/phone/stop-summary.js +235 -0
  327. package/lib/mobile/phone/tool-groups.js +125 -0
  328. package/lib/mobile/phone/tools.js +589 -0
  329. package/lib/mobile/phone/untrusted.js +65 -0
  330. package/lib/mobile/phone-knowledge.js +20 -4
  331. package/lib/mobile/schedule-edit.js +500 -0
  332. package/lib/mobile/schedule.js +5 -0
  333. package/lib/mobile/send-continuation.js +52 -0
  334. package/lib/mobile/session-models.js +27 -31
  335. package/lib/mobile/session-send.js +12 -12
  336. package/lib/mobile/skill-import.js +338 -0
  337. package/lib/mobile/skill-store.js +524 -0
  338. package/lib/routes/mobile-api.js +42 -0
  339. package/package.json +7 -6
  340. package/skills/skill-authoring/SKILL.md +46 -0
  341. package/skills/skill-authoring/references/examples.md +82 -0
  342. package/skills/skill-authoring/references/frontmatter-and-fields.md +46 -0
  343. package/skills/skill-authoring/scripts/check_skill.py +167 -0
  344. package/skills/skill-authoring/scripts/manifest.json +3 -0
  345. package/knowledge/sites/bilibili.com.md +0 -27
  346. package/knowledge/sites/github.com.md +0 -27
  347. package/knowledge/sites/x.com.md +0 -28
  348. package/knowledge/sites/xiaohongshu.com.md +0 -27
  349. package/knowledge/sites/youtube.com.md +0 -28
  350. package/knowledge/sites/zhihu.com.md +0 -27
@@ -0,0 +1,223 @@
1
+ // The text of a part of the context window card (context.js): what the
2
+ // request sent there, opened from the card. context.js imports this when a
3
+ // part is first opened, so it weighs nothing on the core. A request whose
4
+ // body has left memory is read from the request archive, when it kept one,
5
+ // and the reply beside it (wangbinyq on Discord).
6
+ const TEXT_STEP = 20000, ITEM_STEP = 100;
7
+ const ROLE_NAMES = {
8
+ system: "System prompt", user: "You", assistant: "Assistant", thinking: "Thinking",
9
+ call: "Tool call", result: "Tool result", tool: "Tool definition", image: "Image", sealed: "Sealed",
10
+ };
11
+ // read: /api/context/<what>; a 404 is {archive: why}, why it is gone
12
+ async function read(what, q) {
13
+ // fetched, not api(): the text isn't looked through for accounts
14
+ const res = await fetch("/api/context/" + what + "?" + new URLSearchParams(q));
15
+ if (res.status === 404) return { gone: (await res.json().catch(() => ({}))).archive || "off" };
16
+ if (!res.ok) throw new Error((await res.text()).trim() || res.statusText);
17
+ return res.json();
18
+ }
19
+ const GONE = {
20
+ off: "This request's text is no longer kept: magpie keeps the text of the last {n} requests, in memory only, while it runs.",
21
+ missing: "Not in the request archive: it is saved just after the call, the oldest are removed past the archive's size, or the save failed (magpie's log says why)",
22
+ cut: "The request archive kept only the start of this request, so it can't be read",
23
+ unread: "The request archive's copy couldn't be read or masked, so none of it is shown",
24
+ };
25
+ const gone = (why, n) => el("p", "ctx-view-gone", t(GONE[why] || GONE.off, { n }));
26
+ // a stretch of text, and a button for the next
27
+ function longText(text) {
28
+ const box = el("div", "ctx-text-box");
29
+ const pre = el("pre", "ctx-text");
30
+ let at = 0;
31
+ const more = el("button", "text ctx-text-more");
32
+ more.type = "button";
33
+ const step = () => {
34
+ pre.append(document.createTextNode(text.slice(at, at + TEXT_STEP)));
35
+ at = Math.min(text.length, at + TEXT_STEP);
36
+ more.hidden = at >= text.length;
37
+ more.textContent = t("Show more · {n} characters left", { n: (text.length - at).toLocaleString(intlLang()) });
38
+ };
39
+ more.onclick = (e) => { e.stopPropagation(); step(); };
40
+ step();
41
+ box.append(pre, more);
42
+ return box;
43
+ }
44
+ // picture: an image the request carried, as it sent it (a data: URL
45
+ // the gateway checked is a PNG, JPEG, GIF or WebP). It fades in once
46
+ // decoded; clicked, it opens to its own size and back
47
+ function picture(src) {
48
+ const fig = el("button", "ctx-pic");
49
+ fig.type = "button";
50
+ fig.setAttribute("aria-expanded", "false");
51
+ const img = el("img");
52
+ img.alt = t("Image");
53
+ img.decoding = "async";
54
+ img.onload = () => fig.classList.add("in");
55
+ img.onerror = () => fig.replaceWith(el("div", "ctx-piece-note", t("An image: magpie doesn't show it here")));
56
+ img.src = src;
57
+ fig.append(img);
58
+ fig.onclick = (e) => {
59
+ e.stopPropagation();
60
+ const first = fig.getBoundingClientRect();
61
+ const open = fig.classList.toggle("open");
62
+ fig.setAttribute("aria-expanded", String(open));
63
+ if (calm() || !fig.animate) return;
64
+ const last = fig.getBoundingClientRect();
65
+ if (!first.width || !last.width) return;
66
+ fig.animate([{ transform: `scale(${first.width / last.width}, ${first.height / last.height})` }, { transform: "none" }],
67
+ { duration: 460, easing: IOS_EASE });
68
+ };
69
+ return fig;
70
+ }
71
+ function pieceView(pc) {
72
+ const box = el("div", "ctx-piece");
73
+ const head = el("div", "ctx-piece-head");
74
+ if (pc.role) head.append(el("span", "ctx-role r-" + pc.role, t(ROLE_NAMES[pc.role] || pc.role)));
75
+ if (pc.name) head.append(el("code", "ctx-piece-name", pc.name));
76
+ head.append(el("span", "grow"));
77
+ if (pc.text) head.append(copyBtn(pc.text, pc.name || t(ROLE_NAMES[pc.role] || "Text")));
78
+ box.append(head);
79
+ if (pc.role === "image" && pc.src) box.append(picture(pc.src));
80
+ else if (pc.role === "image") box.append(el("div", "ctx-piece-note", t("An image: magpie doesn't show it here")));
81
+ else if (pc.role === "sealed") box.append(el("div", "ctx-piece-note", t("Sealed by the vendor, {n} bytes: only the vendor can read it", { n: (pc.size || 0).toLocaleString(intlLang()) })));
82
+ else {
83
+ if (pc.size) box.append(el("div", "ctx-piece-note", t("Sealed by the vendor, {n} bytes: only the vendor can read it", { n: pc.size.toLocaleString(intlLang()) })));
84
+ if (pc.text) box.append(longText(pc.text));
85
+ else if (!pc.size) box.append(el("div", "ctx-piece-note", t("Empty")));
86
+ }
87
+ return box;
88
+ }
89
+ export async function open(kit, route, kind, pick) {
90
+ const { fmtK, partName, itemName, itemLabel, tagOf } = kit;
91
+ const id = route?.id;
92
+ if (!id) return;
93
+ // the day the history keeps it under, for one the gateway no longer holds
94
+ const day = String(route.time || "").slice(0, 10);
95
+ const readText = (kind, item) => read("text", { id, kind, day, ...(item === undefined ? {} : { item }) });
96
+ const ed = el("div", "editor ctx-view wide");
97
+ const head = el("div", "ehead");
98
+ const title = el("b", "", partName(kind));
99
+ const total = el("span", "ctx-view-total");
100
+ head.append(el("i", "dot k-" + kind), title, el("span", "grow"), total);
101
+ const body = el("div", "ctx-view-body");
102
+ body.append(el("div", "ctx-view-wait", t("Reading…")));
103
+ const bar = el("div", "bar");
104
+ const close = el("button", "text primary", t("Close"));
105
+ close.onclick = (e) => { e.stopPropagation(); closeConfirmAsk(); };
106
+ // the reply beside it: what the model answered, from memory or the archive
107
+ const reply = el("button", "text", t("Reply"));
108
+ reply.type = "button";
109
+ let view = null;
110
+ reply.onclick = async (e) => {
111
+ e.stopPropagation();
112
+ if (reply.classList.toggle("on")) {
113
+ reply.textContent = partName(kind);
114
+ title.textContent = t("Reply");
115
+ total.textContent = "";
116
+ body.replaceChildren(el("div", "ctx-view-wait", t("Reading…")));
117
+ let r;
118
+ try { r = await read("reply", { id, day }); } catch (err) { r = { err }; }
119
+ if (confirmAsk !== ed || !reply.classList.contains("on")) return;
120
+ if (r.err) return body.replaceChildren(el("p", "ctx-view-gone", r.err.message));
121
+ if (r.gone) return body.replaceChildren(gone(r.gone, 10));
122
+ const note = el("p", "ctx-view-note", t(r.from === "archive" ? "The reply as the agent got it, read from the request archive, masked where masking is on." : "The reply as the agent got it, masked where masking is on."));
123
+ body.replaceChildren(note, ...r.pieces.map(pieceView));
124
+ if (r.cut) body.append(el("p", "ctx-view-note", t("Only the start of the reply was kept")));
125
+ } else {
126
+ reply.textContent = t("Reply");
127
+ title.textContent = partName(kind);
128
+ if (view) view(); else body.replaceChildren(el("div", "ctx-view-wait", t("Reading…")));
129
+ }
130
+ };
131
+ bar.append(reply, el("span", "grow"), close);
132
+ ed.append(head, body, bar);
133
+ confirmAsk = ed;
134
+ openModal(ed);
135
+ $("#modal").classList.add("lib");
136
+ let list;
137
+ const failed = (err) => { view = () => body.replaceChildren(el("p", "ctx-view-gone", err.message)); };
138
+ try { list = await readText(kind); } catch (err) { failed(err); }
139
+ if (confirmAsk !== ed) return;
140
+ if (!list) return reply.classList.contains("on") || view();
141
+ if (list.gone) {
142
+ view = () => body.replaceChildren(gone(list.gone, 10));
143
+ return reply.classList.contains("on") || view();
144
+ }
145
+ const items = list.items || [];
146
+ const sum = () => fmtK(items.reduce((s, it) => s + it.tokens, 0)) + " " + t("tokens");
147
+ const note = el("p", "ctx-view-note", list.from === "archive"
148
+ ? t("As magpie sent it, read from the request archive, masked where masking is on.")
149
+ : t("As magpie sent it, masked where masking is on. Kept in memory for the last {n} requests only.", { n: list.kept }));
150
+ // an item: its text alone; "N more" or the earlier turns: the part's list
151
+ const at = pick && pick.tag !== "more" && pick.tag !== "turns"
152
+ ? items.findIndex((it) => it.name === pick.name && (it.tag || "") === (pick.tag || "")) : -1;
153
+ const entry = (it, i, open) => {
154
+ const box = el("div", "ctx-vi");
155
+ const h = el("button", "ctx-vi-head");
156
+ h.type = "button";
157
+ h.setAttribute("aria-expanded", "false");
158
+ const tg = tagOf(it);
159
+ h.append(el("span", "tw"), itemLabel(it, kind));
160
+ h.querySelector(".tw").append(svg(CHEV, 10, 1.7));
161
+ if (it.n > 1) h.append(el("span", "ctx-x", "×" + it.n));
162
+ if (tg) h.append(el("code", "ctx-tag", tg));
163
+ h.append(el("span", "ctx-v", fmtK(it.tokens)));
164
+ const text = el("div", "ctx-vi-text");
165
+ text.hidden = true;
166
+ let read = null;
167
+ const show = async () => {
168
+ const on = text.hidden;
169
+ text.hidden = !on;
170
+ h.setAttribute("aria-expanded", String(on));
171
+ box.classList.toggle("open", on);
172
+ if (!on || read) return;
173
+ text.replaceChildren(el("div", "ctx-view-wait", t("Reading…")));
174
+ read = readText(kind, i).then((one) => {
175
+ const pieces = one?.items?.[i]?.pieces;
176
+ if (!pieces) { read = null; text.replaceChildren(gone(one?.gone, list.kept)); return; }
177
+ text.replaceChildren(...(pieces.length ? pieces.map(pieceView) : [el("div", "ctx-piece-note", t("Empty"))]));
178
+ }).catch((err) => { read = null; text.replaceChildren(el("p", "ctx-view-gone", err.message)); });
179
+ };
180
+ h.onclick = (e) => { e.stopPropagation(); show(); };
181
+ box.append(h, text);
182
+ if (open) show();
183
+ return box;
184
+ };
185
+ const showAll = () => {
186
+ view = showAll;
187
+ title.textContent = partName(kind);
188
+ total.textContent = sum();
189
+ const rows = el("div", "ctx-vi-list");
190
+ let shown = 0;
191
+ const more = el("button", "text ctx-text-more");
192
+ more.type = "button";
193
+ const step = () => {
194
+ const next = items.slice(shown, shown + ITEM_STEP).map((it, j) => entry(it, shown + j, items.length === 1));
195
+ rows.append(...next);
196
+ shown += next.length;
197
+ more.hidden = shown >= items.length;
198
+ more.textContent = t("Show {n} more", { n: items.length - shown });
199
+ };
200
+ more.onclick = (e) => { e.stopPropagation(); step(); };
201
+ step();
202
+ body.replaceChildren(note, items.length ? rows : el("div", "ctx-empty", t("Nothing in it")), more);
203
+ };
204
+ if (at < 0) view = showAll;
205
+ else {
206
+ // the item alone, the part's other items a click away
207
+ const all = el("button", "text ctx-view-all", t("All of {part} · {n}", { part: partName(kind), n: items.length }));
208
+ all.type = "button";
209
+ all.onclick = (e) => {
210
+ e.stopPropagation();
211
+ all.remove();
212
+ if (reply.classList.contains("on")) reply.click();
213
+ showAll();
214
+ };
215
+ if (items.length > 1) bar.prepend(all);
216
+ view = () => {
217
+ title.textContent = partName(kind) + " · " + itemName(items[at]);
218
+ total.textContent = fmtK(items[at].tokens) + " " + t("tokens");
219
+ body.replaceChildren(note, entry(items[at], at, true));
220
+ };
221
+ }
222
+ if (!reply.classList.contains("on")) view();
223
+ }
@@ -0,0 +1,42 @@
1
+ // Installed font choices reach both webviews before their first paint.
2
+ // Keep --font and --code as the platform/theme fallbacks: an explicit
3
+ // choice is a separate variable, including on Omarchy's body. A browser
4
+ // tab's choice is its own (it may be on another computer), from the
5
+ // families it draws (webfonts.js).
6
+ window.desktopFonts = (() => {
7
+ let catalogue = null, held = null;
8
+ const web = window.bootPrefs?.web, KEY = "magpie.fonts";
9
+ const own = () => { try { return JSON.parse(localStorage[KEY]); } catch { return held; } };
10
+ function keep(key, v) {
11
+ held = { ...own(), [key]: v };
12
+ try { localStorage[KEY] = JSON.stringify(held); } catch {}
13
+ apply();
14
+ }
15
+ const same = (a, b) => !!a && !!b && ["family", "name", "weight", "style", "stretch"].every((k) => a[k] === b[k]);
16
+ const available = (face) => !face || catalogue === null || catalogue.some((f) => f.styles.some((s) => same(s, face)));
17
+ const quoted = (s) => '"' + s.replace(/[\\"\x00-\x1f\x7f]/g, (c) => "\\" + c.charCodeAt(0).toString(16) + " ") + '"';
18
+ function apply(s) {
19
+ const root = document.documentElement;
20
+ let active = false;
21
+ for (const [key, prefix, fallback] of [["uiFont", "ui", "font"], ["codeFont", "code", "code"]]) {
22
+ const f = (web ? own() : s)?.[key];
23
+ const valid = f && typeof f.family === "string" && f.family && ["normal", "italic", "oblique"].includes(f.style)
24
+ && Number.isFinite(f.weight) && f.weight >= 1 && f.weight <= 1000 && Number.isFinite(f.stretch) && f.stretch >= 0;
25
+ const values = valid && available(f) ? {
26
+ font: quoted(f.family) + ", var(--" + fallback + ")", weight: f.weight, style: f.style, stretch: f.stretch + "%",
27
+ } : {};
28
+ if (values.font) active = true;
29
+ for (const part of ["font", "weight", "style", "stretch"]) {
30
+ const name = "--" + prefix + "-" + part;
31
+ if (values[part] !== undefined) root.style.setProperty(name, values[part]);
32
+ else root.style.removeProperty(name);
33
+ }
34
+ }
35
+ if (active) root.setAttribute("data-fonts", "");
36
+ else root.removeAttribute("data-fonts");
37
+ // a wider font widens the tabs too: the header is fitted again (kiwiflysky on X)
38
+ window.fitTop?.();
39
+ }
40
+ return { apply, available, same, own, keep, quoted, catalogue: (list) => { catalogue = list; } };
41
+ })();
42
+ window.desktopFonts.apply(window.bootPrefs);