openmausbot 0.1.94 → 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-bxM7NV3N.js → DesktopViewer-BwWpc4RK.js} +1 -1
- package/dist/assets/{abnfDiagram-O67JEVCF-BhMdJhRJ.js → abnfDiagram-O67JEVCF-jsQkIqTn.js} +1 -1
- package/dist/assets/{arc-B5itKDcx.js → arc-7kei4Hsu.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-C5d7UY6U.js → architectureDiagram-NJMV4G6O-CRWDFDMq.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-BrZIhMmu.js → blockDiagram-BEXU5L5S-CTKW_IKs.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-7I0ArfbD.js → c4Diagram-YGBWAQC7-BBTW7-6M.js} +1 -1
- package/dist/assets/channel-DS2NbT5x.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-BnEsyN36.js → chunk-2Q5K7J3B-M_Ox-MkD.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-BXATQ52s.js → chunk-3FUC2YCW-D2YiN-Ud.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-B0BpTkEx.js → chunk-5VM5RSS4-BmVYJ0f8.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-BtLTz6FR.js → chunk-GTNCS2PH-BtiLVVnZ.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-D6gcZOYt.js → chunk-GWA4HPMP-DFYSb6J6.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-DCLrosvf.js → chunk-JWPE2WC7-mknKBzgV.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-B9JsknV9.js → chunk-NETBCI7D-DgSYGiOu.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-CsoTxw7z.js → chunk-WEXAMYUT-C7ZvuguH.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-0F_frB0c.js → chunk-XXDRQBXY-CPqxINpA.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-DkrpnflX.js → classDiagram-v2-NBCMYWYE-Cd6xfJaC.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-BNDwYBt9.js → cose-bilkent-JH36ORCC-BSXY5qRh.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-JUkNr1Mk.js → cynefin-OW5HDTMX-D_lhEMj1.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-DKeh9N4M.js → cynefinDiagram-VND7K2PF-Da9FrFwk.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-ve-6T_wX.js → dagre-6A5THRUB-T77jMOXe.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-BuJ2d8rT.js → diagram-22UHCM2B-Dkj96X5E.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-BgOs_Ni-.js → diagram-3UASUU5V-CMi9zlD_.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-DMK6VmcP.js → diagram-ATOU4E4O-CXK6YUfS.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-DksASlcY.js → diagram-CDSNMT55-BE7B1u9Q.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-Bgn8I5k6.js → diagram-MLGK6HIB-CCMQphKr.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-zK0jqO8N.js → diagram-MPIPVDR6-iHJ_-tGH.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-vKrbzTwr.js → ebnfDiagram-ZINNZB2B-DONsCWQ7.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-Bzv2mPNf.js → elk-276RUBZZ-CU_WOaXk.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-CvOyYuxu.js → erDiagram-OPXOYQCR-BeYwM04G.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-CtbnDbc0.js → flowDiagram-KWPJA3E3-Bdw9DqEl.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP-c4dMRYyG.js → ganttDiagram-FUAMR5RP-C9iwq3qm.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-B34uaQho.js → gitGraphDiagram-X574FWY7-Dx-VWzUg.js} +1 -1
- package/dist/assets/{index-CPiqc_DN.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-o64ma4CI.js → infoDiagram-VRGFBTTK-BG7uaEd4.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-DV4C9BAm.js → ishikawaDiagram-OU5B5YK6-D72WAXnM.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-Bf0AHk1H.js → journeyDiagram-ZHPQQLJL-DKH1gjYT.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-B1UMSKmE.js → kanban-definition-PNTS6WVX-3upm9JUT.js} +1 -1
- package/dist/assets/{linear-BpKhuyLm.js → linear-CcR4pc0-.js} +1 -1
- package/dist/assets/{mermaid.core-B_BKNCw5.js → mermaid.core-C6yU5FSS.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-DeARruT1.js → mindmap-definition-NLK3R4M7-DOI2xEuv.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-BOQEk_1D.js → pegDiagram-GJSIUBJH-BVWJSgLd.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-EIfoiTZo.js → pieDiagram-5QR66LMP-jtbYezhq.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-GgZwT-fi.js → quadrantDiagram-O4NWA36T-g0u8mtPX.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-D9rDQomj.js → railroadDiagram-XR7U4H2S-k8689Wny.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-DAh1MIeo.js → requirementDiagram-PLB6GJNP-DsJ22PDt.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-CPr6Uz64.js → sankeyDiagram-IPEJSGJF-CneWBRgG.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-BU6VIdcm.js → sequenceDiagram-PO4LG4MO-DWsFCWap.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-qF2HO41r.js → sizeCapture-INFHLROL-Bvf0YE3S.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-DlJ8G4MD.js → stateDiagram-v2-GCMORJYK-Bxb3Iei8.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-DzYE8I54.js → swimlanes-2SLR337P-DLkk7W4A.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-C6bZtBXk.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-B7wzEQ0A.js → timeline-definition-EJHVYXUP-KR9bIHYC.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-BvGgrxIP.js → usecaseDiagram-POWQR4AR-DfsOrj8t.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-CEECdgQg.js → vennDiagram-UO4OBE2U-DRSTzG3h.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-XQHA0P_P.js → wardleyDiagram-VNRHLVJA-DtEdhPgT.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-B5mLcZI2.js → xychartDiagram-PMCCYNJV-B-XhTxjG.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/cloud-home-start.js +2 -1
- package/dist-server/companion/src/routes.js +39 -0
- package/dist-server/container-mcp.js +2 -2
- package/dist-server/drivers/agents-proxy.js +58 -38
- package/dist-server/enterprise/server/index.js +2 -1
- package/dist-server/{browser-proxy.js → harness-mcp-proxy.js} +35 -19
- package/dist-server/index.js +3159 -2313
- package/dist-server/local-computer.js +2 -1
- package/dist-server/openmausbot.js +314 -1336
- package/dist-server/pair-cli.js +314 -1336
- package/dist-server/proxy-paths.js +2 -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 +6 -0
- 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-runtime.js +1 -2
- package/dist-server/server/chief-of-staff.js +2 -3
- 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/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/config.js +29 -1
- 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/drivers/acp/core.js +7 -5
- package/dist-server/server/drivers/agents-call.js +42 -29
- package/dist-server/server/drivers/agents-catalog.js +24 -11
- 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 +23 -4
- package/dist-server/server/drivers/cerebras.js +3 -3
- package/dist-server/server/drivers/chat-mcp-tools.js +4 -7
- package/dist-server/server/drivers/claude.js +16 -14
- package/dist-server/server/drivers/openai-chat.js +3 -6
- package/dist-server/server/drivers/retry.js +8 -4
- package/dist-server/server/engine-install.js +1 -5
- 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 +789 -256
- package/dist-server/server/lending-memory.js +12 -8
- 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/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/proxy-paths.js +2 -1
- package/dist-server/server/room-handoffs.js +5 -13
- 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 +0 -15
- package/dist-server/server/store.js +9 -1
- package/dist-server/server/surface.js +65 -20
- package/dist-server/server/system-prompt.js +4 -4
- package/dist-server/server/team-memory.js +209 -0
- package/dist-server/server/thread-events.js +2 -2
- 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/bot-avatar.js +8 -0
- package/dist-server/shared/connector-scopes.js +78 -0
- package/dist-server/shared/outbound.js +128 -0
- package/dist-server/shared/tool-surface.js +3 -2
- package/dist-server/vps-container-mcp.js +2 -2
- package/enterprise/server/index.js +2 -1
- package/package.json +1 -1
- package/dist/assets/channel-CdJX6i8k.js +0 -1
- package/dist/assets/index-CPYrGsv1.js +0 -610
- package/dist/assets/index-CzT42GR8.css +0 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-D-U4GtLQ.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,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
|
-
}
|