openmausbot 0.1.89 → 0.1.91

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 (168) hide show
  1. package/dist/assets/{abnfDiagram-O67JEVCF-BwaMaZEm.js → abnfDiagram-O67JEVCF-yP-w8pRq.js} +1 -1
  2. package/dist/assets/{arc-Be-8GKxd.js → arc-DsivfZEh.js} +1 -1
  3. package/dist/assets/{architectureDiagram-NJMV4G6O-Dp_U2Kv1.js → architectureDiagram-NJMV4G6O-CILw7lzT.js} +1 -1
  4. package/dist/assets/{blockDiagram-BEXU5L5S-DQjUjYUk.js → blockDiagram-BEXU5L5S-DEQUV3HF.js} +1 -1
  5. package/dist/assets/{c4Diagram-YGBWAQC7-Bd3aE4Kc.js → c4Diagram-YGBWAQC7-lSXCZoKA.js} +1 -1
  6. package/dist/assets/channel-DrfGMu7X.js +1 -0
  7. package/dist/assets/{chunk-2Q5K7J3B-BijjTBeJ.js → chunk-2Q5K7J3B-QCD5bgWP.js} +1 -1
  8. package/dist/assets/{chunk-3FUC2YCW-CMGdwvzW.js → chunk-3FUC2YCW-C5-iZJuL.js} +2 -2
  9. package/dist/assets/{chunk-5VM5RSS4-0G09BfsZ.js → chunk-5VM5RSS4-cxsawMpY.js} +1 -1
  10. package/dist/assets/{chunk-GTNCS2PH-FOp3vSHe.js → chunk-GTNCS2PH-DV8tV8H7.js} +1 -1
  11. package/dist/assets/{chunk-GWA4HPMP-Dv-20VIn.js → chunk-GWA4HPMP-CJFZyfbW.js} +1 -1
  12. package/dist/assets/{chunk-JWPE2WC7-CRgrdFcz.js → chunk-JWPE2WC7-BigbMXco.js} +1 -1
  13. package/dist/assets/{chunk-NETBCI7D-3hP4f7QB.js → chunk-NETBCI7D-oVxTfpDy.js} +1 -1
  14. package/dist/assets/{chunk-WEXAMYUT-CG98IjlG.js → chunk-WEXAMYUT-CH4BiroW.js} +1 -1
  15. package/dist/assets/{chunk-XXDRQBXY-BrSTC9xG.js → chunk-XXDRQBXY-KEDa6gax.js} +1 -1
  16. package/dist/assets/{classDiagram-v2-NBCMYWYE-rpQQQDFX.js → classDiagram-v2-NBCMYWYE-BiPjfqVv.js} +1 -1
  17. package/dist/assets/{cose-bilkent-JH36ORCC-G6RSafHA.js → cose-bilkent-JH36ORCC-Caxew3OY.js} +1 -1
  18. package/dist/assets/{cynefin-OW5HDTMX-CXjv-IM2.js → cynefin-OW5HDTMX-B_Pui369.js} +1 -1
  19. package/dist/assets/{cynefinDiagram-VND7K2PF-Dw07MR9f.js → cynefinDiagram-VND7K2PF-X64ydIhP.js} +1 -1
  20. package/dist/assets/{dagre-6A5THRUB-BwPnlTg2.js → dagre-6A5THRUB-TqYCI1E1.js} +1 -1
  21. package/dist/assets/{diagram-22UHCM2B-Cm6xcMiz.js → diagram-22UHCM2B-TeOt3rAQ.js} +1 -1
  22. package/dist/assets/{diagram-3UASUU5V-CDpogPbE.js → diagram-3UASUU5V-D70BLhDA.js} +1 -1
  23. package/dist/assets/{diagram-ATOU4E4O-BV8z3Pnc.js → diagram-ATOU4E4O-BbQDLwUC.js} +1 -1
  24. package/dist/assets/{diagram-CDSNMT55-CKCQhOOC.js → diagram-CDSNMT55-ChNJZ1u-.js} +1 -1
  25. package/dist/assets/{diagram-MLGK6HIB-FGvJg69C.js → diagram-MLGK6HIB-DMBl2APa.js} +1 -1
  26. package/dist/assets/{diagram-MPIPVDR6-CwATvgnS.js → diagram-MPIPVDR6-CEqDchOp.js} +1 -1
  27. package/dist/assets/{ebnfDiagram-ZINNZB2B-CH_c3SSC.js → ebnfDiagram-ZINNZB2B-BVDKRp_-.js} +1 -1
  28. package/dist/assets/{elk-276RUBZZ-3guZi71R.js → elk-276RUBZZ-CRkofO9B.js} +1 -1
  29. package/dist/assets/{erDiagram-OPXOYQCR-BMHphR2n.js → erDiagram-OPXOYQCR-DruOMh5e.js} +1 -1
  30. package/dist/assets/{flowDiagram-KWPJA3E3-Vm5DkW5x.js → flowDiagram-KWPJA3E3-8GMQeB7t.js} +1 -1
  31. package/dist/assets/{ganttDiagram-FUAMR5RP-DO-1ct07.js → ganttDiagram-FUAMR5RP-ORE9jcsM.js} +1 -1
  32. package/dist/assets/{gitGraphDiagram-X574FWY7-nxeksEIN.js → gitGraphDiagram-X574FWY7-BmsedsWh.js} +1 -1
  33. package/dist/assets/index-BlnCEcU6.js +588 -0
  34. package/dist/assets/{index-Oxk9x45i.js → index-DKNEM8Q6.js} +1 -1
  35. package/dist/assets/index-DVxjOvID.css +1 -0
  36. package/dist/assets/{infoDiagram-VRGFBTTK-Dkcvr0p7.js → infoDiagram-VRGFBTTK-E_p7AooJ.js} +1 -1
  37. package/dist/assets/{ishikawaDiagram-OU5B5YK6-BwVibkoO.js → ishikawaDiagram-OU5B5YK6-Y-B2mKda.js} +1 -1
  38. package/dist/assets/{journeyDiagram-ZHPQQLJL-ByiBZqgG.js → journeyDiagram-ZHPQQLJL-eA8RELcK.js} +1 -1
  39. package/dist/assets/{kanban-definition-PNTS6WVX-qqjgXBF3.js → kanban-definition-PNTS6WVX-DqIL2e8e.js} +1 -1
  40. package/dist/assets/{linear-CtJnKe6A.js → linear-yC_29R6e.js} +1 -1
  41. package/dist/assets/{mermaid.core-BEiDklrY.js → mermaid.core-VhEMkSND.js} +5 -5
  42. package/dist/assets/{mindmap-definition-NLK3R4M7-DfIYHia9.js → mindmap-definition-NLK3R4M7-oJ7kyQZy.js} +1 -1
  43. package/dist/assets/{pegDiagram-GJSIUBJH-CYyRqa1a.js → pegDiagram-GJSIUBJH-BmfYcY0O.js} +1 -1
  44. package/dist/assets/{pieDiagram-5QR66LMP-hOToy_zH.js → pieDiagram-5QR66LMP-DKvgP7w9.js} +1 -1
  45. package/dist/assets/{quadrantDiagram-O4NWA36T-DKAsNN9I.js → quadrantDiagram-O4NWA36T-BEKL3W0L.js} +1 -1
  46. package/dist/assets/{railroadDiagram-XR7U4H2S-BSA-d8JU.js → railroadDiagram-XR7U4H2S-BEsiqR5s.js} +1 -1
  47. package/dist/assets/{requirementDiagram-PLB6GJNP-CSmlvb-p.js → requirementDiagram-PLB6GJNP-DWBcWvAP.js} +1 -1
  48. package/dist/assets/{sankeyDiagram-IPEJSGJF-CD5F6fnG.js → sankeyDiagram-IPEJSGJF-rpZ2_O4s.js} +1 -1
  49. package/dist/assets/{sequenceDiagram-PO4LG4MO-JUq5sx6d.js → sequenceDiagram-PO4LG4MO-B99HQdJR.js} +1 -1
  50. package/dist/assets/{sizeCapture-INFHLROL-BjIS-Stk.js → sizeCapture-INFHLROL-BjN0qT5T.js} +1 -1
  51. package/dist/assets/{stateDiagram-v2-GCMORJYK-DklkUxOg.js → stateDiagram-v2-GCMORJYK-BbsVgGsC.js} +1 -1
  52. package/dist/assets/{swimlanes-2SLR337P-CsjIU6be.js → swimlanes-2SLR337P-DG3gKkeR.js} +1 -1
  53. package/dist/assets/swimlanesDiagram-TC7HE7FX-BCZhxl7e.js +8 -0
  54. package/dist/assets/{timeline-definition-EJHVYXUP-BkFqK7AB.js → timeline-definition-EJHVYXUP-BTHOdtF_.js} +1 -1
  55. package/dist/assets/{usecaseDiagram-POWQR4AR-70gJB1EU.js → usecaseDiagram-POWQR4AR-acLSLFwc.js} +1 -1
  56. package/dist/assets/{vennDiagram-UO4OBE2U-83Tm62dN.js → vennDiagram-UO4OBE2U-C5JzNX9G.js} +1 -1
  57. package/dist/assets/{wardleyDiagram-VNRHLVJA-tTmseoX9.js → wardleyDiagram-VNRHLVJA-DL1-PrR_.js} +1 -1
  58. package/dist/assets/{xychartDiagram-PMCCYNJV-R1LBA55a.js → xychartDiagram-PMCCYNJV-Bvr1477p.js} +1 -1
  59. package/dist/index.html +2 -2
  60. package/dist-server/cloud-home-start.js +14810 -0
  61. package/dist-server/container-mcp.js +136 -36
  62. package/dist-server/drivers/agents-proxy.js +31 -10
  63. package/dist-server/index.js +48251 -44124
  64. package/dist-server/openmausbot.js +628 -292
  65. package/dist-server/pair-cli.js +628 -292
  66. package/dist-server/permission-proxy.js +1 -1
  67. package/dist-server/server/admission.js +46 -0
  68. package/dist-server/server/{box-create-idempotency.js → boat-create-idempotency.js} +32 -31
  69. package/dist-server/server/{box-delete-journal.js → boat-delete-journal.js} +26 -25
  70. package/dist-server/server/{box.js → boat.js} +381 -334
  71. package/dist-server/server/bot-overview.js +7 -4
  72. package/dist-server/server/bot-profile.js +7 -1
  73. package/dist-server/server/channel-queue.js +58 -18
  74. package/dist-server/server/checkpoints.js +98 -52
  75. package/dist-server/server/claim-idle.js +33 -0
  76. package/dist-server/server/cloud-backend.js +5 -5
  77. package/dist-server/server/cloud-home-start.js +121 -0
  78. package/dist-server/server/cloud-home.js +241 -0
  79. package/dist-server/server/cloud-lending.js +103 -0
  80. package/dist-server/server/cloud-move-http.js +268 -0
  81. package/dist-server/server/cloud-move.js +418 -0
  82. package/dist-server/server/cloud-overflow.js +167 -0
  83. package/dist-server/server/composio.js +5 -0
  84. package/dist-server/server/computer-observation.js +2 -2
  85. package/dist-server/server/config.js +156 -9
  86. package/dist-server/server/container-computer.js +13 -0
  87. package/dist-server/server/control-client.js +2 -2
  88. package/dist-server/server/decider/index.js +238 -0
  89. package/dist-server/server/decider/jev.js +183 -0
  90. package/dist-server/server/decider/log.js +62 -0
  91. package/dist-server/server/decider/relay.js +52 -0
  92. package/dist-server/server/decider/room-routing.js +88 -0
  93. package/dist-server/server/decider/types.js +5 -0
  94. package/dist-server/server/delegations.js +11 -3
  95. package/dist-server/server/drivers/acp/core.js +5 -4
  96. package/dist-server/server/drivers/agents-call.js +5 -1
  97. package/dist-server/server/drivers/agents-catalog.js +25 -3
  98. package/dist-server/server/drivers/{boxagent.js → boatagent.js} +30 -21
  99. package/dist-server/server/drivers/builtIn.js +2 -2
  100. package/dist-server/server/drivers/{chat-box-tools.js → chat-boat-tools.js} +3 -3
  101. package/dist-server/server/drivers/chat-mcp-tools.js +2 -2
  102. package/dist-server/server/drivers/claude.js +178 -13
  103. package/dist-server/server/drivers/native.js +1 -1
  104. package/dist-server/server/drivers/openai-chat.js +15 -4
  105. package/dist-server/server/drivers/pi.js +3 -3
  106. package/dist-server/server/group-goal-run.js +6 -4
  107. package/dist-server/server/harness-capabilities.js +2 -0
  108. package/dist-server/server/hosted-models.js +6 -1
  109. package/dist-server/server/included-services.js +70 -0
  110. package/dist-server/server/index.js +1462 -576
  111. package/dist-server/server/local-vm-inventory.js +11 -1
  112. package/dist-server/server/local-vm-seat-pool.js +141 -0
  113. package/dist-server/server/managed-policy.js +4 -1
  114. package/dist-server/server/memory-capture.js +194 -0
  115. package/dist-server/server/memory-entries.js +76 -0
  116. package/dist-server/server/memory-organize.js +102 -0
  117. package/dist-server/server/memory-tidy.js +144 -0
  118. package/dist-server/server/memory-topics.js +169 -0
  119. package/dist-server/server/memory-upkeep.js +452 -0
  120. package/dist-server/server/message-db.js +49 -5
  121. package/dist-server/server/model-context-window.js +4 -4
  122. package/dist-server/server/package-export.js +17 -10
  123. package/dist-server/server/package-import.js +6 -3
  124. package/dist-server/server/package-parts.js +3 -1
  125. package/dist-server/server/permission-proxy.js +3 -3
  126. package/dist-server/server/profile-learned.js +98 -0
  127. package/dist-server/server/profile-versions.js +45 -11
  128. package/dist-server/server/recall.js +172 -0
  129. package/dist-server/server/redact.js +1 -1
  130. package/dist-server/server/request-auth.js +2 -0
  131. package/dist-server/server/room-cwd.js +1 -1
  132. package/dist-server/server/room-handoffs.js +61 -6
  133. package/dist-server/server/routes/bot-memory.js +215 -0
  134. package/dist-server/server/routes/decider.js +19 -0
  135. package/dist-server/server/routine-requests.js +27 -16
  136. package/dist-server/server/routines.js +10 -6
  137. package/dist-server/server/shared-computers.js +116 -30
  138. package/dist-server/server/steer-queue.js +41 -10
  139. package/dist-server/server/store.js +42 -3
  140. package/dist-server/server/surface.js +14 -1
  141. package/dist-server/server/system-prompt.js +16 -5
  142. package/dist-server/server/team-backup.js +6 -2
  143. package/dist-server/server/team-computers.js +2 -2
  144. package/dist-server/server/team-manifest.js +11 -3
  145. package/dist-server/server/tightening-requests.js +34 -4
  146. package/dist-server/server/tool-summary.js +2 -2
  147. package/dist-server/server/tts/elevenlabs.js +12 -7
  148. package/dist-server/server/tts/index.js +17 -10
  149. package/dist-server/server/turn-resources.js +87 -11
  150. package/dist-server/server/vps-computer.js +1 -1
  151. package/dist-server/server/workspace-backup-policy.js +22 -3
  152. package/dist-server/server/workspace-backup.js +25 -8
  153. package/dist-server/server/workspace.js +57 -22
  154. package/dist-server/shared/ask-question.js +7 -5
  155. package/dist-server/shared/bot-avatar.js +19 -0
  156. package/dist-server/shared/cloud-home.js +4 -0
  157. package/dist-server/shared/credential-request.js +3 -3
  158. package/dist-server/shared/package-format.js +30 -4
  159. package/dist-server/shared/team-backup.js +20 -3
  160. package/dist-server/shared/tool-surface.js +1 -1
  161. package/dist-server/src/lib/composer-attachments.js +9 -0
  162. package/dist-server/vps-container-mcp.js +136 -36
  163. package/dist-server/workspace-backup.worker.js +165 -35
  164. package/package.json +1 -1
  165. package/dist/assets/channel-DqY_gMLg.js +0 -1
  166. package/dist/assets/index-BIMdIbaw.css +0 -1
  167. package/dist/assets/index-BVPdbq2r.js +0 -583
  168. package/dist/assets/swimlanesDiagram-TC7HE7FX-Bk14M0_B.js +0 -8
@@ -63,6 +63,20 @@ const memory = z.object({
63
63
  * against. Shareable exports never carry grants at all, and an import
64
64
  * always lands bots grant-less whatever the file says. */
65
65
  const connectorTools = z.record(z.string().regex(CONNECTOR_SLUG_PATTERN), z.object({ tools: z.union([z.literal("*"), z.array(z.string().regex(CONNECTOR_TOOL_NAME_PATTERN)).min(1).max(500)]) }));
66
+ /** A responder kind from a newer release restores as the room's first
67
+ * member as lead (what a room without one does) instead of refusing the
68
+ * whole backup. Malformed values still fail the schema. */
69
+ function knownRoomResponder(value) {
70
+ if (!value || typeof value !== "object" || Array.isArray(value))
71
+ return value;
72
+ const group = value;
73
+ const kind = group.defaultResponder && typeof group.defaultResponder === "object"
74
+ ? group.defaultResponder.kind : undefined;
75
+ if (typeof kind !== "string" || ["member", "everyone", "mentions", "auto"].includes(kind))
76
+ return value;
77
+ const first = Array.isArray(group.memberIds) && typeof group.memberIds[0] === "string" ? group.memberIds[0] : undefined;
78
+ return { ...group, defaultResponder: first ? { kind: "member", botId: first } : { kind: "mentions" } };
79
+ }
66
80
  const backupSchema = z.object({
67
81
  format: z.literal("openmaus.backup"),
68
82
  version: z.literal(1),
@@ -86,7 +100,7 @@ const backupSchema = z.object({
86
100
  connectorTools: connectorTools.optional(),
87
101
  memory: memory.optional(),
88
102
  })).min(1).max(200),
89
- groups: z.array(z.object({
103
+ groups: z.array(z.preprocess(knownRoomResponder, z.object({
90
104
  ...owner,
91
105
  memberIds: z.array(key).max(200),
92
106
  dm: z.boolean(),
@@ -95,8 +109,9 @@ const backupSchema = z.object({
95
109
  z.object({ kind: z.literal("member"), botId: key }),
96
110
  z.object({ kind: z.literal("everyone") }),
97
111
  z.object({ kind: z.literal("mentions") }),
112
+ z.object({ kind: z.literal("auto"), fallbackBotId: key.optional() }),
98
113
  ]),
99
- })).max(2_000),
114
+ }))).max(2_000),
100
115
  routines: z.array(z.object({
101
116
  name, prompt: z.string().trim().min(1).max(200_000),
102
117
  target: z.enum(["bot", "room-goal"]), botId: key, groupId: key.optional(),
@@ -136,7 +151,9 @@ export function parseTeamBackup(input) {
136
151
  if (group.memberIds.some((id) => !bots.has(id)))
137
152
  throw new Error("Invalid backup: unknown room member");
138
153
  unique(group.memberIds, "room member");
139
- if (group.defaultResponder.kind === "member" && !group.memberIds.includes(group.defaultResponder.botId)) {
154
+ const lead = group.defaultResponder.kind === "member" ? group.defaultResponder.botId
155
+ : group.defaultResponder.kind === "auto" ? group.defaultResponder.fallbackBotId : undefined;
156
+ if (lead !== undefined && !group.memberIds.includes(lead)) {
140
157
  throw new Error("Invalid backup: room responder is not a member");
141
158
  }
142
159
  if (group.dm && (group.memberIds.length !== 2 || group.tasks.length !== 1))
@@ -7,7 +7,7 @@
7
7
  * computer is illustrated only after one of these; the built-in browser's
8
8
  * read-only calls (snapshot, read, get_text, waits) stay out by the same rule. */
9
9
  export const SCREEN_TOUCHING_TOOLS = new Set([
10
- // cloud box / remote computer
10
+ // cloud boat / remote computer
11
11
  "screenshot", "click", "type_text", "press_key", "scroll", "computer_batch", "open_url", "browser_click", "browser_fill",
12
12
  // built-in browser: the Electron surface's names, kept because a bot on an
13
13
  // older remote harness can still call them
@@ -746,3 +746,12 @@ export function composerTakesFocusOnOpen(active, input) {
746
746
  return false;
747
747
  return !active.closest?.("[role=dialog], [role=alertdialog], [aria-modal=true]");
748
748
  }
749
+ /**
750
+ * Whether a change of reply target should put the caret in the composer.
751
+ * Choosing a message to reply to means the next thing is typing the reply,
752
+ * so a newly chosen target takes focus (MOCA-263). Clearing the reply, or the
753
+ * same target arriving again as the draft re-renders, does not.
754
+ */
755
+ export function replyTargetTakesFocus(previousId, nextId) {
756
+ return Boolean(nextId) && nextId !== previousId;
757
+ }
@@ -503,7 +503,7 @@ import { promisify } from "node:util";
503
503
 
504
504
  // server/config.ts
505
505
  import { homedir as homedir2 } from "node:os";
506
- import { join as join2 } from "node:path";
506
+ import { join as join3 } from "node:path";
507
507
 
508
508
  // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
509
509
  var external_exports = {};
@@ -15041,6 +15041,8 @@ function normalizeImageGenerationUrl(value) {
15041
15041
  // shared/bot-avatar.ts
15042
15042
  var BOT_AVATAR_CROPS = ["mascot", "circle", "rounded", "square"];
15043
15043
  var botAvatarCropSchema = external_exports.enum(BOT_AVATAR_CROPS);
15044
+ var AVATAR_ZOOM_MIN = 1;
15045
+ var AVATAR_ZOOM_MAX = 3;
15044
15046
  var botAvatarUrlSchema = external_exports.string().regex(
15045
15047
  /^\/api\/attachments\/[A-Za-z0-9-]+\.(?:png|jpg|gif|webp)$/,
15046
15048
  "must be a stored PNG, JPEG, GIF, or WebP attachment"
@@ -15079,6 +15081,9 @@ var profilePatchSchema = external_exports.object({
15079
15081
  error: "avatarUrl must be a stored PNG, JPEG, GIF, or WebP attachment"
15080
15082
  }).optional(),
15081
15083
  avatarCrop: botAvatarCropSchema.optional(),
15084
+ avatarZoom: external_exports.number({ error: "avatarZoom must be a number from 1 to 3" }).finite().min(AVATAR_ZOOM_MIN).max(AVATAR_ZOOM_MAX).optional(),
15085
+ avatarFocusX: external_exports.number({ error: "avatarFocusX must be a number from 0 to 1" }).finite().min(0).max(1).optional(),
15086
+ avatarFocusY: external_exports.number({ error: "avatarFocusY must be a number from 0 to 1" }).finite().min(0).max(1).optional(),
15082
15087
  mascotBody: mascotBodySchema.optional(),
15083
15088
  voice: external_exports.string({ error: "voice must be a string" }).max(BOT_PROFILE_LIMITS.voice, { error: "voice must be at most 200 characters" }).optional(),
15084
15089
  speakReplies: external_exports.boolean({ error: "speakReplies must be true or false" }).optional()
@@ -16014,6 +16019,76 @@ var remoteMutationSchema = remoteEntrySchema.extend({
16014
16019
  headers: external_exports.record(external_exports.string(), external_exports.union([external_exports.string().max(16384), external_exports.literal(true)])).optional()
16015
16020
  });
16016
16021
 
16022
+ // server/cloud-overflow.ts
16023
+ var CLOUD_SEAT_IDLE_STOP_MS = 5 * 6e4;
16024
+ var CLOUD_SEAT_SLEEP_RETRY_MAX_MS = 10 * 6e4;
16025
+
16026
+ // server/proxy-paths.ts
16027
+ import { existsSync as existsSync2 } from "node:fs";
16028
+ import { dirname as dirname2, join as join2 } from "node:path";
16029
+ import { fileURLToPath } from "node:url";
16030
+ var SERVER_ROOT = dirname2(fileURLToPath(import.meta.url));
16031
+ function resolveProxy(relative) {
16032
+ const source = join2(SERVER_ROOT, `${relative}.ts`);
16033
+ return existsSync2(source) ? source : join2(SERVER_ROOT, `${relative}.js`);
16034
+ }
16035
+ var SPAWNED_PROXIES = {
16036
+ browser: resolveProxy("browser-proxy"),
16037
+ localComputer: resolveProxy("local-computer-proxy"),
16038
+ permission: resolveProxy("permission-proxy"),
16039
+ containerMcp: resolveProxy("container-mcp"),
16040
+ vpsContainerMcp: resolveProxy("vps-container-mcp"),
16041
+ agents: resolveProxy("drivers/agents-proxy"),
16042
+ dweb: resolveProxy("drivers/dweb-proxy"),
16043
+ connectors: resolveProxy("connector-proxy"),
16044
+ mcpGate: resolveProxy("mcp-gate"),
16045
+ phone: resolveProxy("drivers/phone-proxy"),
16046
+ hook: resolveProxy("hooks/omb-hook"),
16047
+ // Loaded by the external `pi` process via `-e`, not by this server — but
16048
+ // resolved through the same single source of truth so the packaged layout
16049
+ // check can assert it ships.
16050
+ piMcpExtension: resolveProxy("drivers/pi-mcp-extension")
16051
+ };
16052
+
16053
+ // server/enterprise.ts
16054
+ var layerSchema = external_exports.object({
16055
+ customer: external_exports.string().min(1),
16056
+ features: external_exports.array(external_exports.string().min(1)),
16057
+ expiresAt: external_exports.string().nullable()
16058
+ });
16059
+ var DAY_MS = 24 * 60 * 6e4;
16060
+
16061
+ // server/sessions.ts
16062
+ var PAIRING_CODE_TTL_MS = 5 * 6e4;
16063
+ function daysMs(value, fallbackDays) {
16064
+ const days = Number(value);
16065
+ const ok = Number.isInteger(days) && days >= 1 && days <= 3650;
16066
+ return (ok ? days : fallbackDays) * 24 * 60 * 6e4;
16067
+ }
16068
+ var SESSION_TTL_MS = daysMs(process.env.OMB_SESSION_TTL_DAYS, 30);
16069
+ var SESSION_MAX_AGE_MS = daysMs(process.env.OMB_SESSION_MAX_DAYS, 180);
16070
+ var SESSION_RENEW_WHEN_LEFT_MS = SESSION_TTL_MS / 2;
16071
+ var STREAM_TICKET_TTL_MS = 5 * 6e4;
16072
+ var scopeSchema = external_exports.enum(["admin", "client"]);
16073
+ var sessionSchema = external_exports.object({
16074
+ id: external_exports.string().min(1),
16075
+ tokenHash: external_exports.string().length(64),
16076
+ label: external_exports.string().max(80),
16077
+ scopes: external_exports.array(scopeSchema).min(1),
16078
+ createdAt: external_exports.number(),
16079
+ lastSeenAt: external_exports.number(),
16080
+ expiresAt: external_exports.number(),
16081
+ /** Set when the session came from an account sign-in rather than a code. */
16082
+ userId: external_exports.string().max(256).optional(),
16083
+ email: external_exports.string().max(320).optional(),
16084
+ /** Set only by the internal verified-portal issuance path, never by email or pairing input. */
16085
+ membershipAuthority: external_exports.literal("portal").optional()
16086
+ });
16087
+ var fileSchema = external_exports.object({ version: external_exports.literal(1), sessions: external_exports.array(sessionSchema) });
16088
+
16089
+ // server/cloud-home.ts
16090
+ var CLOUD_PAIRING_NONCE_MS = 10 * 6e4;
16091
+
16017
16092
  // server/config.ts
16018
16093
  var optionalText = external_exports.string().optional();
16019
16094
  var SSH_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
@@ -16055,7 +16130,8 @@ var browserEngineConfigSchema = external_exports.object({
16055
16130
  var roomConfigSchema = external_exports.object({
16056
16131
  turnTimeoutMinutes: external_exports.number().int().min(MIN_ROOM_TURN_TIMEOUT_MINUTES).max(MAX_ROOM_TURN_TIMEOUT_MINUTES),
16057
16132
  /** Room handoff tree lifetime. Active execution pauses this clock; the
16058
- * hard cap is wall-clock and bounds trees that never stop executing. */
16133
+ * hard cap is the maximum stall window, measured wall-clock from the
16134
+ * tree's last durable progress. */
16059
16135
  handoffLifetimeMinutes: external_exports.number().int().min(1).max(MAX_ROOM_TURN_TIMEOUT_MINUTES).optional(),
16060
16136
  handoffMinRunwayMinutes: external_exports.number().int().min(1).max(MAX_ROOM_TURN_TIMEOUT_MINUTES).optional(),
16061
16137
  handoffHardCapMinutes: external_exports.number().int().min(1).max(7 * MAX_ROOM_TURN_TIMEOUT_MINUTES).optional()
@@ -16064,7 +16140,7 @@ var roomConfigSchema = external_exports.object({
16064
16140
  { message: "rooms handoff bounds must satisfy handoffMinRunwayMinutes <= handoffLifetimeMinutes <= handoffHardCapMinutes" }
16065
16141
  );
16066
16142
  var localVmConfigSchema = external_exports.object({
16067
- mode: external_exports.enum(["shared", "per-bot"]).optional(),
16143
+ mode: external_exports.enum(["shared", "per-bot", "pool"]).optional(),
16068
16144
  maxInstances: external_exports.number().int().min(MIN_LOCAL_VM_MAX_INSTANCES).max(MAX_LOCAL_VM_MAX_INSTANCES).optional()
16069
16145
  });
16070
16146
  var browserProfileSchema = external_exports.object({
@@ -16183,6 +16259,10 @@ var featureConfigSchema = external_exports.object({
16183
16259
  skillAuthoring: external_exports.boolean().optional(),
16184
16260
  /** Show each tool run in the transcript. Off unless explicitly enabled. */
16185
16261
  showToolCalls: external_exports.boolean().optional(),
16262
+ /** Run a routine inside the conversation it reports to, instead of a hidden
16263
+ * thread. Off unless explicitly enabled. The run still starts from its own
16264
+ * instructions, but the messages stay in that chat. */
16265
+ routinesInConversation: external_exports.boolean().optional(),
16186
16266
  /** Experimental built-in browser. Off until explicitly enabled; each bot
16187
16267
  * also has its own switch. */
16188
16268
  browser: external_exports.boolean().optional(),
@@ -16196,8 +16276,23 @@ var featureConfigSchema = external_exports.object({
16196
16276
  claudeUserMcp: external_exports.boolean().optional(),
16197
16277
  /** LLM-generated titles for new bot threads. Off until explicitly
16198
16278
  * enabled; a one-shot that fails or answers junk leaves the first-message
16199
- * snippet in place — see llmThreadTitlesEnabled. */
16200
- llmThreadTitles: external_exports.boolean().optional()
16279
+ * snippet in place — see llmThreadTitlesEnabled. */
16280
+ llmThreadTitles: external_exports.boolean().optional(),
16281
+ /** Before each turn, passages from the bot's own memory files and earlier
16282
+ * conversations that share words with the message ride into the turn.
16283
+ * Read-only; on unless explicitly switched off — see autoRecallEnabled. */
16284
+ autoRecall: external_exports.boolean().optional(),
16285
+ /** Idle release for computer claims (#1653): a desktop seat that stays
16286
+ * screen-quiet for 90 seconds is released to waiting turns while its
16287
+ * holder's turn still lives; the previous holder re-claims directly
16288
+ * for 10 minutes and yields to an occupied seat. Off until baked; see
16289
+ * computerClaimIdleReleaseEnabled for how to enable it by hand. */
16290
+ computerClaimIdleRelease: external_exports.boolean().optional(),
16291
+ /** Consented cloud overflow for local computer waits (#1655): a wait
16292
+ * may offer a per-second-billed cloud seat, but only through an explicit
16293
+ * consent card or a configured allowlist — never a silent Auto default.
16294
+ * Off until baked; see cloudOverflowEnabled for how to enable it by hand. */
16295
+ cloudOverflow: external_exports.boolean().optional()
16201
16296
  });
16202
16297
  var onboardingConfigSchema = external_exports.object({
16203
16298
  /** ISO timestamp of finishing (or skipping to the end of) the welcome flow. */
@@ -16304,6 +16399,8 @@ var appConfigSchema = external_exports.object({
16304
16399
  /** Project key used for Sessions, catalog and agent tools. userId/sessionId
16305
16400
  * are non-secret local identifiers used to reuse one Composio Session. */
16306
16401
  composio: external_exports.object({ apiKey: optionalText, userId: optionalText, sessionId: optionalText }).optional(),
16402
+ /** Historical config section name "box" (the persisted config.json key); the
16403
+ * provider is Boat now and the key is kept for compatibility. */
16307
16404
  box: external_exports.object({ token: optionalText }).optional(),
16308
16405
  vps: vpsConfigSchema.optional(),
16309
16406
  /** Optional OpenCode key; persisted write-only and passed only to its child. */
@@ -16323,6 +16420,19 @@ var appConfigSchema = external_exports.object({
16323
16420
  baseUrl: external_exports.string().trim().max(2048).refine((value) => !value || /^https?:\/\//i.test(value), "the Chatterbox server address must start with http:// or https://").optional(),
16324
16421
  model: optionalText
16325
16422
  }).optional(),
16423
+ /** The decision model (server/decider): a fast classifier that picks
16424
+ * things for bots, starting with who answers a room message. `key` is
16425
+ * write-only like every credential; `baseUrl` points at a Jev-compatible
16426
+ * server instead of TypeSafe's (an operator setting with no UI); `jobs`
16427
+ * switches each decision on or off. Not `decisions`: that section is the
16428
+ * authorization log's retention. */
16429
+ decider: external_exports.object({
16430
+ enabled: external_exports.boolean().optional(),
16431
+ provider: external_exports.enum(["jev", "off"]).optional(),
16432
+ key: optionalText,
16433
+ baseUrl: external_exports.string().trim().max(2048).refine((value) => !value || /^https?:\/\//i.test(value), "the decision model address must start with http:// or https://").optional(),
16434
+ jobs: external_exports.object({ roomRouting: external_exports.boolean().optional() }).optional()
16435
+ }).optional(),
16326
16436
  /** Avatar provider credentials stay separate; choosing a router never reuses a cloud key. */
16327
16437
  imageGen: external_exports.object({
16328
16438
  provider: external_exports.enum(["openai", "xai", "custom"]).optional(),
@@ -16353,10 +16463,26 @@ var appConfigSchema = external_exports.object({
16353
16463
  compactAt: external_exports.number().positive().max(1e7).optional(),
16354
16464
  autoCompact: external_exports.boolean().optional()
16355
16465
  }).optional(),
16466
+ /** Memory upkeep timing, for bots with Memory upkeep switched on. */
16467
+ memory: external_exports.object({
16468
+ /** Quiet time after a turn before its facts are captured (ms). */
16469
+ captureQuietMs: external_exports.number().int().min(1e3).max(24 * 60 * 6e4).optional(),
16470
+ /** Local hour (0-23) after which the nightly tidy-up runs. */
16471
+ tidyHour: external_exports.number().int().min(0).max(23).optional()
16472
+ }).strict().optional(),
16356
16473
  threads: threadsConfigSchema.optional(),
16357
16474
  /** The authorization decision log (server/decision-log.ts): days of month
16358
16475
  * files kept, at least; OMB_DECISION_RETENTION_DAYS wins when set. */
16359
16476
  decisions: external_exports.object({ retentionDays: external_exports.number().int().min(1).max(3650).optional() }).strict().optional(),
16477
+ /** #1655 cloud-overflow settings. perSecondCostUsd is the operator's own
16478
+ * verified rate: with no price configured the feature stays inert rather
16479
+ * than show an invented one. allowlistedThreads carries standing consent
16480
+ * for exact thread ids. */
16481
+ cloudOverflow: external_exports.object({
16482
+ perSecondCostUsd: external_exports.number().positive().max(10).optional(),
16483
+ idleStopMs: external_exports.number().int().positive().max(24 * 60 * 6e4).optional(),
16484
+ allowlistedThreads: external_exports.array(external_exports.string().min(1)).max(1e3).optional()
16485
+ }).strict().optional(),
16360
16486
  localVm: localVmConfigSchema.optional(),
16361
16487
  features: featureConfigSchema.optional(),
16362
16488
  onboarding: onboardingConfigSchema.optional(),
@@ -16375,37 +16501,11 @@ var storedAppConfigSchema = appConfigSchema.extend({
16375
16501
  });
16376
16502
  var appConfigPatchSchema = appConfigSchema.omit({ instances: true, mcpServers: true, cliStartup: true, customDomain: true }).extend({ threads: threadsPatchSchema.optional(), newBots: newBotsPatchSchema.optional() });
16377
16503
  var jsonObjectSchema = external_exports.record(external_exports.string(), external_exports.json());
16378
- var DATA_DIR = process.env.OMB_DATA_DIR ?? join2(homedir2(), ".openmausbot");
16379
- var LEGACY_DATA_DIR = join2(homedir2(), ".opengrokbot");
16380
- var EVENTS_DIR = join2(DATA_DIR, "events");
16381
- var NATIVE_DIR = join2(DATA_DIR, "native");
16382
-
16383
- // server/proxy-paths.ts
16384
- import { existsSync as existsSync2 } from "node:fs";
16385
- import { dirname as dirname2, join as join3 } from "node:path";
16386
- import { fileURLToPath } from "node:url";
16387
- var SERVER_ROOT = dirname2(fileURLToPath(import.meta.url));
16388
- function resolveProxy(relative) {
16389
- const source = join3(SERVER_ROOT, `${relative}.ts`);
16390
- return existsSync2(source) ? source : join3(SERVER_ROOT, `${relative}.js`);
16391
- }
16392
- var SPAWNED_PROXIES = {
16393
- browser: resolveProxy("browser-proxy"),
16394
- localComputer: resolveProxy("local-computer-proxy"),
16395
- permission: resolveProxy("permission-proxy"),
16396
- containerMcp: resolveProxy("container-mcp"),
16397
- vpsContainerMcp: resolveProxy("vps-container-mcp"),
16398
- agents: resolveProxy("drivers/agents-proxy"),
16399
- dweb: resolveProxy("drivers/dweb-proxy"),
16400
- connectors: resolveProxy("connector-proxy"),
16401
- mcpGate: resolveProxy("mcp-gate"),
16402
- phone: resolveProxy("drivers/phone-proxy"),
16403
- hook: resolveProxy("hooks/omb-hook"),
16404
- // Loaded by the external `pi` process via `-e`, not by this server — but
16405
- // resolved through the same single source of truth so the packaged layout
16406
- // check can assert it ships.
16407
- piMcpExtension: resolveProxy("drivers/pi-mcp-extension")
16408
- };
16504
+ var DEFAULT_CAPTURE_QUIET_MS = 2 * 6e4;
16505
+ var DATA_DIR = process.env.OMB_DATA_DIR ?? join3(homedir2(), ".openmausbot");
16506
+ var LEGACY_DATA_DIR = join3(homedir2(), ".opengrokbot");
16507
+ var EVENTS_DIR = join3(DATA_DIR, "events");
16508
+ var NATIVE_DIR = join3(DATA_DIR, "native");
16409
16509
 
16410
16510
  // server/container-computer.ts
16411
16511
  var run = promisify(execFile2);