@vama/openclaw 2026.5.5-5 → 2026.5.5-7
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/dist/api-CBt1Mjce.js +25 -0
- package/dist/api.js +4 -4
- package/dist/{channel-plugin-api-KLKTLQFV.js → channel-plugin-api-Bi8Gs3E6.js} +3 -3
- package/dist/channel-plugin-api.js +1 -1
- package/dist/cli-uxMxzdnO.js +378 -0
- package/dist/index.js +5 -17
- package/dist/{monitor-DLgOtdLQ.js → monitor-BlnFXk24.js} +7 -7
- package/dist/runtime-api.js +1 -1
- package/package.json +1 -1
- package/dist/api-DftFHS2s.js +0 -13
- package/dist/cli-F0a1J9Rj.js +0 -150
- /package/dist/{probe-Cf1xor23.js → probe-COpuChEq.js} +0 -0
- /package/dist/{runtime-Cq09Y5cd.js → runtime-CQ9kld4S.js} +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "./probe-COpuChEq.js";
|
|
2
|
+
import { i as dispatchStarted, r as dispatchEnded } from "./monitor-BlnFXk24.js";
|
|
3
|
+
//#region extensions/vama/src/cli-metadata.ts
|
|
4
|
+
function registerVamaCliMetadata(api) {
|
|
5
|
+
api.registerCli(async ({ program }) => {
|
|
6
|
+
const { registerVamaCli } = await import("./cli-uxMxzdnO.js");
|
|
7
|
+
registerVamaCli({ program });
|
|
8
|
+
}, { descriptors: [{
|
|
9
|
+
name: "vama",
|
|
10
|
+
description: "Connect this OpenClaw to Vama and manage the Vama channel",
|
|
11
|
+
hasSubcommands: true
|
|
12
|
+
}] });
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region extensions/vama/src/subagent-keepalive-hooks.ts
|
|
16
|
+
function registerVamaSubagentKeepaliveHooks(api) {
|
|
17
|
+
api.on("subagent_spawned", () => {
|
|
18
|
+
dispatchStarted();
|
|
19
|
+
});
|
|
20
|
+
api.on("subagent_ended", () => {
|
|
21
|
+
dispatchEnded();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { registerVamaCliMetadata as n, registerVamaSubagentKeepaliveHooks as t };
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as
|
|
3
|
-
import { t as
|
|
4
|
-
export { monitorVamaProvider, probeVama, registerVamaSubagentKeepaliveHooks, sendMessageVama };
|
|
1
|
+
import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-CBt1Mjce.js";
|
|
2
|
+
import { n as probeVama } from "./probe-COpuChEq.js";
|
|
3
|
+
import { n as sendMessageVama, t as monitorVamaProvider } from "./monitor-BlnFXk24.js";
|
|
4
|
+
export { monitorVamaProvider, probeVama, registerVamaCliMetadata, registerVamaSubagentKeepaliveHooks, sendMessageVama };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as exchangeConnectCode, i as createBotHubClient, n as attachmentHintFromExtension, o as provisionBot } from "./client-BzhfASX8.js";
|
|
2
|
-
import { a as resolveDefaultVamaAccountId, i as listVamaAccountIds, n as probeVama, o as resolveVamaAccount } from "./probe-
|
|
3
|
-
import { a as DEFAULT_ACCOUNT_ID$1, c as createDefaultChannelRuntimeState, n as sendMessageVama, o as PAIRING_APPROVED_MESSAGE, s as buildBaseChannelStatusSummary, t as monitorVamaProvider } from "./monitor-
|
|
4
|
-
import { t as getVamaRuntime } from "./runtime-
|
|
2
|
+
import { a as resolveDefaultVamaAccountId, i as listVamaAccountIds, n as probeVama, o as resolveVamaAccount } from "./probe-COpuChEq.js";
|
|
3
|
+
import { a as DEFAULT_ACCOUNT_ID$1, c as createDefaultChannelRuntimeState, n as sendMessageVama, o as PAIRING_APPROVED_MESSAGE, s as buildBaseChannelStatusSummary, t as monitorVamaProvider } from "./monitor-BlnFXk24.js";
|
|
4
|
+
import { t as getVamaRuntime } from "./runtime-CQ9kld4S.js";
|
|
5
5
|
import { t as parseVamaConnectCode } from "./connect-code-Bbp9J6TH.js";
|
|
6
6
|
import { jsonResult, readStringOrNumberParam, readStringParam } from "openclaw/plugin-sdk/channel-actions";
|
|
7
7
|
import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as vamaPlugin } from "./channel-plugin-api-
|
|
1
|
+
import { t as vamaPlugin } from "./channel-plugin-api-Bi8Gs3E6.js";
|
|
2
2
|
export { vamaPlugin };
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { a as exchangeConnectCode } from "./client-BzhfASX8.js";
|
|
2
|
+
import { n as probeVama, o as resolveVamaAccount, t as clearProbeCache } from "./probe-COpuChEq.js";
|
|
3
|
+
import { t as getVamaRuntime } from "./runtime-CQ9kld4S.js";
|
|
4
|
+
import { t as parseVamaConnectCode } from "./connect-code-Bbp9J6TH.js";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
//#region extensions/vama/src/connect-verify.ts
|
|
9
|
+
/**
|
|
10
|
+
* Post-connect verification: make `openclaw vama connect` end with a TRUE
|
|
11
|
+
* statement about liveness instead of "credentials look right, good luck".
|
|
12
|
+
*
|
|
13
|
+
* Two halves:
|
|
14
|
+
* 1. ensureGatewayRunning — the gateway process is what actually holds the
|
|
15
|
+
* WebSocket to BotHub. If it isn't up, try `gateway start` (service
|
|
16
|
+
* installed but stopped), then `gateway install` (fresh machine —
|
|
17
|
+
* installs the launchd/systemd service, which auto-starts).
|
|
18
|
+
* 2. waitForWSConnected — poll BotHub's GET /v1/bot/me (bot-token auth)
|
|
19
|
+
* until `ws_connected` flips true, proving the gateway's socket arrived
|
|
20
|
+
* server-side. Raw fetch on purpose: the BotHub client logs every call,
|
|
21
|
+
* and a 1.5s poll loop would spam ~20 log lines into the summary.
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULT_GATEWAY_PORT = 18789;
|
|
24
|
+
function resolveGatewayPort(cfg) {
|
|
25
|
+
const port = cfg.gateway?.port;
|
|
26
|
+
return typeof port === "number" && Number.isInteger(port) && port > 0 ? port : DEFAULT_GATEWAY_PORT;
|
|
27
|
+
}
|
|
28
|
+
/** Any HTTP response (even an error status) proves something is listening. */
|
|
29
|
+
async function isGatewayUp(port, fetchImpl = fetch) {
|
|
30
|
+
try {
|
|
31
|
+
await fetchImpl(`http://127.0.0.1:${port}/`, {
|
|
32
|
+
method: "GET",
|
|
33
|
+
signal: AbortSignal.timeout(1500)
|
|
34
|
+
});
|
|
35
|
+
return true;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Invoke the host CLI's `gateway` subcommand. Plugins can't import gateway
|
|
42
|
+
* lifecycle internals, so we respawn the CLI we're running under: when
|
|
43
|
+
* process.argv[1] is a real script on disk (npm installs), reuse it with the
|
|
44
|
+
* current Node binary; otherwise (compiled single-binary builds) fall back
|
|
45
|
+
* to `openclaw` on PATH.
|
|
46
|
+
*/
|
|
47
|
+
const runGatewayCommand = (args) => {
|
|
48
|
+
const entry = process.argv[1];
|
|
49
|
+
const viaScript = Boolean(entry && fs.existsSync(entry));
|
|
50
|
+
const bin = viaScript ? process.execPath : "openclaw";
|
|
51
|
+
const argv = viaScript ? [
|
|
52
|
+
entry,
|
|
53
|
+
"gateway",
|
|
54
|
+
...args
|
|
55
|
+
] : ["gateway", ...args];
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
let output = "";
|
|
58
|
+
const child = spawn(bin, argv, {
|
|
59
|
+
stdio: [
|
|
60
|
+
"ignore",
|
|
61
|
+
"pipe",
|
|
62
|
+
"pipe"
|
|
63
|
+
],
|
|
64
|
+
env: process.env
|
|
65
|
+
});
|
|
66
|
+
const timer = setTimeout(() => {
|
|
67
|
+
child.kill("SIGTERM");
|
|
68
|
+
}, 6e4);
|
|
69
|
+
child.stdout?.on("data", (chunk) => {
|
|
70
|
+
output += chunk.toString();
|
|
71
|
+
});
|
|
72
|
+
child.stderr?.on("data", (chunk) => {
|
|
73
|
+
output += chunk.toString();
|
|
74
|
+
});
|
|
75
|
+
child.once("error", (err) => {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
resolve({
|
|
78
|
+
ok: false,
|
|
79
|
+
output: `${output}\n${err.message}`.trim()
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
child.once("close", (code) => {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
resolve({
|
|
85
|
+
ok: code === 0,
|
|
86
|
+
output: output.trim()
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
async function waitUntilUp(params) {
|
|
92
|
+
const deadline = Date.now() + params.timeoutMs;
|
|
93
|
+
while (Date.now() < deadline) {
|
|
94
|
+
if (await params.probe(params.port)) return true;
|
|
95
|
+
await params.sleep(750);
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
100
|
+
async function ensureGatewayRunning(params, deps = {}) {
|
|
101
|
+
const probe = deps.probe ?? isGatewayUp;
|
|
102
|
+
const runGateway = deps.runGateway ?? runGatewayCommand;
|
|
103
|
+
const sleep = deps.sleep ?? defaultSleep;
|
|
104
|
+
const log = params.log ?? (() => {});
|
|
105
|
+
if (await probe(params.port)) return {
|
|
106
|
+
action: "already-running",
|
|
107
|
+
up: true
|
|
108
|
+
};
|
|
109
|
+
log("Gateway not running — starting the service…");
|
|
110
|
+
const start = await runGateway(["start"]);
|
|
111
|
+
if (start.ok && await waitUntilUp({
|
|
112
|
+
port: params.port,
|
|
113
|
+
timeoutMs: 8e3,
|
|
114
|
+
probe,
|
|
115
|
+
sleep
|
|
116
|
+
})) return {
|
|
117
|
+
action: "started",
|
|
118
|
+
up: true
|
|
119
|
+
};
|
|
120
|
+
log("Gateway service not installed — installing it (auto-starts on login)…");
|
|
121
|
+
const install = await runGateway(["install"]);
|
|
122
|
+
if (install.ok && await waitUntilUp({
|
|
123
|
+
port: params.port,
|
|
124
|
+
timeoutMs: 12e3,
|
|
125
|
+
probe,
|
|
126
|
+
sleep
|
|
127
|
+
})) return {
|
|
128
|
+
action: "installed",
|
|
129
|
+
up: true
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
action: "failed",
|
|
133
|
+
up: false,
|
|
134
|
+
detail: (install.output || start.output).split("\n").slice(-4).join("\n").trim() || void 0
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Poll GET /v1/bot/me until `ws_connected` is true. "unsupported" means the
|
|
139
|
+
* server doesn't report the field yet (BotHub older than this feature) —
|
|
140
|
+
* callers should fall back to a non-committal message, not an error.
|
|
141
|
+
*/
|
|
142
|
+
async function waitForWSConnected(params, deps = {}) {
|
|
143
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
144
|
+
const sleep = deps.sleep ?? defaultSleep;
|
|
145
|
+
const baseUrl = params.bothubUrl.replace(/\/+$/, "");
|
|
146
|
+
const deadline = Date.now() + (params.timeoutMs ?? 3e4);
|
|
147
|
+
let lastError;
|
|
148
|
+
while (Date.now() < deadline) {
|
|
149
|
+
try {
|
|
150
|
+
const res = await fetchImpl(`${baseUrl}/v1/bot/me`, {
|
|
151
|
+
method: "GET",
|
|
152
|
+
headers: { Authorization: `Bot ${params.botToken}` },
|
|
153
|
+
signal: AbortSignal.timeout(5e3)
|
|
154
|
+
});
|
|
155
|
+
if (res.ok) {
|
|
156
|
+
const me = await res.json();
|
|
157
|
+
if (!("ws_connected" in me)) return { status: "unsupported" };
|
|
158
|
+
if (me.ws_connected === true) return { status: "live" };
|
|
159
|
+
lastError = void 0;
|
|
160
|
+
} else lastError = `GET /v1/bot/me returned ${res.status}`;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
lastError = err instanceof Error ? err.message : String(err);
|
|
163
|
+
}
|
|
164
|
+
await sleep(1500);
|
|
165
|
+
}
|
|
166
|
+
return lastError ? {
|
|
167
|
+
status: "error",
|
|
168
|
+
error: lastError
|
|
169
|
+
} : { status: "timeout" };
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region extensions/vama/src/cli.ts
|
|
173
|
+
/**
|
|
174
|
+
* Apply freshly exchanged credentials to the config. Default account writes
|
|
175
|
+
* top-level under channels.vama (matching the setup wizard); named accounts
|
|
176
|
+
* write under channels.vama.accounts.<id>. Existing unrelated keys
|
|
177
|
+
* (dmPolicy, webhookPort, …) are preserved.
|
|
178
|
+
*/
|
|
179
|
+
function applyVamaConnectCredentials(params) {
|
|
180
|
+
const { cfg, accountId } = params;
|
|
181
|
+
const vama = cfg.channels?.vama ?? {};
|
|
182
|
+
const credentialPatch = {
|
|
183
|
+
enabled: true,
|
|
184
|
+
botToken: params.botToken,
|
|
185
|
+
webhookSecret: params.webhookSecret
|
|
186
|
+
};
|
|
187
|
+
if (params.bothubUrl !== "https://bothub.vama.com") credentialPatch.bothubUrl = params.bothubUrl;
|
|
188
|
+
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
189
|
+
const next = {
|
|
190
|
+
...vama,
|
|
191
|
+
...credentialPatch
|
|
192
|
+
};
|
|
193
|
+
if (params.bothubUrl === "https://bothub.vama.com") delete next.bothubUrl;
|
|
194
|
+
return {
|
|
195
|
+
...cfg,
|
|
196
|
+
channels: {
|
|
197
|
+
...cfg.channels,
|
|
198
|
+
vama: {
|
|
199
|
+
...next,
|
|
200
|
+
enabled: true
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const nextAccount = {
|
|
206
|
+
...vama.accounts?.[accountId] ?? {},
|
|
207
|
+
...credentialPatch
|
|
208
|
+
};
|
|
209
|
+
if (params.bothubUrl === "https://bothub.vama.com") delete nextAccount.bothubUrl;
|
|
210
|
+
return {
|
|
211
|
+
...cfg,
|
|
212
|
+
channels: {
|
|
213
|
+
...cfg.channels,
|
|
214
|
+
vama: {
|
|
215
|
+
...vama,
|
|
216
|
+
enabled: true,
|
|
217
|
+
accounts: {
|
|
218
|
+
...vama.accounts,
|
|
219
|
+
[accountId]: nextAccount
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* `openclaw vama connect <code>` — the whole BYO onboarding in one command:
|
|
227
|
+
* exchange the code for credentials, write the config, verify with a live
|
|
228
|
+
* probe. WebSocket-enabled bots (the default for codes minted from Vama
|
|
229
|
+
* settings) need no tunnel, no public URL, no webhook registration.
|
|
230
|
+
*/
|
|
231
|
+
async function runVamaConnect(params, deps = {}) {
|
|
232
|
+
const exchange = deps.exchange ?? exchangeConnectCode;
|
|
233
|
+
const probe = deps.probe ?? probeVama;
|
|
234
|
+
const ensureGateway = deps.ensureGateway ?? ensureGatewayRunning;
|
|
235
|
+
const waitForLive = deps.waitForLive ?? waitForWSConnected;
|
|
236
|
+
const log = deps.log ?? ((msg) => console.log(msg));
|
|
237
|
+
const parsed = parseVamaConnectCode(params.rawCode);
|
|
238
|
+
const runtime = getVamaRuntime();
|
|
239
|
+
const cfg = runtime.config.current();
|
|
240
|
+
const accountId = normalizeAccountId(params.account?.trim() || DEFAULT_ACCOUNT_ID);
|
|
241
|
+
const existingUrl = (cfg.channels?.vama ?? {}).bothubUrl?.trim();
|
|
242
|
+
const bothubUrl = (params.bothubUrlFlag?.trim() || parsed.bothubUrl || existingUrl || "https://bothub.vama.com").replace(/\/+$/, "");
|
|
243
|
+
log(`Exchanging connect code with ${bothubUrl}…`);
|
|
244
|
+
const exchanged = await exchange({
|
|
245
|
+
bothubUrl,
|
|
246
|
+
code: parsed.code
|
|
247
|
+
});
|
|
248
|
+
const updated = applyVamaConnectCredentials({
|
|
249
|
+
cfg,
|
|
250
|
+
accountId,
|
|
251
|
+
botToken: exchanged.bot_token,
|
|
252
|
+
webhookSecret: exchanged.webhook_secret,
|
|
253
|
+
bothubUrl
|
|
254
|
+
});
|
|
255
|
+
await runtime.config.replaceConfigFile({
|
|
256
|
+
nextConfig: updated,
|
|
257
|
+
afterWrite: { mode: "auto" }
|
|
258
|
+
});
|
|
259
|
+
clearProbeCache();
|
|
260
|
+
const result = {
|
|
261
|
+
accountId,
|
|
262
|
+
botId: exchanged.bot_id,
|
|
263
|
+
username: exchanged.username,
|
|
264
|
+
displayName: exchanged.display_name,
|
|
265
|
+
websocketEnabled: exchanged.websocket_enabled === true,
|
|
266
|
+
bothubUrl,
|
|
267
|
+
created: exchanged.created
|
|
268
|
+
};
|
|
269
|
+
try {
|
|
270
|
+
const probed = await probe(resolveVamaAccount({
|
|
271
|
+
cfg: updated,
|
|
272
|
+
accountId
|
|
273
|
+
}));
|
|
274
|
+
result.probeOk = probed.ok;
|
|
275
|
+
if (!probed.ok) result.probeError = probed.error;
|
|
276
|
+
} catch (err) {
|
|
277
|
+
result.probeOk = false;
|
|
278
|
+
result.probeError = err instanceof Error ? err.message : String(err);
|
|
279
|
+
}
|
|
280
|
+
if (params.skipGateway) {
|
|
281
|
+
result.gatewayAction = "skipped";
|
|
282
|
+
result.liveCheck = "skipped";
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
const gateway = await ensureGateway({
|
|
286
|
+
port: resolveGatewayPort(updated),
|
|
287
|
+
log
|
|
288
|
+
});
|
|
289
|
+
result.gatewayAction = gateway.action;
|
|
290
|
+
if (gateway.detail) result.gatewayDetail = gateway.detail;
|
|
291
|
+
if (!gateway.up) {
|
|
292
|
+
result.live = false;
|
|
293
|
+
result.liveCheck = "skipped";
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
if (!result.websocketEnabled) {
|
|
297
|
+
result.liveCheck = "skipped";
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
log("Waiting for your agent to come online…");
|
|
301
|
+
const live = await waitForLive({
|
|
302
|
+
bothubUrl,
|
|
303
|
+
botToken: exchanged.bot_token
|
|
304
|
+
});
|
|
305
|
+
result.liveCheck = live.status;
|
|
306
|
+
result.live = live.status === "live";
|
|
307
|
+
if (live.error) result.liveError = live.error;
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
const GATEWAY_ACTION_LABEL = {
|
|
311
|
+
"already-running": "already running (config reloaded)",
|
|
312
|
+
started: "started",
|
|
313
|
+
installed: "installed as a service (auto-starts on login)",
|
|
314
|
+
failed: "could not be started automatically",
|
|
315
|
+
skipped: "left alone (--no-gateway)"
|
|
316
|
+
};
|
|
317
|
+
function printConnectResult(result) {
|
|
318
|
+
const botLabel = result.displayName || result.username || result.botId;
|
|
319
|
+
console.log("");
|
|
320
|
+
console.log(`✔ Credentials saved for ${botLabel}${result.username ? ` (@${result.username})` : ""}`);
|
|
321
|
+
if (result.websocketEnabled) console.log(" Transport: WebSocket — no tunnel or public URL needed.");
|
|
322
|
+
else console.log(" Transport: webhook — set channels.vama.webhookUrl to a public URL (or mint a new code from Vama settings to enable WebSocket).");
|
|
323
|
+
if (result.gatewayAction) console.log(` Gateway: ${GATEWAY_ACTION_LABEL[result.gatewayAction]}`);
|
|
324
|
+
if (result.probeOk === false && result.probeError) console.log(` Verification warning: ${result.probeError}`);
|
|
325
|
+
console.log("");
|
|
326
|
+
if (result.live) {
|
|
327
|
+
console.log("🎉 Your agent is LIVE — open Vama and say hi.");
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
switch (result.liveCheck) {
|
|
331
|
+
case "skipped":
|
|
332
|
+
if (result.gatewayAction === "failed") {
|
|
333
|
+
console.log("✖ NOT live yet — the gateway could not be started.");
|
|
334
|
+
if (result.gatewayDetail) console.log(` ${result.gatewayDetail.split("\n").join("\n ")}`);
|
|
335
|
+
console.log(" Start it yourself, then your agent connects with the saved credentials:");
|
|
336
|
+
console.log(" openclaw gateway install # background service (recommended)");
|
|
337
|
+
console.log(" openclaw gateway run # or foreground, for a quick test");
|
|
338
|
+
} else if (result.gatewayAction === "skipped") {
|
|
339
|
+
console.log("Gateway untouched (--no-gateway). Your agent goes live when it runs:");
|
|
340
|
+
console.log(" openclaw gateway run");
|
|
341
|
+
} else console.log("Gateway is up. Complete webhook setup to bring the agent online.");
|
|
342
|
+
return;
|
|
343
|
+
case "unsupported":
|
|
344
|
+
console.log("Gateway is up. (This BotHub doesn't report live status yet —");
|
|
345
|
+
console.log(" check the agent in Vama: it should be online now.)");
|
|
346
|
+
return;
|
|
347
|
+
default:
|
|
348
|
+
console.log("⚠ NOT live yet — gateway is up but BotHub hasn't seen its connection.");
|
|
349
|
+
if (result.liveError) console.log(` Last error: ${result.liveError}`);
|
|
350
|
+
console.log(" It may just be slow. Check again with: openclaw channels status --probe");
|
|
351
|
+
console.log(" Gateway logs: openclaw gateway status");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function registerVamaCli({ program }) {
|
|
356
|
+
program.command("vama").description("Vama channel tools (connect codes, account state)").command("connect").description("Connect this OpenClaw to Vama with a one-time code from Vama settings (Settings → AI Agents)").argument("<code>", "connect code (vmc1_… token or 64-char hex)").option("--bothub-url <url>", "BotHub endpoint override (defaults to the URL embedded in the code)").option("--account <id>", "Vama account id to write credentials to", DEFAULT_ACCOUNT_ID).option("--json", "print the result as JSON", false).option("--no-gateway", "save credentials only; don't start/install the gateway").action(async (code, opts) => {
|
|
357
|
+
try {
|
|
358
|
+
const result = await runVamaConnect({
|
|
359
|
+
rawCode: code,
|
|
360
|
+
bothubUrlFlag: opts.bothubUrl,
|
|
361
|
+
account: opts.account,
|
|
362
|
+
skipGateway: opts.gateway === false
|
|
363
|
+
}, { log: opts.json ? () => {} : void 0 });
|
|
364
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
365
|
+
else printConnectResult(result);
|
|
366
|
+
} catch (err) {
|
|
367
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
368
|
+
if (opts.json) console.log(JSON.stringify({
|
|
369
|
+
ok: false,
|
|
370
|
+
error: message
|
|
371
|
+
}, null, 2));
|
|
372
|
+
else console.error(`✖ Connect failed: ${message}`);
|
|
373
|
+
process.exitCode = 1;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
378
|
+
export { registerVamaCli };
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as
|
|
3
|
-
import { n as
|
|
4
|
-
import {
|
|
5
|
-
import { t as vamaPlugin } from "./channel-plugin-api-
|
|
1
|
+
import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-CBt1Mjce.js";
|
|
2
|
+
import { n as probeVama } from "./probe-COpuChEq.js";
|
|
3
|
+
import { n as sendMessageVama, t as monitorVamaProvider } from "./monitor-BlnFXk24.js";
|
|
4
|
+
import { n as setVamaRuntime } from "./runtime-CQ9kld4S.js";
|
|
5
|
+
import { t as vamaPlugin } from "./channel-plugin-api-Bi8Gs3E6.js";
|
|
6
6
|
import "./runtime-api.js";
|
|
7
|
-
//#region extensions/vama/src/cli-metadata.ts
|
|
8
|
-
function registerVamaCliMetadata(api) {
|
|
9
|
-
api.registerCli(async ({ program }) => {
|
|
10
|
-
const { registerVamaCli } = await import("./cli-F0a1J9Rj.js");
|
|
11
|
-
registerVamaCli({ program });
|
|
12
|
-
}, { descriptors: [{
|
|
13
|
-
name: "vama",
|
|
14
|
-
description: "Connect this OpenClaw to Vama and manage the Vama channel",
|
|
15
|
-
hasSubcommands: true
|
|
16
|
-
}] });
|
|
17
|
-
}
|
|
18
|
-
//#endregion
|
|
19
7
|
//#region extensions/vama/index.ts
|
|
20
8
|
const channelEntry = {
|
|
21
9
|
kind: "bundled-channel-entry",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as createBotHubClient, n as attachmentHintFromExtension } from "./client-BzhfASX8.js";
|
|
2
|
-
import { o as resolveVamaAccount, r as startVamaWebSocket, t as clearProbeCache } from "./probe-
|
|
3
|
-
import { t as getVamaRuntime } from "./runtime-
|
|
4
|
-
import * as fs from "node:fs";
|
|
2
|
+
import { o as resolveVamaAccount, r as startVamaWebSocket, t as clearProbeCache } from "./probe-COpuChEq.js";
|
|
3
|
+
import { t as getVamaRuntime } from "./runtime-CQ9kld4S.js";
|
|
4
|
+
import * as fs$1 from "node:fs";
|
|
5
5
|
import { promises } from "node:fs";
|
|
6
6
|
import * as http from "node:http";
|
|
7
7
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
@@ -125,10 +125,10 @@ function loadFcEnv() {
|
|
|
125
125
|
if (envCacheLoaded) return;
|
|
126
126
|
envCacheLoaded = true;
|
|
127
127
|
try {
|
|
128
|
-
cachedVmName = fs.readFileSync("/etc/openclaw/vm-name", "utf8").trim() || void 0;
|
|
128
|
+
cachedVmName = fs$1.readFileSync("/etc/openclaw/vm-name", "utf8").trim() || void 0;
|
|
129
129
|
} catch {}
|
|
130
130
|
try {
|
|
131
|
-
const m = fs.readFileSync("/etc/vmctl.env", "utf8").match(/FC_AUTH_TOKEN=["']?([^"'\n]+)/);
|
|
131
|
+
const m = fs$1.readFileSync("/etc/vmctl.env", "utf8").match(/FC_AUTH_TOKEN=["']?([^"'\n]+)/);
|
|
132
132
|
if (m) cachedAuthToken = m[1];
|
|
133
133
|
} catch {
|
|
134
134
|
if (process.env.FC_AUTH_TOKEN) cachedAuthToken = process.env.FC_AUTH_TOKEN;
|
|
@@ -756,7 +756,7 @@ const SECRET_CACHE = /* @__PURE__ */ new Map();
|
|
|
756
756
|
function readSecretFromFile(path, log) {
|
|
757
757
|
let stat;
|
|
758
758
|
try {
|
|
759
|
-
stat = fs.statSync(path);
|
|
759
|
+
stat = fs$1.statSync(path);
|
|
760
760
|
} catch (e) {
|
|
761
761
|
log(`vama: webhookSecretFile stat failed (${path}): ${e instanceof Error ? e.message : String(e)}`);
|
|
762
762
|
return;
|
|
@@ -765,7 +765,7 @@ function readSecretFromFile(path, log) {
|
|
|
765
765
|
if (cached && cached.mtimeMs === stat.mtimeMs && cached.sizeBytes === stat.size) return cached.secret;
|
|
766
766
|
let raw;
|
|
767
767
|
try {
|
|
768
|
-
raw = fs.readFileSync(path, "utf8");
|
|
768
|
+
raw = fs$1.readFileSync(path, "utf8");
|
|
769
769
|
} catch (e) {
|
|
770
770
|
log(`vama: webhookSecretFile read failed (${path}): ${e instanceof Error ? e.message : String(e)}`);
|
|
771
771
|
return;
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as setVamaRuntime } from "./runtime-
|
|
1
|
+
import { n as setVamaRuntime } from "./runtime-CQ9kld4S.js";
|
|
2
2
|
export { setVamaRuntime };
|
package/package.json
CHANGED
package/dist/api-DftFHS2s.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import "./probe-Cf1xor23.js";
|
|
2
|
-
import { i as dispatchStarted, r as dispatchEnded } from "./monitor-DLgOtdLQ.js";
|
|
3
|
-
//#region extensions/vama/src/subagent-keepalive-hooks.ts
|
|
4
|
-
function registerVamaSubagentKeepaliveHooks(api) {
|
|
5
|
-
api.on("subagent_spawned", () => {
|
|
6
|
-
dispatchStarted();
|
|
7
|
-
});
|
|
8
|
-
api.on("subagent_ended", () => {
|
|
9
|
-
dispatchEnded();
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
//#endregion
|
|
13
|
-
export { registerVamaSubagentKeepaliveHooks as t };
|
package/dist/cli-F0a1J9Rj.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { a as exchangeConnectCode } from "./client-BzhfASX8.js";
|
|
2
|
-
import { n as probeVama, o as resolveVamaAccount, t as clearProbeCache } from "./probe-Cf1xor23.js";
|
|
3
|
-
import { t as getVamaRuntime } from "./runtime-Cq09Y5cd.js";
|
|
4
|
-
import { t as parseVamaConnectCode } from "./connect-code-Bbp9J6TH.js";
|
|
5
|
-
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
6
|
-
//#region extensions/vama/src/cli.ts
|
|
7
|
-
/**
|
|
8
|
-
* Apply freshly exchanged credentials to the config. Default account writes
|
|
9
|
-
* top-level under channels.vama (matching the setup wizard); named accounts
|
|
10
|
-
* write under channels.vama.accounts.<id>. Existing unrelated keys
|
|
11
|
-
* (dmPolicy, webhookPort, …) are preserved.
|
|
12
|
-
*/
|
|
13
|
-
function applyVamaConnectCredentials(params) {
|
|
14
|
-
const { cfg, accountId } = params;
|
|
15
|
-
const vama = cfg.channels?.vama ?? {};
|
|
16
|
-
const credentialPatch = {
|
|
17
|
-
enabled: true,
|
|
18
|
-
botToken: params.botToken,
|
|
19
|
-
webhookSecret: params.webhookSecret
|
|
20
|
-
};
|
|
21
|
-
if (params.bothubUrl !== "https://bothub.vama.com") credentialPatch.bothubUrl = params.bothubUrl;
|
|
22
|
-
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
23
|
-
const next = {
|
|
24
|
-
...vama,
|
|
25
|
-
...credentialPatch
|
|
26
|
-
};
|
|
27
|
-
if (params.bothubUrl === "https://bothub.vama.com") delete next.bothubUrl;
|
|
28
|
-
return {
|
|
29
|
-
...cfg,
|
|
30
|
-
channels: {
|
|
31
|
-
...cfg.channels,
|
|
32
|
-
vama: {
|
|
33
|
-
...next,
|
|
34
|
-
enabled: true
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
const nextAccount = {
|
|
40
|
-
...vama.accounts?.[accountId] ?? {},
|
|
41
|
-
...credentialPatch
|
|
42
|
-
};
|
|
43
|
-
if (params.bothubUrl === "https://bothub.vama.com") delete nextAccount.bothubUrl;
|
|
44
|
-
return {
|
|
45
|
-
...cfg,
|
|
46
|
-
channels: {
|
|
47
|
-
...cfg.channels,
|
|
48
|
-
vama: {
|
|
49
|
-
...vama,
|
|
50
|
-
enabled: true,
|
|
51
|
-
accounts: {
|
|
52
|
-
...vama.accounts,
|
|
53
|
-
[accountId]: nextAccount
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* `openclaw vama connect <code>` — the whole BYO onboarding in one command:
|
|
61
|
-
* exchange the code for credentials, write the config, verify with a live
|
|
62
|
-
* probe. WebSocket-enabled bots (the default for codes minted from Vama
|
|
63
|
-
* settings) need no tunnel, no public URL, no webhook registration.
|
|
64
|
-
*/
|
|
65
|
-
async function runVamaConnect(params, deps = {}) {
|
|
66
|
-
const exchange = deps.exchange ?? exchangeConnectCode;
|
|
67
|
-
const probe = deps.probe ?? probeVama;
|
|
68
|
-
const log = deps.log ?? ((msg) => console.log(msg));
|
|
69
|
-
const parsed = parseVamaConnectCode(params.rawCode);
|
|
70
|
-
const runtime = getVamaRuntime();
|
|
71
|
-
const cfg = runtime.config.current();
|
|
72
|
-
const accountId = normalizeAccountId(params.account?.trim() || DEFAULT_ACCOUNT_ID);
|
|
73
|
-
const existingUrl = (cfg.channels?.vama ?? {}).bothubUrl?.trim();
|
|
74
|
-
const bothubUrl = (params.bothubUrlFlag?.trim() || parsed.bothubUrl || existingUrl || "https://bothub.vama.com").replace(/\/+$/, "");
|
|
75
|
-
log(`Exchanging connect code with ${bothubUrl}…`);
|
|
76
|
-
const exchanged = await exchange({
|
|
77
|
-
bothubUrl,
|
|
78
|
-
code: parsed.code
|
|
79
|
-
});
|
|
80
|
-
const updated = applyVamaConnectCredentials({
|
|
81
|
-
cfg,
|
|
82
|
-
accountId,
|
|
83
|
-
botToken: exchanged.bot_token,
|
|
84
|
-
webhookSecret: exchanged.webhook_secret,
|
|
85
|
-
bothubUrl
|
|
86
|
-
});
|
|
87
|
-
await runtime.config.replaceConfigFile({
|
|
88
|
-
nextConfig: updated,
|
|
89
|
-
afterWrite: { mode: "auto" }
|
|
90
|
-
});
|
|
91
|
-
clearProbeCache();
|
|
92
|
-
const result = {
|
|
93
|
-
accountId,
|
|
94
|
-
botId: exchanged.bot_id,
|
|
95
|
-
username: exchanged.username,
|
|
96
|
-
displayName: exchanged.display_name,
|
|
97
|
-
websocketEnabled: exchanged.websocket_enabled === true,
|
|
98
|
-
bothubUrl,
|
|
99
|
-
created: exchanged.created
|
|
100
|
-
};
|
|
101
|
-
try {
|
|
102
|
-
const probed = await probe(resolveVamaAccount({
|
|
103
|
-
cfg: updated,
|
|
104
|
-
accountId
|
|
105
|
-
}));
|
|
106
|
-
result.probeOk = probed.ok;
|
|
107
|
-
if (!probed.ok) result.probeError = probed.error;
|
|
108
|
-
} catch (err) {
|
|
109
|
-
result.probeOk = false;
|
|
110
|
-
result.probeError = err instanceof Error ? err.message : String(err);
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
function printConnectResult(result) {
|
|
115
|
-
const botLabel = result.displayName || result.username || result.botId;
|
|
116
|
-
console.log("");
|
|
117
|
-
console.log(`✔ Connected to Vama as ${botLabel}${result.username ? ` (@${result.username})` : ""}`);
|
|
118
|
-
if (result.websocketEnabled) console.log(" Transport: WebSocket — no tunnel or public URL needed.");
|
|
119
|
-
else console.log(" Transport: webhook — set channels.vama.webhookUrl to a public URL (or mint a new code from Vama settings to enable WebSocket).");
|
|
120
|
-
if (result.probeOk === false && result.probeError) {
|
|
121
|
-
console.log(` Verification warning: ${result.probeError}`);
|
|
122
|
-
console.log(" Re-check later with: openclaw channels status --probe");
|
|
123
|
-
}
|
|
124
|
-
console.log("");
|
|
125
|
-
console.log(" If your gateway is running it reloads automatically; otherwise start it:");
|
|
126
|
-
console.log(" openclaw gateway");
|
|
127
|
-
}
|
|
128
|
-
function registerVamaCli({ program }) {
|
|
129
|
-
program.command("vama").description("Vama channel tools (connect codes, account state)").command("connect").description("Connect this OpenClaw to Vama with a one-time code from Vama settings (Settings → AI Agents)").argument("<code>", "connect code (vmc1_… token or 64-char hex)").option("--bothub-url <url>", "BotHub endpoint override (defaults to the URL embedded in the code)").option("--account <id>", "Vama account id to write credentials to", DEFAULT_ACCOUNT_ID).option("--json", "print the result as JSON", false).action(async (code, opts) => {
|
|
130
|
-
try {
|
|
131
|
-
const result = await runVamaConnect({
|
|
132
|
-
rawCode: code,
|
|
133
|
-
bothubUrlFlag: opts.bothubUrl,
|
|
134
|
-
account: opts.account
|
|
135
|
-
}, { log: opts.json ? () => {} : void 0 });
|
|
136
|
-
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
137
|
-
else printConnectResult(result);
|
|
138
|
-
} catch (err) {
|
|
139
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
140
|
-
if (opts.json) console.log(JSON.stringify({
|
|
141
|
-
ok: false,
|
|
142
|
-
error: message
|
|
143
|
-
}, null, 2));
|
|
144
|
-
else console.error(`✖ Connect failed: ${message}`);
|
|
145
|
-
process.exitCode = 1;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
//#endregion
|
|
150
|
-
export { registerVamaCli };
|
|
File without changes
|
|
File without changes
|