diff --git a/.github/prompts/update-agents-md.md b/.github/prompts/update-agents-md.md new file mode 100644 index 0000000..1433102 --- /dev/null +++ b/.github/prompts/update-agents-md.md @@ -0,0 +1,62 @@ +# Update AGENTS.md + +You are regenerating `AGENTS.md` at the root of the `customerio-node` repository. This file is the canonical agent-friendly description of this SDK. It is read by LLM-based coding assistants and routing layers that need to pick the right Customer.io SDK for a given task. Optimize for an LLM to ingest in a single read. + +## What you must do + +1. Inspect the current state of the SDK source. At minimum, read: + - `package.json` (for the current version, name, and entry points) + - `README.md` (for the canonical user-facing examples and any region/auth notes) + - `index.ts` and the `lib/` directory (for the actual exported classes and methods) + - `examples/` (for representative usage of the most-common methods) +2. Regenerate `AGENTS.md` at the repo root using the structure defined below. Replace the entire file. Do not append. +3. If the regenerated file is byte-identical to the existing one, do nothing. The workflow handles the no-op case via `git diff --quiet`. +4. Do not modify any file other than `AGENTS.md`. +5. Keep the file under 300 lines. Prefer compactness over completeness. If you must choose, drop sections in this order: extra examples, edge cases, then commentary. Never drop the structural sections listed below. + +## Required structure + +Use these section headings, in this exact order, as level-2 markdown headings: + +``` +# Customer.io Node.js SDK (AGENTS.md) + +## What this is +## Install +## Initialize +## Common calls +## Auth and regions +## When to use this vs cdp-analytics-js +## Best for +## Links +``` + +### Section content rules + +- **What this is**: One paragraph. Lead with: "Customer.io Node.js SDK for sending events, identifying users, and managing customer data via the Track API." Add one sentence on what the SDK wraps and one sentence on the typical caller (backend Node service authenticating with site id and API key). +- **Install**: Show the `npm install customerio-node` command. Include the current version pulled from `package.json` as a parenthetical: `npm install customerio-node` (current version: `X.Y.Z`). If `package.json` is missing for any reason, omit the version rather than guess. +- **Initialize**: Two fenced code blocks, one TypeScript and one JavaScript. Show importing the client, constructing it with site id and API key, and selecting a region. Mirror the patterns already in `README.md` or `examples/`. Do not invent new constructor shapes. +- **Common calls**: Pick the 5 to 7 most-used methods on the exported client by inspecting `lib/` and `examples/`. Likely candidates: `identify`, `track`, `trackAnonymous`, `destroy`, `addDevice`, `deleteDevice`, `mergeCustomers`, plus any transactional API helper such as `sendEmail` if it exists in this SDK. For each method, give a one-line purpose and a minimal code snippet (3 to 6 lines). Do not list every method on the client. Pick the high-traffic ones. +- **Auth and regions**: One short paragraph each on: + - Site id and API key: explain that these are Track API credentials, where they live in the Customer.io UI (Account Settings, API Credentials, Track API Keys), and that they are workspace-scoped. + - Region: US vs EU. Mention the region selector in the constructor and the default. Do not guess; read it from `lib/regions.ts`. +- **When to use this vs cdp-analytics-js**: Two to four lines. Server-side use this SDK; it talks to the Track API. Client-side or pipelines-style ingestion goes through `cdp-analytics-js`, which targets the Pipelines API. Make the contrast crisp so a routing agent can choose without reading either README. +- **Best for**: One line. "Backend Node services, serverless platforms like Vercel and AWS Lambda, and Express, Fastify, or Nest apps." +- **Links**: Bulleted list. Include: + - Canonical API docs: https://docs.customer.io/api/ + - Track API guide: https://docs.customer.io/integrations/api/track/ + - This repository: https://github.com/customerio/customerio-node + - npm package: https://www.npmjs.com/package/customerio-node + +## Style rules + +- No em dashes. Use hyphens, commas, periods, or rewrite. This applies to every line. +- No filler phrases ("It is worth noting", "Let's dive in"). State the thing. +- Active voice. Short paragraphs. +- Code blocks must be valid and import the right symbols. Do not invent method names. If you are unsure whether a method exists, omit it. +- Do not include a changelog, contributing guide, or test instructions. Those live elsewhere. +- Do not include AI authorship attribution anywhere. + +## Output + +Write the final document to `AGENTS.md` at the repository root. The workflow will diff and commit. If nothing changed, exit cleanly without writing. diff --git a/.github/workflows/agents-md-update.yml b/.github/workflows/agents-md-update.yml new file mode 100644 index 0000000..be3eaad --- /dev/null +++ b/.github/workflows/agents-md-update.yml @@ -0,0 +1,133 @@ +name: agents md update + +on: + workflow_dispatch: + push: + branches: + - main + paths-ignore: + - 'AGENTS.md' + +permissions: + contents: write + id-token: write + +concurrency: + group: agents-md-update-main + cancel-in-progress: true + +jobs: + update: + name: Update AGENTS.md + if: >- + github.event_name == 'workflow_dispatch' || + ( + github.event_name == 'push' && + github.ref == 'refs/heads/main' && + !contains(github.event.head_commit.message, '[skip agents-md]') && + !startsWith(github.event.head_commit.message, 'docs: update agents md') + ) + runs-on: cio-ubuntu-slim + timeout-minutes: 20 + + steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.CIO_CLAUDE_ASSISTANT_APP_ID }} + private-key: ${{ secrets.CIO_CLAUDE_ASSISTANT_APP_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@v6 + with: + token: ${{ steps.app-token.outputs.token }} + fetch-depth: 0 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: '22' + cache: npm + cache-dependency-path: package-lock.json + + - name: Install Bun + uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 + with: + bun-version: 1.3.6 + + - name: Capture Bun path + id: bun-path + run: echo "path=$(which bun)" >> "$GITHUB_OUTPUT" + + - name: Authenticate to Google Cloud + id: auth + uses: google-github-actions/auth@v2 + with: + workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: ${{ secrets.VERTEX_GCP_SERVICE_ACCOUNT }} + + - name: Run Claude AGENTS.md updater + id: claude-code + uses: anthropics/claude-code-action/base-action@1844b756107a5f85fc3e23a1c5328ddd6f958f82 + with: + path_to_bun_executable: ${{ steps.bun-path.outputs.path }} + prompt_file: .github/prompts/update-agents-md.md + settings: | + { + "model": "claude-sonnet-4-6[1m]", + "env": { + "DISABLE_TELEMETRY": "1", + "DISABLE_ERROR_REPORTING": "1", + "DISABLE_AUTOUPDATER": "1", + "DISABLE_BUG_COMMAND": "1", + "DISABLE_NON_ESSENTIAL_MODEL_CALLS": "1", + "DISABLE_COST_WARNINGS": "1", + "DISABLE_TERMINAL_TITLE": "1", + "CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL": "1" + } + } + claude_args: | + --effort medium + --tools "Read,Glob,Grep,Edit,MultiEdit,Write,Bash" + --allowedTools "Read,Glob,Grep,Edit,MultiEdit,Write,Bash(git diff:*),Bash(git status:*)" + use_vertex: "true" + env: + ANTHROPIC_VERTEX_PROJECT_ID: ${{ steps.auth.outputs.project_id }} + CLOUD_ML_REGION: global + ANTHROPIC_DEFAULT_SONNET_MODEL: "claude-sonnet-4-6[1m]" + ANTHROPIC_DEFAULT_HAIKU_MODEL: claude-haiku-4-5@20251001 + ANTHROPIC_DEFAULT_OPUS_MODEL: claude-opus-4-6@default + + - name: Remove transient Google credentials + run: rm -f gha-creds-*.json + + - name: Guard update scope + run: | + unexpected="$(git status --porcelain | awk '{print $2}' | grep -Ev '^AGENTS\.md$' || true)" + if [ -n "$unexpected" ]; then + echo "::error::The AGENTS.md updater changed files outside the allowed scope:" + echo "$unexpected" + exit 1 + fi + + - name: Commit and push updates + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + if git diff --quiet -- AGENTS.md; then + echo "AGENTS.md is already current." + exit 0 + fi + + git fetch origin main + if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then + echo "::notice::main advanced while the AGENTS.md updater was running; skipping push. The newer push will run its own updater." + exit 0 + fi + + git config user.name "cio-claude-assistant[bot]" + git config user.email "cio-claude-assistant[bot]@users.noreply.github.com" + git add AGENTS.md + git commit -m "docs: update agents md [skip agents-md]" + git push origin HEAD:main