- Implement check-billing.sh script that verifies the most recent transcript has entrypoint 'cli' (subscription pool) not 'sdk-cli' - Script finds newest *.jsonl under ~/.claude/projects/ and scans for entrypoint field, exiting 0 iff it equals 'cli' - Handle no-transcripts and no-directory cases with distinct errors - Update README with Troubleshooting and Release checklist sections referencing the script as the pre-release gate Acceptance criteria: - bash -n passes (syntax valid) - Executable mode 755 - README updated with troubleshooting/release checklist references Bead-Id: bf-1n6
79 lines
2.4 KiB
Bash
Executable file
79 lines
2.4 KiB
Bash
Executable file
#!/bin/bash
|
|
# check-billing.sh - AS-4 billing conformance script
|
|
# Inspects the most recent transcript JSONL under ~/.claude/projects/ and asserts
|
|
# the session has entrypoint 'cli' (subscription pool), not 'sdk-cli'.
|
|
# This is the AS-4 pre-release gate - run before every release.
|
|
|
|
set -eu
|
|
|
|
# ANSI color codes for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1" >&2
|
|
}
|
|
|
|
# Find the newest JSONL file under ~/.claude/projects/
|
|
TRANSCRIPTS_DIR="$HOME/.claude/projects"
|
|
|
|
if [ ! -d "$TRANSCRIPTS_DIR" ]; then
|
|
log_error "Claude projects directory not found: $TRANSCRIPTS_DIR"
|
|
log_error "Has claude or claude-print been run on this machine?"
|
|
exit 1
|
|
fi
|
|
|
|
# Find the most recently modified .jsonl file (recursive)
|
|
NEWEST_JSONL=$(find "$TRANSCRIPTS_DIR" -type f -name "*.jsonl" -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
|
|
if [ -z "$NEWEST_JSONL" ]; then
|
|
log_error "No transcript JSONL files found under: $TRANSCRIPTS_DIR"
|
|
log_error "Run claude or claude-print first to generate a transcript."
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Inspecting most recent transcript: $NEWEST_JSONL"
|
|
|
|
# Scan for the entrypoint field in the JSONL
|
|
# We use jq if available, fallback to grep+sed
|
|
ENTRYPOINT=
|
|
|
|
if command -v jq >/dev/null 2>&1; then
|
|
# Use jq for robust JSON parsing
|
|
ENTRYPOINT=$(grep -m1 '"entrypoint"' "$NEWEST_JSONL" | jq -r '.entrypoint // empty' 2>/dev/null || echo "")
|
|
else
|
|
# Fallback: extract with grep and sed
|
|
# Matches: "entrypoint": "cli" or "entrypoint":"cli"
|
|
ENTRYPOINT=$(grep -m1 '"entrypoint"' "$NEWEST_JSONL" | sed -n 's/.*"entrypoint"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' 2>/dev/null || echo "")
|
|
fi
|
|
|
|
if [ -z "$ENTRYPOINT" ]; then
|
|
log_error "No entrypoint field found in transcript: $NEWEST_JSONL"
|
|
log_error "The transcript may be from an incompatible Claude Code version."
|
|
exit 1
|
|
fi
|
|
|
|
# Print the entrypoint value
|
|
echo "entrypoint: $ENTRYPOINT"
|
|
|
|
# Assert it equals 'cli'
|
|
if [ "$ENTRYPOINT" = "cli" ]; then
|
|
log_info "Billing classification: SUBSCRIPTION (cli) - PASS"
|
|
exit 0
|
|
else
|
|
log_error "Billing classification: AGENT SDK CREDIT POOL ($ENTRYPOINT) - FAIL"
|
|
log_error "Expected: cli (subscription pool)"
|
|
log_error "Actual: $ENTRYPOINT"
|
|
log_error "File inspected: $NEWEST_JSONL"
|
|
exit 1
|
|
fi
|