@chrysb/alphaclaw 0.9.6 → 0.9.8

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 (31) hide show
  1. package/README.md +3 -2
  2. package/lib/public/assets/icons/whatsapp.svg +14 -0
  3. package/lib/public/css/tailwind.generated.css +1 -1
  4. package/lib/public/dist/app.bundle.js +2031 -1925
  5. package/lib/public/js/components/agents-tab/create-channel-modal.js +30 -13
  6. package/lib/public/js/components/channel-login-modal.js +82 -0
  7. package/lib/public/js/components/channels.js +347 -1
  8. package/lib/public/js/components/general/index.js +56 -8
  9. package/lib/public/js/components/modal-shell.js +18 -2
  10. package/lib/public/js/components/onboarding/welcome-pairing-step.js +11 -6
  11. package/lib/public/js/components/pairings.js +1 -1
  12. package/lib/public/js/components/welcome/index.js +0 -1
  13. package/lib/public/js/components/welcome/use-welcome.js +1 -1
  14. package/lib/public/js/lib/api.js +23 -0
  15. package/lib/public/js/lib/channel-provider-availability.js +1 -1
  16. package/lib/server/agents/channels.js +268 -4
  17. package/lib/server/agents/service.js +2 -0
  18. package/lib/server/agents/shared.js +133 -42
  19. package/lib/server/alphaclaw-version.js +7 -3
  20. package/lib/server/commands.js +5 -1
  21. package/lib/server/constants.js +7 -0
  22. package/lib/server/gateway.js +61 -18
  23. package/lib/server/onboarding/import/import-applier.js +25 -4
  24. package/lib/server/onboarding/import/secret-detector.js +9 -0
  25. package/lib/server/onboarding/openclaw.js +39 -0
  26. package/lib/server/onboarding/validation.js +1 -1
  27. package/lib/server/routes/agents.js +39 -0
  28. package/lib/server/routes/pairings.js +2 -2
  29. package/lib/server/watchdog-notify.js +54 -13
  30. package/lib/server.js +1 -0
  31. package/package.json +1 -1
@@ -2,8 +2,10 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const { OPENCLAW_DIR } = require("./constants");
4
4
  const { createSlackApi } = require("./slack-api");
5
+ const { quoteShellArg } = require("./utils/shell");
5
6
 
6
7
  const kSlackBotEnvKey = "SLACK_BOT_TOKEN";
8
+ const kWhatsAppOwnerNumberEnvKey = "WHATSAPP_OWNER_NUMBER";
7
9
 
8
10
  const normalizeAccountId = (value) =>
9
11
  String(value || "").trim().toLowerCase() || "default";
@@ -106,6 +108,7 @@ const createWatchdogNotifier = ({
106
108
  telegramApi,
107
109
  discordApi,
108
110
  slackApi,
111
+ clawCmd = null,
109
112
  readEnvFile = () => [],
110
113
  createSlackApi: createSlackApiFactory = createSlackApi,
111
114
  fsImpl = fs,
@@ -116,7 +119,17 @@ const createWatchdogNotifier = ({
116
119
  telegram: { sent: 0, failed: 0, skipped: false, targets: 0 },
117
120
  discord: { sent: 0, failed: 0, skipped: false, targets: 0 },
118
121
  slack: { sent: 0, failed: 0, skipped: false, targets: 0 },
122
+ whatsapp: { sent: 0, failed: 0, skipped: false, targets: 0 },
119
123
  };
124
+ const envVars = typeof readEnvFile === "function" ? readEnvFile() : [];
125
+ const envMap = new Map(
126
+ (Array.isArray(envVars) ? envVars : [])
127
+ .map((entry) => [
128
+ String(entry?.key || "").trim(),
129
+ String(entry?.value || "").trim(),
130
+ ])
131
+ .filter(([key]) => key),
132
+ );
120
133
  const telegramTargets = getPairedIds({
121
134
  channel: "telegram",
122
135
  fsImpl,
@@ -174,17 +187,6 @@ const createWatchdogNotifier = ({
174
187
  summary.slack.skipped = true;
175
188
  } else {
176
189
  const eventType = opts.eventType || "info"; // crash, recovery, health, info
177
- const envVars = typeof readEnvFile === "function" ? readEnvFile() : [];
178
-
179
- const envMap = new Map(
180
- (Array.isArray(envVars) ? envVars : [])
181
- .map((entry) => [
182
- String(entry?.key || "").trim(),
183
- String(entry?.value || "").trim(),
184
- ])
185
- .filter(([key]) => key),
186
- );
187
-
188
190
  for (const [accountId, slackTargets] of slackTargetsByAccount.entries()) {
189
191
  if (!slackTargets.length) continue;
190
192
  const envKey = deriveSlackBotEnvKey(accountId);
@@ -261,8 +263,47 @@ const createWatchdogNotifier = ({
261
263
  }
262
264
  }
263
265
 
264
- const sent = summary.telegram.sent + summary.discord.sent + summary.slack.sent;
265
- const failed = summary.telegram.failed + summary.discord.failed + summary.slack.failed;
266
+ const whatsAppOwnerNumber = String(
267
+ envMap.get(kWhatsAppOwnerNumberEnvKey) ||
268
+ process.env[kWhatsAppOwnerNumberEnvKey] ||
269
+ "",
270
+ ).trim();
271
+ const whatsappTargets = whatsAppOwnerNumber ? [whatsAppOwnerNumber] : [];
272
+ summary.whatsapp.targets = whatsappTargets.length;
273
+ if (!clawCmd || whatsappTargets.length === 0) {
274
+ summary.whatsapp.skipped = true;
275
+ } else {
276
+ for (const target of whatsappTargets) {
277
+ try {
278
+ const result = await clawCmd(
279
+ `message send --channel whatsapp --target ${quoteShellArg(
280
+ String(target || "").trim(),
281
+ )} --message ${quoteShellArg(String(message || ""))}`,
282
+ { quiet: true, timeoutMs: 30000 },
283
+ );
284
+ if (!result?.ok) {
285
+ throw new Error(
286
+ String(result?.stderr || result?.stdout || "WhatsApp send failed"),
287
+ );
288
+ }
289
+ summary.whatsapp.sent += 1;
290
+ } catch (err) {
291
+ summary.whatsapp.failed += 1;
292
+ console.error(`[watchdog] whatsapp notification failed for ${target}: ${err.message}`);
293
+ }
294
+ }
295
+ }
296
+
297
+ const sent =
298
+ summary.telegram.sent +
299
+ summary.discord.sent +
300
+ summary.slack.sent +
301
+ summary.whatsapp.sent;
302
+ const failed =
303
+ summary.telegram.failed +
304
+ summary.discord.failed +
305
+ summary.slack.failed +
306
+ summary.whatsapp.failed;
266
307
  return {
267
308
  ok: sent > 0,
268
309
  sent,
package/lib/server.js CHANGED
@@ -232,6 +232,7 @@ const watchdogNotifier = createWatchdogNotifier({
232
232
  telegramApi,
233
233
  discordApi,
234
234
  slackApi,
235
+ clawCmd,
235
236
  readEnvFile,
236
237
  });
237
238
  const watchdog = createWatchdog({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrysb/alphaclaw",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },