@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 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.2/SETUP-AGENT.md
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.7.1**. The standalone
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
- ## Known issue: idle backends can be evicted by OpenClaw core
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#107596](https://github.com/openclaw/openclaw/pull/107596)
618
+ - Upstream fix: [openclaw#108110](https://github.com/openclaw/openclaw/pull/108110)
619
619
 
620
- **Until that lands:** a gateway restart always restores the backend (startup
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.** 38 Claude/Anthropic
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
- return {
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
- sessionArg: "--session-id",
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 = (api.runtime?.config?.current
466
+ const runtimeConfigLoader = api.runtime?.config?.current
438
467
  ? () => api.runtime.config.current()
439
- : undefined);
468
+ : undefined;
440
469
  const candidates = [
441
- resolveLivePluginConfigObject(runtimeConfigLoader, "multi-clawd", api.pluginConfig),
442
- resolvePluginConfigObject(api.config, "multi-clawd"),
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) &&
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "multi-clawd",
3
3
  "name": "multi-clawd",
4
- "version": "1.8.2",
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.2",
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.7.1"
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.7.1",
75
+ "openclaw": "2026.8.1",
76
76
  "typescript": "^5.9.0",
77
77
  "vitest": "^4.1.10"
78
78
  },