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
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ uv add --group dev package_name
### Database Access

```bash
scripts/supabase/tables.sh # List all tables (dev)
scripts/supabase/describe.sh users # Show columns for a table (dev)
scripts/supabase/query.sh "SELECT * FROM users LIMIT 1" # Run a query (dev, tabular)
scripts/supabase/query.sh -x "SELECT * FROM users LIMIT 1" # Vertical display
scripts/supabase/query.sh --prod "SELECT ..." # Run against production
scripts/supabase/tables.sh --dev # List all tables (dev)
scripts/supabase/describe.sh --dev users # Show columns for a table (dev)
scripts/supabase/query.sh --dev "SELECT * FROM users LIMIT 1" # Run a query (dev, tabular)
scripts/supabase/query.sh --dev -x "SELECT * FROM users LIMIT 1" # Vertical display
scripts/supabase/query.sh --prd "SELECT ..." # Run against production
```

### Sentry CLI
Expand Down Expand Up @@ -135,7 +135,7 @@ assert find_test_files("foo.ts", all_files, None) == ["foo.test.ts"]
- Technical, descriptive title. **No `## Test plan`**.
- **Two posts** (last section, customer-facing only): GitAuto (changelog) + Wes (personal voice, don't emphasize "GitAuto")
- Format: `## Social Media Post (GitAuto)` and `## Social Media Post (Wes)` headers (parsed by `extract-social-posts.js`)
- **GitAuto post**: Changelog format — one-liner headline + change bullets. No storytelling.
- **GitAuto post**: Changelog format — one-liner headline + customer-facing feature bullets (no test/internal changes). Each feature on one line. Include items mentioned in the PR title.
- **Wes post**: Honest stories. Vary openers — check recent posts first.
- Guidelines: No em dashes (—). Under 280 chars. No marketing keywords. No negative framing. No internal names. No small numbers — use relative language.
8. If Sentry issue: `python3 scripts/sentry/get_issue.py AGENT-XXX` then `python3 scripts/sentry/resolve_issue.py AGENT-XXX ...`
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "GitAuto"
version = "1.6.10"
version = "1.6.11"
requires-python = ">=3.14"
dependencies = [
"annotated-doc==0.0.4",
Expand Down
7 changes: 7 additions & 0 deletions scripts/git/pre_commit_hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ set -uo pipefail

echo "=== Pre-commit hook ==="

# Block commits directly to main
BRANCH=$(git branch --show-current)
if [ "$BRANCH" = "main" ]; then
echo "FAILED: Cannot commit directly to main. Use a feature branch."
exit 1
fi

# Keep local main in sync with remote (no checkout needed)
git fetch origin main:main 2>/dev/null || true

Expand Down
59 changes: 38 additions & 21 deletions scripts/supabase/daily_cost_report.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#!/bin/bash
# Usage: scripts/supabase/daily_cost_report.sh [YYYY-MM-DD] [--prod]
# Usage: scripts/supabase/daily_cost_report.sh [YYYY-MM-DD] [--dev|--prd]
# Defaults to today (PT timezone) and production database.
# Shows LLM cost breakdown by repo/PR/trigger/model with totals.
# Shows LLM cost breakdown grouped by repo/PR, with trigger/model detail.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

DATE=""
PROD_FLAG="--prod"
ENV_FLAG="--prd"

while [[ $# -gt 0 ]]; do
case $1 in
--dev) PROD_FLAG=""; shift ;;
--prod) PROD_FLAG="--prod"; shift ;;
--dev) ENV_FLAG="--dev"; shift ;;
--prod|--prd) ENV_FLAG="--prd"; shift ;;
*) DATE="$1"; shift ;;
esac
done
Expand All @@ -25,16 +25,16 @@ fi

NEXT_DATE=$(date -j -f "%Y-%m-%d" -v+1d "$DATE" +%Y-%m-%d 2>/dev/null || date -d "$DATE + 1 day" +%Y-%m-%d)

WHERE="u.created_at >= '${DATE}T00:00:00-07:00' AND u.created_at < '${NEXT_DATE}T00:00:00-07:00'"

echo "=== Daily LLM Cost Report: $DATE (PT) ==="
echo ""
echo "--- By PR (grouped) ---"

# Summary by repo/PR/trigger/model
"$SCRIPT_DIR/query.sh" $PROD_FLAG "
"$SCRIPT_DIR/query.sh" $ENV_FLAG "
SELECT
u.owner_name || '/' || u.repo_name AS repo,
u.pr_number AS pr,
u.trigger,
REPLACE(REPLACE(REPLACE(lr.model_id, 'claude-', ''), '-4-6', '46'), '-4-5', '45') AS model,
COUNT(lr.id) AS calls,
SUM(lr.input_tokens) AS in_tok,
SUM(lr.output_tokens) AS out_tok,
Expand All @@ -43,18 +43,38 @@ SELECT
ROUND(SUM(lr.total_cost_usd)::numeric, 2) AS total
FROM usage u
JOIN llm_requests lr ON lr.usage_id = u.id
WHERE u.created_at >= '${DATE}T00:00:00-07:00'
AND u.created_at < '${NEXT_DATE}T00:00:00-07:00'
GROUP BY u.owner_name, u.repo_name, u.pr_number, u.trigger, lr.model_id
WHERE $WHERE
GROUP BY u.owner_name, u.repo_name, u.pr_number
ORDER BY total DESC
"

echo ""
echo "--- Breakdown by trigger/model (within each PR) ---"

"$SCRIPT_DIR/query.sh" $ENV_FLAG "
SELECT
u.owner_name || '/' || u.repo_name AS repo,
u.pr_number AS pr,
u.trigger,
REPLACE(REPLACE(REPLACE(lr.model_id, 'claude-', ''), '-4-6', '46'), '-4-5', '45') AS model,
COUNT(lr.id) AS calls,
ROUND(SUM(lr.input_cost_usd)::numeric, 2) AS in_cost,
ROUND(SUM(lr.output_cost_usd)::numeric, 2) AS out_cost,
ROUND(SUM(lr.total_cost_usd)::numeric, 2) AS total
FROM usage u
JOIN llm_requests lr ON lr.usage_id = u.id
WHERE $WHERE
GROUP BY u.owner_name, u.repo_name, u.pr_number, u.trigger, lr.model_id
ORDER BY u.owner_name, u.repo_name, u.pr_number, total DESC
"

echo ""
echo "=== Totals ==="

"$SCRIPT_DIR/query.sh" $PROD_FLAG "
"$SCRIPT_DIR/query.sh" $ENV_FLAG "
SELECT
COUNT(DISTINCT u.id) AS runs,
COUNT(DISTINCT u.owner_name || '/' || u.repo_name || '#' || u.pr_number) AS prs,
COUNT(lr.id) AS calls,
SUM(lr.input_tokens) AS in_tokens,
SUM(lr.output_tokens) AS out_tokens,
Expand All @@ -63,28 +83,25 @@ SELECT
ROUND(SUM(lr.total_cost_usd)::numeric, 2) AS total
FROM usage u
JOIN llm_requests lr ON lr.usage_id = u.id
WHERE u.created_at >= '${DATE}T00:00:00-07:00'
AND u.created_at < '${NEXT_DATE}T00:00:00-07:00'
WHERE $WHERE
"

echo ""
echo "=== Top 5 Most Expensive Runs (input growth pattern) ==="
echo "=== Top 5 Most Expensive PRs (input growth pattern) ==="

"$SCRIPT_DIR/query.sh" $PROD_FLAG "
"$SCRIPT_DIR/query.sh" $ENV_FLAG "
SELECT
u.owner_name || '/' || u.repo_name AS repo,
u.pr_number AS pr,
u.trigger,
COUNT(lr.id) AS calls,
MIN(lr.input_length) AS min_in_len,
MAX(lr.input_length) AS max_in_len,
ROUND(MAX(lr.input_length)::numeric / NULLIF(MIN(lr.input_length), 0), 1) AS growth_x,
ROUND(SUM(lr.total_cost_usd)::numeric, 2) AS total
FROM usage u
JOIN llm_requests lr ON lr.usage_id = u.id
WHERE u.created_at >= '${DATE}T00:00:00-07:00'
AND u.created_at < '${NEXT_DATE}T00:00:00-07:00'
GROUP BY u.id, u.owner_name, u.repo_name, u.pr_number, u.trigger
WHERE $WHERE
GROUP BY u.owner_name, u.repo_name, u.pr_number
ORDER BY total DESC
LIMIT 5
"
19 changes: 13 additions & 6 deletions scripts/supabase/describe.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# Usage: scripts/supabase/describe.sh [-p|--prod] <table_name>
# Shows columns, types, and nullability for a table.
# Usage: scripts/supabase/describe.sh <--dev|--prd> <table_name>
# Shows columns, types, and nullability for a table. Requires explicit --dev or --prd.

set -euo pipefail

Expand All @@ -9,24 +9,31 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

source "$PROJECT_ROOT/.env"

ENV="dev"
ENV=""
TABLE=""

while [[ $# -gt 0 ]]; do
case $1 in
-p|--prod) ENV="prod"; shift ;;
-d|--dev) ENV="dev"; shift ;;
-p|--prd) ENV="prd"; shift ;;
*) TABLE="$1"; shift ;;
esac
done

if [[ -z "$ENV" ]]; then
echo "Error: must specify --dev or --prd"
echo "Usage: $0 <--dev|--prd> <table_name>"
exit 1
fi

if [[ -z "$TABLE" ]]; then
echo "Usage: $0 [-p|--prod] <table_name>"
echo "Usage: $0 <--dev|--prd> <table_name>"
exit 1
fi

QUERY="SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '$TABLE' ORDER BY ordinal_position;"

if [[ "$ENV" == "prod" ]]; then
if [[ "$ENV" == "prd" ]]; then
psql "postgresql://postgres.awegqusxzsmlgxaxyyrq:$SUPABASE_DB_PASSWORD_PRD@aws-0-us-west-1.pooler.supabase.com:6543/postgres" -c "$QUERY"
else
psql "postgresql://postgres.dkrxtcbaqzrodvsagwwn:$SUPABASE_DB_PASSWORD_DEV@aws-0-us-west-1.pooler.supabase.com:6543/postgres" -c "$QUERY"
Expand Down
19 changes: 13 additions & 6 deletions scripts/supabase/query.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# Usage: scripts/supabase/query.sh [-p|--prod] [-x] "SQL query"
# Defaults to development database. Use -x for vertical display.
# Usage: scripts/supabase/query.sh <--dev|--prd> [-x] "SQL query"
# Requires explicit --dev or --prd. Use -x for vertical display.

set -euo pipefail

Expand All @@ -9,25 +9,32 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

source "$PROJECT_ROOT/.env"

ENV="dev"
ENV=""
QUERY=""
PSQL_FLAGS=""

while [[ $# -gt 0 ]]; do
case $1 in
-p|--prod) ENV="prod"; shift ;;
-d|--dev) ENV="dev"; shift ;;
-p|--prd) ENV="prd"; shift ;;
-x) PSQL_FLAGS="-x"; shift ;;
*) QUERY="$1"; shift ;;
esac
done

if [[ -z "$ENV" ]]; then
echo "Error: must specify --dev or --prd"
echo "Usage: $0 <--dev|--prd> [-x] \"SQL query\""
exit 1
fi

if [[ -z "$QUERY" ]]; then
echo "Usage: $0 [-p|--prod] [-x] \"SQL query\""
echo "Usage: $0 <--dev|--prd> [-x] \"SQL query\""
echo " -x Vertical display (expanded output)"
exit 1
fi

if [[ "$ENV" == "prod" ]]; then
if [[ "$ENV" == "prd" ]]; then
psql "postgresql://postgres.awegqusxzsmlgxaxyyrq:$SUPABASE_DB_PASSWORD_PRD@aws-0-us-west-1.pooler.supabase.com:6543/postgres" $PSQL_FLAGS -c "$QUERY"
else
psql "postgresql://postgres.dkrxtcbaqzrodvsagwwn:$SUPABASE_DB_PASSWORD_DEV@aws-0-us-west-1.pooler.supabase.com:6543/postgres" $PSQL_FLAGS -c "$QUERY"
Expand Down
19 changes: 13 additions & 6 deletions scripts/supabase/tables.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# Usage: scripts/supabase/tables.sh [-p|--prod]
# Lists all tables in the public schema.
# Usage: scripts/supabase/tables.sh <--dev|--prd>
# Lists all tables in the public schema. Requires explicit --dev or --prd.

set -euo pipefail

Expand All @@ -9,18 +9,25 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

source "$PROJECT_ROOT/.env"

ENV="dev"
ENV=""

while [[ $# -gt 0 ]]; do
case $1 in
-p|--prod) ENV="prod"; shift ;;
*) echo "Usage: $0 [-p|--prod]"; exit 1 ;;
-d|--dev) ENV="dev"; shift ;;
-p|--prd) ENV="prd"; shift ;;
*) echo "Usage: $0 <--dev|--prd>"; exit 1 ;;
esac
done

if [[ -z "$ENV" ]]; then
echo "Error: must specify --dev or --prd"
echo "Usage: $0 <--dev|--prd>"
exit 1
fi

QUERY="SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;"

if [[ "$ENV" == "prod" ]]; then
if [[ "$ENV" == "prd" ]]; then
psql "postgresql://postgres.awegqusxzsmlgxaxyyrq:$SUPABASE_DB_PASSWORD_PRD@aws-0-us-west-1.pooler.supabase.com:6543/postgres" -c "$QUERY"
else
psql "postgresql://postgres.dkrxtcbaqzrodvsagwwn:$SUPABASE_DB_PASSWORD_DEV@aws-0-us-west-1.pooler.supabase.com:6543/postgres" -c "$QUERY"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.