openmausbot 0.1.93 → 0.1.95
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.
- package/dist/assets/{DesktopViewer-CKNR3SEW.js → DesktopViewer-BwWpc4RK.js} +1 -1
- package/dist/assets/{abnfDiagram-O67JEVCF-Ckrm1I1X.js → abnfDiagram-O67JEVCF-jsQkIqTn.js} +1 -1
- package/dist/assets/{arc-BBdBuCgB.js → arc-7kei4Hsu.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-CDdA3Hjs.js → architectureDiagram-NJMV4G6O-CRWDFDMq.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-AUrsx1YR.js → blockDiagram-BEXU5L5S-CTKW_IKs.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-BEqQ0Unh.js → c4Diagram-YGBWAQC7-BBTW7-6M.js} +1 -1
- package/dist/assets/channel-DS2NbT5x.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-CEEuvd4C.js → chunk-2Q5K7J3B-M_Ox-MkD.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-DyANCiHl.js → chunk-3FUC2YCW-D2YiN-Ud.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-Dx_Slpw9.js → chunk-5VM5RSS4-BmVYJ0f8.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-Dl7h7iiD.js → chunk-GTNCS2PH-BtiLVVnZ.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-BLx07SPb.js → chunk-GWA4HPMP-DFYSb6J6.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BMxDj3n7.js → chunk-JWPE2WC7-mknKBzgV.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-CN66PT4H.js → chunk-NETBCI7D-DgSYGiOu.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-6HwhsDKw.js → chunk-WEXAMYUT-C7ZvuguH.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-gWnLt7SN.js → chunk-XXDRQBXY-CPqxINpA.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-CMS5l2ea.js → classDiagram-v2-NBCMYWYE-Cd6xfJaC.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-CV7sQwIG.js → cose-bilkent-JH36ORCC-BSXY5qRh.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-CSyl-7vl.js → cynefin-OW5HDTMX-D_lhEMj1.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-BCLKL6az.js → cynefinDiagram-VND7K2PF-Da9FrFwk.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-DiaZs6S1.js → dagre-6A5THRUB-T77jMOXe.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-BeTtmt3I.js → diagram-22UHCM2B-Dkj96X5E.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-CsdBG-QQ.js → diagram-3UASUU5V-CMi9zlD_.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-BczvdbR1.js → diagram-ATOU4E4O-CXK6YUfS.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-DHTTTMhi.js → diagram-CDSNMT55-BE7B1u9Q.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-RTjHyd8z.js → diagram-MLGK6HIB-CCMQphKr.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-BDenHEH_.js → diagram-MPIPVDR6-iHJ_-tGH.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-BSiRSbtL.js → ebnfDiagram-ZINNZB2B-DONsCWQ7.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-BCAElss-.js → elk-276RUBZZ-CU_WOaXk.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-C4_1ZPJe.js → erDiagram-OPXOYQCR-BeYwM04G.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-Bcb4Z75S.js → flowDiagram-KWPJA3E3-Bdw9DqEl.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP-BiPOzxzb.js → ganttDiagram-FUAMR5RP-C9iwq3qm.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-B1wtF3ZS.js → gitGraphDiagram-X574FWY7-Dx-VWzUg.js} +1 -1
- package/dist/assets/{index-BkYwilkG.js → index-KygHRE3E.js} +1 -1
- package/dist/assets/index-NF7XCHAy.css +1 -0
- package/dist/assets/index-X_5ydXIE.js +610 -0
- package/dist/assets/{infoDiagram-VRGFBTTK-A19No71U.js → infoDiagram-VRGFBTTK-BG7uaEd4.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-BQsqJ_cV.js → ishikawaDiagram-OU5B5YK6-D72WAXnM.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-DAO0pVan.js → journeyDiagram-ZHPQQLJL-DKH1gjYT.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-NepmKEe2.js → kanban-definition-PNTS6WVX-3upm9JUT.js} +1 -1
- package/dist/assets/{linear-bq1PTDTW.js → linear-CcR4pc0-.js} +1 -1
- package/dist/assets/{mermaid.core-s4LTbQle.js → mermaid.core-C6yU5FSS.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-LtdbgHFH.js → mindmap-definition-NLK3R4M7-DOI2xEuv.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-tdbaCxiK.js → pegDiagram-GJSIUBJH-BVWJSgLd.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-DvkbpW8l.js → pieDiagram-5QR66LMP-jtbYezhq.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-Do4KaH-E.js → quadrantDiagram-O4NWA36T-g0u8mtPX.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-BQWULOAs.js → railroadDiagram-XR7U4H2S-k8689Wny.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-w9kei1FU.js → requirementDiagram-PLB6GJNP-DsJ22PDt.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-D2gRy0e8.js → sankeyDiagram-IPEJSGJF-CneWBRgG.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-a2sO5_Eo.js → sequenceDiagram-PO4LG4MO-DWsFCWap.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-CiPJmFEB.js → sizeCapture-INFHLROL-Bvf0YE3S.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-DAkUUlL7.js → stateDiagram-v2-GCMORJYK-Bxb3Iei8.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-DANf2R8Y.js → swimlanes-2SLR337P-DLkk7W4A.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-C6bZtBXk.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-BKpQmzrT.js → timeline-definition-EJHVYXUP-KR9bIHYC.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-BtI7qLN-.js → usecaseDiagram-POWQR4AR-DfsOrj8t.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-gXJXrAG_.js → vennDiagram-UO4OBE2U-DRSTzG3h.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-GU8Po5-n.js → wardleyDiagram-VNRHLVJA-DtEdhPgT.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-BF4J30g6.js → xychartDiagram-PMCCYNJV-B-XhTxjG.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/cloud-home-start.js +3 -1
- package/dist-server/companion/src/routes.js +60 -0
- package/dist-server/container-mcp.js +94 -77
- package/dist-server/drivers/agents-proxy.js +96 -39
- package/dist-server/drivers/pi-mcp-extension.ts +245 -299
- package/dist-server/enterprise/server/index.js +3 -1
- package/dist-server/{browser-proxy.js → harness-mcp-proxy.js} +35 -19
- package/dist-server/index.js +18242 -13645
- package/dist-server/local-computer.js +3 -1
- package/dist-server/mcp-gate.js +147 -19
- package/dist-server/mcp-remote-proxy.js +437 -0
- package/dist-server/openmausbot.js +9618 -10058
- package/dist-server/pair-cli.js +9618 -10058
- package/dist-server/permission-proxy.js +65 -1
- package/dist-server/proxy-paths.js +3 -1
- package/dist-server/server/account-signin.js +0 -2
- package/dist-server/server/activity.js +201 -0
- package/dist-server/server/auto-approve.js +39 -11
- package/dist-server/server/automatic-recovery.js +1 -1
- package/dist-server/server/boat-create-idempotency.js +0 -7
- package/dist-server/server/boat-delete-journal.js +0 -4
- package/dist-server/server/bot-package.js +1 -19
- package/dist-server/server/browser-live.js +14 -5
- package/dist-server/server/browser-runtime.js +7 -2
- package/dist-server/server/channel-queue.js +4 -1
- package/dist-server/server/chief-of-staff.js +2 -3
- package/dist-server/server/cli.js +32 -12
- package/dist-server/server/cloud-backend.js +0 -4
- package/dist-server/server/cloud-computer-tools.js +110 -0
- package/dist-server/server/cloud-home.js +0 -1
- package/dist-server/server/cloud-lending.js +0 -3
- package/dist-server/server/cloud-move-http.js +9 -3
- package/dist-server/server/cloud-move.js +18 -0
- package/dist-server/server/composio.js +31 -2
- package/dist-server/server/computer-control.js +0 -15
- package/dist-server/server/computer-observation.js +0 -74
- package/dist-server/server/computer-wait.js +33 -13
- package/dist-server/server/config.js +73 -11
- package/dist-server/server/container-computer.js +7 -19
- package/dist-server/server/contracts.js +9 -0
- package/dist-server/server/control-client.js +4 -10
- package/dist-server/server/decision-log.js +9 -6
- package/dist-server/server/delegations.js +47 -22
- package/dist-server/server/drivers/acp/core.js +64 -13
- package/dist-server/server/drivers/acp/grok.js +208 -3
- package/dist-server/server/drivers/agents-call.js +70 -29
- package/dist-server/server/drivers/agents-catalog.js +34 -12
- package/dist-server/server/drivers/agents-proxy.js +8 -30
- package/dist-server/server/drivers/antigravity.js +1 -4
- package/dist-server/server/drivers/boatagent.js +25 -4
- package/dist-server/server/drivers/cerebras.js +3 -3
- package/dist-server/server/drivers/chat-mcp-tools.js +29 -19
- package/dist-server/server/drivers/claude.js +33 -19
- package/dist-server/server/drivers/codex.js +84 -10
- package/dist-server/server/drivers/openai-chat.js +14 -9
- package/dist-server/server/drivers/pi.js +48 -4
- package/dist-server/server/drivers/retry.js +8 -4
- package/dist-server/server/engine-install.js +1 -5
- package/dist-server/server/environment.js +3 -0
- package/dist-server/server/guarded-requests.js +2 -1
- package/dist-server/server/harness/registry.js +0 -1
- package/dist-server/server/{browser-proxy.js → harness-mcp-proxy.js} +40 -20
- package/dist-server/server/index.js +1929 -507
- package/dist-server/server/lending-memory.js +12 -8
- package/dist-server/server/live-call-controller.js +868 -0
- package/dist-server/server/live-call.js +216 -0
- package/dist-server/server/mcp-gate-config.js +43 -12
- package/dist-server/server/mcp-gate.js +127 -25
- package/dist-server/server/mcp-http.js +46 -8
- package/dist-server/server/mcp-remote-proxy.js +108 -0
- package/dist-server/server/memory-entries.js +38 -8
- package/dist-server/server/memory-organize.js +1 -8
- package/dist-server/server/memory-topics.js +4 -4
- package/dist-server/server/memory-upkeep.js +13 -15
- package/dist-server/server/message-file.js +5 -9
- package/dist-server/server/new-bot-defaults.js +3 -0
- package/dist-server/server/outbound-counts.js +79 -0
- package/dist-server/server/outbound-requests.js +60 -0
- package/dist-server/server/package-import.js +1 -1
- package/dist-server/server/peer-delivery.js +1 -0
- package/dist-server/server/peer-provenance.js +4 -2
- package/dist-server/server/permission-proxy.js +15 -1
- package/dist-server/server/plan-usage.js +797 -0
- package/dist-server/server/proxy-paths.js +3 -1
- package/dist-server/server/redact.js +2 -0
- package/dist-server/server/request-auth.js +3 -2
- package/dist-server/server/room-handoffs.js +5 -13
- package/dist-server/server/routes/live.js +98 -0
- package/dist-server/server/routine-requests.js +1 -1
- package/dist-server/server/routines.js +5 -1
- package/dist-server/server/setup-mode.js +0 -2
- package/dist-server/server/skill-learn.js +0 -1
- package/dist-server/server/skill-library.js +195 -3
- package/dist-server/server/skills-library-migration.js +235 -0
- package/dist-server/server/skills.js +66 -3
- package/dist-server/server/steer-queue.js +13 -1
- package/dist-server/server/store.js +41 -5
- package/dist-server/server/surface.js +74 -23
- package/dist-server/server/system-prompt.js +4 -4
- package/dist-server/server/team-backup.js +2 -1
- package/dist-server/server/team-memory.js +209 -0
- package/dist-server/server/thread-events.js +3 -3
- package/dist-server/server/tunnel.js +20 -1
- package/dist-server/server/turn-log.js +10 -0
- package/dist-server/server/turn-resources.js +124 -0
- package/dist-server/server/vps-computer.js +4 -14
- package/dist-server/server/workspace.js +85 -47
- package/dist-server/shared/activity.js +3 -0
- package/dist-server/shared/ask-question.js +13 -0
- package/dist-server/shared/bot-avatar.js +8 -0
- package/dist-server/shared/call-consent.js +28 -0
- package/dist-server/shared/connector-scopes.js +78 -0
- package/dist-server/shared/live-approval.js +124 -0
- package/dist-server/shared/live-call.js +176 -0
- package/dist-server/shared/outbound.js +128 -0
- package/dist-server/shared/skill-md.js +10 -0
- package/dist-server/shared/team-backup.js +3 -0
- package/dist-server/shared/tool-scope-support.js +25 -0
- package/dist-server/shared/tool-scope.js +136 -0
- package/dist-server/shared/tool-surface.js +3 -2
- package/dist-server/src/lib/thread-refs.js +406 -0
- package/dist-server/vps-container-mcp.js +94 -77
- package/dist-server/workspace-backup.worker.js +89 -100
- package/enterprise/server/index.js +3 -1
- package/package.json +1 -1
- package/dist/assets/channel-BU94VpxE.js +0 -1
- package/dist/assets/index-Biji-bfL.css +0 -1
- package/dist/assets/index-DZlhoES0.js +0 -597
- package/dist/assets/swimlanesDiagram-TC7HE7FX-CdHxG8aM.js +0 -8
- package/dist-server/server/drivers/chat-boat-tools.js +0 -90
- package/dist-server/server/drivers/grokagent.js +0 -4
- package/dist-server/server/openmaus-status-capsule.js +0 -329
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{c as r,s as e}from"./flowDiagram-KWPJA3E3-Bcb4Z75S.js";import{_ as a}from"./mermaid.core-s4LTbQle.js";import"./chunk-5VM5RSS4-Dx_Slpw9.js";import"./chunk-XXDRQBXY-gWnLt7SN.js";import"./chunk-WEXAMYUT-6HwhsDKw.js";import"./chunk-GWA4HPMP-BLx07SPb.js";import"./channel-BU94VpxE.js";import"./index-DZlhoES0.js";var o=a(t=>`${e(t)}
|
|
2
|
-
.swimlane.cluster:not([data-color-id]) rect {
|
|
3
|
-
stroke: ${t.clusterBorder} !important;
|
|
4
|
-
}
|
|
5
|
-
[data-look="neo"].cluster rect {
|
|
6
|
-
filter: none;
|
|
7
|
-
}
|
|
8
|
-
`,"getStyles"),s=o,u=r({styles:s});export{u as diagram};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { isolatedRemoteCommand, runCommand, screenshotBoat } from "../boat.js";
|
|
2
|
-
import { createControlClient, CONTROL_REFUSAL_PLAIN } from "../control-client.js";
|
|
3
|
-
const coordinate = { type: "integer", minimum: 0, maximum: 32767 };
|
|
4
|
-
const tool = (name, description, properties = {}, required = []) => ({ name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } });
|
|
5
|
-
const TOOLS = [
|
|
6
|
-
tool("screenshot", "See the assigned cloud desktop at native pixel resolution."),
|
|
7
|
-
tool("get_screen_size", "Get the cloud desktop width and height."),
|
|
8
|
-
tool("click", "Click a point on the cloud desktop.", { x: coordinate, y: coordinate, button: { type: "string", enum: ["left", "middle", "right"] }, count: { type: "integer", minimum: 1, maximum: 3 } }, ["x", "y"]),
|
|
9
|
-
tool("move", "Move the cloud mouse pointer.", { x: coordinate, y: coordinate }, ["x", "y"]),
|
|
10
|
-
tool("drag", "Drag on the cloud desktop.", { x: coordinate, y: coordinate, to_x: coordinate, to_y: coordinate }, ["x", "y", "to_x", "to_y"]),
|
|
11
|
-
tool("type_text", "Type Unicode text into the focused cloud application.", { text: { type: "string", maxLength: 4000 } }, ["text"]),
|
|
12
|
-
tool("key_press", "Press an X11 key or shortcut.", { key: { type: "string", pattern: "^[A-Za-z0-9_+]+$", minLength: 1, maxLength: 100 } }, ["key"]),
|
|
13
|
-
tool("scroll", "Scroll at a point on the cloud desktop.", { x: coordinate, y: coordinate, direction: { type: "string", enum: ["up", "down", "left", "right"] }, amount: { type: "integer", minimum: 1, maximum: 30 } }, ["x", "y", "direction"]),
|
|
14
|
-
tool("open_url", "Request opening an HTTP or HTTPS URL in the cloud desktop browser; inspect the screen to confirm it loaded.", { url: { type: "string", pattern: "^https?://", maxLength: 2000 } }, ["url"]),
|
|
15
|
-
tool("exec", "Run a shell command on the assigned cloud computer.", { command: { type: "string", minLength: 1, maxLength: 4000 } }, ["command"]),
|
|
16
|
-
];
|
|
17
|
-
const quote = (value) => "'" + value.replace(/'/g, "'\\''") + "'";
|
|
18
|
-
const buttons = { left: 1, middle: 2, right: 3 };
|
|
19
|
-
const scrollButtons = { up: 4, down: 5, left: 6, right: 7 };
|
|
20
|
-
/** Uses only the leased descriptor supplied by the harness. Schema validation
|
|
21
|
-
* and user approval happen in the shared chat tool executor before this call. */
|
|
22
|
-
export class ChatBoatClient {
|
|
23
|
-
closed = false;
|
|
24
|
-
control;
|
|
25
|
-
descriptor;
|
|
26
|
-
constructor(descriptor) {
|
|
27
|
-
this.descriptor = descriptor;
|
|
28
|
-
if (!descriptor.control?.url || !descriptor.control.token)
|
|
29
|
-
throw new Error("Cloud computer control gate missing");
|
|
30
|
-
this.control = createControlClient(descriptor.control);
|
|
31
|
-
}
|
|
32
|
-
async tools() { return TOOLS; }
|
|
33
|
-
async close() { this.closed = true; }
|
|
34
|
-
async call(_method, params, signal) {
|
|
35
|
-
signal.throwIfAborted();
|
|
36
|
-
if (this.closed)
|
|
37
|
-
throw new Error("Cloud computer session closed");
|
|
38
|
-
const state = await this.control.state(true);
|
|
39
|
-
signal.throwIfAborted();
|
|
40
|
-
if (this.closed)
|
|
41
|
-
throw new Error("Cloud computer session closed");
|
|
42
|
-
if (state.held || state.blockedReason)
|
|
43
|
-
return { isError: true, content: [{ type: "text", text: state.blockedReason || CONTROL_REFUSAL_PLAIN }] };
|
|
44
|
-
const { name, arguments: a } = params;
|
|
45
|
-
const config = { box: { token: this.descriptor.token } };
|
|
46
|
-
const id = this.descriptor.boxId;
|
|
47
|
-
if (name === "screenshot") {
|
|
48
|
-
const shot = await screenshotBoat(config, "", id, { signal, nativeSize: true });
|
|
49
|
-
signal.throwIfAborted();
|
|
50
|
-
return { content: [{ type: "image", mimeType: "image/jpeg", data: shot.png }] };
|
|
51
|
-
}
|
|
52
|
-
const mouse = `xdotool mousemove --sync ${a.x} ${a.y}`;
|
|
53
|
-
let command;
|
|
54
|
-
switch (name) {
|
|
55
|
-
case "get_screen_size":
|
|
56
|
-
command = "xdotool getdisplaygeometry";
|
|
57
|
-
break;
|
|
58
|
-
case "click":
|
|
59
|
-
command = `${mouse} click --repeat ${a.count ?? 1} --delay 100 ${buttons[String(a.button ?? "left")]}`;
|
|
60
|
-
break;
|
|
61
|
-
case "move":
|
|
62
|
-
command = mouse;
|
|
63
|
-
break;
|
|
64
|
-
case "drag":
|
|
65
|
-
command = `${mouse} mousedown 1 mousemove --sync ${a.to_x} ${a.to_y} mouseup 1`;
|
|
66
|
-
break;
|
|
67
|
-
case "type_text":
|
|
68
|
-
command = `printf %s ${quote(Buffer.from(String(a.text)).toString("base64"))} | base64 -d | xclip -selection clipboard && xdotool key --clearmodifiers ctrl+v`;
|
|
69
|
-
break;
|
|
70
|
-
case "key_press":
|
|
71
|
-
command = `xdotool key --clearmodifiers ${quote(String(a.key))}`;
|
|
72
|
-
break;
|
|
73
|
-
case "scroll":
|
|
74
|
-
command = `${mouse} click --repeat ${a.amount ?? 3} --delay 80 ${scrollButtons[String(a.direction)]}`;
|
|
75
|
-
break;
|
|
76
|
-
case "open_url":
|
|
77
|
-
command = `nohup xdg-open ${quote(String(a.url))} >/dev/null 2>&1 </dev/null &`;
|
|
78
|
-
break;
|
|
79
|
-
case "exec":
|
|
80
|
-
command = String(a.command);
|
|
81
|
-
break;
|
|
82
|
-
default: throw new Error("Unknown cloud computer tool");
|
|
83
|
-
}
|
|
84
|
-
const result = await runCommand(config, id, isolatedRemoteCommand(command), { signal });
|
|
85
|
-
signal.throwIfAborted();
|
|
86
|
-
if (name === "open_url" && result.ok)
|
|
87
|
-
return { content: [{ type: "text", text: "Browser launch requested. Page loading is not confirmed; inspect the screen before continuing." }] };
|
|
88
|
-
return { isError: !result.ok, content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { closeSync, constants, fstatSync, lstatSync, openSync, readFileSync, } from "node:fs";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { parseJson } from "./schema.js";
|
|
7
|
-
const SCHEMA = "aos.openmausbot_status.v1";
|
|
8
|
-
const TTL_SECONDS = 300;
|
|
9
|
-
const MAX_CACHE_BYTES = 16_384;
|
|
10
|
-
const DIGEST = /^sha256:[a-f0-9]{64}$/;
|
|
11
|
-
const UTC_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
|
|
12
|
-
const digestSchema = z.string().regex(DIGEST);
|
|
13
|
-
const slotSchema = z.object({
|
|
14
|
-
slot: z.string().regex(/^vm-[1-4]$/),
|
|
15
|
-
container: z.enum(["running", "stopped", "missing"]),
|
|
16
|
-
readiness: z.enum(["ready", "not_ready"]),
|
|
17
|
-
network: z.enum(["loopback", "unsafe", "unknown"]),
|
|
18
|
-
security: z.enum(["hardened", "unsafe", "unknown"]),
|
|
19
|
-
persistence: z.enum(["durable", "unsafe", "unknown"]),
|
|
20
|
-
}).strict();
|
|
21
|
-
const uiSchema = z.object({
|
|
22
|
-
two_up: z.boolean(),
|
|
23
|
-
max_visible: z.union([z.literal(1), z.literal(2)]),
|
|
24
|
-
max_interactive: z.literal(1),
|
|
25
|
-
default_watch_only: z.boolean(),
|
|
26
|
-
}).strict();
|
|
27
|
-
const capsuleSchema = z.object({
|
|
28
|
-
schema: z.literal(SCHEMA),
|
|
29
|
-
observed_at: z.string().regex(UTC_TIMESTAMP),
|
|
30
|
-
fresh_until: z.string().regex(UTC_TIMESTAMP),
|
|
31
|
-
ttl_seconds: z.literal(TTL_SECONDS),
|
|
32
|
-
source_sha256: digestSchema.nullable(),
|
|
33
|
-
dual_view_sha256: digestSchema.nullable(),
|
|
34
|
-
receipt_sha256: digestSchema,
|
|
35
|
-
refresh_status: z.enum(["success", "failed"]),
|
|
36
|
-
failure_reason: z.enum([
|
|
37
|
-
"config_unavailable",
|
|
38
|
-
"bots_unavailable",
|
|
39
|
-
"vm_status_unavailable",
|
|
40
|
-
"capacity_exceeded",
|
|
41
|
-
"source_hash_unavailable",
|
|
42
|
-
"source_hash_mismatch",
|
|
43
|
-
]).optional(),
|
|
44
|
-
runtime_state: z.enum(["ready", "degraded", "unknown"]),
|
|
45
|
-
mode: z.enum(["shared", "per-bot", "unknown"]),
|
|
46
|
-
max_instances: z.number().int().min(1).max(4).nullable(),
|
|
47
|
-
ready_count: z.number().int().min(0).max(4),
|
|
48
|
-
slots: z.array(slotSchema).max(4),
|
|
49
|
-
ui: uiSchema,
|
|
50
|
-
}).strict();
|
|
51
|
-
const jsonObjectSchema = z.record(z.string(), z.custom());
|
|
52
|
-
export const OPENMAUS_STATUS_CACHE_PATH = join(homedir(), ".local/state/aos-session-bridge/openmausbot/latest.json");
|
|
53
|
-
function canonicalValue(value) {
|
|
54
|
-
if (Array.isArray(value))
|
|
55
|
-
return value.map(canonicalValue);
|
|
56
|
-
const parsedObject = jsonObjectSchema.safeParse(value);
|
|
57
|
-
if (!parsedObject.success)
|
|
58
|
-
return value;
|
|
59
|
-
const sorted = {};
|
|
60
|
-
for (const key of Object.keys(parsedObject.data).sort()) {
|
|
61
|
-
const child = parsedObject.data[key];
|
|
62
|
-
if (child !== undefined)
|
|
63
|
-
sorted[key] = canonicalValue(child);
|
|
64
|
-
}
|
|
65
|
-
return sorted;
|
|
66
|
-
}
|
|
67
|
-
function canonical(value) {
|
|
68
|
-
return JSON.stringify(canonicalValue(value));
|
|
69
|
-
}
|
|
70
|
-
function sha256(value) {
|
|
71
|
-
return `sha256:${createHash("sha256").update(value, "utf8").digest("hex")}`;
|
|
72
|
-
}
|
|
73
|
-
function timestamp(value) {
|
|
74
|
-
const parsed = Date.parse(value);
|
|
75
|
-
if (!Number.isFinite(parsed))
|
|
76
|
-
return null;
|
|
77
|
-
if (new Date(parsed).toISOString().replace(".000Z", "Z") !== value)
|
|
78
|
-
return null;
|
|
79
|
-
return parsed;
|
|
80
|
-
}
|
|
81
|
-
function expectedUi(twoUp) {
|
|
82
|
-
return {
|
|
83
|
-
two_up: twoUp,
|
|
84
|
-
max_visible: twoUp ? 2 : 1,
|
|
85
|
-
max_interactive: 1,
|
|
86
|
-
default_watch_only: twoUp,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function sameUi(left, right) {
|
|
90
|
-
return (left.two_up === right.two_up &&
|
|
91
|
-
left.max_visible === right.max_visible &&
|
|
92
|
-
left.max_interactive === right.max_interactive &&
|
|
93
|
-
left.default_watch_only === right.default_watch_only);
|
|
94
|
-
}
|
|
95
|
-
function unsignedDocument(capsule) {
|
|
96
|
-
const document = {
|
|
97
|
-
schema: capsule.schema,
|
|
98
|
-
observed_at: capsule.observed_at,
|
|
99
|
-
fresh_until: capsule.fresh_until,
|
|
100
|
-
ttl_seconds: capsule.ttl_seconds,
|
|
101
|
-
source_sha256: capsule.source_sha256,
|
|
102
|
-
dual_view_sha256: capsule.dual_view_sha256,
|
|
103
|
-
refresh_status: capsule.refresh_status,
|
|
104
|
-
runtime_state: capsule.runtime_state,
|
|
105
|
-
mode: capsule.mode,
|
|
106
|
-
max_instances: capsule.max_instances,
|
|
107
|
-
ready_count: capsule.ready_count,
|
|
108
|
-
slots: capsule.slots.map((slot) => ({
|
|
109
|
-
slot: slot.slot,
|
|
110
|
-
container: slot.container,
|
|
111
|
-
readiness: slot.readiness,
|
|
112
|
-
network: slot.network,
|
|
113
|
-
security: slot.security,
|
|
114
|
-
persistence: slot.persistence,
|
|
115
|
-
})),
|
|
116
|
-
ui: {
|
|
117
|
-
two_up: capsule.ui.two_up,
|
|
118
|
-
max_visible: capsule.ui.max_visible,
|
|
119
|
-
max_interactive: capsule.ui.max_interactive,
|
|
120
|
-
default_watch_only: capsule.ui.default_watch_only,
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
if (capsule.failure_reason !== undefined)
|
|
124
|
-
document.failure_reason = capsule.failure_reason;
|
|
125
|
-
return document;
|
|
126
|
-
}
|
|
127
|
-
function validSlotState(slot) {
|
|
128
|
-
return (slot.readiness !== "ready" ||
|
|
129
|
-
(slot.container === "running" &&
|
|
130
|
-
slot.network === "loopback" &&
|
|
131
|
-
slot.security === "hardened" &&
|
|
132
|
-
slot.persistence === "durable"));
|
|
133
|
-
}
|
|
134
|
-
function validateCapsule(value) {
|
|
135
|
-
const parsed = capsuleSchema.safeParse(value);
|
|
136
|
-
if (!parsed.success)
|
|
137
|
-
return null;
|
|
138
|
-
const capsule = parsed.data;
|
|
139
|
-
const observed = timestamp(capsule.observed_at);
|
|
140
|
-
const freshUntil = timestamp(capsule.fresh_until);
|
|
141
|
-
if (observed === null || freshUntil === null || freshUntil - observed !== TTL_SECONDS * 1000)
|
|
142
|
-
return null;
|
|
143
|
-
if (capsule.receipt_sha256 !== sha256(canonical(unsignedDocument(capsule))))
|
|
144
|
-
return null;
|
|
145
|
-
if (!capsule.slots.every((slot, index) => slot.slot === `vm-${index + 1}` && validSlotState(slot))) {
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
const readyCount = capsule.slots.filter((slot) => slot.readiness === "ready").length;
|
|
149
|
-
if (capsule.ready_count !== readyCount)
|
|
150
|
-
return null;
|
|
151
|
-
const twoUp = Boolean(capsule.refresh_status === "success" &&
|
|
152
|
-
capsule.mode === "per-bot" &&
|
|
153
|
-
capsule.max_instances !== null &&
|
|
154
|
-
capsule.max_instances >= 2 &&
|
|
155
|
-
capsule.source_sha256 !== null &&
|
|
156
|
-
capsule.dual_view_sha256 !== null &&
|
|
157
|
-
capsule.source_sha256 === capsule.dual_view_sha256);
|
|
158
|
-
if (!sameUi(capsule.ui, expectedUi(twoUp)))
|
|
159
|
-
return null;
|
|
160
|
-
if (capsule.refresh_status === "failed") {
|
|
161
|
-
if (capsule.failure_reason === undefined ||
|
|
162
|
-
capsule.runtime_state !== "unknown" ||
|
|
163
|
-
capsule.mode !== "unknown" ||
|
|
164
|
-
capsule.max_instances !== null ||
|
|
165
|
-
capsule.ready_count !== 0 ||
|
|
166
|
-
capsule.slots.length !== 0 ||
|
|
167
|
-
!sameUi(capsule.ui, expectedUi(false)))
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
const expectedRuntime = capsule.slots.length > 0 && readyCount === capsule.slots.length ? "ready" : "degraded";
|
|
172
|
-
if (capsule.failure_reason !== undefined ||
|
|
173
|
-
capsule.runtime_state !== expectedRuntime ||
|
|
174
|
-
(capsule.mode !== "shared" && capsule.mode !== "per-bot") ||
|
|
175
|
-
capsule.max_instances === null ||
|
|
176
|
-
readyCount > capsule.max_instances ||
|
|
177
|
-
capsule.source_sha256 === null ||
|
|
178
|
-
capsule.dual_view_sha256 === null ||
|
|
179
|
-
capsule.source_sha256 !== capsule.dual_view_sha256)
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
return capsule;
|
|
183
|
-
}
|
|
184
|
-
function privateCache(path) {
|
|
185
|
-
const uid = process.getuid?.();
|
|
186
|
-
if (uid === undefined)
|
|
187
|
-
return null;
|
|
188
|
-
let descriptor = null;
|
|
189
|
-
try {
|
|
190
|
-
const parentStatus = lstatSync(dirname(path));
|
|
191
|
-
const fileStatus = lstatSync(path);
|
|
192
|
-
if (parentStatus.isSymbolicLink() ||
|
|
193
|
-
!parentStatus.isDirectory() ||
|
|
194
|
-
parentStatus.uid !== uid ||
|
|
195
|
-
(parentStatus.mode & 0o777) !== 0o700)
|
|
196
|
-
return null;
|
|
197
|
-
if (fileStatus.isSymbolicLink() ||
|
|
198
|
-
!fileStatus.isFile() ||
|
|
199
|
-
fileStatus.uid !== uid ||
|
|
200
|
-
(fileStatus.mode & 0o777) !== 0o600 ||
|
|
201
|
-
fileStatus.size > MAX_CACHE_BYTES)
|
|
202
|
-
return null;
|
|
203
|
-
descriptor = openSync(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
204
|
-
const openedStatus = fstatSync(descriptor);
|
|
205
|
-
if (!openedStatus.isFile() ||
|
|
206
|
-
openedStatus.uid !== uid ||
|
|
207
|
-
(openedStatus.mode & 0o777) !== 0o600 ||
|
|
208
|
-
openedStatus.dev !== fileStatus.dev ||
|
|
209
|
-
openedStatus.ino !== fileStatus.ino ||
|
|
210
|
-
openedStatus.size > MAX_CACHE_BYTES)
|
|
211
|
-
return null;
|
|
212
|
-
const contents = readFileSync(descriptor);
|
|
213
|
-
return contents.length <= MAX_CACHE_BYTES ? contents : null;
|
|
214
|
-
}
|
|
215
|
-
catch {
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
finally {
|
|
219
|
-
if (descriptor !== null) {
|
|
220
|
-
try {
|
|
221
|
-
closeSync(descriptor);
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
// Cleanup failures must not escape the fail-closed cache read.
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function unknownDigest(reason, freshness = "unknown", receipt) {
|
|
230
|
-
return {
|
|
231
|
-
schema: SCHEMA,
|
|
232
|
-
freshness,
|
|
233
|
-
reason,
|
|
234
|
-
...receipt,
|
|
235
|
-
runtimeState: "unknown",
|
|
236
|
-
mode: "unknown",
|
|
237
|
-
maxInstances: null,
|
|
238
|
-
readyCount: 0,
|
|
239
|
-
slots: [],
|
|
240
|
-
ui: {
|
|
241
|
-
twoUp: false,
|
|
242
|
-
maxVisible: 1,
|
|
243
|
-
maxInteractive: 1,
|
|
244
|
-
defaultWatchOnly: false,
|
|
245
|
-
oneActiveController: true,
|
|
246
|
-
},
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
export function readOpenMausStatus(options = {}) {
|
|
250
|
-
const raw = privateCache(options.cachePath ?? OPENMAUS_STATUS_CACHE_PATH);
|
|
251
|
-
if (raw === null)
|
|
252
|
-
return unknownDigest("missing_or_insecure");
|
|
253
|
-
let capsule;
|
|
254
|
-
try {
|
|
255
|
-
capsule = validateCapsule(parseJson(raw.toString("utf8")));
|
|
256
|
-
}
|
|
257
|
-
catch {
|
|
258
|
-
capsule = null;
|
|
259
|
-
}
|
|
260
|
-
if (capsule === null)
|
|
261
|
-
return unknownDigest("invalid");
|
|
262
|
-
const observed = timestamp(capsule.observed_at);
|
|
263
|
-
const freshUntil = timestamp(capsule.fresh_until);
|
|
264
|
-
const now = (options.now ?? new Date()).getTime();
|
|
265
|
-
const receipt = { observedAt: capsule.observed_at, receiptSha256: capsule.receipt_sha256 };
|
|
266
|
-
if (!Number.isFinite(now) || now < observed)
|
|
267
|
-
return unknownDigest("clock_skew");
|
|
268
|
-
if (now >= freshUntil)
|
|
269
|
-
return unknownDigest("stale", "stale", receipt);
|
|
270
|
-
if (capsule.refresh_status === "failed")
|
|
271
|
-
return unknownDigest("refresh_failed", "fresh", receipt);
|
|
272
|
-
const result = {
|
|
273
|
-
schema: SCHEMA,
|
|
274
|
-
freshness: "fresh",
|
|
275
|
-
...receipt,
|
|
276
|
-
runtimeState: capsule.runtime_state,
|
|
277
|
-
mode: capsule.mode,
|
|
278
|
-
maxInstances: capsule.max_instances,
|
|
279
|
-
readyCount: capsule.ready_count,
|
|
280
|
-
slots: capsule.slots,
|
|
281
|
-
ui: {
|
|
282
|
-
twoUp: capsule.ui.two_up,
|
|
283
|
-
maxVisible: capsule.ui.max_visible,
|
|
284
|
-
maxInteractive: 1,
|
|
285
|
-
defaultWatchOnly: capsule.ui.default_watch_only,
|
|
286
|
-
oneActiveController: true,
|
|
287
|
-
},
|
|
288
|
-
};
|
|
289
|
-
if (capsule.source_sha256 !== null)
|
|
290
|
-
result.sourceSha256 = capsule.source_sha256;
|
|
291
|
-
if (capsule.dual_view_sha256 !== null)
|
|
292
|
-
result.dualViewSha256 = capsule.dual_view_sha256;
|
|
293
|
-
return result;
|
|
294
|
-
}
|
|
295
|
-
export function openMausStatusSystemPrompt(options = {}) {
|
|
296
|
-
const status = readOpenMausStatus(options);
|
|
297
|
-
const receipt = [
|
|
298
|
-
status.observedAt ? `observed_at=${status.observedAt}` : null,
|
|
299
|
-
status.receiptSha256 ? `receipt_sha256=${status.receiptSha256}` : null,
|
|
300
|
-
status.sourceSha256 ? `source_sha256=${status.sourceSha256}` : null,
|
|
301
|
-
status.dualViewSha256 ? `accepted_dual_view_sha256=${status.dualViewSha256}` : null,
|
|
302
|
-
status.sourceSha256 && status.dualViewSha256
|
|
303
|
-
? `source_match=${status.sourceSha256 === status.dualViewSha256}`
|
|
304
|
-
: null,
|
|
305
|
-
].filter(Boolean).join("; ");
|
|
306
|
-
const runtime = status.freshness === "fresh" && status.reason === undefined
|
|
307
|
-
? [
|
|
308
|
-
`runtime_state=${status.runtimeState}`,
|
|
309
|
-
`mode=${status.mode}`,
|
|
310
|
-
`maximum_instances=${status.maxInstances}`,
|
|
311
|
-
`ready_count=${status.readyCount}`,
|
|
312
|
-
].join("; ")
|
|
313
|
-
: "runtime_state=unknown; mode=unknown; maximum_instances=unknown; ready_count=0";
|
|
314
|
-
const slots = status.slots.length
|
|
315
|
-
? status.slots
|
|
316
|
-
.map((slot) => `${slot.slot}(container=${slot.container},readiness=${slot.readiness},network=${slot.network},security=${slot.security},persistence=${slot.persistence})`)
|
|
317
|
-
.join(",")
|
|
318
|
-
: "none";
|
|
319
|
-
return [
|
|
320
|
-
"TRUSTED OPENMAUSBOT STATUS (read-only, validated, no transcript or credential data):",
|
|
321
|
-
`schema=${status.schema}; freshness=${status.freshness}${status.reason ? `; reason=${status.reason}` : ""}`,
|
|
322
|
-
receipt || "receipt=unavailable",
|
|
323
|
-
runtime,
|
|
324
|
-
`anonymous_slots=${slots}`,
|
|
325
|
-
`ui.two_up=${status.ui.twoUp}; ui.max_visible=${status.ui.maxVisible}; ui.max_interactive=1; ui.default_watch_only=${status.ui.defaultWatchOnly}; one_active_controller=true`,
|
|
326
|
-
"Opening a viewer or two-up workspace never starts or provisions a VM. Only one pane may be interactive at a time; switching control must release the previous pane before activating the next.",
|
|
327
|
-
"Treat missing, stale, failed, clock-skewed, malformed, or receipt-hash-mismatched runtime data as unknown. Do not infer bot identities, viewer URLs, paths, messages, models, accounts, or credentials from this block.",
|
|
328
|
-
].join("\n");
|
|
329
|
-
}
|