multiclaws 0.4.41 → 0.4.43

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.
Files changed (39) hide show
  1. package/README.md +2 -0
  2. package/dist/gateway/handlers.d.ts +4 -4
  3. package/dist/gateway/handlers.js +239 -239
  4. package/dist/index.d.ts +8 -8
  5. package/dist/index.js +710 -710
  6. package/dist/infra/frp.d.ts +55 -55
  7. package/dist/infra/frp.js +398 -398
  8. package/dist/infra/gateway-client.d.ts +27 -27
  9. package/dist/infra/gateway-client.js +136 -136
  10. package/dist/infra/json-store.d.ts +4 -4
  11. package/dist/infra/json-store.js +57 -57
  12. package/dist/infra/logger.d.ts +14 -14
  13. package/dist/infra/logger.js +25 -25
  14. package/dist/infra/rate-limiter.d.ts +19 -19
  15. package/dist/infra/rate-limiter.js +69 -69
  16. package/dist/infra/tailscale.d.ts +19 -19
  17. package/dist/infra/tailscale.js +120 -120
  18. package/dist/infra/telemetry.d.ts +3 -3
  19. package/dist/infra/telemetry.js +17 -17
  20. package/dist/infra/version.d.ts +1 -1
  21. package/dist/infra/version.js +19 -19
  22. package/dist/service/a2a-adapter.d.ts +80 -80
  23. package/dist/service/a2a-adapter.js +505 -505
  24. package/dist/service/agent-profile.d.ts +17 -17
  25. package/dist/service/agent-profile.js +58 -58
  26. package/dist/service/agent-registry.d.ts +29 -29
  27. package/dist/service/agent-registry.js +131 -131
  28. package/dist/service/multiclaws-service.d.ts +150 -150
  29. package/dist/service/multiclaws-service.js +1137 -1137
  30. package/dist/service/session-store.d.ts +46 -46
  31. package/dist/service/session-store.js +143 -143
  32. package/dist/task/tracker.d.ts +46 -46
  33. package/dist/task/tracker.js +191 -191
  34. package/dist/team/team-store.d.ts +42 -42
  35. package/dist/team/team-store.js +195 -195
  36. package/dist/types/openclaw.d.ts +109 -109
  37. package/dist/types/openclaw.js +2 -2
  38. package/package.json +1 -1
  39. package/skills/meeting-scheduler/SKILL.md +112 -105
@@ -1,69 +1,69 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RateLimiter = void 0;
4
- /**
5
- * Simple sliding-window rate limiter keyed by peer ID.
6
- * Returns true if the request should be allowed, false if rate-limited.
7
- * Periodically prunes empty/stale keys to prevent unbounded memory growth.
8
- */
9
- class RateLimiter {
10
- windowMs;
11
- maxRequests;
12
- windows = new Map();
13
- pruneTimer = null;
14
- constructor(opts) {
15
- this.windowMs = opts?.windowMs ?? 60_000;
16
- this.maxRequests = opts?.maxRequests ?? 60;
17
- // Prune stale keys every 5 minutes
18
- this.pruneTimer = setInterval(() => this.pruneStaleKeys(), 5 * 60_000);
19
- if (this.pruneTimer && typeof this.pruneTimer === "object" && "unref" in this.pruneTimer) {
20
- this.pruneTimer.unref();
21
- }
22
- }
23
- allow(key) {
24
- const now = Date.now();
25
- const cutoff = now - this.windowMs;
26
- let timestamps = this.windows.get(key);
27
- if (!timestamps) {
28
- timestamps = [];
29
- this.windows.set(key, timestamps);
30
- }
31
- // Binary search for the first timestamp within the window, then
32
- // bulk-remove all expired entries in one splice (O(log n) + O(k)).
33
- let lo = 0;
34
- let hi = timestamps.length;
35
- while (lo < hi) {
36
- const mid = (lo + hi) >>> 1;
37
- if (timestamps[mid] < cutoff)
38
- lo = mid + 1;
39
- else
40
- hi = mid;
41
- }
42
- if (lo > 0)
43
- timestamps.splice(0, lo);
44
- if (timestamps.length >= this.maxRequests) {
45
- return false;
46
- }
47
- timestamps.push(now);
48
- return true;
49
- }
50
- reset(key) {
51
- this.windows.delete(key);
52
- }
53
- destroy() {
54
- if (this.pruneTimer) {
55
- clearInterval(this.pruneTimer);
56
- this.pruneTimer = null;
57
- }
58
- this.windows.clear();
59
- }
60
- pruneStaleKeys() {
61
- const cutoff = Date.now() - this.windowMs;
62
- for (const [key, timestamps] of this.windows) {
63
- if (timestamps.length === 0 || timestamps[timestamps.length - 1] < cutoff) {
64
- this.windows.delete(key);
65
- }
66
- }
67
- }
68
- }
69
- exports.RateLimiter = RateLimiter;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimiter = void 0;
4
+ /**
5
+ * Simple sliding-window rate limiter keyed by peer ID.
6
+ * Returns true if the request should be allowed, false if rate-limited.
7
+ * Periodically prunes empty/stale keys to prevent unbounded memory growth.
8
+ */
9
+ class RateLimiter {
10
+ windowMs;
11
+ maxRequests;
12
+ windows = new Map();
13
+ pruneTimer = null;
14
+ constructor(opts) {
15
+ this.windowMs = opts?.windowMs ?? 60_000;
16
+ this.maxRequests = opts?.maxRequests ?? 60;
17
+ // Prune stale keys every 5 minutes
18
+ this.pruneTimer = setInterval(() => this.pruneStaleKeys(), 5 * 60_000);
19
+ if (this.pruneTimer && typeof this.pruneTimer === "object" && "unref" in this.pruneTimer) {
20
+ this.pruneTimer.unref();
21
+ }
22
+ }
23
+ allow(key) {
24
+ const now = Date.now();
25
+ const cutoff = now - this.windowMs;
26
+ let timestamps = this.windows.get(key);
27
+ if (!timestamps) {
28
+ timestamps = [];
29
+ this.windows.set(key, timestamps);
30
+ }
31
+ // Binary search for the first timestamp within the window, then
32
+ // bulk-remove all expired entries in one splice (O(log n) + O(k)).
33
+ let lo = 0;
34
+ let hi = timestamps.length;
35
+ while (lo < hi) {
36
+ const mid = (lo + hi) >>> 1;
37
+ if (timestamps[mid] < cutoff)
38
+ lo = mid + 1;
39
+ else
40
+ hi = mid;
41
+ }
42
+ if (lo > 0)
43
+ timestamps.splice(0, lo);
44
+ if (timestamps.length >= this.maxRequests) {
45
+ return false;
46
+ }
47
+ timestamps.push(now);
48
+ return true;
49
+ }
50
+ reset(key) {
51
+ this.windows.delete(key);
52
+ }
53
+ destroy() {
54
+ if (this.pruneTimer) {
55
+ clearInterval(this.pruneTimer);
56
+ this.pruneTimer = null;
57
+ }
58
+ this.windows.clear();
59
+ }
60
+ pruneStaleKeys() {
61
+ const cutoff = Date.now() - this.windowMs;
62
+ for (const [key, timestamps] of this.windows) {
63
+ if (timestamps.length === 0 || timestamps[timestamps.length - 1] < cutoff) {
64
+ this.windows.delete(key);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ exports.RateLimiter = RateLimiter;
@@ -1,19 +1,19 @@
1
- export type TailscaleStatus = {
2
- status: "ready";
3
- ip: string;
4
- } | {
5
- status: "needs_auth";
6
- authUrl: string;
7
- } | {
8
- status: "not_installed";
9
- } | {
10
- status: "unavailable";
11
- reason: string;
12
- };
13
- /** Check network interfaces for a Tailscale IP (100.x.x.x) — exported for fast-path checks */
14
- export declare function getTailscaleIpFromInterfaces(): string | null;
15
- /**
16
- * Detect Tailscale status — does NOT install or modify system state.
17
- * Returns one of: ready | needs_auth | not_installed | unavailable
18
- */
19
- export declare function detectTailscale(): Promise<TailscaleStatus>;
1
+ export type TailscaleStatus = {
2
+ status: "ready";
3
+ ip: string;
4
+ } | {
5
+ status: "needs_auth";
6
+ authUrl: string;
7
+ } | {
8
+ status: "not_installed";
9
+ } | {
10
+ status: "unavailable";
11
+ reason: string;
12
+ };
13
+ /** Check network interfaces for a Tailscale IP (100.x.x.x) — exported for fast-path checks */
14
+ export declare function getTailscaleIpFromInterfaces(): string | null;
15
+ /**
16
+ * Detect Tailscale status — does NOT install or modify system state.
17
+ * Returns one of: ready | needs_auth | not_installed | unavailable
18
+ */
19
+ export declare function detectTailscale(): Promise<TailscaleStatus>;
@@ -1,120 +1,120 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getTailscaleIpFromInterfaces = getTailscaleIpFromInterfaces;
7
- exports.detectTailscale = detectTailscale;
8
- const node_child_process_1 = require("node:child_process");
9
- const node_os_1 = __importDefault(require("node:os"));
10
- function run(cmd, timeoutMs = 5_000) {
11
- return (0, node_child_process_1.execSync)(cmd, { timeout: timeoutMs, stdio: ["ignore", "pipe", "pipe"] })
12
- .toString()
13
- .trim();
14
- }
15
- function commandExists(cmd) {
16
- try {
17
- run(`which ${cmd}`);
18
- return true;
19
- }
20
- catch {
21
- return false;
22
- }
23
- }
24
- /** Check network interfaces for a Tailscale IP (100.x.x.x) — exported for fast-path checks */
25
- function getTailscaleIpFromInterfaces() {
26
- const interfaces = node_os_1.default.networkInterfaces();
27
- for (const addrs of Object.values(interfaces)) {
28
- if (!addrs)
29
- continue;
30
- for (const addr of addrs) {
31
- if (addr.family === "IPv4" && addr.address.startsWith("100.")) {
32
- return addr.address;
33
- }
34
- }
35
- }
36
- return null;
37
- }
38
- /** Ask tailscale CLI for the IP */
39
- function getTailscaleIpFromCli() {
40
- try {
41
- const ip = run("tailscale ip -4").split("\n")[0];
42
- return ip || null;
43
- }
44
- catch {
45
- return null;
46
- }
47
- }
48
- /** Check if tailscale daemon is running and authenticated */
49
- function isAuthenticated() {
50
- try {
51
- const out = run("tailscale status --json");
52
- const json = JSON.parse(out);
53
- return json.BackendState === "Running";
54
- }
55
- catch {
56
- return false;
57
- }
58
- }
59
- /** Get auth URL from `tailscale up` output (non-blocking, reads stderr/stdout for a few seconds) */
60
- async function getAuthUrl() {
61
- return new Promise((resolve) => {
62
- try {
63
- // tailscale up prints the auth URL to stderr
64
- const { spawn } = require("node:child_process");
65
- const proc = spawn("tailscale", ["up"], { stdio: ["ignore", "pipe", "pipe"] });
66
- let output = "";
67
- let resolved = false;
68
- const tryResolve = (text) => {
69
- const match = text.match(/https:\/\/login\.tailscale\.com\/[^\s]+/);
70
- if (match && !resolved) {
71
- resolved = true;
72
- proc.kill();
73
- resolve(match[0]);
74
- }
75
- };
76
- proc.stdout?.on("data", (d) => { output += d.toString(); tryResolve(output); });
77
- proc.stderr?.on("data", (d) => { output += d.toString(); tryResolve(output); });
78
- proc.on("close", () => { if (!resolved) {
79
- resolved = true;
80
- resolve(null);
81
- } });
82
- setTimeout(() => { if (!resolved) {
83
- resolved = true;
84
- proc.kill();
85
- resolve(null);
86
- } }, 8_000);
87
- }
88
- catch {
89
- resolve(null);
90
- }
91
- });
92
- }
93
- /**
94
- * Detect Tailscale status — does NOT install or modify system state.
95
- * Returns one of: ready | needs_auth | not_installed | unavailable
96
- */
97
- async function detectTailscale() {
98
- // Fast path: check network interfaces first (no subprocess)
99
- const ifaceIp = getTailscaleIpFromInterfaces();
100
- if (ifaceIp) {
101
- return { status: "ready", ip: ifaceIp };
102
- }
103
- // Not installed
104
- if (!commandExists("tailscale")) {
105
- return { status: "not_installed" };
106
- }
107
- // Installed but check auth
108
- if (isAuthenticated()) {
109
- const ip = getTailscaleIpFromCli();
110
- if (ip)
111
- return { status: "ready", ip };
112
- return { status: "unavailable", reason: "authenticated but no IP assigned" };
113
- }
114
- // Needs auth — try to get login URL
115
- const authUrl = await getAuthUrl();
116
- if (authUrl) {
117
- return { status: "needs_auth", authUrl };
118
- }
119
- return { status: "unavailable", reason: "could not determine auth URL" };
120
- }
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getTailscaleIpFromInterfaces = getTailscaleIpFromInterfaces;
7
+ exports.detectTailscale = detectTailscale;
8
+ const node_child_process_1 = require("node:child_process");
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ function run(cmd, timeoutMs = 5_000) {
11
+ return (0, node_child_process_1.execSync)(cmd, { timeout: timeoutMs, stdio: ["ignore", "pipe", "pipe"] })
12
+ .toString()
13
+ .trim();
14
+ }
15
+ function commandExists(cmd) {
16
+ try {
17
+ run(`which ${cmd}`);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ /** Check network interfaces for a Tailscale IP (100.x.x.x) — exported for fast-path checks */
25
+ function getTailscaleIpFromInterfaces() {
26
+ const interfaces = node_os_1.default.networkInterfaces();
27
+ for (const addrs of Object.values(interfaces)) {
28
+ if (!addrs)
29
+ continue;
30
+ for (const addr of addrs) {
31
+ if (addr.family === "IPv4" && addr.address.startsWith("100.")) {
32
+ return addr.address;
33
+ }
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+ /** Ask tailscale CLI for the IP */
39
+ function getTailscaleIpFromCli() {
40
+ try {
41
+ const ip = run("tailscale ip -4").split("\n")[0];
42
+ return ip || null;
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ /** Check if tailscale daemon is running and authenticated */
49
+ function isAuthenticated() {
50
+ try {
51
+ const out = run("tailscale status --json");
52
+ const json = JSON.parse(out);
53
+ return json.BackendState === "Running";
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ /** Get auth URL from `tailscale up` output (non-blocking, reads stderr/stdout for a few seconds) */
60
+ async function getAuthUrl() {
61
+ return new Promise((resolve) => {
62
+ try {
63
+ // tailscale up prints the auth URL to stderr
64
+ const { spawn } = require("node:child_process");
65
+ const proc = spawn("tailscale", ["up"], { stdio: ["ignore", "pipe", "pipe"] });
66
+ let output = "";
67
+ let resolved = false;
68
+ const tryResolve = (text) => {
69
+ const match = text.match(/https:\/\/login\.tailscale\.com\/[^\s]+/);
70
+ if (match && !resolved) {
71
+ resolved = true;
72
+ proc.kill();
73
+ resolve(match[0]);
74
+ }
75
+ };
76
+ proc.stdout?.on("data", (d) => { output += d.toString(); tryResolve(output); });
77
+ proc.stderr?.on("data", (d) => { output += d.toString(); tryResolve(output); });
78
+ proc.on("close", () => { if (!resolved) {
79
+ resolved = true;
80
+ resolve(null);
81
+ } });
82
+ setTimeout(() => { if (!resolved) {
83
+ resolved = true;
84
+ proc.kill();
85
+ resolve(null);
86
+ } }, 8_000);
87
+ }
88
+ catch {
89
+ resolve(null);
90
+ }
91
+ });
92
+ }
93
+ /**
94
+ * Detect Tailscale status — does NOT install or modify system state.
95
+ * Returns one of: ready | needs_auth | not_installed | unavailable
96
+ */
97
+ async function detectTailscale() {
98
+ // Fast path: check network interfaces first (no subprocess)
99
+ const ifaceIp = getTailscaleIpFromInterfaces();
100
+ if (ifaceIp) {
101
+ return { status: "ready", ip: ifaceIp };
102
+ }
103
+ // Not installed
104
+ if (!commandExists("tailscale")) {
105
+ return { status: "not_installed" };
106
+ }
107
+ // Installed but check auth
108
+ if (isAuthenticated()) {
109
+ const ip = getTailscaleIpFromCli();
110
+ if (ip)
111
+ return { status: "ready", ip };
112
+ return { status: "unavailable", reason: "authenticated but no IP assigned" };
113
+ }
114
+ // Needs auth — try to get login URL
115
+ const authUrl = await getAuthUrl();
116
+ if (authUrl) {
117
+ return { status: "needs_auth", authUrl };
118
+ }
119
+ return { status: "unavailable", reason: "could not determine auth URL" };
120
+ }
@@ -1,3 +1,3 @@
1
- export declare function initializeTelemetry(params?: {
2
- enableConsoleExporter?: boolean;
3
- }): void;
1
+ export declare function initializeTelemetry(params?: {
2
+ enableConsoleExporter?: boolean;
3
+ }): void;
@@ -1,17 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initializeTelemetry = initializeTelemetry;
4
- const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
5
- const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
6
- let initialized = false;
7
- function initializeTelemetry(params) {
8
- if (initialized) {
9
- return;
10
- }
11
- const spanProcessors = (params?.enableConsoleExporter || process.env.MULTICLAWS_OTEL_CONSOLE === "1")
12
- ? [new sdk_trace_base_1.SimpleSpanProcessor(new sdk_trace_base_1.ConsoleSpanExporter())]
13
- : [];
14
- const provider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors });
15
- provider.register();
16
- initialized = true;
17
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeTelemetry = initializeTelemetry;
4
+ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
5
+ const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
6
+ let initialized = false;
7
+ function initializeTelemetry(params) {
8
+ if (initialized) {
9
+ return;
10
+ }
11
+ const spanProcessors = (params?.enableConsoleExporter || process.env.MULTICLAWS_OTEL_CONSOLE === "1")
12
+ ? [new sdk_trace_base_1.SimpleSpanProcessor(new sdk_trace_base_1.ConsoleSpanExporter())]
13
+ : [];
14
+ const provider = new sdk_trace_node_1.NodeTracerProvider({ spanProcessors });
15
+ provider.register();
16
+ initialized = true;
17
+ }
@@ -1 +1 @@
1
- export declare const PLUGIN_VERSION: string;
1
+ export declare const PLUGIN_VERSION: string;
@@ -1,19 +1,19 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PLUGIN_VERSION = void 0;
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- function readPackageVersion() {
10
- try {
11
- const pkgPath = node_path_1.default.resolve(__dirname, "..", "..", "package.json");
12
- const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgPath, "utf-8"));
13
- return pkg.version ?? "0.0.0";
14
- }
15
- catch {
16
- return "0.0.0";
17
- }
18
- }
19
- exports.PLUGIN_VERSION = readPackageVersion();
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PLUGIN_VERSION = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ function readPackageVersion() {
10
+ try {
11
+ const pkgPath = node_path_1.default.resolve(__dirname, "..", "..", "package.json");
12
+ const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgPath, "utf-8"));
13
+ return pkg.version ?? "0.0.0";
14
+ }
15
+ catch {
16
+ return "0.0.0";
17
+ }
18
+ }
19
+ exports.PLUGIN_VERSION = readPackageVersion();