This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Opal agent implementation for the Whitney Museum of American Art. Three agent types demonstrate Optimizely's Opal platform capabilities: a standalone A/B test analyzer, a two-step content workflow (writer -> reviewer), and a Cloudflare Workers tool service that wraps the Whitney public API and content analysis checks.
# Everything runs from tools/
cd tools && npm install
cp .env.example .env # fill in ANTHROPIC_API_KEY (and optionally Cloudflare creds)
# Tool service (Cloudflare Workers + Hono)
npm run dev # local dev server via wrangler (http://localhost:8787)
npm run typecheck # tsc --noEmit
npm run deploy # deploy to Cloudflare Workers (requires CLOUDFLARE_API_TOKEN)
npm run tail # stream live logs from deployed worker
# Local agent test harness (runs agents via Claude API)
npm run harness -- list --agents-dir ../agents
npm run harness -- discover
npm run harness -- run ../agents/<agent>.json -p key=value [-v]
# Endpoints (tool service)
# GET / health check
# GET /discovery Opal tool discovery (SDK pattern)
# GET /registry Opal tool discovery (raw HTTP pattern)
# POST /tools/:name execute a tool (body = parameters JSON)No test suite or linter exists yet.
Agents (agents/) — JSON configs for the Opal platform, testable locally via the harness:
whitney-exhibition-ab-test-analyzer.json— standalone specialized agent, no tools, creativity 0.2whitney-content-writer.json— workflow step 1, usesget_exhibitions+search_collection, creativity 0.7whitney-content-reviewer.json— workflow step 2, usescheck_brand_voice+check_accessibility, creativity 0.2whitney-exhibition-content-workflow.json— workflow orchestrator linking writer -> reviewer
Tool service (tools/src/index.ts) — single-file Hono app deployed as a Cloudflare Worker:
get_exhibitions/search_collection— proxy the Whitney public API (whitney.org/api), no auth neededcheck_brand_voice— regex-based checks against 5 rules (WBV-001 through WBV-005), score starts at 100 with deductionscheck_accessibility— Flesch-Kincaid grade level + 4 structural checks (ACC-001 through ACC-005), default target grade 8
Tools are defined in the TOOLS array with metadata and handler functions. The /discovery endpoint is generated from this array (replaces the Opal SDK's @tool decorator auto-generation).
Test harness (tools/src/cli.ts) — local CLI that replaces Opal's runtime for testing. Reads agent JSON configs, sends prompts to the Claude API, routes tool calls to the local Worker. Supports single agents and multi-step workflows. Run via npm run harness.
Instructions (instructions/) — CLEAR framework templates (Context, Layout, Example, Action, Review) used as instruction references alongside agent prompt_templates.
CI/CD (.github/workflows/deploy.yml) — deploys tool service to Cloudflare Workers on push to main when tools/** changes. Requires two GitHub Actions secrets: CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.
No secrets in plain files. All credentials go through:
- GitHub Actions secrets:
CLOUDFLARE_API_TOKEN,CLOUDFLARE_ACCOUNT_ID - Cloudflare Workers secrets:
wrangler secret put SECRET_NAME(accessed viac.env.SECRET_NAMEin Hono) - Local dev/harness:
tools/.envfile (gitignored) — holdsANTHROPIC_API_KEYand optionally Cloudflare creds - Worker runtime secrets:
tools/.dev.varsfile (gitignored)
- Agent JSON schema:
schema_version: "1.0", fields includecreativity,inference_type,enabled_tools,prompt_template,parameters - Whitney API uses Ransack query syntax:
q[field_matcher]=value(e.g.,q[title_cont]=hopper,q[start_time_gt]=...) - Brand voice rules use "exhibition" not "exhibit", "artwork"/"work" not "art piece", avoid exclusionary terms (see WBV-003)
- Tool execution accepts both
{ parameters: {...} }and flat parameter objects - TypeScript strict mode; wrangler handles bundling (no separate build step)