@drakon-systems/multi-clawd 1.8.4 → 1.8.5
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 +1 -1
- package/dist/index.js +4 -1
- package/dist/tool-cap.js +120 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -367,7 +367,7 @@ openclaw plugins install (Get-Location).Path
|
|
|
367
367
|
**Or let your agent install it.** Running an OpenClaw assistant or Claude
|
|
368
368
|
Code on the target machine already? Paste it this and go make coffee:
|
|
369
369
|
|
|
370
|
-
> Read https://raw.githubusercontent.com/Drakon-Systems-Ltd/multi-clawd/v1.8.
|
|
370
|
+
> Read https://raw.githubusercontent.com/Drakon-Systems-Ltd/multi-clawd/v1.8.5/SETUP-AGENT.md
|
|
371
371
|
> and follow it to set up multi-clawd on this machine. I own a second
|
|
372
372
|
> Claude account — ask me when you need me to log in.
|
|
373
373
|
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { decideStickySelection } from "./sticky.js";
|
|
|
12
12
|
import { mergeHealthStates, parseStoredState, recordCredentialFailure, } from "./shim-core.js";
|
|
13
13
|
import { createTokenRefResolver, isSecretRefShape, } from "./token-resolution.js";
|
|
14
14
|
import { resolveSecretRefValues } from "openclaw/plugin-sdk/secret-ref-runtime";
|
|
15
|
+
import { resolvePoolExecutionArgs } from "./tool-cap.js";
|
|
15
16
|
import { addAlert, alertKeysWithPrefix, clearAlert, pendingAlertText, } from "./alerts.js";
|
|
16
17
|
import { healthStateFile, clearAccountCredentialFailure } from "./credential-state.js";
|
|
17
18
|
export { healthStateFile, clearAccountCredentialFailure };
|
|
@@ -389,7 +390,9 @@ export function buildBackend(account, execMode) {
|
|
|
389
390
|
},
|
|
390
391
|
bundleMcp: true,
|
|
391
392
|
bundleMcpMode: "claude-config-file",
|
|
392
|
-
nativeToolMode: "
|
|
393
|
+
nativeToolMode: "selectable",
|
|
394
|
+
toolAvailabilityEnforcement: "execution-args",
|
|
395
|
+
resolveExecutionArgs: resolvePoolExecutionArgs,
|
|
393
396
|
sideQuestionToolMode: "disabled",
|
|
394
397
|
ownsNativeCompaction: true,
|
|
395
398
|
config: {
|
package/dist/tool-cap.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export const OPENCLAW_MCP_TOOL_PREFIX = "mcp__openclaw__";
|
|
2
|
+
const TOOLS_ARG = "--tools";
|
|
3
|
+
const ALLOWED_TOOLS_ARG = "--allowedTools";
|
|
4
|
+
const DISALLOWED_TOOLS_ARG = "--disallowedTools";
|
|
5
|
+
const SETTING_SOURCES_ARG = "--setting-sources";
|
|
6
|
+
const SETTINGS_ARG = "--settings";
|
|
7
|
+
const DISABLE_SLASH_COMMANDS_ARG = "--disable-slash-commands";
|
|
8
|
+
const NO_CHROME_ARG = "--no-chrome";
|
|
9
|
+
const STRICT_MCP_CONFIG_ARG = "--strict-mcp-config";
|
|
10
|
+
const DENY_MCP_TOOLS_VALUE = "mcp__*";
|
|
11
|
+
export const RESTRICTED_SETTINGS = JSON.stringify({
|
|
12
|
+
disableAllHooks: true,
|
|
13
|
+
enabledPlugins: {},
|
|
14
|
+
autoMemoryEnabled: false,
|
|
15
|
+
claudeMdExcludes: ["**/CLAUDE.md", "**/CLAUDE.local.md", "**/.claude/rules/**"],
|
|
16
|
+
});
|
|
17
|
+
const RESTRICTED_VARIADIC_VALUE_ARGS = new Set([
|
|
18
|
+
TOOLS_ARG,
|
|
19
|
+
ALLOWED_TOOLS_ARG,
|
|
20
|
+
"--allowed-tools",
|
|
21
|
+
DISALLOWED_TOOLS_ARG,
|
|
22
|
+
"--disallowed-tools",
|
|
23
|
+
"--add-dir",
|
|
24
|
+
"--file",
|
|
25
|
+
]);
|
|
26
|
+
const RESTRICTED_VALUE_ARGS = new Set([
|
|
27
|
+
"--permission-mode",
|
|
28
|
+
SETTING_SOURCES_ARG,
|
|
29
|
+
SETTINGS_ARG,
|
|
30
|
+
"--agent",
|
|
31
|
+
"--agents",
|
|
32
|
+
"--managed-settings",
|
|
33
|
+
"--plugin-dir",
|
|
34
|
+
"--plugin-dir-no-mcp",
|
|
35
|
+
"--plugin-url",
|
|
36
|
+
"--system-prompt",
|
|
37
|
+
"--system-prompt-file",
|
|
38
|
+
"--append-system-prompt",
|
|
39
|
+
"--append-system-prompt-file",
|
|
40
|
+
]);
|
|
41
|
+
const RESTRICTED_BARE_ARGS = new Set([
|
|
42
|
+
"--bare",
|
|
43
|
+
"--safe-mode",
|
|
44
|
+
DISABLE_SLASH_COMMANDS_ARG,
|
|
45
|
+
"--chrome",
|
|
46
|
+
NO_CHROME_ARG,
|
|
47
|
+
STRICT_MCP_CONFIG_ARG,
|
|
48
|
+
"--dangerously-skip-permissions",
|
|
49
|
+
"--allow-dangerously-skip-permissions",
|
|
50
|
+
"--ide",
|
|
51
|
+
]);
|
|
52
|
+
export function stripClaudeArgs(args, policy) {
|
|
53
|
+
const normalized = [];
|
|
54
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
55
|
+
const arg = args[i] ?? "";
|
|
56
|
+
const equalsIndex = arg.indexOf("=");
|
|
57
|
+
const argName = equalsIndex > 0 ? arg.slice(0, equalsIndex) : arg;
|
|
58
|
+
if (policy.bare?.has(argName))
|
|
59
|
+
continue;
|
|
60
|
+
if (policy.variadicValue?.has(argName)) {
|
|
61
|
+
if (equalsIndex < 0) {
|
|
62
|
+
while (typeof args[i + 1] === "string" && !args[i + 1]?.startsWith("-"))
|
|
63
|
+
i += 1;
|
|
64
|
+
}
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (policy.value?.has(argName)) {
|
|
68
|
+
if (equalsIndex < 0) {
|
|
69
|
+
const maybeValue = args[i + 1];
|
|
70
|
+
if (typeof maybeValue === "string" && !maybeValue.startsWith("-"))
|
|
71
|
+
i += 1;
|
|
72
|
+
}
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
normalized.push(arg);
|
|
76
|
+
}
|
|
77
|
+
return normalized;
|
|
78
|
+
}
|
|
79
|
+
function collectPreservedDenials(baseArgs) {
|
|
80
|
+
const preserved = [];
|
|
81
|
+
for (let i = 0; i < baseArgs.length; i += 1) {
|
|
82
|
+
const arg = baseArgs[i] ?? "";
|
|
83
|
+
if (arg === DISALLOWED_TOOLS_ARG || arg === "--disallowed-tools") {
|
|
84
|
+
while (typeof baseArgs[i + 1] === "string" && !baseArgs[i + 1]?.startsWith("-")) {
|
|
85
|
+
i += 1;
|
|
86
|
+
preserved.push(...(baseArgs[i] ?? "").split(","));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else if (arg.startsWith(`${DISALLOWED_TOOLS_ARG}=`) || arg.startsWith("--disallowed-tools=")) {
|
|
90
|
+
preserved.push(...arg.slice(arg.indexOf("=") + 1).split(","));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return preserved;
|
|
94
|
+
}
|
|
95
|
+
export function resolveRestrictedExecutionArgs(baseArgs, availability) {
|
|
96
|
+
const preservedDenials = collectPreservedDenials(baseArgs);
|
|
97
|
+
const normalized = stripClaudeArgs(baseArgs, {
|
|
98
|
+
bare: RESTRICTED_BARE_ARGS,
|
|
99
|
+
variadicValue: RESTRICTED_VARIADIC_VALUE_ARGS,
|
|
100
|
+
value: RESTRICTED_VALUE_ARGS,
|
|
101
|
+
});
|
|
102
|
+
normalized.push(SETTING_SOURCES_ARG, "", SETTINGS_ARG, RESTRICTED_SETTINGS, DISABLE_SLASH_COMMANDS_ARG, NO_CHROME_ARG, STRICT_MCP_CONFIG_ARG, TOOLS_ARG, availability.native.join(","));
|
|
103
|
+
if (availability.openClaw.length > 0) {
|
|
104
|
+
normalized.push(ALLOWED_TOOLS_ARG, availability.openClaw.map((toolName) => `${OPENCLAW_MCP_TOOL_PREFIX}${toolName}`).join(","));
|
|
105
|
+
}
|
|
106
|
+
const denials = [
|
|
107
|
+
...new Set([
|
|
108
|
+
...preservedDenials.map((entry) => entry.trim()).filter(Boolean),
|
|
109
|
+
...(availability.openClaw.length === 0 ? [DENY_MCP_TOOLS_VALUE] : []),
|
|
110
|
+
]),
|
|
111
|
+
].sort();
|
|
112
|
+
if (denials.length > 0)
|
|
113
|
+
normalized.push(DISALLOWED_TOOLS_ARG, denials.join(","));
|
|
114
|
+
return normalized;
|
|
115
|
+
}
|
|
116
|
+
export function resolvePoolExecutionArgs(ctx) {
|
|
117
|
+
return ctx.toolAvailability
|
|
118
|
+
? resolveRestrictedExecutionArgs(ctx.baseArgs, ctx.toolAvailability)
|
|
119
|
+
: ctx.baseArgs;
|
|
120
|
+
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "multi-clawd",
|
|
3
3
|
"name": "multi-clawd",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.5",
|
|
5
5
|
"description": "Register additional Claude Code logins (Max/Pro accounts) as first-class OpenClaw CLI backends for cross-account failover, keeping the full skills/MCP harness on every account.",
|
|
6
6
|
"cliBackends": [
|
|
7
7
|
"claw1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakon-systems/multi-clawd",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.5",
|
|
4
4
|
"description": "Multi-account Claude Code failover for OpenClaw — register additional Claude (Max/Pro) logins as first-class CLI backends and keep the full skills/MCP harness across every account. Also imports those accounts' setup tokens into Hermes Agent's Anthropic credential pool.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|