machine-bridge-mcp 0.12.2 → 0.13.0
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/CHANGELOG.md +19 -0
- package/README.md +6 -4
- package/SECURITY.md +4 -0
- package/browser-extension/manifest.json +2 -2
- package/docs/AGENT_CONTEXT.md +16 -6
- package/docs/ARCHITECTURE.md +6 -4
- package/docs/AUDIT.md +13 -1
- package/docs/CLIENTS.md +1 -1
- package/docs/ENGINEERING.md +1 -0
- package/docs/LOCAL_AUTOMATION.md +1 -1
- package/docs/LOGGING.md +3 -1
- package/docs/OPERATIONS.md +5 -0
- package/docs/TESTING.md +4 -3
- package/package.json +3 -1
- package/src/local/agent-context.mjs +75 -18
- package/src/local/app-automation.mjs +15 -1
- package/src/local/capability-observer.mjs +56 -0
- package/src/local/default-instructions.mjs +21 -91
- package/src/local/network-proxy.mjs +34 -0
- package/src/local/process-sessions.mjs +7 -0
- package/src/local/project-package.mjs +234 -0
- package/src/local/relay-connection.mjs +26 -0
- package/src/local/runtime.mjs +21 -20
- package/src/shared/tool-catalog.json +4 -4
- package/src/worker/index.ts +1 -1
package/src/local/runtime.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import path, { basename, dirname, isAbsolute, join, relative, resolve, sep } fro
|
|
|
7
7
|
import { RelayConnection } from "./relay-connection.mjs";
|
|
8
8
|
import { applyUpdateHunks, parsePatchEnvelope } from "./patch.mjs";
|
|
9
9
|
import { executionEnv, workspaceShellCommand } from "./shell.mjs";
|
|
10
|
-
import { MAX_COMMAND_BYTES, ProcessSessionManager, terminateProcessTree, validateArgv } from "./process-sessions.mjs";
|
|
10
|
+
import { MAX_COMMAND_BYTES, ProcessSessionManager, terminateProcessTree, terminateProcessTreeWithEscalation, validateArgv } from "./process-sessions.mjs";
|
|
11
11
|
export { MAX_COMMAND_BYTES } from "./process-sessions.mjs";
|
|
12
12
|
import { allToolNames, assertCanonicalFullPolicy, isCanonicalFullPolicy, MCP_PROTOCOL_VERSION, MCP_SUPPORTED_PROTOCOL_VERSIONS, normalizePolicy, POLICY_PROFILES, SERVER_NAME, toolNamesForPolicy } from "./tools.mjs";
|
|
13
13
|
import { classifyOperationalError } from "./log.mjs";
|
|
@@ -17,6 +17,7 @@ import { expandHome } from "./state.mjs";
|
|
|
17
17
|
import { AgentContextManager } from "./agent-context.mjs";
|
|
18
18
|
import { AppAutomationManager } from "./app-automation.mjs";
|
|
19
19
|
import { BrowserBridgeManager } from "./browser-bridge.mjs";
|
|
20
|
+
import { CapabilityObserver } from "./capability-observer.mjs";
|
|
20
21
|
import { readBoundedRegularFileSync } from "./secure-file.mjs";
|
|
21
22
|
|
|
22
23
|
export const MAX_WRITE_BYTES = 5 * 1024 * 1024;
|
|
@@ -85,7 +86,7 @@ export function runtimeToolHandlerNames() {
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
export class LocalRuntime {
|
|
88
|
-
constructor({ workerUrl = "", secret = "", expectedRelayVersion = "", workspace, policy, logger = console, onSuperseded = null, onFatal = null, jobRoot = "", resources = {}, resourceStatePath = "", browserStateRoot = "", agentHome = process.env.HOME || process.env.USERPROFILE || "", codexHome = process.env.CODEX_HOME || "", recoverJobs = true }) {
|
|
89
|
+
constructor({ workerUrl = "", secret = "", expectedRelayVersion = "", workspace, policy, logger = console, onSuperseded = null, onFatal = null, jobRoot = "", resources = {}, resourceStatePath = "", browserStateRoot = "", agentHome = process.env.HOME || process.env.USERPROFILE || "", codexHome = process.env.CODEX_HOME || "", recoverJobs = true, applicationAutomation = {} }) {
|
|
89
90
|
const remoteWorkerUrl = workerUrl ? String(workerUrl) : "";
|
|
90
91
|
const remoteSecret = secret || "";
|
|
91
92
|
this.workspaceInput = resolve(workspace || process.cwd());
|
|
@@ -100,6 +101,7 @@ export class LocalRuntime {
|
|
|
100
101
|
this.callProcesses = new Map();
|
|
101
102
|
this.cancelledCalls = new Set();
|
|
102
103
|
this.mutationQueue = Promise.resolve();
|
|
104
|
+
this.capabilityObserver = new CapabilityObserver();
|
|
103
105
|
this.runtimeDir = createRuntimeDir();
|
|
104
106
|
if (typeof jobRoot !== "string" || !jobRoot.trim()) throw new Error("persistent managed-job root is required");
|
|
105
107
|
this.managedJobManager = new ManagedJobManager({
|
|
@@ -139,6 +141,7 @@ export class LocalRuntime {
|
|
|
139
141
|
const readResourceText = (name) => this.readLocalResourceText(name);
|
|
140
142
|
const readResourceBinary = (name) => this.readLocalResourceBinary(name);
|
|
141
143
|
this.appAutomationManager = new AppAutomationManager({
|
|
144
|
+
...applicationAutomation,
|
|
142
145
|
policy: this.policy,
|
|
143
146
|
displayPath: (value) => this.displayPath(value),
|
|
144
147
|
runProcess,
|
|
@@ -198,9 +201,11 @@ export class LocalRuntime {
|
|
|
198
201
|
per_tool_events: "debug-only",
|
|
199
202
|
default_logs_include_tool_failures: false,
|
|
200
203
|
tool_arguments_or_results_logged: false,
|
|
204
|
+
capability_routing: this.capabilityObserver.snapshot(),
|
|
201
205
|
},
|
|
202
206
|
runtime: {
|
|
203
207
|
environment: this.policy.minimalEnv ? "isolated-minimal" : "full-parent",
|
|
208
|
+
relay: this.relay?.status?.() || null,
|
|
204
209
|
runtime_dir: this.policy.exposeAbsolutePaths ? this.runtimeDir : "<private-runtime-dir>",
|
|
205
210
|
process_sessions: this.processSessionManager.status(),
|
|
206
211
|
managed_jobs: this.managedJobManager.status(),
|
|
@@ -323,14 +328,8 @@ export class LocalRuntime {
|
|
|
323
328
|
this.cancelledCalls.add(callId);
|
|
324
329
|
this.processSessionManager.notifyCancellation();
|
|
325
330
|
this.browserBridgeManager?.cancelCall(callId);
|
|
326
|
-
for (const child of this.callProcesses.get(callId) || []) terminateProcessTree(child, "SIGTERM");
|
|
327
331
|
const children = [...(this.callProcesses.get(callId) || [])];
|
|
328
|
-
|
|
329
|
-
const timer = setTimeout(() => {
|
|
330
|
-
for (const child of children) if (this.activeProcesses.has(child)) terminateProcessTree(child, "SIGKILL");
|
|
331
|
-
}, 2000);
|
|
332
|
-
timer.unref?.();
|
|
333
|
-
}
|
|
332
|
+
for (const child of children) terminateProcessTreeWithEscalation(child);
|
|
334
333
|
this.logger.debug?.("tool call cancellation requested", { call_id: shortCallId(callId), reason });
|
|
335
334
|
}
|
|
336
335
|
|
|
@@ -351,6 +350,7 @@ export class LocalRuntime {
|
|
|
351
350
|
gitRoot: git.code === 0 ? this.displayPath(git.stdout.trim()) : "",
|
|
352
351
|
policy: this.policy,
|
|
353
352
|
tools: ["server_info", ...this.tools()],
|
|
353
|
+
capabilityRouting: this.capabilityObserver.snapshot(),
|
|
354
354
|
topLevel: top.entries || [],
|
|
355
355
|
};
|
|
356
356
|
}
|
|
@@ -795,13 +795,14 @@ export class LocalRuntime {
|
|
|
795
795
|
status_tool: "browser_status",
|
|
796
796
|
} : null,
|
|
797
797
|
};
|
|
798
|
+
this.capabilityObserver.recordBootstrap(bootstrap);
|
|
798
799
|
return bootstrap;
|
|
799
800
|
}
|
|
800
801
|
|
|
801
802
|
async resolveTaskCapabilities(args = {}, context = {}) {
|
|
802
803
|
const result = await this.agentContextManager.resolveTaskCapabilities(args, context);
|
|
803
804
|
const task = String(args.task || "");
|
|
804
|
-
if (
|
|
805
|
+
if (this.policy.profile === "full") {
|
|
805
806
|
const applications = await this.appAutomationManager.listApplications({ query: "", max_results: 500 }, context).catch(() => ({ applications: [] }));
|
|
806
807
|
const lower = task.toLowerCase();
|
|
807
808
|
result.application_matches = applications.applications
|
|
@@ -813,7 +814,12 @@ export class LocalRuntime {
|
|
|
813
814
|
} else {
|
|
814
815
|
result.application_matches = [];
|
|
815
816
|
}
|
|
817
|
+
if (result.application_matches.length) {
|
|
818
|
+
result.recommended_tools = [...new Set([...result.recommended_tools, "list_local_applications", "open_local_application", "inspect_local_application", "operate_local_application"])];
|
|
819
|
+
}
|
|
816
820
|
result.browser_backend = this.policy.profile === "full" ? { tool: "browser_status", existing_profile: true, extension_bridge: true } : null;
|
|
821
|
+
result.routing_observability = "Call server_info or project_overview to verify that bootstrap and task capability resolution reached the local runtime.";
|
|
822
|
+
this.capabilityObserver.recordResolution(task, result);
|
|
817
823
|
return result;
|
|
818
824
|
}
|
|
819
825
|
|
|
@@ -873,12 +879,9 @@ export class LocalRuntime {
|
|
|
873
879
|
|
|
874
880
|
terminateActiveProcesses(signal = "SIGTERM", escalate = false) {
|
|
875
881
|
const children = [...this.activeProcesses];
|
|
876
|
-
for (const child of children)
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
for (const child of children) if (this.activeProcesses.has(child)) terminateProcessTree(child, "SIGKILL");
|
|
880
|
-
}, 2000);
|
|
881
|
-
timer.unref?.();
|
|
882
|
+
for (const child of children) {
|
|
883
|
+
if (escalate && signal !== "SIGKILL") terminateProcessTreeWithEscalation(child);
|
|
884
|
+
else terminateProcessTree(child, signal);
|
|
882
885
|
}
|
|
883
886
|
}
|
|
884
887
|
|
|
@@ -911,14 +914,12 @@ export class LocalRuntime {
|
|
|
911
914
|
let killTimer = null;
|
|
912
915
|
const timer = setTimeout(() => {
|
|
913
916
|
timedOut = true;
|
|
914
|
-
|
|
915
|
-
killTimer = setTimeout(() => terminateProcessTree(child, "SIGKILL"), 2000);
|
|
916
|
-
killTimer.unref?.();
|
|
917
|
+
killTimer = terminateProcessTreeWithEscalation(child);
|
|
917
918
|
}, timeoutMs);
|
|
918
919
|
timer.unref?.();
|
|
919
920
|
const cleanup = () => {
|
|
920
921
|
clearTimeout(timer);
|
|
921
|
-
if (killTimer) clearTimeout(killTimer);
|
|
922
|
+
if (killTimer && !timedOut) clearTimeout(killTimer);
|
|
922
923
|
this.activeProcesses.delete(child);
|
|
923
924
|
if (context.callId) {
|
|
924
925
|
const set = this.callProcesses.get(context.callId);
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
{
|
|
58
58
|
"name": "resolve_task_capabilities",
|
|
59
59
|
"title": "Resolve task capabilities",
|
|
60
|
-
"description": "Rescan built-in and automatic project context, local instruction files, skills,
|
|
60
|
+
"description": "Rescan built-in and automatic project context, local instruction files, skills, explicit and automatic package commands, installed applications, and browser capability metadata; rank the capabilities relevant to the current task and optionally load the best skill.",
|
|
61
61
|
"availability": "always",
|
|
62
62
|
"annotations": {
|
|
63
63
|
"readOnlyHint": true,
|
|
@@ -897,7 +897,7 @@
|
|
|
897
897
|
{
|
|
898
898
|
"name": "agent_context",
|
|
899
899
|
"title": "Load agent context",
|
|
900
|
-
"description": "Discover built-in defaults, bounded automatic project facts, Codex-compatible global/root-to-target instruction precedence, progressively disclosed local skills, and
|
|
900
|
+
"description": "Discover built-in defaults, bounded automatic project facts, Codex-compatible global/root-to-target instruction precedence, progressively disclosed local skills, explicit commands, and safe automatic package-script command aliases for a target path.",
|
|
901
901
|
"availability": "always",
|
|
902
902
|
"annotations": {
|
|
903
903
|
"readOnlyHint": true,
|
|
@@ -1001,7 +1001,7 @@
|
|
|
1001
1001
|
{
|
|
1002
1002
|
"name": "list_local_commands",
|
|
1003
1003
|
"title": "List registered local commands",
|
|
1004
|
-
"description": "List commands
|
|
1004
|
+
"description": "List effective direct-argv commands from project manifests and safe automatic package-script aliases, including provenance and timeout limits.",
|
|
1005
1005
|
"availability": "always",
|
|
1006
1006
|
"annotations": {
|
|
1007
1007
|
"readOnlyHint": true,
|
|
@@ -1024,7 +1024,7 @@
|
|
|
1024
1024
|
{
|
|
1025
1025
|
"name": "run_local_command",
|
|
1026
1026
|
"title": "Run registered local command",
|
|
1027
|
-
"description": "
|
|
1027
|
+
"description": "Run an effective manifest or automatic package-script command through its fixed argv, cwd, timeout ceiling, and extra-argument policy.",
|
|
1028
1028
|
"availability": "direct-exec",
|
|
1029
1029
|
"annotations": {
|
|
1030
1030
|
"readOnlyHint": false,
|
package/src/worker/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import toolCatalog from "../shared/tool-catalog.json";
|
|
|
3
3
|
import serverMetadata from "../shared/server-metadata.json";
|
|
4
4
|
|
|
5
5
|
const SERVER_NAME = String(serverMetadata.name);
|
|
6
|
-
const SERVER_VERSION = "0.
|
|
6
|
+
const SERVER_VERSION = "0.13.0";
|
|
7
7
|
const MCP_PROTOCOL_VERSION = String(serverMetadata.protocolVersion);
|
|
8
8
|
const MCP_SUPPORTED_PROTOCOL_VERSIONS = serverMetadata.supportedProtocolVersions.map((value) => String(value));
|
|
9
9
|
const JSONRPC_VERSION = "2.0";
|