From dadf258136b7a8c851681c4e632bfb976fac2e04 Mon Sep 17 00:00:00 2001 From: Koshkoshinsk Date: Mon, 20 Apr 2026 15:33:56 +0000 Subject: [PATCH] feat(new-setup-2): add per-channel bundled install scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twelve idempotent install scripts matching install-telegram.sh's shape, one per channel in /new-setup-2's pick list (except Emacs, which uses a git-merge install flow). Each bundles preflight + fetch + copy + register + pnpm install + build so a single allowlisted bash call can replace a chain of permission prompts. Linear's also patches chat-sdk-bridge.ts for catchAll forwarding; Matrix's runs the post-install ESM-extension dist patch; WhatsApp-native's covers the deterministic install portion only — QR/pairing auth still lives in /add-whatsapp. Scripts only; new-setup-2/SKILL.md integration deferred pending a decision on whether to generalize the set-env pattern from 712a0e1 across the Chat SDK channels (each /add-/SKILL.md's Credentials section has a similar unapprovable shell chain). Co-Authored-By: Claude Opus 4.7 (1M context) --- setup/install-discord.sh | 46 ++++++++++++++++ setup/install-gchat.sh | 46 ++++++++++++++++ setup/install-github.sh | 46 ++++++++++++++++ setup/install-imessage.sh | 47 ++++++++++++++++ setup/install-linear.sh | 95 +++++++++++++++++++++++++++++++++ setup/install-matrix.sh | 62 +++++++++++++++++++++ setup/install-resend.sh | 46 ++++++++++++++++ setup/install-slack.sh | 46 ++++++++++++++++ setup/install-teams.sh | 46 ++++++++++++++++ setup/install-webex.sh | 46 ++++++++++++++++ setup/install-whatsapp-cloud.sh | 46 ++++++++++++++++ setup/install-whatsapp.sh | 75 ++++++++++++++++++++++++++ 12 files changed, 647 insertions(+) create mode 100755 setup/install-discord.sh create mode 100755 setup/install-gchat.sh create mode 100755 setup/install-github.sh create mode 100755 setup/install-imessage.sh create mode 100755 setup/install-linear.sh create mode 100755 setup/install-matrix.sh create mode 100755 setup/install-resend.sh create mode 100755 setup/install-slack.sh create mode 100755 setup/install-teams.sh create mode 100755 setup/install-webex.sh create mode 100755 setup/install-whatsapp-cloud.sh create mode 100755 setup/install-whatsapp.sh diff --git a/setup/install-discord.sh b/setup/install-discord.sh new file mode 100755 index 000000000..ee221f910 --- /dev/null +++ b/setup/install-discord.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-discord — bundles the preflight + install commands +# from the /add-discord skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Discord adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/discord package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_DISCORD ===" + +needs_install=false +[[ -f src/channels/discord.ts ]] || needs_install=true +grep -q "import './discord.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/discord"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/discord ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/discord.ts > src/channels/discord.ts + +echo "STEP: register-import" +if ! grep -q "import './discord.js';" src/channels/index.ts; then + printf "import './discord.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/discord@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-gchat.sh b/setup/install-gchat.sh new file mode 100755 index 000000000..f5c210b57 --- /dev/null +++ b/setup/install-gchat.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-gchat — bundles the preflight + install commands +# from the /add-gchat skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Google Chat adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/gchat package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_GCHAT ===" + +needs_install=false +[[ -f src/channels/gchat.ts ]] || needs_install=true +grep -q "import './gchat.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/gchat"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/gchat ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/gchat.ts > src/channels/gchat.ts + +echo "STEP: register-import" +if ! grep -q "import './gchat.js';" src/channels/index.ts; then + printf "import './gchat.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/gchat@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-github.sh b/setup/install-github.sh new file mode 100755 index 000000000..81c2977e8 --- /dev/null +++ b/setup/install-github.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-github — bundles the preflight + install commands +# from the /add-github skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the GitHub adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/github package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_GITHUB ===" + +needs_install=false +[[ -f src/channels/github.ts ]] || needs_install=true +grep -q "import './github.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/github"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/github ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/github.ts > src/channels/github.ts + +echo "STEP: register-import" +if ! grep -q "import './github.js';" src/channels/index.ts; then + printf "import './github.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/github@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-imessage.sh b/setup/install-imessage.sh new file mode 100755 index 000000000..0b1df3467 --- /dev/null +++ b/setup/install-imessage.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Setup helper: install-imessage — bundles the preflight + install commands +# from the /add-imessage skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the iMessage adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned chat-adapter-imessage package; +# builds. Local vs remote mode pick stays in the skill — this script only +# handles the deterministic install. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_IMESSAGE ===" + +needs_install=false +[[ -f src/channels/imessage.ts ]] || needs_install=true +grep -q "import './imessage.js';" src/channels/index.ts || needs_install=true +grep -q '"chat-adapter-imessage"' package.json || needs_install=true +[[ -d node_modules/chat-adapter-imessage ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/imessage.ts > src/channels/imessage.ts + +echo "STEP: register-import" +if ! grep -q "import './imessage.js';" src/channels/index.ts; then + printf "import './imessage.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install chat-adapter-imessage@0.1.1 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-linear.sh b/setup/install-linear.sh new file mode 100755 index 000000000..9f42bec54 --- /dev/null +++ b/setup/install-linear.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# Setup helper: install-linear — bundles the preflight + install commands +# from the /add-linear skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Linear adapter in from the `channels` branch; appends the +# self-registration import; patches src/channels/chat-sdk-bridge.ts to add +# catch-all forwarding (Linear OAuth apps can't be @-mentioned, so the +# onNewMention handler never fires — the bridge needs a catchAll path); +# installs the pinned @chat-adapter/linear package; builds. All steps are +# safe to re-run. +# +# Note: the bridge patch's onNewMessage handler passes `false` for isMention +# (current trunk signature requires the arg). The /add-linear SKILL's +# snippet omits the arg — this script uses the full signature so TypeScript +# builds cleanly. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_LINEAR ===" + +needs_install=false +[[ -f src/channels/linear.ts ]] || needs_install=true +grep -q "import './linear.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/linear"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/linear ]] || needs_install=true +grep -q 'catchAll' src/channels/chat-sdk-bridge.ts || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/linear.ts > src/channels/linear.ts + +echo "STEP: register-import" +if ! grep -q "import './linear.js';" src/channels/index.ts; then + printf "import './linear.js';\n" >> src/channels/index.ts +fi + +echo "STEP: patch-bridge-catchall-field" +if ! grep -q 'catchAll?: boolean;' src/channels/chat-sdk-bridge.ts; then + awk ' + /^export interface ChatSdkBridgeConfig \{/ { in_iface = 1 } + in_iface && /^\}/ && !inserted { + print " /**" + print " * Forward ALL messages in unsubscribed threads, not just @-mentions." + print " * Use for platforms where the bot identity can'\''t be @-mentioned (e.g." + print " * Linear OAuth apps). The thread is auto-subscribed on first message." + print " */" + print " catchAll?: boolean;" + inserted = 1 + in_iface = 0 + } + { print } + ' src/channels/chat-sdk-bridge.ts > src/channels/chat-sdk-bridge.ts.tmp \ + && mv src/channels/chat-sdk-bridge.ts.tmp src/channels/chat-sdk-bridge.ts +fi + +echo "STEP: patch-bridge-catchall-handler" +if ! grep -q 'if (config.catchAll) {' src/channels/chat-sdk-bridge.ts; then + awk ' + / \/\/ DMs — apply engage rules too/ && !inserted { + print " // Catch-all for platforms where @-mention isn'\''t possible (e.g. Linear" + print " // OAuth apps). Forward every unsubscribed message and auto-subscribe." + print " if (config.catchAll) {" + print " chat.onNewMessage(/.*/, async (thread, message) => {" + print " const channelId = adapter.channelIdFromThreadId(thread.id);" + print " await setupConfig.onInbound(channelId, thread.id, await messageToInbound(message, false));" + print " await thread.subscribe();" + print " });" + print " }" + print "" + inserted = 1 + } + { print } + ' src/channels/chat-sdk-bridge.ts > src/channels/chat-sdk-bridge.ts.tmp \ + && mv src/channels/chat-sdk-bridge.ts.tmp src/channels/chat-sdk-bridge.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/linear@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-matrix.sh b/setup/install-matrix.sh new file mode 100755 index 000000000..06d5ccd76 --- /dev/null +++ b/setup/install-matrix.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# Setup helper: install-matrix — bundles the preflight + install commands +# from the /add-matrix skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Matrix adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @beeper/chat-adapter-matrix +# package; patches the adapter's published dist so its matrix-js-sdk/lib +# imports carry .js extensions (required under Node 22 strict ESM); builds. +# All steps are safe to re-run — re-run this script after any pnpm install +# that touches the adapter. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_MATRIX ===" + +needs_install=false +[[ -f src/channels/matrix.ts ]] || needs_install=true +grep -q "import './matrix.js';" src/channels/index.ts || needs_install=true +grep -q '"@beeper/chat-adapter-matrix"' package.json || needs_install=true +[[ -d node_modules/@beeper/chat-adapter-matrix ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/matrix.ts > src/channels/matrix.ts + +echo "STEP: register-import" +if ! grep -q "import './matrix.js';" src/channels/index.ts; then + printf "import './matrix.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @beeper/chat-adapter-matrix@0.2.0 + +echo "STEP: patch-esm-extensions" +node -e ' + const fs = require("fs"), path = require("path"); + const root = "node_modules/.pnpm"; + const dir = fs.readdirSync(root).find(d => d.startsWith("@beeper+chat-adapter-matrix@")); + if (!dir) { console.log("Matrix adapter not installed"); process.exit(0); } + const f = path.join(root, dir, "node_modules/@beeper/chat-adapter-matrix/dist/index.js"); + fs.writeFileSync(f, fs.readFileSync(f, "utf8").replace( + /from "(matrix-js-sdk\/lib\/[^"]+?)(? src/channels/resend.ts + +echo "STEP: register-import" +if ! grep -q "import './resend.js';" src/channels/index.ts; then + printf "import './resend.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @resend/chat-sdk-adapter@0.1.1 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-slack.sh b/setup/install-slack.sh new file mode 100755 index 000000000..8be6a373d --- /dev/null +++ b/setup/install-slack.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-slack — bundles the preflight + install commands +# from the /add-slack skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Slack adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/slack package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_SLACK ===" + +needs_install=false +[[ -f src/channels/slack.ts ]] || needs_install=true +grep -q "import './slack.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/slack"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/slack ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/slack.ts > src/channels/slack.ts + +echo "STEP: register-import" +if ! grep -q "import './slack.js';" src/channels/index.ts; then + printf "import './slack.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/slack@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-teams.sh b/setup/install-teams.sh new file mode 100755 index 000000000..cb66f67e7 --- /dev/null +++ b/setup/install-teams.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-teams — bundles the preflight + install commands +# from the /add-teams skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Teams adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/teams package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_TEAMS ===" + +needs_install=false +[[ -f src/channels/teams.ts ]] || needs_install=true +grep -q "import './teams.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/teams"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/teams ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/teams.ts > src/channels/teams.ts + +echo "STEP: register-import" +if ! grep -q "import './teams.js';" src/channels/index.ts; then + printf "import './teams.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/teams@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-webex.sh b/setup/install-webex.sh new file mode 100755 index 000000000..8bbbc836c --- /dev/null +++ b/setup/install-webex.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-webex — bundles the preflight + install commands +# from the /add-webex skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to credentials. +# +# Copies the Webex adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @bitbasti/chat-adapter-webex +# package; builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_WEBEX ===" + +needs_install=false +[[ -f src/channels/webex.ts ]] || needs_install=true +grep -q "import './webex.js';" src/channels/index.ts || needs_install=true +grep -q '"@bitbasti/chat-adapter-webex"' package.json || needs_install=true +[[ -d node_modules/@bitbasti/chat-adapter-webex ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/webex.ts > src/channels/webex.ts + +echo "STEP: register-import" +if ! grep -q "import './webex.js';" src/channels/index.ts; then + printf "import './webex.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @bitbasti/chat-adapter-webex@0.1.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-whatsapp-cloud.sh b/setup/install-whatsapp-cloud.sh new file mode 100755 index 000000000..377327809 --- /dev/null +++ b/setup/install-whatsapp-cloud.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Setup helper: install-whatsapp-cloud — bundles the preflight + install +# commands from the /add-whatsapp-cloud skill into one idempotent script so +# /new-setup-2 can run them programmatically before continuing to credentials. +# +# Copies the WhatsApp Cloud adapter in from the `channels` branch; appends the +# self-registration import; installs the pinned @chat-adapter/whatsapp package; +# builds. All steps are safe to re-run. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_WHATSAPP_CLOUD ===" + +needs_install=false +[[ -f src/channels/whatsapp-cloud.ts ]] || needs_install=true +grep -q "import './whatsapp-cloud.js';" src/channels/index.ts || needs_install=true +grep -q '"@chat-adapter/whatsapp"' package.json || needs_install=true +[[ -d node_modules/@chat-adapter/whatsapp ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +git show origin/channels:src/channels/whatsapp-cloud.ts > src/channels/whatsapp-cloud.ts + +echo "STEP: register-import" +if ! grep -q "import './whatsapp-cloud.js';" src/channels/index.ts; then + printf "import './whatsapp-cloud.js';\n" >> src/channels/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @chat-adapter/whatsapp@4.26.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ===" diff --git a/setup/install-whatsapp.sh b/setup/install-whatsapp.sh new file mode 100755 index 000000000..0d307f53c --- /dev/null +++ b/setup/install-whatsapp.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Setup helper: install-whatsapp — bundles the preflight + install commands +# from the /add-whatsapp skill into one idempotent script so /new-setup-2 can +# run them programmatically before continuing to QR/pairing-code auth. +# +# Copies the native Baileys WhatsApp adapter, its whatsapp-auth and groups +# setup steps in from the `channels` branch; appends the self-registration +# import; registers `groups` and `whatsapp-auth` entries in the setup STEPS +# map; installs the pinned @whiskeysockets/baileys + qrcode + pino packages; +# builds. All steps are safe to re-run. QR/pairing-code authentication +# stays in the skill — this script only handles the deterministic install. +set -euo pipefail + +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_ROOT" + +echo "=== NANOCLAW SETUP: INSTALL_WHATSAPP ===" + +CHANNEL_FILES=( + src/channels/whatsapp.ts + setup/whatsapp-auth.ts + setup/groups.ts +) + +needs_install=false +for f in "${CHANNEL_FILES[@]}"; do + [[ -f "$f" ]] || needs_install=true +done +grep -q "import './whatsapp.js';" src/channels/index.ts || needs_install=true +grep -q "groups: " setup/index.ts || needs_install=true +grep -q "'whatsapp-auth':" setup/index.ts || needs_install=true +grep -q '"@whiskeysockets/baileys"' package.json || needs_install=true +grep -q '"qrcode"' package.json || needs_install=true +grep -q '"pino"' package.json || needs_install=true +[[ -d node_modules/@whiskeysockets/baileys ]] || needs_install=true + +if ! $needs_install; then + echo "STATUS: already-installed" + echo "=== END ===" + exit 0 +fi + +echo "STEP: fetch-channels-branch" +git fetch origin channels + +echo "STEP: copy-files" +for f in "${CHANNEL_FILES[@]}"; do + git show "origin/channels:$f" > "$f" +done + +echo "STEP: register-import" +if ! grep -q "import './whatsapp.js';" src/channels/index.ts; then + printf "import './whatsapp.js';\n" >> src/channels/index.ts +fi + +echo "STEP: register-setup-steps" +if ! grep -q "'whatsapp-auth':" setup/index.ts; then + awk ' + { print } + /register: \(\) => import/ && !inserted { + print " groups: () => import('\''./groups.js'\'')," + print " '\''whatsapp-auth'\'': () => import('\''./whatsapp-auth.js'\'')," + inserted = 1 + } + ' setup/index.ts > setup/index.ts.tmp && mv setup/index.ts.tmp setup/index.ts +fi + +echo "STEP: pnpm-install" +pnpm install @whiskeysockets/baileys@6.17.16 qrcode@1.5.4 @types/qrcode@1.5.6 pino@9.6.0 + +echo "STEP: pnpm-build" +pnpm run build + +echo "STATUS: installed" +echo "=== END ==="