Implement S7 operator connect helpers for SaaS and channels.
Add dry-run-default connect dispatcher and per-integration scripts with gitignored local capability state, docs, and unit tests. Mutations require --apply and use nemohermes/openshell only.
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/connect.sh — S7: Operator connect dispatcher
|
||||
#
|
||||
# Dispatches to per-integration connect helpers.
|
||||
# All mutations require --apply; default is --dry-run for safety.
|
||||
#
|
||||
# Platform-first: all mutations via nemohermes / openshell.
|
||||
# Owner never receives terminal/Docker/nano instructions.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/connect.sh --help
|
||||
# ./scripts/connect.sh status
|
||||
# ./scripts/connect.sh name --dry-run
|
||||
# ./scripts/connect.sh name --apply
|
||||
# ./scripts/connect.sh channels --target whatsapp --dry-run
|
||||
# ./scripts/connect.sh square --dry-run
|
||||
# ./scripts/connect.sh square --apply
|
||||
# ./scripts/connect.sh quickbooks --dry-run
|
||||
# ./scripts/connect.sh vagaro --dry-run
|
||||
# ./scripts/connect.sh all --dry-run
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Source shared helpers
|
||||
# shellcheck source=lib/common.sh
|
||||
source "$SCRIPT_DIR/lib/common.sh"
|
||||
# shellcheck source=lib/env.sh
|
||||
source "$SCRIPT_DIR/lib/env.sh"
|
||||
# shellcheck source=lib/connect_state.sh
|
||||
source "$SCRIPT_DIR/lib/connect_state.sh"
|
||||
|
||||
# ── Defaults ───────────────────────────────────────────────────────────────
|
||||
DRY_RUN=1
|
||||
APPLY=0
|
||||
TARGET=""
|
||||
SUBCOMMAND=""
|
||||
EXTRA_ARGS=()
|
||||
|
||||
# ── Usage ──────────────────────────────────────────────────────────────────
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [SUBCOMMAND] [OPTIONS]
|
||||
|
||||
S7: Operator connect helpers — wire the owner's SaaS and channels.
|
||||
|
||||
Safety model: --dry-run is the default. Use --apply to perform mutations.
|
||||
--dry-run Preview actions without executing (default)
|
||||
--apply Execute mutations (prompts for credentials when needed)
|
||||
|
||||
Subcommands:
|
||||
status Show current connection status
|
||||
name [--dry-run|--apply] Name / profile setup (sandbox rename guidance)
|
||||
channels [--target <ch>] Connect messaging channels
|
||||
--target whatsapp|email|telegram
|
||||
square [--dry-run|--apply] Connect Square (remote MCP)
|
||||
quickbooks [--dry-run|--apply] Connect QuickBooks Online (local MCP)
|
||||
vagaro [--dry-run|--apply] Connect Vagaro (REST + webhooks)
|
||||
all [--dry-run|--apply] Walk all targets sequentially
|
||||
|
||||
Options:
|
||||
--help Show this help
|
||||
--dry-run Preview only (default)
|
||||
--apply Execute mutations
|
||||
--target <name> Target channel (for 'channels' subcommand)
|
||||
|
||||
Examples:
|
||||
$(basename "$0") status
|
||||
$(basename "$0") square --dry-run
|
||||
$(basename "$0") square --apply
|
||||
$(basename "$0") channels --target telegram --dry-run
|
||||
$(basename "$0") all --dry-run
|
||||
|
||||
State:
|
||||
Connection state is stored in .local/capability_state.json (gitignored).
|
||||
Fixtures under data/fixtures/setup/ are NOT modified.
|
||||
|
||||
Platform-first:
|
||||
All mutations use nemohermes / openshell. No parallel control API.
|
||||
Owner never receives terminal/Docker/nano instructions.
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Parse args ─────────────────────────────────────────────────────────────
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
usage
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
APPLY=0
|
||||
shift
|
||||
;;
|
||||
--apply)
|
||||
DRY_RUN=0
|
||||
APPLY=1
|
||||
shift
|
||||
;;
|
||||
--target)
|
||||
shift
|
||||
TARGET="${1:-}"
|
||||
if [[ -z "$TARGET" ]]; then
|
||||
log_error "--target requires a value (whatsapp|email|telegram)"
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
status|name|channels|square|quickbooks|vagaro|all)
|
||||
SUBCOMMAND="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# Collect remaining args for subcommand passthrough
|
||||
SUBCOMMAND="${SUBCOMMAND:-$1}"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── Validate subcommand ────────────────────────────────────────────────────
|
||||
if [[ -z "$SUBCOMMAND" ]]; then
|
||||
log_error "No subcommand specified."
|
||||
usage
|
||||
fi
|
||||
|
||||
VALID_SUBCOMMANDS="status name channels square quickbooks vagaro all"
|
||||
valid=0
|
||||
for s in $VALID_SUBCOMMANDS; do
|
||||
if [[ "$s" == "$SUBCOMMAND" ]]; then
|
||||
valid=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ $valid -eq 0 ]]; then
|
||||
log_error "Unknown subcommand: $SUBCOMMAND"
|
||||
log_error "Valid subcommands: $VALID_SUBCOMMANDS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Load .env (best-effort; warn if missing) ───────────────────────────────
|
||||
if ! load_env 2>/dev/null; then
|
||||
log_warn "Could not load .env — connect scripts may use defaults."
|
||||
fi
|
||||
|
||||
# ── Dispatch ───────────────────────────────────────────────────────────────
|
||||
log_section "S7: Connect — $SUBCOMMAND"
|
||||
|
||||
case "$SUBCOMMAND" in
|
||||
status)
|
||||
print_status
|
||||
;;
|
||||
name)
|
||||
if [[ $APPLY -eq 1 ]]; then
|
||||
bash "$SCRIPT_DIR/connect/connect-name.sh" --apply
|
||||
else
|
||||
bash "$SCRIPT_DIR/connect/connect-name.sh"
|
||||
fi
|
||||
;;
|
||||
channels)
|
||||
channels_args=()
|
||||
[[ $APPLY -eq 1 ]] && channels_args+=(--apply)
|
||||
[[ -n "$TARGET" ]] && channels_args+=(--target "$TARGET")
|
||||
bash "$SCRIPT_DIR/connect/connect-channels.sh" "${channels_args[@]}"
|
||||
;;
|
||||
square)
|
||||
if [[ $APPLY -eq 1 ]]; then
|
||||
bash "$SCRIPT_DIR/connect/connect-square.sh" --apply
|
||||
else
|
||||
bash "$SCRIPT_DIR/connect/connect-square.sh"
|
||||
fi
|
||||
;;
|
||||
quickbooks)
|
||||
if [[ $APPLY -eq 1 ]]; then
|
||||
bash "$SCRIPT_DIR/connect/connect-quickbooks.sh" --apply
|
||||
else
|
||||
bash "$SCRIPT_DIR/connect/connect-quickbooks.sh"
|
||||
fi
|
||||
;;
|
||||
vagaro)
|
||||
if [[ $APPLY -eq 1 ]]; then
|
||||
bash "$SCRIPT_DIR/connect/connect-vagaro.sh" --apply
|
||||
else
|
||||
bash "$SCRIPT_DIR/connect/connect-vagaro.sh"
|
||||
fi
|
||||
;;
|
||||
all)
|
||||
if [[ -n "$TARGET" ]]; then
|
||||
log_warn "--target is ignored with 'all' subcommand (all targets are walked)."
|
||||
fi
|
||||
log_info "Walking all targets..."
|
||||
all_args=()
|
||||
[[ $APPLY -eq 1 ]] && all_args+=(--apply)
|
||||
echo ""
|
||||
bash "$SCRIPT_DIR/connect/connect-name.sh" "${all_args[@]}"
|
||||
echo ""
|
||||
bash "$SCRIPT_DIR/connect/connect-channels.sh" "${all_args[@]}"
|
||||
echo ""
|
||||
bash "$SCRIPT_DIR/connect/connect-square.sh" "${all_args[@]}"
|
||||
echo ""
|
||||
bash "$SCRIPT_DIR/connect/connect-quickbooks.sh" "${all_args[@]}"
|
||||
echo ""
|
||||
bash "$SCRIPT_DIR/connect/connect-vagaro.sh" "${all_args[@]}"
|
||||
echo ""
|
||||
log_section "All targets complete"
|
||||
print_status
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "S7 connect ($SUBCOMMAND) complete."
|
||||
Reference in New Issue
Block a user