machine-bridge-mcp 0.15.0 → 0.16.1

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 (44) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +12 -2
  3. package/SECURITY.md +7 -0
  4. package/browser-extension/manifest.json +2 -2
  5. package/docs/ARCHITECTURE.md +5 -3
  6. package/docs/AUDIT.md +12 -1
  7. package/docs/LOGGING.md +7 -1
  8. package/docs/OPERATIONS.md +9 -2
  9. package/docs/POLICY_REFERENCE.md +88 -0
  10. package/docs/TESTING.md +7 -0
  11. package/package.json +14 -3
  12. package/scripts/coverage-check.mjs +108 -0
  13. package/scripts/generate-policy-reference.mjs +95 -0
  14. package/src/local/agent-context.mjs +1 -103
  15. package/src/local/app-automation.mjs +7 -11
  16. package/src/local/browser-bridge.mjs +26 -156
  17. package/src/local/browser-extension-protocol.mjs +75 -0
  18. package/src/local/browser-pairing-store.mjs +83 -0
  19. package/src/local/call-registry.mjs +113 -0
  20. package/src/local/capability-ranking.mjs +103 -0
  21. package/src/local/cli-local-admin.mjs +308 -0
  22. package/src/local/cli-options.mjs +151 -0
  23. package/src/local/cli-policy.mjs +89 -0
  24. package/src/local/cli.mjs +16 -521
  25. package/src/local/errors.mjs +122 -0
  26. package/src/local/git-service.mjs +88 -0
  27. package/src/local/lifecycle.mjs +64 -0
  28. package/src/local/log.mjs +50 -19
  29. package/src/local/managed-job-plan.mjs +235 -0
  30. package/src/local/managed-jobs.mjs +16 -220
  31. package/src/local/observability.mjs +83 -0
  32. package/src/local/policy.mjs +148 -0
  33. package/src/local/process-execution.mjs +153 -0
  34. package/src/local/process-sessions.mjs +10 -20
  35. package/src/local/process-tracker.mjs +55 -0
  36. package/src/local/runtime.mjs +154 -672
  37. package/src/local/service.mjs +1 -0
  38. package/src/local/stdio.mjs +3 -11
  39. package/src/local/tool-executor.mjs +102 -0
  40. package/src/local/tools.mjs +21 -104
  41. package/src/local/workspace-file-service.mjs +451 -0
  42. package/src/shared/policy-contract.json +54 -0
  43. package/src/shared/tool-catalog.json +4 -4
  44. package/src/worker/index.ts +69 -524
@@ -0,0 +1,89 @@
1
+ import {
2
+ DEFAULT_POLICY_PROFILE,
3
+ DEFAULT_POLICY_REVISION,
4
+ POLICY_PROFILES,
5
+ normalizePolicy,
6
+ policyProfile,
7
+ } from "./policy.mjs";
8
+
9
+ const POLICY_OVERRIDE_KEYS = Object.freeze(["execMode", "noWrite", "noExec", "fullEnv", "unrestrictedPaths", "absolutePaths"]);
10
+
11
+ export function resolvePolicy(args = {}, stored = {}) {
12
+ const hasStored = stored && typeof stored === "object" && (
13
+ typeof stored.allowWrite === "boolean" || typeof stored.allowExec === "boolean" || typeof stored.execMode === "string"
14
+ );
15
+ const explicitKeys = ["profile", ...POLICY_OVERRIDE_KEYS];
16
+ const hasExplicit = explicitKeys.some((key) => Object.prototype.hasOwnProperty.call(args, key));
17
+ const base = { ...selectPolicyBase(args, stored, hasStored) };
18
+ if (!hasExplicit) return policyState(base);
19
+ applyPolicyOverrides(base, args);
20
+ if (args.profile === undefined || POLICY_OVERRIDE_KEYS.some((key) => Object.prototype.hasOwnProperty.call(args, key))) {
21
+ base.profile = "custom";
22
+ base.origin = "custom";
23
+ base.revision = DEFAULT_POLICY_REVISION;
24
+ }
25
+ return policyState(base);
26
+ }
27
+
28
+ function policyState(policy) {
29
+ // Capability fields retain the canonical immutable contract. The CLI owns a
30
+ // sealed persistence record with exactly one writable metadata field.
31
+ const normalized = normalizePolicy(policy);
32
+ const state = {};
33
+ for (const [key, value] of Object.entries(normalized)) {
34
+ Object.defineProperty(state, key, { value, enumerable: true, writable: false, configurable: false });
35
+ }
36
+ Object.defineProperty(state, "updatedAt", { value: undefined, enumerable: true, writable: true, configurable: false });
37
+ return Object.seal(state);
38
+ }
39
+
40
+ function selectPolicyBase(args, stored, hasStored) {
41
+ if (args.profile !== undefined) {
42
+ const profile = String(args.profile).trim().toLowerCase();
43
+ if (!POLICY_PROFILES[profile]) throw new Error(`--profile must be one of: ${Object.keys(POLICY_PROFILES).join(", ")}`);
44
+ return policyProfile(profile, "explicit");
45
+ }
46
+ if (hasStored) return migrateLegacyPolicy(stored);
47
+ return policyProfile(DEFAULT_POLICY_PROFILE, "default");
48
+ }
49
+
50
+ function applyPolicyOverrides(policy, args) {
51
+ if (args.execMode !== undefined) {
52
+ const execMode = String(args.execMode).trim().toLowerCase();
53
+ if (!["off", "direct", "shell"].includes(execMode)) throw new Error("--exec-mode must be off, direct, or shell");
54
+ policy.execMode = execMode;
55
+ }
56
+ applyBooleanOverride(args, "noWrite", (enabled) => { policy.allowWrite = !enabled; });
57
+ applyBooleanOverride(args, "noExec", (enabled) => {
58
+ if (enabled) policy.execMode = "off";
59
+ else if (policy.execMode === "off") policy.execMode = "direct";
60
+ });
61
+ applyBooleanOverride(args, "fullEnv", (enabled) => { policy.minimalEnv = !enabled; });
62
+ applyBooleanOverride(args, "unrestrictedPaths", (enabled) => { policy.unrestrictedPaths = enabled; });
63
+ applyBooleanOverride(args, "absolutePaths", (enabled) => { policy.exposeAbsolutePaths = enabled; });
64
+ }
65
+
66
+ function applyBooleanOverride(args, key, apply) {
67
+ if (typeof args[key] === "boolean") apply(args[key]);
68
+ }
69
+
70
+ function migrateLegacyPolicy(stored = {}) {
71
+ if (stored.origin === "default" && Number(stored.revision || 0) < DEFAULT_POLICY_REVISION) {
72
+ return policyProfile(DEFAULT_POLICY_PROFILE, "default");
73
+ }
74
+ if (stored.origin === "migrated" && Number(stored.revision || 0) < DEFAULT_POLICY_REVISION) {
75
+ return policyProfile(DEFAULT_POLICY_PROFILE, "migrated");
76
+ }
77
+ if (stored.origin) return normalizePolicy(stored);
78
+ const normalized = normalizePolicy(stored);
79
+ const looksLikeLegacyImplicitDefault = (
80
+ normalized.profile === "custom"
81
+ && normalized.allowWrite === true
82
+ && normalized.execMode === "shell"
83
+ && normalized.unrestrictedPaths === false
84
+ && normalized.minimalEnv === true
85
+ && normalized.exposeAbsolutePaths === false
86
+ );
87
+ if (looksLikeLegacyImplicitDefault) return policyProfile("full", "migrated");
88
+ return normalizePolicy({ ...normalized, origin: "legacy-preserved", revision: DEFAULT_POLICY_REVISION });
89
+ }