diff --git a/trigger-dev/github-ai-agent/.env.example b/trigger-dev/github-ai-agent/.env.example new file mode 100644 index 0000000..2335058 --- /dev/null +++ b/trigger-dev/github-ai-agent/.env.example @@ -0,0 +1,19 @@ +# Hookdeck +HOOKDECK_API_KEY= # Project API key (Dashboard -> Project Settings -> API Keys) +GITHUB_WEBHOOK_SECRET= # Shared secret for GitHub HMAC verification + +# Trigger.dev (Production only — this demo deploys to prod and uses prod for Hookdeck HTTP triggers) +TRIGGER_SECRET_KEY= # Production API key from dashboard (tr_prod_...) +TRIGGER_PROJECT_REF= # Project ref from Trigger.dev dashboard (e.g., proj_xxxx) + +# GitHub (used by tasks at runtime) +GITHUB_REPO= # e.g., hookdeck/hookdeck-demos +GITHUB_ACCESS_TOKEN= # GitHub API token with repo scope (tasks + deploy sync) +GITHUB_LABELS= # CSV of labels for issue labeler (auto-fetched during setup) + +# AI (used by tasks at runtime) +ANTHROPIC_API_KEY= # From console.anthropic.com + +# Slack (used by handle-push task) +SLACK_WEBHOOK_URL= # Incoming webhook URL from Slack app settings +# GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY=true # optional: limit Slack summaries to default branch only diff --git a/trigger-dev/github-ai-agent/.gitignore b/trigger-dev/github-ai-agent/.gitignore new file mode 100644 index 0000000..7f7eb07 --- /dev/null +++ b/trigger-dev/github-ai-agent/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +.env +.trigger/ +.hookdeck-source-url diff --git a/trigger-dev/github-ai-agent/.plan/trigger-dev-collaboration-build-plan.md b/trigger-dev/github-ai-agent/.plan/trigger-dev-collaboration-build-plan.md new file mode 100644 index 0000000..b41f33b --- /dev/null +++ b/trigger-dev/github-ai-agent/.plan/trigger-dev-collaboration-build-plan.md @@ -0,0 +1,962 @@ +# Trigger.dev x Hookdeck: Validated Build Plan + +**Date:** March 19, 2026 +**Target delivery:** ~March 30, 2026 (2 weeks from March 16 call) +**Author:** Phil Leggetter + +--- + +## Execution status + +*Last updated: March 2026* + +| Phase | Status | +|-------|--------| +| **Phase 1–3** | **Done** — Trigger.dev deploy, Hookdeck resources (incl. Pattern A + B connections from `setup-hookdeck.sh`), GitHub webhook registered. | +| **Phase 4 (Pattern A)** | **Mostly done** — Issue labeler, PR AI review, push → Slack validated; Hookdeck + Trigger.dev dashboards checked for those paths. **Open:** send an **unsupported** GitHub event (e.g. `star`, if enabled on the webhook) and confirm Pattern A behavior in `github-webhook-handler` (ignored / default branch of `switch`). | +| **Phase 4b (Pattern B)** | **Next** — Exercise the **header-filtered** connections (`github-to-handle-pr`, `github-to-handle-issue`, `github-to-handle-push`) end-to-end: same repo events, verify each task runs **only** for its event type, Hookdeck shows **per-connection** delivery, and each task still calls `verifyHookdeckEvent` independently. Optionally confirm an unsupported event **does not** create deliveries on Pattern B connections (or only hits Pattern A if both are active — document actual wiring). | +| **Pros / cons** | **Next** — Validate the trade-off table below against real runs (observability, deploy vs dashboard change, noise). Capture 2–3 sentences for the guide. | +| **Phase 5 (Guide)** | **After** Phase 4 complete + Pattern B tested + trade-offs agreed — draft the Trigger.dev + Hookdeck guide with screenshots, both patterns, verification chain, transformation. | + +**Guide dependencies:** Pattern B E2E + trade-off notes → then Phase 5. Skills repo PR to `triggerdotdev/skills` remains **after** the guide is published (see Open Items). + +--- + +## Resolved Technical Questions + +The context doc flagged five open questions. Here's what the research confirmed. + +### 1. Can Hookdeck filter rules match on request headers? + +**Yes, confirmed.** Hookdeck filters support a Headers tab alongside Body, Query, and Path. The JSON syntax for header filtering uses the same operators as body filters. + +Example for GitHub event type filtering: + +```json +{ + "X-GitHub-Event": { + "$eq": "pull_request" + } +} +``` + +The CLI also supports `--filter-headers '{"x-github-event":"pull_request"}'`. This confirms Pattern B (Hookdeck routing to different tasks per event type) is fully viable using header-based filter rules. + +### 2. What verification headers does Hookdeck add when forwarding? + +**Confirmed: two headers.** + +- `x-hookdeck-verified: true` — added when source verification is enabled and the incoming request passes signature verification. Confirms the original webhook was authenticated. +- `x-hookdeck-signature` — always added, generated using the Hookdeck project's signing secret and the forwarded request data. This lets the destination independently verify the request came through Hookdeck. + +The original provider headers (e.g., `X-Hub-Signature-256` from GitHub) are also forwarded by default, though the signature won't re-verify because the body may be transformed. + +**Implication for the guide:** The verification chain is: GitHub HMAC verified at Hookdeck source, then `x-hookdeck-verified: true` confirms this downstream. The Trigger.dev task receives only verified events. The guide should explain this chain clearly and recommend trusting it rather than attempting to re-verify the GitHub HMAC after transformation. + +### 3. Can transformations access request headers? + +**Yes, confirmed.** The transformation `request` object has this shape: + +```typescript +{ + headers: { [key: string]: string }; + body: string | boolean | number | object | null; + query: string; + parsed_query: object; + path: string; +} +``` + +The `addHandler("transform", (request, context) => { ... return request; })` pattern is confirmed. You can read headers and modify the body. The `context` object contains `{ connection: Connection }`. + +**Validated transformation code** for wrapping the payload with the GitHub event type: + +```javascript +addHandler("transform", (request, context) => { + request.body = { + payload: { + _hookdeck: { + verified: request.headers["x-hookdeck-verified"] === "true", + signature: request.headers["x-hookdeck-signature"], + }, + event: request.headers["x-github-event"], + action: request.body.action, + ...request.body, + }, + }; + return request; +}); +``` + +**Note:** The handler must return a valid request object with a valid `content-type` header. Existing Hookdeck transformations in the Radar project confirm this pattern works (e.g., `grafana-to-public-alert` transformation reads `request.body` and sets `request.headers`). + +### 4. Trigger.dev task trigger API format + +**Confirmed from docs.** + +**Endpoint:** `POST https://api.trigger.dev/api/v1/tasks/{taskIdentifier}/trigger` + +**Authentication:** `Authorization: Bearer ` — keys start with `tr_dev_`, `tr_prod_`, or `tr_stg_`. + +**Request body:** + +```json +{ + "payload": { ... }, + "context": { ... }, + "options": { + "idempotencyKey": "...", + "concurrencyKey": "...", + "queue": { "name": "...", "concurrencyLimit": 1 } + } +} +``` + +Only `payload` is required. The `context` and `options` fields are optional. + +**Task code pattern (TypeScript):** + +```typescript +import { task } from "@trigger.dev/sdk"; + +export const webhookHandler = task({ + id: "webhook-handler", + run: async (payload: Record) => { + console.log("Received webhook:", payload); + // payload is the unwrapped data from the "payload" field + }, +}); +``` + +**Response:** `{ "id": "run_1234" }` on success (200). + +### 5. Payload size considerations + +Not explicitly documented for either platform. GitHub webhook payloads are typically small (a few KB for most events, up to ~100KB for large PR or push events with many commits). No practical concern for this demo. + +--- + +## Current State of Trigger.dev's Hookdeck Guide + +The existing guide at `trigger.dev/docs/guides/examples/hookdeck-webhook` is minimal — a single pattern: + +1. Create a destination pointing to `https://api.trigger.dev/api/v1/tasks//trigger` with Bearer auth +2. Add a transformation that wraps the body: `request.body = { payload: { ...request.body } }` +3. Create a connection linking source to destination + +It shows a generic `webhookHandler` task receiving `Record`. No GitHub-specific patterns, no header filtering, no multi-connection routing. This is the baseline we're improving on. + +--- + +## Hookdeck Project Setup + +**New project needed.** The current Hookdeck account has many projects across several orgs ("Demos", "Examples", etc.). The demo should use a new dedicated project. + +**Recommended:** Create a new project in the "Demos" org called `trigger-dev-github-webhooks` (or similar). + +### Resources to create during build + +**Source (shared by both patterns):** + +| Resource | Configuration | +|----------|--------------| +| Name | `github` | +| Verification | GitHub (HMAC SHA-256 using `X-Hub-Signature-256`) | +| Allowed methods | POST | +| Webhook secret | Set during GitHub webhook registration | + +**Transformation (shared by all connections):** + +| Resource | Configuration | +|----------|--------------| +| Name | `trigger-wrapper` | +| Code | See transformation code below | + +```javascript +addHandler("transform", (request, context) => { + request.body = { + payload: { + _hookdeck: { + verified: request.headers["x-hookdeck-verified"] === "true", + signature: request.headers["x-hookdeck-signature"], + }, + event: request.headers["x-github-event"], + action: request.body.action, + ...request.body, + }, + }; + return request; +}); +``` + +### Pattern A: Single Main Task (Fan-out) + +| Resource | Type | Configuration | +|----------|------|--------------| +| `trigger-dev-main` | Destination | URL: `https://api.trigger.dev/api/v1/tasks/github-webhook-handler/trigger`, Auth: Bearer `TRIGGER_SECRET_KEY` | +| `github → trigger-dev-main` | Connection | Source: `github`, Destination: `trigger-dev-main`, Transform: `trigger-wrapper`, Retry: 5 attempts / linear | + +The single Trigger.dev task receives all event types and uses the `event` field to fan out: + +```typescript +import { task } from "@trigger.dev/sdk"; + +// Main handler — receives all GitHub events via Hookdeck +export const githubWebhookHandler = task({ + id: "github-webhook-handler", + run: async (payload: { + event: string; + action?: string; + [key: string]: unknown; + }) => { + switch (payload.event) { + case "pull_request": + // trigger handlePR task + break; + case "issues": + // trigger handleIssue task + break; + case "push": + // trigger handlePush task + break; + default: + console.log(`Unhandled event: ${payload.event}`); + } + }, +}); +``` + +### Pattern B: Hookdeck Routes to Different Tasks + +| Resource | Type | Configuration | +|----------|------|--------------| +| `trigger-dev-pr` | Destination | URL: `.../tasks/handle-pr/trigger`, Auth: Bearer `TRIGGER_SECRET_KEY` | +| `trigger-dev-issues` | Destination | URL: `.../tasks/handle-issue/trigger`, Auth: Bearer `TRIGGER_SECRET_KEY` | +| `trigger-dev-push` | Destination | URL: `.../tasks/handle-push/trigger`, Auth: Bearer `TRIGGER_SECRET_KEY` | +| `github → trigger-dev-pr` | Connection | Filter (headers): `{ "X-GitHub-Event": { "$eq": "pull_request" } }`, Transform: `trigger-wrapper` | +| `github → trigger-dev-issues` | Connection | Filter (headers): `{ "X-GitHub-Event": { "$eq": "issues" } }`, Transform: `trigger-wrapper` | +| `github → trigger-dev-push` | Connection | Filter (headers): `{ "X-GitHub-Event": { "$eq": "push" } }`, Transform: `trigger-wrapper` | + +Each Trigger.dev task is purpose-built: + +```typescript +import { task } from "@trigger.dev/sdk"; + +export const handlePR = task({ + id: "handle-pr", + run: async (payload: { + event: "pull_request"; + action: string; + number: number; + pull_request: Record; + repository: Record; + }) => { + console.log(`PR #${payload.number}: ${payload.action}`); + // PR-specific logic + }, +}); + +export const handleIssue = task({ + id: "handle-issue", + run: async (payload: { + event: "issues"; + action: string; + issue: Record; + repository: Record; + }) => { + // Issue-specific logic + }, +}); + +export const handlePush = task({ + id: "handle-push", + run: async (payload: { + event: "push"; + ref: string; + commits: Array>; + repository: Record; + }) => { + // Skip non-default branch pushes + // Summarize commits with LLM + // Post to Slack + }, +}); +``` + +--- + +## Build Steps (Execution Order) + +### Phase 0: Rename and reorganize `hookdeck-demos` repo + +Before adding the Trigger.dev demo, rename and reorganize the existing repo. + +**Rename:** `hookdeck/hookdeck-demos` → `hookdeck/hookdeck-demoss` (plural). GitHub automatically redirects the old URL, so existing links won't break. Update any CI workflows, bookmarks, or documentation that reference the old name. + +**Reorganize:** Adopt a consistent `vendor/use-case/` directory convention. Hookdeck itself is treated as a vendor — the demos are typically feature demos. + +**Current state → new location:** + +| Current directory | New location | Notes | +|---|---|---| +| `ai/deepgram/` | `deepgram/stt-tts/` | Vendor-first, use-case second | +| `stripe-fetch-before-process/` | `stripe/fetch-before-process/` | | +| `shopify-webhooks-at-scale/` | `shopify/webhooks-at-scale/` | | +| `deduplication/` | `hookdeck/deduplication/` | Hookdeck feature demo | +| `transformation-reording/` | `hookdeck/transformation-reordering/` | Fix the typo while we're at it | +| `session-filters/` | `hookdeck/session-filters/` | Hookdeck feature demo | +| `cli-overview/` | `hookdeck/cli-overview/` | Hookdeck tooling demo | +| `general/` | `hookdeck/general/` | General webhook handling | +| `demo_scripts/` | `hookdeck/demo-scripts/` | Normalize to kebab-case | +| `tmux-presenter/` | `_shared/tmux-presenter/` | Shared utility for running tmux-based live demos — not a vendor demo itself, but used by demos across vendors | + +**New directory after reorg + Trigger.dev demo added:** + +``` +hookdeck-demos/ + hookdeck/ + cli-overview/ + deduplication/ + demo-scripts/ + general/ + session-filters/ + transformation-reordering/ + stripe/ + fetch-before-process/ + shopify/ + webhooks-at-scale/ + deepgram/ + stt-tts/ + trigger-dev/ + github-ai-agent/ # ← the new demo + _shared/ + tmux-presenter/ # shared utility for tmux-based live demos + .prettierrc + README.md +``` + +**Implementation notes:** + +- Use `git mv` for all renames so history is preserved. +- Update the root `README.md` to reflect the new structure. +- Update any internal path references within each demo (READMEs, scripts, CI workflows if any). +- This is a single PR, merged before the Trigger.dev demo work begins. +- The convention going forward: every new demo goes in `vendor/use-case/`. Hookdeck is a vendor like any other. + +### Phase 1: Trigger.dev project setup + +1. Create a new Trigger.dev project (or use an existing dev project) +2. Deploy the task definitions (all tasks for both patterns) +3. Note the `TRIGGER_SECRET_KEY` for Hookdeck destination auth +4. Verify tasks appear in the Trigger.dev dashboard + +### Phase 2: Hookdeck project setup + +1. Create a new Hookdeck project in the "Demos" org +2. Create the `github` source with GitHub verification +3. Create the `trigger-wrapper` transformation +4. **Pattern A:** Create destination + connection (no filter, transformation applied) +5. **Pattern B:** Create 3 destinations + 3 connections (each with header filter + shared transformation) + +### Phase 3: GitHub webhook registration + +1. Choose a test repo (or create one) +2. Register a webhook pointing to the Hookdeck source URL +3. Set the webhook secret (same value configured in Hookdeck source verification) +4. Select events: `pull_request`, `issues`, `push` + +### Phase 4: End-to-end testing + +**Pattern A (single connection → `github-webhook-handler` → fan-out)** — *largely complete* + +1. ~~Create a test issue~~ → `handle-issue` via router +2. ~~Open a test PR~~ → `handle-pr` via router +3. ~~Push a commit~~ → `handle-push` via router (incl. Slack) +4. ~~Check Hookdeck dashboard~~ for those events: received, verified, transformed, delivered +5. ~~Check Trigger.dev dashboard~~: runs for router + child tasks with correct payloads +6. **Remaining:** **Unsupported event** — Enable a webhook event **not** handled in the router (e.g. `star` or `watch`) *or* simulate payload; confirm router hits `default` / “Ignoring event” and **no** erroneous child triggers. Document result for the guide. + +**Pattern B (per-event Hookdeck connections → dedicated tasks)** — *next* + +7. With `setup-hookdeck.sh` connections active, trigger **issues** / **pull_request** / **push** and confirm **each** flows through the **matching** connection only (`github-to-handle-*`), destinations point at `handle-pr` / `handle-issue` / `handle-push` directly (not only via router). Compare Hookdeck **connection-level** logs vs Pattern A’s single connection. +8. Confirm **verification** runs in each task (Pattern B path). Optionally compare run counts vs Pattern A for the same repo activity (duplicate deliveries if **both** Pattern A and B connections are enabled — clarify in guide: typically test Pattern B with understanding that setup script creates **both** patterns; may need to pause/disable Pattern A connection for clean Pattern B-only testing, or document dual-delivery behavior). + +### Phase 4b: Pros / cons validation (for guide) + +Before Phase 5, sanity-check the **Trade-offs** table (below) against experience: routing in code vs Hookdeck, deploy vs dashboard for new event types, observability, retries. Add a short “When to use A vs B” subsection outline for the guide. + +### Phase 5: Guide drafting + +**Prerequisites:** Phase 4 item (6) done; Phase 4 Pattern B steps (7–8) done; Phase 4b notes captured. + +1. Write the guide based on validated patterns and real screenshots +2. Include both patterns with trade-off discussion (use Phase 4b notes) +3. Cover: setup, verification chain, transformation, testing, when to use which pattern +4. Optional: link from Trigger.dev docs / skills repo after publish + +--- + +## Trade-offs for the Guide (Pattern A vs Pattern B) + +| Consideration | Pattern A (Fan-out) | Pattern B (Hookdeck Routing) | +|--------------|--------------------|-----------------------------| +| Hookdeck resources | 1 connection, 1 destination | N connections, N destinations | +| Routing logic | In Trigger.dev task code | In Hookdeck filter rules | +| Adding new event types | Code change + deploy | New connection in Hookdeck dashboard | +| Observability | All events in one Hookdeck connection | Each event type visible separately | +| Retry granularity | Same retry policy for all events | Per-event-type retry policies | +| Best for | Simple setups, few event types | Complex routing, many event types, per-type config | + +--- + +## Project Setup Automation + +The goal is: clone the repo, add API keys to a `.env` file, run a setup script, and everything is configured. No clicking around in dashboards. + +### Developer experience (target) + +``` +git clone https://github.com/hookdeck/hookdeck-demos +cd hookdeck-demos/trigger-dev/github-ai-agent +cp .env.example .env +# Edit .env with your keys (see below) +npm install +npm run setup # deploys Trigger.dev tasks (Production) + Hookdeck + GitHub webhook +npm run deploy # redeploy task code to Production after changes +``` + +### What goes in `.env` + +```bash +# Hookdeck +HOOKDECK_API_KEY= # Project API key (from Hookdeck dashboard → Project Settings → API Keys) +GITHUB_WEBHOOK_SECRET= # Shared secret for GitHub webhook HMAC verification + +# Trigger.dev +TRIGGER_SECRET_KEY= # Production API key (tr_prod_...) — demo is Production-only; Hookdeck uses this Bearer token +TRIGGER_PROJECT_REF= # Project ref from Trigger.dev dashboard (e.g., proj_xxxx) +``` + +Both platforms require you to create a project manually first (Hookdeck project, Trigger.dev project) and grab the API keys. There's no way around that initial step. But everything after that is scripted. + +### Trigger.dev side: fully automatable + +Trigger.dev's workflow is already code-first and well suited to this: + +- **Project config:** `trigger.config.ts` at the repo root defines the project ref, task directories, retry settings, etc. This is checked into version control. +- **Task definitions:** TypeScript files in a `/trigger` directory. Each task is a file exporting a `task()` call. This is the code that runs on Trigger.dev's infrastructure. +- **Local dev:** `npx trigger.dev@latest dev` starts a local dev server that registers tasks with the Trigger.dev platform, watches for changes, and executes tasks locally. Tasks show up in the Trigger.dev dashboard immediately. +- **Deploy:** `npx trigger.dev@latest deploy` bundles and deploys tasks to Trigger.dev Cloud. One command, no manual steps. Supports `--env dev` / `--env prod` / `--env staging`. +- **Init (first time only):** `npx trigger.dev@latest init` scaffolds the config file and trigger directory. We'd run this once when setting up the repo, then check the result in. + +So the Trigger.dev side of setup is just `npm install` + `npx trigger.dev@latest deploy` (for cloud). The task code, config, and directory structure are all in the repo. No separate resource creation step — tasks are registered as part of the deploy. + +**Important ordering:** Trigger.dev tasks need to be deployed *before* Hookdeck destinations are created, because the Hookdeck destinations point to specific task trigger URLs (e.g., `.../tasks/handle-pr/trigger`). If the tasks don't exist yet on Trigger.dev, the URLs will return 404s. The setup script should deploy to Trigger.dev first, then create Hookdeck resources, then register the GitHub webhook. + +For local development, `npx trigger.dev@latest dev` replaces the deploy step — it starts a local server that registers tasks with the platform in dev mode. Tasks run on your machine but appear in the Trigger.dev dashboard and can receive events. + +### Hookdeck side: fully automatable via CLI + +The Hookdeck CLI (`hookdeck gateway connection upsert`) is idempotent and supports every configuration option we need as flags. Key flags confirmed from the CLI reference: + +**Source configuration:** +- `--source-name` — source name (creates inline if doesn't exist) +- `--source-type` — `GITHUB` enables built-in GitHub HMAC verification +- `--source-webhook-secret` — the shared secret for verification +- `--source-allowed-http-methods` — restrict to POST + +**Destination configuration:** +- `--destination-name` — destination name (creates inline if doesn't exist) +- `--destination-type` — `HTTP` +- `--destination-url` — the Trigger.dev task trigger endpoint +- `--destination-auth-method` — `bearer` +- `--destination-bearer-token` — the `TRIGGER_SECRET_KEY` + +**Rules (filters, transforms, retries):** +- `--rule-filter-headers` — JSON filter on request headers (for Pattern B) +- `--rule-transform-code` — inline transformation code (for creating new) +- `--rule-transform-name` — reference an existing transformation by name or ID (for sharing) +- `--rule-retry-count` — number of retry attempts +- `--rule-retry-strategy` — `linear` or `exponential` +- `--rules-file` — path to a JSON file containing the full rules array (for complex configs) + +**Operational:** +- `--dry-run` — preview changes without applying +- `hookdeck ci --api-key $HOOKDECK_API_KEY` — authenticate non-interactively (for scripts/CI) + +### Trigger.dev deploy (no separate script needed) + +The Trigger.dev CLI already handles everything. `npx trigger.dev@latest deploy` reads the project ref from `trigger.config.ts`, authenticates via `TRIGGER_SECRET_KEY` from the environment, bundles the TypeScript task files, uploads them, and registers the tasks. No wrapper script needed. + +This runs first in the setup flow because Hookdeck destinations point to specific task trigger URLs (e.g., `.../tasks/handle-pr/trigger`). Those endpoints need to exist before Hookdeck tries to deliver to them. + +**Runtime environment variables:** The tasks themselves need `GITHUB_TOKEN` and `ANTHROPIC_API_KEY` at runtime. Because tasks run on Trigger.dev's infrastructure (not locally), these need to be set in the Trigger.dev dashboard under Project Settings → Environment Variables, or synced via the `syncEnvVars` build extension. Worth investigating during the build whether `syncEnvVars` can pull from the `.env` file automatically. + +### The Hookdeck setup script + +The Hookdeck setup script (`scripts/setup-hookdeck.sh`) uses `hookdeck ci` for auth and `hookdeck gateway connection upsert` for idempotent resource creation. Because transformations can be created inline via `--rule-transform-code` or referenced by name via `--rule-transform-name`, we have two options: + +**Option A: Inline transformation on every connection (simpler, self-contained):** + +Each `connection upsert` includes the transformation code directly. Hookdeck will create the transformation if it doesn't exist and reuse it if the name matches. This keeps the script self-contained but means the transformation code is repeated in each command. + +**Option B: Shared transformation referenced by name (cleaner, DRY):** + +Create the transformation once (first connection creates it with `--rule-transform-code` and `--rule-transform-name`), then subsequent connections reference it with `--rule-transform-name` only. This is cleaner but depends on execution order. + +**Recommended: Option B with a `--rules-file`** for the complex Pattern B connections. + +### Draft setup script structure + +```bash +#!/bin/bash +set -euo pipefail + +# Load environment variables +source .env + +echo "Authenticating with Hookdeck..." +hookdeck ci --api-key "$HOOKDECK_API_KEY" + +TRIGGER_BASE_URL="https://api.trigger.dev/api/v1/tasks" + +# Read transformation code from file +TRANSFORM_CODE=$(cat hookdeck/trigger-wrapper.js) + +echo "" +echo "=== Pattern A: Single main task (fan-out) ===" + +hookdeck gateway connection upsert "github-to-main-handler" \ + --source-name "github" \ + --source-type GITHUB \ + --source-webhook-secret "$GITHUB_WEBHOOK_SECRET" \ + --source-allowed-http-methods "POST" \ + --destination-name "trigger-dev-main" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/github-webhook-handler/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-transform-name "trigger-wrapper" \ + --rule-transform-code "$TRANSFORM_CODE" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear + +echo "" +echo "=== Pattern B: Hookdeck routes to per-event tasks ===" + +# PR events +hookdeck gateway connection upsert "github-to-handle-pr" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-pr" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-pr/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"pull_request"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear + +# Issue events +hookdeck gateway connection upsert "github-to-handle-issue" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-issues" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-issue/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"issues"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear + +# Push events +hookdeck gateway connection upsert "github-to-handle-push" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-push" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-push/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"push"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear + +echo "" +echo "Setup complete. Hookdeck source URL:" +hookdeck gateway source get github --output json | jq -r '.url' +echo "" +echo "Register this URL as your GitHub webhook endpoint." +``` + +### Proposed repo structure + +See "Demo Task Design" section below for the final repo structure, which includes the GitHub webhook setup script and updated task files. + +### What can't be automated + +- **Creating the Hookdeck project itself.** The CLI manages resources within a project, but creating the project is done in the dashboard. The API key is per-project. +- **Creating the Trigger.dev project.** Same story — you create the project in the dashboard, then use the CLI for everything else. +- **Registering the GitHub webhook.** Automatable — see "GitHub Webhook Registration" section below. +- **Selecting which pattern to use.** Both patterns share the same source and transformation, so running the setup script creates resources for both. The user could comment out one pattern in the script if they only want one. + +### npm scripts (package.json) + +See "GitHub Webhook Registration" section below for the full updated scripts including `setup:github`. + +### Things to validate during build + +- Whether `--rule-transform-name` reuses an existing transformation by name (vs. creating a duplicate). The docs suggest `upsert` is idempotent, but this needs confirmation with transformations specifically. +- Whether `--source-type GITHUB` automatically configures HMAC verification using the `--source-webhook-secret`, or whether additional config flags are needed. +- Whether all connections can share the same source (the `upsert` command references sources by name, so the second call should find the existing source). +- The exact `--rule-filter-headers` JSON syntax — the filter operator might need to be lowercase `x-github-event` rather than `X-GitHub-Event` (headers are case-insensitive in HTTP but Hookdeck's filter matching may be case-sensitive). + +### GitHub Webhook Registration + +This can be automated with `gh api`. The `gh` CLI ships with authentication built in (the user runs `gh auth login` once), and the repos webhooks API lets you create webhooks programmatically: + +```bash +#!/bin/bash +# scripts/setup-github-webhook.sh +set -euo pipefail + +source .env + +# Required: GITHUB_REPO (e.g., "hookdeck/trigger-dev-github-webhooks") +# Required: GITHUB_WEBHOOK_SECRET (same value used in Hookdeck source verification) +# Required: HOOKDECK_SOURCE_URL (output from setup-hookdeck.sh) + +if [ -z "${GITHUB_REPO:-}" ]; then + echo "Error: GITHUB_REPO not set (e.g., hookdeck/trigger-dev-github-webhooks)" + exit 1 +fi + +if [ -z "${HOOKDECK_SOURCE_URL:-}" ]; then + echo "Getting Hookdeck source URL..." + HOOKDECK_SOURCE_URL=$(hookdeck gateway source get github --output json | jq -r '.url') +fi + +echo "Creating GitHub webhook for $GITHUB_REPO..." +echo " URL: $HOOKDECK_SOURCE_URL" +echo " Events: pull_request, issues, push" + +gh api "repos/$GITHUB_REPO/hooks" \ + --method POST \ + -f "name=web" \ + -f "config[url]=$HOOKDECK_SOURCE_URL" \ + -f "config[content_type]=json" \ + -f "config[secret]=$GITHUB_WEBHOOK_SECRET" \ + -f "events[]=pull_request" \ + -f "events[]=issues" \ + -f "events[]=push" \ + -f "active=true" + +echo "GitHub webhook created successfully." +``` + +This means the full setup becomes: `npm run setup` (Hookdeck) then `npm run setup:github` (webhook registration). Or we combine them into a single `npm run setup` that runs both sequentially. + +The updated npm scripts: + +```json +{ + "scripts": { + "setup": "npm run deploy && bash scripts/setup-hookdeck.sh && bash scripts/setup-github-webhook.sh", + "setup:hookdeck": "bash scripts/setup-hookdeck.sh", + "setup:github": "bash scripts/setup-github-webhook.sh", + "setup:dry-run": "DRY_RUN=true bash scripts/setup-hookdeck.sh", + "dev": "npx trigger.dev@latest dev", + "deploy": "npx trigger.dev@latest deploy" + } +} +``` + +The order matters: `deploy` first (so Trigger.dev task endpoints exist), Hookdeck resources second (destinations point to those endpoints), GitHub webhook last (source URL comes from Hookdeck). + +**Prerequisites for GitHub automation:** The user needs `gh` installed and authenticated (`gh auth login`). The `.env` needs an additional `GITHUB_REPO` variable. This is a reasonable ask for a developer audience. + +**Idempotency note:** The GitHub webhooks API doesn't have an upsert — calling it twice creates a duplicate webhook. The script should check for an existing webhook first and update it (using `PATCH /repos/{owner}/{repo}/hooks/{hook_id}`) or skip if one already exists pointing to the same URL. This is worth implementing for robustness but not essential for v1. + +--- + +## Event Verification in Trigger.dev Tasks + +### The problem + +Trigger.dev tasks only receive the `payload` object — they don't have access to the HTTP headers from the incoming request. So the `x-hookdeck-verified` and `x-hookdeck-signature` headers that Hookdeck adds are consumed by the Trigger.dev API and never reach the task code. + +This means the task has no way to verify the event came through Hookdeck unless we explicitly inject that information into the payload. + +### The solution: transformation injects, task verifies + +The `trigger-wrapper` transformation now injects a `_hookdeck` metadata object into the payload: + +```javascript +// The transformation adds verification data from Hookdeck headers +payload: { + _hookdeck: { + verified: true, // from x-hookdeck-verified header + signature: "abc123...", // from x-hookdeck-signature header + }, + event: "pull_request", + action: "opened", + // ... rest of the GitHub webhook payload +} +``` + +The underscore prefix on `_hookdeck` signals it's metadata injected by the infrastructure, not part of the original GitHub payload. + +### Reusable verification utility + +Verification should be a shared utility function, not a task. Tasks call it synchronously before doing any processing: + +```typescript +// trigger/lib/verify-hookdeck.ts + +export interface HookdeckMeta { + verified: boolean; + signature?: string; +} + +export function verifyHookdeckEvent(payload: { _hookdeck?: HookdeckMeta }): void { + if (!payload._hookdeck) { + throw new Error("Missing _hookdeck metadata — event did not come through Hookdeck"); + } + + if (!payload._hookdeck.verified) { + throw new Error("Event failed Hookdeck source verification"); + } + + // Optionally: verify the signature against the Hookdeck project signing secret + // This is defense-in-depth — the Bearer token on the destination already authenticates + // the request to Trigger.dev, and verified:true confirms Hookdeck verified the source. +} +``` + +### Where verification runs depends on the pattern + +**Pattern A (fan-out):** The router task (`github-webhook-handler`) verifies once. Sub-tasks trust the payload because they were triggered by the router, not by an external HTTP request. + +```typescript +// Pattern A: verify once in the router +export const githubWebhookHandler = task({ + id: "github-webhook-handler", + run: async (payload) => { + verifyHookdeckEvent(payload); // ← verify here, once + + switch (payload.event) { + case "pull_request": + await tasks.trigger("handle-pr", payload); // sub-task trusts the payload + break; + // ... + } + }, +}); +``` + +**Pattern B (Hookdeck routing):** Each task receives events directly from Hookdeck via the Trigger.dev API, so each task must verify independently. + +```typescript +// Pattern B: each task verifies independently +export const handlePR = task({ + id: "handle-pr", + run: async (payload) => { + verifyHookdeckEvent(payload); // ← each task verifies + + // ... PR review logic + }, +}); +``` + +This is a useful trade-off to highlight in the guide: Pattern A centralizes verification (and routing logic) in one place; Pattern B requires each task to handle it, but gives you independent observability and retry per event type. + +### Defense in depth + +The verification chain has three layers: + +1. **Hookdeck source verification** — validates the GitHub HMAC signature (`X-Hub-Signature-256`) at ingress. Events that fail are rejected before they reach any connection. +2. **Trigger.dev destination auth** — the Bearer token (`TRIGGER_SECRET_KEY`) authenticates Hookdeck to the Trigger.dev API. Only requests with the correct token can trigger tasks. +3. **Task-level verification** — the `verifyHookdeckEvent()` check confirms the `_hookdeck.verified` flag is `true`, ensuring the event actually passed source verification (not just that someone had the Bearer token). + +Layers 1 and 2 are handled by infrastructure. Layer 3 is the application-level check. The guide should be explicit about all three. + +--- + +## Demo Task Design + +The demo needs to do something real enough to be compelling, but simple enough that people can follow along and adapt it. The context doc notes that Trigger.dev's fastest-growing use case is AI coding agents triggered by GitHub webhooks — people running Claude Code inside Trigger.dev tasks. The demo should lean into that. + +### Guiding principle + +Each task should do one clear, useful thing that a developer would actually want automated. The tasks should be interesting enough to make someone think "I want to build something like this" but not so complex that they obscure the Hookdeck + Trigger.dev integration, which is the real point. + +### Proposed tasks + +**1. PR Code Review Summary (`handle-pr`)** + +When a PR is opened or updated, generate a summary of the changes and post it as a PR comment. This is the showcase task — it demonstrates the AI agent use case that Trigger.dev is known for. + +What it does: +- Receives a `pull_request` event (action: `opened`, `synchronize`) +- Fetches the PR diff using the GitHub API +- Sends the diff to an LLM (Claude via the Anthropic SDK or Vercel AI SDK) with a prompt like "Summarize the key changes in this PR and flag any potential issues" +- Posts the summary as a comment on the PR via the GitHub API + +Why this works for the demo: +- It's the exact use case Trigger.dev highlights (AI agents triggered by GitHub events) +- It produces a visible result (a PR comment) that's easy to screenshot and put in the guide +- It's genuinely useful — many developers already use similar tools +- It shows why you'd want Hookdeck in the middle: verification, retry on LLM failures, observability + +**2. Issue Labeler (`handle-issue`)** + +When an issue is created, analyze the title and body and auto-apply labels. + +What it does: +- Receives an `issues` event (action: `opened`) +- Reads the issue title and body +- Uses an LLM to classify it (bug, feature request, question, documentation) +- Applies the matching label(s) via the GitHub API + +Why this works: +- Simple, focused, quick to execute +- Shows a different event type flowing through the same Hookdeck source +- Produces a visible result (label appears on the issue) +- Doesn't require fetching additional data (the payload has everything needed) + +**3. Deployment Summary to Slack (`handle-push`)** + +When code is pushed to the main branch, use an LLM to summarize what shipped and post it to a Slack channel. + +What it does: +- Receives a `push` event +- Checks if the push is to the default branch (ignores feature branch pushes) +- Collects the commit messages and list of changed files from the payload +- Sends them to an LLM with a prompt like "Summarize what changed in this deployment in 2-3 sentences, suitable for a team Slack channel. Focus on what shipped, not the individual commits." +- Posts the summary to a Slack channel via the Slack Web API (or an incoming webhook URL) + +Why this works: +- All three tasks now use an LLM, giving the demo a consistent "AI agent" feel +- Slack is a tangible, visible output that every developer relates to +- It's genuinely useful — teams often want a human-readable "what just shipped" message +- Shows a different integration surface (Slack) alongside the GitHub API interactions in the other tasks +- The push payload includes commit messages and file lists, so no extra API calls needed to gather context + +### Pattern A fan-out version + +For Pattern A, the single `github-webhook-handler` task receives all events and triggers the appropriate sub-task: + +```typescript +import { task, tasks } from "@trigger.dev/sdk"; +import { verifyHookdeckEvent } from "./lib/verify-hookdeck"; + +export const githubWebhookHandler = task({ + id: "github-webhook-handler", + run: async (payload: { + event: string; + action?: string; + [key: string]: unknown; + }) => { + verifyHookdeckEvent(payload); // verify once — sub-tasks trust the payload + + switch (payload.event) { + case "pull_request": + if (payload.action === "opened" || payload.action === "synchronize") { + await tasks.trigger("handle-pr", payload); + } + break; + case "issues": + if (payload.action === "opened") { + await tasks.trigger("handle-issue", payload); + } + break; + case "push": + await tasks.trigger("handle-push", payload); + break; + default: + console.log(`Ignoring event: ${payload.event}`); + } + }, +}); +``` + +This shows the fan-out pattern clearly: one entry point, routing in code, sub-tasks for each concern. + +### What the tasks need + +**GitHub API access:** The PR review and issue labeler tasks need a GitHub token with `repo` scope to fetch diffs and post comments/labels. This goes in `.env` as `GITHUB_ACCESS_TOKEN` (synced to Trigger on deploy). The `gh` CLI token can be reused, or the user creates a token in GitHub settings. + +**LLM API access:** All three tasks use Claude for summarization/classification. This goes in `.env` as `ANTHROPIC_API_KEY`. + +**Slack API access:** The deployment summary task posts to a Slack channel. Simplest approach is a Slack incoming webhook URL (no OAuth needed — just create one in the Slack app settings). This goes in `.env` as `SLACK_WEBHOOK_URL`. Alternatively, use a Slack bot token (`SLACK_BOT_TOKEN`) with `chat:write` scope for richer formatting. + +**Updated `.env.example`:** + +```bash +# Hookdeck +HOOKDECK_API_KEY= +GITHUB_WEBHOOK_SECRET= + +# Trigger.dev +TRIGGER_SECRET_KEY= +TRIGGER_PROJECT_REF= + +# GitHub (for tasks that interact with the GitHub API) +GITHUB_REPO= # e.g., hookdeck/hookdeck-demos +GITHUB_ACCESS_TOKEN= # GitHub API token with repo scope (synced to Trigger on deploy) + +# AI (all tasks use Claude for summarization/classification) +ANTHROPIC_API_KEY= + +# Slack (for deployment summary notifications) +SLACK_WEBHOOK_URL= # Incoming webhook URL from Slack app settings +``` + +### Keeping it buildable + +The tasks should use standard, well-documented libraries: +- `@anthropic-ai/sdk` or `ai` (Vercel AI SDK) for LLM calls +- `@octokit/rest` or raw `fetch` for GitHub API calls +- Raw `fetch` for Slack webhook posts (no SDK needed — it's a single POST) +- No heavy frameworks — just TypeScript files in the `/trigger` directory + +Each task file should be self-contained and readable. Someone should be able to open `handle-pr.ts` and understand what it does without reading anything else. + +### Location: `hookdeck/hookdeck-demos` repo + +This demo lives at `trigger-dev/github-ai-agent/` in the [`hookdeck/hookdeck-demos`](https://github.com/hookdeck/hookdeck-demos) repo, following the `vendor/use-case/` convention established in Phase 0. + +``` +trigger-dev/github-ai-agent/ + .env.example + package.json + trigger.config.ts + trigger/ + lib/ + verify-hookdeck.ts # Shared verification utility + github-webhook-handler.ts # Pattern A: fan-out router (verifies here) + handle-pr.ts # AI-powered PR review summary (verifies in Pattern B) + handle-issue.ts # AI-powered issue labeler (verifies in Pattern B) + handle-push.ts # Deploy/push notification (verifies in Pattern B) + hookdeck/ + trigger-wrapper.js + scripts/ + setup-hookdeck.sh + setup-github-webhook.sh + README.md +``` + +Future Trigger.dev demos go alongside: `trigger-dev/stripe-background-jobs/`, etc. + +--- + +## Open Items (Non-blocking) + +- **Shared Slack channel:** Matt offered to create this. Check if it exists yet; if not, follow up. +- **GitHub repo for demo code:** Resolved — using `hookdeck/hookdeck-demos` under `trigger-dev/github-ai-agent/`. +- **Trigger.dev skills repo PR:** After guide is live, submit PR to `triggerdotdev/skills` pointing to the guide. +- **Newsletter timing:** Coordinate with Gareth on when to promote. diff --git a/trigger-dev/github-ai-agent/README.md b/trigger-dev/github-ai-agent/README.md new file mode 100644 index 0000000..8d2cc7c --- /dev/null +++ b/trigger-dev/github-ai-agent/README.md @@ -0,0 +1,209 @@ +# GitHub AI Agent: Hookdeck + Trigger.dev + +AI-powered GitHub automation using Hookdeck for webhook routing and Trigger.dev for task execution. This demo shows two integration patterns with three real tasks. + +## What it does + +GitHub webhooks flow through Hookdeck (verification, routing, transformation) into Trigger.dev tasks that use Claude to automate developer workflows: + +- **PR review summary** — when a PR is opened, fetches the diff, generates a code review summary with Claude, and posts it as a PR comment +- **Issue labeler** — when an issue is created, classifies it with Claude and auto-applies labels (bug, feature, question, documentation) +- **Deployment summary** — when code is pushed to main, summarizes what shipped with Claude and posts to Slack + +## Two patterns + +The demo shows two ways to fan out work after the same Hookdeck ingress: + +**Pattern A — Trigger fan-out (task router):** One Hookdeck connection delivers **all** GitHub events to a single Trigger.dev task, `github-webhook-handler`, which verifies once and **fans out inside Trigger.dev** (`tasks.trigger` to `handle-pr`, `handle-issue`, `handle-push` based on event type). Simpler Hookdeck surface area; branching logic lives in application code. + +**Pattern B — Hookdeck fan-out (connections + filters):** **Multiple** Hookdeck connections share the same source; each connection uses **header filter rules** (e.g. `x-github-event`) so only matching events reach a dedicated Trigger.dev task. Fan-out happens **in Hookdeck** before Trigger. Each task verifies independently. More Hookdeck resources, but per-event-type observability, retries, and policies are separate. + +> **Setup note:** `npm run setup` / `scripts/setup-hookdeck.sh` creates **both** Pattern A and Pattern B resources (same shared Hookdeck source `github`). A single GitHub delivery can therefore be processed **more than once** unless you disable or remove one pattern’s connections in Hookdeck for clean testing. + +## Architecture + +**Pattern A** is **Trigger fan-out**: one HTTP trigger hits a **router handler** task, which dispatches child tasks. **Pattern B** is **Hookdeck fan-out**: the platform splits traffic across **filtered connections** so each task’s HTTP trigger fires only for its event family. + +The diagrams use short labels; **each numbered block** under a diagram explains that component and how it fits the demo. + +### Pattern A — Trigger fan-out: task router (`github-webhook-handler`) + +```mermaid +flowchart TB + GH[GitHub] + SRC[Source: github] + CONN[Conn: github-to-main-handler] + XFORM[Transform: trigger-wrapper] + DEST[Dest: trigger-dev-main] + HND[Task: github-webhook-handler] + PR[handle-pr] + IS[handle-issue] + PS[handle-push] + + GH -->|Webhook POST| SRC + SRC --> CONN + CONN --> XFORM + XFORM --> DEST + DEST -->|Bearer token| HND + HND --> PR + HND --> IS + HND --> PS +``` + +**Components (Pattern A)** + +1. **GitHub** — Sends repo webhooks (e.g. `pull_request`, `issues`, `push`) to the URL shown after Hookdeck setup (the **Source** ingest URL). +2. **Source: `github`** — Shared Hookdeck **source** (`GITHUB` type). Hooks are registered against this URL; Hookdeck can verify the GitHub HMAC at ingress (see **Verification chain**). +3. **Connection: `github-to-main-handler`** — Single Hookdeck **connection** for Pattern A: source → transform → the one destination used for **Trigger fan-out** (no per-event-type filters here). +4. **Transform: `trigger-wrapper`** — Rule-level **transformation** running `hookdeck/trigger-wrapper.js`: shapes the payload for Trigger.dev HTTP triggers and sets `_hookdeck.verified` for task-side checks. +5. **Destination: `trigger-dev-main`** — Hookdeck **HTTP destination** pointing at Trigger.dev Production: + `https://api.trigger.dev/api/v1/tasks/github-webhook-handler/trigger` with **Bearer** auth using `TRIGGER_SECRET_KEY`. +6. **Task: `github-webhook-handler`** — **Router handler**: verifies the event once, then performs **Trigger fan-out** — `tasks.trigger` to the right worker (`handle-pr`, `handle-issue`, `handle-push`) from this task. + +**Downstream tasks:** **`handle-pr`**, **`handle-issue`**, **`handle-push`** — The three demo workers (PR summary comment, issue labels, push → Slack). In Pattern A they are started **only** by the router task, not by separate Hookdeck connections. + +--- + +### Pattern B — Hookdeck fan-out: connections + filters + +```mermaid +flowchart TB + GH[GitHub] + SRC[Source: github] + GH -->|Webhook POST| SRC + SRC --> C1[Conn: github-to-handle-pr
filter pull_request] + SRC --> C2[Conn: github-to-handle-issue
filter issues] + SRC --> C3[Conn: github-to-handle-push
filter push] + C1 --> D1[Dest: trigger-dev-pr] + C2 --> D2[Dest: trigger-dev-issues] + C3 --> D3[Dest: trigger-dev-push] + D1 --> T1[Task: handle-pr] + D2 --> T2[Task: handle-issue] + D3 --> T3[Task: handle-push] +``` + +**Components (Pattern B)** + +Fan-out is **in Hookdeck**: one ingress on the source, then **parallel connection paths** — each path’s **filter** (e.g. on `x-github-event`) decides whether that delivery is forwarded to its destination. + +1. **GitHub** — Same as Pattern A; deliveries hit the shared source URL. +2. **Source: `github`** — Same shared source; one ingress point for all events. +3. **Connection: `github-to-handle-pr`** — One branch of **Hookdeck fan-out**: **`x-github-event` = `pull_request`**. Non-matching events do not go to this destination. Uses the same **`trigger-wrapper`** transform and retry settings as in `setup-hookdeck.sh`. +4. **Connection: `github-to-handle-issue`** — Filter **`x-github-event` = `issues`** → dedicated issue path. +5. **Connection: `github-to-handle-push`** — Filter **`x-github-event` = `push`** → dedicated push path. +6. **Destinations (`trigger-dev-pr`, `trigger-dev-issues`, `trigger-dev-push`)** — Three HTTP destinations to Trigger.dev task trigger URLs: `/handle-pr/trigger`, `/handle-issue/trigger`, `/handle-push/trigger`, each with Bearer `TRIGGER_SECRET_KEY`. +7. **Tasks (`handle-pr`, `handle-issue`, `handle-push`)** — Each task’s HTTP trigger is called **directly** by Hookdeck after **connection + filter** fan-out — no `github-webhook-handler` on this path. **Each** runs **`verifyHookdeckEvent()`** independently. + +## Prerequisites + +- [Node.js](https://nodejs.org/) 18+ +- [Hookdeck CLI](https://hookdeck.com/docs/cli) v1.2.0+ +- [GitHub CLI](https://cli.github.com/) (`gh`) — authenticated +- A [Trigger.dev](https://trigger.dev) account and project +- A [Hookdeck](https://hookdeck.com) account and project +- An [Anthropic](https://console.anthropic.com) API key +- A [Slack incoming webhook URL](https://api.slack.com/messaging/webhooks) (for deployment notifications) + +## Setup + +```bash +cp .env.example .env +# Fill in all values (see .env.example for descriptions) + +npm install +npm run setup +``` + +`npm run setup` does three things in order: + +1. **Deploys Trigger.dev tasks to Production** — `npm run deploy:prod` (explicit `--env prod`) +2. **Creates Hookdeck resources** — source, destinations, connections, filters, and transformation (idempotent) +3. **Registers GitHub webhook** — points the webhook at the Hookdeck source URL + +### Trigger.dev (Production only) + +This demo is wired for **Trigger.dev Production** only: + +- **`TRIGGER_SECRET_KEY`** must be your **Production** API key (`tr_prod_…`). Hookdeck destinations use it as the Bearer token, so HTTP triggers always hit Production workers. +- **`npm run setup`** and **`npm run deploy`** run **`trigger.dev deploy --env prod`**. + +Task runtime secrets are **synced from your local `.env` to Trigger.dev Production on every `npm run deploy`** (see `trigger.config.ts` → `syncEnvVars`): `ANTHROPIC_API_KEY`, `GITHUB_ACCESS_TOKEN`, and optional `GITHUB_LABELS`, `SLACK_WEBHOOK_URL`. Use the **same variable names** in `.env` and in the Trigger dashboard. If you still have an old `GITHUB_TOKEN` line only, deploy copies it to `GITHUB_ACCESS_TOKEN` for sync — rename when convenient. + +**Why `GITHUB_ACCESS_TOKEN` and not `GITHUB_TOKEN`?** Many tools use `GITHUB_TOKEN`, but that name is special in GitHub Actions and some cloud UIs don’t persist it reliably. `GITHUB_ACCESS_TOKEN` is explicit and syncs cleanly. + +If you previously used `GITHUB_PERSONAL_ACCESS_TOKEN` in `.env`, rename that line to `GITHUB_ACCESS_TOKEN` and redeploy. + +**Dashboard:** open **Production** (not Development) when checking vars. + +### Environment variables + +**For setup scripts** (used locally): + +| Variable | Description | +|----------|-------------| +| `HOOKDECK_API_KEY` | Hookdeck project API key | +| `GITHUB_WEBHOOK_SECRET` | Shared secret for GitHub HMAC verification | +| `TRIGGER_SECRET_KEY` | Trigger.dev **Production** secret (`tr_prod_…` only) | +| `TRIGGER_PROJECT_REF` | Trigger.dev project ref | +| `GITHUB_REPO` | Target repo (e.g., `hookdeck/hookdeck-demos`) | + +**For task runtime** (keep in `.env` — **synced to Production on `npm run deploy`**, or set in the Trigger.dev dashboard): + +| Variable | Description | +|----------|-------------| +| `GITHUB_ACCESS_TOKEN` | GitHub API token with `repo` scope (**required** in `.env`; synced on deploy) | +| `ANTHROPIC_API_KEY` | Anthropic API key for Claude (**required** for deploy sync) | +| `GITHUB_LABELS` | Optional CSV of allowed issue labels | +| `SLACK_WEBHOOK_URL` | Optional Slack incoming webhook URL | +| `GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY` | Optional. If `true`, **`handle-push`** only runs for the repo’s default branch (`main`). **Default:** unset / `false` — **any branch** gets a Slack summary (easier for demos). | + +## Deploying task changes + +After editing files under `trigger/`, push new code to Trigger.dev Production: + +```bash +npm run deploy +``` + +This also **re-syncs** the task env vars listed in `trigger.config.ts` from `.env` (so updating an API key locally and redeploying updates Production). `deploy:prod` passes **`--env-file .env`** so the deploy CLI loads your file before `syncEnvVars` runs. During deploy, Trigger prints **`Found N env vars to sync`** — `N` should match how many keys you’re syncing (typically **4** if `ANTHROPIC_API_KEY`, `GITHUB_ACCESS_TOKEN`, `GITHUB_LABELS`, and `SLACK_WEBHOOK_URL` are all set). + +**CI:** use `npm run deploy:prod:ci` and export `ANTHROPIC_API_KEY`, `GITHUB_ACCESS_TOKEN`, etc. as job secrets instead of `--env-file`. + +Then re-run Hooks or events as needed; Hookdeck continues to call the same task URLs. + +## Project structure + +``` +trigger.config.ts Trigger.dev project configuration +trigger/ + lib/ + ai.ts Claude helper (Anthropic SDK) + github.ts GitHub API helpers (fetch-based) + slack.ts Slack incoming webhook helper + verify-hookdeck.ts Event verification utility + github-webhook-handler.ts Pattern A: Trigger fan-out router handler + handle-pr.ts PR code review summary + handle-issue.ts Issue labeler + handle-push.ts Deployment summary to Slack +hookdeck/ + trigger-wrapper.js Shared Hookdeck transformation +scripts/ + setup-hookdeck.sh Hookdeck resource creation (idempotent) + setup-github-webhook.sh GitHub webhook registration +``` + +## Verification chain + +Events are verified at three levels: + +1. **Hookdeck source verification** — validates the GitHub HMAC signature (`X-Hub-Signature-256`) at ingress +2. **Trigger.dev destination auth** — Bearer token authenticates Hookdeck to the Trigger.dev API +3. **Task-level verification** — `verifyHookdeckEvent()` confirms the `_hookdeck.verified` flag injected by the transformation + +In Pattern A (**Trigger fan-out**), verification happens once in the router handler. In Pattern B (**Hookdeck fan-out**), each leaf task verifies independently. + +## TODO + +- [x] **Architecture diagrams:** Mermaid diagrams for Pattern A vs Pattern B are in **Architecture** above, with per-component descriptions under each diagram. +- [ ] **Hookdeck source verification:** Revisit event-source verification end-to-end (e.g. `x-hookdeck-verified` vs transform-time `context.connection.source.verification`, `_hookdeck.verified` semantics, and docs alignment). See `hookdeck/trigger-wrapper.js` and `trigger/lib/verify-hookdeck.ts`. +- [ ] **Development environment & prod parity:** Explore what a **dev** setup would look like (Trigger.dev Development + `trigger dev`, Hookdeck project or connections, webhook routing), how to **migrate or promote** to Production, and how to keep a dev stack **effectively matching prod** (env vars, connection names, transformation code, secrets rotation). This demo is Production-only today; document or script an optional path if we add it later. diff --git a/trigger-dev/github-ai-agent/hookdeck/trigger-wrapper.js b/trigger-dev/github-ai-agent/hookdeck/trigger-wrapper.js new file mode 100644 index 0000000..3211a53 --- /dev/null +++ b/trigger-dev/github-ai-agent/hookdeck/trigger-wrapper.js @@ -0,0 +1,61 @@ +/** + * Hookdeck transformation: trigger-wrapper + * + * Wraps the incoming webhook payload in the { payload: { ... } } structure + * that Trigger.dev expects, and injects: + * - _hookdeck.verified: whether Hookdeck verified the source signature (see below) + * - _hookdeck.signature: Hookdeck signing header when present on this request + * - event: the GitHub event type from the X-GitHub-Event header + * + * Verified semantics: + * - `x-hookdeck-verified` / `x-hookdeck-signature` are often added when Hookdeck + * *forwards* to the destination. The transform runs on the ingress request, so + * those headers may be missing here even when verification succeeded. + * - When headers are absent, use `context.connection.source.verification`: + * if the source has verification configured, invalid signatures are rejected + * before the transform runs, so reaching this handler implies verification passed. + * If verification is not configured, there is no source signature to enforce. + * + * This transformation is shared across all connections (both Pattern A + * and Pattern B). It is referenced by name in the setup script. + */ +function header(headers, name) { + if (!headers) return undefined; + const lower = name.toLowerCase(); + for (const key of Object.keys(headers)) { + if (key.toLowerCase() === lower) return headers[key]; + } + return undefined; +} + +function isHookdeckVerified(request, context) { + const v = header(request.headers, "x-hookdeck-verified"); + if (v === "true") return true; + if (v === "false") return false; + + var conn = context && context.connection; + var source = conn && conn.source; + var verification = source && source.verification; + if (verification && typeof verification === "object" && Object.keys(verification).length > 0) { + // Source has verification config — failed signatures never reach this transform. + return true; + } + + // No source verification configured: nothing to fail at ingress for signature. + return true; +} + +addHandler("transform", (request, context) => { + request.body = { + payload: { + _hookdeck: { + verified: isHookdeckVerified(request, context), + signature: header(request.headers, "x-hookdeck-signature"), + }, + event: header(request.headers, "x-github-event"), + action: request.body.action, + ...request.body, + }, + }; + return request; +}); diff --git a/trigger-dev/github-ai-agent/package-lock.json b/trigger-dev/github-ai-agent/package-lock.json new file mode 100644 index 0000000..7fc5551 --- /dev/null +++ b/trigger-dev/github-ai-agent/package-lock.json @@ -0,0 +1,5650 @@ +{ + "name": "trigger-dev-github-ai-agent", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "trigger-dev-github-ai-agent", + "version": "1.0.0", + "dependencies": { + "@anthropic-ai/sdk": "^0.39.0", + "@trigger.dev/sdk": "^4.3.3" + }, + "devDependencies": { + "@trigger.dev/build": "^4.3.3", + "dotenv": "^16.4.5", + "trigger.dev": "^4.3.3", + "typescript": "^5.7.0" + } + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.39.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.39.0.tgz", + "integrity": "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==", + "license": "MIT", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + } + }, + "node_modules/@arr/every": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz", + "integrity": "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bugsnag/cuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@bugsnag/cuid/-/cuid-3.2.1.tgz", + "integrity": "sha512-zpvN8xQ5rdRWakMd/BcVkdn2F8HKlDSbM3l7duueK590WmI1T0ObTLc1V/1e55r14WNjPd5AJTYX4yPEAFVi+Q==", + "license": "MIT" + }, + "node_modules/@clack/core": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", + "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", + "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "0.5.0", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@depot/cli": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli/-/cli-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-KvmOiQdpbamFziqnzzgqBm6RjfGhLJimBBYEOVriTxCPtVJuBIFm34xZllM36OQzPZIWpWBP+2/UnOyRG5smUg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "depot": "bin/depot" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@depot/cli-darwin-arm64": "0.0.1-cli.2.80.0", + "@depot/cli-darwin-x64": "0.0.1-cli.2.80.0", + "@depot/cli-linux-arm": "0.0.1-cli.2.80.0", + "@depot/cli-linux-arm64": "0.0.1-cli.2.80.0", + "@depot/cli-linux-ia32": "0.0.1-cli.2.80.0", + "@depot/cli-linux-x64": "0.0.1-cli.2.80.0", + "@depot/cli-win32-arm64": "0.0.1-cli.2.80.0", + "@depot/cli-win32-ia32": "0.0.1-cli.2.80.0", + "@depot/cli-win32-x64": "0.0.1-cli.2.80.0" + } + }, + "node_modules/@depot/cli-darwin-arm64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-darwin-arm64/-/cli-darwin-arm64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-H7tQ0zWXVmdYXGFvt3d/v5fmquMlMM1I9JC8C2yiBZ9En9a20hzSbKoiym92RtcfqjKQFvhXL0DT6vQmJ8bgQA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-darwin-x64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-darwin-x64/-/cli-darwin-x64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-3RDyybnCC2YSvbJCkHxXBYbKR7adUO7U00O9DHreX8EyS2E/C3kQgET+rFXR+iDdeG0h+h+At2rDng7AxvUhDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-linux-arm": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-linux-arm/-/cli-linux-arm-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-95kjKwKxP6RKkAhJoPlO6g3drEYpFWy9AC7QfvQMHDRnI3HXgbxA/BSTp4R3C4TTfp5JUPShVf8Js/NAcrUpUQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-linux-arm64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-linux-arm64/-/cli-linux-arm64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-Fc1+Guqdsl2WM+b+76FirRjjRvEoYZX0MI4uuIQF9c9gwp6UZSZ5o3U7lAUpdkclVMKXSAW5bsIpgcOfUiJX3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-linux-ia32": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-linux-ia32/-/cli-linux-ia32-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-2KoyIoYqnyIuynPN+mWbugoOB2APiNNvFLKERWOwPa0KYLSfcENT3sYxDW8tDuIw2dftHlmZN73uvXrGFeMcDQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-linux-x64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-linux-x64/-/cli-linux-x64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-B8xDlXFxhYHD2tUk0jUv7SKipLfWwJVlY7ZhDQixyQzatibXakahdqpvZJgE6FLZJd3lgFIEAVsKURZHa1l57A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-win32-arm64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-win32-arm64/-/cli-win32-arm64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-CPJX691MKEhnKZX25xS+opWESgPQ73HKkEwkAvvVqdBzahndcHoqAeIxYLv2hoCqrDlkH3YCF+DJleLiEP3blA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-win32-ia32": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-win32-ia32/-/cli-win32-ia32-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-6eewZ1zPEyNL3zcCwC01s3rZNMqMGVu1iv/EPywj3/uk4CNyUBaTlZ3StQ1BLFHPQnU0vk29yOzA5ZEuRLSyxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@depot/cli-win32-x64": { + "version": "0.0.1-cli.2.80.0", + "resolved": "https://registry.npmjs.org/@depot/cli-win32-x64/-/cli-win32-x64-0.0.1-cli.2.80.0.tgz", + "integrity": "sha512-9CRcc7D0/x4UrBkDuc35WVPMQG5gKMD1JckGLEl6VREE0Ppdny6n+hunQ8prwVc8aqzKG134XCC2U4DUjYg18A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14" + } + }, + "node_modules/@electric-sql/client": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@electric-sql/client/-/client-1.0.14.tgz", + "integrity": "sha512-LtPAfeMxXRiYS0hyDQ5hue2PjljUiK9stvzsVyVb4nwxWQxfOWTSF42bHTs/o5i3x1T4kAQ7mwHpxa4A+f8X7Q==", + "license": "Apache-2.0", + "dependencies": { + "@microsoft/fetch-event-source": "^2.0.1" + }, + "optionalDependencies": { + "@rollup/rollup-darwin-arm64": "^4.18.1" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@google-cloud/precise-date": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/precise-date/-/precise-date-4.0.0.tgz", + "integrity": "sha512-1TUx3KdaU3cN7nfCdNf+UVqA/PSX29Cjcox3fZZBtINlRrXVTmUkQnCKv2MbBUbCopbK4olAT1IHl76uZyCiVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jsonhero/path": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/@jsonhero/path/-/path-1.0.21.tgz", + "integrity": "sha512-gVUDj/92acpVoJwsVJ/RuWOaHyG4oFzn898WNGQItLCTQ+hOaVlEaImhwE1WqOTf+l3dGOUkbSiVKlb3q1hd1Q==", + "license": "MIT" + }, + "node_modules/@microsoft/fetch-event-source": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz", + "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==", + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/jose": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", + "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.1.tgz", + "integrity": "sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.203.0.tgz", + "integrity": "sha512-s0hys1ljqlMTbXx2XiplmMJg9wG570Z5lH7wMvrZX6lcODI56sG4HL03jklF63tBeyNwK2RV1/ntXGo3HgG4Qw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/sdk-logs": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.203.0.tgz", + "integrity": "sha512-HFSW10y8lY6BTZecGNpV3GpoSy7eaO0Z6GATwZasnT4bEsILp8UJXNG5OmEsz4SdwCSYvyCbTJdNbZP3/8LGCQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-metrics": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.203.0.tgz", + "integrity": "sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.203.0", + "@opentelemetry/otlp-transformer": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/host-metrics": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/host-metrics/-/host-metrics-0.37.0.tgz", + "integrity": "sha512-gf6nRFci0PTni9R1QQKjZ2uZE4Y6olLKhlwdM0qqLbbn3SBVKyP2jyBMiosBTHtRNLjY7s8hzQ44eLdK5wkGNQ==", + "license": "Apache-2.0", + "dependencies": { + "systeminformation": "5.23.8" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.203.0.tgz", + "integrity": "sha512-Z+mls3rOP2BaVykDZLLZPvchjj9l2oj3dYG1GTnrc27Y8o3biE+5M1b0izblycbbQHXjMPHQCpmjHbLMQuWtBg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/sdk-trace-web": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.203.0.tgz", + "integrity": "sha512-Wbxf7k+87KyvxFr5D7uOiSq/vHXWommvdnNE7vECO3tAhsA2GfOlpWINCMWUEPdHZ7tCXxw6Epp3vgx3jU7llQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-transformer": "0.203.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.203.0.tgz", + "integrity": "sha512-Y8I6GgoCna0qDQ2W6GCRtaF24SnvqvA8OfeTi7fqigD23u8Jpb4R5KFv/pRvrlGagcCLICMIyh9wiejp4TXu/A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.203.0.tgz", + "integrity": "sha512-vM2+rPq0Vi3nYA5akQD2f3QwossDnTDLvKbea6u/A2NZ3XDkPxMfo/PNrDoXhDUD/0pPo2CdH5ce/thn9K0kLw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.1.tgz", + "integrity": "sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.1.tgz", + "integrity": "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.0.1.tgz", + "integrity": "sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.0.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-2.0.1.tgz", + "integrity": "sha512-R4/i0rISvAujG4Zwk3s6ySyrWG+Db3SerZVM4jZ2lEzjrNylF7nRAy1hVvWe8gTbwIxX+6w6ZvZwdtl2C7UQHQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.36.0.tgz", + "integrity": "sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz", + "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prisma/config": { + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.2.tgz", + "integrity": "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "c12": "3.1.0", + "deepmerge-ts": "7.1.5", + "effect": "3.18.4", + "empathic": "2.0.0" + } + }, + "node_modules/@prisma/config/node_modules/c12": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", + "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.6.1", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/@prisma/config/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@prisma/config/node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/@prisma/config/node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@prisma/config/node_modules/nypm": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz", + "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.2.0", + "pathe": "^2.0.3", + "tinyexec": "^1.0.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@prisma/config/node_modules/nypm/node_modules/citty": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.1.tgz", + "integrity": "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prisma/config/node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prisma/config/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prisma/config/node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/@prisma/config/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@prisma/config/node_modules/tinyexec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@protobuf-ts/runtime": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.1.tgz", + "integrity": "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==", + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@s2-dev/streamstore": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/@s2-dev/streamstore/-/streamstore-0.22.5.tgz", + "integrity": "sha512-GqdOKIbIoIxT+40fnKzHbrsHB6gBqKdECmFe7D3Ojk4FoN1Hu0LhFzZv6ZmVMjoHHU+55debS1xSWjZwQmbIyQ==", + "license": "MIT", + "dependencies": { + "@protobuf-ts/runtime": "^2.11.1", + "debug": "^4.4.3" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@sodaru/yup-to-json-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@sodaru/yup-to-json-schema/-/yup-to-json-schema-2.0.1.tgz", + "integrity": "sha512-lWb0Wiz8KZ9ip/dY1eUqt7fhTPmL24p6Hmv5Fd9pzlzAdw/YNcWZr+tiCT4oZ4Zyxzi9+1X4zv82o7jYvcFxYA==", + "dev": true, + "license": "MIT License" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@trigger.dev/build": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@trigger.dev/build/-/build-4.4.3.tgz", + "integrity": "sha512-t/hYmQiv2SdrUao9scoczrvfhyzSLkuT8DNyiBt9q29GKct37zytWyAo16hpN2Uf+yXh0EkdnkHbfR9odF0YtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@prisma/config": "^6.10.0", + "@trigger.dev/core": "4.4.3", + "mlly": "^1.7.1", + "pkg-types": "^1.1.3", + "resolve": "^1.22.8", + "tinyglobby": "^0.2.2", + "tsconfck": "3.1.3" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@trigger.dev/core": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@trigger.dev/core/-/core-4.4.3.tgz", + "integrity": "sha512-4srm2UGoDEcHO29Lqp4Isioq+b6au0EjW9/pjYmzOSxXqGPFDjPquK0BnKYGHyAbKYxuBx8wr2T/ru+zbY0/Jg==", + "license": "MIT", + "dependencies": { + "@bugsnag/cuid": "^3.1.1", + "@electric-sql/client": "1.0.14", + "@google-cloud/precise-date": "^4.0.0", + "@jsonhero/path": "^1.0.21", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/exporter-logs-otlp-http": "0.203.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.203.0", + "@opentelemetry/exporter-trace-otlp-http": "0.203.0", + "@opentelemetry/host-metrics": "^0.37.0", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.203.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "@opentelemetry/sdk-trace-node": "2.0.1", + "@opentelemetry/semantic-conventions": "1.36.0", + "@s2-dev/streamstore": "0.22.5", + "dequal": "^2.0.3", + "eventsource": "^3.0.5", + "eventsource-parser": "^3.0.0", + "execa": "^8.0.1", + "humanize-duration": "^3.27.3", + "jose": "^5.4.0", + "nanoid": "3.3.8", + "prom-client": "^15.1.0", + "socket.io": "4.7.4", + "socket.io-client": "4.7.5", + "std-env": "^3.8.1", + "tinyexec": "^0.3.2", + "uncrypto": "^0.1.3", + "zod": "3.25.76", + "zod-error": "1.5.0", + "zod-validation-error": "^1.5.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@trigger.dev/schema-to-json": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@trigger.dev/schema-to-json/-/schema-to-json-4.4.3.tgz", + "integrity": "sha512-/NuUV7Fq0KGG/md68dAJv/aOsLgUbpXCmPgKzZ9wO8uap3fD3zoS5x+Z1QE4VcVbk9KhOGvY9BR3WD6hFJCTbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sodaru/yup-to-json-schema": "^2", + "@trigger.dev/core": "4.4.3", + "effect": "^3", + "zod": "3.25.76", + "zod-to-json-schema": "^3.24.0" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "@sinclair/typebox": ">=0.34.30", + "arktype": ">=2.0.0", + "runtypes": ">=5.0.0", + "superstruct": ">=0.14.2", + "valibot": ">=0.41.0" + }, + "peerDependenciesMeta": { + "@sinclair/typebox": { + "optional": true + }, + "arktype": { + "optional": true + }, + "runtypes": { + "optional": true + }, + "superstruct": { + "optional": true + }, + "valibot": { + "optional": true + } + } + }, + "node_modules/@trigger.dev/sdk": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@trigger.dev/sdk/-/sdk-4.4.3.tgz", + "integrity": "sha512-ghJkak+PTBJJ9HiHMcnahJmzjsgCzYiIHu5Qj5R7I9q5LS6i7mkx169rB/tOE9HLadd4HSu3yYA5DrH4wXhZuw==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/semantic-conventions": "1.36.0", + "@trigger.dev/core": "4.4.3", + "chalk": "^5.2.0", + "cronstrue": "^2.21.0", + "debug": "^4.3.4", + "evt": "^2.4.13", + "slug": "^6.0.0", + "ulid": "^2.3.0", + "uncrypto": "^0.1.3", + "uuid": "^9.0.0", + "ws": "^8.11.0" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "ai": "^4.2.0 || ^5.0.0 || ^6.0.0", + "zod": "^3.0.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "ai": { + "optional": true + } + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tinycolor2": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", + "integrity": "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bintrees": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", + "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c12": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/c12/-/c12-1.11.2.tgz", + "integrity": "sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "confbox": "^0.1.7", + "defu": "^6.1.4", + "dotenv": "^16.4.5", + "giget": "^1.2.3", + "jiti": "^1.21.6", + "mlly": "^1.7.1", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.4" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/c12/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cronstrue": { + "version": "2.59.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.59.0.tgz", + "integrity": "sha512-YKGmAy84hKH+hHIIER07VCAHf9u0Ldelx1uU6EBxsRPDXIA1m5fsKmJfyC3xBhw6cVC/1i83VdbL4PvepTrt8A==", + "license": "MIT", + "bin": { + "cronstrue": "bin/cli.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/effect": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", + "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "fast-check": "^3.23.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", + "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-polyfill": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/event-target-polyfill/-/event-target-polyfill-0.0.4.tgz", + "integrity": "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/evt": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/evt/-/evt-2.5.9.tgz", + "integrity": "sha512-GpjX476FSlttEGWHT8BdVMoI8wGXQGbEOtKcP4E+kggg+yJzXBZN2n4x7TS/zPBJ1DZqWI+rguZZApjjzQ0HpA==", + "license": "MIT", + "dependencies": { + "minimal-polyfills": "^2.2.3", + "run-exclusive": "^2.2.19", + "tsafe": "^1.8.5" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-check": { + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT", + "dependencies": { + "pure-rand": "^6.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-npm-meta": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-npm-meta/-/fast-npm-meta-0.2.2.tgz", + "integrity": "sha512-E+fdxeaOQGo/CMWc9f4uHFfgUPJRAu7N3uB8GBvB3SDPAIWJK4GKyYhkAGFq+GYrcbKNfQIz5VVQyJnDuPPCrg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/giget": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.5.tgz", + "integrity": "sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.5.4", + "pathe": "^2.0.3", + "tar": "^6.2.1" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/giget/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/giget/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/giget/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/giget/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/giget/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/giget/node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/giget/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/git-last-commit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-last-commit/-/git-last-commit-1.0.1.tgz", + "integrity": "sha512-FDSgeMqa7GnJDxt/q0AbrxbfeTyxp4ImxEw1e4nw6NUHA5FMhFUq33dTXI4Xdgcj1VQ1q5QLWF6WxFrJ8KCBOg==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gradient-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gradient-string/-/gradient-string-2.0.2.tgz", + "integrity": "sha512-rEDCuqUQ4tbD78TpzsMtt5OIf0cBCSDWSJtUDaF6JsAh+k0v9r++NzxNEG87oDZx9ZwGhD8DaezR2L/yrw0Jdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tinygradient": "^1.1.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gradient-string/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/gradient-string/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/gradient-string/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-flag": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.8", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", + "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/humanize-duration": { + "version": "3.33.2", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.2.tgz", + "integrity": "sha512-K7Ny/ULO1hDm2nnhvAY+SJV1skxFb61fd073SG1IWJl+D44ULrruCuTyjHKjBVVcSuTlnY99DKtgEG39CM5QOQ==", + "license": "Unlicense", + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", + "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/json-stable-stringify": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", + "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "license": "Public Domain", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/matchit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz", + "integrity": "sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@arr/every": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimal-polyfills": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz", + "integrity": "sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mlly": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.1.tgz", + "integrity": "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nypm": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz", + "integrity": "sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "tinyexec": "^0.3.2", + "ufo": "^1.5.4" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/nypm/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ohash": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.6.tgz", + "integrity": "sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-paths": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/os-paths/-/os-paths-7.4.0.tgz", + "integrity": "sha512-Ux1J4NUqC6tZayBqLN1kUlDAEvLiQlli/53sSddU4IN+h+3xxnv2HmRSMpVSvr1hvJzotfMs3ERvETGK+f4OwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/partysocket": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/partysocket/-/partysocket-1.1.16.tgz", + "integrity": "sha512-d7xFv+ZC7x0p/DAHWJ5FhxQhimIx+ucyZY+kxL0cKddLBmK9c4p2tEA/L+dOOrWm6EYrRwrBjKQV0uSzOY9x1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-polyfill": "^0.0.4" + }, + "peerDependencies": { + "react": ">=17" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/polka": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/polka/-/polka-0.5.2.tgz", + "integrity": "sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^0.5.0", + "trouter": "^2.0.1" + } + }, + "node_modules/prom-client": { + "version": "15.1.3", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", + "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.4.0", + "tdigest": "^0.1.1" + }, + "engines": { + "node": "^16 || ^18 || >=20" + } + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-exclusive": { + "version": "2.2.19", + "resolved": "https://registry.npmjs.org/run-exclusive/-/run-exclusive-2.2.19.tgz", + "integrity": "sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==", + "license": "MIT", + "dependencies": { + "minimal-polyfills": "^2.2.3" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slug": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/slug/-/slug-6.1.0.tgz", + "integrity": "sha512-x6vLHCMasg4DR2LPiyFGI0gJJhywY6DTiGhCrOMzb3SOk/0JVLIaL4UhyFSHu04SD3uAavrKY/K3zZ3i6iRcgA==", + "license": "MIT" + }, + "node_modules/socket.io": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", + "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", + "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", + "license": "MIT", + "dependencies": { + "debug": "~4.4.1", + "ws": "~8.18.3" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/systeminformation": { + "version": "5.23.8", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.23.8.tgz", + "integrity": "sha512-Osd24mNKe6jr/YoXLLK3k8TMdzaxDffhpCxgkfgBHcapykIkd50HXThM3TCEuHO2pPuCsSx2ms/SunqhU5MmsQ==", + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } + }, + "node_modules/tar": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", + "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tdigest": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", + "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", + "license": "MIT", + "dependencies": { + "bintrees": "1.0.2" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinygradient": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/tinygradient/-/tinygradient-1.1.5.tgz", + "integrity": "sha512-8nIfc2vgQ4TeLnk2lFj4tRLvvJwEfQuabdsmvDdQPT0xlk9TaNtpGd6nNRxXoK6vQhN6RSzj+Cnp5tTQmpxmbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tinycolor2": "^1.4.0", + "tinycolor2": "^1.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/trigger.dev": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/trigger.dev/-/trigger.dev-4.4.3.tgz", + "integrity": "sha512-DR6qy7xVvCTa3FygqaiSNL48Y06EGWghTikx+CufJ5lg/pFRvQo95xSF+pOVS9lQ/ZBiMDa3Awz3Rji/aQUEiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/prompts": "0.11.0", + "@depot/cli": "0.0.1-cli.2.80.0", + "@modelcontextprotocol/sdk": "^1.25.2", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/api-logs": "0.203.0", + "@opentelemetry/exporter-trace-otlp-http": "0.203.0", + "@opentelemetry/instrumentation": "0.203.0", + "@opentelemetry/instrumentation-fetch": "0.203.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-node": "2.0.1", + "@opentelemetry/semantic-conventions": "1.36.0", + "@s2-dev/streamstore": "^0.22.5", + "@trigger.dev/build": "4.4.3", + "@trigger.dev/core": "4.4.3", + "@trigger.dev/schema-to-json": "4.4.3", + "ansi-escapes": "^7.0.0", + "braces": "^3.0.3", + "c12": "^1.11.1", + "chalk": "^5.2.0", + "chokidar": "^3.6.0", + "cli-table3": "^0.6.3", + "commander": "^9.4.1", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.4.5", + "esbuild": "^0.23.0", + "eventsource": "^3.0.2", + "evt": "^2.4.13", + "fast-npm-meta": "^0.2.2", + "git-last-commit": "^1.0.1", + "gradient-string": "^2.0.2", + "has-flag": "^5.0.1", + "ignore": "^7.0.5", + "import-in-the-middle": "1.11.0", + "import-meta-resolve": "^4.1.0", + "ini": "^5.0.0", + "json-stable-stringify": "^1.3.0", + "jsonc-parser": "3.2.1", + "magicast": "^0.3.4", + "minimatch": "^10.0.1", + "mlly": "^1.7.1", + "nypm": "^0.5.4", + "object-hash": "^3.0.0", + "open": "^10.0.3", + "p-limit": "^6.2.0", + "p-retry": "^6.1.0", + "partysocket": "^1.0.2", + "pkg-types": "^1.1.3", + "polka": "^0.5.2", + "resolve": "^1.22.8", + "semver": "^7.5.0", + "signal-exit": "^4.1.0", + "socket.io-client": "4.7.5", + "source-map-support": "0.5.21", + "std-env": "^3.7.0", + "strip-ansi": "^7.1.0", + "supports-color": "^10.0.0", + "tar": "^7.5.4", + "tiny-invariant": "^1.2.0", + "tinyexec": "^0.3.1", + "tinyglobby": "^0.2.10", + "ws": "^8.18.0", + "xdg-app-paths": "^8.3.0", + "zod": "3.25.76", + "zod-validation-error": "^1.5.0" + }, + "bin": { + "trigger": "dist/esm/index.js" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/trigger.dev/node_modules/import-in-the-middle": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", + "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/trouter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/trouter/-/trouter-2.0.1.tgz", + "integrity": "sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "matchit": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsafe": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/tsafe/-/tsafe-1.8.12.tgz", + "integrity": "sha512-nFRqW0ttu/2o6XTXsHiVZWJBCOaxhVqZLg7dgs3coZNsCMPXPfwz+zPHAQA+70fNnVJLAPg1EgGIqK9Q84tvAw==", + "license": "MIT" + }, + "node_modules/tsconfck": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.3.tgz", + "integrity": "sha512-ulNZP1SVpRDesxeMLON/LtWM8HIgAJEIVpVVhBM6gsmvQ8+Rh+ZG7FWGvHh7Ah3pRABwVJWklWCr/BTZSv0xnQ==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/ulid": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.4.0.tgz", + "integrity": "sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==", + "license": "MIT", + "bin": { + "ulid": "bin/cli.js" + } + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xdg-app-paths": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/xdg-app-paths/-/xdg-app-paths-8.3.0.tgz", + "integrity": "sha512-mgxlWVZw0TNWHoGmXq+NC3uhCIc55dDpAlDkMQUaIAcQzysb0kxctwv//fvuW61/nAAeUBJMQ8mnZjMmuYwOcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "xdg-portable": "^10.6.0" + }, + "engines": { + "node": ">= 4.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, + "node_modules/xdg-portable": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/xdg-portable/-/xdg-portable-10.6.0.tgz", + "integrity": "sha512-xrcqhWDvtZ7WLmt8G4f3hHy37iK7D2idtosRgkeiSPZEPmBShp0VfmRBLWAPC6zLF48APJ21yfea+RfQMF4/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-paths": "^7.4.0" + }, + "engines": { + "node": ">= 4.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-error": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/zod-error/-/zod-error-1.5.0.tgz", + "integrity": "sha512-zzopKZ/skI9iXpqCEPj+iLCKl9b88E43ehcU+sbRoHuwGd9F1IDVGQ70TyO6kmfiRL1g4IXkjsXK+g1gLYl4WQ==", + "license": "MIT", + "dependencies": { + "zod": "^3.20.2" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-validation-error": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-1.5.0.tgz", + "integrity": "sha512-/7eFkAI4qV0tcxMBB/3+d2c1P6jzzZYdYSlBuAklzMuCrJu5bzJfHS0yVAS87dRHVlhftd6RFJDIvv03JgkSbw==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "zod": "^3.18.0" + } + } + } +} diff --git a/trigger-dev/github-ai-agent/package.json b/trigger-dev/github-ai-agent/package.json new file mode 100644 index 0000000..ccd6721 --- /dev/null +++ b/trigger-dev/github-ai-agent/package.json @@ -0,0 +1,26 @@ +{ + "name": "trigger-dev-github-ai-agent", + "version": "1.0.0", + "private": true, + "description": "GitHub AI agent demo: Hookdeck webhook routing to Trigger.dev tasks", + "scripts": { + "setup": "bash scripts/setup.sh", + "setup:check": "bash scripts/setup.sh --check", + "setup:hookdeck": "bash scripts/setup-hookdeck.sh", + "setup:github": "bash scripts/setup-github-webhook.sh", + "setup:dry-run": "DRY_RUN=true bash scripts/setup-hookdeck.sh", + "deploy": "npm run deploy:prod", + "deploy:prod": "npx trigger.dev@latest deploy --env prod --skip-update-check --env-file .env", + "deploy:prod:ci": "npx trigger.dev@latest deploy --env prod --skip-update-check" + }, + "dependencies": { + "@anthropic-ai/sdk": "^0.39.0", + "@trigger.dev/sdk": "^4.3.3" + }, + "devDependencies": { + "@trigger.dev/build": "^4.3.3", + "dotenv": "^16.4.5", + "trigger.dev": "^4.3.3", + "typescript": "^5.7.0" + } +} diff --git a/trigger-dev/github-ai-agent/scripts/setup-github-webhook.sh b/trigger-dev/github-ai-agent/scripts/setup-github-webhook.sh new file mode 100755 index 0000000..7f1ff15 --- /dev/null +++ b/trigger-dev/github-ai-agent/scripts/setup-github-webhook.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# setup-github-webhook.sh +# +# Registers a GitHub webhook pointing to the Hookdeck source URL. +# Checks for an existing webhook first to avoid duplicates. +# +# Prerequisites: +# - gh CLI installed and authenticated (gh auth login) +# - .env file with GITHUB_REPO, GITHUB_WEBHOOK_SECRET +# - Hookdeck setup already run (source URL must exist) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +# Load environment variables +if [ -f "$PROJECT_DIR/.env" ]; then + set -a + source "$PROJECT_DIR/.env" + set +a +fi + +# Validate required env vars +for var in GITHUB_REPO GITHUB_WEBHOOK_SECRET HOOKDECK_API_KEY; do + if [ -z "${!var:-}" ]; then + echo "Error: $var is not set. See .env.example." + exit 1 + fi +done + +# Get the Hookdeck source URL +echo "Getting Hookdeck source URL..." + +# First, check if setup-hookdeck.sh saved the URL to a file +SOURCE_URL_FILE="$PROJECT_DIR/.hookdeck-source-url" +if [ -f "$SOURCE_URL_FILE" ]; then + HOOKDECK_SOURCE_URL=$(cat "$SOURCE_URL_FILE") + echo " Found saved URL from Hookdeck setup" +fi + +# If not found in file, try to fetch it via the CLI +if [ -z "${HOOKDECK_SOURCE_URL:-}" ]; then + echo " Fetching from Hookdeck API..." + hookdeck ci --api-key "$HOOKDECK_API_KEY" 2>/dev/null + + # Try to get the source and parse the URL using Python (more portable than jq) + SOURCE_JSON=$(hookdeck gateway source get github --output json 2>/dev/null || true) + if [ -n "$SOURCE_JSON" ]; then + HOOKDECK_SOURCE_URL=$(echo "$SOURCE_JSON" | python3 -c " +import sys +import json +try: + data = json.load(sys.stdin) + print(data.get('url', '')) +except: + pass +" 2>/dev/null || true) + fi +fi + +if [ -z "${HOOKDECK_SOURCE_URL:-}" ]; then + echo "Error: Could not get Hookdeck source URL." + echo " Run setup-hookdeck.sh first, or set HOOKDECK_SOURCE_URL in .env" + exit 1 +fi + +echo "Hookdeck source URL: $HOOKDECK_SOURCE_URL" + +# Check for existing webhook pointing to this URL +echo "Checking for existing webhook on $GITHUB_REPO..." +EXISTING_HOOK_ID=$(gh api "repos/$GITHUB_REPO/hooks" --jq ".[] | select(.config.url == \"$HOOKDECK_SOURCE_URL\") | .id" 2>/dev/null || true) + +if [ -n "$EXISTING_HOOK_ID" ]; then + echo "Found existing webhook (ID: $EXISTING_HOOK_ID). Updating..." + gh api "repos/$GITHUB_REPO/hooks/$EXISTING_HOOK_ID" \ + --method PATCH \ + -f "config[url]=$HOOKDECK_SOURCE_URL" \ + -f "config[content_type]=json" \ + -f "config[secret]=$GITHUB_WEBHOOK_SECRET" \ + -f "events[]=pull_request" \ + -f "events[]=issues" \ + -f "events[]=push" \ + -F "active=true" \ + --silent + echo "Webhook updated successfully." +else + echo "Creating new webhook..." + gh api "repos/$GITHUB_REPO/hooks" \ + --method POST \ + -f "name=web" \ + -f "config[url]=$HOOKDECK_SOURCE_URL" \ + -f "config[content_type]=json" \ + -f "config[secret]=$GITHUB_WEBHOOK_SECRET" \ + -f "events[]=pull_request" \ + -f "events[]=issues" \ + -f "events[]=push" \ + -F "active=true" \ + --silent + echo "Webhook created successfully." +fi + +echo "" +echo "GitHub webhook configured for $GITHUB_REPO" +echo " URL: $HOOKDECK_SOURCE_URL" +echo " Events: pull_request, issues, push" diff --git a/trigger-dev/github-ai-agent/scripts/setup-hookdeck.sh b/trigger-dev/github-ai-agent/scripts/setup-hookdeck.sh new file mode 100755 index 0000000..93987e4 --- /dev/null +++ b/trigger-dev/github-ai-agent/scripts/setup-hookdeck.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# setup-hookdeck.sh +# +# Creates Hookdeck resources for the Trigger.dev GitHub AI agent demo. +# Idempotent: safe to run multiple times (uses connection upsert). +# +# Prerequisites: +# - hookdeck CLI installed (v1.2.0+) +# - .env file with HOOKDECK_API_KEY, GITHUB_WEBHOOK_SECRET, TRIGGER_SECRET_KEY +# +# Supports both Pattern A (fan-out) and Pattern B (per-event routing). + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +# Load environment variables +if [ -f "$PROJECT_DIR/.env" ]; then + set -a + source "$PROJECT_DIR/.env" + set +a +fi + +# Validate required env vars +for var in HOOKDECK_API_KEY GITHUB_WEBHOOK_SECRET TRIGGER_SECRET_KEY; do + if [ -z "${!var:-}" ]; then + echo "Error: $var is not set. See .env.example." + exit 1 + fi +done + +# Optional dry-run mode +DRY_RUN_FLAG="" +if [ "${DRY_RUN:-}" = "true" ]; then + DRY_RUN_FLAG="--dry-run" + echo "=== DRY RUN MODE ===" +fi + +TRIGGER_BASE_URL="https://api.trigger.dev/api/v1/tasks" + +# Read transformation code from file +TRANSFORM_CODE=$(cat "$PROJECT_DIR/hookdeck/trigger-wrapper.js") + +# Authenticate with Hookdeck (non-interactive, for scripts/CI) +echo "Authenticating with Hookdeck..." +hookdeck ci --api-key "$HOOKDECK_API_KEY" + +echo "" +echo "=== Pattern A: Single main task (fan-out) ===" +echo "" + +# Create the first connection and capture output to extract the Source URL +CONNECTION_OUTPUT=$(hookdeck gateway connection upsert "github-to-main-handler" \ + --source-name "github" \ + --source-type GITHUB \ + --source-webhook-secret "$GITHUB_WEBHOOK_SECRET" \ + --source-allowed-http-methods "POST" \ + --destination-name "trigger-dev-main" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/github-webhook-handler/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-transform-name "trigger-wrapper" \ + --rule-transform-code "$TRANSFORM_CODE" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear \ + --rule-retry-interval 60000 \ + $DRY_RUN_FLAG 2>&1) + +echo "$CONNECTION_OUTPUT" + +# Extract Source URL from the connection output using Python (more portable than jq) +HOOKDECK_SOURCE_URL=$(echo "$CONNECTION_OUTPUT" | python3 -c " +import sys +for line in sys.stdin: + if 'Source URL:' in line: + # Format is 'Source URL: https://hkdk.events/xxx' + print(line.split('Source URL:')[1].strip()) + break +" 2>/dev/null || true) + +# Export for later use by setup-github-webhook.sh +if [ -n "$HOOKDECK_SOURCE_URL" ]; then + export HOOKDECK_SOURCE_URL +fi + +echo "" +echo "=== Pattern B: Per-event routing ===" +echo "" + +# PR events +echo "Creating connection: github-to-handle-pr" +hookdeck gateway connection upsert "github-to-handle-pr" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-pr" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-pr/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"pull_request"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear \ + --rule-retry-interval 60000 \ + $DRY_RUN_FLAG + +echo "" + +# Issue events +echo "Creating connection: github-to-handle-issue" +hookdeck gateway connection upsert "github-to-handle-issue" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-issues" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-issue/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"issues"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear \ + --rule-retry-interval 60000 \ + $DRY_RUN_FLAG + +echo "" + +# Push events +echo "Creating connection: github-to-handle-push" +hookdeck gateway connection upsert "github-to-handle-push" \ + --source-name "github" \ + --source-type GITHUB \ + --destination-name "trigger-dev-push" \ + --destination-type HTTP \ + --destination-url "$TRIGGER_BASE_URL/handle-push/trigger" \ + --destination-auth-method bearer \ + --destination-bearer-token "$TRIGGER_SECRET_KEY" \ + --rule-filter-headers '{"x-github-event":{"$eq":"push"}}' \ + --rule-transform-name "trigger-wrapper" \ + --rule-retry-count 5 \ + --rule-retry-strategy linear \ + --rule-retry-interval 60000 \ + $DRY_RUN_FLAG + +echo "" +echo "=== Hookdeck setup complete ===" +echo "" + +# Output the Source URL that was captured during connection creation +if [ -n "${HOOKDECK_SOURCE_URL:-}" ]; then + echo "Source URL (register this with GitHub):" + echo " $HOOKDECK_SOURCE_URL" + + # Save to a temp file so setup-github-webhook.sh can read it + echo "$HOOKDECK_SOURCE_URL" > "$PROJECT_DIR/.hookdeck-source-url" +else + echo "Source URL: (could not extract — check the Hookdeck dashboard)" +fi +echo "" diff --git a/trigger-dev/github-ai-agent/scripts/setup.sh b/trigger-dev/github-ai-agent/scripts/setup.sh new file mode 100644 index 0000000..786ca15 --- /dev/null +++ b/trigger-dev/github-ai-agent/scripts/setup.sh @@ -0,0 +1,324 @@ +#!/bin/bash +# setup.sh +# +# Interactive setup for the Trigger.dev GitHub AI agent demo. +# Walks through all credentials, auto-generates what it can, +# prompts for the rest, writes .env, then runs the setup scripts. +# +# Usage: +# bash scripts/setup.sh # interactive setup +# bash scripts/setup.sh --check # just verify .env is complete + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +ENV_FILE="$PROJECT_DIR/.env" + +# Colors for output +BOLD='\033[1m' +DIM='\033[2m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +RED='\033[0;31m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +info() { echo -e "${CYAN}ℹ${NC} $1"; } +ok() { echo -e "${GREEN}✓${NC} $1"; } +warn() { echo -e "${YELLOW}⚠${NC} $1"; } +err() { echo -e "${RED}✗${NC} $1"; } +header() { echo -e "\n${BOLD}── $1 ──${NC}\n"; } + +# Load existing .env if present +load_env() { + if [ -f "$ENV_FILE" ]; then + set -a + source "$ENV_FILE" + set +a + fi +} + +# Write a key=value to .env (update if exists, append if not) +# Values are quoted to handle spaces (e.g., label names like "good first issue") +set_env() { + local key="$1" + local value="$2" + if [ -f "$ENV_FILE" ] && grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then + # Update existing line - delete and re-append to handle quoting properly + grep -v "^${key}=" "$ENV_FILE" > "${ENV_FILE}.tmp" && mv "${ENV_FILE}.tmp" "$ENV_FILE" + fi + echo "${key}=\"${value}\"" >> "$ENV_FILE" + export "$key=$value" +} + +# Prompt for a value, showing the current value if set +prompt_for() { + local key="$1" + local description="$2" + local help_text="${3:-}" + local current="${!key:-}" + + if [ -n "$current" ]; then + echo -e " ${DIM}Current value: ${current:0:20}...${NC}" + read -p " Keep current value? [Y/n]: " keep + if [ "${keep,,}" != "n" ]; then + ok "$key already set" + return + fi + fi + + if [ -n "$help_text" ]; then + echo -e " ${DIM}${help_text}${NC}" + fi + + read -p " Enter $description: " value + if [ -z "$value" ]; then + err "$key is required" + exit 1 + fi + set_env "$key" "$value" + ok "$key set" +} + +# ───────────────────────────────────────────────────────────── +# Main setup flow +# ───────────────────────────────────────────────────────────── + +echo "" +echo -e "${BOLD}Trigger.dev + Hookdeck: GitHub AI Agent Demo${NC}" +echo -e "${DIM}Interactive setup — generates what it can, prompts for the rest${NC}" +echo "" + +# Start with existing .env or create from example +if [ -f "$ENV_FILE" ]; then + info "Found existing .env file" + load_env +else + info "Creating .env from .env.example" + cp "$PROJECT_DIR/.env.example" "$ENV_FILE" + load_env +fi + +# ── 1. GitHub CLI ────────────────────────────────────────── + +header "GitHub CLI" + +if ! command -v gh &> /dev/null; then + err "gh CLI not found. Install it: https://cli.github.com" + exit 1 +fi + +if ! gh auth status &> /dev/null; then + err "gh CLI not authenticated. Run: gh auth login" + exit 1 +fi + +ok "gh CLI authenticated" + +# GitHub API token for tasks (same name in .env and Trigger.dev) +if [ -z "${GITHUB_ACCESS_TOKEN:-}" ] && [ -n "${GITHUB_TOKEN:-}" ]; then + set_env "GITHUB_ACCESS_TOKEN" "$GITHUB_TOKEN" + ok "Copied legacy GITHUB_TOKEN → GITHUB_ACCESS_TOKEN (you can delete GITHUB_TOKEN from .env)" +fi +if [ -z "${GITHUB_ACCESS_TOKEN:-}" ]; then + GH_TOKEN=$(gh auth token 2>/dev/null || true) + if [ -n "$GH_TOKEN" ]; then + set_env "GITHUB_ACCESS_TOKEN" "$GH_TOKEN" + ok "GITHUB_ACCESS_TOKEN auto-detected from gh CLI" + else + prompt_for "GITHUB_ACCESS_TOKEN" "GitHub access token" "Create at: https://github.com/settings/tokens (repo scope)" + fi +else + ok "GITHUB_ACCESS_TOKEN already set" +fi + +# Auto-detect repo +if [ -z "${GITHUB_REPO:-}" ]; then + DETECTED_REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null || true) + if [ -n "$DETECTED_REPO" ]; then + echo -e " ${DIM}Detected repo: ${DETECTED_REPO}${NC}" + read -p " Use this repo for the webhook? [Y/n]: " use_detected + if [ "${use_detected,,}" != "n" ]; then + set_env "GITHUB_REPO" "$DETECTED_REPO" + ok "GITHUB_REPO set to $DETECTED_REPO" + else + prompt_for "GITHUB_REPO" "GitHub repo (owner/name)" "e.g., hookdeck/hookdeck-demos" + fi + else + prompt_for "GITHUB_REPO" "GitHub repo (owner/name)" "e.g., hookdeck/hookdeck-demos" + fi +else + ok "GITHUB_REPO already set (${GITHUB_REPO})" +fi + +# Auto-generate webhook secret +if [ -z "${GITHUB_WEBHOOK_SECRET:-}" ]; then + GENERATED_SECRET=$(openssl rand -hex 32 2>/dev/null || head -c 32 /dev/urandom | xxd -p 2>/dev/null || date +%s%N | sha256sum | head -c 64) + set_env "GITHUB_WEBHOOK_SECRET" "$GENERATED_SECRET" + ok "GITHUB_WEBHOOK_SECRET auto-generated" +else + ok "GITHUB_WEBHOOK_SECRET already set" +fi + +# Fetch available labels from the repo +if [ -z "${GITHUB_LABELS:-}" ]; then + echo " Fetching labels from $GITHUB_REPO..." + REPO_LABELS=$(gh api "repos/$GITHUB_REPO/labels" --jq '.[].name' 2>/dev/null | tr '\n' ',' | sed 's/,$//') + if [ -n "$REPO_LABELS" ]; then + set_env "GITHUB_LABELS" "$REPO_LABELS" + ok "GITHUB_LABELS fetched from repo" + echo -e " ${DIM}Labels: ${REPO_LABELS}${NC}" + else + warn "Could not fetch labels — using defaults" + set_env "GITHUB_LABELS" "bug,enhancement,question,documentation" + fi +else + ok "GITHUB_LABELS already set" +fi + +# ── 2. Hookdeck ─────────────────────────────────────────── + +header "Hookdeck" + +if ! command -v hookdeck &> /dev/null; then + err "Hookdeck CLI not found. Install it: https://hookdeck.com/docs/cli" + exit 1 +fi + +ok "Hookdeck CLI installed" + +prompt_for "HOOKDECK_API_KEY" "Hookdeck API key" \ + "Dashboard → Project Settings → API Keys (https://dashboard.hookdeck.com)" + +# ── 3. Trigger.dev ──────────────────────────────────────── + +header "Trigger.dev" + +prompt_for "TRIGGER_SECRET_KEY" "Trigger.dev Production secret key" \ + "Dashboard → API keys → Production (must start with tr_prod_) https://cloud.trigger.dev" + +prompt_for "TRIGGER_PROJECT_REF" "Trigger.dev project ref" \ + "Project settings → General (e.g., proj_xxxx) https://cloud.trigger.dev" + +# ── 4. Anthropic ────────────────────────────────────────── + +header "Anthropic (Claude API)" + +prompt_for "ANTHROPIC_API_KEY" "Anthropic API key" \ + "Get one at: https://console.anthropic.com/settings/keys" + +# ── 5. Slack (optional) ────────────────────────────────── + +header "Slack (optional — for deployment notifications)" + +if [ -z "${SLACK_WEBHOOK_URL:-}" ]; then + echo -e " ${DIM}The handle-push task posts deployment summaries to Slack.${NC}" + echo -e " ${DIM}To set up: Slack → Apps → Create New App → Incoming Webhooks${NC}" + echo -e " ${DIM}→ Add New Webhook to Workspace → pick a channel → copy the URL${NC}" + echo "" + read -p " Enter Slack webhook URL (or press Enter to skip): " slack_url + if [ -n "$slack_url" ]; then + set_env "SLACK_WEBHOOK_URL" "$slack_url" + ok "SLACK_WEBHOOK_URL set" + else + warn "Skipped — handle-push task will log to console instead" + set_env "SLACK_WEBHOOK_URL" "" + fi +else + ok "SLACK_WEBHOOK_URL already set" +fi + +# ── Summary ─────────────────────────────────────────────── + +header "Configuration summary" + +# Helper to show masked status +show_var() { + local name="$1" + local label="${2:-}" + local value="${!name:-}" + local pad=$(printf "%-24s" "$name") + if [ -n "$value" ]; then + if [ -n "$label" ]; then + echo -e " ${pad} ${GREEN}$label${NC}" + else + echo -e " ${pad} ${GREEN}set${NC}" + fi + else + echo -e " ${pad} ${RED}not set${NC}" + fi +} + +show_var "GITHUB_REPO" +show_var "GITHUB_ACCESS_TOKEN" "auto-detected (gh CLI)" +show_var "GITHUB_WEBHOOK_SECRET" "auto-generated" +show_var "GITHUB_LABELS" "fetched from repo" +show_var "HOOKDECK_API_KEY" +show_var "TRIGGER_SECRET_KEY" +show_var "TRIGGER_PROJECT_REF" +show_var "ANTHROPIC_API_KEY" +if [ -n "${SLACK_WEBHOOK_URL:-}" ]; then + show_var "SLACK_WEBHOOK_URL" +else + printf " %-24s ${YELLOW}skipped${NC}\n" "SLACK_WEBHOOK_URL" +fi +echo "" + +# ── Check mode: stop here ───────────────────────────────── + +if [ "${1:-}" = "--check" ]; then + info "Check complete. Run without --check to proceed with setup." + exit 0 +fi + +# ── Run setup steps ─────────────────────────────────────── + +header "Step 1/3: Deploy Trigger.dev tasks" + +# This demo is Production-only: Hookdeck must use the Production API key (tr_prod_...). +if [ -n "${TRIGGER_SECRET_KEY:-}" ]; then + case "$TRIGGER_SECRET_KEY" in + tr_dev_*|tr_stg_*) + err "TRIGGER_SECRET_KEY must be a Production secret (tr_prod_...). This demo does not use Development or Staging." + err "Create or copy a Production key in Trigger.dev → API keys, update .env, then run setup again." + exit 1 + ;; + tr_prod_*) ;; + *) + warn "TRIGGER_SECRET_KEY does not start with tr_prod_. Use a Production key or setup may fail." + ;; + esac +fi + +echo -e " ${DIM}Running: npm run deploy:prod (Trigger.dev Production environment)${NC}" +cd "$PROJECT_DIR" +npm run deploy:prod + +echo "" +header "Step 2/3: Create Hookdeck resources" + +bash "$SCRIPT_DIR/setup-hookdeck.sh" + +echo "" +header "Step 3/3: Register GitHub webhook" + +bash "$SCRIPT_DIR/setup-github-webhook.sh" + +# ── Done ────────────────────────────────────────────────── + +echo "" +echo -e "${GREEN}${BOLD}Setup complete!${NC}" +echo "" +echo " Next steps:" +echo " npm run deploy # redeploy task code to Trigger.dev Production after changes" +echo "" +echo " Test it:" +echo " • Create an issue on ${GITHUB_REPO} → watch it get labeled" +echo " • Open a PR → watch for the AI review comment" +echo " • Push to main → check Slack for the deployment summary" +echo "" +echo " Dashboards:" +echo " • Hookdeck: https://dashboard.hookdeck.com" +echo " • Trigger.dev: https://cloud.trigger.dev" +echo "" diff --git a/trigger-dev/github-ai-agent/trigger.config.ts b/trigger-dev/github-ai-agent/trigger.config.ts new file mode 100644 index 0000000..cb07544 --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger.config.ts @@ -0,0 +1,109 @@ +import { existsSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { defineConfig } from "@trigger.dev/sdk"; +import { syncEnvVars } from "@trigger.dev/build/extensions/core"; +import { config as loadDotenv } from "dotenv"; + +/** + * Env vars consumed by tasks at runtime. Synced from `.env` → Trigger.dev Production on each + * `npm run deploy` (see syncEnvVars below). Do not add Hookdeck or TRIGGER_SECRET_KEY here. + * + * `deploy:prod` uses `--env-file .env` so the CLI hydrates `process.env` before this config runs. + * We also call `loadDotenv` here so sync still works if deploy is invoked without that flag. + */ +/** Keys stored in Trigger.dev / available in tasks at runtime (one name per secret — no duplicates). */ +const TASK_ENV_KEYS = [ + "ANTHROPIC_API_KEY", + "GITHUB_ACCESS_TOKEN", + "GITHUB_LABELS", + "SLACK_WEBHOOK_URL", +] as const; + +function configFileDir(): string { + try { + return dirname(fileURLToPath(import.meta.url)); + } catch { + return process.cwd(); + } +} + +/** Prefer repo root (cwd), then folder containing this config file. */ +function resolveDotenvPath(): string | undefined { + const candidates = [ + resolve(process.cwd(), ".env"), + resolve(configFileDir(), ".env"), + ]; + for (const p of candidates) { + if (existsSync(p)) return p; + } + return undefined; +} + +/** + * Load `.env` into `process.env` (does not override existing env vars). + * If an older `.env` only defines `GITHUB_TOKEN`, copy it to `GITHUB_ACCESS_TOKEN` for sync + * (some UIs don’t persist `GITHUB_TOKEN` reliably; `GITHUB_ACCESS_TOKEN` is explicit). + */ +function readTaskEnv(): Record { + const dotenvPath = resolveDotenvPath(); + if (dotenvPath) { + loadDotenv({ path: dotenvPath }); + } + const access = process.env.GITHUB_ACCESS_TOKEN?.trim(); + const legacy = process.env.GITHUB_TOKEN?.trim(); + if (!access && legacy) { + process.env.GITHUB_ACCESS_TOKEN = legacy; + } + const out: Record = {}; + for (const key of TASK_ENV_KEYS) { + const v = process.env[key]; + out[key] = v === "" ? undefined : v; + } + return out; +} + +export default defineConfig({ + // Replace with your Trigger.dev project ref from the dashboard + project: process.env.TRIGGER_PROJECT_REF!, + dirs: ["./trigger"], + maxDuration: 120, // seconds — generous limit for LLM calls + retries: { + enabledInDev: false, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + build: { + extensions: [ + syncEnvVars(async () => { + const env = readTaskEnv(); + const missing: string[] = []; + if (!env.ANTHROPIC_API_KEY?.trim()) missing.push("ANTHROPIC_API_KEY"); + if (!env.GITHUB_ACCESS_TOKEN?.trim()) { + missing.push( + "GITHUB_ACCESS_TOKEN (or legacy GITHUB_TOKEN in .env)", + ); + } + if (missing.length) { + const hint = resolveDotenvPath() + ? `Found .env at ${resolveDotenvPath()} but ${missing.join(", ")} empty/missing.` + : `No .env found (looked in ${process.cwd()} and ${configFileDir()}).`; + throw new Error( + `[trigger.config] Missing ${missing.join(", ")} for task sync. ${hint} Add GITHUB_ACCESS_TOKEN to .env or set in Trigger.dev → Environment variables → Production. Deploy with: npm run deploy (uses --env-file .env).`, + ); + } + const synced: Record = {}; + for (const key of TASK_ENV_KEYS) { + const value = env[key]?.trim(); + if (value) synced[key] = value; + } + return synced; + }), + ], + }, +}); diff --git a/trigger-dev/github-ai-agent/trigger/github-webhook-handler.ts b/trigger-dev/github-ai-agent/trigger/github-webhook-handler.ts new file mode 100644 index 0000000..53bc239 --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/github-webhook-handler.ts @@ -0,0 +1,60 @@ +/** + * Pattern A: Fan-out router. + * + * Receives all GitHub webhook events via a single Hookdeck connection and + * routes them to the appropriate sub-task based on the event type. Verification + * happens once here; sub-tasks trust the payload because they are triggered + * internally, not by external HTTP requests. + * + * Hookdeck config for this pattern: + * - One source, one connection, one destination + * - Destination URL: https://api.trigger.dev/api/v1/tasks/github-webhook-handler/trigger + * - No filter rules (all events come through) + * - trigger-wrapper transformation wraps the payload + */ + +import { task, tasks } from "@trigger.dev/sdk"; +import { verifyHookdeckEvent } from "./lib/verify-hookdeck.js"; + +interface GitHubWebhookPayload { + _hookdeck?: { + verified: boolean; + signature?: string; + }; + event: string; + action?: string; + [key: string]: unknown; +} + +export const githubWebhookHandler = task({ + id: "github-webhook-handler", + run: async (payload: GitHubWebhookPayload) => { + verifyHookdeckEvent(payload); + + console.log(`Received GitHub event: ${payload.event} (action: ${payload.action ?? "none"})`); + + switch (payload.event) { + case "pull_request": + if (payload.action === "opened" || payload.action === "synchronize") { + await tasks.trigger("handle-pr", payload); + console.log(`Triggered handle-pr for PR #${payload.number}`); + } + break; + + case "issues": + if (payload.action === "opened") { + await tasks.trigger("handle-issue", payload); + console.log(`Triggered handle-issue for issue #${(payload.issue as { number: number })?.number}`); + } + break; + + case "push": + await tasks.trigger("handle-push", payload); + console.log(`Triggered handle-push for ref ${payload.ref}`); + break; + + default: + console.log(`Ignoring event: ${payload.event}`); + } + }, +}); diff --git a/trigger-dev/github-ai-agent/trigger/handle-issue.ts b/trigger-dev/github-ai-agent/trigger/handle-issue.ts new file mode 100644 index 0000000..a16f63e --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/handle-issue.ts @@ -0,0 +1,99 @@ +/** + * AI-powered issue labeler. + * + * When an issue is created, analyzes the title and body with Claude and + * auto-applies appropriate labels. + * + * In Pattern A: triggered by github-webhook-handler (no verification needed). + * In Pattern B: triggered directly by Hookdeck (verifies independently). + * + * Hookdeck config for Pattern B: + * - Filter: { "x-github-event": { "$eq": "issues" } } + * - Destination URL: https://api.trigger.dev/api/v1/tasks/handle-issue/trigger + */ + +import { task } from "@trigger.dev/sdk"; +import { verifyHookdeckEvent } from "./lib/verify-hookdeck.js"; +import { addLabels, parseRepo } from "./lib/github.js"; +import { ask } from "./lib/ai.js"; + +// Labels the LLM can apply, loaded from GITHUB_LABELS env var (CSV). +// Falls back to GitHub's default labels if not set. +function getValidLabels(): string[] { + const labelsEnv = process.env.GITHUB_LABELS; + if (labelsEnv) { + return labelsEnv.split(",").map((l) => l.trim()).filter(Boolean); + } + return ["bug", "enhancement", "question", "documentation"]; +} + +interface IssuePayload { + _hookdeck?: { + verified: boolean; + signature?: string; + }; + event: string; + action: string; + issue: { + number: number; + title: string; + body: string | null; + html_url: string; + }; + repository: { + full_name: string; + }; + [key: string]: unknown; +} + +export const handleIssue = task({ + id: "handle-issue", + run: async (payload: IssuePayload) => { + verifyHookdeckEvent(payload); + + const { owner, repo } = parseRepo(payload.repository.full_name); + const issue = payload.issue; + const validLabels = getValidLabels(); + + console.log(`Labeling issue #${issue.number}: ${issue.title}`); + console.log(`Available labels: ${validLabels.join(", ")}`); + + const prompt = `Classify this GitHub issue into one or more categories. Return ONLY a JSON array of labels from this list: ${JSON.stringify(validLabels)}. + +Pick the most appropriate label(s) based on the issue content. If none fit well, return an empty array []. + +Return only the JSON array, nothing else. Example: ["bug"] or ["enhancement", "documentation"] + +Issue title: ${issue.title} +Issue body: ${issue.body ?? "(no body)"}`; + + const response = await ask(prompt, 100); + + // Parse the LLM response as a JSON array of labels + let labels: string[]; + try { + labels = JSON.parse(response.trim()); + if (!Array.isArray(labels)) { + throw new Error("Response is not an array"); + } + // Filter to only valid labels + labels = labels.filter((l): l is string => + typeof l === "string" && validLabels.includes(l) + ); + } catch { + console.warn(`Failed to parse LLM response as labels: ${response}`); + labels = []; + } + + if (labels.length === 0) { + console.log(`No labels to apply for issue #${issue.number}`); + return { issueNumber: issue.number, labels: [] }; + } + + await addLabels(owner, repo, issue.number, labels); + + console.log(`Applied labels [${labels.join(", ")}] to issue #${issue.number}`); + + return { issueNumber: issue.number, owner, repo, labels }; + }, +}); diff --git a/trigger-dev/github-ai-agent/trigger/handle-pr.ts b/trigger-dev/github-ai-agent/trigger/handle-pr.ts new file mode 100644 index 0000000..6a8ce1b --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/handle-pr.ts @@ -0,0 +1,100 @@ +/** + * AI-powered PR code review summary. + * + * When a pull request is opened or updated, fetches the diff, sends it to + * Claude for analysis, and posts a summary comment on the PR. + * + * In Pattern A: triggered by github-webhook-handler (no verification needed). + * In Pattern B: triggered directly by Hookdeck (verifies independently). + * + * Hookdeck config for Pattern B: + * - Filter: { "x-github-event": { "$eq": "pull_request" } } + * - Destination URL: https://api.trigger.dev/api/v1/tasks/handle-pr/trigger + */ + +import { task } from "@trigger.dev/sdk"; +import { verifyHookdeckEvent } from "./lib/verify-hookdeck.js"; +import { getPRDiff, postComment, parseRepo } from "./lib/github.js"; +import { ask } from "./lib/ai.js"; + +interface PRPayload { + _hookdeck?: { + verified: boolean; + signature?: string; + }; + event: string; + action: string; + number: number; + pull_request: { + title: string; + body: string | null; + html_url: string; + additions: number; + deletions: number; + changed_files: number; + }; + repository: { + full_name: string; + }; + /** Allows passing this payload to `verifyHookdeckEvent` (`HookdeckPayload`). */ + [key: string]: unknown; +} + +export const handlePR = task({ + id: "handle-pr", + run: async (payload: PRPayload) => { + // In Pattern B, events arrive directly from Hookdeck. + // In Pattern A, this is a no-op because github-webhook-handler already verified. + verifyHookdeckEvent(payload); + + const { owner, repo } = parseRepo(payload.repository.full_name); + const prNumber = payload.number; + const pr = payload.pull_request; + + console.log(`Reviewing PR #${prNumber}: ${pr.title}`); + console.log(` ${pr.additions} additions, ${pr.deletions} deletions, ${pr.changed_files} files`); + + // Fetch the diff + const diff = await getPRDiff(owner, repo, prNumber); + + // Truncate very large diffs to stay within context limits + const maxDiffLength = 50000; + const truncatedDiff = + diff.length > maxDiffLength + ? diff.slice(0, maxDiffLength) + "\n\n[diff truncated]" + : diff; + + // Ask Claude for a review summary + const prompt = `You are a senior developer reviewing a pull request. Analyze the following diff and provide: + +1. A brief summary of what changed (2-3 sentences) +2. Key observations (things that look good, potential concerns) +3. Any suggestions for improvement + +Keep it concise and constructive. Focus on substance, not style nitpicks. + +PR title: ${pr.title} +PR description: ${pr.body ?? "(no description)"} + +Diff: +\`\`\` +${truncatedDiff} +\`\`\``; + + const review = await ask(prompt, 1500); + + // Post the review as a PR comment + const comment = `## AI Review Summary + +${review} + +--- +*Generated by [Hookdeck](https://hookdeck.com) + [Trigger.dev](https://trigger.dev)*`; + + await postComment(owner, repo, prNumber, comment); + + console.log(`Posted review comment on PR #${prNumber}`); + + return { prNumber, owner, repo, reviewLength: review.length }; + }, +}); diff --git a/trigger-dev/github-ai-agent/trigger/handle-push.ts b/trigger-dev/github-ai-agent/trigger/handle-push.ts new file mode 100644 index 0000000..6e1173b --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/handle-push.ts @@ -0,0 +1,112 @@ +/** + * AI-powered deployment summary to Slack. + * + * On `push`, summarizes what changed using Claude and posts to Slack. + * By default **any branch** is summarized (good for demos). Set + * `GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY=true` in Trigger.dev env to only + * run for the repo default branch (e.g. `main`). + * + * In Pattern A: triggered by github-webhook-handler (no verification needed). + * In Pattern B: triggered directly by Hookdeck (verifies independently). + * + * Hookdeck config for Pattern B: + * - Filter: { "x-github-event": { "$eq": "push" } } + * - Destination URL: https://api.trigger.dev/api/v1/tasks/handle-push/trigger + */ + +import { task } from "@trigger.dev/sdk"; +import { verifyHookdeckEvent } from "./lib/verify-hookdeck.js"; +import { ask } from "./lib/ai.js"; +import { postToSlack } from "./lib/slack.js"; + +interface Commit { + id: string; + message: string; + author: { name: string; username?: string }; + added: string[]; + removed: string[]; + modified: string[]; +} + +interface PushPayload { + _hookdeck?: { + verified: boolean; + signature?: string; + }; + event: string; + ref: string; + compare: string; + pusher: { name: string }; + commits: Commit[]; + repository: { + full_name: string; + default_branch: string; + }; + [key: string]: unknown; +} + +export const handlePush = task({ + id: "handle-push", + run: async (payload: PushPayload) => { + verifyHookdeckEvent(payload); + + const repoName = payload.repository.full_name; + const branch = payload.ref.replace("refs/heads/", ""); + const defaultBranch = payload.repository.default_branch; + + const defaultBranchOnly = + process.env.GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY === "true" || + process.env.GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY === "1"; + + if (defaultBranchOnly && branch !== defaultBranch) { + console.log( + `Ignoring push to non-default branch (${branch}; default is ${defaultBranch}) — set GITHUB_PUSH_SUMMARY_DEFAULT_BRANCH_ONLY=false to allow all branches` + ); + return { skipped: true, branch, defaultBranch }; + } + + const commits = payload.commits ?? []; + if (commits.length === 0) { + console.log("No commits in push event"); + return { skipped: true, reason: "no commits" }; + } + + console.log( + `Summarizing push to ${repoName}@${branch}${branch === defaultBranch ? " (default)" : ""}: ${commits.length} commits` + ); + + // Build context for the LLM + const commitSummary = commits + .map((c) => { + const files = [...c.added, ...c.modified, ...c.removed]; + return `- ${c.message} (${c.author.name}, ${files.length} files)`; + }) + .join("\n"); + + const allFiles = [ + ...new Set(commits.flatMap((c) => [...c.added, ...c.modified, ...c.removed])), + ]; + + const prompt = `Summarize this code push for a team Slack channel. Write 2-3 sentences about what changed. Be specific, not generic. Don't list individual commits — synthesize them into a cohesive summary. + +Repository: ${repoName} +Branch: ${branch}${branch === defaultBranch ? " (default branch)" : ""} +Pushed by: ${payload.pusher.name} +Commits (${commits.length}): +${commitSummary} + +Files changed (${allFiles.length}): +${allFiles.slice(0, 30).join("\n")}${allFiles.length > 30 ? `\n... and ${allFiles.length - 30} more` : ""}`; + + const summary = await ask(prompt, 300); + + // Format the Slack message + const slackMessage = `*Push: ${repoName} (${branch})*\n${summary}\n\n_${commits.length} commits by ${payload.pusher.name}_ | <${payload.compare}|View diff>`; + + await postToSlack(slackMessage); + + console.log(`Posted deployment summary to Slack for ${repoName}`); + + return { repoName, branch, commitCount: commits.length, summary }; + }, +}); diff --git a/trigger-dev/github-ai-agent/trigger/lib/ai.ts b/trigger-dev/github-ai-agent/trigger/lib/ai.ts new file mode 100644 index 0000000..d95574f --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/lib/ai.ts @@ -0,0 +1,39 @@ +/** + * LLM helper using the Anthropic SDK. + * + * The ANTHROPIC_API_KEY environment variable must be set in Trigger.dev's + * environment variables. + */ + +import Anthropic from "@anthropic-ai/sdk"; + +let client: Anthropic | null = null; + +function getClient(): Anthropic { + const apiKey = process.env.ANTHROPIC_API_KEY?.trim(); + if (!apiKey) { + throw new Error( + "ANTHROPIC_API_KEY is not set in this Trigger.dev environment. Add it under Project → Environment variables → Production, or ensure it is in .env and run npm run deploy (secrets sync on deploy)." + ); + } + if (!client) { + client = new Anthropic({ apiKey }); + } + return client; +} + +/** Send a prompt to Claude and return the text response. */ +export async function ask(prompt: string, maxTokens: number = 1024): Promise { + const response = await getClient().messages.create({ + model: "claude-sonnet-4-20250514", + max_tokens: maxTokens, + messages: [{ role: "user", content: prompt }], + }); + + const textBlock = response.content.find((block) => block.type === "text"); + if (!textBlock || textBlock.type !== "text") { + throw new Error("No text response from Claude"); + } + + return textBlock.text; +} diff --git a/trigger-dev/github-ai-agent/trigger/lib/github.ts b/trigger-dev/github-ai-agent/trigger/lib/github.ts new file mode 100644 index 0000000..d5661ca --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/lib/github.ts @@ -0,0 +1,100 @@ +/** + * Lightweight GitHub API helpers. + * + * Uses raw fetch to keep dependencies minimal. Set `GITHUB_ACCESS_TOKEN` in Trigger.dev + * Production (synced from `.env` on deploy). Legacy `GITHUB_TOKEN` is still accepted. + * Needs repo scope for posting comments and applying labels. + */ + +const GITHUB_API = "https://api.github.com"; + +function githubToken(): string | undefined { + const t = + process.env.GITHUB_ACCESS_TOKEN?.trim() || process.env.GITHUB_TOKEN?.trim(); + return t || undefined; +} + +function headers(): Record { + const token = githubToken(); + if (!token) { + throw new Error( + "GITHUB_ACCESS_TOKEN is not set in this Trigger.dev environment (Production). Add it in the dashboard or in .env and redeploy." + ); + } + return { + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github.v3+json", + "Content-Type": "application/json", + }; +} + +/** Fetch the diff for a pull request. */ +export async function getPRDiff( + owner: string, + repo: string, + prNumber: number +): Promise { + const response = await fetch( + `${GITHUB_API}/repos/${owner}/${repo}/pulls/${prNumber}`, + { + headers: { + ...headers(), + Accept: "application/vnd.github.v3.diff", + }, + } + ); + + if (!response.ok) { + throw new Error(`Failed to fetch PR diff: ${response.status} ${response.statusText}`); + } + + return response.text(); +} + +/** Post a comment on a pull request or issue. */ +export async function postComment( + owner: string, + repo: string, + issueNumber: number, + body: string +): Promise { + const response = await fetch( + `${GITHUB_API}/repos/${owner}/${repo}/issues/${issueNumber}/comments`, + { + method: "POST", + headers: headers(), + body: JSON.stringify({ body }), + } + ); + + if (!response.ok) { + throw new Error(`Failed to post comment: ${response.status} ${response.statusText}`); + } +} + +/** Apply labels to an issue. */ +export async function addLabels( + owner: string, + repo: string, + issueNumber: number, + labels: string[] +): Promise { + const response = await fetch( + `${GITHUB_API}/repos/${owner}/${repo}/issues/${issueNumber}/labels`, + { + method: "POST", + headers: headers(), + body: JSON.stringify({ labels }), + } + ); + + if (!response.ok) { + throw new Error(`Failed to add labels: ${response.status} ${response.statusText}`); + } +} + +/** Parse owner and repo from a repository full_name (e.g., "hookdeck/hookdeck-demos"). */ +export function parseRepo(fullName: string): { owner: string; repo: string } { + const [owner, repo] = fullName.split("/"); + return { owner, repo }; +} diff --git a/trigger-dev/github-ai-agent/trigger/lib/slack.ts b/trigger-dev/github-ai-agent/trigger/lib/slack.ts new file mode 100644 index 0000000..8dac024 --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/lib/slack.ts @@ -0,0 +1,32 @@ +/** + * Slack notification helper using incoming webhooks. + * + * The SLACK_WEBHOOK_URL environment variable must be set in Trigger.dev's + * environment variables. Get a webhook URL from your Slack app settings + * under Incoming Webhooks. + */ + +/** + * Post a message to a Slack channel via incoming webhook. + * If SLACK_WEBHOOK_URL is not set, logs to console instead of failing. + * Returns true if posted to Slack, false if logged to console. + */ +export async function postToSlack(text: string): Promise { + const webhookUrl = process.env.SLACK_WEBHOOK_URL; + if (!webhookUrl) { + console.log("[Slack not configured] Would have posted:", text); + return false; + } + + const response = await fetch(webhookUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text }), + }); + + if (!response.ok) { + throw new Error(`Failed to post to Slack: ${response.status} ${response.statusText}`); + } + + return true; +} diff --git a/trigger-dev/github-ai-agent/trigger/lib/verify-hookdeck.ts b/trigger-dev/github-ai-agent/trigger/lib/verify-hookdeck.ts new file mode 100644 index 0000000..7cb7a87 --- /dev/null +++ b/trigger-dev/github-ai-agent/trigger/lib/verify-hookdeck.ts @@ -0,0 +1,37 @@ +/** + * Hookdeck event verification utility. + * + * The trigger-wrapper transformation injects a _hookdeck metadata object + * into every payload. `verified` reflects Hookdeck's x-hookdeck-verified header + * when present, otherwise it is derived from connection context (see hookdeck/trigger-wrapper.js). + * This utility checks that metadata before any task processing begins. + * + * Verification chain: + * 1. Hookdeck source verification validates the GitHub HMAC signature at ingress + * 2. Hookdeck destination auth (Bearer token) authenticates to the Trigger.dev API + * 3. This check confirms the event actually passed source verification + */ + +export interface HookdeckMeta { + verified: boolean; + signature?: string; +} + +export interface HookdeckPayload { + _hookdeck?: HookdeckMeta; + [key: string]: unknown; +} + +export function verifyHookdeckEvent(payload: HookdeckPayload): void { + if (!payload._hookdeck) { + throw new Error( + "Missing _hookdeck metadata. Event did not come through the trigger-wrapper transformation." + ); + } + + if (!payload._hookdeck.verified) { + throw new Error( + "Event failed Hookdeck source verification. The webhook signature was invalid." + ); + } +} diff --git a/trigger-dev/github-ai-agent/tsconfig.json b/trigger-dev/github-ai-agent/tsconfig.json new file mode 100644 index 0000000..22bfe4d --- /dev/null +++ b/trigger-dev/github-ai-agent/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "outDir": "./dist" + }, + "include": ["trigger/**/*.ts"] +}