openmausbot 0.1.82 → 0.1.84

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 (54) hide show
  1. package/dist/assets/index-BbU5REzd.js +310 -0
  2. package/dist/assets/{index-CKysBq-V.css → index-CLGfYlx_.css} +1 -1
  3. package/dist/assets/{index-5HVwp5m2.js → index-DNa2umw-.js} +1 -1
  4. package/dist/index.html +2 -2
  5. package/dist-server/container-mcp.js +20 -4
  6. package/dist-server/drivers/agents-proxy.js +30 -4
  7. package/dist-server/index.js +1716 -581
  8. package/dist-server/mcp-gate.js +2 -1
  9. package/dist-server/openmausbot.js +224 -63
  10. package/dist-server/pair-cli.js +224 -63
  11. package/dist-server/server/auto-approve.js +15 -1
  12. package/dist-server/server/auto-vm-claims.js +22 -0
  13. package/dist-server/server/browser-bundle-release.js +8 -7
  14. package/dist-server/server/browser-engine.js +1 -1
  15. package/dist-server/server/channel-queue.js +58 -0
  16. package/dist-server/server/checkpoints.js +9 -5
  17. package/dist-server/server/chief-of-staff.js +5 -2
  18. package/dist-server/server/computer-wait.js +33 -0
  19. package/dist-server/server/config.js +58 -3
  20. package/dist-server/server/contracts.js +0 -7
  21. package/dist-server/server/delta-context.js +258 -0
  22. package/dist-server/server/drivers/acp/gemini.js +11 -1
  23. package/dist-server/server/drivers/acp/qwen.js +16 -1
  24. package/dist-server/server/drivers/agents-proxy.js +32 -4
  25. package/dist-server/server/drivers/claude.js +26 -8
  26. package/dist-server/server/drivers/codex.js +79 -6
  27. package/dist-server/server/drivers/pi.js +2 -1
  28. package/dist-server/server/env-path.js +6 -1
  29. package/dist-server/server/incidents.js +104 -0
  30. package/dist-server/server/index.js +886 -134
  31. package/dist-server/server/local-routing.js +10 -4
  32. package/dist-server/server/notify.js +3 -1
  33. package/dist-server/server/peer-roster.js +37 -1
  34. package/dist-server/server/recent-work.js +4 -1
  35. package/dist-server/server/redact.js +5 -48
  36. package/dist-server/server/room-handoffs.js +79 -16
  37. package/dist-server/server/skill-fetch.js +1 -1
  38. package/dist-server/server/steer-queue.js +29 -0
  39. package/dist-server/server/store.js +43 -3
  40. package/dist-server/server/thread-retention.js +50 -0
  41. package/dist-server/server/turn-context.js +7 -0
  42. package/dist-server/server/turn-resources.js +6 -0
  43. package/dist-server/shared/approval-mode.js +8 -5
  44. package/dist-server/shared/inspector.js +1 -0
  45. package/dist-server/shared/json.js +1 -0
  46. package/dist-server/shared/notification.js +1 -0
  47. package/dist-server/shared/redact.js +61 -0
  48. package/dist-server/shared/routines.js +1 -0
  49. package/dist-server/shared/runtime-events.js +1 -0
  50. package/dist-server/shared/webhooks.js +1 -0
  51. package/dist-server/shared/wire.js +8 -0
  52. package/dist-server/vps-container-mcp.js +20 -4
  53. package/package.json +1 -1
  54. package/dist/assets/index-BLLsDK2F.js +0 -309
@@ -0,0 +1,61 @@
1
+ // Keeping secrets out of text that crosses a trust boundary — the native
2
+ // protocol log, tool titles, activity chips. The log keeps the SHAPE and
3
+ // loses the VALUES: a redacted entry still tells you a token was passed,
4
+ // under which name, and how long it was — enough to debug "the proxy got
5
+ // no token" without the token being there.
6
+ //
7
+ // Single home in shared/ so the client (task timeline) and the server
8
+ // (redact.ts deep scrub, native tee) redact identically; server/redact.ts
9
+ // re-exports redactSecretsInText under its historical path.
10
+ /** Keep repeated redaction byte-for-byte stable. Persisted payloads can pass
11
+ * through both a content scrub and the store-wide scrub; re-masking our own
12
+ * marker would change its reported length (and any hash over the payload). */
13
+ const REDACTION_MARKER = /^«redacted \d+ chars»$/;
14
+ export const mask = (value) => (REDACTION_MARKER.test(value) ? value : `«redacted ${value.length} chars»`);
15
+ // ── content-shaped secrets ────────────────────────────────────────────
16
+ // High precision on purpose: a generic "long hex/base64" heuristic would
17
+ // rewrite real code in the transcript, so only shapes that are unmistakably
18
+ // credentials match.
19
+ const KEY_PREFIXES = [
20
+ /\bom[dg]_[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])/g, // desktop device and model-only credentials
21
+ /\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{16,}/g, // anthropic / openai / stripe
22
+ /\bxai-[A-Za-z0-9_-]{20,}/g, // xai (grok)
23
+ /\bgsk_[A-Za-z0-9]{40,}/g, // groq
24
+ /\bhf_[A-Za-z0-9]{30,}/g, // hugging face
25
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/g, // github classic
26
+ /\bgithub_pat_[A-Za-z0-9_]{20,}/g, // github fine-grained
27
+ /\bxox[abposr]-[A-Za-z0-9-]{20,}/g, // slack
28
+ /\bAKIA[0-9A-Z]{16}\b/g, // aws access key id
29
+ /\bAIza[0-9A-Za-z_-]{30,}/g, // google api key
30
+ /\bnpm_[A-Za-z0-9]{20,}/g, // npm
31
+ /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, // jwt
32
+ ];
33
+ const BEARER = /(\bBearer\s+)([A-Za-z0-9._~+/=-]{12,})/g;
34
+ const PEM_BLOCK = /(-----BEGIN [A-Z ]*PRIVATE KEY-----)([\s\S]*?)(-----END [A-Z ]*PRIVATE KEY-----)/g;
35
+ /** key=value / key: value / key="value" where the key is secret-shaped.
36
+ * The value must be a single token of some length; prose after a colon
37
+ * ("password: leave blank…") has spaces and does not match. */
38
+ const KEY_VALUE = /\b((?:[A-Za-z0-9_-]*_)?(?:api[_-]?key|apikey|secret|token|password|passwd|authorization|auth[_-]?token|access[_-]?key|private[_-]?key)s?)(["']?\s*[=:]\s*)(["']?)([A-Za-z0-9._~+/=-]{8,})\3/gi;
39
+ /** `X_KEY=value`, `xai-key=value`: an assignment to a name that ENDS in key
40
+ * is a credential whatever the value looks like, so no length floor. The
41
+ * separator before `key` is what keeps `hotkey=` and `keyboard=` out. */
42
+ const KEY_SUFFIX_ASSIGNMENT = /\b([A-Za-z][A-Za-z0-9_-]*[_-]key)s?(=)(["']?)([A-Za-z0-9._~+/=-]+)\3/gi;
43
+ /** `--token abc`, `--password=abc`: the flag names a secret; the value is
44
+ * whatever single token follows, never another flag. */
45
+ const SECRET_FLAG = /(--(?:token|password|passwd|api-key|apikey|secret|access-key|auth-token)(?:=|\s+))(["']?)(?!-)([A-Za-z0-9._~+/=-]+)\2/gi;
46
+ /** `scheme://user:secret@host` — the password in a URL's userinfo. */
47
+ const URL_USERINFO = /(\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@'"]+:)([^\s/@'"«»]+)(@)/gi;
48
+ export function redactSecretsInText(text) {
49
+ if (!text || text.length < 8)
50
+ return text;
51
+ let out = text;
52
+ out = out.replace(PEM_BLOCK, (_m, open, body, close) => `${open}\n${mask(body.trim())}\n${close}`);
53
+ for (const re of KEY_PREFIXES)
54
+ out = out.replace(re, (m) => mask(m));
55
+ out = out.replace(BEARER, (_m, lead, tok) => `${lead}${mask(tok)}`);
56
+ out = out.replace(KEY_VALUE, (_m, key, sep, quote, value) => `${key}${sep}${quote}${mask(value)}${quote}`);
57
+ out = out.replace(KEY_SUFFIX_ASSIGNMENT, (_m, key, sep, quote, value) => `${key}${sep}${quote}${mask(value)}${quote}`);
58
+ out = out.replace(SECRET_FLAG, (_m, flag, quote, value) => `${flag}${quote}${mask(value)}${quote}`);
59
+ out = out.replace(URL_USERINFO, (_m, lead, secret, at) => `${lead}${mask(secret)}${at}`);
60
+ return out;
61
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ /** Reasoning-effort levels, ascending. A union of everything any engine
2
+ * accepts; each driver declares the subset its CLI will take. Lives here
3
+ * because it is part of ModelSelection, which rides the wire. */
4
+ export const EFFORT_LEVELS = ["none", "low", "medium", "high", "xhigh", "max"];
5
+ /** Narrow untrusted API/config input before it becomes a model selection. */
6
+ export function isEffortLevel(value) {
7
+ return typeof value === "string" && EFFORT_LEVELS.includes(value);
8
+ }
@@ -14954,8 +14954,10 @@ function normalizeImageGenerationUrl(value) {
14954
14954
  return url2.toString().replace(/\/+$/, "");
14955
14955
  }
14956
14956
 
14957
- // server/contracts.ts
14957
+ // shared/wire.ts
14958
14958
  var EFFORT_LEVELS = ["none", "low", "medium", "high", "xhigh", "max"];
14959
+
14960
+ // server/contracts.ts
14959
14961
  function isModelVariant(value) {
14960
14962
  return typeof value === "string" && value.length > 0 && value.length <= 256 && value.trim() === value && !new RegExp("\\p{Cc}", "u").test(value);
14961
14963
  }
@@ -14989,6 +14991,9 @@ var LEGACY_BROWSER_PROFILE_ID = /^[A-Za-z0-9_-]{1,40}$/;
14989
14991
  var BROWSER_PROFILE_ID = /^[a-z0-9_-]{1,40}$/;
14990
14992
  var MIN_ROOM_TURN_TIMEOUT_MINUTES = 1;
14991
14993
  var MAX_ROOM_TURN_TIMEOUT_MINUTES = 1440;
14994
+ var DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES = 30;
14995
+ var DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES = 10;
14996
+ var DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES = 240;
14992
14997
  var MAX_CONCURRENT_BOT_THREADS = 10;
14993
14998
  var MIN_THREAD_EVENT_LOG_BYTES = 256 * 1024;
14994
14999
  var MAX_THREAD_EVENT_LOG_BYTES = 4 * 1024 * 1024 * 1024;
@@ -15003,8 +15008,16 @@ var vpsConfigSchema = external_exports.object({
15003
15008
  }).optional()
15004
15009
  });
15005
15010
  var roomConfigSchema = external_exports.object({
15006
- turnTimeoutMinutes: external_exports.number().int().min(MIN_ROOM_TURN_TIMEOUT_MINUTES).max(MAX_ROOM_TURN_TIMEOUT_MINUTES)
15007
- });
15011
+ turnTimeoutMinutes: external_exports.number().int().min(MIN_ROOM_TURN_TIMEOUT_MINUTES).max(MAX_ROOM_TURN_TIMEOUT_MINUTES),
15012
+ /** Room handoff tree lifetime. Active execution pauses this clock; the
15013
+ * hard cap is wall-clock and bounds trees that never stop executing. */
15014
+ handoffLifetimeMinutes: external_exports.number().int().min(1).max(MAX_ROOM_TURN_TIMEOUT_MINUTES).optional(),
15015
+ handoffMinRunwayMinutes: external_exports.number().int().min(1).max(MAX_ROOM_TURN_TIMEOUT_MINUTES).optional(),
15016
+ handoffHardCapMinutes: external_exports.number().int().min(1).max(7 * MAX_ROOM_TURN_TIMEOUT_MINUTES).optional()
15017
+ }).refine(
15018
+ (rooms) => (rooms.handoffMinRunwayMinutes ?? DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES) <= (rooms.handoffLifetimeMinutes ?? DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES) && (rooms.handoffLifetimeMinutes ?? DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES) <= (rooms.handoffHardCapMinutes ?? DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES),
15019
+ { message: "rooms handoff bounds must satisfy handoffMinRunwayMinutes <= handoffLifetimeMinutes <= handoffHardCapMinutes" }
15020
+ );
15008
15021
  var localVmConfigSchema = external_exports.object({
15009
15022
  mode: external_exports.enum(["shared", "per-bot"]).optional(),
15010
15023
  maxInstances: external_exports.number().int().min(MIN_LOCAL_VM_MAX_INSTANCES).max(MAX_LOCAL_VM_MAX_INSTANCES).optional()
@@ -15253,7 +15266,10 @@ var appConfigSchema = external_exports.object({
15253
15266
  maxConcurrentPerBot: external_exports.number().int().min(1).max(MAX_CONCURRENT_BOT_THREADS),
15254
15267
  /** Cap each per-thread events/ and native/ NDJSON log at this many
15255
15268
  * bytes; absent (the default) keeps today's unbounded growth (#1280). */
15256
- eventLogMaxBytes: external_exports.number().int().min(MIN_THREAD_EVENT_LOG_BYTES).max(MAX_THREAD_EVENT_LOG_BYTES).optional()
15269
+ eventLogMaxBytes: external_exports.number().int().min(MIN_THREAD_EVENT_LOG_BYTES).max(MAX_THREAD_EVENT_LOG_BYTES).optional(),
15270
+ /** Days a closed or archived thread's event logs survive (#1280).
15271
+ * Absent keeps them forever. */
15272
+ eventLogRetentionDays: external_exports.number().int().min(1).max(3650).optional()
15257
15273
  }).strict().optional(),
15258
15274
  localVm: localVmConfigSchema.optional(),
15259
15275
  features: featureConfigSchema.optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmausbot",
3
- "version": "0.1.82",
3
+ "version": "0.1.84",
4
4
  "description": "Run the OpenMausBot server anywhere and pair your devices to it",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",