Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 0 additions & 107 deletions .claude-plugin/agents/basecamp-navigator.md

This file was deleted.

104 changes: 0 additions & 104 deletions .claude-plugin/agents/context-linker.md

This file was deleted.

26 changes: 26 additions & 0 deletions .claude-plugin/commands/doctor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: basecamp-doctor
description: Check Basecamp plugin health — CLI, auth, API connectivity, project context.
invocable: true
---

# /basecamp-doctor

Run the Basecamp CLI health check and report results.

```bash
basecamp doctor --json
```

Interpret the output:
- **pass**: Working correctly
- **warn**: Non-critical issue (e.g., shell completion not installed)
- **skip**: Check not run (e.g., unauthenticated or not applicable)
- **fail**: Broken — needs attention

For any failures, follow the `hint` field in the check output. Common fixes:
- Authentication failed → `basecamp auth login`
- API unreachable → check network / VPN
- Plugin not installed → `claude plugin install basecamp`

Report results concisely: list failures and warnings with their hints. If everything passes, say so.
103 changes: 31 additions & 72 deletions .claude-plugin/hooks/session-start.sh
Original file line number Diff line number Diff line change
@@ -1,93 +1,52 @@
#!/usr/bin/env bash
# session-start.sh - Load Basecamp context at session start
# session-start.sh - Basecamp plugin liveness check
#
# This hook runs when Claude Code starts a session and outputs
# relevant Basecamp project context if configured.
# Lightweight: one subprocess call. Confirms the CLI is available and,
# when jq is installed, whether it is authenticated. Context priming
# (project IDs, etc.) happens on first use via the /basecamp skill,
# not here.

set -euo pipefail

# Require jq for JSON parsing
if ! command -v jq &>/dev/null; then
exit 0
fi

# Find basecamp - prefer PATH, fall back to plugin's bin directory
if command -v basecamp &>/dev/null; then
BASECAMP_BIN="basecamp"
else
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASECAMP_BIN="${SCRIPT_DIR}/../../bin/basecamp"
if [[ ! -x "$BASECAMP_BIN" ]]; then
cat << 'EOF'
if ! command -v basecamp &>/dev/null; then
cat << 'EOF'
<hook-output>
Basecamp plugin: basecamp CLI not found.
Basecamp plugin active — CLI not found on PATH.
Install: https://github.com/basecamp/basecamp-cli#installation
</hook-output>
EOF
exit 0
fi
fi

# Get CLI version (--version prints "basecamp version X.Y.Z")
cli_version=$("$BASECAMP_BIN" --version 2>/dev/null | awk '{print $NF}' || true)

# Check if we have any Basecamp configuration
config_output=$("$BASECAMP_BIN" config show --json 2>/dev/null || echo '{}')
has_config=$(echo "$config_output" | jq -r '.data // empty' 2>/dev/null)

if [[ -z "$has_config" ]] || [[ "$has_config" == "{}" ]]; then
exit 0
fi

# Extract config values
account_id=$(echo "$has_config" | jq -r '.account_id.value // empty')
project_id=$(echo "$has_config" | jq -r '.project_id.value // empty')
todolist_id=$(echo "$has_config" | jq -r '.todolist_id.value // empty')
# Single subprocess: auth status tells us if we're good to go
auth_json=$(basecamp auth status --json 2>/dev/null || echo '{}')

# Only output if we have at least account_id
if [[ -z "$account_id" ]]; then
if ! command -v jq &>/dev/null; then
# No jq — can't parse, just confirm presence
cat << 'EOF'
<hook-output>
Basecamp plugin active.
</hook-output>
EOF
exit 0
fi

# Build context message
context="Basecamp context loaded:"

if [[ -n "$cli_version" ]]; then
context+="\n CLI: v${cli_version}"
fi

# Show active profile if using named profiles
active_profile=$("$BASECAMP_BIN" profile show --json 2>/dev/null | jq -r '.data.name // empty' 2>/dev/null || true)
if [[ -n "$active_profile" ]]; then
context+="\n Profile: $active_profile"
fi

context+="\n Account: $account_id"

if [[ -n "$project_id" ]]; then
context+="\n Project: $project_id"
fi

if [[ -n "$todolist_id" ]]; then
context+="\n Todolist: $todolist_id"
is_auth=false
if parsed_auth=$(echo "$auth_json" | jq -er '.data.authenticated' 2>/dev/null); then
is_auth="$parsed_auth"
fi

# Check if authenticated
auth_status=$("$BASECAMP_BIN" auth status --json 2>/dev/null || echo '{}')
is_auth=$(echo "$auth_status" | jq -r '.data.authenticated // false')

if [[ "$is_auth" != "true" ]]; then
context+="\n Auth: Not authenticated (run: basecamp auth login)"
fi

cat << EOF
if [[ "$is_auth" == "true" ]]; then
cat << 'EOF'
<hook-output>
$(echo -e "$context")

Use \`basecamp\` commands to interact with Basecamp:
basecamp todos list # List todos in current project
basecamp search "query" # Search across projects
basecamp reports assigned # See what's assigned to you
basecamp clock <id> --hours 1.5 # Log time on a recording
Basecamp plugin active.
</hook-output>
EOF
else
cat << 'EOF'
<hook-output>
Basecamp plugin active — not authenticated.
Run: basecamp auth login
</hook-output>
EOF
fi
20 changes: 0 additions & 20 deletions .claude-plugin/marketplace.json

This file was deleted.

1 change: 0 additions & 1 deletion .claude-plugin/skills/basecamp-api-reference

This file was deleted.

Loading