openmausbot 0.1.90 → 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 (112) hide show
  1. package/dist/assets/{abnfDiagram-O67JEVCF-DUyXd0kL.js → abnfDiagram-O67JEVCF-yP-w8pRq.js} +1 -1
  2. package/dist/assets/{arc-q73qM-At.js → arc-DsivfZEh.js} +1 -1
  3. package/dist/assets/{architectureDiagram-NJMV4G6O-D33O3Wur.js → architectureDiagram-NJMV4G6O-CILw7lzT.js} +1 -1
  4. package/dist/assets/{blockDiagram-BEXU5L5S-DLsJeoXC.js → blockDiagram-BEXU5L5S-DEQUV3HF.js} +1 -1
  5. package/dist/assets/{c4Diagram-YGBWAQC7-DnaljZnu.js → c4Diagram-YGBWAQC7-lSXCZoKA.js} +1 -1
  6. package/dist/assets/channel-DrfGMu7X.js +1 -0
  7. package/dist/assets/{chunk-2Q5K7J3B-Da0h2i79.js → chunk-2Q5K7J3B-QCD5bgWP.js} +1 -1
  8. package/dist/assets/{chunk-3FUC2YCW-CfzHi54f.js → chunk-3FUC2YCW-C5-iZJuL.js} +2 -2
  9. package/dist/assets/{chunk-5VM5RSS4-LjE4d9Jf.js → chunk-5VM5RSS4-cxsawMpY.js} +1 -1
  10. package/dist/assets/{chunk-GTNCS2PH-DY-UGmvc.js → chunk-GTNCS2PH-DV8tV8H7.js} +1 -1
  11. package/dist/assets/{chunk-GWA4HPMP-BqeGhyhP.js → chunk-GWA4HPMP-CJFZyfbW.js} +1 -1
  12. package/dist/assets/{chunk-JWPE2WC7-BYa9EBAg.js → chunk-JWPE2WC7-BigbMXco.js} +1 -1
  13. package/dist/assets/{chunk-NETBCI7D-vTrDtWyb.js → chunk-NETBCI7D-oVxTfpDy.js} +1 -1
  14. package/dist/assets/{chunk-WEXAMYUT-ic5tXadM.js → chunk-WEXAMYUT-CH4BiroW.js} +1 -1
  15. package/dist/assets/{chunk-XXDRQBXY-DvRCY-c6.js → chunk-XXDRQBXY-KEDa6gax.js} +1 -1
  16. package/dist/assets/{classDiagram-v2-NBCMYWYE-DVbmgz_L.js → classDiagram-v2-NBCMYWYE-BiPjfqVv.js} +1 -1
  17. package/dist/assets/{cose-bilkent-JH36ORCC-vdUs2n57.js → cose-bilkent-JH36ORCC-Caxew3OY.js} +1 -1
  18. package/dist/assets/{cynefin-OW5HDTMX-BvLGlV3U.js → cynefin-OW5HDTMX-B_Pui369.js} +1 -1
  19. package/dist/assets/{cynefinDiagram-VND7K2PF-C4GcJQDt.js → cynefinDiagram-VND7K2PF-X64ydIhP.js} +1 -1
  20. package/dist/assets/{dagre-6A5THRUB-BMSaHpt_.js → dagre-6A5THRUB-TqYCI1E1.js} +1 -1
  21. package/dist/assets/{diagram-22UHCM2B-D5b9UBhC.js → diagram-22UHCM2B-TeOt3rAQ.js} +1 -1
  22. package/dist/assets/{diagram-3UASUU5V-CIKLlB7Y.js → diagram-3UASUU5V-D70BLhDA.js} +1 -1
  23. package/dist/assets/{diagram-ATOU4E4O-BzXb-7k7.js → diagram-ATOU4E4O-BbQDLwUC.js} +1 -1
  24. package/dist/assets/{diagram-CDSNMT55-HsTvJ7uT.js → diagram-CDSNMT55-ChNJZ1u-.js} +1 -1
  25. package/dist/assets/{diagram-MLGK6HIB-Db9ySNbQ.js → diagram-MLGK6HIB-DMBl2APa.js} +1 -1
  26. package/dist/assets/{diagram-MPIPVDR6-D6BKbpqY.js → diagram-MPIPVDR6-CEqDchOp.js} +1 -1
  27. package/dist/assets/{ebnfDiagram-ZINNZB2B-Bq067L0t.js → ebnfDiagram-ZINNZB2B-BVDKRp_-.js} +1 -1
  28. package/dist/assets/{elk-276RUBZZ-DhaD7fNJ.js → elk-276RUBZZ-CRkofO9B.js} +1 -1
  29. package/dist/assets/{erDiagram-OPXOYQCR-fwIhfz36.js → erDiagram-OPXOYQCR-DruOMh5e.js} +1 -1
  30. package/dist/assets/{flowDiagram-KWPJA3E3-DygIyu0V.js → flowDiagram-KWPJA3E3-8GMQeB7t.js} +1 -1
  31. package/dist/assets/{ganttDiagram-FUAMR5RP-DPYfSO96.js → ganttDiagram-FUAMR5RP-ORE9jcsM.js} +1 -1
  32. package/dist/assets/{gitGraphDiagram-X574FWY7-DhkHeCle.js → gitGraphDiagram-X574FWY7-BmsedsWh.js} +1 -1
  33. package/dist/assets/index-BlnCEcU6.js +588 -0
  34. package/dist/assets/{index-G1PHKGyh.js → index-DKNEM8Q6.js} +1 -1
  35. package/dist/assets/index-DVxjOvID.css +1 -0
  36. package/dist/assets/{infoDiagram-VRGFBTTK-DstBLxME.js → infoDiagram-VRGFBTTK-E_p7AooJ.js} +1 -1
  37. package/dist/assets/{ishikawaDiagram-OU5B5YK6-CrIsGgch.js → ishikawaDiagram-OU5B5YK6-Y-B2mKda.js} +1 -1
  38. package/dist/assets/{journeyDiagram-ZHPQQLJL-CYypGDbB.js → journeyDiagram-ZHPQQLJL-eA8RELcK.js} +1 -1
  39. package/dist/assets/{kanban-definition-PNTS6WVX-DGjPt8E_.js → kanban-definition-PNTS6WVX-DqIL2e8e.js} +1 -1
  40. package/dist/assets/{linear-Dwc3Hrru.js → linear-yC_29R6e.js} +1 -1
  41. package/dist/assets/{mermaid.core-Dc4OePBL.js → mermaid.core-VhEMkSND.js} +5 -5
  42. package/dist/assets/{mindmap-definition-NLK3R4M7-DV-vepj-.js → mindmap-definition-NLK3R4M7-oJ7kyQZy.js} +1 -1
  43. package/dist/assets/{pegDiagram-GJSIUBJH-lx5Kj-n5.js → pegDiagram-GJSIUBJH-BmfYcY0O.js} +1 -1
  44. package/dist/assets/{pieDiagram-5QR66LMP-Bq7Vmm15.js → pieDiagram-5QR66LMP-DKvgP7w9.js} +1 -1
  45. package/dist/assets/{quadrantDiagram-O4NWA36T-DeqeqOBj.js → quadrantDiagram-O4NWA36T-BEKL3W0L.js} +1 -1
  46. package/dist/assets/{railroadDiagram-XR7U4H2S-CXwRQzSC.js → railroadDiagram-XR7U4H2S-BEsiqR5s.js} +1 -1
  47. package/dist/assets/{requirementDiagram-PLB6GJNP-8tAeoB88.js → requirementDiagram-PLB6GJNP-DWBcWvAP.js} +1 -1
  48. package/dist/assets/{sankeyDiagram-IPEJSGJF-BG5zjGWU.js → sankeyDiagram-IPEJSGJF-rpZ2_O4s.js} +1 -1
  49. package/dist/assets/{sequenceDiagram-PO4LG4MO-DKF3iLcw.js → sequenceDiagram-PO4LG4MO-B99HQdJR.js} +1 -1
  50. package/dist/assets/{sizeCapture-INFHLROL-B-y1qUgT.js → sizeCapture-INFHLROL-BjN0qT5T.js} +1 -1
  51. package/dist/assets/{stateDiagram-v2-GCMORJYK-MkzPgxAc.js → stateDiagram-v2-GCMORJYK-BbsVgGsC.js} +1 -1
  52. package/dist/assets/{swimlanes-2SLR337P-DnbaOEwH.js → swimlanes-2SLR337P-DG3gKkeR.js} +1 -1
  53. package/dist/assets/swimlanesDiagram-TC7HE7FX-BCZhxl7e.js +8 -0
  54. package/dist/assets/{timeline-definition-EJHVYXUP-Bb4xG_Bt.js → timeline-definition-EJHVYXUP-BTHOdtF_.js} +1 -1
  55. package/dist/assets/{usecaseDiagram-POWQR4AR-JgkR9pFf.js → usecaseDiagram-POWQR4AR-acLSLFwc.js} +1 -1
  56. package/dist/assets/{vennDiagram-UO4OBE2U-CIPIrAYe.js → vennDiagram-UO4OBE2U-C5JzNX9G.js} +1 -1
  57. package/dist/assets/{wardleyDiagram-VNRHLVJA-BjCLuUvJ.js → wardleyDiagram-VNRHLVJA-DL1-PrR_.js} +1 -1
  58. package/dist/assets/{xychartDiagram-PMCCYNJV-DKgiaYxT.js → xychartDiagram-PMCCYNJV-Bvr1477p.js} +1 -1
  59. package/dist/index.html +2 -2
  60. package/dist-server/cloud-home-start.js +18 -3
  61. package/dist-server/container-mcp.js +84 -32
  62. package/dist-server/drivers/agents-proxy.js +11 -0
  63. package/dist-server/index.js +25183 -23580
  64. package/dist-server/openmausbot.js +313 -159
  65. package/dist-server/pair-cli.js +313 -159
  66. package/dist-server/server/boat.js +66 -21
  67. package/dist-server/server/bot-overview.js +7 -4
  68. package/dist-server/server/cloud-home-start.js +23 -5
  69. package/dist-server/server/cloud-home.js +25 -2
  70. package/dist-server/server/cloud-lending.js +103 -0
  71. package/dist-server/server/cloud-move-http.js +268 -0
  72. package/dist-server/server/cloud-move.js +418 -0
  73. package/dist-server/server/config.js +42 -4
  74. package/dist-server/server/decider/index.js +238 -0
  75. package/dist-server/server/decider/jev.js +183 -0
  76. package/dist-server/server/decider/log.js +62 -0
  77. package/dist-server/server/decider/relay.js +52 -0
  78. package/dist-server/server/decider/room-routing.js +88 -0
  79. package/dist-server/server/decider/types.js +5 -0
  80. package/dist-server/server/drivers/agents-catalog.js +16 -0
  81. package/dist-server/server/drivers/boatagent.js +20 -12
  82. package/dist-server/server/drivers/claude.js +1 -0
  83. package/dist-server/server/group-goal-run.js +6 -4
  84. package/dist-server/server/harness-capabilities.js +2 -0
  85. package/dist-server/server/included-services.js +70 -0
  86. package/dist-server/server/index.js +438 -102
  87. package/dist-server/server/model-context-window.js +4 -4
  88. package/dist-server/server/package-export.js +17 -10
  89. package/dist-server/server/package-import.js +6 -3
  90. package/dist-server/server/package-parts.js +3 -1
  91. package/dist-server/server/request-auth.js +2 -0
  92. package/dist-server/server/routes/decider.js +19 -0
  93. package/dist-server/server/shared-computers.js +116 -30
  94. package/dist-server/server/store.js +17 -2
  95. package/dist-server/server/surface.js +13 -0
  96. package/dist-server/server/system-prompt.js +11 -0
  97. package/dist-server/server/team-backup.js +6 -2
  98. package/dist-server/server/team-manifest.js +11 -3
  99. package/dist-server/server/tts/elevenlabs.js +11 -6
  100. package/dist-server/server/tts/index.js +17 -10
  101. package/dist-server/server/workspace-backup-policy.js +22 -3
  102. package/dist-server/server/workspace-backup.js +25 -8
  103. package/dist-server/shared/cloud-home.js +4 -0
  104. package/dist-server/shared/package-format.js +30 -4
  105. package/dist-server/shared/team-backup.js +20 -3
  106. package/dist-server/vps-container-mcp.js +84 -32
  107. package/dist-server/workspace-backup.worker.js +113 -31
  108. package/package.json +1 -1
  109. package/dist/assets/channel-BCuyHjFV.js +0 -1
  110. package/dist/assets/index-CRvo-DS2.css +0 -1
  111. package/dist/assets/index-CWYGlA63.js +0 -588
  112. package/dist/assets/swimlanesDiagram-TC7HE7FX-BZQ07DGE.js +0 -8
@@ -16318,6 +16318,25 @@ var init_proxy_paths = __esm({
16318
16318
  }
16319
16319
  });
16320
16320
 
16321
+ // server/enterprise.ts
16322
+ function hostedWorkspaceConfigured(env = process.env) {
16323
+ return env.OMB_ADMIN_URL !== void 0 || env.OMB_ADMIN_WORKSPACE !== void 0 || env.OMB_ADMIN_MEMBERSHIP !== void 0;
16324
+ }
16325
+ var layerSchema, DAY_MS3;
16326
+ var init_enterprise = __esm({
16327
+ "server/enterprise.ts"() {
16328
+ "use strict";
16329
+ init_zod();
16330
+ init_proxy_paths();
16331
+ layerSchema = external_exports.object({
16332
+ customer: external_exports.string().min(1),
16333
+ features: external_exports.array(external_exports.string().min(1)),
16334
+ expiresAt: external_exports.string().nullable()
16335
+ });
16336
+ DAY_MS3 = 24 * 60 * 6e4;
16337
+ }
16338
+ });
16339
+
16321
16340
  // server/atomic.ts
16322
16341
  import { randomUUID as randomUUID3 } from "node:crypto";
16323
16342
  import { closeSync, fsyncSync, openSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
@@ -17530,7 +17549,7 @@ function displayText(value, multiline = false) {
17530
17549
  }
17531
17550
  function plainText(question, hidden, context) {
17532
17551
  const { input, output, signal } = context;
17533
- return new Promise((resolve12, reject) => {
17552
+ return new Promise((resolve13, reject) => {
17534
17553
  input.setRawMode?.(hidden);
17535
17554
  const rl = createInterface({ input, terminal: hidden });
17536
17555
  let finished = false;
@@ -17541,7 +17560,7 @@ function plainText(question, hidden, context) {
17541
17560
  rl.close();
17542
17561
  output.write("\n");
17543
17562
  if (error51) reject(error51);
17544
- else resolve12(answer ?? "");
17563
+ else resolve13(answer ?? "");
17545
17564
  };
17546
17565
  const cancel = () => finish(void 0, signal.reason ?? new SetupCancelled());
17547
17566
  signal.addEventListener("abort", cancel, { once: true });
@@ -18817,6 +18836,62 @@ var init_cloud_overflow = __esm({
18817
18836
  }
18818
18837
  });
18819
18838
 
18839
+ // server/sessions.ts
18840
+ function daysMs(value, fallbackDays) {
18841
+ const days = Number(value);
18842
+ const ok = Number.isInteger(days) && days >= 1 && days <= 3650;
18843
+ return (ok ? days : fallbackDays) * 24 * 60 * 6e4;
18844
+ }
18845
+ var PAIRING_CODE_TTL_MS, SESSION_TTL_MS, SESSION_MAX_AGE_MS, SESSION_RENEW_WHEN_LEFT_MS, STREAM_TICKET_TTL_MS, scopeSchema, sessionSchema, fileSchema;
18846
+ var init_sessions = __esm({
18847
+ "server/sessions.ts"() {
18848
+ "use strict";
18849
+ init_zod();
18850
+ init_atomic();
18851
+ PAIRING_CODE_TTL_MS = 5 * 6e4;
18852
+ SESSION_TTL_MS = daysMs(process.env.OMB_SESSION_TTL_DAYS, 30);
18853
+ SESSION_MAX_AGE_MS = daysMs(process.env.OMB_SESSION_MAX_DAYS, 180);
18854
+ SESSION_RENEW_WHEN_LEFT_MS = SESSION_TTL_MS / 2;
18855
+ STREAM_TICKET_TTL_MS = 5 * 6e4;
18856
+ scopeSchema = external_exports.enum(["admin", "client"]);
18857
+ sessionSchema = external_exports.object({
18858
+ id: external_exports.string().min(1),
18859
+ tokenHash: external_exports.string().length(64),
18860
+ label: external_exports.string().max(80),
18861
+ scopes: external_exports.array(scopeSchema).min(1),
18862
+ createdAt: external_exports.number(),
18863
+ lastSeenAt: external_exports.number(),
18864
+ expiresAt: external_exports.number(),
18865
+ /** Set when the session came from an account sign-in rather than a code. */
18866
+ userId: external_exports.string().max(256).optional(),
18867
+ email: external_exports.string().max(320).optional(),
18868
+ /** Set only by the internal verified-portal issuance path, never by email or pairing input. */
18869
+ membershipAuthority: external_exports.literal("portal").optional()
18870
+ });
18871
+ fileSchema = external_exports.object({ version: external_exports.literal(1), sessions: external_exports.array(sessionSchema) });
18872
+ }
18873
+ });
18874
+
18875
+ // shared/cloud-home.ts
18876
+ var init_cloud_home = __esm({
18877
+ "shared/cloud-home.ts"() {
18878
+ "use strict";
18879
+ }
18880
+ });
18881
+
18882
+ // server/cloud-home.ts
18883
+ var CLOUD_PAIRING_NONCE_MS;
18884
+ var init_cloud_home2 = __esm({
18885
+ "server/cloud-home.ts"() {
18886
+ "use strict";
18887
+ init_atomic();
18888
+ init_enterprise();
18889
+ init_sessions();
18890
+ init_cloud_home();
18891
+ CLOUD_PAIRING_NONCE_MS = 10 * 6e4;
18892
+ }
18893
+ });
18894
+
18820
18895
  // server/config.ts
18821
18896
  import { readFileSync as readFileSync3, mkdirSync as mkdirSync6, existsSync as existsSync6, renameSync as renameSync3 } from "node:fs";
18822
18897
  import { homedir as homedir4 } from "node:os";
@@ -18996,6 +19071,8 @@ function loadConfig() {
18996
19071
  const presetVoice = process.env.OMB_TTS_DEFAULT_VOICE?.trim();
18997
19072
  if (presetVoice && !cfg.tts.voice?.trim() && (cfg.tts.provider ?? "elevenlabs") === "elevenlabs") cfg.tts.voice = presetVoice;
18998
19073
  if (process.env.OMB_FISH_AUDIO_API_KEY !== void 0) cfg.tts.fishKey = process.env.OMB_FISH_AUDIO_API_KEY;
19074
+ cfg.decider = { ...cfg.decider };
19075
+ if (process.env.OMB_JEV_API_KEY !== void 0) cfg.decider.key = process.env.OMB_JEV_API_KEY;
18999
19076
  cfg.imageGen = { ...cfg.imageGen };
19000
19077
  if (process.env.OMB_OPENAI_IMAGE_KEY !== void 0) cfg.imageGen.key = process.env.OMB_OPENAI_IMAGE_KEY;
19001
19078
  if (process.env.OMB_CUSTOM_IMAGE_KEY !== void 0) cfg.imageGen.customApiKey = process.env.OMB_CUSTOM_IMAGE_KEY;
@@ -19029,7 +19106,7 @@ function saveConfig(patch, options = {}) {
19029
19106
  const before = configSaveListeners.size ? structuredClone(disk) : disk;
19030
19107
  const storedProfiles = storedBrowserProfilesSchema.safeParse(disk.browserProfiles);
19031
19108
  if (storedProfiles.success) disk.browserProfiles = storedProfiles.data;
19032
- for (const key of ["xai", "anthropic", "mistral", "openaiCompat", "composio", "box", "opencodeGo", "tts", "imageGen", "profile", "rooms", "threads", "context", "memory", "localVm", "features", "cloudOverflow", "budgets", "billing", "decisions", "onboarding", "browserEngine", "newBots"]) {
19109
+ for (const key of ["xai", "anthropic", "mistral", "openaiCompat", "composio", "box", "opencodeGo", "tts", "decider", "imageGen", "profile", "rooms", "threads", "context", "memory", "localVm", "features", "cloudOverflow", "budgets", "billing", "decisions", "onboarding", "browserEngine", "newBots"]) {
19033
19110
  const section = checkedPatch[key];
19034
19111
  if (!section) continue;
19035
19112
  const current = jsonObjectSchema.safeParse(disk[key]);
@@ -19215,6 +19292,7 @@ var init_config = __esm({
19215
19292
  init_mcp_registry();
19216
19293
  init_schema();
19217
19294
  init_cloud_overflow();
19295
+ init_cloud_home2();
19218
19296
  optionalText = external_exports.string().optional();
19219
19297
  SSH_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
19220
19298
  LEGACY_BROWSER_PROFILE_ID = /^[A-Za-z0-9_-]{1,40}$/;
@@ -19458,6 +19536,19 @@ var init_config = __esm({
19458
19536
  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(),
19459
19537
  model: optionalText
19460
19538
  }).optional(),
19539
+ /** The decision model (server/decider): a fast classifier that picks
19540
+ * things for bots, starting with who answers a room message. `key` is
19541
+ * write-only like every credential; `baseUrl` points at a Jev-compatible
19542
+ * server instead of TypeSafe's (an operator setting with no UI); `jobs`
19543
+ * switches each decision on or off. Not `decisions`: that section is the
19544
+ * authorization log's retention. */
19545
+ decider: external_exports.object({
19546
+ enabled: external_exports.boolean().optional(),
19547
+ provider: external_exports.enum(["jev", "off"]).optional(),
19548
+ key: optionalText,
19549
+ 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(),
19550
+ jobs: external_exports.object({ roomRouting: external_exports.boolean().optional() }).optional()
19551
+ }).optional(),
19461
19552
  /** Avatar provider credentials stay separate; choosing a router never reuses a cloud key. */
19462
19553
  imageGen: external_exports.object({
19463
19554
  provider: external_exports.enum(["openai", "xai", "custom"]).optional(),
@@ -19545,10 +19636,17 @@ var init_config = __esm({
19545
19636
  "OPENCODE_API_KEY",
19546
19637
  "OMB_TTS_KEY",
19547
19638
  "OMB_FISH_AUDIO_API_KEY",
19639
+ "OMB_JEV_API_KEY",
19548
19640
  "OMB_OPENAI_IMAGE_KEY",
19549
19641
  "OMB_CUSTOM_IMAGE_KEY",
19550
19642
  "COMPOSIO_API_KEY",
19551
19643
  "OMB_COMPOSIO_BROKER_TOKEN",
19644
+ // Cloud Pro's included Boat, voice and decision relay tokens
19645
+ // (included-services.ts), used only in-process by the Boat, voice and
19646
+ // decider modules.
19647
+ "OMB_CLOUD_BOAT_TOKEN",
19648
+ "OMB_CLOUD_VOICE_TOKEN",
19649
+ "OMB_CLOUD_DECIDER_TOKEN",
19552
19650
  // Harness-private filesystem hints are not credentials themselves, but
19553
19651
  // exposing them to a shell-capable agent points straight at app-owned
19554
19652
  // state. The built-in browser master is delivered privately in memory.
@@ -19628,6 +19726,14 @@ function ownerPredatesThisBoot(owner) {
19628
19726
  function ownerIsAlive(owner) {
19629
19727
  return !ownerPredatesThisBoot(owner) && processIsAlive2(owner.pid) && ownerIdentityMatches(owner);
19630
19728
  }
19729
+ function sameMachine(record3) {
19730
+ if (record3.host === hostname4()) return true;
19731
+ const boot = bootSession();
19732
+ return boot !== null && typeof record3.boot === "string" && record3.boot === boot;
19733
+ }
19734
+ function otherMachineAdvice(path3) {
19735
+ return ` If OpenMausBot is not running on another computer that shares this folder, quit OpenMausBot, delete ${JSON.stringify(path3)} and start again.`;
19736
+ }
19631
19737
  function isLeaseOwner(value) {
19632
19738
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
19633
19739
  return value.version === 1 && isPid(value.pid) && typeof value.host === "string" && value.host.length > 0 && value.host.length <= 255 && !/[\r\n\0]/.test(value.host) && typeof value.token === "string" && UUID2.test(value.token) && typeof value.createdAt === "number" && Number.isFinite(value.createdAt) && value.createdAt > 0 && (value.boot === void 0 || isBootIdentity(value.boot)) && (value.uptime === void 0 || Number.isInteger(value.uptime) && value.uptime >= 0);
@@ -19773,7 +19879,7 @@ function claimReaperAuthority(leasePath, expected) {
19773
19879
  )) return true;
19774
19880
  const current = readReaper(reaperPath, expected.token);
19775
19881
  if (!current) continue;
19776
- if (current.host !== candidate.host) {
19882
+ if (!sameMachine(current)) {
19777
19883
  throw leaseError(
19778
19884
  `A stale OpenMausBot data-directory lease is being recovered on another machine. Recovery record: ${JSON.stringify(reaperPath)}.`
19779
19885
  );
@@ -19787,7 +19893,7 @@ function retireDeadOwner(leasePath, expected) {
19787
19893
  if (!claimReaperAuthority(leasePath, expected)) return false;
19788
19894
  const current = readOwner(leasePath);
19789
19895
  if (!current || current.token !== expected.token) return true;
19790
- if (current.host !== hostname4()) {
19896
+ if (!sameMachine(current)) {
19791
19897
  throw leaseError(
19792
19898
  `The stale OpenMausBot data-directory lease changed ownership to another machine. Lease record: ${JSON.stringify(leasePath)}.`
19793
19899
  );
@@ -19824,9 +19930,9 @@ function assertNoLiveDelegatedChild(dataDir) {
19824
19930
  const childLeasePath = join10(dataDir, DELEGATED_CHILD_DIR, LEASE_NAME);
19825
19931
  const child = readOwner(childLeasePath);
19826
19932
  if (!child) return;
19827
- if (child.host !== hostname4()) {
19933
+ if (!sameMachine(child)) {
19828
19934
  throw leaseError(
19829
- `This OpenMausBot data directory still has a delegated server on another machine. Delegated server lease: ${JSON.stringify(childLeasePath)}.`
19935
+ `This OpenMausBot data directory still has a delegated server on another machine. Delegated server lease: ${JSON.stringify(childLeasePath)}.${otherMachineAdvice(childLeasePath)}`
19830
19936
  );
19831
19937
  }
19832
19938
  if (ownerIsAlive(child)) {
@@ -19871,9 +19977,9 @@ function acquireDataDirLeaseInternal(dataDir, options = {}) {
19871
19977
  }
19872
19978
  const current = readOwner(leasePath);
19873
19979
  if (!current) continue;
19874
- if (current.host !== owner.host) {
19980
+ if (!sameMachine(current)) {
19875
19981
  throw leaseError(
19876
- `This OpenMausBot data directory is already owned by a process on another machine. Lease record: ${JSON.stringify(leasePath)}.`
19982
+ `This OpenMausBot data directory is already owned by a process on another machine. Lease record: ${JSON.stringify(leasePath)}.${otherMachineAdvice(leasePath)}`
19877
19983
  );
19878
19984
  }
19879
19985
  if (ownerIsAlive(current)) {
@@ -20309,7 +20415,7 @@ async function stopCliTree(child, pid, timeoutMs) {
20309
20415
  while (!settled()) {
20310
20416
  const remaining = deadline - Date.now();
20311
20417
  if (remaining <= 0) return false;
20312
- await new Promise((resolve12) => setTimeout(resolve12, Math.min(25, remaining)));
20418
+ await new Promise((resolve13) => setTimeout(resolve13, Math.min(25, remaining)));
20313
20419
  }
20314
20420
  return true;
20315
20421
  };
@@ -20320,7 +20426,7 @@ async function stopCliTree(child, pid, timeoutMs) {
20320
20426
  return wait2(1e3);
20321
20427
  }
20322
20428
  if (exited()) return true;
20323
- return new Promise((resolve12) => {
20429
+ return new Promise((resolve13) => {
20324
20430
  let timer;
20325
20431
  let finished = false;
20326
20432
  const done = (stopped) => {
@@ -20329,7 +20435,7 @@ async function stopCliTree(child, pid, timeoutMs) {
20329
20435
  clearTimeout(timer);
20330
20436
  child.off("close", closed);
20331
20437
  child.off("exit", closed);
20332
- resolve12(stopped);
20438
+ resolve13(stopped);
20333
20439
  };
20334
20440
  const closed = () => done(true);
20335
20441
  child.once("close", closed);
@@ -21624,13 +21730,13 @@ function computeBackoff(attempt, random = Math.random) {
21624
21730
  function interruptibleDelay(ms, signal) {
21625
21731
  let timer = null;
21626
21732
  let onCancel = null;
21627
- const promise2 = new Promise((resolve12) => {
21628
- timer = setTimeout(() => resolve12("elapsed"), Math.max(1, ms));
21733
+ const promise2 = new Promise((resolve13) => {
21734
+ timer = setTimeout(() => resolve13("elapsed"), Math.max(1, ms));
21629
21735
  timer.unref?.();
21630
- if (signal?.aborted) return resolve12("cancelled");
21736
+ if (signal?.aborted) return resolve13("cancelled");
21631
21737
  onCancel = () => {
21632
21738
  clearTimeout(timer);
21633
- resolve12("cancelled");
21739
+ resolve13("cancelled");
21634
21740
  };
21635
21741
  signal?.addEventListener("abort", onCancel, { once: true });
21636
21742
  });
@@ -22026,7 +22132,7 @@ function createAcpDriver(support11) {
22026
22132
  }
22027
22133
  appendNative(threadId, { dir: "out", source: SOURCE, msg: nativeLogMessage(obj) });
22028
22134
  };
22029
- const request = (method, params, timeoutMs, receive, idleMs, idleMessage) => new Promise((resolve12, reject) => {
22135
+ const request = (method, params, timeoutMs, receive, idleMs, idleMessage) => new Promise((resolve13, reject) => {
22030
22136
  const id = nextId++;
22031
22137
  let timer = null;
22032
22138
  if (timeoutMs) {
@@ -22059,7 +22165,7 @@ function createAcpDriver(support11) {
22059
22165
  // response may arrive before the awaiting continuation resumes.
22060
22166
  resolve: (result) => {
22061
22167
  receive?.(result);
22062
- resolve12(result);
22168
+ resolve13(result);
22063
22169
  },
22064
22170
  reject,
22065
22171
  timer,
@@ -22475,8 +22581,8 @@ function createAcpDriver(support11) {
22475
22581
  };
22476
22582
  let rejectStartup = (_error) => {
22477
22583
  };
22478
- const startupAck = turn.startupRecovery ? new Promise((resolve12, reject) => {
22479
- acknowledge = () => resolve12({ turnId });
22584
+ const startupAck = turn.startupRecovery ? new Promise((resolve13, reject) => {
22585
+ acknowledge = () => resolve13({ turnId });
22480
22586
  rejectStartup = reject;
22481
22587
  }) : null;
22482
22588
  const asks = /* @__PURE__ */ new Map();
@@ -22838,12 +22944,12 @@ ${promptInput.text}` : promptInput.text;
22838
22944
  const snapshot = async () => {
22839
22945
  const env = childEnv();
22840
22946
  if (support11.snapshot) return support11.snapshot(env, config2, instanceId);
22841
- const version2 = await new Promise((resolve12) => {
22947
+ const version2 = await new Promise((resolve13) => {
22842
22948
  execCli(
22843
22949
  config2.cli,
22844
22950
  ["--version"],
22845
22951
  { timeout: 8e3, env },
22846
- (err, stdout2, stderr) => resolve12(err ? null : versionFromProbe(stdout2, stderr))
22952
+ (err, stdout2, stderr) => resolve13(err ? null : versionFromProbe(stdout2, stderr))
22847
22953
  );
22848
22954
  });
22849
22955
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
@@ -23255,14 +23361,14 @@ var init_antigravity_acp = __esm({
23255
23361
  this.child.stderr.setEncoding("utf8");
23256
23362
  this.child.stderr.on("data", (chunk) => this.consumeDiagnostics(chunk));
23257
23363
  this.child.once("error", (error51) => this.failAll(error51));
23258
- this.exited = new Promise((resolve12) => {
23364
+ this.exited = new Promise((resolve13) => {
23259
23365
  this.child.once("close", (code, signal) => {
23260
23366
  this.noteStartupDiagnostic(this.diagnosticBuffer);
23261
23367
  this.diagnosticBuffer = "";
23262
23368
  if (!this.closed) this.failAll(new Error(
23263
23369
  `Antigravity ACP exited ${code ?? signal ?? "unexpectedly"}.${this.nativeStartupHint ? ` ${this.nativeStartupHint}` : ""}`
23264
23370
  ));
23265
- resolve12();
23371
+ resolve13();
23266
23372
  });
23267
23373
  });
23268
23374
  }
@@ -23368,8 +23474,8 @@ var init_antigravity_acp = __esm({
23368
23474
  async closeAndWait(timeoutMs = 7e3) {
23369
23475
  this.close();
23370
23476
  let timer;
23371
- const timedOut = new Promise((resolve12) => {
23372
- timer = setTimeout(() => resolve12(false), timeoutMs);
23477
+ const timedOut = new Promise((resolve13) => {
23478
+ timer = setTimeout(() => resolve13(false), timeoutMs);
23373
23479
  timer.unref?.();
23374
23480
  });
23375
23481
  try {
@@ -23878,7 +23984,7 @@ var init_antigravity_runtime = __esm({
23878
23984
  FREE_SPACE_MARGIN = 256 * 1024 * 1024;
23879
23985
  DOWNLOAD_TIMEOUT_MS2 = 45 * 6e4;
23880
23986
  STAGING_PREFIX = ".install-";
23881
- wait = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
23987
+ wait = (ms) => new Promise((resolve13) => setTimeout(resolve13, ms));
23882
23988
  INSTALL_RECORD = ".install-complete.json";
23883
23989
  AntigravitySetupError = class extends Error {
23884
23990
  status = 409;
@@ -24047,9 +24153,51 @@ var init_antigravity = __esm({
24047
24153
  }
24048
24154
  });
24049
24155
 
24156
+ // server/decider/jev.ts
24157
+ var init_jev = __esm({
24158
+ "server/decider/jev.ts"() {
24159
+ "use strict";
24160
+ }
24161
+ });
24162
+
24163
+ // server/included-services.ts
24164
+ function includedService(url2, token) {
24165
+ const api2 = url2?.trim().replace(/\/+$/, "");
24166
+ const secret = token?.trim();
24167
+ return api2 && secret ? { token: secret, api: api2, included: true } : null;
24168
+ }
24169
+ function resolve6(own, providerApi, included) {
24170
+ if (own) {
24171
+ if (included && own === included.token) return included;
24172
+ return { token: own, api: providerApi, included: false };
24173
+ }
24174
+ return included;
24175
+ }
24176
+ function boatCredential(own, env = process.env) {
24177
+ return resolve6(own, boatProviderApi(env), (held ?? includedFrom(env)).boat);
24178
+ }
24179
+ var BOAT_API_DEFAULT, includedFrom, held, boatProviderApi;
24180
+ var init_included_services = __esm({
24181
+ "server/included-services.ts"() {
24182
+ "use strict";
24183
+ init_jev();
24184
+ BOAT_API_DEFAULT = "https://ascii.dev/api/box/v1";
24185
+ includedFrom = (env) => ({
24186
+ boat: includedService(env.OMB_CLOUD_BOAT_URL, env.OMB_CLOUD_BOAT_TOKEN),
24187
+ voice: includedService(env.OMB_CLOUD_VOICE_URL, env.OMB_CLOUD_VOICE_TOKEN),
24188
+ // A Jev base URL as it is: the decider adds /v1/systemone, the relay's one route.
24189
+ decider: includedService(env.OMB_CLOUD_DECIDER_URL, env.OMB_CLOUD_DECIDER_TOKEN)
24190
+ });
24191
+ held = null;
24192
+ boatProviderApi = (env = process.env) => env.OMB_BOX_API || BOAT_API_DEFAULT;
24193
+ }
24194
+ });
24195
+
24050
24196
  // server/drivers/boatagent.ts
24051
- async function loadCatalog() {
24052
- const root = BOAT_API.replace(/\/api\/box\/v1\/?$/, "");
24197
+ async function loadCatalog(api2) {
24198
+ const root = api2.replace(/\/api\/box\/v1\/?$/, "");
24199
+ if (catalog && catalogRoot === root) return;
24200
+ catalogRoot = root;
24053
24201
  catalog = await fetch(`${root}/api/provider-models`, { signal: AbortSignal.timeout(15e3) }).then((res) => res.ok ? res.json() : null).catch(() => null);
24054
24202
  }
24055
24203
  function decodeConfig(raw) {
@@ -24059,15 +24207,15 @@ function decodeConfig(raw) {
24059
24207
  ...typeof o.askTimeoutMs === "number" ? { askTimeoutMs: o.askTimeoutMs } : {}
24060
24208
  };
24061
24209
  }
24062
- var DRIVER_KIND, BOAT_API, MODELS, ASK_FENCE_ANY, catalog, providerFor, BoatAgentDriver;
24210
+ var DRIVER_KIND, MODELS, ASK_FENCE_ANY, catalog, catalogRoot, providerFor, BoatAgentDriver;
24063
24211
  var init_boatagent = __esm({
24064
24212
  "server/drivers/boatagent.ts"() {
24065
24213
  "use strict";
24066
24214
  init_contracts();
24215
+ init_included_services();
24067
24216
  init_native();
24068
24217
  init_ask_question();
24069
24218
  DRIVER_KIND = "boxAgent";
24070
- BOAT_API = process.env.OMB_BOX_API || "https://ascii.dev/api/box/v1";
24071
24219
  MODELS = {
24072
24220
  default: "claude-fable-5",
24073
24221
  options: [
@@ -24078,6 +24226,7 @@ var init_boatagent = __esm({
24078
24226
  };
24079
24227
  ASK_FENCE_ANY = /(^|\n)[ \t]{0,3}(`{3,}|~{3,})[ \t]*omb-ask\b/;
24080
24228
  catalog = null;
24229
+ catalogRoot = "";
24081
24230
  providerFor = (model) => {
24082
24231
  const slash = model.indexOf("/");
24083
24232
  if (slash > 0 && catalog?.[model.slice(0, slash)]) return { provider: model.slice(0, slash), model: model.slice(slash + 1) };
@@ -24094,7 +24243,8 @@ var init_boatagent = __esm({
24094
24243
  defaultConfig: () => decodeConfig({}),
24095
24244
  async create(input) {
24096
24245
  const { instanceId, config: config2 } = input;
24097
- const token = input.environment.BOX_TOKEN ?? process.env.BOX_TOKEN ?? "";
24246
+ const ownToken = input.environment.BOX_TOKEN ?? process.env.BOX_TOKEN;
24247
+ const account = () => boatCredential(ownToken);
24098
24248
  const listeners = /* @__PURE__ */ new Set();
24099
24249
  const active = /* @__PURE__ */ new Map();
24100
24250
  const heldAsks = /* @__PURE__ */ new Map();
@@ -24110,9 +24260,10 @@ var init_boatagent = __esm({
24110
24260
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
24111
24261
  });
24112
24262
  const api2 = async (path3, opts = {}) => {
24113
- const res = await fetch(`${BOAT_API}${path3}`, {
24263
+ const credential = account();
24264
+ const res = await fetch(`${credential?.api ?? boatProviderApi()}${path3}`, {
24114
24265
  ...opts,
24115
- headers: { authorization: `Bearer ${token}`, "content-type": "application/json", ...opts.headers },
24266
+ headers: { authorization: `Bearer ${credential?.token ?? ""}`, "content-type": "application/json", ...opts.headers },
24116
24267
  signal: opts.signal ?? AbortSignal.timeout(3e4)
24117
24268
  });
24118
24269
  const body = await res.json().catch(() => null);
@@ -24125,7 +24276,7 @@ var init_boatagent = __esm({
24125
24276
  const { threadId } = turn;
24126
24277
  const computer = turn.integrations?.computer;
24127
24278
  const boxId = computer && (!computer.kind || computer.kind === "box") ? computer.boxId : void 0;
24128
- if (!token) throw new Error('box not configured \u2014 add {"box":{"token":"\u2026"}} to ~/.openmausbot/config.json');
24279
+ if (!account()) throw new Error('box not configured \u2014 add {"box":{"token":"\u2026"}} to ~/.openmausbot/config.json');
24129
24280
  if (!boxId) {
24130
24281
  throw new Error("this bot has no computer yet \u2014 open the Computer panel and provision one");
24131
24282
  }
@@ -24142,7 +24293,7 @@ var init_boatagent = __esm({
24142
24293
  turn.text
24143
24294
  ].filter((s2) => s2 !== void 0).join("\n");
24144
24295
  const postPrompt = async (promptText) => {
24145
- if (!catalog) await loadCatalog();
24296
+ await loadCatalog(account()?.api ?? boatProviderApi());
24146
24297
  const started = await api2(`/boxes/${boxId}/prompt`, {
24147
24298
  method: "POST",
24148
24299
  body: JSON.stringify({ ...providerFor(model), prompt: promptText })
@@ -24195,13 +24346,13 @@ var init_boatagent = __esm({
24195
24346
  }
24196
24347
  const requestId = newId();
24197
24348
  let settleHeld;
24198
- const held = new Promise((resolve12) => {
24349
+ const held2 = new Promise((resolve13) => {
24199
24350
  const timer = setTimeout(() => settleHeld(null, "timeout"), config2.askTimeoutMs ?? 15 * 6e4);
24200
24351
  timer.unref?.();
24201
24352
  settleHeld = (reply2, source2) => {
24202
24353
  heldAsks.delete(threadId);
24203
24354
  clearTimeout(timer);
24204
- resolve12([reply2, source2]);
24355
+ resolve13([reply2, source2]);
24205
24356
  };
24206
24357
  });
24207
24358
  heldAsks.set(threadId, { requestId, settle: settleHeld });
@@ -24217,7 +24368,7 @@ var init_boatagent = __esm({
24217
24368
  ...choices?.length ? { choices } : {},
24218
24369
  origin: "output"
24219
24370
  });
24220
- const [reply, source] = await held;
24371
+ const [reply, source] = await held2;
24221
24372
  emit({ ...base2(threadId, turnId), requestId, type: "request.resolved", behavior: reply !== null ? "answer" : "deny", source });
24222
24373
  if (reply === null || cancelled) {
24223
24374
  return { ok: ok && !cancelled, stopReason: cancelled ? "interrupted" : stopReason };
@@ -24316,7 +24467,7 @@ var init_boatagent = __esm({
24316
24467
  return { turnId };
24317
24468
  };
24318
24469
  const snapshot = async () => {
24319
- if (!token) {
24470
+ if (!account()) {
24320
24471
  return { state: "unavailable", reason: 'no Boat token \u2014 add {"box":{"token":"\u2026"}} to ~/.openmausbot/config.json' };
24321
24472
  }
24322
24473
  try {
@@ -24339,15 +24490,15 @@ var init_boatagent = __esm({
24339
24490
  sendTurn,
24340
24491
  interruptTurn: async (threadId) => active.get(threadId)?.cancel(),
24341
24492
  respondToRequest: async (threadId, requestId, decision) => {
24342
- const held = heldAsks.get(threadId);
24343
- if (!held || held.requestId !== requestId) return "unavailable";
24493
+ const held2 = heldAsks.get(threadId);
24494
+ if (!held2 || held2.requestId !== requestId) return "unavailable";
24344
24495
  const reply = decision.message?.trim();
24345
24496
  if (decision.behavior === "answer" && reply) {
24346
- held.settle(decision.message, "user");
24497
+ held2.settle(decision.message, "user");
24347
24498
  return "answered";
24348
24499
  }
24349
24500
  if (decision.behavior === "deny") {
24350
- held.settle(null, "user");
24501
+ held2.settle(null, "user");
24351
24502
  return "rejected";
24352
24503
  }
24353
24504
  return "unavailable";
@@ -24375,7 +24526,7 @@ var init_boatagent = __esm({
24375
24526
  import { randomUUID as randomUUID8 } from "node:crypto";
24376
24527
  import { realpathSync as realpathSync2 } from "node:fs";
24377
24528
  import { homedir as homedir8 } from "node:os";
24378
- import { basename as basename6, dirname as dirname8, isAbsolute as isAbsolute4, join as join19, resolve as resolve6 } from "node:path";
24529
+ import { basename as basename6, dirname as dirname8, isAbsolute as isAbsolute4, join as join19, resolve as resolve7 } from "node:path";
24379
24530
  import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
24380
24531
  function canonicalPath(path3) {
24381
24532
  try {
@@ -24439,7 +24590,7 @@ var init_claude_login_auth = __esm({
24439
24590
  if (!isAbsolute4(home) || env.CLAUDE_CONFIG_DIR && !isAbsolute4(env.CLAUDE_CONFIG_DIR)) {
24440
24591
  throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing in.");
24441
24592
  }
24442
- const homeKey = canonicalPath(resolve6(env.CLAUDE_CONFIG_DIR || join19(home, ".claude")));
24593
+ const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR || join19(home, ".claude")));
24443
24594
  if (authenticatingHomes.has(homeKey)) {
24444
24595
  throw new Error("A Claude sign-in is already running for this server account. Finish or cancel it before starting another.");
24445
24596
  }
@@ -24535,7 +24686,7 @@ var init_claude_login_auth = __esm({
24535
24686
  if (!isAbsolute4(home) || env.CLAUDE_CONFIG_DIR && !isAbsolute4(env.CLAUDE_CONFIG_DIR)) {
24536
24687
  throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing out.");
24537
24688
  }
24538
- const homeKey = canonicalPath(resolve6(env.CLAUDE_CONFIG_DIR || join19(home, ".claude")));
24689
+ const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR || join19(home, ".claude")));
24539
24690
  if (authenticatingHomes.has(homeKey)) {
24540
24691
  throw new Error("A Claude sign-in is running for this server account. Finish or cancel it before signing out.");
24541
24692
  }
@@ -24795,12 +24946,12 @@ import { createServer as createNetServer } from "node:net";
24795
24946
  import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
24796
24947
  import { join as join21, dirname as dirname9, isAbsolute as isAbsolute5, normalize } from "node:path";
24797
24948
  function claudeAuthStatus(cli, env, run2 = execCli) {
24798
- return new Promise((resolve12) => {
24949
+ return new Promise((resolve13) => {
24799
24950
  run2(cli, ["auth", "status", "--json"], { timeout: 8e3, maxBuffer: 65536, env }, (_error, stdout2) => {
24800
24951
  try {
24801
24952
  const status = JSON.parse(stdout2);
24802
24953
  if (!status || typeof status !== "object" || !("loggedIn" in status) || status.loggedIn !== true) {
24803
- return resolve12({ authenticated: false });
24954
+ return resolve13({ authenticated: false });
24804
24955
  }
24805
24956
  const identity = status;
24806
24957
  const boundedText2 = (value, max) => typeof value === "string" && value.trim().length > 0 && value.length <= max && !/[\p{Cc}\p{Cf}]/u.test(value) ? value.trim() : void 0;
@@ -24812,9 +24963,9 @@ function claudeAuthStatus(cli, env, run2 = execCli) {
24812
24963
  ...organization ? { organization } : {},
24813
24964
  ...identity.authMethod === "api_key" ? { method: "api-key" } : {}
24814
24965
  };
24815
- resolve12({ authenticated: true, ...Object.keys(account).length ? { account } : {} });
24966
+ resolve13({ authenticated: true, ...Object.keys(account).length ? { account } : {} });
24816
24967
  } catch {
24817
- resolve12({ authenticated: false });
24968
+ resolve13({ authenticated: false });
24818
24969
  }
24819
24970
  });
24820
24971
  });
@@ -25094,9 +25245,9 @@ async function createPermissionBroker(opts) {
25094
25245
  unlinkSync3(candidate);
25095
25246
  } catch {
25096
25247
  }
25097
- let outcome = await new Promise((resolve12) => {
25098
- attempt.once("listening", () => resolve12("listening"));
25099
- attempt.once("error", (error51) => resolve12(error51));
25248
+ let outcome = await new Promise((resolve13) => {
25249
+ attempt.once("listening", () => resolve13("listening"));
25250
+ attempt.once("error", (error51) => resolve13(error51));
25100
25251
  attempt.listen(candidate);
25101
25252
  });
25102
25253
  if (outcome === "listening" && process.platform !== "win32") {
@@ -25370,6 +25521,7 @@ var init_claude = __esm({
25370
25521
  { id: "claude-fable-5", label: "Claude Fable 5" },
25371
25522
  { id: "claude-opus-5-5", label: "Claude Opus 5.5", contextWindow: 1e6 },
25372
25523
  { id: "claude-opus-5", label: "Claude Opus 5" },
25524
+ { id: "claude-sonnet-5-5", label: "Claude Sonnet 5.5", contextWindow: 1e6 },
25373
25525
  { id: "claude-sonnet-5", label: "Claude Sonnet 5" },
25374
25526
  { id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
25375
25527
  ]
@@ -25422,12 +25574,12 @@ var init_claude = __esm({
25422
25574
  await refreshModels();
25423
25575
  let cliVersion = null;
25424
25576
  let cliVersionChecked = false;
25425
- const readCliVersion = (env) => new Promise((resolve12) => {
25577
+ const readCliVersion = (env) => new Promise((resolve13) => {
25426
25578
  execCli(
25427
25579
  config2.cli,
25428
25580
  ["--version"],
25429
25581
  { timeout: 8e3, env },
25430
- (err, stdout2) => resolve12(err ? null : stdout2.trim() || null)
25582
+ (err, stdout2) => resolve13(err ? null : stdout2.trim() || null)
25431
25583
  );
25432
25584
  });
25433
25585
  const listeners = /* @__PURE__ */ new Set();
@@ -25466,19 +25618,19 @@ var init_claude = __esm({
25466
25618
  };
25467
25619
  const writeUser = (s2, threadId, promptMsg) => {
25468
25620
  if (!s2.child.stdin.writable || s2.child.stdin.destroyed) return Promise.resolve(false);
25469
- return new Promise((resolve12) => {
25621
+ return new Promise((resolve13) => {
25470
25622
  try {
25471
25623
  s2.child.stdin.write(JSON.stringify(promptMsg) + "\n", (error51) => {
25472
- if (error51) return resolve12(false);
25624
+ if (error51) return resolve13(false);
25473
25625
  appendNative(threadId, {
25474
25626
  dir: "out",
25475
25627
  source: "claude.sdk.message",
25476
25628
  msg: diagnosticClaudeUserMessage(promptMsg)
25477
25629
  });
25478
- resolve12(true);
25630
+ resolve13(true);
25479
25631
  });
25480
25632
  } catch {
25481
- resolve12(false);
25633
+ resolve13(false);
25482
25634
  }
25483
25635
  });
25484
25636
  };
@@ -26189,7 +26341,7 @@ var init_claude = __esm({
26189
26341
  const warning = claudeInheritWarning(env);
26190
26342
  return { state: "available", version: version2, ...auth, ...update ? { update } : {}, ...warning ? { warning } : {}, billing: "subscription" };
26191
26343
  };
26192
- const generateReview = (prompt, signal, onUsage) => new Promise((resolve12, reject) => {
26344
+ const generateReview = (prompt, signal, onUsage) => new Promise((resolve13, reject) => {
26193
26345
  const model = config2.managedModels?.[0] ?? "claude-haiku-4-5";
26194
26346
  const child = spawnCli(
26195
26347
  config2.cli,
@@ -26208,7 +26360,7 @@ var init_claude = __esm({
26208
26360
  clearTimeout(timer);
26209
26361
  signal?.removeEventListener("abort", onAbort);
26210
26362
  if (error51) reject(error51);
26211
- else resolve12(stdout2.trim());
26363
+ else resolve13(stdout2.trim());
26212
26364
  };
26213
26365
  const onAbort = () => {
26214
26366
  killCliTree(child);
@@ -26406,9 +26558,9 @@ var init_codex_mcp_names = __esm({
26406
26558
 
26407
26559
  // server/drivers/codex-identity.ts
26408
26560
  import { homedir as homedir11 } from "node:os";
26409
- import { isAbsolute as isAbsolute6, join as join23, resolve as resolve7 } from "node:path";
26561
+ import { isAbsolute as isAbsolute6, join as join23, resolve as resolve8 } from "node:path";
26410
26562
  function codexHome(env) {
26411
- if (env.CODEX_HOME) return isAbsolute6(env.CODEX_HOME) ? resolve7(env.CODEX_HOME) : null;
26563
+ if (env.CODEX_HOME) return isAbsolute6(env.CODEX_HOME) ? resolve8(env.CODEX_HOME) : null;
26412
26564
  const home = userHome(env);
26413
26565
  return isAbsolute6(home) ? join23(home, ".codex") : null;
26414
26566
  }
@@ -26534,7 +26686,7 @@ function decodeCodexSelection(id) {
26534
26686
  return { model: id, modelProvider: MODEL_ID2.test(id) ? OFFICIAL_CODEX_PROVIDER : null };
26535
26687
  }
26536
26688
  function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
26537
- return new Promise((resolve12) => {
26689
+ return new Promise((resolve13) => {
26538
26690
  const child = spawnCli(cli, ["app-server"], {
26539
26691
  cwd: homedir12(),
26540
26692
  env,
@@ -26551,7 +26703,7 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
26551
26703
  settled = true;
26552
26704
  clearTimeout(timer);
26553
26705
  killCliTree(child);
26554
- resolve12(catalog2);
26706
+ resolve13(catalog2);
26555
26707
  };
26556
26708
  const request = (method, params, kind) => {
26557
26709
  const id = nextId++;
@@ -26958,7 +27110,7 @@ var init_codex_instructions = __esm({
26958
27110
  import { randomUUID as randomUUID9 } from "node:crypto";
26959
27111
  import { realpathSync as realpathSync3 } from "node:fs";
26960
27112
  import { homedir as homedir13 } from "node:os";
26961
- import { basename as basename8, dirname as dirname10, isAbsolute as isAbsolute7, join as join26, resolve as resolve8 } from "node:path";
27113
+ import { basename as basename8, dirname as dirname10, isAbsolute as isAbsolute7, join as join26, resolve as resolve9 } from "node:path";
26962
27114
  import { stripVTControlCharacters as stripVTControlCharacters5 } from "node:util";
26963
27115
  function canonicalPath2(path3) {
26964
27116
  try {
@@ -27016,7 +27168,7 @@ var init_codex_device_auth = __esm({
27016
27168
  if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
27017
27169
  throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
27018
27170
  }
27019
- const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
27171
+ const homeKey = canonicalPath2(resolve9(env.CODEX_HOME || join26(home, ".codex")));
27020
27172
  if (authenticatingHomes2.has(homeKey)) {
27021
27173
  throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
27022
27174
  }
@@ -27095,7 +27247,7 @@ var init_codex_device_auth = __esm({
27095
27247
  if (!isAbsolute7(home) || env.CODEX_HOME && !isAbsolute7(env.CODEX_HOME)) {
27096
27248
  throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
27097
27249
  }
27098
- const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join26(home, ".codex")));
27250
+ const homeKey = canonicalPath2(resolve9(env.CODEX_HOME || join26(home, ".codex")));
27099
27251
  if (authenticatingHomes2.has(homeKey)) {
27100
27252
  throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
27101
27253
  }
@@ -27833,7 +27985,7 @@ var init_codex = __esm({
27833
27985
  msg: codexNativeLogMessage(obj)
27834
27986
  });
27835
27987
  };
27836
- const request = (method, params, timeoutMs = 6e4) => new Promise((resolve12, reject) => {
27988
+ const request = (method, params, timeoutMs = 6e4) => new Promise((resolve13, reject) => {
27837
27989
  const id = nextId++;
27838
27990
  if (method === "config/read") sensitiveResponseIds.add(id);
27839
27991
  const timer = setTimeout(() => {
@@ -27861,7 +28013,7 @@ var init_codex = __esm({
27861
28013
  handleNotification(notification);
27862
28014
  }
27863
28015
  }
27864
- resolve12(v2);
28016
+ resolve13(v2);
27865
28017
  },
27866
28018
  reject: (e) => {
27867
28019
  clearTimeout(timer);
@@ -28461,22 +28613,22 @@ var init_codex = __esm({
28461
28613
  };
28462
28614
  const snapshot = async () => {
28463
28615
  const env = childEnv();
28464
- const version2 = await new Promise((resolve12) => {
28616
+ const version2 = await new Promise((resolve13) => {
28465
28617
  execCli(
28466
28618
  config2.cli,
28467
28619
  ["--version"],
28468
28620
  { timeout: 8e3, env },
28469
- (err, stdout2) => resolve12(err ? null : stdout2.trim())
28621
+ (err, stdout2) => resolve13(err ? null : stdout2.trim())
28470
28622
  );
28471
28623
  });
28472
28624
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
28473
28625
  if (config2.managed) return { state: "available", version: version2, authenticated: Boolean(input.environment.OPENMAUSBOT_COMPANY_API_KEY && input.environment.CODEX_HOME), billing: "metered" };
28474
- const authenticated = await new Promise((resolve12) => {
28626
+ const authenticated = await new Promise((resolve13) => {
28475
28627
  execCli(
28476
28628
  config2.cli,
28477
28629
  ["login", "status"],
28478
28630
  { timeout: 8e3, env },
28479
- (err, stdout2, stderr) => resolve12(!err && /^logged in\b/im.test(`${stdout2}
28631
+ (err, stdout2, stderr) => resolve13(!err && /^logged in\b/im.test(`${stdout2}
28480
28632
  ${stderr ?? ""}`))
28481
28633
  );
28482
28634
  });
@@ -31507,7 +31659,7 @@ var require_compile = __commonJS({
31507
31659
  const schOrFunc = root.refs[ref];
31508
31660
  if (schOrFunc)
31509
31661
  return schOrFunc;
31510
- let _sch = resolve12.call(this, root, ref);
31662
+ let _sch = resolve13.call(this, root, ref);
31511
31663
  if (_sch === void 0) {
31512
31664
  const schema4 = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
31513
31665
  const { schemaId } = this.opts;
@@ -31534,7 +31686,7 @@ var require_compile = __commonJS({
31534
31686
  function sameSchemaEnv(s1, s2) {
31535
31687
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
31536
31688
  }
31537
- function resolve12(root, ref) {
31689
+ function resolve13(root, ref) {
31538
31690
  let sch;
31539
31691
  while (typeof (sch = this.refs[ref]) == "string")
31540
31692
  ref = sch;
@@ -32165,7 +32317,7 @@ var require_fast_uri = __commonJS({
32165
32317
  }
32166
32318
  return uri;
32167
32319
  }
32168
- function resolve12(baseURI, relativeURI, options) {
32320
+ function resolve13(baseURI, relativeURI, options) {
32169
32321
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
32170
32322
  const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
32171
32323
  const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
@@ -32449,7 +32601,7 @@ var require_fast_uri = __commonJS({
32449
32601
  var fastUri = {
32450
32602
  SCHEMES,
32451
32603
  normalize: normalize2,
32452
- resolve: resolve12,
32604
+ resolve: resolve13,
32453
32605
  resolveComponent,
32454
32606
  equal,
32455
32607
  serialize,
@@ -36946,10 +37098,11 @@ function snapshotBoatConfig(cfg) {
36946
37098
  return { box: cfg.box ? { token: cfg.box.token } : void 0 };
36947
37099
  }
36948
37100
  function boatFetch(cfg, path3, opts = {}) {
36949
- return fetch(`${BOAT_API2}${path3}`, {
37101
+ const account = boatAccount(cfg);
37102
+ return fetch(`${account?.api ?? boatProviderApi()}${path3}`, {
36950
37103
  ...opts,
36951
37104
  headers: {
36952
- authorization: `Bearer ${cfg.box?.token}`,
37105
+ authorization: `Bearer ${account?.token}`,
36953
37106
  "content-type": "application/json",
36954
37107
  ...opts.headers
36955
37108
  }
@@ -36988,9 +37141,9 @@ async function runCommand(cfg, boxId, command, { timeoutMs = 12e4, signal } = {}
36988
37141
  stderr: body?.stderr ?? ""
36989
37142
  };
36990
37143
  }
36991
- function boatInventoryProblem(status, body) {
37144
+ function boatInventoryProblem(status, body, included = false) {
36992
37145
  if (status === 401 || status === 403) {
36993
- return "boat.dev rejected the Boat API key \u2014 update it in Settings \u2192 Connections";
37146
+ return included ? INCLUDED_BOAT_UNAVAILABLE : "boat.dev rejected the Boat API key \u2014 update it in Settings \u2192 Connections";
36994
37147
  }
36995
37148
  if (status === 429) return "boat.dev is rate-limiting this account \u2014 wait a minute and refresh";
36996
37149
  const message2 = typeof body?.message === "string" ? body.message.trim() : "";
@@ -37009,7 +37162,11 @@ async function listBoatPages(cfg) {
37009
37162
  return { ok: false, problem: "Could not reach boat.dev to list cloud computers \u2014 check your connection and refresh" };
37010
37163
  }
37011
37164
  if (!listed.ok || !Array.isArray(listed.body?.boxes)) {
37012
- return { ok: false, problem: boatInventoryProblem(listed.status, listed.body), credentialRejected: listed.status === 401 || listed.status === 403 };
37165
+ return {
37166
+ ok: false,
37167
+ problem: boatInventoryProblem(listed.status, listed.body, usesIncludedBoat(cfg)),
37168
+ credentialRejected: listed.status === 401 || listed.status === 403
37169
+ };
37013
37170
  }
37014
37171
  boats.push(...listed.body.boxes);
37015
37172
  const next = listed.body?.pageInfo?.nextCursor;
@@ -37075,6 +37232,12 @@ async function findBoat(cfg, botId) {
37075
37232
  }
37076
37233
  return found;
37077
37234
  }
37235
+ function boatAccount(cfg) {
37236
+ return boatCredential(cfg.box?.token);
37237
+ }
37238
+ function usesIncludedBoat(cfg) {
37239
+ return boatAccount(cfg)?.included === true;
37240
+ }
37078
37241
  function panelShotCommand({ width = PANEL_FRAME_WIDTH, quality = PANEL_FRAME_QUALITY, framePath = PANEL_PATH, nativeSize = false } = {}) {
37079
37242
  return [
37080
37243
  "export DISPLAY=${DISPLAY:-:0}",
@@ -37136,16 +37299,16 @@ async function screenshotBoat(cfg, botId, knownBoatId, options) {
37136
37299
  if (!data) throw new Error("could not read the frame back from the box");
37137
37300
  return { png: data, format: "jpeg" };
37138
37301
  }
37139
- var shellQuote2, BOAT_API2, READY, DEFAULT_BOAT_TTL_SECONDS, TRIAL_BOAT_TTL_SECONDS, BOAT_INVENTORY_PAGE_SIZE, MAX_BOAT_INVENTORY_PAGES, BOAT_ID3, scopedBoatPrefixCache, boatIdCache, QUIESCE_BROWSER, PANEL_PATH, PANEL_FRAME_WIDTH, PANEL_FRAME_QUALITY, PANEL_FRAME_FFMPEG_Q, SHOT_CMD, MAX_FRAME_BYTES, FRAME_TOO_LARGE;
37302
+ var shellQuote2, READY, DEFAULT_BOAT_TTL_SECONDS, TRIAL_BOAT_TTL_SECONDS, BOAT_INVENTORY_PAGE_SIZE, MAX_BOAT_INVENTORY_PAGES, BOAT_ID3, scopedBoatPrefixCache, boatIdCache, QUIESCE_BROWSER, INCLUDED_BOAT_UNAVAILABLE, PANEL_PATH, PANEL_FRAME_WIDTH, PANEL_FRAME_QUALITY, PANEL_FRAME_FFMPEG_Q, SHOT_CMD, MAX_FRAME_BYTES, FRAME_TOO_LARGE;
37140
37303
  var init_boat = __esm({
37141
37304
  "server/boat.ts"() {
37142
37305
  "use strict";
37143
37306
  init_config();
37144
37307
  init_environment();
37308
+ init_included_services();
37145
37309
  init_boat_create_idempotency();
37146
37310
  init_boat_delete_journal();
37147
37311
  shellQuote2 = (value) => `'${value.replace(/'/g, "'\\''")}'`;
37148
- BOAT_API2 = process.env.OMB_BOX_API || "https://ascii.dev/api/box/v1";
37149
37312
  READY = /* @__PURE__ */ new Set(["idle", "ready", "running"]);
37150
37313
  DEFAULT_BOAT_TTL_SECONDS = 8 * 60 * 60;
37151
37314
  TRIAL_BOAT_TTL_SECONDS = 2 * 60 * 60;
@@ -37158,6 +37321,7 @@ var init_boat = __esm({
37158
37321
  'for name in chrome google-chrome chromium chromium-browser; do pid=$(pgrep -o -x "$name" 2>/dev/null || true); [ -z "$pid" ] || kill -TERM "$pid" 2>/dev/null || true; done',
37159
37322
  "for i in 1 2 3 4 5 6 7 8; do if ! pgrep -x chrome >/dev/null 2>&1 && ! pgrep -x google-chrome >/dev/null 2>&1 && ! pgrep -x chromium >/dev/null 2>&1 && ! pgrep -x chromium-browser >/dev/null 2>&1; then break; fi; sleep 0.25; done"
37160
37323
  ].join("; ");
37324
+ INCLUDED_BOAT_UNAVAILABLE = "Cloud Pro's included cloud computers aren't available right now. Try again later.";
37161
37325
  PANEL_PATH = "/tmp/ogb-panel.jpg";
37162
37326
  PANEL_FRAME_WIDTH = 1920;
37163
37327
  PANEL_FRAME_QUALITY = 85;
@@ -37614,13 +37778,13 @@ var init_chat_mcp_tools = __esm({
37614
37778
  if (this.closed) throw new Error("MCP session closed");
37615
37779
  const id = this.nextId++;
37616
37780
  try {
37617
- return await new Promise((resolve12, reject) => {
37781
+ return await new Promise((resolve13, reject) => {
37618
37782
  const finish = (error51, value) => {
37619
37783
  clearTimeout(timer);
37620
37784
  signal.removeEventListener("abort", cancel);
37621
37785
  this.pending.delete(id);
37622
37786
  if (error51) reject(error51);
37623
- else resolve12(value);
37787
+ else resolve13(value);
37624
37788
  };
37625
37789
  const cancel = () => {
37626
37790
  try {
@@ -37701,7 +37865,7 @@ function createChatToolApproval(options) {
37701
37865
  ask(tool2, summary) {
37702
37866
  if (closed || options.signal.aborted) return Promise.resolve(false);
37703
37867
  const ask = { id: newId(), tool: tool2, summary };
37704
- return new Promise((resolve12) => {
37868
+ return new Promise((resolve13) => {
37705
37869
  let timer;
37706
37870
  const card = {
37707
37871
  kind: "permission",
@@ -37712,7 +37876,7 @@ function createChatToolApproval(options) {
37712
37876
  options.signal.removeEventListener("abort", abort);
37713
37877
  const allowed = decision?.allowed === true;
37714
37878
  options.resolved(ask, allowed, source);
37715
- resolve12(allowed);
37879
+ resolve13(allowed);
37716
37880
  }
37717
37881
  };
37718
37882
  const abort = () => card.finish("system");
@@ -37726,7 +37890,7 @@ function createChatToolApproval(options) {
37726
37890
  question(tool2, summary, questions) {
37727
37891
  if (closed || options.signal.aborted) return Promise.resolve(null);
37728
37892
  const ask = { id: newId(), tool: tool2, summary };
37729
- return new Promise((resolve12) => {
37893
+ return new Promise((resolve13) => {
37730
37894
  let timer;
37731
37895
  const card = {
37732
37896
  kind: "question",
@@ -37737,7 +37901,7 @@ function createChatToolApproval(options) {
37737
37901
  options.signal.removeEventListener("abort", abort);
37738
37902
  const reply = typeof decision?.message === "string" && decision.message.length > 0 ? decision.message : null;
37739
37903
  options.resolvedQuestion(ask, reply !== null, source);
37740
- resolve12(reply);
37904
+ resolve13(reply);
37741
37905
  }
37742
37906
  };
37743
37907
  const abort = () => card.finish("system");
@@ -38142,8 +38306,8 @@ function createOpenAIChatRuntime(options) {
38142
38306
  })
38143
38307
  });
38144
38308
  let resolveDone;
38145
- const done = new Promise((resolve12) => {
38146
- resolveDone = resolve12;
38309
+ const done = new Promise((resolve13) => {
38310
+ resolveDone = resolve13;
38147
38311
  });
38148
38312
  const turnEntry = { abort, turnId, done, approval, asides: [] };
38149
38313
  active.set(turn.threadId, turnEntry);
@@ -39644,10 +39808,10 @@ function decodeCursorAuthText(text4) {
39644
39808
  return null;
39645
39809
  }
39646
39810
  function execText(run2, cli, args, env) {
39647
- return new Promise((resolve12) => {
39811
+ return new Promise((resolve13) => {
39648
39812
  run2(cli, args, { timeout: EXEC_TIMEOUT_MS, env }, (err, stdout2) => {
39649
- if (err) return resolve12(null);
39650
- resolve12(String(stdout2 ?? ""));
39813
+ if (err) return resolve13(null);
39814
+ resolve13(String(stdout2 ?? ""));
39651
39815
  });
39652
39816
  });
39653
39817
  }
@@ -39844,7 +40008,7 @@ function parseOpenCodeModelsOutput(stdout2) {
39844
40008
  return { default: (preferred ?? options[0]).id, options };
39845
40009
  }
39846
40010
  function runOpenCodeModels(cli, environment, verbose) {
39847
- return new Promise((resolve12, reject) => {
40011
+ return new Promise((resolve13, reject) => {
39848
40012
  execCli(
39849
40013
  cli,
39850
40014
  ["models", ...verbose ? ["--verbose"] : []],
@@ -39854,7 +40018,7 @@ function runOpenCodeModels(cli, environment, verbose) {
39854
40018
  reject(new Error(stderr?.trim() || error51.message, { cause: error51 }));
39855
40019
  return;
39856
40020
  }
39857
- resolve12(stdout2);
40021
+ resolve13(stdout2);
39858
40022
  }
39859
40023
  );
39860
40024
  });
@@ -47331,13 +47495,13 @@ function hermesAcpModelsTimeoutMs(env) {
47331
47495
  return Number.isInteger(parsed) && parsed > 0 && parsed <= 2147483647 ? parsed : HERMES_ACP_MODELS_DEFAULT_TIMEOUT_MS;
47332
47496
  }
47333
47497
  async function fetchHermesAcpModels(cli, env) {
47334
- return await new Promise((resolve12) => {
47498
+ return await new Promise((resolve13) => {
47335
47499
  let child;
47336
47500
  try {
47337
47501
  const resolved = resolveCli(cli, ["acp"], env);
47338
47502
  child = spawn6(resolved.command, resolved.args, { stdio: ["pipe", "pipe", "ignore"], env, windowsHide: true });
47339
47503
  } catch {
47340
- return resolve12([]);
47504
+ return resolve13([]);
47341
47505
  }
47342
47506
  let settled = false;
47343
47507
  let timer;
@@ -47358,7 +47522,7 @@ async function fetchHermesAcpModels(cli, env) {
47358
47522
  }
47359
47523
  } catch {
47360
47524
  }
47361
- resolve12(out);
47525
+ resolve13(out);
47362
47526
  };
47363
47527
  timer = setTimeout(() => done([]), hermesAcpModelsTimeoutMs(env));
47364
47528
  child.once("error", () => done([]));
@@ -47833,7 +47997,7 @@ function readPiDefaultModel(env) {
47833
47997
  }
47834
47998
  async function fetchPiModels(cli, env) {
47835
47999
  const child = spawnCli(cli, PI_ARGS, { stdio: ["pipe", "pipe", "pipe"], env });
47836
- return new Promise((resolve12) => {
48000
+ return new Promise((resolve13) => {
47837
48001
  let buf = "";
47838
48002
  let done = false;
47839
48003
  const fallbackDefault = readPiDefaultModel(env);
@@ -47844,7 +48008,7 @@ async function fetchPiModels(cli, env) {
47844
48008
  killCliTree(child);
47845
48009
  } catch {
47846
48010
  }
47847
- resolve12(catalog2);
48011
+ resolve13(catalog2);
47848
48012
  };
47849
48013
  const timer = setTimeout(() => finish({ default: "", options: [] }), 15e3);
47850
48014
  timer.unref?.();
@@ -47874,12 +48038,12 @@ async function fetchPiModels(cli, env) {
47874
48038
  });
47875
48039
  }
47876
48040
  async function updatePiModelCatalog(cli, env) {
47877
- return new Promise((resolve12) => {
48041
+ return new Promise((resolve13) => {
47878
48042
  execCli(
47879
48043
  cli,
47880
48044
  PI_MODEL_UPDATE_ARGS,
47881
48045
  { env, timeout: 6e4, maxBuffer: 1024 * 1024 },
47882
- (error51) => resolve12(!error51)
48046
+ (error51) => resolve13(!error51)
47883
48047
  );
47884
48048
  });
47885
48049
  }
@@ -48043,13 +48207,13 @@ var init_pi = __esm({
48043
48207
  }
48044
48208
  responseWaiters.clear();
48045
48209
  };
48046
- const awaitResponse = (command, timeoutMs = 2e4, key = command) => new Promise((resolve12, reject) => {
48210
+ const awaitResponse = (command, timeoutMs = 2e4, key = command) => new Promise((resolve13, reject) => {
48047
48211
  const timer = setTimeout(() => {
48048
48212
  responseWaiters.delete(key);
48049
48213
  reject(new Error(`pi ${command} timed out`));
48050
48214
  }, timeoutMs);
48051
48215
  timer.unref?.();
48052
- responseWaiters.set(key, { resolve: resolve12, reject, timer });
48216
+ responseWaiters.set(key, { resolve: resolve13, reject, timer });
48053
48217
  });
48054
48218
  child.stdin.on("error", () => rejectWaiters(new Error("pi stdin closed")));
48055
48219
  const send = (obj) => {
@@ -48395,7 +48559,7 @@ ${turn.text}` : turn.text;
48395
48559
  return { turnId };
48396
48560
  };
48397
48561
  const snapshot = async () => {
48398
- const version2 = await new Promise((resolve12) => {
48562
+ const version2 = await new Promise((resolve13) => {
48399
48563
  const child = spawnCli(config2.cli, ["--version"], {
48400
48564
  stdio: ["ignore", "pipe", "pipe"],
48401
48565
  env: piEnvironment({ ...process.env, ...input.environment })
@@ -48408,16 +48572,16 @@ ${turn.text}` : turn.text;
48408
48572
  killCliTree(child);
48409
48573
  } catch {
48410
48574
  }
48411
- resolve12(null);
48575
+ resolve13(null);
48412
48576
  }, 8e3);
48413
48577
  timer.unref?.();
48414
48578
  child.on("error", () => {
48415
48579
  clearTimeout(timer);
48416
- resolve12(null);
48580
+ resolve13(null);
48417
48581
  });
48418
48582
  child.on("close", () => {
48419
48583
  clearTimeout(timer);
48420
- resolve12(out.trim() || null);
48584
+ resolve13(out.trim() || null);
48421
48585
  });
48422
48586
  });
48423
48587
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
@@ -48910,7 +49074,7 @@ __export(cli_setup_exports, {
48910
49074
  });
48911
49075
  import { spawn as spawn7 } from "node:child_process";
48912
49076
  import { readFileSync as readFileSync25 } from "node:fs";
48913
- import { join as join39, resolve as resolve9 } from "node:path";
49077
+ import { join as join39, resolve as resolve10 } from "node:path";
48914
49078
  import { randomUUID as randomUUID13 } from "node:crypto";
48915
49079
  async function inspect(id, entry) {
48916
49080
  const registry2 = new ProviderRegistry(BUILT_IN_DRIVERS);
@@ -48943,7 +49107,7 @@ async function runSetupCli(cli, args, environment = {}) {
48943
49107
  resetPathCache();
48944
49108
  }
48945
49109
  function assertDataDir(dataDir) {
48946
- if (resolve9(dataDir) !== resolve9(DATA_DIR)) throw new Error("Setup data directory mismatch. Restart the CLI with --data-dir.");
49110
+ if (resolve10(dataDir) !== resolve10(DATA_DIR)) throw new Error("Setup data directory mismatch. Restart the CLI with --data-dir.");
48947
49111
  }
48948
49112
  function checkStoredConfig(dataDir) {
48949
49113
  try {
@@ -49358,7 +49522,7 @@ import { spawn as spawn8 } from "node:child_process";
49358
49522
  import { createHash as createHash13, randomBytes as randomBytes3, randomUUID as randomUUID14 } from "node:crypto";
49359
49523
  import { chmodSync as chmodSync7, constants as constants2, copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync21, readFileSync as readFileSync26, readdirSync as readdirSync3, renameSync as renameSync6, rmSync as rmSync8, statSync as statSync5, unlinkSync as unlinkSync7, writeFileSync as writeFileSync16 } from "node:fs";
49360
49524
  import { homedir as homedir20, tmpdir as tmpdir5 } from "node:os";
49361
- import { delimiter as delimiter6, dirname as dirname12, join as join42, resolve as resolve10 } from "node:path";
49525
+ import { delimiter as delimiter6, dirname as dirname12, join as join42, resolve as resolve11 } from "node:path";
49362
49526
  function browserRestoreKey(session) {
49363
49527
  if (!/^[A-Za-z0-9_.-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
49364
49528
  return `omb-${createHash13("sha256").update(session).digest("hex")}`;
@@ -49454,7 +49618,7 @@ async function closeBrowserSession(binaryPath, env, timeoutMs = 15e3) {
49454
49618
  } catch {
49455
49619
  return false;
49456
49620
  }
49457
- await new Promise((resolve12) => setTimeout(resolve12, Math.min(25, Math.max(1, deadline - Date.now()))));
49621
+ await new Promise((resolve13) => setTimeout(resolve13, Math.min(25, Math.max(1, deadline - Date.now()))));
49458
49622
  }
49459
49623
  return false;
49460
49624
  }
@@ -49524,7 +49688,7 @@ function onPath(env, platform, exists) {
49524
49688
  for (const part of (pathValue ?? "").split(delimiter6)) {
49525
49689
  const dir = part.trim().replace(/^"|"$/gu, "");
49526
49690
  if (!dir) continue;
49527
- const candidate = resolve10(dir, executableName(platform));
49691
+ const candidate = resolve11(dir, executableName(platform));
49528
49692
  if (exists(candidate)) return candidate;
49529
49693
  }
49530
49694
  return null;
@@ -49533,7 +49697,7 @@ function packagedBrowser(options) {
49533
49697
  const resources = (options.env ?? process.env).OMB_RESOURCES_PATH;
49534
49698
  if (!resources) return null;
49535
49699
  try {
49536
- return browserBundlePaths(join42(resolve10(resources), "browser-engine"), `${options.platform ?? process.platform}-${options.arch ?? process.arch}`);
49700
+ return browserBundlePaths(join42(resolve11(resources), "browser-engine"), `${options.platform ?? process.platform}-${options.arch ?? process.arch}`);
49537
49701
  } catch {
49538
49702
  return null;
49539
49703
  }
@@ -49546,7 +49710,7 @@ function resolveAgentBrowserBinary(options = {}) {
49546
49710
  const platform = options.platform ?? process.platform;
49547
49711
  const exists = options.exists ?? existsSync18;
49548
49712
  const override = env.OMB_AGENT_BROWSER_PATH?.trim();
49549
- if (override) return resolve10(override) && exists(resolve10(override)) ? resolve10(override) : null;
49713
+ if (override) return resolve11(override) && exists(resolve11(override)) ? resolve11(override) : null;
49550
49714
  const bundle = packagedBrowser(options);
49551
49715
  if (bundle && exists(bundle.directory)) return completePackage(bundle, exists) ? bundle.engine : null;
49552
49716
  const pinned = pinnedBinaryPath(options.dataDir, platform, options.arch);
@@ -49616,7 +49780,7 @@ async function installAgentBrowserBinary(options = {}) {
49616
49780
  }
49617
49781
  function ensureChrome(binaryPath, options = {}) {
49618
49782
  const bundle = packagedBrowser(options);
49619
- if (!options.withDeps && bundle && resolve10(binaryPath) === bundle.engine && completePackage(bundle, existsSync18)) {
49783
+ if (!options.withDeps && bundle && resolve11(binaryPath) === bundle.engine && completePackage(bundle, existsSync18)) {
49620
49784
  options.log?.("agent-browser: the bundled browser is ready; no download needed");
49621
49785
  return Promise.resolve();
49622
49786
  }
@@ -49716,7 +49880,7 @@ function agentBrowserIntegration(input) {
49716
49880
  if (sourceEnv[name]) env[name] = sourceEnv[name];
49717
49881
  }
49718
49882
  const bundle = packagedBrowser({ env: sourceEnv, platform: input.platform, arch: input.arch });
49719
- if (!env.AGENT_BROWSER_EXECUTABLE_PATH && bundle && resolve10(input.binaryPath) === bundle.engine && completePackage(bundle, existsSync18)) {
49883
+ if (!env.AGENT_BROWSER_EXECUTABLE_PATH && bundle && resolve11(input.binaryPath) === bundle.engine && completePackage(bundle, existsSync18)) {
49720
49884
  env.AGENT_BROWSER_EXECUTABLE_PATH = bundle.chrome;
49721
49885
  }
49722
49886
  return { command: input.binaryPath, args: ["mcp", "--tools", "core", "--no-webmcp"], env };
@@ -49833,7 +49997,7 @@ import { spawn as spawn9 } from "node:child_process";
49833
49997
  import { randomBytes as randomBytes4 } from "node:crypto";
49834
49998
  import { closeSync as closeSync6, existsSync as existsSync19, mkdirSync as mkdirSync22, openSync as openSync6, readFileSync as readFileSync27 } from "node:fs";
49835
49999
  import { homedir as homedir21 } from "node:os";
49836
- import { dirname as dirname13, join as join43, resolve as resolve11 } from "node:path";
50000
+ import { dirname as dirname13, join as join43, resolve as resolve12 } from "node:path";
49837
50001
  import { createInterface as createInterface2 } from "node:readline/promises";
49838
50002
  import { fileURLToPath as fileURLToPath3 } from "node:url";
49839
50003
 
@@ -50431,13 +50595,13 @@ function writePrivateToken(runtimeRoot2, token, { fileSystem, processId, identif
50431
50595
  }
50432
50596
  async function waitForExit(child, milliseconds) {
50433
50597
  if (child.exitCode !== null || child.signalCode !== null) return;
50434
- await new Promise((resolve12) => {
50598
+ await new Promise((resolve13) => {
50435
50599
  let settled = false;
50436
50600
  const finish = () => {
50437
50601
  if (settled) return;
50438
50602
  settled = true;
50439
50603
  clearTimeout(timer);
50440
- resolve12();
50604
+ resolve13();
50441
50605
  };
50442
50606
  child.once("exit", finish);
50443
50607
  const timer = setTimeout(finish, milliseconds);
@@ -50601,8 +50765,8 @@ function createManagedCompanionTunnel({
50601
50765
  child = spawned;
50602
50766
  const cancellationController = new AbortController();
50603
50767
  let resolveCancellation;
50604
- const cancellation = new Promise((resolve12) => {
50605
- resolveCancellation = resolve12;
50768
+ const cancellation = new Promise((resolve13) => {
50769
+ resolveCancellation = resolve13;
50606
50770
  });
50607
50771
  let cancelled = false;
50608
50772
  attemptHandle = {
@@ -50618,8 +50782,8 @@ function createManagedCompanionTunnel({
50618
50782
  let terminated = false;
50619
50783
  let expectedStop = false;
50620
50784
  let resolveExit;
50621
- const exit = new Promise((resolve12) => {
50622
- resolveExit = resolve12;
50785
+ const exit = new Promise((resolve13) => {
50786
+ resolveExit = resolve13;
50623
50787
  });
50624
50788
  const onTerminated = () => {
50625
50789
  if (terminated) return;
@@ -50653,8 +50817,8 @@ function createManagedCompanionTunnel({
50653
50817
  }
50654
50818
  if (Date.now() >= deadline) break;
50655
50819
  await Promise.race([
50656
- new Promise((resolve12) => {
50657
- const timer = setTimeout(resolve12, verifyIntervalMs);
50820
+ new Promise((resolve13) => {
50821
+ const timer = setTimeout(resolve13, verifyIntervalMs);
50658
50822
  timer.unref?.();
50659
50823
  }),
50660
50824
  exit,
@@ -51434,18 +51598,8 @@ function sharedSignIn(lists) {
51434
51598
  return lists.members.length > 0 || lists.admins.length > 1 || [...lists.admins, ...lists.members].some((entry) => entry.trim().startsWith("@"));
51435
51599
  }
51436
51600
 
51437
- // server/enterprise.ts
51438
- init_zod();
51439
- init_proxy_paths();
51440
- var layerSchema = external_exports.object({
51441
- customer: external_exports.string().min(1),
51442
- features: external_exports.array(external_exports.string().min(1)),
51443
- expiresAt: external_exports.string().nullable()
51444
- });
51445
- var DAY_MS3 = 24 * 60 * 6e4;
51446
- function hostedWorkspaceConfigured(env = process.env) {
51447
- return env.OMB_ADMIN_URL !== void 0 || env.OMB_ADMIN_WORKSPACE !== void 0 || env.OMB_ADMIN_MEMBERSHIP !== void 0;
51448
- }
51601
+ // server/cli.ts
51602
+ init_enterprise();
51449
51603
 
51450
51604
  // server/request-auth.ts
51451
51605
  function resolveLoopbackTrust(input) {
@@ -52372,7 +52526,7 @@ function tenantIo(owner, file2, action, content, mode) {
52372
52526
  function defaultFleetDeps() {
52373
52527
  return {
52374
52528
  isRoot: () => typeof process.getuid === "function" && process.getuid() === 0,
52375
- run: (argv) => new Promise((resolve12) => {
52529
+ run: (argv) => new Promise((resolve13) => {
52376
52530
  const [command, ...args] = argv;
52377
52531
  let output = "";
52378
52532
  try {
@@ -52382,10 +52536,10 @@ function defaultFleetDeps() {
52382
52536
  };
52383
52537
  child.stdout.on("data", receive);
52384
52538
  child.stderr.on("data", receive);
52385
- child.once("error", (error51) => resolve12({ code: null, output: `${output}${error51.message}` }));
52386
- child.once("close", (code) => resolve12({ code, output }));
52539
+ child.once("error", (error51) => resolve13({ code: null, output: `${output}${error51.message}` }));
52540
+ child.once("close", (code) => resolve13({ code, output }));
52387
52541
  } catch (error51) {
52388
- resolve12({ code: null, output: error51 instanceof Error ? error51.message : String(error51) });
52542
+ resolve13({ code: null, output: error51 instanceof Error ? error51.message : String(error51) });
52389
52543
  }
52390
52544
  }),
52391
52545
  pathExists: (path3) => {
@@ -52434,7 +52588,7 @@ ${line}
52434
52588
  if (response.ok) return true;
52435
52589
  } catch {
52436
52590
  }
52437
- await new Promise((resolve12) => setTimeout(resolve12, 1e3));
52591
+ await new Promise((resolve13) => setTimeout(resolve13, 1e3));
52438
52592
  }
52439
52593
  return false;
52440
52594
  }
@@ -52653,17 +52807,17 @@ import { createServer } from "node:http";
52653
52807
  import { dirname as dirname3 } from "node:path";
52654
52808
  var MAX_BODY = 256 * 1024;
52655
52809
  function readBody(req) {
52656
- return new Promise((resolve12, reject) => {
52810
+ return new Promise((resolve13, reject) => {
52657
52811
  let text4 = "";
52658
52812
  req.on("data", (chunk) => {
52659
52813
  text4 += chunk.toString("utf8");
52660
52814
  if (text4.length > MAX_BODY) reject(Object.assign(new Error("request too large"), { status: 413 }));
52661
52815
  });
52662
52816
  req.on("end", () => {
52663
- if (!text4.trim()) return resolve12({});
52817
+ if (!text4.trim()) return resolve13({});
52664
52818
  try {
52665
52819
  const value = JSON.parse(text4);
52666
- resolve12(value && typeof value === "object" && !Array.isArray(value) ? value : {});
52820
+ resolve13(value && typeof value === "object" && !Array.isArray(value) ? value : {});
52667
52821
  } catch {
52668
52822
  reject(Object.assign(new Error("body must be JSON"), { status: 400 }));
52669
52823
  }
@@ -52833,9 +52987,9 @@ async function startFleetAgent(options, io) {
52833
52987
  const server = createFleetAgent(options);
52834
52988
  mkdirSync4(dirname3(options.socketPath), { recursive: true, mode: 493 });
52835
52989
  if (existsSync4(options.socketPath)) rmSync3(options.socketPath, { force: true });
52836
- await new Promise((resolve12, reject) => {
52990
+ await new Promise((resolve13, reject) => {
52837
52991
  server.once("error", reject);
52838
- server.listen(options.socketPath, () => resolve12());
52992
+ server.listen(options.socketPath, () => resolve13());
52839
52993
  });
52840
52994
  chmodSync2(options.socketPath, 432);
52841
52995
  if (options.group) {
@@ -52902,14 +53056,14 @@ function explainTailscaleFailure(reason) {
52902
53056
  }
52903
53057
  }
52904
53058
  function run(cli, args, timeoutMs) {
52905
- return new Promise((resolve12) => {
53059
+ return new Promise((resolve13) => {
52906
53060
  execFile(
52907
53061
  cli,
52908
53062
  args,
52909
53063
  { timeout: timeoutMs, killSignal: "SIGKILL", maxBuffer: 16 * 1024 * 1024, env: tailscaleEnvironment() },
52910
53064
  (error51, stdout2, stderr) => {
52911
53065
  const code = error51 && "code" in error51 && typeof error51.code === "number" ? error51.code : error51 ? null : 0;
52912
- resolve12({ ok: !error51, stdout: String(stdout2 ?? ""), stderr: String(stderr ?? ""), code });
53066
+ resolve13({ ok: !error51, stdout: String(stdout2 ?? ""), stderr: String(stderr ?? ""), code });
52913
53067
  }
52914
53068
  );
52915
53069
  });
@@ -53345,7 +53499,7 @@ function parseArgs(argv, env = process.env) {
53345
53499
  };
53346
53500
  try {
53347
53501
  if (arg === "--port") options.port = Number(value());
53348
- else if (arg === "--data-dir") options.dataDir = resolve11(value());
53502
+ else if (arg === "--data-dir") options.dataDir = resolve12(value());
53349
53503
  else if (arg === "--label") options.label = value();
53350
53504
  else if (arg === "--public-url") options.publicUrl = value().replace(/\/+$/, "");
53351
53505
  else if (arg === "--tailscale") options.tailscale = true;
@@ -53382,8 +53536,8 @@ function parseArgs(argv, env = process.env) {
53382
53536
  options.email = value();
53383
53537
  } else if (options.command === "fleet" && arg === "--admin") options.admins = [...options.admins ?? [], value()];
53384
53538
  else if (options.command === "fleet" && arg === "--member") options.members = [...options.members ?? [], value()];
53385
- else if (options.command === "fleet" && arg === "--brand") options.brandFile = resolve11(value());
53386
- else if (options.command === "fleet" && arg === "--anthropic-key-file") options.anthropicKeyFile = resolve11(value());
53539
+ else if (options.command === "fleet" && arg === "--brand") options.brandFile = resolve12(value());
53540
+ else if (options.command === "fleet" && arg === "--anthropic-key-file") options.anthropicKeyFile = resolve12(value());
53387
53541
  else if (options.command === "fleet" && arg === "--cap") options.cap = Number(value());
53388
53542
  else if (options.command === "fleet" && arg === "--license-key") options.licenseKey = value();
53389
53543
  else if (options.command === "fleet" && arg === "--memory") options.memory = value();
@@ -53498,7 +53652,7 @@ function defaultIo() {
53498
53652
  }
53499
53653
  function serverVersion(here = HERE2) {
53500
53654
  try {
53501
- const parsed = JSON.parse(readFileSync27(resolve11(here, "..", "package.json"), "utf8"));
53655
+ const parsed = JSON.parse(readFileSync27(resolve12(here, "..", "package.json"), "utf8"));
53502
53656
  const version2 = typeof parsed === "object" && parsed !== null ? Reflect.get(parsed, "version") : void 0;
53503
53657
  return typeof version2 === "string" && version2 ? version2 : "0.0.0";
53504
53658
  } catch {
@@ -53935,7 +54089,7 @@ async function runBrowser(options, io = defaultIo()) {
53935
54089
  }
53936
54090
  function serverEntry(here = HERE2) {
53937
54091
  const bundled = join43(here, "index.js");
53938
- const root = resolve11(here, "..");
54092
+ const root = resolve12(here, "..");
53939
54093
  if (existsSync19(bundled)) {
53940
54094
  const staticDir2 = [join43(root, "dist"), join43(here, "..", "ui")].find((d) => existsSync19(join43(d, "index.html"))) ?? null;
53941
54095
  const skillsDir = existsSync19(join43(root, "skills")) ? join43(root, "skills") : null;