@openclaw/acpx 2026.9.7 → 2026.10.1-beta.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.
- package/README.md +6 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{config-CdPsIued.mjs → config-76krYh6C.mjs} +145 -17
- package/dist/.setup/{pi-session-catalog-runtime-UhiQSaDw.mjs → pi-session-catalog-runtime-7jc50ZJ4.mjs} +21 -56
- package/dist/.setup/{register.runtime-Bm4HrMCp.mjs → register.runtime-C0nVOTzT.mjs} +15 -38
- package/dist/.setup/runtime-doctor-migrations-hxP-CXX7.mjs +191 -0
- package/dist/.setup/{service-DMae5pPH.mjs → service-BXgGdE56.mjs} +111 -183
- package/dist/.setup/session-owner-migration-C73lfijV.mjs +431 -0
- package/dist/.setup/{session-resource-BaJ6bs5d.mjs → session-resource-DKJsUJPu.mjs} +1 -13
- package/dist/doctor-contract-api.js +10 -104
- package/dist/index.js +43 -22
- package/dist/register.runtime.js +1 -1
- package/openclaw.plugin.json +0 -1
- package/package.json +7 -16
- package/skills/acp-router/SKILL.md +2 -2
- package/dist/.setup/command-line-CPBLOiZM.mjs +0 -138
- package/dist/.setup/process-lease-C3dNPtu8.mjs +0 -138
- package/dist/.setup/session-owner-migration-CdJSYRk1.mjs +0 -203
- package/dist/mcp-command-line.mjs +0 -128
- package/dist/mcp-proxy.mjs +0 -159
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command-line parser for ACPX MCP proxy targets. It handles simple quoting and
|
|
3
|
-
* Windows executable paths before spawning the configured MCP target.
|
|
4
|
-
*/
|
|
5
|
-
const WINDOWS_DIRECT_EXECUTABLE_PATH_RE =
|
|
6
|
-
/^(?<command>(?:[A-Za-z]:[\\/]|\\\\[^\\/]+[\\/][^\\/]+[\\/]).*?\.(?:exe|com))(?=\s|$)(?:\s+(?<rest>.*))?$/i;
|
|
7
|
-
|
|
8
|
-
// Windows wrapper scripts need their host shell or interpreter (`cmd.exe`,
|
|
9
|
-
// `powershell.exe`, or `node`) instead of direct spawning.
|
|
10
|
-
const WINDOWS_WRAPPER_PATH_RE =
|
|
11
|
-
/^(?:[A-Za-z]:[\\/]|\\\\[^\\/]+[\\/][^\\/]+[\\/]).*?\.(?:bat|cmd|cjs|js|mjs|ps1)$/i;
|
|
12
|
-
|
|
13
|
-
function splitCommandParts(value, platform = process.platform) {
|
|
14
|
-
const parts = [];
|
|
15
|
-
let current = "";
|
|
16
|
-
let quote = null;
|
|
17
|
-
let escaping = false;
|
|
18
|
-
|
|
19
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
20
|
-
const ch = value[index];
|
|
21
|
-
const next = value[index + 1];
|
|
22
|
-
if (escaping) {
|
|
23
|
-
current += ch;
|
|
24
|
-
escaping = false;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (ch === "\\") {
|
|
28
|
-
if (quote === "'") {
|
|
29
|
-
current += ch;
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
if (platform === "win32") {
|
|
33
|
-
if (quote === '"') {
|
|
34
|
-
if (next === '"' || next === "\\") {
|
|
35
|
-
escaping = true;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
current += ch;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (!quote) {
|
|
42
|
-
current += ch;
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
escaping = true;
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (quote) {
|
|
50
|
-
if (ch === quote) {
|
|
51
|
-
quote = null;
|
|
52
|
-
} else {
|
|
53
|
-
current += ch;
|
|
54
|
-
}
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (ch === "'" || ch === '"') {
|
|
58
|
-
quote = ch;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (/\s/.test(ch)) {
|
|
62
|
-
if (current.length > 0) {
|
|
63
|
-
parts.push(current);
|
|
64
|
-
current = "";
|
|
65
|
-
}
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
current += ch;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (escaping) {
|
|
72
|
-
current += "\\";
|
|
73
|
-
}
|
|
74
|
-
if (quote) {
|
|
75
|
-
throw new Error("Invalid agent command: unterminated quote");
|
|
76
|
-
}
|
|
77
|
-
if (current.length > 0) {
|
|
78
|
-
parts.push(current);
|
|
79
|
-
}
|
|
80
|
-
return parts;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function splitWindowsExecutableCommand(value, platform = process.platform) {
|
|
84
|
-
if (platform !== "win32") {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
const trimmed = value.trim();
|
|
88
|
-
if (!trimmed || trimmed.startsWith('"') || trimmed.startsWith("'")) {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const match = trimmed.match(WINDOWS_DIRECT_EXECUTABLE_PATH_RE);
|
|
92
|
-
if (!match?.groups?.command) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
const rest = match.groups.rest?.trim() ?? "";
|
|
96
|
-
return {
|
|
97
|
-
command: match.groups.command,
|
|
98
|
-
args: rest ? splitCommandParts(rest, platform) : [],
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function assertSupportedWindowsCommand(command, platform = process.platform) {
|
|
103
|
-
if (platform !== "win32" || !WINDOWS_WRAPPER_PATH_RE.test(command)) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
throw new Error(
|
|
107
|
-
`Unsupported Windows agent command wrapper: ${command}. ` +
|
|
108
|
-
"Invoke wrapper scripts through their shell or interpreter instead " +
|
|
109
|
-
"(for example `cmd.exe /c`, `powershell.exe -File`, or `node <script>`).",
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** Split a configured command string into `{ command, args }` for child_process.spawn. */
|
|
114
|
-
export function splitCommandLine(value, platform = process.platform) {
|
|
115
|
-
const windowsCommand = splitWindowsExecutableCommand(value, platform);
|
|
116
|
-
const parts = windowsCommand ?? splitCommandParts(value, platform);
|
|
117
|
-
if (parts.length === 0) {
|
|
118
|
-
throw new Error("Invalid agent command: empty command");
|
|
119
|
-
}
|
|
120
|
-
const parsed = Array.isArray(parts)
|
|
121
|
-
? {
|
|
122
|
-
command: parts[0],
|
|
123
|
-
args: parts.slice(1),
|
|
124
|
-
}
|
|
125
|
-
: parts;
|
|
126
|
-
assertSupportedWindowsCommand(parsed.command, platform);
|
|
127
|
-
return parsed;
|
|
128
|
-
}
|
package/dist/mcp-proxy.mjs
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stdio MCP proxy used by ACPX wrappers. It injects OpenClaw-provided MCP
|
|
5
|
-
* servers into session creation/load/fork requests before forwarding to target.
|
|
6
|
-
*/
|
|
7
|
-
import { spawn } from "node:child_process";
|
|
8
|
-
import path from "node:path";
|
|
9
|
-
import { createInterface } from "node:readline";
|
|
10
|
-
import { pathToFileURL } from "node:url";
|
|
11
|
-
import { splitCommandLine } from "./mcp-command-line.mjs";
|
|
12
|
-
|
|
13
|
-
function formatErrorMessage(error) {
|
|
14
|
-
if (error instanceof Error) {
|
|
15
|
-
return error.message || error.name || "Error";
|
|
16
|
-
}
|
|
17
|
-
return String(error);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function decodePayload(argv) {
|
|
21
|
-
const payloadIndex = argv.indexOf("--payload");
|
|
22
|
-
if (payloadIndex < 0) {
|
|
23
|
-
throw new Error("Missing --payload");
|
|
24
|
-
}
|
|
25
|
-
const encoded = argv[payloadIndex + 1];
|
|
26
|
-
if (!encoded) {
|
|
27
|
-
throw new Error("Missing MCP proxy payload value");
|
|
28
|
-
}
|
|
29
|
-
const parsed = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
30
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
31
|
-
throw new Error("Invalid MCP proxy payload");
|
|
32
|
-
}
|
|
33
|
-
if (typeof parsed.targetCommand !== "string" || parsed.targetCommand.trim() === "") {
|
|
34
|
-
throw new Error("MCP proxy payload missing targetCommand");
|
|
35
|
-
}
|
|
36
|
-
const mcpServers = Array.isArray(parsed.mcpServers) ? parsed.mcpServers : [];
|
|
37
|
-
return {
|
|
38
|
-
targetCommand: parsed.targetCommand,
|
|
39
|
-
mcpServers,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function shouldInject(method) {
|
|
44
|
-
return method === "session/new" || method === "session/load" || method === "session/fork";
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function rewriteLine(line, mcpServers) {
|
|
48
|
-
if (!line.trim()) {
|
|
49
|
-
return line;
|
|
50
|
-
}
|
|
51
|
-
try {
|
|
52
|
-
const parsed = JSON.parse(line);
|
|
53
|
-
if (
|
|
54
|
-
!parsed ||
|
|
55
|
-
typeof parsed !== "object" ||
|
|
56
|
-
Array.isArray(parsed) ||
|
|
57
|
-
!shouldInject(parsed.method) ||
|
|
58
|
-
!parsed.params ||
|
|
59
|
-
typeof parsed.params !== "object" ||
|
|
60
|
-
Array.isArray(parsed.params)
|
|
61
|
-
) {
|
|
62
|
-
return line;
|
|
63
|
-
}
|
|
64
|
-
const next = {
|
|
65
|
-
...parsed,
|
|
66
|
-
params: {
|
|
67
|
-
...parsed.params,
|
|
68
|
-
mcpServers,
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
return JSON.stringify(next);
|
|
72
|
-
} catch {
|
|
73
|
-
return line;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Build spawn options for the proxied MCP target process. */
|
|
78
|
-
export function createTargetSpawnOptions(platform = process.platform) {
|
|
79
|
-
const options = {
|
|
80
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
81
|
-
env: process.env,
|
|
82
|
-
};
|
|
83
|
-
if (platform === "win32") {
|
|
84
|
-
options.windowsHide = true;
|
|
85
|
-
}
|
|
86
|
-
return options;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function isMainModule() {
|
|
90
|
-
const mainPath = process.argv[1];
|
|
91
|
-
if (!mainPath) {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
return import.meta.url === pathToFileURL(path.resolve(mainPath)).href;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function main() {
|
|
98
|
-
const { targetCommand, mcpServers } = decodePayload(process.argv.slice(2));
|
|
99
|
-
const target = splitCommandLine(targetCommand);
|
|
100
|
-
const child = spawn(target.command, target.args, createTargetSpawnOptions());
|
|
101
|
-
|
|
102
|
-
if (!child.stdin || !child.stdout) {
|
|
103
|
-
throw new Error("Failed to create MCP proxy stdio pipes");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const input = createInterface({ input: process.stdin });
|
|
107
|
-
let exiting = false;
|
|
108
|
-
|
|
109
|
-
const exitWithError = (error) => {
|
|
110
|
-
if (exiting) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
exiting = true;
|
|
114
|
-
input.close();
|
|
115
|
-
child.kill();
|
|
116
|
-
process.stderr.write(`${formatErrorMessage(error)}\n`);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
child.stdin.on("error", exitWithError);
|
|
121
|
-
process.stdout.on("error", exitWithError);
|
|
122
|
-
|
|
123
|
-
input.on("line", (line) => {
|
|
124
|
-
if (exiting) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
child.stdin.write(`${rewriteLine(line, mcpServers)}\n`, (error) => {
|
|
128
|
-
if (error) {
|
|
129
|
-
exitWithError(error);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
input.on("close", () => {
|
|
134
|
-
if (exiting || child.stdin.destroyed || child.stdin.writableEnded) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
child.stdin.end();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
child.stdout.pipe(process.stdout);
|
|
141
|
-
|
|
142
|
-
child.on("error", exitWithError);
|
|
143
|
-
|
|
144
|
-
child.on("close", (code, signal) => {
|
|
145
|
-
if (exiting) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
exiting = true;
|
|
149
|
-
if (signal) {
|
|
150
|
-
process.kill(process.pid, signal);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
process.exit(code ?? 0);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (isMainModule()) {
|
|
158
|
-
main();
|
|
159
|
-
}
|