#!/usr/bin/env bash # Comma plugin for Claude Code — one-line installer. # # Usage: # curl -fsSL https://commareports.com/install.sh | bash # # What this does: # 1. Verifies the `claude` CLI is on PATH. # 2. Adds the Comma marketplace (`comma/comma`). # 3. Installs the `comma` plugin. # 4. Prompts for a COMMA_API_TOKEN and writes ~/.config/comma/env. # 5. Prints the env line you need to add to your shell profile. # # Safe by design: # - No sudo. # - No binary downloads. Only invokes `claude`, the CLI you already # have installed. # - Writes one file (~/.config/comma/env, 0600) and nothing else. set -eu MARKETPLACE="comma/comma" PLUGIN="comma@comma" CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/comma" ENV_FILE="$CONFIG_DIR/env" SETTINGS_URL="https://commareports.com/settings#tokens" bold() { printf '\033[1m%s\033[0m\n' "$*"; } warn() { printf '\033[33m%s\033[0m\n' "$*" >&2; } err() { printf '\033[31m%s\033[0m\n' "$*" >&2; } bold "Comma plugin for Claude Code" echo if ! command -v claude >/dev/null 2>&1; then err "claude CLI not found on PATH." err "Install Claude Code first: https://docs.anthropic.com/claude-code" exit 1 fi if [ ! -d "$HOME/.claude" ]; then warn "~/.claude not found — Claude Code may not be initialized yet." warn "The install will still try; run 'claude' once afterward if it fails." fi echo "1/4 Adding marketplace $MARKETPLACE..." if ! claude plugin marketplace add "$MARKETPLACE" 2>/dev/null; then warn " (marketplace may already be added — continuing)" fi echo "2/4 Installing plugin $PLUGIN..." if ! claude plugin install "$PLUGIN"; then err "plugin install failed. Try: claude plugin install $PLUGIN" exit 1 fi echo "3/4 Configuring API token..." mkdir -p "$CONFIG_DIR" chmod 700 "$CONFIG_DIR" # Skip the prompt if a token is already in env or in the env file — # this lets re-runs (and CI) work without interactive input. EXISTING_TOKEN="" if [ -n "${COMMA_API_TOKEN:-}" ]; then EXISTING_TOKEN="$COMMA_API_TOKEN" elif [ -f "$ENV_FILE" ] && grep -q '^COMMA_API_TOKEN=' "$ENV_FILE"; then EXISTING_TOKEN="$(grep '^COMMA_API_TOKEN=' "$ENV_FILE" | head -1 | cut -d= -f2-)" fi if [ -n "$EXISTING_TOKEN" ]; then echo " Using existing token (set COMMA_API_TOKEN= to override)." TOKEN="$EXISTING_TOKEN" else echo " Get a token at: $SETTINGS_URL" echo " It will start with: comma_sk_" if [ -t 0 ]; then printf " Paste your token (input hidden): " # Read silently so the token isn't echoed. stty -echo 2>/dev/null || true IFS= read -r TOKEN || TOKEN="" stty echo 2>/dev/null || true echo else warn " No TTY available — skipping token prompt." warn " Set COMMA_API_TOKEN in your shell, or write it to $ENV_FILE manually." TOKEN="" fi fi if [ -n "$TOKEN" ]; then case "$TOKEN" in comma_sk_*) ;; *) warn " Token doesn't start with comma_sk_ — saving anyway, but it may not work." ;; esac umask 077 printf 'COMMA_API_TOKEN=%s\n' "$TOKEN" > "$ENV_FILE" chmod 600 "$ENV_FILE" echo " Wrote $ENV_FILE" fi echo "4/4 Done." echo bold "Next step:" echo " Export the token in the shell that launches Claude Code:" echo echo " # Add to ~/.zshrc, ~/.bashrc, or ~/.config/fish/config.fish:" echo " set -a; . $ENV_FILE; set +a" echo echo " Or just:" echo " export COMMA_API_TOKEN=comma_sk_..." echo echo "Then restart Claude Code and try:" echo " /comma-publish publish the last reply as a report" echo " /comma-search ... search your reports" echo " /comma-link open a report by id" echo