diff --git a/.claude-plugin/agents/context-linker.md b/.claude-plugin/agents/context-linker.md deleted file mode 100644 index 2e431d0..0000000 --- a/.claude-plugin/agents/context-linker.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -name: context-linker -description: | - Automatically link code changes to Fizzy cards. - Use when: committing code, creating PRs, resolving issues. - Detects card numbers from branch names, commit messages, and PR descriptions. ---- - -# Context Linker Agent - -Connect code changes to Fizzy cards and discussions. - -## Detection Patterns - -Look for Fizzy references in: - -1. **Branch names**: - - `feature/card-42-description` -> card 42 - - `fix/FIZZY-42-auth-bug` -> card 42 - - `42-feature-name` -> card 42 - -2. **Commit messages**: - - `[FIZZY-42] Fix authentication` -> card 42 - - `[card:42] Update docs` -> card 42 - -3. **PR descriptions**: - - `Closes FIZZY-42` -> card 42 - - `Related: card #42` -> card 42 - -## Commands - -```bash -# Link current commit to a card -fizzy comment create --card 42 --body "Commit $(git rev-parse --short HEAD): $(git log -1 --format=%s)" - -# Link a PR -fizzy comment create --card 42 --body "PR: " - -# Close a card -fizzy card close 42 -``` - -## Workflow: On Commit - -When user commits code: - -1. Extract card number from branch name: - ```bash - BRANCH=$(git branch --show-current) - CARD_NUM=$(echo "$BRANCH" | grep -oE '(FIZZY-|card-?|^)[0-9]+' | grep -oE '[0-9]+' | head -1) - ``` - -2. If found, offer to link: - ```bash - COMMIT=$(git rev-parse --short HEAD) - MSG=$(git log -1 --format=%s) - fizzy comment create --card $CARD_NUM --body "Commit $COMMIT: $MSG" - ``` - -## Workflow: On PR Creation - -When user creates a PR: - -1. Check branch name and PR description for card references -2. For each referenced card, add PR link as comment -3. Offer to close cards if PR is merged - -## Workflow: On Merge - -When a PR is merged: - -1. Find all referenced cards -2. Offer to close them: - ```bash - fizzy card close 42 - ``` - -## Project Context - -Check for `.fizzy.yaml` to get default board: -```bash -# If .fizzy.yaml exists with a board setting, card commands -# will automatically scope to that board -cat .fizzy.yaml -``` - -This enables card operations without explicit `--board` flags. - -## Example Session - -``` -User: I just committed the auth fix - -Agent: I see you're on branch `fix/FIZZY-42-auth-bug`. - The commit is: abc1234 "Fix OAuth token refresh" - - Would you like me to link this commit to card #42? - -User: yes - -Agent: [runs: fizzy comment create --card 42 --body "Commit abc1234: Fix OAuth token refresh"] - Done! Comment added to card #42. - - Should I close this card? -``` diff --git a/.claude-plugin/agents/fizzy-navigator.md b/.claude-plugin/agents/fizzy-navigator.md deleted file mode 100644 index e172220..0000000 --- a/.claude-plugin/agents/fizzy-navigator.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -name: fizzy-navigator -description: | - Cross-board search and navigation for Fizzy. - Use when user needs to find cards across boards, discover board structure, - or navigate the Fizzy workspace. -tools: - - Bash - - Read -model: sonnet ---- - -# Fizzy Navigator Agent - -You help users find and navigate Fizzy cards across their workspace. - -## Capabilities - -1. **Search across boards** - Find cards by content -2. **Discover structure** - List boards, columns, users, tags -3. **Filter and sort** - By assignee, status, tag, column, date -4. **Navigate context** - Help users drill down to specific cards - -## Available Commands - -### Discovery -```bash -fizzy board list # All boards -fizzy user list # All users -fizzy tag list # All tags -fizzy column list --board # Columns on a board -``` - -### Search -```bash -# Search cards by text -fizzy search "keyword" -fizzy search "keyword" --board -fizzy search "keyword" --tag -fizzy search "keyword" --assignee - -# Filter by status -fizzy card list --indexed-by closed # Done cards -fizzy card list --indexed-by not_now # Postponed cards -fizzy card list --indexed-by golden # Starred cards -fizzy card list --indexed-by stalled # Stalled cards -``` - -### Board Deep Dive -```bash -fizzy card list --board -fizzy card list --board --assignee -fizzy card list --board --column -fizzy card list --board --tag -fizzy card list --board --sort newest -``` - -## Search Strategy - -1. **Use full-text search for content queries** - ```bash - fizzy search "keyword" # Search all cards - fizzy search "keyword" --board # Limit to board - ``` - -2. **Use card list with filters for browsing** - ```bash - fizzy card list --board --all # All open cards - fizzy card list --board --unassigned # Unassigned cards - fizzy card list --board --created thisweek # Recently created - ``` - -3. **Narrow by known context** - - If user mentions board name, find board ID first - - If user mentions person, resolve to user ID - -## Common Queries - -| User Request | Approach | -|--------------|----------| -| "Find cards about auth" | `fizzy search "auth"` | -| "What's assigned to me?" | `fizzy card list --assignee ` (per board) | -| "What boards exist?" | `fizzy board list` | -| "Unassigned cards" | `fizzy card list --board --unassigned` | -| "Recently created" | `fizzy card list --board --created thisweek` | - -## Output - -Present results clearly: -- Show card number for follow-up actions -- Include board name for context -- Offer breadcrumb actions (comment, close, assign, move) - -## Important - -- Cards use NUMBER (not internal ID) for CLI commands -- `fizzy card show 42` uses the card number, not the card ID -- Use `jq` to filter and format JSON output from commands diff --git a/.claude-plugin/hooks/hooks.json b/.claude-plugin/hooks/hooks.json index 2cd51be..ac478b1 100644 --- a/.claude-plugin/hooks/hooks.json +++ b/.claude-plugin/hooks/hooks.json @@ -1,5 +1,4 @@ { - "description": "fizzy hooks for Fizzy integration", "hooks": { "SessionStart": [ { @@ -11,18 +10,6 @@ } ] } - ], - "PostToolUse": [ - { - "matcher": "Bash", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-commit-check.sh", - "timeout": 5 - } - ] - } ] } } diff --git a/.claude-plugin/hooks/post-commit-check.sh b/.claude-plugin/hooks/post-commit-check.sh deleted file mode 100755 index ebbd4cc..0000000 --- a/.claude-plugin/hooks/post-commit-check.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -# post-commit-check.sh - Check for Fizzy card references after git commits -# -# This hook runs after Bash tool use and checks if a git commit was made -# that references a Fizzy card (FIZZY-123, card-123, etc.) - -set -euo pipefail - -# Read tool input from stdin (JSON with tool_name, tool_input, tool_output) -input=$(cat) - -# Extract tool input (the bash command that was run) -tool_input=$(echo "$input" | jq -r '.tool_input.command // empty' 2>/dev/null) - -# Only process git commit commands -if [[ ! "$tool_input" =~ ^git\ commit ]]; then - exit 0 -fi - -# Check if commit succeeded by looking for output patterns -tool_output=$(echo "$input" | jq -r '.tool_output // empty' 2>/dev/null) - -# Skip if commit failed — detect error indicators before checking for success. -# Strip the "[branch hash] subject" success line before scanning for errors. -filtered_output=$(echo "$tool_output" | grep -v '^\[.*[a-f0-9]\{7,\}\]' || true) -if echo "$filtered_output" | grep -qiE '(^|[[:space:]])(error|fatal|aborted|rejected)[[:space:]:]|hook[[:space:]].*[[:space:]]failed|pre-commit[[:space:]].*[[:space:]]failed|^error:'; then - exit 0 -fi - -# Verify commit actually succeeded - look for commit hash pattern or "create mode" -if [[ ! "$tool_output" =~ \[.*[a-f0-9]{7,}\] ]] && [[ ! "$tool_output" =~ "create mode" ]]; then - exit 0 -fi - -# Look for card references in the commit message or branch name -branch=$(git branch --show-current 2>/dev/null || true) -last_commit_msg=$(git log -1 --format=%s 2>/dev/null || true) - -# Patterns: FIZZY-123, card-123, fizzy-123 -todo_patterns='FIZZY-[0-9]+|card-[0-9]+|fizzy-[0-9]+' - -found_in_branch=$(echo "$branch" | grep -oEi "$todo_patterns" | head -1 || true) -found_in_msg=$(echo "$last_commit_msg" | grep -oEi "$todo_patterns" | head -1 || true) - -if [[ -n "$found_in_branch" ]] || [[ -n "$found_in_msg" ]]; then - ref="${found_in_msg:-$found_in_branch}" - # Extract just the number - card_number=$(echo "$ref" | grep -oE '[0-9]+') - - cat << EOF - -Detected Fizzy card reference: $ref - -To link this commit to Fizzy: - fizzy comment create --card $card_number --body "Commit $(git rev-parse --short HEAD 2>/dev/null): $last_commit_msg" - -Or close the card: - fizzy card close $card_number - -EOF -fi diff --git a/.claude-plugin/hooks/session-start.sh b/.claude-plugin/hooks/session-start.sh index aa55d39..058aee5 100755 --- a/.claude-plugin/hooks/session-start.sh +++ b/.claude-plugin/hooks/session-start.sh @@ -1,81 +1,48 @@ #!/usr/bin/env bash -# session-start.sh - Load Fizzy context at session start +# session-start.sh - Fizzy plugin liveness check # -# This hook runs when Claude Code starts a session and outputs -# relevant Fizzy board context if configured. +# Lightweight: one subprocess call. Context priming happens on first +# use via the /fizzy skill, not here. set -euo pipefail -# Require jq for JSON parsing -if ! command -v jq &>/dev/null; then - exit 0 -fi - -# Find fizzy - prefer PATH, fall back to plugin's bin directory -if command -v fizzy &>/dev/null; then - FIZZY_BIN="fizzy" -else - SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - FIZZY_BIN="${SCRIPT_DIR}/../../bin/fizzy" - if [[ ! -x "$FIZZY_BIN" ]]; then - cat << 'EOF' +if ! command -v fizzy &>/dev/null; then + cat << 'EOF' -Fizzy plugin: fizzy CLI not found. -Install: https://github.com/basecamp/fizzy-cli#quick-start +Fizzy plugin active — CLI not found on PATH. +Install: https://github.com/basecamp/fizzy-cli#installation EOF - exit 0 - fi + exit 0 fi -# Get CLI version -cli_version=$("$FIZZY_BIN" version 2>/dev/null | jq -r '.data.version // empty' 2>/dev/null || true) +auth_json=$(fizzy auth status --json 2>/dev/null || echo '{}') -# Check if authenticated -auth_output=$("$FIZZY_BIN" auth status 2>/dev/null || echo '{}') -is_auth=$(echo "$auth_output" | jq -r '.data.authenticated // false') -account=$(echo "$auth_output" | jq -r '.data.account // empty') - -if [[ "$is_auth" != "true" ]]; then +if ! command -v jq &>/dev/null; then cat << 'EOF' -Fizzy plugin: Not authenticated. -Run: fizzy setup +Fizzy plugin active. EOF exit 0 fi -# Build context message -context="Fizzy context loaded:" - -if [[ -n "$cli_version" ]]; then - context+="\n CLI: ${cli_version}" -fi - -if [[ -n "$account" ]]; then - context+="\n Account: $account" +is_auth=false +if parsed_auth=$(echo "$auth_json" | jq -er '.data.authenticated' 2>/dev/null); then + is_auth="$parsed_auth" fi -# Check for local .fizzy.yaml board config -if command -v yq &>/dev/null; then - local_board=$(yq -r '.board // empty' .fizzy.yaml 2>/dev/null || true) -elif command -v python3 &>/dev/null; then - local_board=$(python3 -c "import yaml,sys; d=yaml.safe_load(open('.fizzy.yaml')); print(d.get('board',''))" 2>/dev/null || true) -fi - -if [[ -n "${local_board:-}" ]]; then - context+="\n Board: $local_board (from .fizzy.yaml)" -fi - -cat << EOF +if [[ "$is_auth" == "true" ]]; then + cat << 'EOF' -$(echo -e "$context") - -Use \`fizzy\` commands to interact with Fizzy: - fizzy board list # List boards - fizzy card list # List cards on default board - fizzy search "query" # Search across cards - fizzy card show # Show card details +Fizzy plugin active. EOF +else + cat << 'EOF' + +Fizzy plugin active — not authenticated. +Run: fizzy setup + +EOF +fi diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json deleted file mode 100644 index 8eb6ba5..0000000 --- a/.claude-plugin/marketplace.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", - "name": "fizzy", - "metadata": { - "description": "Fizzy CLI and Claude Code integration", - "version": "0.1.0" - }, - "owner": { - "name": "37signals", - "email": "support@37signals.com" - }, - "plugins": [ - { - "name": "fizzy", - "description": "Fizzy integration for Claude Code. Manage boards, cards, track work, and link code to projects.", - "source": "./", - "category": "productivity" - } - ] -} diff --git a/.claude-plugin/skills/fizzy b/.claude-plugin/skills/fizzy new file mode 120000 index 0000000..d31901d --- /dev/null +++ b/.claude-plugin/skills/fizzy @@ -0,0 +1 @@ +../../skills/fizzy \ No newline at end of file