@drakon-systems/multi-clawd 1.8.2 → 1.8.3
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 -5
- package/SECURITY.md +1 -1
- package/dist/index.js +38 -9
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
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.3/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
|
|
|
@@ -381,7 +381,7 @@ prefer a tag over a branch.
|
|
|
381
381
|
|
|
382
382
|
**Requirements:** OpenClaw ≥ 2026.6, the `claude` CLI on `PATH`, and a
|
|
383
383
|
second Claude subscription you own. The current plugin SDK contract and runtime
|
|
384
|
-
registration path are tested against OpenClaw **2026.
|
|
384
|
+
registration path are tested against OpenClaw **2026.8.1**. The standalone
|
|
385
385
|
`multi-clawd` CLI and Hermes commands do not require the optional OpenClaw peer
|
|
386
386
|
to be resolvable; plugin loading and OpenClaw-backed commands still require the
|
|
387
387
|
host-provided peer.
|
|
@@ -603,7 +603,7 @@ Three moves, all through the official plugin SDK (details in
|
|
|
603
603
|
(`CLAUDE_CONFIG_DIR` + `CLAUDE_CODE_OAUTH_TOKEN`) into the child process
|
|
604
604
|
env, after the host's ambient Claude credentials are stripped.
|
|
605
605
|
|
|
606
|
-
##
|
|
606
|
+
## Legacy issue: idle backend eviction on OpenClaw ≤ 2026.7.1
|
|
607
607
|
|
|
608
608
|
On OpenClaw ≤ 2026.7.1, core's *scoped* harness activation can silently drop
|
|
609
609
|
a plugin-registered CLI backend from the live registry: when an agent turn
|
|
@@ -615,9 +615,10 @@ list` (a separate cache) still lists its models. A common real-world trigger
|
|
|
615
615
|
is an hourly heartbeat running on a model served by another harness.
|
|
616
616
|
|
|
617
617
|
- Upstream bug: [openclaw#107408](https://github.com/openclaw/openclaw/issues/107408)
|
|
618
|
-
- Upstream fix: [openclaw#
|
|
618
|
+
- Upstream fix: [openclaw#108110](https://github.com/openclaw/openclaw/pull/108110)
|
|
619
619
|
|
|
620
|
-
|
|
620
|
+
OpenClaw 2026.8.1 includes the fix. On affected older runtimes, a gateway
|
|
621
|
+
restart always restores the backend (startup
|
|
621
622
|
loads are full-scope), and backends that are in regular use effectively
|
|
622
623
|
re-assert themselves. This repo ships a ready-made mitigation —
|
|
623
624
|
`scripts/eviction-watchdog.mjs` — which tails the gateway log for the
|
package/SECURITY.md
CHANGED
|
@@ -30,7 +30,7 @@ credit you (unless you'd rather we didn't), and note it in the CHANGELOG.
|
|
|
30
30
|
`oauthTokenFile`, multi-clawd warns (once per process) when the file is
|
|
31
31
|
readable beyond your own user account. It warns rather than refuses: the
|
|
32
32
|
credential still works, and the fix is yours to make — `chmod 600`.
|
|
33
|
-
- **Host credentials are stripped from child processes.**
|
|
33
|
+
- **Host credentials are stripped from child processes.** 42 Claude/Anthropic
|
|
34
34
|
environment variables covering authentication, runtime, and telemetry are
|
|
35
35
|
cleared before each launch, so one account's credential cannot bleed into
|
|
36
36
|
another account's session.
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
-
import { resolvePluginConfigObject, resolveLivePluginConfigObject, } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
3
|
-
import { CLI_FRESH_WATCHDOG_DEFAULTS, CLI_RESUME_WATCHDOG_DEFAULTS, } from "openclaw/plugin-sdk/cli-backend";
|
|
1
|
+
import { definePluginEntry, } from "openclaw/plugin-sdk/plugin-entry";
|
|
4
2
|
import { homedir } from "node:os";
|
|
5
3
|
import { mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
6
4
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -21,6 +19,16 @@ import { buildAccountChildEnv, tokenFileModeWarning, validateAccountTokenSources
|
|
|
21
19
|
import { diffCatalogModels, formatNewModelNotice, } from "./model-currency.js";
|
|
22
20
|
import { checkAccountCredential, createRefProbeTracker, } from "./login-health.js";
|
|
23
21
|
import { execFileSync } from "node:child_process";
|
|
22
|
+
const CLI_FRESH_WATCHDOG_DEFAULTS = {
|
|
23
|
+
noOutputTimeoutRatio: 0.8,
|
|
24
|
+
minMs: 180_000,
|
|
25
|
+
maxMs: 600_000,
|
|
26
|
+
};
|
|
27
|
+
const CLI_RESUME_WATCHDOG_DEFAULTS = {
|
|
28
|
+
noOutputTimeoutRatio: 0.3,
|
|
29
|
+
minMs: 60_000,
|
|
30
|
+
maxMs: 180_000,
|
|
31
|
+
};
|
|
24
32
|
const BASE_ARGS = [
|
|
25
33
|
"-p",
|
|
26
34
|
"--output-format",
|
|
@@ -44,6 +52,10 @@ export const CLEAR_ENV = [
|
|
|
44
52
|
"ANTHROPIC_OAUTH_TOKEN",
|
|
45
53
|
"ANTHROPIC_UNIX_SOCKET",
|
|
46
54
|
"CLAUDE_CONFIG_DIR",
|
|
55
|
+
"CLAUDE_CODE_AUTO_COMPACT_WINDOW",
|
|
56
|
+
"CLAUDE_CODE_DISABLE_1M_CONTEXT",
|
|
57
|
+
"CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING",
|
|
58
|
+
"MAX_THINKING_TOKENS",
|
|
47
59
|
"CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR",
|
|
48
60
|
"CLAUDE_CODE_ENTRYPOINT",
|
|
49
61
|
"CLAUDE_CODE_OAUTH_REFRESH_TOKEN",
|
|
@@ -81,6 +93,18 @@ function expandHome(p) {
|
|
|
81
93
|
return resolve(homedir(), p.slice(2));
|
|
82
94
|
return resolve(p);
|
|
83
95
|
}
|
|
96
|
+
function pluginConfigFromRoot(root, pluginId) {
|
|
97
|
+
if (typeof root !== "object" || root === null)
|
|
98
|
+
return undefined;
|
|
99
|
+
const entries = root.plugins?.entries;
|
|
100
|
+
const entry = entries?.[pluginId];
|
|
101
|
+
if (typeof entry !== "object" || entry === null)
|
|
102
|
+
return undefined;
|
|
103
|
+
const config = entry.config;
|
|
104
|
+
return typeof config === "object" && config !== null && !Array.isArray(config)
|
|
105
|
+
? config
|
|
106
|
+
: undefined;
|
|
107
|
+
}
|
|
84
108
|
let activeTokenResolver;
|
|
85
109
|
let alertState = { alerts: [] };
|
|
86
110
|
let loginProbeTimer;
|
|
@@ -352,7 +376,7 @@ function checkModelCurrency(catalogIds, chainRefs, poolId) {
|
|
|
352
376
|
}
|
|
353
377
|
}
|
|
354
378
|
export function buildBackend(account, execMode) {
|
|
355
|
-
|
|
379
|
+
const backend = {
|
|
356
380
|
id: account.id,
|
|
357
381
|
liveTest: {
|
|
358
382
|
defaultModelRef: `${account.id}/${account.defaultModel ?? "claude-fable-5"}`,
|
|
@@ -372,6 +396,8 @@ export function buildBackend(account, execMode) {
|
|
|
372
396
|
command: process.execPath,
|
|
373
397
|
args: [SHIM_PATH, ...BASE_ARGS, ...permissionModeArgs(execMode)],
|
|
374
398
|
resumeArgs: [SHIM_PATH, ...BASE_ARGS, ...permissionModeArgs(execMode), "--resume", "{sessionId}"],
|
|
399
|
+
forkArg: "--fork-session",
|
|
400
|
+
resumeAtArg: "--resume-session-at",
|
|
375
401
|
output: "jsonl",
|
|
376
402
|
liveSession: "claude-stdio",
|
|
377
403
|
input: "stdin",
|
|
@@ -380,8 +406,9 @@ export function buildBackend(account, execMode) {
|
|
|
380
406
|
modelAliases: { ...MODEL_ALIASES },
|
|
381
407
|
imageArg: "@",
|
|
382
408
|
imagePathScope: "workspace",
|
|
383
|
-
|
|
409
|
+
sessionArgs: ["--session-id", "{sessionId}"],
|
|
384
410
|
sessionMode: "always",
|
|
411
|
+
freshSessionRecovery: "invalidated-only",
|
|
385
412
|
reseedFromRawTranscriptWhenUncompacted: true,
|
|
386
413
|
sessionIdFields: ["session_id", "sessionId", "conversation_id", "conversationId"],
|
|
387
414
|
systemPromptFileArg: "--append-system-prompt-file",
|
|
@@ -400,6 +427,8 @@ export function buildBackend(account, execMode) {
|
|
|
400
427
|
return { env: await buildAccountEnv(account) };
|
|
401
428
|
},
|
|
402
429
|
};
|
|
430
|
+
Object.assign(backend.config, { sessionArg: "--session-id" });
|
|
431
|
+
return backend;
|
|
403
432
|
}
|
|
404
433
|
async function buildAccountEnv(account, resolver) {
|
|
405
434
|
const token = await resolveTokenAsync(account, resolver);
|
|
@@ -434,12 +463,12 @@ export default definePluginEntry({
|
|
|
434
463
|
name: "multi-clawd",
|
|
435
464
|
description: "Register additional Claude Code logins as first-class OpenClaw CLI backends for cross-account failover.",
|
|
436
465
|
register(api) {
|
|
437
|
-
const runtimeConfigLoader =
|
|
466
|
+
const runtimeConfigLoader = api.runtime?.config?.current
|
|
438
467
|
? () => api.runtime.config.current()
|
|
439
|
-
: undefined
|
|
468
|
+
: undefined;
|
|
440
469
|
const candidates = [
|
|
441
|
-
|
|
442
|
-
|
|
470
|
+
pluginConfigFromRoot(runtimeConfigLoader?.(), "multi-clawd"),
|
|
471
|
+
pluginConfigFromRoot(api.config, "multi-clawd"),
|
|
443
472
|
api.pluginConfig,
|
|
444
473
|
];
|
|
445
474
|
const hasAccounts = (c) => Array.isArray(c?.accounts) &&
|
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.3",
|
|
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.3",
|
|
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",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
],
|
|
22
22
|
"openclaw": {
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.
|
|
24
|
+
"openclawVersion": "2026.8.1"
|
|
25
25
|
},
|
|
26
26
|
"extensions": [
|
|
27
27
|
"./src/index.ts"
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"openclaw": "2026.
|
|
75
|
+
"openclaw": "2026.8.1",
|
|
76
76
|
"typescript": "^5.9.0",
|
|
77
77
|
"vitest": "^4.1.10"
|
|
78
78
|
},
|