@drakon-systems/multi-clawd 1.2.0 → 1.2.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/package.json +1 -1
- package/scripts/_shared.mjs +48 -0
- package/scripts/cli.mjs +3 -28
- package/scripts/setup.mjs +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakon-systems/multi-clawd",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
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.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the CLI scripts (cli.mjs, setup.mjs).
|
|
3
|
+
*
|
|
4
|
+
* resolveWatchdogScript exists because of a real footgun: run via `npx`, a
|
|
5
|
+
* script's __dirname is the EPHEMERAL npx cache — pointing a scheduled unit
|
|
6
|
+
* there breaks on the next cache clean. The watchdog target must be the
|
|
7
|
+
* INSTALLED plugin's copy whenever one exists; the __dirname sibling is only
|
|
8
|
+
* correct for a source checkout with no install.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
|
|
14
|
+
/** Where the plugin is installed: path install wins, else newest npm-project install. */
|
|
15
|
+
export function resolveInstallDir() {
|
|
16
|
+
const HOME = homedir();
|
|
17
|
+
const extDir = join(HOME, ".openclaw", "extensions", "multi-clawd");
|
|
18
|
+
if (existsSync(join(extDir, "openclaw.plugin.json"))) return extDir;
|
|
19
|
+
const projects = join(HOME, ".openclaw", "npm", "projects");
|
|
20
|
+
let best;
|
|
21
|
+
let bestM = -1;
|
|
22
|
+
try {
|
|
23
|
+
for (const p of readdirSync(projects)) {
|
|
24
|
+
if (!p.startsWith("drakon-systems-multi-clawd-")) continue;
|
|
25
|
+
const dir = join(projects, p, "node_modules", "@drakon-systems", "multi-clawd");
|
|
26
|
+
const manifest = join(dir, "openclaw.plugin.json");
|
|
27
|
+
if (!existsSync(manifest)) continue;
|
|
28
|
+
const m = statSync(manifest).mtimeMs;
|
|
29
|
+
if (m > bestM) {
|
|
30
|
+
bestM = m;
|
|
31
|
+
best = dir;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
/* no npm projects dir */
|
|
36
|
+
}
|
|
37
|
+
return best;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The watchdog script a scheduled unit should point at. */
|
|
41
|
+
export function resolveWatchdogScript(fallbackDir) {
|
|
42
|
+
const inst = resolveInstallDir();
|
|
43
|
+
if (inst) {
|
|
44
|
+
const p = join(inst, "scripts", "eviction-watchdog.mjs");
|
|
45
|
+
if (existsSync(p)) return p;
|
|
46
|
+
}
|
|
47
|
+
return join(fallbackDir, "eviction-watchdog.mjs");
|
|
48
|
+
}
|
package/scripts/cli.mjs
CHANGED
|
@@ -15,15 +15,13 @@
|
|
|
15
15
|
* has to remember `--pin --force`.
|
|
16
16
|
*/
|
|
17
17
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
18
|
-
import {
|
|
19
|
-
import { homedir } from "node:os";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
20
19
|
import { dirname, join, resolve } from "node:path";
|
|
21
20
|
import { fileURLToPath } from "node:url";
|
|
22
21
|
import readline from "node:readline/promises";
|
|
23
22
|
|
|
24
23
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
24
|
const PKG = "@drakon-systems/multi-clawd";
|
|
26
|
-
const HOME = homedir();
|
|
27
25
|
const BOLD = process.stdout.isTTY ? "\x1b[1m" : "";
|
|
28
26
|
const DIM = process.stdout.isTTY ? "\x1b[2m" : "";
|
|
29
27
|
const RESET = process.stdout.isTTY ? "\x1b[0m" : "";
|
|
@@ -44,30 +42,7 @@ Run via npx (${DIM}npx ${PKG} <command>${RESET}) or install globally
|
|
|
44
42
|
`);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
function resolveInstallDir() {
|
|
49
|
-
const extDir = join(HOME, ".openclaw", "extensions", "multi-clawd");
|
|
50
|
-
if (existsSync(join(extDir, "openclaw.plugin.json"))) return extDir;
|
|
51
|
-
const projects = join(HOME, ".openclaw", "npm", "projects");
|
|
52
|
-
let best;
|
|
53
|
-
let bestM = -1;
|
|
54
|
-
try {
|
|
55
|
-
for (const p of readdirSync(projects)) {
|
|
56
|
-
if (!p.startsWith("drakon-systems-multi-clawd-")) continue;
|
|
57
|
-
const dir = join(projects, p, "node_modules", "@drakon-systems", "multi-clawd");
|
|
58
|
-
const manifest = join(dir, "openclaw.plugin.json");
|
|
59
|
-
if (!existsSync(manifest)) continue;
|
|
60
|
-
const m = statSync(manifest).mtimeMs;
|
|
61
|
-
if (m > bestM) {
|
|
62
|
-
bestM = m;
|
|
63
|
-
best = dir;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
} catch {
|
|
67
|
-
/* no npm projects dir */
|
|
68
|
-
}
|
|
69
|
-
return best;
|
|
70
|
-
}
|
|
45
|
+
const { resolveInstallDir } = await import(join(__dirname, "_shared.mjs"));
|
|
71
46
|
|
|
72
47
|
function installedVersion() {
|
|
73
48
|
const dir = resolveInstallDir();
|
|
@@ -155,7 +130,7 @@ async function update() {
|
|
|
155
130
|
console.log(`\n${BOLD} health check${RESET}`);
|
|
156
131
|
const doc = spawnSync(process.execPath, [join(__dirname, "doctor.mjs")], { stdio: "inherit" });
|
|
157
132
|
if (doc.status !== 0) {
|
|
158
|
-
console.log(`\n ⚠ doctor found problems — if it flagged the watchdog, run ${BOLD}
|
|
133
|
+
console.log(`\n ⚠ doctor found problems — if it flagged the watchdog, run ${BOLD}npx ${PKG} setup${RESET} to repair it.`);
|
|
159
134
|
process.exit(doc.status ?? 1);
|
|
160
135
|
}
|
|
161
136
|
console.log(`\n ✅ done — now on v${installedVersion() ?? "?"}`);
|
package/scripts/setup.mjs
CHANGED
|
@@ -229,7 +229,10 @@ async function watchdogStep() {
|
|
|
229
229
|
console.log(" (auto-scheduling not supported on this platform — see README for manual setup)");
|
|
230
230
|
return;
|
|
231
231
|
}
|
|
232
|
-
|
|
232
|
+
// Install-aware: under npx, __dirname is the EPHEMERAL npx cache — the unit
|
|
233
|
+
// must point at the installed plugin's copy whenever one exists.
|
|
234
|
+
const { resolveWatchdogScript } = await import(resolve(__dirname, "_shared.mjs"));
|
|
235
|
+
const scriptPath = resolveWatchdogScript(__dirname);
|
|
233
236
|
const scanDir =
|
|
234
237
|
platform === "darwin"
|
|
235
238
|
? join(homedir(), "Library", "LaunchAgents")
|