@@ -717,6 +717,102 @@ for channel in "${!SETUP_ENTRY_DEP_SENTINELS[@]}"; do
717717 fi
718718done
719719
720+ echo "Running packaged guided WhatsApp setup; runtime deps should be staged before finalize..."
721+ OPENCLAW_PACKAGE_ROOT="$root" node --input-type=module - <<'NODE'
722+ import path from "node:path";
723+ import { readdir } from "node:fs/promises";
724+ import { pathToFileURL } from "node:url";
725+
726+ const root = process.env.OPENCLAW_PACKAGE_ROOT;
727+ if (!root) {
728+ throw new Error("missing OPENCLAW_PACKAGE_ROOT");
729+ }
730+ const distDir = path.join(root, "dist");
731+ const onboardChannelFiles = (await readdir(distDir))
732+ .filter((entry) => /^onboard-channels-.*\.js$/.test(entry))
733+ .sort();
734+ let setupChannels;
735+ for (const entry of onboardChannelFiles) {
736+ const module = await import(pathToFileURL(path.join(distDir, entry)));
737+ if (typeof module.setupChannels === "function") {
738+ setupChannels = module.setupChannels;
739+ break;
740+ }
741+ }
742+ if (!setupChannels) {
743+ throw new Error(
744+ `could not find packaged setupChannels export in ${JSON.stringify(onboardChannelFiles)}`,
745+ );
746+ }
747+
748+ let channelSelectCount = 0;
749+ const notes = [];
750+ const prompter = {
751+ intro: async () => {},
752+ outro: async () => {},
753+ note: async (body, title) => {
754+ notes.push({ title, body });
755+ },
756+ confirm: async ({ message, initialValue }) => {
757+ if (message === "Link WhatsApp now (QR)?") {
758+ return false;
759+ }
760+ return initialValue ?? true;
761+ },
762+ select: async ({ message }) => {
763+ if (message === "Select a channel") {
764+ channelSelectCount += 1;
765+ return channelSelectCount === 1 ? "whatsapp" : "__done__";
766+ }
767+ if (message === "WhatsApp phone setup") {
768+ return "separate";
769+ }
770+ if (message === "WhatsApp DM policy") {
771+ return "disabled";
772+ }
773+ throw new Error(`unexpected select prompt: ${message}`);
774+ },
775+ multiselect: async ({ message }) => {
776+ throw new Error(`unexpected multiselect prompt: ${message}`);
777+ },
778+ text: async ({ message }) => {
779+ throw new Error(`unexpected text prompt: ${message}`);
780+ },
781+ };
782+ const runtime = {
783+ log: (message) => console.log(message),
784+ error: (message) => console.error(message),
785+ };
786+
787+ const result = await setupChannels(
788+ { plugins: { enabled: true } },
789+ runtime,
790+ prompter,
791+ {
792+ deferStatusUntilSelection: true,
793+ skipConfirm: true,
794+ skipStatusNote: true,
795+ skipDmPolicyPrompt: true,
796+ initialSelection: ["whatsapp"],
797+ },
798+ );
799+
800+ if (!result.channels?.whatsapp) {
801+ throw new Error(`WhatsApp setup did not write channel config: ${JSON.stringify(result)}`);
802+ }
803+ console.log("packaged guided WhatsApp setup completed");
804+ NODE
805+
806+ if [ -e "$root/dist/extensions/whatsapp/node_modules/@whiskeysockets/baileys/package.json" ]; then
807+ echo "expected guided WhatsApp setup deps to be installed externally, not into bundled plugin tree" >&2
808+ exit 1
809+ fi
810+ if ! find "$OPENCLAW_PLUGIN_STAGE_DIR" -maxdepth 12 -path "*/node_modules/@whiskeysockets/baileys/package.json" -type f | grep -q .; then
811+ echo "guided WhatsApp setup did not stage @whiskeysockets/baileys before finalize" >&2
812+ find "$OPENCLAW_PLUGIN_STAGE_DIR" -maxdepth 12 -type f | sort | head -160 >&2 || true
813+ exit 1
814+ fi
815+
720816echo "Configuring setup-entry channels; doctor should now install bundled runtime deps externally..."
721817node - <<'NODE'
722818const fs = require("node:fs");
0 commit comments