feat(new-setup-2): add per-channel bundled install scripts
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-<channel>/SKILL.md's
Credentials section has a similar unapprovable shell chain).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
95
setup/install-linear.sh
Executable file
95
setup/install-linear.sh
Executable file
@@ -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 ==="
|
||||
Reference in New Issue
Block a user