# Example: Claude Code Wrapper

This shell wrapper starts a Keito timer before launching Claude Code and cleans it up when Claude exits.

## Prerequisites

- Keito CLI installed.
- Claude Code installed.
- `KEITO_API_KEY` and `KEITO_ACCOUNT_ID` environment variables set, or `keito auth login` completed.
- A Keito project and task to track against.

## Full Code

```bash
#!/usr/bin/env bash
# keito-claude.sh - Track Claude Code sessions with Keito

set -euo pipefail

if [ "$#" -lt 2 ]; then
  echo "Usage: keito-claude.sh <project-id-or-name> <task-id-or-name> [claude args...]" >&2
  exit 2
fi

PROJECT="$1"
TASK="$2"
shift 2

STARTED=0

cleanup() {
  status=$?
  if [ "$STARTED" = "1" ]; then
    if [ "$status" -eq 0 ]; then
      keito time stop --notes "Claude Code session completed" --json || true
    else
      keito time stop --discard --json || true
    fi
  fi
}

trap cleanup EXIT

keito auth status --json >/dev/null
keito time start \
  --project "$PROJECT" \
  --task "$TASK" \
  --notes "Claude Code session" \
  --json
STARTED=1

claude "$@"
```

## Usage

```bash
chmod +x keito-claude.sh
./keito-claude.sh "Acme Website" "Development"
```

Use IDs for automation:

```bash
./keito-claude.sh "project_id_here" "task_id_here" --model opus
```

## Notes

- This wrapper uses regular CLI timers, so entries use `source=cli`.
- For `source=agent`, session IDs, and metadata, use [CLI Agent Workflows](/docs/cli/agent-mode) or install the [Keito Agent Skill](/docs/integrations/skills).
- This wrapper discards the timer if Claude exits non-zero. Change the cleanup block if failed sessions should still be billed.