openmausbot 0.1.85 → 0.1.87

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 (262) hide show
  1. package/README.md +2 -2
  2. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  3. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  4. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  5. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  6. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  7. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  8. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  9. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  10. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  11. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  12. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  13. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  14. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  15. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  16. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  17. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  18. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  19. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  20. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  21. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  22. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  23. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  24. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  25. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  26. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  27. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  28. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  29. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  30. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  31. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  32. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  33. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  34. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  35. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  36. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  37. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  38. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  39. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  40. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  41. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  42. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  43. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  44. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  45. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  46. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  47. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  48. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  49. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  50. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  51. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  52. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  53. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  54. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  55. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  56. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  57. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  58. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  59. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  60. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  61. package/dist/assets/abnfDiagram-O67JEVCF-BTiuL79F.js +1 -0
  62. package/dist/assets/arc-C88Blc2v.js +1 -0
  63. package/dist/assets/architectureDiagram-NJMV4G6O-BZsJIZrb.js +36 -0
  64. package/dist/assets/blockDiagram-BEXU5L5S-CVeMe9Ah.js +140 -0
  65. package/dist/assets/c4Diagram-YGBWAQC7-Cedk3Bhx.js +38 -0
  66. package/dist/assets/channel-taCNRlUU.js +1 -0
  67. package/dist/assets/chunk-2Q5K7J3B-D-VRqzTB.js +1 -0
  68. package/dist/assets/chunk-3FUC2YCW-BChov01Y.js +2 -0
  69. package/dist/assets/chunk-5VM5RSS4-C-TfwvHy.js +15 -0
  70. package/dist/assets/chunk-GTNCS2PH-Db7CGj5Y.js +88 -0
  71. package/dist/assets/chunk-GWA4HPMP-CNvIfqKT.js +1 -0
  72. package/dist/assets/chunk-JWPE2WC7-C_bEp5tq.js +1 -0
  73. package/dist/assets/chunk-NETBCI7D-Coi4BOls.js +1 -0
  74. package/dist/assets/chunk-WEXAMYUT-CzylEuL3.js +1 -0
  75. package/dist/assets/chunk-XXDRQBXY-m7p7ztaD.js +1 -0
  76. package/dist/assets/classDiagram-v2-NBCMYWYE-BMy6o9x2.js +217 -0
  77. package/dist/assets/cose-bilkent-JH36ORCC-BDQ__0_J.js +1 -0
  78. package/dist/assets/cynefin-OW5HDTMX-Djv4ghUb.js +166 -0
  79. package/dist/assets/cynefinDiagram-VND7K2PF-BULrlGYH.js +62 -0
  80. package/dist/assets/cytoscape.esm-BB4DxJjf.js +321 -0
  81. package/dist/assets/dagre-6A5THRUB-D-jrT_hU.js +4 -0
  82. package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  83. package/dist/assets/diagram-22UHCM2B-p2UhQmfL.js +200 -0
  84. package/dist/assets/diagram-3UASUU5V-DHvGWZ7q.js +24 -0
  85. package/dist/assets/diagram-ATOU4E4O-ChhKDot-.js +3 -0
  86. package/dist/assets/diagram-CDSNMT55-B-T7A43R.js +30 -0
  87. package/dist/assets/diagram-MLGK6HIB-CJm8ENNY.js +24 -0
  88. package/dist/assets/diagram-MPIPVDR6-510tlza8.js +41 -0
  89. package/dist/assets/ebnfDiagram-ZINNZB2B-PkvRPHel.js +1 -0
  90. package/dist/assets/elk-276RUBZZ-BVBVPoX3.js +27 -0
  91. package/dist/assets/erDiagram-OPXOYQCR-BgYMVm7L.js +99 -0
  92. package/dist/assets/flowDiagram-KWPJA3E3-BGqsnc_3.js +213 -0
  93. package/dist/assets/ganttDiagram-FUAMR5RP-D_-UeReH.js +292 -0
  94. package/dist/assets/gitGraphDiagram-X574FWY7-D0uooONx.js +106 -0
  95. package/dist/assets/graph-D8UmR1vK.js +1 -0
  96. package/dist/assets/index-BwdMAQ6p.css +1 -0
  97. package/dist/assets/index-ByJennr7.js +581 -0
  98. package/dist/assets/{index-CTNNoqSJ.js → index-zRsJERGJ.js} +1 -1
  99. package/dist/assets/infoDiagram-VRGFBTTK-B9e1z77f.js +2 -0
  100. package/dist/assets/init-Gi6I4Gst.js +1 -0
  101. package/dist/assets/ishikawaDiagram-OU5B5YK6-BB4vNwvD.js +70 -0
  102. package/dist/assets/journeyDiagram-ZHPQQLJL-DpkosOTB.js +139 -0
  103. package/dist/assets/kanban-definition-PNTS6WVX-DbDP4kUu.js +89 -0
  104. package/dist/assets/linear-DBJGPmjT.js +1 -0
  105. package/dist/assets/mermaid.core-DWPRi-ue.js +311 -0
  106. package/dist/assets/mindmap-definition-NLK3R4M7-nszBbJmx.js +96 -0
  107. package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  108. package/dist/assets/pegDiagram-GJSIUBJH-CWykJWu_.js +1 -0
  109. package/dist/assets/pieDiagram-5QR66LMP-g3Da-Vnv.js +39 -0
  110. package/dist/assets/quadrantDiagram-O4NWA36T-Wzrlpzgh.js +7 -0
  111. package/dist/assets/railroadDiagram-XR7U4H2S-moHTFMC0.js +1 -0
  112. package/dist/assets/requirementDiagram-PLB6GJNP-CwfXdFH8.js +84 -0
  113. package/dist/assets/sankeyDiagram-IPEJSGJF-3ZROYvnq.js +40 -0
  114. package/dist/assets/sequenceDiagram-PO4LG4MO-E1TBebP8.js +169 -0
  115. package/dist/assets/sizeCapture-INFHLROL-DHKEU5pu.js +1 -0
  116. package/dist/assets/stateDiagram-v2-GCMORJYK-BguEj09D.js +291 -0
  117. package/dist/assets/swimlanes-2SLR337P-C7IDYnhd.js +1 -0
  118. package/dist/assets/swimlanesDiagram-TC7HE7FX-BpEdoB2e.js +8 -0
  119. package/dist/assets/timeline-definition-EJHVYXUP-DCW-F5PW.js +120 -0
  120. package/dist/assets/usecaseDiagram-POWQR4AR-xBMFtWYV.js +370 -0
  121. package/dist/assets/vennDiagram-UO4OBE2U-B5nIkuH8.js +34 -0
  122. package/dist/assets/wardleyDiagram-VNRHLVJA-DYFAhdbr.js +78 -0
  123. package/dist/assets/xychartDiagram-PMCCYNJV-DeXwX6Cz.js +7 -0
  124. package/dist/index.html +2 -2
  125. package/dist-server/browser-proxy.js +2 -1
  126. package/dist-server/container-mcp.js +1047 -173
  127. package/dist-server/drivers/agents-proxy.js +16121 -1504
  128. package/dist-server/drivers/phone-proxy.js +33 -2
  129. package/dist-server/enterprise/LICENSE +32 -0
  130. package/dist-server/enterprise/server/index.js +5 -5
  131. package/dist-server/index.js +16134 -7446
  132. package/dist-server/local-computer-proxy.js +3 -3
  133. package/dist-server/local-computer.js +53 -17
  134. package/dist-server/mcp-server.js +3 -1
  135. package/dist-server/openmausbot.js +9353 -6124
  136. package/dist-server/pair-cli.js +9353 -6124
  137. package/dist-server/permission-proxy.js +29 -9
  138. package/dist-server/server/admin-activity.js +410 -0
  139. package/dist-server/server/attachments.js +55 -0
  140. package/dist-server/server/auto-approve.js +4 -3
  141. package/dist-server/server/auto-vm-claims.js +1 -0
  142. package/dist-server/server/bot-package.js +18 -292
  143. package/dist-server/server/bot-profile.js +5 -17
  144. package/dist-server/server/bot-visibility.js +462 -0
  145. package/dist-server/server/box-create-idempotency.js +3 -3
  146. package/dist-server/server/box.js +59 -56
  147. package/dist-server/server/browser-proxy.js +3 -2
  148. package/dist-server/server/browser-runtime.js +38 -2
  149. package/dist-server/server/channel-queue.js +2 -0
  150. package/dist-server/server/cli-prompts.js +24 -2
  151. package/dist-server/server/cli.js +81 -12
  152. package/dist-server/server/command-allowlist.js +154 -0
  153. package/dist-server/server/composio.js +49 -11
  154. package/dist-server/server/computer-wait.js +22 -9
  155. package/dist-server/server/config.js +133 -17
  156. package/dist-server/server/connector-verdict.js +141 -0
  157. package/dist-server/server/container-computer.js +1 -1
  158. package/dist-server/server/decision-log.js +209 -48
  159. package/dist-server/server/default-model-selection.js +29 -3
  160. package/dist-server/server/delegations.js +97 -44
  161. package/dist-server/server/drivers/acp/core.js +163 -33
  162. package/dist-server/server/drivers/acp/grok.js +4 -3
  163. package/dist-server/server/drivers/agents-call.js +1162 -0
  164. package/dist-server/server/drivers/agents-catalog.js +689 -0
  165. package/dist-server/server/drivers/agents-client.js +28 -0
  166. package/dist-server/server/drivers/agents-proxy.js +18 -1722
  167. package/dist-server/server/drivers/boxagent.js +174 -36
  168. package/dist-server/server/drivers/builtIn.js +2 -0
  169. package/dist-server/server/drivers/chat-box-tools.js +90 -0
  170. package/dist-server/server/drivers/chat-images.js +54 -0
  171. package/dist-server/server/drivers/chat-mcp-tools.js +55 -10
  172. package/dist-server/server/drivers/chat-tool-approval.js +70 -18
  173. package/dist-server/server/drivers/claude.js +28 -8
  174. package/dist-server/server/drivers/codex-instructions.js +48 -6
  175. package/dist-server/server/drivers/codex-mcp-names.js +44 -0
  176. package/dist-server/server/drivers/codex-tool-surface.js +20 -0
  177. package/dist-server/server/drivers/codex.js +121 -34
  178. package/dist-server/server/drivers/grok.js +2 -1
  179. package/dist-server/server/drivers/mistral.js +115 -0
  180. package/dist-server/server/drivers/openai-chat.js +155 -32
  181. package/dist-server/server/drivers/openai-compat.js +16 -8
  182. package/dist-server/server/drivers/permission-command.js +35 -0
  183. package/dist-server/server/drivers/phone-proxy.js +47 -2
  184. package/dist-server/server/drivers/pi.js +75 -4
  185. package/dist-server/server/drivers/prompt-split.js +87 -0
  186. package/dist-server/server/enterprise.js +97 -16
  187. package/dist-server/server/external-runtime.js +83 -0
  188. package/dist-server/server/fleet.js +1 -1
  189. package/dist-server/server/group-thread-usage.js +103 -0
  190. package/dist-server/server/guarded-requests.js +60 -0
  191. package/dist-server/server/harness/http.js +61 -0
  192. package/dist-server/server/harness/registry.js +1 -0
  193. package/dist-server/server/hosted-models.js +151 -0
  194. package/dist-server/server/hosted-slack.js +11 -0
  195. package/dist-server/server/index.js +3091 -658
  196. package/dist-server/server/local-computer.js +72 -23
  197. package/dist-server/server/managed-desktop.js +79 -14
  198. package/dist-server/server/managed-policy.js +153 -0
  199. package/dist-server/server/mcp-bridge.js +6 -6
  200. package/dist-server/server/message-db.js +28 -0
  201. package/dist-server/server/model-context-window.js +7 -0
  202. package/dist-server/server/model-prices.js +121 -0
  203. package/dist-server/server/new-bot-defaults.js +115 -0
  204. package/dist-server/server/notify.js +10 -1
  205. package/dist-server/server/org-library.js +1051 -0
  206. package/dist-server/server/package-export.js +627 -39
  207. package/dist-server/server/package-import.js +458 -0
  208. package/dist-server/server/package-parts.js +87 -0
  209. package/dist-server/server/peer-approval.js +16 -7
  210. package/dist-server/server/peer-roster.js +23 -2
  211. package/dist-server/server/presets.js +492 -0
  212. package/dist-server/server/provider-key-check.js +3 -2
  213. package/dist-server/server/published-teams.js +80 -0
  214. package/dist-server/server/recent-work.js +15 -0
  215. package/dist-server/server/request-auth.js +96 -0
  216. package/dist-server/server/room-handoffs.js +44 -14
  217. package/dist-server/server/routes/bot-presets.js +25 -0
  218. package/dist-server/server/routes/hosted-slack.js +20 -0
  219. package/dist-server/server/routes/table.js +14 -0
  220. package/dist-server/server/routine-requests.js +6 -3
  221. package/dist-server/server/routines.js +63 -1
  222. package/dist-server/server/section-context.js +10 -0
  223. package/dist-server/server/skills.js +34 -61
  224. package/dist-server/server/spend.js +111 -16
  225. package/dist-server/server/steer-queue.js +9 -3
  226. package/dist-server/server/store.js +550 -35
  227. package/dist-server/server/surface.js +10 -4
  228. package/dist-server/server/system-prompt.js +12 -4
  229. package/dist-server/server/team-backup.js +16 -3
  230. package/dist-server/server/team-computers.js +10 -0
  231. package/dist-server/server/team-library.js +6 -2
  232. package/dist-server/server/team-manifest.js +4 -3
  233. package/dist-server/server/team-setup-requests.js +16 -5
  234. package/dist-server/server/thread-events.js +17 -1
  235. package/dist-server/server/thread-starters.js +53 -0
  236. package/dist-server/server/turn-context.js +2 -0
  237. package/dist-server/server/turn-watchdog.js +12 -3
  238. package/dist-server/server/usage-ledger.js +43 -9
  239. package/dist-server/server/vps-computer.js +139 -51
  240. package/dist-server/server/vps-container-mcp.js +7 -0
  241. package/dist-server/server/vps-ssh.js +36 -7
  242. package/dist-server/server/workspace-backup-policy.js +21 -2
  243. package/dist-server/server/workspace-backup.js +7 -4
  244. package/dist-server/server/workspace.js +1 -1
  245. package/dist-server/shared/approval-mode.js +1 -1
  246. package/dist-server/shared/ask-question.js +188 -12
  247. package/dist-server/shared/bot-profile.js +15 -0
  248. package/dist-server/shared/command-allowlist.js +1 -0
  249. package/dist-server/shared/credential-request.js +1 -1
  250. package/dist-server/shared/mention-boundary.js +15 -0
  251. package/dist-server/shared/package-format.js +967 -0
  252. package/dist-server/shared/routines.js +7 -1
  253. package/dist-server/shared/skill-md.js +64 -0
  254. package/dist-server/shared/team-backup.js +9 -0
  255. package/dist-server/shared/wire.js +4 -0
  256. package/dist-server/src/lib/composer-attachments.js +16 -0
  257. package/dist-server/vps-container-mcp.js +1147 -179
  258. package/enterprise/README.md +33 -12
  259. package/enterprise/server/index.js +5 -5
  260. package/package.json +1 -1
  261. package/dist/assets/index-Ba9G44HI.js +0 -310
  262. package/dist/assets/index-CkRNp7wX.css +0 -1
@@ -1,300 +1,26 @@
1
- import { z } from "zod";
2
- import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
3
- import { schemaIssue } from "./schema.js";
4
- import { isSkillName, parseSkillMd, SKILL_FILE_MAX_BYTES } from "./skills.js";
5
- import { BOT_PROFILE_LIMITS } from "../shared/bot-profile.js";
6
- import { normalizeCronSchedule } from "../shared/routine-schedule.js";
1
+ import { stringify as stringifyYaml } from "yaml";
7
2
  import { cronScheduleLabel } from "../shared/cron-label.js";
8
- export const BOT_PACKAGE_FORMAT = "openmaus.package";
9
- export const BOT_PACKAGE_VERSION = 1;
10
- export const BOTMRR_MARKDOWN_VERSION = 1;
3
+ import { BOTMRR_MARKDOWN_VERSION, isPackageDocument, PACKAGE_FORMAT, PACKAGE_V1_MAX_SKILLS, PACKAGE_V1_VERSION, parsePackageV1, utf8Bytes, } from "../shared/package-format.js";
4
+ // The package file format (v1 and v2) lives in shared/package-format.ts: one
5
+ // validation gate for the server, the renderer and Admin. This module keeps
6
+ // the v1 names the v1 exporter and its Markdown playbook are written in, and
7
+ // re-exports the v2 reader so server code has one place to import from.
8
+ export { canonicalJson, downgradeToV1, PACKAGE_MAX_BYTES, PACKAGE_VERSION, PackageFormatError, packageKeys, packageScanFindings, packageSecretFindings, packageSummary, parsePackageDocument, redactPackageSecrets, upgradeV1, } from "../shared/package-format.js";
9
+ export const BOT_PACKAGE_FORMAT = PACKAGE_FORMAT;
10
+ export const BOT_PACKAGE_VERSION = PACKAGE_V1_VERSION;
11
+ export { BOTMRR_MARKDOWN_VERSION };
11
12
  export const BOT_PACKAGE_SKILLS_VERSION = 1;
12
- export const BOT_PACKAGE_MAX_SKILLS = 20;
13
+ export const BOT_PACKAGE_MAX_SKILLS = PACKAGE_V1_MAX_SKILLS;
13
14
  const BOT_PACKAGE_MARKDOWN_MAX_BYTES = 1_000_000;
14
- const COLORS = [
15
- "green",
16
- "blue",
17
- "red",
18
- "orange",
19
- "purple",
20
- "cyan",
21
- "pink",
22
- "yellow",
23
- "teal",
24
- "coral",
25
- ];
26
- const requiredText = (max) => z.string({ error: "must be text" }).trim().min(1, { message: "is required" }).max(max, { message: "is too long" });
27
- const optionalText = (max) => z
28
- .union([z.string({ error: "must be text" }), z.null(), z.undefined()])
29
- .transform((value) => value?.trim() || undefined)
30
- .refine((value) => value === undefined || value.length <= max, { message: "is too long" })
31
- .optional();
32
- const key = requiredText(64).regex(/^[a-z0-9][a-z0-9_-]*$/, {
33
- message: "may only contain lowercase letters, numbers, - and _",
34
- });
35
- const MAX_DATE_MS = 8_640_000_000_000_000;
36
- const skillName = requiredText(64).refine(isSkillName, {
37
- message: "must be a lowercase skill name",
38
- });
39
- const portableSource = optionalText(2_000).refine((value) => value === undefined || !/^(?:[a-z]:[\\/]|[\\/]|\\\\|file:)/i.test(value), { message: "must not be an absolute path" });
40
- const skillInstructions = z
41
- .string({ error: "must be text" })
42
- .min(1, { message: "is required" })
43
- .max(SKILL_FILE_MAX_BYTES, { message: "is too long" })
44
- .refine((value) => Buffer.byteLength(value, "utf8") <= SKILL_FILE_MAX_BYTES, { message: "is too large" })
45
- .refine((value) => /^---\r?\n/.test(value), { message: "must start with SKILL.md frontmatter" });
46
- const portableSkillSchema = z.object({
47
- name: skillName,
48
- description: requiredText(1_024),
49
- source: portableSource,
50
- license: optionalText(200),
51
- compatibility: optionalText(200),
52
- instructions: skillInstructions,
53
- });
54
- const CLOCK_TIME = /^([01]\d|2[0-3]):[0-5]\d$/;
55
- const intervalWeekdays = z.array(z.number().int().min(0).max(6)).min(1).max(7).refine((weekdays) => new Set(weekdays).size === weekdays.length, "must contain unique weekdays");
56
- const intervalWindow = z.object({
57
- start: z.string().regex(CLOCK_TIME, { message: "must use HH:MM" }),
58
- end: z.string().regex(CLOCK_TIME, { message: "must use HH:MM" }),
59
- }).strict().refine(({ start, end }) => start < end, {
60
- message: "must end later on the same day",
61
- });
62
- const packageRoutineScheduleSchema = z.discriminatedUnion("type", [
63
- z.object({ type: z.literal("cron"), expression: requiredText(256), timeZone: requiredText(100) }).strict(),
64
- z.object({ type: z.literal("once"), at: z.number().int() }),
65
- z.object({
66
- type: z.literal("daily"),
67
- time: requiredText(5).regex(CLOCK_TIME, { message: "must use HH:MM" }),
68
- weekdays: z.array(z.number().int().min(0).max(6)).min(1).max(7),
69
- }),
70
- z.object({
71
- type: z.literal("interval"),
72
- everyMinutes: z.number().int().min(5).max(1_440),
73
- anchorAt: z.number().int().nonnegative().max(MAX_DATE_MS),
74
- weekdays: intervalWeekdays.optional(),
75
- window: intervalWindow.optional(),
76
- endsAt: z.number().int().nonnegative().max(MAX_DATE_MS).optional(),
77
- }),
78
- ]).superRefine((schedule, context) => {
79
- if (schedule.type === "cron") {
80
- try {
81
- normalizeCronSchedule(schedule);
82
- }
83
- catch (error) {
84
- context.addIssue({ code: "custom", message: error instanceof Error ? error.message : "Invalid cron schedule" });
85
- }
86
- return;
87
- }
88
- if (schedule.type !== "interval")
89
- return;
90
- if (schedule.window) {
91
- const [startHour, startMinute] = schedule.window.start.split(":").map(Number);
92
- const [endHour, endMinute] = schedule.window.end.split(":").map(Number);
93
- const windowMinutes = endHour * 60 + endMinute - (startHour * 60 + startMinute);
94
- if (windowMinutes < schedule.everyMinutes) {
95
- context.addIssue({
96
- code: "custom",
97
- message: "must be at least as long as the interval cadence",
98
- path: ["window"],
99
- });
100
- }
101
- }
102
- if (schedule.endsAt !== undefined && schedule.endsAt < schedule.anchorAt) {
103
- context.addIssue({
104
- code: "custom",
105
- message: "must not be before the interval anchor",
106
- path: ["endsAt"],
107
- });
108
- }
109
- });
110
- const packageSchema = z.object({
111
- format: z.literal(BOT_PACKAGE_FORMAT, { error: "This is not an OpenMaus package" }),
112
- version: z.literal(BOT_PACKAGE_VERSION, { error: "Package version is not supported" }),
113
- package: z.object({
114
- id: requiredText(80).regex(/^[a-z0-9][a-z0-9-]*$/, { message: "must be a lowercase slug" }),
115
- release: requiredText(30).regex(/^\d+\.\d+\.\d+$/, { message: "must be semantic versioning" }),
116
- name: requiredText(100),
117
- tagline: requiredText(160),
118
- summary: requiredText(2_000),
119
- category: requiredText(80),
120
- author: z.object({ name: requiredText(100), url: optionalText(500) }),
121
- license: requiredText(80),
122
- featured: z.boolean().optional(),
123
- tags: z.array(requiredText(80)).max(30).optional(),
124
- outcomes: z.array(requiredText(240)).min(1).max(12),
125
- setupMinutes: z.number().int().min(1).max(240),
126
- requirements: z.object({
127
- apps: z.array(z.object({
128
- slug: key,
129
- label: requiredText(100),
130
- reason: requiredText(240),
131
- optional: z.boolean().optional(),
132
- })).max(30),
133
- capabilities: z.array(requiredText(80)).max(20),
134
- platforms: z.array(requiredText(80)).max(10).optional(),
135
- }),
136
- agents: z.array(z.object({
137
- key,
138
- name: requiredText(100),
139
- title: optionalText(200),
140
- description: optionalText(4_000),
141
- soul: z.string().refine((value) => Buffer.byteLength(value, "utf8") <= BOT_PROFILE_LIMITS.soul, {
142
- error: "standing instructions must be at most 24000 bytes",
143
- }).optional(),
144
- appearance: z.object({
145
- color: z.enum(COLORS, { error: "is not supported" }),
146
- mascotExpression: optionalText(80),
147
- mascotBody: optionalText(40),
148
- }),
149
- playbooks: z.array(key).max(40).optional(),
150
- skills: z.array(skillName).max(BOT_PACKAGE_MAX_SKILLS).optional(),
151
- })).min(1).max(200),
152
- chiefOfStaff: key.optional(),
153
- rooms: z.array(z.object({
154
- key,
155
- name: requiredText(100),
156
- members: z.array(key).min(1).max(200),
157
- bulletin: optionalText(12_000),
158
- defaultResponder: z.discriminatedUnion("kind", [
159
- z.object({ kind: z.literal("agent"), agent: key }),
160
- z.object({ kind: z.literal("everyone") }),
161
- z.object({ kind: z.literal("mentions") }),
162
- ]),
163
- })).max(30).optional(),
164
- routines: z.array(z.object({
165
- key,
166
- name: requiredText(80),
167
- agent: key,
168
- prompt: requiredText(20_000),
169
- runOn: z.enum(["maus", "cloud"]),
170
- schedule: packageRoutineScheduleSchema,
171
- durationMinutes: z.number().int().min(5).max(240),
172
- timeoutMinutes: z.number().int().min(5).max(240).optional(),
173
- overlap: z.enum(["skip", "queue"]).optional(),
174
- enabledAfterInstall: z.literal(false),
175
- })).max(50).optional(),
176
- playbooks: z.array(z.object({
177
- key,
178
- name: requiredText(100),
179
- summary: requiredText(300),
180
- triggers: z.array(requiredText(100)).min(1).max(30),
181
- instructions: requiredText(24_000),
182
- })).max(80).optional(),
183
- skills: z.object({
184
- version: z.literal(BOT_PACKAGE_SKILLS_VERSION),
185
- entries: z.array(portableSkillSchema).min(1).max(BOT_PACKAGE_MAX_SKILLS),
186
- }).optional(),
187
- examples: z.array(z.object({
188
- title: requiredText(120),
189
- input: requiredText(4_000),
190
- output: requiredText(8_000),
191
- })).max(12).optional(),
192
- }),
193
- });
194
15
  export function isBotPackage(value) {
195
- if (typeof value === "string")
196
- return /^---\r?\n[\s\S]*?\bbotmrr:\s*1\b/m.test(value);
197
- return Boolean(value) && typeof value === "object" && !Array.isArray(value) &&
198
- value.format === BOT_PACKAGE_FORMAT;
16
+ return isPackageDocument(value);
199
17
  }
200
- function markdownDocument(markdown) {
201
- if (Buffer.byteLength(markdown) > BOT_PACKAGE_MARKDOWN_MAX_BYTES)
202
- throw new Error("The bot playbook is too large");
203
- const frontmatter = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
204
- if (!frontmatter)
205
- throw new Error("This Markdown is missing YAML frontmatter");
206
- let metadata;
207
- try {
208
- metadata = parseYaml(frontmatter[1]);
209
- }
210
- catch {
211
- throw new Error("This Markdown has invalid YAML frontmatter");
212
- }
213
- if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
214
- throw new Error("This Markdown is missing its BotMRR blueprint");
215
- }
216
- const { botmrr, ...definition } = metadata;
217
- if (botmrr !== BOTMRR_MARKDOWN_VERSION)
218
- throw new Error("BotMRR Markdown version is not supported");
219
- for (const heading of ["Activation", "Mission", "Outcomes", "Connections", "Team", "Chief of Staff", "Completion rule"]) {
220
- if (!markdown.includes(`## ${heading}`))
221
- throw new Error(`This Markdown is missing its ${heading} section`);
222
- }
223
- return {
224
- format: BOT_PACKAGE_FORMAT,
225
- version: BOT_PACKAGE_VERSION,
226
- package: definition,
227
- };
228
- }
229
- /** Parse and cross-reference one complete, portable package. Unknown fields
230
- * are stripped; ids, grants, credentials, paths, model selections, and
231
- * runtime state therefore cannot ride through the package boundary. */
18
+ /** Parse and cross-reference one complete v1 package. Unknown fields are
19
+ * stripped; ids, grants, credentials, paths, model selections, and runtime
20
+ * state therefore cannot ride through the package boundary. v2 documents
21
+ * go through parsePackageDocument instead. */
232
22
  export function parseBotPackage(value) {
233
- const source = typeof value === "string" ? markdownDocument(value) : value;
234
- const parsed = packageSchema.safeParse(source);
235
- if (!parsed.success)
236
- throw new Error(schemaIssue(parsed.error, "This is not a bot package"));
237
- const pkg = parsed.data.package;
238
- const unique = (values, label) => {
239
- const seen = new Set();
240
- for (const value of values) {
241
- if (seen.has(value))
242
- throw new Error(`Duplicate ${label} key: ${value}`);
243
- seen.add(value);
244
- }
245
- return seen;
246
- };
247
- const agents = unique(pkg.agents.map((agent) => agent.key), "agent");
248
- const playbooks = unique((pkg.playbooks ?? []).map((playbook) => playbook.key), "playbook");
249
- const skills = unique((pkg.skills?.entries ?? []).map((skill) => skill.name), "skill");
250
- unique((pkg.rooms ?? []).map((room) => room.key), "room");
251
- unique((pkg.routines ?? []).map((routine) => routine.key), "routine");
252
- if (pkg.chiefOfStaff && !agents.has(pkg.chiefOfStaff)) {
253
- throw new Error(`Unknown Chief of Staff: ${pkg.chiefOfStaff}`);
254
- }
255
- for (const agent of pkg.agents) {
256
- for (const playbook of agent.playbooks ?? []) {
257
- if (!playbooks.has(playbook))
258
- throw new Error(`Agent ${agent.key} references unknown playbook: ${playbook}`);
259
- }
260
- const assignedSkills = unique(agent.skills ?? [], `skill in agent ${agent.key}`);
261
- for (const skill of assignedSkills) {
262
- if (!skills.has(skill))
263
- throw new Error(`Agent ${agent.key} references unknown skill: ${skill}`);
264
- }
265
- }
266
- const referencedSkills = new Set(pkg.agents.flatMap((agent) => agent.skills ?? []));
267
- for (const skill of pkg.skills?.entries ?? []) {
268
- const parsed = parseSkillMd(skill.instructions);
269
- if ("error" in parsed)
270
- throw new Error(`Skill ${skill.name} is invalid: ${parsed.error}`);
271
- if (parsed.name !== skill.name)
272
- throw new Error(`Skill ${skill.name} does not match its SKILL.md name`);
273
- if (parsed.description !== skill.description)
274
- throw new Error(`Skill ${skill.name} does not match its description`);
275
- for (const field of ["license", "compatibility"]) {
276
- if (skill[field] !== undefined && skill[field] !== parsed[field]) {
277
- throw new Error(`Skill ${skill.name} does not match its ${field}`);
278
- }
279
- }
280
- if (!referencedSkills.has(skill.name))
281
- throw new Error(`Skill ${skill.name} is not referenced by an agent`);
282
- }
283
- for (const room of pkg.rooms ?? []) {
284
- const members = unique(room.members, `member in room ${room.key}`);
285
- for (const member of members) {
286
- if (!agents.has(member))
287
- throw new Error(`Room ${room.key} references unknown agent: ${member}`);
288
- }
289
- if (room.defaultResponder.kind === "agent" && !members.has(room.defaultResponder.agent)) {
290
- throw new Error(`Room ${room.key} has an unknown default responder`);
291
- }
292
- }
293
- for (const routine of pkg.routines ?? []) {
294
- if (!agents.has(routine.agent))
295
- throw new Error(`Routine ${routine.key} references unknown agent: ${routine.agent}`);
296
- }
297
- return parsed.data;
23
+ return parsePackageV1(value);
298
24
  }
299
25
  const list = (values) => values.map((value) => `- ${value}`).join("\n");
300
26
  const WEEKDAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
@@ -368,7 +94,7 @@ export function renderBotPackageMarkdown(document) {
368
94
  ? pkg.requirements.apps.map((app) => `- **${app.label}${app.optional ? " (optional)" : ""}:** ${app.reason}`).join("\n")
369
95
  : "- No connected apps are required.";
370
96
  const markdown = `---\n${frontmatter}\n---\n\n# ${pkg.name}\n\n${pkg.tagline}\n\n> **Give this file to your Chief of Staff.** It is the complete team blueprint. Any agent system can run it; OpenMausBot can also install it directly.\n\n## Activation\n\nYou are the Chief of Staff for this blueprint. Read the whole document before acting. Confirm the user's goal and any missing inputs, then create or delegate to the specialist roles below. Preserve their names, ownership, boundaries, shared-room rules, and playbooks. If your platform cannot literally spawn agents, perform the roles one at a time and keep their outputs clearly separated.\n\nNever request pasted passwords or secret keys. Use the platform's normal connection flow. Do not send messages, publish content, spend money, delete data, or enable a schedule without the user's explicit approval. All routines start paused.\n\n## Mission\n\n${pkg.summary}\n\n## Outcomes\n\n${list(pkg.outcomes)}\n\n## Connections\n\n${connections}\n\n## Team\n\n${agents}\n\n## Chief of Staff\n\nThe Chief of Staff role is \`${pkg.chiefOfStaff ?? pkg.agents[0].key}\`. This role owns delegation, synthesis, conflict resolution, and the final answer to the user.\n${rooms ? `\n## Shared rooms\n\n${rooms}\n` : ""}${routines ? `\n## Suggested routines\n\n${routines}\n` : ""}${playbooks ? `\n## Playbooks\n\n${playbooks}\n` : ""}${examples ? `\n## Example job\n\n${examples}\n` : ""}\n## Completion rule\n\nReturn one clear result to the user, distinguish evidence from inference, cite source links when the work uses external material, and state what still needs human approval or a connected app.\n`;
371
- if (Buffer.byteLength(markdown) > BOT_PACKAGE_MARKDOWN_MAX_BYTES)
97
+ if (utf8Bytes(markdown) > BOT_PACKAGE_MARKDOWN_MAX_BYTES)
372
98
  throw new Error("The bot playbook is too large");
373
99
  return markdown;
374
100
  }
@@ -1,22 +1,10 @@
1
1
  import { z } from "zod";
2
2
  import { BOT_AVATAR_CROPS, botAvatarCropSchema, botAvatarUrlSchema } from "../shared/bot-avatar.js";
3
- import { BOT_PROFILE_LIMITS } from "../shared/bot-profile.js";
3
+ import { BOT_PROFILE_LIMITS, fitsOnOneLine } from "../shared/bot-profile.js";
4
4
  import { MASCOT_BODY_IDS, mascotBodySchema } from "../shared/mascot-bodies.js";
5
- /** A name or title is quoted inside prompts and cards as one line — a
6
- * roster entry, a "Name: …" speaker line, the bracketed provenance note.
7
- * Text that can break out of that line (a newline, a control byte, the
8
- * Unicode separators) is refused at the door rather than flattened later,
9
- * so what the person sees in the sidebar is what every prompt sees too.
10
- * Written as a scan because a control-character class is the kind of
11
- * literal the linter (rightly) refuses. */
12
- export function fitsOnOneLine(value) {
13
- for (let i = 0; i < value.length; i += 1) {
14
- const code = value.charCodeAt(i);
15
- if (code < 0x20 || (code >= 0x7f && code <= 0x9f) || code === 0x2028 || code === 0x2029)
16
- return false;
17
- }
18
- return true;
19
- }
5
+ // Shared with the package format, which checks the same rule on names it
6
+ // carries; re-exported under its historical path.
7
+ export { fitsOnOneLine } from "../shared/bot-profile.js";
20
8
  export const BOT_PROFILE_PATCH_FIELDS = [
21
9
  "name",
22
10
  "title",
@@ -29,7 +17,7 @@ export const BOT_PROFILE_PATCH_FIELDS = [
29
17
  "voice",
30
18
  "speakReplies",
31
19
  ];
32
- const profilePatchSchema = z.object({
20
+ export const profilePatchSchema = z.object({
33
21
  name: z
34
22
  .string({ error: "name must be a string" })
35
23
  .max(BOT_PROFILE_LIMITS.name, { error: "name must be at most 100 characters" })